summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig3
-rw-r--r--.github/CODEOWNERS224
-rw-r--r--.github/workflows/android_builds.yml9
-rw-r--r--.github/workflows/ios_builds.yml2
-rw-r--r--.github/workflows/javascript_builds.disabled2
-rw-r--r--.github/workflows/linux_builds.yml20
-rw-r--r--.github/workflows/macos_builds.yml4
-rw-r--r--.github/workflows/static_checks.yml7
-rw-r--r--.github/workflows/windows_builds.yml6
-rw-r--r--.gitignore6
-rw-r--r--.mailmap8
-rw-r--r--AUTHORS.md7
-rw-r--r--CONTRIBUTING.md33
-rw-r--r--COPYRIGHT.txt307
-rw-r--r--DONORS.md208
-rw-r--r--LICENSE.txt4
-rw-r--r--README.md3
-rw-r--r--SConstruct71
-rw-r--r--core/SCsub2
-rw-r--r--core/config/engine.cpp4
-rw-r--r--core/config/engine.h14
-rw-r--r--core/config/project_settings.cpp242
-rw-r--r--core/config/project_settings.h18
-rw-r--r--core/core_bind.cpp165
-rw-r--r--core/core_bind.h41
-rw-r--r--core/core_constants.cpp15
-rw-r--r--core/core_constants.h4
-rw-r--r--core/core_string_names.cpp7
-rw-r--r--core/core_string_names.h5
-rw-r--r--core/crypto/aes_context.cpp4
-rw-r--r--core/crypto/aes_context.h4
-rw-r--r--core/crypto/crypto.cpp6
-rw-r--r--core/crypto/crypto.h6
-rw-r--r--core/crypto/crypto_core.cpp4
-rw-r--r--core/crypto/crypto_core.h4
-rw-r--r--core/crypto/hashing_context.cpp4
-rw-r--r--core/crypto/hashing_context.h4
-rw-r--r--core/debugger/debugger_marshalls.cpp4
-rw-r--r--core/debugger/debugger_marshalls.h4
-rw-r--r--core/debugger/engine_debugger.cpp12
-rw-r--r--core/debugger/engine_debugger.h10
-rw-r--r--core/debugger/local_debugger.cpp14
-rw-r--r--core/debugger/local_debugger.h4
-rw-r--r--core/debugger/remote_debugger.cpp11
-rw-r--r--core/debugger/remote_debugger.h4
-rw-r--r--core/debugger/remote_debugger_peer.cpp16
-rw-r--r--core/debugger/remote_debugger_peer.h6
-rw-r--r--core/debugger/script_debugger.cpp4
-rw-r--r--core/debugger/script_debugger.h4
-rw-r--r--core/doc_data.cpp4
-rw-r--r--core/doc_data.h4
-rw-r--r--core/error/error_list.h4
-rw-r--r--core/error/error_macros.cpp4
-rw-r--r--core/error/error_macros.h18
-rw-r--r--core/input/default_controller_mappings.h4
-rw-r--r--core/input/gamecontrollerdb.txt116
-rw-r--r--core/input/godotcontrollerdb.txt27
-rw-r--r--core/input/input.cpp97
-rw-r--r--core/input/input.h17
-rw-r--r--core/input/input_event.cpp73
-rw-r--r--core/input/input_event.h26
-rw-r--r--core/input/input_map.cpp556
-rw-r--r--core/input/input_map.h21
-rw-r--r--core/io/compression.cpp4
-rw-r--r--core/io/compression.h4
-rw-r--r--core/io/config_file.cpp6
-rw-r--r--core/io/config_file.h4
-rw-r--r--core/io/dtls_server.cpp4
-rw-r--r--core/io/dtls_server.h4
-rw-r--r--core/io/file_access_compressed.cpp4
-rw-r--r--core/io/file_access_compressed.h4
-rw-r--r--core/io/file_access_encrypted.cpp4
-rw-r--r--core/io/file_access_encrypted.h4
-rw-r--r--core/io/file_access_memory.cpp4
-rw-r--r--core/io/file_access_memory.h4
-rw-r--r--core/io/file_access_network.cpp19
-rw-r--r--core/io/file_access_network.h6
-rw-r--r--core/io/file_access_pack.cpp6
-rw-r--r--core/io/file_access_pack.h6
-rw-r--r--core/io/file_access_zip.cpp4
-rw-r--r--core/io/file_access_zip.h4
-rw-r--r--core/io/http_client.cpp15
-rw-r--r--core/io/http_client.h4
-rw-r--r--core/io/image.cpp48
-rw-r--r--core/io/image.h12
-rw-r--r--core/io/image_loader.cpp6
-rw-r--r--core/io/image_loader.h6
-rw-r--r--core/io/ip.cpp54
-rw-r--r--core/io/ip.h4
-rw-r--r--core/io/ip_address.cpp4
-rw-r--r--core/io/ip_address.h4
-rw-r--r--core/io/json.cpp54
-rw-r--r--core/io/json.h4
-rw-r--r--core/io/logger.cpp14
-rw-r--r--core/io/logger.h8
-rw-r--r--core/io/marshalls.cpp4
-rw-r--r--core/io/marshalls.h4
-rw-r--r--core/io/multiplayer_api.cpp4
-rw-r--r--core/io/multiplayer_api.h4
-rw-r--r--core/io/net_socket.cpp4
-rw-r--r--core/io/net_socket.h4
-rw-r--r--core/io/networked_multiplayer_peer.cpp4
-rw-r--r--core/io/networked_multiplayer_peer.h4
-rw-r--r--core/io/packed_data_container.cpp4
-rw-r--r--core/io/packed_data_container.h4
-rw-r--r--core/io/packet_peer.cpp4
-rw-r--r--core/io/packet_peer.h4
-rw-r--r--core/io/packet_peer_dtls.cpp4
-rw-r--r--core/io/packet_peer_dtls.h4
-rw-r--r--core/io/packet_peer_udp.cpp4
-rw-r--r--core/io/packet_peer_udp.h4
-rw-r--r--core/io/pck_packer.cpp6
-rw-r--r--core/io/pck_packer.h4
-rw-r--r--core/io/resource.cpp137
-rw-r--r--core/io/resource.h11
-rw-r--r--core/io/resource_format_binary.cpp83
-rw-r--r--core/io/resource_format_binary.h8
-rw-r--r--core/io/resource_importer.cpp14
-rw-r--r--core/io/resource_importer.h7
-rw-r--r--core/io/resource_loader.cpp67
-rw-r--r--core/io/resource_loader.h22
-rw-r--r--core/io/resource_saver.cpp4
-rw-r--r--core/io/resource_saver.h4
-rw-r--r--core/io/stream_peer.cpp4
-rw-r--r--core/io/stream_peer.h4
-rw-r--r--core/io/stream_peer_ssl.cpp4
-rw-r--r--core/io/stream_peer_ssl.h4
-rw-r--r--core/io/stream_peer_tcp.cpp4
-rw-r--r--core/io/stream_peer_tcp.h4
-rw-r--r--core/io/tcp_server.cpp4
-rw-r--r--core/io/tcp_server.h4
-rw-r--r--core/io/translation_loader_po.cpp8
-rw-r--r--core/io/translation_loader_po.h6
-rw-r--r--core/io/udp_server.cpp4
-rw-r--r--core/io/udp_server.h4
-rw-r--r--core/io/xml_parser.cpp70
-rw-r--r--core/io/xml_parser.h6
-rw-r--r--core/io/zip_io.cpp4
-rw-r--r--core/io/zip_io.h4
-rw-r--r--core/math/a_star.cpp10
-rw-r--r--core/math/a_star.h4
-rw-r--r--core/math/aabb.cpp4
-rw-r--r--core/math/aabb.h12
-rw-r--r--core/math/audio_frame.h7
-rw-r--r--core/math/basis.cpp8
-rw-r--r--core/math/basis.h4
-rw-r--r--core/math/camera_matrix.cpp17
-rw-r--r--core/math/camera_matrix.h5
-rw-r--r--core/math/color.cpp139
-rw-r--r--core/math/color.h32
-rw-r--r--core/math/color_names.inc2
-rw-r--r--core/math/delaunay_2d.h4
-rw-r--r--core/math/delaunay_3d.h4
-rw-r--r--core/math/disjoint_set.h4
-rw-r--r--core/math/dynamic_bvh.cpp8
-rw-r--r--core/math/dynamic_bvh.h14
-rw-r--r--core/math/expression.cpp4
-rw-r--r--core/math/expression.h4
-rw-r--r--core/math/face3.cpp4
-rw-r--r--core/math/face3.h4
-rw-r--r--core/math/geometry_2d.cpp22
-rw-r--r--core/math/geometry_2d.h15
-rw-r--r--core/math/geometry_3d.cpp27
-rw-r--r--core/math/geometry_3d.h37
-rw-r--r--core/math/math_defs.h4
-rw-r--r--core/math/math_fieldwise.cpp4
-rw-r--r--core/math/math_fieldwise.h4
-rw-r--r--core/math/math_funcs.cpp6
-rw-r--r--core/math/math_funcs.h18
-rw-r--r--core/math/octree.h22
-rw-r--r--core/math/plane.cpp4
-rw-r--r--core/math/plane.h4
-rw-r--r--core/math/quat.cpp111
-rw-r--r--core/math/quat.h23
-rw-r--r--core/math/quick_hull.cpp4
-rw-r--r--core/math/quick_hull.h4
-rw-r--r--core/math/random_number_generator.cpp4
-rw-r--r--core/math/random_number_generator.h4
-rw-r--r--core/math/random_pcg.cpp4
-rw-r--r--core/math/random_pcg.h4
-rw-r--r--core/math/rect2.cpp4
-rw-r--r--core/math/rect2.h38
-rw-r--r--core/math/transform.cpp4
-rw-r--r--core/math/transform.h12
-rw-r--r--core/math/transform_2d.cpp4
-rw-r--r--core/math/transform_2d.h4
-rw-r--r--core/math/triangle_mesh.cpp4
-rw-r--r--core/math/triangle_mesh.h4
-rw-r--r--core/math/triangulate.cpp4
-rw-r--r--core/math/triangulate.h4
-rw-r--r--core/math/vector2.cpp22
-rw-r--r--core/math/vector2.h36
-rw-r--r--core/math/vector3.cpp16
-rw-r--r--core/math/vector3.h36
-rw-r--r--core/math/vector3i.cpp4
-rw-r--r--core/math/vector3i.h4
-rw-r--r--core/object/callable_method_pointer.cpp4
-rw-r--r--core/object/callable_method_pointer.h4
-rw-r--r--core/object/class_db.cpp18
-rw-r--r--core/object/class_db.h7
-rw-r--r--core/object/message_queue.cpp4
-rw-r--r--core/object/message_queue.h4
-rw-r--r--core/object/method_bind.cpp4
-rw-r--r--core/object/method_bind.h4
-rw-r--r--core/object/object.cpp49
-rw-r--r--core/object/object.h30
-rw-r--r--core/object/object_id.h4
-rw-r--r--core/object/reference.cpp8
-rw-r--r--core/object/reference.h4
-rw-r--r--core/object/script_language.cpp16
-rw-r--r--core/object/script_language.h4
-rw-r--r--core/object/undo_redo.cpp66
-rw-r--r--core/object/undo_redo.h11
-rw-r--r--core/os/copymem.h4
-rw-r--r--core/os/dir_access.cpp6
-rw-r--r--core/os/dir_access.h4
-rw-r--r--core/os/file_access.cpp4
-rw-r--r--core/os/file_access.h4
-rw-r--r--core/os/keyboard.cpp4
-rw-r--r--core/os/keyboard.h4
-rw-r--r--core/os/main_loop.cpp28
-rw-r--r--core/os/main_loop.h16
-rw-r--r--core/os/memory.cpp30
-rw-r--r--core/os/memory.h10
-rw-r--r--core/os/midi_driver.cpp4
-rw-r--r--core/os/midi_driver.h4
-rw-r--r--core/os/mutex.cpp4
-rw-r--r--core/os/mutex.h4
-rw-r--r--core/os/os.cpp4
-rw-r--r--core/os/os.h15
-rw-r--r--core/os/pool_allocator.cpp4
-rw-r--r--core/os/pool_allocator.h4
-rw-r--r--core/os/rw_lock.h88
-rw-r--r--core/os/semaphore.h4
-rw-r--r--core/os/spin_lock.h4
-rw-r--r--core/os/thread.cpp96
-rw-r--r--core/os/thread.h78
-rw-r--r--core/os/thread_dummy.h62
-rw-r--r--core/os/thread_safe.h4
-rw-r--r--core/os/threaded_array_processor.h29
-rw-r--r--core/register_core_types.cpp5
-rw-r--r--core/register_core_types.h4
-rw-r--r--core/string/compressed_translation.cpp4
-rw-r--r--core/string/compressed_translation.h4
-rw-r--r--core/string/node_path.cpp4
-rw-r--r--core/string/node_path.h4
-rw-r--r--core/string/print_string.cpp4
-rw-r--r--core/string/print_string.h4
-rw-r--r--core/string/string_buffer.h10
-rw-r--r--core/string/string_builder.cpp4
-rw-r--r--core/string/string_builder.h4
-rw-r--r--core/string/string_name.cpp4
-rw-r--r--core/string/string_name.h6
-rw-r--r--core/string/translation.cpp37
-rw-r--r--core/string/translation.h4
-rw-r--r--core/string/translation_po.cpp8
-rw-r--r--core/string/translation_po.h4
-rw-r--r--core/string/ucaps.h4
-rw-r--r--core/string/ustring.cpp280
-rw-r--r--core/string/ustring.h23
-rw-r--r--core/templates/command_queue_mt.cpp4
-rw-r--r--core/templates/command_queue_mt.h9
-rw-r--r--core/templates/cowdata.h49
-rw-r--r--core/templates/hash_map.h6
-rw-r--r--core/templates/hashfuncs.h4
-rw-r--r--core/templates/list.h6
-rw-r--r--core/templates/local_vector.h20
-rw-r--r--core/templates/lru.h4
-rw-r--r--core/templates/map.h6
-rw-r--r--core/templates/oa_hash_map.h6
-rw-r--r--core/templates/ordered_hash_map.h6
-rw-r--r--core/templates/paged_allocator.h10
-rw-r--r--core/templates/paged_array.h22
-rw-r--r--core/templates/pair.h4
-rw-r--r--core/templates/pass_func.h4
-rw-r--r--core/templates/rid.h31
-rw-r--r--core/templates/rid_owner.cpp6
-rw-r--r--core/templates/rid_owner.h99
-rw-r--r--core/templates/ring_buffer.h4
-rw-r--r--core/templates/safe_refcount.cpp161
-rw-r--r--core/templates/safe_refcount.h356
-rw-r--r--core/templates/self_list.h4
-rw-r--r--core/templates/set.h6
-rw-r--r--core/templates/simple_type.h4
-rw-r--r--core/templates/sort_array.h4
-rw-r--r--core/templates/thread_work_pool.cpp20
-rw-r--r--core/templates/thread_work_pool.h11
-rw-r--r--core/templates/vector.h6
-rw-r--r--core/templates/vmap.h10
-rw-r--r--core/templates/vset.h10
-rw-r--r--core/typedefs.h4
-rw-r--r--core/variant/array.cpp38
-rw-r--r--core/variant/array.h11
-rw-r--r--core/variant/binder_common.h5
-rw-r--r--core/variant/callable.cpp4
-rw-r--r--core/variant/callable.h4
-rw-r--r--core/variant/callable_bind.cpp4
-rw-r--r--core/variant/callable_bind.h4
-rw-r--r--core/variant/container_type_validate.h4
-rw-r--r--core/variant/dictionary.cpp12
-rw-r--r--core/variant/dictionary.h6
-rw-r--r--core/variant/method_ptrcall.h4
-rw-r--r--core/variant/type_info.h4
-rw-r--r--core/variant/typed_array.h4
-rw-r--r--core/variant/variant.cpp10
-rw-r--r--core/variant/variant.h8
-rw-r--r--core/variant/variant_call.cpp81
-rw-r--r--core/variant/variant_construct.cpp7
-rw-r--r--core/variant/variant_internal.h4
-rw-r--r--core/variant/variant_op.cpp5
-rw-r--r--core/variant/variant_parser.cpp4
-rw-r--r--core/variant/variant_parser.h4
-rw-r--r--core/variant/variant_setget.cpp15
-rw-r--r--core/variant/variant_utility.cpp18
-rw-r--r--core/version.h4
-rw-r--r--doc/Makefile11
-rw-r--r--doc/classes/@GlobalScope.xml100
-rw-r--r--doc/classes/AABB.xml2
-rw-r--r--doc/classes/AStar.xml6
-rw-r--r--doc/classes/AStar2D.xml5
-rw-r--r--doc/classes/AnimatedSprite3D.xml5
-rw-r--r--doc/classes/Animation.xml6
-rw-r--r--doc/classes/AnimationNodeStateMachinePlayback.xml13
-rw-r--r--doc/classes/AnimationPlayer.xml8
-rw-r--r--doc/classes/AnimationTree.xml10
-rw-r--r--doc/classes/Area2D.xml56
-rw-r--r--doc/classes/Area3D.xml56
-rw-r--r--doc/classes/Array.xml55
-rw-r--r--doc/classes/ArrayMesh.xml14
-rw-r--r--doc/classes/AudioEffectCapture.xml75
-rw-r--r--doc/classes/BakedLightmapData.xml6
-rw-r--r--doc/classes/BaseMaterial3D.xml68
-rw-r--r--doc/classes/BoxMesh.xml2
-rw-r--r--doc/classes/BoxShape3D.xml4
-rw-r--r--doc/classes/Button.xml33
-rw-r--r--doc/classes/Callable.xml20
-rw-r--r--doc/classes/Camera2D.xml60
-rw-r--r--doc/classes/Camera3D.xml4
-rw-r--r--doc/classes/CanvasItem.xml2
-rw-r--r--doc/classes/CharFXTransform.xml2
-rw-r--r--doc/classes/CheckBox.xml14
-rw-r--r--doc/classes/CheckButton.xml14
-rw-r--r--doc/classes/ClassDB.xml1
-rw-r--r--doc/classes/ClippedCamera3D.xml8
-rw-r--r--doc/classes/CodeEdit.xml10
-rw-r--r--doc/classes/CodeHighlighter.xml40
-rw-r--r--doc/classes/CollisionPolygon3D.xml3
-rw-r--r--doc/classes/Color.xml24
-rw-r--r--doc/classes/ColorPicker.xml3
-rw-r--r--doc/classes/ColorPickerButton.xml12
-rw-r--r--doc/classes/Control.xml98
-rw-r--r--doc/classes/Curve2D.xml2
-rw-r--r--doc/classes/Curve3D.xml2
-rw-r--r--doc/classes/Decal.xml2
-rw-r--r--doc/classes/Dictionary.xml14
-rw-r--r--doc/classes/DisplayServer.xml38
-rw-r--r--doc/classes/EditorExportPlugin.xml15
-rw-r--r--doc/classes/EditorImportPlugin.xml12
-rw-r--r--doc/classes/EditorInspector.xml8
-rw-r--r--doc/classes/EditorInterface.xml14
-rw-r--r--doc/classes/EditorNode3DGizmoPlugin.xml14
-rw-r--r--doc/classes/EditorPlugin.xml7
-rw-r--r--doc/classes/EditorSceneImporterAssimp.xml36
-rw-r--r--doc/classes/EditorSceneImporterGLTF.xml13
-rw-r--r--doc/classes/EditorSceneImporterMesh.xml160
-rw-r--r--doc/classes/EditorSceneImporterMeshNode3D.xml21
-rw-r--r--doc/classes/EditorSettings.xml10
-rw-r--r--doc/classes/EditorSyntaxHighlighter.xml6
-rw-r--r--doc/classes/EncodedObjectAsID.xml4
-rw-r--r--doc/classes/Engine.xml16
-rw-r--r--doc/classes/Environment.xml10
-rw-r--r--doc/classes/File.xml16
-rw-r--r--doc/classes/FileDialog.xml4
-rw-r--r--doc/classes/Font.xml4
-rw-r--r--doc/classes/FontData.xml86
-rw-r--r--doc/classes/GIProbe.xml2
-rw-r--r--doc/classes/GLTFAccessor.xml43
-rw-r--r--doc/classes/GLTFAnimation.xml17
-rw-r--r--doc/classes/GLTFBufferView.xml25
-rw-r--r--doc/classes/GLTFCamera.xml23
-rw-r--r--doc/classes/GLTFDocument.xml13
-rw-r--r--doc/classes/GLTFLight.xml27
-rw-r--r--doc/classes/GLTFMesh.xml19
-rw-r--r--doc/classes/GLTFNode.xml43
-rw-r--r--doc/classes/GLTFSkeleton.xml67
-rw-r--r--doc/classes/GLTFSkin.xml71
-rw-r--r--doc/classes/GLTFSpecGloss.xml25
-rw-r--r--doc/classes/GLTFState.xml265
-rw-r--r--doc/classes/GLTFTexture.xml17
-rw-r--r--doc/classes/GPUParticles2D.xml3
-rw-r--r--doc/classes/GPUParticles3D.xml3
-rw-r--r--doc/classes/GeometryInstance3D.xml2
-rw-r--r--doc/classes/Gradient.xml4
-rw-r--r--doc/classes/GraphEdit.xml6
-rw-r--r--doc/classes/GraphNode.xml7
-rw-r--r--doc/classes/HTTPClient.xml2
-rw-r--r--doc/classes/HTTPRequest.xml2
-rw-r--r--doc/classes/Image.xml20
-rw-r--r--doc/classes/Input.xml10
-rw-r--r--doc/classes/InputEvent.xml8
-rw-r--r--doc/classes/InputMap.xml2
-rw-r--r--doc/classes/ItemList.xml70
-rw-r--r--doc/classes/JSONParseResult.xml2
-rw-r--r--doc/classes/Label.xml8
-rw-r--r--doc/classes/Light3D.xml2
-rw-r--r--doc/classes/LineEdit.xml18
-rw-r--r--doc/classes/LinkButton.xml10
-rw-r--r--doc/classes/MainLoop.xml24
-rw-r--r--doc/classes/MarginContainer.xml20
-rw-r--r--doc/classes/Material.xml6
-rw-r--r--doc/classes/MenuButton.xml12
-rw-r--r--doc/classes/Mesh.xml6
-rw-r--r--doc/classes/MultiplayerAPI.xml3
-rw-r--r--doc/classes/Navigation2D.xml59
-rw-r--r--doc/classes/Navigation3D.xml84
-rw-r--r--doc/classes/NavigationAgent2D.xml18
-rw-r--r--doc/classes/NavigationAgent3D.xml18
-rw-r--r--doc/classes/NavigationObstacle2D.xml18
-rw-r--r--doc/classes/NavigationObstacle3D.xml18
-rw-r--r--doc/classes/NavigationRegion2D.xml9
-rw-r--r--doc/classes/NavigationRegion3D.xml6
-rw-r--r--doc/classes/NavigationServer2D.xml31
-rw-r--r--doc/classes/NavigationServer3D.xml35
-rw-r--r--doc/classes/NetworkedMultiplayerPeer.xml3
-rw-r--r--doc/classes/NinePatchRect.xml4
-rw-r--r--doc/classes/Node.xml51
-rw-r--r--doc/classes/Node3D.xml10
-rw-r--r--doc/classes/OS.xml108
-rw-r--r--doc/classes/Object.xml250
-rw-r--r--doc/classes/OptionButton.xml12
-rw-r--r--doc/classes/PackedByteArray.xml14
-rw-r--r--doc/classes/PackedColorArray.xml14
-rw-r--r--doc/classes/PackedFloat32Array.xml14
-rw-r--r--doc/classes/PackedFloat64Array.xml14
-rw-r--r--doc/classes/PackedInt32Array.xml14
-rw-r--r--doc/classes/PackedInt64Array.xml14
-rw-r--r--doc/classes/PackedScene.xml2
-rw-r--r--doc/classes/PackedSceneGLTF.xml58
-rw-r--r--doc/classes/PackedStringArray.xml14
-rw-r--r--doc/classes/PackedVector2Array.xml14
-rw-r--r--doc/classes/PackedVector3Array.xml14
-rw-r--r--doc/classes/PhysicsDirectSpaceState2D.xml5
-rw-r--r--doc/classes/PhysicsDirectSpaceState3D.xml5
-rw-r--r--doc/classes/PhysicsServer2D.xml106
-rw-r--r--doc/classes/PhysicsServer3D.xml216
-rw-r--r--doc/classes/Plane.xml2
-rw-r--r--doc/classes/PopupMenu.xml26
-rw-r--r--doc/classes/ProgressBar.xml8
-rw-r--r--doc/classes/ProjectSettings.xml863
-rw-r--r--doc/classes/Quat.xml2
-rw-r--r--doc/classes/RayCast3D.xml7
-rw-r--r--doc/classes/Rect2.xml33
-rw-r--r--doc/classes/Rect2i.xml33
-rw-r--r--doc/classes/RectangleShape2D.xml4
-rw-r--r--doc/classes/Reference.xml2
-rw-r--r--doc/classes/ReflectionProbe.xml2
-rw-r--r--doc/classes/RenderingDevice.xml134
-rw-r--r--doc/classes/RenderingServer.xml54
-rw-r--r--doc/classes/Resource.xml17
-rw-r--r--doc/classes/ResourceFormatLoader.xml11
-rw-r--r--doc/classes/ResourceLoader.xml10
-rw-r--r--doc/classes/RichTextEffect.xml10
-rw-r--r--doc/classes/RichTextLabel.xml85
-rw-r--r--doc/classes/RigidBody2D.xml18
-rw-r--r--doc/classes/RigidBody3D.xml22
-rw-r--r--doc/classes/SceneTree.xml52
-rw-r--r--doc/classes/SceneTreeTimer.xml14
-rw-r--r--doc/classes/ScriptCreateDialog.xml20
-rw-r--r--doc/classes/ScriptEditor.xml6
-rw-r--r--doc/classes/ScriptEditorBase.xml11
-rw-r--r--doc/classes/Shape3D.xml3
-rw-r--r--doc/classes/Sky.xml6
-rw-r--r--doc/classes/SoftBody3D.xml12
-rw-r--r--doc/classes/SpinBox.xml14
-rw-r--r--doc/classes/Sprite2D.xml23
-rw-r--r--doc/classes/SpriteBase3D.xml2
-rw-r--r--doc/classes/StreamPeer.xml18
-rw-r--r--doc/classes/String.xml188
-rw-r--r--doc/classes/StyleBox.xml6
-rw-r--r--doc/classes/StyleBoxFlat.xml16
-rw-r--r--doc/classes/StyleBoxTexture.xml8
-rw-r--r--doc/classes/SurfaceTool.xml57
-rw-r--r--doc/classes/SyntaxHighlighter.xml37
-rw-r--r--doc/classes/TabContainer.xml30
-rw-r--r--doc/classes/Tabs.xml26
-rw-r--r--doc/classes/TextEdit.xml32
-rw-r--r--doc/classes/TextParagraph.xml90
-rw-r--r--doc/classes/TextServer.xml100
-rw-r--r--doc/classes/TextureProgressBar.xml4
-rw-r--r--doc/classes/Theme.xml4
-rw-r--r--doc/classes/TileMap.xml20
-rw-r--r--doc/classes/Timer.xml8
-rw-r--r--doc/classes/TouchScreenButton.xml7
-rw-r--r--doc/classes/Transform.xml2
-rw-r--r--doc/classes/Tree.xml60
-rw-r--r--doc/classes/TreeItem.xml12
-rw-r--r--doc/classes/Tween.xml13
-rw-r--r--doc/classes/UDPServer.xml86
-rw-r--r--doc/classes/UndoRedo.xml64
-rw-r--r--doc/classes/Variant.xml2
-rw-r--r--doc/classes/Vector2.xml28
-rw-r--r--doc/classes/Vector3.xml23
-rw-r--r--doc/classes/VideoPlayer.xml1
-rw-r--r--doc/classes/Viewport.xml20
-rw-r--r--doc/classes/VisualShader.xml13
-rw-r--r--doc/classes/VisualShaderNodeBooleanConstant.xml2
-rw-r--r--doc/classes/VisualShaderNodeClamp.xml32
-rw-r--r--doc/classes/VisualShaderNodeColorConstant.xml2
-rw-r--r--doc/classes/VisualShaderNodeConstant.xml14
-rw-r--r--doc/classes/VisualShaderNodeCubemap.xml2
-rw-r--r--doc/classes/VisualShaderNodeFloatConstant.xml2
-rw-r--r--doc/classes/VisualShaderNodeIntConstant.xml2
-rw-r--r--doc/classes/VisualShaderNodeIntFunc.xml9
-rw-r--r--doc/classes/VisualShaderNodeMix.xml32
-rw-r--r--doc/classes/VisualShaderNodeSDFRaymarch.xml15
-rw-r--r--doc/classes/VisualShaderNodeSDFToScreenUV.xml15
-rw-r--r--doc/classes/VisualShaderNodeScalarClamp.xml15
-rw-r--r--doc/classes/VisualShaderNodeScalarInterp.xml15
-rw-r--r--doc/classes/VisualShaderNodeScalarSmoothStep.xml16
-rw-r--r--doc/classes/VisualShaderNodeScalarSwitch.xml15
-rw-r--r--doc/classes/VisualShaderNodeScreenUVToSDF.xml15
-rw-r--r--doc/classes/VisualShaderNodeSmoothStep.xml33
-rw-r--r--doc/classes/VisualShaderNodeStep.xml33
-rw-r--r--doc/classes/VisualShaderNodeSwitch.xml27
-rw-r--r--doc/classes/VisualShaderNodeTexture.xml2
-rw-r--r--doc/classes/VisualShaderNodeTextureSDF.xml15
-rw-r--r--doc/classes/VisualShaderNodeTextureSDFNormal.xml15
-rw-r--r--doc/classes/VisualShaderNodeTextureUniform.xml2
-rw-r--r--doc/classes/VisualShaderNodeTransformConstant.xml2
-rw-r--r--doc/classes/VisualShaderNodeVec3Constant.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorClamp.xml15
-rw-r--r--doc/classes/VisualShaderNodeVectorInterp.xml15
-rw-r--r--doc/classes/VisualShaderNodeVectorScalarMix.xml15
-rw-r--r--doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml16
-rw-r--r--doc/classes/VisualShaderNodeVectorScalarStep.xml16
-rw-r--r--doc/classes/VisualShaderNodeVectorSmoothStep.xml16
-rw-r--r--doc/classes/WeakRef.xml2
-rw-r--r--doc/classes/Window.xml13
-rw-r--r--doc/classes/World2D.xml3
-rw-r--r--doc/classes/World3D.xml3
-rw-r--r--doc/classes/XRController3D.xml14
-rw-r--r--doc/classes/XRPositionalTracker.xml32
-rwxr-xr-xdoc/tools/makerst.py15
-rw-r--r--doc/translations/README.md1
-rw-r--r--doc/translations/ar.po4
-rw-r--r--doc/translations/ca.po4
-rw-r--r--doc/translations/classes.pot4
-rw-r--r--doc/translations/cs.po4
-rw-r--r--doc/translations/de.po4
-rw-r--r--doc/translations/es.po4
-rw-r--r--doc/translations/extract.py4
-rw-r--r--doc/translations/fa.po4
-rw-r--r--doc/translations/fi.po4
-rw-r--r--doc/translations/fr.po4
-rw-r--r--doc/translations/id.po4
-rw-r--r--doc/translations/it.po4
-rw-r--r--doc/translations/ja.po4
-rw-r--r--doc/translations/ko.po4
-rw-r--r--doc/translations/nl.po4
-rw-r--r--doc/translations/pl.po4
-rw-r--r--doc/translations/pt_BR.po4
-rw-r--r--doc/translations/ro.po4
-rw-r--r--doc/translations/ru.po4
-rw-r--r--doc/translations/sr_Cyrl.po4
-rw-r--r--doc/translations/th.po4
-rw-r--r--doc/translations/tr.po4
-rw-r--r--doc/translations/uk.po4
-rw-r--r--doc/translations/zh_Hans.po4
-rw-r--r--doc/translations/zh_Hant.po4
-rw-r--r--drivers/alsa/SCsub3
-rw-r--r--drivers/alsa/asound-so_wrap.c14092
-rw-r--r--drivers/alsa/asound-so_wrap.h5134
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp46
-rw-r--r--drivers/alsa/audio_driver_alsa.h8
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.cpp17
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.h8
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp12
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h4
-rw-r--r--drivers/coremidi/midi_driver_coremidi.cpp4
-rw-r--r--drivers/coremidi/midi_driver_coremidi.h4
-rw-r--r--drivers/dummy/rasterizer_dummy.h513
-rw-r--r--drivers/dummy/texture_loader_dummy.cpp6
-rw-r--r--drivers/dummy/texture_loader_dummy.h6
-rw-r--r--drivers/png/image_loader_png.cpp4
-rw-r--r--drivers/png/image_loader_png.h4
-rw-r--r--drivers/png/png_driver_common.cpp4
-rw-r--r--drivers/png/png_driver_common.h4
-rw-r--r--drivers/png/resource_saver_png.cpp4
-rw-r--r--drivers/png/resource_saver_png.h4
-rw-r--r--drivers/pulseaudio/SCsub3
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp33
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h8
-rw-r--r--drivers/pulseaudio/pulse-so_wrap.c3950
-rw-r--r--drivers/pulseaudio/pulse-so_wrap.h1446
-rw-r--r--drivers/register_driver_types.cpp4
-rw-r--r--drivers/register_driver_types.h4
-rw-r--r--drivers/unix/dir_access_unix.cpp6
-rw-r--r--drivers/unix/dir_access_unix.h4
-rw-r--r--drivers/unix/file_access_unix.cpp4
-rw-r--r--drivers/unix/file_access_unix.h4
-rw-r--r--drivers/unix/ip_unix.cpp4
-rw-r--r--drivers/unix/ip_unix.h4
-rw-r--r--drivers/unix/net_socket_posix.cpp4
-rw-r--r--drivers/unix/net_socket_posix.h4
-rw-r--r--drivers/unix/os_unix.cpp107
-rw-r--r--drivers/unix/os_unix.h7
-rw-r--r--drivers/unix/rw_lock_posix.cpp93
-rw-r--r--drivers/unix/rw_lock_posix.h62
-rw-r--r--drivers/unix/syslog_logger.cpp4
-rw-r--r--drivers/unix/syslog_logger.h4
-rw-r--r--drivers/unix/thread_posix.cpp100
-rw-r--r--drivers/unix/thread_posix.h42
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp811
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h56
-rw-r--r--drivers/vulkan/vulkan_context.cpp138
-rw-r--r--drivers/vulkan/vulkan_context.h19
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp17
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h6
-rw-r--r--drivers/windows/dir_access_windows.cpp4
-rw-r--r--drivers/windows/dir_access_windows.h4
-rw-r--r--drivers/windows/file_access_windows.cpp4
-rw-r--r--drivers/windows/file_access_windows.h4
-rw-r--r--drivers/windows/rw_lock_windows.h63
-rw-r--r--drivers/windows/thread_windows.cpp88
-rw-r--r--drivers/windows/thread_windows.h67
-rw-r--r--drivers/winmidi/midi_driver_winmidi.cpp4
-rw-r--r--drivers/winmidi/midi_driver_winmidi.h4
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.cpp22
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.h6
-rw-r--r--editor/action_map_editor.cpp1167
-rw-r--r--editor/action_map_editor.h203
-rw-r--r--editor/animation_bezier_editor.cpp12
-rw-r--r--editor/animation_bezier_editor.h4
-rw-r--r--editor/animation_track_editor.cpp43
-rw-r--r--editor/animation_track_editor.h6
-rw-r--r--editor/animation_track_editor_plugins.cpp4
-rw-r--r--editor/animation_track_editor_plugins.h4
-rw-r--r--editor/array_property_edit.cpp17
-rw-r--r--editor/array_property_edit.h5
-rw-r--r--editor/audio_stream_preview.cpp16
-rw-r--r--editor/audio_stream_preview.h18
-rw-r--r--editor/code_editor.cpp12
-rw-r--r--editor/code_editor.h4
-rw-r--r--editor/connections_dialog.cpp8
-rw-r--r--editor/connections_dialog.h4
-rw-r--r--editor/create_dialog.cpp21
-rw-r--r--editor/create_dialog.h6
-rw-r--r--editor/debugger/editor_debugger_inspector.cpp4
-rw-r--r--editor/debugger/editor_debugger_inspector.h6
-rw-r--r--editor/debugger/editor_debugger_node.cpp8
-rw-r--r--editor/debugger/editor_debugger_node.h4
-rw-r--r--editor/debugger/editor_debugger_server.cpp4
-rw-r--r--editor/debugger/editor_debugger_server.h4
-rw-r--r--editor/debugger/editor_debugger_tree.cpp21
-rw-r--r--editor/debugger/editor_debugger_tree.h5
-rw-r--r--editor/debugger/editor_network_profiler.cpp12
-rw-r--r--editor/debugger/editor_network_profiler.h4
-rw-r--r--editor/debugger/editor_performance_profiler.cpp8
-rw-r--r--editor/debugger/editor_performance_profiler.h4
-rw-r--r--editor/debugger/editor_profiler.cpp6
-rw-r--r--editor/debugger/editor_profiler.h4
-rw-r--r--editor/debugger/editor_visual_profiler.cpp6
-rw-r--r--editor/debugger/editor_visual_profiler.h4
-rw-r--r--editor/debugger/script_editor_debugger.cpp18
-rw-r--r--editor/debugger/script_editor_debugger.h4
-rw-r--r--editor/dependency_editor.cpp16
-rw-r--r--editor/dependency_editor.h8
-rw-r--r--editor/dictionary_property_edit.cpp15
-rw-r--r--editor/dictionary_property_edit.h5
-rw-r--r--editor/doc_tools.cpp8
-rw-r--r--editor/doc_tools.h4
-rw-r--r--editor/editor_about.cpp6
-rw-r--r--editor/editor_about.h4
-rw-r--r--editor/editor_asset_installer.cpp4
-rw-r--r--editor/editor_asset_installer.h4
-rw-r--r--editor/editor_atlas_packer.cpp4
-rw-r--r--editor/editor_atlas_packer.h4
-rw-r--r--editor/editor_audio_buses.cpp22
-rw-r--r--editor/editor_audio_buses.h4
-rw-r--r--editor/editor_autoload_settings.cpp8
-rw-r--r--editor/editor_autoload_settings.h4
-rw-r--r--editor/editor_data.cpp75
-rw-r--r--editor/editor_data.h12
-rw-r--r--editor/editor_dir_dialog.cpp4
-rw-r--r--editor/editor_dir_dialog.h4
-rw-r--r--editor/editor_export.cpp119
-rw-r--r--editor/editor_export.h4
-rw-r--r--editor/editor_feature_profile.cpp12
-rw-r--r--editor/editor_feature_profile.h4
-rw-r--r--editor/editor_file_dialog.cpp53
-rw-r--r--editor/editor_file_dialog.h5
-rw-r--r--editor/editor_file_system.cpp82
-rw-r--r--editor/editor_file_system.h13
-rw-r--r--editor/editor_folding.cpp20
-rw-r--r--editor/editor_folding.h4
-rw-r--r--editor/editor_fonts.cpp4
-rw-r--r--editor/editor_fonts.h4
-rw-r--r--editor/editor_help.cpp87
-rw-r--r--editor/editor_help.h4
-rw-r--r--editor/editor_help_search.cpp4
-rw-r--r--editor/editor_help_search.h4
-rw-r--r--editor/editor_inspector.cpp185
-rw-r--r--editor/editor_inspector.h20
-rw-r--r--editor/editor_layouts_dialog.cpp6
-rw-r--r--editor/editor_layouts_dialog.h4
-rw-r--r--editor/editor_log.cpp9
-rw-r--r--editor/editor_log.h4
-rw-r--r--editor/editor_native_shader_source_visualizer.cpp (renamed from modules/arkit/arkit_session_delegate.mm)58
-rw-r--r--editor/editor_native_shader_source_visualizer.h (renamed from modules/icloud/icloud.h)40
-rw-r--r--editor/editor_node.cpp456
-rw-r--r--editor/editor_node.h36
-rw-r--r--editor/editor_path.cpp4
-rw-r--r--editor/editor_path.h4
-rw-r--r--editor/editor_plugin.cpp26
-rw-r--r--editor/editor_plugin.h10
-rw-r--r--editor/editor_plugin_settings.cpp70
-rw-r--r--editor/editor_plugin_settings.h6
-rw-r--r--editor/editor_properties.cpp142
-rw-r--r--editor/editor_properties.h12
-rw-r--r--editor/editor_properties_array_dict.cpp12
-rw-r--r--editor/editor_properties_array_dict.h12
-rw-r--r--editor/editor_resource_preview.cpp27
-rw-r--r--editor/editor_resource_preview.h11
-rw-r--r--editor/editor_run.cpp6
-rw-r--r--editor/editor_run.h4
-rw-r--r--editor/editor_run_native.cpp6
-rw-r--r--editor/editor_run_native.h4
-rw-r--r--editor/editor_run_script.cpp4
-rw-r--r--editor/editor_run_script.h4
-rw-r--r--editor/editor_scale.cpp4
-rw-r--r--editor/editor_scale.h4
-rw-r--r--editor/editor_sectioned_inspector.cpp18
-rw-r--r--editor/editor_sectioned_inspector.h7
-rw-r--r--editor/editor_settings.cpp241
-rw-r--r--editor/editor_settings.h11
-rw-r--r--editor/editor_spin_slider.cpp4
-rw-r--r--editor/editor_spin_slider.h4
-rw-r--r--editor/editor_sub_scene.cpp265
-rw-r--r--editor/editor_themes.cpp245
-rw-r--r--editor/editor_themes.h4
-rw-r--r--editor/editor_translation_parser.cpp4
-rw-r--r--editor/editor_translation_parser.h4
-rw-r--r--editor/editor_vcs_interface.cpp4
-rw-r--r--editor/editor_vcs_interface.h4
-rw-r--r--editor/export_template_manager.cpp4
-rw-r--r--editor/export_template_manager.h4
-rw-r--r--editor/fileserver/editor_file_server.cpp15
-rw-r--r--editor/fileserver/editor_file_server.h8
-rw-r--r--editor/filesystem_dock.cpp74
-rw-r--r--editor/filesystem_dock.h4
-rw-r--r--editor/find_in_files.cpp13
-rw-r--r--editor/find_in_files.h4
-rw-r--r--editor/groups_editor.cpp8
-rw-r--r--editor/groups_editor.h4
-rw-r--r--editor/icons/ColorPickerBarArrow.svg1
-rw-r--r--editor/icons/GPUParticlesAttractorBox.svg1
-rw-r--r--editor/icons/GPUParticlesAttractorSphere.svg1
-rw-r--r--editor/icons/GPUParticlesAttractorVectorField.svg1
-rw-r--r--editor/icons/GPUParticlesCollisionBox.svg1
-rw-r--r--editor/icons/GPUParticlesCollisionHeightField.svg1
-rw-r--r--editor/icons/GPUParticlesCollisionSDF.svg1
-rw-r--r--editor/icons/GPUParticlesCollisionSphere.svg1
-rw-r--r--editor/icons/Logo.svg2
-rw-r--r--editor/icons/NodeDisabled.svg1
-rw-r--r--editor/import/collada.cpp12
-rw-r--r--editor/import/collada.h6
-rw-r--r--editor/import/editor_import_collada.cpp8
-rw-r--r--editor/import/editor_import_collada.h4
-rw-r--r--editor/import/editor_import_plugin.cpp4
-rw-r--r--editor/import/editor_import_plugin.h4
-rw-r--r--editor/import/resource_importer_bitmask.cpp4
-rw-r--r--editor/import/resource_importer_bitmask.h4
-rw-r--r--editor/import/resource_importer_csv.cpp4
-rw-r--r--editor/import/resource_importer_csv.h4
-rw-r--r--editor/import/resource_importer_csv_translation.cpp4
-rw-r--r--editor/import/resource_importer_csv_translation.h4
-rw-r--r--editor/import/resource_importer_image.cpp4
-rw-r--r--editor/import/resource_importer_image.h4
-rw-r--r--editor/import/resource_importer_layered_texture.cpp18
-rw-r--r--editor/import/resource_importer_layered_texture.h34
-rw-r--r--editor/import/resource_importer_obj.cpp4
-rw-r--r--editor/import/resource_importer_obj.h4
-rw-r--r--editor/import/resource_importer_scene.cpp28
-rw-r--r--editor/import/resource_importer_scene.h6
-rw-r--r--editor/import/resource_importer_shader_file.cpp4
-rw-r--r--editor/import/resource_importer_shader_file.h4
-rw-r--r--editor/import/resource_importer_texture.cpp24
-rw-r--r--editor/import/resource_importer_texture.h6
-rw-r--r--editor/import/resource_importer_texture_atlas.cpp4
-rw-r--r--editor/import/resource_importer_texture_atlas.h4
-rw-r--r--editor/import/resource_importer_wav.cpp4
-rw-r--r--editor/import/resource_importer_wav.h4
-rw-r--r--editor/import/scene_importer_mesh.cpp154
-rw-r--r--editor/import/scene_importer_mesh.h9
-rw-r--r--editor/import/scene_importer_mesh_node_3d.cpp4
-rw-r--r--editor/import/scene_importer_mesh_node_3d.h4
-rw-r--r--editor/import_defaults_editor.cpp216
-rw-r--r--editor/import_defaults_editor.h (renamed from editor/editor_sub_scene.h)62
-rw-r--r--editor/import_dock.cpp8
-rw-r--r--editor/import_dock.h4
-rw-r--r--editor/input_map_editor.cpp1033
-rw-r--r--editor/input_map_editor.h109
-rw-r--r--editor/inspector_dock.cpp11
-rw-r--r--editor/inspector_dock.h4
-rw-r--r--editor/localization_editor.cpp171
-rw-r--r--editor/localization_editor.h12
-rw-r--r--editor/multi_node_edit.cpp4
-rw-r--r--editor/multi_node_edit.h4
-rw-r--r--editor/node_3d_editor_gizmos.cpp196
-rw-r--r--editor/node_3d_editor_gizmos.h16
-rw-r--r--editor/node_dock.cpp4
-rw-r--r--editor/node_dock.h4
-rw-r--r--editor/plugin_config_dialog.cpp12
-rw-r--r--editor/plugin_config_dialog.h6
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp4
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h4
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.cpp12
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.h4
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp24
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h4
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp13
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp15
-rw-r--r--editor/plugins/animation_player_editor_plugin.h4
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp8
-rw-r--r--editor/plugins/animation_state_machine_editor.h4
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp4
-rw-r--r--editor/plugins/animation_tree_editor_plugin.h4
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp46
-rw-r--r--editor/plugins/asset_library_editor_plugin.h4
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp10
-rw-r--r--editor/plugins/audio_stream_editor_plugin.h7
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.cpp4
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.h4
-rw-r--r--editor/plugins/camera_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/camera_3d_editor_plugin.h4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp240
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h14
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.h4
-rw-r--r--editor/plugins/collision_polygon_3d_editor_plugin.cpp4
-rw-r--r--editor/plugins/collision_polygon_3d_editor_plugin.h4
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp22
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.h4
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.h4
-rw-r--r--editor/plugins/cpu_particles_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/cpu_particles_3d_editor_plugin.h4
-rw-r--r--editor/plugins/curve_editor_plugin.cpp8
-rw-r--r--editor/plugins/curve_editor_plugin.h4
-rw-r--r--editor/plugins/debugger_editor_plugin.cpp4
-rw-r--r--editor/plugins/debugger_editor_plugin.h4
-rw-r--r--editor/plugins/editor_debugger_plugin.cpp4
-rw-r--r--editor/plugins/editor_debugger_plugin.h4
-rw-r--r--editor/plugins/editor_preview_plugins.cpp38
-rw-r--r--editor/plugins/editor_preview_plugins.h12
-rw-r--r--editor/plugins/font_editor_plugin.cpp6
-rw-r--r--editor/plugins/font_editor_plugin.h4
-rw-r--r--editor/plugins/gi_probe_editor_plugin.cpp4
-rw-r--r--editor/plugins/gi_probe_editor_plugin.h4
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.h4
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.cpp8
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.h4
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp4
-rw-r--r--editor/plugins/gpu_particles_collision_sdf_editor_plugin.h4
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp4
-rw-r--r--editor/plugins/gradient_editor_plugin.h4
-rw-r--r--editor/plugins/item_list_editor_plugin.cpp16
-rw-r--r--editor/plugins/item_list_editor_plugin.h4
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h4
-rw-r--r--editor/plugins/line_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/line_2d_editor_plugin.h4
-rw-r--r--editor/plugins/material_editor_plugin.cpp4
-rw-r--r--editor/plugins/material_editor_plugin.h4
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp4
-rw-r--r--editor/plugins/mesh_editor_plugin.h4
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp8
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.h4
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp6
-rw-r--r--editor/plugins/mesh_library_editor_plugin.h4
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp6
-rw-r--r--editor/plugins/multimesh_editor_plugin.h4
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.cpp4
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.h4
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp935
-rw-r--r--editor/plugins/node_3d_editor_plugin.h77
-rw-r--r--editor/plugins/ot_features_plugin.cpp4
-rw-r--r--editor/plugins/ot_features_plugin.h4
-rw-r--r--editor/plugins/packed_scene_translation_parser_plugin.cpp10
-rw-r--r--editor/plugins/packed_scene_translation_parser_plugin.h4
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/path_2d_editor_plugin.h4
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/path_3d_editor_plugin.h4
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.cpp4
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.h4
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp10
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h4
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp4
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.h4
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp4
-rw-r--r--editor/plugins/root_motion_editor_plugin.h4
-rw-r--r--editor/plugins/script_editor_plugin.cpp57
-rw-r--r--editor/plugins/script_editor_plugin.h6
-rw-r--r--editor/plugins/script_text_editor.cpp52
-rw-r--r--editor/plugins/script_text_editor.h4
-rw-r--r--editor/plugins/shader_editor_plugin.cpp40
-rw-r--r--editor/plugins/shader_editor_plugin.h4
-rw-r--r--editor/plugins/shader_file_editor_plugin.cpp8
-rw-r--r--editor/plugins/shader_file_editor_plugin.h4
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.h4
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp12
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.h4
-rw-r--r--editor/plugins/skeleton_ik_3d_editor_plugin.cpp4
-rw-r--r--editor/plugins/skeleton_ik_3d_editor_plugin.h4
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.cpp17
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.h4
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp13
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h4
-rw-r--r--editor/plugins/style_box_editor_plugin.cpp4
-rw-r--r--editor/plugins/style_box_editor_plugin.h4
-rw-r--r--editor/plugins/text_editor.cpp38
-rw-r--r--editor/plugins/text_editor.h4
-rw-r--r--editor/plugins/texture_3d_editor_plugin.cpp15
-rw-r--r--editor/plugins/texture_3d_editor_plugin.h8
-rw-r--r--editor/plugins/texture_editor_plugin.cpp12
-rw-r--r--editor/plugins/texture_editor_plugin.h6
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp16
-rw-r--r--editor/plugins/texture_layered_editor_plugin.h7
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp81
-rw-r--r--editor/plugins/texture_region_editor_plugin.h8
-rw-r--r--editor/plugins/theme_editor_plugin.cpp4
-rw-r--r--editor/plugins/theme_editor_plugin.h4
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp32
-rw-r--r--editor/plugins/tile_map_editor_plugin.h4
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp25
-rw-r--r--editor/plugins/tile_set_editor_plugin.h4
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp4
-rw-r--r--editor/plugins/version_control_editor_plugin.h4
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp723
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h25
-rw-r--r--editor/pot_generator.cpp16
-rw-r--r--editor/pot_generator.h4
-rw-r--r--editor/progress_dialog.cpp8
-rw-r--r--editor/progress_dialog.h4
-rw-r--r--editor/project_export.cpp14
-rw-r--r--editor/project_export.h4
-rw-r--r--editor/project_manager.cpp102
-rw-r--r--editor/project_manager.h6
-rw-r--r--editor/project_settings_editor.cpp279
-rw-r--r--editor/project_settings_editor.h29
-rw-r--r--editor/property_editor.cpp55
-rw-r--r--editor/property_editor.h4
-rw-r--r--editor/property_selector.cpp4
-rw-r--r--editor/property_selector.h4
-rw-r--r--editor/quick_open.cpp4
-rw-r--r--editor/quick_open.h4
-rw-r--r--editor/register_exporters.h4
-rw-r--r--editor/rename_dialog.cpp6
-rw-r--r--editor/rename_dialog.h4
-rw-r--r--editor/reparent_dialog.cpp4
-rw-r--r--editor/reparent_dialog.h4
-rw-r--r--editor/scene_tree_dock.cpp384
-rw-r--r--editor/scene_tree_dock.h27
-rw-r--r--editor/scene_tree_editor.cpp52
-rw-r--r--editor/scene_tree_editor.h9
-rw-r--r--editor/script_create_dialog.cpp8
-rw-r--r--editor/script_create_dialog.h4
-rw-r--r--editor/settings_config_dialog.cpp352
-rw-r--r--editor/settings_config_dialog.h37
-rw-r--r--editor/shader_globals_editor.cpp9
-rw-r--r--editor/shader_globals_editor.h4
-rw-r--r--editor/translations/af.po288
-rw-r--r--editor/translations/ar.po389
-rw-r--r--editor/translations/bg.po1000
-rw-r--r--editor/translations/bn.po446
-rw-r--r--editor/translations/br.po12481
-rw-r--r--editor/translations/ca.po381
-rw-r--r--editor/translations/cs.po424
-rw-r--r--editor/translations/da.po480
-rw-r--r--editor/translations/de.po455
-rw-r--r--editor/translations/editor.pot272
-rw-r--r--editor/translations/el.po396
-rw-r--r--editor/translations/eo.po300
-rw-r--r--editor/translations/es.po567
-rw-r--r--editor/translations/es_AR.po432
-rw-r--r--editor/translations/et.po429
-rw-r--r--editor/translations/eu.po278
-rwxr-xr-xeditor/translations/extract.py4
-rw-r--r--editor/translations/fa.po303
-rw-r--r--editor/translations/fi.po409
-rw-r--r--editor/translations/fil.po274
-rw-r--r--editor/translations/fr.po417
-rw-r--r--editor/translations/ga.po270
-rw-r--r--editor/translations/gl.po12861
-rw-r--r--editor/translations/he.po391
-rw-r--r--editor/translations/hi.po439
-rw-r--r--editor/translations/hr.po281
-rw-r--r--editor/translations/hu.po333
-rw-r--r--editor/translations/id.po462
-rw-r--r--editor/translations/is.po273
-rw-r--r--editor/translations/it.po711
-rw-r--r--editor/translations/ja.po448
-rw-r--r--editor/translations/ka.po281
-rw-r--r--editor/translations/ko.po581
-rw-r--r--editor/translations/lt.po289
-rw-r--r--editor/translations/lv.po284
-rw-r--r--editor/translations/mi.po272
-rw-r--r--editor/translations/mk.po12464
-rw-r--r--editor/translations/ml.po270
-rw-r--r--editor/translations/mr.po282
-rw-r--r--editor/translations/ms.po878
-rw-r--r--editor/translations/nb.po803
-rw-r--r--editor/translations/nl.po529
-rw-r--r--editor/translations/or.po270
-rw-r--r--editor/translations/pl.po430
-rw-r--r--editor/translations/pr.po277
-rw-r--r--editor/translations/pt.po580
-rw-r--r--editor/translations/pt_BR.po449
-rw-r--r--editor/translations/ro.po327
-rw-r--r--editor/translations/ru.po451
-rw-r--r--editor/translations/si.po291
-rw-r--r--editor/translations/sk.po315
-rw-r--r--editor/translations/sl.po323
-rw-r--r--editor/translations/sq.po303
-rw-r--r--editor/translations/sr_Cyrl.po381
-rw-r--r--editor/translations/sr_Latn.po274
-rw-r--r--editor/translations/sv.po311
-rw-r--r--editor/translations/ta.po273
-rw-r--r--editor/translations/te.po270
-rw-r--r--editor/translations/th.po406
-rw-r--r--editor/translations/tr.po420
-rw-r--r--editor/translations/tzm.po270
-rw-r--r--editor/translations/uk.po412
-rw-r--r--editor/translations/ur_PK.po277
-rw-r--r--editor/translations/vi.po447
-rw-r--r--editor/translations/zh_CN.po421
-rw-r--r--editor/translations/zh_HK.po308
-rw-r--r--editor/translations/zh_TW.po385
-rw-r--r--main/main.cpp475
-rw-r--r--main/main.h6
-rw-r--r--main/main_timer_sync.cpp76
-rw-r--r--main/main_timer_sync.h22
-rw-r--r--main/performance.cpp6
-rw-r--r--main/performance.h4
-rw-r--r--methods.py99
-rw-r--r--misc/dist/html/editor.html232
-rw-r--r--misc/dist/html/full-size.html75
-rw-r--r--misc/dist/html/manifest.json18
-rw-r--r--misc/dist/html/offline.html42
-rw-r--r--misc/dist/html/service-worker.js84
-rw-r--r--misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj16
-rw-r--r--misc/dist/ios_xcode/godot_ios/dummy.cpp4
-rw-r--r--misc/dist/ios_xcode/libgodot.iphone.debug.fat.a0
-rw-r--r--misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist40
-rw-r--r--misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty1
-rw-r--r--misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty1
-rw-r--r--misc/dist/ios_xcode/libgodot.iphone.release.fat.a0
-rw-r--r--misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist40
-rw-r--r--misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty1
-rw-r--r--misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty1
-rw-r--r--misc/dist/linux/org.godotengine.Godot.appdata.xml2
-rw-r--r--misc/dist/linux/org.godotengine.Godot.xml29
-rw-r--r--misc/dist/linux/x-godot-project.xml8
-rw-r--r--[-rwxr-xr-x]misc/dist/osx_template.app/Contents/Info.plist0
-rw-r--r--[-rwxr-xr-x]misc/dist/osx_tools.app/Contents/Info.plist4
-rw-r--r--misc/dist/project_icon.svg2
-rw-r--r--misc/dist/shell/_godot.zsh-completion4
-rw-r--r--misc/dist/shell/godot.bash-completion4
-rw-r--r--misc/dist/shell/godot.fish4
-rwxr-xr-xmisc/hooks/pre-commit-clang-format25
-rw-r--r--[-rwxr-xr-x]misc/hooks/winmessage.ps10
-rwxr-xr-xmisc/scripts/clang_format.sh2
-rwxr-xr-xmisc/scripts/copyright_headers.py4
-rwxr-xr-xmisc/scripts/file_format.sh11
-rw-r--r--modules/SCsub12
-rw-r--r--modules/arkit/SCsub15
-rw-r--r--modules/arkit/arkit.gdip18
-rw-r--r--modules/arkit/arkit_interface.mm791
-rw-r--r--modules/arkit/arkit_module.h37
-rw-r--r--modules/arkit/config.py6
-rw-r--r--modules/basis_universal/register_types.cpp6
-rw-r--r--modules/basis_universal/register_types.h4
-rw-r--r--modules/basis_universal/texture_basisu.cpp5
-rw-r--r--modules/basis_universal/texture_basisu.h6
-rw-r--r--modules/bmp/image_loader_bmp.cpp4
-rw-r--r--modules/bmp/image_loader_bmp.h34
-rw-r--r--modules/bmp/register_types.cpp4
-rw-r--r--modules/bmp/register_types.h4
-rw-r--r--modules/bullet/area_bullet.cpp4
-rw-r--r--modules/bullet/area_bullet.h14
-rw-r--r--modules/bullet/btRayShape.cpp8
-rw-r--r--modules/bullet/btRayShape.h10
-rw-r--r--modules/bullet/bullet_physics_server.cpp44
-rw-r--r--modules/bullet/bullet_physics_server.h40
-rw-r--r--modules/bullet/bullet_types_converter.cpp4
-rw-r--r--modules/bullet/bullet_types_converter.h4
-rw-r--r--modules/bullet/bullet_utilities.h4
-rw-r--r--modules/bullet/collision_object_bullet.cpp12
-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.h4
-rw-r--r--modules/bullet/config.py3
-rw-r--r--modules/bullet/constraint_bullet.cpp4
-rw-r--r--modules/bullet/constraint_bullet.h4
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp4
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.h4
-rw-r--r--modules/bullet/godot_collision_configuration.cpp4
-rw-r--r--modules/bullet/godot_collision_configuration.h4
-rw-r--r--modules/bullet/godot_collision_dispatcher.cpp4
-rw-r--r--modules/bullet/godot_collision_dispatcher.h4
-rw-r--r--modules/bullet/godot_motion_state.h6
-rw-r--r--modules/bullet/godot_ray_world_algorithm.cpp4
-rw-r--r--modules/bullet/godot_ray_world_algorithm.h6
-rw-r--r--modules/bullet/godot_result_callbacks.cpp4
-rw-r--r--modules/bullet/godot_result_callbacks.h42
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp4
-rw-r--r--modules/bullet/hinge_joint_bullet.h4
-rw-r--r--modules/bullet/joint_bullet.cpp4
-rw-r--r--modules/bullet/joint_bullet.h4
-rw-r--r--modules/bullet/pin_joint_bullet.cpp4
-rw-r--r--modules/bullet/pin_joint_bullet.h4
-rw-r--r--modules/bullet/register_types.cpp4
-rw-r--r--modules/bullet/register_types.h4
-rw-r--r--modules/bullet/rid_bullet.h6
-rw-r--r--modules/bullet/rigid_body_bullet.cpp21
-rw-r--r--modules/bullet/rigid_body_bullet.h36
-rw-r--r--modules/bullet/shape_bullet.cpp14
-rw-r--r--modules/bullet/shape_bullet.h14
-rw-r--r--modules/bullet/shape_owner_bullet.cpp4
-rw-r--r--modules/bullet/shape_owner_bullet.h4
-rw-r--r--modules/bullet/slider_joint_bullet.cpp4
-rw-r--r--modules/bullet/slider_joint_bullet.h4
-rw-r--r--modules/bullet/soft_body_bullet.cpp12
-rw-r--r--modules/bullet/soft_body_bullet.h12
-rw-r--r--modules/bullet/space_bullet.cpp56
-rw-r--r--modules/bullet/space_bullet.h23
-rw-r--r--modules/camera/camera_osx.h4
-rw-r--r--modules/camera/camera_osx.mm4
-rw-r--r--modules/camera/camera_win.cpp4
-rw-r--r--modules/camera/camera_win.h4
-rw-r--r--modules/camera/register_types.cpp4
-rw-r--r--modules/camera/register_types.h4
-rw-r--r--modules/camera_iphone/SCsub15
-rw-r--r--modules/camera_iphone/camera.gdip18
-rw-r--r--modules/camera_iphone/camera_ios.mm445
-rw-r--r--modules/camera_iphone/camera_module.h32
-rw-r--r--modules/camera_iphone/config.py6
-rw-r--r--modules/csg/csg.cpp4
-rw-r--r--modules/csg/csg.h36
-rw-r--r--modules/csg/csg_gizmos.cpp80
-rw-r--r--modules/csg/csg_gizmos.h4
-rw-r--r--modules/csg/csg_shape.cpp130
-rw-r--r--modules/csg/csg_shape.h48
-rw-r--r--modules/csg/doc_classes/CSGBox3D.xml10
-rw-r--r--modules/csg/register_types.cpp4
-rw-r--r--modules/csg/register_types.h4
-rw-r--r--modules/cvtt/image_compress_cvtt.cpp35
-rw-r--r--modules/cvtt/image_compress_cvtt.h4
-rw-r--r--modules/cvtt/register_types.cpp4
-rw-r--r--modules/cvtt/register_types.h4
-rw-r--r--modules/dds/register_types.cpp4
-rw-r--r--modules/dds/register_types.h4
-rw-r--r--modules/dds/texture_loader_dds.cpp16
-rw-r--r--modules/dds/texture_loader_dds.h6
-rw-r--r--modules/denoise/denoise_wrapper.cpp4
-rw-r--r--modules/denoise/denoise_wrapper.h4
-rw-r--r--modules/denoise/lightmap_denoiser.cpp4
-rw-r--r--modules/denoise/lightmap_denoiser.h4
-rw-r--r--modules/denoise/register_types.cpp4
-rw-r--r--modules/denoise/register_types.h4
-rw-r--r--modules/enet/doc_classes/NetworkedMultiplayerENet.xml18
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp29
-rw-r--r--modules/enet/networked_multiplayer_enet.h43
-rw-r--r--modules/enet/register_types.cpp4
-rw-r--r--modules/enet/register_types.h4
-rw-r--r--modules/etc/image_compress_etc.cpp14
-rw-r--r--modules/etc/image_compress_etc.h4
-rw-r--r--modules/etc/register_types.cpp4
-rw-r--r--modules/etc/register_types.h4
-rw-r--r--modules/etc/texture_loader_pkm.cpp16
-rw-r--r--modules/etc/texture_loader_pkm.h6
-rw-r--r--modules/fbx/data/fbx_anim_container.h4
-rw-r--r--modules/fbx/data/fbx_bone.cpp4
-rw-r--r--modules/fbx/data/fbx_bone.h4
-rw-r--r--modules/fbx/data/fbx_material.cpp10
-rw-r--r--modules/fbx/data/fbx_material.h9
-rw-r--r--modules/fbx/data/fbx_mesh_data.cpp72
-rw-r--r--modules/fbx/data/fbx_mesh_data.h4
-rw-r--r--modules/fbx/data/fbx_node.h4
-rw-r--r--modules/fbx/data/fbx_skeleton.cpp4
-rw-r--r--modules/fbx/data/fbx_skeleton.h4
-rw-r--r--modules/fbx/data/import_state.h5
-rw-r--r--modules/fbx/data/model_abstraction.h4
-rw-r--r--modules/fbx/data/pivot_transform.cpp19
-rw-r--r--modules/fbx/data/pivot_transform.h4
-rw-r--r--modules/fbx/doc_classes/EditorSceneImporterFBX.xml2
-rw-r--r--modules/fbx/editor_scene_importer_fbx.cpp27
-rw-r--r--modules/fbx/editor_scene_importer_fbx.h8
-rw-r--r--modules/fbx/fbx_parser/ByteSwapper.h4
-rw-r--r--modules/fbx/fbx_parser/FBXAnimation.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXCommon.h4
-rw-r--r--modules/fbx/fbx_parser/FBXDeformer.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXDocument.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXDocument.h4
-rw-r--r--modules/fbx/fbx_parser/FBXDocumentUtil.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXDocumentUtil.h4
-rw-r--r--modules/fbx/fbx_parser/FBXImportSettings.h4
-rw-r--r--modules/fbx/fbx_parser/FBXMaterial.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXMeshGeometry.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXMeshGeometry.h4
-rw-r--r--modules/fbx/fbx_parser/FBXModel.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXNodeAttribute.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXParseTools.h4
-rw-r--r--modules/fbx/fbx_parser/FBXParser.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXParser.h4
-rw-r--r--modules/fbx/fbx_parser/FBXPose.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXProperties.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXProperties.h4
-rw-r--r--modules/fbx/fbx_parser/FBXTokenizer.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXTokenizer.h4
-rw-r--r--modules/fbx/fbx_parser/FBXUtil.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXUtil.h4
-rw-r--r--modules/fbx/register_types.cpp4
-rw-r--r--modules/fbx/register_types.h4
-rw-r--r--modules/fbx/tools/import_utils.cpp4
-rw-r--r--modules/fbx/tools/import_utils.h4
-rw-r--r--modules/fbx/tools/validation_tools.cpp4
-rw-r--r--modules/fbx/tools/validation_tools.h4
-rw-r--r--modules/freetype/register_types.cpp4
-rw-r--r--modules/freetype/register_types.h4
-rw-r--r--modules/freetype/uwpdef.h4
-rw-r--r--modules/gamecenter/SCsub15
-rw-r--r--modules/gamecenter/config.py6
-rw-r--r--modules/gamecenter/game_center.mm380
-rw-r--r--modules/gamecenter/game_center_delegate.mm45
-rw-r--r--modules/gamecenter/game_center_module.h32
-rw-r--r--modules/gamecenter/gamecenter.gdip17
-rw-r--r--modules/gdnative/android/android_gdn.cpp6
-rw-r--r--modules/gdnative/gdnative.cpp18
-rw-r--r--modules/gdnative/gdnative.h8
-rw-r--r--modules/gdnative/gdnative/aabb.cpp192
-rw-r--r--modules/gdnative/gdnative/array.cpp359
-rw-r--r--modules/gdnative/gdnative/basis.cpp261
-rw-r--r--modules/gdnative/gdnative/callable.cpp211
-rw-r--r--modules/gdnative/gdnative/color.cpp173
-rw-r--r--modules/gdnative/gdnative/dictionary.cpp146
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp13
-rw-r--r--modules/gdnative/gdnative/node_path.cpp86
-rw-r--r--modules/gdnative/gdnative/packed_arrays.cpp1111
-rw-r--r--modules/gdnative/gdnative/plane.cpp136
-rw-r--r--modules/gdnative/gdnative/quat.cpp200
-rw-r--r--modules/gdnative/gdnative/rect2.cpp299
-rw-r--r--modules/gdnative/gdnative/rid.cpp42
-rw-r--r--modules/gdnative/gdnative/signal.cpp (renamed from modules/gamecenter/game_center_module.cpp)33
-rw-r--r--modules/gdnative/gdnative/string.cpp1245
-rw-r--r--modules/gdnative/gdnative/string_name.cpp49
-rw-r--r--modules/gdnative/gdnative/transform.cpp195
-rw-r--r--modules/gdnative/gdnative/transform2d.cpp176
-rw-r--r--modules/gdnative/gdnative/variant.cpp727
-rw-r--r--modules/gdnative/gdnative/vector2.cpp424
-rw-r--r--modules/gdnative/gdnative/vector3.cpp428
-rw-r--r--modules/gdnative/gdnative_api.json13319
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp14
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.h10
-rw-r--r--modules/gdnative/gdnative_library_singleton_editor.cpp4
-rw-r--r--modules/gdnative/gdnative_library_singleton_editor.h4
-rw-r--r--modules/gdnative/include/android/godot_android.h4
-rw-r--r--modules/gdnative/include/gdnative/aabb.h73
-rw-r--r--modules/gdnative/include/gdnative/array.h101
-rw-r--r--modules/gdnative/include/gdnative/basis.h91
-rw-r--r--modules/gdnative/include/gdnative/callable.h74
-rw-r--r--modules/gdnative/include/gdnative/color.h72
-rw-r--r--modules/gdnative/include/gdnative/dictionary.h56
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h31
-rw-r--r--modules/gdnative/include/gdnative/math_defs.h66
-rw-r--r--modules/gdnative/include/gdnative/node_path.h37
-rw-r--r--modules/gdnative/include/gdnative/packed_arrays.h404
-rw-r--r--modules/gdnative/include/gdnative/plane.h54
-rw-r--r--modules/gdnative/include/gdnative/quat.h73
-rw-r--r--modules/gdnative/include/gdnative/rect2.h111
-rw-r--r--modules/gdnative/include/gdnative/rid.h23
-rw-r--r--modules/gdnative/include/gdnative/signal.h58
-rw-r--r--modules/gdnative/include/gdnative/string.h235
-rw-r--r--modules/gdnative/include/gdnative/string_name.h28
-rw-r--r--modules/gdnative/include/gdnative/transform.h64
-rw-r--r--modules/gdnative/include/gdnative/transform2d.h64
-rw-r--r--modules/gdnative/include/gdnative/variant.h234
-rw-r--r--modules/gdnative/include/gdnative/variant_struct.h (renamed from core/os/thread_dummy.cpp)36
-rw-r--r--modules/gdnative/include/gdnative/vector2.h148
-rw-r--r--modules/gdnative/include/gdnative/vector3.h153
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h6
-rw-r--r--modules/gdnative/include/net/godot_net.h4
-rw-r--r--modules/gdnative/include/net/godot_webrtc.h4
-rw-r--r--modules/gdnative/include/pluginscript/godot_pluginscript.h4
-rw-r--r--modules/gdnative/include/text/godot_text.h18
-rw-r--r--modules/gdnative/include/videodecoder/godot_videodecoder.h12
-rw-r--r--modules/gdnative/include/xr/godot_xr.h12
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp458
-rw-r--r--modules/gdnative/nativescript/api_generator.h5
-rw-r--r--modules/gdnative/nativescript/godot_nativescript.cpp4
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp38
-rw-r--r--modules/gdnative/nativescript/nativescript.h41
-rw-r--r--modules/gdnative/nativescript/register_types.cpp4
-rw-r--r--modules/gdnative/nativescript/register_types.h4
-rw-r--r--modules/gdnative/net/multiplayer_peer_gdnative.cpp4
-rw-r--r--modules/gdnative/net/multiplayer_peer_gdnative.h4
-rw-r--r--modules/gdnative/net/packet_peer_gdnative.cpp4
-rw-r--r--modules/gdnative/net/packet_peer_gdnative.h4
-rw-r--r--modules/gdnative/net/register_types.cpp4
-rw-r--r--modules/gdnative/net/register_types.h4
-rw-r--r--modules/gdnative/net/stream_peer_gdnative.cpp4
-rw-r--r--modules/gdnative/net/stream_peer_gdnative.h4
-rw-r--r--modules/gdnative/net/webrtc_gdnative.cpp4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.cpp4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.h10
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.cpp6
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.h4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.cpp6
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.h6
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.h4
-rw-r--r--modules/gdnative/pluginscript/register_types.cpp4
-rw-r--r--modules/gdnative/pluginscript/register_types.h4
-rw-r--r--modules/gdnative/register_types.cpp4
-rw-r--r--modules/gdnative/register_types.h4
-rw-r--r--modules/gdnative/tests/test_string.h1979
-rw-r--r--modules/gdnative/tests/test_variant.h205
-rw-r--r--modules/gdnative/text/register_types.cpp4
-rw-r--r--modules/gdnative/text/register_types.h4
-rw-r--r--modules/gdnative/text/text_server_gdnative.cpp54
-rw-r--r--modules/gdnative/text/text_server_gdnative.h15
-rw-r--r--modules/gdnative/videodecoder/register_types.cpp4
-rw-r--r--modules/gdnative/videodecoder/register_types.h4
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.cpp8
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.h8
-rw-r--r--modules/gdnative/xr/register_types.cpp4
-rw-r--r--modules/gdnative/xr/register_types.h4
-rw-r--r--modules/gdnative/xr/xr_interface_gdnative.cpp14
-rw-r--r--modules/gdnative/xr/xr_interface_gdnative.h4
-rw-r--r--modules/gdnavigation/gd_navigation_server.cpp22
-rw-r--r--modules/gdnavigation/gd_navigation_server.h8
-rw-r--r--modules/gdnavigation/nav_map.cpp18
-rw-r--r--modules/gdnavigation/nav_map.h6
-rw-r--r--modules/gdnavigation/nav_region.cpp12
-rw-r--r--modules/gdnavigation/nav_region.h12
-rw-r--r--modules/gdnavigation/nav_rid.h4
-rw-r--r--modules/gdnavigation/nav_utils.h18
-rw-r--r--modules/gdnavigation/navigation_mesh_editor_plugin.cpp6
-rw-r--r--modules/gdnavigation/navigation_mesh_editor_plugin.h4
-rw-r--r--modules/gdnavigation/navigation_mesh_generator.cpp8
-rw-r--r--modules/gdnavigation/navigation_mesh_generator.h4
-rw-r--r--modules/gdnavigation/register_types.cpp4
-rw-r--r--modules/gdnavigation/register_types.h4
-rw-r--r--modules/gdnavigation/rvo_agent.cpp4
-rw-r--r--modules/gdnavigation/rvo_agent.h6
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml1117
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp18
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.h4
-rw-r--r--modules/gdscript/editor/gdscript_translation_parser_plugin.cpp6
-rw-r--r--modules/gdscript/editor/gdscript_translation_parser_plugin.h8
-rw-r--r--modules/gdscript/gdscript.cpp39
-rw-r--r--modules/gdscript/gdscript.h22
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp57
-rw-r--r--modules/gdscript/gdscript_analyzer.h4
-rw-r--r--modules/gdscript/gdscript_byte_codegen.cpp15
-rw-r--r--modules/gdscript/gdscript_byte_codegen.h5
-rw-r--r--modules/gdscript/gdscript_cache.cpp4
-rw-r--r--modules/gdscript/gdscript_cache.h4
-rw-r--r--modules/gdscript/gdscript_codegen.h5
-rw-r--r--modules/gdscript/gdscript_compiler.cpp89
-rw-r--r--modules/gdscript/gdscript_compiler.h8
-rw-r--r--modules/gdscript/gdscript_disassembler.cpp4
-rw-r--r--modules/gdscript/gdscript_editor.cpp17
-rw-r--r--modules/gdscript/gdscript_function.cpp13
-rw-r--r--modules/gdscript/gdscript_function.h20
-rw-r--r--modules/gdscript/gdscript_parser.cpp85
-rw-r--r--modules/gdscript/gdscript_parser.h16
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp10
-rw-r--r--modules/gdscript/gdscript_tokenizer.h7
-rw-r--r--modules/gdscript/gdscript_utility_functions.cpp4
-rw-r--r--modules/gdscript/gdscript_utility_functions.h4
-rw-r--r--modules/gdscript/gdscript_vm.cpp22
-rw-r--r--modules/gdscript/gdscript_warning.cpp4
-rw-r--r--modules/gdscript/gdscript_warning.h4
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp18
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.h4
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.cpp12
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.h4
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.cpp19
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.h14
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp12
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.h4
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp26
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.h4
-rw-r--r--modules/gdscript/language_server/lsp.hpp24
-rw-r--r--modules/gdscript/register_types.cpp4
-rw-r--r--modules/gdscript/register_types.h4
-rw-r--r--modules/gdscript/tests/test_gdscript.cpp6
-rw-r--r--modules/gdscript/tests/test_gdscript.h4
-rw-r--r--modules/glslang/register_types.cpp6
-rw-r--r--modules/glslang/register_types.h4
-rw-r--r--modules/gltf/editor_scene_exporter_gltf_plugin.cpp6
-rw-r--r--modules/gltf/editor_scene_exporter_gltf_plugin.h4
-rw-r--r--modules/gltf/editor_scene_importer_gltf.cpp4
-rw-r--r--modules/gltf/editor_scene_importer_gltf.h4
-rw-r--r--modules/gltf/gltf_accessor.cpp4
-rw-r--r--modules/gltf/gltf_accessor.h4
-rw-r--r--modules/gltf/gltf_animation.cpp4
-rw-r--r--modules/gltf/gltf_animation.h4
-rw-r--r--modules/gltf/gltf_buffer_view.cpp4
-rw-r--r--modules/gltf/gltf_buffer_view.h4
-rw-r--r--modules/gltf/gltf_camera.cpp4
-rw-r--r--modules/gltf/gltf_camera.h8
-rw-r--r--modules/gltf/gltf_document.cpp410
-rw-r--r--modules/gltf/gltf_document.h13
-rw-r--r--modules/gltf/gltf_light.cpp4
-rw-r--r--modules/gltf/gltf_light.h4
-rw-r--r--modules/gltf/gltf_mesh.cpp4
-rw-r--r--modules/gltf/gltf_mesh.h4
-rw-r--r--modules/gltf/gltf_node.cpp4
-rw-r--r--modules/gltf/gltf_node.h4
-rw-r--r--modules/gltf/gltf_skeleton.cpp6
-rw-r--r--modules/gltf/gltf_skeleton.h4
-rw-r--r--modules/gltf/gltf_skin.cpp6
-rw-r--r--modules/gltf/gltf_skin.h4
-rw-r--r--modules/gltf/gltf_spec_gloss.cpp4
-rw-r--r--modules/gltf/gltf_spec_gloss.h4
-rw-r--r--modules/gltf/gltf_state.cpp21
-rw-r--r--modules/gltf/gltf_state.h8
-rw-r--r--modules/gltf/gltf_texture.cpp4
-rw-r--r--modules/gltf/gltf_texture.h4
-rw-r--r--modules/gltf/register_types.cpp8
-rw-r--r--modules/gltf/register_types.h4
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml8
-rw-r--r--modules/gridmap/grid_map.cpp96
-rw-r--r--modules/gridmap/grid_map.h66
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp21
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h38
-rw-r--r--modules/gridmap/register_types.cpp4
-rw-r--r--modules/gridmap/register_types.h4
-rw-r--r--modules/hdr/image_loader_hdr.cpp4
-rw-r--r--modules/hdr/image_loader_hdr.h4
-rw-r--r--modules/hdr/register_types.cpp4
-rw-r--r--modules/hdr/register_types.h4
-rw-r--r--modules/icloud/SCsub15
-rw-r--r--modules/icloud/config.py6
-rw-r--r--modules/icloud/icloud.gdip17
-rw-r--r--modules/icloud/icloud.mm345
-rw-r--r--modules/icloud/icloud_module.h32
-rw-r--r--modules/inappstore/SCsub15
-rw-r--r--modules/inappstore/config.py6
-rw-r--r--modules/inappstore/in_app_store.h77
-rw-r--r--modules/inappstore/in_app_store.mm411
-rw-r--r--modules/inappstore/in_app_store_module.cpp48
-rw-r--r--modules/inappstore/in_app_store_module.h32
-rw-r--r--modules/inappstore/inappstore.gdip17
-rw-r--r--modules/jpg/image_loader_jpegd.cpp4
-rw-r--r--modules/jpg/image_loader_jpegd.h4
-rw-r--r--modules/jpg/register_types.cpp4
-rw-r--r--modules/jpg/register_types.h4
-rw-r--r--modules/jsonrpc/jsonrpc.cpp6
-rw-r--r--modules/jsonrpc/jsonrpc.h4
-rw-r--r--modules/jsonrpc/register_types.cpp4
-rw-r--r--modules/jsonrpc/register_types.h4
-rw-r--r--modules/lightmapper_rd/lightmapper_rd.cpp38
-rw-r--r--modules/lightmapper_rd/lightmapper_rd.h106
-rw-r--r--modules/lightmapper_rd/lm_common_inc.glsl4
-rw-r--r--modules/lightmapper_rd/lm_compute.glsl22
-rw-r--r--modules/lightmapper_rd/register_types.cpp26
-rw-r--r--modules/lightmapper_rd/register_types.h4
-rw-r--r--[-rwxr-xr-x]modules/mbedtls/SCsub0
-rw-r--r--[-rwxr-xr-x]modules/mbedtls/config.py0
-rw-r--r--modules/mbedtls/crypto_mbedtls.cpp8
-rw-r--r--modules/mbedtls/crypto_mbedtls.h4
-rw-r--r--modules/mbedtls/dtls_server_mbedtls.cpp4
-rw-r--r--modules/mbedtls/dtls_server_mbedtls.h4
-rw-r--r--modules/mbedtls/packet_peer_mbed_dtls.cpp5
-rw-r--r--[-rwxr-xr-x]modules/mbedtls/packet_peer_mbed_dtls.h6
-rw-r--r--modules/mbedtls/register_types.cpp4
-rw-r--r--[-rwxr-xr-x]modules/mbedtls/register_types.h4
-rw-r--r--modules/mbedtls/ssl_context_mbedtls.cpp6
-rw-r--r--modules/mbedtls/ssl_context_mbedtls.h8
-rw-r--r--modules/mbedtls/stream_peer_mbedtls.cpp5
-rw-r--r--[-rwxr-xr-x]modules/mbedtls/stream_peer_mbedtls.h6
-rw-r--r--modules/mbedtls/tests/test_crypto_mbedtls.cpp4
-rw-r--r--modules/mbedtls/tests/test_crypto_mbedtls.h4
-rw-r--r--modules/meshoptimizer/register_types.cpp8
-rw-r--r--modules/meshoptimizer/register_types.h4
-rw-r--r--modules/minimp3/audio_stream_mp3.cpp12
-rw-r--r--modules/minimp3/audio_stream_mp3.h10
-rw-r--r--modules/minimp3/register_types.cpp4
-rw-r--r--modules/minimp3/register_types.h4
-rw-r--r--modules/minimp3/resource_importer_mp3.cpp4
-rw-r--r--modules/minimp3/resource_importer_mp3.h4
-rw-r--r--modules/mobile_vr/mobile_vr_interface.cpp18
-rw-r--r--modules/mobile_vr/mobile_vr_interface.h30
-rw-r--r--modules/mobile_vr/register_types.cpp4
-rw-r--r--modules/mobile_vr/register_types.h4
-rw-r--r--modules/mono/Directory.Build.props3
-rw-r--r--modules/mono/SdkPackageVersions.props6
-rw-r--r--modules/mono/build_scripts/godot_net_sdk_build.py24
-rw-r--r--modules/mono/class_db_api_json.cpp16
-rw-r--r--modules/mono/class_db_api_json.h4
-rw-r--r--modules/mono/csharp_script.cpp165
-rw-r--r--modules/mono/csharp_script.h40
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln18
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj40
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.nuspec22
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk_PackageVersion.txt1
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props3
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets5
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs15
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs11
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj31
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs33
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs86
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj40
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props7
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs9
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs156
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs47
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs31
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs3
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs86
-rw-r--r--[-rwxr-xr-x]modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs0
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs3
-rw-r--r--[-rwxr-xr-x]modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs61
-rw-r--r--modules/mono/editor/bindings_generator.cpp216
-rw-r--r--modules/mono/editor/bindings_generator.h5
-rw-r--r--modules/mono/editor/code_completion.cpp6
-rw-r--r--modules/mono/editor/code_completion.h4
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp51
-rw-r--r--modules/mono/editor/editor_internal_calls.h4
-rw-r--r--modules/mono/editor/godotsharp_export.cpp4
-rw-r--r--modules/mono/editor/godotsharp_export.h4
-rw-r--r--modules/mono/editor/script_class_parser.cpp753
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs22
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs9
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs15
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs101
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs27
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs21
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs65
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs65
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs114
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs20
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs27
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj6
-rw-r--r--modules/mono/glue/arguments_vector.h4
-rw-r--r--modules/mono/glue/base_object_glue.cpp4
-rw-r--r--modules/mono/glue/collections_glue.cpp4
-rw-r--r--modules/mono/glue/gd_glue.cpp4
-rw-r--r--modules/mono/glue/glue_header.h4
-rw-r--r--modules/mono/glue/nodepath_glue.cpp4
-rw-r--r--modules/mono/glue/rid_glue.cpp4
-rw-r--r--modules/mono/glue/scene_tree_glue.cpp6
-rw-r--r--modules/mono/glue/string_glue.cpp4
-rw-r--r--modules/mono/glue/string_name_glue.cpp4
-rw-r--r--modules/mono/godotsharp_defs.h4
-rw-r--r--modules/mono/godotsharp_dirs.cpp16
-rw-r--r--modules/mono/godotsharp_dirs.h4
-rw-r--r--modules/mono/managed_callable.cpp4
-rw-r--r--modules/mono/managed_callable.h4
-rw-r--r--modules/mono/mono_gc_handle.cpp4
-rw-r--r--modules/mono/mono_gc_handle.h4
-rw-r--r--modules/mono/mono_gd/android_mono_config.h4
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp35
-rw-r--r--modules/mono/mono_gd/gd_mono.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp121
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.h17
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h9
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp18
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_field.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_header.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp17
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.h7
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_log.h8
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp27
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h6
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono_method.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_method_thunk.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_property.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_property.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_wasm_m2n.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono_wasm_m2n.h4
-rw-r--r--modules/mono/mono_gd/i_mono_class_member.h4
-rw-r--r--modules/mono/mono_gd/managed_type.cpp4
-rw-r--r--modules/mono/mono_gd/managed_type.h4
-rw-r--r--modules/mono/mono_gd/support/android_support.cpp24
-rw-r--r--[-rwxr-xr-x]modules/mono/mono_gd/support/android_support.h4
-rw-r--r--[-rwxr-xr-x]modules/mono/mono_gd/support/ios_support.h4
-rw-r--r--modules/mono/mono_gd/support/ios_support.mm4
-rw-r--r--modules/mono/register_types.cpp4
-rw-r--r--modules/mono/register_types.h4
-rw-r--r--modules/mono/signal_awaiter_utils.cpp4
-rw-r--r--modules/mono/signal_awaiter_utils.h4
-rw-r--r--modules/mono/utils/macros.h4
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp8
-rw-r--r--modules/mono/utils/mono_reg_utils.h4
-rw-r--r--modules/mono/utils/osx_utils.cpp4
-rw-r--r--modules/mono/utils/osx_utils.h4
-rw-r--r--modules/mono/utils/path_utils.cpp8
-rw-r--r--modules/mono/utils/path_utils.h4
-rw-r--r--modules/mono/utils/string_utils.cpp4
-rw-r--r--modules/mono/utils/string_utils.h4
-rw-r--r--modules/ogg/register_types.cpp4
-rw-r--r--modules/ogg/register_types.h4
-rw-r--r--modules/opensimplex/doc_classes/NoiseTexture.xml5
-rw-r--r--modules/opensimplex/doc_classes/OpenSimplexNoise.xml5
-rw-r--r--modules/opensimplex/noise_texture.cpp55
-rw-r--r--modules/opensimplex/noise_texture.h26
-rw-r--r--modules/opensimplex/open_simplex_noise.cpp36
-rw-r--r--modules/opensimplex/open_simplex_noise.h24
-rw-r--r--modules/opensimplex/register_types.cpp4
-rw-r--r--modules/opensimplex/register_types.h4
-rw-r--r--modules/opus/register_types.cpp4
-rw-r--r--modules/opus/register_types.h4
-rw-r--r--modules/pvr/image_compress_pvrtc.cpp4
-rw-r--r--modules/pvr/image_compress_pvrtc.h4
-rw-r--r--modules/pvr/register_types.cpp4
-rw-r--r--modules/pvr/register_types.h4
-rw-r--r--modules/pvr/texture_loader_pvr.cpp10
-rw-r--r--modules/pvr/texture_loader_pvr.h6
-rw-r--r--modules/regex/doc_classes/RegEx.xml4
-rw-r--r--modules/regex/regex.cpp6
-rw-r--r--modules/regex/regex.h10
-rw-r--r--modules/regex/register_types.cpp4
-rw-r--r--modules/regex/register_types.h4
-rw-r--r--modules/regex/tests/test_regex.h4
-rw-r--r--modules/register_module_types.h4
-rw-r--r--modules/squish/image_compress_squish.cpp4
-rw-r--r--modules/squish/image_compress_squish.h4
-rw-r--r--modules/squish/register_types.cpp4
-rw-r--r--modules/squish/register_types.h4
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp22
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.h28
-rw-r--r--modules/stb_vorbis/register_types.cpp4
-rw-r--r--modules/stb_vorbis/register_types.h4
-rw-r--r--modules/stb_vorbis/resource_importer_ogg_vorbis.cpp4
-rw-r--r--modules/stb_vorbis/resource_importer_ogg_vorbis.h4
-rw-r--r--modules/svg/image_loader_svg.cpp4
-rw-r--r--modules/svg/image_loader_svg.h4
-rw-r--r--modules/svg/register_types.cpp4
-rw-r--r--modules/svg/register_types.h4
-rw-r--r--modules/text_server_adv/SCsub43
-rw-r--r--modules/text_server_adv/bitmap_font_adv.cpp121
-rw-r--r--modules/text_server_adv/bitmap_font_adv.h15
-rw-r--r--modules/text_server_adv/config.py2
-rw-r--r--modules/text_server_adv/dynamic_font_adv.cpp20
-rw-r--r--modules/text_server_adv/dynamic_font_adv.h23
-rw-r--r--modules/text_server_adv/font_adv.h27
-rw-r--r--modules/text_server_adv/icu_data/icudata_stub.cpp4
-rw-r--r--modules/text_server_adv/register_types.cpp4
-rw-r--r--modules/text_server_adv/register_types.h4
-rw-r--r--modules/text_server_adv/script_iterator.cpp4
-rw-r--r--modules/text_server_adv/script_iterator.h10
-rw-r--r--modules/text_server_adv/text_server_adv.cpp114
-rw-r--r--modules/text_server_adv/text_server_adv.h15
-rw-r--r--modules/text_server_fb/bitmap_font_fb.cpp100
-rw-r--r--modules/text_server_fb/bitmap_font_fb.h10
-rw-r--r--modules/text_server_fb/config.py2
-rw-r--r--modules/text_server_fb/dynamic_font_fb.cpp19
-rw-r--r--modules/text_server_fb/dynamic_font_fb.h23
-rw-r--r--modules/text_server_fb/font_fb.h27
-rw-r--r--modules/text_server_fb/register_types.cpp4
-rw-r--r--modules/text_server_fb/register_types.h4
-rw-r--r--modules/text_server_fb/text_server_fb.cpp90
-rw-r--r--modules/text_server_fb/text_server_fb.h15
-rw-r--r--modules/tga/image_loader_tga.cpp29
-rw-r--r--modules/tga/image_loader_tga.h28
-rw-r--r--modules/tga/register_types.cpp4
-rw-r--r--modules/tga/register_types.h4
-rw-r--r--modules/theora/register_types.cpp4
-rw-r--r--modules/theora/register_types.h4
-rw-r--r--modules/theora/video_stream_theora.cpp32
-rw-r--r--modules/theora/video_stream_theora.h57
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp4
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h4
-rw-r--r--modules/tinyexr/image_saver_tinyexr.cpp4
-rw-r--r--modules/tinyexr/image_saver_tinyexr.h4
-rw-r--r--modules/tinyexr/register_types.cpp4
-rw-r--r--modules/tinyexr/register_types.h4
-rw-r--r--modules/upnp/register_types.cpp4
-rw-r--r--modules/upnp/register_types.h4
-rw-r--r--modules/upnp/upnp.cpp11
-rw-r--r--modules/upnp/upnp.h10
-rw-r--r--modules/upnp/upnp_device.cpp6
-rw-r--r--modules/upnp/upnp_device.h4
-rw-r--r--modules/vhacd/register_types.cpp4
-rw-r--r--modules/vhacd/register_types.h4
-rw-r--r--modules/visual_script/doc_classes/VisualScript.xml134
-rw-r--r--modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml16
-rw-r--r--modules/visual_script/register_types.cpp4
-rw-r--r--modules/visual_script/register_types.h4
-rw-r--r--modules/visual_script/visual_script.cpp1094
-rw-r--r--modules/visual_script/visual_script.h213
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp45
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h7
-rw-r--r--modules/visual_script/visual_script_editor.cpp1848
-rw-r--r--modules/visual_script/visual_script_editor.h20
-rw-r--r--modules/visual_script/visual_script_expression.cpp25
-rw-r--r--modules/visual_script/visual_script_expression.h51
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp16
-rw-r--r--modules/visual_script/visual_script_flow_control.h6
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp52
-rw-r--r--modules/visual_script/visual_script_func_nodes.h4
-rw-r--r--modules/visual_script/visual_script_nodes.cpp65
-rw-r--r--modules/visual_script/visual_script_nodes.h8
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp6
-rw-r--r--modules/visual_script/visual_script_property_selector.h4
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp14
-rw-r--r--modules/visual_script/visual_script_yield_nodes.h4
-rw-r--r--modules/vorbis/register_types.cpp4
-rw-r--r--modules/vorbis/register_types.h4
-rw-r--r--modules/webm/register_types.cpp4
-rw-r--r--modules/webm/register_types.h4
-rw-r--r--modules/webm/video_stream_webm.cpp8
-rw-r--r--modules/webm/video_stream_webm.h6
-rw-r--r--modules/webp/image_loader_webp.cpp6
-rw-r--r--modules/webp/image_loader_webp.h4
-rw-r--r--modules/webp/register_types.cpp4
-rw-r--r--modules/webp/register_types.h4
-rw-r--r--modules/webrtc/library_godot_webrtc.js4
-rw-r--r--modules/webrtc/register_types.cpp4
-rw-r--r--modules/webrtc/register_types.h4
-rw-r--r--modules/webrtc/webrtc_data_channel.cpp4
-rw-r--r--modules/webrtc/webrtc_data_channel.h4
-rw-r--r--modules/webrtc/webrtc_data_channel_gdnative.cpp4
-rw-r--r--modules/webrtc/webrtc_data_channel_gdnative.h4
-rw-r--r--modules/webrtc/webrtc_data_channel_js.cpp11
-rw-r--r--modules/webrtc/webrtc_data_channel_js.h12
-rw-r--r--modules/webrtc/webrtc_multiplayer.cpp4
-rw-r--r--modules/webrtc/webrtc_multiplayer.h4
-rw-r--r--modules/webrtc/webrtc_peer_connection.cpp4
-rw-r--r--modules/webrtc/webrtc_peer_connection.h4
-rw-r--r--modules/webrtc/webrtc_peer_connection_gdnative.cpp4
-rw-r--r--modules/webrtc/webrtc_peer_connection_gdnative.h4
-rw-r--r--modules/webrtc/webrtc_peer_connection_js.cpp4
-rw-r--r--modules/webrtc/webrtc_peer_connection_js.h4
-rw-r--r--modules/websocket/editor_debugger_server_websocket.cpp4
-rw-r--r--modules/websocket/editor_debugger_server_websocket.h4
-rw-r--r--modules/websocket/emws_client.cpp8
-rw-r--r--modules/websocket/emws_client.h12
-rw-r--r--modules/websocket/emws_peer.cpp6
-rw-r--r--modules/websocket/emws_peer.h10
-rw-r--r--modules/websocket/emws_server.cpp4
-rw-r--r--modules/websocket/emws_server.h4
-rw-r--r--modules/websocket/library_godot_websocket.js4
-rw-r--r--modules/websocket/packet_buffer.h4
-rw-r--r--modules/websocket/register_types.cpp4
-rw-r--r--modules/websocket/register_types.h4
-rw-r--r--modules/websocket/remote_debugger_peer_websocket.cpp4
-rw-r--r--modules/websocket/remote_debugger_peer_websocket.h4
-rw-r--r--modules/websocket/websocket_client.cpp5
-rw-r--r--modules/websocket/websocket_client.h6
-rw-r--r--modules/websocket/websocket_macros.h4
-rw-r--r--modules/websocket/websocket_multiplayer_peer.cpp13
-rw-r--r--modules/websocket/websocket_multiplayer_peer.h20
-rw-r--r--modules/websocket/websocket_peer.cpp4
-rw-r--r--modules/websocket/websocket_peer.h4
-rw-r--r--modules/websocket/websocket_server.cpp4
-rw-r--r--modules/websocket/websocket_server.h4
-rw-r--r--modules/websocket/wsl_client.cpp9
-rw-r--r--modules/websocket/wsl_client.h18
-rw-r--r--modules/websocket/wsl_peer.cpp8
-rw-r--r--modules/websocket/wsl_peer.h42
-rw-r--r--modules/websocket/wsl_server.cpp17
-rw-r--r--modules/websocket/wsl_server.h26
-rw-r--r--modules/webxr/SCsub11
-rw-r--r--modules/webxr/config.py14
-rw-r--r--modules/webxr/doc_classes/WebXRInterface.xml257
-rw-r--r--modules/webxr/godot_webxr.h85
-rw-r--r--modules/webxr/native/library_godot_webxr.js672
-rw-r--r--modules/webxr/native/webxr.externs.js499
-rw-r--r--modules/webxr/register_types.cpp (renamed from modules/arkit/arkit_module.cpp)26
-rw-r--r--modules/webxr/register_types.h (renamed from modules/gamecenter/game_center_delegate.h)14
-rw-r--r--modules/webxr/webxr_interface.cpp71
-rw-r--r--modules/webxr/webxr_interface.h (renamed from modules/gamecenter/game_center.h)64
-rw-r--r--modules/webxr/webxr_interface_js.cpp460
-rw-r--r--modules/webxr/webxr_interface_js.h (renamed from modules/arkit/arkit_interface.h)119
-rw-r--r--modules/xatlas_unwrap/register_types.cpp9
-rw-r--r--modules/xatlas_unwrap/register_types.h4
-rw-r--r--platform/android/android_keys_utils.cpp4
-rw-r--r--platform/android/android_keys_utils.h4
-rw-r--r--platform/android/api/api.cpp4
-rw-r--r--platform/android/api/api.h4
-rw-r--r--platform/android/api/java_class_wrapper.h4
-rw-r--r--platform/android/api/jni_singleton.h6
-rw-r--r--platform/android/audio_driver_jandroid.cpp16
-rw-r--r--platform/android/audio_driver_jandroid.h4
-rw-r--r--platform/android/audio_driver_opensl.cpp4
-rw-r--r--platform/android/audio_driver_opensl.h4
-rw-r--r--platform/android/detect.py58
-rw-r--r--platform/android/dir_access_jandroid.cpp18
-rw-r--r--platform/android/dir_access_jandroid.h4
-rw-r--r--platform/android/display_server_android.cpp4
-rw-r--r--platform/android/display_server_android.h4
-rw-r--r--platform/android/export/export.cpp518
-rw-r--r--platform/android/export/export.h4
-rw-r--r--platform/android/export/gradle_export_util.h28
-rw-r--r--platform/android/file_access_android.cpp4
-rw-r--r--platform/android/file_access_android.h4
-rw-r--r--platform/android/java/app/AndroidManifest.xml10
-rw-r--r--platform/android/java/app/build.gradle4
-rw-r--r--platform/android/java/app/config.gradle64
-rw-r--r--platform/android/java/app/res/drawable/splash_drawable.xml2
-rw-r--r--platform/android/java/app/src/com/godot/game/GodotApp.java4
-rw-r--r--platform/android/java/build.gradle6
-rw-r--r--platform/android/java/lib/AndroidManifest.xml5
-rw-r--r--platform/android/java/lib/build.gradle6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Dictionary.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java46
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java12
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java251
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java17
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java103
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java (renamed from modules/arkit/arkit_session_delegate.h)51
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java42
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java4
-rw-r--r--platform/android/java/nativeSrcsConfigs/build.gradle2
-rw-r--r--platform/android/java_class_wrapper.cpp10
-rw-r--r--platform/android/java_godot_io_wrapper.cpp38
-rw-r--r--platform/android/java_godot_io_wrapper.h4
-rw-r--r--platform/android/java_godot_lib_jni.cpp12
-rw-r--r--platform/android/java_godot_lib_jni.h4
-rw-r--r--platform/android/java_godot_view_wrapper.cpp12
-rw-r--r--platform/android/java_godot_view_wrapper.h4
-rw-r--r--platform/android/java_godot_wrapper.cpp46
-rw-r--r--platform/android/java_godot_wrapper.h4
-rw-r--r--platform/android/jni_utils.cpp4
-rw-r--r--platform/android/jni_utils.h4
-rw-r--r--platform/android/net_socket_android.cpp10
-rw-r--r--platform/android/net_socket_android.h4
-rw-r--r--platform/android/os_android.cpp8
-rw-r--r--platform/android/os_android.h4
-rw-r--r--platform/android/platform_config.h4
-rw-r--r--platform/android/plugin/godot_plugin_config.h123
-rw-r--r--platform/android/plugin/godot_plugin_jni.cpp14
-rw-r--r--platform/android/plugin/godot_plugin_jni.h14
-rw-r--r--platform/android/string_android.h8
-rw-r--r--platform/android/thread_jandroid.cpp119
-rw-r--r--platform/android/thread_jandroid.h46
-rw-r--r--platform/android/vulkan/vulkan_context_android.cpp4
-rw-r--r--platform/android/vulkan/vulkan_context_android.h4
-rw-r--r--platform/iphone/app_delegate.h4
-rw-r--r--platform/iphone/app_delegate.mm4
-rw-r--r--platform/iphone/detect.py57
-rw-r--r--platform/iphone/device_metrics.h4
-rw-r--r--platform/iphone/device_metrics.m4
-rw-r--r--platform/iphone/display_layer.h4
-rw-r--r--platform/iphone/display_layer.mm6
-rw-r--r--platform/iphone/display_server_iphone.h4
-rw-r--r--platform/iphone/display_server_iphone.mm4
-rw-r--r--platform/iphone/export/export.cpp138
-rw-r--r--platform/iphone/export/export.h4
-rw-r--r--platform/iphone/godot_app_delegate.h4
-rw-r--r--platform/iphone/godot_app_delegate.m36
-rw-r--r--platform/iphone/godot_iphone.mm4
-rw-r--r--platform/iphone/godot_view.h12
-rw-r--r--platform/iphone/godot_view.mm13
-rw-r--r--platform/iphone/godot_view_gesture_recognizer.h4
-rw-r--r--platform/iphone/godot_view_gesture_recognizer.mm4
-rw-r--r--platform/iphone/godot_view_renderer.h4
-rw-r--r--platform/iphone/godot_view_renderer.mm4
-rw-r--r--platform/iphone/ios.h4
-rw-r--r--platform/iphone/ios.mm4
-rw-r--r--platform/iphone/joypad_iphone.h4
-rw-r--r--platform/iphone/joypad_iphone.mm4
-rw-r--r--platform/iphone/keyboard_input_view.h4
-rw-r--r--platform/iphone/keyboard_input_view.mm4
-rw-r--r--platform/iphone/main.m4
-rw-r--r--platform/iphone/native_video_view.h4
-rw-r--r--platform/iphone/native_video_view.m4
-rw-r--r--platform/iphone/os_iphone.h4
-rw-r--r--platform/iphone/os_iphone.mm12
-rw-r--r--platform/iphone/platform_config.h4
-rw-r--r--platform/iphone/plugin/godot_plugin_config.h129
-rw-r--r--platform/iphone/view_controller.h4
-rw-r--r--platform/iphone/view_controller.mm40
-rw-r--r--platform/iphone/vulkan_context_iphone.h4
-rw-r--r--platform/iphone/vulkan_context_iphone.mm4
-rw-r--r--platform/javascript/.eslintrc.engine.js2
-rw-r--r--platform/javascript/.eslintrc.libs.js3
-rw-r--r--platform/javascript/SCsub48
-rw-r--r--platform/javascript/api/api.cpp4
-rw-r--r--platform/javascript/api/api.h4
-rw-r--r--platform/javascript/api/javascript_eval.h4
-rw-r--r--platform/javascript/api/javascript_tools_editor_plugin.cpp6
-rw-r--r--platform/javascript/api/javascript_tools_editor_plugin.h4
-rw-r--r--platform/javascript/audio_driver_javascript.cpp14
-rw-r--r--platform/javascript/audio_driver_javascript.h6
-rw-r--r--platform/javascript/detect.py40
-rw-r--r--platform/javascript/display_server_javascript.cpp169
-rw-r--r--platform/javascript/display_server_javascript.h10
-rw-r--r--platform/javascript/dom_keys.inc4
-rw-r--r--platform/javascript/emscripten_helpers.py78
-rw-r--r--platform/javascript/export/export.cpp99
-rw-r--r--platform/javascript/export/export.h4
-rw-r--r--platform/javascript/godot_audio.h4
-rw-r--r--platform/javascript/godot_js.h23
-rw-r--r--platform/javascript/http_client.h.inc17
-rw-r--r--platform/javascript/http_client_javascript.cpp190
-rw-r--r--platform/javascript/http_request.h75
-rw-r--r--platform/javascript/javascript_eval.cpp4
-rw-r--r--platform/javascript/javascript_main.cpp13
-rw-r--r--platform/javascript/javascript_runtime.cpp4
-rw-r--r--platform/javascript/js/dynlink.pre.js1
-rw-r--r--platform/javascript/js/engine/config.js320
-rw-r--r--platform/javascript/js/engine/engine.externs.js1
-rw-r--r--platform/javascript/js/engine/engine.js496
-rw-r--r--platform/javascript/js/engine/preloader.js125
-rw-r--r--platform/javascript/js/engine/utils.js58
-rw-r--r--platform/javascript/js/jsdoc2rst/publish.js354
-rw-r--r--platform/javascript/js/libs/audio.worklet.js4
-rw-r--r--platform/javascript/js/libs/library_godot_audio.js9
-rw-r--r--platform/javascript/js/libs/library_godot_display.js406
-rw-r--r--platform/javascript/js/libs/library_godot_editor_tools.js4
-rw-r--r--platform/javascript/js/libs/library_godot_eval.js4
-rw-r--r--platform/javascript/js/libs/library_godot_fetch.js258
-rw-r--r--platform/javascript/js/libs/library_godot_http_request.js160
-rw-r--r--platform/javascript/js/libs/library_godot_os.js42
-rw-r--r--platform/javascript/js/libs/library_godot_runtime.js20
-rw-r--r--platform/javascript/os_javascript.cpp16
-rw-r--r--platform/javascript/os_javascript.h8
-rw-r--r--platform/javascript/package-lock.json154
-rw-r--r--platform/javascript/package.json12
-rw-r--r--platform/javascript/platform_config.h4
-rw-r--r--platform/linuxbsd/SCsub5
-rw-r--r--platform/linuxbsd/context_gl_x11.cpp4
-rw-r--r--platform/linuxbsd/context_gl_x11.h4
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.cpp6
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.h4
-rw-r--r--platform/linuxbsd/detect.py37
-rw-r--r--platform/linuxbsd/detect_prime_x11.cpp7
-rw-r--r--platform/linuxbsd/detect_prime_x11.h4
-rw-r--r--platform/linuxbsd/display_server_x11.cpp47
-rw-r--r--platform/linuxbsd/display_server_x11.h8
-rw-r--r--platform/linuxbsd/export/export.cpp4
-rw-r--r--platform/linuxbsd/export/export.h4
-rw-r--r--platform/linuxbsd/godot_linuxbsd.cpp4
-rw-r--r--platform/linuxbsd/joypad_linux.cpp71
-rw-r--r--platform/linuxbsd/joypad_linux.h13
-rw-r--r--platform/linuxbsd/key_mapping_x11.cpp4
-rw-r--r--platform/linuxbsd/key_mapping_x11.h4
-rw-r--r--platform/linuxbsd/libudev-so_wrap.c1013
-rw-r--r--platform/linuxbsd/libudev-so_wrap.h378
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp34
-rw-r--r--platform/linuxbsd/os_linuxbsd.h4
-rw-r--r--platform/linuxbsd/platform_config.h4
-rw-r--r--platform/linuxbsd/vulkan_context_x11.cpp4
-rw-r--r--platform/linuxbsd/vulkan_context_x11.h4
-rw-r--r--platform/osx/SCsub2
-rw-r--r--platform/osx/context_gl_osx.h4
-rw-r--r--platform/osx/context_gl_osx.mm4
-rw-r--r--platform/osx/crash_handler_osx.h4
-rw-r--r--platform/osx/crash_handler_osx.mm6
-rw-r--r--platform/osx/detect.py13
-rw-r--r--platform/osx/dir_access_osx.h4
-rw-r--r--platform/osx/dir_access_osx.mm4
-rw-r--r--platform/osx/display_server_osx.h5
-rw-r--r--platform/osx/display_server_osx.mm19
-rw-r--r--platform/osx/export/export.cpp193
-rw-r--r--platform/osx/export/export.h4
-rw-r--r--platform/osx/godot_main_osx.mm4
-rw-r--r--platform/osx/joypad_osx.cpp4
-rw-r--r--platform/osx/joypad_osx.h4
-rw-r--r--platform/osx/os_osx.h4
-rw-r--r--platform/osx/os_osx.mm10
-rw-r--r--platform/osx/platform_config.h4
-rw-r--r--platform/osx/vulkan_context_osx.h4
-rw-r--r--platform/osx/vulkan_context_osx.mm4
-rw-r--r--platform/register_platform_apis.h4
-rw-r--r--platform/server/detect.py16
-rw-r--r--platform/server/godot_server.cpp4
-rw-r--r--platform/server/os_server.cpp4
-rw-r--r--platform/server/os_server.h4
-rw-r--r--platform/server/platform_config.h4
-rw-r--r--platform/uwp/app.cpp4
-rw-r--r--platform/uwp/app.h4
-rw-r--r--platform/uwp/context_egl_uwp.cpp4
-rw-r--r--platform/uwp/context_egl_uwp.h4
-rw-r--r--platform/uwp/export/export.cpp20
-rw-r--r--platform/uwp/export/export.h4
-rw-r--r--platform/uwp/joypad_uwp.cpp4
-rw-r--r--platform/uwp/joypad_uwp.h4
-rw-r--r--platform/uwp/os_uwp.cpp16
-rw-r--r--platform/uwp/os_uwp.h7
-rw-r--r--platform/uwp/platform_config.h4
-rw-r--r--platform/uwp/thread_uwp.cpp61
-rw-r--r--platform/uwp/thread_uwp.h59
-rw-r--r--platform/windows/SCsub2
-rw-r--r--platform/windows/context_gl_windows.cpp4
-rw-r--r--platform/windows/context_gl_windows.h4
-rw-r--r--platform/windows/crash_handler_windows.cpp4
-rw-r--r--platform/windows/crash_handler_windows.h4
-rw-r--r--platform/windows/detect.py13
-rw-r--r--platform/windows/display_server_windows.cpp171
-rw-r--r--platform/windows/display_server_windows.h28
-rw-r--r--platform/windows/export/export.cpp12
-rw-r--r--platform/windows/export/export.h4
-rw-r--r--platform/windows/godot.natvis58
-rw-r--r--platform/windows/godot_windows.cpp4
-rw-r--r--platform/windows/joypad_windows.cpp4
-rw-r--r--platform/windows/joypad_windows.h4
-rw-r--r--platform/windows/key_mapping_windows.cpp4
-rw-r--r--platform/windows/key_mapping_windows.h4
-rw-r--r--platform/windows/lang_table.h4
-rw-r--r--platform/windows/os_windows.cpp164
-rw-r--r--platform/windows/os_windows.h15
-rw-r--r--platform/windows/platform_config.h4
-rw-r--r--platform/windows/vulkan_context_win.cpp4
-rw-r--r--platform/windows/vulkan_context_win.h4
-rw-r--r--platform/windows/windows_terminal_logger.cpp4
-rw-r--r--platform/windows/windows_terminal_logger.h4
-rw-r--r--scene/2d/animated_sprite_2d.cpp29
-rw-r--r--scene/2d/animated_sprite_2d.h33
-rw-r--r--scene/2d/area_2d.cpp28
-rw-r--r--scene/2d/area_2d.h44
-rw-r--r--scene/2d/audio_stream_player_2d.cpp81
-rw-r--r--scene/2d/audio_stream_player_2d.h39
-rw-r--r--scene/2d/back_buffer_copy.cpp6
-rw-r--r--scene/2d/back_buffer_copy.h8
-rw-r--r--scene/2d/camera_2d.cpp176
-rw-r--r--scene/2d/camera_2d.h75
-rw-r--r--scene/2d/canvas_group.cpp5
-rw-r--r--scene/2d/canvas_group.h4
-rw-r--r--scene/2d/canvas_modulate.cpp7
-rw-r--r--scene/2d/canvas_modulate.h6
-rw-r--r--scene/2d/collision_object_2d.cpp12
-rw-r--r--scene/2d/collision_object_2d.h34
-rw-r--r--scene/2d/collision_polygon_2d.cpp80
-rw-r--r--scene/2d/collision_polygon_2d.h22
-rw-r--r--scene/2d/collision_shape_2d.cpp21
-rw-r--r--scene/2d/collision_shape_2d.h20
-rw-r--r--scene/2d/cpu_particles_2d.cpp185
-rw-r--r--scene/2d/cpu_particles_2d.h74
-rw-r--r--scene/2d/gpu_particles_2d.cpp7
-rw-r--r--scene/2d/gpu_particles_2d.h4
-rw-r--r--scene/2d/joints_2d.cpp123
-rw-r--r--scene/2d/joints_2d.h36
-rw-r--r--scene/2d/light_2d.cpp30
-rw-r--r--scene/2d/light_2d.h37
-rw-r--r--scene/2d/light_occluder_2d.cpp11
-rw-r--r--scene/2d/light_occluder_2d.h10
-rw-r--r--scene/2d/line_2d.cpp14
-rw-r--r--scene/2d/line_2d.h22
-rw-r--r--scene/2d/line_builder.cpp20
-rw-r--r--scene/2d/line_builder.h30
-rw-r--r--scene/2d/mesh_instance_2d.cpp5
-rw-r--r--scene/2d/mesh_instance_2d.h4
-rw-r--r--scene/2d/multimesh_instance_2d.cpp5
-rw-r--r--scene/2d/multimesh_instance_2d.h4
-rw-r--r--scene/2d/navigation_2d.cpp92
-rw-r--r--scene/2d/navigation_2d.h71
-rw-r--r--scene/2d/navigation_agent_2d.cpp51
-rw-r--r--scene/2d/navigation_agent_2d.h19
-rw-r--r--scene/2d/navigation_obstacle_2d.cpp119
-rw-r--r--scene/2d/navigation_obstacle_2d.h18
-rw-r--r--scene/2d/navigation_region_2d.cpp72
-rw-r--r--scene/2d/navigation_region_2d.h10
-rw-r--r--scene/2d/node_2d.cpp21
-rw-r--r--scene/2d/node_2d.h8
-rw-r--r--scene/2d/parallax_background.cpp8
-rw-r--r--scene/2d/parallax_background.h10
-rw-r--r--scene/2d/parallax_layer.cpp7
-rw-r--r--scene/2d/parallax_layer.h6
-rw-r--r--scene/2d/path_2d.cpp12
-rw-r--r--scene/2d/path_2d.h12
-rw-r--r--scene/2d/physics_body_2d.cpp58
-rw-r--r--scene/2d/physics_body_2d.h70
-rw-r--r--scene/2d/polygon_2d.cpp25
-rw-r--r--scene/2d/polygon_2d.h23
-rw-r--r--scene/2d/position_2d.cpp4
-rw-r--r--scene/2d/position_2d.h4
-rw-r--r--scene/2d/ray_cast_2d.cpp81
-rw-r--r--scene/2d/ray_cast_2d.h22
-rw-r--r--scene/2d/remote_transform_2d.cpp11
-rw-r--r--scene/2d/remote_transform_2d.h12
-rw-r--r--scene/2d/skeleton_2d.cpp17
-rw-r--r--scene/2d/skeleton_2d.h20
-rw-r--r--scene/2d/sprite_2d.cpp29
-rw-r--r--scene/2d/sprite_2d.h22
-rw-r--r--scene/2d/tile_map.cpp123
-rw-r--r--scene/2d/tile_map.h70
-rw-r--r--scene/2d/touch_screen_button.cpp27
-rw-r--r--scene/2d/touch_screen_button.h14
-rw-r--r--scene/2d/visibility_notifier_2d.cpp10
-rw-r--r--scene/2d/visibility_notifier_2d.h6
-rw-r--r--scene/2d/y_sort.cpp5
-rw-r--r--scene/2d/y_sort.h6
-rw-r--r--scene/3d/area_3d.cpp35
-rw-r--r--scene/3d/area_3d.h54
-rw-r--r--scene/3d/audio_stream_player_3d.cpp103
-rw-r--r--scene/3d/audio_stream_player_3d.h72
-rw-r--r--scene/3d/baked_lightmap.cpp24
-rw-r--r--scene/3d/baked_lightmap.h55
-rw-r--r--scene/3d/bone_attachment_3d.cpp5
-rw-r--r--scene/3d/bone_attachment_3d.h6
-rw-r--r--scene/3d/camera_3d.cpp74
-rw-r--r--scene/3d/camera_3d.h57
-rw-r--r--scene/3d/collision_object_3d.cpp66
-rw-r--r--scene/3d/collision_object_3d.h30
-rw-r--r--scene/3d/collision_polygon_3d.cpp35
-rw-r--r--scene/3d/collision_polygon_3d.h22
-rw-r--r--scene/3d/collision_shape_3d.cpp49
-rw-r--r--scene/3d/collision_shape_3d.h14
-rw-r--r--scene/3d/cpu_particles_3d.cpp97
-rw-r--r--scene/3d/cpu_particles_3d.h86
-rw-r--r--scene/3d/decal.cpp24
-rw-r--r--scene/3d/decal.h27
-rw-r--r--scene/3d/gi_probe.cpp35
-rw-r--r--scene/3d/gi_probe.h28
-rw-r--r--scene/3d/gpu_particles_3d.cpp9
-rw-r--r--scene/3d/gpu_particles_3d.h4
-rw-r--r--scene/3d/gpu_particles_collision_3d.cpp8
-rw-r--r--scene/3d/gpu_particles_collision_3d.h20
-rw-r--r--scene/3d/immediate_geometry_3d.cpp16
-rw-r--r--scene/3d/immediate_geometry_3d.h6
-rw-r--r--scene/3d/light_3d.cpp35
-rw-r--r--scene/3d/light_3d.h20
-rw-r--r--scene/3d/lightmap_probe.cpp4
-rw-r--r--scene/3d/lightmap_probe.h4
-rw-r--r--scene/3d/lightmapper.cpp4
-rw-r--r--scene/3d/lightmapper.h4
-rw-r--r--scene/3d/listener_3d.cpp6
-rw-r--r--scene/3d/listener_3d.h8
-rw-r--r--scene/3d/mesh_instance_3d.cpp13
-rw-r--r--scene/3d/mesh_instance_3d.h14
-rw-r--r--scene/3d/multimesh_instance_3d.cpp4
-rw-r--r--scene/3d/multimesh_instance_3d.h4
-rw-r--r--scene/3d/navigation_3d.cpp119
-rw-r--r--scene/3d/navigation_3d.h78
-rw-r--r--scene/3d/navigation_agent_3d.cpp51
-rw-r--r--scene/3d/navigation_agent_3d.h14
-rw-r--r--scene/3d/navigation_obstacle_3d.cpp136
-rw-r--r--scene/3d/navigation_obstacle_3d.h18
-rw-r--r--scene/3d/navigation_region_3d.cpp72
-rw-r--r--scene/3d/navigation_region_3d.h15
-rw-r--r--scene/3d/node_3d.cpp24
-rw-r--r--scene/3d/node_3d.h8
-rw-r--r--scene/3d/path_3d.cpp10
-rw-r--r--scene/3d/path_3d.h12
-rw-r--r--scene/3d/physics_body_3d.cpp96
-rw-r--r--scene/3d/physics_body_3d.h142
-rw-r--r--scene/3d/physics_joint_3d.cpp240
-rw-r--r--scene/3d/physics_joint_3d.h116
-rw-r--r--scene/3d/position_3d.cpp4
-rw-r--r--scene/3d/position_3d.h4
-rw-r--r--scene/3d/proximity_group_3d.cpp4
-rw-r--r--scene/3d/proximity_group_3d.h4
-rw-r--r--scene/3d/ray_cast_3d.cpp178
-rw-r--r--scene/3d/ray_cast_3d.h39
-rw-r--r--scene/3d/reflection_probe.cpp24
-rw-r--r--scene/3d/reflection_probe.h32
-rw-r--r--scene/3d/remote_transform_3d.cpp11
-rw-r--r--scene/3d/remote_transform_3d.h12
-rw-r--r--scene/3d/skeleton_3d.cpp10
-rw-r--r--scene/3d/skeleton_3d.h43
-rw-r--r--scene/3d/skeleton_ik_3d.cpp10
-rw-r--r--scene/3d/skeleton_ik_3d.h12
-rw-r--r--scene/3d/soft_body_3d.cpp32
-rw-r--r--scene/3d/soft_body_3d.h26
-rw-r--r--scene/3d/spring_arm_3d.cpp16
-rw-r--r--scene/3d/spring_arm_3d.h20
-rw-r--r--scene/3d/sprite_3d.cpp47
-rw-r--r--scene/3d/sprite_3d.h44
-rw-r--r--scene/3d/vehicle_body_3d.cpp114
-rw-r--r--scene/3d/vehicle_body_3d.h138
-rw-r--r--scene/3d/velocity_tracker_3d.cpp12
-rw-r--r--scene/3d/velocity_tracker_3d.h10
-rw-r--r--scene/3d/visibility_notifier_3d.cpp17
-rw-r--r--scene/3d/visibility_notifier_3d.h10
-rw-r--r--scene/3d/visual_instance_3d.cpp20
-rw-r--r--scene/3d/visual_instance_3d.h24
-rw-r--r--scene/3d/voxelizer.cpp9
-rw-r--r--scene/3d/voxelizer.h52
-rw-r--r--scene/3d/world_environment.cpp94
-rw-r--r--scene/3d/world_environment.h7
-rw-r--r--scene/3d/xr_nodes.cpp26
-rw-r--r--scene/3d/xr_nodes.h4
-rw-r--r--scene/animation/animation_blend_space_1d.cpp12
-rw-r--r--scene/animation/animation_blend_space_1d.h18
-rw-r--r--scene/animation/animation_blend_space_2d.cpp20
-rw-r--r--scene/animation/animation_blend_space_2d.h30
-rw-r--r--scene/animation/animation_blend_tree.cpp50
-rw-r--r--scene/animation/animation_blend_tree.h71
-rw-r--r--scene/animation/animation_cache.cpp7
-rw-r--r--scene/animation/animation_cache.h30
-rw-r--r--scene/animation/animation_node_state_machine.cpp38
-rw-r--r--scene/animation/animation_node_state_machine.h38
-rw-r--r--scene/animation/animation_player.cpp67
-rw-r--r--scene/animation/animation_player.h79
-rw-r--r--scene/animation/animation_tree.cpp56
-rw-r--r--scene/animation/animation_tree.h96
-rw-r--r--scene/animation/root_motion_view.cpp12
-rw-r--r--scene/animation/root_motion_view.h16
-rw-r--r--scene/animation/tween.cpp35
-rw-r--r--scene/animation/tween.h45
-rw-r--r--scene/audio/audio_stream_player.cpp67
-rw-r--r--scene/audio/audio_stream_player.h33
-rw-r--r--scene/debugger/scene_debugger.cpp4
-rw-r--r--scene/debugger/scene_debugger.h6
-rw-r--r--scene/gui/aspect_ratio_container.cpp4
-rw-r--r--scene/gui/aspect_ratio_container.h4
-rw-r--r--scene/gui/base_button.cpp17
-rw-r--r--scene/gui/base_button.h24
-rw-r--r--scene/gui/box_container.cpp15
-rw-r--r--scene/gui/box_container.h8
-rw-r--r--scene/gui/button.cpp64
-rw-r--r--scene/gui/button.h14
-rw-r--r--scene/gui/center_container.cpp8
-rw-r--r--scene/gui/center_container.h6
-rw-r--r--scene/gui/check_box.cpp4
-rw-r--r--scene/gui/check_box.h4
-rw-r--r--scene/gui/check_button.cpp4
-rw-r--r--scene/gui/check_button.h4
-rw-r--r--scene/gui/code_edit.cpp4
-rw-r--r--scene/gui/code_edit.h4
-rw-r--r--scene/gui/color_picker.cpp134
-rw-r--r--scene/gui/color_picker.h41
-rw-r--r--scene/gui/color_rect.cpp4
-rw-r--r--scene/gui/color_rect.h4
-rw-r--r--scene/gui/container.cpp7
-rw-r--r--scene/gui/container.h6
-rw-r--r--scene/gui/control.cpp57
-rw-r--r--scene/gui/control.h11
-rw-r--r--scene/gui/dialogs.cpp9
-rw-r--r--scene/gui/dialogs.h8
-rw-r--r--scene/gui/file_dialog.cpp46
-rw-r--r--scene/gui/file_dialog.h14
-rw-r--r--scene/gui/gradient_edit.cpp8
-rw-r--r--scene/gui/gradient_edit.h8
-rw-r--r--scene/gui/graph_edit.cpp127
-rw-r--r--scene/gui/graph_edit.h49
-rw-r--r--scene/gui/graph_node.cpp33
-rw-r--r--scene/gui/graph_node.h41
-rw-r--r--scene/gui/grid_container.cpp8
-rw-r--r--scene/gui/grid_container.h6
-rw-r--r--scene/gui/item_list.cpp67
-rw-r--r--scene/gui/item_list.h58
-rw-r--r--scene/gui/label.cpp52
-rw-r--r--scene/gui/label.h6
-rw-r--r--scene/gui/line_edit.cpp911
-rw-r--r--scene/gui/line_edit.h43
-rw-r--r--scene/gui/link_button.cpp23
-rw-r--r--scene/gui/link_button.h6
-rw-r--r--scene/gui/margin_container.cpp4
-rw-r--r--scene/gui/margin_container.h4
-rw-r--r--scene/gui/menu_button.cpp5
-rw-r--r--scene/gui/menu_button.h10
-rw-r--r--scene/gui/nine_patch_rect.cpp29
-rw-r--r--scene/gui/nine_patch_rect.h11
-rw-r--r--scene/gui/option_button.cpp11
-rw-r--r--scene/gui/option_button.h6
-rw-r--r--scene/gui/panel.cpp4
-rw-r--r--scene/gui/panel.h4
-rw-r--r--scene/gui/panel_container.cpp4
-rw-r--r--scene/gui/panel_container.h4
-rw-r--r--scene/gui/popup.cpp4
-rw-r--r--scene/gui/popup.h4
-rw-r--r--scene/gui/popup_menu.cpp136
-rw-r--r--scene/gui/popup_menu.h65
-rw-r--r--scene/gui/progress_bar.cpp13
-rw-r--r--scene/gui/progress_bar.h6
-rw-r--r--scene/gui/range.cpp23
-rw-r--r--scene/gui/range.h19
-rw-r--r--scene/gui/reference_rect.cpp4
-rw-r--r--scene/gui/reference_rect.h4
-rw-r--r--scene/gui/rich_text_effect.cpp4
-rw-r--r--scene/gui/rich_text_effect.h4
-rw-r--r--scene/gui/rich_text_label.cpp434
-rw-r--r--scene/gui/rich_text_label.h135
-rw-r--r--scene/gui/scroll_bar.cpp6
-rw-r--r--scene/gui/scroll_bar.h18
-rw-r--r--scene/gui/scroll_container.cpp139
-rw-r--r--scene/gui/scroll_container.h25
-rw-r--r--scene/gui/separator.cpp4
-rw-r--r--scene/gui/separator.h6
-rw-r--r--scene/gui/shortcut.cpp4
-rw-r--r--scene/gui/shortcut.h4
-rw-r--r--scene/gui/slider.cpp13
-rw-r--r--scene/gui/slider.h22
-rw-r--r--scene/gui/spin_box.cpp23
-rw-r--r--scene/gui/spin_box.h15
-rw-r--r--scene/gui/split_container.cpp13
-rw-r--r--scene/gui/split_container.h24
-rw-r--r--scene/gui/subviewport_container.cpp6
-rw-r--r--scene/gui/subviewport_container.h8
-rw-r--r--scene/gui/tab_container.cpp74
-rw-r--r--scene/gui/tab_container.h32
-rw-r--r--scene/gui/tabs.cpp92
-rw-r--r--scene/gui/tabs.h54
-rw-r--r--scene/gui/text_edit.cpp2500
-rw-r--r--scene/gui/text_edit.h284
-rw-r--r--scene/gui/texture_button.cpp21
-rw-r--r--scene/gui/texture_button.h14
-rw-r--r--scene/gui/texture_progress_bar.cpp22
-rw-r--r--scene/gui/texture_progress_bar.h18
-rw-r--r--scene/gui/texture_rect.cpp8
-rw-r--r--scene/gui/texture_rect.h12
-rw-r--r--scene/gui/tree.cpp124
-rw-r--r--scene/gui/tree.h202
-rw-r--r--scene/gui/video_player.cpp24
-rw-r--r--scene/gui/video_player.h31
-rw-r--r--scene/main/canvas_item.cpp14
-rw-r--r--scene/main/canvas_item.h8
-rw-r--r--scene/main/canvas_layer.cpp21
-rw-r--r--scene/main/canvas_layer.h23
-rw-r--r--scene/main/http_request.cpp68
-rw-r--r--scene/main/http_request.h43
-rw-r--r--scene/main/instance_placeholder.cpp4
-rw-r--r--scene/main/instance_placeholder.h4
-rw-r--r--scene/main/node.cpp474
-rw-r--r--scene/main/node.h55
-rw-r--r--scene/main/resource_preloader.cpp4
-rw-r--r--scene/main/resource_preloader.h4
-rw-r--r--scene/main/scene_tree.cpp167
-rw-r--r--scene/main/scene_tree.h34
-rw-r--r--scene/main/shader_globals_override.cpp10
-rw-r--r--scene/main/shader_globals_override.h6
-rw-r--r--scene/main/timer.cpp38
-rw-r--r--scene/main/timer.h26
-rw-r--r--scene/main/viewport.cpp697
-rw-r--r--scene/main/viewport.h150
-rw-r--r--scene/main/window.cpp27
-rw-r--r--scene/main/window.h10
-rw-r--r--scene/register_scene_types.cpp53
-rw-r--r--scene/register_scene_types.h4
-rw-r--r--scene/resources/animation.cpp22
-rw-r--r--scene/resources/animation.h50
-rw-r--r--scene/resources/audio_stream_sample.cpp21
-rw-r--r--scene/resources/audio_stream_sample.h40
-rw-r--r--scene/resources/bit_map.cpp17
-rw-r--r--scene/resources/bit_map.h8
-rw-r--r--scene/resources/box_shape_3d.cpp29
-rw-r--r--scene/resources/box_shape_3d.h10
-rw-r--r--scene/resources/camera_effects.cpp17
-rw-r--r--scene/resources/camera_effects.h13
-rw-r--r--scene/resources/capsule_shape_2d.cpp16
-rw-r--r--scene/resources/capsule_shape_2d.h8
-rw-r--r--scene/resources/capsule_shape_3d.cpp8
-rw-r--r--scene/resources/capsule_shape_3d.h8
-rw-r--r--scene/resources/circle_shape_2d.cpp13
-rw-r--r--scene/resources/circle_shape_2d.h6
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp6
-rw-r--r--scene/resources/concave_polygon_shape_2d.h4
-rw-r--r--scene/resources/concave_polygon_shape_3d.cpp6
-rw-r--r--scene/resources/concave_polygon_shape_3d.h4
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp15
-rw-r--r--scene/resources/convex_polygon_shape_2d.h4
-rw-r--r--scene/resources/convex_polygon_shape_3d.cpp6
-rw-r--r--scene/resources/convex_polygon_shape_3d.h4
-rw-r--r--scene/resources/curve.cpp24
-rw-r--r--scene/resources/curve.h52
-rw-r--r--scene/resources/cylinder_shape_3d.cpp8
-rw-r--r--scene/resources/cylinder_shape_3d.h8
-rw-r--r--scene/resources/default_theme/bar_arrow.pngbin0 -> 208 bytes
-rw-r--r--scene/resources/default_theme/default_theme.cpp290
-rw-r--r--scene/resources/default_theme/default_theme.h4
-rw-r--r--scene/resources/default_theme/theme_data.h4
-rwxr-xr-xscene/resources/default_theme/xpmfix.sh2
-rw-r--r--scene/resources/environment.cpp80
-rw-r--r--scene/resources/environment.h23
-rw-r--r--scene/resources/font.cpp106
-rw-r--r--scene/resources/font.h31
-rw-r--r--scene/resources/gradient.cpp7
-rw-r--r--scene/resources/gradient.h10
-rw-r--r--scene/resources/height_map_shape_3d.cpp13
-rw-r--r--scene/resources/height_map_shape_3d.h12
-rw-r--r--scene/resources/line_shape_2d.cpp12
-rw-r--r--scene/resources/line_shape_2d.h8
-rw-r--r--scene/resources/material.cpp112
-rw-r--r--scene/resources/material.h53
-rw-r--r--scene/resources/mesh.cpp52
-rw-r--r--scene/resources/mesh.h24
-rw-r--r--scene/resources/mesh_data_tool.cpp44
-rw-r--r--scene/resources/mesh_data_tool.h12
-rw-r--r--scene/resources/mesh_library.cpp29
-rw-r--r--scene/resources/mesh_library.h5
-rw-r--r--scene/resources/multimesh.cpp11
-rw-r--r--scene/resources/multimesh.h14
-rw-r--r--scene/resources/navigation_mesh.cpp41
-rw-r--r--scene/resources/navigation_mesh.h52
-rw-r--r--scene/resources/packed_scene.cpp38
-rw-r--r--scene/resources/packed_scene.h38
-rw-r--r--scene/resources/particles_material.cpp44
-rw-r--r--scene/resources/particles_material.h12
-rw-r--r--scene/resources/physics_material.cpp4
-rw-r--r--scene/resources/physics_material.h8
-rw-r--r--scene/resources/polygon_path_finder.cpp4
-rw-r--r--scene/resources/polygon_path_finder.h12
-rw-r--r--scene/resources/primitive_meshes.cpp96
-rw-r--r--scene/resources/primitive_meshes.h70
-rw-r--r--scene/resources/ray_shape_2d.cpp8
-rw-r--r--scene/resources/ray_shape_2d.h8
-rw-r--r--scene/resources/ray_shape_3d.cpp11
-rw-r--r--scene/resources/ray_shape_3d.h8
-rw-r--r--scene/resources/rectangle_shape_2d.cpp46
-rw-r--r--scene/resources/rectangle_shape_2d.h10
-rw-r--r--scene/resources/resource_format_text.cpp144
-rw-r--r--scene/resources/resource_format_text.h40
-rw-r--r--scene/resources/segment_shape_2d.cpp4
-rw-r--r--scene/resources/segment_shape_2d.h4
-rw-r--r--scene/resources/shader.cpp8
-rw-r--r--scene/resources/shader.h10
-rw-r--r--scene/resources/shape_2d.cpp18
-rw-r--r--scene/resources/shape_2d.h9
-rw-r--r--scene/resources/shape_3d.cpp6
-rw-r--r--scene/resources/shape_3d.h4
-rw-r--r--scene/resources/skin.cpp12
-rw-r--r--scene/resources/skin.h9
-rw-r--r--scene/resources/sky.cpp6
-rw-r--r--scene/resources/sky.h8
-rw-r--r--scene/resources/sky_material.cpp105
-rw-r--r--scene/resources/sky_material.h10
-rw-r--r--scene/resources/sphere_shape_3d.cpp5
-rw-r--r--scene/resources/sphere_shape_3d.h4
-rw-r--r--scene/resources/style_box.cpp99
-rw-r--r--scene/resources/style_box.h51
-rw-r--r--scene/resources/surface_tool.cpp14
-rw-r--r--scene/resources/surface_tool.h22
-rw-r--r--scene/resources/syntax_highlighter.cpp23
-rw-r--r--scene/resources/syntax_highlighter.h6
-rw-r--r--scene/resources/text_file.cpp4
-rw-r--r--scene/resources/text_file.h4
-rw-r--r--scene/resources/text_line.cpp7
-rw-r--r--scene/resources/text_line.h6
-rw-r--r--scene/resources/text_paragraph.cpp231
-rw-r--r--scene/resources/text_paragraph.h24
-rw-r--r--scene/resources/texture.cpp113
-rw-r--r--scene/resources/texture.h88
-rw-r--r--scene/resources/theme.cpp39
-rw-r--r--scene/resources/theme.h6
-rw-r--r--scene/resources/tile_set.cpp21
-rw-r--r--scene/resources/tile_set.h6
-rw-r--r--scene/resources/video_stream.h4
-rw-r--r--scene/resources/visual_shader.cpp62
-rw-r--r--scene/resources/visual_shader.h42
-rw-r--r--scene/resources/visual_shader_nodes.cpp769
-rw-r--r--scene/resources/visual_shader_nodes.h265
-rw-r--r--scene/resources/visual_shader_sdf_nodes.cpp283
-rw-r--r--scene/resources/visual_shader_sdf_nodes.h132
-rw-r--r--scene/resources/world_2d.cpp51
-rw-r--r--scene/resources/world_2d.h10
-rw-r--r--scene/resources/world_3d.cpp25
-rw-r--r--scene/resources/world_3d.h6
-rw-r--r--scene/resources/world_margin_shape_3d.cpp5
-rw-r--r--scene/resources/world_margin_shape_3d.h4
-rw-r--r--scene/scene_string_names.cpp4
-rw-r--r--scene/scene_string_names.h4
-rw-r--r--servers/audio/audio_driver_dummy.cpp25
-rw-r--r--servers/audio/audio_driver_dummy.h6
-rw-r--r--servers/audio/audio_effect.cpp4
-rw-r--r--servers/audio/audio_effect.h4
-rw-r--r--servers/audio/audio_filter_sw.cpp10
-rw-r--r--servers/audio/audio_filter_sw.h4
-rw-r--r--servers/audio/audio_rb_resampler.cpp18
-rw-r--r--servers/audio/audio_rb_resampler.h61
-rw-r--r--servers/audio/audio_stream.cpp24
-rw-r--r--servers/audio/audio_stream.h4
-rw-r--r--servers/audio/effects/audio_effect_amplify.cpp4
-rw-r--r--servers/audio/effects/audio_effect_amplify.h4
-rw-r--r--servers/audio/effects/audio_effect_capture.cpp140
-rw-r--r--servers/audio/effects/audio_effect_capture.h (renamed from modules/mono/editor/script_class_parser.h)108
-rw-r--r--servers/audio/effects/audio_effect_chorus.cpp10
-rw-r--r--servers/audio/effects/audio_effect_chorus.h4
-rw-r--r--servers/audio/effects/audio_effect_compressor.cpp4
-rw-r--r--servers/audio/effects/audio_effect_compressor.h4
-rw-r--r--servers/audio/effects/audio_effect_delay.cpp6
-rw-r--r--servers/audio/effects/audio_effect_delay.h4
-rw-r--r--servers/audio/effects/audio_effect_distortion.cpp11
-rw-r--r--servers/audio/effects/audio_effect_distortion.h4
-rw-r--r--servers/audio/effects/audio_effect_eq.cpp4
-rw-r--r--servers/audio/effects/audio_effect_eq.h4
-rw-r--r--servers/audio/effects/audio_effect_filter.cpp4
-rw-r--r--servers/audio/effects/audio_effect_filter.h4
-rw-r--r--servers/audio/effects/audio_effect_limiter.cpp4
-rw-r--r--servers/audio/effects/audio_effect_limiter.h4
-rw-r--r--servers/audio/effects/audio_effect_panner.cpp4
-rw-r--r--servers/audio/effects/audio_effect_panner.h4
-rw-r--r--servers/audio/effects/audio_effect_phaser.cpp10
-rw-r--r--servers/audio/effects/audio_effect_phaser.h4
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp4
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.h4
-rw-r--r--servers/audio/effects/audio_effect_record.cpp10
-rw-r--r--servers/audio/effects/audio_effect_record.h6
-rw-r--r--servers/audio/effects/audio_effect_reverb.cpp4
-rw-r--r--servers/audio/effects/audio_effect_reverb.h4
-rw-r--r--servers/audio/effects/audio_effect_spectrum_analyzer.cpp7
-rw-r--r--servers/audio/effects/audio_effect_spectrum_analyzer.h4
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.cpp4
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.h4
-rw-r--r--servers/audio/effects/audio_stream_generator.cpp4
-rw-r--r--servers/audio/effects/audio_stream_generator.h4
-rw-r--r--servers/audio/effects/eq.cpp8
-rw-r--r--servers/audio/effects/eq.h4
-rw-r--r--servers/audio/effects/reverb.cpp8
-rw-r--r--servers/audio/effects/reverb.h4
-rw-r--r--servers/audio_server.cpp42
-rw-r--r--servers/audio_server.h10
-rw-r--r--servers/camera/camera_feed.cpp4
-rw-r--r--servers/camera/camera_feed.h4
-rw-r--r--servers/camera_server.cpp4
-rw-r--r--servers/camera_server.h4
-rw-r--r--servers/display_server.cpp11
-rw-r--r--servers/display_server.h11
-rw-r--r--servers/navigation_server_2d.cpp29
-rw-r--r--servers/navigation_server_2d.h10
-rw-r--r--servers/navigation_server_3d.cpp8
-rw-r--r--servers/navigation_server_3d.h10
-rw-r--r--servers/physics_2d/area_2d_sw.cpp8
-rw-r--r--servers/physics_2d/area_2d_sw.h4
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp4
-rw-r--r--servers/physics_2d/area_pair_2d_sw.h4
-rw-r--r--servers/physics_2d/body_2d_sw.cpp4
-rw-r--r--servers/physics_2d/body_2d_sw.h6
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp51
-rw-r--r--servers/physics_2d/body_pair_2d_sw.h4
-rw-r--r--servers/physics_2d/broad_phase_2d_basic.cpp4
-rw-r--r--servers/physics_2d/broad_phase_2d_basic.h4
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp6
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.h4
-rw-r--r--servers/physics_2d/broad_phase_2d_sw.cpp4
-rw-r--r--servers/physics_2d/broad_phase_2d_sw.h4
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp4
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h10
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.cpp12
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.h4
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp4
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.h4
-rw-r--r--servers/physics_2d/constraint_2d_sw.h4
-rw-r--r--servers/physics_2d/joints_2d_sw.cpp41
-rw-r--r--servers/physics_2d/joints_2d_sw.h29
-rw-r--r--servers/physics_2d/physics_server_2d_sw.cpp123
-rw-r--r--servers/physics_2d/physics_server_2d_sw.h31
-rw-r--r--servers/physics_2d/physics_server_2d_wrap_mt.cpp40
-rw-r--r--servers/physics_2d/physics_server_2d_wrap_mt.h74
-rw-r--r--servers/physics_2d/shape_2d_sw.cpp28
-rw-r--r--servers/physics_2d/shape_2d_sw.h8
-rw-r--r--servers/physics_2d/space_2d_sw.cpp131
-rw-r--r--servers/physics_2d/space_2d_sw.h6
-rw-r--r--servers/physics_2d/step_2d_sw.cpp4
-rw-r--r--servers/physics_2d/step_2d_sw.h4
-rw-r--r--servers/physics_3d/area_3d_sw.cpp8
-rw-r--r--servers/physics_3d/area_3d_sw.h4
-rw-r--r--servers/physics_3d/area_pair_3d_sw.cpp4
-rw-r--r--servers/physics_3d/area_pair_3d_sw.h4
-rw-r--r--servers/physics_3d/body_3d_sw.cpp24
-rw-r--r--servers/physics_3d/body_3d_sw.h8
-rw-r--r--servers/physics_3d/body_pair_3d_sw.cpp4
-rw-r--r--servers/physics_3d/body_pair_3d_sw.h4
-rw-r--r--servers/physics_3d/broad_phase_3d_basic.cpp4
-rw-r--r--servers/physics_3d/broad_phase_3d_basic.h4
-rw-r--r--servers/physics_3d/broad_phase_3d_sw.cpp4
-rw-r--r--servers/physics_3d/broad_phase_3d_sw.h4
-rw-r--r--servers/physics_3d/broad_phase_octree.cpp4
-rw-r--r--servers/physics_3d/broad_phase_octree.h4
-rw-r--r--servers/physics_3d/collision_object_3d_sw.cpp14
-rw-r--r--servers/physics_3d/collision_object_3d_sw.h4
-rw-r--r--servers/physics_3d/collision_solver_3d_sat.cpp719
-rw-r--r--servers/physics_3d/collision_solver_3d_sat.h4
-rw-r--r--servers/physics_3d/collision_solver_3d_sw.cpp43
-rw-r--r--servers/physics_3d/collision_solver_3d_sw.h4
-rw-r--r--servers/physics_3d/constraint_3d_sw.h4
-rw-r--r--servers/physics_3d/gjk_epa.cpp103
-rw-r--r--servers/physics_3d/gjk_epa.h4
-rw-r--r--servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp10
-rw-r--r--servers/physics_3d/joints/cone_twist_joint_3d_sw.h6
-rw-r--r--servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp8
-rw-r--r--servers/physics_3d/joints/generic_6dof_joint_3d_sw.h6
-rw-r--r--servers/physics_3d/joints/hinge_joint_3d_sw.cpp4
-rw-r--r--servers/physics_3d/joints/hinge_joint_3d_sw.h6
-rw-r--r--servers/physics_3d/joints/jacobian_entry_3d_sw.h4
-rw-r--r--servers/physics_3d/joints/pin_joint_3d_sw.cpp4
-rw-r--r--servers/physics_3d/joints/pin_joint_3d_sw.h6
-rw-r--r--servers/physics_3d/joints/slider_joint_3d_sw.cpp4
-rw-r--r--servers/physics_3d/joints/slider_joint_3d_sw.h6
-rw-r--r--servers/physics_3d/joints_3d_sw.h24
-rw-r--r--servers/physics_3d/physics_server_3d_sw.cpp329
-rw-r--r--servers/physics_3d/physics_server_3d_sw.h89
-rw-r--r--servers/physics_3d/physics_server_3d_wrap_mt.cpp140
-rw-r--r--servers/physics_3d/physics_server_3d_wrap_mt.h422
-rw-r--r--servers/physics_3d/shape_3d_sw.cpp264
-rw-r--r--servers/physics_3d/shape_3d_sw.h60
-rw-r--r--servers/physics_3d/space_3d_sw.cpp147
-rw-r--r--servers/physics_3d/space_3d_sw.h6
-rw-r--r--servers/physics_3d/step_3d_sw.cpp4
-rw-r--r--servers/physics_3d/step_3d_sw.h4
-rw-r--r--servers/physics_server_2d.cpp31
-rw-r--r--servers/physics_server_2d.h69
-rw-r--r--servers/physics_server_3d.cpp84
-rw-r--r--servers/physics_server_3d.h136
-rw-r--r--servers/register_server_types.cpp30
-rw-r--r--servers/register_server_types.h4
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp83
-rw-r--r--servers/rendering/renderer_canvas_cull.h38
-rw-r--r--servers/rendering/renderer_canvas_render.cpp4
-rw-r--r--servers/rendering/renderer_canvas_render.h4
-rw-r--r--servers/rendering/renderer_compositor.cpp4
-rw-r--r--servers/rendering/renderer_compositor.h4
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp555
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.h378
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp287
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h35
-rw-r--r--servers/rendering/renderer_rd/light_cluster_builder.cpp252
-rw-r--r--servers/rendering/renderer_rd/light_cluster_builder.h290
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp39
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h6
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h10
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp126
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_environment_rd.h155
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp3403
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.h668
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_forward.h599
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.cpp (renamed from servers/rendering/renderer_rd/renderer_scene_render_forward.cpp)2113
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h766
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp6429
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h1207
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp1491
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h292
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp526
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h255
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.cpp99
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.h5
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp144
-rw-r--r--servers/rendering/renderer_rd/shader_rd.h11
-rw-r--r--servers/rendering/renderer_rd/shaders/SCsub6
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl18
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl20
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_debug.glsl115
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_render.glsl168
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_store.glsl119
-rw-r--r--servers/rendering/renderer_rd/shaders/cube_to_dp.glsl45
-rw-r--r--servers/rendering/renderer_rd/shaders/gi.glsl160
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe.glsl25
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe_write.glsl14
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/resolve.glsl112
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl (renamed from servers/rendering/renderer_rd/shaders/scene_forward.glsl)1683
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl (renamed from servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl)304
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl107
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl204
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl205
-rw-r--r--servers/rendering/renderer_rd/shaders/shadow_reduce.glsl105
-rw-r--r--servers/rendering/renderer_rd/shaders/skeleton.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao.glsl13
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl330
-rw-r--r--servers/rendering/renderer_scene.cpp4
-rw-r--r--servers/rendering/renderer_scene.h37
-rw-r--r--servers/rendering/renderer_scene_cull.cpp1785
-rw-r--r--servers/rendering/renderer_scene_cull.h548
-rw-r--r--servers/rendering/renderer_scene_render.cpp4
-rw-r--r--servers/rendering/renderer_scene_render.h175
-rw-r--r--servers/rendering/renderer_storage.cpp27
-rw-r--r--servers/rendering/renderer_storage.h175
-rw-r--r--servers/rendering/renderer_thread_pool.cpp (renamed from modules/camera_iphone/camera_module.cpp)18
-rw-r--r--servers/rendering/renderer_thread_pool.h (renamed from modules/camera_iphone/camera_ios.h)24
-rw-r--r--servers/rendering/renderer_viewport.cpp29
-rw-r--r--servers/rendering/renderer_viewport.h15
-rw-r--r--servers/rendering/rendering_device.cpp62
-rw-r--r--servers/rendering/rendering_device.h58
-rw-r--r--servers/rendering/rendering_device_binds.cpp6
-rw-r--r--servers/rendering/rendering_device_binds.h4
-rw-r--r--servers/rendering/rendering_server_default.cpp168
-rw-r--r--servers/rendering/rendering_server_default.h1221
-rw-r--r--servers/rendering/rendering_server_globals.cpp4
-rw-r--r--servers/rendering/rendering_server_globals.h4
-rw-r--r--servers/rendering/rendering_server_wrap_mt.cpp178
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h800
-rw-r--r--servers/rendering/shader_language.cpp593
-rw-r--r--servers/rendering/shader_language.h35
-rw-r--r--servers/rendering/shader_types.cpp14
-rw-r--r--servers/rendering/shader_types.h4
-rw-r--r--servers/rendering_server.cpp283
-rw-r--r--servers/rendering_server.h78
-rw-r--r--servers/server_wrap_mt_common.h864
-rw-r--r--servers/text_server.cpp19
-rw-r--r--servers/text_server.h27
-rw-r--r--servers/xr/xr_interface.cpp4
-rw-r--r--servers/xr/xr_interface.h4
-rw-r--r--servers/xr/xr_positional_tracker.cpp4
-rw-r--r--servers/xr/xr_positional_tracker.h4
-rw-r--r--servers/xr_server.cpp4
-rw-r--r--servers/xr_server.h4
-rw-r--r--tests/SCsub5
-rw-r--r--tests/data/images/icon.bmpbin0 -> 262282 bytes
-rw-r--r--tests/data/images/icon.jpgbin0 -> 14866 bytes
-rw-r--r--tests/data/images/icon.pngbin0 -> 29261 bytes
-rw-r--r--tests/data/images/icon.tgabin0 -> 262162 bytes
-rw-r--r--tests/data/images/icon.webpbin0 -> 4522 bytes
-rw-r--r--tests/test_aabb.h4
-rw-r--r--tests/test_array.h186
-rw-r--r--tests/test_astar.h4
-rw-r--r--tests/test_basis.h4
-rw-r--r--tests/test_class_db.h113
-rw-r--r--tests/test_color.h4
-rw-r--r--tests/test_command_queue.h20
-rw-r--r--tests/test_config_file.h4
-rw-r--r--tests/test_crypto.h4
-rw-r--r--tests/test_curve.h4
-rw-r--r--tests/test_expression.h8
-rw-r--r--tests/test_file_access.h7
-rw-r--r--tests/test_geometry_2d.h553
-rw-r--r--tests/test_geometry_3d.h417
-rw-r--r--tests/test_gradient.h4
-rw-r--r--tests/test_gui.cpp8
-rw-r--r--tests/test_gui.h4
-rw-r--r--tests/test_hashing_context.h165
-rw-r--r--tests/test_image.h259
-rw-r--r--tests/test_json.h4
-rw-r--r--tests/test_list.h14
-rw-r--r--tests/test_local_vector.h229
-rw-r--r--tests/test_lru.h4
-rw-r--r--tests/test_macros.cpp4
-rw-r--r--tests/test_macros.h10
-rw-r--r--tests/test_main.cpp13
-rw-r--r--tests/test_main.h4
-rw-r--r--tests/test_marshalls.h329
-rw-r--r--tests/test_math.cpp8
-rw-r--r--tests/test_math.h4
-rw-r--r--tests/test_method_bind.h4
-rw-r--r--tests/test_node_path.h4
-rw-r--r--tests/test_oa_hash_map.cpp4
-rw-r--r--tests/test_oa_hash_map.h4
-rw-r--r--tests/test_object.h217
-rw-r--r--tests/test_ordered_hash_map.h4
-rw-r--r--tests/test_paged_array.h4
-rw-r--r--tests/test_path_follow_2d.h241
-rw-r--r--tests/test_path_follow_3d.h220
-rw-r--r--tests/test_pck_packer.h4
-rw-r--r--tests/test_physics_2d.cpp10
-rw-r--r--tests/test_physics_2d.h4
-rw-r--r--tests/test_physics_3d.cpp44
-rw-r--r--tests/test_physics_3d.h4
-rw-r--r--tests/test_random_number_generator.h32
-rw-r--r--tests/test_rect2.h20
-rw-r--r--tests/test_render.cpp8
-rw-r--r--tests/test_render.h4
-rw-r--r--tests/test_resource.h114
-rw-r--r--tests/test_shader_lang.cpp6
-rw-r--r--tests/test_shader_lang.h4
-rw-r--r--tests/test_string.h93
-rw-r--r--tests/test_text_server.h6
-rw-r--r--tests/test_utils.cpp (renamed from modules/icloud/icloud_module.cpp)26
-rw-r--r--tests/test_utils.h (renamed from core/os/rw_lock.cpp)23
-rw-r--r--tests/test_validate_testing.h10
-rw-r--r--tests/test_variant.h598
-rw-r--r--tests/test_xml_parser.h (renamed from drivers/windows/rw_lock_windows.cpp)83
-rw-r--r--thirdparty/README.md230
-rw-r--r--[-rwxr-xr-x]thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp0
-rw-r--r--[-rwxr-xr-x]thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h0
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp5
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h3
-rw-r--r--thirdparty/bullet/LinearMath/btQuickprof.cpp3
-rw-r--r--thirdparty/bullet/LinearMath/btScalar.h2
-rw-r--r--thirdparty/bullet/LinearMath/btSerializer.h2
-rw-r--r--thirdparty/doctest/doctest.h334
-rw-r--r--thirdparty/enet/enet/enet.h12
-rw-r--r--thirdparty/enet/enet/godot.h4
-rw-r--r--thirdparty/enet/godot.cpp4
-rw-r--r--thirdparty/enet/host.c3
-rw-r--r--thirdparty/enet/patches/godot_socket.patch (renamed from thirdparty/enet/patches/godot.patch)14
-rw-r--r--thirdparty/enet/peer.c34
-rw-r--r--thirdparty/enet/protocol.c312
-rw-r--r--thirdparty/harfbuzz/NEWS30
-rw-r--r--thirdparty/harfbuzz/src/hb-aat-layout.cc91
-rw-r--r--thirdparty/harfbuzz/src/hb-aat-layout.h305
-rw-r--r--thirdparty/harfbuzz/src/hb-algs.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-blob.cc54
-rw-r--r--thirdparty/harfbuzz/src/hb-blob.h35
-rw-r--r--thirdparty/harfbuzz/src/hb-blob.hh1
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh1146
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh1223
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer-serialize.cc519
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.cc266
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.h52
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.hh41
-rw-r--r--thirdparty/harfbuzz/src/hb-common.cc88
-rw-r--r--thirdparty/harfbuzz/src/hb-common.h293
-rw-r--r--thirdparty/harfbuzz/src/hb-directwrite.cc9
-rw-r--r--thirdparty/harfbuzz/src/hb-face.cc179
-rw-r--r--thirdparty/harfbuzz/src/hb-face.h6
-rw-r--r--thirdparty/harfbuzz/src/hb-font.cc1184
-rw-r--r--thirdparty/harfbuzz/src/hb-font.h391
-rw-r--r--thirdparty/harfbuzz/src/hb-ft.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-gdi.cc10
-rw-r--r--thirdparty/harfbuzz/src/hb-map.cc87
-rw-r--r--thirdparty/harfbuzz/src/hb-map.h6
-rw-r--r--thirdparty/harfbuzz/src/hb-null.hh1
-rw-r--r--thirdparty/harfbuzz/src/hb-open-type.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color.h3
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-deprecated.h3
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-font.cc3
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh18
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-common.hh5
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.cc40
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-map.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-metrics.cc9
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-name.h3
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc10
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc10
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-machine-index.hh69
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc17
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh668
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc515
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc15
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-use.hh17
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex.hh7
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc5
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape.cc25
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-tag-table.hh1416
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-tag.cc1
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var.cc115
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var.h44
-rw-r--r--thirdparty/harfbuzz/src/hb-set.cc207
-rw-r--r--thirdparty/harfbuzz/src/hb-set.h9
-rw-r--r--thirdparty/harfbuzz/src/hb-shape-plan.cc184
-rw-r--r--thirdparty/harfbuzz/src/hb-shape-plan.h14
-rw-r--r--thirdparty/harfbuzz/src/hb-shape.cc4
-rw-r--r--thirdparty/harfbuzz/src/hb-unicode.cc123
-rw-r--r--thirdparty/harfbuzz/src/hb-unicode.h343
-rw-r--r--thirdparty/harfbuzz/src/hb-version.h4
-rw-r--r--thirdparty/meshoptimizer/indexcodec.cpp80
-rw-r--r--thirdparty/meshoptimizer/meshoptimizer.h42
-rw-r--r--thirdparty/meshoptimizer/patches/simplifier_get_resulting_error.patch96
-rw-r--r--thirdparty/meshoptimizer/simplifier.cpp321
-rw-r--r--thirdparty/meshoptimizer/vertexcodec.cpp66
-rw-r--r--thirdparty/meshoptimizer/vertexfilter.cpp31
-rw-r--r--thirdparty/misc/patches/polypartition-godot-types.patch819
-rw-r--r--thirdparty/misc/polypartition.cpp1849
-rw-r--r--thirdparty/misc/polypartition.h378
-rw-r--r--thirdparty/misc/r128.h10
-rw-r--r--thirdparty/misc/triangulator.cpp1550
-rw-r--r--thirdparty/misc/triangulator.h306
-rwxr-xr-xthirdparty/opus/celt/arm/arm2gnu.pl353
-rw-r--r--thirdparty/pcre2/AUTHORS10
-rw-r--r--thirdparty/pcre2/LICENCE10
-rw-r--r--thirdparty/pcre2/src/config.h12
-rw-r--r--thirdparty/pcre2/src/pcre2.h10
-rw-r--r--thirdparty/pcre2/src/pcre2_auto_possess.c34
-rw-r--r--thirdparty/pcre2/src/pcre2_chartables.c38
-rw-r--r--thirdparty/pcre2/src/pcre2_compile.c197
-rw-r--r--thirdparty/pcre2/src/pcre2_config.c10
-rw-r--r--thirdparty/pcre2/src/pcre2_dfa_match.c38
-rw-r--r--thirdparty/pcre2/src/pcre2_internal.h21
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_compile.c1309
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_misc.c7
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_neon_inc.h34
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_simd_inc.h130
-rw-r--r--thirdparty/pcre2/src/pcre2_maketables.c64
-rw-r--r--thirdparty/pcre2/src/pcre2_match.c170
-rw-r--r--thirdparty/pcre2/src/pcre2_serialize.c16
-rw-r--r--thirdparty/pcre2/src/pcre2_study.c94
-rw-r--r--thirdparty/pcre2/src/pcre2_substitute.c195
-rw-r--r--thirdparty/pcre2/src/pcre2_tables.c352
-rw-r--r--thirdparty/pcre2/src/pcre2_ucd.c3959
-rw-r--r--thirdparty/pcre2/src/pcre2_ucp.h7
-rw-r--r--thirdparty/pcre2/src/pcre2_valid_utf.c4
-rw-r--r--thirdparty/pcre2/src/sljit/sljitConfig.h59
-rw-r--r--thirdparty/pcre2/src/sljit/sljitConfigInternal.h196
-rw-r--r--thirdparty/pcre2/src/sljit/sljitExecAllocator.c56
-rw-r--r--thirdparty/pcre2/src/sljit/sljitLir.c152
-rw-r--r--thirdparty/pcre2/src/sljit/sljitLir.h140
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_32.c150
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_64.c111
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c81
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c42
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c33
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c193
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_32.c11
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_64.c12
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_common.c61
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeS390X.c2812
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c11
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c60
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c10159
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c2555
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_32.c50
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_64.c28
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_common.c230
-rw-r--r--thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c157
-rw-r--r--thirdparty/pcre2/src/sljit/sljitUtils.c354
-rw-r--r--thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c225
-rw-r--r--thirdparty/spirv-reflect/LICENSE201
-rw-r--r--thirdparty/spirv-reflect/include/spirv/unified1/spirv.h1129
-rw-r--r--thirdparty/spirv-reflect/spirv_reflect.c789
-rw-r--r--thirdparty/spirv-reflect/spirv_reflect.h206
-rw-r--r--thirdparty/zstd/common/bitstream.h39
-rw-r--r--thirdparty/zstd/common/compiler.h119
-rw-r--r--thirdparty/zstd/common/cpu.h2
-rw-r--r--thirdparty/zstd/common/debug.h29
-rw-r--r--thirdparty/zstd/common/entropy_common.c230
-rw-r--r--thirdparty/zstd/common/error_private.c1
-rw-r--r--thirdparty/zstd/common/error_private.h2
-rw-r--r--thirdparty/zstd/common/fse.h50
-rw-r--r--thirdparty/zstd/common/fse_decompress.c139
-rw-r--r--thirdparty/zstd/common/huf.h31
-rw-r--r--thirdparty/zstd/common/mem.h159
-rw-r--r--thirdparty/zstd/common/pool.c38
-rw-r--r--thirdparty/zstd/common/pool.h2
-rw-r--r--thirdparty/zstd/common/threading.c11
-rw-r--r--thirdparty/zstd/common/xxhash.c74
-rw-r--r--thirdparty/zstd/common/xxhash.h2
-rw-r--r--thirdparty/zstd/common/zstd_common.c18
-rw-r--r--thirdparty/zstd/common/zstd_deps.h111
-rw-r--r--thirdparty/zstd/common/zstd_errors.h1
-rw-r--r--thirdparty/zstd/common/zstd_internal.h147
-rw-r--r--thirdparty/zstd/compress/fse_compress.c53
-rw-r--r--thirdparty/zstd/compress/hist.c54
-rw-r--r--thirdparty/zstd/compress/hist.h2
-rw-r--r--thirdparty/zstd/compress/huf_compress.c316
-rw-r--r--thirdparty/zstd/compress/zstd_compress.c1750
-rw-r--r--thirdparty/zstd/compress/zstd_compress_internal.h160
-rw-r--r--thirdparty/zstd/compress/zstd_compress_literals.c8
-rw-r--r--thirdparty/zstd/compress/zstd_compress_sequences.c20
-rw-r--r--thirdparty/zstd/compress/zstd_compress_superblock.c42
-rw-r--r--thirdparty/zstd/compress/zstd_cwksp.h84
-rw-r--r--thirdparty/zstd/compress/zstd_double_fast.c44
-rw-r--r--thirdparty/zstd/compress/zstd_fast.c38
-rw-r--r--thirdparty/zstd/compress/zstd_lazy.c428
-rw-r--r--thirdparty/zstd/compress/zstd_lazy.h20
-rw-r--r--thirdparty/zstd/compress/zstd_ldm.c77
-rw-r--r--thirdparty/zstd/compress/zstd_ldm.h6
-rw-r--r--thirdparty/zstd/compress/zstd_opt.c235
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.c480
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.h134
-rw-r--r--thirdparty/zstd/decompress/huf_decompress.c502
-rw-r--r--thirdparty/zstd/decompress/zstd_ddict.c16
-rw-r--r--thirdparty/zstd/decompress/zstd_ddict.h2
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress.c205
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_block.c184
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_block.h7
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_internal.h21
-rw-r--r--thirdparty/zstd/zstd.h395
-rw-r--r--version.py2
2988 files changed, 178330 insertions, 99653 deletions
diff --git a/.editorconfig b/.editorconfig
index 49517a5104..7743622e78 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -17,7 +17,8 @@ indent_size = 4
indent_style = space
indent_size = 4
-[.travis.yml]
+# YAML requires indentation with spaces instead of tabs.
+[*.{yml,yaml}]
indent_style = space
indent_size = 2
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index e08c8bf9de..09ff2454ee 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -2,49 +2,181 @@
# Each line is a file pattern followed by one or more owners.
# Owners can be @users, @org/teams or emails
-/doc/ @godotengine/documentation
-doc_classes/* @godotengine/documentation
-
-# Rendering
-/drivers/gl_context/ @reduz
-/drivers/gles2/ @reduz
-/drivers/gles3/ @reduz
-
-# Audio
-/drivers/alsa/ @marcelofg55
-/drivers/alsamidi/ @marcelofg55
-/drivers/coreaudio/ @marcelofg55
-/drivers/coremidi/ @marcelofg55
-/drivers/pulseaudio/ @marcelofg55
-/drivers/wasapi/ @marcelofg55
-/drivers/winmidi/ @marcelofg55
-/drivers/xaudio2/ @marcelofg55
-
-/drivers/unix/ @hpvb
-/drivers/windows/ @hpvb
-
-/editor/icons/ @djrm
-
-/misc/ @akien-mga
-
-/modules/bullet/ @AndreaCatania
-/modules/csg/ @BastiaanOlij
-/modules/enet/ @godotengine/network
-/modules/gdnative/*arvr/ @BastiaanOlij
-/modules/gdscript/ @vnen
-/modules/mbedtls/ @godotengine/network
-/modules/mobile_vr/ @BastiaanOlij
-/modules/mono/ @neikeq
-/modules/mono/glue/GodotSharp @aaronfranke
-/modules/opensimplex/ @JFonS
-/modules/regex/ @LeeZH
-/modules/upnp/ @godotengine/network
-/modules/websocket/ @godotengine/network
-
-/platform/javascript/ @eska014
-/platform/uwp/ @vnen
-
-/server/physics*/ @reduz @AndreaCatania
-/server/visual*/ @reduz
-
-/thirdparty/ @akien-mga
+# Buildsystem
+
+.* @godotengine/buildsystem
+.github/ @godotengine/buildsystem
+*.py @godotengine/buildsystem
+SConstruct @godotengine/buildsystem
+SCsub @godotengine/buildsystem
+
+# Core
+
+/core/ @godotengine/core
+/core/crypto/ @godotengine/network
+/core/debugger/ @godotengine/debugger
+/core/input/ @godotengine/input
+
+# Doc
+
+/doc/ @godotengine/documentation
+doc_classes/* @godotengine/documentation
+
+# Drivers
+
+## Audio
+/drivers/alsa/ @godotengine/audio
+/drivers/alsamidi/ @godotengine/audio
+/drivers/coreaudio/ @godotengine/audio
+/drivers/coremidi/ @godotengine/audio
+/drivers/pulseaudio/ @godotengine/audio
+/drivers/wasapi/ @godotengine/audio
+/drivers/winmidi/ @godotengine/audio
+/drivers/xaudio2/ @godotengine/audio
+
+## Rendering
+/drivers/dummy/ @godotengine/rendering
+/drivers/spirv-reflect/ @godotengine/rendering
+/drivers/vulkan/ @godotengine/rendering
+
+## OS
+/drivers/unix/ @godotengine/_platforms
+/drivers/windows/ @godotengine/windows
+
+## Misc
+/drivers/png/ @godotengine/import
+
+# Editor
+
+/editor/*debugger* @godotengine/debugger
+/editor/icons/ @godotengine/usability
+/editor/import/ @godotengine/import
+/editor/plugins/*2d_*.* @godotengine/2d-editor
+/editor/plugins/*3d_*.* @godotengine/3d-editor
+/editor/plugins/script_*.* @godotengine/script-editor
+/editor/plugins/*shader*.* @godotengine/shaders
+/editor/code_editor.* @godotengine/script-editor
+/editor/*dock*.* @godotengine/docks
+/editor/*shader*.* @godotengine/shaders
+
+# Main
+
+/main/ @godotengine/core
+
+# Misc
+
+/misc/ @godotengine/buildsystem
+
+# Modules
+
+## Audio (+ video)
+/modules/minimp3/ @godotengine/audio
+/modules/ogg/ @godotengine/audio
+/modules/opus/ @godotengine/audio
+/modules/stb_vorbis/ @godotengine/audio
+/modules/theora/ @godotengine/audio
+/modules/vorbis/ @godotengine/audio
+/modules/webm/ @godotengine/audio
+
+## Import
+/modules/basis_universal/ @godotengine/import
+/modules/bmp/ @godotengine/import
+/modules/cvtt/ @godotengine/import
+/modules/dds/ @godotengine/import
+/modules/etc/ @godotengine/import
+/modules/fbx/ @godotengine/import
+/modules/gltf/ @godotengine/import
+/modules/hdr/ @godotengine/import
+/modules/jpg/ @godotengine/import
+/modules/pvr/ @godotengine/import
+/modules/squish/ @godotengine/import
+/modules/svg/ @godotengine/import
+/modules/tga/ @godotengine/import
+/modules/tinyexr/ @godotengine/import
+/modules/webp/ @godotengine/import
+
+## Network
+/modules/enet/ @godotengine/network
+/modules/mbedtls/ @godotengine/network
+/modules/upnp/ @godotengine/network
+/modules/webrtc/ @godotengine/network
+/modules/websocket/ @godotengine/network
+
+## Rendering
+/modules/denoise/ @godotengine/rendering
+/modules/glslang/ @godotengine/rendering
+/modules/lightmapper_rd/ @godotengine/rendering
+/modules/meshoptimizer/ @godotengine/rendering
+/modules/vhacd/ @godotengine/rendering
+/modules/xatlas_unwrap/ @godotengine/rendering
+
+## Scripting
+/modules/gdnative/ @godotengine/gdnative
+/modules/gdscript/ @godotengine/gdscript
+/modules/jsonrpc/ @godotengine/gdscript
+/modules/mono/ @godotengine/mono
+/modules/visual_script/ @godotengine/visualscript
+
+## Text
+/modules/freetype/ @godotengine/buildsystem
+/modules/gdnative/text/ @godotengine/gui-nodes
+/modules/text_server_adv/ @godotengine/gui-nodes
+/modules/text_server_fb/ @godotengine/gui-nodes
+
+## XR
+/modules/camera/ @godotengine/xr
+/modules/gdnative/xr/ @godotengine/xr
+/modules/mobile_vr/ @godotengine/xr
+/modules/webxr/ @godotengine/xr
+
+## Misc
+/modules/bullet/ @godotengine/physics
+/modules/csg/ @godotengine/3d-nodes
+/modules/gdnavigation/ @godotengine/navigation
+/modules/gridmap/ @godotengine/3d-nodes
+/modules/opensimplex/ @godotengine/3d-nodes
+/modules/regex/ @godotengine/core
+
+# Platform
+
+/platform/android/ @godotengine/android
+/platform/iphone/ @godotengine/ios
+/platform/javascript/ @godotengine/html5
+/platform/linuxbsd/ @godotengine/linux-bsd
+/platform/osx/ @godotengine/macos
+/platform/uwp/ @godotengine/uwp
+/platform/windows/ @godotengine/windows
+
+# Scene
+
+/scene/2d/ @godotengine/2d-nodes
+/scene/3d/ @godotengine/3d-nodes
+/scene/animation/ @godotengine/animation
+/scene/audio/ @godotengine/audio
+/scene/debugger/ @godotengine/debugger
+/scene/gui/ @godotengine/gui-nodes
+/scene/main/ @godotengine/core
+/scene/resources/default_theme/ @godotengine/gui-nodes
+/scene/resources/font.* @godotengine/gui-nodes
+/scene/resources/text_line.* @godotengine/gui-nodes
+/scene/resources/text_paragraph.* @godotengine/gui-nodes
+/scene/resources/visual_shader*.* @godotengine/shaders
+
+# Servers
+
+/servers/audio* @godotengine/audio
+/servers/camera* @godotengine/xr
+/servers/display_server.* @godotengine/_platforms
+/servers/navigation_server*.* @godotengine/navigation
+/servers/physics* @godotengine/physics
+/servers/rendering* @godotengine/rendering
+/servers/text_server.* @godotengine/gui-nodes
+/servers/xr* @godotengine/xr
+
+# Tests
+
+/tests/ @godotengine/tests
+
+# Thirdparty
+
+/thirdparty/ @godotengine/buildsystem
diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml
index f4b571fc08..b24a36beef 100644
--- a/.github/workflows/android_builds.yml
+++ b/.github/workflows/android_builds.yml
@@ -4,8 +4,9 @@ on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: master
- SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes --jobs=2
+ SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_LIMIT: 4096
+ ANDROID_NDK_VERSION: 21.1.6352462
jobs:
android-template:
@@ -28,6 +29,10 @@ jobs:
with:
java-version: 8
+ - name: Install Android NDK r21
+ run: |
+ sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install 'ndk;${{env.ANDROID_NDK_VERSION}}'
+
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: android-template-cache
@@ -59,7 +64,7 @@ jobs:
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
- ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk-bundle
+ ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/${{env.ANDROID_NDK_VERSION}}/
run: |
scons target=release tools=no android_arch=armv7
scons target=release tools=no android_arch=arm64v8
diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml
index fa965a45f1..c4da3cb683 100644
--- a/.github/workflows/ios_builds.yml
+++ b/.github/workflows/ios_builds.yml
@@ -4,7 +4,7 @@ on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: master
- SCONSFLAGS: platform=iphone verbose=yes warnings=extra werror=yes --jobs=2
+ SCONSFLAGS: platform=iphone verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_LIMIT: 4096
jobs:
diff --git a/.github/workflows/javascript_builds.disabled b/.github/workflows/javascript_builds.disabled
index 015a1f314c..006981f3d4 100644
--- a/.github/workflows/javascript_builds.disabled
+++ b/.github/workflows/javascript_builds.disabled
@@ -4,7 +4,7 @@ on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: master
- SCONSFLAGS: platform=javascript verbose=yes warnings=extra werror=yes --jobs=2
+ SCONSFLAGS: platform=javascript verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
EM_VERSION: 1.39.20
EM_CACHE_FOLDER: 'emsdk-cache'
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml
index b7b40eccbd..15a7be9c4f 100644
--- a/.github/workflows/linux_builds.yml
+++ b/.github/workflows/linux_builds.yml
@@ -4,13 +4,13 @@ on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: master
- SCONSFLAGS: platform=linuxbsd verbose=yes warnings=extra werror=yes --jobs=2
+ SCONSFLAGS: platform=linuxbsd verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_LIMIT: 4096
jobs:
- linux-editor-mono:
+ linux-editor:
runs-on: "ubuntu-20.04"
- name: Editor w/ Mono (target=release_debug, tools=yes, tests=yes)
+ name: Editor (target=release_debug, tools=yes, tests=yes)
steps:
- uses: actions/checkout@v2
@@ -62,13 +62,13 @@ jobs:
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
- scons tools=yes tests=yes target=release_debug module_mono_enabled=yes mono_glue=no
+ scons tools=yes tests=yes target=release_debug
ls -l bin/
# Execute unit tests for the editor
- name: Unit Tests
run: |
- ./bin/godot.linuxbsd.opt.tools.64.mono --test
+ ./bin/godot.linuxbsd.opt.tools.64 --test
- uses: actions/upload-artifact@v2
with:
@@ -76,9 +76,9 @@ jobs:
path: bin/*
retention-days: 14
- linux-editor-sanitizers:
+ linux-editor-sanitizers-mono:
runs-on: "ubuntu-20.04"
- name: Editor with sanitizers (target=debug, tools=yes, tests=yes, use_asan=yes, use_ubsan=yes)
+ name: Editor w/ Mono and sanitizers (target=debug, tools=yes, tests=yes, use_asan=yes, use_ubsan=yes)
steps:
- uses: actions/checkout@v2
@@ -130,13 +130,13 @@ jobs:
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
- scons tools=yes tests=yes target=debug use_asan=yes use_ubsan=yes
+ scons tools=yes tests=yes target=debug module_mono_enabled=yes mono_glue=no use_asan=yes use_ubsan=yes
ls -l bin/
# Execute unit tests for the editor
- name: Unit Tests
run: |
- ./bin/godot.linuxbsd.tools.64s --test
+ ./bin/godot.linuxbsd.tools.64s.mono --test
linux-template-mono:
runs-on: "ubuntu-20.04"
@@ -191,7 +191,7 @@ jobs:
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
- scons target=release tools=no module_mono_enabled=yes mono_glue=no debug_symbols=no
+ scons target=release tools=no module_mono_enabled=yes mono_glue=no
ls -l bin/
- uses: actions/upload-artifact@v2
diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml
index 401cfadc30..a15ab92052 100644
--- a/.github/workflows/macos_builds.yml
+++ b/.github/workflows/macos_builds.yml
@@ -4,7 +4,7 @@ on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: master
- SCONSFLAGS: platform=osx verbose=yes warnings=extra werror=yes --jobs=2
+ SCONSFLAGS: platform=osx verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_LIMIT: 4096
jobs:
@@ -104,7 +104,7 @@ jobs:
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
- scons target=release tools=no debug_symbols=no
+ scons target=release tools=no
ls -l bin/
- uses: actions/upload-artifact@v2
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index da3327246b..30468034ff 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -18,7 +18,9 @@ jobs:
- name: Install dependencies
run: |
- sudo apt-get install -qq dos2unix recode clang-format
+ sudo apt-get install -qq dos2unix recode clang-format-11
+ sudo update-alternatives --remove-all clang-format
+ sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-11 100
sudo pip3 install black==20.8b1 pygments
- name: File formatting checks (file_format.sh)
@@ -33,11 +35,12 @@ jobs:
run: |
bash ./misc/scripts/black_format.sh
- - name: JavaScript style checks via ESLint
+ - name: JavaScript style and documentation checks via ESLint and JSDoc
run: |
cd platform/javascript
npm ci
npm run lint
+ npm run docs -- -d dry-run
- name: Documentation checks
run: |
diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml
index e8f3d3d297..b7cc127226 100644
--- a/.github/workflows/windows_builds.yml
+++ b/.github/workflows/windows_builds.yml
@@ -5,7 +5,7 @@ on: [push, pull_request]
# SCONS_CACHE for windows must be set in the build environment
env:
GODOT_BASE_BRANCH: master
- SCONSFLAGS: platform=windows verbose=yes warnings=all werror=yes --jobs=2
+ SCONSFLAGS: platform=windows verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_MSVC_CONFIG: true
SCONS_CACHE_LIMIT: 3072
@@ -24,7 +24,7 @@ jobs:
# Editing this is pretty dangerous for Windows since it can break and needs to be properly tested with a fresh cache.
- name: Load .scons_cache directory
id: windows-editor-cache
- uses: RevoluPowered/cache@v2.1
+ uses: actions/cache@v2
with:
path: /.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
@@ -110,7 +110,7 @@ jobs:
env:
SCONS_CACHE: /.scons_cache/
run: |
- scons target=release tools=no debug_symbols=no
+ scons target=release tools=no
ls -l bin/
- uses: actions/upload-artifact@v2
diff --git a/.gitignore b/.gitignore
index f928c2e6ec..c1c2374bc3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -268,9 +268,12 @@ __pycache__/
# KDE
.directory
-#Kdevelop project files
+# Kdevelop project files
*.kdev4
+# Kate swap files
+*.kate-swp
+
# Xcode
xcuserdata/
*.xcscmblueprint
@@ -386,3 +389,4 @@ gcov.css
# https://clangd.llvm.org/ cache folder
.clangd/
+.cache/
diff --git a/.mailmap b/.mailmap
index 06fd11e521..dfbd13e612 100644
--- a/.mailmap
+++ b/.mailmap
@@ -6,6 +6,7 @@ Anish Bhobe <anishbhobe@hotmail.com>
Anutrix <numaanzaheerahmed@yahoo.com>
Aren Villanueva <arenvillanueva@yomogi-soft.com> <aren@displaysweet.com>
Ariel Manzur <ariel@godotengine.org>
+Ariel Manzur <ariel@godotengine.org> <puntob@gmail.com>
Ariel Manzur <ariel@godotengine.org> <punto@godotengine.org>
Ariel Manzur <ariel@godotengine.org> <ariel@okamstudio.com>
Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini.local>
@@ -25,6 +26,7 @@ Daniel J. Ramirez <djrmuv@gmail.com>
Dominik 'dreamsComeTrue' Jasiński <dominikjasinski@o2.pl>
Emmanuel Barroga <emmanuelbarroga@gmail.com>
Eric M <itsjusteza@gmail.com>
+Eric Rybicki <info@ericrybicki.com> <stratos695@googlemail.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com>
Fabian <supagu@gmail.com>
@@ -38,6 +40,7 @@ Gilles Roudiere <gilles.roudiere@gmail.com> <gilles.roudiere@laas.fr>
Gordon MacPherson <gordon@gordonite.tech>
Guilherme Felipe <guilhermefelipecgs@gmail.com>
Hanif Bin Ariffin <hanif.ariffin.4326@gmail.com>
+HaSa1002 <johawitt@outlook.de>
Hein-Pieter van Braam-Stewart <hp@tmm.cx>
Hubert Jarosz <marqin.pl@gmail.com>
Hubert Jarosz <marqin.pl@gmail.com> <marqin.pl+git@gmail.com>
@@ -84,6 +87,7 @@ Mateo Kuruk Miccino <mateomiccino@gmail.com>
Max Hilbrunner <m.hilbrunner@gmail.com>
Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com>
Michael Alexsander <michaelalexsander@protonmail.com>
+Nathan Franke <natfra@pm.me> <nathanwfranke@gmail.com>
Nathan Lovato <nathan@gdquest.com>
Nathan Warden <nathan@nathanwarden.com> <nathanwardenlee@icloud.com>
Nils ANDRÉ-CHANG <nils@nilsand.re>
@@ -97,7 +101,7 @@ Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Pieter-Jan Briers <pieterjan.briers+git@gmail.com> <pieterjan.briers@gmail.com>
Poommetee Ketson <poommetee@protonmail.com>
Przemysław Gołąb (n-pigeon) <golab.przemyslaw@gmail.com>
-Rafał Mikrut <mikrutrafal54@gmail.com>
+Rafał Mikrut <mikrutrafal@protonmail.com> <mikrutrafal54@gmail.com>
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@posteo.de>
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@users.noreply.github.com>
Ramesh Ravone <ramesh.maran443@gmail.com>
@@ -116,11 +120,13 @@ Theo Hallenius <redsymbzone@hotmail.com>
Thomas Herzog <therzog@mail.de>
Thomas Herzog <therzog@mail.de> <thomas.herzog@mail.com>
Thomas Herzog <therzog@mail.de> <thomas.herzog@simedis.com>
+Tomasz Chabora <kobewi4e@gmail.com>
Twarit <wtwarit@gmail.com>
V.VamsiKrishna <vk@bsb.in> <vamsikrishna.v@gmail.com>
Wilhem Barbier <nounoursheureux@openmailbox.org> <wilhem.b@free.fr>
Wilhem Barbier <nounoursheureux@openmailbox.org> <schtroumps31@gmail.com>
Will Nations <willnationsdev@gmail.com>
yg2f <yoann@terminajones.com>
+Yuri Sizov <yuris@humnom.net> <pycbouh@users.noreply.github.com>
Zak Stam <zakscomputers@hotmail.com>
Zher Huei Lee <lee.zh.92@gmail.com>
diff --git a/AUTHORS.md b/AUTHORS.md
index 97c66a014c..8c26d2892b 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -57,7 +57,9 @@ name is available.
Daniel J. Ramirez (djrm)
Daniel Rakos (aqnuep)
dankan1890
+ Danil Alexeev (dalexeev)
David Sichma (DavidSichma)
+ David Snopek (dsnopek)
Dharkael (lupoDharkael)
Dmitry Koteroff (Krakean)
Dominik Jasiński (dreamsComeTrue)
@@ -99,6 +101,7 @@ name is available.
Jérôme Gully (Nutriz)
Jia Jun Chai (SkyLucilfer)
Joan Fons Sanchez (JFonS)
+ Johannes Witt (HaSa1002)
Johan Manuel (29jm)
Joshua Grams (JoshuaGrams)
Juan Linietsky (reduz)
@@ -111,6 +114,7 @@ name is available.
Leon Krause (leonkrause)
Liz Haas (27thLiz)
Lucien Menassol (Kanabenki)
+ Lyuma
m4nu3lf
Maganty Rushyendra (mrushyendra)
Marcel Admiraal (madmiraal)
@@ -135,6 +139,7 @@ name is available.
MichiRecRoom (LikeLakers2)
mrezai
muiroc
+ Nathan Franke (nathanfranke)
Nathan Lovato (NathanLovato)
Nathan Warden (NathanWarden)
Nils André-Chang (NilsIrl)
@@ -158,6 +163,7 @@ name is available.
Ray Koopa (RayKoopa)
Rémi Verschelde (akien-mga)
Rhody Lugo (rraallvv)
+ Ricardo Subtil (Ev1lbl0w)
Roberto F. Arroyo (robfram)
Robin Hübner (profan)
romulox-x
@@ -188,6 +194,7 @@ name is available.
Xavier Cho (mysticfall)
yg2f (SuperUserNameMan)
Yuri Roubinsky (Chaosus)
+ Yuri Sizov (pycbouh)
Zak Stam (zaksnet)
Zher Huei Lee (leezh)
ZuBsPaCe
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1abd76b2ff..d7a4f976bf 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -72,6 +72,11 @@ by drag and dropping the file in the GitHub edition field.
We recommend always attaching a minimal reproduction project, even if the issue
may seem simple to reproduce manually.
+**Note for C# users:** If your issue is not Mono-specific, please upload a
+minimal reproduction project written in GDScript or VisualScript.
+This will make it easier for contributors to reproduce the issue
+locally as not everyone has a Mono setup available.
+
**If you've been asked by a maintainer to upload a minimal reproduction project,
you *must* do so within 7 days.** Otherwise, your bug report will be closed as
it'll be considered too difficult to diagnose.
@@ -236,25 +241,21 @@ discussions and support, others more for development discussions.
To communicate with developers (e.g. to discuss a feature you want to implement
or a bug you want to fix), the following channels can be used:
-- [GitHub issues](https://github.com/godotengine/godot/issues): If there is an
- existing issue about a topic you want to discuss, just add a comment to it -
- all developers watch the repository and will get an email notification. You
- can also create a new issue - please keep in mind to create issues only to
- discuss quite specific points about the development, and not general user
- feedback or support requests.
-- [#godotengine-devel IRC channel on
- Freenode](https://webchat.freenode.net/?channels=godotengine-devel): You will
- find most core developers there, so it's the go-to channel for direct chat
+- [Godot Contributors Chat](https://chat.godotengine.org): You will
+ find most core developers there, so it's the go-to platform for direct chat
about Godot Engine development. Feel free to start discussing something there
to get some early feedback before writing up a detailed proposal in a GitHub
issue.
-- [devel@godotengine.org mailing
- list](https://listengine.tuxfamily.org/godotengine.org/devel/): Mailing list
- for Godot developers, used primarily to announce developer meetings on IRC
- and other important discussions that need to reach people directly in their
- mailbox. See the [index
- page](https://listengine.tuxfamily.org/godotengine.org/devel/) for
- subscription instructions.
+- [Bug tracker](https://github.com/godotengine/godot/issues): If there is an
+ existing issue about a topic you want to discuss, just add a comment to it -
+ many developers watch the repository and will get a notification. You can
+ also create a new issue - please keep in mind to create issues only to
+ discuss quite specific points about the development, and not general user
+ feedback or support requests.
+- [Feature proposals](https://github.com/godotengine/godot-proposals/issues):
+ To propose a new feature, we have a dedicated issue tracker for that. Don't
+ hesitate to start by talking about your idea on the Godot Contributors Chat
+ to make sure that it makes sense in Godot's context.
Thanks for your interest in contributing!
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 03865b14ac..ff24d18e6f 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -30,7 +30,7 @@
# (e.g. a public domain dedication), but as far as Godot Engine is concerned
# the library is considered as a whole under the Zlib license.
#
-# Nota: When linking dynamically against thirdparty libraries instead of
+# Note: When linking dynamically against thirdparty libraries instead of
# building them into the Godot binary, you may remove the corresponding
# license details from this file.
@@ -43,8 +43,8 @@ Source: https://github.com/godotengine/godot
Files: *
Comment: Godot Engine
-Copyright: 2007-2020, Juan Linietsky, Ariel Manzur.
- 2014-2020, Godot Engine contributors.
+Copyright: 2007-2021, Juan Linietsky, Ariel Manzur.
+ 2014-2021, Godot Engine contributors.
License: Expat
Files: ./icon.png
@@ -55,56 +55,52 @@ Comment: Godot Engine logo
Copyright: 2017, Andrea Calabró
License: CC-BY-4.0
-Files: ./platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl
- ./platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml
- ./platform/android/java/src/com/google/android/vending/expansion/downloader/*
- ./platform/android/java/src/com/google/android/vending/licensing/*
- ./platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
- ./platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
-Comment: The Android Open Source Project
-Copyright: 2008-2013, The Android Open Source Project
-License: Apache-2.0
+Files: ./modules/fbx/fbx_parser/
+Comment: Open Asset Import Library (FBX parser)
+Copyright: 2006-2020, assimp team
+ 2007-2021, Juan Linietsky, Ariel Manzur.
+ 2014-2021, Godot Engine contributors.
+License: BSD-3-clause
-Files: ./platform/android/java/src/com/android/vending/licensing/util/Base64.java
- ./platform/android/java/src/com/android/vending/licensing/util/Base64DecoderException.java
+Files: ./platform/android/java/lib/aidl/com/android/*
+ ./platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml
+ ./platform/android/java/lib/src/com/google/android/*
+ ./platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java
+ ./platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java
Comment: The Android Open Source Project
-Copyright: 2002, Google Inc.
+Copyright: 2008-2016, The Android Open Source Project
+ 2002, Google, Inc.
License: Apache-2.0
-Files: ./scene/animation/tween_interpolaters.cpp
-Comment: Penner Easing
-Copyright: 2001, Robert Penner
+Files: ./servers/physics_3d/collision_solver_3d_sat.cpp
+Comment: Open Dynamics Engine
+Copyright: 2001-2003, Russell L. Smith, Alen Ladavac, Nguyen Binh
License: BSD-3-clause
-Files: ./servers/physics/gjk_epa.cpp
- ./servers/physics/joints/generic_6dof_joint_sw.cpp
- ./servers/physics/joints/generic_6dof_joint_sw.h
- ./servers/physics/joints/hinge_joint_sw.cpp
- ./servers/physics/joints/hinge_joint_sw.h
- ./servers/physics/joints/jacobian_entry_sw.h
- ./servers/physics/joints/pin_joint_sw.cpp
- ./servers/physics/joints/pin_joint_sw.h
- ./servers/physics/joints/slider_joint_sw.cpp
- ./servers/physics/joints/slider_joint_sw.h
+Files: ./servers/physics_3d/gjk_epa.cpp
+ ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
+ ./servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
+ ./servers/physics_3d/joints/hinge_joint_3d_sw.cpp
+ ./servers/physics_3d/joints/hinge_joint_3d_sw.h
+ ./servers/physics_3d/joints/jacobian_entry_3d_sw.h
+ ./servers/physics_3d/joints/pin_joint_3d_sw.cpp
+ ./servers/physics_3d/joints/pin_joint_3d_sw.h
+ ./servers/physics_3d/joints/slider_joint_3d_sw.cpp
+ ./servers/physics_3d/joints/slider_joint_3d_sw.h
Comment: Bullet Continuous Collision Detection and Physics Library
Copyright: 2003-2008, Erwin Coumans
- 2007-2020, Juan Linietsky, Ariel Manzur.
- 2014-2020, Godot Engine contributors.
+ 2007-2021, Juan Linietsky, Ariel Manzur.
+ 2014-2021, Godot Engine contributors.
License: Expat and Zlib
-Files: ./servers/physics/joints/cone_twist_joint_sw.cpp
- ./servers/physics/joints/cone_twist_joint_sw.h
+Files: ./servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp
+ ./servers/physics_3d/joints/cone_twist_joint_3d_sw.h
Comment: Bullet Continuous Collision Detection and Physics Library
Copyright: 2007, Starbreeze Studios
- 2007-2020, Juan Linietsky, Ariel Manzur.
- 2014-2020, Godot Engine contributors.
+ 2007-2021, Juan Linietsky, Ariel Manzur.
+ 2014-2021, Godot Engine contributors.
License: Expat and Zlib
-Files: ./thirdparty/assimp/
-Comment: Open Asset Import Library (assimp)
-Copyright: 2006-2016, assimp team
-License: BSD-3-clause
-
Files: ./thirdparty/basis_universal/
Comment: Basis Universal
Copyright: 2019, Binomial LLC.
@@ -169,7 +165,7 @@ License: FTL
Files: ./thirdparty/glslang/
Comment: glslang
-Copyright: 2015-2020 Google, Inc.
+Copyright: 2015-2020, Google, Inc.
2014-2020, The Khronos Group Inc
2002, NVIDIA Corporation.
License: glslang
@@ -181,19 +177,19 @@ License: MPL-2.0
Files: ./thirdparty/harfbuzz/
Comment: HarfBuzz text shaping library
-Copyright: 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 Google, Inc.
- 2018,2019,2020 Ebrahim Byagowi
- 2019,2020 Facebook, Inc.
- 2012 Mozilla Foundation
- 2011 Codethink Limited
- 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
- 2009 Keith Stribley
- 2009 Martin Hosken and SIL International
- 2007 Chris Wilson
- 2006 Behdad Esfahbod
- 2005 David Turner
- 2004,2007,2008,2009,2010 Red Hat, Inc.
- 1998-2004 David Turner and Werner Lemberg
+Copyright: 2010-2020, Google, Inc.
+ 2018-2020, Ebrahim Byagowi
+ 2019-2020, Facebook, Inc.
+ 2012, Mozilla Foundation
+ 2011, Codethink Limited
+ 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
+ 2009, Keith Stribley
+ 2009, Martin Hosken and SIL International
+ 2007, Chris Wilson
+ 2006, Behdad Esfahbod
+ 2005, David Turner
+ 2004, 2007-2010, Red Hat, Inc.
+ 1998-2004, David Turner and Werner Lemberg
License: HarfBuzz
Files: ./thirdparty/icu4c/
@@ -201,10 +197,10 @@ Comment: International Components for Unicode
Copyright: 1991-2020, Unicode
License: Unicode
-Files: ./thirdparty/jpeg_compressor/
+Files: ./thirdparty/jpeg-compressor/
Comment: jpeg-compressor
Copyright: 2012, Rich Geldreich
-License: public-domain
+License: public-domain or Apache-2.0
Files: ./thirdparty/libogg/
Comment: OggVorbis
@@ -258,12 +254,22 @@ License: BSD-3-clause
Files: ./thirdparty/mbedtls/
Comment: Mbed TLS
-Copyright: 2006-2018, Arm Limited (or its affiliates)
+Copyright: The Mbed TLS Contributors
License: Apache-2.0
+Files: ./thirdparty/meshoptimizer/
+Comment: meshoptimizer
+Copyright: 2016-2020, Arseny Kapoulkine
+License: Expat
+
+Files: ./thirdparty/minimp3/
+Comment: MiniMP3
+Copyright: lieff
+License: CC0-1.0
+
Files: ./thirdparty/miniupnpc/
Comment: MiniUPnPc
-Copyright: 2005-2018, Thomas Bernard
+Copyright: 2005-2019, Thomas Bernard
License: BSD-3-clause
Files: ./thirdparty/minizip/
@@ -279,6 +285,11 @@ Comment: Clipper
Copyright: 2010-2017, Angus Johnson
License: BSL-1.0
+Files: ./thirdparty/misc/cubemap_coeffs.h
+Comment: Fast Filtering of Reflection Probes
+Copyright: 2016, Activision Publishing, Inc.
+License: Expat
+
Files: ./thirdparty/misc/easing_equations.cpp
Comment: Robert Penner's Easing Functions
Copyright: 2001, Robert Penner
@@ -302,23 +313,41 @@ Comment: Tangent Space Normal Maps implementation
Copyright: 2011, Morten S. Mikkelsen
License: Zlib
+Files: ./thirdparty/misc/open-simplex-noise.c
+ ./thirdparty/misc/open-simplex-noise.h
+Comment: OpenSimplex Noise
+Copyright: 2014, Stephen M. Cameron
+License: public-domain or Unlicense
+
Files: ./thirdparty/misc/pcg.cpp
./thirdparty/misc/pcg.h
Comment: Minimal PCG32 implementation
Copyright: 2014, M.E. O'Neill
License: Apache-2.0
+Files: ./thirdparty/misc/polypartition.cpp
+ ./thirdparty/misc/polypartition.h
+Comment: PolyPartition / Triangulator
+Copyright: 2011-2021, Ivan Fratric and contributors
+License: Expat
+
+Files: ./thirdparty/misc/r128.c
+ ./thirdparty/misc/r128.h
+Comment: r128 library
+Copyright: Alan Hickman
+License: public-domain or Unlicense
+
Files: ./thirdparty/misc/smaz.c
./thirdparty/misc/smaz.h
Comment: SMAZ
Copyright: 2006-2009, Salvatore Sanfilippo
License: BSD-3-clause
-Files: ./thirdparty/misc/triangulator.cpp
- ./thirdparty/misc/triangulator.h
-Comment: PolyPartition
-Copyright: 2011, Ivan Fratric
-License: Expat
+Files: ./thirdparty/misc/stb_rect_pack.h
+ ./thirdparty/misc/stb_vorbis.c
+Comment: stb libraries
+Copyright: Sean Barrett
+License: public-domain or Unlicense or Expat
Files: ./thirdparty/misc/yuv2rgb.h
Comment: YUV2RGB
@@ -345,8 +374,8 @@ License: BSD-3-clause
Files: ./thirdparty/pcre2/
Comment: PCRE2
-Copyright: 1997-2019, University of Cambridge,
- 2009-2019, Zoltan Herczeg
+Copyright: 1997-2020, University of Cambridge
+ 2009-2020, Zoltan Herczeg
License: BSD-3-clause
Files: ./thirdparty/pvrtccompressor/
@@ -362,7 +391,12 @@ License: Zlib
Files: ./thirdparty/rvo2/
Comment: RVO2
Copyright: 2016, University of North Carolina at Chapel Hill
-License: Apache 2.0
+License: Apache-2.0
+
+Files: ./thirdparty/spirv-reflect/
+Comment: SPIRV-Reflect
+Copyright: 2017-2018, Google Inc.
+License: Apache-2.0
Files: ./thirdparty/squish/
Comment: libSquish
@@ -396,7 +430,7 @@ License: Expat
Files: ./thirdparty/wslay/
Comment: Wslay
-Copyright: 2011-2015, Tatsuhiro Tsujikawa
+Copyright: 2011, 2012, 2015, Tatsuhiro Tsujikawa
License: Expat
Files: ./thirdparty/xatlas/
@@ -548,6 +582,121 @@ License: BSL-1.0
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+License: CC0-1.0
+ CC0 1.0 Universal
+ .
+ Statement of Purpose
+ .
+ The laws of most jurisdictions throughout the world automatically confer
+ exclusive Copyright and Related Rights (defined below) upon the creator and
+ subsequent owner(s) (each and all, an "owner") of an original work of
+ authorship and/or a database (each, a "Work").
+ .
+ Certain owners wish to permanently relinquish those rights to a Work for the
+ purpose of contributing to a commons of creative, cultural and scientific
+ works ("Commons") that the public can reliably and without fear of later
+ claims of infringement build upon, modify, incorporate in other works, reuse
+ and redistribute as freely as possible in any form whatsoever and for any
+ purposes, including without limitation commercial purposes. These owners may
+ contribute to the Commons to promote the ideal of a free culture and the
+ further production of creative, cultural and scientific works, or to gain
+ reputation or greater distribution for their Work in part through the use and
+ efforts of others.
+ .
+ For these and/or other purposes and motivations, and without any expectation
+ of additional consideration or compensation, the person associating CC0 with a
+ Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
+ and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
+ and publicly distribute the Work under its terms, with knowledge of his or her
+ Copyright and Related Rights in the Work and the meaning and intended legal
+ effect of CC0 on those rights.
+ .
+ 1. Copyright and Related Rights. A Work made available under CC0 may be
+ protected by copyright and related or neighboring rights ("Copyright and
+ Related Rights"). Copyright and Related Rights include, but are not limited
+ to, the following:
+ .
+ i. the right to reproduce, adapt, distribute, perform, display, communicate,
+ and translate a Work;
+ .
+ ii. moral rights retained by the original author(s) and/or performer(s);
+ .
+ iii. publicity and privacy rights pertaining to a person's image or likeness
+ depicted in a Work;
+ .
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ .
+ v. rights protecting the extraction, dissemination, use and reuse of data in
+ a Work;
+ .
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation thereof,
+ including any amended or successor version of such directive); and
+ .
+ vii. other similar, equivalent or corresponding rights throughout the world
+ based on applicable law or treaty, and any national implementations thereof.
+ .
+ 2. Waiver. To the greatest extent permitted by, but not in contravention of,
+ applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
+ unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
+ and Related Rights and associated claims and causes of action, whether now
+ known or unknown (including existing as well as future claims and causes of
+ action), in the Work (i) in all territories worldwide, (ii) for the maximum
+ duration provided by applicable law or treaty (including future time
+ extensions), (iii) in any current or future medium and for any number of
+ copies, and (iv) for any purpose whatsoever, including without limitation
+ commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
+ the Waiver for the benefit of each member of the public at large and to the
+ detriment of Affirmer's heirs and successors, fully intending that such Waiver
+ shall not be subject to revocation, rescission, cancellation, termination, or
+ any other legal or equitable action to disrupt the quiet enjoyment of the Work
+ by the public as contemplated by Affirmer's express Statement of Purpose.
+ .
+ 3. Public License Fallback. Should any part of the Waiver for any reason be
+ judged legally invalid or ineffective under applicable law, then the Waiver
+ shall be preserved to the maximum extent permitted taking into account
+ Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
+ is so judged Affirmer hereby grants to each affected person a royalty-free,
+ non transferable, non sublicensable, non exclusive, irrevocable and
+ unconditional license to exercise Affirmer's Copyright and Related Rights in
+ the Work (i) in all territories worldwide, (ii) for the maximum duration
+ provided by applicable law or treaty (including future time extensions), (iii)
+ in any current or future medium and for any number of copies, and (iv) for any
+ purpose whatsoever, including without limitation commercial, advertising or
+ promotional purposes (the "License"). The License shall be deemed effective as
+ of the date CC0 was applied by Affirmer to the Work. Should any part of the
+ License for any reason be judged legally invalid or ineffective under
+ applicable law, such partial invalidity or ineffectiveness shall not
+ invalidate the remainder of the License, and in such case Affirmer hereby
+ affirms that he or she will not (i) exercise any of his or her remaining
+ Copyright and Related Rights in the Work or (ii) assert any associated claims
+ and causes of action with respect to the Work, in either case contrary to
+ Affirmer's express Statement of Purpose.
+ .
+ 4. Limitations and Disclaimers.
+ .
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ .
+ b. Affirmer offers the Work as-is and makes no representations or warranties
+ of any kind concerning the Work, express, implied, statutory or otherwise,
+ including without limitation warranties of title, merchantability, fitness
+ for a particular purpose, non infringement, or the absence of latent or
+ other defects, accuracy, or the present or absence of errors, whether or not
+ discoverable, all to the greatest extent permissible under applicable law.
+ .
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without limitation
+ any person's Copyright and Related Rights in the Work. Further, Affirmer
+ disclaims responsibility for obtaining any necessary consents, permissions
+ or other rights required for any use of the Work.
+ .
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to this
+ CC0 or use of the Work.
+
License: CC-BY-4.0
Creative Commons Attribution 4.0 International Public License
.
@@ -1729,6 +1878,32 @@ License: Unicode
use or other dealings in these Data Files or Software without prior
written authorization of the copyright holder.
+License: Unlicense
+ This is free and unencumbered software released into the public domain.
+ .
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+ .
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ .
+ For more information, please refer to <https://unlicense.org/>
+
License: Zlib
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
diff --git a/DONORS.md b/DONORS.md
index 58600f8f08..614ef1486a 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -32,6 +32,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Garry Newman
Gordon MacPherson
Hunter Dickson
+ Kyle Szklenski
## Mini sponsors
@@ -39,6 +40,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Alejandro Saucedo
alex brown
Andrew Dunai
+ Ben Nolan
+ blurp
CD
Christian Baune
Christoffer Sundbom
@@ -48,7 +51,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Digital Grows
Dov Zimring
Edward Flick
- Franz Silva
Gamechuck
GameDev.net
Hein-Pieter van Braam
@@ -59,6 +61,7 @@ generous deed immortalized in the next stable release of Godot Engine.
John G Gentzel
Jonah Stich
Justin Arnold
+ Kamil Brzezinski
Marcel Kräml
Matthieu Huvé
Maxim Karsten
@@ -68,6 +71,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Patrick Horn
Patrick Schmidt
Péter Magyar
+ Rami
Ronnie Cheng
Slobodan Milnovic
Stephan Lanfermann
@@ -76,34 +80,34 @@ generous deed immortalized in the next stable release of Godot Engine.
Tristan Pemble
VilliHaukka
Violin Iliev
+ Xwdit
## Gold donors
Acheron
albinaask
+ Alvaro A Baena R
Asher Glick
- Bernhard Werner
+ Barugon
Carlo Cabanilla
Chris Goddard
Christopher Case
Daniel James
David Gehrig
David Snopek
+ Don B
Ed Morley
Ellen Poe
Florian Neumann
Florian Rämisch
Forge
Gamejunkey
- Grady
Hoojib
Jakub Grzesik
Javier Roman
- Jeff Nyte
Joan Fons
Johnny IV Young
Jon Woodward
- Kai Klyden
Karl Werf
Klavdij Voncina
Lex Steers
@@ -115,13 +119,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Matthew Hillier
Michael
m kaersten
- Mohamed Ikbel Boulabiar
Monster Vial
Officine Pixel S.n.c.
- Pixel Booty
- Rami
Rene
- Rene Tailleur
Retro Village
Rob Messick
Roland Fredenhagen
@@ -136,25 +136,30 @@ generous deed immortalized in the next stable release of Godot Engine.
Tom Langwaldt
Tricky Fat Cat
tukon
+ Vitaliy Sapronenko
William Wold
xagonist
Xeno Coliseum
Zaven Muradyan
- Aaron Winter
Adam Nakonieczny
Adrian Adamiak
+ Aleksey Korotkevich
Alexander J Maynard
Alex de la Mare
+ Alexey Dyadchenko
Alex Khayrullin
alice gambrell
Andreas Funke
André Frélicot
+ Andrew Cunningham
+ Antanas Paskauskas
Antoni Batchelli
Arisaka Mayuki
- Aubin Detrez
- Barugon
+ Arthur S. Muszynski
Ben Botwin
+ Brandon Hawkinson
+ Caleb Sizemore
Can Eris
Charlie Whitfield
Chase Taranto
@@ -162,39 +167,42 @@ generous deed immortalized in the next stable release of Godot Engine.
Chris Petrich
Chris Serino
Christian Leth Jeppesen
- Cody Brooks
- Conrad Curry
Craig Ostrin
Craig Smith
+ Cristopher
D
+ dan didenko
Darrian Little
+ Dennis Belfrage
Dev To be curious
Digital Denizen
+ Dimitri Nüscheler
Donn Eddy
Easypete
Edgar Sun
Eugenio Hugo Salgüero Jáñez
flesk
- Francisco Arámburo
F S
Gabrielius Vaiškūnas
Gary Hulst
gavlig
+ General Chicken
GGGames.org
- GiulianoB
- Green Fox
Guilherme Felipe de C. G. da Silva
Harvey Fong
Heath Hayes
Horváth Péter
Hu Hund
- Idilio Alfaro
+ Jake Burga
James Couzens
Jared
Jared White
+ Jesús Chicharro
Joel Fivat
Joel Höglund
+ Johnathan Kupferer
Jose Malheiro
+ Jose Manuel Muñoz Perez
Joseph Crane
Joshie Sparks
Joshua Flores
@@ -208,35 +216,44 @@ generous deed immortalized in the next stable release of Godot Engine.
Kelteseth
kickmaniac
kinfox
+ Kos
kuku
Lachie
Lain Ballard
+ Laszlo Kiss
+ leetNightshade
Leo Fidel R Liban
+ Liam Smyth
Luc-Frédéric Langis
luka duren
MadScientistCarl
Marcelo Dornbusch Lopes
Marcus Dobler
Marcus Richter
- Marisa Clardy
+ Marek Belski
Mark Barrett
- Markus Fehr
Martin Eigel
Martin Kotz
Martin Soucek
Matt Eunson
Matt Greene
+ Matthias Toepp
+ medecau
Michael
Michael Dürwald
+ Michael Noll
+ Michael Policastro
+ MightyPossum
MikadoSC
MuffinManKen
Nick Abousselam
+ Nick Barovic
Oliver Dick
Oscar Campos
- Patrick Brock
Patrick Ting
Paul Hocker
Paul Von Zimmerman
+ Pavel Kotlyar
Pedro Silva
Pete Goodwin
Petr Malac
@@ -244,39 +261,43 @@ generous deed immortalized in the next stable release of Godot Engine.
pl
Raymond Harris
Raz A
+ Rene Tailleur
Ricardo Alcantara
+ Robert Larnach
Robert Willes
Rob McInroy
Rocknight Studios
Rodrigo Favarete
Ronnie Ashlock
Ronny Mühle
- Ryan Wilson
+ Ryan Scott
+ Ryszard Sommefeldt
Samuel Judd
- Scott Pilet
Sean Morgan
+ Sebastian Hutter
Sébastien
Serban Serafimescu
+ Sergey Fonaryov
Sergey Minakov
Shishir Tandale
SKison
+ Song Junwoo
spilldata
Stephan Hennion
Steven Landow
Stoned Xander
- TheLevelOfDetail .
Thomas Bjarnelöf
Thomas Kurz
Tim Howard
Tobias Bocanegra
- Trent Fehl
+ Todd Smith
Turntsnaco
+ tweaklab
Valryia
Vincent Cloutier
Vlad Ceru Opran
VoidPointer
voxelv
- William Foster
Wojciech Chojnacki
xzibiting
Yuancheng Zhang
@@ -287,7 +308,6 @@ generous deed immortalized in the next stable release of Godot Engine.
## Silver donors
1D_Inc
- Aaron Passchier
Abraham Haskins
Adam
Adam Brunnmeier
@@ -305,48 +325,47 @@ generous deed immortalized in the next stable release of Godot Engine.
AJ Austinson
Aki Mimoto
Alan Beauchamp
+ Alberto Vilches
Albin Jonasson Svärdsby
Alder Stefano
AleMax
Alessandro Senese
Alexander Erlemann
+ Alexander Ryndin
+ Alexander Walter (SilvanuZ)
Alexandre Beaudoin
alex clavelle
- Ali Al-Khalifa
+ Alex Schmidt
Allan Davis
Allen Schade
- Ancient Phoenix
Anders Marstein Kruke
Andreas Krampitz
- André Simões
Andre Stackhouse
andrew james morris
Andrew Mansuetti
- Andrew Rosenwinkel
Andrew Thomas
Ano Nim
Anthony Avina
+ Anton Bouwer
aomimezura11
AP Condomines
Arch Toasty
Arda Erol
Armin Preiml
Arseniy M
- Arthur S. Muszynski
Ashley Claymore
Astier Mickael
Aubrey Falconer
AzulCrescent
- B A
Balázs Batári
- Balázs Kondákor
Bartosz Bielecki
- Bekhoucha Danyl
Benedikt
Ben Vercammen
Bernd Jänichen
+ Bernhard Werner
Bjarne Voigtländer
Black Block
+ blackjacksike
Blair Allen
Bobby CC Wong
Borkzilla
@@ -356,7 +375,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Brian Klein
Brodie Fairhall
Bronson Zgeb
+ Bùi Việt Thành
Burney Waring
+ bwhirt
Caleb Gartner
Cameron Meyer
Carlos Cejudo
@@ -364,7 +385,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Carwyn Edwards
Cas Brugman
Cassidy James
+ Cédric Givord
Chad Steadman
+ Charles Alston
Chris Chapin
Chris Jagusch
Chris Langford
@@ -373,12 +396,13 @@ generous deed immortalized in the next stable release of Godot Engine.
Christian Winter
Christoffer Dahlblom
Christophe Gagnier
+ Christopher Chin
Christopher Schmitt
- Christoph Woinke
Chris Truebe
Clay Heaton
+ Cody Parker
Conall O
- Cyrelouyea
+ Craig Post
CzechBlueBear
Daniel Cheney
Daniel Johnson
@@ -393,25 +417,24 @@ generous deed immortalized in the next stable release of Godot Engine.
Dmitry Fisher
Dmytro Korchynskyi
Dominik Wetzel
+ Douglas Plumley
Dragontrapper
Dr Ewan Murray
Dr.Raccoon
Duobix
Duodecimal
+ DurrDiss
Eduardo Teixeira
Edward Herbert
Edward Swartz
- Eelco F Hillenius
Egon Elbre
Elgenzay
Elias Nykrem
Ephemeral
- Eric Ellingson
+ Eric Walkingshaw
Eric Williams
Erkki Seppälä
- ET Garcia
Evan Rose
- Fain
Faisal Alkubaisi
Fancy Ants Studios
Fekinox
@@ -421,14 +444,15 @@ generous deed immortalized in the next stable release of Godot Engine.
Francois Holland
Frank
FuDiggity
- Gadzhi Kharkharov
gamedev by Celio
+ Game Endeavor
+ Gareth Knowles
Gary Thomas
George Marques
- Gerard Ruiz Torruella
+ georgios katsanakis
+ GFizz
Greg Lincoln
Greg Olson
- GREGORY C FEIN
Greyson Richey
Grid
Guillaume Audirac
@@ -438,19 +462,15 @@ generous deed immortalized in the next stable release of Godot Engine.
Hal A
helija
Heribert Hirth
- Hoai Nam Tran
Hunter Jones
- Hylpher
Ian Williams
Iiari
- iKlem
IndustrialRobot
+ Ivan Nikolaev
iveks
- Ivica Šimić
Jackson Harmer
Jacob
Jaguar
- Jaiden Gerig
Jaime Ruiz-Borau Vizárraga
Jake D
Jake Huxell
@@ -458,17 +478,18 @@ generous deed immortalized in the next stable release of Godot Engine.
James
James A F Manley
James Thomas
- Jamiee H
Jamie Massey
+ Jan Vetulani
JARKKO PARVIAINEN
Jason Uechi
Jean-Baptiste LEPESME
Jeff Hungerford
Jennifer Graves
Jesse Dubay
- Joe Alden
+ Jhon Adams
Joe Klemmer
John Gabriel
+ Jonah Branch
Jonas
Jonas Bernemann
Jonas Rudlang
@@ -480,45 +501,46 @@ generous deed immortalized in the next stable release of Godot Engine.
Jon Sully
Jordy Goodridge
Jorge Antunes
- Jorge Javier Araya Navarro
+ Jorge Araya Navarro
Jose C. Rubio
Joseph Catrambone
- Josh Mitchell
Josh Taylor
- Joshua Southerland
+ Josue David
+ jromkjrom
Juanfran
+ Juan Uys
Jueast
Julian Murgia
June Little
- JungleRobba
+ Justin Hamilton
Justin Oaksford
Justin Spedding
+ Justin W. Flory
KaDokta
Kalin
- Karel Němec
- Kauzig
Keedong Park
Keinan Powers
Keith Bradner
Kenji Kawabata
+ Ken Minardo
Kenneth Lee
Kent Jofur
+ Ketafuki
Kevin McPhillips
Kiri Jolly
- Kiyohiro Kawamura (kyorohiro)
Kjetil Haugland
+ Konstantin Goncharov
+ Kridsada Thanabulpong
Kristian Nygaard Jensen
KsyTek Games
- Kuan Cheang
kycho
Kyle Jacobs
- Kyle Szklenski
Kyuppin
+ Lasse le Dous
Laurent CHEA
Laurent Tréguier
- Lee Meichin
+ Laxman Pradhan
LEMMiNO
- Lenny
Leonardo Dimano
Lin Chear
Linus Lind Lundgren
@@ -527,92 +549,95 @@ generous deed immortalized in the next stable release of Godot Engine.
Luis Gaemperle
Luis M
LunaticInAHat
- Lurkars
Major Haul
makoto asano
Malcolm
Marco Lardelli
Mark Jad
- Mark Krenz
+ Mark Malone
Markus Martin
Markus Michael Egger
Martin FIbik
Martin Holas
- Martin Linklater
Martin Trbola
Marvin
Mathieu
Matt Edwards
Matthew Booe
- Max Brister
Max Fiedler
Maxime Blade
Maxwell
Megasploot
Melissa Mears
+ Merlyn Morgan-Graham
mewin
Michael
+ Michael Bruce-Lockhart
Michael Haney
Michał Skwarek
+ MidoriBunn 'tis BS
Mikayla
Mike Birkhead
Mike Cunningham
Mitchell J. Wagner
Molinghu
Molly Jameson
- MoM
MrAZIE
Nathan Fish
Nathaniel
Natrim
nee
+ neighty
Neil Blakey-Milner
Neil Wang
Nerdforge
Nerdyninja
Nicholas
- Nicholas Girga
Nick Allen
Nick Macholl
Niclas Eriksen
Nicolas Goll-Perrier
- Nicolás Montaña
+ Nicolas Rosset
Nicolas SAN AGUSTIN
Nima Farid
NZ
+ oceoh
OKV
Oleg Reva
Oleksandr Kryvonos
- Olivier
Omar Delarosa
+ Oriol Muñoz Princep
Oscar Domingo
- Oscar Norlander
Parinya Teerakasemsuk
patricio lara briones
+ Patrick Brock
Patrick Dully
Patrick Nafarrete
Paul Gieske
- Paul Mason
Paweł Kowal
PaweÅ‚ Åyczkowski
- Pedro Assuncao
+ Peter Höglund
+ Peter Richmond
Petrus Prinsloo
Philip Cohoe
+ Pierre Caye
Piotr Góral
+ Pipo
Point08
Preethi Vaidyanathan
- Price Comstock
pwab
+ Rad Cat
Rafa Laguna
Raffaele Aramo
+ Rami Hanano
+ RAMupgrade
Remi Rampin
Rémi Verschelde
Reneator
- Richard Diss
+ Riccardo Marini
Richard Ivánek
Riley
Robert Farr (Larington)
- Robert Larnach
Rob Ruana
Roger Smith
Roland RzÄ…sa
@@ -621,21 +646,23 @@ generous deed immortalized in the next stable release of Godot Engine.
Ronan
Ross Squires
Ryan Groom
+ Sam Caulfield
Sam Edson
Samuele Zolfanelli
- sayaks
+ scapegoat57
Scott D. Yelich
Scott Longley
- ScottMakesGames
+ Sean Lynch
Sebastian Michailidis
- Sebastian Vetter
SeongWan Kim
+ Serenitor
+ Sergey
Sergiy Onenko
- Shaher
Shane
Shane Sicienski
Shane Spoor
Siim Raidma
+ simdee
Simon Jonas Larsen
Simon Schoenenberger
Simon Wenner
@@ -644,26 +671,27 @@ generous deed immortalized in the next stable release of Godot Engine.
smo1704
soft circles
Squirrel
- Stefano Caronia
Steve Cloete
+ summerblind
Sung soo Choi
Svenne Krap
tadashi endo
tannhauser_gate
+ Tarch
Terry
+ The Liquidator
Theodore Lindsey
- TheTrainDoctor
TheVoiceInMyHead
thomas
Thomas Bechtold
Thomas Detoy
- Thomas Kelly
+ Thomas Horwath
Tim Drumheller
Tim Erskine
Tim Gleason
Timothy B. MacDonald
- Tobbun
Tobias Bradtke
+ Tom Coxon
Toni Duran
Tony Zhao
Torgeir Lilleskog
@@ -671,7 +699,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Travis O'Brien
Trent Skinner
tril zerobyte
- Triptych
Triumph263 .
Troy Bonneau
Tryggve Sollid
@@ -682,30 +709,25 @@ generous deed immortalized in the next stable release of Godot Engine.
Uther
Vaughan Ling
Victor
- Vigilant Watch
Viktor Ismagilov
- Vitaliy Sapronenko
- Vitor Balbio
+ Vi Watch
Vladimir Savin
Vladislav Smirnov
- Výrus Hemomancer
+ Vytenis Narušis
waka nya
Wayne Haak
werner mendizabal
Wiley Thompson
- Will
William Edwards
William F Siqueira
William Hogben
Wyatt Goodin
+ x1212
xenomat
Yegor Smirnov
- YiYin Gu
Zack Yang
Zak Stephens
- ΒΑΣΙΛΗΣ ΓΕΩΡΓΑΚΟΠΟΥΛΟΣ
蕭惟å…
- éƒæ™¨ç…œ
## Bronze donors
diff --git a/LICENSE.txt b/LICENSE.txt
index 52bd041102..bee83fb8b8 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,5 +1,5 @@
-Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 1f2aa00f08..72a85492fd 100644
--- a/README.md
+++ b/README.md
@@ -50,8 +50,7 @@ Godot is not only an engine but an ever-growing community of users and engine
developers. The main community channels are listed [on the homepage](https://godotengine.org/community).
To get in touch with the engine developers, the best way is to join the
-[#godotengine-devel IRC channel](https://webchat.freenode.net/?channels=godotengine-devel)
-on Freenode.
+[Godot Contributors Chat](https://chat.godotengine.org).
To get started contributing to the project, see the [contributing guide](CONTRIBUTING.md).
diff --git a/SConstruct b/SConstruct
index 2281b8a77f..b006dddbe6 100644
--- a/SConstruct
+++ b/SConstruct
@@ -55,17 +55,21 @@ custom_tools = ["default"]
platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False))
-if os.name == "nt" and (platform_arg == "android" or ARGUMENTS.get("use_mingw", False)):
+if os.name == "nt" and (platform_arg == "android" or methods.get_cmdline_bool("use_mingw", False)):
custom_tools = ["mingw"]
elif platform_arg == "javascript":
# Use generic POSIX build toolchain for Emscripten.
custom_tools = ["cc", "c++", "ar", "link", "textfile", "zip"]
+# We let SCons build its default ENV as it includes OS-specific things which we don't
+# want to have to pull in manually.
+# Then we prepend PATH to make it take precedence, while preserving SCons' own entries.
env_base = Environment(tools=custom_tools)
-if "TERM" in os.environ:
+env_base.PrependENVPath("PATH", os.getenv("PATH"))
+env_base.PrependENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH"))
+if "TERM" in os.environ: # Used for colored output.
env_base["ENV"]["TERM"] = os.environ["TERM"]
-env_base.AppendENVPath("PATH", os.getenv("PATH"))
-env_base.AppendENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH"))
+
env_base.disabled_modules = []
env_base.module_version_string = ""
env_base.msvc = False
@@ -95,7 +99,7 @@ env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL))
customs = ["custom.py"]
-profile = ARGUMENTS.get("profile", False)
+profile = ARGUMENTS.get("profile", "")
if profile:
if os.path.isfile(profile):
customs.append(profile)
@@ -105,15 +109,14 @@ if profile:
opts = Variables(customs, ARGUMENTS)
# Target build options
-opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "")
-opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64")))
opts.Add("p", "Platform (alias for 'platform')", "")
opts.Add("platform", "Target platform (%s)" % ("|".join(platform_list),), "")
+opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True))
opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release_debug", "release")))
+opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "")
+opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64")))
opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size")))
-
-opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True))
-opts.Add(BoolVariable("tests", "Build the unit tests", False))
+opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False))
opts.Add(BoolVariable("use_lto", "Use link-time optimization", False))
# Components
@@ -121,13 +124,15 @@ opts.Add(BoolVariable("deprecated", "Enable deprecated features", True))
opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True))
opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
+opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True))
# Advanced options
-opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
+opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False))
opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True))
+opts.Add(BoolVariable("tests", "Build the unit tests", False))
+opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extra", "all", "moderate", "no")))
opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", False))
-opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False))
opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "")
opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False))
opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False))
@@ -237,8 +242,14 @@ if env_base["custom_modules"]:
Exit(255)
for path in module_search_paths:
+ if path == "modules":
+ # Built-in modules don't have nested modules,
+ # so save the time it takes to parse directories.
+ modules = methods.detect_modules(path, recursive=False)
+ else: # External.
+ modules = methods.detect_modules(path, env_base["custom_modules_recursive"])
# Note: custom modules can override built-in ones.
- modules_detected.update(methods.detect_modules(path))
+ modules_detected.update(modules)
include_path = os.path.dirname(path)
if include_path:
env_base.Prepend(CPPPATH=[include_path])
@@ -308,7 +319,7 @@ if selected_platform in platform_list:
else:
env = env_base.Clone()
- # Compilation DB requires SCons 3.1.1+.
+ # Generating the compilation DB (`compile_commands.json`) requires SCons 4.0.0 or later.
from SCons import __version__ as scons_raw_version
scons_ver = env._get_major_minor_revision(scons_raw_version)
@@ -317,12 +328,34 @@ if selected_platform in platform_list:
env.Tool("compilation_db")
env.Alias("compiledb", env.CompilationDatabase())
+ # 'dev' and 'production' are aliases to set default options if they haven't been set
+ # manually by the user.
if env["dev"]:
- env["verbose"] = True
- env["warnings"] = "extra"
- env["werror"] = True
+ env["verbose"] = methods.get_cmdline_bool("verbose", True)
+ env["warnings"] = ARGUMENTS.get("warnings", "extra")
+ env["werror"] = methods.get_cmdline_bool("werror", True)
if env["tools"]:
- env["tests"] = True
+ env["tests"] = methods.get_cmdline_bool("tests", True)
+ if env["production"]:
+ env["use_static_cpp"] = methods.get_cmdline_bool("use_static_cpp", True)
+ env["use_lto"] = methods.get_cmdline_bool("use_lto", True)
+ env["debug_symbols"] = methods.get_cmdline_bool("debug_symbols", False)
+ if not env["tools"] and env["target"] == "debug":
+ print(
+ "WARNING: Requested `production` build with `tools=no target=debug`, "
+ "this will give you a full debug template (use `target=release_debug` "
+ "for an optimized template with debug features)."
+ )
+ if env.msvc:
+ print(
+ "WARNING: For `production` Windows builds, you should use MinGW with GCC "
+ "or Clang instead of Visual Studio, as they can better optimize the "
+ "GDScript VM in a very significant way. MSVC LTO also doesn't work "
+ "reliably for our use case."
+ "If you want to use MSVC nevertheless for production builds, set "
+ "`debug_symbols=no use_lto=no` instead of the `production=yes` option."
+ )
+ Exit(255)
env.extra_suffix = ""
@@ -588,7 +621,7 @@ if selected_platform in platform_list:
if env["minizip"]:
env.Append(CPPDEFINES=["MINIZIP_ENABLED"])
- editor_module_list = ["regex"]
+ editor_module_list = ["freetype", "regex"]
if env["tools"] and not env.module_check_dependencies("tools", editor_module_list):
print(
"Build option 'module_"
diff --git a/core/SCsub b/core/SCsub
index c9f84a9a00..21829553a7 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -54,7 +54,7 @@ thirdparty_misc_sources = [
"smaz.c",
# C++ sources
"pcg.cpp",
- "triangulator.cpp",
+ "polypartition.cpp",
"clipper.cpp",
]
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
diff --git a/core/config/engine.cpp b/core/config/engine.cpp
index 26f8cdf840..2360d66438 100644
--- a/core/config/engine.cpp
+++ b/core/config/engine.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/config/engine.h b/core/config/engine.h
index 0d9aa02f28..a9080e3dfd 100644
--- a/core/config/engine.h
+++ b/core/config/engine.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,7 +50,7 @@ private:
uint64_t frames_drawn = 0;
uint32_t _frame_delay = 0;
uint64_t _frame_ticks = 0;
- float _frame_step = 0;
+ float _process_step = 0;
int ips = 60;
float physics_jitter_fix = 0.5;
@@ -62,7 +62,7 @@ private:
bool abort_on_gpu_errors = false;
bool use_validation_layers = false;
- uint64_t _idle_frames = 0;
+ uint64_t _process_frames = 0;
bool _in_physics = false;
List<Singleton> singletons;
@@ -89,10 +89,10 @@ public:
uint64_t get_frames_drawn();
uint64_t get_physics_frames() const { return _physics_frames; }
- uint64_t get_idle_frames() const { return _idle_frames; }
+ uint64_t get_process_frames() const { return _process_frames; }
bool is_in_physics_frame() const { return _in_physics; }
- uint64_t get_idle_frame_ticks() const { return _frame_ticks; }
- float get_idle_frame_step() const { return _frame_step; }
+ uint64_t get_frame_ticks() const { return _frame_ticks; }
+ float get_process_step() const { return _process_step; }
float get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; }
void set_time_scale(float p_scale);
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index f939fca984..02effc2001 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#include "core/core_bind.h"
#include "core/core_string_names.h"
+#include "core/input/input_map.h"
#include "core/io/file_access_network.h"
#include "core/io/file_access_pack.h"
#include "core/io/marshalls.h"
@@ -124,6 +125,11 @@ void ProjectSettings::set_restart_if_changed(const String &p_name, bool p_restar
props[p_name].restart_if_changed = p_restart;
}
+void ProjectSettings::set_as_basic(const String &p_name, bool p_basic) {
+ ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
+ props[p_name].basic = p_basic;
+}
+
void ProjectSettings::set_ignore_value_in_docs(const String &p_name, bool p_ignore) {
ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
#ifdef DEBUG_METHODS_ENABLED
@@ -269,6 +275,10 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
vc.flags = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
}
+ if (v->basic) {
+ vc.flags |= PROPERTY_USAGE_EDITOR_BASIC_SETTING;
+ }
+
if (v->restart_if_changed) {
vc.flags |= PROPERTY_USAGE_RESTART_IF_CHANGED;
}
@@ -278,7 +288,7 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
for (Set<_VCSort>::Element *E = vclist.front(); E; E = E->next()) {
String prop_info_name = E->get().name;
int dot = prop_info_name.find(".");
- if (dot != -1) {
+ if (dot != -1 && !custom_prop_info.has(prop_info_name)) {
prop_info_name = prop_info_name.substr(0, dot);
}
@@ -597,6 +607,7 @@ Error ProjectSettings::_load_settings_text(const String &p_path) {
// If we're loading a project.godot from source code, we can operate some
// ProjectSettings conversions if need be.
_convert_to_last_version(config_version);
+ last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot"));
return OK;
} else if (err != OK) {
ERR_PRINT("Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted.");
@@ -676,7 +687,11 @@ void ProjectSettings::clear(const String &p_name) {
}
Error ProjectSettings::save() {
- return save_custom(get_resource_path().plus_file("project.godot"));
+ Error error = save_custom(get_resource_path().plus_file("project.godot"));
+ if (error == OK) {
+ last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot"));
+ }
+ return error;
}
Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) {
@@ -894,7 +909,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
custom_features += f;
}
- if (p_path.ends_with(".godot")) {
+ if (p_path.ends_with(".godot") || p_path.ends_with("override.cfg")) {
return _save_settings_text(p_path, props, p_custom, custom_features);
} else if (p_path.ends_with(".binary")) {
return _save_settings_binary(p_path, props, p_custom, custom_features);
@@ -903,7 +918,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
}
}
-Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed, bool p_ignore_value_in_docs) {
+Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed, bool p_ignore_value_in_docs, bool p_basic) {
Variant ret;
if (!ProjectSettings::get_singleton()->has_setting(p_var)) {
ProjectSettings::get_singleton()->set(p_var, p_default);
@@ -912,6 +927,7 @@ Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restar
ProjectSettings::get_singleton()->set_initial_value(p_var, p_default);
ProjectSettings::get_singleton()->set_builtin_order(p_var);
+ ProjectSettings::get_singleton()->set_as_basic(p_var, p_basic);
ProjectSettings::get_singleton()->set_restart_if_changed(p_var, p_restart_if_changed);
ProjectSettings::get_singleton()->set_ignore_value_in_docs(p_var, p_ignore_value_in_docs);
return ret;
@@ -1042,29 +1058,47 @@ void ProjectSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("save_custom", "file"), &ProjectSettings::_save_custom_bnd);
}
+void ProjectSettings::_add_builtin_input_map() {
+ if (InputMap::get_singleton()) {
+ OrderedHashMap<String, List<Ref<InputEvent>>> builtins = InputMap::get_singleton()->get_builtins();
+
+ for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) {
+ Array events;
+
+ // Convert list of input events into array
+ for (List<Ref<InputEvent>>::Element *I = E.get().front(); I; I = I->next()) {
+ events.push_back(I->get());
+ }
+
+ Dictionary action;
+ action["deadzone"] = Variant(0.5f);
+ action["events"] = events;
+
+ String action_name = "input/" + E.key();
+ GLOBAL_DEF(action_name, action);
+ input_presets.push_back(action_name);
+ }
+ }
+}
+
ProjectSettings::ProjectSettings() {
// Initialization of engine variables should be done in the setup() method,
// so that the values can be overridden from project.godot or project.binary.
singleton = this;
- Array events;
- Dictionary action;
- Ref<InputEventKey> key;
- Ref<InputEventJoypadButton> joyb;
-
- GLOBAL_DEF("application/config/name", "");
- GLOBAL_DEF("application/config/description", "");
+ GLOBAL_DEF_BASIC("application/config/name", "");
+ GLOBAL_DEF_BASIC("application/config/description", "");
custom_prop_info["application/config/description"] = PropertyInfo(Variant::STRING, "application/config/description", PROPERTY_HINT_MULTILINE_TEXT);
- GLOBAL_DEF("application/run/main_scene", "");
+ GLOBAL_DEF_BASIC("application/run/main_scene", "");
custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res");
GLOBAL_DEF("application/run/disable_stdout", false);
GLOBAL_DEF("application/run/disable_stderr", false);
GLOBAL_DEF("application/config/use_custom_user_dir", false);
GLOBAL_DEF("application/config/custom_user_dir_name", "");
GLOBAL_DEF("application/config/project_settings_override", "");
- GLOBAL_DEF("audio/default_bus_layout", "res://default_bus_layout.tres");
- custom_prop_info["audio/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/default_bus_layout", PROPERTY_HINT_FILE, "*.tres");
+ GLOBAL_DEF_BASIC("audio/buses/default_bus_layout", "res://default_bus_layout.tres");
+ custom_prop_info["audio/buses/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/buses/default_bus_layout", PROPERTY_HINT_FILE, "*.tres");
PackedStringArray extensions = PackedStringArray();
extensions.push_back("gd");
@@ -1073,174 +1107,18 @@ ProjectSettings::ProjectSettings() {
}
extensions.push_back("shader");
- GLOBAL_DEF("editor/search_in_file_extensions", extensions);
- custom_prop_info["editor/search_in_file_extensions"] = PropertyInfo(Variant::PACKED_STRING_ARRAY, "editor/search_in_file_extensions");
-
- GLOBAL_DEF("editor/script_templates_search_path", "res://script_templates");
- custom_prop_info["editor/script_templates_search_path"] = PropertyInfo(Variant::STRING, "editor/script_templates_search_path", PROPERTY_HINT_DIR);
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_ENTER);
- events.push_back(key);
- key.instance();
- key->set_keycode(KEY_KP_ENTER);
- events.push_back(key);
- key.instance();
- key->set_keycode(KEY_SPACE);
- events.push_back(key);
- joyb.instance();
- joyb->set_button_index(JOY_BUTTON_A);
- events.push_back(joyb);
- action["events"] = events;
- GLOBAL_DEF("input/ui_accept", action);
- input_presets.push_back("input/ui_accept");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_SPACE);
- events.push_back(key);
- joyb.instance();
- joyb->set_button_index(JOY_BUTTON_Y);
- events.push_back(joyb);
- action["events"] = events;
- GLOBAL_DEF("input/ui_select", action);
- input_presets.push_back("input/ui_select");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_ESCAPE);
- events.push_back(key);
- joyb.instance();
- joyb->set_button_index(JOY_BUTTON_B);
- events.push_back(joyb);
- action["events"] = events;
- GLOBAL_DEF("input/ui_cancel", action);
- input_presets.push_back("input/ui_cancel");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_TAB);
- events.push_back(key);
- action["events"] = events;
- GLOBAL_DEF("input/ui_focus_next", action);
- input_presets.push_back("input/ui_focus_next");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_TAB);
- key->set_shift(true);
- events.push_back(key);
- action["events"] = events;
- GLOBAL_DEF("input/ui_focus_prev", action);
- input_presets.push_back("input/ui_focus_prev");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_LEFT);
- events.push_back(key);
- joyb.instance();
- joyb->set_button_index(JOY_BUTTON_DPAD_LEFT);
- events.push_back(joyb);
- action["events"] = events;
- GLOBAL_DEF("input/ui_left", action);
- input_presets.push_back("input/ui_left");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_RIGHT);
- events.push_back(key);
- joyb.instance();
- joyb->set_button_index(JOY_BUTTON_DPAD_RIGHT);
- events.push_back(joyb);
- action["events"] = events;
- GLOBAL_DEF("input/ui_right", action);
- input_presets.push_back("input/ui_right");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_UP);
- events.push_back(key);
- joyb.instance();
- joyb->set_button_index(JOY_BUTTON_DPAD_UP);
- events.push_back(joyb);
- action["events"] = events;
- GLOBAL_DEF("input/ui_up", action);
- input_presets.push_back("input/ui_up");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_DOWN);
- events.push_back(key);
- joyb.instance();
- joyb->set_button_index(JOY_BUTTON_DPAD_DOWN);
- events.push_back(joyb);
- action["events"] = events;
- GLOBAL_DEF("input/ui_down", action);
- input_presets.push_back("input/ui_down");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_PAGEUP);
- events.push_back(key);
- action["events"] = events;
- GLOBAL_DEF("input/ui_page_up", action);
- input_presets.push_back("input/ui_page_up");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_PAGEDOWN);
- events.push_back(key);
- action["events"] = events;
- GLOBAL_DEF("input/ui_page_down", action);
- input_presets.push_back("input/ui_page_down");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_HOME);
- events.push_back(key);
- action["events"] = events;
- GLOBAL_DEF("input/ui_home", action);
- input_presets.push_back("input/ui_home");
-
- action = Dictionary();
- action["deadzone"] = Variant(0.5f);
- events = Array();
- key.instance();
- key->set_keycode(KEY_END);
- events.push_back(key);
- action["events"] = events;
- GLOBAL_DEF("input/ui_end", action);
- input_presets.push_back("input/ui_end");
+ GLOBAL_DEF("editor/script/search_in_file_extensions", extensions);
+ custom_prop_info["editor/script/search_in_file_extensions"] = PropertyInfo(Variant::PACKED_STRING_ARRAY, "editor/script/search_in_file_extensions");
+
+ GLOBAL_DEF("editor/script/templates_search_path", "res://script_templates");
+ custom_prop_info["editor/script/templates_search_path"] = PropertyInfo(Variant::STRING, "editor/script/templates_search_path", PROPERTY_HINT_DIR);
+
+ _add_builtin_input_map();
custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
- custom_prop_info["rendering/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
- custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
- custom_prop_info["rendering/quality/intended_usage/framebuffer_allocation"] = PropertyInfo(Variant::INT, "rendering/quality/intended_usage/framebuffer_allocation", PROPERTY_HINT_ENUM, "2D,2D Without Sampling,3D,3D Without Effects");
+ custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
+ GLOBAL_DEF("physics/2d/run_on_thread", false);
+ GLOBAL_DEF("physics/3d/run_on_thread", false);
GLOBAL_DEF("debug/settings/profiler/max_functions", 16384);
custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1");
diff --git a/core/config/project_settings.h b/core/config/project_settings.h
index 5a16248c76..ed8fb19fa0 100644
--- a/core/config/project_settings.h
+++ b/core/config/project_settings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,6 +58,7 @@ protected:
struct VariantContainer {
int order = 0;
bool persist = false;
+ bool basic = false;
Variant variant;
Variant initial;
bool hide_from_editor = false;
@@ -78,6 +79,8 @@ protected:
int last_order = NO_BUILTIN_ORDER_BASE;
int last_builtin_order = 0;
+ uint64_t last_save_time = 0;
+
Map<StringName, VariantContainer> props;
String resource_path;
Map<StringName, PropertyInfo> custom_prop_info;
@@ -113,6 +116,8 @@ protected:
Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false);
+ void _add_builtin_input_map();
+
protected:
static void _bind_methods();
@@ -127,6 +132,7 @@ public:
String globalize_path(const String &p_path) const;
void set_initial_value(const String &p_name, const Variant &p_value);
+ void set_as_basic(const String &p_name, bool p_basic);
void set_restart_if_changed(const String &p_name, bool p_restart);
void set_ignore_value_in_docs(const String &p_name, bool p_ignore);
bool get_ignore_value_in_docs(const String &p_name) const;
@@ -150,6 +156,7 @@ public:
Error save();
void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info);
const Map<StringName, PropertyInfo> &get_custom_property_info() const;
+ uint64_t get_last_saved_time() { return last_save_time; }
Vector<String> get_optimizer_presets() const;
@@ -172,11 +179,16 @@ public:
};
//not a macro any longer
-Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed = false, bool p_ignore_value_in_docs = false);
+Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed = false, bool p_ignore_value_in_docs = false, bool p_basic = false);
#define GLOBAL_DEF(m_var, m_value) _GLOBAL_DEF(m_var, m_value)
#define GLOBAL_DEF_RST(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true)
#define GLOBAL_DEF_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true)
#define GLOBAL_DEF_RST_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true)
#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var)
+#define GLOBAL_DEF_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, false, true)
+#define GLOBAL_DEF_RST_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, false, true)
+#define GLOBAL_DEF_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true, true)
+#define GLOBAL_DEF_RST_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true, true)
+
#endif // PROJECT_SETTINGS_H
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 259d899d39..e7a77384da 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -86,9 +86,9 @@ RES _ResourceLoader::load_threaded_get(const String &p_path) {
return res;
}
-RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache) {
+RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, CacheMode p_cache_mode) {
Error err = OK;
- RES ret = ResourceLoader::load(p_path, p_type_hint, p_no_cache, &err);
+ RES ret = ResourceLoader::load(p_path, p_type_hint, ResourceFormatLoader::CacheMode(p_cache_mode), &err);
ERR_FAIL_COND_V_MSG(err != OK, ret, "Error loading resource: '" + p_path + "'.");
return ret;
@@ -135,7 +135,7 @@ void _ResourceLoader::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &_ResourceLoader::load_threaded_get_status, DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("load_threaded_get", "path"), &_ResourceLoader::load_threaded_get);
- ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "cache_mode"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(CACHE_MODE_REUSE));
ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type);
ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources);
ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies);
@@ -146,6 +146,10 @@ void _ResourceLoader::_bind_methods() {
BIND_ENUM_CONSTANT(THREAD_LOAD_IN_PROGRESS);
BIND_ENUM_CONSTANT(THREAD_LOAD_FAILED);
BIND_ENUM_CONSTANT(THREAD_LOAD_LOADED);
+
+ BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE);
+ BIND_ENUM_CONSTANT(CACHE_MODE_REUSE);
+ BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE);
}
////// _ResourceSaver //////
@@ -228,24 +232,32 @@ Error _OS::shell_open(String p_uri) {
return OS::get_singleton()->shell_open(p_uri);
}
-int _OS::execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking, Array p_output, bool p_read_stderr) {
- OS::ProcessID pid = -2;
- int exitcode = 0;
+int _OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r_output, bool p_read_stderr) {
List<String> args;
for (int i = 0; i < p_arguments.size(); i++) {
args.push_back(p_arguments[i]);
}
String pipe;
- Error err = OS::get_singleton()->execute(p_path, args, p_blocking, &pid, &pipe, &exitcode, p_read_stderr);
- p_output.clear();
- p_output.push_back(pipe);
+ int exitcode = 0;
+ Error err = OS::get_singleton()->execute(p_path, args, &pipe, &exitcode, p_read_stderr);
+ r_output.push_back(pipe);
if (err != OK) {
return -1;
- } else if (p_blocking) {
- return exitcode;
- } else {
- return pid;
}
+ return exitcode;
+}
+
+int _OS::create_process(const String &p_path, const Vector<String> &p_arguments) {
+ List<String> args;
+ for (int i = 0; i < p_arguments.size(); i++) {
+ args.push_back(p_arguments[i]);
+ }
+ OS::ProcessID pid = 0;
+ Error err = OS::get_singleton()->create_process(p_path, args, &pid);
+ if (err != OK) {
+ return -1;
+ }
+ return pid;
}
Error _OS::kill(int p_pid) {
@@ -264,6 +276,10 @@ String _OS::get_environment(const String &p_var) const {
return OS::get_singleton()->get_environment(p_var);
}
+bool _OS::set_environment(const String &p_var, const String &p_value) const {
+ return OS::get_singleton()->set_environment(p_var, p_value);
+}
+
String _OS::get_name() const {
return OS::get_singleton()->get_name();
}
@@ -290,6 +306,10 @@ Error _OS::set_thread_name(const String &p_name) {
return Thread::set_name(p_name);
}
+Thread::ID _OS::get_thread_caller_id() const {
+ return Thread::get_caller_id();
+};
+
bool _OS::has_feature(const String &p_feature) const {
return OS::get_singleton()->has_feature(p_feature);
}
@@ -302,18 +322,6 @@ uint64_t _OS::get_static_memory_peak_usage() const {
return OS::get_singleton()->get_static_memory_peak_usage();
}
-int _OS::get_exit_code() const {
- return OS::get_singleton()->get_exit_code();
-}
-
-void _OS::set_exit_code(int p_code) {
- if (p_code < 0 || p_code > 125) {
- WARN_PRINT("For portability reasons, the exit code should be set between 0 and 125 (inclusive).");
- }
-
- OS::get_singleton()->set_exit_code(p_code);
-}
-
/**
* Get current datetime with consideration for utc and
* dst
@@ -503,11 +511,19 @@ double _OS::get_unix_time() const {
return OS::get_singleton()->get_unix_time();
}
-void _OS::delay_usec(uint32_t p_usec) const {
+/** This method uses a signed argument for better error reporting as it's used from the scripting API. */
+void _OS::delay_usec(int p_usec) const {
+ ERR_FAIL_COND_MSG(
+ p_usec < 0,
+ vformat("Can't sleep for %d microseconds. The delay provided must be greater than or equal to 0 microseconds.", p_usec));
OS::get_singleton()->delay_usec(p_usec);
}
-void _OS::delay_msec(uint32_t p_msec) const {
+/** This method uses a signed argument for better error reporting as it's used from the scripting API. */
+void _OS::delay_msec(int p_msec) const {
+ ERR_FAIL_COND_MSG(
+ p_msec < 0,
+ vformat("Can't sleep for %d milliseconds. The delay provided must be greater than or equal to 0 milliseconds.", p_msec));
OS::get_singleton()->delay_usec(int64_t(p_msec) * 1000);
}
@@ -550,7 +566,7 @@ struct _OSCoreBindImg {
void _OS::print_all_textures_by_size() {
List<_OSCoreBindImg> imgs;
- int total = 0;
+ uint64_t total = 0;
{
List<Ref<Resource>> rsrc;
ResourceCache::get_cached_resources(&rsrc);
@@ -587,10 +603,7 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) {
List<Ref<Resource>> resources;
ResourceCache::get_cached_resources(&resources);
- List<Ref<Resource>> rsrc;
- ResourceCache::get_cached_resources(&rsrc);
-
- for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) {
+ for (List<Ref<Resource>>::Element *E = resources.front(); E; E = E->next()) {
Ref<Resource> r = E->get();
bool found = false;
@@ -668,22 +681,6 @@ String _OS::get_unique_id() const {
return OS::get_singleton()->get_unique_id();
}
-int _OS::get_tablet_driver_count() const {
- return OS::get_singleton()->get_tablet_driver_count();
-}
-
-String _OS::get_tablet_driver_name(int p_driver) const {
- return OS::get_singleton()->get_tablet_driver_name(p_driver);
-}
-
-String _OS::get_current_tablet_driver() const {
- return OS::get_singleton()->get_current_tablet_driver();
-}
-
-void _OS::set_current_tablet_driver(const String &p_driver) {
- OS::get_singleton()->set_current_tablet_driver(p_driver);
-}
-
_OS *_OS::singleton = nullptr;
void _OS::_bind_methods() {
@@ -700,13 +697,15 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_processor_count"), &_OS::get_processor_count);
ClassDB::bind_method(D_METHOD("get_executable_path"), &_OS::get_executable_path);
- ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "blocking", "output", "read_stderr"), &_OS::execute, DEFVAL(true), DEFVAL(Array()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr"), &_OS::execute, DEFVAL(Array()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("create_process", "path", "arguments"), &_OS::create_process);
ClassDB::bind_method(D_METHOD("kill", "pid"), &_OS::kill);
ClassDB::bind_method(D_METHOD("shell_open", "uri"), &_OS::shell_open);
ClassDB::bind_method(D_METHOD("get_process_id"), &_OS::get_process_id);
- ClassDB::bind_method(D_METHOD("get_environment", "environment"), &_OS::get_environment);
- ClassDB::bind_method(D_METHOD("has_environment", "environment"), &_OS::has_environment);
+ ClassDB::bind_method(D_METHOD("get_environment", "variable"), &_OS::get_environment);
+ ClassDB::bind_method(D_METHOD("set_environment", "variable", "value"), &_OS::set_environment);
+ ClassDB::bind_method(D_METHOD("has_environment", "variable"), &_OS::has_environment);
ClassDB::bind_method(D_METHOD("get_name"), &_OS::get_name);
ClassDB::bind_method(D_METHOD("get_cmdline_args"), &_OS::get_cmdline_args);
@@ -719,9 +718,6 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_datetime_from_unix_time", "unix_time_val"), &_OS::get_datetime_from_unix_time);
ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime", "datetime"), &_OS::get_unix_time_from_datetime);
- ClassDB::bind_method(D_METHOD("get_exit_code"), &_OS::get_exit_code);
- ClassDB::bind_method(D_METHOD("set_exit_code", "code"), &_OS::set_exit_code);
-
ClassDB::bind_method(D_METHOD("delay_usec", "usec"), &_OS::delay_usec);
ClassDB::bind_method(D_METHOD("delay_msec", "msec"), &_OS::delay_msec);
ClassDB::bind_method(D_METHOD("get_ticks_msec"), &_OS::get_ticks_msec);
@@ -758,6 +754,7 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_file_access_save_and_swap", "enabled"), &_OS::set_use_file_access_save_and_swap);
ClassDB::bind_method(D_METHOD("set_thread_name", "name"), &_OS::set_thread_name);
+ ClassDB::bind_method(D_METHOD("get_thread_caller_id"), &_OS::get_thread_caller_id);
ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &_OS::has_feature);
@@ -765,19 +762,11 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("request_permissions"), &_OS::request_permissions);
ClassDB::bind_method(D_METHOD("get_granted_permissions"), &_OS::get_granted_permissions);
- ClassDB::bind_method(D_METHOD("get_tablet_driver_count"), &_OS::get_tablet_driver_count);
- ClassDB::bind_method(D_METHOD("get_tablet_driver_name", "idx"), &_OS::get_tablet_driver_name);
- ClassDB::bind_method(D_METHOD("get_current_tablet_driver"), &_OS::get_current_tablet_driver);
- ClassDB::bind_method(D_METHOD("set_current_tablet_driver", "name"), &_OS::set_current_tablet_driver);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "low_processor_usage_mode"), "set_low_processor_usage_mode", "is_in_low_processor_usage_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "low_processor_usage_mode_sleep_usec"), "set_low_processor_usage_mode_sleep_usec", "get_low_processor_usage_mode_sleep_usec");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "tablet_driver"), "set_current_tablet_driver", "get_current_tablet_driver");
// Those default values need to be specified for the docs generator,
// to avoid using values from the documentation writer's own OS instance.
- ADD_PROPERTY_DEFAULT("tablet_driver", "");
ADD_PROPERTY_DEFAULT("exit_code", 0);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode", false);
ADD_PROPERTY_DEFAULT("low_processor_usage_mode_sleep_usec", 6900);
@@ -1239,6 +1228,11 @@ Error _File::open(const String &p_path, ModeFlags p_mode_flags) {
return err;
}
+void _File::flush() {
+ ERR_FAIL_COND_MSG(!f, "File must be opened before flushing.");
+ f->flush();
+}
+
void _File::close() {
if (f) {
memdelete(f);
@@ -1532,6 +1526,7 @@ void _File::_bind_methods() {
ClassDB::bind_method(D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &_File::open_compressed, DEFVAL(0));
ClassDB::bind_method(D_METHOD("open", "path", "flags"), &_File::open);
+ ClassDB::bind_method(D_METHOD("flush"), &_File::flush);
ClassDB::bind_method(D_METHOD("close"), &_File::close);
ClassDB::bind_method(D_METHOD("get_path"), &_File::get_path);
ClassDB::bind_method(D_METHOD("get_path_absolute"), &_File::get_path_absolute);
@@ -1969,7 +1964,7 @@ void _Thread::_start_func(void *ud) {
}
Error _Thread::start(Object *p_instance, const StringName &p_method, const Variant &p_userdata, Priority p_priority) {
- ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "Thread already started.");
+ ERR_FAIL_COND_V_MSG(active.is_set(), ERR_ALREADY_IN_USE, "Thread already started.");
ERR_FAIL_COND_V(!p_instance, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_method == StringName(), ERR_INVALID_PARAMETER);
ERR_FAIL_INDEX_V(p_priority, PRIORITY_MAX, ERR_INVALID_PARAMETER);
@@ -1978,49 +1973,33 @@ Error _Thread::start(Object *p_instance, const StringName &p_method, const Varia
target_method = p_method;
target_instance = p_instance;
userdata = p_userdata;
- active = true;
+ active.set();
Ref<_Thread> *ud = memnew(Ref<_Thread>(this));
Thread::Settings s;
s.priority = (Thread::Priority)p_priority;
- thread = Thread::create(_start_func, ud, s);
- if (!thread) {
- active = false;
- target_method = StringName();
- target_instance = nullptr;
- userdata = Variant();
- return ERR_CANT_CREATE;
- }
+ thread.start(_start_func, ud, s);
return OK;
}
String _Thread::get_id() const {
- if (!thread) {
- return String();
- }
-
- return itos(thread->get_id());
+ return itos(thread.get_id());
}
bool _Thread::is_active() const {
- return active;
+ return active.is_set();
}
Variant _Thread::wait_to_finish() {
- ERR_FAIL_COND_V_MSG(!thread, Variant(), "Thread must exist to wait for its completion.");
- ERR_FAIL_COND_V_MSG(!active, Variant(), "Thread must be active to wait for its completion.");
- Thread::wait_to_finish(thread);
+ ERR_FAIL_COND_V_MSG(!active.is_set(), Variant(), "Thread must be active to wait for its completion.");
+ thread.wait_to_finish();
Variant r = ret;
- active = false;
+ active.clear();
target_method = StringName();
target_instance = nullptr;
userdata = Variant();
- if (thread) {
- memdelete(thread);
- }
- thread = nullptr;
return r;
}
@@ -2036,10 +2015,6 @@ void _Thread::_bind_methods() {
BIND_ENUM_CONSTANT(PRIORITY_HIGH);
}
-_Thread::~_Thread() {
- ERR_FAIL_COND_MSG(active, "Reference to a Thread object was lost while the thread is still running...");
-}
-
////// _ClassDB //////
PackedStringArray _ClassDB::get_class_list() const {
@@ -2278,8 +2253,8 @@ uint64_t _Engine::get_physics_frames() const {
return Engine::get_singleton()->get_physics_frames();
}
-uint64_t _Engine::get_idle_frames() const {
- return Engine::get_singleton()->get_idle_frames();
+uint64_t _Engine::get_process_frames() const {
+ return Engine::get_singleton()->get_process_frames();
}
void _Engine::set_time_scale(float p_scale) {
@@ -2358,7 +2333,7 @@ void _Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_frames_drawn"), &_Engine::get_frames_drawn);
ClassDB::bind_method(D_METHOD("get_frames_per_second"), &_Engine::get_frames_per_second);
ClassDB::bind_method(D_METHOD("get_physics_frames"), &_Engine::get_physics_frames);
- ClassDB::bind_method(D_METHOD("get_idle_frames"), &_Engine::get_idle_frames);
+ ClassDB::bind_method(D_METHOD("get_process_frames"), &_Engine::get_process_frames);
ClassDB::bind_method(D_METHOD("get_main_loop"), &_Engine::get_main_loop);
diff --git a/core/core_bind.h b/core/core_bind.h
index f3a77a4fa6..3920116ca4 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,6 +40,7 @@
#include "core/os/os.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
class _ResourceLoader : public Object {
GDCLASS(_ResourceLoader, Object);
@@ -56,13 +57,19 @@ public:
THREAD_LOAD_LOADED
};
+ enum CacheMode {
+ CACHE_MODE_IGNORE, //resource and subresources do not use path cache, no path is set into resource.
+ CACHE_MODE_REUSE, //resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available
+ CACHE_MODE_REPLACE, //resource and and subresource use path cache, but replace existing loaded resources when available with information from disk
+ };
+
static _ResourceLoader *get_singleton() { return singleton; }
Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false);
ThreadLoadStatus load_threaded_get_status(const String &p_path, Array r_progress = Array());
RES load_threaded_get(const String &p_path);
- RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false);
+ RES load(const String &p_path, const String &p_type_hint = "", CacheMode p_cache_mode = CACHE_MODE_REUSE);
Vector<String> get_recognized_extensions_for_type(const String &p_type);
void set_abort_on_missing_resources(bool p_abort);
PackedStringArray get_dependencies(const String &p_path);
@@ -73,6 +80,7 @@ public:
};
VARIANT_ENUM_CAST(_ResourceLoader::ThreadLoadStatus);
+VARIANT_ENUM_CAST(_ResourceLoader::CacheMode);
class _ResourceSaver : public Object {
GDCLASS(_ResourceSaver, Object);
@@ -155,8 +163,8 @@ public:
int get_low_processor_usage_mode_sleep_usec() const;
String get_executable_path() const;
- int execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking = true, Array p_output = Array(), bool p_read_stderr = false);
-
+ int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false);
+ int create_process(const String &p_path, const Vector<String> &p_arguments);
Error kill(int p_pid);
Error shell_open(String p_uri);
@@ -164,6 +172,7 @@ public:
bool has_environment(const String &p_var) const;
String get_environment(const String &p_var) const;
+ bool set_environment(const String &p_var, const String &p_value) const;
String get_name() const;
Vector<String> get_cmdline_args();
@@ -190,8 +199,6 @@ public:
void set_use_file_access_save_and_swap(bool p_enable);
- int get_exit_code() const;
- void set_exit_code(int p_code);
Dictionary get_date(bool utc) const;
Dictionary get_time(bool utc) const;
Dictionary get_datetime(bool utc) const;
@@ -203,8 +210,8 @@ public:
uint64_t get_static_memory_usage() const;
uint64_t get_static_memory_peak_usage() const;
- void delay_usec(uint32_t p_usec) const;
- void delay_msec(uint32_t p_msec) const;
+ void delay_usec(int p_usec) const;
+ void delay_msec(int p_msec) const;
uint32_t get_ticks_msec() const;
uint64_t get_ticks_usec() const;
@@ -232,6 +239,7 @@ public:
String get_user_data_dir() const;
Error set_thread_name(const String &p_name);
+ Thread::ID get_thread_caller_id() const;
bool has_feature(const String &p_feature) const;
@@ -239,11 +247,6 @@ public:
bool request_permissions();
Vector<String> get_granted_permissions() const;
- int get_tablet_driver_count() const;
- String get_tablet_driver_name(int p_driver) const;
- String get_current_tablet_driver() const;
- void set_current_tablet_driver(const String &p_driver);
-
static _OS *get_singleton() { return singleton; }
_OS() { singleton = this; }
@@ -378,6 +381,7 @@ public:
Error open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode = COMPRESSION_FASTLZ);
Error open(const String &p_path, ModeFlags p_mode_flags); // open a file.
+ void flush(); // Flush a file (write its buffer to disk).
void close(); // Close a file.
bool is_open() const; // True when file is open.
@@ -550,10 +554,10 @@ class _Thread : public Reference {
protected:
Variant ret;
Variant userdata;
- volatile bool active = false;
+ SafeFlag active;
Object *target_instance = nullptr;
StringName target_method;
- Thread *thread = nullptr;
+ Thread thread;
static void _bind_methods();
static void _start_func(void *ud);
@@ -569,9 +573,6 @@ public:
String get_id() const;
bool is_active() const;
Variant wait_to_finish();
-
- _Thread() {}
- ~_Thread();
};
VARIANT_ENUM_CAST(_Thread::Priority);
@@ -635,7 +636,7 @@ public:
float get_frames_per_second() const;
uint64_t get_physics_frames() const;
- uint64_t get_idle_frames() const;
+ uint64_t get_process_frames() const;
int get_frames_drawn();
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 555908ea79..a99df93638 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -125,6 +125,9 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(VERTICAL);
BIND_CORE_ENUM_CONSTANT(HORIZONTAL);
+ BIND_CORE_ENUM_CONSTANT(CLOCKWISE);
+ BIND_CORE_ENUM_CONSTANT(COUNTERCLOCKWISE);
+
BIND_CORE_ENUM_CONSTANT(HALIGN_LEFT);
BIND_CORE_ENUM_CONSTANT(HALIGN_CENTER);
BIND_CORE_ENUM_CONSTANT(HALIGN_RIGHT);
@@ -426,6 +429,12 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_DOWN);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_LEFT);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_RIGHT);
+ BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MISC1);
+ BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE1);
+ BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE2);
+ BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE3);
+ BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_PADDLE4);
+ BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_TOUCHPAD);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_SDL_MAX);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MAX);
@@ -512,8 +521,10 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_RENDER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_PHYSICS);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_NAVIGATION);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_RENDER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_PHYSICS);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_NAVIGATION);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_DIR);
diff --git a/core/core_constants.h b/core/core_constants.h
index 6cddd9daec..deaf9ec60f 100644
--- a/core/core_constants.h
+++ b/core/core_constants.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp
index 6f86f107e6..ff8569e45d 100644
--- a/core/core_string_names.cpp
+++ b/core/core_string_names.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -76,5 +76,6 @@ CoreStringNames::CoreStringNames() :
bind(StaticCString::create("bind")),
unbind(StaticCString::create("unbind")),
emit(StaticCString::create("emit")),
- notification(StaticCString::create("notification")) {
+ notification(StaticCString::create("notification")),
+ property_list_changed(StaticCString::create("property_list_changed")) {
}
diff --git a/core/core_string_names.h b/core/core_string_names.h
index c0bdc33d28..abe751372e 100644
--- a/core/core_string_names.h
+++ b/core/core_string_names.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -96,6 +96,7 @@ public:
StringName unbind;
StringName emit;
StringName notification;
+ StringName property_list_changed;
};
#endif // CORE_STRING_NAMES_H
diff --git a/core/crypto/aes_context.cpp b/core/crypto/aes_context.cpp
index 608f3c912c..b387aeb27d 100644
--- a/core/crypto/aes_context.cpp
+++ b/core/crypto/aes_context.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/crypto/aes_context.h b/core/crypto/aes_context.h
index 557bde1f04..cc00b18fd2 100644
--- a/core/crypto/aes_context.h
+++ b/core/crypto/aes_context.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp
index 33ba0ba704..f43f3e3290 100644
--- a/core/crypto/crypto.cpp
+++ b/core/crypto/crypto.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -141,7 +141,7 @@ void Crypto::_bind_methods() {
/// Resource loader/saver
-RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
String el = p_path.get_extension().to_lower();
if (el == "crt") {
X509Certificate *cert = X509Certificate::create();
diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h
index 5cacddaea0..9438fcfea5 100644
--- a/core/crypto/crypto.h
+++ b/core/crypto/crypto.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -116,7 +116,7 @@ public:
class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/crypto/crypto_core.cpp b/core/crypto/crypto_core.cpp
index 117e47d538..f90092056e 100644
--- a/core/crypto/crypto_core.cpp
+++ b/core/crypto/crypto_core.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h
index c2ec6febe3..27b380e838 100644
--- a/core/crypto/crypto_core.h
+++ b/core/crypto/crypto_core.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/crypto/hashing_context.cpp b/core/crypto/hashing_context.cpp
index fb0dadfbab..070d2d4dd7 100644
--- a/core/crypto/hashing_context.cpp
+++ b/core/crypto/hashing_context.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/crypto/hashing_context.h b/core/crypto/hashing_context.h
index 7cd55ba267..892a48a4e8 100644
--- a/core/crypto/hashing_context.h
+++ b/core/crypto/hashing_context.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/debugger/debugger_marshalls.cpp b/core/debugger/debugger_marshalls.cpp
index 03de832b5e..26f82c2658 100644
--- a/core/debugger/debugger_marshalls.cpp
+++ b/core/debugger/debugger_marshalls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/debugger/debugger_marshalls.h b/core/debugger/debugger_marshalls.h
index 0c13790d60..3e8c34d84b 100644
--- a/core/debugger/debugger_marshalls.h
+++ b/core/debugger/debugger_marshalls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp
index 4bf31aa55f..895b8c23a9 100644
--- a/core/debugger/engine_debugger.cpp
+++ b/core/debugger/engine_debugger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -117,9 +117,9 @@ void EngineDebugger::line_poll() {
poll_every++;
}
-void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, uint64_t p_physics_ticks, float p_physics_frame_time) {
+void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks, uint64_t p_physics_ticks, float p_physics_frame_time) {
frame_time = USEC_TO_SEC(p_frame_ticks);
- idle_time = USEC_TO_SEC(p_idle_ticks);
+ process_time = USEC_TO_SEC(p_process_ticks);
physics_time = USEC_TO_SEC(p_physics_ticks);
physics_frame_time = p_physics_frame_time;
// Notify tick to running profilers
@@ -128,14 +128,14 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, ui
if (!p.active || !p.tick) {
continue;
}
- p.tick(p.data, frame_time, idle_time, physics_time, physics_frame_time);
+ p.tick(p.data, frame_time, process_time, physics_time, physics_frame_time);
}
singleton->poll_events(true);
}
void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints) {
register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
- if (p_uri.empty()) {
+ if (p_uri.is_empty()) {
return;
}
if (p_uri == "local://") {
diff --git a/core/debugger/engine_debugger.h b/core/debugger/engine_debugger.h
index 10f04bf97a..c6daea6e2f 100644
--- a/core/debugger/engine_debugger.h
+++ b/core/debugger/engine_debugger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,7 +44,7 @@ class ScriptDebugger;
class EngineDebugger {
public:
typedef void (*ProfilingToggle)(void *p_user, bool p_enable, const Array &p_opts);
- typedef void (*ProfilingTick)(void *p_user, float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time);
+ typedef void (*ProfilingTick)(void *p_user, float p_frame_time, float p_process_time, float p_physics_time, float p_physics_frame_time);
typedef void (*ProfilingAdd)(void *p_user, const Array &p_arr);
typedef Error (*CaptureFunc)(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
@@ -86,7 +86,7 @@ public:
private:
float frame_time = 0.0;
- float idle_time = 0.0;
+ float process_time = 0.0;
float physics_time = 0.0;
float physics_frame_time = 0.0;
@@ -120,7 +120,7 @@ public:
static void register_uri_handler(const String &p_protocol, CreatePeerFunc p_func);
- void iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, uint64_t p_physics_ticks, float p_physics_frame_time);
+ void iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks, uint64_t p_physics_ticks, float p_physics_frame_time);
void profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts = Array());
Error capture_parse(const StringName &p_name, const String &p_msg, const Array &p_args, bool &r_captured);
diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp
index 876be79418..1dd7e268a5 100644
--- a/core/debugger/local_debugger.cpp
+++ b/core/debugger/local_debugger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -117,7 +117,7 @@ struct LocalDebugger::ScriptsProfiler {
void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
ScriptLanguage *script_lang = script_debugger->get_break_language();
- if (!target_function.empty()) {
+ if (!target_function.is_empty()) {
String current_function = script_lang->debug_get_stack_level_function(0);
if (current_function != target_function) {
script_debugger->set_depth(0);
@@ -259,7 +259,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
String source = breakpoint.first;
int linenr = breakpoint.second;
- if (source.empty()) {
+ if (source.is_empty()) {
continue;
}
@@ -285,7 +285,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
String source = breakpoint.first;
int linenr = breakpoint.second;
- if (source.empty()) {
+ if (source.is_empty()) {
continue;
}
@@ -323,7 +323,7 @@ void LocalDebugger::print_variables(const List<String> &names, const List<Varian
for (const List<String>::Element *E = names.front(); E; E = E->next()) {
value = String(V->get());
- if (variable_prefix.empty()) {
+ if (variable_prefix.is_empty()) {
print_line(E->get() + ": " + String(V->get()));
} else {
print_line(E->get() + ":");
@@ -359,7 +359,7 @@ void LocalDebugger::send_message(const String &p_message, const Array &p_args) {
}
void LocalDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) {
- print_line("ERROR: '" + (p_descr.empty() ? p_err : p_descr) + "'");
+ print_line("ERROR: '" + (p_descr.is_empty() ? p_err : p_descr) + "'");
}
LocalDebugger::LocalDebugger() {
diff --git a/core/debugger/local_debugger.h b/core/debugger/local_debugger.h
index dbdeec173b..e793b2a859 100644
--- a/core/debugger/local_debugger.h
+++ b/core/debugger/local_debugger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp
index ff89517497..bdbb7766fa 100644
--- a/core/debugger/remote_debugger.cpp
+++ b/core/debugger/remote_debugger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -76,6 +76,7 @@ public:
NetworkProfiler() {}
int bandwidth_usage(const Vector<BandwidthFrame> &p_buffer, int p_pointer) {
+ ERR_FAIL_COND_V(p_buffer.size() == 0, 0);
int total_bandwidth = 0;
uint32_t timestamp = OS::get_singleton()->get_ticks_msec();
@@ -317,7 +318,7 @@ struct RemoteDebugger::ServersProfiler {
void _send_frame_data(bool p_final) {
DebuggerMarshalls::ServersProfilerFrame frame;
- frame.frame_number = Engine::get_singleton()->get_idle_frames();
+ frame.frame_number = Engine::get_singleton()->get_process_frames();
frame.frame_time = frame_time;
frame.idle_time = idle_time;
frame.physics_time = physics_time;
@@ -553,7 +554,7 @@ void RemoteDebugger::flush_output() {
for (int i = 0; i < output_strings.size(); i++) {
const OutputString &output_string = output_strings[i];
if (output_string.type == MESSAGE_TYPE_ERROR) {
- if (!joined_log_strings.empty()) {
+ if (!joined_log_strings.is_empty()) {
strings.push_back(String("\n").join(joined_log_strings));
types.push_back(MESSAGE_TYPE_LOG);
joined_log_strings.clear();
@@ -565,7 +566,7 @@ void RemoteDebugger::flush_output() {
}
}
- if (!joined_log_strings.empty()) {
+ if (!joined_log_strings.is_empty()) {
strings.push_back(String("\n").join(joined_log_strings));
types.push_back(MESSAGE_TYPE_LOG);
}
diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h
index 37cc8af2a5..28e670747e 100644
--- a/core/debugger/remote_debugger.h
+++ b/core/debugger/remote_debugger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp
index 338c637014..857e3af268 100644
--- a/core/debugger/remote_debugger_peer.cpp
+++ b/core/debugger/remote_debugger_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,12 +65,8 @@ int RemoteDebuggerPeerTCP::get_max_message_size() const {
}
void RemoteDebuggerPeerTCP::close() {
- if (thread) {
- running = false;
- Thread::wait_to_finish(thread);
- memdelete(thread);
- thread = nullptr;
- }
+ running = false;
+ thread.wait_to_finish();
tcp_client->disconnect_from_host();
out_buf.resize(0);
in_buf.resize(0);
@@ -85,7 +81,7 @@ RemoteDebuggerPeerTCP::RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_tcp) {
connected = true;
#ifndef NO_THREADS
running = true;
- thread = Thread::create(_thread_func, this);
+ thread.start(_thread_func, this);
#endif
} else {
tcp_client.instance();
@@ -188,7 +184,7 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po
connected = true;
#ifndef NO_THREADS
running = true;
- thread = Thread::create(_thread_func, this);
+ thread.start(_thread_func, this);
#endif
return OK;
}
diff --git a/core/debugger/remote_debugger_peer.h b/core/debugger/remote_debugger_peer.h
index 79b88f5549..652e2d9d20 100644
--- a/core/debugger/remote_debugger_peer.h
+++ b/core/debugger/remote_debugger_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,7 +58,7 @@ class RemoteDebuggerPeerTCP : public RemoteDebuggerPeer {
private:
Ref<StreamPeerTCP> tcp_client;
Mutex mutex;
- Thread *thread = nullptr;
+ Thread thread;
List<Array> in_queue;
List<Array> out_queue;
int out_left = 0;
diff --git a/core/debugger/script_debugger.cpp b/core/debugger/script_debugger.cpp
index 0cd3238efb..6d1e4ed101 100644
--- a/core/debugger/script_debugger.cpp
+++ b/core/debugger/script_debugger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/debugger/script_debugger.h b/core/debugger/script_debugger.h
index 7f2f2becc2..9f034a5e5d 100644
--- a/core/debugger/script_debugger.h
+++ b/core/debugger/script_debugger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/doc_data.cpp b/core/doc_data.cpp
index d84ac6d05b..45450bf97a 100644
--- a/core/doc_data.cpp
+++ b/core/doc_data.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/doc_data.h b/core/doc_data.h
index 65b57d1381..46ab697768 100644
--- a/core/doc_data.h
+++ b/core/doc_data.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/error/error_list.h b/core/error/error_list.h
index a0218cf045..f032f44c1f 100644
--- a/core/error/error_list.h
+++ b/core/error/error_list.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/error/error_macros.cpp b/core/error/error_macros.cpp
index 80879dd25d..272dda97d8 100644
--- a/core/error/error_macros.cpp
+++ b/core/error/error_macros.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/error/error_macros.h b/core/error/error_macros.h
index 6353961b04..f909a67d55 100644
--- a/core/error/error_macros.h
+++ b/core/error/error_macros.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,8 @@
#include "core/typedefs.h"
+#include "core/templates/safe_refcount.h"
+
class String;
enum ErrorHandlerType {
@@ -577,10 +579,10 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*/
#define WARN_DEPRECATED \
if (true) { \
- static volatile bool warning_shown = false; \
- if (!warning_shown) { \
+ static SafeFlag warning_shown; \
+ if (!warning_shown.is_set()) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", ERR_HANDLER_WARNING); \
- warning_shown = true; \
+ warning_shown.set(); \
} \
} else \
((void)0)
@@ -590,10 +592,10 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*/
#define WARN_DEPRECATED_MSG(m_msg) \
if (true) { \
- static volatile bool warning_shown = false; \
- if (!warning_shown) { \
+ static SafeFlag warning_shown; \
+ if (!warning_shown.is_set()) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \
- warning_shown = true; \
+ warning_shown.set(); \
} \
} else \
((void)0)
diff --git a/core/input/default_controller_mappings.h b/core/input/default_controller_mappings.h
index 9e2a69acec..ba5e650226 100644
--- a/core/input/default_controller_mappings.h
+++ b/core/input/default_controller_mappings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt
index 180708cea6..668a531b1f 100644
--- a/core/input/gamecontrollerdb.txt
+++ b/core/input/gamecontrollerdb.txt
@@ -1,4 +1,4 @@
-# Game Controller DB for SDL in 2.0.10 format
+# Game Controller DB for SDL in 2.0.9 format
# Source: https://github.com/gabomdq/SDL_GameControllerDB
# Windows
@@ -35,7 +35,7 @@
03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
-03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
+03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
@@ -80,14 +80,15 @@
030000007d0400000840000000000000,Destroyer Tiltpad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,
03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
+030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
030000006f0e00003001000000000000,EA SPORTS PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,
-030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,
+030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -98,6 +99,7 @@
03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,
03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
+03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
@@ -119,6 +121,7 @@
030000007d0400000540000000000000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
+030000001008000001e1000000000000,Havit HV-G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,
03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
@@ -164,7 +167,8 @@
030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,lefttrigger:b6,righttrigger:b7,platform:Windows,
+030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
+030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
03000000380700006652000000000000,Mad Catz C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -193,6 +197,8 @@
03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000c62400001a89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
+03000000c62400001b89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
@@ -234,6 +240,7 @@
030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
+030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,
03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,
@@ -244,7 +251,6 @@
03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b13,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,
03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
03000000321500000011000000000000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -259,6 +265,7 @@
030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
+03000000bd12000013d0000000000000,Retrolink USB SEGA Saturn Classic,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,
0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
@@ -271,8 +278,8 @@
03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b0,y:b1,platform:Windows,
-03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,x:b0,y:b1,platform:Windows,
+03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Windows,
+03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows,
03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
@@ -283,6 +290,8 @@
03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
+03000000a30c00002500000000000000,Sega Genesis Mini 3B controller,a:b2,b:b1,start:b9,dpup:-a4,dpdown:+a4,dpleft:-a3,dpright:+a3,righttrigger:b5,platform:Windows,
+03000000a30c00002400000000000000,Sega Mega Drive Mini 6B controller,a:b2,b:b1,start:b9,dpup:-a4,dpdown:+a4,dpleft:-a3,dpright:+a3,rightshoulder:b4,righttrigger:b5,x:b3,y:b0,platform:Windows,
030000005e0400008e02000000007801,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
@@ -328,6 +337,8 @@
030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:+a3,righty:+a4,start:b4,x:b2,y:b3,platform:Windows,
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000005e040000ff02000000007801,Xbox One Elite Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
+030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000ac0500005b05000000000000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -338,7 +349,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
# Mac OS X
-030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,
+030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
@@ -355,12 +366,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
-03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
+03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
+03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
+03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
@@ -427,6 +440,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -446,6 +460,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,
+030000004c050000e60c000000010000,Sony DualSense,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
@@ -474,6 +489,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
+030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
+030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
@@ -506,12 +523,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
-03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
-05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
+03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
+05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
-030000005e0400008e02000020010000,8BitDo Wireless Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000c82d00000031000011010000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
+030000005e0400008e02000020010000,8BitDo Wireless Adapter (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000c82d00000031000011010000,8BitDo Wireless Adapter (DInput),a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
+050000005e040000e002000030110000,8BitDo Zero 2 (XInput),a:b0,b:b1,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,start:b7,x:b2,y:b3,platform:Linux,
05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
@@ -521,11 +539,16 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000007c1800000006000010010000,Alienware Dual Compatible Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
-05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
+03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+03000000c21100000791000011010000,Be1 GC101 Controller 1.03 mode,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+03000000c31100000791000011010000,Be1 GC101 GAMEPAD 1.03 mode,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+030000005e0400008e02000003030000,Be1 GC101 Xbox 360 Controller mode,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -567,6 +590,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
030000000d0f00001600000000010000,Hori Real Arcade Pro.EX-SE (Xbox 360),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
@@ -592,6 +616,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000242f00002d00000011010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000242f00008a00000011010000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -600,10 +625,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
-030000006d04000015c2000010010000,Logitech Logitech Extreme 3D,a:b0,b:b4,back:b6,guide:b8,leftshoulder:b9,leftstick:h0.8,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:h0.2,start:b7,x:b2,y:b5,platform:Linux,
+030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
+050000004d4f435554452d3035305800,M54-PC,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,platform:Linux,
05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
@@ -635,6 +660,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
+030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000ea02000008040000,Microsoft Xbox One S pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400001a53000000010000,Mini PE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
@@ -642,12 +669,14 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+05000000c62400001a89000000010000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux,
-060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
+060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
+03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b0,y:b3,platform:Linux,
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
050000007e0500000920000001800000,Nintendo Switch Pro Controller (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
030000007e0500000920000011810000,Nintendo Switch Pro Controller Wired (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
@@ -666,21 +695,23 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000830500005020000010010000,Padix Co. Ltd. Rockfire PSX/USB Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux,
03000000790000001c18000011010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
+030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000006f0e0000b802000013020000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
+030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
+05000000491900000204000000000000,PG-9118,x:b76,a:b73,b:b74,y:b77,back:b83,start:b84,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b79,lefttrigger:b81,rightshoulder:b80,righttrigger:b82,leftstick:b86,rightstick:b87,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,
0500000049190000030400001b010000,PG-9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,
+03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -709,6 +740,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
+030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,
030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
@@ -717,6 +750,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
03000000321500000011000011010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
@@ -735,14 +769,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
-03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,
+03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
+03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux,
+03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,
03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,
03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,
03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
-03000000a30600001005000000010000,Saitek Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,
03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux,
03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -754,15 +789,15 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
+03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
+03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
+03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
-05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
-05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
+05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
+05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
+05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -774,11 +809,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
03000000457500002211000010010000,SZMY-POWER CO. LTD. GAMEPAD,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000008f0e00000d31000010010000,SZMY-POWER CO. LTD. GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+030000008f0e00001431000010010000,SZMY-POWER CO. LTD. PS3 gamepad,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux,
+030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux,
030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,
030000004f04000026b3000002040000,Thrustmaster Gamepad GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c6240000025b000002020000,Thrustmaster GPX Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
@@ -815,6 +852,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
+050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e0400008e02000000010000,xbox360 Wireless EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
03000000ac0500005b05000010010000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
@@ -823,6 +864,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
+03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpdown:+a1,dpleft:-a0,dpright:+a0,
# Android
05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android,
@@ -857,20 +899,27 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
+050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
+050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
62653861643333663663383332396665,Razer Kishi,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
+32633532643734376632656664383733,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
+61303162353165316365336436343139,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android,
30306539356238653637313730656134,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
+050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,platform:Android,
050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
+65633038363832353634653836396239,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android,
050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
@@ -879,13 +928,20 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
05000000ac0500000100000000006d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS,
05000000ac050000010000004f066d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS,
05000000ac05000001000000cf076d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS,
+05000000ac05000001000000df076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
+05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
05000000ac0500000200000000006d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS,
05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS,
-050000004c050000cc090000df070000,DUALSHOCK 4 Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS,
4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS,
+050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
+050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
+050000004c050000cc090000ff876d01,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,,platform:iOS,
+050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,platform:iOS,
05000000ac0500000300000000006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS,
05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS,
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
+050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
+050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
diff --git a/core/input/godotcontrollerdb.txt b/core/input/godotcontrollerdb.txt
index 51ddda1e4e..c43cd6c8ac 100644
--- a/core/input/godotcontrollerdb.txt
+++ b/core/input/godotcontrollerdb.txt
@@ -8,13 +8,26 @@ __XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftst
Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android,
# Javascript
-Default HTML5 Gamepad, Default Mapping,leftx:a0,lefty:a1,dpdown:b13,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:b14,lefttrigger:a6,x:b2,dpup:b12,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:b15,righttrigger:a7,b:b1,platform:Javascript,
-c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,platform:Javascript,
-303534632d303563342d576972656c65,PS4 Controller USB/Win,leftx:a0,lefty:a1,dpdown:b15,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,lefttrigger:a3,x:b0,dpup:b14,dpleft:b16,dpright:b17,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,righttrigger:b7,b:b2,platform:Javascript,
-303534632d303563342d536f6e792043,PS4 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:a7,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,dpleft:a6,lefttrigger:a3,x:b0,dpup:a7,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:a6,righttrigger:a4,b:b2,platform:Javascript,
-303534632d303236382d536f6e792050,PS3 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:b6,rightstick:b2,rightshoulder:b11,rightx:a2,start:b3,righty:a3,dpleft:b7,lefttrigger:b8,x:b15,dpup:b4,back:b0,leftstick:b1,leftshoulder:b10,y:b12,a:b14,dpright:b5,righttrigger:b9,b:b13,platform:Javascript,
-303435652d303731392d58626f782033,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,platform:Javascript,
-303435652d303238652d4d6963726f73,Wired X360 Controller,leftx:a0,lefty:a1,dpdown:a7,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:a6,lefttrigger:a2,x:b2,dpup:a7,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:a6,righttrigger:a5,b:b1,platform:Javascript,
+standard,Standard Gamepad Mapping,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a6,righttrigger:a7,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,leftstick:b10,rightstick:b11,dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,guide:b16,leftstick:b10,rightstick:b11,platform:Javascript,
+Linux24c6581a,PowerA Xbox One Cabled,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript,
+Linux0e6f0301,Logic 3 Controller (xbox compatible),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript,
+Linux045e028e,Microsoft X-Box 360 pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript,
+Linux045e02d1,Microsoft X-Box One pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript,
+Linux045e02ea,Microsoft X-Box One S pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript,
+Linux045e0b12,Microsoft X-Box Series X pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript,
+Linux044fb315,Thrustmaster dual analog 3.2,a:b0,b:b2,y:b3,x:b1,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:-a5,dpleft:-a4,dpdown:+a5,dpright:+a4,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Javascript,
+Linux0e8f0003,PS3 Controller,a:b2,b:b1,back:b8,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Javascript,
+MacOSX24c6581a,PowerA Xbox One Cabled,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript
+MacOSX045e028e,Xbox 360 Wired Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript
+MacOSX045e02d1,Xbox One Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript
+MacOSX045e02ea,Xbox One S Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript
+MacOSX045e0b12,Xbox Series X Controller,a:b11,b:b12,y:b14,x:b13,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Javascript
+Linux15320a14,Razer Wolverine Ultimate,a:b0,b:b1,y:b3,x:b2,start:b7,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript
+Linux05832060,iBuffalo BSGP801,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript
+MacOSX05832060,iBuffalo BSGP801,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript
+Linux0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript
+Windows0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript
+MacOSX0e8f3013,HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a4,dpleft:-a3,dpdown:+a4,dpright:+a3,platform:Javascript
# UWP
__UWP_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:UWP,
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 153656e44a..f928ae7654 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,6 +55,12 @@ static const char *_joy_buttons[JOY_BUTTON_SDL_MAX] = {
"dpdown",
"dpleft",
"dpright",
+ "misc1",
+ "paddle1",
+ "paddle2",
+ "paddle3",
+ "paddle4",
+ "touchpad",
};
static const char *_joy_axes[JOY_AXIS_SDL_MAX] = {
@@ -91,11 +97,11 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed);
ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed);
ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed);
- ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &Input::is_action_pressed);
- ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &Input::is_action_just_pressed);
- ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &Input::is_action_just_released);
- ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &Input::get_action_strength);
- ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action"), &Input::get_action_strength);
+ ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "exact_match"), &Input::is_action_pressed, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action", "exact_match"), &Input::is_action_just_pressed, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("is_action_just_released", "action", "exact_match"), &Input::is_action_just_released, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_axis", "negative_action", "positive_action"), &Input::get_axis);
ClassDB::bind_method(D_METHOD("get_vector", "negative_x", "positive_x", "negative_y", "positive_y", "deadzone"), &Input::get_vector, DEFVAL(-1.0f));
ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false));
@@ -234,51 +240,83 @@ bool Input::is_joy_button_pressed(int p_device, int p_button) const {
return joy_buttons_pressed.has(_combine_device(p_button, p_device));
}
-bool Input::is_action_pressed(const StringName &p_action) const {
- return action_state.has(p_action) && action_state[p_action].pressed;
+bool Input::is_action_pressed(const StringName &p_action, bool p_exact) const {
+#ifdef DEBUG_ENABLED
+ bool has_action = InputMap::get_singleton()->has_action(p_action);
+ ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
+#endif
+ return action_state.has(p_action) && action_state[p_action].pressed && (p_exact ? action_state[p_action].exact : true);
}
-bool Input::is_action_just_pressed(const StringName &p_action) const {
+bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) const {
+#ifdef DEBUG_ENABLED
+ bool has_action = InputMap::get_singleton()->has_action(p_action);
+ ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
+#endif
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return false;
}
+ if (p_exact && E->get().exact == false) {
+ return false;
+ }
+
if (Engine::get_singleton()->is_in_physics_frame()) {
return E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames();
} else {
- return E->get().pressed && E->get().idle_frame == Engine::get_singleton()->get_idle_frames();
+ return E->get().pressed && E->get().process_frame == Engine::get_singleton()->get_process_frames();
}
}
-bool Input::is_action_just_released(const StringName &p_action) const {
+bool Input::is_action_just_released(const StringName &p_action, bool p_exact) const {
+#ifdef DEBUG_ENABLED
+ bool has_action = InputMap::get_singleton()->has_action(p_action);
+ ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
+#endif
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return false;
}
+ if (p_exact && E->get().exact == false) {
+ return false;
+ }
+
if (Engine::get_singleton()->is_in_physics_frame()) {
return !E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames();
} else {
- return !E->get().pressed && E->get().idle_frame == Engine::get_singleton()->get_idle_frames();
+ return !E->get().pressed && E->get().process_frame == Engine::get_singleton()->get_process_frames();
}
}
-float Input::get_action_strength(const StringName &p_action) const {
+float Input::get_action_strength(const StringName &p_action, bool p_exact) const {
+#ifdef DEBUG_ENABLED
+ bool has_action = InputMap::get_singleton()->has_action(p_action);
+ ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
+#endif
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return 0.0f;
}
+ if (p_exact && E->get().exact == false) {
+ return 0.0f;
+ }
+
return E->get().strength;
}
-float Input::get_action_raw_strength(const StringName &p_action) const {
+float Input::get_action_raw_strength(const StringName &p_action, bool p_exact) const {
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return 0.0f;
}
+ if (p_exact && E->get().exact == false) {
+ return 0.0f;
+ }
+
return E->get().raw_strength;
}
@@ -582,20 +620,21 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
}
}
- for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) {
- if (InputMap::get_singleton()->event_is_action(p_event, E->key())) {
- // Save the action's state
- if (!p_event->is_echo() && is_action_pressed(E->key()) != p_event->is_action_pressed(E->key())) {
+ for (OrderedHashMap<StringName, InputMap::Action>::ConstElement E = InputMap::get_singleton()->get_action_map().front(); E; E = E.next()) {
+ if (InputMap::get_singleton()->event_is_action(p_event, E.key())) {
+ // If not echo and action pressed state has changed
+ if (!p_event->is_echo() && is_action_pressed(E.key(), false) != p_event->is_action_pressed(E.key())) {
Action action;
action.physics_frame = Engine::get_singleton()->get_physics_frames();
- action.idle_frame = Engine::get_singleton()->get_idle_frames();
- action.pressed = p_event->is_action_pressed(E->key());
+ action.process_frame = Engine::get_singleton()->get_process_frames();
+ action.pressed = p_event->is_action_pressed(E.key());
action.strength = 0.0f;
action.raw_strength = 0.0f;
- action_state[E->key()] = action;
+ action.exact = InputMap::get_singleton()->event_is_action(p_event, E.key(), true);
+ action_state[E.key()] = action;
}
- action_state[E->key()].strength = p_event->get_action_strength(E->key());
- action_state[E->key()].raw_strength = p_event->get_action_raw_strength(E->key());
+ action_state[E.key()].strength = p_event->get_action_strength(E.key());
+ action_state[E.key()].raw_strength = p_event->get_action_raw_strength(E.key());
}
}
@@ -714,7 +753,7 @@ void Input::action_press(const StringName &p_action, float p_strength) {
Action action;
action.physics_frame = Engine::get_singleton()->get_physics_frames();
- action.idle_frame = Engine::get_singleton()->get_idle_frames();
+ action.process_frame = Engine::get_singleton()->get_process_frames();
action.pressed = true;
action.strength = p_strength;
@@ -725,7 +764,7 @@ void Input::action_release(const StringName &p_action) {
Action action;
action.physics_frame = Engine::get_singleton()->get_physics_frames();
- action.idle_frame = Engine::get_singleton()->get_idle_frames();
+ action.process_frame = Engine::get_singleton()->get_process_frames();
action.pressed = false;
action.strength = 0.f;
@@ -806,7 +845,7 @@ void Input::accumulate_input_event(const Ref<InputEvent> &p_event) {
parse_input_event(p_event);
return;
}
- if (!accumulated_events.empty() && accumulated_events.back()->get()->accumulate(p_event)) {
+ if (!accumulated_events.is_empty() && accumulated_events.back()->get()->accumulate(p_event)) {
return; //event was accumulated, exit
}
@@ -886,10 +925,10 @@ void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
jx.min = p_value.min;
jx.value = p_value.value < 0.5 ? 0.6 : 0.4;
joy_axis(p_device, p_axis, jx);
- } else if (ABS(last) > 0.5 && last * p_value.value < 0) {
+ } else if (ABS(last) > 0.5 && last * p_value.value <= 0) {
JoyAxis jx;
jx.min = p_value.min;
- jx.value = p_value.value < 0 ? 0.1 : -0.1;
+ jx.value = last > 0 ? 0.1 : -0.1;
joy_axis(p_device, p_axis, jx);
}
diff --git a/core/input/input.h b/core/input/input.h
index 1b2df49ac0..0e3af42381 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -114,8 +114,9 @@ private:
struct Action {
uint64_t physics_frame;
- uint64_t idle_frame;
+ uint64_t process_frame;
bool pressed;
+ bool exact;
float strength;
float raw_strength;
};
@@ -261,11 +262,11 @@ public:
bool is_key_pressed(int p_keycode) const;
bool is_mouse_button_pressed(int p_button) const;
bool is_joy_button_pressed(int p_device, int p_button) const;
- bool is_action_pressed(const StringName &p_action) const;
- bool is_action_just_pressed(const StringName &p_action) const;
- bool is_action_just_released(const StringName &p_action) const;
- float get_action_strength(const StringName &p_action) const;
- float get_action_raw_strength(const StringName &p_action) const;
+ bool is_action_pressed(const StringName &p_action, bool p_exact = false) const;
+ bool is_action_just_pressed(const StringName &p_action, bool p_exact = false) const;
+ bool is_action_just_released(const StringName &p_action, bool p_exact = false) const;
+ float get_action_strength(const StringName &p_action, bool p_exact = false) const;
+ float get_action_raw_strength(const StringName &p_action, bool p_exact = false) const;
float get_axis(const StringName &p_negative_action, const StringName &p_positive_action) const;
Vector2 get_vector(const StringName &p_negative_x, const StringName &p_positive_x, const StringName &p_negative_y, const StringName &p_positive_y, float p_deadzone = -1.0f) const;
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 82bfaa82a5..c6910d2b1f 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,31 +44,31 @@ int InputEvent::get_device() const {
return device;
}
-bool InputEvent::is_action(const StringName &p_action) const {
- return InputMap::get_singleton()->event_is_action(Ref<InputEvent>((InputEvent *)this), p_action);
+bool InputEvent::is_action(const StringName &p_action, bool p_exact_match) const {
+ return InputMap::get_singleton()->event_is_action(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match);
}
-bool InputEvent::is_action_pressed(const StringName &p_action, bool p_allow_echo) const {
+bool InputEvent::is_action_pressed(const StringName &p_action, bool p_allow_echo, bool p_exact_match) const {
bool pressed;
- bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed);
+ bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match, &pressed, nullptr, nullptr);
return valid && pressed && (p_allow_echo || !is_echo());
}
-bool InputEvent::is_action_released(const StringName &p_action) const {
+bool InputEvent::is_action_released(const StringName &p_action, bool p_exact_match) const {
bool pressed;
- bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed);
+ bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match, &pressed, nullptr, nullptr);
return valid && !pressed;
}
-float InputEvent::get_action_strength(const StringName &p_action) const {
+float InputEvent::get_action_strength(const StringName &p_action, bool p_exact_match) const {
float strength;
- bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, nullptr, &strength);
+ bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match, nullptr, &strength, nullptr);
return valid ? strength : 0.0f;
}
-float InputEvent::get_action_raw_strength(const StringName &p_action) const {
+float InputEvent::get_action_raw_strength(const StringName &p_action, bool p_exact_match) const {
float raw_strength;
- bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, nullptr, nullptr, &raw_strength);
+ bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, p_exact_match, nullptr, nullptr, &raw_strength);
return valid ? raw_strength : 0.0f;
}
@@ -100,10 +100,10 @@ void InputEvent::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_device", "device"), &InputEvent::set_device);
ClassDB::bind_method(D_METHOD("get_device"), &InputEvent::get_device);
- ClassDB::bind_method(D_METHOD("is_action", "action"), &InputEvent::is_action);
- ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "allow_echo"), &InputEvent::is_action_pressed, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("is_action_released", "action"), &InputEvent::is_action_released);
- ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &InputEvent::get_action_strength);
+ ClassDB::bind_method(D_METHOD("is_action", "action", "exact_match"), &InputEvent::is_action, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "allow_echo", "exact_match"), &InputEvent::is_action_pressed, DEFVAL(false), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("is_action_released", "action", "exact_match"), &InputEvent::is_action_released, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact_match"), &InputEvent::get_action_strength, DEFVAL(false));
ClassDB::bind_method(D_METHOD("is_pressed"), &InputEvent::is_pressed);
ClassDB::bind_method(D_METHOD("is_echo"), &InputEvent::is_echo);
@@ -210,7 +210,7 @@ String InputEventWithModifiers::as_text() const {
mod_names.push_back(find_keycode_name(KEY_META));
}
- if (!mod_names.empty()) {
+ if (!mod_names.is_empty()) {
return String("+").join(mod_names);
} else {
return "";
@@ -384,6 +384,31 @@ String InputEventKey::to_string() {
return vformat("InputEventKey: keycode=%s mods=%s physical=%s pressed=%s echo=%s", kc, mods, physical, p, e);
}
+Ref<InputEventKey> InputEventKey::create_reference(uint32_t p_keycode) {
+ Ref<InputEventKey> ie;
+ ie.instance();
+ ie->set_keycode(p_keycode & KEY_CODE_MASK);
+ ie->set_unicode(p_keycode & KEY_CODE_MASK);
+
+ if (p_keycode & KEY_MASK_SHIFT) {
+ ie->set_shift(true);
+ }
+ if (p_keycode & KEY_MASK_ALT) {
+ ie->set_alt(true);
+ }
+ if (p_keycode & KEY_MASK_CTRL) {
+ ie->set_control(true);
+ }
+ if (p_keycode & KEY_MASK_CMD) {
+ ie->set_command(true);
+ }
+ if (p_keycode & KEY_MASK_META) {
+ ie->set_metakey(true);
+ }
+
+ return ie;
+}
+
bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
Ref<InputEventKey> key = p_event;
if (key.is_null()) {
@@ -985,6 +1010,12 @@ static const char *_joy_button_descriptions[JOY_BUTTON_SDL_MAX] = {
TTRC("D-pad Down"),
TTRC("D-pad Left"),
TTRC("D-pad Right"),
+ TTRC("Xbox Share, PS5 Microphone, Nintendo Capture"),
+ TTRC("Xbox Paddle 1"),
+ TTRC("Xbox Paddle 2"),
+ TTRC("Xbox Paddle 3"),
+ TTRC("Xbox Paddle 4"),
+ TTRC("PS4/5 Touchpad"),
};
String InputEventJoypadButton::as_text() const {
@@ -1005,6 +1036,14 @@ String InputEventJoypadButton::to_string() {
return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure));
}
+Ref<InputEventJoypadButton> InputEventJoypadButton::create_reference(int p_btn_index) {
+ Ref<InputEventJoypadButton> ie;
+ ie.instance();
+ ie->set_button_index(p_btn_index);
+
+ return ie;
+}
+
void InputEventJoypadButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_button_index", "button_index"), &InputEventJoypadButton::set_button_index);
ClassDB::bind_method(D_METHOD("get_button_index"), &InputEventJoypadButton::get_button_index);
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 6a71a24c8b..df81b9fc75 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -76,7 +76,13 @@ enum JoyButtonList {
JOY_BUTTON_DPAD_DOWN = 12,
JOY_BUTTON_DPAD_LEFT = 13,
JOY_BUTTON_DPAD_RIGHT = 14,
- JOY_BUTTON_SDL_MAX = 15,
+ JOY_BUTTON_MISC1 = 15,
+ JOY_BUTTON_PADDLE1 = 16,
+ JOY_BUTTON_PADDLE2 = 17,
+ JOY_BUTTON_PADDLE3 = 18,
+ JOY_BUTTON_PADDLE4 = 19,
+ JOY_BUTTON_TOUCHPAD = 20,
+ JOY_BUTTON_SDL_MAX = 21,
JOY_BUTTON_MAX = 36, // Android supports up to 36 buttons.
};
@@ -122,11 +128,11 @@ public:
void set_device(int p_device);
int get_device() const;
- bool is_action(const StringName &p_action) const;
- bool is_action_pressed(const StringName &p_action, bool p_allow_echo = false) const;
- bool is_action_released(const StringName &p_action) const;
- float get_action_strength(const StringName &p_action) const;
- float get_action_raw_strength(const StringName &p_action) const;
+ bool is_action(const StringName &p_action, bool p_exact_match = false) const;
+ bool is_action_pressed(const StringName &p_action, bool p_allow_echo = false, bool p_exact_match = false) const;
+ bool is_action_released(const StringName &p_action, bool p_exact_match = false) const;
+ float get_action_strength(const StringName &p_action, bool p_exact_match = false) const;
+ float get_action_raw_strength(const StringName &p_action, bool p_exact_match = false) const;
// To be removed someday, since they do not make sense for all events
virtual bool is_pressed() const;
@@ -254,6 +260,8 @@ public:
virtual String as_text() const override;
virtual String to_string() override;
+ static Ref<InputEventKey> create_reference(uint32_t p_keycode_with_modifier_masks);
+
InputEventKey() {}
};
@@ -400,6 +408,8 @@ public:
virtual String as_text() const override;
virtual String to_string() override;
+ static Ref<InputEventJoypadButton> create_reference(int p_btn_index);
+
InputEventJoypadButton() {}
};
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 979809c7af..e0b25fa092 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,7 +50,7 @@ void InputMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("action_erase_event", "action", "event"), &InputMap::action_erase_event);
ClassDB::bind_method(D_METHOD("action_erase_events", "action"), &InputMap::action_erase_events);
ClassDB::bind_method(D_METHOD("action_get_events", "action"), &InputMap::_action_get_events);
- ClassDB::bind_method(D_METHOD("event_is_action", "event", "action"), &InputMap::event_is_action);
+ ClassDB::bind_method(D_METHOD("event_is_action", "event", "action", "exact_match"), &InputMap::event_is_action, DEFVAL(false));
ClassDB::bind_method(D_METHOD("load_from_project_settings"), &InputMap::load_from_project_settings);
}
@@ -71,7 +71,7 @@ void InputMap::erase_action(const StringName &p_action) {
Array InputMap::_get_actions() {
Array ret;
List<StringName> actions = get_actions();
- if (actions.empty()) {
+ if (actions.is_empty()) {
return ret;
}
@@ -84,18 +84,18 @@ Array InputMap::_get_actions() {
List<StringName> InputMap::get_actions() const {
List<StringName> actions = List<StringName>();
- if (input_map.empty()) {
+ if (input_map.is_empty()) {
return actions;
}
- for (Map<StringName, Action>::Element *E = input_map.front(); E; E = E->next()) {
- actions.push_back(E->key());
+ for (OrderedHashMap<StringName, Action>::Element E = input_map.front(); E; E = E.next()) {
+ actions.push_back(E.key());
}
return actions;
}
-List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
+List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
ERR_FAIL_COND_V(!p_event.is_valid(), nullptr);
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
@@ -106,7 +106,9 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re
int device = e->get_device();
if (device == ALL_DEVICES || device == p_event->get_device()) {
- if (e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) {
+ if (p_exact_match && e->shortcut_match(p_event)) {
+ return E;
+ } else if (!p_exact_match && e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) {
return E;
}
}
@@ -134,7 +136,7 @@ void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone)
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
- if (_find_event(input_map[p_action], p_event)) {
+ if (_find_event(input_map[p_action], p_event, true)) {
return; // Already addded.
}
@@ -143,13 +145,13 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
- return (_find_event(input_map[p_action], p_event) != nullptr);
+ return (_find_event(input_map[p_action], p_event, true) != nullptr);
}
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
- List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event);
+ List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event, true);
if (E) {
input_map[p_action].inputs.erase(E);
if (Input::get_singleton()->is_action_pressed(p_action)) {
@@ -177,20 +179,20 @@ Array InputMap::_action_get_events(const StringName &p_action) {
}
const List<Ref<InputEvent>> *InputMap::action_get_events(const StringName &p_action) {
- const Map<StringName, Action>::Element *E = input_map.find(p_action);
+ const OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action);
if (!E) {
return nullptr;
}
- return &E->get().inputs;
+ return &E.get().inputs;
}
-bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const {
- return event_get_action_status(p_event, p_action);
+bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match) const {
+ return event_get_action_status(p_event, p_action, p_exact_match);
}
-bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
- Map<StringName, Action>::Element *E = input_map.find(p_action);
+bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
+ OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action);
ERR_FAIL_COND_V_MSG(!E, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
Ref<InputEventAction> input_event_action = p_event;
@@ -207,7 +209,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
bool pressed;
float strength;
float raw_strength;
- List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength, &raw_strength);
+ List<Ref<InputEvent>>::Element *event = _find_event(E.get(), p_event, p_exact_match, &pressed, &strength, &raw_strength);
if (event != nullptr) {
if (p_pressed != nullptr) {
*p_pressed = pressed;
@@ -224,7 +226,7 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
}
}
-const Map<StringName, InputMap::Action> &InputMap::get_action_map() const {
+const OrderedHashMap<StringName, InputMap::Action> &InputMap::get_action_map() const {
return input_map;
}
@@ -258,84 +260,444 @@ void InputMap::load_from_project_settings() {
}
}
+struct _BuiltinActionDisplayName {
+ const char *name;
+ const char *display_name;
+};
+
+static const _BuiltinActionDisplayName _builtin_action_display_names[] = {
+ /* clang-format off */
+ { "ui_accept", TTRC("Accept") },
+ { "ui_select", TTRC("Select") },
+ { "ui_cancel", TTRC("Cancel") },
+ { "ui_focus_next", TTRC("Focus Next") },
+ { "ui_focus_prev", TTRC("Focus Prev") },
+ { "ui_left", TTRC("Left") },
+ { "ui_right", TTRC("Right") },
+ { "ui_up", TTRC("Up") },
+ { "ui_down", TTRC("Down") },
+ { "ui_page_up", TTRC("Page Up") },
+ { "ui_page_down", TTRC("Page Down") },
+ { "ui_home", TTRC("Home") },
+ { "ui_end", TTRC("End") },
+ { "ui_cut", TTRC("Cut") },
+ { "ui_copy", TTRC("Copy") },
+ { "ui_paste", TTRC("Paste") },
+ { "ui_undo", TTRC("Undo") },
+ { "ui_redo", TTRC("Redo") },
+ { "ui_text_completion_query", TTRC("Completion Query") },
+ { "ui_text_newline", TTRC("New Line") },
+ { "ui_text_newline_blank", TTRC("New Blank Line") },
+ { "ui_text_newline_above", TTRC("New Line Above") },
+ { "ui_text_indent", TTRC("Indent") },
+ { "ui_text_dedent", TTRC("Dedent") },
+ { "ui_text_backspace", TTRC("Backspace") },
+ { "ui_text_backspace_word", TTRC("Backspace Word") },
+ { "ui_text_backspace_word.OSX", TTRC("Backspace Word") },
+ { "ui_text_backspace_all_to_left", TTRC("Backspace all to Left") },
+ { "ui_text_backspace_all_to_left.OSX", TTRC("Backspace all to Left") },
+ { "ui_text_delete", TTRC("Delete") },
+ { "ui_text_delete_word", TTRC("Delete Word") },
+ { "ui_text_delete_word.OSX", TTRC("Delete Word") },
+ { "ui_text_delete_all_to_right", TTRC("Delete all to Right") },
+ { "ui_text_delete_all_to_right.OSX", TTRC("Delete all to Right") },
+ { "ui_text_caret_left", TTRC("Caret Left") },
+ { "ui_text_caret_word_left", TTRC("Caret Word Left") },
+ { "ui_text_caret_word_left.OSX", TTRC("Caret Word Left") },
+ { "ui_text_caret_right", TTRC("Caret Right") },
+ { "ui_text_caret_word_right", TTRC("Caret Word Right") },
+ { "ui_text_caret_word_right.OSX", TTRC("Caret Word Right") },
+ { "ui_text_caret_up", TTRC("Caret Up") },
+ { "ui_text_caret_down", TTRC("Caret Down") },
+ { "ui_text_caret_line_start", TTRC("Caret Line Start") },
+ { "ui_text_caret_line_start.OSX", TTRC("Caret Line Start") },
+ { "ui_text_caret_line_end", TTRC("Caret Line End") },
+ { "ui_text_caret_line_end.OSX", TTRC("Caret Line End") },
+ { "ui_text_caret_page_up", TTRC("Caret Page Up") },
+ { "ui_text_caret_page_down", TTRC("Caret Page Down") },
+ { "ui_text_caret_document_start", TTRC("Caret Document Start") },
+ { "ui_text_caret_document_start.OSX", TTRC("Caret Document Start") },
+ { "ui_text_caret_document_end", TTRC("Caret Document End") },
+ { "ui_text_caret_document_end.OSX", TTRC("Caret Document End") },
+ { "ui_text_scroll_up", TTRC("Scroll Up") },
+ { "ui_text_scroll_up.OSX", TTRC("Scroll Up") },
+ { "ui_text_scroll_down", TTRC("Scroll Down") },
+ { "ui_text_scroll_down.OSX", TTRC("Scroll Down") },
+ { "ui_text_select_all", TTRC("Select All") },
+ { "ui_text_toggle_insert_mode", TTRC("Toggle Insert Mode") },
+ { "ui_graph_duplicate", TTRC("Duplicate Nodes") },
+ { "ui_graph_delete", TTRC("Delete Nodes") },
+ { "ui_filedialog_up_one_level", TTRC("Go Up One Level") },
+ { "ui_filedialog_refresh", TTRC("Refresh") },
+ { "ui_filedialog_show_hidden", TTRC("Show Hidden") },
+ { "ui_swap_input_direction ", TTRC("Swap Input Direction") },
+ { "", TTRC("")}
+ /* clang-format on */
+};
+
+String InputMap::get_builtin_display_name(const String &p_name) const {
+ int len = sizeof(_builtin_action_display_names) / sizeof(_BuiltinActionDisplayName);
+
+ for (int i = 0; i < len; i++) {
+ if (_builtin_action_display_names[i].name == p_name) {
+ return RTR(_builtin_action_display_names[i].display_name);
+ }
+ }
+
+ return p_name;
+}
+
+const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() {
+ // Return cache if it has already been built.
+ if (default_builtin_cache.size()) {
+ return default_builtin_cache;
+ }
+
+ List<Ref<InputEvent>> inputs;
+ inputs.push_back(InputEventKey::create_reference(KEY_ENTER));
+ inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER));
+ inputs.push_back(InputEventKey::create_reference(KEY_SPACE));
+ default_builtin_cache.insert("ui_accept", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_Y));
+ inputs.push_back(InputEventKey::create_reference(KEY_SPACE));
+ default_builtin_cache.insert("ui_select", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_ESCAPE));
+ default_builtin_cache.insert("ui_cancel", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_TAB));
+ default_builtin_cache.insert("ui_focus_next", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_TAB | KEY_MASK_SHIFT));
+ default_builtin_cache.insert("ui_focus_prev", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_LEFT));
+ inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_LEFT));
+ default_builtin_cache.insert("ui_left", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_RIGHT));
+ inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_RIGHT));
+ default_builtin_cache.insert("ui_right", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_UP));
+ inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_UP));
+ default_builtin_cache.insert("ui_up", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DOWN));
+ inputs.push_back(InputEventJoypadButton::create_reference(JOY_BUTTON_DPAD_DOWN));
+ default_builtin_cache.insert("ui_down", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_PAGEUP));
+ default_builtin_cache.insert("ui_page_up", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_PAGEDOWN));
+ default_builtin_cache.insert("ui_page_down", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_HOME));
+ default_builtin_cache.insert("ui_home", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_END));
+ default_builtin_cache.insert("ui_end", inputs);
+
+ // ///// UI basic Shortcuts /////
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_X | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_SHIFT));
+ default_builtin_cache.insert("ui_cut", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_C | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(KEY_INSERT | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_copy", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_V | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(KEY_INSERT | KEY_MASK_SHIFT));
+ default_builtin_cache.insert("ui_paste", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_Z | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_undo", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_Z | KEY_MASK_CMD | KEY_MASK_SHIFT));
+ inputs.push_back(InputEventKey::create_reference(KEY_Y | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_redo", inputs);
+
+ // ///// UI Text Input Shortcuts /////
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_SPACE | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_completion_query", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_TAB));
+ default_builtin_cache.insert("ui_text_completion_accept", inputs);
+
+ // Newlines
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_ENTER));
+ inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER));
+ default_builtin_cache.insert("ui_text_newline", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+
+ inputs.push_back(InputEventKey::create_reference(KEY_ENTER | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_newline_blank", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_ENTER | KEY_MASK_SHIFT | KEY_MASK_CMD));
+ inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER | KEY_MASK_SHIFT | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_newline_above", inputs);
+
+ // Indentation
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_TAB));
+ default_builtin_cache.insert("ui_text_indent", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_TAB | KEY_MASK_SHIFT));
+ default_builtin_cache.insert("ui_text_dedent", inputs);
+
+ // Text Backspace and Delete
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE));
+ default_builtin_cache.insert("ui_text_backspace", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_backspace_word", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_ALT));
+ default_builtin_cache.insert("ui_text_backspace_word.OSX", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ default_builtin_cache.insert("ui_text_backspace_all_to_left", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_backspace_all_to_left.OSX", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DELETE));
+ default_builtin_cache.insert("ui_text_delete", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_delete_word", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_ALT));
+ default_builtin_cache.insert("ui_text_delete_word.OSX", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ default_builtin_cache.insert("ui_text_delete_all_to_right", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DELETE | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_delete_all_to_right.OSX", inputs);
+
+ // Text Caret Movement Left/Right
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_LEFT));
+ default_builtin_cache.insert("ui_text_caret_left", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_caret_word_left", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_ALT));
+ default_builtin_cache.insert("ui_text_caret_word_left.OSX", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_RIGHT));
+ default_builtin_cache.insert("ui_text_caret_right", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_caret_word_right", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_ALT));
+ default_builtin_cache.insert("ui_text_caret_word_right.OSX", inputs);
+
+ // Text Caret Movement Up/Down
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_UP));
+ default_builtin_cache.insert("ui_text_caret_up", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DOWN));
+ default_builtin_cache.insert("ui_text_caret_down", inputs);
+
+ // Text Caret Movement Line Start/End
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_HOME));
+ default_builtin_cache.insert("ui_text_caret_line_start", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_A | KEY_MASK_CTRL));
+ inputs.push_back(InputEventKey::create_reference(KEY_LEFT | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_caret_line_start.OSX", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_END));
+ default_builtin_cache.insert("ui_text_caret_line_end", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_E | KEY_MASK_CTRL));
+ inputs.push_back(InputEventKey::create_reference(KEY_RIGHT | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_caret_line_end.OSX", inputs);
+ // Text Caret Movement Page Up/Down
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_PAGEUP));
+ default_builtin_cache.insert("ui_text_caret_page_up", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_PAGEDOWN));
+ default_builtin_cache.insert("ui_text_caret_page_down", inputs);
+
+ // Text Caret Movement Document Start/End
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_HOME | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_caret_document_start", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_caret_document_start.OSX", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_END | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_caret_document_end", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_caret_document_end.OSX", inputs);
+
+ // Text Scrolling
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_scroll_up", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_UP | KEY_MASK_CMD | KEY_MASK_ALT));
+ default_builtin_cache.insert("ui_text_scroll_up.OSX", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_scroll_down", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DOWN | KEY_MASK_CMD | KEY_MASK_ALT));
+ default_builtin_cache.insert("ui_text_scroll_down.OSX", inputs);
+
+ // Text Misc
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_A | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_text_select_all", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_INSERT));
+ default_builtin_cache.insert("ui_text_toggle_insert_mode", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_MENU));
+ default_builtin_cache.insert("ui_menu", inputs);
+
+ // ///// UI Graph Shortcuts /////
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_D | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_graph_duplicate", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_DELETE));
+ default_builtin_cache.insert("ui_graph_delete", inputs);
+
+ // ///// UI File Dialog Shortcuts /////
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE));
+ default_builtin_cache.insert("ui_filedialog_up_one_level", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_F5));
+ default_builtin_cache.insert("ui_filedialog_refresh", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_H));
+ default_builtin_cache.insert("ui_filedialog_show_hidden", inputs);
+
+ inputs = List<Ref<InputEvent>>();
+ inputs.push_back(InputEventKey::create_reference(KEY_QUOTELEFT | KEY_MASK_CMD));
+ default_builtin_cache.insert("ui_swap_input_direction", inputs);
+
+ return default_builtin_cache;
+}
+
void InputMap::load_default() {
- Ref<InputEventKey> key;
-
- add_action("ui_accept");
- key.instance();
- key->set_keycode(KEY_ENTER);
- action_add_event("ui_accept", key);
-
- key.instance();
- key->set_keycode(KEY_KP_ENTER);
- action_add_event("ui_accept", key);
-
- key.instance();
- key->set_keycode(KEY_SPACE);
- action_add_event("ui_accept", key);
-
- add_action("ui_select");
- key.instance();
- key->set_keycode(KEY_SPACE);
- action_add_event("ui_select", key);
-
- add_action("ui_cancel");
- key.instance();
- key->set_keycode(KEY_ESCAPE);
- action_add_event("ui_cancel", key);
-
- add_action("ui_focus_next");
- key.instance();
- key->set_keycode(KEY_TAB);
- action_add_event("ui_focus_next", key);
-
- add_action("ui_focus_prev");
- key.instance();
- key->set_keycode(KEY_TAB);
- key->set_shift(true);
- action_add_event("ui_focus_prev", key);
-
- add_action("ui_left");
- key.instance();
- key->set_keycode(KEY_LEFT);
- action_add_event("ui_left", key);
-
- add_action("ui_right");
- key.instance();
- key->set_keycode(KEY_RIGHT);
- action_add_event("ui_right", key);
-
- add_action("ui_up");
- key.instance();
- key->set_keycode(KEY_UP);
- action_add_event("ui_up", key);
-
- add_action("ui_down");
- key.instance();
- key->set_keycode(KEY_DOWN);
- action_add_event("ui_down", key);
-
- add_action("ui_page_up");
- key.instance();
- key->set_keycode(KEY_PAGEUP);
- action_add_event("ui_page_up", key);
-
- add_action("ui_page_down");
- key.instance();
- key->set_keycode(KEY_PAGEDOWN);
- action_add_event("ui_page_down", key);
-
- add_action("ui_home");
- key.instance();
- key->set_keycode(KEY_HOME);
- action_add_event("ui_home", key);
-
- add_action("ui_end");
- key.instance();
- key->set_keycode(KEY_END);
- action_add_event("ui_end", key);
-
- //set("display/window/handheld/orientation", "landscape");
+ OrderedHashMap<String, List<Ref<InputEvent>>> builtins = get_builtins();
+
+ // List of Builtins which have an override for OSX.
+ Vector<String> osx_builtins;
+ for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) {
+ if (String(E.key()).ends_with(".OSX")) {
+ // Strip .OSX from name: some_input_name.OSX -> some_input_name
+ osx_builtins.push_back(String(E.key()).split(".")[0]);
+ }
+ }
+
+ for (OrderedHashMap<String, List<Ref<InputEvent>>>::Element E = builtins.front(); E; E = E.next()) {
+ String fullname = E.key();
+ String name = fullname.split(".")[0];
+ String override_for = fullname.split(".").size() > 1 ? fullname.split(".")[1] : "";
+
+#ifdef APPLE_STYLE_KEYS
+ if (osx_builtins.has(name) && override_for != "OSX") {
+ // Name has osx builtin but this particular one is for non-osx systems - so skip.
+ continue;
+ }
+#else
+ if (override_for == "OSX") {
+ // Override for OSX - not needed on non-osx platforms.
+ continue;
+ }
+#endif
+
+ add_action(name);
+
+ List<Ref<InputEvent>> inputs = E.get();
+ for (List<Ref<InputEvent>>::Element *I = inputs.front(); I; I = I->next()) {
+ Ref<InputEventKey> iek = I->get();
+
+ // For the editor, only add keyboard actions.
+ if (iek.is_valid()) {
+ action_add_event(name, I->get());
+ }
+ }
+ }
}
InputMap::InputMap() {
diff --git a/core/input/input_map.h b/core/input/input_map.h
index 948d78ebdd..99c71e1e53 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,8 @@
#include "core/input/input_event.h"
#include "core/object/class_db.h"
+#include "core/object/object.h"
+#include "core/templates/ordered_hash_map.h"
class InputMap : public Object {
GDCLASS(InputMap, Object);
@@ -52,9 +54,10 @@ public:
private:
static InputMap *singleton;
- mutable Map<StringName, Action> input_map;
+ mutable OrderedHashMap<StringName, Action> input_map;
+ OrderedHashMap<String, List<Ref<InputEvent>>> default_builtin_cache;
- List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const;
+ List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match = false, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const;
Array _action_get_events(const StringName &p_action);
Array _get_actions();
@@ -78,13 +81,17 @@ public:
void action_erase_events(const StringName &p_action);
const List<Ref<InputEvent>> *action_get_events(const StringName &p_action);
- bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const;
- bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const;
+ bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false) const;
+ bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const;
- const Map<StringName, Action> &get_action_map() const;
+ const OrderedHashMap<StringName, Action> &get_action_map() const;
void load_from_project_settings();
void load_default();
+ String get_builtin_display_name(const String &p_name) const;
+ // Use an Ordered Map so insertion order is preserved. We want the elements to be 'grouped' somewhat.
+ const OrderedHashMap<String, List<Ref<InputEvent>>> &get_builtins();
+
InputMap();
};
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index 8e613cb3ce..456023e2a6 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/compression.h b/core/io/compression.h
index 864869788a..cbfed74124 100644
--- a/core/io/compression.h
+++ b/core/io/compression.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index 8be39178db..015c1f0d90 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -67,7 +67,7 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V
return; // ?
}
values[p_section].erase(p_key);
- if (values[p_section].empty()) {
+ if (values[p_section].is_empty()) {
values.erase(p_section);
}
diff --git a/core/io/config_file.h b/core/io/config_file.h
index 1dc4492ca8..386d304f07 100644
--- a/core/io/config_file.h
+++ b/core/io/config_file.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/dtls_server.cpp b/core/io/dtls_server.cpp
index 1930f40c47..288b2efe0e 100644
--- a/core/io/dtls_server.cpp
+++ b/core/io/dtls_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/dtls_server.h b/core/io/dtls_server.h
index ae1d3bcd98..92b6caf508 100644
--- a/core/io/dtls_server.h
+++ b/core/io/dtls_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index b06b3c078f..9ec2b27e88 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h
index 52284b347e..118d05ea57 100644
--- a/core/io/file_access_compressed.h
+++ b/core/io/file_access_compressed.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index cf5800b472..8b4c57ce64 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index c760933038..969052d04f 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index 79cba63765..04270de77f 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h
index 47012b4e83..0e3b0ad7b1 100644
--- a/core/io/file_access_memory.h
+++ b/core/io/file_access_memory.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index 1e9266f118..97838fd14c 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -201,7 +201,7 @@ Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const S
return ERR_INVALID_PARAMETER;
}
- thread = Thread::create(_thread_func, this);
+ thread.start(_thread_func, this);
return OK;
}
@@ -214,12 +214,9 @@ FileAccessNetworkClient::FileAccessNetworkClient() {
}
FileAccessNetworkClient::~FileAccessNetworkClient() {
- if (thread) {
- quit = true;
- sem.post();
- Thread::wait_to_finish(thread);
- memdelete(thread);
- }
+ quit = true;
+ sem.post();
+ thread.wait_to_finish();
}
void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) {
@@ -350,7 +347,7 @@ void FileAccessNetwork::_queue_page(int p_page) const {
if (p_page >= pages.size()) {
return;
}
- if (pages[p_page].buffer.empty() && !pages[p_page].queued) {
+ if (pages[p_page].buffer.is_empty() && !pages[p_page].queued) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
{
MutexLock lock(nc->blockrequest_mutex);
@@ -386,7 +383,7 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
if (page != last_page) {
buffer_mutex.lock();
- if (pages[page].buffer.empty()) {
+ if (pages[page].buffer.is_empty()) {
waiting_on_page = page;
for (int j = 0; j < read_ahead; j++) {
_queue_page(page + j);
diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h
index dc5ce1e883..1f5de3e5dd 100644
--- a/core/io/file_access_network.h
+++ b/core/io/file_access_network.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,7 +48,7 @@ class FileAccessNetworkClient {
List<BlockRequest> block_requests;
Semaphore sem;
- Thread *thread = nullptr;
+ Thread thread;
bool quit = false;
Mutex mutex;
Mutex blockrequest_mutex;
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index a025ca5730..faf4fca14f 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -89,7 +89,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
}
String filename = path.get_file();
// Don't add as a file if the path points to a directory
- if (!filename.empty()) {
+ if (!filename.is_empty()) {
cd->files.insert(filename);
}
}
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index c13626a5aa..343adbe592 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -92,7 +92,7 @@ private:
PathMD5() {}
- PathMD5(const Vector<uint8_t> p_buf) {
+ PathMD5(const Vector<uint8_t> &p_buf) {
a = *((uint64_t *)&p_buf[0]);
b = *((uint64_t *)&p_buf[8]);
}
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index 1163c409bc..01f9337a80 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h
index f8e7c1e587..8559f871ce 100644
--- a/core/io/file_access_zip.h
+++ b/core/io/file_access_zip.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 768fcdbb14..3863dce0f6 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -96,6 +96,11 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,
void HTTPClient::set_connection(const Ref<StreamPeer> &p_connection) {
ERR_FAIL_COND_MSG(p_connection.is_null(), "Connection is not a reference to a valid StreamPeer object.");
+ if (ssl) {
+ ERR_FAIL_NULL_MSG(Object::cast_to<StreamPeerSSL>(p_connection.ptr()),
+ "Connection is not a reference to a valid StreamPeerSSL object.");
+ }
+
if (connection == p_connection) {
return;
}
@@ -736,14 +741,14 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
String query = "";
Array keys = p_dict.keys();
for (int i = 0; i < keys.size(); ++i) {
- String encoded_key = String(keys[i]).http_escape();
+ String encoded_key = String(keys[i]).uri_encode();
Variant value = p_dict[keys[i]];
switch (value.get_type()) {
case Variant::ARRAY: {
// Repeat the key with every values
Array values = value;
for (int j = 0; j < values.size(); ++j) {
- query += "&" + encoded_key + "=" + String(values[j]).http_escape();
+ query += "&" + encoded_key + "=" + String(values[j]).uri_encode();
}
break;
}
@@ -754,7 +759,7 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
}
default: {
// Add the key-value pair
- query += "&" + encoded_key + "=" + String(value).http_escape();
+ query += "&" + encoded_key + "=" + String(value).uri_encode();
}
}
}
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 3d9fe321ba..ec4b86b26f 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/image.cpp b/core/io/image.cpp
index 56d84325b5..5d46d75efe 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -375,7 +375,7 @@ Image::Image3DValidateError Image::validate_3d_image(Image::Format p_format, int
if (idx >= p_images.size()) {
return VALIDATE_3D_ERR_MISSING_IMAGES;
}
- if (p_images[idx].is_null() || p_images[idx]->empty()) {
+ if (p_images[idx].is_null() || p_images[idx]->is_empty()) {
return VALIDATE_3D_ERR_IMAGE_EMPTY;
}
if (p_images[idx]->get_format() != p_format) {
@@ -1753,10 +1753,10 @@ Error Image::generate_mipmaps(bool p_renormalize) {
Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, const Ref<Image> &p_normal_map) {
Vector<double> normal_sat_vec; //summed area table
- double *normal_sat = nullptr; //summed area table for normalmap
+ double *normal_sat = nullptr; //summed area table for normal map
int normal_w = 0, normal_h = 0;
- ERR_FAIL_COND_V_MSG(p_normal_map.is_null() || p_normal_map->empty(), ERR_INVALID_PARAMETER, "Must provide a valid normalmap for roughness mipmaps");
+ ERR_FAIL_COND_V_MSG(p_normal_map.is_null() || p_normal_map->is_empty(), ERR_INVALID_PARAMETER, "Must provide a valid normal map for roughness mipmaps");
Ref<Image> nm = p_normal_map->duplicate();
if (nm->is_compressed()) {
@@ -1950,7 +1950,7 @@ void Image::clear_mipmaps() {
return;
}
- if (empty()) {
+ if (is_empty()) {
return;
}
@@ -1961,7 +1961,7 @@ void Image::clear_mipmaps() {
mipmaps = false;
}
-bool Image::empty() const {
+bool Image::is_empty() const {
return (data.size() == 0);
}
@@ -2985,6 +2985,26 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
_set_color_at_ofs(data.ptrw(), ofs, p_color);
}
+void Image::adjust_bcs(float p_brightness, float p_contrast, float p_saturation) {
+ uint8_t *w = data.ptrw();
+ uint32_t pixel_size = get_format_pixel_size(format);
+ uint32_t pixel_count = data.size() / pixel_size;
+
+ for (uint32_t i = 0; i < pixel_count; i++) {
+ Color c = _get_color_at_ofs(w, i);
+ Vector3 rgb(c.r, c.g, c.b);
+
+ rgb *= p_brightness;
+ rgb = Vector3(0.5, 0.5, 0.5).lerp(rgb, p_contrast);
+ float center = (rgb.x + rgb.y + rgb.z) / 3.0;
+ rgb = Vector3(center, center, center).lerp(rgb, p_saturation);
+ c.r = rgb.x;
+ c.g = rgb.y;
+ c.b = rgb.z;
+ _set_color_at_ofs(w, i, c);
+ }
+}
+
Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
ERR_FAIL_COND_V(data.size() == 0, USED_CHANNELS_RGBA);
ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA);
@@ -3090,7 +3110,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("create", "width", "height", "use_mipmaps", "format"), &Image::_create_empty);
ClassDB::bind_method(D_METHOD("create_from_data", "width", "height", "use_mipmaps", "format", "data"), &Image::_create_from_data);
- ClassDB::bind_method(D_METHOD("is_empty"), &Image::empty);
+ ClassDB::bind_method(D_METHOD("is_empty"), &Image::is_empty);
ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
@@ -3109,9 +3129,9 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("fix_alpha_edges"), &Image::fix_alpha_edges);
ClassDB::bind_method(D_METHOD("premultiply_alpha"), &Image::premultiply_alpha);
ClassDB::bind_method(D_METHOD("srgb_to_linear"), &Image::srgb_to_linear);
- ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy);
+ ClassDB::bind_method(D_METHOD("normal_map_to_xy"), &Image::normal_map_to_xy);
ClassDB::bind_method(D_METHOD("rgbe_to_srgb"), &Image::rgbe_to_srgb);
- ClassDB::bind_method(D_METHOD("bumpmap_to_normalmap", "bump_scale"), &Image::bumpmap_to_normalmap, DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("bump_map_to_normal_map", "bump_scale"), &Image::bump_map_to_normal_map, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("blit_rect", "src", "src_rect", "dst"), &Image::blit_rect);
ClassDB::bind_method(D_METHOD("blit_rect_mask", "src", "mask", "src_rect", "dst"), &Image::blit_rect_mask);
@@ -3132,6 +3152,8 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pixelv", "point", "color"), &Image::set_pixelv);
ClassDB::bind_method(D_METHOD("set_pixel", "x", "y", "color"), &Image::set_pixel);
+ ClassDB::bind_method(D_METHOD("adjust_bcs", "brightness", "contrast", "saturation"), &Image::adjust_bcs);
+
ClassDB::bind_method(D_METHOD("load_png_from_buffer", "buffer"), &Image::load_png_from_buffer);
ClassDB::bind_method(D_METHOD("load_jpg_from_buffer", "buffer"), &Image::load_jpg_from_buffer);
ClassDB::bind_method(D_METHOD("load_webp_from_buffer", "buffer"), &Image::load_webp_from_buffer);
@@ -3220,7 +3242,7 @@ void Image::set_compress_bptc_func(void (*p_compress_func)(Image *, float, UsedC
_image_compress_bptc_func = p_compress_func;
}
-void Image::normalmap_to_xy() {
+void Image::normal_map_to_xy() {
convert(Image::FORMAT_RGBA8);
{
@@ -3285,7 +3307,7 @@ Ref<Image> Image::get_image_from_mipmap(int p_mipamp) const {
return image;
}
-void Image::bumpmap_to_normalmap(float bump_scale) {
+void Image::bump_map_to_normal_map(float bump_scale) {
ERR_FAIL_COND(!_can_modify(format));
convert(Image::FORMAT_RF);
@@ -3585,7 +3607,7 @@ Image::Image(const uint8_t *p_mem_png_jpg, int p_len) {
copy_internals_from(_png_mem_loader_func(p_mem_png_jpg, p_len));
}
- if (empty() && _jpg_mem_loader_func) {
+ if (is_empty() && _jpg_mem_loader_func) {
copy_internals_from(_jpg_mem_loader_func(p_mem_png_jpg, p_len));
}
}
diff --git a/core/io/image.h b/core/io/image.h
index 6b4488bd66..df8f9b35a1 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -285,7 +285,7 @@ public:
/**
* returns true when the image is empty (0,0) in size
*/
- bool empty() const;
+ bool is_empty() const;
Vector<uint8_t> get_data() const;
@@ -350,10 +350,10 @@ public:
void fix_alpha_edges();
void premultiply_alpha();
void srgb_to_linear();
- void normalmap_to_xy();
+ void normal_map_to_xy();
Ref<Image> rgbe_to_srgb();
Ref<Image> get_image_from_mipmap(int p_mipamp) const;
- void bumpmap_to_normalmap(float bump_scale = 1.0);
+ void bump_map_to_normal_map(float bump_scale = 1.0);
void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
@@ -390,6 +390,8 @@ public:
void set_pixelv(const Point2i &p_point, const Color &p_color);
void set_pixel(int p_x, int p_y, const Color &p_color);
+ void adjust_bcs(float p_brightness, float p_contrast, float p_saturation);
+
void set_as_black();
void copy_internals_from(const Ref<Image> &p_image) {
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index f6d8668349..7de038e6fe 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -122,7 +122,7 @@ void ImageLoader::cleanup() {
/////////////////
-RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index d5fb4678eb..a5d588e0b5 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -72,7 +72,7 @@ public:
class ResourceFormatLoaderImage : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 9f3540efad..e1d9c19f10 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,13 +40,13 @@ VARIANT_ENUM_CAST(IP::ResolverStatus);
struct _IP_ResolverPrivate {
struct QueueItem {
- volatile IP::ResolverStatus status;
+ SafeNumeric<IP::ResolverStatus> status;
IP_Address response;
String hostname;
IP::Type type;
void clear() {
- status = IP::RESOLVER_STATUS_NONE;
+ status.set(IP::RESOLVER_STATUS_NONE);
response = IP_Address();
type = IP::TYPE_NONE;
hostname = "";
@@ -61,7 +61,7 @@ struct _IP_ResolverPrivate {
IP::ResolverID find_empty_id() const {
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
- if (queue[i].status == IP::RESOLVER_STATUS_NONE) {
+ if (queue[i].status.get() == IP::RESOLVER_STATUS_NONE) {
return i;
}
}
@@ -71,21 +71,21 @@ struct _IP_ResolverPrivate {
Mutex mutex;
Semaphore sem;
- Thread *thread;
+ Thread thread;
//Semaphore* semaphore;
bool thread_abort;
void resolve_queues() {
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
- if (queue[i].status != IP::RESOLVER_STATUS_WAITING) {
+ if (queue[i].status.get() != IP::RESOLVER_STATUS_WAITING) {
continue;
}
queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type);
if (!queue[i].response.is_valid()) {
- queue[i].status = IP::RESOLVER_STATUS_ERROR;
+ queue[i].status.set(IP::RESOLVER_STATUS_ERROR);
} else {
- queue[i].status = IP::RESOLVER_STATUS_DONE;
+ queue[i].status.set(IP::RESOLVER_STATUS_DONE);
}
}
}
@@ -137,11 +137,11 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
resolver->queue[id].type = p_type;
if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
resolver->queue[id].response = resolver->cache[key];
- resolver->queue[id].status = IP::RESOLVER_STATUS_DONE;
+ resolver->queue[id].status.set(IP::RESOLVER_STATUS_DONE);
} else {
resolver->queue[id].response = IP_Address();
- resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING;
- if (resolver->thread) {
+ resolver->queue[id].status.set(IP::RESOLVER_STATUS_WAITING);
+ if (resolver->thread.is_started()) {
resolver->sem.post();
} else {
resolver->resolve_queues();
@@ -156,12 +156,12 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
MutexLock lock(resolver->mutex);
- if (resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE) {
+ if (resolver->queue[p_id].status.get() == IP::RESOLVER_STATUS_NONE) {
ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE");
resolver->mutex.unlock();
return IP::RESOLVER_STATUS_NONE;
}
- return resolver->queue[p_id].status;
+ return resolver->queue[p_id].status.get();
}
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
@@ -169,7 +169,7 @@ IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
MutexLock lock(resolver->mutex);
- if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
+ if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) {
ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
resolver->mutex.unlock();
return IP_Address();
@@ -183,13 +183,13 @@ void IP::erase_resolve_item(ResolverID p_id) {
MutexLock lock(resolver->mutex);
- resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE;
+ resolver->queue[p_id].status.set(IP::RESOLVER_STATUS_NONE);
}
void IP::clear_cache(const String &p_hostname) {
MutexLock lock(resolver->mutex);
- if (p_hostname.empty()) {
+ if (p_hostname.is_empty()) {
resolver->cache.clear();
} else {
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_NONE));
@@ -285,26 +285,14 @@ IP::IP() {
singleton = this;
resolver = memnew(_IP_ResolverPrivate);
-#ifndef NO_THREADS
-
resolver->thread_abort = false;
-
- resolver->thread = Thread::create(_IP_ResolverPrivate::_thread_function, resolver);
-#else
- resolver->thread = nullptr;
-#endif
+ resolver->thread.start(_IP_ResolverPrivate::_thread_function, resolver);
}
IP::~IP() {
-#ifndef NO_THREADS
- if (resolver->thread) {
- resolver->thread_abort = true;
- resolver->sem.post();
- Thread::wait_to_finish(resolver->thread);
- memdelete(resolver->thread);
- }
-
-#endif
+ resolver->thread_abort = true;
+ resolver->sem.post();
+ resolver->thread.wait_to_finish();
memdelete(resolver);
}
diff --git a/core/io/ip.h b/core/io/ip.h
index 32572b8eb2..ae080b8e26 100644
--- a/core/io/ip.h
+++ b/core/io/ip.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp
index 7d730e5ae8..5f98eb69e8 100644
--- a/core/io/ip_address.cpp
+++ b/core/io/ip_address.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/ip_address.h b/core/io/ip_address.h
index 7a813230f5..49bf83d72f 100644
--- a/core/io/ip_address.h
+++ b/core/io/ip_address.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/json.cpp b/core/io/json.cpp
index d61c2b8236..0d9117fdda 100644
--- a/core/io/json.cpp
+++ b/core/io/json.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,7 @@ const char *JSON::tk_name[TK_MAX] = {
static String _make_indent(const String &p_indent, int p_size) {
String indent_text = "";
- if (!p_indent.empty()) {
+ if (!p_indent.is_empty()) {
for (int i = 0; i < p_size; i++) {
indent_text += p_indent;
}
@@ -59,7 +59,7 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
String colon = ":";
String end_statement = "";
- if (!p_indent.empty()) {
+ if (!p_indent.is_empty()) {
colon += " ";
end_statement += "\n";
}
@@ -234,6 +234,52 @@ Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_to
}
index += 4; //will add at the end anyway
+ if ((res & 0xfffffc00) == 0xd800) {
+ if (p_str[index + 1] != '\\' || p_str[index + 2] != 'u') {
+ r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate";
+ return ERR_PARSE_ERROR;
+ }
+ index += 2;
+ char32_t trail = 0;
+ for (int j = 0; j < 4; j++) {
+ char32_t c = p_str[index + j + 1];
+ if (c == 0) {
+ r_err_str = "Unterminated String";
+ return ERR_PARSE_ERROR;
+ }
+ if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
+ r_err_str = "Malformed hex constant in string";
+ return ERR_PARSE_ERROR;
+ }
+ char32_t v;
+ if (c >= '0' && c <= '9') {
+ v = c - '0';
+ } else if (c >= 'a' && c <= 'f') {
+ v = c - 'a';
+ v += 10;
+ } else if (c >= 'A' && c <= 'F') {
+ v = c - 'A';
+ v += 10;
+ } else {
+ ERR_PRINT("Bug parsing hex constant.");
+ v = 0;
+ }
+
+ trail <<= 4;
+ trail |= v;
+ }
+ if ((trail & 0xfffffc00) == 0xdc00) {
+ res = (res << 10UL) + trail - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ index += 4; //will add at the end anyway
+ } else {
+ r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate";
+ return ERR_PARSE_ERROR;
+ }
+ } else if ((res & 0xfffffc00) == 0xdc00) {
+ r_err_str = "Invalid UTF-16 sequence in string, unpaired trail surrogate";
+ return ERR_PARSE_ERROR;
+ }
+
} break;
default: {
res = next;
diff --git a/core/io/json.h b/core/io/json.h
index 431b252e55..537477666e 100644
--- a/core/io/json.h
+++ b/core/io/json.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index 241c72d310..8a07459a1d 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,6 +43,12 @@ bool Logger::should_log(bool p_err) {
return (!p_err || _print_error_enabled) && (p_err || _print_line_enabled);
}
+bool Logger::_flush_stdout_on_print = true;
+
+void Logger::set_flush_stdout_on_print(bool value) {
+ _flush_stdout_on_print = value;
+}
+
void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
if (!should_log(true)) {
return;
@@ -207,7 +213,7 @@ void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) {
Memory::free_static(buf);
}
- if (p_err || GLOBAL_GET("application/run/flush_stdout_on_print")) {
+ if (p_err || _flush_stdout_on_print) {
// Don't always flush when printing stdout to avoid performance
// issues when `print()` is spammed in release builds.
file->flush();
@@ -228,7 +234,7 @@ void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) {
vfprintf(stderr, p_format, p_list);
} else {
vprintf(p_format, p_list);
- if (GLOBAL_GET("application/run/flush_stdout_on_print")) {
+ if (_flush_stdout_on_print) {
// Don't always flush when printing stdout to avoid performance
// issues when `print()` is spammed in release builds.
fflush(stdout);
diff --git a/core/io/logger.h b/core/io/logger.h
index 9eaf506c51..a12945911c 100644
--- a/core/io/logger.h
+++ b/core/io/logger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,6 +41,8 @@ class Logger {
protected:
bool should_log(bool p_err);
+ static bool _flush_stdout_on_print;
+
public:
enum ErrorType {
ERR_ERROR,
@@ -49,6 +51,8 @@ public:
ERR_SHADER
};
+ static void set_flush_stdout_on_print(bool value);
+
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0 = 0;
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index db12fcb7f7..218a612da2 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/marshalls.h b/core/io/marshalls.h
index 6969a9b500..cc0e9ba301 100644
--- a/core/io/marshalls.h
+++ b/core/io/marshalls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index afab00ebd6..6b550e69c8 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index ca52a1c689..7f88b53a27 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/net_socket.cpp b/core/io/net_socket.cpp
index 130a2e245e..b51d26ba83 100644
--- a/core/io/net_socket.cpp
+++ b/core/io/net_socket.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/net_socket.h b/core/io/net_socket.h
index 67d0253985..bc09477693 100644
--- a/core/io/net_socket.h
+++ b/core/io/net_socket.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/networked_multiplayer_peer.cpp b/core/io/networked_multiplayer_peer.cpp
index f521f2bb79..b6af046e77 100644
--- a/core/io/networked_multiplayer_peer.cpp
+++ b/core/io/networked_multiplayer_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/networked_multiplayer_peer.h b/core/io/networked_multiplayer_peer.h
index dc76237f45..7c90f97d88 100644
--- a/core/io/networked_multiplayer_peer.h
+++ b/core/io/networked_multiplayer_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/packed_data_container.cpp b/core/io/packed_data_container.cpp
index fbe8fa8a28..a0b97772e6 100644
--- a/core/io/packed_data_container.cpp
+++ b/core/io/packed_data_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/packed_data_container.h b/core/io/packed_data_container.h
index 3899c14bb4..7791e21bb3 100644
--- a/core/io/packed_data_container.h
+++ b/core/io/packed_data_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index 3da494a8ef..318fd10243 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index a25fa03875..9e03c44750 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/packet_peer_dtls.cpp b/core/io/packet_peer_dtls.cpp
index 9f6fccc993..bac98e20e7 100644
--- a/core/io/packet_peer_dtls.cpp
+++ b/core/io/packet_peer_dtls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/packet_peer_dtls.h b/core/io/packet_peer_dtls.h
index c2ff4e1a7f..31c52f539f 100644
--- a/core/io/packet_peer_dtls.h
+++ b/core/io/packet_peer_dtls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp
index 488cfbeaa8..d8d63d976f 100644
--- a/core/io/packet_peer_udp.cpp
+++ b/core/io/packet_peer_udp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h
index 9a44a1ebea..4bac6994fc 100644
--- a/core/io/packet_peer_udp.h
+++ b/core/io/packet_peer_udp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 5480d3c535..a0697ca18b 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,7 +53,7 @@ void PCKPacker::_bind_methods() {
}
Error PCKPacker::pck_start(const String &p_file, int p_alignment, const String &p_key, bool p_encrypt_directory) {
- ERR_FAIL_COND_V_MSG((p_key.empty() || !p_key.is_valid_hex_number(false) || p_key.length() != 64), ERR_CANT_CREATE, "Invalid Encryption Key (must be 64 characters long).");
+ ERR_FAIL_COND_V_MSG((p_key.is_empty() || !p_key.is_valid_hex_number(false) || p_key.length() != 64), ERR_CANT_CREATE, "Invalid Encryption Key (must be 64 characters long).");
String _key = p_key.to_lower();
key.resize(32);
diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h
index 56be1b52df..dec8f8748d 100644
--- a/core/io/pck_packer.h
+++ b/core/io/pck_packer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 58ab9a8cde..8560e2abc7 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -52,29 +52,29 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
}
if (path_cache != "") {
- ResourceCache::lock->write_lock();
+ ResourceCache::lock.write_lock();
ResourceCache::resources.erase(path_cache);
- ResourceCache::lock->write_unlock();
+ ResourceCache::lock.write_unlock();
}
path_cache = "";
- ResourceCache::lock->read_lock();
+ ResourceCache::lock.read_lock();
bool has_path = ResourceCache::resources.has(p_path);
- ResourceCache::lock->read_unlock();
+ ResourceCache::lock.read_unlock();
if (has_path) {
if (p_take_over) {
- ResourceCache::lock->write_lock();
+ ResourceCache::lock.write_lock();
Resource **res = ResourceCache::resources.getptr(p_path);
if (res) {
(*res)->set_name("");
}
- ResourceCache::lock->write_unlock();
+ ResourceCache::lock.write_unlock();
} else {
- ResourceCache::lock->read_lock();
+ ResourceCache::lock.read_lock();
bool exists = ResourceCache::resources.has(p_path);
- ResourceCache::lock->read_unlock();
+ ResourceCache::lock.read_unlock();
ERR_FAIL_COND_MSG(exists, "Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion).");
}
@@ -82,12 +82,11 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
path_cache = p_path;
if (path_cache != "") {
- ResourceCache::lock->write_lock();
+ ResourceCache::lock.write_lock();
ResourceCache::resources[path_cache] = this;
- ResourceCache::lock->write_unlock();
+ ResourceCache::lock.write_unlock();
}
- _change_notify("resource_path");
_resource_path_changed();
}
@@ -105,7 +104,6 @@ int Resource::get_subindex() const {
void Resource::set_name(const String &p_name) {
name = p_name;
- _change_notify("resource_name");
}
String Resource::get_name() const {
@@ -116,20 +114,18 @@ bool Resource::editor_can_reload_from_file() {
return true; //by default yes
}
-void Resource::reload_from_file() {
- String path = get_path();
- if (!path.is_resource_file()) {
- return;
+void Resource::reset_state() {
+}
+Error Resource::copy_from(const Ref<Resource> &p_resource) {
+ ERR_FAIL_COND_V(p_resource.is_null(), ERR_INVALID_PARAMETER);
+ if (get_class() != p_resource->get_class()) {
+ return ERR_INVALID_PARAMETER;
}
- Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), true);
-
- if (!s.is_valid()) {
- return;
- }
+ reset_state(); //may want to reset state
List<PropertyInfo> pi;
- s->get_property_list(&pi);
+ p_resource->get_property_list(&pi);
for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
@@ -139,8 +135,23 @@ void Resource::reload_from_file() {
continue; //do not change path
}
- set(E->get().name, s->get(E->get().name));
+ set(E->get().name, p_resource->get(E->get().name));
+ }
+ return OK;
+}
+void Resource::reload_from_file() {
+ String path = get_path();
+ if (!path.is_resource_file()) {
+ return;
+ }
+
+ Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE);
+
+ if (!s.is_valid()) {
+ return;
}
+
+ copy_from(s);
}
Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache) {
@@ -315,9 +326,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
return;
}
- if (ResourceCache::lock) {
- ResourceCache::lock->write_lock();
- }
+ ResourceCache::lock.write_lock();
if (p_remapped) {
ResourceLoader::remapped_list.add(&remapped_list);
@@ -325,9 +334,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
ResourceLoader::remapped_list.remove(&remapped_list);
}
- if (ResourceCache::lock) {
- ResourceCache::lock->write_unlock();
- }
+ ResourceCache::lock.write_unlock();
}
bool Resource::is_translation_remapped() const {
@@ -338,38 +345,24 @@ bool Resource::is_translation_remapped() const {
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored
void Resource::set_id_for_path(const String &p_path, int p_id) {
if (p_id == -1) {
- if (ResourceCache::path_cache_lock) {
- ResourceCache::path_cache_lock->write_lock();
- }
+ ResourceCache::path_cache_lock.write_lock();
ResourceCache::resource_path_cache[p_path].erase(get_path());
- if (ResourceCache::path_cache_lock) {
- ResourceCache::path_cache_lock->write_unlock();
- }
+ ResourceCache::path_cache_lock.write_unlock();
} else {
- if (ResourceCache::path_cache_lock) {
- ResourceCache::path_cache_lock->write_lock();
- }
+ ResourceCache::path_cache_lock.write_lock();
ResourceCache::resource_path_cache[p_path][get_path()] = p_id;
- if (ResourceCache::path_cache_lock) {
- ResourceCache::path_cache_lock->write_unlock();
- }
+ ResourceCache::path_cache_lock.write_unlock();
}
}
int Resource::get_id_for_path(const String &p_path) const {
- if (ResourceCache::path_cache_lock) {
- ResourceCache::path_cache_lock->read_lock();
- }
+ ResourceCache::path_cache_lock.read_lock();
if (ResourceCache::resource_path_cache[p_path].has(get_path())) {
int result = ResourceCache::resource_path_cache[p_path][get_path()];
- if (ResourceCache::path_cache_lock) {
- ResourceCache::path_cache_lock->read_unlock();
- }
+ ResourceCache::path_cache_lock.read_unlock();
return result;
} else {
- if (ResourceCache::path_cache_lock) {
- ResourceCache::path_cache_lock->read_unlock();
- }
+ ResourceCache::path_cache_lock.read_unlock();
return -1;
}
}
@@ -386,6 +379,7 @@ void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_local_to_scene"), &Resource::is_local_to_scene);
ClassDB::bind_method(D_METHOD("get_local_scene"), &Resource::get_local_scene);
ClassDB::bind_method(D_METHOD("setup_local_to_scene"), &Resource::setup_local_to_scene);
+ ClassDB::bind_method(D_METHOD("emit_changed"), &Resource::emit_changed);
ClassDB::bind_method(D_METHOD("duplicate", "subresources"), &Resource::duplicate, DEFVAL(false));
ADD_SIGNAL(MethodInfo("changed"));
@@ -402,9 +396,9 @@ Resource::Resource() :
Resource::~Resource() {
if (path_cache != "") {
- ResourceCache::lock->write_lock();
+ ResourceCache::lock.write_lock();
ResourceCache::resources.erase(path_cache);
- ResourceCache::lock->write_unlock();
+ ResourceCache::lock.write_unlock();
}
if (owners.size()) {
WARN_PRINT("Resource is still owned.");
@@ -416,18 +410,11 @@ HashMap<String, Resource *> ResourceCache::resources;
HashMap<String, HashMap<String, int>> ResourceCache::resource_path_cache;
#endif
-RWLock *ResourceCache::lock = nullptr;
+RWLock ResourceCache::lock;
#ifdef TOOLS_ENABLED
-RWLock *ResourceCache::path_cache_lock = nullptr;
+RWLock ResourceCache::path_cache_lock;
#endif
-void ResourceCache::setup() {
- lock = RWLock::create();
-#ifdef TOOLS_ENABLED
- path_cache_lock = RWLock::create();
-#endif
-}
-
void ResourceCache::clear() {
if (resources.size()) {
ERR_PRINT("Resources still in use at exit (run with --verbose for details).");
@@ -441,29 +428,25 @@ void ResourceCache::clear() {
}
resources.clear();
- memdelete(lock);
-#ifdef TOOLS_ENABLED
- memdelete(path_cache_lock);
-#endif
}
void ResourceCache::reload_externals() {
}
bool ResourceCache::has(const String &p_path) {
- lock->read_lock();
+ lock.read_lock();
bool b = resources.has(p_path);
- lock->read_unlock();
+ lock.read_unlock();
return b;
}
Resource *ResourceCache::get(const String &p_path) {
- lock->read_lock();
+ lock.read_lock();
Resource **res = resources.getptr(p_path);
- lock->read_unlock();
+ lock.read_unlock();
if (!res) {
return nullptr;
@@ -473,26 +456,26 @@ Resource *ResourceCache::get(const String &p_path) {
}
void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) {
- lock->read_lock();
+ lock.read_lock();
const String *K = nullptr;
while ((K = resources.next(K))) {
Resource *r = resources[*K];
p_resources->push_back(Ref<Resource>(r));
}
- lock->read_unlock();
+ lock.read_unlock();
}
int ResourceCache::get_cached_resource_count() {
- lock->read_lock();
+ lock.read_lock();
int rc = resources.size();
- lock->read_unlock();
+ lock.read_unlock();
return rc;
}
void ResourceCache::dump(const char *p_file, bool p_short) {
#ifdef DEBUG_ENABLED
- lock->read_lock();
+ lock.read_lock();
Map<String, int> type_count;
@@ -529,6 +512,6 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
memdelete(f);
}
- lock->read_unlock();
+ lock.read_unlock();
#endif
}
diff --git a/core/io/resource.h b/core/io/resource.h
index 6e0bd7d7f4..ae18ac0c8a 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -90,6 +90,8 @@ public:
static Node *(*_get_local_scene_func)(); //used by editor
virtual bool editor_can_reload_from_file();
+ virtual void reset_state(); //for resources that use variable amount of properties, either via _validate_property or _get_property_list, this function needs to be implemented to correctly clear state
+ virtual Error copy_from(const Ref<Resource> &p_resource);
virtual void reload_from_file();
void register_owner(Object *p_owner);
@@ -149,16 +151,15 @@ typedef Ref<Resource> RES;
class ResourceCache {
friend class Resource;
friend class ResourceLoader; //need the lock
- static RWLock *lock;
+ static RWLock lock;
static HashMap<String, Resource *> resources;
#ifdef TOOLS_ENABLED
static HashMap<String, HashMap<String, int>> resource_path_cache; // each tscn has a set of resource paths and IDs
- static RWLock *path_cache_lock;
+ static RWLock path_cache_lock;
#endif // TOOLS_ENABLED
friend void unregister_core_types();
static void clear();
friend void register_core_types();
- static void setup();
public:
static void reload_externals();
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index aeb859aabd..fb6ad7d65e 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -261,11 +261,11 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
case VARIANT_COLOR: {
- Color v;
- v.r = f->get_real();
- v.g = f->get_real();
- v.b = f->get_real();
- v.a = f->get_real();
+ Color v; // Colors should always be in single-precision.
+ v.r = f->get_float();
+ v.g = f->get_float();
+ v.b = f->get_float();
+ v.a = f->get_float();
r_v = v;
} break;
@@ -313,17 +313,12 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
uint32_t index = f->get_32();
String path = res_path + "::" + itos(index);
- if (use_nocache) {
- if (!internal_index_cache.has(path)) {
- WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data());
- }
- r_v = internal_index_cache[path];
+ //always use internal cache for loading internal resources
+ if (!internal_index_cache.has(path)) {
+ WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data());
+ r_v = Variant();
} else {
- RES res = ResourceLoader::load(path);
- if (res.is_null()) {
- WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
- }
- r_v = res;
+ r_v = internal_index_cache[path];
}
} break;
@@ -645,7 +640,7 @@ Error ResourceLoaderBinary::load() {
}
} else {
- Error err = ResourceLoader::load_threaded_request(path, external_resources[i].type, use_sub_threads, local_path);
+ Error err = ResourceLoader::load_threaded_request(path, external_resources[i].type, use_sub_threads, ResourceFormatLoader::CACHE_MODE_REUSE, local_path);
if (err != OK) {
if (!ResourceLoader::get_abort_on_missing_resources()) {
ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type);
@@ -675,7 +670,7 @@ Error ResourceLoaderBinary::load() {
path = res_path + "::" + path;
}
- if (!use_nocache) {
+ if (cache_mode == ResourceFormatLoader::CACHE_MODE_REUSE) {
if (ResourceCache::has(path)) {
//already loaded, don't do anything
stage++;
@@ -684,7 +679,7 @@ Error ResourceLoaderBinary::load() {
}
}
} else {
- if (!use_nocache && !ResourceCache::has(res_path)) {
+ if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && !ResourceCache::has(res_path)) {
path = res_path;
}
}
@@ -695,26 +690,40 @@ Error ResourceLoaderBinary::load() {
String t = get_unicode_string();
- Object *obj = ClassDB::instance(t);
- if (!obj) {
- error = ERR_FILE_CORRUPT;
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + ".");
- }
+ RES res;
- Resource *r = Object::cast_to<Resource>(obj);
- if (!r) {
- String obj_class = obj->get_class();
- error = ERR_FILE_CORRUPT;
- memdelete(obj); //bye
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + ".");
+ if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) {
+ //use the existing one
+ Resource *r = ResourceCache::get(path);
+ if (r->get_class() == t) {
+ r->reset_state();
+ res = Ref<Resource>(r);
+ }
}
- RES res = RES(r);
+ if (res.is_null()) {
+ //did not replace
- if (path != String()) {
- r->set_path(path);
+ Object *obj = ClassDB::instance(t);
+ if (!obj) {
+ error = ERR_FILE_CORRUPT;
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + ".");
+ }
+
+ Resource *r = Object::cast_to<Resource>(obj);
+ if (!r) {
+ String obj_class = obj->get_class();
+ error = ERR_FILE_CORRUPT;
+ memdelete(obj); //bye
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + ".");
+ }
+
+ res = RES(r);
+ if (path != String() && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
+ r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); //if got here because the resource with same path has different type, replace it
+ }
+ r->set_subindex(subindex);
}
- r->set_subindex(subindex);
if (!main) {
internal_index_cache[path] = res;
@@ -961,7 +970,7 @@ ResourceLoaderBinary::~ResourceLoaderBinary() {
}
}
-RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
@@ -972,7 +981,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'.");
ResourceLoaderBinary loader;
- loader.use_nocache = p_no_cache;
+ loader.cache_mode = p_cache_mode;
loader.use_sub_threads = p_use_sub_threads;
loader.progress = r_progress;
String path = p_original_path != "" ? p_original_path : p_path;
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index 54cddca49e..3592bbdbc4 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,7 +78,7 @@ class ResourceLoaderBinary {
Map<String, String> remaps;
Error error = OK;
- bool use_nocache = false;
+ ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
friend class ResourceFormatLoaderBinary;
@@ -103,7 +103,7 @@ public:
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index 9b14d2c763..5ca0eb884a 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -116,7 +116,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
return OK;
}
-RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);
@@ -128,7 +128,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_
return RES();
}
- RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_no_cache, r_error, p_use_sub_threads, r_progress);
+ RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_cache_mode, r_error, p_use_sub_threads, r_progress);
#ifdef TOOLS_ENABLED
if (res.is_valid()) {
@@ -352,6 +352,12 @@ void ResourceFormatImporter::get_importers_for_extension(const String &p_extensi
}
}
+void ResourceFormatImporter::get_importers(List<Ref<ResourceImporter>> *r_importers) {
+ for (int i = 0; i < importers.size(); i++) {
+ r_importers->push_back(importers[i]);
+ }
+}
+
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const {
Ref<ResourceImporter> importer;
float priority = 0;
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index 1b300bf656..91efec5534 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,7 +57,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
public:
static ResourceFormatImporter *get_singleton() { return singleton; }
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
@@ -82,6 +82,7 @@ public:
Ref<ResourceImporter> get_importer_by_name(const String &p_name) const;
Ref<ResourceImporter> get_importer_by_extension(const String &p_extension) const;
void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter>> *r_importers);
+ void get_importers(List<Ref<ResourceImporter>> *r_importers);
bool are_import_settings_valid(const String &p_path) const;
String get_import_settings_hash() const;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index a8ca6a817e..8275dd0ad4 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -113,9 +113,9 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions)
}
}
-RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (get_script_instance() && get_script_instance()->has_method("load")) {
- Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads);
+ Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads, p_cache_mode);
if (res.get_type() == Variant::INT) {
if (r_error) {
@@ -164,7 +164,7 @@ Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map<
void ResourceFormatLoader::_bind_methods() {
{
- MethodInfo info = MethodInfo(Variant::NIL, "load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path"));
+ MethodInfo info = MethodInfo(Variant::NIL, "load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path"), PropertyInfo(Variant::BOOL, "use_sub_threads"), PropertyInfo(Variant::INT, "cache_mode"));
info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
ClassDB::add_virtual_method(get_class_static(), info);
}
@@ -174,11 +174,15 @@ void ResourceFormatLoader::_bind_methods() {
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_resource_type", PropertyInfo(Variant::STRING, "path")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("get_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "add_types")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "rename_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "renames")));
+
+ BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE);
+ BIND_ENUM_CONSTANT(CACHE_MODE_REUSE);
+ BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE);
}
///////////////////////////////////
-RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress) {
bool found = false;
// Try all loaders and pick the first match for the type hint
@@ -187,7 +191,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
continue;
}
found = true;
- RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_no_cache);
+ RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode);
if (res.is_null()) {
continue;
}
@@ -214,7 +218,7 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
//this is an actual thread, so wait for Ok fom semaphore
thread_load_semaphore->wait(); //wait until its ok to start loading
}
- load_task.resource = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, false, &load_task.error, load_task.use_sub_threads, &load_task.progress);
+ load_task.resource = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, load_task.cache_mode, &load_task.error, load_task.use_sub_threads, &load_task.progress);
load_task.progress = 1.0; //it was fully loaded at this point, so force progress to 1.0
@@ -267,7 +271,7 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
thread_load_mutex->unlock();
}
-Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, const String &p_source_resource) {
+Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, ResourceFormatLoader::CacheMode p_cache_mode, const String &p_source_resource) {
String local_path;
if (p_path.is_rel_path()) {
local_path = "res://" + p_path;
@@ -314,6 +318,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
load_task.remapped_path = _path_remap(local_path, &load_task.xl_remapped);
load_task.local_path = local_path;
load_task.type_hint = p_type_hint;
+ load_task.cache_mode = p_cache_mode;
load_task.use_sub_threads = p_use_sub_threads;
{ //must check if resource is already loaded before attempting to load it in a thread
@@ -323,9 +328,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Attempted to load a resource already being loaded from this thread, cyclic reference?");
}
//lock first if possible
- if (ResourceCache::lock) {
- ResourceCache::lock->read_lock();
- }
+ ResourceCache::lock.read_lock();
//get ptr
Resource **rptr = ResourceCache::resources.getptr(local_path);
@@ -340,9 +343,7 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
load_task.progress = 1.0;
}
}
- if (ResourceCache::lock) {
- ResourceCache::lock->read_unlock();
- }
+ ResourceCache::lock.read_unlock();
}
if (p_source_resource != String()) {
@@ -366,7 +367,8 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
print_lt("REQUEST: load count: " + itos(thread_loading_count) + " / wait count: " + itos(thread_waiting_count) + " / suspended count: " + itos(thread_suspended_count) + " / active: " + itos(thread_loading_count - thread_suspended_count));
- load_task.thread = Thread::create(_thread_load_function, &thread_load_tasks[local_path]);
+ load_task.thread = memnew(Thread);
+ load_task.thread->start(_thread_load_function, &thread_load_tasks[local_path]);
load_task.loader_id = load_task.thread->get_id();
}
@@ -493,7 +495,7 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) {
if (load_task.requests == 0) {
if (load_task.thread) { //thread may not have been used
- Thread::wait_to_finish(load_task.thread);
+ load_task.thread->wait_to_finish();
memdelete(load_task.thread);
}
thread_load_tasks.erase(local_path);
@@ -504,7 +506,7 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) {
return resource;
}
-RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
+RES ResourceLoader::load(const String &p_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
@@ -516,7 +518,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
}
- if (!p_no_cache) {
+ if (p_cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
thread_load_mutex->lock();
//Is it already being loaded? poll until done
@@ -535,9 +537,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
}
//Is it cached?
- if (ResourceCache::lock) {
- ResourceCache::lock->read_lock();
- }
+ ResourceCache::lock.read_lock();
Resource **rptr = ResourceCache::resources.getptr(local_path);
@@ -546,9 +546,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
//it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
if (res.is_valid()) {
- if (ResourceCache::lock) {
- ResourceCache::lock->read_unlock();
- }
+ ResourceCache::lock.read_unlock();
thread_load_mutex->unlock();
if (r_error) {
@@ -559,9 +557,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
}
}
- if (ResourceCache::lock) {
- ResourceCache::lock->read_unlock();
- }
+ ResourceCache::lock.read_unlock();
//load using task (but this thread)
ThreadLoadTask load_task;
@@ -570,6 +566,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
load_task.local_path = local_path;
load_task.remapped_path = _path_remap(local_path, &load_task.xl_remapped);
load_task.type_hint = p_type_hint;
+ load_task.cache_mode = p_cache_mode; //ignore
load_task.loader_id = Thread::get_caller_id();
thread_load_tasks[local_path] = load_task;
@@ -590,7 +587,7 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
print_verbose("Loading resource: " + path);
float p;
- RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error, false, &p);
+ RES res = _load(path, local_path, p_type_hint, p_cache_mode, r_error, false, &p);
if (res.is_null()) {
print_verbose("Failed loading resource: " + path);
@@ -955,9 +952,7 @@ String ResourceLoader::path_remap(const String &p_path) {
}
void ResourceLoader::reload_translation_remaps() {
- if (ResourceCache::lock) {
- ResourceCache::lock->read_lock();
- }
+ ResourceCache::lock.read_lock();
List<Resource *> to_reload;
SelfList<Resource> *E = remapped_list.first();
@@ -967,9 +962,7 @@ void ResourceLoader::reload_translation_remaps() {
E = E->next();
}
- if (ResourceCache::lock) {
- ResourceCache::lock->read_unlock();
- }
+ ResourceCache::lock.read_unlock();
//now just make sure to not delete any of these resources while changing locale..
while (to_reload.front()) {
@@ -979,11 +972,11 @@ void ResourceLoader::reload_translation_remaps() {
}
void ResourceLoader::load_translation_remaps() {
- if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
+ if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) {
return;
}
- Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
+ Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps");
List<Variant> keys;
remaps.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 02c668f214..914d988caa 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,11 +38,18 @@
class ResourceFormatLoader : public Reference {
GDCLASS(ResourceFormatLoader, Reference);
+public:
+ enum CacheMode {
+ CACHE_MODE_IGNORE, //resource and subresources do not use path cache, no path is set into resource.
+ CACHE_MODE_REUSE, //resource and subresources use patch cache, reuse existing loaded resources instead of loading from disk when available
+ CACHE_MODE_REPLACE, //resource and and subresource use path cache, but replace existing loaded resources when available with information from disk
+ };
+
protected:
static void _bind_methods();
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual bool exists(const String &p_path) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
@@ -59,6 +66,8 @@ public:
virtual ~ResourceFormatLoader() {}
};
+VARIANT_ENUM_CAST(ResourceFormatLoader::CacheMode)
+
typedef void (*ResourceLoadErrorNotify)(void *p_ud, const String &p_text);
typedef void (*DependencyErrorNotify)(void *p_ud, const String &p_loading, const String &p_which, const String &p_type);
@@ -99,7 +108,7 @@ private:
friend class ResourceFormatImporter;
friend class ResourceInteractiveLoader;
//internal load function
- static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress);
+ static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress);
static ResourceLoadedCallback _loaded_callback;
@@ -114,6 +123,7 @@ private:
String type_hint;
float progress = 0.0;
ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS;
+ ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
Error error = OK;
RES resource;
bool xl_remapped = false;
@@ -136,11 +146,11 @@ private:
static float _dependency_get_progress(const String &p_path);
public:
- static Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, const String &p_source_resource = String());
+ static Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, const String &p_source_resource = String());
static ThreadLoadStatus load_threaded_get_status(const String &p_path, float *r_progress = nullptr);
static RES load_threaded_get(const String &p_path, Error *r_error = nullptr);
- static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = nullptr);
+ static RES load(const String &p_path, const String &p_type_hint = "", ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, Error *r_error = nullptr);
static bool exists(const String &p_path, const String &p_type_hint = "");
static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions);
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 6ded27d82f..7ebc7f34b3 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index c724c4a6e5..2c9e8f1aa3 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index 403f61bb24..8407d55196 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h
index 8c1e918dd8..dadedbd2dc 100644
--- a/core/io/stream_peer.h
+++ b/core/io/stream_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index daf36a5350..6f5a06474c 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index 81b95b856d..1df9ced08c 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp
index aa9c409528..760710a9eb 100644
--- a/core/io/stream_peer_tcp.cpp
+++ b/core/io/stream_peer_tcp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h
index 173f92e2b6..10b90908d4 100644
--- a/core/io/stream_peer_tcp.h
+++ b/core/io/stream_peer_tcp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp
index d7061b6bf4..323d2bbd7f 100644
--- a/core/io/tcp_server.cpp
+++ b/core/io/tcp_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h
index eb715a745c..f06ddd2d99 100644
--- a/core/io/tcp_server.h
+++ b/core/io/tcp_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 34cccca540..0e11ff514a 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -70,7 +70,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
is_eof = f->eof_reached();
// If we reached last line and it's not a content line, break, otherwise let processing that last loop
- if (is_eof && l.empty()) {
+ if (is_eof && l.is_empty()) {
if (status == STATUS_READING_ID || status == STATUS_READING_CONTEXT || (status == STATUS_READING_PLURAL && plural_index != plural_forms - 1)) {
memdelete(f);
ERR_FAIL_V_MSG(RES(), "Unexpected EOF while reading PO file at: " + path + ":" + itos(line));
@@ -277,7 +277,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
return translation;
}
-RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h
index 16c9f1e680..36d33fcac3 100644
--- a/core/io/translation_loader_po.h
+++ b/core/io/translation_loader_po.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,7 @@
class TranslationLoaderPO : public ResourceFormatLoader {
public:
static RES load_translation(FileAccess *f, Error *r_error = nullptr);
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/io/udp_server.cpp b/core/io/udp_server.cpp
index acd15aadc6..f56fb431ef 100644
--- a/core/io/udp_server.cpp
+++ b/core/io/udp_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/udp_server.h b/core/io/udp_server.h
index 3175b09b19..bbd2f951c9 100644
--- a/core/io/udp_server.h
+++ b/core/io/udp_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 85143c0f04..1574634aad 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,63 +36,6 @@
VARIANT_ENUM_CAST(XMLParser::NodeType);
-static bool _equalsn(const char32_t *str1, const char32_t *str2, int len) {
- int i;
- for (i = 0; i < len && str1[i] && str2[i]; ++i) {
- if (str1[i] != str2[i]) {
- return false;
- }
- }
-
- // if one (or both) of the strings was smaller then they
- // are only equal if they have the same length
- return (i == len) || (str1[i] == 0 && str2[i] == 0);
-}
-
-String XMLParser::_replace_special_characters(const String &origstr) {
- int pos = origstr.find("&");
- int oldPos = 0;
-
- if (pos == -1) {
- return origstr;
- }
-
- String newstr;
-
- while (pos != -1 && pos < origstr.length() - 2) {
- // check if it is one of the special characters
-
- int specialChar = -1;
- for (int i = 0; i < (int)special_characters.size(); ++i) {
- const char32_t *p = &origstr[pos] + 1;
-
- if (_equalsn(&special_characters[i][1], p, special_characters[i].length() - 1)) {
- specialChar = i;
- break;
- }
- }
-
- if (specialChar != -1) {
- newstr += (origstr.substr(oldPos, pos - oldPos));
- newstr += (special_characters[specialChar][0]);
- pos += special_characters[specialChar].length();
- } else {
- newstr += (origstr.substr(oldPos, pos - oldPos + 1));
- pos += 1;
- }
-
- // find next &
- oldPos = pos;
- pos = origstr.find("&", pos);
- }
-
- if (oldPos < origstr.length() - 1) {
- newstr += (origstr.substr(oldPos, origstr.length() - oldPos));
- }
-
- return newstr;
-}
-
static inline bool _is_white_space(char c) {
return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
}
@@ -116,7 +59,7 @@ bool XMLParser::_set_text(char *start, char *end) {
// set current text to the parsed text, and replace xml special characters
String s = String::utf8(start, (int)(end - start));
- node_name = _replace_special_characters(s);
+ node_name = s.xml_unescape();
// current XML node type is text
node_type = NODE_TEXT;
@@ -292,7 +235,7 @@ void XMLParser::_parse_opening_xml_element() {
String s = String::utf8(attributeValueBegin,
(int)(attributeValueEnd - attributeValueBegin));
- attr.value = _replace_special_characters(s);
+ attr.value = s.xml_unescape();
attributes.push_back(attr);
} else {
// tag is closed directly
@@ -555,11 +498,6 @@ int XMLParser::get_current_line() const {
}
XMLParser::XMLParser() {
- special_characters.push_back("&amp;");
- special_characters.push_back("<lt;");
- special_characters.push_back(">gt;");
- special_characters.push_back("\"quot;");
- special_characters.push_back("'apos;");
}
XMLParser::~XMLParser() {
diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h
index d8cc26b4c1..847edf958d 100644
--- a/core/io/xml_parser.h
+++ b/core/io/xml_parser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -68,8 +68,6 @@ private:
char *data = nullptr;
char *P = nullptr;
uint64_t length = 0;
- void unescape(String &p_str);
- Vector<String> special_characters;
String node_name;
bool node_empty = false;
NodeType node_type = NODE_NONE;
diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp
index b8e7fd34d0..4b4a46e198 100644
--- a/core/io/zip_io.cpp
+++ b/core/io/zip_io.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/io/zip_io.h b/core/io/zip_io.h
index ba2065b5d1..52691c65e9 100644
--- a/core/io/zip_io.h
+++ b/core/io/zip_io.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index b4410acf7d..88e11a630c 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,7 +35,7 @@
#include "scene/scene_string_names.h"
int AStar::get_available_point_id() const {
- if (points.empty()) {
+ if (points.is_empty()) {
return 1;
}
@@ -341,7 +341,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
begin_point->f_score = _estimate_cost(begin_point->id, end_point->id);
open_list.push_back(begin_point);
- while (!open_list.empty()) {
+ while (!open_list.is_empty()) {
Point *p = open_list[0]; // The currently processed point
if (p == end_point) {
@@ -805,7 +805,7 @@ bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
begin_point->f_score = _estimate_cost(begin_point->id, end_point->id);
open_list.push_back(begin_point);
- while (!open_list.empty()) {
+ while (!open_list.is_empty()) {
AStar::Point *p = open_list[0]; // The currently processed point
if (p == end_point) {
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 7cfa73f2c2..4c61abd91c 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index 08673d0dd1..2c721997d8 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 24908ae59d..e16246902a 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -107,8 +107,8 @@ public:
Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
Variant intersects_ray_bind(const Vector3 &p_from, const Vector3 &p_dir) const;
- _FORCE_INLINE_ void quantize(float p_unit);
- _FORCE_INLINE_ AABB quantized(float p_unit) const;
+ _FORCE_INLINE_ void quantize(real_t p_unit);
+ _FORCE_INLINE_ AABB quantized(real_t p_unit) const;
_FORCE_INLINE_ void set_end(const Vector3 &p_end) {
size = p_end - position;
@@ -430,7 +430,7 @@ void AABB::grow_by(real_t p_amount) {
size.z += 2.0 * p_amount;
}
-void AABB::quantize(float p_unit) {
+void AABB::quantize(real_t p_unit) {
size += position;
position.x -= Math::fposmodp(position.x, p_unit);
@@ -448,7 +448,7 @@ void AABB::quantize(float p_unit) {
size -= position;
}
-AABB AABB::quantized(float p_unit) const {
+AABB AABB::quantized(real_t p_unit) const {
AABB ret = *this;
ret.quantize(p_unit);
return ret;
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index 43d4a63cd3..a5616b8d79 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,6 +47,9 @@ static inline float undenormalise(volatile float f) {
return (v.i & 0x7f800000) < 0x08000000 ? 0.0f : f;
}
+static const float AUDIO_PEAK_OFFSET = 0.0000000001f;
+static const float AUDIO_MIN_PEAK_DB = -200.0f; // linear2db(AUDIO_PEAK_OFFSET)
+
struct AudioFrame {
//left and right samples
float l, r;
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index a64f29517d..cbdd8a8c9f 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -790,8 +790,8 @@ Quat Basis::get_quat() const {
temp[2] = ((m.elements[1][0] - m.elements[0][1]) * s);
} else {
int i = m.elements[0][0] < m.elements[1][1] ?
- (m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
- (m.elements[0][0] < m.elements[2][2] ? 2 : 0);
+ (m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
+ (m.elements[0][0] < m.elements[2][2] ? 2 : 0);
int j = (i + 1) % 3;
int k = (i + 2) % 3;
diff --git a/core/math/basis.h b/core/math/basis.h
index 4cb3d55200..56f6227313 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index f29cb7a269..1066cf5e30 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -74,13 +74,22 @@ Plane CameraMatrix::xform4(const Plane &p_vec4) const {
return ret;
}
+void CameraMatrix::adjust_perspective_znear(real_t p_new_znear) {
+ real_t zfar = get_z_far();
+ real_t znear = p_new_znear;
+
+ real_t deltaZ = zfar - znear;
+ matrix[2][2] = -(zfar + znear) / deltaZ;
+ matrix[3][2] = -2 * znear * zfar / deltaZ;
+}
+
void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) {
if (p_flip_fov) {
p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect);
}
real_t sine, cotangent, deltaZ;
- real_t radians = p_fovy_degrees / 2.0 * Math_PI / 180.0;
+ real_t radians = Math::deg2rad(p_fovy_degrees / 2.0);
deltaZ = p_z_far - p_z_near;
sine = Math::sin(radians);
@@ -107,7 +116,7 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_
real_t left, right, modeltranslation, ymax, xmax, frustumshift;
- ymax = p_z_near * tan(p_fovy_degrees * Math_PI / 360.0f);
+ ymax = p_z_near * tan(Math::deg2rad(p_fovy_degrees / 2.0));
xmax = ymax * p_aspect;
frustumshift = (p_intraocular_dist / 2.0) * p_z_near / p_convergence_dist;
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index f856a7b1bf..3f327d3bc4 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,6 +59,7 @@ struct CameraMatrix {
void set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov = false);
void set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far);
void set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov = false);
+ void adjust_perspective_znear(real_t p_new_znear);
static real_t get_fovy(real_t p_fovx, real_t p_aspect) {
return Math::rad2deg(Math::atan(p_aspect * Math::tan(Math::deg2rad(p_fovx) * 0.5)) * 2.0);
diff --git a/core/math/color.cpp b/core/math/color.cpp
index 2afe14bd63..8affb07e8c 100644
--- a/core/math/color.cpp
+++ b/core/math/color.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -355,6 +355,23 @@ bool Color::html_is_valid(const String &p_color) {
}
Color Color::named(const String &p_name) {
+ int idx = find_named_color(p_name);
+ if (idx == -1) {
+ ERR_FAIL_V_MSG(Color(), "Invalid color name: " + p_name + ".");
+ return Color();
+ }
+ return get_named_color(idx);
+}
+
+Color Color::named(const String &p_name, const Color &p_default) {
+ int idx = find_named_color(p_name);
+ if (idx == -1) {
+ return p_default;
+ }
+ return get_named_color(idx);
+}
+
+int Color::find_named_color(const String &p_name) {
String name = p_name;
// Normalize name
name = name.replace(" ", "");
@@ -367,14 +384,12 @@ Color Color::named(const String &p_name) {
int idx = 0;
while (named_colors[idx].name != nullptr) {
if (name == named_colors[idx].name) {
- return named_colors[idx].color;
+ return idx;
}
idx++;
}
- ERR_FAIL_V_MSG(Color(), "Invalid color name: " + p_name + ".");
-
- return Color();
+ return -1;
}
int Color::get_named_color_count() {
@@ -384,13 +399,25 @@ int Color::get_named_color_count() {
}
return idx;
}
+
String Color::get_named_color_name(int p_idx) {
return named_colors[p_idx].name;
}
+
Color Color::get_named_color(int p_idx) {
return named_colors[p_idx].color;
}
+// For a version that errors on invalid values instead of returning
+// a default color, use the Color(String) constructor instead.
+Color Color::from_string(const String &p_string, const Color &p_default) {
+ if (html_is_valid(p_string)) {
+ return html(p_string);
+ } else {
+ return named(p_string, p_default);
+ }
+}
+
String _to_hex(float p_val) {
int v = Math::round(p_val * 255);
v = CLAMP(v, 0, 255);
@@ -425,56 +452,9 @@ String Color::to_html(bool p_alpha) const {
}
Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
- p_h = Math::fmod(p_h * 360.0f, 360.0f);
- if (p_h < 0.0) {
- p_h += 360.0f;
- }
-
- const float h_ = p_h / 60.0f;
- const float c = p_v * p_s;
- const float x = c * (1.0f - Math::abs(Math::fmod(h_, 2.0f) - 1.0f));
- float r, g, b;
-
- switch ((int)h_) {
- case 0: {
- r = c;
- g = x;
- b = 0;
- } break;
- case 1: {
- r = x;
- g = c;
- b = 0;
- } break;
- case 2: {
- r = 0;
- g = c;
- b = x;
- } break;
- case 3: {
- r = 0;
- g = x;
- b = c;
- } break;
- case 4: {
- r = x;
- g = 0;
- b = c;
- } break;
- case 5: {
- r = c;
- g = 0;
- b = x;
- } break;
- default: {
- r = 0;
- g = 0;
- b = 0;
- } break;
- }
-
- const float m = p_v - c;
- return Color(m + r, m + g, m + b, p_a);
+ Color c;
+ c.set_hsv(p_h, p_s, p_v, p_a);
+ return c;
}
Color::operator String() const {
@@ -519,12 +499,12 @@ Color Color::operator*(const Color &p_color) const {
a * p_color.a);
}
-Color Color::operator*(real_t p_rvalue) const {
+Color Color::operator*(float p_scalar) const {
return Color(
- r * p_rvalue,
- g * p_rvalue,
- b * p_rvalue,
- a * p_rvalue);
+ r * p_scalar,
+ g * p_scalar,
+ b * p_scalar,
+ a * p_scalar);
}
void Color::operator*=(const Color &p_color) {
@@ -534,11 +514,11 @@ void Color::operator*=(const Color &p_color) {
a = a * p_color.a;
}
-void Color::operator*=(real_t p_rvalue) {
- r = r * p_rvalue;
- g = g * p_rvalue;
- b = b * p_rvalue;
- a = a * p_rvalue;
+void Color::operator*=(float p_scalar) {
+ r = r * p_scalar;
+ g = g * p_scalar;
+ b = b * p_scalar;
+ a = a * p_scalar;
}
Color Color::operator/(const Color &p_color) const {
@@ -549,12 +529,12 @@ Color Color::operator/(const Color &p_color) const {
a / p_color.a);
}
-Color Color::operator/(real_t p_rvalue) const {
+Color Color::operator/(float p_scalar) const {
return Color(
- r / p_rvalue,
- g / p_rvalue,
- b / p_rvalue,
- a / p_rvalue);
+ r / p_scalar,
+ g / p_scalar,
+ b / p_scalar,
+ a / p_scalar);
}
void Color::operator/=(const Color &p_color) {
@@ -564,18 +544,11 @@ void Color::operator/=(const Color &p_color) {
a = a / p_color.a;
}
-void Color::operator/=(real_t p_rvalue) {
- if (p_rvalue == 0) {
- r = 1.0;
- g = 1.0;
- b = 1.0;
- a = 1.0;
- } else {
- r = r / p_rvalue;
- g = g / p_rvalue;
- b = b / p_rvalue;
- a = a / p_rvalue;
- }
+void Color::operator/=(float p_scalar) {
+ r = r / p_scalar;
+ g = g / p_scalar;
+ b = b / p_scalar;
+ a = a / p_scalar;
}
Color Color::operator-() const {
diff --git a/core/math/color.h b/core/math/color.h
index b928ff8592..5eb8b1119a 100644
--- a/core/math/color.h
+++ b/core/math/color.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,14 +78,14 @@ struct Color {
void operator-=(const Color &p_color);
Color operator*(const Color &p_color) const;
- Color operator*(real_t p_rvalue) const;
+ Color operator*(float p_scalar) const;
void operator*=(const Color &p_color);
- void operator*=(real_t p_rvalue);
+ void operator*=(float p_scalar);
Color operator/(const Color &p_color) const;
- Color operator/(real_t p_rvalue) const;
+ Color operator/(float p_scalar) const;
void operator/=(const Color &p_color);
- void operator/=(real_t p_rvalue);
+ void operator/=(float p_scalar);
bool is_equal_approx(const Color &p_color) const;
@@ -182,9 +182,12 @@ struct Color {
static Color html(const String &p_rgba);
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
+ static Color named(const String &p_name, const Color &p_default);
+ static int find_named_color(const String &p_name);
static int get_named_color_count();
static String get_named_color_name(int p_idx);
static Color get_named_color(int p_idx);
+ static Color from_string(const String &p_string, const Color &p_default);
String to_html(bool p_alpha = true) const;
Color from_hsv(float p_h, float p_s, float p_v, float p_a) const;
static Color from_rgbe9995(uint32_t p_rgbe);
@@ -238,6 +241,19 @@ struct Color {
b = p_c.b;
a = p_a;
}
+
+ Color(const String &p_code) {
+ if (html_is_valid(p_code)) {
+ *this = html(p_code);
+ } else {
+ *this = named(p_code);
+ }
+ }
+
+ Color(const String &p_code, float p_a) {
+ *this = Color(p_code);
+ a = p_a;
+ }
};
bool Color::operator<(const Color &p_color) const {
@@ -256,8 +272,8 @@ bool Color::operator<(const Color &p_color) const {
}
}
-_FORCE_INLINE_ Color operator*(real_t p_real, const Color &p_color) {
- return p_color * p_real;
+_FORCE_INLINE_ Color operator*(float p_scalar, const Color &p_color) {
+ return p_color * p_scalar;
}
#endif // COLOR_H
diff --git a/core/math/color_names.inc b/core/math/color_names.inc
index 523c7e3c59..e5b935ea9c 100644
--- a/core/math/color_names.inc
+++ b/core/math/color_names.inc
@@ -156,5 +156,5 @@ static NamedColor named_colors[] = {
{ "whitesmoke", Color(0.96, 0.96, 0.96) },
{ "yellow", Color(1.00, 1.00, 0.00) },
{ "yellowgreen", Color(0.60, 0.80, 0.20) },
- { nullptr, Color(0.60, 0.80, 0.20) },
+ { nullptr, Color() },
};
diff --git a/core/math/delaunay_2d.h b/core/math/delaunay_2d.h
index d637671686..95064e5700 100644
--- a/core/math/delaunay_2d.h
+++ b/core/math/delaunay_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h
index ea8655cfff..25cc1125db 100644
--- a/core/math/delaunay_3d.h
+++ b/core/math/delaunay_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h
index 51b9ce81af..b155412f64 100644
--- a/core/math/disjoint_set.h
+++ b/core/math/disjoint_set.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/dynamic_bvh.cpp b/core/math/dynamic_bvh.cpp
index e66de5037d..4639a52278 100644
--- a/core/math/dynamic_bvh.cpp
+++ b/core/math/dynamic_bvh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#include "dynamic_bvh.h"
void DynamicBVH::_delete_node(Node *p_node) {
- memdelete(p_node);
+ node_allocator.free(p_node);
}
void DynamicBVH::_recurse_delete_node(Node *p_node) {
@@ -46,7 +46,7 @@ void DynamicBVH::_recurse_delete_node(Node *p_node) {
}
DynamicBVH::Node *DynamicBVH::_create_node(Node *p_parent, void *p_data) {
- Node *node = memnew(Node);
+ Node *node = node_allocator.alloc();
node->parent = p_parent;
node->data = p_data;
return (node);
diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h
index 968badc093..c71db2d24d 100644
--- a/core/math/dynamic_bvh.h
+++ b/core/math/dynamic_bvh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,6 +34,7 @@
#include "core/math/aabb.h"
#include "core/templates/list.h"
#include "core/templates/local_vector.h"
+#include "core/templates/paged_allocator.h"
#include "core/typedefs.h"
// Based on bullet Dbvh
@@ -217,6 +218,7 @@ private:
}
};
+ PagedAllocator<Node> node_allocator;
// Fields
Node *bvh_root = nullptr;
int lkhd = -1;
@@ -276,7 +278,7 @@ private:
public:
// Methods
void clear();
- bool empty() const { return (0 == bvh_root); }
+ bool is_empty() const { return (0 == bvh_root); }
void optimize_bottom_up();
void optimize_top_down(int bu_threshold = 128);
void optimize_incremental(int passes);
@@ -330,7 +332,7 @@ void DynamicBVH::aabb_query(const AABB &p_box, QueryResult &r_result) {
if (n->volume.intersects(volume)) {
if (n->is_internal()) {
if (depth > threshold) {
- if (aux_stack.empty()) {
+ if (aux_stack.is_empty()) {
aux_stack.resize(ALLOCA_STACK_SIZE * 2);
copymem(aux_stack.ptr(), stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
} else {
@@ -386,7 +388,7 @@ void DynamicBVH::convex_query(const Plane *p_planes, int p_plane_count, const Ve
if (n->volume.intersects(volume) && n->volume.intersects_convex(p_planes, p_plane_count, p_points, p_point_count)) {
if (n->is_internal()) {
if (depth > threshold) {
- if (aux_stack.empty()) {
+ if (aux_stack.is_empty()) {
aux_stack.resize(ALLOCA_STACK_SIZE * 2);
copymem(aux_stack.ptr(), stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
} else {
@@ -443,7 +445,7 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu
if (result1) {
if (node->is_internal()) {
if (depth > threshold) {
- if (aux_stack.empty()) {
+ if (aux_stack.is_empty()) {
aux_stack.resize(ALLOCA_STACK_SIZE * 2);
copymem(aux_stack.ptr(), stack, ALLOCA_STACK_SIZE * sizeof(const Node *));
} else {
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 29b706a3a9..636ea601c7 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/expression.h b/core/math/expression.h
index 6b34bc6ae8..a6b288ed6e 100644
--- a/core/math/expression.h
+++ b/core/math/expression.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index db2bfaa58b..beb0a8e405 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/face3.h b/core/math/face3.h
index fb40e8ab9e..2e86b0a904 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/geometry_2d.cpp b/core/math/geometry_2d.cpp
index 4636e1c774..d67be14d33 100644
--- a/core/math/geometry_2d.cpp
+++ b/core/math/geometry_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,7 @@
#include "geometry_2d.h"
#include "thirdparty/misc/clipper.hpp"
-#include "thirdparty/misc/triangulator.h"
+#include "thirdparty/misc/polypartition.h"
#define STB_RECT_PACK_IMPLEMENTATION
#include "thirdparty/misc/stb_rect_pack.h"
@@ -39,16 +39,16 @@
Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(Vector<Point2> polygon) {
Vector<Vector<Vector2>> decomp;
- List<TriangulatorPoly> in_poly, out_poly;
+ List<TPPLPoly> in_poly, out_poly;
- TriangulatorPoly inp;
+ TPPLPoly inp;
inp.Init(polygon.size());
for (int i = 0; i < polygon.size(); i++) {
inp.GetPoint(i) = polygon[i];
}
- inp.SetOrientation(TRIANGULATOR_CCW);
+ inp.SetOrientation(TPPL_ORIENTATION_CCW);
in_poly.push_back(inp);
- TriangulatorPartition tpart;
+ TPPLPartition tpart;
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { // Failed.
ERR_PRINT("Convex decomposing failed!");
return decomp;
@@ -56,8 +56,8 @@ Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(Vector<Point2> p
decomp.resize(out_poly.size());
int idx = 0;
- for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
- TriangulatorPoly &tp = I->get();
+ for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
+ TPPLPoly &tp = I->get();
decomp.write[idx].resize(tp.GetNumPoints());
@@ -94,6 +94,10 @@ void Geometry2D::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_re
// 256x8192 atlas (won't work anywhere).
ERR_FAIL_COND(p_rects.size() == 0);
+ for (int i = 0; i < p_rects.size(); i++) {
+ ERR_FAIL_COND(p_rects[i].width <= 0);
+ ERR_FAIL_COND(p_rects[i].height <= 0);
+ }
Vector<_AtlasWorkRect> wrects;
wrects.resize(p_rects.size());
diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h
index 12bad5768e..4b5aef352f 100644
--- a/core/math/geometry_2d.h
+++ b/core/math/geometry_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -145,6 +145,12 @@ public:
return p_segment[0] + n * d; // Inside.
}
+// Disable False Positives in MSVC compiler; we correctly check for 0 here to prevent a division by 0.
+// See: https://github.com/godotengine/godot/pull/44274
+#ifdef _MSC_VER
+#pragma warning(disable : 4723)
+#endif
+
static bool line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b, Vector2 &r_result) {
// See http://paulbourke.net/geometry/pointlineplane/
@@ -159,6 +165,11 @@ public:
return true;
}
+// Re-enable division by 0 warning
+#ifdef _MSC_VER
+#pragma warning(default : 4723)
+#endif
+
static bool segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b, Vector2 *r_result) {
Vector2 B = p_to_a - p_from_a;
Vector2 C = p_from_b - p_from_a;
diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp
index ccb6648561..6628b760e0 100644
--- a/core/math/geometry_3d.cpp
+++ b/core/math/geometry_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,7 +33,7 @@
#include "core/string/print_string.h"
#include "thirdparty/misc/clipper.hpp"
-#include "thirdparty/misc/triangulator.h"
+#include "thirdparty/misc/polypartition.h"
void Geometry3D::MeshData::optimize_vertices() {
Map<int, int> vtx_remap;
@@ -775,12 +775,15 @@ Vector<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) {
}
Vector<Plane> Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) {
+ ERR_FAIL_INDEX_V(p_axis, 3, Vector<Plane>());
+
Vector<Plane> planes;
+ const double sides_step = Math_TAU / p_sides;
for (int i = 0; i < p_sides; i++) {
Vector3 normal;
- normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides);
- normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides);
+ normal[(p_axis + 1) % 3] = Math::cos(i * sides_step);
+ normal[(p_axis + 2) % 3] = Math::sin(i * sides_step);
planes.push_back(Plane(normal, p_radius));
}
@@ -795,6 +798,8 @@ Vector<Plane> Geometry3D::build_cylinder_planes(real_t p_radius, real_t p_height
}
Vector<Plane> Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis) {
+ ERR_FAIL_INDEX_V(p_axis, 3, Vector<Plane>());
+
Vector<Plane> planes;
Vector3 axis;
@@ -805,10 +810,11 @@ Vector<Plane> Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p
axis_neg[(p_axis + 2) % 3] = 1.0;
axis_neg[p_axis] = -1.0;
+ const double lon_step = Math_TAU / p_lons;
for (int i = 0; i < p_lons; i++) {
Vector3 normal;
- normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_lons);
- normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_lons);
+ normal[(p_axis + 1) % 3] = Math::cos(i * lon_step);
+ normal[(p_axis + 2) % 3] = Math::sin(i * lon_step);
planes.push_back(Plane(normal, p_radius));
@@ -825,6 +831,8 @@ Vector<Plane> Geometry3D::build_sphere_planes(real_t p_radius, int p_lats, int p
}
Vector<Plane> Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
+ ERR_FAIL_INDEX_V(p_axis, 3, Vector<Plane>());
+
Vector<Plane> planes;
Vector3 axis;
@@ -835,10 +843,11 @@ Vector<Plane> Geometry3D::build_capsule_planes(real_t p_radius, real_t p_height,
axis_neg[(p_axis + 2) % 3] = 1.0;
axis_neg[p_axis] = -1.0;
+ const double sides_step = Math_TAU / p_sides;
for (int i = 0; i < p_sides; i++) {
Vector3 normal;
- normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides);
- normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides);
+ normal[(p_axis + 1) % 3] = Math::cos(i * sides_step);
+ normal[(p_axis + 2) % 3] = Math::sin(i * sides_step);
planes.push_back(Plane(normal, p_radius));
diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h
index f10fbeaaaf..4ef9b4dbe6 100644
--- a/core/math/geometry_3d.h
+++ b/core/math/geometry_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -252,27 +252,34 @@ public:
return true;
}
- static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) {
+ static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr, int p_cylinder_axis = 2) {
Vector3 rel = (p_to - p_from);
real_t rel_l = rel.length();
if (rel_l < CMP_EPSILON) {
return false; // Both points are the same.
}
+ ERR_FAIL_COND_V(p_cylinder_axis < 0, false);
+ ERR_FAIL_COND_V(p_cylinder_axis > 2, false);
+ Vector3 cylinder_axis;
+ cylinder_axis[p_cylinder_axis] = 1.0;
+
// First check if they are parallel.
Vector3 normal = (rel / rel_l);
- Vector3 crs = normal.cross(Vector3(0, 0, 1));
+ Vector3 crs = normal.cross(cylinder_axis);
real_t crs_l = crs.length();
- Vector3 z_dir;
+ Vector3 axis_dir;
if (crs_l < CMP_EPSILON) {
- z_dir = Vector3(1, 0, 0); // Any x/y vector OK.
+ Vector3 side_axis;
+ side_axis[(p_cylinder_axis + 1) % 3] = 1.0; // Any side axis OK.
+ axis_dir = side_axis;
} else {
- z_dir = crs / crs_l;
+ axis_dir = crs / crs_l;
}
- real_t dist = z_dir.dot(p_from);
+ real_t dist = axis_dir.dot(p_from);
if (dist >= p_radius) {
return false; // Too far away.
@@ -285,10 +292,10 @@ public:
}
Size2 size(Math::sqrt(w2), p_height * 0.5);
- Vector3 x_dir = z_dir.cross(Vector3(0, 0, 1)).normalized();
+ Vector3 side_dir = axis_dir.cross(cylinder_axis).normalized();
- Vector2 from2D(x_dir.dot(p_from), p_from.z);
- Vector2 to2D(x_dir.dot(p_to), p_to.z);
+ Vector2 from2D(side_dir.dot(p_from), p_from[p_cylinder_axis]);
+ Vector2 to2D(side_dir.dot(p_to), p_to[p_cylinder_axis]);
real_t min = 0, max = 1;
@@ -335,10 +342,12 @@ public:
Vector3 res_normal = result;
if (axis == 0) {
- res_normal.z = 0;
+ res_normal[p_cylinder_axis] = 0;
} else {
- res_normal.x = 0;
- res_normal.y = 0;
+ int axis_side = (p_cylinder_axis + 1) % 3;
+ res_normal[axis_side] = 0;
+ axis_side = (axis_side + 1) % 3;
+ res_normal[axis_side] = 0;
}
res_normal.normalize();
diff --git a/core/math/math_defs.h b/core/math/math_defs.h
index 0478de732a..df2223fb78 100644
--- a/core/math/math_defs.h
+++ b/core/math/math_defs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp
index 221c6812c1..0985a727f2 100644
--- a/core/math/math_fieldwise.cpp
+++ b/core/math/math_fieldwise.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/math_fieldwise.h b/core/math/math_fieldwise.h
index e8aac0dced..fe44d09900 100644
--- a/core/math/math_fieldwise.h
+++ b/core/math/math_fieldwise.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index e57257b442..e92bb9f4aa 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -123,7 +123,7 @@ double Math::ease(double p_x, double p_c) {
}
}
-double Math::stepify(double p_value, double p_step) {
+double Math::snapped(double p_value, double p_step) {
if (p_step != 0) {
p_value = Math::floor(p_value / p_step + 0.5) * p_step;
}
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 471aa58996..267f6a4fe2 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -223,11 +223,11 @@ public:
return value;
}
- static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * Math_PI / 180.0; }
- static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * Math_PI / 180.0; }
+ static _ALWAYS_INLINE_ double deg2rad(double p_y) { return p_y * (Math_PI / 180.0); }
+ static _ALWAYS_INLINE_ float deg2rad(float p_y) { return p_y * (Math_PI / 180.0); }
- static _ALWAYS_INLINE_ double rad2deg(double p_y) { return p_y * 180.0 / Math_PI; }
- static _ALWAYS_INLINE_ float rad2deg(float p_y) { return p_y * 180.0 / Math_PI; }
+ static _ALWAYS_INLINE_ double rad2deg(double p_y) { return p_y * (180.0 / Math_PI); }
+ static _ALWAYS_INLINE_ float rad2deg(float p_y) { return p_y * (180.0 / Math_PI); }
static _ALWAYS_INLINE_ double lerp(double p_from, double p_to, double p_weight) { return p_from + (p_to - p_from) * p_weight; }
static _ALWAYS_INLINE_ float lerp(float p_from, float p_to, float p_weight) { return p_from + (p_to - p_from) * p_weight; }
@@ -292,7 +292,7 @@ public:
static double ease(double p_x, double p_c);
static int step_decimals(double p_step);
static int range_step_decimals(double p_step);
- static double stepify(double p_value, double p_step);
+ static double snapped(double p_value, double p_step);
static double dectime(double p_value, double p_amount, double p_step);
static uint32_t larger_prime(uint32_t p_val);
@@ -472,12 +472,12 @@ public:
}
static _ALWAYS_INLINE_ float snap_scalar(float p_offset, float p_step, float p_target) {
- return p_step != 0 ? Math::stepify(p_target - p_offset, p_step) + p_offset : p_target;
+ return p_step != 0 ? Math::snapped(p_target - p_offset, p_step) + p_offset : p_target;
}
static _ALWAYS_INLINE_ float snap_scalar_separation(float p_offset, float p_step, float p_target, float p_separation) {
if (p_step != 0) {
- float a = Math::stepify(p_target - p_offset, p_step + p_separation) + p_offset;
+ float a = Math::snapped(p_target - p_offset, p_step + p_separation) + p_offset;
float b = a;
if (p_target >= 0) {
b -= p_separation;
diff --git a/core/math/octree.h b/core/math/octree.h
index be1e7d6a61..493a63aa2e 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -572,7 +572,7 @@ bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, O
Octant *parent = p_octant->parent;
- if (p_octant->children_count == 0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) {
+ if (p_octant->children_count == 0 && p_octant->elements.is_empty() && p_octant->pairable_elements.is_empty()) {
// erase octant
if (p_octant == root) { // won't have a parent, just erase
@@ -942,7 +942,7 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
return; //pointless
}
- if (!p_octant->elements.empty()) {
+ if (!p_octant->elements.is_empty()) {
typename List<Element *, AL>::Element *I;
I = p_octant->elements.front();
@@ -965,7 +965,7 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
}
}
- if (use_pairs && !p_octant->pairable_elements.empty()) {
+ if (use_pairs && !p_octant->pairable_elements.is_empty()) {
typename List<Element *, AL>::Element *I;
I = p_octant->pairable_elements.front();
@@ -1001,7 +1001,7 @@ void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb,
return; //pointless
}
- if (!p_octant->elements.empty()) {
+ if (!p_octant->elements.is_empty()) {
typename List<Element *, AL>::Element *I;
I = p_octant->elements.front();
for (; I; I = I->next()) {
@@ -1027,7 +1027,7 @@ void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb,
}
}
- if (use_pairs && !p_octant->pairable_elements.empty()) {
+ if (use_pairs && !p_octant->pairable_elements.is_empty()) {
typename List<Element *, AL>::Element *I;
I = p_octant->pairable_elements.front();
for (; I; I = I->next()) {
@@ -1065,7 +1065,7 @@ void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_
return; //pointless
}
- if (!p_octant->elements.empty()) {
+ if (!p_octant->elements.is_empty()) {
typename List<Element *, AL>::Element *I;
I = p_octant->elements.front();
for (; I; I = I->next()) {
@@ -1091,7 +1091,7 @@ void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_
}
}
- if (use_pairs && !p_octant->pairable_elements.empty()) {
+ if (use_pairs && !p_octant->pairable_elements.is_empty()) {
typename List<Element *, AL>::Element *I;
I = p_octant->pairable_elements.front();
for (; I; I = I->next()) {
@@ -1132,7 +1132,7 @@ void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_po
return; //pointless
}
- if (!p_octant->elements.empty()) {
+ if (!p_octant->elements.is_empty()) {
typename List<Element *, AL>::Element *I;
I = p_octant->elements.front();
for (; I; I = I->next()) {
@@ -1158,7 +1158,7 @@ void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_po
}
}
- if (use_pairs && !p_octant->pairable_elements.empty()) {
+ if (use_pairs && !p_octant->pairable_elements.is_empty()) {
typename List<Element *, AL>::Element *I;
I = p_octant->pairable_elements.front();
for (; I; I = I->next()) {
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index e1ae3288ed..f1d3bbbd54 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/plane.h b/core/math/plane.h
index 1386b0a2cb..2267b28c53 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index fc2d71c377..a9a21a1ba3 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,32 +33,6 @@
#include "core/math/basis.h"
#include "core/string/print_string.h"
-// set_euler_xyz expects a vector containing the Euler angles in the format
-// (ax,ay,az), where ax is the angle of rotation around x axis,
-// and similar for other axes.
-// This implementation uses XYZ convention (Z is the first rotation).
-void Quat::set_euler_xyz(const Vector3 &p_euler) {
- real_t half_a1 = p_euler.x * 0.5;
- real_t half_a2 = p_euler.y * 0.5;
- real_t half_a3 = p_euler.z * 0.5;
-
- // R = X(a1).Y(a2).Z(a3) convention for Euler angles.
- // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-2)
- // a3 is the angle of the first rotation, following the notation in this reference.
-
- real_t cos_a1 = Math::cos(half_a1);
- real_t sin_a1 = Math::sin(half_a1);
- real_t cos_a2 = Math::cos(half_a2);
- real_t sin_a2 = Math::sin(half_a2);
- real_t cos_a3 = Math::cos(half_a3);
- real_t sin_a3 = Math::sin(half_a3);
-
- set(sin_a1 * cos_a2 * cos_a3 + sin_a2 * sin_a3 * cos_a1,
- -sin_a1 * sin_a3 * cos_a2 + sin_a2 * cos_a1 * cos_a3,
- sin_a1 * sin_a2 * cos_a3 + sin_a3 * cos_a1 * cos_a2,
- -sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3);
-}
-
// get_euler_xyz returns a vector containing the Euler angles in the format
// (ax,ay,az), where ax is the angle of rotation around x axis,
// and similar for other axes.
@@ -68,32 +42,6 @@ Vector3 Quat::get_euler_xyz() const {
return m.get_euler_xyz();
}
-// set_euler_yxz expects a vector containing the Euler angles in the format
-// (ax,ay,az), where ax is the angle of rotation around x axis,
-// and similar for other axes.
-// This implementation uses YXZ convention (Z is the first rotation).
-void Quat::set_euler_yxz(const Vector3 &p_euler) {
- real_t half_a1 = p_euler.y * 0.5;
- real_t half_a2 = p_euler.x * 0.5;
- real_t half_a3 = p_euler.z * 0.5;
-
- // R = Y(a1).X(a2).Z(a3) convention for Euler angles.
- // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
- // a3 is the angle of the first rotation, following the notation in this reference.
-
- real_t cos_a1 = Math::cos(half_a1);
- real_t sin_a1 = Math::sin(half_a1);
- real_t cos_a2 = Math::cos(half_a2);
- real_t sin_a2 = Math::sin(half_a2);
- real_t cos_a3 = Math::cos(half_a3);
- real_t sin_a3 = Math::sin(half_a3);
-
- set(sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3,
- sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3,
- -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3,
- sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3);
-}
-
// get_euler_yxz returns a vector containing the Euler angles in the format
// (ax,ay,az), where ax is the angle of rotation around x axis,
// and similar for other axes.
@@ -107,10 +55,10 @@ Vector3 Quat::get_euler_yxz() const {
}
void Quat::operator*=(const Quat &p_q) {
- set(w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y,
- w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z,
- w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x,
- w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z);
+ x = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y;
+ y = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z;
+ z = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x;
+ w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z;
}
Quat Quat::operator*(const Quat &p_q) const {
@@ -233,18 +181,49 @@ Quat::operator String() const {
return String::num(x) + ", " + String::num(y) + ", " + String::num(z) + ", " + String::num(w);
}
-void Quat::set_axis_angle(const Vector3 &axis, const real_t &angle) {
+Quat::Quat(const Vector3 &p_axis, real_t p_angle) {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_MSG(!axis.is_normalized(), "The axis Vector3 must be normalized.");
+ ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 must be normalized.");
#endif
- real_t d = axis.length();
+ real_t d = p_axis.length();
if (d == 0) {
- set(0, 0, 0, 0);
+ x = 0;
+ y = 0;
+ z = 0;
+ w = 0;
} else {
- real_t sin_angle = Math::sin(angle * 0.5);
- real_t cos_angle = Math::cos(angle * 0.5);
+ real_t sin_angle = Math::sin(p_angle * 0.5);
+ real_t cos_angle = Math::cos(p_angle * 0.5);
real_t s = sin_angle / d;
- set(axis.x * s, axis.y * s, axis.z * s,
- cos_angle);
+ x = p_axis.x * s;
+ y = p_axis.y * s;
+ z = p_axis.z * s;
+ w = cos_angle;
}
}
+
+// Euler constructor expects a vector containing the Euler angles in the format
+// (ax, ay, az), where ax is the angle of rotation around x axis,
+// and similar for other axes.
+// This implementation uses YXZ convention (Z is the first rotation).
+Quat::Quat(const Vector3 &p_euler) {
+ real_t half_a1 = p_euler.y * 0.5;
+ real_t half_a2 = p_euler.x * 0.5;
+ real_t half_a3 = p_euler.z * 0.5;
+
+ // R = Y(a1).X(a2).Z(a3) convention for Euler angles.
+ // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
+ // a3 is the angle of the first rotation, following the notation in this reference.
+
+ real_t cos_a1 = Math::cos(half_a1);
+ real_t sin_a1 = Math::sin(half_a1);
+ real_t cos_a2 = Math::cos(half_a2);
+ real_t sin_a2 = Math::sin(half_a2);
+ real_t cos_a3 = Math::cos(half_a3);
+ real_t sin_a3 = Math::sin(half_a3);
+
+ x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
+ y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
+ z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3;
+ w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
+}
diff --git a/core/math/quat.h b/core/math/quat.h
index bb980f7677..9db914fe52 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,19 +65,14 @@ public:
Quat inverse() const;
_FORCE_INLINE_ real_t dot(const Quat &p_q) const;
- void set_euler_xyz(const Vector3 &p_euler);
Vector3 get_euler_xyz() const;
- void set_euler_yxz(const Vector3 &p_euler);
Vector3 get_euler_yxz() const;
-
- void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); };
Vector3 get_euler() const { return get_euler_yxz(); };
Quat slerp(const Quat &p_to, const real_t &p_weight) const;
Quat slerpni(const Quat &p_to, const real_t &p_weight) const;
Quat cubic_slerp(const Quat &p_b, const Quat &p_pre_a, const Quat &p_post_b, const real_t &p_weight) const;
- void set_axis_angle(const Vector3 &axis, const real_t &angle);
_FORCE_INLINE_ void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
r_angle = 2 * Math::acos(w);
real_t r = ((real_t)1) / Math::sqrt(1 - w * w);
@@ -124,23 +119,19 @@ public:
operator String() const;
- inline void set(real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
- x = p_x;
- y = p_y;
- z = p_z;
- w = p_w;
- }
-
_FORCE_INLINE_ Quat() {}
+
_FORCE_INLINE_ Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) :
x(p_x),
y(p_y),
z(p_z),
w(p_w) {
}
- Quat(const Vector3 &axis, const real_t &angle) { set_axis_angle(axis, angle); }
- Quat(const Vector3 &euler) { set_euler(euler); }
+ Quat(const Vector3 &p_axis, real_t p_angle);
+
+ Quat(const Vector3 &p_euler);
+
Quat(const Quat &p_q) :
x(p_q.x),
y(p_q.y),
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 8dff13c050..ad28967d7a 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h
index 024325c4fc..48ea139cc9 100644
--- a/core/math/quick_hull.h
+++ b/core/math/quick_hull.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/random_number_generator.cpp b/core/math/random_number_generator.cpp
index f045213fb9..b40d010219 100644
--- a/core/math/random_number_generator.cpp
+++ b/core/math/random_number_generator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h
index 7728fd09c0..a396c2b7d7 100644
--- a/core/math/random_number_generator.h
+++ b/core/math/random_number_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/random_pcg.cpp b/core/math/random_pcg.cpp
index c39037747a..9609620469 100644
--- a/core/math/random_pcg.cpp
+++ b/core/math/random_pcg.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h
index 2e257cb5b7..5a03b758ce 100644
--- a/core/math/random_pcg.h
+++ b/core/math/random_pcg.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index 0cc3c4ca0f..60c44999f7 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/rect2.h b/core/math/rect2.h
index aecba9e88c..512499bdb2 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -180,16 +180,16 @@ struct Rect2 {
bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; }
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
- inline Rect2 grow(real_t p_by) const {
+ inline Rect2 grow(real_t p_amount) const {
Rect2 g = *this;
- g.position.x -= p_by;
- g.position.y -= p_by;
- g.size.width += p_by * 2;
- g.size.height += p_by * 2;
+ g.position.x -= p_amount;
+ g.position.y -= p_amount;
+ g.size.width += p_amount * 2;
+ g.size.height += p_amount * 2;
return g;
}
- inline Rect2 grow_margin(Side p_side, real_t p_amount) const {
+ inline Rect2 grow_side(Side p_side, real_t p_amount) const {
Rect2 g = *this;
g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0,
(SIDE_TOP == p_side) ? p_amount : 0,
@@ -198,8 +198,8 @@ struct Rect2 {
return g;
}
- inline Rect2 grow_margin_bind(uint32_t p_side, real_t p_amount) const {
- return grow_margin(Side(p_side), p_amount);
+ inline Rect2 grow_side_bind(uint32_t p_side, real_t p_amount) const {
+ return grow_side(Side(p_side), p_amount);
}
inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const {
@@ -273,7 +273,7 @@ struct Rect2 {
}
//check inside
- Vector2 tg = r.tangent();
+ Vector2 tg = r.orthogonal();
float s = tg.dot(center) - tg.dot(a);
if (s < 0.0) {
side_plus++;
@@ -422,16 +422,16 @@ struct Rect2i {
bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; }
bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
- Rect2i grow(int p_by) const {
+ Rect2i grow(int p_amount) const {
Rect2i g = *this;
- g.position.x -= p_by;
- g.position.y -= p_by;
- g.size.width += p_by * 2;
- g.size.height += p_by * 2;
+ g.position.x -= p_amount;
+ g.position.y -= p_amount;
+ g.size.width += p_amount * 2;
+ g.size.height += p_amount * 2;
return g;
}
- inline Rect2i grow_margin(Side p_side, int p_amount) const {
+ inline Rect2i grow_side(Side p_side, int p_amount) const {
Rect2i g = *this;
g = g.grow_individual((SIDE_LEFT == p_side) ? p_amount : 0,
(SIDE_TOP == p_side) ? p_amount : 0,
@@ -440,8 +440,8 @@ struct Rect2i {
return g;
}
- inline Rect2i grow_margin_bind(uint32_t p_side, int p_amount) const {
- return grow_margin(Side(p_side), p_amount);
+ inline Rect2i grow_side_bind(uint32_t p_side, int p_amount) const {
+ return grow_side(Side(p_side), p_amount);
}
inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const {
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 733bb4d55e..fab5d124fa 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/transform.h b/core/math/transform.h
index c63dbcb989..1c05dbe554 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,8 +51,8 @@ public:
void rotate(const Vector3 &p_axis, real_t p_phi);
void rotate_basis(const Vector3 &p_axis, real_t p_phi);
- void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up);
- Transform looking_at(const Vector3 &p_target, const Vector3 &p_up) const;
+ void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
+ Transform looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)) const;
void scale(const Vector3 &p_scale);
Transform scaled(const Vector3 &p_scale) const;
@@ -144,8 +144,8 @@ _FORCE_INLINE_ Plane Transform::xform(const Plane &p_plane) const {
_FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const {
Vector3 point = p_plane.normal * p_plane.d;
Vector3 point_dir = point + p_plane.normal;
- xform_inv(point);
- xform_inv(point_dir);
+ point = xform_inv(point);
+ point_dir = xform_inv(point_dir);
Vector3 normal = point_dir - point;
normal.normalize();
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 00e561f973..4a521b96ae 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 342623939e..327d0f244f 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index cfe8422d80..23c0c686a2 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h
index d719822ec3..1d1dbc114b 100644
--- a/core/math/triangle_mesh.h
+++ b/core/math/triangle_mesh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp
index 12bd384c6a..0047c0705d 100644
--- a/core/math/triangulate.cpp
+++ b/core/math/triangulate.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/triangulate.h b/core/math/triangulate.h
index c453b77ecf..55dc4e8e7d 100644
--- a/core/math/triangulate.h
+++ b/core/math/triangulate.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index f9c2eeb57d..5129ed336e 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -122,10 +122,10 @@ Vector2 Vector2::project(const Vector2 &p_to) const {
return p_to * (dot(p_to) / p_to.length_squared());
}
-Vector2 Vector2::snapped(const Vector2 &p_by) const {
+Vector2 Vector2::snapped(const Vector2 &p_step) const {
return Vector2(
- Math::stepify(x, p_by.x),
- Math::stepify(y, p_by.y));
+ Math::snapped(x, p_step.x),
+ Math::snapped(y, p_step.y));
}
Vector2 Vector2::clamped(real_t p_len) const {
@@ -211,11 +211,11 @@ Vector2i Vector2i::operator*(const Vector2i &p_v1) const {
return Vector2i(x * p_v1.x, y * p_v1.y);
}
-Vector2i Vector2i::operator*(const int &rvalue) const {
+Vector2i Vector2i::operator*(const int32_t &rvalue) const {
return Vector2i(x * rvalue, y * rvalue);
}
-void Vector2i::operator*=(const int &rvalue) {
+void Vector2i::operator*=(const int32_t &rvalue) {
x *= rvalue;
y *= rvalue;
}
@@ -224,11 +224,11 @@ Vector2i Vector2i::operator/(const Vector2i &p_v1) const {
return Vector2i(x / p_v1.x, y / p_v1.y);
}
-Vector2i Vector2i::operator/(const int &rvalue) const {
+Vector2i Vector2i::operator/(const int32_t &rvalue) const {
return Vector2i(x / rvalue, y / rvalue);
}
-void Vector2i::operator/=(const int &rvalue) {
+void Vector2i::operator/=(const int32_t &rvalue) {
x /= rvalue;
y /= rvalue;
}
@@ -237,11 +237,11 @@ Vector2i Vector2i::operator%(const Vector2i &p_v1) const {
return Vector2i(x % p_v1.x, y % p_v1.y);
}
-Vector2i Vector2i::operator%(const int &rvalue) const {
+Vector2i Vector2i::operator%(const int32_t &rvalue) const {
return Vector2i(x % rvalue, y % rvalue);
}
-void Vector2i::operator%=(const int &rvalue) {
+void Vector2i::operator%=(const int32_t &rvalue) {
x %= rvalue;
y %= rvalue;
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 33f815a39c..81bc71d590 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -134,7 +134,7 @@ struct Vector2 {
}
Vector2 rotated(real_t p_by) const;
- Vector2 tangent() const {
+ Vector2 orthogonal() const {
return Vector2(y, -x);
}
@@ -265,18 +265,18 @@ struct Vector2i {
};
union {
- int x = 0;
- int width;
+ int32_t x = 0;
+ int32_t width;
};
union {
- int y = 0;
- int height;
+ int32_t y = 0;
+ int32_t height;
};
- _FORCE_INLINE_ int &operator[](int p_idx) {
+ _FORCE_INLINE_ int32_t &operator[](int p_idx) {
return p_idx ? y : x;
}
- _FORCE_INLINE_ const int &operator[](int p_idx) const {
+ _FORCE_INLINE_ const int32_t &operator[](int p_idx) const {
return p_idx ? y : x;
}
@@ -286,16 +286,16 @@ struct Vector2i {
void operator-=(const Vector2i &p_v);
Vector2i operator*(const Vector2i &p_v1) const;
- Vector2i operator*(const int &rvalue) const;
- void operator*=(const int &rvalue);
+ Vector2i operator*(const int32_t &rvalue) const;
+ void operator*=(const int32_t &rvalue);
Vector2i operator/(const Vector2i &p_v1) const;
- Vector2i operator/(const int &rvalue) const;
- void operator/=(const int &rvalue);
+ Vector2i operator/(const int32_t &rvalue) const;
+ void operator/=(const int32_t &rvalue);
Vector2i operator%(const Vector2i &p_v1) const;
- Vector2i operator%(const int &rvalue) const;
- void operator%=(const int &rvalue);
+ Vector2i operator%(const int32_t &rvalue) const;
+ void operator%=(const int32_t &rvalue);
Vector2i operator-() const;
bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
@@ -317,10 +317,10 @@ struct Vector2i {
inline Vector2i() {}
inline Vector2i(const Vector2 &p_vec2) {
- x = (int)p_vec2.x;
- y = (int)p_vec2.y;
+ x = (int32_t)p_vec2.x;
+ y = (int32_t)p_vec2.y;
}
- inline Vector2i(int p_x, int p_y) {
+ inline Vector2i(int32_t p_x, int32_t p_y) {
x = p_x;
y = p_y;
}
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index 09354d8e79..f0629d3db8 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -60,15 +60,15 @@ int Vector3::max_axis() const {
return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
}
-void Vector3::snap(Vector3 p_val) {
- x = Math::stepify(x, p_val.x);
- y = Math::stepify(y, p_val.y);
- z = Math::stepify(z, p_val.z);
+void Vector3::snap(Vector3 p_step) {
+ x = Math::snapped(x, p_step.x);
+ y = Math::snapped(y, p_step.y);
+ z = Math::snapped(z, p_step.z);
}
-Vector3 Vector3::snapped(Vector3 p_val) const {
+Vector3 Vector3::snapped(Vector3 p_step) const {
Vector3 v = *this;
- v.snap(p_val);
+ v.snap(p_step);
return v;
}
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 5af84377fd..377581bb45 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -110,6 +110,7 @@ struct Vector3 {
_FORCE_INLINE_ Vector3 project(const Vector3 &p_to) const;
_FORCE_INLINE_ real_t angle_to(const Vector3 &p_to) const;
+ _FORCE_INLINE_ real_t signed_angle_to(const Vector3 &p_to, const Vector3 &p_axis) const;
_FORCE_INLINE_ Vector3 direction_to(const Vector3 &p_to) const;
_FORCE_INLINE_ Vector3 slide(const Vector3 &p_normal) const;
@@ -230,6 +231,13 @@ real_t Vector3::angle_to(const Vector3 &p_to) const {
return Math::atan2(cross(p_to).length(), dot(p_to));
}
+real_t Vector3::signed_angle_to(const Vector3 &p_to, const Vector3 &p_axis) const {
+ Vector3 cross_to = cross(p_to);
+ real_t unsigned_angle = Math::atan2(cross_to.length(), dot(p_to));
+ real_t sign = cross_to.dot(p_axis);
+ return (sign < 0) ? -unsigned_angle : unsigned_angle;
+}
+
Vector3 Vector3::direction_to(const Vector3 &p_to) const {
Vector3 ret(p_to.x - x, p_to.y - y, p_to.z - z);
ret.normalize();
@@ -324,48 +332,40 @@ bool Vector3::operator<(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z < p_v.z;
- } else {
- return y < p_v.y;
}
- } else {
- return x < p_v.x;
+ return y < p_v.y;
}
+ return x < p_v.x;
}
bool Vector3::operator>(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z > p_v.z;
- } else {
- return y > p_v.y;
}
- } else {
- return x > p_v.x;
+ return y > p_v.y;
}
+ return x > p_v.x;
}
bool Vector3::operator<=(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z <= p_v.z;
- } else {
- return y < p_v.y;
}
- } else {
- return x < p_v.x;
+ return y < p_v.y;
}
+ return x < p_v.x;
}
bool Vector3::operator>=(const Vector3 &p_v) const {
if (x == p_v.x) {
if (y == p_v.y) {
return z >= p_v.z;
- } else {
- return y > p_v.y;
}
- } else {
- return x > p_v.x;
+ return y > p_v.y;
}
+ return x > p_v.x;
}
_FORCE_INLINE_ Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) {
diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp
index 718a1553a0..167fa3221d 100644
--- a/core/math/vector3i.cpp
+++ b/core/math/vector3i.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 1bfd6d5ab2..b0411fb62e 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/callable_method_pointer.cpp b/core/object/callable_method_pointer.cpp
index 21a917cbd7..2bfaef744d 100644
--- a/core/object/callable_method_pointer.cpp
+++ b/core/object/callable_method_pointer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/callable_method_pointer.h b/core/object/callable_method_pointer.h
index 68990dcb72..115797a00c 100644
--- a/core/object/callable_method_pointer.h
+++ b/core/object/callable_method_pointer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index f5171f60ec..375ad8fae1 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -377,7 +377,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
while ((k = t->method_map.next(k))) {
String name = k->operator String();
- ERR_CONTINUE(name.empty());
+ ERR_CONTINUE(name.is_empty());
if (name[0] == '_') {
continue; // Ignore non-virtual methods that start with an underscore
@@ -983,9 +983,9 @@ void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, co
// NOTE: For implementation simplicity reasons, this method doesn't allow setters to have optional arguments at the end.
void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
- lock->read_lock();
+ lock.read_lock();
ClassInfo *type = classes.getptr(p_class);
- lock->read_unlock();
+ lock.read_unlock();
ERR_FAIL_COND(!type);
@@ -1541,11 +1541,7 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con
return var;
}
-RWLock *ClassDB::lock = nullptr;
-
-void ClassDB::init() {
- lock = RWLock::create();
-}
+RWLock ClassDB::lock;
void ClassDB::cleanup_defaults() {
default_values.clear();
@@ -1568,8 +1564,6 @@ void ClassDB::cleanup() {
classes.clear();
resource_base_extensions.clear();
compat_classes.clear();
-
- memdelete(lock);
}
//
diff --git a/core/object/class_db.h b/core/object/class_db.h
index 94f26da60d..6fd5748dbb 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -146,7 +146,7 @@ public:
return memnew(T);
}
- static RWLock *lock;
+ static RWLock lock;
static HashMap<StringName, ClassInfo> classes;
static HashMap<StringName, StringName> resource_base_extensions;
static HashMap<StringName, StringName> compat_classes;
@@ -387,7 +387,6 @@ public:
static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions);
static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback);
- static void init();
static void set_current_api(APIType p_api);
static APIType get_current_api();
diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp
index f0d6786853..4751c69f1e 100644
--- a/core/object/message_queue.cpp
+++ b/core/object/message_queue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/message_queue.h b/core/object/message_queue.h
index 2901ab196a..1b8def62d3 100644
--- a/core/object/message_queue.h
+++ b/core/object/message_queue.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/method_bind.cpp b/core/object/method_bind.cpp
index e6652ac09f..9c5ed60708 100644
--- a/core/object/method_bind.cpp
+++ b/core/object/method_bind.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/method_bind.h b/core/object/method_bind.h
index bd308c9630..7cf4f8d4e8 100644
--- a/core/object/method_bind.h
+++ b/core/object/method_bind.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 681e1188ff..1a9cce49d8 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -506,7 +506,7 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
}
void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_value, bool *r_valid) {
- if (p_names.empty()) {
+ if (p_names.is_empty()) {
if (r_valid) {
*r_valid = false;
}
@@ -561,11 +561,11 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val
set(p_names[0], value_stack.back()->get(), r_valid);
value_stack.pop_back();
- ERR_FAIL_COND(!value_stack.empty());
+ ERR_FAIL_COND(!value_stack.is_empty());
}
Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) const {
- if (p_names.empty()) {
+ if (p_names.is_empty()) {
if (r_valid) {
*r_valid = false;
}
@@ -599,7 +599,7 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
if (!is_class("Script")) { // can still be set, but this is for userfriendlyness
p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT));
}
- if (!metadata.empty()) {
+ if (!metadata.is_empty()) {
p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
if (script_instance && !p_reversed) {
@@ -808,21 +808,6 @@ String Object::to_string() {
return "[" + get_class() + ":" + itos(get_instance_id()) + "]";
}
-void Object::_changed_callback(Object *p_changed, const char *p_prop) {
-}
-
-void Object::add_change_receptor(Object *p_receptor) {
- change_receptors.insert(p_receptor);
-}
-
-void Object::remove_change_receptor(Object *p_receptor) {
- change_receptors.erase(p_receptor);
-}
-
-void Object::property_list_changed_notify() {
- _change_notify();
-}
-
void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance) {
//this function is not meant to be used in any of these ways
ERR_FAIL_COND(p_script.is_null());
@@ -856,7 +841,7 @@ void Object::set_script(const Variant &p_script) {
}
}
- _change_notify(); //scripts may add variables, so refresh is desired
+ notify_property_list_changed(); //scripts may add variables, so refresh is desired
emit_signal(CoreStringNames::get_singleton()->script_changed);
}
@@ -1089,7 +1074,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
}
}
- while (!disconnect_data.empty()) {
+ while (!disconnect_data.is_empty()) {
const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get();
_disconnect(dd.signal, dd.callable);
@@ -1357,7 +1342,12 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable,
ERR_FAIL_COND(!target_object);
SignalData *s = signal_map.getptr(p_signal);
- ERR_FAIL_COND_MSG(!s, vformat("Nonexistent signal '%s' in %s.", p_signal, to_string()));
+ if (!s) {
+ bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal) ||
+ (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal));
+ ERR_FAIL_COND_MSG(signal_is_valid, "Attempt to disconnect a nonexistent connection from '" + to_string() + "'. signal: '" + p_signal + "', callable: '" + p_callable + "'.");
+ }
+ ERR_FAIL_COND_MSG(!s, vformat("Disconnecting nonexistent signal '%s' in %s.", p_signal, to_string()));
ERR_FAIL_COND_MSG(!s->slot_map.has(*p_callable.get_base_comparator()), "Disconnecting nonexistent signal '" + p_signal + "', callable: " + p_callable + ".");
@@ -1373,7 +1363,7 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable,
target_object->connections.erase(slot->cE);
s->slot_map.erase(*p_callable.get_base_comparator());
- if (s->slot_map.empty() && ClassDB::has_signal(get_class_name(), p_signal)) {
+ if (s->slot_map.is_empty() && ClassDB::has_signal(get_class_name(), p_signal)) {
//not user signal, delete
signal_map.erase(p_signal);
}
@@ -1491,6 +1481,10 @@ void Object::clear_internal_resource_paths() {
}
}
+void Object::notify_property_list_changed() {
+ emit_signal(CoreStringNames::get_singleton()->property_list_changed);
+}
+
void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_class"), &Object::get_class);
ClassDB::bind_method(D_METHOD("is_class", "class"), &Object::is_class);
@@ -1557,7 +1551,7 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_block_signals", "enable"), &Object::set_block_signals);
ClassDB::bind_method(D_METHOD("is_blocking_signals"), &Object::is_blocking_signals);
- ClassDB::bind_method(D_METHOD("property_list_changed_notify"), &Object::property_list_changed_notify);
+ ClassDB::bind_method(D_METHOD("notify_property_list_changed"), &Object::notify_property_list_changed);
ClassDB::bind_method(D_METHOD("set_message_translation", "enable"), &Object::set_message_translation);
ClassDB::bind_method(D_METHOD("can_translate_messages"), &Object::can_translate_messages);
@@ -1569,6 +1563,7 @@ void Object::_bind_methods() {
ClassDB::add_virtual_method("Object", MethodInfo("free"), false);
ADD_SIGNAL(MethodInfo("script_changed"));
+ ADD_SIGNAL(MethodInfo("property_list_changed"));
BIND_VMETHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what")));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value")));
@@ -1732,7 +1727,7 @@ void *Object::get_script_instance_binding(int p_script_language_index) {
if (!_script_instance_bindings[p_script_language_index]) {
void *script_data = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this);
if (script_data) {
- atomic_increment(&instance_binding_count);
+ instance_binding_count.increment();
_script_instance_bindings[p_script_language_index] = script_data;
}
}
diff --git a/core/object/object.h b/core/object/object.h
index 6e2328848b..448a33d3bc 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,6 +37,7 @@
#include "core/templates/hash_map.h"
#include "core/templates/list.h"
#include "core/templates/map.h"
+#include "core/templates/safe_refcount.h"
#include "core/templates/set.h"
#include "core/templates/vmap.h"
#include "core/variant/callable_bind.h"
@@ -65,8 +66,10 @@ enum PropertyHint {
PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
PROPERTY_HINT_LAYERS_2D_RENDER,
PROPERTY_HINT_LAYERS_2D_PHYSICS,
+ PROPERTY_HINT_LAYERS_2D_NAVIGATION,
PROPERTY_HINT_LAYERS_3D_RENDER,
PROPERTY_HINT_LAYERS_3D_PHYSICS,
+ PROPERTY_HINT_LAYERS_3D_NAVIGATION,
PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
PROPERTY_HINT_DIR, ///< a directory path must be passed
PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
@@ -125,6 +128,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 25, // Used in inspector to increment property when keyed in animation player
PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 26, // when loading, the resource for this property can be set at the end of loading
PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 27, // For Object properties, instantiate them when creating in editor.
+ PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 28, //for project or editor settings, show when basic settings are selected
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
@@ -454,7 +458,6 @@ private:
#endif
bool _block_signals = false;
int _predelete_ok = 0;
- Set<Object *> change_receptors;
ObjectID _instance_id;
bool _predelete();
void _postinitialize();
@@ -486,7 +489,7 @@ private:
friend class Reference;
bool type_is_reference = false;
- uint32_t instance_binding_count = 0;
+ SafeNumeric<uint32_t> instance_binding_count;
void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS];
Object(bool p_reference);
@@ -523,9 +526,6 @@ protected:
static void get_valid_parents_static(List<String> *p_parents);
static void _get_valid_parents_static(List<String> *p_parents);
- void property_list_changed_notify();
- virtual void _changed_callback(Object *p_changed, const char *p_prop);
-
//Variant _call_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant());
//void _call_deferred_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant());
@@ -555,16 +555,8 @@ public: //should be protected, but bug in clang++
_FORCE_INLINE_ static void register_custom_data_to_otdb() {}
public:
-#ifdef TOOLS_ENABLED
- _FORCE_INLINE_ void _change_notify(const char *p_property = "") {
- _edited = true;
- for (Set<Object *>::Element *E = change_receptors.front(); E; E = E->next()) {
- ((Object *)(E->get()))->_changed_callback(this, p_property);
- }
- }
-#else
- _FORCE_INLINE_ void _change_notify(const char *p_what = "") {}
-#endif
+ void notify_property_list_changed();
+
static void *get_class_ptr_static() {
static int ptr;
return &ptr;
@@ -574,10 +566,6 @@ public:
_FORCE_INLINE_ ObjectID get_instance_id() const { return _instance_id; }
- // this is used for editors
- void add_change_receptor(Object *p_receptor);
- void remove_change_receptor(Object *p_receptor);
-
template <class T>
static T *cast_to(Object *p_object) {
#ifndef NO_SAFE_CAST
diff --git a/core/object/object_id.h b/core/object/object_id.h
index 63b0c27af8..7f2496ad48 100644
--- a/core/object/object_id.h
+++ b/core/object/object_id.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/reference.cpp b/core/object/reference.cpp
index ce95d83dfc..22e4e8a336 100644
--- a/core/object/reference.cpp
+++ b/core/object/reference.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -62,7 +62,7 @@ bool Reference::reference() {
if (get_script_instance()) {
get_script_instance()->refcount_incremented();
}
- if (instance_binding_count > 0 && !ScriptServer::are_languages_finished()) {
+ if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) {
for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
if (_script_instance_bindings[i]) {
ScriptServer::get_language(i)->refcount_incremented_instance_binding(this);
@@ -83,7 +83,7 @@ bool Reference::unreference() {
bool script_ret = get_script_instance()->refcount_decremented();
die = die && script_ret;
}
- if (instance_binding_count > 0 && !ScriptServer::are_languages_finished()) {
+ if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) {
for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
if (_script_instance_bindings[i]) {
bool script_ret = ScriptServer::get_language(i)->refcount_decremented_instance_binding(this);
diff --git a/core/object/reference.h b/core/object/reference.h
index 0eb127f362..d02cb12069 100644
--- a/core/object/reference.h
+++ b/core/object/reference.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index 17ac75e19f..42fb0a0caf 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -275,7 +275,15 @@ void ScriptServer::save_global_classes() {
gcarr.push_back(d);
}
- if (gcarr.empty()) {
+ Array old;
+ if (ProjectSettings::get_singleton()->has_setting("_global_script_classes")) {
+ old = ProjectSettings::get_singleton()->get("_global_script_classes");
+ }
+ if ((!old.is_empty() || gcarr.is_empty()) && gcarr.hash() == old.hash()) {
+ return;
+ }
+
+ if (gcarr.is_empty()) {
if (ProjectSettings::get_singleton()->has_setting("_global_script_classes")) {
ProjectSettings::get_singleton()->clear("_global_script_classes");
}
@@ -515,7 +523,7 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c
}
if (owner && owner->get_script_instance() == this) {
- owner->_change_notify();
+ owner->notify_property_list_changed();
}
//change notify
diff --git a/core/object/script_language.h b/core/object/script_language.h
index f5d65cf42d..f9898ccd0c 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp
index 65bae6f6e8..e8735e335c 100644
--- a/core/object/undo_redo.cpp
+++ b/core/object/undo_redo.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,6 +53,23 @@ void UndoRedo::_discard_redo() {
actions.resize(current_action + 1);
}
+bool UndoRedo::_redo(bool p_execute) {
+ ERR_FAIL_COND_V(action_level > 0, false);
+
+ if ((current_action + 1) >= actions.size()) {
+ return false; //nothing to redo
+ }
+
+ current_action++;
+ if (p_execute) {
+ _process_operation_list(actions.write[current_action].do_ops.front());
+ }
+ version++;
+ emit_signal("version_changed");
+
+ return true;
+}
+
void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
uint32_t ticks = OS::get_singleton()->get_ticks_msec();
@@ -242,7 +259,7 @@ bool UndoRedo::is_committing_action() const {
return committing > 0;
}
-void UndoRedo::commit_action() {
+void UndoRedo::commit_action(bool p_execute) {
ERR_FAIL_COND(action_level <= 0);
action_level--;
if (action_level > 0) {
@@ -255,8 +272,9 @@ void UndoRedo::commit_action() {
}
committing++;
- redo(); // perform action
+ _redo(p_execute); // perform action
committing--;
+
if (callback && actions.size() > 0) {
callback(callback_ud, actions[actions.size() - 1].name);
}
@@ -323,19 +341,7 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
}
bool UndoRedo::redo() {
- ERR_FAIL_COND_V(action_level > 0, false);
-
- if ((current_action + 1) >= actions.size()) {
- return false; //nothing to redo
- }
-
- current_action++;
-
- _process_operation_list(actions.write[current_action].do_ops.front());
- version++;
- emit_signal("version_changed");
-
- return true;
+ return _redo(true);
}
bool UndoRedo::undo() {
@@ -351,6 +357,24 @@ bool UndoRedo::undo() {
return true;
}
+int UndoRedo::get_history_count() {
+ ERR_FAIL_COND_V(action_level > 0, -1);
+
+ return actions.size();
+}
+
+int UndoRedo::get_current_action() {
+ ERR_FAIL_COND_V(action_level > 0, -1);
+
+ return current_action;
+}
+
+String UndoRedo::get_action_name(int p_id) {
+ ERR_FAIL_INDEX_V(p_id, actions.size(), "");
+
+ return actions[p_id].name;
+}
+
void UndoRedo::clear_history(bool p_increase_version) {
ERR_FAIL_COND(action_level > 0);
_discard_redo();
@@ -480,7 +504,7 @@ Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Calla
void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE));
- ClassDB::bind_method(D_METHOD("commit_action"), &UndoRedo::commit_action);
+ ClassDB::bind_method(D_METHOD("commit_action", "execute"), &UndoRedo::commit_action, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_committing_action"), &UndoRedo::is_committing_action);
{
@@ -505,8 +529,14 @@ void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_undo_property", "object", "property", "value"), &UndoRedo::add_undo_property);
ClassDB::bind_method(D_METHOD("add_do_reference", "object"), &UndoRedo::add_do_reference);
ClassDB::bind_method(D_METHOD("add_undo_reference", "object"), &UndoRedo::add_undo_reference);
+
+ ClassDB::bind_method(D_METHOD("get_history_count"), &UndoRedo::get_history_count);
+ ClassDB::bind_method(D_METHOD("get_current_action"), &UndoRedo::get_current_action);
+ ClassDB::bind_method(D_METHOD("get_action_name", "id"), &UndoRedo::get_action_name);
ClassDB::bind_method(D_METHOD("clear_history", "increase_version"), &UndoRedo::clear_history, DEFVAL(true));
+
ClassDB::bind_method(D_METHOD("get_current_action_name"), &UndoRedo::get_current_action_name);
+
ClassDB::bind_method(D_METHOD("has_undo"), &UndoRedo::has_undo);
ClassDB::bind_method(D_METHOD("has_redo"), &UndoRedo::has_redo);
ClassDB::bind_method(D_METHOD("get_version"), &UndoRedo::get_version);
diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h
index 06c2759a65..a08ca7792f 100644
--- a/core/object/undo_redo.h
+++ b/core/object/undo_redo.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -84,6 +84,7 @@ private:
void _pop_history_tail();
void _process_operation_list(List<Operation>::Element *E);
void _discard_redo();
+ bool _redo(bool p_execute);
CommitNotifyCallback callback = nullptr;
void *callback_ud = nullptr;
@@ -109,11 +110,15 @@ public:
void add_undo_reference(Object *p_object);
bool is_committing_action() const;
- void commit_action();
+ void commit_action(bool p_execute = true);
bool redo();
bool undo();
String get_current_action_name() const;
+
+ int get_history_count();
+ int get_current_action();
+ String get_action_name(int p_id);
void clear_history(bool p_increase_version = true);
bool has_undo();
diff --git a/core/os/copymem.h b/core/os/copymem.h
index 04ea3caeff..6fd559356c 100644
--- a/core/os/copymem.h
+++ b/core/os/copymem.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 30b1b51b53..b7c3a17ba9 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -170,7 +170,7 @@ Error DirAccess::make_dir_recursive(String p_dir) {
curpath = curpath.plus_file(subdirs[i]);
Error err = make_dir(curpath);
if (err != OK && err != ERR_ALREADY_EXISTS) {
- ERR_FAIL_V(err);
+ ERR_FAIL_V_MSG(err, "Could not create directory: " + curpath);
}
}
diff --git a/core/os/dir_access.h b/core/os/dir_access.h
index 17f84d3c52..c49c4cc4b8 100644
--- a/core/os/dir_access.h
+++ b/core/os/dir_access.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index aa95f06cff..5a3df88619 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/file_access.h b/core/os/file_access.h
index 777c82bbd7..1c78204c1d 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp
index ef341987dc..4b2cafd8fe 100644
--- a/core/os/keyboard.cpp
+++ b/core/os/keyboard.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index 67c60a2dbe..3ef70e786f 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index 9252ba0840..016d9d0a09 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,8 +34,8 @@
void MainLoop::_bind_methods() {
BIND_VMETHOD(MethodInfo("_initialize"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_iteration", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_idle", PropertyInfo(Variant::FLOAT, "delta")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_physics_process", PropertyInfo(Variant::FLOAT, "delta")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_process", PropertyInfo(Variant::FLOAT, "delta")));
BIND_VMETHOD(MethodInfo("_finalize"));
BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
@@ -52,13 +52,13 @@ void MainLoop::_bind_methods() {
ADD_SIGNAL(MethodInfo("on_request_permissions_result", PropertyInfo(Variant::STRING, "permission"), PropertyInfo(Variant::BOOL, "granted")));
};
-void MainLoop::set_init_script(const Ref<Script> &p_init_script) {
- init_script = p_init_script;
+void MainLoop::set_initialize_script(const Ref<Script> &p_initialize_script) {
+ initialize_script = p_initialize_script;
}
-void MainLoop::init() {
- if (init_script.is_valid()) {
- set_script(init_script);
+void MainLoop::initialize() {
+ if (initialize_script.is_valid()) {
+ set_script(initialize_script);
}
if (get_script_instance()) {
@@ -66,23 +66,23 @@ void MainLoop::init() {
}
}
-bool MainLoop::iteration(float p_time) {
+bool MainLoop::physics_process(float p_time) {
if (get_script_instance()) {
- return get_script_instance()->call("_iteration", p_time);
+ return get_script_instance()->call("_physics_process", p_time);
}
return false;
}
-bool MainLoop::idle(float p_time) {
+bool MainLoop::process(float p_time) {
if (get_script_instance()) {
- return get_script_instance()->call("_idle", p_time);
+ return get_script_instance()->call("_process", p_time);
}
return false;
}
-void MainLoop::finish() {
+void MainLoop::finalize() {
if (get_script_instance()) {
get_script_instance()->call("_finalize");
set_script(Variant()); //clear script
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index 7bc91fbb83..25a09fe98f 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,7 +39,7 @@ class MainLoop : public Object {
GDCLASS(MainLoop, Object);
OBJ_CATEGORY("Main Loop");
- Ref<Script> init_script;
+ Ref<Script> initialize_script;
protected:
static void _bind_methods();
@@ -59,12 +59,12 @@ public:
NOTIFICATION_TEXT_SERVER_CHANGED = 2018,
};
- virtual void init();
- virtual bool iteration(float p_time);
- virtual bool idle(float p_time);
- virtual void finish();
+ virtual void initialize();
+ virtual bool physics_process(float p_time);
+ virtual bool process(float p_time);
+ virtual void finalize();
- void set_init_script(const Ref<Script> &p_init_script);
+ void set_initialize_script(const Ref<Script> &p_initialize_script);
MainLoop() {}
virtual ~MainLoop() {}
diff --git a/core/os/memory.cpp b/core/os/memory.cpp
index f2723d13f6..5910cb0e7b 100644
--- a/core/os/memory.cpp
+++ b/core/os/memory.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -60,11 +60,11 @@ void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_d
#endif
#ifdef DEBUG_ENABLED
-uint64_t Memory::mem_usage = 0;
-uint64_t Memory::max_usage = 0;
+SafeNumeric<uint64_t> Memory::mem_usage;
+SafeNumeric<uint64_t> Memory::max_usage;
#endif
-uint64_t Memory::alloc_count = 0;
+SafeNumeric<uint64_t> Memory::alloc_count;
void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
#ifdef DEBUG_ENABLED
@@ -77,7 +77,7 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
ERR_FAIL_COND_V(!mem, nullptr);
- atomic_increment(&alloc_count);
+ alloc_count.increment();
if (prepad) {
uint64_t *s = (uint64_t *)mem;
@@ -86,8 +86,8 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
uint8_t *s8 = (uint8_t *)mem;
#ifdef DEBUG_ENABLED
- atomic_add(&mem_usage, p_bytes);
- atomic_exchange_if_greater(&max_usage, mem_usage);
+ uint64_t new_mem_usage = mem_usage.add(p_bytes);
+ max_usage.exchange_if_greater(new_mem_usage);
#endif
return s8 + PAD_ALIGN;
} else {
@@ -114,10 +114,10 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
#ifdef DEBUG_ENABLED
if (p_bytes > *s) {
- atomic_add(&mem_usage, p_bytes - *s);
- atomic_exchange_if_greater(&max_usage, mem_usage);
+ uint64_t new_mem_usage = mem_usage.add(p_bytes - *s);
+ max_usage.exchange_if_greater(new_mem_usage);
} else {
- atomic_sub(&mem_usage, *s - p_bytes);
+ mem_usage.sub(*s - p_bytes);
}
#endif
@@ -156,14 +156,14 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
bool prepad = p_pad_align;
#endif
- atomic_decrement(&alloc_count);
+ alloc_count.decrement();
if (prepad) {
mem -= PAD_ALIGN;
#ifdef DEBUG_ENABLED
uint64_t *s = (uint64_t *)mem;
- atomic_sub(&mem_usage, *s);
+ mem_usage.sub(*s);
#endif
free(mem);
@@ -178,7 +178,7 @@ uint64_t Memory::get_mem_available() {
uint64_t Memory::get_mem_usage() {
#ifdef DEBUG_ENABLED
- return mem_usage;
+ return mem_usage.get();
#else
return 0;
#endif
@@ -186,7 +186,7 @@ uint64_t Memory::get_mem_usage() {
uint64_t Memory::get_mem_max_usage() {
#ifdef DEBUG_ENABLED
- return max_usage;
+ return max_usage.get();
#else
return 0;
#endif
diff --git a/core/os/memory.h b/core/os/memory.h
index dee08d4de4..10e678103d 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,11 +43,11 @@
class Memory {
Memory();
#ifdef DEBUG_ENABLED
- static uint64_t mem_usage;
- static uint64_t max_usage;
+ static SafeNumeric<uint64_t> mem_usage;
+ static SafeNumeric<uint64_t> max_usage;
#endif
- static uint64_t alloc_count;
+ static SafeNumeric<uint64_t> alloc_count;
public:
static void *alloc_static(size_t p_bytes, bool p_pad_align = false);
diff --git a/core/os/midi_driver.cpp b/core/os/midi_driver.cpp
index e9919aeb86..a8be84c56c 100644
--- a/core/os/midi_driver.cpp
+++ b/core/os/midi_driver.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/midi_driver.h b/core/os/midi_driver.h
index f487b31d4c..ccf624e07e 100644
--- a/core/os/midi_driver.h
+++ b/core/os/midi_driver.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp
index 31a0dc2bfa..b7d7752d35 100644
--- a/core/os/mutex.cpp
+++ b/core/os/mutex.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/mutex.h b/core/os/mutex.h
index 778bdaba09..d77ec362a1 100644
--- a/core/os/mutex.h
+++ b/core/os/mutex.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 9400565484..182bab4058 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/os.h b/core/os/os.h
index 3c79d7bb87..e41d788e12 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,6 +40,7 @@
#include "core/templates/vector.h"
#include <stdarg.h>
+#include <stdlib.h>
class OS {
static OS *singleton;
@@ -53,7 +54,7 @@ class OS {
bool _debug_stdout = false;
String _local_clipboard;
bool _no_window = false;
- int _exit_code = 0;
+ int _exit_code = EXIT_FAILURE; // unexpected exit is marked as failure
int _orientation;
bool _allow_hidpi = false;
bool _allow_layered = false;
@@ -129,7 +130,8 @@ public:
virtual int get_low_processor_usage_mode_sleep_usec() const;
virtual String get_executable_path() const;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) = 0;
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) = 0;
+ virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) = 0;
virtual Error kill(const ProcessID &p_pid) = 0;
virtual int get_process_id() const;
virtual void vibrate_handheld(int p_duration_ms = 500);
@@ -148,11 +150,6 @@ public:
bool is_layered_allowed() const { return _allow_layered; }
bool is_hidpi_allowed() const { return _allow_hidpi; }
- virtual int get_tablet_driver_count() const { return 0; };
- virtual String get_tablet_driver_name(int p_driver) const { return ""; };
- virtual String get_current_tablet_driver() const { return ""; };
- virtual void set_current_tablet_driver(const String &p_driver){};
-
void ensure_user_data_dir();
virtual MainLoop *get_main_loop() const = 0;
diff --git a/core/os/pool_allocator.cpp b/core/os/pool_allocator.cpp
index 52536ff45d..b538ca0c96 100644
--- a/core/os/pool_allocator.cpp
+++ b/core/os/pool_allocator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/pool_allocator.h b/core/os/pool_allocator.h
index c67b4d7fa2..15e50dac90 100644
--- a/core/os/pool_allocator.h
+++ b/core/os/pool_allocator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h
index 1190102a83..560ec57a5f 100644
--- a/core/os/rw_lock.h
+++ b/core/os/rw_lock.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,55 +33,83 @@
#include "core/error/error_list.h"
+#if !defined(NO_THREADS)
+
+#include <shared_mutex>
+
class RWLock {
-protected:
- static RWLock *(*create_func)();
+ mutable std::shared_timed_mutex mutex;
public:
- virtual void read_lock() = 0; ///< Lock the rwlock, block if locked by someone else
- virtual void read_unlock() = 0; ///< Unlock the rwlock, let other threads continue
- virtual Error read_try_lock() = 0; ///< Attempt to lock the rwlock, OK on success, ERROR means it can't lock.
+ // Lock the rwlock, block if locked by someone else
+ void read_lock() const {
+ mutex.lock_shared();
+ }
- virtual void write_lock() = 0; ///< Lock the rwlock, block if locked by someone else
- virtual void write_unlock() = 0; ///< Unlock the rwlock, let other thwrites continue
- virtual Error write_try_lock() = 0; ///< Attempt to lock the rwlock, OK on success, ERROR means it can't lock.
+ // Unlock the rwlock, let other threads continue
+ void read_unlock() const {
+ mutex.unlock_shared();
+ }
- static RWLock *create(); ///< Create a rwlock
+ // Attempt to lock the rwlock, OK on success, ERR_BUSY means it can't lock.
+ Error read_try_lock() const {
+ return mutex.try_lock_shared() ? OK : ERR_BUSY;
+ }
+
+ // Lock the rwlock, block if locked by someone else
+ void write_lock() {
+ mutex.lock();
+ }
+
+ // Unlock the rwlock, let other thwrites continue
+ void write_unlock() {
+ mutex.unlock();
+ }
- virtual ~RWLock() {}
+ // Attempt to lock the rwlock, OK on success, ERR_BUSY means it can't lock.
+ Error write_try_lock() {
+ return mutex.try_lock() ? OK : ERR_BUSY;
+ }
+};
+
+#else
+
+class RWLock {
+public:
+ void read_lock() const {}
+ void read_unlock() const {}
+ Error read_try_lock() const { return OK; }
+
+ void write_lock() {}
+ void write_unlock() {}
+ Error write_try_lock() { return OK; }
};
+#endif
+
class RWLockRead {
- RWLock *lock;
+ const RWLock &lock;
public:
- RWLockRead(const RWLock *p_lock) {
- lock = const_cast<RWLock *>(p_lock);
- if (lock) {
- lock->read_lock();
- }
+ RWLockRead(const RWLock &p_lock) :
+ lock(p_lock) {
+ lock.read_lock();
}
~RWLockRead() {
- if (lock) {
- lock->read_unlock();
- }
+ lock.read_unlock();
}
};
class RWLockWrite {
- RWLock *lock;
+ RWLock &lock;
public:
- RWLockWrite(RWLock *p_lock) {
- lock = p_lock;
- if (lock) {
- lock->write_lock();
- }
+ RWLockWrite(RWLock &p_lock) :
+ lock(p_lock) {
+ lock.write_lock();
}
~RWLockWrite() {
- if (lock) {
- lock->write_unlock();
- }
+ lock.write_unlock();
}
};
diff --git a/core/os/semaphore.h b/core/os/semaphore.h
index b170cada3a..01ae7a3c65 100644
--- a/core/os/semaphore.h
+++ b/core/os/semaphore.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/spin_lock.h b/core/os/spin_lock.h
index 1bb810bb29..929e8b9a58 100644
--- a/core/os/spin_lock.h
+++ b/core/os/spin_lock.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/thread.cpp b/core/os/thread.cpp
index fc0ce3c9b4..73e31bdb3d 100644
--- a/core/os/thread.cpp
+++ b/core/os/thread.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,30 +30,77 @@
#include "thread.h"
-Thread *(*Thread::create_func)(ThreadCreateCallback, void *, const Settings &) = nullptr;
-Thread::ID (*Thread::get_thread_id_func)() = nullptr;
-void (*Thread::wait_to_finish_func)(Thread *) = nullptr;
+#include "core/object/script_language.h"
+
+#if !defined(NO_THREADS)
+
+#include "core/templates/safe_refcount.h"
+
Error (*Thread::set_name_func)(const String &) = nullptr;
+void (*Thread::set_priority_func)(Thread::Priority) = nullptr;
+void (*Thread::init_func)() = nullptr;
+void (*Thread::term_func)() = nullptr;
+
+uint64_t Thread::_thread_id_hash(const std::thread::id &p_t) {
+ static std::hash<std::thread::id> hasher;
+ return hasher(p_t);
+}
-Thread::ID Thread::_main_thread_id = 0;
+Thread::ID Thread::main_thread_id = _thread_id_hash(std::this_thread::get_id());
+thread_local Thread::ID Thread::caller_id = 0;
-Thread::ID Thread::get_caller_id() {
- if (get_thread_id_func) {
- return get_thread_id_func();
+void Thread::_set_platform_funcs(
+ Error (*p_set_name_func)(const String &),
+ void (*p_set_priority_func)(Thread::Priority),
+ void (*p_init_func)(),
+ void (*p_term_func)()) {
+ Thread::set_name_func = p_set_name_func;
+ Thread::set_priority_func = p_set_priority_func;
+ Thread::init_func = p_init_func;
+ Thread::term_func = p_term_func;
+}
+
+void Thread::callback(Thread *p_self, const Settings &p_settings, Callback p_callback, void *p_userdata) {
+ Thread::caller_id = _thread_id_hash(p_self->thread.get_id());
+ if (set_priority_func) {
+ set_priority_func(p_settings.priority);
+ }
+ if (init_func) {
+ init_func();
+ }
+ ScriptServer::thread_enter(); //scripts may need to attach a stack
+ p_callback(p_userdata);
+ ScriptServer::thread_exit();
+ if (term_func) {
+ term_func();
}
- return 0;
}
-Thread *Thread::create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings) {
- if (create_func) {
- return create_func(p_callback, p_user, p_settings);
+void Thread::start(Thread::Callback p_callback, void *p_user, const Settings &p_settings) {
+ if (id != _thread_id_hash(std::thread::id())) {
+#ifdef DEBUG_ENABLED
+ WARN_PRINT("A Thread object has been re-started without wait_to_finish() having been called on it. Please do so to ensure correct cleanup of the thread.");
+#endif
+ thread.detach();
+ std::thread empty_thread;
+ thread.swap(empty_thread);
}
- return nullptr;
+ std::thread new_thread(&Thread::callback, this, p_settings, p_callback, p_user);
+ thread.swap(new_thread);
+ id = _thread_id_hash(thread.get_id());
}
-void Thread::wait_to_finish(Thread *p_thread) {
- if (wait_to_finish_func) {
- wait_to_finish_func(p_thread);
+bool Thread::is_started() const {
+ return id != _thread_id_hash(std::thread::id());
+}
+
+void Thread::wait_to_finish() {
+ if (id != _thread_id_hash(std::thread::id())) {
+ ERR_FAIL_COND_MSG(id == get_caller_id(), "A Thread can't wait for itself to finish.");
+ thread.join();
+ std::thread empty_thread;
+ thread.swap(empty_thread);
+ id = _thread_id_hash(std::thread::id());
}
}
@@ -64,3 +111,18 @@ Error Thread::set_name(const String &p_name) {
return ERR_UNAVAILABLE;
}
+
+Thread::Thread() {
+ caller_id = _thread_id_hash(std::this_thread::get_id());
+}
+
+Thread::~Thread() {
+ if (id != _thread_id_hash(std::thread::id())) {
+#ifdef DEBUG_ENABLED
+ WARN_PRINT("A Thread object has been destroyed without wait_to_finish() having been called on it. Please do so to ensure correct cleanup of the thread.");
+#endif
+ thread.detach();
+ }
+}
+
+#endif
diff --git a/core/os/thread.h b/core/os/thread.h
index b87ec84313..17ac82c650 100644
--- a/core/os/thread.h
+++ b/core/os/thread.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,13 +31,21 @@
#ifndef THREAD_H
#define THREAD_H
-#include "core/string/ustring.h"
#include "core/typedefs.h"
-typedef void (*ThreadCreateCallback)(void *p_userdata);
+#if !defined(NO_THREADS)
+#include "core/templates/safe_refcount.h"
+#include <thread>
+#endif
+
+class String;
class Thread {
public:
+ typedef void (*Callback)(void *p_userdata);
+
+ typedef uint64_t ID;
+
enum Priority {
PRIORITY_LOW,
PRIORITY_NORMAL,
@@ -49,30 +57,62 @@ public:
Settings() { priority = PRIORITY_NORMAL; }
};
- typedef uint64_t ID;
+private:
+#if !defined(NO_THREADS)
+ friend class Main;
-protected:
- static Thread *(*create_func)(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID (*get_thread_id_func)();
- static void (*wait_to_finish_func)(Thread *);
- static Error (*set_name_func)(const String &);
+ static ID main_thread_id;
- friend class Main;
+ static uint64_t _thread_id_hash(const std::thread::id &p_t);
+
+ ID id = _thread_id_hash(std::thread::id());
+ static thread_local ID caller_id;
+ std::thread thread;
- static ID _main_thread_id;
+ static void callback(Thread *p_self, const Settings &p_settings, Thread::Callback p_callback, void *p_userdata);
- Thread() {}
+ static Error (*set_name_func)(const String &);
+ static void (*set_priority_func)(Thread::Priority);
+ static void (*init_func)();
+ static void (*term_func)();
+#endif
public:
- virtual ID get_id() const = 0;
+ static void _set_platform_funcs(
+ Error (*p_set_name_func)(const String &),
+ void (*p_set_priority_func)(Thread::Priority),
+ void (*p_init_func)() = nullptr,
+ void (*p_term_func)() = nullptr);
+
+#if !defined(NO_THREADS)
+ _FORCE_INLINE_ ID get_id() const { return id; }
+ // get the ID of the caller thread
+ _FORCE_INLINE_ static ID get_caller_id() { return caller_id; }
+ // get the ID of the main thread
+ _FORCE_INLINE_ static ID get_main_id() { return main_thread_id; }
static Error set_name(const String &p_name);
- _FORCE_INLINE_ static ID get_main_id() { return _main_thread_id; } ///< get the ID of the main thread
- static ID get_caller_id(); ///< get the ID of the caller function ID
- static void wait_to_finish(Thread *p_thread); ///< waits until thread is finished, and deallocates it.
- static Thread *create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings = Settings()); ///< Static function to create a thread, will call p_callback
- virtual ~Thread() {}
+ void start(Thread::Callback p_callback, void *p_user, const Settings &p_settings = Settings());
+ bool is_started() const;
+ ///< waits until thread is finished, and deallocates it.
+ void wait_to_finish();
+
+ Thread();
+ ~Thread();
+#else
+ _FORCE_INLINE_ ID get_id() const { return 0; }
+ // get the ID of the caller thread
+ _FORCE_INLINE_ static ID get_caller_id() { return 0; }
+ // get the ID of the main thread
+ _FORCE_INLINE_ static ID get_main_id() { return 0; }
+
+ static Error set_name(const String &p_name) { return ERR_UNAVAILABLE; }
+
+ void start(Thread::Callback p_callback, void *p_user, const Settings &p_settings = Settings()) {}
+ bool is_started() const { return false; }
+ void wait_to_finish() {}
+#endif
};
#endif // THREAD_H
diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h
deleted file mode 100644
index 37d9ee0846..0000000000
--- a/core/os/thread_dummy.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*************************************************************************/
-/* thread_dummy.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef THREAD_DUMMY_H
-#define THREAD_DUMMY_H
-
-#include "core/os/rw_lock.h"
-#include "core/os/semaphore.h"
-#include "core/os/thread.h"
-
-class ThreadDummy : public Thread {
- static Thread *create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings = Settings());
-
-public:
- virtual ID get_id() const { return 0; };
-
- static void make_default();
-};
-
-class RWLockDummy : public RWLock {
- static RWLock *create();
-
-public:
- virtual void read_lock() {}
- virtual void read_unlock() {}
- virtual Error read_try_lock() { return OK; }
-
- virtual void write_lock() {}
- virtual void write_unlock() {}
- virtual Error write_try_lock() { return OK; }
-
- static void make_default();
-};
-
-#endif // THREAD_DUMMY_H
diff --git a/core/os/thread_safe.h b/core/os/thread_safe.h
index 670ee8b125..81de079bf3 100644
--- a/core/os/thread_safe.h
+++ b/core/os/thread_safe.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h
index ed141a5339..fec6473589 100644
--- a/core/os/threaded_array_processor.h
+++ b/core/os/threaded_array_processor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@
template <class C, class U>
struct ThreadArrayProcessData {
uint32_t elements;
- uint32_t index;
+ SafeNumeric<uint32_t> index;
C *instance;
U userdata;
void (C::*method)(uint32_t, U);
@@ -56,7 +56,7 @@ template <class T>
void process_array_thread(void *ud) {
T &data = *(T *)ud;
while (true) {
- uint32_t index = atomic_increment(&data.index);
+ uint32_t index = data.index.increment();
if (index >= data.elements) {
break;
}
@@ -70,22 +70,21 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us
data.method = p_method;
data.instance = p_instance;
data.userdata = p_userdata;
- data.index = 0;
+ data.index.set(0);
data.elements = p_elements;
- data.process(data.index); //process first, let threads increment for next
+ data.process(0); //process first, let threads increment for next
- Vector<Thread *> threads;
+ int thread_count = OS::get_singleton()->get_processor_count();
+ Thread *threads = memnew_arr(Thread, thread_count);
- threads.resize(OS::get_singleton()->get_processor_count());
-
- for (int i = 0; i < threads.size(); i++) {
- threads.write[i] = Thread::create(process_array_thread<ThreadArrayProcessData<C, U>>, &data);
+ for (int i = 0; i < thread_count; i++) {
+ threads[i].start(process_array_thread<ThreadArrayProcessData<C, U>>, &data);
}
- for (int i = 0; i < threads.size(); i++) {
- Thread::wait_to_finish(threads[i]);
- memdelete(threads[i]);
+ for (int i = 0; i < thread_count; i++) {
+ threads[i].wait_to_finish();
}
+ memdelete_arr(threads);
}
#else
@@ -96,7 +95,7 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us
data.method = p_method;
data.instance = p_instance;
data.userdata = p_userdata;
- data.index = 0;
+ data.index.set(0);
data.elements = p_elements;
for (uint32_t i = 0; i < p_elements; i++) {
data.process(i);
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 9883ce12a0..b58abc81d1 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -103,7 +103,6 @@ void register_core_types() {
static_assert(sizeof(Callable) <= 16);
ObjectDB::setup();
- ResourceCache::setup();
StringName::setup();
ResourceLoader::initialize();
diff --git a/core/register_core_types.h b/core/register_core_types.h
index bdd335f33c..baf7ddbe65 100644
--- a/core/register_core_types.h
+++ b/core/register_core_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/compressed_translation.cpp b/core/string/compressed_translation.cpp
index bdb296a79b..ad90924293 100644
--- a/core/string/compressed_translation.cpp
+++ b/core/string/compressed_translation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/compressed_translation.h b/core/string/compressed_translation.h
index efb3535362..0abb770178 100644
--- a/core/string/compressed_translation.h
+++ b/core/string/compressed_translation.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp
index a63dde5b41..d3afa7b4dd 100644
--- a/core/string/node_path.cpp
+++ b/core/string/node_path.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/node_path.h b/core/string/node_path.h
index b4513ddb3c..26e15636d9 100644
--- a/core/string/node_path.h
+++ b/core/string/node_path.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/print_string.cpp b/core/string/print_string.cpp
index 54de229471..345371d733 100644
--- a/core/string/print_string.cpp
+++ b/core/string/print_string.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/print_string.h b/core/string/print_string.h
index 3e8f244cc5..1a9ff1efd6 100644
--- a/core/string/print_string.h
+++ b/core/string/print_string.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/string_buffer.h b/core/string/string_buffer.h
index 1317b538d4..33897c3674 100644
--- a/core/string/string_buffer.h
+++ b/core/string/string_buffer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@ class StringBuffer {
int string_length = 0;
_FORCE_INLINE_ char32_t *current_buffer_ptr() {
- return static_cast<String &>(buffer).empty() ? short_buffer : buffer.ptrw();
+ return static_cast<String &>(buffer).is_empty() ? short_buffer : buffer.ptrw();
}
public:
@@ -122,7 +122,7 @@ StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::reserve(int p_
return *this;
}
- bool need_copy = string_length > 0 && buffer.empty();
+ bool need_copy = string_length > 0 && buffer.is_empty();
buffer.resize(next_power_of_2(p_size));
if (need_copy) {
memcpy(buffer.ptrw(), short_buffer, string_length * sizeof(char32_t));
@@ -139,7 +139,7 @@ int StringBuffer<SHORT_BUFFER_SIZE>::length() const {
template <int SHORT_BUFFER_SIZE>
String StringBuffer<SHORT_BUFFER_SIZE>::as_string() {
current_buffer_ptr()[string_length] = '\0';
- if (buffer.empty()) {
+ if (buffer.is_empty()) {
return String(short_buffer);
} else {
buffer.resize(string_length + 1);
diff --git a/core/string/string_builder.cpp b/core/string/string_builder.cpp
index dec299ffa3..834c87c845 100644
--- a/core/string/string_builder.cpp
+++ b/core/string/string_builder.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/string_builder.h b/core/string/string_builder.h
index c732f1b9ea..30ce2a06f7 100644
--- a/core/string/string_builder.h
+++ b/core/string/string_builder.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp
index 34afdaee38..14b87072bb 100644
--- a/core/string/string_name.cpp
+++ b/core/string/string_name.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/string_name.h b/core/string/string_name.h
index 320f63bf68..44d0ea14fa 100644
--- a/core/string/string_name.h
+++ b/core/string/string_name.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -83,7 +83,7 @@ class StringName {
StringName(_Data *p_data) { _data = p_data; }
public:
- operator const void *() const { return (_data && (_data->cname || !_data->name.empty())) ? (void *)1 : nullptr; }
+ operator const void *() const { return (_data && (_data->cname || !_data->name.is_empty())) ? (void *)1 : nullptr; }
bool operator==(const String &p_name) const;
bool operator==(const char *p_name) const;
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index 7b8c28e2e2..9cee218735 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,13 +39,14 @@
#include "main/main.h"
#endif
-// ISO 639-1 language codes, with the addition of glibc locales with their
-// regional identifiers. This list must match the language names (in English)
-// of locale_names.
+// ISO 639-1 language codes (and a couple of three-letter ISO 639-2 codes),
+// with the addition of glibc locales with their regional identifiers.
+// This list must match the language names (in English) of locale_names.
//
// References:
// - https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
// - https://lh.2xlibre.net/locales/
+// - https://iso639-3.sil.org/
static const char *locale_list[] = {
"aa", // Afar
@@ -100,6 +101,7 @@ static const char *locale_list[] = {
"bo", // Tibetan
"bo_CN", // Tibetan (China)
"bo_IN", // Tibetan (India)
+ "br", // Breton
"br_FR", // Breton (France)
"brx_IN", // Bodo (India)
"bs_BA", // Bosnian (Bosnia and Herzegovina)
@@ -201,6 +203,7 @@ static const char *locale_list[] = {
"gd_GB", // Scottish Gaelic (United Kingdom)
"gez_ER", // Geez (Eritrea)
"gez_ET", // Geez (Ethiopia)
+ "gl", // Galician
"gl_ES", // Galician (Spain)
"gu_IN", // Gujarati (India)
"gv_GB", // Manx (United Kingdom)
@@ -273,6 +276,7 @@ static const char *locale_list[] = {
"ml_IN", // Malayalam (India)
"mni_IN", // Manipuri (India)
"mn_MN", // Mongolian (Mongolia)
+ "mr", // Marathi
"mr_IN", // Marathi (India)
"ms", // Malay
"ms_MY", // Malay (Malaysia)
@@ -302,6 +306,7 @@ static const char *locale_list[] = {
"om", // Oromo
"om_ET", // Oromo (Ethiopia)
"om_KE", // Oromo (Kenya)
+ "or", // Oriya
"or_IN", // Oriya (India)
"os_RU", // Ossetian (Russia)
"pa_IN", // Panjabi (India)
@@ -386,6 +391,8 @@ static const char *locale_list[] = {
"tr_TR", // Turkish (Turkey)
"ts_ZA", // Tsonga (South Africa)
"tt_RU", // Tatar (Russia)
+ "tzm", // Central Atlas Tamazight
+ "tzm_MA", // Central Atlas Tamazight (Marrocos)
"ug_CN", // Uighur (China)
"uk", // Ukrainian
"uk_UA", // Ukrainian (Ukraine)
@@ -468,6 +475,7 @@ static const char *locale_names[] = {
"Tibetan",
"Tibetan (China)",
"Tibetan (India)",
+ "Breton",
"Breton (France)",
"Bodo (India)",
"Bosnian (Bosnia and Herzegovina)",
@@ -569,6 +577,7 @@ static const char *locale_names[] = {
"Scottish Gaelic (United Kingdom)",
"Geez (Eritrea)",
"Geez (Ethiopia)",
+ "Galician",
"Galician (Spain)",
"Gujarati (India)",
"Manx (United Kingdom)",
@@ -641,6 +650,7 @@ static const char *locale_names[] = {
"Malayalam (India)",
"Manipuri (India)",
"Mongolian (Mongolia)",
+ "Marathi",
"Marathi (India)",
"Malay",
"Malay (Malaysia)",
@@ -670,6 +680,7 @@ static const char *locale_names[] = {
"Oromo",
"Oromo (Ethiopia)",
"Oromo (Kenya)",
+ "Oriya",
"Oriya (India)",
"Ossetian (Russia)",
"Panjabi (India)",
@@ -754,6 +765,8 @@ static const char *locale_names[] = {
"Turkish (Turkey)",
"Tsonga (South Africa)",
"Tatar (Russia)",
+ "Central Atlas Tamazight",
+ "Central Atlas Tamazight (Marrocos)",
"Uighur (China)",
"Ukrainian",
"Ukrainian (Ukraine)",
@@ -851,7 +864,7 @@ void Translation::add_message(const StringName &p_src_text, const StringName &p_
void Translation::add_plural_message(const StringName &p_src_text, const Vector<String> &p_plural_xlated_texts, const StringName &p_context) {
WARN_PRINT("Translation class doesn't handle plural messages. Calling add_plural_message() on a Translation instance is probably a mistake. \nUse a derived Translation class that handles plurals, such as TranslationPO class");
- ERR_FAIL_COND_MSG(p_plural_xlated_texts.empty(), "Parameter vector p_plural_xlated_texts passed in is empty.");
+ ERR_FAIL_COND_MSG(p_plural_xlated_texts.is_empty(), "Parameter vector p_plural_xlated_texts passed in is empty.");
translation_map[p_src_text] = p_plural_xlated_texts[0];
}
@@ -1191,14 +1204,14 @@ bool TranslationServer::_load_translations(const String &p_from) {
}
void TranslationServer::setup() {
- String test = GLOBAL_DEF("locale/test", "");
+ String test = GLOBAL_DEF("internationalization/locale/test", "");
test = test.strip_edges();
if (test != "") {
set_locale(test);
} else {
set_locale(OS::get_singleton()->get_locale());
}
- fallback = GLOBAL_DEF("locale/fallback", "en");
+ fallback = GLOBAL_DEF("internationalization/locale/fallback", "en");
#ifdef TOOLS_ENABLED
{
String options = "";
@@ -1210,7 +1223,7 @@ void TranslationServer::setup() {
options += locale_list[idx];
idx++;
}
- ProjectSettings::get_singleton()->set_custom_property_info("locale/fallback", PropertyInfo(Variant::STRING, "locale/fallback", PROPERTY_HINT_ENUM, options));
+ ProjectSettings::get_singleton()->set_custom_property_info("internationalization/locale/fallback", PropertyInfo(Variant::STRING, "internationalization/locale/fallback", PROPERTY_HINT_ENUM, options));
}
#endif
}
@@ -1307,11 +1320,11 @@ void TranslationServer::_bind_methods() {
void TranslationServer::load_translations() {
String locale = get_locale();
- _load_translations("locale/translations"); //all
- _load_translations("locale/translations_" + locale.substr(0, 2));
+ _load_translations("internationalization/locale/translations"); //all
+ _load_translations("internationalization/locale/translations_" + locale.substr(0, 2));
if (locale.substr(0, 2) != locale) {
- _load_translations("locale/translations_" + locale);
+ _load_translations("internationalization/locale/translations_" + locale);
}
}
diff --git a/core/string/translation.h b/core/string/translation.h
index c7ffe4d065..72a828227e 100644
--- a/core/string/translation.h
+++ b/core/string/translation.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/translation_po.cpp b/core/string/translation_po.cpp
index 203f29026b..846afe761b 100644
--- a/core/string/translation_po.cpp
+++ b/core/string/translation_po.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -230,7 +230,7 @@ StringName TranslationPO::get_message(const StringName &p_src_text, const String
if (!translation_map.has(p_context) || !translation_map[p_context].has(p_src_text)) {
return StringName();
}
- ERR_FAIL_COND_V_MSG(translation_map[p_context][p_src_text].empty(), StringName(), "Source text \"" + String(p_src_text) + "\" is registered but doesn't have a translation. Please report this bug.");
+ ERR_FAIL_COND_V_MSG(translation_map[p_context][p_src_text].is_empty(), StringName(), "Source text \"" + String(p_src_text) + "\" is registered but doesn't have a translation. Please report this bug.");
return translation_map[p_context][p_src_text][0];
}
@@ -246,7 +246,7 @@ StringName TranslationPO::get_plural_message(const StringName &p_src_text, const
if (!translation_map.has(p_context) || !translation_map[p_context].has(p_src_text)) {
return StringName();
}
- ERR_FAIL_COND_V_MSG(translation_map[p_context][p_src_text].empty(), StringName(), "Source text \"" + String(p_src_text) + "\" is registered but doesn't have a translation. Please report this bug.");
+ ERR_FAIL_COND_V_MSG(translation_map[p_context][p_src_text].is_empty(), StringName(), "Source text \"" + String(p_src_text) + "\" is registered but doesn't have a translation. Please report this bug.");
if (translation_map[p_context][p_src_text].size() == 1) {
WARN_PRINT("Source string \"" + String(p_src_text) + "\" doesn't have plural translations. Use singular translation API for such as tr(), TTR() to translate \"" + String(p_src_text) + "\"");
diff --git a/core/string/translation_po.h b/core/string/translation_po.h
index c8a47bec5a..0e1d03d6ca 100644
--- a/core/string/translation_po.h
+++ b/core/string/translation_po.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/ucaps.h b/core/string/ucaps.h
index 79b346acba..b785ac7879 100644
--- a/core/string/ucaps.h
+++ b/core/string/ucaps.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index fee168993b..9f931ef30b 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -427,12 +427,12 @@ String operator+(char32_t p_chr, const String &p_str) {
}
String &String::operator+=(const String &p_str) {
- if (empty()) {
+ if (is_empty()) {
*this = p_str;
return *this;
}
- if (p_str.empty()) {
+ if (p_str.is_empty()) {
return *this;
}
@@ -519,7 +519,7 @@ bool String::operator==(const char *p_str) const {
if (length() != len) {
return false;
}
- if (empty()) {
+ if (is_empty()) {
return true;
}
@@ -558,7 +558,7 @@ bool String::operator==(const char32_t *p_str) const {
if (length() != len) {
return false;
}
- if (empty()) {
+ if (is_empty()) {
return true;
}
@@ -580,7 +580,7 @@ bool String::operator==(const String &p_str) const {
if (length() != p_str.length()) {
return false;
}
- if (empty()) {
+ if (is_empty()) {
return true;
}
@@ -605,7 +605,7 @@ bool String::operator==(const StrRange &p_str_range) const {
if (length() != len) {
return false;
}
- if (empty()) {
+ if (is_empty()) {
return true;
}
@@ -678,20 +678,20 @@ bool String::operator>=(const String &p_str) const {
}
bool String::operator<(const char *p_str) const {
- if (empty() && p_str[0] == 0) {
+ if (is_empty() && p_str[0] == 0) {
return false;
}
- if (empty()) {
+ if (is_empty()) {
return true;
}
return is_str_less(get_data(), p_str);
}
bool String::operator<(const wchar_t *p_str) const {
- if (empty() && p_str[0] == 0) {
+ if (is_empty() && p_str[0] == 0) {
return false;
}
- if (empty()) {
+ if (is_empty()) {
return true;
}
@@ -705,10 +705,10 @@ bool String::operator<(const wchar_t *p_str) const {
}
bool String::operator<(const char32_t *p_str) const {
- if (empty() && p_str[0] == 0) {
+ if (is_empty() && p_str[0] == 0) {
return false;
}
- if (empty()) {
+ if (is_empty()) {
return true;
}
@@ -720,13 +720,13 @@ bool String::operator<(const String &p_str) const {
}
signed char String::nocasecmp_to(const String &p_str) const {
- if (empty() && p_str.empty()) {
+ if (is_empty() && p_str.is_empty()) {
return 0;
}
- if (empty()) {
+ if (is_empty()) {
return -1;
}
- if (p_str.empty()) {
+ if (p_str.is_empty()) {
return 1;
}
@@ -752,13 +752,13 @@ signed char String::nocasecmp_to(const String &p_str) const {
}
signed char String::casecmp_to(const String &p_str) const {
- if (empty() && p_str.empty()) {
+ if (is_empty() && p_str.is_empty()) {
return 0;
}
- if (empty()) {
+ if (is_empty()) {
return -1;
}
- if (p_str.empty()) {
+ if (p_str.is_empty()) {
return 1;
}
@@ -949,10 +949,10 @@ String String::get_with_code_lines() const {
}
int String::get_slice_count(String p_splitter) const {
- if (empty()) {
+ if (is_empty()) {
return 0;
}
- if (p_splitter.empty()) {
+ if (p_splitter.is_empty()) {
return 0;
}
@@ -968,7 +968,7 @@ int String::get_slice_count(String p_splitter) const {
}
String String::get_slice(String p_splitter, int p_slice) const {
- if (empty() || p_splitter.empty()) {
+ if (is_empty() || p_splitter.is_empty()) {
return "";
}
@@ -1008,7 +1008,7 @@ String String::get_slice(String p_splitter, int p_slice) const {
}
String String::get_slicec(char32_t p_splitter, int p_slice) const {
- if (empty()) {
+ if (is_empty()) {
return String();
}
@@ -1409,8 +1409,9 @@ String String::num(double p_num, int p_decimals) {
if (digit == MAX_DIGITS) //no point in going to infinite
break;
- if ((dec - (double)((int)dec)) < 1e-6)
+ if (dec - (double)((int)dec) < 1e-6) {
break;
+ }
}
if (digit == p_decimals)
@@ -2096,8 +2097,9 @@ String::String(const StrRange &p_range) {
copy_from(p_range.c_str, p_range.len);
}
-int64_t String::hex_to_int(bool p_with_prefix) const {
- if (p_with_prefix && length() < 3) {
+int64_t String::hex_to_int() const {
+ int len = length();
+ if (len == 0) {
return 0;
}
@@ -2109,10 +2111,7 @@ int64_t String::hex_to_int(bool p_with_prefix) const {
s++;
}
- if (p_with_prefix) {
- if (s[0] != '0' || s[1] != 'x') {
- return 0;
- }
+ if (len > 2 && s[0] == '0' && s[1] == 'x') {
s += 2;
}
@@ -2139,8 +2138,9 @@ int64_t String::hex_to_int(bool p_with_prefix) const {
return hex * sign;
}
-int64_t String::bin_to_int(bool p_with_prefix) const {
- if (p_with_prefix && length() < 3) {
+int64_t String::bin_to_int() const {
+ int len = length();
+ if (len == 0) {
return 0;
}
@@ -2152,10 +2152,7 @@ int64_t String::bin_to_int(bool p_with_prefix) const {
s++;
}
- if (p_with_prefix) {
- if (s[0] != '0' || s[1] != 'b') {
- return 0;
- }
+ if (len > 2 && s[0] == '0' && s[1] == 'b') {
s += 2;
}
@@ -2585,7 +2582,7 @@ int64_t String::to_int(const char32_t *p_str, int p_len, bool p_clamp) {
}
double String::to_float() const {
- if (empty()) {
+ if (is_empty()) {
return 0;
}
return built_in_strtod<char32_t>(get_data());
@@ -2767,7 +2764,7 @@ String String::substr(int p_from, int p_chars) const {
p_chars = length() - p_from;
}
- if (empty() || p_from < 0 || p_from >= length() || p_chars <= 0) {
+ if (is_empty() || p_from < 0 || p_from >= length() || p_chars <= 0) {
return "";
}
@@ -3074,35 +3071,47 @@ int String::rfindn(const String &p_str, int p_from) const {
}
bool String::ends_with(const String &p_string) const {
- int pos = rfind(p_string);
- if (pos == -1) {
+ int l = p_string.length();
+ if (l > length()) {
return false;
}
- return pos + p_string.length() == length();
+
+ if (l == 0) {
+ return true;
+ }
+
+ const char32_t *p = &p_string[0];
+ const char32_t *s = &operator[](length() - l);
+
+ for (int i = 0; i < l; i++) {
+ if (p[i] != s[i]) {
+ return false;
+ }
+ }
+
+ return true;
}
bool String::begins_with(const String &p_string) const {
- if (p_string.length() > length()) {
+ int l = p_string.length();
+ if (l > length()) {
return false;
}
- int l = p_string.length();
if (l == 0) {
return true;
}
- const char32_t *src = &p_string[0];
- const char32_t *str = &operator[](0);
+ const char32_t *p = &p_string[0];
+ const char32_t *s = &operator[](0);
- int i = 0;
- for (; i < l; i++) {
- if (src[i] != str[i]) {
+ for (int i = 0; i < l; i++) {
+ if (p[i] != s[i]) {
return false;
}
}
- // only if i == l the p_string matches the beginning
- return i == l;
+ return true;
}
bool String::begins_with(const char *p_string) const {
@@ -3142,7 +3151,7 @@ bool String::is_quoted() const {
}
int String::_count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const {
- if (p_string.empty()) {
+ if (p_string.is_empty()) {
return 0;
}
int len = length();
@@ -3250,8 +3259,8 @@ float String::similarity(const String &p_string) const {
int src_size = src_bigrams.size();
int tgt_size = tgt_bigrams.size();
- double sum = src_size + tgt_size;
- double inter = 0;
+ int sum = src_size + tgt_size;
+ int inter = 0;
for (int i = 0; i < src_size; i++) {
for (int j = 0; j < tgt_size; j++) {
if (src_bigrams[i] == tgt_bigrams[j]) {
@@ -3478,7 +3487,7 @@ String String::right(int p_pos) const {
return substr(p_pos, (length() - p_pos));
}
-char32_t String::ord_at(int p_idx) const {
+char32_t String::unicode_at(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, length(), 0);
return operator[](p_idx);
}
@@ -3750,7 +3759,7 @@ bool String::is_valid_string() const {
return valid;
}
-String String::http_escape() const {
+String String::uri_encode() const {
const CharString temp = utf8();
String res;
for (int i = 0; i < temp.length(); ++i) {
@@ -3774,23 +3783,25 @@ String String::http_escape() const {
return res;
}
-String String::http_unescape() const {
+String String::uri_decode() const {
String res;
for (int i = 0; i < length(); ++i) {
- if (ord_at(i) == '%' && i + 2 < length()) {
- char32_t ord1 = ord_at(i + 1);
+ if (unicode_at(i) == '%' && i + 2 < length()) {
+ char32_t ord1 = unicode_at(i + 1);
if ((ord1 >= '0' && ord1 <= '9') || (ord1 >= 'A' && ord1 <= 'Z')) {
- char32_t ord2 = ord_at(i + 2);
+ char32_t ord2 = unicode_at(i + 2);
if ((ord2 >= '0' && ord2 <= '9') || (ord2 >= 'A' && ord2 <= 'Z')) {
char bytes[3] = { (char)ord1, (char)ord2, 0 };
res += (char)strtol(bytes, nullptr, 16);
i += 2;
}
} else {
- res += ord_at(i);
+ res += unicode_at(i);
}
+ } else if (unicode_at(i) == '+') {
+ res += ' ';
} else {
- res += ord_at(i);
+ res += unicode_at(i);
}
}
return String::utf8(res.ascii());
@@ -3877,25 +3888,55 @@ static _FORCE_INLINE_ int _xml_unescape(const char32_t *p_src, int p_src_len, ch
if (p_src_len >= 4 && p_src[1] == '#') {
char32_t c = 0;
-
- for (int i = 2; i < p_src_len; i++) {
- eat = i + 1;
- char32_t ct = p_src[i];
- if (ct == ';') {
- break;
- } else if (ct >= '0' && ct <= '9') {
- ct = ct - '0';
- } else if (ct >= 'a' && ct <= 'f') {
- ct = (ct - 'a') + 10;
- } else if (ct >= 'A' && ct <= 'F') {
- ct = (ct - 'A') + 10;
- } else {
- continue;
+ bool overflow = false;
+ if (p_src[2] == 'x') {
+ // Hex entity &#x<num>;
+ for (int i = 3; i < p_src_len; i++) {
+ eat = i + 1;
+ char32_t ct = p_src[i];
+ if (ct == ';') {
+ break;
+ } else if (ct >= '0' && ct <= '9') {
+ ct = ct - '0';
+ } else if (ct >= 'a' && ct <= 'f') {
+ ct = (ct - 'a') + 10;
+ } else if (ct >= 'A' && ct <= 'F') {
+ ct = (ct - 'A') + 10;
+ } else {
+ break;
+ }
+ if (c > (UINT32_MAX >> 4)) {
+ overflow = true;
+ break;
+ }
+ c <<= 4;
+ c |= ct;
+ }
+ } else {
+ // Decimal entity &#<num>;
+ for (int i = 2; i < p_src_len; i++) {
+ eat = i + 1;
+ char32_t ct = p_src[i];
+ if (ct == ';' || ct < '0' || ct > '9') {
+ break;
+ }
+ }
+ if (p_src[eat - 1] == ';') {
+ int64_t val = String::to_int(p_src + 2, eat - 3);
+ if (val > 0 && val <= UINT32_MAX) {
+ c = (char32_t)val;
+ } else {
+ overflow = true;
+ }
}
- c <<= 4;
- c |= ct;
}
+ // Value must be non-zero, in the range of char32_t,
+ // actually end with ';'. If invalid, leave the entity as-is
+ if (c == '\0' || overflow || p_src[eat - 1] != ';') {
+ eat = 1;
+ c = *p_src;
+ }
if (p_dst) {
*p_dst = c;
}
@@ -4241,11 +4282,11 @@ bool String::is_valid_ip_address() const {
Vector<String> ip = split(":");
for (int i = 0; i < ip.size(); i++) {
String n = ip[i];
- if (n.empty()) {
+ if (n.is_empty()) {
continue;
}
if (n.is_valid_hex_number(false)) {
- int64_t nint = n.hex_to_int(false);
+ int64_t nint = n.hex_to_int();
if (nint < 0 || nint > 0xffff) {
return false;
}
@@ -4331,7 +4372,7 @@ String String::get_extension() const {
}
String String::plus_file(const String &p_file) const {
- if (empty()) {
+ if (is_empty()) {
return p_file;
}
if (operator[](length() - 1) == '/' || (p_file.size() > 0 && p_file.operator[](0) == '/')) {
@@ -4340,63 +4381,6 @@ String String::plus_file(const String &p_file) const {
return *this + "/" + p_file;
}
-String String::percent_encode() const {
- CharString cs = utf8();
- String encoded;
- for (int i = 0; i < cs.length(); i++) {
- uint8_t c = cs[i];
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '~' || c == '.') {
- char p[2] = { (char)c, 0 };
- encoded += p;
- } else {
- char p[4] = { '%', 0, 0, 0 };
- static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-
- p[1] = hex[c >> 4];
- p[2] = hex[c & 0xF];
- encoded += p;
- }
- }
-
- return encoded;
-}
-
-String String::percent_decode() const {
- CharString pe;
-
- CharString cs = utf8();
- for (int i = 0; i < cs.length(); i++) {
- uint8_t c = cs[i];
- if (c == '%' && i < length() - 2) {
- uint8_t a = LOWERCASE(cs[i + 1]);
- uint8_t b = LOWERCASE(cs[i + 2]);
-
- if (a >= '0' && a <= '9') {
- c = (a - '0') << 4;
- } else if (a >= 'a' && a <= 'f') {
- c = (a - 'a' + 10) << 4;
- } else {
- continue;
- }
-
- uint8_t d = 0;
-
- if (b >= '0' && b <= '9') {
- d = (b - '0');
- } else if (b >= 'a' && b <= 'f') {
- d = (b - 'a' + 10);
- } else {
- continue;
- }
- c += d;
- i += 2;
- }
- pe += c;
- }
-
- return String::utf8(pe.ptr());
-}
-
String String::property_name_encode() const {
// Escape and quote strings with extended ASCII or further Unicode characters
// as well as '"', '=' or ' ' (32)
@@ -4410,6 +4394,18 @@ String String::property_name_encode() const {
return *this;
}
+// Changes made to the set of invalid characters must also be reflected in the String documentation.
+const String String::invalid_node_name_characters = ". : @ / \"";
+
+String String::validate_node_name() const {
+ Vector<String> chars = String::invalid_node_name_characters.split(" ");
+ String name = this->replace(chars[0], "");
+ for (int i = 1; i < chars.size(); i++) {
+ name = name.replace(chars[i], "");
+ }
+ return name;
+}
+
String String::get_basename() const {
int pos = rfind(".");
if (pos < 0 || pos < MAX(rfind("/"), rfind("\\"))) {
@@ -4760,7 +4756,7 @@ String String::unquote() const {
Vector<uint8_t> String::to_ascii_buffer() const {
const String *s = this;
- if (s->empty()) {
+ if (s->is_empty()) {
return Vector<uint8_t>();
}
CharString charstr = s->ascii();
@@ -4776,7 +4772,7 @@ Vector<uint8_t> String::to_ascii_buffer() const {
Vector<uint8_t> String::to_utf8_buffer() const {
const String *s = this;
- if (s->empty()) {
+ if (s->is_empty()) {
return Vector<uint8_t>();
}
CharString charstr = s->utf8();
@@ -4792,7 +4788,7 @@ Vector<uint8_t> String::to_utf8_buffer() const {
Vector<uint8_t> String::to_utf16_buffer() const {
const String *s = this;
- if (s->empty()) {
+ if (s->is_empty()) {
return Vector<uint8_t>();
}
Char16String charstr = s->utf16();
@@ -4808,7 +4804,7 @@ Vector<uint8_t> String::to_utf16_buffer() const {
Vector<uint8_t> String::to_utf32_buffer() const {
const String *s = this;
- if (s->empty()) {
+ if (s->is_empty()) {
return Vector<uint8_t>();
}
diff --git a/core/string/ustring.h b/core/string/ustring.h
index 7ff78b2d86..1e362d7683 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -318,8 +318,8 @@ public:
bool is_numeric() const;
double to_float() const;
- int64_t hex_to_int(bool p_with_prefix = true) const;
- int64_t bin_to_int(bool p_with_prefix = true) const;
+ int64_t hex_to_int() const;
+ int64_t bin_to_int() const;
int64_t to_int() const;
static int64_t to_int(const char *p_str, int p_len = -1);
@@ -366,7 +366,7 @@ public:
String get_extension() const;
String get_basename() const;
String plus_file(const String &p_file) const;
- char32_t ord_at(int p_idx) const;
+ char32_t unicode_at(int p_idx) const;
void erase(int p_pos, int p_chars);
@@ -394,7 +394,7 @@ public:
Vector<uint8_t> sha1_buffer() const;
Vector<uint8_t> sha256_buffer() const;
- _FORCE_INLINE_ bool empty() const { return length() == 0; }
+ _FORCE_INLINE_ bool is_empty() const { return length() == 0; }
// path functions
bool is_abs_path() const;
@@ -409,19 +409,20 @@ public:
String xml_escape(bool p_escape_quotes = false) const;
String xml_unescape() const;
- String http_escape() const;
- String http_unescape() const;
+ String uri_encode() const;
+ String uri_decode() const;
String c_escape() const;
String c_escape_multiline() const;
String c_unescape() const;
String json_escape() const;
String word_wrap(int p_chars_per_line) const;
- String percent_encode() const;
- String percent_decode() const;
-
String property_name_encode() const;
+ // node functions
+ static const String invalid_node_name_characters;
+ String validate_node_name() const;
+
bool is_valid_identifier() const;
bool is_valid_integer() const;
bool is_valid_float() const;
diff --git a/core/templates/command_queue_mt.cpp b/core/templates/command_queue_mt.cpp
index a94853a21c..238bf3975c 100644
--- a/core/templates/command_queue_mt.cpp
+++ b/core/templates/command_queue_mt.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/command_queue_mt.h b/core/templates/command_queue_mt.h
index ac38d330de..0012cea72d 100644
--- a/core/templates/command_queue_mt.h
+++ b/core/templates/command_queue_mt.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -498,6 +498,11 @@ public:
flush_one();
}
+ _FORCE_INLINE_ void flush_if_pending() {
+ if (unlikely(read_ptr_and_epoch != write_ptr_and_epoch)) {
+ flush_all();
+ }
+ }
void flush_all() {
//ERR_FAIL_COND(sync);
lock();
diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h
index d5eb08286d..c985593473 100644
--- a/core/templates/cowdata.h
+++ b/core/templates/cowdata.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,6 +45,10 @@ class CharString;
template <class T, class V>
class VMap;
+#if !defined(NO_THREADS)
+SAFE_NUMERIC_TYPE_PUN_GUARANTEES(uint32_t)
+#endif
+
template <class T>
class CowData {
template <class TV>
@@ -60,12 +64,12 @@ private:
// internal helpers
- _FORCE_INLINE_ uint32_t *_get_refcount() const {
+ _FORCE_INLINE_ SafeNumeric<uint32_t> *_get_refcount() const {
if (!_ptr) {
return nullptr;
}
- return reinterpret_cast<uint32_t *>(_ptr) - 2;
+ return reinterpret_cast<SafeNumeric<uint32_t> *>(_ptr) - 2;
}
_FORCE_INLINE_ uint32_t *_get_size() const {
@@ -111,7 +115,7 @@ private:
void _unref(void *p_data);
void _ref(const CowData *p_from);
void _ref(const CowData &p_from);
- void _copy_on_write();
+ uint32_t _copy_on_write();
public:
void operator=(const CowData<T> &p_from) { _ref(p_from); }
@@ -135,10 +139,10 @@ public:
}
_FORCE_INLINE_ void clear() { resize(0); }
- _FORCE_INLINE_ bool empty() const { return _ptr == nullptr; }
+ _FORCE_INLINE_ bool is_empty() const { return _ptr == nullptr; }
_FORCE_INLINE_ void set(int p_index, const T &p_elem) {
- CRASH_BAD_INDEX(p_index, size());
+ ERR_FAIL_INDEX(p_index, size());
_copy_on_write();
_get_data()[p_index] = p_elem;
}
@@ -192,9 +196,9 @@ void CowData<T>::_unref(void *p_data) {
return;
}
- uint32_t *refc = _get_refcount();
+ SafeNumeric<uint32_t> *refc = _get_refcount();
- if (atomic_decrement(refc) > 0) {
+ if (refc->decrement() > 0) {
return; // still in use
}
// clean up
@@ -214,20 +218,21 @@ void CowData<T>::_unref(void *p_data) {
}
template <class T>
-void CowData<T>::_copy_on_write() {
+uint32_t CowData<T>::_copy_on_write() {
if (!_ptr) {
- return;
+ return 0;
}
- uint32_t *refc = _get_refcount();
+ SafeNumeric<uint32_t> *refc = _get_refcount();
- if (unlikely(*refc > 1)) {
+ uint32_t rc = refc->get();
+ if (unlikely(rc > 1)) {
/* in use by more than me */
uint32_t current_size = *_get_size();
uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true);
- *(mem_new - 2) = 1; //refcount
+ new (mem_new - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount
*(mem_new - 1) = current_size; //size
T *_data = (T *)(mem_new);
@@ -244,7 +249,10 @@ void CowData<T>::_copy_on_write() {
_unref(_ptr);
_ptr = _data;
+
+ rc = 1;
}
+ return rc;
}
template <class T>
@@ -265,7 +273,7 @@ Error CowData<T>::resize(int p_size) {
}
// possibly changing size, copy on write
- _copy_on_write();
+ uint32_t rc = _copy_on_write();
size_t current_alloc_size = _get_alloc_size(current_size);
size_t alloc_size;
@@ -278,13 +286,15 @@ Error CowData<T>::resize(int p_size) {
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
*(ptr - 1) = 0; //size, currently none
- *(ptr - 2) = 1; //refcount
+ new (ptr - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount
_ptr = (T *)ptr;
} else {
- void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
+ uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
+ new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount
+
_ptr = (T *)(_ptrnew);
}
}
@@ -311,8 +321,9 @@ Error CowData<T>::resize(int p_size) {
}
if (alloc_size != current_alloc_size) {
- void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
+ uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
+ new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount
_ptr = (T *)(_ptrnew);
}
@@ -359,7 +370,7 @@ void CowData<T>::_ref(const CowData &p_from) {
return; //nothing to do
}
- if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
+ if (p_from._get_refcount()->conditional_increment() > 0) { // could reference
_ptr = p_from._ptr;
}
}
diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h
index e1ba381595..dc378aed69 100644
--- a/core/templates/hash_map.h
+++ b/core/templates/hash_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -497,7 +497,7 @@ public:
return elements;
}
- inline bool empty() const {
+ inline bool is_empty() const {
return elements == 0;
}
diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h
index 1ed9ab1987..4572b269cf 100644
--- a/core/templates/hashfuncs.h
+++ b/core/templates/hashfuncs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/list.h b/core/templates/list.h
index 8e14aaa90d..eaf1dbb4a0 100644
--- a/core/templates/list.h
+++ b/core/templates/list.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -373,7 +373,7 @@ public:
/**
* return whether the list is empty
*/
- _FORCE_INLINE_ bool empty() const {
+ _FORCE_INLINE_ bool is_empty() const {
return (!_data || !_data->size_cache);
}
diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h
index 4ef040dc77..ffd17b7ee9 100644
--- a/core/templates/local_vector.h
+++ b/core/templates/local_vector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -82,6 +82,19 @@ public:
}
}
+ /// Removes the item copying the last value into the position of the one to
+ /// remove. It's generally faster than `remove`.
+ void remove_unordered(U p_index) {
+ ERR_FAIL_INDEX(p_index, count);
+ count--;
+ if (count > p_index) {
+ data[p_index] = data[count];
+ }
+ if (!__has_trivial_destructor(T) && !force_trivial) {
+ data[count].~T();
+ }
+ }
+
void erase(const T &p_val) {
int64_t idx = find(p_val);
if (idx >= 0) {
@@ -104,7 +117,8 @@ public:
capacity = 0;
}
}
- _FORCE_INLINE_ bool empty() const { return count == 0; }
+ _FORCE_INLINE_ bool is_empty() const { return count == 0; }
+ _FORCE_INLINE_ U get_capacity() const { return capacity; }
_FORCE_INLINE_ void reserve(U p_size) {
p_size = nearest_power_of_2_templated(p_size);
if (p_size > capacity) {
diff --git a/core/templates/lru.h b/core/templates/lru.h
index d02c4337d1..e55e40da48 100644
--- a/core/templates/lru.h
+++ b/core/templates/lru.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/map.h b/core/templates/map.h
index c454d69256..51a237472d 100644
--- a/core/templates/map.h
+++ b/core/templates/map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -625,7 +625,7 @@ public:
return e;
}
- inline bool empty() const { return _data.size_cache == 0; }
+ inline bool is_empty() const { return _data.size_cache == 0; }
inline int size() const { return _data.size_cache; }
int calculate_depth() const {
diff --git a/core/templates/oa_hash_map.h b/core/templates/oa_hash_map.h
index d9d632b4ce..1d4176eb10 100644
--- a/core/templates/oa_hash_map.h
+++ b/core/templates/oa_hash_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -190,7 +190,7 @@ public:
_FORCE_INLINE_ uint32_t get_capacity() const { return capacity; }
_FORCE_INLINE_ uint32_t get_num_elements() const { return num_elements; }
- bool empty() const {
+ bool is_empty() const {
return num_elements == 0;
}
diff --git a/core/templates/ordered_hash_map.h b/core/templates/ordered_hash_map.h
index 9398868b01..7a17eeb644 100644
--- a/core/templates/ordered_hash_map.h
+++ b/core/templates/ordered_hash_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -265,7 +265,7 @@ public:
return ConstElement(list.back());
}
- inline bool empty() const { return list.empty(); }
+ inline bool is_empty() const { return list.is_empty(); }
inline int size() const { return list.size(); }
const void *id() const {
diff --git a/core/templates/paged_allocator.h b/core/templates/paged_allocator.h
index 8bd1eecdeb..7002034710 100644
--- a/core/templates/paged_allocator.h
+++ b/core/templates/paged_allocator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -108,7 +108,7 @@ public:
return page_size > 0;
}
- void configure(uint32_t p_page_size, bool p_thread_safe) {
+ void configure(uint32_t p_page_size) {
ERR_FAIL_COND(page_pool != nullptr); //sanity check
ERR_FAIL_COND(p_page_size == 0);
page_size = nearest_power_of_2_templated(p_page_size);
@@ -116,8 +116,8 @@ public:
page_shift = get_shift_from_power_of_2(page_size);
}
- PagedAllocator(uint32_t p_page_size = 4096, bool p_thread_safe = false) { // power of 2 recommended because of alignment with OS page sizes. Even if element is bigger, its still a multiple and get rounded amount of pages
- configure(p_page_size, false);
+ PagedAllocator(uint32_t p_page_size = 4096) { // power of 2 recommended because of alignment with OS page sizes. Even if element is bigger, its still a multiple and get rounded amount of pages
+ configure(p_page_size);
}
~PagedAllocator() {
diff --git a/core/templates/paged_array.h b/core/templates/paged_array.h
index aaf3893715..599d3dde4f 100644
--- a/core/templates/paged_array.h
+++ b/core/templates/paged_array.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -206,6 +206,24 @@ public:
count++;
}
+ _FORCE_INLINE_ void pop_back() {
+ ERR_FAIL_COND(count == 0);
+
+ if (!__has_trivial_destructor(T)) {
+ uint32_t page = (count - 1) >> page_size_shift;
+ uint32_t offset = (count - 1) & page_size_mask;
+ page_data[page][offset].~T();
+ }
+
+ uint32_t remainder = count & page_size_mask;
+ if (unlikely(remainder == 1)) {
+ // one element remained, so page must be freed.
+ uint32_t last_page = _get_pages_in_use() - 1;
+ page_pool->free_page(page_ids[last_page]);
+ }
+ count--;
+ }
+
void clear() {
//destruct if needed
if (!__has_trivial_destructor(T)) {
diff --git a/core/templates/pair.h b/core/templates/pair.h
index 89ea2b9fd9..bc1a764694 100644
--- a/core/templates/pair.h
+++ b/core/templates/pair.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/pass_func.h b/core/templates/pass_func.h
index a074ad190d..d2f465e91c 100644
--- a/core/templates/pass_func.h
+++ b/core/templates/pass_func.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/rid.h b/core/templates/rid.h
index a475d166d5..4c7119b4ea 100644
--- a/core/templates/rid.h
+++ b/core/templates/rid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,30 +40,37 @@ class RID {
uint64_t _id = 0;
public:
- _FORCE_INLINE_ bool operator==(const RID &p_rid) const {
+ _ALWAYS_INLINE_ bool operator==(const RID &p_rid) const {
return _id == p_rid._id;
}
- _FORCE_INLINE_ bool operator<(const RID &p_rid) const {
+ _ALWAYS_INLINE_ bool operator<(const RID &p_rid) const {
return _id < p_rid._id;
}
- _FORCE_INLINE_ bool operator<=(const RID &p_rid) const {
+ _ALWAYS_INLINE_ bool operator<=(const RID &p_rid) const {
return _id <= p_rid._id;
}
- _FORCE_INLINE_ bool operator>(const RID &p_rid) const {
+ _ALWAYS_INLINE_ bool operator>(const RID &p_rid) const {
return _id > p_rid._id;
}
- _FORCE_INLINE_ bool operator>=(const RID &p_rid) const {
+ _ALWAYS_INLINE_ bool operator>=(const RID &p_rid) const {
return _id >= p_rid._id;
}
- _FORCE_INLINE_ bool operator!=(const RID &p_rid) const {
+ _ALWAYS_INLINE_ bool operator!=(const RID &p_rid) const {
return _id != p_rid._id;
}
- _FORCE_INLINE_ bool is_valid() const { return _id != 0; }
- _FORCE_INLINE_ bool is_null() const { return _id == 0; }
+ _ALWAYS_INLINE_ bool is_valid() const { return _id != 0; }
+ _ALWAYS_INLINE_ bool is_null() const { return _id == 0; }
- _FORCE_INLINE_ uint64_t get_id() const { return _id; }
+ _ALWAYS_INLINE_ uint32_t get_local_index() const { return _id & 0xFFFFFFFF; }
- _FORCE_INLINE_ RID() {}
+ static _ALWAYS_INLINE_ RID from_uint64(uint64_t p_id) {
+ RID _rid;
+ _rid._id = p_id;
+ return _rid;
+ }
+ _ALWAYS_INLINE_ uint64_t get_id() const { return _id; }
+
+ _ALWAYS_INLINE_ RID() {}
};
#endif // RID_H
diff --git a/core/templates/rid_owner.cpp b/core/templates/rid_owner.cpp
index a5065f29f8..56f39ab779 100644
--- a/core/templates/rid_owner.cpp
+++ b/core/templates/rid_owner.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,4 +30,4 @@
#include "rid_owner.h"
-volatile uint64_t RID_AllocBase::base_id = 1;
+SafeNumeric<uint64_t> RID_AllocBase::base_id{ 1 };
diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h
index 7de4e43648..c4aa93c394 100644
--- a/core/templates/rid_owner.h
+++ b/core/templates/rid_owner.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,7 +44,7 @@
#include <typeinfo>
class RID_AllocBase {
- static volatile uint64_t base_id;
+ static SafeNumeric<uint64_t> base_id;
protected:
static RID _make_from_id(uint64_t p_id) {
@@ -54,7 +54,7 @@ protected:
}
static uint64_t _gen_id() {
- return atomic_increment(&base_id);
+ return base_id.increment();
}
static RID _gen_rid() {
@@ -79,8 +79,7 @@ class RID_Alloc : public RID_AllocBase {
SpinLock spin_lock;
-public:
- RID make_rid(const T &p_value) {
+ _FORCE_INLINE_ RID _allocate_rid(const T *p_initializer) {
if (THREAD_SAFE) {
spin_lock.lock();
}
@@ -115,15 +114,22 @@ public:
uint32_t free_chunk = free_index / elements_in_chunk;
uint32_t free_element = free_index % elements_in_chunk;
- T *ptr = &chunks[free_chunk][free_element];
- memnew_placement(ptr, T(p_value));
+ if (p_initializer) {
+ T *ptr = &chunks[free_chunk][free_element];
+ memnew_placement(ptr, T(*p_initializer));
+ }
- uint32_t validator = (uint32_t)(_gen_id() & 0xFFFFFFFF);
+ uint32_t validator = (uint32_t)(_gen_id() & 0x7FFFFFFF);
uint64_t id = validator;
id <<= 32;
id |= free_index;
validator_chunks[free_chunk][free_element] = validator;
+
+ if (!p_initializer) {
+ validator_chunks[free_chunk][free_element] |= 0x80000000; //mark uninitialized bit
+ }
+
alloc_count++;
if (THREAD_SAFE) {
@@ -133,7 +139,20 @@ public:
return _make_from_id(id);
}
- _FORCE_INLINE_ T *getornull(const RID &p_rid) {
+public:
+ RID make_rid(const T &p_value) {
+ return _allocate_rid(&p_value);
+ }
+
+ //allocate but don't initialize, use initialize_rid afterwards
+ RID allocate_rid() {
+ return _allocate_rid(nullptr);
+ }
+
+ _FORCE_INLINE_ T *getornull(const RID &p_rid, bool p_initialize = false) {
+ if (p_rid == RID()) {
+ return nullptr;
+ }
if (THREAD_SAFE) {
spin_lock.lock();
}
@@ -151,10 +170,32 @@ public:
uint32_t idx_element = idx % elements_in_chunk;
uint32_t validator = uint32_t(id >> 32);
- if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {
+
+ if (unlikely(p_initialize)) {
+ if (unlikely(!(validator_chunks[idx_chunk][idx_element] & 0x80000000))) {
+ if (THREAD_SAFE) {
+ spin_lock.unlock();
+ }
+ ERR_FAIL_V_MSG(nullptr, "Initializing already initialized RID");
+ }
+
+ if (unlikely((validator_chunks[idx_chunk][idx_element] & 0x7FFFFFFF) != validator)) {
+ if (THREAD_SAFE) {
+ spin_lock.unlock();
+ }
+ ERR_FAIL_V_MSG(nullptr, "Attempting to initialize the wrong RID");
+ return nullptr;
+ }
+
+ validator_chunks[idx_chunk][idx_element] &= 0x7FFFFFFF; //initialized
+
+ } else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {
if (THREAD_SAFE) {
spin_lock.unlock();
}
+ if (validator_chunks[idx_chunk][idx_element] & 0x80000000) {
+ ERR_FAIL_V_MSG(nullptr, "Attempting to use an uninitialized RID");
+ }
return nullptr;
}
@@ -166,6 +207,11 @@ public:
return ptr;
}
+ void initialize_rid(RID p_rid, const T &p_value) {
+ T *mem = getornull(p_rid, true);
+ ERR_FAIL_COND(!mem);
+ memnew_placement(mem, T(p_value));
+ }
_FORCE_INLINE_ bool owns(const RID &p_rid) {
if (THREAD_SAFE) {
@@ -186,7 +232,7 @@ public:
uint32_t validator = uint32_t(id >> 32);
- bool owned = validator_chunks[idx_chunk][idx_element] == validator;
+ bool owned = (validator_chunks[idx_chunk][idx_element] & 0x7FFFFFFF) == validator;
if (THREAD_SAFE) {
spin_lock.unlock();
@@ -213,7 +259,12 @@ public:
uint32_t idx_element = idx % elements_in_chunk;
uint32_t validator = uint32_t(id >> 32);
- if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {
+ if (unlikely(validator_chunks[idx_chunk][idx_element] & 0x80000000)) {
+ if (THREAD_SAFE) {
+ spin_lock.unlock();
+ }
+ ERR_FAIL_MSG("Attempted to free an uninitialized or invalid RID");
+ } else if (unlikely(validator_chunks[idx_chunk][idx_element] != validator)) {
if (THREAD_SAFE) {
spin_lock.unlock();
}
@@ -330,6 +381,14 @@ public:
return alloc.make_rid(p_ptr);
}
+ _FORCE_INLINE_ RID allocate_rid() {
+ return alloc.allocate_rid();
+ }
+
+ _FORCE_INLINE_ void initialize_rid(RID p_rid, T *p_ptr) {
+ alloc.initialize_rid(p_rid, p_ptr);
+ }
+
_FORCE_INLINE_ T *getornull(const RID &p_rid) {
T **ptr = alloc.getornull(p_rid);
if (unlikely(!ptr)) {
@@ -338,6 +397,12 @@ public:
return *ptr;
}
+ _FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) {
+ T **ptr = alloc.getornull(p_rid);
+ ERR_FAIL_COND(!ptr);
+ *ptr = p_new_ptr;
+ }
+
_FORCE_INLINE_ bool owns(const RID &p_rid) {
return alloc.owns(p_rid);
}
@@ -379,6 +444,14 @@ public:
return alloc.make_rid(p_ptr);
}
+ _FORCE_INLINE_ RID allocate_rid() {
+ return alloc.allocate_rid();
+ }
+
+ _FORCE_INLINE_ void initialize_rid(RID p_rid, const T &p_ptr) {
+ alloc.initialize_rid(p_rid, p_ptr);
+ }
+
_FORCE_INLINE_ T *getornull(const RID &p_rid) {
return alloc.getornull(p_rid);
}
diff --git a/core/templates/ring_buffer.h b/core/templates/ring_buffer.h
index 12ec047fb6..e7b77440f1 100644
--- a/core/templates/ring_buffer.h
+++ b/core/templates/ring_buffer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/safe_refcount.cpp b/core/templates/safe_refcount.cpp
deleted file mode 100644
index d5ee778ef7..0000000000
--- a/core/templates/safe_refcount.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*************************************************************************/
-/* safe_refcount.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "safe_refcount.h"
-
-#if defined(_MSC_VER)
-
-/* Implementation for MSVC-Windows */
-
-// don't pollute my namespace!
-#include <windows.h>
-
-#define ATOMIC_CONDITIONAL_INCREMENT_BODY(m_pw, m_win_type, m_win_cmpxchg, m_cpp_type) \
- /* try to increment until it actually works */ \
- /* taken from boost */ \
- while (true) { \
- m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \
- if (tmp == 0) { \
- return 0; /* if zero, can't add to it anymore */ \
- } \
- if (m_win_cmpxchg((m_win_type volatile *)(m_pw), tmp + 1, tmp) == tmp) { \
- return tmp + 1; \
- } \
- }
-
-#define ATOMIC_EXCHANGE_IF_GREATER_BODY(m_pw, m_val, m_win_type, m_win_cmpxchg, m_cpp_type) \
- while (true) { \
- m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \
- if (tmp >= m_val) { \
- return tmp; /* already greater, or equal */ \
- } \
- if (m_win_cmpxchg((m_win_type volatile *)(m_pw), m_val, tmp) == tmp) { \
- return m_val; \
- } \
- }
-
-_ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(volatile uint32_t *pw) {
- ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t);
-}
-
-_ALWAYS_INLINE_ uint32_t _atomic_decrement_impl(volatile uint32_t *pw) {
- return InterlockedDecrement((LONG volatile *)pw);
-}
-
-_ALWAYS_INLINE_ uint32_t _atomic_increment_impl(volatile uint32_t *pw) {
- return InterlockedIncrement((LONG volatile *)pw);
-}
-
-_ALWAYS_INLINE_ uint32_t _atomic_sub_impl(volatile uint32_t *pw, volatile uint32_t val) {
- return InterlockedExchangeAdd((LONG volatile *)pw, -(int32_t)val) - val;
-}
-
-_ALWAYS_INLINE_ uint32_t _atomic_add_impl(volatile uint32_t *pw, volatile uint32_t val) {
- return InterlockedAdd((LONG volatile *)pw, val);
-}
-
-_ALWAYS_INLINE_ uint32_t _atomic_exchange_if_greater_impl(volatile uint32_t *pw, volatile uint32_t val) {
- ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONG, InterlockedCompareExchange, uint32_t);
-}
-
-_ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(volatile uint64_t *pw) {
- ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t);
-}
-
-_ALWAYS_INLINE_ uint64_t _atomic_decrement_impl(volatile uint64_t *pw) {
- return InterlockedDecrement64((LONGLONG volatile *)pw);
-}
-
-_ALWAYS_INLINE_ uint64_t _atomic_increment_impl(volatile uint64_t *pw) {
- return InterlockedIncrement64((LONGLONG volatile *)pw);
-}
-
-_ALWAYS_INLINE_ uint64_t _atomic_sub_impl(volatile uint64_t *pw, volatile uint64_t val) {
- return InterlockedExchangeAdd64((LONGLONG volatile *)pw, -(int64_t)val) - val;
-}
-
-_ALWAYS_INLINE_ uint64_t _atomic_add_impl(volatile uint64_t *pw, volatile uint64_t val) {
- return InterlockedAdd64((LONGLONG volatile *)pw, val);
-}
-
-_ALWAYS_INLINE_ uint64_t _atomic_exchange_if_greater_impl(volatile uint64_t *pw, volatile uint64_t val) {
- ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONGLONG, InterlockedCompareExchange64, uint64_t);
-}
-
-// The actual advertised functions; they'll call the right implementation
-
-uint32_t atomic_conditional_increment(volatile uint32_t *pw) {
- return _atomic_conditional_increment_impl(pw);
-}
-
-uint32_t atomic_decrement(volatile uint32_t *pw) {
- return _atomic_decrement_impl(pw);
-}
-
-uint32_t atomic_increment(volatile uint32_t *pw) {
- return _atomic_increment_impl(pw);
-}
-
-uint32_t atomic_sub(volatile uint32_t *pw, volatile uint32_t val) {
- return _atomic_sub_impl(pw, val);
-}
-
-uint32_t atomic_add(volatile uint32_t *pw, volatile uint32_t val) {
- return _atomic_add_impl(pw, val);
-}
-
-uint32_t atomic_exchange_if_greater(volatile uint32_t *pw, volatile uint32_t val) {
- return _atomic_exchange_if_greater_impl(pw, val);
-}
-
-uint64_t atomic_conditional_increment(volatile uint64_t *pw) {
- return _atomic_conditional_increment_impl(pw);
-}
-
-uint64_t atomic_decrement(volatile uint64_t *pw) {
- return _atomic_decrement_impl(pw);
-}
-
-uint64_t atomic_increment(volatile uint64_t *pw) {
- return _atomic_increment_impl(pw);
-}
-
-uint64_t atomic_sub(volatile uint64_t *pw, volatile uint64_t val) {
- return _atomic_sub_impl(pw, val);
-}
-
-uint64_t atomic_add(volatile uint64_t *pw, volatile uint64_t val) {
- return _atomic_add_impl(pw, val);
-}
-
-uint64_t atomic_exchange_if_greater(volatile uint64_t *pw, volatile uint64_t val) {
- return _atomic_exchange_if_greater_impl(pw, val);
-}
-#endif
diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h
index 6b08b876f8..91a34ecd54 100644
--- a/core/templates/safe_refcount.h
+++ b/core/templates/safe_refcount.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,167 +31,291 @@
#ifndef SAFE_REFCOUNT_H
#define SAFE_REFCOUNT_H
-#include "core/os/mutex.h"
#include "core/typedefs.h"
-#include "platform_config.h"
-// Atomic functions, these are used for multithread safe reference counters!
+#if !defined(NO_THREADS)
-#ifdef NO_THREADS
+#include <atomic>
-/* Bogus implementation unaware of multiprocessing */
+// Design goals for these classes:
+// - No automatic conversions or arithmetic operators,
+// to keep explicit the use of atomics everywhere.
+// - Using acquire-release semantics, even to set the first value.
+// The first value may be set relaxedly in many cases, but adding the distinction
+// between relaxed and unrelaxed operation to the interface would make it needlessly
+// flexible. There's negligible waste in having release semantics for the initial
+// value and, as an important benefit, you can be sure the value is properly synchronized
+// even with threads that are already running.
+
+// This is used in very specific areas of the engine where it's critical that these guarantees are held
+#define SAFE_NUMERIC_TYPE_PUN_GUARANTEES(m_type) \
+ static_assert(sizeof(SafeNumeric<m_type>) == sizeof(m_type)); \
+ static_assert(alignof(SafeNumeric<m_type>) == alignof(m_type)); \
+ static_assert(std::is_trivially_destructible<std::atomic<m_type>>::value);
template <class T>
-static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
- if (*pw == 0) {
- return 0;
+class SafeNumeric {
+ std::atomic<T> value;
+
+ static_assert(std::atomic<T>::is_always_lock_free);
+
+public:
+ _ALWAYS_INLINE_ void set(T p_value) {
+ value.store(p_value, std::memory_order_release);
}
- (*pw)++;
+ _ALWAYS_INLINE_ T get() const {
+ return value.load(std::memory_order_acquire);
+ }
- return *pw;
-}
+ _ALWAYS_INLINE_ T increment() {
+ return value.fetch_add(1, std::memory_order_acq_rel) + 1;
+ }
-template <class T>
-static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) {
- (*pw)--;
+ // Returns the original value instead of the new one
+ _ALWAYS_INLINE_ T postincrement() {
+ return value.fetch_add(1, std::memory_order_acq_rel);
+ }
- return *pw;
-}
+ _ALWAYS_INLINE_ T decrement() {
+ return value.fetch_sub(1, std::memory_order_acq_rel) - 1;
+ }
-template <class T>
-static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) {
- (*pw)++;
+ // Returns the original value instead of the new one
+ _ALWAYS_INLINE_ T postdecrement() {
+ return value.fetch_sub(1, std::memory_order_acq_rel);
+ }
- return *pw;
-}
+ _ALWAYS_INLINE_ T add(T p_value) {
+ return value.fetch_add(p_value, std::memory_order_acq_rel) + p_value;
+ }
-template <class T, class V>
-static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) {
- (*pw) -= val;
+ // Returns the original value instead of the new one
+ _ALWAYS_INLINE_ T postadd(T p_value) {
+ return value.fetch_add(p_value, std::memory_order_acq_rel);
+ }
- return *pw;
-}
+ _ALWAYS_INLINE_ T sub(T p_value) {
+ return value.fetch_sub(p_value, std::memory_order_acq_rel) - p_value;
+ }
-template <class T, class V>
-static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) {
- (*pw) += val;
+ // Returns the original value instead of the new one
+ _ALWAYS_INLINE_ T postsub(T p_value) {
+ return value.fetch_sub(p_value, std::memory_order_acq_rel);
+ }
- return *pw;
-}
+ _ALWAYS_INLINE_ T exchange_if_greater(T p_value) {
+ while (true) {
+ T tmp = value.load(std::memory_order_acquire);
+ if (tmp >= p_value) {
+ return tmp; // already greater, or equal
+ }
+ if (value.compare_exchange_weak(tmp, p_value, std::memory_order_release)) {
+ return p_value;
+ }
+ }
+ }
-template <class T, class V>
-static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V val) {
- if (val > *pw) {
- *pw = val;
+ _ALWAYS_INLINE_ T conditional_increment() {
+ while (true) {
+ T c = value.load(std::memory_order_acquire);
+ if (c == 0) {
+ return 0;
+ }
+ if (value.compare_exchange_weak(c, c + 1, std::memory_order_release)) {
+ return c + 1;
+ }
+ }
}
- return *pw;
-}
+ _ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) {
+ set(p_value);
+ }
+};
-#elif defined(__GNUC__)
+class SafeFlag {
+ std::atomic_bool flag;
-/* Implementation for GCC & Clang */
+ static_assert(std::atomic_bool::is_always_lock_free);
-// GCC guarantees atomic intrinsics for sizes of 1, 2, 4 and 8 bytes.
-// Clang states it supports GCC atomic builtins.
+public:
+ _ALWAYS_INLINE_ bool is_set() const {
+ return flag.load(std::memory_order_acquire);
+ }
-template <class T>
-static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
- while (true) {
- T tmp = static_cast<T const volatile &>(*pw);
- if (tmp == 0) {
- return 0; // if zero, can't add to it anymore
- }
- if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp) {
- return tmp + 1;
- }
+ _ALWAYS_INLINE_ void set() {
+ flag.store(true, std::memory_order_release);
}
-}
-template <class T>
-static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) {
- return __sync_sub_and_fetch(pw, 1);
-}
+ _ALWAYS_INLINE_ void clear() {
+ flag.store(false, std::memory_order_release);
+ }
+
+ _ALWAYS_INLINE_ void set_to(bool p_value) {
+ flag.store(p_value, std::memory_order_release);
+ }
+
+ _ALWAYS_INLINE_ explicit SafeFlag(bool p_value = false) {
+ set_to(p_value);
+ }
+};
+
+class SafeRefCount {
+ SafeNumeric<uint32_t> count;
+
+public:
+ _ALWAYS_INLINE_ bool ref() { // true on success
+ return count.conditional_increment() != 0;
+ }
+
+ _ALWAYS_INLINE_ uint32_t refval() { // none-zero on success
+ return count.conditional_increment();
+ }
+
+ _ALWAYS_INLINE_ bool unref() { // true if must be disposed of
+ return count.decrement() == 0;
+ }
+
+ _ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of
+ return count.decrement();
+ }
+
+ _ALWAYS_INLINE_ uint32_t get() const {
+ return count.get();
+ }
+
+ _ALWAYS_INLINE_ void init(uint32_t p_value = 1) {
+ count.set(p_value);
+ }
+};
+
+#else
template <class T>
-static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) {
- return __sync_add_and_fetch(pw, 1);
-}
-
-template <class T, class V>
-static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) {
- return __sync_sub_and_fetch(pw, val);
-}
-
-template <class T, class V>
-static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) {
- return __sync_add_and_fetch(pw, val);
-}
-
-template <class T, class V>
-static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V val) {
- while (true) {
- T tmp = static_cast<T const volatile &>(*pw);
- if (tmp >= val) {
- return tmp; // already greater, or equal
+class SafeNumeric {
+protected:
+ T value;
+
+public:
+ _ALWAYS_INLINE_ void set(T p_value) {
+ value = p_value;
+ }
+
+ _ALWAYS_INLINE_ T get() const {
+ return value;
+ }
+
+ _ALWAYS_INLINE_ T increment() {
+ return ++value;
+ }
+
+ _ALWAYS_INLINE_ T postincrement() {
+ return value++;
+ }
+
+ _ALWAYS_INLINE_ T decrement() {
+ return --value;
+ }
+
+ _ALWAYS_INLINE_ T postdecrement() {
+ return value--;
+ }
+
+ _ALWAYS_INLINE_ T add(T p_value) {
+ return value += p_value;
+ }
+
+ _ALWAYS_INLINE_ T postadd(T p_value) {
+ T old = value;
+ value += p_value;
+ return old;
+ }
+
+ _ALWAYS_INLINE_ T sub(T p_value) {
+ return value -= p_value;
+ }
+
+ _ALWAYS_INLINE_ T postsub(T p_value) {
+ T old = value;
+ value -= p_value;
+ return old;
+ }
+
+ _ALWAYS_INLINE_ T exchange_if_greater(T p_value) {
+ if (value < p_value) {
+ value = p_value;
}
- if (__sync_val_compare_and_swap(pw, tmp, val) == tmp) {
- return val;
+ return value;
+ }
+
+ _ALWAYS_INLINE_ T conditional_increment() {
+ if (value == 0) {
+ return 0;
+ } else {
+ return ++value;
}
}
-}
-
-#elif defined(_MSC_VER)
-// For MSVC use a separate compilation unit to prevent windows.h from polluting
-// the global namespace.
-uint32_t atomic_conditional_increment(volatile uint32_t *pw);
-uint32_t atomic_decrement(volatile uint32_t *pw);
-uint32_t atomic_increment(volatile uint32_t *pw);
-uint32_t atomic_sub(volatile uint32_t *pw, volatile uint32_t val);
-uint32_t atomic_add(volatile uint32_t *pw, volatile uint32_t val);
-uint32_t atomic_exchange_if_greater(volatile uint32_t *pw, volatile uint32_t val);
-
-uint64_t atomic_conditional_increment(volatile uint64_t *pw);
-uint64_t atomic_decrement(volatile uint64_t *pw);
-uint64_t atomic_increment(volatile uint64_t *pw);
-uint64_t atomic_sub(volatile uint64_t *pw, volatile uint64_t val);
-uint64_t atomic_add(volatile uint64_t *pw, volatile uint64_t val);
-uint64_t atomic_exchange_if_greater(volatile uint64_t *pw, volatile uint64_t val);
-#else
-//no threads supported?
-#error Must provide atomic functions for this platform or compiler!
-#endif
+ _ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) :
+ value(p_value) {
+ }
+};
-struct SafeRefCount {
- uint32_t count = 0;
+class SafeFlag {
+protected:
+ bool flag;
public:
- // destroy() is called when weak_count_ drops to zero.
-
- _ALWAYS_INLINE_ bool ref() { // true on success
+ _ALWAYS_INLINE_ bool is_set() const {
+ return flag;
+ }
- return atomic_conditional_increment(&count) != 0;
+ _ALWAYS_INLINE_ void set() {
+ flag = true;
}
- _ALWAYS_INLINE_ uint32_t refval() { // none-zero on success
+ _ALWAYS_INLINE_ void clear() {
+ flag = false;
+ }
- return atomic_conditional_increment(&count);
+ _ALWAYS_INLINE_ void set_to(bool p_value) {
+ flag = p_value;
}
- _ALWAYS_INLINE_ bool unref() { // true if must be disposed of
+ _ALWAYS_INLINE_ explicit SafeFlag(bool p_value = false) :
+ flag(p_value) {}
+};
+
+class SafeRefCount {
+ uint32_t count = 0;
- return atomic_decrement(&count) == 0;
+public:
+ _ALWAYS_INLINE_ bool ref() { // true on success
+ if (count != 0) {
+ ++count;
+ return true;
+ } else {
+ return false;
+ }
}
- _ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of
+ _ALWAYS_INLINE_ uint32_t refval() { // none-zero on success
+ if (count != 0) {
+ return ++count;
+ } else {
+ return 0;
+ }
+ }
- return atomic_decrement(&count);
+ _ALWAYS_INLINE_ bool unref() { // true if must be disposed of
+ return --count == 0;
}
- _ALWAYS_INLINE_ uint32_t get() const { // nothrow
+ _ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of
+ return --count;
+ }
+ _ALWAYS_INLINE_ uint32_t get() const {
return count;
}
@@ -200,4 +324,6 @@ public:
}
};
+#endif
+
#endif // SAFE_REFCOUNT_H
diff --git a/core/templates/self_list.h b/core/templates/self_list.h
index 2a037d109c..e8d36ea358 100644
--- a/core/templates/self_list.h
+++ b/core/templates/self_list.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/set.h b/core/templates/set.h
index d0ac71a710..3036ecf27d 100644
--- a/core/templates/set.h
+++ b/core/templates/set.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -576,7 +576,7 @@ public:
return e;
}
- inline bool empty() const { return _data.size_cache == 0; }
+ inline bool is_empty() const { return _data.size_cache == 0; }
inline int size() const { return _data.size_cache; }
int calculate_depth() const {
diff --git a/core/templates/simple_type.h b/core/templates/simple_type.h
index 841ab9f384..80bfa83fde 100644
--- a/core/templates/simple_type.h
+++ b/core/templates/simple_type.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/sort_array.h b/core/templates/sort_array.h
index ece5e72e51..1656d2991d 100644
--- a/core/templates/sort_array.h
+++ b/core/templates/sort_array.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/templates/thread_work_pool.cpp b/core/templates/thread_work_pool.cpp
index 3a95e83ffc..17969a2c90 100644
--- a/core/templates/thread_work_pool.cpp
+++ b/core/templates/thread_work_pool.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,14 +32,15 @@
#include "core/os/os.h"
-void ThreadWorkPool::_thread_function(ThreadData *p_thread) {
+void ThreadWorkPool::_thread_function(void *p_user) {
+ ThreadData *thread = static_cast<ThreadData *>(p_user);
while (true) {
- p_thread->start.wait();
- if (p_thread->exit.load()) {
+ thread->start.wait();
+ if (thread->exit.load()) {
break;
}
- p_thread->work->work();
- p_thread->completed.post();
+ thread->work->work();
+ thread->completed.post();
}
}
@@ -54,7 +55,7 @@ void ThreadWorkPool::init(int p_thread_count) {
for (uint32_t i = 0; i < thread_count; i++) {
threads[i].exit.store(false);
- threads[i].thread = memnew(std::thread(ThreadWorkPool::_thread_function, &threads[i]));
+ threads[i].thread.start(&ThreadWorkPool::_thread_function, &threads[i]);
}
}
@@ -68,8 +69,7 @@ void ThreadWorkPool::finish() {
threads[i].start.post();
}
for (uint32_t i = 0; i < thread_count; i++) {
- threads[i].thread->join();
- memdelete(threads[i].thread);
+ threads[i].thread.wait_to_finish();
}
memdelete_arr(threads);
diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h
index e083cdcb24..19ab1dda3a 100644
--- a/core/templates/thread_work_pool.h
+++ b/core/templates/thread_work_pool.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,9 +33,9 @@
#include "core/os/memory.h"
#include "core/os/semaphore.h"
+#include "core/os/thread.h"
#include <atomic>
-#include <thread>
class ThreadWorkPool {
std::atomic<uint32_t> index;
@@ -64,7 +64,7 @@ class ThreadWorkPool {
};
struct ThreadData {
- std::thread *thread;
+ Thread thread;
Semaphore start;
Semaphore completed;
std::atomic<bool> exit;
@@ -75,7 +75,7 @@ class ThreadWorkPool {
uint32_t thread_count = 0;
BaseWork *current_work = nullptr;
- static void _thread_function(ThreadData *p_thread);
+ static void _thread_function(void *p_user);
public:
template <class C, class M, class U>
@@ -125,6 +125,7 @@ public:
end_work();
}
+ _FORCE_INLINE_ int get_thread_count() const { return thread_count; }
void init(int p_thread_count = -1);
void finish();
~ThreadWorkPool();
diff --git a/core/templates/vector.h b/core/templates/vector.h
index 7420384bf7..6a8902707c 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -79,7 +79,7 @@ public:
_FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
_FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); }
_FORCE_INLINE_ void clear() { resize(0); }
- _FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
+ _FORCE_INLINE_ bool is_empty() const { return _cowdata.is_empty(); }
_FORCE_INLINE_ T get(int p_index) { return _cowdata.get(p_index); }
_FORCE_INLINE_ const T &get(int p_index) const { return _cowdata.get(p_index); }
diff --git a/core/templates/vmap.h b/core/templates/vmap.h
index 8d2a3d2a9c..520e0b3720 100644
--- a/core/templates/vmap.h
+++ b/core/templates/vmap.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,7 +54,7 @@ private:
_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
r_exact = false;
- if (_cowdata.empty()) {
+ if (_cowdata.is_empty()) {
return 0;
}
@@ -89,7 +89,7 @@ private:
}
_FORCE_INLINE_ int _find_exact(const T &p_val) const {
- if (_cowdata.empty()) {
+ if (_cowdata.is_empty()) {
return -1;
}
@@ -147,7 +147,7 @@ public:
}
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
- _FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
+ _FORCE_INLINE_ bool is_empty() const { return _cowdata.is_empty(); }
const Pair *get_array() const {
return _cowdata.ptr();
diff --git a/core/templates/vset.h b/core/templates/vset.h
index 4c0b8717b6..6665651d42 100644
--- a/core/templates/vset.h
+++ b/core/templates/vset.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@ class VSet {
_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
r_exact = false;
- if (_data.empty()) {
+ if (_data.is_empty()) {
return 0;
}
@@ -76,7 +76,7 @@ class VSet {
}
_FORCE_INLINE_ int _find_exact(const T &p_val) const {
- if (_data.empty()) {
+ if (_data.is_empty()) {
return -1;
}
@@ -126,7 +126,7 @@ public:
return _find_exact(p_val);
}
- _FORCE_INLINE_ bool empty() const { return _data.empty(); }
+ _FORCE_INLINE_ bool is_empty() const { return _data.is_empty(); }
_FORCE_INLINE_ int size() const { return _data.size(); }
diff --git a/core/typedefs.h b/core/typedefs.h
index 7c98bc37f7..cdbfb34e56 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 5043868b1d..9a2922a777 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,6 +35,7 @@
#include "core/object/script_language.h"
#include "core/templates/hashfuncs.h"
#include "core/templates/vector.h"
+#include "core/variant/callable.h"
#include "core/variant/variant.h"
class ArrayPrivate {
@@ -86,8 +87,8 @@ int Array::size() const {
return _p->array.size();
}
-bool Array::empty() const {
- return _p->array.empty();
+bool Array::is_empty() const {
+ return _p->array.is_empty();
}
void Array::clear() {
@@ -318,7 +319,7 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // l
ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero.");
- if (empty()) { // Don't try to slice empty arrays.
+ if (is_empty()) { // Don't try to slice empty arrays.
return new_arr;
}
if (p_step > 0) {
@@ -371,25 +372,22 @@ void Array::sort() {
}
struct _ArrayVariantSortCustom {
- Object *obj = nullptr;
- StringName func;
+ Callable func;
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
const Variant *args[2] = { &p_l, &p_r };
Callable::CallError err;
- bool res = obj->call(func, args, 2, err);
- if (err.error != Callable::CallError::CALL_OK) {
- res = false;
- }
+ Variant res;
+ func.call(args, 2, res, err);
+ ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false,
+ "Error calling sorting method: " + Variant::get_callable_error_text(func, args, 1, err));
return res;
}
};
-void Array::sort_custom(Object *p_obj, const StringName &p_function) {
- ERR_FAIL_NULL(p_obj);
+void Array::sort_custom(Callable p_callable) {
SortArray<Variant, _ArrayVariantSortCustom, true> avs;
- avs.compare.obj = p_obj;
- avs.compare.func = p_function;
+ avs.compare.func = p_callable;
avs.sort(_p->array.ptrw(), _p->array.size());
}
@@ -438,13 +436,11 @@ int Array::bsearch(const Variant &p_value, bool p_before) {
return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
}
-int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
+int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before) {
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1);
- ERR_FAIL_NULL_V(p_obj, 0);
_ArrayVariantSortCustom less;
- less.obj = p_obj;
- less.func = p_function;
+ less.func = p_callable;
return bisect(_p->array, p_value, p_before, less);
}
@@ -459,7 +455,7 @@ void Array::push_front(const Variant &p_value) {
}
Variant Array::pop_back() {
- if (!_p->array.empty()) {
+ if (!_p->array.is_empty()) {
int n = _p->array.size() - 1;
Variant ret = _p->array.get(n);
_p->array.resize(n);
@@ -469,7 +465,7 @@ Variant Array::pop_back() {
}
Variant Array::pop_front() {
- if (!_p->array.empty()) {
+ if (!_p->array.is_empty()) {
Variant ret = _p->array.get(0);
_p->array.remove(0);
return ret;
diff --git a/core/variant/array.h b/core/variant/array.h
index e01ac13168..d8f2402330 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,6 +37,7 @@ class Variant;
class ArrayPrivate;
class Object;
class StringName;
+class Callable;
class Array {
mutable ArrayPrivate *_p;
@@ -57,7 +58,7 @@ public:
const Variant &get(int p_idx) const;
int size() const;
- bool empty() const;
+ bool is_empty() const;
void clear();
bool operator==(const Array &p_array) const;
@@ -78,10 +79,10 @@ public:
Variant back() const;
void sort();
- void sort_custom(Object *p_obj, const StringName &p_function);
+ void sort_custom(Callable p_callable);
void shuffle();
int bsearch(const Variant &p_value, bool p_before = true);
- int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true);
+ int bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before = true);
void invert();
int find(const Variant &p_value, int p_from = 0) const;
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 95113c89ba..490bd45b7b 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -88,6 +88,7 @@ VARIANT_ENUM_CAST(Vector3::Axis);
VARIANT_ENUM_CAST(Error);
VARIANT_ENUM_CAST(Side);
+VARIANT_ENUM_CAST(ClockDirection);
VARIANT_ENUM_CAST(Corner);
VARIANT_ENUM_CAST(Orientation);
VARIANT_ENUM_CAST(HAlign);
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index e504fd05e3..bd51e2dd1e 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 9334ae3581..090fd888e2 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp
index da08d3ccbd..10446a5ec1 100644
--- a/core/variant/callable_bind.cpp
+++ b/core/variant/callable_bind.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h
index fc5659e412..feb40d1de9 100644
--- a/core/variant/callable_bind.h
+++ b/core/variant/callable_bind.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/container_type_validate.h b/core/variant/container_type_validate.h
index 4d3a5f683b..f13a37cddd 100644
--- a/core/variant/container_type_validate.h
+++ b/core/variant/container_type_validate.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index 2bc1f7a86d..b2f7c6aa0a 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@ struct DictionaryPrivate {
};
void Dictionary::get_key_list(List<Variant> *p_keys) const {
- if (_p->variant_map.empty()) {
+ if (_p->variant_map.is_empty()) {
return;
}
@@ -121,7 +121,7 @@ int Dictionary::size() const {
return _p->variant_map.size();
}
-bool Dictionary::empty() const {
+bool Dictionary::is_empty() const {
return !_p->variant_map.size();
}
@@ -192,7 +192,7 @@ uint32_t Dictionary::hash() const {
Array Dictionary::keys() const {
Array varr;
- if (_p->variant_map.empty()) {
+ if (_p->variant_map.is_empty()) {
return varr;
}
@@ -209,7 +209,7 @@ Array Dictionary::keys() const {
Array Dictionary::values() const {
Array varr;
- if (_p->variant_map.empty()) {
+ if (_p->variant_map.is_empty()) {
return varr;
}
diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h
index bbe94122ad..4067ff9fd9 100644
--- a/core/variant/dictionary.h
+++ b/core/variant/dictionary.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -60,7 +60,7 @@ public:
Variant get(const Variant &p_key, const Variant &p_default) const;
int size() const;
- bool empty() const;
+ bool is_empty() const;
void clear();
bool has(const Variant &p_key) const;
diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h
index b00455f8ad..c294592b63 100644
--- a/core/variant/method_ptrcall.h
+++ b/core/variant/method_ptrcall.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/type_info.h b/core/variant/type_info.h
index ce7c2bfe14..f61ff29b8f 100644
--- a/core/variant/type_info.h
+++ b/core/variant/type_info.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h
index 2f11f22ff8..e0309aa3fe 100644
--- a/core/variant/typed_array.h
+++ b/core/variant/typed_array.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 9eb512f71d..015cee09a7 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -912,11 +912,11 @@ bool Variant::is_zero() const {
} break;
case DICTIONARY: {
- return reinterpret_cast<const Dictionary *>(_data._mem)->empty();
+ return reinterpret_cast<const Dictionary *>(_data._mem)->is_empty();
} break;
case ARRAY: {
- return reinterpret_cast<const Array *>(_data._mem)->empty();
+ return reinterpret_cast<const Array *>(_data._mem)->is_empty();
} break;
@@ -2023,7 +2023,7 @@ Variant::operator Color() const {
if (type == COLOR) {
return *reinterpret_cast<const Color *>(_data._mem);
} else if (type == STRING) {
- return Color::html(operator String());
+ return Color(operator String());
} else if (type == INT) {
return Color::hex(operator int());
} else {
diff --git a/core/variant/variant.h b/core/variant/variant.h
index b22488a877..5050aa24ec 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -497,6 +497,7 @@ public:
static bool is_builtin_method_const(Variant::Type p_type, const StringName &p_method);
static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method);
static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list);
+ static int get_builtin_method_count(Variant::Type p_type);
void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant());
@@ -535,6 +536,7 @@ public:
static bool has_member(Variant::Type p_type, const StringName &p_member);
static Variant::Type get_member_type(Variant::Type p_type, const StringName &p_member);
static void get_member_list(Type p_type, List<StringName> *r_members);
+ static int get_member_count(Type p_type);
static ValidatedSetter get_member_validated_setter(Variant::Type p_type, const StringName &p_member);
static ValidatedGetter get_member_validated_getter(Variant::Type p_type, const StringName &p_member);
@@ -628,6 +630,7 @@ public:
static bool is_utility_function_vararg(const StringName &p_name);
static void get_utility_function_list(List<StringName> *r_functions);
+ static int get_utility_function_count();
//argsVariant call()
@@ -642,6 +645,7 @@ public:
void static_assign(const Variant &p_variant);
static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants);
+ static int get_constants_count_for_type(Variant::Type p_type);
static bool has_constant(Variant::Type p_type, const StringName &p_value);
static Variant get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid = nullptr);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index afe4f2702e..90272ad5b4 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -705,6 +705,11 @@ void Variant::get_builtin_method_list(Variant::Type p_type, List<StringName> *p_
}
}
+int Variant::get_builtin_method_count(Variant::Type p_type) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1);
+ return builtin_method_names[p_type].size();
+}
+
Variant::Type Variant::get_builtin_method_return_type(Variant::Type p_type, const StringName &p_method) {
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::NIL);
const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method);
@@ -799,6 +804,13 @@ void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_c
}
}
+int Variant::get_constants_count_for_type(Variant::Type p_type) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1);
+ _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type];
+
+ return cd.value.size() + cd.variant_value.size();
+}
+
bool Variant::has_constant(Variant::Type p_type, const StringName &p_value) {
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false);
_VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type];
@@ -917,7 +929,7 @@ static void _register_variant_builtin_methods() {
bind_method(String, get_extension, sarray(), varray());
bind_method(String, get_basename, sarray(), varray());
bind_method(String, plus_file, sarray("file"), varray());
- bind_method(String, ord_at, sarray("at"), varray());
+ bind_method(String, unicode_at, sarray("at"), varray());
bind_method(String, dedent, sarray(), varray());
// FIXME: String needs to be immutable when binding
//bind_method(String, erase, sarray("position", "chars"), varray());
@@ -928,7 +940,7 @@ static void _register_variant_builtin_methods() {
bind_method(String, md5_buffer, sarray(), varray());
bind_method(String, sha1_buffer, sarray(), varray());
bind_method(String, sha256_buffer, sarray(), varray());
- bind_method(String, empty, sarray(), varray());
+ bind_method(String, is_empty, sarray(), varray());
// FIXME: Static function, not sure how to bind
//bind_method(String, humanize_size, sarray("size"), varray());
@@ -938,13 +950,13 @@ static void _register_variant_builtin_methods() {
bind_method(String, get_file, sarray(), varray());
bind_method(String, xml_escape, sarray("escape_quotes"), varray(false));
bind_method(String, xml_unescape, sarray(), varray());
- bind_method(String, http_escape, sarray(), varray());
- bind_method(String, http_unescape, sarray(), varray());
+ bind_method(String, uri_encode, sarray(), varray());
+ bind_method(String, uri_decode, sarray(), varray());
bind_method(String, c_escape, sarray(), varray());
bind_method(String, c_unescape, sarray(), varray());
bind_method(String, json_escape, sarray(), varray());
- bind_method(String, percent_encode, sarray(), varray());
- bind_method(String, percent_decode, sarray(), varray());
+
+ bind_method(String, validate_node_name, sarray(), varray());
bind_method(String, is_valid_identifier, sarray(), varray());
bind_method(String, is_valid_integer, sarray(), varray());
@@ -956,8 +968,8 @@ static void _register_variant_builtin_methods() {
bind_method(String, to_int, sarray(), varray());
bind_method(String, to_float, sarray(), varray());
- bind_method(String, hex_to_int, sarray("with_prefix"), varray(true));
- bind_method(String, bin_to_int, sarray("with_prefix"), varray(true));
+ bind_method(String, hex_to_int, sarray(), varray());
+ bind_method(String, bin_to_int, sarray(), varray());
bind_method(String, lpad, sarray("min_length", "character"), varray(" "));
bind_method(String, rpad, sarray("min_length", "character"), varray(" "));
@@ -992,7 +1004,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray());
bind_method(Vector2, move_toward, sarray("to", "delta"), varray());
bind_method(Vector2, rotated, sarray("phi"), varray());
- bind_method(Vector2, tangent, sarray(), varray());
+ bind_method(Vector2, orthogonal, sarray(), varray());
bind_method(Vector2, floor, sarray(), varray());
bind_method(Vector2, ceil, sarray(), varray());
bind_method(Vector2, round, sarray(), varray());
@@ -1004,7 +1016,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, cross, sarray("with"), varray());
bind_method(Vector2, abs, sarray(), varray());
bind_method(Vector2, sign, sarray(), varray());
- bind_method(Vector2, snapped, sarray("by"), varray());
+ bind_method(Vector2, snapped, sarray("step"), varray());
bind_method(Vector2, clamped, sarray("length"), varray());
/* Vector2i */
@@ -1024,8 +1036,8 @@ static void _register_variant_builtin_methods() {
bind_method(Rect2, intersection, sarray("b"), varray());
bind_method(Rect2, merge, sarray("b"), varray());
bind_method(Rect2, expand, sarray("to"), varray());
- bind_method(Rect2, grow, sarray("by"), varray());
- bind_methodv(Rect2, grow_margin, &Rect2::grow_margin_bind, sarray("margin", "by"), varray());
+ bind_method(Rect2, grow, sarray("amount"), varray());
+ bind_methodv(Rect2, grow_side, &Rect2::grow_side_bind, sarray("side", "amount"), varray());
bind_method(Rect2, grow_individual, sarray("left", "top", "right", "bottom"), varray());
bind_method(Rect2, abs, sarray(), varray());
@@ -1039,8 +1051,8 @@ static void _register_variant_builtin_methods() {
bind_method(Rect2i, intersection, sarray("b"), varray());
bind_method(Rect2i, merge, sarray("b"), varray());
bind_method(Rect2i, expand, sarray("to"), varray());
- bind_method(Rect2i, grow, sarray("by"), varray());
- bind_methodv(Rect2i, grow_margin, &Rect2i::grow_margin_bind, sarray("margin", "by"), varray());
+ bind_method(Rect2i, grow, sarray("amount"), varray());
+ bind_methodv(Rect2i, grow_side, &Rect2i::grow_side_bind, sarray("side", "amount"), varray());
bind_method(Rect2i, grow_individual, sarray("left", "top", "right", "bottom"), varray());
bind_method(Rect2i, abs, sarray(), varray());
@@ -1049,6 +1061,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3, min_axis, sarray(), varray());
bind_method(Vector3, max_axis, sarray(), varray());
bind_method(Vector3, angle_to, sarray("to"), varray());
+ bind_method(Vector3, signed_angle_to, sarray("to", "axis"), varray());
bind_method(Vector3, direction_to, sarray("b"), varray());
bind_method(Vector3, distance_to, sarray("b"), varray());
bind_method(Vector3, distance_squared_to, sarray("b"), varray());
@@ -1058,7 +1071,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3, is_normalized, sarray(), varray());
bind_method(Vector3, is_equal_approx, sarray("to"), varray());
bind_method(Vector3, inverse, sarray(), varray());
- bind_method(Vector3, snapped, sarray("by"), varray());
+ bind_method(Vector3, snapped, sarray("step"), varray());
bind_method(Vector3, rotated, sarray("by_axis", "phi"), varray());
bind_method(Vector3, lerp, sarray("to", "weight"), varray());
bind_method(Vector3, slerp, sarray("to", "weight"), varray());
@@ -1114,10 +1127,6 @@ static void _register_variant_builtin_methods() {
bind_method(Quat, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray());
bind_method(Quat, get_euler, sarray(), varray());
- // FIXME: Quat is atomic, this should be done via construcror
- //ADDFUNC1(QUAT, NIL, Quat, set_euler, VECTOR3, "euler", varray());
- //ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", FLOAT, "angle", varray());
-
/* Color */
bind_method(Color, to_argb32, sarray(), varray());
@@ -1204,7 +1213,7 @@ static void _register_variant_builtin_methods() {
bind_method(Basis, transposed, sarray(), varray());
bind_method(Basis, orthonormalized, sarray(), varray());
bind_method(Basis, determinant, sarray(), varray());
- bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, float) const>(&Basis::rotated), sarray("axis", "phi"), varray());
+ bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, real_t) const>(&Basis::rotated), sarray("axis", "phi"), varray());
bind_method(Basis, scaled, sarray("scale"), varray());
bind_method(Basis, get_scale, sarray(), varray());
bind_method(Basis, get_euler, sarray(), varray());
@@ -1250,14 +1259,14 @@ static void _register_variant_builtin_methods() {
bind_method(Transform, rotated, sarray("axis", "phi"), varray());
bind_method(Transform, scaled, sarray("scale"), varray());
bind_method(Transform, translated, sarray("offset"), varray());
- bind_method(Transform, looking_at, sarray("target", "up"), varray());
+ bind_method(Transform, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
bind_method(Transform, interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform, is_equal_approx, sarray("xform"), varray());
/* Dictionary */
bind_method(Dictionary, size, sarray(), varray());
- bind_method(Dictionary, empty, sarray(), varray());
+ bind_method(Dictionary, is_empty, sarray(), varray());
bind_method(Dictionary, clear, sarray(), varray());
bind_method(Dictionary, has, sarray("key"), varray());
bind_method(Dictionary, has_all, sarray("keys"), varray());
@@ -1271,7 +1280,7 @@ static void _register_variant_builtin_methods() {
/* Array */
bind_method(Array, size, sarray(), varray());
- bind_method(Array, empty, sarray(), varray());
+ bind_method(Array, is_empty, sarray(), varray());
bind_method(Array, clear, sarray(), varray());
bind_method(Array, hash, sarray(), varray());
bind_method(Array, push_back, sarray("value"), varray());
@@ -1292,10 +1301,10 @@ static void _register_variant_builtin_methods() {
bind_method(Array, pop_back, sarray(), varray());
bind_method(Array, pop_front, sarray(), varray());
bind_method(Array, sort, sarray(), varray());
- bind_method(Array, sort_custom, sarray("obj", "func"), varray());
+ bind_method(Array, sort_custom, sarray("func"), varray());
bind_method(Array, shuffle, sarray(), varray());
bind_method(Array, bsearch, sarray("value", "before"), varray(true));
- bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true));
+ bind_method(Array, bsearch_custom, sarray("value", "func", "before"), varray(true));
bind_method(Array, invert, sarray(), varray());
bind_method(Array, duplicate, sarray("deep"), varray(false));
bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false));
@@ -1304,7 +1313,7 @@ static void _register_variant_builtin_methods() {
/* Byte Array */
bind_method(PackedByteArray, size, sarray(), varray());
- bind_method(PackedByteArray, empty, sarray(), varray());
+ bind_method(PackedByteArray, is_empty, sarray(), varray());
bind_method(PackedByteArray, set, sarray("index", "value"), varray());
bind_method(PackedByteArray, push_back, sarray("value"), varray());
bind_method(PackedByteArray, append, sarray("value"), varray());
@@ -1330,7 +1339,7 @@ static void _register_variant_builtin_methods() {
/* Int32 Array */
bind_method(PackedInt32Array, size, sarray(), varray());
- bind_method(PackedInt32Array, empty, sarray(), varray());
+ bind_method(PackedInt32Array, is_empty, sarray(), varray());
bind_method(PackedInt32Array, set, sarray("index", "value"), varray());
bind_method(PackedInt32Array, push_back, sarray("value"), varray());
bind_method(PackedInt32Array, append, sarray("value"), varray());
@@ -1348,7 +1357,7 @@ static void _register_variant_builtin_methods() {
/* Int64 Array */
bind_method(PackedInt64Array, size, sarray(), varray());
- bind_method(PackedInt64Array, empty, sarray(), varray());
+ bind_method(PackedInt64Array, is_empty, sarray(), varray());
bind_method(PackedInt64Array, set, sarray("index", "value"), varray());
bind_method(PackedInt64Array, push_back, sarray("value"), varray());
bind_method(PackedInt64Array, append, sarray("value"), varray());
@@ -1366,7 +1375,7 @@ static void _register_variant_builtin_methods() {
/* Float32 Array */
bind_method(PackedFloat32Array, size, sarray(), varray());
- bind_method(PackedFloat32Array, empty, sarray(), varray());
+ bind_method(PackedFloat32Array, is_empty, sarray(), varray());
bind_method(PackedFloat32Array, set, sarray("index", "value"), varray());
bind_method(PackedFloat32Array, push_back, sarray("value"), varray());
bind_method(PackedFloat32Array, append, sarray("value"), varray());
@@ -1384,7 +1393,7 @@ static void _register_variant_builtin_methods() {
/* Float64 Array */
bind_method(PackedFloat64Array, size, sarray(), varray());
- bind_method(PackedFloat64Array, empty, sarray(), varray());
+ bind_method(PackedFloat64Array, is_empty, sarray(), varray());
bind_method(PackedFloat64Array, set, sarray("index", "value"), varray());
bind_method(PackedFloat64Array, push_back, sarray("value"), varray());
bind_method(PackedFloat64Array, append, sarray("value"), varray());
@@ -1402,7 +1411,7 @@ static void _register_variant_builtin_methods() {
/* String Array */
bind_method(PackedStringArray, size, sarray(), varray());
- bind_method(PackedStringArray, empty, sarray(), varray());
+ bind_method(PackedStringArray, is_empty, sarray(), varray());
bind_method(PackedStringArray, set, sarray("index", "value"), varray());
bind_method(PackedStringArray, push_back, sarray("value"), varray());
bind_method(PackedStringArray, append, sarray("value"), varray());
@@ -1420,7 +1429,7 @@ static void _register_variant_builtin_methods() {
/* Vector2 Array */
bind_method(PackedVector2Array, size, sarray(), varray());
- bind_method(PackedVector2Array, empty, sarray(), varray());
+ bind_method(PackedVector2Array, is_empty, sarray(), varray());
bind_method(PackedVector2Array, set, sarray("index", "value"), varray());
bind_method(PackedVector2Array, push_back, sarray("value"), varray());
bind_method(PackedVector2Array, append, sarray("value"), varray());
@@ -1438,7 +1447,7 @@ static void _register_variant_builtin_methods() {
/* Vector3 Array */
bind_method(PackedVector3Array, size, sarray(), varray());
- bind_method(PackedVector3Array, empty, sarray(), varray());
+ bind_method(PackedVector3Array, is_empty, sarray(), varray());
bind_method(PackedVector3Array, set, sarray("index", "value"), varray());
bind_method(PackedVector3Array, push_back, sarray("value"), varray());
bind_method(PackedVector3Array, append, sarray("value"), varray());
@@ -1456,7 +1465,7 @@ static void _register_variant_builtin_methods() {
/* Color Array */
bind_method(PackedColorArray, size, sarray(), varray());
- bind_method(PackedColorArray, empty, sarray(), varray());
+ bind_method(PackedColorArray, is_empty, sarray(), varray());
bind_method(PackedColorArray, set, sarray("index", "value"), varray());
bind_method(PackedColorArray, push_back, sarray("value"), varray());
bind_method(PackedColorArray, append, sarray("value"), varray());
diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp
index 732e7a26f2..f0c9e52b46 100644
--- a/core/variant/variant_construct.cpp
+++ b/core/variant/variant_construct.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -688,6 +688,8 @@ void Variant::_register_variant_constructors() {
add_constructor<VariantConstructor<Color, Color, double>>(sarray("from", "alpha"));
add_constructor<VariantConstructor<Color, double, double, double>>(sarray("r", "g", "b"));
add_constructor<VariantConstructor<Color, double, double, double, double>>(sarray("r", "g", "b", "a"));
+ add_constructor<VariantConstructor<Color, String>>(sarray("code"));
+ add_constructor<VariantConstructor<Color, String, double>>(sarray("code", "alpha"));
add_constructor<VariantConstructNoArgs<StringName>>(sarray());
add_constructor<VariantConstructor<StringName, StringName>>(sarray("from"));
@@ -771,6 +773,7 @@ void Variant::_unregister_variant_constructors() {
}
void Variant::construct(Variant::Type p_type, Variant &base, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+ ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX);
uint32_t s = construct_data[p_type].size();
for (uint32_t i = 0; i < s; i++) {
int argc = construct_data[p_type][i].argument_count;
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 57e8f8813f..7d33d85cd6 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp
index df29ec7b63..e0a3cf4215 100644
--- a/core/variant/variant_op.cpp
+++ b/core/variant/variant_op.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -318,6 +318,7 @@ public:
r_valid = true;
}
static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ VariantTypeChanger<R>::change(r_ret);
*VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) & *VariantGetInternalPtr<B>::get_ptr(right);
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 00d81f597a..ed936c626b 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h
index cf1941a40e..5703f0200c 100644
--- a/core/variant/variant_parser.h
+++ b/core/variant/variant_parser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 28cf8ef967..ea8263402a 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -437,6 +437,11 @@ void Variant::get_member_list(Variant::Type p_type, List<StringName> *r_members)
}
}
+int Variant::get_member_count(Type p_type) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1);
+ return variant_setters_getters_names[p_type].size();
+}
+
Variant::ValidatedSetter Variant::get_member_validated_setter(Variant::Type p_type, const StringName &p_member) {
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
@@ -1472,7 +1477,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
case STRING: {
const String *str = reinterpret_cast<const String *>(_data._mem);
- if (str->empty()) {
+ if (str->is_empty()) {
return false;
}
r_iter = 0;
@@ -1480,7 +1485,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
} break;
case DICTIONARY: {
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
- if (dic->empty()) {
+ if (dic->is_empty()) {
return false;
}
@@ -1491,7 +1496,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
} break;
case ARRAY: {
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
- if (arr->empty()) {
+ if (arr->is_empty()) {
return false;
}
r_iter = 0;
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index d54e223a99..f154ab1ed6 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -217,8 +217,8 @@ struct VariantUtilityFunctions {
return Math::range_step_decimals(step);
}
- static inline double stepify(double value, double step) {
- return Math::stepify(value, step);
+ static inline double snapped(double value, double step) {
+ return Math::snapped(value, step);
}
static inline double lerp(double from, double to, double weight) {
@@ -291,7 +291,7 @@ struct VariantUtilityFunctions {
Variant ret;
for (int i = 1; i < p_argcount; i++) {
bool valid;
- Variant::evaluate(Variant::OP_GREATER, base, *p_args[i], ret, valid);
+ Variant::evaluate(Variant::OP_LESS, base, *p_args[i], ret, valid);
if (!valid) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.expected = base.get_type();
@@ -324,7 +324,7 @@ struct VariantUtilityFunctions {
Variant ret;
for (int i = 1; i < p_argcount; i++) {
bool valid;
- Variant::evaluate(Variant::OP_LESS, base, *p_args[i], ret, valid);
+ Variant::evaluate(Variant::OP_GREATER, base, *p_args[i], ret, valid);
if (!valid) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.expected = base.get_type();
@@ -1181,7 +1181,7 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(ease, sarray("x", "curve"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(range_step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(stepify, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(snapped, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(lerp_angle, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);
@@ -1379,3 +1379,7 @@ void Variant::get_utility_function_list(List<StringName> *r_functions) {
r_functions->push_back(E->get());
}
}
+
+int Variant::get_utility_function_count() {
+ return utility_function_name_table.size();
+}
diff --git a/core/version.h b/core/version.h
index 1198f62db4..2a4fa9cfd4 100644
--- a/core/version.h
+++ b/core/version.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/doc/Makefile b/doc/Makefile
index 9534da9bd5..d4bc53bcf9 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -2,6 +2,7 @@ BASEDIR = $(CURDIR)
CLASSES = $(BASEDIR)/classes/ $(BASEDIR)/../modules/
OUTPUTDIR = $(BASEDIR)/_build
TOOLSDIR = $(BASEDIR)/tools
+JSDIR = $(BASEDIR)/../platform/javascript
.ONESHELL:
@@ -16,6 +17,10 @@ doxygen:
rst:
rm -rf $(OUTPUTDIR)/rst
mkdir -p $(OUTPUTDIR)/rst
- pushd $(OUTPUTDIR)/rst
- python3 $(TOOLSDIR)/makerst.py $(CLASSES)
- popd
+ python3 $(TOOLSDIR)/makerst.py -o $(OUTPUTDIR)/rst $(CLASSES)
+
+rstjs:
+ rm -rf $(OUTPUTDIR)/rstjs
+ mkdir -p $(OUTPUTDIR)/rstjs
+ npm --prefix $(JSDIR) ci
+ npm --prefix $(JSDIR) run docs -- --destination $(OUTPUTDIR)/rstjs/html5_shell_classref.rst
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index f128de52ea..d57d241b53 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -140,7 +140,7 @@
i = ceil(1.45) # i is 2
i = ceil(1.001) # i is 2
[/codeblock]
- See also [method floor], [method round], and [method stepify].
+ See also [method floor], [method round], and [method snapped].
</description>
</method>
<method name="clamp">
@@ -303,7 +303,7 @@
# a is -3.0
a = floor(-2.99)
[/codeblock]
- See also [method ceil], [method round], and [method stepify].
+ See also [method ceil], [method round], and [method snapped].
[b]Note:[/b] This method returns a float. If you need an integer, you can use [code]int(x)[/code] directly.
</description>
</method>
@@ -668,7 +668,7 @@
</method>
<method name="print" qualifiers="vararg">
<description>
- Converts one or more arguments to strings in the best way possible and prints them to the console.
+ Converts one or more arguments of any type to string in the best way possible and prints them to the console.
[codeblock]
a = [1, 2, 3]
print("a", "b", a) # Prints ab[1, 2, 3]
@@ -848,7 +848,7 @@
[codeblock]
round(2.6) # Returns 3
[/codeblock]
- See also [method floor], [method ceil], and [method stepify].
+ See also [method floor], [method ceil], and [method snapped].
</description>
</method>
<method name="seed">
@@ -935,7 +935,7 @@
<description>
Returns the result of smoothly interpolating the value of [code]x[/code] between [code]0[/code] and [code]1[/code], based on the where [code]x[/code] lies with respect to the edges [code]from[/code] and [code]to[/code].
The return value is [code]0[/code] if [code]x &lt;= from[/code], and [code]1[/code] if [code]x &gt;= to[/code]. If [code]x[/code] lies between [code]from[/code] and [code]to[/code], the returned value follows an S-shaped curve that maps [code]x[/code] between [code]0[/code] and [code]1[/code].
- This S-shaped curve is the cubic Hermite interpolator, given by [code]f(x) = 3*x^2 - 2*x^3[/code].
+ This S-shaped curve is the cubic Hermite interpolator, given by [code]f(y) = 3*y^2 - 2*y^3[/code] where [code]y = (x-from) / (to-from)[/code].
[codeblock]
smoothstep(0, 2, -5.0) # Returns 0.0
smoothstep(0, 2, 0.5) # Returns 0.15625
@@ -944,6 +944,22 @@
[/codeblock]
</description>
</method>
+ <method name="snapped">
+ <return type="float">
+ </return>
+ <argument index="0" name="x" type="float">
+ </argument>
+ <argument index="1" name="step" type="float">
+ </argument>
+ <description>
+ Snaps float value [code]x[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals.
+ [codeblock]
+ snapped(100, 32) # Returns 96
+ snapped(3.14159, 0.01) # Returns 3.14
+ [/codeblock]
+ See also [method ceil], [method floor], and [method round].
+ </description>
+ </method>
<method name="sqrt">
<return type="float">
</return>
@@ -974,27 +990,11 @@
[/codeblock]
</description>
</method>
- <method name="stepify">
- <return type="float">
- </return>
- <argument index="0" name="x" type="float">
- </argument>
- <argument index="1" name="step" type="float">
- </argument>
- <description>
- Snaps float value [code]x[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals.
- [codeblock]
- stepify(100, 32) # Returns 96
- stepify(3.14159, 0.01) # Returns 3.14
- [/codeblock]
- See also [method ceil], [method floor], and [method round].
- </description>
- </method>
<method name="str" qualifiers="vararg">
<return type="String">
</return>
<description>
- Converts one or more arguments to string in the best way possible.
+ Converts one or more arguments of any type to string in the best way possible.
</description>
</method>
<method name="str2var">
@@ -1280,6 +1280,10 @@
<constant name="HORIZONTAL" value="0" enum="Orientation">
General horizontal alignment, usually used for [Separator], [ScrollBar], [Slider], etc.
</constant>
+ <constant name="CLOCKWISE" value="0" enum="ClockDirection">
+ </constant>
+ <constant name="COUNTERCLOCKWISE" value="1" enum="ClockDirection">
+ </constant>
<constant name="HALIGN_LEFT" value="0" enum="HAlign">
Horizontal left alignment, usually for text-derived classes.
</constant>
@@ -2147,7 +2151,25 @@
<constant name="JOY_BUTTON_DPAD_RIGHT" value="14" enum="JoyButtonList">
Game controller D-pad right button.
</constant>
- <constant name="JOY_BUTTON_SDL_MAX" value="15" enum="JoyButtonList">
+ <constant name="JOY_BUTTON_MISC1" value="15" enum="JoyButtonList">
+ Game controller SDL miscellaneous button. Corresponds to Xbox share button, PS5 microphone button, Nintendo capture button.
+ </constant>
+ <constant name="JOY_BUTTON_PADDLE1" value="16" enum="JoyButtonList">
+ Game controller SDL paddle 1 button.
+ </constant>
+ <constant name="JOY_BUTTON_PADDLE2" value="17" enum="JoyButtonList">
+ Game controller SDL paddle 2 button.
+ </constant>
+ <constant name="JOY_BUTTON_PADDLE3" value="18" enum="JoyButtonList">
+ Game controller SDL paddle 3 button.
+ </constant>
+ <constant name="JOY_BUTTON_PADDLE4" value="19" enum="JoyButtonList">
+ Game controller SDL paddle 4 button.
+ </constant>
+ <constant name="JOY_BUTTON_TOUCHPAD" value="20" enum="JoyButtonList">
+ Game controller SDL touchpad button.
+ </constant>
+ <constant name="JOY_BUTTON_SDL_MAX" value="21" enum="JoyButtonList">
The number of SDL game controller buttons.
</constant>
<constant name="JOY_BUTTON_MAX" value="36" enum="JoyButtonList">
@@ -2387,43 +2409,49 @@
<constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="9" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D physics layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="10" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_NAVIGATION" value="10" enum="PropertyHint">
+ Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
+ </constant>
+ <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="11" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="11" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="12" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D physics layers.
</constant>
- <constant name="PROPERTY_HINT_FILE" value="12" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_NAVIGATION" value="13" enum="PropertyHint">
+ Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
+ </constant>
+ <constant name="PROPERTY_HINT_FILE" value="14" enum="PropertyHint">
Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_DIR" value="13" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_DIR" value="15" enum="PropertyHint">
Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_FILE" value="14" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_FILE" value="16" enum="PropertyHint">
Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_DIR" value="15" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_DIR" value="17" enum="PropertyHint">
Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="16" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="18" enum="PropertyHint">
Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate.
</constant>
- <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="17" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="19" enum="PropertyHint">
Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed.
</constant>
- <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="18" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="20" enum="PropertyHint">
Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use.
</constant>
- <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="19" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="21" enum="PropertyHint">
Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="20" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="22" enum="PropertyHint">
Hints that an image is compressed using lossy compression.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="21" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="23" enum="PropertyHint">
Hints that an image is compressed using lossless compression.
</constant>
- <constant name="PROPERTY_HINT_TYPE_STRING" value="23" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_TYPE_STRING" value="25" enum="PropertyHint">
Hint that a property represents a particular type. If a property is [constant TYPE_STRING], allows to set a type from the create dialog. If you need to create an [Array] to contain elements of a specific type, the [code]hint_string[/code] must encode nested types using [code]":"[/code] and [code]"/"[/code] for specifying [Resource] types. For instance:
[codeblock]
hint_string = "%s:" % [TYPE_INT] # Array of inteters.
diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml
index baea84df65..8cd7e6f5fa 100644
--- a/doc/classes/AABB.xml
+++ b/doc/classes/AABB.xml
@@ -219,7 +219,7 @@
<argument index="0" name="aabb" type="AABB">
</argument>
<description>
- Returns [code]true[/code] if this [AABB] and [code]aabb[/code] are approximately equal, by calling [method @GDScript.is_equal_approx] on each component.
+ Returns [code]true[/code] if this [AABB] and [code]aabb[/code] are approximately equal, by calling [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
<method name="merge">
diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml
index 0cd7d3dc25..bfdc66623d 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -33,6 +33,7 @@
[/csharp]
[/codeblocks]
[method _estimate_cost] should return a lower bound of the distance, i.e. [code]_estimate_cost(u, v) &lt;= _compute_cost(u, v)[/code]. This serves as a hint to the algorithm because the custom [code]_compute_cost[/code] might be computation-heavy. If this is not the case, make [method _estimate_cost] return the same value as [method _compute_cost] to provide the algorithm with the most accurate information.
+ If the default [method _estimate_cost] and [method _compute_cost] methods are used, or if the supplied [method _estimate_cost] method returns a lower bound of the cost, then the paths returned by A* will be the lowest cost paths. Here, the cost of a path equals to the sum of the [method _compute_cost] results of all segments in the path multiplied by the [code]weight_scale[/code]s of the end points of the respective segments. If the default methods are used and the [code]weight_scale[/code]s of all points are set to [code]1.0[/code], then this equals to the sum of Euclidean distances of all segments in the path.
</description>
<tutorials>
</tutorials>
@@ -71,7 +72,8 @@
<argument index="2" name="weight_scale" type="float" default="1.0">
</argument>
<description>
- Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
+ Adds a new point at the given position with the given identifier. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
+ The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point. Thus, all else being equal, the algorithm prefers points with lower [code]weight_scale[/code]s to form a path.
[codeblocks]
[gdscript]
var astar = AStar.new()
@@ -380,7 +382,7 @@
<argument index="1" name="weight_scale" type="float">
</argument>
<description>
- Sets the [code]weight_scale[/code] for the point with the given [code]id[/code].
+ Sets the [code]weight_scale[/code] for the point with the given [code]id[/code]. The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point.
</description>
</method>
</methods>
diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml
index 1540d8dacc..2a51678209 100644
--- a/doc/classes/AStar2D.xml
+++ b/doc/classes/AStar2D.xml
@@ -43,7 +43,8 @@
<argument index="2" name="weight_scale" type="float" default="1.0">
</argument>
<description>
- Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
+ Adds a new point at the given position with the given identifier. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
+ The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point. Thus, all else being equal, the algorithm prefers points with lower [code]weight_scale[/code]s to form a path.
[codeblocks]
[gdscript]
var astar = AStar2D.new()
@@ -350,7 +351,7 @@
<argument index="1" name="weight_scale" type="float">
</argument>
<description>
- Sets the [code]weight_scale[/code] for the point with the given [code]id[/code].
+ Sets the [code]weight_scale[/code] for the point with the given [code]id[/code]. The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point.
</description>
</method>
</methods>
diff --git a/doc/classes/AnimatedSprite3D.xml b/doc/classes/AnimatedSprite3D.xml
index e1fb78e5b5..02ccab4e05 100644
--- a/doc/classes/AnimatedSprite3D.xml
+++ b/doc/classes/AnimatedSprite3D.xml
@@ -49,6 +49,11 @@
</member>
</members>
<signals>
+ <signal name="animation_finished">
+ <description>
+ Emitted when the animation is finished (when it plays the last frame). If the animation is looping, this signal is emitted every time the last frame is drawn.
+ </description>
+ </signal>
<signal name="frame_changed">
<description>
Emitted when [member frame] changed.
diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml
index 3e33a879b3..9720405ffd 100644
--- a/doc/classes/Animation.xml
+++ b/doc/classes/Animation.xml
@@ -168,7 +168,7 @@
<argument index="2" name="stream" type="Resource">
</argument>
<description>
- Sets the stream of the key identified by [code]key_idx[/code] to value [code]offset[/code]. The [code]track_idx[/code] must be the index of an Audio Track.
+ Sets the stream of the key identified by [code]key_idx[/code] to value [code]stream[/code]. The [code]track_idx[/code] must be the index of an Audio Track.
</description>
</method>
<method name="bezier_track_get_key_in_handle" qualifiers="const">
@@ -409,7 +409,7 @@
<argument index="1" name="key_idx" type="int">
</argument>
<description>
- Returns the transition curve (easing) for a specific key (see the built-in math function [method @GDScript.ease]).
+ Returns the transition curve (easing) for a specific key (see the built-in math function [method @GlobalScope.ease]).
</description>
</method>
<method name="track_get_key_value" qualifiers="const">
@@ -592,7 +592,7 @@
<argument index="2" name="transition" type="float">
</argument>
<description>
- Sets the transition curve (easing) for a specific key (see the built-in math function [method @GDScript.ease]).
+ Sets the transition curve (easing) for a specific key (see the built-in math function [method @GlobalScope.ease]).
</description>
</method>
<method name="track_set_key_value">
diff --git a/doc/classes/AnimationNodeStateMachinePlayback.xml b/doc/classes/AnimationNodeStateMachinePlayback.xml
index 60ff425cdb..c8468f9c8f 100644
--- a/doc/classes/AnimationNodeStateMachinePlayback.xml
+++ b/doc/classes/AnimationNodeStateMachinePlayback.xml
@@ -21,6 +21,12 @@
<link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
+ <method name="get_current_length" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_current_node" qualifiers="const">
<return type="StringName">
</return>
@@ -28,6 +34,13 @@
Returns the currently playing animation state.
</description>
</method>
+ <method name="get_current_play_position" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ Returns the playback position within the current animation state.
+ </description>
+ </method>
<method name="get_travel_path" qualifiers="const">
<return type="PackedStringArray">
</return>
diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml
index bebff61671..e5ba1d58f7 100644
--- a/doc/classes/AnimationPlayer.xml
+++ b/doc/classes/AnimationPlayer.xml
@@ -254,7 +254,7 @@
<member name="playback_default_blend_time" type="float" setter="set_default_blend_time" getter="get_default_blend_time" default="0.0">
The default time in which to blend animations. Ranges from 0 to 4096 with 0.01 precision.
</member>
- <member name="playback_process_mode" type="int" setter="set_animation_process_mode" getter="get_animation_process_mode" enum="AnimationPlayer.AnimationProcessMode" default="1">
+ <member name="playback_process_mode" type="int" setter="set_process_callback" getter="get_process_callback" enum="AnimationPlayer.AnimationProcessCallback" default="1">
The process notification in which to update animations.
</member>
<member name="playback_speed" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0">
@@ -299,13 +299,13 @@
</signal>
</signals>
<constants>
- <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessMode">
+ <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessCallback">
Process animation during the physics process. This is especially useful when animating physics bodies.
</constant>
- <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessMode">
+ <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessCallback">
Process animation during the idle process.
</constant>
- <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessMode">
+ <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessCallback">
Do not process animation. Use [method advance] to process the animation manually.
</constant>
<constant name="ANIMATION_METHOD_CALL_DEFERRED" value="0" enum="AnimationMethodCallMode">
diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml
index 262b5addb7..2517941133 100644
--- a/doc/classes/AnimationTree.xml
+++ b/doc/classes/AnimationTree.xml
@@ -45,8 +45,8 @@
<member name="anim_player" type="NodePath" setter="set_animation_player" getter="get_animation_player" default="NodePath(&quot;&quot;)">
The path to the [AnimationPlayer] used for animating.
</member>
- <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="AnimationTree.AnimationProcessMode" default="1">
- The process mode of this [AnimationTree]. See [enum AnimationProcessMode] for available modes.
+ <member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="AnimationTree.AnimationProcessCallback" default="1">
+ The process mode of this [AnimationTree]. See [enum AnimationProcessCallback] for available modes.
</member>
<member name="root_motion_track" type="NodePath" setter="set_root_motion_track" getter="get_root_motion_track" default="NodePath(&quot;&quot;)">
The path to the Animation track used for root motion. Paths must be valid scene-tree paths to a node, and must be specified starting from the parent node of the node that will reproduce the animation. To specify a track that controls properties or bones, append its name after the path, separated by [code]":"[/code]. For example, [code]"character/skeleton:ankle"[/code] or [code]"character/mesh:transform/local"[/code].
@@ -57,13 +57,13 @@
</member>
</members>
<constants>
- <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessMode">
+ <constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessCallback">
The animations will progress during the physics frame (i.e. [method Node._physics_process]).
</constant>
- <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessMode">
+ <constant name="ANIMATION_PROCESS_IDLE" value="1" enum="AnimationProcessCallback">
The animations will progress during the idle frame (i.e. [method Node._process]).
</constant>
- <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessMode">
+ <constant name="ANIMATION_PROCESS_MANUAL" value="2" enum="AnimationProcessCallback">
The animations will only progress manually (see [method advance]).
</constant>
</constants>
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index 72c40478bb..9711a2a35b 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -140,14 +140,16 @@
<argument index="0" name="area" type="Area2D">
</argument>
<description>
- Emitted when another area enters.
+ Emitted when another Area2D enters this Area2D. Requires [member monitoring] to be set to [code]true[/code].
+ [code]area[/code] the other Area2D.
</description>
</signal>
<signal name="area_exited">
<argument index="0" name="area" type="Area2D">
</argument>
<description>
- Emitted when another area exits.
+ Emitted when another Area2D exits this Area2D. Requires [member monitoring] to be set to [code]true[/code].
+ [code]area[/code] the other Area2D.
</description>
</signal>
<signal name="area_shape_entered">
@@ -157,10 +159,14 @@
</argument>
<argument index="2" name="area_shape" type="int">
</argument>
- <argument index="3" name="self_shape" type="int">
+ <argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when another area enters, reporting which shapes overlapped. [code]shape_owner_get_owner(shape_find_owner(shape))[/code] returns the parent object of the owner of the [code]shape[/code].
+ Emitted when one of another Area2D's [Shape2D]s enters one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code].
+ [code]area_id[/code] the [RID] of the other Area2D's [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]area[/code] the other Area2D.
+ [code]area_shape[/code] the index of the [Shape2D] of the other Area2D used by the [PhysicsServer2D].
+ [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D].
</description>
</signal>
<signal name="area_shape_exited">
@@ -170,54 +176,64 @@
</argument>
<argument index="2" name="area_shape" type="int">
</argument>
- <argument index="3" name="self_shape" type="int">
+ <argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when another area exits, reporting which shapes were overlapping.
+ Emitted when one of another Area2D's [Shape2D]s exits one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code].
+ [code]area_id[/code] the [RID] of the other Area2D's [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]area[/code] the other Area2D.
+ [code]area_shape[/code] the index of the [Shape2D] of the other Area2D used by the [PhysicsServer2D].
+ [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D].
</description>
</signal>
<signal name="body_entered">
- <argument index="0" name="body" type="Node">
+ <argument index="0" name="body" type="Node2D">
</argument>
<description>
- Emitted when a physics body enters.
- The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ Emitted when a [PhysicsBody2D] or [TileMap] enters this Area2D. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap].
</description>
</signal>
<signal name="body_exited">
- <argument index="0" name="body" type="Node">
+ <argument index="0" name="body" type="Node2D">
</argument>
<description>
- Emitted when a physics body exits.
- The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ Emitted when a [PhysicsBody2D] or [TileMap] exits this Area2D. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap].
</description>
</signal>
<signal name="body_shape_entered">
<argument index="0" name="body_id" type="int">
</argument>
- <argument index="1" name="body" type="Node">
+ <argument index="1" name="body" type="Node2D">
</argument>
<argument index="2" name="body_shape" type="int">
</argument>
- <argument index="3" name="area_shape" type="int">
+ <argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when a physics body enters, reporting which shapes overlapped.
- The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ Emitted when one of a [PhysicsBody2D] or [TileMap]'s [Shape2D]s enters one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
+ [code]body_id[/code] the [RID] of the [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody2D] or [TileMap].
+ [code]body_shape[/code] the index of the [Shape2D] of the [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D].
+ [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D].
</description>
</signal>
<signal name="body_shape_exited">
<argument index="0" name="body_id" type="int">
</argument>
- <argument index="1" name="body" type="Node">
+ <argument index="1" name="body" type="Node2D">
</argument>
<argument index="2" name="body_shape" type="int">
</argument>
- <argument index="3" name="area_shape" type="int">
+ <argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when a physics body exits, reporting which shapes were overlapping.
- The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ Emitted when one of a [PhysicsBody2D] or [TileMap]'s [Shape2D]s exits one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
+ [code]body_id[/code] the [RID] of the [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody2D] or [TileMap].
+ [code]body_shape[/code] the index of the [Shape2D] of the [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D].
+ [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D].
</description>
</signal>
</signals>
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index 2f8042bb1e..4271769155 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -150,14 +150,16 @@
<argument index="0" name="area" type="Area3D">
</argument>
<description>
- Emitted when another area enters.
+ Emitted when another Area3D enters this Area3D. Requires [member monitoring] to be set to [code]true[/code].
+ [code]area[/code] the other Area3D.
</description>
</signal>
<signal name="area_exited">
<argument index="0" name="area" type="Area3D">
</argument>
<description>
- Emitted when another area exits.
+ Emitted when another Area3D exits this Area3D. Requires [member monitoring] to be set to [code]true[/code].
+ [code]area[/code] the other Area3D.
</description>
</signal>
<signal name="area_shape_entered">
@@ -167,10 +169,14 @@
</argument>
<argument index="2" name="area_shape" type="int">
</argument>
- <argument index="3" name="self_shape" type="int">
+ <argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when another area enters, reporting which areas overlapped. [code]shape_owner_get_owner(shape_find_owner(shape))[/code] returns the parent object of the owner of the [code]shape[/code].
+ Emitted when one of another Area3D's [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code].
+ [code]area_id[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]area[/code] the other Area3D.
+ [code]area_shape[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D].
+ [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D].
</description>
</signal>
<signal name="area_shape_exited">
@@ -180,54 +186,64 @@
</argument>
<argument index="2" name="area_shape" type="int">
</argument>
- <argument index="3" name="self_shape" type="int">
+ <argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when another area exits, reporting which areas were overlapping.
+ Emitted when one of another Area3D's [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code].
+ [code]area_id[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]area[/code] the other Area3D.
+ [code]area_shape[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D].
+ [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D].
</description>
</signal>
<signal name="body_entered">
- <argument index="0" name="body" type="Node">
+ <argument index="0" name="body" type="Node3D">
</argument>
<description>
- Emitted when a physics body enters.
- The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ Emitted when a [PhysicsBody3D] or [GridMap] enters this Area3D. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap].
</description>
</signal>
<signal name="body_exited">
- <argument index="0" name="body" type="Node">
+ <argument index="0" name="body" type="Node3D">
</argument>
<description>
- Emitted when a physics body exits.
- The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ Emitted when a [PhysicsBody3D] or [GridMap] exits this Area3D. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap].
</description>
</signal>
<signal name="body_shape_entered">
<argument index="0" name="body_id" type="int">
</argument>
- <argument index="1" name="body" type="Node">
+ <argument index="1" name="body" type="Node3D">
</argument>
<argument index="2" name="body_shape" type="int">
</argument>
- <argument index="3" name="area_shape" type="int">
+ <argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when a physics body enters, reporting which shapes overlapped.
- The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ Emitted when one of a [PhysicsBody3D] or [GridMap]'s [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
+ [code]body_id[/code] the [RID] of the [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody3D] or [GridMap].
+ [code]body_shape[/code] the index of the [Shape3D] of the [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D].
+ [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D].
</description>
</signal>
<signal name="body_shape_exited">
<argument index="0" name="body_id" type="int">
</argument>
- <argument index="1" name="body" type="Node">
+ <argument index="1" name="body" type="Node3D">
</argument>
<argument index="2" name="body_shape" type="int">
</argument>
- <argument index="3" name="area_shape" type="int">
+ <argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when a physics body exits, reporting which shapes were overlapping.
- The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ Emitted when one of a [PhysicsBody3D] or [GridMap]'s [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
+ [code]body_id[/code] the [RID] of the [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody3D] or [GridMap].
+ [code]body_shape[/code] the index of the [Shape3D] of the [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D].
+ [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D].
</description>
</signal>
</signals>
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index 6a9eb89602..8fb688a8ae 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -191,15 +191,13 @@
</return>
<argument index="0" name="value" type="Variant">
</argument>
- <argument index="1" name="obj" type="Object">
+ <argument index="1" name="func" type="Callable">
</argument>
- <argument index="2" name="func" type="StringName">
- </argument>
- <argument index="3" name="before" type="bool" default="true">
+ <argument index="2" name="before" type="bool" default="true">
</argument>
<description>
Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search and a custom comparison method. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. The custom method receives two arguments (an element from the array and the value searched for) and must return [code]true[/code] if the first argument is less than the second, and return [code]false[/code] otherwise.
- [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior.
+ [b]Note:[/b] Calling [method bsearch_custom] on an unsorted array results in unexpected behavior.
</description>
</method>
<method name="clear">
@@ -228,20 +226,15 @@
If [code]deep[/code] is [code]true[/code], a deep copy is performed: all nested arrays and dictionaries are duplicated and will not be shared with the original array. If [code]false[/code], a shallow copy is made and references to the original nested arrays and dictionaries are kept, so that modifying a sub-array or dictionary in the copy will also impact those referenced in the source array.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="erase">
<return type="void">
</return>
<argument index="0" name="value" type="Variant">
</argument>
<description>
- Removes the first occurrence of a value from the array.
+ Removes the first occurrence of a value from the array. To remove an element by index, use [method remove] instead.
+ [b]Note:[/b] This method acts in-place and doesn't return a value.
+ [b]Note:[/b] On large arrays, this method will be slower if the removed element is close to the beginning of the array (index 0). This is because all elements placed after the removed element have to be reindexed.
</description>
</method>
<method name="find">
@@ -318,7 +311,8 @@
<return type="int">
</return>
<description>
- Returns a hashed integer value representing the array contents.
+ Returns a hashed integer value representing the array and its contents.
+ [b]Note:[/b] Arrays with equal contents can still produce different hashes. Only the exact same arrays will produce the same hashed integer value.
</description>
</method>
<method name="insert">
@@ -330,6 +324,8 @@
</argument>
<description>
Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]pos == size()[/code]).
+ [b]Note:[/b] This method acts in-place and doesn't return a value.
+ [b]Note:[/b] On large arrays, this method will be slower if the inserted element is close to the beginning of the array (index 0). This is because all elements placed after the newly inserted element have to be reindexed.
</description>
</method>
<method name="invert">
@@ -339,6 +335,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="max">
<return type="Variant">
</return>
@@ -421,14 +424,15 @@
<return type="Variant">
</return>
<description>
- Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty, without printing an error message.
+ Removes and returns the last element of the array. Returns [code]null[/code] if the array is empty, without printing an error message. See also [method pop_front].
</description>
</method>
<method name="pop_front">
<return type="Variant">
</return>
<description>
- Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty, without printing an error message.
+ Removes and returns the first element of the array. Returns [code]null[/code] if the array is empty, without printing an error message. See also [method pop_back].
+ [b]Note:[/b] On large arrays, this method is much slower than [method pop_back] as it will reindex all the array's elements every time it's called. The larger the array, the slower [method pop_front] will be.
</description>
</method>
<method name="push_back">
@@ -437,7 +441,7 @@
<argument index="0" name="value" type="Variant">
</argument>
<description>
- Appends an element at the end of the array.
+ Appends an element at the end of the array. See also [method push_front].
</description>
</method>
<method name="push_front">
@@ -446,7 +450,8 @@
<argument index="0" name="value" type="Variant">
</argument>
<description>
- Adds an element at the beginning of the array.
+ Adds an element at the beginning of the array. See also [method push_back].
+ [b]Note:[/b] On large arrays, this method is much slower than [method push_back] as it will reindex all the array's elements every time it's called. The larger the array, the slower [method push_front] will be.
</description>
</method>
<method name="remove">
@@ -455,7 +460,9 @@
<argument index="0" name="position" type="int">
</argument>
<description>
- Removes an element from the array by index. If the index does not exist in the array, nothing happens.
+ Removes an element from the array by index. If the index does not exist in the array, nothing happens. To remove an element by searching for its value, use [method erase] instead.
+ [b]Note:[/b] This method acts in-place and doesn't return a value.
+ [b]Note:[/b] On large arrays, this method will be slower if the removed element is close to the beginning of the array (index 0). This is because all elements placed after the removed element have to be reindexed.
</description>
</method>
<method name="resize">
@@ -482,7 +489,7 @@
<return type="void">
</return>
<description>
- Shuffles the array such that the items will have a random order. This method uses the global random number generator common to methods such as [method @GDScript.randi]. Call [method @GDScript.randomize] to ensure that a new seed will be used each time if you want non-reproducible shuffling.
+ Shuffles the array such that the items will have a random order. This method uses the global random number generator common to methods such as [method @GlobalScope.randi]. Call [method @GlobalScope.randomize] to ensure that a new seed will be used each time if you want non-reproducible shuffling.
</description>
</method>
<method name="size">
@@ -528,12 +535,10 @@
<method name="sort_custom">
<return type="void">
</return>
- <argument index="0" name="obj" type="Object">
- </argument>
- <argument index="1" name="func" type="StringName">
+ <argument index="0" name="func" type="Callable">
</argument>
<description>
- Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code].
+ Sorts the array using a custom method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code].
[b]Note:[/b] you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior.
[codeblocks]
[gdscript]
@@ -544,7 +549,7 @@
return false
var my_items = [[5, "Potato"], [9, "Rice"], [4, "Tomato"]]
- my_items.sort_custom(MyCustomSorter, "sort_ascending")
+ my_items.sort_custom(MyCustomSorter.sort_ascending)
print(my_items) # Prints [[4, Tomato], [5, Potato], [9, Rice]].
[/gdscript]
[csharp]
diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml
index ef33d7ea77..e2c4ed1430 100644
--- a/doc/classes/ArrayMesh.xml
+++ b/doc/classes/ArrayMesh.xml
@@ -121,7 +121,7 @@
Will perform a UV unwrap on the [ArrayMesh] to prepare the mesh for lightmapping.
</description>
</method>
- <method name="regen_normalmaps">
+ <method name="regen_normal_maps">
<return type="void">
</return>
<description>
@@ -209,19 +209,15 @@
</method>
</methods>
<members>
- <member name="blend_shape_mode" type="int" setter="set_blend_shape_mode" getter="get_blend_shape_mode" enum="ArrayMesh.BlendShapeMode" default="1">
- Sets the blend shape mode to one of [enum ArrayMesh.BlendShapeMode].
+ <member name="blend_shape_mode" type="int" setter="set_blend_shape_mode" getter="get_blend_shape_mode" enum="Mesh.BlendShapeMode" default="1">
+ Sets the blend shape mode to one of [enum Mesh.BlendShapeMode].
</member>
<member name="custom_aabb" type="AABB" setter="set_custom_aabb" getter="get_custom_aabb" default="AABB( 0, 0, 0, 0, 0, 0 )">
Overrides the [AABB] with one defined by user for use with frustum culling. Especially useful to avoid unexpected culling when using a shader to offset vertices.
</member>
+ <member name="shadow_mesh" type="ArrayMesh" setter="set_shadow_mesh" getter="get_shadow_mesh">
+ </member>
</members>
<constants>
- <constant name="BLEND_SHAPE_MODE_NORMALIZED" value="0" enum="BlendShapeMode">
- Blend shapes are normalized.
- </constant>
- <constant name="BLEND_SHAPE_MODE_RELATIVE" value="1" enum="BlendShapeMode">
- Blend shapes are relative to base weight.
- </constant>
</constants>
</class>
diff --git a/doc/classes/AudioEffectCapture.xml b/doc/classes/AudioEffectCapture.xml
new file mode 100644
index 0000000000..cf3d87c2e4
--- /dev/null
+++ b/doc/classes/AudioEffectCapture.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="AudioEffectCapture" inherits="AudioEffect" version="4.0">
+ <brief_description>
+ Captures audio from an audio bus in real-time.
+ </brief_description>
+ <description>
+ AudioEffectCapture is an AudioEffect which copies all audio frames from the attached audio effect bus into its internal ring buffer.
+ Application code should consume these audio frames from this ring buffer using [method get_buffer] and process it as needed, for example to capture data from a microphone, implement application defined effects, or to transmit audio over the network.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="can_get_buffer" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="frames" type="int">
+ </argument>
+ <description>
+ Returns [code]true[/code] if at least [code]frames[/code] audio frames are available to read in the internal ring buffer.
+ </description>
+ </method>
+ <method name="clear_buffer">
+ <return type="void">
+ </return>
+ <description>
+ Clears the internal ring buffer.
+ </description>
+ </method>
+ <method name="get_buffer">
+ <return type="PackedVector2Array">
+ </return>
+ <argument index="0" name="frames" type="int">
+ </argument>
+ <description>
+ Gets the next [code]frames[/code] audio samples from the internal ring buffer.
+ Returns a [PackedVector2Array] containing exactly [code]frames[/code] audio samples if available, or an empty [PackedVector2Array] if insufficient data was available.
+ </description>
+ </method>
+ <method name="get_buffer_length_frames" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the total size of the internal ring buffer in frames.
+ </description>
+ </method>
+ <method name="get_discarded_frames" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of audio frames discarded from the audio bus due to full buffer.
+ </description>
+ </method>
+ <method name="get_frames_available" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of frames available to read using [method get_buffer].
+ </description>
+ </method>
+ <method name="get_pushed_frames" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of audio frames inserted from the audio bus.
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="buffer_length" type="float" setter="set_buffer_length" getter="get_buffer_length" default="0.1">
+ Length of the internal ring buffer, in seconds.
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/BakedLightmapData.xml b/doc/classes/BakedLightmapData.xml
index 026477782a..904555c48e 100644
--- a/doc/classes/BakedLightmapData.xml
+++ b/doc/classes/BakedLightmapData.xml
@@ -12,11 +12,11 @@
</return>
<argument index="0" name="path" type="NodePath">
</argument>
- <argument index="1" name="lightmap" type="Rect2">
+ <argument index="1" name="uv_scale" type="Rect2">
</argument>
- <argument index="2" name="offset" type="int">
+ <argument index="2" name="slice_index" type="int">
</argument>
- <argument index="3" name="arg3" type="int">
+ <argument index="3" name="sub_instance" type="int">
</argument>
<description>
</description>
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index 31e6ea5e54..fa0c3b167a 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -93,7 +93,7 @@
<member name="alpha_scissor_threshold" type="float" setter="set_alpha_scissor_threshold" getter="get_alpha_scissor_threshold">
Threshold at which the alpha scissor will discard values.
</member>
- <member name="anisotropy" type="float" setter="set_anisotropy" getter="get_anisotropy">
+ <member name="anisotropy" type="float" setter="set_anisotropy" getter="get_anisotropy" default="0.0">
The strength of the anisotropy effect.
</member>
<member name="anisotropy_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
@@ -105,19 +105,19 @@
<member name="ao_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
If [code]true[/code], ambient occlusion is enabled. Ambient occlusion darkens areas based on the [member ao_texture].
</member>
- <member name="ao_light_affect" type="float" setter="set_ao_light_affect" getter="get_ao_light_affect">
+ <member name="ao_light_affect" type="float" setter="set_ao_light_affect" getter="get_ao_light_affect" default="0.0">
Amount that ambient occlusion affects lighting from lights. If [code]0[/code], ambient occlusion only affects ambient light. If [code]1[/code], ambient occlusion affects lights just as much as it affects ambient light. This can be used to impact the strength of the ambient occlusion effect, but typically looks unrealistic.
</member>
- <member name="ao_on_uv2" type="bool" setter="set_flag" getter="get_flag">
+ <member name="ao_on_uv2" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], use [code]UV2[/code] coordinates to look up from the [member ao_texture].
</member>
<member name="ao_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture that defines the amount of ambient occlusion for a given point on the object.
</member>
- <member name="ao_texture_channel" type="int" setter="set_ao_texture_channel" getter="get_ao_texture_channel" enum="BaseMaterial3D.TextureChannel">
+ <member name="ao_texture_channel" type="int" setter="set_ao_texture_channel" getter="get_ao_texture_channel" enum="BaseMaterial3D.TextureChannel" default="0">
Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
</member>
- <member name="backlight" type="Color" setter="set_backlight" getter="get_backlight">
+ <member name="backlight" type="Color" setter="set_backlight" getter="get_backlight" default="Color( 0, 0, 0, 1 )">
The color used by the backlight effect. Represents the light passing through an object.
</member>
<member name="backlight_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
@@ -137,13 +137,13 @@
The material's blend mode.
[b]Note:[/b] Values other than [code]Mix[/code] force the object into the transparent pipeline. See [enum BlendMode].
</member>
- <member name="clearcoat" type="float" setter="set_clearcoat" getter="get_clearcoat">
+ <member name="clearcoat" type="float" setter="set_clearcoat" getter="get_clearcoat" default="1.0">
Sets the strength of the clearcoat effect. Setting to [code]0[/code] looks the same as disabling the clearcoat effect.
</member>
<member name="clearcoat_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
If [code]true[/code], clearcoat rendering is enabled. Adds a secondary transparent pass to the lighting calculation resulting in an added specular blob. This makes materials appear as if they have a clear layer on them that can be either glossy or rough.
</member>
- <member name="clearcoat_gloss" type="float" setter="set_clearcoat_gloss" getter="get_clearcoat_gloss">
+ <member name="clearcoat_gloss" type="float" setter="set_clearcoat_gloss" getter="get_clearcoat_gloss" default="0.5">
Sets the roughness of the clearcoat pass. A higher value results in a smoother clearcoat while a lower value results in a rougher clearcoat.
</member>
<member name="clearcoat_texture" type="Texture2D" setter="set_texture" getter="get_texture">
@@ -158,7 +158,7 @@
<member name="detail_albedo" type="Texture2D" setter="set_texture" getter="get_texture">
Texture that specifies the color of the detail overlay.
</member>
- <member name="detail_blend_mode" type="int" setter="set_detail_blend_mode" getter="get_detail_blend_mode" enum="BaseMaterial3D.BlendMode">
+ <member name="detail_blend_mode" type="int" setter="set_detail_blend_mode" getter="get_detail_blend_mode" enum="BaseMaterial3D.BlendMode" default="0">
Specifies how the [member detail_albedo] should blend with the current [code]ALBEDO[/code]. See [enum BlendMode] for options.
</member>
<member name="detail_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
@@ -171,7 +171,7 @@
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.
</member>
- <member name="detail_uv_layer" type="int" setter="set_detail_uv" getter="get_detail_uv" enum="BaseMaterial3D.DetailUV">
+ <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.
</member>
<member name="diffuse_mode" type="int" setter="set_diffuse_mode" getter="get_diffuse_mode" enum="BaseMaterial3D.DiffuseMode" default="0">
@@ -183,30 +183,30 @@
<member name="disable_receive_shadows" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the object receives no shadow that would otherwise be cast onto it.
</member>
- <member name="distance_fade_max_distance" type="float" setter="set_distance_fade_max_distance" getter="get_distance_fade_max_distance">
+ <member name="distance_fade_max_distance" type="float" setter="set_distance_fade_max_distance" getter="get_distance_fade_max_distance" default="10.0">
Distance at which the object appears fully opaque.
[b]Note:[/b] If [code]distance_fade_max_distance[/code] is less than [code]distance_fade_min_distance[/code], the behavior will be reversed. The object will start to fade away at [code]distance_fade_max_distance[/code] and will fully disappear once it reaches [code]distance_fade_min_distance[/code].
</member>
- <member name="distance_fade_min_distance" type="float" setter="set_distance_fade_min_distance" getter="get_distance_fade_min_distance">
+ <member name="distance_fade_min_distance" type="float" setter="set_distance_fade_min_distance" getter="get_distance_fade_min_distance" default="0.0">
Distance at which the object starts to become visible. If the object is less than this distance away, it will be invisible.
[b]Note:[/b] If [code]distance_fade_min_distance[/code] is greater than [code]distance_fade_max_distance[/code], the behavior will be reversed. The object will start to fade away at [code]distance_fade_max_distance[/code] and will fully disappear once it reaches [code]distance_fade_min_distance[/code].
</member>
<member name="distance_fade_mode" type="int" setter="set_distance_fade" getter="get_distance_fade" enum="BaseMaterial3D.DistanceFadeMode" default="0">
Specifies which type of fade to use. Can be any of the [enum DistanceFadeMode]s.
</member>
- <member name="emission" type="Color" setter="set_emission" getter="get_emission">
+ <member name="emission" type="Color" setter="set_emission" getter="get_emission" default="Color( 0, 0, 0, 1 )">
The emitted light's color. See [member emission_enabled].
</member>
<member name="emission_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
If [code]true[/code], the body emits light. Emitting light makes the object appear brighter. The object can also cast light on other objects if a [GIProbe] is used and this object is used in baked lighting.
</member>
- <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy">
+ <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy" default="1.0">
The emitted light's strength. See [member emission_enabled].
</member>
- <member name="emission_on_uv2" type="bool" setter="set_flag" getter="get_flag">
+ <member name="emission_on_uv2" type="bool" setter="set_flag" getter="get_flag" default="false">
Use [code]UV2[/code] to read from the [member emission_texture].
</member>
- <member name="emission_operator" type="int" setter="set_emission_operator" getter="get_emission_operator" enum="BaseMaterial3D.EmissionOperator">
+ <member name="emission_operator" type="int" setter="set_emission_operator" getter="get_emission_operator" enum="BaseMaterial3D.EmissionOperator" default="0">
Sets how [member emission] interacts with [member emission_texture]. Can either add or multiply. See [enum EmissionOperator] for options.
</member>
<member name="emission_texture" type="Texture2D" setter="set_texture" getter="get_texture">
@@ -221,21 +221,23 @@
<member name="grow_amount" type="float" setter="set_grow" getter="get_grow" default="0.0">
Grows object vertices in the direction of their normals.
</member>
- <member name="heightmap_deep_parallax" type="bool" setter="set_heightmap_deep_parallax" getter="is_heightmap_deep_parallax_enabled">
+ <member name="heightmap_deep_parallax" type="bool" setter="set_heightmap_deep_parallax" getter="is_heightmap_deep_parallax_enabled" default="false">
</member>
<member name="heightmap_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
+ If [code]true[/code], height mapping is enabled (also called "parallax mapping" or "depth mapping"). See also [member normal_enabled].
+ [b]Note:[/b] Height mapping is not supported if triplanar mapping is used on the same material. The value of [member heightmap_enabled] will be ignored if [member uv1_triplanar] is enabled.
</member>
- <member name="heightmap_flip_binormal" type="bool" setter="set_heightmap_deep_parallax_flip_binormal" getter="get_heightmap_deep_parallax_flip_binormal">
+ <member name="heightmap_flip_binormal" type="bool" setter="set_heightmap_deep_parallax_flip_binormal" getter="get_heightmap_deep_parallax_flip_binormal" default="false">
</member>
- <member name="heightmap_flip_tangent" type="bool" setter="set_heightmap_deep_parallax_flip_tangent" getter="get_heightmap_deep_parallax_flip_tangent">
+ <member name="heightmap_flip_tangent" type="bool" setter="set_heightmap_deep_parallax_flip_tangent" getter="get_heightmap_deep_parallax_flip_tangent" default="false">
</member>
- <member name="heightmap_flip_texture" type="bool" setter="set_flag" getter="get_flag">
+ <member name="heightmap_flip_texture" type="bool" setter="set_flag" getter="get_flag" default="false">
</member>
<member name="heightmap_max_layers" type="int" setter="set_heightmap_deep_parallax_max_layers" getter="get_heightmap_deep_parallax_max_layers">
</member>
<member name="heightmap_min_layers" type="int" setter="set_heightmap_deep_parallax_min_layers" getter="get_heightmap_deep_parallax_min_layers">
</member>
- <member name="heightmap_scale" type="float" setter="set_heightmap_scale" getter="get_heightmap_scale">
+ <member name="heightmap_scale" type="float" setter="set_heightmap_scale" getter="get_heightmap_scale" default="0.05">
</member>
<member name="heightmap_texture" type="Texture2D" setter="set_texture" getter="get_texture">
</member>
@@ -258,7 +260,7 @@
<member name="normal_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
If [code]true[/code], normal mapping is enabled.
</member>
- <member name="normal_scale" type="float" setter="set_normal_scale" getter="get_normal_scale">
+ <member name="normal_scale" type="float" setter="set_normal_scale" getter="get_normal_scale" default="1.0">
The strength of the normal map's effect.
</member>
<member name="normal_texture" type="Texture2D" setter="set_texture" getter="get_texture">
@@ -279,7 +281,7 @@
<member name="point_size" type="float" setter="set_point_size" getter="get_point_size" default="1.0">
The point size in pixels. See [member use_point_size].
</member>
- <member name="proximity_fade_distance" type="float" setter="set_proximity_fade_distance" getter="get_proximity_fade_distance">
+ <member name="proximity_fade_distance" type="float" setter="set_proximity_fade_distance" getter="get_proximity_fade_distance" default="1.0">
Distance over which the fade effect takes place. The larger the distance the longer it takes for an object to fade.
</member>
<member name="proximity_fade_enable" type="bool" setter="set_proximity_fade" getter="is_proximity_fade_enabled" default="false">
@@ -288,16 +290,16 @@
<member name="refraction_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
If [code]true[/code], the refraction effect is enabled. Distorts transparency based on light from behind the object.
</member>
- <member name="refraction_scale" type="float" setter="set_refraction" getter="get_refraction">
+ <member name="refraction_scale" type="float" setter="set_refraction" getter="get_refraction" default="0.05">
The strength of the refraction effect.
</member>
<member name="refraction_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture that controls the strength of the refraction per-pixel. Multiplied by [member refraction_scale].
</member>
- <member name="refraction_texture_channel" type="int" setter="set_refraction_texture_channel" getter="get_refraction_texture_channel" enum="BaseMaterial3D.TextureChannel">
+ <member name="refraction_texture_channel" type="int" setter="set_refraction_texture_channel" getter="get_refraction_texture_channel" enum="BaseMaterial3D.TextureChannel" default="0">
Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
</member>
- <member name="rim" type="float" setter="set_rim" getter="get_rim">
+ <member name="rim" type="float" setter="set_rim" getter="get_rim" default="1.0">
Sets the strength of the rim lighting effect.
</member>
<member name="rim_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
@@ -306,7 +308,7 @@
<member name="rim_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to set the strength of the rim lighting effect per-pixel. Multiplied by [member rim].
</member>
- <member name="rim_tint" type="float" setter="set_rim_tint" getter="get_rim_tint">
+ <member name="rim_tint" type="float" setter="set_rim_tint" getter="get_rim_tint" default="0.5">
The amount of to blend light and albedo color when rendering rim effect. If [code]0[/code] the light color is used, while [code]1[/code] means albedo color is used. An intermediate value generally works best.
</member>
<member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0">
@@ -330,24 +332,24 @@
<member name="subsurf_scatter_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
If [code]true[/code], subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges.
</member>
- <member name="subsurf_scatter_skin_mode" type="bool" setter="set_flag" getter="get_flag">
+ <member name="subsurf_scatter_skin_mode" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], subsurface scattering will use a special mode optimized for the color and density of human skin.
</member>
- <member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength">
+ <member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength" default="0.0">
The strength of the subsurface scattering effect.
</member>
<member name="subsurf_scatter_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to control the subsurface scattering strength. Stored in the red texture channel. Multiplied by [member subsurf_scatter_strength].
</member>
- <member name="subsurf_scatter_transmittance_boost" type="float" setter="set_transmittance_boost" getter="get_transmittance_boost">
+ <member name="subsurf_scatter_transmittance_boost" type="float" setter="set_transmittance_boost" getter="get_transmittance_boost" default="0.0">
</member>
- <member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color">
+ <member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color" default="Color( 1, 1, 1, 1 )">
</member>
- <member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve">
+ <member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve" default="1.0">
</member>
- <member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth">
+ <member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth" default="0.1">
</member>
- <member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature">
+ <member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
</member>
<member name="subsurf_scatter_transmittance_texture" type="Texture2D" setter="set_texture" getter="get_texture">
</member>
diff --git a/doc/classes/BoxMesh.xml b/doc/classes/BoxMesh.xml
index 8a1b9e939e..1404477b46 100644
--- a/doc/classes/BoxMesh.xml
+++ b/doc/classes/BoxMesh.xml
@@ -14,7 +14,7 @@
</methods>
<members>
<member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3( 2, 2, 2 )">
- Size of the box mesh.
+ The box's width, height and depth.
</member>
<member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" default="0">
Number of extra edge loops inserted along the Z axis.
diff --git a/doc/classes/BoxShape3D.xml b/doc/classes/BoxShape3D.xml
index d8cbd8b980..f5051413ce 100644
--- a/doc/classes/BoxShape3D.xml
+++ b/doc/classes/BoxShape3D.xml
@@ -14,8 +14,8 @@
<methods>
</methods>
<members>
- <member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3( 1, 1, 1 )">
- The box's half extents. The width, height and depth of this shape is twice the half extents.
+ <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3( 2, 2, 2 )">
+ The box's width, height and depth.
</member>
</members>
<constants>
diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml
index e47198a381..51c35b15ce 100644
--- a/doc/classes/Button.xml
+++ b/doc/classes/Button.xml
@@ -34,6 +34,7 @@
[/codeblocks]
Buttons (like all Control nodes) can also be created in the editor, but some situations may require creating them from code.
See also [BaseButton] which contains common properties and methods associated with this node.
+ [b]Note:[/b] Buttons do not interpret touch input and therefore don't support multitouch, since mouse emulation can only press one button at a given time. Use [TouchScreenButton] for buttons that trigger gameplay movement or actions, as [TouchScreenButton] supports multitouch.
</description>
<tutorials>
<link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/515</link>
@@ -118,17 +119,20 @@
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
Default text [Color] of the [Button].
</theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
Text [Color] used when the [Button] is disabled.
</theme_item>
- <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
Text [Color] used when the [Button] is being hovered.
</theme_item>
- <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
- Text [Color] used when the [Button] is being pressed.
+ <theme_item name="font_hover_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ Text [Color] used when the [Button] is being hovered and pressed.
+ </theme_item>
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [Button].
</theme_item>
- <theme_item name="font_outline_modulate" type="Color" default="Color( 1, 1, 1, 1 )">
- Text oubline [Color] of the [Button].
+ <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ Text [Color] used when the [Button] is being pressed.
</theme_item>
<theme_item name="font_size" type="int">
Font size of the [Button]'s text.
@@ -139,11 +143,26 @@
<theme_item name="hseparation" type="int" default="2">
The horizontal space between [Button]'s icon and text.
</theme_item>
+ <theme_item name="icon_disabled_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ Icon modulate [Color] used when the [Button] is disabled.
+ </theme_item>
+ <theme_item name="icon_hover_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ Icon modulate [Color] used when the [Button] is being hovered.
+ </theme_item>
+ <theme_item name="icon_hover_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ Icon modulate [Color] used when the [Button] is being hovered and pressed.
+ </theme_item>
+ <theme_item name="icon_normal_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ Default icon modulate [Color] of the [Button].
+ </theme_item>
+ <theme_item name="icon_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ Icon modulate [Color] used when the [Button] is being pressed.
+ </theme_item>
<theme_item name="normal" type="StyleBox">
Default [StyleBox] for the [Button].
</theme_item>
<theme_item name="outline_size" type="int" default="0">
- Size of the [Button]'s text outline.
+ The size of the text outline.
</theme_item>
<theme_item name="pressed" type="StyleBox">
[StyleBox] used when the [Button] is being pressed.
diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml
index f137ede90f..b69768d33f 100644
--- a/doc/classes/Callable.xml
+++ b/doc/classes/Callable.xml
@@ -8,26 +8,26 @@
[b]Example:[/b]
[codeblocks]
[gdscript]
- var callable = Callable(self, "print_args")
func print_args(arg1, arg2, arg3 = ""):
prints(arg1, arg2, arg3)
func test():
- callable.call("hello", "world") # Prints "hello world".
+ var callable = Callable(self, "print_args")
+ callable.call("hello", "world") # Prints "hello world ".
callable.call(Vector2.UP, 42, callable) # Prints "(0, -1) 42 Node(Node.gd)::print_args".
callable.call("invalid") # Invalid call, should have at least 2 arguments.
[/gdscript]
[csharp]
- Callable callable = new Callable(this, "print_args");
- public void PrintArgs(object arg1, object arg2, object arg3 = "")
+ public void PrintArgs(object arg1, object arg2, object arg3 = null)
{
GD.PrintS(arg1, arg2, arg3);
}
public void Test()
{
- callable.Call("hello", "world"); // Prints "hello world".
- callable.Call(Vector2.Up, 42, callable); // Prints "(0, -1) 42 Node(Node.gd)::print_args".
+ Callable callable = new Callable(this, nameof(PrintArgs));
+ callable.Call("hello", "world"); // Prints "hello world null".
+ callable.Call(Vector2.Up, 42, callable); // Prints "(0, -1) 42 Node(Node.cs)::PrintArgs".
callable.Call("invalid"); // Invalid call, should have at least 2 arguments.
}
[/csharp]
@@ -67,6 +67,7 @@
<return type="Callable">
</return>
<description>
+ Returns a copy of this [Callable] with the arguments bound. Bound arguments are passed after the arguments supplied by [method call].
</description>
</method>
<method name="call" qualifiers="vararg">
@@ -108,24 +109,28 @@
<return type="int">
</return>
<description>
+ Returns the hash value of this [Callable]'s object.
</description>
</method>
<method name="is_custom">
<return type="bool">
</return>
<description>
+ Returns [code]true[/code] if this [Callable] is a custom callable whose behavior differs based on implementation details. Custom callables are used in the engine for various reasons. If [code]true[/code], you can't use [method get_method].
</description>
</method>
<method name="is_null">
<return type="bool">
</return>
<description>
+ Returns [code]true[/code] if this [Callable] has no target to call the method on.
</description>
</method>
<method name="is_standard">
<return type="bool">
</return>
<description>
+ Returns [code]true[/code] if this [Callable] is a standard callable, referencing an object and a method using a [StringName].
</description>
</method>
<method name="operator !=" qualifiers="operator">
@@ -134,6 +139,7 @@
<argument index="0" name="right" type="Callable">
</argument>
<description>
+ Returns [code]true[/code] if both [Callable]s invoke different targets.
</description>
</method>
<method name="operator ==" qualifiers="operator">
@@ -142,6 +148,7 @@
<argument index="0" name="right" type="Callable">
</argument>
<description>
+ Returns [code]true[/code] if both [Callable]s invoke the same custom target.
</description>
</method>
<method name="unbind">
@@ -150,6 +157,7 @@
<argument index="0" name="argcount" type="int">
</argument>
<description>
+ Returns a copy of this [Callable] with the arguments unbound. Calling the returned [Callable] will call the method without the extra arguments that are supplied in the [Callable] on which you are calling this method.
</description>
</method>
</methods>
diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml
index 957195d73b..d40567bdcb 100644
--- a/doc/classes/Camera2D.xml
+++ b/doc/classes/Camera2D.xml
@@ -52,16 +52,16 @@
<method name="get_drag_margin" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
- Returns the drag margin for the specified [enum Side]. See also [member drag_margin_bottom], [member drag_margin_top], [member drag_margin_left], and [member drag_margin_right].
+ Returns the specified [enum Side]'s margin. See also [member drag_bottom_margin], [member drag_top_margin], [member drag_left_margin], and [member drag_right_margin].
</description>
</method>
<method name="get_limit" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
Returns the camera limit for the specified [enum Side]. See also [member limit_bottom], [member limit_top], [member limit_left], and [member limit_right].
@@ -85,18 +85,18 @@
<method name="set_drag_margin">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="drag_margin" type="float">
</argument>
<description>
- Sets the drag margin for the specified [enum Side]. See also [member drag_margin_bottom], [member drag_margin_top], [member drag_margin_left], and [member drag_margin_right].
+ Sets the specified [enum Side]'s margin. See also [member drag_bottom_margin], [member drag_top_margin], [member drag_left_margin], and [member drag_right_margin].
</description>
</method>
<method name="set_limit">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="limit" type="int">
</argument>
@@ -115,23 +115,31 @@
<member name="custom_viewport" type="Node" setter="set_custom_viewport" getter="get_custom_viewport">
The custom [Viewport] node attached to the [Camera2D]. If [code]null[/code] or not a [Viewport], uses the default viewport instead.
</member>
- <member name="drag_margin_bottom" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
- Bottom margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
+ <member name="drag_bottom_margin" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
+ Bottom margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the bottom edge of the screen.
</member>
- <member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled" default="false">
- If [code]true[/code], the camera only moves when reaching the horizontal drag margins. If [code]false[/code], the camera moves horizontally regardless of margins.
+ <member name="drag_horizontal_enabled" type="bool" setter="set_drag_horizontal_enabled" getter="is_drag_horizontal_enabled" default="false">
+ If [code]true[/code], the camera only moves when reaching the horizontal (left and right) drag margins. If [code]false[/code], the camera moves horizontally regardless of margins.
</member>
- <member name="drag_margin_left" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
- Left margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
+ <member name="drag_horizontal_offset" type="float" setter="set_drag_horizontal_offset" getter="get_drag_horizontal_offset" default="0.0">
+ The relative horizontal drag offset of the camera between the right ([code]-1[/code]) and left ([code]1[/code]) drag margins.
+ [b]Note:[/b] Used to set the initial horizontal drag offset; determine the current offset; or force the current offset. It's not automatically updated when the horizontal drag margin is enabled or the drag margins are changed.
</member>
- <member name="drag_margin_right" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
- Right margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
+ <member name="drag_left_margin" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
+ Left margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the left edge of the screen.
</member>
- <member name="drag_margin_top" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
- Top margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
+ <member name="drag_right_margin" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
+ Right margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the right edge of the screen.
</member>
- <member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" default="false">
- If [code]true[/code], the camera only moves when reaching the vertical drag margins. If [code]false[/code], the camera moves vertically regardless of margins.
+ <member name="drag_top_margin" type="float" setter="set_drag_margin" getter="get_drag_margin" default="0.2">
+ Top margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the top edge of the screen.
+ </member>
+ <member name="drag_vertical_enabled" type="bool" setter="set_drag_vertical_enabled" getter="is_drag_vertical_enabled" default="false">
+ If [code]true[/code], the camera only moves when reaching the vertical (top and bottom) drag margins. If [code]false[/code], the camera moves vertically regardless of the drag margins.
+ </member>
+ <member name="drag_vertical_offset" type="float" setter="set_drag_vertical_offset" getter="get_drag_vertical_offset" default="0.0">
+ The relative vertical drag offset of the camera between the bottom ([code]-1[/code]) and top ([code]1[/code]) drag margins.
+ [b]Note:[/b] Used to set the initial vertical drag offset; determine the current offset; or force the current offset. It's not automatically updated when the vertical drag margin is enabled or the drag margins are changed.
</member>
<member name="editor_draw_drag_margin" type="bool" setter="set_margin_drawing_enabled" getter="is_margin_drawing_enabled" default="false">
If [code]true[/code], draws the camera's drag margin rectangle in the editor.
@@ -160,16 +168,8 @@
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )">
The camera's offset, useful for looking around or camera shake animations.
</member>
- <member name="offset_h" type="float" setter="set_h_offset" getter="get_h_offset" default="0.0">
- The horizontal offset of the camera, relative to the drag margins.
- [b]Note:[/b] Offset H is used only to force offset relative to margins. It's not updated in any way if drag margins are enabled and can be used to set initial offset.
- </member>
- <member name="offset_v" type="float" setter="set_v_offset" getter="get_v_offset" default="0.0">
- The vertical offset of the camera, relative to the drag margins.
- [b]Note:[/b] Used the same as [member offset_h].
- </member>
- <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="Camera2D.Camera2DProcessMode" default="1">
- The camera's process callback. See [enum Camera2DProcessMode].
+ <member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="Camera2D.Camera2DProcessCallback" default="1">
+ The camera's process callback. See [enum Camera2DProcessCallback].
</member>
<member name="rotating" type="bool" setter="set_rotating" getter="is_rotating" default="false">
If [code]true[/code], the camera rotates with the target.
@@ -191,10 +191,10 @@
<constant name="ANCHOR_MODE_DRAG_CENTER" value="1" enum="AnchorMode">
The camera's position takes into account vertical/horizontal offsets and the screen size.
</constant>
- <constant name="CAMERA2D_PROCESS_PHYSICS" value="0" enum="Camera2DProcessMode">
+ <constant name="CAMERA2D_PROCESS_PHYSICS" value="0" enum="Camera2DProcessCallback">
The camera updates with the [code]_physics_process[/code] callback.
</constant>
- <constant name="CAMERA2D_PROCESS_IDLE" value="1" enum="Camera2DProcessMode">
+ <constant name="CAMERA2D_PROCESS_IDLE" value="1" enum="Camera2DProcessCallback">
The camera updates with the [code]_process[/code] callback.
</constant>
</constants>
diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml
index 052b23a7ab..034b2e9629 100644
--- a/doc/classes/Camera3D.xml
+++ b/doc/classes/Camera3D.xml
@@ -189,7 +189,7 @@
<member name="environment" type="Environment" setter="set_environment" getter="get_environment">
The [Environment] to use for this camera.
</member>
- <member name="far" type="float" setter="set_zfar" getter="get_zfar" default="4000.0">
+ <member name="far" type="float" setter="set_far" getter="get_far" default="4000.0">
The distance to the far culling boundary for this camera relative to its local Z axis.
</member>
<member name="fov" type="float" setter="set_fov" getter="get_fov" default="75.0">
@@ -209,7 +209,7 @@
<member name="keep_aspect" type="int" setter="set_keep_aspect_mode" getter="get_keep_aspect_mode" enum="Camera3D.KeepAspect" default="1">
The axis to lock during [member fov]/[member size] adjustments. Can be either [constant KEEP_WIDTH] or [constant KEEP_HEIGHT].
</member>
- <member name="near" type="float" setter="set_znear" getter="get_znear" default="0.05">
+ <member name="near" type="float" setter="set_near" getter="get_near" default="0.05">
The distance to the near culling boundary for this camera relative to its local Z axis.
</member>
<member name="projection" type="int" setter="set_projection" getter="get_projection" enum="Camera3D.Projection" default="0">
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index fcdd072c80..d13f431a16 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -9,7 +9,7 @@
Canvas items are drawn in tree order. By default, children are on top of their parents so a root [CanvasItem] will be drawn behind everything. This behavior can be changed on a per-item basis.
A [CanvasItem] can also be hidden, which will also hide its children. It provides many ways to change parameters such as modulation (for itself and its children) and self modulation (only for itself), as well as its blend mode.
Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed.
- [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad].
+ [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GlobalScope.deg2rad].
</description>
<tutorials>
<link title="Viewport and canvas transforms">https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link>
diff --git a/doc/classes/CharFXTransform.xml b/doc/classes/CharFXTransform.xml
index b4cb110337..850098f741 100644
--- a/doc/classes/CharFXTransform.xml
+++ b/doc/classes/CharFXTransform.xml
@@ -17,7 +17,7 @@
The color the character will be drawn with.
</member>
<member name="elapsed_time" type="float" setter="set_elapsed_time" getter="get_elapsed_time" default="0.0">
- The time elapsed since the [RichTextLabel] was added to the scene tree (in seconds). Time stops when the project is paused, unless the [RichTextLabel]'s [member Node.pause_mode] is set to [constant Node.PAUSE_MODE_PROCESS].
+ The time elapsed since the [RichTextLabel] was added to the scene tree (in seconds). Time stops when the project is paused depending on the value of the [RichTextLabel]'s [member Node.process_mode].
[b]Note:[/b] Time still passes while the [RichTextLabel] is hidden.
</member>
<member name="env" type="Dictionary" setter="set_environment" getter="get_environment" default="{}">
diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml
index 89fb960e88..80febfbfe7 100644
--- a/doc/classes/CheckBox.xml
+++ b/doc/classes/CheckBox.xml
@@ -36,16 +36,19 @@
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
The [CheckBox] text's font color.
</theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
The [CheckBox] text's font color when it's disabled.
</theme_item>
- <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
The [CheckBox] text's font color when it's hovered.
</theme_item>
- <theme_item name="font_color_hover_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_hover_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
The [CheckBox] text's font color when it's hovered and pressed.
</theme_item>
- <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [CheckBox].
+ </theme_item>
+ <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
The [CheckBox] text's font color when it's pressed.
</theme_item>
<theme_item name="font_size" type="int">
@@ -63,6 +66,9 @@
<theme_item name="normal" type="StyleBox">
The [StyleBox] to display as a background.
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="pressed" type="StyleBox">
The [StyleBox] to display as a background when the [CheckBox] is pressed.
</theme_item>
diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml
index 882f1c69f3..46e590a115 100644
--- a/doc/classes/CheckButton.xml
+++ b/doc/classes/CheckButton.xml
@@ -33,16 +33,19 @@
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
The [CheckButton] text's font color.
</theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
The [CheckButton] text's font color when it's disabled.
</theme_item>
- <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
The [CheckButton] text's font color when it's hovered.
</theme_item>
- <theme_item name="font_color_hover_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_hover_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
The [CheckButton] text's font color when it's hovered and pressed.
</theme_item>
- <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [CheckButton].
+ </theme_item>
+ <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
The [CheckButton] text's font color when it's pressed.
</theme_item>
<theme_item name="font_size" type="int">
@@ -84,6 +87,9 @@
<theme_item name="on_mirrored" type="Texture2D">
The icon to display when the [CheckButton] is checked (for right-to-left layouts).
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="pressed" type="StyleBox">
The [StyleBox] to display as a background when the [CheckButton] is pressed.
</theme_item>
diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml
index 2a6a2ddd91..860bdc7c8f 100644
--- a/doc/classes/ClassDB.xml
+++ b/doc/classes/ClassDB.xml
@@ -67,6 +67,7 @@
</argument>
<description>
Returns an array with all the methods of [code]class[/code] or its ancestry if [code]no_inheritance[/code] is [code]false[/code]. Every element of the array is a [Dictionary] with the following keys: [code]args[/code], [code]default_args[/code], [code]flags[/code], [code]id[/code], [code]name[/code], [code]return: (class_name, hint, hint_string, name, type, usage)[/code].
+ [b]Note:[/code] In exported release builds the debug info is not available, so the returned dictionaries will contain only method names.
</description>
</method>
<method name="class_get_property" qualifiers="const">
diff --git a/doc/classes/ClippedCamera3D.xml b/doc/classes/ClippedCamera3D.xml
index de90247536..9116af19c3 100644
--- a/doc/classes/ClippedCamera3D.xml
+++ b/doc/classes/ClippedCamera3D.xml
@@ -95,15 +95,15 @@
<member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0">
The camera's collision margin. The camera can't get closer than this distance to a colliding object.
</member>
- <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="ClippedCamera3D.ProcessMode" default="0">
- The camera's process callback. See [enum ProcessMode].
+ <member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="ClippedCamera3D.ClipProcessCallback" default="0">
+ The camera's process callback. See [enum ClipProcessCallback].
</member>
</members>
<constants>
- <constant name="CLIP_PROCESS_PHYSICS" value="0" enum="ProcessMode">
+ <constant name="CLIP_PROCESS_PHYSICS" value="0" enum="ClipProcessCallback">
The camera updates with the [code]_physics_process[/code] callback.
</constant>
- <constant name="CLIP_PROCESS_IDLE" value="1" enum="ProcessMode">
+ <constant name="CLIP_PROCESS_IDLE" value="1" enum="ClipProcessCallback">
The camera updates with the [code]_process[/code] callback.
</constant>
</constants>
diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml
index 8834ff82c6..d1483ac88e 100644
--- a/doc/classes/CodeEdit.xml
+++ b/doc/classes/CodeEdit.xml
@@ -179,9 +179,12 @@
</theme_item>
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
</theme_item>
- <theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [CodeEdit].
</theme_item>
- <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )">
+ <theme_item name="font_readonly_color" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
+ </theme_item>
+ <theme_item name="font_selected_color" type="Color" default="Color( 0, 0, 0, 1 )">
</theme_item>
<theme_item name="font_size" type="int">
Font size of the [CodeEdit]'s text.
@@ -194,6 +197,9 @@
</theme_item>
<theme_item name="normal" type="StyleBox">
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="read_only" type="StyleBox">
</theme_item>
<theme_item name="safe_line_number_color" type="Color" default="Color( 0.67, 0.78, 0.67, 0.6 )">
diff --git a/doc/classes/CodeHighlighter.xml b/doc/classes/CodeHighlighter.xml
index 7a1dad547b..f078e4e5b0 100644
--- a/doc/classes/CodeHighlighter.xml
+++ b/doc/classes/CodeHighlighter.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CodeHighlighter" inherits="SyntaxHighlighter" version="4.0">
<brief_description>
+ A syntax highlighter for code.
</brief_description>
<description>
+ A syntax highlighter for code.
</description>
<tutorials>
</tutorials>
@@ -10,15 +12,18 @@
<method name="add_color_region">
<return type="void">
</return>
- <argument index="0" name="p_start_key" type="String">
+ <argument index="0" name="start_key" type="String">
</argument>
- <argument index="1" name="p_end_key" type="String">
+ <argument index="1" name="end_key" type="String">
</argument>
- <argument index="2" name="p_color" type="Color">
+ <argument index="2" name="color" type="Color">
</argument>
- <argument index="3" name="p_line_only" type="bool" default="false">
+ <argument index="3" name="line_only" type="bool" default="false">
</argument>
<description>
+ Adds a color region such as comments or strings.
+ Both the start and end keys must be symbols. Only the start key has to be unique.
+ Line only denotes if the region should continue until the end of the line or carry over on to the next line. If the end key is blank this is automatically set to [code]true[/code].
</description>
</method>
<method name="add_keyword_color">
@@ -29,6 +34,8 @@
<argument index="1" name="color" type="Color">
</argument>
<description>
+ Sets the color for a keyword.
+ The keyword cannot contain any symbols except '_'.
</description>
</method>
<method name="add_member_keyword_color">
@@ -39,24 +46,30 @@
<argument index="1" name="color" type="Color">
</argument>
<description>
+ Sets the color for a member keyword.
+ The member keyword cannot contain any symbols except '_'.
+ It will not be highlighted if preceded by a '.'.
</description>
</method>
<method name="clear_color_regions">
<return type="void">
</return>
<description>
+ Removes all color regions.
</description>
</method>
<method name="clear_keyword_colors">
<return type="void">
</return>
<description>
+ Removes all keywords.
</description>
</method>
<method name="clear_member_keyword_colors">
<return type="void">
</return>
<description>
+ Removes all member keywords.
</description>
</method>
<method name="get_keyword_color" qualifiers="const">
@@ -65,6 +78,7 @@
<argument index="0" name="keyword" type="String">
</argument>
<description>
+ Returns the color for a keyword.
</description>
</method>
<method name="get_member_keyword_color" qualifiers="const">
@@ -73,14 +87,16 @@
<argument index="0" name="member_keyword" type="String">
</argument>
<description>
+ Returns the color for a member keyword.
</description>
</method>
<method name="has_color_region" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="p_start_key" type="String">
+ <argument index="0" name="start_key" type="String">
</argument>
<description>
+ Return [code]true[/code] if the start key exists, else [code]false[/code].
</description>
</method>
<method name="has_keyword_color" qualifiers="const">
@@ -89,6 +105,7 @@
<argument index="0" name="keyword" type="String">
</argument>
<description>
+ Return [code]true[/code] if the keyword exists, else [code]false[/code].
</description>
</method>
<method name="has_member_keyword_color" qualifiers="const">
@@ -97,14 +114,16 @@
<argument index="0" name="member_keyword" type="String">
</argument>
<description>
+ Return [code]true[/code] if the member keyword exists, else [code]false[/code].
</description>
</method>
<method name="remove_color_region">
<return type="void">
</return>
- <argument index="0" name="p_start_key" type="String">
+ <argument index="0" name="start_key" type="String">
</argument>
<description>
+ Removes the color region that uses that start key.
</description>
</method>
<method name="remove_keyword_color">
@@ -113,6 +132,7 @@
<argument index="0" name="keyword" type="String">
</argument>
<description>
+ Removes the keyword.
</description>
</method>
<method name="remove_member_keyword_color">
@@ -121,23 +141,31 @@
<argument index="0" name="member_keyword" type="String">
</argument>
<description>
+ Removes the member keyword.
</description>
</method>
</methods>
<members>
<member name="color_regions" type="Dictionary" setter="set_color_regions" getter="get_color_regions" default="{}">
+ Sets the color regions. All existing regions will be removed. The [Dictionary] key is the region start and end key, separated by a space. The value is the region color.
</member>
<member name="function_color" type="Color" setter="set_function_color" getter="get_function_color" default="Color( 0, 0, 0, 1 )">
+ Sets color for functions. A function is a non-keyword string followed by a '('.
</member>
<member name="keyword_colors" type="Dictionary" setter="set_keyword_colors" getter="get_keyword_colors" default="{}">
+ Sets the keyword colors. All existing keywords will be removed. The [Dictionary] key is the keyword. The value is the keyword color.
</member>
<member name="member_keyword_colors" type="Dictionary" setter="set_member_keyword_colors" getter="get_member_keyword_colors" default="{}">
+ Sets the member keyword colors. All existing member keyword will be removed. The [Dictionary] key is the member keyword. The value is the member keyword color.
</member>
<member name="member_variable_color" type="Color" setter="set_member_variable_color" getter="get_member_variable_color" default="Color( 0, 0, 0, 1 )">
+ Sets color for member variables. A member variable is non-keyword, non-function string proceeded with a '.'.
</member>
<member name="number_color" type="Color" setter="set_number_color" getter="get_number_color" default="Color( 0, 0, 0, 1 )">
+ Sets the color for numbers.
</member>
<member name="symbol_color" type="Color" setter="set_symbol_color" getter="get_symbol_color" default="Color( 0, 0, 0, 1 )">
+ Sets the color for symbols.
</member>
</members>
<constants>
diff --git a/doc/classes/CollisionPolygon3D.xml b/doc/classes/CollisionPolygon3D.xml
index dd3c57d1d0..38f4c5fe5c 100644
--- a/doc/classes/CollisionPolygon3D.xml
+++ b/doc/classes/CollisionPolygon3D.xml
@@ -17,6 +17,9 @@
<member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" default="false">
If [code]true[/code], no collision will be produced.
</member>
+ <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.04">
+ The collision margin for the generated [Shape3D]. See [member Shape3D.margin] for more details.
+ </member>
<member name="polygon" type="PackedVector2Array" setter="set_polygon" getter="get_polygon" default="PackedVector2Array( )">
Array of vertices which define the polygon.
[b]Note:[/b] The returned value is a copy of the original. Methods which mutate the size or properties of the return value will not impact the original polygon. To change properties of the polygon, assign it to a temporary variable and make changes before reassigning the [code]polygon[/code] member.
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index 755fd7eea2..ce88e0ae88 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
A color represented by red, green, blue, and alpha (RGBA) components. The alpha component is often used for transparency. Values are in floating-point and usually range from 0 to 1. Some properties (such as CanvasItem.modulate) may accept values greater than 1 (overbright or HDR colors).
- You can also create a color from standardized color names by using [method @GDScript.ColorN] or directly using the color constants defined here. The standardized color set is based on the [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url].
+ You can also create a color from standardized color names by using the string constructor or directly using the color constants defined here. The standardized color set is based on the [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url].
If you want to supply values in a range of 0 to 255, you should use [method @GDScript.Color8].
[b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it's equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). Otherwise, a Color will always evaluate to [code]true[/code].
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/color_constants.png]Color constants cheatsheet[/url]
@@ -54,6 +54,26 @@
<method name="Color" qualifiers="constructor">
<return type="Color">
</return>
+ <argument index="0" name="code" type="String">
+ </argument>
+ <argument index="1" name="alpha" type="float">
+ </argument>
+ <description>
+ Constructs a [Color] either from an HTML color code or from a standardized color name, with [code]alpha[/code] on the range of 0 to 1. Supported color names are the same as the constants.
+ </description>
+ </method>
+ <method name="Color" qualifiers="constructor">
+ <return type="Color">
+ </return>
+ <argument index="0" name="code" type="String">
+ </argument>
+ <description>
+ Constructs a [Color] either from an HTML color code or from a standardized color name. Supported color names are the same as the constants.
+ </description>
+ </method>
+ <method name="Color" qualifiers="constructor">
+ <return type="Color">
+ </return>
<argument index="0" name="r" type="float">
</argument>
<argument index="1" name="g" type="float">
@@ -158,7 +178,7 @@
<argument index="0" name="to" type="Color">
</argument>
<description>
- Returns [code]true[/code] if this color and [code]color[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component.
+ Returns [code]true[/code] if this color and [code]color[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
<method name="lerp">
diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml
index aea3542867..2fc4313e47 100644
--- a/doc/classes/ColorPicker.xml
+++ b/doc/classes/ColorPicker.xml
@@ -91,6 +91,9 @@
<theme_item name="add_preset" type="Texture2D">
The icon for the "Add Preset" button.
</theme_item>
+ <theme_item name="bar_arrow" type="Texture2D">
+ The texture for the arrow grabber.
+ </theme_item>
<theme_item name="color_hue" type="Texture2D">
Custom texture for the hue selection slider on the right.
</theme_item>
diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml
index c04e8b9ea0..e49027e61d 100644
--- a/doc/classes/ColorPickerButton.xml
+++ b/doc/classes/ColorPickerButton.xml
@@ -73,13 +73,16 @@
<theme_item name="font_color" type="Color" default="Color( 1, 1, 1, 1 )">
Default text [Color] of the [ColorPickerButton].
</theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.3 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.3 )">
Text [Color] used when the [ColorPickerButton] is disabled.
</theme_item>
- <theme_item name="font_color_hover" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_hover_color" type="Color" default="Color( 1, 1, 1, 1 )">
Text [Color] used when the [ColorPickerButton] is being hovered.
</theme_item>
- <theme_item name="font_color_pressed" type="Color" default="Color( 0.8, 0.8, 0.8, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [ColorPickerButton].
+ </theme_item>
+ <theme_item name="font_pressed_color" type="Color" default="Color( 0.8, 0.8, 0.8, 1 )">
Text [Color] used when the [ColorPickerButton] is being pressed.
</theme_item>
<theme_item name="font_size" type="int">
@@ -94,6 +97,9 @@
<theme_item name="normal" type="StyleBox">
Default [StyleBox] for the [ColorPickerButton].
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="pressed" type="StyleBox">
[StyleBox] used when the [ColorPickerButton] is being pressed.
</theme_item>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 811d0d6369..c5e820e9fe 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -16,8 +16,9 @@
[b]Note:[/b] Theme items are [i]not[/i] [Object] properties. This means you can't access their values using [method Object.get] and [method Object.set]. Instead, use the [code]get_theme_*[/code] and [code]add_theme_*_override[/code] methods provided by this class.
</description>
<tutorials>
- <link title="GUI tutorial index">https://docs.godotengine.org/en/latest/tutorials/gui/index.html</link>
+ <link title="GUI tutorial index">https://docs.godotengine.org/en/latest/tutorials/ui/index.html</link>
<link title="Custom drawing in 2D">https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html</link>
+ <link title="Control node gallery">https://docs.godotengine.org/en/latest/tutorials/ui/control_node_gallery.html</link>
<link title="All GUI Demos">https://github.com/godotengine/godot-demo-projects/tree/master/gui</link>
</tutorials>
<methods>
@@ -213,17 +214,6 @@
Overrides the icon with given [code]name[/code] in the [member theme] resource the control uses. If [code]icon[/code] is [code]null[/code] or invalid, the override is cleared and the icon from assigned [Theme] is used.
</description>
</method>
- <method name="add_theme_shader_override">
- <return type="void">
- </return>
- <argument index="0" name="name" type="StringName">
- </argument>
- <argument index="1" name="shader" type="Shader">
- </argument>
- <description>
- Overrides the [Shader] with given [code]name[/code] in the [member theme] resource the control uses. If [code]shader[/code] is [code]null[/code] or invalid, the override is cleared and the shader from assigned [Theme] is used.
- </description>
- </method>
<method name="add_theme_stylebox_override">
<return type="void">
</return>
@@ -317,6 +307,20 @@
[/codeblocks]
</description>
</method>
+ <method name="find_next_valid_focus" qualifiers="const">
+ <return type="Control">
+ </return>
+ <description>
+ Finds the next (below in the tree) [Control] that can receive the focus.
+ </description>
+ </method>
+ <method name="find_prev_valid_focus" qualifiers="const">
+ <return type="Control">
+ </return>
+ <description>
+ Finds the previous (above in the tree) [Control] that can receive the focus.
+ </description>
+ </method>
<method name="force_drag">
<return type="void">
</return>
@@ -417,20 +421,20 @@
Returns the position and size of the control relative to the top-left corner of the screen. See [member rect_position] and [member rect_size].
</description>
</method>
- <method name="get_offset" qualifiers="const">
- <return type="float">
+ <method name="get_minimum_size" qualifiers="const">
+ <return type="Vector2">
</return>
- <argument index="0" name="side" type="int" enum="Side">
- </argument>
<description>
- Returns the anchor for the specified [enum Side]. A getter method for [member offset_bottom], [member offset_left], [member offset_right] and [member offset_top].
+ Returns the minimum size for this control. See [member rect_min_size].
</description>
</method>
- <method name="get_minimum_size" qualifiers="const">
- <return type="Vector2">
+ <method name="get_offset" qualifiers="const">
+ <return type="float">
</return>
+ <argument index="0" name="offset" type="int" enum="Side">
+ </argument>
<description>
- Returns the minimum size for this control. See [member rect_min_size].
+ Returns the anchor for the specified [enum Side]. A getter method for [member offset_bottom], [member offset_left], [member offset_right] and [member offset_top].
</description>
</method>
<method name="get_parent_area_size" qualifiers="const">
@@ -454,13 +458,6 @@
Returns the position and size of the control relative to the top-left corner of the parent Control. See [member rect_position] and [member rect_size].
</description>
</method>
- <method name="get_rotation" qualifiers="const">
- <return type="float">
- </return>
- <description>
- Returns the rotation (in radians).
- </description>
- </method>
<method name="get_theme_color" qualifiers="const">
<return type="Color">
</return>
@@ -692,15 +689,6 @@
Returns [code]true[/code] if icon with given [code]name[/code] has a valid override in this [Control] node.
</description>
</method>
- <method name="has_theme_shader_override" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="name" type="StringName">
- </argument>
- <description>
- Returns [code]true[/code] if [Shader] with given [code]name[/code] has a valid override in this [Control] node.
- </description>
- </method>
<method name="has_theme_stylebox" qualifiers="const">
<return type="bool">
</return>
@@ -881,7 +869,7 @@
<argument index="0" name="control" type="Control">
</argument>
<description>
- Shows the given control at the mouse pointer. A good time to call this method is in [method get_drag_data]. The control must not be in the scene tree.
+ Shows the given control at the mouse pointer. A good time to call this method is in [method get_drag_data]. The control must not be in the scene tree. You should not free the control, and you should not keep a reference to the control beyond the duration of the drag. It will be deleted automatically after the drag has ended.
[codeblocks]
[gdscript]
export (Color, RGBA) var color = Color(1, 0, 0, 1)
@@ -981,15 +969,6 @@
If [code]keep_offsets[/code] is [code]true[/code], control's anchors will be updated instead of offsets.
</description>
</method>
- <method name="set_rotation">
- <return type="void">
- </return>
- <argument index="0" name="radians" type="float">
- </argument>
- <description>
- Sets the rotation (in radians).
- </description>
- </method>
<method name="set_size">
<return type="void">
</return>
@@ -1079,28 +1058,28 @@
<member name="layout_direction" type="int" setter="set_layout_direction" getter="get_layout_direction" enum="Control.LayoutDirection" default="0">
Controls layout direction and text writing direction. Right-to-left layouts are necessary for certain languages (e.g. Arabic and Hebrew).
</member>
+ <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" enum="Control.CursorShape" default="0">
+ The default cursor shape for this control. Useful for Godot plugins and applications or games that use the system's mouse cursors.
+ [b]Note:[/b] On Linux, shapes may vary depending on the cursor theme of the system.
+ </member>
+ <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" enum="Control.MouseFilter" default="0">
+ Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. Also controls whether the control can receive the [signal mouse_entered], and [signal mouse_exited] signals. See the constants to learn what each does.
+ </member>
<member name="offset_bottom" type="float" setter="set_offset" getter="get_offset" default="0.0">
Distance between the node's bottom edge and its parent control, based on [member anchor_bottom].
- Margins are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Margins update automatically when you move or resize the node.
+ Offsets are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Offsets update automatically when you move or resize the node.
</member>
<member name="offset_left" type="float" setter="set_offset" getter="get_offset" default="0.0">
Distance between the node's left edge and its parent control, based on [member anchor_left].
- Margins are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Margins update automatically when you move or resize the node.
+ Offsets are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Offsets update automatically when you move or resize the node.
</member>
<member name="offset_right" type="float" setter="set_offset" getter="get_offset" default="0.0">
Distance between the node's right edge and its parent control, based on [member anchor_right].
- Margins are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Margins update automatically when you move or resize the node.
+ Offsets are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Offsets update automatically when you move or resize the node.
</member>
<member name="offset_top" type="float" setter="set_offset" getter="get_offset" default="0.0">
Distance between the node's top edge and its parent control, based on [member anchor_top].
- Margins are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Margins update automatically when you move or resize the node.
- </member>
- <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" enum="Control.CursorShape" default="0">
- The default cursor shape for this control. Useful for Godot plugins and applications or games that use the system's mouse cursors.
- [b]Note:[/b] On Linux, shapes may vary depending on the cursor theme of the system.
- </member>
- <member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" enum="Control.MouseFilter" default="0">
- Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. Also controls whether the control can receive the [signal mouse_entered], and [signal mouse_exited] signals. See the constants to learn what each does.
+ Offsets are often controlled by one or multiple parent [Container] nodes, so you should not modify them manually if your node is a direct child of a [Container]. Offsets update automatically when you move or resize the node.
</member>
<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" default="false">
Enables whether rendering of [CanvasItem] based children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered.
@@ -1117,7 +1096,10 @@
<member name="rect_position" type="Vector2" setter="_set_position" getter="get_position" default="Vector2( 0, 0 )">
The node's position, relative to its parent. It corresponds to the rectangle's top-left corner. The property is not affected by [member rect_pivot_offset].
</member>
- <member name="rect_rotation" type="float" setter="set_rotation_degrees" getter="get_rotation_degrees" default="0.0">
+ <member name="rect_rotation" type="float" setter="set_rotation" getter="get_rotation" default="0.0">
+ The node's rotation around its pivot, in radians. See [member rect_pivot_offset] to change the pivot's position.
+ </member>
+ <member name="rect_rotation_degrees" type="float" setter="set_rotation_degrees" getter="get_rotation_degrees" default="0.0">
The node's rotation around its pivot, in degrees. See [member rect_pivot_offset] to change the pivot's position.
</member>
<member name="rect_scale" type="Vector2" setter="set_scale" getter="get_scale" default="Vector2( 1, 1 )">
diff --git a/doc/classes/Curve2D.xml b/doc/classes/Curve2D.xml
index 2d50d98a74..b33f3b4ffc 100644
--- a/doc/classes/Curve2D.xml
+++ b/doc/classes/Curve2D.xml
@@ -63,7 +63,7 @@
<argument index="0" name="to_point" type="Vector2">
</argument>
<description>
- Returns the closest point (in curve's local space) to [code]to_point[/code].
+ Returns the closest baked point (in curve's local space) to [code]to_point[/code].
[code]to_point[/code] must be in this curve's local space.
</description>
</method>
diff --git a/doc/classes/Curve3D.xml b/doc/classes/Curve3D.xml
index bda04f010b..fcd150ad57 100644
--- a/doc/classes/Curve3D.xml
+++ b/doc/classes/Curve3D.xml
@@ -78,7 +78,7 @@
<argument index="0" name="to_point" type="Vector3">
</argument>
<description>
- Returns the closest point (in curve's local space) to [code]to_point[/code].
+ Returns the closest baked point (in curve's local space) to [code]to_point[/code].
[code]to_point[/code] must be in this curve's local space.
</description>
</method>
diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml
index 8107d97b67..ca36b2400c 100644
--- a/doc/classes/Decal.xml
+++ b/doc/classes/Decal.xml
@@ -98,7 +98,7 @@
[Texture2D] with the emission [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object.
</member>
<member name="texture_normal" type="Texture2D" setter="set_texture" getter="get_texture">
- [Texture2D] with the per-pixel normalmap for the decal. Use this to add extra detail to decals.
+ [Texture2D] with the per-pixel normal map for the decal. Use this to add extra detail to decals.
</member>
<member name="texture_orm" type="Texture2D" setter="set_texture" getter="get_texture">
[Texture2D] storing ambient occlusion, roughness, and metallic for the decal. Use this to add extra detail to decals.
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml
index cd0b5ac027..d3fcbc9f64 100644
--- a/doc/classes/Dictionary.xml
+++ b/doc/classes/Dictionary.xml
@@ -215,13 +215,6 @@
Creates a copy of the dictionary, and returns it. The [code]deep[/code] parameter causes inner dictionaries and arrays to be copied recursively, but does not apply to objects.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the dictionary is empty.
- </description>
- </method>
<method name="erase">
<return type="bool">
</return>
@@ -299,6 +292,13 @@
[b]Note:[/b] Dictionaries with the same keys/values but in a different order will have a different hash.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the dictionary is empty.
+ </description>
+ </method>
<method name="keys">
<return type="Array">
</return>
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index d91ea6528a..91e90d051d 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -492,7 +492,7 @@
</argument>
<argument index="3" name="subtitle_track" type="String">
</argument>
- <argument index="4" name="arg4" type="int">
+ <argument index="4" name="screen" type="int">
</argument>
<description>
</description>
@@ -635,6 +635,42 @@
<description>
</description>
</method>
+ <method name="tablet_get_current_driver" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ Returns current active tablet driver name.
+ [b]Note:[/b] This method is implemented on Windows.
+ </description>
+ </method>
+ <method name="tablet_get_driver_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the total number of available tablet drivers.
+ [b]Note:[/b] This method is implemented on Windows.
+ </description>
+ </method>
+ <method name="tablet_get_driver_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ Returns the tablet driver name for the given index.
+ [b]Note:[/b] This method is implemented on Windows.
+ </description>
+ </method>
+ <method name="tablet_set_current_driver">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ Set active tablet driver name.
+ [b]Note:[/b] This method is implemented on Windows.
+ </description>
+ </method>
<method name="virtual_keyboard_get_height" qualifiers="const">
<return type="int">
</return>
diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml
index 9ef2bd21cc..b29734de1c 100644
--- a/doc/classes/EditorExportPlugin.xml
+++ b/doc/classes/EditorExportPlugin.xml
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorExportPlugin" inherits="Reference" version="4.0">
<brief_description>
- A script that is executed when exporting projects.
+ A script that is executed when exporting the project.
</brief_description>
<description>
+ Editor export plugins are automatically activated whenever the user exports the project. Their most common use is to determine what files are being included in the exported project. For each plugin, [method _export_begin] is called at the beginning of the export process and then [method _export_file] is called for each exported file.
</description>
<tutorials>
</tutorials>
@@ -20,7 +21,7 @@
<argument index="3" name="flags" type="int">
</argument>
<description>
- Virtual method to be overridden by the user. It is called when the export starts and provides all information about the export.
+ Virtual method to be overridden by the user. It is called when the export starts and provides all information about the export. [code]features[/code] is the list of features for the export, [code]is_debug[/code] is [code]true[/code] for debug builds, [code]path[/code] is the target path for the exported project. [code]flags[/code] is only used when running a runnable profile, e.g. when using native run on Android.
</description>
</method>
<method name="_export_end" qualifiers="virtual">
@@ -40,6 +41,8 @@
<argument index="2" name="features" type="PackedStringArray">
</argument>
<description>
+ Virtual method to be overridden by the user. Called for each exported file, providing arguments that can be used to identify the file. [code]path[/code] is the path of the file, [code]type[/code] is the [Resource] represented by the file (e.g. [PackedScene]) and [code]features[/code] is the list of features for the export.
+ Calling [method skip] inside this callback will make the file not included in the export.
</description>
</method>
<method name="add_file">
@@ -52,6 +55,7 @@
<argument index="2" name="remap" type="bool">
</argument>
<description>
+ Adds a custom file to be exported. [code]path[/code] is the virtual path that can be used to load the file, [code]file[/code] is the binary data of the file. If [code]remap[/code] is [code]true[/code], file will not be exported, but instead remapped to the given [code]path[/code].
</description>
</method>
<method name="add_ios_bundle_file">
@@ -60,6 +64,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
+ Adds an iOS bundle file from the given [code]path[/code] to the exported project.
</description>
</method>
<method name="add_ios_cpp_code">
@@ -68,6 +73,7 @@
<argument index="0" name="code" type="String">
</argument>
<description>
+ Adds a C++ code to the iOS export. The final code is created from the code appended by each active export plugin.
</description>
</method>
<method name="add_ios_embedded_framework">
@@ -96,6 +102,7 @@
<argument index="0" name="flags" type="String">
</argument>
<description>
+ Adds linker flags for the iOS export.
</description>
</method>
<method name="add_ios_plist_content">
@@ -104,6 +111,7 @@
<argument index="0" name="plist_content" type="String">
</argument>
<description>
+ Adds content for iOS Property List files.
</description>
</method>
<method name="add_ios_project_static_lib">
@@ -112,6 +120,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
+ Adds a static lib from the given [code]path[/code] to the iOS project.
</description>
</method>
<method name="add_shared_object">
@@ -122,12 +131,14 @@
<argument index="1" name="tags" type="PackedStringArray">
</argument>
<description>
+ Adds a shared object with the given [code]tags[/code] and destination [code]path[/code].
</description>
</method>
<method name="skip">
<return type="void">
</return>
<description>
+ To be called inside [method _export_file]. Skips the current file, so it's not included in the export.
</description>
</method>
</methods>
diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml
index e5401134bf..aa64ab4043 100644
--- a/doc/classes/EditorImportPlugin.xml
+++ b/doc/classes/EditorImportPlugin.xml
@@ -16,7 +16,7 @@
return "my.special.plugin"
func get_visible_name():
- return "Special Mesh Importer"
+ return "Special Mesh"
func get_recognized_extensions():
return ["special", "spec"]
@@ -44,8 +44,7 @@
# Fill the Mesh with data read in "file", left as an exercise to the reader.
var filename = save_path + "." + get_save_extension()
- ResourceSaver.save(filename, mesh)
- return OK
+ return ResourceSaver.save(filename, mesh)
[/gdscript]
[csharp]
using Godot;
@@ -60,7 +59,7 @@
public override String GetVisibleName()
{
- return "Special Mesh Importer";
+ return "Special Mesh";
}
public override Godot.Collections.Array GetRecognizedExtensions()
@@ -104,8 +103,7 @@
var mesh = new ArrayMesh();
// Fill the Mesh with data read in "file", left as an exercise to the reader.
String filename = savePath + "." + GetSaveExtension();
- ResourceSaver.Save(filename, mesh);
- return (int)Error.Ok;
+ return (int)ResourceSaver.Save(filename, mesh);
}
}
[/csharp]
@@ -220,7 +218,7 @@
<return type="String">
</return>
<description>
- Gets the name to display in the import window.
+ Gets the name to display in the import window. You should choose this name as a continuation to "Import as", e.g. "Import as Special Mesh".
</description>
</method>
<method name="import" qualifiers="virtual">
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
index 6f03165a97..d85f95baff 100644
--- a/doc/classes/EditorInspector.xml
+++ b/doc/classes/EditorInspector.xml
@@ -10,14 +10,6 @@
<tutorials>
</tutorials>
<methods>
- <method name="refresh">
- <return type="void">
- </return>
- <description>
- Refreshes the inspector.
- [b]Note:[/b] To save on CPU resources, calling this method will do nothing if the time specified in [code]docks/property_editor/auto_refresh_interval[/code] editor setting hasn't passed yet since this method was last called. (By default, this interval is set to 0.3 seconds.)
- </description>
- </method>
</methods>
<members>
<member name="scroll_horizontal_enabled" type="bool" setter="set_enable_h_scroll" getter="is_h_scroll_enabled" override="true" default="false" />
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index c7561449b9..b01af71852 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -40,19 +40,19 @@
Returns the edited (current) scene's root [Node].
</description>
</method>
- <method name="get_editor_settings">
- <return type="EditorSettings">
+ <method name="get_editor_main_control">
+ <return type="Control">
</return>
<description>
- Returns the editor's [EditorSettings] instance.
+ Returns the main editor control. Use this as a parent for main screens.
+ [b]Note:[/b] This returns the main editor control containing the whole editor, not the 2D or 3D viewports specifically.
</description>
</method>
- <method name="get_editor_viewport">
- <return type="Control">
+ <method name="get_editor_settings">
+ <return type="EditorSettings">
</return>
<description>
- Returns the main editor control. Use this as a parent for main screens.
- [b]Note:[/b] This returns the main editor control containing the whole editor, not the 2D or 3D viewports specifically.
+ Returns the editor's [EditorSettings] instance.
</description>
</method>
<method name="get_file_system_dock">
diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml
index 322cff4e43..1e9d089962 100644
--- a/doc/classes/EditorNode3DGizmoPlugin.xml
+++ b/doc/classes/EditorNode3DGizmoPlugin.xml
@@ -98,6 +98,13 @@
Creates an unshaded material with its variants (selected and/or editable) and adds them to the internal material list. They can then be accessed with [method get_material] and used in [method EditorNode3DGizmo.add_mesh] and [method EditorNode3DGizmo.add_lines]. Should not be overridden.
</description>
</method>
+ <method name="get_gizmo_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ Override this method to provide the name that will appear in the gizmo visibility menu.
+ </description>
+ </method>
<method name="get_handle_name" qualifiers="virtual">
<return type="String">
</return>
@@ -131,13 +138,6 @@
Gets material from the internal list of materials. If an [EditorNode3DGizmo] is provided, it will try to get the corresponding variant (selected and/or editable).
</description>
</method>
- <method name="get_name" qualifiers="virtual">
- <return type="String">
- </return>
- <description>
- Override this method to provide the name that will appear in the gizmo visibility menu.
- </description>
- </method>
<method name="get_priority" qualifiers="virtual">
<return type="int">
</return>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 874fe4e3de..a24e4bbdc5 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -91,6 +91,7 @@
<argument index="0" name="plugin" type="EditorExportPlugin">
</argument>
<description>
+ Registers a new export plugin. Export plugins are used when the project is being exported. See [EditorExportPlugin] for more information.
</description>
</method>
<method name="add_import_plugin">
@@ -168,6 +169,8 @@
<return type="bool">
</return>
<description>
+ This method is called when the editor is about to run the project. The plugin can then perform required operations before the project runs.
+ This method must return a boolean. If this method returns [code]false[/code], the project will not run. The run is aborted immediately, so this also prevents all other plugins' [method build] methods from running.
</description>
</method>
<method name="clear" qualifiers="virtual">
@@ -674,6 +677,10 @@
Emitted when user changes the workspace ([b]2D[/b], [b]3D[/b], [b]Script[/b], [b]AssetLib[/b]). Also works with custom screens defined by plugins.
</description>
</signal>
+ <signal name="project_settings_changed">
+ <description>
+ </description>
+ </signal>
<signal name="resource_saved">
<argument index="0" name="resource" type="Resource">
</argument>
diff --git a/doc/classes/EditorSceneImporterAssimp.xml b/doc/classes/EditorSceneImporterAssimp.xml
deleted file mode 100644
index c72d4ee25a..0000000000
--- a/doc/classes/EditorSceneImporterAssimp.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="EditorSceneImporterAssimp" inherits="EditorSceneImporter" version="4.0">
- <brief_description>
- FBX 3D asset importer based on [url=http://assimp.org/]Assimp[/url].
- </brief_description>
- <description>
- This is an FBX 3D asset importer based on [url=http://assimp.org/]Assimp[/url]. It currently has many known limitations and works best with static meshes. Most animated meshes won't import correctly.
- If exporting a FBX scene from Autodesk Maya, use these FBX export settings:
- [codeblock]
- - Smoothing Groups
- - Smooth Mesh
- - Triangluate (for meshes with blend shapes)
- - Bake Animation
- - Resample All
- - Deformed Models
- - Skins
- - Blend Shapes
- - Curve Filters
- - Constant Key Reducer
- - Auto Tangents Only
- - *Do not check* Constraints (as it will break the file)
- - Can check Embed Media (embeds textures into the exported FBX file)
- - Note that when importing embedded media, the texture and mesh will be a single immutable file.
- - You will have to re-export then re-import the FBX if the texture has changed.
- - Units: Centimeters
- - Up Axis: Y
- - Binary format in FBX 2017
- [/codeblock]
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/EditorSceneImporterGLTF.xml b/doc/classes/EditorSceneImporterGLTF.xml
new file mode 100644
index 0000000000..e717b30f73
--- /dev/null
+++ b/doc/classes/EditorSceneImporterGLTF.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="EditorSceneImporterGLTF" inherits="EditorSceneImporter" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/EditorSceneImporterMesh.xml b/doc/classes/EditorSceneImporterMesh.xml
new file mode 100644
index 0000000000..58b7104667
--- /dev/null
+++ b/doc/classes/EditorSceneImporterMesh.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="EditorSceneImporterMesh" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_blend_shape">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="add_surface">
+ <return type="void">
+ </return>
+ <argument index="0" name="primitive" type="int" enum="Mesh.PrimitiveType">
+ </argument>
+ <argument index="1" name="arrays" type="Array">
+ </argument>
+ <argument index="2" name="blend_shapes" type="Array" default="[ ]">
+ </argument>
+ <argument index="3" name="lods" type="Dictionary" default="{
+}">
+ </argument>
+ <argument index="4" name="material" type="Material" default="null">
+ </argument>
+ <argument index="5" name="name" type="String" default="&quot;&quot;">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="clear">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_blend_shape_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_blend_shape_mode" qualifiers="const">
+ <return type="int" enum="Mesh.BlendShapeMode">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_blend_shape_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="blend_shape_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_mesh">
+ <return type="ArrayMesh">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_arrays" qualifiers="const">
+ <return type="Array">
+ </return>
+ <argument index="0" name="surface_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_blend_shape_arrays" qualifiers="const">
+ <return type="Array">
+ </return>
+ <argument index="0" name="surface_idx" type="int">
+ </argument>
+ <argument index="1" name="blend_shape_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_lod_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="surface_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_lod_indices" qualifiers="const">
+ <return type="PackedInt32Array">
+ </return>
+ <argument index="0" name="surface_idx" type="int">
+ </argument>
+ <argument index="1" name="lod_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_lod_size" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="surface_idx" type="int">
+ </argument>
+ <argument index="1" name="lod_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_material" qualifiers="const">
+ <return type="Material">
+ </return>
+ <argument index="0" name="surface_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="surface_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_primitive_type">
+ <return type="int" enum="Mesh.PrimitiveType">
+ </return>
+ <argument index="0" name="surface_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_blend_shape_mode">
+ <return type="void">
+ </return>
+ <argument index="0" name="mode" type="int" enum="Mesh.BlendShapeMode">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="_data" type="Dictionary" setter="_set_data" getter="_get_data" default="{&quot;surfaces&quot;: [ ]}">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/EditorSceneImporterMeshNode3D.xml b/doc/classes/EditorSceneImporterMeshNode3D.xml
new file mode 100644
index 0000000000..1e459c1cee
--- /dev/null
+++ b/doc/classes/EditorSceneImporterMeshNode3D.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="EditorSceneImporterMeshNode3D" inherits="Node3D" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="mesh" type="EditorSceneImporterMesh" setter="set_mesh" getter="get_mesh">
+ </member>
+ <member name="skeleton_path" type="NodePath" setter="set_skeleton_path" getter="get_skeleton_path" default="NodePath(&quot;&quot;)">
+ </member>
+ <member name="skin" type="Skin" setter="set_skin" getter="get_skin">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index 6088ae7a43..016d0128eb 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -160,6 +160,16 @@
Returns the default value of the setting specified by [code]name[/code]. This is the value that would be applied when clicking the Revert button in the Editor Settings.
</description>
</method>
+ <method name="set_builtin_action_override">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="actions_list" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_favorites">
<return type="void">
</return>
diff --git a/doc/classes/EditorSyntaxHighlighter.xml b/doc/classes/EditorSyntaxHighlighter.xml
index 103d95e1d6..b80e81928f 100644
--- a/doc/classes/EditorSyntaxHighlighter.xml
+++ b/doc/classes/EditorSyntaxHighlighter.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorSyntaxHighlighter" inherits="SyntaxHighlighter" version="4.0">
<brief_description>
+ Base Syntax highlighter resource for the [ScriptEditor].
</brief_description>
<description>
+ Base syntax highlighter resource all editor syntax highlighters extend from, it is used in the [ScriptEditor].
+ Add a syntax highlighter to an individual script by calling [method ScriptEditorBase.add_syntax_highlighter]. To apply to all scripts on open, call [method ScriptEditor.register_syntax_highlighter]
</description>
<tutorials>
</tutorials>
@@ -11,18 +14,21 @@
<return type="String">
</return>
<description>
+ Virtual method which can be overridden to return the syntax highlighter name.
</description>
</method>
<method name="_get_supported_extentions" qualifiers="virtual">
<return type="Array">
</return>
<description>
+ Virtual method which can be overridden to return the supported file extensions.
</description>
</method>
<method name="_get_supported_languages" qualifiers="virtual">
<return type="Array">
</return>
<description>
+ Virtual method which can be overridden to return the supported language names.
</description>
</method>
</methods>
diff --git a/doc/classes/EncodedObjectAsID.xml b/doc/classes/EncodedObjectAsID.xml
index fc68b47645..1e4fde453b 100644
--- a/doc/classes/EncodedObjectAsID.xml
+++ b/doc/classes/EncodedObjectAsID.xml
@@ -4,7 +4,7 @@
Holds a reference to an [Object]'s instance ID.
</brief_description>
<description>
- Utility class which holds a reference to the internal identifier of an [Object] instance, as given by [method Object.get_instance_id]. This ID can then be used to retrieve the object instance with [method @GDScript.instance_from_id].
+ Utility class which holds a reference to the internal identifier of an [Object] instance, as given by [method Object.get_instance_id]. This ID can then be used to retrieve the object instance with [method @GlobalScope.instance_from_id].
This class is used internally by the editor inspector and script debugger, but can also be used in plugins to pass and display objects as their IDs.
</description>
<tutorials>
@@ -13,7 +13,7 @@
</methods>
<members>
<member name="object_id" type="int" setter="set_object_id" getter="get_object_id" default="0">
- The [Object] identifier stored in this [EncodedObjectAsID] instance. The object instance can be retrieved with [method @GDScript.instance_from_id].
+ The [Object] identifier stored in this [EncodedObjectAsID] instance. The object instance can be retrieved with [method @GlobalScope.instance_from_id].
</member>
</members>
<constants>
diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml
index fab8512e4a..02b81ee9b7 100644
--- a/doc/classes/Engine.xml
+++ b/doc/classes/Engine.xml
@@ -41,7 +41,7 @@
<return type="int">
</return>
<description>
- Returns the total number of frames drawn. If the render loop is disabled with [code]--disable-render-loop[/code] via command line, this returns [code]0[/code]. See also [method get_idle_frames].
+ Returns the total number of frames drawn. If the render loop is disabled with [code]--disable-render-loop[/code] via command line, this returns [code]0[/code]. See also [method get_process_frames].
</description>
</method>
<method name="get_frames_per_second" qualifiers="const">
@@ -51,13 +51,6 @@
Returns the frames per second of the running game.
</description>
</method>
- <method name="get_idle_frames" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Returns the total number of frames passed since engine initialization which is advanced on each [b]idle frame[/b], regardless of whether the render loop is enabled. See also [method get_frames_drawn].
- </description>
- </method>
<method name="get_license_info" qualifiers="const">
<return type="Dictionary">
</return>
@@ -93,6 +86,13 @@
Returns the fraction through the current physics tick we are at the time of rendering the frame. This can be used to implement fixed timestep interpolation.
</description>
</method>
+ <method name="get_process_frames" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the total number of frames passed since engine initialization which is advanced on each [b]process frame[/b], regardless of whether the render loop is enabled. See also [method get_frames_drawn].
+ </description>
+ </method>
<method name="get_singleton" qualifiers="const">
<return type="Object">
</return>
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 9dd4ecc37b..821aa91d21 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -169,6 +169,8 @@
</member>
<member name="reflected_light_source" type="int" setter="set_reflection_source" getter="get_reflection_source" enum="Environment.ReflectionSource" default="0">
</member>
+ <member name="sdfgi_bounce_feedback" type="float" setter="set_sdfgi_bounce_feedback" getter="get_sdfgi_bounce_feedback" default="0.0">
+ </member>
<member name="sdfgi_cascade0_distance" type="float" setter="set_sdfgi_cascade0_distance" getter="get_sdfgi_cascade0_distance" default="12.8">
</member>
<member name="sdfgi_cascades" type="int" setter="set_sdfgi_cascades" getter="get_sdfgi_cascades" enum="Environment.SDFGICascades" default="1">
@@ -187,8 +189,6 @@
</member>
<member name="sdfgi_read_sky_light" type="bool" setter="set_sdfgi_read_sky_light" getter="is_sdfgi_reading_sky_light" default="false">
</member>
- <member name="sdfgi_use_multi_bounce" type="bool" setter="set_sdfgi_use_multi_bounce" getter="is_sdfgi_using_multi_bounce" default="false">
- </member>
<member name="sdfgi_use_occlusion" type="bool" setter="set_sdfgi_use_occlusion" getter="is_sdfgi_using_occlusion" default="false">
</member>
<member name="sdfgi_y_scale" type="int" setter="set_sdfgi_y_scale" getter="get_sdfgi_y_scale" enum="Environment.SDFGIYScale" default="0">
@@ -265,12 +265,14 @@
</member>
<member name="volumetric_fog_light_energy" type="float" setter="set_volumetric_fog_light_energy" getter="get_volumetric_fog_light_energy" default="1.0">
</member>
- <member name="volumetric_fog_shadow_filter" type="int" setter="set_volumetric_fog_shadow_filter" getter="get_volumetric_fog_shadow_filter" enum="Environment.VolumetricFogShadowFilter" default="1">
+ <member name="volumetric_fog_temporal_reprojection_amount" type="float" setter="set_volumetric_fog_temporal_reprojection_amount" getter="get_volumetric_fog_temporal_reprojection_amount" default="0.9">
+ </member>
+ <member name="volumetric_fog_temporal_reprojection_enabled" type="bool" setter="set_volumetric_fog_temporal_reprojection_enabled" getter="is_volumetric_fog_temporal_reprojection_enabled" default="true">
</member>
</members>
<constants>
<constant name="BG_CLEAR_COLOR" value="0" enum="BGMode">
- Clears the background using the clear color defined in [member ProjectSettings.rendering/environment/default_clear_color].
+ Clears the background using the clear color defined in [member ProjectSettings.rendering/environment/defaults/default_clear_color].
</constant>
<constant name="BG_COLOR" value="1" enum="BGMode">
Clears the background using a custom clear color.
diff --git a/doc/classes/File.xml b/doc/classes/File.xml
index 2f7ac551cf..e0781e807f 100644
--- a/doc/classes/File.xml
+++ b/doc/classes/File.xml
@@ -42,6 +42,7 @@
[/codeblocks]
In the example above, the file will be saved in the user data folder as specified in the [url=https://docs.godotengine.org/en/latest/tutorials/io/data_paths.html]Data paths[/url] documentation.
[b]Note:[/b] To access project resources once exported, it is recommended to use [ResourceLoader] instead of the [File] API, as some files are converted to engine-specific formats and their original source files might not be present in the exported PCK package.
+ [b]Note:[/b] Files are automatically closed only if the process exits "normally" (such as by clicking the window manager's close button or pressing [b]Alt + F4[/b]). If you stop the project execution by pressing [b]F8[/b] while the project is running, the file won't be closed as the game process will be killed. You can work around this by calling [method flush] at regular intervals.
</description>
<tutorials>
<link title="File system">https://docs.godotengine.org/en/latest/getting_started/step_by_step/filesystem.html</link>
@@ -52,7 +53,7 @@
<return type="void">
</return>
<description>
- Closes the currently opened file.
+ Closes the currently opened file and prevents subsequent read/write operations. Use [method flush] to persist the data to disk without closing the file.
</description>
</method>
<method name="eof_reached" qualifiers="const">
@@ -73,6 +74,14 @@
[b]Note:[/b] Many resources types are imported (e.g. textures or sound files), and their source asset will not be included in the exported game, as only the imported version is used. See [method ResourceLoader.exists] for an alternative approach that takes resource remapping into account.
</description>
</method>
+ <method name="flush">
+ <return type="void">
+ </return>
+ <description>
+ Writes the file's buffer to disk. Flushing is automatically performed when the file is closed. This means you don't need to call [method flush] manually before closing a file using [method close]. Still, calling [method flush] can be used to ensure the data is safe even if the project crashes instead of being closed gracefully.
+ [b]Note:[/b] Only call [method flush] when you actually need it. Otherwise, it will decrease performance due to constant disk writes.
+ </description>
+ </method>
<method name="get_16" qualifiers="const">
<return type="int">
</return>
@@ -481,8 +490,9 @@
</methods>
<members>
<member name="endian_swap" type="bool" setter="set_endian_swap" getter="get_endian_swap" default="false">
- If [code]true[/code], the file's endianness is swapped. Use this if you're dealing with files written on big-endian machines.
- [b]Note:[/b] This is about the file format, not CPU type. This is always reset to [code]false[/code] whenever you open the file.
+ If [code]true[/code], the file is read with big-endian [url=https://en.wikipedia.org/wiki/Endianness]endianness[/url]. If [code]false[/code], the file is read with little-endian endianness. If in doubt, leave this to [code]false[/code] as most files are written with little-endian endianness.
+ [b]Note:[/b] [member endian_swap] is only about the file format, not the CPU type. The CPU endianness doesn't affect the default endianness for files written.
+ [b]Note:[/b] This is always reset to [code]false[/code] whenever you open the file. Therefore, you must set [member endian_swap] [i]after[/i] opening the file, not before.
</member>
</members>
<constants>
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index b4afee7610..ed437aefd5 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -25,11 +25,11 @@
Clear all the added filters in the dialog.
</description>
</method>
- <method name="deselect_items">
+ <method name="deselect_all">
<return type="void">
</return>
<description>
- Clear currently selected items in the dialog.
+ Clear all currently selected items in the dialog.
</description>
</method>
<method name="get_line_edit">
diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml
index edd2bd137f..409e405551 100644
--- a/doc/classes/Font.xml
+++ b/doc/classes/Font.xml
@@ -329,10 +329,10 @@
</methods>
<members>
<member name="extra_spacing_bottom" type="int" setter="set_spacing" getter="get_spacing" default="0">
- Extra spacing at the bottom in pixels.
+ Extra spacing at the bottom of the line in pixels.
</member>
<member name="extra_spacing_top" type="int" setter="set_spacing" getter="get_spacing" default="0">
- Extra character spacing in pixels.
+ Extra spacing at the top of the line in pixels.
</member>
</members>
<constants>
diff --git a/doc/classes/FontData.xml b/doc/classes/FontData.xml
index e2c35f9ce7..6c54af05cd 100644
--- a/doc/classes/FontData.xml
+++ b/doc/classes/FontData.xml
@@ -11,6 +11,45 @@
<tutorials>
</tutorials>
<methods>
+ <method name="bitmap_add_char">
+ <return type="void">
+ </return>
+ <argument index="0" name="char" type="int">
+ </argument>
+ <argument index="1" name="texture_idx" type="int">
+ </argument>
+ <argument index="2" name="rect" type="Rect2">
+ </argument>
+ <argument index="3" name="align" type="Vector2">
+ </argument>
+ <argument index="4" name="advance" type="float">
+ </argument>
+ <description>
+ Adds a character to the font, where [code]character[/code] is the Unicode value, [code]texture[/code] is the texture index, [code]rect[/code] is the region in the texture (in pixels!), [code]align[/code] is the (optional) alignment for the character and [code]advance[/code] is the (optional) advance.
+ </description>
+ </method>
+ <method name="bitmap_add_kerning_pair">
+ <return type="void">
+ </return>
+ <argument index="0" name="A" type="int">
+ </argument>
+ <argument index="1" name="B" type="int">
+ </argument>
+ <argument index="2" name="kerning" type="int">
+ </argument>
+ <description>
+ Adds a kerning pair to the bitmap font as a difference. Kerning pairs are special cases where a typeface advance is determined by the next character.
+ </description>
+ </method>
+ <method name="bitmap_add_texture">
+ <return type="void">
+ </return>
+ <argument index="0" name="texture" type="Texture">
+ </argument>
+ <description>
+ Adds a texture to the bitmap font.
+ </description>
+ </method>
<method name="draw_glyph" qualifiers="const">
<return type="Vector2">
</return>
@@ -154,6 +193,15 @@
Returns list of script support overrides.
</description>
</method>
+ <method name="get_spacing" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="type" type="int">
+ </argument>
+ <description>
+ Returns the spacing for the given [code]type[/code] (see [enum SpacingType]).
+ </description>
+ </method>
<method name="get_supported_chars" qualifiers="const">
<return type="String">
</return>
@@ -256,6 +304,19 @@
Note: For non-scalable fonts [code]base_size[/code] is ignored, use [method get_base_size] to check actual font size.
</description>
</method>
+ <method name="new_bitmap">
+ <return type="void">
+ </return>
+ <argument index="0" name="height" type="float">
+ </argument>
+ <argument index="1" name="ascent" type="float">
+ </argument>
+ <argument index="2" name="base_size" type="int">
+ </argument>
+ <description>
+ Creates new, empty bitmap font.
+ </description>
+ </method>
<method name="remove_language_support_override">
<return type="void">
</return>
@@ -296,6 +357,17 @@
Adds override for [method is_script_supported].
</description>
</method>
+ <method name="set_spacing">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int">
+ </argument>
+ <argument index="1" name="value" type="int">
+ </argument>
+ <description>
+ Sets the spacing for [code]type[/code] (see [enum SpacingType]) to [code]value[/code] in pixels (not relative to the font size).
+ </description>
+ </method>
<method name="set_variation">
<return type="void">
</return>
@@ -318,6 +390,14 @@
<member name="distance_field_hint" type="bool" setter="set_distance_field_hint" getter="get_distance_field_hint" default="false">
If [code]true[/code], distance field hint is enabled.
</member>
+ <member name="extra_spacing_glyph" type="int" setter="set_spacing" getter="get_spacing" default="0">
+ Extra spacing for each glyphs in pixels.
+ This can be a negative number to make the distance between glyphs smaller.
+ </member>
+ <member name="extra_spacing_space" type="int" setter="set_spacing" getter="get_spacing" default="0">
+ Extra spacing for the space character in pixels.
+ This can be a negative number to make the distance between words smaller.
+ </member>
<member name="force_autohinter" type="bool" setter="set_force_autohinter" getter="get_force_autohinter" default="false">
If [code]true[/code], default autohinter is used for font hinting.
</member>
@@ -326,5 +406,11 @@
</member>
</members>
<constants>
+ <constant name="SPACING_GLYPH" value="0" enum="SpacingType">
+ Spacing for each glyph.
+ </constant>
+ <constant name="SPACING_SPACE" value="1" enum="SpacingType">
+ Spacing for the space character.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/GIProbe.xml b/doc/classes/GIProbe.xml
index 52d3698201..dd51248fd9 100644
--- a/doc/classes/GIProbe.xml
+++ b/doc/classes/GIProbe.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
[GIProbe]s are used to provide high-quality real-time indirect light to scenes. They precompute the effect of objects that emit light and the effect of static geometry to simulate the behavior of complex light in real-time. [GIProbe]s need to be baked before using, however, once baked, dynamic objects will receive light from them. Further, lights can be fully dynamic or baked.
- Having [GIProbe]s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the [ProjectSettings] using [member ProjectSettings.rendering/quality/gi_probes/quality].
+ Having [GIProbe]s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the [ProjectSettings] using [member ProjectSettings.rendering/global_illumination/gi_probes/quality].
</description>
<tutorials>
<link title="GI probes">https://docs.godotengine.org/en/latest/tutorials/3d/gi_probes.html</link>
diff --git a/doc/classes/GLTFAccessor.xml b/doc/classes/GLTFAccessor.xml
new file mode 100644
index 0000000000..a1f596f7dd
--- /dev/null
+++ b/doc/classes/GLTFAccessor.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFAccessor" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="buffer_view" type="int" setter="set_buffer_view" getter="get_buffer_view" default="0">
+ </member>
+ <member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0">
+ </member>
+ <member name="component_type" type="int" setter="set_component_type" getter="get_component_type" default="0">
+ </member>
+ <member name="count" type="int" setter="set_count" getter="get_count" default="0">
+ </member>
+ <member name="max" type="PackedFloat64Array" setter="set_max" getter="get_max" default="PackedFloat64Array( )">
+ </member>
+ <member name="min" type="PackedFloat64Array" setter="set_min" getter="get_min" default="PackedFloat64Array( )">
+ </member>
+ <member name="normalized" type="bool" setter="set_normalized" getter="get_normalized" default="false">
+ </member>
+ <member name="sparse_count" type="int" setter="set_sparse_count" getter="get_sparse_count" default="0">
+ </member>
+ <member name="sparse_indices_buffer_view" type="int" setter="set_sparse_indices_buffer_view" getter="get_sparse_indices_buffer_view" default="0">
+ </member>
+ <member name="sparse_indices_byte_offset" type="int" setter="set_sparse_indices_byte_offset" getter="get_sparse_indices_byte_offset" default="0">
+ </member>
+ <member name="sparse_indices_component_type" type="int" setter="set_sparse_indices_component_type" getter="get_sparse_indices_component_type" default="0">
+ </member>
+ <member name="sparse_values_buffer_view" type="int" setter="set_sparse_values_buffer_view" getter="get_sparse_values_buffer_view" default="0">
+ </member>
+ <member name="sparse_values_byte_offset" type="int" setter="set_sparse_values_byte_offset" getter="get_sparse_values_byte_offset" default="0">
+ </member>
+ <member name="type" type="int" setter="set_type" getter="get_type" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFAnimation.xml b/doc/classes/GLTFAnimation.xml
new file mode 100644
index 0000000000..5c1fa02f11
--- /dev/null
+++ b/doc/classes/GLTFAnimation.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFAnimation" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="loop" type="bool" setter="set_loop" getter="get_loop" default="false">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFBufferView.xml b/doc/classes/GLTFBufferView.xml
new file mode 100644
index 0000000000..edaad85e0a
--- /dev/null
+++ b/doc/classes/GLTFBufferView.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFBufferView" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="buffer" type="int" setter="set_buffer" getter="get_buffer" default="-1">
+ </member>
+ <member name="byte_length" type="int" setter="set_byte_length" getter="get_byte_length" default="0">
+ </member>
+ <member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0">
+ </member>
+ <member name="byte_stride" type="int" setter="set_byte_stride" getter="get_byte_stride" default="-1">
+ </member>
+ <member name="indices" type="bool" setter="set_indices" getter="get_indices" default="false">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFCamera.xml b/doc/classes/GLTFCamera.xml
new file mode 100644
index 0000000000..0b95f2c802
--- /dev/null
+++ b/doc/classes/GLTFCamera.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFCamera" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="fov_size" type="float" setter="set_fov_size" getter="get_fov_size" default="75.0">
+ </member>
+ <member name="perspective" type="bool" setter="set_perspective" getter="get_perspective" default="true">
+ </member>
+ <member name="zfar" type="float" setter="set_zfar" getter="get_zfar" default="4000.0">
+ </member>
+ <member name="znear" type="float" setter="set_znear" getter="get_znear" default="0.05">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFDocument.xml b/doc/classes/GLTFDocument.xml
new file mode 100644
index 0000000000..04c40dd752
--- /dev/null
+++ b/doc/classes/GLTFDocument.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFDocument" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFLight.xml b/doc/classes/GLTFLight.xml
new file mode 100644
index 0000000000..bfeaf9a86e
--- /dev/null
+++ b/doc/classes/GLTFLight.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFLight" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 0, 0, 0, 1 )">
+ </member>
+ <member name="inner_cone_angle" type="float" setter="set_inner_cone_angle" getter="get_inner_cone_angle" default="0.0">
+ </member>
+ <member name="intensity" type="float" setter="set_intensity" getter="get_intensity" default="0.0">
+ </member>
+ <member name="outer_cone_angle" type="float" setter="set_outer_cone_angle" getter="get_outer_cone_angle" default="0.0">
+ </member>
+ <member name="range" type="float" setter="set_range" getter="get_range" default="0.0">
+ </member>
+ <member name="type" type="String" setter="set_type" getter="get_type" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFMesh.xml b/doc/classes/GLTFMesh.xml
new file mode 100644
index 0000000000..55f79d2c55
--- /dev/null
+++ b/doc/classes/GLTFMesh.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFMesh" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="blend_weights" type="PackedFloat32Array" setter="set_blend_weights" getter="get_blend_weights" default="PackedFloat32Array( )">
+ </member>
+ <member name="mesh" type="EditorSceneImporterMesh" setter="set_mesh" getter="get_mesh">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFNode.xml b/doc/classes/GLTFNode.xml
new file mode 100644
index 0000000000..5b7d4fadec
--- /dev/null
+++ b/doc/classes/GLTFNode.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFNode" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="camera" type="int" setter="set_camera" getter="get_camera" default="-1">
+ </member>
+ <member name="children" type="PackedInt32Array" setter="set_children" getter="get_children" default="PackedInt32Array( )">
+ </member>
+ <member name="fake_joint_parent" type="int" setter="set_fake_joint_parent" getter="get_fake_joint_parent" default="-1">
+ </member>
+ <member name="height" type="int" setter="set_height" getter="get_height" default="-1">
+ </member>
+ <member name="joint" type="bool" setter="set_joint" getter="get_joint" default="false">
+ </member>
+ <member name="light" type="int" setter="set_light" getter="get_light" default="-1">
+ </member>
+ <member name="mesh" type="int" setter="set_mesh" getter="get_mesh" default="-1">
+ </member>
+ <member name="parent" type="int" setter="set_parent" getter="get_parent" default="-1">
+ </member>
+ <member name="rotation" type="Quat" setter="set_rotation" getter="get_rotation" default="Quat( 0, 0, 0, 1 )">
+ </member>
+ <member name="scale" type="Vector3" setter="set_scale" getter="get_scale" default="Vector3( 1, 1, 1 )">
+ </member>
+ <member name="skeleton" type="int" setter="set_skeleton" getter="get_skeleton" default="-1">
+ </member>
+ <member name="skin" type="int" setter="set_skin" getter="get_skin" default="-1">
+ </member>
+ <member name="translation" type="Vector3" setter="set_translation" getter="get_translation" default="Vector3( 0, 0, 0 )">
+ </member>
+ <member name="xform" type="Transform" setter="set_xform" getter="get_xform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFSkeleton.xml b/doc/classes/GLTFSkeleton.xml
new file mode 100644
index 0000000000..9680c27705
--- /dev/null
+++ b/doc/classes/GLTFSkeleton.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFSkeleton" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_bone_attachment">
+ <return type="BoneAttachment3D">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_bone_attachment_count">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_godot_bone_node">
+ <return type="Dictionary">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_godot_skeleton">
+ <return type="Skeleton3D">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_unique_names">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_godot_bone_node">
+ <return type="void">
+ </return>
+ <argument index="0" name="godot_bone_node" type="Dictionary">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_unique_names">
+ <return type="void">
+ </return>
+ <argument index="0" name="unique_names" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="joints" type="PackedInt32Array" setter="set_joints" getter="get_joints" default="PackedInt32Array( )">
+ </member>
+ <member name="roots" type="PackedInt32Array" setter="set_roots" getter="get_roots" default="PackedInt32Array( )">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFSkin.xml b/doc/classes/GLTFSkin.xml
new file mode 100644
index 0000000000..5a80c7097a
--- /dev/null
+++ b/doc/classes/GLTFSkin.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFSkin" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_inverse_binds">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_joint_i_to_bone_i">
+ <return type="Dictionary">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_joint_i_to_name">
+ <return type="Dictionary">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_inverse_binds">
+ <return type="void">
+ </return>
+ <argument index="0" name="inverse_binds" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_joint_i_to_bone_i">
+ <return type="void">
+ </return>
+ <argument index="0" name="joint_i_to_bone_i" type="Dictionary">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_joint_i_to_name">
+ <return type="void">
+ </return>
+ <argument index="0" name="joint_i_to_name" type="Dictionary">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="godot_skin" type="Skin" setter="set_godot_skin" getter="get_godot_skin">
+ </member>
+ <member name="joints" type="PackedInt32Array" setter="set_joints" getter="get_joints" default="PackedInt32Array( )">
+ </member>
+ <member name="joints_original" type="PackedInt32Array" setter="set_joints_original" getter="get_joints_original" default="PackedInt32Array( )">
+ </member>
+ <member name="non_joints" type="PackedInt32Array" setter="set_non_joints" getter="get_non_joints" default="PackedInt32Array( )">
+ </member>
+ <member name="roots" type="PackedInt32Array" setter="set_roots" getter="get_roots" default="PackedInt32Array( )">
+ </member>
+ <member name="skeleton" type="int" setter="set_skeleton" getter="get_skeleton" default="-1">
+ </member>
+ <member name="skin_root" type="int" setter="set_skin_root" getter="get_skin_root" default="-1">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFSpecGloss.xml b/doc/classes/GLTFSpecGloss.xml
new file mode 100644
index 0000000000..68cc7c845d
--- /dev/null
+++ b/doc/classes/GLTFSpecGloss.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFSpecGloss" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="diffuse_factor" type="Color" setter="set_diffuse_factor" getter="get_diffuse_factor" default="Color( 1, 1, 1, 1 )">
+ </member>
+ <member name="diffuse_img" type="Image" setter="set_diffuse_img" getter="get_diffuse_img">
+ </member>
+ <member name="gloss_factor" type="float" setter="set_gloss_factor" getter="get_gloss_factor" default="1.0">
+ </member>
+ <member name="spec_gloss_img" type="Image" setter="set_spec_gloss_img" getter="get_spec_gloss_img">
+ </member>
+ <member name="specular_factor" type="Color" setter="set_specular_factor" getter="get_specular_factor" default="Color( 1, 1, 1, 1 )">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFState.xml b/doc/classes/GLTFState.xml
new file mode 100644
index 0000000000..8255cd73d0
--- /dev/null
+++ b/doc/classes/GLTFState.xml
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFState" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_accessors">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_animation_player">
+ <return type="AnimationPlayer">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_animation_players_count">
+ <return type="int">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_animations">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_buffer_views">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_cameras">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_images">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_lights">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_materials">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_meshes">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_nodes">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_scene_node">
+ <return type="Node">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_skeleton_to_node">
+ <return type="Dictionary">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_skeletons">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_skins">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_textures">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_unique_animation_names">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_unique_names">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_accessors">
+ <return type="void">
+ </return>
+ <argument index="0" name="accessors" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_animations">
+ <return type="void">
+ </return>
+ <argument index="0" name="animations" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_buffer_views">
+ <return type="void">
+ </return>
+ <argument index="0" name="buffer_views" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_cameras">
+ <return type="void">
+ </return>
+ <argument index="0" name="cameras" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_images">
+ <return type="void">
+ </return>
+ <argument index="0" name="images" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_lights">
+ <return type="void">
+ </return>
+ <argument index="0" name="lights" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_materials">
+ <return type="void">
+ </return>
+ <argument index="0" name="materials" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_meshes">
+ <return type="void">
+ </return>
+ <argument index="0" name="meshes" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_nodes">
+ <return type="void">
+ </return>
+ <argument index="0" name="nodes" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_skeleton_to_node">
+ <return type="void">
+ </return>
+ <argument index="0" name="skeleton_to_node" type="Dictionary">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_skeletons">
+ <return type="void">
+ </return>
+ <argument index="0" name="skeletons" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_skins">
+ <return type="void">
+ </return>
+ <argument index="0" name="skins" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_textures">
+ <return type="void">
+ </return>
+ <argument index="0" name="textures" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_unique_animation_names">
+ <return type="void">
+ </return>
+ <argument index="0" name="unique_animation_names" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_unique_names">
+ <return type="void">
+ </return>
+ <argument index="0" name="unique_names" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="buffers" type="Array" setter="set_buffers" getter="get_buffers" default="[ ]">
+ </member>
+ <member name="glb_data" type="PackedByteArray" setter="set_glb_data" getter="get_glb_data" default="PackedByteArray( )">
+ </member>
+ <member name="json" type="Dictionary" setter="set_json" getter="get_json" default="{}">
+ </member>
+ <member name="major_version" type="int" setter="set_major_version" getter="get_major_version" default="0">
+ </member>
+ <member name="minor_version" type="int" setter="set_minor_version" getter="get_minor_version" default="0">
+ </member>
+ <member name="root_nodes" type="Array" setter="set_root_nodes" getter="get_root_nodes" default="[ ]">
+ </member>
+ <member name="scene_name" type="String" setter="set_scene_name" getter="get_scene_name" default="&quot;&quot;">
+ </member>
+ <member name="use_named_skin_binds" type="bool" setter="set_use_named_skin_binds" getter="get_use_named_skin_binds" default="false">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GLTFTexture.xml b/doc/classes/GLTFTexture.xml
new file mode 100644
index 0000000000..be2210331f
--- /dev/null
+++ b/doc/classes/GLTFTexture.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GLTFTexture" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="src_image" type="int" setter="set_src_image" getter="get_src_image" default="195773152">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml
index c09151405a..ebe4e3b00d 100644
--- a/doc/classes/GPUParticles2D.xml
+++ b/doc/classes/GPUParticles2D.xml
@@ -71,7 +71,8 @@
Particle texture. If [code]null[/code], particles will be squares.
</member>
<member name="visibility_rect" type="Rect2" setter="set_visibility_rect" getter="get_visibility_rect" default="Rect2( -100, -100, 200, 200 )">
- Editor visibility helper.
+ The [Rect2] that determines the node's region which needs to be visible on screen for the particle system to be active.
+ Grow the rect if particles suddenly appear/disappear when the node enters/exits the screen. The [Rect2] can be grown via code or with the [b]Particles → Generate Visibility Rect[/b] editor tool.
</member>
</members>
<constants>
diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml
index d1296c3418..aea106af50 100644
--- a/doc/classes/GPUParticles3D.xml
+++ b/doc/classes/GPUParticles3D.xml
@@ -123,7 +123,8 @@
<member name="sub_emitter" type="NodePath" setter="set_sub_emitter" getter="get_sub_emitter" default="NodePath(&quot;&quot;)">
</member>
<member name="visibility_aabb" type="AABB" setter="set_visibility_aabb" getter="get_visibility_aabb" default="AABB( -4, -4, -4, 8, 8, 8 )">
- The [AABB] that determines the area of the world part of which needs to be visible on screen for the particle system to be active.
+ The [AABB] that determines the node's region which needs to be visible on screen for the particle system to be active.
+ Grow the box if particles suddenly appear/disappear when the node enters/exits the screen. The [AABB] can be grown via code or with the [b]Particles → Generate AABB[/b] editor tool.
</member>
</members>
<constants>
diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml
index cc85ce295b..631a30abab 100644
--- a/doc/classes/GeometryInstance3D.xml
+++ b/doc/classes/GeometryInstance3D.xml
@@ -48,6 +48,8 @@
</member>
<member name="gi_mode" type="int" setter="set_gi_mode" getter="get_gi_mode" enum="GeometryInstance3D.GIMode" default="0">
</member>
+ <member name="lod_bias" type="float" setter="set_lod_bias" getter="get_lod_bias" default="1.0">
+ </member>
<member name="lod_max_distance" type="float" setter="set_lod_max_distance" getter="get_lod_max_distance" default="0.0">
The GeometryInstance3D's max LOD distance.
[b]Note:[/b] This property currently has no effect.
diff --git a/doc/classes/Gradient.xml b/doc/classes/Gradient.xml
index 4ccbdee144..28c647a1c3 100644
--- a/doc/classes/Gradient.xml
+++ b/doc/classes/Gradient.xml
@@ -57,10 +57,10 @@
<method name="remove_point">
<return type="void">
</return>
- <argument index="0" name="offset" type="int">
+ <argument index="0" name="point" type="int">
</argument>
<description>
- Removes the color at the index [code]offset[/code].
+ Removes the color at the index [code]point[/code].
</description>
</method>
<method name="set_color">
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index c5884aa44a..10afa4c339 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -281,17 +281,17 @@
Emitted at the end of a GraphNode movement.
</description>
</signal>
- <signal name="node_selected">
+ <signal name="node_deselected">
<argument index="0" name="node" type="Node">
</argument>
<description>
- Emitted when a GraphNode is selected.
</description>
</signal>
- <signal name="node_unselected">
+ <signal name="node_selected">
<argument index="0" name="node" type="Node">
</argument>
<description>
+ Emitted when a GraphNode is selected.
</description>
</signal>
<signal name="paste_nodes_request">
diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml
index 4b0ea4dcb1..279c4c4c94 100644
--- a/doc/classes/GraphNode.xml
+++ b/doc/classes/GraphNode.xml
@@ -272,6 +272,13 @@
Emitted when the GraphNode is requested to be resized. Happens on dragging the resizer handle (see [member resizable]).
</description>
</signal>
+ <signal name="slot_updated">
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ Emitted when any GraphNode's slot is updated.
+ </description>
+ </signal>
</signals>
<constants>
<constant name="OVERLAY_DISABLED" value="0" enum="Overlay">
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index b6594aac39..9ff682f79d 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -175,7 +175,7 @@
var result = new HTTPClient().Request(HTTPClient.Method.Post, "index.php", headers, queryString);
[/csharp]
[/codeblocks]
- [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.http_escape] for an example.
+ [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.uri_encode] for an example.
</description>
</method>
<method name="request_raw">
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index f2ab93033a..a65f66c72a 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -203,7 +203,7 @@
<description>
Creates request on the underlying [HTTPClient]. If there is no configuration errors, it tries to connect using [method HTTPClient.connect_to_host] and passes parameters onto [method HTTPClient.request].
Returns [constant OK] if request is successfully created. (Does not imply that the server has responded), [constant ERR_UNCONFIGURED] if not in the tree, [constant ERR_BUSY] if still processing previous request, [constant ERR_INVALID_PARAMETER] if given string is not a valid URL format, or [constant ERR_CANT_CONNECT] if not using thread and the [HTTPClient] cannot connect to host.
- [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.http_escape] for an example.
+ [b]Note:[/b] The [code]request_data[/code] parameter is ignored if [code]method[/code] is [constant HTTPClient.METHOD_GET]. This is because GET methods can't contain request data. As a workaround, you can pass request data as a query string in the URL. See [method String.uri_encode] for an example.
</description>
</method>
<method name="request_raw">
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index 414249f110..bad8127c03 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -12,6 +12,18 @@
<link title="Importing images">https://docs.godotengine.org/en/latest/getting_started/workflow/assets/importing_images.html</link>
</tutorials>
<methods>
+ <method name="adjust_bcs">
+ <return type="void">
+ </return>
+ <argument index="0" name="brightness" type="float">
+ </argument>
+ <argument index="1" name="contrast" type="float">
+ </argument>
+ <argument index="2" name="saturation" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="blend_rect">
<return type="void">
</return>
@@ -68,13 +80,13 @@
Blits [code]src_rect[/code] area from [code]src[/code] image to this image at the coordinates given by [code]dst[/code]. [code]src[/code] pixel is copied onto [code]dst[/code] if the corresponding [code]mask[/code] pixel's alpha value is not 0. [code]src[/code] image and [code]mask[/code] image [b]must[/b] have the same size (width and height) but they can have different formats.
</description>
</method>
- <method name="bumpmap_to_normalmap">
+ <method name="bump_map_to_normal_map">
<return type="void">
</return>
<argument index="0" name="bump_scale" type="float" default="1.0">
</argument>
<description>
- Converts a bumpmap to a normalmap. A bumpmap provides a height offset per-pixel, while a normalmap provides a normal direction per pixel.
+ Converts a bump map to a normal map. A bump map provides a height offset per-pixel, while a normal map provides a normal direction per pixel.
</description>
</method>
<method name="clear_mipmaps">
@@ -398,11 +410,11 @@
Loads an image from the binary contents of a WebP file.
</description>
</method>
- <method name="normalmap_to_xy">
+ <method name="normal_map_to_xy">
<return type="void">
</return>
<description>
- Converts the image's data to represent coordinates on a 3D plane. This is used when the image represents a normalmap. A normalmap can add lots of detail to a 3D surface without increasing the polygon count.
+ Converts the image's data to represent coordinates on a 3D plane. This is used when the image represents a normal map. A normal map can add lots of detail to a 3D surface without increasing the polygon count.
</description>
</method>
<method name="premultiply_alpha">
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index cfb3e8d981..1f872db6c6 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -59,6 +59,8 @@
</return>
<argument index="0" name="action" type="StringName">
</argument>
+ <argument index="1" name="exact_match" type="bool" default="false">
+ </argument>
<description>
Returns a value between 0 and 1 representing the raw intensity of the given action, ignoring the action's deadzone. In most cases, you should use [method get_action_strength] instead.
</description>
@@ -68,6 +70,8 @@
</return>
<argument index="0" name="action" type="StringName">
</argument>
+ <argument index="1" name="exact_match" type="bool" default="false">
+ </argument>
<description>
Returns a value between 0 and 1 representing the intensity of the given action. In a joypad, for example, the further away the axis (analog sticks or L2, R2 triggers) is from the dead zone, the closer the value will be to 1. If the action is mapped to a control that has no axis as the keyboard, the value returned will be 0 or 1.
</description>
@@ -214,6 +218,8 @@
</return>
<argument index="0" name="action" type="StringName">
</argument>
+ <argument index="1" name="exact_match" type="bool" default="false">
+ </argument>
<description>
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 the button.
This is useful for code that needs to run only once when an action is pressed, instead of every frame while it's pressed.
@@ -224,6 +230,8 @@
</return>
<argument index="0" name="action" type="StringName">
</argument>
+ <argument index="1" name="exact_match" type="bool" default="false">
+ </argument>
<description>
Returns [code]true[/code] when the user stops pressing the action event, meaning it's [code]true[/code] only on the frame that the user released the button.
</description>
@@ -233,6 +241,8 @@
</return>
<argument index="0" name="action" type="StringName">
</argument>
+ <argument index="1" name="exact_match" type="bool" default="false">
+ </argument>
<description>
Returns [code]true[/code] if you are pressing the action event. Note that if an action has multiple buttons assigned and more than one of them is pressed, releasing one button will release the action, even if some other button assigned to this action is still pressed.
</description>
diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml
index 8c6063bd67..28c4773f51 100644
--- a/doc/classes/InputEvent.xml
+++ b/doc/classes/InputEvent.xml
@@ -35,6 +35,8 @@
</return>
<argument index="0" name="action" type="StringName">
</argument>
+ <argument index="1" name="exact_match" type="bool" default="false">
+ </argument>
<description>
Returns a value between 0.0 and 1.0 depending on the given actions' state. Useful for getting the value of events of type [InputEventJoypadMotion].
</description>
@@ -44,6 +46,8 @@
</return>
<argument index="0" name="action" type="StringName">
</argument>
+ <argument index="1" name="exact_match" type="bool" default="false">
+ </argument>
<description>
Returns [code]true[/code] if this input event matches a pre-defined action of any type.
</description>
@@ -55,6 +59,8 @@
</argument>
<argument index="1" name="allow_echo" type="bool" default="false">
</argument>
+ <argument index="2" name="exact_match" type="bool" default="false">
+ </argument>
<description>
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 [code]true[/code]). Not relevant for events of type [InputEventMouseMotion] or [InputEventScreenDrag].
</description>
@@ -64,6 +70,8 @@
</return>
<argument index="0" name="action" type="StringName">
</argument>
+ <argument index="1" name="exact_match" type="bool" default="false">
+ </argument>
<description>
Returns [code]true[/code] if the given action is released (i.e. not pressed). Not relevant for events of type [InputEventMouseMotion] or [InputEventScreenDrag].
</description>
diff --git a/doc/classes/InputMap.xml b/doc/classes/InputMap.xml
index 49d29b3a53..0fb18d8e81 100644
--- a/doc/classes/InputMap.xml
+++ b/doc/classes/InputMap.xml
@@ -100,6 +100,8 @@
</argument>
<argument index="1" name="action" type="StringName">
</argument>
+ <argument index="2" name="exact_match" type="bool" default="false">
+ </argument>
<description>
Returns [code]true[/code] if the given event is part of an existing action. This method ignores keyboard modifiers if the given [InputEvent] is not pressed (for proper release detection). See [method action_has_event] if you don't want this behavior.
</description>
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index 0fd0fe7b3d..0020cbf242 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -12,18 +12,18 @@
</tutorials>
<methods>
<method name="add_icon_item">
- <return type="void">
+ <return type="int">
</return>
<argument index="0" name="icon" type="Texture2D">
</argument>
<argument index="1" name="selectable" type="bool" default="true">
</argument>
<description>
- Adds an item to the item list with no text, only an icon.
+ Adds an item to the item list with no text, only an icon. Returns the index of an added item.
</description>
</method>
<method name="add_item">
- <return type="void">
+ <return type="int">
</return>
<argument index="0" name="text" type="String">
</argument>
@@ -32,7 +32,8 @@
<argument index="2" name="selectable" type="bool" default="true">
</argument>
<description>
- Adds an item to the item list with specified text. Specify an [code]icon[/code], or use [code]null[/code] as the [code]icon[/code] for a list item with no icon.
+ Adds an item to the item list with specified text. Returns the index of an added item.
+ Specify an [code]icon[/code], or use [code]null[/code] as the [code]icon[/code] for a list item with no icon.
If selectable is [code]true[/code], the list item will be selectable.
</description>
</method>
@@ -52,6 +53,22 @@
Removes all OpenType features from the item's text.
</description>
</method>
+ <method name="deselect">
+ <return type="void">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ Ensures the item associated with the specified index is not selected.
+ </description>
+ </method>
+ <method name="deselect_all">
+ <return type="void">
+ </return>
+ <description>
+ Ensures there are no items selected.
+ </description>
+ </method>
<method name="ensure_current_is_visible">
<return type="void">
</return>
@@ -285,16 +302,7 @@
<argument index="1" name="custom_bg_color" type="Color">
</argument>
<description>
- [codeblocks]
- [gdscript]
- var itemList = ItemList.new()
- some_string.set_item_custom_bg_color(0, Color.red) # This will set the background color of the first item of the control to red.
- [/gdscript]
- [csharp]
- var itemList = new ItemList();
- itemList.SetItemCustomBgColor(0, Colors.Red); // This will set the background color of the first item of the control to red.
- [/csharp]
- [/codeblocks]
+ Sets the background color of the item specified by [code]idx[/code] index to the specified [Color].
</description>
</method>
<method name="set_item_custom_fg_color">
@@ -306,16 +314,6 @@
</argument>
<description>
Sets the foreground color of the item specified by [code]idx[/code] index to the specified [Color].
- [codeblocks]
- [gdscript]
- var item_list = ItemList.new()
- item_list.set_item_custom_fg_color(0, Color.red) # This will set the foreground color of the first item of the control to red.
- [/gdscript]
- [csharp]
- var itemList = new ItemList();
- itemList.SetItemCustomFgColor(0, Colors.Red); // This will set the foreground color of the first item of the control to red.
- [/csharp]
- [/codeblocks]
</description>
</method>
<method name="set_item_disabled">
@@ -471,22 +469,6 @@
Sorts items in the list by their text.
</description>
</method>
- <method name="unselect">
- <return type="void">
- </return>
- <argument index="0" name="idx" type="int">
- </argument>
- <description>
- Ensures the item associated with the specified index is not selected.
- </description>
- </method>
- <method name="unselect_all">
- <return type="void">
- </return>
- <description>
- Ensures there are no items selected.
- </description>
- </method>
</methods>
<members>
<member name="allow_reselect" type="bool" setter="set_allow_reselect" getter="get_allow_reselect" default="false">
@@ -614,7 +596,10 @@
<theme_item name="font_color" type="Color" default="Color( 0.63, 0.63, 0.63, 1 )">
Default text [Color] of the item.
</theme_item>
- <theme_item name="font_color_selected" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the item.
+ </theme_item>
+ <theme_item name="font_selected_color" type="Color" default="Color( 1, 1, 1, 1 )">
Text [Color] used when the item is selected.
</theme_item>
<theme_item name="font_size" type="int">
@@ -632,6 +617,9 @@
<theme_item name="line_separation" type="int" default="2">
The vertical spacing between each line of text.
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the item text outline.
+ </theme_item>
<theme_item name="selected" type="StyleBox">
[StyleBox] for the selected items, used when the [ItemList] is not being focused.
</theme_item>
diff --git a/doc/classes/JSONParseResult.xml b/doc/classes/JSONParseResult.xml
index 991ebcd7a0..bc94f74b07 100644
--- a/doc/classes/JSONParseResult.xml
+++ b/doc/classes/JSONParseResult.xml
@@ -21,7 +21,7 @@
The error message if the JSON source was not successfully parsed. See the [enum Error] constants.
</member>
<member name="result" type="Variant" setter="set_result" getter="get_result">
- A [Variant] containing the parsed JSON. Use [method @GDScript.typeof] or the [code]is[/code] keyword to check if it is what you expect. For example, if the JSON source starts with curly braces ([code]{}[/code]), a [Dictionary] will be returned. If the JSON source starts with brackets ([code][][/code]), an [Array] will be returned.
+ A [Variant] containing the parsed JSON. Use [method @GlobalScope.typeof] or the [code]is[/code] keyword to check if it is what you expect. For example, if the JSON source starts with curly braces ([code]{}[/code]), a [Dictionary] will be returned. If the JSON source starts with brackets ([code][][/code]), an [Array] will be returned.
[b]Note:[/b] The JSON specification does not define integer or float types, but only a [i]number[/i] type. Therefore, parsing a JSON text will convert all numerical values to [float] types.
[b]Note:[/b] JSON objects do not preserve key order like Godot dictionaries, thus, you should not rely on keys being in a certain order if a dictionary is constructed from JSON. In contrast, JSON arrays retain the order of their elements:
[codeblocks]
diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml
index 1edf31de4a..8574ff9836 100644
--- a/doc/classes/Label.xml
+++ b/doc/classes/Label.xml
@@ -150,12 +150,12 @@
<theme_item name="font_color" type="Color" default="Color( 1, 1, 1, 1 )">
Default text [Color] of the [Label].
</theme_item>
- <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 0 )">
- [Color] of the text's shadow effect.
- </theme_item>
- <theme_item name="font_outline_modulate" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
The tint of [Font]'s outline.
</theme_item>
+ <theme_item name="font_shadow_color" type="Color" default="Color( 0, 0, 0, 0 )">
+ [Color] of the text's shadow effect.
+ </theme_item>
<theme_item name="font_size" type="int">
Font size of the [Label]'s text.
</theme_item>
diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml
index 6c008e4f7e..111473e098 100644
--- a/doc/classes/Light3D.xml
+++ b/doc/classes/Light3D.xml
@@ -78,7 +78,7 @@
<member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false">
If [code]true[/code], the light will cast shadows.
</member>
- <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="1.0">
+ <member name="shadow_fog_fade" type="float" setter="set_param" getter="get_param" default="0.1">
</member>
<member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="2.0">
Offsets the lookup into the shadow map by the object's normal. This can be used to reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible.
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index f05121d48c..360f5c451e 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -380,21 +380,27 @@
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
Default font color.
</theme_item>
- <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )">
- Font color for selected text (inside the selection rectangle).
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [LineEdit].
</theme_item>
- <theme_item name="font_color_uneditable" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
- Font color when editing is disabled.
+ <theme_item name="font_selected_color" type="Color" default="Color( 0, 0, 0, 1 )">
+ Font color for selected text (inside the selection rectangle).
</theme_item>
<theme_item name="font_size" type="int">
Font size of the [LineEdit]'s text.
</theme_item>
- <theme_item name="minimum_spaces" type="int" default="12">
- Minimum horizontal space for the text (not counting the clear button and content margins). This value is measured in count of space characters (i.e. this amount of space characters can be displayed without scrolling).
+ <theme_item name="font_uneditable_color" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
+ Font color when editing is disabled.
+ </theme_item>
+ <theme_item name="minimum_character_width" type="int" default="4">
+ Minimum horizontal space for the text (not counting the clear button and content margins). This value is measured in count of 'M' characters (i.e. this amount of 'M' characters can be displayed without scrolling).
</theme_item>
<theme_item name="normal" type="StyleBox">
Default background for the [LineEdit].
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="read_only" type="StyleBox">
Background used when [LineEdit] is in read-only mode ([member editable] is set to [code]false[/code]).
</theme_item>
diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml
index 93384843de..6e2f4399b3 100644
--- a/doc/classes/LinkButton.xml
+++ b/doc/classes/LinkButton.xml
@@ -81,15 +81,21 @@
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
Default text [Color] of the [LinkButton].
</theme_item>
- <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
Text [Color] used when the [LinkButton] is being hovered.
</theme_item>
- <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [LinkButton].
+ </theme_item>
+ <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
Text [Color] used when the [LinkButton] is being pressed.
</theme_item>
<theme_item name="font_size" type="int">
Font size of the [LinkButton]'s text.
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="underline_spacing" type="int" default="2">
The vertical space between the baseline of text and the underline.
</theme_item>
diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml
index 7682379b64..537ecf2b2b 100644
--- a/doc/classes/MainLoop.xml
+++ b/doc/classes/MainLoop.xml
@@ -19,7 +19,7 @@
print("Initialized:")
print(" Starting time: %s" % str(time_elapsed))
- func _idle(delta):
+ func _process(delta):
time_elapsed += delta
# Return true to end the main loop.
return quit
@@ -51,30 +51,30 @@
Called before the program exits.
</description>
</method>
- <method name="_idle" qualifiers="virtual">
- <return type="bool">
+ <method name="_initialize" qualifiers="virtual">
+ <return type="void">
</return>
- <argument index="0" name="delta" type="float">
- </argument>
<description>
- Called each idle frame with the time since the last idle frame as argument (in seconds). Equivalent to [method Node._process].
- If implemented, the method must return a boolean value. [code]true[/code] ends the main loop, while [code]false[/code] lets it proceed to the next frame.
+ Called once during initialization.
</description>
</method>
- <method name="_initialize" qualifiers="virtual">
- <return type="void">
+ <method name="_physics_process" qualifiers="virtual">
+ <return type="bool">
</return>
+ <argument index="0" name="delta" type="float">
+ </argument>
<description>
- Called once during initialization.
+ Called each physics frame with the time since the last physics frame as argument ([code]delta[/code], in seconds). Equivalent to [method Node._physics_process].
+ If implemented, the method must return a boolean value. [code]true[/code] ends the main loop, while [code]false[/code] lets it proceed to the next frame.
</description>
</method>
- <method name="_iteration" qualifiers="virtual">
+ <method name="_process" qualifiers="virtual">
<return type="bool">
</return>
<argument index="0" name="delta" type="float">
</argument>
<description>
- Called each physics frame with the time since the last physics frame as argument (in seconds). Equivalent to [method Node._physics_process].
+ Called each process (idle) frame with the time since the last process frame as argument (in seconds). Equivalent to [method Node._process].
If implemented, the method must return a boolean value. [code]true[/code] ends the main loop, while [code]false[/code] lets it proceed to the next frame.
</description>
</method>
diff --git a/doc/classes/MarginContainer.xml b/doc/classes/MarginContainer.xml
index c8eebd4677..a51632d5f1 100644
--- a/doc/classes/MarginContainer.xml
+++ b/doc/classes/MarginContainer.xml
@@ -5,21 +5,23 @@
</brief_description>
<description>
Adds a top, left, bottom, and right margin to all [Control] nodes that are direct children of the container. To control the [MarginContainer]'s margin, use the [code]margin_*[/code] theme properties listed below.
- [b]Note:[/b] Be careful, [Control] margin values are different than the constant margin values. If you want to change the custom margin values of the [MarginContainer] by code, you should use the following examples:
+ [b]Note:[/b] Be careful, [Control] margin values are different from the constant margin values. If you want to change the custom margin values of the [MarginContainer] by code, you should use the following examples:
[codeblocks]
[gdscript]
+ # This code sample assumes the current script is extending MarginContainer.
var margin_value = 100
- set("custom_constants/margin_top", margin_value)
- set("custom_constants/margin_left", margin_value)
- set("custom_constants/margin_bottom", margin_value)
- set("custom_constants/margin_right", margin_value)
+ add_theme_constant_override("margin_top", margin_value)
+ add_theme_constant_override("margin_left", margin_value)
+ add_theme_constant_override("margin_bottom", margin_value)
+ add_theme_constant_override("margin_right", margin_value)
[/gdscript]
[csharp]
+ // This code sample assumes the current script is extending MarginContainer.
int marginValue = 100;
- Set("custom_constants/margin_top", marginValue);
- Set("custom_constants/margin_left", marginValue);
- Set("custom_constants/margin_bottom", marginValue);
- Set("custom_constants/margin_right", marginValue);
+ AddThemeConstantOverride("margin_top", marginValue);
+ AddThemeConstantOverride("margin_left", marginValue);
+ AddThemeConstantOverride("margin_bottom", marginValue);
+ AddThemeConstantOverride("margin_right", marginValue);
[/csharp]
[/codeblocks]
</description>
diff --git a/doc/classes/Material.xml b/doc/classes/Material.xml
index 10a7061bef..0d287a5d1d 100644
--- a/doc/classes/Material.xml
+++ b/doc/classes/Material.xml
@@ -11,6 +11,12 @@
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
</tutorials>
<methods>
+ <method name="inspect_native_shader_code">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="next_pass" type="Material" setter="set_next_pass" getter="get_next_pass">
diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml
index a002ce636b..481b737eee 100644
--- a/doc/classes/MenuButton.xml
+++ b/doc/classes/MenuButton.xml
@@ -59,13 +59,16 @@
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
Default text [Color] of the [MenuButton].
</theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 1, 1, 1, 0.3 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 1, 1, 1, 0.3 )">
Text [Color] used when the [MenuButton] is disabled.
</theme_item>
- <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
Text [Color] used when the [MenuButton] is being hovered.
</theme_item>
- <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [MenuButton].
+ </theme_item>
+ <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
Text [Color] used when the [MenuButton] is being pressed.
</theme_item>
<theme_item name="font_size" type="int">
@@ -80,6 +83,9 @@
<theme_item name="normal" type="StyleBox">
Default [StyleBox] for the [MenuButton].
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="pressed" type="StyleBox">
[StyleBox] used when the [MenuButton] is being pressed.
</theme_item>
diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml
index dff4b4f7ab..ed7c39d4d9 100644
--- a/doc/classes/Mesh.xml
+++ b/doc/classes/Mesh.xml
@@ -242,5 +242,11 @@
</constant>
<constant name="ARRAY_FLAG_USE_8_BONE_WEIGHTS" value="134217728" enum="ArrayFormat">
</constant>
+ <constant name="BLEND_SHAPE_MODE_NORMALIZED" value="0" enum="BlendShapeMode">
+ Blend shapes are normalized.
+ </constant>
+ <constant name="BLEND_SHAPE_MODE_RELATIVE" value="1" enum="BlendShapeMode">
+ Blend shapes are relative to base weight.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml
index fcc259fb44..c168695d61 100644
--- a/doc/classes/MultiplayerAPI.xml
+++ b/doc/classes/MultiplayerAPI.xml
@@ -4,9 +4,10 @@
High-level multiplayer API.
</brief_description>
<description>
- This class implements most of the logic behind the high-level multiplayer API.
+ This class implements most of the logic behind the high-level multiplayer API. See also [NetworkedMultiplayerPeer].
By default, [SceneTree] has a reference to this class that is used to provide multiplayer capabilities (i.e. RPC/RSET) across the whole scene.
It is possible to override the MultiplayerAPI instance used by specific Nodes by setting the [member Node.custom_multiplayer] property, effectively allowing to run both client and server in the same scene.
+ [b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Navigation2D.xml b/doc/classes/Navigation2D.xml
deleted file mode 100644
index abac29bdb7..0000000000
--- a/doc/classes/Navigation2D.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="Navigation2D" inherits="Node2D" version="4.0">
- <brief_description>
- 2D navigation and pathfinding node.
- </brief_description>
- <description>
- Navigation2D provides navigation and pathfinding within a 2D area, specified as a collection of [NavigationPolygon] resources. These are automatically collected from child [NavigationRegion2D] nodes.
- </description>
- <tutorials>
- <link title="2D Navigation Demo">https://godotengine.org/asset-library/asset/117</link>
- </tutorials>
- <methods>
- <method name="get_closest_point" qualifiers="const">
- <return type="Vector2">
- </return>
- <argument index="0" name="to_point" type="Vector2">
- </argument>
- <description>
- Returns the point closest to the provided [code]to_point[/code] on the navigation mesh surface.
- </description>
- </method>
- <method name="get_closest_point_owner" qualifiers="const">
- <return type="RID">
- </return>
- <argument index="0" name="to_point" type="Vector2">
- </argument>
- <description>
- Returns the owner region RID for the point returned by [method get_closest_point].
- </description>
- </method>
- <method name="get_rid" qualifiers="const">
- <return type="RID">
- </return>
- <description>
- </description>
- </method>
- <method name="get_simple_path" qualifiers="const">
- <return type="PackedVector2Array">
- </return>
- <argument index="0" name="start" type="Vector2">
- </argument>
- <argument index="1" name="end" type="Vector2">
- </argument>
- <argument index="2" name="optimize" type="bool" default="true">
- </argument>
- <description>
- 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.
- </description>
- </method>
- </methods>
- <members>
- <member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size" default="10.0">
- </member>
- <member name="edge_connection_margin" type="float" setter="set_edge_connection_margin" getter="get_edge_connection_margin" default="100.0">
- </member>
- </members>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/Navigation3D.xml b/doc/classes/Navigation3D.xml
deleted file mode 100644
index e7a4fe3c43..0000000000
--- a/doc/classes/Navigation3D.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="Navigation3D" inherits="Node3D" version="4.0">
- <brief_description>
- Mesh-based navigation and pathfinding node.
- </brief_description>
- <description>
- Provides navigation and pathfinding within a collection of [NavigationMesh]es. These will be automatically collected from child [NavigationRegion3D] nodes. In addition to basic pathfinding, this class also assists with aligning navigation agents with the meshes they are navigating on.
- </description>
- <tutorials>
- <link title="3D Navmesh Demo">https://godotengine.org/asset-library/asset/124</link>
- </tutorials>
- <methods>
- <method name="get_closest_point" qualifiers="const">
- <return type="Vector3">
- </return>
- <argument index="0" name="to_point" type="Vector3">
- </argument>
- <description>
- Returns the point closest to the provided [code]to_point[/code] on the navigation mesh surface.
- </description>
- </method>
- <method name="get_closest_point_normal" qualifiers="const">
- <return type="Vector3">
- </return>
- <argument index="0" name="to_point" type="Vector3">
- </argument>
- <description>
- Returns the normal for the point returned by [method get_closest_point].
- </description>
- </method>
- <method name="get_closest_point_owner" qualifiers="const">
- <return type="RID">
- </return>
- <argument index="0" name="to_point" type="Vector3">
- </argument>
- <description>
- Returns the owner region RID for the point returned by [method get_closest_point].
- </description>
- </method>
- <method name="get_closest_point_to_segment" qualifiers="const">
- <return type="Vector3">
- </return>
- <argument index="0" name="start" type="Vector3">
- </argument>
- <argument index="1" name="end" type="Vector3">
- </argument>
- <argument index="2" name="use_collision" type="bool" default="false">
- </argument>
- <description>
- Returns the closest point between the navigation surface and the segment.
- </description>
- </method>
- <method name="get_rid" qualifiers="const">
- <return type="RID">
- </return>
- <description>
- </description>
- </method>
- <method name="get_simple_path" qualifiers="const">
- <return type="PackedVector3Array">
- </return>
- <argument index="0" name="start" type="Vector3">
- </argument>
- <argument index="1" name="end" type="Vector3">
- </argument>
- <argument index="2" name="optimize" type="bool" default="true">
- </argument>
- <description>
- 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.
- </description>
- </method>
- </methods>
- <members>
- <member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size" default="0.3">
- </member>
- <member name="edge_connection_margin" type="float" setter="set_edge_connection_margin" getter="get_edge_connection_margin" default="5.0">
- </member>
- <member name="up_vector" type="Vector3" setter="set_up_vector" getter="get_up_vector" default="Vector3( 0, 1, 0 )">
- Defines which direction is up. By default, this is [code](0, 1, 0)[/code], which is the world's "up" direction.
- </member>
- </members>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index 5a9c31ef67..59bf06eaf2 100644
--- a/doc/classes/NavigationAgent2D.xml
+++ b/doc/classes/NavigationAgent2D.xml
@@ -4,7 +4,7 @@
2D Agent used in navigation for collision avoidance.
</brief_description>
<description>
- 2D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. This can be done by having the agent as a child of a [Navigation2D] node, or using [method set_navigation]. [NavigationAgent2D] is physics safe.
+ 2D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. [NavigationAgent2D] is physics safe.
</description>
<tutorials>
</tutorials>
@@ -37,13 +37,6 @@
Returns which index the agent is currently on in the navigation path's [PackedVector2Array].
</description>
</method>
- <method name="get_navigation" qualifiers="const">
- <return type="Node">
- </return>
- <description>
- Returns the [Navigation2D] node that the agent is using for its navigation system.
- </description>
- </method>
<method name="get_next_location">
<return type="Vector2">
</return>
@@ -79,15 +72,6 @@
Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location].
</description>
</method>
- <method name="set_navigation">
- <return type="void">
- </return>
- <argument index="0" name="navigation" type="Node">
- </argument>
- <description>
- Sets the [Navigation2D] node used by the agent. Useful when you don't want to make the agent a child of a [Navigation2D] node.
- </description>
- </method>
<method name="set_target_location">
<return type="void">
</return>
diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml
index f9df1d390b..7a130e9591 100644
--- a/doc/classes/NavigationAgent3D.xml
+++ b/doc/classes/NavigationAgent3D.xml
@@ -4,7 +4,7 @@
3D Agent used in navigation for collision avoidance.
</brief_description>
<description>
- 3D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. This can be done by having the agent as a child of a [Navigation3D] node, or using [method set_navigation]. [NavigationAgent3D] is physics safe.
+ 3D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. [NavigationAgent3D] is physics safe.
</description>
<tutorials>
</tutorials>
@@ -37,13 +37,6 @@
Returns which index the agent is currently on in the navigation path's [PackedVector3Array].
</description>
</method>
- <method name="get_navigation" qualifiers="const">
- <return type="Node">
- </return>
- <description>
- Returns the [Navigation3D] node that the agent is using for its navigation system.
- </description>
- </method>
<method name="get_next_location">
<return type="Vector3">
</return>
@@ -79,15 +72,6 @@
Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location].
</description>
</method>
- <method name="set_navigation">
- <return type="void">
- </return>
- <argument index="0" name="navigation" type="Node">
- </argument>
- <description>
- Sets the [Navigation3D] node used by the agent. Useful when you don't want to make the agent a child of a [Navigation3D] node.
- </description>
- </method>
<method name="set_target_location">
<return type="void">
</return>
diff --git a/doc/classes/NavigationObstacle2D.xml b/doc/classes/NavigationObstacle2D.xml
index ddd96975f1..2e94eb0bba 100644
--- a/doc/classes/NavigationObstacle2D.xml
+++ b/doc/classes/NavigationObstacle2D.xml
@@ -4,27 +4,11 @@
2D Obstacle used in navigation for collision avoidance.
</brief_description>
<description>
- 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]. [NavigationObstacle2D] is physics safe.
+ 2D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. [NavigationObstacle2D] is physics safe.
</description>
<tutorials>
</tutorials>
<methods>
- <method name="get_navigation" qualifiers="const">
- <return type="Node">
- </return>
- <description>
- Returns the [Navigation2D] node that the obstacle is using for its navigation system.
- </description>
- </method>
- <method name="set_navigation">
- <return type="void">
- </return>
- <argument index="0" name="navigation" type="Node">
- </argument>
- <description>
- Sets the [Navigation2D] node used by the obstacle. Useful when you don't want to make the obstacle a child of a [Navigation2D] node.
- </description>
- </method>
</methods>
<constants>
</constants>
diff --git a/doc/classes/NavigationObstacle3D.xml b/doc/classes/NavigationObstacle3D.xml
index e01a40ed73..d7454a7bea 100644
--- a/doc/classes/NavigationObstacle3D.xml
+++ b/doc/classes/NavigationObstacle3D.xml
@@ -4,27 +4,11 @@
3D Obstacle used in navigation for collision avoidance.
</brief_description>
<description>
- 3D 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 [Navigation3D] node, or using [method set_navigation]. [NavigationObstacle3D] is physics safe.
+ 3D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. [NavigationObstacle3D] is physics safe.
</description>
<tutorials>
</tutorials>
<methods>
- <method name="get_navigation" qualifiers="const">
- <return type="Node">
- </return>
- <description>
- Returns the [Navigation3D] node that the obstacle is using for its navigation system.
- </description>
- </method>
- <method name="set_navigation">
- <return type="void">
- </return>
- <argument index="0" name="navigation" type="Node">
- </argument>
- <description>
- Sets the [Navigation3D] node used by the obstacle. Useful when you don't want to make the obstacle a child of a [Navigation3D] node.
- </description>
- </method>
</methods>
<constants>
</constants>
diff --git a/doc/classes/NavigationRegion2D.xml b/doc/classes/NavigationRegion2D.xml
index aef114e1db..33a3f04c3d 100644
--- a/doc/classes/NavigationRegion2D.xml
+++ b/doc/classes/NavigationRegion2D.xml
@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NavigationRegion2D" inherits="Node2D" version="4.0">
<brief_description>
+ A region of the 2D navigation map.
</brief_description>
<description>
+ A region of the navigation map. It tells the [NavigationServer2D] what can be navigated and what cannot, based on its [NavigationPolygon] resource.
+ Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer2D.map_set_edge_connection_margin].
+ [b]Note:[/b] Overlapping two regions' polygons is not enough for connecting two regions. They must share a similar edge.
</description>
<tutorials>
</tutorials>
@@ -10,8 +14,13 @@
</methods>
<members>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
+ Determines if the [NavigationRegion2D] is enabled or disabled.
+ </member>
+ <member name="layers" type="int" setter="set_layers" getter="get_layers" default="1">
+ A bitfield determining all layers the region belongs to. These layers can be checked upon when requesting a path with [method NavigationServer2D.map_get_path].
</member>
<member name="navpoly" type="NavigationPolygon" setter="set_navigation_polygon" getter="get_navigation_polygon">
+ The [NavigationPolygon] resource to use.
</member>
</members>
<constants>
diff --git a/doc/classes/NavigationRegion3D.xml b/doc/classes/NavigationRegion3D.xml
index b70bfb6596..2904ba4200 100644
--- a/doc/classes/NavigationRegion3D.xml
+++ b/doc/classes/NavigationRegion3D.xml
@@ -4,7 +4,8 @@
A region of the navigation map.
</brief_description>
<description>
- A region of the navigation map. It tells the [Navigation3D] node what can be navigated and what cannot, based on the [NavigationMesh] resource. This should be a child of a [Navigation3D] node (even not a direct child).
+ A region of the navigation map. It tells the [NavigationServer3D] what can be navigated and what cannot, based on its [NavigationMesh] resource.
+ Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer3D.map_set_edge_connection_margin].
</description>
<tutorials>
</tutorials>
@@ -21,6 +22,9 @@
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
Determines if the [NavigationRegion3D] is enabled or disabled.
</member>
+ <member name="layers" type="int" setter="set_layers" getter="get_layers" default="1">
+ A bitfield determining all layers the region belongs to. These layers can be checked upon when requesting a path with [method NavigationServer3D.map_get_path].
+ </member>
<member name="navmesh" type="NavigationMesh" setter="set_navigation_mesh" getter="get_navigation_mesh">
The [NavigationMesh] resource to use.
</member>
diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml
index 5f0b04487e..4f34a8a424 100644
--- a/doc/classes/NavigationServer2D.xml
+++ b/doc/classes/NavigationServer2D.xml
@@ -4,7 +4,12 @@
Server interface for low-level 2D navigation access
</brief_description>
<description>
- NavigationServer2D is the server responsible for all 2D navigation. It creates the agents, maps, and regions for navigation to work as expected. This keeps tracks of any call and executes them during the sync phase. This means that you can request any change to the map, using any thread, without worrying.
+ NavigationServer2D is the server responsible for all 2D navigation. It handles several objects, namely maps, regions and agents.
+ Maps are made up of regions, which are made of navigation polygons. Together, they define the navigable areas in the 2D world. For two regions to be connected to each other, they must share a similar edge. An edges is considered connected to another if both of its two vertices are at a distance less than [code]edge_connection_margin[/code] to the respective other edge's vertex.
+ You may assign navigation layers to regions with [method NavigationServer2D.region_set_layers], which then can be checked upon when requesting a path with [method NavigationServer2D.map_get_path]. This allows allowing or forbidding some areas to 2D objects.
+ To use the collision avoidance system, you may use agents. You can set an agent's target velocity, then the servers will emit a callback with a modified velocity.
+ [b]Note:[/b] the collision avoidance system ignores regions. Using the modified velocity as-is might lead to pushing and agent outside of a navigable area. This is a limitation of the collision avoidance system, any more complex situation may require the use of the physics engine.
+ This server keeps tracks of any call and executes them during the sync phase. This means that you can request any change to the map, using any thread, without worrying.
</description>
<tutorials>
<link title="2D Navigation Demo">https://godotengine.org/asset-library/asset/117</link>
@@ -207,8 +212,10 @@
</argument>
<argument index="3" name="optimize" type="bool">
</argument>
+ <argument index="4" name="layers" type="int" default="1">
+ </argument>
<description>
- Returns the navigation path to reach the destination from the origin, while avoiding static obstacles.
+ Returns the navigation path to reach the destination from the origin. [code]layers[/code] is a bitmask of all region layers that are allowed to be in the path.
</description>
</method>
<method name="map_is_active" qualifiers="const">
@@ -260,6 +267,26 @@
Creates a new region.
</description>
</method>
+ <method name="region_get_layers" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="region" type="RID">
+ </argument>
+ <description>
+ Returns the region's layers.
+ </description>
+ </method>
+ <method name="region_set_layers" qualifiers="const">
+ <return type="void">
+ </return>
+ <argument index="0" name="region" type="RID">
+ </argument>
+ <argument index="1" name="layers" type="int">
+ </argument>
+ <description>
+ Set the region's layers. This allows selecting regions from a path request (when using [method NavigationServer2D.map_get_path]).
+ </description>
+ </method>
<method name="region_set_map" qualifiers="const">
<return type="void">
</return>
diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml
index 95890c4b4c..0653c0d27d 100644
--- a/doc/classes/NavigationServer3D.xml
+++ b/doc/classes/NavigationServer3D.xml
@@ -4,7 +4,12 @@
Server interface for low-level 3D navigation access
</brief_description>
<description>
- NavigationServer3D is the server responsible for all 3D navigation. It creates the agents, maps, and regions for navigation to work as expected. This keeps tracks of any call and executes them during the sync phase. This means that you can request any change to the map, using any thread, without worrying.
+ NavigationServer3D is the server responsible for all 3D navigation. It handles several objects, namely maps, regions and agents.
+ Maps are made up of regions, which are made of navigation meshes. Together, they define the navigable areas in the 3D world. For two regions to be connected to each other, they must share a similar edge. An edges is considered connected to another if both of its two vertices are at a distance less than [code]edge_connection_margin[/code] to the respective other edge's vertex.
+ You may assign navigation layers to regions with [method NavigationServer3D.region_set_layers], which then can be checked upon when requesting a path with [method NavigationServer3D.map_get_path]. This allows allowing or forbidding some areas to 3D objects.
+ To use the collision avoidance system, you may use agents. You can set an agent's target velocity, then the servers will emit a callback with a modified velocity.
+ [b]Note:[/b] the collision avoidance system ignores regions. Using the modified velocity as-is might lead to pushing and agent outside of a navigable area. This is a limitation of the collision avoidance system, any more complex situation may require the use of the physics engine.
+ This server keeps tracks of any call and executes them during the sync phase. This means that you can request any change to the map, using any thread, without worrying.
</description>
<tutorials>
<link title="3D Navmesh Demo">https://godotengine.org/asset-library/asset/124</link>
@@ -219,7 +224,7 @@
<argument index="0" name="map" type="RID">
</argument>
<description>
- Returns the edge connection margin of the map.
+ Returns the edge connection margin of the map. This distance is the minimum vertex distance needed to connect two edges from different regions.
</description>
</method>
<method name="map_get_path" qualifiers="const">
@@ -233,8 +238,10 @@
</argument>
<argument index="3" name="optimize" type="bool">
</argument>
+ <argument index="4" name="layers" type="int" default="1">
+ </argument>
<description>
- Returns the navigation path to reach the destination from the origin.
+ Returns the navigation path to reach the destination from the origin. [code]layers[/code] is a bitmask of all region layers that are allowed to be in the path.
</description>
</method>
<method name="map_get_up" qualifiers="const">
@@ -285,7 +292,7 @@
<argument index="1" name="margin" type="float">
</argument>
<description>
- Set the map edge connection margein used to weld the compatible region edges.
+ Set the map edge connection margin used to weld the compatible region edges.
</description>
</method>
<method name="map_set_up" qualifiers="const">
@@ -328,6 +335,26 @@
Creates a new region.
</description>
</method>
+ <method name="region_get_layers" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="region" type="RID">
+ </argument>
+ <description>
+ Returns the region's layers.
+ </description>
+ </method>
+ <method name="region_set_layers" qualifiers="const">
+ <return type="void">
+ </return>
+ <argument index="0" name="region" type="RID">
+ </argument>
+ <argument index="1" name="layers" type="int">
+ </argument>
+ <description>
+ Set the region's layers. This allows selecting regions from a path request (when using [method NavigationServer3D.map_get_path]).
+ </description>
+ </method>
<method name="region_set_map" qualifiers="const">
<return type="void">
</return>
diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/NetworkedMultiplayerPeer.xml
index 954d31794a..06ea46f023 100644
--- a/doc/classes/NetworkedMultiplayerPeer.xml
+++ b/doc/classes/NetworkedMultiplayerPeer.xml
@@ -4,7 +4,8 @@
A high-level network interface to simplify multiplayer interactions.
</brief_description>
<description>
- Manages the connection to network peers. Assigns unique IDs to each client connected to the server.
+ Manages the connection to network peers. Assigns unique IDs to each client connected to the server. See also [MultiplayerAPI].
+ [b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice.
</description>
<tutorials>
<link title="High-level multiplayer">https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link>
diff --git a/doc/classes/NinePatchRect.xml b/doc/classes/NinePatchRect.xml
index f4b9d75e91..d6de0ef4cf 100644
--- a/doc/classes/NinePatchRect.xml
+++ b/doc/classes/NinePatchRect.xml
@@ -12,7 +12,7 @@
<method name="get_patch_margin" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
Returns the size of the margin on the specified [enum Side].
@@ -21,7 +21,7 @@
<method name="set_patch_margin">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="value" type="int">
</argument>
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 62d88afa51..7ee6860dfc 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -9,7 +9,7 @@
[b]Scene tree:[/b] The [SceneTree] contains the active tree of nodes. When a node is added to the scene tree, it receives the [constant NOTIFICATION_ENTER_TREE] notification and its [method _enter_tree] callback is triggered. Child nodes are always added [i]after[/i] their parent node, i.e. the [method _enter_tree] callback of a parent node will be triggered before its child's.
Once all nodes have been added in the scene tree, they receive the [constant NOTIFICATION_READY] notification and their respective [method _ready] callbacks are triggered. For groups of nodes, the [method _ready] callback is called in reverse order, starting with the children and moving up to the parent nodes.
This means that when adding a node to the scene tree, the following order will be used for the callbacks: [method _enter_tree] of the parent, [method _enter_tree] of the children, [method _ready] of the children and finally [method _ready] of the parent (recursively for the entire scene tree).
- [b]Processing:[/b] Nodes can override the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] is passed as an argument. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed number of times per second (60 by default) and is useful for code related to the physics engine.
+ [b]Processing:[/b] Nodes can override the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] (in seconds) is passed as an argument. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed number of times per second (60 by default) and is useful for code related to the physics engine.
Nodes can also process input events. When present, the [method _input] function will be called for each input that the program receives. In many cases, this can be overkill (unless used for simple projects), and the [method _unhandled_input] function might be preferred; it is called when the input event was not handled by anyone else (typically, GUI [Control] nodes), ensuring that the node only receives the events that were meant for it.
To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with the [member owner] property. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though.
Finally, when a node is freed with [method Object.free] or [method queue_free], it will also free all its children.
@@ -65,7 +65,7 @@
<argument index="0" name="delta" type="float">
</argument>
<description>
- Called during the physics processing step of the main loop. Physics processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant.
+ Called during the physics processing step of the main loop. Physics processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant. [code]delta[/code] is in seconds.
It is only called if physics processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_physics_process].
Corresponds to the [constant NOTIFICATION_PHYSICS_PROCESS] notification in [method Object._notification].
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not orphan).
@@ -77,7 +77,7 @@
<argument index="0" name="delta" type="float">
</argument>
<description>
- Called during the processing step of the main loop. Processing happens at every frame and as fast as possible, so the [code]delta[/code] time since the previous frame is not constant.
+ Called during the processing step of the main loop. Processing happens at every frame and as fast as possible, so the [code]delta[/code] time since the previous frame is not constant. [code]delta[/code] is in seconds.
It is only called if processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process].
Corresponds to the [constant NOTIFICATION_PROCESS] notification in [method Object._notification].
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not orphan).
@@ -179,7 +179,7 @@
<return type="bool">
</return>
<description>
- Returns [code]true[/code] if the node can process while the scene tree is paused (see [member pause_mode]). Always returns [code]true[/code] if the scene tree is not paused, and [code]false[/code] if the node is not in the tree.
+ Returns [code]true[/code] if the node can process while the scene tree is paused (see [member process_mode]). Always returns [code]true[/code] if the scene tree is not paused, and [code]false[/code] if the node is not in the tree.
</description>
</method>
<method name="duplicate" qualifiers="const">
@@ -245,6 +245,12 @@
Returns an array of references to node's children.
</description>
</method>
+ <method name="get_editor_description" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_groups" qualifiers="const">
<return type="Array">
</return>
@@ -361,7 +367,7 @@
<return type="float">
</return>
<description>
- Returns the time elapsed since the last physics-bound frame (see [method _physics_process]). This is always a constant value in physics processing unless the frames per second is changed via [member Engine.iterations_per_second].
+ Returns the time elapsed (in seconds) since the last physics-bound frame (see [method _physics_process]). This is always a constant value in physics processing unless the frames per second is changed via [member Engine.iterations_per_second].
</description>
</method>
<method name="get_process_delta_time" qualifiers="const">
@@ -590,7 +596,7 @@
<return type="void">
</return>
<description>
- Moves this node to the bottom of parent node's children hierarchy. This is often useful in GUIs ([Control] nodes), because their order of drawing depends on their order in the tree, i.e. the further they are on the node list, the higher they are drawn. After using [code]raise[/code], a Control will be drawn on top of their siblings.
+ Moves this node to the bottom of parent node's children hierarchy. This is often useful in GUIs ([Control] nodes), because their order of drawing depends on their order in the tree. The top Node is drawn first, then any siblings below the top Node in the hierarchy are successively drawn on top of it. After using [code]raise[/code], a Control will be drawn on top of its siblings.
</description>
</method>
<method name="remove_and_skip">
@@ -623,10 +629,11 @@
</return>
<argument index="0" name="node" type="Node">
</argument>
- <argument index="1" name="keep_data" type="bool" default="false">
+ <argument index="1" name="keep_groups" type="bool" default="false">
</argument>
<description>
Replaces a node in a scene by the given one. Subscriptions that pass through this node will be lost.
+ If [code]keep_groups[/code] is [code]true[/code], the [code]node[/code] is added to the same groups that the replaced node is in.
</description>
</method>
<method name="request_ready">
@@ -756,6 +763,14 @@
Sets the folded state of the node in the Scene dock.
</description>
</method>
+ <method name="set_editor_description">
+ <return type="void">
+ </return>
+ <argument index="0" name="editor_description" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_network_master">
<return type="void">
</return>
@@ -867,8 +882,8 @@
<member name="owner" type="Node" setter="set_owner" getter="get_owner">
The node owner. A node can have any other node as owner (as long as it is a valid parent, grandparent, etc. ascending in the tree). When saving a node (using [PackedScene]), all the nodes it owns will be saved with it. This allows for the creation of complex [SceneTree]s, with instancing and subinstancing.
</member>
- <member name="pause_mode" type="int" setter="set_pause_mode" getter="get_pause_mode" enum="Node.PauseMode" default="0">
- Pause mode. How the node will behave if the [SceneTree] is paused.
+ <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="Node.ProcessMode" default="0">
+ Can be used to pause or unpause the node, or make the node paused based on the [SceneTree], or make it inherit the process mode from its parent (default).
</member>
<member name="process_priority" type="int" setter="set_process_priority" getter="get_process_priority" default="0">
The node's priority in the execution order of the enabled processing callbacks (i.e. [constant NOTIFICATION_PROCESS], [constant NOTIFICATION_PHYSICS_PROCESS] and their internal counterparts). Nodes whose process priority value is [i]lower[/i] will have their processing callbacks executed first.
@@ -1016,14 +1031,20 @@
<constant name="NOTIFICATION_TEXT_SERVER_CHANGED" value="2018">
Notification received when text server is changed.
</constant>
- <constant name="PAUSE_MODE_INHERIT" value="0" enum="PauseMode">
- Inherits pause mode from the node's parent. For the root node, it is equivalent to [constant PAUSE_MODE_STOP]. Default.
+ <constant name="PROCESS_MODE_INHERIT" value="0" enum="ProcessMode">
+ Inherits process mode from the node's parent. For the root node, it is equivalent to [constant PROCESS_MODE_PAUSABLE]. Default.
+ </constant>
+ <constant name="PROCESS_MODE_PAUSABLE" value="1" enum="ProcessMode">
+ Stops processing when the [SceneTree] is paused (process when unpaused). This is the inverse of [constant PROCESS_MODE_WHEN_PAUSED].
+ </constant>
+ <constant name="PROCESS_MODE_WHEN_PAUSED" value="2" enum="ProcessMode">
+ Only process when the [SceneTree] is paused (don't process when unpaused). This is the inverse of [constant PROCESS_MODE_PAUSABLE].
</constant>
- <constant name="PAUSE_MODE_STOP" value="1" enum="PauseMode">
- Stops processing when the [SceneTree] is paused.
+ <constant name="PROCESS_MODE_ALWAYS" value="3" enum="ProcessMode">
+ Always process. Continue processing always, ignoring the [SceneTree]'s paused property. This is the inverse of [constant PROCESS_MODE_DISABLED].
</constant>
- <constant name="PAUSE_MODE_PROCESS" value="2" enum="PauseMode">
- Continue to process regardless of the [SceneTree] pause state.
+ <constant name="PROCESS_MODE_DISABLED" value="4" enum="ProcessMode">
+ Never process. Completely disables processing, ignoring the [SceneTree]'s paused property. This is the inverse of [constant PROCESS_MODE_ALWAYS].
</constant>
<constant name="DUPLICATE_SIGNALS" value="1" enum="DuplicateFlags">
Duplicate the node's signals.
diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml
index f6ff514474..5c29c0d48f 100644
--- a/doc/classes/Node3D.xml
+++ b/doc/classes/Node3D.xml
@@ -6,7 +6,7 @@
<description>
Most basic 3D game object, with a 3D [Transform] and visibility settings. All other 3D game objects inherit from Node3D. Use [Node3D] as a parent node to move, scale, rotate and show/hide children in a 3D project.
Affine operations (rotate, scale, translate) happen in parent's local coordinate system, unless the [Node3D] object is set as top-level. Affine operations in this coordinate system correspond to direct affine operations on the [Node3D]'s transform. The word local below refers to this coordinate system. The coordinate system that is attached to the [Node3D] object itself is referred to as object-local coordinate system.
- [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad].
+ [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GlobalScope.deg2rad].
</description>
<tutorials>
<link title="Introduction to 3D">https://docs.godotengine.org/en/latest/tutorials/3d/introduction_to_3d.html</link>
@@ -103,7 +103,7 @@
</return>
<argument index="0" name="target" type="Vector3">
</argument>
- <argument index="1" name="up" type="Vector3">
+ <argument index="1" name="up" type="Vector3" default="Vector3( 0, 1, 0 )">
</argument>
<description>
Rotates itself so that the local -Z axis points towards the [code]target[/code] position.
@@ -118,7 +118,7 @@
</argument>
<argument index="1" name="target" type="Vector3">
</argument>
- <argument index="2" name="up" type="Vector3">
+ <argument index="2" name="up" type="Vector3" default="Vector3( 0, 1, 0 )">
</argument>
<description>
Moves the node to the specified [code]position[/code], and then rotates itself to point toward the [code]target[/code] as per [method look_at]. Operations take place in global space.
@@ -229,7 +229,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Sets whether the node notifies about its global and local transformation changes. [Node3D] will not propagate this by default.
+ Sets whether the node notifies about its global and local transformation changes. [Node3D] will not propagate this by default, unless it is in the editor context and it has a valid gizmo.
</description>
</method>
<method name="show">
@@ -324,7 +324,7 @@
<constants>
<constant name="NOTIFICATION_TRANSFORM_CHANGED" value="2000">
Node3D nodes receives this notification when their global transform changes. This means that either the current or a parent node changed its transform.
- In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_transform].
+ In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_transform]. The notification is also sent if the node is in the editor context and it has a valid gizmo.
</constant>
<constant name="NOTIFICATION_ENTER_WORLD" value="41">
Node3D nodes receives this notification when they are registered to new [World3D] resource.
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 65a815a603..057a2b8d1a 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -25,13 +25,36 @@
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
+ <method name="create_process">
+ <return type="int">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <argument index="1" name="arguments" type="PackedStringArray">
+ </argument>
+ <description>
+ Creates a new process that runs independently of Godot. It will not terminate if Godot terminates. The file specified in [code]path[/code] must exist and be executable. Platform path resolution will be used. The [code]arguments[/code] are used in the given order and separated by a space.
+ If the process creation succeeds, the method will return the new process ID, which you can use to monitor the process (and potentially terminate it with [method kill]). If the process creation fails, the method will return [code]-1[/code].
+ For example, running another instance of the project:
+ [codeblocks]
+ [gdscript]
+ var pid = OS.create_process(OS.get_executable_path(), [])
+ [/gdscript]
+ [csharp]
+ var pid = OS.CreateProcess(OS.GetExecutablePath(), new string[] {});
+ [/csharp]
+ [/codeblocks]
+ See [method execute] if you wish to run an external command and retrieve the results.
+ [b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows.
+ </description>
+ </method>
<method name="delay_msec" qualifiers="const">
<return type="void">
</return>
<argument index="0" name="msec" type="int">
</argument>
<description>
- Delay execution of the current thread by [code]msec[/code] milliseconds.
+ Delay execution of the current thread by [code]msec[/code] milliseconds. [code]usec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_msec] will do nothing and will print an error message.
</description>
</method>
<method name="delay_usec" qualifiers="const">
@@ -40,7 +63,7 @@
<argument index="0" name="usec" type="int">
</argument>
<description>
- Delay execution of the current thread by [code]usec[/code] microseconds.
+ Delay execution of the current thread by [code]usec[/code] microseconds. [code]usec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_usec] will do nothing and will print an error message.
</description>
</method>
<method name="dump_memory_to_file">
@@ -71,48 +94,34 @@
</argument>
<argument index="1" name="arguments" type="PackedStringArray">
</argument>
- <argument index="2" name="blocking" type="bool" default="true">
- </argument>
- <argument index="3" name="output" type="Array" default="[ ]">
+ <argument index="2" name="output" type="Array" default="[ ]">
</argument>
- <argument index="4" name="read_stderr" type="bool" default="false">
+ <argument index="3" name="read_stderr" type="bool" default="false">
</argument>
<description>
- Execute the file at the given path with the arguments passed as an array of strings. Platform path resolution will take place. The resolved file must exist and be executable.
- The arguments are used in the given order and separated by a space, so [code]OS.execute("ping", ["-w", "3", "godotengine.org"], false)[/code] will resolve to [code]ping -w 3 godotengine.org[/code] in the system's shell.
- This method has slightly different behavior based on whether the [code]blocking[/code] mode is enabled.
- If [code]blocking[/code] is [code]true[/code], the Godot thread will pause its execution while waiting for the process to terminate. The shell output of the process will be written to the [code]output[/code] array as a single string. When the process terminates, the Godot thread will resume execution.
- If [code]blocking[/code] is [code]false[/code], the Godot thread will continue while the new process runs. It is not possible to retrieve the shell output in non-blocking mode, so [code]output[/code] will be empty.
- The return value also depends on the blocking mode. When blocking, the method will return an exit code of the process. When non-blocking, the method returns a process ID, which you can use to monitor the process (and potentially terminate it with [method kill]). If the process forking (non-blocking) or opening (blocking) fails, the method will return [code]-1[/code] or another exit code.
- Example of blocking mode and retrieving the shell output:
+ Executes a command. The file specified in [code]path[/code] must exist and be executable. Platform path resolution will be used. The [code]arguments[/code] are used in the given order and separated by a space. If an [code]output[/code] [Array] is provided, the complete shell output of the process will be appended as a single [String] element in [code]output[/code]. If [code]read_stderr[/code] is [code]true[/code], the output to the standard error stream will be included too.
+ If the command is successfully executed, the method will return the exit code of the command, or [code]-1[/code] if it fails.
+ [b]Note:[/b] The Godot thread will pause its execution until the executed command terminates. Use [Thread] to create a separate thread that will not pause the Godot thread, or use [method create_process] to create a completely independent process.
+ For example, to retrieve a list of the working directory's contents:
[codeblocks]
[gdscript]
var output = []
- var exit_code = OS.execute("ls", ["-l", "/tmp"], true, output)
+ var exit_code = OS.execute("ls", ["-l", "/tmp"], output)
[/gdscript]
[csharp]
var output = new Godot.Collections.Array();
- int exitCode = OS.Execute("ls", new string[] {"-l", "/tmp"}, true, output);
- [/csharp]
- [/codeblocks]
- Example of non-blocking mode, running another instance of the project and storing its process ID:
- [codeblocks]
- [gdscript]
- var pid = OS.execute(OS.get_executable_path(), [], false)
- [/gdscript]
- [csharp]
- var pid = OS.Execute(OS.GetExecutablePath(), new string[] {}, false);
+ int exitCode = OS.Execute("ls", new string[] {"-l", "/tmp"}, output);
[/csharp]
[/codeblocks]
- If you wish to access a shell built-in or perform a composite command, a platform-specific shell can be invoked. For example:
+ To execute a composite command, a platform-specific shell can be invoked. For example:
[codeblocks]
[gdscript]
var output = []
- OS.execute("CMD.exe", ["/C", "cd %TEMP% &amp;&amp; dir"], true, output)
+ OS.execute("CMD.exe", ["/C", "cd %TEMP% &amp;&amp; dir"], output)
[/gdscript]
[csharp]
var output = new Godot.Collections.Array();
- OS.Execute("CMD.exe", new string[] {"/C", "cd %TEMP% &amp;&amp; dir"}, true, output);
+ OS.Execute("CMD.exe", new string[] {"/C", "cd %TEMP% &amp;&amp; dir"}, output);
[/csharp]
[/codeblocks]
[b]Note:[/b] This method is implemented on Android, iOS, Linux, macOS and Windows.
@@ -198,10 +207,11 @@
<method name="get_environment" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="environment" type="String">
+ <argument index="0" name="variable" type="String">
</argument>
<description>
- Returns an environment variable.
+ Returns the value of an environment variable. Returns an empty string if the environment variable doesn't exist.
+ [b]Note:[/b] Double-check the casing of [code]variable[/code]. Environment variable names are case-sensitive on all platforms except Windows.
</description>
</method>
<method name="get_executable_path" qualifiers="const">
@@ -295,22 +305,12 @@
[b]Note:[/b] This method is implemented on Android, Linux, macOS and Windows.
</description>
</method>
- <method name="get_tablet_driver_count" qualifiers="const">
+ <method name="get_thread_caller_id" qualifiers="const">
<return type="int">
</return>
<description>
- Returns the total number of available tablet drivers.
- [b]Note:[/b] This method is implemented on Windows.
- </description>
- </method>
- <method name="get_tablet_driver_name" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="idx" type="int">
- </argument>
- <description>
- Returns the tablet driver name for the given index.
- [b]Note:[/b] This method is implemented on Windows.
+ Returns the ID of the current thread. This can be used in logs to ease debugging of multi-threaded applications.
+ [b]Note:[/b] Thread IDs are not deterministic and may be reused across application restarts.
</description>
</method>
<method name="get_ticks_msec" qualifiers="const">
@@ -384,10 +384,11 @@
<method name="has_environment" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="environment" type="String">
+ <argument index="0" name="variable" type="String">
</argument>
<description>
- Returns [code]true[/code] if an environment variable exists.
+ Returns [code]true[/code] if the environment variable with the name [code]variable[/code] exists.
+ [b]Note:[/b] Double-check the casing of [code]variable[/code]. Environment variable names are case-sensitive on all platforms except Windows.
</description>
</method>
<method name="has_feature" qualifiers="const">
@@ -502,6 +503,18 @@
[b]Note:[/b] This method is implemented on Android.
</description>
</method>
+ <method name="set_environment" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="variable" type="String">
+ </argument>
+ <argument index="1" name="value" type="String">
+ </argument>
+ <description>
+ Sets the value of the environment variable [code]variable[/code] to [code]value[/code]. The environment variable will be set for the Godot process and any process executed with [method execute] after running [method set_environment]. The environment variable will [i]not[/i] persist to processes run after the Godot process was terminated.
+ [b]Note:[/b] Double-check the casing of [code]variable[/code]. Environment variable names are case-sensitive on all platforms except Windows.
+ </description>
+ </method>
<method name="set_thread_name">
<return type="int" enum="Error">
</return>
@@ -536,19 +549,12 @@
</method>
</methods>
<members>
- <member name="exit_code" type="int" setter="set_exit_code" getter="get_exit_code" default="0">
- The exit code passed to the OS when the main loop exits. By convention, an exit code of [code]0[/code] indicates success whereas a non-zero exit code indicates an error. For portability reasons, the exit code should be set between 0 and 125 (inclusive).
- [b]Note:[/b] This value will be ignored if using [method SceneTree.quit] with an [code]exit_code[/code] argument passed.
- </member>
<member name="low_processor_usage_mode" type="bool" setter="set_low_processor_usage_mode" getter="is_in_low_processor_usage_mode" default="false">
If [code]true[/code], the engine optimizes for low processor usage by only refreshing the screen if needed. Can improve battery consumption on mobile.
</member>
<member name="low_processor_usage_mode_sleep_usec" type="int" setter="set_low_processor_usage_mode_sleep_usec" getter="get_low_processor_usage_mode_sleep_usec" default="6900">
The amount of sleeping between frames when the low-processor usage mode is enabled (in microseconds). Higher values will result in lower CPU usage.
</member>
- <member name="tablet_driver" type="String" setter="set_current_tablet_driver" getter="get_current_tablet_driver" default="&quot;&quot;">
- The current tablet driver in use.
- </member>
</members>
<constants>
<constant name="VIDEO_DRIVER_GLES2" value="0" enum="VideoDriver">
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index 50d91c7943..ad3ce8e93e 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -10,11 +10,20 @@
Some classes that extend Object add memory management. This is the case of [Reference], which counts references and deletes itself automatically when no longer referenced. [Node], another fundamental type, deletes all its children when freed from memory.
Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simpler means to export them.
Property membership can be tested directly in GDScript using [code]in[/code]:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var n = Node2D.new()
print("position" in n) # Prints "True".
print("other_property" in n) # Prints "False".
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var node = new Node2D();
+ // C# has no direct equivalent to GDScript's `in` operator here, but we
+ // can achieve the same behavior by performing `Get` with a null check.
+ GD.Print(node.Get("position") != null); // Prints "True".
+ GD.Print(node.Get("other_property") != null); // Prints "False".
+ [/csharp]
+ [/codeblocks]
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 [Reference], references to an Object stored in a variable can become invalid without warning. Therefore, it's recommended to use [Reference] for data classes instead of [Object].
@@ -96,9 +105,16 @@
</argument>
<description>
Calls the [code]method[/code] on the object and returns the result. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example:
- [codeblock]
- call("set", "position", Vector2(42.0, 0.0))
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var node = Node2D.new()
+ node.call("set", "position", Vector2(42, 0))
+ [/gdscript]
+ [csharp]
+ var node = new Node2D();
+ node.Call("set", "position", new Vector2(42, 0));
+ [/csharp]
+ [/codeblocks]
[b]Note:[/b] In C#, the method name must be specified as snake_case if it is defined by a built-in Godot node. This doesn't apply to user-defined methods where you should use the same convention as in the C# source (typically PascalCase).
</description>
</method>
@@ -109,9 +125,16 @@
</argument>
<description>
Calls the [code]method[/code] on the object during idle time. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example:
- [codeblock]
- call_deferred("set", "position", Vector2(42.0, 0.0))
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var node = Node2D.new()
+ node.call_deferred("set", "position", Vector2(42, 0))
+ [/gdscript]
+ [csharp]
+ var node = new Node2D();
+ node.CallDeferred("set", "position", new Vector2(42, 0));
+ [/csharp]
+ [/codeblocks]
[b]Note:[/b] In C#, the method name must be specified as snake_case if it is defined by a built-in Godot node. This doesn't apply to user-defined methods where you should use the same convention as in the C# source (typically PascalCase).
</description>
</method>
@@ -124,9 +147,16 @@
</argument>
<description>
Calls the [code]method[/code] on the object and returns the result. Contrarily to [method call], this method does not support a variable number of arguments but expects all parameters to be via a single [Array].
- [codeblock]
- callv("set", [ "position", Vector2(42.0, 0.0) ])
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var node = Node2D.new()
+ node.callv("set", ["position", Vector2(42, 0)])
+ [/gdscript]
+ [csharp]
+ var node = new Node2D();
+ node.Callv("set", new Godot.Collections.Array { "position", new Vector2(42, 0) });
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="can_translate_messages" qualifiers="const">
@@ -148,23 +178,140 @@
<argument index="3" name="flags" type="int" default="0">
</argument>
<description>
- [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated.
- Connects a [code]signal[/code] to a [code]method[/code] on a [code]target[/code] object. Pass optional [code]binds[/code] to the call as an [Array] of parameters. These parameters will be passed to the method after any parameter used in the call to [method emit_signal]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants.
- A [code]signal[/code] can only be connected once to a [code]method[/code]. It will throw an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections.
- If the [code]target[/code] is destroyed in the game's lifecycle, the connection will be lost.
- Examples:
- [codeblock]
- connect("pressed", self, "_on_Button_pressed") # BaseButton signal
- connect("text_entered", self, "_on_LineEdit_text_entered") # LineEdit signal
- connect("hit", self, "_on_Player_hit", [ weapon_type, damage ]) # User-defined signal
- [/codeblock]
- An example of the relationship between [code]binds[/code] passed to [method connect] and parameters used when calling [method emit_signal]:
- [codeblock]
- connect("hit", self, "_on_Player_hit", [ weapon_type, damage ]) # weapon_type and damage are passed last
- emit_signal("hit", "Dark lord", 5) # "Dark lord" and 5 are passed first
- func _on_Player_hit(hit_by, level, weapon_type, damage):
- print("Hit by %s (lvl %d) with weapon %s for %d damage" % [hit_by, level, weapon_type, damage])
- [/codeblock]
+ Connects a [code]signal[/code] to a [code]callable[/code]. Pass optional [code]binds[/code] to the call as an [Array] of parameters. These parameters will be passed to the [Callable]'s method after any parameter used in the call to [method emit_signal]. Use [code]flags[/code] to set deferred or one-shot connections. See [enum ConnectFlags] constants.
+ [b]Note:[/b] This method is the legacy implementation for connecting signals. The recommend modern approach is to use [method Signal.connect] and to use [method Callable.bind] to add and validate parameter binds. Both syntaxes are shown below.
+ A signal can only be connected once to a [Callable]. It will throw an error if already connected, unless the signal was connected with [constant CONNECT_REFERENCE_COUNTED]. To avoid this, first, use [method is_connected] to check for existing connections.
+ If the callable's target is destroyed in the game's lifecycle, the connection will be lost.
+ [b]Examples with recommended syntax:[/b]
+ Connecting signals is one of the most common operations in Godot and the API gives many options to do so, which are described further down. The code block below shows the recommended approach for both GDScript and C#.
+ [codeblocks]
+ [gdscript]
+ func _ready():
+ var button = Button.new()
+ # `button_down` here is a Signal object, and we thus call the Signal.connect() method,
+ # not Object.connect(). See discussion below for a more in-depth overview of the API.
+ button.button_down.connect(_on_button_down)
+
+ # This assumes that a `Player` class exists which defines a `hit` signal.
+ var player = Player.new()
+ # We use Signal.connect() again, and we also use the Callable.bind() method which
+ # returns a new Callable with the parameter binds.
+ player.hit.connect(_on_player_hit.bind("sword", 100))
+
+ func _on_button_down():
+ print("Button down!")
+
+ func _on_player_hit(weapon_type, damage):
+ print("Hit with weapon %s for %d damage." % [weapon_type, damage])
+ [/gdscript]
+ [csharp]
+ public override void _Ready()
+ {
+ var button = new Button();
+ // C# supports passing signals as events, so we can use this idiomatic construct:
+ button.ButtonDown += OnButtonDown;
+
+ // This assumes that a `Player` class exists which defines a `Hit` signal.
+ var player = new Player();
+ // Signals as events (`player.Hit += OnPlayerHit;`) do not support argument binding. You have to use:
+ player.Hit.Connect(OnPlayerHit, new Godot.Collections.Array {"sword", 100 });
+ }
+
+ private void OnButtonDown()
+ {
+ GD.Print("Button down!");
+ }
+
+ private void OnPlayerHit(string weaponType, int damage)
+ {
+ GD.Print(String.Format("Hit with weapon {0} for {1} damage.", weaponType, damage));
+ }
+ [/csharp]
+ [/codeblocks]
+ [b][code]Object.connect()[/code] or [code]Signal.connect()[/code]?[/b]
+ As seen above, the recommended method to connect signals is not [method Object.connect]. The code block below shows the four options for connecting signals, using either this legacy method or the recommended [method Signal.connect], and using either an implicit [Callable] or a manually defined one.
+ [codeblocks]
+ [gdscript]
+ func _ready():
+ var button = Button.new()
+ # Option 1: Object.connect() with an implicit Callable for the defined function.
+ button.connect("button_down", _on_button_down)
+ # Option 2: Object.connect() with a constructed Callable using a target object and method name.
+ button.connect("button_down", Callable(self, "_on_button_down"))
+ # Option 3: Signal.connect() with an implicit Callable for the defined function.
+ button.button_down.connect(_on_button_down)
+ # Option 4: Signal.connect() with a constructed Callable using a target object and method name.
+ button.button_down.connect(Callable(self, "_on_button_down"))
+
+ func _on_button_down():
+ print("Button down!")
+ [/gdscript]
+ [csharp]
+ public override void _Ready()
+ {
+ var button = new Button();
+ // Option 1: Object.Connect() with an implicit Callable for the defined function.
+ button.Connect("button_down", OnButtonDown);
+ // Option 2: Object.connect() with a constructed Callable using a target object and method name.
+ button.Connect("button_down", new Callable(self, nameof(OnButtonDown)));
+ // Option 3: Signal.connect() with an implicit Callable for the defined function.
+ button.ButtonDown.Connect(OnButtonDown);
+ // Option 3b: In C#, we can use signals as events and connect with this more idiomatic syntax:
+ button.ButtonDown += OnButtonDown;
+ // Option 4: Signal.connect() with a constructed Callable using a target object and method name.
+ button.ButtonDown.Connect(new Callable(self, nameof(OnButtonDown)));
+ }
+
+ private void OnButtonDown()
+ {
+ GD.Print("Button down!");
+ }
+ [/csharp]
+ [/codeblocks]
+ While all options have the same outcome ([code]button[/code]'s [signal BaseButton.button_down] signal will be connected to [code]_on_button_down[/code]), option 3 offers the best validation: it will throw a compile-time error if either the [code]button_down[/code] signal or the [code]_on_button_down[/code] callable are undefined. On the other hand, option 2 only relies on string names and will only be able to validate either names at runtime: it will throw a runtime error if [code]"button_down"[/code] doesn't correspond to a signal, or if [code]"_on_button_down"[/code] is not a registered method in the object [code]self[/code]. The main reason for using options 1, 2, or 4 would be if you actually need to use strings (e.g. to connect signals programmatically based on strings read from a configuration file). Otherwise, option 3 is the recommended (and fastest) method.
+ [b]Parameter bindings and passing:[/b]
+ For legacy or language-specific reasons, there are also several ways to bind parameters to signals. One can pass a [code]binds[/code] [Array] to [method Object.connect] or [method Signal.connect], or use the recommended [method Callable.bind] method to create a new callable from an existing one, with the given parameter binds.
+ One can also pass additional parameters when emitting the signal with [method emit_signal]. The examples below show the relationship between those two types of parameters.
+ [codeblocks]
+ [gdscript]
+ func _ready():
+ # This assumes that a `Player` class exists which defines a `hit` signal.
+ var player = Player.new()
+ # Option 1: Using Callable.bind().
+ player.hit.connect(_on_player_hit.bind("sword", 100))
+ # Option 2: Using a `binds` Array in Signal.connect() (same syntax for Object.connect()).
+ player.hit.connect(_on_player_hit, ["sword", 100])
+
+ # Parameters added when emitting the signal are passed first.
+ player.emit_signal("hit", "Dark lord", 5)
+
+ # Four arguments, since we pass two when emitting (hit_by, level)
+ # and two when connecting (weapon_type, damage).
+ func _on_player_hit(hit_by, level, weapon_type, damage):
+ print("Hit by %s (level %d) with weapon %s for %d damage." % [hit_by, level, weapon_type, damage])
+ [/gdscript]
+ [csharp]
+ public override void _Ready()
+ {
+ // This assumes that a `Player` class exists which defines a `Hit` signal.
+ var player = new Player();
+ // Option 1: Using Callable.Bind(). This way we can still use signals as events.
+ player.Hit += OnPlayerHit.Bind("sword", 100);
+ // Option 2: Using a `binds` Array in Signal.Connect() (same syntax for Object.Connect()).
+ player.Hit.Connect(OnPlayerHit, new Godot.Collections.Array{ "sword", 100 });
+
+ // Parameters added when emitting the signal are passed first.
+ player.EmitSignal("hit", "Dark lord", 5);
+ }
+
+ // Four arguments, since we pass two when emitting (hitBy, level)
+ // and two when connecting (weaponType, damage).
+ private void OnPlayerHit(string hitBy, int level, string weaponType, int damage)
+ {
+ GD.Print(String.Format("Hit by {0} (level {1}) with weapon {2} for {3} damage.", hitBy, level, weaponType, damage));
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="disconnect">
@@ -175,8 +322,7 @@
<argument index="1" name="callable" type="Callable">
</argument>
<description>
- [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated.
- Disconnects a [code]signal[/code] from a [code]method[/code] on the given [code]target[/code].
+ Disconnects a [code]signal[/code] from a given [code]callable[/code].
If you try to disconnect a connection that does not exist, the method will throw an error. Use [method is_connected] to ensure that the connection exists.
</description>
</method>
@@ -187,10 +333,16 @@
</argument>
<description>
Emits the given [code]signal[/code]. The signal must exist, so it should be a built-in signal of this class or one of its parent classes, or a user-defined signal. This method supports a variable number of arguments, so parameters are passed as a comma separated list. Example:
- [codeblock]
- emit_signal("hit", weapon_type, damage)
+ [codeblocks]
+ [gdscript]
+ emit_signal("hit", "sword", 100)
emit_signal("game_over")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ EmitSignal("hit", "sword", 100);
+ EmitSignal("game_over");
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="free">
@@ -242,7 +394,7 @@
</return>
<description>
Returns the object's unique instance ID.
- This ID can be saved in [EncodedObjectAsID], and can be used to retrieve the object instance with [method @GDScript.instance_from_id].
+ This ID can be saved in [EncodedObjectAsID], and can be used to retrieve the object instance with [method @GlobalScope.instance_from_id].
</description>
</method>
<method name="get_meta" qualifiers="const">
@@ -359,8 +511,7 @@
<argument index="1" name="callable" type="Callable">
</argument>
<description>
- [b]FIXME:[/b] The syntax changed with the addition of [Callable], this should be updated.
- Returns [code]true[/code] if a connection exists for a given [code]signal[/code], [code]target[/code], and [code]method[/code].
+ Returns [code]true[/code] if a connection exists for a given [code]signal[/code] and [code]callable[/code].
</description>
</method>
<method name="is_queued_for_deletion" qualifiers="const">
@@ -382,11 +533,11 @@
If [code]reversed[/code] is [code]true[/code], [method _notification] is called first on the object's own class, and then up to its successive parent classes. If [code]reversed[/code] is [code]false[/code], [method _notification] is called first on the highest ancestor ([Object] itself), and then down to its successive inheriting classes.
</description>
</method>
- <method name="property_list_changed_notify">
+ <method name="notify_property_list_changed">
<return type="void">
</return>
<description>
- Notify the editor that the property list has changed, so that editor plugins can take the new values into account. Does nothing on export builds.
+ Notify the editor that the property list has changed by emitting the [signal property_list_changed] signal, so that editor plugins can take the new values into account.
</description>
</method>
<method name="remove_meta">
@@ -440,11 +591,20 @@
</argument>
<description>
Assigns a new value to the property identified by the [NodePath]. The node path should be relative to the current object and can use the colon character ([code]:[/code]) to access nested properties. Example:
- [codeblock]
- set_indexed("position", Vector2(42, 0))
- set_indexed("position:y", -10)
- print(position) # (42, -10)
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ var node = Node2D.new()
+ node.set_indexed("position", Vector2(42, 0))
+ node.set_indexed("position:y", -10)
+ print(node.position) # (42, -10)
+ [/gdscript]
+ [csharp]
+ var node = new Node2D();
+ node.SetIndexed("position", new Vector2(42, 0));
+ node.SetIndexed("position:y", -10);
+ GD.Print(node.Position); // (42, -10)
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="set_message_translation">
@@ -520,6 +680,10 @@
</method>
</methods>
<signals>
+ <signal name="property_list_changed">
+ <description>
+ </description>
+ </signal>
<signal name="script_changed">
<description>
Emitted whenever the object's script is changed.
diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml
index 53309bae96..52da08c02f 100644
--- a/doc/classes/OptionButton.xml
+++ b/doc/classes/OptionButton.xml
@@ -253,13 +253,16 @@
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
Default text [Color] of the [OptionButton].
</theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
Text [Color] used when the [OptionButton] is disabled.
</theme_item>
- <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ <theme_item name="font_hover_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
Text [Color] used when the [OptionButton] is being hovered.
</theme_item>
- <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [OptionButton].
+ </theme_item>
+ <theme_item name="font_pressed_color" type="Color" default="Color( 1, 1, 1, 1 )">
Text [Color] used when the [OptionButton] is being pressed.
</theme_item>
<theme_item name="font_size" type="int">
@@ -280,6 +283,9 @@
<theme_item name="normal_mirrored" type="StyleBox">
Default [StyleBox] for the [OptionButton] (for right-to-left layouts).
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="pressed" type="StyleBox">
[StyleBox] used when the [OptionButton] is being pressed (for left-to-right layouts).
</theme_item>
diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml
index 0cef26df79..75fb7c1465 100644
--- a/doc/classes/PackedByteArray.xml
+++ b/doc/classes/PackedByteArray.xml
@@ -92,13 +92,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="get_string_from_ascii">
<return type="String">
</return>
@@ -171,6 +164,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml
index b45e2cbe2e..48d5822f7c 100644
--- a/doc/classes/PackedColorArray.xml
+++ b/doc/classes/PackedColorArray.xml
@@ -59,13 +59,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="has">
<return type="bool">
</return>
@@ -93,6 +86,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml
index d6825dbcd7..6598828089 100644
--- a/doc/classes/PackedFloat32Array.xml
+++ b/doc/classes/PackedFloat32Array.xml
@@ -60,13 +60,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="has">
<return type="bool">
</return>
@@ -94,6 +87,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml
index 9b6df93cf5..d116c6756b 100644
--- a/doc/classes/PackedFloat64Array.xml
+++ b/doc/classes/PackedFloat64Array.xml
@@ -60,13 +60,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="has">
<return type="bool">
</return>
@@ -94,6 +87,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml
index 7923b268a4..2ac7a67b4b 100644
--- a/doc/classes/PackedInt32Array.xml
+++ b/doc/classes/PackedInt32Array.xml
@@ -60,13 +60,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="has">
<return type="bool">
</return>
@@ -94,6 +87,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml
index f7e9128410..a7b6bf0a0f 100644
--- a/doc/classes/PackedInt64Array.xml
+++ b/doc/classes/PackedInt64Array.xml
@@ -60,13 +60,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="has">
<return type="bool">
</return>
@@ -94,6 +87,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml
index d15bcfd114..1d9be7f165 100644
--- a/doc/classes/PackedScene.xml
+++ b/doc/classes/PackedScene.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
A simplified interface to a scene file. Provides access to operations and checks that can be performed on the scene resource itself.
- Can be used to save a node to a file. When saving, the node as well as all the node it owns get saved (see [code]owner[/code] property on [Node]).
+ Can be used to save a node to a file. When saving, the node as well as all the nodes it owns get saved (see [code]owner[/code] property on [Node]).
[b]Note:[/b] The node doesn't need to own itself.
[b]Example of loading a saved scene:[/b]
[codeblocks]
diff --git a/doc/classes/PackedSceneGLTF.xml b/doc/classes/PackedSceneGLTF.xml
new file mode 100644
index 0000000000..a04c6ef0b6
--- /dev/null
+++ b/doc/classes/PackedSceneGLTF.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="PackedSceneGLTF" inherits="PackedScene" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="export_gltf">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="node" type="Node">
+ </argument>
+ <argument index="1" name="path" type="String">
+ </argument>
+ <argument index="2" name="flags" type="int" default="0">
+ </argument>
+ <argument index="3" name="bake_fps" type="float" default="1000.0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="import_gltf_scene">
+ <return type="Node">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <argument index="1" name="flags" type="int" default="0">
+ </argument>
+ <argument index="2" name="bake_fps" type="float" default="1000.0">
+ </argument>
+ <argument index="3" name="state" type="GLTFState" default="null">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="pack_gltf">
+ <return type="void">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <argument index="1" name="flags" type="int" default="0">
+ </argument>
+ <argument index="2" name="bake_fps" type="float" default="1000.0">
+ </argument>
+ <argument index="3" name="state" type="GLTFState" default="null">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="_bundled" type="Dictionary" setter="_set_bundled_scene" getter="_get_bundled_scene" override="true" default="{&quot;conn_count&quot;: 0,&quot;conns&quot;: PackedInt32Array( ),&quot;editable_instances&quot;: [ ],&quot;names&quot;: PackedStringArray( ),&quot;node_count&quot;: 0,&quot;node_paths&quot;: [ ],&quot;nodes&quot;: PackedInt32Array( ),&quot;variants&quot;: [ ],&quot;version&quot;: 2}" />
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml
index 1ae0d55177..fb7ed2a906 100644
--- a/doc/classes/PackedStringArray.xml
+++ b/doc/classes/PackedStringArray.xml
@@ -60,13 +60,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="has">
<return type="bool">
</return>
@@ -94,6 +87,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml
index 9ab3a03edb..eb364ddb18 100644
--- a/doc/classes/PackedVector2Array.xml
+++ b/doc/classes/PackedVector2Array.xml
@@ -60,13 +60,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="has">
<return type="bool">
</return>
@@ -94,6 +87,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml
index 80787547ac..08ce187b5c 100644
--- a/doc/classes/PackedVector3Array.xml
+++ b/doc/classes/PackedVector3Array.xml
@@ -59,13 +59,6 @@
Creates a copy of the array, and returns it.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the array is empty.
- </description>
- </method>
<method name="has">
<return type="bool">
</return>
@@ -93,6 +86,13 @@
Reverses the order of the elements in the array.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="operator !=" qualifiers="operator">
<return type="bool">
</return>
diff --git a/doc/classes/PhysicsDirectSpaceState2D.xml b/doc/classes/PhysicsDirectSpaceState2D.xml
index c26cf0514c..b6f95305ed 100644
--- a/doc/classes/PhysicsDirectSpaceState2D.xml
+++ b/doc/classes/PhysicsDirectSpaceState2D.xml
@@ -16,8 +16,9 @@
<argument index="0" name="shape" type="PhysicsShapeQueryParameters2D">
</argument>
<description>
- Checks how far the shape can travel toward a point. If the shape can not move, the array will be empty.
- [b]Note:[/b] Both the shape and the motion are supplied through a [PhysicsShapeQueryParameters2D] object. The method will return an array with two floats between 0 and 1, both representing a fraction of [code]motion[/code]. The first is how far the shape can move without triggering a collision, and the second is the point at which a collision will occur. If no collision is detected, the returned array will be [code][1, 1][/code].
+ Checks how far a [Shape2D] can move without colliding. All the parameters for the query, including the shape and the motion, are supplied through a [PhysicsShapeQueryParameters2D] object.
+ Returns an array with the safe and unsafe proportions (between 0 and 1) of the motion. The safe proportion is the maximum fraction of the motion that can be made without a collision. The unsafe proportion is the minimum fraction of the distance that must be moved for a collision. If no collision is detected a result of [code][1.0, 1.0][/code] will be returned.
+ [b]Note:[/b] Any [Shape2D]s that the shape is already colliding with e.g. inside of, will be ignored. Use [method collide_shape] to determine the [Shape2D]s that the shape is already colliding with.
</description>
</method>
<method name="collide_shape">
diff --git a/doc/classes/PhysicsDirectSpaceState3D.xml b/doc/classes/PhysicsDirectSpaceState3D.xml
index 789e8cc731..243d071c56 100644
--- a/doc/classes/PhysicsDirectSpaceState3D.xml
+++ b/doc/classes/PhysicsDirectSpaceState3D.xml
@@ -18,8 +18,9 @@
<argument index="1" name="motion" type="Vector3">
</argument>
<description>
- Checks whether the shape can travel to a point. The method will return an array with two floats between 0 and 1, both representing a fraction of [code]motion[/code]. The first is how far the shape can move without triggering a collision, and the second is the point at which a collision will occur. If no collision is detected, the returned array will be [code][1, 1][/code].
- If the shape can not move, the returned array will be [code][0, 0][/code] under Bullet, and empty under GodotPhysics3D.
+ Checks how far a [Shape3D] can move without colliding. All the parameters for the query, including the shape, are supplied through a [PhysicsShapeQueryParameters3D] object.
+ Returns an array with the safe and unsafe proportions (between 0 and 1) of the motion. The safe proportion is the maximum fraction of the motion that can be made without a collision. The unsafe proportion is the minimum fraction of the distance that must be moved for a collision. If no collision is detected a result of [code][1.0, 1.0][/code] will be returned.
+ [b]Note:[/b] Any [Shape3D]s that the shape is already colliding with e.g. inside of, will be ignored. Use [method collide_shape] to determine the [Shape3D]s that the shape is already colliding with.
</description>
</method>
<method name="collide_shape">
diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml
index 6a1508b0e3..701a430538 100644
--- a/doc/classes/PhysicsServer2D.xml
+++ b/doc/classes/PhysicsServer2D.xml
@@ -58,7 +58,7 @@
<return type="RID">
</return>
<description>
- Creates an [Area2D].
+ Creates an [Area2D]. After creating an [Area2D] with this method, assign it to a space using [method area_set_space] to use the created [Area2D] in the physics world.
</description>
</method>
<method name="area_get_canvas_instance_id" qualifiers="const">
@@ -850,21 +850,6 @@
<description>
</description>
</method>
- <method name="damped_spring_joint_create">
- <return type="RID">
- </return>
- <argument index="0" name="anchor_a" type="Vector2">
- </argument>
- <argument index="1" name="anchor_b" type="Vector2">
- </argument>
- <argument index="2" name="body_a" type="RID">
- </argument>
- <argument index="3" name="body_b" type="RID">
- </argument>
- <description>
- Creates a damped spring joint between two bodies. If not specified, the second body is assumed to be the joint itself.
- </description>
- </method>
<method name="damped_spring_joint_get_param" qualifiers="const">
<return type="float">
</return>
@@ -907,21 +892,18 @@
Returns information about the current state of the 2D physics engine. See [enum ProcessInfo] for a list of available states.
</description>
</method>
- <method name="groove_joint_create">
- <return type="RID">
+ <method name="joint_clear">
+ <return type="void">
</return>
- <argument index="0" name="groove1_a" type="Vector2">
- </argument>
- <argument index="1" name="groove2_a" type="Vector2">
- </argument>
- <argument index="2" name="anchor_b" type="Vector2">
- </argument>
- <argument index="3" name="body_a" type="RID">
- </argument>
- <argument index="4" name="body_b" type="RID">
+ <argument index="0" name="joint" type="RID">
</argument>
<description>
- Creates a groove joint between two bodies. If not specified, the bodies are assumed to be the joint itself.
+ </description>
+ </method>
+ <method name="joint_create">
+ <return type="RID">
+ </return>
+ <description>
</description>
</method>
<method name="joint_get_param" qualifiers="const">
@@ -944,36 +926,71 @@
Returns a joint's type (see [enum JointType]).
</description>
</method>
- <method name="joint_set_param">
+ <method name="joint_make_damped_spring">
<return type="void">
</return>
<argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="param" type="int" enum="PhysicsServer2D.JointParam">
+ <argument index="1" name="anchor_a" type="Vector2">
</argument>
- <argument index="2" name="value" type="float">
+ <argument index="2" name="anchor_b" type="Vector2">
+ </argument>
+ <argument index="3" name="body_a" type="RID">
+ </argument>
+ <argument index="4" name="body_b" type="RID">
</argument>
<description>
- Sets a joint parameter. See [enum JointParam] for a list of available parameters.
</description>
</method>
- <method name="line_shape_create">
- <return type="RID">
+ <method name="joint_make_groove">
+ <return type="void">
</return>
+ <argument index="0" name="joint" type="RID">
+ </argument>
+ <argument index="1" name="groove1_a" type="Vector2">
+ </argument>
+ <argument index="2" name="groove2_a" type="Vector2">
+ </argument>
+ <argument index="3" name="anchor_b" type="Vector2">
+ </argument>
+ <argument index="4" name="body_a" type="RID">
+ </argument>
+ <argument index="5" name="body_b" type="RID">
+ </argument>
<description>
</description>
</method>
- <method name="pin_joint_create">
- <return type="RID">
+ <method name="joint_make_pin">
+ <return type="void">
</return>
- <argument index="0" name="anchor" type="Vector2">
+ <argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="body_a" type="RID">
+ <argument index="1" name="anchor" type="Vector2">
</argument>
- <argument index="2" name="body_b" type="RID">
+ <argument index="2" name="body_a" type="RID">
+ </argument>
+ <argument index="3" name="body_b" type="RID">
</argument>
<description>
- Creates a pin joint between two bodies. If not specified, the second body is assumed to be the joint itself.
+ </description>
+ </method>
+ <method name="joint_set_param">
+ <return type="void">
+ </return>
+ <argument index="0" name="joint" type="RID">
+ </argument>
+ <argument index="1" name="param" type="int" enum="PhysicsServer2D.JointParam">
+ </argument>
+ <argument index="2" name="value" type="float">
+ </argument>
+ <description>
+ Sets a joint parameter. See [enum JointParam] for a list of available parameters.
+ </description>
+ </method>
+ <method name="line_shape_create">
+ <return type="RID">
+ </return>
+ <description>
</description>
</method>
<method name="ray_shape_create">
@@ -1233,15 +1250,18 @@
<constant name="BODY_STATE_CAN_SLEEP" value="4" enum="BodyState">
Constant to set/get whether the body can sleep.
</constant>
- <constant name="JOINT_PIN" value="0" enum="JointType">
+ <constant name="JOINT_TYPE_PIN" value="0" enum="JointType">
Constant to create pin joints.
</constant>
- <constant name="JOINT_GROOVE" value="1" enum="JointType">
+ <constant name="JOINT_TYPE_GROOVE" value="1" enum="JointType">
Constant to create groove joints.
</constant>
- <constant name="JOINT_DAMPED_SPRING" value="2" enum="JointType">
+ <constant name="JOINT_TYPE_DAMPED_SPRING" value="2" enum="JointType">
Constant to create damped spring joints.
</constant>
+ <constant name="JOINT_TYPE_MAX" value="3" enum="JointType">
+ Represents the size of the [enum JointType] enum.
+ </constant>
<constant name="JOINT_PARAM_BIAS" value="0" enum="JointParam">
</constant>
<constant name="JOINT_PARAM_MAX_BIAS" value="1" enum="JointParam">
diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml
index 5fd3ef5db2..9a7926e937 100644
--- a/doc/classes/PhysicsServer3D.xml
+++ b/doc/classes/PhysicsServer3D.xml
@@ -129,15 +129,6 @@
Returns the transform matrix for an area.
</description>
</method>
- <method name="area_is_ray_pickable" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="area" type="RID">
- </argument>
- <description>
- If [code]true[/code], area collides with rays.
- </description>
- </method>
<method name="area_remove_shape">
<return type="void">
</return>
@@ -421,12 +412,7 @@
<method name="body_create">
<return type="RID">
</return>
- <argument index="0" name="mode" type="int" enum="PhysicsServer3D.BodyMode" default="2">
- </argument>
- <argument index="1" name="init_sleeping" type="bool" default="false">
- </argument>
<description>
- Creates a physics body. The first parameter can be any value from [enum BodyMode] constants, for the type of body created. Additionally, the body can be created in sleeping state to save processing time.
</description>
</method>
<method name="body_get_collision_layer" qualifiers="const">
@@ -582,15 +568,6 @@
Returns whether a body uses a callback function to calculate its own physics (see [method body_set_force_integration_callback]).
</description>
</method>
- <method name="body_is_ray_pickable" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="body" type="RID">
- </argument>
- <description>
- If [code]true[/code], the body can be detected by rays.
- </description>
- </method>
<method name="body_remove_collision_exception">
<return type="void">
</return>
@@ -815,6 +792,24 @@
Sets a body state (see [enum BodyState] constants).
</description>
</method>
+ <method name="box_shape_create">
+ <return type="RID">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="capsule_shape_create">
+ <return type="RID">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="concave_polygon_shape_create">
+ <return type="RID">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="cone_twist_joint_get_param" qualifiers="const">
<return type="float">
</return>
@@ -839,6 +834,24 @@
Sets a cone_twist_joint parameter (see [enum ConeTwistJointParam] constants).
</description>
</method>
+ <method name="convex_polygon_shape_create">
+ <return type="RID">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="custom_shape_create">
+ <return type="RID">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="cylinder_shape_create">
+ <return type="RID">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="free_rid">
<return type="void">
</return>
@@ -848,7 +861,7 @@
Destroys any of the objects created by PhysicsServer3D. If the [RID] passed is not one of the objects that can be created by PhysicsServer3D, an error will be sent to the console.
</description>
</method>
- <method name="generic_6dof_joint_get_flag">
+ <method name="generic_6dof_joint_get_flag" qualifiers="const">
<return type="bool">
</return>
<argument index="0" name="joint" type="RID">
@@ -861,7 +874,7 @@
Gets a generic_6_DOF_joint flag (see [enum G6DOFJointAxisFlag] constants).
</description>
</method>
- <method name="generic_6dof_joint_get_param">
+ <method name="generic_6dof_joint_get_param" qualifiers="const">
<return type="float">
</return>
<argument index="0" name="joint" type="RID">
@@ -913,6 +926,12 @@
Returns an Info defined by the [enum ProcessInfo] input given.
</description>
</method>
+ <method name="heightmap_shape_create">
+ <return type="RID">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="hinge_joint_get_flag" qualifiers="const">
<return type="bool">
</return>
@@ -961,97 +980,116 @@
Sets a hinge_joint parameter (see [enum HingeJointParam] constants).
</description>
</method>
- <method name="joint_create_cone_twist">
- <return type="RID">
+ <method name="joint_clear">
+ <return type="void">
</return>
- <argument index="0" name="body_A" type="RID">
- </argument>
- <argument index="1" name="local_ref_A" type="Transform">
- </argument>
- <argument index="2" name="body_B" type="RID">
- </argument>
- <argument index="3" name="local_ref_B" type="Transform">
+ <argument index="0" name="joint" type="RID">
</argument>
<description>
- Creates a [ConeTwistJoint3D].
</description>
</method>
- <method name="joint_create_generic_6dof">
+ <method name="joint_create">
<return type="RID">
</return>
- <argument index="0" name="body_A" type="RID">
- </argument>
- <argument index="1" name="local_ref_A" type="Transform">
- </argument>
- <argument index="2" name="body_B" type="RID">
+ <description>
+ </description>
+ </method>
+ <method name="joint_get_solver_priority" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="joint" type="RID">
</argument>
- <argument index="3" name="local_ref_B" type="Transform">
+ <description>
+ Gets the priority value of the Joint3D.
+ </description>
+ </method>
+ <method name="joint_get_type" qualifiers="const">
+ <return type="int" enum="PhysicsServer3D.JointType">
+ </return>
+ <argument index="0" name="joint" type="RID">
</argument>
<description>
- Creates a [Generic6DOFJoint3D].
+ Returns the type of the Joint3D.
</description>
</method>
- <method name="joint_create_hinge">
- <return type="RID">
+ <method name="joint_make_cone_twist">
+ <return type="void">
</return>
- <argument index="0" name="body_A" type="RID">
+ <argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="hinge_A" type="Transform">
+ <argument index="1" name="body_A" type="RID">
</argument>
- <argument index="2" name="body_B" type="RID">
+ <argument index="2" name="local_ref_A" type="Transform">
</argument>
- <argument index="3" name="hinge_B" type="Transform">
+ <argument index="3" name="body_B" type="RID">
+ </argument>
+ <argument index="4" name="local_ref_B" type="Transform">
</argument>
<description>
- Creates a [HingeJoint3D].
</description>
</method>
- <method name="joint_create_pin">
- <return type="RID">
+ <method name="joint_make_generic_6dof">
+ <return type="void">
</return>
- <argument index="0" name="body_A" type="RID">
+ <argument index="0" name="joint" type="RID">
</argument>
- <argument index="1" name="local_A" type="Vector3">
+ <argument index="1" name="body_A" type="RID">
+ </argument>
+ <argument index="2" name="local_ref_A" type="Transform">
</argument>
- <argument index="2" name="body_B" type="RID">
+ <argument index="3" name="body_B" type="RID">
</argument>
- <argument index="3" name="local_B" type="Vector3">
+ <argument index="4" name="local_ref_B" type="Transform">
</argument>
<description>
- Creates a [PinJoint3D].
</description>
</method>
- <method name="joint_create_slider">
- <return type="RID">
+ <method name="joint_make_hinge">
+ <return type="void">
</return>
- <argument index="0" name="body_A" type="RID">
+ <argument index="0" name="joint" type="RID">
+ </argument>
+ <argument index="1" name="body_A" type="RID">
</argument>
- <argument index="1" name="local_ref_A" type="Transform">
+ <argument index="2" name="hinge_A" type="Transform">
</argument>
- <argument index="2" name="body_B" type="RID">
+ <argument index="3" name="body_B" type="RID">
</argument>
- <argument index="3" name="local_ref_B" type="Transform">
+ <argument index="4" name="hinge_B" type="Transform">
</argument>
<description>
- Creates a [SliderJoint3D].
</description>
</method>
- <method name="joint_get_solver_priority" qualifiers="const">
- <return type="int">
+ <method name="joint_make_pin">
+ <return type="void">
</return>
<argument index="0" name="joint" type="RID">
</argument>
+ <argument index="1" name="body_A" type="RID">
+ </argument>
+ <argument index="2" name="local_A" type="Vector3">
+ </argument>
+ <argument index="3" name="body_B" type="RID">
+ </argument>
+ <argument index="4" name="local_B" type="Vector3">
+ </argument>
<description>
- Gets the priority value of the Joint3D.
</description>
</method>
- <method name="joint_get_type" qualifiers="const">
- <return type="int" enum="PhysicsServer3D.JointType">
+ <method name="joint_make_slider">
+ <return type="void">
</return>
<argument index="0" name="joint" type="RID">
</argument>
+ <argument index="1" name="body_A" type="RID">
+ </argument>
+ <argument index="2" name="local_ref_A" type="Transform">
+ </argument>
+ <argument index="3" name="body_B" type="RID">
+ </argument>
+ <argument index="4" name="local_ref_B" type="Transform">
+ </argument>
<description>
- Returns the type of the Joint3D.
</description>
</method>
<method name="joint_set_solver_priority">
@@ -1129,22 +1167,25 @@
Sets a pin_joint parameter (see [enum PinJointParam] constants).
</description>
</method>
- <method name="set_active">
- <return type="void">
+ <method name="plane_shape_create">
+ <return type="RID">
</return>
- <argument index="0" name="active" type="bool">
- </argument>
<description>
- Activates or deactivates the 3D physics engine.
</description>
</method>
- <method name="shape_create">
+ <method name="ray_shape_create">
<return type="RID">
</return>
- <argument index="0" name="type" type="int" enum="PhysicsServer3D.ShapeType">
+ <description>
+ </description>
+ </method>
+ <method name="set_active">
+ <return type="void">
+ </return>
+ <argument index="0" name="active" type="bool">
</argument>
<description>
- Creates a shape of a type from [enum ShapeType]. Does not assign it to a body or an area. To do so, you must use [method area_set_shape] or [method body_set_shape].
+ Activates or deactivates the 3D physics engine.
</description>
</method>
<method name="shape_get_data" qualifiers="const">
@@ -1260,23 +1301,32 @@
Sets the value for a space parameter. A list of available parameters is on the [enum SpaceParameter] constants.
</description>
</method>
+ <method name="sphere_shape_create">
+ <return type="RID">
+ </return>
+ <description>
+ </description>
+ </method>
</methods>
<constants>
- <constant name="JOINT_PIN" value="0" enum="JointType">
+ <constant name="JOINT_TYPE_PIN" value="0" enum="JointType">
The [Joint3D] is a [PinJoint3D].
</constant>
- <constant name="JOINT_HINGE" value="1" enum="JointType">
+ <constant name="JOINT_TYPE_HINGE" value="1" enum="JointType">
The [Joint3D] is a [HingeJoint3D].
</constant>
- <constant name="JOINT_SLIDER" value="2" enum="JointType">
+ <constant name="JOINT_TYPE_SLIDER" value="2" enum="JointType">
The [Joint3D] is a [SliderJoint3D].
</constant>
- <constant name="JOINT_CONE_TWIST" value="3" enum="JointType">
+ <constant name="JOINT_TYPE_CONE_TWIST" value="3" enum="JointType">
The [Joint3D] is a [ConeTwistJoint3D].
</constant>
- <constant name="JOINT_6DOF" value="4" enum="JointType">
+ <constant name="JOINT_TYPE_6DOF" value="4" enum="JointType">
The [Joint3D] is a [Generic6DOFJoint3D].
</constant>
+ <constant name="JOINT_TYPE_MAX" value="5" enum="JointType">
+ Represents the size of the [enum JointType] enum.
+ </constant>
<constant name="PIN_JOINT_BIAS" value="0" enum="PinJointParam">
The strength with which the pinned objects try to stay in positional relation to each other.
The higher, the stronger.
diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml
index e3242512c4..ed96f753c2 100644
--- a/doc/classes/Plane.xml
+++ b/doc/classes/Plane.xml
@@ -142,7 +142,7 @@
<argument index="0" name="to_plane" type="Plane">
</argument>
<description>
- Returns [code]true[/code] if this plane and [code]plane[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component.
+ Returns [code]true[/code] if this plane and [code]plane[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
<method name="is_point_over">
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 04798c04e9..51ec509a14 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -205,8 +205,10 @@
</return>
<argument index="0" name="label" type="String" default="&quot;&quot;">
</argument>
+ <argument index="1" name="id" type="int" default="-1">
+ </argument>
<description>
- Adds a separator between items. Separators also occupy an index.
+ Adds a separator between items. Separators also occupy an index, which you can set by using the [code]id[/code] parameter.
A [code]label[/code] can optionally be provided, which will appear at the center of the separator.
</description>
</method>
@@ -715,19 +717,22 @@
<theme_item name="font" type="Font">
[Font] used for the menu items.
</theme_item>
+ <theme_item name="font_accelerator_color" type="Color" default="Color( 0.7, 0.7, 0.7, 0.8 )">
+ The text [Color] used for shortcuts and accelerators that show next to the menu item name when defined. See [method get_item_accelerator] for more info on accelerators.
+ </theme_item>
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
The default text [Color] for menu items' names.
</theme_item>
- <theme_item name="font_color_accel" type="Color" default="Color( 0.7, 0.7, 0.7, 0.8 )">
- The text [Color] used for shortcuts and accelerators that show next to the menu item name when defined. See [method get_item_accelerator] for more info on accelerators.
- </theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 0.4, 0.4, 0.4, 0.8 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 0.4, 0.4, 0.4, 0.8 )">
[Color] used for disabled menu items' text.
</theme_item>
- <theme_item name="font_color_hover" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
+ <theme_item name="font_hover_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
[Color] used for the hovered text.
</theme_item>
- <theme_item name="font_color_separator" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the menu item.
+ </theme_item>
+ <theme_item name="font_separator_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
[Color] used for labeled separators' text. See [method add_separator].
</theme_item>
<theme_item name="font_size" type="int">
@@ -739,12 +744,19 @@
<theme_item name="hseparation" type="int" default="4">
The horizontal space between the item's name and the shortcut text/submenu arrow.
</theme_item>
+ <theme_item name="item_end_padding" type="int" default="2">
+ </theme_item>
+ <theme_item name="item_start_padding" type="int" default="2">
+ </theme_item>
<theme_item name="labeled_separator_left" type="StyleBox">
[StyleBox] for the left side of labeled separator. See [method add_separator].
</theme_item>
<theme_item name="labeled_separator_right" type="StyleBox">
[StyleBox] for the right side of labeled separator. See [method add_separator].
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the item text outline.
+ </theme_item>
<theme_item name="panel" type="StyleBox">
Default [StyleBox] of the [PopupMenu] items.
</theme_item>
diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml
index c05cbf4413..160b61c720 100644
--- a/doc/classes/ProgressBar.xml
+++ b/doc/classes/ProgressBar.xml
@@ -32,11 +32,17 @@
<theme_item name="font_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
The color of the text.
</theme_item>
- <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [ProgressBar].
+ </theme_item>
+ <theme_item name="font_shadow_color" type="Color" default="Color( 0, 0, 0, 1 )">
The color of the text's shadow.
</theme_item>
<theme_item name="font_size" type="int">
Font size used to draw the fill percentage if [member percent_visible] is [code]true[/code].
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index e856d1ea9c..ac63c5da79 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -169,6 +169,7 @@
</return>
<description>
Saves the configuration to the [code]project.godot[/code] file.
+ [b]Note:[/b] This method is intended to be used by editor plugins, as modified [ProjectSettings] can't be loaded back in the running app. If you want to change project settings in exported projects, use [method save_custom] to save [code]override.cfg[/code] file.
</description>
</method>
<method name="save_custom">
@@ -177,7 +178,7 @@
<argument index="0" name="file" type="String">
</argument>
<description>
- Saves the configuration to a custom file. The file extension must be [code].godot[/code] (to save in text-based [ConfigFile] format) or [code].binary[/code] (to save in binary format).
+ Saves the configuration to a custom file. The file extension must be [code].godot[/code] (to save in text-based [ConfigFile] format) or [code].binary[/code] (to save in binary format). You can also save [code]override.cfg[/code] file, which is also text, but can be used in exported projects unlike other formats.
</description>
</method>
<method name="set_initial_value">
@@ -273,9 +274,11 @@
If [code]true[/code], flushes the standard output stream every time a line is printed. This affects both terminal logging and file logging.
When running a project, this setting must be enabled if you want logs to be collected by service managers such as systemd/journalctl. This setting is disabled by default on release builds, since flushing on every printed line will negatively affect performance if lots of lines are printed in a rapid succession. Also, if this setting is enabled, logged files will still be written successfully if the application crashes or is otherwise killed by the user (without being closed "normally").
[b]Note:[/b] Regardless of this setting, the standard error stream ([code]stderr[/code]) is always flushed when a line is printed to it.
+ Changes to this setting will only be applied upon restarting the application.
</member>
<member name="application/run/flush_stdout_on_print.debug" type="bool" setter="" getter="" default="true">
Debug build override for [member application/run/flush_stdout_on_print], as performance is less important during debugging.
+ Changes to this setting will only be applied upon restarting the application.
</member>
<member name="application/run/frame_delay_msec" type="int" setter="" getter="" default="0">
Forces a delay between frames in the main loop (in milliseconds). This may be useful if you plan to disable vertical synchronization.
@@ -289,31 +292,31 @@
<member name="application/run/main_scene" type="String" setter="" getter="" default="&quot;&quot;">
Path to the main scene file that will be loaded when the project runs.
</member>
- <member name="audio/channel_disable_threshold_db" type="float" setter="" getter="" default="-60.0">
+ <member name="audio/buses/channel_disable_threshold_db" type="float" setter="" getter="" default="-60.0">
Audio buses will disable automatically when sound goes below a given dB threshold for a given time. This saves CPU as effects assigned to that bus will no longer do any processing.
</member>
- <member name="audio/channel_disable_time" type="float" setter="" getter="" default="2.0">
+ <member name="audio/buses/channel_disable_time" type="float" setter="" getter="" default="2.0">
Audio buses will disable automatically when sound goes below a given dB threshold for a given time. This saves CPU as effects assigned to that bus will no longer do any processing.
</member>
- <member name="audio/default_bus_layout" type="String" setter="" getter="" default="&quot;res://default_bus_layout.tres&quot;">
+ <member name="audio/buses/default_bus_layout" type="String" setter="" getter="" default="&quot;res://default_bus_layout.tres&quot;">
Default [AudioBusLayout] resource file to use in the project, unless overridden by the scene.
</member>
- <member name="audio/driver" type="String" setter="" getter="">
+ <member name="audio/driver/driver" type="String" setter="" getter="">
Specifies the audio driver to use. This setting is platform-dependent as each platform supports different audio drivers. If left empty, the default audio driver will be used.
</member>
- <member name="audio/enable_audio_input" type="bool" setter="" getter="" default="false">
+ <member name="audio/driver/enable_input" type="bool" setter="" getter="" default="false">
If [code]true[/code], microphone input will be allowed. This requires appropriate permissions to be set when exporting to Android or iOS.
</member>
- <member name="audio/mix_rate" type="int" setter="" getter="" default="44100">
+ <member name="audio/driver/mix_rate" type="int" setter="" getter="" default="44100">
Mixing rate used for audio. In general, it's better to not touch this and leave it to the host operating system.
</member>
- <member name="audio/output_latency" type="int" setter="" getter="" default="15">
+ <member name="audio/driver/output_latency" type="int" setter="" getter="" default="15">
Output latency in milliseconds for audio. Lower values will result in lower audio latency at the cost of increased CPU usage. Low values may result in audible cracking on slower hardware.
</member>
- <member name="audio/output_latency.web" type="int" setter="" getter="" default="50">
- Safer override for [member audio/output_latency] in the Web platform, to avoid audio issues especially on mobile devices.
+ <member name="audio/driver/output_latency.web" type="int" setter="" getter="" default="50">
+ Safer override for [member audio/driver/output_latency] in the Web platform, to avoid audio issues especially on mobile devices.
</member>
- <member name="audio/video_delay_compensation_ms" type="int" setter="" getter="" default="0">
+ <member name="audio/video/video_delay_compensation_ms" type="int" setter="" getter="" default="0">
Setting to hardcode audio delay when playing video. Best to leave this untouched unless you know what you are doing.
</member>
<member name="compression/formats/gzip/compression_level" type="int" setter="" getter="" default="-1">
@@ -331,6 +334,18 @@
<member name="compression/formats/zstd/window_log_size" type="int" setter="" getter="" default="27">
Largest size limit (in power of 2) allowed when compressing using long-distance matching with Zstandard. Higher values can result in better compression, but will require more memory when compressing and decompressing.
</member>
+ <member name="debug/file_logging/enable_file_logging" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], logs all output to files.
+ </member>
+ <member name="debug/file_logging/enable_file_logging.pc" type="bool" setter="" getter="" default="true">
+ Desktop override for [member debug/file_logging/enable_file_logging], as log files are not readily accessible on mobile/Web platforms.
+ </member>
+ <member name="debug/file_logging/log_path" type="String" setter="" getter="" default="&quot;user://logs/godot.log&quot;">
+ Path to logs within the project. Using an [code]user://[/code] path is recommended.
+ </member>
+ <member name="debug/file_logging/max_log_files" type="int" setter="" getter="" default="5">
+ Specifies the maximum amount of log files allowed (used for rotation).
+ </member>
<member name="debug/gdscript/completion/autocomplete_setters_and_getters" type="bool" setter="" getter="" default="false">
If [code]true[/code], displays getters and setters in autocompletion results in the script editor. This setting is meant to be used when porting old projects (Godot 2), as using member variables is the preferred style from Godot 3 onwards.
</member>
@@ -448,10 +463,13 @@
<member name="debug/shapes/collision/contact_color" type="Color" setter="" getter="" default="Color( 1, 0.2, 0.1, 0.8 )">
Color of the contact points between collision shapes, visible when "Visible Collision Shapes" is enabled in the Debug menu.
</member>
+ <member name="debug/shapes/collision/draw_2d_outlines" type="bool" setter="" getter="" default="true">
+ Sets whether 2D physics will display collision outlines in game when "Visible Collision Shapes" is enabled in the Debug menu.
+ </member>
<member name="debug/shapes/collision/max_contacts_displayed" type="int" setter="" getter="" default="10000">
Maximum number of contact points between collision shapes to display when "Visible Collision Shapes" is enabled in the Debug menu.
</member>
- <member name="debug/shapes/collision/shape_color" type="Color" setter="" getter="" default="Color( 0, 0.6, 0.7, 0.5 )">
+ <member name="debug/shapes/collision/shape_color" type="Color" setter="" getter="" default="Color( 0, 0.6, 0.7, 0.42 )">
Color of the collision shapes, visible when "Visible Collision Shapes" is enabled in the Debug menu.
</member>
<member name="debug/shapes/navigation/disabled_geometry_color" type="Color" setter="" getter="" default="Color( 1, 0.7, 0.1, 0.4 )">
@@ -470,14 +488,11 @@
Position offset for tooltips, relative to the mouse cursor's hotspot.
</member>
<member name="display/window/dpi/allow_hidpi" type="bool" setter="" getter="" default="false">
- If [code]true[/code], allows HiDPI display on Windows and macOS. This setting has no effect on desktop Linux, as DPI-awareness fallbacks are not supported there.
+ If [code]true[/code], allows HiDPI display on Windows, macOS, and the HTML5 platform. This setting has no effect on desktop Linux, as DPI-awareness fallbacks are not supported there.
</member>
<member name="display/window/energy_saving/keep_screen_on" type="bool" setter="" getter="" default="true">
If [code]true[/code], keeps the screen on (even in case of inactivity), so the screensaver does not take over. Works on desktop and mobile platforms.
</member>
- <member name="display/window/force_right_to_left_layout_direction" type="bool" setter="" getter="" default="false">
- Force layout direction and text writing direction to RTL for all locales.
- </member>
<member name="display/window/handheld/orientation" type="String" setter="" getter="" default="&quot;landscape&quot;">
Default orientation on mobile devices.
</member>
@@ -513,12 +528,6 @@
<member name="display/window/size/width" type="int" setter="" getter="" default="1024">
Sets the game's main viewport width. On desktop platforms, this is the default window size. Stretch mode settings also use this as a reference when enabled.
</member>
- <member name="display/window/tablet_driver" type="String" setter="" getter="">
- Specifies the tablet driver to use. If left empty, the default driver will be used.
- </member>
- <member name="display/window/text_name" type="String" setter="" getter="" default="&quot;&quot;">
- Specifies the [TextServer] to use. If left empty, the default will be used.
- </member>
<member name="display/window/vsync/use_vsync" type="bool" setter="" getter="" default="true">
If [code]true[/code], enables vertical synchronization. This eliminates tearing that may appear in moving scenes, at the cost of higher input latency and stuttering at lower framerates. If [code]false[/code], vertical synchronization will be disabled, however, many platforms will enforce it regardless (such as mobile platforms and HTML5).
</member>
@@ -526,12 +535,18 @@
If [code]Use Vsync[/code] is enabled and this setting is [code]true[/code], enables vertical synchronization via the operating system's window compositor when in windowed mode and the compositor is enabled. This will prevent stutter in certain situations. (Windows only.)
[b]Note:[/b] This option is experimental and meant to alleviate stutter experienced by some users. However, some users have experienced a Vsync framerate halving (e.g. from 60 FPS to 30 FPS) when using it.
</member>
- <member name="editor/script_templates_search_path" type="String" setter="" getter="" default="&quot;res://script_templates&quot;">
- Search path for project-specific script templates. Godot will search for script templates both in the editor-specific path and in this project-specific path.
+ <member name="editor/node_naming/name_casing" type="int" setter="" getter="" default="0">
+ When creating node names automatically, set the type of casing in this project. This is mostly an editor setting.
</member>
- <member name="editor/search_in_file_extensions" type="PackedStringArray" setter="" getter="" default="PackedStringArray( &quot;gd&quot;, &quot;shader&quot; )">
+ <member name="editor/node_naming/name_num_separator" type="int" setter="" getter="" default="0">
+ What to use to separate node name from number. This is mostly an editor setting.
+ </member>
+ <member name="editor/script/search_in_file_extensions" type="PackedStringArray" setter="" getter="" default="PackedStringArray( &quot;gd&quot;, &quot;shader&quot; )">
Text-based file extensions to include in the script editor's "Find in Files" feature. You can add e.g. [code]tscn[/code] if you wish to also parse your scene files, especially if you use built-in scripts which are serialized in the scene files.
</member>
+ <member name="editor/script/templates_search_path" type="String" setter="" getter="" default="&quot;res://script_templates&quot;">
+ Search path for project-specific script templates. Godot will search for script templates both in the editor-specific path and in this project-specific path.
+ </member>
<member name="gui/common/default_scroll_deadzone" type="int" setter="" getter="" default="0">
Default value for [member ScrollContainer.scroll_deadzone], which will be used for all [ScrollContainer]s unless overridden.
</member>
@@ -566,6 +581,10 @@
Default [InputEventAction] to discard a modal or pending input.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
+ <member name="input/ui_copy" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_cut" type="Dictionary" setter="" getter="">
+ </member>
<member name="input/ui_down" type="Dictionary" setter="" getter="">
Default [InputEventAction] to move down in the UI.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
@@ -574,6 +593,12 @@
Default [InputEventAction] to go to the end position of a [Control] (e.g. last item in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_END] on typical desktop UI systems.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
+ <member name="input/ui_filedialog_refresh" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_filedialog_show_hidden" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_filedialog_up_one_level" type="Dictionary" setter="" getter="">
+ </member>
<member name="input/ui_focus_next" type="Dictionary" setter="" getter="">
Default [InputEventAction] to focus the next [Control] in the scene. The focus behavior can be configured via [member Control.focus_next].
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
@@ -582,6 +607,10 @@
Default [InputEventAction] to focus the previous [Control] in the scene. The focus behavior can be configured via [member Control.focus_previous].
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
+ <member name="input/ui_graph_delete" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_graph_duplicate" type="Dictionary" setter="" getter="">
+ </member>
<member name="input/ui_home" type="Dictionary" setter="" getter="">
Default [InputEventAction] to go to the start position of a [Control] (e.g. first item in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_HOME] on typical desktop UI systems.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
@@ -590,6 +619,8 @@
Default [InputEventAction] to move left in the UI.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
+ <member name="input/ui_menu" type="Dictionary" setter="" getter="">
+ </member>
<member name="input/ui_page_down" type="Dictionary" setter="" getter="">
Default [InputEventAction] to go down a page in a [Control] (e.g. in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_PAGEDOWN] on typical desktop UI systems.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
@@ -598,6 +629,10 @@
Default [InputEventAction] to go up a page in a [Control] (e.g. in an [ItemList] or a [Tree]), matching the behavior of [constant KEY_PAGEUP] on typical desktop UI systems.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
+ <member name="input/ui_paste" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_redo" type="Dictionary" setter="" getter="">
+ </member>
<member name="input/ui_right" type="Dictionary" setter="" getter="">
Default [InputEventAction] to move right in the UI.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
@@ -606,10 +641,102 @@
Default [InputEventAction] to select an item in a [Control] (e.g. in an [ItemList] or a [Tree]).
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
+ <member name="input/ui_swap_input_direction" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_backspace" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_backspace_all_to_left" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_backspace_all_to_left.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_backspace_word" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_backspace_word.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_document_end" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_document_end.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_document_start" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_document_start.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_down" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_left" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_line_end" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_line_end.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_line_start" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_line_start.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_page_down" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_page_up" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_right" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_up" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_word_left" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_word_left.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_word_right" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_caret_word_right.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_completion_accept" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_completion_query" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_dedent" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_delete" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_delete_all_to_right" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_delete_all_to_right.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_delete_word" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_delete_word.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_indent" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_newline" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_newline_above" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_newline_blank" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_scroll_down" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_scroll_down.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_scroll_up" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_scroll_up.OSX" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_select_all" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_text_toggle_insert_mode" type="Dictionary" setter="" getter="">
+ </member>
+ <member name="input/ui_undo" type="Dictionary" setter="" getter="">
+ </member>
<member name="input/ui_up" type="Dictionary" setter="" getter="">
Default [InputEventAction] to move up in the UI.
[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified.
</member>
+ <member name="input_devices/pen_tablet/driver" type="String" setter="" getter="">
+ Specifies the tablet driver to use. If left empty, the default driver will be used.
+ </member>
+ <member name="input_devices/pen_tablet/driver.windows" type="String" setter="" getter="">
+ Override for [member input_devices/pen_tablet/driver] on Windows.
+ </member>
<member name="input_devices/pointing/emulate_mouse_from_touch" type="bool" setter="" getter="" default="true">
If [code]true[/code], sends mouse input events when tapping or swiping on the touchscreen.
</member>
@@ -619,262 +746,377 @@
<member name="input_devices/pointing/ios/touch_delay" type="float" setter="" getter="" default="0.15">
Default delay for touch events. This only affects iOS devices.
</member>
+ <member name="internationalization/locale/fallback" type="String" setter="" getter="" default="&quot;en&quot;">
+ The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used.
+ </member>
+ <member name="internationalization/locale/test" type="String" setter="" getter="" default="&quot;&quot;">
+ If non-empty, this locale will be used when running the project from the editor.
+ </member>
+ <member name="internationalization/rendering/force_right_to_left_layout_direction" type="bool" setter="" getter="" default="false">
+ Force layout direction and text writing direction to RTL for all locales.
+ </member>
+ <member name="internationalization/rendering/text_driver" type="String" setter="" getter="" default="&quot;&quot;">
+ Specifies the [TextServer] to use. If left empty, the default will be used.
+ </member>
+ <member name="layer_names/2d_navigation/layer_0" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 0. If left empty, the layer will display as "Layer 0".
+ </member>
+ <member name="layer_names/2d_navigation/layer_1" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 1. If left empty, the layer will display as "Layer 1".
+ </member>
+ <member name="layer_names/2d_navigation/layer_10" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 10. If left empty, the layer will display as "Layer 10".
+ </member>
+ <member name="layer_names/2d_navigation/layer_11" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 11. If left empty, the layer will display as "Layer 11".
+ </member>
+ <member name="layer_names/2d_navigation/layer_12" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 12. If left empty, the layer will display as "Layer 12".
+ </member>
+ <member name="layer_names/2d_navigation/layer_13" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 13. If left empty, the layer will display as "Layer 13".
+ </member>
+ <member name="layer_names/2d_navigation/layer_14" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 14. If left empty, the layer will display as "Layer 14".
+ </member>
+ <member name="layer_names/2d_navigation/layer_15" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 15. If left empty, the layer will display as "Layer 15".
+ </member>
+ <member name="layer_names/2d_navigation/layer_16" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 16. If left empty, the layer will display as "Layer 16".
+ </member>
+ <member name="layer_names/2d_navigation/layer_17" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 17. If left empty, the layer will display as "Layer 17".
+ </member>
+ <member name="layer_names/2d_navigation/layer_18" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 18. If left empty, the layer will display as "Layer 18".
+ </member>
+ <member name="layer_names/2d_navigation/layer_19" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 19. If left empty, the layer will display as "Layer 19".
+ </member>
+ <member name="layer_names/2d_navigation/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 2. If left empty, the layer will display as "Layer 2".
+ </member>
+ <member name="layer_names/2d_navigation/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 3. If left empty, the layer will display as "Layer 3".
+ </member>
+ <member name="layer_names/2d_navigation/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 4. If left empty, the layer will display as "Layer 4".
+ </member>
+ <member name="layer_names/2d_navigation/layer_5" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 5. If left empty, the layer will display as "Layer 5".
+ </member>
+ <member name="layer_names/2d_navigation/layer_6" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 6. If left empty, the layer will display as "Layer 6".
+ </member>
+ <member name="layer_names/2d_navigation/layer_7" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 7. If left empty, the layer will display as "Layer 7".
+ </member>
+ <member name="layer_names/2d_navigation/layer_8" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 8. If left empty, the layer will display as "Layer 8".
+ </member>
+ <member name="layer_names/2d_navigation/layer_9" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D navigation layer 9. If left empty, the layer will display as "Layer 9".
+ </member>
+ <member name="layer_names/2d_physics/layer_0" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D physics layer 0. If left empty, the layer will display as "Layer 0".
+ </member>
<member name="layer_names/2d_physics/layer_1" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 1.
+ Optional name for the 2D physics layer 1. If left empty, the layer will display as "Layer 1".
</member>
<member name="layer_names/2d_physics/layer_10" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 10.
+ Optional name for the 2D physics layer 10. If left empty, the layer will display as "Layer 10".
</member>
<member name="layer_names/2d_physics/layer_11" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 11.
+ Optional name for the 2D physics layer 11. If left empty, the layer will display as "Layer 11".
</member>
<member name="layer_names/2d_physics/layer_12" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 12.
+ Optional name for the 2D physics layer 12. If left empty, the layer will display as "Layer 12".
</member>
<member name="layer_names/2d_physics/layer_13" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 13.
+ Optional name for the 2D physics layer 13. If left empty, the layer will display as "Layer 13".
</member>
<member name="layer_names/2d_physics/layer_14" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 14.
+ Optional name for the 2D physics layer 14. If left empty, the layer will display as "Layer 14".
</member>
<member name="layer_names/2d_physics/layer_15" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 15.
+ Optional name for the 2D physics layer 15. If left empty, the layer will display as "Layer 15".
</member>
<member name="layer_names/2d_physics/layer_16" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 16.
+ Optional name for the 2D physics layer 16. If left empty, the layer will display as "Layer 16".
</member>
<member name="layer_names/2d_physics/layer_17" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 17.
+ Optional name for the 2D physics layer 17. If left empty, the layer will display as "Layer 17".
</member>
<member name="layer_names/2d_physics/layer_18" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 18.
+ Optional name for the 2D physics layer 18. If left empty, the layer will display as "Layer 18".
</member>
<member name="layer_names/2d_physics/layer_19" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 19.
+ Optional name for the 2D physics layer 19. If left empty, the layer will display as "Layer 19".
</member>
<member name="layer_names/2d_physics/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 2.
- </member>
- <member name="layer_names/2d_physics/layer_20" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 20.
+ Optional name for the 2D physics layer 2. If left empty, the layer will display as "Layer 2".
</member>
<member name="layer_names/2d_physics/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 3.
+ Optional name for the 2D physics layer 3. If left empty, the layer will display as "Layer 3".
</member>
<member name="layer_names/2d_physics/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 4.
+ Optional name for the 2D physics layer 4. If left empty, the layer will display as "Layer 4".
</member>
<member name="layer_names/2d_physics/layer_5" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 5.
+ Optional name for the 2D physics layer 5. If left empty, the layer will display as "Layer 5".
</member>
<member name="layer_names/2d_physics/layer_6" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 6.
+ Optional name for the 2D physics layer 6. If left empty, the layer will display as "Layer 6".
</member>
<member name="layer_names/2d_physics/layer_7" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 7.
+ Optional name for the 2D physics layer 7. If left empty, the layer will display as "Layer 7".
</member>
<member name="layer_names/2d_physics/layer_8" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 8.
+ Optional name for the 2D physics layer 8. If left empty, the layer will display as "Layer 8".
</member>
<member name="layer_names/2d_physics/layer_9" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D physics layer 9.
+ Optional name for the 2D physics layer 9. If left empty, the layer will display as "Layer 9".
+ </member>
+ <member name="layer_names/2d_render/layer_0" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D render layer 0. If left empty, the layer will display as "Layer 0".
</member>
<member name="layer_names/2d_render/layer_1" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 1.
+ Optional name for the 2D render layer 1. If left empty, the layer will display as "Layer 1".
</member>
<member name="layer_names/2d_render/layer_10" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 10.
+ Optional name for the 2D render layer 10. If left empty, the layer will display as "Layer 10".
</member>
<member name="layer_names/2d_render/layer_11" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 11.
+ Optional name for the 2D render layer 11. If left empty, the layer will display as "Layer 11".
</member>
<member name="layer_names/2d_render/layer_12" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 12.
+ Optional name for the 2D render layer 12. If left empty, the layer will display as "Layer 12".
</member>
<member name="layer_names/2d_render/layer_13" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 13.
+ Optional name for the 2D render layer 13. If left empty, the layer will display as "Layer 13".
</member>
<member name="layer_names/2d_render/layer_14" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 14.
+ Optional name for the 2D render layer 14. If left empty, the layer will display as "Layer 14".
</member>
<member name="layer_names/2d_render/layer_15" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 15.
+ Optional name for the 2D render layer 15. If left empty, the layer will display as "Layer 15".
</member>
<member name="layer_names/2d_render/layer_16" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 16.
+ Optional name for the 2D render layer 16. If left empty, the layer will display as "Layer 16".
</member>
<member name="layer_names/2d_render/layer_17" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 17.
+ Optional name for the 2D render layer 17. If left empty, the layer will display as "Layer 17".
</member>
<member name="layer_names/2d_render/layer_18" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 18.
+ Optional name for the 2D render layer 18. If left empty, the layer will display as "Layer 18".
</member>
<member name="layer_names/2d_render/layer_19" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 19.
+ Optional name for the 2D render layer 19. If left empty, the layer will display as "Layer 19".
</member>
<member name="layer_names/2d_render/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 2.
- </member>
- <member name="layer_names/2d_render/layer_20" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 20.
+ Optional name for the 2D render layer 2. If left empty, the layer will display as "Layer 2".
</member>
<member name="layer_names/2d_render/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 3.
+ Optional name for the 2D render layer 3. If left empty, the layer will display as "Layer 3".
</member>
<member name="layer_names/2d_render/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 4.
+ Optional name for the 2D render layer 4. If left empty, the layer will display as "Layer 4".
</member>
<member name="layer_names/2d_render/layer_5" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 5.
+ Optional name for the 2D render layer 5. If left empty, the layer will display as "Layer 5".
</member>
<member name="layer_names/2d_render/layer_6" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 6.
+ Optional name for the 2D render layer 6. If left empty, the layer will display as "Layer 6".
</member>
<member name="layer_names/2d_render/layer_7" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 7.
+ Optional name for the 2D render layer 7. If left empty, the layer will display as "Layer 7".
</member>
<member name="layer_names/2d_render/layer_8" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 8.
+ Optional name for the 2D render layer 8. If left empty, the layer will display as "Layer 8".
</member>
<member name="layer_names/2d_render/layer_9" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 2D render layer 9.
+ Optional name for the 2D render layer 9. If left empty, the layer will display as "Layer 9".
+ </member>
+ <member name="layer_names/3d_navigation/layer_0" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 0. If left empty, the layer will display as "Layer 0".
+ </member>
+ <member name="layer_names/3d_navigation/layer_1" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 1. If left empty, the layer will display as "Layer 1".
+ </member>
+ <member name="layer_names/3d_navigation/layer_10" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 10. If left empty, the layer will display as "Layer 10".
+ </member>
+ <member name="layer_names/3d_navigation/layer_11" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 11. If left empty, the layer will display as "Layer 11".
+ </member>
+ <member name="layer_names/3d_navigation/layer_12" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 12. If left empty, the layer will display as "Layer 12".
+ </member>
+ <member name="layer_names/3d_navigation/layer_13" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 13. If left empty, the layer will display as "Layer 13".
+ </member>
+ <member name="layer_names/3d_navigation/layer_14" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 14. If left empty, the layer will display as "Layer 14".
+ </member>
+ <member name="layer_names/3d_navigation/layer_15" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 15. If left empty, the layer will display as "Layer 15".
+ </member>
+ <member name="layer_names/3d_navigation/layer_16" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 16. If left empty, the layer will display as "Layer 16".
+ </member>
+ <member name="layer_names/3d_navigation/layer_17" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 17. If left empty, the layer will display as "Layer 17".
+ </member>
+ <member name="layer_names/3d_navigation/layer_18" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 18. If left empty, the layer will display as "Layer 18".
+ </member>
+ <member name="layer_names/3d_navigation/layer_19" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 19. If left empty, the layer will display as "Layer 19".
+ </member>
+ <member name="layer_names/3d_navigation/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 2. If left empty, the layer will display as "Layer 2".
+ </member>
+ <member name="layer_names/3d_navigation/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 3. If left empty, the layer will display as "Layer 3".
+ </member>
+ <member name="layer_names/3d_navigation/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 4. If left empty, the layer will display as "Layer 4".
+ </member>
+ <member name="layer_names/3d_navigation/layer_5" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 5. If left empty, the layer will display as "Layer 5".
+ </member>
+ <member name="layer_names/3d_navigation/layer_6" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 6. If left empty, the layer will display as "Layer 6".
+ </member>
+ <member name="layer_names/3d_navigation/layer_7" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 7. If left empty, the layer will display as "Layer 7".
+ </member>
+ <member name="layer_names/3d_navigation/layer_8" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 8. If left empty, the layer will display as "Layer 8".
+ </member>
+ <member name="layer_names/3d_navigation/layer_9" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D navigation layer 9. If left empty, the layer will display as "Layer 9".
+ </member>
+ <member name="layer_names/3d_physics/layer_0" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 3D physics layer 0. If left empty, the layer will display as "Layer 0".
</member>
<member name="layer_names/3d_physics/layer_1" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 1.
+ Optional name for the 3D physics layer 1. If left empty, the layer will display as "Layer 1".
</member>
<member name="layer_names/3d_physics/layer_10" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 10.
+ Optional name for the 3D physics layer 10. If left empty, the layer will display as "Layer 10".
</member>
<member name="layer_names/3d_physics/layer_11" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 11.
+ Optional name for the 3D physics layer 11. If left empty, the layer will display as "Layer 11".
</member>
<member name="layer_names/3d_physics/layer_12" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 12.
+ Optional name for the 3D physics layer 12. If left empty, the layer will display as "Layer 12".
</member>
<member name="layer_names/3d_physics/layer_13" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 13.
+ Optional name for the 3D physics layer 13. If left empty, the layer will display as "Layer 13".
</member>
<member name="layer_names/3d_physics/layer_14" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 14.
+ Optional name for the 3D physics layer 14. If left empty, the layer will display as "Layer 14".
</member>
<member name="layer_names/3d_physics/layer_15" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 15.
+ Optional name for the 3D physics layer 15. If left empty, the layer will display as "Layer 15".
</member>
<member name="layer_names/3d_physics/layer_16" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 16.
+ Optional name for the 3D physics layer 16. If left empty, the layer will display as "Layer 16".
</member>
<member name="layer_names/3d_physics/layer_17" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 17.
+ Optional name for the 3D physics layer 17. If left empty, the layer will display as "Layer 17".
</member>
<member name="layer_names/3d_physics/layer_18" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 18.
+ Optional name for the 3D physics layer 18. If left empty, the layer will display as "Layer 18".
</member>
<member name="layer_names/3d_physics/layer_19" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 19.
+ Optional name for the 3D physics layer 19. If left empty, the layer will display as "Layer 19".
</member>
<member name="layer_names/3d_physics/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 2.
- </member>
- <member name="layer_names/3d_physics/layer_20" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 20.
+ Optional name for the 3D physics layer 2. If left empty, the layer will display as "Layer 2".
</member>
<member name="layer_names/3d_physics/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 3.
+ Optional name for the 3D physics layer 3. If left empty, the layer will display as "Layer 3".
</member>
<member name="layer_names/3d_physics/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 4.
+ Optional name for the 3D physics layer 4. If left empty, the layer will display as "Layer 4".
</member>
<member name="layer_names/3d_physics/layer_5" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 5.
+ Optional name for the 3D physics layer 5. If left empty, the layer will display as "Layer 5".
</member>
<member name="layer_names/3d_physics/layer_6" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 6.
+ Optional name for the 3D physics layer 6. If left empty, the layer will display as "Layer 6".
</member>
<member name="layer_names/3d_physics/layer_7" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 7.
+ Optional name for the 3D physics layer 7. If left empty, the layer will display as "Layer 7".
</member>
<member name="layer_names/3d_physics/layer_8" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 8.
+ Optional name for the 3D physics layer 8. If left empty, the layer will display as "Layer 8".
</member>
<member name="layer_names/3d_physics/layer_9" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D physics layer 9.
+ Optional name for the 3D physics layer 9. If left empty, the layer will display as "Layer 9".
+ </member>
+ <member name="layer_names/3d_render/layer_0" type="String" setter="" getter="" default="&quot;&quot;">
+ Optional name for the 2D render layer 0. If left empty, the layer will display as "Layer 0".
</member>
<member name="layer_names/3d_render/layer_1" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 1.
+ Optional name for the 3D render layer 1. If left empty, the layer will display as "Layer 1".
</member>
<member name="layer_names/3d_render/layer_10" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 10.
+ Optional name for the 3D render layer 10. If left empty, the layer will display as "Layer 10".
</member>
<member name="layer_names/3d_render/layer_11" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 11.
+ Optional name for the 3D render layer 11. If left empty, the layer will display as "Layer 11".
</member>
<member name="layer_names/3d_render/layer_12" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 12.
+ Optional name for the 3D render layer 12. If left empty, the layer will display as "Layer 12".
</member>
<member name="layer_names/3d_render/layer_13" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 13.
+ Optional name for the 3D render layer 13. If left empty, the layer will display as "Layer 13".
</member>
<member name="layer_names/3d_render/layer_14" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 14
+ Optional name for the 3D render layer 14. If left empty, the layer will display as "Layer 14"
</member>
<member name="layer_names/3d_render/layer_15" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 15.
+ Optional name for the 3D render layer 15. If left empty, the layer will display as "Layer 15".
</member>
<member name="layer_names/3d_render/layer_16" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 16.
+ Optional name for the 3D render layer 16. If left empty, the layer will display as "Layer 16".
</member>
<member name="layer_names/3d_render/layer_17" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 17.
+ Optional name for the 3D render layer 17. If left empty, the layer will display as "Layer 17".
</member>
<member name="layer_names/3d_render/layer_18" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 18.
+ Optional name for the 3D render layer 18. If left empty, the layer will display as "Layer 18".
</member>
<member name="layer_names/3d_render/layer_19" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 19.
+ Optional name for the 3D render layer 19. If left empty, the layer will display as "Layer 19".
</member>
<member name="layer_names/3d_render/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 2.
- </member>
- <member name="layer_names/3d_render/layer_20" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 20.
+ Optional name for the 3D render layer 2. If left empty, the layer will display as "Layer 2".
</member>
<member name="layer_names/3d_render/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 3.
+ Optional name for the 3D render layer 3. If left empty, the layer will display as "Layer 3".
</member>
<member name="layer_names/3d_render/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 4.
+ Optional name for the 3D render layer 4. If left empty, the layer will display as "Layer 4".
</member>
<member name="layer_names/3d_render/layer_5" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 5.
+ Optional name for the 3D render layer 5. If left empty, the layer will display as "Layer 5".
</member>
<member name="layer_names/3d_render/layer_6" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 6.
+ Optional name for the 3D render layer 6. If left empty, the layer will display as "Layer 6".
</member>
<member name="layer_names/3d_render/layer_7" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 7.
+ Optional name for the 3D render layer 7. If left empty, the layer will display as "Layer 7".
</member>
<member name="layer_names/3d_render/layer_8" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 8.
+ Optional name for the 3D render layer 8. If left empty, the layer will display as "Layer 8".
</member>
<member name="layer_names/3d_render/layer_9" type="String" setter="" getter="" default="&quot;&quot;">
- Optional name for the 3D render layer 9.
- </member>
- <member name="locale/fallback" type="String" setter="" getter="" default="&quot;en&quot;">
- The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used.
- </member>
- <member name="locale/test" type="String" setter="" getter="" default="&quot;&quot;">
- If non-empty, this locale will be used when running the project from the editor.
- </member>
- <member name="logging/file_logging/enable_file_logging" type="bool" setter="" getter="" default="false">
- If [code]true[/code], logs all output to files.
- </member>
- <member name="logging/file_logging/enable_file_logging.pc" type="bool" setter="" getter="" default="true">
- </member>
- <member name="logging/file_logging/log_path" type="String" setter="" getter="" default="&quot;user://logs/godot.log&quot;">
- Path to logs within the project. Using an [code]user://[/code] path is recommended.
- </member>
- <member name="logging/file_logging/max_log_files" type="int" setter="" getter="" default="5">
- Specifies the maximum amount of log files allowed (used for rotation).
+ Optional name for the 3D render layer 9. If left empty, the layer will display as "Layer 9".
</member>
<member name="memory/limits/command_queue/multithreading_queue_size_kb" type="int" setter="" getter="" default="256">
</member>
@@ -898,6 +1140,18 @@
</member>
<member name="mono/unhandled_exception_policy" type="int" setter="" getter="" default="0">
</member>
+ <member name="navigation/2d/default_cell_size" type="int" setter="" getter="" default="10">
+ Default cell size for 2D navigation maps. See [method NavigationServer2D.map_set_cell_size].
+ </member>
+ <member name="navigation/2d/default_edge_connection_margin" type="int" setter="" getter="" default="100">
+ Default edge connection margin for 2D navigation maps. See [method NavigationServer2D.map_set_edge_connection_margin].
+ </member>
+ <member name="navigation/3d/default_cell_size" type="float" setter="" getter="" default="0.3">
+ Default cell size for 3D navigation maps. See [method NavigationServer3D.map_set_cell_size].
+ </member>
+ <member name="navigation/3d/default_edge_connection_margin" type="float" setter="" getter="" default="5.0">
+ Default edge connection margin for 3D navigation maps. See [method NavigationServer3D.map_set_edge_connection_margin].
+ </member>
<member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="32768">
Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
</member>
@@ -929,12 +1183,6 @@
The CA certificates bundle to use for SSL connections. If this is set to a non-empty value, this will [i]override[/i] Godot's default [url=https://github.com/godotengine/godot/blob/master/thirdparty/certs/ca-certificates.crt]Mozilla certificate bundle[/url]. If left empty, the default certificate bundle will be used.
If in doubt, leave this setting empty.
</member>
- <member name="node/name_casing" type="int" setter="" getter="" default="0">
- When creating node names automatically, set the type of casing in this project. This is mostly an editor setting.
- </member>
- <member name="node/name_num_separator" type="int" setter="" getter="" default="0">
- What to use to separate node name from number. This is mostly an editor setting.
- </member>
<member name="physics/2d/bp_hash_table_size" type="int" setter="" getter="" default="4096">
Size of the hash table used for the broad-phase 2D hash grid algorithm.
</member>
@@ -984,22 +1232,18 @@
Sets which physics engine to use for 2D physics.
"DEFAULT" and "GodotPhysics2D" are the same, as there is currently no alternative 2D physics server implemented.
</member>
+ <member name="physics/2d/run_on_thread" type="bool" setter="" getter="" default="false">
+ Sets whether 2D physics is run on the main thread or a separate one. Running the server on a thread increases performance, but restricts API access to only physics process.
+ </member>
<member name="physics/2d/sleep_threshold_angular" type="float" setter="" getter="" default="0.139626">
Threshold angular velocity under which a 2D physics body will be considered inactive. See [constant PhysicsServer2D.SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD].
</member>
<member name="physics/2d/sleep_threshold_linear" type="float" setter="" getter="" default="2.0">
Threshold linear velocity under which a 2D physics body will be considered inactive. See [constant PhysicsServer2D.SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD].
</member>
- <member name="physics/2d/thread_model" type="int" setter="" getter="" default="1">
- Sets whether physics is run on the main thread or a separate one. Running the server on a thread increases performance, but restricts API access to only physics process.
- [b]Warning:[/b] As of Godot 3.2, there are mixed reports about the use of a Multi-Threaded thread model for physics. Be sure to assess whether it does give you extra performance and no regressions when using it.
- </member>
<member name="physics/2d/time_before_sleep" type="float" setter="" getter="" default="0.5">
Time (in seconds) of inactivity before which a 2D physics body will put to sleep. See [constant PhysicsServer2D.SPACE_PARAM_BODY_TIME_TO_SLEEP].
</member>
- <member name="physics/3d/active_soft_world" type="bool" setter="" getter="" default="true">
- Sets whether the 3D physics world will be created with support for [SoftBody3D] physics. Only applies to the Bullet physics engine.
- </member>
<member name="physics/3d/default_angular_damp" type="float" setter="" getter="" default="0.1">
The default angular damp in 3D.
[b]Note:[/b] Good values are in the range [code]0[/code] to [code]1[/code]. At value [code]0[/code] objects will keep moving with the same velocity. Values greater than [code]1[/code] will aim to reduce the velocity to [code]0[/code] in less than a second e.g. a value of [code]2[/code] will aim to reduce the velocity to [code]0[/code] in half a second. A value equal to or greater than the physics frame rate ([member ProjectSettings.physics/common/physics_fps], [code]60[/code] by default) will bring the object to a stop in one iteration.
@@ -1040,6 +1284,15 @@
Sets which physics engine to use for 3D physics.
"DEFAULT" is currently the [url=https://bulletphysics.org]Bullet[/url] physics engine. The "GodotPhysics3D" engine is still supported as an alternative.
</member>
+ <member name="physics/3d/run_on_thread" type="bool" setter="" getter="" default="false">
+ Sets whether 3D physics is run on the main thread or a separate one. Running the server on a thread increases performance, but restricts API access to only physics process.
+ </member>
+ <member name="physics/3d/sleep_threshold_angular" type="float" setter="" getter="" default="0.139626">
+ </member>
+ <member name="physics/3d/sleep_threshold_linear" type="float" setter="" getter="" default="0.1">
+ </member>
+ <member name="physics/3d/time_before_sleep" type="float" setter="" getter="" default="0.5">
+ </member>
<member name="physics/common/enable_object_picking" type="bool" setter="" getter="" default="true">
Enables [member Viewport.physics_object_picking] on the root viewport.
</member>
@@ -1051,261 +1304,269 @@
Fix to improve physics jitter, specially on monitors where refresh rate is different than the physics FPS.
[b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_jitter_fix] instead.
</member>
- <member name="rendering/environment/default_clear_color" type="Color" setter="" getter="" default="Color( 0.3, 0.3, 0.3, 1 )">
- Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method RenderingServer.set_default_clear_color].
+ <member name="rendering/2d/sdf/oversize" type="int" setter="" getter="" default="1">
</member>
- <member name="rendering/environment/default_environment" type="String" setter="" getter="" default="&quot;&quot;">
- [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here.
+ <member name="rendering/2d/sdf/scale" type="int" setter="" getter="" default="1">
</member>
- <member name="rendering/gpu_lightmapper/performance/max_rays_per_pass" type="int" setter="" getter="" default="32">
+ <member name="rendering/2d/shadow_atlas/size" type="int" setter="" getter="" default="2048">
</member>
- <member name="rendering/gpu_lightmapper/performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64">
+ <member name="rendering/2d/snap/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false">
</member>
- <member name="rendering/gpu_lightmapper/performance/region_size" type="int" setter="" getter="" default="512">
+ <member name="rendering/2d/snap/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false">
</member>
- <member name="rendering/gpu_lightmapper/quality/high_quality_probe_ray_count" type="int" setter="" getter="" default="512">
+ <member name="rendering/anti_aliasing/quality/msaa" type="int" setter="" getter="" default="0">
+ Sets the number of MSAA samples to use (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware.
</member>
- <member name="rendering/gpu_lightmapper/quality/high_quality_ray_count" type="int" setter="" getter="" default="256">
+ <member name="rendering/anti_aliasing/quality/screen_space_aa" type="int" setter="" getter="" default="0">
+ Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry.
+ Another way to combat specular aliasing is to enable [member rendering/anti_aliasing/screen_space_roughness_limiter/enabled].
</member>
- <member name="rendering/gpu_lightmapper/quality/low_quality_probe_ray_count" type="int" setter="" getter="" default="64">
+ <member name="rendering/anti_aliasing/quality/use_debanding" type="bool" setter="" getter="" default="false">
</member>
- <member name="rendering/gpu_lightmapper/quality/low_quality_ray_count" type="int" setter="" getter="" default="16">
+ <member name="rendering/anti_aliasing/screen_space_roughness_limiter/amount" type="float" setter="" getter="" default="0.25">
</member>
- <member name="rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count" type="int" setter="" getter="" default="256">
+ <member name="rendering/anti_aliasing/screen_space_roughness_limiter/enabled" type="bool" setter="" getter="" default="true">
</member>
- <member name="rendering/gpu_lightmapper/quality/medium_quality_ray_count" type="int" setter="" getter="" default="64">
+ <member name="rendering/anti_aliasing/screen_space_roughness_limiter/limit" type="float" setter="" getter="" default="0.18">
</member>
- <member name="rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count" type="int" setter="" getter="" default="2048">
+ <member name="rendering/camera/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2">
+ Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother.
</member>
- <member name="rendering/gpu_lightmapper/quality/ultra_quality_ray_count" type="int" setter="" getter="" default="1024">
+ <member name="rendering/camera/depth_of_field/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1">
+ Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the fastest. Circle is the most realistic, but also the most expensive to compute.
</member>
- <member name="rendering/high_end/global_shader_variables_buffer_size" type="int" setter="" getter="" default="65536">
+ <member name="rendering/camera/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples.
</member>
- <member name="rendering/lightmapper/probe_capture_update_speed" type="float" setter="" getter="" default="15">
+ <member name="rendering/driver/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default="&quot;PowerVR,Mali,Adreno,Apple&quot;">
+ Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this.
</member>
- <member name="rendering/limits/rendering/max_renderable_elements" type="int" setter="" getter="" default="128000">
- Max amount of elements renderable in a frame. If more than this are visible per frame, they will be dropped. Keep in mind elements refer to mesh surfaces and not meshes themselves.
+ <member name="rendering/driver/depth_prepass/enable" type="bool" setter="" getter="" default="true">
+ If [code]true[/code], performs a previous depth pass before rendering materials. This increases performance in scenes with high overdraw, when complex materials and lighting are used.
</member>
- <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600">
+ <member name="rendering/driver/driver_name" type="String" setter="" getter="" default="&quot;Vulkan&quot;">
+ The video driver to use (currently only "Vulkan" is implemented).
+ [b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument.
+ [b]FIXME:[/b] No longer valid after DisplayServer split:
+ In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time.
</member>
- <member name="rendering/quality/2d/snap_2d_transforms_to_pixel" type="bool" setter="" getter="" default="false">
+ <member name="rendering/driver/rd_renderer/use_low_end_renderer" type="bool" setter="" getter="" default="false">
</member>
- <member name="rendering/quality/2d/snap_2d_vertices_to_pixel" type="bool" setter="" getter="" default="false">
+ <member name="rendering/driver/rd_renderer/use_low_end_renderer.mobile" type="bool" setter="" getter="" default="true">
</member>
- <member name="rendering/quality/2d_sdf/oversize" type="int" setter="" getter="" default="1">
+ <member name="rendering/driver/threads/thread_model" type="int" setter="" getter="" default="1">
+ Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter.
</member>
- <member name="rendering/quality/2d_sdf/scale" type="int" setter="" getter="" default="1">
+ <member name="rendering/environment/defaults/default_clear_color" type="Color" setter="" getter="" default="Color( 0.3, 0.3, 0.3, 1 )">
+ Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method RenderingServer.set_default_clear_color].
</member>
- <member name="rendering/quality/2d_shadow_atlas/size" type="int" setter="" getter="" default="2048">
+ <member name="rendering/environment/defaults/default_environment" type="String" setter="" getter="" default="&quot;&quot;">
+ [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here.
</member>
- <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2">
- Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother.
+ <member name="rendering/environment/glow/upscale_mode" type="int" setter="" getter="" default="1">
+ Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth.
</member>
- <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1">
- Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the fastest. Circle is the most realistic, but also the most expensive to compute.
+ <member name="rendering/environment/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/environment/glow/upscale_mode] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/quality/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
- If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples.
+ <member name="rendering/environment/glow/use_high_quality" type="bool" setter="" getter="" default="false">
+ Takes more samples during downsample pass of glow. This ensures that single pixels are captured by glow which makes the glow look smoother and more stable during movement. However, it is very expensive and makes the glow post process take twice as long.
</member>
- <member name="rendering/quality/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default="&quot;PowerVR,Mali,Adreno,Apple&quot;">
- Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this.
+ <member name="rendering/environment/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1">
+ Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better.
</member>
- <member name="rendering/quality/depth_prepass/enable" type="bool" setter="" getter="" default="true">
- If [code]true[/code], performs a previous depth pass before rendering materials. This increases performance in scenes with high overdraw, when complex materials and lighting are used.
+ <member name="rendering/environment/ssao/adaptive_target" type="float" setter="" getter="" default="0.5">
+ Quality target to use when [member rendering/environment/ssao/quality] is set to [code]ULTRA[/code]. A value of [code]0.0[/code] provides a quality and speed similar to [code]MEDIUM[/code] while a value of [code]1.0[/code] provides much higher quality than any of the other settings at the cost of performance.
</member>
- <member name="rendering/quality/directional_shadow/size" type="int" setter="" getter="" default="4096">
- The directional shadow's size in pixels. Higher values will result in sharper shadows, at the cost of performance. The value will be rounded up to the nearest power of 2.
+ <member name="rendering/environment/ssao/blur_passes" type="int" setter="" getter="" default="2">
+ Number of blur passes to use when computing screen-space ambient occlusion. A higher number will result in a smoother look, but will be slower to compute and will have less high-frequency detail.
</member>
- <member name="rendering/quality/directional_shadow/size.mobile" type="int" setter="" getter="" default="2048">
- Lower-end override for [member rendering/quality/directional_shadow/size] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/environment/ssao/fadeout_from" type="float" setter="" getter="" default="50.0">
+ Distance at which the screen-space ambient occlusion effect starts to fade out. Use this hide ambient occlusion at great distances.
</member>
- <member name="rendering/quality/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="2">
- Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
+ <member name="rendering/environment/ssao/fadeout_to" type="float" setter="" getter="" default="300.0">
+ Distance at which the screen-space ambient occlusion is fully faded out. Use this hide ambient occlusion at great distances.
</member>
- <member name="rendering/quality/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
- Lower-end override for [member rendering/quality/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/environment/ssao/half_size" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details.
</member>
- <member name="rendering/quality/driver/driver_name" type="String" setter="" getter="" default="&quot;Vulkan&quot;">
- The video driver to use ("GLES2" or "Vulkan").
- [b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument.
- [b]FIXME:[/b] No longer valid after DisplayServer split:
- In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time.
+ <member name="rendering/environment/ssao/half_size.mobile" type="bool" setter="" getter="" default="true">
+ Lower-end override for [member rendering/environment/ssao/half_size] on mobile devices, due to performance concerns.
</member>
- <member name="rendering/quality/gi_probes/anisotropic" type="bool" setter="" getter="" default="false">
- If [code]true[/code], take additional samples when rendering objects affected by a [GIProbe] to reduce artifacts from only sampling in one direction.
+ <member name="rendering/environment/ssao/quality" type="int" setter="" getter="" default="2">
+ Sets the quality of the screen-space ambient occlusion effect. Higher values take more samples and so will result in better quality, at the cost of performance. Setting to [code]ULTRA[/code] will use the [member rendering/environment/ssao/adaptive_target] setting.
</member>
- <member name="rendering/quality/gi_probes/quality" type="int" setter="" getter="" default="1">
- Sets the number of cone samples taken when rendering objects affected by [GIProbe]s.
+ <member name="rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale" type="float" setter="" getter="" default="0.01">
+ Scales the depth over which the subsurface scattering effect is applied. A high value may allow light to scatter into a part of the mesh or another mesh that is close in screen space but far in depth.
</member>
- <member name="rendering/quality/glow/upscale_mode" type="int" setter="" getter="" default="1">
- Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth.
+ <member name="rendering/environment/subsurface_scattering/subsurface_scattering_quality" type="int" setter="" getter="" default="1">
+ Sets the quality of the subsurface scattering effect. Higher values are slower but look nicer.
</member>
- <member name="rendering/quality/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0">
- Lower-end override for [member rendering/quality/glow/upscale_mode] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/environment/subsurface_scattering/subsurface_scattering_scale" type="float" setter="" getter="" default="0.05">
+ Scales the distance over which samples are taken for subsurface scattering effect. Changing this does not impact performance, but higher values will result in significant artifacts as the samples will become obviously spread out. A lower value results in a smaller spread of scattered light.
</member>
- <member name="rendering/quality/glow/use_high_quality" type="bool" setter="" getter="" default="false">
- Takes more samples during downsample pass of glow. This ensures that single pixels are captured by glow which makes the glow look smoother and more stable during movement. However, it is very expensive and makes the glow post process take twice as long.
+ <member name="rendering/environment/volumetric_fog/use_filter" type="int" setter="" getter="" default="1">
</member>
- <member name="rendering/quality/intended_usage/framebuffer_allocation" type="int" setter="" getter="" default="2">
- Strategy used for framebuffer allocation. The simpler it is, the less resources it uses (but the less features it supports). If set to "2D Without Sampling" or "3D Without Effects", sample buffers will not be allocated. This means [code]SCREEN_TEXTURE[/code] and [code]DEPTH_TEXTURE[/code] will not be available in shaders and post-processing effects will not be available in the [Environment].
+ <member name="rendering/environment/volumetric_fog/volume_depth" type="int" setter="" getter="" default="128">
</member>
- <member name="rendering/quality/intended_usage/framebuffer_allocation.mobile" type="int" setter="" getter="" default="3">
- Lower-end override for [member rendering/quality/intended_usage/framebuffer_allocation] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/environment/volumetric_fog/volume_size" type="int" setter="" getter="" default="64">
</member>
- <member name="rendering/quality/reflection_atlas/reflection_count" type="int" setter="" getter="" default="64">
- Number of cubemaps to store in the reflection atlas. The number of [ReflectionProbe]s in a scene will be limited by this amount. A higher number requires more VRAM.
+ <member name="rendering/global_illumination/gi/use_half_resolution" type="bool" setter="" getter="" default="false">
</member>
- <member name="rendering/quality/reflection_atlas/reflection_size" type="int" setter="" getter="" default="256">
- Size of cubemap faces for [ReflectionProbe]s. A higher number requires more VRAM and may make reflection probe updating slower.
+ <member name="rendering/global_illumination/gi_probes/anisotropic" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], take additional samples when rendering objects affected by a [GIProbe] to reduce artifacts from only sampling in one direction.
</member>
- <member name="rendering/quality/reflection_atlas/reflection_size.mobile" type="int" setter="" getter="" default="128">
- Lower-end override for [member rendering/quality/reflection_atlas/reflection_size] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/global_illumination/gi_probes/quality" type="int" setter="" getter="" default="1">
+ Sets the number of cone samples taken when rendering objects affected by [GIProbe]s.
</member>
- <member name="rendering/quality/reflections/fast_filter_high_quality" type="bool" setter="" getter="" default="false">
- Use a higher quality variant of the fast filtering algorithm. Significantly slower than using default quality, but results in smoother reflections. Should only be used when the scene is especially detailed.
+ <member name="rendering/global_illumination/sdfgi/frames_to_converge" type="int" setter="" getter="" default="4">
</member>
- <member name="rendering/quality/reflections/ggx_samples" type="int" setter="" getter="" default="1024">
- Sets the number of samples to take when using importance sampling for [Sky]s and [ReflectionProbe]s. A higher value will result in smoother, higher quality reflections, but increases time to calculate radiance maps. In general, fewer samples are needed for simpler, low dynamic range environments while more samples are needed for HDR environments and environments with a high level of detail.
+ <member name="rendering/global_illumination/sdfgi/frames_to_update_lights" type="int" setter="" getter="" default="2">
</member>
- <member name="rendering/quality/reflections/ggx_samples.mobile" type="int" setter="" getter="" default="128">
- Lower-end override for [member rendering/quality/reflections/ggx_samples] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/global_illumination/sdfgi/probe_ray_count" type="int" setter="" getter="" default="1">
</member>
- <member name="rendering/quality/reflections/roughness_layers" type="int" setter="" getter="" default="8">
- Limits the number of layers to use in radiance maps when using importance sampling. A lower number will be slightly faster and take up less VRAM.
+ <member name="rendering/lightmapping/bake_performance/max_rays_per_pass" type="int" setter="" getter="" default="32">
</member>
- <member name="rendering/quality/reflections/texture_array_reflections" type="bool" setter="" getter="" default="true">
- If [code]true[/code], uses texture arrays instead of mipmaps for reflection probes and panorama backgrounds (sky). This reduces jitter noise and upscaling artifacts on reflections, but is significantly slower to compute and uses [member rendering/quality/reflections/roughness_layers] times more memory.
+ <member name="rendering/lightmapping/bake_performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64">
</member>
- <member name="rendering/quality/reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false">
- Lower-end override for [member rendering/quality/reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/lightmapping/bake_performance/region_size" type="int" setter="" getter="" default="512">
</member>
- <member name="rendering/quality/screen_filters/msaa" type="int" setter="" getter="" default="0">
- Sets the number of MSAA samples to use (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware.
- [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend.
+ <member name="rendering/lightmapping/bake_quality/high_quality_probe_ray_count" type="int" setter="" getter="" default="512">
</member>
- <member name="rendering/quality/screen_filters/screen_space_aa" type="int" setter="" getter="" default="0">
- Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry.
- Another way to combat specular aliasing is to enable [member rendering/quality/screen_filters/screen_space_roughness_limiter_enabled].
+ <member name="rendering/lightmapping/bake_quality/high_quality_ray_count" type="int" setter="" getter="" default="256">
</member>
- <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_amount" type="float" setter="" getter="" default="0.25">
+ <member name="rendering/lightmapping/bake_quality/low_quality_probe_ray_count" type="int" setter="" getter="" default="64">
</member>
- <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_enabled" type="bool" setter="" getter="" default="true">
+ <member name="rendering/lightmapping/bake_quality/low_quality_ray_count" type="int" setter="" getter="" default="16">
</member>
- <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_limit" type="float" setter="" getter="" default="0.18">
+ <member name="rendering/lightmapping/bake_quality/medium_quality_probe_ray_count" type="int" setter="" getter="" default="256">
</member>
- <member name="rendering/quality/screen_filters/use_debanding" type="bool" setter="" getter="" default="false">
+ <member name="rendering/lightmapping/bake_quality/medium_quality_ray_count" type="int" setter="" getter="" default="64">
</member>
- <member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1">
- Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better.
+ <member name="rendering/lightmapping/bake_quality/ultra_quality_probe_ray_count" type="int" setter="" getter="" default="2048">
</member>
- <member name="rendering/quality/shading/force_blinn_over_ggx" type="bool" setter="" getter="" default="false">
- If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model.
+ <member name="rendering/lightmapping/bake_quality/ultra_quality_ray_count" type="int" setter="" getter="" default="1024">
</member>
- <member name="rendering/quality/shading/force_blinn_over_ggx.mobile" type="bool" setter="" getter="" default="true">
- Lower-end override for [member rendering/quality/shading/force_blinn_over_ggx] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/lightmapping/probe_capture/update_speed" type="float" setter="" getter="" default="15">
</member>
- <member name="rendering/quality/shading/force_lambert_over_burley" type="bool" setter="" getter="" default="false">
- If [code]true[/code], uses faster but lower-quality Lambert material lighting model instead of Burley.
+ <member name="rendering/limits/cluster_builder/max_clustered_elements" type="float" setter="" getter="" default="512">
</member>
- <member name="rendering/quality/shading/force_lambert_over_burley.mobile" type="bool" setter="" getter="" default="true">
- Lower-end override for [member rendering/quality/shading/force_lambert_over_burley] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/limits/forward_renderer/threaded_render_minimum_instances" type="int" setter="" getter="" default="500">
</member>
- <member name="rendering/quality/shading/force_vertex_shading" type="bool" setter="" getter="" default="false">
- If [code]true[/code], forces vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can be used to optimize performance on low-end mobile devices.
+ <member name="rendering/limits/global_shader_variables/buffer_size" type="int" setter="" getter="" default="65536">
</member>
- <member name="rendering/quality/shading/force_vertex_shading.mobile" type="bool" setter="" getter="" default="true">
- Lower-end override for [member rendering/quality/shading/force_vertex_shading] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/limits/spatial_indexer/threaded_cull_minimum_instances" type="int" setter="" getter="" default="1000">
</member>
- <member name="rendering/quality/shadow_atlas/quadrant_0_subdiv" type="int" setter="" getter="" default="1">
- Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
+ <member name="rendering/limits/spatial_indexer/update_iterations_per_frame" type="int" setter="" getter="" default="10">
</member>
- <member name="rendering/quality/shadow_atlas/quadrant_1_subdiv" type="int" setter="" getter="" default="2">
- Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
+ <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600">
</member>
- <member name="rendering/quality/shadow_atlas/quadrant_2_subdiv" type="int" setter="" getter="" default="3">
- Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
+ <member name="rendering/mesh_lod/lod_change/threshold_pixels" type="float" setter="" getter="" default="1.0">
</member>
- <member name="rendering/quality/shadow_atlas/quadrant_3_subdiv" type="int" setter="" getter="" default="4">
- Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
+ <member name="rendering/reflections/reflection_atlas/reflection_count" type="int" setter="" getter="" default="64">
+ Number of cubemaps to store in the reflection atlas. The number of [ReflectionProbe]s in a scene will be limited by this amount. A higher number requires more VRAM.
</member>
- <member name="rendering/quality/shadow_atlas/size" type="int" setter="" getter="" default="4096">
- Size for shadow atlas (used for OmniLights and SpotLights). See documentation.
+ <member name="rendering/reflections/reflection_atlas/reflection_size" type="int" setter="" getter="" default="256">
+ Size of cubemap faces for [ReflectionProbe]s. A higher number requires more VRAM and may make reflection probe updating slower.
</member>
- <member name="rendering/quality/shadow_atlas/size.mobile" type="int" setter="" getter="" default="2048">
- Lower-end override for [member rendering/quality/shadow_atlas/size] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/reflections/reflection_atlas/reflection_size.mobile" type="int" setter="" getter="" default="128">
+ Lower-end override for [member rendering/reflections/reflection_atlas/reflection_size] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/quality/shadows/soft_shadow_quality" type="int" setter="" getter="" default="2">
- Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
+ <member name="rendering/reflections/sky_reflections/fast_filter_high_quality" type="bool" setter="" getter="" default="false">
+ Use a higher quality variant of the fast filtering algorithm. Significantly slower than using default quality, but results in smoother reflections. Should only be used when the scene is especially detailed.
</member>
- <member name="rendering/quality/shadows/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
- Lower-end override for [member rendering/quality/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
+ <member name="rendering/reflections/sky_reflections/ggx_samples" type="int" setter="" getter="" default="1024">
+ Sets the number of samples to take when using importance sampling for [Sky]s and [ReflectionProbe]s. A higher value will result in smoother, higher quality reflections, but increases time to calculate radiance maps. In general, fewer samples are needed for simpler, low dynamic range environments while more samples are needed for HDR environments and environments with a high level of detail.
</member>
- <member name="rendering/quality/ssao/adaptive_target" type="float" setter="" getter="" default="0.5">
- Quality target to use when [member rendering/quality/ssao/quality] is set to [code]ULTRA[/code]. A value of [code]0.0[/code] provides a quality and speed similar to [code]MEDIUM[/code] while a value of [code]1.0[/code] provides much higher quality than any of the other settings at the cost of performance.
+ <member name="rendering/reflections/sky_reflections/ggx_samples.mobile" type="int" setter="" getter="" default="128">
+ Lower-end override for [member rendering/reflections/sky_reflections/ggx_samples] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/quality/ssao/blur_passes" type="int" setter="" getter="" default="2">
- Number of blur passes to use when computing screen-space ambient occlusion. A higher number will result in a smoother look, but will be slower to compute and will have less high-frequency detail.
+ <member name="rendering/reflections/sky_reflections/roughness_layers" type="int" setter="" getter="" default="8">
+ Limits the number of layers to use in radiance maps when using importance sampling. A lower number will be slightly faster and take up less VRAM.
</member>
- <member name="rendering/quality/ssao/fadeout_from" type="float" setter="" getter="" default="50.0">
- Distance at which the screen-space ambient occlusion effect starts to fade out. Use this hide ambient occlusion at great distances.
+ <member name="rendering/reflections/sky_reflections/texture_array_reflections" type="bool" setter="" getter="" default="true">
+ If [code]true[/code], uses texture arrays instead of mipmaps for reflection probes and panorama backgrounds (sky). This reduces jitter noise and upscaling artifacts on reflections, but is significantly slower to compute and uses [member rendering/reflections/sky_reflections/roughness_layers] times more memory.
</member>
- <member name="rendering/quality/ssao/fadeout_to" type="float" setter="" getter="" default="300.0">
- Distance at which the screen-space ambient occlusion is fully faded out. Use this hide ambient occlusion at great distances.
+ <member name="rendering/reflections/sky_reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false">
+ Lower-end override for [member rendering/reflections/sky_reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/quality/ssao/half_size" type="bool" setter="" getter="" default="false">
- If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details.
+ <member name="rendering/shading/overrides/force_blinn_over_ggx" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model.
</member>
- <member name="rendering/quality/ssao/half_size.mobile" type="bool" setter="" getter="" default="true">
- Lower-end override for [member rendering/quality/ssao/half_size] on mobile devices, due to performance concerns.
+ <member name="rendering/shading/overrides/force_blinn_over_ggx.mobile" type="bool" setter="" getter="" default="true">
+ Lower-end override for [member rendering/shading/overrides/force_blinn_over_ggx] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/quality/ssao/quality" type="int" setter="" getter="" default="2">
- Sets the quality of the screen-space ambient occlusion effect. Higher values take more samples and so will result in better quality, at the cost of performance. Setting to [code]ULTRA[/code] will use the [member rendering/quality/ssao/adaptive_target] setting.
+ <member name="rendering/shading/overrides/force_lambert_over_burley" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], uses faster but lower-quality Lambert material lighting model instead of Burley.
</member>
- <member name="rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale" type="float" setter="" getter="" default="0.01">
- Scales the depth over which the subsurface scattering effect is applied. A high value may allow light to scatter into a part of the mesh or another mesh that is close in screen space but far in depth.
+ <member name="rendering/shading/overrides/force_lambert_over_burley.mobile" type="bool" setter="" getter="" default="true">
+ Lower-end override for [member rendering/shading/overrides/force_lambert_over_burley] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/quality/subsurface_scattering/subsurface_scattering_quality" type="int" setter="" getter="" default="1">
- Sets the quality of the subsurface scattering effect. Higher values are slower but look nicer.
+ <member name="rendering/shading/overrides/force_vertex_shading" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], forces vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can be used to optimize performance on low-end mobile devices.
</member>
- <member name="rendering/quality/subsurface_scattering/subsurface_scattering_scale" type="float" setter="" getter="" default="0.05">
- Scales the distance over which samples are taken for subsurface scattering effect. Changing this does not impact performance, but higher values will result in significant artifacts as the samples will become obviously spread out. A lower value results in a smaller spread of scattered light.
+ <member name="rendering/shading/overrides/force_vertex_shading.mobile" type="bool" setter="" getter="" default="true">
+ Lower-end override for [member rendering/shading/overrides/force_vertex_shading] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/quality/texture_filters/anisotropic_filtering_level" type="int" setter="" getter="" default="2">
- Sets the maximum number of samples to take when using anisotropic filtering on textures (as a power of two). A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. A value of [code]0[/code] forcibly disables anisotropic filtering, even on materials where it is enabled.
+ <member name="rendering/shadows/directional_shadow/16_bits" type="bool" setter="" getter="" default="true">
</member>
- <member name="rendering/quality/texture_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false">
- If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used.
+ <member name="rendering/shadows/directional_shadow/size" type="int" setter="" getter="" default="4096">
+ The directional shadow's size in pixels. Higher values will result in sharper shadows, at the cost of performance. The value will be rounded up to the nearest power of 2.
</member>
- <member name="rendering/sdfgi/frames_to_converge" type="int" setter="" getter="" default="1">
+ <member name="rendering/shadows/directional_shadow/size.mobile" type="int" setter="" getter="" default="2048">
+ Lower-end override for [member rendering/shadows/directional_shadow/size] on mobile devices, due to performance concerns or driver support.
</member>
- <member name="rendering/sdfgi/probe_ray_count" type="int" setter="" getter="" default="2">
+ <member name="rendering/shadows/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="2">
+ Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
</member>
- <member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1">
- Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter.
+ <member name="rendering/shadows/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/shadows/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
+ </member>
+ <member name="rendering/shadows/shadow_atlas/16_bits" type="bool" setter="" getter="" default="true">
+ </member>
+ <member name="rendering/shadows/shadow_atlas/quadrant_0_subdiv" type="int" setter="" getter="" default="2">
+ Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
</member>
- <member name="rendering/volumetric_fog/directional_shadow_shrink" type="int" setter="" getter="" default="512">
+ <member name="rendering/shadows/shadow_atlas/quadrant_1_subdiv" type="int" setter="" getter="" default="2">
+ Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
</member>
- <member name="rendering/volumetric_fog/positional_shadow_shrink" type="int" setter="" getter="" default="512">
+ <member name="rendering/shadows/shadow_atlas/quadrant_2_subdiv" type="int" setter="" getter="" default="3">
+ Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
</member>
- <member name="rendering/volumetric_fog/use_filter" type="int" setter="" getter="" default="0">
+ <member name="rendering/shadows/shadow_atlas/quadrant_3_subdiv" type="int" setter="" getter="" default="4">
+ Subdivision quadrant size for shadow mapping. See shadow mapping documentation.
</member>
- <member name="rendering/volumetric_fog/volume_depth" type="int" setter="" getter="" default="128">
+ <member name="rendering/shadows/shadow_atlas/size" type="int" setter="" getter="" default="4096">
+ Size for shadow atlas (used for OmniLights and SpotLights). See documentation.
</member>
- <member name="rendering/volumetric_fog/volume_size" type="int" setter="" getter="" default="64">
+ <member name="rendering/shadows/shadow_atlas/size.mobile" type="int" setter="" getter="" default="2048">
+ Lower-end override for [member rendering/shadows/shadow_atlas/size] on mobile devices, due to performance concerns or driver support.
+ </member>
+ <member name="rendering/shadows/shadows/soft_shadow_quality" type="int" setter="" getter="" default="2">
+ Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
+ </member>
+ <member name="rendering/shadows/shadows/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/shadows/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
+ </member>
+ <member name="rendering/textures/default_filters/anisotropic_filtering_level" type="int" setter="" getter="" default="2">
+ Sets the maximum number of samples to take when using anisotropic filtering on textures (as a power of two). A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. A value of [code]0[/code] forcibly disables anisotropic filtering, even on materials where it is enabled.
+ </member>
+ <member name="rendering/textures/default_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used.
</member>
- <member name="rendering/vram_compression/import_bptc" type="bool" setter="" getter="" default="false">
+ <member name="rendering/textures/vram_compression/import_bptc" type="bool" setter="" getter="" default="false">
If [code]true[/code], the texture importer will import VRAM-compressed textures using the BPTC algorithm. This texture compression algorithm is only supported on desktop platforms, and only when using the Vulkan renderer.
</member>
- <member name="rendering/vram_compression/import_etc" type="bool" setter="" getter="" default="false">
+ <member name="rendering/textures/vram_compression/import_etc" type="bool" setter="" getter="" default="false">
If [code]true[/code], the texture importer will import VRAM-compressed textures using the Ericsson Texture Compression algorithm. This algorithm doesn't support alpha channels in textures.
</member>
- <member name="rendering/vram_compression/import_etc2" type="bool" setter="" getter="" default="true">
+ <member name="rendering/textures/vram_compression/import_etc2" type="bool" setter="" getter="" default="true">
If [code]true[/code], the texture importer will import VRAM-compressed textures using the Ericsson Texture Compression 2 algorithm. This texture compression algorithm is only supported when using the Vulkan renderer.
</member>
- <member name="rendering/vram_compression/import_pvrtc" type="bool" setter="" getter="" default="false">
+ <member name="rendering/textures/vram_compression/import_pvrtc" type="bool" setter="" getter="" default="false">
If [code]true[/code], the texture importer will import VRAM-compressed textures using the PowerVR Texture Compression algorithm. This texture compression algorithm is only supported on iOS.
</member>
- <member name="rendering/vram_compression/import_s3tc" type="bool" setter="" getter="" default="true">
+ <member name="rendering/textures/vram_compression/import_s3tc" type="bool" setter="" getter="" default="true">
If [code]true[/code], the texture importer will import VRAM-compressed textures using the S3 Texture Compression algorithm. This algorithm is only supported on desktop platforms and consoles.
</member>
<member name="rendering/vulkan/descriptor_pools/max_descriptors_per_pool" type="int" setter="" getter="" default="64">
diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml
index 425e82c744..ef83ae7fb9 100644
--- a/doc/classes/Quat.xml
+++ b/doc/classes/Quat.xml
@@ -127,7 +127,7 @@
<argument index="0" name="to" type="Quat">
</argument>
<description>
- Returns [code]true[/code] if this quaterion and [code]quat[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component.
+ Returns [code]true[/code] if this quaterion and [code]quat[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
<method name="is_normalized">
diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml
index d24e86a08b..443890438f 100644
--- a/doc/classes/RayCast3D.xml
+++ b/doc/classes/RayCast3D.xml
@@ -136,6 +136,13 @@
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
+ <member name="debug_shape_custom_color" type="Color" setter="set_debug_shape_custom_color" getter="get_debug_shape_custom_color" default="Color( 0, 0, 0, 1 )">
+ 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">
+ 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">
If [code]true[/code], collisions will be reported.
</member>
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index 8feeb91b97..5d7ff39587 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -72,15 +72,6 @@
Returns a [Rect2] with equivalent position and area, modified so that the top-left corner is the origin and [code]width[/code] and [code]height[/code] are positive.
</description>
</method>
- <method name="intersection">
- <return type="Rect2">
- </return>
- <argument index="0" name="b" type="Rect2">
- </argument>
- <description>
- Returns the intersection of this [Rect2] and b.
- </description>
- </method>
<method name="encloses">
<return type="bool">
</return>
@@ -109,10 +100,10 @@
<method name="grow">
<return type="Rect2">
</return>
- <argument index="0" name="by" type="float">
+ <argument index="0" name="amount" type="float">
</argument>
<description>
- Returns a copy of the [Rect2] grown a given amount of units towards all the sides.
+ Returns a copy of the [Rect2] grown by the specified [code]amount[/code] on all sides.
</description>
</method>
<method name="grow_individual">
@@ -127,18 +118,18 @@
<argument index="3" name="bottom" type="float">
</argument>
<description>
- Returns a copy of the [Rect2] grown a given amount of units towards each direction individually.
+ Returns a copy of the [Rect2] grown by the specified amount on each side individually.
</description>
</method>
- <method name="grow_margin">
+ <method name="grow_side">
<return type="Rect2">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="side" type="int">
</argument>
- <argument index="1" name="by" type="float">
+ <argument index="1" name="amount" type="float">
</argument>
<description>
- Returns a copy of the [Rect2] grown a given amount of units on the specified [enum Side].
+ Returns a copy of the [Rect2] grown by the specified [code]amount[/code] on the specified [enum Side].
</description>
</method>
<method name="has_no_area">
@@ -157,6 +148,16 @@
Returns [code]true[/code] if the [Rect2] contains a point.
</description>
</method>
+ <method name="intersection">
+ <return type="Rect2">
+ </return>
+ <argument index="0" name="b" type="Rect2">
+ </argument>
+ <description>
+ Returns the intersection of this [Rect2] and [code]b[/code].
+ If the rectangles do not intersect, an empty [Rect2] is returned.
+ </description>
+ </method>
<method name="intersects">
<return type="bool">
</return>
diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml
index 80f2a87f31..e581ccdb11 100644
--- a/doc/classes/Rect2i.xml
+++ b/doc/classes/Rect2i.xml
@@ -70,15 +70,6 @@
Returns a [Rect2i] with equivalent position and area, modified so that the top-left corner is the origin and [code]width[/code] and [code]height[/code] are positive.
</description>
</method>
- <method name="intersection">
- <return type="Rect2i">
- </return>
- <argument index="0" name="b" type="Rect2i">
- </argument>
- <description>
- Returns the intersection of this [Rect2i] and b.
- </description>
- </method>
<method name="encloses">
<return type="bool">
</return>
@@ -107,10 +98,10 @@
<method name="grow">
<return type="Rect2i">
</return>
- <argument index="0" name="by" type="int">
+ <argument index="0" name="amount" type="int">
</argument>
<description>
- Returns a copy of the [Rect2i] grown a given amount of units towards all the sides.
+ Returns a copy of the [Rect2i] grown by the specified [code]amount[/code] on all sides.
</description>
</method>
<method name="grow_individual">
@@ -125,18 +116,18 @@
<argument index="3" name="bottom" type="int">
</argument>
<description>
- Returns a copy of the [Rect2i] grown a given amount of units towards each direction individually.
+ Returns a copy of the [Rect2i] grown by the specified amount on each side individually.
</description>
</method>
- <method name="grow_margin">
+ <method name="grow_side">
<return type="Rect2i">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="side" type="int">
</argument>
- <argument index="1" name="by" type="int">
+ <argument index="1" name="amount" type="int">
</argument>
<description>
- Returns a copy of the [Rect2i] grown a given amount of units on the specified [enum Side].
+ Returns a copy of the [Rect2i] grown by the specified [code]amount[/code] on the specified [enum Side].
</description>
</method>
<method name="has_no_area">
@@ -155,6 +146,16 @@
Returns [code]true[/code] if the [Rect2i] contains a point.
</description>
</method>
+ <method name="intersection">
+ <return type="Rect2i">
+ </return>
+ <argument index="0" name="b" type="Rect2i">
+ </argument>
+ <description>
+ Returns the intersection of this [Rect2i] and [code]b[/code].
+ If the rectangles do not intersect, an empty [Rect2i] is returned.
+ </description>
+ </method>
<method name="intersects">
<return type="bool">
</return>
diff --git a/doc/classes/RectangleShape2D.xml b/doc/classes/RectangleShape2D.xml
index 041416a24b..8e37fbad6f 100644
--- a/doc/classes/RectangleShape2D.xml
+++ b/doc/classes/RectangleShape2D.xml
@@ -13,8 +13,8 @@
<methods>
</methods>
<members>
- <member name="extents" type="Vector2" setter="set_extents" getter="get_extents" default="Vector2( 10, 10 )">
- The rectangle's half extents. The width and height of this shape is twice the half extents.
+ <member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2( 20, 20 )">
+ The rectangle's width and height.
</member>
</members>
<constants>
diff --git a/doc/classes/Reference.xml b/doc/classes/Reference.xml
index 44ee6fbda1..724d2db924 100644
--- a/doc/classes/Reference.xml
+++ b/doc/classes/Reference.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Base class for any object that keeps a reference count. [Resource] and many other helper objects inherit this class.
- Unlike [Object]s, References keep an internal reference counter so that they are automatically released when no longer in use, and only then. References therefore do not need to be freed manually with [method Object.free].
+ Unlike other [Object] types, References keep an internal reference counter so that they are automatically released when no longer in use, and only then. References therefore do not need to be freed manually with [method Object.free].
In the vast majority of use cases, instantiating and using [Reference]-derived types is all you need to do. The methods provided in this class are only for advanced users, and can cause issues if misused.
[b]Note:[/b] In C#, references will not be freed instantly after they are no longer in use. Instead, garbage collection will run periodically and will free references that are no longer in use. This means that unused references will linger on for a while before being removed.
</description>
diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml
index 5458b496da..cd08778c89 100644
--- a/doc/classes/ReflectionProbe.xml
+++ b/doc/classes/ReflectionProbe.xml
@@ -37,6 +37,8 @@
<member name="interior" type="bool" setter="set_as_interior" getter="is_set_as_interior" default="false">
If [code]true[/code], reflections will ignore sky contribution.
</member>
+ <member name="lod_threshold" type="float" setter="set_lod_threshold" getter="get_lod_threshold" default="1.0">
+ </member>
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0">
Sets the max distance away from the probe an object can be before it is culled.
</member>
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index 7e5df9c40d..841d2bde72 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -7,6 +7,30 @@
<tutorials>
</tutorials>
<methods>
+ <method name="barrier">
+ <return type="void">
+ </return>
+ <argument index="0" name="from" type="int" default="7">
+ </argument>
+ <argument index="1" name="to" type="int" default="7">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="buffer_clear">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="buffer" type="RID">
+ </argument>
+ <argument index="1" name="offset" type="int">
+ </argument>
+ <argument index="2" name="size_bytes" type="int">
+ </argument>
+ <argument index="3" name="post_barrier" type="int" default="7">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="buffer_get_data">
<return type="PackedByteArray">
</return>
@@ -26,7 +50,7 @@
</argument>
<argument index="3" name="data" type="PackedByteArray">
</argument>
- <argument index="4" name="sync_with_draw" type="bool" default="true">
+ <argument index="4" name="post_barrier" type="int" default="7">
</argument>
<description>
</description>
@@ -36,8 +60,6 @@
</return>
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="sync_to_draw" type="bool">
- </argument>
<description>
</description>
</method>
@@ -52,6 +74,8 @@
<method name="compute_list_begin">
<return type="int">
</return>
+ <argument index="0" name="allow_draw_overlap" type="bool" default="false">
+ </argument>
<description>
</description>
</method>
@@ -94,6 +118,8 @@
<method name="compute_list_end">
<return type="void">
</return>
+ <argument index="0" name="post_barrier" type="int" default="7">
+ </argument>
<description>
</description>
</method>
@@ -131,6 +157,32 @@
<description>
</description>
</method>
+ <method name="draw_command_begin_label">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_command_end_label">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="draw_command_insert_label">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="draw_list_begin">
<return type="int">
</return>
@@ -272,6 +324,8 @@
<method name="draw_list_end">
<return type="void">
</return>
+ <argument index="0" name="post_barrier" type="int" default="7">
+ </argument>
<description>
</description>
</method>
@@ -302,7 +356,9 @@
</return>
<argument index="0" name="size" type="Vector2i">
</argument>
- <argument index="1" name="validate_with_format" type="int" default="-1">
+ <argument index="1" name="samples" type="int" enum="RenderingDevice.TextureSamples" default="0">
+ </argument>
+ <argument index="2" name="validate_with_format" type="int" default="-1">
</argument>
<description>
</description>
@@ -318,7 +374,7 @@
<method name="framebuffer_format_create_empty">
<return type="int">
</return>
- <argument index="0" name="size" type="Vector2i">
+ <argument index="0" name="samples" type="int" enum="RenderingDevice.TextureSamples" default="0">
</argument>
<description>
</description>
@@ -347,6 +403,12 @@
<description>
</description>
</method>
+ <method name="full_barrier">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_captured_timestamp_cpu_time" qualifiers="const">
<return type="int">
</return>
@@ -383,6 +445,24 @@
<description>
</description>
</method>
+ <method name="get_device_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_device_pipeline_cache_uuid" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_device_vendor_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_frame_delay" qualifiers="const">
<return type="int">
</return>
@@ -410,7 +490,7 @@
</argument>
<argument index="2" name="data" type="PackedByteArray" default="PackedByteArray( )">
</argument>
- <argument index="3" name="arg3" type="bool" default="false">
+ <argument index="3" name="use_restart_indices" type="bool" default="false">
</argument>
<description>
</description>
@@ -485,6 +565,16 @@
<description>
</description>
</method>
+ <method name="set_resource_name">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="RID">
+ </argument>
+ <argument index="1" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="shader_compile_from_source">
<return type="RDShaderBytecode">
</return>
@@ -562,7 +652,7 @@
</argument>
<argument index="5" name="layer_count" type="int">
</argument>
- <argument index="6" name="sync_with_draw" type="bool" default="false">
+ <argument index="6" name="post_barrier" type="int" default="7">
</argument>
<description>
</description>
@@ -588,7 +678,7 @@
</argument>
<argument index="8" name="dst_layer" type="int">
</argument>
- <argument index="9" name="sync_with_draw" type="bool" default="false">
+ <argument index="9" name="post_barrier" type="int" default="7">
</argument>
<description>
</description>
@@ -674,7 +764,7 @@
</argument>
<argument index="1" name="to_texture" type="RID">
</argument>
- <argument index="2" name="sync_with_draw" type="bool" default="false">
+ <argument index="2" name="post_barrier" type="int" default="7">
</argument>
<description>
</description>
@@ -688,7 +778,7 @@
</argument>
<argument index="2" name="data" type="PackedByteArray">
</argument>
- <argument index="3" name="sync_with_draw" type="bool" default="false">
+ <argument index="3" name="post_barrier" type="int" default="7">
</argument>
<description>
</description>
@@ -730,6 +820,8 @@
</argument>
<argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )">
</argument>
+ <argument index="2" name="use_as_storage" type="bool" default="false">
+ </argument>
<description>
</description>
</method>
@@ -743,6 +835,16 @@
</method>
</methods>
<constants>
+ <constant name="BARRIER_MASK_RASTER" value="1">
+ </constant>
+ <constant name="BARRIER_MASK_COMPUTE" value="2">
+ </constant>
+ <constant name="BARRIER_MASK_TRANSFER" value="4">
+ </constant>
+ <constant name="BARRIER_MASK_ALL" value="7">
+ </constant>
+ <constant name="BARRIER_MASK_NO_BARRIER" value="8">
+ </constant>
<constant name="DATA_FORMAT_R4G4_UNORM_PACK8" value="0" enum="DataFormat">
</constant>
<constant name="DATA_FORMAT_R4G4B4A4_UNORM_PACK16" value="1" enum="DataFormat">
@@ -1505,13 +1607,17 @@
</constant>
<constant name="INITIAL_ACTION_CLEAR" value="0" enum="InitialAction">
</constant>
- <constant name="INITIAL_ACTION_KEEP" value="1" enum="InitialAction">
+ <constant name="INITIAL_ACTION_CLEAR_REGION" value="1" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_CLEAR_REGION_CONTINUE" value="2" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_KEEP" value="3" enum="InitialAction">
</constant>
- <constant name="INITIAL_ACTION_DROP" value="2" enum="InitialAction">
+ <constant name="INITIAL_ACTION_DROP" value="4" enum="InitialAction">
</constant>
- <constant name="INITIAL_ACTION_CONTINUE" value="3" enum="InitialAction">
+ <constant name="INITIAL_ACTION_CONTINUE" value="5" enum="InitialAction">
</constant>
- <constant name="INITIAL_ACTION_MAX" value="4" enum="InitialAction">
+ <constant name="INITIAL_ACTION_MAX" value="6" enum="InitialAction">
</constant>
<constant name="FINAL_ACTION_READ" value="0" enum="FinalAction">
</constant>
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 036b50f0ed..d2b95fda20 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -859,6 +859,12 @@
Tries to free an object in the RenderingServer.
</description>
</method>
+ <method name="get_frame_setup_time_cpu" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_render_info">
<return type="int">
</return>
@@ -1354,7 +1360,7 @@
<argument index="1" name="scenario" type="RID">
</argument>
<description>
- Returns an array of object IDs intersecting with the provided AABB. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GDScript.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update.
+ Returns an array of object IDs intersecting with the provided AABB. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update.
[b]Warning:[/b] This function is primarily intended for editor usage. For in-game use cases, prefer physics collision.
</description>
</method>
@@ -1366,7 +1372,7 @@
<argument index="1" name="scenario" type="RID">
</argument>
<description>
- Returns an array of object IDs intersecting with the provided convex shape. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GDScript.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update.
+ Returns an array of object IDs intersecting with the provided convex shape. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update.
[b]Warning:[/b] This function is primarily intended for editor usage. For in-game use cases, prefer physics collision.
</description>
</method>
@@ -1380,7 +1386,7 @@
<argument index="2" name="scenario" type="RID">
</argument>
<description>
- Returns an array of object IDs intersecting with the provided 3D ray. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GDScript.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update.
+ Returns an array of object IDs intersecting with the provided 3D ray. Only visual 3D nodes are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update.
[b]Warning:[/b] This function is primarily intended for editor usage. For in-game use cases, prefer physics collision.
</description>
</method>
@@ -1796,7 +1802,7 @@
Updates a specific region of a vertex buffer for the specified surface. Warning: this function alters the vertex buffer directly with no safety mechanisms, you can easily corrupt your mesh.
</description>
</method>
- <method name="multimesh_allocate">
+ <method name="multimesh_allocate_data">
<return type="void">
</return>
<argument index="0" name="multimesh" type="RID">
@@ -2543,7 +2549,7 @@
Sets a shader's default texture. Overwrites the texture given by name.
</description>
</method>
- <method name="skeleton_allocate">
+ <method name="skeleton_allocate_data">
<return type="void">
</return>
<argument index="0" name="skeleton" type="RID">
@@ -2553,7 +2559,6 @@
<argument index="2" name="is_2d_skeleton" type="bool" default="false">
</argument>
<description>
- Allocates the GPU buffers for this skeleton.
</description>
</method>
<method name="skeleton_bone_get_transform" qualifiers="const">
@@ -2699,11 +2704,14 @@
<description>
Copies the viewport to a region of the screen specified by [code]rect[/code]. If [method viewport_set_render_direct_to_screen] is [code]true[/code], then the viewport does not use a framebuffer and the contents of the viewport are rendered directly to screen. However, note that the root viewport is drawn last, therefore it will draw over the screen. Accordingly, you must set the root viewport to an area that does not cover the area that you have attached this viewport to.
For example, you can set the root viewport to not render at all with the following code:
- [codeblock]
+ FIXME: The method seems to be non-existent.
+ [codeblocks]
+ [gdscript]
func _ready():
get_viewport().set_attach_to_screen_rect(Rect2())
$Viewport.set_attach_to_screen_rect(Rect2(0, 0, 600, 600))
- [/codeblock]
+ [/gdscript]
+ [/codeblocks]
Using this can result in significant optimization, especially on lower-end devices. However, it comes at the cost of having to manage your viewports manually. For a further optimization see, [method viewport_set_render_direct_to_screen].
</description>
</method>
@@ -2715,6 +2723,22 @@
Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method.
</description>
</method>
+ <method name="viewport_get_measured_render_time_cpu" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="viewport" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="viewport_get_measured_render_time_gpu" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="viewport" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="viewport_get_render_info">
<return type="int">
</return>
@@ -2852,6 +2876,16 @@
Currently unimplemented in Godot 3.x.
</description>
</method>
+ <method name="viewport_set_measure_render_time">
+ <return type="void">
+ </return>
+ <argument index="0" name="viewport" type="RID">
+ </argument>
+ <argument index="1" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="viewport_set_msaa">
<return type="void">
</return>
@@ -2917,6 +2951,8 @@
</argument>
<argument index="1" name="size" type="int">
</argument>
+ <argument index="2" name="use_16_bits" type="bool" default="false">
+ </argument>
<description>
Sets the size of the shadow atlas's images (used for omni and spot lights). The value will be rounded up to the nearest power of 2.
</description>
@@ -3419,7 +3455,7 @@
<constant name="VIEWPORT_DEBUG_DRAW_GI_BUFFER" value="17" enum="ViewportDebugDraw">
</constant>
<constant name="SKY_MODE_QUALITY" value="1" enum="SkyMode">
- Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples].
+ Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/reflections/sky_reflections/ggx_samples].
</constant>
<constant name="SKY_MODE_REALTIME" value="3" enum="SkyMode">
Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times.
diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml
index 54984b7785..2548f8d911 100644
--- a/doc/classes/Resource.xml
+++ b/doc/classes/Resource.xml
@@ -4,7 +4,7 @@
Base class for all resources.
</brief_description>
<description>
- Resource is the base class for all Godot-specific resource types, serving primarily as data containers. Unlike [Object]s, they are reference-counted and freed when no longer in use. They are also cached once loaded from disk, so that any further attempts to load a resource from a given path will return the same reference (all this in contrast to a [Node], which is not reference-counted and can be instanced from disk as many times as desired). Resources can be saved externally on disk or bundled into another object, such as a [Node] or another resource.
+ Resource is the base class for all Godot-specific resource types, serving primarily as data containers. Since they inherit from [Reference], resources are reference-counted and freed when no longer in use. They are also cached once loaded from disk, so that any further attempts to load a resource from a given path will return the same reference (all this in contrast to a [Node], which is not reference-counted and can be instanced from disk as many times as desired). Resources can be saved externally on disk or bundled into another object, such as a [Node] or another resource.
[b]Note:[/b] In C#, resources will not be freed instantly after they are no longer in use. Instead, garbage collection will run periodically and will free resources that are no longer in use. This means that unused resources will linger on for a while before being removed.
</description>
<tutorials>
@@ -29,6 +29,19 @@
[b]Note:[/b] If [code]subresources[/code] is [code]true[/code], this method will only perform a shallow copy. Nested resources within subresources will not be duplicated and will still be shared.
</description>
</method>
+ <method name="emit_changed">
+ <return type="void">
+ </return>
+ <description>
+ Emits the [signal changed] signal.
+ If external objects which depend on this resource should be updated, this method must be called manually whenever the state of this resource has changed (such as modification of properties).
+ The method is equivalent to:
+ [codeblock]
+ emit_signal("changed")
+ [/codeblock]
+ [b]Note:[/b] This method is called automatically for built-in resources.
+ </description>
+ </method>
<method name="get_local_scene" qualifiers="const">
<return type="Node">
</return>
@@ -66,7 +79,7 @@
If [code]true[/code], the resource will be made unique in each instance of its local scene. It can thus be modified in a scene instance without impacting other instances of that same scene.
</member>
<member name="resource_name" type="String" setter="set_name" getter="get_name" default="&quot;&quot;">
- The name of the resource. This is an optional identifier.
+ The name of the resource. This is an optional identifier. If [member resource_name] is not empty, its value will be displayed to represent the current resource in the editor inspector. For built-in scripts, the [member resource_name] will be displayed as the tab name in the script editor.
</member>
<member name="resource_path" type="String" setter="set_path" getter="get_path" default="&quot;&quot;">
The path to the resource. In case it has its own file, it will return its filepath. If it's tied to the scene, it will return the scene's path, followed by the resource's index.
diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml
index ad0c438f98..2683156ec5 100644
--- a/doc/classes/ResourceFormatLoader.xml
+++ b/doc/classes/ResourceFormatLoader.xml
@@ -57,8 +57,13 @@
</argument>
<argument index="1" name="original_path" type="String">
</argument>
+ <argument index="2" name="use_sub_threads" type="bool">
+ </argument>
+ <argument index="3" name="cache_mode" type="int">
+ </argument>
<description>
Loads a resource when the engine finds this loader to be compatible. If the loaded resource is the result of an import, [code]original_path[/code] will target the source file. Returns a [Resource] object on success, or an [enum Error] constant in case of failure.
+ The [code]cache_mode[/code] property defines whether and how the cache should be used or updated when loading the resource. See [enum CacheMode] for details.
</description>
</method>
<method name="rename_dependencies" qualifiers="virtual">
@@ -75,5 +80,11 @@
</method>
</methods>
<constants>
+ <constant name="CACHE_MODE_IGNORE" value="0" enum="CacheMode">
+ </constant>
+ <constant name="CACHE_MODE_REUSE" value="1" enum="CacheMode">
+ </constant>
+ <constant name="CACHE_MODE_REPLACE" value="2" enum="CacheMode">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml
index c55a51c7ae..c81b21333f 100644
--- a/doc/classes/ResourceLoader.xml
+++ b/doc/classes/ResourceLoader.xml
@@ -58,13 +58,13 @@
</argument>
<argument index="1" name="type_hint" type="String" default="&quot;&quot;">
</argument>
- <argument index="2" name="no_cache" type="bool" default="false">
+ <argument index="2" name="cache_mode" type="int" enum="ResourceLoader.CacheMode" default="1">
</argument>
<description>
Loads a resource at the given [code]path[/code], caching the result for further access.
The registered [ResourceFormatLoader]s are queried sequentially to find the first one which can handle the file's extension, and then attempt loading. If loading fails, the remaining ResourceFormatLoaders are also attempted.
An optional [code]type_hint[/code] can be used to further specify the [Resource] type that should be handled by the [ResourceFormatLoader]. Anything that inherits from [Resource] can be used as a type hint, for example [Image].
- If [code]no_cache[/code] is [code]true[/code], the resource cache will be bypassed and the resource will be loaded anew. Otherwise, the cached resource will be returned if it exists.
+ The [code]cache_mode[/code] property defines whether and how the cache should be used or updated when loading the resource. See [enum CacheMode] for details.
Returns an empty resource if no [ResourceFormatLoader] could handle the file.
GDScript has a simplified [method @GDScript.load] built-in method which can be used in most situations, leaving the use of [ResourceLoader] for more advanced scenarios.
</description>
@@ -127,5 +127,11 @@
<constant name="THREAD_LOAD_LOADED" value="3" enum="ThreadLoadStatus">
The resource was loaded successfully and can be accessed via [method load_threaded_get].
</constant>
+ <constant name="CACHE_MODE_IGNORE" value="0" enum="CacheMode">
+ </constant>
+ <constant name="CACHE_MODE_REUSE" value="1" enum="CacheMode">
+ </constant>
+ <constant name="CACHE_MODE_REPLACE" value="2" enum="CacheMode">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/RichTextEffect.xml b/doc/classes/RichTextEffect.xml
index 726b26fbc7..edab35f162 100644
--- a/doc/classes/RichTextEffect.xml
+++ b/doc/classes/RichTextEffect.xml
@@ -6,10 +6,16 @@
<description>
A custom effect for use with [RichTextLabel].
[b]Note:[/b] For a [RichTextEffect] to be usable, a BBCode tag must be defined as a member variable called [code]bbcode[/code] in the script.
- [codeblock]
+ [codeblocks]
+ [gdscript]
# The RichTextEffect will be usable like this: `[example]Some text[/example]`
var bbcode = "example"
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // The RichTextEffect will be usable like this: `[example]Some text[/example]`
+ public string bbcode = "example";
+ [/csharp]
+ [/codeblocks]
[b]Note:[/b] As soon as a [RichTextLabel] contains at least one [RichTextEffect], it will continuously process the effect unless the project is paused. This may impact battery life negatively.
</description>
<tutorials>
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index 0fd440fa75..7ca70f5a7a 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -6,6 +6,7 @@
<description>
Rich text can contain custom text, fonts, images and some basic formatting. The label manages these as an internal tag stack. It also adapts itself to given width/heights.
[b]Note:[/b] Assignments to [member bbcode_text] clear the tag stack and reconstruct it from the property's contents. Any edits made to [member bbcode_text] will erase previous edits made from other manual sources such as [method append_bbcode] and the [code]push_*[/code] / [method pop] methods.
+ [b]Note:[/b] RichTextLabel doesn't support entangled BBCode tags. For example, instead of using [code][b]bold[i]bold italic[/b]italic[/i][/code], use [code][b]bold[i]bold italic[/i][/b][i]italic[/i][/code].
[b]Note:[/b] Unlike [Label], RichTextLabel doesn't have a [i]property[/i] to horizontally align text to the center. Instead, enable [member bbcode_enabled] and surround the text in a [code][center][/code] tag as follows: [code][center]Example[/center][/code]. There is currently no built-in way to vertically align text either, but this can be emulated by relying on anchors/containers and the [member fit_content_height] property.
</description>
<tutorials>
@@ -69,7 +70,35 @@
<return type="int">
</return>
<description>
- Returns the total number of newlines in the tag stack's text tags. Considers wrapped text as one line.
+ Returns the total number of lines in the text. Wrapped text is counted as multiple lines.
+ </description>
+ </method>
+ <method name="get_paragraph_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the total number of paragraphs (newlines or [code]p[/code] tags in the tag stack's text tags). Considers wrapped text as one paragraph.
+ </description>
+ </method>
+ <method name="get_selected_text" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ Returns the current selection text. Does not include BBCodes.
+ </description>
+ </method>
+ <method name="get_selection_from" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the current selection first character index if a selection is active, [code]-1[/code] otherwise. Does not include BBCodes.
+ </description>
+ </method>
+ <method name="get_selection_to" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the current selection last character index if a selection is active, [code]-1[/code] otherwise. Does not include BBCodes.
</description>
</method>
<method name="get_total_character_count" qualifiers="const">
@@ -93,6 +122,13 @@
Returns the number of visible lines.
</description>
</method>
+ <method name="get_visible_paragraph_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of visible paragraphs. A paragraph is considered visible if at least one of its lines is visible.
+ </description>
+ </method>
<method name="install_effect">
<return type="void">
</return>
@@ -164,6 +200,27 @@
Adds a [code][color][/code] tag to the tag stack.
</description>
</method>
+ <method name="push_dropcap">
+ <return type="void">
+ </return>
+ <argument index="0" name="string" type="String">
+ </argument>
+ <argument index="1" name="font" type="Font">
+ </argument>
+ <argument index="2" name="size" type="int">
+ </argument>
+ <argument index="3" name="dropcap_margins" type="Rect2" default="Rect2( 0, 0, 0, 0 )">
+ </argument>
+ <argument index="4" name="color" type="Color" default="Color( 1, 1, 1, 1 )">
+ </argument>
+ <argument index="5" name="outline_size" type="int" default="0">
+ </argument>
+ <argument index="6" name="outline_color" type="Color" default="Color( 0, 0, 0, 0 )">
+ </argument>
+ <description>
+ Adds a [code][dropcap][/code] tag to the tag stack. Drop cap (dropped capital) is a decorative element at the beginning of a paragraph that is larger than the rest of the text.
+ </description>
+ </method>
<method name="push_font">
<return type="void">
</return>
@@ -320,6 +377,15 @@
Scrolls the window's top line to match [code]line[/code].
</description>
</method>
+ <method name="scroll_to_paragraph">
+ <return type="void">
+ </return>
+ <argument index="0" name="paragraph" type="int">
+ </argument>
+ <description>
+ Scrolls the window's top line to match first line of the [code]paragraph[/code].
+ </description>
+ </method>
<method name="set_cell_border_color">
<return type="void">
</return>
@@ -433,6 +499,7 @@
</member>
<member name="visible_characters" type="int" setter="set_visible_characters" getter="get_visible_characters" default="-1">
The restricted number of characters to display in the label. If [code]-1[/code], all characters will be displayed.
+ [b]Note:[/b] Setting this property updates [member percent_visible] based on current [method get_total_character_count].
</member>
</members>
<signals>
@@ -525,10 +592,12 @@
</constant>
<constant name="ITEM_RAINBOW" value="20" enum="ItemType">
</constant>
- <constant name="ITEM_CUSTOMFX" value="22" enum="ItemType">
- </constant>
<constant name="ITEM_META" value="21" enum="ItemType">
</constant>
+ <constant name="ITEM_DROPCAP" value="22" enum="ItemType">
+ </constant>
+ <constant name="ITEM_CUSTOMFX" value="23" enum="ItemType">
+ </constant>
</constants>
<theme_items>
<theme_item name="bold_font" type="Font">
@@ -549,10 +618,13 @@
<theme_item name="focus" type="StyleBox">
The background The background used when the [RichTextLabel] is focused.
</theme_item>
- <theme_item name="font_color_selected" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The default tint of text outline.
+ </theme_item>
+ <theme_item name="font_selected_color" type="Color" default="Color( 0, 0, 0, 1 )">
The color of selected text, used when [member selection_enabled] is [code]true[/code].
</theme_item>
- <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 0 )">
+ <theme_item name="font_shadow_color" type="Color" default="Color( 0, 0, 0, 0 )">
The color of the font's shadow.
</theme_item>
<theme_item name="italics_font" type="Font">
@@ -579,6 +651,9 @@
<theme_item name="normal_font_size" type="int">
The default text font size.
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="selection_color" type="Color" default="Color( 0.1, 0.1, 1, 0.8 )">
The color of the selection box.
</theme_item>
diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml
index 2a0b44f3f3..6b27c77f26 100644
--- a/doc/classes/RigidBody2D.xml
+++ b/doc/classes/RigidBody2D.xml
@@ -180,14 +180,16 @@
<argument index="0" name="body" type="Node">
</argument>
<description>
- Emitted when a body enters into contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions.
+ Emitted when a collision with another [PhysicsBody2D] or [TileMap] occurs. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap].
</description>
</signal>
<signal name="body_exited">
<argument index="0" name="body" type="Node">
</argument>
<description>
- Emitted when a body exits contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions.
+ Emitted when the collision with another [PhysicsBody2D] or [TileMap] ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap].
</description>
</signal>
<signal name="body_shape_entered">
@@ -200,7 +202,11 @@
<argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when a body enters into contact with this one. Reports colliding shape information. See [CollisionObject2D] for shape index information. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions.
+ Emitted when one of this RigidBody2D's [Shape2D]s collides with another [PhysicsBody2D] or [TileMap]'s [Shape2D]s. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
+ [code]body_id[/code] the [RID] of the other [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap].
+ [code]body_shape[/code] the index of the [Shape2D] of the other [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D].
+ [code]local_shape[/code] the index of the [Shape2D] of this RigidBody2D used by the [PhysicsServer2D].
</description>
</signal>
<signal name="body_shape_exited">
@@ -213,7 +219,11 @@
<argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when a body shape exits contact with this one. Reports colliding shape information. See [CollisionObject2D] for shape index information. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions.
+ Emitted when the collision between one of this RigidBody2D's [Shape2D]s and another [PhysicsBody2D] or [TileMap]'s [Shape2D]s ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
+ [code]body_id[/code] the [RID] of the other [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap].
+ [code]body_shape[/code] the index of the [Shape2D] of the other [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D].
+ [code]local_shape[/code] the index of the [Shape2D] of this RigidBody2D used by the [PhysicsServer2D].
</description>
</signal>
<signal name="sleeping_state_changed">
diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml
index 21321d4de0..1c6c8852a9 100644
--- a/doc/classes/RigidBody3D.xml
+++ b/doc/classes/RigidBody3D.xml
@@ -204,14 +204,16 @@
<argument index="0" name="body" type="Node">
</argument>
<description>
- Emitted when a body enters into contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions.
+ Emitted when a collision with another [PhysicsBody3D] or [GridMap] occurs. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap].
</description>
</signal>
<signal name="body_exited">
<argument index="0" name="body" type="Node">
</argument>
<description>
- Emitted when a body shape exits contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions.
+ Emitted when the collision with another [PhysicsBody3D] or [GridMap] ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap].
</description>
</signal>
<signal name="body_shape_entered">
@@ -224,8 +226,12 @@
<argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when a body enters into contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions.
- This signal not only receives the body that collided with this one, but also its [RID] ([code]body_id[/code]), the shape index from the colliding body ([code]body_shape[/code]), and the shape index from this body ([code]local_shape[/code]) the other body collided with.
+ Emitted when one of this RigidBody3D's [Shape3D]s collides with another [PhysicsBody3D] or [GridMap]'s [Shape3D]s. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
+ [code]body_id[/code] the [RID] of the other [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap].
+ [code]body_shape[/code] the index of the [Shape3D] of the other [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D].
+ [code]local_shape[/code] the index of the [Shape3D] of this RigidBody3D used by the [PhysicsServer3D].
+ [b]Note:[/b] Bullet physics cannot identify the shape index when using a [ConcavePolygonShape3D]. Don't use multiple [CollisionShape3D]s when using a [ConcavePolygonShape3D] with Bullet physics if you need shape indices.
</description>
</signal>
<signal name="body_shape_exited">
@@ -238,8 +244,12 @@
<argument index="3" name="local_shape" type="int">
</argument>
<description>
- Emitted when a body shape exits contact with this one. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions.
- This signal not only receives the body that stopped colliding with this one, but also its [RID] ([code]body_id[/code]), the shape index from the colliding body ([code]body_shape[/code]), and the shape index from this body ([code]local_shape[/code]) the other body stopped colliding with.
+ Emitted when the collision between one of this RigidBody3D's [Shape3D]s and another [PhysicsBody3D] or [GridMap]'s [Shape3D]s ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
+ [code]body_id[/code] the [RID] of the other [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D]. [GridMap]s are detected if the Meshes have [Shape3D]s.
+ [code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap].
+ [code]body_shape[/code] the index of the [Shape3D] of the other [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D].
+ [code]local_shape[/code] the index of the [Shape3D] of this RigidBody3D used by the [PhysicsServer3D].
+ [b]Note:[/b] Bullet physics cannot identify the shape index when using a [ConcavePolygonShape3D]. Don't use multiple [CollisionShape3D]s when using a [ConcavePolygonShape3D] with Bullet physics if you need shape indices.
</description>
</signal>
<signal name="sleeping_state_changed">
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index a95ce6c663..e1f6830eb2 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -45,6 +45,7 @@
<description>
Changes the running scene to the one at the given [code]path[/code], after loading it into a [PackedScene] and creating a new instance.
Returns [constant OK] on success, [constant ERR_CANT_OPEN] if the [code]path[/code] cannot be loaded into a [PackedScene], or [constant ERR_CANT_CREATE] if that scene cannot be instantiated.
+ [b]Note:[/b] The scene change is deferred, which means that the new scene node is added on the next idle frame. You won't be able to access it immediately after the [method change_scene] call.
</description>
</method>
<method name="change_scene_to">
@@ -55,6 +56,7 @@
<description>
Changes the running scene to a new instance of the given [PackedScene].
Returns [constant OK] on success or [constant ERR_CANT_CREATE] if the scene cannot be instantiated.
+ [b]Note:[/b] The scene change is deferred, which means that the new scene node is added on the next idle frame. You won't be able to access it immediately after the [method change_scene_to] call.
</description>
</method>
<method name="create_timer">
@@ -62,17 +64,36 @@
</return>
<argument index="0" name="time_sec" type="float">
</argument>
- <argument index="1" name="pause_mode_process" type="bool" default="true">
+ <argument index="1" name="process_always" type="bool" default="true">
</argument>
<description>
- Returns a [SceneTreeTimer] which will [signal SceneTreeTimer.timeout] after the given time in seconds elapsed in this [SceneTree]. If [code]pause_mode_process[/code] is set to [code]false[/code], pausing the [SceneTree] will also pause the timer.
+ Returns a [SceneTreeTimer] which will [signal SceneTreeTimer.timeout] after the given time in seconds elapsed in this [SceneTree]. If [code]process_always[/code] is set to [code]false[/code], pausing the [SceneTree] will also pause the timer.
Commonly used to create a one-shot delay timer as in the following example:
- [codeblock]
+ [codeblocks]
+ [gdscript]
func some_function():
print("start")
yield(get_tree().create_timer(1.0), "timeout")
print("end")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public async void SomeFunction()
+ {
+ GD.Print("start");
+ await ToSignal(GetTree().CreateTimer(1.0f), "timeout");
+ GD.Print("end");
+ }
+ [/csharp]
+ [/codeblocks]
+ The timer will be automatically freed after its time elapses.
+ </description>
+ </method>
+ <method name="get_first_node_in_group">
+ <return type="Node">
+ </return>
+ <argument index="0" name="group" type="StringName">
+ </argument>
+ <description>
</description>
</method>
<method name="get_frame" qualifiers="const">
@@ -178,10 +199,12 @@
<method name="quit">
<return type="void">
</return>
- <argument index="0" name="exit_code" type="int" default="-1">
+ <argument index="0" name="exit_code" type="int" default="0">
</argument>
<description>
- Quits the application at the end of the current iteration. A process [code]exit_code[/code] can optionally be passed as an argument. If this argument is [code]0[/code] or greater, it will override the [member OS.exit_code] defined before quitting the application.
+ Quits the application at the end of the current iteration. Argument [code]exit_code[/code] can optionally be given (defaulting to 0) to customize the exit status code.
+ By convention, an exit code of [code]0[/code] indicates success whereas a non-zero exit code indicates an error.
+ For portability reasons, the exit code should be set between 0 and 125 (inclusive).
</description>
</method>
<method name="reload_current_scene">
@@ -258,7 +281,7 @@
The default [MultiplayerAPI] instance for this [SceneTree].
</member>
<member name="multiplayer_poll" type="bool" setter="set_multiplayer_poll_enabled" getter="is_multiplayer_poll_enabled" default="true">
- If [code]true[/code] (default value), enables automatic polling of the [MultiplayerAPI] for this SceneTree during [signal idle_frame].
+ If [code]true[/code] (default value), enables automatic polling of the [MultiplayerAPI] for this SceneTree during [signal process_frame].
If [code]false[/code], you need to manually call [method MultiplayerAPI.poll] to process network packets and deliver RPCs/RSETs. This allows running RPCs/RSETs in a different loop (e.g. physics, thread, specific time step) and for manual [Mutex] protection when accessing the [MultiplayerAPI] from threads.
</member>
<member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer">
@@ -296,11 +319,6 @@
Emitted when files are dragged from the OS file manager and dropped in the game window. The arguments are a list of file paths and the identifier of the screen where the drag originated.
</description>
</signal>
- <signal name="idle_frame">
- <description>
- Emitted immediately before [method Node._process] is called on every node in the [SceneTree].
- </description>
- </signal>
<signal name="network_peer_connected">
<argument index="0" name="id" type="int">
</argument>
@@ -348,6 +366,11 @@
Emitted immediately before [method Node._physics_process] is called on every node in the [SceneTree].
</description>
</signal>
+ <signal name="process_frame">
+ <description>
+ Emitted immediately before [method Node._process] is called on every node in the [SceneTree].
+ </description>
+ </signal>
<signal name="server_disconnected">
<description>
Emitted whenever this [SceneTree]'s [member network_peer] disconnected from server. Only emitted on clients.
@@ -358,6 +381,11 @@
Emitted whenever the [SceneTree] hierarchy changed (children being moved or renamed, etc.).
</description>
</signal>
+ <signal name="tree_process_mode_changed">
+ <description>
+ This signal is only emitted in the editor, it allows the editor to update the visibility of disabled nodes. Emitted whenever any node's [member Node.process_mode] is changed.
+ </description>
+ </signal>
</signals>
<constants>
<constant name="GROUP_CALL_DEFAULT" value="0" enum="GroupCallFlags">
diff --git a/doc/classes/SceneTreeTimer.xml b/doc/classes/SceneTreeTimer.xml
index a4a83fa65b..b223bf6821 100644
--- a/doc/classes/SceneTreeTimer.xml
+++ b/doc/classes/SceneTreeTimer.xml
@@ -6,12 +6,22 @@
<description>
A one-shot timer managed by the scene tree, which emits [signal timeout] on completion. See also [method SceneTree.create_timer].
As opposed to [Timer], it does not require the instantiation of a node. Commonly used to create a one-shot delay timer as in the following example:
- [codeblock]
+ [codeblocks]
+ [gdscript]
func some_function():
print("Timer started.")
yield(get_tree().create_timer(1.0), "timeout")
print("Timer ended.")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public async void SomeFunction()
+ {
+ GD.Print("Timer started.");
+ await ToSignal(GetTree().CreateTimer(1.0f), "timeout");
+ GD.Print("Timer ended.");
+ }
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ScriptCreateDialog.xml b/doc/classes/ScriptCreateDialog.xml
index aa60ecb12b..7185213c44 100644
--- a/doc/classes/ScriptCreateDialog.xml
+++ b/doc/classes/ScriptCreateDialog.xml
@@ -5,12 +5,24 @@
</brief_description>
<description>
The [ScriptCreateDialog] creates script files according to a given template for a given scripting language. The standard use is to configure its fields prior to calling one of the [method Window.popup] methods.
- [codeblock]
+ [codeblocks]
+ [gdscript]
func _ready():
- dialog.config("Node", "res://new_node.gd") # For in-engine types
- dialog.config("\"res://base_node.gd\"", "res://derived_node.gd") # For script types
+ var dialog = ScriptCreateDialog.new();
+ dialog.config("Node", "res://new_node.gd") # For in-engine types.
+ dialog.config("\"res://base_node.gd\"", "res://derived_node.gd") # For script types.
dialog.popup_centered()
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override void _Ready()
+ {
+ var dialog = new ScriptCreateDialog();
+ dialog.Config("Node", "res://NewNode.cs"); // For in-engine types.
+ dialog.Config("\"res://BaseNode.cs\"", "res://DerivedNode.cs"); // For script types.
+ dialog.PopupCentered();
+ }
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml
index d5a32dd20c..28620bd29b 100644
--- a/doc/classes/ScriptEditor.xml
+++ b/doc/classes/ScriptEditor.xml
@@ -37,6 +37,7 @@
<return type="ScriptEditorBase">
</return>
<description>
+ Returns the [ScriptEditorBase] object that the user is currently editing.
</description>
</method>
<method name="get_current_script">
@@ -60,6 +61,7 @@
<return type="Array">
</return>
<description>
+ Returns an array with all [ScriptEditorBase] objects which are currently open in editor.
</description>
</method>
<method name="get_open_scripts" qualifiers="const">
@@ -95,6 +97,8 @@
<argument index="0" name="syntax_highlighter" type="EditorSyntaxHighlighter">
</argument>
<description>
+ Registers the [EditorSyntaxHighlighter] to the editor, the [EditorSyntaxHighlighter] will be available on all open scripts.
+ [b]Note:[/b] Does not apply to scripts that are already opened.
</description>
</method>
<method name="unregister_syntax_highlighter">
@@ -103,6 +107,8 @@
<argument index="0" name="syntax_highlighter" type="EditorSyntaxHighlighter">
</argument>
<description>
+ Unregisters the [EditorSyntaxHighlighter] from the editor.
+ [b]Note:[/b] The [EditorSyntaxHighlighter] will still be applied to scripts that are already opened.
</description>
</method>
</methods>
diff --git a/doc/classes/ScriptEditorBase.xml b/doc/classes/ScriptEditorBase.xml
index 9968ae06c3..ee498de302 100644
--- a/doc/classes/ScriptEditorBase.xml
+++ b/doc/classes/ScriptEditorBase.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ScriptEditorBase" inherits="VBoxContainer" version="4.0">
<brief_description>
+ Base editor for editing scripts in the [ScriptEditor].
</brief_description>
<description>
+ Base editor for editing scripts in the [ScriptEditor], this does not include documentation items.
</description>
<tutorials>
</tutorials>
@@ -13,34 +15,40 @@
<argument index="0" name="highlighter" type="Object">
</argument>
<description>
+ Adds a [EditorSyntaxHighlighter] to the open script.
</description>
</method>
</methods>
<signals>
<signal name="edited_script_changed">
<description>
+ Emitted after script validation. For visual scripts on modification.
</description>
</signal>
<signal name="go_to_help">
<argument index="0" name="what" type="String">
</argument>
<description>
+ Emitted when the user requests a specific documentation page.
</description>
</signal>
<signal name="name_changed">
<description>
+ Emitted after script validation or when the edited resource has changed. Not used by visual scripts.
</description>
</signal>
<signal name="replace_in_files_requested">
<argument index="0" name="text" type="String">
</argument>
<description>
+ Emitted when the user request to find and replace text in the file system. Not used by visual scripts.
</description>
</signal>
<signal name="request_help">
<argument index="0" name="topic" type="String">
</argument>
<description>
+ Emitted when the user requests contextual help.
</description>
</signal>
<signal name="request_open_script_at_line">
@@ -49,16 +57,19 @@
<argument index="1" name="line" type="int">
</argument>
<description>
+ Emitted when the user requests a script.
</description>
</signal>
<signal name="request_save_history">
<description>
+ Emitted when the user contextual goto and the item is in the same script.
</description>
</signal>
<signal name="search_in_files_requested">
<argument index="0" name="text" type="String">
</argument>
<description>
+ Emitted when the user request to search text in the file system. Not used by visual scripts.
</description>
</signal>
</signals>
diff --git a/doc/classes/Shape3D.xml b/doc/classes/Shape3D.xml
index 2d8bb5d051..f3e62175c6 100644
--- a/doc/classes/Shape3D.xml
+++ b/doc/classes/Shape3D.xml
@@ -13,7 +13,8 @@
</methods>
<members>
<member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.04">
- The collision margin for the shape.
+ The collision margin for the shape. Used in Bullet Physics only.
+ Collision margins allows collision detection to be more efficient by adding an extra shell around shapes. Collision algorithms are more expensive when objects overlap by more than their margin, so a higher value for margins is better for performance, at the cost of accuracy around edges as it makes them less sharp.
</member>
</members>
<constants>
diff --git a/doc/classes/Sky.xml b/doc/classes/Sky.xml
index a77515b3e6..d9553a3be3 100644
--- a/doc/classes/Sky.xml
+++ b/doc/classes/Sky.xml
@@ -52,13 +52,13 @@
Automatically selects the appropriate process mode based on your sky shader. If your shader uses [code]TIME[/code] or [code]POSITION[/code], this will use [constant PROCESS_MODE_REALTIME]. If your shader uses any of the [code]LIGHT_*[/code] variables or any custom uniforms, this uses [constant PROCESS_MODE_INCREMENTAL]. Otherwise, this defaults to [constant PROCESS_MODE_QUALITY].
</constant>
<constant name="PROCESS_MODE_QUALITY" value="1" enum="ProcessMode">
- Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples].
+ Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/reflections/sky_reflections/ggx_samples].
</constant>
<constant name="PROCESS_MODE_INCREMENTAL" value="2" enum="ProcessMode">
- Uses the same high quality importance sampling to process the radiance map as [constant PROCESS_MODE_QUALITY], but updates over several frames. The number of frames is determined by [member ProjectSettings.rendering/quality/reflections/roughness_layers]. Use this when you need highest quality radiance maps, but have a sky that updates slowly.
+ Uses the same high quality importance sampling to process the radiance map as [constant PROCESS_MODE_QUALITY], but updates over several frames. The number of frames is determined by [member ProjectSettings.rendering/reflections/sky_reflections/roughness_layers]. Use this when you need highest quality radiance maps, but have a sky that updates slowly.
</constant>
<constant name="PROCESS_MODE_REALTIME" value="3" enum="ProcessMode">
- Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. If you need better quality, but still need to update the sky every frame, consider turning on [member ProjectSettings.rendering/quality/reflections/fast_filter_high_quality].
+ Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. If you need better quality, but still need to update the sky every frame, consider turning on [member ProjectSettings.rendering/reflections/sky_reflections/fast_filter_high_quality].
[b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so [member radiance_size] must be set to [constant RADIANCE_SIZE_256].
</constant>
</constants>
diff --git a/doc/classes/SoftBody3D.xml b/doc/classes/SoftBody3D.xml
index d3ab955570..04e201e1bd 100644
--- a/doc/classes/SoftBody3D.xml
+++ b/doc/classes/SoftBody3D.xml
@@ -77,7 +77,7 @@
</method>
</methods>
<members>
- <member name="areaAngular_stiffness" type="float" setter="set_areaAngular_stiffness" getter="get_areaAngular_stiffness" default="0.5">
+ <member name="angular_stiffness" type="float" setter="set_angular_stiffness" getter="get_angular_stiffness" default="0.0">
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
The physics layers this SoftBody3D is in.
@@ -87,11 +87,11 @@
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
The physics layers this SoftBody3D scans for collisions. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
- <member name="damping_coefficient" type="float" setter="set_damping_coefficient" getter="get_damping_coefficient" default="0.01">
+ <member name="damping_coefficient" type="float" setter="set_damping_coefficient" getter="get_damping_coefficient" default="0.0">
</member>
<member name="drag_coefficient" type="float" setter="set_drag_coefficient" getter="get_drag_coefficient" default="0.0">
</member>
- <member name="linear_stiffness" type="float" setter="set_linear_stiffness" getter="get_linear_stiffness" default="0.5">
+ <member name="linear_stiffness" type="float" setter="set_linear_stiffness" getter="get_linear_stiffness" default="0.0">
</member>
<member name="parent_collision_ignore" type="NodePath" setter="set_parent_collision_ignore" getter="get_parent_collision_ignore" default="NodePath(&quot;&quot;)">
[NodePath] to a [CollisionObject3D] this SoftBody3D should avoid clipping.
@@ -103,13 +103,13 @@
<member name="ray_pickable" type="bool" setter="set_ray_pickable" getter="is_ray_pickable" default="true">
If [code]true[/code], the [SoftBody3D] will respond to [RayCast3D]s.
</member>
- <member name="simulation_precision" type="int" setter="set_simulation_precision" getter="get_simulation_precision" default="5">
+ <member name="simulation_precision" type="int" setter="set_simulation_precision" getter="get_simulation_precision" default="0">
Increasing this value will improve the resulting simulation, but can affect performance. Use with care.
</member>
- <member name="total_mass" type="float" setter="set_total_mass" getter="get_total_mass" default="1.0">
+ <member name="total_mass" type="float" setter="set_total_mass" getter="get_total_mass" default="0.0">
The SoftBody3D's mass.
</member>
- <member name="volume_stiffness" type="float" setter="set_volume_stiffness" getter="get_volume_stiffness" default="0.5">
+ <member name="volume_stiffness" type="float" setter="set_volume_stiffness" getter="get_volume_stiffness" default="0.0">
</member>
</members>
<constants>
diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml
index e674ceb57e..7e2481f458 100644
--- a/doc/classes/SpinBox.xml
+++ b/doc/classes/SpinBox.xml
@@ -6,15 +6,25 @@
<description>
SpinBox is a numerical input text field. It allows entering integers and floats.
[b]Example:[/b]
- [codeblock]
+ [codeblocks]
+ [gdscript]
var spin_box = SpinBox.new()
add_child(spin_box)
var line_edit = spin_box.get_line_edit()
line_edit.context_menu_enabled = false
spin_box.align = LineEdit.ALIGN_RIGHT
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var spinBox = new SpinBox();
+ AddChild(spinBox);
+ var lineEdit = spinBox.GetLineEdit();
+ lineEdit.ContextMenuEnabled = false;
+ spinBox.Align = LineEdit.AlignEnum.Right;
+ [/csharp]
+ [/codeblocks]
The above code will create a [SpinBox], disable context menu on it and set the text alignment to right.
See [Range] class for more options over the [SpinBox].
+ [b]Note:[/b] [SpinBox] relies on an underlying [LineEdit] node. To theme a [SpinBox]'s background, add theme items for [LineEdit] and customize them.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml
index c56596423d..e4df753674 100644
--- a/doc/classes/Sprite2D.xml
+++ b/doc/classes/Sprite2D.xml
@@ -15,12 +15,29 @@
</return>
<description>
Returns a [Rect2] representing the Sprite2D's boundary in local coordinates. Can be used to detect if the Sprite2D was clicked. Example:
- [codeblock]
+ [codeblocks]
+ [gdscript]
func _input(event):
if event is InputEventMouseButton and event.pressed and event.button_index == BUTTON_LEFT:
if get_rect().has_point(to_local(event.position)):
print("A click!")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override void _Input(InputEvent inputEvent)
+ {
+ if (inputEvent is InputEventMouseButton inputEventMouse)
+ {
+ if (inputEventMouse.Pressed &amp;&amp; inputEventMouse.ButtonIndex == (int)ButtonList.Left)
+ {
+ if (GetRect().HasPoint(ToLocal(inputEventMouse.Position)))
+ {
+ GD.Print("A click!");
+ }
+ }
+ }
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="is_pixel_opaque" qualifiers="const">
@@ -60,7 +77,7 @@
If [code]true[/code], texture is cut from a larger atlas texture. See [member region_rect].
</member>
<member name="region_filter_clip" type="bool" setter="set_region_filter_clip" getter="is_region_filter_clip_enabled" default="false">
- If [code]true[/code], the outermost pixels get blurred out.
+ If [code]true[/code], the outermost pixels get blurred out. [member region_enabled] must be [code]true[/code].
</member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )">
The region of the atlas texture to display. [member region_enabled] must be [code]true[/code].
diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml
index 44b08408c1..078520a095 100644
--- a/doc/classes/SpriteBase3D.xml
+++ b/doc/classes/SpriteBase3D.xml
@@ -102,7 +102,7 @@
This mode performs standard alpha blending. It can display translucent areas, but transparency sorting issues may be visible when multiple transparent materials are overlapping.
</constant>
<constant name="ALPHA_CUT_DISCARD" value="1" enum="AlphaCutMode">
- This mode only allows fully transparent or fully opaque pixels. Harsh edges will be visible unless some form of screen-space antialiasing is enabled (see [member ProjectSettings.rendering/quality/screen_filters/screen_space_aa]). On the bright side, this mode doesn't suffer from transparency sorting issues when multiple transparent materials are overlapping. This mode is also known as [i]alpha testing[/i] or [i]1-bit transparency[/i].
+ This mode only allows fully transparent or fully opaque pixels. Harsh edges will be visible unless some form of screen-space antialiasing is enabled (see [member ProjectSettings.rendering/anti_aliasing/quality/screen_space_aa]). On the bright side, this mode doesn't suffer from transparency sorting issues when multiple transparent materials are overlapping. This mode is also known as [i]alpha testing[/i] or [i]1-bit transparency[/i].
</constant>
<constant name="ALPHA_CUT_OPAQUE_PREPASS" value="2" enum="AlphaCutMode">
This mode draws fully opaque pixels in the depth prepass. This is slower than [constant ALPHA_CUT_DISABLED] or [constant ALPHA_CUT_DISCARD], but it allows displaying translucent areas and smooth edges while using proper sorting.
diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml
index a73d3c8212..a1b858acf6 100644
--- a/doc/classes/StreamPeer.xml
+++ b/doc/classes/StreamPeer.xml
@@ -212,9 +212,14 @@
<description>
Puts a zero-terminated ASCII string into the stream prepended by a 32-bit unsigned integer representing its size.
Note: To put an ASCII string without prepending its size, you can use [method put_data]:
- [codeblock]
+ [codeblocks]
+ [gdscript]
put_data("Hello world".to_ascii())
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ PutData("Hello World".ToAscii());
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="put_u16">
@@ -261,9 +266,14 @@
<description>
Puts a zero-terminated UTF-8 string into the stream prepended by a 32 bits unsigned integer representing its size.
Note: To put an UTF-8 string without prepending its size, you can use [method put_data]:
- [codeblock]
+ [codeblocks]
+ [gdscript]
put_data("Hello world".to_utf8())
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ PutData("Hello World".ToUTF8());
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="put_var">
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 4ee9dbf1f9..475b17d395 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -63,9 +63,18 @@
<method name="bin_to_int">
<return type="int">
</return>
- <argument index="0" name="with_prefix" type="bool" default="true">
- </argument>
<description>
+ Converts a string containing a binary number into an integer. Binary strings can either be prefixed with [code]0b[/code] or not, and they can also start with a [code]-[/code] before the optional prefix.
+ [codeblocks]
+ [gdscript]
+ print("0x101".bin_to_int()) # Prints "5".
+ print("101".bin_to_int()) # Prints "5".
+ [/gdscript]
+ [csharp]
+ GD.Print("0x101".BinToInt()); // Prints "5".
+ GD.Print("101".BinToInt()); // Prints "5".
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="c_escape">
@@ -135,13 +144,6 @@
Returns a copy of the string with indentation (leading tabs and spaces) removed.
</description>
</method>
- <method name="empty">
- <return type="bool">
- </return>
- <description>
- Returns [code]true[/code] if the length of the string equals [code]0[/code].
- </description>
- </method>
<method name="ends_with">
<return type="bool">
</return>
@@ -161,11 +163,15 @@
<description>
Returns the index of the [b]first[/b] case-sensitive occurrence of the specified string in this instance, or [code]-1[/code]. Optionally, the starting search index can be specified, continuing to the end of the string.
[b]Note:[/b] If you just want to know whether a string contains a substring, use the [code]in[/code] operator as follows:
- [codeblock]
- # Will evaluate to `false`.
- if "i" in "team":
- pass
- [/codeblock]
+ [codeblocks]
+ [gdscript]
+ print("i" in "team") # Will print `false`.
+ [/gdscript]
+ [csharp]
+ // C# has no in operator, but we can use `Contains()`.
+ GD.Print("team".Contains("i")); // Will print `false`.
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="findn">
@@ -228,34 +234,18 @@
<method name="hex_to_int">
<return type="int">
</return>
- <argument index="0" name="with_prefix" type="bool" default="true">
- </argument>
- <description>
- Converts a string containing a hexadecimal number into a decimal integer. If [code]with_prefix[/code] is [code]true[/code], the hexadecimal string should start with the [code]0x[/code] prefix, otherwise [code]0[/code] is returned.
- [codeblock]
- print("0xff".hex_to_int()) # Print "255"
- print("ab".hex_to_int(false)) # Print "171"
- [/codeblock]
- </description>
- </method>
- <method name="http_escape">
- <return type="String">
- </return>
- <description>
- Escapes (encodes) a string to URL friendly format. Also referred to as 'URL encode'.
- [codeblock]
- print("https://example.org/?escaped=" + "Godot Engine:'docs'".http_escape())
- [/codeblock]
- </description>
- </method>
- <method name="http_unescape">
- <return type="String">
- </return>
<description>
- Unescapes (decodes) a string in URL encoded format. Also referred to as 'URL decode'.
- [codeblock]
- print("https://example.org/?escaped=" + "Godot%20Engine%3A%27docs%27".http_unescape())
- [/codeblock]
+ Converts a string containing a hexadecimal number into an integer. Hexadecimal strings can either be prefixed with [code]0x[/code] or not, and they can also start with a [code]-[/code] before the optional prefix.
+ [codeblocks]
+ [gdscript]
+ print("0xff".hex_to_int()) # Prints "255".
+ print("ab".hex_to_int()) # Prints "171".
+ [/gdscript]
+ [csharp]
+ GD.Print("0xff".HexToInt()); // Prints "255".
+ GD.Print("ab".HexToInt()); // Prints "171".
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="insert">
@@ -276,6 +266,13 @@
If the string is a path to a file or directory, returns [code]true[/code] if the path is absolute.
</description>
</method>
+ <method name="is_empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the length of the string equals [code]0[/code].
+ </description>
+ </method>
<method name="is_rel_path">
<return type="bool">
</return>
@@ -361,9 +358,14 @@
<description>
Return a [String] which is the concatenation of the [code]parts[/code]. The separator between elements is the string providing this method.
Example:
- [codeblock]
+ [codeblocks]
+ [gdscript]
print(", ".join(["One", "Two", "Three", "Four"]))
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ GD.Print(String.Join(",", new string[] {"One", "Two", "Three", "Four"}));
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="json_escape">
@@ -406,7 +408,8 @@
<argument index="0" name="chars" type="String">
</argument>
<description>
- Returns a copy of the string with characters removed from the left.
+ Returns a copy of the string with characters removed from the left. The [code]chars[/code] argument is a string specifying the set of characters to be removed.
+ [b]Note:[/b] The [code]chars[/code] is not a prefix. See [method trim_prefix] method that will remove a single prefix string rather than a set of characters.
</description>
</method>
<method name="match">
@@ -546,15 +549,6 @@
<description>
</description>
</method>
- <method name="ord_at">
- <return type="int">
- </return>
- <argument index="0" name="at" type="int">
- </argument>
- <description>
- Returns the character code at position [code]at[/code].
- </description>
- </method>
<method name="pad_decimals">
<return type="String">
</return>
@@ -573,20 +567,6 @@
Formats a number to have an exact number of [code]digits[/code] before the decimal point.
</description>
</method>
- <method name="percent_decode">
- <return type="String">
- </return>
- <description>
- Decode a percent-encoded string. See [method percent_encode].
- </description>
- </method>
- <method name="percent_encode">
- <return type="String">
- </return>
- <description>
- Percent-encodes a string. Encodes parameters in a URL when sending a HTTP GET request (and bodies of form-urlencoded POST requests).
- </description>
- </method>
<method name="plus_file">
<return type="String">
</return>
@@ -683,13 +663,18 @@
The splits in the returned array are sorted in the same order as the original string, from left to right.
If [code]maxsplit[/code] is specified, it defines the number of splits to do from the right up to [code]maxsplit[/code]. The default value of 0 means that all items are split, thus giving the same result as [method split].
Example:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var some_string = "One,Two,Three,Four"
var some_array = some_string.rsplit(",", true, 1)
print(some_array.size()) # Prints 2
print(some_array[0]) # Prints "Four"
print(some_array[1]) # Prints "Three,Two,One"
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ // There is no Rsplit.
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="rstrip">
@@ -698,7 +683,8 @@
<argument index="0" name="chars" type="String">
</argument>
<description>
- Returns a copy of the string with characters removed from the right.
+ Returns a copy of the string with characters removed from the right. The [code]chars[/code] argument is a string specifying the set of characters to be removed.
+ [b]Note:[/b] The [code]chars[/code] is not a suffix. See [method trim_suffix] method that will remove a single suffix string rather than a set of characters.
</description>
</method>
<method name="sha1_buffer">
@@ -751,13 +737,21 @@
Splits the string by a [code]delimiter[/code] string and returns an array of the substrings. The [code]delimiter[/code] can be of any length.
If [code]maxsplit[/code] is specified, it defines the number of splits to do from the left up to [code]maxsplit[/code]. The default value of [code]0[/code] means that all items are split.
Example:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var some_string = "One,Two,Three,Four"
var some_array = some_string.split(",", true, 1)
print(some_array.size()) # Prints 2
- print(some_array[0]) # Prints "One"
- print(some_array[1]) # Prints "Two,Three,Four"
- [/codeblock]
+ print(some_array[0]) # Prints "Four"
+ print(some_array[1]) # Prints "Three,Two,One"
+ [/gdscript]
+ [csharp]
+ var someString = "One,Two,Three,Four";
+ var someArray = someString.Split(",", true); // This is as close as it gets to Godots API.
+ GD.Print(someArray[0]); // Prints "Four"
+ GD.Print(someArray[1]); // Prints "Three,Two,One"
+ [/csharp]
+ [/codeblocks]
If you need to split strings with more complex rules, use the [RegEx] class instead.
</description>
</method>
@@ -876,6 +870,52 @@
Removes a given string from the end if it ends with it or leaves the string unchanged.
</description>
</method>
+ <method name="unicode_at">
+ <return type="int">
+ </return>
+ <argument index="0" name="at" type="int">
+ </argument>
+ <description>
+ Returns the character code at position [code]at[/code].
+ </description>
+ </method>
+ <method name="uri_decode">
+ <return type="String">
+ </return>
+ <description>
+ Decodes a string in URL encoded format. This is meant to decode parameters in a URL when receiving an HTTP request.
+ [codeblocks]
+ [gdscript]
+ print("https://example.org/?escaped=" + "Godot%20Engine%3A%27docs%27".uri_decode())
+ [/gdscript]
+ [csharp]
+ GD.Print("https://example.org/?escaped=" + "Godot%20Engine%3a%27Docs%27".URIDecode());
+ [/csharp]
+ [/codeblocks]
+ </description>
+ </method>
+ <method name="uri_encode">
+ <return type="String">
+ </return>
+ <description>
+ Encodes a string to URL friendly format. This is meant to encode parameters in a URL when sending an HTTP request.
+ [codeblocks]
+ [gdscript]
+ print("https://example.org/?escaped=" + "Godot Engine:'docs'".uri_encode())
+ [/gdscript]
+ [csharp]
+ GD.Print("https://example.org/?escaped=" + "Godot Engine:'docs'".URIEncode());
+ [/csharp]
+ [/codeblocks]
+ </description>
+ </method>
+ <method name="validate_node_name">
+ <return type="String">
+ </return>
+ <description>
+ Removes any characters from the string that are prohibited in [Node] names ([code].[/code] [code]:[/code] [code]@[/code] [code]/[/code] [code]"[/code]).
+ </description>
+ </method>
<method name="xml_escape">
<return type="String">
</return>
diff --git a/doc/classes/StyleBox.xml b/doc/classes/StyleBox.xml
index 525dba0549..a01dfbd4b8 100644
--- a/doc/classes/StyleBox.xml
+++ b/doc/classes/StyleBox.xml
@@ -39,7 +39,7 @@
<method name="get_default_margin" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
Returns the default margin of the specified [enum Side].
@@ -48,7 +48,7 @@
<method name="get_margin" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
Returns the content margin offset for the specified [enum Side].
@@ -72,7 +72,7 @@
<method name="set_default_margin">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="offset" type="float">
</argument>
diff --git a/doc/classes/StyleBoxFlat.xml b/doc/classes/StyleBoxFlat.xml
index 71f227dfb0..d66ae210ec 100644
--- a/doc/classes/StyleBoxFlat.xml
+++ b/doc/classes/StyleBoxFlat.xml
@@ -4,12 +4,12 @@
Customizable [StyleBox] with a given set of parameters (no texture required).
</brief_description>
<description>
- This [StyleBox] can be used to achieve all kinds of looks without the need of a texture. Those properties are customizable:
+ This [StyleBox] can be used to achieve all kinds of looks without the need of a texture. The following properties are customizable:
- Color
- Border width (individual width for each border)
- Rounded corners (individual radius for each corner)
- Shadow (with blur and offset)
- Setting corner radius to high values is allowed. As soon as corners would overlap, the stylebox will switch to a relative system. Example:
+ Setting corner radius to high values is allowed. As soon as corners overlap, the stylebox will switch to a relative system. Example:
[codeblock]
height = 30
corner_radius_top_left = 50
@@ -27,7 +27,7 @@
<method name="get_border_width" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
Returns the specified [enum Side]'s border width.
@@ -52,7 +52,7 @@
<method name="get_expand_margin" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
Returns the size of the specified [enum Side]'s expand margin.
@@ -61,7 +61,7 @@
<method name="set_border_width">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="width" type="int">
</argument>
@@ -116,7 +116,7 @@
<method name="set_expand_margin">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="size" type="float">
</argument>
@@ -178,8 +178,8 @@
Border width for the top border.
</member>
<member name="corner_detail" type="int" setter="set_corner_detail" getter="get_corner_detail" default="8">
- This sets the amount of vertices used for each corner. Higher values result in rounder corners but take more processing power to compute. When choosing a value, you should take the corner radius ([method set_corner_radius_all]) into account.
- For corner radii smaller than 10, [code]4[/code] or [code]5[/code] should be enough. For corner radii smaller than 30, values between [code]8[/code] and [code]12[/code] should be enough.
+ This sets the number of vertices used for each corner. Higher values result in rounder corners but take more processing power to compute. When choosing a value, you should take the corner radius ([method set_corner_radius_all]) into account.
+ For corner radii less than 10, [code]4[/code] or [code]5[/code] should be enough. For corner radii less than 30, values between [code]8[/code] and [code]12[/code] should be enough.
A corner detail of [code]1[/code] will result in chamfered corners instead of rounded corners, which is useful for some artistic effects.
</member>
<member name="corner_radius_bottom_left" type="int" setter="set_corner_radius" getter="get_corner_radius" default="0">
diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml
index 5b17f25978..895d0c357d 100644
--- a/doc/classes/StyleBoxTexture.xml
+++ b/doc/classes/StyleBoxTexture.xml
@@ -12,7 +12,7 @@
<method name="get_expand_margin_size" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
Returns the expand margin size of the specified [enum Side].
@@ -21,7 +21,7 @@
<method name="get_margin_size" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
Returns the margin size of the specified [enum Side].
@@ -54,7 +54,7 @@
<method name="set_expand_margin_size">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="size" type="float">
</argument>
@@ -65,7 +65,7 @@
<method name="set_margin_size">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="size" type="float">
</argument>
diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml
index 82ffe86251..d145b4ce97 100644
--- a/doc/classes/SurfaceTool.xml
+++ b/doc/classes/SurfaceTool.xml
@@ -5,13 +5,22 @@
</brief_description>
<description>
The [SurfaceTool] is used to construct a [Mesh] by specifying vertex attributes individually. It can be used to construct a [Mesh] from a script. All properties except indices need to be added before calling [method add_vertex]. For example, to add vertex colors and UVs:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_color(Color(1, 0, 0))
st.set_uv(Vector2(0, 0))
st.set_vertex(Vector3(0, 0, 0))
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var st = new SurfaceTool();
+ st.Begin(Mesh.PrimitiveType.Triangles);
+ st.SetColor(new Color(1, 0, 0));
+ st.SetUv(new Vector2(0, 0));
+ st.SetVertex(new Vector3(0, 0, 0));
+ [/csharp]
+ [/codeblocks]
The above [SurfaceTool] now contains one vertex of a triangle which has a UV coordinate and a specified [Color]. If another vertex were added without calling [method set_uv] or [method set_color], then the last values would be used.
Vertex attributes must be passed [b]before[/b] calling [method add_vertex]. Failure to do so will result in an error when committing the vertex information to a mesh.
Additionally, the attributes used before the first vertex is added determine the format of the mesh. For example, if you only add UVs to the first vertex, you cannot add color to any of the subsequent vertices.
@@ -31,15 +40,6 @@
Adds an index to index array if you are using indexed vertices. Does not need to be called before adding vertices.
</description>
</method>
- <method name="add_smooth_group">
- <return type="void">
- </return>
- <argument index="0" name="smooth" type="bool">
- </argument>
- <description>
- Specifies whether the current vertex (if using only vertex arrays) or current index (if also using index arrays) should use smooth normals for normal calculation.
- </description>
- </method>
<method name="add_triangle_fan">
<return type="void">
</return>
@@ -148,14 +148,24 @@
Removes the index array by expanding the vertex array.
</description>
</method>
+ <method name="generate_lod">
+ <return type="PackedInt32Array">
+ </return>
+ <argument index="0" name="nd_threshold" type="float">
+ </argument>
+ <argument index="1" name="target_index_count" type="int" default="3">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="generate_normals">
<return type="void">
</return>
<argument index="0" name="flip" type="bool" default="false">
</argument>
<description>
- Generates normals from vertices so you do not have to do it manually. If [code]flip[/code] is [code]true[/code], the resulting normals will be inverted.
- Requires the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES].
+ Generates normals from vertices so you do not have to do it manually. If [code]flip[/code] is [code]true[/code], the resulting normals will be inverted. [method generate_normals] should be called [i]after[/i] generating geometry and [i]before[/i] committing the mesh using [method commit] or [method commit_to_arrays].
+ [b]Note:[/b] [method generate_normals] only works if the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES].
</description>
</method>
<method name="generate_tangents">
@@ -173,6 +183,12 @@
<description>
</description>
</method>
+ <method name="get_max_axis_length" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_skin_weight_count" qualifiers="const">
<return type="int" enum="SurfaceTool.SkinWeightCount">
</return>
@@ -186,6 +202,12 @@
Shrinks the vertex array by creating an index array (avoids reusing vertices).
</description>
</method>
+ <method name="optimize_indices_for_cache">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_bones">
<return type="void">
</return>
@@ -251,6 +273,15 @@
<description>
</description>
</method>
+ <method name="set_smooth_group">
+ <return type="void">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ Specifies whether the current vertex (if using only vertex arrays) or current index (if also using index arrays) should use smooth normals for normal calculation.
+ </description>
+ </method>
<method name="set_tangent">
<return type="void">
</return>
diff --git a/doc/classes/SyntaxHighlighter.xml b/doc/classes/SyntaxHighlighter.xml
index 2d6e3de02a..642d75fa9b 100644
--- a/doc/classes/SyntaxHighlighter.xml
+++ b/doc/classes/SyntaxHighlighter.xml
@@ -1,50 +1,83 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SyntaxHighlighter" inherits="Resource" version="4.0">
<brief_description>
+ Base Syntax highlighter resource for [TextEdit].
</brief_description>
<description>
+ Base syntax highlighter resource all syntax highlighters extend from, provides syntax highlighting data to [TextEdit].
+ The associated [TextEdit] node will call into the [SyntaxHighlighter] on a as needed basis.
+ [b]Note:[/b] Each Syntax highlighter instance should not be shared across multiple [TextEdit] nodes.
</description>
<tutorials>
</tutorials>
<methods>
+ <method name="_clear_highlighting_cache" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <description>
+ Virtual method which can be overridden to clear any local caches.
+ </description>
+ </method>
<method name="_get_line_syntax_highlighting" qualifiers="virtual">
<return type="Dictionary">
</return>
- <argument index="0" name="p_line" type="int">
+ <argument index="0" name="line" type="int">
</argument>
<description>
+ Virtual method which can be overridden to return syntax highlighting data.
+ See [method get_line_syntax_highlighting] for more details.
</description>
</method>
<method name="_update_cache" qualifiers="virtual">
<return type="void">
</return>
<description>
+ Virtual method which can be overridden to update any local caches.
</description>
</method>
<method name="clear_highlighting_cache">
<return type="void">
</return>
<description>
+ Clears all cached syntax highlighting data.
+ Then calls overridable method [method _clear_highlighting_cache].
</description>
</method>
<method name="get_line_syntax_highlighting">
<return type="Dictionary">
</return>
- <argument index="0" name="p_line" type="int">
+ <argument index="0" name="line" type="int">
</argument>
<description>
+ Returns syntax highlighting data for a single line. If the line is not cached, calls [method _get_line_syntax_highlighting] to calculate the data.
+ The return [Dictionary] is column number to [Dictionary]. The column number notes the start of a region, the region will end if another region is found, or at the end of the line. The nested [Dictionary] contains the data for that region, currently only the key "color" is supported.
+ [b]Example return:[/b]
+ [codeblock]
+ var color_map = {
+ 0: {
+ "color": Color(1, 0, 0)
+ },
+ 5: {
+ "color": Color(0, 1, 0)
+ }
+ }
+ [/codeblock]
+ This will color columns 0-4 red, and columns 5-eol in green.
</description>
</method>
<method name="get_text_edit">
<return type="TextEdit">
</return>
<description>
+ Returns the associated [TextEdit] node.
</description>
</method>
<method name="update_cache">
<return type="void">
</return>
<description>
+ Clears then updates the [SyntaxHighlighter] caches. Override [method _update_cache] for a callback.
+ [b]Note:[/b] This is called automatically when the associated [TextEdit] node, updates its own cache.
</description>
</method>
</methods>
diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml
index c9ed1aaec9..ddf6b465a4 100644
--- a/doc/classes/TabContainer.xml
+++ b/doc/classes/TabContainer.xml
@@ -137,6 +137,9 @@
</method>
</methods>
<members>
+ <member name="all_tabs_in_front" type="bool" setter="set_all_tabs_in_front" getter="is_all_tabs_in_front" default="false">
+ If [code]true[/code], all tabs are drawn in front of the panel. If [code]false[/code], inactive tabs are drawn behind the panel.
+ </member>
<member name="current_tab" type="int" setter="set_current_tab" getter="get_current_tab" default="0">
The current tab index. When set, this index's [Control] node's [code]visible[/code] property is set to [code]true[/code] and all others are set to [code]false[/code].
</member>
@@ -149,9 +152,6 @@
<member name="tabs_visible" type="bool" setter="set_tabs_visible" getter="are_tabs_visible" default="true">
If [code]true[/code], tabs are visible. If [code]false[/code], tabs' content and titles are hidden.
</member>
- <member name="all_tabs_in_front" type="bool" setter="set_all_tabs_in_front" getter="is_all_tabs_in_front" default="false">
- If [code]true[/code], all tabs are drawn in front of the panel. If [code]false[/code], inactive tabs are drawn behind the panel.
- </member>
<member name="use_hidden_tabs_for_min_size" type="bool" setter="set_use_hidden_tabs_for_min_size" getter="get_use_hidden_tabs_for_min_size" default="false">
If [code]true[/code], children [Control] nodes that are hidden have their minimum size take into account in the total, instead of only the currently visible one.
</member>
@@ -198,18 +198,21 @@
<theme_item name="font" type="Font">
The font used to draw tab names.
</theme_item>
- <theme_item name="font_color_bg" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )">
- Font color of inactive tabs.
- </theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
Font color of disabled tabs.
</theme_item>
- <theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the tab name.
+ </theme_item>
+ <theme_item name="font_selected_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
Font color of the currently selected tab.
</theme_item>
<theme_item name="font_size" type="int">
Font size of the tab names.
</theme_item>
+ <theme_item name="font_unselected_color" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )">
+ Font color of the other, unselected tabs.
+ </theme_item>
<theme_item name="icon_separation" type="int" default="4">
Space between tab's name and its icon.
</theme_item>
@@ -225,20 +228,23 @@
<theme_item name="menu_highlight" type="Texture2D">
The icon for the menu button (see [method set_popup]) when it's being hovered with the cursor.
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the tab text outline.
+ </theme_item>
<theme_item name="panel" type="StyleBox">
The style for the background fill.
</theme_item>
<theme_item name="side_margin" type="int" default="8">
The space at the left and right edges of the tab bar.
</theme_item>
- <theme_item name="tab_bg" type="StyleBox">
- The style of inactive tabs.
- </theme_item>
<theme_item name="tab_disabled" type="StyleBox">
The style of disabled tabs.
</theme_item>
- <theme_item name="tab_fg" type="StyleBox">
+ <theme_item name="tab_selected" type="StyleBox">
The style of the currently selected tab.
</theme_item>
+ <theme_item name="tab_unselected" type="StyleBox">
+ The style of the other, unselected tabs.
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml
index 47cf869fe9..df9680bf28 100644
--- a/doc/classes/Tabs.xml
+++ b/doc/classes/Tabs.xml
@@ -359,18 +359,21 @@
<theme_item name="font" type="Font">
The font used to draw tab names.
</theme_item>
- <theme_item name="font_color_bg" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )">
- Font color of inactive tabs.
- </theme_item>
- <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
+ <theme_item name="font_disabled_color" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )">
Font color of disabled tabs.
</theme_item>
- <theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the tab name.
+ </theme_item>
+ <theme_item name="font_selected_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
Font color of the currently selected tab.
</theme_item>
<theme_item name="font_size" type="int">
Font size of the tab names.
</theme_item>
+ <theme_item name="font_unselected_color" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )">
+ Font color of the other, unselected tabs.
+ </theme_item>
<theme_item name="hseparation" type="int" default="4">
The horizontal separation between the tabs.
</theme_item>
@@ -380,16 +383,19 @@
<theme_item name="increment_highlight" type="Texture2D">
Icon for the right arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor.
</theme_item>
- <theme_item name="panel" type="StyleBox">
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the tab text outline.
</theme_item>
- <theme_item name="tab_bg" type="StyleBox">
- The style of an inactive tab.
+ <theme_item name="panel" type="StyleBox">
</theme_item>
<theme_item name="tab_disabled" type="StyleBox">
- The style of a disabled tab
+ The style of disabled tabs.
</theme_item>
- <theme_item name="tab_fg" type="StyleBox">
+ <theme_item name="tab_selected" type="StyleBox">
The style of the currently selected tab.
</theme_item>
+ <theme_item name="tab_unselected" type="StyleBox">
+ The style of the other, unselected tabs.
+ </theme_item>
</theme_items>
</class>
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index eedf3b848f..088bcd1c3c 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -402,13 +402,24 @@
<description>
Perform a search inside the text. Search flags can be specified in the [enum SearchFlags] enum.
Returns an empty [code]Dictionary[/code] if no result was found. Otherwise, returns a [code]Dictionary[/code] containing [code]line[/code] and [code]column[/code] entries, e.g:
- [codeblock]
- var result = search(key, flags, line, column)
+ [codeblocks]
+ [gdscript]
+ var result = search("print", SEARCH_WHOLE_WORDS, 0, 0)
if !result.empty():
# Result found.
var line_number = result.line
var column_number = result.column
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ int[] result = Search("print", (uint)TextEdit.SearchFlags.WholeWords, 0, 0);
+ if (result.Length &gt; 0)
+ {
+ // Result found.
+ int lineNumber = result[(int)TextEdit.SearchResult.Line];
+ int columnNumber = result[(int)TextEdit.SearchResult.Column];
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="select">
@@ -697,7 +708,7 @@
</member>
<member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" />
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false">
- If [code]true[/code], custom [code]font_color_selected[/code] will be used for selected text.
+ If [code]true[/code], custom [code]font_selected_color[/code] will be used for selected text.
</member>
<member name="readonly" type="bool" setter="set_readonly" getter="is_readonly" default="false">
If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added.
@@ -725,6 +736,7 @@
Set additional options for BiDi override.
</member>
<member name="syntax_highlighter" type="SyntaxHighlighter" setter="set_syntax_highlighter" getter="get_syntax_highlighter">
+ Sets the [SyntaxHighlighter] to use.
</member>
<member name="text" type="String" setter="set_text" getter="get_text" default="&quot;&quot;">
String value of the [TextEdit].
@@ -914,7 +926,7 @@
</constants>
<theme_items>
<theme_item name="background_color" type="Color" default="Color( 0, 0, 0, 0 )">
- Sets the background [Color] of this [TextEdit]. [member syntax_highlighting] has to be enabled.
+ Sets the background [Color] of this [TextEdit].
</theme_item>
<theme_item name="brace_mismatch_color" type="Color" default="Color( 1, 0.2, 0.2, 1 )">
</theme_item>
@@ -953,9 +965,12 @@
<theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )">
Sets the font [Color].
</theme_item>
- <theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the [TextEdit].
</theme_item>
- <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )">
+ <theme_item name="font_readonly_color" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
+ </theme_item>
+ <theme_item name="font_selected_color" type="Color" default="Color( 0, 0, 0, 1 )">
Sets the [Color] of the selected text. [member override_selected_font_color] has to be enabled.
</theme_item>
<theme_item name="font_size" type="int">
@@ -970,6 +985,9 @@
<theme_item name="normal" type="StyleBox">
Sets the [StyleBox] of this [TextEdit].
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="read_only" type="StyleBox">
Sets the [StyleBox] of this [TextEdit] when [member readonly] is enabled.
</theme_item>
diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml
index fabf22eef7..99eb8b81d4 100644
--- a/doc/classes/TextParagraph.xml
+++ b/doc/classes/TextParagraph.xml
@@ -49,6 +49,13 @@
Clears text paragraph (removes text and inline objects).
</description>
</method>
+ <method name="clear_dropcap">
+ <return type="void">
+ </return>
+ <description>
+ Removes dropcap.
+ </description>
+ </method>
<method name="draw" qualifiers="const">
<return type="void">
</return>
@@ -58,8 +65,38 @@
</argument>
<argument index="2" name="color" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
+ <argument index="3" name="dc_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ </argument>
<description>
- Draw text into a canvas item at a given position, with [code]color[/code]. [code]pos[/code] specifies the top left corner of the bounding box.
+ Draw all lines of the text and drop cap into a canvas item at a given position, with [code]color[/code]. [code]pos[/code] specifies the top left corner of the bounding box.
+ </description>
+ </method>
+ <method name="draw_dropcap" qualifiers="const">
+ <return type="void">
+ </return>
+ <argument index="0" name="canvas" type="RID">
+ </argument>
+ <argument index="1" name="pos" type="Vector2">
+ </argument>
+ <argument index="2" name="color" type="Color" default="Color( 1, 1, 1, 1 )">
+ </argument>
+ <description>
+ Draw drop cap into a canvas item at a given position, with [code]color[/code]. [code]pos[/code] specifies the top left corner of the bounding box.
+ </description>
+ </method>
+ <method name="draw_dropcap_outline" qualifiers="const">
+ <return type="void">
+ </return>
+ <argument index="0" name="canvas" type="RID">
+ </argument>
+ <argument index="1" name="pos" type="Vector2">
+ </argument>
+ <argument index="2" name="outline_size" type="int" default="1">
+ </argument>
+ <argument index="3" name="color" type="Color" default="Color( 1, 1, 1, 1 )">
+ </argument>
+ <description>
+ Draw drop cap outline into a canvas item at a given position, with [code]color[/code]. [code]pos[/code] specifies the top left corner of the bounding box.
</description>
</method>
<method name="draw_line" qualifiers="const">
@@ -99,14 +136,37 @@
</return>
<argument index="0" name="canvas" type="RID">
</argument>
- <argument index="1" name="outline_size" type="Vector2">
+ <argument index="1" name="pos" type="Vector2">
+ </argument>
+ <argument index="2" name="outline_size" type="int" default="1">
</argument>
- <argument index="2" name="color" type="int" default="1">
+ <argument index="3" name="color" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
- <argument index="3" name="arg3" type="Color" default="Color( 1, 1, 1, 1 )">
+ <argument index="4" name="dc_color" type="Color" default="Color( 1, 1, 1, 1 )">
</argument>
<description>
- Draw outline of the text into a canvas item at a given position, with [code]color[/code]. [code]pos[/code] specifies the top left corner of the bounding box.
+ Draw outilines of all lines of the text and drop cap into a canvas item at a given position, with [code]color[/code]. [code]pos[/code] specifies the top left corner of the bounding box.
+ </description>
+ </method>
+ <method name="get_dropcap_lines" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns number of lines used by dropcap.
+ </description>
+ </method>
+ <method name="get_dropcap_rid" qualifiers="const">
+ <return type="RID">
+ </return>
+ <description>
+ Return drop cap text buffer RID.
+ </description>
+ </method>
+ <method name="get_dropcap_size" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ Returns drop cap bounding box size.
</description>
</method>
<method name="get_line_ascent" qualifiers="const">
@@ -261,6 +321,26 @@
Override ranges should cover full source text without overlaps. BiDi algorithm will be used on each range separately.
</description>
</method>
+ <method name="set_dropcap">
+ <return type="bool">
+ </return>
+ <argument index="0" name="text" type="String">
+ </argument>
+ <argument index="1" name="fonts" type="Font">
+ </argument>
+ <argument index="2" name="size" type="int">
+ </argument>
+ <argument index="3" name="dropcap_margins" type="Rect2" default="Rect2( 0, 0, 0, 0 )">
+ </argument>
+ <argument index="4" name="opentype_features" type="Dictionary" default="{
+}">
+ </argument>
+ <argument index="5" name="language" type="String" default="&quot;&quot;">
+ </argument>
+ <description>
+ Sets drop cap, overrides previously set drop cap. Drop cap (dropped capital) is a decorative element at the beginning of a paragraph that is larger than the rest of the text.
+ </description>
+ </method>
<method name="tab_align">
<return type="void">
</return>
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index 791646000b..5635ec2be0 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -9,6 +9,19 @@
<tutorials>
</tutorials>
<methods>
+ <method name="create_font_bitmap">
+ <return type="RID">
+ </return>
+ <argument index="0" name="height" type="float">
+ </argument>
+ <argument index="1" name="ascent" type="float">
+ </argument>
+ <argument index="2" name="base_size" type="int">
+ </argument>
+ <description>
+ Creates new, empty bitmap font. To free the resulting font, use [method free_rid] method.
+ </description>
+ </method>
<method name="create_font_memory">
<return type="RID">
</return>
@@ -78,6 +91,51 @@
Draws box displaying character hexadecimal code. Used for replacing missing characters.
</description>
</method>
+ <method name="font_bitmap_add_char">
+ <return type="void">
+ </return>
+ <argument index="0" name="font" type="RID">
+ </argument>
+ <argument index="1" name="char" type="int">
+ </argument>
+ <argument index="2" name="texture_idx" type="int">
+ </argument>
+ <argument index="3" name="rect" type="Rect2">
+ </argument>
+ <argument index="4" name="align" type="Vector2">
+ </argument>
+ <argument index="5" name="advance" type="float">
+ </argument>
+ <description>
+ Adds a character to the font, where [code]character[/code] is the Unicode value, [code]texture[/code] is the texture index, [code]rect[/code] is the region in the texture (in pixels!), [code]align[/code] is the (optional) alignment for the character and [code]advance[/code] is the (optional) advance.
+ </description>
+ </method>
+ <method name="font_bitmap_add_kerning_pair">
+ <return type="void">
+ </return>
+ <argument index="0" name="font" type="RID">
+ </argument>
+ <argument index="1" name="A" type="int">
+ </argument>
+ <argument index="2" name="B" type="int">
+ </argument>
+ <argument index="3" name="kerning" type="int">
+ </argument>
+ <description>
+ Adds a kerning pair to the bitmap font as a difference. Kerning pairs are special cases where a typeface advance is determined by the next character.
+ </description>
+ </method>
+ <method name="font_bitmap_add_texture">
+ <return type="void">
+ </return>
+ <argument index="0" name="font" type="RID">
+ </argument>
+ <argument index="1" name="texture" type="Texture">
+ </argument>
+ <description>
+ Adds a texture to the bitmap font.
+ </description>
+ </method>
<method name="font_draw_glyph" qualifiers="const">
<return type="Vector2">
</return>
@@ -295,6 +353,24 @@
Returns list of script support overrides.
</description>
</method>
+ <method name="font_get_spacing_glyph" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="font" type="RID">
+ </argument>
+ <description>
+ Returns extra spacing for each glyphs in pixels.
+ </description>
+ </method>
+ <method name="font_get_spacing_space" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="font" type="RID">
+ </argument>
+ <description>
+ Sets extra spacing for each glyphs in pixels.
+ </description>
+ </method>
<method name="font_get_supported_chars" qualifiers="const">
<return type="String">
</return>
@@ -490,6 +566,28 @@
Adds override for [method font_is_script_supported].
</description>
</method>
+ <method name="font_set_spacing_glyph">
+ <return type="void">
+ </return>
+ <argument index="0" name="font" type="RID">
+ </argument>
+ <argument index="1" name="value" type="int">
+ </argument>
+ <description>
+ Returns extra spacing for the space character in pixels.
+ </description>
+ </method>
+ <method name="font_set_spacing_space">
+ <return type="void">
+ </return>
+ <argument index="0" name="font" type="RID">
+ </argument>
+ <argument index="1" name="value" type="int">
+ </argument>
+ <description>
+ Sets extra spacing for the space character in pixels.
+ </description>
+ </method>
<method name="font_set_variation">
<return type="void">
</return>
@@ -655,7 +753,7 @@
<method name="shaped_text_clear">
<return type="void">
</return>
- <argument index="0" name="arg0" type="RID">
+ <argument index="0" name="rid" type="RID">
</argument>
<description>
Clears text buffer (removes text and inline objects).
diff --git a/doc/classes/TextureProgressBar.xml b/doc/classes/TextureProgressBar.xml
index cfc8f16648..b40759578f 100644
--- a/doc/classes/TextureProgressBar.xml
+++ b/doc/classes/TextureProgressBar.xml
@@ -12,7 +12,7 @@
<method name="get_stretch_margin" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<description>
</description>
@@ -20,7 +20,7 @@
<method name="set_stretch_margin">
<return type="void">
</return>
- <argument index="0" name="side" type="int" enum="Side">
+ <argument index="0" name="margin" type="int" enum="Side">
</argument>
<argument index="1" name="value" type="int">
</argument>
diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml
index 3f7f22ebcd..9f976838e9 100644
--- a/doc/classes/Theme.xml
+++ b/doc/classes/Theme.xml
@@ -236,7 +236,8 @@
<argument index="1" name="node_type" type="StringName">
</argument>
<description>
- Returns the icon [StyleBox] at [code]name[/code] if the theme has [code]node_type[/code].
+ Returns the [StyleBox] at [code]name[/code] if the theme has [code]node_type[/code].
+ Valid [code]name[/code]s may be found using [method get_stylebox_list]. Valid [code]node_type[/code]s may be found using [method get_stylebox_type_list].
</description>
</method>
<method name="get_stylebox_list" qualifiers="const">
@@ -246,6 +247,7 @@
</argument>
<description>
Returns all the [StyleBox]s as a [PackedStringArray] filled with each [StyleBox]'s name, for use in [method get_stylebox], if the theme has [code]node_type[/code].
+ Valid [code]node_type[/code]s may be found using [method get_stylebox_type_list].
</description>
</method>
<method name="get_stylebox_type_list" qualifiers="const">
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index c500052592..7ed8ad6d4a 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Node for 2D tile-based maps. Tilemaps use a [TileSet] which contain a list of tiles (textures plus optional collision, navigation, and/or occluder shapes) which are used to create grid-based maps.
+ When doing physics queries against the tilemap, the cell coordinates are encoded as [code]metadata[/code] for each detected collision shape returned by methods such as [method PhysicsDirectSpaceState2D.intersect_shape], [method PhysicsDirectBodyState2D.get_contact_collider_shape_metadata] etc.
</description>
<tutorials>
<link title="Using Tilemaps">https://docs.godotengine.org/en/latest/tutorials/2d/using_tilemaps.html</link>
@@ -143,7 +144,7 @@
<argument index="1" name="ignore_half_ofs" type="bool" default="false">
</argument>
<description>
- Returns the global position corresponding to the given tilemap (grid-based) coordinates.
+ Returns the local position corresponding to the given tilemap (grid-based) coordinates.
Optionally, the tilemap's half offset can be ignored.
</description>
</method>
@@ -171,12 +172,22 @@
[b]Note:[/b] Data such as navigation polygons and collision shapes are not immediately updated for performance reasons.
If you need these to be immediately updated, you can call [method update_dirty_quadrants].
Overriding this method also overrides it internally, allowing custom logic to be implemented when tiles are placed/removed:
- [codeblock]
+ [codeblocks]
+ [gdscript]
func set_cell(x, y, tile, flip_x=false, flip_y=false, transpose=false, autotile_coord=Vector2())
# Write your custom logic here.
# To call the default method:
.set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public void SetCell(int x, int y, int tile, bool flipX = false, bool flipY = false, bool transpose = false, Vector2 autotileCoord = new Vector2())
+ {
+ // Write your custom logic here.
+ // To call the default method:
+ base.SetCell(x, y, tile, flipX, flipY, transpose, autotileCoord);
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="set_cellv">
@@ -261,6 +272,9 @@
</method>
</methods>
<members>
+ <member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false">
+ If [code]true[/code], this TileMap bakes a navigation region.
+ </member>
<member name="cell_clip_uv" type="bool" setter="set_clip_uv" getter="get_clip_uv" default="false">
If [code]true[/code], the cell's UVs will be clipped.
</member>
diff --git a/doc/classes/Timer.xml b/doc/classes/Timer.xml
index ab75e21ce8..5265e75429 100644
--- a/doc/classes/Timer.xml
+++ b/doc/classes/Timer.xml
@@ -47,8 +47,8 @@
<member name="paused" type="bool" setter="set_paused" getter="is_paused">
If [code]true[/code], the timer is paused and will not process until it is unpaused again, even if [method start] is called.
</member>
- <member name="process_mode" type="int" setter="set_timer_process_mode" getter="get_timer_process_mode" enum="Timer.TimerProcessMode" default="1">
- Processing mode. See [enum TimerProcessMode].
+ <member name="process_callback" type="int" setter="set_timer_process_callback" getter="get_timer_process_callback" enum="Timer.TimerProcessCallback" default="1">
+ Processing callback. See [enum TimerProcessCallback].
</member>
<member name="time_left" type="float" setter="" getter="get_time_left">
The timer's remaining time in seconds. Returns 0 if the timer is inactive.
@@ -66,10 +66,10 @@
</signal>
</signals>
<constants>
- <constant name="TIMER_PROCESS_PHYSICS" value="0" enum="TimerProcessMode">
+ <constant name="TIMER_PROCESS_PHYSICS" value="0" enum="TimerProcessCallback">
Update the timer during the physics step at each frame (fixed framerate processing).
</constant>
- <constant name="TIMER_PROCESS_IDLE" value="1" enum="TimerProcessMode">
+ <constant name="TIMER_PROCESS_IDLE" value="1" enum="TimerProcessCallback">
Update the timer during the idle time at each frame.
</constant>
</constants>
diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml
index 355804f2a3..bb4c17c531 100644
--- a/doc/classes/TouchScreenButton.xml
+++ b/doc/classes/TouchScreenButton.xml
@@ -4,7 +4,7 @@
Button for touch screen devices for gameplay use.
</brief_description>
<description>
- TouchScreenButton allows you to create on-screen buttons for touch devices. It's intended for gameplay use, such as a unit you have to touch to move.
+ TouchScreenButton allows you to create on-screen buttons for touch devices. It's intended for gameplay use, such as a unit you have to touch to move. Unlike [Button], TouchScreenButton supports multitouch out of the box. Several TouchScreenButtons can be pressed at the same time with touch input.
This node inherits from [Node2D]. Unlike with [Control] nodes, you cannot set anchors on it. If you want to create menus or user interfaces, you may want to use [Button] nodes instead. To make button nodes react to touch events, you can enable the Emulate Mouse option in the Project Settings.
You can configure TouchScreenButton to be visible only on touch devices, helping you develop your game both for desktop and mobile devices.
</description>
@@ -30,7 +30,8 @@
The button's texture for the normal state.
</member>
<member name="passby_press" type="bool" setter="set_passby_press" getter="is_passby_press_enabled" default="false">
- If [code]true[/code], pass-by presses are enabled.
+ If [code]true[/code], the [signal pressed] and [signal released] signals are emitted whenever a pressed finger goes in and out of the button, even if the pressure started outside the active area of the button.
+ [b]Note:[/b] this is a "pass-by" (not "bypass") press mode.
</member>
<member name="pressed" type="Texture2D" setter="set_texture_pressed" getter="get_texture_pressed">
The button's texture for the pressed state.
@@ -42,7 +43,7 @@
If [code]true[/code], the button's shape is centered in the provided texture. If no texture is used, this property has no effect.
</member>
<member name="shape_visible" type="bool" setter="set_shape_visible" getter="is_shape_visible" default="true">
- If [code]true[/code], the button's shape is visible.
+ If [code]true[/code], the button's shape is visible in the editor.
</member>
<member name="visibility_mode" type="int" setter="set_visibility_mode" getter="get_visibility_mode" enum="TouchScreenButton.VisibilityMode" default="0">
The button's visibility mode. See [enum VisibilityMode] for possible values.
diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml
index cda69f6a64..d75b81eece 100644
--- a/doc/classes/Transform.xml
+++ b/doc/classes/Transform.xml
@@ -97,7 +97,7 @@
</return>
<argument index="0" name="target" type="Vector3">
</argument>
- <argument index="1" name="up" type="Vector3">
+ <argument index="1" name="up" type="Vector3" default="Vector3( 0, 1, 0 )">
</argument>
<description>
Returns a copy of the transform rotated such that its -Z axis points towards the [code]target[/code] position.
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 01818e2993..a09f1bf470 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -6,16 +6,30 @@
<description>
This shows a tree of items that can be selected, expanded and collapsed. The tree can have multiple columns with custom controls like text editing, buttons and popups. It can be useful for structured displays and interactions.
Trees are built via code, using [TreeItem] objects to create the structure. They have a single root but multiple roots can be simulated if a dummy hidden root is added.
- [codeblock]
+ [codeblocks]
+ [gdscript]
func _ready():
var tree = Tree.new()
var root = tree.create_item()
- tree.set_hide_root(true)
+ tree.hide_root = true
var child1 = tree.create_item(root)
var child2 = tree.create_item(root)
var subchild1 = tree.create_item(child1)
subchild1.set_text(0, "Subchild1")
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override void _Ready()
+ {
+ var tree = new Tree();
+ TreeItem root = tree.CreateItem();
+ tree.HideRoot = true;
+ TreeItem child1 = tree.CreateItem(root);
+ TreeItem child2 = tree.CreateItem(root);
+ TreeItem subchild1 = tree.CreateItem(child1);
+ subchild1.SetText(0, "Subchild1");
+ }
+ [/csharp]
+ [/codeblocks]
To iterate over all the [TreeItem] objects in a [Tree] object, use [method TreeItem.get_next] and [method TreeItem.get_children] after getting the root through [method get_root]. You can use [method Object.free] on a [TreeItem] to remove it from the [Tree].
</description>
<tutorials>
@@ -57,6 +71,13 @@
The new item will be the [code]idx[/code]th child of parent, or it will be the last child if there are not enough siblings.
</description>
</method>
+ <method name="edit_selected">
+ <return type="bool">
+ </return>
+ <description>
+ Edits the selected tree item as if it was clicked. The item must be set editable with [method TreeItem.set_editable]. Returns [code]true[/code] if the item could be edited. Fails if no item is selected.
+ </description>
+ </method>
<method name="ensure_cursor_is_visible">
<return type="void">
</return>
@@ -145,13 +166,26 @@
</return>
<description>
Returns the currently edited item. Can be used with [signal item_edited] to get the item that was modified.
- [codeblock]
+ [codeblocks]
+ [gdscript]
func _ready():
$Tree.item_edited.connect(on_Tree_item_edited)
func on_Tree_item_edited():
print($Tree.get_edited()) # This item just got edited (e.g. checked).
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public override void _Ready()
+ {
+ GetNode&lt;Tree&gt;("Tree").ItemEdited += OnTreeItemEdited;
+ }
+
+ public void OnTreeItemEdited()
+ {
+ GD.Print(GetNode&lt;Tree&gt;("Tree").GetEdited()); // This item just got edited (e.g. checked).
+ }
+ [/csharp]
+ [/codeblocks]
</description>
</method>
<method name="get_edited_column" qualifiers="const">
@@ -230,6 +264,14 @@
To tell whether a column of an item is selected, use [method TreeItem.is_selected].
</description>
</method>
+ <method name="scroll_to_item">
+ <return type="void">
+ </return>
+ <argument index="0" name="item" type="Object">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_column_expand">
<return type="void">
</return>
@@ -524,7 +566,10 @@
<theme_item name="font_color" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )">
Default text [Color] of the item.
</theme_item>
- <theme_item name="font_color_selected" type="Color" default="Color( 1, 1, 1, 1 )">
+ <theme_item name="font_outline_color" type="Color" default="Color( 1, 1, 1, 1 )">
+ The tint of text outline of the item.
+ </theme_item>
+ <theme_item name="font_selected_color" type="Color" default="Color( 1, 1, 1, 1 )">
Text [Color] used when the item is selected.
</theme_item>
<theme_item name="font_size" type="int">
@@ -539,6 +584,9 @@
<theme_item name="item_margin" type="int" default="12">
The horizontal margin at the start of an item. This is used when folding is enabled for the item.
</theme_item>
+ <theme_item name="outline_size" type="int" default="0">
+ The size of the text outline.
+ </theme_item>
<theme_item name="relationship_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )">
[Color] of the relationship lines.
</theme_item>
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index e97c1e580c..fd157e5eb9 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -208,6 +208,7 @@
<argument index="0" name="column" type="int">
</argument>
<description>
+ Returns the metadata value that was set for the given column using [method set_metadata].
</description>
</method>
<method name="get_next">
@@ -268,6 +269,7 @@
<argument index="0" name="column" type="int">
</argument>
<description>
+ Returns the value of a [constant CELL_MODE_RANGE] column.
</description>
</method>
<method name="get_range_config">
@@ -276,6 +278,7 @@
<argument index="0" name="column" type="int">
</argument>
<description>
+ Returns a dictionary containing the range parameters for a given column. The keys are "min", "max", "step", and "expr".
</description>
</method>
<method name="get_structured_text_bidi_override" qualifiers="const">
@@ -300,6 +303,7 @@
<argument index="0" name="column" type="int">
</argument>
<description>
+ Gets the suffix string shown after the column value.
</description>
</method>
<method name="get_text" qualifiers="const">
@@ -606,6 +610,7 @@
<argument index="1" name="meta" type="Variant">
</argument>
<description>
+ Sets the metadata value for the given column, which can be retrieved later using [method get_metadata]. This can be used, for example, to store a reference to the original data.
</description>
</method>
<method name="set_opentype_feature">
@@ -629,6 +634,7 @@
<argument index="1" name="value" type="float">
</argument>
<description>
+ Sets the value of a [constant CELL_MODE_RANGE] column.
</description>
</method>
<method name="set_range_config">
@@ -645,6 +651,8 @@
<argument index="4" name="expr" type="bool" default="false">
</argument>
<description>
+ Sets the range of accepted values for a column. The column must be in the [constant CELL_MODE_RANGE] mode.
+ If [code]expr[/code] is [code]true[/code], the edit mode slider will use an exponential scale as with [member Range.exp_edit].
</description>
</method>
<method name="set_selectable">
@@ -686,6 +694,7 @@
<argument index="1" name="text" type="String">
</argument>
<description>
+ Sets a string to be shown after a column's value (for example, a unit abbreviation).
</description>
</method>
<method name="set_text">
@@ -696,6 +705,7 @@
<argument index="1" name="text" type="String">
</argument>
<description>
+ Sets the given column's text value.
</description>
</method>
<method name="set_text_align">
@@ -748,7 +758,7 @@
Cell contains a string.
</constant>
<constant name="CELL_MODE_CHECK" value="1" enum="TreeCellMode">
- Cell can be checked.
+ Cell contains a checkbox.
</constant>
<constant name="CELL_MODE_RANGE" value="2" enum="TreeCellMode">
Cell contains a range.
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index 56ccaaf383..b32bb1e2d9 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -7,13 +7,22 @@
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-betweening[/i], an animation technique where you specify [i]keyframes[/i] and the computer interpolates the frames that appear between them.
[Tween] is more suited than [AnimationPlayer] for animations where you don't know the final values in advance. For example, interpolating a dynamically-chosen camera zoom value is best done with a [Tween] node; it would be difficult to do the same thing with an [AnimationPlayer] node.
Here is a brief usage example that makes a 2D node move smoothly between two positions:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var tween = get_node("Tween")
tween.interpolate_property($Node2D, "position",
Vector2(0, 0), Vector2(100, 100), 1,
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
tween.start()
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ var tween = GetNode&lt;Tween&gt;("Tween");
+ tween.InterpolateProperty(GetNode&lt;Node2D&gt;("Node2D"), "position",
+ new Vector2(0, 0), new Vector2(100, 100), 1,
+ Tween.TransitionType.Linear, Tween.EaseType.InOut);
+ tween.Start();
+ [/csharp]
+ [/codeblocks]
Many methods require a property name, such as [code]"position"[/code] above. You can find the correct property name by hovering over the property in the Inspector. You can also provide the components of a property directly by using [code]"property:component"[/code] (eg. [code]position:x[/code]), where it would only apply to that particular component.
Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [url=https://easings.net/]easings.net[/url] for some examples). The second accepts an [enum EaseType] constant, and controls where the [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best.
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]
diff --git a/doc/classes/UDPServer.xml b/doc/classes/UDPServer.xml
index aabfed85f0..0fc00f67f8 100644
--- a/doc/classes/UDPServer.xml
+++ b/doc/classes/UDPServer.xml
@@ -7,8 +7,9 @@
A simple server that opens a UDP socket and returns connected [PacketPeerUDP] upon receiving new packets. See also [method PacketPeerUDP.connect_to_host].
After starting the server ([method listen]), you will need to [method poll] it at regular intervals (e.g. inside [method Node._process]) for it to process new packets, delivering them to the appropriate [PacketPeerUDP], and taking new connections.
Below a small example of how it can be used:
- [codeblock]
- # server.gd
+ [codeblocks]
+ [gdscript]
+ class_name Server
extends Node
var server := UDPServer.new()
@@ -21,20 +22,57 @@
server.poll() # Important!
if server.is_connection_available():
var peer : PacketPeerUDP = server.take_connection()
- var pkt = peer.get_packet()
+ var packet = peer.get_packet()
print("Accepted peer: %s:%s" % [peer.get_packet_ip(), peer.get_packet_port()])
- print("Received data: %s" % [pkt.get_string_from_utf8()])
+ print("Received data: %s" % [packet.get_string_from_utf8()])
# Reply so it knows we received the message.
- peer.put_packet(pkt)
+ peer.put_packet(packet)
# Keep a reference so we can keep contacting the remote peer.
peers.append(peer)
for i in range(0, peers.size()):
pass # Do something with the connected peers.
+ [/gdscript]
+ [csharp]
+ using Godot;
+ using System;
+ using System.Collections.Generic;
- [/codeblock]
- [codeblock]
- # client.gd
+ public class Server : Node
+ {
+ public UDPServer Server = new UDPServer();
+ public List&lt;PacketPeerUDP&gt; Peers = new List&lt;PacketPeerUDP&gt;();
+
+ public override void _Ready()
+ {
+ Server.Listen(4242);
+ }
+
+ public override void _Process(float delta)
+ {
+ Server.Poll(); // Important!
+ if (Server.IsConnectionAvailable())
+ {
+ PacketPeerUDP peer = Server.TakeConnection();
+ byte[] packet = peer.GetPacket();
+ GD.Print($"Accepted Peer: {peer.GetPacketIp()}:{peer.GetPacketPort()}");
+ GD.Print($"Received Data: {packet.GetStringFromUTF8()}");
+ // Reply so it knows we received the message.
+ peer.PutPacket(packet);
+ // Keep a reference so we can keep contacting the remote peer.
+ Peers.Add(peer);
+ }
+ foreach (var peer in Peers)
+ {
+ // Do something with the peers.
+ }
+ }
+ }
+ [/csharp]
+ [/codeblocks]
+ [codeblocks]
+ [gdscript]
+ class_name Client
extends Node
var udp := PacketPeerUDP.new()
@@ -50,7 +88,37 @@
if udp.get_available_packet_count() &gt; 0:
print("Connected: %s" % udp.get_packet().get_string_from_utf8())
connected = true
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ using Godot;
+ using System;
+
+ public class Client : Node
+ {
+ public PacketPeerUDP Udp = new PacketPeerUDP();
+ public bool Connected = false;
+
+ public override void _Ready()
+ {
+ Udp.ConnectToHost("127.0.0.1", 4242);
+ }
+
+ public override void _Process(float delta)
+ {
+ if (!Connected)
+ {
+ // Try to contact server
+ Udp.PutPacket("The Answer Is..42!".ToUTF8());
+ }
+ if (Udp.GetAvailablePacketCount() &gt; 0)
+ {
+ GD.Print($"Connected: {Udp.GetPacket().GetStringFromUTF8()}");
+ Connected = true;
+ }
+ }
+ }
+ [/csharp]
+ [/codeblocks]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/UndoRedo.xml b/doc/classes/UndoRedo.xml
index 2cc3e974e2..a0330de4fa 100644
--- a/doc/classes/UndoRedo.xml
+++ b/doc/classes/UndoRedo.xml
@@ -7,7 +7,8 @@
Helper to manage undo/redo operations in the editor or custom tools. It works by registering methods and property changes inside "actions".
Common behavior is to create an action, then add do/undo calls to functions or property changes, then committing the action.
Here's an example on how to add an action to the Godot editor's own [UndoRedo], from a plugin:
- [codeblock]
+ [codeblocks]
+ [gdscript]
var undo_redo = get_undo_redo() # Method of EditorPlugin.
func do_something():
@@ -24,7 +25,37 @@
undo_redo.add_do_property(node, "position", Vector2(100,100))
undo_redo.add_undo_property(node, "position", node.position)
undo_redo.commit_action()
- [/codeblock]
+ [/gdscript]
+ [csharp]
+ public UndoRedo UndoRedo;
+
+ public override void _Ready()
+ {
+ UndoRedo = GetUndoRedo(); // Method of EditorPlugin.
+ }
+
+ public void DoSomething()
+ {
+ // Put your code here.
+ }
+
+ public void UndoSomething()
+ {
+ // Put here the code that reverts what's done by "DoSomething()".
+ }
+
+ private void OnMyButtonPressed()
+ {
+ var node = GetNode&lt;Node2D&gt;("MyNode2D");
+ UndoRedo.CreateAction("Move the node");
+ UndoRedo.AddDoMethod(this, nameof(DoSomething));
+ UndoRedo.AddUndoMethod(this, nameof(UndoSomething));
+ UndoRedo.AddDoProperty(node, "position", new Vector2(100, 100));
+ UndoRedo.AddUndoProperty(node, "position", node.Position);
+ UndoRedo.CommitAction();
+ }
+ [/csharp]
+ [/codeblocks]
[method create_action], [method add_do_method], [method add_undo_method], [method add_do_property], [method add_undo_property], and [method commit_action] should be called one after the other, like in the example. Not doing so could lead to crashes.
If you don't need to register a method, you can leave [method add_do_method] and [method add_undo_method] out; the same goes for properties. You can also register more than one method/property.
</description>
@@ -110,8 +141,10 @@
<method name="commit_action">
<return type="void">
</return>
+ <argument index="0" name="execute" type="bool" default="true">
+ </argument>
<description>
- Commit the action. All "do" methods/properties are called/set when this function is called.
+ Commit the action. If [code]execute[/code] is true (default), all "do" methods/properties are called/set when this function is called.
</description>
</method>
<method name="create_action">
@@ -126,11 +159,34 @@
The way actions are merged is dictated by the [code]merge_mode[/code] argument. See [enum MergeMode] for details.
</description>
</method>
+ <method name="get_action_name">
+ <return type="String">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ Gets the action name from its index.
+ </description>
+ </method>
+ <method name="get_current_action">
+ <return type="int">
+ </return>
+ <description>
+ Gets the index of the current action.
+ </description>
+ </method>
<method name="get_current_action_name" qualifiers="const">
<return type="String">
</return>
<description>
- Gets the name of the current action.
+ Gets the name of the current action, equivalent to [code]get_action_name(get_current_action())[/code].
+ </description>
+ </method>
+ <method name="get_history_count">
+ <return type="int">
+ </return>
+ <description>
+ Return how many element are in the history.
</description>
</method>
<method name="get_version" qualifiers="const">
diff --git a/doc/classes/Variant.xml b/doc/classes/Variant.xml
index cd76689ffe..775bd58bcf 100644
--- a/doc/classes/Variant.xml
+++ b/doc/classes/Variant.xml
@@ -17,7 +17,7 @@
- VisualScript tracks properties inside Variants as well, but it also uses static typing. The GUI interface enforces that properties have a particular type that doesn't change over time.
- C# is statically typed, but uses the Mono [code]object[/code] type in place of Godot's Variant class when it needs to represent a dynamic value. [code]object[/code] is the Mono runtime's equivalent of the same concept.
- The statically-typed language NativeScript C++ does not define a built-in Variant-like class. Godot's GDNative bindings provide their own godot::Variant class for users; Any point at which the C++ code starts interacting with the Godot runtime is a place where you might have to start wrapping data inside Variant objects.
- The global [method @GDScript.typeof] function returns the enumerated value of the Variant type stored in the current variable (see [enum Variant.Type]).
+ The global [method @GlobalScope.typeof] function returns the enumerated value of the Variant type stored in the current variable (see [enum Variant.Type]).
[codeblock]
var foo = 2
match typeof(foo):
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 05194337db..4159a38d96 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -66,7 +66,7 @@
<description>
Returns this vector's angle with respect to the positive X axis, or [code](1, 0)[/code] vector, in radians.
For example, [code]Vector2.RIGHT.angle()[/code] will return zero, [code]Vector2.DOWN.angle()[/code] will return [code]PI / 2[/code] (a quarter turn, or 90 degrees), and [code]Vector2(1, -1).angle()[/code] will return [code]-PI / 4[/code] (a negative eighth turn, or -45 degrees).
- Equivalent to the result of [method @GDScript.atan2] when called with the vector's [member y] and [member x] as parameters: [code]atan2(y, x)[/code].
+ Equivalent to the result of [method @GlobalScope.atan2] when called with the vector's [member y] and [member x] as parameters: [code]atan2(y, x)[/code].
</description>
</method>
<method name="angle_to">
@@ -196,7 +196,7 @@
<argument index="0" name="to" type="Vector2">
</argument>
<description>
- Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component.
+ Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
<method name="is_normalized">
@@ -390,13 +390,20 @@
<description>
</description>
</method>
+ <method name="orthogonal">
+ <return type="Vector2">
+ </return>
+ <description>
+ Returns a perpendicular vector rotated 90 degrees counter-clockwise compared to the original, with the same length.
+ </description>
+ </method>
<method name="posmod">
<return type="Vector2">
</return>
<argument index="0" name="mod" type="float">
</argument>
<description>
- Returns a vector composed of the [method @GDScript.fposmod] of this vector's components and [code]mod[/code].
+ Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]mod[/code].
</description>
</method>
<method name="posmodv">
@@ -405,7 +412,7 @@
<argument index="0" name="modv" type="Vector2">
</argument>
<description>
- Returns a vector composed of the [method @GDScript.fposmod] of this vector's components and [code]modv[/code]'s components.
+ Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]modv[/code]'s components.
</description>
</method>
<method name="project">
@@ -432,7 +439,7 @@
<argument index="0" name="phi" type="float">
</argument>
<description>
- Returns the vector rotated by [code]phi[/code] radians. See also [method @GDScript.deg2rad].
+ Returns the vector rotated by [code]phi[/code] radians. See also [method @GlobalScope.deg2rad].
</description>
</method>
<method name="round">
@@ -446,7 +453,7 @@
<return type="Vector2">
</return>
<description>
- Returns the vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GDScript.sign] on each component.
+ Returns the vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component.
</description>
</method>
<method name="slerp">
@@ -473,19 +480,12 @@
<method name="snapped">
<return type="Vector2">
</return>
- <argument index="0" name="by" type="Vector2">
+ <argument index="0" name="step" type="Vector2">
</argument>
<description>
Returns this vector with each component snapped to the nearest multiple of [code]step[/code]. This can also be used to round to an arbitrary number of decimals.
</description>
</method>
- <method name="tangent">
- <return type="Vector2">
- </return>
- <description>
- Returns a perpendicular vector rotated 90 degrees counter-clockwise compared to the original, with the same length.
- </description>
- </method>
</methods>
<members>
<member name="x" type="float" setter="" getter="" default="0.0">
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 14a829d7a5..ea80b7c248 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -68,7 +68,7 @@
<argument index="0" name="to" type="Vector3">
</argument>
<description>
- Returns the minimum angle to the given vector, in radians.
+ Returns the unsigned minimum angle to the given vector, in radians.
</description>
</method>
<method name="bounce">
@@ -171,7 +171,7 @@
<argument index="0" name="to" type="Vector3">
</argument>
<description>
- Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component.
+ Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component.
</description>
</method>
<method name="is_normalized">
@@ -410,7 +410,7 @@
<argument index="0" name="mod" type="float">
</argument>
<description>
- Returns a vector composed of the [method @GDScript.fposmod] of this vector's components and [code]mod[/code].
+ Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]mod[/code].
</description>
</method>
<method name="posmodv">
@@ -419,7 +419,7 @@
<argument index="0" name="modv" type="Vector3">
</argument>
<description>
- Returns a vector composed of the [method @GDScript.fposmod] of this vector's components and [code]modv[/code]'s components.
+ Returns a vector composed of the [method @GlobalScope.fposmod] of this vector's components and [code]modv[/code]'s components.
</description>
</method>
<method name="project">
@@ -462,7 +462,18 @@
<return type="Vector3">
</return>
<description>
- Returns a vector with each component set to one or negative one, depending on the signs of this vector's components, or zero if the component is zero, by calling [method @GDScript.sign] on each component.
+ Returns a vector with each component set to one or negative one, depending on the signs of this vector's components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component.
+ </description>
+ </method>
+ <method name="signed_angle_to">
+ <return type="float">
+ </return>
+ <argument index="0" name="to" type="Vector3">
+ </argument>
+ <argument index="1" name="axis" type="Vector3">
+ </argument>
+ <description>
+ Returns the signed angle to the given vector, in radians. The sign of the angle is positive in a counter-clockwise direction and negative in a clockwise direction when viewed from the side specified by the [code]axis[/code].
</description>
</method>
<method name="slerp">
@@ -489,7 +500,7 @@
<method name="snapped">
<return type="Vector3">
</return>
- <argument index="0" name="by" type="Vector3">
+ <argument index="0" name="step" type="Vector3">
</argument>
<description>
Returns this vector with each component snapped to the nearest multiple of [code]step[/code]. This can also be used to round to an arbitrary number of decimals.
diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoPlayer.xml
index 80f97c3419..b2ab356b0d 100644
--- a/doc/classes/VideoPlayer.xml
+++ b/doc/classes/VideoPlayer.xml
@@ -7,6 +7,7 @@
Control node for playing video streams using [VideoStream] resources.
Supported video formats are [url=https://www.webmproject.org/]WebM[/url] ([code].webm[/code], [VideoStreamWebm]), [url=https://www.theora.org/]Ogg Theora[/url] ([code].ogv[/code], [VideoStreamTheora]), and any format exposed via a GDNative plugin using [VideoStreamGDNative].
[b]Note:[/b] Due to a bug, VideoPlayer does not support localization remapping yet.
+ [b]Warning:[/b] On HTML5, video playback [i]will[/i] perform poorly due to missing architecture-specific assembly optimizations, especially for VP8/VP9.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index e2cf848f45..8120ae539e 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -213,7 +213,7 @@
The global canvas transform of the viewport. The canvas transform is relative to this.
</member>
<member name="gui_disable_input" type="bool" setter="set_disable_input" getter="is_input_disabled" default="false">
- If [code]true[/code], the viewport will not receive input event.
+ If [code]true[/code], the viewport will not receive input events.
</member>
<member name="gui_embed_subwindows" type="bool" setter="set_embed_subwindows_hint" getter="get_embed_subwindows_hint" default="false">
</member>
@@ -222,6 +222,8 @@
</member>
<member name="handle_input_locally" type="bool" setter="set_handle_input_locally" getter="is_handling_input_locally" default="true">
</member>
+ <member name="lod_threshold" type="float" setter="set_lod_threshold" getter="get_lod_threshold" default="1.0">
+ </member>
<member name="msaa" type="int" setter="set_msaa" getter="get_msaa" enum="Viewport.MSAA" default="0">
The multisample anti-aliasing mode. A higher number results in smoother edges at the cost of significantly worse performance. A value of 4 is best unless targeting very high-end systems.
</member>
@@ -238,6 +240,8 @@
</member>
<member name="sdf_scale" type="int" setter="set_sdf_scale" getter="get_sdf_scale" enum="Viewport.SDFScale" default="1">
</member>
+ <member name="shadow_atlas_16_bits" type="bool" setter="set_shadow_atlas_16_bits" getter="get_shadow_atlas_16_bits" default="true">
+ </member>
<member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2">
The subdivision amount of the first quadrant on the shadow atlas.
</member>
@@ -250,9 +254,9 @@
<member name="shadow_atlas_quad_3" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="4">
The subdivision amount of the fourth quadrant on the shadow atlas.
</member>
- <member name="shadow_atlas_size" type="int" setter="set_shadow_atlas_size" getter="get_shadow_atlas_size" default="0">
+ <member name="shadow_atlas_size" type="int" setter="set_shadow_atlas_size" getter="get_shadow_atlas_size" default="2048">
The shadow atlas' resolution (used for omni and spot lights). The value will be rounded up to the nearest power of 2.
- [b]Note:[/b] If this is set to 0, shadows won't be visible. Since user-created viewports default to a value of 0, this value must be set above 0 manually.
+ [b]Note:[/b] If this is set to 0, shadows won't be visible.
</member>
<member name="snap_2d_transforms_to_pixel" type="bool" setter="set_snap_2d_transforms_to_pixel" getter="is_snap_2d_transforms_to_pixel_enabled" default="false">
</member>
@@ -405,6 +409,16 @@
</constant>
<constant name="DEBUG_DRAW_GI_BUFFER" value="17" enum="DebugDraw">
</constant>
+ <constant name="DEBUG_DRAW_DISABLE_LOD" value="18" enum="DebugDraw">
+ </constant>
+ <constant name="DEBUG_DRAW_CLUSTER_OMNI_LIGHTS" value="19" enum="DebugDraw">
+ </constant>
+ <constant name="DEBUG_DRAW_CLUSTER_SPOT_LIGHTS" value="20" enum="DebugDraw">
+ </constant>
+ <constant name="DEBUG_DRAW_CLUSTER_DECALS" value="21" enum="DebugDraw">
+ </constant>
+ <constant name="DEBUG_DRAW_CLUSTER_REFLECTION_PROBES" value="22" enum="DebugDraw">
+ </constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="0" enum="DefaultCanvasItemTextureFilter">
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
</constant>
diff --git a/doc/classes/VisualShader.xml b/doc/classes/VisualShader.xml
index f03550bd5e..c29c30289a 100644
--- a/doc/classes/VisualShader.xml
+++ b/doc/classes/VisualShader.xml
@@ -169,6 +169,19 @@
Removes the specified node from the shader.
</description>
</method>
+ <method name="replace_node">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="VisualShader.Type">
+ </argument>
+ <argument index="1" name="id" type="int">
+ </argument>
+ <argument index="2" name="new_class" type="StringName">
+ </argument>
+ <description>
+ Replaces the specified node with a node of new class type.
+ </description>
+ </method>
<method name="set_mode">
<return type="void">
</return>
diff --git a/doc/classes/VisualShaderNodeBooleanConstant.xml b/doc/classes/VisualShaderNodeBooleanConstant.xml
index cccb64e874..688679f2a3 100644
--- a/doc/classes/VisualShaderNodeBooleanConstant.xml
+++ b/doc/classes/VisualShaderNodeBooleanConstant.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeBooleanConstant" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeBooleanConstant" inherits="VisualShaderNodeConstant" version="4.0">
<brief_description>
A boolean constant to be used within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeClamp.xml b/doc/classes/VisualShaderNodeClamp.xml
new file mode 100644
index 0000000000..504171bb13
--- /dev/null
+++ b/doc/classes/VisualShaderNodeClamp.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeClamp" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ Clamps a value within the visual shader graph.
+ </brief_description>
+ <description>
+ Constrains a value to lie between [code]min[/code] and [code]max[/code] values.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeClamp.OpType" default="0">
+ A type of operands and returned value.
+ </member>
+ </members>
+ <constants>
+ <constant name="OP_TYPE_FLOAT" value="0" enum="OpType">
+ A floating-point scalar.
+ </constant>
+ <constant name="OP_TYPE_INT" value="1" enum="OpType">
+ An integer scalar.
+ </constant>
+ <constant name="OP_TYPE_VECTOR" value="2" enum="OpType">
+ A vector type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ Represents the size of the [enum OpType] enum.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeColorConstant.xml b/doc/classes/VisualShaderNodeColorConstant.xml
index 9b122ca8e1..8644013ef2 100644
--- a/doc/classes/VisualShaderNodeColorConstant.xml
+++ b/doc/classes/VisualShaderNodeColorConstant.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeColorConstant" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeColorConstant" inherits="VisualShaderNodeConstant" version="4.0">
<brief_description>
A [Color] constant to be used within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeConstant.xml b/doc/classes/VisualShaderNodeConstant.xml
new file mode 100644
index 0000000000..8c61529dd1
--- /dev/null
+++ b/doc/classes/VisualShaderNodeConstant.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeConstant" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ A base type for the constants within the visual shader graph.
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeCubemap.xml b/doc/classes/VisualShaderNodeCubemap.xml
index b6813bdae8..13b367e8f2 100644
--- a/doc/classes/VisualShaderNodeCubemap.xml
+++ b/doc/classes/VisualShaderNodeCubemap.xml
@@ -34,7 +34,7 @@
<constant name="TYPE_COLOR" value="1" enum="TextureType">
Adds [code]hint_albedo[/code] as hint to the uniform declaration for proper sRGB to linear conversion.
</constant>
- <constant name="TYPE_NORMALMAP" value="2" enum="TextureType">
+ <constant name="TYPE_NORMAL_MAP" value="2" enum="TextureType">
Adds [code]hint_normal[/code] as hint to the uniform declaration, which internally converts the texture for proper usage as normal map.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeFloatConstant.xml b/doc/classes/VisualShaderNodeFloatConstant.xml
index 3ba9ff07d3..a71563af54 100644
--- a/doc/classes/VisualShaderNodeFloatConstant.xml
+++ b/doc/classes/VisualShaderNodeFloatConstant.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeFloatConstant" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeFloatConstant" inherits="VisualShaderNodeConstant" version="4.0">
<brief_description>
A scalar floating-point constant to be used within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeIntConstant.xml b/doc/classes/VisualShaderNodeIntConstant.xml
index 1c407b21ca..18d6e96ab5 100644
--- a/doc/classes/VisualShaderNodeIntConstant.xml
+++ b/doc/classes/VisualShaderNodeIntConstant.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeIntConstant" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeIntConstant" inherits="VisualShaderNodeConstant" version="4.0">
<brief_description>
A scalar integer constant to be used within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeIntFunc.xml b/doc/classes/VisualShaderNodeIntFunc.xml
index 5c68c0ec71..a9f4144a01 100644
--- a/doc/classes/VisualShaderNodeIntFunc.xml
+++ b/doc/classes/VisualShaderNodeIntFunc.xml
@@ -11,7 +11,7 @@
<methods>
</methods>
<members>
- <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIntFunc.Function" default="3">
+ <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIntFunc.Function" default="2">
A function to be applied to the scalar. See [enum Function] for options.
</member>
</members>
@@ -19,13 +19,10 @@
<constant name="FUNC_ABS" value="0" enum="Function">
Returns the absolute value of the parameter. Translates to [code]abs(x)[/code] in the Godot Shader Language.
</constant>
- <constant name="FUNC_CLAMP" value="1" enum="Function">
- Constrains a parameter between [code]min[/code] and [code]max[/code]. Translates to [code]clamp(x, min, max)[/code] in the Godot Shader Language.
- </constant>
- <constant name="FUNC_NEGATE" value="2" enum="Function">
+ <constant name="FUNC_NEGATE" value="1" enum="Function">
Negates the [code]x[/code] using [code]-(x)[/code].
</constant>
- <constant name="FUNC_SIGN" value="3" enum="Function">
+ <constant name="FUNC_SIGN" value="2" enum="Function">
Extracts the sign of the parameter. Translates to [code]sign(x)[/code] in the Godot Shader Language.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeMix.xml b/doc/classes/VisualShaderNodeMix.xml
new file mode 100644
index 0000000000..c70ac7e599
--- /dev/null
+++ b/doc/classes/VisualShaderNodeMix.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeMix" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ Linearly interpolates between two values within the visual shader graph.
+ </brief_description>
+ <description>
+ Translates to [code]mix(a, b, weight)[/code] in the shader language.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeMix.OpType" default="0">
+ A type of operands and returned value.
+ </member>
+ </members>
+ <constants>
+ <constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
+ A scalar type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
+ A vector type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType">
+ A vector type. [code]weight[/code] port is using a scalar type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ Represents the size of the [enum OpType] enum.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeSDFRaymarch.xml b/doc/classes/VisualShaderNodeSDFRaymarch.xml
new file mode 100644
index 0000000000..775f2814c2
--- /dev/null
+++ b/doc/classes/VisualShaderNodeSDFRaymarch.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeSDFRaymarch" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ SDF raymarching algorithm to be used within the visual shader graph.
+ </brief_description>
+ <description>
+ Casts a ray against the screen SDF (signed-distance field) and returns the distance travelled.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeSDFToScreenUV.xml b/doc/classes/VisualShaderNodeSDFToScreenUV.xml
new file mode 100644
index 0000000000..ea04180095
--- /dev/null
+++ b/doc/classes/VisualShaderNodeSDFToScreenUV.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeSDFToScreenUV" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ A function to convert a SDF (signed-distance field) to screen UV, to be used within the visual shader graph.
+ </brief_description>
+ <description>
+ Translates to [code]sdf_to_screen_uv(sdf_pos)[/code] in the shader language.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeScalarClamp.xml b/doc/classes/VisualShaderNodeScalarClamp.xml
deleted file mode 100644
index 7432e8dfca..0000000000
--- a/doc/classes/VisualShaderNodeScalarClamp.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeScalarClamp" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Clamps a scalar value within the visual shader graph.
- </brief_description>
- <description>
- Constrains a value to lie between [code]min[/code] and [code]max[/code] values.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeScalarInterp.xml b/doc/classes/VisualShaderNodeScalarInterp.xml
deleted file mode 100644
index 393ea70e1a..0000000000
--- a/doc/classes/VisualShaderNodeScalarInterp.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeScalarInterp" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Linearly interpolates between two scalars within the visual shader graph.
- </brief_description>
- <description>
- Translates to [code]mix(a, b, weight)[/code] in the shader language.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeScalarSmoothStep.xml b/doc/classes/VisualShaderNodeScalarSmoothStep.xml
deleted file mode 100644
index e619cc8571..0000000000
--- a/doc/classes/VisualShaderNodeScalarSmoothStep.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeScalarSmoothStep" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Calculates a scalar SmoothStep function within the visual shader graph.
- </brief_description>
- <description>
- Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language.
- Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeScalarSwitch.xml b/doc/classes/VisualShaderNodeScalarSwitch.xml
deleted file mode 100644
index 2ad5202745..0000000000
--- a/doc/classes/VisualShaderNodeScalarSwitch.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeScalarSwitch" inherits="VisualShaderNodeSwitch" version="4.0">
- <brief_description>
- A boolean/scalar function for use within the visual shader graph.
- </brief_description>
- <description>
- Returns an associated scalar if the provided boolean value is [code]true[/code] or [code]false[/code].
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeScreenUVToSDF.xml b/doc/classes/VisualShaderNodeScreenUVToSDF.xml
new file mode 100644
index 0000000000..438c8dc67b
--- /dev/null
+++ b/doc/classes/VisualShaderNodeScreenUVToSDF.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeScreenUVToSDF" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ A function to convert screen UV to a SDF (signed-distance field), to be used within the visual shader graph.
+ </brief_description>
+ <description>
+ Translates to [code]screen_uv_to_sdf(uv)[/code] in the shader language. If the UV port isn't connected, [code]SCREEN_UV[/code] is used instead.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeSmoothStep.xml b/doc/classes/VisualShaderNodeSmoothStep.xml
new file mode 100644
index 0000000000..fa22d16da8
--- /dev/null
+++ b/doc/classes/VisualShaderNodeSmoothStep.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeSmoothStep" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ Calculates a SmoothStep function within the visual shader graph.
+ </brief_description>
+ <description>
+ Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language.
+ Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeSmoothStep.OpType" default="0">
+ A type of operands and returned value.
+ </member>
+ </members>
+ <constants>
+ <constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
+ A scalar type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
+ A vector type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType">
+ A vector type. [code]edge0[/code] and [code]edge1[/code] are using a scalar type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ Represents the size of the [enum OpType] enum.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeStep.xml b/doc/classes/VisualShaderNodeStep.xml
new file mode 100644
index 0000000000..694c144445
--- /dev/null
+++ b/doc/classes/VisualShaderNodeStep.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeStep" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ Calculates a Step function within the visual shader graph.
+ </brief_description>
+ <description>
+ Translates to [code]step(edge, x)[/code] in the shader language.
+ Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge[/code] and [code]1.0[/code] otherwise.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeStep.OpType" default="0">
+ A type of operands and returned value.
+ </member>
+ </members>
+ <constants>
+ <constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
+ A scalar type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
+ A vector type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType">
+ A vector type. [code]edge[/code] port is using a scalar type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ Represents the size of the [enum OpType] enum.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeSwitch.xml b/doc/classes/VisualShaderNodeSwitch.xml
index 9f8a12c0fd..3961070a74 100644
--- a/doc/classes/VisualShaderNodeSwitch.xml
+++ b/doc/classes/VisualShaderNodeSwitch.xml
@@ -1,15 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeSwitch" inherits="VisualShaderNode" version="4.0">
<brief_description>
- A boolean/vector function for use within the visual shader graph.
+ A selector function for use within the visual shader graph.
</brief_description>
<description>
- Returns an associated vector if the provided boolean value is [code]true[/code] or [code]false[/code].
+ Returns an associated value of the [code]op_type[/code] type if the provided boolean value is [code]true[/code] or [code]false[/code].
</description>
<tutorials>
</tutorials>
<methods>
</methods>
+ <members>
+ <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeSwitch.OpType" default="0">
+ A type of operands and returned value.
+ </member>
+ </members>
<constants>
+ <constant name="OP_TYPE_FLOAT" value="0" enum="OpType">
+ A floating-point scalar.
+ </constant>
+ <constant name="OP_TYPE_INT" value="1" enum="OpType">
+ An integer scalar.
+ </constant>
+ <constant name="OP_TYPE_VECTOR" value="2" enum="OpType">
+ A vector type.
+ </constant>
+ <constant name="OP_TYPE_BOOLEAN" value="3" enum="OpType">
+ A boolean type.
+ </constant>
+ <constant name="OP_TYPE_TRANSFORM" value="4" enum="OpType">
+ A transform type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="5" enum="OpType">
+ Represents the size of the [enum OpType] enum.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeTexture.xml b/doc/classes/VisualShaderNodeTexture.xml
index 0c83ffffe4..8fa71b490d 100644
--- a/doc/classes/VisualShaderNodeTexture.xml
+++ b/doc/classes/VisualShaderNodeTexture.xml
@@ -46,7 +46,7 @@
<constant name="TYPE_COLOR" value="1" enum="TextureType">
Adds [code]hint_albedo[/code] as hint to the uniform declaration for proper sRGB to linear conversion.
</constant>
- <constant name="TYPE_NORMALMAP" value="2" enum="TextureType">
+ <constant name="TYPE_NORMAL_MAP" value="2" enum="TextureType">
Adds [code]hint_normal[/code] as hint to the uniform declaration, which internally converts the texture for proper usage as normal map.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeTextureSDF.xml b/doc/classes/VisualShaderNodeTextureSDF.xml
new file mode 100644
index 0000000000..7d3d654bd0
--- /dev/null
+++ b/doc/classes/VisualShaderNodeTextureSDF.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeTextureSDF" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ Performs a SDF (signed-distance field) texture lookup within the visual shader graph.
+ </brief_description>
+ <description>
+ Translates to [code]texture_sdf(sdf_pos)[/code] in the shader language.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeTextureSDFNormal.xml b/doc/classes/VisualShaderNodeTextureSDFNormal.xml
new file mode 100644
index 0000000000..5dbf3e545a
--- /dev/null
+++ b/doc/classes/VisualShaderNodeTextureSDFNormal.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeTextureSDFNormal" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ Performs a SDF (signed-distance field) normal texture lookup within the visual shader graph.
+ </brief_description>
+ <description>
+ Translates to [code]texture_sdf_normal(sdf_pos)[/code] in the shader language.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeTextureUniform.xml b/doc/classes/VisualShaderNodeTextureUniform.xml
index 107f08ba28..5a7474cca1 100644
--- a/doc/classes/VisualShaderNodeTextureUniform.xml
+++ b/doc/classes/VisualShaderNodeTextureUniform.xml
@@ -25,7 +25,7 @@
<constant name="TYPE_COLOR" value="1" enum="TextureType">
Adds [code]hint_albedo[/code] as hint to the uniform declaration for proper sRGB to linear conversion.
</constant>
- <constant name="TYPE_NORMALMAP" value="2" enum="TextureType">
+ <constant name="TYPE_NORMAL_MAP" value="2" enum="TextureType">
Adds [code]hint_normal[/code] as hint to the uniform declaration, which internally converts the texture for proper usage as normal map.
</constant>
<constant name="TYPE_ANISO" value="3" enum="TextureType">
diff --git a/doc/classes/VisualShaderNodeTransformConstant.xml b/doc/classes/VisualShaderNodeTransformConstant.xml
index e5004e5bb6..b8f054e914 100644
--- a/doc/classes/VisualShaderNodeTransformConstant.xml
+++ b/doc/classes/VisualShaderNodeTransformConstant.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeTransformConstant" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeTransformConstant" inherits="VisualShaderNodeConstant" version="4.0">
<brief_description>
A [Transform] constant for use within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeVec3Constant.xml b/doc/classes/VisualShaderNodeVec3Constant.xml
index 4dfc9dc081..b01bb514fe 100644
--- a/doc/classes/VisualShaderNodeVec3Constant.xml
+++ b/doc/classes/VisualShaderNodeVec3Constant.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVec3Constant" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeVec3Constant" inherits="VisualShaderNodeConstant" version="4.0">
<brief_description>
A [Vector3] constant to be used within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeVectorClamp.xml b/doc/classes/VisualShaderNodeVectorClamp.xml
deleted file mode 100644
index 567fed8a41..0000000000
--- a/doc/classes/VisualShaderNodeVectorClamp.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorClamp" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Clamps a vector value within the visual shader graph.
- </brief_description>
- <description>
- Constrains a value to lie between [code]min[/code] and [code]max[/code] values. The operation is performed on each component of the vector individually.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeVectorInterp.xml b/doc/classes/VisualShaderNodeVectorInterp.xml
deleted file mode 100644
index b63d34b742..0000000000
--- a/doc/classes/VisualShaderNodeVectorInterp.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorInterp" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Linearly interpolates between two vectors within the visual shader graph.
- </brief_description>
- <description>
- Translates to [code]mix(a, b, weight)[/code] in the shader language, where [code]weight[/code] is a [Vector3] with weights for each component.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeVectorScalarMix.xml b/doc/classes/VisualShaderNodeVectorScalarMix.xml
deleted file mode 100644
index 791a9e6be1..0000000000
--- a/doc/classes/VisualShaderNodeVectorScalarMix.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorScalarMix" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Linearly interpolates between two vectors using a scalar. For use within the visual shader graph.
- </brief_description>
- <description>
- Translates to [code]mix(a, b, weight)[/code] in the shader language, where [code]a[/code] and [code]b[/code] are vectors and [code]weight[/code] is a scalar.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml b/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml
deleted file mode 100644
index 580abaf5fe..0000000000
--- a/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorScalarSmoothStep" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Calculates a vector SmoothStep function using scalar within the visual shader graph.
- </brief_description>
- <description>
- Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language, where [code]x[/code] is a scalar.
- Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeVectorScalarStep.xml b/doc/classes/VisualShaderNodeVectorScalarStep.xml
deleted file mode 100644
index d61414f3a8..0000000000
--- a/doc/classes/VisualShaderNodeVectorScalarStep.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorScalarStep" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Calculates a vector Step function within the visual shader graph.
- </brief_description>
- <description>
- Translates to [code]step(edge, x)[/code] in the shader language.
- Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge[/code] and [code]1.0[/code] otherwise.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeVectorSmoothStep.xml b/doc/classes/VisualShaderNodeVectorSmoothStep.xml
deleted file mode 100644
index 1b77a3c535..0000000000
--- a/doc/classes/VisualShaderNodeVectorSmoothStep.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorSmoothStep" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Calculates a vector SmoothStep function within the visual shader graph.
- </brief_description>
- <description>
- Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language, where [code]x[/code] is a vector.
- Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/WeakRef.xml b/doc/classes/WeakRef.xml
index 07d82289a3..4140df5828 100644
--- a/doc/classes/WeakRef.xml
+++ b/doc/classes/WeakRef.xml
@@ -4,7 +4,7 @@
Holds an [Object], but does not contribute to the reference count if the object is a reference.
</brief_description>
<description>
- A weakref can hold a [Reference], without contributing to the reference counter. A weakref can be created from an [Object] using [method @GDScript.weakref]. If this object is not a reference, weakref still works, however, it does not have any effect on the object. Weakrefs are useful in cases where multiple classes have variables that refer to each other. Without weakrefs, using these classes could lead to memory leaks, since both references keep each other from being released. Making part of the variables a weakref can prevent this cyclic dependency, and allows the references to be released.
+ A weakref can hold a [Reference], without contributing to the reference counter. A weakref can be created from an [Object] using [method @GlobalScope.weakref]. If this object is not a reference, weakref still works, however, it does not have any effect on the object. Weakrefs are useful in cases where multiple classes have variables that refer to each other. Without weakrefs, using these classes could lead to memory leaks, since both references keep each other from being released. Making part of the variables a weakref can prevent this cyclic dependency, and allows the references to be released.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index 0f887c7705..b99a251a11 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -276,7 +276,7 @@
<method name="set_ime_active">
<return type="void">
</return>
- <argument index="0" name="arg0" type="bool">
+ <argument index="0" name="active" type="bool">
</argument>
<description>
</description>
@@ -284,7 +284,7 @@
<method name="set_ime_position">
<return type="void">
</return>
- <argument index="0" name="arg0" type="Vector2i">
+ <argument index="0" name="position" type="Vector2i">
</argument>
<description>
</description>
@@ -474,8 +474,17 @@
</theme_item>
<theme_item name="title_font" type="Font">
</theme_item>
+ <theme_item name="title_font_size" type="int">
+ The size of the title font.
+ </theme_item>
<theme_item name="title_height" type="int" default="20">
</theme_item>
+ <theme_item name="title_outline_modulate" type="Color" default="Color( 1, 1, 1, 1 )">
+ The color of the title outline.
+ </theme_item>
+ <theme_item name="title_outline_size" type="int" default="0">
+ The size of the title outline.
+ </theme_item>
<theme_item name="window_panel" type="StyleBox">
</theme_item>
</theme_items>
diff --git a/doc/classes/World2D.xml b/doc/classes/World2D.xml
index 25033cdb09..20b3afbd0b 100644
--- a/doc/classes/World2D.xml
+++ b/doc/classes/World2D.xml
@@ -18,6 +18,9 @@
<member name="direct_space_state" type="PhysicsDirectSpaceState2D" setter="" getter="get_direct_space_state">
Direct access to the world's physics 2D space state. Used for querying current and potential collisions. When using multi-threaded physics, access is limited to [code]_physics_process(delta)[/code] in the main thread.
</member>
+ <member name="navigation_map" type="RID" setter="" getter="get_navigation_map">
+ The [RID] of this world's navigation map. Used by the [NavigationServer2D].
+ </member>
<member name="space" type="RID" setter="" getter="get_space">
The [RID] of this world's physics space resource. Used by the [PhysicsServer2D] for 2D physics, treating it as both a space and an area.
</member>
diff --git a/doc/classes/World3D.xml b/doc/classes/World3D.xml
index fe92077432..610ecacff4 100644
--- a/doc/classes/World3D.xml
+++ b/doc/classes/World3D.xml
@@ -23,6 +23,9 @@
<member name="fallback_environment" type="Environment" setter="set_fallback_environment" getter="get_fallback_environment">
The World3D's fallback_environment will be used if the World3D's [Environment] fails or is missing.
</member>
+ <member name="navigation_map" type="RID" setter="" getter="get_navigation_map">
+ The [RID] of this world's navigation map. Used by the [NavigationServer3D].
+ </member>
<member name="scenario" type="RID" setter="" getter="get_scenario">
The World3D's visual scenario.
</member>
diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml
index 345e5efdee..a4a86cc22a 100644
--- a/doc/classes/XRController3D.xml
+++ b/doc/classes/XRController3D.xml
@@ -19,13 +19,6 @@
If active, returns the name of the associated controller if provided by the AR/VR SDK used.
</description>
</method>
- <method name="get_tracker_hand" qualifiers="const">
- <return type="int" enum="XRPositionalTracker.TrackerHand">
- </return>
- <description>
- Returns the hand holding this controller, if known. See [enum XRPositionalTracker.TrackerHand].
- </description>
- </method>
<method name="get_is_active" qualifiers="const">
<return type="bool">
</return>
@@ -56,6 +49,13 @@
If provided by the [XRInterface], this returns a mesh associated with the controller. This can be used to visualize the controller.
</description>
</method>
+ <method name="get_tracker_hand" qualifiers="const">
+ <return type="int" enum="XRPositionalTracker.TrackerHand">
+ </return>
+ <description>
+ Returns the hand holding this controller, if known. See [enum XRPositionalTracker.TrackerHand].
+ </description>
+ </method>
<method name="is_button_pressed" qualifiers="const">
<return type="bool">
</return>
diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml
index 36ff312e4d..36cd6e2ea0 100644
--- a/doc/classes/XRPositionalTracker.xml
+++ b/doc/classes/XRPositionalTracker.xml
@@ -12,13 +12,6 @@
<link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
- <method name="get_tracker_hand" qualifiers="const">
- <return type="int" enum="XRPositionalTracker.TrackerHand">
- </return>
- <description>
- Returns the hand holding this tracker, if known. See [enum TrackerHand] constants.
- </description>
- </method>
<method name="get_joy_id" qualifiers="const">
<return type="int">
</return>
@@ -47,6 +40,13 @@
Returns the world-space controller position.
</description>
</method>
+ <method name="get_tracker_hand" qualifiers="const">
+ <return type="int" enum="XRPositionalTracker.TrackerHand">
+ </return>
+ <description>
+ Returns the hand holding this tracker, if known. See [enum TrackerHand] constants.
+ </description>
+ </method>
<method name="get_tracker_id" qualifiers="const">
<return type="int">
</return>
@@ -68,6 +68,15 @@
Returns the tracker's type, which will be one of the values from the [enum XRServer.TrackerType] enum.
</description>
</method>
+ <method name="get_transform" qualifiers="const">
+ <return type="Transform">
+ </return>
+ <argument index="0" name="adjust_by_reference_frame" type="bool">
+ </argument>
+ <description>
+ Returns the transform combining this device's orientation and position.
+ </description>
+ </method>
<method name="is_tracking_orientation" qualifiers="const">
<return type="bool">
</return>
@@ -82,15 +91,6 @@
Returns [code]true[/code] if this device is tracking position.
</description>
</method>
- <method name="get_transform" qualifiers="const">
- <return type="Transform">
- </return>
- <argument index="0" name="adjust_by_reference_frame" type="bool">
- </argument>
- <description>
- Returns the transform combining this device's orientation and position.
- </description>
- </method>
</methods>
<members>
<member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0">
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 5335116c8a..ae3cc73098 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -110,6 +110,9 @@ class ClassDef:
self.theme_items = None # type: Optional[OrderedDict[str, List[ThemeItemDef]]]
self.tutorials = [] # type: List[str]
+ # Used to match the class with XML source for output filtering purposes.
+ self.filepath = "" # type: str
+
class State:
def __init__(self): # type: () -> None
@@ -118,11 +121,12 @@ class State:
self.classes = OrderedDict() # type: OrderedDict[str, ClassDef]
self.current_class = "" # type: str
- def parse_class(self, class_root): # type: (ET.Element) -> None
+ def parse_class(self, class_root, filepath): # type: (ET.Element, str) -> None
class_name = class_root.attrib["name"]
class_def = ClassDef(class_name)
self.classes[class_name] = class_def
+ class_def.filepath = filepath
inherits = class_root.get("inherits")
if inherits is not None:
@@ -278,6 +282,7 @@ def parse_arguments(root): # type: (ET.Element) -> List[ParameterDef]
def main(): # type: () -> None
parser = argparse.ArgumentParser()
parser.add_argument("path", nargs="+", help="A path to an XML file or a directory containing XML files to parse.")
+ parser.add_argument("--filter", default="", help="The filepath pattern for XML files to filter.")
group = parser.add_mutually_exclusive_group()
group.add_argument("--output", "-o", default=".", help="The directory to save output .rst files in.")
group.add_argument(
@@ -333,17 +338,21 @@ def main(): # type: () -> None
print_error("Duplicate class '{}'".format(name), state)
continue
- classes[name] = doc
+ classes[name] = (doc, cur_file)
for name, data in classes.items():
try:
- state.parse_class(data)
+ state.parse_class(data[0], data[1])
except Exception as e:
print_error("Exception while parsing class '{}': {}".format(name, e), state)
state.sort_classes()
+ pattern = re.compile(args.filter)
+
for class_name, class_def in state.classes.items():
+ if args.filter and not pattern.search(class_def.filepath):
+ continue
state.current_class = class_name
make_rst_class(class_def, state, args.dry_run, args.output)
diff --git a/doc/translations/README.md b/doc/translations/README.md
new file mode 100644
index 0000000000..a941eeaf49
--- /dev/null
+++ b/doc/translations/README.md
@@ -0,0 +1 @@
+These `.po` and `.pot` files come from Weblate. Do not modify them manually.
diff --git a/doc/translations/ar.po b/doc/translations/ar.po
index 1857e45627..b4ae664714 100644
--- a/doc/translations/ar.po
+++ b/doc/translations/ar.po
@@ -1,6 +1,6 @@
# Arabic translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Airbus5717 <Abdussamadf350@gmail.com>, 2020.
diff --git a/doc/translations/ca.po b/doc/translations/ca.po
index 2e5c7e2c84..6485111b20 100644
--- a/doc/translations/ca.po
+++ b/doc/translations/ca.po
@@ -1,6 +1,6 @@
# Catalan translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# roger <616steam@gmail.com>, 2020.
diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot
index 41c20b05ea..4cd89924ee 100644
--- a/doc/translations/classes.pot
+++ b/doc/translations/classes.pot
@@ -1,6 +1,6 @@
# LANGUAGE translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
diff --git a/doc/translations/cs.po b/doc/translations/cs.po
index 8d94351710..7b958a5049 100644
--- a/doc/translations/cs.po
+++ b/doc/translations/cs.po
@@ -1,6 +1,6 @@
# Czech translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Ondrej Pavelka <ondrej.pavelka@outlook.com>, 2020.
diff --git a/doc/translations/de.po b/doc/translations/de.po
index 95b73f8257..2e3e219ba6 100644
--- a/doc/translations/de.po
+++ b/doc/translations/de.po
@@ -1,6 +1,6 @@
# German translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Jaigskim <filzstift112@gmail.com>, 2020.
diff --git a/doc/translations/es.po b/doc/translations/es.po
index ef6012b240..3078c1bf90 100644
--- a/doc/translations/es.po
+++ b/doc/translations/es.po
@@ -1,6 +1,6 @@
# Spanish translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# 44pes Games <44pes.games@gmail.com>, 2020.
diff --git a/doc/translations/extract.py b/doc/translations/extract.py
index a65f942b92..a2bc5e37ec 100644
--- a/doc/translations/extract.py
+++ b/doc/translations/extract.py
@@ -9,8 +9,8 @@ from collections import OrderedDict
EXTRACT_TAGS = ["description", "brief_description", "member", "constant", "theme_item", "link"]
HEADER = """\
# LANGUAGE translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
diff --git a/doc/translations/fa.po b/doc/translations/fa.po
index 06d6ee47d7..733d3bb969 100644
--- a/doc/translations/fa.po
+++ b/doc/translations/fa.po
@@ -1,6 +1,6 @@
# LANGUAGE translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Tetra Homer <tetrahomer@gmail.com>, 2020.
diff --git a/doc/translations/fi.po b/doc/translations/fi.po
index 02ac9fdd76..0a40863a52 100644
--- a/doc/translations/fi.po
+++ b/doc/translations/fi.po
@@ -1,6 +1,6 @@
# Finnish translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Tapani Niemi <tapani.niemi@kapsi.fi>, 2020.
diff --git a/doc/translations/fr.po b/doc/translations/fr.po
index a8075d919d..c4fe08e67b 100644
--- a/doc/translations/fr.po
+++ b/doc/translations/fr.po
@@ -1,6 +1,6 @@
# French translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Rémi Verschelde <remi@godotengine.org>, 2020.
diff --git a/doc/translations/id.po b/doc/translations/id.po
index b686ef8de6..1bce3d6b50 100644
--- a/doc/translations/id.po
+++ b/doc/translations/id.po
@@ -1,6 +1,6 @@
# Indonesian translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Sofyan Sugianto <sofyanartem@gmail.com>, 2020.
diff --git a/doc/translations/it.po b/doc/translations/it.po
index f664268ebe..18e162476c 100644
--- a/doc/translations/it.po
+++ b/doc/translations/it.po
@@ -1,6 +1,6 @@
# Italian translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Micila Micillotto <micillotto@gmail.com>, 2020.
diff --git a/doc/translations/ja.po b/doc/translations/ja.po
index 9727ca0cd3..ede80a35ef 100644
--- a/doc/translations/ja.po
+++ b/doc/translations/ja.po
@@ -1,6 +1,6 @@
# Japanese translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Wataru Onuki <bettawat@yahoo.co.jp>, 2020.
diff --git a/doc/translations/ko.po b/doc/translations/ko.po
index f69b5f00c0..e71cd06ba7 100644
--- a/doc/translations/ko.po
+++ b/doc/translations/ko.po
@@ -1,6 +1,6 @@
# Korean translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Doyun Kwon <caen4516@gmail.com>, 2020.
diff --git a/doc/translations/nl.po b/doc/translations/nl.po
index 17bd3db383..032ff95bdb 100644
--- a/doc/translations/nl.po
+++ b/doc/translations/nl.po
@@ -1,6 +1,6 @@
# Dutch translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Stijn Hinlopen <f.a.hinlopen@gmail.com>, 2020.
diff --git a/doc/translations/pl.po b/doc/translations/pl.po
index fd494dc656..b0c94b55be 100644
--- a/doc/translations/pl.po
+++ b/doc/translations/pl.po
@@ -1,6 +1,6 @@
# Polish translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Tomek <kobewi4e@gmail.com>, 2020.
diff --git a/doc/translations/pt_BR.po b/doc/translations/pt_BR.po
index 2e8337989f..a508d38859 100644
--- a/doc/translations/pt_BR.po
+++ b/doc/translations/pt_BR.po
@@ -1,6 +1,6 @@
# Portuguese (Brazil) translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# José Paulo <jose.paulo1919@gmail.com>, 2020.
diff --git a/doc/translations/ro.po b/doc/translations/ro.po
index f7e5e0f86f..96c0161312 100644
--- a/doc/translations/ro.po
+++ b/doc/translations/ro.po
@@ -1,6 +1,6 @@
# LANGUAGE translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# EVOKZH <avip.ady@gmail.com>, 2020.
diff --git a/doc/translations/ru.po b/doc/translations/ru.po
index 6a397ec35d..1108967bc9 100644
--- a/doc/translations/ru.po
+++ b/doc/translations/ru.po
@@ -1,6 +1,6 @@
# Russian translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Alex <Alex.Gorichev@protonmail.com>, 2020.
diff --git a/doc/translations/sr_Cyrl.po b/doc/translations/sr_Cyrl.po
index 156fbabfc0..d7d2911b97 100644
--- a/doc/translations/sr_Cyrl.po
+++ b/doc/translations/sr_Cyrl.po
@@ -1,6 +1,6 @@
# Serbian (cyrillic) translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Младен Габић <cupakabra@protonmail.com>, 2020.
diff --git a/doc/translations/th.po b/doc/translations/th.po
index cbcbc51f63..5031ecfb0e 100644
--- a/doc/translations/th.po
+++ b/doc/translations/th.po
@@ -1,6 +1,6 @@
# Thai translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020.
diff --git a/doc/translations/tr.po b/doc/translations/tr.po
index 33208243f8..a317f4ee83 100644
--- a/doc/translations/tr.po
+++ b/doc/translations/tr.po
@@ -1,6 +1,6 @@
# Turkish translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# hüseyinyıldız <hsynyldzcn@gmail.com>, 2020.
diff --git a/doc/translations/uk.po b/doc/translations/uk.po
index 45da6d19aa..8ca75e8b19 100644
--- a/doc/translations/uk.po
+++ b/doc/translations/uk.po
@@ -1,6 +1,6 @@
# Ukrainian translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Yuri Chornoivan <yurchor@ukr.net>, 2020.
diff --git a/doc/translations/zh_Hans.po b/doc/translations/zh_Hans.po
index 2e9d14c0d8..aee852699c 100644
--- a/doc/translations/zh_Hans.po
+++ b/doc/translations/zh_Hans.po
@@ -1,6 +1,6 @@
# Chinese (Simplified) translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Haoyu Qiu <timothyqiu32@gmail.com>, 2020.
diff --git a/doc/translations/zh_Hant.po b/doc/translations/zh_Hant.po
index 9483576d0e..242c8cc086 100644
--- a/doc/translations/zh_Hant.po
+++ b/doc/translations/zh_Hant.po
@@ -1,6 +1,6 @@
# Chinese (Traditional) translation of the Godot Engine class reference.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# binotaliu <binota@protonmail.ch>, 2020.
diff --git a/drivers/alsa/SCsub b/drivers/alsa/SCsub
index 91e1140b75..1d76bb18c4 100644
--- a/drivers/alsa/SCsub
+++ b/drivers/alsa/SCsub
@@ -2,4 +2,7 @@
Import("env")
+if "alsa" in env and env["alsa"]:
+ env.add_source_files(env.drivers_sources, "asound-so_wrap.c")
+
env.add_source_files(env.drivers_sources, "*.cpp")
diff --git a/drivers/alsa/asound-so_wrap.c b/drivers/alsa/asound-so_wrap.c
new file mode 100644
index 0000000000..65624bcb70
--- /dev/null
+++ b/drivers/alsa/asound-so_wrap.c
@@ -0,0 +1,14092 @@
+// This file is generated. Do not edit!
+// see https://github.com/hpvb/dynload-wrapper for details
+// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-22 19:22:12
+// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/alsa/asoundlib.h --sys-include <alsa/asoundlib.h> --soname libasound.so.2 --init-name asound --omit-prefix snd_pcm_sw_params_set_tstamp_type --omit-prefix snd_pcm_status_get_audio_htstamp_report --omit-prefix snd_pcm_sw_params_get_tstamp_type --omit-prefix snd_pcm_status_set_audio_htstamp_config --output-header asound-so_wrap.h --output-implementation asound-so_wrap.c
+//
+#include <stdint.h>
+
+#define snd_asoundlib_version snd_asoundlib_version_dylibloader_orig_asound
+#define snd_dlpath snd_dlpath_dylibloader_orig_asound
+#define snd_dlopen snd_dlopen_dylibloader_orig_asound
+#define snd_dlsym snd_dlsym_dylibloader_orig_asound
+#define snd_dlclose snd_dlclose_dylibloader_orig_asound
+#define snd_async_add_handler snd_async_add_handler_dylibloader_orig_asound
+#define snd_async_del_handler snd_async_del_handler_dylibloader_orig_asound
+#define snd_async_handler_get_fd snd_async_handler_get_fd_dylibloader_orig_asound
+#define snd_async_handler_get_signo snd_async_handler_get_signo_dylibloader_orig_asound
+#define snd_async_handler_get_callback_private snd_async_handler_get_callback_private_dylibloader_orig_asound
+#define snd_shm_area_create snd_shm_area_create_dylibloader_orig_asound
+#define snd_shm_area_share snd_shm_area_share_dylibloader_orig_asound
+#define snd_shm_area_destroy snd_shm_area_destroy_dylibloader_orig_asound
+#define snd_user_file snd_user_file_dylibloader_orig_asound
+#define snd_input_stdio_open snd_input_stdio_open_dylibloader_orig_asound
+#define snd_input_stdio_attach snd_input_stdio_attach_dylibloader_orig_asound
+#define snd_input_buffer_open snd_input_buffer_open_dylibloader_orig_asound
+#define snd_input_close snd_input_close_dylibloader_orig_asound
+#define snd_input_scanf snd_input_scanf_dylibloader_orig_asound
+#define snd_input_gets snd_input_gets_dylibloader_orig_asound
+#define snd_input_getc snd_input_getc_dylibloader_orig_asound
+#define snd_input_ungetc snd_input_ungetc_dylibloader_orig_asound
+#define snd_output_stdio_open snd_output_stdio_open_dylibloader_orig_asound
+#define snd_output_stdio_attach snd_output_stdio_attach_dylibloader_orig_asound
+#define snd_output_buffer_open snd_output_buffer_open_dylibloader_orig_asound
+#define snd_output_buffer_string snd_output_buffer_string_dylibloader_orig_asound
+#define snd_output_close snd_output_close_dylibloader_orig_asound
+#define snd_output_printf snd_output_printf_dylibloader_orig_asound
+#define snd_output_vprintf snd_output_vprintf_dylibloader_orig_asound
+#define snd_output_puts snd_output_puts_dylibloader_orig_asound
+#define snd_output_putc snd_output_putc_dylibloader_orig_asound
+#define snd_output_flush snd_output_flush_dylibloader_orig_asound
+#define snd_strerror snd_strerror_dylibloader_orig_asound
+#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_orig_asound
+#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_orig_asound
+#define snd_config_topdir snd_config_topdir_dylibloader_orig_asound
+#define snd_config_top snd_config_top_dylibloader_orig_asound
+#define snd_config_load snd_config_load_dylibloader_orig_asound
+#define snd_config_load_override snd_config_load_override_dylibloader_orig_asound
+#define snd_config_save snd_config_save_dylibloader_orig_asound
+#define snd_config_update snd_config_update_dylibloader_orig_asound
+#define snd_config_update_r snd_config_update_r_dylibloader_orig_asound
+#define snd_config_update_free snd_config_update_free_dylibloader_orig_asound
+#define snd_config_update_free_global snd_config_update_free_global_dylibloader_orig_asound
+#define snd_config_update_ref snd_config_update_ref_dylibloader_orig_asound
+#define snd_config_ref snd_config_ref_dylibloader_orig_asound
+#define snd_config_unref snd_config_unref_dylibloader_orig_asound
+#define snd_config_search snd_config_search_dylibloader_orig_asound
+#define snd_config_searchv snd_config_searchv_dylibloader_orig_asound
+#define snd_config_search_definition snd_config_search_definition_dylibloader_orig_asound
+#define snd_config_expand snd_config_expand_dylibloader_orig_asound
+#define snd_config_evaluate snd_config_evaluate_dylibloader_orig_asound
+#define snd_config_add snd_config_add_dylibloader_orig_asound
+#define snd_config_add_before snd_config_add_before_dylibloader_orig_asound
+#define snd_config_add_after snd_config_add_after_dylibloader_orig_asound
+#define snd_config_remove snd_config_remove_dylibloader_orig_asound
+#define snd_config_delete snd_config_delete_dylibloader_orig_asound
+#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_orig_asound
+#define snd_config_copy snd_config_copy_dylibloader_orig_asound
+#define snd_config_make snd_config_make_dylibloader_orig_asound
+#define snd_config_make_integer snd_config_make_integer_dylibloader_orig_asound
+#define snd_config_make_integer64 snd_config_make_integer64_dylibloader_orig_asound
+#define snd_config_make_real snd_config_make_real_dylibloader_orig_asound
+#define snd_config_make_string snd_config_make_string_dylibloader_orig_asound
+#define snd_config_make_pointer snd_config_make_pointer_dylibloader_orig_asound
+#define snd_config_make_compound snd_config_make_compound_dylibloader_orig_asound
+#define snd_config_imake_integer snd_config_imake_integer_dylibloader_orig_asound
+#define snd_config_imake_integer64 snd_config_imake_integer64_dylibloader_orig_asound
+#define snd_config_imake_real snd_config_imake_real_dylibloader_orig_asound
+#define snd_config_imake_string snd_config_imake_string_dylibloader_orig_asound
+#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_orig_asound
+#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_orig_asound
+#define snd_config_get_type snd_config_get_type_dylibloader_orig_asound
+#define snd_config_is_array snd_config_is_array_dylibloader_orig_asound
+#define snd_config_set_id snd_config_set_id_dylibloader_orig_asound
+#define snd_config_set_integer snd_config_set_integer_dylibloader_orig_asound
+#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_orig_asound
+#define snd_config_set_real snd_config_set_real_dylibloader_orig_asound
+#define snd_config_set_string snd_config_set_string_dylibloader_orig_asound
+#define snd_config_set_ascii snd_config_set_ascii_dylibloader_orig_asound
+#define snd_config_set_pointer snd_config_set_pointer_dylibloader_orig_asound
+#define snd_config_get_id snd_config_get_id_dylibloader_orig_asound
+#define snd_config_get_integer snd_config_get_integer_dylibloader_orig_asound
+#define snd_config_get_integer64 snd_config_get_integer64_dylibloader_orig_asound
+#define snd_config_get_real snd_config_get_real_dylibloader_orig_asound
+#define snd_config_get_ireal snd_config_get_ireal_dylibloader_orig_asound
+#define snd_config_get_string snd_config_get_string_dylibloader_orig_asound
+#define snd_config_get_ascii snd_config_get_ascii_dylibloader_orig_asound
+#define snd_config_get_pointer snd_config_get_pointer_dylibloader_orig_asound
+#define snd_config_test_id snd_config_test_id_dylibloader_orig_asound
+#define snd_config_iterator_first snd_config_iterator_first_dylibloader_orig_asound
+#define snd_config_iterator_next snd_config_iterator_next_dylibloader_orig_asound
+#define snd_config_iterator_end snd_config_iterator_end_dylibloader_orig_asound
+#define snd_config_iterator_entry snd_config_iterator_entry_dylibloader_orig_asound
+#define snd_config_get_bool_ascii snd_config_get_bool_ascii_dylibloader_orig_asound
+#define snd_config_get_bool snd_config_get_bool_dylibloader_orig_asound
+#define snd_config_get_ctl_iface_ascii snd_config_get_ctl_iface_ascii_dylibloader_orig_asound
+#define snd_config_get_ctl_iface snd_config_get_ctl_iface_dylibloader_orig_asound
+#define snd_names_list snd_names_list_dylibloader_orig_asound
+#define snd_names_list_free snd_names_list_free_dylibloader_orig_asound
+#define snd_pcm_open snd_pcm_open_dylibloader_orig_asound
+#define snd_pcm_open_lconf snd_pcm_open_lconf_dylibloader_orig_asound
+#define snd_pcm_open_fallback snd_pcm_open_fallback_dylibloader_orig_asound
+#define snd_pcm_close snd_pcm_close_dylibloader_orig_asound
+#define snd_pcm_name snd_pcm_name_dylibloader_orig_asound
+#define snd_pcm_type snd_pcm_type_dylibloader_orig_asound
+#define snd_pcm_stream snd_pcm_stream_dylibloader_orig_asound
+#define snd_pcm_poll_descriptors_count snd_pcm_poll_descriptors_count_dylibloader_orig_asound
+#define snd_pcm_poll_descriptors snd_pcm_poll_descriptors_dylibloader_orig_asound
+#define snd_pcm_poll_descriptors_revents snd_pcm_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_pcm_nonblock snd_pcm_nonblock_dylibloader_orig_asound
+#define snd_async_add_pcm_handler snd_async_add_pcm_handler_dylibloader_orig_asound
+#define snd_async_handler_get_pcm snd_async_handler_get_pcm_dylibloader_orig_asound
+#define snd_pcm_info snd_pcm_info_dylibloader_orig_asound
+#define snd_pcm_hw_params_current snd_pcm_hw_params_current_dylibloader_orig_asound
+#define snd_pcm_hw_params snd_pcm_hw_params_dylibloader_orig_asound
+#define snd_pcm_hw_free snd_pcm_hw_free_dylibloader_orig_asound
+#define snd_pcm_sw_params_current snd_pcm_sw_params_current_dylibloader_orig_asound
+#define snd_pcm_sw_params snd_pcm_sw_params_dylibloader_orig_asound
+#define snd_pcm_prepare snd_pcm_prepare_dylibloader_orig_asound
+#define snd_pcm_reset snd_pcm_reset_dylibloader_orig_asound
+#define snd_pcm_status snd_pcm_status_dylibloader_orig_asound
+#define snd_pcm_start snd_pcm_start_dylibloader_orig_asound
+#define snd_pcm_drop snd_pcm_drop_dylibloader_orig_asound
+#define snd_pcm_drain snd_pcm_drain_dylibloader_orig_asound
+#define snd_pcm_pause snd_pcm_pause_dylibloader_orig_asound
+#define snd_pcm_state snd_pcm_state_dylibloader_orig_asound
+#define snd_pcm_hwsync snd_pcm_hwsync_dylibloader_orig_asound
+#define snd_pcm_delay snd_pcm_delay_dylibloader_orig_asound
+#define snd_pcm_resume snd_pcm_resume_dylibloader_orig_asound
+#define snd_pcm_htimestamp snd_pcm_htimestamp_dylibloader_orig_asound
+#define snd_pcm_avail snd_pcm_avail_dylibloader_orig_asound
+#define snd_pcm_avail_update snd_pcm_avail_update_dylibloader_orig_asound
+#define snd_pcm_avail_delay snd_pcm_avail_delay_dylibloader_orig_asound
+#define snd_pcm_rewindable snd_pcm_rewindable_dylibloader_orig_asound
+#define snd_pcm_rewind snd_pcm_rewind_dylibloader_orig_asound
+#define snd_pcm_forwardable snd_pcm_forwardable_dylibloader_orig_asound
+#define snd_pcm_forward snd_pcm_forward_dylibloader_orig_asound
+#define snd_pcm_writei snd_pcm_writei_dylibloader_orig_asound
+#define snd_pcm_readi snd_pcm_readi_dylibloader_orig_asound
+#define snd_pcm_writen snd_pcm_writen_dylibloader_orig_asound
+#define snd_pcm_readn snd_pcm_readn_dylibloader_orig_asound
+#define snd_pcm_wait snd_pcm_wait_dylibloader_orig_asound
+#define snd_pcm_link snd_pcm_link_dylibloader_orig_asound
+#define snd_pcm_unlink snd_pcm_unlink_dylibloader_orig_asound
+#define snd_pcm_query_chmaps snd_pcm_query_chmaps_dylibloader_orig_asound
+#define snd_pcm_query_chmaps_from_hw snd_pcm_query_chmaps_from_hw_dylibloader_orig_asound
+#define snd_pcm_free_chmaps snd_pcm_free_chmaps_dylibloader_orig_asound
+#define snd_pcm_get_chmap snd_pcm_get_chmap_dylibloader_orig_asound
+#define snd_pcm_set_chmap snd_pcm_set_chmap_dylibloader_orig_asound
+#define snd_pcm_chmap_type_name snd_pcm_chmap_type_name_dylibloader_orig_asound
+#define snd_pcm_chmap_name snd_pcm_chmap_name_dylibloader_orig_asound
+#define snd_pcm_chmap_long_name snd_pcm_chmap_long_name_dylibloader_orig_asound
+#define snd_pcm_chmap_print snd_pcm_chmap_print_dylibloader_orig_asound
+#define snd_pcm_chmap_from_string snd_pcm_chmap_from_string_dylibloader_orig_asound
+#define snd_pcm_chmap_parse_string snd_pcm_chmap_parse_string_dylibloader_orig_asound
+#define snd_pcm_recover snd_pcm_recover_dylibloader_orig_asound
+#define snd_pcm_set_params snd_pcm_set_params_dylibloader_orig_asound
+#define snd_pcm_get_params snd_pcm_get_params_dylibloader_orig_asound
+#define snd_pcm_info_sizeof snd_pcm_info_sizeof_dylibloader_orig_asound
+#define snd_pcm_info_malloc snd_pcm_info_malloc_dylibloader_orig_asound
+#define snd_pcm_info_free snd_pcm_info_free_dylibloader_orig_asound
+#define snd_pcm_info_copy snd_pcm_info_copy_dylibloader_orig_asound
+#define snd_pcm_info_get_device snd_pcm_info_get_device_dylibloader_orig_asound
+#define snd_pcm_info_get_subdevice snd_pcm_info_get_subdevice_dylibloader_orig_asound
+#define snd_pcm_info_get_stream snd_pcm_info_get_stream_dylibloader_orig_asound
+#define snd_pcm_info_get_card snd_pcm_info_get_card_dylibloader_orig_asound
+#define snd_pcm_info_get_id snd_pcm_info_get_id_dylibloader_orig_asound
+#define snd_pcm_info_get_name snd_pcm_info_get_name_dylibloader_orig_asound
+#define snd_pcm_info_get_subdevice_name snd_pcm_info_get_subdevice_name_dylibloader_orig_asound
+#define snd_pcm_info_get_class snd_pcm_info_get_class_dylibloader_orig_asound
+#define snd_pcm_info_get_subclass snd_pcm_info_get_subclass_dylibloader_orig_asound
+#define snd_pcm_info_get_subdevices_count snd_pcm_info_get_subdevices_count_dylibloader_orig_asound
+#define snd_pcm_info_get_subdevices_avail snd_pcm_info_get_subdevices_avail_dylibloader_orig_asound
+#define snd_pcm_info_get_sync snd_pcm_info_get_sync_dylibloader_orig_asound
+#define snd_pcm_info_set_device snd_pcm_info_set_device_dylibloader_orig_asound
+#define snd_pcm_info_set_subdevice snd_pcm_info_set_subdevice_dylibloader_orig_asound
+#define snd_pcm_info_set_stream snd_pcm_info_set_stream_dylibloader_orig_asound
+#define snd_pcm_hw_params_any snd_pcm_hw_params_any_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_mmap_sample_resolution snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_double snd_pcm_hw_params_is_double_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_batch snd_pcm_hw_params_is_batch_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_block_transfer snd_pcm_hw_params_is_block_transfer_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_monotonic snd_pcm_hw_params_is_monotonic_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_overrange snd_pcm_hw_params_can_overrange_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_pause snd_pcm_hw_params_can_pause_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_resume snd_pcm_hw_params_can_resume_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_half_duplex snd_pcm_hw_params_is_half_duplex_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_joint_duplex snd_pcm_hw_params_is_joint_duplex_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_sync_start snd_pcm_hw_params_can_sync_start_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_disable_period_wakeup snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_orig_asound
+#define snd_pcm_hw_params_supports_audio_wallclock_ts snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_orig_asound
+#define snd_pcm_hw_params_supports_audio_ts_type snd_pcm_hw_params_supports_audio_ts_type_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate_numden snd_pcm_hw_params_get_rate_numden_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_sbits snd_pcm_hw_params_get_sbits_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_fifo_size snd_pcm_hw_params_get_fifo_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_sizeof snd_pcm_hw_params_sizeof_dylibloader_orig_asound
+#define snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc_dylibloader_orig_asound
+#define snd_pcm_hw_params_free snd_pcm_hw_params_free_dylibloader_orig_asound
+#define snd_pcm_hw_params_copy snd_pcm_hw_params_copy_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_access snd_pcm_hw_params_get_access_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_access snd_pcm_hw_params_test_access_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_access_first snd_pcm_hw_params_set_access_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_access_last snd_pcm_hw_params_set_access_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_access_mask snd_pcm_hw_params_set_access_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_access_mask snd_pcm_hw_params_get_access_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_format snd_pcm_hw_params_get_format_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_format snd_pcm_hw_params_test_format_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_format_first snd_pcm_hw_params_set_format_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_format_last snd_pcm_hw_params_set_format_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_format_mask snd_pcm_hw_params_set_format_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_format_mask snd_pcm_hw_params_get_format_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_subformat snd_pcm_hw_params_get_subformat_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_subformat snd_pcm_hw_params_test_subformat_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_subformat snd_pcm_hw_params_set_subformat_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_subformat_first snd_pcm_hw_params_set_subformat_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_subformat_last snd_pcm_hw_params_set_subformat_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_subformat_mask snd_pcm_hw_params_set_subformat_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_subformat_mask snd_pcm_hw_params_get_subformat_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_channels snd_pcm_hw_params_get_channels_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_channels_min snd_pcm_hw_params_get_channels_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_channels_max snd_pcm_hw_params_get_channels_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_channels snd_pcm_hw_params_test_channels_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels snd_pcm_hw_params_set_channels_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_min snd_pcm_hw_params_set_channels_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_max snd_pcm_hw_params_set_channels_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_minmax snd_pcm_hw_params_set_channels_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_near snd_pcm_hw_params_set_channels_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_first snd_pcm_hw_params_set_channels_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_last snd_pcm_hw_params_set_channels_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate snd_pcm_hw_params_get_rate_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate_min snd_pcm_hw_params_get_rate_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate_max snd_pcm_hw_params_get_rate_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_rate snd_pcm_hw_params_test_rate_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate snd_pcm_hw_params_set_rate_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_min snd_pcm_hw_params_set_rate_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_max snd_pcm_hw_params_set_rate_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_minmax snd_pcm_hw_params_set_rate_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_near snd_pcm_hw_params_set_rate_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_first snd_pcm_hw_params_set_rate_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_last snd_pcm_hw_params_set_rate_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_resample snd_pcm_hw_params_set_rate_resample_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate_resample snd_pcm_hw_params_get_rate_resample_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_export_buffer snd_pcm_hw_params_set_export_buffer_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_export_buffer snd_pcm_hw_params_get_export_buffer_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_wakeup snd_pcm_hw_params_set_period_wakeup_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_wakeup snd_pcm_hw_params_get_period_wakeup_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_time snd_pcm_hw_params_get_period_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_time_min snd_pcm_hw_params_get_period_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_time_max snd_pcm_hw_params_get_period_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_period_time snd_pcm_hw_params_test_period_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time snd_pcm_hw_params_set_period_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_min snd_pcm_hw_params_set_period_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_max snd_pcm_hw_params_set_period_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_minmax snd_pcm_hw_params_set_period_time_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_near snd_pcm_hw_params_set_period_time_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_first snd_pcm_hw_params_set_period_time_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_last snd_pcm_hw_params_set_period_time_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_size snd_pcm_hw_params_get_period_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_size_min snd_pcm_hw_params_get_period_size_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_size_max snd_pcm_hw_params_get_period_size_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_period_size snd_pcm_hw_params_test_period_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size snd_pcm_hw_params_set_period_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_min snd_pcm_hw_params_set_period_size_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_max snd_pcm_hw_params_set_period_size_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_minmax snd_pcm_hw_params_set_period_size_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_near snd_pcm_hw_params_set_period_size_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_first snd_pcm_hw_params_set_period_size_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_last snd_pcm_hw_params_set_period_size_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_integer snd_pcm_hw_params_set_period_size_integer_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_periods snd_pcm_hw_params_get_periods_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_periods_min snd_pcm_hw_params_get_periods_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_periods_max snd_pcm_hw_params_get_periods_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_periods snd_pcm_hw_params_test_periods_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods snd_pcm_hw_params_set_periods_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_min snd_pcm_hw_params_set_periods_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_max snd_pcm_hw_params_set_periods_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_minmax snd_pcm_hw_params_set_periods_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_near snd_pcm_hw_params_set_periods_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_first snd_pcm_hw_params_set_periods_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_last snd_pcm_hw_params_set_periods_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_integer snd_pcm_hw_params_set_periods_integer_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_time snd_pcm_hw_params_get_buffer_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_time_min snd_pcm_hw_params_get_buffer_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_time_max snd_pcm_hw_params_get_buffer_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_buffer_time snd_pcm_hw_params_test_buffer_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time snd_pcm_hw_params_set_buffer_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_min snd_pcm_hw_params_set_buffer_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_max snd_pcm_hw_params_set_buffer_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_minmax snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_near snd_pcm_hw_params_set_buffer_time_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_first snd_pcm_hw_params_set_buffer_time_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_last snd_pcm_hw_params_set_buffer_time_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_size snd_pcm_hw_params_get_buffer_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_size_min snd_pcm_hw_params_get_buffer_size_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_size_max snd_pcm_hw_params_get_buffer_size_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_buffer_size snd_pcm_hw_params_test_buffer_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size snd_pcm_hw_params_set_buffer_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_min snd_pcm_hw_params_set_buffer_size_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_max snd_pcm_hw_params_set_buffer_size_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_minmax snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_near snd_pcm_hw_params_set_buffer_size_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_first snd_pcm_hw_params_set_buffer_size_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_last snd_pcm_hw_params_set_buffer_size_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_min_align snd_pcm_hw_params_get_min_align_dylibloader_orig_asound
+#define snd_pcm_sw_params_sizeof snd_pcm_sw_params_sizeof_dylibloader_orig_asound
+#define snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc_dylibloader_orig_asound
+#define snd_pcm_sw_params_free snd_pcm_sw_params_free_dylibloader_orig_asound
+#define snd_pcm_sw_params_copy snd_pcm_sw_params_copy_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_boundary snd_pcm_sw_params_get_boundary_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_tstamp_mode snd_pcm_sw_params_set_tstamp_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_tstamp_mode snd_pcm_sw_params_get_tstamp_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_avail_min snd_pcm_sw_params_set_avail_min_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_avail_min snd_pcm_sw_params_get_avail_min_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_period_event snd_pcm_sw_params_set_period_event_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_period_event snd_pcm_sw_params_get_period_event_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_start_threshold snd_pcm_sw_params_set_start_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_start_threshold snd_pcm_sw_params_get_start_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_stop_threshold snd_pcm_sw_params_set_stop_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_stop_threshold snd_pcm_sw_params_get_stop_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_silence_threshold snd_pcm_sw_params_set_silence_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_silence_threshold snd_pcm_sw_params_get_silence_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_silence_size snd_pcm_sw_params_set_silence_size_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_silence_size snd_pcm_sw_params_get_silence_size_dylibloader_orig_asound
+#define snd_pcm_access_mask_sizeof snd_pcm_access_mask_sizeof_dylibloader_orig_asound
+#define snd_pcm_access_mask_malloc snd_pcm_access_mask_malloc_dylibloader_orig_asound
+#define snd_pcm_access_mask_free snd_pcm_access_mask_free_dylibloader_orig_asound
+#define snd_pcm_access_mask_copy snd_pcm_access_mask_copy_dylibloader_orig_asound
+#define snd_pcm_access_mask_none snd_pcm_access_mask_none_dylibloader_orig_asound
+#define snd_pcm_access_mask_any snd_pcm_access_mask_any_dylibloader_orig_asound
+#define snd_pcm_access_mask_test snd_pcm_access_mask_test_dylibloader_orig_asound
+#define snd_pcm_access_mask_empty snd_pcm_access_mask_empty_dylibloader_orig_asound
+#define snd_pcm_access_mask_set snd_pcm_access_mask_set_dylibloader_orig_asound
+#define snd_pcm_access_mask_reset snd_pcm_access_mask_reset_dylibloader_orig_asound
+#define snd_pcm_format_mask_sizeof snd_pcm_format_mask_sizeof_dylibloader_orig_asound
+#define snd_pcm_format_mask_malloc snd_pcm_format_mask_malloc_dylibloader_orig_asound
+#define snd_pcm_format_mask_free snd_pcm_format_mask_free_dylibloader_orig_asound
+#define snd_pcm_format_mask_copy snd_pcm_format_mask_copy_dylibloader_orig_asound
+#define snd_pcm_format_mask_none snd_pcm_format_mask_none_dylibloader_orig_asound
+#define snd_pcm_format_mask_any snd_pcm_format_mask_any_dylibloader_orig_asound
+#define snd_pcm_format_mask_test snd_pcm_format_mask_test_dylibloader_orig_asound
+#define snd_pcm_format_mask_empty snd_pcm_format_mask_empty_dylibloader_orig_asound
+#define snd_pcm_format_mask_set snd_pcm_format_mask_set_dylibloader_orig_asound
+#define snd_pcm_format_mask_reset snd_pcm_format_mask_reset_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_sizeof snd_pcm_subformat_mask_sizeof_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_malloc snd_pcm_subformat_mask_malloc_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_free snd_pcm_subformat_mask_free_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_copy snd_pcm_subformat_mask_copy_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_none snd_pcm_subformat_mask_none_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_any snd_pcm_subformat_mask_any_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_test snd_pcm_subformat_mask_test_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_empty snd_pcm_subformat_mask_empty_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_set snd_pcm_subformat_mask_set_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_reset snd_pcm_subformat_mask_reset_dylibloader_orig_asound
+#define snd_pcm_status_sizeof snd_pcm_status_sizeof_dylibloader_orig_asound
+#define snd_pcm_status_malloc snd_pcm_status_malloc_dylibloader_orig_asound
+#define snd_pcm_status_free snd_pcm_status_free_dylibloader_orig_asound
+#define snd_pcm_status_copy snd_pcm_status_copy_dylibloader_orig_asound
+#define snd_pcm_status_get_state snd_pcm_status_get_state_dylibloader_orig_asound
+#define snd_pcm_status_get_trigger_tstamp snd_pcm_status_get_trigger_tstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_trigger_htstamp snd_pcm_status_get_trigger_htstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_tstamp snd_pcm_status_get_tstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_htstamp snd_pcm_status_get_htstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_audio_htstamp snd_pcm_status_get_audio_htstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_driver_htstamp snd_pcm_status_get_driver_htstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_delay snd_pcm_status_get_delay_dylibloader_orig_asound
+#define snd_pcm_status_get_avail snd_pcm_status_get_avail_dylibloader_orig_asound
+#define snd_pcm_status_get_avail_max snd_pcm_status_get_avail_max_dylibloader_orig_asound
+#define snd_pcm_status_get_overrange snd_pcm_status_get_overrange_dylibloader_orig_asound
+#define snd_pcm_type_name snd_pcm_type_name_dylibloader_orig_asound
+#define snd_pcm_stream_name snd_pcm_stream_name_dylibloader_orig_asound
+#define snd_pcm_access_name snd_pcm_access_name_dylibloader_orig_asound
+#define snd_pcm_format_name snd_pcm_format_name_dylibloader_orig_asound
+#define snd_pcm_format_description snd_pcm_format_description_dylibloader_orig_asound
+#define snd_pcm_subformat_name snd_pcm_subformat_name_dylibloader_orig_asound
+#define snd_pcm_subformat_description snd_pcm_subformat_description_dylibloader_orig_asound
+#define snd_pcm_format_value snd_pcm_format_value_dylibloader_orig_asound
+#define snd_pcm_tstamp_mode_name snd_pcm_tstamp_mode_name_dylibloader_orig_asound
+#define snd_pcm_state_name snd_pcm_state_name_dylibloader_orig_asound
+#define snd_pcm_dump snd_pcm_dump_dylibloader_orig_asound
+#define snd_pcm_dump_hw_setup snd_pcm_dump_hw_setup_dylibloader_orig_asound
+#define snd_pcm_dump_sw_setup snd_pcm_dump_sw_setup_dylibloader_orig_asound
+#define snd_pcm_dump_setup snd_pcm_dump_setup_dylibloader_orig_asound
+#define snd_pcm_hw_params_dump snd_pcm_hw_params_dump_dylibloader_orig_asound
+#define snd_pcm_sw_params_dump snd_pcm_sw_params_dump_dylibloader_orig_asound
+#define snd_pcm_status_dump snd_pcm_status_dump_dylibloader_orig_asound
+#define snd_pcm_mmap_begin snd_pcm_mmap_begin_dylibloader_orig_asound
+#define snd_pcm_mmap_commit snd_pcm_mmap_commit_dylibloader_orig_asound
+#define snd_pcm_mmap_writei snd_pcm_mmap_writei_dylibloader_orig_asound
+#define snd_pcm_mmap_readi snd_pcm_mmap_readi_dylibloader_orig_asound
+#define snd_pcm_mmap_writen snd_pcm_mmap_writen_dylibloader_orig_asound
+#define snd_pcm_mmap_readn snd_pcm_mmap_readn_dylibloader_orig_asound
+#define snd_pcm_format_signed snd_pcm_format_signed_dylibloader_orig_asound
+#define snd_pcm_format_unsigned snd_pcm_format_unsigned_dylibloader_orig_asound
+#define snd_pcm_format_linear snd_pcm_format_linear_dylibloader_orig_asound
+#define snd_pcm_format_float snd_pcm_format_float_dylibloader_orig_asound
+#define snd_pcm_format_little_endian snd_pcm_format_little_endian_dylibloader_orig_asound
+#define snd_pcm_format_big_endian snd_pcm_format_big_endian_dylibloader_orig_asound
+#define snd_pcm_format_cpu_endian snd_pcm_format_cpu_endian_dylibloader_orig_asound
+#define snd_pcm_format_width snd_pcm_format_width_dylibloader_orig_asound
+#define snd_pcm_format_physical_width snd_pcm_format_physical_width_dylibloader_orig_asound
+#define snd_pcm_build_linear_format snd_pcm_build_linear_format_dylibloader_orig_asound
+#define snd_pcm_format_size snd_pcm_format_size_dylibloader_orig_asound
+#define snd_pcm_format_silence snd_pcm_format_silence_dylibloader_orig_asound
+#define snd_pcm_format_silence_16 snd_pcm_format_silence_16_dylibloader_orig_asound
+#define snd_pcm_format_silence_32 snd_pcm_format_silence_32_dylibloader_orig_asound
+#define snd_pcm_format_silence_64 snd_pcm_format_silence_64_dylibloader_orig_asound
+#define snd_pcm_format_set_silence snd_pcm_format_set_silence_dylibloader_orig_asound
+#define snd_pcm_bytes_to_frames snd_pcm_bytes_to_frames_dylibloader_orig_asound
+#define snd_pcm_frames_to_bytes snd_pcm_frames_to_bytes_dylibloader_orig_asound
+#define snd_pcm_bytes_to_samples snd_pcm_bytes_to_samples_dylibloader_orig_asound
+#define snd_pcm_samples_to_bytes snd_pcm_samples_to_bytes_dylibloader_orig_asound
+#define snd_pcm_area_silence snd_pcm_area_silence_dylibloader_orig_asound
+#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_orig_asound
+#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_orig_asound
+#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_orig_asound
+#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_orig_asound
+#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_orig_asound
+#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_orig_asound
+#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_orig_asound
+#define snd_pcm_hook_add snd_pcm_hook_add_dylibloader_orig_asound
+#define snd_pcm_hook_remove snd_pcm_hook_remove_dylibloader_orig_asound
+#define snd_pcm_meter_get_bufsize snd_pcm_meter_get_bufsize_dylibloader_orig_asound
+#define snd_pcm_meter_get_channels snd_pcm_meter_get_channels_dylibloader_orig_asound
+#define snd_pcm_meter_get_rate snd_pcm_meter_get_rate_dylibloader_orig_asound
+#define snd_pcm_meter_get_now snd_pcm_meter_get_now_dylibloader_orig_asound
+#define snd_pcm_meter_get_boundary snd_pcm_meter_get_boundary_dylibloader_orig_asound
+#define snd_pcm_meter_add_scope snd_pcm_meter_add_scope_dylibloader_orig_asound
+#define snd_pcm_meter_search_scope snd_pcm_meter_search_scope_dylibloader_orig_asound
+#define snd_pcm_scope_malloc snd_pcm_scope_malloc_dylibloader_orig_asound
+#define snd_pcm_scope_set_ops snd_pcm_scope_set_ops_dylibloader_orig_asound
+#define snd_pcm_scope_set_name snd_pcm_scope_set_name_dylibloader_orig_asound
+#define snd_pcm_scope_get_name snd_pcm_scope_get_name_dylibloader_orig_asound
+#define snd_pcm_scope_get_callback_private snd_pcm_scope_get_callback_private_dylibloader_orig_asound
+#define snd_pcm_scope_set_callback_private snd_pcm_scope_set_callback_private_dylibloader_orig_asound
+#define snd_pcm_scope_s16_open snd_pcm_scope_s16_open_dylibloader_orig_asound
+#define snd_pcm_scope_s16_get_channel_buffer snd_pcm_scope_s16_get_channel_buffer_dylibloader_orig_asound
+#define snd_spcm_init snd_spcm_init_dylibloader_orig_asound
+#define snd_spcm_init_duplex snd_spcm_init_duplex_dylibloader_orig_asound
+#define snd_spcm_init_get_params snd_spcm_init_get_params_dylibloader_orig_asound
+#define snd_pcm_start_mode_name snd_pcm_start_mode_name_dylibloader_orig_asound
+#define snd_pcm_xrun_mode_name snd_pcm_xrun_mode_name_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_start_mode snd_pcm_sw_params_set_start_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_start_mode snd_pcm_sw_params_get_start_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_xrun_mode snd_pcm_sw_params_set_xrun_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_xrun_mode snd_pcm_sw_params_get_xrun_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_xfer_align snd_pcm_sw_params_set_xfer_align_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_xfer_align snd_pcm_sw_params_get_xfer_align_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_sleep_min snd_pcm_sw_params_set_sleep_min_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_sleep_min snd_pcm_sw_params_get_sleep_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_tick_time snd_pcm_hw_params_get_tick_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_tick_time_min snd_pcm_hw_params_get_tick_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_tick_time_max snd_pcm_hw_params_get_tick_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_tick_time snd_pcm_hw_params_test_tick_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time snd_pcm_hw_params_set_tick_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_min snd_pcm_hw_params_set_tick_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_max snd_pcm_hw_params_set_tick_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_minmax snd_pcm_hw_params_set_tick_time_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_near snd_pcm_hw_params_set_tick_time_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_first snd_pcm_hw_params_set_tick_time_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_last snd_pcm_hw_params_set_tick_time_last_dylibloader_orig_asound
+#define snd_rawmidi_open snd_rawmidi_open_dylibloader_orig_asound
+#define snd_rawmidi_open_lconf snd_rawmidi_open_lconf_dylibloader_orig_asound
+#define snd_rawmidi_close snd_rawmidi_close_dylibloader_orig_asound
+#define snd_rawmidi_poll_descriptors_count snd_rawmidi_poll_descriptors_count_dylibloader_orig_asound
+#define snd_rawmidi_poll_descriptors snd_rawmidi_poll_descriptors_dylibloader_orig_asound
+#define snd_rawmidi_poll_descriptors_revents snd_rawmidi_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_rawmidi_nonblock snd_rawmidi_nonblock_dylibloader_orig_asound
+#define snd_rawmidi_info_sizeof snd_rawmidi_info_sizeof_dylibloader_orig_asound
+#define snd_rawmidi_info_malloc snd_rawmidi_info_malloc_dylibloader_orig_asound
+#define snd_rawmidi_info_free snd_rawmidi_info_free_dylibloader_orig_asound
+#define snd_rawmidi_info_copy snd_rawmidi_info_copy_dylibloader_orig_asound
+#define snd_rawmidi_info_get_device snd_rawmidi_info_get_device_dylibloader_orig_asound
+#define snd_rawmidi_info_get_subdevice snd_rawmidi_info_get_subdevice_dylibloader_orig_asound
+#define snd_rawmidi_info_get_stream snd_rawmidi_info_get_stream_dylibloader_orig_asound
+#define snd_rawmidi_info_get_card snd_rawmidi_info_get_card_dylibloader_orig_asound
+#define snd_rawmidi_info_get_flags snd_rawmidi_info_get_flags_dylibloader_orig_asound
+#define snd_rawmidi_info_get_id snd_rawmidi_info_get_id_dylibloader_orig_asound
+#define snd_rawmidi_info_get_name snd_rawmidi_info_get_name_dylibloader_orig_asound
+#define snd_rawmidi_info_get_subdevice_name snd_rawmidi_info_get_subdevice_name_dylibloader_orig_asound
+#define snd_rawmidi_info_get_subdevices_count snd_rawmidi_info_get_subdevices_count_dylibloader_orig_asound
+#define snd_rawmidi_info_get_subdevices_avail snd_rawmidi_info_get_subdevices_avail_dylibloader_orig_asound
+#define snd_rawmidi_info_set_device snd_rawmidi_info_set_device_dylibloader_orig_asound
+#define snd_rawmidi_info_set_subdevice snd_rawmidi_info_set_subdevice_dylibloader_orig_asound
+#define snd_rawmidi_info_set_stream snd_rawmidi_info_set_stream_dylibloader_orig_asound
+#define snd_rawmidi_info snd_rawmidi_info_dylibloader_orig_asound
+#define snd_rawmidi_params_sizeof snd_rawmidi_params_sizeof_dylibloader_orig_asound
+#define snd_rawmidi_params_malloc snd_rawmidi_params_malloc_dylibloader_orig_asound
+#define snd_rawmidi_params_free snd_rawmidi_params_free_dylibloader_orig_asound
+#define snd_rawmidi_params_copy snd_rawmidi_params_copy_dylibloader_orig_asound
+#define snd_rawmidi_params_set_buffer_size snd_rawmidi_params_set_buffer_size_dylibloader_orig_asound
+#define snd_rawmidi_params_get_buffer_size snd_rawmidi_params_get_buffer_size_dylibloader_orig_asound
+#define snd_rawmidi_params_set_avail_min snd_rawmidi_params_set_avail_min_dylibloader_orig_asound
+#define snd_rawmidi_params_get_avail_min snd_rawmidi_params_get_avail_min_dylibloader_orig_asound
+#define snd_rawmidi_params_set_no_active_sensing snd_rawmidi_params_set_no_active_sensing_dylibloader_orig_asound
+#define snd_rawmidi_params_get_no_active_sensing snd_rawmidi_params_get_no_active_sensing_dylibloader_orig_asound
+#define snd_rawmidi_params snd_rawmidi_params_dylibloader_orig_asound
+#define snd_rawmidi_params_current snd_rawmidi_params_current_dylibloader_orig_asound
+#define snd_rawmidi_status_sizeof snd_rawmidi_status_sizeof_dylibloader_orig_asound
+#define snd_rawmidi_status_malloc snd_rawmidi_status_malloc_dylibloader_orig_asound
+#define snd_rawmidi_status_free snd_rawmidi_status_free_dylibloader_orig_asound
+#define snd_rawmidi_status_copy snd_rawmidi_status_copy_dylibloader_orig_asound
+#define snd_rawmidi_status_get_tstamp snd_rawmidi_status_get_tstamp_dylibloader_orig_asound
+#define snd_rawmidi_status_get_avail snd_rawmidi_status_get_avail_dylibloader_orig_asound
+#define snd_rawmidi_status_get_xruns snd_rawmidi_status_get_xruns_dylibloader_orig_asound
+#define snd_rawmidi_status snd_rawmidi_status_dylibloader_orig_asound
+#define snd_rawmidi_drain snd_rawmidi_drain_dylibloader_orig_asound
+#define snd_rawmidi_drop snd_rawmidi_drop_dylibloader_orig_asound
+#define snd_rawmidi_write snd_rawmidi_write_dylibloader_orig_asound
+#define snd_rawmidi_read snd_rawmidi_read_dylibloader_orig_asound
+#define snd_rawmidi_name snd_rawmidi_name_dylibloader_orig_asound
+#define snd_rawmidi_type snd_rawmidi_type_dylibloader_orig_asound
+#define snd_rawmidi_stream snd_rawmidi_stream_dylibloader_orig_asound
+#define snd_timer_query_open snd_timer_query_open_dylibloader_orig_asound
+#define snd_timer_query_open_lconf snd_timer_query_open_lconf_dylibloader_orig_asound
+#define snd_timer_query_close snd_timer_query_close_dylibloader_orig_asound
+#define snd_timer_query_next_device snd_timer_query_next_device_dylibloader_orig_asound
+#define snd_timer_query_info snd_timer_query_info_dylibloader_orig_asound
+#define snd_timer_query_params snd_timer_query_params_dylibloader_orig_asound
+#define snd_timer_query_status snd_timer_query_status_dylibloader_orig_asound
+#define snd_timer_open snd_timer_open_dylibloader_orig_asound
+#define snd_timer_open_lconf snd_timer_open_lconf_dylibloader_orig_asound
+#define snd_timer_close snd_timer_close_dylibloader_orig_asound
+#define snd_async_add_timer_handler snd_async_add_timer_handler_dylibloader_orig_asound
+#define snd_async_handler_get_timer snd_async_handler_get_timer_dylibloader_orig_asound
+#define snd_timer_poll_descriptors_count snd_timer_poll_descriptors_count_dylibloader_orig_asound
+#define snd_timer_poll_descriptors snd_timer_poll_descriptors_dylibloader_orig_asound
+#define snd_timer_poll_descriptors_revents snd_timer_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_timer_info snd_timer_info_dylibloader_orig_asound
+#define snd_timer_params snd_timer_params_dylibloader_orig_asound
+#define snd_timer_status snd_timer_status_dylibloader_orig_asound
+#define snd_timer_start snd_timer_start_dylibloader_orig_asound
+#define snd_timer_stop snd_timer_stop_dylibloader_orig_asound
+#define snd_timer_continue snd_timer_continue_dylibloader_orig_asound
+#define snd_timer_read snd_timer_read_dylibloader_orig_asound
+#define snd_timer_id_sizeof snd_timer_id_sizeof_dylibloader_orig_asound
+#define snd_timer_id_malloc snd_timer_id_malloc_dylibloader_orig_asound
+#define snd_timer_id_free snd_timer_id_free_dylibloader_orig_asound
+#define snd_timer_id_copy snd_timer_id_copy_dylibloader_orig_asound
+#define snd_timer_id_set_class snd_timer_id_set_class_dylibloader_orig_asound
+#define snd_timer_id_get_class snd_timer_id_get_class_dylibloader_orig_asound
+#define snd_timer_id_set_sclass snd_timer_id_set_sclass_dylibloader_orig_asound
+#define snd_timer_id_get_sclass snd_timer_id_get_sclass_dylibloader_orig_asound
+#define snd_timer_id_set_card snd_timer_id_set_card_dylibloader_orig_asound
+#define snd_timer_id_get_card snd_timer_id_get_card_dylibloader_orig_asound
+#define snd_timer_id_set_device snd_timer_id_set_device_dylibloader_orig_asound
+#define snd_timer_id_get_device snd_timer_id_get_device_dylibloader_orig_asound
+#define snd_timer_id_set_subdevice snd_timer_id_set_subdevice_dylibloader_orig_asound
+#define snd_timer_id_get_subdevice snd_timer_id_get_subdevice_dylibloader_orig_asound
+#define snd_timer_ginfo_sizeof snd_timer_ginfo_sizeof_dylibloader_orig_asound
+#define snd_timer_ginfo_malloc snd_timer_ginfo_malloc_dylibloader_orig_asound
+#define snd_timer_ginfo_free snd_timer_ginfo_free_dylibloader_orig_asound
+#define snd_timer_ginfo_copy snd_timer_ginfo_copy_dylibloader_orig_asound
+#define snd_timer_ginfo_set_tid snd_timer_ginfo_set_tid_dylibloader_orig_asound
+#define snd_timer_ginfo_get_tid snd_timer_ginfo_get_tid_dylibloader_orig_asound
+#define snd_timer_ginfo_get_flags snd_timer_ginfo_get_flags_dylibloader_orig_asound
+#define snd_timer_ginfo_get_card snd_timer_ginfo_get_card_dylibloader_orig_asound
+#define snd_timer_ginfo_get_id snd_timer_ginfo_get_id_dylibloader_orig_asound
+#define snd_timer_ginfo_get_name snd_timer_ginfo_get_name_dylibloader_orig_asound
+#define snd_timer_ginfo_get_resolution snd_timer_ginfo_get_resolution_dylibloader_orig_asound
+#define snd_timer_ginfo_get_resolution_min snd_timer_ginfo_get_resolution_min_dylibloader_orig_asound
+#define snd_timer_ginfo_get_resolution_max snd_timer_ginfo_get_resolution_max_dylibloader_orig_asound
+#define snd_timer_ginfo_get_clients snd_timer_ginfo_get_clients_dylibloader_orig_asound
+#define snd_timer_info_sizeof snd_timer_info_sizeof_dylibloader_orig_asound
+#define snd_timer_info_malloc snd_timer_info_malloc_dylibloader_orig_asound
+#define snd_timer_info_free snd_timer_info_free_dylibloader_orig_asound
+#define snd_timer_info_copy snd_timer_info_copy_dylibloader_orig_asound
+#define snd_timer_info_is_slave snd_timer_info_is_slave_dylibloader_orig_asound
+#define snd_timer_info_get_card snd_timer_info_get_card_dylibloader_orig_asound
+#define snd_timer_info_get_id snd_timer_info_get_id_dylibloader_orig_asound
+#define snd_timer_info_get_name snd_timer_info_get_name_dylibloader_orig_asound
+#define snd_timer_info_get_resolution snd_timer_info_get_resolution_dylibloader_orig_asound
+#define snd_timer_params_sizeof snd_timer_params_sizeof_dylibloader_orig_asound
+#define snd_timer_params_malloc snd_timer_params_malloc_dylibloader_orig_asound
+#define snd_timer_params_free snd_timer_params_free_dylibloader_orig_asound
+#define snd_timer_params_copy snd_timer_params_copy_dylibloader_orig_asound
+#define snd_timer_params_set_auto_start snd_timer_params_set_auto_start_dylibloader_orig_asound
+#define snd_timer_params_get_auto_start snd_timer_params_get_auto_start_dylibloader_orig_asound
+#define snd_timer_params_set_exclusive snd_timer_params_set_exclusive_dylibloader_orig_asound
+#define snd_timer_params_get_exclusive snd_timer_params_get_exclusive_dylibloader_orig_asound
+#define snd_timer_params_set_early_event snd_timer_params_set_early_event_dylibloader_orig_asound
+#define snd_timer_params_get_early_event snd_timer_params_get_early_event_dylibloader_orig_asound
+#define snd_timer_params_set_ticks snd_timer_params_set_ticks_dylibloader_orig_asound
+#define snd_timer_params_get_ticks snd_timer_params_get_ticks_dylibloader_orig_asound
+#define snd_timer_params_set_queue_size snd_timer_params_set_queue_size_dylibloader_orig_asound
+#define snd_timer_params_get_queue_size snd_timer_params_get_queue_size_dylibloader_orig_asound
+#define snd_timer_params_set_filter snd_timer_params_set_filter_dylibloader_orig_asound
+#define snd_timer_params_get_filter snd_timer_params_get_filter_dylibloader_orig_asound
+#define snd_timer_status_sizeof snd_timer_status_sizeof_dylibloader_orig_asound
+#define snd_timer_status_malloc snd_timer_status_malloc_dylibloader_orig_asound
+#define snd_timer_status_free snd_timer_status_free_dylibloader_orig_asound
+#define snd_timer_status_copy snd_timer_status_copy_dylibloader_orig_asound
+#define snd_timer_status_get_timestamp snd_timer_status_get_timestamp_dylibloader_orig_asound
+#define snd_timer_status_get_resolution snd_timer_status_get_resolution_dylibloader_orig_asound
+#define snd_timer_status_get_lost snd_timer_status_get_lost_dylibloader_orig_asound
+#define snd_timer_status_get_overrun snd_timer_status_get_overrun_dylibloader_orig_asound
+#define snd_timer_status_get_queue snd_timer_status_get_queue_dylibloader_orig_asound
+#define snd_timer_info_get_ticks snd_timer_info_get_ticks_dylibloader_orig_asound
+#define snd_hwdep_open snd_hwdep_open_dylibloader_orig_asound
+#define snd_hwdep_close snd_hwdep_close_dylibloader_orig_asound
+#define snd_hwdep_poll_descriptors snd_hwdep_poll_descriptors_dylibloader_orig_asound
+#define snd_hwdep_poll_descriptors_count snd_hwdep_poll_descriptors_count_dylibloader_orig_asound
+#define snd_hwdep_poll_descriptors_revents snd_hwdep_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_hwdep_nonblock snd_hwdep_nonblock_dylibloader_orig_asound
+#define snd_hwdep_info snd_hwdep_info_dylibloader_orig_asound
+#define snd_hwdep_dsp_status snd_hwdep_dsp_status_dylibloader_orig_asound
+#define snd_hwdep_dsp_load snd_hwdep_dsp_load_dylibloader_orig_asound
+#define snd_hwdep_ioctl snd_hwdep_ioctl_dylibloader_orig_asound
+#define snd_hwdep_write snd_hwdep_write_dylibloader_orig_asound
+#define snd_hwdep_read snd_hwdep_read_dylibloader_orig_asound
+#define snd_hwdep_info_sizeof snd_hwdep_info_sizeof_dylibloader_orig_asound
+#define snd_hwdep_info_malloc snd_hwdep_info_malloc_dylibloader_orig_asound
+#define snd_hwdep_info_free snd_hwdep_info_free_dylibloader_orig_asound
+#define snd_hwdep_info_copy snd_hwdep_info_copy_dylibloader_orig_asound
+#define snd_hwdep_info_get_device snd_hwdep_info_get_device_dylibloader_orig_asound
+#define snd_hwdep_info_get_card snd_hwdep_info_get_card_dylibloader_orig_asound
+#define snd_hwdep_info_get_id snd_hwdep_info_get_id_dylibloader_orig_asound
+#define snd_hwdep_info_get_name snd_hwdep_info_get_name_dylibloader_orig_asound
+#define snd_hwdep_info_get_iface snd_hwdep_info_get_iface_dylibloader_orig_asound
+#define snd_hwdep_info_set_device snd_hwdep_info_set_device_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_sizeof snd_hwdep_dsp_status_sizeof_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_malloc snd_hwdep_dsp_status_malloc_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_free snd_hwdep_dsp_status_free_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_copy snd_hwdep_dsp_status_copy_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_version snd_hwdep_dsp_status_get_version_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_id snd_hwdep_dsp_status_get_id_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_num_dsps snd_hwdep_dsp_status_get_num_dsps_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_dsp_loaded snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_chip_ready snd_hwdep_dsp_status_get_chip_ready_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_sizeof snd_hwdep_dsp_image_sizeof_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_malloc snd_hwdep_dsp_image_malloc_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_free snd_hwdep_dsp_image_free_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_copy snd_hwdep_dsp_image_copy_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_get_index snd_hwdep_dsp_image_get_index_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_get_name snd_hwdep_dsp_image_get_name_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_get_image snd_hwdep_dsp_image_get_image_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_get_length snd_hwdep_dsp_image_get_length_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_set_index snd_hwdep_dsp_image_set_index_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_set_name snd_hwdep_dsp_image_set_name_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_set_image snd_hwdep_dsp_image_set_image_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_set_length snd_hwdep_dsp_image_set_length_dylibloader_orig_asound
+#define snd_card_load snd_card_load_dylibloader_orig_asound
+#define snd_card_next snd_card_next_dylibloader_orig_asound
+#define snd_card_get_index snd_card_get_index_dylibloader_orig_asound
+#define snd_card_get_name snd_card_get_name_dylibloader_orig_asound
+#define snd_card_get_longname snd_card_get_longname_dylibloader_orig_asound
+#define snd_device_name_hint snd_device_name_hint_dylibloader_orig_asound
+#define snd_device_name_free_hint snd_device_name_free_hint_dylibloader_orig_asound
+#define snd_device_name_get_hint snd_device_name_get_hint_dylibloader_orig_asound
+#define snd_ctl_open snd_ctl_open_dylibloader_orig_asound
+#define snd_ctl_open_lconf snd_ctl_open_lconf_dylibloader_orig_asound
+#define snd_ctl_open_fallback snd_ctl_open_fallback_dylibloader_orig_asound
+#define snd_ctl_close snd_ctl_close_dylibloader_orig_asound
+#define snd_ctl_nonblock snd_ctl_nonblock_dylibloader_orig_asound
+#define snd_async_add_ctl_handler snd_async_add_ctl_handler_dylibloader_orig_asound
+#define snd_async_handler_get_ctl snd_async_handler_get_ctl_dylibloader_orig_asound
+#define snd_ctl_poll_descriptors_count snd_ctl_poll_descriptors_count_dylibloader_orig_asound
+#define snd_ctl_poll_descriptors snd_ctl_poll_descriptors_dylibloader_orig_asound
+#define snd_ctl_poll_descriptors_revents snd_ctl_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_ctl_subscribe_events snd_ctl_subscribe_events_dylibloader_orig_asound
+#define snd_ctl_card_info snd_ctl_card_info_dylibloader_orig_asound
+#define snd_ctl_elem_list snd_ctl_elem_list_dylibloader_orig_asound
+#define snd_ctl_elem_info snd_ctl_elem_info_dylibloader_orig_asound
+#define snd_ctl_elem_read snd_ctl_elem_read_dylibloader_orig_asound
+#define snd_ctl_elem_write snd_ctl_elem_write_dylibloader_orig_asound
+#define snd_ctl_elem_lock snd_ctl_elem_lock_dylibloader_orig_asound
+#define snd_ctl_elem_unlock snd_ctl_elem_unlock_dylibloader_orig_asound
+#define snd_ctl_elem_tlv_read snd_ctl_elem_tlv_read_dylibloader_orig_asound
+#define snd_ctl_elem_tlv_write snd_ctl_elem_tlv_write_dylibloader_orig_asound
+#define snd_ctl_elem_tlv_command snd_ctl_elem_tlv_command_dylibloader_orig_asound
+#define snd_ctl_hwdep_next_device snd_ctl_hwdep_next_device_dylibloader_orig_asound
+#define snd_ctl_hwdep_info snd_ctl_hwdep_info_dylibloader_orig_asound
+#define snd_ctl_pcm_next_device snd_ctl_pcm_next_device_dylibloader_orig_asound
+#define snd_ctl_pcm_info snd_ctl_pcm_info_dylibloader_orig_asound
+#define snd_ctl_pcm_prefer_subdevice snd_ctl_pcm_prefer_subdevice_dylibloader_orig_asound
+#define snd_ctl_rawmidi_next_device snd_ctl_rawmidi_next_device_dylibloader_orig_asound
+#define snd_ctl_rawmidi_info snd_ctl_rawmidi_info_dylibloader_orig_asound
+#define snd_ctl_rawmidi_prefer_subdevice snd_ctl_rawmidi_prefer_subdevice_dylibloader_orig_asound
+#define snd_ctl_set_power_state snd_ctl_set_power_state_dylibloader_orig_asound
+#define snd_ctl_get_power_state snd_ctl_get_power_state_dylibloader_orig_asound
+#define snd_ctl_read snd_ctl_read_dylibloader_orig_asound
+#define snd_ctl_wait snd_ctl_wait_dylibloader_orig_asound
+#define snd_ctl_name snd_ctl_name_dylibloader_orig_asound
+#define snd_ctl_type snd_ctl_type_dylibloader_orig_asound
+#define snd_ctl_elem_type_name snd_ctl_elem_type_name_dylibloader_orig_asound
+#define snd_ctl_elem_iface_name snd_ctl_elem_iface_name_dylibloader_orig_asound
+#define snd_ctl_event_type_name snd_ctl_event_type_name_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_mask snd_ctl_event_elem_get_mask_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_numid snd_ctl_event_elem_get_numid_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_id snd_ctl_event_elem_get_id_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_interface snd_ctl_event_elem_get_interface_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_device snd_ctl_event_elem_get_device_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_subdevice snd_ctl_event_elem_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_name snd_ctl_event_elem_get_name_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_index snd_ctl_event_elem_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_list_alloc_space snd_ctl_elem_list_alloc_space_dylibloader_orig_asound
+#define snd_ctl_elem_list_free_space snd_ctl_elem_list_free_space_dylibloader_orig_asound
+#define snd_ctl_ascii_elem_id_get snd_ctl_ascii_elem_id_get_dylibloader_orig_asound
+#define snd_ctl_ascii_elem_id_parse snd_ctl_ascii_elem_id_parse_dylibloader_orig_asound
+#define snd_ctl_ascii_value_parse snd_ctl_ascii_value_parse_dylibloader_orig_asound
+#define snd_ctl_elem_id_sizeof snd_ctl_elem_id_sizeof_dylibloader_orig_asound
+#define snd_ctl_elem_id_malloc snd_ctl_elem_id_malloc_dylibloader_orig_asound
+#define snd_ctl_elem_id_free snd_ctl_elem_id_free_dylibloader_orig_asound
+#define snd_ctl_elem_id_clear snd_ctl_elem_id_clear_dylibloader_orig_asound
+#define snd_ctl_elem_id_copy snd_ctl_elem_id_copy_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_numid snd_ctl_elem_id_get_numid_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_interface snd_ctl_elem_id_get_interface_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_device snd_ctl_elem_id_get_device_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_subdevice snd_ctl_elem_id_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_name snd_ctl_elem_id_get_name_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_index snd_ctl_elem_id_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_numid snd_ctl_elem_id_set_numid_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_interface snd_ctl_elem_id_set_interface_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_device snd_ctl_elem_id_set_device_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_subdevice snd_ctl_elem_id_set_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_name snd_ctl_elem_id_set_name_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_index snd_ctl_elem_id_set_index_dylibloader_orig_asound
+#define snd_ctl_card_info_sizeof snd_ctl_card_info_sizeof_dylibloader_orig_asound
+#define snd_ctl_card_info_malloc snd_ctl_card_info_malloc_dylibloader_orig_asound
+#define snd_ctl_card_info_free snd_ctl_card_info_free_dylibloader_orig_asound
+#define snd_ctl_card_info_clear snd_ctl_card_info_clear_dylibloader_orig_asound
+#define snd_ctl_card_info_copy snd_ctl_card_info_copy_dylibloader_orig_asound
+#define snd_ctl_card_info_get_card snd_ctl_card_info_get_card_dylibloader_orig_asound
+#define snd_ctl_card_info_get_id snd_ctl_card_info_get_id_dylibloader_orig_asound
+#define snd_ctl_card_info_get_driver snd_ctl_card_info_get_driver_dylibloader_orig_asound
+#define snd_ctl_card_info_get_name snd_ctl_card_info_get_name_dylibloader_orig_asound
+#define snd_ctl_card_info_get_longname snd_ctl_card_info_get_longname_dylibloader_orig_asound
+#define snd_ctl_card_info_get_mixername snd_ctl_card_info_get_mixername_dylibloader_orig_asound
+#define snd_ctl_card_info_get_components snd_ctl_card_info_get_components_dylibloader_orig_asound
+#define snd_ctl_event_sizeof snd_ctl_event_sizeof_dylibloader_orig_asound
+#define snd_ctl_event_malloc snd_ctl_event_malloc_dylibloader_orig_asound
+#define snd_ctl_event_free snd_ctl_event_free_dylibloader_orig_asound
+#define snd_ctl_event_clear snd_ctl_event_clear_dylibloader_orig_asound
+#define snd_ctl_event_copy snd_ctl_event_copy_dylibloader_orig_asound
+#define snd_ctl_event_get_type snd_ctl_event_get_type_dylibloader_orig_asound
+#define snd_ctl_elem_list_sizeof snd_ctl_elem_list_sizeof_dylibloader_orig_asound
+#define snd_ctl_elem_list_malloc snd_ctl_elem_list_malloc_dylibloader_orig_asound
+#define snd_ctl_elem_list_free snd_ctl_elem_list_free_dylibloader_orig_asound
+#define snd_ctl_elem_list_clear snd_ctl_elem_list_clear_dylibloader_orig_asound
+#define snd_ctl_elem_list_copy snd_ctl_elem_list_copy_dylibloader_orig_asound
+#define snd_ctl_elem_list_set_offset snd_ctl_elem_list_set_offset_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_used snd_ctl_elem_list_get_used_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_count snd_ctl_elem_list_get_count_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_id snd_ctl_elem_list_get_id_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_numid snd_ctl_elem_list_get_numid_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_interface snd_ctl_elem_list_get_interface_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_device snd_ctl_elem_list_get_device_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_subdevice snd_ctl_elem_list_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_name snd_ctl_elem_list_get_name_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_index snd_ctl_elem_list_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_info_sizeof snd_ctl_elem_info_sizeof_dylibloader_orig_asound
+#define snd_ctl_elem_info_malloc snd_ctl_elem_info_malloc_dylibloader_orig_asound
+#define snd_ctl_elem_info_free snd_ctl_elem_info_free_dylibloader_orig_asound
+#define snd_ctl_elem_info_clear snd_ctl_elem_info_clear_dylibloader_orig_asound
+#define snd_ctl_elem_info_copy snd_ctl_elem_info_copy_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_type snd_ctl_elem_info_get_type_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_readable snd_ctl_elem_info_is_readable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_writable snd_ctl_elem_info_is_writable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_volatile snd_ctl_elem_info_is_volatile_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_inactive snd_ctl_elem_info_is_inactive_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_locked snd_ctl_elem_info_is_locked_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_tlv_readable snd_ctl_elem_info_is_tlv_readable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_tlv_writable snd_ctl_elem_info_is_tlv_writable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_tlv_commandable snd_ctl_elem_info_is_tlv_commandable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_owner snd_ctl_elem_info_is_owner_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_user snd_ctl_elem_info_is_user_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_owner snd_ctl_elem_info_get_owner_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_count snd_ctl_elem_info_get_count_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_min snd_ctl_elem_info_get_min_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_max snd_ctl_elem_info_get_max_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_step snd_ctl_elem_info_get_step_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_min64 snd_ctl_elem_info_get_min64_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_max64 snd_ctl_elem_info_get_max64_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_step64 snd_ctl_elem_info_get_step64_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_items snd_ctl_elem_info_get_items_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_item snd_ctl_elem_info_set_item_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_item_name snd_ctl_elem_info_get_item_name_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_dimensions snd_ctl_elem_info_get_dimensions_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_dimension snd_ctl_elem_info_get_dimension_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_dimension snd_ctl_elem_info_set_dimension_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_id snd_ctl_elem_info_get_id_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_numid snd_ctl_elem_info_get_numid_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_interface snd_ctl_elem_info_get_interface_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_device snd_ctl_elem_info_get_device_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_subdevice snd_ctl_elem_info_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_name snd_ctl_elem_info_get_name_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_index snd_ctl_elem_info_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_id snd_ctl_elem_info_set_id_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_numid snd_ctl_elem_info_set_numid_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_interface snd_ctl_elem_info_set_interface_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_device snd_ctl_elem_info_set_device_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_subdevice snd_ctl_elem_info_set_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_name snd_ctl_elem_info_set_name_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_index snd_ctl_elem_info_set_index_dylibloader_orig_asound
+#define snd_ctl_add_integer_elem_set snd_ctl_add_integer_elem_set_dylibloader_orig_asound
+#define snd_ctl_add_integer64_elem_set snd_ctl_add_integer64_elem_set_dylibloader_orig_asound
+#define snd_ctl_add_boolean_elem_set snd_ctl_add_boolean_elem_set_dylibloader_orig_asound
+#define snd_ctl_add_enumerated_elem_set snd_ctl_add_enumerated_elem_set_dylibloader_orig_asound
+#define snd_ctl_add_bytes_elem_set snd_ctl_add_bytes_elem_set_dylibloader_orig_asound
+#define snd_ctl_elem_add_integer snd_ctl_elem_add_integer_dylibloader_orig_asound
+#define snd_ctl_elem_add_integer64 snd_ctl_elem_add_integer64_dylibloader_orig_asound
+#define snd_ctl_elem_add_boolean snd_ctl_elem_add_boolean_dylibloader_orig_asound
+#define snd_ctl_elem_add_enumerated snd_ctl_elem_add_enumerated_dylibloader_orig_asound
+#define snd_ctl_elem_add_iec958 snd_ctl_elem_add_iec958_dylibloader_orig_asound
+#define snd_ctl_elem_remove snd_ctl_elem_remove_dylibloader_orig_asound
+#define snd_ctl_elem_value_sizeof snd_ctl_elem_value_sizeof_dylibloader_orig_asound
+#define snd_ctl_elem_value_malloc snd_ctl_elem_value_malloc_dylibloader_orig_asound
+#define snd_ctl_elem_value_free snd_ctl_elem_value_free_dylibloader_orig_asound
+#define snd_ctl_elem_value_clear snd_ctl_elem_value_clear_dylibloader_orig_asound
+#define snd_ctl_elem_value_copy snd_ctl_elem_value_copy_dylibloader_orig_asound
+#define snd_ctl_elem_value_compare snd_ctl_elem_value_compare_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_id snd_ctl_elem_value_get_id_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_numid snd_ctl_elem_value_get_numid_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_interface snd_ctl_elem_value_get_interface_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_device snd_ctl_elem_value_get_device_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_subdevice snd_ctl_elem_value_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_name snd_ctl_elem_value_get_name_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_index snd_ctl_elem_value_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_id snd_ctl_elem_value_set_id_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_numid snd_ctl_elem_value_set_numid_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_interface snd_ctl_elem_value_set_interface_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_device snd_ctl_elem_value_set_device_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_subdevice snd_ctl_elem_value_set_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_name snd_ctl_elem_value_set_name_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_index snd_ctl_elem_value_set_index_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_boolean snd_ctl_elem_value_get_boolean_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_integer snd_ctl_elem_value_get_integer_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_integer64 snd_ctl_elem_value_get_integer64_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_enumerated snd_ctl_elem_value_get_enumerated_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_byte snd_ctl_elem_value_get_byte_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_boolean snd_ctl_elem_value_set_boolean_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_integer snd_ctl_elem_value_set_integer_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_integer64 snd_ctl_elem_value_set_integer64_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_enumerated snd_ctl_elem_value_set_enumerated_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_byte snd_ctl_elem_value_set_byte_dylibloader_orig_asound
+#define snd_ctl_elem_set_bytes snd_ctl_elem_set_bytes_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_bytes snd_ctl_elem_value_get_bytes_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_iec958 snd_ctl_elem_value_get_iec958_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_iec958 snd_ctl_elem_value_set_iec958_dylibloader_orig_asound
+#define snd_tlv_parse_dB_info snd_tlv_parse_dB_info_dylibloader_orig_asound
+#define snd_tlv_get_dB_range snd_tlv_get_dB_range_dylibloader_orig_asound
+#define snd_tlv_convert_to_dB snd_tlv_convert_to_dB_dylibloader_orig_asound
+#define snd_tlv_convert_from_dB snd_tlv_convert_from_dB_dylibloader_orig_asound
+#define snd_ctl_get_dB_range snd_ctl_get_dB_range_dylibloader_orig_asound
+#define snd_ctl_convert_to_dB snd_ctl_convert_to_dB_dylibloader_orig_asound
+#define snd_ctl_convert_from_dB snd_ctl_convert_from_dB_dylibloader_orig_asound
+#define snd_hctl_compare_fast snd_hctl_compare_fast_dylibloader_orig_asound
+#define snd_hctl_open snd_hctl_open_dylibloader_orig_asound
+#define snd_hctl_open_ctl snd_hctl_open_ctl_dylibloader_orig_asound
+#define snd_hctl_close snd_hctl_close_dylibloader_orig_asound
+#define snd_hctl_nonblock snd_hctl_nonblock_dylibloader_orig_asound
+#define snd_hctl_poll_descriptors_count snd_hctl_poll_descriptors_count_dylibloader_orig_asound
+#define snd_hctl_poll_descriptors snd_hctl_poll_descriptors_dylibloader_orig_asound
+#define snd_hctl_poll_descriptors_revents snd_hctl_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_hctl_get_count snd_hctl_get_count_dylibloader_orig_asound
+#define snd_hctl_set_compare snd_hctl_set_compare_dylibloader_orig_asound
+#define snd_hctl_first_elem snd_hctl_first_elem_dylibloader_orig_asound
+#define snd_hctl_last_elem snd_hctl_last_elem_dylibloader_orig_asound
+#define snd_hctl_find_elem snd_hctl_find_elem_dylibloader_orig_asound
+#define snd_hctl_set_callback snd_hctl_set_callback_dylibloader_orig_asound
+#define snd_hctl_set_callback_private snd_hctl_set_callback_private_dylibloader_orig_asound
+#define snd_hctl_get_callback_private snd_hctl_get_callback_private_dylibloader_orig_asound
+#define snd_hctl_load snd_hctl_load_dylibloader_orig_asound
+#define snd_hctl_free snd_hctl_free_dylibloader_orig_asound
+#define snd_hctl_handle_events snd_hctl_handle_events_dylibloader_orig_asound
+#define snd_hctl_name snd_hctl_name_dylibloader_orig_asound
+#define snd_hctl_wait snd_hctl_wait_dylibloader_orig_asound
+#define snd_hctl_ctl snd_hctl_ctl_dylibloader_orig_asound
+#define snd_hctl_elem_next snd_hctl_elem_next_dylibloader_orig_asound
+#define snd_hctl_elem_prev snd_hctl_elem_prev_dylibloader_orig_asound
+#define snd_hctl_elem_info snd_hctl_elem_info_dylibloader_orig_asound
+#define snd_hctl_elem_read snd_hctl_elem_read_dylibloader_orig_asound
+#define snd_hctl_elem_write snd_hctl_elem_write_dylibloader_orig_asound
+#define snd_hctl_elem_tlv_read snd_hctl_elem_tlv_read_dylibloader_orig_asound
+#define snd_hctl_elem_tlv_write snd_hctl_elem_tlv_write_dylibloader_orig_asound
+#define snd_hctl_elem_tlv_command snd_hctl_elem_tlv_command_dylibloader_orig_asound
+#define snd_hctl_elem_get_hctl snd_hctl_elem_get_hctl_dylibloader_orig_asound
+#define snd_hctl_elem_get_id snd_hctl_elem_get_id_dylibloader_orig_asound
+#define snd_hctl_elem_get_numid snd_hctl_elem_get_numid_dylibloader_orig_asound
+#define snd_hctl_elem_get_interface snd_hctl_elem_get_interface_dylibloader_orig_asound
+#define snd_hctl_elem_get_device snd_hctl_elem_get_device_dylibloader_orig_asound
+#define snd_hctl_elem_get_subdevice snd_hctl_elem_get_subdevice_dylibloader_orig_asound
+#define snd_hctl_elem_get_name snd_hctl_elem_get_name_dylibloader_orig_asound
+#define snd_hctl_elem_get_index snd_hctl_elem_get_index_dylibloader_orig_asound
+#define snd_hctl_elem_set_callback snd_hctl_elem_set_callback_dylibloader_orig_asound
+#define snd_hctl_elem_get_callback_private snd_hctl_elem_get_callback_private_dylibloader_orig_asound
+#define snd_hctl_elem_set_callback_private snd_hctl_elem_set_callback_private_dylibloader_orig_asound
+#define snd_sctl_build snd_sctl_build_dylibloader_orig_asound
+#define snd_sctl_free snd_sctl_free_dylibloader_orig_asound
+#define snd_sctl_install snd_sctl_install_dylibloader_orig_asound
+#define snd_sctl_remove snd_sctl_remove_dylibloader_orig_asound
+#define snd_mixer_open snd_mixer_open_dylibloader_orig_asound
+#define snd_mixer_close snd_mixer_close_dylibloader_orig_asound
+#define snd_mixer_first_elem snd_mixer_first_elem_dylibloader_orig_asound
+#define snd_mixer_last_elem snd_mixer_last_elem_dylibloader_orig_asound
+#define snd_mixer_handle_events snd_mixer_handle_events_dylibloader_orig_asound
+#define snd_mixer_attach snd_mixer_attach_dylibloader_orig_asound
+#define snd_mixer_attach_hctl snd_mixer_attach_hctl_dylibloader_orig_asound
+#define snd_mixer_detach snd_mixer_detach_dylibloader_orig_asound
+#define snd_mixer_detach_hctl snd_mixer_detach_hctl_dylibloader_orig_asound
+#define snd_mixer_get_hctl snd_mixer_get_hctl_dylibloader_orig_asound
+#define snd_mixer_poll_descriptors_count snd_mixer_poll_descriptors_count_dylibloader_orig_asound
+#define snd_mixer_poll_descriptors snd_mixer_poll_descriptors_dylibloader_orig_asound
+#define snd_mixer_poll_descriptors_revents snd_mixer_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_mixer_load snd_mixer_load_dylibloader_orig_asound
+#define snd_mixer_free snd_mixer_free_dylibloader_orig_asound
+#define snd_mixer_wait snd_mixer_wait_dylibloader_orig_asound
+#define snd_mixer_set_compare snd_mixer_set_compare_dylibloader_orig_asound
+#define snd_mixer_set_callback snd_mixer_set_callback_dylibloader_orig_asound
+#define snd_mixer_get_callback_private snd_mixer_get_callback_private_dylibloader_orig_asound
+#define snd_mixer_set_callback_private snd_mixer_set_callback_private_dylibloader_orig_asound
+#define snd_mixer_get_count snd_mixer_get_count_dylibloader_orig_asound
+#define snd_mixer_class_unregister snd_mixer_class_unregister_dylibloader_orig_asound
+#define snd_mixer_elem_next snd_mixer_elem_next_dylibloader_orig_asound
+#define snd_mixer_elem_prev snd_mixer_elem_prev_dylibloader_orig_asound
+#define snd_mixer_elem_set_callback snd_mixer_elem_set_callback_dylibloader_orig_asound
+#define snd_mixer_elem_get_callback_private snd_mixer_elem_get_callback_private_dylibloader_orig_asound
+#define snd_mixer_elem_set_callback_private snd_mixer_elem_set_callback_private_dylibloader_orig_asound
+#define snd_mixer_elem_get_type snd_mixer_elem_get_type_dylibloader_orig_asound
+#define snd_mixer_class_register snd_mixer_class_register_dylibloader_orig_asound
+#define snd_mixer_elem_new snd_mixer_elem_new_dylibloader_orig_asound
+#define snd_mixer_elem_add snd_mixer_elem_add_dylibloader_orig_asound
+#define snd_mixer_elem_remove snd_mixer_elem_remove_dylibloader_orig_asound
+#define snd_mixer_elem_free snd_mixer_elem_free_dylibloader_orig_asound
+#define snd_mixer_elem_info snd_mixer_elem_info_dylibloader_orig_asound
+#define snd_mixer_elem_value snd_mixer_elem_value_dylibloader_orig_asound
+#define snd_mixer_elem_attach snd_mixer_elem_attach_dylibloader_orig_asound
+#define snd_mixer_elem_detach snd_mixer_elem_detach_dylibloader_orig_asound
+#define snd_mixer_elem_empty snd_mixer_elem_empty_dylibloader_orig_asound
+#define snd_mixer_elem_get_private snd_mixer_elem_get_private_dylibloader_orig_asound
+#define snd_mixer_class_sizeof snd_mixer_class_sizeof_dylibloader_orig_asound
+#define snd_mixer_class_malloc snd_mixer_class_malloc_dylibloader_orig_asound
+#define snd_mixer_class_free snd_mixer_class_free_dylibloader_orig_asound
+#define snd_mixer_class_copy snd_mixer_class_copy_dylibloader_orig_asound
+#define snd_mixer_class_get_mixer snd_mixer_class_get_mixer_dylibloader_orig_asound
+#define snd_mixer_class_get_event snd_mixer_class_get_event_dylibloader_orig_asound
+#define snd_mixer_class_get_private snd_mixer_class_get_private_dylibloader_orig_asound
+#define snd_mixer_class_get_compare snd_mixer_class_get_compare_dylibloader_orig_asound
+#define snd_mixer_class_set_event snd_mixer_class_set_event_dylibloader_orig_asound
+#define snd_mixer_class_set_private snd_mixer_class_set_private_dylibloader_orig_asound
+#define snd_mixer_class_set_private_free snd_mixer_class_set_private_free_dylibloader_orig_asound
+#define snd_mixer_class_set_compare snd_mixer_class_set_compare_dylibloader_orig_asound
+#define snd_mixer_selem_channel_name snd_mixer_selem_channel_name_dylibloader_orig_asound
+#define snd_mixer_selem_register snd_mixer_selem_register_dylibloader_orig_asound
+#define snd_mixer_selem_get_id snd_mixer_selem_get_id_dylibloader_orig_asound
+#define snd_mixer_selem_get_name snd_mixer_selem_get_name_dylibloader_orig_asound
+#define snd_mixer_selem_get_index snd_mixer_selem_get_index_dylibloader_orig_asound
+#define snd_mixer_find_selem snd_mixer_find_selem_dylibloader_orig_asound
+#define snd_mixer_selem_is_active snd_mixer_selem_is_active_dylibloader_orig_asound
+#define snd_mixer_selem_is_playback_mono snd_mixer_selem_is_playback_mono_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_channel snd_mixer_selem_has_playback_channel_dylibloader_orig_asound
+#define snd_mixer_selem_is_capture_mono snd_mixer_selem_is_capture_mono_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_channel snd_mixer_selem_has_capture_channel_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_group snd_mixer_selem_get_capture_group_dylibloader_orig_asound
+#define snd_mixer_selem_has_common_volume snd_mixer_selem_has_common_volume_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_volume snd_mixer_selem_has_playback_volume_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_volume_joined snd_mixer_selem_has_playback_volume_joined_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_volume snd_mixer_selem_has_capture_volume_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_volume_joined snd_mixer_selem_has_capture_volume_joined_dylibloader_orig_asound
+#define snd_mixer_selem_has_common_switch snd_mixer_selem_has_common_switch_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_switch snd_mixer_selem_has_playback_switch_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_switch_joined snd_mixer_selem_has_playback_switch_joined_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_switch snd_mixer_selem_has_capture_switch_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_switch_joined snd_mixer_selem_has_capture_switch_joined_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_switch_exclusive snd_mixer_selem_has_capture_switch_exclusive_dylibloader_orig_asound
+#define snd_mixer_selem_ask_playback_vol_dB snd_mixer_selem_ask_playback_vol_dB_dylibloader_orig_asound
+#define snd_mixer_selem_ask_capture_vol_dB snd_mixer_selem_ask_capture_vol_dB_dylibloader_orig_asound
+#define snd_mixer_selem_ask_playback_dB_vol snd_mixer_selem_ask_playback_dB_vol_dylibloader_orig_asound
+#define snd_mixer_selem_ask_capture_dB_vol snd_mixer_selem_ask_capture_dB_vol_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_volume snd_mixer_selem_get_playback_volume_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_volume snd_mixer_selem_get_capture_volume_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_dB snd_mixer_selem_get_playback_dB_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_dB snd_mixer_selem_get_capture_dB_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_switch snd_mixer_selem_get_playback_switch_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_switch snd_mixer_selem_get_capture_switch_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_volume snd_mixer_selem_set_playback_volume_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_volume snd_mixer_selem_set_capture_volume_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_dB snd_mixer_selem_set_playback_dB_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_dB snd_mixer_selem_set_capture_dB_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_volume_all snd_mixer_selem_set_playback_volume_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_volume_all snd_mixer_selem_set_capture_volume_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_dB_all snd_mixer_selem_set_playback_dB_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_dB_all snd_mixer_selem_set_capture_dB_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_switch snd_mixer_selem_set_playback_switch_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_switch snd_mixer_selem_set_capture_switch_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_switch_all snd_mixer_selem_set_playback_switch_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_switch_all snd_mixer_selem_set_capture_switch_all_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_volume_range snd_mixer_selem_get_playback_volume_range_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_dB_range snd_mixer_selem_get_playback_dB_range_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_volume_range snd_mixer_selem_set_playback_volume_range_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_volume_range snd_mixer_selem_get_capture_volume_range_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_dB_range snd_mixer_selem_get_capture_dB_range_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_volume_range snd_mixer_selem_set_capture_volume_range_dylibloader_orig_asound
+#define snd_mixer_selem_is_enumerated snd_mixer_selem_is_enumerated_dylibloader_orig_asound
+#define snd_mixer_selem_is_enum_playback snd_mixer_selem_is_enum_playback_dylibloader_orig_asound
+#define snd_mixer_selem_is_enum_capture snd_mixer_selem_is_enum_capture_dylibloader_orig_asound
+#define snd_mixer_selem_get_enum_items snd_mixer_selem_get_enum_items_dylibloader_orig_asound
+#define snd_mixer_selem_get_enum_item_name snd_mixer_selem_get_enum_item_name_dylibloader_orig_asound
+#define snd_mixer_selem_get_enum_item snd_mixer_selem_get_enum_item_dylibloader_orig_asound
+#define snd_mixer_selem_set_enum_item snd_mixer_selem_set_enum_item_dylibloader_orig_asound
+#define snd_mixer_selem_id_sizeof snd_mixer_selem_id_sizeof_dylibloader_orig_asound
+#define snd_mixer_selem_id_malloc snd_mixer_selem_id_malloc_dylibloader_orig_asound
+#define snd_mixer_selem_id_free snd_mixer_selem_id_free_dylibloader_orig_asound
+#define snd_mixer_selem_id_copy snd_mixer_selem_id_copy_dylibloader_orig_asound
+#define snd_mixer_selem_id_get_name snd_mixer_selem_id_get_name_dylibloader_orig_asound
+#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_orig_asound
+#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_orig_asound
+#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_orig_asound
+#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_orig_asound
+#define snd_seq_open snd_seq_open_dylibloader_orig_asound
+#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_orig_asound
+#define snd_seq_name snd_seq_name_dylibloader_orig_asound
+#define snd_seq_type snd_seq_type_dylibloader_orig_asound
+#define snd_seq_close snd_seq_close_dylibloader_orig_asound
+#define snd_seq_poll_descriptors_count snd_seq_poll_descriptors_count_dylibloader_orig_asound
+#define snd_seq_poll_descriptors snd_seq_poll_descriptors_dylibloader_orig_asound
+#define snd_seq_poll_descriptors_revents snd_seq_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_seq_nonblock snd_seq_nonblock_dylibloader_orig_asound
+#define snd_seq_client_id snd_seq_client_id_dylibloader_orig_asound
+#define snd_seq_get_output_buffer_size snd_seq_get_output_buffer_size_dylibloader_orig_asound
+#define snd_seq_get_input_buffer_size snd_seq_get_input_buffer_size_dylibloader_orig_asound
+#define snd_seq_set_output_buffer_size snd_seq_set_output_buffer_size_dylibloader_orig_asound
+#define snd_seq_set_input_buffer_size snd_seq_set_input_buffer_size_dylibloader_orig_asound
+#define snd_seq_system_info_sizeof snd_seq_system_info_sizeof_dylibloader_orig_asound
+#define snd_seq_system_info_malloc snd_seq_system_info_malloc_dylibloader_orig_asound
+#define snd_seq_system_info_free snd_seq_system_info_free_dylibloader_orig_asound
+#define snd_seq_system_info_copy snd_seq_system_info_copy_dylibloader_orig_asound
+#define snd_seq_system_info_get_queues snd_seq_system_info_get_queues_dylibloader_orig_asound
+#define snd_seq_system_info_get_clients snd_seq_system_info_get_clients_dylibloader_orig_asound
+#define snd_seq_system_info_get_ports snd_seq_system_info_get_ports_dylibloader_orig_asound
+#define snd_seq_system_info_get_channels snd_seq_system_info_get_channels_dylibloader_orig_asound
+#define snd_seq_system_info_get_cur_clients snd_seq_system_info_get_cur_clients_dylibloader_orig_asound
+#define snd_seq_system_info_get_cur_queues snd_seq_system_info_get_cur_queues_dylibloader_orig_asound
+#define snd_seq_system_info snd_seq_system_info_dylibloader_orig_asound
+#define snd_seq_client_info_sizeof snd_seq_client_info_sizeof_dylibloader_orig_asound
+#define snd_seq_client_info_malloc snd_seq_client_info_malloc_dylibloader_orig_asound
+#define snd_seq_client_info_free snd_seq_client_info_free_dylibloader_orig_asound
+#define snd_seq_client_info_copy snd_seq_client_info_copy_dylibloader_orig_asound
+#define snd_seq_client_info_get_client snd_seq_client_info_get_client_dylibloader_orig_asound
+#define snd_seq_client_info_get_type snd_seq_client_info_get_type_dylibloader_orig_asound
+#define snd_seq_client_info_get_name snd_seq_client_info_get_name_dylibloader_orig_asound
+#define snd_seq_client_info_get_broadcast_filter snd_seq_client_info_get_broadcast_filter_dylibloader_orig_asound
+#define snd_seq_client_info_get_error_bounce snd_seq_client_info_get_error_bounce_dylibloader_orig_asound
+#define snd_seq_client_info_get_card snd_seq_client_info_get_card_dylibloader_orig_asound
+#define snd_seq_client_info_get_pid snd_seq_client_info_get_pid_dylibloader_orig_asound
+#define snd_seq_client_info_get_event_filter snd_seq_client_info_get_event_filter_dylibloader_orig_asound
+#define snd_seq_client_info_get_num_ports snd_seq_client_info_get_num_ports_dylibloader_orig_asound
+#define snd_seq_client_info_get_event_lost snd_seq_client_info_get_event_lost_dylibloader_orig_asound
+#define snd_seq_client_info_set_client snd_seq_client_info_set_client_dylibloader_orig_asound
+#define snd_seq_client_info_set_name snd_seq_client_info_set_name_dylibloader_orig_asound
+#define snd_seq_client_info_set_broadcast_filter snd_seq_client_info_set_broadcast_filter_dylibloader_orig_asound
+#define snd_seq_client_info_set_error_bounce snd_seq_client_info_set_error_bounce_dylibloader_orig_asound
+#define snd_seq_client_info_set_event_filter snd_seq_client_info_set_event_filter_dylibloader_orig_asound
+#define snd_seq_client_info_event_filter_clear snd_seq_client_info_event_filter_clear_dylibloader_orig_asound
+#define snd_seq_client_info_event_filter_add snd_seq_client_info_event_filter_add_dylibloader_orig_asound
+#define snd_seq_client_info_event_filter_del snd_seq_client_info_event_filter_del_dylibloader_orig_asound
+#define snd_seq_client_info_event_filter_check snd_seq_client_info_event_filter_check_dylibloader_orig_asound
+#define snd_seq_get_client_info snd_seq_get_client_info_dylibloader_orig_asound
+#define snd_seq_get_any_client_info snd_seq_get_any_client_info_dylibloader_orig_asound
+#define snd_seq_set_client_info snd_seq_set_client_info_dylibloader_orig_asound
+#define snd_seq_query_next_client snd_seq_query_next_client_dylibloader_orig_asound
+#define snd_seq_client_pool_sizeof snd_seq_client_pool_sizeof_dylibloader_orig_asound
+#define snd_seq_client_pool_malloc snd_seq_client_pool_malloc_dylibloader_orig_asound
+#define snd_seq_client_pool_free snd_seq_client_pool_free_dylibloader_orig_asound
+#define snd_seq_client_pool_copy snd_seq_client_pool_copy_dylibloader_orig_asound
+#define snd_seq_client_pool_get_client snd_seq_client_pool_get_client_dylibloader_orig_asound
+#define snd_seq_client_pool_get_output_pool snd_seq_client_pool_get_output_pool_dylibloader_orig_asound
+#define snd_seq_client_pool_get_input_pool snd_seq_client_pool_get_input_pool_dylibloader_orig_asound
+#define snd_seq_client_pool_get_output_room snd_seq_client_pool_get_output_room_dylibloader_orig_asound
+#define snd_seq_client_pool_get_output_free snd_seq_client_pool_get_output_free_dylibloader_orig_asound
+#define snd_seq_client_pool_get_input_free snd_seq_client_pool_get_input_free_dylibloader_orig_asound
+#define snd_seq_client_pool_set_output_pool snd_seq_client_pool_set_output_pool_dylibloader_orig_asound
+#define snd_seq_client_pool_set_input_pool snd_seq_client_pool_set_input_pool_dylibloader_orig_asound
+#define snd_seq_client_pool_set_output_room snd_seq_client_pool_set_output_room_dylibloader_orig_asound
+#define snd_seq_get_client_pool snd_seq_get_client_pool_dylibloader_orig_asound
+#define snd_seq_set_client_pool snd_seq_set_client_pool_dylibloader_orig_asound
+#define snd_seq_port_info_sizeof snd_seq_port_info_sizeof_dylibloader_orig_asound
+#define snd_seq_port_info_malloc snd_seq_port_info_malloc_dylibloader_orig_asound
+#define snd_seq_port_info_free snd_seq_port_info_free_dylibloader_orig_asound
+#define snd_seq_port_info_copy snd_seq_port_info_copy_dylibloader_orig_asound
+#define snd_seq_port_info_get_client snd_seq_port_info_get_client_dylibloader_orig_asound
+#define snd_seq_port_info_get_port snd_seq_port_info_get_port_dylibloader_orig_asound
+#define snd_seq_port_info_get_addr snd_seq_port_info_get_addr_dylibloader_orig_asound
+#define snd_seq_port_info_get_name snd_seq_port_info_get_name_dylibloader_orig_asound
+#define snd_seq_port_info_get_capability snd_seq_port_info_get_capability_dylibloader_orig_asound
+#define snd_seq_port_info_get_type snd_seq_port_info_get_type_dylibloader_orig_asound
+#define snd_seq_port_info_get_midi_channels snd_seq_port_info_get_midi_channels_dylibloader_orig_asound
+#define snd_seq_port_info_get_midi_voices snd_seq_port_info_get_midi_voices_dylibloader_orig_asound
+#define snd_seq_port_info_get_synth_voices snd_seq_port_info_get_synth_voices_dylibloader_orig_asound
+#define snd_seq_port_info_get_read_use snd_seq_port_info_get_read_use_dylibloader_orig_asound
+#define snd_seq_port_info_get_write_use snd_seq_port_info_get_write_use_dylibloader_orig_asound
+#define snd_seq_port_info_get_port_specified snd_seq_port_info_get_port_specified_dylibloader_orig_asound
+#define snd_seq_port_info_get_timestamping snd_seq_port_info_get_timestamping_dylibloader_orig_asound
+#define snd_seq_port_info_get_timestamp_real snd_seq_port_info_get_timestamp_real_dylibloader_orig_asound
+#define snd_seq_port_info_get_timestamp_queue snd_seq_port_info_get_timestamp_queue_dylibloader_orig_asound
+#define snd_seq_port_info_set_client snd_seq_port_info_set_client_dylibloader_orig_asound
+#define snd_seq_port_info_set_port snd_seq_port_info_set_port_dylibloader_orig_asound
+#define snd_seq_port_info_set_addr snd_seq_port_info_set_addr_dylibloader_orig_asound
+#define snd_seq_port_info_set_name snd_seq_port_info_set_name_dylibloader_orig_asound
+#define snd_seq_port_info_set_capability snd_seq_port_info_set_capability_dylibloader_orig_asound
+#define snd_seq_port_info_set_type snd_seq_port_info_set_type_dylibloader_orig_asound
+#define snd_seq_port_info_set_midi_channels snd_seq_port_info_set_midi_channels_dylibloader_orig_asound
+#define snd_seq_port_info_set_midi_voices snd_seq_port_info_set_midi_voices_dylibloader_orig_asound
+#define snd_seq_port_info_set_synth_voices snd_seq_port_info_set_synth_voices_dylibloader_orig_asound
+#define snd_seq_port_info_set_port_specified snd_seq_port_info_set_port_specified_dylibloader_orig_asound
+#define snd_seq_port_info_set_timestamping snd_seq_port_info_set_timestamping_dylibloader_orig_asound
+#define snd_seq_port_info_set_timestamp_real snd_seq_port_info_set_timestamp_real_dylibloader_orig_asound
+#define snd_seq_port_info_set_timestamp_queue snd_seq_port_info_set_timestamp_queue_dylibloader_orig_asound
+#define snd_seq_create_port snd_seq_create_port_dylibloader_orig_asound
+#define snd_seq_delete_port snd_seq_delete_port_dylibloader_orig_asound
+#define snd_seq_get_port_info snd_seq_get_port_info_dylibloader_orig_asound
+#define snd_seq_get_any_port_info snd_seq_get_any_port_info_dylibloader_orig_asound
+#define snd_seq_set_port_info snd_seq_set_port_info_dylibloader_orig_asound
+#define snd_seq_query_next_port snd_seq_query_next_port_dylibloader_orig_asound
+#define snd_seq_port_subscribe_sizeof snd_seq_port_subscribe_sizeof_dylibloader_orig_asound
+#define snd_seq_port_subscribe_malloc snd_seq_port_subscribe_malloc_dylibloader_orig_asound
+#define snd_seq_port_subscribe_free snd_seq_port_subscribe_free_dylibloader_orig_asound
+#define snd_seq_port_subscribe_copy snd_seq_port_subscribe_copy_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_sender snd_seq_port_subscribe_get_sender_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_dest snd_seq_port_subscribe_get_dest_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_queue snd_seq_port_subscribe_get_queue_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_exclusive snd_seq_port_subscribe_get_exclusive_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_time_update snd_seq_port_subscribe_get_time_update_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_time_real snd_seq_port_subscribe_get_time_real_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_sender snd_seq_port_subscribe_set_sender_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_dest snd_seq_port_subscribe_set_dest_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_queue snd_seq_port_subscribe_set_queue_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_exclusive snd_seq_port_subscribe_set_exclusive_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_time_update snd_seq_port_subscribe_set_time_update_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_time_real snd_seq_port_subscribe_set_time_real_dylibloader_orig_asound
+#define snd_seq_get_port_subscription snd_seq_get_port_subscription_dylibloader_orig_asound
+#define snd_seq_subscribe_port snd_seq_subscribe_port_dylibloader_orig_asound
+#define snd_seq_unsubscribe_port snd_seq_unsubscribe_port_dylibloader_orig_asound
+#define snd_seq_query_subscribe_sizeof snd_seq_query_subscribe_sizeof_dylibloader_orig_asound
+#define snd_seq_query_subscribe_malloc snd_seq_query_subscribe_malloc_dylibloader_orig_asound
+#define snd_seq_query_subscribe_free snd_seq_query_subscribe_free_dylibloader_orig_asound
+#define snd_seq_query_subscribe_copy snd_seq_query_subscribe_copy_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_client snd_seq_query_subscribe_get_client_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_port snd_seq_query_subscribe_get_port_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_root snd_seq_query_subscribe_get_root_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_type snd_seq_query_subscribe_get_type_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_index snd_seq_query_subscribe_get_index_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_num_subs snd_seq_query_subscribe_get_num_subs_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_addr snd_seq_query_subscribe_get_addr_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_queue snd_seq_query_subscribe_get_queue_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_exclusive snd_seq_query_subscribe_get_exclusive_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_time_update snd_seq_query_subscribe_get_time_update_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_time_real snd_seq_query_subscribe_get_time_real_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_client snd_seq_query_subscribe_set_client_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_port snd_seq_query_subscribe_set_port_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_root snd_seq_query_subscribe_set_root_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_type snd_seq_query_subscribe_set_type_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_index snd_seq_query_subscribe_set_index_dylibloader_orig_asound
+#define snd_seq_query_port_subscribers snd_seq_query_port_subscribers_dylibloader_orig_asound
+#define snd_seq_queue_info_sizeof snd_seq_queue_info_sizeof_dylibloader_orig_asound
+#define snd_seq_queue_info_malloc snd_seq_queue_info_malloc_dylibloader_orig_asound
+#define snd_seq_queue_info_free snd_seq_queue_info_free_dylibloader_orig_asound
+#define snd_seq_queue_info_copy snd_seq_queue_info_copy_dylibloader_orig_asound
+#define snd_seq_queue_info_get_queue snd_seq_queue_info_get_queue_dylibloader_orig_asound
+#define snd_seq_queue_info_get_name snd_seq_queue_info_get_name_dylibloader_orig_asound
+#define snd_seq_queue_info_get_owner snd_seq_queue_info_get_owner_dylibloader_orig_asound
+#define snd_seq_queue_info_get_locked snd_seq_queue_info_get_locked_dylibloader_orig_asound
+#define snd_seq_queue_info_get_flags snd_seq_queue_info_get_flags_dylibloader_orig_asound
+#define snd_seq_queue_info_set_name snd_seq_queue_info_set_name_dylibloader_orig_asound
+#define snd_seq_queue_info_set_owner snd_seq_queue_info_set_owner_dylibloader_orig_asound
+#define snd_seq_queue_info_set_locked snd_seq_queue_info_set_locked_dylibloader_orig_asound
+#define snd_seq_queue_info_set_flags snd_seq_queue_info_set_flags_dylibloader_orig_asound
+#define snd_seq_create_queue snd_seq_create_queue_dylibloader_orig_asound
+#define snd_seq_alloc_named_queue snd_seq_alloc_named_queue_dylibloader_orig_asound
+#define snd_seq_alloc_queue snd_seq_alloc_queue_dylibloader_orig_asound
+#define snd_seq_free_queue snd_seq_free_queue_dylibloader_orig_asound
+#define snd_seq_get_queue_info snd_seq_get_queue_info_dylibloader_orig_asound
+#define snd_seq_set_queue_info snd_seq_set_queue_info_dylibloader_orig_asound
+#define snd_seq_query_named_queue snd_seq_query_named_queue_dylibloader_orig_asound
+#define snd_seq_get_queue_usage snd_seq_get_queue_usage_dylibloader_orig_asound
+#define snd_seq_set_queue_usage snd_seq_set_queue_usage_dylibloader_orig_asound
+#define snd_seq_queue_status_sizeof snd_seq_queue_status_sizeof_dylibloader_orig_asound
+#define snd_seq_queue_status_malloc snd_seq_queue_status_malloc_dylibloader_orig_asound
+#define snd_seq_queue_status_free snd_seq_queue_status_free_dylibloader_orig_asound
+#define snd_seq_queue_status_copy snd_seq_queue_status_copy_dylibloader_orig_asound
+#define snd_seq_queue_status_get_queue snd_seq_queue_status_get_queue_dylibloader_orig_asound
+#define snd_seq_queue_status_get_events snd_seq_queue_status_get_events_dylibloader_orig_asound
+#define snd_seq_queue_status_get_tick_time snd_seq_queue_status_get_tick_time_dylibloader_orig_asound
+#define snd_seq_queue_status_get_real_time snd_seq_queue_status_get_real_time_dylibloader_orig_asound
+#define snd_seq_queue_status_get_status snd_seq_queue_status_get_status_dylibloader_orig_asound
+#define snd_seq_get_queue_status snd_seq_get_queue_status_dylibloader_orig_asound
+#define snd_seq_queue_tempo_sizeof snd_seq_queue_tempo_sizeof_dylibloader_orig_asound
+#define snd_seq_queue_tempo_malloc snd_seq_queue_tempo_malloc_dylibloader_orig_asound
+#define snd_seq_queue_tempo_free snd_seq_queue_tempo_free_dylibloader_orig_asound
+#define snd_seq_queue_tempo_copy snd_seq_queue_tempo_copy_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_queue snd_seq_queue_tempo_get_queue_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_tempo snd_seq_queue_tempo_get_tempo_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_ppq snd_seq_queue_tempo_get_ppq_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_skew snd_seq_queue_tempo_get_skew_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_skew_base snd_seq_queue_tempo_get_skew_base_dylibloader_orig_asound
+#define snd_seq_queue_tempo_set_tempo snd_seq_queue_tempo_set_tempo_dylibloader_orig_asound
+#define snd_seq_queue_tempo_set_ppq snd_seq_queue_tempo_set_ppq_dylibloader_orig_asound
+#define snd_seq_queue_tempo_set_skew snd_seq_queue_tempo_set_skew_dylibloader_orig_asound
+#define snd_seq_queue_tempo_set_skew_base snd_seq_queue_tempo_set_skew_base_dylibloader_orig_asound
+#define snd_seq_get_queue_tempo snd_seq_get_queue_tempo_dylibloader_orig_asound
+#define snd_seq_set_queue_tempo snd_seq_set_queue_tempo_dylibloader_orig_asound
+#define snd_seq_queue_timer_sizeof snd_seq_queue_timer_sizeof_dylibloader_orig_asound
+#define snd_seq_queue_timer_malloc snd_seq_queue_timer_malloc_dylibloader_orig_asound
+#define snd_seq_queue_timer_free snd_seq_queue_timer_free_dylibloader_orig_asound
+#define snd_seq_queue_timer_copy snd_seq_queue_timer_copy_dylibloader_orig_asound
+#define snd_seq_queue_timer_get_queue snd_seq_queue_timer_get_queue_dylibloader_orig_asound
+#define snd_seq_queue_timer_get_type snd_seq_queue_timer_get_type_dylibloader_orig_asound
+#define snd_seq_queue_timer_get_id snd_seq_queue_timer_get_id_dylibloader_orig_asound
+#define snd_seq_queue_timer_get_resolution snd_seq_queue_timer_get_resolution_dylibloader_orig_asound
+#define snd_seq_queue_timer_set_type snd_seq_queue_timer_set_type_dylibloader_orig_asound
+#define snd_seq_queue_timer_set_id snd_seq_queue_timer_set_id_dylibloader_orig_asound
+#define snd_seq_queue_timer_set_resolution snd_seq_queue_timer_set_resolution_dylibloader_orig_asound
+#define snd_seq_get_queue_timer snd_seq_get_queue_timer_dylibloader_orig_asound
+#define snd_seq_set_queue_timer snd_seq_set_queue_timer_dylibloader_orig_asound
+#define snd_seq_free_event snd_seq_free_event_dylibloader_orig_asound
+#define snd_seq_event_length snd_seq_event_length_dylibloader_orig_asound
+#define snd_seq_event_output snd_seq_event_output_dylibloader_orig_asound
+#define snd_seq_event_output_buffer snd_seq_event_output_buffer_dylibloader_orig_asound
+#define snd_seq_event_output_direct snd_seq_event_output_direct_dylibloader_orig_asound
+#define snd_seq_event_input snd_seq_event_input_dylibloader_orig_asound
+#define snd_seq_event_input_pending snd_seq_event_input_pending_dylibloader_orig_asound
+#define snd_seq_drain_output snd_seq_drain_output_dylibloader_orig_asound
+#define snd_seq_event_output_pending snd_seq_event_output_pending_dylibloader_orig_asound
+#define snd_seq_extract_output snd_seq_extract_output_dylibloader_orig_asound
+#define snd_seq_drop_output snd_seq_drop_output_dylibloader_orig_asound
+#define snd_seq_drop_output_buffer snd_seq_drop_output_buffer_dylibloader_orig_asound
+#define snd_seq_drop_input snd_seq_drop_input_dylibloader_orig_asound
+#define snd_seq_drop_input_buffer snd_seq_drop_input_buffer_dylibloader_orig_asound
+#define snd_seq_remove_events_sizeof snd_seq_remove_events_sizeof_dylibloader_orig_asound
+#define snd_seq_remove_events_malloc snd_seq_remove_events_malloc_dylibloader_orig_asound
+#define snd_seq_remove_events_free snd_seq_remove_events_free_dylibloader_orig_asound
+#define snd_seq_remove_events_copy snd_seq_remove_events_copy_dylibloader_orig_asound
+#define snd_seq_remove_events_get_condition snd_seq_remove_events_get_condition_dylibloader_orig_asound
+#define snd_seq_remove_events_get_queue snd_seq_remove_events_get_queue_dylibloader_orig_asound
+#define snd_seq_remove_events_get_time snd_seq_remove_events_get_time_dylibloader_orig_asound
+#define snd_seq_remove_events_get_dest snd_seq_remove_events_get_dest_dylibloader_orig_asound
+#define snd_seq_remove_events_get_channel snd_seq_remove_events_get_channel_dylibloader_orig_asound
+#define snd_seq_remove_events_get_event_type snd_seq_remove_events_get_event_type_dylibloader_orig_asound
+#define snd_seq_remove_events_get_tag snd_seq_remove_events_get_tag_dylibloader_orig_asound
+#define snd_seq_remove_events_set_condition snd_seq_remove_events_set_condition_dylibloader_orig_asound
+#define snd_seq_remove_events_set_queue snd_seq_remove_events_set_queue_dylibloader_orig_asound
+#define snd_seq_remove_events_set_time snd_seq_remove_events_set_time_dylibloader_orig_asound
+#define snd_seq_remove_events_set_dest snd_seq_remove_events_set_dest_dylibloader_orig_asound
+#define snd_seq_remove_events_set_channel snd_seq_remove_events_set_channel_dylibloader_orig_asound
+#define snd_seq_remove_events_set_event_type snd_seq_remove_events_set_event_type_dylibloader_orig_asound
+#define snd_seq_remove_events_set_tag snd_seq_remove_events_set_tag_dylibloader_orig_asound
+#define snd_seq_remove_events snd_seq_remove_events_dylibloader_orig_asound
+#define snd_seq_set_bit snd_seq_set_bit_dylibloader_orig_asound
+#define snd_seq_unset_bit snd_seq_unset_bit_dylibloader_orig_asound
+#define snd_seq_change_bit snd_seq_change_bit_dylibloader_orig_asound
+#define snd_seq_get_bit snd_seq_get_bit_dylibloader_orig_asound
+#define snd_seq_control_queue snd_seq_control_queue_dylibloader_orig_asound
+#define snd_seq_create_simple_port snd_seq_create_simple_port_dylibloader_orig_asound
+#define snd_seq_delete_simple_port snd_seq_delete_simple_port_dylibloader_orig_asound
+#define snd_seq_connect_from snd_seq_connect_from_dylibloader_orig_asound
+#define snd_seq_connect_to snd_seq_connect_to_dylibloader_orig_asound
+#define snd_seq_disconnect_from snd_seq_disconnect_from_dylibloader_orig_asound
+#define snd_seq_disconnect_to snd_seq_disconnect_to_dylibloader_orig_asound
+#define snd_seq_set_client_name snd_seq_set_client_name_dylibloader_orig_asound
+#define snd_seq_set_client_event_filter snd_seq_set_client_event_filter_dylibloader_orig_asound
+#define snd_seq_set_client_pool_output snd_seq_set_client_pool_output_dylibloader_orig_asound
+#define snd_seq_set_client_pool_output_room snd_seq_set_client_pool_output_room_dylibloader_orig_asound
+#define snd_seq_set_client_pool_input snd_seq_set_client_pool_input_dylibloader_orig_asound
+#define snd_seq_sync_output_queue snd_seq_sync_output_queue_dylibloader_orig_asound
+#define snd_seq_parse_address snd_seq_parse_address_dylibloader_orig_asound
+#define snd_seq_reset_pool_output snd_seq_reset_pool_output_dylibloader_orig_asound
+#define snd_seq_reset_pool_input snd_seq_reset_pool_input_dylibloader_orig_asound
+#define snd_midi_event_new snd_midi_event_new_dylibloader_orig_asound
+#define snd_midi_event_resize_buffer snd_midi_event_resize_buffer_dylibloader_orig_asound
+#define snd_midi_event_free snd_midi_event_free_dylibloader_orig_asound
+#define snd_midi_event_init snd_midi_event_init_dylibloader_orig_asound
+#define snd_midi_event_reset_encode snd_midi_event_reset_encode_dylibloader_orig_asound
+#define snd_midi_event_reset_decode snd_midi_event_reset_decode_dylibloader_orig_asound
+#define snd_midi_event_no_status snd_midi_event_no_status_dylibloader_orig_asound
+#define snd_midi_event_encode snd_midi_event_encode_dylibloader_orig_asound
+#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_orig_asound
+#define snd_midi_event_decode snd_midi_event_decode_dylibloader_orig_asound
+#include <alsa/asoundlib.h>
+#undef snd_asoundlib_version
+#undef snd_dlpath
+#undef snd_dlopen
+#undef snd_dlsym
+#undef snd_dlclose
+#undef snd_async_add_handler
+#undef snd_async_del_handler
+#undef snd_async_handler_get_fd
+#undef snd_async_handler_get_signo
+#undef snd_async_handler_get_callback_private
+#undef snd_shm_area_create
+#undef snd_shm_area_share
+#undef snd_shm_area_destroy
+#undef snd_user_file
+#undef snd_input_stdio_open
+#undef snd_input_stdio_attach
+#undef snd_input_buffer_open
+#undef snd_input_close
+#undef snd_input_scanf
+#undef snd_input_gets
+#undef snd_input_getc
+#undef snd_input_ungetc
+#undef snd_output_stdio_open
+#undef snd_output_stdio_attach
+#undef snd_output_buffer_open
+#undef snd_output_buffer_string
+#undef snd_output_close
+#undef snd_output_printf
+#undef snd_output_vprintf
+#undef snd_output_puts
+#undef snd_output_putc
+#undef snd_output_flush
+#undef snd_strerror
+#undef snd_lib_error_set_handler
+#undef snd_lib_error_set_local
+#undef snd_config_topdir
+#undef snd_config_top
+#undef snd_config_load
+#undef snd_config_load_override
+#undef snd_config_save
+#undef snd_config_update
+#undef snd_config_update_r
+#undef snd_config_update_free
+#undef snd_config_update_free_global
+#undef snd_config_update_ref
+#undef snd_config_ref
+#undef snd_config_unref
+#undef snd_config_search
+#undef snd_config_searchv
+#undef snd_config_search_definition
+#undef snd_config_expand
+#undef snd_config_evaluate
+#undef snd_config_add
+#undef snd_config_add_before
+#undef snd_config_add_after
+#undef snd_config_remove
+#undef snd_config_delete
+#undef snd_config_delete_compound_members
+#undef snd_config_copy
+#undef snd_config_make
+#undef snd_config_make_integer
+#undef snd_config_make_integer64
+#undef snd_config_make_real
+#undef snd_config_make_string
+#undef snd_config_make_pointer
+#undef snd_config_make_compound
+#undef snd_config_imake_integer
+#undef snd_config_imake_integer64
+#undef snd_config_imake_real
+#undef snd_config_imake_string
+#undef snd_config_imake_safe_string
+#undef snd_config_imake_pointer
+#undef snd_config_get_type
+#undef snd_config_is_array
+#undef snd_config_set_id
+#undef snd_config_set_integer
+#undef snd_config_set_integer64
+#undef snd_config_set_real
+#undef snd_config_set_string
+#undef snd_config_set_ascii
+#undef snd_config_set_pointer
+#undef snd_config_get_id
+#undef snd_config_get_integer
+#undef snd_config_get_integer64
+#undef snd_config_get_real
+#undef snd_config_get_ireal
+#undef snd_config_get_string
+#undef snd_config_get_ascii
+#undef snd_config_get_pointer
+#undef snd_config_test_id
+#undef snd_config_iterator_first
+#undef snd_config_iterator_next
+#undef snd_config_iterator_end
+#undef snd_config_iterator_entry
+#undef snd_config_get_bool_ascii
+#undef snd_config_get_bool
+#undef snd_config_get_ctl_iface_ascii
+#undef snd_config_get_ctl_iface
+#undef snd_names_list
+#undef snd_names_list_free
+#undef snd_pcm_open
+#undef snd_pcm_open_lconf
+#undef snd_pcm_open_fallback
+#undef snd_pcm_close
+#undef snd_pcm_name
+#undef snd_pcm_type
+#undef snd_pcm_stream
+#undef snd_pcm_poll_descriptors_count
+#undef snd_pcm_poll_descriptors
+#undef snd_pcm_poll_descriptors_revents
+#undef snd_pcm_nonblock
+#undef snd_async_add_pcm_handler
+#undef snd_async_handler_get_pcm
+#undef snd_pcm_info
+#undef snd_pcm_hw_params_current
+#undef snd_pcm_hw_params
+#undef snd_pcm_hw_free
+#undef snd_pcm_sw_params_current
+#undef snd_pcm_sw_params
+#undef snd_pcm_prepare
+#undef snd_pcm_reset
+#undef snd_pcm_status
+#undef snd_pcm_start
+#undef snd_pcm_drop
+#undef snd_pcm_drain
+#undef snd_pcm_pause
+#undef snd_pcm_state
+#undef snd_pcm_hwsync
+#undef snd_pcm_delay
+#undef snd_pcm_resume
+#undef snd_pcm_htimestamp
+#undef snd_pcm_avail
+#undef snd_pcm_avail_update
+#undef snd_pcm_avail_delay
+#undef snd_pcm_rewindable
+#undef snd_pcm_rewind
+#undef snd_pcm_forwardable
+#undef snd_pcm_forward
+#undef snd_pcm_writei
+#undef snd_pcm_readi
+#undef snd_pcm_writen
+#undef snd_pcm_readn
+#undef snd_pcm_wait
+#undef snd_pcm_link
+#undef snd_pcm_unlink
+#undef snd_pcm_query_chmaps
+#undef snd_pcm_query_chmaps_from_hw
+#undef snd_pcm_free_chmaps
+#undef snd_pcm_get_chmap
+#undef snd_pcm_set_chmap
+#undef snd_pcm_chmap_type_name
+#undef snd_pcm_chmap_name
+#undef snd_pcm_chmap_long_name
+#undef snd_pcm_chmap_print
+#undef snd_pcm_chmap_from_string
+#undef snd_pcm_chmap_parse_string
+#undef snd_pcm_recover
+#undef snd_pcm_set_params
+#undef snd_pcm_get_params
+#undef snd_pcm_info_sizeof
+#undef snd_pcm_info_malloc
+#undef snd_pcm_info_free
+#undef snd_pcm_info_copy
+#undef snd_pcm_info_get_device
+#undef snd_pcm_info_get_subdevice
+#undef snd_pcm_info_get_stream
+#undef snd_pcm_info_get_card
+#undef snd_pcm_info_get_id
+#undef snd_pcm_info_get_name
+#undef snd_pcm_info_get_subdevice_name
+#undef snd_pcm_info_get_class
+#undef snd_pcm_info_get_subclass
+#undef snd_pcm_info_get_subdevices_count
+#undef snd_pcm_info_get_subdevices_avail
+#undef snd_pcm_info_get_sync
+#undef snd_pcm_info_set_device
+#undef snd_pcm_info_set_subdevice
+#undef snd_pcm_info_set_stream
+#undef snd_pcm_hw_params_any
+#undef snd_pcm_hw_params_can_mmap_sample_resolution
+#undef snd_pcm_hw_params_is_double
+#undef snd_pcm_hw_params_is_batch
+#undef snd_pcm_hw_params_is_block_transfer
+#undef snd_pcm_hw_params_is_monotonic
+#undef snd_pcm_hw_params_can_overrange
+#undef snd_pcm_hw_params_can_pause
+#undef snd_pcm_hw_params_can_resume
+#undef snd_pcm_hw_params_is_half_duplex
+#undef snd_pcm_hw_params_is_joint_duplex
+#undef snd_pcm_hw_params_can_sync_start
+#undef snd_pcm_hw_params_can_disable_period_wakeup
+#undef snd_pcm_hw_params_supports_audio_wallclock_ts
+#undef snd_pcm_hw_params_supports_audio_ts_type
+#undef snd_pcm_hw_params_get_rate_numden
+#undef snd_pcm_hw_params_get_sbits
+#undef snd_pcm_hw_params_get_fifo_size
+#undef snd_pcm_hw_params_sizeof
+#undef snd_pcm_hw_params_malloc
+#undef snd_pcm_hw_params_free
+#undef snd_pcm_hw_params_copy
+#undef snd_pcm_hw_params_get_access
+#undef snd_pcm_hw_params_test_access
+#undef snd_pcm_hw_params_set_access
+#undef snd_pcm_hw_params_set_access_first
+#undef snd_pcm_hw_params_set_access_last
+#undef snd_pcm_hw_params_set_access_mask
+#undef snd_pcm_hw_params_get_access_mask
+#undef snd_pcm_hw_params_get_format
+#undef snd_pcm_hw_params_test_format
+#undef snd_pcm_hw_params_set_format
+#undef snd_pcm_hw_params_set_format_first
+#undef snd_pcm_hw_params_set_format_last
+#undef snd_pcm_hw_params_set_format_mask
+#undef snd_pcm_hw_params_get_format_mask
+#undef snd_pcm_hw_params_get_subformat
+#undef snd_pcm_hw_params_test_subformat
+#undef snd_pcm_hw_params_set_subformat
+#undef snd_pcm_hw_params_set_subformat_first
+#undef snd_pcm_hw_params_set_subformat_last
+#undef snd_pcm_hw_params_set_subformat_mask
+#undef snd_pcm_hw_params_get_subformat_mask
+#undef snd_pcm_hw_params_get_channels
+#undef snd_pcm_hw_params_get_channels_min
+#undef snd_pcm_hw_params_get_channels_max
+#undef snd_pcm_hw_params_test_channels
+#undef snd_pcm_hw_params_set_channels
+#undef snd_pcm_hw_params_set_channels_min
+#undef snd_pcm_hw_params_set_channels_max
+#undef snd_pcm_hw_params_set_channels_minmax
+#undef snd_pcm_hw_params_set_channels_near
+#undef snd_pcm_hw_params_set_channels_first
+#undef snd_pcm_hw_params_set_channels_last
+#undef snd_pcm_hw_params_get_rate
+#undef snd_pcm_hw_params_get_rate_min
+#undef snd_pcm_hw_params_get_rate_max
+#undef snd_pcm_hw_params_test_rate
+#undef snd_pcm_hw_params_set_rate
+#undef snd_pcm_hw_params_set_rate_min
+#undef snd_pcm_hw_params_set_rate_max
+#undef snd_pcm_hw_params_set_rate_minmax
+#undef snd_pcm_hw_params_set_rate_near
+#undef snd_pcm_hw_params_set_rate_first
+#undef snd_pcm_hw_params_set_rate_last
+#undef snd_pcm_hw_params_set_rate_resample
+#undef snd_pcm_hw_params_get_rate_resample
+#undef snd_pcm_hw_params_set_export_buffer
+#undef snd_pcm_hw_params_get_export_buffer
+#undef snd_pcm_hw_params_set_period_wakeup
+#undef snd_pcm_hw_params_get_period_wakeup
+#undef snd_pcm_hw_params_get_period_time
+#undef snd_pcm_hw_params_get_period_time_min
+#undef snd_pcm_hw_params_get_period_time_max
+#undef snd_pcm_hw_params_test_period_time
+#undef snd_pcm_hw_params_set_period_time
+#undef snd_pcm_hw_params_set_period_time_min
+#undef snd_pcm_hw_params_set_period_time_max
+#undef snd_pcm_hw_params_set_period_time_minmax
+#undef snd_pcm_hw_params_set_period_time_near
+#undef snd_pcm_hw_params_set_period_time_first
+#undef snd_pcm_hw_params_set_period_time_last
+#undef snd_pcm_hw_params_get_period_size
+#undef snd_pcm_hw_params_get_period_size_min
+#undef snd_pcm_hw_params_get_period_size_max
+#undef snd_pcm_hw_params_test_period_size
+#undef snd_pcm_hw_params_set_period_size
+#undef snd_pcm_hw_params_set_period_size_min
+#undef snd_pcm_hw_params_set_period_size_max
+#undef snd_pcm_hw_params_set_period_size_minmax
+#undef snd_pcm_hw_params_set_period_size_near
+#undef snd_pcm_hw_params_set_period_size_first
+#undef snd_pcm_hw_params_set_period_size_last
+#undef snd_pcm_hw_params_set_period_size_integer
+#undef snd_pcm_hw_params_get_periods
+#undef snd_pcm_hw_params_get_periods_min
+#undef snd_pcm_hw_params_get_periods_max
+#undef snd_pcm_hw_params_test_periods
+#undef snd_pcm_hw_params_set_periods
+#undef snd_pcm_hw_params_set_periods_min
+#undef snd_pcm_hw_params_set_periods_max
+#undef snd_pcm_hw_params_set_periods_minmax
+#undef snd_pcm_hw_params_set_periods_near
+#undef snd_pcm_hw_params_set_periods_first
+#undef snd_pcm_hw_params_set_periods_last
+#undef snd_pcm_hw_params_set_periods_integer
+#undef snd_pcm_hw_params_get_buffer_time
+#undef snd_pcm_hw_params_get_buffer_time_min
+#undef snd_pcm_hw_params_get_buffer_time_max
+#undef snd_pcm_hw_params_test_buffer_time
+#undef snd_pcm_hw_params_set_buffer_time
+#undef snd_pcm_hw_params_set_buffer_time_min
+#undef snd_pcm_hw_params_set_buffer_time_max
+#undef snd_pcm_hw_params_set_buffer_time_minmax
+#undef snd_pcm_hw_params_set_buffer_time_near
+#undef snd_pcm_hw_params_set_buffer_time_first
+#undef snd_pcm_hw_params_set_buffer_time_last
+#undef snd_pcm_hw_params_get_buffer_size
+#undef snd_pcm_hw_params_get_buffer_size_min
+#undef snd_pcm_hw_params_get_buffer_size_max
+#undef snd_pcm_hw_params_test_buffer_size
+#undef snd_pcm_hw_params_set_buffer_size
+#undef snd_pcm_hw_params_set_buffer_size_min
+#undef snd_pcm_hw_params_set_buffer_size_max
+#undef snd_pcm_hw_params_set_buffer_size_minmax
+#undef snd_pcm_hw_params_set_buffer_size_near
+#undef snd_pcm_hw_params_set_buffer_size_first
+#undef snd_pcm_hw_params_set_buffer_size_last
+#undef snd_pcm_hw_params_get_min_align
+#undef snd_pcm_sw_params_sizeof
+#undef snd_pcm_sw_params_malloc
+#undef snd_pcm_sw_params_free
+#undef snd_pcm_sw_params_copy
+#undef snd_pcm_sw_params_get_boundary
+#undef snd_pcm_sw_params_set_tstamp_mode
+#undef snd_pcm_sw_params_get_tstamp_mode
+#undef snd_pcm_sw_params_set_avail_min
+#undef snd_pcm_sw_params_get_avail_min
+#undef snd_pcm_sw_params_set_period_event
+#undef snd_pcm_sw_params_get_period_event
+#undef snd_pcm_sw_params_set_start_threshold
+#undef snd_pcm_sw_params_get_start_threshold
+#undef snd_pcm_sw_params_set_stop_threshold
+#undef snd_pcm_sw_params_get_stop_threshold
+#undef snd_pcm_sw_params_set_silence_threshold
+#undef snd_pcm_sw_params_get_silence_threshold
+#undef snd_pcm_sw_params_set_silence_size
+#undef snd_pcm_sw_params_get_silence_size
+#undef snd_pcm_access_mask_sizeof
+#undef snd_pcm_access_mask_malloc
+#undef snd_pcm_access_mask_free
+#undef snd_pcm_access_mask_copy
+#undef snd_pcm_access_mask_none
+#undef snd_pcm_access_mask_any
+#undef snd_pcm_access_mask_test
+#undef snd_pcm_access_mask_empty
+#undef snd_pcm_access_mask_set
+#undef snd_pcm_access_mask_reset
+#undef snd_pcm_format_mask_sizeof
+#undef snd_pcm_format_mask_malloc
+#undef snd_pcm_format_mask_free
+#undef snd_pcm_format_mask_copy
+#undef snd_pcm_format_mask_none
+#undef snd_pcm_format_mask_any
+#undef snd_pcm_format_mask_test
+#undef snd_pcm_format_mask_empty
+#undef snd_pcm_format_mask_set
+#undef snd_pcm_format_mask_reset
+#undef snd_pcm_subformat_mask_sizeof
+#undef snd_pcm_subformat_mask_malloc
+#undef snd_pcm_subformat_mask_free
+#undef snd_pcm_subformat_mask_copy
+#undef snd_pcm_subformat_mask_none
+#undef snd_pcm_subformat_mask_any
+#undef snd_pcm_subformat_mask_test
+#undef snd_pcm_subformat_mask_empty
+#undef snd_pcm_subformat_mask_set
+#undef snd_pcm_subformat_mask_reset
+#undef snd_pcm_status_sizeof
+#undef snd_pcm_status_malloc
+#undef snd_pcm_status_free
+#undef snd_pcm_status_copy
+#undef snd_pcm_status_get_state
+#undef snd_pcm_status_get_trigger_tstamp
+#undef snd_pcm_status_get_trigger_htstamp
+#undef snd_pcm_status_get_tstamp
+#undef snd_pcm_status_get_htstamp
+#undef snd_pcm_status_get_audio_htstamp
+#undef snd_pcm_status_get_driver_htstamp
+#undef snd_pcm_status_get_delay
+#undef snd_pcm_status_get_avail
+#undef snd_pcm_status_get_avail_max
+#undef snd_pcm_status_get_overrange
+#undef snd_pcm_type_name
+#undef snd_pcm_stream_name
+#undef snd_pcm_access_name
+#undef snd_pcm_format_name
+#undef snd_pcm_format_description
+#undef snd_pcm_subformat_name
+#undef snd_pcm_subformat_description
+#undef snd_pcm_format_value
+#undef snd_pcm_tstamp_mode_name
+#undef snd_pcm_state_name
+#undef snd_pcm_dump
+#undef snd_pcm_dump_hw_setup
+#undef snd_pcm_dump_sw_setup
+#undef snd_pcm_dump_setup
+#undef snd_pcm_hw_params_dump
+#undef snd_pcm_sw_params_dump
+#undef snd_pcm_status_dump
+#undef snd_pcm_mmap_begin
+#undef snd_pcm_mmap_commit
+#undef snd_pcm_mmap_writei
+#undef snd_pcm_mmap_readi
+#undef snd_pcm_mmap_writen
+#undef snd_pcm_mmap_readn
+#undef snd_pcm_format_signed
+#undef snd_pcm_format_unsigned
+#undef snd_pcm_format_linear
+#undef snd_pcm_format_float
+#undef snd_pcm_format_little_endian
+#undef snd_pcm_format_big_endian
+#undef snd_pcm_format_cpu_endian
+#undef snd_pcm_format_width
+#undef snd_pcm_format_physical_width
+#undef snd_pcm_build_linear_format
+#undef snd_pcm_format_size
+#undef snd_pcm_format_silence
+#undef snd_pcm_format_silence_16
+#undef snd_pcm_format_silence_32
+#undef snd_pcm_format_silence_64
+#undef snd_pcm_format_set_silence
+#undef snd_pcm_bytes_to_frames
+#undef snd_pcm_frames_to_bytes
+#undef snd_pcm_bytes_to_samples
+#undef snd_pcm_samples_to_bytes
+#undef snd_pcm_area_silence
+#undef snd_pcm_areas_silence
+#undef snd_pcm_area_copy
+#undef snd_pcm_areas_copy
+#undef snd_pcm_areas_copy_wrap
+#undef snd_pcm_hook_get_pcm
+#undef snd_pcm_hook_get_private
+#undef snd_pcm_hook_set_private
+#undef snd_pcm_hook_add
+#undef snd_pcm_hook_remove
+#undef snd_pcm_meter_get_bufsize
+#undef snd_pcm_meter_get_channels
+#undef snd_pcm_meter_get_rate
+#undef snd_pcm_meter_get_now
+#undef snd_pcm_meter_get_boundary
+#undef snd_pcm_meter_add_scope
+#undef snd_pcm_meter_search_scope
+#undef snd_pcm_scope_malloc
+#undef snd_pcm_scope_set_ops
+#undef snd_pcm_scope_set_name
+#undef snd_pcm_scope_get_name
+#undef snd_pcm_scope_get_callback_private
+#undef snd_pcm_scope_set_callback_private
+#undef snd_pcm_scope_s16_open
+#undef snd_pcm_scope_s16_get_channel_buffer
+#undef snd_spcm_init
+#undef snd_spcm_init_duplex
+#undef snd_spcm_init_get_params
+#undef snd_pcm_start_mode_name
+#undef snd_pcm_xrun_mode_name
+#undef snd_pcm_sw_params_set_start_mode
+#undef snd_pcm_sw_params_get_start_mode
+#undef snd_pcm_sw_params_set_xrun_mode
+#undef snd_pcm_sw_params_get_xrun_mode
+#undef snd_pcm_sw_params_set_xfer_align
+#undef snd_pcm_sw_params_get_xfer_align
+#undef snd_pcm_sw_params_set_sleep_min
+#undef snd_pcm_sw_params_get_sleep_min
+#undef snd_pcm_hw_params_get_tick_time
+#undef snd_pcm_hw_params_get_tick_time_min
+#undef snd_pcm_hw_params_get_tick_time_max
+#undef snd_pcm_hw_params_test_tick_time
+#undef snd_pcm_hw_params_set_tick_time
+#undef snd_pcm_hw_params_set_tick_time_min
+#undef snd_pcm_hw_params_set_tick_time_max
+#undef snd_pcm_hw_params_set_tick_time_minmax
+#undef snd_pcm_hw_params_set_tick_time_near
+#undef snd_pcm_hw_params_set_tick_time_first
+#undef snd_pcm_hw_params_set_tick_time_last
+#undef snd_rawmidi_open
+#undef snd_rawmidi_open_lconf
+#undef snd_rawmidi_close
+#undef snd_rawmidi_poll_descriptors_count
+#undef snd_rawmidi_poll_descriptors
+#undef snd_rawmidi_poll_descriptors_revents
+#undef snd_rawmidi_nonblock
+#undef snd_rawmidi_info_sizeof
+#undef snd_rawmidi_info_malloc
+#undef snd_rawmidi_info_free
+#undef snd_rawmidi_info_copy
+#undef snd_rawmidi_info_get_device
+#undef snd_rawmidi_info_get_subdevice
+#undef snd_rawmidi_info_get_stream
+#undef snd_rawmidi_info_get_card
+#undef snd_rawmidi_info_get_flags
+#undef snd_rawmidi_info_get_id
+#undef snd_rawmidi_info_get_name
+#undef snd_rawmidi_info_get_subdevice_name
+#undef snd_rawmidi_info_get_subdevices_count
+#undef snd_rawmidi_info_get_subdevices_avail
+#undef snd_rawmidi_info_set_device
+#undef snd_rawmidi_info_set_subdevice
+#undef snd_rawmidi_info_set_stream
+#undef snd_rawmidi_info
+#undef snd_rawmidi_params_sizeof
+#undef snd_rawmidi_params_malloc
+#undef snd_rawmidi_params_free
+#undef snd_rawmidi_params_copy
+#undef snd_rawmidi_params_set_buffer_size
+#undef snd_rawmidi_params_get_buffer_size
+#undef snd_rawmidi_params_set_avail_min
+#undef snd_rawmidi_params_get_avail_min
+#undef snd_rawmidi_params_set_no_active_sensing
+#undef snd_rawmidi_params_get_no_active_sensing
+#undef snd_rawmidi_params
+#undef snd_rawmidi_params_current
+#undef snd_rawmidi_status_sizeof
+#undef snd_rawmidi_status_malloc
+#undef snd_rawmidi_status_free
+#undef snd_rawmidi_status_copy
+#undef snd_rawmidi_status_get_tstamp
+#undef snd_rawmidi_status_get_avail
+#undef snd_rawmidi_status_get_xruns
+#undef snd_rawmidi_status
+#undef snd_rawmidi_drain
+#undef snd_rawmidi_drop
+#undef snd_rawmidi_write
+#undef snd_rawmidi_read
+#undef snd_rawmidi_name
+#undef snd_rawmidi_type
+#undef snd_rawmidi_stream
+#undef snd_timer_query_open
+#undef snd_timer_query_open_lconf
+#undef snd_timer_query_close
+#undef snd_timer_query_next_device
+#undef snd_timer_query_info
+#undef snd_timer_query_params
+#undef snd_timer_query_status
+#undef snd_timer_open
+#undef snd_timer_open_lconf
+#undef snd_timer_close
+#undef snd_async_add_timer_handler
+#undef snd_async_handler_get_timer
+#undef snd_timer_poll_descriptors_count
+#undef snd_timer_poll_descriptors
+#undef snd_timer_poll_descriptors_revents
+#undef snd_timer_info
+#undef snd_timer_params
+#undef snd_timer_status
+#undef snd_timer_start
+#undef snd_timer_stop
+#undef snd_timer_continue
+#undef snd_timer_read
+#undef snd_timer_id_sizeof
+#undef snd_timer_id_malloc
+#undef snd_timer_id_free
+#undef snd_timer_id_copy
+#undef snd_timer_id_set_class
+#undef snd_timer_id_get_class
+#undef snd_timer_id_set_sclass
+#undef snd_timer_id_get_sclass
+#undef snd_timer_id_set_card
+#undef snd_timer_id_get_card
+#undef snd_timer_id_set_device
+#undef snd_timer_id_get_device
+#undef snd_timer_id_set_subdevice
+#undef snd_timer_id_get_subdevice
+#undef snd_timer_ginfo_sizeof
+#undef snd_timer_ginfo_malloc
+#undef snd_timer_ginfo_free
+#undef snd_timer_ginfo_copy
+#undef snd_timer_ginfo_set_tid
+#undef snd_timer_ginfo_get_tid
+#undef snd_timer_ginfo_get_flags
+#undef snd_timer_ginfo_get_card
+#undef snd_timer_ginfo_get_id
+#undef snd_timer_ginfo_get_name
+#undef snd_timer_ginfo_get_resolution
+#undef snd_timer_ginfo_get_resolution_min
+#undef snd_timer_ginfo_get_resolution_max
+#undef snd_timer_ginfo_get_clients
+#undef snd_timer_info_sizeof
+#undef snd_timer_info_malloc
+#undef snd_timer_info_free
+#undef snd_timer_info_copy
+#undef snd_timer_info_is_slave
+#undef snd_timer_info_get_card
+#undef snd_timer_info_get_id
+#undef snd_timer_info_get_name
+#undef snd_timer_info_get_resolution
+#undef snd_timer_params_sizeof
+#undef snd_timer_params_malloc
+#undef snd_timer_params_free
+#undef snd_timer_params_copy
+#undef snd_timer_params_set_auto_start
+#undef snd_timer_params_get_auto_start
+#undef snd_timer_params_set_exclusive
+#undef snd_timer_params_get_exclusive
+#undef snd_timer_params_set_early_event
+#undef snd_timer_params_get_early_event
+#undef snd_timer_params_set_ticks
+#undef snd_timer_params_get_ticks
+#undef snd_timer_params_set_queue_size
+#undef snd_timer_params_get_queue_size
+#undef snd_timer_params_set_filter
+#undef snd_timer_params_get_filter
+#undef snd_timer_status_sizeof
+#undef snd_timer_status_malloc
+#undef snd_timer_status_free
+#undef snd_timer_status_copy
+#undef snd_timer_status_get_timestamp
+#undef snd_timer_status_get_resolution
+#undef snd_timer_status_get_lost
+#undef snd_timer_status_get_overrun
+#undef snd_timer_status_get_queue
+#undef snd_timer_info_get_ticks
+#undef snd_hwdep_open
+#undef snd_hwdep_close
+#undef snd_hwdep_poll_descriptors
+#undef snd_hwdep_poll_descriptors_count
+#undef snd_hwdep_poll_descriptors_revents
+#undef snd_hwdep_nonblock
+#undef snd_hwdep_info
+#undef snd_hwdep_dsp_status
+#undef snd_hwdep_dsp_load
+#undef snd_hwdep_ioctl
+#undef snd_hwdep_write
+#undef snd_hwdep_read
+#undef snd_hwdep_info_sizeof
+#undef snd_hwdep_info_malloc
+#undef snd_hwdep_info_free
+#undef snd_hwdep_info_copy
+#undef snd_hwdep_info_get_device
+#undef snd_hwdep_info_get_card
+#undef snd_hwdep_info_get_id
+#undef snd_hwdep_info_get_name
+#undef snd_hwdep_info_get_iface
+#undef snd_hwdep_info_set_device
+#undef snd_hwdep_dsp_status_sizeof
+#undef snd_hwdep_dsp_status_malloc
+#undef snd_hwdep_dsp_status_free
+#undef snd_hwdep_dsp_status_copy
+#undef snd_hwdep_dsp_status_get_version
+#undef snd_hwdep_dsp_status_get_id
+#undef snd_hwdep_dsp_status_get_num_dsps
+#undef snd_hwdep_dsp_status_get_dsp_loaded
+#undef snd_hwdep_dsp_status_get_chip_ready
+#undef snd_hwdep_dsp_image_sizeof
+#undef snd_hwdep_dsp_image_malloc
+#undef snd_hwdep_dsp_image_free
+#undef snd_hwdep_dsp_image_copy
+#undef snd_hwdep_dsp_image_get_index
+#undef snd_hwdep_dsp_image_get_name
+#undef snd_hwdep_dsp_image_get_image
+#undef snd_hwdep_dsp_image_get_length
+#undef snd_hwdep_dsp_image_set_index
+#undef snd_hwdep_dsp_image_set_name
+#undef snd_hwdep_dsp_image_set_image
+#undef snd_hwdep_dsp_image_set_length
+#undef snd_card_load
+#undef snd_card_next
+#undef snd_card_get_index
+#undef snd_card_get_name
+#undef snd_card_get_longname
+#undef snd_device_name_hint
+#undef snd_device_name_free_hint
+#undef snd_device_name_get_hint
+#undef snd_ctl_open
+#undef snd_ctl_open_lconf
+#undef snd_ctl_open_fallback
+#undef snd_ctl_close
+#undef snd_ctl_nonblock
+#undef snd_async_add_ctl_handler
+#undef snd_async_handler_get_ctl
+#undef snd_ctl_poll_descriptors_count
+#undef snd_ctl_poll_descriptors
+#undef snd_ctl_poll_descriptors_revents
+#undef snd_ctl_subscribe_events
+#undef snd_ctl_card_info
+#undef snd_ctl_elem_list
+#undef snd_ctl_elem_info
+#undef snd_ctl_elem_read
+#undef snd_ctl_elem_write
+#undef snd_ctl_elem_lock
+#undef snd_ctl_elem_unlock
+#undef snd_ctl_elem_tlv_read
+#undef snd_ctl_elem_tlv_write
+#undef snd_ctl_elem_tlv_command
+#undef snd_ctl_hwdep_next_device
+#undef snd_ctl_hwdep_info
+#undef snd_ctl_pcm_next_device
+#undef snd_ctl_pcm_info
+#undef snd_ctl_pcm_prefer_subdevice
+#undef snd_ctl_rawmidi_next_device
+#undef snd_ctl_rawmidi_info
+#undef snd_ctl_rawmidi_prefer_subdevice
+#undef snd_ctl_set_power_state
+#undef snd_ctl_get_power_state
+#undef snd_ctl_read
+#undef snd_ctl_wait
+#undef snd_ctl_name
+#undef snd_ctl_type
+#undef snd_ctl_elem_type_name
+#undef snd_ctl_elem_iface_name
+#undef snd_ctl_event_type_name
+#undef snd_ctl_event_elem_get_mask
+#undef snd_ctl_event_elem_get_numid
+#undef snd_ctl_event_elem_get_id
+#undef snd_ctl_event_elem_get_interface
+#undef snd_ctl_event_elem_get_device
+#undef snd_ctl_event_elem_get_subdevice
+#undef snd_ctl_event_elem_get_name
+#undef snd_ctl_event_elem_get_index
+#undef snd_ctl_elem_list_alloc_space
+#undef snd_ctl_elem_list_free_space
+#undef snd_ctl_ascii_elem_id_get
+#undef snd_ctl_ascii_elem_id_parse
+#undef snd_ctl_ascii_value_parse
+#undef snd_ctl_elem_id_sizeof
+#undef snd_ctl_elem_id_malloc
+#undef snd_ctl_elem_id_free
+#undef snd_ctl_elem_id_clear
+#undef snd_ctl_elem_id_copy
+#undef snd_ctl_elem_id_get_numid
+#undef snd_ctl_elem_id_get_interface
+#undef snd_ctl_elem_id_get_device
+#undef snd_ctl_elem_id_get_subdevice
+#undef snd_ctl_elem_id_get_name
+#undef snd_ctl_elem_id_get_index
+#undef snd_ctl_elem_id_set_numid
+#undef snd_ctl_elem_id_set_interface
+#undef snd_ctl_elem_id_set_device
+#undef snd_ctl_elem_id_set_subdevice
+#undef snd_ctl_elem_id_set_name
+#undef snd_ctl_elem_id_set_index
+#undef snd_ctl_card_info_sizeof
+#undef snd_ctl_card_info_malloc
+#undef snd_ctl_card_info_free
+#undef snd_ctl_card_info_clear
+#undef snd_ctl_card_info_copy
+#undef snd_ctl_card_info_get_card
+#undef snd_ctl_card_info_get_id
+#undef snd_ctl_card_info_get_driver
+#undef snd_ctl_card_info_get_name
+#undef snd_ctl_card_info_get_longname
+#undef snd_ctl_card_info_get_mixername
+#undef snd_ctl_card_info_get_components
+#undef snd_ctl_event_sizeof
+#undef snd_ctl_event_malloc
+#undef snd_ctl_event_free
+#undef snd_ctl_event_clear
+#undef snd_ctl_event_copy
+#undef snd_ctl_event_get_type
+#undef snd_ctl_elem_list_sizeof
+#undef snd_ctl_elem_list_malloc
+#undef snd_ctl_elem_list_free
+#undef snd_ctl_elem_list_clear
+#undef snd_ctl_elem_list_copy
+#undef snd_ctl_elem_list_set_offset
+#undef snd_ctl_elem_list_get_used
+#undef snd_ctl_elem_list_get_count
+#undef snd_ctl_elem_list_get_id
+#undef snd_ctl_elem_list_get_numid
+#undef snd_ctl_elem_list_get_interface
+#undef snd_ctl_elem_list_get_device
+#undef snd_ctl_elem_list_get_subdevice
+#undef snd_ctl_elem_list_get_name
+#undef snd_ctl_elem_list_get_index
+#undef snd_ctl_elem_info_sizeof
+#undef snd_ctl_elem_info_malloc
+#undef snd_ctl_elem_info_free
+#undef snd_ctl_elem_info_clear
+#undef snd_ctl_elem_info_copy
+#undef snd_ctl_elem_info_get_type
+#undef snd_ctl_elem_info_is_readable
+#undef snd_ctl_elem_info_is_writable
+#undef snd_ctl_elem_info_is_volatile
+#undef snd_ctl_elem_info_is_inactive
+#undef snd_ctl_elem_info_is_locked
+#undef snd_ctl_elem_info_is_tlv_readable
+#undef snd_ctl_elem_info_is_tlv_writable
+#undef snd_ctl_elem_info_is_tlv_commandable
+#undef snd_ctl_elem_info_is_owner
+#undef snd_ctl_elem_info_is_user
+#undef snd_ctl_elem_info_get_owner
+#undef snd_ctl_elem_info_get_count
+#undef snd_ctl_elem_info_get_min
+#undef snd_ctl_elem_info_get_max
+#undef snd_ctl_elem_info_get_step
+#undef snd_ctl_elem_info_get_min64
+#undef snd_ctl_elem_info_get_max64
+#undef snd_ctl_elem_info_get_step64
+#undef snd_ctl_elem_info_get_items
+#undef snd_ctl_elem_info_set_item
+#undef snd_ctl_elem_info_get_item_name
+#undef snd_ctl_elem_info_get_dimensions
+#undef snd_ctl_elem_info_get_dimension
+#undef snd_ctl_elem_info_set_dimension
+#undef snd_ctl_elem_info_get_id
+#undef snd_ctl_elem_info_get_numid
+#undef snd_ctl_elem_info_get_interface
+#undef snd_ctl_elem_info_get_device
+#undef snd_ctl_elem_info_get_subdevice
+#undef snd_ctl_elem_info_get_name
+#undef snd_ctl_elem_info_get_index
+#undef snd_ctl_elem_info_set_id
+#undef snd_ctl_elem_info_set_numid
+#undef snd_ctl_elem_info_set_interface
+#undef snd_ctl_elem_info_set_device
+#undef snd_ctl_elem_info_set_subdevice
+#undef snd_ctl_elem_info_set_name
+#undef snd_ctl_elem_info_set_index
+#undef snd_ctl_add_integer_elem_set
+#undef snd_ctl_add_integer64_elem_set
+#undef snd_ctl_add_boolean_elem_set
+#undef snd_ctl_add_enumerated_elem_set
+#undef snd_ctl_add_bytes_elem_set
+#undef snd_ctl_elem_add_integer
+#undef snd_ctl_elem_add_integer64
+#undef snd_ctl_elem_add_boolean
+#undef snd_ctl_elem_add_enumerated
+#undef snd_ctl_elem_add_iec958
+#undef snd_ctl_elem_remove
+#undef snd_ctl_elem_value_sizeof
+#undef snd_ctl_elem_value_malloc
+#undef snd_ctl_elem_value_free
+#undef snd_ctl_elem_value_clear
+#undef snd_ctl_elem_value_copy
+#undef snd_ctl_elem_value_compare
+#undef snd_ctl_elem_value_get_id
+#undef snd_ctl_elem_value_get_numid
+#undef snd_ctl_elem_value_get_interface
+#undef snd_ctl_elem_value_get_device
+#undef snd_ctl_elem_value_get_subdevice
+#undef snd_ctl_elem_value_get_name
+#undef snd_ctl_elem_value_get_index
+#undef snd_ctl_elem_value_set_id
+#undef snd_ctl_elem_value_set_numid
+#undef snd_ctl_elem_value_set_interface
+#undef snd_ctl_elem_value_set_device
+#undef snd_ctl_elem_value_set_subdevice
+#undef snd_ctl_elem_value_set_name
+#undef snd_ctl_elem_value_set_index
+#undef snd_ctl_elem_value_get_boolean
+#undef snd_ctl_elem_value_get_integer
+#undef snd_ctl_elem_value_get_integer64
+#undef snd_ctl_elem_value_get_enumerated
+#undef snd_ctl_elem_value_get_byte
+#undef snd_ctl_elem_value_set_boolean
+#undef snd_ctl_elem_value_set_integer
+#undef snd_ctl_elem_value_set_integer64
+#undef snd_ctl_elem_value_set_enumerated
+#undef snd_ctl_elem_value_set_byte
+#undef snd_ctl_elem_set_bytes
+#undef snd_ctl_elem_value_get_bytes
+#undef snd_ctl_elem_value_get_iec958
+#undef snd_ctl_elem_value_set_iec958
+#undef snd_tlv_parse_dB_info
+#undef snd_tlv_get_dB_range
+#undef snd_tlv_convert_to_dB
+#undef snd_tlv_convert_from_dB
+#undef snd_ctl_get_dB_range
+#undef snd_ctl_convert_to_dB
+#undef snd_ctl_convert_from_dB
+#undef snd_hctl_compare_fast
+#undef snd_hctl_open
+#undef snd_hctl_open_ctl
+#undef snd_hctl_close
+#undef snd_hctl_nonblock
+#undef snd_hctl_poll_descriptors_count
+#undef snd_hctl_poll_descriptors
+#undef snd_hctl_poll_descriptors_revents
+#undef snd_hctl_get_count
+#undef snd_hctl_set_compare
+#undef snd_hctl_first_elem
+#undef snd_hctl_last_elem
+#undef snd_hctl_find_elem
+#undef snd_hctl_set_callback
+#undef snd_hctl_set_callback_private
+#undef snd_hctl_get_callback_private
+#undef snd_hctl_load
+#undef snd_hctl_free
+#undef snd_hctl_handle_events
+#undef snd_hctl_name
+#undef snd_hctl_wait
+#undef snd_hctl_ctl
+#undef snd_hctl_elem_next
+#undef snd_hctl_elem_prev
+#undef snd_hctl_elem_info
+#undef snd_hctl_elem_read
+#undef snd_hctl_elem_write
+#undef snd_hctl_elem_tlv_read
+#undef snd_hctl_elem_tlv_write
+#undef snd_hctl_elem_tlv_command
+#undef snd_hctl_elem_get_hctl
+#undef snd_hctl_elem_get_id
+#undef snd_hctl_elem_get_numid
+#undef snd_hctl_elem_get_interface
+#undef snd_hctl_elem_get_device
+#undef snd_hctl_elem_get_subdevice
+#undef snd_hctl_elem_get_name
+#undef snd_hctl_elem_get_index
+#undef snd_hctl_elem_set_callback
+#undef snd_hctl_elem_get_callback_private
+#undef snd_hctl_elem_set_callback_private
+#undef snd_sctl_build
+#undef snd_sctl_free
+#undef snd_sctl_install
+#undef snd_sctl_remove
+#undef snd_mixer_open
+#undef snd_mixer_close
+#undef snd_mixer_first_elem
+#undef snd_mixer_last_elem
+#undef snd_mixer_handle_events
+#undef snd_mixer_attach
+#undef snd_mixer_attach_hctl
+#undef snd_mixer_detach
+#undef snd_mixer_detach_hctl
+#undef snd_mixer_get_hctl
+#undef snd_mixer_poll_descriptors_count
+#undef snd_mixer_poll_descriptors
+#undef snd_mixer_poll_descriptors_revents
+#undef snd_mixer_load
+#undef snd_mixer_free
+#undef snd_mixer_wait
+#undef snd_mixer_set_compare
+#undef snd_mixer_set_callback
+#undef snd_mixer_get_callback_private
+#undef snd_mixer_set_callback_private
+#undef snd_mixer_get_count
+#undef snd_mixer_class_unregister
+#undef snd_mixer_elem_next
+#undef snd_mixer_elem_prev
+#undef snd_mixer_elem_set_callback
+#undef snd_mixer_elem_get_callback_private
+#undef snd_mixer_elem_set_callback_private
+#undef snd_mixer_elem_get_type
+#undef snd_mixer_class_register
+#undef snd_mixer_elem_new
+#undef snd_mixer_elem_add
+#undef snd_mixer_elem_remove
+#undef snd_mixer_elem_free
+#undef snd_mixer_elem_info
+#undef snd_mixer_elem_value
+#undef snd_mixer_elem_attach
+#undef snd_mixer_elem_detach
+#undef snd_mixer_elem_empty
+#undef snd_mixer_elem_get_private
+#undef snd_mixer_class_sizeof
+#undef snd_mixer_class_malloc
+#undef snd_mixer_class_free
+#undef snd_mixer_class_copy
+#undef snd_mixer_class_get_mixer
+#undef snd_mixer_class_get_event
+#undef snd_mixer_class_get_private
+#undef snd_mixer_class_get_compare
+#undef snd_mixer_class_set_event
+#undef snd_mixer_class_set_private
+#undef snd_mixer_class_set_private_free
+#undef snd_mixer_class_set_compare
+#undef snd_mixer_selem_channel_name
+#undef snd_mixer_selem_register
+#undef snd_mixer_selem_get_id
+#undef snd_mixer_selem_get_name
+#undef snd_mixer_selem_get_index
+#undef snd_mixer_find_selem
+#undef snd_mixer_selem_is_active
+#undef snd_mixer_selem_is_playback_mono
+#undef snd_mixer_selem_has_playback_channel
+#undef snd_mixer_selem_is_capture_mono
+#undef snd_mixer_selem_has_capture_channel
+#undef snd_mixer_selem_get_capture_group
+#undef snd_mixer_selem_has_common_volume
+#undef snd_mixer_selem_has_playback_volume
+#undef snd_mixer_selem_has_playback_volume_joined
+#undef snd_mixer_selem_has_capture_volume
+#undef snd_mixer_selem_has_capture_volume_joined
+#undef snd_mixer_selem_has_common_switch
+#undef snd_mixer_selem_has_playback_switch
+#undef snd_mixer_selem_has_playback_switch_joined
+#undef snd_mixer_selem_has_capture_switch
+#undef snd_mixer_selem_has_capture_switch_joined
+#undef snd_mixer_selem_has_capture_switch_exclusive
+#undef snd_mixer_selem_ask_playback_vol_dB
+#undef snd_mixer_selem_ask_capture_vol_dB
+#undef snd_mixer_selem_ask_playback_dB_vol
+#undef snd_mixer_selem_ask_capture_dB_vol
+#undef snd_mixer_selem_get_playback_volume
+#undef snd_mixer_selem_get_capture_volume
+#undef snd_mixer_selem_get_playback_dB
+#undef snd_mixer_selem_get_capture_dB
+#undef snd_mixer_selem_get_playback_switch
+#undef snd_mixer_selem_get_capture_switch
+#undef snd_mixer_selem_set_playback_volume
+#undef snd_mixer_selem_set_capture_volume
+#undef snd_mixer_selem_set_playback_dB
+#undef snd_mixer_selem_set_capture_dB
+#undef snd_mixer_selem_set_playback_volume_all
+#undef snd_mixer_selem_set_capture_volume_all
+#undef snd_mixer_selem_set_playback_dB_all
+#undef snd_mixer_selem_set_capture_dB_all
+#undef snd_mixer_selem_set_playback_switch
+#undef snd_mixer_selem_set_capture_switch
+#undef snd_mixer_selem_set_playback_switch_all
+#undef snd_mixer_selem_set_capture_switch_all
+#undef snd_mixer_selem_get_playback_volume_range
+#undef snd_mixer_selem_get_playback_dB_range
+#undef snd_mixer_selem_set_playback_volume_range
+#undef snd_mixer_selem_get_capture_volume_range
+#undef snd_mixer_selem_get_capture_dB_range
+#undef snd_mixer_selem_set_capture_volume_range
+#undef snd_mixer_selem_is_enumerated
+#undef snd_mixer_selem_is_enum_playback
+#undef snd_mixer_selem_is_enum_capture
+#undef snd_mixer_selem_get_enum_items
+#undef snd_mixer_selem_get_enum_item_name
+#undef snd_mixer_selem_get_enum_item
+#undef snd_mixer_selem_set_enum_item
+#undef snd_mixer_selem_id_sizeof
+#undef snd_mixer_selem_id_malloc
+#undef snd_mixer_selem_id_free
+#undef snd_mixer_selem_id_copy
+#undef snd_mixer_selem_id_get_name
+#undef snd_mixer_selem_id_get_index
+#undef snd_mixer_selem_id_set_name
+#undef snd_mixer_selem_id_set_index
+#undef snd_mixer_selem_id_parse
+#undef snd_seq_open
+#undef snd_seq_open_lconf
+#undef snd_seq_name
+#undef snd_seq_type
+#undef snd_seq_close
+#undef snd_seq_poll_descriptors_count
+#undef snd_seq_poll_descriptors
+#undef snd_seq_poll_descriptors_revents
+#undef snd_seq_nonblock
+#undef snd_seq_client_id
+#undef snd_seq_get_output_buffer_size
+#undef snd_seq_get_input_buffer_size
+#undef snd_seq_set_output_buffer_size
+#undef snd_seq_set_input_buffer_size
+#undef snd_seq_system_info_sizeof
+#undef snd_seq_system_info_malloc
+#undef snd_seq_system_info_free
+#undef snd_seq_system_info_copy
+#undef snd_seq_system_info_get_queues
+#undef snd_seq_system_info_get_clients
+#undef snd_seq_system_info_get_ports
+#undef snd_seq_system_info_get_channels
+#undef snd_seq_system_info_get_cur_clients
+#undef snd_seq_system_info_get_cur_queues
+#undef snd_seq_system_info
+#undef snd_seq_client_info_sizeof
+#undef snd_seq_client_info_malloc
+#undef snd_seq_client_info_free
+#undef snd_seq_client_info_copy
+#undef snd_seq_client_info_get_client
+#undef snd_seq_client_info_get_type
+#undef snd_seq_client_info_get_name
+#undef snd_seq_client_info_get_broadcast_filter
+#undef snd_seq_client_info_get_error_bounce
+#undef snd_seq_client_info_get_card
+#undef snd_seq_client_info_get_pid
+#undef snd_seq_client_info_get_event_filter
+#undef snd_seq_client_info_get_num_ports
+#undef snd_seq_client_info_get_event_lost
+#undef snd_seq_client_info_set_client
+#undef snd_seq_client_info_set_name
+#undef snd_seq_client_info_set_broadcast_filter
+#undef snd_seq_client_info_set_error_bounce
+#undef snd_seq_client_info_set_event_filter
+#undef snd_seq_client_info_event_filter_clear
+#undef snd_seq_client_info_event_filter_add
+#undef snd_seq_client_info_event_filter_del
+#undef snd_seq_client_info_event_filter_check
+#undef snd_seq_get_client_info
+#undef snd_seq_get_any_client_info
+#undef snd_seq_set_client_info
+#undef snd_seq_query_next_client
+#undef snd_seq_client_pool_sizeof
+#undef snd_seq_client_pool_malloc
+#undef snd_seq_client_pool_free
+#undef snd_seq_client_pool_copy
+#undef snd_seq_client_pool_get_client
+#undef snd_seq_client_pool_get_output_pool
+#undef snd_seq_client_pool_get_input_pool
+#undef snd_seq_client_pool_get_output_room
+#undef snd_seq_client_pool_get_output_free
+#undef snd_seq_client_pool_get_input_free
+#undef snd_seq_client_pool_set_output_pool
+#undef snd_seq_client_pool_set_input_pool
+#undef snd_seq_client_pool_set_output_room
+#undef snd_seq_get_client_pool
+#undef snd_seq_set_client_pool
+#undef snd_seq_port_info_sizeof
+#undef snd_seq_port_info_malloc
+#undef snd_seq_port_info_free
+#undef snd_seq_port_info_copy
+#undef snd_seq_port_info_get_client
+#undef snd_seq_port_info_get_port
+#undef snd_seq_port_info_get_addr
+#undef snd_seq_port_info_get_name
+#undef snd_seq_port_info_get_capability
+#undef snd_seq_port_info_get_type
+#undef snd_seq_port_info_get_midi_channels
+#undef snd_seq_port_info_get_midi_voices
+#undef snd_seq_port_info_get_synth_voices
+#undef snd_seq_port_info_get_read_use
+#undef snd_seq_port_info_get_write_use
+#undef snd_seq_port_info_get_port_specified
+#undef snd_seq_port_info_get_timestamping
+#undef snd_seq_port_info_get_timestamp_real
+#undef snd_seq_port_info_get_timestamp_queue
+#undef snd_seq_port_info_set_client
+#undef snd_seq_port_info_set_port
+#undef snd_seq_port_info_set_addr
+#undef snd_seq_port_info_set_name
+#undef snd_seq_port_info_set_capability
+#undef snd_seq_port_info_set_type
+#undef snd_seq_port_info_set_midi_channels
+#undef snd_seq_port_info_set_midi_voices
+#undef snd_seq_port_info_set_synth_voices
+#undef snd_seq_port_info_set_port_specified
+#undef snd_seq_port_info_set_timestamping
+#undef snd_seq_port_info_set_timestamp_real
+#undef snd_seq_port_info_set_timestamp_queue
+#undef snd_seq_create_port
+#undef snd_seq_delete_port
+#undef snd_seq_get_port_info
+#undef snd_seq_get_any_port_info
+#undef snd_seq_set_port_info
+#undef snd_seq_query_next_port
+#undef snd_seq_port_subscribe_sizeof
+#undef snd_seq_port_subscribe_malloc
+#undef snd_seq_port_subscribe_free
+#undef snd_seq_port_subscribe_copy
+#undef snd_seq_port_subscribe_get_sender
+#undef snd_seq_port_subscribe_get_dest
+#undef snd_seq_port_subscribe_get_queue
+#undef snd_seq_port_subscribe_get_exclusive
+#undef snd_seq_port_subscribe_get_time_update
+#undef snd_seq_port_subscribe_get_time_real
+#undef snd_seq_port_subscribe_set_sender
+#undef snd_seq_port_subscribe_set_dest
+#undef snd_seq_port_subscribe_set_queue
+#undef snd_seq_port_subscribe_set_exclusive
+#undef snd_seq_port_subscribe_set_time_update
+#undef snd_seq_port_subscribe_set_time_real
+#undef snd_seq_get_port_subscription
+#undef snd_seq_subscribe_port
+#undef snd_seq_unsubscribe_port
+#undef snd_seq_query_subscribe_sizeof
+#undef snd_seq_query_subscribe_malloc
+#undef snd_seq_query_subscribe_free
+#undef snd_seq_query_subscribe_copy
+#undef snd_seq_query_subscribe_get_client
+#undef snd_seq_query_subscribe_get_port
+#undef snd_seq_query_subscribe_get_root
+#undef snd_seq_query_subscribe_get_type
+#undef snd_seq_query_subscribe_get_index
+#undef snd_seq_query_subscribe_get_num_subs
+#undef snd_seq_query_subscribe_get_addr
+#undef snd_seq_query_subscribe_get_queue
+#undef snd_seq_query_subscribe_get_exclusive
+#undef snd_seq_query_subscribe_get_time_update
+#undef snd_seq_query_subscribe_get_time_real
+#undef snd_seq_query_subscribe_set_client
+#undef snd_seq_query_subscribe_set_port
+#undef snd_seq_query_subscribe_set_root
+#undef snd_seq_query_subscribe_set_type
+#undef snd_seq_query_subscribe_set_index
+#undef snd_seq_query_port_subscribers
+#undef snd_seq_queue_info_sizeof
+#undef snd_seq_queue_info_malloc
+#undef snd_seq_queue_info_free
+#undef snd_seq_queue_info_copy
+#undef snd_seq_queue_info_get_queue
+#undef snd_seq_queue_info_get_name
+#undef snd_seq_queue_info_get_owner
+#undef snd_seq_queue_info_get_locked
+#undef snd_seq_queue_info_get_flags
+#undef snd_seq_queue_info_set_name
+#undef snd_seq_queue_info_set_owner
+#undef snd_seq_queue_info_set_locked
+#undef snd_seq_queue_info_set_flags
+#undef snd_seq_create_queue
+#undef snd_seq_alloc_named_queue
+#undef snd_seq_alloc_queue
+#undef snd_seq_free_queue
+#undef snd_seq_get_queue_info
+#undef snd_seq_set_queue_info
+#undef snd_seq_query_named_queue
+#undef snd_seq_get_queue_usage
+#undef snd_seq_set_queue_usage
+#undef snd_seq_queue_status_sizeof
+#undef snd_seq_queue_status_malloc
+#undef snd_seq_queue_status_free
+#undef snd_seq_queue_status_copy
+#undef snd_seq_queue_status_get_queue
+#undef snd_seq_queue_status_get_events
+#undef snd_seq_queue_status_get_tick_time
+#undef snd_seq_queue_status_get_real_time
+#undef snd_seq_queue_status_get_status
+#undef snd_seq_get_queue_status
+#undef snd_seq_queue_tempo_sizeof
+#undef snd_seq_queue_tempo_malloc
+#undef snd_seq_queue_tempo_free
+#undef snd_seq_queue_tempo_copy
+#undef snd_seq_queue_tempo_get_queue
+#undef snd_seq_queue_tempo_get_tempo
+#undef snd_seq_queue_tempo_get_ppq
+#undef snd_seq_queue_tempo_get_skew
+#undef snd_seq_queue_tempo_get_skew_base
+#undef snd_seq_queue_tempo_set_tempo
+#undef snd_seq_queue_tempo_set_ppq
+#undef snd_seq_queue_tempo_set_skew
+#undef snd_seq_queue_tempo_set_skew_base
+#undef snd_seq_get_queue_tempo
+#undef snd_seq_set_queue_tempo
+#undef snd_seq_queue_timer_sizeof
+#undef snd_seq_queue_timer_malloc
+#undef snd_seq_queue_timer_free
+#undef snd_seq_queue_timer_copy
+#undef snd_seq_queue_timer_get_queue
+#undef snd_seq_queue_timer_get_type
+#undef snd_seq_queue_timer_get_id
+#undef snd_seq_queue_timer_get_resolution
+#undef snd_seq_queue_timer_set_type
+#undef snd_seq_queue_timer_set_id
+#undef snd_seq_queue_timer_set_resolution
+#undef snd_seq_get_queue_timer
+#undef snd_seq_set_queue_timer
+#undef snd_seq_free_event
+#undef snd_seq_event_length
+#undef snd_seq_event_output
+#undef snd_seq_event_output_buffer
+#undef snd_seq_event_output_direct
+#undef snd_seq_event_input
+#undef snd_seq_event_input_pending
+#undef snd_seq_drain_output
+#undef snd_seq_event_output_pending
+#undef snd_seq_extract_output
+#undef snd_seq_drop_output
+#undef snd_seq_drop_output_buffer
+#undef snd_seq_drop_input
+#undef snd_seq_drop_input_buffer
+#undef snd_seq_remove_events_sizeof
+#undef snd_seq_remove_events_malloc
+#undef snd_seq_remove_events_free
+#undef snd_seq_remove_events_copy
+#undef snd_seq_remove_events_get_condition
+#undef snd_seq_remove_events_get_queue
+#undef snd_seq_remove_events_get_time
+#undef snd_seq_remove_events_get_dest
+#undef snd_seq_remove_events_get_channel
+#undef snd_seq_remove_events_get_event_type
+#undef snd_seq_remove_events_get_tag
+#undef snd_seq_remove_events_set_condition
+#undef snd_seq_remove_events_set_queue
+#undef snd_seq_remove_events_set_time
+#undef snd_seq_remove_events_set_dest
+#undef snd_seq_remove_events_set_channel
+#undef snd_seq_remove_events_set_event_type
+#undef snd_seq_remove_events_set_tag
+#undef snd_seq_remove_events
+#undef snd_seq_set_bit
+#undef snd_seq_unset_bit
+#undef snd_seq_change_bit
+#undef snd_seq_get_bit
+#undef snd_seq_control_queue
+#undef snd_seq_create_simple_port
+#undef snd_seq_delete_simple_port
+#undef snd_seq_connect_from
+#undef snd_seq_connect_to
+#undef snd_seq_disconnect_from
+#undef snd_seq_disconnect_to
+#undef snd_seq_set_client_name
+#undef snd_seq_set_client_event_filter
+#undef snd_seq_set_client_pool_output
+#undef snd_seq_set_client_pool_output_room
+#undef snd_seq_set_client_pool_input
+#undef snd_seq_sync_output_queue
+#undef snd_seq_parse_address
+#undef snd_seq_reset_pool_output
+#undef snd_seq_reset_pool_input
+#undef snd_midi_event_new
+#undef snd_midi_event_resize_buffer
+#undef snd_midi_event_free
+#undef snd_midi_event_init
+#undef snd_midi_event_reset_encode
+#undef snd_midi_event_reset_decode
+#undef snd_midi_event_no_status
+#undef snd_midi_event_encode
+#undef snd_midi_event_encode_byte
+#undef snd_midi_event_decode
+#include <dlfcn.h>
+#include <stdio.h>
+const char* (*snd_asoundlib_version_dylibloader_wrapper_asound)( void);
+int (*snd_dlpath_dylibloader_wrapper_asound)( char*, size_t,const char*);
+void* (*snd_dlopen_dylibloader_wrapper_asound)(const char*, int, char*, size_t);
+void* (*snd_dlsym_dylibloader_wrapper_asound)( void*,const char*,const char*);
+int (*snd_dlclose_dylibloader_wrapper_asound)( void*);
+int (*snd_async_add_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, int, snd_async_callback_t, void*);
+int (*snd_async_del_handler_dylibloader_wrapper_asound)( snd_async_handler_t*);
+int (*snd_async_handler_get_fd_dylibloader_wrapper_asound)( snd_async_handler_t*);
+int (*snd_async_handler_get_signo_dylibloader_wrapper_asound)( snd_async_handler_t*);
+void* (*snd_async_handler_get_callback_private_dylibloader_wrapper_asound)( snd_async_handler_t*);
+struct snd_shm_area* (*snd_shm_area_create_dylibloader_wrapper_asound)( int, void*);
+struct snd_shm_area* (*snd_shm_area_share_dylibloader_wrapper_asound)(struct snd_shm_area*);
+int (*snd_shm_area_destroy_dylibloader_wrapper_asound)(struct snd_shm_area*);
+int (*snd_user_file_dylibloader_wrapper_asound)(const char*, char**);
+int (*snd_input_stdio_open_dylibloader_wrapper_asound)( snd_input_t**,const char*,const char*);
+int (*snd_input_stdio_attach_dylibloader_wrapper_asound)( snd_input_t**, FILE*, int);
+int (*snd_input_buffer_open_dylibloader_wrapper_asound)( snd_input_t**,const char*, ssize_t);
+int (*snd_input_close_dylibloader_wrapper_asound)( snd_input_t*);
+int (*snd_input_scanf_dylibloader_wrapper_asound)( snd_input_t*,const char*,...);
+char* (*snd_input_gets_dylibloader_wrapper_asound)( snd_input_t*, char*, size_t);
+int (*snd_input_getc_dylibloader_wrapper_asound)( snd_input_t*);
+int (*snd_input_ungetc_dylibloader_wrapper_asound)( snd_input_t*, int);
+int (*snd_output_stdio_open_dylibloader_wrapper_asound)( snd_output_t**,const char*,const char*);
+int (*snd_output_stdio_attach_dylibloader_wrapper_asound)( snd_output_t**, FILE*, int);
+int (*snd_output_buffer_open_dylibloader_wrapper_asound)( snd_output_t**);
+size_t (*snd_output_buffer_string_dylibloader_wrapper_asound)( snd_output_t*, char**);
+int (*snd_output_close_dylibloader_wrapper_asound)( snd_output_t*);
+int (*snd_output_printf_dylibloader_wrapper_asound)( snd_output_t*,const char*,...);
+int (*snd_output_vprintf_dylibloader_wrapper_asound)( snd_output_t*,const char*, va_list);
+int (*snd_output_puts_dylibloader_wrapper_asound)( snd_output_t*,const char*);
+int (*snd_output_putc_dylibloader_wrapper_asound)( snd_output_t*, int);
+int (*snd_output_flush_dylibloader_wrapper_asound)( snd_output_t*);
+const char* (*snd_strerror_dylibloader_wrapper_asound)( int);
+int (*snd_lib_error_set_handler_dylibloader_wrapper_asound)( snd_lib_error_handler_t);
+snd_local_error_handler_t (*snd_lib_error_set_local_dylibloader_wrapper_asound)( snd_local_error_handler_t);
+const char* (*snd_config_topdir_dylibloader_wrapper_asound)( void);
+int (*snd_config_top_dylibloader_wrapper_asound)( snd_config_t**);
+int (*snd_config_load_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*);
+int (*snd_config_load_override_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*);
+int (*snd_config_save_dylibloader_wrapper_asound)( snd_config_t*, snd_output_t*);
+int (*snd_config_update_dylibloader_wrapper_asound)( void);
+int (*snd_config_update_r_dylibloader_wrapper_asound)( snd_config_t**, snd_config_update_t**,const char*);
+int (*snd_config_update_free_dylibloader_wrapper_asound)( snd_config_update_t*);
+int (*snd_config_update_free_global_dylibloader_wrapper_asound)( void);
+int (*snd_config_update_ref_dylibloader_wrapper_asound)( snd_config_t**);
+void (*snd_config_ref_dylibloader_wrapper_asound)( snd_config_t*);
+void (*snd_config_unref_dylibloader_wrapper_asound)( snd_config_t*);
+int (*snd_config_search_dylibloader_wrapper_asound)( snd_config_t*,const char*, snd_config_t**);
+int (*snd_config_searchv_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t**,...);
+int (*snd_config_search_definition_dylibloader_wrapper_asound)( snd_config_t*,const char*,const char*, snd_config_t**);
+int (*snd_config_expand_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*,const char*, snd_config_t*, snd_config_t**);
+int (*snd_config_evaluate_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*, snd_config_t*, snd_config_t**);
+int (*snd_config_add_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
+int (*snd_config_add_before_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
+int (*snd_config_add_after_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
+int (*snd_config_remove_dylibloader_wrapper_asound)( snd_config_t*);
+int (*snd_config_delete_dylibloader_wrapper_asound)( snd_config_t*);
+int (*snd_config_delete_compound_members_dylibloader_wrapper_asound)(const snd_config_t*);
+int (*snd_config_copy_dylibloader_wrapper_asound)( snd_config_t**, snd_config_t*);
+int (*snd_config_make_dylibloader_wrapper_asound)( snd_config_t**,const char*, snd_config_type_t);
+int (*snd_config_make_integer_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+int (*snd_config_make_integer64_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+int (*snd_config_make_real_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+int (*snd_config_make_string_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+int (*snd_config_make_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+int (*snd_config_make_compound_dylibloader_wrapper_asound)( snd_config_t**,const char*, int);
+int (*snd_config_imake_integer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const long);
+int (*snd_config_imake_integer64_dylibloader_wrapper_asound)( snd_config_t**,const char*,const long long);
+int (*snd_config_imake_real_dylibloader_wrapper_asound)( snd_config_t**,const char*,const double);
+int (*snd_config_imake_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*);
+int (*snd_config_imake_safe_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*);
+int (*snd_config_imake_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const void*);
+snd_config_type_t (*snd_config_get_type_dylibloader_wrapper_asound)(const snd_config_t*);
+int (*snd_config_is_array_dylibloader_wrapper_asound)(const snd_config_t*);
+int (*snd_config_set_id_dylibloader_wrapper_asound)( snd_config_t*,const char*);
+int (*snd_config_set_integer_dylibloader_wrapper_asound)( snd_config_t*, long);
+int (*snd_config_set_integer64_dylibloader_wrapper_asound)( snd_config_t*, long long);
+int (*snd_config_set_real_dylibloader_wrapper_asound)( snd_config_t*, double);
+int (*snd_config_set_string_dylibloader_wrapper_asound)( snd_config_t*,const char*);
+int (*snd_config_set_ascii_dylibloader_wrapper_asound)( snd_config_t*,const char*);
+int (*snd_config_set_pointer_dylibloader_wrapper_asound)( snd_config_t*,const void*);
+int (*snd_config_get_id_dylibloader_wrapper_asound)(const snd_config_t*,const char**);
+int (*snd_config_get_integer_dylibloader_wrapper_asound)(const snd_config_t*, long*);
+int (*snd_config_get_integer64_dylibloader_wrapper_asound)(const snd_config_t*, long long*);
+int (*snd_config_get_real_dylibloader_wrapper_asound)(const snd_config_t*, double*);
+int (*snd_config_get_ireal_dylibloader_wrapper_asound)(const snd_config_t*, double*);
+int (*snd_config_get_string_dylibloader_wrapper_asound)(const snd_config_t*,const char**);
+int (*snd_config_get_ascii_dylibloader_wrapper_asound)(const snd_config_t*, char**);
+int (*snd_config_get_pointer_dylibloader_wrapper_asound)(const snd_config_t*,const void**);
+int (*snd_config_test_id_dylibloader_wrapper_asound)(const snd_config_t*,const char*);
+snd_config_iterator_t (*snd_config_iterator_first_dylibloader_wrapper_asound)(const snd_config_t*);
+snd_config_iterator_t (*snd_config_iterator_next_dylibloader_wrapper_asound)(const snd_config_iterator_t);
+snd_config_iterator_t (*snd_config_iterator_end_dylibloader_wrapper_asound)(const snd_config_t*);
+snd_config_t* (*snd_config_iterator_entry_dylibloader_wrapper_asound)(const snd_config_iterator_t);
+int (*snd_config_get_bool_ascii_dylibloader_wrapper_asound)(const char*);
+int (*snd_config_get_bool_dylibloader_wrapper_asound)(const snd_config_t*);
+int (*snd_config_get_ctl_iface_ascii_dylibloader_wrapper_asound)(const char*);
+int (*snd_config_get_ctl_iface_dylibloader_wrapper_asound)(const snd_config_t*);
+int (*snd_names_list_dylibloader_wrapper_asound)(const char*, snd_devname_t**);
+void (*snd_names_list_free_dylibloader_wrapper_asound)( snd_devname_t*);
+int (*snd_pcm_open_dylibloader_wrapper_asound)( snd_pcm_t**,const char*, snd_pcm_stream_t, int);
+int (*snd_pcm_open_lconf_dylibloader_wrapper_asound)( snd_pcm_t**,const char*, snd_pcm_stream_t, int, snd_config_t*);
+int (*snd_pcm_open_fallback_dylibloader_wrapper_asound)( snd_pcm_t**, snd_config_t*,const char*,const char*, snd_pcm_stream_t, int);
+int (*snd_pcm_close_dylibloader_wrapper_asound)( snd_pcm_t*);
+const char* (*snd_pcm_name_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_type_t (*snd_pcm_type_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_stream_t (*snd_pcm_stream_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_poll_descriptors_count_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_poll_descriptors_dylibloader_wrapper_asound)( snd_pcm_t*,struct pollfd*, unsigned int);
+int (*snd_pcm_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_pcm_t*,struct pollfd*, unsigned int, unsigned short*);
+int (*snd_pcm_nonblock_dylibloader_wrapper_asound)( snd_pcm_t*, int);
+int (*snd_async_add_pcm_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_pcm_t*, snd_async_callback_t, void*);
+snd_pcm_t* (*snd_async_handler_get_pcm_dylibloader_wrapper_asound)( snd_async_handler_t*);
+int (*snd_pcm_info_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_info_t*);
+int (*snd_pcm_hw_params_current_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_free_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_sw_params_current_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*);
+int (*snd_pcm_sw_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*);
+int (*snd_pcm_prepare_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_reset_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_status_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_status_t*);
+int (*snd_pcm_start_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_drop_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_drain_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_pause_dylibloader_wrapper_asound)( snd_pcm_t*, int);
+snd_pcm_state_t (*snd_pcm_state_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_hwsync_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_delay_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t*);
+int (*snd_pcm_resume_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_htimestamp_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t*, snd_htimestamp_t*);
+snd_pcm_sframes_t (*snd_pcm_avail_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_sframes_t (*snd_pcm_avail_update_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_avail_delay_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t*, snd_pcm_sframes_t*);
+snd_pcm_sframes_t (*snd_pcm_rewindable_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_sframes_t (*snd_pcm_rewind_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_forwardable_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_sframes_t (*snd_pcm_forward_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_writei_dylibloader_wrapper_asound)( snd_pcm_t*,const void*, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_readi_dylibloader_wrapper_asound)( snd_pcm_t*, void*, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_writen_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_readn_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t);
+int (*snd_pcm_wait_dylibloader_wrapper_asound)( snd_pcm_t*, int);
+int (*snd_pcm_link_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_t*);
+int (*snd_pcm_unlink_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_chmap_query_t** (*snd_pcm_query_chmaps_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_chmap_query_t** (*snd_pcm_query_chmaps_from_hw_dylibloader_wrapper_asound)( int, int, int, snd_pcm_stream_t);
+void (*snd_pcm_free_chmaps_dylibloader_wrapper_asound)( snd_pcm_chmap_query_t**);
+snd_pcm_chmap_t* (*snd_pcm_get_chmap_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_set_chmap_dylibloader_wrapper_asound)( snd_pcm_t*,const snd_pcm_chmap_t*);
+const char* (*snd_pcm_chmap_type_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_type);
+const char* (*snd_pcm_chmap_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_position);
+const char* (*snd_pcm_chmap_long_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_position);
+int (*snd_pcm_chmap_print_dylibloader_wrapper_asound)(const snd_pcm_chmap_t*, size_t, char*);
+unsigned int (*snd_pcm_chmap_from_string_dylibloader_wrapper_asound)(const char*);
+snd_pcm_chmap_t* (*snd_pcm_chmap_parse_string_dylibloader_wrapper_asound)(const char*);
+int (*snd_pcm_recover_dylibloader_wrapper_asound)( snd_pcm_t*, int, int);
+int (*snd_pcm_set_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_format_t, snd_pcm_access_t, unsigned int, unsigned int, int, unsigned int);
+int (*snd_pcm_get_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t*, snd_pcm_uframes_t*);
+size_t (*snd_pcm_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_pcm_info_malloc_dylibloader_wrapper_asound)( snd_pcm_info_t**);
+void (*snd_pcm_info_free_dylibloader_wrapper_asound)( snd_pcm_info_t*);
+void (*snd_pcm_info_copy_dylibloader_wrapper_asound)( snd_pcm_info_t*,const snd_pcm_info_t*);
+unsigned int (*snd_pcm_info_get_device_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+unsigned int (*snd_pcm_info_get_subdevice_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+snd_pcm_stream_t (*snd_pcm_info_get_stream_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+int (*snd_pcm_info_get_card_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+const char* (*snd_pcm_info_get_id_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+const char* (*snd_pcm_info_get_name_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+const char* (*snd_pcm_info_get_subdevice_name_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+snd_pcm_class_t (*snd_pcm_info_get_class_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+snd_pcm_subclass_t (*snd_pcm_info_get_subclass_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+unsigned int (*snd_pcm_info_get_subdevices_count_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+unsigned int (*snd_pcm_info_get_subdevices_avail_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+snd_pcm_sync_id_t (*snd_pcm_info_get_sync_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+void (*snd_pcm_info_set_device_dylibloader_wrapper_asound)( snd_pcm_info_t*, unsigned int);
+void (*snd_pcm_info_set_subdevice_dylibloader_wrapper_asound)( snd_pcm_info_t*, unsigned int);
+void (*snd_pcm_info_set_stream_dylibloader_wrapper_asound)( snd_pcm_info_t*, snd_pcm_stream_t);
+int (*snd_pcm_hw_params_any_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_is_double_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_is_batch_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_is_block_transfer_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_is_monotonic_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_can_overrange_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_can_pause_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_can_resume_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_is_half_duplex_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_is_joint_duplex_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_can_sync_start_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_supports_audio_ts_type_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, int);
+int (*snd_pcm_hw_params_get_rate_numden_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, unsigned int*);
+int (*snd_pcm_hw_params_get_sbits_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_get_fifo_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+size_t (*snd_pcm_hw_params_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_pcm_hw_params_malloc_dylibloader_wrapper_asound)( snd_pcm_hw_params_t**);
+void (*snd_pcm_hw_params_free_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*);
+void (*snd_pcm_hw_params_copy_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*,const snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_get_access_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_access_t*);
+int (*snd_pcm_hw_params_test_access_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t);
+int (*snd_pcm_hw_params_set_access_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t);
+int (*snd_pcm_hw_params_set_access_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t*);
+int (*snd_pcm_hw_params_set_access_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t*);
+int (*snd_pcm_hw_params_set_access_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_mask_t*);
+int (*snd_pcm_hw_params_get_access_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_access_mask_t*);
+int (*snd_pcm_hw_params_get_format_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_format_t*);
+int (*snd_pcm_hw_params_test_format_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t);
+int (*snd_pcm_hw_params_set_format_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t);
+int (*snd_pcm_hw_params_set_format_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t*);
+int (*snd_pcm_hw_params_set_format_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t*);
+int (*snd_pcm_hw_params_set_format_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_mask_t*);
+void (*snd_pcm_hw_params_get_format_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_format_mask_t*);
+int (*snd_pcm_hw_params_get_subformat_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_subformat_t*);
+int (*snd_pcm_hw_params_test_subformat_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t);
+int (*snd_pcm_hw_params_set_subformat_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t);
+int (*snd_pcm_hw_params_set_subformat_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t*);
+int (*snd_pcm_hw_params_set_subformat_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t*);
+int (*snd_pcm_hw_params_set_subformat_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_mask_t*);
+void (*snd_pcm_hw_params_get_subformat_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_subformat_mask_t*);
+int (*snd_pcm_hw_params_get_channels_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_get_channels_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_get_channels_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_test_channels_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+int (*snd_pcm_hw_params_set_channels_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+int (*snd_pcm_hw_params_set_channels_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_set_channels_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_set_channels_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, unsigned int*);
+int (*snd_pcm_hw_params_set_channels_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_set_channels_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_set_channels_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_get_rate_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_rate_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_rate_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_test_rate_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_rate_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_rate_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_rate_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_rate_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_rate_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_rate_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_rate_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_rate_resample_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+int (*snd_pcm_hw_params_get_rate_resample_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_set_export_buffer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+int (*snd_pcm_hw_params_get_export_buffer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_set_period_wakeup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+int (*snd_pcm_hw_params_get_period_wakeup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_get_period_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_period_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_period_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_test_period_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_period_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_period_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_period_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_period_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_period_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_period_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_period_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_period_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_get_period_size_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_get_period_size_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_test_period_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t, int);
+int (*snd_pcm_hw_params_set_period_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t, int);
+int (*snd_pcm_hw_params_set_period_size_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_set_period_size_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_set_period_size_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_set_period_size_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_set_period_size_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_set_period_size_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+int (*snd_pcm_hw_params_set_period_size_integer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_get_periods_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_periods_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_periods_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_test_periods_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_periods_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_periods_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_periods_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_periods_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_periods_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_periods_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_periods_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_periods_integer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+int (*snd_pcm_hw_params_get_buffer_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_buffer_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_buffer_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_test_buffer_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_buffer_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_buffer_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_buffer_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_buffer_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_buffer_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_buffer_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_buffer_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_get_buffer_size_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_get_buffer_size_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_test_buffer_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t);
+int (*snd_pcm_hw_params_set_buffer_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t);
+int (*snd_pcm_hw_params_set_buffer_size_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_set_buffer_size_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_set_buffer_size_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_set_buffer_size_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_set_buffer_size_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_hw_params_get_min_align_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+size_t (*snd_pcm_sw_params_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_pcm_sw_params_malloc_dylibloader_wrapper_asound)( snd_pcm_sw_params_t**);
+void (*snd_pcm_sw_params_free_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*);
+void (*snd_pcm_sw_params_copy_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*,const snd_pcm_sw_params_t*);
+int (*snd_pcm_sw_params_get_boundary_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_sw_params_set_tstamp_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_tstamp_t);
+int (*snd_pcm_sw_params_get_tstamp_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_tstamp_t*);
+int (*snd_pcm_sw_params_set_avail_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+int (*snd_pcm_sw_params_get_avail_min_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_sw_params_set_period_event_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, int);
+int (*snd_pcm_sw_params_get_period_event_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, int*);
+int (*snd_pcm_sw_params_set_start_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+int (*snd_pcm_sw_params_get_start_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_sw_params_set_stop_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+int (*snd_pcm_sw_params_get_stop_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_sw_params_set_silence_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+int (*snd_pcm_sw_params_get_silence_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_sw_params_set_silence_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+int (*snd_pcm_sw_params_get_silence_size_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+size_t (*snd_pcm_access_mask_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_pcm_access_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_access_mask_t**);
+void (*snd_pcm_access_mask_free_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*);
+void (*snd_pcm_access_mask_copy_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*,const snd_pcm_access_mask_t*);
+void (*snd_pcm_access_mask_none_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*);
+void (*snd_pcm_access_mask_any_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*);
+int (*snd_pcm_access_mask_test_dylibloader_wrapper_asound)(const snd_pcm_access_mask_t*, snd_pcm_access_t);
+int (*snd_pcm_access_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_access_mask_t*);
+void (*snd_pcm_access_mask_set_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*, snd_pcm_access_t);
+void (*snd_pcm_access_mask_reset_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*, snd_pcm_access_t);
+size_t (*snd_pcm_format_mask_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_pcm_format_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_format_mask_t**);
+void (*snd_pcm_format_mask_free_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*);
+void (*snd_pcm_format_mask_copy_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*,const snd_pcm_format_mask_t*);
+void (*snd_pcm_format_mask_none_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*);
+void (*snd_pcm_format_mask_any_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*);
+int (*snd_pcm_format_mask_test_dylibloader_wrapper_asound)(const snd_pcm_format_mask_t*, snd_pcm_format_t);
+int (*snd_pcm_format_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_format_mask_t*);
+void (*snd_pcm_format_mask_set_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*, snd_pcm_format_t);
+void (*snd_pcm_format_mask_reset_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*, snd_pcm_format_t);
+size_t (*snd_pcm_subformat_mask_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_pcm_subformat_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t**);
+void (*snd_pcm_subformat_mask_free_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*);
+void (*snd_pcm_subformat_mask_copy_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*,const snd_pcm_subformat_mask_t*);
+void (*snd_pcm_subformat_mask_none_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*);
+void (*snd_pcm_subformat_mask_any_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*);
+int (*snd_pcm_subformat_mask_test_dylibloader_wrapper_asound)(const snd_pcm_subformat_mask_t*, snd_pcm_subformat_t);
+int (*snd_pcm_subformat_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_subformat_mask_t*);
+void (*snd_pcm_subformat_mask_set_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*, snd_pcm_subformat_t);
+void (*snd_pcm_subformat_mask_reset_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*, snd_pcm_subformat_t);
+size_t (*snd_pcm_status_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_pcm_status_malloc_dylibloader_wrapper_asound)( snd_pcm_status_t**);
+void (*snd_pcm_status_free_dylibloader_wrapper_asound)( snd_pcm_status_t*);
+void (*snd_pcm_status_copy_dylibloader_wrapper_asound)( snd_pcm_status_t*,const snd_pcm_status_t*);
+snd_pcm_state_t (*snd_pcm_status_get_state_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+void (*snd_pcm_status_get_trigger_tstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_timestamp_t*);
+void (*snd_pcm_status_get_trigger_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*);
+void (*snd_pcm_status_get_tstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_timestamp_t*);
+void (*snd_pcm_status_get_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*);
+void (*snd_pcm_status_get_audio_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*);
+void (*snd_pcm_status_get_driver_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*);
+snd_pcm_sframes_t (*snd_pcm_status_get_delay_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+snd_pcm_uframes_t (*snd_pcm_status_get_avail_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+snd_pcm_uframes_t (*snd_pcm_status_get_avail_max_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+snd_pcm_uframes_t (*snd_pcm_status_get_overrange_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+const char* (*snd_pcm_type_name_dylibloader_wrapper_asound)( snd_pcm_type_t);
+const char* (*snd_pcm_stream_name_dylibloader_wrapper_asound)(const snd_pcm_stream_t);
+const char* (*snd_pcm_access_name_dylibloader_wrapper_asound)(const snd_pcm_access_t);
+const char* (*snd_pcm_format_name_dylibloader_wrapper_asound)(const snd_pcm_format_t);
+const char* (*snd_pcm_format_description_dylibloader_wrapper_asound)(const snd_pcm_format_t);
+const char* (*snd_pcm_subformat_name_dylibloader_wrapper_asound)(const snd_pcm_subformat_t);
+const char* (*snd_pcm_subformat_description_dylibloader_wrapper_asound)(const snd_pcm_subformat_t);
+snd_pcm_format_t (*snd_pcm_format_value_dylibloader_wrapper_asound)(const char*);
+const char* (*snd_pcm_tstamp_mode_name_dylibloader_wrapper_asound)(const snd_pcm_tstamp_t);
+const char* (*snd_pcm_state_name_dylibloader_wrapper_asound)(const snd_pcm_state_t);
+int (*snd_pcm_dump_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*);
+int (*snd_pcm_dump_hw_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*);
+int (*snd_pcm_dump_sw_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*);
+int (*snd_pcm_dump_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*);
+int (*snd_pcm_hw_params_dump_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_output_t*);
+int (*snd_pcm_sw_params_dump_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*, snd_output_t*);
+int (*snd_pcm_status_dump_dylibloader_wrapper_asound)( snd_pcm_status_t*, snd_output_t*);
+int (*snd_pcm_mmap_begin_dylibloader_wrapper_asound)( snd_pcm_t*,const snd_pcm_channel_area_t**, snd_pcm_uframes_t*, snd_pcm_uframes_t*);
+snd_pcm_sframes_t (*snd_pcm_mmap_commit_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_mmap_writei_dylibloader_wrapper_asound)( snd_pcm_t*,const void*, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_mmap_readi_dylibloader_wrapper_asound)( snd_pcm_t*, void*, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_mmap_writen_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t);
+snd_pcm_sframes_t (*snd_pcm_mmap_readn_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t);
+int (*snd_pcm_format_signed_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_unsigned_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_linear_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_float_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_little_endian_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_big_endian_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_cpu_endian_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_width_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_physical_width_dylibloader_wrapper_asound)( snd_pcm_format_t);
+snd_pcm_format_t (*snd_pcm_build_linear_format_dylibloader_wrapper_asound)( int, int, int, int);
+ssize_t (*snd_pcm_format_size_dylibloader_wrapper_asound)( snd_pcm_format_t, size_t);
+uint8_t (*snd_pcm_format_silence_dylibloader_wrapper_asound)( snd_pcm_format_t);
+uint16_t (*snd_pcm_format_silence_16_dylibloader_wrapper_asound)( snd_pcm_format_t);
+uint32_t (*snd_pcm_format_silence_32_dylibloader_wrapper_asound)( snd_pcm_format_t);
+uint64_t (*snd_pcm_format_silence_64_dylibloader_wrapper_asound)( snd_pcm_format_t);
+int (*snd_pcm_format_set_silence_dylibloader_wrapper_asound)( snd_pcm_format_t, void*, unsigned int);
+snd_pcm_sframes_t (*snd_pcm_bytes_to_frames_dylibloader_wrapper_asound)( snd_pcm_t*, ssize_t);
+ssize_t (*snd_pcm_frames_to_bytes_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t);
+long (*snd_pcm_bytes_to_samples_dylibloader_wrapper_asound)( snd_pcm_t*, ssize_t);
+ssize_t (*snd_pcm_samples_to_bytes_dylibloader_wrapper_asound)( snd_pcm_t*, long);
+int (*snd_pcm_area_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t);
+int (*snd_pcm_areas_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t);
+int (*snd_pcm_area_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t);
+int (*snd_pcm_areas_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t);
+int (*snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const unsigned int, snd_pcm_uframes_t,const snd_pcm_format_t);
+snd_pcm_t* (*snd_pcm_hook_get_pcm_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
+void* (*snd_pcm_hook_get_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
+void (*snd_pcm_hook_set_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*, void*);
+int (*snd_pcm_hook_add_dylibloader_wrapper_asound)( snd_pcm_hook_t**, snd_pcm_t*, snd_pcm_hook_type_t, snd_pcm_hook_func_t, void*);
+int (*snd_pcm_hook_remove_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
+snd_pcm_uframes_t (*snd_pcm_meter_get_bufsize_dylibloader_wrapper_asound)( snd_pcm_t*);
+unsigned int (*snd_pcm_meter_get_channels_dylibloader_wrapper_asound)( snd_pcm_t*);
+unsigned int (*snd_pcm_meter_get_rate_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_uframes_t (*snd_pcm_meter_get_now_dylibloader_wrapper_asound)( snd_pcm_t*);
+snd_pcm_uframes_t (*snd_pcm_meter_get_boundary_dylibloader_wrapper_asound)( snd_pcm_t*);
+int (*snd_pcm_meter_add_scope_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_scope_t*);
+snd_pcm_scope_t* (*snd_pcm_meter_search_scope_dylibloader_wrapper_asound)( snd_pcm_t*,const char*);
+int (*snd_pcm_scope_malloc_dylibloader_wrapper_asound)( snd_pcm_scope_t**);
+void (*snd_pcm_scope_set_ops_dylibloader_wrapper_asound)( snd_pcm_scope_t*,const snd_pcm_scope_ops_t*);
+void (*snd_pcm_scope_set_name_dylibloader_wrapper_asound)( snd_pcm_scope_t*,const char*);
+const char* (*snd_pcm_scope_get_name_dylibloader_wrapper_asound)( snd_pcm_scope_t*);
+void* (*snd_pcm_scope_get_callback_private_dylibloader_wrapper_asound)( snd_pcm_scope_t*);
+void (*snd_pcm_scope_set_callback_private_dylibloader_wrapper_asound)( snd_pcm_scope_t*, void*);
+int (*snd_pcm_scope_s16_open_dylibloader_wrapper_asound)( snd_pcm_t*,const char*, snd_pcm_scope_t**);
+int16_t* (*snd_pcm_scope_s16_get_channel_buffer_dylibloader_wrapper_asound)( snd_pcm_scope_t*, unsigned int);
+int (*snd_spcm_init_dylibloader_wrapper_asound)( snd_pcm_t*, unsigned int, unsigned int, snd_pcm_format_t, snd_pcm_subformat_t, snd_spcm_latency_t, snd_pcm_access_t, snd_spcm_xrun_type_t);
+int (*snd_spcm_init_duplex_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_t*, unsigned int, unsigned int, snd_pcm_format_t, snd_pcm_subformat_t, snd_spcm_latency_t, snd_pcm_access_t, snd_spcm_xrun_type_t, snd_spcm_duplex_type_t);
+int (*snd_spcm_init_get_params_dylibloader_wrapper_asound)( snd_pcm_t*, unsigned int*, snd_pcm_uframes_t*, snd_pcm_uframes_t*);
+const char* (*snd_pcm_start_mode_name_dylibloader_wrapper_asound)( snd_pcm_start_t);
+const char* (*snd_pcm_xrun_mode_name_dylibloader_wrapper_asound)( snd_pcm_xrun_t);
+int (*snd_pcm_sw_params_set_start_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_start_t);
+snd_pcm_start_t (*snd_pcm_sw_params_get_start_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*);
+int (*snd_pcm_sw_params_set_xrun_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_xrun_t);
+snd_pcm_xrun_t (*snd_pcm_sw_params_get_xrun_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*);
+int (*snd_pcm_sw_params_set_xfer_align_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+int (*snd_pcm_sw_params_get_xfer_align_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+int (*snd_pcm_sw_params_set_sleep_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, unsigned int);
+int (*snd_pcm_sw_params_get_sleep_min_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, unsigned int*);
+int (*snd_pcm_hw_params_get_tick_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_tick_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_get_tick_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_test_tick_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_tick_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+int (*snd_pcm_hw_params_set_tick_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_tick_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_tick_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_tick_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_tick_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_pcm_hw_params_set_tick_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+int (*snd_rawmidi_open_dylibloader_wrapper_asound)( snd_rawmidi_t**, snd_rawmidi_t**,const char*, int);
+int (*snd_rawmidi_open_lconf_dylibloader_wrapper_asound)( snd_rawmidi_t**, snd_rawmidi_t**,const char*, int, snd_config_t*);
+int (*snd_rawmidi_close_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+int (*snd_rawmidi_poll_descriptors_count_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+int (*snd_rawmidi_poll_descriptors_dylibloader_wrapper_asound)( snd_rawmidi_t*,struct pollfd*, unsigned int);
+int (*snd_rawmidi_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_rawmidi_t*,struct pollfd*, unsigned int, unsigned short*);
+int (*snd_rawmidi_nonblock_dylibloader_wrapper_asound)( snd_rawmidi_t*, int);
+size_t (*snd_rawmidi_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_rawmidi_info_malloc_dylibloader_wrapper_asound)( snd_rawmidi_info_t**);
+void (*snd_rawmidi_info_free_dylibloader_wrapper_asound)( snd_rawmidi_info_t*);
+void (*snd_rawmidi_info_copy_dylibloader_wrapper_asound)( snd_rawmidi_info_t*,const snd_rawmidi_info_t*);
+unsigned int (*snd_rawmidi_info_get_device_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+unsigned int (*snd_rawmidi_info_get_subdevice_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+snd_rawmidi_stream_t (*snd_rawmidi_info_get_stream_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+int (*snd_rawmidi_info_get_card_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+unsigned int (*snd_rawmidi_info_get_flags_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+const char* (*snd_rawmidi_info_get_id_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+const char* (*snd_rawmidi_info_get_name_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+const char* (*snd_rawmidi_info_get_subdevice_name_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+unsigned int (*snd_rawmidi_info_get_subdevices_count_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+unsigned int (*snd_rawmidi_info_get_subdevices_avail_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+void (*snd_rawmidi_info_set_device_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, unsigned int);
+void (*snd_rawmidi_info_set_subdevice_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, unsigned int);
+void (*snd_rawmidi_info_set_stream_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, snd_rawmidi_stream_t);
+int (*snd_rawmidi_info_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_info_t*);
+size_t (*snd_rawmidi_params_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_rawmidi_params_malloc_dylibloader_wrapper_asound)( snd_rawmidi_params_t**);
+void (*snd_rawmidi_params_free_dylibloader_wrapper_asound)( snd_rawmidi_params_t*);
+void (*snd_rawmidi_params_copy_dylibloader_wrapper_asound)( snd_rawmidi_params_t*,const snd_rawmidi_params_t*);
+int (*snd_rawmidi_params_set_buffer_size_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, size_t);
+size_t (*snd_rawmidi_params_get_buffer_size_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*);
+int (*snd_rawmidi_params_set_avail_min_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, size_t);
+size_t (*snd_rawmidi_params_get_avail_min_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*);
+int (*snd_rawmidi_params_set_no_active_sensing_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, int);
+int (*snd_rawmidi_params_get_no_active_sensing_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*);
+int (*snd_rawmidi_params_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*);
+int (*snd_rawmidi_params_current_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*);
+size_t (*snd_rawmidi_status_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_rawmidi_status_malloc_dylibloader_wrapper_asound)( snd_rawmidi_status_t**);
+void (*snd_rawmidi_status_free_dylibloader_wrapper_asound)( snd_rawmidi_status_t*);
+void (*snd_rawmidi_status_copy_dylibloader_wrapper_asound)( snd_rawmidi_status_t*,const snd_rawmidi_status_t*);
+void (*snd_rawmidi_status_get_tstamp_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*, snd_htimestamp_t*);
+size_t (*snd_rawmidi_status_get_avail_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*);
+size_t (*snd_rawmidi_status_get_xruns_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*);
+int (*snd_rawmidi_status_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_status_t*);
+int (*snd_rawmidi_drain_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+int (*snd_rawmidi_drop_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+ssize_t (*snd_rawmidi_write_dylibloader_wrapper_asound)( snd_rawmidi_t*,const void*, size_t);
+ssize_t (*snd_rawmidi_read_dylibloader_wrapper_asound)( snd_rawmidi_t*, void*, size_t);
+const char* (*snd_rawmidi_name_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+snd_rawmidi_type_t (*snd_rawmidi_type_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+snd_rawmidi_stream_t (*snd_rawmidi_stream_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+int (*snd_timer_query_open_dylibloader_wrapper_asound)( snd_timer_query_t**,const char*, int);
+int (*snd_timer_query_open_lconf_dylibloader_wrapper_asound)( snd_timer_query_t**,const char*, int, snd_config_t*);
+int (*snd_timer_query_close_dylibloader_wrapper_asound)( snd_timer_query_t*);
+int (*snd_timer_query_next_device_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_id_t*);
+int (*snd_timer_query_info_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_ginfo_t*);
+int (*snd_timer_query_params_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_gparams_t*);
+int (*snd_timer_query_status_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_gstatus_t*);
+int (*snd_timer_open_dylibloader_wrapper_asound)( snd_timer_t**,const char*, int);
+int (*snd_timer_open_lconf_dylibloader_wrapper_asound)( snd_timer_t**,const char*, int, snd_config_t*);
+int (*snd_timer_close_dylibloader_wrapper_asound)( snd_timer_t*);
+int (*snd_async_add_timer_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_timer_t*, snd_async_callback_t, void*);
+snd_timer_t* (*snd_async_handler_get_timer_dylibloader_wrapper_asound)( snd_async_handler_t*);
+int (*snd_timer_poll_descriptors_count_dylibloader_wrapper_asound)( snd_timer_t*);
+int (*snd_timer_poll_descriptors_dylibloader_wrapper_asound)( snd_timer_t*,struct pollfd*, unsigned int);
+int (*snd_timer_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_timer_t*,struct pollfd*, unsigned int, unsigned short*);
+int (*snd_timer_info_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_info_t*);
+int (*snd_timer_params_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_params_t*);
+int (*snd_timer_status_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_status_t*);
+int (*snd_timer_start_dylibloader_wrapper_asound)( snd_timer_t*);
+int (*snd_timer_stop_dylibloader_wrapper_asound)( snd_timer_t*);
+int (*snd_timer_continue_dylibloader_wrapper_asound)( snd_timer_t*);
+ssize_t (*snd_timer_read_dylibloader_wrapper_asound)( snd_timer_t*, void*, size_t);
+size_t (*snd_timer_id_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_timer_id_malloc_dylibloader_wrapper_asound)( snd_timer_id_t**);
+void (*snd_timer_id_free_dylibloader_wrapper_asound)( snd_timer_id_t*);
+void (*snd_timer_id_copy_dylibloader_wrapper_asound)( snd_timer_id_t*,const snd_timer_id_t*);
+void (*snd_timer_id_set_class_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+int (*snd_timer_id_get_class_dylibloader_wrapper_asound)( snd_timer_id_t*);
+void (*snd_timer_id_set_sclass_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+int (*snd_timer_id_get_sclass_dylibloader_wrapper_asound)( snd_timer_id_t*);
+void (*snd_timer_id_set_card_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+int (*snd_timer_id_get_card_dylibloader_wrapper_asound)( snd_timer_id_t*);
+void (*snd_timer_id_set_device_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+int (*snd_timer_id_get_device_dylibloader_wrapper_asound)( snd_timer_id_t*);
+void (*snd_timer_id_set_subdevice_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+int (*snd_timer_id_get_subdevice_dylibloader_wrapper_asound)( snd_timer_id_t*);
+size_t (*snd_timer_ginfo_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_timer_ginfo_malloc_dylibloader_wrapper_asound)( snd_timer_ginfo_t**);
+void (*snd_timer_ginfo_free_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+void (*snd_timer_ginfo_copy_dylibloader_wrapper_asound)( snd_timer_ginfo_t*,const snd_timer_ginfo_t*);
+int (*snd_timer_ginfo_set_tid_dylibloader_wrapper_asound)( snd_timer_ginfo_t*, snd_timer_id_t*);
+snd_timer_id_t* (*snd_timer_ginfo_get_tid_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+unsigned int (*snd_timer_ginfo_get_flags_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+int (*snd_timer_ginfo_get_card_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+char* (*snd_timer_ginfo_get_id_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+char* (*snd_timer_ginfo_get_name_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+unsigned long (*snd_timer_ginfo_get_resolution_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+unsigned long (*snd_timer_ginfo_get_resolution_min_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+unsigned long (*snd_timer_ginfo_get_resolution_max_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+unsigned int (*snd_timer_ginfo_get_clients_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+size_t (*snd_timer_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_timer_info_malloc_dylibloader_wrapper_asound)( snd_timer_info_t**);
+void (*snd_timer_info_free_dylibloader_wrapper_asound)( snd_timer_info_t*);
+void (*snd_timer_info_copy_dylibloader_wrapper_asound)( snd_timer_info_t*,const snd_timer_info_t*);
+int (*snd_timer_info_is_slave_dylibloader_wrapper_asound)( snd_timer_info_t*);
+int (*snd_timer_info_get_card_dylibloader_wrapper_asound)( snd_timer_info_t*);
+const char* (*snd_timer_info_get_id_dylibloader_wrapper_asound)( snd_timer_info_t*);
+const char* (*snd_timer_info_get_name_dylibloader_wrapper_asound)( snd_timer_info_t*);
+long (*snd_timer_info_get_resolution_dylibloader_wrapper_asound)( snd_timer_info_t*);
+size_t (*snd_timer_params_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_timer_params_malloc_dylibloader_wrapper_asound)( snd_timer_params_t**);
+void (*snd_timer_params_free_dylibloader_wrapper_asound)( snd_timer_params_t*);
+void (*snd_timer_params_copy_dylibloader_wrapper_asound)( snd_timer_params_t*,const snd_timer_params_t*);
+int (*snd_timer_params_set_auto_start_dylibloader_wrapper_asound)( snd_timer_params_t*, int);
+int (*snd_timer_params_get_auto_start_dylibloader_wrapper_asound)( snd_timer_params_t*);
+int (*snd_timer_params_set_exclusive_dylibloader_wrapper_asound)( snd_timer_params_t*, int);
+int (*snd_timer_params_get_exclusive_dylibloader_wrapper_asound)( snd_timer_params_t*);
+int (*snd_timer_params_set_early_event_dylibloader_wrapper_asound)( snd_timer_params_t*, int);
+int (*snd_timer_params_get_early_event_dylibloader_wrapper_asound)( snd_timer_params_t*);
+void (*snd_timer_params_set_ticks_dylibloader_wrapper_asound)( snd_timer_params_t*, long);
+long (*snd_timer_params_get_ticks_dylibloader_wrapper_asound)( snd_timer_params_t*);
+void (*snd_timer_params_set_queue_size_dylibloader_wrapper_asound)( snd_timer_params_t*, long);
+long (*snd_timer_params_get_queue_size_dylibloader_wrapper_asound)( snd_timer_params_t*);
+void (*snd_timer_params_set_filter_dylibloader_wrapper_asound)( snd_timer_params_t*, unsigned int);
+unsigned int (*snd_timer_params_get_filter_dylibloader_wrapper_asound)( snd_timer_params_t*);
+size_t (*snd_timer_status_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_timer_status_malloc_dylibloader_wrapper_asound)( snd_timer_status_t**);
+void (*snd_timer_status_free_dylibloader_wrapper_asound)( snd_timer_status_t*);
+void (*snd_timer_status_copy_dylibloader_wrapper_asound)( snd_timer_status_t*,const snd_timer_status_t*);
+snd_htimestamp_t (*snd_timer_status_get_timestamp_dylibloader_wrapper_asound)( snd_timer_status_t*);
+long (*snd_timer_status_get_resolution_dylibloader_wrapper_asound)( snd_timer_status_t*);
+long (*snd_timer_status_get_lost_dylibloader_wrapper_asound)( snd_timer_status_t*);
+long (*snd_timer_status_get_overrun_dylibloader_wrapper_asound)( snd_timer_status_t*);
+long (*snd_timer_status_get_queue_dylibloader_wrapper_asound)( snd_timer_status_t*);
+long (*snd_timer_info_get_ticks_dylibloader_wrapper_asound)( snd_timer_info_t*);
+int (*snd_hwdep_open_dylibloader_wrapper_asound)( snd_hwdep_t**,const char*, int);
+int (*snd_hwdep_close_dylibloader_wrapper_asound)( snd_hwdep_t*);
+int (*snd_hwdep_poll_descriptors_dylibloader_wrapper_asound)( snd_hwdep_t*,struct pollfd*, unsigned int);
+int (*snd_hwdep_poll_descriptors_count_dylibloader_wrapper_asound)( snd_hwdep_t*);
+int (*snd_hwdep_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_hwdep_t*,struct pollfd*, unsigned int, unsigned short*);
+int (*snd_hwdep_nonblock_dylibloader_wrapper_asound)( snd_hwdep_t*, int);
+int (*snd_hwdep_info_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_info_t*);
+int (*snd_hwdep_dsp_status_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_dsp_status_t*);
+int (*snd_hwdep_dsp_load_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_dsp_image_t*);
+int (*snd_hwdep_ioctl_dylibloader_wrapper_asound)( snd_hwdep_t*, unsigned int, void*);
+ssize_t (*snd_hwdep_write_dylibloader_wrapper_asound)( snd_hwdep_t*,const void*, size_t);
+ssize_t (*snd_hwdep_read_dylibloader_wrapper_asound)( snd_hwdep_t*, void*, size_t);
+size_t (*snd_hwdep_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_hwdep_info_malloc_dylibloader_wrapper_asound)( snd_hwdep_info_t**);
+void (*snd_hwdep_info_free_dylibloader_wrapper_asound)( snd_hwdep_info_t*);
+void (*snd_hwdep_info_copy_dylibloader_wrapper_asound)( snd_hwdep_info_t*,const snd_hwdep_info_t*);
+unsigned int (*snd_hwdep_info_get_device_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+int (*snd_hwdep_info_get_card_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+const char* (*snd_hwdep_info_get_id_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+const char* (*snd_hwdep_info_get_name_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+snd_hwdep_iface_t (*snd_hwdep_info_get_iface_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+void (*snd_hwdep_info_set_device_dylibloader_wrapper_asound)( snd_hwdep_info_t*, unsigned int);
+size_t (*snd_hwdep_dsp_status_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_hwdep_dsp_status_malloc_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t**);
+void (*snd_hwdep_dsp_status_free_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t*);
+void (*snd_hwdep_dsp_status_copy_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t*,const snd_hwdep_dsp_status_t*);
+unsigned int (*snd_hwdep_dsp_status_get_version_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+const char* (*snd_hwdep_dsp_status_get_id_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+unsigned int (*snd_hwdep_dsp_status_get_num_dsps_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+unsigned int (*snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+unsigned int (*snd_hwdep_dsp_status_get_chip_ready_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+size_t (*snd_hwdep_dsp_image_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_hwdep_dsp_image_malloc_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t**);
+void (*snd_hwdep_dsp_image_free_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*);
+void (*snd_hwdep_dsp_image_copy_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*,const snd_hwdep_dsp_image_t*);
+unsigned int (*snd_hwdep_dsp_image_get_index_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*);
+const char* (*snd_hwdep_dsp_image_get_name_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*);
+const void* (*snd_hwdep_dsp_image_get_image_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*);
+size_t (*snd_hwdep_dsp_image_get_length_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*);
+void (*snd_hwdep_dsp_image_set_index_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, unsigned int);
+void (*snd_hwdep_dsp_image_set_name_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*,const char*);
+void (*snd_hwdep_dsp_image_set_image_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, void*);
+void (*snd_hwdep_dsp_image_set_length_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, size_t);
+int (*snd_card_load_dylibloader_wrapper_asound)( int);
+int (*snd_card_next_dylibloader_wrapper_asound)( int*);
+int (*snd_card_get_index_dylibloader_wrapper_asound)(const char*);
+int (*snd_card_get_name_dylibloader_wrapper_asound)( int, char**);
+int (*snd_card_get_longname_dylibloader_wrapper_asound)( int, char**);
+int (*snd_device_name_hint_dylibloader_wrapper_asound)( int,const char*, void***);
+int (*snd_device_name_free_hint_dylibloader_wrapper_asound)( void**);
+char* (*snd_device_name_get_hint_dylibloader_wrapper_asound)(const void*,const char*);
+int (*snd_ctl_open_dylibloader_wrapper_asound)( snd_ctl_t**,const char*, int);
+int (*snd_ctl_open_lconf_dylibloader_wrapper_asound)( snd_ctl_t**,const char*, int, snd_config_t*);
+int (*snd_ctl_open_fallback_dylibloader_wrapper_asound)( snd_ctl_t**, snd_config_t*,const char*,const char*, int);
+int (*snd_ctl_close_dylibloader_wrapper_asound)( snd_ctl_t*);
+int (*snd_ctl_nonblock_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+int (*snd_async_add_ctl_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_ctl_t*, snd_async_callback_t, void*);
+snd_ctl_t* (*snd_async_handler_get_ctl_dylibloader_wrapper_asound)( snd_async_handler_t*);
+int (*snd_ctl_poll_descriptors_count_dylibloader_wrapper_asound)( snd_ctl_t*);
+int (*snd_ctl_poll_descriptors_dylibloader_wrapper_asound)( snd_ctl_t*,struct pollfd*, unsigned int);
+int (*snd_ctl_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_ctl_t*,struct pollfd*, unsigned int, unsigned short*);
+int (*snd_ctl_subscribe_events_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+int (*snd_ctl_card_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_card_info_t*);
+int (*snd_ctl_elem_list_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_list_t*);
+int (*snd_ctl_elem_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_read_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*);
+int (*snd_ctl_elem_write_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*);
+int (*snd_ctl_elem_lock_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*);
+int (*snd_ctl_elem_unlock_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*);
+int (*snd_ctl_elem_tlv_read_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int*, unsigned int);
+int (*snd_ctl_elem_tlv_write_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*,const unsigned int*);
+int (*snd_ctl_elem_tlv_command_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*,const unsigned int*);
+int (*snd_ctl_hwdep_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*);
+int (*snd_ctl_hwdep_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_hwdep_info_t*);
+int (*snd_ctl_pcm_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*);
+int (*snd_ctl_pcm_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_pcm_info_t*);
+int (*snd_ctl_pcm_prefer_subdevice_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+int (*snd_ctl_rawmidi_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*);
+int (*snd_ctl_rawmidi_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_rawmidi_info_t*);
+int (*snd_ctl_rawmidi_prefer_subdevice_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+int (*snd_ctl_set_power_state_dylibloader_wrapper_asound)( snd_ctl_t*, unsigned int);
+int (*snd_ctl_get_power_state_dylibloader_wrapper_asound)( snd_ctl_t*, unsigned int*);
+int (*snd_ctl_read_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_event_t*);
+int (*snd_ctl_wait_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+const char* (*snd_ctl_name_dylibloader_wrapper_asound)( snd_ctl_t*);
+snd_ctl_type_t (*snd_ctl_type_dylibloader_wrapper_asound)( snd_ctl_t*);
+const char* (*snd_ctl_elem_type_name_dylibloader_wrapper_asound)( snd_ctl_elem_type_t);
+const char* (*snd_ctl_elem_iface_name_dylibloader_wrapper_asound)( snd_ctl_elem_iface_t);
+const char* (*snd_ctl_event_type_name_dylibloader_wrapper_asound)( snd_ctl_event_type_t);
+unsigned int (*snd_ctl_event_elem_get_mask_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+unsigned int (*snd_ctl_event_elem_get_numid_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+void (*snd_ctl_event_elem_get_id_dylibloader_wrapper_asound)(const snd_ctl_event_t*, snd_ctl_elem_id_t*);
+snd_ctl_elem_iface_t (*snd_ctl_event_elem_get_interface_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+unsigned int (*snd_ctl_event_elem_get_device_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+unsigned int (*snd_ctl_event_elem_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+const char* (*snd_ctl_event_elem_get_name_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+unsigned int (*snd_ctl_event_elem_get_index_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+int (*snd_ctl_elem_list_alloc_space_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*, unsigned int);
+void (*snd_ctl_elem_list_free_space_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*);
+char* (*snd_ctl_ascii_elem_id_get_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*);
+int (*snd_ctl_ascii_elem_id_parse_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const char*);
+int (*snd_ctl_ascii_value_parse_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*, snd_ctl_elem_info_t*,const char*);
+size_t (*snd_ctl_elem_id_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_ctl_elem_id_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_id_t**);
+void (*snd_ctl_elem_id_free_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*);
+void (*snd_ctl_elem_id_clear_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*);
+void (*snd_ctl_elem_id_copy_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const snd_ctl_elem_id_t*);
+unsigned int (*snd_ctl_elem_id_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+snd_ctl_elem_iface_t (*snd_ctl_elem_id_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+unsigned int (*snd_ctl_elem_id_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+unsigned int (*snd_ctl_elem_id_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+const char* (*snd_ctl_elem_id_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+unsigned int (*snd_ctl_elem_id_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+void (*snd_ctl_elem_id_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int);
+void (*snd_ctl_elem_id_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, snd_ctl_elem_iface_t);
+void (*snd_ctl_elem_id_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int);
+void (*snd_ctl_elem_id_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int);
+void (*snd_ctl_elem_id_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const char*);
+void (*snd_ctl_elem_id_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int);
+size_t (*snd_ctl_card_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_ctl_card_info_malloc_dylibloader_wrapper_asound)( snd_ctl_card_info_t**);
+void (*snd_ctl_card_info_free_dylibloader_wrapper_asound)( snd_ctl_card_info_t*);
+void (*snd_ctl_card_info_clear_dylibloader_wrapper_asound)( snd_ctl_card_info_t*);
+void (*snd_ctl_card_info_copy_dylibloader_wrapper_asound)( snd_ctl_card_info_t*,const snd_ctl_card_info_t*);
+int (*snd_ctl_card_info_get_card_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+const char* (*snd_ctl_card_info_get_id_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+const char* (*snd_ctl_card_info_get_driver_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+const char* (*snd_ctl_card_info_get_name_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+const char* (*snd_ctl_card_info_get_longname_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+const char* (*snd_ctl_card_info_get_mixername_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+const char* (*snd_ctl_card_info_get_components_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+size_t (*snd_ctl_event_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_ctl_event_malloc_dylibloader_wrapper_asound)( snd_ctl_event_t**);
+void (*snd_ctl_event_free_dylibloader_wrapper_asound)( snd_ctl_event_t*);
+void (*snd_ctl_event_clear_dylibloader_wrapper_asound)( snd_ctl_event_t*);
+void (*snd_ctl_event_copy_dylibloader_wrapper_asound)( snd_ctl_event_t*,const snd_ctl_event_t*);
+snd_ctl_event_type_t (*snd_ctl_event_get_type_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+size_t (*snd_ctl_elem_list_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_ctl_elem_list_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_list_t**);
+void (*snd_ctl_elem_list_free_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*);
+void (*snd_ctl_elem_list_clear_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*);
+void (*snd_ctl_elem_list_copy_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*,const snd_ctl_elem_list_t*);
+void (*snd_ctl_elem_list_set_offset_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*, unsigned int);
+unsigned int (*snd_ctl_elem_list_get_used_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*);
+unsigned int (*snd_ctl_elem_list_get_count_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*);
+void (*snd_ctl_elem_list_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int, snd_ctl_elem_id_t*);
+unsigned int (*snd_ctl_elem_list_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+snd_ctl_elem_iface_t (*snd_ctl_elem_list_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+unsigned int (*snd_ctl_elem_list_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+unsigned int (*snd_ctl_elem_list_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+const char* (*snd_ctl_elem_list_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+unsigned int (*snd_ctl_elem_list_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+size_t (*snd_ctl_elem_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_ctl_elem_info_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_info_t**);
+void (*snd_ctl_elem_info_free_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*);
+void (*snd_ctl_elem_info_clear_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*);
+void (*snd_ctl_elem_info_copy_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const snd_ctl_elem_info_t*);
+snd_ctl_elem_type_t (*snd_ctl_elem_info_get_type_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_readable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_writable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_volatile_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_inactive_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_locked_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_tlv_readable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_tlv_writable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_tlv_commandable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_owner_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_is_user_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+pid_t (*snd_ctl_elem_info_get_owner_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+unsigned int (*snd_ctl_elem_info_get_count_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+long (*snd_ctl_elem_info_get_min_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+long (*snd_ctl_elem_info_get_max_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+long (*snd_ctl_elem_info_get_step_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+long long (*snd_ctl_elem_info_get_min64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+long long (*snd_ctl_elem_info_get_max64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+long long (*snd_ctl_elem_info_get_step64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+unsigned int (*snd_ctl_elem_info_get_items_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+void (*snd_ctl_elem_info_set_item_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+const char* (*snd_ctl_elem_info_get_item_name_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_get_dimensions_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+int (*snd_ctl_elem_info_get_dimension_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*, unsigned int);
+int (*snd_ctl_elem_info_set_dimension_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const int [4]);
+void (*snd_ctl_elem_info_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*, snd_ctl_elem_id_t*);
+unsigned int (*snd_ctl_elem_info_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+snd_ctl_elem_iface_t (*snd_ctl_elem_info_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+unsigned int (*snd_ctl_elem_info_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+unsigned int (*snd_ctl_elem_info_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+const char* (*snd_ctl_elem_info_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+unsigned int (*snd_ctl_elem_info_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+void (*snd_ctl_elem_info_set_id_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const snd_ctl_elem_id_t*);
+void (*snd_ctl_elem_info_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+void (*snd_ctl_elem_info_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, snd_ctl_elem_iface_t);
+void (*snd_ctl_elem_info_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+void (*snd_ctl_elem_info_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+void (*snd_ctl_elem_info_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const char*);
+void (*snd_ctl_elem_info_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+int (*snd_ctl_add_integer_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, long, long, long);
+int (*snd_ctl_add_integer64_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, long long, long long, long long);
+int (*snd_ctl_add_boolean_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int);
+int (*snd_ctl_add_enumerated_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, unsigned int,const char* []);
+int (*snd_ctl_add_bytes_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int);
+int (*snd_ctl_elem_add_integer_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, long, long, long);
+int (*snd_ctl_elem_add_integer64_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, long long, long long, long long);
+int (*snd_ctl_elem_add_boolean_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int);
+int (*snd_ctl_elem_add_enumerated_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, unsigned int,const char* []);
+int (*snd_ctl_elem_add_iec958_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*);
+int (*snd_ctl_elem_remove_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*);
+size_t (*snd_ctl_elem_value_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_ctl_elem_value_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_value_t**);
+void (*snd_ctl_elem_value_free_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*);
+void (*snd_ctl_elem_value_clear_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*);
+void (*snd_ctl_elem_value_copy_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_value_t*);
+int (*snd_ctl_elem_value_compare_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_value_t*);
+void (*snd_ctl_elem_value_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, snd_ctl_elem_id_t*);
+unsigned int (*snd_ctl_elem_value_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+snd_ctl_elem_iface_t (*snd_ctl_elem_value_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+unsigned int (*snd_ctl_elem_value_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+unsigned int (*snd_ctl_elem_value_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+const char* (*snd_ctl_elem_value_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+unsigned int (*snd_ctl_elem_value_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+void (*snd_ctl_elem_value_set_id_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_id_t*);
+void (*snd_ctl_elem_value_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int);
+void (*snd_ctl_elem_value_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, snd_ctl_elem_iface_t);
+void (*snd_ctl_elem_value_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int);
+void (*snd_ctl_elem_value_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int);
+void (*snd_ctl_elem_value_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const char*);
+void (*snd_ctl_elem_value_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int);
+int (*snd_ctl_elem_value_get_boolean_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+long (*snd_ctl_elem_value_get_integer_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+long long (*snd_ctl_elem_value_get_integer64_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+unsigned int (*snd_ctl_elem_value_get_enumerated_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+unsigned char (*snd_ctl_elem_value_get_byte_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+void (*snd_ctl_elem_value_set_boolean_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long);
+void (*snd_ctl_elem_value_set_integer_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long);
+void (*snd_ctl_elem_value_set_integer64_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long long);
+void (*snd_ctl_elem_value_set_enumerated_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, unsigned int);
+void (*snd_ctl_elem_value_set_byte_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, unsigned char);
+void (*snd_ctl_elem_set_bytes_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, void*, size_t);
+const void* (*snd_ctl_elem_value_get_bytes_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+void (*snd_ctl_elem_value_get_iec958_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, snd_aes_iec958_t*);
+void (*snd_ctl_elem_value_set_iec958_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_aes_iec958_t*);
+int (*snd_tlv_parse_dB_info_dylibloader_wrapper_asound)( unsigned int*, unsigned int, unsigned int**);
+int (*snd_tlv_get_dB_range_dylibloader_wrapper_asound)( unsigned int*, long, long, long*, long*);
+int (*snd_tlv_convert_to_dB_dylibloader_wrapper_asound)( unsigned int*, long, long, long, long*);
+int (*snd_tlv_convert_from_dB_dylibloader_wrapper_asound)( unsigned int*, long, long, long, long*, int);
+int (*snd_ctl_get_dB_range_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long*, long*);
+int (*snd_ctl_convert_to_dB_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long, long*);
+int (*snd_ctl_convert_from_dB_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long, long*, int);
+int (*snd_hctl_compare_fast_dylibloader_wrapper_asound)(const snd_hctl_elem_t*,const snd_hctl_elem_t*);
+int (*snd_hctl_open_dylibloader_wrapper_asound)( snd_hctl_t**,const char*, int);
+int (*snd_hctl_open_ctl_dylibloader_wrapper_asound)( snd_hctl_t**, snd_ctl_t*);
+int (*snd_hctl_close_dylibloader_wrapper_asound)( snd_hctl_t*);
+int (*snd_hctl_nonblock_dylibloader_wrapper_asound)( snd_hctl_t*, int);
+int (*snd_hctl_poll_descriptors_count_dylibloader_wrapper_asound)( snd_hctl_t*);
+int (*snd_hctl_poll_descriptors_dylibloader_wrapper_asound)( snd_hctl_t*,struct pollfd*, unsigned int);
+int (*snd_hctl_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_hctl_t*,struct pollfd*, unsigned int, unsigned short*);
+unsigned int (*snd_hctl_get_count_dylibloader_wrapper_asound)( snd_hctl_t*);
+int (*snd_hctl_set_compare_dylibloader_wrapper_asound)( snd_hctl_t*, snd_hctl_compare_t);
+snd_hctl_elem_t* (*snd_hctl_first_elem_dylibloader_wrapper_asound)( snd_hctl_t*);
+snd_hctl_elem_t* (*snd_hctl_last_elem_dylibloader_wrapper_asound)( snd_hctl_t*);
+snd_hctl_elem_t* (*snd_hctl_find_elem_dylibloader_wrapper_asound)( snd_hctl_t*,const snd_ctl_elem_id_t*);
+void (*snd_hctl_set_callback_dylibloader_wrapper_asound)( snd_hctl_t*, snd_hctl_callback_t);
+void (*snd_hctl_set_callback_private_dylibloader_wrapper_asound)( snd_hctl_t*, void*);
+void* (*snd_hctl_get_callback_private_dylibloader_wrapper_asound)( snd_hctl_t*);
+int (*snd_hctl_load_dylibloader_wrapper_asound)( snd_hctl_t*);
+int (*snd_hctl_free_dylibloader_wrapper_asound)( snd_hctl_t*);
+int (*snd_hctl_handle_events_dylibloader_wrapper_asound)( snd_hctl_t*);
+const char* (*snd_hctl_name_dylibloader_wrapper_asound)( snd_hctl_t*);
+int (*snd_hctl_wait_dylibloader_wrapper_asound)( snd_hctl_t*, int);
+snd_ctl_t* (*snd_hctl_ctl_dylibloader_wrapper_asound)( snd_hctl_t*);
+snd_hctl_elem_t* (*snd_hctl_elem_next_dylibloader_wrapper_asound)( snd_hctl_elem_t*);
+snd_hctl_elem_t* (*snd_hctl_elem_prev_dylibloader_wrapper_asound)( snd_hctl_elem_t*);
+int (*snd_hctl_elem_info_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_info_t*);
+int (*snd_hctl_elem_read_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_value_t*);
+int (*snd_hctl_elem_write_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_value_t*);
+int (*snd_hctl_elem_tlv_read_dylibloader_wrapper_asound)( snd_hctl_elem_t*, unsigned int*, unsigned int);
+int (*snd_hctl_elem_tlv_write_dylibloader_wrapper_asound)( snd_hctl_elem_t*,const unsigned int*);
+int (*snd_hctl_elem_tlv_command_dylibloader_wrapper_asound)( snd_hctl_elem_t*,const unsigned int*);
+snd_hctl_t* (*snd_hctl_elem_get_hctl_dylibloader_wrapper_asound)( snd_hctl_elem_t*);
+void (*snd_hctl_elem_get_id_dylibloader_wrapper_asound)(const snd_hctl_elem_t*, snd_ctl_elem_id_t*);
+unsigned int (*snd_hctl_elem_get_numid_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+snd_ctl_elem_iface_t (*snd_hctl_elem_get_interface_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+unsigned int (*snd_hctl_elem_get_device_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+unsigned int (*snd_hctl_elem_get_subdevice_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+const char* (*snd_hctl_elem_get_name_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+unsigned int (*snd_hctl_elem_get_index_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+void (*snd_hctl_elem_set_callback_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_hctl_elem_callback_t);
+void* (*snd_hctl_elem_get_callback_private_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+void (*snd_hctl_elem_set_callback_private_dylibloader_wrapper_asound)( snd_hctl_elem_t*, void*);
+int (*snd_sctl_build_dylibloader_wrapper_asound)( snd_sctl_t**, snd_ctl_t*, snd_config_t*, snd_config_t*, int);
+int (*snd_sctl_free_dylibloader_wrapper_asound)( snd_sctl_t*);
+int (*snd_sctl_install_dylibloader_wrapper_asound)( snd_sctl_t*);
+int (*snd_sctl_remove_dylibloader_wrapper_asound)( snd_sctl_t*);
+int (*snd_mixer_open_dylibloader_wrapper_asound)( snd_mixer_t**, int);
+int (*snd_mixer_close_dylibloader_wrapper_asound)( snd_mixer_t*);
+snd_mixer_elem_t* (*snd_mixer_first_elem_dylibloader_wrapper_asound)( snd_mixer_t*);
+snd_mixer_elem_t* (*snd_mixer_last_elem_dylibloader_wrapper_asound)( snd_mixer_t*);
+int (*snd_mixer_handle_events_dylibloader_wrapper_asound)( snd_mixer_t*);
+int (*snd_mixer_attach_dylibloader_wrapper_asound)( snd_mixer_t*,const char*);
+int (*snd_mixer_attach_hctl_dylibloader_wrapper_asound)( snd_mixer_t*, snd_hctl_t*);
+int (*snd_mixer_detach_dylibloader_wrapper_asound)( snd_mixer_t*,const char*);
+int (*snd_mixer_detach_hctl_dylibloader_wrapper_asound)( snd_mixer_t*, snd_hctl_t*);
+int (*snd_mixer_get_hctl_dylibloader_wrapper_asound)( snd_mixer_t*,const char*, snd_hctl_t**);
+int (*snd_mixer_poll_descriptors_count_dylibloader_wrapper_asound)( snd_mixer_t*);
+int (*snd_mixer_poll_descriptors_dylibloader_wrapper_asound)( snd_mixer_t*,struct pollfd*, unsigned int);
+int (*snd_mixer_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_mixer_t*,struct pollfd*, unsigned int, unsigned short*);
+int (*snd_mixer_load_dylibloader_wrapper_asound)( snd_mixer_t*);
+void (*snd_mixer_free_dylibloader_wrapper_asound)( snd_mixer_t*);
+int (*snd_mixer_wait_dylibloader_wrapper_asound)( snd_mixer_t*, int);
+int (*snd_mixer_set_compare_dylibloader_wrapper_asound)( snd_mixer_t*, snd_mixer_compare_t);
+void (*snd_mixer_set_callback_dylibloader_wrapper_asound)( snd_mixer_t*, snd_mixer_callback_t);
+void* (*snd_mixer_get_callback_private_dylibloader_wrapper_asound)(const snd_mixer_t*);
+void (*snd_mixer_set_callback_private_dylibloader_wrapper_asound)( snd_mixer_t*, void*);
+unsigned int (*snd_mixer_get_count_dylibloader_wrapper_asound)(const snd_mixer_t*);
+int (*snd_mixer_class_unregister_dylibloader_wrapper_asound)( snd_mixer_class_t*);
+snd_mixer_elem_t* (*snd_mixer_elem_next_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+snd_mixer_elem_t* (*snd_mixer_elem_prev_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+void (*snd_mixer_elem_set_callback_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_elem_callback_t);
+void* (*snd_mixer_elem_get_callback_private_dylibloader_wrapper_asound)(const snd_mixer_elem_t*);
+void (*snd_mixer_elem_set_callback_private_dylibloader_wrapper_asound)( snd_mixer_elem_t*, void*);
+snd_mixer_elem_type_t (*snd_mixer_elem_get_type_dylibloader_wrapper_asound)(const snd_mixer_elem_t*);
+int (*snd_mixer_class_register_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_t*);
+int (*snd_mixer_elem_new_dylibloader_wrapper_asound)( snd_mixer_elem_t**, snd_mixer_elem_type_t, int, void*, void*);
+int (*snd_mixer_elem_add_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_class_t*);
+int (*snd_mixer_elem_remove_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+void (*snd_mixer_elem_free_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_elem_info_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_elem_value_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_elem_attach_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_hctl_elem_t*);
+int (*snd_mixer_elem_detach_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_hctl_elem_t*);
+int (*snd_mixer_elem_empty_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+void* (*snd_mixer_elem_get_private_dylibloader_wrapper_asound)(const snd_mixer_elem_t*);
+size_t (*snd_mixer_class_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_mixer_class_malloc_dylibloader_wrapper_asound)( snd_mixer_class_t**);
+void (*snd_mixer_class_free_dylibloader_wrapper_asound)( snd_mixer_class_t*);
+void (*snd_mixer_class_copy_dylibloader_wrapper_asound)( snd_mixer_class_t*,const snd_mixer_class_t*);
+snd_mixer_t* (*snd_mixer_class_get_mixer_dylibloader_wrapper_asound)(const snd_mixer_class_t*);
+snd_mixer_event_t (*snd_mixer_class_get_event_dylibloader_wrapper_asound)(const snd_mixer_class_t*);
+void* (*snd_mixer_class_get_private_dylibloader_wrapper_asound)(const snd_mixer_class_t*);
+snd_mixer_compare_t (*snd_mixer_class_get_compare_dylibloader_wrapper_asound)(const snd_mixer_class_t*);
+int (*snd_mixer_class_set_event_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_event_t);
+int (*snd_mixer_class_set_private_dylibloader_wrapper_asound)( snd_mixer_class_t*, void*);
+int (*snd_mixer_class_set_private_free_dylibloader_wrapper_asound)( snd_mixer_class_t*, void*);
+int (*snd_mixer_class_set_compare_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_compare_t);
+const char* (*snd_mixer_selem_channel_name_dylibloader_wrapper_asound)( snd_mixer_selem_channel_id_t);
+int (*snd_mixer_selem_register_dylibloader_wrapper_asound)( snd_mixer_t*,struct snd_mixer_selem_regopt*, snd_mixer_class_t**);
+void (*snd_mixer_selem_get_id_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_id_t*);
+const char* (*snd_mixer_selem_get_name_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+unsigned int (*snd_mixer_selem_get_index_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+snd_mixer_elem_t* (*snd_mixer_find_selem_dylibloader_wrapper_asound)( snd_mixer_t*,const snd_mixer_selem_id_t*);
+int (*snd_mixer_selem_is_active_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_is_playback_mono_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_playback_channel_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t);
+int (*snd_mixer_selem_is_capture_mono_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_capture_channel_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t);
+int (*snd_mixer_selem_get_capture_group_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_common_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_playback_volume_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_capture_volume_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_common_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_playback_switch_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_capture_switch_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_has_capture_switch_exclusive_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_ask_playback_vol_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long*);
+int (*snd_mixer_selem_ask_capture_vol_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long*);
+int (*snd_mixer_selem_ask_playback_dB_vol_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int, long*);
+int (*snd_mixer_selem_ask_capture_dB_vol_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int, long*);
+int (*snd_mixer_selem_get_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*);
+int (*snd_mixer_selem_get_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*);
+int (*snd_mixer_selem_get_playback_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*);
+int (*snd_mixer_selem_get_capture_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*);
+int (*snd_mixer_selem_get_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int*);
+int (*snd_mixer_selem_get_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int*);
+int (*snd_mixer_selem_set_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long);
+int (*snd_mixer_selem_set_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long);
+int (*snd_mixer_selem_set_playback_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long, int);
+int (*snd_mixer_selem_set_capture_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long, int);
+int (*snd_mixer_selem_set_playback_volume_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long);
+int (*snd_mixer_selem_set_capture_volume_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long);
+int (*snd_mixer_selem_set_playback_dB_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int);
+int (*snd_mixer_selem_set_capture_dB_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int);
+int (*snd_mixer_selem_set_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int);
+int (*snd_mixer_selem_set_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int);
+int (*snd_mixer_selem_set_playback_switch_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, int);
+int (*snd_mixer_selem_set_capture_switch_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, int);
+int (*snd_mixer_selem_get_playback_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*);
+int (*snd_mixer_selem_get_playback_dB_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*);
+int (*snd_mixer_selem_set_playback_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long);
+int (*snd_mixer_selem_get_capture_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*);
+int (*snd_mixer_selem_get_capture_dB_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*);
+int (*snd_mixer_selem_set_capture_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long);
+int (*snd_mixer_selem_is_enumerated_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_is_enum_playback_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_is_enum_capture_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_get_enum_items_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+int (*snd_mixer_selem_get_enum_item_name_dylibloader_wrapper_asound)( snd_mixer_elem_t*, unsigned int, size_t, char*);
+int (*snd_mixer_selem_get_enum_item_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, unsigned int*);
+int (*snd_mixer_selem_set_enum_item_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, unsigned int);
+size_t (*snd_mixer_selem_id_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_mixer_selem_id_malloc_dylibloader_wrapper_asound)( snd_mixer_selem_id_t**);
+void (*snd_mixer_selem_id_free_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*);
+void (*snd_mixer_selem_id_copy_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const snd_mixer_selem_id_t*);
+const char* (*snd_mixer_selem_id_get_name_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*);
+unsigned int (*snd_mixer_selem_id_get_index_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*);
+void (*snd_mixer_selem_id_set_name_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*);
+void (*snd_mixer_selem_id_set_index_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*, unsigned int);
+int (*snd_mixer_selem_id_parse_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*);
+int (*snd_seq_open_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int);
+int (*snd_seq_open_lconf_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int, snd_config_t*);
+const char* (*snd_seq_name_dylibloader_wrapper_asound)( snd_seq_t*);
+snd_seq_type_t (*snd_seq_type_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_close_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_poll_descriptors_count_dylibloader_wrapper_asound)( snd_seq_t*, short);
+int (*snd_seq_poll_descriptors_dylibloader_wrapper_asound)( snd_seq_t*,struct pollfd*, unsigned int, short);
+int (*snd_seq_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_seq_t*,struct pollfd*, unsigned int, unsigned short*);
+int (*snd_seq_nonblock_dylibloader_wrapper_asound)( snd_seq_t*, int);
+int (*snd_seq_client_id_dylibloader_wrapper_asound)( snd_seq_t*);
+size_t (*snd_seq_get_output_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*);
+size_t (*snd_seq_get_input_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_set_output_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+int (*snd_seq_set_input_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+size_t (*snd_seq_system_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_system_info_malloc_dylibloader_wrapper_asound)( snd_seq_system_info_t**);
+void (*snd_seq_system_info_free_dylibloader_wrapper_asound)( snd_seq_system_info_t*);
+void (*snd_seq_system_info_copy_dylibloader_wrapper_asound)( snd_seq_system_info_t*,const snd_seq_system_info_t*);
+int (*snd_seq_system_info_get_queues_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+int (*snd_seq_system_info_get_clients_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+int (*snd_seq_system_info_get_ports_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+int (*snd_seq_system_info_get_channels_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+int (*snd_seq_system_info_get_cur_clients_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+int (*snd_seq_system_info_get_cur_queues_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+int (*snd_seq_system_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_system_info_t*);
+size_t (*snd_seq_client_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_client_info_malloc_dylibloader_wrapper_asound)( snd_seq_client_info_t**);
+void (*snd_seq_client_info_free_dylibloader_wrapper_asound)( snd_seq_client_info_t*);
+void (*snd_seq_client_info_copy_dylibloader_wrapper_asound)( snd_seq_client_info_t*,const snd_seq_client_info_t*);
+int (*snd_seq_client_info_get_client_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+snd_seq_client_type_t (*snd_seq_client_info_get_type_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+const char* (*snd_seq_client_info_get_name_dylibloader_wrapper_asound)( snd_seq_client_info_t*);
+int (*snd_seq_client_info_get_broadcast_filter_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+int (*snd_seq_client_info_get_error_bounce_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+int (*snd_seq_client_info_get_card_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+int (*snd_seq_client_info_get_pid_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+const unsigned char* (*snd_seq_client_info_get_event_filter_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+int (*snd_seq_client_info_get_num_ports_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+int (*snd_seq_client_info_get_event_lost_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+void (*snd_seq_client_info_set_client_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+void (*snd_seq_client_info_set_name_dylibloader_wrapper_asound)( snd_seq_client_info_t*,const char*);
+void (*snd_seq_client_info_set_broadcast_filter_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+void (*snd_seq_client_info_set_error_bounce_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+void (*snd_seq_client_info_set_event_filter_dylibloader_wrapper_asound)( snd_seq_client_info_t*, unsigned char*);
+void (*snd_seq_client_info_event_filter_clear_dylibloader_wrapper_asound)( snd_seq_client_info_t*);
+void (*snd_seq_client_info_event_filter_add_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+void (*snd_seq_client_info_event_filter_del_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+int (*snd_seq_client_info_event_filter_check_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+int (*snd_seq_get_client_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*);
+int (*snd_seq_get_any_client_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_client_info_t*);
+int (*snd_seq_set_client_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*);
+int (*snd_seq_query_next_client_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*);
+size_t (*snd_seq_client_pool_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_client_pool_malloc_dylibloader_wrapper_asound)( snd_seq_client_pool_t**);
+void (*snd_seq_client_pool_free_dylibloader_wrapper_asound)( snd_seq_client_pool_t*);
+void (*snd_seq_client_pool_copy_dylibloader_wrapper_asound)( snd_seq_client_pool_t*,const snd_seq_client_pool_t*);
+int (*snd_seq_client_pool_get_client_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+size_t (*snd_seq_client_pool_get_output_pool_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+size_t (*snd_seq_client_pool_get_input_pool_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+size_t (*snd_seq_client_pool_get_output_room_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+size_t (*snd_seq_client_pool_get_output_free_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+size_t (*snd_seq_client_pool_get_input_free_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+void (*snd_seq_client_pool_set_output_pool_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t);
+void (*snd_seq_client_pool_set_input_pool_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t);
+void (*snd_seq_client_pool_set_output_room_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t);
+int (*snd_seq_get_client_pool_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_pool_t*);
+int (*snd_seq_set_client_pool_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_pool_t*);
+size_t (*snd_seq_port_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_port_info_malloc_dylibloader_wrapper_asound)( snd_seq_port_info_t**);
+void (*snd_seq_port_info_free_dylibloader_wrapper_asound)( snd_seq_port_info_t*);
+void (*snd_seq_port_info_copy_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_client_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_port_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+const snd_seq_addr_t* (*snd_seq_port_info_get_addr_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+const char* (*snd_seq_port_info_get_name_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+unsigned int (*snd_seq_port_info_get_capability_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+unsigned int (*snd_seq_port_info_get_type_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_midi_channels_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_midi_voices_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_synth_voices_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_read_use_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_write_use_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_port_specified_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_timestamping_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_timestamp_real_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+int (*snd_seq_port_info_get_timestamp_queue_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+void (*snd_seq_port_info_set_client_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+void (*snd_seq_port_info_set_port_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+void (*snd_seq_port_info_set_addr_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const snd_seq_addr_t*);
+void (*snd_seq_port_info_set_name_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const char*);
+void (*snd_seq_port_info_set_capability_dylibloader_wrapper_asound)( snd_seq_port_info_t*, unsigned int);
+void (*snd_seq_port_info_set_type_dylibloader_wrapper_asound)( snd_seq_port_info_t*, unsigned int);
+void (*snd_seq_port_info_set_midi_channels_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+void (*snd_seq_port_info_set_midi_voices_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+void (*snd_seq_port_info_set_synth_voices_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+void (*snd_seq_port_info_set_port_specified_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+void (*snd_seq_port_info_set_timestamping_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+void (*snd_seq_port_info_set_timestamp_real_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+void (*snd_seq_port_info_set_timestamp_queue_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+int (*snd_seq_create_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_info_t*);
+int (*snd_seq_delete_port_dylibloader_wrapper_asound)( snd_seq_t*, int);
+int (*snd_seq_get_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_port_info_t*);
+int (*snd_seq_get_any_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, int, snd_seq_port_info_t*);
+int (*snd_seq_set_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_port_info_t*);
+int (*snd_seq_query_next_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_info_t*);
+size_t (*snd_seq_port_subscribe_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_port_subscribe_malloc_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t**);
+void (*snd_seq_port_subscribe_free_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*);
+void (*snd_seq_port_subscribe_copy_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_port_subscribe_t*);
+const snd_seq_addr_t* (*snd_seq_port_subscribe_get_sender_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+const snd_seq_addr_t* (*snd_seq_port_subscribe_get_dest_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+int (*snd_seq_port_subscribe_get_queue_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+int (*snd_seq_port_subscribe_get_exclusive_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+int (*snd_seq_port_subscribe_get_time_update_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+int (*snd_seq_port_subscribe_get_time_real_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+void (*snd_seq_port_subscribe_set_sender_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_addr_t*);
+void (*snd_seq_port_subscribe_set_dest_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_addr_t*);
+void (*snd_seq_port_subscribe_set_queue_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int);
+void (*snd_seq_port_subscribe_set_exclusive_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int);
+void (*snd_seq_port_subscribe_set_time_update_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int);
+void (*snd_seq_port_subscribe_set_time_real_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int);
+int (*snd_seq_get_port_subscription_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*);
+int (*snd_seq_subscribe_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*);
+int (*snd_seq_unsubscribe_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*);
+size_t (*snd_seq_query_subscribe_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_query_subscribe_malloc_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t**);
+void (*snd_seq_query_subscribe_free_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*);
+void (*snd_seq_query_subscribe_copy_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*,const snd_seq_query_subscribe_t*);
+int (*snd_seq_query_subscribe_get_client_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+int (*snd_seq_query_subscribe_get_port_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+const snd_seq_addr_t* (*snd_seq_query_subscribe_get_root_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+snd_seq_query_subs_type_t (*snd_seq_query_subscribe_get_type_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+int (*snd_seq_query_subscribe_get_index_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+int (*snd_seq_query_subscribe_get_num_subs_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+const snd_seq_addr_t* (*snd_seq_query_subscribe_get_addr_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+int (*snd_seq_query_subscribe_get_queue_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+int (*snd_seq_query_subscribe_get_exclusive_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+int (*snd_seq_query_subscribe_get_time_update_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+int (*snd_seq_query_subscribe_get_time_real_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+void (*snd_seq_query_subscribe_set_client_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int);
+void (*snd_seq_query_subscribe_set_port_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int);
+void (*snd_seq_query_subscribe_set_root_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*,const snd_seq_addr_t*);
+void (*snd_seq_query_subscribe_set_type_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, snd_seq_query_subs_type_t);
+void (*snd_seq_query_subscribe_set_index_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int);
+int (*snd_seq_query_port_subscribers_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_query_subscribe_t*);
+size_t (*snd_seq_queue_info_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_queue_info_malloc_dylibloader_wrapper_asound)( snd_seq_queue_info_t**);
+void (*snd_seq_queue_info_free_dylibloader_wrapper_asound)( snd_seq_queue_info_t*);
+void (*snd_seq_queue_info_copy_dylibloader_wrapper_asound)( snd_seq_queue_info_t*,const snd_seq_queue_info_t*);
+int (*snd_seq_queue_info_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+const char* (*snd_seq_queue_info_get_name_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+int (*snd_seq_queue_info_get_owner_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+int (*snd_seq_queue_info_get_locked_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+unsigned int (*snd_seq_queue_info_get_flags_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+void (*snd_seq_queue_info_set_name_dylibloader_wrapper_asound)( snd_seq_queue_info_t*,const char*);
+void (*snd_seq_queue_info_set_owner_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, int);
+void (*snd_seq_queue_info_set_locked_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, int);
+void (*snd_seq_queue_info_set_flags_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, unsigned int);
+int (*snd_seq_create_queue_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_queue_info_t*);
+int (*snd_seq_alloc_named_queue_dylibloader_wrapper_asound)( snd_seq_t*,const char*);
+int (*snd_seq_alloc_queue_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_free_queue_dylibloader_wrapper_asound)( snd_seq_t*, int);
+int (*snd_seq_get_queue_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_info_t*);
+int (*snd_seq_set_queue_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_info_t*);
+int (*snd_seq_query_named_queue_dylibloader_wrapper_asound)( snd_seq_t*,const char*);
+int (*snd_seq_get_queue_usage_dylibloader_wrapper_asound)( snd_seq_t*, int);
+int (*snd_seq_set_queue_usage_dylibloader_wrapper_asound)( snd_seq_t*, int, int);
+size_t (*snd_seq_queue_status_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_queue_status_malloc_dylibloader_wrapper_asound)( snd_seq_queue_status_t**);
+void (*snd_seq_queue_status_free_dylibloader_wrapper_asound)( snd_seq_queue_status_t*);
+void (*snd_seq_queue_status_copy_dylibloader_wrapper_asound)( snd_seq_queue_status_t*,const snd_seq_queue_status_t*);
+int (*snd_seq_queue_status_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+int (*snd_seq_queue_status_get_events_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+snd_seq_tick_time_t (*snd_seq_queue_status_get_tick_time_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+const snd_seq_real_time_t* (*snd_seq_queue_status_get_real_time_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+unsigned int (*snd_seq_queue_status_get_status_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+int (*snd_seq_get_queue_status_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_status_t*);
+size_t (*snd_seq_queue_tempo_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_queue_tempo_malloc_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t**);
+void (*snd_seq_queue_tempo_free_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*);
+void (*snd_seq_queue_tempo_copy_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*,const snd_seq_queue_tempo_t*);
+int (*snd_seq_queue_tempo_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+unsigned int (*snd_seq_queue_tempo_get_tempo_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+int (*snd_seq_queue_tempo_get_ppq_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+unsigned int (*snd_seq_queue_tempo_get_skew_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+unsigned int (*snd_seq_queue_tempo_get_skew_base_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+void (*snd_seq_queue_tempo_set_tempo_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int);
+void (*snd_seq_queue_tempo_set_ppq_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, int);
+void (*snd_seq_queue_tempo_set_skew_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int);
+void (*snd_seq_queue_tempo_set_skew_base_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int);
+int (*snd_seq_get_queue_tempo_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_tempo_t*);
+int (*snd_seq_set_queue_tempo_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_tempo_t*);
+size_t (*snd_seq_queue_timer_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_queue_timer_malloc_dylibloader_wrapper_asound)( snd_seq_queue_timer_t**);
+void (*snd_seq_queue_timer_free_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*);
+void (*snd_seq_queue_timer_copy_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*,const snd_seq_queue_timer_t*);
+int (*snd_seq_queue_timer_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*);
+snd_seq_queue_timer_type_t (*snd_seq_queue_timer_get_type_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*);
+const snd_timer_id_t* (*snd_seq_queue_timer_get_id_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*);
+unsigned int (*snd_seq_queue_timer_get_resolution_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*);
+void (*snd_seq_queue_timer_set_type_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*, snd_seq_queue_timer_type_t);
+void (*snd_seq_queue_timer_set_id_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*,const snd_timer_id_t*);
+void (*snd_seq_queue_timer_set_resolution_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*, unsigned int);
+int (*snd_seq_get_queue_timer_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_timer_t*);
+int (*snd_seq_set_queue_timer_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_timer_t*);
+int (*snd_seq_free_event_dylibloader_wrapper_asound)( snd_seq_event_t*);
+ssize_t (*snd_seq_event_length_dylibloader_wrapper_asound)( snd_seq_event_t*);
+int (*snd_seq_event_output_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*);
+int (*snd_seq_event_output_buffer_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*);
+int (*snd_seq_event_output_direct_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*);
+int (*snd_seq_event_input_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t**);
+int (*snd_seq_event_input_pending_dylibloader_wrapper_asound)( snd_seq_t*, int);
+int (*snd_seq_drain_output_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_event_output_pending_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_extract_output_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t**);
+int (*snd_seq_drop_output_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_drop_output_buffer_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_drop_input_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_drop_input_buffer_dylibloader_wrapper_asound)( snd_seq_t*);
+size_t (*snd_seq_remove_events_sizeof_dylibloader_wrapper_asound)( void);
+int (*snd_seq_remove_events_malloc_dylibloader_wrapper_asound)( snd_seq_remove_events_t**);
+void (*snd_seq_remove_events_free_dylibloader_wrapper_asound)( snd_seq_remove_events_t*);
+void (*snd_seq_remove_events_copy_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_remove_events_t*);
+unsigned int (*snd_seq_remove_events_get_condition_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+int (*snd_seq_remove_events_get_queue_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+const snd_seq_timestamp_t* (*snd_seq_remove_events_get_time_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+const snd_seq_addr_t* (*snd_seq_remove_events_get_dest_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+int (*snd_seq_remove_events_get_channel_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+int (*snd_seq_remove_events_get_event_type_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+int (*snd_seq_remove_events_get_tag_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+void (*snd_seq_remove_events_set_condition_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, unsigned int);
+void (*snd_seq_remove_events_set_queue_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int);
+void (*snd_seq_remove_events_set_time_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_timestamp_t*);
+void (*snd_seq_remove_events_set_dest_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_addr_t*);
+void (*snd_seq_remove_events_set_channel_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int);
+void (*snd_seq_remove_events_set_event_type_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int);
+void (*snd_seq_remove_events_set_tag_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int);
+int (*snd_seq_remove_events_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_remove_events_t*);
+void (*snd_seq_set_bit_dylibloader_wrapper_asound)( int, void*);
+void (*snd_seq_unset_bit_dylibloader_wrapper_asound)( int, void*);
+int (*snd_seq_change_bit_dylibloader_wrapper_asound)( int, void*);
+int (*snd_seq_get_bit_dylibloader_wrapper_asound)( int, void*);
+int (*snd_seq_control_queue_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int, snd_seq_event_t*);
+int (*snd_seq_create_simple_port_dylibloader_wrapper_asound)( snd_seq_t*,const char*, unsigned int, unsigned int);
+int (*snd_seq_delete_simple_port_dylibloader_wrapper_asound)( snd_seq_t*, int);
+int (*snd_seq_connect_from_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int);
+int (*snd_seq_connect_to_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int);
+int (*snd_seq_disconnect_from_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int);
+int (*snd_seq_disconnect_to_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int);
+int (*snd_seq_set_client_name_dylibloader_wrapper_asound)( snd_seq_t*,const char*);
+int (*snd_seq_set_client_event_filter_dylibloader_wrapper_asound)( snd_seq_t*, int);
+int (*snd_seq_set_client_pool_output_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+int (*snd_seq_set_client_pool_output_room_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+int (*snd_seq_set_client_pool_input_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+int (*snd_seq_sync_output_queue_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_parse_address_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_addr_t*,const char*);
+int (*snd_seq_reset_pool_output_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_seq_reset_pool_input_dylibloader_wrapper_asound)( snd_seq_t*);
+int (*snd_midi_event_new_dylibloader_wrapper_asound)( size_t, snd_midi_event_t**);
+int (*snd_midi_event_resize_buffer_dylibloader_wrapper_asound)( snd_midi_event_t*, size_t);
+void (*snd_midi_event_free_dylibloader_wrapper_asound)( snd_midi_event_t*);
+void (*snd_midi_event_init_dylibloader_wrapper_asound)( snd_midi_event_t*);
+void (*snd_midi_event_reset_encode_dylibloader_wrapper_asound)( snd_midi_event_t*);
+void (*snd_midi_event_reset_decode_dylibloader_wrapper_asound)( snd_midi_event_t*);
+void (*snd_midi_event_no_status_dylibloader_wrapper_asound)( snd_midi_event_t*, int);
+long (*snd_midi_event_encode_dylibloader_wrapper_asound)( snd_midi_event_t*,const unsigned char*, long, snd_seq_event_t*);
+int (*snd_midi_event_encode_byte_dylibloader_wrapper_asound)( snd_midi_event_t*, int, snd_seq_event_t*);
+long (*snd_midi_event_decode_dylibloader_wrapper_asound)( snd_midi_event_t*, unsigned char*, long,const snd_seq_event_t*);
+int initialize_asound(int verbose) {
+ void *handle;
+ char *error;
+ handle = dlopen("libasound.so.2", RTLD_LAZY);
+ if (!handle) {
+ if (verbose) {
+ fprintf(stderr, "%s\n", dlerror());
+ }
+ return(1);
+ }
+ dlerror();
+// snd_asoundlib_version
+ *(void **) (&snd_asoundlib_version_dylibloader_wrapper_asound) = dlsym(handle, "snd_asoundlib_version");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_dlpath
+ *(void **) (&snd_dlpath_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlpath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_dlopen
+ *(void **) (&snd_dlopen_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlopen");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_dlsym
+ *(void **) (&snd_dlsym_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlsym");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_dlclose
+ *(void **) (&snd_dlclose_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlclose");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_add_handler
+ *(void **) (&snd_async_add_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_add_handler");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_del_handler
+ *(void **) (&snd_async_del_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_del_handler");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_handler_get_fd
+ *(void **) (&snd_async_handler_get_fd_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_fd");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_handler_get_signo
+ *(void **) (&snd_async_handler_get_signo_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_signo");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_handler_get_callback_private
+ *(void **) (&snd_async_handler_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_shm_area_create
+ *(void **) (&snd_shm_area_create_dylibloader_wrapper_asound) = dlsym(handle, "snd_shm_area_create");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_shm_area_share
+ *(void **) (&snd_shm_area_share_dylibloader_wrapper_asound) = dlsym(handle, "snd_shm_area_share");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_shm_area_destroy
+ *(void **) (&snd_shm_area_destroy_dylibloader_wrapper_asound) = dlsym(handle, "snd_shm_area_destroy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_user_file
+ *(void **) (&snd_user_file_dylibloader_wrapper_asound) = dlsym(handle, "snd_user_file");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_input_stdio_open
+ *(void **) (&snd_input_stdio_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_stdio_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_input_stdio_attach
+ *(void **) (&snd_input_stdio_attach_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_stdio_attach");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_input_buffer_open
+ *(void **) (&snd_input_buffer_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_buffer_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_input_close
+ *(void **) (&snd_input_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_input_scanf
+ *(void **) (&snd_input_scanf_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_scanf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_input_gets
+ *(void **) (&snd_input_gets_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_gets");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_input_getc
+ *(void **) (&snd_input_getc_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_getc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_input_ungetc
+ *(void **) (&snd_input_ungetc_dylibloader_wrapper_asound) = dlsym(handle, "snd_input_ungetc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_stdio_open
+ *(void **) (&snd_output_stdio_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_stdio_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_stdio_attach
+ *(void **) (&snd_output_stdio_attach_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_stdio_attach");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_buffer_open
+ *(void **) (&snd_output_buffer_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_buffer_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_buffer_string
+ *(void **) (&snd_output_buffer_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_buffer_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_close
+ *(void **) (&snd_output_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_printf
+ *(void **) (&snd_output_printf_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_printf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_vprintf
+ *(void **) (&snd_output_vprintf_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_vprintf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_puts
+ *(void **) (&snd_output_puts_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_puts");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_putc
+ *(void **) (&snd_output_putc_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_putc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_output_flush
+ *(void **) (&snd_output_flush_dylibloader_wrapper_asound) = dlsym(handle, "snd_output_flush");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_strerror
+ *(void **) (&snd_strerror_dylibloader_wrapper_asound) = dlsym(handle, "snd_strerror");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_lib_error_set_handler
+ *(void **) (&snd_lib_error_set_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_lib_error_set_handler");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_lib_error_set_local
+ *(void **) (&snd_lib_error_set_local_dylibloader_wrapper_asound) = dlsym(handle, "snd_lib_error_set_local");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_topdir
+ *(void **) (&snd_config_topdir_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_topdir");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_top
+ *(void **) (&snd_config_top_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_top");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_load
+ *(void **) (&snd_config_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_load");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_load_override
+ *(void **) (&snd_config_load_override_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_load_override");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_save
+ *(void **) (&snd_config_save_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_save");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_update
+ *(void **) (&snd_config_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_update_r
+ *(void **) (&snd_config_update_r_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update_r");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_update_free
+ *(void **) (&snd_config_update_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_update_free_global
+ *(void **) (&snd_config_update_free_global_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update_free_global");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_update_ref
+ *(void **) (&snd_config_update_ref_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_update_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_ref
+ *(void **) (&snd_config_ref_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_unref
+ *(void **) (&snd_config_unref_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_search
+ *(void **) (&snd_config_search_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_search");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_searchv
+ *(void **) (&snd_config_searchv_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_searchv");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_search_definition
+ *(void **) (&snd_config_search_definition_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_search_definition");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_expand
+ *(void **) (&snd_config_expand_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_expand");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_evaluate
+ *(void **) (&snd_config_evaluate_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_evaluate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_add
+ *(void **) (&snd_config_add_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_add");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_add_before
+ *(void **) (&snd_config_add_before_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_add_before");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_add_after
+ *(void **) (&snd_config_add_after_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_add_after");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_remove
+ *(void **) (&snd_config_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_delete
+ *(void **) (&snd_config_delete_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_delete");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_delete_compound_members
+ *(void **) (&snd_config_delete_compound_members_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_delete_compound_members");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_copy
+ *(void **) (&snd_config_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_make
+ *(void **) (&snd_config_make_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_make_integer
+ *(void **) (&snd_config_make_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_make_integer64
+ *(void **) (&snd_config_make_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_integer64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_make_real
+ *(void **) (&snd_config_make_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_make_string
+ *(void **) (&snd_config_make_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_make_pointer
+ *(void **) (&snd_config_make_pointer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_pointer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_make_compound
+ *(void **) (&snd_config_make_compound_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_make_compound");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_imake_integer
+ *(void **) (&snd_config_imake_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_imake_integer64
+ *(void **) (&snd_config_imake_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_integer64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_imake_real
+ *(void **) (&snd_config_imake_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_imake_string
+ *(void **) (&snd_config_imake_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_imake_safe_string
+ *(void **) (&snd_config_imake_safe_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_safe_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_imake_pointer
+ *(void **) (&snd_config_imake_pointer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_imake_pointer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_type
+ *(void **) (&snd_config_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_is_array
+ *(void **) (&snd_config_is_array_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_is_array");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_set_id
+ *(void **) (&snd_config_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_set_integer
+ *(void **) (&snd_config_set_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_set_integer64
+ *(void **) (&snd_config_set_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_integer64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_set_real
+ *(void **) (&snd_config_set_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_set_string
+ *(void **) (&snd_config_set_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_set_ascii
+ *(void **) (&snd_config_set_ascii_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_ascii");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_set_pointer
+ *(void **) (&snd_config_set_pointer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_pointer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_id
+ *(void **) (&snd_config_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_integer
+ *(void **) (&snd_config_get_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_integer64
+ *(void **) (&snd_config_get_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_integer64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_real
+ *(void **) (&snd_config_get_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_ireal
+ *(void **) (&snd_config_get_ireal_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_ireal");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_string
+ *(void **) (&snd_config_get_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_ascii
+ *(void **) (&snd_config_get_ascii_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_ascii");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_pointer
+ *(void **) (&snd_config_get_pointer_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_pointer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_test_id
+ *(void **) (&snd_config_test_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_test_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_iterator_first
+ *(void **) (&snd_config_iterator_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_iterator_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_iterator_next
+ *(void **) (&snd_config_iterator_next_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_iterator_next");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_iterator_end
+ *(void **) (&snd_config_iterator_end_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_iterator_end");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_iterator_entry
+ *(void **) (&snd_config_iterator_entry_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_iterator_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_bool_ascii
+ *(void **) (&snd_config_get_bool_ascii_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_bool_ascii");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_bool
+ *(void **) (&snd_config_get_bool_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_bool");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_ctl_iface_ascii
+ *(void **) (&snd_config_get_ctl_iface_ascii_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_ctl_iface_ascii");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_config_get_ctl_iface
+ *(void **) (&snd_config_get_ctl_iface_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_get_ctl_iface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_names_list
+ *(void **) (&snd_names_list_dylibloader_wrapper_asound) = dlsym(handle, "snd_names_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_names_list_free
+ *(void **) (&snd_names_list_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_names_list_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_open
+ *(void **) (&snd_pcm_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_open_lconf
+ *(void **) (&snd_pcm_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_open_lconf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_open_fallback
+ *(void **) (&snd_pcm_open_fallback_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_open_fallback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_close
+ *(void **) (&snd_pcm_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_name
+ *(void **) (&snd_pcm_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_type
+ *(void **) (&snd_pcm_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_stream
+ *(void **) (&snd_pcm_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_stream");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_poll_descriptors_count
+ *(void **) (&snd_pcm_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_poll_descriptors_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_poll_descriptors
+ *(void **) (&snd_pcm_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_poll_descriptors");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_poll_descriptors_revents
+ *(void **) (&snd_pcm_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_poll_descriptors_revents");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_nonblock
+ *(void **) (&snd_pcm_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_nonblock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_add_pcm_handler
+ *(void **) (&snd_async_add_pcm_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_add_pcm_handler");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_handler_get_pcm
+ *(void **) (&snd_async_handler_get_pcm_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_pcm");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info
+ *(void **) (&snd_pcm_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_current
+ *(void **) (&snd_pcm_hw_params_current_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_current");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params
+ *(void **) (&snd_pcm_hw_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_free
+ *(void **) (&snd_pcm_hw_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_current
+ *(void **) (&snd_pcm_sw_params_current_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_current");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params
+ *(void **) (&snd_pcm_sw_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_prepare
+ *(void **) (&snd_pcm_prepare_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_prepare");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_reset
+ *(void **) (&snd_pcm_reset_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_reset");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status
+ *(void **) (&snd_pcm_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_start
+ *(void **) (&snd_pcm_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_start");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_drop
+ *(void **) (&snd_pcm_drop_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_drop");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_drain
+ *(void **) (&snd_pcm_drain_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_drain");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_pause
+ *(void **) (&snd_pcm_pause_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_pause");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_state
+ *(void **) (&snd_pcm_state_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_state");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hwsync
+ *(void **) (&snd_pcm_hwsync_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hwsync");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_delay
+ *(void **) (&snd_pcm_delay_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_delay");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_resume
+ *(void **) (&snd_pcm_resume_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_resume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_htimestamp
+ *(void **) (&snd_pcm_htimestamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_htimestamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_avail
+ *(void **) (&snd_pcm_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_avail");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_avail_update
+ *(void **) (&snd_pcm_avail_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_avail_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_avail_delay
+ *(void **) (&snd_pcm_avail_delay_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_avail_delay");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_rewindable
+ *(void **) (&snd_pcm_rewindable_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_rewindable");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_rewind
+ *(void **) (&snd_pcm_rewind_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_rewind");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_forwardable
+ *(void **) (&snd_pcm_forwardable_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_forwardable");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_forward
+ *(void **) (&snd_pcm_forward_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_forward");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_writei
+ *(void **) (&snd_pcm_writei_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_writei");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_readi
+ *(void **) (&snd_pcm_readi_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_readi");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_writen
+ *(void **) (&snd_pcm_writen_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_writen");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_readn
+ *(void **) (&snd_pcm_readn_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_readn");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_wait
+ *(void **) (&snd_pcm_wait_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_wait");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_link
+ *(void **) (&snd_pcm_link_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_link");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_unlink
+ *(void **) (&snd_pcm_unlink_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_unlink");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_query_chmaps
+ *(void **) (&snd_pcm_query_chmaps_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_query_chmaps");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_query_chmaps_from_hw
+ *(void **) (&snd_pcm_query_chmaps_from_hw_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_query_chmaps_from_hw");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_free_chmaps
+ *(void **) (&snd_pcm_free_chmaps_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_free_chmaps");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_get_chmap
+ *(void **) (&snd_pcm_get_chmap_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_get_chmap");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_set_chmap
+ *(void **) (&snd_pcm_set_chmap_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_set_chmap");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_chmap_type_name
+ *(void **) (&snd_pcm_chmap_type_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_type_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_chmap_name
+ *(void **) (&snd_pcm_chmap_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_chmap_long_name
+ *(void **) (&snd_pcm_chmap_long_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_long_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_chmap_print
+ *(void **) (&snd_pcm_chmap_print_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_print");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_chmap_from_string
+ *(void **) (&snd_pcm_chmap_from_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_from_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_chmap_parse_string
+ *(void **) (&snd_pcm_chmap_parse_string_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_chmap_parse_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_recover
+ *(void **) (&snd_pcm_recover_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_recover");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_set_params
+ *(void **) (&snd_pcm_set_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_set_params");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_get_params
+ *(void **) (&snd_pcm_get_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_get_params");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_sizeof
+ *(void **) (&snd_pcm_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_malloc
+ *(void **) (&snd_pcm_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_free
+ *(void **) (&snd_pcm_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_copy
+ *(void **) (&snd_pcm_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_device
+ *(void **) (&snd_pcm_info_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_subdevice
+ *(void **) (&snd_pcm_info_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_stream
+ *(void **) (&snd_pcm_info_get_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_stream");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_card
+ *(void **) (&snd_pcm_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_id
+ *(void **) (&snd_pcm_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_name
+ *(void **) (&snd_pcm_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_subdevice_name
+ *(void **) (&snd_pcm_info_get_subdevice_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subdevice_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_class
+ *(void **) (&snd_pcm_info_get_class_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_class");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_subclass
+ *(void **) (&snd_pcm_info_get_subclass_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subclass");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_subdevices_count
+ *(void **) (&snd_pcm_info_get_subdevices_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subdevices_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_subdevices_avail
+ *(void **) (&snd_pcm_info_get_subdevices_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_subdevices_avail");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_get_sync
+ *(void **) (&snd_pcm_info_get_sync_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_get_sync");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_set_device
+ *(void **) (&snd_pcm_info_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_set_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_set_subdevice
+ *(void **) (&snd_pcm_info_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_set_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_info_set_stream
+ *(void **) (&snd_pcm_info_set_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_info_set_stream");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_any
+ *(void **) (&snd_pcm_hw_params_any_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_any");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_can_mmap_sample_resolution
+ *(void **) (&snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_mmap_sample_resolution");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_is_double
+ *(void **) (&snd_pcm_hw_params_is_double_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_double");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_is_batch
+ *(void **) (&snd_pcm_hw_params_is_batch_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_batch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_is_block_transfer
+ *(void **) (&snd_pcm_hw_params_is_block_transfer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_block_transfer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_is_monotonic
+ *(void **) (&snd_pcm_hw_params_is_monotonic_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_monotonic");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_can_overrange
+ *(void **) (&snd_pcm_hw_params_can_overrange_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_overrange");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_can_pause
+ *(void **) (&snd_pcm_hw_params_can_pause_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_pause");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_can_resume
+ *(void **) (&snd_pcm_hw_params_can_resume_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_resume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_is_half_duplex
+ *(void **) (&snd_pcm_hw_params_is_half_duplex_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_half_duplex");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_is_joint_duplex
+ *(void **) (&snd_pcm_hw_params_is_joint_duplex_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_is_joint_duplex");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_can_sync_start
+ *(void **) (&snd_pcm_hw_params_can_sync_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_sync_start");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_can_disable_period_wakeup
+ *(void **) (&snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_can_disable_period_wakeup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_supports_audio_wallclock_ts
+ *(void **) (&snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_supports_audio_wallclock_ts");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_supports_audio_ts_type
+ *(void **) (&snd_pcm_hw_params_supports_audio_ts_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_supports_audio_ts_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_rate_numden
+ *(void **) (&snd_pcm_hw_params_get_rate_numden_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate_numden");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_sbits
+ *(void **) (&snd_pcm_hw_params_get_sbits_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_sbits");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_fifo_size
+ *(void **) (&snd_pcm_hw_params_get_fifo_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_fifo_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_sizeof
+ *(void **) (&snd_pcm_hw_params_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_malloc
+ *(void **) (&snd_pcm_hw_params_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_free
+ *(void **) (&snd_pcm_hw_params_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_copy
+ *(void **) (&snd_pcm_hw_params_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_access
+ *(void **) (&snd_pcm_hw_params_get_access_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_access");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_access
+ *(void **) (&snd_pcm_hw_params_test_access_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_access");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_access
+ *(void **) (&snd_pcm_hw_params_set_access_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_access");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_access_first
+ *(void **) (&snd_pcm_hw_params_set_access_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_access_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_access_last
+ *(void **) (&snd_pcm_hw_params_set_access_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_access_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_access_mask
+ *(void **) (&snd_pcm_hw_params_set_access_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_access_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_access_mask
+ *(void **) (&snd_pcm_hw_params_get_access_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_access_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_format
+ *(void **) (&snd_pcm_hw_params_get_format_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_format");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_format
+ *(void **) (&snd_pcm_hw_params_test_format_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_format");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_format
+ *(void **) (&snd_pcm_hw_params_set_format_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_format");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_format_first
+ *(void **) (&snd_pcm_hw_params_set_format_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_format_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_format_last
+ *(void **) (&snd_pcm_hw_params_set_format_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_format_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_format_mask
+ *(void **) (&snd_pcm_hw_params_set_format_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_format_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_format_mask
+ *(void **) (&snd_pcm_hw_params_get_format_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_format_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_subformat
+ *(void **) (&snd_pcm_hw_params_get_subformat_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_subformat");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_subformat
+ *(void **) (&snd_pcm_hw_params_test_subformat_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_subformat");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_subformat
+ *(void **) (&snd_pcm_hw_params_set_subformat_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_subformat");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_subformat_first
+ *(void **) (&snd_pcm_hw_params_set_subformat_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_subformat_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_subformat_last
+ *(void **) (&snd_pcm_hw_params_set_subformat_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_subformat_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_subformat_mask
+ *(void **) (&snd_pcm_hw_params_set_subformat_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_subformat_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_subformat_mask
+ *(void **) (&snd_pcm_hw_params_get_subformat_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_subformat_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_channels
+ *(void **) (&snd_pcm_hw_params_get_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_channels_min
+ *(void **) (&snd_pcm_hw_params_get_channels_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_channels_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_channels_max
+ *(void **) (&snd_pcm_hw_params_get_channels_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_channels_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_channels
+ *(void **) (&snd_pcm_hw_params_test_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_channels
+ *(void **) (&snd_pcm_hw_params_set_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_channels_min
+ *(void **) (&snd_pcm_hw_params_set_channels_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_channels_max
+ *(void **) (&snd_pcm_hw_params_set_channels_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_channels_minmax
+ *(void **) (&snd_pcm_hw_params_set_channels_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_minmax");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_channels_near
+ *(void **) (&snd_pcm_hw_params_set_channels_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_near");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_channels_first
+ *(void **) (&snd_pcm_hw_params_set_channels_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_channels_last
+ *(void **) (&snd_pcm_hw_params_set_channels_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_channels_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_rate
+ *(void **) (&snd_pcm_hw_params_get_rate_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_rate_min
+ *(void **) (&snd_pcm_hw_params_get_rate_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_rate_max
+ *(void **) (&snd_pcm_hw_params_get_rate_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_rate
+ *(void **) (&snd_pcm_hw_params_test_rate_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_rate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_rate
+ *(void **) (&snd_pcm_hw_params_set_rate_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_rate_min
+ *(void **) (&snd_pcm_hw_params_set_rate_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_rate_max
+ *(void **) (&snd_pcm_hw_params_set_rate_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_rate_minmax
+ *(void **) (&snd_pcm_hw_params_set_rate_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_minmax");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_rate_near
+ *(void **) (&snd_pcm_hw_params_set_rate_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_near");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_rate_first
+ *(void **) (&snd_pcm_hw_params_set_rate_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_rate_last
+ *(void **) (&snd_pcm_hw_params_set_rate_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_rate_resample
+ *(void **) (&snd_pcm_hw_params_set_rate_resample_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_rate_resample");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_rate_resample
+ *(void **) (&snd_pcm_hw_params_get_rate_resample_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_rate_resample");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_export_buffer
+ *(void **) (&snd_pcm_hw_params_set_export_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_export_buffer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_export_buffer
+ *(void **) (&snd_pcm_hw_params_get_export_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_export_buffer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_wakeup
+ *(void **) (&snd_pcm_hw_params_set_period_wakeup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_wakeup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_period_wakeup
+ *(void **) (&snd_pcm_hw_params_get_period_wakeup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_wakeup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_period_time
+ *(void **) (&snd_pcm_hw_params_get_period_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_period_time_min
+ *(void **) (&snd_pcm_hw_params_get_period_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_time_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_period_time_max
+ *(void **) (&snd_pcm_hw_params_get_period_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_time_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_period_time
+ *(void **) (&snd_pcm_hw_params_test_period_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_period_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_time
+ *(void **) (&snd_pcm_hw_params_set_period_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_time_min
+ *(void **) (&snd_pcm_hw_params_set_period_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_time_max
+ *(void **) (&snd_pcm_hw_params_set_period_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_time_minmax
+ *(void **) (&snd_pcm_hw_params_set_period_time_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_minmax");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_time_near
+ *(void **) (&snd_pcm_hw_params_set_period_time_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_near");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_time_first
+ *(void **) (&snd_pcm_hw_params_set_period_time_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_time_last
+ *(void **) (&snd_pcm_hw_params_set_period_time_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_time_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_period_size
+ *(void **) (&snd_pcm_hw_params_get_period_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_period_size_min
+ *(void **) (&snd_pcm_hw_params_get_period_size_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_size_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_period_size_max
+ *(void **) (&snd_pcm_hw_params_get_period_size_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_period_size_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_period_size
+ *(void **) (&snd_pcm_hw_params_test_period_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_period_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_size
+ *(void **) (&snd_pcm_hw_params_set_period_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_size_min
+ *(void **) (&snd_pcm_hw_params_set_period_size_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_size_max
+ *(void **) (&snd_pcm_hw_params_set_period_size_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_size_minmax
+ *(void **) (&snd_pcm_hw_params_set_period_size_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_minmax");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_size_near
+ *(void **) (&snd_pcm_hw_params_set_period_size_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_near");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_size_first
+ *(void **) (&snd_pcm_hw_params_set_period_size_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_size_last
+ *(void **) (&snd_pcm_hw_params_set_period_size_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_period_size_integer
+ *(void **) (&snd_pcm_hw_params_set_period_size_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_period_size_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_periods
+ *(void **) (&snd_pcm_hw_params_get_periods_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_periods");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_periods_min
+ *(void **) (&snd_pcm_hw_params_get_periods_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_periods_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_periods_max
+ *(void **) (&snd_pcm_hw_params_get_periods_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_periods_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_periods
+ *(void **) (&snd_pcm_hw_params_test_periods_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_periods");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_periods
+ *(void **) (&snd_pcm_hw_params_set_periods_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_periods_min
+ *(void **) (&snd_pcm_hw_params_set_periods_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_periods_max
+ *(void **) (&snd_pcm_hw_params_set_periods_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_periods_minmax
+ *(void **) (&snd_pcm_hw_params_set_periods_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_minmax");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_periods_near
+ *(void **) (&snd_pcm_hw_params_set_periods_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_near");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_periods_first
+ *(void **) (&snd_pcm_hw_params_set_periods_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_periods_last
+ *(void **) (&snd_pcm_hw_params_set_periods_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_periods_integer
+ *(void **) (&snd_pcm_hw_params_set_periods_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_periods_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_buffer_time
+ *(void **) (&snd_pcm_hw_params_get_buffer_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_buffer_time_min
+ *(void **) (&snd_pcm_hw_params_get_buffer_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_time_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_buffer_time_max
+ *(void **) (&snd_pcm_hw_params_get_buffer_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_time_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_buffer_time
+ *(void **) (&snd_pcm_hw_params_test_buffer_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_buffer_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_time
+ *(void **) (&snd_pcm_hw_params_set_buffer_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_time_min
+ *(void **) (&snd_pcm_hw_params_set_buffer_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_time_max
+ *(void **) (&snd_pcm_hw_params_set_buffer_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_time_minmax
+ *(void **) (&snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_minmax");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_time_near
+ *(void **) (&snd_pcm_hw_params_set_buffer_time_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_near");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_time_first
+ *(void **) (&snd_pcm_hw_params_set_buffer_time_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_time_last
+ *(void **) (&snd_pcm_hw_params_set_buffer_time_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_time_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_buffer_size
+ *(void **) (&snd_pcm_hw_params_get_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_buffer_size_min
+ *(void **) (&snd_pcm_hw_params_get_buffer_size_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_size_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_buffer_size_max
+ *(void **) (&snd_pcm_hw_params_get_buffer_size_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_buffer_size_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_buffer_size
+ *(void **) (&snd_pcm_hw_params_test_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_size
+ *(void **) (&snd_pcm_hw_params_set_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_size_min
+ *(void **) (&snd_pcm_hw_params_set_buffer_size_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_size_max
+ *(void **) (&snd_pcm_hw_params_set_buffer_size_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_size_minmax
+ *(void **) (&snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_minmax");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_size_near
+ *(void **) (&snd_pcm_hw_params_set_buffer_size_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_near");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_size_first
+ *(void **) (&snd_pcm_hw_params_set_buffer_size_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_buffer_size_last
+ *(void **) (&snd_pcm_hw_params_set_buffer_size_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_buffer_size_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_min_align
+ *(void **) (&snd_pcm_hw_params_get_min_align_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_min_align");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_sizeof
+ *(void **) (&snd_pcm_sw_params_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_malloc
+ *(void **) (&snd_pcm_sw_params_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_free
+ *(void **) (&snd_pcm_sw_params_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_copy
+ *(void **) (&snd_pcm_sw_params_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_boundary
+ *(void **) (&snd_pcm_sw_params_get_boundary_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_boundary");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_tstamp_mode
+ *(void **) (&snd_pcm_sw_params_set_tstamp_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_tstamp_mode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_tstamp_mode
+ *(void **) (&snd_pcm_sw_params_get_tstamp_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_tstamp_mode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_avail_min
+ *(void **) (&snd_pcm_sw_params_set_avail_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_avail_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_avail_min
+ *(void **) (&snd_pcm_sw_params_get_avail_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_avail_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_period_event
+ *(void **) (&snd_pcm_sw_params_set_period_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_period_event");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_period_event
+ *(void **) (&snd_pcm_sw_params_get_period_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_period_event");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_start_threshold
+ *(void **) (&snd_pcm_sw_params_set_start_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_start_threshold");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_start_threshold
+ *(void **) (&snd_pcm_sw_params_get_start_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_start_threshold");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_stop_threshold
+ *(void **) (&snd_pcm_sw_params_set_stop_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_stop_threshold");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_stop_threshold
+ *(void **) (&snd_pcm_sw_params_get_stop_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_stop_threshold");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_silence_threshold
+ *(void **) (&snd_pcm_sw_params_set_silence_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_silence_threshold");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_silence_threshold
+ *(void **) (&snd_pcm_sw_params_get_silence_threshold_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_silence_threshold");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_silence_size
+ *(void **) (&snd_pcm_sw_params_set_silence_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_silence_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_silence_size
+ *(void **) (&snd_pcm_sw_params_get_silence_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_silence_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_sizeof
+ *(void **) (&snd_pcm_access_mask_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_malloc
+ *(void **) (&snd_pcm_access_mask_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_free
+ *(void **) (&snd_pcm_access_mask_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_copy
+ *(void **) (&snd_pcm_access_mask_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_none
+ *(void **) (&snd_pcm_access_mask_none_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_none");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_any
+ *(void **) (&snd_pcm_access_mask_any_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_any");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_test
+ *(void **) (&snd_pcm_access_mask_test_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_test");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_empty
+ *(void **) (&snd_pcm_access_mask_empty_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_empty");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_set
+ *(void **) (&snd_pcm_access_mask_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_mask_reset
+ *(void **) (&snd_pcm_access_mask_reset_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_mask_reset");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_sizeof
+ *(void **) (&snd_pcm_format_mask_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_malloc
+ *(void **) (&snd_pcm_format_mask_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_free
+ *(void **) (&snd_pcm_format_mask_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_copy
+ *(void **) (&snd_pcm_format_mask_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_none
+ *(void **) (&snd_pcm_format_mask_none_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_none");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_any
+ *(void **) (&snd_pcm_format_mask_any_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_any");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_test
+ *(void **) (&snd_pcm_format_mask_test_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_test");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_empty
+ *(void **) (&snd_pcm_format_mask_empty_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_empty");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_set
+ *(void **) (&snd_pcm_format_mask_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_mask_reset
+ *(void **) (&snd_pcm_format_mask_reset_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_mask_reset");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_sizeof
+ *(void **) (&snd_pcm_subformat_mask_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_malloc
+ *(void **) (&snd_pcm_subformat_mask_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_free
+ *(void **) (&snd_pcm_subformat_mask_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_copy
+ *(void **) (&snd_pcm_subformat_mask_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_none
+ *(void **) (&snd_pcm_subformat_mask_none_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_none");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_any
+ *(void **) (&snd_pcm_subformat_mask_any_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_any");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_test
+ *(void **) (&snd_pcm_subformat_mask_test_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_test");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_empty
+ *(void **) (&snd_pcm_subformat_mask_empty_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_empty");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_set
+ *(void **) (&snd_pcm_subformat_mask_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_mask_reset
+ *(void **) (&snd_pcm_subformat_mask_reset_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_mask_reset");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_sizeof
+ *(void **) (&snd_pcm_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_malloc
+ *(void **) (&snd_pcm_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_free
+ *(void **) (&snd_pcm_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_copy
+ *(void **) (&snd_pcm_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_state
+ *(void **) (&snd_pcm_status_get_state_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_state");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_trigger_tstamp
+ *(void **) (&snd_pcm_status_get_trigger_tstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_trigger_tstamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_trigger_htstamp
+ *(void **) (&snd_pcm_status_get_trigger_htstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_trigger_htstamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_tstamp
+ *(void **) (&snd_pcm_status_get_tstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_tstamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_htstamp
+ *(void **) (&snd_pcm_status_get_htstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_htstamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_audio_htstamp
+ *(void **) (&snd_pcm_status_get_audio_htstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_audio_htstamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_driver_htstamp
+ *(void **) (&snd_pcm_status_get_driver_htstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_driver_htstamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_delay
+ *(void **) (&snd_pcm_status_get_delay_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_delay");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_avail
+ *(void **) (&snd_pcm_status_get_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_avail");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_avail_max
+ *(void **) (&snd_pcm_status_get_avail_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_avail_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_get_overrange
+ *(void **) (&snd_pcm_status_get_overrange_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_get_overrange");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_type_name
+ *(void **) (&snd_pcm_type_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_type_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_stream_name
+ *(void **) (&snd_pcm_stream_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_stream_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_access_name
+ *(void **) (&snd_pcm_access_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_access_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_name
+ *(void **) (&snd_pcm_format_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_description
+ *(void **) (&snd_pcm_format_description_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_description");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_name
+ *(void **) (&snd_pcm_subformat_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_subformat_description
+ *(void **) (&snd_pcm_subformat_description_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_subformat_description");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_value
+ *(void **) (&snd_pcm_format_value_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_tstamp_mode_name
+ *(void **) (&snd_pcm_tstamp_mode_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_tstamp_mode_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_state_name
+ *(void **) (&snd_pcm_state_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_state_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_dump
+ *(void **) (&snd_pcm_dump_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_dump");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_dump_hw_setup
+ *(void **) (&snd_pcm_dump_hw_setup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_dump_hw_setup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_dump_sw_setup
+ *(void **) (&snd_pcm_dump_sw_setup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_dump_sw_setup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_dump_setup
+ *(void **) (&snd_pcm_dump_setup_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_dump_setup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_dump
+ *(void **) (&snd_pcm_hw_params_dump_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_dump");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_dump
+ *(void **) (&snd_pcm_sw_params_dump_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_dump");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_status_dump
+ *(void **) (&snd_pcm_status_dump_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_status_dump");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_mmap_begin
+ *(void **) (&snd_pcm_mmap_begin_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_begin");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_mmap_commit
+ *(void **) (&snd_pcm_mmap_commit_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_commit");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_mmap_writei
+ *(void **) (&snd_pcm_mmap_writei_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_writei");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_mmap_readi
+ *(void **) (&snd_pcm_mmap_readi_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_readi");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_mmap_writen
+ *(void **) (&snd_pcm_mmap_writen_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_writen");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_mmap_readn
+ *(void **) (&snd_pcm_mmap_readn_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_mmap_readn");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_signed
+ *(void **) (&snd_pcm_format_signed_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_signed");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_unsigned
+ *(void **) (&snd_pcm_format_unsigned_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_unsigned");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_linear
+ *(void **) (&snd_pcm_format_linear_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_linear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_float
+ *(void **) (&snd_pcm_format_float_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_float");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_little_endian
+ *(void **) (&snd_pcm_format_little_endian_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_little_endian");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_big_endian
+ *(void **) (&snd_pcm_format_big_endian_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_big_endian");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_cpu_endian
+ *(void **) (&snd_pcm_format_cpu_endian_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_cpu_endian");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_width
+ *(void **) (&snd_pcm_format_width_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_width");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_physical_width
+ *(void **) (&snd_pcm_format_physical_width_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_physical_width");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_build_linear_format
+ *(void **) (&snd_pcm_build_linear_format_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_build_linear_format");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_size
+ *(void **) (&snd_pcm_format_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_silence
+ *(void **) (&snd_pcm_format_silence_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_silence");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_silence_16
+ *(void **) (&snd_pcm_format_silence_16_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_silence_16");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_silence_32
+ *(void **) (&snd_pcm_format_silence_32_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_silence_32");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_silence_64
+ *(void **) (&snd_pcm_format_silence_64_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_silence_64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_format_set_silence
+ *(void **) (&snd_pcm_format_set_silence_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_format_set_silence");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_bytes_to_frames
+ *(void **) (&snd_pcm_bytes_to_frames_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_bytes_to_frames");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_frames_to_bytes
+ *(void **) (&snd_pcm_frames_to_bytes_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_frames_to_bytes");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_bytes_to_samples
+ *(void **) (&snd_pcm_bytes_to_samples_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_bytes_to_samples");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_samples_to_bytes
+ *(void **) (&snd_pcm_samples_to_bytes_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_samples_to_bytes");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_area_silence
+ *(void **) (&snd_pcm_area_silence_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_area_silence");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_areas_silence
+ *(void **) (&snd_pcm_areas_silence_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_areas_silence");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_area_copy
+ *(void **) (&snd_pcm_area_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_area_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_areas_copy
+ *(void **) (&snd_pcm_areas_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_areas_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_areas_copy_wrap
+ *(void **) (&snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_areas_copy_wrap");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hook_get_pcm
+ *(void **) (&snd_pcm_hook_get_pcm_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_get_pcm");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hook_get_private
+ *(void **) (&snd_pcm_hook_get_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_get_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hook_set_private
+ *(void **) (&snd_pcm_hook_set_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_set_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hook_add
+ *(void **) (&snd_pcm_hook_add_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_add");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hook_remove
+ *(void **) (&snd_pcm_hook_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_meter_get_bufsize
+ *(void **) (&snd_pcm_meter_get_bufsize_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_bufsize");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_meter_get_channels
+ *(void **) (&snd_pcm_meter_get_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_meter_get_rate
+ *(void **) (&snd_pcm_meter_get_rate_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_rate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_meter_get_now
+ *(void **) (&snd_pcm_meter_get_now_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_now");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_meter_get_boundary
+ *(void **) (&snd_pcm_meter_get_boundary_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_get_boundary");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_meter_add_scope
+ *(void **) (&snd_pcm_meter_add_scope_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_add_scope");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_meter_search_scope
+ *(void **) (&snd_pcm_meter_search_scope_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_meter_search_scope");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_scope_malloc
+ *(void **) (&snd_pcm_scope_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_scope_set_ops
+ *(void **) (&snd_pcm_scope_set_ops_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_set_ops");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_scope_set_name
+ *(void **) (&snd_pcm_scope_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_scope_get_name
+ *(void **) (&snd_pcm_scope_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_scope_get_callback_private
+ *(void **) (&snd_pcm_scope_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_get_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_scope_set_callback_private
+ *(void **) (&snd_pcm_scope_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_set_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_scope_s16_open
+ *(void **) (&snd_pcm_scope_s16_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_s16_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_scope_s16_get_channel_buffer
+ *(void **) (&snd_pcm_scope_s16_get_channel_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_scope_s16_get_channel_buffer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_spcm_init
+ *(void **) (&snd_spcm_init_dylibloader_wrapper_asound) = dlsym(handle, "snd_spcm_init");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_spcm_init_duplex
+ *(void **) (&snd_spcm_init_duplex_dylibloader_wrapper_asound) = dlsym(handle, "snd_spcm_init_duplex");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_spcm_init_get_params
+ *(void **) (&snd_spcm_init_get_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_spcm_init_get_params");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_start_mode_name
+ *(void **) (&snd_pcm_start_mode_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_start_mode_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_xrun_mode_name
+ *(void **) (&snd_pcm_xrun_mode_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_xrun_mode_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_start_mode
+ *(void **) (&snd_pcm_sw_params_set_start_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_start_mode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_start_mode
+ *(void **) (&snd_pcm_sw_params_get_start_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_start_mode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_xrun_mode
+ *(void **) (&snd_pcm_sw_params_set_xrun_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_xrun_mode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_xrun_mode
+ *(void **) (&snd_pcm_sw_params_get_xrun_mode_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_xrun_mode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_xfer_align
+ *(void **) (&snd_pcm_sw_params_set_xfer_align_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_xfer_align");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_xfer_align
+ *(void **) (&snd_pcm_sw_params_get_xfer_align_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_xfer_align");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_set_sleep_min
+ *(void **) (&snd_pcm_sw_params_set_sleep_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_set_sleep_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_sw_params_get_sleep_min
+ *(void **) (&snd_pcm_sw_params_get_sleep_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_sw_params_get_sleep_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_tick_time
+ *(void **) (&snd_pcm_hw_params_get_tick_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_tick_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_tick_time_min
+ *(void **) (&snd_pcm_hw_params_get_tick_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_tick_time_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_get_tick_time_max
+ *(void **) (&snd_pcm_hw_params_get_tick_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_get_tick_time_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_test_tick_time
+ *(void **) (&snd_pcm_hw_params_test_tick_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_test_tick_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_tick_time
+ *(void **) (&snd_pcm_hw_params_set_tick_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_tick_time_min
+ *(void **) (&snd_pcm_hw_params_set_tick_time_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_tick_time_max
+ *(void **) (&snd_pcm_hw_params_set_tick_time_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_tick_time_minmax
+ *(void **) (&snd_pcm_hw_params_set_tick_time_minmax_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_minmax");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_tick_time_near
+ *(void **) (&snd_pcm_hw_params_set_tick_time_near_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_near");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_tick_time_first
+ *(void **) (&snd_pcm_hw_params_set_tick_time_first_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_first");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_pcm_hw_params_set_tick_time_last
+ *(void **) (&snd_pcm_hw_params_set_tick_time_last_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hw_params_set_tick_time_last");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_open
+ *(void **) (&snd_rawmidi_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_open_lconf
+ *(void **) (&snd_rawmidi_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_open_lconf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_close
+ *(void **) (&snd_rawmidi_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_poll_descriptors_count
+ *(void **) (&snd_rawmidi_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_poll_descriptors_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_poll_descriptors
+ *(void **) (&snd_rawmidi_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_poll_descriptors");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_poll_descriptors_revents
+ *(void **) (&snd_rawmidi_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_poll_descriptors_revents");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_nonblock
+ *(void **) (&snd_rawmidi_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_nonblock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_sizeof
+ *(void **) (&snd_rawmidi_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_malloc
+ *(void **) (&snd_rawmidi_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_free
+ *(void **) (&snd_rawmidi_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_copy
+ *(void **) (&snd_rawmidi_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_device
+ *(void **) (&snd_rawmidi_info_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_subdevice
+ *(void **) (&snd_rawmidi_info_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_stream
+ *(void **) (&snd_rawmidi_info_get_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_stream");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_card
+ *(void **) (&snd_rawmidi_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_flags
+ *(void **) (&snd_rawmidi_info_get_flags_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_flags");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_id
+ *(void **) (&snd_rawmidi_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_name
+ *(void **) (&snd_rawmidi_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_subdevice_name
+ *(void **) (&snd_rawmidi_info_get_subdevice_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_subdevice_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_subdevices_count
+ *(void **) (&snd_rawmidi_info_get_subdevices_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_subdevices_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_get_subdevices_avail
+ *(void **) (&snd_rawmidi_info_get_subdevices_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_get_subdevices_avail");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_set_device
+ *(void **) (&snd_rawmidi_info_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_set_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_set_subdevice
+ *(void **) (&snd_rawmidi_info_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_set_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info_set_stream
+ *(void **) (&snd_rawmidi_info_set_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info_set_stream");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_info
+ *(void **) (&snd_rawmidi_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_sizeof
+ *(void **) (&snd_rawmidi_params_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_malloc
+ *(void **) (&snd_rawmidi_params_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_free
+ *(void **) (&snd_rawmidi_params_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_copy
+ *(void **) (&snd_rawmidi_params_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_set_buffer_size
+ *(void **) (&snd_rawmidi_params_set_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_set_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_get_buffer_size
+ *(void **) (&snd_rawmidi_params_get_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_get_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_set_avail_min
+ *(void **) (&snd_rawmidi_params_set_avail_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_set_avail_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_get_avail_min
+ *(void **) (&snd_rawmidi_params_get_avail_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_get_avail_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_set_no_active_sensing
+ *(void **) (&snd_rawmidi_params_set_no_active_sensing_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_set_no_active_sensing");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_get_no_active_sensing
+ *(void **) (&snd_rawmidi_params_get_no_active_sensing_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_get_no_active_sensing");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params
+ *(void **) (&snd_rawmidi_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_params_current
+ *(void **) (&snd_rawmidi_params_current_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_params_current");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_status_sizeof
+ *(void **) (&snd_rawmidi_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_status_malloc
+ *(void **) (&snd_rawmidi_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_status_free
+ *(void **) (&snd_rawmidi_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_status_copy
+ *(void **) (&snd_rawmidi_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_status_get_tstamp
+ *(void **) (&snd_rawmidi_status_get_tstamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_get_tstamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_status_get_avail
+ *(void **) (&snd_rawmidi_status_get_avail_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_get_avail");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_status_get_xruns
+ *(void **) (&snd_rawmidi_status_get_xruns_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status_get_xruns");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_status
+ *(void **) (&snd_rawmidi_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_status");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_drain
+ *(void **) (&snd_rawmidi_drain_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_drain");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_drop
+ *(void **) (&snd_rawmidi_drop_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_drop");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_write
+ *(void **) (&snd_rawmidi_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_read
+ *(void **) (&snd_rawmidi_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_read");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_name
+ *(void **) (&snd_rawmidi_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_type
+ *(void **) (&snd_rawmidi_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_rawmidi_stream
+ *(void **) (&snd_rawmidi_stream_dylibloader_wrapper_asound) = dlsym(handle, "snd_rawmidi_stream");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_query_open
+ *(void **) (&snd_timer_query_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_query_open_lconf
+ *(void **) (&snd_timer_query_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_open_lconf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_query_close
+ *(void **) (&snd_timer_query_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_query_next_device
+ *(void **) (&snd_timer_query_next_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_next_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_query_info
+ *(void **) (&snd_timer_query_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_query_params
+ *(void **) (&snd_timer_query_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_params");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_query_status
+ *(void **) (&snd_timer_query_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_query_status");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_open
+ *(void **) (&snd_timer_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_open_lconf
+ *(void **) (&snd_timer_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_open_lconf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_close
+ *(void **) (&snd_timer_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_add_timer_handler
+ *(void **) (&snd_async_add_timer_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_add_timer_handler");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_handler_get_timer
+ *(void **) (&snd_async_handler_get_timer_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_timer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_poll_descriptors_count
+ *(void **) (&snd_timer_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_poll_descriptors_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_poll_descriptors
+ *(void **) (&snd_timer_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_poll_descriptors");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_poll_descriptors_revents
+ *(void **) (&snd_timer_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_poll_descriptors_revents");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info
+ *(void **) (&snd_timer_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params
+ *(void **) (&snd_timer_params_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status
+ *(void **) (&snd_timer_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_start
+ *(void **) (&snd_timer_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_start");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_stop
+ *(void **) (&snd_timer_stop_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_stop");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_continue
+ *(void **) (&snd_timer_continue_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_continue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_read
+ *(void **) (&snd_timer_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_read");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_sizeof
+ *(void **) (&snd_timer_id_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_malloc
+ *(void **) (&snd_timer_id_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_free
+ *(void **) (&snd_timer_id_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_copy
+ *(void **) (&snd_timer_id_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_set_class
+ *(void **) (&snd_timer_id_set_class_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_class");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_get_class
+ *(void **) (&snd_timer_id_get_class_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_class");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_set_sclass
+ *(void **) (&snd_timer_id_set_sclass_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_sclass");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_get_sclass
+ *(void **) (&snd_timer_id_get_sclass_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_sclass");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_set_card
+ *(void **) (&snd_timer_id_set_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_get_card
+ *(void **) (&snd_timer_id_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_set_device
+ *(void **) (&snd_timer_id_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_get_device
+ *(void **) (&snd_timer_id_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_set_subdevice
+ *(void **) (&snd_timer_id_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_set_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_id_get_subdevice
+ *(void **) (&snd_timer_id_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_id_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_sizeof
+ *(void **) (&snd_timer_ginfo_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_malloc
+ *(void **) (&snd_timer_ginfo_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_free
+ *(void **) (&snd_timer_ginfo_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_copy
+ *(void **) (&snd_timer_ginfo_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_set_tid
+ *(void **) (&snd_timer_ginfo_set_tid_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_set_tid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_tid
+ *(void **) (&snd_timer_ginfo_get_tid_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_tid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_flags
+ *(void **) (&snd_timer_ginfo_get_flags_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_flags");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_card
+ *(void **) (&snd_timer_ginfo_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_id
+ *(void **) (&snd_timer_ginfo_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_name
+ *(void **) (&snd_timer_ginfo_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_resolution
+ *(void **) (&snd_timer_ginfo_get_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_resolution");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_resolution_min
+ *(void **) (&snd_timer_ginfo_get_resolution_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_resolution_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_resolution_max
+ *(void **) (&snd_timer_ginfo_get_resolution_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_resolution_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_ginfo_get_clients
+ *(void **) (&snd_timer_ginfo_get_clients_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_ginfo_get_clients");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_sizeof
+ *(void **) (&snd_timer_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_malloc
+ *(void **) (&snd_timer_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_free
+ *(void **) (&snd_timer_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_copy
+ *(void **) (&snd_timer_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_is_slave
+ *(void **) (&snd_timer_info_is_slave_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_is_slave");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_get_card
+ *(void **) (&snd_timer_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_get_id
+ *(void **) (&snd_timer_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_get_name
+ *(void **) (&snd_timer_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_get_resolution
+ *(void **) (&snd_timer_info_get_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_resolution");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_sizeof
+ *(void **) (&snd_timer_params_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_malloc
+ *(void **) (&snd_timer_params_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_free
+ *(void **) (&snd_timer_params_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_copy
+ *(void **) (&snd_timer_params_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_set_auto_start
+ *(void **) (&snd_timer_params_set_auto_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_auto_start");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_get_auto_start
+ *(void **) (&snd_timer_params_get_auto_start_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_auto_start");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_set_exclusive
+ *(void **) (&snd_timer_params_set_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_exclusive");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_get_exclusive
+ *(void **) (&snd_timer_params_get_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_exclusive");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_set_early_event
+ *(void **) (&snd_timer_params_set_early_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_early_event");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_get_early_event
+ *(void **) (&snd_timer_params_get_early_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_early_event");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_set_ticks
+ *(void **) (&snd_timer_params_set_ticks_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_ticks");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_get_ticks
+ *(void **) (&snd_timer_params_get_ticks_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_ticks");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_set_queue_size
+ *(void **) (&snd_timer_params_set_queue_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_queue_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_get_queue_size
+ *(void **) (&snd_timer_params_get_queue_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_queue_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_set_filter
+ *(void **) (&snd_timer_params_set_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_set_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_params_get_filter
+ *(void **) (&snd_timer_params_get_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_params_get_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_sizeof
+ *(void **) (&snd_timer_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_malloc
+ *(void **) (&snd_timer_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_free
+ *(void **) (&snd_timer_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_copy
+ *(void **) (&snd_timer_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_get_timestamp
+ *(void **) (&snd_timer_status_get_timestamp_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_timestamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_get_resolution
+ *(void **) (&snd_timer_status_get_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_resolution");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_get_lost
+ *(void **) (&snd_timer_status_get_lost_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_lost");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_get_overrun
+ *(void **) (&snd_timer_status_get_overrun_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_overrun");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_status_get_queue
+ *(void **) (&snd_timer_status_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_status_get_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_timer_info_get_ticks
+ *(void **) (&snd_timer_info_get_ticks_dylibloader_wrapper_asound) = dlsym(handle, "snd_timer_info_get_ticks");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_open
+ *(void **) (&snd_hwdep_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_close
+ *(void **) (&snd_hwdep_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_poll_descriptors
+ *(void **) (&snd_hwdep_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_poll_descriptors");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_poll_descriptors_count
+ *(void **) (&snd_hwdep_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_poll_descriptors_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_poll_descriptors_revents
+ *(void **) (&snd_hwdep_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_poll_descriptors_revents");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_nonblock
+ *(void **) (&snd_hwdep_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_nonblock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info
+ *(void **) (&snd_hwdep_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status
+ *(void **) (&snd_hwdep_dsp_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_load
+ *(void **) (&snd_hwdep_dsp_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_load");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_ioctl
+ *(void **) (&snd_hwdep_ioctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_ioctl");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_write
+ *(void **) (&snd_hwdep_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_read
+ *(void **) (&snd_hwdep_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_read");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_sizeof
+ *(void **) (&snd_hwdep_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_malloc
+ *(void **) (&snd_hwdep_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_free
+ *(void **) (&snd_hwdep_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_copy
+ *(void **) (&snd_hwdep_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_get_device
+ *(void **) (&snd_hwdep_info_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_get_card
+ *(void **) (&snd_hwdep_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_get_id
+ *(void **) (&snd_hwdep_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_get_name
+ *(void **) (&snd_hwdep_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_get_iface
+ *(void **) (&snd_hwdep_info_get_iface_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_get_iface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_info_set_device
+ *(void **) (&snd_hwdep_info_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_info_set_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_sizeof
+ *(void **) (&snd_hwdep_dsp_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_malloc
+ *(void **) (&snd_hwdep_dsp_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_free
+ *(void **) (&snd_hwdep_dsp_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_copy
+ *(void **) (&snd_hwdep_dsp_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_get_version
+ *(void **) (&snd_hwdep_dsp_status_get_version_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_version");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_get_id
+ *(void **) (&snd_hwdep_dsp_status_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_get_num_dsps
+ *(void **) (&snd_hwdep_dsp_status_get_num_dsps_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_num_dsps");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_get_dsp_loaded
+ *(void **) (&snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_dsp_loaded");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_status_get_chip_ready
+ *(void **) (&snd_hwdep_dsp_status_get_chip_ready_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_status_get_chip_ready");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_sizeof
+ *(void **) (&snd_hwdep_dsp_image_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_malloc
+ *(void **) (&snd_hwdep_dsp_image_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_free
+ *(void **) (&snd_hwdep_dsp_image_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_copy
+ *(void **) (&snd_hwdep_dsp_image_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_get_index
+ *(void **) (&snd_hwdep_dsp_image_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_get_name
+ *(void **) (&snd_hwdep_dsp_image_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_get_image
+ *(void **) (&snd_hwdep_dsp_image_get_image_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_get_image");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_get_length
+ *(void **) (&snd_hwdep_dsp_image_get_length_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_get_length");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_set_index
+ *(void **) (&snd_hwdep_dsp_image_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_set_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_set_name
+ *(void **) (&snd_hwdep_dsp_image_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_set_image
+ *(void **) (&snd_hwdep_dsp_image_set_image_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_set_image");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hwdep_dsp_image_set_length
+ *(void **) (&snd_hwdep_dsp_image_set_length_dylibloader_wrapper_asound) = dlsym(handle, "snd_hwdep_dsp_image_set_length");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_card_load
+ *(void **) (&snd_card_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_load");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_card_next
+ *(void **) (&snd_card_next_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_next");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_card_get_index
+ *(void **) (&snd_card_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_card_get_name
+ *(void **) (&snd_card_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_card_get_longname
+ *(void **) (&snd_card_get_longname_dylibloader_wrapper_asound) = dlsym(handle, "snd_card_get_longname");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_device_name_hint
+ *(void **) (&snd_device_name_hint_dylibloader_wrapper_asound) = dlsym(handle, "snd_device_name_hint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_device_name_free_hint
+ *(void **) (&snd_device_name_free_hint_dylibloader_wrapper_asound) = dlsym(handle, "snd_device_name_free_hint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_device_name_get_hint
+ *(void **) (&snd_device_name_get_hint_dylibloader_wrapper_asound) = dlsym(handle, "snd_device_name_get_hint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_open
+ *(void **) (&snd_ctl_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_open_lconf
+ *(void **) (&snd_ctl_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_open_lconf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_open_fallback
+ *(void **) (&snd_ctl_open_fallback_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_open_fallback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_close
+ *(void **) (&snd_ctl_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_nonblock
+ *(void **) (&snd_ctl_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_nonblock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_add_ctl_handler
+ *(void **) (&snd_async_add_ctl_handler_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_add_ctl_handler");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_async_handler_get_ctl
+ *(void **) (&snd_async_handler_get_ctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_async_handler_get_ctl");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_poll_descriptors_count
+ *(void **) (&snd_ctl_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_poll_descriptors_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_poll_descriptors
+ *(void **) (&snd_ctl_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_poll_descriptors");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_poll_descriptors_revents
+ *(void **) (&snd_ctl_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_poll_descriptors_revents");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_subscribe_events
+ *(void **) (&snd_ctl_subscribe_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_subscribe_events");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info
+ *(void **) (&snd_ctl_card_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list
+ *(void **) (&snd_ctl_elem_list_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info
+ *(void **) (&snd_ctl_elem_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_read
+ *(void **) (&snd_ctl_elem_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_read");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_write
+ *(void **) (&snd_ctl_elem_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_lock
+ *(void **) (&snd_ctl_elem_lock_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_lock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_unlock
+ *(void **) (&snd_ctl_elem_unlock_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_unlock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_tlv_read
+ *(void **) (&snd_ctl_elem_tlv_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_tlv_read");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_tlv_write
+ *(void **) (&snd_ctl_elem_tlv_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_tlv_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_tlv_command
+ *(void **) (&snd_ctl_elem_tlv_command_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_tlv_command");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_hwdep_next_device
+ *(void **) (&snd_ctl_hwdep_next_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_hwdep_next_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_hwdep_info
+ *(void **) (&snd_ctl_hwdep_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_hwdep_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_pcm_next_device
+ *(void **) (&snd_ctl_pcm_next_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_pcm_next_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_pcm_info
+ *(void **) (&snd_ctl_pcm_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_pcm_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_pcm_prefer_subdevice
+ *(void **) (&snd_ctl_pcm_prefer_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_pcm_prefer_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_rawmidi_next_device
+ *(void **) (&snd_ctl_rawmidi_next_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_rawmidi_next_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_rawmidi_info
+ *(void **) (&snd_ctl_rawmidi_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_rawmidi_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_rawmidi_prefer_subdevice
+ *(void **) (&snd_ctl_rawmidi_prefer_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_rawmidi_prefer_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_set_power_state
+ *(void **) (&snd_ctl_set_power_state_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_set_power_state");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_get_power_state
+ *(void **) (&snd_ctl_get_power_state_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_get_power_state");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_read
+ *(void **) (&snd_ctl_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_read");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_wait
+ *(void **) (&snd_ctl_wait_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_wait");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_name
+ *(void **) (&snd_ctl_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_type
+ *(void **) (&snd_ctl_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_type_name
+ *(void **) (&snd_ctl_elem_type_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_type_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_iface_name
+ *(void **) (&snd_ctl_elem_iface_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_iface_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_type_name
+ *(void **) (&snd_ctl_event_type_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_type_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_elem_get_mask
+ *(void **) (&snd_ctl_event_elem_get_mask_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_elem_get_numid
+ *(void **) (&snd_ctl_event_elem_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_elem_get_id
+ *(void **) (&snd_ctl_event_elem_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_elem_get_interface
+ *(void **) (&snd_ctl_event_elem_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_elem_get_device
+ *(void **) (&snd_ctl_event_elem_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_elem_get_subdevice
+ *(void **) (&snd_ctl_event_elem_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_elem_get_name
+ *(void **) (&snd_ctl_event_elem_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_elem_get_index
+ *(void **) (&snd_ctl_event_elem_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_elem_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_alloc_space
+ *(void **) (&snd_ctl_elem_list_alloc_space_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_alloc_space");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_free_space
+ *(void **) (&snd_ctl_elem_list_free_space_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_free_space");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_ascii_elem_id_get
+ *(void **) (&snd_ctl_ascii_elem_id_get_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_ascii_elem_id_get");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_ascii_elem_id_parse
+ *(void **) (&snd_ctl_ascii_elem_id_parse_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_ascii_elem_id_parse");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_ascii_value_parse
+ *(void **) (&snd_ctl_ascii_value_parse_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_ascii_value_parse");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_sizeof
+ *(void **) (&snd_ctl_elem_id_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_malloc
+ *(void **) (&snd_ctl_elem_id_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_free
+ *(void **) (&snd_ctl_elem_id_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_clear
+ *(void **) (&snd_ctl_elem_id_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_clear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_copy
+ *(void **) (&snd_ctl_elem_id_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_get_numid
+ *(void **) (&snd_ctl_elem_id_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_get_interface
+ *(void **) (&snd_ctl_elem_id_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_get_device
+ *(void **) (&snd_ctl_elem_id_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_get_subdevice
+ *(void **) (&snd_ctl_elem_id_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_get_name
+ *(void **) (&snd_ctl_elem_id_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_get_index
+ *(void **) (&snd_ctl_elem_id_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_set_numid
+ *(void **) (&snd_ctl_elem_id_set_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_set_interface
+ *(void **) (&snd_ctl_elem_id_set_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_set_device
+ *(void **) (&snd_ctl_elem_id_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_set_subdevice
+ *(void **) (&snd_ctl_elem_id_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_set_name
+ *(void **) (&snd_ctl_elem_id_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_id_set_index
+ *(void **) (&snd_ctl_elem_id_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_id_set_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_sizeof
+ *(void **) (&snd_ctl_card_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_malloc
+ *(void **) (&snd_ctl_card_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_free
+ *(void **) (&snd_ctl_card_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_clear
+ *(void **) (&snd_ctl_card_info_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_clear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_copy
+ *(void **) (&snd_ctl_card_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_get_card
+ *(void **) (&snd_ctl_card_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_get_id
+ *(void **) (&snd_ctl_card_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_get_driver
+ *(void **) (&snd_ctl_card_info_get_driver_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_driver");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_get_name
+ *(void **) (&snd_ctl_card_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_get_longname
+ *(void **) (&snd_ctl_card_info_get_longname_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_longname");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_get_mixername
+ *(void **) (&snd_ctl_card_info_get_mixername_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_mixername");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_card_info_get_components
+ *(void **) (&snd_ctl_card_info_get_components_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_card_info_get_components");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_sizeof
+ *(void **) (&snd_ctl_event_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_malloc
+ *(void **) (&snd_ctl_event_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_free
+ *(void **) (&snd_ctl_event_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_clear
+ *(void **) (&snd_ctl_event_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_clear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_copy
+ *(void **) (&snd_ctl_event_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_event_get_type
+ *(void **) (&snd_ctl_event_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_event_get_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_sizeof
+ *(void **) (&snd_ctl_elem_list_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_malloc
+ *(void **) (&snd_ctl_elem_list_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_free
+ *(void **) (&snd_ctl_elem_list_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_clear
+ *(void **) (&snd_ctl_elem_list_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_clear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_copy
+ *(void **) (&snd_ctl_elem_list_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_set_offset
+ *(void **) (&snd_ctl_elem_list_set_offset_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_set_offset");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_used
+ *(void **) (&snd_ctl_elem_list_get_used_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_used");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_count
+ *(void **) (&snd_ctl_elem_list_get_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_id
+ *(void **) (&snd_ctl_elem_list_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_numid
+ *(void **) (&snd_ctl_elem_list_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_interface
+ *(void **) (&snd_ctl_elem_list_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_device
+ *(void **) (&snd_ctl_elem_list_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_subdevice
+ *(void **) (&snd_ctl_elem_list_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_name
+ *(void **) (&snd_ctl_elem_list_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_list_get_index
+ *(void **) (&snd_ctl_elem_list_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_list_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_sizeof
+ *(void **) (&snd_ctl_elem_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_malloc
+ *(void **) (&snd_ctl_elem_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_free
+ *(void **) (&snd_ctl_elem_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_clear
+ *(void **) (&snd_ctl_elem_info_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_clear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_copy
+ *(void **) (&snd_ctl_elem_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_type
+ *(void **) (&snd_ctl_elem_info_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_readable
+ *(void **) (&snd_ctl_elem_info_is_readable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_readable");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_writable
+ *(void **) (&snd_ctl_elem_info_is_writable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_writable");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_volatile
+ *(void **) (&snd_ctl_elem_info_is_volatile_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_volatile");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_inactive
+ *(void **) (&snd_ctl_elem_info_is_inactive_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_inactive");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_locked
+ *(void **) (&snd_ctl_elem_info_is_locked_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_locked");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_tlv_readable
+ *(void **) (&snd_ctl_elem_info_is_tlv_readable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_tlv_readable");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_tlv_writable
+ *(void **) (&snd_ctl_elem_info_is_tlv_writable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_tlv_writable");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_tlv_commandable
+ *(void **) (&snd_ctl_elem_info_is_tlv_commandable_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_tlv_commandable");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_owner
+ *(void **) (&snd_ctl_elem_info_is_owner_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_owner");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_is_user
+ *(void **) (&snd_ctl_elem_info_is_user_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_is_user");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_owner
+ *(void **) (&snd_ctl_elem_info_get_owner_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_owner");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_count
+ *(void **) (&snd_ctl_elem_info_get_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_min
+ *(void **) (&snd_ctl_elem_info_get_min_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_max
+ *(void **) (&snd_ctl_elem_info_get_max_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_step
+ *(void **) (&snd_ctl_elem_info_get_step_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_step");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_min64
+ *(void **) (&snd_ctl_elem_info_get_min64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_min64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_max64
+ *(void **) (&snd_ctl_elem_info_get_max64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_max64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_step64
+ *(void **) (&snd_ctl_elem_info_get_step64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_step64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_items
+ *(void **) (&snd_ctl_elem_info_get_items_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_items");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_item
+ *(void **) (&snd_ctl_elem_info_set_item_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_item");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_item_name
+ *(void **) (&snd_ctl_elem_info_get_item_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_item_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_dimensions
+ *(void **) (&snd_ctl_elem_info_get_dimensions_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_dimensions");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_dimension
+ *(void **) (&snd_ctl_elem_info_get_dimension_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_dimension");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_dimension
+ *(void **) (&snd_ctl_elem_info_set_dimension_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_dimension");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_id
+ *(void **) (&snd_ctl_elem_info_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_numid
+ *(void **) (&snd_ctl_elem_info_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_interface
+ *(void **) (&snd_ctl_elem_info_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_device
+ *(void **) (&snd_ctl_elem_info_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_subdevice
+ *(void **) (&snd_ctl_elem_info_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_name
+ *(void **) (&snd_ctl_elem_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_get_index
+ *(void **) (&snd_ctl_elem_info_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_id
+ *(void **) (&snd_ctl_elem_info_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_numid
+ *(void **) (&snd_ctl_elem_info_set_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_interface
+ *(void **) (&snd_ctl_elem_info_set_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_device
+ *(void **) (&snd_ctl_elem_info_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_subdevice
+ *(void **) (&snd_ctl_elem_info_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_name
+ *(void **) (&snd_ctl_elem_info_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_info_set_index
+ *(void **) (&snd_ctl_elem_info_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_info_set_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_add_integer_elem_set
+ *(void **) (&snd_ctl_add_integer_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_integer_elem_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_add_integer64_elem_set
+ *(void **) (&snd_ctl_add_integer64_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_integer64_elem_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_add_boolean_elem_set
+ *(void **) (&snd_ctl_add_boolean_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_boolean_elem_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_add_enumerated_elem_set
+ *(void **) (&snd_ctl_add_enumerated_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_enumerated_elem_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_add_bytes_elem_set
+ *(void **) (&snd_ctl_add_bytes_elem_set_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_add_bytes_elem_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_add_integer
+ *(void **) (&snd_ctl_elem_add_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_add_integer64
+ *(void **) (&snd_ctl_elem_add_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_integer64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_add_boolean
+ *(void **) (&snd_ctl_elem_add_boolean_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_boolean");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_add_enumerated
+ *(void **) (&snd_ctl_elem_add_enumerated_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_enumerated");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_add_iec958
+ *(void **) (&snd_ctl_elem_add_iec958_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_add_iec958");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_remove
+ *(void **) (&snd_ctl_elem_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_sizeof
+ *(void **) (&snd_ctl_elem_value_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_malloc
+ *(void **) (&snd_ctl_elem_value_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_free
+ *(void **) (&snd_ctl_elem_value_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_clear
+ *(void **) (&snd_ctl_elem_value_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_clear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_copy
+ *(void **) (&snd_ctl_elem_value_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_compare
+ *(void **) (&snd_ctl_elem_value_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_compare");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_id
+ *(void **) (&snd_ctl_elem_value_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_numid
+ *(void **) (&snd_ctl_elem_value_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_interface
+ *(void **) (&snd_ctl_elem_value_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_device
+ *(void **) (&snd_ctl_elem_value_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_subdevice
+ *(void **) (&snd_ctl_elem_value_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_name
+ *(void **) (&snd_ctl_elem_value_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_index
+ *(void **) (&snd_ctl_elem_value_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_id
+ *(void **) (&snd_ctl_elem_value_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_numid
+ *(void **) (&snd_ctl_elem_value_set_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_interface
+ *(void **) (&snd_ctl_elem_value_set_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_device
+ *(void **) (&snd_ctl_elem_value_set_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_subdevice
+ *(void **) (&snd_ctl_elem_value_set_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_name
+ *(void **) (&snd_ctl_elem_value_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_index
+ *(void **) (&snd_ctl_elem_value_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_boolean
+ *(void **) (&snd_ctl_elem_value_get_boolean_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_boolean");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_integer
+ *(void **) (&snd_ctl_elem_value_get_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_integer64
+ *(void **) (&snd_ctl_elem_value_get_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_integer64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_enumerated
+ *(void **) (&snd_ctl_elem_value_get_enumerated_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_enumerated");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_byte
+ *(void **) (&snd_ctl_elem_value_get_byte_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_byte");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_boolean
+ *(void **) (&snd_ctl_elem_value_set_boolean_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_boolean");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_integer
+ *(void **) (&snd_ctl_elem_value_set_integer_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_integer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_integer64
+ *(void **) (&snd_ctl_elem_value_set_integer64_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_integer64");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_enumerated
+ *(void **) (&snd_ctl_elem_value_set_enumerated_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_enumerated");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_byte
+ *(void **) (&snd_ctl_elem_value_set_byte_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_byte");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_set_bytes
+ *(void **) (&snd_ctl_elem_set_bytes_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_set_bytes");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_bytes
+ *(void **) (&snd_ctl_elem_value_get_bytes_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_bytes");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_get_iec958
+ *(void **) (&snd_ctl_elem_value_get_iec958_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_get_iec958");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_elem_value_set_iec958
+ *(void **) (&snd_ctl_elem_value_set_iec958_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_elem_value_set_iec958");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_tlv_parse_dB_info
+ *(void **) (&snd_tlv_parse_dB_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_tlv_parse_dB_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_tlv_get_dB_range
+ *(void **) (&snd_tlv_get_dB_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_tlv_get_dB_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_tlv_convert_to_dB
+ *(void **) (&snd_tlv_convert_to_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_tlv_convert_to_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_tlv_convert_from_dB
+ *(void **) (&snd_tlv_convert_from_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_tlv_convert_from_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_get_dB_range
+ *(void **) (&snd_ctl_get_dB_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_get_dB_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_convert_to_dB
+ *(void **) (&snd_ctl_convert_to_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_convert_to_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_ctl_convert_from_dB
+ *(void **) (&snd_ctl_convert_from_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_ctl_convert_from_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_compare_fast
+ *(void **) (&snd_hctl_compare_fast_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_compare_fast");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_open
+ *(void **) (&snd_hctl_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_open_ctl
+ *(void **) (&snd_hctl_open_ctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_open_ctl");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_close
+ *(void **) (&snd_hctl_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_nonblock
+ *(void **) (&snd_hctl_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_nonblock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_poll_descriptors_count
+ *(void **) (&snd_hctl_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_poll_descriptors_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_poll_descriptors
+ *(void **) (&snd_hctl_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_poll_descriptors");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_poll_descriptors_revents
+ *(void **) (&snd_hctl_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_poll_descriptors_revents");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_get_count
+ *(void **) (&snd_hctl_get_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_get_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_set_compare
+ *(void **) (&snd_hctl_set_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_set_compare");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_first_elem
+ *(void **) (&snd_hctl_first_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_first_elem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_last_elem
+ *(void **) (&snd_hctl_last_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_last_elem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_find_elem
+ *(void **) (&snd_hctl_find_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_find_elem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_set_callback
+ *(void **) (&snd_hctl_set_callback_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_set_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_set_callback_private
+ *(void **) (&snd_hctl_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_set_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_get_callback_private
+ *(void **) (&snd_hctl_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_get_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_load
+ *(void **) (&snd_hctl_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_load");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_free
+ *(void **) (&snd_hctl_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_handle_events
+ *(void **) (&snd_hctl_handle_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_handle_events");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_name
+ *(void **) (&snd_hctl_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_wait
+ *(void **) (&snd_hctl_wait_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_wait");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_ctl
+ *(void **) (&snd_hctl_ctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_ctl");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_next
+ *(void **) (&snd_hctl_elem_next_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_next");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_prev
+ *(void **) (&snd_hctl_elem_prev_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_prev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_info
+ *(void **) (&snd_hctl_elem_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_read
+ *(void **) (&snd_hctl_elem_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_read");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_write
+ *(void **) (&snd_hctl_elem_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_tlv_read
+ *(void **) (&snd_hctl_elem_tlv_read_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_tlv_read");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_tlv_write
+ *(void **) (&snd_hctl_elem_tlv_write_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_tlv_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_tlv_command
+ *(void **) (&snd_hctl_elem_tlv_command_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_tlv_command");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_hctl
+ *(void **) (&snd_hctl_elem_get_hctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_hctl");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_id
+ *(void **) (&snd_hctl_elem_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_numid
+ *(void **) (&snd_hctl_elem_get_numid_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_numid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_interface
+ *(void **) (&snd_hctl_elem_get_interface_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_interface");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_device
+ *(void **) (&snd_hctl_elem_get_device_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_subdevice
+ *(void **) (&snd_hctl_elem_get_subdevice_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_subdevice");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_name
+ *(void **) (&snd_hctl_elem_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_index
+ *(void **) (&snd_hctl_elem_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_set_callback
+ *(void **) (&snd_hctl_elem_set_callback_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_set_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_get_callback_private
+ *(void **) (&snd_hctl_elem_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_get_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_hctl_elem_set_callback_private
+ *(void **) (&snd_hctl_elem_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_hctl_elem_set_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_sctl_build
+ *(void **) (&snd_sctl_build_dylibloader_wrapper_asound) = dlsym(handle, "snd_sctl_build");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_sctl_free
+ *(void **) (&snd_sctl_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_sctl_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_sctl_install
+ *(void **) (&snd_sctl_install_dylibloader_wrapper_asound) = dlsym(handle, "snd_sctl_install");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_sctl_remove
+ *(void **) (&snd_sctl_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_sctl_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_open
+ *(void **) (&snd_mixer_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_close
+ *(void **) (&snd_mixer_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_first_elem
+ *(void **) (&snd_mixer_first_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_first_elem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_last_elem
+ *(void **) (&snd_mixer_last_elem_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_last_elem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_handle_events
+ *(void **) (&snd_mixer_handle_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_handle_events");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_attach
+ *(void **) (&snd_mixer_attach_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_attach");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_attach_hctl
+ *(void **) (&snd_mixer_attach_hctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_attach_hctl");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_detach
+ *(void **) (&snd_mixer_detach_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_detach");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_detach_hctl
+ *(void **) (&snd_mixer_detach_hctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_detach_hctl");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_get_hctl
+ *(void **) (&snd_mixer_get_hctl_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_get_hctl");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_poll_descriptors_count
+ *(void **) (&snd_mixer_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_poll_descriptors_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_poll_descriptors
+ *(void **) (&snd_mixer_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_poll_descriptors");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_poll_descriptors_revents
+ *(void **) (&snd_mixer_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_poll_descriptors_revents");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_load
+ *(void **) (&snd_mixer_load_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_load");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_free
+ *(void **) (&snd_mixer_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_wait
+ *(void **) (&snd_mixer_wait_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_wait");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_set_compare
+ *(void **) (&snd_mixer_set_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_set_compare");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_set_callback
+ *(void **) (&snd_mixer_set_callback_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_set_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_get_callback_private
+ *(void **) (&snd_mixer_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_get_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_set_callback_private
+ *(void **) (&snd_mixer_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_set_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_get_count
+ *(void **) (&snd_mixer_get_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_get_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_unregister
+ *(void **) (&snd_mixer_class_unregister_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_unregister");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_next
+ *(void **) (&snd_mixer_elem_next_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_next");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_prev
+ *(void **) (&snd_mixer_elem_prev_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_prev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_set_callback
+ *(void **) (&snd_mixer_elem_set_callback_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_set_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_get_callback_private
+ *(void **) (&snd_mixer_elem_get_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_get_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_set_callback_private
+ *(void **) (&snd_mixer_elem_set_callback_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_set_callback_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_get_type
+ *(void **) (&snd_mixer_elem_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_get_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_register
+ *(void **) (&snd_mixer_class_register_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_register");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_new
+ *(void **) (&snd_mixer_elem_new_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_add
+ *(void **) (&snd_mixer_elem_add_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_add");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_remove
+ *(void **) (&snd_mixer_elem_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_free
+ *(void **) (&snd_mixer_elem_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_info
+ *(void **) (&snd_mixer_elem_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_value
+ *(void **) (&snd_mixer_elem_value_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_attach
+ *(void **) (&snd_mixer_elem_attach_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_attach");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_detach
+ *(void **) (&snd_mixer_elem_detach_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_detach");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_empty
+ *(void **) (&snd_mixer_elem_empty_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_empty");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_elem_get_private
+ *(void **) (&snd_mixer_elem_get_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_elem_get_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_sizeof
+ *(void **) (&snd_mixer_class_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_malloc
+ *(void **) (&snd_mixer_class_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_free
+ *(void **) (&snd_mixer_class_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_copy
+ *(void **) (&snd_mixer_class_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_get_mixer
+ *(void **) (&snd_mixer_class_get_mixer_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_get_mixer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_get_event
+ *(void **) (&snd_mixer_class_get_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_get_event");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_get_private
+ *(void **) (&snd_mixer_class_get_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_get_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_get_compare
+ *(void **) (&snd_mixer_class_get_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_get_compare");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_set_event
+ *(void **) (&snd_mixer_class_set_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_set_event");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_set_private
+ *(void **) (&snd_mixer_class_set_private_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_set_private");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_set_private_free
+ *(void **) (&snd_mixer_class_set_private_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_set_private_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_class_set_compare
+ *(void **) (&snd_mixer_class_set_compare_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_class_set_compare");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_channel_name
+ *(void **) (&snd_mixer_selem_channel_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_channel_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_register
+ *(void **) (&snd_mixer_selem_register_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_register");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_id
+ *(void **) (&snd_mixer_selem_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_name
+ *(void **) (&snd_mixer_selem_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_index
+ *(void **) (&snd_mixer_selem_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_find_selem
+ *(void **) (&snd_mixer_find_selem_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_find_selem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_is_active
+ *(void **) (&snd_mixer_selem_is_active_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_active");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_is_playback_mono
+ *(void **) (&snd_mixer_selem_is_playback_mono_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_playback_mono");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_playback_channel
+ *(void **) (&snd_mixer_selem_has_playback_channel_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_channel");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_is_capture_mono
+ *(void **) (&snd_mixer_selem_is_capture_mono_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_capture_mono");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_capture_channel
+ *(void **) (&snd_mixer_selem_has_capture_channel_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_channel");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_capture_group
+ *(void **) (&snd_mixer_selem_get_capture_group_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_group");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_common_volume
+ *(void **) (&snd_mixer_selem_has_common_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_common_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_playback_volume
+ *(void **) (&snd_mixer_selem_has_playback_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_playback_volume_joined
+ *(void **) (&snd_mixer_selem_has_playback_volume_joined_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_volume_joined");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_capture_volume
+ *(void **) (&snd_mixer_selem_has_capture_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_capture_volume_joined
+ *(void **) (&snd_mixer_selem_has_capture_volume_joined_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_volume_joined");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_common_switch
+ *(void **) (&snd_mixer_selem_has_common_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_common_switch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_playback_switch
+ *(void **) (&snd_mixer_selem_has_playback_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_switch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_playback_switch_joined
+ *(void **) (&snd_mixer_selem_has_playback_switch_joined_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_playback_switch_joined");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_capture_switch
+ *(void **) (&snd_mixer_selem_has_capture_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_switch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_capture_switch_joined
+ *(void **) (&snd_mixer_selem_has_capture_switch_joined_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_switch_joined");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_has_capture_switch_exclusive
+ *(void **) (&snd_mixer_selem_has_capture_switch_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_has_capture_switch_exclusive");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_ask_playback_vol_dB
+ *(void **) (&snd_mixer_selem_ask_playback_vol_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_ask_playback_vol_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_ask_capture_vol_dB
+ *(void **) (&snd_mixer_selem_ask_capture_vol_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_ask_capture_vol_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_ask_playback_dB_vol
+ *(void **) (&snd_mixer_selem_ask_playback_dB_vol_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_ask_playback_dB_vol");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_ask_capture_dB_vol
+ *(void **) (&snd_mixer_selem_ask_capture_dB_vol_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_ask_capture_dB_vol");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_playback_volume
+ *(void **) (&snd_mixer_selem_get_playback_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_capture_volume
+ *(void **) (&snd_mixer_selem_get_capture_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_playback_dB
+ *(void **) (&snd_mixer_selem_get_playback_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_capture_dB
+ *(void **) (&snd_mixer_selem_get_capture_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_playback_switch
+ *(void **) (&snd_mixer_selem_get_playback_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_switch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_capture_switch
+ *(void **) (&snd_mixer_selem_get_capture_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_switch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_playback_volume
+ *(void **) (&snd_mixer_selem_set_playback_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_capture_volume
+ *(void **) (&snd_mixer_selem_set_capture_volume_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_playback_dB
+ *(void **) (&snd_mixer_selem_set_playback_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_capture_dB
+ *(void **) (&snd_mixer_selem_set_capture_dB_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_playback_volume_all
+ *(void **) (&snd_mixer_selem_set_playback_volume_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_volume_all");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_capture_volume_all
+ *(void **) (&snd_mixer_selem_set_capture_volume_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_volume_all");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_playback_dB_all
+ *(void **) (&snd_mixer_selem_set_playback_dB_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_dB_all");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_capture_dB_all
+ *(void **) (&snd_mixer_selem_set_capture_dB_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_dB_all");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_playback_switch
+ *(void **) (&snd_mixer_selem_set_playback_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_switch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_capture_switch
+ *(void **) (&snd_mixer_selem_set_capture_switch_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_switch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_playback_switch_all
+ *(void **) (&snd_mixer_selem_set_playback_switch_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_switch_all");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_capture_switch_all
+ *(void **) (&snd_mixer_selem_set_capture_switch_all_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_switch_all");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_playback_volume_range
+ *(void **) (&snd_mixer_selem_get_playback_volume_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_volume_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_playback_dB_range
+ *(void **) (&snd_mixer_selem_get_playback_dB_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_playback_dB_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_playback_volume_range
+ *(void **) (&snd_mixer_selem_set_playback_volume_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_playback_volume_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_capture_volume_range
+ *(void **) (&snd_mixer_selem_get_capture_volume_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_volume_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_capture_dB_range
+ *(void **) (&snd_mixer_selem_get_capture_dB_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_capture_dB_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_capture_volume_range
+ *(void **) (&snd_mixer_selem_set_capture_volume_range_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_capture_volume_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_is_enumerated
+ *(void **) (&snd_mixer_selem_is_enumerated_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_enumerated");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_is_enum_playback
+ *(void **) (&snd_mixer_selem_is_enum_playback_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_enum_playback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_is_enum_capture
+ *(void **) (&snd_mixer_selem_is_enum_capture_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_is_enum_capture");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_enum_items
+ *(void **) (&snd_mixer_selem_get_enum_items_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_enum_items");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_enum_item_name
+ *(void **) (&snd_mixer_selem_get_enum_item_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_enum_item_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_get_enum_item
+ *(void **) (&snd_mixer_selem_get_enum_item_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_get_enum_item");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_set_enum_item
+ *(void **) (&snd_mixer_selem_set_enum_item_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_set_enum_item");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_sizeof
+ *(void **) (&snd_mixer_selem_id_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_malloc
+ *(void **) (&snd_mixer_selem_id_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_free
+ *(void **) (&snd_mixer_selem_id_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_copy
+ *(void **) (&snd_mixer_selem_id_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_get_name
+ *(void **) (&snd_mixer_selem_id_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_get_index
+ *(void **) (&snd_mixer_selem_id_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_set_name
+ *(void **) (&snd_mixer_selem_id_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_set_index
+ *(void **) (&snd_mixer_selem_id_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_set_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_mixer_selem_id_parse
+ *(void **) (&snd_mixer_selem_id_parse_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_parse");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_open
+ *(void **) (&snd_seq_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_open");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_open_lconf
+ *(void **) (&snd_seq_open_lconf_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_open_lconf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_name
+ *(void **) (&snd_seq_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_type
+ *(void **) (&snd_seq_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_close
+ *(void **) (&snd_seq_close_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_close");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_poll_descriptors_count
+ *(void **) (&snd_seq_poll_descriptors_count_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_poll_descriptors_count");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_poll_descriptors
+ *(void **) (&snd_seq_poll_descriptors_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_poll_descriptors");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_poll_descriptors_revents
+ *(void **) (&snd_seq_poll_descriptors_revents_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_poll_descriptors_revents");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_nonblock
+ *(void **) (&snd_seq_nonblock_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_nonblock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_id
+ *(void **) (&snd_seq_client_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_output_buffer_size
+ *(void **) (&snd_seq_get_output_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_output_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_input_buffer_size
+ *(void **) (&snd_seq_get_input_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_input_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_output_buffer_size
+ *(void **) (&snd_seq_set_output_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_output_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_input_buffer_size
+ *(void **) (&snd_seq_set_input_buffer_size_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_input_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_sizeof
+ *(void **) (&snd_seq_system_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_malloc
+ *(void **) (&snd_seq_system_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_free
+ *(void **) (&snd_seq_system_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_copy
+ *(void **) (&snd_seq_system_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_get_queues
+ *(void **) (&snd_seq_system_info_get_queues_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_queues");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_get_clients
+ *(void **) (&snd_seq_system_info_get_clients_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_clients");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_get_ports
+ *(void **) (&snd_seq_system_info_get_ports_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_ports");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_get_channels
+ *(void **) (&snd_seq_system_info_get_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_get_cur_clients
+ *(void **) (&snd_seq_system_info_get_cur_clients_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_cur_clients");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info_get_cur_queues
+ *(void **) (&snd_seq_system_info_get_cur_queues_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info_get_cur_queues");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_system_info
+ *(void **) (&snd_seq_system_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_system_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_sizeof
+ *(void **) (&snd_seq_client_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_malloc
+ *(void **) (&snd_seq_client_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_free
+ *(void **) (&snd_seq_client_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_copy
+ *(void **) (&snd_seq_client_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_client
+ *(void **) (&snd_seq_client_info_get_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_type
+ *(void **) (&snd_seq_client_info_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_name
+ *(void **) (&snd_seq_client_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_broadcast_filter
+ *(void **) (&snd_seq_client_info_get_broadcast_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_broadcast_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_error_bounce
+ *(void **) (&snd_seq_client_info_get_error_bounce_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_error_bounce");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_card
+ *(void **) (&snd_seq_client_info_get_card_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_card");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_pid
+ *(void **) (&snd_seq_client_info_get_pid_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_pid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_event_filter
+ *(void **) (&snd_seq_client_info_get_event_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_event_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_num_ports
+ *(void **) (&snd_seq_client_info_get_num_ports_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_num_ports");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_get_event_lost
+ *(void **) (&snd_seq_client_info_get_event_lost_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_get_event_lost");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_set_client
+ *(void **) (&snd_seq_client_info_set_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_set_name
+ *(void **) (&snd_seq_client_info_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_set_broadcast_filter
+ *(void **) (&snd_seq_client_info_set_broadcast_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_broadcast_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_set_error_bounce
+ *(void **) (&snd_seq_client_info_set_error_bounce_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_error_bounce");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_set_event_filter
+ *(void **) (&snd_seq_client_info_set_event_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_set_event_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_event_filter_clear
+ *(void **) (&snd_seq_client_info_event_filter_clear_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_event_filter_clear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_event_filter_add
+ *(void **) (&snd_seq_client_info_event_filter_add_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_event_filter_add");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_event_filter_del
+ *(void **) (&snd_seq_client_info_event_filter_del_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_event_filter_del");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_info_event_filter_check
+ *(void **) (&snd_seq_client_info_event_filter_check_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_info_event_filter_check");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_client_info
+ *(void **) (&snd_seq_get_client_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_client_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_any_client_info
+ *(void **) (&snd_seq_get_any_client_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_any_client_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_client_info
+ *(void **) (&snd_seq_set_client_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_next_client
+ *(void **) (&snd_seq_query_next_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_next_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_sizeof
+ *(void **) (&snd_seq_client_pool_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_malloc
+ *(void **) (&snd_seq_client_pool_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_free
+ *(void **) (&snd_seq_client_pool_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_copy
+ *(void **) (&snd_seq_client_pool_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_get_client
+ *(void **) (&snd_seq_client_pool_get_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_get_output_pool
+ *(void **) (&snd_seq_client_pool_get_output_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_output_pool");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_get_input_pool
+ *(void **) (&snd_seq_client_pool_get_input_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_input_pool");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_get_output_room
+ *(void **) (&snd_seq_client_pool_get_output_room_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_output_room");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_get_output_free
+ *(void **) (&snd_seq_client_pool_get_output_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_output_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_get_input_free
+ *(void **) (&snd_seq_client_pool_get_input_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_get_input_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_set_output_pool
+ *(void **) (&snd_seq_client_pool_set_output_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_set_output_pool");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_set_input_pool
+ *(void **) (&snd_seq_client_pool_set_input_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_set_input_pool");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_client_pool_set_output_room
+ *(void **) (&snd_seq_client_pool_set_output_room_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_client_pool_set_output_room");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_client_pool
+ *(void **) (&snd_seq_get_client_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_client_pool");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_client_pool
+ *(void **) (&snd_seq_set_client_pool_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_pool");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_sizeof
+ *(void **) (&snd_seq_port_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_malloc
+ *(void **) (&snd_seq_port_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_free
+ *(void **) (&snd_seq_port_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_copy
+ *(void **) (&snd_seq_port_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_client
+ *(void **) (&snd_seq_port_info_get_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_port
+ *(void **) (&snd_seq_port_info_get_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_addr
+ *(void **) (&snd_seq_port_info_get_addr_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_addr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_name
+ *(void **) (&snd_seq_port_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_capability
+ *(void **) (&snd_seq_port_info_get_capability_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_capability");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_type
+ *(void **) (&snd_seq_port_info_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_midi_channels
+ *(void **) (&snd_seq_port_info_get_midi_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_midi_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_midi_voices
+ *(void **) (&snd_seq_port_info_get_midi_voices_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_midi_voices");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_synth_voices
+ *(void **) (&snd_seq_port_info_get_synth_voices_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_synth_voices");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_read_use
+ *(void **) (&snd_seq_port_info_get_read_use_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_read_use");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_write_use
+ *(void **) (&snd_seq_port_info_get_write_use_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_write_use");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_port_specified
+ *(void **) (&snd_seq_port_info_get_port_specified_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_port_specified");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_timestamping
+ *(void **) (&snd_seq_port_info_get_timestamping_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_timestamping");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_timestamp_real
+ *(void **) (&snd_seq_port_info_get_timestamp_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_timestamp_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_get_timestamp_queue
+ *(void **) (&snd_seq_port_info_get_timestamp_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_get_timestamp_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_client
+ *(void **) (&snd_seq_port_info_set_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_port
+ *(void **) (&snd_seq_port_info_set_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_addr
+ *(void **) (&snd_seq_port_info_set_addr_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_addr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_name
+ *(void **) (&snd_seq_port_info_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_capability
+ *(void **) (&snd_seq_port_info_set_capability_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_capability");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_type
+ *(void **) (&snd_seq_port_info_set_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_midi_channels
+ *(void **) (&snd_seq_port_info_set_midi_channels_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_midi_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_midi_voices
+ *(void **) (&snd_seq_port_info_set_midi_voices_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_midi_voices");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_synth_voices
+ *(void **) (&snd_seq_port_info_set_synth_voices_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_synth_voices");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_port_specified
+ *(void **) (&snd_seq_port_info_set_port_specified_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_port_specified");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_timestamping
+ *(void **) (&snd_seq_port_info_set_timestamping_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_timestamping");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_timestamp_real
+ *(void **) (&snd_seq_port_info_set_timestamp_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_timestamp_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_info_set_timestamp_queue
+ *(void **) (&snd_seq_port_info_set_timestamp_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_info_set_timestamp_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_create_port
+ *(void **) (&snd_seq_create_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_create_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_delete_port
+ *(void **) (&snd_seq_delete_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_delete_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_port_info
+ *(void **) (&snd_seq_get_port_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_port_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_any_port_info
+ *(void **) (&snd_seq_get_any_port_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_any_port_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_port_info
+ *(void **) (&snd_seq_set_port_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_port_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_next_port
+ *(void **) (&snd_seq_query_next_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_next_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_sizeof
+ *(void **) (&snd_seq_port_subscribe_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_malloc
+ *(void **) (&snd_seq_port_subscribe_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_free
+ *(void **) (&snd_seq_port_subscribe_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_copy
+ *(void **) (&snd_seq_port_subscribe_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_get_sender
+ *(void **) (&snd_seq_port_subscribe_get_sender_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_sender");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_get_dest
+ *(void **) (&snd_seq_port_subscribe_get_dest_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_dest");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_get_queue
+ *(void **) (&snd_seq_port_subscribe_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_get_exclusive
+ *(void **) (&snd_seq_port_subscribe_get_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_exclusive");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_get_time_update
+ *(void **) (&snd_seq_port_subscribe_get_time_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_time_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_get_time_real
+ *(void **) (&snd_seq_port_subscribe_get_time_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_get_time_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_set_sender
+ *(void **) (&snd_seq_port_subscribe_set_sender_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_sender");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_set_dest
+ *(void **) (&snd_seq_port_subscribe_set_dest_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_dest");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_set_queue
+ *(void **) (&snd_seq_port_subscribe_set_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_set_exclusive
+ *(void **) (&snd_seq_port_subscribe_set_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_exclusive");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_set_time_update
+ *(void **) (&snd_seq_port_subscribe_set_time_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_time_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_port_subscribe_set_time_real
+ *(void **) (&snd_seq_port_subscribe_set_time_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_port_subscribe_set_time_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_port_subscription
+ *(void **) (&snd_seq_get_port_subscription_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_port_subscription");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_subscribe_port
+ *(void **) (&snd_seq_subscribe_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_subscribe_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_unsubscribe_port
+ *(void **) (&snd_seq_unsubscribe_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_unsubscribe_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_sizeof
+ *(void **) (&snd_seq_query_subscribe_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_malloc
+ *(void **) (&snd_seq_query_subscribe_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_free
+ *(void **) (&snd_seq_query_subscribe_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_copy
+ *(void **) (&snd_seq_query_subscribe_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_client
+ *(void **) (&snd_seq_query_subscribe_get_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_port
+ *(void **) (&snd_seq_query_subscribe_get_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_root
+ *(void **) (&snd_seq_query_subscribe_get_root_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_root");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_type
+ *(void **) (&snd_seq_query_subscribe_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_index
+ *(void **) (&snd_seq_query_subscribe_get_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_num_subs
+ *(void **) (&snd_seq_query_subscribe_get_num_subs_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_num_subs");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_addr
+ *(void **) (&snd_seq_query_subscribe_get_addr_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_addr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_queue
+ *(void **) (&snd_seq_query_subscribe_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_exclusive
+ *(void **) (&snd_seq_query_subscribe_get_exclusive_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_exclusive");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_time_update
+ *(void **) (&snd_seq_query_subscribe_get_time_update_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_time_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_get_time_real
+ *(void **) (&snd_seq_query_subscribe_get_time_real_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_get_time_real");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_set_client
+ *(void **) (&snd_seq_query_subscribe_set_client_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_set_port
+ *(void **) (&snd_seq_query_subscribe_set_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_set_root
+ *(void **) (&snd_seq_query_subscribe_set_root_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_root");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_set_type
+ *(void **) (&snd_seq_query_subscribe_set_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_subscribe_set_index
+ *(void **) (&snd_seq_query_subscribe_set_index_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_subscribe_set_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_port_subscribers
+ *(void **) (&snd_seq_query_port_subscribers_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_port_subscribers");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_sizeof
+ *(void **) (&snd_seq_queue_info_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_malloc
+ *(void **) (&snd_seq_queue_info_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_free
+ *(void **) (&snd_seq_queue_info_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_copy
+ *(void **) (&snd_seq_queue_info_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_get_queue
+ *(void **) (&snd_seq_queue_info_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_get_name
+ *(void **) (&snd_seq_queue_info_get_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_get_owner
+ *(void **) (&snd_seq_queue_info_get_owner_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_owner");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_get_locked
+ *(void **) (&snd_seq_queue_info_get_locked_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_locked");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_get_flags
+ *(void **) (&snd_seq_queue_info_get_flags_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_get_flags");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_set_name
+ *(void **) (&snd_seq_queue_info_set_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_set_owner
+ *(void **) (&snd_seq_queue_info_set_owner_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_set_owner");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_set_locked
+ *(void **) (&snd_seq_queue_info_set_locked_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_set_locked");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_info_set_flags
+ *(void **) (&snd_seq_queue_info_set_flags_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_info_set_flags");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_create_queue
+ *(void **) (&snd_seq_create_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_create_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_alloc_named_queue
+ *(void **) (&snd_seq_alloc_named_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_alloc_named_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_alloc_queue
+ *(void **) (&snd_seq_alloc_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_alloc_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_free_queue
+ *(void **) (&snd_seq_free_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_free_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_queue_info
+ *(void **) (&snd_seq_get_queue_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_queue_info
+ *(void **) (&snd_seq_set_queue_info_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_queue_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_query_named_queue
+ *(void **) (&snd_seq_query_named_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_query_named_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_queue_usage
+ *(void **) (&snd_seq_get_queue_usage_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_usage");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_queue_usage
+ *(void **) (&snd_seq_set_queue_usage_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_queue_usage");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_sizeof
+ *(void **) (&snd_seq_queue_status_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_malloc
+ *(void **) (&snd_seq_queue_status_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_free
+ *(void **) (&snd_seq_queue_status_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_copy
+ *(void **) (&snd_seq_queue_status_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_get_queue
+ *(void **) (&snd_seq_queue_status_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_get_events
+ *(void **) (&snd_seq_queue_status_get_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_events");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_get_tick_time
+ *(void **) (&snd_seq_queue_status_get_tick_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_tick_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_get_real_time
+ *(void **) (&snd_seq_queue_status_get_real_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_real_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_status_get_status
+ *(void **) (&snd_seq_queue_status_get_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_status_get_status");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_queue_status
+ *(void **) (&snd_seq_get_queue_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_status");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_sizeof
+ *(void **) (&snd_seq_queue_tempo_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_malloc
+ *(void **) (&snd_seq_queue_tempo_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_free
+ *(void **) (&snd_seq_queue_tempo_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_copy
+ *(void **) (&snd_seq_queue_tempo_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_get_queue
+ *(void **) (&snd_seq_queue_tempo_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_get_tempo
+ *(void **) (&snd_seq_queue_tempo_get_tempo_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_tempo");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_get_ppq
+ *(void **) (&snd_seq_queue_tempo_get_ppq_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_ppq");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_get_skew
+ *(void **) (&snd_seq_queue_tempo_get_skew_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_skew");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_get_skew_base
+ *(void **) (&snd_seq_queue_tempo_get_skew_base_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_get_skew_base");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_set_tempo
+ *(void **) (&snd_seq_queue_tempo_set_tempo_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_set_tempo");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_set_ppq
+ *(void **) (&snd_seq_queue_tempo_set_ppq_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_set_ppq");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_set_skew
+ *(void **) (&snd_seq_queue_tempo_set_skew_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_set_skew");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_tempo_set_skew_base
+ *(void **) (&snd_seq_queue_tempo_set_skew_base_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_tempo_set_skew_base");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_queue_tempo
+ *(void **) (&snd_seq_get_queue_tempo_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_tempo");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_queue_tempo
+ *(void **) (&snd_seq_set_queue_tempo_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_queue_tempo");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_sizeof
+ *(void **) (&snd_seq_queue_timer_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_malloc
+ *(void **) (&snd_seq_queue_timer_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_free
+ *(void **) (&snd_seq_queue_timer_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_copy
+ *(void **) (&snd_seq_queue_timer_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_get_queue
+ *(void **) (&snd_seq_queue_timer_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_get_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_get_type
+ *(void **) (&snd_seq_queue_timer_get_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_get_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_get_id
+ *(void **) (&snd_seq_queue_timer_get_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_get_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_get_resolution
+ *(void **) (&snd_seq_queue_timer_get_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_get_resolution");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_set_type
+ *(void **) (&snd_seq_queue_timer_set_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_set_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_set_id
+ *(void **) (&snd_seq_queue_timer_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_set_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_queue_timer_set_resolution
+ *(void **) (&snd_seq_queue_timer_set_resolution_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_queue_timer_set_resolution");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_queue_timer
+ *(void **) (&snd_seq_get_queue_timer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_queue_timer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_queue_timer
+ *(void **) (&snd_seq_set_queue_timer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_queue_timer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_free_event
+ *(void **) (&snd_seq_free_event_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_free_event");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_event_length
+ *(void **) (&snd_seq_event_length_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_length");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_event_output
+ *(void **) (&snd_seq_event_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_output");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_event_output_buffer
+ *(void **) (&snd_seq_event_output_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_output_buffer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_event_output_direct
+ *(void **) (&snd_seq_event_output_direct_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_output_direct");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_event_input
+ *(void **) (&snd_seq_event_input_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_input");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_event_input_pending
+ *(void **) (&snd_seq_event_input_pending_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_input_pending");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_drain_output
+ *(void **) (&snd_seq_drain_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drain_output");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_event_output_pending
+ *(void **) (&snd_seq_event_output_pending_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_event_output_pending");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_extract_output
+ *(void **) (&snd_seq_extract_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_extract_output");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_drop_output
+ *(void **) (&snd_seq_drop_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drop_output");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_drop_output_buffer
+ *(void **) (&snd_seq_drop_output_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drop_output_buffer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_drop_input
+ *(void **) (&snd_seq_drop_input_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drop_input");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_drop_input_buffer
+ *(void **) (&snd_seq_drop_input_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_drop_input_buffer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_sizeof
+ *(void **) (&snd_seq_remove_events_sizeof_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_sizeof");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_malloc
+ *(void **) (&snd_seq_remove_events_malloc_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_malloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_free
+ *(void **) (&snd_seq_remove_events_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_copy
+ *(void **) (&snd_seq_remove_events_copy_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_get_condition
+ *(void **) (&snd_seq_remove_events_get_condition_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_condition");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_get_queue
+ *(void **) (&snd_seq_remove_events_get_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_get_time
+ *(void **) (&snd_seq_remove_events_get_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_get_dest
+ *(void **) (&snd_seq_remove_events_get_dest_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_dest");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_get_channel
+ *(void **) (&snd_seq_remove_events_get_channel_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_channel");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_get_event_type
+ *(void **) (&snd_seq_remove_events_get_event_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_event_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_get_tag
+ *(void **) (&snd_seq_remove_events_get_tag_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_get_tag");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_set_condition
+ *(void **) (&snd_seq_remove_events_set_condition_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_condition");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_set_queue
+ *(void **) (&snd_seq_remove_events_set_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_set_time
+ *(void **) (&snd_seq_remove_events_set_time_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_set_dest
+ *(void **) (&snd_seq_remove_events_set_dest_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_dest");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_set_channel
+ *(void **) (&snd_seq_remove_events_set_channel_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_channel");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_set_event_type
+ *(void **) (&snd_seq_remove_events_set_event_type_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_event_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events_set_tag
+ *(void **) (&snd_seq_remove_events_set_tag_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events_set_tag");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_remove_events
+ *(void **) (&snd_seq_remove_events_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_remove_events");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_bit
+ *(void **) (&snd_seq_set_bit_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_bit");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_unset_bit
+ *(void **) (&snd_seq_unset_bit_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_unset_bit");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_change_bit
+ *(void **) (&snd_seq_change_bit_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_change_bit");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_get_bit
+ *(void **) (&snd_seq_get_bit_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_get_bit");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_control_queue
+ *(void **) (&snd_seq_control_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_control_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_create_simple_port
+ *(void **) (&snd_seq_create_simple_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_create_simple_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_delete_simple_port
+ *(void **) (&snd_seq_delete_simple_port_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_delete_simple_port");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_connect_from
+ *(void **) (&snd_seq_connect_from_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_connect_from");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_connect_to
+ *(void **) (&snd_seq_connect_to_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_connect_to");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_disconnect_from
+ *(void **) (&snd_seq_disconnect_from_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_disconnect_from");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_disconnect_to
+ *(void **) (&snd_seq_disconnect_to_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_disconnect_to");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_client_name
+ *(void **) (&snd_seq_set_client_name_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_client_event_filter
+ *(void **) (&snd_seq_set_client_event_filter_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_event_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_client_pool_output
+ *(void **) (&snd_seq_set_client_pool_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_pool_output");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_client_pool_output_room
+ *(void **) (&snd_seq_set_client_pool_output_room_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_pool_output_room");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_set_client_pool_input
+ *(void **) (&snd_seq_set_client_pool_input_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_set_client_pool_input");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_sync_output_queue
+ *(void **) (&snd_seq_sync_output_queue_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_sync_output_queue");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_parse_address
+ *(void **) (&snd_seq_parse_address_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_parse_address");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_reset_pool_output
+ *(void **) (&snd_seq_reset_pool_output_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_reset_pool_output");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_seq_reset_pool_input
+ *(void **) (&snd_seq_reset_pool_input_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_reset_pool_input");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_new
+ *(void **) (&snd_midi_event_new_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_resize_buffer
+ *(void **) (&snd_midi_event_resize_buffer_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_resize_buffer");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_free
+ *(void **) (&snd_midi_event_free_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_init
+ *(void **) (&snd_midi_event_init_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_init");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_reset_encode
+ *(void **) (&snd_midi_event_reset_encode_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_reset_encode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_reset_decode
+ *(void **) (&snd_midi_event_reset_decode_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_reset_decode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_no_status
+ *(void **) (&snd_midi_event_no_status_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_no_status");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_encode
+ *(void **) (&snd_midi_event_encode_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_encode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_encode_byte
+ *(void **) (&snd_midi_event_encode_byte_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_encode_byte");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// snd_midi_event_decode
+ *(void **) (&snd_midi_event_decode_dylibloader_wrapper_asound) = dlsym(handle, "snd_midi_event_decode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+return 0;
+}
diff --git a/drivers/alsa/asound-so_wrap.h b/drivers/alsa/asound-so_wrap.h
new file mode 100644
index 0000000000..5332d74152
--- /dev/null
+++ b/drivers/alsa/asound-so_wrap.h
@@ -0,0 +1,5134 @@
+#ifndef DYLIBLOAD_WRAPPER_ASOUND
+#define DYLIBLOAD_WRAPPER_ASOUND
+// This file is generated. Do not edit!
+// see https://github.com/hpvb/dynload-wrapper for details
+// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-22 19:22:12
+// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/alsa/asoundlib.h --sys-include <alsa/asoundlib.h> --soname libasound.so.2 --init-name asound --omit-prefix snd_pcm_sw_params_set_tstamp_type --omit-prefix snd_pcm_status_get_audio_htstamp_report --omit-prefix snd_pcm_sw_params_get_tstamp_type --omit-prefix snd_pcm_status_set_audio_htstamp_config --output-header asound-so_wrap.h --output-implementation asound-so_wrap.c
+//
+#include <stdint.h>
+
+#define snd_asoundlib_version snd_asoundlib_version_dylibloader_orig_asound
+#define snd_dlpath snd_dlpath_dylibloader_orig_asound
+#define snd_dlopen snd_dlopen_dylibloader_orig_asound
+#define snd_dlsym snd_dlsym_dylibloader_orig_asound
+#define snd_dlclose snd_dlclose_dylibloader_orig_asound
+#define snd_async_add_handler snd_async_add_handler_dylibloader_orig_asound
+#define snd_async_del_handler snd_async_del_handler_dylibloader_orig_asound
+#define snd_async_handler_get_fd snd_async_handler_get_fd_dylibloader_orig_asound
+#define snd_async_handler_get_signo snd_async_handler_get_signo_dylibloader_orig_asound
+#define snd_async_handler_get_callback_private snd_async_handler_get_callback_private_dylibloader_orig_asound
+#define snd_shm_area_create snd_shm_area_create_dylibloader_orig_asound
+#define snd_shm_area_share snd_shm_area_share_dylibloader_orig_asound
+#define snd_shm_area_destroy snd_shm_area_destroy_dylibloader_orig_asound
+#define snd_user_file snd_user_file_dylibloader_orig_asound
+#define snd_input_stdio_open snd_input_stdio_open_dylibloader_orig_asound
+#define snd_input_stdio_attach snd_input_stdio_attach_dylibloader_orig_asound
+#define snd_input_buffer_open snd_input_buffer_open_dylibloader_orig_asound
+#define snd_input_close snd_input_close_dylibloader_orig_asound
+#define snd_input_scanf snd_input_scanf_dylibloader_orig_asound
+#define snd_input_gets snd_input_gets_dylibloader_orig_asound
+#define snd_input_getc snd_input_getc_dylibloader_orig_asound
+#define snd_input_ungetc snd_input_ungetc_dylibloader_orig_asound
+#define snd_output_stdio_open snd_output_stdio_open_dylibloader_orig_asound
+#define snd_output_stdio_attach snd_output_stdio_attach_dylibloader_orig_asound
+#define snd_output_buffer_open snd_output_buffer_open_dylibloader_orig_asound
+#define snd_output_buffer_string snd_output_buffer_string_dylibloader_orig_asound
+#define snd_output_close snd_output_close_dylibloader_orig_asound
+#define snd_output_printf snd_output_printf_dylibloader_orig_asound
+#define snd_output_vprintf snd_output_vprintf_dylibloader_orig_asound
+#define snd_output_puts snd_output_puts_dylibloader_orig_asound
+#define snd_output_putc snd_output_putc_dylibloader_orig_asound
+#define snd_output_flush snd_output_flush_dylibloader_orig_asound
+#define snd_strerror snd_strerror_dylibloader_orig_asound
+#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_orig_asound
+#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_orig_asound
+#define snd_config_topdir snd_config_topdir_dylibloader_orig_asound
+#define snd_config_top snd_config_top_dylibloader_orig_asound
+#define snd_config_load snd_config_load_dylibloader_orig_asound
+#define snd_config_load_override snd_config_load_override_dylibloader_orig_asound
+#define snd_config_save snd_config_save_dylibloader_orig_asound
+#define snd_config_update snd_config_update_dylibloader_orig_asound
+#define snd_config_update_r snd_config_update_r_dylibloader_orig_asound
+#define snd_config_update_free snd_config_update_free_dylibloader_orig_asound
+#define snd_config_update_free_global snd_config_update_free_global_dylibloader_orig_asound
+#define snd_config_update_ref snd_config_update_ref_dylibloader_orig_asound
+#define snd_config_ref snd_config_ref_dylibloader_orig_asound
+#define snd_config_unref snd_config_unref_dylibloader_orig_asound
+#define snd_config_search snd_config_search_dylibloader_orig_asound
+#define snd_config_searchv snd_config_searchv_dylibloader_orig_asound
+#define snd_config_search_definition snd_config_search_definition_dylibloader_orig_asound
+#define snd_config_expand snd_config_expand_dylibloader_orig_asound
+#define snd_config_evaluate snd_config_evaluate_dylibloader_orig_asound
+#define snd_config_add snd_config_add_dylibloader_orig_asound
+#define snd_config_add_before snd_config_add_before_dylibloader_orig_asound
+#define snd_config_add_after snd_config_add_after_dylibloader_orig_asound
+#define snd_config_remove snd_config_remove_dylibloader_orig_asound
+#define snd_config_delete snd_config_delete_dylibloader_orig_asound
+#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_orig_asound
+#define snd_config_copy snd_config_copy_dylibloader_orig_asound
+#define snd_config_make snd_config_make_dylibloader_orig_asound
+#define snd_config_make_integer snd_config_make_integer_dylibloader_orig_asound
+#define snd_config_make_integer64 snd_config_make_integer64_dylibloader_orig_asound
+#define snd_config_make_real snd_config_make_real_dylibloader_orig_asound
+#define snd_config_make_string snd_config_make_string_dylibloader_orig_asound
+#define snd_config_make_pointer snd_config_make_pointer_dylibloader_orig_asound
+#define snd_config_make_compound snd_config_make_compound_dylibloader_orig_asound
+#define snd_config_imake_integer snd_config_imake_integer_dylibloader_orig_asound
+#define snd_config_imake_integer64 snd_config_imake_integer64_dylibloader_orig_asound
+#define snd_config_imake_real snd_config_imake_real_dylibloader_orig_asound
+#define snd_config_imake_string snd_config_imake_string_dylibloader_orig_asound
+#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_orig_asound
+#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_orig_asound
+#define snd_config_get_type snd_config_get_type_dylibloader_orig_asound
+#define snd_config_is_array snd_config_is_array_dylibloader_orig_asound
+#define snd_config_set_id snd_config_set_id_dylibloader_orig_asound
+#define snd_config_set_integer snd_config_set_integer_dylibloader_orig_asound
+#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_orig_asound
+#define snd_config_set_real snd_config_set_real_dylibloader_orig_asound
+#define snd_config_set_string snd_config_set_string_dylibloader_orig_asound
+#define snd_config_set_ascii snd_config_set_ascii_dylibloader_orig_asound
+#define snd_config_set_pointer snd_config_set_pointer_dylibloader_orig_asound
+#define snd_config_get_id snd_config_get_id_dylibloader_orig_asound
+#define snd_config_get_integer snd_config_get_integer_dylibloader_orig_asound
+#define snd_config_get_integer64 snd_config_get_integer64_dylibloader_orig_asound
+#define snd_config_get_real snd_config_get_real_dylibloader_orig_asound
+#define snd_config_get_ireal snd_config_get_ireal_dylibloader_orig_asound
+#define snd_config_get_string snd_config_get_string_dylibloader_orig_asound
+#define snd_config_get_ascii snd_config_get_ascii_dylibloader_orig_asound
+#define snd_config_get_pointer snd_config_get_pointer_dylibloader_orig_asound
+#define snd_config_test_id snd_config_test_id_dylibloader_orig_asound
+#define snd_config_iterator_first snd_config_iterator_first_dylibloader_orig_asound
+#define snd_config_iterator_next snd_config_iterator_next_dylibloader_orig_asound
+#define snd_config_iterator_end snd_config_iterator_end_dylibloader_orig_asound
+#define snd_config_iterator_entry snd_config_iterator_entry_dylibloader_orig_asound
+#define snd_config_get_bool_ascii snd_config_get_bool_ascii_dylibloader_orig_asound
+#define snd_config_get_bool snd_config_get_bool_dylibloader_orig_asound
+#define snd_config_get_ctl_iface_ascii snd_config_get_ctl_iface_ascii_dylibloader_orig_asound
+#define snd_config_get_ctl_iface snd_config_get_ctl_iface_dylibloader_orig_asound
+#define snd_names_list snd_names_list_dylibloader_orig_asound
+#define snd_names_list_free snd_names_list_free_dylibloader_orig_asound
+#define snd_pcm_open snd_pcm_open_dylibloader_orig_asound
+#define snd_pcm_open_lconf snd_pcm_open_lconf_dylibloader_orig_asound
+#define snd_pcm_open_fallback snd_pcm_open_fallback_dylibloader_orig_asound
+#define snd_pcm_close snd_pcm_close_dylibloader_orig_asound
+#define snd_pcm_name snd_pcm_name_dylibloader_orig_asound
+#define snd_pcm_type snd_pcm_type_dylibloader_orig_asound
+#define snd_pcm_stream snd_pcm_stream_dylibloader_orig_asound
+#define snd_pcm_poll_descriptors_count snd_pcm_poll_descriptors_count_dylibloader_orig_asound
+#define snd_pcm_poll_descriptors snd_pcm_poll_descriptors_dylibloader_orig_asound
+#define snd_pcm_poll_descriptors_revents snd_pcm_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_pcm_nonblock snd_pcm_nonblock_dylibloader_orig_asound
+#define snd_async_add_pcm_handler snd_async_add_pcm_handler_dylibloader_orig_asound
+#define snd_async_handler_get_pcm snd_async_handler_get_pcm_dylibloader_orig_asound
+#define snd_pcm_info snd_pcm_info_dylibloader_orig_asound
+#define snd_pcm_hw_params_current snd_pcm_hw_params_current_dylibloader_orig_asound
+#define snd_pcm_hw_params snd_pcm_hw_params_dylibloader_orig_asound
+#define snd_pcm_hw_free snd_pcm_hw_free_dylibloader_orig_asound
+#define snd_pcm_sw_params_current snd_pcm_sw_params_current_dylibloader_orig_asound
+#define snd_pcm_sw_params snd_pcm_sw_params_dylibloader_orig_asound
+#define snd_pcm_prepare snd_pcm_prepare_dylibloader_orig_asound
+#define snd_pcm_reset snd_pcm_reset_dylibloader_orig_asound
+#define snd_pcm_status snd_pcm_status_dylibloader_orig_asound
+#define snd_pcm_start snd_pcm_start_dylibloader_orig_asound
+#define snd_pcm_drop snd_pcm_drop_dylibloader_orig_asound
+#define snd_pcm_drain snd_pcm_drain_dylibloader_orig_asound
+#define snd_pcm_pause snd_pcm_pause_dylibloader_orig_asound
+#define snd_pcm_state snd_pcm_state_dylibloader_orig_asound
+#define snd_pcm_hwsync snd_pcm_hwsync_dylibloader_orig_asound
+#define snd_pcm_delay snd_pcm_delay_dylibloader_orig_asound
+#define snd_pcm_resume snd_pcm_resume_dylibloader_orig_asound
+#define snd_pcm_htimestamp snd_pcm_htimestamp_dylibloader_orig_asound
+#define snd_pcm_avail snd_pcm_avail_dylibloader_orig_asound
+#define snd_pcm_avail_update snd_pcm_avail_update_dylibloader_orig_asound
+#define snd_pcm_avail_delay snd_pcm_avail_delay_dylibloader_orig_asound
+#define snd_pcm_rewindable snd_pcm_rewindable_dylibloader_orig_asound
+#define snd_pcm_rewind snd_pcm_rewind_dylibloader_orig_asound
+#define snd_pcm_forwardable snd_pcm_forwardable_dylibloader_orig_asound
+#define snd_pcm_forward snd_pcm_forward_dylibloader_orig_asound
+#define snd_pcm_writei snd_pcm_writei_dylibloader_orig_asound
+#define snd_pcm_readi snd_pcm_readi_dylibloader_orig_asound
+#define snd_pcm_writen snd_pcm_writen_dylibloader_orig_asound
+#define snd_pcm_readn snd_pcm_readn_dylibloader_orig_asound
+#define snd_pcm_wait snd_pcm_wait_dylibloader_orig_asound
+#define snd_pcm_link snd_pcm_link_dylibloader_orig_asound
+#define snd_pcm_unlink snd_pcm_unlink_dylibloader_orig_asound
+#define snd_pcm_query_chmaps snd_pcm_query_chmaps_dylibloader_orig_asound
+#define snd_pcm_query_chmaps_from_hw snd_pcm_query_chmaps_from_hw_dylibloader_orig_asound
+#define snd_pcm_free_chmaps snd_pcm_free_chmaps_dylibloader_orig_asound
+#define snd_pcm_get_chmap snd_pcm_get_chmap_dylibloader_orig_asound
+#define snd_pcm_set_chmap snd_pcm_set_chmap_dylibloader_orig_asound
+#define snd_pcm_chmap_type_name snd_pcm_chmap_type_name_dylibloader_orig_asound
+#define snd_pcm_chmap_name snd_pcm_chmap_name_dylibloader_orig_asound
+#define snd_pcm_chmap_long_name snd_pcm_chmap_long_name_dylibloader_orig_asound
+#define snd_pcm_chmap_print snd_pcm_chmap_print_dylibloader_orig_asound
+#define snd_pcm_chmap_from_string snd_pcm_chmap_from_string_dylibloader_orig_asound
+#define snd_pcm_chmap_parse_string snd_pcm_chmap_parse_string_dylibloader_orig_asound
+#define snd_pcm_recover snd_pcm_recover_dylibloader_orig_asound
+#define snd_pcm_set_params snd_pcm_set_params_dylibloader_orig_asound
+#define snd_pcm_get_params snd_pcm_get_params_dylibloader_orig_asound
+#define snd_pcm_info_sizeof snd_pcm_info_sizeof_dylibloader_orig_asound
+#define snd_pcm_info_malloc snd_pcm_info_malloc_dylibloader_orig_asound
+#define snd_pcm_info_free snd_pcm_info_free_dylibloader_orig_asound
+#define snd_pcm_info_copy snd_pcm_info_copy_dylibloader_orig_asound
+#define snd_pcm_info_get_device snd_pcm_info_get_device_dylibloader_orig_asound
+#define snd_pcm_info_get_subdevice snd_pcm_info_get_subdevice_dylibloader_orig_asound
+#define snd_pcm_info_get_stream snd_pcm_info_get_stream_dylibloader_orig_asound
+#define snd_pcm_info_get_card snd_pcm_info_get_card_dylibloader_orig_asound
+#define snd_pcm_info_get_id snd_pcm_info_get_id_dylibloader_orig_asound
+#define snd_pcm_info_get_name snd_pcm_info_get_name_dylibloader_orig_asound
+#define snd_pcm_info_get_subdevice_name snd_pcm_info_get_subdevice_name_dylibloader_orig_asound
+#define snd_pcm_info_get_class snd_pcm_info_get_class_dylibloader_orig_asound
+#define snd_pcm_info_get_subclass snd_pcm_info_get_subclass_dylibloader_orig_asound
+#define snd_pcm_info_get_subdevices_count snd_pcm_info_get_subdevices_count_dylibloader_orig_asound
+#define snd_pcm_info_get_subdevices_avail snd_pcm_info_get_subdevices_avail_dylibloader_orig_asound
+#define snd_pcm_info_get_sync snd_pcm_info_get_sync_dylibloader_orig_asound
+#define snd_pcm_info_set_device snd_pcm_info_set_device_dylibloader_orig_asound
+#define snd_pcm_info_set_subdevice snd_pcm_info_set_subdevice_dylibloader_orig_asound
+#define snd_pcm_info_set_stream snd_pcm_info_set_stream_dylibloader_orig_asound
+#define snd_pcm_hw_params_any snd_pcm_hw_params_any_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_mmap_sample_resolution snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_double snd_pcm_hw_params_is_double_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_batch snd_pcm_hw_params_is_batch_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_block_transfer snd_pcm_hw_params_is_block_transfer_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_monotonic snd_pcm_hw_params_is_monotonic_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_overrange snd_pcm_hw_params_can_overrange_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_pause snd_pcm_hw_params_can_pause_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_resume snd_pcm_hw_params_can_resume_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_half_duplex snd_pcm_hw_params_is_half_duplex_dylibloader_orig_asound
+#define snd_pcm_hw_params_is_joint_duplex snd_pcm_hw_params_is_joint_duplex_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_sync_start snd_pcm_hw_params_can_sync_start_dylibloader_orig_asound
+#define snd_pcm_hw_params_can_disable_period_wakeup snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_orig_asound
+#define snd_pcm_hw_params_supports_audio_wallclock_ts snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_orig_asound
+#define snd_pcm_hw_params_supports_audio_ts_type snd_pcm_hw_params_supports_audio_ts_type_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate_numden snd_pcm_hw_params_get_rate_numden_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_sbits snd_pcm_hw_params_get_sbits_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_fifo_size snd_pcm_hw_params_get_fifo_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_sizeof snd_pcm_hw_params_sizeof_dylibloader_orig_asound
+#define snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc_dylibloader_orig_asound
+#define snd_pcm_hw_params_free snd_pcm_hw_params_free_dylibloader_orig_asound
+#define snd_pcm_hw_params_copy snd_pcm_hw_params_copy_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_access snd_pcm_hw_params_get_access_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_access snd_pcm_hw_params_test_access_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_access_first snd_pcm_hw_params_set_access_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_access_last snd_pcm_hw_params_set_access_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_access_mask snd_pcm_hw_params_set_access_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_access_mask snd_pcm_hw_params_get_access_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_format snd_pcm_hw_params_get_format_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_format snd_pcm_hw_params_test_format_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_format_first snd_pcm_hw_params_set_format_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_format_last snd_pcm_hw_params_set_format_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_format_mask snd_pcm_hw_params_set_format_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_format_mask snd_pcm_hw_params_get_format_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_subformat snd_pcm_hw_params_get_subformat_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_subformat snd_pcm_hw_params_test_subformat_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_subformat snd_pcm_hw_params_set_subformat_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_subformat_first snd_pcm_hw_params_set_subformat_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_subformat_last snd_pcm_hw_params_set_subformat_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_subformat_mask snd_pcm_hw_params_set_subformat_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_subformat_mask snd_pcm_hw_params_get_subformat_mask_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_channels snd_pcm_hw_params_get_channels_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_channels_min snd_pcm_hw_params_get_channels_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_channels_max snd_pcm_hw_params_get_channels_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_channels snd_pcm_hw_params_test_channels_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels snd_pcm_hw_params_set_channels_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_min snd_pcm_hw_params_set_channels_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_max snd_pcm_hw_params_set_channels_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_minmax snd_pcm_hw_params_set_channels_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_near snd_pcm_hw_params_set_channels_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_first snd_pcm_hw_params_set_channels_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_channels_last snd_pcm_hw_params_set_channels_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate snd_pcm_hw_params_get_rate_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate_min snd_pcm_hw_params_get_rate_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate_max snd_pcm_hw_params_get_rate_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_rate snd_pcm_hw_params_test_rate_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate snd_pcm_hw_params_set_rate_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_min snd_pcm_hw_params_set_rate_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_max snd_pcm_hw_params_set_rate_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_minmax snd_pcm_hw_params_set_rate_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_near snd_pcm_hw_params_set_rate_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_first snd_pcm_hw_params_set_rate_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_last snd_pcm_hw_params_set_rate_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_rate_resample snd_pcm_hw_params_set_rate_resample_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_rate_resample snd_pcm_hw_params_get_rate_resample_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_export_buffer snd_pcm_hw_params_set_export_buffer_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_export_buffer snd_pcm_hw_params_get_export_buffer_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_wakeup snd_pcm_hw_params_set_period_wakeup_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_wakeup snd_pcm_hw_params_get_period_wakeup_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_time snd_pcm_hw_params_get_period_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_time_min snd_pcm_hw_params_get_period_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_time_max snd_pcm_hw_params_get_period_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_period_time snd_pcm_hw_params_test_period_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time snd_pcm_hw_params_set_period_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_min snd_pcm_hw_params_set_period_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_max snd_pcm_hw_params_set_period_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_minmax snd_pcm_hw_params_set_period_time_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_near snd_pcm_hw_params_set_period_time_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_first snd_pcm_hw_params_set_period_time_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_time_last snd_pcm_hw_params_set_period_time_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_size snd_pcm_hw_params_get_period_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_size_min snd_pcm_hw_params_get_period_size_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_period_size_max snd_pcm_hw_params_get_period_size_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_period_size snd_pcm_hw_params_test_period_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size snd_pcm_hw_params_set_period_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_min snd_pcm_hw_params_set_period_size_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_max snd_pcm_hw_params_set_period_size_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_minmax snd_pcm_hw_params_set_period_size_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_near snd_pcm_hw_params_set_period_size_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_first snd_pcm_hw_params_set_period_size_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_last snd_pcm_hw_params_set_period_size_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_period_size_integer snd_pcm_hw_params_set_period_size_integer_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_periods snd_pcm_hw_params_get_periods_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_periods_min snd_pcm_hw_params_get_periods_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_periods_max snd_pcm_hw_params_get_periods_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_periods snd_pcm_hw_params_test_periods_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods snd_pcm_hw_params_set_periods_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_min snd_pcm_hw_params_set_periods_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_max snd_pcm_hw_params_set_periods_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_minmax snd_pcm_hw_params_set_periods_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_near snd_pcm_hw_params_set_periods_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_first snd_pcm_hw_params_set_periods_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_last snd_pcm_hw_params_set_periods_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_periods_integer snd_pcm_hw_params_set_periods_integer_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_time snd_pcm_hw_params_get_buffer_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_time_min snd_pcm_hw_params_get_buffer_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_time_max snd_pcm_hw_params_get_buffer_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_buffer_time snd_pcm_hw_params_test_buffer_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time snd_pcm_hw_params_set_buffer_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_min snd_pcm_hw_params_set_buffer_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_max snd_pcm_hw_params_set_buffer_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_minmax snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_near snd_pcm_hw_params_set_buffer_time_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_first snd_pcm_hw_params_set_buffer_time_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_time_last snd_pcm_hw_params_set_buffer_time_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_size snd_pcm_hw_params_get_buffer_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_size_min snd_pcm_hw_params_get_buffer_size_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_buffer_size_max snd_pcm_hw_params_get_buffer_size_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_buffer_size snd_pcm_hw_params_test_buffer_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size snd_pcm_hw_params_set_buffer_size_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_min snd_pcm_hw_params_set_buffer_size_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_max snd_pcm_hw_params_set_buffer_size_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_minmax snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_near snd_pcm_hw_params_set_buffer_size_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_first snd_pcm_hw_params_set_buffer_size_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_buffer_size_last snd_pcm_hw_params_set_buffer_size_last_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_min_align snd_pcm_hw_params_get_min_align_dylibloader_orig_asound
+#define snd_pcm_sw_params_sizeof snd_pcm_sw_params_sizeof_dylibloader_orig_asound
+#define snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc_dylibloader_orig_asound
+#define snd_pcm_sw_params_free snd_pcm_sw_params_free_dylibloader_orig_asound
+#define snd_pcm_sw_params_copy snd_pcm_sw_params_copy_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_boundary snd_pcm_sw_params_get_boundary_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_tstamp_mode snd_pcm_sw_params_set_tstamp_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_tstamp_mode snd_pcm_sw_params_get_tstamp_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_avail_min snd_pcm_sw_params_set_avail_min_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_avail_min snd_pcm_sw_params_get_avail_min_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_period_event snd_pcm_sw_params_set_period_event_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_period_event snd_pcm_sw_params_get_period_event_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_start_threshold snd_pcm_sw_params_set_start_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_start_threshold snd_pcm_sw_params_get_start_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_stop_threshold snd_pcm_sw_params_set_stop_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_stop_threshold snd_pcm_sw_params_get_stop_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_silence_threshold snd_pcm_sw_params_set_silence_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_silence_threshold snd_pcm_sw_params_get_silence_threshold_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_silence_size snd_pcm_sw_params_set_silence_size_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_silence_size snd_pcm_sw_params_get_silence_size_dylibloader_orig_asound
+#define snd_pcm_access_mask_sizeof snd_pcm_access_mask_sizeof_dylibloader_orig_asound
+#define snd_pcm_access_mask_malloc snd_pcm_access_mask_malloc_dylibloader_orig_asound
+#define snd_pcm_access_mask_free snd_pcm_access_mask_free_dylibloader_orig_asound
+#define snd_pcm_access_mask_copy snd_pcm_access_mask_copy_dylibloader_orig_asound
+#define snd_pcm_access_mask_none snd_pcm_access_mask_none_dylibloader_orig_asound
+#define snd_pcm_access_mask_any snd_pcm_access_mask_any_dylibloader_orig_asound
+#define snd_pcm_access_mask_test snd_pcm_access_mask_test_dylibloader_orig_asound
+#define snd_pcm_access_mask_empty snd_pcm_access_mask_empty_dylibloader_orig_asound
+#define snd_pcm_access_mask_set snd_pcm_access_mask_set_dylibloader_orig_asound
+#define snd_pcm_access_mask_reset snd_pcm_access_mask_reset_dylibloader_orig_asound
+#define snd_pcm_format_mask_sizeof snd_pcm_format_mask_sizeof_dylibloader_orig_asound
+#define snd_pcm_format_mask_malloc snd_pcm_format_mask_malloc_dylibloader_orig_asound
+#define snd_pcm_format_mask_free snd_pcm_format_mask_free_dylibloader_orig_asound
+#define snd_pcm_format_mask_copy snd_pcm_format_mask_copy_dylibloader_orig_asound
+#define snd_pcm_format_mask_none snd_pcm_format_mask_none_dylibloader_orig_asound
+#define snd_pcm_format_mask_any snd_pcm_format_mask_any_dylibloader_orig_asound
+#define snd_pcm_format_mask_test snd_pcm_format_mask_test_dylibloader_orig_asound
+#define snd_pcm_format_mask_empty snd_pcm_format_mask_empty_dylibloader_orig_asound
+#define snd_pcm_format_mask_set snd_pcm_format_mask_set_dylibloader_orig_asound
+#define snd_pcm_format_mask_reset snd_pcm_format_mask_reset_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_sizeof snd_pcm_subformat_mask_sizeof_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_malloc snd_pcm_subformat_mask_malloc_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_free snd_pcm_subformat_mask_free_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_copy snd_pcm_subformat_mask_copy_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_none snd_pcm_subformat_mask_none_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_any snd_pcm_subformat_mask_any_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_test snd_pcm_subformat_mask_test_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_empty snd_pcm_subformat_mask_empty_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_set snd_pcm_subformat_mask_set_dylibloader_orig_asound
+#define snd_pcm_subformat_mask_reset snd_pcm_subformat_mask_reset_dylibloader_orig_asound
+#define snd_pcm_status_sizeof snd_pcm_status_sizeof_dylibloader_orig_asound
+#define snd_pcm_status_malloc snd_pcm_status_malloc_dylibloader_orig_asound
+#define snd_pcm_status_free snd_pcm_status_free_dylibloader_orig_asound
+#define snd_pcm_status_copy snd_pcm_status_copy_dylibloader_orig_asound
+#define snd_pcm_status_get_state snd_pcm_status_get_state_dylibloader_orig_asound
+#define snd_pcm_status_get_trigger_tstamp snd_pcm_status_get_trigger_tstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_trigger_htstamp snd_pcm_status_get_trigger_htstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_tstamp snd_pcm_status_get_tstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_htstamp snd_pcm_status_get_htstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_audio_htstamp snd_pcm_status_get_audio_htstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_driver_htstamp snd_pcm_status_get_driver_htstamp_dylibloader_orig_asound
+#define snd_pcm_status_get_delay snd_pcm_status_get_delay_dylibloader_orig_asound
+#define snd_pcm_status_get_avail snd_pcm_status_get_avail_dylibloader_orig_asound
+#define snd_pcm_status_get_avail_max snd_pcm_status_get_avail_max_dylibloader_orig_asound
+#define snd_pcm_status_get_overrange snd_pcm_status_get_overrange_dylibloader_orig_asound
+#define snd_pcm_type_name snd_pcm_type_name_dylibloader_orig_asound
+#define snd_pcm_stream_name snd_pcm_stream_name_dylibloader_orig_asound
+#define snd_pcm_access_name snd_pcm_access_name_dylibloader_orig_asound
+#define snd_pcm_format_name snd_pcm_format_name_dylibloader_orig_asound
+#define snd_pcm_format_description snd_pcm_format_description_dylibloader_orig_asound
+#define snd_pcm_subformat_name snd_pcm_subformat_name_dylibloader_orig_asound
+#define snd_pcm_subformat_description snd_pcm_subformat_description_dylibloader_orig_asound
+#define snd_pcm_format_value snd_pcm_format_value_dylibloader_orig_asound
+#define snd_pcm_tstamp_mode_name snd_pcm_tstamp_mode_name_dylibloader_orig_asound
+#define snd_pcm_state_name snd_pcm_state_name_dylibloader_orig_asound
+#define snd_pcm_dump snd_pcm_dump_dylibloader_orig_asound
+#define snd_pcm_dump_hw_setup snd_pcm_dump_hw_setup_dylibloader_orig_asound
+#define snd_pcm_dump_sw_setup snd_pcm_dump_sw_setup_dylibloader_orig_asound
+#define snd_pcm_dump_setup snd_pcm_dump_setup_dylibloader_orig_asound
+#define snd_pcm_hw_params_dump snd_pcm_hw_params_dump_dylibloader_orig_asound
+#define snd_pcm_sw_params_dump snd_pcm_sw_params_dump_dylibloader_orig_asound
+#define snd_pcm_status_dump snd_pcm_status_dump_dylibloader_orig_asound
+#define snd_pcm_mmap_begin snd_pcm_mmap_begin_dylibloader_orig_asound
+#define snd_pcm_mmap_commit snd_pcm_mmap_commit_dylibloader_orig_asound
+#define snd_pcm_mmap_writei snd_pcm_mmap_writei_dylibloader_orig_asound
+#define snd_pcm_mmap_readi snd_pcm_mmap_readi_dylibloader_orig_asound
+#define snd_pcm_mmap_writen snd_pcm_mmap_writen_dylibloader_orig_asound
+#define snd_pcm_mmap_readn snd_pcm_mmap_readn_dylibloader_orig_asound
+#define snd_pcm_format_signed snd_pcm_format_signed_dylibloader_orig_asound
+#define snd_pcm_format_unsigned snd_pcm_format_unsigned_dylibloader_orig_asound
+#define snd_pcm_format_linear snd_pcm_format_linear_dylibloader_orig_asound
+#define snd_pcm_format_float snd_pcm_format_float_dylibloader_orig_asound
+#define snd_pcm_format_little_endian snd_pcm_format_little_endian_dylibloader_orig_asound
+#define snd_pcm_format_big_endian snd_pcm_format_big_endian_dylibloader_orig_asound
+#define snd_pcm_format_cpu_endian snd_pcm_format_cpu_endian_dylibloader_orig_asound
+#define snd_pcm_format_width snd_pcm_format_width_dylibloader_orig_asound
+#define snd_pcm_format_physical_width snd_pcm_format_physical_width_dylibloader_orig_asound
+#define snd_pcm_build_linear_format snd_pcm_build_linear_format_dylibloader_orig_asound
+#define snd_pcm_format_size snd_pcm_format_size_dylibloader_orig_asound
+#define snd_pcm_format_silence snd_pcm_format_silence_dylibloader_orig_asound
+#define snd_pcm_format_silence_16 snd_pcm_format_silence_16_dylibloader_orig_asound
+#define snd_pcm_format_silence_32 snd_pcm_format_silence_32_dylibloader_orig_asound
+#define snd_pcm_format_silence_64 snd_pcm_format_silence_64_dylibloader_orig_asound
+#define snd_pcm_format_set_silence snd_pcm_format_set_silence_dylibloader_orig_asound
+#define snd_pcm_bytes_to_frames snd_pcm_bytes_to_frames_dylibloader_orig_asound
+#define snd_pcm_frames_to_bytes snd_pcm_frames_to_bytes_dylibloader_orig_asound
+#define snd_pcm_bytes_to_samples snd_pcm_bytes_to_samples_dylibloader_orig_asound
+#define snd_pcm_samples_to_bytes snd_pcm_samples_to_bytes_dylibloader_orig_asound
+#define snd_pcm_area_silence snd_pcm_area_silence_dylibloader_orig_asound
+#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_orig_asound
+#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_orig_asound
+#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_orig_asound
+#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_orig_asound
+#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_orig_asound
+#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_orig_asound
+#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_orig_asound
+#define snd_pcm_hook_add snd_pcm_hook_add_dylibloader_orig_asound
+#define snd_pcm_hook_remove snd_pcm_hook_remove_dylibloader_orig_asound
+#define snd_pcm_meter_get_bufsize snd_pcm_meter_get_bufsize_dylibloader_orig_asound
+#define snd_pcm_meter_get_channels snd_pcm_meter_get_channels_dylibloader_orig_asound
+#define snd_pcm_meter_get_rate snd_pcm_meter_get_rate_dylibloader_orig_asound
+#define snd_pcm_meter_get_now snd_pcm_meter_get_now_dylibloader_orig_asound
+#define snd_pcm_meter_get_boundary snd_pcm_meter_get_boundary_dylibloader_orig_asound
+#define snd_pcm_meter_add_scope snd_pcm_meter_add_scope_dylibloader_orig_asound
+#define snd_pcm_meter_search_scope snd_pcm_meter_search_scope_dylibloader_orig_asound
+#define snd_pcm_scope_malloc snd_pcm_scope_malloc_dylibloader_orig_asound
+#define snd_pcm_scope_set_ops snd_pcm_scope_set_ops_dylibloader_orig_asound
+#define snd_pcm_scope_set_name snd_pcm_scope_set_name_dylibloader_orig_asound
+#define snd_pcm_scope_get_name snd_pcm_scope_get_name_dylibloader_orig_asound
+#define snd_pcm_scope_get_callback_private snd_pcm_scope_get_callback_private_dylibloader_orig_asound
+#define snd_pcm_scope_set_callback_private snd_pcm_scope_set_callback_private_dylibloader_orig_asound
+#define snd_pcm_scope_s16_open snd_pcm_scope_s16_open_dylibloader_orig_asound
+#define snd_pcm_scope_s16_get_channel_buffer snd_pcm_scope_s16_get_channel_buffer_dylibloader_orig_asound
+#define snd_spcm_init snd_spcm_init_dylibloader_orig_asound
+#define snd_spcm_init_duplex snd_spcm_init_duplex_dylibloader_orig_asound
+#define snd_spcm_init_get_params snd_spcm_init_get_params_dylibloader_orig_asound
+#define snd_pcm_start_mode_name snd_pcm_start_mode_name_dylibloader_orig_asound
+#define snd_pcm_xrun_mode_name snd_pcm_xrun_mode_name_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_start_mode snd_pcm_sw_params_set_start_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_start_mode snd_pcm_sw_params_get_start_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_xrun_mode snd_pcm_sw_params_set_xrun_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_xrun_mode snd_pcm_sw_params_get_xrun_mode_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_xfer_align snd_pcm_sw_params_set_xfer_align_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_xfer_align snd_pcm_sw_params_get_xfer_align_dylibloader_orig_asound
+#define snd_pcm_sw_params_set_sleep_min snd_pcm_sw_params_set_sleep_min_dylibloader_orig_asound
+#define snd_pcm_sw_params_get_sleep_min snd_pcm_sw_params_get_sleep_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_tick_time snd_pcm_hw_params_get_tick_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_tick_time_min snd_pcm_hw_params_get_tick_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_get_tick_time_max snd_pcm_hw_params_get_tick_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_test_tick_time snd_pcm_hw_params_test_tick_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time snd_pcm_hw_params_set_tick_time_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_min snd_pcm_hw_params_set_tick_time_min_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_max snd_pcm_hw_params_set_tick_time_max_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_minmax snd_pcm_hw_params_set_tick_time_minmax_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_near snd_pcm_hw_params_set_tick_time_near_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_first snd_pcm_hw_params_set_tick_time_first_dylibloader_orig_asound
+#define snd_pcm_hw_params_set_tick_time_last snd_pcm_hw_params_set_tick_time_last_dylibloader_orig_asound
+#define snd_rawmidi_open snd_rawmidi_open_dylibloader_orig_asound
+#define snd_rawmidi_open_lconf snd_rawmidi_open_lconf_dylibloader_orig_asound
+#define snd_rawmidi_close snd_rawmidi_close_dylibloader_orig_asound
+#define snd_rawmidi_poll_descriptors_count snd_rawmidi_poll_descriptors_count_dylibloader_orig_asound
+#define snd_rawmidi_poll_descriptors snd_rawmidi_poll_descriptors_dylibloader_orig_asound
+#define snd_rawmidi_poll_descriptors_revents snd_rawmidi_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_rawmidi_nonblock snd_rawmidi_nonblock_dylibloader_orig_asound
+#define snd_rawmidi_info_sizeof snd_rawmidi_info_sizeof_dylibloader_orig_asound
+#define snd_rawmidi_info_malloc snd_rawmidi_info_malloc_dylibloader_orig_asound
+#define snd_rawmidi_info_free snd_rawmidi_info_free_dylibloader_orig_asound
+#define snd_rawmidi_info_copy snd_rawmidi_info_copy_dylibloader_orig_asound
+#define snd_rawmidi_info_get_device snd_rawmidi_info_get_device_dylibloader_orig_asound
+#define snd_rawmidi_info_get_subdevice snd_rawmidi_info_get_subdevice_dylibloader_orig_asound
+#define snd_rawmidi_info_get_stream snd_rawmidi_info_get_stream_dylibloader_orig_asound
+#define snd_rawmidi_info_get_card snd_rawmidi_info_get_card_dylibloader_orig_asound
+#define snd_rawmidi_info_get_flags snd_rawmidi_info_get_flags_dylibloader_orig_asound
+#define snd_rawmidi_info_get_id snd_rawmidi_info_get_id_dylibloader_orig_asound
+#define snd_rawmidi_info_get_name snd_rawmidi_info_get_name_dylibloader_orig_asound
+#define snd_rawmidi_info_get_subdevice_name snd_rawmidi_info_get_subdevice_name_dylibloader_orig_asound
+#define snd_rawmidi_info_get_subdevices_count snd_rawmidi_info_get_subdevices_count_dylibloader_orig_asound
+#define snd_rawmidi_info_get_subdevices_avail snd_rawmidi_info_get_subdevices_avail_dylibloader_orig_asound
+#define snd_rawmidi_info_set_device snd_rawmidi_info_set_device_dylibloader_orig_asound
+#define snd_rawmidi_info_set_subdevice snd_rawmidi_info_set_subdevice_dylibloader_orig_asound
+#define snd_rawmidi_info_set_stream snd_rawmidi_info_set_stream_dylibloader_orig_asound
+#define snd_rawmidi_info snd_rawmidi_info_dylibloader_orig_asound
+#define snd_rawmidi_params_sizeof snd_rawmidi_params_sizeof_dylibloader_orig_asound
+#define snd_rawmidi_params_malloc snd_rawmidi_params_malloc_dylibloader_orig_asound
+#define snd_rawmidi_params_free snd_rawmidi_params_free_dylibloader_orig_asound
+#define snd_rawmidi_params_copy snd_rawmidi_params_copy_dylibloader_orig_asound
+#define snd_rawmidi_params_set_buffer_size snd_rawmidi_params_set_buffer_size_dylibloader_orig_asound
+#define snd_rawmidi_params_get_buffer_size snd_rawmidi_params_get_buffer_size_dylibloader_orig_asound
+#define snd_rawmidi_params_set_avail_min snd_rawmidi_params_set_avail_min_dylibloader_orig_asound
+#define snd_rawmidi_params_get_avail_min snd_rawmidi_params_get_avail_min_dylibloader_orig_asound
+#define snd_rawmidi_params_set_no_active_sensing snd_rawmidi_params_set_no_active_sensing_dylibloader_orig_asound
+#define snd_rawmidi_params_get_no_active_sensing snd_rawmidi_params_get_no_active_sensing_dylibloader_orig_asound
+#define snd_rawmidi_params snd_rawmidi_params_dylibloader_orig_asound
+#define snd_rawmidi_params_current snd_rawmidi_params_current_dylibloader_orig_asound
+#define snd_rawmidi_status_sizeof snd_rawmidi_status_sizeof_dylibloader_orig_asound
+#define snd_rawmidi_status_malloc snd_rawmidi_status_malloc_dylibloader_orig_asound
+#define snd_rawmidi_status_free snd_rawmidi_status_free_dylibloader_orig_asound
+#define snd_rawmidi_status_copy snd_rawmidi_status_copy_dylibloader_orig_asound
+#define snd_rawmidi_status_get_tstamp snd_rawmidi_status_get_tstamp_dylibloader_orig_asound
+#define snd_rawmidi_status_get_avail snd_rawmidi_status_get_avail_dylibloader_orig_asound
+#define snd_rawmidi_status_get_xruns snd_rawmidi_status_get_xruns_dylibloader_orig_asound
+#define snd_rawmidi_status snd_rawmidi_status_dylibloader_orig_asound
+#define snd_rawmidi_drain snd_rawmidi_drain_dylibloader_orig_asound
+#define snd_rawmidi_drop snd_rawmidi_drop_dylibloader_orig_asound
+#define snd_rawmidi_write snd_rawmidi_write_dylibloader_orig_asound
+#define snd_rawmidi_read snd_rawmidi_read_dylibloader_orig_asound
+#define snd_rawmidi_name snd_rawmidi_name_dylibloader_orig_asound
+#define snd_rawmidi_type snd_rawmidi_type_dylibloader_orig_asound
+#define snd_rawmidi_stream snd_rawmidi_stream_dylibloader_orig_asound
+#define snd_timer_query_open snd_timer_query_open_dylibloader_orig_asound
+#define snd_timer_query_open_lconf snd_timer_query_open_lconf_dylibloader_orig_asound
+#define snd_timer_query_close snd_timer_query_close_dylibloader_orig_asound
+#define snd_timer_query_next_device snd_timer_query_next_device_dylibloader_orig_asound
+#define snd_timer_query_info snd_timer_query_info_dylibloader_orig_asound
+#define snd_timer_query_params snd_timer_query_params_dylibloader_orig_asound
+#define snd_timer_query_status snd_timer_query_status_dylibloader_orig_asound
+#define snd_timer_open snd_timer_open_dylibloader_orig_asound
+#define snd_timer_open_lconf snd_timer_open_lconf_dylibloader_orig_asound
+#define snd_timer_close snd_timer_close_dylibloader_orig_asound
+#define snd_async_add_timer_handler snd_async_add_timer_handler_dylibloader_orig_asound
+#define snd_async_handler_get_timer snd_async_handler_get_timer_dylibloader_orig_asound
+#define snd_timer_poll_descriptors_count snd_timer_poll_descriptors_count_dylibloader_orig_asound
+#define snd_timer_poll_descriptors snd_timer_poll_descriptors_dylibloader_orig_asound
+#define snd_timer_poll_descriptors_revents snd_timer_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_timer_info snd_timer_info_dylibloader_orig_asound
+#define snd_timer_params snd_timer_params_dylibloader_orig_asound
+#define snd_timer_status snd_timer_status_dylibloader_orig_asound
+#define snd_timer_start snd_timer_start_dylibloader_orig_asound
+#define snd_timer_stop snd_timer_stop_dylibloader_orig_asound
+#define snd_timer_continue snd_timer_continue_dylibloader_orig_asound
+#define snd_timer_read snd_timer_read_dylibloader_orig_asound
+#define snd_timer_id_sizeof snd_timer_id_sizeof_dylibloader_orig_asound
+#define snd_timer_id_malloc snd_timer_id_malloc_dylibloader_orig_asound
+#define snd_timer_id_free snd_timer_id_free_dylibloader_orig_asound
+#define snd_timer_id_copy snd_timer_id_copy_dylibloader_orig_asound
+#define snd_timer_id_set_class snd_timer_id_set_class_dylibloader_orig_asound
+#define snd_timer_id_get_class snd_timer_id_get_class_dylibloader_orig_asound
+#define snd_timer_id_set_sclass snd_timer_id_set_sclass_dylibloader_orig_asound
+#define snd_timer_id_get_sclass snd_timer_id_get_sclass_dylibloader_orig_asound
+#define snd_timer_id_set_card snd_timer_id_set_card_dylibloader_orig_asound
+#define snd_timer_id_get_card snd_timer_id_get_card_dylibloader_orig_asound
+#define snd_timer_id_set_device snd_timer_id_set_device_dylibloader_orig_asound
+#define snd_timer_id_get_device snd_timer_id_get_device_dylibloader_orig_asound
+#define snd_timer_id_set_subdevice snd_timer_id_set_subdevice_dylibloader_orig_asound
+#define snd_timer_id_get_subdevice snd_timer_id_get_subdevice_dylibloader_orig_asound
+#define snd_timer_ginfo_sizeof snd_timer_ginfo_sizeof_dylibloader_orig_asound
+#define snd_timer_ginfo_malloc snd_timer_ginfo_malloc_dylibloader_orig_asound
+#define snd_timer_ginfo_free snd_timer_ginfo_free_dylibloader_orig_asound
+#define snd_timer_ginfo_copy snd_timer_ginfo_copy_dylibloader_orig_asound
+#define snd_timer_ginfo_set_tid snd_timer_ginfo_set_tid_dylibloader_orig_asound
+#define snd_timer_ginfo_get_tid snd_timer_ginfo_get_tid_dylibloader_orig_asound
+#define snd_timer_ginfo_get_flags snd_timer_ginfo_get_flags_dylibloader_orig_asound
+#define snd_timer_ginfo_get_card snd_timer_ginfo_get_card_dylibloader_orig_asound
+#define snd_timer_ginfo_get_id snd_timer_ginfo_get_id_dylibloader_orig_asound
+#define snd_timer_ginfo_get_name snd_timer_ginfo_get_name_dylibloader_orig_asound
+#define snd_timer_ginfo_get_resolution snd_timer_ginfo_get_resolution_dylibloader_orig_asound
+#define snd_timer_ginfo_get_resolution_min snd_timer_ginfo_get_resolution_min_dylibloader_orig_asound
+#define snd_timer_ginfo_get_resolution_max snd_timer_ginfo_get_resolution_max_dylibloader_orig_asound
+#define snd_timer_ginfo_get_clients snd_timer_ginfo_get_clients_dylibloader_orig_asound
+#define snd_timer_info_sizeof snd_timer_info_sizeof_dylibloader_orig_asound
+#define snd_timer_info_malloc snd_timer_info_malloc_dylibloader_orig_asound
+#define snd_timer_info_free snd_timer_info_free_dylibloader_orig_asound
+#define snd_timer_info_copy snd_timer_info_copy_dylibloader_orig_asound
+#define snd_timer_info_is_slave snd_timer_info_is_slave_dylibloader_orig_asound
+#define snd_timer_info_get_card snd_timer_info_get_card_dylibloader_orig_asound
+#define snd_timer_info_get_id snd_timer_info_get_id_dylibloader_orig_asound
+#define snd_timer_info_get_name snd_timer_info_get_name_dylibloader_orig_asound
+#define snd_timer_info_get_resolution snd_timer_info_get_resolution_dylibloader_orig_asound
+#define snd_timer_params_sizeof snd_timer_params_sizeof_dylibloader_orig_asound
+#define snd_timer_params_malloc snd_timer_params_malloc_dylibloader_orig_asound
+#define snd_timer_params_free snd_timer_params_free_dylibloader_orig_asound
+#define snd_timer_params_copy snd_timer_params_copy_dylibloader_orig_asound
+#define snd_timer_params_set_auto_start snd_timer_params_set_auto_start_dylibloader_orig_asound
+#define snd_timer_params_get_auto_start snd_timer_params_get_auto_start_dylibloader_orig_asound
+#define snd_timer_params_set_exclusive snd_timer_params_set_exclusive_dylibloader_orig_asound
+#define snd_timer_params_get_exclusive snd_timer_params_get_exclusive_dylibloader_orig_asound
+#define snd_timer_params_set_early_event snd_timer_params_set_early_event_dylibloader_orig_asound
+#define snd_timer_params_get_early_event snd_timer_params_get_early_event_dylibloader_orig_asound
+#define snd_timer_params_set_ticks snd_timer_params_set_ticks_dylibloader_orig_asound
+#define snd_timer_params_get_ticks snd_timer_params_get_ticks_dylibloader_orig_asound
+#define snd_timer_params_set_queue_size snd_timer_params_set_queue_size_dylibloader_orig_asound
+#define snd_timer_params_get_queue_size snd_timer_params_get_queue_size_dylibloader_orig_asound
+#define snd_timer_params_set_filter snd_timer_params_set_filter_dylibloader_orig_asound
+#define snd_timer_params_get_filter snd_timer_params_get_filter_dylibloader_orig_asound
+#define snd_timer_status_sizeof snd_timer_status_sizeof_dylibloader_orig_asound
+#define snd_timer_status_malloc snd_timer_status_malloc_dylibloader_orig_asound
+#define snd_timer_status_free snd_timer_status_free_dylibloader_orig_asound
+#define snd_timer_status_copy snd_timer_status_copy_dylibloader_orig_asound
+#define snd_timer_status_get_timestamp snd_timer_status_get_timestamp_dylibloader_orig_asound
+#define snd_timer_status_get_resolution snd_timer_status_get_resolution_dylibloader_orig_asound
+#define snd_timer_status_get_lost snd_timer_status_get_lost_dylibloader_orig_asound
+#define snd_timer_status_get_overrun snd_timer_status_get_overrun_dylibloader_orig_asound
+#define snd_timer_status_get_queue snd_timer_status_get_queue_dylibloader_orig_asound
+#define snd_timer_info_get_ticks snd_timer_info_get_ticks_dylibloader_orig_asound
+#define snd_hwdep_open snd_hwdep_open_dylibloader_orig_asound
+#define snd_hwdep_close snd_hwdep_close_dylibloader_orig_asound
+#define snd_hwdep_poll_descriptors snd_hwdep_poll_descriptors_dylibloader_orig_asound
+#define snd_hwdep_poll_descriptors_count snd_hwdep_poll_descriptors_count_dylibloader_orig_asound
+#define snd_hwdep_poll_descriptors_revents snd_hwdep_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_hwdep_nonblock snd_hwdep_nonblock_dylibloader_orig_asound
+#define snd_hwdep_info snd_hwdep_info_dylibloader_orig_asound
+#define snd_hwdep_dsp_status snd_hwdep_dsp_status_dylibloader_orig_asound
+#define snd_hwdep_dsp_load snd_hwdep_dsp_load_dylibloader_orig_asound
+#define snd_hwdep_ioctl snd_hwdep_ioctl_dylibloader_orig_asound
+#define snd_hwdep_write snd_hwdep_write_dylibloader_orig_asound
+#define snd_hwdep_read snd_hwdep_read_dylibloader_orig_asound
+#define snd_hwdep_info_sizeof snd_hwdep_info_sizeof_dylibloader_orig_asound
+#define snd_hwdep_info_malloc snd_hwdep_info_malloc_dylibloader_orig_asound
+#define snd_hwdep_info_free snd_hwdep_info_free_dylibloader_orig_asound
+#define snd_hwdep_info_copy snd_hwdep_info_copy_dylibloader_orig_asound
+#define snd_hwdep_info_get_device snd_hwdep_info_get_device_dylibloader_orig_asound
+#define snd_hwdep_info_get_card snd_hwdep_info_get_card_dylibloader_orig_asound
+#define snd_hwdep_info_get_id snd_hwdep_info_get_id_dylibloader_orig_asound
+#define snd_hwdep_info_get_name snd_hwdep_info_get_name_dylibloader_orig_asound
+#define snd_hwdep_info_get_iface snd_hwdep_info_get_iface_dylibloader_orig_asound
+#define snd_hwdep_info_set_device snd_hwdep_info_set_device_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_sizeof snd_hwdep_dsp_status_sizeof_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_malloc snd_hwdep_dsp_status_malloc_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_free snd_hwdep_dsp_status_free_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_copy snd_hwdep_dsp_status_copy_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_version snd_hwdep_dsp_status_get_version_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_id snd_hwdep_dsp_status_get_id_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_num_dsps snd_hwdep_dsp_status_get_num_dsps_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_dsp_loaded snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_orig_asound
+#define snd_hwdep_dsp_status_get_chip_ready snd_hwdep_dsp_status_get_chip_ready_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_sizeof snd_hwdep_dsp_image_sizeof_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_malloc snd_hwdep_dsp_image_malloc_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_free snd_hwdep_dsp_image_free_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_copy snd_hwdep_dsp_image_copy_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_get_index snd_hwdep_dsp_image_get_index_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_get_name snd_hwdep_dsp_image_get_name_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_get_image snd_hwdep_dsp_image_get_image_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_get_length snd_hwdep_dsp_image_get_length_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_set_index snd_hwdep_dsp_image_set_index_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_set_name snd_hwdep_dsp_image_set_name_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_set_image snd_hwdep_dsp_image_set_image_dylibloader_orig_asound
+#define snd_hwdep_dsp_image_set_length snd_hwdep_dsp_image_set_length_dylibloader_orig_asound
+#define snd_card_load snd_card_load_dylibloader_orig_asound
+#define snd_card_next snd_card_next_dylibloader_orig_asound
+#define snd_card_get_index snd_card_get_index_dylibloader_orig_asound
+#define snd_card_get_name snd_card_get_name_dylibloader_orig_asound
+#define snd_card_get_longname snd_card_get_longname_dylibloader_orig_asound
+#define snd_device_name_hint snd_device_name_hint_dylibloader_orig_asound
+#define snd_device_name_free_hint snd_device_name_free_hint_dylibloader_orig_asound
+#define snd_device_name_get_hint snd_device_name_get_hint_dylibloader_orig_asound
+#define snd_ctl_open snd_ctl_open_dylibloader_orig_asound
+#define snd_ctl_open_lconf snd_ctl_open_lconf_dylibloader_orig_asound
+#define snd_ctl_open_fallback snd_ctl_open_fallback_dylibloader_orig_asound
+#define snd_ctl_close snd_ctl_close_dylibloader_orig_asound
+#define snd_ctl_nonblock snd_ctl_nonblock_dylibloader_orig_asound
+#define snd_async_add_ctl_handler snd_async_add_ctl_handler_dylibloader_orig_asound
+#define snd_async_handler_get_ctl snd_async_handler_get_ctl_dylibloader_orig_asound
+#define snd_ctl_poll_descriptors_count snd_ctl_poll_descriptors_count_dylibloader_orig_asound
+#define snd_ctl_poll_descriptors snd_ctl_poll_descriptors_dylibloader_orig_asound
+#define snd_ctl_poll_descriptors_revents snd_ctl_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_ctl_subscribe_events snd_ctl_subscribe_events_dylibloader_orig_asound
+#define snd_ctl_card_info snd_ctl_card_info_dylibloader_orig_asound
+#define snd_ctl_elem_list snd_ctl_elem_list_dylibloader_orig_asound
+#define snd_ctl_elem_info snd_ctl_elem_info_dylibloader_orig_asound
+#define snd_ctl_elem_read snd_ctl_elem_read_dylibloader_orig_asound
+#define snd_ctl_elem_write snd_ctl_elem_write_dylibloader_orig_asound
+#define snd_ctl_elem_lock snd_ctl_elem_lock_dylibloader_orig_asound
+#define snd_ctl_elem_unlock snd_ctl_elem_unlock_dylibloader_orig_asound
+#define snd_ctl_elem_tlv_read snd_ctl_elem_tlv_read_dylibloader_orig_asound
+#define snd_ctl_elem_tlv_write snd_ctl_elem_tlv_write_dylibloader_orig_asound
+#define snd_ctl_elem_tlv_command snd_ctl_elem_tlv_command_dylibloader_orig_asound
+#define snd_ctl_hwdep_next_device snd_ctl_hwdep_next_device_dylibloader_orig_asound
+#define snd_ctl_hwdep_info snd_ctl_hwdep_info_dylibloader_orig_asound
+#define snd_ctl_pcm_next_device snd_ctl_pcm_next_device_dylibloader_orig_asound
+#define snd_ctl_pcm_info snd_ctl_pcm_info_dylibloader_orig_asound
+#define snd_ctl_pcm_prefer_subdevice snd_ctl_pcm_prefer_subdevice_dylibloader_orig_asound
+#define snd_ctl_rawmidi_next_device snd_ctl_rawmidi_next_device_dylibloader_orig_asound
+#define snd_ctl_rawmidi_info snd_ctl_rawmidi_info_dylibloader_orig_asound
+#define snd_ctl_rawmidi_prefer_subdevice snd_ctl_rawmidi_prefer_subdevice_dylibloader_orig_asound
+#define snd_ctl_set_power_state snd_ctl_set_power_state_dylibloader_orig_asound
+#define snd_ctl_get_power_state snd_ctl_get_power_state_dylibloader_orig_asound
+#define snd_ctl_read snd_ctl_read_dylibloader_orig_asound
+#define snd_ctl_wait snd_ctl_wait_dylibloader_orig_asound
+#define snd_ctl_name snd_ctl_name_dylibloader_orig_asound
+#define snd_ctl_type snd_ctl_type_dylibloader_orig_asound
+#define snd_ctl_elem_type_name snd_ctl_elem_type_name_dylibloader_orig_asound
+#define snd_ctl_elem_iface_name snd_ctl_elem_iface_name_dylibloader_orig_asound
+#define snd_ctl_event_type_name snd_ctl_event_type_name_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_mask snd_ctl_event_elem_get_mask_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_numid snd_ctl_event_elem_get_numid_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_id snd_ctl_event_elem_get_id_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_interface snd_ctl_event_elem_get_interface_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_device snd_ctl_event_elem_get_device_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_subdevice snd_ctl_event_elem_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_name snd_ctl_event_elem_get_name_dylibloader_orig_asound
+#define snd_ctl_event_elem_get_index snd_ctl_event_elem_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_list_alloc_space snd_ctl_elem_list_alloc_space_dylibloader_orig_asound
+#define snd_ctl_elem_list_free_space snd_ctl_elem_list_free_space_dylibloader_orig_asound
+#define snd_ctl_ascii_elem_id_get snd_ctl_ascii_elem_id_get_dylibloader_orig_asound
+#define snd_ctl_ascii_elem_id_parse snd_ctl_ascii_elem_id_parse_dylibloader_orig_asound
+#define snd_ctl_ascii_value_parse snd_ctl_ascii_value_parse_dylibloader_orig_asound
+#define snd_ctl_elem_id_sizeof snd_ctl_elem_id_sizeof_dylibloader_orig_asound
+#define snd_ctl_elem_id_malloc snd_ctl_elem_id_malloc_dylibloader_orig_asound
+#define snd_ctl_elem_id_free snd_ctl_elem_id_free_dylibloader_orig_asound
+#define snd_ctl_elem_id_clear snd_ctl_elem_id_clear_dylibloader_orig_asound
+#define snd_ctl_elem_id_copy snd_ctl_elem_id_copy_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_numid snd_ctl_elem_id_get_numid_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_interface snd_ctl_elem_id_get_interface_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_device snd_ctl_elem_id_get_device_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_subdevice snd_ctl_elem_id_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_name snd_ctl_elem_id_get_name_dylibloader_orig_asound
+#define snd_ctl_elem_id_get_index snd_ctl_elem_id_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_numid snd_ctl_elem_id_set_numid_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_interface snd_ctl_elem_id_set_interface_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_device snd_ctl_elem_id_set_device_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_subdevice snd_ctl_elem_id_set_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_name snd_ctl_elem_id_set_name_dylibloader_orig_asound
+#define snd_ctl_elem_id_set_index snd_ctl_elem_id_set_index_dylibloader_orig_asound
+#define snd_ctl_card_info_sizeof snd_ctl_card_info_sizeof_dylibloader_orig_asound
+#define snd_ctl_card_info_malloc snd_ctl_card_info_malloc_dylibloader_orig_asound
+#define snd_ctl_card_info_free snd_ctl_card_info_free_dylibloader_orig_asound
+#define snd_ctl_card_info_clear snd_ctl_card_info_clear_dylibloader_orig_asound
+#define snd_ctl_card_info_copy snd_ctl_card_info_copy_dylibloader_orig_asound
+#define snd_ctl_card_info_get_card snd_ctl_card_info_get_card_dylibloader_orig_asound
+#define snd_ctl_card_info_get_id snd_ctl_card_info_get_id_dylibloader_orig_asound
+#define snd_ctl_card_info_get_driver snd_ctl_card_info_get_driver_dylibloader_orig_asound
+#define snd_ctl_card_info_get_name snd_ctl_card_info_get_name_dylibloader_orig_asound
+#define snd_ctl_card_info_get_longname snd_ctl_card_info_get_longname_dylibloader_orig_asound
+#define snd_ctl_card_info_get_mixername snd_ctl_card_info_get_mixername_dylibloader_orig_asound
+#define snd_ctl_card_info_get_components snd_ctl_card_info_get_components_dylibloader_orig_asound
+#define snd_ctl_event_sizeof snd_ctl_event_sizeof_dylibloader_orig_asound
+#define snd_ctl_event_malloc snd_ctl_event_malloc_dylibloader_orig_asound
+#define snd_ctl_event_free snd_ctl_event_free_dylibloader_orig_asound
+#define snd_ctl_event_clear snd_ctl_event_clear_dylibloader_orig_asound
+#define snd_ctl_event_copy snd_ctl_event_copy_dylibloader_orig_asound
+#define snd_ctl_event_get_type snd_ctl_event_get_type_dylibloader_orig_asound
+#define snd_ctl_elem_list_sizeof snd_ctl_elem_list_sizeof_dylibloader_orig_asound
+#define snd_ctl_elem_list_malloc snd_ctl_elem_list_malloc_dylibloader_orig_asound
+#define snd_ctl_elem_list_free snd_ctl_elem_list_free_dylibloader_orig_asound
+#define snd_ctl_elem_list_clear snd_ctl_elem_list_clear_dylibloader_orig_asound
+#define snd_ctl_elem_list_copy snd_ctl_elem_list_copy_dylibloader_orig_asound
+#define snd_ctl_elem_list_set_offset snd_ctl_elem_list_set_offset_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_used snd_ctl_elem_list_get_used_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_count snd_ctl_elem_list_get_count_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_id snd_ctl_elem_list_get_id_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_numid snd_ctl_elem_list_get_numid_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_interface snd_ctl_elem_list_get_interface_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_device snd_ctl_elem_list_get_device_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_subdevice snd_ctl_elem_list_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_name snd_ctl_elem_list_get_name_dylibloader_orig_asound
+#define snd_ctl_elem_list_get_index snd_ctl_elem_list_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_info_sizeof snd_ctl_elem_info_sizeof_dylibloader_orig_asound
+#define snd_ctl_elem_info_malloc snd_ctl_elem_info_malloc_dylibloader_orig_asound
+#define snd_ctl_elem_info_free snd_ctl_elem_info_free_dylibloader_orig_asound
+#define snd_ctl_elem_info_clear snd_ctl_elem_info_clear_dylibloader_orig_asound
+#define snd_ctl_elem_info_copy snd_ctl_elem_info_copy_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_type snd_ctl_elem_info_get_type_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_readable snd_ctl_elem_info_is_readable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_writable snd_ctl_elem_info_is_writable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_volatile snd_ctl_elem_info_is_volatile_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_inactive snd_ctl_elem_info_is_inactive_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_locked snd_ctl_elem_info_is_locked_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_tlv_readable snd_ctl_elem_info_is_tlv_readable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_tlv_writable snd_ctl_elem_info_is_tlv_writable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_tlv_commandable snd_ctl_elem_info_is_tlv_commandable_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_owner snd_ctl_elem_info_is_owner_dylibloader_orig_asound
+#define snd_ctl_elem_info_is_user snd_ctl_elem_info_is_user_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_owner snd_ctl_elem_info_get_owner_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_count snd_ctl_elem_info_get_count_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_min snd_ctl_elem_info_get_min_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_max snd_ctl_elem_info_get_max_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_step snd_ctl_elem_info_get_step_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_min64 snd_ctl_elem_info_get_min64_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_max64 snd_ctl_elem_info_get_max64_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_step64 snd_ctl_elem_info_get_step64_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_items snd_ctl_elem_info_get_items_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_item snd_ctl_elem_info_set_item_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_item_name snd_ctl_elem_info_get_item_name_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_dimensions snd_ctl_elem_info_get_dimensions_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_dimension snd_ctl_elem_info_get_dimension_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_dimension snd_ctl_elem_info_set_dimension_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_id snd_ctl_elem_info_get_id_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_numid snd_ctl_elem_info_get_numid_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_interface snd_ctl_elem_info_get_interface_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_device snd_ctl_elem_info_get_device_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_subdevice snd_ctl_elem_info_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_name snd_ctl_elem_info_get_name_dylibloader_orig_asound
+#define snd_ctl_elem_info_get_index snd_ctl_elem_info_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_id snd_ctl_elem_info_set_id_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_numid snd_ctl_elem_info_set_numid_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_interface snd_ctl_elem_info_set_interface_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_device snd_ctl_elem_info_set_device_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_subdevice snd_ctl_elem_info_set_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_name snd_ctl_elem_info_set_name_dylibloader_orig_asound
+#define snd_ctl_elem_info_set_index snd_ctl_elem_info_set_index_dylibloader_orig_asound
+#define snd_ctl_add_integer_elem_set snd_ctl_add_integer_elem_set_dylibloader_orig_asound
+#define snd_ctl_add_integer64_elem_set snd_ctl_add_integer64_elem_set_dylibloader_orig_asound
+#define snd_ctl_add_boolean_elem_set snd_ctl_add_boolean_elem_set_dylibloader_orig_asound
+#define snd_ctl_add_enumerated_elem_set snd_ctl_add_enumerated_elem_set_dylibloader_orig_asound
+#define snd_ctl_add_bytes_elem_set snd_ctl_add_bytes_elem_set_dylibloader_orig_asound
+#define snd_ctl_elem_add_integer snd_ctl_elem_add_integer_dylibloader_orig_asound
+#define snd_ctl_elem_add_integer64 snd_ctl_elem_add_integer64_dylibloader_orig_asound
+#define snd_ctl_elem_add_boolean snd_ctl_elem_add_boolean_dylibloader_orig_asound
+#define snd_ctl_elem_add_enumerated snd_ctl_elem_add_enumerated_dylibloader_orig_asound
+#define snd_ctl_elem_add_iec958 snd_ctl_elem_add_iec958_dylibloader_orig_asound
+#define snd_ctl_elem_remove snd_ctl_elem_remove_dylibloader_orig_asound
+#define snd_ctl_elem_value_sizeof snd_ctl_elem_value_sizeof_dylibloader_orig_asound
+#define snd_ctl_elem_value_malloc snd_ctl_elem_value_malloc_dylibloader_orig_asound
+#define snd_ctl_elem_value_free snd_ctl_elem_value_free_dylibloader_orig_asound
+#define snd_ctl_elem_value_clear snd_ctl_elem_value_clear_dylibloader_orig_asound
+#define snd_ctl_elem_value_copy snd_ctl_elem_value_copy_dylibloader_orig_asound
+#define snd_ctl_elem_value_compare snd_ctl_elem_value_compare_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_id snd_ctl_elem_value_get_id_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_numid snd_ctl_elem_value_get_numid_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_interface snd_ctl_elem_value_get_interface_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_device snd_ctl_elem_value_get_device_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_subdevice snd_ctl_elem_value_get_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_name snd_ctl_elem_value_get_name_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_index snd_ctl_elem_value_get_index_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_id snd_ctl_elem_value_set_id_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_numid snd_ctl_elem_value_set_numid_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_interface snd_ctl_elem_value_set_interface_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_device snd_ctl_elem_value_set_device_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_subdevice snd_ctl_elem_value_set_subdevice_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_name snd_ctl_elem_value_set_name_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_index snd_ctl_elem_value_set_index_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_boolean snd_ctl_elem_value_get_boolean_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_integer snd_ctl_elem_value_get_integer_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_integer64 snd_ctl_elem_value_get_integer64_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_enumerated snd_ctl_elem_value_get_enumerated_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_byte snd_ctl_elem_value_get_byte_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_boolean snd_ctl_elem_value_set_boolean_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_integer snd_ctl_elem_value_set_integer_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_integer64 snd_ctl_elem_value_set_integer64_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_enumerated snd_ctl_elem_value_set_enumerated_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_byte snd_ctl_elem_value_set_byte_dylibloader_orig_asound
+#define snd_ctl_elem_set_bytes snd_ctl_elem_set_bytes_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_bytes snd_ctl_elem_value_get_bytes_dylibloader_orig_asound
+#define snd_ctl_elem_value_get_iec958 snd_ctl_elem_value_get_iec958_dylibloader_orig_asound
+#define snd_ctl_elem_value_set_iec958 snd_ctl_elem_value_set_iec958_dylibloader_orig_asound
+#define snd_tlv_parse_dB_info snd_tlv_parse_dB_info_dylibloader_orig_asound
+#define snd_tlv_get_dB_range snd_tlv_get_dB_range_dylibloader_orig_asound
+#define snd_tlv_convert_to_dB snd_tlv_convert_to_dB_dylibloader_orig_asound
+#define snd_tlv_convert_from_dB snd_tlv_convert_from_dB_dylibloader_orig_asound
+#define snd_ctl_get_dB_range snd_ctl_get_dB_range_dylibloader_orig_asound
+#define snd_ctl_convert_to_dB snd_ctl_convert_to_dB_dylibloader_orig_asound
+#define snd_ctl_convert_from_dB snd_ctl_convert_from_dB_dylibloader_orig_asound
+#define snd_hctl_compare_fast snd_hctl_compare_fast_dylibloader_orig_asound
+#define snd_hctl_open snd_hctl_open_dylibloader_orig_asound
+#define snd_hctl_open_ctl snd_hctl_open_ctl_dylibloader_orig_asound
+#define snd_hctl_close snd_hctl_close_dylibloader_orig_asound
+#define snd_hctl_nonblock snd_hctl_nonblock_dylibloader_orig_asound
+#define snd_hctl_poll_descriptors_count snd_hctl_poll_descriptors_count_dylibloader_orig_asound
+#define snd_hctl_poll_descriptors snd_hctl_poll_descriptors_dylibloader_orig_asound
+#define snd_hctl_poll_descriptors_revents snd_hctl_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_hctl_get_count snd_hctl_get_count_dylibloader_orig_asound
+#define snd_hctl_set_compare snd_hctl_set_compare_dylibloader_orig_asound
+#define snd_hctl_first_elem snd_hctl_first_elem_dylibloader_orig_asound
+#define snd_hctl_last_elem snd_hctl_last_elem_dylibloader_orig_asound
+#define snd_hctl_find_elem snd_hctl_find_elem_dylibloader_orig_asound
+#define snd_hctl_set_callback snd_hctl_set_callback_dylibloader_orig_asound
+#define snd_hctl_set_callback_private snd_hctl_set_callback_private_dylibloader_orig_asound
+#define snd_hctl_get_callback_private snd_hctl_get_callback_private_dylibloader_orig_asound
+#define snd_hctl_load snd_hctl_load_dylibloader_orig_asound
+#define snd_hctl_free snd_hctl_free_dylibloader_orig_asound
+#define snd_hctl_handle_events snd_hctl_handle_events_dylibloader_orig_asound
+#define snd_hctl_name snd_hctl_name_dylibloader_orig_asound
+#define snd_hctl_wait snd_hctl_wait_dylibloader_orig_asound
+#define snd_hctl_ctl snd_hctl_ctl_dylibloader_orig_asound
+#define snd_hctl_elem_next snd_hctl_elem_next_dylibloader_orig_asound
+#define snd_hctl_elem_prev snd_hctl_elem_prev_dylibloader_orig_asound
+#define snd_hctl_elem_info snd_hctl_elem_info_dylibloader_orig_asound
+#define snd_hctl_elem_read snd_hctl_elem_read_dylibloader_orig_asound
+#define snd_hctl_elem_write snd_hctl_elem_write_dylibloader_orig_asound
+#define snd_hctl_elem_tlv_read snd_hctl_elem_tlv_read_dylibloader_orig_asound
+#define snd_hctl_elem_tlv_write snd_hctl_elem_tlv_write_dylibloader_orig_asound
+#define snd_hctl_elem_tlv_command snd_hctl_elem_tlv_command_dylibloader_orig_asound
+#define snd_hctl_elem_get_hctl snd_hctl_elem_get_hctl_dylibloader_orig_asound
+#define snd_hctl_elem_get_id snd_hctl_elem_get_id_dylibloader_orig_asound
+#define snd_hctl_elem_get_numid snd_hctl_elem_get_numid_dylibloader_orig_asound
+#define snd_hctl_elem_get_interface snd_hctl_elem_get_interface_dylibloader_orig_asound
+#define snd_hctl_elem_get_device snd_hctl_elem_get_device_dylibloader_orig_asound
+#define snd_hctl_elem_get_subdevice snd_hctl_elem_get_subdevice_dylibloader_orig_asound
+#define snd_hctl_elem_get_name snd_hctl_elem_get_name_dylibloader_orig_asound
+#define snd_hctl_elem_get_index snd_hctl_elem_get_index_dylibloader_orig_asound
+#define snd_hctl_elem_set_callback snd_hctl_elem_set_callback_dylibloader_orig_asound
+#define snd_hctl_elem_get_callback_private snd_hctl_elem_get_callback_private_dylibloader_orig_asound
+#define snd_hctl_elem_set_callback_private snd_hctl_elem_set_callback_private_dylibloader_orig_asound
+#define snd_sctl_build snd_sctl_build_dylibloader_orig_asound
+#define snd_sctl_free snd_sctl_free_dylibloader_orig_asound
+#define snd_sctl_install snd_sctl_install_dylibloader_orig_asound
+#define snd_sctl_remove snd_sctl_remove_dylibloader_orig_asound
+#define snd_mixer_open snd_mixer_open_dylibloader_orig_asound
+#define snd_mixer_close snd_mixer_close_dylibloader_orig_asound
+#define snd_mixer_first_elem snd_mixer_first_elem_dylibloader_orig_asound
+#define snd_mixer_last_elem snd_mixer_last_elem_dylibloader_orig_asound
+#define snd_mixer_handle_events snd_mixer_handle_events_dylibloader_orig_asound
+#define snd_mixer_attach snd_mixer_attach_dylibloader_orig_asound
+#define snd_mixer_attach_hctl snd_mixer_attach_hctl_dylibloader_orig_asound
+#define snd_mixer_detach snd_mixer_detach_dylibloader_orig_asound
+#define snd_mixer_detach_hctl snd_mixer_detach_hctl_dylibloader_orig_asound
+#define snd_mixer_get_hctl snd_mixer_get_hctl_dylibloader_orig_asound
+#define snd_mixer_poll_descriptors_count snd_mixer_poll_descriptors_count_dylibloader_orig_asound
+#define snd_mixer_poll_descriptors snd_mixer_poll_descriptors_dylibloader_orig_asound
+#define snd_mixer_poll_descriptors_revents snd_mixer_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_mixer_load snd_mixer_load_dylibloader_orig_asound
+#define snd_mixer_free snd_mixer_free_dylibloader_orig_asound
+#define snd_mixer_wait snd_mixer_wait_dylibloader_orig_asound
+#define snd_mixer_set_compare snd_mixer_set_compare_dylibloader_orig_asound
+#define snd_mixer_set_callback snd_mixer_set_callback_dylibloader_orig_asound
+#define snd_mixer_get_callback_private snd_mixer_get_callback_private_dylibloader_orig_asound
+#define snd_mixer_set_callback_private snd_mixer_set_callback_private_dylibloader_orig_asound
+#define snd_mixer_get_count snd_mixer_get_count_dylibloader_orig_asound
+#define snd_mixer_class_unregister snd_mixer_class_unregister_dylibloader_orig_asound
+#define snd_mixer_elem_next snd_mixer_elem_next_dylibloader_orig_asound
+#define snd_mixer_elem_prev snd_mixer_elem_prev_dylibloader_orig_asound
+#define snd_mixer_elem_set_callback snd_mixer_elem_set_callback_dylibloader_orig_asound
+#define snd_mixer_elem_get_callback_private snd_mixer_elem_get_callback_private_dylibloader_orig_asound
+#define snd_mixer_elem_set_callback_private snd_mixer_elem_set_callback_private_dylibloader_orig_asound
+#define snd_mixer_elem_get_type snd_mixer_elem_get_type_dylibloader_orig_asound
+#define snd_mixer_class_register snd_mixer_class_register_dylibloader_orig_asound
+#define snd_mixer_elem_new snd_mixer_elem_new_dylibloader_orig_asound
+#define snd_mixer_elem_add snd_mixer_elem_add_dylibloader_orig_asound
+#define snd_mixer_elem_remove snd_mixer_elem_remove_dylibloader_orig_asound
+#define snd_mixer_elem_free snd_mixer_elem_free_dylibloader_orig_asound
+#define snd_mixer_elem_info snd_mixer_elem_info_dylibloader_orig_asound
+#define snd_mixer_elem_value snd_mixer_elem_value_dylibloader_orig_asound
+#define snd_mixer_elem_attach snd_mixer_elem_attach_dylibloader_orig_asound
+#define snd_mixer_elem_detach snd_mixer_elem_detach_dylibloader_orig_asound
+#define snd_mixer_elem_empty snd_mixer_elem_empty_dylibloader_orig_asound
+#define snd_mixer_elem_get_private snd_mixer_elem_get_private_dylibloader_orig_asound
+#define snd_mixer_class_sizeof snd_mixer_class_sizeof_dylibloader_orig_asound
+#define snd_mixer_class_malloc snd_mixer_class_malloc_dylibloader_orig_asound
+#define snd_mixer_class_free snd_mixer_class_free_dylibloader_orig_asound
+#define snd_mixer_class_copy snd_mixer_class_copy_dylibloader_orig_asound
+#define snd_mixer_class_get_mixer snd_mixer_class_get_mixer_dylibloader_orig_asound
+#define snd_mixer_class_get_event snd_mixer_class_get_event_dylibloader_orig_asound
+#define snd_mixer_class_get_private snd_mixer_class_get_private_dylibloader_orig_asound
+#define snd_mixer_class_get_compare snd_mixer_class_get_compare_dylibloader_orig_asound
+#define snd_mixer_class_set_event snd_mixer_class_set_event_dylibloader_orig_asound
+#define snd_mixer_class_set_private snd_mixer_class_set_private_dylibloader_orig_asound
+#define snd_mixer_class_set_private_free snd_mixer_class_set_private_free_dylibloader_orig_asound
+#define snd_mixer_class_set_compare snd_mixer_class_set_compare_dylibloader_orig_asound
+#define snd_mixer_selem_channel_name snd_mixer_selem_channel_name_dylibloader_orig_asound
+#define snd_mixer_selem_register snd_mixer_selem_register_dylibloader_orig_asound
+#define snd_mixer_selem_get_id snd_mixer_selem_get_id_dylibloader_orig_asound
+#define snd_mixer_selem_get_name snd_mixer_selem_get_name_dylibloader_orig_asound
+#define snd_mixer_selem_get_index snd_mixer_selem_get_index_dylibloader_orig_asound
+#define snd_mixer_find_selem snd_mixer_find_selem_dylibloader_orig_asound
+#define snd_mixer_selem_is_active snd_mixer_selem_is_active_dylibloader_orig_asound
+#define snd_mixer_selem_is_playback_mono snd_mixer_selem_is_playback_mono_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_channel snd_mixer_selem_has_playback_channel_dylibloader_orig_asound
+#define snd_mixer_selem_is_capture_mono snd_mixer_selem_is_capture_mono_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_channel snd_mixer_selem_has_capture_channel_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_group snd_mixer_selem_get_capture_group_dylibloader_orig_asound
+#define snd_mixer_selem_has_common_volume snd_mixer_selem_has_common_volume_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_volume snd_mixer_selem_has_playback_volume_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_volume_joined snd_mixer_selem_has_playback_volume_joined_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_volume snd_mixer_selem_has_capture_volume_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_volume_joined snd_mixer_selem_has_capture_volume_joined_dylibloader_orig_asound
+#define snd_mixer_selem_has_common_switch snd_mixer_selem_has_common_switch_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_switch snd_mixer_selem_has_playback_switch_dylibloader_orig_asound
+#define snd_mixer_selem_has_playback_switch_joined snd_mixer_selem_has_playback_switch_joined_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_switch snd_mixer_selem_has_capture_switch_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_switch_joined snd_mixer_selem_has_capture_switch_joined_dylibloader_orig_asound
+#define snd_mixer_selem_has_capture_switch_exclusive snd_mixer_selem_has_capture_switch_exclusive_dylibloader_orig_asound
+#define snd_mixer_selem_ask_playback_vol_dB snd_mixer_selem_ask_playback_vol_dB_dylibloader_orig_asound
+#define snd_mixer_selem_ask_capture_vol_dB snd_mixer_selem_ask_capture_vol_dB_dylibloader_orig_asound
+#define snd_mixer_selem_ask_playback_dB_vol snd_mixer_selem_ask_playback_dB_vol_dylibloader_orig_asound
+#define snd_mixer_selem_ask_capture_dB_vol snd_mixer_selem_ask_capture_dB_vol_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_volume snd_mixer_selem_get_playback_volume_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_volume snd_mixer_selem_get_capture_volume_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_dB snd_mixer_selem_get_playback_dB_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_dB snd_mixer_selem_get_capture_dB_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_switch snd_mixer_selem_get_playback_switch_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_switch snd_mixer_selem_get_capture_switch_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_volume snd_mixer_selem_set_playback_volume_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_volume snd_mixer_selem_set_capture_volume_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_dB snd_mixer_selem_set_playback_dB_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_dB snd_mixer_selem_set_capture_dB_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_volume_all snd_mixer_selem_set_playback_volume_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_volume_all snd_mixer_selem_set_capture_volume_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_dB_all snd_mixer_selem_set_playback_dB_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_dB_all snd_mixer_selem_set_capture_dB_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_switch snd_mixer_selem_set_playback_switch_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_switch snd_mixer_selem_set_capture_switch_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_switch_all snd_mixer_selem_set_playback_switch_all_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_switch_all snd_mixer_selem_set_capture_switch_all_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_volume_range snd_mixer_selem_get_playback_volume_range_dylibloader_orig_asound
+#define snd_mixer_selem_get_playback_dB_range snd_mixer_selem_get_playback_dB_range_dylibloader_orig_asound
+#define snd_mixer_selem_set_playback_volume_range snd_mixer_selem_set_playback_volume_range_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_volume_range snd_mixer_selem_get_capture_volume_range_dylibloader_orig_asound
+#define snd_mixer_selem_get_capture_dB_range snd_mixer_selem_get_capture_dB_range_dylibloader_orig_asound
+#define snd_mixer_selem_set_capture_volume_range snd_mixer_selem_set_capture_volume_range_dylibloader_orig_asound
+#define snd_mixer_selem_is_enumerated snd_mixer_selem_is_enumerated_dylibloader_orig_asound
+#define snd_mixer_selem_is_enum_playback snd_mixer_selem_is_enum_playback_dylibloader_orig_asound
+#define snd_mixer_selem_is_enum_capture snd_mixer_selem_is_enum_capture_dylibloader_orig_asound
+#define snd_mixer_selem_get_enum_items snd_mixer_selem_get_enum_items_dylibloader_orig_asound
+#define snd_mixer_selem_get_enum_item_name snd_mixer_selem_get_enum_item_name_dylibloader_orig_asound
+#define snd_mixer_selem_get_enum_item snd_mixer_selem_get_enum_item_dylibloader_orig_asound
+#define snd_mixer_selem_set_enum_item snd_mixer_selem_set_enum_item_dylibloader_orig_asound
+#define snd_mixer_selem_id_sizeof snd_mixer_selem_id_sizeof_dylibloader_orig_asound
+#define snd_mixer_selem_id_malloc snd_mixer_selem_id_malloc_dylibloader_orig_asound
+#define snd_mixer_selem_id_free snd_mixer_selem_id_free_dylibloader_orig_asound
+#define snd_mixer_selem_id_copy snd_mixer_selem_id_copy_dylibloader_orig_asound
+#define snd_mixer_selem_id_get_name snd_mixer_selem_id_get_name_dylibloader_orig_asound
+#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_orig_asound
+#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_orig_asound
+#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_orig_asound
+#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_orig_asound
+#define snd_seq_open snd_seq_open_dylibloader_orig_asound
+#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_orig_asound
+#define snd_seq_name snd_seq_name_dylibloader_orig_asound
+#define snd_seq_type snd_seq_type_dylibloader_orig_asound
+#define snd_seq_close snd_seq_close_dylibloader_orig_asound
+#define snd_seq_poll_descriptors_count snd_seq_poll_descriptors_count_dylibloader_orig_asound
+#define snd_seq_poll_descriptors snd_seq_poll_descriptors_dylibloader_orig_asound
+#define snd_seq_poll_descriptors_revents snd_seq_poll_descriptors_revents_dylibloader_orig_asound
+#define snd_seq_nonblock snd_seq_nonblock_dylibloader_orig_asound
+#define snd_seq_client_id snd_seq_client_id_dylibloader_orig_asound
+#define snd_seq_get_output_buffer_size snd_seq_get_output_buffer_size_dylibloader_orig_asound
+#define snd_seq_get_input_buffer_size snd_seq_get_input_buffer_size_dylibloader_orig_asound
+#define snd_seq_set_output_buffer_size snd_seq_set_output_buffer_size_dylibloader_orig_asound
+#define snd_seq_set_input_buffer_size snd_seq_set_input_buffer_size_dylibloader_orig_asound
+#define snd_seq_system_info_sizeof snd_seq_system_info_sizeof_dylibloader_orig_asound
+#define snd_seq_system_info_malloc snd_seq_system_info_malloc_dylibloader_orig_asound
+#define snd_seq_system_info_free snd_seq_system_info_free_dylibloader_orig_asound
+#define snd_seq_system_info_copy snd_seq_system_info_copy_dylibloader_orig_asound
+#define snd_seq_system_info_get_queues snd_seq_system_info_get_queues_dylibloader_orig_asound
+#define snd_seq_system_info_get_clients snd_seq_system_info_get_clients_dylibloader_orig_asound
+#define snd_seq_system_info_get_ports snd_seq_system_info_get_ports_dylibloader_orig_asound
+#define snd_seq_system_info_get_channels snd_seq_system_info_get_channels_dylibloader_orig_asound
+#define snd_seq_system_info_get_cur_clients snd_seq_system_info_get_cur_clients_dylibloader_orig_asound
+#define snd_seq_system_info_get_cur_queues snd_seq_system_info_get_cur_queues_dylibloader_orig_asound
+#define snd_seq_system_info snd_seq_system_info_dylibloader_orig_asound
+#define snd_seq_client_info_sizeof snd_seq_client_info_sizeof_dylibloader_orig_asound
+#define snd_seq_client_info_malloc snd_seq_client_info_malloc_dylibloader_orig_asound
+#define snd_seq_client_info_free snd_seq_client_info_free_dylibloader_orig_asound
+#define snd_seq_client_info_copy snd_seq_client_info_copy_dylibloader_orig_asound
+#define snd_seq_client_info_get_client snd_seq_client_info_get_client_dylibloader_orig_asound
+#define snd_seq_client_info_get_type snd_seq_client_info_get_type_dylibloader_orig_asound
+#define snd_seq_client_info_get_name snd_seq_client_info_get_name_dylibloader_orig_asound
+#define snd_seq_client_info_get_broadcast_filter snd_seq_client_info_get_broadcast_filter_dylibloader_orig_asound
+#define snd_seq_client_info_get_error_bounce snd_seq_client_info_get_error_bounce_dylibloader_orig_asound
+#define snd_seq_client_info_get_card snd_seq_client_info_get_card_dylibloader_orig_asound
+#define snd_seq_client_info_get_pid snd_seq_client_info_get_pid_dylibloader_orig_asound
+#define snd_seq_client_info_get_event_filter snd_seq_client_info_get_event_filter_dylibloader_orig_asound
+#define snd_seq_client_info_get_num_ports snd_seq_client_info_get_num_ports_dylibloader_orig_asound
+#define snd_seq_client_info_get_event_lost snd_seq_client_info_get_event_lost_dylibloader_orig_asound
+#define snd_seq_client_info_set_client snd_seq_client_info_set_client_dylibloader_orig_asound
+#define snd_seq_client_info_set_name snd_seq_client_info_set_name_dylibloader_orig_asound
+#define snd_seq_client_info_set_broadcast_filter snd_seq_client_info_set_broadcast_filter_dylibloader_orig_asound
+#define snd_seq_client_info_set_error_bounce snd_seq_client_info_set_error_bounce_dylibloader_orig_asound
+#define snd_seq_client_info_set_event_filter snd_seq_client_info_set_event_filter_dylibloader_orig_asound
+#define snd_seq_client_info_event_filter_clear snd_seq_client_info_event_filter_clear_dylibloader_orig_asound
+#define snd_seq_client_info_event_filter_add snd_seq_client_info_event_filter_add_dylibloader_orig_asound
+#define snd_seq_client_info_event_filter_del snd_seq_client_info_event_filter_del_dylibloader_orig_asound
+#define snd_seq_client_info_event_filter_check snd_seq_client_info_event_filter_check_dylibloader_orig_asound
+#define snd_seq_get_client_info snd_seq_get_client_info_dylibloader_orig_asound
+#define snd_seq_get_any_client_info snd_seq_get_any_client_info_dylibloader_orig_asound
+#define snd_seq_set_client_info snd_seq_set_client_info_dylibloader_orig_asound
+#define snd_seq_query_next_client snd_seq_query_next_client_dylibloader_orig_asound
+#define snd_seq_client_pool_sizeof snd_seq_client_pool_sizeof_dylibloader_orig_asound
+#define snd_seq_client_pool_malloc snd_seq_client_pool_malloc_dylibloader_orig_asound
+#define snd_seq_client_pool_free snd_seq_client_pool_free_dylibloader_orig_asound
+#define snd_seq_client_pool_copy snd_seq_client_pool_copy_dylibloader_orig_asound
+#define snd_seq_client_pool_get_client snd_seq_client_pool_get_client_dylibloader_orig_asound
+#define snd_seq_client_pool_get_output_pool snd_seq_client_pool_get_output_pool_dylibloader_orig_asound
+#define snd_seq_client_pool_get_input_pool snd_seq_client_pool_get_input_pool_dylibloader_orig_asound
+#define snd_seq_client_pool_get_output_room snd_seq_client_pool_get_output_room_dylibloader_orig_asound
+#define snd_seq_client_pool_get_output_free snd_seq_client_pool_get_output_free_dylibloader_orig_asound
+#define snd_seq_client_pool_get_input_free snd_seq_client_pool_get_input_free_dylibloader_orig_asound
+#define snd_seq_client_pool_set_output_pool snd_seq_client_pool_set_output_pool_dylibloader_orig_asound
+#define snd_seq_client_pool_set_input_pool snd_seq_client_pool_set_input_pool_dylibloader_orig_asound
+#define snd_seq_client_pool_set_output_room snd_seq_client_pool_set_output_room_dylibloader_orig_asound
+#define snd_seq_get_client_pool snd_seq_get_client_pool_dylibloader_orig_asound
+#define snd_seq_set_client_pool snd_seq_set_client_pool_dylibloader_orig_asound
+#define snd_seq_port_info_sizeof snd_seq_port_info_sizeof_dylibloader_orig_asound
+#define snd_seq_port_info_malloc snd_seq_port_info_malloc_dylibloader_orig_asound
+#define snd_seq_port_info_free snd_seq_port_info_free_dylibloader_orig_asound
+#define snd_seq_port_info_copy snd_seq_port_info_copy_dylibloader_orig_asound
+#define snd_seq_port_info_get_client snd_seq_port_info_get_client_dylibloader_orig_asound
+#define snd_seq_port_info_get_port snd_seq_port_info_get_port_dylibloader_orig_asound
+#define snd_seq_port_info_get_addr snd_seq_port_info_get_addr_dylibloader_orig_asound
+#define snd_seq_port_info_get_name snd_seq_port_info_get_name_dylibloader_orig_asound
+#define snd_seq_port_info_get_capability snd_seq_port_info_get_capability_dylibloader_orig_asound
+#define snd_seq_port_info_get_type snd_seq_port_info_get_type_dylibloader_orig_asound
+#define snd_seq_port_info_get_midi_channels snd_seq_port_info_get_midi_channels_dylibloader_orig_asound
+#define snd_seq_port_info_get_midi_voices snd_seq_port_info_get_midi_voices_dylibloader_orig_asound
+#define snd_seq_port_info_get_synth_voices snd_seq_port_info_get_synth_voices_dylibloader_orig_asound
+#define snd_seq_port_info_get_read_use snd_seq_port_info_get_read_use_dylibloader_orig_asound
+#define snd_seq_port_info_get_write_use snd_seq_port_info_get_write_use_dylibloader_orig_asound
+#define snd_seq_port_info_get_port_specified snd_seq_port_info_get_port_specified_dylibloader_orig_asound
+#define snd_seq_port_info_get_timestamping snd_seq_port_info_get_timestamping_dylibloader_orig_asound
+#define snd_seq_port_info_get_timestamp_real snd_seq_port_info_get_timestamp_real_dylibloader_orig_asound
+#define snd_seq_port_info_get_timestamp_queue snd_seq_port_info_get_timestamp_queue_dylibloader_orig_asound
+#define snd_seq_port_info_set_client snd_seq_port_info_set_client_dylibloader_orig_asound
+#define snd_seq_port_info_set_port snd_seq_port_info_set_port_dylibloader_orig_asound
+#define snd_seq_port_info_set_addr snd_seq_port_info_set_addr_dylibloader_orig_asound
+#define snd_seq_port_info_set_name snd_seq_port_info_set_name_dylibloader_orig_asound
+#define snd_seq_port_info_set_capability snd_seq_port_info_set_capability_dylibloader_orig_asound
+#define snd_seq_port_info_set_type snd_seq_port_info_set_type_dylibloader_orig_asound
+#define snd_seq_port_info_set_midi_channels snd_seq_port_info_set_midi_channels_dylibloader_orig_asound
+#define snd_seq_port_info_set_midi_voices snd_seq_port_info_set_midi_voices_dylibloader_orig_asound
+#define snd_seq_port_info_set_synth_voices snd_seq_port_info_set_synth_voices_dylibloader_orig_asound
+#define snd_seq_port_info_set_port_specified snd_seq_port_info_set_port_specified_dylibloader_orig_asound
+#define snd_seq_port_info_set_timestamping snd_seq_port_info_set_timestamping_dylibloader_orig_asound
+#define snd_seq_port_info_set_timestamp_real snd_seq_port_info_set_timestamp_real_dylibloader_orig_asound
+#define snd_seq_port_info_set_timestamp_queue snd_seq_port_info_set_timestamp_queue_dylibloader_orig_asound
+#define snd_seq_create_port snd_seq_create_port_dylibloader_orig_asound
+#define snd_seq_delete_port snd_seq_delete_port_dylibloader_orig_asound
+#define snd_seq_get_port_info snd_seq_get_port_info_dylibloader_orig_asound
+#define snd_seq_get_any_port_info snd_seq_get_any_port_info_dylibloader_orig_asound
+#define snd_seq_set_port_info snd_seq_set_port_info_dylibloader_orig_asound
+#define snd_seq_query_next_port snd_seq_query_next_port_dylibloader_orig_asound
+#define snd_seq_port_subscribe_sizeof snd_seq_port_subscribe_sizeof_dylibloader_orig_asound
+#define snd_seq_port_subscribe_malloc snd_seq_port_subscribe_malloc_dylibloader_orig_asound
+#define snd_seq_port_subscribe_free snd_seq_port_subscribe_free_dylibloader_orig_asound
+#define snd_seq_port_subscribe_copy snd_seq_port_subscribe_copy_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_sender snd_seq_port_subscribe_get_sender_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_dest snd_seq_port_subscribe_get_dest_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_queue snd_seq_port_subscribe_get_queue_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_exclusive snd_seq_port_subscribe_get_exclusive_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_time_update snd_seq_port_subscribe_get_time_update_dylibloader_orig_asound
+#define snd_seq_port_subscribe_get_time_real snd_seq_port_subscribe_get_time_real_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_sender snd_seq_port_subscribe_set_sender_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_dest snd_seq_port_subscribe_set_dest_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_queue snd_seq_port_subscribe_set_queue_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_exclusive snd_seq_port_subscribe_set_exclusive_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_time_update snd_seq_port_subscribe_set_time_update_dylibloader_orig_asound
+#define snd_seq_port_subscribe_set_time_real snd_seq_port_subscribe_set_time_real_dylibloader_orig_asound
+#define snd_seq_get_port_subscription snd_seq_get_port_subscription_dylibloader_orig_asound
+#define snd_seq_subscribe_port snd_seq_subscribe_port_dylibloader_orig_asound
+#define snd_seq_unsubscribe_port snd_seq_unsubscribe_port_dylibloader_orig_asound
+#define snd_seq_query_subscribe_sizeof snd_seq_query_subscribe_sizeof_dylibloader_orig_asound
+#define snd_seq_query_subscribe_malloc snd_seq_query_subscribe_malloc_dylibloader_orig_asound
+#define snd_seq_query_subscribe_free snd_seq_query_subscribe_free_dylibloader_orig_asound
+#define snd_seq_query_subscribe_copy snd_seq_query_subscribe_copy_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_client snd_seq_query_subscribe_get_client_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_port snd_seq_query_subscribe_get_port_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_root snd_seq_query_subscribe_get_root_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_type snd_seq_query_subscribe_get_type_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_index snd_seq_query_subscribe_get_index_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_num_subs snd_seq_query_subscribe_get_num_subs_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_addr snd_seq_query_subscribe_get_addr_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_queue snd_seq_query_subscribe_get_queue_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_exclusive snd_seq_query_subscribe_get_exclusive_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_time_update snd_seq_query_subscribe_get_time_update_dylibloader_orig_asound
+#define snd_seq_query_subscribe_get_time_real snd_seq_query_subscribe_get_time_real_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_client snd_seq_query_subscribe_set_client_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_port snd_seq_query_subscribe_set_port_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_root snd_seq_query_subscribe_set_root_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_type snd_seq_query_subscribe_set_type_dylibloader_orig_asound
+#define snd_seq_query_subscribe_set_index snd_seq_query_subscribe_set_index_dylibloader_orig_asound
+#define snd_seq_query_port_subscribers snd_seq_query_port_subscribers_dylibloader_orig_asound
+#define snd_seq_queue_info_sizeof snd_seq_queue_info_sizeof_dylibloader_orig_asound
+#define snd_seq_queue_info_malloc snd_seq_queue_info_malloc_dylibloader_orig_asound
+#define snd_seq_queue_info_free snd_seq_queue_info_free_dylibloader_orig_asound
+#define snd_seq_queue_info_copy snd_seq_queue_info_copy_dylibloader_orig_asound
+#define snd_seq_queue_info_get_queue snd_seq_queue_info_get_queue_dylibloader_orig_asound
+#define snd_seq_queue_info_get_name snd_seq_queue_info_get_name_dylibloader_orig_asound
+#define snd_seq_queue_info_get_owner snd_seq_queue_info_get_owner_dylibloader_orig_asound
+#define snd_seq_queue_info_get_locked snd_seq_queue_info_get_locked_dylibloader_orig_asound
+#define snd_seq_queue_info_get_flags snd_seq_queue_info_get_flags_dylibloader_orig_asound
+#define snd_seq_queue_info_set_name snd_seq_queue_info_set_name_dylibloader_orig_asound
+#define snd_seq_queue_info_set_owner snd_seq_queue_info_set_owner_dylibloader_orig_asound
+#define snd_seq_queue_info_set_locked snd_seq_queue_info_set_locked_dylibloader_orig_asound
+#define snd_seq_queue_info_set_flags snd_seq_queue_info_set_flags_dylibloader_orig_asound
+#define snd_seq_create_queue snd_seq_create_queue_dylibloader_orig_asound
+#define snd_seq_alloc_named_queue snd_seq_alloc_named_queue_dylibloader_orig_asound
+#define snd_seq_alloc_queue snd_seq_alloc_queue_dylibloader_orig_asound
+#define snd_seq_free_queue snd_seq_free_queue_dylibloader_orig_asound
+#define snd_seq_get_queue_info snd_seq_get_queue_info_dylibloader_orig_asound
+#define snd_seq_set_queue_info snd_seq_set_queue_info_dylibloader_orig_asound
+#define snd_seq_query_named_queue snd_seq_query_named_queue_dylibloader_orig_asound
+#define snd_seq_get_queue_usage snd_seq_get_queue_usage_dylibloader_orig_asound
+#define snd_seq_set_queue_usage snd_seq_set_queue_usage_dylibloader_orig_asound
+#define snd_seq_queue_status_sizeof snd_seq_queue_status_sizeof_dylibloader_orig_asound
+#define snd_seq_queue_status_malloc snd_seq_queue_status_malloc_dylibloader_orig_asound
+#define snd_seq_queue_status_free snd_seq_queue_status_free_dylibloader_orig_asound
+#define snd_seq_queue_status_copy snd_seq_queue_status_copy_dylibloader_orig_asound
+#define snd_seq_queue_status_get_queue snd_seq_queue_status_get_queue_dylibloader_orig_asound
+#define snd_seq_queue_status_get_events snd_seq_queue_status_get_events_dylibloader_orig_asound
+#define snd_seq_queue_status_get_tick_time snd_seq_queue_status_get_tick_time_dylibloader_orig_asound
+#define snd_seq_queue_status_get_real_time snd_seq_queue_status_get_real_time_dylibloader_orig_asound
+#define snd_seq_queue_status_get_status snd_seq_queue_status_get_status_dylibloader_orig_asound
+#define snd_seq_get_queue_status snd_seq_get_queue_status_dylibloader_orig_asound
+#define snd_seq_queue_tempo_sizeof snd_seq_queue_tempo_sizeof_dylibloader_orig_asound
+#define snd_seq_queue_tempo_malloc snd_seq_queue_tempo_malloc_dylibloader_orig_asound
+#define snd_seq_queue_tempo_free snd_seq_queue_tempo_free_dylibloader_orig_asound
+#define snd_seq_queue_tempo_copy snd_seq_queue_tempo_copy_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_queue snd_seq_queue_tempo_get_queue_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_tempo snd_seq_queue_tempo_get_tempo_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_ppq snd_seq_queue_tempo_get_ppq_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_skew snd_seq_queue_tempo_get_skew_dylibloader_orig_asound
+#define snd_seq_queue_tempo_get_skew_base snd_seq_queue_tempo_get_skew_base_dylibloader_orig_asound
+#define snd_seq_queue_tempo_set_tempo snd_seq_queue_tempo_set_tempo_dylibloader_orig_asound
+#define snd_seq_queue_tempo_set_ppq snd_seq_queue_tempo_set_ppq_dylibloader_orig_asound
+#define snd_seq_queue_tempo_set_skew snd_seq_queue_tempo_set_skew_dylibloader_orig_asound
+#define snd_seq_queue_tempo_set_skew_base snd_seq_queue_tempo_set_skew_base_dylibloader_orig_asound
+#define snd_seq_get_queue_tempo snd_seq_get_queue_tempo_dylibloader_orig_asound
+#define snd_seq_set_queue_tempo snd_seq_set_queue_tempo_dylibloader_orig_asound
+#define snd_seq_queue_timer_sizeof snd_seq_queue_timer_sizeof_dylibloader_orig_asound
+#define snd_seq_queue_timer_malloc snd_seq_queue_timer_malloc_dylibloader_orig_asound
+#define snd_seq_queue_timer_free snd_seq_queue_timer_free_dylibloader_orig_asound
+#define snd_seq_queue_timer_copy snd_seq_queue_timer_copy_dylibloader_orig_asound
+#define snd_seq_queue_timer_get_queue snd_seq_queue_timer_get_queue_dylibloader_orig_asound
+#define snd_seq_queue_timer_get_type snd_seq_queue_timer_get_type_dylibloader_orig_asound
+#define snd_seq_queue_timer_get_id snd_seq_queue_timer_get_id_dylibloader_orig_asound
+#define snd_seq_queue_timer_get_resolution snd_seq_queue_timer_get_resolution_dylibloader_orig_asound
+#define snd_seq_queue_timer_set_type snd_seq_queue_timer_set_type_dylibloader_orig_asound
+#define snd_seq_queue_timer_set_id snd_seq_queue_timer_set_id_dylibloader_orig_asound
+#define snd_seq_queue_timer_set_resolution snd_seq_queue_timer_set_resolution_dylibloader_orig_asound
+#define snd_seq_get_queue_timer snd_seq_get_queue_timer_dylibloader_orig_asound
+#define snd_seq_set_queue_timer snd_seq_set_queue_timer_dylibloader_orig_asound
+#define snd_seq_free_event snd_seq_free_event_dylibloader_orig_asound
+#define snd_seq_event_length snd_seq_event_length_dylibloader_orig_asound
+#define snd_seq_event_output snd_seq_event_output_dylibloader_orig_asound
+#define snd_seq_event_output_buffer snd_seq_event_output_buffer_dylibloader_orig_asound
+#define snd_seq_event_output_direct snd_seq_event_output_direct_dylibloader_orig_asound
+#define snd_seq_event_input snd_seq_event_input_dylibloader_orig_asound
+#define snd_seq_event_input_pending snd_seq_event_input_pending_dylibloader_orig_asound
+#define snd_seq_drain_output snd_seq_drain_output_dylibloader_orig_asound
+#define snd_seq_event_output_pending snd_seq_event_output_pending_dylibloader_orig_asound
+#define snd_seq_extract_output snd_seq_extract_output_dylibloader_orig_asound
+#define snd_seq_drop_output snd_seq_drop_output_dylibloader_orig_asound
+#define snd_seq_drop_output_buffer snd_seq_drop_output_buffer_dylibloader_orig_asound
+#define snd_seq_drop_input snd_seq_drop_input_dylibloader_orig_asound
+#define snd_seq_drop_input_buffer snd_seq_drop_input_buffer_dylibloader_orig_asound
+#define snd_seq_remove_events_sizeof snd_seq_remove_events_sizeof_dylibloader_orig_asound
+#define snd_seq_remove_events_malloc snd_seq_remove_events_malloc_dylibloader_orig_asound
+#define snd_seq_remove_events_free snd_seq_remove_events_free_dylibloader_orig_asound
+#define snd_seq_remove_events_copy snd_seq_remove_events_copy_dylibloader_orig_asound
+#define snd_seq_remove_events_get_condition snd_seq_remove_events_get_condition_dylibloader_orig_asound
+#define snd_seq_remove_events_get_queue snd_seq_remove_events_get_queue_dylibloader_orig_asound
+#define snd_seq_remove_events_get_time snd_seq_remove_events_get_time_dylibloader_orig_asound
+#define snd_seq_remove_events_get_dest snd_seq_remove_events_get_dest_dylibloader_orig_asound
+#define snd_seq_remove_events_get_channel snd_seq_remove_events_get_channel_dylibloader_orig_asound
+#define snd_seq_remove_events_get_event_type snd_seq_remove_events_get_event_type_dylibloader_orig_asound
+#define snd_seq_remove_events_get_tag snd_seq_remove_events_get_tag_dylibloader_orig_asound
+#define snd_seq_remove_events_set_condition snd_seq_remove_events_set_condition_dylibloader_orig_asound
+#define snd_seq_remove_events_set_queue snd_seq_remove_events_set_queue_dylibloader_orig_asound
+#define snd_seq_remove_events_set_time snd_seq_remove_events_set_time_dylibloader_orig_asound
+#define snd_seq_remove_events_set_dest snd_seq_remove_events_set_dest_dylibloader_orig_asound
+#define snd_seq_remove_events_set_channel snd_seq_remove_events_set_channel_dylibloader_orig_asound
+#define snd_seq_remove_events_set_event_type snd_seq_remove_events_set_event_type_dylibloader_orig_asound
+#define snd_seq_remove_events_set_tag snd_seq_remove_events_set_tag_dylibloader_orig_asound
+#define snd_seq_remove_events snd_seq_remove_events_dylibloader_orig_asound
+#define snd_seq_set_bit snd_seq_set_bit_dylibloader_orig_asound
+#define snd_seq_unset_bit snd_seq_unset_bit_dylibloader_orig_asound
+#define snd_seq_change_bit snd_seq_change_bit_dylibloader_orig_asound
+#define snd_seq_get_bit snd_seq_get_bit_dylibloader_orig_asound
+#define snd_seq_control_queue snd_seq_control_queue_dylibloader_orig_asound
+#define snd_seq_create_simple_port snd_seq_create_simple_port_dylibloader_orig_asound
+#define snd_seq_delete_simple_port snd_seq_delete_simple_port_dylibloader_orig_asound
+#define snd_seq_connect_from snd_seq_connect_from_dylibloader_orig_asound
+#define snd_seq_connect_to snd_seq_connect_to_dylibloader_orig_asound
+#define snd_seq_disconnect_from snd_seq_disconnect_from_dylibloader_orig_asound
+#define snd_seq_disconnect_to snd_seq_disconnect_to_dylibloader_orig_asound
+#define snd_seq_set_client_name snd_seq_set_client_name_dylibloader_orig_asound
+#define snd_seq_set_client_event_filter snd_seq_set_client_event_filter_dylibloader_orig_asound
+#define snd_seq_set_client_pool_output snd_seq_set_client_pool_output_dylibloader_orig_asound
+#define snd_seq_set_client_pool_output_room snd_seq_set_client_pool_output_room_dylibloader_orig_asound
+#define snd_seq_set_client_pool_input snd_seq_set_client_pool_input_dylibloader_orig_asound
+#define snd_seq_sync_output_queue snd_seq_sync_output_queue_dylibloader_orig_asound
+#define snd_seq_parse_address snd_seq_parse_address_dylibloader_orig_asound
+#define snd_seq_reset_pool_output snd_seq_reset_pool_output_dylibloader_orig_asound
+#define snd_seq_reset_pool_input snd_seq_reset_pool_input_dylibloader_orig_asound
+#define snd_midi_event_new snd_midi_event_new_dylibloader_orig_asound
+#define snd_midi_event_resize_buffer snd_midi_event_resize_buffer_dylibloader_orig_asound
+#define snd_midi_event_free snd_midi_event_free_dylibloader_orig_asound
+#define snd_midi_event_init snd_midi_event_init_dylibloader_orig_asound
+#define snd_midi_event_reset_encode snd_midi_event_reset_encode_dylibloader_orig_asound
+#define snd_midi_event_reset_decode snd_midi_event_reset_decode_dylibloader_orig_asound
+#define snd_midi_event_no_status snd_midi_event_no_status_dylibloader_orig_asound
+#define snd_midi_event_encode snd_midi_event_encode_dylibloader_orig_asound
+#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_orig_asound
+#define snd_midi_event_decode snd_midi_event_decode_dylibloader_orig_asound
+#include <alsa/asoundlib.h>
+#undef snd_asoundlib_version
+#undef snd_dlpath
+#undef snd_dlopen
+#undef snd_dlsym
+#undef snd_dlclose
+#undef snd_async_add_handler
+#undef snd_async_del_handler
+#undef snd_async_handler_get_fd
+#undef snd_async_handler_get_signo
+#undef snd_async_handler_get_callback_private
+#undef snd_shm_area_create
+#undef snd_shm_area_share
+#undef snd_shm_area_destroy
+#undef snd_user_file
+#undef snd_input_stdio_open
+#undef snd_input_stdio_attach
+#undef snd_input_buffer_open
+#undef snd_input_close
+#undef snd_input_scanf
+#undef snd_input_gets
+#undef snd_input_getc
+#undef snd_input_ungetc
+#undef snd_output_stdio_open
+#undef snd_output_stdio_attach
+#undef snd_output_buffer_open
+#undef snd_output_buffer_string
+#undef snd_output_close
+#undef snd_output_printf
+#undef snd_output_vprintf
+#undef snd_output_puts
+#undef snd_output_putc
+#undef snd_output_flush
+#undef snd_strerror
+#undef snd_lib_error_set_handler
+#undef snd_lib_error_set_local
+#undef snd_config_topdir
+#undef snd_config_top
+#undef snd_config_load
+#undef snd_config_load_override
+#undef snd_config_save
+#undef snd_config_update
+#undef snd_config_update_r
+#undef snd_config_update_free
+#undef snd_config_update_free_global
+#undef snd_config_update_ref
+#undef snd_config_ref
+#undef snd_config_unref
+#undef snd_config_search
+#undef snd_config_searchv
+#undef snd_config_search_definition
+#undef snd_config_expand
+#undef snd_config_evaluate
+#undef snd_config_add
+#undef snd_config_add_before
+#undef snd_config_add_after
+#undef snd_config_remove
+#undef snd_config_delete
+#undef snd_config_delete_compound_members
+#undef snd_config_copy
+#undef snd_config_make
+#undef snd_config_make_integer
+#undef snd_config_make_integer64
+#undef snd_config_make_real
+#undef snd_config_make_string
+#undef snd_config_make_pointer
+#undef snd_config_make_compound
+#undef snd_config_imake_integer
+#undef snd_config_imake_integer64
+#undef snd_config_imake_real
+#undef snd_config_imake_string
+#undef snd_config_imake_safe_string
+#undef snd_config_imake_pointer
+#undef snd_config_get_type
+#undef snd_config_is_array
+#undef snd_config_set_id
+#undef snd_config_set_integer
+#undef snd_config_set_integer64
+#undef snd_config_set_real
+#undef snd_config_set_string
+#undef snd_config_set_ascii
+#undef snd_config_set_pointer
+#undef snd_config_get_id
+#undef snd_config_get_integer
+#undef snd_config_get_integer64
+#undef snd_config_get_real
+#undef snd_config_get_ireal
+#undef snd_config_get_string
+#undef snd_config_get_ascii
+#undef snd_config_get_pointer
+#undef snd_config_test_id
+#undef snd_config_iterator_first
+#undef snd_config_iterator_next
+#undef snd_config_iterator_end
+#undef snd_config_iterator_entry
+#undef snd_config_get_bool_ascii
+#undef snd_config_get_bool
+#undef snd_config_get_ctl_iface_ascii
+#undef snd_config_get_ctl_iface
+#undef snd_names_list
+#undef snd_names_list_free
+#undef snd_pcm_open
+#undef snd_pcm_open_lconf
+#undef snd_pcm_open_fallback
+#undef snd_pcm_close
+#undef snd_pcm_name
+#undef snd_pcm_type
+#undef snd_pcm_stream
+#undef snd_pcm_poll_descriptors_count
+#undef snd_pcm_poll_descriptors
+#undef snd_pcm_poll_descriptors_revents
+#undef snd_pcm_nonblock
+#undef snd_async_add_pcm_handler
+#undef snd_async_handler_get_pcm
+#undef snd_pcm_info
+#undef snd_pcm_hw_params_current
+#undef snd_pcm_hw_params
+#undef snd_pcm_hw_free
+#undef snd_pcm_sw_params_current
+#undef snd_pcm_sw_params
+#undef snd_pcm_prepare
+#undef snd_pcm_reset
+#undef snd_pcm_status
+#undef snd_pcm_start
+#undef snd_pcm_drop
+#undef snd_pcm_drain
+#undef snd_pcm_pause
+#undef snd_pcm_state
+#undef snd_pcm_hwsync
+#undef snd_pcm_delay
+#undef snd_pcm_resume
+#undef snd_pcm_htimestamp
+#undef snd_pcm_avail
+#undef snd_pcm_avail_update
+#undef snd_pcm_avail_delay
+#undef snd_pcm_rewindable
+#undef snd_pcm_rewind
+#undef snd_pcm_forwardable
+#undef snd_pcm_forward
+#undef snd_pcm_writei
+#undef snd_pcm_readi
+#undef snd_pcm_writen
+#undef snd_pcm_readn
+#undef snd_pcm_wait
+#undef snd_pcm_link
+#undef snd_pcm_unlink
+#undef snd_pcm_query_chmaps
+#undef snd_pcm_query_chmaps_from_hw
+#undef snd_pcm_free_chmaps
+#undef snd_pcm_get_chmap
+#undef snd_pcm_set_chmap
+#undef snd_pcm_chmap_type_name
+#undef snd_pcm_chmap_name
+#undef snd_pcm_chmap_long_name
+#undef snd_pcm_chmap_print
+#undef snd_pcm_chmap_from_string
+#undef snd_pcm_chmap_parse_string
+#undef snd_pcm_recover
+#undef snd_pcm_set_params
+#undef snd_pcm_get_params
+#undef snd_pcm_info_sizeof
+#undef snd_pcm_info_malloc
+#undef snd_pcm_info_free
+#undef snd_pcm_info_copy
+#undef snd_pcm_info_get_device
+#undef snd_pcm_info_get_subdevice
+#undef snd_pcm_info_get_stream
+#undef snd_pcm_info_get_card
+#undef snd_pcm_info_get_id
+#undef snd_pcm_info_get_name
+#undef snd_pcm_info_get_subdevice_name
+#undef snd_pcm_info_get_class
+#undef snd_pcm_info_get_subclass
+#undef snd_pcm_info_get_subdevices_count
+#undef snd_pcm_info_get_subdevices_avail
+#undef snd_pcm_info_get_sync
+#undef snd_pcm_info_set_device
+#undef snd_pcm_info_set_subdevice
+#undef snd_pcm_info_set_stream
+#undef snd_pcm_hw_params_any
+#undef snd_pcm_hw_params_can_mmap_sample_resolution
+#undef snd_pcm_hw_params_is_double
+#undef snd_pcm_hw_params_is_batch
+#undef snd_pcm_hw_params_is_block_transfer
+#undef snd_pcm_hw_params_is_monotonic
+#undef snd_pcm_hw_params_can_overrange
+#undef snd_pcm_hw_params_can_pause
+#undef snd_pcm_hw_params_can_resume
+#undef snd_pcm_hw_params_is_half_duplex
+#undef snd_pcm_hw_params_is_joint_duplex
+#undef snd_pcm_hw_params_can_sync_start
+#undef snd_pcm_hw_params_can_disable_period_wakeup
+#undef snd_pcm_hw_params_supports_audio_wallclock_ts
+#undef snd_pcm_hw_params_supports_audio_ts_type
+#undef snd_pcm_hw_params_get_rate_numden
+#undef snd_pcm_hw_params_get_sbits
+#undef snd_pcm_hw_params_get_fifo_size
+#undef snd_pcm_hw_params_sizeof
+#undef snd_pcm_hw_params_malloc
+#undef snd_pcm_hw_params_free
+#undef snd_pcm_hw_params_copy
+#undef snd_pcm_hw_params_get_access
+#undef snd_pcm_hw_params_test_access
+#undef snd_pcm_hw_params_set_access
+#undef snd_pcm_hw_params_set_access_first
+#undef snd_pcm_hw_params_set_access_last
+#undef snd_pcm_hw_params_set_access_mask
+#undef snd_pcm_hw_params_get_access_mask
+#undef snd_pcm_hw_params_get_format
+#undef snd_pcm_hw_params_test_format
+#undef snd_pcm_hw_params_set_format
+#undef snd_pcm_hw_params_set_format_first
+#undef snd_pcm_hw_params_set_format_last
+#undef snd_pcm_hw_params_set_format_mask
+#undef snd_pcm_hw_params_get_format_mask
+#undef snd_pcm_hw_params_get_subformat
+#undef snd_pcm_hw_params_test_subformat
+#undef snd_pcm_hw_params_set_subformat
+#undef snd_pcm_hw_params_set_subformat_first
+#undef snd_pcm_hw_params_set_subformat_last
+#undef snd_pcm_hw_params_set_subformat_mask
+#undef snd_pcm_hw_params_get_subformat_mask
+#undef snd_pcm_hw_params_get_channels
+#undef snd_pcm_hw_params_get_channels_min
+#undef snd_pcm_hw_params_get_channels_max
+#undef snd_pcm_hw_params_test_channels
+#undef snd_pcm_hw_params_set_channels
+#undef snd_pcm_hw_params_set_channels_min
+#undef snd_pcm_hw_params_set_channels_max
+#undef snd_pcm_hw_params_set_channels_minmax
+#undef snd_pcm_hw_params_set_channels_near
+#undef snd_pcm_hw_params_set_channels_first
+#undef snd_pcm_hw_params_set_channels_last
+#undef snd_pcm_hw_params_get_rate
+#undef snd_pcm_hw_params_get_rate_min
+#undef snd_pcm_hw_params_get_rate_max
+#undef snd_pcm_hw_params_test_rate
+#undef snd_pcm_hw_params_set_rate
+#undef snd_pcm_hw_params_set_rate_min
+#undef snd_pcm_hw_params_set_rate_max
+#undef snd_pcm_hw_params_set_rate_minmax
+#undef snd_pcm_hw_params_set_rate_near
+#undef snd_pcm_hw_params_set_rate_first
+#undef snd_pcm_hw_params_set_rate_last
+#undef snd_pcm_hw_params_set_rate_resample
+#undef snd_pcm_hw_params_get_rate_resample
+#undef snd_pcm_hw_params_set_export_buffer
+#undef snd_pcm_hw_params_get_export_buffer
+#undef snd_pcm_hw_params_set_period_wakeup
+#undef snd_pcm_hw_params_get_period_wakeup
+#undef snd_pcm_hw_params_get_period_time
+#undef snd_pcm_hw_params_get_period_time_min
+#undef snd_pcm_hw_params_get_period_time_max
+#undef snd_pcm_hw_params_test_period_time
+#undef snd_pcm_hw_params_set_period_time
+#undef snd_pcm_hw_params_set_period_time_min
+#undef snd_pcm_hw_params_set_period_time_max
+#undef snd_pcm_hw_params_set_period_time_minmax
+#undef snd_pcm_hw_params_set_period_time_near
+#undef snd_pcm_hw_params_set_period_time_first
+#undef snd_pcm_hw_params_set_period_time_last
+#undef snd_pcm_hw_params_get_period_size
+#undef snd_pcm_hw_params_get_period_size_min
+#undef snd_pcm_hw_params_get_period_size_max
+#undef snd_pcm_hw_params_test_period_size
+#undef snd_pcm_hw_params_set_period_size
+#undef snd_pcm_hw_params_set_period_size_min
+#undef snd_pcm_hw_params_set_period_size_max
+#undef snd_pcm_hw_params_set_period_size_minmax
+#undef snd_pcm_hw_params_set_period_size_near
+#undef snd_pcm_hw_params_set_period_size_first
+#undef snd_pcm_hw_params_set_period_size_last
+#undef snd_pcm_hw_params_set_period_size_integer
+#undef snd_pcm_hw_params_get_periods
+#undef snd_pcm_hw_params_get_periods_min
+#undef snd_pcm_hw_params_get_periods_max
+#undef snd_pcm_hw_params_test_periods
+#undef snd_pcm_hw_params_set_periods
+#undef snd_pcm_hw_params_set_periods_min
+#undef snd_pcm_hw_params_set_periods_max
+#undef snd_pcm_hw_params_set_periods_minmax
+#undef snd_pcm_hw_params_set_periods_near
+#undef snd_pcm_hw_params_set_periods_first
+#undef snd_pcm_hw_params_set_periods_last
+#undef snd_pcm_hw_params_set_periods_integer
+#undef snd_pcm_hw_params_get_buffer_time
+#undef snd_pcm_hw_params_get_buffer_time_min
+#undef snd_pcm_hw_params_get_buffer_time_max
+#undef snd_pcm_hw_params_test_buffer_time
+#undef snd_pcm_hw_params_set_buffer_time
+#undef snd_pcm_hw_params_set_buffer_time_min
+#undef snd_pcm_hw_params_set_buffer_time_max
+#undef snd_pcm_hw_params_set_buffer_time_minmax
+#undef snd_pcm_hw_params_set_buffer_time_near
+#undef snd_pcm_hw_params_set_buffer_time_first
+#undef snd_pcm_hw_params_set_buffer_time_last
+#undef snd_pcm_hw_params_get_buffer_size
+#undef snd_pcm_hw_params_get_buffer_size_min
+#undef snd_pcm_hw_params_get_buffer_size_max
+#undef snd_pcm_hw_params_test_buffer_size
+#undef snd_pcm_hw_params_set_buffer_size
+#undef snd_pcm_hw_params_set_buffer_size_min
+#undef snd_pcm_hw_params_set_buffer_size_max
+#undef snd_pcm_hw_params_set_buffer_size_minmax
+#undef snd_pcm_hw_params_set_buffer_size_near
+#undef snd_pcm_hw_params_set_buffer_size_first
+#undef snd_pcm_hw_params_set_buffer_size_last
+#undef snd_pcm_hw_params_get_min_align
+#undef snd_pcm_sw_params_sizeof
+#undef snd_pcm_sw_params_malloc
+#undef snd_pcm_sw_params_free
+#undef snd_pcm_sw_params_copy
+#undef snd_pcm_sw_params_get_boundary
+#undef snd_pcm_sw_params_set_tstamp_mode
+#undef snd_pcm_sw_params_get_tstamp_mode
+#undef snd_pcm_sw_params_set_avail_min
+#undef snd_pcm_sw_params_get_avail_min
+#undef snd_pcm_sw_params_set_period_event
+#undef snd_pcm_sw_params_get_period_event
+#undef snd_pcm_sw_params_set_start_threshold
+#undef snd_pcm_sw_params_get_start_threshold
+#undef snd_pcm_sw_params_set_stop_threshold
+#undef snd_pcm_sw_params_get_stop_threshold
+#undef snd_pcm_sw_params_set_silence_threshold
+#undef snd_pcm_sw_params_get_silence_threshold
+#undef snd_pcm_sw_params_set_silence_size
+#undef snd_pcm_sw_params_get_silence_size
+#undef snd_pcm_access_mask_sizeof
+#undef snd_pcm_access_mask_malloc
+#undef snd_pcm_access_mask_free
+#undef snd_pcm_access_mask_copy
+#undef snd_pcm_access_mask_none
+#undef snd_pcm_access_mask_any
+#undef snd_pcm_access_mask_test
+#undef snd_pcm_access_mask_empty
+#undef snd_pcm_access_mask_set
+#undef snd_pcm_access_mask_reset
+#undef snd_pcm_format_mask_sizeof
+#undef snd_pcm_format_mask_malloc
+#undef snd_pcm_format_mask_free
+#undef snd_pcm_format_mask_copy
+#undef snd_pcm_format_mask_none
+#undef snd_pcm_format_mask_any
+#undef snd_pcm_format_mask_test
+#undef snd_pcm_format_mask_empty
+#undef snd_pcm_format_mask_set
+#undef snd_pcm_format_mask_reset
+#undef snd_pcm_subformat_mask_sizeof
+#undef snd_pcm_subformat_mask_malloc
+#undef snd_pcm_subformat_mask_free
+#undef snd_pcm_subformat_mask_copy
+#undef snd_pcm_subformat_mask_none
+#undef snd_pcm_subformat_mask_any
+#undef snd_pcm_subformat_mask_test
+#undef snd_pcm_subformat_mask_empty
+#undef snd_pcm_subformat_mask_set
+#undef snd_pcm_subformat_mask_reset
+#undef snd_pcm_status_sizeof
+#undef snd_pcm_status_malloc
+#undef snd_pcm_status_free
+#undef snd_pcm_status_copy
+#undef snd_pcm_status_get_state
+#undef snd_pcm_status_get_trigger_tstamp
+#undef snd_pcm_status_get_trigger_htstamp
+#undef snd_pcm_status_get_tstamp
+#undef snd_pcm_status_get_htstamp
+#undef snd_pcm_status_get_audio_htstamp
+#undef snd_pcm_status_get_driver_htstamp
+#undef snd_pcm_status_get_delay
+#undef snd_pcm_status_get_avail
+#undef snd_pcm_status_get_avail_max
+#undef snd_pcm_status_get_overrange
+#undef snd_pcm_type_name
+#undef snd_pcm_stream_name
+#undef snd_pcm_access_name
+#undef snd_pcm_format_name
+#undef snd_pcm_format_description
+#undef snd_pcm_subformat_name
+#undef snd_pcm_subformat_description
+#undef snd_pcm_format_value
+#undef snd_pcm_tstamp_mode_name
+#undef snd_pcm_state_name
+#undef snd_pcm_dump
+#undef snd_pcm_dump_hw_setup
+#undef snd_pcm_dump_sw_setup
+#undef snd_pcm_dump_setup
+#undef snd_pcm_hw_params_dump
+#undef snd_pcm_sw_params_dump
+#undef snd_pcm_status_dump
+#undef snd_pcm_mmap_begin
+#undef snd_pcm_mmap_commit
+#undef snd_pcm_mmap_writei
+#undef snd_pcm_mmap_readi
+#undef snd_pcm_mmap_writen
+#undef snd_pcm_mmap_readn
+#undef snd_pcm_format_signed
+#undef snd_pcm_format_unsigned
+#undef snd_pcm_format_linear
+#undef snd_pcm_format_float
+#undef snd_pcm_format_little_endian
+#undef snd_pcm_format_big_endian
+#undef snd_pcm_format_cpu_endian
+#undef snd_pcm_format_width
+#undef snd_pcm_format_physical_width
+#undef snd_pcm_build_linear_format
+#undef snd_pcm_format_size
+#undef snd_pcm_format_silence
+#undef snd_pcm_format_silence_16
+#undef snd_pcm_format_silence_32
+#undef snd_pcm_format_silence_64
+#undef snd_pcm_format_set_silence
+#undef snd_pcm_bytes_to_frames
+#undef snd_pcm_frames_to_bytes
+#undef snd_pcm_bytes_to_samples
+#undef snd_pcm_samples_to_bytes
+#undef snd_pcm_area_silence
+#undef snd_pcm_areas_silence
+#undef snd_pcm_area_copy
+#undef snd_pcm_areas_copy
+#undef snd_pcm_areas_copy_wrap
+#undef snd_pcm_hook_get_pcm
+#undef snd_pcm_hook_get_private
+#undef snd_pcm_hook_set_private
+#undef snd_pcm_hook_add
+#undef snd_pcm_hook_remove
+#undef snd_pcm_meter_get_bufsize
+#undef snd_pcm_meter_get_channels
+#undef snd_pcm_meter_get_rate
+#undef snd_pcm_meter_get_now
+#undef snd_pcm_meter_get_boundary
+#undef snd_pcm_meter_add_scope
+#undef snd_pcm_meter_search_scope
+#undef snd_pcm_scope_malloc
+#undef snd_pcm_scope_set_ops
+#undef snd_pcm_scope_set_name
+#undef snd_pcm_scope_get_name
+#undef snd_pcm_scope_get_callback_private
+#undef snd_pcm_scope_set_callback_private
+#undef snd_pcm_scope_s16_open
+#undef snd_pcm_scope_s16_get_channel_buffer
+#undef snd_spcm_init
+#undef snd_spcm_init_duplex
+#undef snd_spcm_init_get_params
+#undef snd_pcm_start_mode_name
+#undef snd_pcm_xrun_mode_name
+#undef snd_pcm_sw_params_set_start_mode
+#undef snd_pcm_sw_params_get_start_mode
+#undef snd_pcm_sw_params_set_xrun_mode
+#undef snd_pcm_sw_params_get_xrun_mode
+#undef snd_pcm_sw_params_set_xfer_align
+#undef snd_pcm_sw_params_get_xfer_align
+#undef snd_pcm_sw_params_set_sleep_min
+#undef snd_pcm_sw_params_get_sleep_min
+#undef snd_pcm_hw_params_get_tick_time
+#undef snd_pcm_hw_params_get_tick_time_min
+#undef snd_pcm_hw_params_get_tick_time_max
+#undef snd_pcm_hw_params_test_tick_time
+#undef snd_pcm_hw_params_set_tick_time
+#undef snd_pcm_hw_params_set_tick_time_min
+#undef snd_pcm_hw_params_set_tick_time_max
+#undef snd_pcm_hw_params_set_tick_time_minmax
+#undef snd_pcm_hw_params_set_tick_time_near
+#undef snd_pcm_hw_params_set_tick_time_first
+#undef snd_pcm_hw_params_set_tick_time_last
+#undef snd_rawmidi_open
+#undef snd_rawmidi_open_lconf
+#undef snd_rawmidi_close
+#undef snd_rawmidi_poll_descriptors_count
+#undef snd_rawmidi_poll_descriptors
+#undef snd_rawmidi_poll_descriptors_revents
+#undef snd_rawmidi_nonblock
+#undef snd_rawmidi_info_sizeof
+#undef snd_rawmidi_info_malloc
+#undef snd_rawmidi_info_free
+#undef snd_rawmidi_info_copy
+#undef snd_rawmidi_info_get_device
+#undef snd_rawmidi_info_get_subdevice
+#undef snd_rawmidi_info_get_stream
+#undef snd_rawmidi_info_get_card
+#undef snd_rawmidi_info_get_flags
+#undef snd_rawmidi_info_get_id
+#undef snd_rawmidi_info_get_name
+#undef snd_rawmidi_info_get_subdevice_name
+#undef snd_rawmidi_info_get_subdevices_count
+#undef snd_rawmidi_info_get_subdevices_avail
+#undef snd_rawmidi_info_set_device
+#undef snd_rawmidi_info_set_subdevice
+#undef snd_rawmidi_info_set_stream
+#undef snd_rawmidi_info
+#undef snd_rawmidi_params_sizeof
+#undef snd_rawmidi_params_malloc
+#undef snd_rawmidi_params_free
+#undef snd_rawmidi_params_copy
+#undef snd_rawmidi_params_set_buffer_size
+#undef snd_rawmidi_params_get_buffer_size
+#undef snd_rawmidi_params_set_avail_min
+#undef snd_rawmidi_params_get_avail_min
+#undef snd_rawmidi_params_set_no_active_sensing
+#undef snd_rawmidi_params_get_no_active_sensing
+#undef snd_rawmidi_params
+#undef snd_rawmidi_params_current
+#undef snd_rawmidi_status_sizeof
+#undef snd_rawmidi_status_malloc
+#undef snd_rawmidi_status_free
+#undef snd_rawmidi_status_copy
+#undef snd_rawmidi_status_get_tstamp
+#undef snd_rawmidi_status_get_avail
+#undef snd_rawmidi_status_get_xruns
+#undef snd_rawmidi_status
+#undef snd_rawmidi_drain
+#undef snd_rawmidi_drop
+#undef snd_rawmidi_write
+#undef snd_rawmidi_read
+#undef snd_rawmidi_name
+#undef snd_rawmidi_type
+#undef snd_rawmidi_stream
+#undef snd_timer_query_open
+#undef snd_timer_query_open_lconf
+#undef snd_timer_query_close
+#undef snd_timer_query_next_device
+#undef snd_timer_query_info
+#undef snd_timer_query_params
+#undef snd_timer_query_status
+#undef snd_timer_open
+#undef snd_timer_open_lconf
+#undef snd_timer_close
+#undef snd_async_add_timer_handler
+#undef snd_async_handler_get_timer
+#undef snd_timer_poll_descriptors_count
+#undef snd_timer_poll_descriptors
+#undef snd_timer_poll_descriptors_revents
+#undef snd_timer_info
+#undef snd_timer_params
+#undef snd_timer_status
+#undef snd_timer_start
+#undef snd_timer_stop
+#undef snd_timer_continue
+#undef snd_timer_read
+#undef snd_timer_id_sizeof
+#undef snd_timer_id_malloc
+#undef snd_timer_id_free
+#undef snd_timer_id_copy
+#undef snd_timer_id_set_class
+#undef snd_timer_id_get_class
+#undef snd_timer_id_set_sclass
+#undef snd_timer_id_get_sclass
+#undef snd_timer_id_set_card
+#undef snd_timer_id_get_card
+#undef snd_timer_id_set_device
+#undef snd_timer_id_get_device
+#undef snd_timer_id_set_subdevice
+#undef snd_timer_id_get_subdevice
+#undef snd_timer_ginfo_sizeof
+#undef snd_timer_ginfo_malloc
+#undef snd_timer_ginfo_free
+#undef snd_timer_ginfo_copy
+#undef snd_timer_ginfo_set_tid
+#undef snd_timer_ginfo_get_tid
+#undef snd_timer_ginfo_get_flags
+#undef snd_timer_ginfo_get_card
+#undef snd_timer_ginfo_get_id
+#undef snd_timer_ginfo_get_name
+#undef snd_timer_ginfo_get_resolution
+#undef snd_timer_ginfo_get_resolution_min
+#undef snd_timer_ginfo_get_resolution_max
+#undef snd_timer_ginfo_get_clients
+#undef snd_timer_info_sizeof
+#undef snd_timer_info_malloc
+#undef snd_timer_info_free
+#undef snd_timer_info_copy
+#undef snd_timer_info_is_slave
+#undef snd_timer_info_get_card
+#undef snd_timer_info_get_id
+#undef snd_timer_info_get_name
+#undef snd_timer_info_get_resolution
+#undef snd_timer_params_sizeof
+#undef snd_timer_params_malloc
+#undef snd_timer_params_free
+#undef snd_timer_params_copy
+#undef snd_timer_params_set_auto_start
+#undef snd_timer_params_get_auto_start
+#undef snd_timer_params_set_exclusive
+#undef snd_timer_params_get_exclusive
+#undef snd_timer_params_set_early_event
+#undef snd_timer_params_get_early_event
+#undef snd_timer_params_set_ticks
+#undef snd_timer_params_get_ticks
+#undef snd_timer_params_set_queue_size
+#undef snd_timer_params_get_queue_size
+#undef snd_timer_params_set_filter
+#undef snd_timer_params_get_filter
+#undef snd_timer_status_sizeof
+#undef snd_timer_status_malloc
+#undef snd_timer_status_free
+#undef snd_timer_status_copy
+#undef snd_timer_status_get_timestamp
+#undef snd_timer_status_get_resolution
+#undef snd_timer_status_get_lost
+#undef snd_timer_status_get_overrun
+#undef snd_timer_status_get_queue
+#undef snd_timer_info_get_ticks
+#undef snd_hwdep_open
+#undef snd_hwdep_close
+#undef snd_hwdep_poll_descriptors
+#undef snd_hwdep_poll_descriptors_count
+#undef snd_hwdep_poll_descriptors_revents
+#undef snd_hwdep_nonblock
+#undef snd_hwdep_info
+#undef snd_hwdep_dsp_status
+#undef snd_hwdep_dsp_load
+#undef snd_hwdep_ioctl
+#undef snd_hwdep_write
+#undef snd_hwdep_read
+#undef snd_hwdep_info_sizeof
+#undef snd_hwdep_info_malloc
+#undef snd_hwdep_info_free
+#undef snd_hwdep_info_copy
+#undef snd_hwdep_info_get_device
+#undef snd_hwdep_info_get_card
+#undef snd_hwdep_info_get_id
+#undef snd_hwdep_info_get_name
+#undef snd_hwdep_info_get_iface
+#undef snd_hwdep_info_set_device
+#undef snd_hwdep_dsp_status_sizeof
+#undef snd_hwdep_dsp_status_malloc
+#undef snd_hwdep_dsp_status_free
+#undef snd_hwdep_dsp_status_copy
+#undef snd_hwdep_dsp_status_get_version
+#undef snd_hwdep_dsp_status_get_id
+#undef snd_hwdep_dsp_status_get_num_dsps
+#undef snd_hwdep_dsp_status_get_dsp_loaded
+#undef snd_hwdep_dsp_status_get_chip_ready
+#undef snd_hwdep_dsp_image_sizeof
+#undef snd_hwdep_dsp_image_malloc
+#undef snd_hwdep_dsp_image_free
+#undef snd_hwdep_dsp_image_copy
+#undef snd_hwdep_dsp_image_get_index
+#undef snd_hwdep_dsp_image_get_name
+#undef snd_hwdep_dsp_image_get_image
+#undef snd_hwdep_dsp_image_get_length
+#undef snd_hwdep_dsp_image_set_index
+#undef snd_hwdep_dsp_image_set_name
+#undef snd_hwdep_dsp_image_set_image
+#undef snd_hwdep_dsp_image_set_length
+#undef snd_card_load
+#undef snd_card_next
+#undef snd_card_get_index
+#undef snd_card_get_name
+#undef snd_card_get_longname
+#undef snd_device_name_hint
+#undef snd_device_name_free_hint
+#undef snd_device_name_get_hint
+#undef snd_ctl_open
+#undef snd_ctl_open_lconf
+#undef snd_ctl_open_fallback
+#undef snd_ctl_close
+#undef snd_ctl_nonblock
+#undef snd_async_add_ctl_handler
+#undef snd_async_handler_get_ctl
+#undef snd_ctl_poll_descriptors_count
+#undef snd_ctl_poll_descriptors
+#undef snd_ctl_poll_descriptors_revents
+#undef snd_ctl_subscribe_events
+#undef snd_ctl_card_info
+#undef snd_ctl_elem_list
+#undef snd_ctl_elem_info
+#undef snd_ctl_elem_read
+#undef snd_ctl_elem_write
+#undef snd_ctl_elem_lock
+#undef snd_ctl_elem_unlock
+#undef snd_ctl_elem_tlv_read
+#undef snd_ctl_elem_tlv_write
+#undef snd_ctl_elem_tlv_command
+#undef snd_ctl_hwdep_next_device
+#undef snd_ctl_hwdep_info
+#undef snd_ctl_pcm_next_device
+#undef snd_ctl_pcm_info
+#undef snd_ctl_pcm_prefer_subdevice
+#undef snd_ctl_rawmidi_next_device
+#undef snd_ctl_rawmidi_info
+#undef snd_ctl_rawmidi_prefer_subdevice
+#undef snd_ctl_set_power_state
+#undef snd_ctl_get_power_state
+#undef snd_ctl_read
+#undef snd_ctl_wait
+#undef snd_ctl_name
+#undef snd_ctl_type
+#undef snd_ctl_elem_type_name
+#undef snd_ctl_elem_iface_name
+#undef snd_ctl_event_type_name
+#undef snd_ctl_event_elem_get_mask
+#undef snd_ctl_event_elem_get_numid
+#undef snd_ctl_event_elem_get_id
+#undef snd_ctl_event_elem_get_interface
+#undef snd_ctl_event_elem_get_device
+#undef snd_ctl_event_elem_get_subdevice
+#undef snd_ctl_event_elem_get_name
+#undef snd_ctl_event_elem_get_index
+#undef snd_ctl_elem_list_alloc_space
+#undef snd_ctl_elem_list_free_space
+#undef snd_ctl_ascii_elem_id_get
+#undef snd_ctl_ascii_elem_id_parse
+#undef snd_ctl_ascii_value_parse
+#undef snd_ctl_elem_id_sizeof
+#undef snd_ctl_elem_id_malloc
+#undef snd_ctl_elem_id_free
+#undef snd_ctl_elem_id_clear
+#undef snd_ctl_elem_id_copy
+#undef snd_ctl_elem_id_get_numid
+#undef snd_ctl_elem_id_get_interface
+#undef snd_ctl_elem_id_get_device
+#undef snd_ctl_elem_id_get_subdevice
+#undef snd_ctl_elem_id_get_name
+#undef snd_ctl_elem_id_get_index
+#undef snd_ctl_elem_id_set_numid
+#undef snd_ctl_elem_id_set_interface
+#undef snd_ctl_elem_id_set_device
+#undef snd_ctl_elem_id_set_subdevice
+#undef snd_ctl_elem_id_set_name
+#undef snd_ctl_elem_id_set_index
+#undef snd_ctl_card_info_sizeof
+#undef snd_ctl_card_info_malloc
+#undef snd_ctl_card_info_free
+#undef snd_ctl_card_info_clear
+#undef snd_ctl_card_info_copy
+#undef snd_ctl_card_info_get_card
+#undef snd_ctl_card_info_get_id
+#undef snd_ctl_card_info_get_driver
+#undef snd_ctl_card_info_get_name
+#undef snd_ctl_card_info_get_longname
+#undef snd_ctl_card_info_get_mixername
+#undef snd_ctl_card_info_get_components
+#undef snd_ctl_event_sizeof
+#undef snd_ctl_event_malloc
+#undef snd_ctl_event_free
+#undef snd_ctl_event_clear
+#undef snd_ctl_event_copy
+#undef snd_ctl_event_get_type
+#undef snd_ctl_elem_list_sizeof
+#undef snd_ctl_elem_list_malloc
+#undef snd_ctl_elem_list_free
+#undef snd_ctl_elem_list_clear
+#undef snd_ctl_elem_list_copy
+#undef snd_ctl_elem_list_set_offset
+#undef snd_ctl_elem_list_get_used
+#undef snd_ctl_elem_list_get_count
+#undef snd_ctl_elem_list_get_id
+#undef snd_ctl_elem_list_get_numid
+#undef snd_ctl_elem_list_get_interface
+#undef snd_ctl_elem_list_get_device
+#undef snd_ctl_elem_list_get_subdevice
+#undef snd_ctl_elem_list_get_name
+#undef snd_ctl_elem_list_get_index
+#undef snd_ctl_elem_info_sizeof
+#undef snd_ctl_elem_info_malloc
+#undef snd_ctl_elem_info_free
+#undef snd_ctl_elem_info_clear
+#undef snd_ctl_elem_info_copy
+#undef snd_ctl_elem_info_get_type
+#undef snd_ctl_elem_info_is_readable
+#undef snd_ctl_elem_info_is_writable
+#undef snd_ctl_elem_info_is_volatile
+#undef snd_ctl_elem_info_is_inactive
+#undef snd_ctl_elem_info_is_locked
+#undef snd_ctl_elem_info_is_tlv_readable
+#undef snd_ctl_elem_info_is_tlv_writable
+#undef snd_ctl_elem_info_is_tlv_commandable
+#undef snd_ctl_elem_info_is_owner
+#undef snd_ctl_elem_info_is_user
+#undef snd_ctl_elem_info_get_owner
+#undef snd_ctl_elem_info_get_count
+#undef snd_ctl_elem_info_get_min
+#undef snd_ctl_elem_info_get_max
+#undef snd_ctl_elem_info_get_step
+#undef snd_ctl_elem_info_get_min64
+#undef snd_ctl_elem_info_get_max64
+#undef snd_ctl_elem_info_get_step64
+#undef snd_ctl_elem_info_get_items
+#undef snd_ctl_elem_info_set_item
+#undef snd_ctl_elem_info_get_item_name
+#undef snd_ctl_elem_info_get_dimensions
+#undef snd_ctl_elem_info_get_dimension
+#undef snd_ctl_elem_info_set_dimension
+#undef snd_ctl_elem_info_get_id
+#undef snd_ctl_elem_info_get_numid
+#undef snd_ctl_elem_info_get_interface
+#undef snd_ctl_elem_info_get_device
+#undef snd_ctl_elem_info_get_subdevice
+#undef snd_ctl_elem_info_get_name
+#undef snd_ctl_elem_info_get_index
+#undef snd_ctl_elem_info_set_id
+#undef snd_ctl_elem_info_set_numid
+#undef snd_ctl_elem_info_set_interface
+#undef snd_ctl_elem_info_set_device
+#undef snd_ctl_elem_info_set_subdevice
+#undef snd_ctl_elem_info_set_name
+#undef snd_ctl_elem_info_set_index
+#undef snd_ctl_add_integer_elem_set
+#undef snd_ctl_add_integer64_elem_set
+#undef snd_ctl_add_boolean_elem_set
+#undef snd_ctl_add_enumerated_elem_set
+#undef snd_ctl_add_bytes_elem_set
+#undef snd_ctl_elem_add_integer
+#undef snd_ctl_elem_add_integer64
+#undef snd_ctl_elem_add_boolean
+#undef snd_ctl_elem_add_enumerated
+#undef snd_ctl_elem_add_iec958
+#undef snd_ctl_elem_remove
+#undef snd_ctl_elem_value_sizeof
+#undef snd_ctl_elem_value_malloc
+#undef snd_ctl_elem_value_free
+#undef snd_ctl_elem_value_clear
+#undef snd_ctl_elem_value_copy
+#undef snd_ctl_elem_value_compare
+#undef snd_ctl_elem_value_get_id
+#undef snd_ctl_elem_value_get_numid
+#undef snd_ctl_elem_value_get_interface
+#undef snd_ctl_elem_value_get_device
+#undef snd_ctl_elem_value_get_subdevice
+#undef snd_ctl_elem_value_get_name
+#undef snd_ctl_elem_value_get_index
+#undef snd_ctl_elem_value_set_id
+#undef snd_ctl_elem_value_set_numid
+#undef snd_ctl_elem_value_set_interface
+#undef snd_ctl_elem_value_set_device
+#undef snd_ctl_elem_value_set_subdevice
+#undef snd_ctl_elem_value_set_name
+#undef snd_ctl_elem_value_set_index
+#undef snd_ctl_elem_value_get_boolean
+#undef snd_ctl_elem_value_get_integer
+#undef snd_ctl_elem_value_get_integer64
+#undef snd_ctl_elem_value_get_enumerated
+#undef snd_ctl_elem_value_get_byte
+#undef snd_ctl_elem_value_set_boolean
+#undef snd_ctl_elem_value_set_integer
+#undef snd_ctl_elem_value_set_integer64
+#undef snd_ctl_elem_value_set_enumerated
+#undef snd_ctl_elem_value_set_byte
+#undef snd_ctl_elem_set_bytes
+#undef snd_ctl_elem_value_get_bytes
+#undef snd_ctl_elem_value_get_iec958
+#undef snd_ctl_elem_value_set_iec958
+#undef snd_tlv_parse_dB_info
+#undef snd_tlv_get_dB_range
+#undef snd_tlv_convert_to_dB
+#undef snd_tlv_convert_from_dB
+#undef snd_ctl_get_dB_range
+#undef snd_ctl_convert_to_dB
+#undef snd_ctl_convert_from_dB
+#undef snd_hctl_compare_fast
+#undef snd_hctl_open
+#undef snd_hctl_open_ctl
+#undef snd_hctl_close
+#undef snd_hctl_nonblock
+#undef snd_hctl_poll_descriptors_count
+#undef snd_hctl_poll_descriptors
+#undef snd_hctl_poll_descriptors_revents
+#undef snd_hctl_get_count
+#undef snd_hctl_set_compare
+#undef snd_hctl_first_elem
+#undef snd_hctl_last_elem
+#undef snd_hctl_find_elem
+#undef snd_hctl_set_callback
+#undef snd_hctl_set_callback_private
+#undef snd_hctl_get_callback_private
+#undef snd_hctl_load
+#undef snd_hctl_free
+#undef snd_hctl_handle_events
+#undef snd_hctl_name
+#undef snd_hctl_wait
+#undef snd_hctl_ctl
+#undef snd_hctl_elem_next
+#undef snd_hctl_elem_prev
+#undef snd_hctl_elem_info
+#undef snd_hctl_elem_read
+#undef snd_hctl_elem_write
+#undef snd_hctl_elem_tlv_read
+#undef snd_hctl_elem_tlv_write
+#undef snd_hctl_elem_tlv_command
+#undef snd_hctl_elem_get_hctl
+#undef snd_hctl_elem_get_id
+#undef snd_hctl_elem_get_numid
+#undef snd_hctl_elem_get_interface
+#undef snd_hctl_elem_get_device
+#undef snd_hctl_elem_get_subdevice
+#undef snd_hctl_elem_get_name
+#undef snd_hctl_elem_get_index
+#undef snd_hctl_elem_set_callback
+#undef snd_hctl_elem_get_callback_private
+#undef snd_hctl_elem_set_callback_private
+#undef snd_sctl_build
+#undef snd_sctl_free
+#undef snd_sctl_install
+#undef snd_sctl_remove
+#undef snd_mixer_open
+#undef snd_mixer_close
+#undef snd_mixer_first_elem
+#undef snd_mixer_last_elem
+#undef snd_mixer_handle_events
+#undef snd_mixer_attach
+#undef snd_mixer_attach_hctl
+#undef snd_mixer_detach
+#undef snd_mixer_detach_hctl
+#undef snd_mixer_get_hctl
+#undef snd_mixer_poll_descriptors_count
+#undef snd_mixer_poll_descriptors
+#undef snd_mixer_poll_descriptors_revents
+#undef snd_mixer_load
+#undef snd_mixer_free
+#undef snd_mixer_wait
+#undef snd_mixer_set_compare
+#undef snd_mixer_set_callback
+#undef snd_mixer_get_callback_private
+#undef snd_mixer_set_callback_private
+#undef snd_mixer_get_count
+#undef snd_mixer_class_unregister
+#undef snd_mixer_elem_next
+#undef snd_mixer_elem_prev
+#undef snd_mixer_elem_set_callback
+#undef snd_mixer_elem_get_callback_private
+#undef snd_mixer_elem_set_callback_private
+#undef snd_mixer_elem_get_type
+#undef snd_mixer_class_register
+#undef snd_mixer_elem_new
+#undef snd_mixer_elem_add
+#undef snd_mixer_elem_remove
+#undef snd_mixer_elem_free
+#undef snd_mixer_elem_info
+#undef snd_mixer_elem_value
+#undef snd_mixer_elem_attach
+#undef snd_mixer_elem_detach
+#undef snd_mixer_elem_empty
+#undef snd_mixer_elem_get_private
+#undef snd_mixer_class_sizeof
+#undef snd_mixer_class_malloc
+#undef snd_mixer_class_free
+#undef snd_mixer_class_copy
+#undef snd_mixer_class_get_mixer
+#undef snd_mixer_class_get_event
+#undef snd_mixer_class_get_private
+#undef snd_mixer_class_get_compare
+#undef snd_mixer_class_set_event
+#undef snd_mixer_class_set_private
+#undef snd_mixer_class_set_private_free
+#undef snd_mixer_class_set_compare
+#undef snd_mixer_selem_channel_name
+#undef snd_mixer_selem_register
+#undef snd_mixer_selem_get_id
+#undef snd_mixer_selem_get_name
+#undef snd_mixer_selem_get_index
+#undef snd_mixer_find_selem
+#undef snd_mixer_selem_is_active
+#undef snd_mixer_selem_is_playback_mono
+#undef snd_mixer_selem_has_playback_channel
+#undef snd_mixer_selem_is_capture_mono
+#undef snd_mixer_selem_has_capture_channel
+#undef snd_mixer_selem_get_capture_group
+#undef snd_mixer_selem_has_common_volume
+#undef snd_mixer_selem_has_playback_volume
+#undef snd_mixer_selem_has_playback_volume_joined
+#undef snd_mixer_selem_has_capture_volume
+#undef snd_mixer_selem_has_capture_volume_joined
+#undef snd_mixer_selem_has_common_switch
+#undef snd_mixer_selem_has_playback_switch
+#undef snd_mixer_selem_has_playback_switch_joined
+#undef snd_mixer_selem_has_capture_switch
+#undef snd_mixer_selem_has_capture_switch_joined
+#undef snd_mixer_selem_has_capture_switch_exclusive
+#undef snd_mixer_selem_ask_playback_vol_dB
+#undef snd_mixer_selem_ask_capture_vol_dB
+#undef snd_mixer_selem_ask_playback_dB_vol
+#undef snd_mixer_selem_ask_capture_dB_vol
+#undef snd_mixer_selem_get_playback_volume
+#undef snd_mixer_selem_get_capture_volume
+#undef snd_mixer_selem_get_playback_dB
+#undef snd_mixer_selem_get_capture_dB
+#undef snd_mixer_selem_get_playback_switch
+#undef snd_mixer_selem_get_capture_switch
+#undef snd_mixer_selem_set_playback_volume
+#undef snd_mixer_selem_set_capture_volume
+#undef snd_mixer_selem_set_playback_dB
+#undef snd_mixer_selem_set_capture_dB
+#undef snd_mixer_selem_set_playback_volume_all
+#undef snd_mixer_selem_set_capture_volume_all
+#undef snd_mixer_selem_set_playback_dB_all
+#undef snd_mixer_selem_set_capture_dB_all
+#undef snd_mixer_selem_set_playback_switch
+#undef snd_mixer_selem_set_capture_switch
+#undef snd_mixer_selem_set_playback_switch_all
+#undef snd_mixer_selem_set_capture_switch_all
+#undef snd_mixer_selem_get_playback_volume_range
+#undef snd_mixer_selem_get_playback_dB_range
+#undef snd_mixer_selem_set_playback_volume_range
+#undef snd_mixer_selem_get_capture_volume_range
+#undef snd_mixer_selem_get_capture_dB_range
+#undef snd_mixer_selem_set_capture_volume_range
+#undef snd_mixer_selem_is_enumerated
+#undef snd_mixer_selem_is_enum_playback
+#undef snd_mixer_selem_is_enum_capture
+#undef snd_mixer_selem_get_enum_items
+#undef snd_mixer_selem_get_enum_item_name
+#undef snd_mixer_selem_get_enum_item
+#undef snd_mixer_selem_set_enum_item
+#undef snd_mixer_selem_id_sizeof
+#undef snd_mixer_selem_id_malloc
+#undef snd_mixer_selem_id_free
+#undef snd_mixer_selem_id_copy
+#undef snd_mixer_selem_id_get_name
+#undef snd_mixer_selem_id_get_index
+#undef snd_mixer_selem_id_set_name
+#undef snd_mixer_selem_id_set_index
+#undef snd_mixer_selem_id_parse
+#undef snd_seq_open
+#undef snd_seq_open_lconf
+#undef snd_seq_name
+#undef snd_seq_type
+#undef snd_seq_close
+#undef snd_seq_poll_descriptors_count
+#undef snd_seq_poll_descriptors
+#undef snd_seq_poll_descriptors_revents
+#undef snd_seq_nonblock
+#undef snd_seq_client_id
+#undef snd_seq_get_output_buffer_size
+#undef snd_seq_get_input_buffer_size
+#undef snd_seq_set_output_buffer_size
+#undef snd_seq_set_input_buffer_size
+#undef snd_seq_system_info_sizeof
+#undef snd_seq_system_info_malloc
+#undef snd_seq_system_info_free
+#undef snd_seq_system_info_copy
+#undef snd_seq_system_info_get_queues
+#undef snd_seq_system_info_get_clients
+#undef snd_seq_system_info_get_ports
+#undef snd_seq_system_info_get_channels
+#undef snd_seq_system_info_get_cur_clients
+#undef snd_seq_system_info_get_cur_queues
+#undef snd_seq_system_info
+#undef snd_seq_client_info_sizeof
+#undef snd_seq_client_info_malloc
+#undef snd_seq_client_info_free
+#undef snd_seq_client_info_copy
+#undef snd_seq_client_info_get_client
+#undef snd_seq_client_info_get_type
+#undef snd_seq_client_info_get_name
+#undef snd_seq_client_info_get_broadcast_filter
+#undef snd_seq_client_info_get_error_bounce
+#undef snd_seq_client_info_get_card
+#undef snd_seq_client_info_get_pid
+#undef snd_seq_client_info_get_event_filter
+#undef snd_seq_client_info_get_num_ports
+#undef snd_seq_client_info_get_event_lost
+#undef snd_seq_client_info_set_client
+#undef snd_seq_client_info_set_name
+#undef snd_seq_client_info_set_broadcast_filter
+#undef snd_seq_client_info_set_error_bounce
+#undef snd_seq_client_info_set_event_filter
+#undef snd_seq_client_info_event_filter_clear
+#undef snd_seq_client_info_event_filter_add
+#undef snd_seq_client_info_event_filter_del
+#undef snd_seq_client_info_event_filter_check
+#undef snd_seq_get_client_info
+#undef snd_seq_get_any_client_info
+#undef snd_seq_set_client_info
+#undef snd_seq_query_next_client
+#undef snd_seq_client_pool_sizeof
+#undef snd_seq_client_pool_malloc
+#undef snd_seq_client_pool_free
+#undef snd_seq_client_pool_copy
+#undef snd_seq_client_pool_get_client
+#undef snd_seq_client_pool_get_output_pool
+#undef snd_seq_client_pool_get_input_pool
+#undef snd_seq_client_pool_get_output_room
+#undef snd_seq_client_pool_get_output_free
+#undef snd_seq_client_pool_get_input_free
+#undef snd_seq_client_pool_set_output_pool
+#undef snd_seq_client_pool_set_input_pool
+#undef snd_seq_client_pool_set_output_room
+#undef snd_seq_get_client_pool
+#undef snd_seq_set_client_pool
+#undef snd_seq_port_info_sizeof
+#undef snd_seq_port_info_malloc
+#undef snd_seq_port_info_free
+#undef snd_seq_port_info_copy
+#undef snd_seq_port_info_get_client
+#undef snd_seq_port_info_get_port
+#undef snd_seq_port_info_get_addr
+#undef snd_seq_port_info_get_name
+#undef snd_seq_port_info_get_capability
+#undef snd_seq_port_info_get_type
+#undef snd_seq_port_info_get_midi_channels
+#undef snd_seq_port_info_get_midi_voices
+#undef snd_seq_port_info_get_synth_voices
+#undef snd_seq_port_info_get_read_use
+#undef snd_seq_port_info_get_write_use
+#undef snd_seq_port_info_get_port_specified
+#undef snd_seq_port_info_get_timestamping
+#undef snd_seq_port_info_get_timestamp_real
+#undef snd_seq_port_info_get_timestamp_queue
+#undef snd_seq_port_info_set_client
+#undef snd_seq_port_info_set_port
+#undef snd_seq_port_info_set_addr
+#undef snd_seq_port_info_set_name
+#undef snd_seq_port_info_set_capability
+#undef snd_seq_port_info_set_type
+#undef snd_seq_port_info_set_midi_channels
+#undef snd_seq_port_info_set_midi_voices
+#undef snd_seq_port_info_set_synth_voices
+#undef snd_seq_port_info_set_port_specified
+#undef snd_seq_port_info_set_timestamping
+#undef snd_seq_port_info_set_timestamp_real
+#undef snd_seq_port_info_set_timestamp_queue
+#undef snd_seq_create_port
+#undef snd_seq_delete_port
+#undef snd_seq_get_port_info
+#undef snd_seq_get_any_port_info
+#undef snd_seq_set_port_info
+#undef snd_seq_query_next_port
+#undef snd_seq_port_subscribe_sizeof
+#undef snd_seq_port_subscribe_malloc
+#undef snd_seq_port_subscribe_free
+#undef snd_seq_port_subscribe_copy
+#undef snd_seq_port_subscribe_get_sender
+#undef snd_seq_port_subscribe_get_dest
+#undef snd_seq_port_subscribe_get_queue
+#undef snd_seq_port_subscribe_get_exclusive
+#undef snd_seq_port_subscribe_get_time_update
+#undef snd_seq_port_subscribe_get_time_real
+#undef snd_seq_port_subscribe_set_sender
+#undef snd_seq_port_subscribe_set_dest
+#undef snd_seq_port_subscribe_set_queue
+#undef snd_seq_port_subscribe_set_exclusive
+#undef snd_seq_port_subscribe_set_time_update
+#undef snd_seq_port_subscribe_set_time_real
+#undef snd_seq_get_port_subscription
+#undef snd_seq_subscribe_port
+#undef snd_seq_unsubscribe_port
+#undef snd_seq_query_subscribe_sizeof
+#undef snd_seq_query_subscribe_malloc
+#undef snd_seq_query_subscribe_free
+#undef snd_seq_query_subscribe_copy
+#undef snd_seq_query_subscribe_get_client
+#undef snd_seq_query_subscribe_get_port
+#undef snd_seq_query_subscribe_get_root
+#undef snd_seq_query_subscribe_get_type
+#undef snd_seq_query_subscribe_get_index
+#undef snd_seq_query_subscribe_get_num_subs
+#undef snd_seq_query_subscribe_get_addr
+#undef snd_seq_query_subscribe_get_queue
+#undef snd_seq_query_subscribe_get_exclusive
+#undef snd_seq_query_subscribe_get_time_update
+#undef snd_seq_query_subscribe_get_time_real
+#undef snd_seq_query_subscribe_set_client
+#undef snd_seq_query_subscribe_set_port
+#undef snd_seq_query_subscribe_set_root
+#undef snd_seq_query_subscribe_set_type
+#undef snd_seq_query_subscribe_set_index
+#undef snd_seq_query_port_subscribers
+#undef snd_seq_queue_info_sizeof
+#undef snd_seq_queue_info_malloc
+#undef snd_seq_queue_info_free
+#undef snd_seq_queue_info_copy
+#undef snd_seq_queue_info_get_queue
+#undef snd_seq_queue_info_get_name
+#undef snd_seq_queue_info_get_owner
+#undef snd_seq_queue_info_get_locked
+#undef snd_seq_queue_info_get_flags
+#undef snd_seq_queue_info_set_name
+#undef snd_seq_queue_info_set_owner
+#undef snd_seq_queue_info_set_locked
+#undef snd_seq_queue_info_set_flags
+#undef snd_seq_create_queue
+#undef snd_seq_alloc_named_queue
+#undef snd_seq_alloc_queue
+#undef snd_seq_free_queue
+#undef snd_seq_get_queue_info
+#undef snd_seq_set_queue_info
+#undef snd_seq_query_named_queue
+#undef snd_seq_get_queue_usage
+#undef snd_seq_set_queue_usage
+#undef snd_seq_queue_status_sizeof
+#undef snd_seq_queue_status_malloc
+#undef snd_seq_queue_status_free
+#undef snd_seq_queue_status_copy
+#undef snd_seq_queue_status_get_queue
+#undef snd_seq_queue_status_get_events
+#undef snd_seq_queue_status_get_tick_time
+#undef snd_seq_queue_status_get_real_time
+#undef snd_seq_queue_status_get_status
+#undef snd_seq_get_queue_status
+#undef snd_seq_queue_tempo_sizeof
+#undef snd_seq_queue_tempo_malloc
+#undef snd_seq_queue_tempo_free
+#undef snd_seq_queue_tempo_copy
+#undef snd_seq_queue_tempo_get_queue
+#undef snd_seq_queue_tempo_get_tempo
+#undef snd_seq_queue_tempo_get_ppq
+#undef snd_seq_queue_tempo_get_skew
+#undef snd_seq_queue_tempo_get_skew_base
+#undef snd_seq_queue_tempo_set_tempo
+#undef snd_seq_queue_tempo_set_ppq
+#undef snd_seq_queue_tempo_set_skew
+#undef snd_seq_queue_tempo_set_skew_base
+#undef snd_seq_get_queue_tempo
+#undef snd_seq_set_queue_tempo
+#undef snd_seq_queue_timer_sizeof
+#undef snd_seq_queue_timer_malloc
+#undef snd_seq_queue_timer_free
+#undef snd_seq_queue_timer_copy
+#undef snd_seq_queue_timer_get_queue
+#undef snd_seq_queue_timer_get_type
+#undef snd_seq_queue_timer_get_id
+#undef snd_seq_queue_timer_get_resolution
+#undef snd_seq_queue_timer_set_type
+#undef snd_seq_queue_timer_set_id
+#undef snd_seq_queue_timer_set_resolution
+#undef snd_seq_get_queue_timer
+#undef snd_seq_set_queue_timer
+#undef snd_seq_free_event
+#undef snd_seq_event_length
+#undef snd_seq_event_output
+#undef snd_seq_event_output_buffer
+#undef snd_seq_event_output_direct
+#undef snd_seq_event_input
+#undef snd_seq_event_input_pending
+#undef snd_seq_drain_output
+#undef snd_seq_event_output_pending
+#undef snd_seq_extract_output
+#undef snd_seq_drop_output
+#undef snd_seq_drop_output_buffer
+#undef snd_seq_drop_input
+#undef snd_seq_drop_input_buffer
+#undef snd_seq_remove_events_sizeof
+#undef snd_seq_remove_events_malloc
+#undef snd_seq_remove_events_free
+#undef snd_seq_remove_events_copy
+#undef snd_seq_remove_events_get_condition
+#undef snd_seq_remove_events_get_queue
+#undef snd_seq_remove_events_get_time
+#undef snd_seq_remove_events_get_dest
+#undef snd_seq_remove_events_get_channel
+#undef snd_seq_remove_events_get_event_type
+#undef snd_seq_remove_events_get_tag
+#undef snd_seq_remove_events_set_condition
+#undef snd_seq_remove_events_set_queue
+#undef snd_seq_remove_events_set_time
+#undef snd_seq_remove_events_set_dest
+#undef snd_seq_remove_events_set_channel
+#undef snd_seq_remove_events_set_event_type
+#undef snd_seq_remove_events_set_tag
+#undef snd_seq_remove_events
+#undef snd_seq_set_bit
+#undef snd_seq_unset_bit
+#undef snd_seq_change_bit
+#undef snd_seq_get_bit
+#undef snd_seq_control_queue
+#undef snd_seq_create_simple_port
+#undef snd_seq_delete_simple_port
+#undef snd_seq_connect_from
+#undef snd_seq_connect_to
+#undef snd_seq_disconnect_from
+#undef snd_seq_disconnect_to
+#undef snd_seq_set_client_name
+#undef snd_seq_set_client_event_filter
+#undef snd_seq_set_client_pool_output
+#undef snd_seq_set_client_pool_output_room
+#undef snd_seq_set_client_pool_input
+#undef snd_seq_sync_output_queue
+#undef snd_seq_parse_address
+#undef snd_seq_reset_pool_output
+#undef snd_seq_reset_pool_input
+#undef snd_midi_event_new
+#undef snd_midi_event_resize_buffer
+#undef snd_midi_event_free
+#undef snd_midi_event_init
+#undef snd_midi_event_reset_encode
+#undef snd_midi_event_reset_decode
+#undef snd_midi_event_no_status
+#undef snd_midi_event_encode
+#undef snd_midi_event_encode_byte
+#undef snd_midi_event_decode
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define snd_asoundlib_version snd_asoundlib_version_dylibloader_wrapper_asound
+#define snd_dlpath snd_dlpath_dylibloader_wrapper_asound
+#define snd_dlopen snd_dlopen_dylibloader_wrapper_asound
+#define snd_dlsym snd_dlsym_dylibloader_wrapper_asound
+#define snd_dlclose snd_dlclose_dylibloader_wrapper_asound
+#define snd_async_add_handler snd_async_add_handler_dylibloader_wrapper_asound
+#define snd_async_del_handler snd_async_del_handler_dylibloader_wrapper_asound
+#define snd_async_handler_get_fd snd_async_handler_get_fd_dylibloader_wrapper_asound
+#define snd_async_handler_get_signo snd_async_handler_get_signo_dylibloader_wrapper_asound
+#define snd_async_handler_get_callback_private snd_async_handler_get_callback_private_dylibloader_wrapper_asound
+#define snd_shm_area_create snd_shm_area_create_dylibloader_wrapper_asound
+#define snd_shm_area_share snd_shm_area_share_dylibloader_wrapper_asound
+#define snd_shm_area_destroy snd_shm_area_destroy_dylibloader_wrapper_asound
+#define snd_user_file snd_user_file_dylibloader_wrapper_asound
+#define snd_input_stdio_open snd_input_stdio_open_dylibloader_wrapper_asound
+#define snd_input_stdio_attach snd_input_stdio_attach_dylibloader_wrapper_asound
+#define snd_input_buffer_open snd_input_buffer_open_dylibloader_wrapper_asound
+#define snd_input_close snd_input_close_dylibloader_wrapper_asound
+#define snd_input_scanf snd_input_scanf_dylibloader_wrapper_asound
+#define snd_input_gets snd_input_gets_dylibloader_wrapper_asound
+#define snd_input_getc snd_input_getc_dylibloader_wrapper_asound
+#define snd_input_ungetc snd_input_ungetc_dylibloader_wrapper_asound
+#define snd_output_stdio_open snd_output_stdio_open_dylibloader_wrapper_asound
+#define snd_output_stdio_attach snd_output_stdio_attach_dylibloader_wrapper_asound
+#define snd_output_buffer_open snd_output_buffer_open_dylibloader_wrapper_asound
+#define snd_output_buffer_string snd_output_buffer_string_dylibloader_wrapper_asound
+#define snd_output_close snd_output_close_dylibloader_wrapper_asound
+#define snd_output_printf snd_output_printf_dylibloader_wrapper_asound
+#define snd_output_vprintf snd_output_vprintf_dylibloader_wrapper_asound
+#define snd_output_puts snd_output_puts_dylibloader_wrapper_asound
+#define snd_output_putc snd_output_putc_dylibloader_wrapper_asound
+#define snd_output_flush snd_output_flush_dylibloader_wrapper_asound
+#define snd_strerror snd_strerror_dylibloader_wrapper_asound
+#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_wrapper_asound
+#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_wrapper_asound
+#define snd_config_topdir snd_config_topdir_dylibloader_wrapper_asound
+#define snd_config_top snd_config_top_dylibloader_wrapper_asound
+#define snd_config_load snd_config_load_dylibloader_wrapper_asound
+#define snd_config_load_override snd_config_load_override_dylibloader_wrapper_asound
+#define snd_config_save snd_config_save_dylibloader_wrapper_asound
+#define snd_config_update snd_config_update_dylibloader_wrapper_asound
+#define snd_config_update_r snd_config_update_r_dylibloader_wrapper_asound
+#define snd_config_update_free snd_config_update_free_dylibloader_wrapper_asound
+#define snd_config_update_free_global snd_config_update_free_global_dylibloader_wrapper_asound
+#define snd_config_update_ref snd_config_update_ref_dylibloader_wrapper_asound
+#define snd_config_ref snd_config_ref_dylibloader_wrapper_asound
+#define snd_config_unref snd_config_unref_dylibloader_wrapper_asound
+#define snd_config_search snd_config_search_dylibloader_wrapper_asound
+#define snd_config_searchv snd_config_searchv_dylibloader_wrapper_asound
+#define snd_config_search_definition snd_config_search_definition_dylibloader_wrapper_asound
+#define snd_config_expand snd_config_expand_dylibloader_wrapper_asound
+#define snd_config_evaluate snd_config_evaluate_dylibloader_wrapper_asound
+#define snd_config_add snd_config_add_dylibloader_wrapper_asound
+#define snd_config_add_before snd_config_add_before_dylibloader_wrapper_asound
+#define snd_config_add_after snd_config_add_after_dylibloader_wrapper_asound
+#define snd_config_remove snd_config_remove_dylibloader_wrapper_asound
+#define snd_config_delete snd_config_delete_dylibloader_wrapper_asound
+#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_wrapper_asound
+#define snd_config_copy snd_config_copy_dylibloader_wrapper_asound
+#define snd_config_make snd_config_make_dylibloader_wrapper_asound
+#define snd_config_make_integer snd_config_make_integer_dylibloader_wrapper_asound
+#define snd_config_make_integer64 snd_config_make_integer64_dylibloader_wrapper_asound
+#define snd_config_make_real snd_config_make_real_dylibloader_wrapper_asound
+#define snd_config_make_string snd_config_make_string_dylibloader_wrapper_asound
+#define snd_config_make_pointer snd_config_make_pointer_dylibloader_wrapper_asound
+#define snd_config_make_compound snd_config_make_compound_dylibloader_wrapper_asound
+#define snd_config_imake_integer snd_config_imake_integer_dylibloader_wrapper_asound
+#define snd_config_imake_integer64 snd_config_imake_integer64_dylibloader_wrapper_asound
+#define snd_config_imake_real snd_config_imake_real_dylibloader_wrapper_asound
+#define snd_config_imake_string snd_config_imake_string_dylibloader_wrapper_asound
+#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_wrapper_asound
+#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_wrapper_asound
+#define snd_config_get_type snd_config_get_type_dylibloader_wrapper_asound
+#define snd_config_is_array snd_config_is_array_dylibloader_wrapper_asound
+#define snd_config_set_id snd_config_set_id_dylibloader_wrapper_asound
+#define snd_config_set_integer snd_config_set_integer_dylibloader_wrapper_asound
+#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_wrapper_asound
+#define snd_config_set_real snd_config_set_real_dylibloader_wrapper_asound
+#define snd_config_set_string snd_config_set_string_dylibloader_wrapper_asound
+#define snd_config_set_ascii snd_config_set_ascii_dylibloader_wrapper_asound
+#define snd_config_set_pointer snd_config_set_pointer_dylibloader_wrapper_asound
+#define snd_config_get_id snd_config_get_id_dylibloader_wrapper_asound
+#define snd_config_get_integer snd_config_get_integer_dylibloader_wrapper_asound
+#define snd_config_get_integer64 snd_config_get_integer64_dylibloader_wrapper_asound
+#define snd_config_get_real snd_config_get_real_dylibloader_wrapper_asound
+#define snd_config_get_ireal snd_config_get_ireal_dylibloader_wrapper_asound
+#define snd_config_get_string snd_config_get_string_dylibloader_wrapper_asound
+#define snd_config_get_ascii snd_config_get_ascii_dylibloader_wrapper_asound
+#define snd_config_get_pointer snd_config_get_pointer_dylibloader_wrapper_asound
+#define snd_config_test_id snd_config_test_id_dylibloader_wrapper_asound
+#define snd_config_iterator_first snd_config_iterator_first_dylibloader_wrapper_asound
+#define snd_config_iterator_next snd_config_iterator_next_dylibloader_wrapper_asound
+#define snd_config_iterator_end snd_config_iterator_end_dylibloader_wrapper_asound
+#define snd_config_iterator_entry snd_config_iterator_entry_dylibloader_wrapper_asound
+#define snd_config_get_bool_ascii snd_config_get_bool_ascii_dylibloader_wrapper_asound
+#define snd_config_get_bool snd_config_get_bool_dylibloader_wrapper_asound
+#define snd_config_get_ctl_iface_ascii snd_config_get_ctl_iface_ascii_dylibloader_wrapper_asound
+#define snd_config_get_ctl_iface snd_config_get_ctl_iface_dylibloader_wrapper_asound
+#define snd_names_list snd_names_list_dylibloader_wrapper_asound
+#define snd_names_list_free snd_names_list_free_dylibloader_wrapper_asound
+#define snd_pcm_open snd_pcm_open_dylibloader_wrapper_asound
+#define snd_pcm_open_lconf snd_pcm_open_lconf_dylibloader_wrapper_asound
+#define snd_pcm_open_fallback snd_pcm_open_fallback_dylibloader_wrapper_asound
+#define snd_pcm_close snd_pcm_close_dylibloader_wrapper_asound
+#define snd_pcm_name snd_pcm_name_dylibloader_wrapper_asound
+#define snd_pcm_type snd_pcm_type_dylibloader_wrapper_asound
+#define snd_pcm_stream snd_pcm_stream_dylibloader_wrapper_asound
+#define snd_pcm_poll_descriptors_count snd_pcm_poll_descriptors_count_dylibloader_wrapper_asound
+#define snd_pcm_poll_descriptors snd_pcm_poll_descriptors_dylibloader_wrapper_asound
+#define snd_pcm_poll_descriptors_revents snd_pcm_poll_descriptors_revents_dylibloader_wrapper_asound
+#define snd_pcm_nonblock snd_pcm_nonblock_dylibloader_wrapper_asound
+#define snd_async_add_pcm_handler snd_async_add_pcm_handler_dylibloader_wrapper_asound
+#define snd_async_handler_get_pcm snd_async_handler_get_pcm_dylibloader_wrapper_asound
+#define snd_pcm_info snd_pcm_info_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_current snd_pcm_hw_params_current_dylibloader_wrapper_asound
+#define snd_pcm_hw_params snd_pcm_hw_params_dylibloader_wrapper_asound
+#define snd_pcm_hw_free snd_pcm_hw_free_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_current snd_pcm_sw_params_current_dylibloader_wrapper_asound
+#define snd_pcm_sw_params snd_pcm_sw_params_dylibloader_wrapper_asound
+#define snd_pcm_prepare snd_pcm_prepare_dylibloader_wrapper_asound
+#define snd_pcm_reset snd_pcm_reset_dylibloader_wrapper_asound
+#define snd_pcm_status snd_pcm_status_dylibloader_wrapper_asound
+#define snd_pcm_start snd_pcm_start_dylibloader_wrapper_asound
+#define snd_pcm_drop snd_pcm_drop_dylibloader_wrapper_asound
+#define snd_pcm_drain snd_pcm_drain_dylibloader_wrapper_asound
+#define snd_pcm_pause snd_pcm_pause_dylibloader_wrapper_asound
+#define snd_pcm_state snd_pcm_state_dylibloader_wrapper_asound
+#define snd_pcm_hwsync snd_pcm_hwsync_dylibloader_wrapper_asound
+#define snd_pcm_delay snd_pcm_delay_dylibloader_wrapper_asound
+#define snd_pcm_resume snd_pcm_resume_dylibloader_wrapper_asound
+#define snd_pcm_htimestamp snd_pcm_htimestamp_dylibloader_wrapper_asound
+#define snd_pcm_avail snd_pcm_avail_dylibloader_wrapper_asound
+#define snd_pcm_avail_update snd_pcm_avail_update_dylibloader_wrapper_asound
+#define snd_pcm_avail_delay snd_pcm_avail_delay_dylibloader_wrapper_asound
+#define snd_pcm_rewindable snd_pcm_rewindable_dylibloader_wrapper_asound
+#define snd_pcm_rewind snd_pcm_rewind_dylibloader_wrapper_asound
+#define snd_pcm_forwardable snd_pcm_forwardable_dylibloader_wrapper_asound
+#define snd_pcm_forward snd_pcm_forward_dylibloader_wrapper_asound
+#define snd_pcm_writei snd_pcm_writei_dylibloader_wrapper_asound
+#define snd_pcm_readi snd_pcm_readi_dylibloader_wrapper_asound
+#define snd_pcm_writen snd_pcm_writen_dylibloader_wrapper_asound
+#define snd_pcm_readn snd_pcm_readn_dylibloader_wrapper_asound
+#define snd_pcm_wait snd_pcm_wait_dylibloader_wrapper_asound
+#define snd_pcm_link snd_pcm_link_dylibloader_wrapper_asound
+#define snd_pcm_unlink snd_pcm_unlink_dylibloader_wrapper_asound
+#define snd_pcm_query_chmaps snd_pcm_query_chmaps_dylibloader_wrapper_asound
+#define snd_pcm_query_chmaps_from_hw snd_pcm_query_chmaps_from_hw_dylibloader_wrapper_asound
+#define snd_pcm_free_chmaps snd_pcm_free_chmaps_dylibloader_wrapper_asound
+#define snd_pcm_get_chmap snd_pcm_get_chmap_dylibloader_wrapper_asound
+#define snd_pcm_set_chmap snd_pcm_set_chmap_dylibloader_wrapper_asound
+#define snd_pcm_chmap_type_name snd_pcm_chmap_type_name_dylibloader_wrapper_asound
+#define snd_pcm_chmap_name snd_pcm_chmap_name_dylibloader_wrapper_asound
+#define snd_pcm_chmap_long_name snd_pcm_chmap_long_name_dylibloader_wrapper_asound
+#define snd_pcm_chmap_print snd_pcm_chmap_print_dylibloader_wrapper_asound
+#define snd_pcm_chmap_from_string snd_pcm_chmap_from_string_dylibloader_wrapper_asound
+#define snd_pcm_chmap_parse_string snd_pcm_chmap_parse_string_dylibloader_wrapper_asound
+#define snd_pcm_recover snd_pcm_recover_dylibloader_wrapper_asound
+#define snd_pcm_set_params snd_pcm_set_params_dylibloader_wrapper_asound
+#define snd_pcm_get_params snd_pcm_get_params_dylibloader_wrapper_asound
+#define snd_pcm_info_sizeof snd_pcm_info_sizeof_dylibloader_wrapper_asound
+#define snd_pcm_info_malloc snd_pcm_info_malloc_dylibloader_wrapper_asound
+#define snd_pcm_info_free snd_pcm_info_free_dylibloader_wrapper_asound
+#define snd_pcm_info_copy snd_pcm_info_copy_dylibloader_wrapper_asound
+#define snd_pcm_info_get_device snd_pcm_info_get_device_dylibloader_wrapper_asound
+#define snd_pcm_info_get_subdevice snd_pcm_info_get_subdevice_dylibloader_wrapper_asound
+#define snd_pcm_info_get_stream snd_pcm_info_get_stream_dylibloader_wrapper_asound
+#define snd_pcm_info_get_card snd_pcm_info_get_card_dylibloader_wrapper_asound
+#define snd_pcm_info_get_id snd_pcm_info_get_id_dylibloader_wrapper_asound
+#define snd_pcm_info_get_name snd_pcm_info_get_name_dylibloader_wrapper_asound
+#define snd_pcm_info_get_subdevice_name snd_pcm_info_get_subdevice_name_dylibloader_wrapper_asound
+#define snd_pcm_info_get_class snd_pcm_info_get_class_dylibloader_wrapper_asound
+#define snd_pcm_info_get_subclass snd_pcm_info_get_subclass_dylibloader_wrapper_asound
+#define snd_pcm_info_get_subdevices_count snd_pcm_info_get_subdevices_count_dylibloader_wrapper_asound
+#define snd_pcm_info_get_subdevices_avail snd_pcm_info_get_subdevices_avail_dylibloader_wrapper_asound
+#define snd_pcm_info_get_sync snd_pcm_info_get_sync_dylibloader_wrapper_asound
+#define snd_pcm_info_set_device snd_pcm_info_set_device_dylibloader_wrapper_asound
+#define snd_pcm_info_set_subdevice snd_pcm_info_set_subdevice_dylibloader_wrapper_asound
+#define snd_pcm_info_set_stream snd_pcm_info_set_stream_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_any snd_pcm_hw_params_any_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_can_mmap_sample_resolution snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_is_double snd_pcm_hw_params_is_double_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_is_batch snd_pcm_hw_params_is_batch_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_is_block_transfer snd_pcm_hw_params_is_block_transfer_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_is_monotonic snd_pcm_hw_params_is_monotonic_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_can_overrange snd_pcm_hw_params_can_overrange_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_can_pause snd_pcm_hw_params_can_pause_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_can_resume snd_pcm_hw_params_can_resume_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_is_half_duplex snd_pcm_hw_params_is_half_duplex_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_is_joint_duplex snd_pcm_hw_params_is_joint_duplex_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_can_sync_start snd_pcm_hw_params_can_sync_start_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_can_disable_period_wakeup snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_supports_audio_wallclock_ts snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_supports_audio_ts_type snd_pcm_hw_params_supports_audio_ts_type_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_rate_numden snd_pcm_hw_params_get_rate_numden_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_sbits snd_pcm_hw_params_get_sbits_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_fifo_size snd_pcm_hw_params_get_fifo_size_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_sizeof snd_pcm_hw_params_sizeof_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_free snd_pcm_hw_params_free_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_copy snd_pcm_hw_params_copy_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_access snd_pcm_hw_params_get_access_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_access snd_pcm_hw_params_test_access_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_access_first snd_pcm_hw_params_set_access_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_access_last snd_pcm_hw_params_set_access_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_access_mask snd_pcm_hw_params_set_access_mask_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_access_mask snd_pcm_hw_params_get_access_mask_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_format snd_pcm_hw_params_get_format_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_format snd_pcm_hw_params_test_format_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_format_first snd_pcm_hw_params_set_format_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_format_last snd_pcm_hw_params_set_format_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_format_mask snd_pcm_hw_params_set_format_mask_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_format_mask snd_pcm_hw_params_get_format_mask_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_subformat snd_pcm_hw_params_get_subformat_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_subformat snd_pcm_hw_params_test_subformat_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_subformat snd_pcm_hw_params_set_subformat_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_subformat_first snd_pcm_hw_params_set_subformat_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_subformat_last snd_pcm_hw_params_set_subformat_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_subformat_mask snd_pcm_hw_params_set_subformat_mask_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_subformat_mask snd_pcm_hw_params_get_subformat_mask_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_channels snd_pcm_hw_params_get_channels_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_channels_min snd_pcm_hw_params_get_channels_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_channels_max snd_pcm_hw_params_get_channels_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_channels snd_pcm_hw_params_test_channels_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_channels snd_pcm_hw_params_set_channels_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_channels_min snd_pcm_hw_params_set_channels_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_channels_max snd_pcm_hw_params_set_channels_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_channels_minmax snd_pcm_hw_params_set_channels_minmax_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_channels_near snd_pcm_hw_params_set_channels_near_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_channels_first snd_pcm_hw_params_set_channels_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_channels_last snd_pcm_hw_params_set_channels_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_rate snd_pcm_hw_params_get_rate_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_rate_min snd_pcm_hw_params_get_rate_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_rate_max snd_pcm_hw_params_get_rate_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_rate snd_pcm_hw_params_test_rate_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_rate snd_pcm_hw_params_set_rate_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_rate_min snd_pcm_hw_params_set_rate_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_rate_max snd_pcm_hw_params_set_rate_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_rate_minmax snd_pcm_hw_params_set_rate_minmax_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_rate_near snd_pcm_hw_params_set_rate_near_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_rate_first snd_pcm_hw_params_set_rate_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_rate_last snd_pcm_hw_params_set_rate_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_rate_resample snd_pcm_hw_params_set_rate_resample_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_rate_resample snd_pcm_hw_params_get_rate_resample_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_export_buffer snd_pcm_hw_params_set_export_buffer_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_export_buffer snd_pcm_hw_params_get_export_buffer_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_wakeup snd_pcm_hw_params_set_period_wakeup_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_period_wakeup snd_pcm_hw_params_get_period_wakeup_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_period_time snd_pcm_hw_params_get_period_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_period_time_min snd_pcm_hw_params_get_period_time_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_period_time_max snd_pcm_hw_params_get_period_time_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_period_time snd_pcm_hw_params_test_period_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_time snd_pcm_hw_params_set_period_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_time_min snd_pcm_hw_params_set_period_time_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_time_max snd_pcm_hw_params_set_period_time_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_time_minmax snd_pcm_hw_params_set_period_time_minmax_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_time_near snd_pcm_hw_params_set_period_time_near_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_time_first snd_pcm_hw_params_set_period_time_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_time_last snd_pcm_hw_params_set_period_time_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_period_size snd_pcm_hw_params_get_period_size_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_period_size_min snd_pcm_hw_params_get_period_size_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_period_size_max snd_pcm_hw_params_get_period_size_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_period_size snd_pcm_hw_params_test_period_size_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_size snd_pcm_hw_params_set_period_size_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_size_min snd_pcm_hw_params_set_period_size_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_size_max snd_pcm_hw_params_set_period_size_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_size_minmax snd_pcm_hw_params_set_period_size_minmax_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_size_near snd_pcm_hw_params_set_period_size_near_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_size_first snd_pcm_hw_params_set_period_size_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_size_last snd_pcm_hw_params_set_period_size_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_period_size_integer snd_pcm_hw_params_set_period_size_integer_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_periods snd_pcm_hw_params_get_periods_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_periods_min snd_pcm_hw_params_get_periods_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_periods_max snd_pcm_hw_params_get_periods_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_periods snd_pcm_hw_params_test_periods_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_periods snd_pcm_hw_params_set_periods_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_periods_min snd_pcm_hw_params_set_periods_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_periods_max snd_pcm_hw_params_set_periods_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_periods_minmax snd_pcm_hw_params_set_periods_minmax_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_periods_near snd_pcm_hw_params_set_periods_near_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_periods_first snd_pcm_hw_params_set_periods_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_periods_last snd_pcm_hw_params_set_periods_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_periods_integer snd_pcm_hw_params_set_periods_integer_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_buffer_time snd_pcm_hw_params_get_buffer_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_buffer_time_min snd_pcm_hw_params_get_buffer_time_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_buffer_time_max snd_pcm_hw_params_get_buffer_time_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_buffer_time snd_pcm_hw_params_test_buffer_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_time snd_pcm_hw_params_set_buffer_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_time_min snd_pcm_hw_params_set_buffer_time_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_time_max snd_pcm_hw_params_set_buffer_time_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_time_minmax snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_time_near snd_pcm_hw_params_set_buffer_time_near_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_time_first snd_pcm_hw_params_set_buffer_time_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_time_last snd_pcm_hw_params_set_buffer_time_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_buffer_size snd_pcm_hw_params_get_buffer_size_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_buffer_size_min snd_pcm_hw_params_get_buffer_size_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_buffer_size_max snd_pcm_hw_params_get_buffer_size_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_buffer_size snd_pcm_hw_params_test_buffer_size_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_size snd_pcm_hw_params_set_buffer_size_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_size_min snd_pcm_hw_params_set_buffer_size_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_size_max snd_pcm_hw_params_set_buffer_size_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_size_minmax snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_size_near snd_pcm_hw_params_set_buffer_size_near_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_size_first snd_pcm_hw_params_set_buffer_size_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_buffer_size_last snd_pcm_hw_params_set_buffer_size_last_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_min_align snd_pcm_hw_params_get_min_align_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_sizeof snd_pcm_sw_params_sizeof_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_free snd_pcm_sw_params_free_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_copy snd_pcm_sw_params_copy_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_boundary snd_pcm_sw_params_get_boundary_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_tstamp_mode snd_pcm_sw_params_set_tstamp_mode_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_tstamp_mode snd_pcm_sw_params_get_tstamp_mode_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_avail_min snd_pcm_sw_params_set_avail_min_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_avail_min snd_pcm_sw_params_get_avail_min_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_period_event snd_pcm_sw_params_set_period_event_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_period_event snd_pcm_sw_params_get_period_event_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_start_threshold snd_pcm_sw_params_set_start_threshold_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_start_threshold snd_pcm_sw_params_get_start_threshold_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_stop_threshold snd_pcm_sw_params_set_stop_threshold_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_stop_threshold snd_pcm_sw_params_get_stop_threshold_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_silence_threshold snd_pcm_sw_params_set_silence_threshold_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_silence_threshold snd_pcm_sw_params_get_silence_threshold_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_silence_size snd_pcm_sw_params_set_silence_size_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_silence_size snd_pcm_sw_params_get_silence_size_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_sizeof snd_pcm_access_mask_sizeof_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_malloc snd_pcm_access_mask_malloc_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_free snd_pcm_access_mask_free_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_copy snd_pcm_access_mask_copy_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_none snd_pcm_access_mask_none_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_any snd_pcm_access_mask_any_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_test snd_pcm_access_mask_test_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_empty snd_pcm_access_mask_empty_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_set snd_pcm_access_mask_set_dylibloader_wrapper_asound
+#define snd_pcm_access_mask_reset snd_pcm_access_mask_reset_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_sizeof snd_pcm_format_mask_sizeof_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_malloc snd_pcm_format_mask_malloc_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_free snd_pcm_format_mask_free_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_copy snd_pcm_format_mask_copy_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_none snd_pcm_format_mask_none_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_any snd_pcm_format_mask_any_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_test snd_pcm_format_mask_test_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_empty snd_pcm_format_mask_empty_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_set snd_pcm_format_mask_set_dylibloader_wrapper_asound
+#define snd_pcm_format_mask_reset snd_pcm_format_mask_reset_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_sizeof snd_pcm_subformat_mask_sizeof_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_malloc snd_pcm_subformat_mask_malloc_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_free snd_pcm_subformat_mask_free_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_copy snd_pcm_subformat_mask_copy_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_none snd_pcm_subformat_mask_none_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_any snd_pcm_subformat_mask_any_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_test snd_pcm_subformat_mask_test_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_empty snd_pcm_subformat_mask_empty_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_set snd_pcm_subformat_mask_set_dylibloader_wrapper_asound
+#define snd_pcm_subformat_mask_reset snd_pcm_subformat_mask_reset_dylibloader_wrapper_asound
+#define snd_pcm_status_sizeof snd_pcm_status_sizeof_dylibloader_wrapper_asound
+#define snd_pcm_status_malloc snd_pcm_status_malloc_dylibloader_wrapper_asound
+#define snd_pcm_status_free snd_pcm_status_free_dylibloader_wrapper_asound
+#define snd_pcm_status_copy snd_pcm_status_copy_dylibloader_wrapper_asound
+#define snd_pcm_status_get_state snd_pcm_status_get_state_dylibloader_wrapper_asound
+#define snd_pcm_status_get_trigger_tstamp snd_pcm_status_get_trigger_tstamp_dylibloader_wrapper_asound
+#define snd_pcm_status_get_trigger_htstamp snd_pcm_status_get_trigger_htstamp_dylibloader_wrapper_asound
+#define snd_pcm_status_get_tstamp snd_pcm_status_get_tstamp_dylibloader_wrapper_asound
+#define snd_pcm_status_get_htstamp snd_pcm_status_get_htstamp_dylibloader_wrapper_asound
+#define snd_pcm_status_get_audio_htstamp snd_pcm_status_get_audio_htstamp_dylibloader_wrapper_asound
+#define snd_pcm_status_get_driver_htstamp snd_pcm_status_get_driver_htstamp_dylibloader_wrapper_asound
+#define snd_pcm_status_get_delay snd_pcm_status_get_delay_dylibloader_wrapper_asound
+#define snd_pcm_status_get_avail snd_pcm_status_get_avail_dylibloader_wrapper_asound
+#define snd_pcm_status_get_avail_max snd_pcm_status_get_avail_max_dylibloader_wrapper_asound
+#define snd_pcm_status_get_overrange snd_pcm_status_get_overrange_dylibloader_wrapper_asound
+#define snd_pcm_type_name snd_pcm_type_name_dylibloader_wrapper_asound
+#define snd_pcm_stream_name snd_pcm_stream_name_dylibloader_wrapper_asound
+#define snd_pcm_access_name snd_pcm_access_name_dylibloader_wrapper_asound
+#define snd_pcm_format_name snd_pcm_format_name_dylibloader_wrapper_asound
+#define snd_pcm_format_description snd_pcm_format_description_dylibloader_wrapper_asound
+#define snd_pcm_subformat_name snd_pcm_subformat_name_dylibloader_wrapper_asound
+#define snd_pcm_subformat_description snd_pcm_subformat_description_dylibloader_wrapper_asound
+#define snd_pcm_format_value snd_pcm_format_value_dylibloader_wrapper_asound
+#define snd_pcm_tstamp_mode_name snd_pcm_tstamp_mode_name_dylibloader_wrapper_asound
+#define snd_pcm_state_name snd_pcm_state_name_dylibloader_wrapper_asound
+#define snd_pcm_dump snd_pcm_dump_dylibloader_wrapper_asound
+#define snd_pcm_dump_hw_setup snd_pcm_dump_hw_setup_dylibloader_wrapper_asound
+#define snd_pcm_dump_sw_setup snd_pcm_dump_sw_setup_dylibloader_wrapper_asound
+#define snd_pcm_dump_setup snd_pcm_dump_setup_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_dump snd_pcm_hw_params_dump_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_dump snd_pcm_sw_params_dump_dylibloader_wrapper_asound
+#define snd_pcm_status_dump snd_pcm_status_dump_dylibloader_wrapper_asound
+#define snd_pcm_mmap_begin snd_pcm_mmap_begin_dylibloader_wrapper_asound
+#define snd_pcm_mmap_commit snd_pcm_mmap_commit_dylibloader_wrapper_asound
+#define snd_pcm_mmap_writei snd_pcm_mmap_writei_dylibloader_wrapper_asound
+#define snd_pcm_mmap_readi snd_pcm_mmap_readi_dylibloader_wrapper_asound
+#define snd_pcm_mmap_writen snd_pcm_mmap_writen_dylibloader_wrapper_asound
+#define snd_pcm_mmap_readn snd_pcm_mmap_readn_dylibloader_wrapper_asound
+#define snd_pcm_format_signed snd_pcm_format_signed_dylibloader_wrapper_asound
+#define snd_pcm_format_unsigned snd_pcm_format_unsigned_dylibloader_wrapper_asound
+#define snd_pcm_format_linear snd_pcm_format_linear_dylibloader_wrapper_asound
+#define snd_pcm_format_float snd_pcm_format_float_dylibloader_wrapper_asound
+#define snd_pcm_format_little_endian snd_pcm_format_little_endian_dylibloader_wrapper_asound
+#define snd_pcm_format_big_endian snd_pcm_format_big_endian_dylibloader_wrapper_asound
+#define snd_pcm_format_cpu_endian snd_pcm_format_cpu_endian_dylibloader_wrapper_asound
+#define snd_pcm_format_width snd_pcm_format_width_dylibloader_wrapper_asound
+#define snd_pcm_format_physical_width snd_pcm_format_physical_width_dylibloader_wrapper_asound
+#define snd_pcm_build_linear_format snd_pcm_build_linear_format_dylibloader_wrapper_asound
+#define snd_pcm_format_size snd_pcm_format_size_dylibloader_wrapper_asound
+#define snd_pcm_format_silence snd_pcm_format_silence_dylibloader_wrapper_asound
+#define snd_pcm_format_silence_16 snd_pcm_format_silence_16_dylibloader_wrapper_asound
+#define snd_pcm_format_silence_32 snd_pcm_format_silence_32_dylibloader_wrapper_asound
+#define snd_pcm_format_silence_64 snd_pcm_format_silence_64_dylibloader_wrapper_asound
+#define snd_pcm_format_set_silence snd_pcm_format_set_silence_dylibloader_wrapper_asound
+#define snd_pcm_bytes_to_frames snd_pcm_bytes_to_frames_dylibloader_wrapper_asound
+#define snd_pcm_frames_to_bytes snd_pcm_frames_to_bytes_dylibloader_wrapper_asound
+#define snd_pcm_bytes_to_samples snd_pcm_bytes_to_samples_dylibloader_wrapper_asound
+#define snd_pcm_samples_to_bytes snd_pcm_samples_to_bytes_dylibloader_wrapper_asound
+#define snd_pcm_area_silence snd_pcm_area_silence_dylibloader_wrapper_asound
+#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_wrapper_asound
+#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_wrapper_asound
+#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_wrapper_asound
+#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound
+#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_wrapper_asound
+#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_wrapper_asound
+#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_wrapper_asound
+#define snd_pcm_hook_add snd_pcm_hook_add_dylibloader_wrapper_asound
+#define snd_pcm_hook_remove snd_pcm_hook_remove_dylibloader_wrapper_asound
+#define snd_pcm_meter_get_bufsize snd_pcm_meter_get_bufsize_dylibloader_wrapper_asound
+#define snd_pcm_meter_get_channels snd_pcm_meter_get_channels_dylibloader_wrapper_asound
+#define snd_pcm_meter_get_rate snd_pcm_meter_get_rate_dylibloader_wrapper_asound
+#define snd_pcm_meter_get_now snd_pcm_meter_get_now_dylibloader_wrapper_asound
+#define snd_pcm_meter_get_boundary snd_pcm_meter_get_boundary_dylibloader_wrapper_asound
+#define snd_pcm_meter_add_scope snd_pcm_meter_add_scope_dylibloader_wrapper_asound
+#define snd_pcm_meter_search_scope snd_pcm_meter_search_scope_dylibloader_wrapper_asound
+#define snd_pcm_scope_malloc snd_pcm_scope_malloc_dylibloader_wrapper_asound
+#define snd_pcm_scope_set_ops snd_pcm_scope_set_ops_dylibloader_wrapper_asound
+#define snd_pcm_scope_set_name snd_pcm_scope_set_name_dylibloader_wrapper_asound
+#define snd_pcm_scope_get_name snd_pcm_scope_get_name_dylibloader_wrapper_asound
+#define snd_pcm_scope_get_callback_private snd_pcm_scope_get_callback_private_dylibloader_wrapper_asound
+#define snd_pcm_scope_set_callback_private snd_pcm_scope_set_callback_private_dylibloader_wrapper_asound
+#define snd_pcm_scope_s16_open snd_pcm_scope_s16_open_dylibloader_wrapper_asound
+#define snd_pcm_scope_s16_get_channel_buffer snd_pcm_scope_s16_get_channel_buffer_dylibloader_wrapper_asound
+#define snd_spcm_init snd_spcm_init_dylibloader_wrapper_asound
+#define snd_spcm_init_duplex snd_spcm_init_duplex_dylibloader_wrapper_asound
+#define snd_spcm_init_get_params snd_spcm_init_get_params_dylibloader_wrapper_asound
+#define snd_pcm_start_mode_name snd_pcm_start_mode_name_dylibloader_wrapper_asound
+#define snd_pcm_xrun_mode_name snd_pcm_xrun_mode_name_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_start_mode snd_pcm_sw_params_set_start_mode_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_start_mode snd_pcm_sw_params_get_start_mode_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_xrun_mode snd_pcm_sw_params_set_xrun_mode_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_xrun_mode snd_pcm_sw_params_get_xrun_mode_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_xfer_align snd_pcm_sw_params_set_xfer_align_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_xfer_align snd_pcm_sw_params_get_xfer_align_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_set_sleep_min snd_pcm_sw_params_set_sleep_min_dylibloader_wrapper_asound
+#define snd_pcm_sw_params_get_sleep_min snd_pcm_sw_params_get_sleep_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_tick_time snd_pcm_hw_params_get_tick_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_tick_time_min snd_pcm_hw_params_get_tick_time_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_get_tick_time_max snd_pcm_hw_params_get_tick_time_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_test_tick_time snd_pcm_hw_params_test_tick_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_tick_time snd_pcm_hw_params_set_tick_time_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_tick_time_min snd_pcm_hw_params_set_tick_time_min_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_tick_time_max snd_pcm_hw_params_set_tick_time_max_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_tick_time_minmax snd_pcm_hw_params_set_tick_time_minmax_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_tick_time_near snd_pcm_hw_params_set_tick_time_near_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_tick_time_first snd_pcm_hw_params_set_tick_time_first_dylibloader_wrapper_asound
+#define snd_pcm_hw_params_set_tick_time_last snd_pcm_hw_params_set_tick_time_last_dylibloader_wrapper_asound
+#define snd_rawmidi_open snd_rawmidi_open_dylibloader_wrapper_asound
+#define snd_rawmidi_open_lconf snd_rawmidi_open_lconf_dylibloader_wrapper_asound
+#define snd_rawmidi_close snd_rawmidi_close_dylibloader_wrapper_asound
+#define snd_rawmidi_poll_descriptors_count snd_rawmidi_poll_descriptors_count_dylibloader_wrapper_asound
+#define snd_rawmidi_poll_descriptors snd_rawmidi_poll_descriptors_dylibloader_wrapper_asound
+#define snd_rawmidi_poll_descriptors_revents snd_rawmidi_poll_descriptors_revents_dylibloader_wrapper_asound
+#define snd_rawmidi_nonblock snd_rawmidi_nonblock_dylibloader_wrapper_asound
+#define snd_rawmidi_info_sizeof snd_rawmidi_info_sizeof_dylibloader_wrapper_asound
+#define snd_rawmidi_info_malloc snd_rawmidi_info_malloc_dylibloader_wrapper_asound
+#define snd_rawmidi_info_free snd_rawmidi_info_free_dylibloader_wrapper_asound
+#define snd_rawmidi_info_copy snd_rawmidi_info_copy_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_device snd_rawmidi_info_get_device_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_subdevice snd_rawmidi_info_get_subdevice_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_stream snd_rawmidi_info_get_stream_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_card snd_rawmidi_info_get_card_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_flags snd_rawmidi_info_get_flags_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_id snd_rawmidi_info_get_id_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_name snd_rawmidi_info_get_name_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_subdevice_name snd_rawmidi_info_get_subdevice_name_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_subdevices_count snd_rawmidi_info_get_subdevices_count_dylibloader_wrapper_asound
+#define snd_rawmidi_info_get_subdevices_avail snd_rawmidi_info_get_subdevices_avail_dylibloader_wrapper_asound
+#define snd_rawmidi_info_set_device snd_rawmidi_info_set_device_dylibloader_wrapper_asound
+#define snd_rawmidi_info_set_subdevice snd_rawmidi_info_set_subdevice_dylibloader_wrapper_asound
+#define snd_rawmidi_info_set_stream snd_rawmidi_info_set_stream_dylibloader_wrapper_asound
+#define snd_rawmidi_info snd_rawmidi_info_dylibloader_wrapper_asound
+#define snd_rawmidi_params_sizeof snd_rawmidi_params_sizeof_dylibloader_wrapper_asound
+#define snd_rawmidi_params_malloc snd_rawmidi_params_malloc_dylibloader_wrapper_asound
+#define snd_rawmidi_params_free snd_rawmidi_params_free_dylibloader_wrapper_asound
+#define snd_rawmidi_params_copy snd_rawmidi_params_copy_dylibloader_wrapper_asound
+#define snd_rawmidi_params_set_buffer_size snd_rawmidi_params_set_buffer_size_dylibloader_wrapper_asound
+#define snd_rawmidi_params_get_buffer_size snd_rawmidi_params_get_buffer_size_dylibloader_wrapper_asound
+#define snd_rawmidi_params_set_avail_min snd_rawmidi_params_set_avail_min_dylibloader_wrapper_asound
+#define snd_rawmidi_params_get_avail_min snd_rawmidi_params_get_avail_min_dylibloader_wrapper_asound
+#define snd_rawmidi_params_set_no_active_sensing snd_rawmidi_params_set_no_active_sensing_dylibloader_wrapper_asound
+#define snd_rawmidi_params_get_no_active_sensing snd_rawmidi_params_get_no_active_sensing_dylibloader_wrapper_asound
+#define snd_rawmidi_params snd_rawmidi_params_dylibloader_wrapper_asound
+#define snd_rawmidi_params_current snd_rawmidi_params_current_dylibloader_wrapper_asound
+#define snd_rawmidi_status_sizeof snd_rawmidi_status_sizeof_dylibloader_wrapper_asound
+#define snd_rawmidi_status_malloc snd_rawmidi_status_malloc_dylibloader_wrapper_asound
+#define snd_rawmidi_status_free snd_rawmidi_status_free_dylibloader_wrapper_asound
+#define snd_rawmidi_status_copy snd_rawmidi_status_copy_dylibloader_wrapper_asound
+#define snd_rawmidi_status_get_tstamp snd_rawmidi_status_get_tstamp_dylibloader_wrapper_asound
+#define snd_rawmidi_status_get_avail snd_rawmidi_status_get_avail_dylibloader_wrapper_asound
+#define snd_rawmidi_status_get_xruns snd_rawmidi_status_get_xruns_dylibloader_wrapper_asound
+#define snd_rawmidi_status snd_rawmidi_status_dylibloader_wrapper_asound
+#define snd_rawmidi_drain snd_rawmidi_drain_dylibloader_wrapper_asound
+#define snd_rawmidi_drop snd_rawmidi_drop_dylibloader_wrapper_asound
+#define snd_rawmidi_write snd_rawmidi_write_dylibloader_wrapper_asound
+#define snd_rawmidi_read snd_rawmidi_read_dylibloader_wrapper_asound
+#define snd_rawmidi_name snd_rawmidi_name_dylibloader_wrapper_asound
+#define snd_rawmidi_type snd_rawmidi_type_dylibloader_wrapper_asound
+#define snd_rawmidi_stream snd_rawmidi_stream_dylibloader_wrapper_asound
+#define snd_timer_query_open snd_timer_query_open_dylibloader_wrapper_asound
+#define snd_timer_query_open_lconf snd_timer_query_open_lconf_dylibloader_wrapper_asound
+#define snd_timer_query_close snd_timer_query_close_dylibloader_wrapper_asound
+#define snd_timer_query_next_device snd_timer_query_next_device_dylibloader_wrapper_asound
+#define snd_timer_query_info snd_timer_query_info_dylibloader_wrapper_asound
+#define snd_timer_query_params snd_timer_query_params_dylibloader_wrapper_asound
+#define snd_timer_query_status snd_timer_query_status_dylibloader_wrapper_asound
+#define snd_timer_open snd_timer_open_dylibloader_wrapper_asound
+#define snd_timer_open_lconf snd_timer_open_lconf_dylibloader_wrapper_asound
+#define snd_timer_close snd_timer_close_dylibloader_wrapper_asound
+#define snd_async_add_timer_handler snd_async_add_timer_handler_dylibloader_wrapper_asound
+#define snd_async_handler_get_timer snd_async_handler_get_timer_dylibloader_wrapper_asound
+#define snd_timer_poll_descriptors_count snd_timer_poll_descriptors_count_dylibloader_wrapper_asound
+#define snd_timer_poll_descriptors snd_timer_poll_descriptors_dylibloader_wrapper_asound
+#define snd_timer_poll_descriptors_revents snd_timer_poll_descriptors_revents_dylibloader_wrapper_asound
+#define snd_timer_info snd_timer_info_dylibloader_wrapper_asound
+#define snd_timer_params snd_timer_params_dylibloader_wrapper_asound
+#define snd_timer_status snd_timer_status_dylibloader_wrapper_asound
+#define snd_timer_start snd_timer_start_dylibloader_wrapper_asound
+#define snd_timer_stop snd_timer_stop_dylibloader_wrapper_asound
+#define snd_timer_continue snd_timer_continue_dylibloader_wrapper_asound
+#define snd_timer_read snd_timer_read_dylibloader_wrapper_asound
+#define snd_timer_id_sizeof snd_timer_id_sizeof_dylibloader_wrapper_asound
+#define snd_timer_id_malloc snd_timer_id_malloc_dylibloader_wrapper_asound
+#define snd_timer_id_free snd_timer_id_free_dylibloader_wrapper_asound
+#define snd_timer_id_copy snd_timer_id_copy_dylibloader_wrapper_asound
+#define snd_timer_id_set_class snd_timer_id_set_class_dylibloader_wrapper_asound
+#define snd_timer_id_get_class snd_timer_id_get_class_dylibloader_wrapper_asound
+#define snd_timer_id_set_sclass snd_timer_id_set_sclass_dylibloader_wrapper_asound
+#define snd_timer_id_get_sclass snd_timer_id_get_sclass_dylibloader_wrapper_asound
+#define snd_timer_id_set_card snd_timer_id_set_card_dylibloader_wrapper_asound
+#define snd_timer_id_get_card snd_timer_id_get_card_dylibloader_wrapper_asound
+#define snd_timer_id_set_device snd_timer_id_set_device_dylibloader_wrapper_asound
+#define snd_timer_id_get_device snd_timer_id_get_device_dylibloader_wrapper_asound
+#define snd_timer_id_set_subdevice snd_timer_id_set_subdevice_dylibloader_wrapper_asound
+#define snd_timer_id_get_subdevice snd_timer_id_get_subdevice_dylibloader_wrapper_asound
+#define snd_timer_ginfo_sizeof snd_timer_ginfo_sizeof_dylibloader_wrapper_asound
+#define snd_timer_ginfo_malloc snd_timer_ginfo_malloc_dylibloader_wrapper_asound
+#define snd_timer_ginfo_free snd_timer_ginfo_free_dylibloader_wrapper_asound
+#define snd_timer_ginfo_copy snd_timer_ginfo_copy_dylibloader_wrapper_asound
+#define snd_timer_ginfo_set_tid snd_timer_ginfo_set_tid_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_tid snd_timer_ginfo_get_tid_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_flags snd_timer_ginfo_get_flags_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_card snd_timer_ginfo_get_card_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_id snd_timer_ginfo_get_id_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_name snd_timer_ginfo_get_name_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_resolution snd_timer_ginfo_get_resolution_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_resolution_min snd_timer_ginfo_get_resolution_min_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_resolution_max snd_timer_ginfo_get_resolution_max_dylibloader_wrapper_asound
+#define snd_timer_ginfo_get_clients snd_timer_ginfo_get_clients_dylibloader_wrapper_asound
+#define snd_timer_info_sizeof snd_timer_info_sizeof_dylibloader_wrapper_asound
+#define snd_timer_info_malloc snd_timer_info_malloc_dylibloader_wrapper_asound
+#define snd_timer_info_free snd_timer_info_free_dylibloader_wrapper_asound
+#define snd_timer_info_copy snd_timer_info_copy_dylibloader_wrapper_asound
+#define snd_timer_info_is_slave snd_timer_info_is_slave_dylibloader_wrapper_asound
+#define snd_timer_info_get_card snd_timer_info_get_card_dylibloader_wrapper_asound
+#define snd_timer_info_get_id snd_timer_info_get_id_dylibloader_wrapper_asound
+#define snd_timer_info_get_name snd_timer_info_get_name_dylibloader_wrapper_asound
+#define snd_timer_info_get_resolution snd_timer_info_get_resolution_dylibloader_wrapper_asound
+#define snd_timer_params_sizeof snd_timer_params_sizeof_dylibloader_wrapper_asound
+#define snd_timer_params_malloc snd_timer_params_malloc_dylibloader_wrapper_asound
+#define snd_timer_params_free snd_timer_params_free_dylibloader_wrapper_asound
+#define snd_timer_params_copy snd_timer_params_copy_dylibloader_wrapper_asound
+#define snd_timer_params_set_auto_start snd_timer_params_set_auto_start_dylibloader_wrapper_asound
+#define snd_timer_params_get_auto_start snd_timer_params_get_auto_start_dylibloader_wrapper_asound
+#define snd_timer_params_set_exclusive snd_timer_params_set_exclusive_dylibloader_wrapper_asound
+#define snd_timer_params_get_exclusive snd_timer_params_get_exclusive_dylibloader_wrapper_asound
+#define snd_timer_params_set_early_event snd_timer_params_set_early_event_dylibloader_wrapper_asound
+#define snd_timer_params_get_early_event snd_timer_params_get_early_event_dylibloader_wrapper_asound
+#define snd_timer_params_set_ticks snd_timer_params_set_ticks_dylibloader_wrapper_asound
+#define snd_timer_params_get_ticks snd_timer_params_get_ticks_dylibloader_wrapper_asound
+#define snd_timer_params_set_queue_size snd_timer_params_set_queue_size_dylibloader_wrapper_asound
+#define snd_timer_params_get_queue_size snd_timer_params_get_queue_size_dylibloader_wrapper_asound
+#define snd_timer_params_set_filter snd_timer_params_set_filter_dylibloader_wrapper_asound
+#define snd_timer_params_get_filter snd_timer_params_get_filter_dylibloader_wrapper_asound
+#define snd_timer_status_sizeof snd_timer_status_sizeof_dylibloader_wrapper_asound
+#define snd_timer_status_malloc snd_timer_status_malloc_dylibloader_wrapper_asound
+#define snd_timer_status_free snd_timer_status_free_dylibloader_wrapper_asound
+#define snd_timer_status_copy snd_timer_status_copy_dylibloader_wrapper_asound
+#define snd_timer_status_get_timestamp snd_timer_status_get_timestamp_dylibloader_wrapper_asound
+#define snd_timer_status_get_resolution snd_timer_status_get_resolution_dylibloader_wrapper_asound
+#define snd_timer_status_get_lost snd_timer_status_get_lost_dylibloader_wrapper_asound
+#define snd_timer_status_get_overrun snd_timer_status_get_overrun_dylibloader_wrapper_asound
+#define snd_timer_status_get_queue snd_timer_status_get_queue_dylibloader_wrapper_asound
+#define snd_timer_info_get_ticks snd_timer_info_get_ticks_dylibloader_wrapper_asound
+#define snd_hwdep_open snd_hwdep_open_dylibloader_wrapper_asound
+#define snd_hwdep_close snd_hwdep_close_dylibloader_wrapper_asound
+#define snd_hwdep_poll_descriptors snd_hwdep_poll_descriptors_dylibloader_wrapper_asound
+#define snd_hwdep_poll_descriptors_count snd_hwdep_poll_descriptors_count_dylibloader_wrapper_asound
+#define snd_hwdep_poll_descriptors_revents snd_hwdep_poll_descriptors_revents_dylibloader_wrapper_asound
+#define snd_hwdep_nonblock snd_hwdep_nonblock_dylibloader_wrapper_asound
+#define snd_hwdep_info snd_hwdep_info_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status snd_hwdep_dsp_status_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_load snd_hwdep_dsp_load_dylibloader_wrapper_asound
+#define snd_hwdep_ioctl snd_hwdep_ioctl_dylibloader_wrapper_asound
+#define snd_hwdep_write snd_hwdep_write_dylibloader_wrapper_asound
+#define snd_hwdep_read snd_hwdep_read_dylibloader_wrapper_asound
+#define snd_hwdep_info_sizeof snd_hwdep_info_sizeof_dylibloader_wrapper_asound
+#define snd_hwdep_info_malloc snd_hwdep_info_malloc_dylibloader_wrapper_asound
+#define snd_hwdep_info_free snd_hwdep_info_free_dylibloader_wrapper_asound
+#define snd_hwdep_info_copy snd_hwdep_info_copy_dylibloader_wrapper_asound
+#define snd_hwdep_info_get_device snd_hwdep_info_get_device_dylibloader_wrapper_asound
+#define snd_hwdep_info_get_card snd_hwdep_info_get_card_dylibloader_wrapper_asound
+#define snd_hwdep_info_get_id snd_hwdep_info_get_id_dylibloader_wrapper_asound
+#define snd_hwdep_info_get_name snd_hwdep_info_get_name_dylibloader_wrapper_asound
+#define snd_hwdep_info_get_iface snd_hwdep_info_get_iface_dylibloader_wrapper_asound
+#define snd_hwdep_info_set_device snd_hwdep_info_set_device_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_sizeof snd_hwdep_dsp_status_sizeof_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_malloc snd_hwdep_dsp_status_malloc_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_free snd_hwdep_dsp_status_free_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_copy snd_hwdep_dsp_status_copy_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_get_version snd_hwdep_dsp_status_get_version_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_get_id snd_hwdep_dsp_status_get_id_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_get_num_dsps snd_hwdep_dsp_status_get_num_dsps_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_get_dsp_loaded snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_status_get_chip_ready snd_hwdep_dsp_status_get_chip_ready_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_sizeof snd_hwdep_dsp_image_sizeof_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_malloc snd_hwdep_dsp_image_malloc_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_free snd_hwdep_dsp_image_free_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_copy snd_hwdep_dsp_image_copy_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_get_index snd_hwdep_dsp_image_get_index_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_get_name snd_hwdep_dsp_image_get_name_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_get_image snd_hwdep_dsp_image_get_image_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_get_length snd_hwdep_dsp_image_get_length_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_set_index snd_hwdep_dsp_image_set_index_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_set_name snd_hwdep_dsp_image_set_name_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_set_image snd_hwdep_dsp_image_set_image_dylibloader_wrapper_asound
+#define snd_hwdep_dsp_image_set_length snd_hwdep_dsp_image_set_length_dylibloader_wrapper_asound
+#define snd_card_load snd_card_load_dylibloader_wrapper_asound
+#define snd_card_next snd_card_next_dylibloader_wrapper_asound
+#define snd_card_get_index snd_card_get_index_dylibloader_wrapper_asound
+#define snd_card_get_name snd_card_get_name_dylibloader_wrapper_asound
+#define snd_card_get_longname snd_card_get_longname_dylibloader_wrapper_asound
+#define snd_device_name_hint snd_device_name_hint_dylibloader_wrapper_asound
+#define snd_device_name_free_hint snd_device_name_free_hint_dylibloader_wrapper_asound
+#define snd_device_name_get_hint snd_device_name_get_hint_dylibloader_wrapper_asound
+#define snd_ctl_open snd_ctl_open_dylibloader_wrapper_asound
+#define snd_ctl_open_lconf snd_ctl_open_lconf_dylibloader_wrapper_asound
+#define snd_ctl_open_fallback snd_ctl_open_fallback_dylibloader_wrapper_asound
+#define snd_ctl_close snd_ctl_close_dylibloader_wrapper_asound
+#define snd_ctl_nonblock snd_ctl_nonblock_dylibloader_wrapper_asound
+#define snd_async_add_ctl_handler snd_async_add_ctl_handler_dylibloader_wrapper_asound
+#define snd_async_handler_get_ctl snd_async_handler_get_ctl_dylibloader_wrapper_asound
+#define snd_ctl_poll_descriptors_count snd_ctl_poll_descriptors_count_dylibloader_wrapper_asound
+#define snd_ctl_poll_descriptors snd_ctl_poll_descriptors_dylibloader_wrapper_asound
+#define snd_ctl_poll_descriptors_revents snd_ctl_poll_descriptors_revents_dylibloader_wrapper_asound
+#define snd_ctl_subscribe_events snd_ctl_subscribe_events_dylibloader_wrapper_asound
+#define snd_ctl_card_info snd_ctl_card_info_dylibloader_wrapper_asound
+#define snd_ctl_elem_list snd_ctl_elem_list_dylibloader_wrapper_asound
+#define snd_ctl_elem_info snd_ctl_elem_info_dylibloader_wrapper_asound
+#define snd_ctl_elem_read snd_ctl_elem_read_dylibloader_wrapper_asound
+#define snd_ctl_elem_write snd_ctl_elem_write_dylibloader_wrapper_asound
+#define snd_ctl_elem_lock snd_ctl_elem_lock_dylibloader_wrapper_asound
+#define snd_ctl_elem_unlock snd_ctl_elem_unlock_dylibloader_wrapper_asound
+#define snd_ctl_elem_tlv_read snd_ctl_elem_tlv_read_dylibloader_wrapper_asound
+#define snd_ctl_elem_tlv_write snd_ctl_elem_tlv_write_dylibloader_wrapper_asound
+#define snd_ctl_elem_tlv_command snd_ctl_elem_tlv_command_dylibloader_wrapper_asound
+#define snd_ctl_hwdep_next_device snd_ctl_hwdep_next_device_dylibloader_wrapper_asound
+#define snd_ctl_hwdep_info snd_ctl_hwdep_info_dylibloader_wrapper_asound
+#define snd_ctl_pcm_next_device snd_ctl_pcm_next_device_dylibloader_wrapper_asound
+#define snd_ctl_pcm_info snd_ctl_pcm_info_dylibloader_wrapper_asound
+#define snd_ctl_pcm_prefer_subdevice snd_ctl_pcm_prefer_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_rawmidi_next_device snd_ctl_rawmidi_next_device_dylibloader_wrapper_asound
+#define snd_ctl_rawmidi_info snd_ctl_rawmidi_info_dylibloader_wrapper_asound
+#define snd_ctl_rawmidi_prefer_subdevice snd_ctl_rawmidi_prefer_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_set_power_state snd_ctl_set_power_state_dylibloader_wrapper_asound
+#define snd_ctl_get_power_state snd_ctl_get_power_state_dylibloader_wrapper_asound
+#define snd_ctl_read snd_ctl_read_dylibloader_wrapper_asound
+#define snd_ctl_wait snd_ctl_wait_dylibloader_wrapper_asound
+#define snd_ctl_name snd_ctl_name_dylibloader_wrapper_asound
+#define snd_ctl_type snd_ctl_type_dylibloader_wrapper_asound
+#define snd_ctl_elem_type_name snd_ctl_elem_type_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_iface_name snd_ctl_elem_iface_name_dylibloader_wrapper_asound
+#define snd_ctl_event_type_name snd_ctl_event_type_name_dylibloader_wrapper_asound
+#define snd_ctl_event_elem_get_mask snd_ctl_event_elem_get_mask_dylibloader_wrapper_asound
+#define snd_ctl_event_elem_get_numid snd_ctl_event_elem_get_numid_dylibloader_wrapper_asound
+#define snd_ctl_event_elem_get_id snd_ctl_event_elem_get_id_dylibloader_wrapper_asound
+#define snd_ctl_event_elem_get_interface snd_ctl_event_elem_get_interface_dylibloader_wrapper_asound
+#define snd_ctl_event_elem_get_device snd_ctl_event_elem_get_device_dylibloader_wrapper_asound
+#define snd_ctl_event_elem_get_subdevice snd_ctl_event_elem_get_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_event_elem_get_name snd_ctl_event_elem_get_name_dylibloader_wrapper_asound
+#define snd_ctl_event_elem_get_index snd_ctl_event_elem_get_index_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_alloc_space snd_ctl_elem_list_alloc_space_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_free_space snd_ctl_elem_list_free_space_dylibloader_wrapper_asound
+#define snd_ctl_ascii_elem_id_get snd_ctl_ascii_elem_id_get_dylibloader_wrapper_asound
+#define snd_ctl_ascii_elem_id_parse snd_ctl_ascii_elem_id_parse_dylibloader_wrapper_asound
+#define snd_ctl_ascii_value_parse snd_ctl_ascii_value_parse_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_sizeof snd_ctl_elem_id_sizeof_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_malloc snd_ctl_elem_id_malloc_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_free snd_ctl_elem_id_free_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_clear snd_ctl_elem_id_clear_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_copy snd_ctl_elem_id_copy_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_get_numid snd_ctl_elem_id_get_numid_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_get_interface snd_ctl_elem_id_get_interface_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_get_device snd_ctl_elem_id_get_device_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_get_subdevice snd_ctl_elem_id_get_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_get_name snd_ctl_elem_id_get_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_get_index snd_ctl_elem_id_get_index_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_set_numid snd_ctl_elem_id_set_numid_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_set_interface snd_ctl_elem_id_set_interface_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_set_device snd_ctl_elem_id_set_device_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_set_subdevice snd_ctl_elem_id_set_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_set_name snd_ctl_elem_id_set_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_id_set_index snd_ctl_elem_id_set_index_dylibloader_wrapper_asound
+#define snd_ctl_card_info_sizeof snd_ctl_card_info_sizeof_dylibloader_wrapper_asound
+#define snd_ctl_card_info_malloc snd_ctl_card_info_malloc_dylibloader_wrapper_asound
+#define snd_ctl_card_info_free snd_ctl_card_info_free_dylibloader_wrapper_asound
+#define snd_ctl_card_info_clear snd_ctl_card_info_clear_dylibloader_wrapper_asound
+#define snd_ctl_card_info_copy snd_ctl_card_info_copy_dylibloader_wrapper_asound
+#define snd_ctl_card_info_get_card snd_ctl_card_info_get_card_dylibloader_wrapper_asound
+#define snd_ctl_card_info_get_id snd_ctl_card_info_get_id_dylibloader_wrapper_asound
+#define snd_ctl_card_info_get_driver snd_ctl_card_info_get_driver_dylibloader_wrapper_asound
+#define snd_ctl_card_info_get_name snd_ctl_card_info_get_name_dylibloader_wrapper_asound
+#define snd_ctl_card_info_get_longname snd_ctl_card_info_get_longname_dylibloader_wrapper_asound
+#define snd_ctl_card_info_get_mixername snd_ctl_card_info_get_mixername_dylibloader_wrapper_asound
+#define snd_ctl_card_info_get_components snd_ctl_card_info_get_components_dylibloader_wrapper_asound
+#define snd_ctl_event_sizeof snd_ctl_event_sizeof_dylibloader_wrapper_asound
+#define snd_ctl_event_malloc snd_ctl_event_malloc_dylibloader_wrapper_asound
+#define snd_ctl_event_free snd_ctl_event_free_dylibloader_wrapper_asound
+#define snd_ctl_event_clear snd_ctl_event_clear_dylibloader_wrapper_asound
+#define snd_ctl_event_copy snd_ctl_event_copy_dylibloader_wrapper_asound
+#define snd_ctl_event_get_type snd_ctl_event_get_type_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_sizeof snd_ctl_elem_list_sizeof_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_malloc snd_ctl_elem_list_malloc_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_free snd_ctl_elem_list_free_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_clear snd_ctl_elem_list_clear_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_copy snd_ctl_elem_list_copy_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_set_offset snd_ctl_elem_list_set_offset_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_used snd_ctl_elem_list_get_used_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_count snd_ctl_elem_list_get_count_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_id snd_ctl_elem_list_get_id_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_numid snd_ctl_elem_list_get_numid_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_interface snd_ctl_elem_list_get_interface_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_device snd_ctl_elem_list_get_device_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_subdevice snd_ctl_elem_list_get_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_name snd_ctl_elem_list_get_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_list_get_index snd_ctl_elem_list_get_index_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_sizeof snd_ctl_elem_info_sizeof_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_malloc snd_ctl_elem_info_malloc_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_free snd_ctl_elem_info_free_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_clear snd_ctl_elem_info_clear_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_copy snd_ctl_elem_info_copy_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_type snd_ctl_elem_info_get_type_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_readable snd_ctl_elem_info_is_readable_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_writable snd_ctl_elem_info_is_writable_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_volatile snd_ctl_elem_info_is_volatile_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_inactive snd_ctl_elem_info_is_inactive_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_locked snd_ctl_elem_info_is_locked_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_tlv_readable snd_ctl_elem_info_is_tlv_readable_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_tlv_writable snd_ctl_elem_info_is_tlv_writable_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_tlv_commandable snd_ctl_elem_info_is_tlv_commandable_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_owner snd_ctl_elem_info_is_owner_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_is_user snd_ctl_elem_info_is_user_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_owner snd_ctl_elem_info_get_owner_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_count snd_ctl_elem_info_get_count_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_min snd_ctl_elem_info_get_min_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_max snd_ctl_elem_info_get_max_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_step snd_ctl_elem_info_get_step_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_min64 snd_ctl_elem_info_get_min64_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_max64 snd_ctl_elem_info_get_max64_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_step64 snd_ctl_elem_info_get_step64_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_items snd_ctl_elem_info_get_items_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_item snd_ctl_elem_info_set_item_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_item_name snd_ctl_elem_info_get_item_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_dimensions snd_ctl_elem_info_get_dimensions_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_dimension snd_ctl_elem_info_get_dimension_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_dimension snd_ctl_elem_info_set_dimension_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_id snd_ctl_elem_info_get_id_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_numid snd_ctl_elem_info_get_numid_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_interface snd_ctl_elem_info_get_interface_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_device snd_ctl_elem_info_get_device_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_subdevice snd_ctl_elem_info_get_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_name snd_ctl_elem_info_get_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_get_index snd_ctl_elem_info_get_index_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_id snd_ctl_elem_info_set_id_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_numid snd_ctl_elem_info_set_numid_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_interface snd_ctl_elem_info_set_interface_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_device snd_ctl_elem_info_set_device_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_subdevice snd_ctl_elem_info_set_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_name snd_ctl_elem_info_set_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_info_set_index snd_ctl_elem_info_set_index_dylibloader_wrapper_asound
+#define snd_ctl_add_integer_elem_set snd_ctl_add_integer_elem_set_dylibloader_wrapper_asound
+#define snd_ctl_add_integer64_elem_set snd_ctl_add_integer64_elem_set_dylibloader_wrapper_asound
+#define snd_ctl_add_boolean_elem_set snd_ctl_add_boolean_elem_set_dylibloader_wrapper_asound
+#define snd_ctl_add_enumerated_elem_set snd_ctl_add_enumerated_elem_set_dylibloader_wrapper_asound
+#define snd_ctl_add_bytes_elem_set snd_ctl_add_bytes_elem_set_dylibloader_wrapper_asound
+#define snd_ctl_elem_add_integer snd_ctl_elem_add_integer_dylibloader_wrapper_asound
+#define snd_ctl_elem_add_integer64 snd_ctl_elem_add_integer64_dylibloader_wrapper_asound
+#define snd_ctl_elem_add_boolean snd_ctl_elem_add_boolean_dylibloader_wrapper_asound
+#define snd_ctl_elem_add_enumerated snd_ctl_elem_add_enumerated_dylibloader_wrapper_asound
+#define snd_ctl_elem_add_iec958 snd_ctl_elem_add_iec958_dylibloader_wrapper_asound
+#define snd_ctl_elem_remove snd_ctl_elem_remove_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_sizeof snd_ctl_elem_value_sizeof_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_malloc snd_ctl_elem_value_malloc_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_free snd_ctl_elem_value_free_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_clear snd_ctl_elem_value_clear_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_copy snd_ctl_elem_value_copy_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_compare snd_ctl_elem_value_compare_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_id snd_ctl_elem_value_get_id_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_numid snd_ctl_elem_value_get_numid_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_interface snd_ctl_elem_value_get_interface_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_device snd_ctl_elem_value_get_device_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_subdevice snd_ctl_elem_value_get_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_name snd_ctl_elem_value_get_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_index snd_ctl_elem_value_get_index_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_id snd_ctl_elem_value_set_id_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_numid snd_ctl_elem_value_set_numid_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_interface snd_ctl_elem_value_set_interface_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_device snd_ctl_elem_value_set_device_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_subdevice snd_ctl_elem_value_set_subdevice_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_name snd_ctl_elem_value_set_name_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_index snd_ctl_elem_value_set_index_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_boolean snd_ctl_elem_value_get_boolean_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_integer snd_ctl_elem_value_get_integer_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_integer64 snd_ctl_elem_value_get_integer64_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_enumerated snd_ctl_elem_value_get_enumerated_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_byte snd_ctl_elem_value_get_byte_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_boolean snd_ctl_elem_value_set_boolean_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_integer snd_ctl_elem_value_set_integer_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_integer64 snd_ctl_elem_value_set_integer64_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_enumerated snd_ctl_elem_value_set_enumerated_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_byte snd_ctl_elem_value_set_byte_dylibloader_wrapper_asound
+#define snd_ctl_elem_set_bytes snd_ctl_elem_set_bytes_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_bytes snd_ctl_elem_value_get_bytes_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_get_iec958 snd_ctl_elem_value_get_iec958_dylibloader_wrapper_asound
+#define snd_ctl_elem_value_set_iec958 snd_ctl_elem_value_set_iec958_dylibloader_wrapper_asound
+#define snd_tlv_parse_dB_info snd_tlv_parse_dB_info_dylibloader_wrapper_asound
+#define snd_tlv_get_dB_range snd_tlv_get_dB_range_dylibloader_wrapper_asound
+#define snd_tlv_convert_to_dB snd_tlv_convert_to_dB_dylibloader_wrapper_asound
+#define snd_tlv_convert_from_dB snd_tlv_convert_from_dB_dylibloader_wrapper_asound
+#define snd_ctl_get_dB_range snd_ctl_get_dB_range_dylibloader_wrapper_asound
+#define snd_ctl_convert_to_dB snd_ctl_convert_to_dB_dylibloader_wrapper_asound
+#define snd_ctl_convert_from_dB snd_ctl_convert_from_dB_dylibloader_wrapper_asound
+#define snd_hctl_compare_fast snd_hctl_compare_fast_dylibloader_wrapper_asound
+#define snd_hctl_open snd_hctl_open_dylibloader_wrapper_asound
+#define snd_hctl_open_ctl snd_hctl_open_ctl_dylibloader_wrapper_asound
+#define snd_hctl_close snd_hctl_close_dylibloader_wrapper_asound
+#define snd_hctl_nonblock snd_hctl_nonblock_dylibloader_wrapper_asound
+#define snd_hctl_poll_descriptors_count snd_hctl_poll_descriptors_count_dylibloader_wrapper_asound
+#define snd_hctl_poll_descriptors snd_hctl_poll_descriptors_dylibloader_wrapper_asound
+#define snd_hctl_poll_descriptors_revents snd_hctl_poll_descriptors_revents_dylibloader_wrapper_asound
+#define snd_hctl_get_count snd_hctl_get_count_dylibloader_wrapper_asound
+#define snd_hctl_set_compare snd_hctl_set_compare_dylibloader_wrapper_asound
+#define snd_hctl_first_elem snd_hctl_first_elem_dylibloader_wrapper_asound
+#define snd_hctl_last_elem snd_hctl_last_elem_dylibloader_wrapper_asound
+#define snd_hctl_find_elem snd_hctl_find_elem_dylibloader_wrapper_asound
+#define snd_hctl_set_callback snd_hctl_set_callback_dylibloader_wrapper_asound
+#define snd_hctl_set_callback_private snd_hctl_set_callback_private_dylibloader_wrapper_asound
+#define snd_hctl_get_callback_private snd_hctl_get_callback_private_dylibloader_wrapper_asound
+#define snd_hctl_load snd_hctl_load_dylibloader_wrapper_asound
+#define snd_hctl_free snd_hctl_free_dylibloader_wrapper_asound
+#define snd_hctl_handle_events snd_hctl_handle_events_dylibloader_wrapper_asound
+#define snd_hctl_name snd_hctl_name_dylibloader_wrapper_asound
+#define snd_hctl_wait snd_hctl_wait_dylibloader_wrapper_asound
+#define snd_hctl_ctl snd_hctl_ctl_dylibloader_wrapper_asound
+#define snd_hctl_elem_next snd_hctl_elem_next_dylibloader_wrapper_asound
+#define snd_hctl_elem_prev snd_hctl_elem_prev_dylibloader_wrapper_asound
+#define snd_hctl_elem_info snd_hctl_elem_info_dylibloader_wrapper_asound
+#define snd_hctl_elem_read snd_hctl_elem_read_dylibloader_wrapper_asound
+#define snd_hctl_elem_write snd_hctl_elem_write_dylibloader_wrapper_asound
+#define snd_hctl_elem_tlv_read snd_hctl_elem_tlv_read_dylibloader_wrapper_asound
+#define snd_hctl_elem_tlv_write snd_hctl_elem_tlv_write_dylibloader_wrapper_asound
+#define snd_hctl_elem_tlv_command snd_hctl_elem_tlv_command_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_hctl snd_hctl_elem_get_hctl_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_id snd_hctl_elem_get_id_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_numid snd_hctl_elem_get_numid_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_interface snd_hctl_elem_get_interface_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_device snd_hctl_elem_get_device_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_subdevice snd_hctl_elem_get_subdevice_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_name snd_hctl_elem_get_name_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_index snd_hctl_elem_get_index_dylibloader_wrapper_asound
+#define snd_hctl_elem_set_callback snd_hctl_elem_set_callback_dylibloader_wrapper_asound
+#define snd_hctl_elem_get_callback_private snd_hctl_elem_get_callback_private_dylibloader_wrapper_asound
+#define snd_hctl_elem_set_callback_private snd_hctl_elem_set_callback_private_dylibloader_wrapper_asound
+#define snd_sctl_build snd_sctl_build_dylibloader_wrapper_asound
+#define snd_sctl_free snd_sctl_free_dylibloader_wrapper_asound
+#define snd_sctl_install snd_sctl_install_dylibloader_wrapper_asound
+#define snd_sctl_remove snd_sctl_remove_dylibloader_wrapper_asound
+#define snd_mixer_open snd_mixer_open_dylibloader_wrapper_asound
+#define snd_mixer_close snd_mixer_close_dylibloader_wrapper_asound
+#define snd_mixer_first_elem snd_mixer_first_elem_dylibloader_wrapper_asound
+#define snd_mixer_last_elem snd_mixer_last_elem_dylibloader_wrapper_asound
+#define snd_mixer_handle_events snd_mixer_handle_events_dylibloader_wrapper_asound
+#define snd_mixer_attach snd_mixer_attach_dylibloader_wrapper_asound
+#define snd_mixer_attach_hctl snd_mixer_attach_hctl_dylibloader_wrapper_asound
+#define snd_mixer_detach snd_mixer_detach_dylibloader_wrapper_asound
+#define snd_mixer_detach_hctl snd_mixer_detach_hctl_dylibloader_wrapper_asound
+#define snd_mixer_get_hctl snd_mixer_get_hctl_dylibloader_wrapper_asound
+#define snd_mixer_poll_descriptors_count snd_mixer_poll_descriptors_count_dylibloader_wrapper_asound
+#define snd_mixer_poll_descriptors snd_mixer_poll_descriptors_dylibloader_wrapper_asound
+#define snd_mixer_poll_descriptors_revents snd_mixer_poll_descriptors_revents_dylibloader_wrapper_asound
+#define snd_mixer_load snd_mixer_load_dylibloader_wrapper_asound
+#define snd_mixer_free snd_mixer_free_dylibloader_wrapper_asound
+#define snd_mixer_wait snd_mixer_wait_dylibloader_wrapper_asound
+#define snd_mixer_set_compare snd_mixer_set_compare_dylibloader_wrapper_asound
+#define snd_mixer_set_callback snd_mixer_set_callback_dylibloader_wrapper_asound
+#define snd_mixer_get_callback_private snd_mixer_get_callback_private_dylibloader_wrapper_asound
+#define snd_mixer_set_callback_private snd_mixer_set_callback_private_dylibloader_wrapper_asound
+#define snd_mixer_get_count snd_mixer_get_count_dylibloader_wrapper_asound
+#define snd_mixer_class_unregister snd_mixer_class_unregister_dylibloader_wrapper_asound
+#define snd_mixer_elem_next snd_mixer_elem_next_dylibloader_wrapper_asound
+#define snd_mixer_elem_prev snd_mixer_elem_prev_dylibloader_wrapper_asound
+#define snd_mixer_elem_set_callback snd_mixer_elem_set_callback_dylibloader_wrapper_asound
+#define snd_mixer_elem_get_callback_private snd_mixer_elem_get_callback_private_dylibloader_wrapper_asound
+#define snd_mixer_elem_set_callback_private snd_mixer_elem_set_callback_private_dylibloader_wrapper_asound
+#define snd_mixer_elem_get_type snd_mixer_elem_get_type_dylibloader_wrapper_asound
+#define snd_mixer_class_register snd_mixer_class_register_dylibloader_wrapper_asound
+#define snd_mixer_elem_new snd_mixer_elem_new_dylibloader_wrapper_asound
+#define snd_mixer_elem_add snd_mixer_elem_add_dylibloader_wrapper_asound
+#define snd_mixer_elem_remove snd_mixer_elem_remove_dylibloader_wrapper_asound
+#define snd_mixer_elem_free snd_mixer_elem_free_dylibloader_wrapper_asound
+#define snd_mixer_elem_info snd_mixer_elem_info_dylibloader_wrapper_asound
+#define snd_mixer_elem_value snd_mixer_elem_value_dylibloader_wrapper_asound
+#define snd_mixer_elem_attach snd_mixer_elem_attach_dylibloader_wrapper_asound
+#define snd_mixer_elem_detach snd_mixer_elem_detach_dylibloader_wrapper_asound
+#define snd_mixer_elem_empty snd_mixer_elem_empty_dylibloader_wrapper_asound
+#define snd_mixer_elem_get_private snd_mixer_elem_get_private_dylibloader_wrapper_asound
+#define snd_mixer_class_sizeof snd_mixer_class_sizeof_dylibloader_wrapper_asound
+#define snd_mixer_class_malloc snd_mixer_class_malloc_dylibloader_wrapper_asound
+#define snd_mixer_class_free snd_mixer_class_free_dylibloader_wrapper_asound
+#define snd_mixer_class_copy snd_mixer_class_copy_dylibloader_wrapper_asound
+#define snd_mixer_class_get_mixer snd_mixer_class_get_mixer_dylibloader_wrapper_asound
+#define snd_mixer_class_get_event snd_mixer_class_get_event_dylibloader_wrapper_asound
+#define snd_mixer_class_get_private snd_mixer_class_get_private_dylibloader_wrapper_asound
+#define snd_mixer_class_get_compare snd_mixer_class_get_compare_dylibloader_wrapper_asound
+#define snd_mixer_class_set_event snd_mixer_class_set_event_dylibloader_wrapper_asound
+#define snd_mixer_class_set_private snd_mixer_class_set_private_dylibloader_wrapper_asound
+#define snd_mixer_class_set_private_free snd_mixer_class_set_private_free_dylibloader_wrapper_asound
+#define snd_mixer_class_set_compare snd_mixer_class_set_compare_dylibloader_wrapper_asound
+#define snd_mixer_selem_channel_name snd_mixer_selem_channel_name_dylibloader_wrapper_asound
+#define snd_mixer_selem_register snd_mixer_selem_register_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_id snd_mixer_selem_get_id_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_name snd_mixer_selem_get_name_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_index snd_mixer_selem_get_index_dylibloader_wrapper_asound
+#define snd_mixer_find_selem snd_mixer_find_selem_dylibloader_wrapper_asound
+#define snd_mixer_selem_is_active snd_mixer_selem_is_active_dylibloader_wrapper_asound
+#define snd_mixer_selem_is_playback_mono snd_mixer_selem_is_playback_mono_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_playback_channel snd_mixer_selem_has_playback_channel_dylibloader_wrapper_asound
+#define snd_mixer_selem_is_capture_mono snd_mixer_selem_is_capture_mono_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_capture_channel snd_mixer_selem_has_capture_channel_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_capture_group snd_mixer_selem_get_capture_group_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_common_volume snd_mixer_selem_has_common_volume_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_playback_volume snd_mixer_selem_has_playback_volume_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_playback_volume_joined snd_mixer_selem_has_playback_volume_joined_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_capture_volume snd_mixer_selem_has_capture_volume_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_capture_volume_joined snd_mixer_selem_has_capture_volume_joined_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_common_switch snd_mixer_selem_has_common_switch_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_playback_switch snd_mixer_selem_has_playback_switch_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_playback_switch_joined snd_mixer_selem_has_playback_switch_joined_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_capture_switch snd_mixer_selem_has_capture_switch_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_capture_switch_joined snd_mixer_selem_has_capture_switch_joined_dylibloader_wrapper_asound
+#define snd_mixer_selem_has_capture_switch_exclusive snd_mixer_selem_has_capture_switch_exclusive_dylibloader_wrapper_asound
+#define snd_mixer_selem_ask_playback_vol_dB snd_mixer_selem_ask_playback_vol_dB_dylibloader_wrapper_asound
+#define snd_mixer_selem_ask_capture_vol_dB snd_mixer_selem_ask_capture_vol_dB_dylibloader_wrapper_asound
+#define snd_mixer_selem_ask_playback_dB_vol snd_mixer_selem_ask_playback_dB_vol_dylibloader_wrapper_asound
+#define snd_mixer_selem_ask_capture_dB_vol snd_mixer_selem_ask_capture_dB_vol_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_playback_volume snd_mixer_selem_get_playback_volume_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_capture_volume snd_mixer_selem_get_capture_volume_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_playback_dB snd_mixer_selem_get_playback_dB_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_capture_dB snd_mixer_selem_get_capture_dB_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_playback_switch snd_mixer_selem_get_playback_switch_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_capture_switch snd_mixer_selem_get_capture_switch_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_playback_volume snd_mixer_selem_set_playback_volume_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_capture_volume snd_mixer_selem_set_capture_volume_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_playback_dB snd_mixer_selem_set_playback_dB_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_capture_dB snd_mixer_selem_set_capture_dB_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_playback_volume_all snd_mixer_selem_set_playback_volume_all_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_capture_volume_all snd_mixer_selem_set_capture_volume_all_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_playback_dB_all snd_mixer_selem_set_playback_dB_all_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_capture_dB_all snd_mixer_selem_set_capture_dB_all_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_playback_switch snd_mixer_selem_set_playback_switch_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_capture_switch snd_mixer_selem_set_capture_switch_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_playback_switch_all snd_mixer_selem_set_playback_switch_all_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_capture_switch_all snd_mixer_selem_set_capture_switch_all_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_playback_volume_range snd_mixer_selem_get_playback_volume_range_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_playback_dB_range snd_mixer_selem_get_playback_dB_range_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_playback_volume_range snd_mixer_selem_set_playback_volume_range_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_capture_volume_range snd_mixer_selem_get_capture_volume_range_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_capture_dB_range snd_mixer_selem_get_capture_dB_range_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_capture_volume_range snd_mixer_selem_set_capture_volume_range_dylibloader_wrapper_asound
+#define snd_mixer_selem_is_enumerated snd_mixer_selem_is_enumerated_dylibloader_wrapper_asound
+#define snd_mixer_selem_is_enum_playback snd_mixer_selem_is_enum_playback_dylibloader_wrapper_asound
+#define snd_mixer_selem_is_enum_capture snd_mixer_selem_is_enum_capture_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_enum_items snd_mixer_selem_get_enum_items_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_enum_item_name snd_mixer_selem_get_enum_item_name_dylibloader_wrapper_asound
+#define snd_mixer_selem_get_enum_item snd_mixer_selem_get_enum_item_dylibloader_wrapper_asound
+#define snd_mixer_selem_set_enum_item snd_mixer_selem_set_enum_item_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_sizeof snd_mixer_selem_id_sizeof_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_malloc snd_mixer_selem_id_malloc_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_free snd_mixer_selem_id_free_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_copy snd_mixer_selem_id_copy_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_get_name snd_mixer_selem_id_get_name_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_wrapper_asound
+#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_wrapper_asound
+#define snd_seq_open snd_seq_open_dylibloader_wrapper_asound
+#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_wrapper_asound
+#define snd_seq_name snd_seq_name_dylibloader_wrapper_asound
+#define snd_seq_type snd_seq_type_dylibloader_wrapper_asound
+#define snd_seq_close snd_seq_close_dylibloader_wrapper_asound
+#define snd_seq_poll_descriptors_count snd_seq_poll_descriptors_count_dylibloader_wrapper_asound
+#define snd_seq_poll_descriptors snd_seq_poll_descriptors_dylibloader_wrapper_asound
+#define snd_seq_poll_descriptors_revents snd_seq_poll_descriptors_revents_dylibloader_wrapper_asound
+#define snd_seq_nonblock snd_seq_nonblock_dylibloader_wrapper_asound
+#define snd_seq_client_id snd_seq_client_id_dylibloader_wrapper_asound
+#define snd_seq_get_output_buffer_size snd_seq_get_output_buffer_size_dylibloader_wrapper_asound
+#define snd_seq_get_input_buffer_size snd_seq_get_input_buffer_size_dylibloader_wrapper_asound
+#define snd_seq_set_output_buffer_size snd_seq_set_output_buffer_size_dylibloader_wrapper_asound
+#define snd_seq_set_input_buffer_size snd_seq_set_input_buffer_size_dylibloader_wrapper_asound
+#define snd_seq_system_info_sizeof snd_seq_system_info_sizeof_dylibloader_wrapper_asound
+#define snd_seq_system_info_malloc snd_seq_system_info_malloc_dylibloader_wrapper_asound
+#define snd_seq_system_info_free snd_seq_system_info_free_dylibloader_wrapper_asound
+#define snd_seq_system_info_copy snd_seq_system_info_copy_dylibloader_wrapper_asound
+#define snd_seq_system_info_get_queues snd_seq_system_info_get_queues_dylibloader_wrapper_asound
+#define snd_seq_system_info_get_clients snd_seq_system_info_get_clients_dylibloader_wrapper_asound
+#define snd_seq_system_info_get_ports snd_seq_system_info_get_ports_dylibloader_wrapper_asound
+#define snd_seq_system_info_get_channels snd_seq_system_info_get_channels_dylibloader_wrapper_asound
+#define snd_seq_system_info_get_cur_clients snd_seq_system_info_get_cur_clients_dylibloader_wrapper_asound
+#define snd_seq_system_info_get_cur_queues snd_seq_system_info_get_cur_queues_dylibloader_wrapper_asound
+#define snd_seq_system_info snd_seq_system_info_dylibloader_wrapper_asound
+#define snd_seq_client_info_sizeof snd_seq_client_info_sizeof_dylibloader_wrapper_asound
+#define snd_seq_client_info_malloc snd_seq_client_info_malloc_dylibloader_wrapper_asound
+#define snd_seq_client_info_free snd_seq_client_info_free_dylibloader_wrapper_asound
+#define snd_seq_client_info_copy snd_seq_client_info_copy_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_client snd_seq_client_info_get_client_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_type snd_seq_client_info_get_type_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_name snd_seq_client_info_get_name_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_broadcast_filter snd_seq_client_info_get_broadcast_filter_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_error_bounce snd_seq_client_info_get_error_bounce_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_card snd_seq_client_info_get_card_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_pid snd_seq_client_info_get_pid_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_event_filter snd_seq_client_info_get_event_filter_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_num_ports snd_seq_client_info_get_num_ports_dylibloader_wrapper_asound
+#define snd_seq_client_info_get_event_lost snd_seq_client_info_get_event_lost_dylibloader_wrapper_asound
+#define snd_seq_client_info_set_client snd_seq_client_info_set_client_dylibloader_wrapper_asound
+#define snd_seq_client_info_set_name snd_seq_client_info_set_name_dylibloader_wrapper_asound
+#define snd_seq_client_info_set_broadcast_filter snd_seq_client_info_set_broadcast_filter_dylibloader_wrapper_asound
+#define snd_seq_client_info_set_error_bounce snd_seq_client_info_set_error_bounce_dylibloader_wrapper_asound
+#define snd_seq_client_info_set_event_filter snd_seq_client_info_set_event_filter_dylibloader_wrapper_asound
+#define snd_seq_client_info_event_filter_clear snd_seq_client_info_event_filter_clear_dylibloader_wrapper_asound
+#define snd_seq_client_info_event_filter_add snd_seq_client_info_event_filter_add_dylibloader_wrapper_asound
+#define snd_seq_client_info_event_filter_del snd_seq_client_info_event_filter_del_dylibloader_wrapper_asound
+#define snd_seq_client_info_event_filter_check snd_seq_client_info_event_filter_check_dylibloader_wrapper_asound
+#define snd_seq_get_client_info snd_seq_get_client_info_dylibloader_wrapper_asound
+#define snd_seq_get_any_client_info snd_seq_get_any_client_info_dylibloader_wrapper_asound
+#define snd_seq_set_client_info snd_seq_set_client_info_dylibloader_wrapper_asound
+#define snd_seq_query_next_client snd_seq_query_next_client_dylibloader_wrapper_asound
+#define snd_seq_client_pool_sizeof snd_seq_client_pool_sizeof_dylibloader_wrapper_asound
+#define snd_seq_client_pool_malloc snd_seq_client_pool_malloc_dylibloader_wrapper_asound
+#define snd_seq_client_pool_free snd_seq_client_pool_free_dylibloader_wrapper_asound
+#define snd_seq_client_pool_copy snd_seq_client_pool_copy_dylibloader_wrapper_asound
+#define snd_seq_client_pool_get_client snd_seq_client_pool_get_client_dylibloader_wrapper_asound
+#define snd_seq_client_pool_get_output_pool snd_seq_client_pool_get_output_pool_dylibloader_wrapper_asound
+#define snd_seq_client_pool_get_input_pool snd_seq_client_pool_get_input_pool_dylibloader_wrapper_asound
+#define snd_seq_client_pool_get_output_room snd_seq_client_pool_get_output_room_dylibloader_wrapper_asound
+#define snd_seq_client_pool_get_output_free snd_seq_client_pool_get_output_free_dylibloader_wrapper_asound
+#define snd_seq_client_pool_get_input_free snd_seq_client_pool_get_input_free_dylibloader_wrapper_asound
+#define snd_seq_client_pool_set_output_pool snd_seq_client_pool_set_output_pool_dylibloader_wrapper_asound
+#define snd_seq_client_pool_set_input_pool snd_seq_client_pool_set_input_pool_dylibloader_wrapper_asound
+#define snd_seq_client_pool_set_output_room snd_seq_client_pool_set_output_room_dylibloader_wrapper_asound
+#define snd_seq_get_client_pool snd_seq_get_client_pool_dylibloader_wrapper_asound
+#define snd_seq_set_client_pool snd_seq_set_client_pool_dylibloader_wrapper_asound
+#define snd_seq_port_info_sizeof snd_seq_port_info_sizeof_dylibloader_wrapper_asound
+#define snd_seq_port_info_malloc snd_seq_port_info_malloc_dylibloader_wrapper_asound
+#define snd_seq_port_info_free snd_seq_port_info_free_dylibloader_wrapper_asound
+#define snd_seq_port_info_copy snd_seq_port_info_copy_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_client snd_seq_port_info_get_client_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_port snd_seq_port_info_get_port_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_addr snd_seq_port_info_get_addr_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_name snd_seq_port_info_get_name_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_capability snd_seq_port_info_get_capability_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_type snd_seq_port_info_get_type_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_midi_channels snd_seq_port_info_get_midi_channels_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_midi_voices snd_seq_port_info_get_midi_voices_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_synth_voices snd_seq_port_info_get_synth_voices_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_read_use snd_seq_port_info_get_read_use_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_write_use snd_seq_port_info_get_write_use_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_port_specified snd_seq_port_info_get_port_specified_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_timestamping snd_seq_port_info_get_timestamping_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_timestamp_real snd_seq_port_info_get_timestamp_real_dylibloader_wrapper_asound
+#define snd_seq_port_info_get_timestamp_queue snd_seq_port_info_get_timestamp_queue_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_client snd_seq_port_info_set_client_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_port snd_seq_port_info_set_port_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_addr snd_seq_port_info_set_addr_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_name snd_seq_port_info_set_name_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_capability snd_seq_port_info_set_capability_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_type snd_seq_port_info_set_type_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_midi_channels snd_seq_port_info_set_midi_channels_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_midi_voices snd_seq_port_info_set_midi_voices_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_synth_voices snd_seq_port_info_set_synth_voices_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_port_specified snd_seq_port_info_set_port_specified_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_timestamping snd_seq_port_info_set_timestamping_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_timestamp_real snd_seq_port_info_set_timestamp_real_dylibloader_wrapper_asound
+#define snd_seq_port_info_set_timestamp_queue snd_seq_port_info_set_timestamp_queue_dylibloader_wrapper_asound
+#define snd_seq_create_port snd_seq_create_port_dylibloader_wrapper_asound
+#define snd_seq_delete_port snd_seq_delete_port_dylibloader_wrapper_asound
+#define snd_seq_get_port_info snd_seq_get_port_info_dylibloader_wrapper_asound
+#define snd_seq_get_any_port_info snd_seq_get_any_port_info_dylibloader_wrapper_asound
+#define snd_seq_set_port_info snd_seq_set_port_info_dylibloader_wrapper_asound
+#define snd_seq_query_next_port snd_seq_query_next_port_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_sizeof snd_seq_port_subscribe_sizeof_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_malloc snd_seq_port_subscribe_malloc_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_free snd_seq_port_subscribe_free_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_copy snd_seq_port_subscribe_copy_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_get_sender snd_seq_port_subscribe_get_sender_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_get_dest snd_seq_port_subscribe_get_dest_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_get_queue snd_seq_port_subscribe_get_queue_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_get_exclusive snd_seq_port_subscribe_get_exclusive_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_get_time_update snd_seq_port_subscribe_get_time_update_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_get_time_real snd_seq_port_subscribe_get_time_real_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_set_sender snd_seq_port_subscribe_set_sender_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_set_dest snd_seq_port_subscribe_set_dest_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_set_queue snd_seq_port_subscribe_set_queue_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_set_exclusive snd_seq_port_subscribe_set_exclusive_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_set_time_update snd_seq_port_subscribe_set_time_update_dylibloader_wrapper_asound
+#define snd_seq_port_subscribe_set_time_real snd_seq_port_subscribe_set_time_real_dylibloader_wrapper_asound
+#define snd_seq_get_port_subscription snd_seq_get_port_subscription_dylibloader_wrapper_asound
+#define snd_seq_subscribe_port snd_seq_subscribe_port_dylibloader_wrapper_asound
+#define snd_seq_unsubscribe_port snd_seq_unsubscribe_port_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_sizeof snd_seq_query_subscribe_sizeof_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_malloc snd_seq_query_subscribe_malloc_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_free snd_seq_query_subscribe_free_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_copy snd_seq_query_subscribe_copy_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_client snd_seq_query_subscribe_get_client_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_port snd_seq_query_subscribe_get_port_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_root snd_seq_query_subscribe_get_root_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_type snd_seq_query_subscribe_get_type_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_index snd_seq_query_subscribe_get_index_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_num_subs snd_seq_query_subscribe_get_num_subs_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_addr snd_seq_query_subscribe_get_addr_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_queue snd_seq_query_subscribe_get_queue_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_exclusive snd_seq_query_subscribe_get_exclusive_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_time_update snd_seq_query_subscribe_get_time_update_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_get_time_real snd_seq_query_subscribe_get_time_real_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_set_client snd_seq_query_subscribe_set_client_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_set_port snd_seq_query_subscribe_set_port_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_set_root snd_seq_query_subscribe_set_root_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_set_type snd_seq_query_subscribe_set_type_dylibloader_wrapper_asound
+#define snd_seq_query_subscribe_set_index snd_seq_query_subscribe_set_index_dylibloader_wrapper_asound
+#define snd_seq_query_port_subscribers snd_seq_query_port_subscribers_dylibloader_wrapper_asound
+#define snd_seq_queue_info_sizeof snd_seq_queue_info_sizeof_dylibloader_wrapper_asound
+#define snd_seq_queue_info_malloc snd_seq_queue_info_malloc_dylibloader_wrapper_asound
+#define snd_seq_queue_info_free snd_seq_queue_info_free_dylibloader_wrapper_asound
+#define snd_seq_queue_info_copy snd_seq_queue_info_copy_dylibloader_wrapper_asound
+#define snd_seq_queue_info_get_queue snd_seq_queue_info_get_queue_dylibloader_wrapper_asound
+#define snd_seq_queue_info_get_name snd_seq_queue_info_get_name_dylibloader_wrapper_asound
+#define snd_seq_queue_info_get_owner snd_seq_queue_info_get_owner_dylibloader_wrapper_asound
+#define snd_seq_queue_info_get_locked snd_seq_queue_info_get_locked_dylibloader_wrapper_asound
+#define snd_seq_queue_info_get_flags snd_seq_queue_info_get_flags_dylibloader_wrapper_asound
+#define snd_seq_queue_info_set_name snd_seq_queue_info_set_name_dylibloader_wrapper_asound
+#define snd_seq_queue_info_set_owner snd_seq_queue_info_set_owner_dylibloader_wrapper_asound
+#define snd_seq_queue_info_set_locked snd_seq_queue_info_set_locked_dylibloader_wrapper_asound
+#define snd_seq_queue_info_set_flags snd_seq_queue_info_set_flags_dylibloader_wrapper_asound
+#define snd_seq_create_queue snd_seq_create_queue_dylibloader_wrapper_asound
+#define snd_seq_alloc_named_queue snd_seq_alloc_named_queue_dylibloader_wrapper_asound
+#define snd_seq_alloc_queue snd_seq_alloc_queue_dylibloader_wrapper_asound
+#define snd_seq_free_queue snd_seq_free_queue_dylibloader_wrapper_asound
+#define snd_seq_get_queue_info snd_seq_get_queue_info_dylibloader_wrapper_asound
+#define snd_seq_set_queue_info snd_seq_set_queue_info_dylibloader_wrapper_asound
+#define snd_seq_query_named_queue snd_seq_query_named_queue_dylibloader_wrapper_asound
+#define snd_seq_get_queue_usage snd_seq_get_queue_usage_dylibloader_wrapper_asound
+#define snd_seq_set_queue_usage snd_seq_set_queue_usage_dylibloader_wrapper_asound
+#define snd_seq_queue_status_sizeof snd_seq_queue_status_sizeof_dylibloader_wrapper_asound
+#define snd_seq_queue_status_malloc snd_seq_queue_status_malloc_dylibloader_wrapper_asound
+#define snd_seq_queue_status_free snd_seq_queue_status_free_dylibloader_wrapper_asound
+#define snd_seq_queue_status_copy snd_seq_queue_status_copy_dylibloader_wrapper_asound
+#define snd_seq_queue_status_get_queue snd_seq_queue_status_get_queue_dylibloader_wrapper_asound
+#define snd_seq_queue_status_get_events snd_seq_queue_status_get_events_dylibloader_wrapper_asound
+#define snd_seq_queue_status_get_tick_time snd_seq_queue_status_get_tick_time_dylibloader_wrapper_asound
+#define snd_seq_queue_status_get_real_time snd_seq_queue_status_get_real_time_dylibloader_wrapper_asound
+#define snd_seq_queue_status_get_status snd_seq_queue_status_get_status_dylibloader_wrapper_asound
+#define snd_seq_get_queue_status snd_seq_get_queue_status_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_sizeof snd_seq_queue_tempo_sizeof_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_malloc snd_seq_queue_tempo_malloc_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_free snd_seq_queue_tempo_free_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_copy snd_seq_queue_tempo_copy_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_get_queue snd_seq_queue_tempo_get_queue_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_get_tempo snd_seq_queue_tempo_get_tempo_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_get_ppq snd_seq_queue_tempo_get_ppq_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_get_skew snd_seq_queue_tempo_get_skew_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_get_skew_base snd_seq_queue_tempo_get_skew_base_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_set_tempo snd_seq_queue_tempo_set_tempo_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_set_ppq snd_seq_queue_tempo_set_ppq_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_set_skew snd_seq_queue_tempo_set_skew_dylibloader_wrapper_asound
+#define snd_seq_queue_tempo_set_skew_base snd_seq_queue_tempo_set_skew_base_dylibloader_wrapper_asound
+#define snd_seq_get_queue_tempo snd_seq_get_queue_tempo_dylibloader_wrapper_asound
+#define snd_seq_set_queue_tempo snd_seq_set_queue_tempo_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_sizeof snd_seq_queue_timer_sizeof_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_malloc snd_seq_queue_timer_malloc_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_free snd_seq_queue_timer_free_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_copy snd_seq_queue_timer_copy_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_get_queue snd_seq_queue_timer_get_queue_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_get_type snd_seq_queue_timer_get_type_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_get_id snd_seq_queue_timer_get_id_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_get_resolution snd_seq_queue_timer_get_resolution_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_set_type snd_seq_queue_timer_set_type_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_set_id snd_seq_queue_timer_set_id_dylibloader_wrapper_asound
+#define snd_seq_queue_timer_set_resolution snd_seq_queue_timer_set_resolution_dylibloader_wrapper_asound
+#define snd_seq_get_queue_timer snd_seq_get_queue_timer_dylibloader_wrapper_asound
+#define snd_seq_set_queue_timer snd_seq_set_queue_timer_dylibloader_wrapper_asound
+#define snd_seq_free_event snd_seq_free_event_dylibloader_wrapper_asound
+#define snd_seq_event_length snd_seq_event_length_dylibloader_wrapper_asound
+#define snd_seq_event_output snd_seq_event_output_dylibloader_wrapper_asound
+#define snd_seq_event_output_buffer snd_seq_event_output_buffer_dylibloader_wrapper_asound
+#define snd_seq_event_output_direct snd_seq_event_output_direct_dylibloader_wrapper_asound
+#define snd_seq_event_input snd_seq_event_input_dylibloader_wrapper_asound
+#define snd_seq_event_input_pending snd_seq_event_input_pending_dylibloader_wrapper_asound
+#define snd_seq_drain_output snd_seq_drain_output_dylibloader_wrapper_asound
+#define snd_seq_event_output_pending snd_seq_event_output_pending_dylibloader_wrapper_asound
+#define snd_seq_extract_output snd_seq_extract_output_dylibloader_wrapper_asound
+#define snd_seq_drop_output snd_seq_drop_output_dylibloader_wrapper_asound
+#define snd_seq_drop_output_buffer snd_seq_drop_output_buffer_dylibloader_wrapper_asound
+#define snd_seq_drop_input snd_seq_drop_input_dylibloader_wrapper_asound
+#define snd_seq_drop_input_buffer snd_seq_drop_input_buffer_dylibloader_wrapper_asound
+#define snd_seq_remove_events_sizeof snd_seq_remove_events_sizeof_dylibloader_wrapper_asound
+#define snd_seq_remove_events_malloc snd_seq_remove_events_malloc_dylibloader_wrapper_asound
+#define snd_seq_remove_events_free snd_seq_remove_events_free_dylibloader_wrapper_asound
+#define snd_seq_remove_events_copy snd_seq_remove_events_copy_dylibloader_wrapper_asound
+#define snd_seq_remove_events_get_condition snd_seq_remove_events_get_condition_dylibloader_wrapper_asound
+#define snd_seq_remove_events_get_queue snd_seq_remove_events_get_queue_dylibloader_wrapper_asound
+#define snd_seq_remove_events_get_time snd_seq_remove_events_get_time_dylibloader_wrapper_asound
+#define snd_seq_remove_events_get_dest snd_seq_remove_events_get_dest_dylibloader_wrapper_asound
+#define snd_seq_remove_events_get_channel snd_seq_remove_events_get_channel_dylibloader_wrapper_asound
+#define snd_seq_remove_events_get_event_type snd_seq_remove_events_get_event_type_dylibloader_wrapper_asound
+#define snd_seq_remove_events_get_tag snd_seq_remove_events_get_tag_dylibloader_wrapper_asound
+#define snd_seq_remove_events_set_condition snd_seq_remove_events_set_condition_dylibloader_wrapper_asound
+#define snd_seq_remove_events_set_queue snd_seq_remove_events_set_queue_dylibloader_wrapper_asound
+#define snd_seq_remove_events_set_time snd_seq_remove_events_set_time_dylibloader_wrapper_asound
+#define snd_seq_remove_events_set_dest snd_seq_remove_events_set_dest_dylibloader_wrapper_asound
+#define snd_seq_remove_events_set_channel snd_seq_remove_events_set_channel_dylibloader_wrapper_asound
+#define snd_seq_remove_events_set_event_type snd_seq_remove_events_set_event_type_dylibloader_wrapper_asound
+#define snd_seq_remove_events_set_tag snd_seq_remove_events_set_tag_dylibloader_wrapper_asound
+#define snd_seq_remove_events snd_seq_remove_events_dylibloader_wrapper_asound
+#define snd_seq_set_bit snd_seq_set_bit_dylibloader_wrapper_asound
+#define snd_seq_unset_bit snd_seq_unset_bit_dylibloader_wrapper_asound
+#define snd_seq_change_bit snd_seq_change_bit_dylibloader_wrapper_asound
+#define snd_seq_get_bit snd_seq_get_bit_dylibloader_wrapper_asound
+#define snd_seq_control_queue snd_seq_control_queue_dylibloader_wrapper_asound
+#define snd_seq_create_simple_port snd_seq_create_simple_port_dylibloader_wrapper_asound
+#define snd_seq_delete_simple_port snd_seq_delete_simple_port_dylibloader_wrapper_asound
+#define snd_seq_connect_from snd_seq_connect_from_dylibloader_wrapper_asound
+#define snd_seq_connect_to snd_seq_connect_to_dylibloader_wrapper_asound
+#define snd_seq_disconnect_from snd_seq_disconnect_from_dylibloader_wrapper_asound
+#define snd_seq_disconnect_to snd_seq_disconnect_to_dylibloader_wrapper_asound
+#define snd_seq_set_client_name snd_seq_set_client_name_dylibloader_wrapper_asound
+#define snd_seq_set_client_event_filter snd_seq_set_client_event_filter_dylibloader_wrapper_asound
+#define snd_seq_set_client_pool_output snd_seq_set_client_pool_output_dylibloader_wrapper_asound
+#define snd_seq_set_client_pool_output_room snd_seq_set_client_pool_output_room_dylibloader_wrapper_asound
+#define snd_seq_set_client_pool_input snd_seq_set_client_pool_input_dylibloader_wrapper_asound
+#define snd_seq_sync_output_queue snd_seq_sync_output_queue_dylibloader_wrapper_asound
+#define snd_seq_parse_address snd_seq_parse_address_dylibloader_wrapper_asound
+#define snd_seq_reset_pool_output snd_seq_reset_pool_output_dylibloader_wrapper_asound
+#define snd_seq_reset_pool_input snd_seq_reset_pool_input_dylibloader_wrapper_asound
+#define snd_midi_event_new snd_midi_event_new_dylibloader_wrapper_asound
+#define snd_midi_event_resize_buffer snd_midi_event_resize_buffer_dylibloader_wrapper_asound
+#define snd_midi_event_free snd_midi_event_free_dylibloader_wrapper_asound
+#define snd_midi_event_init snd_midi_event_init_dylibloader_wrapper_asound
+#define snd_midi_event_reset_encode snd_midi_event_reset_encode_dylibloader_wrapper_asound
+#define snd_midi_event_reset_decode snd_midi_event_reset_decode_dylibloader_wrapper_asound
+#define snd_midi_event_no_status snd_midi_event_no_status_dylibloader_wrapper_asound
+#define snd_midi_event_encode snd_midi_event_encode_dylibloader_wrapper_asound
+#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_wrapper_asound
+#define snd_midi_event_decode snd_midi_event_decode_dylibloader_wrapper_asound
+extern const char* (*snd_asoundlib_version_dylibloader_wrapper_asound)( void);
+extern int (*snd_dlpath_dylibloader_wrapper_asound)( char*, size_t,const char*);
+extern void* (*snd_dlopen_dylibloader_wrapper_asound)(const char*, int, char*, size_t);
+extern void* (*snd_dlsym_dylibloader_wrapper_asound)( void*,const char*,const char*);
+extern int (*snd_dlclose_dylibloader_wrapper_asound)( void*);
+extern int (*snd_async_add_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, int, snd_async_callback_t, void*);
+extern int (*snd_async_del_handler_dylibloader_wrapper_asound)( snd_async_handler_t*);
+extern int (*snd_async_handler_get_fd_dylibloader_wrapper_asound)( snd_async_handler_t*);
+extern int (*snd_async_handler_get_signo_dylibloader_wrapper_asound)( snd_async_handler_t*);
+extern void* (*snd_async_handler_get_callback_private_dylibloader_wrapper_asound)( snd_async_handler_t*);
+extern struct snd_shm_area* (*snd_shm_area_create_dylibloader_wrapper_asound)( int, void*);
+extern struct snd_shm_area* (*snd_shm_area_share_dylibloader_wrapper_asound)(struct snd_shm_area*);
+extern int (*snd_shm_area_destroy_dylibloader_wrapper_asound)(struct snd_shm_area*);
+extern int (*snd_user_file_dylibloader_wrapper_asound)(const char*, char**);
+extern int (*snd_input_stdio_open_dylibloader_wrapper_asound)( snd_input_t**,const char*,const char*);
+extern int (*snd_input_stdio_attach_dylibloader_wrapper_asound)( snd_input_t**, FILE*, int);
+extern int (*snd_input_buffer_open_dylibloader_wrapper_asound)( snd_input_t**,const char*, ssize_t);
+extern int (*snd_input_close_dylibloader_wrapper_asound)( snd_input_t*);
+extern int (*snd_input_scanf_dylibloader_wrapper_asound)( snd_input_t*,const char*,...);
+extern char* (*snd_input_gets_dylibloader_wrapper_asound)( snd_input_t*, char*, size_t);
+extern int (*snd_input_getc_dylibloader_wrapper_asound)( snd_input_t*);
+extern int (*snd_input_ungetc_dylibloader_wrapper_asound)( snd_input_t*, int);
+extern int (*snd_output_stdio_open_dylibloader_wrapper_asound)( snd_output_t**,const char*,const char*);
+extern int (*snd_output_stdio_attach_dylibloader_wrapper_asound)( snd_output_t**, FILE*, int);
+extern int (*snd_output_buffer_open_dylibloader_wrapper_asound)( snd_output_t**);
+extern size_t (*snd_output_buffer_string_dylibloader_wrapper_asound)( snd_output_t*, char**);
+extern int (*snd_output_close_dylibloader_wrapper_asound)( snd_output_t*);
+extern int (*snd_output_printf_dylibloader_wrapper_asound)( snd_output_t*,const char*,...);
+extern int (*snd_output_vprintf_dylibloader_wrapper_asound)( snd_output_t*,const char*, va_list);
+extern int (*snd_output_puts_dylibloader_wrapper_asound)( snd_output_t*,const char*);
+extern int (*snd_output_putc_dylibloader_wrapper_asound)( snd_output_t*, int);
+extern int (*snd_output_flush_dylibloader_wrapper_asound)( snd_output_t*);
+extern const char* (*snd_strerror_dylibloader_wrapper_asound)( int);
+extern int (*snd_lib_error_set_handler_dylibloader_wrapper_asound)( snd_lib_error_handler_t);
+extern snd_local_error_handler_t (*snd_lib_error_set_local_dylibloader_wrapper_asound)( snd_local_error_handler_t);
+extern const char* (*snd_config_topdir_dylibloader_wrapper_asound)( void);
+extern int (*snd_config_top_dylibloader_wrapper_asound)( snd_config_t**);
+extern int (*snd_config_load_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*);
+extern int (*snd_config_load_override_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*);
+extern int (*snd_config_save_dylibloader_wrapper_asound)( snd_config_t*, snd_output_t*);
+extern int (*snd_config_update_dylibloader_wrapper_asound)( void);
+extern int (*snd_config_update_r_dylibloader_wrapper_asound)( snd_config_t**, snd_config_update_t**,const char*);
+extern int (*snd_config_update_free_dylibloader_wrapper_asound)( snd_config_update_t*);
+extern int (*snd_config_update_free_global_dylibloader_wrapper_asound)( void);
+extern int (*snd_config_update_ref_dylibloader_wrapper_asound)( snd_config_t**);
+extern void (*snd_config_ref_dylibloader_wrapper_asound)( snd_config_t*);
+extern void (*snd_config_unref_dylibloader_wrapper_asound)( snd_config_t*);
+extern int (*snd_config_search_dylibloader_wrapper_asound)( snd_config_t*,const char*, snd_config_t**);
+extern int (*snd_config_searchv_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t**,...);
+extern int (*snd_config_search_definition_dylibloader_wrapper_asound)( snd_config_t*,const char*,const char*, snd_config_t**);
+extern int (*snd_config_expand_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*,const char*, snd_config_t*, snd_config_t**);
+extern int (*snd_config_evaluate_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*, snd_config_t*, snd_config_t**);
+extern int (*snd_config_add_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
+extern int (*snd_config_add_before_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
+extern int (*snd_config_add_after_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
+extern int (*snd_config_remove_dylibloader_wrapper_asound)( snd_config_t*);
+extern int (*snd_config_delete_dylibloader_wrapper_asound)( snd_config_t*);
+extern int (*snd_config_delete_compound_members_dylibloader_wrapper_asound)(const snd_config_t*);
+extern int (*snd_config_copy_dylibloader_wrapper_asound)( snd_config_t**, snd_config_t*);
+extern int (*snd_config_make_dylibloader_wrapper_asound)( snd_config_t**,const char*, snd_config_type_t);
+extern int (*snd_config_make_integer_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+extern int (*snd_config_make_integer64_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+extern int (*snd_config_make_real_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+extern int (*snd_config_make_string_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+extern int (*snd_config_make_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*);
+extern int (*snd_config_make_compound_dylibloader_wrapper_asound)( snd_config_t**,const char*, int);
+extern int (*snd_config_imake_integer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const long);
+extern int (*snd_config_imake_integer64_dylibloader_wrapper_asound)( snd_config_t**,const char*,const long long);
+extern int (*snd_config_imake_real_dylibloader_wrapper_asound)( snd_config_t**,const char*,const double);
+extern int (*snd_config_imake_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*);
+extern int (*snd_config_imake_safe_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*);
+extern int (*snd_config_imake_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const void*);
+extern snd_config_type_t (*snd_config_get_type_dylibloader_wrapper_asound)(const snd_config_t*);
+extern int (*snd_config_is_array_dylibloader_wrapper_asound)(const snd_config_t*);
+extern int (*snd_config_set_id_dylibloader_wrapper_asound)( snd_config_t*,const char*);
+extern int (*snd_config_set_integer_dylibloader_wrapper_asound)( snd_config_t*, long);
+extern int (*snd_config_set_integer64_dylibloader_wrapper_asound)( snd_config_t*, long long);
+extern int (*snd_config_set_real_dylibloader_wrapper_asound)( snd_config_t*, double);
+extern int (*snd_config_set_string_dylibloader_wrapper_asound)( snd_config_t*,const char*);
+extern int (*snd_config_set_ascii_dylibloader_wrapper_asound)( snd_config_t*,const char*);
+extern int (*snd_config_set_pointer_dylibloader_wrapper_asound)( snd_config_t*,const void*);
+extern int (*snd_config_get_id_dylibloader_wrapper_asound)(const snd_config_t*,const char**);
+extern int (*snd_config_get_integer_dylibloader_wrapper_asound)(const snd_config_t*, long*);
+extern int (*snd_config_get_integer64_dylibloader_wrapper_asound)(const snd_config_t*, long long*);
+extern int (*snd_config_get_real_dylibloader_wrapper_asound)(const snd_config_t*, double*);
+extern int (*snd_config_get_ireal_dylibloader_wrapper_asound)(const snd_config_t*, double*);
+extern int (*snd_config_get_string_dylibloader_wrapper_asound)(const snd_config_t*,const char**);
+extern int (*snd_config_get_ascii_dylibloader_wrapper_asound)(const snd_config_t*, char**);
+extern int (*snd_config_get_pointer_dylibloader_wrapper_asound)(const snd_config_t*,const void**);
+extern int (*snd_config_test_id_dylibloader_wrapper_asound)(const snd_config_t*,const char*);
+extern snd_config_iterator_t (*snd_config_iterator_first_dylibloader_wrapper_asound)(const snd_config_t*);
+extern snd_config_iterator_t (*snd_config_iterator_next_dylibloader_wrapper_asound)(const snd_config_iterator_t);
+extern snd_config_iterator_t (*snd_config_iterator_end_dylibloader_wrapper_asound)(const snd_config_t*);
+extern snd_config_t* (*snd_config_iterator_entry_dylibloader_wrapper_asound)(const snd_config_iterator_t);
+extern int (*snd_config_get_bool_ascii_dylibloader_wrapper_asound)(const char*);
+extern int (*snd_config_get_bool_dylibloader_wrapper_asound)(const snd_config_t*);
+extern int (*snd_config_get_ctl_iface_ascii_dylibloader_wrapper_asound)(const char*);
+extern int (*snd_config_get_ctl_iface_dylibloader_wrapper_asound)(const snd_config_t*);
+extern int (*snd_names_list_dylibloader_wrapper_asound)(const char*, snd_devname_t**);
+extern void (*snd_names_list_free_dylibloader_wrapper_asound)( snd_devname_t*);
+extern int (*snd_pcm_open_dylibloader_wrapper_asound)( snd_pcm_t**,const char*, snd_pcm_stream_t, int);
+extern int (*snd_pcm_open_lconf_dylibloader_wrapper_asound)( snd_pcm_t**,const char*, snd_pcm_stream_t, int, snd_config_t*);
+extern int (*snd_pcm_open_fallback_dylibloader_wrapper_asound)( snd_pcm_t**, snd_config_t*,const char*,const char*, snd_pcm_stream_t, int);
+extern int (*snd_pcm_close_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern const char* (*snd_pcm_name_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_type_t (*snd_pcm_type_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_stream_t (*snd_pcm_stream_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_poll_descriptors_count_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_poll_descriptors_dylibloader_wrapper_asound)( snd_pcm_t*,struct pollfd*, unsigned int);
+extern int (*snd_pcm_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_pcm_t*,struct pollfd*, unsigned int, unsigned short*);
+extern int (*snd_pcm_nonblock_dylibloader_wrapper_asound)( snd_pcm_t*, int);
+extern int (*snd_async_add_pcm_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_pcm_t*, snd_async_callback_t, void*);
+extern snd_pcm_t* (*snd_async_handler_get_pcm_dylibloader_wrapper_asound)( snd_async_handler_t*);
+extern int (*snd_pcm_info_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_info_t*);
+extern int (*snd_pcm_hw_params_current_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_free_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_sw_params_current_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*);
+extern int (*snd_pcm_sw_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*);
+extern int (*snd_pcm_prepare_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_reset_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_status_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_status_t*);
+extern int (*snd_pcm_start_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_drop_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_drain_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_pause_dylibloader_wrapper_asound)( snd_pcm_t*, int);
+extern snd_pcm_state_t (*snd_pcm_state_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_hwsync_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_delay_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t*);
+extern int (*snd_pcm_resume_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_htimestamp_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t*, snd_htimestamp_t*);
+extern snd_pcm_sframes_t (*snd_pcm_avail_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_sframes_t (*snd_pcm_avail_update_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_avail_delay_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t*, snd_pcm_sframes_t*);
+extern snd_pcm_sframes_t (*snd_pcm_rewindable_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_sframes_t (*snd_pcm_rewind_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_forwardable_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_sframes_t (*snd_pcm_forward_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_writei_dylibloader_wrapper_asound)( snd_pcm_t*,const void*, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_readi_dylibloader_wrapper_asound)( snd_pcm_t*, void*, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_writen_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_readn_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t);
+extern int (*snd_pcm_wait_dylibloader_wrapper_asound)( snd_pcm_t*, int);
+extern int (*snd_pcm_link_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_t*);
+extern int (*snd_pcm_unlink_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_chmap_query_t** (*snd_pcm_query_chmaps_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_chmap_query_t** (*snd_pcm_query_chmaps_from_hw_dylibloader_wrapper_asound)( int, int, int, snd_pcm_stream_t);
+extern void (*snd_pcm_free_chmaps_dylibloader_wrapper_asound)( snd_pcm_chmap_query_t**);
+extern snd_pcm_chmap_t* (*snd_pcm_get_chmap_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_set_chmap_dylibloader_wrapper_asound)( snd_pcm_t*,const snd_pcm_chmap_t*);
+extern const char* (*snd_pcm_chmap_type_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_type);
+extern const char* (*snd_pcm_chmap_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_position);
+extern const char* (*snd_pcm_chmap_long_name_dylibloader_wrapper_asound)(enum snd_pcm_chmap_position);
+extern int (*snd_pcm_chmap_print_dylibloader_wrapper_asound)(const snd_pcm_chmap_t*, size_t, char*);
+extern unsigned int (*snd_pcm_chmap_from_string_dylibloader_wrapper_asound)(const char*);
+extern snd_pcm_chmap_t* (*snd_pcm_chmap_parse_string_dylibloader_wrapper_asound)(const char*);
+extern int (*snd_pcm_recover_dylibloader_wrapper_asound)( snd_pcm_t*, int, int);
+extern int (*snd_pcm_set_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_format_t, snd_pcm_access_t, unsigned int, unsigned int, int, unsigned int);
+extern int (*snd_pcm_get_params_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t*, snd_pcm_uframes_t*);
+extern size_t (*snd_pcm_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_pcm_info_malloc_dylibloader_wrapper_asound)( snd_pcm_info_t**);
+extern void (*snd_pcm_info_free_dylibloader_wrapper_asound)( snd_pcm_info_t*);
+extern void (*snd_pcm_info_copy_dylibloader_wrapper_asound)( snd_pcm_info_t*,const snd_pcm_info_t*);
+extern unsigned int (*snd_pcm_info_get_device_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern unsigned int (*snd_pcm_info_get_subdevice_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern snd_pcm_stream_t (*snd_pcm_info_get_stream_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern int (*snd_pcm_info_get_card_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern const char* (*snd_pcm_info_get_id_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern const char* (*snd_pcm_info_get_name_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern const char* (*snd_pcm_info_get_subdevice_name_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern snd_pcm_class_t (*snd_pcm_info_get_class_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern snd_pcm_subclass_t (*snd_pcm_info_get_subclass_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern unsigned int (*snd_pcm_info_get_subdevices_count_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern unsigned int (*snd_pcm_info_get_subdevices_avail_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern snd_pcm_sync_id_t (*snd_pcm_info_get_sync_dylibloader_wrapper_asound)(const snd_pcm_info_t*);
+extern void (*snd_pcm_info_set_device_dylibloader_wrapper_asound)( snd_pcm_info_t*, unsigned int);
+extern void (*snd_pcm_info_set_subdevice_dylibloader_wrapper_asound)( snd_pcm_info_t*, unsigned int);
+extern void (*snd_pcm_info_set_stream_dylibloader_wrapper_asound)( snd_pcm_info_t*, snd_pcm_stream_t);
+extern int (*snd_pcm_hw_params_any_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_can_mmap_sample_resolution_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_is_double_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_is_batch_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_is_block_transfer_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_is_monotonic_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_can_overrange_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_can_pause_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_can_resume_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_is_half_duplex_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_is_joint_duplex_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_can_sync_start_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_can_disable_period_wakeup_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_supports_audio_wallclock_ts_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_supports_audio_ts_type_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, int);
+extern int (*snd_pcm_hw_params_get_rate_numden_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, unsigned int*);
+extern int (*snd_pcm_hw_params_get_sbits_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_get_fifo_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*);
+extern size_t (*snd_pcm_hw_params_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_pcm_hw_params_malloc_dylibloader_wrapper_asound)( snd_pcm_hw_params_t**);
+extern void (*snd_pcm_hw_params_free_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*);
+extern void (*snd_pcm_hw_params_copy_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*,const snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_get_access_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_access_t*);
+extern int (*snd_pcm_hw_params_test_access_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t);
+extern int (*snd_pcm_hw_params_set_access_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t);
+extern int (*snd_pcm_hw_params_set_access_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t*);
+extern int (*snd_pcm_hw_params_set_access_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_t*);
+extern int (*snd_pcm_hw_params_set_access_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_access_mask_t*);
+extern int (*snd_pcm_hw_params_get_access_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_access_mask_t*);
+extern int (*snd_pcm_hw_params_get_format_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_format_t*);
+extern int (*snd_pcm_hw_params_test_format_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t);
+extern int (*snd_pcm_hw_params_set_format_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t);
+extern int (*snd_pcm_hw_params_set_format_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t*);
+extern int (*snd_pcm_hw_params_set_format_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_t*);
+extern int (*snd_pcm_hw_params_set_format_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_format_mask_t*);
+extern void (*snd_pcm_hw_params_get_format_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_format_mask_t*);
+extern int (*snd_pcm_hw_params_get_subformat_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_subformat_t*);
+extern int (*snd_pcm_hw_params_test_subformat_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t);
+extern int (*snd_pcm_hw_params_set_subformat_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t);
+extern int (*snd_pcm_hw_params_set_subformat_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t*);
+extern int (*snd_pcm_hw_params_set_subformat_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_t*);
+extern int (*snd_pcm_hw_params_set_subformat_mask_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_subformat_mask_t*);
+extern void (*snd_pcm_hw_params_get_subformat_mask_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_pcm_subformat_mask_t*);
+extern int (*snd_pcm_hw_params_get_channels_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_get_channels_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_get_channels_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_test_channels_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+extern int (*snd_pcm_hw_params_set_channels_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+extern int (*snd_pcm_hw_params_set_channels_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_set_channels_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_set_channels_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, unsigned int*);
+extern int (*snd_pcm_hw_params_set_channels_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_set_channels_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_set_channels_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_get_rate_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_rate_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_rate_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_test_rate_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_rate_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_rate_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_rate_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_rate_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_rate_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_rate_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_rate_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_rate_resample_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+extern int (*snd_pcm_hw_params_get_rate_resample_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_set_export_buffer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+extern int (*snd_pcm_hw_params_get_export_buffer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_set_period_wakeup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int);
+extern int (*snd_pcm_hw_params_get_period_wakeup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_get_period_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_period_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_period_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_test_period_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_period_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_period_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_period_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_period_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_period_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_period_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_period_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_period_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_get_period_size_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_get_period_size_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_test_period_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t, int);
+extern int (*snd_pcm_hw_params_set_period_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t, int);
+extern int (*snd_pcm_hw_params_set_period_size_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_set_period_size_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_set_period_size_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_set_period_size_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_set_period_size_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_set_period_size_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, int*);
+extern int (*snd_pcm_hw_params_set_period_size_integer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_get_periods_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_periods_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_periods_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_test_periods_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_periods_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_periods_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_periods_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_periods_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_periods_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_periods_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_periods_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_periods_integer_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*);
+extern int (*snd_pcm_hw_params_get_buffer_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_buffer_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_buffer_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_test_buffer_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_buffer_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_buffer_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_buffer_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_buffer_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_buffer_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_buffer_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_buffer_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_buffer_size_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_get_buffer_size_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_get_buffer_size_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_test_buffer_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t);
+extern int (*snd_pcm_hw_params_set_buffer_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t);
+extern int (*snd_pcm_hw_params_set_buffer_size_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_set_buffer_size_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_set_buffer_size_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_set_buffer_size_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_set_buffer_size_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_set_buffer_size_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_hw_params_get_min_align_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, snd_pcm_uframes_t*);
+extern size_t (*snd_pcm_sw_params_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_pcm_sw_params_malloc_dylibloader_wrapper_asound)( snd_pcm_sw_params_t**);
+extern void (*snd_pcm_sw_params_free_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*);
+extern void (*snd_pcm_sw_params_copy_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*,const snd_pcm_sw_params_t*);
+extern int (*snd_pcm_sw_params_get_boundary_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_sw_params_set_tstamp_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_tstamp_t);
+extern int (*snd_pcm_sw_params_get_tstamp_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_tstamp_t*);
+extern int (*snd_pcm_sw_params_set_avail_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+extern int (*snd_pcm_sw_params_get_avail_min_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_sw_params_set_period_event_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, int);
+extern int (*snd_pcm_sw_params_get_period_event_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, int*);
+extern int (*snd_pcm_sw_params_set_start_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+extern int (*snd_pcm_sw_params_get_start_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_sw_params_set_stop_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+extern int (*snd_pcm_sw_params_get_stop_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_sw_params_set_silence_threshold_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+extern int (*snd_pcm_sw_params_get_silence_threshold_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_sw_params_set_silence_size_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+extern int (*snd_pcm_sw_params_get_silence_size_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+extern size_t (*snd_pcm_access_mask_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_pcm_access_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_access_mask_t**);
+extern void (*snd_pcm_access_mask_free_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*);
+extern void (*snd_pcm_access_mask_copy_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*,const snd_pcm_access_mask_t*);
+extern void (*snd_pcm_access_mask_none_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*);
+extern void (*snd_pcm_access_mask_any_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*);
+extern int (*snd_pcm_access_mask_test_dylibloader_wrapper_asound)(const snd_pcm_access_mask_t*, snd_pcm_access_t);
+extern int (*snd_pcm_access_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_access_mask_t*);
+extern void (*snd_pcm_access_mask_set_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*, snd_pcm_access_t);
+extern void (*snd_pcm_access_mask_reset_dylibloader_wrapper_asound)( snd_pcm_access_mask_t*, snd_pcm_access_t);
+extern size_t (*snd_pcm_format_mask_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_pcm_format_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_format_mask_t**);
+extern void (*snd_pcm_format_mask_free_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*);
+extern void (*snd_pcm_format_mask_copy_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*,const snd_pcm_format_mask_t*);
+extern void (*snd_pcm_format_mask_none_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*);
+extern void (*snd_pcm_format_mask_any_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*);
+extern int (*snd_pcm_format_mask_test_dylibloader_wrapper_asound)(const snd_pcm_format_mask_t*, snd_pcm_format_t);
+extern int (*snd_pcm_format_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_format_mask_t*);
+extern void (*snd_pcm_format_mask_set_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*, snd_pcm_format_t);
+extern void (*snd_pcm_format_mask_reset_dylibloader_wrapper_asound)( snd_pcm_format_mask_t*, snd_pcm_format_t);
+extern size_t (*snd_pcm_subformat_mask_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_pcm_subformat_mask_malloc_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t**);
+extern void (*snd_pcm_subformat_mask_free_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*);
+extern void (*snd_pcm_subformat_mask_copy_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*,const snd_pcm_subformat_mask_t*);
+extern void (*snd_pcm_subformat_mask_none_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*);
+extern void (*snd_pcm_subformat_mask_any_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*);
+extern int (*snd_pcm_subformat_mask_test_dylibloader_wrapper_asound)(const snd_pcm_subformat_mask_t*, snd_pcm_subformat_t);
+extern int (*snd_pcm_subformat_mask_empty_dylibloader_wrapper_asound)(const snd_pcm_subformat_mask_t*);
+extern void (*snd_pcm_subformat_mask_set_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*, snd_pcm_subformat_t);
+extern void (*snd_pcm_subformat_mask_reset_dylibloader_wrapper_asound)( snd_pcm_subformat_mask_t*, snd_pcm_subformat_t);
+extern size_t (*snd_pcm_status_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_pcm_status_malloc_dylibloader_wrapper_asound)( snd_pcm_status_t**);
+extern void (*snd_pcm_status_free_dylibloader_wrapper_asound)( snd_pcm_status_t*);
+extern void (*snd_pcm_status_copy_dylibloader_wrapper_asound)( snd_pcm_status_t*,const snd_pcm_status_t*);
+extern snd_pcm_state_t (*snd_pcm_status_get_state_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+extern void (*snd_pcm_status_get_trigger_tstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_timestamp_t*);
+extern void (*snd_pcm_status_get_trigger_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*);
+extern void (*snd_pcm_status_get_tstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_timestamp_t*);
+extern void (*snd_pcm_status_get_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*);
+extern void (*snd_pcm_status_get_audio_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*);
+extern void (*snd_pcm_status_get_driver_htstamp_dylibloader_wrapper_asound)(const snd_pcm_status_t*, snd_htimestamp_t*);
+extern snd_pcm_sframes_t (*snd_pcm_status_get_delay_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+extern snd_pcm_uframes_t (*snd_pcm_status_get_avail_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+extern snd_pcm_uframes_t (*snd_pcm_status_get_avail_max_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+extern snd_pcm_uframes_t (*snd_pcm_status_get_overrange_dylibloader_wrapper_asound)(const snd_pcm_status_t*);
+extern const char* (*snd_pcm_type_name_dylibloader_wrapper_asound)( snd_pcm_type_t);
+extern const char* (*snd_pcm_stream_name_dylibloader_wrapper_asound)(const snd_pcm_stream_t);
+extern const char* (*snd_pcm_access_name_dylibloader_wrapper_asound)(const snd_pcm_access_t);
+extern const char* (*snd_pcm_format_name_dylibloader_wrapper_asound)(const snd_pcm_format_t);
+extern const char* (*snd_pcm_format_description_dylibloader_wrapper_asound)(const snd_pcm_format_t);
+extern const char* (*snd_pcm_subformat_name_dylibloader_wrapper_asound)(const snd_pcm_subformat_t);
+extern const char* (*snd_pcm_subformat_description_dylibloader_wrapper_asound)(const snd_pcm_subformat_t);
+extern snd_pcm_format_t (*snd_pcm_format_value_dylibloader_wrapper_asound)(const char*);
+extern const char* (*snd_pcm_tstamp_mode_name_dylibloader_wrapper_asound)(const snd_pcm_tstamp_t);
+extern const char* (*snd_pcm_state_name_dylibloader_wrapper_asound)(const snd_pcm_state_t);
+extern int (*snd_pcm_dump_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*);
+extern int (*snd_pcm_dump_hw_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*);
+extern int (*snd_pcm_dump_sw_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*);
+extern int (*snd_pcm_dump_setup_dylibloader_wrapper_asound)( snd_pcm_t*, snd_output_t*);
+extern int (*snd_pcm_hw_params_dump_dylibloader_wrapper_asound)( snd_pcm_hw_params_t*, snd_output_t*);
+extern int (*snd_pcm_sw_params_dump_dylibloader_wrapper_asound)( snd_pcm_sw_params_t*, snd_output_t*);
+extern int (*snd_pcm_status_dump_dylibloader_wrapper_asound)( snd_pcm_status_t*, snd_output_t*);
+extern int (*snd_pcm_mmap_begin_dylibloader_wrapper_asound)( snd_pcm_t*,const snd_pcm_channel_area_t**, snd_pcm_uframes_t*, snd_pcm_uframes_t*);
+extern snd_pcm_sframes_t (*snd_pcm_mmap_commit_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_uframes_t, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_mmap_writei_dylibloader_wrapper_asound)( snd_pcm_t*,const void*, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_mmap_readi_dylibloader_wrapper_asound)( snd_pcm_t*, void*, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_mmap_writen_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t);
+extern snd_pcm_sframes_t (*snd_pcm_mmap_readn_dylibloader_wrapper_asound)( snd_pcm_t*, void**, snd_pcm_uframes_t);
+extern int (*snd_pcm_format_signed_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_unsigned_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_linear_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_float_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_little_endian_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_big_endian_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_cpu_endian_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_width_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_physical_width_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern snd_pcm_format_t (*snd_pcm_build_linear_format_dylibloader_wrapper_asound)( int, int, int, int);
+extern ssize_t (*snd_pcm_format_size_dylibloader_wrapper_asound)( snd_pcm_format_t, size_t);
+extern uint8_t (*snd_pcm_format_silence_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern uint16_t (*snd_pcm_format_silence_16_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern uint32_t (*snd_pcm_format_silence_32_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern uint64_t (*snd_pcm_format_silence_64_dylibloader_wrapper_asound)( snd_pcm_format_t);
+extern int (*snd_pcm_format_set_silence_dylibloader_wrapper_asound)( snd_pcm_format_t, void*, unsigned int);
+extern snd_pcm_sframes_t (*snd_pcm_bytes_to_frames_dylibloader_wrapper_asound)( snd_pcm_t*, ssize_t);
+extern ssize_t (*snd_pcm_frames_to_bytes_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sframes_t);
+extern long (*snd_pcm_bytes_to_samples_dylibloader_wrapper_asound)( snd_pcm_t*, ssize_t);
+extern ssize_t (*snd_pcm_samples_to_bytes_dylibloader_wrapper_asound)( snd_pcm_t*, long);
+extern int (*snd_pcm_area_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t);
+extern int (*snd_pcm_areas_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t);
+extern int (*snd_pcm_area_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t);
+extern int (*snd_pcm_areas_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t);
+extern int (*snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const unsigned int, snd_pcm_uframes_t,const snd_pcm_format_t);
+extern snd_pcm_t* (*snd_pcm_hook_get_pcm_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
+extern void* (*snd_pcm_hook_get_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
+extern void (*snd_pcm_hook_set_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*, void*);
+extern int (*snd_pcm_hook_add_dylibloader_wrapper_asound)( snd_pcm_hook_t**, snd_pcm_t*, snd_pcm_hook_type_t, snd_pcm_hook_func_t, void*);
+extern int (*snd_pcm_hook_remove_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
+extern snd_pcm_uframes_t (*snd_pcm_meter_get_bufsize_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern unsigned int (*snd_pcm_meter_get_channels_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern unsigned int (*snd_pcm_meter_get_rate_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_uframes_t (*snd_pcm_meter_get_now_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern snd_pcm_uframes_t (*snd_pcm_meter_get_boundary_dylibloader_wrapper_asound)( snd_pcm_t*);
+extern int (*snd_pcm_meter_add_scope_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_scope_t*);
+extern snd_pcm_scope_t* (*snd_pcm_meter_search_scope_dylibloader_wrapper_asound)( snd_pcm_t*,const char*);
+extern int (*snd_pcm_scope_malloc_dylibloader_wrapper_asound)( snd_pcm_scope_t**);
+extern void (*snd_pcm_scope_set_ops_dylibloader_wrapper_asound)( snd_pcm_scope_t*,const snd_pcm_scope_ops_t*);
+extern void (*snd_pcm_scope_set_name_dylibloader_wrapper_asound)( snd_pcm_scope_t*,const char*);
+extern const char* (*snd_pcm_scope_get_name_dylibloader_wrapper_asound)( snd_pcm_scope_t*);
+extern void* (*snd_pcm_scope_get_callback_private_dylibloader_wrapper_asound)( snd_pcm_scope_t*);
+extern void (*snd_pcm_scope_set_callback_private_dylibloader_wrapper_asound)( snd_pcm_scope_t*, void*);
+extern int (*snd_pcm_scope_s16_open_dylibloader_wrapper_asound)( snd_pcm_t*,const char*, snd_pcm_scope_t**);
+extern int16_t* (*snd_pcm_scope_s16_get_channel_buffer_dylibloader_wrapper_asound)( snd_pcm_scope_t*, unsigned int);
+extern int (*snd_spcm_init_dylibloader_wrapper_asound)( snd_pcm_t*, unsigned int, unsigned int, snd_pcm_format_t, snd_pcm_subformat_t, snd_spcm_latency_t, snd_pcm_access_t, snd_spcm_xrun_type_t);
+extern int (*snd_spcm_init_duplex_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_t*, unsigned int, unsigned int, snd_pcm_format_t, snd_pcm_subformat_t, snd_spcm_latency_t, snd_pcm_access_t, snd_spcm_xrun_type_t, snd_spcm_duplex_type_t);
+extern int (*snd_spcm_init_get_params_dylibloader_wrapper_asound)( snd_pcm_t*, unsigned int*, snd_pcm_uframes_t*, snd_pcm_uframes_t*);
+extern const char* (*snd_pcm_start_mode_name_dylibloader_wrapper_asound)( snd_pcm_start_t);
+extern const char* (*snd_pcm_xrun_mode_name_dylibloader_wrapper_asound)( snd_pcm_xrun_t);
+extern int (*snd_pcm_sw_params_set_start_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_start_t);
+extern snd_pcm_start_t (*snd_pcm_sw_params_get_start_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*);
+extern int (*snd_pcm_sw_params_set_xrun_mode_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_xrun_t);
+extern snd_pcm_xrun_t (*snd_pcm_sw_params_get_xrun_mode_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*);
+extern int (*snd_pcm_sw_params_set_xfer_align_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, snd_pcm_uframes_t);
+extern int (*snd_pcm_sw_params_get_xfer_align_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, snd_pcm_uframes_t*);
+extern int (*snd_pcm_sw_params_set_sleep_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_sw_params_t*, unsigned int);
+extern int (*snd_pcm_sw_params_get_sleep_min_dylibloader_wrapper_asound)(const snd_pcm_sw_params_t*, unsigned int*);
+extern int (*snd_pcm_hw_params_get_tick_time_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_tick_time_min_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_get_tick_time_max_dylibloader_wrapper_asound)(const snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_test_tick_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_tick_time_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int, int);
+extern int (*snd_pcm_hw_params_set_tick_time_min_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_tick_time_max_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_tick_time_minmax_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_tick_time_near_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_tick_time_first_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_pcm_hw_params_set_tick_time_last_dylibloader_wrapper_asound)( snd_pcm_t*, snd_pcm_hw_params_t*, unsigned int*, int*);
+extern int (*snd_rawmidi_open_dylibloader_wrapper_asound)( snd_rawmidi_t**, snd_rawmidi_t**,const char*, int);
+extern int (*snd_rawmidi_open_lconf_dylibloader_wrapper_asound)( snd_rawmidi_t**, snd_rawmidi_t**,const char*, int, snd_config_t*);
+extern int (*snd_rawmidi_close_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+extern int (*snd_rawmidi_poll_descriptors_count_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+extern int (*snd_rawmidi_poll_descriptors_dylibloader_wrapper_asound)( snd_rawmidi_t*,struct pollfd*, unsigned int);
+extern int (*snd_rawmidi_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_rawmidi_t*,struct pollfd*, unsigned int, unsigned short*);
+extern int (*snd_rawmidi_nonblock_dylibloader_wrapper_asound)( snd_rawmidi_t*, int);
+extern size_t (*snd_rawmidi_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_rawmidi_info_malloc_dylibloader_wrapper_asound)( snd_rawmidi_info_t**);
+extern void (*snd_rawmidi_info_free_dylibloader_wrapper_asound)( snd_rawmidi_info_t*);
+extern void (*snd_rawmidi_info_copy_dylibloader_wrapper_asound)( snd_rawmidi_info_t*,const snd_rawmidi_info_t*);
+extern unsigned int (*snd_rawmidi_info_get_device_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern unsigned int (*snd_rawmidi_info_get_subdevice_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern snd_rawmidi_stream_t (*snd_rawmidi_info_get_stream_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern int (*snd_rawmidi_info_get_card_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern unsigned int (*snd_rawmidi_info_get_flags_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern const char* (*snd_rawmidi_info_get_id_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern const char* (*snd_rawmidi_info_get_name_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern const char* (*snd_rawmidi_info_get_subdevice_name_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern unsigned int (*snd_rawmidi_info_get_subdevices_count_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern unsigned int (*snd_rawmidi_info_get_subdevices_avail_dylibloader_wrapper_asound)(const snd_rawmidi_info_t*);
+extern void (*snd_rawmidi_info_set_device_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, unsigned int);
+extern void (*snd_rawmidi_info_set_subdevice_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, unsigned int);
+extern void (*snd_rawmidi_info_set_stream_dylibloader_wrapper_asound)( snd_rawmidi_info_t*, snd_rawmidi_stream_t);
+extern int (*snd_rawmidi_info_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_info_t*);
+extern size_t (*snd_rawmidi_params_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_rawmidi_params_malloc_dylibloader_wrapper_asound)( snd_rawmidi_params_t**);
+extern void (*snd_rawmidi_params_free_dylibloader_wrapper_asound)( snd_rawmidi_params_t*);
+extern void (*snd_rawmidi_params_copy_dylibloader_wrapper_asound)( snd_rawmidi_params_t*,const snd_rawmidi_params_t*);
+extern int (*snd_rawmidi_params_set_buffer_size_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, size_t);
+extern size_t (*snd_rawmidi_params_get_buffer_size_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*);
+extern int (*snd_rawmidi_params_set_avail_min_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, size_t);
+extern size_t (*snd_rawmidi_params_get_avail_min_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*);
+extern int (*snd_rawmidi_params_set_no_active_sensing_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*, int);
+extern int (*snd_rawmidi_params_get_no_active_sensing_dylibloader_wrapper_asound)(const snd_rawmidi_params_t*);
+extern int (*snd_rawmidi_params_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*);
+extern int (*snd_rawmidi_params_current_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_params_t*);
+extern size_t (*snd_rawmidi_status_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_rawmidi_status_malloc_dylibloader_wrapper_asound)( snd_rawmidi_status_t**);
+extern void (*snd_rawmidi_status_free_dylibloader_wrapper_asound)( snd_rawmidi_status_t*);
+extern void (*snd_rawmidi_status_copy_dylibloader_wrapper_asound)( snd_rawmidi_status_t*,const snd_rawmidi_status_t*);
+extern void (*snd_rawmidi_status_get_tstamp_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*, snd_htimestamp_t*);
+extern size_t (*snd_rawmidi_status_get_avail_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*);
+extern size_t (*snd_rawmidi_status_get_xruns_dylibloader_wrapper_asound)(const snd_rawmidi_status_t*);
+extern int (*snd_rawmidi_status_dylibloader_wrapper_asound)( snd_rawmidi_t*, snd_rawmidi_status_t*);
+extern int (*snd_rawmidi_drain_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+extern int (*snd_rawmidi_drop_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+extern ssize_t (*snd_rawmidi_write_dylibloader_wrapper_asound)( snd_rawmidi_t*,const void*, size_t);
+extern ssize_t (*snd_rawmidi_read_dylibloader_wrapper_asound)( snd_rawmidi_t*, void*, size_t);
+extern const char* (*snd_rawmidi_name_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+extern snd_rawmidi_type_t (*snd_rawmidi_type_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+extern snd_rawmidi_stream_t (*snd_rawmidi_stream_dylibloader_wrapper_asound)( snd_rawmidi_t*);
+extern int (*snd_timer_query_open_dylibloader_wrapper_asound)( snd_timer_query_t**,const char*, int);
+extern int (*snd_timer_query_open_lconf_dylibloader_wrapper_asound)( snd_timer_query_t**,const char*, int, snd_config_t*);
+extern int (*snd_timer_query_close_dylibloader_wrapper_asound)( snd_timer_query_t*);
+extern int (*snd_timer_query_next_device_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_id_t*);
+extern int (*snd_timer_query_info_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_ginfo_t*);
+extern int (*snd_timer_query_params_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_gparams_t*);
+extern int (*snd_timer_query_status_dylibloader_wrapper_asound)( snd_timer_query_t*, snd_timer_gstatus_t*);
+extern int (*snd_timer_open_dylibloader_wrapper_asound)( snd_timer_t**,const char*, int);
+extern int (*snd_timer_open_lconf_dylibloader_wrapper_asound)( snd_timer_t**,const char*, int, snd_config_t*);
+extern int (*snd_timer_close_dylibloader_wrapper_asound)( snd_timer_t*);
+extern int (*snd_async_add_timer_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_timer_t*, snd_async_callback_t, void*);
+extern snd_timer_t* (*snd_async_handler_get_timer_dylibloader_wrapper_asound)( snd_async_handler_t*);
+extern int (*snd_timer_poll_descriptors_count_dylibloader_wrapper_asound)( snd_timer_t*);
+extern int (*snd_timer_poll_descriptors_dylibloader_wrapper_asound)( snd_timer_t*,struct pollfd*, unsigned int);
+extern int (*snd_timer_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_timer_t*,struct pollfd*, unsigned int, unsigned short*);
+extern int (*snd_timer_info_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_info_t*);
+extern int (*snd_timer_params_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_params_t*);
+extern int (*snd_timer_status_dylibloader_wrapper_asound)( snd_timer_t*, snd_timer_status_t*);
+extern int (*snd_timer_start_dylibloader_wrapper_asound)( snd_timer_t*);
+extern int (*snd_timer_stop_dylibloader_wrapper_asound)( snd_timer_t*);
+extern int (*snd_timer_continue_dylibloader_wrapper_asound)( snd_timer_t*);
+extern ssize_t (*snd_timer_read_dylibloader_wrapper_asound)( snd_timer_t*, void*, size_t);
+extern size_t (*snd_timer_id_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_timer_id_malloc_dylibloader_wrapper_asound)( snd_timer_id_t**);
+extern void (*snd_timer_id_free_dylibloader_wrapper_asound)( snd_timer_id_t*);
+extern void (*snd_timer_id_copy_dylibloader_wrapper_asound)( snd_timer_id_t*,const snd_timer_id_t*);
+extern void (*snd_timer_id_set_class_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+extern int (*snd_timer_id_get_class_dylibloader_wrapper_asound)( snd_timer_id_t*);
+extern void (*snd_timer_id_set_sclass_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+extern int (*snd_timer_id_get_sclass_dylibloader_wrapper_asound)( snd_timer_id_t*);
+extern void (*snd_timer_id_set_card_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+extern int (*snd_timer_id_get_card_dylibloader_wrapper_asound)( snd_timer_id_t*);
+extern void (*snd_timer_id_set_device_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+extern int (*snd_timer_id_get_device_dylibloader_wrapper_asound)( snd_timer_id_t*);
+extern void (*snd_timer_id_set_subdevice_dylibloader_wrapper_asound)( snd_timer_id_t*, int);
+extern int (*snd_timer_id_get_subdevice_dylibloader_wrapper_asound)( snd_timer_id_t*);
+extern size_t (*snd_timer_ginfo_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_timer_ginfo_malloc_dylibloader_wrapper_asound)( snd_timer_ginfo_t**);
+extern void (*snd_timer_ginfo_free_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern void (*snd_timer_ginfo_copy_dylibloader_wrapper_asound)( snd_timer_ginfo_t*,const snd_timer_ginfo_t*);
+extern int (*snd_timer_ginfo_set_tid_dylibloader_wrapper_asound)( snd_timer_ginfo_t*, snd_timer_id_t*);
+extern snd_timer_id_t* (*snd_timer_ginfo_get_tid_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern unsigned int (*snd_timer_ginfo_get_flags_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern int (*snd_timer_ginfo_get_card_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern char* (*snd_timer_ginfo_get_id_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern char* (*snd_timer_ginfo_get_name_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern unsigned long (*snd_timer_ginfo_get_resolution_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern unsigned long (*snd_timer_ginfo_get_resolution_min_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern unsigned long (*snd_timer_ginfo_get_resolution_max_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern unsigned int (*snd_timer_ginfo_get_clients_dylibloader_wrapper_asound)( snd_timer_ginfo_t*);
+extern size_t (*snd_timer_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_timer_info_malloc_dylibloader_wrapper_asound)( snd_timer_info_t**);
+extern void (*snd_timer_info_free_dylibloader_wrapper_asound)( snd_timer_info_t*);
+extern void (*snd_timer_info_copy_dylibloader_wrapper_asound)( snd_timer_info_t*,const snd_timer_info_t*);
+extern int (*snd_timer_info_is_slave_dylibloader_wrapper_asound)( snd_timer_info_t*);
+extern int (*snd_timer_info_get_card_dylibloader_wrapper_asound)( snd_timer_info_t*);
+extern const char* (*snd_timer_info_get_id_dylibloader_wrapper_asound)( snd_timer_info_t*);
+extern const char* (*snd_timer_info_get_name_dylibloader_wrapper_asound)( snd_timer_info_t*);
+extern long (*snd_timer_info_get_resolution_dylibloader_wrapper_asound)( snd_timer_info_t*);
+extern size_t (*snd_timer_params_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_timer_params_malloc_dylibloader_wrapper_asound)( snd_timer_params_t**);
+extern void (*snd_timer_params_free_dylibloader_wrapper_asound)( snd_timer_params_t*);
+extern void (*snd_timer_params_copy_dylibloader_wrapper_asound)( snd_timer_params_t*,const snd_timer_params_t*);
+extern int (*snd_timer_params_set_auto_start_dylibloader_wrapper_asound)( snd_timer_params_t*, int);
+extern int (*snd_timer_params_get_auto_start_dylibloader_wrapper_asound)( snd_timer_params_t*);
+extern int (*snd_timer_params_set_exclusive_dylibloader_wrapper_asound)( snd_timer_params_t*, int);
+extern int (*snd_timer_params_get_exclusive_dylibloader_wrapper_asound)( snd_timer_params_t*);
+extern int (*snd_timer_params_set_early_event_dylibloader_wrapper_asound)( snd_timer_params_t*, int);
+extern int (*snd_timer_params_get_early_event_dylibloader_wrapper_asound)( snd_timer_params_t*);
+extern void (*snd_timer_params_set_ticks_dylibloader_wrapper_asound)( snd_timer_params_t*, long);
+extern long (*snd_timer_params_get_ticks_dylibloader_wrapper_asound)( snd_timer_params_t*);
+extern void (*snd_timer_params_set_queue_size_dylibloader_wrapper_asound)( snd_timer_params_t*, long);
+extern long (*snd_timer_params_get_queue_size_dylibloader_wrapper_asound)( snd_timer_params_t*);
+extern void (*snd_timer_params_set_filter_dylibloader_wrapper_asound)( snd_timer_params_t*, unsigned int);
+extern unsigned int (*snd_timer_params_get_filter_dylibloader_wrapper_asound)( snd_timer_params_t*);
+extern size_t (*snd_timer_status_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_timer_status_malloc_dylibloader_wrapper_asound)( snd_timer_status_t**);
+extern void (*snd_timer_status_free_dylibloader_wrapper_asound)( snd_timer_status_t*);
+extern void (*snd_timer_status_copy_dylibloader_wrapper_asound)( snd_timer_status_t*,const snd_timer_status_t*);
+extern snd_htimestamp_t (*snd_timer_status_get_timestamp_dylibloader_wrapper_asound)( snd_timer_status_t*);
+extern long (*snd_timer_status_get_resolution_dylibloader_wrapper_asound)( snd_timer_status_t*);
+extern long (*snd_timer_status_get_lost_dylibloader_wrapper_asound)( snd_timer_status_t*);
+extern long (*snd_timer_status_get_overrun_dylibloader_wrapper_asound)( snd_timer_status_t*);
+extern long (*snd_timer_status_get_queue_dylibloader_wrapper_asound)( snd_timer_status_t*);
+extern long (*snd_timer_info_get_ticks_dylibloader_wrapper_asound)( snd_timer_info_t*);
+extern int (*snd_hwdep_open_dylibloader_wrapper_asound)( snd_hwdep_t**,const char*, int);
+extern int (*snd_hwdep_close_dylibloader_wrapper_asound)( snd_hwdep_t*);
+extern int (*snd_hwdep_poll_descriptors_dylibloader_wrapper_asound)( snd_hwdep_t*,struct pollfd*, unsigned int);
+extern int (*snd_hwdep_poll_descriptors_count_dylibloader_wrapper_asound)( snd_hwdep_t*);
+extern int (*snd_hwdep_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_hwdep_t*,struct pollfd*, unsigned int, unsigned short*);
+extern int (*snd_hwdep_nonblock_dylibloader_wrapper_asound)( snd_hwdep_t*, int);
+extern int (*snd_hwdep_info_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_info_t*);
+extern int (*snd_hwdep_dsp_status_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_dsp_status_t*);
+extern int (*snd_hwdep_dsp_load_dylibloader_wrapper_asound)( snd_hwdep_t*, snd_hwdep_dsp_image_t*);
+extern int (*snd_hwdep_ioctl_dylibloader_wrapper_asound)( snd_hwdep_t*, unsigned int, void*);
+extern ssize_t (*snd_hwdep_write_dylibloader_wrapper_asound)( snd_hwdep_t*,const void*, size_t);
+extern ssize_t (*snd_hwdep_read_dylibloader_wrapper_asound)( snd_hwdep_t*, void*, size_t);
+extern size_t (*snd_hwdep_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_hwdep_info_malloc_dylibloader_wrapper_asound)( snd_hwdep_info_t**);
+extern void (*snd_hwdep_info_free_dylibloader_wrapper_asound)( snd_hwdep_info_t*);
+extern void (*snd_hwdep_info_copy_dylibloader_wrapper_asound)( snd_hwdep_info_t*,const snd_hwdep_info_t*);
+extern unsigned int (*snd_hwdep_info_get_device_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+extern int (*snd_hwdep_info_get_card_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+extern const char* (*snd_hwdep_info_get_id_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+extern const char* (*snd_hwdep_info_get_name_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+extern snd_hwdep_iface_t (*snd_hwdep_info_get_iface_dylibloader_wrapper_asound)(const snd_hwdep_info_t*);
+extern void (*snd_hwdep_info_set_device_dylibloader_wrapper_asound)( snd_hwdep_info_t*, unsigned int);
+extern size_t (*snd_hwdep_dsp_status_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_hwdep_dsp_status_malloc_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t**);
+extern void (*snd_hwdep_dsp_status_free_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t*);
+extern void (*snd_hwdep_dsp_status_copy_dylibloader_wrapper_asound)( snd_hwdep_dsp_status_t*,const snd_hwdep_dsp_status_t*);
+extern unsigned int (*snd_hwdep_dsp_status_get_version_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+extern const char* (*snd_hwdep_dsp_status_get_id_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+extern unsigned int (*snd_hwdep_dsp_status_get_num_dsps_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+extern unsigned int (*snd_hwdep_dsp_status_get_dsp_loaded_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+extern unsigned int (*snd_hwdep_dsp_status_get_chip_ready_dylibloader_wrapper_asound)(const snd_hwdep_dsp_status_t*);
+extern size_t (*snd_hwdep_dsp_image_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_hwdep_dsp_image_malloc_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t**);
+extern void (*snd_hwdep_dsp_image_free_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*);
+extern void (*snd_hwdep_dsp_image_copy_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*,const snd_hwdep_dsp_image_t*);
+extern unsigned int (*snd_hwdep_dsp_image_get_index_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*);
+extern const char* (*snd_hwdep_dsp_image_get_name_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*);
+extern const void* (*snd_hwdep_dsp_image_get_image_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*);
+extern size_t (*snd_hwdep_dsp_image_get_length_dylibloader_wrapper_asound)(const snd_hwdep_dsp_image_t*);
+extern void (*snd_hwdep_dsp_image_set_index_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, unsigned int);
+extern void (*snd_hwdep_dsp_image_set_name_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*,const char*);
+extern void (*snd_hwdep_dsp_image_set_image_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, void*);
+extern void (*snd_hwdep_dsp_image_set_length_dylibloader_wrapper_asound)( snd_hwdep_dsp_image_t*, size_t);
+extern int (*snd_card_load_dylibloader_wrapper_asound)( int);
+extern int (*snd_card_next_dylibloader_wrapper_asound)( int*);
+extern int (*snd_card_get_index_dylibloader_wrapper_asound)(const char*);
+extern int (*snd_card_get_name_dylibloader_wrapper_asound)( int, char**);
+extern int (*snd_card_get_longname_dylibloader_wrapper_asound)( int, char**);
+extern int (*snd_device_name_hint_dylibloader_wrapper_asound)( int,const char*, void***);
+extern int (*snd_device_name_free_hint_dylibloader_wrapper_asound)( void**);
+extern char* (*snd_device_name_get_hint_dylibloader_wrapper_asound)(const void*,const char*);
+extern int (*snd_ctl_open_dylibloader_wrapper_asound)( snd_ctl_t**,const char*, int);
+extern int (*snd_ctl_open_lconf_dylibloader_wrapper_asound)( snd_ctl_t**,const char*, int, snd_config_t*);
+extern int (*snd_ctl_open_fallback_dylibloader_wrapper_asound)( snd_ctl_t**, snd_config_t*,const char*,const char*, int);
+extern int (*snd_ctl_close_dylibloader_wrapper_asound)( snd_ctl_t*);
+extern int (*snd_ctl_nonblock_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+extern int (*snd_async_add_ctl_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, snd_ctl_t*, snd_async_callback_t, void*);
+extern snd_ctl_t* (*snd_async_handler_get_ctl_dylibloader_wrapper_asound)( snd_async_handler_t*);
+extern int (*snd_ctl_poll_descriptors_count_dylibloader_wrapper_asound)( snd_ctl_t*);
+extern int (*snd_ctl_poll_descriptors_dylibloader_wrapper_asound)( snd_ctl_t*,struct pollfd*, unsigned int);
+extern int (*snd_ctl_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_ctl_t*,struct pollfd*, unsigned int, unsigned short*);
+extern int (*snd_ctl_subscribe_events_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+extern int (*snd_ctl_card_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_card_info_t*);
+extern int (*snd_ctl_elem_list_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_list_t*);
+extern int (*snd_ctl_elem_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_read_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*);
+extern int (*snd_ctl_elem_write_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*);
+extern int (*snd_ctl_elem_lock_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*);
+extern int (*snd_ctl_elem_unlock_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*);
+extern int (*snd_ctl_elem_tlv_read_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int*, unsigned int);
+extern int (*snd_ctl_elem_tlv_write_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*,const unsigned int*);
+extern int (*snd_ctl_elem_tlv_command_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*,const unsigned int*);
+extern int (*snd_ctl_hwdep_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*);
+extern int (*snd_ctl_hwdep_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_hwdep_info_t*);
+extern int (*snd_ctl_pcm_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*);
+extern int (*snd_ctl_pcm_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_pcm_info_t*);
+extern int (*snd_ctl_pcm_prefer_subdevice_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+extern int (*snd_ctl_rawmidi_next_device_dylibloader_wrapper_asound)( snd_ctl_t*, int*);
+extern int (*snd_ctl_rawmidi_info_dylibloader_wrapper_asound)( snd_ctl_t*, snd_rawmidi_info_t*);
+extern int (*snd_ctl_rawmidi_prefer_subdevice_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+extern int (*snd_ctl_set_power_state_dylibloader_wrapper_asound)( snd_ctl_t*, unsigned int);
+extern int (*snd_ctl_get_power_state_dylibloader_wrapper_asound)( snd_ctl_t*, unsigned int*);
+extern int (*snd_ctl_read_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_event_t*);
+extern int (*snd_ctl_wait_dylibloader_wrapper_asound)( snd_ctl_t*, int);
+extern const char* (*snd_ctl_name_dylibloader_wrapper_asound)( snd_ctl_t*);
+extern snd_ctl_type_t (*snd_ctl_type_dylibloader_wrapper_asound)( snd_ctl_t*);
+extern const char* (*snd_ctl_elem_type_name_dylibloader_wrapper_asound)( snd_ctl_elem_type_t);
+extern const char* (*snd_ctl_elem_iface_name_dylibloader_wrapper_asound)( snd_ctl_elem_iface_t);
+extern const char* (*snd_ctl_event_type_name_dylibloader_wrapper_asound)( snd_ctl_event_type_t);
+extern unsigned int (*snd_ctl_event_elem_get_mask_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+extern unsigned int (*snd_ctl_event_elem_get_numid_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+extern void (*snd_ctl_event_elem_get_id_dylibloader_wrapper_asound)(const snd_ctl_event_t*, snd_ctl_elem_id_t*);
+extern snd_ctl_elem_iface_t (*snd_ctl_event_elem_get_interface_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+extern unsigned int (*snd_ctl_event_elem_get_device_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+extern unsigned int (*snd_ctl_event_elem_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+extern const char* (*snd_ctl_event_elem_get_name_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+extern unsigned int (*snd_ctl_event_elem_get_index_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+extern int (*snd_ctl_elem_list_alloc_space_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*, unsigned int);
+extern void (*snd_ctl_elem_list_free_space_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*);
+extern char* (*snd_ctl_ascii_elem_id_get_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*);
+extern int (*snd_ctl_ascii_elem_id_parse_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const char*);
+extern int (*snd_ctl_ascii_value_parse_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_value_t*, snd_ctl_elem_info_t*,const char*);
+extern size_t (*snd_ctl_elem_id_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_ctl_elem_id_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_id_t**);
+extern void (*snd_ctl_elem_id_free_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*);
+extern void (*snd_ctl_elem_id_clear_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*);
+extern void (*snd_ctl_elem_id_copy_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const snd_ctl_elem_id_t*);
+extern unsigned int (*snd_ctl_elem_id_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+extern snd_ctl_elem_iface_t (*snd_ctl_elem_id_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+extern unsigned int (*snd_ctl_elem_id_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+extern unsigned int (*snd_ctl_elem_id_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+extern const char* (*snd_ctl_elem_id_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+extern unsigned int (*snd_ctl_elem_id_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_id_t*);
+extern void (*snd_ctl_elem_id_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int);
+extern void (*snd_ctl_elem_id_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, snd_ctl_elem_iface_t);
+extern void (*snd_ctl_elem_id_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int);
+extern void (*snd_ctl_elem_id_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int);
+extern void (*snd_ctl_elem_id_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*,const char*);
+extern void (*snd_ctl_elem_id_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_id_t*, unsigned int);
+extern size_t (*snd_ctl_card_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_ctl_card_info_malloc_dylibloader_wrapper_asound)( snd_ctl_card_info_t**);
+extern void (*snd_ctl_card_info_free_dylibloader_wrapper_asound)( snd_ctl_card_info_t*);
+extern void (*snd_ctl_card_info_clear_dylibloader_wrapper_asound)( snd_ctl_card_info_t*);
+extern void (*snd_ctl_card_info_copy_dylibloader_wrapper_asound)( snd_ctl_card_info_t*,const snd_ctl_card_info_t*);
+extern int (*snd_ctl_card_info_get_card_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+extern const char* (*snd_ctl_card_info_get_id_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+extern const char* (*snd_ctl_card_info_get_driver_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+extern const char* (*snd_ctl_card_info_get_name_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+extern const char* (*snd_ctl_card_info_get_longname_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+extern const char* (*snd_ctl_card_info_get_mixername_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+extern const char* (*snd_ctl_card_info_get_components_dylibloader_wrapper_asound)(const snd_ctl_card_info_t*);
+extern size_t (*snd_ctl_event_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_ctl_event_malloc_dylibloader_wrapper_asound)( snd_ctl_event_t**);
+extern void (*snd_ctl_event_free_dylibloader_wrapper_asound)( snd_ctl_event_t*);
+extern void (*snd_ctl_event_clear_dylibloader_wrapper_asound)( snd_ctl_event_t*);
+extern void (*snd_ctl_event_copy_dylibloader_wrapper_asound)( snd_ctl_event_t*,const snd_ctl_event_t*);
+extern snd_ctl_event_type_t (*snd_ctl_event_get_type_dylibloader_wrapper_asound)(const snd_ctl_event_t*);
+extern size_t (*snd_ctl_elem_list_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_ctl_elem_list_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_list_t**);
+extern void (*snd_ctl_elem_list_free_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*);
+extern void (*snd_ctl_elem_list_clear_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*);
+extern void (*snd_ctl_elem_list_copy_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*,const snd_ctl_elem_list_t*);
+extern void (*snd_ctl_elem_list_set_offset_dylibloader_wrapper_asound)( snd_ctl_elem_list_t*, unsigned int);
+extern unsigned int (*snd_ctl_elem_list_get_used_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*);
+extern unsigned int (*snd_ctl_elem_list_get_count_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*);
+extern void (*snd_ctl_elem_list_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int, snd_ctl_elem_id_t*);
+extern unsigned int (*snd_ctl_elem_list_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+extern snd_ctl_elem_iface_t (*snd_ctl_elem_list_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+extern unsigned int (*snd_ctl_elem_list_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+extern unsigned int (*snd_ctl_elem_list_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+extern const char* (*snd_ctl_elem_list_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+extern unsigned int (*snd_ctl_elem_list_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_list_t*, unsigned int);
+extern size_t (*snd_ctl_elem_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_ctl_elem_info_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_info_t**);
+extern void (*snd_ctl_elem_info_free_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*);
+extern void (*snd_ctl_elem_info_clear_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*);
+extern void (*snd_ctl_elem_info_copy_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const snd_ctl_elem_info_t*);
+extern snd_ctl_elem_type_t (*snd_ctl_elem_info_get_type_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_readable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_writable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_volatile_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_inactive_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_locked_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_tlv_readable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_tlv_writable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_tlv_commandable_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_owner_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_is_user_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern pid_t (*snd_ctl_elem_info_get_owner_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern unsigned int (*snd_ctl_elem_info_get_count_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern long (*snd_ctl_elem_info_get_min_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern long (*snd_ctl_elem_info_get_max_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern long (*snd_ctl_elem_info_get_step_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern long long (*snd_ctl_elem_info_get_min64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern long long (*snd_ctl_elem_info_get_max64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern long long (*snd_ctl_elem_info_get_step64_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern unsigned int (*snd_ctl_elem_info_get_items_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern void (*snd_ctl_elem_info_set_item_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+extern const char* (*snd_ctl_elem_info_get_item_name_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_get_dimensions_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern int (*snd_ctl_elem_info_get_dimension_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*, unsigned int);
+extern int (*snd_ctl_elem_info_set_dimension_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const int [4]);
+extern void (*snd_ctl_elem_info_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*, snd_ctl_elem_id_t*);
+extern unsigned int (*snd_ctl_elem_info_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern snd_ctl_elem_iface_t (*snd_ctl_elem_info_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern unsigned int (*snd_ctl_elem_info_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern unsigned int (*snd_ctl_elem_info_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern const char* (*snd_ctl_elem_info_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern unsigned int (*snd_ctl_elem_info_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_info_t*);
+extern void (*snd_ctl_elem_info_set_id_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const snd_ctl_elem_id_t*);
+extern void (*snd_ctl_elem_info_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+extern void (*snd_ctl_elem_info_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, snd_ctl_elem_iface_t);
+extern void (*snd_ctl_elem_info_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+extern void (*snd_ctl_elem_info_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+extern void (*snd_ctl_elem_info_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*,const char*);
+extern void (*snd_ctl_elem_info_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_info_t*, unsigned int);
+extern int (*snd_ctl_add_integer_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, long, long, long);
+extern int (*snd_ctl_add_integer64_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, long long, long long, long long);
+extern int (*snd_ctl_add_boolean_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int);
+extern int (*snd_ctl_add_enumerated_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int, unsigned int,const char* []);
+extern int (*snd_ctl_add_bytes_elem_set_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_info_t*, unsigned int, unsigned int);
+extern int (*snd_ctl_elem_add_integer_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, long, long, long);
+extern int (*snd_ctl_elem_add_integer64_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, long long, long long, long long);
+extern int (*snd_ctl_elem_add_boolean_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int);
+extern int (*snd_ctl_elem_add_enumerated_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, unsigned int, unsigned int,const char* []);
+extern int (*snd_ctl_elem_add_iec958_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*);
+extern int (*snd_ctl_elem_remove_dylibloader_wrapper_asound)( snd_ctl_t*, snd_ctl_elem_id_t*);
+extern size_t (*snd_ctl_elem_value_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_ctl_elem_value_malloc_dylibloader_wrapper_asound)( snd_ctl_elem_value_t**);
+extern void (*snd_ctl_elem_value_free_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*);
+extern void (*snd_ctl_elem_value_clear_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*);
+extern void (*snd_ctl_elem_value_copy_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_value_t*);
+extern int (*snd_ctl_elem_value_compare_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_value_t*);
+extern void (*snd_ctl_elem_value_get_id_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, snd_ctl_elem_id_t*);
+extern unsigned int (*snd_ctl_elem_value_get_numid_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+extern snd_ctl_elem_iface_t (*snd_ctl_elem_value_get_interface_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+extern unsigned int (*snd_ctl_elem_value_get_device_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+extern unsigned int (*snd_ctl_elem_value_get_subdevice_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+extern const char* (*snd_ctl_elem_value_get_name_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+extern unsigned int (*snd_ctl_elem_value_get_index_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+extern void (*snd_ctl_elem_value_set_id_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_ctl_elem_id_t*);
+extern void (*snd_ctl_elem_value_set_numid_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int);
+extern void (*snd_ctl_elem_value_set_interface_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, snd_ctl_elem_iface_t);
+extern void (*snd_ctl_elem_value_set_device_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int);
+extern void (*snd_ctl_elem_value_set_subdevice_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int);
+extern void (*snd_ctl_elem_value_set_name_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const char*);
+extern void (*snd_ctl_elem_value_set_index_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int);
+extern int (*snd_ctl_elem_value_get_boolean_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+extern long (*snd_ctl_elem_value_get_integer_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+extern long long (*snd_ctl_elem_value_get_integer64_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+extern unsigned int (*snd_ctl_elem_value_get_enumerated_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+extern unsigned char (*snd_ctl_elem_value_get_byte_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, unsigned int);
+extern void (*snd_ctl_elem_value_set_boolean_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long);
+extern void (*snd_ctl_elem_value_set_integer_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long);
+extern void (*snd_ctl_elem_value_set_integer64_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, long long);
+extern void (*snd_ctl_elem_value_set_enumerated_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, unsigned int);
+extern void (*snd_ctl_elem_value_set_byte_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, unsigned int, unsigned char);
+extern void (*snd_ctl_elem_set_bytes_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*, void*, size_t);
+extern const void* (*snd_ctl_elem_value_get_bytes_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*);
+extern void (*snd_ctl_elem_value_get_iec958_dylibloader_wrapper_asound)(const snd_ctl_elem_value_t*, snd_aes_iec958_t*);
+extern void (*snd_ctl_elem_value_set_iec958_dylibloader_wrapper_asound)( snd_ctl_elem_value_t*,const snd_aes_iec958_t*);
+extern int (*snd_tlv_parse_dB_info_dylibloader_wrapper_asound)( unsigned int*, unsigned int, unsigned int**);
+extern int (*snd_tlv_get_dB_range_dylibloader_wrapper_asound)( unsigned int*, long, long, long*, long*);
+extern int (*snd_tlv_convert_to_dB_dylibloader_wrapper_asound)( unsigned int*, long, long, long, long*);
+extern int (*snd_tlv_convert_from_dB_dylibloader_wrapper_asound)( unsigned int*, long, long, long, long*, int);
+extern int (*snd_ctl_get_dB_range_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long*, long*);
+extern int (*snd_ctl_convert_to_dB_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long, long*);
+extern int (*snd_ctl_convert_from_dB_dylibloader_wrapper_asound)( snd_ctl_t*,const snd_ctl_elem_id_t*, long, long*, int);
+extern int (*snd_hctl_compare_fast_dylibloader_wrapper_asound)(const snd_hctl_elem_t*,const snd_hctl_elem_t*);
+extern int (*snd_hctl_open_dylibloader_wrapper_asound)( snd_hctl_t**,const char*, int);
+extern int (*snd_hctl_open_ctl_dylibloader_wrapper_asound)( snd_hctl_t**, snd_ctl_t*);
+extern int (*snd_hctl_close_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern int (*snd_hctl_nonblock_dylibloader_wrapper_asound)( snd_hctl_t*, int);
+extern int (*snd_hctl_poll_descriptors_count_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern int (*snd_hctl_poll_descriptors_dylibloader_wrapper_asound)( snd_hctl_t*,struct pollfd*, unsigned int);
+extern int (*snd_hctl_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_hctl_t*,struct pollfd*, unsigned int, unsigned short*);
+extern unsigned int (*snd_hctl_get_count_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern int (*snd_hctl_set_compare_dylibloader_wrapper_asound)( snd_hctl_t*, snd_hctl_compare_t);
+extern snd_hctl_elem_t* (*snd_hctl_first_elem_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern snd_hctl_elem_t* (*snd_hctl_last_elem_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern snd_hctl_elem_t* (*snd_hctl_find_elem_dylibloader_wrapper_asound)( snd_hctl_t*,const snd_ctl_elem_id_t*);
+extern void (*snd_hctl_set_callback_dylibloader_wrapper_asound)( snd_hctl_t*, snd_hctl_callback_t);
+extern void (*snd_hctl_set_callback_private_dylibloader_wrapper_asound)( snd_hctl_t*, void*);
+extern void* (*snd_hctl_get_callback_private_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern int (*snd_hctl_load_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern int (*snd_hctl_free_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern int (*snd_hctl_handle_events_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern const char* (*snd_hctl_name_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern int (*snd_hctl_wait_dylibloader_wrapper_asound)( snd_hctl_t*, int);
+extern snd_ctl_t* (*snd_hctl_ctl_dylibloader_wrapper_asound)( snd_hctl_t*);
+extern snd_hctl_elem_t* (*snd_hctl_elem_next_dylibloader_wrapper_asound)( snd_hctl_elem_t*);
+extern snd_hctl_elem_t* (*snd_hctl_elem_prev_dylibloader_wrapper_asound)( snd_hctl_elem_t*);
+extern int (*snd_hctl_elem_info_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_info_t*);
+extern int (*snd_hctl_elem_read_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_value_t*);
+extern int (*snd_hctl_elem_write_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_ctl_elem_value_t*);
+extern int (*snd_hctl_elem_tlv_read_dylibloader_wrapper_asound)( snd_hctl_elem_t*, unsigned int*, unsigned int);
+extern int (*snd_hctl_elem_tlv_write_dylibloader_wrapper_asound)( snd_hctl_elem_t*,const unsigned int*);
+extern int (*snd_hctl_elem_tlv_command_dylibloader_wrapper_asound)( snd_hctl_elem_t*,const unsigned int*);
+extern snd_hctl_t* (*snd_hctl_elem_get_hctl_dylibloader_wrapper_asound)( snd_hctl_elem_t*);
+extern void (*snd_hctl_elem_get_id_dylibloader_wrapper_asound)(const snd_hctl_elem_t*, snd_ctl_elem_id_t*);
+extern unsigned int (*snd_hctl_elem_get_numid_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+extern snd_ctl_elem_iface_t (*snd_hctl_elem_get_interface_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+extern unsigned int (*snd_hctl_elem_get_device_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+extern unsigned int (*snd_hctl_elem_get_subdevice_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+extern const char* (*snd_hctl_elem_get_name_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+extern unsigned int (*snd_hctl_elem_get_index_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+extern void (*snd_hctl_elem_set_callback_dylibloader_wrapper_asound)( snd_hctl_elem_t*, snd_hctl_elem_callback_t);
+extern void* (*snd_hctl_elem_get_callback_private_dylibloader_wrapper_asound)(const snd_hctl_elem_t*);
+extern void (*snd_hctl_elem_set_callback_private_dylibloader_wrapper_asound)( snd_hctl_elem_t*, void*);
+extern int (*snd_sctl_build_dylibloader_wrapper_asound)( snd_sctl_t**, snd_ctl_t*, snd_config_t*, snd_config_t*, int);
+extern int (*snd_sctl_free_dylibloader_wrapper_asound)( snd_sctl_t*);
+extern int (*snd_sctl_install_dylibloader_wrapper_asound)( snd_sctl_t*);
+extern int (*snd_sctl_remove_dylibloader_wrapper_asound)( snd_sctl_t*);
+extern int (*snd_mixer_open_dylibloader_wrapper_asound)( snd_mixer_t**, int);
+extern int (*snd_mixer_close_dylibloader_wrapper_asound)( snd_mixer_t*);
+extern snd_mixer_elem_t* (*snd_mixer_first_elem_dylibloader_wrapper_asound)( snd_mixer_t*);
+extern snd_mixer_elem_t* (*snd_mixer_last_elem_dylibloader_wrapper_asound)( snd_mixer_t*);
+extern int (*snd_mixer_handle_events_dylibloader_wrapper_asound)( snd_mixer_t*);
+extern int (*snd_mixer_attach_dylibloader_wrapper_asound)( snd_mixer_t*,const char*);
+extern int (*snd_mixer_attach_hctl_dylibloader_wrapper_asound)( snd_mixer_t*, snd_hctl_t*);
+extern int (*snd_mixer_detach_dylibloader_wrapper_asound)( snd_mixer_t*,const char*);
+extern int (*snd_mixer_detach_hctl_dylibloader_wrapper_asound)( snd_mixer_t*, snd_hctl_t*);
+extern int (*snd_mixer_get_hctl_dylibloader_wrapper_asound)( snd_mixer_t*,const char*, snd_hctl_t**);
+extern int (*snd_mixer_poll_descriptors_count_dylibloader_wrapper_asound)( snd_mixer_t*);
+extern int (*snd_mixer_poll_descriptors_dylibloader_wrapper_asound)( snd_mixer_t*,struct pollfd*, unsigned int);
+extern int (*snd_mixer_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_mixer_t*,struct pollfd*, unsigned int, unsigned short*);
+extern int (*snd_mixer_load_dylibloader_wrapper_asound)( snd_mixer_t*);
+extern void (*snd_mixer_free_dylibloader_wrapper_asound)( snd_mixer_t*);
+extern int (*snd_mixer_wait_dylibloader_wrapper_asound)( snd_mixer_t*, int);
+extern int (*snd_mixer_set_compare_dylibloader_wrapper_asound)( snd_mixer_t*, snd_mixer_compare_t);
+extern void (*snd_mixer_set_callback_dylibloader_wrapper_asound)( snd_mixer_t*, snd_mixer_callback_t);
+extern void* (*snd_mixer_get_callback_private_dylibloader_wrapper_asound)(const snd_mixer_t*);
+extern void (*snd_mixer_set_callback_private_dylibloader_wrapper_asound)( snd_mixer_t*, void*);
+extern unsigned int (*snd_mixer_get_count_dylibloader_wrapper_asound)(const snd_mixer_t*);
+extern int (*snd_mixer_class_unregister_dylibloader_wrapper_asound)( snd_mixer_class_t*);
+extern snd_mixer_elem_t* (*snd_mixer_elem_next_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern snd_mixer_elem_t* (*snd_mixer_elem_prev_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern void (*snd_mixer_elem_set_callback_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_elem_callback_t);
+extern void* (*snd_mixer_elem_get_callback_private_dylibloader_wrapper_asound)(const snd_mixer_elem_t*);
+extern void (*snd_mixer_elem_set_callback_private_dylibloader_wrapper_asound)( snd_mixer_elem_t*, void*);
+extern snd_mixer_elem_type_t (*snd_mixer_elem_get_type_dylibloader_wrapper_asound)(const snd_mixer_elem_t*);
+extern int (*snd_mixer_class_register_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_t*);
+extern int (*snd_mixer_elem_new_dylibloader_wrapper_asound)( snd_mixer_elem_t**, snd_mixer_elem_type_t, int, void*, void*);
+extern int (*snd_mixer_elem_add_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_class_t*);
+extern int (*snd_mixer_elem_remove_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern void (*snd_mixer_elem_free_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_elem_info_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_elem_value_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_elem_attach_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_hctl_elem_t*);
+extern int (*snd_mixer_elem_detach_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_hctl_elem_t*);
+extern int (*snd_mixer_elem_empty_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern void* (*snd_mixer_elem_get_private_dylibloader_wrapper_asound)(const snd_mixer_elem_t*);
+extern size_t (*snd_mixer_class_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_mixer_class_malloc_dylibloader_wrapper_asound)( snd_mixer_class_t**);
+extern void (*snd_mixer_class_free_dylibloader_wrapper_asound)( snd_mixer_class_t*);
+extern void (*snd_mixer_class_copy_dylibloader_wrapper_asound)( snd_mixer_class_t*,const snd_mixer_class_t*);
+extern snd_mixer_t* (*snd_mixer_class_get_mixer_dylibloader_wrapper_asound)(const snd_mixer_class_t*);
+extern snd_mixer_event_t (*snd_mixer_class_get_event_dylibloader_wrapper_asound)(const snd_mixer_class_t*);
+extern void* (*snd_mixer_class_get_private_dylibloader_wrapper_asound)(const snd_mixer_class_t*);
+extern snd_mixer_compare_t (*snd_mixer_class_get_compare_dylibloader_wrapper_asound)(const snd_mixer_class_t*);
+extern int (*snd_mixer_class_set_event_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_event_t);
+extern int (*snd_mixer_class_set_private_dylibloader_wrapper_asound)( snd_mixer_class_t*, void*);
+extern int (*snd_mixer_class_set_private_free_dylibloader_wrapper_asound)( snd_mixer_class_t*, void*);
+extern int (*snd_mixer_class_set_compare_dylibloader_wrapper_asound)( snd_mixer_class_t*, snd_mixer_compare_t);
+extern const char* (*snd_mixer_selem_channel_name_dylibloader_wrapper_asound)( snd_mixer_selem_channel_id_t);
+extern int (*snd_mixer_selem_register_dylibloader_wrapper_asound)( snd_mixer_t*,struct snd_mixer_selem_regopt*, snd_mixer_class_t**);
+extern void (*snd_mixer_selem_get_id_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_id_t*);
+extern const char* (*snd_mixer_selem_get_name_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern unsigned int (*snd_mixer_selem_get_index_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern snd_mixer_elem_t* (*snd_mixer_find_selem_dylibloader_wrapper_asound)( snd_mixer_t*,const snd_mixer_selem_id_t*);
+extern int (*snd_mixer_selem_is_active_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_is_playback_mono_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_playback_channel_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t);
+extern int (*snd_mixer_selem_is_capture_mono_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_capture_channel_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t);
+extern int (*snd_mixer_selem_get_capture_group_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_common_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_playback_volume_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_capture_volume_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_common_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_playback_switch_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_capture_switch_joined_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_has_capture_switch_exclusive_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_ask_playback_vol_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long*);
+extern int (*snd_mixer_selem_ask_capture_vol_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long*);
+extern int (*snd_mixer_selem_ask_playback_dB_vol_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int, long*);
+extern int (*snd_mixer_selem_ask_capture_dB_vol_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int, long*);
+extern int (*snd_mixer_selem_get_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*);
+extern int (*snd_mixer_selem_get_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*);
+extern int (*snd_mixer_selem_get_playback_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*);
+extern int (*snd_mixer_selem_get_capture_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long*);
+extern int (*snd_mixer_selem_get_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int*);
+extern int (*snd_mixer_selem_get_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int*);
+extern int (*snd_mixer_selem_set_playback_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long);
+extern int (*snd_mixer_selem_set_capture_volume_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long);
+extern int (*snd_mixer_selem_set_playback_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long, int);
+extern int (*snd_mixer_selem_set_capture_dB_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, long, int);
+extern int (*snd_mixer_selem_set_playback_volume_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long);
+extern int (*snd_mixer_selem_set_capture_volume_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long);
+extern int (*snd_mixer_selem_set_playback_dB_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int);
+extern int (*snd_mixer_selem_set_capture_dB_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, int);
+extern int (*snd_mixer_selem_set_playback_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int);
+extern int (*snd_mixer_selem_set_capture_switch_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, int);
+extern int (*snd_mixer_selem_set_playback_switch_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, int);
+extern int (*snd_mixer_selem_set_capture_switch_all_dylibloader_wrapper_asound)( snd_mixer_elem_t*, int);
+extern int (*snd_mixer_selem_get_playback_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*);
+extern int (*snd_mixer_selem_get_playback_dB_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*);
+extern int (*snd_mixer_selem_set_playback_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long);
+extern int (*snd_mixer_selem_get_capture_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*);
+extern int (*snd_mixer_selem_get_capture_dB_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long*, long*);
+extern int (*snd_mixer_selem_set_capture_volume_range_dylibloader_wrapper_asound)( snd_mixer_elem_t*, long, long);
+extern int (*snd_mixer_selem_is_enumerated_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_is_enum_playback_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_is_enum_capture_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_get_enum_items_dylibloader_wrapper_asound)( snd_mixer_elem_t*);
+extern int (*snd_mixer_selem_get_enum_item_name_dylibloader_wrapper_asound)( snd_mixer_elem_t*, unsigned int, size_t, char*);
+extern int (*snd_mixer_selem_get_enum_item_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, unsigned int*);
+extern int (*snd_mixer_selem_set_enum_item_dylibloader_wrapper_asound)( snd_mixer_elem_t*, snd_mixer_selem_channel_id_t, unsigned int);
+extern size_t (*snd_mixer_selem_id_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_mixer_selem_id_malloc_dylibloader_wrapper_asound)( snd_mixer_selem_id_t**);
+extern void (*snd_mixer_selem_id_free_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*);
+extern void (*snd_mixer_selem_id_copy_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const snd_mixer_selem_id_t*);
+extern const char* (*snd_mixer_selem_id_get_name_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*);
+extern unsigned int (*snd_mixer_selem_id_get_index_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*);
+extern void (*snd_mixer_selem_id_set_name_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*);
+extern void (*snd_mixer_selem_id_set_index_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*, unsigned int);
+extern int (*snd_mixer_selem_id_parse_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*);
+extern int (*snd_seq_open_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int);
+extern int (*snd_seq_open_lconf_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int, snd_config_t*);
+extern const char* (*snd_seq_name_dylibloader_wrapper_asound)( snd_seq_t*);
+extern snd_seq_type_t (*snd_seq_type_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_close_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_poll_descriptors_count_dylibloader_wrapper_asound)( snd_seq_t*, short);
+extern int (*snd_seq_poll_descriptors_dylibloader_wrapper_asound)( snd_seq_t*,struct pollfd*, unsigned int, short);
+extern int (*snd_seq_poll_descriptors_revents_dylibloader_wrapper_asound)( snd_seq_t*,struct pollfd*, unsigned int, unsigned short*);
+extern int (*snd_seq_nonblock_dylibloader_wrapper_asound)( snd_seq_t*, int);
+extern int (*snd_seq_client_id_dylibloader_wrapper_asound)( snd_seq_t*);
+extern size_t (*snd_seq_get_output_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*);
+extern size_t (*snd_seq_get_input_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_set_output_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+extern int (*snd_seq_set_input_buffer_size_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+extern size_t (*snd_seq_system_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_system_info_malloc_dylibloader_wrapper_asound)( snd_seq_system_info_t**);
+extern void (*snd_seq_system_info_free_dylibloader_wrapper_asound)( snd_seq_system_info_t*);
+extern void (*snd_seq_system_info_copy_dylibloader_wrapper_asound)( snd_seq_system_info_t*,const snd_seq_system_info_t*);
+extern int (*snd_seq_system_info_get_queues_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+extern int (*snd_seq_system_info_get_clients_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+extern int (*snd_seq_system_info_get_ports_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+extern int (*snd_seq_system_info_get_channels_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+extern int (*snd_seq_system_info_get_cur_clients_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+extern int (*snd_seq_system_info_get_cur_queues_dylibloader_wrapper_asound)(const snd_seq_system_info_t*);
+extern int (*snd_seq_system_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_system_info_t*);
+extern size_t (*snd_seq_client_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_client_info_malloc_dylibloader_wrapper_asound)( snd_seq_client_info_t**);
+extern void (*snd_seq_client_info_free_dylibloader_wrapper_asound)( snd_seq_client_info_t*);
+extern void (*snd_seq_client_info_copy_dylibloader_wrapper_asound)( snd_seq_client_info_t*,const snd_seq_client_info_t*);
+extern int (*snd_seq_client_info_get_client_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern snd_seq_client_type_t (*snd_seq_client_info_get_type_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern const char* (*snd_seq_client_info_get_name_dylibloader_wrapper_asound)( snd_seq_client_info_t*);
+extern int (*snd_seq_client_info_get_broadcast_filter_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern int (*snd_seq_client_info_get_error_bounce_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern int (*snd_seq_client_info_get_card_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern int (*snd_seq_client_info_get_pid_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern const unsigned char* (*snd_seq_client_info_get_event_filter_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern int (*snd_seq_client_info_get_num_ports_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern int (*snd_seq_client_info_get_event_lost_dylibloader_wrapper_asound)(const snd_seq_client_info_t*);
+extern void (*snd_seq_client_info_set_client_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+extern void (*snd_seq_client_info_set_name_dylibloader_wrapper_asound)( snd_seq_client_info_t*,const char*);
+extern void (*snd_seq_client_info_set_broadcast_filter_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+extern void (*snd_seq_client_info_set_error_bounce_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+extern void (*snd_seq_client_info_set_event_filter_dylibloader_wrapper_asound)( snd_seq_client_info_t*, unsigned char*);
+extern void (*snd_seq_client_info_event_filter_clear_dylibloader_wrapper_asound)( snd_seq_client_info_t*);
+extern void (*snd_seq_client_info_event_filter_add_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+extern void (*snd_seq_client_info_event_filter_del_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+extern int (*snd_seq_client_info_event_filter_check_dylibloader_wrapper_asound)( snd_seq_client_info_t*, int);
+extern int (*snd_seq_get_client_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*);
+extern int (*snd_seq_get_any_client_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_client_info_t*);
+extern int (*snd_seq_set_client_info_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*);
+extern int (*snd_seq_query_next_client_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_info_t*);
+extern size_t (*snd_seq_client_pool_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_client_pool_malloc_dylibloader_wrapper_asound)( snd_seq_client_pool_t**);
+extern void (*snd_seq_client_pool_free_dylibloader_wrapper_asound)( snd_seq_client_pool_t*);
+extern void (*snd_seq_client_pool_copy_dylibloader_wrapper_asound)( snd_seq_client_pool_t*,const snd_seq_client_pool_t*);
+extern int (*snd_seq_client_pool_get_client_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+extern size_t (*snd_seq_client_pool_get_output_pool_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+extern size_t (*snd_seq_client_pool_get_input_pool_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+extern size_t (*snd_seq_client_pool_get_output_room_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+extern size_t (*snd_seq_client_pool_get_output_free_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+extern size_t (*snd_seq_client_pool_get_input_free_dylibloader_wrapper_asound)(const snd_seq_client_pool_t*);
+extern void (*snd_seq_client_pool_set_output_pool_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t);
+extern void (*snd_seq_client_pool_set_input_pool_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t);
+extern void (*snd_seq_client_pool_set_output_room_dylibloader_wrapper_asound)( snd_seq_client_pool_t*, size_t);
+extern int (*snd_seq_get_client_pool_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_pool_t*);
+extern int (*snd_seq_set_client_pool_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_client_pool_t*);
+extern size_t (*snd_seq_port_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_port_info_malloc_dylibloader_wrapper_asound)( snd_seq_port_info_t**);
+extern void (*snd_seq_port_info_free_dylibloader_wrapper_asound)( snd_seq_port_info_t*);
+extern void (*snd_seq_port_info_copy_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_client_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_port_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern const snd_seq_addr_t* (*snd_seq_port_info_get_addr_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern const char* (*snd_seq_port_info_get_name_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern unsigned int (*snd_seq_port_info_get_capability_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern unsigned int (*snd_seq_port_info_get_type_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_midi_channels_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_midi_voices_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_synth_voices_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_read_use_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_write_use_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_port_specified_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_timestamping_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_timestamp_real_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern int (*snd_seq_port_info_get_timestamp_queue_dylibloader_wrapper_asound)(const snd_seq_port_info_t*);
+extern void (*snd_seq_port_info_set_client_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern void (*snd_seq_port_info_set_port_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern void (*snd_seq_port_info_set_addr_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const snd_seq_addr_t*);
+extern void (*snd_seq_port_info_set_name_dylibloader_wrapper_asound)( snd_seq_port_info_t*,const char*);
+extern void (*snd_seq_port_info_set_capability_dylibloader_wrapper_asound)( snd_seq_port_info_t*, unsigned int);
+extern void (*snd_seq_port_info_set_type_dylibloader_wrapper_asound)( snd_seq_port_info_t*, unsigned int);
+extern void (*snd_seq_port_info_set_midi_channels_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern void (*snd_seq_port_info_set_midi_voices_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern void (*snd_seq_port_info_set_synth_voices_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern void (*snd_seq_port_info_set_port_specified_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern void (*snd_seq_port_info_set_timestamping_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern void (*snd_seq_port_info_set_timestamp_real_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern void (*snd_seq_port_info_set_timestamp_queue_dylibloader_wrapper_asound)( snd_seq_port_info_t*, int);
+extern int (*snd_seq_create_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_info_t*);
+extern int (*snd_seq_delete_port_dylibloader_wrapper_asound)( snd_seq_t*, int);
+extern int (*snd_seq_get_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_port_info_t*);
+extern int (*snd_seq_get_any_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, int, snd_seq_port_info_t*);
+extern int (*snd_seq_set_port_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_port_info_t*);
+extern int (*snd_seq_query_next_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_info_t*);
+extern size_t (*snd_seq_port_subscribe_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_port_subscribe_malloc_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t**);
+extern void (*snd_seq_port_subscribe_free_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*);
+extern void (*snd_seq_port_subscribe_copy_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_port_subscribe_t*);
+extern const snd_seq_addr_t* (*snd_seq_port_subscribe_get_sender_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+extern const snd_seq_addr_t* (*snd_seq_port_subscribe_get_dest_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+extern int (*snd_seq_port_subscribe_get_queue_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+extern int (*snd_seq_port_subscribe_get_exclusive_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+extern int (*snd_seq_port_subscribe_get_time_update_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+extern int (*snd_seq_port_subscribe_get_time_real_dylibloader_wrapper_asound)(const snd_seq_port_subscribe_t*);
+extern void (*snd_seq_port_subscribe_set_sender_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_addr_t*);
+extern void (*snd_seq_port_subscribe_set_dest_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*,const snd_seq_addr_t*);
+extern void (*snd_seq_port_subscribe_set_queue_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int);
+extern void (*snd_seq_port_subscribe_set_exclusive_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int);
+extern void (*snd_seq_port_subscribe_set_time_update_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int);
+extern void (*snd_seq_port_subscribe_set_time_real_dylibloader_wrapper_asound)( snd_seq_port_subscribe_t*, int);
+extern int (*snd_seq_get_port_subscription_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*);
+extern int (*snd_seq_subscribe_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*);
+extern int (*snd_seq_unsubscribe_port_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_port_subscribe_t*);
+extern size_t (*snd_seq_query_subscribe_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_query_subscribe_malloc_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t**);
+extern void (*snd_seq_query_subscribe_free_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*);
+extern void (*snd_seq_query_subscribe_copy_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*,const snd_seq_query_subscribe_t*);
+extern int (*snd_seq_query_subscribe_get_client_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern int (*snd_seq_query_subscribe_get_port_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern const snd_seq_addr_t* (*snd_seq_query_subscribe_get_root_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern snd_seq_query_subs_type_t (*snd_seq_query_subscribe_get_type_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern int (*snd_seq_query_subscribe_get_index_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern int (*snd_seq_query_subscribe_get_num_subs_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern const snd_seq_addr_t* (*snd_seq_query_subscribe_get_addr_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern int (*snd_seq_query_subscribe_get_queue_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern int (*snd_seq_query_subscribe_get_exclusive_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern int (*snd_seq_query_subscribe_get_time_update_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern int (*snd_seq_query_subscribe_get_time_real_dylibloader_wrapper_asound)(const snd_seq_query_subscribe_t*);
+extern void (*snd_seq_query_subscribe_set_client_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int);
+extern void (*snd_seq_query_subscribe_set_port_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int);
+extern void (*snd_seq_query_subscribe_set_root_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*,const snd_seq_addr_t*);
+extern void (*snd_seq_query_subscribe_set_type_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, snd_seq_query_subs_type_t);
+extern void (*snd_seq_query_subscribe_set_index_dylibloader_wrapper_asound)( snd_seq_query_subscribe_t*, int);
+extern int (*snd_seq_query_port_subscribers_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_query_subscribe_t*);
+extern size_t (*snd_seq_queue_info_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_queue_info_malloc_dylibloader_wrapper_asound)( snd_seq_queue_info_t**);
+extern void (*snd_seq_queue_info_free_dylibloader_wrapper_asound)( snd_seq_queue_info_t*);
+extern void (*snd_seq_queue_info_copy_dylibloader_wrapper_asound)( snd_seq_queue_info_t*,const snd_seq_queue_info_t*);
+extern int (*snd_seq_queue_info_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+extern const char* (*snd_seq_queue_info_get_name_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+extern int (*snd_seq_queue_info_get_owner_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+extern int (*snd_seq_queue_info_get_locked_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+extern unsigned int (*snd_seq_queue_info_get_flags_dylibloader_wrapper_asound)(const snd_seq_queue_info_t*);
+extern void (*snd_seq_queue_info_set_name_dylibloader_wrapper_asound)( snd_seq_queue_info_t*,const char*);
+extern void (*snd_seq_queue_info_set_owner_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, int);
+extern void (*snd_seq_queue_info_set_locked_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, int);
+extern void (*snd_seq_queue_info_set_flags_dylibloader_wrapper_asound)( snd_seq_queue_info_t*, unsigned int);
+extern int (*snd_seq_create_queue_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_queue_info_t*);
+extern int (*snd_seq_alloc_named_queue_dylibloader_wrapper_asound)( snd_seq_t*,const char*);
+extern int (*snd_seq_alloc_queue_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_free_queue_dylibloader_wrapper_asound)( snd_seq_t*, int);
+extern int (*snd_seq_get_queue_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_info_t*);
+extern int (*snd_seq_set_queue_info_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_info_t*);
+extern int (*snd_seq_query_named_queue_dylibloader_wrapper_asound)( snd_seq_t*,const char*);
+extern int (*snd_seq_get_queue_usage_dylibloader_wrapper_asound)( snd_seq_t*, int);
+extern int (*snd_seq_set_queue_usage_dylibloader_wrapper_asound)( snd_seq_t*, int, int);
+extern size_t (*snd_seq_queue_status_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_queue_status_malloc_dylibloader_wrapper_asound)( snd_seq_queue_status_t**);
+extern void (*snd_seq_queue_status_free_dylibloader_wrapper_asound)( snd_seq_queue_status_t*);
+extern void (*snd_seq_queue_status_copy_dylibloader_wrapper_asound)( snd_seq_queue_status_t*,const snd_seq_queue_status_t*);
+extern int (*snd_seq_queue_status_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+extern int (*snd_seq_queue_status_get_events_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+extern snd_seq_tick_time_t (*snd_seq_queue_status_get_tick_time_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+extern const snd_seq_real_time_t* (*snd_seq_queue_status_get_real_time_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+extern unsigned int (*snd_seq_queue_status_get_status_dylibloader_wrapper_asound)(const snd_seq_queue_status_t*);
+extern int (*snd_seq_get_queue_status_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_status_t*);
+extern size_t (*snd_seq_queue_tempo_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_queue_tempo_malloc_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t**);
+extern void (*snd_seq_queue_tempo_free_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*);
+extern void (*snd_seq_queue_tempo_copy_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*,const snd_seq_queue_tempo_t*);
+extern int (*snd_seq_queue_tempo_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+extern unsigned int (*snd_seq_queue_tempo_get_tempo_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+extern int (*snd_seq_queue_tempo_get_ppq_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+extern unsigned int (*snd_seq_queue_tempo_get_skew_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+extern unsigned int (*snd_seq_queue_tempo_get_skew_base_dylibloader_wrapper_asound)(const snd_seq_queue_tempo_t*);
+extern void (*snd_seq_queue_tempo_set_tempo_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int);
+extern void (*snd_seq_queue_tempo_set_ppq_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, int);
+extern void (*snd_seq_queue_tempo_set_skew_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int);
+extern void (*snd_seq_queue_tempo_set_skew_base_dylibloader_wrapper_asound)( snd_seq_queue_tempo_t*, unsigned int);
+extern int (*snd_seq_get_queue_tempo_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_tempo_t*);
+extern int (*snd_seq_set_queue_tempo_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_tempo_t*);
+extern size_t (*snd_seq_queue_timer_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_queue_timer_malloc_dylibloader_wrapper_asound)( snd_seq_queue_timer_t**);
+extern void (*snd_seq_queue_timer_free_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*);
+extern void (*snd_seq_queue_timer_copy_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*,const snd_seq_queue_timer_t*);
+extern int (*snd_seq_queue_timer_get_queue_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*);
+extern snd_seq_queue_timer_type_t (*snd_seq_queue_timer_get_type_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*);
+extern const snd_timer_id_t* (*snd_seq_queue_timer_get_id_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*);
+extern unsigned int (*snd_seq_queue_timer_get_resolution_dylibloader_wrapper_asound)(const snd_seq_queue_timer_t*);
+extern void (*snd_seq_queue_timer_set_type_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*, snd_seq_queue_timer_type_t);
+extern void (*snd_seq_queue_timer_set_id_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*,const snd_timer_id_t*);
+extern void (*snd_seq_queue_timer_set_resolution_dylibloader_wrapper_asound)( snd_seq_queue_timer_t*, unsigned int);
+extern int (*snd_seq_get_queue_timer_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_timer_t*);
+extern int (*snd_seq_set_queue_timer_dylibloader_wrapper_asound)( snd_seq_t*, int, snd_seq_queue_timer_t*);
+extern int (*snd_seq_free_event_dylibloader_wrapper_asound)( snd_seq_event_t*);
+extern ssize_t (*snd_seq_event_length_dylibloader_wrapper_asound)( snd_seq_event_t*);
+extern int (*snd_seq_event_output_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*);
+extern int (*snd_seq_event_output_buffer_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*);
+extern int (*snd_seq_event_output_direct_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t*);
+extern int (*snd_seq_event_input_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t**);
+extern int (*snd_seq_event_input_pending_dylibloader_wrapper_asound)( snd_seq_t*, int);
+extern int (*snd_seq_drain_output_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_event_output_pending_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_extract_output_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_event_t**);
+extern int (*snd_seq_drop_output_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_drop_output_buffer_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_drop_input_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_drop_input_buffer_dylibloader_wrapper_asound)( snd_seq_t*);
+extern size_t (*snd_seq_remove_events_sizeof_dylibloader_wrapper_asound)( void);
+extern int (*snd_seq_remove_events_malloc_dylibloader_wrapper_asound)( snd_seq_remove_events_t**);
+extern void (*snd_seq_remove_events_free_dylibloader_wrapper_asound)( snd_seq_remove_events_t*);
+extern void (*snd_seq_remove_events_copy_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_remove_events_t*);
+extern unsigned int (*snd_seq_remove_events_get_condition_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+extern int (*snd_seq_remove_events_get_queue_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+extern const snd_seq_timestamp_t* (*snd_seq_remove_events_get_time_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+extern const snd_seq_addr_t* (*snd_seq_remove_events_get_dest_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+extern int (*snd_seq_remove_events_get_channel_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+extern int (*snd_seq_remove_events_get_event_type_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+extern int (*snd_seq_remove_events_get_tag_dylibloader_wrapper_asound)(const snd_seq_remove_events_t*);
+extern void (*snd_seq_remove_events_set_condition_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, unsigned int);
+extern void (*snd_seq_remove_events_set_queue_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int);
+extern void (*snd_seq_remove_events_set_time_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_timestamp_t*);
+extern void (*snd_seq_remove_events_set_dest_dylibloader_wrapper_asound)( snd_seq_remove_events_t*,const snd_seq_addr_t*);
+extern void (*snd_seq_remove_events_set_channel_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int);
+extern void (*snd_seq_remove_events_set_event_type_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int);
+extern void (*snd_seq_remove_events_set_tag_dylibloader_wrapper_asound)( snd_seq_remove_events_t*, int);
+extern int (*snd_seq_remove_events_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_remove_events_t*);
+extern void (*snd_seq_set_bit_dylibloader_wrapper_asound)( int, void*);
+extern void (*snd_seq_unset_bit_dylibloader_wrapper_asound)( int, void*);
+extern int (*snd_seq_change_bit_dylibloader_wrapper_asound)( int, void*);
+extern int (*snd_seq_get_bit_dylibloader_wrapper_asound)( int, void*);
+extern int (*snd_seq_control_queue_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int, snd_seq_event_t*);
+extern int (*snd_seq_create_simple_port_dylibloader_wrapper_asound)( snd_seq_t*,const char*, unsigned int, unsigned int);
+extern int (*snd_seq_delete_simple_port_dylibloader_wrapper_asound)( snd_seq_t*, int);
+extern int (*snd_seq_connect_from_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int);
+extern int (*snd_seq_connect_to_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int);
+extern int (*snd_seq_disconnect_from_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int);
+extern int (*snd_seq_disconnect_to_dylibloader_wrapper_asound)( snd_seq_t*, int, int, int);
+extern int (*snd_seq_set_client_name_dylibloader_wrapper_asound)( snd_seq_t*,const char*);
+extern int (*snd_seq_set_client_event_filter_dylibloader_wrapper_asound)( snd_seq_t*, int);
+extern int (*snd_seq_set_client_pool_output_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+extern int (*snd_seq_set_client_pool_output_room_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+extern int (*snd_seq_set_client_pool_input_dylibloader_wrapper_asound)( snd_seq_t*, size_t);
+extern int (*snd_seq_sync_output_queue_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_parse_address_dylibloader_wrapper_asound)( snd_seq_t*, snd_seq_addr_t*,const char*);
+extern int (*snd_seq_reset_pool_output_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_seq_reset_pool_input_dylibloader_wrapper_asound)( snd_seq_t*);
+extern int (*snd_midi_event_new_dylibloader_wrapper_asound)( size_t, snd_midi_event_t**);
+extern int (*snd_midi_event_resize_buffer_dylibloader_wrapper_asound)( snd_midi_event_t*, size_t);
+extern void (*snd_midi_event_free_dylibloader_wrapper_asound)( snd_midi_event_t*);
+extern void (*snd_midi_event_init_dylibloader_wrapper_asound)( snd_midi_event_t*);
+extern void (*snd_midi_event_reset_encode_dylibloader_wrapper_asound)( snd_midi_event_t*);
+extern void (*snd_midi_event_reset_decode_dylibloader_wrapper_asound)( snd_midi_event_t*);
+extern void (*snd_midi_event_no_status_dylibloader_wrapper_asound)( snd_midi_event_t*, int);
+extern long (*snd_midi_event_encode_dylibloader_wrapper_asound)( snd_midi_event_t*,const unsigned char*, long, snd_seq_event_t*);
+extern int (*snd_midi_event_encode_byte_dylibloader_wrapper_asound)( snd_midi_event_t*, int, snd_seq_event_t*);
+extern long (*snd_midi_event_decode_dylibloader_wrapper_asound)( snd_midi_event_t*, unsigned char*, long,const snd_seq_event_t*);
+int initialize_asound(int verbose);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 7aa3787ced..61475c74e7 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,8 +37,14 @@
#include <errno.h>
+#ifdef PULSEAUDIO_ENABLED
+extern "C" {
+extern int initialize_pulse(int verbose);
+}
+#endif
+
Error AudioDriverALSA::init_device() {
- mix_rate = GLOBAL_GET("audio/mix_rate");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
@@ -104,7 +110,7 @@ Error AudioDriverALSA::init_device() {
// In ALSA the period size seems to be the one that will determine the actual latency
// Ref: https://www.alsa-project.org/main/index.php/FramesPeriods
unsigned int periods = 2;
- int latency = GLOBAL_GET("audio/output_latency");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
buffer_size = buffer_frames * periods;
period_size = buffer_frames;
@@ -147,13 +153,28 @@ Error AudioDriverALSA::init_device() {
}
Error AudioDriverALSA::init() {
+#ifdef DEBUG_ENABLED
+ int dylibloader_verbose = 1;
+#else
+ int dylibloader_verbose = 0;
+#endif
+#ifdef PULSEAUDIO_ENABLED
+ // On pulse enabled systems Alsa will silently use pulse.
+ // It doesn't matter if this fails as that likely means there is no pulse
+ initialize_pulse(dylibloader_verbose);
+#endif
+
+ if (initialize_asound(dylibloader_verbose)) {
+ return ERR_CANT_OPEN;
+ }
+
active = false;
thread_exited = false;
exit_thread = false;
Error err = init_device();
if (err == OK) {
- thread = Thread::create(AudioDriverALSA::thread_func, this);
+ thread.start(AudioDriverALSA::thread_func, this);
}
return err;
@@ -291,16 +312,10 @@ void AudioDriverALSA::set_device(String device) {
}
void AudioDriverALSA::lock() {
- if (!thread) {
- return;
- }
mutex.lock();
}
void AudioDriverALSA::unlock() {
- if (!thread) {
- return;
- }
mutex.unlock();
}
@@ -312,13 +327,8 @@ void AudioDriverALSA::finish_device() {
}
void AudioDriverALSA::finish() {
- if (thread) {
- exit_thread = true;
- Thread::wait_to_finish(thread);
-
- memdelete(thread);
- thread = nullptr;
- }
+ exit_thread = true;
+ thread.wait_to_finish();
finish_device();
}
diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h
index bb4b1c5476..ca97e76bc2 100644
--- a/drivers/alsa/audio_driver_alsa.h
+++ b/drivers/alsa/audio_driver_alsa.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,10 +37,10 @@
#include "core/os/thread.h"
#include "servers/audio_server.h"
-#include <alsa/asoundlib.h>
+#include "asound-so_wrap.h"
class AudioDriverALSA : public AudioDriver {
- Thread *thread = nullptr;
+ Thread thread;
Mutex mutex;
snd_pcm_t *pcm_handle = nullptr;
diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp
index 07a4360cd2..245ea07730 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.cpp
+++ b/drivers/alsamidi/midi_driver_alsamidi.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -150,19 +150,14 @@ Error MIDIDriverALSAMidi::open() {
snd_device_name_free_hint(hints);
exit_thread = false;
- thread = Thread::create(MIDIDriverALSAMidi::thread_func, this);
+ thread.start(MIDIDriverALSAMidi::thread_func, this);
return OK;
}
void MIDIDriverALSAMidi::close() {
- if (thread) {
- exit_thread = true;
- Thread::wait_to_finish(thread);
-
- memdelete(thread);
- thread = nullptr;
- }
+ exit_thread = true;
+ thread.wait_to_finish();
for (int i = 0; i < connected_inputs.size(); i++) {
snd_rawmidi_t *midi_in = connected_inputs[i];
@@ -198,8 +193,6 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() {
}
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
- thread = nullptr;
-
exit_thread = false;
}
diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h
index fef87459c7..c327712ee7 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.h
+++ b/drivers/alsamidi/midi_driver_alsamidi.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,11 +38,11 @@
#include "core/os/thread.h"
#include "core/templates/vector.h"
-#include <alsa/asoundlib.h>
+#include "../alsa/asound-so_wrap.h"
#include <stdio.h>
class MIDIDriverALSAMidi : public MIDIDriver {
- Thread *thread;
+ Thread thread;
Mutex mutex;
Vector<snd_rawmidi_t *> connected_inputs;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 60c491f5f8..baa60f5526 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -116,7 +116,7 @@ Error AudioDriverCoreAudio::init() {
break;
}
- mix_rate = GLOBAL_GET("audio/mix_rate");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
zeromem(&strdesc, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
@@ -131,7 +131,7 @@ Error AudioDriverCoreAudio::init() {
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
- int latency = GLOBAL_GET("audio/output_latency");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
@@ -157,7 +157,7 @@ Error AudioDriverCoreAudio::init() {
result = AudioUnitInitialize(audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
- if (GLOBAL_GET("audio/enable_audio_input")) {
+ if (GLOBAL_GET("audio/driver/enable_input")) {
return capture_init();
}
return OK;
@@ -403,7 +403,7 @@ Error AudioDriverCoreAudio::capture_init() {
break;
}
- mix_rate = GLOBAL_GET("audio/mix_rate");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
zeromem(&strdesc, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index 6b7a35588f..b31835760e 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/coremidi/midi_driver_coremidi.cpp b/drivers/coremidi/midi_driver_coremidi.cpp
index b9e7853735..87764d9b10 100644
--- a/drivers/coremidi/midi_driver_coremidi.cpp
+++ b/drivers/coremidi/midi_driver_coremidi.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/coremidi/midi_driver_coremidi.h b/drivers/coremidi/midi_driver_coremidi.h
index 02167aa891..41a7c760ac 100644
--- a/drivers/coremidi/midi_driver_coremidi.h
+++ b/drivers/coremidi/midi_driver_coremidi.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index f674c36500..9d6be1a802 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,14 +40,37 @@
class RasterizerSceneDummy : public RendererSceneRender {
public:
+ GeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; }
+ void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override {}
+ void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override {}
+ void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override {}
+ void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override {}
+ void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {}
+ void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override {}
+ void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override {}
+ void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override {}
+ void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override {}
+ void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {}
+ void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override {}
+ void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override {}
+ void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override {}
+
+ uint32_t geometry_instance_get_pair_mask() override { return 0; }
+ void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override {}
+ void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {}
+ void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override {}
+ void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) override {}
+
+ void geometry_instance_free(GeometryInstance *p_geometry_instance) override {}
+
/* SHADOW ATLAS API */
RID shadow_atlas_create() override { return RID(); }
- void shadow_atlas_set_size(RID p_atlas, int p_size) override {}
+ void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) override {}
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override {}
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override { return false; }
- void directional_shadow_atlas_set_size(int p_size) override {}
+ void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) override {}
int get_directional_light_shadow_size(RID p_light_intance) override { return 0; }
void set_directional_shadow_count(int p_count) override {}
@@ -57,11 +80,11 @@ public:
int sdfgi_get_pending_region_count(RID p_render_buffers) const override { return 0; }
AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { return AABB(); }
uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { return 0; }
- void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) override {}
/* SKY API */
- RID sky_create() override { return RID(); }
+ RID sky_allocate() override { return RID(); }
+ void sky_initialize(RID p_rid) override {}
void sky_set_radiance_size(RID p_sky, int p_radiance_size) override {}
void sky_set_mode(RID p_sky, RS::SkyMode p_samples) override {}
void sky_set_material(RID p_sky, RID p_material) override {}
@@ -69,8 +92,8 @@ public:
/* ENVIRONMENT API */
- RID environment_create() override { return RID(); }
-
+ RID environment_allocate() override { return RID(); }
+ void environment_initialize(RID p_rid) override {}
void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override {}
void environment_set_sky(RID p_env, RID p_sky) override {}
void environment_set_sky_custom_fov(RID p_env, float p_scale) override {}
@@ -89,21 +112,20 @@ public:
void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override {}
void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {}
- void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {}
+ void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {}
void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override {}
void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override {}
+ void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override {}
void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override {}
void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {}
void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {}
- void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) override {}
+ void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) override {}
void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {}
void environment_set_volumetric_fog_filter_active(bool p_enable) override {}
- void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) override {}
- void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) override {}
Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); }
@@ -111,8 +133,8 @@ public:
RS::EnvironmentBG environment_get_background(RID p_env) const override { return RS::ENV_BG_KEEP; }
int environment_get_canvas_max_layer(RID p_env) const override { return 0; }
- RID camera_effects_create() override { return RID(); }
-
+ RID camera_effects_allocate() override { return RID(); }
+ void camera_effects_initialize(RID p_rid) override {}
void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override {}
void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override {}
@@ -129,6 +151,7 @@ public:
void light_instance_mark_visible(RID p_light_instance) override {}
RID reflection_atlas_create() override { return RID(); }
+ int reflection_atlas_get_size(RID p_ref_atlas) const override { return 0; }
void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override {}
RID reflection_probe_instance_create(RID p_probe) override { return RID(); }
@@ -142,19 +165,19 @@ public:
RID decal_instance_create(RID p_decal) override { return RID(); }
void decal_instance_set_transform(RID p_decal, const Transform &p_transform) override {}
+ RID lightmap_instance_create(RID p_lightmap) override { return RID(); }
+ void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) override {}
+
RID gi_probe_instance_create(RID p_gi_probe) override { return RID(); }
void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) override {}
bool gi_probe_needs_update(RID p_probe) const override { return false; }
- void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) override {}
+ void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override {}
void gi_probe_set_quality(RS::GIProbeQuality) override {}
- void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) override {}
- void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) override {}
- void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) override {}
- void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) override {}
- void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) override {}
- void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, InstanceBase **p_cull_result, int p_cull_count) override {}
+ void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) override {}
+ void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {}
+ void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {}
void set_scene_pass(uint64_t p_pass) override {}
void set_time(double p_time, double p_step) override {}
@@ -162,6 +185,7 @@ public:
RID render_buffers_create() override { return RID(); }
void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) override {}
+ void gi_set_use_half_resolution(bool p_enable) override {}
void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {}
bool screen_space_roughness_limiter_is_active() const override { return false; }
@@ -183,61 +207,48 @@ public:
class RasterizerStorageDummy : public RendererStorage {
public:
+ bool can_create_resources_async() const override { return false; }
+
/* TEXTURE API */
struct DummyTexture {
- int width = 0;
- int height = 0;
- uint32_t flags = 0;
- Image::Format format = Image::Format::FORMAT_MAX;
Ref<Image> image;
- String path;
- };
-
- struct DummySurface {
- uint32_t format = 0;
- RS::PrimitiveType primitive = RS::PrimitiveType::PRIMITIVE_MAX;
- Vector<uint8_t> array;
- int vertex_count = 0;
- Vector<uint8_t> index_array;
- int index_count = 0;
- AABB aabb;
- Vector<Vector<uint8_t>> blend_shapes;
- Vector<AABB> bone_aabbs;
- };
-
- struct DummyMesh {
- Vector<DummySurface> surfaces;
- int blend_shape_count = 0;
- RS::BlendShapeMode blend_shape_mode = RS::BlendShapeMode::BLEND_SHAPE_MODE_NORMALIZED;
};
-
mutable RID_PtrOwner<DummyTexture> texture_owner;
- mutable RID_PtrOwner<DummyMesh> mesh_owner;
- RID texture_2d_create(const Ref<Image> &p_image) override { return RID(); }
- RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override { return RID(); }
- RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override { return RID(); }
- RID texture_proxy_create(RID p_base) override { return RID(); }
+ RID texture_allocate() override {
+ DummyTexture *texture = memnew(DummyTexture);
+ ERR_FAIL_COND_V(!texture, RID());
+ return texture_owner.make_rid(texture);
+ }
+ void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override {
+ DummyTexture *t = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND(!t);
+ t->image = p_image->duplicate();
+ }
+ void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override {}
void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {}
void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {}
+ void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override {}
void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override {}
+ void texture_proxy_initialize(RID p_texture, RID p_base) override {}
void texture_proxy_update(RID p_proxy, RID p_base) override {}
- RID texture_2d_placeholder_create() override { return RID(); }
- RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) override { return RID(); }
- RID texture_3d_placeholder_create() override { return RID(); }
+ void texture_2d_placeholder_initialize(RID p_texture) override {}
+ void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) override {}
+ void texture_3d_placeholder_initialize(RID p_texture) override {}
+
+ Ref<Image> texture_2d_get(RID p_texture) const override {
+ DummyTexture *t = texture_owner.getornull(p_texture);
+ ERR_FAIL_COND_V(!t, Ref<Image>());
+ return t->image;
+ }
- Ref<Image> texture_2d_get(RID p_texture) const override { return Ref<Image>(); }
Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const override { return Ref<Image>(); }
Vector<Ref<Image>> texture_3d_get(RID p_texture) const override { return Vector<Ref<Image>>(); }
void texture_replace(RID p_texture, RID p_by_texture) override {}
void texture_set_size_override(RID p_texture, int p_width, int p_height) override {}
-// FIXME: Disabled during Vulkan refactoring, should be ported.
-#if 0
- void texture_bind(RID p_texture, uint32_t p_texture_no) = 0;
-#endif
void texture_set_path(RID p_texture, const String &p_path) override {}
String texture_get_path(RID p_texture) const override { return String(); }
@@ -255,113 +266,18 @@ public:
/* CANVAS TEXTURE API */
- RID canvas_texture_create() override { return RID(); }
+ RID canvas_texture_allocate() override { return RID(); }
+ 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_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override {}
void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override {}
-#if 0
- RID texture_create() override {
- DummyTexture *texture = memnew(DummyTexture);
- ERR_FAIL_COND_V(!texture, RID());
- return texture_owner.make_rid(texture);
- }
-
- void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, RenderingServer::TextureType p_type = RS::TEXTURE_TYPE_2D, uint32_t p_flags = RS::TEXTURE_FLAGS_DEFAULT) override {
- DummyTexture *t = texture_owner.getornull(p_texture);
- ERR_FAIL_COND(!t);
- t->width = p_width;
- t->height = p_height;
- t->flags = p_flags;
- t->format = p_format;
- t->image = Ref<Image>(memnew(Image));
- t->image->create(p_width, p_height, false, p_format);
- }
- void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_level) override {
- DummyTexture *t = texture_owner.getornull(p_texture);
- ERR_FAIL_COND(!t);
- t->width = p_image->get_width();
- t->height = p_image->get_height();
- t->format = p_image->get_format();
- t->image->create(t->width, t->height, false, t->format, p_image->get_data());
- }
-
- void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_level) override {
- DummyTexture *t = texture_owner.getornull(p_texture);
-
- ERR_FAIL_COND(!t);
- ERR_FAIL_COND_MSG(p_image.is_null(), "It's not a reference to a valid Image object.");
- ERR_FAIL_COND(t->format != p_image->get_format());
- ERR_FAIL_COND(src_w <= 0 || src_h <= 0);
- ERR_FAIL_COND(src_x < 0 || src_y < 0 || src_x + src_w > p_image->get_width() || src_y + src_h > p_image->get_height());
- ERR_FAIL_COND(dst_x < 0 || dst_y < 0 || dst_x + src_w > t->width || dst_y + src_h > t->height);
-
- t->image->blit_rect(p_image, Rect2(src_x, src_y, src_w, src_h), Vector2(dst_x, dst_y));
- }
-
- Ref<Image> texture_get_data(RID p_texture, int p_level) const override {
- DummyTexture *t = texture_owner.getornull(p_texture);
- ERR_FAIL_COND_V(!t, Ref<Image>());
- return t->image;
- }
- void texture_set_flags(RID p_texture, uint32_t p_flags) override {
- DummyTexture *t = texture_owner.getornull(p_texture);
- ERR_FAIL_COND(!t);
- t->flags = p_flags;
- }
- uint32_t texture_get_flags(RID p_texture) const override {
- DummyTexture *t = texture_owner.getornull(p_texture);
- ERR_FAIL_COND_V(!t, 0);
- return t->flags;
- }
- Image::Format texture_get_format(RID p_texture) const override {
- DummyTexture *t = texture_owner.getornull(p_texture);
- ERR_FAIL_COND_V(!t, Image::FORMAT_RGB8);
- return t->format;
- }
-
- RenderingServer::TextureType texture_get_type(RID p_texture) const override { return RS::TEXTURE_TYPE_2D; }
- uint32_t texture_get_texid(RID p_texture) const override { return 0; }
- uint32_t texture_get_width(RID p_texture) const override { return 0; }
- uint32_t texture_get_height(RID p_texture) const override { return 0; }
- uint32_t texture_get_depth(RID p_texture) const override { return 0; }
- void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth_3d) override {}
- void texture_bind(RID p_texture, uint32_t p_texture_no) override {}
-
- void texture_set_path(RID p_texture, const String &p_path) override {
- DummyTexture *t = texture_owner.getornull(p_texture);
- ERR_FAIL_COND(!t);
- t->path = p_path;
- }
- String texture_get_path(RID p_texture) const override {
- DummyTexture *t = texture_owner.getornull(p_texture);
- ERR_FAIL_COND_V(!t, String());
- return t->path;
- }
-
- void texture_set_shrink_all_x2_on_set_data(bool p_enable) override {}
-
- void texture_debug_usage(List<RS::TextureInfo> *r_info) override {}
-
- RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const override { return RID(); }
-
- void texture_set_detect_3d_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {}
- void texture_set_detect_srgb_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {}
- void texture_set_detect_normal_callback(RID p_texture, RenderingServer::TextureDetectCallback p_callback, void *p_userdata) override {}
-
- void textures_keep_original(bool p_enable) override {}
-
- void texture_set_proxy(RID p_proxy, RID p_base) override {}
- Size2 texture_size_with_proxy(RID p_texture) const override { return Size2(); }
- void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override {}
-#endif
-
/* SHADER API */
- RID shader_create() override { return RID(); }
-
+ RID shader_allocate() override { return RID(); }
+ void shader_initialize(RID p_rid) override {}
void shader_set_code(RID p_shader, const String &p_code) override {}
String shader_get_code(RID p_shader) const override { return ""; }
void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {}
@@ -370,10 +286,12 @@ public:
RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const override { return RID(); }
Variant shader_get_param_default(RID p_material, const StringName &p_param) const override { return Variant(); }
- /* COMMON MATERIAL API */
+ RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
- RID material_create() override { return RID(); }
+ /* COMMON MATERIAL API */
+ RID material_allocate() override { return RID(); }
+ void material_initialize(RID p_rid) override {}
void material_set_render_priority(RID p_material, int priority) override {}
void material_set_shader(RID p_shader_material, RID p_shader) override {}
@@ -385,153 +303,49 @@ public:
bool material_is_animated(RID p_material) override { return false; }
bool material_casts_shadows(RID p_material) override { return false; }
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
- void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) override {}
+ void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {}
/* MESH API */
- RID mesh_create() override {
- DummyMesh *mesh = memnew(DummyMesh);
- ERR_FAIL_COND_V(!mesh, RID());
- mesh->blend_shape_count = 0;
- mesh->blend_shape_mode = RS::BLEND_SHAPE_MODE_NORMALIZED;
- return mesh_owner.make_rid(mesh);
- }
+ RID mesh_allocate() override { return RID(); }
+ void mesh_initialize(RID p_rid) override {}
+ void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override {}
+ bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override { return false; }
+ RID mesh_instance_create(RID p_base) override { return RID(); }
+ void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override {}
+ void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override {}
+ void mesh_instance_check_for_update(RID p_mesh_instance) override {}
+ void update_mesh_instances() override {}
+ void reflection_probe_set_lod_threshold(RID p_probe, float p_ratio) override {}
+ float reflection_probe_get_lod_threshold(RID p_probe) const override { return 0.0; }
void mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) override {}
-#if 0
- void mesh_add_surface(RID p_mesh, uint32_t p_format, RS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes = Vector<Vector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND(!m);
-
- m->surfaces.push_back(DummySurface());
- DummySurface *s = &m->surfaces.write[m->surfaces.size() - 1];
- s->format = p_format;
- s->primitive = p_primitive;
- s->array = p_array;
- s->vertex_count = p_vertex_count;
- s->index_array = p_index_array;
- s->index_count = p_index_count;
- s->aabb = p_aabb;
- s->blend_shapes = p_blend_shapes;
- s->bone_aabbs = p_bone_aabbs;
- }
+ int mesh_get_blend_shape_count(RID p_mesh) const override { return 0; }
- void mesh_set_blend_shape_count(RID p_mesh, int p_amount) override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND(!m);
- m->blend_shape_count = p_amount;
- }
-#endif
-
- int mesh_get_blend_shape_count(RID p_mesh) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, 0);
- return m->blend_shape_count;
- }
-
- void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND(!m);
- m->blend_shape_mode = p_mode;
- }
- RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, RS::BLEND_SHAPE_MODE_NORMALIZED);
- return m->blend_shape_mode;
- }
+ void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) override {}
+ RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const override { return RS::BLEND_SHAPE_MODE_NORMALIZED; }
void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) override {}
void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) override {}
RID mesh_surface_get_material(RID p_mesh, int p_surface) const override { return RID(); }
-#if 0
- int mesh_surface_get_array_len(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, 0);
-
- return m->surfaces[p_surface].vertex_count;
- }
- int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, 0);
-
- return m->surfaces[p_surface].index_count;
- }
-
- Vector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, Vector<uint8_t>());
-
- return m->surfaces[p_surface].array;
- }
- Vector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, Vector<uint8_t>());
-
- return m->surfaces[p_surface].index_array;
- }
-
- uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, 0);
-
- return m->surfaces[p_surface].format;
- }
- RS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, RS::PRIMITIVE_POINTS);
-
- return m->surfaces[p_surface].primitive;
- }
-
- AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, AABB());
-
- return m->surfaces[p_surface].aabb;
- }
- Vector<Vector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, Vector<Vector<uint8_t> >());
-
- return m->surfaces[p_surface].blend_shapes;
- }
- Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, Vector<AABB>());
-
- return m->surfaces[p_surface].bone_aabbs;
- }
-
- void mesh_remove_surface(RID p_mesh, int p_index) override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND(!m);
- ERR_FAIL_COND(p_index >= m->surfaces.size());
-
- m->surfaces.remove(p_index);
- }
-#endif
-
RS::SurfaceData mesh_get_surface(RID p_mesh, int p_surface) const override { return RS::SurfaceData(); }
- int mesh_get_surface_count(RID p_mesh) const override {
- DummyMesh *m = mesh_owner.getornull(p_mesh);
- ERR_FAIL_COND_V(!m, 0);
- return m->surfaces.size();
- }
+ int mesh_get_surface_count(RID p_mesh) const override { return 0; }
void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override {}
AABB mesh_get_custom_aabb(RID p_mesh) const override { return AABB(); }
AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override { return AABB(); }
+ void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override {}
void mesh_clear(RID p_mesh) override {}
/* MULTIMESH API */
- RID multimesh_create() override { return RID(); }
-
- void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override {}
+ RID multimesh_allocate() override { return RID(); }
+ 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 {}
int multimesh_get_instance_count(RID p_multimesh) const override { return 0; }
void multimesh_set_mesh(RID p_multimesh, RID p_mesh) override {}
@@ -555,7 +369,8 @@ public:
/* IMMEDIATE API */
- RID immediate_create() override { return RID(); }
+ RID immediate_allocate() override { return RID(); }
+ void immediate_initialize(RID p_rid) override {}
void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) override {}
void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) override {}
void immediate_normal(RID p_immediate, const Vector3 &p_normal) override {}
@@ -571,8 +386,9 @@ public:
/* SKELETON API */
- RID skeleton_create() override { return RID(); }
- void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override {}
+ RID skeleton_allocate() override { return RID(); }
+ void skeleton_initialize(RID p_rid) override {}
+ void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) override {}
void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) override {}
int skeleton_get_bone_count(RID p_skeleton) const override { return 0; }
void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) override {}
@@ -582,7 +398,14 @@ public:
/* Light API */
- RID light_create(RS::LightType p_type) override { return RID(); }
+ RID directional_light_allocate() override { return RID(); }
+ void directional_light_initialize(RID p_rid) override {}
+ RID omni_light_allocate() override { return RID(); }
+ void omni_light_initialize(RID p_rid) override {}
+ RID spot_light_allocate() override { return RID(); }
+ void spot_light_initialize(RID p_rid) override {}
+ RID reflection_probe_allocate() override { return RID(); }
+ void reflection_probe_initialize(RID p_rid) override {}
void light_set_color(RID p_light, const Color &p_color) override {}
void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {}
@@ -620,8 +443,6 @@ public:
/* PROBE API */
- RID reflection_probe_create() override { return RID(); }
-
void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) override {}
void reflection_probe_set_intensity(RID p_probe, float p_intensity) override {}
void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) override {}
@@ -644,12 +465,13 @@ public:
float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; }
bool reflection_probe_renders_shadows(RID p_probe) const override { return false; }
- void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) override {}
- void skeleton_update_dependency(RID p_base, InstanceBaseDependency *p_instance) override {}
+ void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
+ void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
/* DECAL API */
- RID decal_create() override { return RID(); }
+ RID decal_allocate() override { return RID(); }
+ void decal_initialize(RID p_rid) override {}
void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
void decal_set_emission_energy(RID p_decal, float p_energy) override {}
@@ -664,9 +486,9 @@ public:
/* GI PROBE API */
- RID gi_probe_create() override { return RID(); }
-
- void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {}
+ RID gi_probe_allocate() override { return RID(); }
+ void gi_probe_initialize(RID p_rid) override {}
+ void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {}
AABB gi_probe_get_bounds(RID p_gi_probe) const override { return AABB(); }
Vector3i gi_probe_get_octree_size(RID p_gi_probe) const override { return Vector3i(); }
@@ -710,72 +532,8 @@ public:
uint32_t gi_probe_get_version(RID p_gi_probe) override { return 0; }
/* LIGHTMAP CAPTURE */
-#if 0
- struct Instantiable {
- SelfList<RendererSceneRender::InstanceBase>::List instance_list;
-
- _FORCE_INLINE_ void instance_change_notify(bool p_aabb = true, bool p_materials = true) override {
- SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first();
- while (instances) override {
- //instances->self()->base_changed(p_aabb, p_materials);
- instances = instances->next();
- }
- }
-
- _FORCE_INLINE_ void instance_remove_deps() override {
- SelfList<RendererSceneRender::InstanceBase> *instances = instance_list.first();
- while (instances) override {
- SelfList<RendererSceneRender::InstanceBase> *next = instances->next();
- //instances->self()->base_removed();
- instances = next;
- }
- }
-
- Instantiable() override {}
- ~Instantiable() override {
- }
- };
-
- struct LightmapCapture : public Instantiable {
- Vector<LightmapCaptureOctree> octree;
- AABB bounds;
- Transform cell_xform;
- int cell_subdiv;
- float energy;
- LightmapCapture() override {
- energy = 1.0;
- cell_subdiv = 1;
- }
- };
-
- mutable RID_PtrOwner<LightmapCapture> lightmap_capture_data_owner;
- void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) override {}
- AABB lightmap_capture_get_bounds(RID p_capture) const override { return AABB(); }
- void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) override {}
- RID lightmap_capture_create() override {
- LightmapCapture *capture = memnew(LightmapCapture);
- return lightmap_capture_data_owner.make_rid(capture);
- }
- Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const override {
- const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
- ERR_FAIL_COND_V(!capture, Vector<uint8_t>());
- return Vector<uint8_t>();
- }
- void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) override {}
- Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const override { return Transform(); }
- void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) override {}
- int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const override { return 0; }
- void lightmap_capture_set_energy(RID p_capture, float p_energy) override {}
- float lightmap_capture_get_energy(RID p_capture) const override { return 0.0; }
- const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const override {
- const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
- ERR_FAIL_COND_V(!capture, nullptr);
- return &capture->octree;
- }
-#endif
-
- RID lightmap_create() override { return RID(); }
-
+ RID lightmap_allocate() override { return RID(); }
+ void lightmap_initialize(RID p_rid) override {}
void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override {}
void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override {}
void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) override {}
@@ -792,8 +550,8 @@ public:
/* PARTICLES */
- RID particles_create() override { return RID(); }
-
+ RID particles_allocate() override { return RID(); }
+ void particles_initialize(RID p_rid) override {}
void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) override {}
void particles_set_emitting(RID p_particles, bool p_emitting) override {}
void particles_set_amount(RID p_particles, int p_amount) override {}
@@ -828,14 +586,15 @@ public:
int particles_get_draw_passes(RID p_particles) const override { return 0; }
RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const override { return RID(); }
- void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) override {}
- void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) override {}
+ void particles_add_collision(RID p_particles, RID p_instance) override {}
+ void particles_remove_collision(RID p_particles, RID p_instance) override {}
void update_particles() override {}
/* PARTICLES COLLISION */
- RID particles_collision_create() override { return RID(); }
+ RID particles_collision_allocate() override { return RID(); }
+ void particles_collision_initialize(RID p_rid) override {}
void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) override {}
void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) override {}
void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) override {}
@@ -850,6 +609,10 @@ public:
bool particles_collision_is_heightfield(RID p_particles_collision) const override { return false; }
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const override { return RID(); }
+ RID particles_collision_instance_create(RID p_collision) override { return RID(); };
+ void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) override{};
+ void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override{};
+
/* GLOBAL VARIABLES */
void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override {}
@@ -890,14 +653,7 @@ public:
void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {}
Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); }
- RS::InstanceType get_base_type(RID p_rid) const override {
- if (mesh_owner.owns(p_rid)) {
- return RS::INSTANCE_MESH;
- }
-
- return RS::INSTANCE_NONE;
- }
-
+ RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
bool free(RID p_rid) override {
if (texture_owner.owns(p_rid)) {
// delete the texture
@@ -905,13 +661,6 @@ public:
texture_owner.free(p_rid);
memdelete(texture);
}
-
- if (mesh_owner.owns(p_rid)) {
- // delete the mesh
- DummyMesh *mesh = mesh_owner.getornull(p_rid);
- mesh_owner.free(p_rid);
- memdelete(mesh);
- }
return true;
}
@@ -925,7 +674,7 @@ public:
void render_info_end_capture() override {}
int get_captured_render_info(RS::RenderInfo p_info) override { return 0; }
- int get_render_info(RS::RenderInfo p_info) override { return 0; }
+ uint64_t get_render_info(RS::RenderInfo p_info) override { return 0; }
String get_video_adapter_name() const override { return String(); }
String get_video_adapter_vendor() const override { return String(); }
diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp
index 6158a2ac54..f148e42845 100644
--- a/drivers/dummy/texture_loader_dummy.cpp
+++ b/drivers/dummy/texture_loader_dummy.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,7 +35,7 @@
#include <string.h>
-RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
unsigned int width = 8;
unsigned int height = 8;
diff --git a/drivers/dummy/texture_loader_dummy.h b/drivers/dummy/texture_loader_dummy.h
index ef9f3b13b6..00e6b9cc53 100644
--- a/drivers/dummy/texture_loader_dummy.h
+++ b/drivers/dummy/texture_loader_dummy.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class ResourceFormatDummyTexture : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index cd0c68e947..854c6706e6 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h
index 0154be0398..b4a58616f6 100644
--- a/drivers/png/image_loader_png.h
+++ b/drivers/png/image_loader_png.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/png/png_driver_common.cpp b/drivers/png/png_driver_common.cpp
index aed3fc9414..9e848a2253 100644
--- a/drivers/png/png_driver_common.cpp
+++ b/drivers/png/png_driver_common.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/png/png_driver_common.h b/drivers/png/png_driver_common.h
index e47996193f..003b587913 100644
--- a/drivers/png/png_driver_common.h
+++ b/drivers/png/png_driver_common.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index a2d0d5881a..f47fc403cc 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/png/resource_saver_png.h b/drivers/png/resource_saver_png.h
index 1d4dcfb57f..c924438224 100644
--- a/drivers/png/resource_saver_png.h
+++ b/drivers/png/resource_saver_png.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/pulseaudio/SCsub b/drivers/pulseaudio/SCsub
index 91e1140b75..467d1448dc 100644
--- a/drivers/pulseaudio/SCsub
+++ b/drivers/pulseaudio/SCsub
@@ -2,4 +2,7 @@
Import("env")
+if "pulseaudio" in env and env["pulseaudio"]:
+ env.add_source_files(env.drivers_sources, "pulse-so_wrap.c")
+
env.add_source_files(env.drivers_sources, "*.cpp")
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index 5acaa3ac99..5e87bc019b 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -179,7 +179,7 @@ Error AudioDriverPulseAudio::init_device() {
break;
}
- int latency = GLOBAL_GET("audio/output_latency");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
pa_buffer_size = buffer_frames * pa_map.channels;
@@ -233,11 +233,20 @@ Error AudioDriverPulseAudio::init_device() {
}
Error AudioDriverPulseAudio::init() {
+#ifdef DEBUG_ENABLED
+ int dylibloader_verbose = 1;
+#else
+ int dylibloader_verbose = 0;
+#endif
+ if (initialize_pulse(dylibloader_verbose)) {
+ return ERR_CANT_OPEN;
+ }
+
active = false;
thread_exited = false;
exit_thread = false;
- mix_rate = GLOBAL_GET("audio/mix_rate");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
pa_ml = pa_mainloop_new();
ERR_FAIL_COND_V(pa_ml == nullptr, ERR_CANT_OPEN);
@@ -287,7 +296,7 @@ Error AudioDriverPulseAudio::init() {
Error err = init_device();
if (err == OK) {
- thread = Thread::create(AudioDriverPulseAudio::thread_func, this);
+ thread.start(AudioDriverPulseAudio::thread_func, this);
}
return OK;
@@ -581,16 +590,10 @@ void AudioDriverPulseAudio::set_device(String device) {
}
void AudioDriverPulseAudio::lock() {
- if (!thread) {
- return;
- }
mutex.lock();
}
void AudioDriverPulseAudio::unlock() {
- if (!thread) {
- return;
- }
mutex.unlock();
}
@@ -603,12 +606,12 @@ void AudioDriverPulseAudio::finish_device() {
}
void AudioDriverPulseAudio::finish() {
- if (!thread) {
+ if (!thread.is_started()) {
return;
}
exit_thread = true;
- Thread::wait_to_finish(thread);
+ thread.wait_to_finish();
finish_device();
@@ -622,10 +625,6 @@ void AudioDriverPulseAudio::finish() {
pa_mainloop_free(pa_ml);
pa_ml = nullptr;
}
-
- memdelete(thread);
-
- thread = nullptr;
}
Error AudioDriverPulseAudio::capture_init_device() {
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index 35ccae94b8..fa9b573d94 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,10 +37,10 @@
#include "core/os/thread.h"
#include "servers/audio_server.h"
-#include <pulse/pulseaudio.h>
+#include "pulse-so_wrap.h"
class AudioDriverPulseAudio : public AudioDriver {
- Thread *thread = nullptr;
+ Thread thread;
Mutex mutex;
pa_mainloop *pa_ml = nullptr;
diff --git a/drivers/pulseaudio/pulse-so_wrap.c b/drivers/pulseaudio/pulse-so_wrap.c
new file mode 100644
index 0000000000..12bdcc704e
--- /dev/null
+++ b/drivers/pulseaudio/pulse-so_wrap.c
@@ -0,0 +1,3950 @@
+// This file is generated. Do not edit!
+// see https://github.com/hpvb/dynload-wrapper for details
+// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:31
+// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include <pulse/pulseaudio.h> --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse-so_wrap.h --output-implementation pulse-so_wrap.c
+//
+#include <stdint.h>
+
+#define pa_get_library_version pa_get_library_version_dylibloader_orig_pulse
+#define pa_bytes_per_second pa_bytes_per_second_dylibloader_orig_pulse
+#define pa_frame_size pa_frame_size_dylibloader_orig_pulse
+#define pa_sample_size pa_sample_size_dylibloader_orig_pulse
+#define pa_sample_size_of_format pa_sample_size_of_format_dylibloader_orig_pulse
+#define pa_bytes_to_usec pa_bytes_to_usec_dylibloader_orig_pulse
+#define pa_usec_to_bytes pa_usec_to_bytes_dylibloader_orig_pulse
+#define pa_sample_spec_init pa_sample_spec_init_dylibloader_orig_pulse
+#define pa_sample_format_valid pa_sample_format_valid_dylibloader_orig_pulse
+#define pa_sample_rate_valid pa_sample_rate_valid_dylibloader_orig_pulse
+#define pa_channels_valid pa_channels_valid_dylibloader_orig_pulse
+#define pa_sample_spec_valid pa_sample_spec_valid_dylibloader_orig_pulse
+#define pa_sample_spec_equal pa_sample_spec_equal_dylibloader_orig_pulse
+#define pa_sample_format_to_string pa_sample_format_to_string_dylibloader_orig_pulse
+#define pa_parse_sample_format pa_parse_sample_format_dylibloader_orig_pulse
+#define pa_sample_spec_snprint pa_sample_spec_snprint_dylibloader_orig_pulse
+#define pa_bytes_snprint pa_bytes_snprint_dylibloader_orig_pulse
+#define pa_sample_format_is_le pa_sample_format_is_le_dylibloader_orig_pulse
+#define pa_sample_format_is_be pa_sample_format_is_be_dylibloader_orig_pulse
+#define pa_direction_valid pa_direction_valid_dylibloader_orig_pulse
+#define pa_direction_to_string pa_direction_to_string_dylibloader_orig_pulse
+#define pa_mainloop_api_once pa_mainloop_api_once_dylibloader_orig_pulse
+#define pa_proplist_new pa_proplist_new_dylibloader_orig_pulse
+#define pa_proplist_free pa_proplist_free_dylibloader_orig_pulse
+#define pa_proplist_key_valid pa_proplist_key_valid_dylibloader_orig_pulse
+#define pa_proplist_sets pa_proplist_sets_dylibloader_orig_pulse
+#define pa_proplist_setp pa_proplist_setp_dylibloader_orig_pulse
+#define pa_proplist_setf pa_proplist_setf_dylibloader_orig_pulse
+#define pa_proplist_set pa_proplist_set_dylibloader_orig_pulse
+#define pa_proplist_gets pa_proplist_gets_dylibloader_orig_pulse
+#define pa_proplist_get pa_proplist_get_dylibloader_orig_pulse
+#define pa_proplist_update pa_proplist_update_dylibloader_orig_pulse
+#define pa_proplist_unset pa_proplist_unset_dylibloader_orig_pulse
+#define pa_proplist_unset_many pa_proplist_unset_many_dylibloader_orig_pulse
+#define pa_proplist_iterate pa_proplist_iterate_dylibloader_orig_pulse
+#define pa_proplist_to_string pa_proplist_to_string_dylibloader_orig_pulse
+#define pa_proplist_to_string_sep pa_proplist_to_string_sep_dylibloader_orig_pulse
+#define pa_proplist_from_string pa_proplist_from_string_dylibloader_orig_pulse
+#define pa_proplist_contains pa_proplist_contains_dylibloader_orig_pulse
+#define pa_proplist_clear pa_proplist_clear_dylibloader_orig_pulse
+#define pa_proplist_copy pa_proplist_copy_dylibloader_orig_pulse
+#define pa_proplist_size pa_proplist_size_dylibloader_orig_pulse
+#define pa_proplist_isempty pa_proplist_isempty_dylibloader_orig_pulse
+#define pa_proplist_equal pa_proplist_equal_dylibloader_orig_pulse
+#define pa_channel_map_init pa_channel_map_init_dylibloader_orig_pulse
+#define pa_channel_map_init_mono pa_channel_map_init_mono_dylibloader_orig_pulse
+#define pa_channel_map_init_stereo pa_channel_map_init_stereo_dylibloader_orig_pulse
+#define pa_channel_map_init_auto pa_channel_map_init_auto_dylibloader_orig_pulse
+#define pa_channel_map_init_extend pa_channel_map_init_extend_dylibloader_orig_pulse
+#define pa_channel_position_to_string pa_channel_position_to_string_dylibloader_orig_pulse
+#define pa_channel_position_from_string pa_channel_position_from_string_dylibloader_orig_pulse
+#define pa_channel_position_to_pretty_string pa_channel_position_to_pretty_string_dylibloader_orig_pulse
+#define pa_channel_map_snprint pa_channel_map_snprint_dylibloader_orig_pulse
+#define pa_channel_map_parse pa_channel_map_parse_dylibloader_orig_pulse
+#define pa_channel_map_equal pa_channel_map_equal_dylibloader_orig_pulse
+#define pa_channel_map_valid pa_channel_map_valid_dylibloader_orig_pulse
+#define pa_channel_map_compatible pa_channel_map_compatible_dylibloader_orig_pulse
+#define pa_channel_map_superset pa_channel_map_superset_dylibloader_orig_pulse
+#define pa_channel_map_can_balance pa_channel_map_can_balance_dylibloader_orig_pulse
+#define pa_channel_map_can_fade pa_channel_map_can_fade_dylibloader_orig_pulse
+#define pa_channel_map_can_lfe_balance pa_channel_map_can_lfe_balance_dylibloader_orig_pulse
+#define pa_channel_map_to_name pa_channel_map_to_name_dylibloader_orig_pulse
+#define pa_channel_map_to_pretty_name pa_channel_map_to_pretty_name_dylibloader_orig_pulse
+#define pa_channel_map_has_position pa_channel_map_has_position_dylibloader_orig_pulse
+#define pa_channel_map_mask pa_channel_map_mask_dylibloader_orig_pulse
+#define pa_encoding_to_string pa_encoding_to_string_dylibloader_orig_pulse
+#define pa_encoding_from_string pa_encoding_from_string_dylibloader_orig_pulse
+#define pa_format_info_new pa_format_info_new_dylibloader_orig_pulse
+#define pa_format_info_copy pa_format_info_copy_dylibloader_orig_pulse
+#define pa_format_info_free pa_format_info_free_dylibloader_orig_pulse
+#define pa_format_info_valid pa_format_info_valid_dylibloader_orig_pulse
+#define pa_format_info_is_pcm pa_format_info_is_pcm_dylibloader_orig_pulse
+#define pa_format_info_is_compatible pa_format_info_is_compatible_dylibloader_orig_pulse
+#define pa_format_info_snprint pa_format_info_snprint_dylibloader_orig_pulse
+#define pa_format_info_from_string pa_format_info_from_string_dylibloader_orig_pulse
+#define pa_format_info_from_sample_spec pa_format_info_from_sample_spec_dylibloader_orig_pulse
+#define pa_format_info_to_sample_spec pa_format_info_to_sample_spec_dylibloader_orig_pulse
+#define pa_format_info_get_prop_type pa_format_info_get_prop_type_dylibloader_orig_pulse
+#define pa_format_info_get_prop_int pa_format_info_get_prop_int_dylibloader_orig_pulse
+#define pa_format_info_get_prop_int_range pa_format_info_get_prop_int_range_dylibloader_orig_pulse
+#define pa_format_info_get_prop_int_array pa_format_info_get_prop_int_array_dylibloader_orig_pulse
+#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_orig_pulse
+#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_orig_pulse
+#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_orig_pulse
+#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_orig_pulse
+#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_orig_pulse
+#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_orig_pulse
+#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_orig_pulse
+#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_orig_pulse
+#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_orig_pulse
+#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_orig_pulse
+#define pa_format_info_set_prop_string pa_format_info_set_prop_string_dylibloader_orig_pulse
+#define pa_format_info_set_prop_string_array pa_format_info_set_prop_string_array_dylibloader_orig_pulse
+#define pa_format_info_set_sample_format pa_format_info_set_sample_format_dylibloader_orig_pulse
+#define pa_format_info_set_rate pa_format_info_set_rate_dylibloader_orig_pulse
+#define pa_format_info_set_channels pa_format_info_set_channels_dylibloader_orig_pulse
+#define pa_format_info_set_channel_map pa_format_info_set_channel_map_dylibloader_orig_pulse
+#define pa_operation_ref pa_operation_ref_dylibloader_orig_pulse
+#define pa_operation_unref pa_operation_unref_dylibloader_orig_pulse
+#define pa_operation_cancel pa_operation_cancel_dylibloader_orig_pulse
+#define pa_operation_get_state pa_operation_get_state_dylibloader_orig_pulse
+#define pa_operation_set_state_callback pa_operation_set_state_callback_dylibloader_orig_pulse
+#define pa_context_new pa_context_new_dylibloader_orig_pulse
+#define pa_context_new_with_proplist pa_context_new_with_proplist_dylibloader_orig_pulse
+#define pa_context_unref pa_context_unref_dylibloader_orig_pulse
+#define pa_context_ref pa_context_ref_dylibloader_orig_pulse
+#define pa_context_set_state_callback pa_context_set_state_callback_dylibloader_orig_pulse
+#define pa_context_set_event_callback pa_context_set_event_callback_dylibloader_orig_pulse
+#define pa_context_errno pa_context_errno_dylibloader_orig_pulse
+#define pa_context_is_pending pa_context_is_pending_dylibloader_orig_pulse
+#define pa_context_get_state pa_context_get_state_dylibloader_orig_pulse
+#define pa_context_connect pa_context_connect_dylibloader_orig_pulse
+#define pa_context_disconnect pa_context_disconnect_dylibloader_orig_pulse
+#define pa_context_drain pa_context_drain_dylibloader_orig_pulse
+#define pa_context_exit_daemon pa_context_exit_daemon_dylibloader_orig_pulse
+#define pa_context_set_default_sink pa_context_set_default_sink_dylibloader_orig_pulse
+#define pa_context_set_default_source pa_context_set_default_source_dylibloader_orig_pulse
+#define pa_context_is_local pa_context_is_local_dylibloader_orig_pulse
+#define pa_context_set_name pa_context_set_name_dylibloader_orig_pulse
+#define pa_context_get_server pa_context_get_server_dylibloader_orig_pulse
+#define pa_context_get_protocol_version pa_context_get_protocol_version_dylibloader_orig_pulse
+#define pa_context_get_server_protocol_version pa_context_get_server_protocol_version_dylibloader_orig_pulse
+#define pa_context_proplist_update pa_context_proplist_update_dylibloader_orig_pulse
+#define pa_context_proplist_remove pa_context_proplist_remove_dylibloader_orig_pulse
+#define pa_context_get_index pa_context_get_index_dylibloader_orig_pulse
+#define pa_context_rttime_new pa_context_rttime_new_dylibloader_orig_pulse
+#define pa_context_rttime_restart pa_context_rttime_restart_dylibloader_orig_pulse
+#define pa_context_get_tile_size pa_context_get_tile_size_dylibloader_orig_pulse
+#define pa_context_load_cookie_from_file pa_context_load_cookie_from_file_dylibloader_orig_pulse
+#define pa_cvolume_equal pa_cvolume_equal_dylibloader_orig_pulse
+#define pa_cvolume_init pa_cvolume_init_dylibloader_orig_pulse
+#define pa_cvolume_set pa_cvolume_set_dylibloader_orig_pulse
+#define pa_cvolume_snprint pa_cvolume_snprint_dylibloader_orig_pulse
+#define pa_sw_cvolume_snprint_dB pa_sw_cvolume_snprint_dB_dylibloader_orig_pulse
+#define pa_cvolume_snprint_verbose pa_cvolume_snprint_verbose_dylibloader_orig_pulse
+#define pa_volume_snprint pa_volume_snprint_dylibloader_orig_pulse
+#define pa_sw_volume_snprint_dB pa_sw_volume_snprint_dB_dylibloader_orig_pulse
+#define pa_volume_snprint_verbose pa_volume_snprint_verbose_dylibloader_orig_pulse
+#define pa_cvolume_avg pa_cvolume_avg_dylibloader_orig_pulse
+#define pa_cvolume_avg_mask pa_cvolume_avg_mask_dylibloader_orig_pulse
+#define pa_cvolume_max pa_cvolume_max_dylibloader_orig_pulse
+#define pa_cvolume_max_mask pa_cvolume_max_mask_dylibloader_orig_pulse
+#define pa_cvolume_min pa_cvolume_min_dylibloader_orig_pulse
+#define pa_cvolume_min_mask pa_cvolume_min_mask_dylibloader_orig_pulse
+#define pa_cvolume_valid pa_cvolume_valid_dylibloader_orig_pulse
+#define pa_cvolume_channels_equal_to pa_cvolume_channels_equal_to_dylibloader_orig_pulse
+#define pa_sw_volume_multiply pa_sw_volume_multiply_dylibloader_orig_pulse
+#define pa_sw_cvolume_multiply pa_sw_cvolume_multiply_dylibloader_orig_pulse
+#define pa_sw_cvolume_multiply_scalar pa_sw_cvolume_multiply_scalar_dylibloader_orig_pulse
+#define pa_sw_volume_divide pa_sw_volume_divide_dylibloader_orig_pulse
+#define pa_sw_cvolume_divide pa_sw_cvolume_divide_dylibloader_orig_pulse
+#define pa_sw_cvolume_divide_scalar pa_sw_cvolume_divide_scalar_dylibloader_orig_pulse
+#define pa_sw_volume_from_dB pa_sw_volume_from_dB_dylibloader_orig_pulse
+#define pa_sw_volume_to_dB pa_sw_volume_to_dB_dylibloader_orig_pulse
+#define pa_sw_volume_from_linear pa_sw_volume_from_linear_dylibloader_orig_pulse
+#define pa_sw_volume_to_linear pa_sw_volume_to_linear_dylibloader_orig_pulse
+#define pa_cvolume_remap pa_cvolume_remap_dylibloader_orig_pulse
+#define pa_cvolume_compatible pa_cvolume_compatible_dylibloader_orig_pulse
+#define pa_cvolume_compatible_with_channel_map pa_cvolume_compatible_with_channel_map_dylibloader_orig_pulse
+#define pa_cvolume_get_balance pa_cvolume_get_balance_dylibloader_orig_pulse
+#define pa_cvolume_set_balance pa_cvolume_set_balance_dylibloader_orig_pulse
+#define pa_cvolume_get_fade pa_cvolume_get_fade_dylibloader_orig_pulse
+#define pa_cvolume_set_fade pa_cvolume_set_fade_dylibloader_orig_pulse
+#define pa_cvolume_get_lfe_balance pa_cvolume_get_lfe_balance_dylibloader_orig_pulse
+#define pa_cvolume_set_lfe_balance pa_cvolume_set_lfe_balance_dylibloader_orig_pulse
+#define pa_cvolume_scale pa_cvolume_scale_dylibloader_orig_pulse
+#define pa_cvolume_scale_mask pa_cvolume_scale_mask_dylibloader_orig_pulse
+#define pa_cvolume_set_position pa_cvolume_set_position_dylibloader_orig_pulse
+#define pa_cvolume_get_position pa_cvolume_get_position_dylibloader_orig_pulse
+#define pa_cvolume_merge pa_cvolume_merge_dylibloader_orig_pulse
+#define pa_cvolume_inc_clamp pa_cvolume_inc_clamp_dylibloader_orig_pulse
+#define pa_cvolume_inc pa_cvolume_inc_dylibloader_orig_pulse
+#define pa_cvolume_dec pa_cvolume_dec_dylibloader_orig_pulse
+#define pa_stream_new pa_stream_new_dylibloader_orig_pulse
+#define pa_stream_new_with_proplist pa_stream_new_with_proplist_dylibloader_orig_pulse
+#define pa_stream_new_extended pa_stream_new_extended_dylibloader_orig_pulse
+#define pa_stream_unref pa_stream_unref_dylibloader_orig_pulse
+#define pa_stream_ref pa_stream_ref_dylibloader_orig_pulse
+#define pa_stream_get_state pa_stream_get_state_dylibloader_orig_pulse
+#define pa_stream_get_context pa_stream_get_context_dylibloader_orig_pulse
+#define pa_stream_get_index pa_stream_get_index_dylibloader_orig_pulse
+#define pa_stream_get_device_index pa_stream_get_device_index_dylibloader_orig_pulse
+#define pa_stream_get_device_name pa_stream_get_device_name_dylibloader_orig_pulse
+#define pa_stream_is_suspended pa_stream_is_suspended_dylibloader_orig_pulse
+#define pa_stream_is_corked pa_stream_is_corked_dylibloader_orig_pulse
+#define pa_stream_connect_playback pa_stream_connect_playback_dylibloader_orig_pulse
+#define pa_stream_connect_record pa_stream_connect_record_dylibloader_orig_pulse
+#define pa_stream_disconnect pa_stream_disconnect_dylibloader_orig_pulse
+#define pa_stream_begin_write pa_stream_begin_write_dylibloader_orig_pulse
+#define pa_stream_cancel_write pa_stream_cancel_write_dylibloader_orig_pulse
+#define pa_stream_write pa_stream_write_dylibloader_orig_pulse
+#define pa_stream_write_ext_free pa_stream_write_ext_free_dylibloader_orig_pulse
+#define pa_stream_peek pa_stream_peek_dylibloader_orig_pulse
+#define pa_stream_drop pa_stream_drop_dylibloader_orig_pulse
+#define pa_stream_writable_size pa_stream_writable_size_dylibloader_orig_pulse
+#define pa_stream_readable_size pa_stream_readable_size_dylibloader_orig_pulse
+#define pa_stream_drain pa_stream_drain_dylibloader_orig_pulse
+#define pa_stream_update_timing_info pa_stream_update_timing_info_dylibloader_orig_pulse
+#define pa_stream_set_state_callback pa_stream_set_state_callback_dylibloader_orig_pulse
+#define pa_stream_set_write_callback pa_stream_set_write_callback_dylibloader_orig_pulse
+#define pa_stream_set_read_callback pa_stream_set_read_callback_dylibloader_orig_pulse
+#define pa_stream_set_overflow_callback pa_stream_set_overflow_callback_dylibloader_orig_pulse
+#define pa_stream_get_underflow_index pa_stream_get_underflow_index_dylibloader_orig_pulse
+#define pa_stream_set_underflow_callback pa_stream_set_underflow_callback_dylibloader_orig_pulse
+#define pa_stream_set_started_callback pa_stream_set_started_callback_dylibloader_orig_pulse
+#define pa_stream_set_latency_update_callback pa_stream_set_latency_update_callback_dylibloader_orig_pulse
+#define pa_stream_set_moved_callback pa_stream_set_moved_callback_dylibloader_orig_pulse
+#define pa_stream_set_suspended_callback pa_stream_set_suspended_callback_dylibloader_orig_pulse
+#define pa_stream_set_event_callback pa_stream_set_event_callback_dylibloader_orig_pulse
+#define pa_stream_set_buffer_attr_callback pa_stream_set_buffer_attr_callback_dylibloader_orig_pulse
+#define pa_stream_cork pa_stream_cork_dylibloader_orig_pulse
+#define pa_stream_flush pa_stream_flush_dylibloader_orig_pulse
+#define pa_stream_prebuf pa_stream_prebuf_dylibloader_orig_pulse
+#define pa_stream_trigger pa_stream_trigger_dylibloader_orig_pulse
+#define pa_stream_set_name pa_stream_set_name_dylibloader_orig_pulse
+#define pa_stream_get_time pa_stream_get_time_dylibloader_orig_pulse
+#define pa_stream_get_latency pa_stream_get_latency_dylibloader_orig_pulse
+#define pa_stream_get_timing_info pa_stream_get_timing_info_dylibloader_orig_pulse
+#define pa_stream_get_sample_spec pa_stream_get_sample_spec_dylibloader_orig_pulse
+#define pa_stream_get_channel_map pa_stream_get_channel_map_dylibloader_orig_pulse
+#define pa_stream_get_format_info pa_stream_get_format_info_dylibloader_orig_pulse
+#define pa_stream_get_buffer_attr pa_stream_get_buffer_attr_dylibloader_orig_pulse
+#define pa_stream_set_buffer_attr pa_stream_set_buffer_attr_dylibloader_orig_pulse
+#define pa_stream_update_sample_rate pa_stream_update_sample_rate_dylibloader_orig_pulse
+#define pa_stream_proplist_update pa_stream_proplist_update_dylibloader_orig_pulse
+#define pa_stream_proplist_remove pa_stream_proplist_remove_dylibloader_orig_pulse
+#define pa_stream_set_monitor_stream pa_stream_set_monitor_stream_dylibloader_orig_pulse
+#define pa_stream_get_monitor_stream pa_stream_get_monitor_stream_dylibloader_orig_pulse
+#define pa_context_get_sink_info_by_name pa_context_get_sink_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_sink_info_by_index pa_context_get_sink_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_sink_info_list pa_context_get_sink_info_list_dylibloader_orig_pulse
+#define pa_context_set_sink_volume_by_index pa_context_set_sink_volume_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_volume_by_name pa_context_set_sink_volume_by_name_dylibloader_orig_pulse
+#define pa_context_set_sink_mute_by_index pa_context_set_sink_mute_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_mute_by_name pa_context_set_sink_mute_by_name_dylibloader_orig_pulse
+#define pa_context_suspend_sink_by_name pa_context_suspend_sink_by_name_dylibloader_orig_pulse
+#define pa_context_suspend_sink_by_index pa_context_suspend_sink_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_port_by_index pa_context_set_sink_port_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_port_by_name pa_context_set_sink_port_by_name_dylibloader_orig_pulse
+#define pa_context_get_source_info_by_name pa_context_get_source_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_source_info_by_index pa_context_get_source_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_source_info_list pa_context_get_source_info_list_dylibloader_orig_pulse
+#define pa_context_set_source_volume_by_index pa_context_set_source_volume_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_volume_by_name pa_context_set_source_volume_by_name_dylibloader_orig_pulse
+#define pa_context_set_source_mute_by_index pa_context_set_source_mute_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_mute_by_name pa_context_set_source_mute_by_name_dylibloader_orig_pulse
+#define pa_context_suspend_source_by_name pa_context_suspend_source_by_name_dylibloader_orig_pulse
+#define pa_context_suspend_source_by_index pa_context_suspend_source_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_port_by_index pa_context_set_source_port_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_port_by_name pa_context_set_source_port_by_name_dylibloader_orig_pulse
+#define pa_context_get_server_info pa_context_get_server_info_dylibloader_orig_pulse
+#define pa_context_get_module_info pa_context_get_module_info_dylibloader_orig_pulse
+#define pa_context_get_module_info_list pa_context_get_module_info_list_dylibloader_orig_pulse
+#define pa_context_load_module pa_context_load_module_dylibloader_orig_pulse
+#define pa_context_unload_module pa_context_unload_module_dylibloader_orig_pulse
+#define pa_context_get_client_info pa_context_get_client_info_dylibloader_orig_pulse
+#define pa_context_get_client_info_list pa_context_get_client_info_list_dylibloader_orig_pulse
+#define pa_context_kill_client pa_context_kill_client_dylibloader_orig_pulse
+#define pa_context_get_card_info_by_index pa_context_get_card_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_card_info_by_name pa_context_get_card_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_card_info_list pa_context_get_card_info_list_dylibloader_orig_pulse
+#define pa_context_set_card_profile_by_index pa_context_set_card_profile_by_index_dylibloader_orig_pulse
+#define pa_context_set_card_profile_by_name pa_context_set_card_profile_by_name_dylibloader_orig_pulse
+#define pa_context_set_port_latency_offset pa_context_set_port_latency_offset_dylibloader_orig_pulse
+#define pa_context_get_sink_input_info pa_context_get_sink_input_info_dylibloader_orig_pulse
+#define pa_context_get_sink_input_info_list pa_context_get_sink_input_info_list_dylibloader_orig_pulse
+#define pa_context_move_sink_input_by_name pa_context_move_sink_input_by_name_dylibloader_orig_pulse
+#define pa_context_move_sink_input_by_index pa_context_move_sink_input_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_input_volume pa_context_set_sink_input_volume_dylibloader_orig_pulse
+#define pa_context_set_sink_input_mute pa_context_set_sink_input_mute_dylibloader_orig_pulse
+#define pa_context_kill_sink_input pa_context_kill_sink_input_dylibloader_orig_pulse
+#define pa_context_get_source_output_info pa_context_get_source_output_info_dylibloader_orig_pulse
+#define pa_context_get_source_output_info_list pa_context_get_source_output_info_list_dylibloader_orig_pulse
+#define pa_context_move_source_output_by_name pa_context_move_source_output_by_name_dylibloader_orig_pulse
+#define pa_context_move_source_output_by_index pa_context_move_source_output_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_output_volume pa_context_set_source_output_volume_dylibloader_orig_pulse
+#define pa_context_set_source_output_mute pa_context_set_source_output_mute_dylibloader_orig_pulse
+#define pa_context_kill_source_output pa_context_kill_source_output_dylibloader_orig_pulse
+#define pa_context_stat pa_context_stat_dylibloader_orig_pulse
+#define pa_context_get_sample_info_by_name pa_context_get_sample_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_sample_info_by_index pa_context_get_sample_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_sample_info_list pa_context_get_sample_info_list_dylibloader_orig_pulse
+#define pa_context_get_autoload_info_by_name pa_context_get_autoload_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_autoload_info_by_index pa_context_get_autoload_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_autoload_info_list pa_context_get_autoload_info_list_dylibloader_orig_pulse
+#define pa_context_add_autoload pa_context_add_autoload_dylibloader_orig_pulse
+#define pa_context_remove_autoload_by_name pa_context_remove_autoload_by_name_dylibloader_orig_pulse
+#define pa_context_remove_autoload_by_index pa_context_remove_autoload_by_index_dylibloader_orig_pulse
+#define pa_context_subscribe pa_context_subscribe_dylibloader_orig_pulse
+#define pa_context_set_subscribe_callback pa_context_set_subscribe_callback_dylibloader_orig_pulse
+#define pa_stream_connect_upload pa_stream_connect_upload_dylibloader_orig_pulse
+#define pa_stream_finish_upload pa_stream_finish_upload_dylibloader_orig_pulse
+#define pa_context_remove_sample pa_context_remove_sample_dylibloader_orig_pulse
+#define pa_context_play_sample pa_context_play_sample_dylibloader_orig_pulse
+#define pa_context_play_sample_with_proplist pa_context_play_sample_with_proplist_dylibloader_orig_pulse
+#define pa_strerror pa_strerror_dylibloader_orig_pulse
+#define pa_xmalloc pa_xmalloc_dylibloader_orig_pulse
+#define pa_xmalloc0 pa_xmalloc0_dylibloader_orig_pulse
+#define pa_xrealloc pa_xrealloc_dylibloader_orig_pulse
+#define pa_xfree pa_xfree_dylibloader_orig_pulse
+#define pa_xstrdup pa_xstrdup_dylibloader_orig_pulse
+#define pa_xstrndup pa_xstrndup_dylibloader_orig_pulse
+#define pa_xmemdup pa_xmemdup_dylibloader_orig_pulse
+#define pa_utf8_valid pa_utf8_valid_dylibloader_orig_pulse
+#define pa_ascii_valid pa_ascii_valid_dylibloader_orig_pulse
+#define pa_utf8_filter pa_utf8_filter_dylibloader_orig_pulse
+#define pa_ascii_filter pa_ascii_filter_dylibloader_orig_pulse
+#define pa_utf8_to_locale pa_utf8_to_locale_dylibloader_orig_pulse
+#define pa_locale_to_utf8 pa_locale_to_utf8_dylibloader_orig_pulse
+#define pa_threaded_mainloop_new pa_threaded_mainloop_new_dylibloader_orig_pulse
+#define pa_threaded_mainloop_free pa_threaded_mainloop_free_dylibloader_orig_pulse
+#define pa_threaded_mainloop_start pa_threaded_mainloop_start_dylibloader_orig_pulse
+#define pa_threaded_mainloop_stop pa_threaded_mainloop_stop_dylibloader_orig_pulse
+#define pa_threaded_mainloop_lock pa_threaded_mainloop_lock_dylibloader_orig_pulse
+#define pa_threaded_mainloop_unlock pa_threaded_mainloop_unlock_dylibloader_orig_pulse
+#define pa_threaded_mainloop_wait pa_threaded_mainloop_wait_dylibloader_orig_pulse
+#define pa_threaded_mainloop_signal pa_threaded_mainloop_signal_dylibloader_orig_pulse
+#define pa_threaded_mainloop_accept pa_threaded_mainloop_accept_dylibloader_orig_pulse
+#define pa_threaded_mainloop_get_retval pa_threaded_mainloop_get_retval_dylibloader_orig_pulse
+#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_orig_pulse
+#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_orig_pulse
+#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_orig_pulse
+#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_orig_pulse
+#define pa_mainloop_new pa_mainloop_new_dylibloader_orig_pulse
+#define pa_mainloop_free pa_mainloop_free_dylibloader_orig_pulse
+#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_orig_pulse
+#define pa_mainloop_poll pa_mainloop_poll_dylibloader_orig_pulse
+#define pa_mainloop_dispatch pa_mainloop_dispatch_dylibloader_orig_pulse
+#define pa_mainloop_get_retval pa_mainloop_get_retval_dylibloader_orig_pulse
+#define pa_mainloop_iterate pa_mainloop_iterate_dylibloader_orig_pulse
+#define pa_mainloop_run pa_mainloop_run_dylibloader_orig_pulse
+#define pa_mainloop_get_api pa_mainloop_get_api_dylibloader_orig_pulse
+#define pa_mainloop_quit pa_mainloop_quit_dylibloader_orig_pulse
+#define pa_mainloop_wakeup pa_mainloop_wakeup_dylibloader_orig_pulse
+#define pa_mainloop_set_poll_func pa_mainloop_set_poll_func_dylibloader_orig_pulse
+#define pa_signal_init pa_signal_init_dylibloader_orig_pulse
+#define pa_signal_done pa_signal_done_dylibloader_orig_pulse
+#define pa_signal_new pa_signal_new_dylibloader_orig_pulse
+#define pa_signal_free pa_signal_free_dylibloader_orig_pulse
+#define pa_signal_set_destroy pa_signal_set_destroy_dylibloader_orig_pulse
+#define pa_get_user_name pa_get_user_name_dylibloader_orig_pulse
+#define pa_get_host_name pa_get_host_name_dylibloader_orig_pulse
+#define pa_get_fqdn pa_get_fqdn_dylibloader_orig_pulse
+#define pa_get_home_dir pa_get_home_dir_dylibloader_orig_pulse
+#define pa_get_binary_name pa_get_binary_name_dylibloader_orig_pulse
+#define pa_path_get_filename pa_path_get_filename_dylibloader_orig_pulse
+#define pa_msleep pa_msleep_dylibloader_orig_pulse
+#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_orig_pulse
+#define pa_gettimeofday pa_gettimeofday_dylibloader_orig_pulse
+#define pa_timeval_diff pa_timeval_diff_dylibloader_orig_pulse
+#define pa_timeval_cmp pa_timeval_cmp_dylibloader_orig_pulse
+#define pa_timeval_age pa_timeval_age_dylibloader_orig_pulse
+#define pa_timeval_add pa_timeval_add_dylibloader_orig_pulse
+#define pa_timeval_sub pa_timeval_sub_dylibloader_orig_pulse
+#define pa_timeval_store pa_timeval_store_dylibloader_orig_pulse
+#define pa_timeval_load pa_timeval_load_dylibloader_orig_pulse
+#define pa_rtclock_now pa_rtclock_now_dylibloader_orig_pulse
+#include <pulse/pulseaudio.h>
+#undef pa_get_library_version
+#undef pa_bytes_per_second
+#undef pa_frame_size
+#undef pa_sample_size
+#undef pa_sample_size_of_format
+#undef pa_bytes_to_usec
+#undef pa_usec_to_bytes
+#undef pa_sample_spec_init
+#undef pa_sample_format_valid
+#undef pa_sample_rate_valid
+#undef pa_channels_valid
+#undef pa_sample_spec_valid
+#undef pa_sample_spec_equal
+#undef pa_sample_format_to_string
+#undef pa_parse_sample_format
+#undef pa_sample_spec_snprint
+#undef pa_bytes_snprint
+#undef pa_sample_format_is_le
+#undef pa_sample_format_is_be
+#undef pa_direction_valid
+#undef pa_direction_to_string
+#undef pa_mainloop_api_once
+#undef pa_proplist_new
+#undef pa_proplist_free
+#undef pa_proplist_key_valid
+#undef pa_proplist_sets
+#undef pa_proplist_setp
+#undef pa_proplist_setf
+#undef pa_proplist_set
+#undef pa_proplist_gets
+#undef pa_proplist_get
+#undef pa_proplist_update
+#undef pa_proplist_unset
+#undef pa_proplist_unset_many
+#undef pa_proplist_iterate
+#undef pa_proplist_to_string
+#undef pa_proplist_to_string_sep
+#undef pa_proplist_from_string
+#undef pa_proplist_contains
+#undef pa_proplist_clear
+#undef pa_proplist_copy
+#undef pa_proplist_size
+#undef pa_proplist_isempty
+#undef pa_proplist_equal
+#undef pa_channel_map_init
+#undef pa_channel_map_init_mono
+#undef pa_channel_map_init_stereo
+#undef pa_channel_map_init_auto
+#undef pa_channel_map_init_extend
+#undef pa_channel_position_to_string
+#undef pa_channel_position_from_string
+#undef pa_channel_position_to_pretty_string
+#undef pa_channel_map_snprint
+#undef pa_channel_map_parse
+#undef pa_channel_map_equal
+#undef pa_channel_map_valid
+#undef pa_channel_map_compatible
+#undef pa_channel_map_superset
+#undef pa_channel_map_can_balance
+#undef pa_channel_map_can_fade
+#undef pa_channel_map_can_lfe_balance
+#undef pa_channel_map_to_name
+#undef pa_channel_map_to_pretty_name
+#undef pa_channel_map_has_position
+#undef pa_channel_map_mask
+#undef pa_encoding_to_string
+#undef pa_encoding_from_string
+#undef pa_format_info_new
+#undef pa_format_info_copy
+#undef pa_format_info_free
+#undef pa_format_info_valid
+#undef pa_format_info_is_pcm
+#undef pa_format_info_is_compatible
+#undef pa_format_info_snprint
+#undef pa_format_info_from_string
+#undef pa_format_info_from_sample_spec
+#undef pa_format_info_to_sample_spec
+#undef pa_format_info_get_prop_type
+#undef pa_format_info_get_prop_int
+#undef pa_format_info_get_prop_int_range
+#undef pa_format_info_get_prop_int_array
+#undef pa_format_info_get_prop_string
+#undef pa_format_info_get_prop_string_array
+#undef pa_format_info_free_string_array
+#undef pa_format_info_get_sample_format
+#undef pa_format_info_get_rate
+#undef pa_format_info_get_channels
+#undef pa_format_info_get_channel_map
+#undef pa_format_info_set_prop_int
+#undef pa_format_info_set_prop_int_array
+#undef pa_format_info_set_prop_int_range
+#undef pa_format_info_set_prop_string
+#undef pa_format_info_set_prop_string_array
+#undef pa_format_info_set_sample_format
+#undef pa_format_info_set_rate
+#undef pa_format_info_set_channels
+#undef pa_format_info_set_channel_map
+#undef pa_operation_ref
+#undef pa_operation_unref
+#undef pa_operation_cancel
+#undef pa_operation_get_state
+#undef pa_operation_set_state_callback
+#undef pa_context_new
+#undef pa_context_new_with_proplist
+#undef pa_context_unref
+#undef pa_context_ref
+#undef pa_context_set_state_callback
+#undef pa_context_set_event_callback
+#undef pa_context_errno
+#undef pa_context_is_pending
+#undef pa_context_get_state
+#undef pa_context_connect
+#undef pa_context_disconnect
+#undef pa_context_drain
+#undef pa_context_exit_daemon
+#undef pa_context_set_default_sink
+#undef pa_context_set_default_source
+#undef pa_context_is_local
+#undef pa_context_set_name
+#undef pa_context_get_server
+#undef pa_context_get_protocol_version
+#undef pa_context_get_server_protocol_version
+#undef pa_context_proplist_update
+#undef pa_context_proplist_remove
+#undef pa_context_get_index
+#undef pa_context_rttime_new
+#undef pa_context_rttime_restart
+#undef pa_context_get_tile_size
+#undef pa_context_load_cookie_from_file
+#undef pa_cvolume_equal
+#undef pa_cvolume_init
+#undef pa_cvolume_set
+#undef pa_cvolume_snprint
+#undef pa_sw_cvolume_snprint_dB
+#undef pa_cvolume_snprint_verbose
+#undef pa_volume_snprint
+#undef pa_sw_volume_snprint_dB
+#undef pa_volume_snprint_verbose
+#undef pa_cvolume_avg
+#undef pa_cvolume_avg_mask
+#undef pa_cvolume_max
+#undef pa_cvolume_max_mask
+#undef pa_cvolume_min
+#undef pa_cvolume_min_mask
+#undef pa_cvolume_valid
+#undef pa_cvolume_channels_equal_to
+#undef pa_sw_volume_multiply
+#undef pa_sw_cvolume_multiply
+#undef pa_sw_cvolume_multiply_scalar
+#undef pa_sw_volume_divide
+#undef pa_sw_cvolume_divide
+#undef pa_sw_cvolume_divide_scalar
+#undef pa_sw_volume_from_dB
+#undef pa_sw_volume_to_dB
+#undef pa_sw_volume_from_linear
+#undef pa_sw_volume_to_linear
+#undef pa_cvolume_remap
+#undef pa_cvolume_compatible
+#undef pa_cvolume_compatible_with_channel_map
+#undef pa_cvolume_get_balance
+#undef pa_cvolume_set_balance
+#undef pa_cvolume_get_fade
+#undef pa_cvolume_set_fade
+#undef pa_cvolume_get_lfe_balance
+#undef pa_cvolume_set_lfe_balance
+#undef pa_cvolume_scale
+#undef pa_cvolume_scale_mask
+#undef pa_cvolume_set_position
+#undef pa_cvolume_get_position
+#undef pa_cvolume_merge
+#undef pa_cvolume_inc_clamp
+#undef pa_cvolume_inc
+#undef pa_cvolume_dec
+#undef pa_stream_new
+#undef pa_stream_new_with_proplist
+#undef pa_stream_new_extended
+#undef pa_stream_unref
+#undef pa_stream_ref
+#undef pa_stream_get_state
+#undef pa_stream_get_context
+#undef pa_stream_get_index
+#undef pa_stream_get_device_index
+#undef pa_stream_get_device_name
+#undef pa_stream_is_suspended
+#undef pa_stream_is_corked
+#undef pa_stream_connect_playback
+#undef pa_stream_connect_record
+#undef pa_stream_disconnect
+#undef pa_stream_begin_write
+#undef pa_stream_cancel_write
+#undef pa_stream_write
+#undef pa_stream_write_ext_free
+#undef pa_stream_peek
+#undef pa_stream_drop
+#undef pa_stream_writable_size
+#undef pa_stream_readable_size
+#undef pa_stream_drain
+#undef pa_stream_update_timing_info
+#undef pa_stream_set_state_callback
+#undef pa_stream_set_write_callback
+#undef pa_stream_set_read_callback
+#undef pa_stream_set_overflow_callback
+#undef pa_stream_get_underflow_index
+#undef pa_stream_set_underflow_callback
+#undef pa_stream_set_started_callback
+#undef pa_stream_set_latency_update_callback
+#undef pa_stream_set_moved_callback
+#undef pa_stream_set_suspended_callback
+#undef pa_stream_set_event_callback
+#undef pa_stream_set_buffer_attr_callback
+#undef pa_stream_cork
+#undef pa_stream_flush
+#undef pa_stream_prebuf
+#undef pa_stream_trigger
+#undef pa_stream_set_name
+#undef pa_stream_get_time
+#undef pa_stream_get_latency
+#undef pa_stream_get_timing_info
+#undef pa_stream_get_sample_spec
+#undef pa_stream_get_channel_map
+#undef pa_stream_get_format_info
+#undef pa_stream_get_buffer_attr
+#undef pa_stream_set_buffer_attr
+#undef pa_stream_update_sample_rate
+#undef pa_stream_proplist_update
+#undef pa_stream_proplist_remove
+#undef pa_stream_set_monitor_stream
+#undef pa_stream_get_monitor_stream
+#undef pa_context_get_sink_info_by_name
+#undef pa_context_get_sink_info_by_index
+#undef pa_context_get_sink_info_list
+#undef pa_context_set_sink_volume_by_index
+#undef pa_context_set_sink_volume_by_name
+#undef pa_context_set_sink_mute_by_index
+#undef pa_context_set_sink_mute_by_name
+#undef pa_context_suspend_sink_by_name
+#undef pa_context_suspend_sink_by_index
+#undef pa_context_set_sink_port_by_index
+#undef pa_context_set_sink_port_by_name
+#undef pa_context_get_source_info_by_name
+#undef pa_context_get_source_info_by_index
+#undef pa_context_get_source_info_list
+#undef pa_context_set_source_volume_by_index
+#undef pa_context_set_source_volume_by_name
+#undef pa_context_set_source_mute_by_index
+#undef pa_context_set_source_mute_by_name
+#undef pa_context_suspend_source_by_name
+#undef pa_context_suspend_source_by_index
+#undef pa_context_set_source_port_by_index
+#undef pa_context_set_source_port_by_name
+#undef pa_context_get_server_info
+#undef pa_context_get_module_info
+#undef pa_context_get_module_info_list
+#undef pa_context_load_module
+#undef pa_context_unload_module
+#undef pa_context_get_client_info
+#undef pa_context_get_client_info_list
+#undef pa_context_kill_client
+#undef pa_context_get_card_info_by_index
+#undef pa_context_get_card_info_by_name
+#undef pa_context_get_card_info_list
+#undef pa_context_set_card_profile_by_index
+#undef pa_context_set_card_profile_by_name
+#undef pa_context_set_port_latency_offset
+#undef pa_context_get_sink_input_info
+#undef pa_context_get_sink_input_info_list
+#undef pa_context_move_sink_input_by_name
+#undef pa_context_move_sink_input_by_index
+#undef pa_context_set_sink_input_volume
+#undef pa_context_set_sink_input_mute
+#undef pa_context_kill_sink_input
+#undef pa_context_get_source_output_info
+#undef pa_context_get_source_output_info_list
+#undef pa_context_move_source_output_by_name
+#undef pa_context_move_source_output_by_index
+#undef pa_context_set_source_output_volume
+#undef pa_context_set_source_output_mute
+#undef pa_context_kill_source_output
+#undef pa_context_stat
+#undef pa_context_get_sample_info_by_name
+#undef pa_context_get_sample_info_by_index
+#undef pa_context_get_sample_info_list
+#undef pa_context_get_autoload_info_by_name
+#undef pa_context_get_autoload_info_by_index
+#undef pa_context_get_autoload_info_list
+#undef pa_context_add_autoload
+#undef pa_context_remove_autoload_by_name
+#undef pa_context_remove_autoload_by_index
+#undef pa_context_subscribe
+#undef pa_context_set_subscribe_callback
+#undef pa_stream_connect_upload
+#undef pa_stream_finish_upload
+#undef pa_context_remove_sample
+#undef pa_context_play_sample
+#undef pa_context_play_sample_with_proplist
+#undef pa_strerror
+#undef pa_xmalloc
+#undef pa_xmalloc0
+#undef pa_xrealloc
+#undef pa_xfree
+#undef pa_xstrdup
+#undef pa_xstrndup
+#undef pa_xmemdup
+#undef pa_utf8_valid
+#undef pa_ascii_valid
+#undef pa_utf8_filter
+#undef pa_ascii_filter
+#undef pa_utf8_to_locale
+#undef pa_locale_to_utf8
+#undef pa_threaded_mainloop_new
+#undef pa_threaded_mainloop_free
+#undef pa_threaded_mainloop_start
+#undef pa_threaded_mainloop_stop
+#undef pa_threaded_mainloop_lock
+#undef pa_threaded_mainloop_unlock
+#undef pa_threaded_mainloop_wait
+#undef pa_threaded_mainloop_signal
+#undef pa_threaded_mainloop_accept
+#undef pa_threaded_mainloop_get_retval
+#undef pa_threaded_mainloop_get_api
+#undef pa_threaded_mainloop_in_thread
+#undef pa_threaded_mainloop_set_name
+#undef pa_threaded_mainloop_once_unlocked
+#undef pa_mainloop_new
+#undef pa_mainloop_free
+#undef pa_mainloop_prepare
+#undef pa_mainloop_poll
+#undef pa_mainloop_dispatch
+#undef pa_mainloop_get_retval
+#undef pa_mainloop_iterate
+#undef pa_mainloop_run
+#undef pa_mainloop_get_api
+#undef pa_mainloop_quit
+#undef pa_mainloop_wakeup
+#undef pa_mainloop_set_poll_func
+#undef pa_signal_init
+#undef pa_signal_done
+#undef pa_signal_new
+#undef pa_signal_free
+#undef pa_signal_set_destroy
+#undef pa_get_user_name
+#undef pa_get_host_name
+#undef pa_get_fqdn
+#undef pa_get_home_dir
+#undef pa_get_binary_name
+#undef pa_path_get_filename
+#undef pa_msleep
+#undef pa_thread_make_realtime
+#undef pa_gettimeofday
+#undef pa_timeval_diff
+#undef pa_timeval_cmp
+#undef pa_timeval_age
+#undef pa_timeval_add
+#undef pa_timeval_sub
+#undef pa_timeval_store
+#undef pa_timeval_load
+#undef pa_rtclock_now
+#include <dlfcn.h>
+#include <stdio.h>
+const char* (*pa_get_library_version_dylibloader_wrapper_pulse)( void);
+size_t (*pa_bytes_per_second_dylibloader_wrapper_pulse)(const pa_sample_spec*);
+size_t (*pa_frame_size_dylibloader_wrapper_pulse)(const pa_sample_spec*);
+size_t (*pa_sample_size_dylibloader_wrapper_pulse)(const pa_sample_spec*);
+size_t (*pa_sample_size_of_format_dylibloader_wrapper_pulse)( pa_sample_format_t);
+pa_usec_t (*pa_bytes_to_usec_dylibloader_wrapper_pulse)( uint64_t,const pa_sample_spec*);
+size_t (*pa_usec_to_bytes_dylibloader_wrapper_pulse)( pa_usec_t,const pa_sample_spec*);
+pa_sample_spec* (*pa_sample_spec_init_dylibloader_wrapper_pulse)( pa_sample_spec*);
+int (*pa_sample_format_valid_dylibloader_wrapper_pulse)( unsigned);
+int (*pa_sample_rate_valid_dylibloader_wrapper_pulse)( uint32_t);
+int (*pa_channels_valid_dylibloader_wrapper_pulse)( uint8_t);
+int (*pa_sample_spec_valid_dylibloader_wrapper_pulse)(const pa_sample_spec*);
+int (*pa_sample_spec_equal_dylibloader_wrapper_pulse)(const pa_sample_spec*,const pa_sample_spec*);
+const char* (*pa_sample_format_to_string_dylibloader_wrapper_pulse)( pa_sample_format_t);
+pa_sample_format_t (*pa_parse_sample_format_dylibloader_wrapper_pulse)(const char*);
+char* (*pa_sample_spec_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_sample_spec*);
+char* (*pa_bytes_snprint_dylibloader_wrapper_pulse)( char*, size_t, unsigned);
+int (*pa_sample_format_is_le_dylibloader_wrapper_pulse)( pa_sample_format_t);
+int (*pa_sample_format_is_be_dylibloader_wrapper_pulse)( pa_sample_format_t);
+int (*pa_direction_valid_dylibloader_wrapper_pulse)( pa_direction_t);
+const char* (*pa_direction_to_string_dylibloader_wrapper_pulse)( pa_direction_t);
+void (*pa_mainloop_api_once_dylibloader_wrapper_pulse)( pa_mainloop_api*, void*, void*);
+pa_proplist* (*pa_proplist_new_dylibloader_wrapper_pulse)( void);
+void (*pa_proplist_free_dylibloader_wrapper_pulse)( pa_proplist*);
+int (*pa_proplist_key_valid_dylibloader_wrapper_pulse)(const char*);
+int (*pa_proplist_sets_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*);
+int (*pa_proplist_setp_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
+int (*pa_proplist_setf_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*,...);
+int (*pa_proplist_set_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const void*, size_t);
+const char* (*pa_proplist_gets_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+int (*pa_proplist_get_dylibloader_wrapper_pulse)(const pa_proplist*,const char*,const void**, size_t*);
+void (*pa_proplist_update_dylibloader_wrapper_pulse)( pa_proplist*, pa_update_mode_t,const pa_proplist*);
+int (*pa_proplist_unset_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
+int (*pa_proplist_unset_many_dylibloader_wrapper_pulse)( pa_proplist*,const char* []);
+const char* (*pa_proplist_iterate_dylibloader_wrapper_pulse)(const pa_proplist*, void**);
+char* (*pa_proplist_to_string_dylibloader_wrapper_pulse)(const pa_proplist*);
+char* (*pa_proplist_to_string_sep_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+pa_proplist* (*pa_proplist_from_string_dylibloader_wrapper_pulse)(const char*);
+int (*pa_proplist_contains_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+void (*pa_proplist_clear_dylibloader_wrapper_pulse)( pa_proplist*);
+pa_proplist* (*pa_proplist_copy_dylibloader_wrapper_pulse)(const pa_proplist*);
+unsigned (*pa_proplist_size_dylibloader_wrapper_pulse)(const pa_proplist*);
+int (*pa_proplist_isempty_dylibloader_wrapper_pulse)(const pa_proplist*);
+int (*pa_proplist_equal_dylibloader_wrapper_pulse)(const pa_proplist*,const pa_proplist*);
+pa_channel_map* (*pa_channel_map_init_dylibloader_wrapper_pulse)( pa_channel_map*);
+pa_channel_map* (*pa_channel_map_init_mono_dylibloader_wrapper_pulse)( pa_channel_map*);
+pa_channel_map* (*pa_channel_map_init_stereo_dylibloader_wrapper_pulse)( pa_channel_map*);
+pa_channel_map* (*pa_channel_map_init_auto_dylibloader_wrapper_pulse)( pa_channel_map*, unsigned, pa_channel_map_def_t);
+pa_channel_map* (*pa_channel_map_init_extend_dylibloader_wrapper_pulse)( pa_channel_map*, unsigned, pa_channel_map_def_t);
+const char* (*pa_channel_position_to_string_dylibloader_wrapper_pulse)( pa_channel_position_t);
+pa_channel_position_t (*pa_channel_position_from_string_dylibloader_wrapper_pulse)(const char*);
+const char* (*pa_channel_position_to_pretty_string_dylibloader_wrapper_pulse)( pa_channel_position_t);
+char* (*pa_channel_map_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_channel_map*);
+pa_channel_map* (*pa_channel_map_parse_dylibloader_wrapper_pulse)( pa_channel_map*,const char*);
+int (*pa_channel_map_equal_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_channel_map*);
+int (*pa_channel_map_valid_dylibloader_wrapper_pulse)(const pa_channel_map*);
+int (*pa_channel_map_compatible_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_sample_spec*);
+int (*pa_channel_map_superset_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_channel_map*);
+int (*pa_channel_map_can_balance_dylibloader_wrapper_pulse)(const pa_channel_map*);
+int (*pa_channel_map_can_fade_dylibloader_wrapper_pulse)(const pa_channel_map*);
+int (*pa_channel_map_can_lfe_balance_dylibloader_wrapper_pulse)(const pa_channel_map*);
+const char* (*pa_channel_map_to_name_dylibloader_wrapper_pulse)(const pa_channel_map*);
+const char* (*pa_channel_map_to_pretty_name_dylibloader_wrapper_pulse)(const pa_channel_map*);
+int (*pa_channel_map_has_position_dylibloader_wrapper_pulse)(const pa_channel_map*, pa_channel_position_t);
+pa_channel_position_mask_t (*pa_channel_map_mask_dylibloader_wrapper_pulse)(const pa_channel_map*);
+const char* (*pa_encoding_to_string_dylibloader_wrapper_pulse)( pa_encoding_t);
+pa_encoding_t (*pa_encoding_from_string_dylibloader_wrapper_pulse)(const char*);
+pa_format_info* (*pa_format_info_new_dylibloader_wrapper_pulse)( void);
+pa_format_info* (*pa_format_info_copy_dylibloader_wrapper_pulse)(const pa_format_info*);
+void (*pa_format_info_free_dylibloader_wrapper_pulse)( pa_format_info*);
+int (*pa_format_info_valid_dylibloader_wrapper_pulse)(const pa_format_info*);
+int (*pa_format_info_is_pcm_dylibloader_wrapper_pulse)(const pa_format_info*);
+int (*pa_format_info_is_compatible_dylibloader_wrapper_pulse)(const pa_format_info*,const pa_format_info*);
+char* (*pa_format_info_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_format_info*);
+pa_format_info* (*pa_format_info_from_string_dylibloader_wrapper_pulse)(const char*);
+pa_format_info* (*pa_format_info_from_sample_spec_dylibloader_wrapper_pulse)(const pa_sample_spec*,const pa_channel_map*);
+int (*pa_format_info_to_sample_spec_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_spec*, pa_channel_map*);
+pa_prop_type_t (*pa_format_info_get_prop_type_dylibloader_wrapper_pulse)(const pa_format_info*,const char*);
+int (*pa_format_info_get_prop_int_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int*);
+int (*pa_format_info_get_prop_int_range_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int*, int*);
+int (*pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int**, int*);
+int (*pa_format_info_get_prop_string_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char**);
+int (*pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char***, int*);
+void (*pa_format_info_free_string_array_dylibloader_wrapper_pulse)( char**, int);
+int (*pa_format_info_get_sample_format_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_format_t*);
+int (*pa_format_info_get_rate_dylibloader_wrapper_pulse)(const pa_format_info*, uint32_t*);
+int (*pa_format_info_get_channels_dylibloader_wrapper_pulse)(const pa_format_info*, uint8_t*);
+int (*pa_format_info_get_channel_map_dylibloader_wrapper_pulse)(const pa_format_info*, pa_channel_map*);
+void (*pa_format_info_set_prop_int_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int);
+void (*pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const int*, int);
+void (*pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int, int);
+void (*pa_format_info_set_prop_string_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const char*);
+void (*pa_format_info_set_prop_string_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const char**, int);
+void (*pa_format_info_set_sample_format_dylibloader_wrapper_pulse)( pa_format_info*, pa_sample_format_t);
+void (*pa_format_info_set_rate_dylibloader_wrapper_pulse)( pa_format_info*, int);
+void (*pa_format_info_set_channels_dylibloader_wrapper_pulse)( pa_format_info*, int);
+void (*pa_format_info_set_channel_map_dylibloader_wrapper_pulse)( pa_format_info*,const pa_channel_map*);
+pa_operation* (*pa_operation_ref_dylibloader_wrapper_pulse)( pa_operation*);
+void (*pa_operation_unref_dylibloader_wrapper_pulse)( pa_operation*);
+void (*pa_operation_cancel_dylibloader_wrapper_pulse)( pa_operation*);
+pa_operation_state_t (*pa_operation_get_state_dylibloader_wrapper_pulse)(const pa_operation*);
+void (*pa_operation_set_state_callback_dylibloader_wrapper_pulse)( pa_operation*, pa_operation_notify_cb_t, void*);
+pa_context* (*pa_context_new_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*);
+pa_context* (*pa_context_new_with_proplist_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*,const pa_proplist*);
+void (*pa_context_unref_dylibloader_wrapper_pulse)( pa_context*);
+pa_context* (*pa_context_ref_dylibloader_wrapper_pulse)( pa_context*);
+void (*pa_context_set_state_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*);
+void (*pa_context_set_event_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_event_cb_t, void*);
+int (*pa_context_errno_dylibloader_wrapper_pulse)(const pa_context*);
+int (*pa_context_is_pending_dylibloader_wrapper_pulse)(const pa_context*);
+pa_context_state_t (*pa_context_get_state_dylibloader_wrapper_pulse)(const pa_context*);
+int (*pa_context_connect_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_flags_t,const pa_spawn_api*);
+void (*pa_context_disconnect_dylibloader_wrapper_pulse)( pa_context*);
+pa_operation* (*pa_context_drain_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*);
+pa_operation* (*pa_context_exit_daemon_dylibloader_wrapper_pulse)( pa_context*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_default_sink_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_default_source_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
+int (*pa_context_is_local_dylibloader_wrapper_pulse)(const pa_context*);
+pa_operation* (*pa_context_set_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
+const char* (*pa_context_get_server_dylibloader_wrapper_pulse)(const pa_context*);
+uint32_t (*pa_context_get_protocol_version_dylibloader_wrapper_pulse)(const pa_context*);
+uint32_t (*pa_context_get_server_protocol_version_dylibloader_wrapper_pulse)(const pa_context*);
+pa_operation* (*pa_context_proplist_update_dylibloader_wrapper_pulse)( pa_context*, pa_update_mode_t,const pa_proplist*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_proplist_remove_dylibloader_wrapper_pulse)( pa_context*,const char* [], pa_context_success_cb_t, void*);
+uint32_t (*pa_context_get_index_dylibloader_wrapper_pulse)(const pa_context*);
+pa_time_event* (*pa_context_rttime_new_dylibloader_wrapper_pulse)(const pa_context*, pa_usec_t, pa_time_event_cb_t, void*);
+void (*pa_context_rttime_restart_dylibloader_wrapper_pulse)(const pa_context*, pa_time_event*, pa_usec_t);
+size_t (*pa_context_get_tile_size_dylibloader_wrapper_pulse)(const pa_context*,const pa_sample_spec*);
+int (*pa_context_load_cookie_from_file_dylibloader_wrapper_pulse)( pa_context*,const char*);
+int (*pa_cvolume_equal_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_cvolume*);
+pa_cvolume* (*pa_cvolume_init_dylibloader_wrapper_pulse)( pa_cvolume*);
+pa_cvolume* (*pa_cvolume_set_dylibloader_wrapper_pulse)( pa_cvolume*, unsigned, pa_volume_t);
+char* (*pa_cvolume_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*);
+char* (*pa_sw_cvolume_snprint_dB_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*);
+char* (*pa_cvolume_snprint_verbose_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*,const pa_channel_map*, int);
+char* (*pa_volume_snprint_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t);
+char* (*pa_sw_volume_snprint_dB_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t);
+char* (*pa_volume_snprint_verbose_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t, int);
+pa_volume_t (*pa_cvolume_avg_dylibloader_wrapper_pulse)(const pa_cvolume*);
+pa_volume_t (*pa_cvolume_avg_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t);
+pa_volume_t (*pa_cvolume_max_dylibloader_wrapper_pulse)(const pa_cvolume*);
+pa_volume_t (*pa_cvolume_max_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t);
+pa_volume_t (*pa_cvolume_min_dylibloader_wrapper_pulse)(const pa_cvolume*);
+pa_volume_t (*pa_cvolume_min_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t);
+int (*pa_cvolume_valid_dylibloader_wrapper_pulse)(const pa_cvolume*);
+int (*pa_cvolume_channels_equal_to_dylibloader_wrapper_pulse)(const pa_cvolume*, pa_volume_t);
+pa_volume_t (*pa_sw_volume_multiply_dylibloader_wrapper_pulse)( pa_volume_t, pa_volume_t);
+pa_cvolume* (*pa_sw_cvolume_multiply_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*);
+pa_cvolume* (*pa_sw_cvolume_multiply_scalar_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*, pa_volume_t);
+pa_volume_t (*pa_sw_volume_divide_dylibloader_wrapper_pulse)( pa_volume_t, pa_volume_t);
+pa_cvolume* (*pa_sw_cvolume_divide_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*);
+pa_cvolume* (*pa_sw_cvolume_divide_scalar_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*, pa_volume_t);
+pa_volume_t (*pa_sw_volume_from_dB_dylibloader_wrapper_pulse)( double);
+double (*pa_sw_volume_to_dB_dylibloader_wrapper_pulse)( pa_volume_t);
+pa_volume_t (*pa_sw_volume_from_linear_dylibloader_wrapper_pulse)( double);
+double (*pa_sw_volume_to_linear_dylibloader_wrapper_pulse)( pa_volume_t);
+pa_cvolume* (*pa_cvolume_remap_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*,const pa_channel_map*);
+int (*pa_cvolume_compatible_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_sample_spec*);
+int (*pa_cvolume_compatible_with_channel_map_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
+float (*pa_cvolume_get_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
+pa_cvolume* (*pa_cvolume_set_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float);
+float (*pa_cvolume_get_fade_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
+pa_cvolume* (*pa_cvolume_set_fade_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float);
+float (*pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
+pa_cvolume* (*pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float);
+pa_cvolume* (*pa_cvolume_scale_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
+pa_cvolume* (*pa_cvolume_scale_mask_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t,const pa_channel_map*, pa_channel_position_mask_t);
+pa_cvolume* (*pa_cvolume_set_position_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, pa_channel_position_t, pa_volume_t);
+pa_volume_t (*pa_cvolume_get_position_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_t);
+pa_cvolume* (*pa_cvolume_merge_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*);
+pa_cvolume* (*pa_cvolume_inc_clamp_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t, pa_volume_t);
+pa_cvolume* (*pa_cvolume_inc_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
+pa_cvolume* (*pa_cvolume_dec_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
+pa_stream* (*pa_stream_new_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_sample_spec*,const pa_channel_map*);
+pa_stream* (*pa_stream_new_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_sample_spec*,const pa_channel_map*, pa_proplist*);
+pa_stream* (*pa_stream_new_extended_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_format_info**, unsigned int, pa_proplist*);
+void (*pa_stream_unref_dylibloader_wrapper_pulse)( pa_stream*);
+pa_stream* (*pa_stream_ref_dylibloader_wrapper_pulse)( pa_stream*);
+pa_stream_state_t (*pa_stream_get_state_dylibloader_wrapper_pulse)(const pa_stream*);
+pa_context* (*pa_stream_get_context_dylibloader_wrapper_pulse)(const pa_stream*);
+uint32_t (*pa_stream_get_index_dylibloader_wrapper_pulse)(const pa_stream*);
+uint32_t (*pa_stream_get_device_index_dylibloader_wrapper_pulse)(const pa_stream*);
+const char* (*pa_stream_get_device_name_dylibloader_wrapper_pulse)(const pa_stream*);
+int (*pa_stream_is_suspended_dylibloader_wrapper_pulse)(const pa_stream*);
+int (*pa_stream_is_corked_dylibloader_wrapper_pulse)(const pa_stream*);
+int (*pa_stream_connect_playback_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t,const pa_cvolume*, pa_stream*);
+int (*pa_stream_connect_record_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t);
+int (*pa_stream_disconnect_dylibloader_wrapper_pulse)( pa_stream*);
+int (*pa_stream_begin_write_dylibloader_wrapper_pulse)( pa_stream*, void**, size_t*);
+int (*pa_stream_cancel_write_dylibloader_wrapper_pulse)( pa_stream*);
+int (*pa_stream_write_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, int64_t, pa_seek_mode_t);
+int (*pa_stream_write_ext_free_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, void*, int64_t, pa_seek_mode_t);
+int (*pa_stream_peek_dylibloader_wrapper_pulse)( pa_stream*,const void**, size_t*);
+int (*pa_stream_drop_dylibloader_wrapper_pulse)( pa_stream*);
+size_t (*pa_stream_writable_size_dylibloader_wrapper_pulse)(const pa_stream*);
+size_t (*pa_stream_readable_size_dylibloader_wrapper_pulse)(const pa_stream*);
+pa_operation* (*pa_stream_drain_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+pa_operation* (*pa_stream_update_timing_info_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+void (*pa_stream_set_state_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+void (*pa_stream_set_write_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*);
+void (*pa_stream_set_read_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*);
+void (*pa_stream_set_overflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+int64_t (*pa_stream_get_underflow_index_dylibloader_wrapper_pulse)(const pa_stream*);
+void (*pa_stream_set_underflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+void (*pa_stream_set_started_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+void (*pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+void (*pa_stream_set_moved_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+void (*pa_stream_set_suspended_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+void (*pa_stream_set_event_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_event_cb_t, void*);
+void (*pa_stream_set_buffer_attr_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+pa_operation* (*pa_stream_cork_dylibloader_wrapper_pulse)( pa_stream*, int, pa_stream_success_cb_t, void*);
+pa_operation* (*pa_stream_flush_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+pa_operation* (*pa_stream_prebuf_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+pa_operation* (*pa_stream_trigger_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+pa_operation* (*pa_stream_set_name_dylibloader_wrapper_pulse)( pa_stream*,const char*, pa_stream_success_cb_t, void*);
+int (*pa_stream_get_time_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*);
+int (*pa_stream_get_latency_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*, int*);
+const pa_timing_info* (*pa_stream_get_timing_info_dylibloader_wrapper_pulse)( pa_stream*);
+const pa_sample_spec* (*pa_stream_get_sample_spec_dylibloader_wrapper_pulse)( pa_stream*);
+const pa_channel_map* (*pa_stream_get_channel_map_dylibloader_wrapper_pulse)( pa_stream*);
+const pa_format_info* (*pa_stream_get_format_info_dylibloader_wrapper_pulse)(const pa_stream*);
+const pa_buffer_attr* (*pa_stream_get_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*);
+pa_operation* (*pa_stream_set_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*,const pa_buffer_attr*, pa_stream_success_cb_t, void*);
+pa_operation* (*pa_stream_update_sample_rate_dylibloader_wrapper_pulse)( pa_stream*, uint32_t, pa_stream_success_cb_t, void*);
+pa_operation* (*pa_stream_proplist_update_dylibloader_wrapper_pulse)( pa_stream*, pa_update_mode_t, pa_proplist*, pa_stream_success_cb_t, void*);
+pa_operation* (*pa_stream_proplist_remove_dylibloader_wrapper_pulse)( pa_stream*,const char* [], pa_stream_success_cb_t, void*);
+int (*pa_stream_set_monitor_stream_dylibloader_wrapper_pulse)( pa_stream*, uint32_t);
+uint32_t (*pa_stream_get_monitor_stream_dylibloader_wrapper_pulse)(const pa_stream*);
+pa_operation* (*pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sink_info_cb_t, void*);
+pa_operation* (*pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_info_cb_t, void*);
+pa_operation* (*pa_context_get_sink_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_info_cb_t, void*);
+pa_operation* (*pa_context_set_sink_volume_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_sink_volume_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_cvolume*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_sink_mute_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_sink_mute_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_suspend_sink_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_suspend_sink_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_sink_port_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_sink_port_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_get_source_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_source_info_cb_t, void*);
+pa_operation* (*pa_context_get_source_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_source_info_cb_t, void*);
+pa_operation* (*pa_context_get_source_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_source_info_cb_t, void*);
+pa_operation* (*pa_context_set_source_volume_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_source_volume_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_cvolume*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_source_mute_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_source_mute_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_suspend_source_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_suspend_source_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_source_port_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_source_port_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_get_server_info_dylibloader_wrapper_pulse)( pa_context*, pa_server_info_cb_t, void*);
+pa_operation* (*pa_context_get_module_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_module_info_cb_t, void*);
+pa_operation* (*pa_context_get_module_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_module_info_cb_t, void*);
+pa_operation* (*pa_context_load_module_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_index_cb_t, void*);
+pa_operation* (*pa_context_unload_module_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_get_client_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_client_info_cb_t, void*);
+pa_operation* (*pa_context_get_client_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_client_info_cb_t, void*);
+pa_operation* (*pa_context_kill_client_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_get_card_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_card_info_cb_t, void*);
+pa_operation* (*pa_context_get_card_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_card_info_cb_t, void*);
+pa_operation* (*pa_context_get_card_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_card_info_cb_t, void*);
+pa_operation* (*pa_context_set_card_profile_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_card_profile_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_port_latency_offset_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, int64_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_get_sink_input_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_input_info_cb_t, void*);
+pa_operation* (*pa_context_get_sink_input_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_input_info_cb_t, void*);
+pa_operation* (*pa_context_move_sink_input_by_name_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_move_sink_input_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, uint32_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_sink_input_volume_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_sink_input_mute_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_kill_sink_input_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_get_source_output_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_source_output_info_cb_t, void*);
+pa_operation* (*pa_context_get_source_output_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_source_output_info_cb_t, void*);
+pa_operation* (*pa_context_move_source_output_by_name_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_move_source_output_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, uint32_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_source_output_volume_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_set_source_output_mute_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_kill_source_output_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_stat_dylibloader_wrapper_pulse)( pa_context*, pa_stat_info_cb_t, void*);
+pa_operation* (*pa_context_get_sample_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sample_info_cb_t, void*);
+pa_operation* (*pa_context_get_sample_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sample_info_cb_t, void*);
+pa_operation* (*pa_context_get_sample_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sample_info_cb_t, void*);
+pa_operation* (*pa_context_get_autoload_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t, pa_autoload_info_cb_t, void*);
+pa_operation* (*pa_context_get_autoload_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_autoload_info_cb_t, void*);
+pa_operation* (*pa_context_get_autoload_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_autoload_info_cb_t, void*);
+pa_operation* (*pa_context_add_autoload_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t,const char*,const char*, pa_context_index_cb_t, void*);
+pa_operation* (*pa_context_remove_autoload_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_remove_autoload_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_subscribe_dylibloader_wrapper_pulse)( pa_context*, pa_subscription_mask_t, pa_context_success_cb_t, void*);
+void (*pa_context_set_subscribe_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_subscribe_cb_t, void*);
+int (*pa_stream_connect_upload_dylibloader_wrapper_pulse)( pa_stream*, size_t);
+int (*pa_stream_finish_upload_dylibloader_wrapper_pulse)( pa_stream*);
+pa_operation* (*pa_context_remove_sample_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_play_sample_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t, pa_context_success_cb_t, void*);
+pa_operation* (*pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t,const pa_proplist*, pa_context_play_sample_cb_t, void*);
+const char* (*pa_strerror_dylibloader_wrapper_pulse)( int);
+void* (*pa_xmalloc_dylibloader_wrapper_pulse)( size_t);
+void* (*pa_xmalloc0_dylibloader_wrapper_pulse)( size_t);
+void* (*pa_xrealloc_dylibloader_wrapper_pulse)( void*, size_t);
+void (*pa_xfree_dylibloader_wrapper_pulse)( void*);
+char* (*pa_xstrdup_dylibloader_wrapper_pulse)(const char*);
+char* (*pa_xstrndup_dylibloader_wrapper_pulse)(const char*, size_t);
+void* (*pa_xmemdup_dylibloader_wrapper_pulse)(const void*, size_t);
+char* (*pa_utf8_valid_dylibloader_wrapper_pulse)(const char*);
+char* (*pa_ascii_valid_dylibloader_wrapper_pulse)(const char*);
+char* (*pa_utf8_filter_dylibloader_wrapper_pulse)(const char*);
+char* (*pa_ascii_filter_dylibloader_wrapper_pulse)(const char*);
+char* (*pa_utf8_to_locale_dylibloader_wrapper_pulse)(const char*);
+char* (*pa_locale_to_utf8_dylibloader_wrapper_pulse)(const char*);
+pa_threaded_mainloop* (*pa_threaded_mainloop_new_dylibloader_wrapper_pulse)( void);
+void (*pa_threaded_mainloop_free_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+int (*pa_threaded_mainloop_start_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+void (*pa_threaded_mainloop_stop_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+void (*pa_threaded_mainloop_lock_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+void (*pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+void (*pa_threaded_mainloop_wait_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+void (*pa_threaded_mainloop_signal_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, int);
+void (*pa_threaded_mainloop_accept_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+int (*pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_threaded_mainloop*);
+pa_mainloop_api* (*pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+int (*pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+void (*pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse)( pa_threaded_mainloop*,const char*);
+void (*pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, void*, void*);
+pa_mainloop* (*pa_mainloop_new_dylibloader_wrapper_pulse)( void);
+void (*pa_mainloop_free_dylibloader_wrapper_pulse)( pa_mainloop*);
+int (*pa_mainloop_prepare_dylibloader_wrapper_pulse)( pa_mainloop*, int);
+int (*pa_mainloop_poll_dylibloader_wrapper_pulse)( pa_mainloop*);
+int (*pa_mainloop_dispatch_dylibloader_wrapper_pulse)( pa_mainloop*);
+int (*pa_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_mainloop*);
+int (*pa_mainloop_iterate_dylibloader_wrapper_pulse)( pa_mainloop*, int, int*);
+int (*pa_mainloop_run_dylibloader_wrapper_pulse)( pa_mainloop*, int*);
+pa_mainloop_api* (*pa_mainloop_get_api_dylibloader_wrapper_pulse)( pa_mainloop*);
+void (*pa_mainloop_quit_dylibloader_wrapper_pulse)( pa_mainloop*, int);
+void (*pa_mainloop_wakeup_dylibloader_wrapper_pulse)( pa_mainloop*);
+void (*pa_mainloop_set_poll_func_dylibloader_wrapper_pulse)( pa_mainloop*, pa_poll_func, void*);
+int (*pa_signal_init_dylibloader_wrapper_pulse)( pa_mainloop_api*);
+void (*pa_signal_done_dylibloader_wrapper_pulse)( void);
+pa_signal_event* (*pa_signal_new_dylibloader_wrapper_pulse)( int, pa_signal_cb_t, void*);
+void (*pa_signal_free_dylibloader_wrapper_pulse)( pa_signal_event*);
+void (*pa_signal_set_destroy_dylibloader_wrapper_pulse)( pa_signal_event*, pa_signal_destroy_cb_t);
+char* (*pa_get_user_name_dylibloader_wrapper_pulse)( char*, size_t);
+char* (*pa_get_host_name_dylibloader_wrapper_pulse)( char*, size_t);
+char* (*pa_get_fqdn_dylibloader_wrapper_pulse)( char*, size_t);
+char* (*pa_get_home_dir_dylibloader_wrapper_pulse)( char*, size_t);
+char* (*pa_get_binary_name_dylibloader_wrapper_pulse)( char*, size_t);
+char* (*pa_path_get_filename_dylibloader_wrapper_pulse)(const char*);
+int (*pa_msleep_dylibloader_wrapper_pulse)( unsigned long);
+int (*pa_thread_make_realtime_dylibloader_wrapper_pulse)( int);
+struct timeval* (*pa_gettimeofday_dylibloader_wrapper_pulse)(struct timeval*);
+pa_usec_t (*pa_timeval_diff_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*);
+int (*pa_timeval_cmp_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*);
+pa_usec_t (*pa_timeval_age_dylibloader_wrapper_pulse)(struct timeval*);
+struct timeval* (*pa_timeval_add_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t);
+struct timeval* (*pa_timeval_sub_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t);
+struct timeval* (*pa_timeval_store_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t);
+pa_usec_t (*pa_timeval_load_dylibloader_wrapper_pulse)(struct timeval*);
+pa_usec_t (*pa_rtclock_now_dylibloader_wrapper_pulse)( void);
+int initialize_pulse(int verbose) {
+ void *handle;
+ char *error;
+ handle = dlopen("libpulse.so.0", RTLD_LAZY);
+ if (!handle) {
+ if (verbose) {
+ fprintf(stderr, "%s\n", dlerror());
+ }
+ return(1);
+ }
+ dlerror();
+// pa_get_library_version
+ *(void **) (&pa_get_library_version_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_library_version");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_bytes_per_second
+ *(void **) (&pa_bytes_per_second_dylibloader_wrapper_pulse) = dlsym(handle, "pa_bytes_per_second");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_frame_size
+ *(void **) (&pa_frame_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_frame_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_size
+ *(void **) (&pa_sample_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_size_of_format
+ *(void **) (&pa_sample_size_of_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_size_of_format");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_bytes_to_usec
+ *(void **) (&pa_bytes_to_usec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_bytes_to_usec");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_usec_to_bytes
+ *(void **) (&pa_usec_to_bytes_dylibloader_wrapper_pulse) = dlsym(handle, "pa_usec_to_bytes");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_spec_init
+ *(void **) (&pa_sample_spec_init_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_spec_init");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_format_valid
+ *(void **) (&pa_sample_format_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_format_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_rate_valid
+ *(void **) (&pa_sample_rate_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_rate_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channels_valid
+ *(void **) (&pa_channels_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channels_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_spec_valid
+ *(void **) (&pa_sample_spec_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_spec_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_spec_equal
+ *(void **) (&pa_sample_spec_equal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_spec_equal");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_format_to_string
+ *(void **) (&pa_sample_format_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_format_to_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_parse_sample_format
+ *(void **) (&pa_parse_sample_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_parse_sample_format");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_spec_snprint
+ *(void **) (&pa_sample_spec_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_spec_snprint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_bytes_snprint
+ *(void **) (&pa_bytes_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_bytes_snprint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_format_is_le
+ *(void **) (&pa_sample_format_is_le_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_format_is_le");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sample_format_is_be
+ *(void **) (&pa_sample_format_is_be_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sample_format_is_be");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_direction_valid
+ *(void **) (&pa_direction_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_direction_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_direction_to_string
+ *(void **) (&pa_direction_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_direction_to_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_api_once
+ *(void **) (&pa_mainloop_api_once_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_api_once");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_new
+ *(void **) (&pa_proplist_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_free
+ *(void **) (&pa_proplist_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_key_valid
+ *(void **) (&pa_proplist_key_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_key_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_sets
+ *(void **) (&pa_proplist_sets_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_sets");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_setp
+ *(void **) (&pa_proplist_setp_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_setp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_setf
+ *(void **) (&pa_proplist_setf_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_setf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_set
+ *(void **) (&pa_proplist_set_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_gets
+ *(void **) (&pa_proplist_gets_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_gets");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_get
+ *(void **) (&pa_proplist_get_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_get");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_update
+ *(void **) (&pa_proplist_update_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_unset
+ *(void **) (&pa_proplist_unset_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_unset");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_unset_many
+ *(void **) (&pa_proplist_unset_many_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_unset_many");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_iterate
+ *(void **) (&pa_proplist_iterate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_iterate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_to_string
+ *(void **) (&pa_proplist_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_to_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_to_string_sep
+ *(void **) (&pa_proplist_to_string_sep_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_to_string_sep");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_from_string
+ *(void **) (&pa_proplist_from_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_from_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_contains
+ *(void **) (&pa_proplist_contains_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_contains");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_clear
+ *(void **) (&pa_proplist_clear_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_clear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_copy
+ *(void **) (&pa_proplist_copy_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_size
+ *(void **) (&pa_proplist_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_isempty
+ *(void **) (&pa_proplist_isempty_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_isempty");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_proplist_equal
+ *(void **) (&pa_proplist_equal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_proplist_equal");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_init
+ *(void **) (&pa_channel_map_init_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_init_mono
+ *(void **) (&pa_channel_map_init_mono_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init_mono");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_init_stereo
+ *(void **) (&pa_channel_map_init_stereo_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init_stereo");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_init_auto
+ *(void **) (&pa_channel_map_init_auto_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init_auto");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_init_extend
+ *(void **) (&pa_channel_map_init_extend_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_init_extend");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_position_to_string
+ *(void **) (&pa_channel_position_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_position_to_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_position_from_string
+ *(void **) (&pa_channel_position_from_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_position_from_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_position_to_pretty_string
+ *(void **) (&pa_channel_position_to_pretty_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_position_to_pretty_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_snprint
+ *(void **) (&pa_channel_map_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_snprint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_parse
+ *(void **) (&pa_channel_map_parse_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_parse");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_equal
+ *(void **) (&pa_channel_map_equal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_equal");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_valid
+ *(void **) (&pa_channel_map_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_compatible
+ *(void **) (&pa_channel_map_compatible_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_compatible");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_superset
+ *(void **) (&pa_channel_map_superset_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_superset");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_can_balance
+ *(void **) (&pa_channel_map_can_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_can_balance");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_can_fade
+ *(void **) (&pa_channel_map_can_fade_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_can_fade");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_can_lfe_balance
+ *(void **) (&pa_channel_map_can_lfe_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_can_lfe_balance");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_to_name
+ *(void **) (&pa_channel_map_to_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_to_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_to_pretty_name
+ *(void **) (&pa_channel_map_to_pretty_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_to_pretty_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_has_position
+ *(void **) (&pa_channel_map_has_position_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_has_position");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_channel_map_mask
+ *(void **) (&pa_channel_map_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_channel_map_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_encoding_to_string
+ *(void **) (&pa_encoding_to_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_encoding_to_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_encoding_from_string
+ *(void **) (&pa_encoding_from_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_encoding_from_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_new
+ *(void **) (&pa_format_info_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_copy
+ *(void **) (&pa_format_info_copy_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_copy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_free
+ *(void **) (&pa_format_info_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_valid
+ *(void **) (&pa_format_info_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_is_pcm
+ *(void **) (&pa_format_info_is_pcm_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_is_pcm");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_is_compatible
+ *(void **) (&pa_format_info_is_compatible_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_is_compatible");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_snprint
+ *(void **) (&pa_format_info_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_snprint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_from_string
+ *(void **) (&pa_format_info_from_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_from_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_from_sample_spec
+ *(void **) (&pa_format_info_from_sample_spec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_from_sample_spec");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_to_sample_spec
+ *(void **) (&pa_format_info_to_sample_spec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_to_sample_spec");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_prop_type
+ *(void **) (&pa_format_info_get_prop_type_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_type");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_prop_int
+ *(void **) (&pa_format_info_get_prop_int_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_int");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_prop_int_range
+ *(void **) (&pa_format_info_get_prop_int_range_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_int_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_prop_int_array
+ *(void **) (&pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_int_array");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_prop_string
+ *(void **) (&pa_format_info_get_prop_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_prop_string_array
+ *(void **) (&pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_prop_string_array");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_free_string_array
+ *(void **) (&pa_format_info_free_string_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_free_string_array");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_sample_format
+ *(void **) (&pa_format_info_get_sample_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_sample_format");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_rate
+ *(void **) (&pa_format_info_get_rate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_rate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_channels
+ *(void **) (&pa_format_info_get_channels_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_get_channel_map
+ *(void **) (&pa_format_info_get_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_channel_map");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_prop_int
+ *(void **) (&pa_format_info_set_prop_int_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_int");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_prop_int_array
+ *(void **) (&pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_int_array");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_prop_int_range
+ *(void **) (&pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_int_range");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_prop_string
+ *(void **) (&pa_format_info_set_prop_string_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_prop_string_array
+ *(void **) (&pa_format_info_set_prop_string_array_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_string_array");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_sample_format
+ *(void **) (&pa_format_info_set_sample_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_sample_format");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_rate
+ *(void **) (&pa_format_info_set_rate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_rate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_channels
+ *(void **) (&pa_format_info_set_channels_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_channels");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_format_info_set_channel_map
+ *(void **) (&pa_format_info_set_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_channel_map");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_operation_ref
+ *(void **) (&pa_operation_ref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_operation_unref
+ *(void **) (&pa_operation_unref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_operation_cancel
+ *(void **) (&pa_operation_cancel_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_cancel");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_operation_get_state
+ *(void **) (&pa_operation_get_state_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_get_state");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_operation_set_state_callback
+ *(void **) (&pa_operation_set_state_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_operation_set_state_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_new
+ *(void **) (&pa_context_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_new_with_proplist
+ *(void **) (&pa_context_new_with_proplist_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_new_with_proplist");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_unref
+ *(void **) (&pa_context_unref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_ref
+ *(void **) (&pa_context_ref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_state_callback
+ *(void **) (&pa_context_set_state_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_state_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_event_callback
+ *(void **) (&pa_context_set_event_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_event_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_errno
+ *(void **) (&pa_context_errno_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_errno");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_is_pending
+ *(void **) (&pa_context_is_pending_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_is_pending");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_state
+ *(void **) (&pa_context_get_state_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_state");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_connect
+ *(void **) (&pa_context_connect_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_connect");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_disconnect
+ *(void **) (&pa_context_disconnect_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_disconnect");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_drain
+ *(void **) (&pa_context_drain_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_drain");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_exit_daemon
+ *(void **) (&pa_context_exit_daemon_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_exit_daemon");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_default_sink
+ *(void **) (&pa_context_set_default_sink_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_default_sink");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_default_source
+ *(void **) (&pa_context_set_default_source_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_default_source");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_is_local
+ *(void **) (&pa_context_is_local_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_is_local");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_name
+ *(void **) (&pa_context_set_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_server
+ *(void **) (&pa_context_get_server_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_server");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_protocol_version
+ *(void **) (&pa_context_get_protocol_version_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_protocol_version");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_server_protocol_version
+ *(void **) (&pa_context_get_server_protocol_version_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_server_protocol_version");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_proplist_update
+ *(void **) (&pa_context_proplist_update_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_proplist_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_proplist_remove
+ *(void **) (&pa_context_proplist_remove_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_proplist_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_index
+ *(void **) (&pa_context_get_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_rttime_new
+ *(void **) (&pa_context_rttime_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_rttime_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_rttime_restart
+ *(void **) (&pa_context_rttime_restart_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_rttime_restart");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_tile_size
+ *(void **) (&pa_context_get_tile_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_tile_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_load_cookie_from_file
+ *(void **) (&pa_context_load_cookie_from_file_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_load_cookie_from_file");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_equal
+ *(void **) (&pa_cvolume_equal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_equal");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_init
+ *(void **) (&pa_cvolume_init_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_init");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_set
+ *(void **) (&pa_cvolume_set_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_snprint
+ *(void **) (&pa_cvolume_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_snprint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_cvolume_snprint_dB
+ *(void **) (&pa_sw_cvolume_snprint_dB_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_snprint_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_snprint_verbose
+ *(void **) (&pa_cvolume_snprint_verbose_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_snprint_verbose");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_volume_snprint
+ *(void **) (&pa_volume_snprint_dylibloader_wrapper_pulse) = dlsym(handle, "pa_volume_snprint");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_volume_snprint_dB
+ *(void **) (&pa_sw_volume_snprint_dB_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_snprint_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_volume_snprint_verbose
+ *(void **) (&pa_volume_snprint_verbose_dylibloader_wrapper_pulse) = dlsym(handle, "pa_volume_snprint_verbose");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_avg
+ *(void **) (&pa_cvolume_avg_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_avg");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_avg_mask
+ *(void **) (&pa_cvolume_avg_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_avg_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_max
+ *(void **) (&pa_cvolume_max_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_max");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_max_mask
+ *(void **) (&pa_cvolume_max_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_max_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_min
+ *(void **) (&pa_cvolume_min_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_min");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_min_mask
+ *(void **) (&pa_cvolume_min_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_min_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_valid
+ *(void **) (&pa_cvolume_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_channels_equal_to
+ *(void **) (&pa_cvolume_channels_equal_to_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_channels_equal_to");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_volume_multiply
+ *(void **) (&pa_sw_volume_multiply_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_multiply");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_cvolume_multiply
+ *(void **) (&pa_sw_cvolume_multiply_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_multiply");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_cvolume_multiply_scalar
+ *(void **) (&pa_sw_cvolume_multiply_scalar_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_multiply_scalar");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_volume_divide
+ *(void **) (&pa_sw_volume_divide_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_divide");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_cvolume_divide
+ *(void **) (&pa_sw_cvolume_divide_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_divide");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_cvolume_divide_scalar
+ *(void **) (&pa_sw_cvolume_divide_scalar_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_cvolume_divide_scalar");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_volume_from_dB
+ *(void **) (&pa_sw_volume_from_dB_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_from_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_volume_to_dB
+ *(void **) (&pa_sw_volume_to_dB_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_to_dB");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_volume_from_linear
+ *(void **) (&pa_sw_volume_from_linear_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_from_linear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_sw_volume_to_linear
+ *(void **) (&pa_sw_volume_to_linear_dylibloader_wrapper_pulse) = dlsym(handle, "pa_sw_volume_to_linear");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_remap
+ *(void **) (&pa_cvolume_remap_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_remap");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_compatible
+ *(void **) (&pa_cvolume_compatible_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_compatible");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_compatible_with_channel_map
+ *(void **) (&pa_cvolume_compatible_with_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_compatible_with_channel_map");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_get_balance
+ *(void **) (&pa_cvolume_get_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_get_balance");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_set_balance
+ *(void **) (&pa_cvolume_set_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set_balance");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_get_fade
+ *(void **) (&pa_cvolume_get_fade_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_get_fade");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_set_fade
+ *(void **) (&pa_cvolume_set_fade_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set_fade");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_get_lfe_balance
+ *(void **) (&pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_get_lfe_balance");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_set_lfe_balance
+ *(void **) (&pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set_lfe_balance");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_scale
+ *(void **) (&pa_cvolume_scale_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_scale");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_scale_mask
+ *(void **) (&pa_cvolume_scale_mask_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_scale_mask");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_set_position
+ *(void **) (&pa_cvolume_set_position_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_set_position");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_get_position
+ *(void **) (&pa_cvolume_get_position_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_get_position");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_merge
+ *(void **) (&pa_cvolume_merge_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_merge");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_inc_clamp
+ *(void **) (&pa_cvolume_inc_clamp_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_inc_clamp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_inc
+ *(void **) (&pa_cvolume_inc_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_inc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_cvolume_dec
+ *(void **) (&pa_cvolume_dec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_cvolume_dec");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_new
+ *(void **) (&pa_stream_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_new_with_proplist
+ *(void **) (&pa_stream_new_with_proplist_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_new_with_proplist");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_new_extended
+ *(void **) (&pa_stream_new_extended_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_new_extended");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_unref
+ *(void **) (&pa_stream_unref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_ref
+ *(void **) (&pa_stream_ref_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_state
+ *(void **) (&pa_stream_get_state_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_state");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_context
+ *(void **) (&pa_stream_get_context_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_context");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_index
+ *(void **) (&pa_stream_get_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_device_index
+ *(void **) (&pa_stream_get_device_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_device_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_device_name
+ *(void **) (&pa_stream_get_device_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_device_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_is_suspended
+ *(void **) (&pa_stream_is_suspended_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_is_suspended");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_is_corked
+ *(void **) (&pa_stream_is_corked_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_is_corked");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_connect_playback
+ *(void **) (&pa_stream_connect_playback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_connect_playback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_connect_record
+ *(void **) (&pa_stream_connect_record_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_connect_record");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_disconnect
+ *(void **) (&pa_stream_disconnect_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_disconnect");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_begin_write
+ *(void **) (&pa_stream_begin_write_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_begin_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_cancel_write
+ *(void **) (&pa_stream_cancel_write_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_cancel_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_write
+ *(void **) (&pa_stream_write_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_write");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_write_ext_free
+ *(void **) (&pa_stream_write_ext_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_write_ext_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_peek
+ *(void **) (&pa_stream_peek_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_peek");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_drop
+ *(void **) (&pa_stream_drop_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_drop");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_writable_size
+ *(void **) (&pa_stream_writable_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_writable_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_readable_size
+ *(void **) (&pa_stream_readable_size_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_readable_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_drain
+ *(void **) (&pa_stream_drain_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_drain");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_update_timing_info
+ *(void **) (&pa_stream_update_timing_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_update_timing_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_state_callback
+ *(void **) (&pa_stream_set_state_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_state_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_write_callback
+ *(void **) (&pa_stream_set_write_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_write_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_read_callback
+ *(void **) (&pa_stream_set_read_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_read_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_overflow_callback
+ *(void **) (&pa_stream_set_overflow_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_overflow_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_underflow_index
+ *(void **) (&pa_stream_get_underflow_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_underflow_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_underflow_callback
+ *(void **) (&pa_stream_set_underflow_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_underflow_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_started_callback
+ *(void **) (&pa_stream_set_started_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_started_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_latency_update_callback
+ *(void **) (&pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_latency_update_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_moved_callback
+ *(void **) (&pa_stream_set_moved_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_moved_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_suspended_callback
+ *(void **) (&pa_stream_set_suspended_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_suspended_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_event_callback
+ *(void **) (&pa_stream_set_event_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_event_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_buffer_attr_callback
+ *(void **) (&pa_stream_set_buffer_attr_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_buffer_attr_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_cork
+ *(void **) (&pa_stream_cork_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_cork");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_flush
+ *(void **) (&pa_stream_flush_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_flush");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_prebuf
+ *(void **) (&pa_stream_prebuf_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_prebuf");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_trigger
+ *(void **) (&pa_stream_trigger_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_trigger");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_name
+ *(void **) (&pa_stream_set_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_time
+ *(void **) (&pa_stream_get_time_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_time");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_latency
+ *(void **) (&pa_stream_get_latency_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_latency");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_timing_info
+ *(void **) (&pa_stream_get_timing_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_timing_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_sample_spec
+ *(void **) (&pa_stream_get_sample_spec_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_sample_spec");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_channel_map
+ *(void **) (&pa_stream_get_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_channel_map");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_format_info
+ *(void **) (&pa_stream_get_format_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_format_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_buffer_attr
+ *(void **) (&pa_stream_get_buffer_attr_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_buffer_attr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_buffer_attr
+ *(void **) (&pa_stream_set_buffer_attr_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_buffer_attr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_update_sample_rate
+ *(void **) (&pa_stream_update_sample_rate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_update_sample_rate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_proplist_update
+ *(void **) (&pa_stream_proplist_update_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_proplist_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_proplist_remove
+ *(void **) (&pa_stream_proplist_remove_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_proplist_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_set_monitor_stream
+ *(void **) (&pa_stream_set_monitor_stream_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_set_monitor_stream");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_get_monitor_stream
+ *(void **) (&pa_stream_get_monitor_stream_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_get_monitor_stream");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_sink_info_by_name
+ *(void **) (&pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_info_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_sink_info_by_index
+ *(void **) (&pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_info_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_sink_info_list
+ *(void **) (&pa_context_get_sink_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_sink_volume_by_index
+ *(void **) (&pa_context_set_sink_volume_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_volume_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_sink_volume_by_name
+ *(void **) (&pa_context_set_sink_volume_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_volume_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_sink_mute_by_index
+ *(void **) (&pa_context_set_sink_mute_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_mute_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_sink_mute_by_name
+ *(void **) (&pa_context_set_sink_mute_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_mute_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_suspend_sink_by_name
+ *(void **) (&pa_context_suspend_sink_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_suspend_sink_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_suspend_sink_by_index
+ *(void **) (&pa_context_suspend_sink_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_suspend_sink_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_sink_port_by_index
+ *(void **) (&pa_context_set_sink_port_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_port_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_sink_port_by_name
+ *(void **) (&pa_context_set_sink_port_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_port_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_source_info_by_name
+ *(void **) (&pa_context_get_source_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_info_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_source_info_by_index
+ *(void **) (&pa_context_get_source_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_info_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_source_info_list
+ *(void **) (&pa_context_get_source_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_source_volume_by_index
+ *(void **) (&pa_context_set_source_volume_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_volume_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_source_volume_by_name
+ *(void **) (&pa_context_set_source_volume_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_volume_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_source_mute_by_index
+ *(void **) (&pa_context_set_source_mute_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_mute_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_source_mute_by_name
+ *(void **) (&pa_context_set_source_mute_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_mute_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_suspend_source_by_name
+ *(void **) (&pa_context_suspend_source_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_suspend_source_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_suspend_source_by_index
+ *(void **) (&pa_context_suspend_source_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_suspend_source_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_source_port_by_index
+ *(void **) (&pa_context_set_source_port_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_port_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_source_port_by_name
+ *(void **) (&pa_context_set_source_port_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_port_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_server_info
+ *(void **) (&pa_context_get_server_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_server_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_module_info
+ *(void **) (&pa_context_get_module_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_module_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_module_info_list
+ *(void **) (&pa_context_get_module_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_module_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_load_module
+ *(void **) (&pa_context_load_module_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_load_module");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_unload_module
+ *(void **) (&pa_context_unload_module_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_unload_module");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_client_info
+ *(void **) (&pa_context_get_client_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_client_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_client_info_list
+ *(void **) (&pa_context_get_client_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_client_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_kill_client
+ *(void **) (&pa_context_kill_client_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_kill_client");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_card_info_by_index
+ *(void **) (&pa_context_get_card_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_card_info_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_card_info_by_name
+ *(void **) (&pa_context_get_card_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_card_info_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_card_info_list
+ *(void **) (&pa_context_get_card_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_card_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_card_profile_by_index
+ *(void **) (&pa_context_set_card_profile_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_card_profile_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_card_profile_by_name
+ *(void **) (&pa_context_set_card_profile_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_card_profile_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_port_latency_offset
+ *(void **) (&pa_context_set_port_latency_offset_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_port_latency_offset");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_sink_input_info
+ *(void **) (&pa_context_get_sink_input_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_input_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_sink_input_info_list
+ *(void **) (&pa_context_get_sink_input_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sink_input_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_move_sink_input_by_name
+ *(void **) (&pa_context_move_sink_input_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_move_sink_input_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_move_sink_input_by_index
+ *(void **) (&pa_context_move_sink_input_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_move_sink_input_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_sink_input_volume
+ *(void **) (&pa_context_set_sink_input_volume_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_input_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_sink_input_mute
+ *(void **) (&pa_context_set_sink_input_mute_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_sink_input_mute");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_kill_sink_input
+ *(void **) (&pa_context_kill_sink_input_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_kill_sink_input");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_source_output_info
+ *(void **) (&pa_context_get_source_output_info_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_output_info");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_source_output_info_list
+ *(void **) (&pa_context_get_source_output_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_source_output_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_move_source_output_by_name
+ *(void **) (&pa_context_move_source_output_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_move_source_output_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_move_source_output_by_index
+ *(void **) (&pa_context_move_source_output_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_move_source_output_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_source_output_volume
+ *(void **) (&pa_context_set_source_output_volume_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_output_volume");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_source_output_mute
+ *(void **) (&pa_context_set_source_output_mute_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_source_output_mute");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_kill_source_output
+ *(void **) (&pa_context_kill_source_output_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_kill_source_output");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_stat
+ *(void **) (&pa_context_stat_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_stat");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_sample_info_by_name
+ *(void **) (&pa_context_get_sample_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sample_info_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_sample_info_by_index
+ *(void **) (&pa_context_get_sample_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sample_info_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_sample_info_list
+ *(void **) (&pa_context_get_sample_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_sample_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_autoload_info_by_name
+ *(void **) (&pa_context_get_autoload_info_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_autoload_info_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_autoload_info_by_index
+ *(void **) (&pa_context_get_autoload_info_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_autoload_info_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_get_autoload_info_list
+ *(void **) (&pa_context_get_autoload_info_list_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_get_autoload_info_list");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_add_autoload
+ *(void **) (&pa_context_add_autoload_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_add_autoload");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_remove_autoload_by_name
+ *(void **) (&pa_context_remove_autoload_by_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_remove_autoload_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_remove_autoload_by_index
+ *(void **) (&pa_context_remove_autoload_by_index_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_remove_autoload_by_index");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_subscribe
+ *(void **) (&pa_context_subscribe_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_subscribe");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_set_subscribe_callback
+ *(void **) (&pa_context_set_subscribe_callback_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_set_subscribe_callback");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_connect_upload
+ *(void **) (&pa_stream_connect_upload_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_connect_upload");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_stream_finish_upload
+ *(void **) (&pa_stream_finish_upload_dylibloader_wrapper_pulse) = dlsym(handle, "pa_stream_finish_upload");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_remove_sample
+ *(void **) (&pa_context_remove_sample_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_remove_sample");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_play_sample
+ *(void **) (&pa_context_play_sample_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_play_sample");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_context_play_sample_with_proplist
+ *(void **) (&pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse) = dlsym(handle, "pa_context_play_sample_with_proplist");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_strerror
+ *(void **) (&pa_strerror_dylibloader_wrapper_pulse) = dlsym(handle, "pa_strerror");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_xmalloc
+ *(void **) (&pa_xmalloc_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xmalloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_xmalloc0
+ *(void **) (&pa_xmalloc0_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xmalloc0");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_xrealloc
+ *(void **) (&pa_xrealloc_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xrealloc");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_xfree
+ *(void **) (&pa_xfree_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xfree");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_xstrdup
+ *(void **) (&pa_xstrdup_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xstrdup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_xstrndup
+ *(void **) (&pa_xstrndup_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xstrndup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_xmemdup
+ *(void **) (&pa_xmemdup_dylibloader_wrapper_pulse) = dlsym(handle, "pa_xmemdup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_utf8_valid
+ *(void **) (&pa_utf8_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_utf8_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_ascii_valid
+ *(void **) (&pa_ascii_valid_dylibloader_wrapper_pulse) = dlsym(handle, "pa_ascii_valid");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_utf8_filter
+ *(void **) (&pa_utf8_filter_dylibloader_wrapper_pulse) = dlsym(handle, "pa_utf8_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_ascii_filter
+ *(void **) (&pa_ascii_filter_dylibloader_wrapper_pulse) = dlsym(handle, "pa_ascii_filter");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_utf8_to_locale
+ *(void **) (&pa_utf8_to_locale_dylibloader_wrapper_pulse) = dlsym(handle, "pa_utf8_to_locale");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_locale_to_utf8
+ *(void **) (&pa_locale_to_utf8_dylibloader_wrapper_pulse) = dlsym(handle, "pa_locale_to_utf8");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_new
+ *(void **) (&pa_threaded_mainloop_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_free
+ *(void **) (&pa_threaded_mainloop_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_start
+ *(void **) (&pa_threaded_mainloop_start_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_start");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_stop
+ *(void **) (&pa_threaded_mainloop_stop_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_stop");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_lock
+ *(void **) (&pa_threaded_mainloop_lock_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_lock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_unlock
+ *(void **) (&pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_unlock");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_wait
+ *(void **) (&pa_threaded_mainloop_wait_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_wait");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_signal
+ *(void **) (&pa_threaded_mainloop_signal_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_signal");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_accept
+ *(void **) (&pa_threaded_mainloop_accept_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_accept");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_get_retval
+ *(void **) (&pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_get_retval");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_get_api
+ *(void **) (&pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_get_api");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_in_thread
+ *(void **) (&pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_in_thread");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_set_name
+ *(void **) (&pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_set_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_threaded_mainloop_once_unlocked
+ *(void **) (&pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_once_unlocked");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_new
+ *(void **) (&pa_mainloop_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_free
+ *(void **) (&pa_mainloop_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_prepare
+ *(void **) (&pa_mainloop_prepare_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_prepare");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_poll
+ *(void **) (&pa_mainloop_poll_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_poll");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_dispatch
+ *(void **) (&pa_mainloop_dispatch_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_dispatch");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_get_retval
+ *(void **) (&pa_mainloop_get_retval_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_get_retval");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_iterate
+ *(void **) (&pa_mainloop_iterate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_iterate");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_run
+ *(void **) (&pa_mainloop_run_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_run");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_get_api
+ *(void **) (&pa_mainloop_get_api_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_get_api");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_quit
+ *(void **) (&pa_mainloop_quit_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_quit");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_wakeup
+ *(void **) (&pa_mainloop_wakeup_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_wakeup");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_mainloop_set_poll_func
+ *(void **) (&pa_mainloop_set_poll_func_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_set_poll_func");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_signal_init
+ *(void **) (&pa_signal_init_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_init");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_signal_done
+ *(void **) (&pa_signal_done_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_done");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_signal_new
+ *(void **) (&pa_signal_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_signal_free
+ *(void **) (&pa_signal_free_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_free");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_signal_set_destroy
+ *(void **) (&pa_signal_set_destroy_dylibloader_wrapper_pulse) = dlsym(handle, "pa_signal_set_destroy");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_get_user_name
+ *(void **) (&pa_get_user_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_user_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_get_host_name
+ *(void **) (&pa_get_host_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_host_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_get_fqdn
+ *(void **) (&pa_get_fqdn_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_fqdn");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_get_home_dir
+ *(void **) (&pa_get_home_dir_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_home_dir");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_get_binary_name
+ *(void **) (&pa_get_binary_name_dylibloader_wrapper_pulse) = dlsym(handle, "pa_get_binary_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_path_get_filename
+ *(void **) (&pa_path_get_filename_dylibloader_wrapper_pulse) = dlsym(handle, "pa_path_get_filename");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_msleep
+ *(void **) (&pa_msleep_dylibloader_wrapper_pulse) = dlsym(handle, "pa_msleep");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_thread_make_realtime
+ *(void **) (&pa_thread_make_realtime_dylibloader_wrapper_pulse) = dlsym(handle, "pa_thread_make_realtime");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_gettimeofday
+ *(void **) (&pa_gettimeofday_dylibloader_wrapper_pulse) = dlsym(handle, "pa_gettimeofday");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_timeval_diff
+ *(void **) (&pa_timeval_diff_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_diff");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_timeval_cmp
+ *(void **) (&pa_timeval_cmp_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_cmp");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_timeval_age
+ *(void **) (&pa_timeval_age_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_age");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_timeval_add
+ *(void **) (&pa_timeval_add_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_add");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_timeval_sub
+ *(void **) (&pa_timeval_sub_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_sub");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_timeval_store
+ *(void **) (&pa_timeval_store_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_store");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_timeval_load
+ *(void **) (&pa_timeval_load_dylibloader_wrapper_pulse) = dlsym(handle, "pa_timeval_load");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// pa_rtclock_now
+ *(void **) (&pa_rtclock_now_dylibloader_wrapper_pulse) = dlsym(handle, "pa_rtclock_now");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+return 0;
+}
diff --git a/drivers/pulseaudio/pulse-so_wrap.h b/drivers/pulseaudio/pulse-so_wrap.h
new file mode 100644
index 0000000000..7f9a70fae1
--- /dev/null
+++ b/drivers/pulseaudio/pulse-so_wrap.h
@@ -0,0 +1,1446 @@
+#ifndef DYLIBLOAD_WRAPPER_PULSE
+#define DYLIBLOAD_WRAPPER_PULSE
+// This file is generated. Do not edit!
+// see https://github.com/hpvb/dynload-wrapper for details
+// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:31
+// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include <pulse/pulseaudio.h> --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse-so_wrap.h --output-implementation pulse-so_wrap.c
+//
+#include <stdint.h>
+
+#define pa_get_library_version pa_get_library_version_dylibloader_orig_pulse
+#define pa_bytes_per_second pa_bytes_per_second_dylibloader_orig_pulse
+#define pa_frame_size pa_frame_size_dylibloader_orig_pulse
+#define pa_sample_size pa_sample_size_dylibloader_orig_pulse
+#define pa_sample_size_of_format pa_sample_size_of_format_dylibloader_orig_pulse
+#define pa_bytes_to_usec pa_bytes_to_usec_dylibloader_orig_pulse
+#define pa_usec_to_bytes pa_usec_to_bytes_dylibloader_orig_pulse
+#define pa_sample_spec_init pa_sample_spec_init_dylibloader_orig_pulse
+#define pa_sample_format_valid pa_sample_format_valid_dylibloader_orig_pulse
+#define pa_sample_rate_valid pa_sample_rate_valid_dylibloader_orig_pulse
+#define pa_channels_valid pa_channels_valid_dylibloader_orig_pulse
+#define pa_sample_spec_valid pa_sample_spec_valid_dylibloader_orig_pulse
+#define pa_sample_spec_equal pa_sample_spec_equal_dylibloader_orig_pulse
+#define pa_sample_format_to_string pa_sample_format_to_string_dylibloader_orig_pulse
+#define pa_parse_sample_format pa_parse_sample_format_dylibloader_orig_pulse
+#define pa_sample_spec_snprint pa_sample_spec_snprint_dylibloader_orig_pulse
+#define pa_bytes_snprint pa_bytes_snprint_dylibloader_orig_pulse
+#define pa_sample_format_is_le pa_sample_format_is_le_dylibloader_orig_pulse
+#define pa_sample_format_is_be pa_sample_format_is_be_dylibloader_orig_pulse
+#define pa_direction_valid pa_direction_valid_dylibloader_orig_pulse
+#define pa_direction_to_string pa_direction_to_string_dylibloader_orig_pulse
+#define pa_mainloop_api_once pa_mainloop_api_once_dylibloader_orig_pulse
+#define pa_proplist_new pa_proplist_new_dylibloader_orig_pulse
+#define pa_proplist_free pa_proplist_free_dylibloader_orig_pulse
+#define pa_proplist_key_valid pa_proplist_key_valid_dylibloader_orig_pulse
+#define pa_proplist_sets pa_proplist_sets_dylibloader_orig_pulse
+#define pa_proplist_setp pa_proplist_setp_dylibloader_orig_pulse
+#define pa_proplist_setf pa_proplist_setf_dylibloader_orig_pulse
+#define pa_proplist_set pa_proplist_set_dylibloader_orig_pulse
+#define pa_proplist_gets pa_proplist_gets_dylibloader_orig_pulse
+#define pa_proplist_get pa_proplist_get_dylibloader_orig_pulse
+#define pa_proplist_update pa_proplist_update_dylibloader_orig_pulse
+#define pa_proplist_unset pa_proplist_unset_dylibloader_orig_pulse
+#define pa_proplist_unset_many pa_proplist_unset_many_dylibloader_orig_pulse
+#define pa_proplist_iterate pa_proplist_iterate_dylibloader_orig_pulse
+#define pa_proplist_to_string pa_proplist_to_string_dylibloader_orig_pulse
+#define pa_proplist_to_string_sep pa_proplist_to_string_sep_dylibloader_orig_pulse
+#define pa_proplist_from_string pa_proplist_from_string_dylibloader_orig_pulse
+#define pa_proplist_contains pa_proplist_contains_dylibloader_orig_pulse
+#define pa_proplist_clear pa_proplist_clear_dylibloader_orig_pulse
+#define pa_proplist_copy pa_proplist_copy_dylibloader_orig_pulse
+#define pa_proplist_size pa_proplist_size_dylibloader_orig_pulse
+#define pa_proplist_isempty pa_proplist_isempty_dylibloader_orig_pulse
+#define pa_proplist_equal pa_proplist_equal_dylibloader_orig_pulse
+#define pa_channel_map_init pa_channel_map_init_dylibloader_orig_pulse
+#define pa_channel_map_init_mono pa_channel_map_init_mono_dylibloader_orig_pulse
+#define pa_channel_map_init_stereo pa_channel_map_init_stereo_dylibloader_orig_pulse
+#define pa_channel_map_init_auto pa_channel_map_init_auto_dylibloader_orig_pulse
+#define pa_channel_map_init_extend pa_channel_map_init_extend_dylibloader_orig_pulse
+#define pa_channel_position_to_string pa_channel_position_to_string_dylibloader_orig_pulse
+#define pa_channel_position_from_string pa_channel_position_from_string_dylibloader_orig_pulse
+#define pa_channel_position_to_pretty_string pa_channel_position_to_pretty_string_dylibloader_orig_pulse
+#define pa_channel_map_snprint pa_channel_map_snprint_dylibloader_orig_pulse
+#define pa_channel_map_parse pa_channel_map_parse_dylibloader_orig_pulse
+#define pa_channel_map_equal pa_channel_map_equal_dylibloader_orig_pulse
+#define pa_channel_map_valid pa_channel_map_valid_dylibloader_orig_pulse
+#define pa_channel_map_compatible pa_channel_map_compatible_dylibloader_orig_pulse
+#define pa_channel_map_superset pa_channel_map_superset_dylibloader_orig_pulse
+#define pa_channel_map_can_balance pa_channel_map_can_balance_dylibloader_orig_pulse
+#define pa_channel_map_can_fade pa_channel_map_can_fade_dylibloader_orig_pulse
+#define pa_channel_map_can_lfe_balance pa_channel_map_can_lfe_balance_dylibloader_orig_pulse
+#define pa_channel_map_to_name pa_channel_map_to_name_dylibloader_orig_pulse
+#define pa_channel_map_to_pretty_name pa_channel_map_to_pretty_name_dylibloader_orig_pulse
+#define pa_channel_map_has_position pa_channel_map_has_position_dylibloader_orig_pulse
+#define pa_channel_map_mask pa_channel_map_mask_dylibloader_orig_pulse
+#define pa_encoding_to_string pa_encoding_to_string_dylibloader_orig_pulse
+#define pa_encoding_from_string pa_encoding_from_string_dylibloader_orig_pulse
+#define pa_format_info_new pa_format_info_new_dylibloader_orig_pulse
+#define pa_format_info_copy pa_format_info_copy_dylibloader_orig_pulse
+#define pa_format_info_free pa_format_info_free_dylibloader_orig_pulse
+#define pa_format_info_valid pa_format_info_valid_dylibloader_orig_pulse
+#define pa_format_info_is_pcm pa_format_info_is_pcm_dylibloader_orig_pulse
+#define pa_format_info_is_compatible pa_format_info_is_compatible_dylibloader_orig_pulse
+#define pa_format_info_snprint pa_format_info_snprint_dylibloader_orig_pulse
+#define pa_format_info_from_string pa_format_info_from_string_dylibloader_orig_pulse
+#define pa_format_info_from_sample_spec pa_format_info_from_sample_spec_dylibloader_orig_pulse
+#define pa_format_info_to_sample_spec pa_format_info_to_sample_spec_dylibloader_orig_pulse
+#define pa_format_info_get_prop_type pa_format_info_get_prop_type_dylibloader_orig_pulse
+#define pa_format_info_get_prop_int pa_format_info_get_prop_int_dylibloader_orig_pulse
+#define pa_format_info_get_prop_int_range pa_format_info_get_prop_int_range_dylibloader_orig_pulse
+#define pa_format_info_get_prop_int_array pa_format_info_get_prop_int_array_dylibloader_orig_pulse
+#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_orig_pulse
+#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_orig_pulse
+#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_orig_pulse
+#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_orig_pulse
+#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_orig_pulse
+#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_orig_pulse
+#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_orig_pulse
+#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_orig_pulse
+#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_orig_pulse
+#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_orig_pulse
+#define pa_format_info_set_prop_string pa_format_info_set_prop_string_dylibloader_orig_pulse
+#define pa_format_info_set_prop_string_array pa_format_info_set_prop_string_array_dylibloader_orig_pulse
+#define pa_format_info_set_sample_format pa_format_info_set_sample_format_dylibloader_orig_pulse
+#define pa_format_info_set_rate pa_format_info_set_rate_dylibloader_orig_pulse
+#define pa_format_info_set_channels pa_format_info_set_channels_dylibloader_orig_pulse
+#define pa_format_info_set_channel_map pa_format_info_set_channel_map_dylibloader_orig_pulse
+#define pa_operation_ref pa_operation_ref_dylibloader_orig_pulse
+#define pa_operation_unref pa_operation_unref_dylibloader_orig_pulse
+#define pa_operation_cancel pa_operation_cancel_dylibloader_orig_pulse
+#define pa_operation_get_state pa_operation_get_state_dylibloader_orig_pulse
+#define pa_operation_set_state_callback pa_operation_set_state_callback_dylibloader_orig_pulse
+#define pa_context_new pa_context_new_dylibloader_orig_pulse
+#define pa_context_new_with_proplist pa_context_new_with_proplist_dylibloader_orig_pulse
+#define pa_context_unref pa_context_unref_dylibloader_orig_pulse
+#define pa_context_ref pa_context_ref_dylibloader_orig_pulse
+#define pa_context_set_state_callback pa_context_set_state_callback_dylibloader_orig_pulse
+#define pa_context_set_event_callback pa_context_set_event_callback_dylibloader_orig_pulse
+#define pa_context_errno pa_context_errno_dylibloader_orig_pulse
+#define pa_context_is_pending pa_context_is_pending_dylibloader_orig_pulse
+#define pa_context_get_state pa_context_get_state_dylibloader_orig_pulse
+#define pa_context_connect pa_context_connect_dylibloader_orig_pulse
+#define pa_context_disconnect pa_context_disconnect_dylibloader_orig_pulse
+#define pa_context_drain pa_context_drain_dylibloader_orig_pulse
+#define pa_context_exit_daemon pa_context_exit_daemon_dylibloader_orig_pulse
+#define pa_context_set_default_sink pa_context_set_default_sink_dylibloader_orig_pulse
+#define pa_context_set_default_source pa_context_set_default_source_dylibloader_orig_pulse
+#define pa_context_is_local pa_context_is_local_dylibloader_orig_pulse
+#define pa_context_set_name pa_context_set_name_dylibloader_orig_pulse
+#define pa_context_get_server pa_context_get_server_dylibloader_orig_pulse
+#define pa_context_get_protocol_version pa_context_get_protocol_version_dylibloader_orig_pulse
+#define pa_context_get_server_protocol_version pa_context_get_server_protocol_version_dylibloader_orig_pulse
+#define pa_context_proplist_update pa_context_proplist_update_dylibloader_orig_pulse
+#define pa_context_proplist_remove pa_context_proplist_remove_dylibloader_orig_pulse
+#define pa_context_get_index pa_context_get_index_dylibloader_orig_pulse
+#define pa_context_rttime_new pa_context_rttime_new_dylibloader_orig_pulse
+#define pa_context_rttime_restart pa_context_rttime_restart_dylibloader_orig_pulse
+#define pa_context_get_tile_size pa_context_get_tile_size_dylibloader_orig_pulse
+#define pa_context_load_cookie_from_file pa_context_load_cookie_from_file_dylibloader_orig_pulse
+#define pa_cvolume_equal pa_cvolume_equal_dylibloader_orig_pulse
+#define pa_cvolume_init pa_cvolume_init_dylibloader_orig_pulse
+#define pa_cvolume_set pa_cvolume_set_dylibloader_orig_pulse
+#define pa_cvolume_snprint pa_cvolume_snprint_dylibloader_orig_pulse
+#define pa_sw_cvolume_snprint_dB pa_sw_cvolume_snprint_dB_dylibloader_orig_pulse
+#define pa_cvolume_snprint_verbose pa_cvolume_snprint_verbose_dylibloader_orig_pulse
+#define pa_volume_snprint pa_volume_snprint_dylibloader_orig_pulse
+#define pa_sw_volume_snprint_dB pa_sw_volume_snprint_dB_dylibloader_orig_pulse
+#define pa_volume_snprint_verbose pa_volume_snprint_verbose_dylibloader_orig_pulse
+#define pa_cvolume_avg pa_cvolume_avg_dylibloader_orig_pulse
+#define pa_cvolume_avg_mask pa_cvolume_avg_mask_dylibloader_orig_pulse
+#define pa_cvolume_max pa_cvolume_max_dylibloader_orig_pulse
+#define pa_cvolume_max_mask pa_cvolume_max_mask_dylibloader_orig_pulse
+#define pa_cvolume_min pa_cvolume_min_dylibloader_orig_pulse
+#define pa_cvolume_min_mask pa_cvolume_min_mask_dylibloader_orig_pulse
+#define pa_cvolume_valid pa_cvolume_valid_dylibloader_orig_pulse
+#define pa_cvolume_channels_equal_to pa_cvolume_channels_equal_to_dylibloader_orig_pulse
+#define pa_sw_volume_multiply pa_sw_volume_multiply_dylibloader_orig_pulse
+#define pa_sw_cvolume_multiply pa_sw_cvolume_multiply_dylibloader_orig_pulse
+#define pa_sw_cvolume_multiply_scalar pa_sw_cvolume_multiply_scalar_dylibloader_orig_pulse
+#define pa_sw_volume_divide pa_sw_volume_divide_dylibloader_orig_pulse
+#define pa_sw_cvolume_divide pa_sw_cvolume_divide_dylibloader_orig_pulse
+#define pa_sw_cvolume_divide_scalar pa_sw_cvolume_divide_scalar_dylibloader_orig_pulse
+#define pa_sw_volume_from_dB pa_sw_volume_from_dB_dylibloader_orig_pulse
+#define pa_sw_volume_to_dB pa_sw_volume_to_dB_dylibloader_orig_pulse
+#define pa_sw_volume_from_linear pa_sw_volume_from_linear_dylibloader_orig_pulse
+#define pa_sw_volume_to_linear pa_sw_volume_to_linear_dylibloader_orig_pulse
+#define pa_cvolume_remap pa_cvolume_remap_dylibloader_orig_pulse
+#define pa_cvolume_compatible pa_cvolume_compatible_dylibloader_orig_pulse
+#define pa_cvolume_compatible_with_channel_map pa_cvolume_compatible_with_channel_map_dylibloader_orig_pulse
+#define pa_cvolume_get_balance pa_cvolume_get_balance_dylibloader_orig_pulse
+#define pa_cvolume_set_balance pa_cvolume_set_balance_dylibloader_orig_pulse
+#define pa_cvolume_get_fade pa_cvolume_get_fade_dylibloader_orig_pulse
+#define pa_cvolume_set_fade pa_cvolume_set_fade_dylibloader_orig_pulse
+#define pa_cvolume_get_lfe_balance pa_cvolume_get_lfe_balance_dylibloader_orig_pulse
+#define pa_cvolume_set_lfe_balance pa_cvolume_set_lfe_balance_dylibloader_orig_pulse
+#define pa_cvolume_scale pa_cvolume_scale_dylibloader_orig_pulse
+#define pa_cvolume_scale_mask pa_cvolume_scale_mask_dylibloader_orig_pulse
+#define pa_cvolume_set_position pa_cvolume_set_position_dylibloader_orig_pulse
+#define pa_cvolume_get_position pa_cvolume_get_position_dylibloader_orig_pulse
+#define pa_cvolume_merge pa_cvolume_merge_dylibloader_orig_pulse
+#define pa_cvolume_inc_clamp pa_cvolume_inc_clamp_dylibloader_orig_pulse
+#define pa_cvolume_inc pa_cvolume_inc_dylibloader_orig_pulse
+#define pa_cvolume_dec pa_cvolume_dec_dylibloader_orig_pulse
+#define pa_stream_new pa_stream_new_dylibloader_orig_pulse
+#define pa_stream_new_with_proplist pa_stream_new_with_proplist_dylibloader_orig_pulse
+#define pa_stream_new_extended pa_stream_new_extended_dylibloader_orig_pulse
+#define pa_stream_unref pa_stream_unref_dylibloader_orig_pulse
+#define pa_stream_ref pa_stream_ref_dylibloader_orig_pulse
+#define pa_stream_get_state pa_stream_get_state_dylibloader_orig_pulse
+#define pa_stream_get_context pa_stream_get_context_dylibloader_orig_pulse
+#define pa_stream_get_index pa_stream_get_index_dylibloader_orig_pulse
+#define pa_stream_get_device_index pa_stream_get_device_index_dylibloader_orig_pulse
+#define pa_stream_get_device_name pa_stream_get_device_name_dylibloader_orig_pulse
+#define pa_stream_is_suspended pa_stream_is_suspended_dylibloader_orig_pulse
+#define pa_stream_is_corked pa_stream_is_corked_dylibloader_orig_pulse
+#define pa_stream_connect_playback pa_stream_connect_playback_dylibloader_orig_pulse
+#define pa_stream_connect_record pa_stream_connect_record_dylibloader_orig_pulse
+#define pa_stream_disconnect pa_stream_disconnect_dylibloader_orig_pulse
+#define pa_stream_begin_write pa_stream_begin_write_dylibloader_orig_pulse
+#define pa_stream_cancel_write pa_stream_cancel_write_dylibloader_orig_pulse
+#define pa_stream_write pa_stream_write_dylibloader_orig_pulse
+#define pa_stream_write_ext_free pa_stream_write_ext_free_dylibloader_orig_pulse
+#define pa_stream_peek pa_stream_peek_dylibloader_orig_pulse
+#define pa_stream_drop pa_stream_drop_dylibloader_orig_pulse
+#define pa_stream_writable_size pa_stream_writable_size_dylibloader_orig_pulse
+#define pa_stream_readable_size pa_stream_readable_size_dylibloader_orig_pulse
+#define pa_stream_drain pa_stream_drain_dylibloader_orig_pulse
+#define pa_stream_update_timing_info pa_stream_update_timing_info_dylibloader_orig_pulse
+#define pa_stream_set_state_callback pa_stream_set_state_callback_dylibloader_orig_pulse
+#define pa_stream_set_write_callback pa_stream_set_write_callback_dylibloader_orig_pulse
+#define pa_stream_set_read_callback pa_stream_set_read_callback_dylibloader_orig_pulse
+#define pa_stream_set_overflow_callback pa_stream_set_overflow_callback_dylibloader_orig_pulse
+#define pa_stream_get_underflow_index pa_stream_get_underflow_index_dylibloader_orig_pulse
+#define pa_stream_set_underflow_callback pa_stream_set_underflow_callback_dylibloader_orig_pulse
+#define pa_stream_set_started_callback pa_stream_set_started_callback_dylibloader_orig_pulse
+#define pa_stream_set_latency_update_callback pa_stream_set_latency_update_callback_dylibloader_orig_pulse
+#define pa_stream_set_moved_callback pa_stream_set_moved_callback_dylibloader_orig_pulse
+#define pa_stream_set_suspended_callback pa_stream_set_suspended_callback_dylibloader_orig_pulse
+#define pa_stream_set_event_callback pa_stream_set_event_callback_dylibloader_orig_pulse
+#define pa_stream_set_buffer_attr_callback pa_stream_set_buffer_attr_callback_dylibloader_orig_pulse
+#define pa_stream_cork pa_stream_cork_dylibloader_orig_pulse
+#define pa_stream_flush pa_stream_flush_dylibloader_orig_pulse
+#define pa_stream_prebuf pa_stream_prebuf_dylibloader_orig_pulse
+#define pa_stream_trigger pa_stream_trigger_dylibloader_orig_pulse
+#define pa_stream_set_name pa_stream_set_name_dylibloader_orig_pulse
+#define pa_stream_get_time pa_stream_get_time_dylibloader_orig_pulse
+#define pa_stream_get_latency pa_stream_get_latency_dylibloader_orig_pulse
+#define pa_stream_get_timing_info pa_stream_get_timing_info_dylibloader_orig_pulse
+#define pa_stream_get_sample_spec pa_stream_get_sample_spec_dylibloader_orig_pulse
+#define pa_stream_get_channel_map pa_stream_get_channel_map_dylibloader_orig_pulse
+#define pa_stream_get_format_info pa_stream_get_format_info_dylibloader_orig_pulse
+#define pa_stream_get_buffer_attr pa_stream_get_buffer_attr_dylibloader_orig_pulse
+#define pa_stream_set_buffer_attr pa_stream_set_buffer_attr_dylibloader_orig_pulse
+#define pa_stream_update_sample_rate pa_stream_update_sample_rate_dylibloader_orig_pulse
+#define pa_stream_proplist_update pa_stream_proplist_update_dylibloader_orig_pulse
+#define pa_stream_proplist_remove pa_stream_proplist_remove_dylibloader_orig_pulse
+#define pa_stream_set_monitor_stream pa_stream_set_monitor_stream_dylibloader_orig_pulse
+#define pa_stream_get_monitor_stream pa_stream_get_monitor_stream_dylibloader_orig_pulse
+#define pa_context_get_sink_info_by_name pa_context_get_sink_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_sink_info_by_index pa_context_get_sink_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_sink_info_list pa_context_get_sink_info_list_dylibloader_orig_pulse
+#define pa_context_set_sink_volume_by_index pa_context_set_sink_volume_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_volume_by_name pa_context_set_sink_volume_by_name_dylibloader_orig_pulse
+#define pa_context_set_sink_mute_by_index pa_context_set_sink_mute_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_mute_by_name pa_context_set_sink_mute_by_name_dylibloader_orig_pulse
+#define pa_context_suspend_sink_by_name pa_context_suspend_sink_by_name_dylibloader_orig_pulse
+#define pa_context_suspend_sink_by_index pa_context_suspend_sink_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_port_by_index pa_context_set_sink_port_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_port_by_name pa_context_set_sink_port_by_name_dylibloader_orig_pulse
+#define pa_context_get_source_info_by_name pa_context_get_source_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_source_info_by_index pa_context_get_source_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_source_info_list pa_context_get_source_info_list_dylibloader_orig_pulse
+#define pa_context_set_source_volume_by_index pa_context_set_source_volume_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_volume_by_name pa_context_set_source_volume_by_name_dylibloader_orig_pulse
+#define pa_context_set_source_mute_by_index pa_context_set_source_mute_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_mute_by_name pa_context_set_source_mute_by_name_dylibloader_orig_pulse
+#define pa_context_suspend_source_by_name pa_context_suspend_source_by_name_dylibloader_orig_pulse
+#define pa_context_suspend_source_by_index pa_context_suspend_source_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_port_by_index pa_context_set_source_port_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_port_by_name pa_context_set_source_port_by_name_dylibloader_orig_pulse
+#define pa_context_get_server_info pa_context_get_server_info_dylibloader_orig_pulse
+#define pa_context_get_module_info pa_context_get_module_info_dylibloader_orig_pulse
+#define pa_context_get_module_info_list pa_context_get_module_info_list_dylibloader_orig_pulse
+#define pa_context_load_module pa_context_load_module_dylibloader_orig_pulse
+#define pa_context_unload_module pa_context_unload_module_dylibloader_orig_pulse
+#define pa_context_get_client_info pa_context_get_client_info_dylibloader_orig_pulse
+#define pa_context_get_client_info_list pa_context_get_client_info_list_dylibloader_orig_pulse
+#define pa_context_kill_client pa_context_kill_client_dylibloader_orig_pulse
+#define pa_context_get_card_info_by_index pa_context_get_card_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_card_info_by_name pa_context_get_card_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_card_info_list pa_context_get_card_info_list_dylibloader_orig_pulse
+#define pa_context_set_card_profile_by_index pa_context_set_card_profile_by_index_dylibloader_orig_pulse
+#define pa_context_set_card_profile_by_name pa_context_set_card_profile_by_name_dylibloader_orig_pulse
+#define pa_context_set_port_latency_offset pa_context_set_port_latency_offset_dylibloader_orig_pulse
+#define pa_context_get_sink_input_info pa_context_get_sink_input_info_dylibloader_orig_pulse
+#define pa_context_get_sink_input_info_list pa_context_get_sink_input_info_list_dylibloader_orig_pulse
+#define pa_context_move_sink_input_by_name pa_context_move_sink_input_by_name_dylibloader_orig_pulse
+#define pa_context_move_sink_input_by_index pa_context_move_sink_input_by_index_dylibloader_orig_pulse
+#define pa_context_set_sink_input_volume pa_context_set_sink_input_volume_dylibloader_orig_pulse
+#define pa_context_set_sink_input_mute pa_context_set_sink_input_mute_dylibloader_orig_pulse
+#define pa_context_kill_sink_input pa_context_kill_sink_input_dylibloader_orig_pulse
+#define pa_context_get_source_output_info pa_context_get_source_output_info_dylibloader_orig_pulse
+#define pa_context_get_source_output_info_list pa_context_get_source_output_info_list_dylibloader_orig_pulse
+#define pa_context_move_source_output_by_name pa_context_move_source_output_by_name_dylibloader_orig_pulse
+#define pa_context_move_source_output_by_index pa_context_move_source_output_by_index_dylibloader_orig_pulse
+#define pa_context_set_source_output_volume pa_context_set_source_output_volume_dylibloader_orig_pulse
+#define pa_context_set_source_output_mute pa_context_set_source_output_mute_dylibloader_orig_pulse
+#define pa_context_kill_source_output pa_context_kill_source_output_dylibloader_orig_pulse
+#define pa_context_stat pa_context_stat_dylibloader_orig_pulse
+#define pa_context_get_sample_info_by_name pa_context_get_sample_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_sample_info_by_index pa_context_get_sample_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_sample_info_list pa_context_get_sample_info_list_dylibloader_orig_pulse
+#define pa_context_get_autoload_info_by_name pa_context_get_autoload_info_by_name_dylibloader_orig_pulse
+#define pa_context_get_autoload_info_by_index pa_context_get_autoload_info_by_index_dylibloader_orig_pulse
+#define pa_context_get_autoload_info_list pa_context_get_autoload_info_list_dylibloader_orig_pulse
+#define pa_context_add_autoload pa_context_add_autoload_dylibloader_orig_pulse
+#define pa_context_remove_autoload_by_name pa_context_remove_autoload_by_name_dylibloader_orig_pulse
+#define pa_context_remove_autoload_by_index pa_context_remove_autoload_by_index_dylibloader_orig_pulse
+#define pa_context_subscribe pa_context_subscribe_dylibloader_orig_pulse
+#define pa_context_set_subscribe_callback pa_context_set_subscribe_callback_dylibloader_orig_pulse
+#define pa_stream_connect_upload pa_stream_connect_upload_dylibloader_orig_pulse
+#define pa_stream_finish_upload pa_stream_finish_upload_dylibloader_orig_pulse
+#define pa_context_remove_sample pa_context_remove_sample_dylibloader_orig_pulse
+#define pa_context_play_sample pa_context_play_sample_dylibloader_orig_pulse
+#define pa_context_play_sample_with_proplist pa_context_play_sample_with_proplist_dylibloader_orig_pulse
+#define pa_strerror pa_strerror_dylibloader_orig_pulse
+#define pa_xmalloc pa_xmalloc_dylibloader_orig_pulse
+#define pa_xmalloc0 pa_xmalloc0_dylibloader_orig_pulse
+#define pa_xrealloc pa_xrealloc_dylibloader_orig_pulse
+#define pa_xfree pa_xfree_dylibloader_orig_pulse
+#define pa_xstrdup pa_xstrdup_dylibloader_orig_pulse
+#define pa_xstrndup pa_xstrndup_dylibloader_orig_pulse
+#define pa_xmemdup pa_xmemdup_dylibloader_orig_pulse
+#define pa_utf8_valid pa_utf8_valid_dylibloader_orig_pulse
+#define pa_ascii_valid pa_ascii_valid_dylibloader_orig_pulse
+#define pa_utf8_filter pa_utf8_filter_dylibloader_orig_pulse
+#define pa_ascii_filter pa_ascii_filter_dylibloader_orig_pulse
+#define pa_utf8_to_locale pa_utf8_to_locale_dylibloader_orig_pulse
+#define pa_locale_to_utf8 pa_locale_to_utf8_dylibloader_orig_pulse
+#define pa_threaded_mainloop_new pa_threaded_mainloop_new_dylibloader_orig_pulse
+#define pa_threaded_mainloop_free pa_threaded_mainloop_free_dylibloader_orig_pulse
+#define pa_threaded_mainloop_start pa_threaded_mainloop_start_dylibloader_orig_pulse
+#define pa_threaded_mainloop_stop pa_threaded_mainloop_stop_dylibloader_orig_pulse
+#define pa_threaded_mainloop_lock pa_threaded_mainloop_lock_dylibloader_orig_pulse
+#define pa_threaded_mainloop_unlock pa_threaded_mainloop_unlock_dylibloader_orig_pulse
+#define pa_threaded_mainloop_wait pa_threaded_mainloop_wait_dylibloader_orig_pulse
+#define pa_threaded_mainloop_signal pa_threaded_mainloop_signal_dylibloader_orig_pulse
+#define pa_threaded_mainloop_accept pa_threaded_mainloop_accept_dylibloader_orig_pulse
+#define pa_threaded_mainloop_get_retval pa_threaded_mainloop_get_retval_dylibloader_orig_pulse
+#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_orig_pulse
+#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_orig_pulse
+#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_orig_pulse
+#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_orig_pulse
+#define pa_mainloop_new pa_mainloop_new_dylibloader_orig_pulse
+#define pa_mainloop_free pa_mainloop_free_dylibloader_orig_pulse
+#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_orig_pulse
+#define pa_mainloop_poll pa_mainloop_poll_dylibloader_orig_pulse
+#define pa_mainloop_dispatch pa_mainloop_dispatch_dylibloader_orig_pulse
+#define pa_mainloop_get_retval pa_mainloop_get_retval_dylibloader_orig_pulse
+#define pa_mainloop_iterate pa_mainloop_iterate_dylibloader_orig_pulse
+#define pa_mainloop_run pa_mainloop_run_dylibloader_orig_pulse
+#define pa_mainloop_get_api pa_mainloop_get_api_dylibloader_orig_pulse
+#define pa_mainloop_quit pa_mainloop_quit_dylibloader_orig_pulse
+#define pa_mainloop_wakeup pa_mainloop_wakeup_dylibloader_orig_pulse
+#define pa_mainloop_set_poll_func pa_mainloop_set_poll_func_dylibloader_orig_pulse
+#define pa_signal_init pa_signal_init_dylibloader_orig_pulse
+#define pa_signal_done pa_signal_done_dylibloader_orig_pulse
+#define pa_signal_new pa_signal_new_dylibloader_orig_pulse
+#define pa_signal_free pa_signal_free_dylibloader_orig_pulse
+#define pa_signal_set_destroy pa_signal_set_destroy_dylibloader_orig_pulse
+#define pa_get_user_name pa_get_user_name_dylibloader_orig_pulse
+#define pa_get_host_name pa_get_host_name_dylibloader_orig_pulse
+#define pa_get_fqdn pa_get_fqdn_dylibloader_orig_pulse
+#define pa_get_home_dir pa_get_home_dir_dylibloader_orig_pulse
+#define pa_get_binary_name pa_get_binary_name_dylibloader_orig_pulse
+#define pa_path_get_filename pa_path_get_filename_dylibloader_orig_pulse
+#define pa_msleep pa_msleep_dylibloader_orig_pulse
+#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_orig_pulse
+#define pa_gettimeofday pa_gettimeofday_dylibloader_orig_pulse
+#define pa_timeval_diff pa_timeval_diff_dylibloader_orig_pulse
+#define pa_timeval_cmp pa_timeval_cmp_dylibloader_orig_pulse
+#define pa_timeval_age pa_timeval_age_dylibloader_orig_pulse
+#define pa_timeval_add pa_timeval_add_dylibloader_orig_pulse
+#define pa_timeval_sub pa_timeval_sub_dylibloader_orig_pulse
+#define pa_timeval_store pa_timeval_store_dylibloader_orig_pulse
+#define pa_timeval_load pa_timeval_load_dylibloader_orig_pulse
+#define pa_rtclock_now pa_rtclock_now_dylibloader_orig_pulse
+#include <pulse/pulseaudio.h>
+#undef pa_get_library_version
+#undef pa_bytes_per_second
+#undef pa_frame_size
+#undef pa_sample_size
+#undef pa_sample_size_of_format
+#undef pa_bytes_to_usec
+#undef pa_usec_to_bytes
+#undef pa_sample_spec_init
+#undef pa_sample_format_valid
+#undef pa_sample_rate_valid
+#undef pa_channels_valid
+#undef pa_sample_spec_valid
+#undef pa_sample_spec_equal
+#undef pa_sample_format_to_string
+#undef pa_parse_sample_format
+#undef pa_sample_spec_snprint
+#undef pa_bytes_snprint
+#undef pa_sample_format_is_le
+#undef pa_sample_format_is_be
+#undef pa_direction_valid
+#undef pa_direction_to_string
+#undef pa_mainloop_api_once
+#undef pa_proplist_new
+#undef pa_proplist_free
+#undef pa_proplist_key_valid
+#undef pa_proplist_sets
+#undef pa_proplist_setp
+#undef pa_proplist_setf
+#undef pa_proplist_set
+#undef pa_proplist_gets
+#undef pa_proplist_get
+#undef pa_proplist_update
+#undef pa_proplist_unset
+#undef pa_proplist_unset_many
+#undef pa_proplist_iterate
+#undef pa_proplist_to_string
+#undef pa_proplist_to_string_sep
+#undef pa_proplist_from_string
+#undef pa_proplist_contains
+#undef pa_proplist_clear
+#undef pa_proplist_copy
+#undef pa_proplist_size
+#undef pa_proplist_isempty
+#undef pa_proplist_equal
+#undef pa_channel_map_init
+#undef pa_channel_map_init_mono
+#undef pa_channel_map_init_stereo
+#undef pa_channel_map_init_auto
+#undef pa_channel_map_init_extend
+#undef pa_channel_position_to_string
+#undef pa_channel_position_from_string
+#undef pa_channel_position_to_pretty_string
+#undef pa_channel_map_snprint
+#undef pa_channel_map_parse
+#undef pa_channel_map_equal
+#undef pa_channel_map_valid
+#undef pa_channel_map_compatible
+#undef pa_channel_map_superset
+#undef pa_channel_map_can_balance
+#undef pa_channel_map_can_fade
+#undef pa_channel_map_can_lfe_balance
+#undef pa_channel_map_to_name
+#undef pa_channel_map_to_pretty_name
+#undef pa_channel_map_has_position
+#undef pa_channel_map_mask
+#undef pa_encoding_to_string
+#undef pa_encoding_from_string
+#undef pa_format_info_new
+#undef pa_format_info_copy
+#undef pa_format_info_free
+#undef pa_format_info_valid
+#undef pa_format_info_is_pcm
+#undef pa_format_info_is_compatible
+#undef pa_format_info_snprint
+#undef pa_format_info_from_string
+#undef pa_format_info_from_sample_spec
+#undef pa_format_info_to_sample_spec
+#undef pa_format_info_get_prop_type
+#undef pa_format_info_get_prop_int
+#undef pa_format_info_get_prop_int_range
+#undef pa_format_info_get_prop_int_array
+#undef pa_format_info_get_prop_string
+#undef pa_format_info_get_prop_string_array
+#undef pa_format_info_free_string_array
+#undef pa_format_info_get_sample_format
+#undef pa_format_info_get_rate
+#undef pa_format_info_get_channels
+#undef pa_format_info_get_channel_map
+#undef pa_format_info_set_prop_int
+#undef pa_format_info_set_prop_int_array
+#undef pa_format_info_set_prop_int_range
+#undef pa_format_info_set_prop_string
+#undef pa_format_info_set_prop_string_array
+#undef pa_format_info_set_sample_format
+#undef pa_format_info_set_rate
+#undef pa_format_info_set_channels
+#undef pa_format_info_set_channel_map
+#undef pa_operation_ref
+#undef pa_operation_unref
+#undef pa_operation_cancel
+#undef pa_operation_get_state
+#undef pa_operation_set_state_callback
+#undef pa_context_new
+#undef pa_context_new_with_proplist
+#undef pa_context_unref
+#undef pa_context_ref
+#undef pa_context_set_state_callback
+#undef pa_context_set_event_callback
+#undef pa_context_errno
+#undef pa_context_is_pending
+#undef pa_context_get_state
+#undef pa_context_connect
+#undef pa_context_disconnect
+#undef pa_context_drain
+#undef pa_context_exit_daemon
+#undef pa_context_set_default_sink
+#undef pa_context_set_default_source
+#undef pa_context_is_local
+#undef pa_context_set_name
+#undef pa_context_get_server
+#undef pa_context_get_protocol_version
+#undef pa_context_get_server_protocol_version
+#undef pa_context_proplist_update
+#undef pa_context_proplist_remove
+#undef pa_context_get_index
+#undef pa_context_rttime_new
+#undef pa_context_rttime_restart
+#undef pa_context_get_tile_size
+#undef pa_context_load_cookie_from_file
+#undef pa_cvolume_equal
+#undef pa_cvolume_init
+#undef pa_cvolume_set
+#undef pa_cvolume_snprint
+#undef pa_sw_cvolume_snprint_dB
+#undef pa_cvolume_snprint_verbose
+#undef pa_volume_snprint
+#undef pa_sw_volume_snprint_dB
+#undef pa_volume_snprint_verbose
+#undef pa_cvolume_avg
+#undef pa_cvolume_avg_mask
+#undef pa_cvolume_max
+#undef pa_cvolume_max_mask
+#undef pa_cvolume_min
+#undef pa_cvolume_min_mask
+#undef pa_cvolume_valid
+#undef pa_cvolume_channels_equal_to
+#undef pa_sw_volume_multiply
+#undef pa_sw_cvolume_multiply
+#undef pa_sw_cvolume_multiply_scalar
+#undef pa_sw_volume_divide
+#undef pa_sw_cvolume_divide
+#undef pa_sw_cvolume_divide_scalar
+#undef pa_sw_volume_from_dB
+#undef pa_sw_volume_to_dB
+#undef pa_sw_volume_from_linear
+#undef pa_sw_volume_to_linear
+#undef pa_cvolume_remap
+#undef pa_cvolume_compatible
+#undef pa_cvolume_compatible_with_channel_map
+#undef pa_cvolume_get_balance
+#undef pa_cvolume_set_balance
+#undef pa_cvolume_get_fade
+#undef pa_cvolume_set_fade
+#undef pa_cvolume_get_lfe_balance
+#undef pa_cvolume_set_lfe_balance
+#undef pa_cvolume_scale
+#undef pa_cvolume_scale_mask
+#undef pa_cvolume_set_position
+#undef pa_cvolume_get_position
+#undef pa_cvolume_merge
+#undef pa_cvolume_inc_clamp
+#undef pa_cvolume_inc
+#undef pa_cvolume_dec
+#undef pa_stream_new
+#undef pa_stream_new_with_proplist
+#undef pa_stream_new_extended
+#undef pa_stream_unref
+#undef pa_stream_ref
+#undef pa_stream_get_state
+#undef pa_stream_get_context
+#undef pa_stream_get_index
+#undef pa_stream_get_device_index
+#undef pa_stream_get_device_name
+#undef pa_stream_is_suspended
+#undef pa_stream_is_corked
+#undef pa_stream_connect_playback
+#undef pa_stream_connect_record
+#undef pa_stream_disconnect
+#undef pa_stream_begin_write
+#undef pa_stream_cancel_write
+#undef pa_stream_write
+#undef pa_stream_write_ext_free
+#undef pa_stream_peek
+#undef pa_stream_drop
+#undef pa_stream_writable_size
+#undef pa_stream_readable_size
+#undef pa_stream_drain
+#undef pa_stream_update_timing_info
+#undef pa_stream_set_state_callback
+#undef pa_stream_set_write_callback
+#undef pa_stream_set_read_callback
+#undef pa_stream_set_overflow_callback
+#undef pa_stream_get_underflow_index
+#undef pa_stream_set_underflow_callback
+#undef pa_stream_set_started_callback
+#undef pa_stream_set_latency_update_callback
+#undef pa_stream_set_moved_callback
+#undef pa_stream_set_suspended_callback
+#undef pa_stream_set_event_callback
+#undef pa_stream_set_buffer_attr_callback
+#undef pa_stream_cork
+#undef pa_stream_flush
+#undef pa_stream_prebuf
+#undef pa_stream_trigger
+#undef pa_stream_set_name
+#undef pa_stream_get_time
+#undef pa_stream_get_latency
+#undef pa_stream_get_timing_info
+#undef pa_stream_get_sample_spec
+#undef pa_stream_get_channel_map
+#undef pa_stream_get_format_info
+#undef pa_stream_get_buffer_attr
+#undef pa_stream_set_buffer_attr
+#undef pa_stream_update_sample_rate
+#undef pa_stream_proplist_update
+#undef pa_stream_proplist_remove
+#undef pa_stream_set_monitor_stream
+#undef pa_stream_get_monitor_stream
+#undef pa_context_get_sink_info_by_name
+#undef pa_context_get_sink_info_by_index
+#undef pa_context_get_sink_info_list
+#undef pa_context_set_sink_volume_by_index
+#undef pa_context_set_sink_volume_by_name
+#undef pa_context_set_sink_mute_by_index
+#undef pa_context_set_sink_mute_by_name
+#undef pa_context_suspend_sink_by_name
+#undef pa_context_suspend_sink_by_index
+#undef pa_context_set_sink_port_by_index
+#undef pa_context_set_sink_port_by_name
+#undef pa_context_get_source_info_by_name
+#undef pa_context_get_source_info_by_index
+#undef pa_context_get_source_info_list
+#undef pa_context_set_source_volume_by_index
+#undef pa_context_set_source_volume_by_name
+#undef pa_context_set_source_mute_by_index
+#undef pa_context_set_source_mute_by_name
+#undef pa_context_suspend_source_by_name
+#undef pa_context_suspend_source_by_index
+#undef pa_context_set_source_port_by_index
+#undef pa_context_set_source_port_by_name
+#undef pa_context_get_server_info
+#undef pa_context_get_module_info
+#undef pa_context_get_module_info_list
+#undef pa_context_load_module
+#undef pa_context_unload_module
+#undef pa_context_get_client_info
+#undef pa_context_get_client_info_list
+#undef pa_context_kill_client
+#undef pa_context_get_card_info_by_index
+#undef pa_context_get_card_info_by_name
+#undef pa_context_get_card_info_list
+#undef pa_context_set_card_profile_by_index
+#undef pa_context_set_card_profile_by_name
+#undef pa_context_set_port_latency_offset
+#undef pa_context_get_sink_input_info
+#undef pa_context_get_sink_input_info_list
+#undef pa_context_move_sink_input_by_name
+#undef pa_context_move_sink_input_by_index
+#undef pa_context_set_sink_input_volume
+#undef pa_context_set_sink_input_mute
+#undef pa_context_kill_sink_input
+#undef pa_context_get_source_output_info
+#undef pa_context_get_source_output_info_list
+#undef pa_context_move_source_output_by_name
+#undef pa_context_move_source_output_by_index
+#undef pa_context_set_source_output_volume
+#undef pa_context_set_source_output_mute
+#undef pa_context_kill_source_output
+#undef pa_context_stat
+#undef pa_context_get_sample_info_by_name
+#undef pa_context_get_sample_info_by_index
+#undef pa_context_get_sample_info_list
+#undef pa_context_get_autoload_info_by_name
+#undef pa_context_get_autoload_info_by_index
+#undef pa_context_get_autoload_info_list
+#undef pa_context_add_autoload
+#undef pa_context_remove_autoload_by_name
+#undef pa_context_remove_autoload_by_index
+#undef pa_context_subscribe
+#undef pa_context_set_subscribe_callback
+#undef pa_stream_connect_upload
+#undef pa_stream_finish_upload
+#undef pa_context_remove_sample
+#undef pa_context_play_sample
+#undef pa_context_play_sample_with_proplist
+#undef pa_strerror
+#undef pa_xmalloc
+#undef pa_xmalloc0
+#undef pa_xrealloc
+#undef pa_xfree
+#undef pa_xstrdup
+#undef pa_xstrndup
+#undef pa_xmemdup
+#undef pa_utf8_valid
+#undef pa_ascii_valid
+#undef pa_utf8_filter
+#undef pa_ascii_filter
+#undef pa_utf8_to_locale
+#undef pa_locale_to_utf8
+#undef pa_threaded_mainloop_new
+#undef pa_threaded_mainloop_free
+#undef pa_threaded_mainloop_start
+#undef pa_threaded_mainloop_stop
+#undef pa_threaded_mainloop_lock
+#undef pa_threaded_mainloop_unlock
+#undef pa_threaded_mainloop_wait
+#undef pa_threaded_mainloop_signal
+#undef pa_threaded_mainloop_accept
+#undef pa_threaded_mainloop_get_retval
+#undef pa_threaded_mainloop_get_api
+#undef pa_threaded_mainloop_in_thread
+#undef pa_threaded_mainloop_set_name
+#undef pa_threaded_mainloop_once_unlocked
+#undef pa_mainloop_new
+#undef pa_mainloop_free
+#undef pa_mainloop_prepare
+#undef pa_mainloop_poll
+#undef pa_mainloop_dispatch
+#undef pa_mainloop_get_retval
+#undef pa_mainloop_iterate
+#undef pa_mainloop_run
+#undef pa_mainloop_get_api
+#undef pa_mainloop_quit
+#undef pa_mainloop_wakeup
+#undef pa_mainloop_set_poll_func
+#undef pa_signal_init
+#undef pa_signal_done
+#undef pa_signal_new
+#undef pa_signal_free
+#undef pa_signal_set_destroy
+#undef pa_get_user_name
+#undef pa_get_host_name
+#undef pa_get_fqdn
+#undef pa_get_home_dir
+#undef pa_get_binary_name
+#undef pa_path_get_filename
+#undef pa_msleep
+#undef pa_thread_make_realtime
+#undef pa_gettimeofday
+#undef pa_timeval_diff
+#undef pa_timeval_cmp
+#undef pa_timeval_age
+#undef pa_timeval_add
+#undef pa_timeval_sub
+#undef pa_timeval_store
+#undef pa_timeval_load
+#undef pa_rtclock_now
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define pa_get_library_version pa_get_library_version_dylibloader_wrapper_pulse
+#define pa_bytes_per_second pa_bytes_per_second_dylibloader_wrapper_pulse
+#define pa_frame_size pa_frame_size_dylibloader_wrapper_pulse
+#define pa_sample_size pa_sample_size_dylibloader_wrapper_pulse
+#define pa_sample_size_of_format pa_sample_size_of_format_dylibloader_wrapper_pulse
+#define pa_bytes_to_usec pa_bytes_to_usec_dylibloader_wrapper_pulse
+#define pa_usec_to_bytes pa_usec_to_bytes_dylibloader_wrapper_pulse
+#define pa_sample_spec_init pa_sample_spec_init_dylibloader_wrapper_pulse
+#define pa_sample_format_valid pa_sample_format_valid_dylibloader_wrapper_pulse
+#define pa_sample_rate_valid pa_sample_rate_valid_dylibloader_wrapper_pulse
+#define pa_channels_valid pa_channels_valid_dylibloader_wrapper_pulse
+#define pa_sample_spec_valid pa_sample_spec_valid_dylibloader_wrapper_pulse
+#define pa_sample_spec_equal pa_sample_spec_equal_dylibloader_wrapper_pulse
+#define pa_sample_format_to_string pa_sample_format_to_string_dylibloader_wrapper_pulse
+#define pa_parse_sample_format pa_parse_sample_format_dylibloader_wrapper_pulse
+#define pa_sample_spec_snprint pa_sample_spec_snprint_dylibloader_wrapper_pulse
+#define pa_bytes_snprint pa_bytes_snprint_dylibloader_wrapper_pulse
+#define pa_sample_format_is_le pa_sample_format_is_le_dylibloader_wrapper_pulse
+#define pa_sample_format_is_be pa_sample_format_is_be_dylibloader_wrapper_pulse
+#define pa_direction_valid pa_direction_valid_dylibloader_wrapper_pulse
+#define pa_direction_to_string pa_direction_to_string_dylibloader_wrapper_pulse
+#define pa_mainloop_api_once pa_mainloop_api_once_dylibloader_wrapper_pulse
+#define pa_proplist_new pa_proplist_new_dylibloader_wrapper_pulse
+#define pa_proplist_free pa_proplist_free_dylibloader_wrapper_pulse
+#define pa_proplist_key_valid pa_proplist_key_valid_dylibloader_wrapper_pulse
+#define pa_proplist_sets pa_proplist_sets_dylibloader_wrapper_pulse
+#define pa_proplist_setp pa_proplist_setp_dylibloader_wrapper_pulse
+#define pa_proplist_setf pa_proplist_setf_dylibloader_wrapper_pulse
+#define pa_proplist_set pa_proplist_set_dylibloader_wrapper_pulse
+#define pa_proplist_gets pa_proplist_gets_dylibloader_wrapper_pulse
+#define pa_proplist_get pa_proplist_get_dylibloader_wrapper_pulse
+#define pa_proplist_update pa_proplist_update_dylibloader_wrapper_pulse
+#define pa_proplist_unset pa_proplist_unset_dylibloader_wrapper_pulse
+#define pa_proplist_unset_many pa_proplist_unset_many_dylibloader_wrapper_pulse
+#define pa_proplist_iterate pa_proplist_iterate_dylibloader_wrapper_pulse
+#define pa_proplist_to_string pa_proplist_to_string_dylibloader_wrapper_pulse
+#define pa_proplist_to_string_sep pa_proplist_to_string_sep_dylibloader_wrapper_pulse
+#define pa_proplist_from_string pa_proplist_from_string_dylibloader_wrapper_pulse
+#define pa_proplist_contains pa_proplist_contains_dylibloader_wrapper_pulse
+#define pa_proplist_clear pa_proplist_clear_dylibloader_wrapper_pulse
+#define pa_proplist_copy pa_proplist_copy_dylibloader_wrapper_pulse
+#define pa_proplist_size pa_proplist_size_dylibloader_wrapper_pulse
+#define pa_proplist_isempty pa_proplist_isempty_dylibloader_wrapper_pulse
+#define pa_proplist_equal pa_proplist_equal_dylibloader_wrapper_pulse
+#define pa_channel_map_init pa_channel_map_init_dylibloader_wrapper_pulse
+#define pa_channel_map_init_mono pa_channel_map_init_mono_dylibloader_wrapper_pulse
+#define pa_channel_map_init_stereo pa_channel_map_init_stereo_dylibloader_wrapper_pulse
+#define pa_channel_map_init_auto pa_channel_map_init_auto_dylibloader_wrapper_pulse
+#define pa_channel_map_init_extend pa_channel_map_init_extend_dylibloader_wrapper_pulse
+#define pa_channel_position_to_string pa_channel_position_to_string_dylibloader_wrapper_pulse
+#define pa_channel_position_from_string pa_channel_position_from_string_dylibloader_wrapper_pulse
+#define pa_channel_position_to_pretty_string pa_channel_position_to_pretty_string_dylibloader_wrapper_pulse
+#define pa_channel_map_snprint pa_channel_map_snprint_dylibloader_wrapper_pulse
+#define pa_channel_map_parse pa_channel_map_parse_dylibloader_wrapper_pulse
+#define pa_channel_map_equal pa_channel_map_equal_dylibloader_wrapper_pulse
+#define pa_channel_map_valid pa_channel_map_valid_dylibloader_wrapper_pulse
+#define pa_channel_map_compatible pa_channel_map_compatible_dylibloader_wrapper_pulse
+#define pa_channel_map_superset pa_channel_map_superset_dylibloader_wrapper_pulse
+#define pa_channel_map_can_balance pa_channel_map_can_balance_dylibloader_wrapper_pulse
+#define pa_channel_map_can_fade pa_channel_map_can_fade_dylibloader_wrapper_pulse
+#define pa_channel_map_can_lfe_balance pa_channel_map_can_lfe_balance_dylibloader_wrapper_pulse
+#define pa_channel_map_to_name pa_channel_map_to_name_dylibloader_wrapper_pulse
+#define pa_channel_map_to_pretty_name pa_channel_map_to_pretty_name_dylibloader_wrapper_pulse
+#define pa_channel_map_has_position pa_channel_map_has_position_dylibloader_wrapper_pulse
+#define pa_channel_map_mask pa_channel_map_mask_dylibloader_wrapper_pulse
+#define pa_encoding_to_string pa_encoding_to_string_dylibloader_wrapper_pulse
+#define pa_encoding_from_string pa_encoding_from_string_dylibloader_wrapper_pulse
+#define pa_format_info_new pa_format_info_new_dylibloader_wrapper_pulse
+#define pa_format_info_copy pa_format_info_copy_dylibloader_wrapper_pulse
+#define pa_format_info_free pa_format_info_free_dylibloader_wrapper_pulse
+#define pa_format_info_valid pa_format_info_valid_dylibloader_wrapper_pulse
+#define pa_format_info_is_pcm pa_format_info_is_pcm_dylibloader_wrapper_pulse
+#define pa_format_info_is_compatible pa_format_info_is_compatible_dylibloader_wrapper_pulse
+#define pa_format_info_snprint pa_format_info_snprint_dylibloader_wrapper_pulse
+#define pa_format_info_from_string pa_format_info_from_string_dylibloader_wrapper_pulse
+#define pa_format_info_from_sample_spec pa_format_info_from_sample_spec_dylibloader_wrapper_pulse
+#define pa_format_info_to_sample_spec pa_format_info_to_sample_spec_dylibloader_wrapper_pulse
+#define pa_format_info_get_prop_type pa_format_info_get_prop_type_dylibloader_wrapper_pulse
+#define pa_format_info_get_prop_int pa_format_info_get_prop_int_dylibloader_wrapper_pulse
+#define pa_format_info_get_prop_int_range pa_format_info_get_prop_int_range_dylibloader_wrapper_pulse
+#define pa_format_info_get_prop_int_array pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse
+#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_wrapper_pulse
+#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse
+#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_wrapper_pulse
+#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_wrapper_pulse
+#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_wrapper_pulse
+#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_wrapper_pulse
+#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_wrapper_pulse
+#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_wrapper_pulse
+#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse
+#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse
+#define pa_format_info_set_prop_string pa_format_info_set_prop_string_dylibloader_wrapper_pulse
+#define pa_format_info_set_prop_string_array pa_format_info_set_prop_string_array_dylibloader_wrapper_pulse
+#define pa_format_info_set_sample_format pa_format_info_set_sample_format_dylibloader_wrapper_pulse
+#define pa_format_info_set_rate pa_format_info_set_rate_dylibloader_wrapper_pulse
+#define pa_format_info_set_channels pa_format_info_set_channels_dylibloader_wrapper_pulse
+#define pa_format_info_set_channel_map pa_format_info_set_channel_map_dylibloader_wrapper_pulse
+#define pa_operation_ref pa_operation_ref_dylibloader_wrapper_pulse
+#define pa_operation_unref pa_operation_unref_dylibloader_wrapper_pulse
+#define pa_operation_cancel pa_operation_cancel_dylibloader_wrapper_pulse
+#define pa_operation_get_state pa_operation_get_state_dylibloader_wrapper_pulse
+#define pa_operation_set_state_callback pa_operation_set_state_callback_dylibloader_wrapper_pulse
+#define pa_context_new pa_context_new_dylibloader_wrapper_pulse
+#define pa_context_new_with_proplist pa_context_new_with_proplist_dylibloader_wrapper_pulse
+#define pa_context_unref pa_context_unref_dylibloader_wrapper_pulse
+#define pa_context_ref pa_context_ref_dylibloader_wrapper_pulse
+#define pa_context_set_state_callback pa_context_set_state_callback_dylibloader_wrapper_pulse
+#define pa_context_set_event_callback pa_context_set_event_callback_dylibloader_wrapper_pulse
+#define pa_context_errno pa_context_errno_dylibloader_wrapper_pulse
+#define pa_context_is_pending pa_context_is_pending_dylibloader_wrapper_pulse
+#define pa_context_get_state pa_context_get_state_dylibloader_wrapper_pulse
+#define pa_context_connect pa_context_connect_dylibloader_wrapper_pulse
+#define pa_context_disconnect pa_context_disconnect_dylibloader_wrapper_pulse
+#define pa_context_drain pa_context_drain_dylibloader_wrapper_pulse
+#define pa_context_exit_daemon pa_context_exit_daemon_dylibloader_wrapper_pulse
+#define pa_context_set_default_sink pa_context_set_default_sink_dylibloader_wrapper_pulse
+#define pa_context_set_default_source pa_context_set_default_source_dylibloader_wrapper_pulse
+#define pa_context_is_local pa_context_is_local_dylibloader_wrapper_pulse
+#define pa_context_set_name pa_context_set_name_dylibloader_wrapper_pulse
+#define pa_context_get_server pa_context_get_server_dylibloader_wrapper_pulse
+#define pa_context_get_protocol_version pa_context_get_protocol_version_dylibloader_wrapper_pulse
+#define pa_context_get_server_protocol_version pa_context_get_server_protocol_version_dylibloader_wrapper_pulse
+#define pa_context_proplist_update pa_context_proplist_update_dylibloader_wrapper_pulse
+#define pa_context_proplist_remove pa_context_proplist_remove_dylibloader_wrapper_pulse
+#define pa_context_get_index pa_context_get_index_dylibloader_wrapper_pulse
+#define pa_context_rttime_new pa_context_rttime_new_dylibloader_wrapper_pulse
+#define pa_context_rttime_restart pa_context_rttime_restart_dylibloader_wrapper_pulse
+#define pa_context_get_tile_size pa_context_get_tile_size_dylibloader_wrapper_pulse
+#define pa_context_load_cookie_from_file pa_context_load_cookie_from_file_dylibloader_wrapper_pulse
+#define pa_cvolume_equal pa_cvolume_equal_dylibloader_wrapper_pulse
+#define pa_cvolume_init pa_cvolume_init_dylibloader_wrapper_pulse
+#define pa_cvolume_set pa_cvolume_set_dylibloader_wrapper_pulse
+#define pa_cvolume_snprint pa_cvolume_snprint_dylibloader_wrapper_pulse
+#define pa_sw_cvolume_snprint_dB pa_sw_cvolume_snprint_dB_dylibloader_wrapper_pulse
+#define pa_cvolume_snprint_verbose pa_cvolume_snprint_verbose_dylibloader_wrapper_pulse
+#define pa_volume_snprint pa_volume_snprint_dylibloader_wrapper_pulse
+#define pa_sw_volume_snprint_dB pa_sw_volume_snprint_dB_dylibloader_wrapper_pulse
+#define pa_volume_snprint_verbose pa_volume_snprint_verbose_dylibloader_wrapper_pulse
+#define pa_cvolume_avg pa_cvolume_avg_dylibloader_wrapper_pulse
+#define pa_cvolume_avg_mask pa_cvolume_avg_mask_dylibloader_wrapper_pulse
+#define pa_cvolume_max pa_cvolume_max_dylibloader_wrapper_pulse
+#define pa_cvolume_max_mask pa_cvolume_max_mask_dylibloader_wrapper_pulse
+#define pa_cvolume_min pa_cvolume_min_dylibloader_wrapper_pulse
+#define pa_cvolume_min_mask pa_cvolume_min_mask_dylibloader_wrapper_pulse
+#define pa_cvolume_valid pa_cvolume_valid_dylibloader_wrapper_pulse
+#define pa_cvolume_channels_equal_to pa_cvolume_channels_equal_to_dylibloader_wrapper_pulse
+#define pa_sw_volume_multiply pa_sw_volume_multiply_dylibloader_wrapper_pulse
+#define pa_sw_cvolume_multiply pa_sw_cvolume_multiply_dylibloader_wrapper_pulse
+#define pa_sw_cvolume_multiply_scalar pa_sw_cvolume_multiply_scalar_dylibloader_wrapper_pulse
+#define pa_sw_volume_divide pa_sw_volume_divide_dylibloader_wrapper_pulse
+#define pa_sw_cvolume_divide pa_sw_cvolume_divide_dylibloader_wrapper_pulse
+#define pa_sw_cvolume_divide_scalar pa_sw_cvolume_divide_scalar_dylibloader_wrapper_pulse
+#define pa_sw_volume_from_dB pa_sw_volume_from_dB_dylibloader_wrapper_pulse
+#define pa_sw_volume_to_dB pa_sw_volume_to_dB_dylibloader_wrapper_pulse
+#define pa_sw_volume_from_linear pa_sw_volume_from_linear_dylibloader_wrapper_pulse
+#define pa_sw_volume_to_linear pa_sw_volume_to_linear_dylibloader_wrapper_pulse
+#define pa_cvolume_remap pa_cvolume_remap_dylibloader_wrapper_pulse
+#define pa_cvolume_compatible pa_cvolume_compatible_dylibloader_wrapper_pulse
+#define pa_cvolume_compatible_with_channel_map pa_cvolume_compatible_with_channel_map_dylibloader_wrapper_pulse
+#define pa_cvolume_get_balance pa_cvolume_get_balance_dylibloader_wrapper_pulse
+#define pa_cvolume_set_balance pa_cvolume_set_balance_dylibloader_wrapper_pulse
+#define pa_cvolume_get_fade pa_cvolume_get_fade_dylibloader_wrapper_pulse
+#define pa_cvolume_set_fade pa_cvolume_set_fade_dylibloader_wrapper_pulse
+#define pa_cvolume_get_lfe_balance pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse
+#define pa_cvolume_set_lfe_balance pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse
+#define pa_cvolume_scale pa_cvolume_scale_dylibloader_wrapper_pulse
+#define pa_cvolume_scale_mask pa_cvolume_scale_mask_dylibloader_wrapper_pulse
+#define pa_cvolume_set_position pa_cvolume_set_position_dylibloader_wrapper_pulse
+#define pa_cvolume_get_position pa_cvolume_get_position_dylibloader_wrapper_pulse
+#define pa_cvolume_merge pa_cvolume_merge_dylibloader_wrapper_pulse
+#define pa_cvolume_inc_clamp pa_cvolume_inc_clamp_dylibloader_wrapper_pulse
+#define pa_cvolume_inc pa_cvolume_inc_dylibloader_wrapper_pulse
+#define pa_cvolume_dec pa_cvolume_dec_dylibloader_wrapper_pulse
+#define pa_stream_new pa_stream_new_dylibloader_wrapper_pulse
+#define pa_stream_new_with_proplist pa_stream_new_with_proplist_dylibloader_wrapper_pulse
+#define pa_stream_new_extended pa_stream_new_extended_dylibloader_wrapper_pulse
+#define pa_stream_unref pa_stream_unref_dylibloader_wrapper_pulse
+#define pa_stream_ref pa_stream_ref_dylibloader_wrapper_pulse
+#define pa_stream_get_state pa_stream_get_state_dylibloader_wrapper_pulse
+#define pa_stream_get_context pa_stream_get_context_dylibloader_wrapper_pulse
+#define pa_stream_get_index pa_stream_get_index_dylibloader_wrapper_pulse
+#define pa_stream_get_device_index pa_stream_get_device_index_dylibloader_wrapper_pulse
+#define pa_stream_get_device_name pa_stream_get_device_name_dylibloader_wrapper_pulse
+#define pa_stream_is_suspended pa_stream_is_suspended_dylibloader_wrapper_pulse
+#define pa_stream_is_corked pa_stream_is_corked_dylibloader_wrapper_pulse
+#define pa_stream_connect_playback pa_stream_connect_playback_dylibloader_wrapper_pulse
+#define pa_stream_connect_record pa_stream_connect_record_dylibloader_wrapper_pulse
+#define pa_stream_disconnect pa_stream_disconnect_dylibloader_wrapper_pulse
+#define pa_stream_begin_write pa_stream_begin_write_dylibloader_wrapper_pulse
+#define pa_stream_cancel_write pa_stream_cancel_write_dylibloader_wrapper_pulse
+#define pa_stream_write pa_stream_write_dylibloader_wrapper_pulse
+#define pa_stream_write_ext_free pa_stream_write_ext_free_dylibloader_wrapper_pulse
+#define pa_stream_peek pa_stream_peek_dylibloader_wrapper_pulse
+#define pa_stream_drop pa_stream_drop_dylibloader_wrapper_pulse
+#define pa_stream_writable_size pa_stream_writable_size_dylibloader_wrapper_pulse
+#define pa_stream_readable_size pa_stream_readable_size_dylibloader_wrapper_pulse
+#define pa_stream_drain pa_stream_drain_dylibloader_wrapper_pulse
+#define pa_stream_update_timing_info pa_stream_update_timing_info_dylibloader_wrapper_pulse
+#define pa_stream_set_state_callback pa_stream_set_state_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_write_callback pa_stream_set_write_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_read_callback pa_stream_set_read_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_overflow_callback pa_stream_set_overflow_callback_dylibloader_wrapper_pulse
+#define pa_stream_get_underflow_index pa_stream_get_underflow_index_dylibloader_wrapper_pulse
+#define pa_stream_set_underflow_callback pa_stream_set_underflow_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_started_callback pa_stream_set_started_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_latency_update_callback pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_moved_callback pa_stream_set_moved_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_suspended_callback pa_stream_set_suspended_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_event_callback pa_stream_set_event_callback_dylibloader_wrapper_pulse
+#define pa_stream_set_buffer_attr_callback pa_stream_set_buffer_attr_callback_dylibloader_wrapper_pulse
+#define pa_stream_cork pa_stream_cork_dylibloader_wrapper_pulse
+#define pa_stream_flush pa_stream_flush_dylibloader_wrapper_pulse
+#define pa_stream_prebuf pa_stream_prebuf_dylibloader_wrapper_pulse
+#define pa_stream_trigger pa_stream_trigger_dylibloader_wrapper_pulse
+#define pa_stream_set_name pa_stream_set_name_dylibloader_wrapper_pulse
+#define pa_stream_get_time pa_stream_get_time_dylibloader_wrapper_pulse
+#define pa_stream_get_latency pa_stream_get_latency_dylibloader_wrapper_pulse
+#define pa_stream_get_timing_info pa_stream_get_timing_info_dylibloader_wrapper_pulse
+#define pa_stream_get_sample_spec pa_stream_get_sample_spec_dylibloader_wrapper_pulse
+#define pa_stream_get_channel_map pa_stream_get_channel_map_dylibloader_wrapper_pulse
+#define pa_stream_get_format_info pa_stream_get_format_info_dylibloader_wrapper_pulse
+#define pa_stream_get_buffer_attr pa_stream_get_buffer_attr_dylibloader_wrapper_pulse
+#define pa_stream_set_buffer_attr pa_stream_set_buffer_attr_dylibloader_wrapper_pulse
+#define pa_stream_update_sample_rate pa_stream_update_sample_rate_dylibloader_wrapper_pulse
+#define pa_stream_proplist_update pa_stream_proplist_update_dylibloader_wrapper_pulse
+#define pa_stream_proplist_remove pa_stream_proplist_remove_dylibloader_wrapper_pulse
+#define pa_stream_set_monitor_stream pa_stream_set_monitor_stream_dylibloader_wrapper_pulse
+#define pa_stream_get_monitor_stream pa_stream_get_monitor_stream_dylibloader_wrapper_pulse
+#define pa_context_get_sink_info_by_name pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse
+#define pa_context_get_sink_info_by_index pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse
+#define pa_context_get_sink_info_list pa_context_get_sink_info_list_dylibloader_wrapper_pulse
+#define pa_context_set_sink_volume_by_index pa_context_set_sink_volume_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_sink_volume_by_name pa_context_set_sink_volume_by_name_dylibloader_wrapper_pulse
+#define pa_context_set_sink_mute_by_index pa_context_set_sink_mute_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_sink_mute_by_name pa_context_set_sink_mute_by_name_dylibloader_wrapper_pulse
+#define pa_context_suspend_sink_by_name pa_context_suspend_sink_by_name_dylibloader_wrapper_pulse
+#define pa_context_suspend_sink_by_index pa_context_suspend_sink_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_sink_port_by_index pa_context_set_sink_port_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_sink_port_by_name pa_context_set_sink_port_by_name_dylibloader_wrapper_pulse
+#define pa_context_get_source_info_by_name pa_context_get_source_info_by_name_dylibloader_wrapper_pulse
+#define pa_context_get_source_info_by_index pa_context_get_source_info_by_index_dylibloader_wrapper_pulse
+#define pa_context_get_source_info_list pa_context_get_source_info_list_dylibloader_wrapper_pulse
+#define pa_context_set_source_volume_by_index pa_context_set_source_volume_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_source_volume_by_name pa_context_set_source_volume_by_name_dylibloader_wrapper_pulse
+#define pa_context_set_source_mute_by_index pa_context_set_source_mute_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_source_mute_by_name pa_context_set_source_mute_by_name_dylibloader_wrapper_pulse
+#define pa_context_suspend_source_by_name pa_context_suspend_source_by_name_dylibloader_wrapper_pulse
+#define pa_context_suspend_source_by_index pa_context_suspend_source_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_source_port_by_index pa_context_set_source_port_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_source_port_by_name pa_context_set_source_port_by_name_dylibloader_wrapper_pulse
+#define pa_context_get_server_info pa_context_get_server_info_dylibloader_wrapper_pulse
+#define pa_context_get_module_info pa_context_get_module_info_dylibloader_wrapper_pulse
+#define pa_context_get_module_info_list pa_context_get_module_info_list_dylibloader_wrapper_pulse
+#define pa_context_load_module pa_context_load_module_dylibloader_wrapper_pulse
+#define pa_context_unload_module pa_context_unload_module_dylibloader_wrapper_pulse
+#define pa_context_get_client_info pa_context_get_client_info_dylibloader_wrapper_pulse
+#define pa_context_get_client_info_list pa_context_get_client_info_list_dylibloader_wrapper_pulse
+#define pa_context_kill_client pa_context_kill_client_dylibloader_wrapper_pulse
+#define pa_context_get_card_info_by_index pa_context_get_card_info_by_index_dylibloader_wrapper_pulse
+#define pa_context_get_card_info_by_name pa_context_get_card_info_by_name_dylibloader_wrapper_pulse
+#define pa_context_get_card_info_list pa_context_get_card_info_list_dylibloader_wrapper_pulse
+#define pa_context_set_card_profile_by_index pa_context_set_card_profile_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_card_profile_by_name pa_context_set_card_profile_by_name_dylibloader_wrapper_pulse
+#define pa_context_set_port_latency_offset pa_context_set_port_latency_offset_dylibloader_wrapper_pulse
+#define pa_context_get_sink_input_info pa_context_get_sink_input_info_dylibloader_wrapper_pulse
+#define pa_context_get_sink_input_info_list pa_context_get_sink_input_info_list_dylibloader_wrapper_pulse
+#define pa_context_move_sink_input_by_name pa_context_move_sink_input_by_name_dylibloader_wrapper_pulse
+#define pa_context_move_sink_input_by_index pa_context_move_sink_input_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_sink_input_volume pa_context_set_sink_input_volume_dylibloader_wrapper_pulse
+#define pa_context_set_sink_input_mute pa_context_set_sink_input_mute_dylibloader_wrapper_pulse
+#define pa_context_kill_sink_input pa_context_kill_sink_input_dylibloader_wrapper_pulse
+#define pa_context_get_source_output_info pa_context_get_source_output_info_dylibloader_wrapper_pulse
+#define pa_context_get_source_output_info_list pa_context_get_source_output_info_list_dylibloader_wrapper_pulse
+#define pa_context_move_source_output_by_name pa_context_move_source_output_by_name_dylibloader_wrapper_pulse
+#define pa_context_move_source_output_by_index pa_context_move_source_output_by_index_dylibloader_wrapper_pulse
+#define pa_context_set_source_output_volume pa_context_set_source_output_volume_dylibloader_wrapper_pulse
+#define pa_context_set_source_output_mute pa_context_set_source_output_mute_dylibloader_wrapper_pulse
+#define pa_context_kill_source_output pa_context_kill_source_output_dylibloader_wrapper_pulse
+#define pa_context_stat pa_context_stat_dylibloader_wrapper_pulse
+#define pa_context_get_sample_info_by_name pa_context_get_sample_info_by_name_dylibloader_wrapper_pulse
+#define pa_context_get_sample_info_by_index pa_context_get_sample_info_by_index_dylibloader_wrapper_pulse
+#define pa_context_get_sample_info_list pa_context_get_sample_info_list_dylibloader_wrapper_pulse
+#define pa_context_get_autoload_info_by_name pa_context_get_autoload_info_by_name_dylibloader_wrapper_pulse
+#define pa_context_get_autoload_info_by_index pa_context_get_autoload_info_by_index_dylibloader_wrapper_pulse
+#define pa_context_get_autoload_info_list pa_context_get_autoload_info_list_dylibloader_wrapper_pulse
+#define pa_context_add_autoload pa_context_add_autoload_dylibloader_wrapper_pulse
+#define pa_context_remove_autoload_by_name pa_context_remove_autoload_by_name_dylibloader_wrapper_pulse
+#define pa_context_remove_autoload_by_index pa_context_remove_autoload_by_index_dylibloader_wrapper_pulse
+#define pa_context_subscribe pa_context_subscribe_dylibloader_wrapper_pulse
+#define pa_context_set_subscribe_callback pa_context_set_subscribe_callback_dylibloader_wrapper_pulse
+#define pa_stream_connect_upload pa_stream_connect_upload_dylibloader_wrapper_pulse
+#define pa_stream_finish_upload pa_stream_finish_upload_dylibloader_wrapper_pulse
+#define pa_context_remove_sample pa_context_remove_sample_dylibloader_wrapper_pulse
+#define pa_context_play_sample pa_context_play_sample_dylibloader_wrapper_pulse
+#define pa_context_play_sample_with_proplist pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse
+#define pa_strerror pa_strerror_dylibloader_wrapper_pulse
+#define pa_xmalloc pa_xmalloc_dylibloader_wrapper_pulse
+#define pa_xmalloc0 pa_xmalloc0_dylibloader_wrapper_pulse
+#define pa_xrealloc pa_xrealloc_dylibloader_wrapper_pulse
+#define pa_xfree pa_xfree_dylibloader_wrapper_pulse
+#define pa_xstrdup pa_xstrdup_dylibloader_wrapper_pulse
+#define pa_xstrndup pa_xstrndup_dylibloader_wrapper_pulse
+#define pa_xmemdup pa_xmemdup_dylibloader_wrapper_pulse
+#define pa_utf8_valid pa_utf8_valid_dylibloader_wrapper_pulse
+#define pa_ascii_valid pa_ascii_valid_dylibloader_wrapper_pulse
+#define pa_utf8_filter pa_utf8_filter_dylibloader_wrapper_pulse
+#define pa_ascii_filter pa_ascii_filter_dylibloader_wrapper_pulse
+#define pa_utf8_to_locale pa_utf8_to_locale_dylibloader_wrapper_pulse
+#define pa_locale_to_utf8 pa_locale_to_utf8_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_new pa_threaded_mainloop_new_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_free pa_threaded_mainloop_free_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_start pa_threaded_mainloop_start_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_stop pa_threaded_mainloop_stop_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_lock pa_threaded_mainloop_lock_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_unlock pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_wait pa_threaded_mainloop_wait_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_signal pa_threaded_mainloop_signal_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_accept pa_threaded_mainloop_accept_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_get_retval pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse
+#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse
+#define pa_mainloop_new pa_mainloop_new_dylibloader_wrapper_pulse
+#define pa_mainloop_free pa_mainloop_free_dylibloader_wrapper_pulse
+#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_wrapper_pulse
+#define pa_mainloop_poll pa_mainloop_poll_dylibloader_wrapper_pulse
+#define pa_mainloop_dispatch pa_mainloop_dispatch_dylibloader_wrapper_pulse
+#define pa_mainloop_get_retval pa_mainloop_get_retval_dylibloader_wrapper_pulse
+#define pa_mainloop_iterate pa_mainloop_iterate_dylibloader_wrapper_pulse
+#define pa_mainloop_run pa_mainloop_run_dylibloader_wrapper_pulse
+#define pa_mainloop_get_api pa_mainloop_get_api_dylibloader_wrapper_pulse
+#define pa_mainloop_quit pa_mainloop_quit_dylibloader_wrapper_pulse
+#define pa_mainloop_wakeup pa_mainloop_wakeup_dylibloader_wrapper_pulse
+#define pa_mainloop_set_poll_func pa_mainloop_set_poll_func_dylibloader_wrapper_pulse
+#define pa_signal_init pa_signal_init_dylibloader_wrapper_pulse
+#define pa_signal_done pa_signal_done_dylibloader_wrapper_pulse
+#define pa_signal_new pa_signal_new_dylibloader_wrapper_pulse
+#define pa_signal_free pa_signal_free_dylibloader_wrapper_pulse
+#define pa_signal_set_destroy pa_signal_set_destroy_dylibloader_wrapper_pulse
+#define pa_get_user_name pa_get_user_name_dylibloader_wrapper_pulse
+#define pa_get_host_name pa_get_host_name_dylibloader_wrapper_pulse
+#define pa_get_fqdn pa_get_fqdn_dylibloader_wrapper_pulse
+#define pa_get_home_dir pa_get_home_dir_dylibloader_wrapper_pulse
+#define pa_get_binary_name pa_get_binary_name_dylibloader_wrapper_pulse
+#define pa_path_get_filename pa_path_get_filename_dylibloader_wrapper_pulse
+#define pa_msleep pa_msleep_dylibloader_wrapper_pulse
+#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_wrapper_pulse
+#define pa_gettimeofday pa_gettimeofday_dylibloader_wrapper_pulse
+#define pa_timeval_diff pa_timeval_diff_dylibloader_wrapper_pulse
+#define pa_timeval_cmp pa_timeval_cmp_dylibloader_wrapper_pulse
+#define pa_timeval_age pa_timeval_age_dylibloader_wrapper_pulse
+#define pa_timeval_add pa_timeval_add_dylibloader_wrapper_pulse
+#define pa_timeval_sub pa_timeval_sub_dylibloader_wrapper_pulse
+#define pa_timeval_store pa_timeval_store_dylibloader_wrapper_pulse
+#define pa_timeval_load pa_timeval_load_dylibloader_wrapper_pulse
+#define pa_rtclock_now pa_rtclock_now_dylibloader_wrapper_pulse
+extern const char* (*pa_get_library_version_dylibloader_wrapper_pulse)( void);
+extern size_t (*pa_bytes_per_second_dylibloader_wrapper_pulse)(const pa_sample_spec*);
+extern size_t (*pa_frame_size_dylibloader_wrapper_pulse)(const pa_sample_spec*);
+extern size_t (*pa_sample_size_dylibloader_wrapper_pulse)(const pa_sample_spec*);
+extern size_t (*pa_sample_size_of_format_dylibloader_wrapper_pulse)( pa_sample_format_t);
+extern pa_usec_t (*pa_bytes_to_usec_dylibloader_wrapper_pulse)( uint64_t,const pa_sample_spec*);
+extern size_t (*pa_usec_to_bytes_dylibloader_wrapper_pulse)( pa_usec_t,const pa_sample_spec*);
+extern pa_sample_spec* (*pa_sample_spec_init_dylibloader_wrapper_pulse)( pa_sample_spec*);
+extern int (*pa_sample_format_valid_dylibloader_wrapper_pulse)( unsigned);
+extern int (*pa_sample_rate_valid_dylibloader_wrapper_pulse)( uint32_t);
+extern int (*pa_channels_valid_dylibloader_wrapper_pulse)( uint8_t);
+extern int (*pa_sample_spec_valid_dylibloader_wrapper_pulse)(const pa_sample_spec*);
+extern int (*pa_sample_spec_equal_dylibloader_wrapper_pulse)(const pa_sample_spec*,const pa_sample_spec*);
+extern const char* (*pa_sample_format_to_string_dylibloader_wrapper_pulse)( pa_sample_format_t);
+extern pa_sample_format_t (*pa_parse_sample_format_dylibloader_wrapper_pulse)(const char*);
+extern char* (*pa_sample_spec_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_sample_spec*);
+extern char* (*pa_bytes_snprint_dylibloader_wrapper_pulse)( char*, size_t, unsigned);
+extern int (*pa_sample_format_is_le_dylibloader_wrapper_pulse)( pa_sample_format_t);
+extern int (*pa_sample_format_is_be_dylibloader_wrapper_pulse)( pa_sample_format_t);
+extern int (*pa_direction_valid_dylibloader_wrapper_pulse)( pa_direction_t);
+extern const char* (*pa_direction_to_string_dylibloader_wrapper_pulse)( pa_direction_t);
+extern void (*pa_mainloop_api_once_dylibloader_wrapper_pulse)( pa_mainloop_api*, void*, void*);
+extern pa_proplist* (*pa_proplist_new_dylibloader_wrapper_pulse)( void);
+extern void (*pa_proplist_free_dylibloader_wrapper_pulse)( pa_proplist*);
+extern int (*pa_proplist_key_valid_dylibloader_wrapper_pulse)(const char*);
+extern int (*pa_proplist_sets_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*);
+extern int (*pa_proplist_setp_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
+extern int (*pa_proplist_setf_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*,...);
+extern int (*pa_proplist_set_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const void*, size_t);
+extern const char* (*pa_proplist_gets_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+extern int (*pa_proplist_get_dylibloader_wrapper_pulse)(const pa_proplist*,const char*,const void**, size_t*);
+extern void (*pa_proplist_update_dylibloader_wrapper_pulse)( pa_proplist*, pa_update_mode_t,const pa_proplist*);
+extern int (*pa_proplist_unset_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
+extern int (*pa_proplist_unset_many_dylibloader_wrapper_pulse)( pa_proplist*,const char* []);
+extern const char* (*pa_proplist_iterate_dylibloader_wrapper_pulse)(const pa_proplist*, void**);
+extern char* (*pa_proplist_to_string_dylibloader_wrapper_pulse)(const pa_proplist*);
+extern char* (*pa_proplist_to_string_sep_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+extern pa_proplist* (*pa_proplist_from_string_dylibloader_wrapper_pulse)(const char*);
+extern int (*pa_proplist_contains_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+extern void (*pa_proplist_clear_dylibloader_wrapper_pulse)( pa_proplist*);
+extern pa_proplist* (*pa_proplist_copy_dylibloader_wrapper_pulse)(const pa_proplist*);
+extern unsigned (*pa_proplist_size_dylibloader_wrapper_pulse)(const pa_proplist*);
+extern int (*pa_proplist_isempty_dylibloader_wrapper_pulse)(const pa_proplist*);
+extern int (*pa_proplist_equal_dylibloader_wrapper_pulse)(const pa_proplist*,const pa_proplist*);
+extern pa_channel_map* (*pa_channel_map_init_dylibloader_wrapper_pulse)( pa_channel_map*);
+extern pa_channel_map* (*pa_channel_map_init_mono_dylibloader_wrapper_pulse)( pa_channel_map*);
+extern pa_channel_map* (*pa_channel_map_init_stereo_dylibloader_wrapper_pulse)( pa_channel_map*);
+extern pa_channel_map* (*pa_channel_map_init_auto_dylibloader_wrapper_pulse)( pa_channel_map*, unsigned, pa_channel_map_def_t);
+extern pa_channel_map* (*pa_channel_map_init_extend_dylibloader_wrapper_pulse)( pa_channel_map*, unsigned, pa_channel_map_def_t);
+extern const char* (*pa_channel_position_to_string_dylibloader_wrapper_pulse)( pa_channel_position_t);
+extern pa_channel_position_t (*pa_channel_position_from_string_dylibloader_wrapper_pulse)(const char*);
+extern const char* (*pa_channel_position_to_pretty_string_dylibloader_wrapper_pulse)( pa_channel_position_t);
+extern char* (*pa_channel_map_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_channel_map*);
+extern pa_channel_map* (*pa_channel_map_parse_dylibloader_wrapper_pulse)( pa_channel_map*,const char*);
+extern int (*pa_channel_map_equal_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_channel_map*);
+extern int (*pa_channel_map_valid_dylibloader_wrapper_pulse)(const pa_channel_map*);
+extern int (*pa_channel_map_compatible_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_sample_spec*);
+extern int (*pa_channel_map_superset_dylibloader_wrapper_pulse)(const pa_channel_map*,const pa_channel_map*);
+extern int (*pa_channel_map_can_balance_dylibloader_wrapper_pulse)(const pa_channel_map*);
+extern int (*pa_channel_map_can_fade_dylibloader_wrapper_pulse)(const pa_channel_map*);
+extern int (*pa_channel_map_can_lfe_balance_dylibloader_wrapper_pulse)(const pa_channel_map*);
+extern const char* (*pa_channel_map_to_name_dylibloader_wrapper_pulse)(const pa_channel_map*);
+extern const char* (*pa_channel_map_to_pretty_name_dylibloader_wrapper_pulse)(const pa_channel_map*);
+extern int (*pa_channel_map_has_position_dylibloader_wrapper_pulse)(const pa_channel_map*, pa_channel_position_t);
+extern pa_channel_position_mask_t (*pa_channel_map_mask_dylibloader_wrapper_pulse)(const pa_channel_map*);
+extern const char* (*pa_encoding_to_string_dylibloader_wrapper_pulse)( pa_encoding_t);
+extern pa_encoding_t (*pa_encoding_from_string_dylibloader_wrapper_pulse)(const char*);
+extern pa_format_info* (*pa_format_info_new_dylibloader_wrapper_pulse)( void);
+extern pa_format_info* (*pa_format_info_copy_dylibloader_wrapper_pulse)(const pa_format_info*);
+extern void (*pa_format_info_free_dylibloader_wrapper_pulse)( pa_format_info*);
+extern int (*pa_format_info_valid_dylibloader_wrapper_pulse)(const pa_format_info*);
+extern int (*pa_format_info_is_pcm_dylibloader_wrapper_pulse)(const pa_format_info*);
+extern int (*pa_format_info_is_compatible_dylibloader_wrapper_pulse)(const pa_format_info*,const pa_format_info*);
+extern char* (*pa_format_info_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_format_info*);
+extern pa_format_info* (*pa_format_info_from_string_dylibloader_wrapper_pulse)(const char*);
+extern pa_format_info* (*pa_format_info_from_sample_spec_dylibloader_wrapper_pulse)(const pa_sample_spec*,const pa_channel_map*);
+extern int (*pa_format_info_to_sample_spec_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_spec*, pa_channel_map*);
+extern pa_prop_type_t (*pa_format_info_get_prop_type_dylibloader_wrapper_pulse)(const pa_format_info*,const char*);
+extern int (*pa_format_info_get_prop_int_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int*);
+extern int (*pa_format_info_get_prop_int_range_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int*, int*);
+extern int (*pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, int**, int*);
+extern int (*pa_format_info_get_prop_string_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char**);
+extern int (*pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char***, int*);
+extern void (*pa_format_info_free_string_array_dylibloader_wrapper_pulse)( char**, int);
+extern int (*pa_format_info_get_sample_format_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_format_t*);
+extern int (*pa_format_info_get_rate_dylibloader_wrapper_pulse)(const pa_format_info*, uint32_t*);
+extern int (*pa_format_info_get_channels_dylibloader_wrapper_pulse)(const pa_format_info*, uint8_t*);
+extern int (*pa_format_info_get_channel_map_dylibloader_wrapper_pulse)(const pa_format_info*, pa_channel_map*);
+extern void (*pa_format_info_set_prop_int_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int);
+extern void (*pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const int*, int);
+extern void (*pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int, int);
+extern void (*pa_format_info_set_prop_string_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const char*);
+extern void (*pa_format_info_set_prop_string_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const char**, int);
+extern void (*pa_format_info_set_sample_format_dylibloader_wrapper_pulse)( pa_format_info*, pa_sample_format_t);
+extern void (*pa_format_info_set_rate_dylibloader_wrapper_pulse)( pa_format_info*, int);
+extern void (*pa_format_info_set_channels_dylibloader_wrapper_pulse)( pa_format_info*, int);
+extern void (*pa_format_info_set_channel_map_dylibloader_wrapper_pulse)( pa_format_info*,const pa_channel_map*);
+extern pa_operation* (*pa_operation_ref_dylibloader_wrapper_pulse)( pa_operation*);
+extern void (*pa_operation_unref_dylibloader_wrapper_pulse)( pa_operation*);
+extern void (*pa_operation_cancel_dylibloader_wrapper_pulse)( pa_operation*);
+extern pa_operation_state_t (*pa_operation_get_state_dylibloader_wrapper_pulse)(const pa_operation*);
+extern void (*pa_operation_set_state_callback_dylibloader_wrapper_pulse)( pa_operation*, pa_operation_notify_cb_t, void*);
+extern pa_context* (*pa_context_new_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*);
+extern pa_context* (*pa_context_new_with_proplist_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*,const pa_proplist*);
+extern void (*pa_context_unref_dylibloader_wrapper_pulse)( pa_context*);
+extern pa_context* (*pa_context_ref_dylibloader_wrapper_pulse)( pa_context*);
+extern void (*pa_context_set_state_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*);
+extern void (*pa_context_set_event_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_event_cb_t, void*);
+extern int (*pa_context_errno_dylibloader_wrapper_pulse)(const pa_context*);
+extern int (*pa_context_is_pending_dylibloader_wrapper_pulse)(const pa_context*);
+extern pa_context_state_t (*pa_context_get_state_dylibloader_wrapper_pulse)(const pa_context*);
+extern int (*pa_context_connect_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_flags_t,const pa_spawn_api*);
+extern void (*pa_context_disconnect_dylibloader_wrapper_pulse)( pa_context*);
+extern pa_operation* (*pa_context_drain_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*);
+extern pa_operation* (*pa_context_exit_daemon_dylibloader_wrapper_pulse)( pa_context*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_default_sink_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_default_source_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
+extern int (*pa_context_is_local_dylibloader_wrapper_pulse)(const pa_context*);
+extern pa_operation* (*pa_context_set_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
+extern const char* (*pa_context_get_server_dylibloader_wrapper_pulse)(const pa_context*);
+extern uint32_t (*pa_context_get_protocol_version_dylibloader_wrapper_pulse)(const pa_context*);
+extern uint32_t (*pa_context_get_server_protocol_version_dylibloader_wrapper_pulse)(const pa_context*);
+extern pa_operation* (*pa_context_proplist_update_dylibloader_wrapper_pulse)( pa_context*, pa_update_mode_t,const pa_proplist*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_proplist_remove_dylibloader_wrapper_pulse)( pa_context*,const char* [], pa_context_success_cb_t, void*);
+extern uint32_t (*pa_context_get_index_dylibloader_wrapper_pulse)(const pa_context*);
+extern pa_time_event* (*pa_context_rttime_new_dylibloader_wrapper_pulse)(const pa_context*, pa_usec_t, pa_time_event_cb_t, void*);
+extern void (*pa_context_rttime_restart_dylibloader_wrapper_pulse)(const pa_context*, pa_time_event*, pa_usec_t);
+extern size_t (*pa_context_get_tile_size_dylibloader_wrapper_pulse)(const pa_context*,const pa_sample_spec*);
+extern int (*pa_context_load_cookie_from_file_dylibloader_wrapper_pulse)( pa_context*,const char*);
+extern int (*pa_cvolume_equal_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_cvolume*);
+extern pa_cvolume* (*pa_cvolume_init_dylibloader_wrapper_pulse)( pa_cvolume*);
+extern pa_cvolume* (*pa_cvolume_set_dylibloader_wrapper_pulse)( pa_cvolume*, unsigned, pa_volume_t);
+extern char* (*pa_cvolume_snprint_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*);
+extern char* (*pa_sw_cvolume_snprint_dB_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*);
+extern char* (*pa_cvolume_snprint_verbose_dylibloader_wrapper_pulse)( char*, size_t,const pa_cvolume*,const pa_channel_map*, int);
+extern char* (*pa_volume_snprint_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t);
+extern char* (*pa_sw_volume_snprint_dB_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t);
+extern char* (*pa_volume_snprint_verbose_dylibloader_wrapper_pulse)( char*, size_t, pa_volume_t, int);
+extern pa_volume_t (*pa_cvolume_avg_dylibloader_wrapper_pulse)(const pa_cvolume*);
+extern pa_volume_t (*pa_cvolume_avg_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t);
+extern pa_volume_t (*pa_cvolume_max_dylibloader_wrapper_pulse)(const pa_cvolume*);
+extern pa_volume_t (*pa_cvolume_max_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t);
+extern pa_volume_t (*pa_cvolume_min_dylibloader_wrapper_pulse)(const pa_cvolume*);
+extern pa_volume_t (*pa_cvolume_min_mask_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_mask_t);
+extern int (*pa_cvolume_valid_dylibloader_wrapper_pulse)(const pa_cvolume*);
+extern int (*pa_cvolume_channels_equal_to_dylibloader_wrapper_pulse)(const pa_cvolume*, pa_volume_t);
+extern pa_volume_t (*pa_sw_volume_multiply_dylibloader_wrapper_pulse)( pa_volume_t, pa_volume_t);
+extern pa_cvolume* (*pa_sw_cvolume_multiply_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*);
+extern pa_cvolume* (*pa_sw_cvolume_multiply_scalar_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*, pa_volume_t);
+extern pa_volume_t (*pa_sw_volume_divide_dylibloader_wrapper_pulse)( pa_volume_t, pa_volume_t);
+extern pa_cvolume* (*pa_sw_cvolume_divide_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*);
+extern pa_cvolume* (*pa_sw_cvolume_divide_scalar_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*, pa_volume_t);
+extern pa_volume_t (*pa_sw_volume_from_dB_dylibloader_wrapper_pulse)( double);
+extern double (*pa_sw_volume_to_dB_dylibloader_wrapper_pulse)( pa_volume_t);
+extern pa_volume_t (*pa_sw_volume_from_linear_dylibloader_wrapper_pulse)( double);
+extern double (*pa_sw_volume_to_linear_dylibloader_wrapper_pulse)( pa_volume_t);
+extern pa_cvolume* (*pa_cvolume_remap_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*,const pa_channel_map*);
+extern int (*pa_cvolume_compatible_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_sample_spec*);
+extern int (*pa_cvolume_compatible_with_channel_map_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
+extern float (*pa_cvolume_get_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
+extern pa_cvolume* (*pa_cvolume_set_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float);
+extern float (*pa_cvolume_get_fade_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
+extern pa_cvolume* (*pa_cvolume_set_fade_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float);
+extern float (*pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
+extern pa_cvolume* (*pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float);
+extern pa_cvolume* (*pa_cvolume_scale_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
+extern pa_cvolume* (*pa_cvolume_scale_mask_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t,const pa_channel_map*, pa_channel_position_mask_t);
+extern pa_cvolume* (*pa_cvolume_set_position_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, pa_channel_position_t, pa_volume_t);
+extern pa_volume_t (*pa_cvolume_get_position_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_t);
+extern pa_cvolume* (*pa_cvolume_merge_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*);
+extern pa_cvolume* (*pa_cvolume_inc_clamp_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t, pa_volume_t);
+extern pa_cvolume* (*pa_cvolume_inc_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
+extern pa_cvolume* (*pa_cvolume_dec_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
+extern pa_stream* (*pa_stream_new_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_sample_spec*,const pa_channel_map*);
+extern pa_stream* (*pa_stream_new_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_sample_spec*,const pa_channel_map*, pa_proplist*);
+extern pa_stream* (*pa_stream_new_extended_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_format_info**, unsigned int, pa_proplist*);
+extern void (*pa_stream_unref_dylibloader_wrapper_pulse)( pa_stream*);
+extern pa_stream* (*pa_stream_ref_dylibloader_wrapper_pulse)( pa_stream*);
+extern pa_stream_state_t (*pa_stream_get_state_dylibloader_wrapper_pulse)(const pa_stream*);
+extern pa_context* (*pa_stream_get_context_dylibloader_wrapper_pulse)(const pa_stream*);
+extern uint32_t (*pa_stream_get_index_dylibloader_wrapper_pulse)(const pa_stream*);
+extern uint32_t (*pa_stream_get_device_index_dylibloader_wrapper_pulse)(const pa_stream*);
+extern const char* (*pa_stream_get_device_name_dylibloader_wrapper_pulse)(const pa_stream*);
+extern int (*pa_stream_is_suspended_dylibloader_wrapper_pulse)(const pa_stream*);
+extern int (*pa_stream_is_corked_dylibloader_wrapper_pulse)(const pa_stream*);
+extern int (*pa_stream_connect_playback_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t,const pa_cvolume*, pa_stream*);
+extern int (*pa_stream_connect_record_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t);
+extern int (*pa_stream_disconnect_dylibloader_wrapper_pulse)( pa_stream*);
+extern int (*pa_stream_begin_write_dylibloader_wrapper_pulse)( pa_stream*, void**, size_t*);
+extern int (*pa_stream_cancel_write_dylibloader_wrapper_pulse)( pa_stream*);
+extern int (*pa_stream_write_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, int64_t, pa_seek_mode_t);
+extern int (*pa_stream_write_ext_free_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, void*, int64_t, pa_seek_mode_t);
+extern int (*pa_stream_peek_dylibloader_wrapper_pulse)( pa_stream*,const void**, size_t*);
+extern int (*pa_stream_drop_dylibloader_wrapper_pulse)( pa_stream*);
+extern size_t (*pa_stream_writable_size_dylibloader_wrapper_pulse)(const pa_stream*);
+extern size_t (*pa_stream_readable_size_dylibloader_wrapper_pulse)(const pa_stream*);
+extern pa_operation* (*pa_stream_drain_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+extern pa_operation* (*pa_stream_update_timing_info_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+extern void (*pa_stream_set_state_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+extern void (*pa_stream_set_write_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*);
+extern void (*pa_stream_set_read_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*);
+extern void (*pa_stream_set_overflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+extern int64_t (*pa_stream_get_underflow_index_dylibloader_wrapper_pulse)(const pa_stream*);
+extern void (*pa_stream_set_underflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+extern void (*pa_stream_set_started_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+extern void (*pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+extern void (*pa_stream_set_moved_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+extern void (*pa_stream_set_suspended_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+extern void (*pa_stream_set_event_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_event_cb_t, void*);
+extern void (*pa_stream_set_buffer_attr_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
+extern pa_operation* (*pa_stream_cork_dylibloader_wrapper_pulse)( pa_stream*, int, pa_stream_success_cb_t, void*);
+extern pa_operation* (*pa_stream_flush_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+extern pa_operation* (*pa_stream_prebuf_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+extern pa_operation* (*pa_stream_trigger_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
+extern pa_operation* (*pa_stream_set_name_dylibloader_wrapper_pulse)( pa_stream*,const char*, pa_stream_success_cb_t, void*);
+extern int (*pa_stream_get_time_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*);
+extern int (*pa_stream_get_latency_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*, int*);
+extern const pa_timing_info* (*pa_stream_get_timing_info_dylibloader_wrapper_pulse)( pa_stream*);
+extern const pa_sample_spec* (*pa_stream_get_sample_spec_dylibloader_wrapper_pulse)( pa_stream*);
+extern const pa_channel_map* (*pa_stream_get_channel_map_dylibloader_wrapper_pulse)( pa_stream*);
+extern const pa_format_info* (*pa_stream_get_format_info_dylibloader_wrapper_pulse)(const pa_stream*);
+extern const pa_buffer_attr* (*pa_stream_get_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*);
+extern pa_operation* (*pa_stream_set_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*,const pa_buffer_attr*, pa_stream_success_cb_t, void*);
+extern pa_operation* (*pa_stream_update_sample_rate_dylibloader_wrapper_pulse)( pa_stream*, uint32_t, pa_stream_success_cb_t, void*);
+extern pa_operation* (*pa_stream_proplist_update_dylibloader_wrapper_pulse)( pa_stream*, pa_update_mode_t, pa_proplist*, pa_stream_success_cb_t, void*);
+extern pa_operation* (*pa_stream_proplist_remove_dylibloader_wrapper_pulse)( pa_stream*,const char* [], pa_stream_success_cb_t, void*);
+extern int (*pa_stream_set_monitor_stream_dylibloader_wrapper_pulse)( pa_stream*, uint32_t);
+extern uint32_t (*pa_stream_get_monitor_stream_dylibloader_wrapper_pulse)(const pa_stream*);
+extern pa_operation* (*pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sink_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_sink_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_info_cb_t, void*);
+extern pa_operation* (*pa_context_set_sink_volume_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_sink_volume_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_cvolume*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_sink_mute_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_sink_mute_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_suspend_sink_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_suspend_sink_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_sink_port_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_sink_port_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_get_source_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_source_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_source_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_source_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_source_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_source_info_cb_t, void*);
+extern pa_operation* (*pa_context_set_source_volume_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_source_volume_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const pa_cvolume*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_source_mute_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_source_mute_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_suspend_source_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_suspend_source_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_source_port_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_source_port_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_get_server_info_dylibloader_wrapper_pulse)( pa_context*, pa_server_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_module_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_module_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_module_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_module_info_cb_t, void*);
+extern pa_operation* (*pa_context_load_module_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_index_cb_t, void*);
+extern pa_operation* (*pa_context_unload_module_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_get_client_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_client_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_client_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_client_info_cb_t, void*);
+extern pa_operation* (*pa_context_kill_client_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_get_card_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_card_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_card_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_card_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_card_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_card_info_cb_t, void*);
+extern pa_operation* (*pa_context_set_card_profile_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_card_profile_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_port_latency_offset_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, int64_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_get_sink_input_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_input_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_sink_input_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_input_info_cb_t, void*);
+extern pa_operation* (*pa_context_move_sink_input_by_name_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_move_sink_input_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, uint32_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_sink_input_volume_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_sink_input_mute_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_kill_sink_input_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_get_source_output_info_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_source_output_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_source_output_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_source_output_info_cb_t, void*);
+extern pa_operation* (*pa_context_move_source_output_by_name_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_move_source_output_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, uint32_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_source_output_volume_dylibloader_wrapper_pulse)( pa_context*, uint32_t,const pa_cvolume*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_set_source_output_mute_dylibloader_wrapper_pulse)( pa_context*, uint32_t, int, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_kill_source_output_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_stat_dylibloader_wrapper_pulse)( pa_context*, pa_stat_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_sample_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sample_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_sample_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sample_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_sample_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sample_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_autoload_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t, pa_autoload_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_autoload_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_autoload_info_cb_t, void*);
+extern pa_operation* (*pa_context_get_autoload_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_autoload_info_cb_t, void*);
+extern pa_operation* (*pa_context_add_autoload_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t,const char*,const char*, pa_context_index_cb_t, void*);
+extern pa_operation* (*pa_context_remove_autoload_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_autoload_type_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_remove_autoload_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_subscribe_dylibloader_wrapper_pulse)( pa_context*, pa_subscription_mask_t, pa_context_success_cb_t, void*);
+extern void (*pa_context_set_subscribe_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_subscribe_cb_t, void*);
+extern int (*pa_stream_connect_upload_dylibloader_wrapper_pulse)( pa_stream*, size_t);
+extern int (*pa_stream_finish_upload_dylibloader_wrapper_pulse)( pa_stream*);
+extern pa_operation* (*pa_context_remove_sample_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_play_sample_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t, pa_context_success_cb_t, void*);
+extern pa_operation* (*pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t,const pa_proplist*, pa_context_play_sample_cb_t, void*);
+extern const char* (*pa_strerror_dylibloader_wrapper_pulse)( int);
+extern void* (*pa_xmalloc_dylibloader_wrapper_pulse)( size_t);
+extern void* (*pa_xmalloc0_dylibloader_wrapper_pulse)( size_t);
+extern void* (*pa_xrealloc_dylibloader_wrapper_pulse)( void*, size_t);
+extern void (*pa_xfree_dylibloader_wrapper_pulse)( void*);
+extern char* (*pa_xstrdup_dylibloader_wrapper_pulse)(const char*);
+extern char* (*pa_xstrndup_dylibloader_wrapper_pulse)(const char*, size_t);
+extern void* (*pa_xmemdup_dylibloader_wrapper_pulse)(const void*, size_t);
+extern char* (*pa_utf8_valid_dylibloader_wrapper_pulse)(const char*);
+extern char* (*pa_ascii_valid_dylibloader_wrapper_pulse)(const char*);
+extern char* (*pa_utf8_filter_dylibloader_wrapper_pulse)(const char*);
+extern char* (*pa_ascii_filter_dylibloader_wrapper_pulse)(const char*);
+extern char* (*pa_utf8_to_locale_dylibloader_wrapper_pulse)(const char*);
+extern char* (*pa_locale_to_utf8_dylibloader_wrapper_pulse)(const char*);
+extern pa_threaded_mainloop* (*pa_threaded_mainloop_new_dylibloader_wrapper_pulse)( void);
+extern void (*pa_threaded_mainloop_free_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern int (*pa_threaded_mainloop_start_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern void (*pa_threaded_mainloop_stop_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern void (*pa_threaded_mainloop_lock_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern void (*pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern void (*pa_threaded_mainloop_wait_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern void (*pa_threaded_mainloop_signal_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, int);
+extern void (*pa_threaded_mainloop_accept_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern int (*pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_threaded_mainloop*);
+extern pa_mainloop_api* (*pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern int (*pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
+extern void (*pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse)( pa_threaded_mainloop*,const char*);
+extern void (*pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, void*, void*);
+extern pa_mainloop* (*pa_mainloop_new_dylibloader_wrapper_pulse)( void);
+extern void (*pa_mainloop_free_dylibloader_wrapper_pulse)( pa_mainloop*);
+extern int (*pa_mainloop_prepare_dylibloader_wrapper_pulse)( pa_mainloop*, int);
+extern int (*pa_mainloop_poll_dylibloader_wrapper_pulse)( pa_mainloop*);
+extern int (*pa_mainloop_dispatch_dylibloader_wrapper_pulse)( pa_mainloop*);
+extern int (*pa_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_mainloop*);
+extern int (*pa_mainloop_iterate_dylibloader_wrapper_pulse)( pa_mainloop*, int, int*);
+extern int (*pa_mainloop_run_dylibloader_wrapper_pulse)( pa_mainloop*, int*);
+extern pa_mainloop_api* (*pa_mainloop_get_api_dylibloader_wrapper_pulse)( pa_mainloop*);
+extern void (*pa_mainloop_quit_dylibloader_wrapper_pulse)( pa_mainloop*, int);
+extern void (*pa_mainloop_wakeup_dylibloader_wrapper_pulse)( pa_mainloop*);
+extern void (*pa_mainloop_set_poll_func_dylibloader_wrapper_pulse)( pa_mainloop*, pa_poll_func, void*);
+extern int (*pa_signal_init_dylibloader_wrapper_pulse)( pa_mainloop_api*);
+extern void (*pa_signal_done_dylibloader_wrapper_pulse)( void);
+extern pa_signal_event* (*pa_signal_new_dylibloader_wrapper_pulse)( int, pa_signal_cb_t, void*);
+extern void (*pa_signal_free_dylibloader_wrapper_pulse)( pa_signal_event*);
+extern void (*pa_signal_set_destroy_dylibloader_wrapper_pulse)( pa_signal_event*, pa_signal_destroy_cb_t);
+extern char* (*pa_get_user_name_dylibloader_wrapper_pulse)( char*, size_t);
+extern char* (*pa_get_host_name_dylibloader_wrapper_pulse)( char*, size_t);
+extern char* (*pa_get_fqdn_dylibloader_wrapper_pulse)( char*, size_t);
+extern char* (*pa_get_home_dir_dylibloader_wrapper_pulse)( char*, size_t);
+extern char* (*pa_get_binary_name_dylibloader_wrapper_pulse)( char*, size_t);
+extern char* (*pa_path_get_filename_dylibloader_wrapper_pulse)(const char*);
+extern int (*pa_msleep_dylibloader_wrapper_pulse)( unsigned long);
+extern int (*pa_thread_make_realtime_dylibloader_wrapper_pulse)( int);
+extern struct timeval* (*pa_gettimeofday_dylibloader_wrapper_pulse)(struct timeval*);
+extern pa_usec_t (*pa_timeval_diff_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*);
+extern int (*pa_timeval_cmp_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*);
+extern pa_usec_t (*pa_timeval_age_dylibloader_wrapper_pulse)(struct timeval*);
+extern struct timeval* (*pa_timeval_add_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t);
+extern struct timeval* (*pa_timeval_sub_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t);
+extern struct timeval* (*pa_timeval_store_dylibloader_wrapper_pulse)(struct timeval*, pa_usec_t);
+extern pa_usec_t (*pa_timeval_load_dylibloader_wrapper_pulse)(struct timeval*);
+extern pa_usec_t (*pa_rtclock_now_dylibloader_wrapper_pulse)( void);
+int initialize_pulse(int verbose);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/drivers/register_driver_types.cpp b/drivers/register_driver_types.cpp
index f0deabec21..18262c74c4 100644
--- a/drivers/register_driver_types.cpp
+++ b/drivers/register_driver_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/register_driver_types.h b/drivers/register_driver_types.h
index c8dbdbb22d..607aa91cb8 100644
--- a/drivers/register_driver_types.h
+++ b/drivers/register_driver_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 63fa143a03..eda929850c 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -232,7 +232,7 @@ static void _get_drives(List<String> *list) {
// Parse only file:// links
if (strncmp(string, "file://", 7) == 0) {
// Strip any unwanted edges on the strings and push_back if it's not a duplicate
- String fpath = String(string + 7).strip_edges().split_spaces()[0].percent_decode();
+ String fpath = String(string + 7).strip_edges().split_spaces()[0].uri_decode();
if (!list->find(fpath)) {
list->push_back(fpath);
}
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index 90f98d4705..b70df1ca02 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index ce1e135fe0..6b24a85ff6 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 9fe43a2554..998fad7909 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index 94ea567c3b..8ec1de4386 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h
index 7497f64a53..ca2ee17f4e 100644
--- a/drivers/unix/ip_unix.h
+++ b/drivers/unix/ip_unix.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 0ee97256fc..19753943c8 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/net_socket_posix.h b/drivers/unix/net_socket_posix.h
index 8cefb6544e..cc6af661c8 100644
--- a/drivers/unix/net_socket_posix.h
+++ b/drivers/unix/net_socket_posix.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index ca08d689b9..b9bd773c2e 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,11 +35,9 @@
#include "core/config/project_settings.h"
#include "core/debugger/engine_debugger.h"
#include "core/debugger/script_debugger.h"
-#include "core/os/thread_dummy.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "drivers/unix/net_socket_posix.h"
-#include "drivers/unix/rw_lock_posix.h"
#include "drivers/unix/thread_posix.h"
#include "servers/rendering_server.h"
@@ -64,6 +62,7 @@
#include <string.h>
#include <sys/time.h>
#include <sys/wait.h>
+#include <time.h>
#include <unistd.h>
/// Clock Setup function (used by get_ticks_usec)
@@ -117,13 +116,10 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) {
}
void OS_Unix::initialize_core() {
-#ifdef NO_THREADS
- ThreadDummy::make_default();
- RWLockDummy::make_default();
-#else
- ThreadPosix::make_default();
- RWLockPosix::make_default();
+#if !defined(NO_THREADS)
+ init_thread_posix();
#endif
+
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM);
@@ -234,8 +230,11 @@ OS::TimeZoneInfo OS_Unix::get_time_zone_info() const {
}
void OS_Unix::delay_usec(uint32_t p_usec) const {
- struct timespec rem = { static_cast<time_t>(p_usec / 1000000), (static_cast<long>(p_usec) % 1000000) * 1000 };
- while (nanosleep(&rem, &rem) == EINTR) {
+ struct timespec requested = { static_cast<time_t>(p_usec / 1000000), (static_cast<long>(p_usec) % 1000000) * 1000 };
+ struct timespec remaining;
+ while (nanosleep(&requested, &remaining) == -1 && errno == EINTR) {
+ requested.tv_sec = remaining.tv_sec;
+ requested.tv_nsec = remaining.tv_nsec;
}
}
@@ -254,31 +253,26 @@ uint64_t OS_Unix::get_ticks_usec() const {
return longtime;
}
-Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
#ifdef __EMSCRIPTEN__
// Don't compile this code at all to avoid undefined references.
// Actual virtual call goes to OS_JavaScript.
ERR_FAIL_V(ERR_BUG);
#else
- if (p_blocking && r_pipe) {
- String argss;
- argss = "\"" + p_path + "\"";
-
+ if (r_pipe) {
+ String command = "\"" + p_path + "\"";
for (int i = 0; i < p_arguments.size(); i++) {
- argss += String(" \"") + p_arguments[i] + "\"";
+ command += String(" \"") + p_arguments[i] + "\"";
}
-
if (read_stderr) {
- argss += " 2>&1"; // Read stderr too
+ command += " 2>&1"; // Include stderr
} else {
- argss += " 2>/dev/null"; //silence stderr
+ command += " 2>/dev/null"; // Silence stderr
}
- FILE *f = popen(argss.utf8().get_data(), "r");
-
- ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot pipe stream from process running with following arguments '" + argss + "'.");
+ FILE *f = popen(command.utf8().get_data(), "r");
+ ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot create pipe from command: " + command);
char buf[65535];
-
while (fgets(buf, 65535, f)) {
if (p_pipe_mutex) {
p_pipe_mutex->lock();
@@ -289,10 +283,10 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
}
}
int rv = pclose(f);
+
if (r_exitcode) {
*r_exitcode = WEXITSTATUS(rv);
}
-
return OK;
}
@@ -300,14 +294,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
ERR_FAIL_COND_V(pid < 0, ERR_CANT_FORK);
if (pid == 0) {
- // is child
-
- if (!p_blocking) {
- // For non blocking calls, create a new session-ID so parent won't wait for it.
- // This ensures the process won't go zombie at end.
- setsid();
- }
-
+ // The child process
Vector<CharString> cs;
cs.push_back(p_path.utf8());
for (int i = 0; i < p_arguments.size(); i++) {
@@ -321,24 +308,56 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
args.push_back(0);
execvp(p_path.utf8().get_data(), &args[0]);
- // still alive? something failed..
- fprintf(stderr, "**ERROR** OS_Unix::execute - Could not create child process while executing: %s\n", p_path.utf8().get_data());
+ // The execvp() function only returns if an error occurs.
+ ERR_PRINT("Could not create child process: " + p_path);
raise(SIGKILL);
}
- if (p_blocking) {
- int status;
- waitpid(pid, &status, 0);
- if (r_exitcode) {
- *r_exitcode = WIFEXITED(status) ? WEXITSTATUS(status) : status;
+ int status;
+ waitpid(pid, &status, 0);
+ if (r_exitcode) {
+ *r_exitcode = WIFEXITED(status) ? WEXITSTATUS(status) : status;
+ }
+ return OK;
+#endif
+}
+
+Error OS_Unix::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) {
+#ifdef __EMSCRIPTEN__
+ // Don't compile this code at all to avoid undefined references.
+ // Actual virtual call goes to OS_JavaScript.
+ ERR_FAIL_V(ERR_BUG);
+#else
+ pid_t pid = fork();
+ ERR_FAIL_COND_V(pid < 0, ERR_CANT_FORK);
+
+ if (pid == 0) {
+ // The new process
+ // Create a new session-ID so parent won't wait for it.
+ // This ensures the process won't go zombie at the end.
+ setsid();
+
+ Vector<CharString> cs;
+ cs.push_back(p_path.utf8());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ cs.push_back(p_arguments[i].utf8());
}
- } else {
- if (r_child_id) {
- *r_child_id = pid;
+ Vector<char *> args;
+ for (int i = 0; i < cs.size(); i++) {
+ args.push_back((char *)cs[i].get_data());
}
+ args.push_back(0);
+
+ execvp(p_path.utf8().get_data(), &args[0]);
+ // The execvp() function only returns if an error occurs.
+ ERR_PRINT("Could not create child process: " + p_path);
+ raise(SIGKILL);
}
+ if (r_child_id) {
+ *r_child_id = pid;
+ }
return OK;
#endif
}
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 51e5a00e36..6c79d984e9 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -82,7 +82,8 @@ public:
virtual void delay_usec(uint32_t p_usec) const override;
virtual uint64_t get_ticks_usec() const override;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
virtual Error kill(const ProcessID &p_pid) override;
virtual int get_process_id() const override;
diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp
deleted file mode 100644
index cf24d54c50..0000000000
--- a/drivers/unix/rw_lock_posix.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*************************************************************************/
-/* rw_lock_posix.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
-
-#include "rw_lock_posix.h"
-
-#include "core/error/error_macros.h"
-#include "core/os/memory.h"
-#include <stdio.h>
-
-void RWLockPosix::read_lock() {
- int err = pthread_rwlock_rdlock(&rwlock);
- if (err != 0) {
- perror("Acquiring lock failed");
- }
- ERR_FAIL_COND(err != 0);
-}
-
-void RWLockPosix::read_unlock() {
- pthread_rwlock_unlock(&rwlock);
-}
-
-Error RWLockPosix::read_try_lock() {
- if (pthread_rwlock_tryrdlock(&rwlock) != 0) {
- return ERR_BUSY;
- } else {
- return OK;
- }
-}
-
-void RWLockPosix::write_lock() {
- int err = pthread_rwlock_wrlock(&rwlock);
- ERR_FAIL_COND(err != 0);
-}
-
-void RWLockPosix::write_unlock() {
- pthread_rwlock_unlock(&rwlock);
-}
-
-Error RWLockPosix::write_try_lock() {
- if (pthread_rwlock_trywrlock(&rwlock) != 0) {
- return ERR_BUSY;
- } else {
- return OK;
- }
-}
-
-RWLock *RWLockPosix::create_func_posix() {
- return memnew(RWLockPosix);
-}
-
-void RWLockPosix::make_default() {
- create_func = create_func_posix;
-}
-
-RWLockPosix::RWLockPosix() {
- //rwlock=PTHREAD_RWLOCK_INITIALIZER; fails on OSX
- pthread_rwlock_init(&rwlock, nullptr);
-}
-
-RWLockPosix::~RWLockPosix() {
- pthread_rwlock_destroy(&rwlock);
-}
-
-#endif
diff --git a/drivers/unix/rw_lock_posix.h b/drivers/unix/rw_lock_posix.h
deleted file mode 100644
index 056fcaea1c..0000000000
--- a/drivers/unix/rw_lock_posix.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*************************************************************************/
-/* rw_lock_posix.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef RWLOCKPOSIX_H
-#define RWLOCKPOSIX_H
-
-#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
-
-#include "core/os/rw_lock.h"
-#include <pthread.h>
-
-class RWLockPosix : public RWLock {
- pthread_rwlock_t rwlock;
-
- static RWLock *create_func_posix();
-
-public:
- virtual void read_lock();
- virtual void read_unlock();
- virtual Error read_try_lock();
-
- virtual void write_lock();
- virtual void write_unlock();
- virtual Error write_try_lock();
-
- static void make_default();
-
- RWLockPosix();
-
- ~RWLockPosix();
-};
-
-#endif
-
-#endif // RWLOCKPOSIX_H
diff --git a/drivers/unix/syslog_logger.cpp b/drivers/unix/syslog_logger.cpp
index b29d1ec541..423ddac793 100644
--- a/drivers/unix/syslog_logger.cpp
+++ b/drivers/unix/syslog_logger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/syslog_logger.h b/drivers/unix/syslog_logger.h
index 52da12481f..d9f7f2ff99 100644
--- a/drivers/unix/syslog_logger.h
+++ b/drivers/unix/syslog_logger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp
index f4e3de7646..19fab1d475 100644
--- a/drivers/unix/thread_posix.cpp
+++ b/drivers/unix/thread_posix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,88 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "thread_posix.h"
-
#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
-#include "core/object/script_language.h"
-#include "core/os/memory.h"
-#include "core/templates/safe_refcount.h"
-
-#ifdef PTHREAD_BSD_SET_NAME
-#include <pthread_np.h>
-#endif
-
-static void _thread_id_key_destr_callback(void *p_value) {
- memdelete(static_cast<Thread::ID *>(p_value));
-}
-
-static pthread_key_t _create_thread_id_key() {
- pthread_key_t key;
- pthread_key_create(&key, &_thread_id_key_destr_callback);
- return key;
-}
-
-pthread_key_t ThreadPosix::thread_id_key = _create_thread_id_key();
-Thread::ID ThreadPosix::next_thread_id = 0;
-
-Thread::ID ThreadPosix::get_id() const {
- return id;
-}
-
-Thread *ThreadPosix::create_thread_posix() {
- return memnew(ThreadPosix);
-}
-
-void *ThreadPosix::thread_callback(void *userdata) {
- ThreadPosix *t = reinterpret_cast<ThreadPosix *>(userdata);
- t->id = atomic_increment(&next_thread_id);
- pthread_setspecific(thread_id_key, (void *)memnew(ID(t->id)));
-
- ScriptServer::thread_enter(); //scripts may need to attach a stack
-
- t->callback(t->user);
-
- ScriptServer::thread_exit();
-
- return nullptr;
-}
-
-Thread *ThreadPosix::create_func_posix(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
- ThreadPosix *tr = memnew(ThreadPosix);
- tr->callback = p_callback;
- tr->user = p_user;
- pthread_attr_init(&tr->pthread_attr);
- pthread_attr_setdetachstate(&tr->pthread_attr, PTHREAD_CREATE_JOINABLE);
- pthread_attr_setstacksize(&tr->pthread_attr, 256 * 1024);
-
- pthread_create(&tr->pthread, &tr->pthread_attr, thread_callback, tr);
-
- return tr;
-}
-
-Thread::ID ThreadPosix::get_thread_id_func_posix() {
- void *value = pthread_getspecific(thread_id_key);
-
- if (value) {
- return *static_cast<ID *>(value);
- }
-
- ID new_id = atomic_increment(&next_thread_id);
- pthread_setspecific(thread_id_key, (void *)memnew(ID(new_id)));
- return new_id;
-}
-
-void ThreadPosix::wait_to_finish_func_posix(Thread *p_thread) {
- ThreadPosix *tp = static_cast<ThreadPosix *>(p_thread);
- ERR_FAIL_COND(!tp);
- ERR_FAIL_COND(tp->pthread == 0);
+#include "thread_posix.h"
- pthread_join(tp->pthread, nullptr);
- tp->pthread = 0;
-}
+#include "core/os/thread.h"
+#include "core/string/ustring.h"
-Error ThreadPosix::set_name_func_posix(const String &p_name) {
+static Error set_name(const String &p_name) {
#ifdef PTHREAD_NO_RENAME
return ERR_UNAVAILABLE;
@@ -137,20 +63,10 @@ Error ThreadPosix::set_name_func_posix(const String &p_name) {
return err == 0 ? OK : ERR_INVALID_PARAMETER;
#endif // PTHREAD_NO_RENAME
-};
-
-void ThreadPosix::make_default() {
- create_func = create_func_posix;
- get_thread_id_func = get_thread_id_func_posix;
- wait_to_finish_func = wait_to_finish_func_posix;
- set_name_func = set_name_func_posix;
-}
-
-ThreadPosix::ThreadPosix() {
- pthread = 0;
}
-ThreadPosix::~ThreadPosix() {
+void init_thread_posix() {
+ Thread::_set_platform_funcs(&set_name, nullptr);
}
#endif
diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h
index 6607dbd111..8b8a736bf0 100644
--- a/drivers/unix/thread_posix.h
+++ b/drivers/unix/thread_posix.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,42 +31,8 @@
#ifndef THREAD_POSIX_H
#define THREAD_POSIX_H
-#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
-
-#include "core/os/thread.h"
-#include <pthread.h>
-#include <sys/types.h>
-
-class ThreadPosix : public Thread {
- static pthread_key_t thread_id_key;
- static ID next_thread_id;
-
- pthread_t pthread;
- pthread_attr_t pthread_attr;
- ThreadCreateCallback callback;
- void *user;
- ID id;
-
- static Thread *create_thread_posix();
-
- static void *thread_callback(void *userdata);
-
- static Thread *create_func_posix(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID get_thread_id_func_posix();
- static void wait_to_finish_func_posix(Thread *p_thread);
-
- static Error set_name_func_posix(const String &p_name);
-
- ThreadPosix();
-
-public:
- virtual ID get_id() const;
-
- static void make_default();
-
- ~ThreadPosix();
-};
-
+#if !defined(NO_THREADS)
+void init_thread_posix();
#endif
#endif
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 03216c667e..9584dd3f67 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,28 +41,62 @@
//#define FORCE_FULL_BARRIER
// Get the Vulkan object information and possible stage access types (bitwise OR'd with incoming values)
-RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &stage_mask, VkAccessFlags &access_mask) {
+RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &r_stage_mask, VkAccessFlags &r_access_mask, uint32_t p_post_barrier) {
Buffer *buffer = nullptr;
if (vertex_buffer_owner.owns(p_buffer)) {
- stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
- access_mask |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
buffer = vertex_buffer_owner.getornull(p_buffer);
+
+ r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
+ r_access_mask |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
+ if (buffer->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) {
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ }
+ }
} else if (index_buffer_owner.owns(p_buffer)) {
- stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
- access_mask |= VK_ACCESS_INDEX_READ_BIT;
+ r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
+ r_access_mask |= VK_ACCESS_INDEX_READ_BIT;
buffer = index_buffer_owner.getornull(p_buffer);
} else if (uniform_buffer_owner.owns(p_buffer)) {
- stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- access_mask |= VK_ACCESS_UNIFORM_READ_BIT;
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ }
+ r_access_mask |= VK_ACCESS_UNIFORM_READ_BIT;
buffer = uniform_buffer_owner.getornull(p_buffer);
} else if (texture_buffer_owner.owns(p_buffer)) {
- stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- access_mask |= VK_ACCESS_SHADER_READ_BIT;
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ r_access_mask |= VK_ACCESS_SHADER_READ_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ r_access_mask |= VK_ACCESS_SHADER_READ_BIT;
+ }
+
buffer = &texture_buffer_owner.getornull(p_buffer)->buffer;
} else if (storage_buffer_owner.owns(p_buffer)) {
- stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
buffer = storage_buffer_owner.getornull(p_buffer);
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+
+ if (buffer->usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) {
+ r_stage_mask |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
+ r_access_mask |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
+ }
}
return buffer;
}
@@ -1595,6 +1629,9 @@ void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mas
mem_barrier.srcAccessMask = p_src_access;
mem_barrier.dstAccessMask = p_dst_sccess;
+ if (p_src_stage_mask == 0 || p_dst_stage_mask == 0) {
+ return; //no barrier, since this is invalid
+ }
vkCmdPipelineBarrier(p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, p_src_stage_mask, p_dst_stage_mask, 0, 1, &mem_barrier, 0, nullptr, 0, nullptr);
}
@@ -2067,6 +2104,48 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
+ VkImageViewUsageCreateInfo usage_info;
+ usage_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
+ usage_info.pNext = nullptr;
+ if (p_view.format_override != DATA_FORMAT_MAX) {
+ //need to validate usage with vulkan
+
+ usage_info.usage = 0;
+
+ if (texture.usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+ }
+
+ if (texture.usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
+ if (texture_is_format_supported_for_usage(p_view.format_override, TEXTURE_USAGE_STORAGE_BIT)) {
+ usage_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
+ }
+ }
+
+ if (texture.usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ if (texture_is_format_supported_for_usage(p_view.format_override, TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
+ usage_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ }
+ }
+
+ if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ }
+
+ if (texture.usage_flags & TEXTURE_USAGE_CAN_UPDATE_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ }
+ if (texture.usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ }
+
+ if (texture.usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ }
+
+ image_view_create_info.pNext = &usage_info;
+ }
+
VkResult err = vkCreateImageView(device, &image_view_create_info, nullptr, &texture.view);
ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateImageView failed with error " + itos(err) + ".");
@@ -2134,7 +2213,16 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
VK_IMAGE_VIEW_TYPE_2D,
};
- image_view_create_info.viewType = p_slice_type == TEXTURE_SLICE_CUBEMAP ? VK_IMAGE_VIEW_TYPE_CUBE : (p_slice_type == TEXTURE_SLICE_3D ? VK_IMAGE_VIEW_TYPE_3D : view_types[texture.type]);
+ image_view_create_info.viewType = view_types[texture.type];
+
+ if (p_slice_type == TEXTURE_SLICE_CUBEMAP) {
+ image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
+ } else if (p_slice_type == TEXTURE_SLICE_3D) {
+ image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D;
+ } else if (p_slice_type == TEXTURE_SLICE_2D_ARRAY) {
+ image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
+ }
+
if (p_view.format_override == DATA_FORMAT_MAX || p_view.format_override == texture.format) {
image_view_create_info.format = vulkan_formats[texture.format];
} else {
@@ -2187,11 +2275,11 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
return id;
}
-Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw) {
+Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier) {
_THREAD_SAFE_METHOD_
- ERR_FAIL_COND_V_MSG(draw_list && p_sync_with_draw, ERR_INVALID_PARAMETER,
- "Updating textures in 'sync to draw' mode is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(draw_list || compute_list, ERR_INVALID_PARAMETER,
+ "Updating textures in is forbidden during creation of a draw or compute list");
Texture *texture = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!texture, ERR_INVALID_PARAMETER);
@@ -2232,7 +2320,7 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
const uint8_t *r = p_data.ptr();
- VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
+ VkCommandBuffer command_buffer = p_post_barrier ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
//barrier to transfer
{
@@ -2257,6 +2345,10 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
}
uint32_t mipmap_offset = 0;
+
+ uint32_t logic_width = texture->width;
+ uint32_t logic_height = texture->height;
+
for (uint32_t mm_i = 0; mm_i < texture->mipmaps; mm_i++) {
uint32_t depth;
uint32_t image_total = get_image_format_required_size(texture->format, texture->width, texture->height, texture->depth, mm_i + 1, &width, &height, &depth);
@@ -2273,12 +2365,15 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
uint32_t region_w = MIN(region_size, width - x);
uint32_t region_h = MIN(region_size, height - y);
+ uint32_t region_logic_w = MIN(region_size, logic_width - x);
+ uint32_t region_logic_h = MIN(region_size, logic_height - y);
+
uint32_t pixel_size = get_image_format_pixel_size(texture->format);
uint32_t to_allocate = region_w * region_h * pixel_size;
to_allocate >>= get_compressed_image_format_pixel_rshift(texture->format);
uint32_t alloc_offset, alloc_size;
- Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false, p_sync_with_draw);
+ Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false, p_post_barrier);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
uint8_t *write_ptr;
@@ -2354,8 +2449,8 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
buffer_image_copy.imageOffset.y = y;
buffer_image_copy.imageOffset.z = z;
- buffer_image_copy.imageExtent.width = region_w;
- buffer_image_copy.imageExtent.height = region_h;
+ buffer_image_copy.imageExtent.width = region_logic_w;
+ buffer_image_copy.imageExtent.height = region_logic_h;
buffer_image_copy.imageExtent.depth = 1;
vkCmdCopyBufferToImage(command_buffer, staging_buffer_blocks[staging_buffer_current].buffer, texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &buffer_image_copy);
@@ -2366,15 +2461,36 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
}
mipmap_offset = image_total;
+ logic_width = MAX(1, logic_width >> 1);
+ logic_height = MAX(1, logic_height >> 1);
}
//barrier to restore layout
{
+ uint32_t barrier_flags = 0;
+ uint32_t access_flags = 0;
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_TRANSFER) {
+ barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
+ }
+
+ if (barrier_flags == 0) {
+ barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
VkImageMemoryBarrier image_memory_barrier;
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ image_memory_barrier.dstAccessMask = access_flags;
image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
image_memory_barrier.newLayout = texture->layout;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@@ -2386,9 +2502,16 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
image_memory_barrier.subresourceRange.baseArrayLayer = p_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
+ if (texture->used_in_frame != frames_drawn) {
+ texture->used_in_raster = false;
+ texture->used_in_compute = false;
+ texture->used_in_frame = frames_drawn;
+ }
+ texture->used_in_transfer = true;
+
return OK;
}
@@ -2599,13 +2722,13 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) {
return texture_owner.owns(p_texture);
}
-Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw) {
+Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier) {
_THREAD_SAFE_METHOD_
Texture *src_tex = texture_owner.getornull(p_from_texture);
ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER,
+ ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER,
"Source texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture.");
ERR_FAIL_COND_V_MSG(!(src_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT), ERR_INVALID_PARAMETER,
"Source texture requires the TEXTURE_USAGE_CAN_COPY_FROM_BIT in order to be retrieved.");
@@ -2626,7 +2749,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
Texture *dst_tex = texture_owner.getornull(p_to_texture);
ERR_FAIL_COND_V(!dst_tex, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V_MSG(p_sync_with_draw && dst_tex->bound, ERR_INVALID_PARAMETER,
+ ERR_FAIL_COND_V_MSG(dst_tex->bound, ERR_INVALID_PARAMETER,
"Destination texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture.");
ERR_FAIL_COND_V_MSG(!(dst_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT), ERR_INVALID_PARAMETER,
"Destination texture requires the TEXTURE_USAGE_CAN_COPY_TO_BIT in order to be retrieved.");
@@ -2647,7 +2770,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
ERR_FAIL_COND_V_MSG(src_tex->read_aspect_mask != dst_tex->read_aspect_mask, ERR_INVALID_PARAMETER,
"Source and destination texture must be of the same type (color or depth).");
- VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
+ VkCommandBuffer command_buffer = frames[frame].draw_command_buffer;
{
//PRE Copy the image
@@ -2722,12 +2845,31 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
// RESTORE LAYOUT for SRC and DST
+ uint32_t barrier_flags = 0;
+ uint32_t access_flags = 0;
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_TRANSFER) {
+ barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
+ }
+
+ if (barrier_flags == 0) {
+ barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
{ //restore src
VkImageMemoryBarrier image_memory_barrier;
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.dstAccessMask = access_flags;
image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
image_memory_barrier.newLayout = src_tex->layout;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@@ -2739,7 +2881,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
image_memory_barrier.subresourceRange.baseArrayLayer = p_src_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
{ //make dst readable
@@ -2748,7 +2890,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.dstAccessMask = access_flags;
image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
image_memory_barrier.newLayout = dst_tex->layout;
@@ -2761,20 +2903,20 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
image_memory_barrier.subresourceRange.baseArrayLayer = p_src_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
}
return OK;
}
-Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw) {
+Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier) {
_THREAD_SAFE_METHOD_
Texture *src_tex = texture_owner.getornull(p_from_texture);
ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER,
+ ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER,
"Source texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture.");
ERR_FAIL_COND_V_MSG(!(src_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT), ERR_INVALID_PARAMETER,
"Source texture requires the TEXTURE_USAGE_CAN_COPY_FROM_BIT in order to be retrieved.");
@@ -2785,7 +2927,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
Texture *dst_tex = texture_owner.getornull(p_to_texture);
ERR_FAIL_COND_V(!dst_tex, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V_MSG(p_sync_with_draw && dst_tex->bound, ERR_INVALID_PARAMETER,
+ ERR_FAIL_COND_V_MSG(dst_tex->bound, ERR_INVALID_PARAMETER,
"Destination texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture.");
ERR_FAIL_COND_V_MSG(!(dst_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT), ERR_INVALID_PARAMETER,
"Destination texture requires the TEXTURE_USAGE_CAN_COPY_TO_BIT in order to be retrieved.");
@@ -2799,7 +2941,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
ERR_FAIL_COND_V_MSG(src_tex->read_aspect_mask != dst_tex->read_aspect_mask, ERR_INVALID_PARAMETER,
"Source and destination texture must be of the same type (color or depth).");
- VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
+ VkCommandBuffer command_buffer = frames[frame].draw_command_buffer;
{
//PRE Copy the image
@@ -2874,12 +3016,31 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
// RESTORE LAYOUT for SRC and DST
+ uint32_t barrier_flags = 0;
+ uint32_t access_flags = 0;
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_TRANSFER) {
+ barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
+ }
+
+ if (barrier_flags == 0) {
+ barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
{ //restore src
VkImageMemoryBarrier image_memory_barrier;
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
- image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.dstAccessMask = access_flags;
image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
image_memory_barrier.newLayout = src_tex->layout;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
@@ -2891,7 +3052,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
{ //make dst readable
@@ -2900,7 +3061,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.dstAccessMask = access_flags;
image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
image_memory_barrier.newLayout = dst_tex->layout;
@@ -2913,20 +3074,20 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
image_memory_barrier.subresourceRange.baseArrayLayer = dst_tex->base_layer;
image_memory_barrier.subresourceRange.layerCount = 1;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
}
return OK;
}
-Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw) {
+Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier) {
_THREAD_SAFE_METHOD_
Texture *src_tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER,
+ ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER,
"Source texture can't be cleared while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture.");
ERR_FAIL_COND_V(p_layers == 0, ERR_INVALID_PARAMETER);
@@ -2943,7 +3104,7 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
ERR_FAIL_COND_V(p_base_mipmap + p_mipmaps > src_tex->mipmaps, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_base_layer + p_layers > src_layer_count, ERR_INVALID_PARAMETER);
- VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
+ VkCommandBuffer command_buffer = frames[frame].draw_command_buffer;
VkImageLayout clear_layout = (src_tex->layout == VK_IMAGE_LAYOUT_GENERAL) ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
@@ -2990,11 +3151,31 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
vkCmdClearColorImage(command_buffer, src_tex->image, clear_layout, &clear_color, 1, &range);
{ // Barrier to post clear accesses (changing back the layout if needed)
+
+ uint32_t barrier_flags = 0;
+ uint32_t access_flags = 0;
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ barrier_flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_TRANSFER) {
+ barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
+ }
+
+ if (barrier_flags == 0) {
+ barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
VkImageMemoryBarrier image_memory_barrier;
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- image_memory_barrier.dstAccessMask = valid_texture_access;
+ image_memory_barrier.dstAccessMask = access_flags;
image_memory_barrier.oldLayout = clear_layout;
image_memory_barrier.newLayout = src_tex->layout;
@@ -3007,9 +3188,16 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + p_base_layer;
image_memory_barrier.subresourceRange.layerCount = p_layers;
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, valid_texture_stages, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, barrier_flags, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
+ if (src_tex->used_in_frame != frames_drawn) {
+ src_tex->used_in_raster = false;
+ src_tex->used_in_compute = false;
+ src_tex->used_in_frame = frames_drawn;
+ }
+ src_tex->used_in_transfer = true;
+
return OK;
}
@@ -3095,6 +3283,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
// the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that
// stage
switch (is_depth_stencil ? p_initial_depth_action : p_initial_color_action) {
+ case INITIAL_ACTION_CLEAR_REGION:
case INITIAL_ACTION_CLEAR: {
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
@@ -3107,9 +3296,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
- description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+ description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+ description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
dependency_from_external.srcStageMask |= reading_stages;
} else {
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@@ -3135,6 +3324,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
dependency_from_external.srcStageMask |= reading_stages;
}
} break;
+ case INITIAL_ACTION_CLEAR_REGION_CONTINUE:
case INITIAL_ACTION_CONTINUE: {
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
@@ -3142,7 +3332,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
- description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; //don't care what is there
+ description.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
} else {
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@@ -3271,8 +3461,13 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
render_pass_create_info.pAttachments = attachments.ptr();
render_pass_create_info.subpassCount = 1;
render_pass_create_info.pSubpasses = &subpass;
- render_pass_create_info.dependencyCount = 2;
- render_pass_create_info.pDependencies = dependencies;
+ // Commenting this because it seems it just avoids raster and compute to work at the same time.
+ // Other barriers seem to be protecting the render pass fine.
+ // render_pass_create_info.dependencyCount = 2;
+ // render_pass_create_info.pDependencies = dependencies;
+
+ render_pass_create_info.dependencyCount = 0;
+ render_pass_create_info.pDependencies = nullptr;
VkRenderPass render_pass;
VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
@@ -3314,11 +3509,8 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
return id;
}
-RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_empty(const Size2i &p_size) {
- ERR_FAIL_COND_V(p_size.width <= 0 || p_size.height <= 0, INVALID_FORMAT_ID);
-
+RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_empty(TextureSamples p_samples) {
FramebufferFormatKey key;
- key.empty_size = p_size;
const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E = framebuffer_format_cache.find(key);
if (E) {
@@ -3366,7 +3558,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
fb_format.E = E;
fb_format.color_attachments = 0;
fb_format.render_pass = render_pass;
- fb_format.samples = TEXTURE_SAMPLES_1;
+ fb_format.samples = p_samples;
framebuffer_formats[id] = fb_format;
return id;
}
@@ -3382,10 +3574,10 @@ RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_te
/**** RENDER TARGET ****/
/***********************/
-RID RenderingDeviceVulkan::framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check) {
+RID RenderingDeviceVulkan::framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples, FramebufferFormatID p_format_check) {
_THREAD_SAFE_METHOD_
Framebuffer framebuffer;
- framebuffer.format_id = framebuffer_format_create_empty(p_size);
+ framebuffer.format_id = framebuffer_format_create_empty(p_samples);
ERR_FAIL_COND_V(p_format_check != INVALID_FORMAT_ID && framebuffer.format_id != p_format_check, RID());
framebuffer.size = p_size;
@@ -3957,6 +4149,8 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
bool is_compute = false;
+ uint32_t compute_local_size[3] = { 0, 0, 0 };
+
for (int i = 0; i < p_stages.size(); i++) {
if (p_stages[i].shader_stage == SHADER_STAGE_COMPUTE) {
is_compute = true;
@@ -3973,6 +4167,11 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(),
"Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_stages[i].shader_stage]) + "' failed parsing shader.");
+ if (is_compute) {
+ compute_local_size[0] = module.entry_points->local_size.x;
+ compute_local_size[1] = module.entry_points->local_size.y;
+ compute_local_size[2] = module.entry_points->local_size.z;
+ }
uint32_t binding_count = 0;
result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(),
@@ -4052,6 +4251,10 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
info.type = UNIFORM_TYPE_INPUT_ATTACHMENT;
} break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
+ ERR_PRINT("Acceleration structure not supported.");
+ continue;
+ } break;
}
if (need_array_dimensions) {
@@ -4173,6 +4376,7 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
}
}
}
+
uint32_t pc_count = 0;
result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(),
@@ -4221,6 +4425,9 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
shader.fragment_outputs = fragment_outputs;
shader.push_constant = push_constant;
shader.is_compute = is_compute;
+ shader.compute_local_size[0] = compute_local_size[0];
+ shader.compute_local_size[1] = compute_local_size[1];
+ shader.compute_local_size[2] = compute_local_size[2];
String error_text;
@@ -4577,7 +4784,7 @@ void RenderingDeviceVulkan::_descriptor_pool_free(const DescriptorPoolKey &p_key
vkDestroyDescriptorPool(device, p_pool->pool, nullptr);
descriptor_pools[p_key].erase(p_pool);
memdelete(p_pool);
- if (descriptor_pools[p_key].empty()) {
+ if (descriptor_pools[p_key].is_empty()) {
descriptor_pools.erase(p_key);
}
}
@@ -5027,19 +5234,22 @@ bool RenderingDeviceVulkan::uniform_set_is_valid(RID p_uniform_set) {
return uniform_set_owner.owns(p_uniform_set);
}
-Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw) {
+Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier) {
_THREAD_SAFE_METHOD_
- ERR_FAIL_COND_V_MSG(draw_list && p_sync_with_draw, ERR_INVALID_PARAMETER,
- "Updating buffers in 'sync to draw' mode is forbidden during creation of a draw list");
- ERR_FAIL_COND_V_MSG(compute_list && p_sync_with_draw, ERR_INVALID_PARAMETER,
- "Updating buffers in 'sync to draw' mode is forbidden during creation of a compute list");
+ ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER,
+ "Updating buffers is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER,
+ "Updating buffers is forbidden during creation of a compute list");
- // Protect subsequent updates...
- VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT;
- VkAccessFlags dst_access = VK_ACCESS_TRANSFER_WRITE_BIT;
-
- Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stage_mask, dst_access);
+ VkPipelineStageFlags dst_stage_mask = 0;
+ VkAccessFlags dst_access = 0;
+ if (p_post_barrier & BARRIER_MASK_TRANSFER) {
+ // Protect subsequent updates...
+ dst_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ dst_access = VK_ACCESS_TRANSFER_WRITE_BIT;
+ }
+ Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stage_mask, dst_access, p_post_barrier);
if (!buffer) {
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Buffer argument is not a valid buffer of any type.");
}
@@ -5047,20 +5257,73 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint
ERR_FAIL_COND_V_MSG(p_offset + p_size > buffer->size, ERR_INVALID_PARAMETER,
"Attempted to write buffer (" + itos((p_offset + p_size) - buffer->size) + " bytes) past the end.");
- _buffer_memory_barrier(buffer->buffer, p_offset, p_size, dst_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_access, VK_ACCESS_TRANSFER_WRITE_BIT, p_sync_with_draw);
- Error err = _buffer_update(buffer, p_offset, (uint8_t *)p_data, p_size, p_sync_with_draw);
+ // no barrier should be needed here
+ // _buffer_memory_barrier(buffer->buffer, p_offset, p_size, dst_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_access, VK_ACCESS_TRANSFER_WRITE_BIT, true);
+
+ Error err = _buffer_update(buffer, p_offset, (uint8_t *)p_data, p_size, p_post_barrier);
if (err) {
return err;
}
#ifdef FORCE_FULL_BARRIER
- _full_barrier(p_sync_with_draw);
+ _full_barrier(true);
#else
- _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, p_sync_with_draw);
+ if (dst_stage_mask == 0) {
+ dst_stage_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
+ if (p_post_barrier != RD::BARRIER_MASK_NO_BARRIER) {
+ _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, true);
+ }
+
#endif
return err;
}
+Error RenderingDeviceVulkan::buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier) {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND_V_MSG((p_size % 4) != 0, ERR_INVALID_PARAMETER,
+ "Size must be a multiple of four");
+ ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER,
+ "Updating buffers in is forbidden during creation of a draw list");
+ ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER,
+ "Updating buffers is forbidden during creation of a compute list");
+
+ VkPipelineStageFlags dst_stage_mask = 0;
+ VkAccessFlags dst_access = 0;
+ if (p_post_barrier & BARRIER_MASK_TRANSFER) {
+ // Protect subsequent updates...
+ dst_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ dst_access = VK_ACCESS_TRANSFER_WRITE_BIT;
+ }
+
+ Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stage_mask, dst_access, p_post_barrier);
+ if (!buffer) {
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Buffer argument is not a valid buffer of any type.");
+ }
+
+ ERR_FAIL_COND_V_MSG(p_offset + p_size > buffer->size, ERR_INVALID_PARAMETER,
+ "Attempted to write buffer (" + itos((p_offset + p_size) - buffer->size) + " bytes) past the end.");
+
+ // should not be needed
+ // _buffer_memory_barrier(buffer->buffer, p_offset, p_size, dst_stage_mask, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_access, VK_ACCESS_TRANSFER_WRITE_BIT, p_post_barrier);
+
+ vkCmdFillBuffer(frames[frame].draw_command_buffer, buffer->buffer, p_offset, p_size, 0);
+
+#ifdef FORCE_FULL_BARRIER
+ _full_barrier(true);
+#else
+ if (dst_stage_mask == 0) {
+ dst_stage_mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
+ _buffer_memory_barrier(buffer->buffer, p_offset, p_size, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage_mask, VK_ACCESS_TRANSFER_WRITE_BIT, dst_access, dst_stage_mask);
+
+#endif
+ return OK;
+}
+
Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
_THREAD_SAFE_METHOD_
@@ -5068,7 +5331,7 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
VkPipelineShaderStageCreateFlags src_stage_mask = VK_PIPELINE_STAGE_TRANSFER_BIT;
VkAccessFlags src_access_mask = VK_ACCESS_TRANSFER_WRITE_BIT;
// Get the vulkan buffer and the potential stage/access possible
- Buffer *buffer = _get_buffer_from_owner(p_buffer, src_stage_mask, src_access_mask);
+ Buffer *buffer = _get_buffer_from_owner(p_buffer, src_stage_mask, src_access_mask, BARRIER_MASK_ALL);
if (!buffer) {
ERR_FAIL_V_MSG(Vector<uint8_t>(), "Buffer is either invalid or this type of buffer can't be retrieved. Only Index and Vertex buffers allow retrieving.");
}
@@ -5511,6 +5774,9 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader) {
pipeline.pipeline_layout = shader->pipeline_layout;
pipeline.shader = p_shader;
pipeline.push_constant_size = shader->push_constant.push_constant_size;
+ pipeline.local_group_size[0] = shader->compute_local_size[0];
+ pipeline.local_group_size[1] = shader->compute_local_size[1];
+ pipeline.local_group_size[2] = shader->compute_local_size[2];
//create ID to associate with this pipeline
RID id = compute_pipeline_owner.make_rid(pipeline);
@@ -5629,7 +5895,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(Di
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
- return ID_TYPE_DRAW_LIST;
+ return int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT;
}
Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass) {
@@ -5682,11 +5948,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
render_pass_begin.pNext = nullptr;
render_pass_begin.renderPass = render_pass;
render_pass_begin.framebuffer = vkframebuffer;
-
+ /*
+ * Given how API works, it makes sense to always fully operate on the whole framebuffer.
+ * This allows better continue operations for operations like shadowmapping.
render_pass_begin.renderArea.extent.width = viewport_size.width;
render_pass_begin.renderArea.extent.height = viewport_size.height;
render_pass_begin.renderArea.offset.x = viewport_offset.x;
render_pass_begin.renderArea.offset.y = viewport_offset.y;
+ */
+ render_pass_begin.renderArea.extent.width = framebuffer->size.width;
+ render_pass_begin.renderArea.extent.height = framebuffer->size.height;
+ render_pass_begin.renderArea.offset.x = 0;
+ render_pass_begin.renderArea.offset.y = 0;
Vector<VkClearValue> clear_values;
clear_values.resize(framebuffer->texture_ids.size());
@@ -5813,7 +6086,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
- ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time.");
+ ERR_FAIL_COND_V_MSG(compute_list != nullptr && !compute_list->state.allow_draw_overlap, INVALID_ID, "Only one draw/compute list can be active at the same time.");
Framebuffer *framebuffer = framebuffer_owner.getornull(p_framebuffer);
ERR_FAIL_COND_V(!framebuffer, INVALID_ID);
@@ -5834,12 +6107,19 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
viewport_offset = regioni.position;
viewport_size = regioni.size;
-
- if (p_initial_color_action == INITIAL_ACTION_CLEAR) {
+ if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) {
+ needs_clear_color = true;
+ p_initial_color_action = INITIAL_ACTION_CONTINUE;
+ }
+ if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) {
+ needs_clear_depth = true;
+ p_initial_depth_action = INITIAL_ACTION_CONTINUE;
+ }
+ if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) {
needs_clear_color = true;
p_initial_color_action = INITIAL_ACTION_KEEP;
}
- if (p_initial_depth_action == INITIAL_ACTION_CLEAR) {
+ if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) {
needs_clear_depth = true;
p_initial_depth_action = INITIAL_ACTION_KEEP;
}
@@ -5896,7 +6176,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
draw_list->viewport = Rect2i(viewport_offset, viewport_size);
- return ID_TYPE_DRAW_LIST;
+ return int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT;
}
Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
@@ -5925,11 +6205,11 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
viewport_offset = regioni.position;
viewport_size = regioni.size;
- if (p_initial_color_action == INITIAL_ACTION_CLEAR) {
+ if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) {
needs_clear_color = true;
p_initial_color_action = INITIAL_ACTION_KEEP;
}
- if (p_initial_depth_action == INITIAL_ACTION_CLEAR) {
+ if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) {
needs_clear_depth = true;
p_initial_depth_action = INITIAL_ACTION_KEEP;
}
@@ -5993,7 +6273,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
for (uint32_t i = 0; i < p_splits; i++) {
//take a command buffer and initialize it
- VkCommandBuffer command_buffer = split_draw_list_allocators[p_splits].command_buffers[frame];
+ VkCommandBuffer command_buffer = split_draw_list_allocators[i].command_buffers[frame];
VkCommandBufferInheritanceInfo inheritance_info;
inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
@@ -6051,7 +6331,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
scissor.extent.height = viewport_size.height;
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
- r_split_ids[i] = (DrawListID(1) << DrawListID(ID_TYPE_SPLIT_DRAW_LIST)) + i;
+ r_split_ids[i] = (int64_t(ID_TYPE_SPLIT_DRAW_LIST) << ID_BASE_SHIFT) + i;
draw_list[i].viewport = Rect2i(viewport_offset, viewport_size);
}
@@ -6066,7 +6346,7 @@ RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawL
if (!draw_list) {
return nullptr;
- } else if (p_id == ID_TYPE_DRAW_LIST) {
+ } else if (p_id == (int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT)) {
if (draw_list_split) {
return nullptr;
}
@@ -6182,6 +6462,19 @@ void RenderingDeviceVulkan::draw_list_bind_uniform_set(DrawListID p_list, RID p_
dl->state.sets[p_index].uniform_set_format = uniform_set->format;
dl->state.sets[p_index].uniform_set = p_uniform_set;
+ uint32_t mst_count = uniform_set->mutable_storage_textures.size();
+ if (mst_count) {
+ Texture **mst_textures = const_cast<UniformSet *>(uniform_set)->mutable_storage_textures.ptrw();
+ for (uint32_t i = 0; i < mst_count; i++) {
+ if (mst_textures[i]->used_in_frame != frames_drawn) {
+ mst_textures[i]->used_in_frame = frames_drawn;
+ mst_textures[i]->used_in_transfer = false;
+ mst_textures[i]->used_in_compute = false;
+ }
+ mst_textures[i]->used_in_raster = true;
+ }
+ }
+
#ifdef DEBUG_ENABLED
{ //validate that textures bound are not attached as framebuffer bindings
uint32_t attachable_count = uniform_set->attachable_textures.size();
@@ -6424,7 +6717,7 @@ void RenderingDeviceVulkan::draw_list_disable_scissor(DrawListID p_list) {
vkCmdSetScissor(dl->command_buffer, 0, 1, &scissor);
}
-void RenderingDeviceVulkan::draw_list_end() {
+void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_MSG(!draw_list, "Immediate draw list is already inactive.");
@@ -6433,8 +6726,8 @@ void RenderingDeviceVulkan::draw_list_end() {
//send all command buffers
VkCommandBuffer *command_buffers = (VkCommandBuffer *)alloca(sizeof(VkCommandBuffer) * draw_list_count);
for (uint32_t i = 0; i < draw_list_count; i++) {
- vkEndCommandBuffer(draw_list->command_buffer);
- command_buffers[i] = draw_list->command_buffer;
+ vkEndCommandBuffer(draw_list[i].command_buffer);
+ command_buffers[i] = draw_list[i].command_buffer;
}
vkCmdExecuteCommands(frames[frame].draw_command_buffer, draw_list_count, command_buffers);
@@ -6460,16 +6753,51 @@ void RenderingDeviceVulkan::draw_list_end() {
}
}
+ uint32_t barrier_flags = 0;
+ uint32_t access_flags = 0;
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT /*| VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT*/;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT /*| VK_ACCESS_INDIRECT_COMMAND_READ_BIT*/;
+ }
+ if (p_post_barrier & BARRIER_MASK_TRANSFER) {
+ barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
+ }
+
+ if (barrier_flags == 0) {
+ barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
draw_list_bound_textures.clear();
- for (int i = 0; i < draw_list_storage_textures.size(); i++) {
+ VkImageMemoryBarrier *image_barriers = nullptr;
+
+ uint32_t image_barrier_count = draw_list_storage_textures.size();
+
+ if (image_barrier_count) {
+ image_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * draw_list_storage_textures.size());
+ }
+
+ uint32_t src_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+ uint32_t src_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+
+ if (image_barrier_count) {
+ src_stage |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ src_access |= VK_ACCESS_SHADER_WRITE_BIT;
+ }
+
+ for (uint32_t i = 0; i < image_barrier_count; i++) {
Texture *texture = texture_owner.getornull(draw_list_storage_textures[i]);
- VkImageMemoryBarrier image_memory_barrier;
+ VkImageMemoryBarrier &image_memory_barrier = image_barriers[i];
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
- image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
- image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ image_memory_barrier.srcAccessMask = src_access;
+ image_memory_barrier.dstAccessMask = access_flags;
image_memory_barrier.oldLayout = texture->layout;
image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
@@ -6482,8 +6810,6 @@ void RenderingDeviceVulkan::draw_list_end() {
image_memory_barrier.subresourceRange.baseArrayLayer = texture->base_layer;
image_memory_barrier.subresourceRange.layerCount = texture->layers;
- vkCmdPipelineBarrier(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
-
texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
@@ -6496,7 +6822,17 @@ void RenderingDeviceVulkan::draw_list_end() {
#ifdef FORCE_FULL_BARRIER
_full_barrier(true);
#else
- _memory_barrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, true);
+
+ VkMemoryBarrier mem_barrier;
+ mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+ mem_barrier.pNext = nullptr;
+ mem_barrier.srcAccessMask = src_access;
+ mem_barrier.dstAccessMask = access_flags;
+
+ if (image_barrier_count > 0 || p_post_barrier != BARRIER_MASK_NO_BARRIER) {
+ vkCmdPipelineBarrier(frames[frame].draw_command_buffer, src_stage, barrier_flags, 0, 1, &mem_barrier, 0, nullptr, image_barrier_count, image_barriers);
+ }
+
#endif
}
@@ -6504,12 +6840,13 @@ void RenderingDeviceVulkan::draw_list_end() {
/**** COMPUTE LISTS ****/
/***********************/
-RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin() {
- ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
+RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin(bool p_allow_draw_overlap) {
+ ERR_FAIL_COND_V_MSG(!p_allow_draw_overlap && draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time.");
compute_list = memnew(ComputeList);
compute_list->command_buffer = frames[frame].draw_command_buffer;
+ compute_list->state.allow_draw_overlap = p_allow_draw_overlap;
return ID_TYPE_COMPUTE_LIST;
}
@@ -6566,6 +6903,9 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l
}
cl->state.pipeline_shader = pipeline->shader;
+ cl->state.local_group_size[0] = pipeline->local_group_size[0];
+ cl->state.local_group_size[1] = pipeline->local_group_size[1];
+ cl->state.local_group_size[2] = pipeline->local_group_size[2];
}
#ifdef DEBUG_ENABLED
@@ -6603,11 +6943,24 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
cl->state.sets[p_index].uniform_set = p_uniform_set;
uint32_t textures_to_sampled_count = uniform_set->mutable_sampled_textures.size();
+ uint32_t textures_to_storage_count = uniform_set->mutable_storage_textures.size();
+
Texture **textures_to_sampled = uniform_set->mutable_sampled_textures.ptrw();
+ VkImageMemoryBarrier *texture_barriers = nullptr;
+
+ if (textures_to_sampled_count + textures_to_storage_count) {
+ texture_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * (textures_to_sampled_count + textures_to_storage_count));
+ }
+ uint32_t texture_barrier_count = 0;
+
+ uint32_t src_stage_flags = 0;
+
for (uint32_t i = 0; i < textures_to_sampled_count; i++) {
if (textures_to_sampled[i]->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
- VkImageMemoryBarrier image_memory_barrier;
+ src_stage_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+
+ VkImageMemoryBarrier &image_memory_barrier = texture_barriers[texture_barrier_count++];
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
@@ -6624,23 +6977,55 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_sampled[i]->base_layer;
image_memory_barrier.subresourceRange.layerCount = textures_to_sampled[i]->layers;
- vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
-
textures_to_sampled[i]->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
cl->state.textures_to_sampled_layout.erase(textures_to_sampled[i]);
}
+
+ if (textures_to_sampled[i]->used_in_frame != frames_drawn) {
+ textures_to_sampled[i]->used_in_frame = frames_drawn;
+ textures_to_sampled[i]->used_in_transfer = false;
+ textures_to_sampled[i]->used_in_raster = false;
+ }
+ textures_to_sampled[i]->used_in_compute = true;
}
- uint32_t textures_to_storage_count = uniform_set->mutable_storage_textures.size();
Texture **textures_to_storage = uniform_set->mutable_storage_textures.ptrw();
for (uint32_t i = 0; i < textures_to_storage_count; i++) {
if (textures_to_storage[i]->layout != VK_IMAGE_LAYOUT_GENERAL) {
- VkImageMemoryBarrier image_memory_barrier;
+ uint32_t src_access_flags = 0;
+
+ if (textures_to_storage[i]->used_in_frame == frames_drawn) {
+ if (textures_to_storage[i]->used_in_compute) {
+ src_stage_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ src_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (textures_to_storage[i]->used_in_raster) {
+ src_stage_flags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
+ src_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (textures_to_storage[i]->used_in_transfer) {
+ src_stage_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ src_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
+ }
+
+ textures_to_storage[i]->used_in_compute = false;
+ textures_to_storage[i]->used_in_raster = false;
+ textures_to_storage[i]->used_in_compute = false;
+
+ } else {
+ src_access_flags = 0;
+ textures_to_storage[i]->used_in_compute = false;
+ textures_to_storage[i]->used_in_raster = false;
+ textures_to_storage[i]->used_in_compute = false;
+ textures_to_storage[i]->used_in_frame = frames_drawn;
+ }
+
+ VkImageMemoryBarrier &image_memory_barrier = texture_barriers[texture_barrier_count++];
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
- image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ image_memory_barrier.srcAccessMask = src_access_flags;
image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
image_memory_barrier.oldLayout = textures_to_storage[i]->layout;
image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
@@ -6654,14 +7039,20 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_storage[i]->base_layer;
image_memory_barrier.subresourceRange.layerCount = textures_to_storage[i]->layers;
- vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
-
textures_to_storage[i]->layout = VK_IMAGE_LAYOUT_GENERAL;
cl->state.textures_to_sampled_layout.insert(textures_to_storage[i]); //needs to go back to sampled layout afterwards
}
}
+ if (texture_barrier_count) {
+ if (src_stage_flags == 0) {
+ src_stage_flags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ }
+
+ vkCmdPipelineBarrier(cl->command_buffer, src_stage_flags, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, texture_barrier_count, texture_barriers);
+ }
+
#if 0
{ //validate that textures bound are not attached as framebuffer bindings
uint32_t attachable_count = uniform_set->attachable_textures.size();
@@ -6755,6 +7146,27 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t
vkCmdDispatch(cl->command_buffer, p_x_groups, p_y_groups, p_z_groups);
}
+void RenderingDeviceVulkan::compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads) {
+ ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST);
+ ERR_FAIL_COND(!compute_list);
+
+ ComputeList *cl = compute_list;
+
+#ifdef DEBUG_ENABLED
+
+ ERR_FAIL_COND_MSG(!cl->validation.pipeline_active, "No compute pipeline was set before attempting to draw.");
+
+ if (cl->validation.pipeline_push_constant_size > 0) {
+ //using push constants, check that they were supplied
+ ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_supplied,
+ "The shader in this pipeline requires a push constant to be set before drawing, but it's not present.");
+ }
+
+#endif
+
+ compute_list_dispatch(p_list, (p_x_threads - 1) / cl->state.local_group_size[0] + 1, (p_y_threads - 1) / cl->state.local_group_size[1] + 1, (p_z_threads - 1) / cl->state.local_group_size[2] + 1);
+}
+
void RenderingDeviceVulkan::compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) {
ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST);
ERR_FAIL_COND(!compute_list);
@@ -6819,14 +7231,44 @@ void RenderingDeviceVulkan::compute_list_add_barrier(ComputeListID p_list) {
#endif
}
-void RenderingDeviceVulkan::compute_list_end() {
+void RenderingDeviceVulkan::compute_list_end(uint32_t p_post_barrier) {
ERR_FAIL_COND(!compute_list);
+
+ uint32_t barrier_flags = 0;
+ uint32_t access_flags = 0;
+ if (p_post_barrier & BARRIER_MASK_COMPUTE) {
+ barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_RASTER) {
+ barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
+ access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
+ }
+ if (p_post_barrier & BARRIER_MASK_TRANSFER) {
+ barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
+ }
+
+ if (barrier_flags == 0) {
+ barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
+ VkImageMemoryBarrier *image_barriers = nullptr;
+
+ uint32_t image_barrier_count = compute_list->state.textures_to_sampled_layout.size();
+
+ if (image_barrier_count) {
+ image_barriers = (VkImageMemoryBarrier *)alloca(sizeof(VkImageMemoryBarrier) * image_barrier_count);
+ }
+
+ uint32_t barrier_idx = 0;
+
for (Set<Texture *>::Element *E = compute_list->state.textures_to_sampled_layout.front(); E; E = E->next()) {
- VkImageMemoryBarrier image_memory_barrier;
+ VkImageMemoryBarrier &image_memory_barrier = image_barriers[barrier_idx++];
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
image_memory_barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
- image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT;
+ image_memory_barrier.dstAccessMask = access_flags;
image_memory_barrier.oldLayout = E->get()->layout;
image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
@@ -6839,19 +7281,75 @@ void RenderingDeviceVulkan::compute_list_end() {
image_memory_barrier.subresourceRange.baseArrayLayer = E->get()->base_layer;
image_memory_barrier.subresourceRange.layerCount = E->get()->layers;
- // TODO: Look at the usages in the compute list and determine tighter dst stage and access masks based on some "final" usage equivalent
- vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
-
E->get()->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ if (E->get()->used_in_frame != frames_drawn) {
+ E->get()->used_in_transfer = false;
+ E->get()->used_in_raster = false;
+ E->get()->used_in_compute = false;
+ E->get()->used_in_frame = frames_drawn;
+ }
}
- memdelete(compute_list);
- compute_list = nullptr;
#ifdef FORCE_FULL_BARRIER
_full_barrier(true);
#else
- _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT, true);
+ VkMemoryBarrier mem_barrier;
+ mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+ mem_barrier.pNext = nullptr;
+ mem_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
+ mem_barrier.dstAccessMask = access_flags;
+
+ if (image_barrier_count > 0 || p_post_barrier != BARRIER_MASK_NO_BARRIER) {
+ vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, barrier_flags, 0, 1, &mem_barrier, 0, nullptr, image_barrier_count, image_barriers);
+ }
+
#endif
+
+ memdelete(compute_list);
+ compute_list = nullptr;
+}
+
+void RenderingDeviceVulkan::barrier(uint32_t p_from, uint32_t p_to) {
+ uint32_t src_barrier_flags = 0;
+ uint32_t src_access_flags = 0;
+ if (p_from & BARRIER_MASK_COMPUTE) {
+ src_barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ src_access_flags |= VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_from & BARRIER_MASK_RASTER) {
+ src_barrier_flags |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+ src_access_flags |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ }
+ if (p_from & BARRIER_MASK_TRANSFER) {
+ src_barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ src_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
+ }
+
+ if (p_from == 0) {
+ src_barrier_flags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ }
+
+ uint32_t dst_barrier_flags = 0;
+ uint32_t dst_access_flags = 0;
+ if (p_to & BARRIER_MASK_COMPUTE) {
+ dst_barrier_flags |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
+ dst_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ }
+ if (p_to & BARRIER_MASK_RASTER) {
+ dst_barrier_flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
+ dst_access_flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
+ }
+ if (p_to & BARRIER_MASK_TRANSFER) {
+ dst_barrier_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
+ dst_access_flags |= VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
+ }
+
+ if (p_to == 0) {
+ dst_barrier_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+ }
+
+ _memory_barrier(src_barrier_flags, dst_barrier_flags, src_access_flags, dst_access_flags, true);
}
void RenderingDeviceVulkan::full_barrier() {
@@ -6988,6 +7486,82 @@ void RenderingDeviceVulkan::free(RID p_id) {
_free_internal(p_id);
}
+// The full list of resources that can be named is in the VkObjectType enum
+// We just expose the resources that are owned and can be accessed easily.
+void RenderingDeviceVulkan::set_resource_name(RID p_id, const String p_name) {
+ if (texture_owner.owns(p_id)) {
+ Texture *texture = texture_owner.getornull(p_id);
+ if (texture->owner.is_null()) {
+ // Don't set the source texture's name when calling on a texture view
+ context->set_object_name(VK_OBJECT_TYPE_IMAGE, uint64_t(texture->image), p_name);
+ }
+ context->set_object_name(VK_OBJECT_TYPE_IMAGE_VIEW, uint64_t(texture->view), p_name + " View");
+ } else if (framebuffer_owner.owns(p_id)) {
+ //Framebuffer *framebuffer = framebuffer_owner.getornull(p_id);
+ // Not implemented for now as the relationship between Framebuffer and RenderPass is very complex
+ } else if (sampler_owner.owns(p_id)) {
+ VkSampler *sampler = sampler_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_SAMPLER, uint64_t(*sampler), p_name);
+ } else if (vertex_buffer_owner.owns(p_id)) {
+ Buffer *vertex_buffer = vertex_buffer_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(vertex_buffer->buffer), p_name);
+ } else if (index_buffer_owner.owns(p_id)) {
+ IndexBuffer *index_buffer = index_buffer_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(index_buffer->buffer), p_name);
+ } else if (shader_owner.owns(p_id)) {
+ Shader *shader = shader_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(shader->pipeline_layout), p_name + " Pipeline Layout");
+ for (int i = 0; i < shader->sets.size(); i++) {
+ context->set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, uint64_t(shader->sets[i].descriptor_set_layout), p_name);
+ }
+ } else if (uniform_buffer_owner.owns(p_id)) {
+ Buffer *uniform_buffer = uniform_buffer_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(uniform_buffer->buffer), p_name);
+ } else if (texture_buffer_owner.owns(p_id)) {
+ TextureBuffer *texture_buffer = texture_buffer_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(texture_buffer->buffer.buffer), p_name);
+ context->set_object_name(VK_OBJECT_TYPE_BUFFER_VIEW, uint64_t(texture_buffer->view), p_name + " View");
+ } else if (storage_buffer_owner.owns(p_id)) {
+ Buffer *storage_buffer = storage_buffer_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(storage_buffer->buffer), p_name);
+ } else if (uniform_set_owner.owns(p_id)) {
+ UniformSet *uniform_set = uniform_set_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET, uint64_t(uniform_set->descriptor_set), p_name);
+ } else if (render_pipeline_owner.owns(p_id)) {
+ RenderPipeline *pipeline = render_pipeline_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_PIPELINE, uint64_t(pipeline->pipeline), p_name);
+ context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(pipeline->pipeline_layout), p_name + " Layout");
+ } else if (compute_pipeline_owner.owns(p_id)) {
+ ComputePipeline *pipeline = compute_pipeline_owner.getornull(p_id);
+ context->set_object_name(VK_OBJECT_TYPE_PIPELINE, uint64_t(pipeline->pipeline), p_name);
+ context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(pipeline->pipeline_layout), p_name + " Layout");
+ } else {
+ ERR_PRINT("Attempted to name invalid ID: " + itos(p_id.get_id()));
+ }
+}
+
+void RenderingDeviceVulkan::draw_command_begin_label(String p_label_name, const Color p_color) {
+ context->command_begin_label(frames[frame].draw_command_buffer, p_label_name, p_color);
+}
+
+void RenderingDeviceVulkan::draw_command_insert_label(String p_label_name, const Color p_color) {
+ context->command_insert_label(frames[frame].draw_command_buffer, p_label_name, p_color);
+}
+
+void RenderingDeviceVulkan::draw_command_end_label() {
+ context->command_end_label(frames[frame].draw_command_buffer);
+}
+
+String RenderingDeviceVulkan::get_device_vendor_name() const {
+ return context->get_device_vendor_name();
+}
+String RenderingDeviceVulkan::get_device_name() const {
+ return context->get_device_name();
+}
+String RenderingDeviceVulkan::get_device_pipeline_cache_uuid() const {
+ return context->get_device_pipeline_cache_uuid();
+}
+
void RenderingDeviceVulkan::_finalize_command_bufers() {
if (draw_list) {
ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work).");
@@ -7040,6 +7614,7 @@ void RenderingDeviceVulkan::_begin_frame() {
if (frames[frame].timestamp_count) {
vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
+ vkCmdResetQueryPool(frames[frame].setup_command_buffer, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count);
SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names);
SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values);
}
@@ -7406,9 +7981,10 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) {
}
}
-void RenderingDeviceVulkan::capture_timestamp(const String &p_name, bool p_sync_to_draw) {
+void RenderingDeviceVulkan::capture_timestamp(const String &p_name) {
ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements);
+ //this should be optional for profiling, else it will slow things down
{
VkMemoryBarrier memoryBarrier;
@@ -7445,9 +8021,10 @@ void RenderingDeviceVulkan::capture_timestamp(const String &p_name, bool p_sync_
VK_ACCESS_HOST_READ_BIT |
VK_ACCESS_HOST_WRITE_BIT;
- vkCmdPipelineBarrier(p_sync_to_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
+ vkCmdPipelineBarrier(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
}
- vkCmdWriteTimestamp(p_sync_to_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frames[frame].timestamp_pool, frames[frame].timestamp_count);
+
+ vkCmdWriteTimestamp(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frames[frame].timestamp_pool, frames[frame].timestamp_count);
frames[frame].timestamp_names[frames[frame].timestamp_count] = p_name;
frames[frame].timestamp_cpu_values[frames[frame].timestamp_count] = OS::get_singleton()->get_ticks_usec();
frames[frame].timestamp_count++;
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 05c5b9c63e..a2527d5c33 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -141,6 +141,11 @@ class RenderingDeviceVulkan : public RenderingDevice {
VkImageLayout layout;
+ uint64_t used_in_frame = 0;
+ bool used_in_transfer = false;
+ bool used_in_raster = false;
+ bool used_in_compute = false;
+
uint32_t read_aspect_mask = 0;
uint32_t barrier_aspect_mask = 0;
bool bound = false; //bound to framebffer
@@ -228,13 +233,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
// used for the render pipelines.
struct FramebufferFormatKey {
- Size2i empty_size;
Vector<AttachmentFormat> attachments;
bool operator<(const FramebufferFormatKey &p_key) const {
- if (empty_size != p_key.empty_size) {
- return empty_size < p_key.empty_size;
- }
-
int as = attachments.size();
int bs = p_key.attachments.size();
if (as != bs) {
@@ -533,6 +533,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
PushConstant push_constant;
+ uint32_t compute_local_size[3] = { 0, 0, 0 };
+
bool is_compute = false;
int max_output = 0;
Vector<Set> sets;
@@ -691,6 +693,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
VkPipeline pipeline = VK_NULL_HANDLE;
uint32_t push_constant_size = 0;
uint32_t push_constant_stages = 0;
+ uint32_t local_group_size[3] = { 0, 0, 0 };
};
RID_Owner<ComputePipeline, true> compute_pipeline_owner;
@@ -790,7 +793,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass);
Error _draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents, const Vector<RID> &p_storage_textures);
_FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id);
- Buffer *_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &dst_stage_mask, VkAccessFlags &dst_access);
+ Buffer *_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &dst_stage_mask, VkAccessFlags &dst_access, uint32_t p_post_barrier);
/**********************/
/**** COMPUTE LIST ****/
@@ -813,8 +816,10 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t set_count = 0;
RID pipeline;
RID pipeline_shader;
+ uint32_t local_group_size[3] = { 0, 0, 0 };
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
uint32_t pipeline_push_constant_stages = 0;
+ bool allow_draw_overlap;
} state;
#ifdef DEBUG_ENABLED
@@ -918,27 +923,27 @@ public:
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture);
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
- virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false);
+ virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer);
virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const;
virtual bool texture_is_shared(RID p_texture);
virtual bool texture_is_valid(RID p_texture);
- virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false);
- virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false);
- virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw = false);
+ virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL);
+ virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL);
+ virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier = BARRIER_MASK_ALL);
/*********************/
/**** FRAMEBUFFER ****/
/*********************/
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format);
- virtual FramebufferFormatID framebuffer_format_create_empty(const Size2i &p_size);
+ virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1);
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format);
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID);
- virtual RID framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check = INVALID_ID);
+ virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID);
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer);
@@ -980,7 +985,8 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set);
virtual bool uniform_set_is_valid(RID p_uniform_set);
- virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw = false); //works for any buffer
+ virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL); //works for any buffer
+ virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL);
virtual Vector<uint8_t> buffer_get_data(RID p_buffer);
/*************************/
@@ -1026,22 +1032,24 @@ public:
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect);
virtual void draw_list_disable_scissor(DrawListID p_list);
- virtual void draw_list_end();
+ virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL);
/***********************/
/**** COMPUTE LISTS ****/
/***********************/
- virtual ComputeListID compute_list_begin();
+ virtual ComputeListID compute_list_begin(bool p_allow_draw_overlap = false);
virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline);
virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index);
virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size);
virtual void compute_list_add_barrier(ComputeListID p_list);
virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups);
+ virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads);
virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset);
- virtual void compute_list_end();
+ virtual void compute_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL);
+ virtual void barrier(uint32_t p_from = BARRIER_MASK_ALL, uint32_t p_to = BARRIER_MASK_ALL);
virtual void full_barrier();
/**************/
@@ -1054,7 +1062,7 @@ public:
/**** Timing ****/
/****************/
- virtual void capture_timestamp(const String &p_name, bool p_sync_to_draw);
+ virtual void capture_timestamp(const String &p_name);
virtual uint32_t get_captured_timestamps_count() const;
virtual uint64_t get_captured_timestamps_frame() const;
virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const;
@@ -1082,6 +1090,16 @@ public:
virtual uint64_t get_memory_usage() const;
+ virtual void set_resource_name(RID p_id, const String p_name);
+
+ virtual void draw_command_begin_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1));
+ virtual void draw_command_insert_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1));
+ virtual void draw_command_end_label();
+
+ virtual String get_device_vendor_name() const;
+ virtual String get_device_name() const;
+ virtual String get_device_pipeline_cache_uuid() const;
+
RenderingDeviceVulkan();
~RenderingDeviceVulkan();
};
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 1f4092745a..ad740efec4 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,10 +55,29 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
return VK_FALSE;
}
// This needs to be ignored because Validator is wrong here.
+ if (strstr(pCallbackData->pMessage, "Invalid SPIR-V binary version 1.3") != nullptr) {
+ return VK_FALSE;
+ }
+ // This needs to be ignored because Validator is wrong here.
+ if (strstr(pCallbackData->pMessage, "Shader requires flag") != nullptr) {
+ return VK_FALSE;
+ }
+
+ // This needs to be ignored because Validator is wrong here.
if (strstr(pCallbackData->pMessage, "SPIR-V module not valid: Pointer operand") != nullptr &&
strstr(pCallbackData->pMessage, "must be a memory object") != nullptr) {
return VK_FALSE;
}
+ /*
+ // This is a valid warning because its illegal in Vulkan, but in practice it should work according to VK_KHR_maintenance2
+ if (strstr(pCallbackData->pMessage, "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 with tiling VK_IMAGE_TILING_OPTIMAL does not support usage that includes VK_IMAGE_USAGE_STORAGE_BIT") != nullptr) {
+ return VK_FALSE;
+ }
+
+ if (strstr(pCallbackData->pMessage, "VK_FORMAT_R4G4B4A4_UNORM_PACK16 with tiling VK_IMAGE_TILING_OPTIMAL does not support usage that includes VK_IMAGE_USAGE_STORAGE_BIT") != nullptr) {
+ return VK_FALSE;
+ }
+*/
// Workaround for Vulkan-Loader usability bug: https://github.com/KhronosGroup/Vulkan-Loader/issues/262.
if (strstr(pCallbackData->pMessage, "wrong ELF class: ELFCLASS32") != nullptr) {
return VK_FALSE;
@@ -220,6 +239,7 @@ Error VulkanContext::_initialize_extensions() {
enabled_extension_count = 0;
enabled_layer_count = 0;
+ enabled_debug_utils = false;
/* Look for instance extensions */
VkBool32 surfaceExtFound = 0;
VkBool32 platformSurfaceExtFound = 0;
@@ -251,9 +271,8 @@ Error VulkanContext::_initialize_extensions() {
}
}
if (!strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, instance_extensions[i].extensionName)) {
- if (use_validation_layers) {
- extension_names[enabled_extension_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
- }
+ extension_names[enabled_extension_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
+ enabled_debug_utils = true;
}
if (enabled_extension_count >= MAX_EXTENSIONS) {
free(instance_extensions);
@@ -312,7 +331,7 @@ Error VulkanContext::_create_physical_device() {
* function to register the final callback.
*/
VkDebugUtilsMessengerCreateInfoEXT dbg_messenger_create_info;
- if (use_validation_layers) {
+ if (enabled_debug_utils) {
// VK_EXT_debug_utils style
dbg_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
dbg_messenger_create_info.pNext = nullptr;
@@ -361,7 +380,8 @@ Error VulkanContext::_create_physical_device() {
ERR_FAIL_V(ERR_CANT_CREATE);
}
/* for now, just grab the first physical device */
- gpu = physical_devices[0];
+ uint32_t device_index = 0;
+ gpu = physical_devices[device_index];
free(physical_devices);
/* Look for device extensions */
@@ -370,6 +390,40 @@ Error VulkanContext::_create_physical_device() {
enabled_extension_count = 0;
memset(extension_names, 0, sizeof(extension_names));
+ /* Get identifier properties */
+ vkGetPhysicalDeviceProperties(gpu, &gpu_props);
+
+ static const struct {
+ uint32_t id;
+ const char *name;
+ } vendor_names[] = {
+ { 0x1002, "AMD" },
+ { 0x1010, "ImgTec" },
+ { 0x10DE, "NVIDIA" },
+ { 0x13B5, "ARM" },
+ { 0x5143, "Qualcomm" },
+ { 0x8086, "INTEL" },
+ { 0, nullptr },
+ };
+ device_name = gpu_props.deviceName;
+ pipeline_cache_id = String::hex_encode_buffer(gpu_props.pipelineCacheUUID, VK_UUID_SIZE);
+ pipeline_cache_id += "-driver-" + itos(gpu_props.driverVersion);
+ {
+ device_vendor = "Unknown";
+ uint32_t vendor_idx = 0;
+ while (vendor_names[vendor_idx].name != nullptr) {
+ if (gpu_props.vendorID == vendor_names[vendor_idx].id) {
+ device_vendor = vendor_names[vendor_idx].name;
+ break;
+ }
+ vendor_idx++;
+ }
+ }
+#ifdef DEBUG_ENABLED
+ print_line("Using Vulkan Device #" + itos(device_index) + ": " + device_vendor + " - " + device_name);
+#endif
+ device_api_version = gpu_props.apiVersion;
+
err = vkEnumerateDeviceExtensionProperties(gpu, nullptr, &device_extension_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
@@ -436,7 +490,7 @@ Error VulkanContext::_create_physical_device() {
" extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\n"
"vkCreateInstance Failure");
- if (use_validation_layers) {
+ if (enabled_debug_utils) {
// Setup VK_EXT_debug_utils function pointers always (we use them for
// debug labels and names).
CreateDebugUtilsMessengerEXT =
@@ -479,7 +533,6 @@ Error VulkanContext::_create_physical_device() {
break;
}
}
- vkGetPhysicalDeviceProperties(gpu, &gpu_props);
/* Call with NULL data to get count */
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queue_family_count, nullptr);
@@ -546,6 +599,7 @@ Error VulkanContext::_create_device() {
}
err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+
return OK;
}
@@ -1567,6 +1621,70 @@ void VulkanContext::local_device_free(RID p_local_device) {
local_device_owner.free(p_local_device);
}
+void VulkanContext::command_begin_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color) {
+ if (!enabled_debug_utils) {
+ return;
+ }
+
+ CharString cs = p_label_name.utf8().get_data();
+ VkDebugUtilsLabelEXT label;
+ label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
+ label.pNext = nullptr;
+ label.pLabelName = cs.get_data();
+ label.color[0] = p_color[0];
+ label.color[1] = p_color[1];
+ label.color[2] = p_color[2];
+ label.color[3] = p_color[3];
+ CmdBeginDebugUtilsLabelEXT(p_command_buffer, &label);
+}
+
+void VulkanContext::command_insert_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color) {
+ if (!enabled_debug_utils) {
+ return;
+ }
+ CharString cs = p_label_name.utf8().get_data();
+ VkDebugUtilsLabelEXT label;
+ label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
+ label.pNext = nullptr;
+ label.pLabelName = cs.get_data();
+ label.color[0] = p_color[0];
+ label.color[1] = p_color[1];
+ label.color[2] = p_color[2];
+ label.color[3] = p_color[3];
+ CmdInsertDebugUtilsLabelEXT(p_command_buffer, &label);
+}
+
+void VulkanContext::command_end_label(VkCommandBuffer p_command_buffer) {
+ if (!enabled_debug_utils) {
+ return;
+ }
+ CmdEndDebugUtilsLabelEXT(p_command_buffer);
+}
+
+void VulkanContext::set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name) {
+ if (!enabled_debug_utils) {
+ return;
+ }
+ CharString obj_data = p_object_name.utf8();
+ VkDebugUtilsObjectNameInfoEXT name_info;
+ name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+ name_info.pNext = nullptr;
+ name_info.objectType = p_object_type;
+ name_info.objectHandle = p_object_handle;
+ name_info.pObjectName = obj_data.get_data();
+ SetDebugUtilsObjectNameEXT(device, &name_info);
+}
+
+String VulkanContext::get_device_vendor_name() const {
+ return device_vendor;
+}
+String VulkanContext::get_device_name() const {
+ return device_name;
+}
+String VulkanContext::get_device_pipeline_cache_uuid() const {
+ return pipeline_cache_id;
+}
+
VulkanContext::VulkanContext() {
use_validation_layers = Engine::get_singleton()->is_validation_layers_enabled();
@@ -1587,7 +1705,7 @@ VulkanContext::~VulkanContext() {
vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr);
}
}
- if (inst_initialized && use_validation_layers) {
+ if (inst_initialized && enabled_debug_utils) {
DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr);
}
vkDestroyDevice(device, nullptr);
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 1aaad29ccd..dc6b0410bc 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,6 +57,11 @@ class VulkanContext {
bool device_initialized = false;
bool inst_initialized = false;
+ String device_vendor;
+ String device_name;
+ String pipeline_cache_id;
+ uint32_t device_api_version = 0;
+
bool buffers_prepared = false;
// Present queue.
@@ -119,6 +124,7 @@ class VulkanContext {
bool VK_GOOGLE_display_timing_enabled = true;
uint32_t enabled_extension_count = 0;
const char *extension_names[MAX_EXTENSIONS];
+ bool enabled_debug_utils = false;
uint32_t enabled_layer_count = 0;
const char *enabled_layers[MAX_LAYERS];
@@ -209,6 +215,15 @@ public:
Error swap_buffers();
Error initialize();
+ void command_begin_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color);
+ void command_insert_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color);
+ void command_end_label(VkCommandBuffer p_command_buffer);
+ void set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name);
+
+ String get_device_vendor_name() const;
+ String get_device_name() const;
+ String get_device_pipeline_cache_uuid() const;
+
VulkanContext();
virtual ~VulkanContext();
};
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 67e175d8d1..43c8722b06 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -387,7 +387,7 @@ Error AudioDriverWASAPI::finish_capture_device() {
}
Error AudioDriverWASAPI::init() {
- mix_rate = GLOBAL_GET("audio/mix_rate");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
Error err = init_render_device();
if (err != OK) {
@@ -397,7 +397,7 @@ Error AudioDriverWASAPI::init() {
exit_thread = false;
thread_exited = false;
- thread = Thread::create(thread_func, this);
+ thread.start(thread_func, this);
return OK;
}
@@ -767,13 +767,8 @@ void AudioDriverWASAPI::unlock() {
}
void AudioDriverWASAPI::finish() {
- if (thread) {
- exit_thread = true;
- Thread::wait_to_finish(thread);
-
- memdelete(thread);
- thread = nullptr;
- }
+ exit_thread = true;
+ thread.wait_to_finish();
finish_capture_device();
finish_render_device();
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index 41ff7c9895..b9b325f0fb 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,7 +64,7 @@ class AudioDriverWASAPI : public AudioDriver {
AudioDeviceWASAPI audio_output;
Mutex mutex;
- Thread *thread = nullptr;
+ Thread thread;
Vector<int32_t> samples_in;
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 197cd1d074..2c9f28717d 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h
index 3b059b1626..7f10023470 100644
--- a/drivers/windows/dir_access_windows.h
+++ b/drivers/windows/dir_access_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index ec393c98ba..35f61c0623 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 98c0efe576..507e0b2c20 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/windows/rw_lock_windows.h b/drivers/windows/rw_lock_windows.h
deleted file mode 100644
index 61dd679d32..0000000000
--- a/drivers/windows/rw_lock_windows.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*************************************************************************/
-/* rw_lock_windows.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef RWLOCKWINDOWS_H
-#define RWLOCKWINDOWS_H
-
-#if defined(WINDOWS_ENABLED)
-
-#include "core/os/rw_lock.h"
-
-#include <windows.h>
-
-class RWLockWindows : public RWLock {
- SRWLOCK lock;
-
- static RWLock *create_func_windows();
-
-public:
- virtual void read_lock();
- virtual void read_unlock();
- virtual Error read_try_lock();
-
- virtual void write_lock();
- virtual void write_unlock();
- virtual Error write_try_lock();
-
- static void make_default();
-
- RWLockWindows();
-
- ~RWLockWindows();
-};
-
-#endif
-
-#endif // RWLOCKWINDOWS_H
diff --git a/drivers/windows/thread_windows.cpp b/drivers/windows/thread_windows.cpp
deleted file mode 100644
index ca7d936fac..0000000000
--- a/drivers/windows/thread_windows.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*************************************************************************/
-/* thread_windows.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "thread_windows.h"
-
-#if defined(WINDOWS_ENABLED) && !defined(UWP_ENABLED)
-
-#include "core/os/memory.h"
-
-Thread::ID ThreadWindows::get_id() const {
- return id;
-}
-
-Thread *ThreadWindows::create_thread_windows() {
- return memnew(ThreadWindows);
-}
-
-DWORD ThreadWindows::thread_callback(LPVOID userdata) {
- ThreadWindows *t = reinterpret_cast<ThreadWindows *>(userdata);
-
- ScriptServer::thread_enter(); //scripts may need to attach a stack
-
- t->id = (ID)GetCurrentThreadId(); // must implement
- t->callback(t->user);
- SetEvent(t->handle);
-
- ScriptServer::thread_exit();
-
- return 0;
-}
-
-Thread *ThreadWindows::create_func_windows(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
- ThreadWindows *tr = memnew(ThreadWindows);
- tr->callback = p_callback;
- tr->user = p_user;
- tr->handle = CreateEvent(nullptr, TRUE, FALSE, nullptr);
-
- QueueUserWorkItem(thread_callback, tr, WT_EXECUTELONGFUNCTION);
-
- return tr;
-}
-
-Thread::ID ThreadWindows::get_thread_id_func_windows() {
- return (ID)GetCurrentThreadId(); //must implement
-}
-
-void ThreadWindows::wait_to_finish_func_windows(Thread *p_thread) {
- ThreadWindows *tp = static_cast<ThreadWindows *>(p_thread);
- ERR_FAIL_COND(!tp);
- WaitForSingleObject(tp->handle, INFINITE);
- CloseHandle(tp->handle);
- //`memdelete(tp);
-}
-
-void ThreadWindows::make_default() {
- create_func = create_func_windows;
- get_thread_id_func = get_thread_id_func_windows;
- wait_to_finish_func = wait_to_finish_func_windows;
-}
-
-#endif
diff --git a/drivers/windows/thread_windows.h b/drivers/windows/thread_windows.h
deleted file mode 100644
index 939f487fc1..0000000000
--- a/drivers/windows/thread_windows.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*************************************************************************/
-/* thread_windows.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef THREAD_WINDOWS_H
-#define THREAD_WINDOWS_H
-
-#ifdef WINDOWS_ENABLED
-
-#include "core/object/script_language.h"
-#include "core/os/thread.h"
-
-#include <windows.h>
-
-class ThreadWindows : public Thread {
- ThreadCreateCallback callback;
- void *user;
- ID id;
- HANDLE handle = nullptr;
-
- static Thread *create_thread_windows();
-
- static DWORD WINAPI thread_callback(LPVOID userdata);
-
- static Thread *create_func_windows(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID get_thread_id_func_windows();
- static void wait_to_finish_func_windows(Thread *p_thread);
-
- ThreadWindows() {}
-
-public:
- virtual ID get_id() const;
-
- static void make_default();
-
- ~ThreadWindows() {}
-};
-
-#endif
-
-#endif
diff --git a/drivers/winmidi/midi_driver_winmidi.cpp b/drivers/winmidi/midi_driver_winmidi.cpp
index 75f57b3bb9..730d608bbf 100644
--- a/drivers/winmidi/midi_driver_winmidi.cpp
+++ b/drivers/winmidi/midi_driver_winmidi.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/winmidi/midi_driver_winmidi.h b/drivers/winmidi/midi_driver_winmidi.h
index 9ed3fc2faa..bb9a87d610 100644
--- a/drivers/winmidi/midi_driver_winmidi.h
+++ b/drivers/winmidi/midi_driver_winmidi.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp
index c9ad054089..1c7bf5d6c6 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.cpp
+++ b/drivers/xaudio2/audio_driver_xaudio2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,12 +44,12 @@ Error AudioDriverXAudio2::init() {
pcm_open = false;
samples_in = nullptr;
- mix_rate = GLOBAL_GET("audio/mix_rate");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
// FIXME: speaker_mode seems unused in the Xaudio2 driver so far
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_GET("audio/output_latency");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
buffer_size = closest_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_size * channels);
@@ -78,7 +78,7 @@ Error AudioDriverXAudio2::init() {
hr = xaudio->CreateSourceVoice(&source_voice, &wave_format, 0, XAUDIO2_MAX_FREQ_RATIO, &voice_callback);
ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_UNAVAILABLE, "Error creating XAudio2 source voice. Error code: " + itos(hr) + ".");
- thread = Thread::create(AudioDriverXAudio2::thread_func, this);
+ thread.start(AudioDriverXAudio2::thread_func, this);
return OK;
}
@@ -146,23 +146,16 @@ float AudioDriverXAudio2::get_latency() {
}
void AudioDriverXAudio2::lock() {
- if (!thread)
- return;
mutex.lock();
}
void AudioDriverXAudio2::unlock() {
- if (!thread)
- return;
mutex.unlock();
}
void AudioDriverXAudio2::finish() {
- if (!thread)
- return;
-
exit_thread = true;
- Thread::wait_to_finish(thread);
+ thread.wait_to_finish();
if (source_voice) {
source_voice->Stop(0);
@@ -179,9 +172,6 @@ void AudioDriverXAudio2::finish() {
}
mastering_voice->DestroyVoice();
-
- memdelete(thread);
- thread = nullptr;
}
AudioDriverXAudio2::AudioDriverXAudio2() {
diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h
index 0aed072ec6..d3938a19d0 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.h
+++ b/drivers/xaudio2/audio_driver_xaudio2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -62,7 +62,7 @@ class AudioDriverXAudio2 : public AudioDriver {
void STDMETHODCALLTYPE OnVoiceError(void *pBufferContext, HRESULT Error) {}
};
- Thread *thread = nullptr;
+ Thread thread;
Mutex mutex;
int32_t *samples_in = nullptr;
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
new file mode 100644
index 0000000000..55640ca590
--- /dev/null
+++ b/editor/action_map_editor.cpp
@@ -0,0 +1,1167 @@
+/*************************************************************************/
+/* action_map_editor.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "action_map_editor.h"
+#include "core/input/input_map.h"
+#include "core/os/keyboard.h"
+#include "editor/editor_scale.h"
+#include "scene/gui/center_container.h"
+
+/////////////////////////////////////////
+
+// Maps to 2*axis if value is neg, or + 1 if value is pos.
+static const char *_joy_axis_descriptions[JOY_AXIS_MAX * 2] = {
+ TTRC("Left Stick Left, Joystick 0 Left"),
+ TTRC("Left Stick Right, Joystick 0 Right"),
+ TTRC("Left Stick Up, Joystick 0 Up"),
+ TTRC("Left Stick Down, Joystick 0 Down"),
+ TTRC("Right Stick Left, Joystick 1 Left"),
+ TTRC("Right Stick Right, Joystick 1 Right"),
+ TTRC("Right Stick Up, Joystick 1 Up"),
+ TTRC("Right Stick Down, Joystick 1 Down"),
+ TTRC("Joystick 2 Left"),
+ TTRC("Left Trigger, Sony L2, Xbox LT, Joystick 2 Right"),
+ TTRC("Joystick 2 Up"),
+ TTRC("Right Trigger, Sony R2, Xbox RT, Joystick 2 Down"),
+ TTRC("Joystick 3 Left"),
+ TTRC("Joystick 3 Right"),
+ TTRC("Joystick 3 Up"),
+ TTRC("Joystick 3 Down"),
+ TTRC("Joystick 4 Left"),
+ TTRC("Joystick 4 Right"),
+ TTRC("Joystick 4 Up"),
+ TTRC("Joystick 4 Down"),
+};
+
+String InputEventConfigurationDialog::get_event_text(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEvent");
+
+ // Joypad motion events will display slighlty differently than what the event->as_text() provides. See #43660.
+ Ref<InputEventJoypadMotion> jpmotion = p_event;
+ if (jpmotion.is_valid()) {
+ String desc = TTR("Unknown Joypad Axis");
+ if (jpmotion->get_axis() < JOY_AXIS_MAX) {
+ desc = RTR(_joy_axis_descriptions[2 * jpmotion->get_axis() + (jpmotion->get_axis_value() < 0 ? 0 : 1)]);
+ }
+
+ return vformat("Joypad Axis %s %s (%s)", itos(jpmotion->get_axis()), jpmotion->get_axis_value() < 0 ? "-" : "+", desc);
+ } else {
+ return p_event->as_text();
+ }
+}
+
+void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event) {
+ if (p_event.is_valid()) {
+ event = p_event;
+
+ // Update Label
+ event_as_text->set_text(get_event_text(event));
+
+ Ref<InputEventKey> k = p_event;
+ Ref<InputEventMouseButton> mb = p_event;
+ Ref<InputEventJoypadButton> joyb = p_event;
+ Ref<InputEventJoypadMotion> joym = p_event;
+ Ref<InputEventWithModifiers> mod = p_event;
+
+ // Update option values and visibility
+ bool show_mods = false;
+ bool show_device = false;
+ bool show_phys_key = false;
+
+ if (mod.is_valid()) {
+ show_mods = true;
+ mod_checkboxes[MOD_ALT]->set_pressed(mod->get_alt());
+ mod_checkboxes[MOD_SHIFT]->set_pressed(mod->get_shift());
+ mod_checkboxes[MOD_COMMAND]->set_pressed(mod->get_command());
+ mod_checkboxes[MOD_CONTROL]->set_pressed(mod->get_control());
+ mod_checkboxes[MOD_META]->set_pressed(mod->get_metakey());
+
+ store_command_checkbox->set_pressed(mod->is_storing_command());
+ }
+
+ if (k.is_valid()) {
+ show_phys_key = true;
+ physical_key_checkbox->set_pressed(k->get_physical_keycode() != 0 && k->get_keycode() == 0);
+
+ } else if (joyb.is_valid() || joym.is_valid() || mb.is_valid()) {
+ show_device = true;
+ _set_current_device(event->get_device());
+ }
+
+ mod_container->set_visible(show_mods);
+ device_container->set_visible(show_device);
+ physical_key_checkbox->set_visible(show_phys_key);
+ additional_options_container->show();
+
+ // Update selected item in input list for keys, joybuttons and joyaxis only (since the mouse cannot be "listened" for).
+ if (k.is_valid() || joyb.is_valid() || joym.is_valid()) {
+ TreeItem *category = input_list_tree->get_root()->get_children();
+ while (category) {
+ TreeItem *input_item = category->get_children();
+
+ // has_type this should be always true, unless the tree structure has been misconfigured.
+ bool has_type = input_item->get_parent()->has_meta("__type");
+ int input_type = input_item->get_parent()->get_meta("__type");
+ if (!has_type) {
+ return;
+ }
+
+ // If event type matches input types of this category.
+ if ((k.is_valid() && input_type == INPUT_KEY) || (joyb.is_valid() && input_type == INPUT_JOY_BUTTON) || (joym.is_valid() && input_type == INPUT_JOY_MOTION)) {
+ // Loop through all items of this category until one matches.
+ while (input_item) {
+ bool key_match = k.is_valid() && (Variant(k->get_keycode()) == input_item->get_meta("__keycode") || Variant(k->get_physical_keycode()) == input_item->get_meta("__keycode"));
+ bool joyb_match = joyb.is_valid() && Variant(joyb->get_button_index()) == input_item->get_meta("__index");
+ bool joym_match = joym.is_valid() && Variant(joym->get_axis()) == input_item->get_meta("__axis") && joym->get_axis_value() == (float)input_item->get_meta("__value");
+ if (key_match || joyb_match || joym_match) {
+ category->set_collapsed(false);
+ input_item->select(0);
+ input_list_tree->ensure_cursor_is_visible();
+ return;
+ }
+ input_item = input_item->get_next();
+ }
+ }
+
+ category->set_collapsed(true); // Event not in this category, so collapse;
+ category = category->get_next();
+ }
+ }
+ } else {
+ // Event is not valid, reset dialog
+ event = p_event;
+ Vector<String> strings;
+
+ // Reset message, promp for input according to which input types are allowed.
+ String text = TTR("Perform an Input (%s).");
+
+ if (allowed_input_types & INPUT_KEY) {
+ strings.append(TTR("Key"));
+ }
+ // We don't check for INPUT_MOUSE_BUTTON since it is ignored in the "Listen Window Input" method.
+
+ if (allowed_input_types & INPUT_JOY_BUTTON) {
+ strings.append(TTR("Joypad Button"));
+ }
+ if (allowed_input_types & INPUT_JOY_MOTION) {
+ strings.append(TTR("Joypad Axis"));
+ }
+
+ if (strings.size() == 0) {
+ text = TTR("Input Event dialog has been misconfigured: No input types are allowed.");
+ event_as_text->set_text(text);
+ } else {
+ String insert_text = String(", ").join(strings);
+ event_as_text->set_text(vformat(text, insert_text));
+ }
+
+ additional_options_container->hide();
+ input_list_tree->deselect_all();
+ _update_input_list();
+ }
+}
+
+void InputEventConfigurationDialog::_tab_selected(int p_tab) {
+ Callable signal_method = callable_mp(this, &InputEventConfigurationDialog::_listen_window_input);
+ if (p_tab == 0) {
+ // Start Listening.
+ if (!is_connected("window_input", signal_method)) {
+ connect("window_input", signal_method);
+ }
+ } else {
+ // Stop Listening.
+ if (is_connected("window_input", signal_method)) {
+ disconnect("window_input", signal_method);
+ }
+ input_list_tree->call_deferred("ensure_cursor_is_visible");
+ if (input_list_tree->get_selected() == nullptr) {
+ // If nothing selected, scroll to top.
+ input_list_tree->scroll_to_item(input_list_tree->get_root());
+ }
+ }
+}
+
+void InputEventConfigurationDialog::_listen_window_input(const Ref<InputEvent> &p_event) {
+ // Ignore if echo or not pressed
+ if (p_event->is_echo() || !p_event->is_pressed()) {
+ return;
+ }
+
+ // Ignore mouse
+ Ref<InputEventMouse> m = p_event;
+ if (m.is_valid()) {
+ return;
+ }
+
+ // Check what the type is and if it is allowed.
+ Ref<InputEventKey> k = p_event;
+ Ref<InputEventJoypadButton> joyb = p_event;
+ Ref<InputEventJoypadMotion> joym = p_event;
+
+ int type = k.is_valid() ? INPUT_KEY : joyb.is_valid() ? INPUT_JOY_BUTTON :
+ joym.is_valid() ? INPUT_JOY_MOTION :
+ 0;
+
+ if (!(allowed_input_types & type)) {
+ return;
+ }
+
+ if (joym.is_valid()) {
+ float axis_value = joym->get_axis_value();
+ if (ABS(axis_value) < 0.9) {
+ // Ignore motion below 0.9 magnitude to avoid accidental touches
+ return;
+ } else {
+ // Always make the value 1 or -1 for display consistency
+ joym->set_axis_value(SGN(axis_value));
+ }
+ }
+
+ if (k.is_valid()) {
+ k->set_pressed(false); // to avoid serialisation of 'pressed' property - doesn't matter for actions anyway.
+ // Maintain physical keycode option state
+ if (physical_key_checkbox->is_pressed()) {
+ k->set_physical_keycode(k->get_keycode());
+ k->set_keycode(0);
+ } else {
+ k->set_keycode(k->get_physical_keycode());
+ k->set_physical_keycode(0);
+ }
+ }
+
+ Ref<InputEventWithModifiers> mod = p_event;
+ if (mod.is_valid()) {
+ // Maintain store command option state
+ mod->set_store_command(store_command_checkbox->is_pressed());
+
+ mod->set_window_id(0);
+ }
+
+ _set_event(p_event);
+ set_input_as_handled();
+}
+
+void InputEventConfigurationDialog::_search_term_updated(const String &) {
+ _update_input_list();
+}
+
+void InputEventConfigurationDialog::_update_input_list() {
+ input_list_tree->clear();
+
+ TreeItem *root = input_list_tree->create_item();
+ String search_term = input_list_search->get_text();
+
+ bool collapse = input_list_search->get_text().is_empty();
+
+ if (allowed_input_types & INPUT_KEY) {
+ TreeItem *kb_root = input_list_tree->create_item(root);
+ kb_root->set_text(0, TTR("Keyboard Keys"));
+ kb_root->set_icon(0, icon_cache.keyboard);
+ kb_root->set_collapsed(collapse);
+ kb_root->set_meta("__type", INPUT_KEY);
+
+ for (int i = 0; i < keycode_get_count(); i++) {
+ String name = keycode_get_name_by_index(i);
+
+ if (!search_term.is_empty() && name.findn(search_term) == -1) {
+ continue;
+ }
+
+ TreeItem *item = input_list_tree->create_item(kb_root);
+ item->set_text(0, name);
+ item->set_meta("__keycode", keycode_get_value_by_index(i));
+ }
+ }
+
+ if (allowed_input_types & INPUT_MOUSE_BUTTON) {
+ TreeItem *mouse_root = input_list_tree->create_item(root);
+ mouse_root->set_text(0, TTR("Mouse Buttons"));
+ mouse_root->set_icon(0, icon_cache.mouse);
+ mouse_root->set_collapsed(collapse);
+ mouse_root->set_meta("__type", INPUT_MOUSE_BUTTON);
+
+ int mouse_buttons[9] = { BUTTON_LEFT, BUTTON_RIGHT, BUTTON_MIDDLE, BUTTON_WHEEL_UP, BUTTON_WHEEL_DOWN, BUTTON_WHEEL_LEFT, BUTTON_WHEEL_RIGHT, BUTTON_XBUTTON1, BUTTON_XBUTTON2 };
+ for (int i = 0; i < 9; i++) {
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+ mb->set_button_index(mouse_buttons[i]);
+ String desc = get_event_text(mb);
+
+ if (!search_term.is_empty() && desc.findn(search_term) == -1) {
+ continue;
+ }
+
+ TreeItem *item = input_list_tree->create_item(mouse_root);
+ item->set_text(0, desc);
+ item->set_meta("__index", mouse_buttons[i]);
+ }
+ }
+
+ if (allowed_input_types & INPUT_JOY_BUTTON) {
+ TreeItem *joyb_root = input_list_tree->create_item(root);
+ joyb_root->set_text(0, TTR("Joypad Buttons"));
+ joyb_root->set_icon(0, icon_cache.joypad_button);
+ joyb_root->set_collapsed(collapse);
+ joyb_root->set_meta("__type", INPUT_JOY_BUTTON);
+
+ for (int i = 0; i < JOY_BUTTON_MAX; i++) {
+ Ref<InputEventJoypadButton> joyb;
+ joyb.instance();
+ joyb->set_button_index(i);
+ String desc = get_event_text(joyb);
+
+ if (!search_term.is_empty() && desc.findn(search_term) == -1) {
+ continue;
+ }
+
+ TreeItem *item = input_list_tree->create_item(joyb_root);
+ item->set_text(0, desc);
+ item->set_meta("__index", i);
+ }
+ }
+
+ if (allowed_input_types & INPUT_JOY_MOTION) {
+ TreeItem *joya_root = input_list_tree->create_item(root);
+ joya_root->set_text(0, TTR("Joypad Axes"));
+ joya_root->set_icon(0, icon_cache.joypad_axis);
+ joya_root->set_collapsed(collapse);
+ joya_root->set_meta("__type", INPUT_JOY_MOTION);
+
+ for (int i = 0; i < JOY_AXIS_MAX * 2; i++) {
+ int axis = i / 2;
+ int direction = (i & 1) ? 1 : -1;
+ Ref<InputEventJoypadMotion> joym;
+ joym.instance();
+ joym->set_axis(axis);
+ joym->set_axis_value(direction);
+ String desc = get_event_text(joym);
+
+ if (!search_term.is_empty() && desc.findn(search_term) == -1) {
+ continue;
+ }
+
+ TreeItem *item = input_list_tree->create_item(joya_root);
+ item->set_text(0, desc);
+ item->set_meta("__axis", i >> 1);
+ item->set_meta("__value", (i & 1) ? 1 : -1);
+ }
+ }
+}
+
+void InputEventConfigurationDialog::_mod_toggled(bool p_checked, int p_index) {
+ Ref<InputEventWithModifiers> ie = event;
+
+ // Not event with modifiers
+ if (ie.is_null()) {
+ return;
+ }
+
+ if (p_index == 0) {
+ ie->set_alt(p_checked);
+ } else if (p_index == 1) {
+ ie->set_shift(p_checked);
+ } else if (p_index == 2) {
+ ie->set_command(p_checked);
+ } else if (p_index == 3) {
+ ie->set_control(p_checked);
+ } else if (p_index == 4) {
+ ie->set_metakey(p_checked);
+ }
+
+ _set_event(ie);
+}
+
+void InputEventConfigurationDialog::_store_command_toggled(bool p_checked) {
+ Ref<InputEventWithModifiers> ie = event;
+ if (ie.is_valid()) {
+ ie->set_store_command(p_checked);
+ _set_event(ie);
+ }
+
+ if (p_checked) {
+ // If storing Command, show it's checkbox and hide Control (Win/Lin) or Meta (Mac)
+#ifdef APPLE_STYLE_KEYS
+ mod_checkboxes[MOD_META]->hide();
+
+ mod_checkboxes[MOD_COMMAND]->show();
+ mod_checkboxes[MOD_COMMAND]->set_text("Meta (Command)");
+#else
+ mod_checkboxes[MOD_CONTROL]->hide();
+
+ mod_checkboxes[MOD_COMMAND]->show();
+ mod_checkboxes[MOD_COMMAND]->set_text("Control (Command)");
+#endif
+ } else {
+ // If not, hide Command, show Control and Meta.
+ mod_checkboxes[MOD_COMMAND]->hide();
+ mod_checkboxes[MOD_CONTROL]->show();
+ mod_checkboxes[MOD_META]->show();
+ }
+}
+
+void InputEventConfigurationDialog::_physical_keycode_toggled(bool p_checked) {
+ Ref<InputEventKey> k = event;
+
+ if (k.is_null()) {
+ return;
+ }
+
+ if (p_checked) {
+ k->set_physical_keycode(k->get_keycode());
+ k->set_keycode(0);
+ } else {
+ k->set_keycode(k->get_physical_keycode());
+ k->set_physical_keycode(0);
+ }
+
+ _set_event(k);
+}
+
+void InputEventConfigurationDialog::_input_list_item_selected() {
+ TreeItem *selected = input_list_tree->get_selected();
+
+ // Invalid tree selection - type only exists on the "category" items, which are not a valid selection.
+ if (selected->has_meta("__type")) {
+ return;
+ }
+
+ int input_type = selected->get_parent()->get_meta("__type");
+
+ switch (input_type) {
+ case InputEventConfigurationDialog::INPUT_KEY: {
+ int kc = selected->get_meta("__keycode");
+ Ref<InputEventKey> k;
+ k.instance();
+
+ if (physical_key_checkbox->is_pressed()) {
+ k->set_physical_keycode(kc);
+ k->set_keycode(0);
+ } else {
+ k->set_physical_keycode(0);
+ k->set_keycode(kc);
+ }
+
+ // Maintain modifier state from checkboxes
+ k->set_alt(mod_checkboxes[MOD_ALT]->is_pressed());
+ k->set_shift(mod_checkboxes[MOD_SHIFT]->is_pressed());
+ k->set_command(mod_checkboxes[MOD_COMMAND]->is_pressed());
+ k->set_control(mod_checkboxes[MOD_CONTROL]->is_pressed());
+ k->set_metakey(mod_checkboxes[MOD_META]->is_pressed());
+ k->set_store_command(store_command_checkbox->is_pressed());
+
+ _set_event(k);
+ } break;
+ case InputEventConfigurationDialog::INPUT_MOUSE_BUTTON: {
+ int idx = selected->get_meta("__index");
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+ mb->set_button_index(idx);
+ // Maintain modifier state from checkboxes
+ mb->set_alt(mod_checkboxes[MOD_ALT]->is_pressed());
+ mb->set_shift(mod_checkboxes[MOD_SHIFT]->is_pressed());
+ mb->set_command(mod_checkboxes[MOD_COMMAND]->is_pressed());
+ mb->set_control(mod_checkboxes[MOD_CONTROL]->is_pressed());
+ mb->set_metakey(mod_checkboxes[MOD_META]->is_pressed());
+ mb->set_store_command(store_command_checkbox->is_pressed());
+
+ _set_event(mb);
+ } break;
+ case InputEventConfigurationDialog::INPUT_JOY_BUTTON: {
+ int idx = selected->get_meta("__index");
+ Ref<InputEventJoypadButton> jb = InputEventJoypadButton::create_reference(idx);
+ _set_event(jb);
+ } break;
+ case InputEventConfigurationDialog::INPUT_JOY_MOTION: {
+ int axis = selected->get_meta("__axis");
+ int value = selected->get_meta("__value");
+
+ Ref<InputEventJoypadMotion> jm;
+ jm.instance();
+ jm->set_axis(axis);
+ jm->set_axis_value(value);
+ _set_event(jm);
+ } break;
+ default:
+ break;
+ }
+}
+
+void InputEventConfigurationDialog::_set_current_device(int i_device) {
+ device_id_option->select(i_device + 1);
+}
+
+int InputEventConfigurationDialog::_get_current_device() const {
+ return device_id_option->get_selected() - 1;
+}
+
+String InputEventConfigurationDialog::_get_device_string(int i_device) const {
+ if (i_device == InputMap::ALL_DEVICES) {
+ return TTR("All Devices");
+ }
+ return TTR("Device") + " " + itos(i_device);
+}
+
+void InputEventConfigurationDialog::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ input_list_search->set_right_icon(input_list_search->get_theme_icon("Search", "EditorIcons"));
+
+ physical_key_checkbox->set_icon(get_theme_icon("KeyboardPhysical", "EditorIcons"));
+
+ icon_cache.keyboard = get_theme_icon("Keyboard", "EditorIcons");
+ icon_cache.mouse = get_theme_icon("Mouse", "EditorIcons");
+ icon_cache.joypad_button = get_theme_icon("JoyButton", "EditorIcons");
+ icon_cache.joypad_axis = get_theme_icon("JoyAxis", "EditorIcons");
+
+ _update_input_list();
+ } break;
+ default:
+ break;
+ }
+}
+
+void InputEventConfigurationDialog::popup_and_configure(const Ref<InputEvent> &p_event) {
+ if (p_event.is_valid()) {
+ _set_event(p_event);
+ } else {
+ // Clear Event
+ _set_event(p_event);
+
+ // Clear Checkbox Values
+ for (int i = 0; i < MOD_MAX; i++) {
+ mod_checkboxes[i]->set_pressed(false);
+ }
+ physical_key_checkbox->set_pressed(false);
+ store_command_checkbox->set_pressed(true);
+ _set_current_device(0);
+
+ // Switch to "Listen" tab
+ tab_container->set_current_tab(0);
+ }
+
+ popup_centered();
+}
+
+Ref<InputEvent> InputEventConfigurationDialog::get_event() const {
+ return event;
+}
+
+void InputEventConfigurationDialog::set_allowed_input_types(int p_type_masks) {
+ allowed_input_types = p_type_masks;
+}
+
+InputEventConfigurationDialog::InputEventConfigurationDialog() {
+ allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION;
+
+ set_title("Event Configuration");
+ set_min_size(Size2i(550 * EDSCALE, 0)); // Min width
+
+ VBoxContainer *main_vbox = memnew(VBoxContainer);
+ add_child(main_vbox);
+
+ tab_container = memnew(TabContainer);
+ tab_container->set_tab_align(TabContainer::TabAlign::ALIGN_LEFT);
+ tab_container->set_use_hidden_tabs_for_min_size(true);
+ tab_container->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ tab_container->connect("tab_selected", callable_mp(this, &InputEventConfigurationDialog::_tab_selected));
+ main_vbox->add_child(tab_container);
+
+ CenterContainer *cc = memnew(CenterContainer);
+ cc->set_name("Listen for Input");
+ event_as_text = memnew(Label);
+ event_as_text->set_align(Label::ALIGN_CENTER);
+ cc->add_child(event_as_text);
+ tab_container->add_child(cc);
+
+ // List of all input options to manually select from.
+
+ VBoxContainer *manual_vbox = memnew(VBoxContainer);
+ manual_vbox->set_name("Manual Selection");
+ manual_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ tab_container->add_child(manual_vbox);
+
+ input_list_search = memnew(LineEdit);
+ input_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ input_list_search->set_placeholder(TTR("Filter Inputs"));
+ input_list_search->set_clear_button_enabled(true);
+ input_list_search->connect("text_changed", callable_mp(this, &InputEventConfigurationDialog::_search_term_updated));
+ manual_vbox->add_child(input_list_search);
+
+ input_list_tree = memnew(Tree);
+ input_list_tree->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); // Min height for tree
+ input_list_tree->connect("item_selected", callable_mp(this, &InputEventConfigurationDialog::_input_list_item_selected));
+ input_list_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ manual_vbox->add_child(input_list_tree);
+
+ input_list_tree->set_hide_root(true);
+ input_list_tree->set_columns(1);
+
+ _update_input_list();
+
+ // Additional Options
+ additional_options_container = memnew(VBoxContainer);
+ additional_options_container->hide();
+
+ Label *opts_label = memnew(Label);
+ opts_label->set_text("Additional Options");
+ additional_options_container->add_child(opts_label);
+
+ // Device Selection
+ device_container = memnew(HBoxContainer);
+ device_container->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+
+ Label *device_label = memnew(Label);
+ device_label->set_text("Device:");
+ device_container->add_child(device_label);
+
+ device_id_option = memnew(OptionButton);
+ device_id_option->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ device_container->add_child(device_id_option);
+
+ for (int i = -1; i < 8; i++) {
+ device_id_option->add_item(_get_device_string(i));
+ }
+ _set_current_device(0);
+ device_container->hide();
+ additional_options_container->add_child(device_container);
+
+ // Modifier Selection
+ mod_container = memnew(HBoxContainer);
+ for (int i = 0; i < MOD_MAX; i++) {
+ String name = mods[i];
+ mod_checkboxes[i] = memnew(CheckBox);
+ mod_checkboxes[i]->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_mod_toggled), varray(i));
+ mod_checkboxes[i]->set_text(name);
+ mod_container->add_child(mod_checkboxes[i]);
+ }
+
+ mod_container->add_child(memnew(VSeparator));
+
+ store_command_checkbox = memnew(CheckBox);
+ store_command_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_store_command_toggled));
+ store_command_checkbox->set_pressed(true);
+ store_command_checkbox->set_text(TTR("Store Command"));
+#ifdef APPLE_STYLE_KEYS
+ store_command_checkbox->set_tooltip(TTR("Toggles between serializing 'command' and 'meta'. Used for compatibility with Windows/Linux style keyboard."));
+#else
+ store_command_checkbox->set_tooltip(TTR("Toggles between serializing 'command' and 'control'. Used for compatibility with Apple Style keyboards."));
+#endif
+ mod_container->add_child(store_command_checkbox);
+
+ mod_container->hide();
+ additional_options_container->add_child(mod_container);
+
+ // Physical Key Checkbox
+
+ physical_key_checkbox = memnew(CheckBox);
+ physical_key_checkbox->set_text(TTR("Use Physical Keycode"));
+ physical_key_checkbox->set_tooltip(TTR("Stores the physical position of the key on the keyboard rather than the keys value. Used for compatibility with non-latin layouts."));
+ physical_key_checkbox->connect("toggled", callable_mp(this, &InputEventConfigurationDialog::_physical_keycode_toggled));
+ physical_key_checkbox->hide();
+ additional_options_container->add_child(physical_key_checkbox);
+
+ main_vbox->add_child(additional_options_container);
+
+ // Default to first tab
+ tab_container->set_current_tab(0);
+}
+
+/////////////////////////////////////////
+
+static bool _is_action_name_valid(const String &p_name) {
+ const char32_t *cstr = p_name.get_data();
+ for (int i = 0; cstr[i]; i++) {
+ if (cstr[i] == '/' || cstr[i] == ':' || cstr[i] == '"' ||
+ cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void ActionMapEditor::_event_config_confirmed() {
+ Ref<InputEvent> ev = event_config_dialog->get_event();
+
+ Dictionary new_action = current_action.duplicate();
+ Array events = new_action["events"];
+
+ if (current_action_event_index == -1) {
+ // Add new event
+ events.push_back(ev);
+ } else {
+ // Edit existing event
+ events[current_action_event_index] = ev;
+ }
+
+ new_action["events"] = events;
+ emit_signal("action_edited", current_action_name, new_action);
+}
+
+void ActionMapEditor::_add_action_pressed() {
+ _add_action(add_edit->get_text());
+}
+
+void ActionMapEditor::_add_action(const String &p_name) {
+ if (!allow_editing_actions) {
+ return;
+ }
+
+ if (p_name == "" || !_is_action_name_valid(p_name)) {
+ show_message(TTR("Invalid action name. it cannot be.is_empty()() nor contain '/', ':', '=', '\\' or '\"'"));
+ return;
+ }
+
+ add_edit->clear();
+ emit_signal("action_added", p_name);
+}
+
+void ActionMapEditor::_action_edited() {
+ if (!allow_editing_actions) {
+ return;
+ }
+
+ TreeItem *ti = action_tree->get_edited();
+ if (!ti) {
+ return;
+ }
+
+ if (action_tree->get_selected_column() == 0) {
+ // Name Edited
+ String new_name = ti->get_text(0);
+ String old_name = ti->get_meta("__name");
+
+ if (new_name == old_name) {
+ return;
+ }
+
+ if (new_name == "" || !_is_action_name_valid(new_name)) {
+ ti->set_text(0, old_name);
+ show_message(TTR("Invalid action name. it cannot be.is_empty()() nor contain '/', ':', '=', '\\' or '\"'"));
+ return;
+ }
+
+ emit_signal("action_renamed", old_name, new_name);
+ } else if (action_tree->get_selected_column() == 1) {
+ // Deadzone Edited
+ String name = ti->get_meta("__name");
+ Dictionary old_action = ti->get_meta("__action");
+ Dictionary new_action = old_action.duplicate();
+ new_action["deadzone"] = ti->get_range(1);
+
+ // Call deferred so that input can finish propagating through tree, allowing re-making of tree to occur.
+ call_deferred("emit_signal", "action_edited", name, new_action);
+ }
+}
+
+void ActionMapEditor::_tree_button_pressed(Object *p_item, int p_column, int p_id) {
+ ItemButton option = (ItemButton)p_id;
+
+ TreeItem *item = Object::cast_to<TreeItem>(p_item);
+ if (!item) {
+ return;
+ }
+
+ switch (option) {
+ case ActionMapEditor::BUTTON_ADD_EVENT: {
+ current_action = item->get_meta("__action");
+ current_action_name = item->get_meta("__name");
+ current_action_event_index = -1;
+
+ event_config_dialog->popup_and_configure();
+
+ } break;
+ case ActionMapEditor::BUTTON_EDIT_EVENT: {
+ // Action and Action name is located on the parent of the event.
+ current_action = item->get_parent()->get_meta("__action");
+ current_action_name = item->get_parent()->get_meta("__name");
+
+ current_action_event_index = item->get_meta("__index");
+
+ Ref<InputEvent> ie = item->get_meta("__event");
+ if (ie.is_valid()) {
+ event_config_dialog->popup_and_configure(ie);
+ }
+
+ } break;
+ case ActionMapEditor::BUTTON_REMOVE_ACTION: {
+ if (!allow_editing_actions) {
+ break;
+ }
+
+ // Send removed action name
+ String name = item->get_meta("__name");
+ emit_signal("action_removed", name);
+ } break;
+ case ActionMapEditor::BUTTON_REMOVE_EVENT: {
+ // Remove event and send updated action
+ Dictionary action = item->get_parent()->get_meta("__action");
+ String action_name = item->get_parent()->get_meta("__name");
+
+ int event_index = item->get_meta("__index");
+
+ Array events = action["events"];
+ events.remove(event_index);
+ action["events"] = events;
+
+ emit_signal("action_edited", action_name, action);
+ } break;
+ default:
+ break;
+ }
+}
+
+void ActionMapEditor::_tree_item_activated() {
+ TreeItem *item = action_tree->get_selected();
+
+ if (!item || !item->has_meta("__event")) {
+ return;
+ }
+
+ _tree_button_pressed(item, 2, BUTTON_EDIT_EVENT);
+}
+
+void ActionMapEditor::set_show_uneditable(bool p_show) {
+ show_uneditable = p_show;
+ show_uneditable_actions_checkbox->set_pressed(p_show);
+
+ // Prevent unnecessary updates of action list when cache is.is_empty()().
+ if (!actions_cache.is_empty()) {
+ update_action_list();
+ }
+}
+
+void ActionMapEditor::_search_term_updated(const String &) {
+ update_action_list();
+}
+
+Variant ActionMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
+ TreeItem *selected = action_tree->get_selected();
+ if (!selected) {
+ return Variant();
+ }
+
+ String name = selected->get_text(0);
+ Label *label = memnew(Label(name));
+ label->set_modulate(Color(1, 1, 1, 1.0f));
+ action_tree->set_drag_preview(label);
+
+ Dictionary drag_data;
+
+ if (selected->has_meta("__action")) {
+ drag_data["input_type"] = "action";
+ }
+
+ if (selected->has_meta("__event")) {
+ drag_data["input_type"] = "event";
+ }
+
+ action_tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
+
+ return drag_data;
+}
+
+bool ActionMapEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
+ Dictionary d = p_data;
+ if (!d.has("input_type")) {
+ return false;
+ }
+
+ TreeItem *selected = action_tree->get_selected();
+ TreeItem *item = action_tree->get_item_at_position(p_point);
+ if (!selected || !item || item == selected) {
+ return false;
+ }
+
+ // Don't allow moving an action in-between events.
+ if (d["input_type"] == "action" && item->has_meta("__event")) {
+ return false;
+ }
+
+ // Don't allow moving an event to a different action.
+ if (d["input_type"] == "event" && item->get_parent() != selected->get_parent()) {
+ return false;
+ }
+
+ return true;
+}
+
+void ActionMapEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
+ return;
+ }
+
+ TreeItem *selected = action_tree->get_selected();
+ TreeItem *target = action_tree->get_item_at_position(p_point);
+ bool drop_above = action_tree->get_drop_section_at_position(p_point) == -1;
+
+ if (!target) {
+ return;
+ }
+
+ Dictionary d = p_data;
+ if (d["input_type"] == "action") {
+ // Change action order.
+ String relative_to = target->get_meta("__name");
+ String action_name = selected->get_meta("__name");
+ emit_signal("action_reordered", action_name, relative_to, drop_above);
+
+ } else if (d["input_type"] == "event") {
+ // Change event order
+ int current_index = selected->get_meta("__index");
+ int target_index = target->get_meta("__index");
+
+ // Construct new events array.
+ Dictionary new_action = selected->get_parent()->get_meta("__action");
+
+ Array events = new_action["events"];
+ Array new_events;
+
+ // The following method was used to perform the array changes since `remove` followed by `insert` was not working properly at time of writing.
+ // Loop thought existing events
+ for (int i = 0; i < events.size(); i++) {
+ // If you come across the current index, just skip it, as it has been moved.
+ if (i == current_index) {
+ continue;
+ } else if (i == target_index) {
+ // We are at the target index. If drop above, add selected event there first, then target, so moved event goes on top.
+ if (drop_above) {
+ new_events.push_back(events[current_index]);
+ new_events.push_back(events[target_index]);
+ } else {
+ new_events.push_back(events[target_index]);
+ new_events.push_back(events[current_index]);
+ }
+ } else {
+ new_events.push_back(events[i]);
+ }
+ }
+
+ new_action["events"] = new_events;
+ emit_signal("action_edited", selected->get_parent()->get_meta("__name"), new_action);
+ }
+}
+
+void ActionMapEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ action_list_search->set_right_icon(get_theme_icon("Search", "EditorIcons"));
+ } break;
+ default:
+ break;
+ }
+}
+
+void ActionMapEditor::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &ActionMapEditor::get_drag_data_fw);
+ ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &ActionMapEditor::can_drop_data_fw);
+ ClassDB::bind_method(D_METHOD("drop_data_fw"), &ActionMapEditor::drop_data_fw);
+
+ ADD_SIGNAL(MethodInfo("action_added", PropertyInfo(Variant::STRING, "name")));
+ ADD_SIGNAL(MethodInfo("action_edited", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::DICTIONARY, "new_action")));
+ ADD_SIGNAL(MethodInfo("action_removed", PropertyInfo(Variant::STRING, "name")));
+ ADD_SIGNAL(MethodInfo("action_renamed", PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name")));
+ ADD_SIGNAL(MethodInfo("action_reordered", PropertyInfo(Variant::STRING, "action_name"), PropertyInfo(Variant::STRING, "relative_to"), PropertyInfo(Variant::BOOL, "before")));
+}
+
+LineEdit *ActionMapEditor::get_search_box() const {
+ return action_list_search;
+}
+
+InputEventConfigurationDialog *ActionMapEditor::get_configuration_dialog() {
+ return event_config_dialog;
+}
+
+void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_infos) {
+ if (!p_action_infos.is_empty()) {
+ actions_cache = p_action_infos;
+ }
+
+ action_tree->clear();
+ TreeItem *root = action_tree->create_item();
+
+ int uneditable_count = 0;
+
+ for (int i = 0; i < actions_cache.size(); i++) {
+ ActionInfo action_info = actions_cache[i];
+
+ if (!action_info.editable) {
+ uneditable_count++;
+ }
+
+ String search_term = action_list_search->get_text();
+ if (!search_term.is_empty() && action_info.name.findn(search_term) == -1) {
+ continue;
+ }
+
+ if (!action_info.editable && !show_uneditable) {
+ continue;
+ }
+
+ const Array events = action_info.action["events"];
+ const Variant deadzone = action_info.action["deadzone"];
+
+ // Update Tree...
+
+ TreeItem *action_item = action_tree->create_item(root);
+ action_item->set_meta("__action", action_info.action);
+ action_item->set_meta("__name", action_info.name);
+
+ // First Column - Action Name
+ action_item->set_text(0, action_info.name);
+ action_item->set_editable(0, action_info.editable);
+ action_item->set_icon(0, action_info.icon);
+
+ // Second Column - Deadzone
+ action_item->set_editable(1, true);
+ action_item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
+ action_item->set_range_config(1, 0.0, 1.0, 0.01);
+ action_item->set_range(1, deadzone);
+
+ // Third column - buttons
+ action_item->add_button(2, action_tree->get_theme_icon("Add", "EditorIcons"), BUTTON_ADD_EVENT, false, TTR("Add Event"));
+ action_item->add_button(2, action_tree->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_ACTION, !action_info.editable, action_info.editable ? "Remove Action" : "Cannot Remove Action");
+
+ action_item->set_custom_bg_color(0, action_tree->get_theme_color("prop_subsection", "Editor"));
+ action_item->set_custom_bg_color(1, action_tree->get_theme_color("prop_subsection", "Editor"));
+
+ for (int evnt_idx = 0; evnt_idx < events.size(); evnt_idx++) {
+ Ref<InputEvent> event = events[evnt_idx];
+ if (event.is_null()) {
+ continue;
+ }
+
+ TreeItem *event_item = action_tree->create_item(action_item);
+
+ // First Column - Text
+ event_item->set_text(0, event_config_dialog->get_event_text(event)); // Need to us the special description for JoypadMotion here, so don't use as_text() directly.
+ event_item->set_meta("__event", event);
+ event_item->set_meta("__index", evnt_idx);
+
+ // Third Column - Buttons
+ event_item->add_button(2, action_tree->get_theme_icon("Edit", "EditorIcons"), BUTTON_EDIT_EVENT, false, TTR("Edit Event"));
+ event_item->add_button(2, action_tree->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_EVENT, false, TTR("Remove Event"));
+ event_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
+ event_item->set_button_color(2, 1, Color(1, 1, 1, 0.75));
+ }
+ }
+}
+
+void ActionMapEditor::show_message(const String &p_message) {
+ message->set_text(p_message);
+ message->popup_centered(Size2(300, 100) * EDSCALE);
+}
+
+void ActionMapEditor::set_allow_editing_actions(bool p_allow) {
+ allow_editing_actions = p_allow;
+ add_hbox->set_visible(p_allow);
+}
+
+void ActionMapEditor::set_toggle_editable_label(const String &p_label) {
+ show_uneditable_actions_checkbox->set_text(p_label);
+}
+
+void ActionMapEditor::use_external_search_box(LineEdit *p_searchbox) {
+ memdelete(action_list_search);
+ action_list_search = p_searchbox;
+ action_list_search->connect("text_changed", callable_mp(this, &ActionMapEditor::_search_term_updated));
+}
+
+ActionMapEditor::ActionMapEditor() {
+ allow_editing_actions = true;
+ show_uneditable = true;
+
+ // Main Vbox Container
+ VBoxContainer *main_vbox = memnew(VBoxContainer);
+ main_vbox->set_anchors_and_offsets_preset(PRESET_WIDE);
+ add_child(main_vbox);
+
+ HBoxContainer *top_hbox = memnew(HBoxContainer);
+ main_vbox->add_child(top_hbox);
+
+ action_list_search = memnew(LineEdit);
+ action_list_search->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ action_list_search->set_placeholder(TTR("Filter Actions"));
+ action_list_search->set_clear_button_enabled(true);
+ action_list_search->connect("text_changed", callable_mp(this, &ActionMapEditor::_search_term_updated));
+ top_hbox->add_child(action_list_search);
+
+ show_uneditable_actions_checkbox = memnew(CheckBox);
+ show_uneditable_actions_checkbox->set_pressed(false);
+ show_uneditable_actions_checkbox->set_text(TTR("Show Uneditable Actions"));
+ show_uneditable_actions_checkbox->connect("toggled", callable_mp(this, &ActionMapEditor::set_show_uneditable));
+ top_hbox->add_child(show_uneditable_actions_checkbox);
+
+ // Adding Action line edit + button
+ add_hbox = memnew(HBoxContainer);
+ add_hbox->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+
+ add_edit = memnew(LineEdit);
+ add_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ add_edit->set_placeholder(TTR("Add New Action"));
+ add_edit->set_clear_button_enabled(true);
+ add_edit->connect("text_entered", callable_mp(this, &ActionMapEditor::_add_action));
+ add_hbox->add_child(add_edit);
+
+ Button *add_button = memnew(Button);
+ add_button->set_text("Add");
+ add_button->connect("pressed", callable_mp(this, &ActionMapEditor::_add_action_pressed));
+ add_hbox->add_child(add_button);
+
+ main_vbox->add_child(add_hbox);
+
+ // Action Editor Tree
+ action_tree = memnew(Tree);
+ action_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ action_tree->set_columns(3);
+ action_tree->set_hide_root(true);
+ action_tree->set_column_titles_visible(true);
+ action_tree->set_column_title(0, TTR("Action"));
+ action_tree->set_column_title(1, TTR("Deadzone"));
+ action_tree->set_column_expand(1, false);
+ action_tree->set_column_min_width(1, 80 * EDSCALE);
+ action_tree->set_column_expand(2, false);
+ action_tree->set_column_min_width(2, 50 * EDSCALE);
+ action_tree->connect("item_edited", callable_mp(this, &ActionMapEditor::_action_edited));
+ action_tree->connect("item_activated", callable_mp(this, &ActionMapEditor::_tree_item_activated));
+ action_tree->connect("button_pressed", callable_mp(this, &ActionMapEditor::_tree_button_pressed));
+ main_vbox->add_child(action_tree);
+
+ action_tree->set_drag_forwarding(this);
+
+ // Adding event dialog
+ event_config_dialog = memnew(InputEventConfigurationDialog);
+ event_config_dialog->connect("confirmed", callable_mp(this, &ActionMapEditor::_event_config_confirmed));
+ add_child(event_config_dialog);
+
+ message = memnew(AcceptDialog);
+ add_child(message);
+}
diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h
new file mode 100644
index 0000000000..f1f7bffef4
--- /dev/null
+++ b/editor/action_map_editor.h
@@ -0,0 +1,203 @@
+/*************************************************************************/
+/* action_map_editor.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef ACTION_MAP_EDITOR_H
+#define ACTION_MAP_EDITOR_H
+
+#include "editor/editor_data.h"
+
+// Confirmation Dialog used when configuring an input event.
+// Separate from ActionMapEditor for code cleanliness and separation of responsibilities.
+class InputEventConfigurationDialog : public ConfirmationDialog {
+ GDCLASS(InputEventConfigurationDialog, ConfirmationDialog);
+
+public:
+ enum InputType {
+ INPUT_KEY = 1,
+ INPUT_MOUSE_BUTTON = 2,
+ INPUT_JOY_BUTTON = 4,
+ INPUT_JOY_MOTION = 8
+ };
+
+private:
+ struct IconCache {
+ Ref<Texture2D> keyboard;
+ Ref<Texture2D> mouse;
+ Ref<Texture2D> joypad_button;
+ Ref<Texture2D> joypad_axis;
+ } icon_cache;
+
+ Ref<InputEvent> event = Ref<InputEvent>();
+
+ TabContainer *tab_container;
+
+ // Listening for input
+ Label *event_as_text;
+
+ // List of All Key/Mouse/Joypad input options.
+ int allowed_input_types;
+ Tree *input_list_tree;
+ LineEdit *input_list_search;
+
+ // Additional Options, shown depending on event selected
+ VBoxContainer *additional_options_container;
+
+ HBoxContainer *device_container;
+ OptionButton *device_id_option;
+
+ HBoxContainer *mod_container; // Contains the subcontainer and the store command checkbox.
+
+ enum ModCheckbox {
+ MOD_ALT,
+ MOD_SHIFT,
+ MOD_COMMAND,
+ MOD_CONTROL,
+ MOD_META,
+ MOD_MAX
+ };
+ String mods[MOD_MAX] = { "Alt", "Shift", "Command", "Control", "Meta" };
+
+ CheckBox *mod_checkboxes[MOD_MAX];
+ CheckBox *store_command_checkbox;
+
+ CheckBox *physical_key_checkbox;
+
+ void _set_event(const Ref<InputEvent> &p_event);
+
+ void _tab_selected(int p_tab);
+ void _listen_window_input(const Ref<InputEvent> &p_event);
+
+ void _search_term_updated(const String &p_term);
+ void _update_input_list();
+ void _input_list_item_selected();
+
+ void _mod_toggled(bool p_checked, int p_index);
+ void _store_command_toggled(bool p_checked);
+ void _physical_keycode_toggled(bool p_checked);
+
+ void _set_current_device(int i_device);
+ int _get_current_device() const;
+ String _get_device_string(int i_device) const;
+
+protected:
+ void _notification(int p_what);
+
+public:
+ // Pass an existing event to configure it. Alternatively, pass no event to start with a blank configuration.
+ void popup_and_configure(const Ref<InputEvent> &p_event = Ref<InputEvent>());
+ Ref<InputEvent> get_event() const;
+ String get_event_text(const Ref<InputEvent> &p_event);
+
+ void set_allowed_input_types(int p_type_masks);
+
+ InputEventConfigurationDialog();
+};
+
+class ActionMapEditor : public Control {
+ GDCLASS(ActionMapEditor, Control);
+
+public:
+ struct ActionInfo {
+ String name = String();
+ Dictionary action = Dictionary();
+
+ Ref<Texture2D> icon = Ref<Texture2D>();
+ bool editable = true;
+ };
+
+private:
+ enum ItemButton {
+ BUTTON_ADD_EVENT,
+ BUTTON_EDIT_EVENT,
+ BUTTON_REMOVE_ACTION,
+ BUTTON_REMOVE_EVENT,
+ };
+
+ Vector<ActionInfo> actions_cache;
+ Tree *action_tree;
+
+ // Storing which action/event is currently being edited in the InputEventConfigurationDialog.
+
+ Dictionary current_action = Dictionary();
+ String current_action_name = String();
+ int current_action_event_index = -1;
+
+ // Popups
+
+ InputEventConfigurationDialog *event_config_dialog;
+ AcceptDialog *message;
+
+ // Filtering and Adding actions
+
+ bool show_uneditable;
+ CheckBox *show_uneditable_actions_checkbox;
+ LineEdit *action_list_search;
+
+ bool allow_editing_actions;
+ HBoxContainer *add_hbox;
+ LineEdit *add_edit;
+
+ void _event_config_confirmed();
+
+ void _add_action_pressed();
+ void _add_action(const String &p_name);
+ void _action_edited();
+
+ void _tree_button_pressed(Object *p_item, int p_column, int p_id);
+ void _tree_item_activated();
+ void _search_term_updated(const String &p_search_term);
+
+ Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
+ bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
+ void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ LineEdit *get_search_box() const;
+ InputEventConfigurationDialog *get_configuration_dialog();
+
+ // Dictionary represents an Action with "events" (Array) and "deadzone" (float) items. Pass with no param to update list from cached action map.
+ void update_action_list(const Vector<ActionInfo> &p_action_infos = Vector<ActionInfo>());
+ void show_message(const String &p_message);
+
+ void set_show_uneditable(bool p_show);
+ void set_allow_editing_actions(bool p_allow);
+
+ void set_toggle_editable_label(const String &p_label);
+
+ void use_external_search_box(LineEdit *p_searchbox);
+
+ ActionMapEditor();
+};
+
+#endif
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index 6530e27dcd..5d2b825c4f 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -367,7 +367,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
float scale = (min_left_scale * 2) * v_zoom;
float step = Math::pow(10.0, Math::round(Math::log(scale / 5.0) / Math::log(10.0))) * 5.0;
- scale = Math::stepify(scale, step);
+ scale = Math::snapped(scale, step);
while (scale / v_zoom < min_left_scale * 2) {
scale += step;
@@ -390,7 +390,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
draw_line(Point2(limit, i), Point2(right_limit, i), lc);
Color c = color;
c.a *= 0.5;
- draw_string(font, Point2(limit + 8, i - 2), TS->format_number(rtos(Math::stepify((iv + 1) * scale, step))), HALIGN_LEFT, -1, font_size, c);
+ draw_string(font, Point2(limit + 8, i - 2), TS->format_number(rtos(Math::snapped((iv + 1) * scale, step))), HALIGN_LEFT, -1, font_size, c);
}
first = false;
@@ -461,8 +461,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
ep.point_rect.size = bezier_icon->get_size();
if (selection.has(i)) {
draw_texture(selected_icon, ep.point_rect.position);
- draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 4), TTR("Time:") + " " + TS->format_number(rtos(Math::stepify(offset, 0.001))), HALIGN_LEFT, -1, font_size, accent);
- draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + TS->format_number(rtos(Math::stepify(value, 0.001))), HALIGN_LEFT, -1, font_size, accent);
+ draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 4), TTR("Time:") + " " + TS->format_number(rtos(Math::snapped(offset, 0.001))), HALIGN_LEFT, -1, font_size, accent);
+ draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + TS->format_number(rtos(Math::snapped(value, 0.001))), HALIGN_LEFT, -1, font_size, accent);
} else {
draw_texture(bezier_icon, ep.point_rect.position);
}
diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h
index 1b7ed8f06c..b082cae3ea 100644
--- a/editor/animation_bezier_editor.h
+++ b/editor/animation_bezier_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 9b2cc686e3..804f02765c 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -634,7 +634,7 @@ public:
bool use_fps = false;
void notify_change() {
- _change_notify();
+ notify_property_list_changed();
}
Node *get_root_path() {
@@ -643,7 +643,7 @@ public:
void set_use_fps(bool p_enable) {
use_fps = p_enable;
- _change_notify();
+ notify_property_list_changed();
}
};
@@ -1276,7 +1276,7 @@ public:
UndoRedo *undo_redo = nullptr;
void notify_change() {
- _change_notify();
+ notify_property_list_changed();
}
Node *get_root_path() {
@@ -1285,7 +1285,7 @@ public:
void set_use_fps(bool p_enable) {
use_fps = p_enable;
- _change_notify();
+ notify_property_list_changed();
}
};
@@ -3431,7 +3431,7 @@ void AnimationTrackEditor::_insert_delay(bool p_create_reset, bool p_create_bezi
if (insert_data.front()->get().advance) {
advance = true;
}
- next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_create_reset, p_create_beziers);
+ next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_create_reset, reset_anim, p_create_beziers);
insert_data.pop_front();
}
@@ -3445,7 +3445,7 @@ void AnimationTrackEditor::_insert_delay(bool p_create_reset, bool p_create_bezi
float pos = timeline->get_play_position();
- pos = Math::stepify(pos + step, step);
+ pos = Math::snapped(pos + step, step);
if (pos > animation->get_length()) {
pos = animation->get_length();
}
@@ -3749,7 +3749,7 @@ void AnimationTrackEditor::_confirm_insert_list() {
TrackIndices next_tracks(animation.ptr(), reset_anim.ptr());
while (insert_data.size()) {
- next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, create_reset, insert_confirm_bezier->is_pressed());
+ next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, create_reset, reset_anim, insert_confirm_bezier->is_pressed());
insert_data.pop_front();
}
@@ -3779,7 +3779,7 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b
r_base_path = node->get_path();
}
- if (leftover_path.empty()) {
+ if (leftover_path.is_empty()) {
if (r_current_val) {
if (res.is_valid()) {
*r_current_val = res;
@@ -3869,7 +3869,7 @@ static Vector<String> _get_bezier_subindices_for_type(Variant::Type p_type, bool
return subindices;
}
-AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, bool p_create_beziers) {
+AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, Ref<Animation> p_reset_anim, bool p_create_beziers) {
bool created = false;
if (p_id.track_idx < 0) {
if (p_create_beziers) {
@@ -3881,7 +3881,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
id.type = Animation::TYPE_BEZIER;
id.value = p_id.value.get(subindices[i].substr(1, subindices[i].length()));
id.path = String(p_id.path) + subindices[i];
- p_next_tracks = _confirm_insert(id, p_next_tracks, p_create_reset, false);
+ p_next_tracks = _confirm_insert(id, p_next_tracks, p_create_reset, p_reset_anim, false);
}
return p_next_tracks;
@@ -3986,7 +3986,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
if (p_create_reset && track_type_is_resettable(p_id.type)) {
bool create_reset_track = true;
- Animation *reset_anim = AnimationPlayerEditor::singleton->get_player()->get_animation("RESET").ptr();
+ Animation *reset_anim = p_reset_anim.ptr();
for (int i = 0; i < reset_anim->get_track_count(); i++) {
if (reset_anim->track_get_path(i) == p_id.path) {
create_reset_track = false;
@@ -4080,8 +4080,8 @@ void AnimationTrackEditor::_update_tracks() {
object = res.ptr();
}
- if (object && !leftover_path.empty()) {
- if (pinfo.name.empty()) {
+ if (object && !leftover_path.is_empty()) {
+ if (pinfo.name.is_empty()) {
pinfo.name = leftover_path[leftover_path.size() - 1];
}
@@ -4283,7 +4283,6 @@ void AnimationTrackEditor::_animation_update() {
_update_step_spinbox();
emit_signal("animation_step_changed", animation->get_step());
emit_signal("animation_len_changed", animation->get_length());
- EditorNode::get_singleton()->get_inspector()->refresh();
animation_changing_awaiting_update = false;
}
@@ -5285,7 +5284,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
scale_dialog->popup_centered(Size2(200, 100) * EDSCALE);
} break;
case EDIT_SCALE_CONFIRM: {
- if (selection.empty()) {
+ if (selection.is_empty()) {
return;
}
@@ -5433,7 +5432,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
float pos = timeline->get_play_position();
- pos = Math::stepify(pos + step, step);
+ pos = Math::snapped(pos + step, step);
if (pos > animation->get_length()) {
pos = animation->get_length();
}
@@ -5452,7 +5451,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
float pos = timeline->get_play_position();
- pos = Math::stepify(pos - step, step);
+ pos = Math::snapped(pos - step, step);
if (pos < 0) {
pos = 0;
}
@@ -5581,9 +5580,9 @@ float AnimationTrackEditor::snap_time(float p_value, bool p_relative) {
if (p_relative) {
double rel = Math::fmod(timeline->get_value(), snap_increment);
- p_value = Math::stepify(p_value + rel, snap_increment) - rel;
+ p_value = Math::snapped(p_value + rel, snap_increment) - rel;
} else {
- p_value = Math::stepify(p_value, snap_increment);
+ p_value = Math::snapped(p_value, snap_increment);
}
}
@@ -5886,7 +5885,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
optimize_max_angle->set_value(22);
optimize_dialog->get_ok_button()->set_text(TTR("Optimize"));
- optimize_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_CLEAN_UP_ANIMATION_CONFIRM));
+ optimize_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed), varray(EDIT_OPTIMIZE_ANIMATION_CONFIRM));
//
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 7006959187..e8e4f915fa 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -384,7 +384,7 @@ class AnimationTrackEditor : public VBoxContainer {
reset = p_reset_anim ? p_reset_anim->get_track_count() : 0;
}
};
- TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, bool p_create_beziers);
+ TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, Ref<Animation> p_reset_anim, bool p_create_beziers);
void _insert_delay(bool p_create_reset, bool p_create_beziers);
void _root_removed(Node *p_root);
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index 4d96289343..0c0ee2856e 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/animation_track_editor_plugins.h b/editor/animation_track_editor_plugins.h
index 7c5d7ae04f..66229c3012 100644
--- a/editor/animation_track_editor_plugins.h
+++ b/editor/animation_track_editor_plugins.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/array_property_edit.cpp b/editor/array_property_edit.cpp
index 0b6b1ef6a7..09defac354 100644
--- a/editor/array_property_edit.cpp
+++ b/editor/array_property_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,11 +49,7 @@ Variant ArrayPropertyEdit::get_array() const {
}
void ArrayPropertyEdit::_notif_change() {
- _change_notify();
-}
-
-void ArrayPropertyEdit::_notif_changev(const String &p_v) {
- _change_notify(p_v.utf8().get_data());
+ notify_property_list_changed();
}
void ArrayPropertyEdit::_set_size(int p_size) {
@@ -120,7 +116,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
}
if (pn == "array/page") {
page = p_value;
- _change_notify();
+ notify_property_list_changed();
return true;
}
@@ -159,8 +155,6 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
ur->create_action(TTR("Change Array Value"));
ur->add_do_method(this, "_set_value", idx, p_value);
ur->add_undo_method(this, "_set_value", idx, value);
- ur->add_do_method(this, "_notif_changev", p_name);
- ur->add_undo_method(this, "_notif_changev", p_name);
ur->commit_action();
return true;
}
@@ -259,7 +253,7 @@ void ArrayPropertyEdit::edit(Object *p_obj, const StringName &p_prop, const Stri
obj = p_obj->get_instance_id();
default_type = p_deftype;
- if (!p_hint_string.empty()) {
+ if (!p_hint_string.is_empty()) {
int hint_subtype_separator = p_hint_string.find(":");
if (hint_subtype_separator >= 0) {
String subtype_string = p_hint_string.substr(0, hint_subtype_separator);
@@ -288,7 +282,6 @@ void ArrayPropertyEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_size"), &ArrayPropertyEdit::_set_size);
ClassDB::bind_method(D_METHOD("_set_value"), &ArrayPropertyEdit::_set_value);
ClassDB::bind_method(D_METHOD("_notif_change"), &ArrayPropertyEdit::_notif_change);
- ClassDB::bind_method(D_METHOD("_notif_changev"), &ArrayPropertyEdit::_notif_changev);
ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &ArrayPropertyEdit::_dont_undo_redo);
}
diff --git a/editor/array_property_edit.h b/editor/array_property_edit.h
index d91701ccaf..fa3dcbe038 100644
--- a/editor/array_property_edit.h
+++ b/editor/array_property_edit.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,6 @@ class ArrayPropertyEdit : public Reference {
Variant::Type default_type;
void _notif_change();
- void _notif_changev(const String &p_v);
void _set_size(int p_size);
void _set_value(int p_idx, const Variant &p_value);
diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp
index 9e4e157c96..539657afd7 100644
--- a/editor/audio_stream_preview.cpp
+++ b/editor/audio_stream_preview.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -155,7 +155,7 @@ void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) {
preview->playback->stop();
- preview->generating = false;
+ preview->generating.clear();
}
Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref<AudioStream> &p_stream) {
@@ -172,7 +172,7 @@ Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref<
Preview *preview = &previews[p_stream->get_instance_id()];
preview->base_stream = p_stream;
preview->playback = preview->base_stream->instance_playback();
- preview->generating = true;
+ preview->generating.set();
preview->id = p_stream->get_instance_id();
float len_s = preview->base_stream->get_length();
@@ -197,7 +197,8 @@ Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref<
preview->preview->length = len_s;
if (preview->playback.is_valid()) {
- preview->thread = Thread::create(_preview_thread, preview);
+ preview->thread = memnew(Thread);
+ preview->thread->start(_preview_thread, preview);
}
return preview->preview;
@@ -216,9 +217,10 @@ void AudioStreamPreviewGenerator::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
List<ObjectID> to_erase;
for (Map<ObjectID, Preview>::Element *E = previews.front(); E; E = E->next()) {
- if (!E->get().generating) {
+ if (!E->get().generating.is_set()) {
if (E->get().thread) {
- Thread::wait_to_finish(E->get().thread);
+ E->get().thread->wait_to_finish();
+ memdelete(E->get().thread);
E->get().thread = nullptr;
}
if (!ObjectDB::get_instance(E->key())) { //no longer in use, get rid of preview
diff --git a/editor/audio_stream_preview.h b/editor/audio_stream_preview.h
index 300f1dc5ca..accc7275c0 100644
--- a/editor/audio_stream_preview.h
+++ b/editor/audio_stream_preview.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#define AUDIO_STREAM_PREVIEW_H
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
#include "scene/main/node.h"
#include "servers/audio/audio_stream.h"
@@ -60,9 +61,20 @@ class AudioStreamPreviewGenerator : public Node {
Ref<AudioStreamPreview> preview;
Ref<AudioStream> base_stream;
Ref<AudioStreamPlayback> playback;
- volatile bool generating = false;
+ SafeFlag generating;
ObjectID id;
Thread *thread = nullptr;
+
+ // Needed for the bookkeeping of the Map
+ Preview &operator=(const Preview &p_rhs) {
+ preview = p_rhs.preview;
+ base_stream = p_rhs.base_stream;
+ playback = p_rhs.playback;
+ generating.set_to(generating.is_set());
+ id = p_rhs.id;
+ thread = p_rhs.thread;
+ return *this;
+ }
};
Map<ObjectID, Preview> previews;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index bca2979e72..f4717830bc 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -325,7 +325,7 @@ void FindReplaceBar::_update_results_count() {
results_count = 0;
String searched = get_search_text();
- if (searched.empty()) {
+ if (searched.is_empty()) {
return;
}
@@ -356,7 +356,7 @@ void FindReplaceBar::_update_results_count() {
}
void FindReplaceBar::_update_matches_label() {
- if (search_text->get_text().empty() || results_count == -1) {
+ if (search_text->get_text().is_empty() || results_count == -1) {
matches_label->hide();
} else {
matches_label->show();
@@ -483,7 +483,7 @@ void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) {
search_text->set_text(text_editor->get_selection_text());
}
- if (!get_search_text().empty()) {
+ if (!get_search_text().is_empty()) {
if (p_focus_replace) {
replace_text->select_all();
replace_text->set_cursor_position(replace_text->get_text().length());
@@ -1309,7 +1309,7 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
for (int i = begin; i <= end; i++) {
String line_text = text_editor->get_line(i);
- if (line_text.strip_edges().empty()) {
+ if (line_text.strip_edges().is_empty()) {
line_text = delimiter;
} else {
if (is_commented) {
diff --git a/editor/code_editor.h b/editor/code_editor.h
index b38170cbf5..e201da446e 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 473597b9b3..0c1fb6fe4d 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -98,7 +98,7 @@ public:
}
void notify_changed() {
- _change_notify();
+ notify_property_list_changed();
}
ConnectDialogBinds() {
@@ -1008,7 +1008,7 @@ void ConnectionsDock::update_tree() {
break;
}
}
- if (!F->get().inherits.empty()) {
+ if (!F->get().inherits.is_empty()) {
F = dd->class_list.find(F->get().inherits);
} else {
break;
diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h
index 826c25895c..18feba0a61 100644
--- a/editor/connections_dialog.h
+++ b/editor/connections_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 75d57b040f..711072f4b2 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -170,6 +170,7 @@ void CreateDialog::_update_search() {
root->set_text(0, base_type);
root->set_icon(0, search_options->get_theme_icon(icon_fallback, "EditorIcons"));
search_options_types[base_type] = root;
+ _configure_search_option_item(root, base_type, ClassDB::class_exists(base_type));
const String search_text = search_box->get_text();
bool empty_search = search_text == "";
@@ -236,7 +237,10 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String
bool can_instance = (p_cpp_type && ClassDB::can_instance(p_type)) || !p_cpp_type;
if (!can_instance) {
r_item->set_custom_color(0, search_options->get_theme_color("disabled_font_color", "Editor"));
+ r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, "NodeDisabled"));
r_item->set_selectable(0, false);
+ } else {
+ r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback));
}
if (search_box->get_text() != "") {
@@ -253,7 +257,6 @@ void CreateDialog::_configure_search_option_item(TreeItem *r_item, const String
const String &description = DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description);
r_item->set_tooltip(0, description);
- r_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_type, icon_fallback));
if (!p_cpp_type && !script_type) {
Ref<Texture2D> icon = EditorNode::get_editor_data().get_custom_types()[custom_type_parents[p_type]][custom_type_indices[p_type]].icon;
@@ -408,15 +411,15 @@ String CreateDialog::get_selected_type() {
return selected->get_text(0);
}
-Object *CreateDialog::instance_selected() {
+Variant CreateDialog::instance_selected() {
TreeItem *selected = search_options->get_selected();
if (!selected) {
- return nullptr;
+ return Variant();
}
Variant md = selected->get_metadata(0);
- Object *obj = nullptr;
+ Variant obj;
if (md.get_type() != Variant::NIL) {
String custom = md;
if (ScriptServer::is_global_class(custom)) {
@@ -434,13 +437,13 @@ Object *CreateDialog::instance_selected() {
// Check if any Object-type property should be instantiated.
List<PropertyInfo> pinfo;
- obj->get_property_list(&pinfo);
+ ((Object *)obj)->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
PropertyInfo pi = E->get();
if (pi.type == Variant::OBJECT && pi.usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) {
Object *prop = ClassDB::instance(pi.class_name);
- obj->set(pi.name, prop);
+ ((Object *)obj)->set(pi.name, prop);
}
}
@@ -492,7 +495,7 @@ void CreateDialog::_favorite_selected() {
}
search_box->set_text(item->get_text(0).get_slicec(' ', 0));
- recent->unselect_all();
+ recent->deselect_all();
_update_search();
}
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index 75a317275a..b08cb72f14 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -102,7 +102,7 @@ protected:
void _save_and_update_favorite_list();
public:
- Object *instance_selected();
+ Variant instance_selected();
String get_selected_type();
void set_base_type(const String &p_base) { base_type = p_base; }
diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp
index dcd7220ed0..6035cc072e 100644
--- a/editor/debugger/editor_debugger_inspector.cpp
+++ b/editor/debugger/editor_debugger_inspector.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/debugger/editor_debugger_inspector.h b/editor/debugger/editor_debugger_inspector.h
index 7d13a4c362..6648c99c03 100644
--- a/editor/debugger/editor_debugger_inspector.h
+++ b/editor/debugger/editor_debugger_inspector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,7 +58,7 @@ public:
prop_values.clear();
}
- void update() { _change_notify(); }
+ void update() { notify_property_list_changed(); }
EditorDebuggerRemoteObject() {}
};
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index 118b8f9f2e..3ef9548727 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -115,7 +115,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() {
tabs->add_theme_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox("DebuggerPanel", "EditorStyles"));
}
- if (!debugger_plugins.empty()) {
+ if (!debugger_plugins.is_empty()) {
for (Set<Ref<Script>>::Element *i = debugger_plugins.front(); i; i = i->next()) {
node->add_debugger_plugin(i->get());
}
@@ -140,7 +140,7 @@ void EditorDebuggerNode::_error_selected(const String &p_file, int p_line, int p
void EditorDebuggerNode::_text_editor_stack_goto(const ScriptEditorDebugger *p_debugger) {
const String file = p_debugger->get_stack_script_file();
- if (file.empty()) {
+ if (file.is_empty()) {
return;
}
stack_script = ResourceLoader::load(file);
diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h
index 0f3be4d2dd..3510ac0726 100644
--- a/editor/debugger/editor_debugger_node.h
+++ b/editor/debugger/editor_debugger_node.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/debugger/editor_debugger_server.cpp b/editor/debugger/editor_debugger_server.cpp
index 0b655044a8..4add891bcb 100644
--- a/editor/debugger/editor_debugger_server.cpp
+++ b/editor/debugger/editor_debugger_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/debugger/editor_debugger_server.h b/editor/debugger/editor_debugger_server.h
index 3ad9d3a9a9..6458421e7a 100644
--- a/editor/debugger/editor_debugger_server.h
+++ b/editor/debugger/editor_debugger_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp
index ebac9b3482..ec92edc795 100644
--- a/editor/debugger/editor_debugger_tree.cpp
+++ b/editor/debugger/editor_debugger_tree.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -129,6 +129,8 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
updating_scene_tree = true;
const String last_path = get_selected_path();
const String filter = EditorNode::get_singleton()->get_scene_tree_dock()->get_filter();
+ bool filter_changed = filter != last_filter;
+ TreeItem *scroll_item = nullptr;
// Nodes are in a flatten list, depth first. Use a stack of parents, avoid recursion.
List<Pair<TreeItem *, int>> parents;
@@ -162,11 +164,17 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
if (debugger_id == p_debugger) { // Can use remote id.
if (node.id == inspected_object_id) {
item->select(0);
+ if (filter_changed) {
+ scroll_item = item;
+ }
}
} else { // Must use path
if (last_path == _get_path(item)) {
updating_scene_tree = false; // Force emission of new selection
item->select(0);
+ if (filter_changed) {
+ scroll_item = item;
+ }
updating_scene_tree = true;
}
}
@@ -183,6 +191,9 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
}
parent->remove_child(item);
memdelete(item);
+ if (scroll_item == item) {
+ scroll_item = nullptr;
+ }
if (had_siblings) {
break; // Parent must survive.
}
@@ -199,6 +210,10 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
}
}
debugger_id = p_debugger; // Needed by hook, could be avoided if every debugger had its own tree
+ if (scroll_item) {
+ call_deferred("scroll_to_item", scroll_item);
+ }
+ last_filter = filter;
updating_scene_tree = false;
}
@@ -242,7 +257,7 @@ void EditorDebuggerTree::_item_menu_id_pressed(int p_option) {
} break;
case ITEM_MENU_COPY_NODE_PATH: {
String text = get_selected_path();
- if (text.empty()) {
+ if (text.is_empty()) {
return;
} else if (text == "/root") {
text = ".";
diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h
index 5ec1423c07..13193344f1 100644
--- a/editor/debugger/editor_debugger_tree.h
+++ b/editor/debugger/editor_debugger_tree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,6 +51,7 @@ private:
Set<ObjectID> unfold_cache;
PopupMenu *item_menu = nullptr;
EditorFileDialog *file_dialog = nullptr;
+ String last_filter;
String _get_path(TreeItem *p_item);
void _scene_tree_folded(Object *p_obj);
diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp
index baa88bcdbc..2d57dff69d 100644
--- a/editor/debugger/editor_network_profiler.cpp
+++ b/editor/debugger/editor_network_profiler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,8 +46,8 @@ void EditorNetworkProfiler::_notification(int p_what) {
outgoing_bandwidth_text->set_right_icon(get_theme_icon("ArrowUp", "EditorIcons"));
// This needs to be done here to set the faded color when the profiler is first opened
- incoming_bandwidth_text->add_theme_color_override("font_color_uneditable", get_theme_color("font_color", "Editor") * Color(1, 1, 1, 0.5));
- outgoing_bandwidth_text->add_theme_color_override("font_color_uneditable", get_theme_color("font_color", "Editor") * Color(1, 1, 1, 0.5));
+ incoming_bandwidth_text->add_theme_color_override("font_uneditable_color", get_theme_color("font_color", "Editor") * Color(1, 1, 1, 0.5));
+ outgoing_bandwidth_text->add_theme_color_override("font_uneditable_color", get_theme_color("font_color", "Editor") * Color(1, 1, 1, 0.5));
}
}
@@ -113,10 +113,10 @@ void EditorNetworkProfiler::set_bandwidth(int p_incoming, int p_outgoing) {
// Make labels more prominent when the bandwidth is greater than 0 to attract user attention
incoming_bandwidth_text->add_theme_color_override(
- "font_color_uneditable",
+ "font_uneditable_color",
get_theme_color("font_color", "Editor") * Color(1, 1, 1, p_incoming > 0 ? 1 : 0.5));
outgoing_bandwidth_text->add_theme_color_override(
- "font_color_uneditable",
+ "font_uneditable_color",
get_theme_color("font_color", "Editor") * Color(1, 1, 1, p_outgoing > 0 ? 1 : 0.5));
}
diff --git a/editor/debugger/editor_network_profiler.h b/editor/debugger/editor_network_profiler.h
index cf65fb5316..8c1da1cb2d 100644
--- a/editor/debugger/editor_network_profiler.h
+++ b/editor/debugger/editor_network_profiler.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp
index 2068d42eb7..33d08a2f6b 100644
--- a/editor/debugger/editor_performance_profiler.cpp
+++ b/editor/debugger/editor_performance_profiler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -102,7 +102,7 @@ void EditorPerformanceProfiler::_monitor_draw() {
}
}
- if (active.empty()) {
+ if (active.is_empty()) {
info_message->show();
return;
}
@@ -217,7 +217,7 @@ void EditorPerformanceProfiler::_build_monitor_tree() {
TreeItem *item = _create_monitor_item(i.value().name, base);
item->set_checked(0, monitor_checked.has(i.key()));
i.value().item = item;
- if (!i.value().history.empty()) {
+ if (!i.value().history.is_empty()) {
i.value().update_value(i.value().history.front()->get());
}
}
diff --git a/editor/debugger/editor_performance_profiler.h b/editor/debugger/editor_performance_profiler.h
index 554a0650b8..ea3404b208 100644
--- a/editor/debugger/editor_performance_profiler.h
+++ b/editor/debugger/editor_performance_profiler.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index 930aca6e5a..9304b116d0 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -596,7 +596,7 @@ bool EditorProfiler::is_profiling() {
Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
Vector<Vector<String>> res;
- if (frame_metrics.empty()) {
+ if (frame_metrics.is_empty()) {
return res;
}
diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h
index 637f732b0b..e16bde41f6 100644
--- a/editor/debugger/editor_profiler.h
+++ b/editor/debugger/editor_profiler.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp
index d7a09d6b0c..d825a980c7 100644
--- a/editor/debugger/editor_visual_profiler.cpp
+++ b/editor/debugger/editor_visual_profiler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -666,7 +666,7 @@ bool EditorVisualProfiler::is_profiling() {
Vector<Vector<String>> EditorVisualProfiler::get_data_as_csv() const {
Vector<Vector<String>> res;
#if 0
- if (frame_metrics.empty()) {
+ if (frame_metrics.is_empty()) {
return res;
}
diff --git a/editor/debugger/editor_visual_profiler.h b/editor/debugger/editor_visual_profiler.h
index 49a2d5c53a..6b04fdbafc 100644
--- a/editor/debugger/editor_visual_profiler.h
+++ b/editor/debugger/editor_visual_profiler.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index fd33115cda..c92e94270e 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -343,7 +343,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
DebuggerMarshalls::ResourceUsage usage;
usage.deserialize(p_data);
- int total = 0;
+ uint64_t total = 0;
for (List<DebuggerMarshalls::ResourceInfo>::Element *E = usage.infos.front(); E; E = E->next()) {
TreeItem *it = vmem_tree->create_item(root);
@@ -490,17 +490,17 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
if (oe.callstack.size() > 0) {
// If available, use the script's stack in the error title.
error_title = oe.callstack[oe.callstack.size() - 1].func + ": ";
- } else if (!oe.source_func.empty()) {
+ } else if (!oe.source_func.is_empty()) {
// Otherwise try to use the C++ source function.
error_title += oe.source_func + ": ";
}
// If we have a (custom) error message, use it as title, and add a C++ Error
// item with the original error condition.
- error_title += oe.error_descr.empty() ? oe.error : oe.error_descr;
+ error_title += oe.error_descr.is_empty() ? oe.error : oe.error_descr;
error->set_text(1, error_title);
tooltip += " " + error_title + "\n";
- if (!oe.error_descr.empty()) {
+ if (!oe.error_descr.is_empty()) {
// Add item for C++ error condition.
TreeItem *cpp_cond = error_tree->create_item(error);
cpp_cond->set_text(0, "<" + TTR("C++ Error") + ">");
@@ -516,7 +516,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
// Source of the error.
String source_txt = (source_is_project_file ? oe.source_file.get_file() : oe.source_file) + ":" + itos(oe.source_line);
- if (!oe.source_func.empty()) {
+ if (!oe.source_func.is_empty()) {
source_txt += " @ " + oe.source_func + "()";
}
@@ -802,8 +802,8 @@ void ScriptEditorDebugger::_notification(int p_what) {
msg.push_back(true);
msg.push_back(cam->get_fov());
}
- msg.push_back(cam->get_znear());
- msg.push_back(cam->get_zfar());
+ msg.push_back(cam->get_near());
+ msg.push_back(cam->get_far());
_put_msg("scene:override_camera_3D:transform", msg);
}
}
diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h
index 56b34e8e8c..e5fb3c35a9 100644
--- a/editor/debugger/script_editor_debugger.h
+++ b/editor/debugger/script_editor_debugger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index a27f196d49..25e155aafe 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -448,7 +448,7 @@ void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector<
Vector<RemovedDependency> removed_deps;
_find_all_removed_dependencies(EditorFileSystem::get_singleton()->get_filesystem(), removed_deps);
removed_deps.sort();
- if (removed_deps.empty()) {
+ if (removed_deps.is_empty()) {
owners->hide();
text->set_text(TTR("Remove selected files from the project? (no undo)\nYou can find the removed files in the system trash to restore them."));
set_size(Size2());
@@ -480,8 +480,8 @@ void DependencyRemoveDialog::ok_pressed() {
if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("application/boot_splash/image"))) {
ProjectSettings::get_singleton()->set("application/boot_splash/image", "");
}
- if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("rendering/environment/default_environment"))) {
- ProjectSettings::get_singleton()->set("rendering/environment/default_environment", "");
+ if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("rendering/environment/defaults/default_environment"))) {
+ ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", "");
}
if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"))) {
ProjectSettings::get_singleton()->set("display/mouse_cursor/custom_image", "");
@@ -492,8 +492,8 @@ void DependencyRemoveDialog::ok_pressed() {
if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("gui/theme/custom_font"))) {
ProjectSettings::get_singleton()->set("gui/theme/custom_font", "");
}
- if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("audio/default_bus_layout"))) {
- ProjectSettings::get_singleton()->set("audio/default_bus_layout", "");
+ if (files_to_delete[i] == String(ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout"))) {
+ ProjectSettings::get_singleton()->set("audio/buses/default_bus_layout", "");
}
String path = OS::get_singleton()->get_resource_dir() + files_to_delete[i].replace_first("res://", "/");
@@ -639,7 +639,7 @@ void OrphanResourcesDialog::ok_pressed() {
paths.clear();
_find_to_delete(files->get_root(), paths);
- if (paths.empty()) {
+ if (paths.is_empty()) {
return;
}
diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h
index 5d2ae582e6..b17a685df8 100644
--- a/editor/dependency_editor.h
+++ b/editor/dependency_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -111,8 +111,8 @@ class DependencyRemoveDialog : public ConfirmationDialog {
String dependency_folder;
bool operator<(const RemovedDependency &p_other) const {
- if (dependency_folder.empty() != p_other.dependency_folder.empty()) {
- return p_other.dependency_folder.empty();
+ if (dependency_folder.is_empty() != p_other.dependency_folder.is_empty()) {
+ return p_other.dependency_folder.is_empty();
} else {
return dependency < p_other.dependency;
}
diff --git a/editor/dictionary_property_edit.cpp b/editor/dictionary_property_edit.cpp
index 276cd12ded..408177e523 100644
--- a/editor/dictionary_property_edit.cpp
+++ b/editor/dictionary_property_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,11 +32,7 @@
#include "editor_node.h"
void DictionaryPropertyEdit::_notif_change() {
- _change_notify();
-}
-
-void DictionaryPropertyEdit::_notif_changev(const String &p_v) {
- _change_notify(p_v.utf8().get_data());
+ notify_property_list_changed();
}
void DictionaryPropertyEdit::_set_key(const Variant &p_old_key, const Variant &p_new_key) {
@@ -107,7 +103,6 @@ void DictionaryPropertyEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_key"), &DictionaryPropertyEdit::_set_key);
ClassDB::bind_method(D_METHOD("_set_value"), &DictionaryPropertyEdit::_set_value);
ClassDB::bind_method(D_METHOD("_notif_change"), &DictionaryPropertyEdit::_notif_change);
- ClassDB::bind_method(D_METHOD("_notif_changev"), &DictionaryPropertyEdit::_notif_changev);
ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &DictionaryPropertyEdit::_dont_undo_redo);
}
@@ -128,8 +123,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val
ur->create_action(TTR("Change Dictionary Key"));
ur->add_do_method(this, "_set_key", key, p_value);
ur->add_undo_method(this, "_set_key", p_value, key);
- ur->add_do_method(this, "_notif_changev", p_name);
- ur->add_undo_method(this, "_notif_changev", p_name);
ur->commit_action();
return true;
@@ -142,8 +135,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val
ur->create_action(TTR("Change Dictionary Value"));
ur->add_do_method(this, "_set_value", key, p_value);
ur->add_undo_method(this, "_set_value", key, value);
- ur->add_do_method(this, "_notif_changev", p_name);
- ur->add_undo_method(this, "_notif_changev", p_name);
ur->commit_action();
return true;
diff --git a/editor/dictionary_property_edit.h b/editor/dictionary_property_edit.h
index 5c97b94d9f..e0fd945491 100644
--- a/editor/dictionary_property_edit.h
+++ b/editor/dictionary_property_edit.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,6 @@ class DictionaryPropertyEdit : public Reference {
StringName property;
void _notif_change();
- void _notif_changev(const String &p_v);
void _set_key(const Variant &p_old_key, const Variant &p_new_key);
void _set_value(const Variant &p_key, const Variant &p_value);
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 5ee9abb183..47ea8cbe2a 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -813,7 +813,7 @@ void DocTools::generate(bool p_basic_types) {
}
// Skip adding the lang if it doesn't expose anything (e.g. C#).
- if (c.methods.empty() && c.constants.empty()) {
+ if (c.methods.is_empty() && c.constants.is_empty()) {
continue;
}
@@ -1165,7 +1165,7 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str
_write_string(f, 1, "<tutorials>");
for (int i = 0; i < c.tutorials.size(); i++) {
DocData::TutorialDoc tutorial = c.tutorials.get(i);
- String title_attribute = (!tutorial.title.empty()) ? " title=\"" + tutorial.title.xml_escape() + "\"" : "";
+ String title_attribute = (!tutorial.title.is_empty()) ? " title=\"" + tutorial.title.xml_escape() + "\"" : "";
_write_string(f, 2, "<link" + title_attribute + ">" + tutorial.link.xml_escape() + "</link>");
}
_write_string(f, 1, "</tutorials>");
diff --git a/editor/doc_tools.h b/editor/doc_tools.h
index db27e38c8b..809eedff2a 100644
--- a/editor/doc_tools.h
+++ b/editor/doc_tools.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index 95802a0b9c..2ed937b6ff 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -133,7 +133,7 @@ EditorAbout::EditorAbout() {
Label *about_text = memnew(Label);
about_text->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
about_text->set_text(VERSION_FULL_NAME + hash +
- String::utf8("\n\xc2\xa9 2007-2020 Juan Linietsky, Ariel Manzur.\n\xc2\xa9 2014-2020 ") +
+ String::utf8("\n\xc2\xa9 2007-2021 Juan Linietsky, Ariel Manzur.\n\xc2\xa9 2014-2021 ") +
TTR("Godot Engine contributors") + "\n");
hbc->add_child(about_text);
diff --git a/editor/editor_about.h b/editor/editor_about.h
index ae4d9c73bf..efb7245e78 100644
--- a/editor/editor_about.h
+++ b/editor/editor_about.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index aa6f7c8766..2d29076476 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_asset_installer.h b/editor/editor_asset_installer.h
index e31cff8845..d9233a5ce8 100644
--- a/editor/editor_asset_installer.h
+++ b/editor/editor_asset_installer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_atlas_packer.cpp b/editor/editor_atlas_packer.cpp
index 68abeb2cda..1b4a505edb 100644
--- a/editor/editor_atlas_packer.cpp
+++ b/editor/editor_atlas_packer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_atlas_packer.h b/editor/editor_atlas_packer.h
index 4a9c3a776b..89824dff1c 100644
--- a/editor/editor_atlas_packer.h
+++ b/editor/editor_atlas_packer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index d768f00c3b..9a826ab106 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,11 +78,11 @@ void EditorAudioBus::_notification(int p_what) {
Color bypass_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(0.13, 0.8, 1.0) : Color(0.44, 0.87, 1.0);
solo->set_icon(get_theme_icon("AudioBusSolo", "EditorIcons"));
- solo->add_theme_color_override("icon_color_pressed", solo_color);
+ solo->add_theme_color_override("icon_pressed_color", solo_color);
mute->set_icon(get_theme_icon("AudioBusMute", "EditorIcons"));
- mute->add_theme_color_override("icon_color_pressed", mute_color);
+ mute->add_theme_color_override("icon_pressed_color", mute_color);
bypass->set_icon(get_theme_icon("AudioBusBypass", "EditorIcons"));
- bypass->add_theme_color_override("icon_color_pressed", bypass_color);
+ bypass->add_theme_color_override("icon_pressed_color", bypass_color);
bus_options->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons"));
@@ -1191,9 +1191,9 @@ void EditorAudioBuses::_load_layout() {
}
void EditorAudioBuses::_load_default_layout() {
- String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout");
+ String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout");
- Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", true);
+ Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE);
if (state.is_null()) {
EditorNode::get_singleton()->show_warning(vformat(TTR("There is no '%s' file."), layout_path));
return;
@@ -1209,7 +1209,7 @@ void EditorAudioBuses::_load_default_layout() {
void EditorAudioBuses::_file_dialog_callback(const String &p_string) {
if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_OPEN_FILE) {
- Ref<AudioBusLayout> state = ResourceLoader::load(p_string, "", true);
+ Ref<AudioBusLayout> state = ResourceLoader::load(p_string, "", ResourceFormatLoader::CACHE_MODE_IGNORE);
if (state.is_null()) {
EditorNode::get_singleton()->show_warning(TTR("Invalid file, not an audio bus layout."));
return;
@@ -1257,7 +1257,7 @@ EditorAudioBuses::EditorAudioBuses() {
add_child(top_hb);
file = memnew(Label);
- String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout");
+ String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout");
file->set_text(String(TTR("Layout")) + ": " + layout_path.get_file());
file->set_clip_text(true);
file->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -1313,7 +1313,7 @@ EditorAudioBuses::EditorAudioBuses() {
set_v_size_flags(SIZE_EXPAND_FILL);
- edited_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout");
+ edited_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout");
file_dialog = memnew(EditorFileDialog);
List<String> ext;
@@ -1330,7 +1330,7 @@ EditorAudioBuses::EditorAudioBuses() {
void EditorAudioBuses::open_layout(const String &p_path) {
EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
- Ref<AudioBusLayout> state = ResourceLoader::load(p_path, "", true);
+ Ref<AudioBusLayout> state = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE);
if (state.is_null()) {
EditorNode::get_singleton()->show_warning(TTR("Invalid file, not an audio bus layout."));
return;
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index b5f2f5af81..8dfc2137ef 100644
--- a/editor/editor_audio_buses.h
+++ b/editor/editor_audio_buses.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 2251440544..d46df05f6e 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -402,7 +402,7 @@ void EditorAutoloadSettings::update_autoload() {
String name = pi.name.get_slice("/", 1);
String path = ProjectSettings::get_singleton()->get(pi.name);
- if (name.empty()) {
+ if (name.is_empty()) {
continue;
}
@@ -774,7 +774,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
String name = pi.name.get_slice("/", 1);
String path = ProjectSettings::get_singleton()->get(pi.name);
- if (name.empty()) {
+ if (name.is_empty()) {
continue;
}
diff --git a/editor/editor_autoload_settings.h b/editor/editor_autoload_settings.h
index 845f86fbb9..762457463c 100644
--- a/editor/editor_autoload_settings.h
+++ b/editor/editor_autoload_settings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index eab1ecf373..213c3f5631 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -273,16 +273,6 @@ EditorPlugin *EditorData::get_editor(Object *p_object) {
return nullptr;
}
-EditorPlugin *EditorData::get_subeditor(Object *p_object) {
- for (int i = editor_plugins.size() - 1; i > -1; i--) {
- if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) {
- return editor_plugins[i];
- }
- }
-
- return nullptr;
-}
-
Vector<EditorPlugin *> EditorData::get_subeditors(Object *p_object) {
Vector<EditorPlugin *> sub_plugins;
for (int i = editor_plugins.size() - 1; i > -1; i--) {
@@ -331,7 +321,7 @@ Dictionary EditorData::get_editor_states() const {
Dictionary metadata;
for (int i = 0; i < editor_plugins.size(); i++) {
Dictionary state = editor_plugins[i]->get_state();
- if (state.empty()) {
+ if (state.is_empty()) {
continue;
}
metadata[editor_plugins[i]->get_name()] = state;
@@ -468,24 +458,25 @@ void EditorData::add_custom_type(const String &p_type, const String &p_inherits,
custom_types[p_inherits].push_back(ct);
}
-Object *EditorData::instance_custom_type(const String &p_type, const String &p_inherits) {
+Variant EditorData::instance_custom_type(const String &p_type, const String &p_inherits) {
if (get_custom_types().has(p_inherits)) {
for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) {
if (get_custom_types()[p_inherits][i].name == p_type) {
Ref<Script> script = get_custom_types()[p_inherits][i].script;
- Object *ob = ClassDB::instance(p_inherits);
- ERR_FAIL_COND_V(!ob, nullptr);
- if (ob->is_class("Node")) {
- ob->call("set_name", p_type);
+ Variant ob = ClassDB::instance(p_inherits);
+ ERR_FAIL_COND_V(!ob, Variant());
+ Node *n = Object::cast_to<Node>(ob);
+ if (n) {
+ n->set_name(p_type);
}
- ob->set_script(script);
+ ((Object *)ob)->set_script(script);
return ob;
}
}
}
- return nullptr;
+ return Variant();
}
void EditorData::remove_custom_type(const String &p_type) {
@@ -493,7 +484,7 @@ void EditorData::remove_custom_type(const String &p_type) {
for (int i = 0; i < E->get().size(); i++) {
if (E->get()[i].name == p_type) {
E->get().remove(i);
- if (E->get().empty()) {
+ if (E->get().is_empty()) {
custom_types.erase(E->key());
}
return;
@@ -509,6 +500,7 @@ int EditorData::add_edited_scene(int p_at_pos) {
EditedScene es;
es.root = nullptr;
es.path = String();
+ es.file_modified_time = 0;
es.history_current = -1;
es.version = 0;
es.live_edit_root = NodePath(String("/root"));
@@ -665,6 +657,10 @@ void EditorData::set_edited_scene_root(Node *p_root) {
p_root->set_filename(edited_scene[current_edited_scene].path);
}
}
+
+ if (edited_scene[current_edited_scene].path != "") {
+ edited_scene.write[current_edited_scene].file_modified_time = FileAccess::get_modified_time(edited_scene[current_edited_scene].path);
+ }
}
int EditorData::get_edited_scene_count() const {
@@ -696,6 +692,21 @@ uint64_t EditorData::get_scene_version(int p_idx) const {
return edited_scene[p_idx].version;
}
+void EditorData::set_scene_modified_time(int p_idx, uint64_t p_time) {
+ if (p_idx == -1) {
+ p_idx = current_edited_scene;
+ }
+
+ ERR_FAIL_INDEX(p_idx, edited_scene.size());
+
+ edited_scene.write[p_idx].file_modified_time = p_time;
+}
+
+uint64_t EditorData::get_scene_modified_time(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), 0);
+ return edited_scene[p_idx].file_modified_time;
+}
+
String EditorData::get_scene_type(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
if (!edited_scene[p_idx].root) {
@@ -867,18 +878,18 @@ StringName EditorData::script_class_get_base(const String &p_class) const {
return script->get_language()->get_global_class_name(base_script->get_path());
}
-Object *EditorData::script_class_instance(const String &p_class) {
+Variant EditorData::script_class_instance(const String &p_class) {
if (ScriptServer::is_global_class(p_class)) {
- Object *obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class));
+ Variant obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class));
if (obj) {
Ref<Script> script = script_class_load_script(p_class);
if (script.is_valid()) {
- obj->set_script(script);
+ ((Object *)obj)->set_script(script);
}
return obj;
}
}
- return nullptr;
+ return Variant();
}
Ref<Script> EditorData::script_class_load_script(const String &p_class) const {
@@ -901,7 +912,7 @@ String EditorData::script_class_get_icon_path(const String &p_class) const {
String current = p_class;
String ret = _script_class_icon_paths[current];
- while (ret.empty()) {
+ while (ret.is_empty()) {
current = script_class_get_base(current);
if (!ScriptServer::is_global_class(current)) {
return String();
@@ -931,7 +942,15 @@ void EditorData::script_class_save_icon_paths() {
}
}
- if (d.empty()) {
+ Dictionary old;
+ if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) {
+ old = ProjectSettings::get_singleton()->get("_global_script_class_icons");
+ }
+ if ((!old.is_empty() || d.is_empty()) && d.hash() == old.hash()) {
+ return;
+ }
+
+ if (d.is_empty()) {
if (ProjectSettings::get_singleton()->has_setting("_global_script_class_icons")) {
ProjectSettings::get_singleton()->clear("_global_script_class_icons");
}
@@ -1125,7 +1144,7 @@ List<Node *> EditorSelection::get_full_selected_node_list() {
}
void EditorSelection::clear() {
- while (!selection.empty()) {
+ while (!selection.is_empty()) {
remove_node(selection.front()->key());
}
diff --git a/editor/editor_data.h b/editor/editor_data.h
index 0d27e06987..18b4137162 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -111,6 +111,7 @@ public:
struct EditedScene {
Node *root = nullptr;
String path;
+ uint64_t file_modified_time = 0;
Dictionary editor_states;
List<Node *> selection;
Vector<EditorHistory::History> history_stored;
@@ -144,7 +145,6 @@ private:
public:
EditorPlugin *get_editor(Object *p_object);
- EditorPlugin *get_subeditor(Object *p_object);
Vector<EditorPlugin *> get_subeditors(Object *p_object);
EditorPlugin *get_editor(String p_name);
@@ -171,7 +171,7 @@ public:
void restore_editor_global_states();
void add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon);
- Object *instance_custom_type(const String &p_type, const String &p_inherits);
+ Variant instance_custom_type(const String &p_type, const String &p_inherits);
void remove_custom_type(const String &p_type);
const Map<String, Vector<CustomType>> &get_custom_types() const { return custom_types; }
@@ -191,6 +191,8 @@ public:
Ref<Script> get_scene_root_script(int p_idx) const;
void set_edited_scene_version(uint64_t version, int p_scene_idx = -1);
uint64_t get_scene_version(int p_idx) const;
+ void set_scene_modified_time(int p_idx, uint64_t p_time);
+ uint64_t get_scene_modified_time(int p_idx) const;
void clear_edited_scenes();
void set_edited_scene_live_edit_root(const NodePath &p_root);
NodePath get_edited_scene_live_edit_root();
@@ -208,7 +210,7 @@ public:
bool script_class_is_parent(const String &p_class, const String &p_inherits);
StringName script_class_get_base(const String &p_class) const;
- Object *script_class_instance(const String &p_class);
+ Variant script_class_instance(const String &p_class);
Ref<Script> script_class_load_script(const String &p_class) const;
diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp
index 17e0fd0fae..4366d83fe2 100644
--- a/editor/editor_dir_dialog.cpp
+++ b/editor/editor_dir_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_dir_dialog.h b/editor/editor_dir_dialog.h
index b688e9dc06..05451b7bda 100644
--- a/editor/editor_dir_dialog.h
+++ b/editor/editor_dir_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 07318c14bc..7f5f51cf70 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -301,6 +301,8 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags)
}
Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
+ ERR_FAIL_COND_V_MSG(p_total < 1, ERR_PARAMETER_RANGE_ERROR, "Must select at least one file to export.");
+
PackData *pd = (PackData *)p_userdata;
SavedData sd;
@@ -368,6 +370,8 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa
}
Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
+ ERR_FAIL_COND_V_MSG(p_total < 1, ERR_PARAMETER_RANGE_ERROR, "Must select at least one file to export.");
+
String path = p_path.replace_first("res://", "");
ZipData *zd = (ZipData *)p_userdata;
@@ -398,7 +402,7 @@ Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_pat
Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const {
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
ERR_FAIL_COND_V(theme.is_null(), Ref<ImageTexture>());
- if (EditorNode::get_singleton()->get_viewport()->is_layout_rtl()) {
+ if (EditorNode::get_singleton()->get_main_control()->is_layout_rtl()) {
return theme->get_icon("PlayBackwards", "EditorIcons");
} else {
return theme->get_icon("Play", "EditorIcons");
@@ -507,6 +511,11 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
if (dir.begins_with(".")) {
continue;
}
+
+ if (EditorFileSystem::_should_skip_directory(cur_dir + dir)) {
+ continue;
+ }
+
da->change_dir(dir);
_edit_files_with_filter(da, p_filters, r_list, exclude);
da->change_dir("..");
@@ -521,7 +530,7 @@ void EditorExportPlatform::_edit_filter_list(Set<String> &r_list, const String &
Vector<String> filters;
for (int i = 0; i < split.size(); i++) {
String f = split[i].strip_edges();
- if (f.empty()) {
+ if (f.is_empty()) {
continue;
}
filters.push_back(f);
@@ -732,6 +741,26 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
_export_find_dependencies(files[i], paths);
}
+
+ // Add autoload resources and their dependencies
+ List<PropertyInfo> props;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ const PropertyInfo &pi = E->get();
+
+ if (!pi.name.begins_with("autoload/")) {
+ continue;
+ }
+
+ String autoload_path = ProjectSettings::get_singleton()->get(pi.name);
+
+ if (autoload_path.begins_with("*")) {
+ autoload_path = autoload_path.substr(1);
+ }
+
+ _export_find_dependencies(autoload_path, paths);
+ }
}
//add native icons to non-resource include list
@@ -754,7 +783,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<String> enc_in_split = p_preset->get_enc_in_filter().split(",");
for (int i = 0; i < enc_in_split.size(); i++) {
String f = enc_in_split[i].strip_edges();
- if (f.empty()) {
+ if (f.is_empty()) {
continue;
}
enc_in_filters.push_back(f);
@@ -763,7 +792,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<String> enc_ex_split = p_preset->get_enc_ex_filter().split(",");
for (int i = 0; i < enc_ex_split.size(); i++) {
String f = enc_ex_split[i].strip_edges();
- if (f.empty()) {
+ if (f.is_empty()) {
continue;
}
enc_ex_filters.push_back(f);
@@ -799,17 +828,25 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
}
}
+ Error err = OK;
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
+
for (int i = 0; i < export_plugins.size(); i++) {
export_plugins.write[i]->set_export_preset(p_preset);
if (p_so_func) {
for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
- p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
+ err = p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
+ if (err != OK) {
+ return err;
+ }
}
}
for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
- p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size(), enc_in_filters, enc_ex_filters, key);
+ err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size(), enc_in_filters, enc_ex_filters, key);
+ if (err != OK) {
+ return err;
+ }
}
export_plugins.write[i]->_clear();
@@ -831,7 +868,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
//file is imported, replace by what it imports
Ref<ConfigFile> config;
config.instance();
- Error err = config->load(path + ".import");
+ err = config->load(path + ".import");
if (err != OK) {
ERR_PRINT("Could not parse: '" + path + "', not exported.");
continue;
@@ -895,12 +932,18 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
}
if (p_so_func) {
for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
- p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
+ err = p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
+ if (err != OK) {
+ return err;
+ }
}
}
for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
- p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key);
+ err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key);
+ if (err != OK) {
+ return err;
+ }
if (export_plugins[i]->extra_files[j].remap) {
do_export = false; //if remap, do not
path_remaps.push_back(path);
@@ -920,7 +963,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
//just store it as it comes
if (do_export) {
Vector<uint8_t> array = FileAccess::get_file_as_array(path);
- p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key);
+ err = p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key);
+ if (err != OK) {
+ return err;
+ }
}
}
@@ -956,7 +1002,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
new_file.write[j] = utf8[j];
}
- p_func(p_udata, from + ".remap", new_file, idx, total, enc_in_filters, enc_ex_filters, key);
+ err = p_func(p_udata, from + ".remap", new_file, idx, total, enc_in_filters, enc_ex_filters, key);
+ if (err != OK) {
+ return err;
+ }
}
} else {
//old remap mode, will still work, but it's unused because it's not multiple pck export friendly
@@ -969,11 +1018,17 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image");
if (icon != String() && FileAccess::exists(icon)) {
Vector<uint8_t> array = FileAccess::get_file_as_array(icon);
- p_func(p_udata, icon, array, idx, total, enc_in_filters, enc_ex_filters, key);
+ err = p_func(p_udata, icon, array, idx, total, enc_in_filters, enc_ex_filters, key);
+ if (err != OK) {
+ return err;
+ }
}
if (splash != String() && FileAccess::exists(splash) && icon != splash) {
Vector<uint8_t> array = FileAccess::get_file_as_array(splash);
- p_func(p_udata, splash, array, idx, total, enc_in_filters, enc_ex_filters, key);
+ err = p_func(p_udata, splash, array, idx, total, enc_in_filters, enc_ex_filters, key);
+ if (err != OK) {
+ return err;
+ }
}
// Store text server data if exists.
@@ -981,7 +1036,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
String ts_data = "res://" + TS->get_support_data_filename();
if (FileAccess::exists(ts_data)) {
Vector<uint8_t> array = FileAccess::get_file_as_array(ts_data);
- p_func(p_udata, ts_data, array, idx, total, enc_in_filters, enc_ex_filters, key);
+ err = p_func(p_udata, ts_data, array, idx, total, enc_in_filters, enc_ex_filters, key);
+ if (err != OK) {
+ return err;
+ }
}
}
@@ -991,9 +1049,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb);
DirAccess::remove_file_or_error(engine_cfb);
- p_func(p_udata, "res://" + config_file, data, idx, total, enc_in_filters, enc_ex_filters, key);
-
- return OK;
+ return p_func(p_udata, "res://" + config_file, data, idx, total, enc_in_filters, enc_ex_filters, key);
}
Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObject &p_so) {
@@ -1008,6 +1064,10 @@ Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObj
Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) {
EditorProgress ep("savepack", TTR("Packing"), 102, true);
+ // Create the temporary export directory if it doesn't exist.
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ da->make_dir_recursive(EditorSettings::get_singleton()->get_cache_dir());
+
String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp");
FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE);
ERR_FAIL_COND_V_MSG(!ftmp, ERR_CANT_CREATE, "Cannot create file '" + tmppath + "'.");
@@ -1023,6 +1083,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
if (err != OK) {
DirAccess::remove_file_or_error(tmppath);
+ ERR_PRINT("Failed to export project files");
return err;
}
@@ -1379,9 +1440,9 @@ void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, in
}
String EditorExportPlatform::test_etc2() const {
- String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
- bool etc_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc");
- bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2");
+ String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
+ bool etc_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc");
+ bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2");
if (driver == "GLES2" && !etc_supported) {
return TTR("Target platform requires 'ETC' texture compression for GLES2. Enable 'Import Etc' in Project Settings.");
@@ -1393,9 +1454,9 @@ String EditorExportPlatform::test_etc2() const {
}
String EditorExportPlatform::test_etc2_or_pvrtc() const {
- String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
- bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2");
- bool pvrtc_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc");
+ String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
+ bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2");
+ bool pvrtc_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc");
if (driver == "GLES2" && !pvrtc_supported) {
return TTR("Target platform requires 'PVRTC' texture compression for GLES2. Enable 'Import Pvrtc' in Project Settings.");
@@ -1696,7 +1757,7 @@ bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset,
valid = dvalid || rvalid;
r_missing_templates = !valid;
- if (!err.empty()) {
+ if (!err.is_empty()) {
r_error = err;
}
return valid;
@@ -1783,7 +1844,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
}
}
- if (err == OK && !so_files.empty()) {
+ if (err == OK && !so_files.is_empty()) {
//if shared object files, copy them
da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < so_files.size() && err == OK; i++) {
@@ -1878,7 +1939,7 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con
return;
}
- bool convert = GLOBAL_GET("editor/convert_text_resources_to_binary_on_export");
+ bool convert = GLOBAL_GET("editor/export/convert_text_resources_to_binary");
if (!convert) {
return;
}
@@ -1898,5 +1959,5 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con
}
EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() {
- GLOBAL_DEF("editor/convert_text_resources_to_binary_on_export", false);
+ GLOBAL_DEF("editor/export/convert_text_resources_to_binary", false);
}
diff --git a/editor/editor_export.h b/editor/editor_export.h
index 584ef17035..e6026e7aae 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp
index ecb659e7d3..bd00d86ec8 100644
--- a/editor/editor_feature_profile.cpp
+++ b/editor/editor_feature_profile.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -96,7 +96,7 @@ void EditorFeatureProfile::set_disable_class_property(const StringName &p_class,
} else {
ERR_FAIL_COND(!disabled_properties.has(p_class));
disabled_properties[p_class].erase(p_property);
- if (disabled_properties[p_class].empty()) {
+ if (disabled_properties[p_class].is_empty()) {
disabled_properties.erase(p_class);
}
}
@@ -277,11 +277,7 @@ void EditorFeatureProfile::_bind_methods() {
BIND_ENUM_CONSTANT(FEATURE_MAX);
}
-EditorFeatureProfile::EditorFeatureProfile() {
- for (int i = 0; i < FEATURE_MAX; i++) {
- features_disabled[i] = false;
- }
-}
+EditorFeatureProfile::EditorFeatureProfile() {}
//////////////////////////
diff --git a/editor/editor_feature_profile.h b/editor/editor_feature_profile.h
index 0f066b8f4a..01e6a6a142 100644
--- a/editor/editor_feature_profile.h
+++ b/editor/editor_feature_profile.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 8ded47605c..6d694358bf 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -230,7 +230,6 @@ void EditorFileDialog::update_dir() {
void EditorFileDialog::_dir_entered(String p_dir) {
dir_access->change_dir(p_dir);
- file->set_text("");
invalidate();
update_dir();
_push_history();
@@ -249,6 +248,14 @@ void EditorFileDialog::_save_confirm_pressed() {
void EditorFileDialog::_post_popup() {
ConfirmationDialog::_post_popup();
+
+ // Check if the current path doesn't exist and correct it.
+ String current = dir_access->get_current_dir();
+ while (!dir_access->dir_exists(current)) {
+ current = current.get_base_dir();
+ }
+ set_current_dir(current);
+
if (invalidated) {
update_file_list();
invalidated = false;
@@ -287,11 +294,17 @@ void EditorFileDialog::_post_popup() {
} else {
name = name.get_file() + "/";
}
-
- recent->add_item(name, folder);
- recent->set_item_metadata(recent->get_item_count() - 1, recentd[i]);
- recent->set_item_icon_modulate(recent->get_item_count() - 1, folder_color);
+ bool exists = dir_access->dir_exists(recentd[i]);
+ if (!exists) {
+ // Remove invalid directory from the list of Recent directories.
+ recentd.remove(i--);
+ } else {
+ recent->add_item(name, folder);
+ recent->set_item_metadata(recent->get_item_count() - 1, recentd[i]);
+ recent->set_item_icon_modulate(recent->get_item_count() - 1, folder_color);
+ }
}
+ EditorSettings::get_singleton()->set_recent_dirs(recentd);
local_history.clear();
local_history_pos = -1;
@@ -442,9 +455,12 @@ void EditorFileDialog::_action_pressed() {
}
}
+ // Add first extension of filter if no valid extension is found.
if (!valid) {
- exterr->popup_centered(Size2(250, 80) * EDSCALE);
- return;
+ int idx = filter->get_selected();
+ String flt = filters[idx].get_slice(";", 0);
+ String ext = flt.get_slice(",", 0).strip_edges().get_extension();
+ f += "." + ext;
}
if (dir_access->file_exists(f) && !disable_overwrite_warning) {
@@ -499,7 +515,7 @@ void EditorFileDialog::_multi_selected(int p_item, bool p_selected) {
}
void EditorFileDialog::_items_clear_selection() {
- item_list->unselect_all();
+ item_list->deselect_all();
// If nothing is selected, then block Open button.
switch (mode) {
@@ -595,7 +611,7 @@ void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p
void EditorFileDialog::_item_list_rmb_clicked(const Vector2 &p_pos) {
// Right click on folder background. Deselect all files so that actions are applied on the current folder.
for (int i = 0; i < item_list->get_item_count(); i++) {
- item_list->unselect(i);
+ item_list->deselect(i);
}
item_menu->clear();
@@ -758,7 +774,7 @@ void EditorFileDialog::update_file_list() {
dirs.sort_custom<NaturalNoCaseComparator>();
files.sort_custom<NaturalNoCaseComparator>();
- while (!dirs.empty()) {
+ while (!dirs.is_empty()) {
const String &dir_name = dirs.front()->get();
item_list->add_item(dir_name);
@@ -806,8 +822,8 @@ void EditorFileDialog::update_file_list() {
}
}
- while (!files.empty()) {
- bool match = patterns.empty();
+ while (!files.is_empty()) {
+ bool match = patterns.is_empty();
for (List<String>::Element *E = patterns.front(); E; E = E->next()) {
if (files.front()->get().matchn(E->get())) {
@@ -849,7 +865,7 @@ void EditorFileDialog::update_file_list() {
}
if (favorites->get_current() >= 0) {
- favorites->unselect(favorites->get_current());
+ favorites->deselect(favorites->get_current());
}
favorite->set_pressed(false);
@@ -1134,7 +1150,6 @@ void EditorFileDialog::_update_drives() {
void EditorFileDialog::_favorite_selected(int p_idx) {
dir_access->change_dir(favorites->get_item_metadata(p_idx));
- file->set_text("");
update_dir();
invalidate();
_push_history();
@@ -1226,7 +1241,7 @@ void EditorFileDialog::_update_favorites() {
if (setthis) {
favorite->set_pressed(true);
favorites->set_current(favorites->get_item_count() - 1);
- recent->unselect_all();
+ recent->deselect_all();
}
}
}
@@ -1683,10 +1698,6 @@ EditorFileDialog::EditorFileDialog() {
mkdirerr->set_text(TTR("Could not create folder."));
add_child(mkdirerr);
- exterr = memnew(AcceptDialog);
- exterr->set_text(TTR("Must use a valid extension."));
- add_child(exterr);
-
update_filters();
update_dir();
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index df5b41ae1d..5a5e3a8807 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -110,7 +110,6 @@ private:
LineEdit *file;
OptionButton *filter;
AcceptDialog *mkdirerr;
- AcceptDialog *exterr;
DirAccess *dir_access;
ConfirmationDialog *confirm_save;
DependencyRemoveDialog *remove_dialog;
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index a8a7262cf0..dce022e86e 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -595,7 +595,7 @@ void EditorFileSystem::scan() {
return;
}
- if (scanning || scanning_changes || thread) {
+ if (scanning || scanning_changes || thread.is_started()) {
return;
}
@@ -619,13 +619,13 @@ void EditorFileSystem::scan() {
_queue_update_script_classes();
first_scan = false;
} else {
- ERR_FAIL_COND(thread);
+ ERR_FAIL_COND(thread.is_started());
set_process(true);
Thread::Settings s;
scanning = true;
scan_total = 0;
s.priority = Thread::PRIORITY_LOW;
- thread = Thread::create(_thread_func, this, s);
+ thread.start(_thread_func, this, s);
//tree->hide();
//progress->show();
}
@@ -669,10 +669,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
continue;
}
- if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) { // skip if another project inside this
- continue;
- }
- if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) { // skip if another project inside this
+ if (_should_skip_directory(cd.plus_file(f))) {
continue;
}
@@ -874,10 +871,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
int idx = p_dir->find_dir_index(f);
if (idx == -1) {
- if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) { // skip if another project inside this
- continue;
- }
- if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) { // skip if another project inside this
+ if (_should_skip_directory(cd.plus_file(f))) {
continue;
}
@@ -1046,7 +1040,7 @@ void EditorFileSystem::_thread_func_sources(void *_userdata) {
void EditorFileSystem::scan_changes() {
if (first_scan || // Prevent a premature changes scan from inhibiting the first full scan
- scanning || scanning_changes || thread) {
+ scanning || scanning_changes || thread.is_started()) {
scan_changes_pending = true;
set_process(true);
return;
@@ -1076,12 +1070,12 @@ void EditorFileSystem::scan_changes() {
scanning_changes_done = true;
emit_signal("sources_changed", sources_changed.size() > 0);
} else {
- ERR_FAIL_COND(thread_sources);
+ ERR_FAIL_COND(thread_sources.is_started());
set_process(true);
scan_total = 0;
Thread::Settings s;
s.priority = Thread::PRIORITY_LOW;
- thread_sources = Thread::create(_thread_func_sources, this, s);
+ thread_sources.start(_thread_func_sources, this, s);
}
}
@@ -1092,17 +1086,14 @@ void EditorFileSystem::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
- Thread *active_thread = thread ? thread : thread_sources;
- if (use_threads && active_thread) {
+ Thread &active_thread = thread.is_started() ? thread : thread_sources;
+ if (use_threads && active_thread.is_started()) {
//abort thread if in progress
abort_scan = true;
while (scanning) {
OS::get_singleton()->delay_usec(1000);
}
- Thread::wait_to_finish(active_thread);
- memdelete(active_thread);
- thread = nullptr;
- thread_sources = nullptr;
+ active_thread.wait_to_finish();
WARN_PRINT("Scan thread aborted...");
set_process(false);
}
@@ -1125,9 +1116,7 @@ void EditorFileSystem::_notification(int p_what) {
set_process(false);
- Thread::wait_to_finish(thread_sources);
- memdelete(thread_sources);
- thread_sources = nullptr;
+ thread_sources.wait_to_finish();
if (_update_scan_actions()) {
emit_signal("filesystem_changed");
}
@@ -1135,7 +1124,7 @@ void EditorFileSystem::_notification(int p_what) {
_queue_update_script_classes();
first_scan = false;
}
- } else if (!scanning && thread) {
+ } else if (!scanning && thread.is_started()) {
set_process(false);
if (filesystem) {
@@ -1143,9 +1132,7 @@ void EditorFileSystem::_notification(int p_what) {
}
filesystem = new_filesystem;
new_filesystem = nullptr;
- Thread::wait_to_finish(thread);
- memdelete(thread);
- thread = nullptr;
+ thread.wait_to_finish();
_update_scan_actions();
emit_signal("filesystem_changed");
emit_signal("sources_changed", sources_changed.size() > 0);
@@ -1420,11 +1407,11 @@ void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) {
}
void EditorFileSystem::update_script_classes() {
- if (!update_script_classes_queued) {
+ if (!update_script_classes_queued.is_set()) {
return;
}
- update_script_classes_queued = false;
+ update_script_classes_queued.clear();
ScriptServer::global_classes_clear();
if (get_filesystem()) {
_scan_script_classes(get_filesystem());
@@ -1443,11 +1430,11 @@ void EditorFileSystem::update_script_classes() {
}
void EditorFileSystem::_queue_update_script_classes() {
- if (update_script_classes_queued) {
+ if (update_script_classes_queued.is_set()) {
return;
}
- update_script_classes_queued = true;
+ update_script_classes_queued.set();
call_deferred("update_script_classes");
}
@@ -1477,20 +1464,21 @@ void EditorFileSystem::update_file(const String &p_file) {
String type = ResourceLoader::get_resource_type(p_file);
if (cpos == -1) {
- //the file did not exist, it was added
+ // The file did not exist, it was added.
- late_added_files.insert(p_file); //remember that it was added. This mean it will be scanned and imported on editor restart
+ late_added_files.insert(p_file); // Remember that it was added. This mean it will be scanned and imported on editor restart.
int idx = 0;
+ String file_name = p_file.get_file();
for (int i = 0; i < fs->files.size(); i++) {
- if (p_file < fs->files[i]->file) {
+ if (file_name < fs->files[i]->file) {
break;
}
idx++;
}
EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo);
- fi->file = p_file.get_file();
+ fi->file = file_name;
fi->import_modified_time = 0;
fi->import_valid = ResourceLoader::is_import_valid(p_file);
@@ -1985,6 +1973,20 @@ Error EditorFileSystem::_resource_import(const String &p_path) {
return OK;
}
+bool EditorFileSystem::_should_skip_directory(const String &p_path) {
+ if (FileAccess::exists(p_path.plus_file("project.godot"))) {
+ // skip if another project inside this
+ return true;
+ }
+
+ if (FileAccess::exists(p_path.plus_file(".gdignore"))) {
+ // skip if a `.gdignore` file is inside this
+ return true;
+ }
+
+ return false;
+}
+
bool EditorFileSystem::is_group_file(const String &p_path) const {
return group_file_cache.has(p_path);
}
@@ -2073,17 +2075,15 @@ void EditorFileSystem::_update_extensions() {
EditorFileSystem::EditorFileSystem() {
ResourceLoader::import = _resource_import;
- reimport_on_missing_imported_files = GLOBAL_DEF("editor/reimport_missing_imported_files", true);
+ reimport_on_missing_imported_files = GLOBAL_DEF("editor/import/reimport_missing_imported_files", true);
singleton = this;
filesystem = memnew(EditorFileSystemDirectory); //like, empty
filesystem->parent = nullptr;
- thread = nullptr;
scanning = false;
importing = false;
use_threads = true;
- thread_sources = nullptr;
new_filesystem = nullptr;
abort_scan = false;
@@ -2099,7 +2099,7 @@ EditorFileSystem::EditorFileSystem() {
memdelete(da);
scan_total = 0;
- update_script_classes_queued = false;
+ update_script_classes_queued.clear();
first_scan = true;
scan_changes_pending = false;
revalidate_import_files = false;
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index a7ab4d6a9a..59bde238a8 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,6 +34,7 @@
#include "core/os/dir_access.h"
#include "core/os/thread.h"
#include "core/os/thread_safe.h"
+#include "core/templates/safe_refcount.h"
#include "core/templates/set.h"
#include "scene/main/node.h"
class FileAccess;
@@ -127,7 +128,7 @@ class EditorFileSystem : public Node {
};
bool use_threads;
- Thread *thread;
+ Thread thread;
static void _thread_func(void *_userdata);
EditorFileSystemDirectory *new_filesystem;
@@ -189,7 +190,7 @@ class EditorFileSystem : public Node {
void _scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess *da, const ScanProgress &p_progress);
- Thread *thread_sources;
+ Thread thread_sources;
bool scanning_changes;
bool scanning_changes_done;
@@ -220,7 +221,7 @@ class EditorFileSystem : public Node {
};
void _scan_script_classes(EditorFileSystemDirectory *p_dir);
- volatile bool update_script_classes_queued;
+ SafeFlag update_script_classes_queued;
void _queue_update_script_classes();
String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const;
@@ -261,6 +262,8 @@ public:
bool is_group_file(const String &p_path) const;
void move_group_file(const String &p_path, const String &p_new_path);
+ static bool _should_skip_directory(const String &p_path);
+
EditorFileSystem();
~EditorFileSystem();
};
diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp
index a7e76e9b2b..97a2c67c26 100644
--- a/editor/editor_folding.cpp
+++ b/editor/editor_folding.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -259,13 +259,17 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) {
}
}
}
- }
- if (E->get().type == Variant::OBJECT) {
- RES res = p_object->get(E->get().name);
- if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
- resources.insert(res);
- _do_object_unfolds(res.ptr(), resources);
+ if (E->get().type == Variant::OBJECT) {
+ RES res = p_object->get(E->get().name);
+ print_line("res: " + String(E->get().name) + " valid " + itos(res.is_valid()));
+ if (res.is_valid()) {
+ print_line("path " + res->get_path());
+ }
+ if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
+ resources.insert(res);
+ _do_object_unfolds(res.ptr(), resources);
+ }
}
}
}
diff --git a/editor/editor_folding.h b/editor/editor_folding.h
index 13f07b99b0..90deb7c0e8 100644
--- a/editor/editor_folding.h
+++ b/editor/editor_folding.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 23dc69af12..96869ae6fd 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_fonts.h b/editor/editor_fonts.h
index 3ad7cf067b..59ee482b53 100644
--- a/editor/editor_fonts.h
+++ b/editor/editor_fonts.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 1592549e0c..283713cd3c 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -167,12 +167,12 @@ void EditorHelp::_class_desc_resized() {
void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
String t = p_type;
- if (t.empty()) {
+ if (t.is_empty()) {
t = "void";
}
- bool can_ref = (t != "void") || !p_enum.empty();
+ bool can_ref = (t != "void") || !p_enum.is_empty();
- if (!p_enum.empty()) {
+ if (!p_enum.is_empty()) {
if (p_enum.get_slice_count(".") > 1) {
t = p_enum.get_slice(".", 1);
} else {
@@ -188,7 +188,7 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
add_array = true;
t = t.replace("[]", "");
}
- if (p_enum.empty()) {
+ if (p_enum.is_empty()) {
class_desc->push_meta("#" + t); //class
} else {
class_desc->push_meta("$" + p_enum); //class
@@ -472,7 +472,7 @@ void EditorHelp::_update_doc() {
for (int i = 0; i < cd.tutorials.size(); i++) {
const String link = DTR(cd.tutorials[i].link);
- String linktxt = (cd.tutorials[i].title.empty()) ? link : DTR(cd.tutorials[i].title);
+ String linktxt = (cd.tutorials[i].title.is_empty()) ? link : DTR(cd.tutorials[i].title);
const int seppos = linktxt.find("//");
if (seppos != -1) {
linktxt = link.right(seppos + 2);
@@ -498,7 +498,7 @@ void EditorHelp::_update_doc() {
if (cd.is_script_doc) {
has_properties = false;
for (int i = 0; i < cd.properties.size(); i++) {
- if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.empty()) {
+ if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.is_empty()) {
continue;
}
has_properties = true;
@@ -522,7 +522,7 @@ void EditorHelp::_update_doc() {
for (int i = 0; i < cd.properties.size(); i++) {
// Ignore undocumented private.
- if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.empty()) {
+ if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.is_empty()) {
continue;
}
property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
@@ -633,7 +633,7 @@ void EditorHelp::_update_doc() {
}
}
// Ignore undocumented private.
- if (cd.methods[i].name.begins_with("_") && cd.methods[i].description.empty()) {
+ if (cd.methods[i].name.begins_with("_") && cd.methods[i].description.is_empty()) {
continue;
}
methods.push_back(cd.methods[i]);
@@ -668,7 +668,7 @@ void EditorHelp::_update_doc() {
}
}
- if (any_previous && !m.empty()) {
+ if (any_previous && !m.is_empty()) {
class_desc->push_cell();
class_desc->pop(); //cell
class_desc->push_cell();
@@ -702,7 +702,7 @@ void EditorHelp::_update_doc() {
_add_method(m[i], true);
}
- any_previous = !m.empty();
+ any_previous = !m.is_empty();
}
class_desc->pop(); //table
@@ -848,7 +848,7 @@ void EditorHelp::_update_doc() {
Vector<DocData::ConstantDoc> constants;
for (int i = 0; i < cd.constants.size(); i++) {
- if (!cd.constants[i].enumeration.empty()) {
+ if (!cd.constants[i].enumeration.is_empty()) {
if (!enums.has(cd.constants[i].enumeration)) {
enums[cd.constants[i].enumeration] = Vector<DocData::ConstantDoc>();
}
@@ -856,7 +856,7 @@ void EditorHelp::_update_doc() {
enums[cd.constants[i].enumeration].push_back(cd.constants[i]);
} else {
// Ignore undocumented private.
- if (cd.constants[i].name.begins_with("_") && cd.constants[i].description.empty()) {
+ if (cd.constants[i].name.begins_with("_") && cd.constants[i].description.is_empty()) {
continue;
}
constants.push_back(cd.constants[i]);
@@ -1174,7 +1174,7 @@ void EditorHelp::_update_doc() {
class_desc->push_color(text_color);
class_desc->push_font(doc_font);
class_desc->push_indent(1);
- if (!cd.properties[i].description.strip_edges().empty()) {
+ if (!cd.properties[i].description.strip_edges().is_empty()) {
_add_text(DTR(cd.properties[i].description));
} else {
class_desc->add_image(get_theme_icon("Error", "EditorIcons"));
@@ -1229,7 +1229,7 @@ void EditorHelp::_update_doc() {
class_desc->push_color(text_color);
class_desc->push_font(doc_font);
class_desc->push_indent(1);
- if (!methods_filtered[i].description.strip_edges().empty()) {
+ if (!methods_filtered[i].description.strip_edges().is_empty()) {
_add_text(DTR(methods_filtered[i].description));
} else {
class_desc->add_image(get_theme_icon("Error", "EditorIcons"));
@@ -1331,11 +1331,11 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
Ref<Font> doc_code_font = p_rt->get_theme_font("doc_source", "EditorFonts");
Ref<Font> doc_kbd_font = p_rt->get_theme_font("doc_keyboard", "EditorFonts");
- Color font_color_hl = p_rt->get_theme_color("headline_color", "EditorHelp");
+ Color headline_color = p_rt->get_theme_color("headline_color", "EditorHelp");
Color accent_color = p_rt->get_theme_color("accent_color", "Editor");
Color property_color = p_rt->get_theme_color("property_color", "Editor");
- Color link_color = accent_color.lerp(font_color_hl, 0.8);
- Color code_color = accent_color.lerp(font_color_hl, 0.6);
+ Color link_color = accent_color.lerp(headline_color, 0.8);
+ Color code_color = accent_color.lerp(headline_color, 0.6);
Color kbd_color = accent_color.lerp(property_color, 0.6);
String bbcode = p_bbcode.dedent().replace("\t", "").replace("\r", "").strip_edges();
@@ -1481,7 +1481,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
tag_stack.push_front(tag);
} else if (tag == "i") {
//use italics font
- p_rt->push_color(font_color_hl);
+ p_rt->push_color(headline_color);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "code" || tag == "codeblock") {
@@ -1549,46 +1549,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
tag_stack.push_front(tag);
} else if (tag.begins_with("color=")) {
String col = tag.substr(6, tag.length());
- Color color;
-
- if (col.begins_with("#")) {
- color = Color::html(col);
- } else if (col == "aqua") {
- color = Color(0, 1, 1);
- } else if (col == "black") {
- color = Color(0, 0, 0);
- } else if (col == "blue") {
- color = Color(0, 0, 1);
- } else if (col == "fuchsia") {
- color = Color(1, 0, 1);
- } else if (col == "gray" || col == "grey") {
- color = Color(0.5, 0.5, 0.5);
- } else if (col == "green") {
- color = Color(0, 0.5, 0);
- } else if (col == "lime") {
- color = Color(0, 1, 0);
- } else if (col == "maroon") {
- color = Color(0.5, 0, 0);
- } else if (col == "navy") {
- color = Color(0, 0, 0.5);
- } else if (col == "olive") {
- color = Color(0.5, 0.5, 0);
- } else if (col == "purple") {
- color = Color(0.5, 0, 0.5);
- } else if (col == "red") {
- color = Color(1, 0, 0);
- } else if (col == "silver") {
- color = Color(0.75, 0.75, 0.75);
- } else if (col == "teal") {
- color = Color(0, 0.5, 0.5);
- } else if (col == "white") {
- color = Color(1, 1, 1);
- } else if (col == "yellow") {
- color = Color(1, 1, 0);
- } else {
- color = Color(0, 0, 0); //base_color;
- }
-
+ Color color = Color::from_string(col, Color());
p_rt->push_color(color);
pos = brk_end + 1;
tag_stack.push_front("color");
@@ -1838,7 +1799,7 @@ void FindBar::popup_search() {
grabbed_focus = true;
}
- if (!search_text->get_text().empty()) {
+ if (!search_text->get_text().is_empty()) {
search_text->select_all();
search_text->set_cursor_position(search_text->get_text().length());
if (grabbed_focus) {
@@ -1908,7 +1869,7 @@ void FindBar::_update_results_count() {
results_count = 0;
String searched = search_text->get_text();
- if (searched.empty()) {
+ if (searched.is_empty()) {
return;
}
@@ -1928,7 +1889,7 @@ void FindBar::_update_results_count() {
}
void FindBar::_update_matches_label() {
- if (search_text->get_text().empty() || results_count == -1) {
+ if (search_text->get_text().is_empty() || results_count == -1) {
matches_label->hide();
} else {
matches_label->show();
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 737f841d30..65e20f060c 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index 5e784ba051..a1ff87fe2e 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_help_search.h b/editor/editor_help_search.h
index d94066308a..0e236d523d 100644
--- a/editor/editor_help_search.h
+++ b/editor/editor_help_search.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index a36b5f5a6a..74b874b54e 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -81,7 +81,7 @@ Size2 EditorProperty::get_minimum_size() const {
}
if (bottom_editor != nullptr && bottom_editor->is_visible()) {
- ms.height += get_theme_constant("vseparation", "Tree");
+ ms.height += get_theme_constant("vseparation");
Size2 bems = bottom_editor->get_combined_minimum_size();
//bems.width += get_constant("item_margin", "Tree");
ms.height += bems.height;
@@ -95,6 +95,7 @@ void EditorProperty::emit_changed(const StringName &p_property, const Variant &p
Variant args[4] = { p_property, p_value, p_field, p_changing };
const Variant *argptrs[4] = { &args[0], &args[1], &args[2], &args[3] };
+ cache[p_property] = p_value;
emit_signal("property_changed", (const Variant **)argptrs, 4);
}
@@ -148,7 +149,7 @@ void EditorProperty::_notification(int p_what) {
if (bottom_editor) {
int m = 0; //get_constant("item_margin", "Tree");
- bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation", "Tree"), size.width - m, bottom_editor->get_combined_minimum_size().height);
+ bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation"), size.width - m, bottom_editor->get_combined_minimum_size().height);
}
if (keying) {
@@ -225,11 +226,15 @@ void EditorProperty::_notification(int p_what) {
size.height = label_reference->get_size().height;
}
+ Ref<StyleBox> sb;
if (selected) {
- Ref<StyleBox> sb = get_theme_stylebox("selected", "Tree");
- draw_style_box(sb, Rect2(Vector2(), size));
+ sb = get_theme_stylebox("bg_selected");
+ } else {
+ sb = get_theme_stylebox("bg");
}
+ draw_style_box(sb, Rect2(Vector2(), size));
+
if (draw_top_bg && right_child_rect != Rect2()) {
draw_rect(right_child_rect, dark_color);
}
@@ -239,15 +244,15 @@ void EditorProperty::_notification(int p_what) {
Color color;
if (draw_red) {
- color = get_theme_color("error_color", "Editor");
+ color = get_theme_color("error_color");
} else {
- color = get_theme_color("property_color", "Editor");
+ color = get_theme_color("property_color");
}
if (label.find(".") != -1) {
color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides
}
- int ofs = 0;
+ int ofs = get_theme_constant("font_offset");
int text_limit = text_size;
if (checkable) {
@@ -805,6 +810,28 @@ void EditorProperty::set_bottom_editor(Control *p_control) {
bottom_editor = p_control;
}
+bool EditorProperty::is_cache_valid() const {
+ if (object) {
+ for (Map<StringName, Variant>::Element *E = cache.front(); E; E = E->next()) {
+ bool valid;
+ Variant value = object->get(E->key(), &valid);
+ if (!valid || value != E->get()) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+void EditorProperty::update_cache() {
+ cache.clear();
+ if (object && property != StringName()) {
+ bool valid;
+ Variant value = object->get(property, &valid);
+ if (valid) {
+ cache[property] = value;
+ }
+ }
+}
Variant EditorProperty::get_drag_data(const Point2 &p_point) {
if (property == StringName()) {
return Variant();
@@ -865,7 +892,7 @@ Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
String text;
PackedStringArray slices = p_text.split("::", false);
- if (!slices.empty()) {
+ if (!slices.is_empty()) {
String property_name = slices[0].strip_edges();
text = TTR("Property:") + " [u][b]" + property_name + "[/b][/u]";
@@ -1098,7 +1125,7 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons
help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE);
PackedStringArray slices = p_text.split("::", false);
- if (!slices.empty()) {
+ if (!slices.is_empty()) {
String property_name = slices[0].strip_edges();
String text = "[u][b]" + property_name + "[/b][/u]";
@@ -1524,6 +1551,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->update_property();
ep->update_reload_status();
ep->set_deletable(deletable_properties);
+ ep->update_cache();
}
}
ped->added_editors.clear();
@@ -1661,7 +1689,7 @@ void EditorInspector::update_tree() {
bool valid = true;
//if no properties in category, skip
while (N) {
- if (N->get().usage & PROPERTY_USAGE_EDITOR) {
+ if (N->get().usage & PROPERTY_USAGE_EDITOR && (!restrict_to_basic || (N->get().usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) {
break;
}
if (N->get().usage & PROPERTY_USAGE_CATEGORY) {
@@ -1729,10 +1757,14 @@ void EditorInspector::update_tree() {
continue;
- } else if (!(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name)) {
+ } else if (!(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name) || (restrict_to_basic && !(p.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) {
continue;
}
+ if (p.name == "script") {
+ category_vbox = nullptr; // script should go into its own category
+ }
+
if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && RS::get_singleton()->is_low_end()) {
continue; //do not show this property in low end gfx
}
@@ -1901,7 +1933,7 @@ void EditorInspector::update_tree() {
}
}
- if (!F->get().inherits.empty()) {
+ if (!F->get().inherits.is_empty()) {
F = dd->class_list.find(F->get().inherits);
} else {
break;
@@ -1982,6 +2014,7 @@ void EditorInspector::update_tree() {
}
ep->update_property();
ep->update_reload_status();
+ ep->update_cache();
if (current_selected && ep->property == current_selected) {
ep->select(current_focusable);
@@ -2012,6 +2045,7 @@ void EditorInspector::update_property(const String &p_prop) {
for (List<EditorProperty *>::Element *E = editor_property_map[p_prop].front(); E; E = E->next()) {
E->get()->update_property();
E->get()->update_reload_status();
+ E->get()->update_cache();
}
}
@@ -2027,13 +2061,6 @@ void EditorInspector::_clear() {
restart_request_props.clear();
}
-void EditorInspector::refresh() {
- if (refresh_countdown > 0 || changing) {
- return;
- }
- refresh_countdown = EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval");
-}
-
Object *EditorInspector::get_edited_object() {
return object;
}
@@ -2044,7 +2071,7 @@ void EditorInspector::edit(Object *p_object) {
}
if (object) {
_clear();
- object->remove_change_receptor(this);
+ object->disconnect("property_list_changed", callable_mp(this, &EditorInspector::_changed_callback));
}
object = p_object;
@@ -2054,7 +2081,7 @@ void EditorInspector::edit(Object *p_object) {
if (scroll_cache.has(object->get_instance_id())) { //if exists, set something else
update_scroll_request = scroll_cache[object->get_instance_id()]; //done this way because wait until full size is accommodated
}
- object->add_change_receptor(this);
+ object->connect("property_list_changed", callable_mp(this, &EditorInspector::_changed_callback));
update_tree();
}
}
@@ -2161,17 +2188,30 @@ void EditorInspector::set_use_wide_editors(bool p_enable) {
wide_editors = p_enable;
}
+void EditorInspector::_update_inspector_bg() {
+ if (sub_inspector) {
+ int count_subinspectors = 0;
+ Node *n = get_parent();
+ while (n) {
+ EditorInspector *ei = Object::cast_to<EditorInspector>(n);
+ if (ei && ei->sub_inspector) {
+ count_subinspectors++;
+ }
+ n = n->get_parent();
+ }
+ count_subinspectors = MIN(15, count_subinspectors);
+ add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), "Editor"));
+ } else {
+ add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
+ }
+}
void EditorInspector::set_sub_inspector(bool p_enable) {
sub_inspector = p_enable;
if (!is_inside_tree()) {
return;
}
- if (sub_inspector) {
- add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
- } else {
- add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
- }
+ _update_inspector_bg();
}
void EditorInspector::set_use_deletable_properties(bool p_enabled) {
@@ -2351,6 +2391,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) {
E->get()->update_property();
E->get()->update_reload_status();
+ E->get()->update_cache();
}
}
@@ -2394,13 +2435,12 @@ void EditorInspector::_node_removed(Node *p_node) {
void EditorInspector::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &EditorInspector::_feature_profile_changed));
+ set_process(is_visible_in_tree());
}
if (p_what == NOTIFICATION_ENTER_TREE) {
- if (sub_inspector) {
- add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
- } else {
- add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
+ _update_inspector_bg();
+ if (!sub_inspector) {
get_tree()->connect("node_removed", callable_mp(this, &EditorInspector::_node_removed));
}
}
@@ -2414,6 +2454,10 @@ void EditorInspector::_notification(int p_what) {
edit(nullptr);
}
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ set_process(is_visible_in_tree());
+ }
+
if (p_what == NOTIFICATION_PROCESS) {
if (update_scroll_request >= 0) {
get_v_scrollbar()->call_deferred("set_value", update_scroll_request);
@@ -2424,10 +2468,14 @@ void EditorInspector::_notification(int p_what) {
if (refresh_countdown <= 0) {
for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) {
for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) {
- E->get()->update_property();
- E->get()->update_reload_status();
+ if (!E->get()->is_cache_valid()) {
+ E->get()->update_property();
+ E->get()->update_reload_status();
+ E->get()->update_cache();
+ }
}
}
+ refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval"));
}
}
@@ -2445,6 +2493,7 @@ void EditorInspector::_notification(int p_what) {
for (List<EditorProperty *>::Element *E = editor_property_map[prop].front(); E; E = E->next()) {
E->get()->update_property();
E->get()->update_reload_status();
+ E->get()->update_cache();
}
}
pending.erase(pending.front());
@@ -2455,19 +2504,17 @@ void EditorInspector::_notification(int p_what) {
}
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- if (sub_inspector) {
- add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
- } else if (is_inside_tree()) {
- add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
- }
+ _update_inspector_bg();
update_tree();
}
}
-void EditorInspector::_changed_callback(Object *p_changed, const char *p_prop) {
- //this is called when property change is notified via _change_notify()
- _edit_request_change(p_changed, p_prop);
+void EditorInspector::_changed_callback() {
+ //this is called when property change is notified via notify_property_list_changed()
+ if (object != nullptr) {
+ _edit_request_change(object, String());
+ }
}
void EditorInspector::_vscroll_changed(double p_offset) {
@@ -2506,26 +2553,15 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li
return;
}
- List<StringName> classes;
- Map<StringName, String> paths;
+ List<Ref<Script>> classes;
// NodeC -> NodeB -> NodeA
while (script.is_valid()) {
- String n = EditorNode::get_editor_data().script_class_get_name(script->get_path());
- if (n.length()) {
- classes.push_front(n);
- } else if (script->get_path() != String() && script->get_path().find("::") == -1) {
- n = script->get_path().get_file();
- classes.push_front(n);
- } else {
- n = TTR("Built-in script");
- classes.push_front(n);
- }
- paths[n] = script->get_path();
+ classes.push_front(script);
script = script->get_base_script();
}
- if (classes.empty()) {
+ if (classes.is_empty()) {
return;
}
@@ -2545,17 +2581,18 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li
}
Set<StringName> added;
- for (List<StringName>::Element *E = classes.front(); E; E = E->next()) {
- StringName name = E->get();
- String path = paths[name];
- Ref<Script> s;
- if (path == String()) {
- // Built-in script. It can't be inherited, so must be the script attached to the object.
- s = p_object.get_script();
- } else {
- s = ResourceLoader::load(path, "Script");
+ for (List<Ref<Script>>::Element *E = classes.front(); E; E = E->next()) {
+ Ref<Script> s = E->get();
+ String path = s->get_path();
+ String name = EditorNode::get_editor_data().script_class_get_name(path);
+ if (name.is_empty()) {
+ if (!path.is_empty() && path.find("::") == -1) {
+ name = path.get_file();
+ } else {
+ name = TTR("Built-in script");
+ }
}
- ERR_FAIL_COND(!s->is_valid());
+
List<PropertyInfo> props;
s->get_script_property_list(&props);
@@ -2587,11 +2624,14 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li
r_list.erase(bottom);
}
+void EditorInspector::set_restrict_to_basic_settings(bool p_restrict) {
+ restrict_to_basic = p_restrict;
+ update_tree();
+}
+
void EditorInspector::_bind_methods() {
ClassDB::bind_method("_edit_request_change", &EditorInspector::_edit_request_change);
- ClassDB::bind_method("refresh", &EditorInspector::refresh);
-
ADD_SIGNAL(MethodInfo("property_selected", PropertyInfo(Variant::STRING, "property")));
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property")));
ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING, "property")));
@@ -2623,16 +2663,21 @@ EditorInspector::EditorInspector() {
use_folding = false;
update_all_pending = false;
update_tree_pending = false;
- refresh_countdown = 0;
read_only = false;
search_box = nullptr;
keying = false;
_prop_edited = "property_edited";
- set_process(true);
+ set_process(false);
property_focusable = -1;
sub_inspector = false;
deletable_properties = false;
get_v_scrollbar()->connect("value_changed", callable_mp(this, &EditorInspector::_vscroll_changed));
update_scroll_request = -1;
+ if (EditorSettings::get_singleton()) {
+ refresh_countdown = float(EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval"));
+ } else {
+ //used when class is created by the docgen to dump default values of everything bindable, editorsettings may not be created
+ refresh_countdown = 0.33;
+ }
}
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index d901bb4ecf..18250780be 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -98,6 +98,8 @@ private:
mutable String tooltip_text;
+ Map<StringName, Variant> cache;
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -152,6 +154,8 @@ public:
virtual void collapse_all_folding();
virtual Variant get_drag_data(const Point2 &p_point) override;
+ virtual void update_cache();
+ virtual bool is_cache_valid() const;
void set_selectable(bool p_selectable);
bool is_selectable() const;
@@ -309,6 +313,8 @@ class EditorInspector : public ScrollContainer {
String property_prefix; //used for sectioned inspector
String object_class;
+ bool restrict_to_basic = false;
+
void _edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all, const String &p_changed_field);
void _property_changed(const String &p_path, const Variant &p_value, const String &p_name = "", bool p_changing = false);
@@ -326,7 +332,7 @@ class EditorInspector : public ScrollContainer {
void _node_removed(Node *p_node);
- void _changed_callback(Object *p_changed, const char *p_prop) override;
+ void _changed_callback();
void _edit_request_change(Object *p_object, const String &p_prop);
void _filter_changed(const String &p_text);
@@ -339,6 +345,8 @@ class EditorInspector : public ScrollContainer {
bool _is_property_disabled_by_feature_profile(const StringName &p_property);
+ void _update_inspector_bg();
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -356,9 +364,6 @@ public:
void update_tree();
void update_property(const String &p_prop);
-
- void refresh();
-
void edit(Object *p_object);
Object *get_edited_object();
@@ -393,9 +398,12 @@ public:
void set_use_wide_editors(bool p_enable);
void set_sub_inspector(bool p_enable);
+ bool is_sub_inspector() const { return sub_inspector; }
void set_use_deletable_properties(bool p_enabled);
+ void set_restrict_to_basic_settings(bool p_restrict);
+
EditorInspector();
};
diff --git a/editor/editor_layouts_dialog.cpp b/editor/editor_layouts_dialog.cpp
index 74f45fa628..0bf1863459 100644
--- a/editor/editor_layouts_dialog.cpp
+++ b/editor/editor_layouts_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -119,7 +119,7 @@ EditorLayoutsDialog::EditorLayoutsDialog() {
name->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 5);
name->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -5);
name->connect("gui_input", callable_mp(this, &EditorLayoutsDialog::_line_gui_input));
- name->connect("focus_entered", callable_mp(layout_names, &ItemList::unselect_all));
+ name->connect("focus_entered", callable_mp(layout_names, &ItemList::deselect_all));
}
void EditorLayoutsDialog::set_name_line_enabled(bool p_enabled) {
diff --git a/editor/editor_layouts_dialog.h b/editor/editor_layouts_dialog.h
index ebb523829f..8687660832 100644
--- a/editor/editor_layouts_dialog.h
+++ b/editor/editor_layouts_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 371cabfe3d..7b94016fb6 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -101,8 +101,6 @@ void EditorLog::copy() {
}
void EditorLog::add_message(const String &p_msg, MessageType p_type) {
- log->add_newline();
-
bool restore = p_type != MSG_TYPE_STD;
switch (p_type) {
case MSG_TYPE_STD: {
@@ -128,6 +126,7 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) {
}
log->add_text(p_msg);
+ log->add_newline();
if (restore) {
log->pop();
@@ -180,7 +179,7 @@ EditorLog::EditorLog() {
log->set_v_size_flags(SIZE_EXPAND_FILL);
log->set_h_size_flags(SIZE_EXPAND_FILL);
vb->add_child(log);
- add_message(VERSION_FULL_NAME " (c) 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors.");
+ add_message(VERSION_FULL_NAME " (c) 2007-2021 Juan Linietsky, Ariel Manzur & Godot Contributors.");
eh.errfunc = _error_handler;
eh.userdata = this;
diff --git a/editor/editor_log.h b/editor/editor_log.h
index 73a8c3f0c5..79dfb3ffaa 100644
--- a/editor/editor_log.h
+++ b/editor/editor_log.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/arkit/arkit_session_delegate.mm b/editor/editor_native_shader_source_visualizer.cpp
index f44f46b7b7..ed2692190c 100644
--- a/modules/arkit/arkit_session_delegate.mm
+++ b/editor/editor_native_shader_source_visualizer.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* arkit_session_delegate.mm */
+/* editor_native_shader_source_visualizer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,29 +28,45 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "arkit_session_delegate.h"
-#include "arkit_interface.h"
+#include "editor_native_shader_source_visualizer.h"
-@implementation ARKitSessionDelegate
+#include "scene/gui/text_edit.h"
-@synthesize arkit_interface;
-
-- (void)session:(ARSession *)session didAddAnchors:(NSArray<ARAnchor *> *)anchors {
- for (ARAnchor *anchor in anchors) {
- arkit_interface->_add_or_update_anchor(anchor);
+void EditorNativeShaderSourceVisualizer::_inspect_shader(RID p_shader) {
+ if (versions) {
+ memdelete(versions);
+ versions = nullptr;
}
-}
-- (void)session:(ARSession *)session didRemoveAnchors:(NSArray<ARAnchor *> *)anchors {
- for (ARAnchor *anchor in anchors) {
- arkit_interface->_remove_anchor(anchor);
- }
-}
+ RS::ShaderNativeSourceCode nsc = RS::get_singleton()->shader_get_native_source_code(p_shader);
-- (void)session:(ARSession *)session didUpdateAnchors:(NSArray<ARAnchor *> *)anchors {
- for (ARAnchor *anchor in anchors) {
- arkit_interface->_add_or_update_anchor(anchor);
+ versions = memnew(TabContainer);
+ versions->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ versions->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ for (int i = 0; i < nsc.versions.size(); i++) {
+ TabContainer *vtab = memnew(TabContainer);
+ vtab->set_name("Version " + itos(i));
+ vtab->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ vtab->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ versions->add_child(vtab);
+ for (int j = 0; j < nsc.versions[i].stages.size(); j++) {
+ TextEdit *vtext = memnew(TextEdit);
+ vtext->set_readonly(true);
+ vtext->set_name(nsc.versions[i].stages[j].name);
+ vtext->set_text(nsc.versions[i].stages[j].code);
+ vtext->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ vtext->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ vtab->add_child(vtext);
+ }
}
+ add_child(versions);
+ popup_centered_ratio();
}
-@end
+void EditorNativeShaderSourceVisualizer::_bind_methods() {
+ ClassDB::bind_method("_inspect_shader", &EditorNativeShaderSourceVisualizer::_inspect_shader);
+}
+EditorNativeShaderSourceVisualizer::EditorNativeShaderSourceVisualizer() {
+ add_to_group("_native_shader_source_visualizer");
+ set_title(TTR("Native Shader Source Inspector"));
+}
diff --git a/modules/icloud/icloud.h b/editor/editor_native_shader_source_visualizer.h
index 35eede0bf9..72a2f8baae 100644
--- a/modules/icloud/icloud.h
+++ b/editor/editor_native_shader_source_visualizer.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* icloud.h */
+/* editor_native_shader_source_visualizer.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,33 +28,23 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ICLOUD_H
-#define ICLOUD_H
+#ifndef EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H
+#define EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H
-#include "core/object/class_db.h"
+#include "scene/gui/dialogs.h"
+#include "scene/gui/tab_container.h"
-class ICloud : public Object {
- GDCLASS(ICloud, Object);
+class EditorNativeShaderSourceVisualizer : public AcceptDialog {
+ GDCLASS(EditorNativeShaderSourceVisualizer, AcceptDialog)
+ TabContainer *versions = nullptr;
- static ICloud *instance;
- static void _bind_methods();
+ void _inspect_shader(RID p_shader);
- List<Variant> pending_events;
+protected:
+ static void _bind_methods();
public:
- Error remove_key(String p_param);
- Array set_key_values(Dictionary p_params);
- Variant get_key_value(String p_param);
- Error synchronize_key_values();
- Variant get_all_key_values();
-
- int get_pending_event_count();
- Variant pop_pending_event();
-
- static ICloud *get_singleton();
-
- ICloud();
- ~ICloud();
+ EditorNativeShaderSourceVisualizer();
};
-#endif
+#endif // EDITOR_NATIVE_SHADER_SOURCE_VISUALIZER_H
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ca8b278ab8..f0e53e7ef5 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -377,9 +377,9 @@ void EditorNode::_version_control_menu_option(int p_idx) {
void EditorNode::_update_title() {
String appname = ProjectSettings::get_singleton()->get("application/config/name");
- String title = appname.empty() ? String(VERSION_FULL_NAME) : String(VERSION_NAME + String(" - ") + appname);
+ String title = appname.is_empty() ? String(VERSION_FULL_NAME) : String(VERSION_NAME + String(" - ") + appname);
String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String();
- if (!edited.empty()) {
+ if (!edited.is_empty()) {
title += " - " + String(edited.get_file());
}
if (unsaved_cache) {
@@ -430,6 +430,74 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
}
}
+void EditorNode::_update_from_settings() {
+ int current_filter = GLOBAL_GET("rendering/textures/canvas_textures/default_texture_filter");
+ if (current_filter != scene_root->get_default_canvas_item_texture_filter()) {
+ Viewport::DefaultCanvasItemTextureFilter tf = (Viewport::DefaultCanvasItemTextureFilter)current_filter;
+ scene_root->set_default_canvas_item_texture_filter(tf);
+ }
+ int current_repeat = GLOBAL_GET("rendering/textures/canvas_textures/default_texture_repeat");
+ if (current_repeat != scene_root->get_default_canvas_item_texture_repeat()) {
+ Viewport::DefaultCanvasItemTextureRepeat tr = (Viewport::DefaultCanvasItemTextureRepeat)current_repeat;
+ scene_root->set_default_canvas_item_texture_repeat(tr);
+ }
+
+ RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_shape")));
+ RS::get_singleton()->camera_effects_set_dof_blur_bokeh_shape(dof_shape);
+ RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_quality")));
+ bool dof_jitter = GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_use_jitter");
+ RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter);
+ RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/environment/ssao/quality"))), GLOBAL_GET("rendering/environment/ssao/half_size"), GLOBAL_GET("rendering/environment/ssao/adaptive_target"), GLOBAL_GET("rendering/environment/ssao/blur_passes"), GLOBAL_GET("rendering/environment/ssao/fadeout_from"), GLOBAL_GET("rendering/environment/ssao/fadeout_to"));
+ RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/enabled"), GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/amount"), GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/limit"));
+ bool glow_bicubic = int(GLOBAL_GET("rendering/environment/glow/upscale_mode")) > 0;
+ RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic);
+ bool glow_high_quality = GLOBAL_GET("rendering/environment/glow/use_high_quality");
+ RS::get_singleton()->environment_glow_set_use_high_quality(glow_high_quality);
+ RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/environment/screen_space_reflection/roughness_quality")));
+ RS::get_singleton()->environment_set_ssr_roughness_quality(ssr_roughness_quality);
+ RS::SubSurfaceScatteringQuality sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_quality")));
+ RS::get_singleton()->sub_surface_scattering_set_quality(sss_quality);
+ float sss_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_scale");
+ float sss_depth_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale");
+ RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale);
+
+ uint32_t directional_shadow_size = GLOBAL_GET("rendering/shadows/directional_shadow/size");
+ uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/shadows/directional_shadow/16_bits");
+ RS::get_singleton()->directional_shadow_atlas_set_size(directional_shadow_size, directional_shadow_16_bits);
+
+ RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/shadows/soft_shadow_quality")));
+ RS::get_singleton()->shadows_quality_set(shadows_quality);
+ RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_quality")));
+ RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality);
+ float probe_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed");
+ RS::get_singleton()->lightmap_set_probe_capture_update_speed(probe_update_speed);
+ RS::EnvironmentSDFGIFramesToConverge frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(int(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge")));
+ RS::get_singleton()->environment_set_sdfgi_frames_to_converge(frames_to_converge);
+ RS::EnvironmentSDFGIRayCount ray_count = RS::EnvironmentSDFGIRayCount(int(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count")));
+ RS::get_singleton()->environment_set_sdfgi_ray_count(ray_count);
+ RS::GIProbeQuality gi_probe_quality = RS::GIProbeQuality(int(GLOBAL_GET("rendering/global_illumination/gi_probes/quality")));
+ RS::get_singleton()->gi_probe_set_quality(gi_probe_quality);
+ RS::get_singleton()->environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/environment/volumetric_fog/volume_size"), GLOBAL_GET("rendering/environment/volumetric_fog/volume_depth"));
+ RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter")));
+ RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/2d/shadow_atlas/size"));
+
+ bool use_half_res_gi = GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false);
+ RS::get_singleton()->gi_set_use_half_resolution(use_half_res_gi);
+
+ bool snap_2d_transforms = GLOBAL_GET("rendering/2d/snap/snap_2d_transforms_to_pixel");
+ scene_root->set_snap_2d_transforms_to_pixel(snap_2d_transforms);
+ bool snap_2d_vertices = GLOBAL_GET("rendering/2d/snap/snap_2d_vertices_to_pixel");
+ scene_root->set_snap_2d_vertices_to_pixel(snap_2d_vertices);
+
+ Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_GET("rendering/2d/sdf/oversize")));
+ scene_root->set_sdf_oversize(sdf_oversize);
+ Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_GET("rendering/2d/sdf/scale")));
+ scene_root->set_sdf_scale(sdf_scale);
+
+ float lod_threshold = GLOBAL_GET("rendering/mesh_lod/lod_change/threshold_pixels");
+ scene_root->set_lod_threshold(lod_threshold);
+}
+
void EditorNode::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_PROCESS: {
@@ -468,69 +536,13 @@ void EditorNode::_notification(int p_what) {
editor_selection->update();
- { //TODO should only happen on settings changed
- int current_filter = GLOBAL_GET("rendering/canvas_textures/default_texture_filter");
- if (current_filter != scene_root->get_default_canvas_item_texture_filter()) {
- Viewport::DefaultCanvasItemTextureFilter tf = (Viewport::DefaultCanvasItemTextureFilter)current_filter;
- scene_root->set_default_canvas_item_texture_filter(tf);
- }
- int current_repeat = GLOBAL_GET("rendering/canvas_textures/default_texture_repeat");
- if (current_repeat != scene_root->get_default_canvas_item_texture_repeat()) {
- Viewport::DefaultCanvasItemTextureRepeat tr = (Viewport::DefaultCanvasItemTextureRepeat)current_repeat;
- scene_root->set_default_canvas_item_texture_repeat(tr);
- }
+ ResourceImporterTexture::get_singleton()->update_imports();
- RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape")));
- RS::get_singleton()->camera_effects_set_dof_blur_bokeh_shape(dof_shape);
- RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality")));
- bool dof_jitter = GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter");
- RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter);
- RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"), GLOBAL_GET("rendering/quality/ssao/adaptive_target"), GLOBAL_GET("rendering/quality/ssao/blur_passes"), GLOBAL_GET("rendering/quality/ssao/fadeout_from"), GLOBAL_GET("rendering/quality/ssao/fadeout_to"));
- RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit"));
- bool glow_bicubic = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0;
- RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic);
- bool glow_high_quality = GLOBAL_GET("rendering/quality/glow/use_high_quality");
- RS::get_singleton()->environment_glow_set_use_high_quality(glow_high_quality);
- RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality")));
- RS::get_singleton()->environment_set_ssr_roughness_quality(ssr_roughness_quality);
- RS::SubSurfaceScatteringQuality sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality")));
- RS::get_singleton()->sub_surface_scattering_set_quality(sss_quality);
- float sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale");
- float sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale");
- RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale);
- RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality")));
- RS::get_singleton()->shadows_quality_set(shadows_quality);
- RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality")));
- RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality);
- float probe_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed");
- RS::get_singleton()->lightmap_set_probe_capture_update_speed(probe_update_speed);
- RS::EnvironmentSDFGIFramesToConverge frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(int(GLOBAL_GET("rendering/sdfgi/frames_to_converge")));
- RS::get_singleton()->environment_set_sdfgi_frames_to_converge(frames_to_converge);
- RS::EnvironmentSDFGIRayCount ray_count = RS::EnvironmentSDFGIRayCount(int(GLOBAL_GET("rendering/sdfgi/probe_ray_count")));
- RS::get_singleton()->environment_set_sdfgi_ray_count(ray_count);
- RS::GIProbeQuality gi_probe_quality = RS::GIProbeQuality(int(GLOBAL_GET("rendering/quality/gi_probes/quality")));
- RS::get_singleton()->gi_probe_set_quality(gi_probe_quality);
- RS::get_singleton()->environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth"));
- RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/volumetric_fog/use_filter")));
- RS::get_singleton()->environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink"));
- RS::get_singleton()->environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
- RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/quality/2d_shadow_atlas/size"));
-
- bool snap_2d_transforms = GLOBAL_GET("rendering/quality/2d/snap_2d_transforms_to_pixel");
- scene_root->set_snap_2d_transforms_to_pixel(snap_2d_transforms);
- bool snap_2d_vertices = GLOBAL_GET("rendering/quality/2d/snap_2d_vertices_to_pixel");
- scene_root->set_snap_2d_vertices_to_pixel(snap_2d_vertices);
-
- Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_GET("rendering/quality/2d_sdf/oversize")));
- scene_root->set_sdf_oversize(sdf_oversize);
- Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_GET("rendering/quality/2d_sdf/scale")));
- scene_root->set_sdf_scale(sdf_scale);
-
- float lod_threshold = GLOBAL_GET("rendering/quality/mesh_lod/threshold_pixels");
- scene_root->set_lod_threshold(lod_threshold);
+ if (settings_changed) {
+ _update_from_settings();
+ settings_changed = false;
+ emit_signal("project_settings_changed");
}
-
- ResourceImporterTexture::get_singleton()->update_imports();
} break;
case NOTIFICATION_ENTER_TREE: {
@@ -588,6 +600,7 @@ void EditorNode::_notification(int p_what) {
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec")));
EditorFileSystem::get_singleton()->scan_changes();
+ _scan_external_changes();
} break;
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
@@ -613,8 +626,8 @@ void EditorNode::_notification(int p_what) {
gui_base->add_theme_style_override("panel", gui_base->get_theme_stylebox("Background", "EditorStyles"));
scene_root_parent->add_theme_style_override("panel", gui_base->get_theme_stylebox("Content", "EditorStyles"));
bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox("panel", "TabContainer"));
- scene_tabs->add_theme_style_override("tab_fg", gui_base->get_theme_stylebox("SceneTabFG", "EditorStyles"));
- scene_tabs->add_theme_style_override("tab_bg", gui_base->get_theme_stylebox("SceneTabBG", "EditorStyles"));
+ scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox("SceneTabFG", "EditorStyles"));
+ scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox("SceneTabBG", "EditorStyles"));
file_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox("MenuHover", "EditorStyles"));
project_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox("MenuHover", "EditorStyles"));
@@ -782,8 +795,8 @@ void EditorNode::_fs_changed() {
preset_name);
} else {
Ref<EditorExportPlatform> platform = preset->get_platform();
- const String export_path = export_defer.path.empty() ? preset->get_export_path() : export_defer.path;
- if (export_path.empty()) {
+ const String export_path = export_defer.path.is_empty() ? preset->get_export_path() : export_defer.path;
+ if (export_path.is_empty()) {
export_error = vformat("Export preset '%s' doesn't have a default export path, and none was specified.", preset_name);
} else if (platform.is_null()) {
export_error = vformat("Export preset '%s' doesn't have a matching platform.", preset_name);
@@ -821,7 +834,7 @@ void EditorNode::_fs_changed() {
}
}
- if (!export_error.empty()) {
+ if (!export_error.is_empty()) {
ERR_PRINT(export_error);
OS::get_singleton()->set_exit_code(EXIT_FAILURE);
}
@@ -880,6 +893,83 @@ void EditorNode::_sources_changed(bool p_exist) {
}
}
+void EditorNode::_scan_external_changes() {
+ disk_changed_list->clear();
+ TreeItem *r = disk_changed_list->create_item();
+ disk_changed_list->set_hide_root(true);
+ bool need_reload = false;
+
+ // Check if any edited scene has changed.
+
+ for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (editor_data.get_scene_path(i) == "" || !da->file_exists(editor_data.get_scene_path(i))) {
+ continue;
+ }
+
+ uint64_t last_date = editor_data.get_scene_modified_time(i);
+ uint64_t date = FileAccess::get_modified_time(editor_data.get_scene_path(i));
+
+ if (date > last_date) {
+ TreeItem *ti = disk_changed_list->create_item(r);
+ ti->set_text(0, editor_data.get_scene_path(i).get_file());
+ need_reload = true;
+ }
+ }
+
+ String project_settings_path = ProjectSettings::get_singleton()->get_resource_path().plus_file("project.godot");
+ if (FileAccess::get_modified_time(project_settings_path) > ProjectSettings::get_singleton()->get_last_saved_time()) {
+ TreeItem *ti = disk_changed_list->create_item(r);
+ ti->set_text(0, "project.godot");
+ need_reload = true;
+ }
+
+ if (need_reload) {
+ disk_changed->call_deferred("popup_centered_ratio", 0.5);
+ }
+}
+
+void EditorNode::_resave_scenes(String p_str) {
+ save_all_scenes();
+ ProjectSettings::get_singleton()->save();
+ disk_changed->hide();
+}
+
+void EditorNode::_reload_modified_scenes() {
+ int current_idx = editor_data.get_edited_scene();
+
+ for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
+ if (editor_data.get_scene_path(i) == "") {
+ continue;
+ }
+
+ uint64_t last_date = editor_data.get_scene_modified_time(i);
+ uint64_t date = FileAccess::get_modified_time(editor_data.get_scene_path(i));
+
+ if (date > last_date) {
+ String filename = editor_data.get_scene_path(i);
+ editor_data.set_edited_scene(i);
+ _remove_edited_scene(false);
+
+ Error err = load_scene(filename, false, false, true, false, true);
+ if (err != OK) {
+ ERR_PRINT(vformat("Failed to load scene: %s", filename));
+ }
+ editor_data.move_edited_scene_to_index(i);
+ }
+ }
+
+ get_undo_redo()->clear_history(false);
+ set_current_scene(current_idx);
+ _update_scene_tabs();
+ disk_changed->hide();
+}
+
+void EditorNode::_reload_project_settings() {
+ ProjectSettings::get_singleton()->setup(ProjectSettings::get_singleton()->get_resource_path(), String(), true);
+ settings_changed = true;
+}
+
void EditorNode::_vp_resized() {
}
@@ -921,7 +1011,7 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d
dependency_errors.clear();
Error err;
- RES res = ResourceLoader::load(p_resource, "", false, &err);
+ RES res = ResourceLoader::load(p_resource, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
ERR_FAIL_COND_V(!res.is_valid(), ERR_CANT_OPEN);
if (!p_ignore_broken_deps && dependency_errors.has(p_resource)) {
@@ -1505,6 +1595,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
} else {
editor_data.set_edited_scene_version(0, idx);
}
+ editor_data.set_scene_modified_time(idx, FileAccess::get_modified_time(p_file));
editor_folding.save_scene_folding(scene, p_file);
@@ -1708,10 +1799,10 @@ void EditorNode::_dialog_action(String p_file) {
ObjectID current = editor_history.get_current();
Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
ERR_FAIL_COND(!current_obj);
- current_obj->_change_notify();
+ current_obj->notify_property_list_changed();
} break;
case SETTINGS_LAYOUT_SAVE: {
- if (p_file.empty()) {
+ if (p_file.is_empty()) {
return;
}
@@ -1739,7 +1830,7 @@ void EditorNode::_dialog_action(String p_file) {
} break;
case SETTINGS_LAYOUT_DELETE: {
- if (p_file.empty()) {
+ if (p_file.is_empty()) {
return;
}
@@ -1822,7 +1913,7 @@ void EditorNode::edit_item(Object *p_object) {
sub_plugins = editor_data.get_subeditors(p_object);
}
- if (!sub_plugins.empty()) {
+ if (!sub_plugins.is_empty()) {
bool same = true;
if (sub_plugins.size() == editor_plugins_over->get_plugins_list().size()) {
for (int i = 0; i < sub_plugins.size(); i++) {
@@ -1850,6 +1941,7 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in
node_dock->set_node(nullptr);
scene_tree_dock->set_selected(nullptr);
inspector_dock->update(nullptr);
+ _display_top_editors(false);
return;
}
@@ -1998,7 +2090,7 @@ void EditorNode::_edit_current() {
multi_nodes.push_back(node);
}
}
- if (!multi_nodes.empty()) {
+ if (!multi_nodes.is_empty()) {
// Pick the top-most node
multi_nodes.sort_custom<Node::Comparator>();
selected_node = multi_nodes.front()->get();
@@ -2080,13 +2172,13 @@ void EditorNode::_edit_current() {
sub_plugins = editor_data.get_subeditors(current_obj);
}
- if (!sub_plugins.empty()) {
+ if (!sub_plugins.is_empty()) {
_display_top_editors(false);
_set_top_editors(sub_plugins);
_set_editing_top_editors(current_obj);
_display_top_editors(true);
- } else if (!editor_plugins_over->get_plugins_list().empty()) {
+ } else if (!editor_plugins_over->get_plugins_list().is_empty()) {
hide_top_editors();
}
}
@@ -2123,7 +2215,10 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
if (scene->get_filename() == "") {
current_option = -1;
- _menu_option_confirm(FILE_SAVE_BEFORE_RUN, false);
+ _menu_option(FILE_SAVE_AS_SCENE);
+ // Set the option to save and run so when the dialog is accepted, the scene runs.
+ current_option = FILE_SAVE_AND_RUN;
+ file->set_title(TTR("Save scene before running..."));
return;
}
@@ -2166,7 +2261,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
List<String> breakpoints;
editor_data.get_editor_breakpoints(&breakpoints);
- args = ProjectSettings::get_singleton()->get("editor/main_run_args");
+ args = ProjectSettings::get_singleton()->get("editor/run/main_run_args");
skip_breakpoints = EditorDebuggerNode::get_singleton()->is_skip_breakpoints();
EditorDebuggerNode::get_singleton()->start();
@@ -2256,7 +2351,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_OPEN_PREV: {
- if (previous_scenes.empty()) {
+ if (previous_scenes.is_empty()) {
break;
}
opening_prev = true;
@@ -2289,6 +2384,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case FILE_CLOSE: {
if (!p_confirmed) {
tab_closing = p_option == FILE_CLOSE ? editor_data.get_edited_scene() : _next_unsaved_scene(false);
+ _scene_tab_changed(tab_closing);
if (unsaved_cache || p_option == FILE_CLOSE_ALL_AND_QUIT || p_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER) {
String scene_filename = editor_data.get_edited_scene_root(tab_closing)->get_filename();
@@ -2358,11 +2454,12 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
if (scene->get_filename() != "") {
- file->set_current_path(scene->get_filename());
+ String path = scene->get_filename();
+ file->set_current_path(path);
if (extensions.size()) {
- String ext = scene->get_filename().get_extension().to_lower();
+ String ext = path.get_extension().to_lower();
if (extensions.find(ext) == nullptr) {
- file->set_current_path(scene->get_filename().replacen("." + ext, "." + extensions.front()->get()));
+ file->set_current_path(path.replacen("." + ext, "." + extensions.front()->get()));
}
}
} else {
@@ -2381,18 +2478,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case FILE_SAVE_ALL_SCENES: {
_save_all_scenes();
} break;
- case FILE_SAVE_BEFORE_RUN: {
- if (!p_confirmed) {
- confirmation->get_cancel_button()->set_text(TTR("No"));
- confirmation->get_ok_button()->set_text(TTR("Yes"));
- confirmation->set_text(TTR("This scene has never been saved. Save before running?"));
- confirmation->popup_centered();
- break;
- }
-
- _menu_option(FILE_SAVE_AS_SCENE);
- _menu_option_confirm(FILE_SAVE_AND_RUN, false);
- } break;
case FILE_EXPORT_PROJECT: {
project_export->popup_export();
@@ -2436,16 +2521,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
- case FILE_IMPORT_SUBSCENE: {
- if (!editor_data.get_edited_scene_root()) {
- show_accept(TTR("This operation can't be done without a selected node."), TTR("OK"));
- break;
- }
-
- scene_tree_dock->import_subscene();
-
- } break;
-
case FILE_EXTERNAL_OPEN_SCENE: {
if (unsaved_cache && !p_confirmed) {
confirmation->get_ok_button()->set_text(TTR("Open"));
@@ -2527,7 +2602,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case RUN_PLAY_CUSTOM_SCENE: {
- if (run_custom_filename.empty() || editor_run.get_status() == EditorRun::STATUS_STOP) {
+ if (run_custom_filename.is_empty() || editor_run.get_status() == EditorRun::STATUS_STOP) {
_menu_option_confirm(RUN_STOP, true);
quick_run->popup_dialog("PackedScene", true);
quick_run->set_title(TTR("Quick Run Scene..."));
@@ -2606,15 +2681,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if (!p_confirmed) {
bool save_each = EDITOR_GET("interface/editor/save_each_scene_on_quit");
if (_next_unsaved_scene(!save_each) == -1) {
- bool confirm = EDITOR_GET("interface/editor/quit_confirmation");
- if (confirm) {
- confirmation->get_ok_button()->set_text(p_option == FILE_QUIT ? TTR("Quit") : TTR("Yes"));
- confirmation->set_text(p_option == FILE_QUIT ? TTR("Exit the editor?") : TTR("Open Project Manager?"));
- confirmation->popup_centered();
- } else {
- _discard_changes();
- break;
- }
+ _discard_changes();
+ break;
} else {
if (save_each) {
_menu_option_confirm(p_option == FILE_QUIT ? FILE_CLOSE_ALL_AND_QUIT : FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER, false);
@@ -2722,7 +2790,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case SET_VIDEO_DRIVER_SAVE_AND_RESTART: {
- ProjectSettings::get_singleton()->set("rendering/quality/driver/driver_name", video_driver_request);
+ ProjectSettings::get_singleton()->set("rendering/driver/driver_name", video_driver_request);
ProjectSettings::get_singleton()->save();
save_all_scenes();
@@ -2745,14 +2813,14 @@ void EditorNode::_screenshot(bool p_use_utc) {
}
void EditorNode::_save_screenshot(NodePath p_path) {
- Control *editor_viewport = EditorInterface::get_singleton()->get_editor_viewport();
- ERR_FAIL_COND_MSG(!editor_viewport, "Cannot get editor viewport.");
- Viewport *viewport = editor_viewport->get_viewport();
- ERR_FAIL_COND_MSG(!viewport, "Cannot get editor viewport.");
+ Control *editor_main_control = EditorInterface::get_singleton()->get_editor_main_control();
+ ERR_FAIL_COND_MSG(!editor_main_control, "Cannot get editor main control.");
+ Viewport *viewport = editor_main_control->get_viewport();
+ ERR_FAIL_COND_MSG(!viewport, "Cannot get editor main control viewport.");
Ref<ViewportTexture> texture = viewport->get_texture();
- ERR_FAIL_COND_MSG(texture.is_null(), "Cannot get editor viewport texture.");
+ ERR_FAIL_COND_MSG(texture.is_null(), "Cannot get editor main control viewport texture.");
Ref<Image> img = texture->get_data();
- ERR_FAIL_COND_MSG(img.is_null(), "Cannot get editor viewport texture image.");
+ ERR_FAIL_COND_MSG(img.is_null(), "Cannot get editor main control viewport texture image.");
Error error = img->save_png(p_path);
ERR_FAIL_COND_MSG(error != OK, "Cannot save screenshot to file '" + p_path + "'.");
}
@@ -2828,6 +2896,10 @@ void EditorNode::_discard_changes(const String &p_str) {
_update_scene_tabs();
if (current_option == FILE_CLOSE_ALL_AND_QUIT || current_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER) {
+ // If restore tabs is enabled, reopen the scene that has just been closed, so it's remembered properly.
+ if (bool(EDITOR_GET("interface/scene_tabs/restore_scenes_on_load"))) {
+ _menu_option_confirm(FILE_OPEN_PREV, true);
+ }
if (_next_unsaved_scene(false) == -1) {
current_option = current_option == FILE_CLOSE_ALL_AND_QUIT ? FILE_QUIT : RUN_PROJECT_MANAGER;
_discard_changes();
@@ -2863,8 +2935,7 @@ void EditorNode::_discard_changes(const String &p_str) {
args.push_back(exec.get_base_dir());
args.push_back("--project-manager");
- OS::ProcessID pid = 0;
- Error err = OS::get_singleton()->execute(exec, args, false, &pid);
+ Error err = OS::get_singleton()->create_process(exec, args);
ERR_FAIL_COND(err);
} break;
}
@@ -2876,7 +2947,7 @@ void EditorNode::_update_file_menu_opened() {
Ref<Shortcut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
reopen_closed_scene_sc->set_name(TTR("Reopen Closed Scene"));
PopupMenu *pop = file_menu->get_popup();
- pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), previous_scenes.empty());
+ pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), previous_scenes.is_empty());
}
void EditorNode::_update_file_menu_closed() {
@@ -2884,8 +2955,8 @@ void EditorNode::_update_file_menu_closed() {
pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), false);
}
-Control *EditorNode::get_viewport() {
- return viewport;
+Control *EditorNode::get_main_control() {
+ return main_control;
}
void EditorNode::_editor_select(int p_which) {
@@ -3042,8 +3113,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
Ref<ConfigFile> cf;
cf.instance();
- String addon_path = String("res://addons").plus_file(p_addon).plus_file("plugin.cfg");
- if (!DirAccess::exists(addon_path.get_base_dir())) {
+ if (!DirAccess::exists(p_addon.get_base_dir())) {
ProjectSettings *ps = ProjectSettings::get_singleton();
PackedStringArray enabled_plugins = ps->get("editor_plugins/enabled");
for (int i = 0; i < enabled_plugins.size(); ++i) {
@@ -3057,14 +3127,14 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
WARN_PRINT("Addon '" + p_addon + "' failed to load. No directory found. Removing from enabled plugins.");
return;
}
- Error err = cf->load(addon_path);
+ Error err = cf->load(p_addon);
if (err != OK) {
- show_warning(vformat(TTR("Unable to enable addon plugin at: '%s' parsing of config failed."), addon_path));
+ show_warning(vformat(TTR("Unable to enable addon plugin at: '%s' parsing of config failed."), p_addon));
return;
}
if (!cf->has_section_key("plugin", "script")) {
- show_warning(vformat(TTR("Unable to find script field for addon plugin at: 'res://addons/%s'."), p_addon));
+ show_warning(vformat(TTR("Unable to find script field for addon plugin at: '%s'."), p_addon));
return;
}
@@ -3073,7 +3143,7 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
// Only try to load the script if it has a name. Else, the plugin has no init script.
if (script_path.length() > 0) {
- script_path = String("res://addons").plus_file(p_addon).plus_file(script_path);
+ script_path = p_addon.get_base_dir().plus_file(script_path);
script = ResourceLoader::load(script_path);
if (script.is_null()) {
@@ -3331,7 +3401,7 @@ int EditorNode::new_scene() {
return idx;
}
-Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported) {
+Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported, bool p_silent_change_tab) {
if (!is_inside_tree()) {
defer_load_scene = p_scene;
return OK;
@@ -3371,14 +3441,16 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
if (!editor_data.get_edited_scene_root() && editor_data.get_edited_scene_count() == 2) {
_remove_edited_scene();
- } else {
+ } else if (!p_silent_change_tab) {
_scene_tab_changed(idx);
+ } else {
+ set_current_scene(idx);
}
dependency_errors.clear();
Error err;
- Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true, &err);
+ Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", ResourceFormatLoader::CACHE_MODE_REPLACE, &err);
if (!sdata.is_valid()) {
_dialog_display_load_error(lpath, err);
opening_prev = false;
@@ -3823,7 +3895,7 @@ Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String
}
Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p_fallback) const {
- ERR_FAIL_COND_V_MSG(p_class.empty(), nullptr, "Class name cannot be empty.");
+ ERR_FAIL_COND_V_MSG(p_class.is_empty(), nullptr, "Class name cannot be empty.");
if (ScriptServer::is_global_class(p_class)) {
Ref<ImageTexture> icon;
@@ -4555,7 +4627,7 @@ bool EditorNode::has_scenes_in_session() {
return false;
}
Array scenes = config->get_value("EditorNode", "open_scenes");
- return !scenes.empty();
+ return !scenes.is_empty();
}
bool EditorNode::ensure_main_scene(bool p_from_native) {
@@ -4711,8 +4783,8 @@ void EditorNode::_scene_tab_closed(int p_tab, int option) {
}
bool unsaved = (p_tab == editor_data.get_edited_scene()) ?
- saved_version != editor_data.get_undo_redo().get_version() :
- editor_data.get_scene_version(p_tab) != 0;
+ saved_version != editor_data.get_undo_redo().get_version() :
+ editor_data.get_scene_version(p_tab) != 0;
if (unsaved) {
save_confirmation->get_ok_button()->set_text(TTR("Save & Close"));
save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_filename() != "" ? scene->get_filename() : "unsaved scene"));
@@ -4781,7 +4853,7 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
Ref<Shortcut> undo_close_tab_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
undo_close_tab_sc->set_name(TTR("Undo Close Tab"));
scene_tabs_context_menu->add_shortcut(undo_close_tab_sc, FILE_OPEN_PREV);
- if (previous_scenes.empty()) {
+ if (previous_scenes.is_empty()) {
scene_tabs_context_menu->set_item_disabled(scene_tabs_context_menu->get_item_index(FILE_OPEN_PREV), true);
}
scene_tabs_context_menu->add_item(TTR("Close Other Tabs"), FILE_CLOSE_OTHERS);
@@ -5147,9 +5219,7 @@ void EditorNode::_global_menu_new_window(const Variant &p_tag) {
List<String> args;
args.push_back("-p");
String exec = OS::get_singleton()->get_executable_path();
-
- OS::ProcessID pid = 0;
- OS::get_singleton()->execute(exec, args, false, &pid);
+ OS::get_singleton()->create_process(exec, args);
}
}
@@ -5185,7 +5255,7 @@ void EditorNode::_add_dropped_files_recursive(const Vector<String> &p_files, Str
next_file = sub_dir->get_next();
}
- if (!sub_files.empty()) {
+ if (!sub_files.is_empty()) {
dir->make_dir(to);
_add_dropped_files_recursive(sub_files, to);
}
@@ -5202,6 +5272,8 @@ void EditorNode::_file_access_close_error_notify(const String &p_str) {
}
void EditorNode::reload_scene(const String &p_path) {
+ /*
+ * No longer necesary since scenes now reset and reload their internal resource if needed.
//first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk
List<Ref<Resource>> cached;
@@ -5219,6 +5291,8 @@ void EditorNode::reload_scene(const String &p_path) {
to_clear.pop_front();
}
+ */
+
int scene_idx = -1;
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
if (editor_data.get_scene_path(i) == p_path) {
@@ -5462,6 +5536,7 @@ void EditorNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("request_help_search"));
ADD_SIGNAL(MethodInfo("script_add_function_request", PropertyInfo(Variant::OBJECT, "obj"), PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::PACKED_STRING_ARRAY, "args")));
ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj")));
+ ADD_SIGNAL(MethodInfo("project_settings_changed"));
}
static Node *_resource_get_edited_scene() {
@@ -5475,13 +5550,14 @@ void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_err
static void _execute_thread(void *p_ud) {
EditorNode::ExecuteThreadArgs *eta = (EditorNode::ExecuteThreadArgs *)p_ud;
- Error err = OS::get_singleton()->execute(eta->path, eta->args, true, nullptr, &eta->output, &eta->exitcode, true, &eta->execute_output_mutex);
+ Error err = OS::get_singleton()->execute(eta->path, eta->args, &eta->output, &eta->exitcode, true, &eta->execute_output_mutex);
print_verbose("Thread exit status: " + itos(eta->exitcode));
if (err != OK) {
eta->exitcode = err;
}
- eta->done = true;
+ eta->done.set();
+ ;
}
int EditorNode::execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok, bool p_close_on_errors) {
@@ -5495,15 +5571,12 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
eta.path = p_path;
eta.args = p_arguments;
eta.exitcode = 255;
- eta.done = false;
int prev_len = 0;
- eta.execute_output_thread = Thread::create(_execute_thread, &eta);
-
- ERR_FAIL_COND_V(!eta.execute_output_thread, 0);
+ eta.execute_output_thread.start(_execute_thread, &eta);
- while (!eta.done) {
+ while (!eta.done.is_set()) {
{
MutexLock lock(eta.execute_output_mutex);
if (prev_len != eta.output.length()) {
@@ -5516,8 +5589,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
OS::get_singleton()->delay_usec(1000);
}
- Thread::wait_to_finish(eta.execute_output_thread);
- memdelete(eta.execute_output_thread);
+ eta.execute_output_thread.wait_to_finish();
execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode));
if (p_close_on_errors && eta.exitcode != 0) {
@@ -5532,6 +5604,10 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
return eta.exitcode;
}
+void EditorNode::notify_settings_changed() {
+ settings_changed = true;
+}
+
EditorNode::EditorNode() {
Input::get_singleton()->set_use_accumulated_input(true);
Resource::_get_local_scene_func = _resource_get_edited_scene;
@@ -5592,6 +5668,8 @@ EditorNode::EditorNode() {
switch (display_scale) {
case 0: {
// Try applying a suitable display scale automatically.
+ // The code below is adapted in `editor/editor_settings.cpp` and `editor/project_manager.cpp`.
+ // Make sure to update those when modifying the code below.
#ifdef OSX_ENABLED
editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale());
#else
@@ -5600,6 +5678,10 @@ EditorNode::EditorNode() {
if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).y >= 1400) {
// hiDPI display.
scale = 2.0;
+ } else if (DisplayServer::get_singleton()->screen_get_size(screen).y >= 1700) {
+ // Likely a hiDPI display, but we aren't certain due to the returned DPI.
+ // Use an intermediate scale to handle this situation.
+ scale = 1.5;
} else if (DisplayServer::get_singleton()->screen_get_size(screen).y <= 800) {
// Small loDPI display. Use a smaller display scale so that editor elements fit more easily.
// Icons won't look great, but this is better than having editor elements overflow from its window.
@@ -5758,7 +5840,7 @@ EditorNode::EditorNode() {
register_exporters();
- GLOBAL_DEF("editor/main_run_args", "");
+ GLOBAL_DEF("editor/run/main_run_args", "");
ClassDB::set_class_enabled("RootMotionView", true);
@@ -5771,7 +5853,6 @@ EditorNode::EditorNode() {
EDITOR_DEF("run/output/always_close_output_on_stop", true);
EDITOR_DEF("run/auto_save/save_before_running", true);
EDITOR_DEF_RST("interface/editor/save_each_scene_on_quit", true);
- EDITOR_DEF("interface/editor/quit_confirmation", true);
EDITOR_DEF("interface/editor/show_update_spinner", false);
EDITOR_DEF("interface/editor/update_continuously", false);
EDITOR_DEF_RST("interface/scene_tabs/restore_scenes_on_load", false);
@@ -5784,7 +5865,7 @@ EditorNode::EditorNode() {
EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true);
EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
- EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "StandardMaterial3D,ORMMaterial3D,Script,MeshLibrary,TileSet");
+ EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "Script,MeshLibrary,TileSet");
EDITOR_DEF("interface/inspector/default_color_picker_mode", 0);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT));
EDITOR_DEF("run/auto_save/save_before_running", true);
@@ -5980,8 +6061,8 @@ EditorNode::EditorNode() {
tab_preview_panel->add_child(tab_preview);
scene_tabs = memnew(Tabs);
- scene_tabs->add_theme_style_override("tab_fg", gui_base->get_theme_stylebox("SceneTabFG", "EditorStyles"));
- scene_tabs->add_theme_style_override("tab_bg", gui_base->get_theme_stylebox("SceneTabBG", "EditorStyles"));
+ scene_tabs->add_theme_style_override("tab_selected", gui_base->get_theme_stylebox("SceneTabFG", "EditorStyles"));
+ scene_tabs->add_theme_style_override("tab_unselected", gui_base->get_theme_stylebox("SceneTabBG", "EditorStyles"));
scene_tabs->set_select_with_rmb(true);
scene_tabs->add_tab("unsaved");
scene_tabs->set_tab_align(Tabs::ALIGN_LEFT);
@@ -6024,7 +6105,7 @@ EditorNode::EditorNode() {
tabbar_container->add_child(distraction_free);
scene_tab_add->set_tooltip(TTR("Add a new scene."));
scene_tab_add->set_icon(gui_base->get_theme_icon("Add", "EditorIcons"));
- scene_tab_add->add_theme_color_override("icon_color_normal", Color(0.6f, 0.6f, 0.6f, 0.8f));
+ scene_tab_add->add_theme_color_override("icon_normal_color", Color(0.6f, 0.6f, 0.6f, 0.8f));
scene_tab_add->connect("pressed", callable_mp(this, &EditorNode::_menu_option), make_binds(FILE_NEW_SCENE));
scene_root_parent = memnew(PanelContainer);
@@ -6041,10 +6122,10 @@ EditorNode::EditorNode() {
scene_root->set_disable_input(true);
scene_root->set_as_audio_listener_2d(true);
- viewport = memnew(VBoxContainer);
- viewport->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- viewport->add_theme_constant_override("separation", 0);
- scene_root_parent->add_child(viewport);
+ main_control = memnew(VBoxContainer);
+ main_control->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ main_control->add_theme_constant_override("separation", 0);
+ scene_root_parent->add_child(main_control);
HBoxContainer *left_menu_hb = memnew(HBoxContainer);
menu_hb->add_child(left_menu_hb);
@@ -6135,8 +6216,8 @@ EditorNode::EditorNode() {
pm_export->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option));
p->add_separator();
- p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true);
- p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_Z), EDIT_REDO, true);
+ p->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO, true);
+ p->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO, true);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/reload_saved_scene", TTR("Reload Saved Scene")), EDIT_RELOAD_SAVED_SCENE);
@@ -6272,7 +6353,11 @@ EditorNode::EditorNode() {
p = help_menu->get_popup();
p->connect("id_pressed", callable_mp(this, &EditorNode::_menu_option));
- p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search"), KEY_MASK_SHIFT | KEY_F1), HELP_SEARCH);
+#ifdef OSX_ENABLED
+ p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_MASK_ALT | KEY_SPACE), HELP_SEARCH);
+#else
+ p->add_icon_shortcut(gui_base->get_theme_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F1), HELP_SEARCH);
+#endif
p->add_separator();
p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/online_docs", TTR("Online Docs")), HELP_DOCS);
p->add_icon_shortcut(gui_base->get_theme_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/q&a", TTR("Q&A")), HELP_QA);
@@ -6377,7 +6462,7 @@ EditorNode::EditorNode() {
#warning needs to be reimplemented
#endif
#if 0
- String video_drivers = ProjectSettings::get_singleton()->get_custom_property_info()["rendering/quality/driver/driver_name"].hint_string;
+ String video_drivers = ProjectSettings::get_singleton()->get_custom_property_info()["rendering/driver/driver_name"].hint_string;
String current_video_driver = OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver());
video_driver_current = 0;
for (int i = 0; i < video_drivers.get_slice_count(","); i++) {
@@ -6527,6 +6612,9 @@ EditorNode::EditorNode() {
center_split->connect("resized", callable_mp(this, &EditorNode::_vp_resized));
+ native_shader_source_visualizer = memnew(EditorNativeShaderSourceVisualizer);
+ gui_base->add_child(native_shader_source_visualizer);
+
orphan_resources = memnew(OrphanResourcesDialog);
gui_base->add_child(orphan_resources);
@@ -6607,6 +6695,30 @@ EditorNode::EditorNode() {
//plugin stuff
add_editor_plugin(memnew(DebuggerEditorPlugin(this, debug_menu)));
+
+ disk_changed = memnew(ConfirmationDialog);
+ {
+ VBoxContainer *vbc = memnew(VBoxContainer);
+ disk_changed->add_child(vbc);
+
+ Label *dl = memnew(Label);
+ dl->set_text(TTR("The following files are newer on disk.\nWhat action should be taken?"));
+ vbc->add_child(dl);
+
+ disk_changed_list = memnew(Tree);
+ vbc->add_child(disk_changed_list);
+ disk_changed_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+
+ disk_changed->connect("confirmed", callable_mp(this, &EditorNode::_reload_modified_scenes));
+ disk_changed->connect("confirmed", callable_mp(this, &EditorNode::_reload_project_settings));
+ disk_changed->get_ok_button()->set_text(TTR("Reload"));
+
+ disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave");
+ disk_changed->connect("custom_action", callable_mp(this, &EditorNode::_resave_scenes));
+ }
+
+ gui_base->add_child(disk_changed);
+
add_editor_plugin(memnew(AnimationPlayerEditorPlugin(this)));
add_editor_plugin(memnew(CanvasItemEditorPlugin(this)));
add_editor_plugin(memnew(Node3DEditorPlugin(this)));
@@ -6836,14 +6948,12 @@ EditorNode::EditorNode() {
ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_ALT | KEY_2);
ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_MASK_ALT | KEY_3);
ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library"), KEY_MASK_ALT | KEY_4);
- ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_MASK_ALT | KEY_SPACE);
#else
// Use the Ctrl modifier so F2 can be used to rename nodes in the scene tree dock.
ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_CTRL | KEY_F1);
ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_CTRL | KEY_F2);
ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_MASK_CTRL | KEY_F3);
ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library"), KEY_MASK_CTRL | KEY_F4);
- ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F1);
#endif
ED_SHORTCUT("editor/editor_next", TTR("Open the next Editor"));
ED_SHORTCUT("editor/editor_prev", TTR("Open the previous Editor"));
@@ -6950,8 +7060,8 @@ void EditorPluginList::remove_plugin(EditorPlugin *p_plugin) {
plugins_list.erase(p_plugin);
}
-bool EditorPluginList::empty() {
- return plugins_list.empty();
+bool EditorPluginList::is_empty() {
+ return plugins_list.is_empty();
}
void EditorPluginList::clear() {
diff --git a/editor/editor_node.h b/editor/editor_node.h
index ab8d268801..91d873d16f 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,9 +31,11 @@
#ifndef EDITOR_NODE_H
#define EDITOR_NODE_H
+#include "core/templates/safe_refcount.h"
#include "editor/editor_data.h"
#include "editor/editor_export.h"
#include "editor/editor_folding.h"
+#include "editor/editor_native_shader_source_visualizer.h"
#include "editor/editor_run.h"
#include "editor/inspector_dock.h"
#include "editor/property_editor.h"
@@ -107,10 +109,10 @@ public:
String path;
List<String> args;
String output;
- Thread *execute_output_thread = nullptr;
+ Thread execute_output_thread;
Mutex execute_output_mutex;
int exitcode = 0;
- volatile bool done = false;
+ SafeFlag done;
};
private:
@@ -125,10 +127,8 @@ private:
FILE_SAVE_SCENE,
FILE_SAVE_AS_SCENE,
FILE_SAVE_ALL_SCENES,
- FILE_SAVE_BEFORE_RUN,
FILE_SAVE_AND_RUN,
FILE_SHOW_IN_FILESYSTEM,
- FILE_IMPORT_SUBSCENE,
FILE_EXPORT_PROJECT,
FILE_EXPORT_MESH_LIBRARY,
FILE_INSTALL_ANDROID_SOURCE,
@@ -255,7 +255,7 @@ private:
Control *vp_base;
HBoxContainer *menu_hb;
- Control *viewport;
+ Control *main_control;
MenuButton *file_menu;
MenuButton *project_menu;
MenuButton *debug_menu;
@@ -312,6 +312,9 @@ private:
EditorSettingsDialog *settings_config_dialog;
ProjectSettingsEditor *project_settings;
+ bool settings_changed = true; //make it update settings on first frame
+ void _update_from_settings();
+
PopupMenu *vcs_actions_menu;
EditorFileDialog *file;
ExportTemplateManager *export_template_manager;
@@ -323,6 +326,8 @@ private:
String current_path;
MenuButton *update_spinner;
+ EditorNativeShaderSourceVisualizer *native_shader_source_visualizer;
+
String defer_load_scene;
Node *_last_instanced_scene;
@@ -420,6 +425,9 @@ private:
Label *version_label;
Button *bottom_panel_raise;
+ Tree *disk_changed_list;
+ ConfirmationDialog *disk_changed;
+
void _bottom_panel_raise_toggled(bool);
EditorInterface *editor_interface;
@@ -639,6 +647,10 @@ private:
static void _resource_loaded(RES p_resource, const String &p_path);
void _resources_changed(const Vector<String> &p_resources);
+ void _scan_external_changes();
+ void _reload_modified_scenes();
+ void _reload_project_settings();
+ void _resave_scenes(String p_str);
void _feature_profile_changed();
bool _is_class_editor_disabled_by_feature_profile(const StringName &p_class);
@@ -707,8 +719,6 @@ public:
void save_resource(const Ref<Resource> &p_resource);
void save_resource_as(const Ref<Resource> &p_resource, const String &p_at_path = String());
- void merge_from_scene() { _menu_option_confirm(FILE_IMPORT_SUBSCENE, false); }
-
void show_about() { _menu_option_confirm(HELP_ABOUT, false); }
static bool has_unsaved_changes() { return singleton->unsaved_cache; }
@@ -728,7 +738,7 @@ public:
bool is_changing_scene() const;
static EditorLog *get_log() { return singleton->log; }
- Control *get_viewport();
+ Control *get_main_control();
void set_edited_scene(Node *p_scene);
@@ -739,7 +749,7 @@ public:
void fix_dependencies(const String &p_for_file);
void clear_scene() { _cleanup_scene(); }
int new_scene();
- Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false);
+ Error load_scene(const String &p_scene, bool p_ignore_broken_deps = false, bool p_set_inherited = false, bool p_clear_errors = true, bool p_force_open_imported = false, bool p_silent_change_tab = false);
Error load_resource(const String &p_resource, bool p_ignore_broken_deps = false);
bool is_scene_open(const String &p_path);
@@ -838,6 +848,8 @@ public:
void save_scene_list(Vector<String> p_scene_filenames);
void restart_editor();
+ void notify_settings_changed();
+
void dim_editor(bool p_dimming, bool p_force_dim = false);
bool is_editor_dimmed() const;
@@ -903,7 +915,7 @@ public:
void add_plugin(EditorPlugin *p_plugin);
void remove_plugin(EditorPlugin *p_plugin);
void clear();
- bool empty();
+ bool is_empty();
EditorPluginList();
~EditorPluginList();
diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp
index c249974f99..d1c52b4310 100644
--- a/editor/editor_path.cpp
+++ b/editor/editor_path.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_path.h b/editor/editor_path.h
index 01ba25ab69..d1090947f9 100644
--- a/editor/editor_path.h
+++ b/editor/editor_path.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index f974ba9998..c0cecbc651 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -128,7 +128,7 @@ Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh
Main::iteration();
Main::iteration();
Ref<Image> img = RS::get_singleton()->texture_2d_get(viewport_texture);
- ERR_CONTINUE(!img.is_valid() || img->empty());
+ ERR_CONTINUE(!img.is_valid() || img->is_empty());
Ref<ImageTexture> it(memnew(ImageTexture));
it->create_from_image(img);
@@ -152,8 +152,8 @@ void EditorInterface::set_main_screen_editor(const String &p_name) {
EditorNode::get_singleton()->select_editor_by_name(p_name);
}
-Control *EditorInterface::get_editor_viewport() {
- return EditorNode::get_singleton()->get_viewport();
+Control *EditorInterface::get_editor_main_control() {
+ return EditorNode::get_singleton()->get_main_control();
}
void EditorInterface::edit_resource(const Ref<Resource> &p_resource) {
@@ -319,7 +319,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_edited_scene_root"), &EditorInterface::get_edited_scene_root);
ClassDB::bind_method(D_METHOD("get_resource_previewer"), &EditorInterface::get_resource_previewer);
ClassDB::bind_method(D_METHOD("get_resource_filesystem"), &EditorInterface::get_resource_file_system);
- ClassDB::bind_method(D_METHOD("get_editor_viewport"), &EditorInterface::get_editor_viewport);
+ ClassDB::bind_method(D_METHOD("get_editor_main_control"), &EditorInterface::get_editor_main_control);
ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews);
ClassDB::bind_method(D_METHOD("select_file", "file"), &EditorInterface::select_file);
ClassDB::bind_method(D_METHOD("get_selected_path"), &EditorInterface::get_selected_path);
@@ -756,7 +756,6 @@ int find(const PackedStringArray &a, const String &v) {
void EditorPlugin::enable_plugin() {
// Called when the plugin gets enabled in project settings, after it's added to the tree.
// You can implement it to register autoloads.
-
if (get_script_instance() && get_script_instance()->has_method("enable_plugin")) {
get_script_instance()->call("enable_plugin");
}
@@ -819,6 +818,18 @@ void EditorPlugin::remove_debugger_plugin(const Ref<Script> &p_script) {
EditorDebuggerNode::get_singleton()->remove_debugger_plugin(p_script);
}
+void EditorPlugin::_editor_project_settings_changed() {
+ emit_signal("project_settings_changed");
+}
+void EditorPlugin::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &EditorPlugin::_editor_project_settings_changed));
+ }
+ if (p_what == NOTIFICATION_EXIT_TREE) {
+ EditorNode::get_singleton()->disconnect("project_settings_changed", callable_mp(this, &EditorPlugin::_editor_project_settings_changed));
+ }
+}
+
void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_control_to_container", "container", "control"), &EditorPlugin::add_control_to_container);
ClassDB::bind_method(D_METHOD("add_control_to_bottom_panel", "control", "title"), &EditorPlugin::add_control_to_bottom_panel);
@@ -890,6 +901,7 @@ void EditorPlugin::_bind_methods() {
ADD_SIGNAL(MethodInfo("scene_closed", PropertyInfo(Variant::STRING, "filepath")));
ADD_SIGNAL(MethodInfo("main_screen_changed", PropertyInfo(Variant::STRING, "screen_name")));
ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
+ ADD_SIGNAL(MethodInfo("project_settings_changed"));
BIND_ENUM_CONSTANT(CONTAINER_TOOLBAR);
BIND_ENUM_CONSTANT(CONTAINER_SPATIAL_EDITOR_MENU);
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 03908b43ca..ae9fcfb28a 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -69,7 +69,7 @@ protected:
public:
static EditorInterface *get_singleton() { return singleton; }
- Control *get_editor_viewport();
+ Control *get_editor_main_control();
void edit_resource(const Ref<Resource> &p_resource);
void open_scene_from_path(const String &scene_path);
void reload_scene_from_path(const String &scene_path);
@@ -130,7 +130,11 @@ class EditorPlugin : public Node {
String last_main_screen_name;
+ void _editor_project_settings_changed();
+
protected:
+ void _notification(int p_what);
+
static void _bind_methods();
UndoRedo &get_undo_redo() { return *undo_redo; }
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index 1fdba10a74..e5b62513ff 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,44 +49,16 @@ void EditorPluginSettings::_notification(int p_what) {
void EditorPluginSettings::update_plugins() {
plugin_list->clear();
-
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- Error err = da->change_dir("res://addons");
- if (err != OK) {
- memdelete(da);
- return;
- }
-
updating = true;
-
TreeItem *root = plugin_list->create_item();
- da->list_dir_begin();
-
- String d = da->get_next();
-
- Vector<String> plugins;
-
- while (d != String()) {
- bool dir = da->current_is_dir();
- String path = "res://addons/" + d + "/plugin.cfg";
-
- if (dir && FileAccess::exists(path)) {
- plugins.push_back(d);
- }
-
- d = da->get_next();
- }
-
- da->list_dir_end();
- memdelete(da);
-
+ Vector<String> plugins = _get_plugins("res://addons");
plugins.sort();
for (int i = 0; i < plugins.size(); i++) {
Ref<ConfigFile> cf;
cf.instance();
- String path = "res://addons/" + plugins[i] + "/plugin.cfg";
+ const String path = plugins[i];
Error err2 = cf->load(path);
@@ -117,7 +89,6 @@ void EditorPluginSettings::update_plugins() {
}
if (!key_missing) {
- String d2 = plugins[i];
String name = cf->get_value("plugin", "name");
String author = cf->get_value("plugin", "author");
String version = cf->get_value("plugin", "version");
@@ -127,14 +98,14 @@ void EditorPluginSettings::update_plugins() {
TreeItem *item = plugin_list->create_item(root);
item->set_text(0, name);
item->set_tooltip(0, TTR("Name:") + " " + name + "\n" + TTR("Path:") + " " + path + "\n" + TTR("Main Script:") + " " + script + "\n" + TTR("Description:") + " " + description);
- item->set_metadata(0, d2);
+ item->set_metadata(0, path);
item->set_text(1, version);
item->set_metadata(1, script);
item->set_text(2, author);
item->set_metadata(2, description);
item->set_cell_mode(3, TreeItem::CELL_MODE_CHECK);
item->set_text(3, TTR("Enable"));
- bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(d2);
+ bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(path);
item->set_checked(3, is_active);
item->set_editable(3, true);
item->add_button(4, get_theme_icon("Edit", "EditorIcons"), BUTTON_PLUGIN_EDIT, false, TTR("Edit Plugin"));
@@ -179,12 +150,39 @@ void EditorPluginSettings::_cell_button_pressed(Object *p_item, int p_column, in
if (p_id == BUTTON_PLUGIN_EDIT) {
if (p_column == 4) {
String dir = item->get_metadata(0);
- plugin_config_dialog->config("res://addons/" + dir + "/plugin.cfg");
+ plugin_config_dialog->config(dir);
plugin_config_dialog->popup_centered();
}
}
}
+Vector<String> EditorPluginSettings::_get_plugins(const String &p_dir) {
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ Error err = da->change_dir(p_dir);
+ if (err != OK) {
+ return Vector<String>();
+ }
+
+ Vector<String> plugins;
+ da->list_dir_begin();
+ for (String path = da->get_next(); path != String(); path = da->get_next()) {
+ if (path[0] == '.' || !da->current_is_dir()) {
+ continue;
+ }
+
+ const String full_path = p_dir.plus_file(path);
+ const String plugin_config = full_path.plus_file("plugin.cfg");
+ if (FileAccess::exists(plugin_config)) {
+ plugins.push_back(plugin_config);
+ } else {
+ plugins.append_array(_get_plugins(full_path));
+ }
+ }
+
+ da->list_dir_end();
+ return plugins;
+}
+
void EditorPluginSettings::_bind_methods() {
}
diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h
index 0b61e28449..34b26de90e 100644
--- a/editor/editor_plugin_settings.h
+++ b/editor/editor_plugin_settings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,6 +54,8 @@ class EditorPluginSettings : public VBoxContainer {
void _create_clicked();
void _cell_button_pressed(Object *p_item, int p_column, int p_id);
+ static Vector<String> _get_plugins(const String &p_dir);
+
protected:
void _notification(int p_what);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index f432d52bf6..dbe4aa55fa 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -68,16 +68,18 @@ void EditorPropertyText::_text_changed(const String &p_string) {
}
if (string_name) {
- emit_changed(get_edited_property(), StringName(p_string), "", false);
+ emit_changed(get_edited_property(), StringName(p_string), "", true);
} else {
- emit_changed(get_edited_property(), p_string, "", false);
+ emit_changed(get_edited_property(), p_string, "", true);
}
}
void EditorPropertyText::update_property() {
String s = get_edited_object()->get(get_edited_property());
updating = true;
- text->set_text(s);
+ if (text->get_text() != s) {
+ text->set_text(s);
+ }
text->set_editable(!is_read_only());
updating = false;
}
@@ -133,9 +135,11 @@ void EditorPropertyMultilineText::_open_big_text() {
void EditorPropertyMultilineText::update_property() {
String t = get_edited_object()->get(get_edited_property());
- text->set_text(t);
- if (big_text && big_text->is_visible_in_tree()) {
- big_text->set_text(t);
+ if (text->get_text() != t) {
+ text->set_text(t);
+ if (big_text && big_text->is_visible_in_tree()) {
+ big_text->set_text(t);
+ }
}
}
@@ -712,12 +716,18 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
case LAYER_PHYSICS_2D:
basename = "layer_names/2d_physics";
break;
+ case LAYER_NAVIGATION_2D:
+ basename = "layer_names/2d_navigation";
+ break;
case LAYER_RENDER_3D:
basename = "layer_names/3d_render";
break;
case LAYER_PHYSICS_3D:
basename = "layer_names/3d_physics";
break;
+ case LAYER_NAVIGATION_3D:
+ basename = "layer_names/3d_navigation";
+ break;
}
Vector<String> names;
@@ -725,12 +735,12 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
for (int i = 0; i < 20; i++) {
String name;
- if (ProjectSettings::get_singleton()->has_setting(basename + "/layer_" + itos(i + 1))) {
- name = ProjectSettings::get_singleton()->get(basename + "/layer_" + itos(i + 1));
+ if (ProjectSettings::get_singleton()->has_setting(basename + vformat("/layer_%d", i))) {
+ name = ProjectSettings::get_singleton()->get(basename + vformat("/layer_%d", i));
}
if (name == "") {
- name = TTR("Layer") + " " + itos(i + 1);
+ name = vformat(TTR("Layer %d"), i);
}
names.push_back(name);
@@ -1263,16 +1273,20 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool
EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) {
bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing"));
-
+ bool grid = false;
BoxContainer *bc;
if (p_force_wide) {
bc = memnew(HBoxContainer);
add_child(bc);
} else if (horizontal) {
- bc = memnew(HBoxContainer);
+ bc = memnew(VBoxContainer);
add_child(bc);
set_bottom_editor(bc);
+
+ bc->add_child(memnew(HBoxContainer));
+ bc->add_child(memnew(HBoxContainer));
+ grid = true;
} else {
bc = memnew(VBoxContainer);
add_child(bc);
@@ -1283,7 +1297,13 @@ EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
spin[i]->set_flat(true);
- bc->add_child(spin[i]);
+
+ if (grid) {
+ bc->get_child(i / 2)->add_child(spin[i]);
+ } else {
+ bc->add_child(spin[i]);
+ }
+
add_focusable(spin[i]);
spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2::_value_changed), varray(desc[i]));
if (horizontal) {
@@ -1526,16 +1546,20 @@ void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider) {
EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) {
bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing"));
-
+ bool grid = false;
BoxContainer *bc;
if (p_force_wide) {
bc = memnew(HBoxContainer);
add_child(bc);
} else if (horizontal) {
- bc = memnew(HBoxContainer);
+ bc = memnew(VBoxContainer);
add_child(bc);
set_bottom_editor(bc);
+
+ bc->add_child(memnew(HBoxContainer));
+ bc->add_child(memnew(HBoxContainer));
+ grid = true;
} else {
bc = memnew(VBoxContainer);
add_child(bc);
@@ -1546,7 +1570,13 @@ EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
spin[i]->set_flat(true);
- bc->add_child(spin[i]);
+
+ if (grid) {
+ bc->get_child(i / 2)->add_child(spin[i]);
+ } else {
+ bc->add_child(spin[i]);
+ }
+
add_focusable(spin[i]);
spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2i::_value_changed), varray(desc[i]));
if (horizontal) {
@@ -2145,7 +2175,9 @@ void EditorPropertyColor::_color_changed(const Color &p_color) {
}
void EditorPropertyColor::_popup_closed() {
- emit_changed(get_edited_property(), picker->get_pick_color(), "", false);
+ if (picker->get_pick_color() != last_color) {
+ emit_changed(get_edited_property(), picker->get_pick_color(), "", false);
+ }
}
void EditorPropertyColor::_picker_created() {
@@ -2158,6 +2190,10 @@ void EditorPropertyColor::_picker_created() {
}
}
+void EditorPropertyColor::_picker_opening() {
+ last_color = picker->get_pick_color();
+}
+
void EditorPropertyColor::_bind_methods() {
}
@@ -2193,6 +2229,7 @@ EditorPropertyColor::EditorPropertyColor() {
picker->connect("color_changed", callable_mp(this, &EditorPropertyColor::_color_changed));
picker->connect("popup_closed", callable_mp(this, &EditorPropertyColor::_popup_closed));
picker->connect("picker_created", callable_mp(this, &EditorPropertyColor::_picker_created));
+ picker->get_popup()->connect("about_to_popup", callable_mp(this, &EditorPropertyColor::_picker_opening));
}
////////////// NODE PATH //////////////////////
@@ -2356,7 +2393,7 @@ void EditorPropertyResource::_file_selected(const String &p_path) {
property_types = E->get().hint_string;
}
}
- if (!property_types.empty()) {
+ if (!property_types.is_empty()) {
bool any_type_matches = false;
const Vector<String> split_property_types = property_types.split(",");
for (int i = 0; i < split_property_types.size(); ++i) {
@@ -2514,7 +2551,7 @@ void EditorPropertyResource::_menu_option(int p_which) {
update_property();
break;
}
- ERR_FAIL_COND(inheritors_array.empty());
+ ERR_FAIL_COND(inheritors_array.is_empty());
String intype = inheritors_array[p_which - TYPE_BASE_ID];
@@ -2545,14 +2582,14 @@ void EditorPropertyResource::_menu_option(int p_which) {
return;
}
- Object *obj = nullptr;
+ Variant obj;
if (ScriptServer::is_global_class(intype)) {
obj = ClassDB::instance(ScriptServer::get_global_class_native_base(intype));
if (obj) {
Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype));
if (script.is_valid()) {
- obj->set_script(Variant(script));
+ ((Object *)obj)->set_script(script);
}
}
} else {
@@ -2563,7 +2600,6 @@ void EditorPropertyResource::_menu_option(int p_which) {
obj = EditorNode::get_editor_data().instance_custom_type(intype, "Resource");
}
- ERR_BREAK(!obj);
Resource *resp = Object::cast_to<Resource>(obj);
ERR_BREAK(!resp);
if (get_edited_object() && base_type != String() && base_type == "Script") {
@@ -2571,7 +2607,7 @@ void EditorPropertyResource::_menu_option(int p_which) {
resp->call("set_instance_base_type", get_edited_object()->get_class());
}
- res = Ref<Resource>(resp);
+ res = RES(resp);
emit_changed(get_edited_property(), res);
update_property();
@@ -2658,7 +2694,7 @@ void EditorPropertyResource::_update_menu_items() {
bool is_custom_resource = false;
Ref<Texture2D> icon;
- if (!custom_resources.empty()) {
+ if (!custom_resources.is_empty()) {
for (int j = 0; j < custom_resources.size(); j++) {
if (custom_resources[j].name == t) {
is_custom_resource = true;
@@ -2829,6 +2865,41 @@ void EditorPropertyResource::_fold_other_editors(Object *p_self) {
}
}
+void EditorPropertyResource::_update_property_bg() {
+ if (!is_inside_tree()) {
+ return;
+ }
+
+ updating_theme = true;
+ if (sub_inspector != nullptr) {
+ int count_subinspectors = 0;
+ Node *n = get_parent();
+ while (n) {
+ EditorInspector *ei = Object::cast_to<EditorInspector>(n);
+ if (ei && ei->is_sub_inspector()) {
+ count_subinspectors++;
+ }
+ n = n->get_parent();
+ }
+ count_subinspectors = MIN(15, count_subinspectors);
+
+ add_theme_color_override("property_color", get_theme_color("sub_inspector_property_color", "Editor"));
+ add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg_selected" + itos(count_subinspectors), "Editor"));
+ add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), "Editor"));
+
+ add_theme_constant_override("font_offset", get_theme_constant("sub_inspector_font_offset", "Editor"));
+ add_theme_constant_override("vseparation", 0);
+ } else {
+ add_theme_color_override("property_color", get_theme_color("property_color", "EditorProperty"));
+ add_theme_style_override("bg_selected", get_theme_stylebox("bg_selected", "EditorProperty"));
+ add_theme_style_override("bg", get_theme_stylebox("bg", "EditorProperty"));
+ add_theme_constant_override("vseparation", get_theme_constant("vseparation", "EditorProperty"));
+ add_theme_constant_override("font_offset", get_theme_constant("font_offset", "EditorProperty"));
+ }
+
+ updating_theme = false;
+ update();
+}
void EditorPropertyResource::update_property() {
RES res = get_edited_object()->get(get_edited_property());
@@ -2877,13 +2948,14 @@ void EditorPropertyResource::update_property() {
}
opened_editor = true;
}
+
+ _update_property_bg();
}
if (res.ptr() != sub_inspector->get_edited_object()) {
sub_inspector->edit(res.ptr());
}
- sub_inspector->refresh();
} else {
if (sub_inspector) {
set_bottom_editor(nullptr);
@@ -2894,6 +2966,7 @@ void EditorPropertyResource::update_property() {
EditorNode::get_singleton()->hide_top_editors();
opened_editor = false;
}
+ _update_property_bg();
}
}
}
@@ -2947,8 +3020,12 @@ void EditorPropertyResource::setup(const String &p_base_type) {
void EditorPropertyResource::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ if (updating_theme) {
+ return;
+ }
Ref<Texture2D> t = get_theme_icon("select_arrow", "Tree");
edit->set_icon(t);
+ _update_property_bg();
}
if (p_what == NOTIFICATION_DRAG_BEGIN) {
@@ -3229,7 +3306,12 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
editor->setup(options);
add_property_editor(p_path, editor);
- } else if (p_hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || p_hint == PROPERTY_HINT_LAYERS_2D_RENDER || p_hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || p_hint == PROPERTY_HINT_LAYERS_3D_RENDER) {
+ } else if (p_hint == PROPERTY_HINT_LAYERS_2D_PHYSICS ||
+ p_hint == PROPERTY_HINT_LAYERS_2D_RENDER ||
+ p_hint == PROPERTY_HINT_LAYERS_2D_NAVIGATION ||
+ p_hint == PROPERTY_HINT_LAYERS_3D_PHYSICS ||
+ p_hint == PROPERTY_HINT_LAYERS_3D_RENDER ||
+ p_hint == PROPERTY_HINT_LAYERS_3D_NAVIGATION) {
EditorPropertyLayers::LayerType lt = EditorPropertyLayers::LAYER_RENDER_2D;
switch (p_hint) {
case PROPERTY_HINT_LAYERS_2D_RENDER:
@@ -3238,12 +3320,18 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
case PROPERTY_HINT_LAYERS_2D_PHYSICS:
lt = EditorPropertyLayers::LAYER_PHYSICS_2D;
break;
+ case PROPERTY_HINT_LAYERS_2D_NAVIGATION:
+ lt = EditorPropertyLayers::LAYER_NAVIGATION_2D;
+ break;
case PROPERTY_HINT_LAYERS_3D_RENDER:
lt = EditorPropertyLayers::LAYER_RENDER_3D;
break;
case PROPERTY_HINT_LAYERS_3D_PHYSICS:
lt = EditorPropertyLayers::LAYER_PHYSICS_3D;
break;
+ case PROPERTY_HINT_LAYERS_3D_NAVIGATION:
+ lt = EditorPropertyLayers::LAYER_NAVIGATION_3D;
+ break;
default: {
} //compiler could be smarter here and realize this can't happen
}
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 63dee9f6d6..07a1e72319 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -239,8 +239,10 @@ public:
enum LayerType {
LAYER_PHYSICS_2D,
LAYER_RENDER_2D,
+ LAYER_NAVIGATION_2D,
LAYER_PHYSICS_3D,
LAYER_RENDER_3D,
+ LAYER_NAVIGATION_3D,
};
private:
@@ -549,6 +551,9 @@ class EditorPropertyColor : public EditorProperty {
void _color_changed(const Color &p_color);
void _popup_closed();
void _picker_created();
+ void _picker_opening();
+
+ Color last_color;
protected:
static void _bind_methods();
@@ -651,6 +656,9 @@ class EditorPropertyResource : public EditorProperty {
bool opened_editor;
+ bool updating_theme = false;
+ void _update_property_bg();
+
protected:
static void _bind_methods();
void _notification(int p_what);
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index c2c309fc32..de688f2709 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -550,7 +550,7 @@ void EditorPropertyArray::_length_changed(double p_page) {
void EditorPropertyArray::setup(Variant::Type p_array_type, const String &p_hint_string) {
array_type = p_array_type;
- if (array_type == Variant::ARRAY && !p_hint_string.empty()) {
+ if (array_type == Variant::ARRAY && !p_hint_string.is_empty()) {
int hint_subtype_separator = p_hint_string.find(":");
if (hint_subtype_separator >= 0) {
String subtype_string = p_hint_string.substr(0, hint_subtype_separator);
@@ -573,8 +573,7 @@ void EditorPropertyArray::_bind_methods() {
EditorPropertyArray::EditorPropertyArray() {
object.instance();
- page_idx = 0;
- page_len = 10;
+ page_len = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
edit = memnew(Button);
edit->set_flat(true);
edit->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -1069,8 +1068,7 @@ void EditorPropertyDictionary::_bind_methods() {
EditorPropertyDictionary::EditorPropertyDictionary() {
object.instance();
- page_idx = 0;
- page_len = 10;
+ page_len = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
edit = memnew(Button);
edit->set_flat(true);
edit->set_h_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h
index c786528d48..fa5adc788d 100644
--- a/editor/editor_properties_array_dict.h
+++ b/editor/editor_properties_array_dict.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -84,8 +84,8 @@ class EditorPropertyArray : public EditorProperty {
bool dropping;
Ref<EditorPropertyArrayObject> object;
- int page_len;
- int page_idx;
+ int page_len = 20;
+ int page_idx = 0;
int changing_type_idx;
Button *edit;
VBoxContainer *vbox;
@@ -129,8 +129,8 @@ class EditorPropertyDictionary : public EditorProperty {
bool updating;
Ref<EditorPropertyDictionaryObject> object;
- int page_len;
- int page_idx;
+ int page_len = 20;
+ int page_idx = 0;
int changing_type_idx;
Button *edit;
VBoxContainer *vbox;
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index d1ec50d786..77288be614 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -206,8 +206,8 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<
}
void EditorResourcePreview::_thread() {
- exited = false;
- while (!exit) {
+ exited.clear();
+ while (!exit.is_set()) {
preview_sem.wait();
preview_mutex.lock();
@@ -326,7 +326,7 @@ void EditorResourcePreview::_thread() {
preview_mutex.unlock();
}
}
- exited = true;
+ exited.set();
}
void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p_res, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata) {
@@ -424,30 +424,25 @@ void EditorResourcePreview::check_for_invalidation(const String &p_path) {
}
void EditorResourcePreview::start() {
- ERR_FAIL_COND_MSG(thread, "Thread already started.");
- thread = Thread::create(_thread_func, this);
+ ERR_FAIL_COND_MSG(thread.is_started(), "Thread already started.");
+ thread.start(_thread_func, this);
}
void EditorResourcePreview::stop() {
- if (thread) {
- exit = true;
+ if (thread.is_started()) {
+ exit.set();
preview_sem.post();
- while (!exited) {
+ while (!exited.is_set()) {
OS::get_singleton()->delay_usec(10000);
RenderingServer::get_singleton()->sync(); //sync pending stuff, as thread may be blocked on visual server
}
- Thread::wait_to_finish(thread);
- memdelete(thread);
- thread = nullptr;
+ thread.wait_to_finish();
}
}
EditorResourcePreview::EditorResourcePreview() {
- thread = nullptr;
singleton = this;
order = 0;
- exit = false;
- exited = false;
}
EditorResourcePreview::~EditorResourcePreview() {
diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h
index 05a4e1bafb..c4e796dcf1 100644
--- a/editor/editor_resource_preview.h
+++ b/editor/editor_resource_preview.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,7 @@
#include "core/os/semaphore.h"
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
#include "scene/main/node.h"
#include "scene/resources/texture.h"
@@ -70,9 +71,9 @@ class EditorResourcePreview : public Node {
Mutex preview_mutex;
Semaphore preview_sem;
- Thread *thread;
- volatile bool exit;
- volatile bool exited;
+ Thread thread;
+ SafeFlag exit;
+ SafeFlag exited;
struct Item {
Ref<Texture2D> preview;
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index 2bba15c017..e46f4eb65a 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -201,7 +201,7 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
int instances = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_instances", 1);
for (int i = 0; i < instances; i++) {
OS::ProcessID pid = 0;
- Error err = OS::get_singleton()->execute(exec, args, false, &pid);
+ Error err = OS::get_singleton()->create_process(exec, args, &pid);
ERR_FAIL_COND_V(err, err);
pids.push_back(pid);
}
diff --git a/editor/editor_run.h b/editor/editor_run.h
index 08b1e74ed1..d6cf3fed71 100644
--- a/editor/editor_run.h
+++ b/editor/editor_run.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp
index 639da371bd..9b92134368 100644
--- a/editor/editor_run_native.cpp
+++ b/editor/editor_run_native.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,7 @@ void EditorRunNative::_notification(int p_what) {
Ref<Image> im = icon->get_data();
im = im->duplicate();
im->clear_mipmaps();
- if (!im->empty()) {
+ if (!im->is_empty()) {
im->resize(16 * EDSCALE, 16 * EDSCALE);
Ref<ImageTexture> small_icon;
small_icon.instance();
diff --git a/editor/editor_run_native.h b/editor/editor_run_native.h
index df6714cb53..3516f668c6 100644
--- a/editor/editor_run_native.h
+++ b/editor/editor_run_native.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_run_script.cpp b/editor/editor_run_script.cpp
index e2446e92be..83ce50a9f9 100644
--- a/editor/editor_run_script.cpp
+++ b/editor/editor_run_script.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_run_script.h b/editor/editor_run_script.h
index 3cb751ecc8..83987ecba1 100644
--- a/editor/editor_run_script.h
+++ b/editor/editor_run_script.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_scale.cpp b/editor/editor_scale.cpp
index 450de75328..85304a9cbc 100644
--- a/editor/editor_scale.cpp
+++ b/editor/editor_scale.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_scale.h b/editor/editor_scale.h
index 91e5df15d4..b20c18706a 100644
--- a/editor/editor_scale.h
+++ b/editor/editor_scale.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index bc9ca15467..f81c87be9e 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -116,12 +116,12 @@ public:
void set_section(const String &p_section, bool p_allow_sub) {
section = p_section;
allow_sub = p_allow_sub;
- _change_notify();
+ notify_property_list_changed();
}
void set_edited(Object *p_edited) {
edited = p_edited;
- _change_notify();
+ notify_property_list_changed();
}
};
@@ -226,7 +226,7 @@ void SectionedInspector::update_category_list() {
if (pi.usage & PROPERTY_USAGE_CATEGORY) {
continue;
- } else if (!(pi.usage & PROPERTY_USAGE_EDITOR)) {
+ } else if (!(pi.usage & PROPERTY_USAGE_EDITOR) || (restrict_to_basic && !(pi.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) {
continue;
}
@@ -234,7 +234,7 @@ void SectionedInspector::update_category_list() {
continue;
}
- if (!filter.empty() && pi.name.findn(filter) == -1 && pi.name.replace("/", " ").capitalize().findn(filter) == -1) {
+ if (!filter.is_empty() && pi.name.findn(filter) == -1 && pi.name.replace("/", " ").capitalize().findn(filter) == -1) {
continue;
}
@@ -294,6 +294,12 @@ EditorInspector *SectionedInspector::get_inspector() {
return inspector;
}
+void SectionedInspector::set_restrict_to_basic_settings(bool p_restrict) {
+ restrict_to_basic = p_restrict;
+ update_category_list();
+ inspector->set_restrict_to_basic_settings(p_restrict);
+}
+
SectionedInspector::SectionedInspector() :
sections(memnew(Tree)),
filter(memnew(SectionedInspectorFilter)),
diff --git a/editor/editor_sectioned_inspector.h b/editor/editor_sectioned_inspector.h
index dfc521302a..1068a4f932 100644
--- a/editor/editor_sectioned_inspector.h
+++ b/editor/editor_sectioned_inspector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,6 +51,8 @@ class SectionedInspector : public HSplitContainer {
String selected_category;
+ bool restrict_to_basic = false;
+
static void _bind_methods();
void _section_selected();
@@ -65,6 +67,7 @@ public:
void set_current_section(const String &p_section);
String get_current_section() const;
+ void set_restrict_to_basic_settings(bool p_restrict);
void update_category_list();
SectionedInspector();
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 73a191d317..ef1f8030fa 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,6 +31,7 @@
#include "editor_settings.h"
#include "core/config/project_settings.h"
+#include "core/input/input_map.h"
#include "core/io/certs_compressed.gen.h"
#include "core/io/compression.h"
#include "core/io/config_file.h"
@@ -70,7 +71,7 @@ bool EditorSettings::_set(const StringName &p_name, const Variant &p_value) {
bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) {
_THREAD_SAFE_METHOD_
- if (p_name.operator String() == "shortcuts") {
+ if (p_name == "shortcuts") {
Array arr = p_value;
ERR_FAIL_COND_V(arr.size() && arr.size() & 1, true);
for (int i = 0; i < arr.size(); i += 2) {
@@ -84,6 +85,24 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value)
}
return false;
+ } else if (p_name == "builtin_action_overrides") {
+ Array actions_arr = p_value;
+ for (int i = 0; i < actions_arr.size(); i++) {
+ Dictionary action_dict = actions_arr[i];
+
+ String name = action_dict["name"];
+ Array events = action_dict["events"];
+
+ InputMap *im = InputMap::get_singleton();
+ im->action_erase_events(name);
+
+ builtin_action_overrides[name].clear();
+ for (int ev_idx = 0; ev_idx < events.size(); ev_idx++) {
+ im->action_add_event(name, events[ev_idx]);
+ builtin_action_overrides[name].push_back(events[ev_idx]);
+ }
+ }
+ return false;
}
bool changed = false;
@@ -118,11 +137,16 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value)
bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
_THREAD_SAFE_METHOD_
- if (p_name.operator String() == "shortcuts") {
+ if (p_name == "shortcuts") {
Array arr;
for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) {
Ref<Shortcut> sc = E->get();
+ if (builtin_action_overrides.has(E->key())) {
+ // This shortcut was auto-generated from built in actions: don't save.
+ continue;
+ }
+
if (optimize_save) {
if (!sc->has_meta("original")) {
continue; //this came from settings but is not any longer used
@@ -139,6 +163,27 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
}
r_ret = arr;
return true;
+ } else if (p_name == "builtin_action_overrides") {
+ Array actions_arr;
+ for (Map<String, List<Ref<InputEvent>>>::Element *E = builtin_action_overrides.front(); E; E = E->next()) {
+ List<Ref<InputEvent>> events = E->get();
+
+ // TODO: skip actions which are the same as the builtin.
+ Dictionary action_dict;
+ action_dict["name"] = E->key();
+
+ Array events_arr;
+ for (List<Ref<InputEvent>>::Element *I = events.front(); I; I = I->next()) {
+ events_arr.push_back(I->get());
+ }
+
+ action_dict["events"] = events_arr;
+
+ actions_arr.push_back(action_dict);
+ }
+
+ r_ret = actions_arr;
+ return true;
}
const VariantContainer *v = props.getptr(p_name);
@@ -220,6 +265,7 @@ void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const {
}
p_list->push_back(PropertyInfo(Variant::ARRAY, "shortcuts", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); //do not edit
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "builtin_action_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
void EditorSettings::_add_property_info_bind(const Dictionary &p_info) {
@@ -281,7 +327,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
locales_to_skip.push_back("te"); // Telugu
}
- if (!locales_to_skip.empty()) {
+ if (!locales_to_skip.is_empty()) {
WARN_PRINT("Some locales are not properly supported by selected Text Server and are disabled.");
}
@@ -326,7 +372,30 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Editor
_initial_set("interface/editor/display_scale", 0);
- hints["interface/editor/display_scale"] = PropertyInfo(Variant::INT, "interface/editor/display_scale", PROPERTY_HINT_ENUM, "Auto,75%,100%,125%,150%,175%,200%,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ // Display what the Auto display scale setting effectively corresponds to.
+ // The code below is adapted in `editor/editor_node.cpp` and `editor/project_manager.cpp`.
+ // Make sure to update those when modifying the code below.
+#ifdef OSX_ENABLED
+ float scale = DisplayServer::get_singleton()->screen_get_max_scale();
+#else
+ const int screen = DisplayServer::get_singleton()->window_get_current_screen();
+ float scale;
+ if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).y >= 1400) {
+ // hiDPI display.
+ scale = 2.0;
+ } else if (DisplayServer::get_singleton()->screen_get_size(screen).y >= 1700) {
+ // Likely a hiDPI display, but we aren't certain due to the returned DPI.
+ // Use an intermediate scale to handle this situation.
+ scale = 1.5;
+ } else if (DisplayServer::get_singleton()->screen_get_size(screen).y <= 800) {
+ // Small loDPI display. Use a smaller display scale so that editor elements fit more easily.
+ // Icons won't look great, but this is better than having editor elements overflow from its window.
+ scale = 0.75;
+ } else {
+ scale = 1.0;
+ }
+#endif
+ hints["interface/editor/display_scale"] = PropertyInfo(Variant::INT, "interface/editor/display_scale", PROPERTY_HINT_ENUM, vformat("Auto (%d%%),75%%,100%%,125%%,150%%,175%%,200%%,Custom", Math::round(scale * 100)), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/custom_display_scale", 1.0f);
hints["interface/editor/custom_display_scale"] = PropertyInfo(Variant::FLOAT, "interface/editor/custom_display_scale", PROPERTY_HINT_RANGE, "0.5,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/main_font_size", 14);
@@ -334,12 +403,16 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/code_font_size", 14);
hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,48,1", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/code_font_contextual_ligatures", 0);
- hints["interface/editor/code_font_contextual_ligatures"] = PropertyInfo(Variant::INT, "interface/editor/code_font_contextual_ligatures", PROPERTY_HINT_ENUM, "Default,Disable contextual alternates (coding ligatures),Use custom OpenType feature set", PROPERTY_USAGE_DEFAULT);
+ hints["interface/editor/code_font_contextual_ligatures"] = PropertyInfo(Variant::INT, "interface/editor/code_font_contextual_ligatures", PROPERTY_HINT_ENUM, "Default,Disable Contextual Alternates (Coding Ligatures),Use Custom OpenType Feature Set", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/code_font_custom_opentype_features", "");
_initial_set("interface/editor/code_font_custom_variations", "");
_initial_set("interface/editor/font_antialiased", true);
_initial_set("interface/editor/font_hinting", 0);
- hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto,None,Light,Normal", PROPERTY_USAGE_DEFAULT);
+#ifdef OSX_ENABLED
+ hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto (None),None,Light,Normal", PROPERTY_USAGE_DEFAULT);
+#else
+ hints["interface/editor/font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/font_hinting", PROPERTY_HINT_ENUM, "Auto (Light),None,Light,Normal", PROPERTY_USAGE_DEFAULT);
+#endif
_initial_set("interface/editor/main_font", "");
hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/editor/main_font_bold", "");
@@ -357,7 +430,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["interface/editor/single_window_mode"] = PropertyInfo(Variant::BOOL, "interface/editor/single_window_mode", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/hide_console_window", false);
_initial_set("interface/editor/save_each_scene_on_quit", true); // Regression
- _initial_set("interface/editor/quit_confirmation", true);
+
+ // Inspector
+ _initial_set("interface/inspector/max_array_dictionary_items_per_page", 20);
+ hints["interface/inspector/max_array_dictionary_items_per_page"] = PropertyInfo(Variant::INT, "interface/inspector/max_array_dictionary_items_per_page", PROPERTY_HINT_RANGE, "10,100,1", PROPERTY_USAGE_DEFAULT);
// Theme
_initial_set("interface/theme/preset", "Default");
@@ -370,6 +446,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["interface/theme/accent_color"] = PropertyInfo(Variant::COLOR, "interface/theme/accent_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/theme/contrast", 0.25);
hints["interface/theme/contrast"] = PropertyInfo(Variant::FLOAT, "interface/theme/contrast", PROPERTY_HINT_RANGE, "0.01, 1, 0.01");
+ _initial_set("interface/theme/icon_saturation", 1.0);
+ hints["interface/theme/icon_saturation"] = PropertyInfo(Variant::FLOAT, "interface/theme/icon_saturation", PROPERTY_HINT_RANGE, "0,2,0.01", PROPERTY_USAGE_DEFAULT);
_initial_set("interface/theme/relationship_line_opacity", 0.1);
hints["interface/theme/relationship_line_opacity"] = PropertyInfo(Variant::FLOAT, "interface/theme/relationship_line_opacity", PROPERTY_HINT_RANGE, "0.00, 1, 0.01");
_initial_set("interface/theme/highlight_tabs", false);
@@ -419,7 +497,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("docks/filesystem/always_show_folders", true);
// Property editor
- _initial_set("docks/property_editor/auto_refresh_interval", 0.3);
+ _initial_set("docks/property_editor/auto_refresh_interval", 0.2); //update 5 times per second by default
+ _initial_set("docks/property_editor/subresource_hue_tint", 0.75);
+ hints["docks/property_editor/subresource_hue_tint"] = PropertyInfo(Variant::FLOAT, "docks/property_editor/subresource_hue_tint", PROPERTY_HINT_RANGE, "0,1,0.01", PROPERTY_USAGE_DEFAULT);
/* Text editor */
@@ -521,6 +601,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("editors/3d/secondary_grid_color", Color(0.38, 0.38, 0.38, 0.5));
hints["editors/3d/secondary_grid_color"] = PropertyInfo(Variant::COLOR, "editors/3d/secondary_grid_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT);
+ // Use a similar color to the 2D editor selection.
+ _initial_set("editors/3d/selection_box_color", Color(1.0, 0.5, 0));
+ hints["editors/3d/selection_box_color"] = PropertyInfo(Variant::COLOR, "editors/3d/selection_box_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+
// If a line is a multiple of this, it uses the primary grid color.
// Use a power of 2 value by default as it's more common to use powers of 2 in level design.
_initial_set("editors/3d/primary_grid_steps", 8);
@@ -633,6 +717,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("editors/animation/onion_layers_past_color", Color(1, 0, 0));
_initial_set("editors/animation/onion_layers_future_color", Color(0, 1, 0));
+ // Visual editors
+ _initial_set("editors/visual_editors/minimap_opacity", 0.85);
+ hints["editors/visual_editors/minimap_opacity"] = PropertyInfo(Variant::FLOAT, "editors/visual_editors/minimap_opacity", PROPERTY_HINT_RANGE, "0.0,1.0,0.01", PROPERTY_USAGE_DEFAULT);
+
/* Run */
// Window placement
@@ -929,27 +1017,16 @@ void EditorSettings::create() {
_create_script_templates(dir->get_current_dir().plus_file("script_templates"));
- if (dir->change_dir("projects") != OK) {
- dir->make_dir("projects");
- } else {
- dir->change_dir("..");
- }
-
- // Validate/create project-specific config dir
-
- dir->change_dir("projects");
- String project_config_dir = ProjectSettings::get_singleton()->get_resource_path();
- if (project_config_dir.ends_with("/")) {
- project_config_dir = config_path.substr(0, project_config_dir.size() - 1);
- }
- project_config_dir = project_config_dir.get_file() + "-" + project_config_dir.md5_text();
-
- if (dir->change_dir(project_config_dir) != OK) {
- dir->make_dir(project_config_dir);
- } else {
- dir->change_dir("..");
+ {
+ // Validate/create project-specific editor settings dir.
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (da->change_dir(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH) != OK) {
+ Error err = da->make_dir_recursive(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH);
+ if (err || da->change_dir(EditorSettings::PROJECT_EDITOR_SETTINGS_PATH) != OK) {
+ ERR_FAIL_MSG("Failed to create '" + EditorSettings::PROJECT_EDITOR_SETTINGS_PATH + "' folder.");
+ }
+ }
}
- dir->change_dir("..");
// Validate editor config file
@@ -971,7 +1048,6 @@ void EditorSettings::create() {
singleton->save_changed_setting = true;
singleton->config_file_path = config_file_path;
- singleton->project_config_dir = project_config_dir;
singleton->settings_dir = config_dir;
singleton->data_dir = data_dir;
singleton->cache_dir = cache_dir;
@@ -1247,7 +1323,7 @@ String EditorSettings::get_settings_dir() const {
}
String EditorSettings::get_project_settings_dir() const {
- return get_settings_dir().plus_file("projects").plus_file(project_config_dir);
+ return EditorSettings::PROJECT_EDITOR_SETTINGS_PATH;
}
String EditorSettings::get_text_editor_themes_dir() const {
@@ -1259,7 +1335,7 @@ String EditorSettings::get_script_templates_dir() const {
}
String EditorSettings::get_project_script_templates_dir() const {
- return ProjectSettings::get_singleton()->get("editor/script_templates_search_path");
+ return ProjectSettings::get_singleton()->get("editor/script/templates_search_path");
}
// Cache directory
@@ -1476,7 +1552,7 @@ bool EditorSettings::is_default_text_editor_theme() {
Vector<String> EditorSettings::get_script_templates(const String &p_extension, const String &p_custom_path) {
Vector<String> templates;
String template_dir = get_script_templates_dir();
- if (!p_custom_path.empty()) {
+ if (!p_custom_path.is_empty()) {
template_dir = p_custom_path;
}
DirAccess *d = DirAccess::open(template_dir);
@@ -1513,12 +1589,39 @@ bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_
}
Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const {
- const Map<String, Ref<Shortcut>>::Element *E = shortcuts.find(p_name);
- if (!E) {
- return Ref<Shortcut>();
+ const Map<String, Ref<Shortcut>>::Element *SC = shortcuts.find(p_name);
+ if (SC) {
+ return SC->get();
+ }
+
+ // If no shortcut with the provided name is found in the list, check the built-in shortcuts.
+ // Use the first item in the action list for the shortcut event, since a shortcut can only have 1 linked event.
+
+ Ref<Shortcut> sc;
+ const Map<String, List<Ref<InputEvent>>>::Element *builtin_override = builtin_action_overrides.find(p_name);
+ if (builtin_override) {
+ sc.instance();
+ sc->set_shortcut(builtin_override->get().front()->get());
+ sc->set_name(InputMap::get_singleton()->get_builtin_display_name(p_name));
+ }
+
+ // If there was no override, check the default builtins to see if it has an InputEvent for the provided name.
+ if (sc.is_null()) {
+ const OrderedHashMap<String, List<Ref<InputEvent>>>::ConstElement builtin_default = InputMap::get_singleton()->get_builtins().find(p_name);
+ if (builtin_default) {
+ sc.instance();
+ sc->set_shortcut(builtin_default.get().front()->get());
+ sc->set_name(InputMap::get_singleton()->get_builtin_display_name(p_name));
+ }
}
- return E->get();
+ if (sc.is_valid()) {
+ // Add the shortcut to the list.
+ shortcuts[p_name] = sc;
+ return sc;
+ }
+
+ return Ref<Shortcut>();
}
void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) {
@@ -1584,6 +1687,66 @@ Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p
return sc;
}
+void EditorSettings::set_builtin_action_override(const String &p_name, const Array &p_events) {
+ List<Ref<InputEvent>> event_list;
+
+ // Override the whole list, since events may have their order changed or be added, removed or edited.
+ InputMap::get_singleton()->action_erase_events(p_name);
+ for (int i = 0; i < p_events.size(); i++) {
+ event_list.push_back(p_events[i]);
+ InputMap::get_singleton()->action_add_event(p_name, p_events[i]);
+ }
+
+ // Check if the provided event array is same as built-in. If it is, it does not need to be added to the overrides.
+ // Note that event order must also be the same.
+ bool same_as_builtin = true;
+ OrderedHashMap<String, List<Ref<InputEvent>>>::ConstElement builtin_default = InputMap::get_singleton()->get_builtins().find(p_name);
+ if (builtin_default) {
+ List<Ref<InputEvent>> builtin_events = builtin_default.get();
+
+ if (p_events.size() == builtin_events.size()) {
+ int event_idx = 0;
+
+ // Check equality of each event.
+ for (List<Ref<InputEvent>>::Element *E = builtin_events.front(); E; E = E->next()) {
+ if (!E->get()->shortcut_match(p_events[event_idx])) {
+ same_as_builtin = false;
+ break;
+ }
+ event_idx++;
+ }
+ } else {
+ same_as_builtin = false;
+ }
+ }
+
+ if (same_as_builtin && builtin_action_overrides.has(p_name)) {
+ builtin_action_overrides.erase(p_name);
+ } else {
+ builtin_action_overrides[p_name] = event_list;
+ }
+
+ // Update the shortcut (if it is used somewhere in the editor) to be the first event of the new list.
+ if (shortcuts.has(p_name)) {
+ shortcuts[p_name]->set_shortcut(event_list.front()->get());
+ }
+}
+
+const Array EditorSettings::get_builtin_action_overrides(const String &p_name) const {
+ const Map<String, List<Ref<InputEvent>>>::Element *AO = builtin_action_overrides.find(p_name);
+ if (AO) {
+ Array event_array;
+
+ List<Ref<InputEvent>> events_list = AO->get();
+ for (List<Ref<InputEvent>>::Element *E = events_list.front(); E; E = E->next()) {
+ event_array.push_back(E->get());
+ }
+ return event_array;
+ }
+
+ return Array();
+}
+
void EditorSettings::notify_changes() {
_THREAD_SAFE_METHOD_
@@ -1622,6 +1785,8 @@ void EditorSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_recent_dirs", "dirs"), &EditorSettings::set_recent_dirs);
ClassDB::bind_method(D_METHOD("get_recent_dirs"), &EditorSettings::get_recent_dirs);
+ ClassDB::bind_method(D_METHOD("set_builtin_action_override", "name", "actions_list"), &EditorSettings::set_builtin_action_override);
+
ADD_SIGNAL(MethodInfo("settings_changed"));
BIND_CONSTANT(NOTIFICATION_EDITOR_SETTINGS_CHANGED);
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 3061da4d43..e5f8527faf 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,6 +46,7 @@ class EditorSettings : public Resource {
_THREAD_SAFE_CLASS_
public:
+ inline static const String PROJECT_EDITOR_SETTINGS_PATH = "res://.godot/editor";
struct Plugin {
EditorPlugin *instance = nullptr;
String path;
@@ -83,7 +84,8 @@ private:
int last_order;
Ref<Resource> clipboard;
- Map<String, Ref<Shortcut>> shortcuts;
+ mutable Map<String, Ref<Shortcut>> shortcuts;
+ Map<String, List<Ref<InputEvent>>> builtin_action_overrides;
String resource_path;
String settings_dir;
@@ -185,6 +187,9 @@ public:
Ref<Shortcut> get_shortcut(const String &p_name) const;
void get_shortcut_list(List<String> *r_shortcuts);
+ void set_builtin_action_override(const String &p_name, const Array &p_events);
+ const Array get_builtin_action_overrides(const String &p_name) const;
+
void notify_changes();
EditorSettings();
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 4a37d26a26..618d953c56 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h
index d000ebd151..248a13f7b6 100644
--- a/editor/editor_spin_slider.h
+++ b/editor/editor_spin_slider.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_sub_scene.cpp b/editor/editor_sub_scene.cpp
deleted file mode 100644
index f794babc24..0000000000
--- a/editor/editor_sub_scene.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*************************************************************************/
-/* editor_sub_scene.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "editor_sub_scene.h"
-
-#include "editor/editor_node.h"
-#include "scene/gui/margin_container.h"
-#include "scene/resources/packed_scene.h"
-
-void EditorSubScene::_path_selected(const String &p_path) {
- path->set_text(p_path);
- _path_changed(p_path);
-}
-
-void EditorSubScene::_path_changed(const String &p_path) {
- tree->clear();
-
- if (scene) {
- memdelete(scene);
- scene = nullptr;
- }
-
- if (p_path == "") {
- return;
- }
-
- Ref<PackedScene> ps = ResourceLoader::load(p_path, "PackedScene");
-
- if (ps.is_null()) {
- return;
- }
-
- scene = ps->instance();
- if (!scene) {
- return;
- }
-
- _fill_tree(scene, nullptr);
-}
-
-void EditorSubScene::_path_browse() {
- file_dialog->popup_file_dialog();
-}
-
-void EditorSubScene::_notification(int p_what) {
- if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- if (is_visible() && scene == nullptr) {
- _path_browse();
- }
- }
-}
-
-void EditorSubScene::_fill_tree(Node *p_node, TreeItem *p_parent) {
- TreeItem *it = tree->create_item(p_parent);
- it->set_metadata(0, p_node);
- it->set_text(0, p_node->get_name());
- it->set_editable(0, false);
- it->set_selectable(0, true);
- it->set_icon(0, EditorNode::get_singleton()->get_object_icon(p_node, "Node"));
-
- for (int i = 0; i < p_node->get_child_count(); i++) {
- Node *c = p_node->get_child(i);
- if (c->get_owner() != scene) {
- continue;
- }
- _fill_tree(c, it);
- }
-}
-
-void EditorSubScene::_selected_changed() {
- TreeItem *item = tree->get_selected();
- ERR_FAIL_COND(!item);
- Node *n = item->get_metadata(0);
-
- if (!n || !selection.find(n)) {
- selection.clear();
- is_root = false;
- }
-}
-
-void EditorSubScene::_item_multi_selected(Object *p_object, int p_cell, bool p_selected) {
- if (!is_root) {
- TreeItem *item = Object::cast_to<TreeItem>(p_object);
- ERR_FAIL_COND(!item);
-
- Node *n = item->get_metadata(0);
-
- if (!n) {
- return;
- }
- if (p_selected) {
- if (n == scene) {
- is_root = true;
- selection.clear();
- }
- selection.push_back(n);
- } else {
- List<Node *>::Element *E = selection.find(n);
-
- if (E) {
- selection.erase(E);
- }
- }
- }
-}
-
-void EditorSubScene::_item_activated() {
- _ok_pressed(); // From AcceptDialog.
-}
-
-void EditorSubScene::_remove_selection_child(Node *p_node) {
- if (p_node->get_child_count() > 0) {
- for (int i = 0; i < p_node->get_child_count(); i++) {
- Node *c = p_node->get_child(i);
- List<Node *>::Element *E = selection.find(c);
- if (E) {
- selection.move_to_back(E);
- selection.pop_back();
- }
- if (c->get_child_count() > 0) {
- _remove_selection_child(c);
- }
- }
- }
-}
-
-void EditorSubScene::ok_pressed() {
- if (selection.size() <= 0) {
- return;
- }
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
- Node *c = E->get();
- _remove_selection_child(c);
- }
- emit_signal("subscene_selected");
- hide();
- clear();
-}
-
-void EditorSubScene::_reown(Node *p_node, List<Node *> *p_to_reown) {
- if (p_node == scene) {
- scene->set_filename("");
- p_to_reown->push_back(p_node);
- } else if (p_node->get_owner() == scene) {
- p_to_reown->push_back(p_node);
- }
-
- for (int i = 0; i < p_node->get_child_count(); i++) {
- Node *c = p_node->get_child(i);
- _reown(c, p_to_reown);
- }
-}
-
-void EditorSubScene::move(Node *p_new_parent, Node *p_new_owner) {
- if (!scene) {
- return;
- }
-
- if (selection.size() <= 0) {
- return;
- }
-
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
- Node *selnode = E->get();
- if (!selnode) {
- return;
- }
- List<Node *> to_reown;
- _reown(selnode, &to_reown);
- if (selnode != scene) {
- selnode->get_parent()->remove_child(selnode);
- }
-
- p_new_parent->add_child(selnode);
- for (List<Node *>::Element *F = to_reown.front(); F; F = F->next()) {
- F->get()->set_owner(p_new_owner);
- }
- }
- if (!is_root) {
- memdelete(scene);
- }
- scene = nullptr;
- //return selnode;
-}
-
-void EditorSubScene::clear() {
- path->set_text("");
- _path_changed("");
-}
-
-void EditorSubScene::_bind_methods() {
- ADD_SIGNAL(MethodInfo("subscene_selected"));
-}
-
-EditorSubScene::EditorSubScene() {
- scene = nullptr;
- is_root = false;
-
- set_title(TTR("Select Node(s) to Import"));
- set_hide_on_ok(false);
-
- VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
- //set_child_rect(vb);
-
- HBoxContainer *hb = memnew(HBoxContainer);
- path = memnew(LineEdit);
- path->connect("text_entered", callable_mp(this, &EditorSubScene::_path_changed));
- hb->add_child(path);
- path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- Button *b = memnew(Button);
- b->set_text(TTR("Browse"));
- hb->add_child(b);
- b->connect("pressed", callable_mp(this, &EditorSubScene::_path_browse));
- vb->add_margin_child(TTR("Scene Path:"), hb);
-
- tree = memnew(Tree);
- tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- vb->add_margin_child(TTR("Import From Node:"), tree, true);
- tree->set_select_mode(Tree::SELECT_MULTI);
- tree->connect("multi_selected", callable_mp(this, &EditorSubScene::_item_multi_selected));
- //tree->connect("nothing_selected", this, "_deselect_items");
- tree->connect("cell_selected", callable_mp(this, &EditorSubScene::_selected_changed));
-
- tree->connect("item_activated", callable_mp(this, &EditorSubScene::_item_activated), make_binds(), CONNECT_DEFERRED);
-
- file_dialog = memnew(EditorFileDialog);
- List<String> extensions;
- ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
-
- for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
- file_dialog->add_filter("*." + E->get());
- }
-
- file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
- add_child(file_dialog);
- file_dialog->connect("file_selected", callable_mp(this, &EditorSubScene::_path_selected));
-}
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 7582c2073f..fe748b81c3 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,16 +41,16 @@
#include "modules/svg/image_loader_svg.h"
#endif
-static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_botton, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1, bool p_draw_center = true) {
+static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) {
Ref<StyleBoxTexture> style(memnew(StyleBoxTexture));
style->set_texture(p_texture);
style->set_margin_size(SIDE_LEFT, p_left * EDSCALE);
style->set_margin_size(SIDE_RIGHT, p_right * EDSCALE);
- style->set_margin_size(SIDE_BOTTOM, p_botton * EDSCALE);
+ style->set_margin_size(SIDE_BOTTOM, p_bottom * EDSCALE);
style->set_margin_size(SIDE_TOP, p_top * EDSCALE);
style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE);
style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE);
- style->set_default_margin(SIDE_BOTTOM, p_margin_botton * EDSCALE);
+ style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE);
style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE);
style->set_draw_center(p_draw_center);
return style;
@@ -92,6 +92,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
Ref<ImageTexture> texture(memnew(ImageTexture));
Ref<Image> img = p_texture->get_data();
+ img = img->duplicate();
if (p_flip_y) {
img->flip_y();
@@ -105,7 +106,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
}
#ifdef MODULE_SVG_ENABLED
-static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, bool p_force_filter = false) {
+static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, float p_saturation = 1.0) {
Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);
@@ -115,6 +116,9 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color,
const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale);
ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color);
+ if (p_saturation != 1.0) {
+ img->adjust_bcs(1.0, 1.0, p_saturation);
+ }
icon->create_from_image(img); // in this case filter really helps
return icon;
@@ -125,7 +129,7 @@ static Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color,
#define ADD_CONVERT_COLOR(dictionary, old_color, new_color) dictionary[Color::html(old_color)] = Color::html(new_color)
#endif
-void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false) {
+void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false, float p_icon_saturation = 1.0) {
#ifdef MODULE_SVG_ENABLED
// The default icon theme is designed to be used for a dark theme.
// This dictionary stores color codes to convert to other colors
@@ -238,14 +242,19 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
if (!p_only_thumbs) {
for (int i = 0; i < editor_icons_count; i++) {
float icon_scale = EDSCALE;
+ float saturation = p_icon_saturation;
// Always keep the DefaultProjectIcon at the default size
if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0) {
icon_scale = 1.0f;
}
+ if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0 || strcmp(editor_icons_names[i], "Godot") == 0 || strcmp(editor_icons_names[i], "Logo") == 0) {
+ saturation = 1.0;
+ }
+
const int is_exception = exceptions.has(editor_icons_names[i]);
- const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, icon_scale);
+ const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, icon_scale, saturation);
p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
}
@@ -289,6 +298,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Color accent_color = EDITOR_GET("interface/theme/accent_color");
Color base_color = EDITOR_GET("interface/theme/base_color");
float contrast = EDITOR_GET("interface/theme/contrast");
+ float icon_saturation = EDITOR_GET("interface/theme/icon_saturation");
float relationship_line_opacity = EDITOR_GET("interface/theme/relationship_line_opacity");
String preset = EDITOR_GET("interface/theme/preset");
@@ -375,23 +385,26 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color contrast_color_2 = base_color.lerp(mono_color, MAX(contrast * 1.5, default_contrast * 1.5));
const Color font_color = mono_color.lerp(base_color, 0.25);
- const Color font_color_hl = mono_color.lerp(base_color, 0.15);
- const Color font_color_disabled = Color(mono_color.r, mono_color.g, mono_color.b, 0.3);
- const Color font_color_selection = accent_color * Color(1, 1, 1, 0.4);
- const Color color_disabled = mono_color.inverted().lerp(base_color, 0.7);
- const Color color_disabled_bg = mono_color.inverted().lerp(base_color, 0.9);
-
- Color icon_color_hover = Color(1, 1, 1) * (dark_theme ? 1.15 : 1.45);
- icon_color_hover.a = 1.0;
+ const Color font_hover_color = mono_color.lerp(base_color, 0.15);
+ const Color font_disabled_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.3);
+ const Color selection_color = accent_color * Color(1, 1, 1, 0.4);
+ const Color disabled_color = mono_color.inverted().lerp(base_color, 0.7);
+ const Color disabled_bg_color = mono_color.inverted().lerp(base_color, 0.9);
+
+ Color icon_hover_color = Color(1, 1, 1) * (dark_theme ? 1.15 : 1.45);
+ icon_hover_color.a = 1.0;
// Make the pressed icon color overbright because icons are not completely white on a dark theme.
// On a light theme, icons are dark, so we need to modulate them with an even brighter color.
- Color icon_color_pressed = accent_color * (dark_theme ? 1.15 : 3.5);
- icon_color_pressed.a = 1.0;
+ Color icon_pressed_color = accent_color * (dark_theme ? 1.15 : 3.5);
+ icon_pressed_color.a = 1.0;
const Color separator_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.1);
const Color highlight_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.2);
+ float prev_icon_saturation = theme->has_color("icon_saturation", "Editor") ? theme->get_color("icon_saturation", "Editor").r : 1.0;
+
+ theme->set_color("icon_saturation", "Editor", Color(icon_saturation, icon_saturation, icon_saturation)); //can't save single float in theme, so using color
theme->set_color("accent_color", "Editor", accent_color);
theme->set_color("highlight_color", "Editor", highlight_color);
theme->set_color("base_color", "Editor", base_color);
@@ -408,8 +421,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("axis_z_color", "Editor", Color(0.16, 0.55, 0.96));
theme->set_color("font_color", "Editor", font_color);
- theme->set_color("highlighted_font_color", "Editor", font_color_hl);
- theme->set_color("disabled_font_color", "Editor", font_color_disabled);
+ theme->set_color("highlighted_font_color", "Editor", font_hover_color);
+ theme->set_color("disabled_font_color", "Editor", font_disabled_color);
theme->set_color("mono_color", "Editor", mono_color);
@@ -443,13 +456,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
//Register icons + font
// the resolution and the icon color (dark_theme bool) has not changed, so we do not regenerate the icons
- if (p_theme != nullptr && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && (bool)p_theme->get_constant("dark_theme", "Editor") == dark_theme) {
+ if (p_theme != nullptr && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && (bool)p_theme->get_constant("dark_theme", "Editor") == dark_theme && prev_icon_saturation == icon_saturation) {
// register already generated icons
for (int i = 0; i < editor_icons_count; i++) {
theme->set_icon(editor_icons_names[i], "EditorIcons", p_theme->get_icon(editor_icons_names[i], "EditorIcons"));
}
} else {
- editor_register_and_generate_icons(theme, dark_theme, thumb_size);
+ editor_register_and_generate_icons(theme, dark_theme, thumb_size, false, icon_saturation);
}
// thumbnail size has changed, so we regenerate the medium sizes
if (p_theme != nullptr && fabs((double)p_theme->get_constant("thumb_size", "Editor") - thumb_size) > 0.00001) {
@@ -485,8 +498,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_widget->set_border_color(dark_color_2);
Ref<StyleBoxFlat> style_widget_disabled = style_widget->duplicate();
- style_widget_disabled->set_border_color(color_disabled);
- style_widget_disabled->set_bg_color(color_disabled_bg);
+ style_widget_disabled->set_border_color(disabled_color);
+ style_widget_disabled->set_bg_color(disabled_bg_color);
Ref<StyleBoxFlat> style_widget_focus = style_widget->duplicate();
style_widget_focus->set_border_color(accent_color);
@@ -550,8 +563,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_tab_unselected->set_border_color(dark_color_2);
Ref<StyleBoxFlat> style_tab_disabled = style_tab_selected->duplicate();
- style_tab_disabled->set_bg_color(color_disabled_bg);
- style_tab_disabled->set_border_color(color_disabled);
+ style_tab_disabled->set_bg_color(disabled_bg_color);
+ style_tab_disabled->set_border_color(disabled_color);
// Editor background
theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(background_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size));
@@ -600,7 +613,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("disabled", "PopupMenu", style_menu);
theme->set_color("font_color", "MenuButton", font_color);
- theme->set_color("font_color_hover", "MenuButton", font_color_hl);
+ theme->set_color("font_hover_color", "MenuButton", font_hover_color);
theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border);
@@ -612,11 +625,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("disabled", "Button", style_widget_disabled);
theme->set_color("font_color", "Button", font_color);
- theme->set_color("font_color_hover", "Button", font_color_hl);
- theme->set_color("font_color_pressed", "Button", accent_color);
- theme->set_color("font_color_disabled", "Button", font_color_disabled);
- theme->set_color("icon_color_hover", "Button", icon_color_hover);
- theme->set_color("icon_color_pressed", "Button", icon_color_pressed);
+ theme->set_color("font_hover_color", "Button", font_hover_color);
+ theme->set_color("font_pressed_color", "Button", accent_color);
+ theme->set_color("font_disabled_color", "Button", font_disabled_color);
+ theme->set_color("icon_hover_color", "Button", icon_hover_color);
+ theme->set_color("icon_pressed_color", "Button", icon_pressed_color);
// OptionButton
theme->set_stylebox("focus", "OptionButton", style_widget_focus);
@@ -632,10 +645,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("disabled_mirrored", "OptionButton", style_widget_disabled);
theme->set_color("font_color", "OptionButton", font_color);
- theme->set_color("font_color_hover", "OptionButton", font_color_hl);
- theme->set_color("font_color_pressed", "OptionButton", accent_color);
- theme->set_color("font_color_disabled", "OptionButton", font_color_disabled);
- theme->set_color("icon_color_hover", "OptionButton", icon_color_hover);
+ theme->set_color("font_hover_color", "OptionButton", font_hover_color);
+ theme->set_color("font_pressed_color", "OptionButton", accent_color);
+ theme->set_color("font_disabled_color", "OptionButton", font_disabled_color);
+ theme->set_color("icon_hover_color", "OptionButton", icon_hover_color);
theme->set_icon("arrow", "OptionButton", theme->get_icon("GuiOptionArrow", "EditorIcons"));
theme->set_constant("arrow_margin", "OptionButton", default_margin_size * EDSCALE);
theme->set_constant("modulate_arrow", "OptionButton", true);
@@ -658,10 +671,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("off_disabled_mirrored", "CheckButton", theme->get_icon("GuiToggleOffDisabledMirrored", "EditorIcons"));
theme->set_color("font_color", "CheckButton", font_color);
- theme->set_color("font_color_hover", "CheckButton", font_color_hl);
- theme->set_color("font_color_pressed", "CheckButton", accent_color);
- theme->set_color("font_color_disabled", "CheckButton", font_color_disabled);
- theme->set_color("icon_color_hover", "CheckButton", icon_color_hover);
+ theme->set_color("font_hover_color", "CheckButton", font_hover_color);
+ theme->set_color("font_pressed_color", "CheckButton", accent_color);
+ theme->set_color("font_disabled_color", "CheckButton", font_disabled_color);
+ theme->set_color("icon_hover_color", "CheckButton", icon_hover_color);
theme->set_constant("hseparation", "CheckButton", 4 * EDSCALE);
theme->set_constant("check_vadjust", "CheckButton", 0 * EDSCALE);
@@ -683,10 +696,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon("GuiRadioUnchecked", "EditorIcons"));
theme->set_color("font_color", "CheckBox", font_color);
- theme->set_color("font_color_hover", "CheckBox", font_color_hl);
- theme->set_color("font_color_pressed", "CheckBox", accent_color);
- theme->set_color("font_color_disabled", "CheckBox", font_color_disabled);
- theme->set_color("icon_color_hover", "CheckBox", icon_color_hover);
+ theme->set_color("font_hover_color", "CheckBox", font_hover_color);
+ theme->set_color("font_pressed_color", "CheckBox", accent_color);
+ theme->set_color("font_disabled_color", "CheckBox", font_disabled_color);
+ theme->set_color("icon_hover_color", "CheckBox", icon_hover_color);
theme->set_constant("hseparation", "CheckBox", 4 * EDSCALE);
theme->set_constant("check_vadjust", "CheckBox", 0 * EDSCALE);
@@ -697,9 +710,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// PopupMenu
const int popup_menu_margin_size = default_margin_size * 1.5 * EDSCALE;
Ref<StyleBoxFlat> style_popup_menu = style_popup->duplicate();
- style_popup_menu->set_default_margin(SIDE_LEFT, popup_menu_margin_size);
+ // Use 1 pixel for the sides, since if 0 is used, the highlight of hovered items is drawn
+ // on top of the popup border. This causes a 'gap' in the panel border when an item is highlighted,
+ // and it looks weird. 1px solves this.
+ style_popup_menu->set_default_margin(SIDE_LEFT, 1 * EDSCALE);
style_popup_menu->set_default_margin(SIDE_TOP, popup_menu_margin_size);
- style_popup_menu->set_default_margin(SIDE_RIGHT, popup_menu_margin_size);
+ style_popup_menu->set_default_margin(SIDE_RIGHT, 1 * EDSCALE);
style_popup_menu->set_default_margin(SIDE_BOTTOM, popup_menu_margin_size);
theme->set_stylebox("panel", "PopupMenu", style_popup_menu);
@@ -708,10 +724,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("labeled_separator_right", "PopupMenu", style_popup_labeled_separator_right);
theme->set_color("font_color", "PopupMenu", font_color);
- theme->set_color("font_color_hover", "PopupMenu", font_color_hl);
- theme->set_color("font_color_accel", "PopupMenu", font_color_disabled);
- theme->set_color("font_color_disabled", "PopupMenu", font_color_disabled);
- theme->set_color("font_color_separator", "PopupMenu", font_color_disabled);
+ theme->set_color("font_hover_color", "PopupMenu", font_hover_color);
+ theme->set_color("font_accelerator_color", "PopupMenu", font_disabled_color);
+ theme->set_color("font_disabled_color", "PopupMenu", font_disabled_color);
+ theme->set_color("font_separator_color", "PopupMenu", font_disabled_color);
theme->set_icon("checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));
theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiRadioChecked", "EditorIcons"));
@@ -721,16 +737,63 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon("GuiVisibilityHidden", "EditorIcons"));
theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon("GuiVisibilityVisible", "EditorIcons"));
theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons"));
+
theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size + 1) * EDSCALE);
+ theme->set_constant("item_start_padding", "PopupMenu", popup_menu_margin_size * EDSCALE);
+ theme->set_constant("item_end_padding", "PopupMenu", popup_menu_margin_size * EDSCALE);
+
+ for (int i = 0; i < 16; i++) {
+ Color si_base_color = accent_color;
+
+ float hue_rotate = (i * 2 % 16) / 16.0;
+ si_base_color.set_hsv(Math::fmod(float(si_base_color.get_h() + hue_rotate), float(1.0)), si_base_color.get_s(), si_base_color.get_v());
+ si_base_color = accent_color.lerp(si_base_color, float(EDITOR_GET("docks/property_editor/subresource_hue_tint")));
+
+ Ref<StyleBoxFlat> sub_inspector_bg;
+
+ sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(si_base_color, 0.08), 2, 0, 2, 2);
+
+ sub_inspector_bg->set_border_width(SIDE_LEFT, 2);
+ sub_inspector_bg->set_border_width(SIDE_RIGHT, 2);
+ sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2);
+ sub_inspector_bg->set_border_width(SIDE_TOP, 2);
+ sub_inspector_bg->set_default_margin(SIDE_LEFT, 3);
+ sub_inspector_bg->set_default_margin(SIDE_RIGHT, 3);
+ sub_inspector_bg->set_default_margin(SIDE_BOTTOM, 10);
+ sub_inspector_bg->set_default_margin(SIDE_TOP, 5);
+ sub_inspector_bg->set_border_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8));
+ sub_inspector_bg->set_draw_center(true);
- Ref<StyleBoxFlat> sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(accent_color, 0.08), 2, 0, 2, 2);
- sub_inspector_bg->set_border_width(SIDE_LEFT, 2);
- sub_inspector_bg->set_border_width(SIDE_RIGHT, 2);
- sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2);
- sub_inspector_bg->set_border_color(accent_color * Color(1, 1, 1, 0.3));
- sub_inspector_bg->set_draw_center(true);
+ theme->set_stylebox("sub_inspector_bg" + itos(i), "Editor", sub_inspector_bg);
+
+ Ref<StyleBoxFlat> bg_color;
+ bg_color.instance();
+ bg_color->set_bg_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8));
+ bg_color->set_border_width_all(0);
+
+ Ref<StyleBoxFlat> bg_color_selected;
+ bg_color_selected.instance();
+ bg_color_selected->set_border_width_all(0);
+ bg_color_selected->set_bg_color(si_base_color * Color(0.8, 0.8, 0.8, 0.8));
+
+ theme->set_stylebox("sub_inspector_property_bg" + itos(i), "Editor", bg_color);
+ theme->set_stylebox("sub_inspector_property_bg_selected" + itos(i), "Editor", bg_color_selected);
+ }
+
+ theme->set_color("sub_inspector_property_color", "Editor", dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1));
+ theme->set_constant("sub_inspector_font_offset", "Editor", 4 * EDSCALE);
+
+ Ref<StyleBoxFlat> style_property_bg = style_default->duplicate();
+ style_property_bg->set_bg_color(highlight_color);
+ style_property_bg->set_border_width_all(0);
+
+ theme->set_constant("font_offset", "EditorProperty", 1 * EDSCALE);
+ theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg);
+ theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE);
+ theme->set_color("error_color", "EditorProperty", error_color);
+ theme->set_color("property_color", "EditorProperty", property_color);
- theme->set_stylebox("sub_inspector_bg", "Editor", sub_inspector_bg);
theme->set_constant("inspector_margin", "Editor", 8 * EDSCALE);
// Tree & ItemList background
@@ -753,9 +816,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("custom_button", "Tree", make_empty_stylebox());
theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox());
theme->set_stylebox("custom_button_hover", "Tree", style_widget);
- theme->set_color("custom_button_font_highlight", "Tree", font_color_hl);
+ theme->set_color("custom_button_font_highlight", "Tree", font_hover_color);
theme->set_color("font_color", "Tree", font_color);
- theme->set_color("font_color_selected", "Tree", mono_color);
+ theme->set_color("font_selected_color", "Tree", mono_color);
theme->set_color("title_button_color", "Tree", font_color);
theme->set_color("guide_color", "Tree", guide_color);
theme->set_color("relationship_line_color", "Tree", relationship_line_color);
@@ -826,7 +889,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("bg_focus", "ItemList", style_focus);
theme->set_stylebox("bg", "ItemList", style_itemlist_bg);
theme->set_color("font_color", "ItemList", font_color);
- theme->set_color("font_color_selected", "ItemList", mono_color);
+ theme->set_color("font_selected_color", "ItemList", mono_color);
theme->set_color("guide_color", "ItemList", guide_color);
theme->set_constant("vseparation", "ItemList", 3 * EDSCALE);
theme->set_constant("hseparation", "ItemList", 3 * EDSCALE);
@@ -834,16 +897,16 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("line_separation", "ItemList", 3 * EDSCALE);
// Tabs & TabContainer
- theme->set_stylebox("tab_fg", "TabContainer", style_tab_selected);
- theme->set_stylebox("tab_bg", "TabContainer", style_tab_unselected);
+ theme->set_stylebox("tab_selected", "TabContainer", style_tab_selected);
+ theme->set_stylebox("tab_unselected", "TabContainer", style_tab_unselected);
theme->set_stylebox("tab_disabled", "TabContainer", style_tab_disabled);
- theme->set_stylebox("tab_fg", "Tabs", style_tab_selected);
- theme->set_stylebox("tab_bg", "Tabs", style_tab_unselected);
+ theme->set_stylebox("tab_selected", "Tabs", style_tab_selected);
+ theme->set_stylebox("tab_unselected", "Tabs", style_tab_unselected);
theme->set_stylebox("tab_disabled", "Tabs", style_tab_disabled);
- theme->set_color("font_color_fg", "TabContainer", font_color);
- theme->set_color("font_color_bg", "TabContainer", font_color_disabled);
- theme->set_color("font_color_fg", "Tabs", font_color);
- theme->set_color("font_color_bg", "Tabs", font_color_disabled);
+ theme->set_color("font_selected_color", "TabContainer", font_color);
+ theme->set_color("font_unselected_color", "TabContainer", font_disabled_color);
+ theme->set_color("font_selected_color", "Tabs", font_color);
+ theme->set_color("font_unselected_color", "Tabs", font_disabled_color);
theme->set_icon("menu", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons"));
theme->set_icon("menu_highlight", "TabContainer", theme->get_icon("GuiTabMenuHl", "EditorIcons"));
theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected);
@@ -891,7 +954,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("DebuggerPanel", "EditorStyles", style_panel_debugger);
Ref<StyleBoxFlat> style_panel_invisible_top = style_content_panel->duplicate();
- int stylebox_offset = theme->get_font("tab_fg", "TabContainer")->get_height(theme->get_font_size("tab_fg", "TabContainer")) + theme->get_stylebox("tab_fg", "TabContainer")->get_minimum_size().height + theme->get_stylebox("panel", "TabContainer")->get_default_margin(SIDE_TOP);
+ int stylebox_offset = theme->get_font("tab_selected", "TabContainer")->get_height(theme->get_font_size("tab_selected", "TabContainer")) + theme->get_stylebox("tab_selected", "TabContainer")->get_minimum_size().height + theme->get_stylebox("panel", "TabContainer")->get_default_margin(SIDE_TOP);
style_panel_invisible_top->set_expand_margin_size(SIDE_TOP, -stylebox_offset);
style_panel_invisible_top->set_default_margin(SIDE_TOP, 0);
theme->set_stylebox("BottomPanelDebuggerOverride", "EditorStyles", style_panel_invisible_top);
@@ -901,11 +964,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("focus", "LineEdit", style_widget_focus);
theme->set_stylebox("read_only", "LineEdit", style_widget_disabled);
theme->set_icon("clear", "LineEdit", theme->get_icon("GuiClose", "EditorIcons"));
- theme->set_color("read_only", "LineEdit", font_color_disabled);
+ theme->set_color("read_only", "LineEdit", font_disabled_color);
theme->set_color("font_color", "LineEdit", font_color);
- theme->set_color("font_color_selected", "LineEdit", mono_color);
+ theme->set_color("font_selected_color", "LineEdit", mono_color);
theme->set_color("cursor_color", "LineEdit", font_color);
- theme->set_color("selection_color", "LineEdit", font_color_selection);
+ theme->set_color("selection_color", "LineEdit", selection_color);
theme->set_color("clear_button_color", "LineEdit", font_color);
theme->set_color("clear_button_color_pressed", "LineEdit", accent_color);
@@ -918,7 +981,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("space", "TextEdit", theme->get_icon("GuiSpace", "EditorIcons"));
theme->set_color("font_color", "TextEdit", font_color);
theme->set_color("caret_color", "TextEdit", font_color);
- theme->set_color("selection_color", "TextEdit", font_color_selection);
+ theme->set_color("selection_color", "TextEdit", selection_color);
// CodeEdit
theme->set_stylebox("normal", "CodeEdit", style_widget);
@@ -932,7 +995,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("executing_line", "CodeEdit", theme->get_icon("MainPlay", "EditorIcons"));
theme->set_color("font_color", "CodeEdit", font_color);
theme->set_color("caret_color", "CodeEdit", font_color);
- theme->set_color("selection_color", "CodeEdit", font_color_selection);
+ theme->set_color("selection_color", "CodeEdit", selection_color);
// H/VSplitContainer
theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon("GuiVsplitBg", "EditorIcons"), 1, 1, 1, 1));
@@ -1023,7 +1086,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
//RichTextLabel
theme->set_color("default_color", "RichTextLabel", font_color);
- theme->set_color("font_color_shadow", "RichTextLabel", Color(0, 0, 0, 0));
+ theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0));
theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * EDSCALE);
theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * EDSCALE);
theme->set_constant("shadow_as_outline", "RichTextLabel", 0 * EDSCALE);
@@ -1039,7 +1102,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Label
theme->set_stylebox("normal", "Label", style_empty);
theme->set_color("font_color", "Label", font_color);
- theme->set_color("font_color_shadow", "Label", Color(0, 0, 0, 0));
+ theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0));
theme->set_constant("shadow_offset_x", "Label", 1 * EDSCALE);
theme->set_constant("shadow_offset_y", "Label", 1 * EDSCALE);
theme->set_constant("shadow_as_outline", "Label", 0 * EDSCALE);
@@ -1048,9 +1111,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// LinkButton
theme->set_stylebox("focus", "LinkButton", style_empty);
theme->set_color("font_color", "LinkButton", font_color);
- theme->set_color("font_color_hover", "LinkButton", font_color_hl);
- theme->set_color("font_color_pressed", "LinkButton", accent_color);
- theme->set_color("font_color_disabled", "LinkButton", font_color_disabled);
+ theme->set_color("font_hover_color", "LinkButton", font_hover_color);
+ theme->set_color("font_pressed_color", "LinkButton", accent_color);
+ theme->set_color("font_disabled_color", "LinkButton", font_disabled_color);
// TooltipPanel
Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate();
@@ -1063,7 +1126,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
style_tooltip->set_border_width_all(border_width);
style_tooltip->set_border_color(mono_color);
theme->set_color("font_color", "TooltipLabel", font_color.inverted());
- theme->set_color("font_color_shadow", "TooltipLabel", mono_color.inverted() * Color(1, 1, 1, 0.1));
+ theme->set_color("font_shadow_color", "TooltipLabel", mono_color.inverted() * Color(1, 1, 1, 0.1));
theme->set_stylebox("panel", "TooltipPanel", style_tooltip);
// PopupPanel
@@ -1098,7 +1161,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("bezier_len_neg", "GraphEdit", 160 * EDSCALE);
// GraphEditMinimap
- theme->set_stylebox("bg", "GraphEditMinimap", make_flat_stylebox(dark_color_1, 0, 0, 0, 0));
+ Ref<StyleBoxFlat> style_minimap_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0);
+ style_minimap_bg->set_border_color(dark_color_3);
+ style_minimap_bg->set_border_width_all(1);
+ theme->set_stylebox("bg", "GraphEditMinimap", style_minimap_bg);
+
Ref<StyleBoxFlat> style_minimap_camera;
Ref<StyleBoxFlat> style_minimap_node;
if (dark_theme) {
@@ -1115,9 +1182,15 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera);
theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node);
- Ref<Texture2D> resizer_icon = theme->get_icon("GuiResizer", "EditorIcons");
- theme->set_icon("resizer", "GraphEditMinimap", flip_icon(resizer_icon, true, true));
- theme->set_color("resizer_color", "GraphEditMinimap", Color(1, 1, 1, 0.65));
+ Ref<Texture2D> minimap_resizer_icon = theme->get_icon("GuiResizer", "EditorIcons");
+ Color minimap_resizer_color;
+ if (dark_theme) {
+ minimap_resizer_color = Color(1, 1, 1, 0.65);
+ } else {
+ minimap_resizer_color = Color(0, 0, 0, 0.65);
+ }
+ theme->set_icon("resizer", "GraphEditMinimap", flip_icon(minimap_resizer_icon, true, true));
+ theme->set_color("resizer_color", "GraphEditMinimap", minimap_resizer_color);
// GraphNode
const float mv = dark_theme ? 0.0 : 1.0;
@@ -1198,7 +1271,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Use a different color for folder icons to make them easier to distinguish from files.
// On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color.
theme->set_color("folder_icon_modulate", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(accent_color, 0.7));
- theme->set_color("files_disabled", "FileDialog", font_color_disabled);
+ theme->set_color("files_disabled", "FileDialog", font_disabled_color);
// color picker
theme->set_constant("margin", "ColorPicker", popup_margin_size);
@@ -1210,6 +1283,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("add_preset", "ColorPicker", theme->get_icon("Add", "EditorIcons"));
theme->set_icon("preset_bg", "ColorPicker", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon("OverbrightIndicator", "EditorIcons"));
+ theme->set_icon("bar_arrow", "ColorPicker", theme->get_icon("ColorPickerBarArrow", "EditorIcons"));
theme->set_icon("bg", "ColorPickerButton", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
@@ -1251,7 +1325,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color caret_color = mono_color;
const Color caret_background_color = mono_color.inverted();
const Color text_selected_color = dark_color_3;
- const Color selection_color = accent_color * Color(1, 1, 1, 0.35);
const Color brace_mismatch_color = error_color;
const Color current_line_color = alpha1;
const Color line_length_guideline_color = dark_theme ? base_color : background_color;
diff --git a/editor/editor_themes.h b/editor/editor_themes.h
index 4d9bfc56c8..852edf7669 100644
--- a/editor/editor_themes.h
+++ b/editor/editor_themes.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_translation_parser.cpp b/editor/editor_translation_parser.cpp
index 4e6a397840..51bd9b3383 100644
--- a/editor/editor_translation_parser.cpp
+++ b/editor/editor_translation_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_translation_parser.h b/editor/editor_translation_parser.h
index bdebdd10a1..4f8f3537f2 100644
--- a/editor/editor_translation_parser.h
+++ b/editor/editor_translation_parser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp
index 4b13a5dd89..eaa8f891ec 100644
--- a/editor/editor_vcs_interface.cpp
+++ b/editor/editor_vcs_interface.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h
index 7de1883fd7..af952eaffc 100644
--- a/editor/editor_vcs_interface.h
+++ b/editor/editor_vcs_interface.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index e9b6f6b5e9..781d21c370 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/export_template_manager.h b/editor/export_template_manager.h
index 3d527f2338..3de74e17d8 100644
--- a/editor/export_template_manager.h
+++ b/editor/export_template_manager.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp
index 7e05bc5d88..d80003a12a 100644
--- a/editor/fileserver/editor_file_server.cpp
+++ b/editor/fileserver/editor_file_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -278,7 +278,8 @@ void EditorFileServer::_thread_start(void *s) {
cd->connection = self->server->take_connection();
cd->efs = self;
cd->quit = false;
- cd->thread = Thread::create(_subthread_start, cd);
+ cd->thread = memnew(Thread);
+ cd->thread->start(_subthread_start, cd);
}
}
@@ -287,8 +288,7 @@ void EditorFileServer::_thread_start(void *s) {
Thread *w = self->to_wait.front()->get();
self->to_wait.erase(w);
self->wait_mutex.unlock();
- Thread::wait_to_finish(w);
- memdelete(w);
+ w->wait_to_finish();
self->wait_mutex.lock();
}
self->wait_mutex.unlock();
@@ -317,7 +317,7 @@ EditorFileServer::EditorFileServer() {
quit = false;
active = false;
cmd = CMD_NONE;
- thread = Thread::create(_thread_start, this);
+ thread.start(_thread_start, this);
EDITOR_DEF("filesystem/file_server/port", 6010);
EDITOR_DEF("filesystem/file_server/password", "");
@@ -325,6 +325,5 @@ EditorFileServer::EditorFileServer() {
EditorFileServer::~EditorFileServer() {
quit = true;
- Thread::wait_to_finish(thread);
- memdelete(thread);
+ thread.wait_to_finish();
}
diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h
index 6d3c0d0d47..8ffd4f9692 100644
--- a/editor/fileserver/editor_file_server.h
+++ b/editor/fileserver/editor_file_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,7 @@ class EditorFileServer : public Object {
};
struct ClientData {
- Thread *thread = nullptr;
+ Thread *thread;
Ref<StreamPeerTCP> connection;
Map<int, FileAccess *> files;
EditorFileServer *efs = nullptr;
@@ -61,7 +61,7 @@ class EditorFileServer : public Object {
static void _subthread_start(void *s);
Mutex wait_mutex;
- Thread *thread;
+ Thread thread;
static void _thread_start(void *);
bool quit;
Command cmd;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 6c8bd1901e..ab5fd30998 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -76,6 +76,9 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
subdirectory_item->set_metadata(0, lpath);
if (!p_select_in_favorites && (path == lpath || ((display_mode == DISPLAY_MODE_SPLIT) && path.get_base_dir() == lpath))) {
subdirectory_item->select(0);
+ // Keep select an item when re-created a tree
+ // To prevent crashing when nothing is selected.
+ subdirectory_item->set_as_cursor(0);
}
if (p_unfold_path && path.begins_with(lpath) && path != lpath) {
@@ -531,7 +534,7 @@ void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_fa
}
String file_name = p_path.get_file();
- if (!file_name.empty()) {
+ if (!file_name.is_empty()) {
for (int i = 0; i < files->get_item_count(); i++) {
if (files->get_item_text(i) == file_name) {
files->select(i, true);
@@ -1407,10 +1410,28 @@ void FileSystemDock::_make_scene_confirm() {
void FileSystemDock::_file_removed(String p_file) {
emit_signal("file_removed", p_file);
+
+ // Find the closest parent directory available, in case multiple items were deleted along the same path.
+ path = p_file.get_base_dir();
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ while (!da->dir_exists(path)) {
+ path = path.get_base_dir();
+ }
+
+ current_path->set_text(path);
}
void FileSystemDock::_folder_removed(String p_folder) {
emit_signal("folder_removed", p_folder);
+
+ // Find the closest parent directory available, in case multiple items were deleted along the same path.
+ path = p_folder.get_base_dir();
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ while (!da->dir_exists(path)) {
+ path = path.get_base_dir();
+ }
+
+ current_path->set_text(path);
}
void FileSystemDock::_rename_operation_confirm() {
@@ -1465,6 +1486,9 @@ void FileSystemDock::_rename_operation_confirm() {
print_verbose("FileSystem: saving moved scenes.");
_save_scenes_after_move(file_renames);
+
+ path = new_path;
+ current_path->set_text(path);
}
void FileSystemDock::_duplicate_operation_confirm() {
@@ -1528,7 +1552,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_ove
if (!p_overwrite) {
to_move_path = p_to_path;
Vector<String> conflicting_items = _check_existing();
- if (!conflicting_items.empty()) {
+ if (!conflicting_items.is_empty()) {
// Ask to do something.
overwrite_dialog->set_text(vformat(
TTR("The following files or folders conflict with items in the target location '%s':\n\n%s\n\nDo you wish to overwrite them?"),
@@ -1573,6 +1597,9 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_ove
print_verbose("FileSystem: saving moved scenes.");
_save_scenes_after_move(file_renames);
+
+ path = p_to_path;
+ current_path->set_text(path);
}
}
@@ -1721,7 +1748,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
paths.push_back(fpath);
}
}
- if (!paths.empty()) {
+ if (!paths.is_empty()) {
emit_signal("instance", paths);
}
} break;
@@ -1753,7 +1780,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
case FILE_DEPENDENCIES: {
// Checkout the file dependencies.
- if (!p_selected.empty()) {
+ if (!p_selected.is_empty()) {
String fpath = p_selected[0];
deps_editor->edit(fpath);
}
@@ -1761,7 +1788,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
case FILE_OWNERS: {
// Checkout the file owners.
- if (!p_selected.empty()) {
+ if (!p_selected.is_empty()) {
String fpath = p_selected[0];
owners_editor->show(fpath);
}
@@ -1784,7 +1811,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
case FILE_RENAME: {
// Rename the active file.
- if (!p_selected.empty()) {
+ if (!p_selected.is_empty()) {
to_rename.path = p_selected[0];
if (to_rename.path != "res://") {
to_rename.is_file = !to_rename.path.ends_with("/");
@@ -1885,7 +1912,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_COPY_PATH: {
- if (!p_selected.empty()) {
+ if (!p_selected.is_empty()) {
String fpath = p_selected[0];
DisplayServer::get_singleton()->clipboard_set(fpath);
}
@@ -1898,7 +1925,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
}
void FileSystemDock::_resource_created() {
- Object *c = new_resource_dialog->instance_selected();
+ Variant c = new_resource_dialog->instance_selected();
ERR_FAIL_COND(!c);
Resource *r = Object::cast_to<Resource>(c);
@@ -1912,17 +1939,14 @@ void FileSystemDock::_resource_created() {
memdelete(node);
}
- REF res(r);
- editor->push_item(c);
-
- RES current_res = RES(r);
+ editor->push_item(r);
String fpath = path;
if (!fpath.ends_with("/")) {
fpath = fpath.get_base_dir();
}
- editor->save_resource_as(current_res, fpath);
+ editor->save_resource_as(RES(r), fpath);
}
void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) {
@@ -2013,7 +2037,7 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from)
all_not_favorites = true;
}
- if (paths.empty()) {
+ if (paths.is_empty()) {
return Variant();
}
@@ -2061,7 +2085,7 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
String to_dir;
bool favorite;
_get_drag_target_folder(to_dir, favorite, p_point, p_from);
- return !to_dir.empty();
+ return !to_dir.is_empty();
}
if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) {
@@ -2074,7 +2098,7 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
return true;
}
- if (to_dir.empty()) {
+ if (to_dir.is_empty()) {
return false;
}
@@ -2169,7 +2193,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
String to_dir;
bool favorite;
_get_drag_target_folder(to_dir, favorite, p_point, p_from);
- if (res.is_valid() && !to_dir.empty()) {
+ if (res.is_valid() && !to_dir.is_empty()) {
EditorNode::get_singleton()->push_item(res.ptr());
EditorNode::get_singleton()->save_resource_as(res, to_dir);
}
@@ -2180,7 +2204,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
String to_dir;
bool favorite;
_get_drag_target_folder(to_dir, favorite, p_point, p_from);
- if (!to_dir.empty()) {
+ if (!to_dir.is_empty()) {
Vector<String> fnames = drag_data["files"];
to_move.clear();
for (int i = 0; i < fnames.size(); i++) {
@@ -2188,7 +2212,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
to_move.push_back(FileOrFolder(fnames[i], !fnames[i].ends_with("/")));
}
}
- if (!to_move.empty()) {
+ if (!to_move.is_empty()) {
if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
for (int i = 0; i < to_move.size(); i++) {
String new_path;
@@ -2291,7 +2315,7 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori
void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<String> p_paths, bool p_display_path_dependent_options) {
// Add options for files and folders.
- ERR_FAIL_COND_MSG(p_paths.empty(), "Path cannot be empty.");
+ ERR_FAIL_COND_MSG(p_paths.is_empty(), "Path cannot be empty.");
Vector<String> filenames;
Vector<String> foldernames;
@@ -2414,7 +2438,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) {
}
// Popup.
- if (!paths.empty()) {
+ if (!paths.is_empty()) {
tree_popup->set_size(Size2(1, 1));
_file_and_folders_fill_popup(tree_popup, paths);
tree_popup->set_position(tree->get_screen_position() + p_pos);
@@ -2447,14 +2471,14 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) {
continue;
}
if (files->get_item_text(p_item) == "..") {
- files->unselect(i);
+ files->deselect(i);
continue;
}
paths.push_back(files->get_item_metadata(i));
}
// Popup.
- if (!paths.empty()) {
+ if (!paths.is_empty()) {
file_list_popup->clear();
file_list_popup->set_size(Size2(1, 1));
_file_and_folders_fill_popup(file_list_popup, paths, searched_string.length() == 0);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 4b93931ba7..39dc4784b8 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index e8588bbed5..47079a92b7 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -463,7 +463,7 @@ void FindInFilesDialog::_notification(int p_what) {
for (int i = 0; i < _filters_container->get_child_count(); i++) {
_filters_container->get_child(i)->queue_delete();
}
- Array exts = ProjectSettings::get_singleton()->get("editor/search_in_file_extensions");
+ Array exts = ProjectSettings::get_singleton()->get("editor/script/search_in_file_extensions");
for (int i = 0; i < exts.size(); ++i) {
CheckBox *cb = memnew(CheckBox);
cb->set_text(exts[i]);
@@ -499,8 +499,8 @@ void FindInFilesDialog::_on_search_text_modified(String text) {
ERR_FAIL_COND(!_find_button);
ERR_FAIL_COND(!_replace_button);
- _find_button->set_disabled(get_search_text().empty());
- _replace_button->set_disabled(get_search_text().empty());
+ _find_button->set_disabled(get_search_text().is_empty());
+ _replace_button->set_disabled(get_search_text().is_empty());
}
void FindInFilesDialog::_on_search_text_entered(String text) {
@@ -687,6 +687,9 @@ void FindInFilesPanel::stop_search() {
void FindInFilesPanel::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
_progress_bar->set_as_ratio(_finder->get_progress());
+ } else if (p_what == NOTIFICATION_THEME_CHANGED) {
+ _search_text_label->add_theme_font_override("font", get_theme_font("source", "EditorFonts"));
+ _results_display->add_theme_font_override("font", get_theme_font("source", "EditorFonts"));
}
}
diff --git a/editor/find_in_files.h b/editor/find_in_files.h
index d4755c7b50..b9d60a8d4f 100644
--- a/editor/find_in_files.h
+++ b/editor/find_in_files.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 1eaf7d70b7..f2a110ca03 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -198,7 +198,7 @@ void GroupDialog::_add_group(String p_name) {
}
String name = p_name.strip_edges();
- if (name.empty() || groups->get_item_with_text(name)) {
+ if (name.is_empty() || groups->get_item_with_text(name)) {
return;
}
@@ -551,7 +551,7 @@ void GroupsEditor::_add_group(const String &p_group) {
}
const String name = group_name->get_text().strip_edges();
- if (name.empty()) {
+ if (name.is_empty()) {
return;
}
diff --git a/editor/groups_editor.h b/editor/groups_editor.h
index 6c3489fffb..69f746801f 100644
--- a/editor/groups_editor.h
+++ b/editor/groups_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/icons/ColorPickerBarArrow.svg b/editor/icons/ColorPickerBarArrow.svg
new file mode 100644
index 0000000000..9d034106ee
--- /dev/null
+++ b/editor/icons/ColorPickerBarArrow.svg
@@ -0,0 +1 @@
+<svg height="20" viewBox="0 0 16 20" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 16h12l-6-6z" fill="#e0e0e0" stroke-width="2"/></svg>
diff --git a/editor/icons/GPUParticlesAttractorBox.svg b/editor/icons/GPUParticlesAttractorBox.svg
new file mode 100644
index 0000000000..3c27b2d3cb
--- /dev/null
+++ b/editor/icons/GPUParticlesAttractorBox.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#fc9c9c" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc9c9c" stroke-opacity=".996078"><ellipse cx="8" cy="-8" rx="2.339226" ry="4.949748" transform="rotate(90)"/><ellipse cx="8" cy="8" rx="2.339226" ry="4.949748"/><path d="m1.498906 1.498906h13.002189v13.002188h-13.002189z" stroke-width=".997813"/></g></svg>
diff --git a/editor/icons/GPUParticlesAttractorSphere.svg b/editor/icons/GPUParticlesAttractorSphere.svg
new file mode 100644
index 0000000000..5473a23854
--- /dev/null
+++ b/editor/icons/GPUParticlesAttractorSphere.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-8" cy="-7.999999" fill="none" rx="6.499003" ry="6.499001" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.002" transform="scale(-1)"/><circle cx="8" cy="8" fill="#fc9c9c" fill-opacity=".996078" r="1"/><g fill="none" stroke="#fc9c9c" stroke-opacity=".996078"><ellipse cx="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 .70710678 -.70710678 .70710678 0 0)"/><ellipse cy="11.313708" rx="2.339226" ry="4.949748" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 0)"/></g></svg>
diff --git a/editor/icons/GPUParticlesAttractorVectorField.svg b/editor/icons/GPUParticlesAttractorVectorField.svg
new file mode 100644
index 0000000000..93a29789e3
--- /dev/null
+++ b/editor/icons/GPUParticlesAttractorVectorField.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="6.663637" cy="9.245457" fill="#fc9c9c" fill-opacity=".996078" rx="1.030661" ry=".998146"/><ellipse cx="-6.672815" cy="-9.387111" fill="none" rx="2.408711" ry="5.096776" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.99999945 .00104887 .00104887 -.99999945 0 0)"/><ellipse cx="9.387111" cy="-6.672815" fill="none" rx="2.408711" ry="5.096776" stroke="#fc9c9c" stroke-opacity=".996078" stroke-width="1.0297" transform="matrix(-.00104887 .99999945 -.99999945 .00104887 0 0)"/><g fill="#fc9c9c" fill-opacity=".996078"><path d="m11.8 15 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/><path d="m11 6 3-3 1 1v-3h-3l1 1-3 3z"/><path d="m1.8 5 2.4-2.4.8.8v-2.4h-2.4l.8.8-2.4 2.4z"/></g></svg>
diff --git a/editor/icons/GPUParticlesCollisionBox.svg b/editor/icons/GPUParticlesCollisionBox.svg
new file mode 100644
index 0000000000..f7296b34c3
--- /dev/null
+++ b/editor/icons/GPUParticlesCollisionBox.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c" fill-opacity=".996078"><path d="m7.5 2.8124998-5.5883107 2.7941554v5.7660988l5.5883107 2.794155 5.588311-2.794155v-5.7660988zm0 1.6886278 3.145021 1.5732692-3.145021 1.5717523-3.1450214-1.5717523zm-3.9916505 2.8362274 3.1933204 1.5966602v3.1465378l-3.1933204-1.598256zm7.9833015 0v3.145021l-3.1933209 1.598257v-3.146538z" stroke-width=".851579"/><circle cx="1.875" cy="3.75" r=".9375"/><circle cx="13.124999" cy="3.75" r=".9375"/><circle cx="9.374999" cy="1.875" r=".9375"/><circle cx="5.625" cy="1.875" r=".9375"/></g></svg>
diff --git a/editor/icons/GPUParticlesCollisionHeightField.svg b/editor/icons/GPUParticlesCollisionHeightField.svg
new file mode 100644
index 0000000000..b483f299e9
--- /dev/null
+++ b/editor/icons/GPUParticlesCollisionHeightField.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c"><path d="m1 10c1-1 3-2 3-4s2-4 4-4 4 2 4 4 2 3 3 4l-7 5z"/><circle cx="2" cy="6" r="1"/><circle cx="14" cy="6" r="1"/><circle cx="12" cy="2" r="1"/><circle cx="4" cy="2" r="1"/></g></svg>
diff --git a/editor/icons/GPUParticlesCollisionSDF.svg b/editor/icons/GPUParticlesCollisionSDF.svg
new file mode 100644
index 0000000000..6279990f3a
--- /dev/null
+++ b/editor/icons/GPUParticlesCollisionSDF.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 14h-12v-9s3 4 5.9999999 3.9999999c3.0000001-.0000001 6.0000001-3.9999999 6.0000001-3.9999999z" fill="none" stroke="#fc9c9c" stroke-linejoin="round" stroke-opacity=".996078" stroke-width="2"/><g fill="#fc9c9c" fill-opacity=".996078"><circle cx="2" cy="2" r="1"/><circle cx="14" cy="2" r="1"/><circle cx="10" cy="5" r="1"/><circle cx="6" cy="5" r="1"/></g></svg>
diff --git a/editor/icons/GPUParticlesCollisionSphere.svg b/editor/icons/GPUParticlesCollisionSphere.svg
new file mode 100644
index 0000000000..fc7715445c
--- /dev/null
+++ b/editor/icons/GPUParticlesCollisionSphere.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#fc9c9c" fill-opacity=".996078"><path d="m8 3.0532484c-3.2888554 0-5.9733758 2.6845204-5.9733758 5.9733758 0 3.2889408 2.6845204 5.9733758 5.9733758 5.9733758 3.288855 0 5.973376-2.684435 5.973376-5.9733758 0-3.2888554-2.684521-5.9733758-5.973376-5.9733758zm-.8533394 1.79005v4.1567016c-1.1034532-.0608789-2.2238878-.2544573-3.3650586-.5900074.256693-1.7901354 1.6087154-3.2141029 3.3650586-3.5667027zm1.7066788 0c1.7535276.3520281 3.1035956 1.77213 3.3633516 3.55834-1.113266.3129793-2.2321649.5142138-3.3633516.5866709zm3.2300606 5.3599956c-.434043 1.51792-1.663927 2.690664-3.2300606 3.005035v-2.518376c1.0915918-.0617 2.1691036-.227875 3.2300606-.486668zm-8.161765.015c1.0865571.272147 2.162106.428504 3.2250256.480003v2.510013c-1.5608431-.313338-2.7870065-1.479605-3.2250256-2.990016z" stroke-width=".853339"/><circle cx="2" cy="5" r="1"/><circle cx="14" cy="5" r="1"/><circle cx="10" cy="2" r="1"/><circle cx="6" cy="2" r="1"/></g></svg>
diff --git a/editor/icons/Logo.svg b/editor/icons/Logo.svg
index d7aef39cc9..a4ad488396 100644
--- a/editor/icons/Logo.svg
+++ b/editor/icons/Logo.svg
@@ -1 +1 @@
-<svg height="69" viewBox="0 0 187 69" width="187" xmlns="http://www.w3.org/2000/svg"><path d="m91.912 19.51c-3.5233 0-6.278 1.1097-8.2676 3.3281-1.9911 2.2193-2.9844 5.1004-2.9844 8.6465 0 4.1636 1.0165 7.3207 3.0508 9.4707 2.0379 2.1497 4.7123 3.2227 8.0293 3.2227 1.7838 0 3.3686-.15384 4.752-.46289 1.3848-.30784 2.3038-.62367 2.7617-.94336l.13867-10.736c0-.62388-1.6471-.90785-3.4941-.93945-1.847-.02857-3.9609.35742-3.9609.35742v3.6055h2.125l-.023438 1.6055c0 .59532-.59062.89453-1.7676.89453-1.1785 0-2.2182-.4989-3.1211-1.4941-.90498-.99645-1.3555-2.4517-1.3555-4.3711 0-1.9233.43964-3.3428 1.3203-4.2578.87885-.9141 2.0322-1.3711 3.4492-1.3711.59532 0 1.2107.095008 1.8516.29102.64121.19418 1.0686.37639 1.2871.54688.21667.17534.42435.25781.61914.25781.19388 0 .50715-.22698.94141-.68555.43487-.45735.82427-1.1501 1.168-2.0742.34218-.92899.51367-1.6414.51367-2.1465 0-.50111-.011023-.84501-.033203-1.0273-.48045-.52573-1.3668-.94394-2.6602-1.2539-1.2909-.30906-2.7387-.46289-4.3398-.46289zm21.049 0c-3.2367 0-5.8788 1.0413-7.9258 3.1211-2.0464 2.0826-3.0703 5.1404-3.0703 9.1797 0 4.0369 1.0128 7.1085 3.0352 9.2129 2.0251 2.1026 4.6444 3.1543 7.8574 3.1543 3.2145 0 5.8383-1.0111 7.875-3.0332 2.0367-2.0263 3.0527-5.1142 3.0527-9.2656 0-4.1484-.99433-7.2508-2.9863-9.2969-1.9884-2.05-4.6018-3.0723-7.8379-3.0723zm45.504 0c-3.2379 0-5.8792 1.0413-7.9277 3.1211-2.0461 2.0826-3.0684 5.1404-3.0684 9.1797 0 4.0369 1.0104 7.1085 3.0352 9.2129 2.0233 2.1026 4.6432 3.1543 7.8574 3.1543 3.213 0 5.8373-1.0111 7.873-3.0332 2.0364-2.0263 3.0547-5.1142 3.0547-9.2656 0-4.1484-.9939-7.2508-2.9844-9.2969-1.9908-2.05-4.6031-3.0723-7.8398-3.0723zm-30.105.30859c-.45888 0-.82988.16637-1.1152.49609-.28717.33489-.42969.78715-.42969 1.3594v20.584c0 1.053.58624 1.5781 1.752 1.5781h5.8652c7.1824-.000001 10.773-4.2092 10.773-12.627 0-3.9348-.94335-6.8151-2.832-8.6445-1.8853-1.83-4.6472-2.7461-8.2832-2.7461h-5.7305zm42.807 0c-.38928 0-.66468.52801-.82422 1.5801-.0687.50294-.10157 1.0191-.10157 1.543 0 .52694.03287 1.0409.10157 1.543.15954 1.0548.43494 1.5801.82422 1.5801h4.1152v17.225c0 .45462 1.1351.68555 3.3984.68555 2.2655 0 3.3965-.23093 3.3965-.68555v-17.225h4.0137c.38868 0 .66225-.52528.82422-1.5801.0672-.50202.10156-1.016.10156-1.543.00001-.52391-.03436-1.04-.10156-1.543-.16197-1.0521-.43554-1.5801-.82422-1.5801h-14.924zm-58.291 6.2793c1.0989 0 2.0193.49244 2.7617 1.4746.74331.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-.35955 3.2363-1.0801 4.2188-.72053.98612-1.6597 1.4785-2.8145 1.4785-1.1554 0-2.0859-.48441-2.7949-1.459-.71019-.97154-1.0644-2.3663-1.0644-4.1875 0-1.8173.37148-3.2302 1.1133-4.2363.74574-1.0053 1.6663-1.5098 2.7637-1.5098zm45.504 0c1.0989 0 2.0181.49244 2.7617 1.4746.74331.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-.3612 3.2363-1.082 4.2188-.71961.98612-1.6574 1.4785-2.8125 1.4785-1.1554 0-2.0888-.48441-2.7969-1.459-.70806-.97154-1.0625-2.3663-1.0625-4.1875 0-1.8173.37179-3.2302 1.1133-4.2363.74453-1.0053 1.666-1.5098 2.7637-1.5098zm-24.977.23828h.34375c1.4638 0 2.5334.33466 3.209.99805.6722.66157 1.0098 2.0859 1.0098 4.2715 0 2.1847-.32289 3.7447-.97656 4.6816-.65214.9378-1.6059 1.4082-2.8652 1.4082-.34218 0-.54909-.063339-.61719-.18945-.06873-.12672-.10352-.42897-.10352-.9082v-10.262z" fill="#fff"/><path d="m137.91 48.551v1.2109h.85938v-1.2109zm-52.396.58984c-.99736 0-1.7963.32424-2.3926.96484-.59745.64576-.89453 1.5712-.89453 2.7773v3.0742c0 1.2329.31639 2.1765.94727 2.832.6333.66066 1.467.98828 2.5039.98828.78586 0 1.4321-.16147 1.9414-.48633.50993-.32273.8592-.67938 1.0488-1.0684v-3.6875h-3.0059v.74805h2.1465v2.6934c-.13766.30115-.38143.55386-.73242.76172-.34978.2109-.8171.31445-1.3984.31445-.79619 0-1.4265-.2632-1.8945-.78711-.46799-.52786-.70312-1.2936-.70312-2.2988v-3.0918c0-.96941.21778-1.7078.65234-2.2168.43578-.51023 1.0297-.76367 1.7812-.76367.74271 0 1.3056.19019 1.6836.56641.38017.37925.58276.91542.61133 1.6113h.79492l.013672-.041016c-.024311-.90802-.30456-1.6179-.83789-2.127-.53484-.50719-1.2907-.76367-2.2656-.76367zm7.6133 2.6641c-.719 0-1.3111.22524-1.7715.67773-.46222.45371-.68069.96571-.6582 1.5449l.013672.041015.79688.007813c0-.42696.14768-.78487.44336-1.0781.2966-.29508.67455-.44141 1.1328-.44141.4926 0 .87459.15388 1.1523.45898.27198.30906.41016.73655.41016 1.2793v.94531h-1.3418c-.85666 0-1.5379.21084-2.0391.63477-.50142.42392-.75195.99502-.75195 1.707 0 .67372.17358 1.2075.51758 1.6035.34613.39445.83497.5918 1.4707.5918.45462 0 .86723-.12355 1.2383-.37305.37166-.24767.67317-.56424.90625-.94531 0 .17413.01089.34527.03125.51758.02097.16927.053163.38614.095703.65234h.88867c-.062302-.24767-.10234-.49621-.12695-.75391-.02401-.25436-.037109-.52051-.037109-.79492v-3.7676c0-.80622-.21809-1.4265-.65234-1.8613-.43669-.43061-1.0083-.64648-1.7188-.64648zm7.1152 0c-.45462 0-.85109.11505-1.1875.3457-.33519.23369-.60486.56357-.80664.99023l-.074219-1.1934h-.75195v7.6816h.85352v-5.5293c.11791-.47346.31244-.84655.58594-1.1191.27168-.27107.63379-.4082 1.082-.4082.4689 0 .83314.19466 1.0957.58789.26378.39323.39258 1.0508.39258 1.9707v4.498h.85351v-4.6211-.19922c.0623-.64455.23396-1.1785.51172-1.6055.27927-.42696.66855-.63672 1.166-.63672.47285 0 .83879.19223 1.0938.57422.25345.38138.38281 1.0443.38281 1.9863v4.502h.85742v-4.4863c0-1.1332-.18468-1.9728-.55664-2.5195-.37044-.54548-.89268-.81836-1.5664-.81836-.48897 0-.91182.1465-1.2598.43945-.34796.29234-.61537.69589-.80469 1.207-.148-.55369-.38151-.966-.69726-1.2383-.31543-.2732-.70589-.4082-1.1699-.4082zm10.316 0c-.74423-.000001-1.3797.32125-1.9082.96094-.52725.64273-.78906 1.4505-.78906 2.4199v1.2754c0 .96758.26259 1.762.7871 2.3828.52604.62206 1.2032.93359 2.0312.93359.5157 0 .95833-.090281 1.3242-.26562.36679-.17626.66658-.41287.89844-.70703l-.34961-.60547c-.21728.27441-.4784.4836-.7832.63281-.3048.14586-.66987.2207-1.0898.2207-.60443 0-1.0864-.24489-1.4414-.74023-.35433-.49412-.53321-1.1138-.53321-1.8574v-.63867h4.3965v-.84375c0-.96667-.22381-1.7371-.66992-2.3105-.44519-.57253-1.0684-.85742-1.873-.85742zm9.4727 0c-.74423-.000001-1.3782.32125-1.9082.96094-.52603.64273-.79101 1.4505-.79101 2.4199v1.2754c0 .96758.26241 1.762.78906 2.3828.52512.62206 1.2028.93359 2.0312.93359.51601 0 .95639-.090281 1.3223-.26562.36741-.17626.66822-.41287.90039-.70703l-.34766-.60547c-.21972.27441-.4811.4836-.78711.63281-.30389.14586-.66639.2207-1.0879.2207-.60656 0-1.0883-.24489-1.4414-.74023-.35646-.49412-.5332-1.1138-.5332-1.8574v-.63867h4.3945v-.84375c0-.96667-.22338-1.7371-.66797-2.3105-.44398-.57253-1.0699-.85742-1.873-.85742zm6.8672 0c-.45614 0-.85274.12451-1.1894.36914-.33975.24342-.60962.5923-.81445 1.043l-.07031-1.2695h-.76172v7.6816h.85351v-5.4824c.14617-.47923.36569-.85918.66016-1.1445.29325-.28809.65767-.42969 1.0938-.42969.48622 0 .85922.17765 1.1133.5332.25557.35555.38477.96807.38477 1.8457v4.6777h.85937v-4.6855c0-1.0736-.18381-1.866-.55273-2.375-.36497-.50993-.89-.76367-1.5762-.76367zm6.2539 0c-.77674 0-1.386.32888-1.8242.98437-.44186.65883-.66211 1.5326-.66211 2.6211l.00196 1.0508c0 1.0031.21834 1.8072.65625 2.4102.43699.60413 1.0429.90625 1.8144.90625.41602 0 .78387-.091234 1.0996-.27539.31695-.18324.58484-.4491.80273-.79492v.92969c0 .75881-.14785 1.3303-.4414 1.7266-.29235.39111-.74301.58789-1.3535.58789-.30359 0-.59763-.04082-.88086-.125-.28565-.081443-.54279-.19619-.77344-.3457l-.23632.74805c.27047.15164.57916.27315.92773.36523.34795.092075.67388.13867.97656.13867.84208 0 1.494-.27297 1.9531-.81055.45857-.53971.68554-1.3009.68554-2.2852v-7.6895h-.72265l-.08399 1.0684c-.21485-.38533-.48269-.68758-.80664-.89453-.32334-.2109-.70159-.31641-1.1328-.31641zm10.467 0c-.45401 0-.85062.12451-1.1895.36914-.33914.24342-.60902.5923-.81445 1.043l-.07031-1.2695h-.75977v7.6816h.85352v-5.4824c.14556-.47923.3663-.85918.66016-1.1445.29295-.28809.65797-.42969 1.0937-.42969.48775 0 .85711.17765 1.1133.5332.25496.35555.38476.96807.38476 1.8457v4.6777h.85742v-4.6855c0-1.0736-.18081-1.866-.54882-2.375-.36588-.50993-.8939-.76367-1.5801-.76367zm6.4043 0c-.74271-.000001-1.3778.32125-1.9062.96094-.52724.64273-.79101 1.4505-.79101 2.4199v1.2754c0 .96758.26334 1.762.78906 2.3828.52361.62206 1.2007.93359 2.0312.93359.5154 0 .9567-.090281 1.3223-.26562.3668-.17626.6667-.41287.90039-.70703l-.34961-.60547c-.2194.27441-.47958.4836-.78711.63281-.30359.14586-.66597.2207-1.0859.2207-.60717 0-1.089-.24489-1.4434-.74023-.35464-.49412-.5332-1.1138-.5332-1.8574v-.63867h4.3965v-.84375c0-.96667-.22369-1.7371-.66797-2.3105-.44551-.57253-1.0709-.85742-1.875-.85742zm-12.113.14258v7.6816h.85938v-7.6816zm-27.352.60938c.53029 0 .9445.20789 1.2441.62695.29781.41876.44531.94616.44531 1.5801v.33008h-3.543c.01429-.71688.19281-1.3186.53711-1.8066.34401-.48622.78217-.73047 1.3164-.73047zm9.4727 0c.52998 0 .94406.20789 1.2422.62695.29963.41876.44727.94616.44727 1.5801v.33008h-3.543c.0155-.71688.19298-1.3186.53516-1.8066.3437-.48622.7826-.73047 1.3184-.73047zm29.992 0c.53089 0 .94602.20789 1.2441.62695.29902.41876.44532.94616.44532 1.5801v.33008h-3.543c.01519-.71688.19402-1.3186.53711-1.8066.34218-.48622.78064-.73047 1.3164-.73047zm-16.686.015625c.42119 0 .77033.1246 1.0469.375.27684.25466.4967.58706.65625.99609v3.8047c-.16593.39718-.39.70872-.67383.93359-.28475.22488-.63089.33594-1.043.33594-.6014 0-1.0536-.22975-1.3496-.69531-.29964-.4613-.44727-1.0819-.44727-1.8613v-1.0508c0-.84177.15149-1.527.45508-2.0527.30146-.52482.75528-.78516 1.3555-.78516zm-40.057 3.3281h1.3652v1.6621c-.15286.42089-.40964.76752-.77734 1.041-.3671.27228-.78783.40625-1.2598.40625-.39262 0-.69782-.12824-.91602-.38867-.2185-.25952-.32617-.59591-.32617-1.0059 0-.48531.17262-.89402.52148-1.2207.34795-.32881.81215-.49414 1.3926-.49414z" fill="#e0e0e0"/><path d="m27 3c-3.0948.68801-6.1571 1.6452-9.0273 3.0898.06564 2.5344.23035 4.963.5625 7.4297-1.1147.71414-2.287 1.3281-3.3281 2.1641-1.0578.81382-2.1378 1.5912-3.0957 2.543-1.9136-1.2657-3.9389-2.454-6.0254-3.5039-2.2491 2.4205-4.3524 5.0317-6.0703 7.9551 1.2924 2.0908 2.6428 4.0523 4.0996 5.9121h.041016v14.438 1.834 1.6699c.03282.000304.06514.000806.097656.003906l11 1.0605c.57617.05561 1.0282.52027 1.0684 1.0977l.33789 4.8555 9.5957.68359.66016-4.4805c.0857-.58104.58415-1.0117 1.1719-1.0117h11.605c.58742 0 1.0862.43068 1.1719 1.0117l.66016 4.4805 9.5957-.68359.33789-4.8555c.04042-.57739.49219-1.0417 1.0684-1.0977l10.996-1.0605c.032519-.003.064836-.003606.097656-.003906v-1.4316l.003906-.001953v-16.508h.041016c1.4571-1.8598 2.8066-3.8214 4.0996-5.9121-1.7173-2.9234-3.8232-5.5346-6.0723-7.9551-2.0859 1.0499-4.1118 2.2382-6.0254 3.5039-.95756-.95178-2.0363-1.7292-3.0957-2.543-1.0408-.836-2.2136-1.4499-3.3262-2.1641.33124-2.4667.49656-4.8952.5625-7.4297-2.8706-1.4447-5.933-2.4018-9.0293-3.0898-1.2362 2.0777-2.367 4.3278-3.3516 6.5273-1.1675-.1951-2.3391-.26727-3.5137-.28125v-.0019532c-.0082 0-.016447.0019531-.023437.0019532-.0073 0-.014194-.0019532-.021484-.0019532v.0019532c-1.1767.013979-2.3497.086153-3.5176.28125-.98399-2.1996-2.1135-4.4497-3.3516-6.5273zm-22.863 45.904c.0045599 1.063.019531 2.2271.019531 2.459 0 10.446 13.251 15.468 29.715 15.525h.019531.019531c16.464-.05774 29.711-5.0795 29.711-15.525 0-.23612.014661-1.3954.019531-2.459l-9.8867.95312-.3418 4.8809c-.04102.58833-.50933 1.0574-1.0977 1.0996l-11.717.83594c-.02857.0021-.055724.003906-.083984.003906-.58225 0-1.0859-.42704-1.1719-1.0117l-.67188-4.5566h-9.5586l-.67188 4.5566c-.09025.61325-.63836 1.0531-1.2559 1.0078l-11.717-.83594c-.58833-.04224-1.0566-.51128-1.0977-1.0996l-.3418-4.8809-9.8906-.95312z" fill="#478cbf"/><path d="m18.299 29.246c-3.6594 0-6.6289 2.9669-6.6289 6.627 0 3.6625 2.9695 6.6289 6.6289 6.6289 3.6613 0 6.627-2.9664 6.627-6.6289 0-3.66-2.9657-6.627-6.627-6.627zm31.186 0c-3.6619 0-6.6289 2.9669-6.6289 6.627 0 3.6625 2.967 6.6289 6.6289 6.6289 3.6591 0 6.627-2.9664 6.627-6.6289 0-3.66-2.9678-6.627-6.627-6.627zm-15.594 3.8789c-1.1785 0-2.1348.86781-2.1348 1.9375v6.1035c0 1.0706.95628 1.9395 2.1348 1.9395s2.1348-.86885 2.1348-1.9395v-6.1035c0-1.0697-.95628-1.9375-2.1348-1.9375z" fill="#f6f6f6"/><path d="m18.932 31.865c-2.4299 0-4.4004 1.9711-4.4004 4.4004s1.9705 4.3984 4.4004 4.3984c2.4311 0 4.4004-1.9691 4.4004-4.3984s-1.9693-4.4004-4.4004-4.4004zm29.916 0c-2.4293 0-4.3984 1.9711-4.3984 4.4004s1.9691 4.3984 4.3984 4.3984c2.4317 0 4.4004-1.9691 4.4004-4.3984s-1.9687-4.4004-4.4004-4.4004z" fill="#414042"/></svg>
+<svg height="69" viewBox="0 0 187 69" width="187" xmlns="http://www.w3.org/2000/svg"><path d="m91.912 19.51c-3.5233 0-6.278 1.1097-8.2676 3.3281-1.9911 2.2193-2.9844 5.1004-2.9844 8.6465 0 4.1636 1.0165 7.3207 3.0508 9.4707 2.0379 2.1497 4.7123 3.2227 8.0293 3.2227 1.7838 0 3.3686-.15384 4.752-.46289 1.3848-.30784 2.3038-.62367 2.7617-.94336l.13867-10.736c0-.62388-1.6471-.90785-3.4941-.93945-1.847-.02857-3.9609.35742-3.9609.35742v3.6055h2.125l-.023438 1.6055c0 .59532-.59062.89453-1.7676.89453-1.1785 0-2.2182-.4989-3.1211-1.4941-.90498-.99645-1.3555-2.4517-1.3555-4.3711 0-1.9233.43964-3.3428 1.3203-4.2578.87885-.9141 2.0322-1.3711 3.4492-1.3711.59532 0 1.2107.095008 1.8516.29102.64121.19418 1.0686.37639 1.2871.54688.21667.17534.42435.25781.61914.25781.19388 0 .50715-.22698.94141-.68555.43487-.45735.82427-1.1501 1.168-2.0742.34218-.92899.51367-1.6414.51367-2.1465 0-.50111-.011023-.84501-.033203-1.0273-.48045-.52573-1.3668-.94394-2.6602-1.2539-1.2909-.30906-2.7387-.46289-4.3398-.46289zm21.049 0c-3.2367 0-5.8788 1.0413-7.9258 3.1211-2.0464 2.0826-3.0703 5.1404-3.0703 9.1797 0 4.0369 1.0128 7.1085 3.0352 9.2129 2.0251 2.1026 4.6444 3.1543 7.8574 3.1543 3.2145 0 5.8383-1.0111 7.875-3.0332 2.0367-2.0263 3.0527-5.1142 3.0527-9.2656 0-4.1484-.99433-7.2508-2.9863-9.2969-1.9884-2.05-4.6018-3.0723-7.8379-3.0723zm45.504 0c-3.2379 0-5.8792 1.0413-7.9277 3.1211-2.0461 2.0826-3.0684 5.1404-3.0684 9.1797 0 4.0369 1.0104 7.1085 3.0352 9.2129 2.0233 2.1026 4.6432 3.1543 7.8574 3.1543 3.213 0 5.8373-1.0111 7.873-3.0332 2.0364-2.0263 3.0547-5.1142 3.0547-9.2656 0-4.1484-.9939-7.2508-2.9844-9.2969-1.9908-2.05-4.6031-3.0723-7.8398-3.0723zm-30.105.30859c-.45888 0-.82988.16637-1.1152.49609-.28717.33489-.42969.78715-.42969 1.3594v20.584c0 1.053.58624 1.5781 1.752 1.5781h5.8652c7.1824-.000001 10.773-4.2092 10.773-12.627 0-3.9348-.94335-6.8151-2.832-8.6445-1.8853-1.83-4.6472-2.7461-8.2832-2.7461h-5.7305zm42.807 0c-.38928 0-.66468.52801-.82422 1.5801-.0687.50294-.10157 1.0191-.10157 1.543 0 .52694.03287 1.0409.10157 1.543.15954 1.0548.43494 1.5801.82422 1.5801h4.1152v17.225c0 .45462 1.1351.68555 3.3984.68555 2.2655 0 3.3965-.23093 3.3965-.68555v-17.225h4.0137c.38868 0 .66225-.52528.82422-1.5801.0672-.50202.10156-1.016.10156-1.543.00001-.52391-.03436-1.04-.10156-1.543-.16197-1.0521-.43554-1.5801-.82422-1.5801h-14.924zm-58.291 6.2793c1.0989 0 2.0193.49244 2.7617 1.4746.74331.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-.35955 3.2363-1.0801 4.2188-.72053.98612-1.6597 1.4785-2.8145 1.4785-1.1554 0-2.0859-.48441-2.7949-1.459-.71019-.97154-1.0644-2.3663-1.0644-4.1875 0-1.8173.37148-3.2302 1.1133-4.2363.74574-1.0053 1.6663-1.5098 2.7637-1.5098zm45.504 0c1.0989 0 2.0181.49244 2.7617 1.4746.74331.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-.3612 3.2363-1.082 4.2188-.71961.98612-1.6574 1.4785-2.8125 1.4785-1.1554 0-2.0888-.48441-2.7969-1.459-.70806-.97154-1.0625-2.3663-1.0625-4.1875 0-1.8173.37179-3.2302 1.1133-4.2363.74453-1.0053 1.666-1.5098 2.7637-1.5098zm-24.977.23828h.34375c1.4638 0 2.5334.33466 3.209.99805.6722.66157 1.0098 2.0859 1.0098 4.2715 0 2.1847-.32289 3.7447-.97656 4.6816-.65214.9378-1.6059 1.4082-2.8652 1.4082-.34218 0-.54909-.063339-.61719-.18945-.06873-.12672-.10352-.42897-.10352-.9082v-10.262z" fill="#fff"/><path d="m137.91 48.551v1.2109h.85938v-1.2109zm-52.396.58984c-.99736 0-1.7963.32424-2.3926.96484-.59745.64576-.89453 1.5712-.89453 2.7773v3.0742c0 1.2329.31639 2.1765.94727 2.832.6333.66066 1.467.98828 2.5039.98828.78586 0 1.4321-.16147 1.9414-.48633.50993-.32273.8592-.67938 1.0488-1.0684v-3.6875h-3.0059v.74805h2.1465v2.6934c-.13766.30115-.38143.55386-.73242.76172-.34978.2109-.8171.31445-1.3984.31445-.79619 0-1.4265-.2632-1.8945-.78711-.46799-.52786-.70312-1.2936-.70312-2.2988v-3.0918c0-.96941.21778-1.7078.65234-2.2168.43578-.51023 1.0297-.76367 1.7812-.76367.74271 0 1.3056.19019 1.6836.56641.38017.37925.58276.91542.61133 1.6113h.79492l.013672-.041016c-.024311-.90802-.30456-1.6179-.83789-2.127-.53484-.50719-1.2907-.76367-2.2656-.76367zm7.6133 2.6641c-.719 0-1.3111.22524-1.7715.67773-.46222.45371-.68069.96571-.6582 1.5449l.013672.041015.79688.007813c0-.42696.14768-.78487.44336-1.0781.2966-.29508.67455-.44141 1.1328-.44141.4926 0 .87459.15388 1.1523.45898.27198.30906.41016.73655.41016 1.2793v.94531h-1.3418c-.85666 0-1.5379.21084-2.0391.63477-.50142.42392-.75195.99502-.75195 1.707 0 .67372.17358 1.2075.51758 1.6035.34613.39445.83497.5918 1.4707.5918.45462 0 .86723-.12355 1.2383-.37305.37166-.24767.67317-.56424.90625-.94531 0 .17413.01089.34527.03125.51758.02097.16927.053163.38614.095703.65234h.88867c-.062302-.24767-.10234-.49621-.12695-.75391-.02401-.25436-.037109-.52051-.037109-.79492v-3.7676c0-.80622-.21809-1.4265-.65234-1.8613-.43669-.43061-1.0083-.64648-1.7188-.64648zm7.1152 0c-.45462 0-.85109.11505-1.1875.3457-.33519.23369-.60486.56357-.80664.99023l-.074219-1.1934h-.75195v7.6816h.85352v-5.5293c.11791-.47346.31244-.84655.58594-1.1191.27168-.27107.63379-.4082 1.082-.4082.4689 0 .83314.19466 1.0957.58789.26378.39323.39258 1.0508.39258 1.9707v4.498h.85351v-4.6211-.19922c.0623-.64455.23396-1.1785.51172-1.6055.27927-.42696.66855-.63672 1.166-.63672.47285 0 .83879.19223 1.0938.57422.25345.38138.38281 1.0443.38281 1.9863v4.502h.85742v-4.4863c0-1.1332-.18468-1.9728-.55664-2.5195-.37044-.54548-.89268-.81836-1.5664-.81836-.48897 0-.91182.1465-1.2598.43945-.34796.29234-.61537.69589-.80469 1.207-.148-.55369-.38151-.966-.69726-1.2383-.31543-.2732-.70589-.4082-1.1699-.4082zm10.316 0c-.74423-.000001-1.3797.32125-1.9082.96094-.52725.64273-.78906 1.4505-.78906 2.4199v1.2754c0 .96758.26259 1.762.7871 2.3828.52604.62206 1.2032.93359 2.0312.93359.5157 0 .95833-.090281 1.3242-.26562.36679-.17626.66658-.41287.89844-.70703l-.34961-.60547c-.21728.27441-.4784.4836-.7832.63281-.3048.14586-.66987.2207-1.0898.2207-.60443 0-1.0864-.24489-1.4414-.74023-.35433-.49412-.53321-1.1138-.53321-1.8574v-.63867h4.3965v-.84375c0-.96667-.22381-1.7371-.66992-2.3105-.44519-.57253-1.0684-.85742-1.873-.85742zm9.4727 0c-.74423-.000001-1.3782.32125-1.9082.96094-.52603.64273-.79101 1.4505-.79101 2.4199v1.2754c0 .96758.26241 1.762.78906 2.3828.52512.62206 1.2028.93359 2.0312.93359.51601 0 .95639-.090281 1.3223-.26562.36741-.17626.66822-.41287.90039-.70703l-.34766-.60547c-.21972.27441-.4811.4836-.78711.63281-.30389.14586-.66639.2207-1.0879.2207-.60656 0-1.0883-.24489-1.4414-.74023-.35646-.49412-.5332-1.1138-.5332-1.8574v-.63867h4.3945v-.84375c0-.96667-.22338-1.7371-.66797-2.3105-.44398-.57253-1.0699-.85742-1.873-.85742zm6.8672 0c-.45614 0-.85274.12451-1.1894.36914-.33975.24342-.60962.5923-.81445 1.043l-.07031-1.2695h-.76172v7.6816h.85351v-5.4824c.14617-.47923.36569-.85918.66016-1.1445.29325-.28809.65767-.42969 1.0938-.42969.48622 0 .85922.17765 1.1133.5332.25557.35555.38477.96807.38477 1.8457v4.6777h.85937v-4.6855c0-1.0736-.18381-1.866-.55273-2.375-.36497-.50993-.89-.76367-1.5762-.76367zm6.2539 0c-.77674 0-1.386.32888-1.8242.98437-.44186.65883-.66211 1.5326-.66211 2.6211l.00196 1.0508c0 1.0031.21834 1.8072.65625 2.4102.43699.60413 1.0429.90625 1.8144.90625.41602 0 .78387-.091234 1.0996-.27539.31695-.18324.58484-.4491.80273-.79492v.92969c0 .75881-.14785 1.3303-.4414 1.7266-.29235.39111-.74301.58789-1.3535.58789-.30359 0-.59763-.04082-.88086-.125-.28565-.081443-.54279-.19619-.77344-.3457l-.23632.74805c.27047.15164.57916.27315.92773.36523.34795.092075.67388.13867.97656.13867.84208 0 1.494-.27297 1.9531-.81055.45857-.53971.68554-1.3009.68554-2.2852v-7.6895h-.72265l-.08399 1.0684c-.21485-.38533-.48269-.68758-.80664-.89453-.32334-.2109-.70159-.31641-1.1328-.31641zm10.467 0c-.45401 0-.85062.12451-1.1895.36914-.33914.24342-.60902.5923-.81445 1.043l-.07031-1.2695h-.75977v7.6816h.85352v-5.4824c.14556-.47923.3663-.85918.66016-1.1445.29295-.28809.65797-.42969 1.0937-.42969.48775 0 .85711.17765 1.1133.5332.25496.35555.38476.96807.38476 1.8457v4.6777h.85742v-4.6855c0-1.0736-.18081-1.866-.54882-2.375-.36588-.50993-.8939-.76367-1.5801-.76367zm6.4043 0c-.74271-.000001-1.3778.32125-1.9062.96094-.52724.64273-.79101 1.4505-.79101 2.4199v1.2754c0 .96758.26334 1.762.78906 2.3828.52361.62206 1.2007.93359 2.0312.93359.5154 0 .9567-.090281 1.3223-.26562.3668-.17626.6667-.41287.90039-.70703l-.34961-.60547c-.2194.27441-.47958.4836-.78711.63281-.30359.14586-.66597.2207-1.0859.2207-.60717 0-1.089-.24489-1.4434-.74023-.35464-.49412-.5332-1.1138-.5332-1.8574v-.63867h4.3965v-.84375c0-.96667-.22369-1.7371-.66797-2.3105-.44551-.57253-1.0709-.85742-1.875-.85742zm-12.113.14258v7.6816h.85938v-7.6816zm-27.352.60938c.53029 0 .9445.20789 1.2441.62695.29781.41876.44531.94616.44531 1.5801v.33008h-3.543c.01429-.71688.19281-1.3186.53711-1.8066.34401-.48622.78217-.73047 1.3164-.73047zm9.4727 0c.52998 0 .94406.20789 1.2422.62695.29963.41876.44727.94616.44727 1.5801v.33008h-3.543c.0155-.71688.19298-1.3186.53516-1.8066.3437-.48622.7826-.73047 1.3184-.73047zm29.992 0c.53089 0 .94602.20789 1.2441.62695.29902.41876.44532.94616.44532 1.5801v.33008h-3.543c.01519-.71688.19402-1.3186.53711-1.8066.34218-.48622.78064-.73047 1.3164-.73047zm-16.686.015625c.42119 0 .77033.1246 1.0469.375.27684.25466.4967.58706.65625.99609v3.8047c-.16593.39718-.39.70872-.67383.93359-.28475.22488-.63089.33594-1.043.33594-.6014 0-1.0536-.22975-1.3496-.69531-.29964-.4613-.44727-1.0819-.44727-1.8613v-1.0508c0-.84177.15149-1.527.45508-2.0527.30146-.52482.75528-.78516 1.3555-.78516zm-40.057 3.3281h1.3652v1.6621c-.15286.42089-.40964.76752-.77734 1.041-.3671.27228-.78783.40625-1.2598.40625-.39262 0-.69782-.12824-.91602-.38867-.2185-.25952-.32617-.59591-.32617-1.0059 0-.48531.17262-.89402.52148-1.2207.34795-.32881.81215-.49414 1.3926-.49414z" fill="#e0e0e0"/><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(.30389749 0 0 -.30389749 63.620953 46.532114)"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164715 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426579-6.973692 9.2079702-13.9828876 13.621-19.449z" fill="#478cbf" transform="matrix(.30389749 0 0 -.30389749 4.154146 28.589689)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(.30389749 0 0 -.30389749 53.752732 49.859089)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(.30389749 0 0 -.30389749 24.925648 35.87311)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(.30389749 0 0 -.30389749 23.330605 36.266305)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(.30389749 0 0 -.30389749 33.889273 43.105751)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(.30389749 0 0 -.30389749 42.854008 35.87311)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(.30389749 0 0 -.30389749 44.449454 36.266305)"/></svg>
diff --git a/editor/icons/NodeDisabled.svg b/editor/icons/NodeDisabled.svg
new file mode 100644
index 0000000000..b2d51fc4fb
--- /dev/null
+++ b/editor/icons/NodeDisabled.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#999"/></svg>
diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp
index 8eb68ecdcf..e38034dd8c 100644
--- a/editor/import/collada.cpp
+++ b/editor/import/collada.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -289,7 +289,7 @@ void Collada::_parse_image(XMLParser &parser) {
String path = parser.get_attribute_value("source").strip_edges();
if (path.find("://") == -1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
- image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().plus_file(path.percent_decode()));
+ image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().plus_file(path.uri_decode()));
}
} else {
while (parser.read() == OK) {
@@ -298,7 +298,7 @@ void Collada::_parse_image(XMLParser &parser) {
if (name == "init_from") {
parser.read();
- String path = parser.get_node_data().strip_edges().percent_decode();
+ String path = parser.get_node_data().strip_edges().uri_decode();
if (path.find("://") == -1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
@@ -1365,7 +1365,7 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
}
if (geom->controller) {
- if (geom->skeletons.empty()) {
+ if (geom->skeletons.is_empty()) {
//XSI style
if (state.skin_controller_data_map.has(geom->source)) {
@@ -2321,7 +2321,7 @@ void Collada::_optimize() {
i--;
}
- while (!mgeom.empty()) {
+ while (!mgeom.is_empty()) {
Node *n = mgeom.front()->get();
n->parent->children.push_back(n);
mgeom.pop_front();
diff --git a/editor/import/collada.h b/editor/import/collada.h
index 29d49d4aa7..2c3f0a3006 100644
--- a/editor/import/collada.h
+++ b/editor/import/collada.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -274,7 +274,7 @@ public:
if (normal == p_vert.normal) {
if (uv == p_vert.uv) {
if (uv2 == p_vert.uv2) {
- if (!weights.empty() || !p_vert.weights.empty()) {
+ if (!weights.is_empty() || !p_vert.weights.is_empty()) {
if (weights.size() == p_vert.weights.size()) {
for (int i = 0; i < weights.size(); i++) {
if (weights[i].bone_idx != p_vert.weights[i].bone_idx) {
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index db5b7b36aa..50b13673fa 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1027,7 +1027,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
Vector<String> skeletons = ng2->skeletons;
- ERR_FAIL_COND_V(skeletons.empty(), ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(skeletons.is_empty(), ERR_INVALID_DATA);
String skname = skeletons[0];
ERR_FAIL_COND_V(!node_map.has(skname), ERR_INVALID_DATA);
@@ -1471,7 +1471,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
}
Vector<float> data = at.get_value_at_time(snapshots[i]);
- ERR_CONTINUE(data.empty());
+ ERR_CONTINUE(data.is_empty());
Collada::Node::XForm &xf = cn->xform_list.write[xform_idx];
diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h
index 5fa17ebd02..bf45322765 100644
--- a/editor/import/editor_import_collada.h
+++ b/editor/import/editor_import_collada.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp
index 2658031bd9..44aff874eb 100644
--- a/editor/import/editor_import_plugin.cpp
+++ b/editor/import/editor_import_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h
index 00a7d9efba..345a40e96d 100644
--- a/editor/import/editor_import_plugin.h
+++ b/editor/import/editor_import_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp
index 06b56fd73f..ffef759c07 100644
--- a/editor/import/resource_importer_bitmask.cpp
+++ b/editor/import/resource_importer_bitmask.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h
index 83959f87cd..d68693c54a 100644
--- a/editor/import/resource_importer_bitmask.h
+++ b/editor/import/resource_importer_bitmask.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_csv.cpp b/editor/import/resource_importer_csv.cpp
index d29ba28a96..f621ce7855 100644
--- a/editor/import/resource_importer_csv.cpp
+++ b/editor/import/resource_importer_csv.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_csv.h b/editor/import/resource_importer_csv.h
index c9fbe75dd2..0f137624b9 100644
--- a/editor/import/resource_importer_csv.h
+++ b/editor/import/resource_importer_csv.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp
index 4c6200e033..7ea39ab3ef 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h
index 7c7646b640..d53e91e38b 100644
--- a/editor/import/resource_importer_csv_translation.h
+++ b/editor/import/resource_importer_csv_translation.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp
index 885b00865b..26c6a8462b 100644
--- a/editor/import/resource_importer_image.cpp
+++ b/editor/import/resource_importer_image.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h
index 703b36b091..7c8d5e228e 100644
--- a/editor/import/resource_importer_image.h
+++ b/editor/import/resource_importer_image.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index ac068c05cf..6d2215c379 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -373,7 +373,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
int x = slice_w * j;
int y = slice_h * i;
Ref<Image> slice = image->get_rect(Rect2(x, y, slice_w, slice_h));
- ERR_CONTINUE(slice.is_null() || slice->empty());
+ ERR_CONTINUE(slice.is_null() || slice->is_empty());
if (slice->get_width() != slice_w || slice->get_height() != slice_h) {
slice->resize(slice_w, slice_h);
}
@@ -391,8 +391,8 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
bool ok_on_pc = false;
bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995);
bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGB565);
- bool can_bptc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc");
- bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc");
+ bool can_bptc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc");
+ bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_s3tc");
if (can_bptc) {
formats_imported.push_back("bptc"); //needs to be aded anyway
@@ -447,13 +447,13 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
ok_on_pc = true;
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
+ if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2")) {
_save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true);
r_platform_variants->push_back("etc2");
formats_imported.push_back("etc2");
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
+ if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc")) {
_save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true);
r_platform_variants->push_back("pvrtc");
formats_imported.push_back("pvrtc");
@@ -492,7 +492,7 @@ String ResourceImporterLayeredTexture::get_import_settings_string() const {
int index = 0;
while (compression_formats[index]) {
- String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]);
+ String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
bool test = ProjectSettings::get_singleton()->get(setting_path);
if (test) {
s += String(compression_formats[index]);
@@ -524,7 +524,7 @@ bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_p
int index = 0;
bool valid = true;
while (compression_formats[index]) {
- String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]);
+ String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
bool test = ProjectSettings::get_singleton()->get(setting_path);
if (test) {
if (formats_imported.find(compression_formats[index]) == -1) {
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
index 7ac3d55dec..86e9c5bde8 100644
--- a/editor/import/resource_importer_layered_texture.h
+++ b/editor/import/resource_importer_layered_texture.h
@@ -5,38 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-/*************************************************************************/
-/* resource_importer_layered_texture.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index e7170ef61c..9111252943 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h
index 97f747b33c..414e0c1fe6 100644
--- a/editor/import/resource_importer_obj.h
+++ b/editor/import/resource_importer_obj.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index d36d811ce8..14ecccc13e 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,7 +35,7 @@
#include "editor/import/scene_importer_mesh_node_3d.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/3d/mesh_instance_3d.h"
-#include "scene/3d/navigation_3d.h"
+#include "scene/3d/navigation_region_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/3d/vehicle_body_3d.h"
#include "scene/animation/animation_player.h"
@@ -431,7 +431,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
CollisionShape3D *colshape = memnew(CollisionShape3D);
if (empty_draw_type == "CUBE") {
BoxShape3D *boxShape = memnew(BoxShape3D);
- boxShape->set_extents(Vector3(1, 1, 1));
+ boxShape->set_size(Vector3(2, 2, 2));
colshape->set_shape(boxShape);
colshape->set_name("BoxShape3D");
} else if (empty_draw_type == "SINGLE_ARROW") {
@@ -964,7 +964,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
if (FileAccess::exists(ext_name) && p_keep_animations) {
// Copy custom animation tracks from previously imported files.
- Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", true);
+ Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", ResourceFormatLoader::CACHE_MODE_IGNORE);
if (old_anim.is_valid()) {
for (int i = 0; i < old_anim->get_track_count(); i++) {
if (!old_anim->track_is_imported(i)) {
@@ -1004,7 +1004,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
p_materials[mat] = ResourceLoader::load(ext_name);
} else {
ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH);
- p_materials[mat] = ResourceLoader::load(ext_name, "", true); // disable loading from the cache.
+ p_materials[mat] = ResourceLoader::load(ext_name, "", ResourceFormatLoader::CACHE_MODE_IGNORE); // disable loading from the cache.
}
}
@@ -1061,7 +1061,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
p_materials[mat] = ResourceLoader::load(ext_name);
} else {
ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH);
- p_materials[mat] = ResourceLoader::load(ext_name, "", true); // disable loading from the cache.
+ p_materials[mat] = ResourceLoader::load(ext_name, "", ResourceFormatLoader::CACHE_MODE_IGNORE); // disable loading from the cache.
}
}
@@ -1129,6 +1129,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files (.mesh),Files (.tres)"), meshes_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/generate_lods"), true));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/create_shadow_meshes"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Enable,Gen Lightmaps", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.1));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true));
@@ -1221,7 +1222,7 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito
return importer->import_animation(p_path, p_flags, p_bake_fps);
}
-void ResourceImporterScene::_generate_meshes(Node *p_node, bool p_generate_lods) {
+void ResourceImporterScene::_generate_meshes(Node *p_node, bool p_generate_lods, bool p_create_shadow_meshes) {
EditorSceneImporterMeshNode3D *src_mesh_node = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
if (src_mesh_node) {
//is mesh
@@ -1237,8 +1238,12 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, bool p_generate_lods)
if (p_generate_lods) {
src_mesh_node->get_mesh()->generate_lods();
}
+ if (p_create_shadow_meshes) {
+ src_mesh_node->get_mesh()->create_shadow_mesh();
+ }
}
mesh = src_mesh_node->get_mesh()->get_mesh();
+
if (mesh.is_valid()) {
mesh_node->set_mesh(mesh);
for (int i = 0; i < mesh->get_surface_count(); i++) {
@@ -1252,7 +1257,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, bool p_generate_lods)
}
for (int i = 0; i < p_node->get_child_count(); i++) {
- _generate_meshes(p_node->get_child(i), p_generate_lods);
+ _generate_meshes(p_node->get_child(i), p_generate_lods, p_create_shadow_meshes);
}
}
Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
@@ -1348,8 +1353,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
}
bool gen_lods = bool(p_options["meshes/generate_lods"]);
+ bool create_shadow_meshes = bool(p_options["meshes/create_shadow_meshes"]);
- _generate_meshes(scene, gen_lods);
+ _generate_meshes(scene, gen_lods, create_shadow_meshes);
err = OK;
@@ -1468,7 +1474,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
if (!ret_used_cache) {
// Cache was not used, add the generated entry to the current cache
- if (cache_data.empty()) {
+ if (cache_data.is_empty()) {
cache_data.resize(4 + ret_cache_size);
int *data = (int *)cache_data.ptrw();
data[0] = 1;
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 5b70f5bd81..aced0226ff 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -121,7 +121,7 @@ class ResourceImporterScene : public ResourceImporter {
};
void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
- void _generate_meshes(Node *p_node, bool p_generate_lods);
+ void _generate_meshes(Node *p_node, bool p_generate_lods, bool p_create_shadow_meshes);
public:
static ResourceImporterScene *get_singleton() { return singleton; }
diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp
index a2e80dfa18..f4d20a6296 100644
--- a/editor/import/resource_importer_shader_file.cpp
+++ b/editor/import/resource_importer_shader_file.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_shader_file.h b/editor/import/resource_importer_shader_file.h
index 66ae626c51..c421132ec2 100644
--- a/editor/import/resource_importer_shader_file.h
+++ b/editor/import/resource_importer_shader_file.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index c8dae53722..de8031af35 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -82,7 +82,7 @@ void ResourceImporterTexture::update_imports() {
MutexLock lock(mutex);
Vector<String> to_reimport;
{
- if (make_flags.empty()) {
+ if (make_flags.is_empty()) {
return;
}
@@ -172,7 +172,7 @@ bool ResourceImporterTexture::get_option_visibility(const String &p_option, cons
if (compress_mode < COMPRESS_VRAM_COMPRESSED) {
return false;
}
- if (!ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc")) {
+ if (!ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc")) {
return false;
}
}
@@ -201,7 +201,7 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/channel_pack", PROPERTY_HINT_ENUM, "sRGB Friendly,Optimized"), 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/streamed"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/streamed"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), (p_preset == PRESET_3D ? true : false)));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "roughness/mode", PROPERTY_HINT_ENUM, "Detect,Disabled,Red,Green,Blue,Alpha,Gray"), 0));
@@ -473,8 +473,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
bool ok_on_pc = false;
bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995);
bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGB565);
- bool can_bptc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc");
- bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc");
+ bool can_bptc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_bptc");
+ bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_s3tc");
if (can_bptc) {
//add to the list anyway
@@ -524,19 +524,19 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
ok_on_pc = true;
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
+ if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2")) {
_save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
r_platform_variants->push_back("etc2");
formats_imported.push_back("etc2");
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
+ if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc")) {
_save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
r_platform_variants->push_back("etc");
formats_imported.push_back("etc");
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
+ if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc")) {
_save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC1_4, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
r_platform_variants->push_back("pvrtc");
formats_imported.push_back("pvrtc");
@@ -574,7 +574,7 @@ String ResourceImporterTexture::get_import_settings_string() const {
int index = 0;
while (compression_formats[index]) {
- String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]);
+ String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
bool test = ProjectSettings::get_singleton()->get(setting_path);
if (test) {
s += String(compression_formats[index]);
@@ -606,7 +606,7 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) co
int index = 0;
bool valid = true;
while (compression_formats[index]) {
- String setting_path = "rendering/vram_compression/import_" + String(compression_formats[index]);
+ String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
bool test = ProjectSettings::get_singleton()->get(setting_path);
if (test) {
if (formats_imported.find(compression_formats[index]) == -1) {
diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h
index 39036d4423..0d551a965c 100644
--- a/editor/import/resource_importer_texture.h
+++ b/editor/import/resource_importer_texture.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -62,7 +62,7 @@ protected:
struct MakeInfo {
int flags = 0;
String normal_path_for_roughness;
- RS::TextureDetectRoughnessChannel channel_for_roughness = RS::TEXTURE_DETECT_ROUGNHESS_R;
+ RS::TextureDetectRoughnessChannel channel_for_roughness = RS::TEXTURE_DETECT_ROUGHNESS_R;
};
Map<StringName, MakeInfo> make_flags;
diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp
index c9f689cc08..4c3ae59951 100644
--- a/editor/import/resource_importer_texture_atlas.cpp
+++ b/editor/import/resource_importer_texture_atlas.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_texture_atlas.h b/editor/import/resource_importer_texture_atlas.h
index d237b096d3..b675d12477 100644
--- a/editor/import/resource_importer_texture_atlas.h
+++ b/editor/import/resource_importer_texture_atlas.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index cb669b4c89..bcc55b330b 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h
index 3c4a8757eb..7413dbd11c 100644
--- a/editor/import/resource_importer_wav.h
+++ b/editor/import/resource_importer_wav.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp
index d7c3b60d5a..46eb4e4fdc 100644
--- a/editor/import/scene_importer_mesh.cpp
+++ b/editor/import/scene_importer_mesh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -140,6 +140,12 @@ void EditorSceneImporterMesh::generate_lods() {
if (!SurfaceTool::simplify_func) {
return;
}
+ if (!SurfaceTool::simplify_scale_func) {
+ return;
+ }
+ if (!SurfaceTool::simplify_sloppy_func) {
+ return;
+ }
for (int i = 0; i < surfaces.size(); i++) {
if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) {
@@ -157,20 +163,52 @@ void EditorSceneImporterMesh::generate_lods() {
int min_indices = 10;
int index_target = indices.size() / 2;
- print_line("total: " + itos(indices.size()));
+ print_line("Total indices: " + itos(indices.size()));
+ float mesh_scale = SurfaceTool::simplify_scale_func((const float *)vertices_ptr, vertex_count, sizeof(Vector3));
+ const float target_error = 1e-3f;
+ float abs_target_error = target_error / mesh_scale;
while (index_target > min_indices) {
float error;
Vector<int> new_indices;
new_indices.resize(indices.size());
- size_t new_len = SurfaceTool::simplify_func((unsigned int *)new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, 1e20, &error);
- print_line("shoot for " + itos(index_target) + ", got " + itos(new_len) + " distance " + rtos(error));
+ size_t new_len = SurfaceTool::simplify_func((unsigned int *)new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, abs_target_error, &error);
if ((int)new_len > (index_target * 120 / 100)) {
+ // Attribute discontinuities break normals.
+ bool is_sloppy = false;
+ if (is_sloppy) {
+ abs_target_error = target_error / mesh_scale;
+ index_target = new_len;
+ while (index_target > min_indices) {
+ Vector<int> sloppy_new_indices;
+ sloppy_new_indices.resize(indices.size());
+ new_len = SurfaceTool::simplify_sloppy_func((unsigned int *)sloppy_new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, abs_target_error, &error);
+ if ((int)new_len > (index_target * 120 / 100)) {
+ break; // 20 percent tolerance
+ }
+ sloppy_new_indices.resize(new_len);
+ Surface::LOD lod;
+ lod.distance = error * mesh_scale;
+ abs_target_error = lod.distance;
+ if (Math::is_equal_approx(abs_target_error, 0.0f)) {
+ return;
+ }
+ lod.indices = sloppy_new_indices;
+ print_line("Lod " + itos(surfaces.write[i].lods.size()) + " shoot for " + itos(index_target / 3) + " triangles, got " + itos(new_len / 3) + " triangles. Distance " + rtos(lod.distance) + ". Use simplify sloppy.");
+ surfaces.write[i].lods.push_back(lod);
+ index_target /= 2;
+ }
+ }
break; // 20 percent tolerance
}
new_indices.resize(new_len);
Surface::LOD lod;
- lod.distance = error;
+ lod.distance = error * mesh_scale;
+ abs_target_error = lod.distance;
+ if (Math::is_equal_approx(abs_target_error, 0.0f)) {
+ return;
+ }
lod.indices = new_indices;
+ print_line("Lod " + itos(surfaces.write[i].lods.size()) + " shoot for " + itos(index_target / 3) + " triangles, got " + itos(new_len / 3) + " triangles. Distance " + rtos(lod.distance));
surfaces.write[i].lods.push_back(lod);
index_target /= 2;
}
@@ -212,6 +250,11 @@ Ref<ArrayMesh> EditorSceneImporterMesh::get_mesh() {
mesh->surface_set_name(mesh->get_surface_count() - 1, surfaces[i].name);
}
}
+
+ if (shadow_mesh.is_valid()) {
+ Ref<ArrayMesh> shadow = shadow_mesh->get_mesh();
+ mesh->set_shadow_mesh(shadow);
+ }
}
return mesh;
@@ -223,6 +266,103 @@ void EditorSceneImporterMesh::clear() {
mesh.unref();
}
+void EditorSceneImporterMesh::create_shadow_mesh() {
+ if (shadow_mesh.is_valid()) {
+ shadow_mesh.unref();
+ }
+
+ //no shadow mesh for blendshapes
+ if (blend_shapes.size() > 0) {
+ return;
+ }
+ //no shadow mesh for skeletons
+ for (int i = 0; i < surfaces.size(); i++) {
+ if (surfaces[i].arrays[RS::ARRAY_BONES].get_type() != Variant::NIL) {
+ return;
+ }
+ if (surfaces[i].arrays[RS::ARRAY_WEIGHTS].get_type() != Variant::NIL) {
+ return;
+ }
+ }
+
+ shadow_mesh.instance();
+
+ for (int i = 0; i < surfaces.size(); i++) {
+ LocalVector<int> vertex_remap;
+ Vector<Vector3> new_vertices;
+ Vector<Vector3> vertices = surfaces[i].arrays[RS::ARRAY_VERTEX];
+ int vertex_count = vertices.size();
+ {
+ Map<Vector3, int> unique_vertices;
+ const Vector3 *vptr = vertices.ptr();
+ for (int j = 0; j < vertex_count; j++) {
+ Vector3 v = vptr[j];
+
+ Map<Vector3, int>::Element *E = unique_vertices.find(v);
+
+ if (E) {
+ vertex_remap.push_back(E->get());
+ } else {
+ int vcount = unique_vertices.size();
+ unique_vertices[v] = vcount;
+ vertex_remap.push_back(vcount);
+ new_vertices.push_back(v);
+ }
+ }
+ }
+
+ Array new_surface;
+ new_surface.resize(RS::ARRAY_MAX);
+ Dictionary lods;
+
+ // print_line("original vertex count: " + itos(vertices.size()) + " new vertex count: " + itos(new_vertices.size()));
+
+ new_surface[RS::ARRAY_VERTEX] = new_vertices;
+
+ Vector<int> indices = surfaces[i].arrays[RS::ARRAY_INDEX];
+ if (indices.size()) {
+ int index_count = indices.size();
+ const int *index_rptr = indices.ptr();
+ Vector<int> new_indices;
+ new_indices.resize(indices.size());
+ int *index_wptr = new_indices.ptrw();
+
+ for (int j = 0; j < index_count; j++) {
+ int index = index_rptr[j];
+ ERR_FAIL_INDEX(index, vertex_count);
+ index_wptr[j] = vertex_remap[index];
+ }
+
+ new_surface[RS::ARRAY_INDEX] = new_indices;
+
+ // Make sure the same LODs as the full version are used.
+ // This makes it more coherent between rendered model and its shadows.
+ for (int j = 0; j < surfaces[i].lods.size(); j++) {
+ indices = surfaces[i].lods[j].indices;
+
+ index_count = indices.size();
+ index_rptr = indices.ptr();
+ new_indices.resize(indices.size());
+ index_wptr = new_indices.ptrw();
+
+ for (int k = 0; k < index_count; k++) {
+ int index = index_rptr[j];
+ ERR_FAIL_INDEX(index, vertex_count);
+ index_wptr[j] = vertex_remap[index];
+ }
+
+ lods[surfaces[i].lods[j].distance] = new_indices;
+ }
+ }
+
+ shadow_mesh->add_surface(surfaces[i].primitive, new_surface, Array(), lods, Ref<Material>(), surfaces[i].name);
+ }
+}
+
+Ref<EditorSceneImporterMesh> EditorSceneImporterMesh::get_shadow_mesh() const {
+ return shadow_mesh;
+}
+
void EditorSceneImporterMesh::_set_data(const Dictionary &p_data) {
clear();
if (p_data.has("blend_shape_names")) {
@@ -304,7 +444,7 @@ void EditorSceneImporterMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &EditorSceneImporterMesh::set_blend_shape_mode);
ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &EditorSceneImporterMesh::get_blend_shape_mode);
- ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material"), &EditorSceneImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name"), &EditorSceneImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()));
ClassDB::bind_method(D_METHOD("get_surface_count"), &EditorSceneImporterMesh::get_surface_count);
ClassDB::bind_method(D_METHOD("get_surface_primitive_type", "surface_idx"), &EditorSceneImporterMesh::get_surface_primitive_type);
diff --git a/editor/import/scene_importer_mesh.h b/editor/import/scene_importer_mesh.h
index 7efe2f2ffb..42507cbe8c 100644
--- a/editor/import/scene_importer_mesh.h
+++ b/editor/import/scene_importer_mesh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -61,6 +61,8 @@ class EditorSceneImporterMesh : public Resource {
Ref<ArrayMesh> mesh;
+ Ref<EditorSceneImporterMesh> shadow_mesh;
+
protected:
void _set_data(const Dictionary &p_data);
Dictionary _get_data() const;
@@ -89,6 +91,9 @@ public:
void generate_lods();
+ void create_shadow_mesh();
+ Ref<EditorSceneImporterMesh> get_shadow_mesh() const;
+
bool has_mesh() const;
Ref<ArrayMesh> get_mesh();
void clear();
diff --git a/editor/import/scene_importer_mesh_node_3d.cpp b/editor/import/scene_importer_mesh_node_3d.cpp
index 53929f77b0..3c201cf674 100644
--- a/editor/import/scene_importer_mesh_node_3d.cpp
+++ b/editor/import/scene_importer_mesh_node_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/scene_importer_mesh_node_3d.h b/editor/import/scene_importer_mesh_node_3d.h
index 9540e3b886..dec1717c99 100644
--- a/editor/import/scene_importer_mesh_node_3d.h
+++ b/editor/import/scene_importer_mesh_node_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import_defaults_editor.cpp b/editor/import_defaults_editor.cpp
new file mode 100644
index 0000000000..43b97eb910
--- /dev/null
+++ b/editor/import_defaults_editor.cpp
@@ -0,0 +1,216 @@
+/*************************************************************************/
+/* import_defaults_editor.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "import_defaults_editor.h"
+
+class ImportDefaultsEditorSettings : public Object {
+ GDCLASS(ImportDefaultsEditorSettings, Object)
+ friend class ImportDefaultsEditor;
+ List<PropertyInfo> properties;
+ Map<StringName, Variant> values;
+ Map<StringName, Variant> default_values;
+
+ Ref<ResourceImporter> importer;
+
+protected:
+ bool _set(const StringName &p_name, const Variant &p_value) {
+ if (values.has(p_name)) {
+ values[p_name] = p_value;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ bool _get(const StringName &p_name, Variant &r_ret) const {
+ if (values.has(p_name)) {
+ r_ret = values[p_name];
+ return true;
+ } else {
+ r_ret = Variant();
+ return false;
+ }
+ }
+ void _get_property_list(List<PropertyInfo> *p_list) const {
+ if (importer.is_null()) {
+ return;
+ }
+ for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ if (importer->get_option_visibility(E->get().name, values)) {
+ p_list->push_back(E->get());
+ }
+ }
+ }
+};
+
+void ImportDefaultsEditor::_notification(int p_what) {
+ if (p_what == NOTIFICATION_PREDELETE) {
+ inspector->edit(nullptr);
+ }
+}
+
+void ImportDefaultsEditor::_reset() {
+ if (settings->importer.is_valid()) {
+ settings->values = settings->default_values;
+ settings->notify_property_list_changed();
+ }
+}
+
+void ImportDefaultsEditor::_save() {
+ if (settings->importer.is_valid()) {
+ Dictionary modified;
+
+ for (Map<StringName, Variant>::Element *E = settings->values.front(); E; E = E->next()) {
+ if (E->get() != settings->default_values[E->key()]) {
+ modified[E->key()] = E->get();
+ }
+ }
+
+ if (modified.size()) {
+ ProjectSettings::get_singleton()->set("importer_defaults/" + settings->importer->get_importer_name(), modified);
+ } else {
+ ProjectSettings::get_singleton()->set("importer_defaults/" + settings->importer->get_importer_name(), Variant());
+ }
+
+ emit_signal("project_settings_changed");
+ }
+}
+
+void ImportDefaultsEditor::_update_importer() {
+ List<Ref<ResourceImporter>> importer_list;
+ ResourceFormatImporter::get_singleton()->get_importers(&importer_list);
+ Ref<ResourceImporter> importer;
+ for (List<Ref<ResourceImporter>>::Element *E = importer_list.front(); E; E = E->next()) {
+ if (E->get()->get_visible_name() == importers->get_item_text(importers->get_selected())) {
+ importer = E->get();
+ break;
+ }
+ }
+
+ settings->properties.clear();
+ settings->values.clear();
+ settings->importer = importer;
+
+ if (importer.is_valid()) {
+ List<ResourceImporter::ImportOption> options;
+ importer->get_import_options(&options);
+ Dictionary d;
+ if (ProjectSettings::get_singleton()->has_setting("importer_defaults/" + importer->get_importer_name())) {
+ d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name());
+ }
+
+ for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
+ settings->properties.push_back(E->get().option);
+ if (d.has(E->get().option.name)) {
+ settings->values[E->get().option.name] = d[E->get().option.name];
+ } else {
+ settings->values[E->get().option.name] = E->get().default_value;
+ }
+ settings->default_values[E->get().option.name] = E->get().default_value;
+ }
+
+ save_defaults->set_disabled(false);
+ reset_defaults->set_disabled(false);
+
+ } else {
+ save_defaults->set_disabled(true);
+ reset_defaults->set_disabled(true);
+ }
+
+ settings->notify_property_list_changed();
+
+ inspector->edit(settings);
+}
+
+void ImportDefaultsEditor::_importer_selected(int p_index) {
+ _update_importer();
+}
+
+void ImportDefaultsEditor::clear() {
+ String last_selected;
+ if (importers->get_selected() > 0) {
+ last_selected = importers->get_item_text(importers->get_selected());
+ }
+
+ importers->clear();
+
+ importers->add_item("<" + TTR("Select Importer") + ">");
+ importers->set_item_disabled(0, true);
+
+ List<Ref<ResourceImporter>> importer_list;
+ ResourceFormatImporter::get_singleton()->get_importers(&importer_list);
+ Vector<String> names;
+ for (List<Ref<ResourceImporter>>::Element *E = importer_list.front(); E; E = E->next()) {
+ String vn = E->get()->get_visible_name();
+ names.push_back(vn);
+ }
+ names.sort();
+
+ for (int i = 0; i < names.size(); i++) {
+ importers->add_item(names[i]);
+
+ if (names[i] == last_selected) {
+ importers->select(i + 1);
+ }
+ }
+}
+
+void ImportDefaultsEditor::_bind_methods() {
+ ADD_SIGNAL(MethodInfo("project_settings_changed"));
+}
+
+ImportDefaultsEditor::ImportDefaultsEditor() {
+ HBoxContainer *hb = memnew(HBoxContainer);
+ hb->add_child(memnew(Label(TTR("Importer:"))));
+ importers = memnew(OptionButton);
+ hb->add_child(importers);
+ hb->add_spacer();
+ importers->connect("item_selected", callable_mp(this, &ImportDefaultsEditor::_importer_selected));
+ reset_defaults = memnew(Button);
+ reset_defaults->set_text(TTR("Reset to Defaults"));
+ reset_defaults->set_disabled(true);
+ reset_defaults->connect("pressed", callable_mp(this, &ImportDefaultsEditor::_reset));
+ hb->add_child(reset_defaults);
+ add_child(hb);
+ inspector = memnew(EditorInspector);
+ add_child(inspector);
+ inspector->set_v_size_flags(SIZE_EXPAND_FILL);
+ CenterContainer *cc = memnew(CenterContainer);
+ save_defaults = memnew(Button);
+ save_defaults->set_text(TTR("Save"));
+ save_defaults->connect("pressed", callable_mp(this, &ImportDefaultsEditor::_save));
+ cc->add_child(save_defaults);
+ add_child(cc);
+
+ settings = memnew(ImportDefaultsEditorSettings);
+}
+
+ImportDefaultsEditor::~ImportDefaultsEditor() {
+ memdelete(settings);
+}
diff --git a/editor/editor_sub_scene.h b/editor/import_defaults_editor.h
index bdfbbca02f..c1becac5e9 100644
--- a/editor/editor_sub_scene.h
+++ b/editor/import_defaults_editor.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* editor_sub_scene.h */
+/* import_defaults_editor.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,44 +28,48 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef EDITOR_SUB_SCENE_H
-#define EDITOR_SUB_SCENE_H
+#ifndef IMPORT_DEFAULTS_EDITOR_H
+#define IMPORT_DEFAULTS_EDITOR_H
-#include "editor/editor_file_dialog.h"
-#include "scene/gui/dialogs.h"
-#include "scene/gui/tree.h"
+#include "core/object/undo_redo.h"
+#include "editor/action_map_editor.h"
+#include "editor/editor_data.h"
+#include "editor/editor_plugin_settings.h"
+#include "editor/editor_sectioned_inspector.h"
+#include "editor/localization_editor.h"
+#include "editor/shader_globals_editor.h"
+#include "editor_autoload_settings.h"
+#include "scene/gui/center_container.h"
+#include "scene/gui/option_button.h"
-class EditorSubScene : public ConfirmationDialog {
- GDCLASS(EditorSubScene, ConfirmationDialog);
+class ImportDefaultsEditorSettings;
- List<Node *> selection;
- LineEdit *path;
- Tree *tree;
- Node *scene;
- bool is_root;
+class ImportDefaultsEditor : public VBoxContainer {
+ GDCLASS(ImportDefaultsEditor, VBoxContainer)
- EditorFileDialog *file_dialog;
+ OptionButton *importers;
+ Button *save_defaults;
+ Button *reset_defaults;
- void _fill_tree(Node *p_node, TreeItem *p_parent);
- void _selected_changed();
- void _item_multi_selected(Object *p_object, int p_cell, bool p_selected);
- void _item_activated();
- void _remove_selection_child(Node *p_node);
- void _reown(Node *p_node, List<Node *> *p_to_reown);
+ EditorInspector *inspector;
- void ok_pressed() override;
+ ImportDefaultsEditorSettings *settings;
+
+ void _update_importer();
+ void _importer_selected(int p_index);
+
+ void _reset();
+ void _save();
protected:
void _notification(int p_what);
static void _bind_methods();
- void _path_browse();
- void _path_selected(const String &p_path);
- void _path_changed(const String &p_path);
public:
- void move(Node *p_new_parent, Node *p_new_owner);
void clear();
- EditorSubScene();
+
+ ImportDefaultsEditor();
+ ~ImportDefaultsEditor();
};
-#endif // EDITOR_SUB_SCENE_H
+#endif // IMPORT_DEFAULTS_EDITOR_H
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 5582f9f5f0..97a04e6557 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,7 +48,7 @@ public:
values[p_name] = p_value;
if (checking) {
checked.insert(p_name);
- _change_notify();
+ notify_property_list_changed();
}
return true;
}
@@ -81,7 +81,7 @@ public:
}
void update() {
- _change_notify();
+ notify_property_list_changed();
}
ImportDockParameters() {
diff --git a/editor/import_dock.h b/editor/import_dock.h
index 7a2e669620..6c5779ddce 100644
--- a/editor/import_dock.h
+++ b/editor/import_dock.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/input_map_editor.cpp b/editor/input_map_editor.cpp
deleted file mode 100644
index 249b9770b1..0000000000
--- a/editor/input_map_editor.cpp
+++ /dev/null
@@ -1,1033 +0,0 @@
-/*************************************************************************/
-/* input_map_editor.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "input_map_editor.h"
-
-#include "core/input/input_map.h"
-#include "core/os/keyboard.h"
-#include "editor/editor_node.h"
-#include "editor/editor_scale.h"
-
-void InputMapEditor::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- action_add_error->add_theme_color_override("font_color", input_editor->get_theme_color("error_color", "Editor"));
- popup_add->add_icon_item(input_editor->get_theme_icon("Keyboard", "EditorIcons"), TTR("Key"), INPUT_KEY);
- popup_add->add_icon_item(input_editor->get_theme_icon("KeyboardPhysical", "EditorIcons"), TTR("Physical Key"), INPUT_KEY_PHYSICAL);
- popup_add->add_icon_item(input_editor->get_theme_icon("JoyButton", "EditorIcons"), TTR("Joy Button"), INPUT_JOY_BUTTON);
- popup_add->add_icon_item(input_editor->get_theme_icon("JoyAxis", "EditorIcons"), TTR("Joy Axis"), INPUT_JOY_MOTION);
- popup_add->add_icon_item(input_editor->get_theme_icon("Mouse", "EditorIcons"), TTR("Mouse Button"), INPUT_MOUSE_BUTTON);
- _update_actions();
- } break;
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- action_add_error->add_theme_color_override("font_color", input_editor->get_theme_color("error_color", "Editor"));
- popup_add->set_item_icon(popup_add->get_item_index(INPUT_KEY), input_editor->get_theme_icon("Keyboard", "EditorIcons"));
- popup_add->set_item_icon(popup_add->get_item_index(INPUT_KEY_PHYSICAL), input_editor->get_theme_icon("KeyboardPhysical", "EditorIcons"));
- popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_BUTTON), input_editor->get_theme_icon("JoyButton", "EditorIcons"));
- popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_MOTION), input_editor->get_theme_icon("JoyAxis", "EditorIcons"));
- popup_add->set_item_icon(popup_add->get_item_index(INPUT_MOUSE_BUTTON), input_editor->get_theme_icon("Mouse", "EditorIcons"));
- _update_actions();
- } break;
- }
-}
-
-static bool _validate_action_name(const String &p_name) {
- const char32_t *cstr = p_name.get_data();
- for (int i = 0; cstr[i]; i++) {
- if (cstr[i] == '/' || cstr[i] == ':' || cstr[i] == '"' ||
- cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32) {
- return false;
- }
- }
- return true;
-}
-
-void InputMapEditor::_action_selected() {
- TreeItem *ti = input_editor->get_selected();
- if (!ti || !ti->is_editable(0)) {
- return;
- }
-
- add_at = "input/" + ti->get_text(0);
- edit_idx = -1;
-}
-
-void InputMapEditor::_action_edited() {
- TreeItem *ti = input_editor->get_selected();
- if (!ti) {
- return;
- }
-
- if (input_editor->get_selected_column() == 0) {
- String new_name = ti->get_text(0);
- String old_name = add_at.substr(add_at.find("/") + 1, add_at.length());
-
- if (new_name == old_name) {
- return;
- }
-
- if (new_name == "" || !_validate_action_name(new_name)) {
- ti->set_text(0, old_name);
- add_at = "input/" + old_name;
-
- message->set_text(TTR("Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or '\"'"));
- message->popup_centered(Size2(300, 100) * EDSCALE);
- return;
- }
-
- String action_prop = "input/" + new_name;
-
- if (ProjectSettings::get_singleton()->has_setting(action_prop)) {
- ti->set_text(0, old_name);
- add_at = "input/" + old_name;
-
- message->set_text(vformat(TTR("An action with the name '%s' already exists."), new_name));
- message->popup_centered(Size2(300, 100) * EDSCALE);
- return;
- }
-
- int order = ProjectSettings::get_singleton()->get_order(add_at);
- Dictionary action = ProjectSettings::get_singleton()->get(add_at);
-
- setting = true;
- undo_redo->create_action(TTR("Rename Input Action Event"));
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", add_at);
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", action_prop, action);
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", action_prop, order);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", action_prop);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", add_at, action);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", add_at, order);
- undo_redo->add_do_method(this, "_update_actions");
- undo_redo->add_undo_method(this, "_update_actions");
- undo_redo->add_do_method(this, "emit_signal", inputmap_changed);
- undo_redo->add_undo_method(this, "emit_signal", inputmap_changed);
- undo_redo->commit_action();
- setting = false;
-
- add_at = action_prop;
- } else if (input_editor->get_selected_column() == 1) {
- String name = "input/" + ti->get_text(0);
- Dictionary old_action = ProjectSettings::get_singleton()->get(name);
- Dictionary new_action = old_action.duplicate();
- new_action["deadzone"] = ti->get_range(1);
-
- undo_redo->create_action(TTR("Change Action deadzone"));
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, new_action);
- undo_redo->add_do_method(this, "emit_signal", inputmap_changed);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_action);
- undo_redo->add_undo_method(this, "emit_signal", inputmap_changed);
- undo_redo->commit_action();
- }
-}
-
-void InputMapEditor::_device_input_add() {
- Ref<InputEvent> ie;
- String name = add_at;
- int idx = edit_idx;
- Dictionary old_val = ProjectSettings::get_singleton()->get(name);
- Dictionary action = old_val.duplicate();
- Array events = action["events"];
-
- switch (add_type) {
- case INPUT_MOUSE_BUTTON: {
- Ref<InputEventMouseButton> mb;
- mb.instance();
- mb->set_button_index(device_index->get_selected() + 1);
- mb->set_device(_get_current_device());
-
- for (int i = 0; i < events.size(); i++) {
- Ref<InputEventMouseButton> aie = events[i];
- if (aie.is_null()) {
- continue;
- }
- if (aie->get_device() == mb->get_device() && aie->get_button_index() == mb->get_button_index()) {
- return;
- }
- }
-
- ie = mb;
-
- } break;
- case INPUT_JOY_MOTION: {
- Ref<InputEventJoypadMotion> jm;
- jm.instance();
- jm->set_axis(device_index->get_selected() >> 1);
- jm->set_axis_value((device_index->get_selected() & 1) ? 1 : -1);
- jm->set_device(_get_current_device());
-
- for (int i = 0; i < events.size(); i++) {
- Ref<InputEventJoypadMotion> aie = events[i];
- if (aie.is_null()) {
- continue;
- }
-
- if (aie->get_device() == jm->get_device() && aie->get_axis() == jm->get_axis() && aie->get_axis_value() == jm->get_axis_value()) {
- return;
- }
- }
-
- ie = jm;
-
- } break;
- case INPUT_JOY_BUTTON: {
- Ref<InputEventJoypadButton> jb;
- jb.instance();
-
- jb->set_button_index(device_index->get_selected());
- jb->set_device(_get_current_device());
-
- for (int i = 0; i < events.size(); i++) {
- Ref<InputEventJoypadButton> aie = events[i];
- if (aie.is_null()) {
- continue;
- }
- if (aie->get_device() == jb->get_device() && aie->get_button_index() == jb->get_button_index()) {
- return;
- }
- }
- ie = jb;
-
- } break;
- default: {
- }
- }
-
- if (idx < 0 || idx >= events.size()) {
- events.push_back(ie);
- } else {
- events[idx] = ie;
- }
- action["events"] = events;
-
- undo_redo->create_action(TTR("Add Input Action Event"));
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val);
- undo_redo->add_do_method(this, "_update_actions");
- undo_redo->add_undo_method(this, "_update_actions");
- undo_redo->add_do_method(this, "emit_signal", inputmap_changed);
- undo_redo->add_undo_method(this, "emit_signal", inputmap_changed);
- undo_redo->commit_action();
-
- _show_last_added(ie, name);
-}
-
-void InputMapEditor::_set_current_device(int i_device) {
- device_id->select(i_device + 1);
-}
-
-int InputMapEditor::_get_current_device() {
- return device_id->get_selected() - 1;
-}
-
-String InputMapEditor::_get_device_string(int i_device) {
- if (i_device == InputMap::ALL_DEVICES) {
- return TTR("All Devices");
- }
- return TTR("Device") + " " + itos(i_device);
-}
-
-void InputMapEditor::_press_a_key_confirm() {
- if (last_wait_for_key.is_null()) {
- return;
- }
-
- Ref<InputEventKey> ie;
- ie.instance();
- if (press_a_key_physical) {
- ie->set_physical_keycode(last_wait_for_key->get_physical_keycode());
- ie->set_keycode(0);
- } else {
- ie->set_physical_keycode(0);
- ie->set_keycode(last_wait_for_key->get_keycode());
- }
- ie->set_shift(last_wait_for_key->get_shift());
- ie->set_alt(last_wait_for_key->get_alt());
- ie->set_control(last_wait_for_key->get_control());
- ie->set_metakey(last_wait_for_key->get_metakey());
-
- String name = add_at;
- int idx = edit_idx;
-
- Dictionary old_val = ProjectSettings::get_singleton()->get(name);
- Dictionary action = old_val.duplicate();
- Array events = action["events"];
-
- for (int i = 0; i < events.size(); i++) {
- Ref<InputEventKey> aie = events[i];
- if (aie.is_null()) {
- continue;
- }
- if (!press_a_key_physical) {
- if (aie->get_keycode_with_modifiers() == ie->get_keycode_with_modifiers()) {
- return;
- }
- } else {
- if (aie->get_physical_keycode_with_modifiers() == ie->get_physical_keycode_with_modifiers()) {
- return;
- }
- }
- }
-
- if (idx < 0 || idx >= events.size()) {
- events.push_back(ie);
- } else {
- events[idx] = ie;
- }
- action["events"] = events;
-
- undo_redo->create_action(TTR("Add Input Action Event"));
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val);
- undo_redo->add_do_method(this, "_update_actions");
- undo_redo->add_undo_method(this, "_update_actions");
- undo_redo->add_do_method(this, "emit_signal", inputmap_changed);
- undo_redo->add_undo_method(this, "emit_signal", inputmap_changed);
- undo_redo->commit_action();
-
- _show_last_added(ie, name);
-}
-
-void InputMapEditor::_show_last_added(const Ref<InputEvent> &p_event, const String &p_name) {
- TreeItem *r = input_editor->get_root();
-
- String name = p_name;
- name.erase(0, 6);
- if (!r) {
- return;
- }
- r = r->get_children();
- if (!r) {
- return;
- }
- bool found = false;
- while (r) {
- if (r->get_text(0) != name) {
- r = r->get_next();
- continue;
- }
- TreeItem *child = r->get_children();
- while (child) {
- Variant input = child->get_meta("__input");
- if (p_event == input) {
- r->set_collapsed(false);
- child->select(0);
- found = true;
- break;
- }
- child = child->get_next();
- }
- if (found) {
- break;
- }
- r = r->get_next();
- }
-
- if (found) {
- input_editor->ensure_cursor_is_visible();
- }
-}
-
-// Maps to 2*axis if value is neg, or + 1 if value is pos.
-static const char *_joy_axis_descriptions[JOY_AXIS_MAX * 2] = {
- TTRC("Left Stick Left, Joystick 0 Left"),
- TTRC("Left Stick Right, Joystick 0 Right"),
- TTRC("Left Stick Up, Joystick 0 Up"),
- TTRC("Left Stick Down, Joystick 0 Down"),
- TTRC("Right Stick Left, Joystick 1 Left"),
- TTRC("Right Stick Right, Joystick 1 Right"),
- TTRC("Right Stick Up, Joystick 1 Up"),
- TTRC("Right Stick Down, Joystick 1 Down"),
- TTRC("Joystick 2 Left"),
- TTRC("Left Trigger, Sony L2, Xbox LT, Joystick 2 Right"),
- TTRC("Joystick 2 Up"),
- TTRC("Right Trigger, Sony R2, Xbox RT, Joystick 2 Down"),
- TTRC("Joystick 3 Left"),
- TTRC("Joystick 3 Right"),
- TTRC("Joystick 3 Up"),
- TTRC("Joystick 3 Down"),
- TTRC("Joystick 4 Left"),
- TTRC("Joystick 4 Right"),
- TTRC("Joystick 4 Up"),
- TTRC("Joystick 4 Down"),
-};
-
-// Separate from `InputEvent::as_text()` since the descriptions need to be different for the input map editor. See #43660.
-String InputMapEditor::_get_joypad_motion_event_text(const Ref<InputEventJoypadMotion> &p_event) {
- ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEventJoypadMotion");
-
- String desc = TTR("Unknown Joypad Axis");
- if (p_event->get_axis() < JOY_AXIS_MAX) {
- desc = RTR(_joy_axis_descriptions[2 * p_event->get_axis() + (p_event->get_axis_value() < 0 ? 0 : 1)]);
- }
-
- return vformat("Joypad Axis %s %s (%s)", itos(p_event->get_axis()), p_event->get_axis_value() < 0 ? "-" : "+", desc);
-}
-
-void InputMapEditor::_wait_for_key(const Ref<InputEvent> &p_event) {
- Ref<InputEventKey> k = p_event;
-
- if (k.is_valid() && k->is_pressed() && k->get_keycode() != 0) {
- last_wait_for_key = p_event;
- const String str = (press_a_key_physical) ? keycode_get_string(k->get_physical_keycode_with_modifiers()) + TTR(" (Physical)") : keycode_get_string(k->get_keycode_with_modifiers());
-
- press_a_key_label->set_text(str);
- press_a_key->get_ok_button()->set_disabled(false);
- press_a_key->set_input_as_handled();
- }
-}
-
-void InputMapEditor::_edit_item(Ref<InputEvent> p_exiting_event) {
- InputType ie_type;
-
- if ((Ref<InputEventKey>(p_exiting_event)).is_valid()) {
- if ((Ref<InputEventKey>(p_exiting_event))->get_keycode() != 0) {
- ie_type = INPUT_KEY;
- } else {
- ie_type = INPUT_KEY_PHYSICAL;
- }
- } else if ((Ref<InputEventJoypadButton>(p_exiting_event)).is_valid()) {
- ie_type = INPUT_JOY_BUTTON;
- } else if ((Ref<InputEventMouseButton>(p_exiting_event)).is_valid()) {
- ie_type = INPUT_MOUSE_BUTTON;
- } else if ((Ref<InputEventJoypadMotion>(p_exiting_event)).is_valid()) {
- ie_type = INPUT_JOY_MOTION;
- } else {
- return;
- }
-
- _add_item(ie_type, p_exiting_event);
-}
-
-void InputMapEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) {
- add_type = InputType(p_item);
-
- switch (add_type) {
- case INPUT_KEY: {
- press_a_key_physical = false;
- press_a_key_label->set_text(TTR("Press a Key..."));
- press_a_key->get_ok_button()->set_disabled(true);
- last_wait_for_key = Ref<InputEvent>();
- press_a_key->popup_centered(Size2(250, 80) * EDSCALE);
- //press_a_key->grab_focus();
-
- } break;
- case INPUT_KEY_PHYSICAL: {
- press_a_key_physical = true;
- press_a_key_label->set_text(TTR("Press a Key..."));
-
- last_wait_for_key = Ref<InputEvent>();
- press_a_key->popup_centered(Size2(250, 80) * EDSCALE);
- press_a_key->grab_focus();
-
- } break;
- case INPUT_MOUSE_BUTTON: {
- device_index_label->set_text(TTR("Mouse Button Index:"));
- device_index->clear();
- device_index->add_item(TTR("Left Button"));
- device_index->add_item(TTR("Right Button"));
- device_index->add_item(TTR("Middle Button"));
- device_index->add_item(TTR("Wheel Up Button"));
- device_index->add_item(TTR("Wheel Down Button"));
- device_index->add_item(TTR("Wheel Left Button"));
- device_index->add_item(TTR("Wheel Right Button"));
- device_index->add_item(TTR("X Button 1"));
- device_index->add_item(TTR("X Button 2"));
- device_input->popup_centered(Size2(350, 95) * EDSCALE);
-
- Ref<InputEventMouseButton> mb = p_exiting_event;
- if (mb.is_valid()) {
- device_index->select(mb->get_button_index() - 1);
- _set_current_device(mb->get_device());
- device_input->get_ok_button()->set_text(TTR("Change"));
- } else {
- _set_current_device(0);
- device_input->get_ok_button()->set_text(TTR("Add"));
- }
-
- } break;
- case INPUT_JOY_MOTION: {
- device_index_label->set_text(TTR("Joypad Axis Index:"));
- device_index->clear();
- for (int i = 0; i < JOY_AXIS_MAX * 2; i++) {
- Ref<InputEventJoypadMotion> jm;
- jm.instance();
- jm->set_axis(i / 2);
- jm->set_axis_value((i & 1) ? 1 : -1);
- device_index->add_item(_get_joypad_motion_event_text(jm));
- }
- device_input->popup_centered(Size2(350, 95) * EDSCALE);
-
- Ref<InputEventJoypadMotion> jm = p_exiting_event;
- if (jm.is_valid()) {
- device_index->select(jm->get_axis() * 2 + (jm->get_axis_value() > 0 ? 1 : 0));
- _set_current_device(jm->get_device());
- device_input->get_ok_button()->set_text(TTR("Change"));
- } else {
- _set_current_device(0);
- device_input->get_ok_button()->set_text(TTR("Add"));
- }
-
- } break;
- case INPUT_JOY_BUTTON: {
- device_index_label->set_text(TTR("Joypad Button Index:"));
- device_index->clear();
- for (int i = 0; i < JOY_BUTTON_MAX; i++) {
- Ref<InputEventJoypadButton> jb;
- jb.instance();
- jb->set_button_index(i);
- device_index->add_item(jb->as_text());
- }
- device_input->popup_centered(Size2(350, 95) * EDSCALE);
-
- Ref<InputEventJoypadButton> jb = p_exiting_event;
- if (jb.is_valid()) {
- device_index->select(jb->get_button_index());
- _set_current_device(jb->get_device());
- device_input->get_ok_button()->set_text(TTR("Change"));
- } else {
- _set_current_device(0);
- device_input->get_ok_button()->set_text(TTR("Add"));
- }
-
- } break;
- default: {
- }
- }
-}
-
-void InputMapEditor::_action_activated() {
- TreeItem *ti = input_editor->get_selected();
-
- if (!ti || ti->get_parent() == input_editor->get_root()) {
- return;
- }
-
- String name = "input/" + ti->get_parent()->get_text(0);
- Dictionary action = ProjectSettings::get_singleton()->get(name);
- Array events = action["events"];
- int idx = ti->get_metadata(0);
-
- ERR_FAIL_INDEX(idx, events.size());
- Ref<InputEvent> event = events[idx];
- if (event.is_null()) {
- return;
- }
-
- add_at = name;
- edit_idx = idx;
- _edit_item(event);
-}
-
-void InputMapEditor::_action_button_pressed(Object *p_obj, int p_column, int p_id) {
- TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
-
- ERR_FAIL_COND(!ti);
-
- if (p_id == 1) {
- // Add action event
- Point2 ofs = input_editor->get_global_position();
- Rect2 ir = input_editor->get_item_rect(ti);
- ir.position.y -= input_editor->get_scroll().y;
- ofs += ir.position + ir.size;
- ofs.x -= 100;
- popup_add->set_position(ofs);
- popup_add->popup();
- add_at = "input/" + ti->get_text(0);
- edit_idx = -1;
-
- } else if (p_id == 2) {
- // Remove
-
- if (ti->get_parent() == input_editor->get_root()) {
- // Remove action
- String name = "input/" + ti->get_text(0);
- Dictionary old_val = ProjectSettings::get_singleton()->get(name);
- int order = ProjectSettings::get_singleton()->get_order(name);
-
- undo_redo->create_action(TTR("Erase Input Action"));
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", name);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", name, order);
- undo_redo->add_do_method(this, "_update_actions");
- undo_redo->add_undo_method(this, "_update_actions");
- undo_redo->add_do_method(this, "emit_signal", inputmap_changed);
- undo_redo->add_undo_method(this, "emit_signal", inputmap_changed);
- undo_redo->commit_action();
-
- } else {
- // Remove action event
- String name = "input/" + ti->get_parent()->get_text(0);
- Dictionary old_val = ProjectSettings::get_singleton()->get(name);
- Dictionary action = old_val.duplicate();
- int idx = ti->get_metadata(0);
-
- Array events = action["events"];
- ERR_FAIL_INDEX(idx, events.size());
- events.remove(idx);
- action["events"] = events;
-
- undo_redo->create_action(TTR("Erase Input Action Event"));
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, old_val);
- undo_redo->add_do_method(this, "_update_actions");
- undo_redo->add_undo_method(this, "_update_actions");
- undo_redo->add_do_method(this, "emit_signal", inputmap_changed);
- undo_redo->add_undo_method(this, "emit_signal", inputmap_changed);
- undo_redo->commit_action();
- }
- } else if (p_id == 3) {
- // Edit
-
- if (ti->get_parent() == input_editor->get_root()) {
- // Edit action name
- ti->set_as_cursor(0);
- input_editor->edit_selected();
-
- } else {
- // Edit action event
- String name = "input/" + ti->get_parent()->get_text(0);
- int idx = ti->get_metadata(0);
- Dictionary action = ProjectSettings::get_singleton()->get(name);
-
- Array events = action["events"];
- ERR_FAIL_INDEX(idx, events.size());
-
- Ref<InputEvent> event = events[idx];
-
- if (event.is_null()) {
- return;
- }
-
- ti->set_as_cursor(0);
- add_at = name;
- edit_idx = idx;
- _edit_item(event);
- }
- }
-}
-
-void InputMapEditor::_update_actions() {
- if (setting) {
- return;
- }
-
- Map<String, bool> collapsed;
-
- if (input_editor->get_root() && input_editor->get_root()->get_children()) {
- for (TreeItem *item = input_editor->get_root()->get_children(); item; item = item->get_next()) {
- collapsed[item->get_text(0)] = item->is_collapsed();
- }
- }
-
- input_editor->clear();
- TreeItem *root = input_editor->create_item();
- input_editor->set_hide_root(true);
-
- List<PropertyInfo> props;
- ProjectSettings::get_singleton()->get_property_list(&props);
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- const String property_name = E->get().name;
-
- if (!property_name.begins_with("input/")) {
- continue;
- }
-
- const String name = property_name.get_slice("/", 1);
-
- TreeItem *item = input_editor->create_item(root);
- item->set_text(0, name);
- item->set_custom_bg_color(0, input_editor->get_theme_color("prop_subsection", "Editor"));
- if (collapsed.has(name)) {
- item->set_collapsed(collapsed[name]);
- }
-
- item->set_editable(1, true);
- item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
- item->set_range_config(1, 0.0, 1.0, 0.01);
-
- item->set_custom_bg_color(1, input_editor->get_theme_color("prop_subsection", "Editor"));
-
- const bool is_builtin_input = ProjectSettings::get_singleton()->get_input_presets().find(property_name) != nullptr;
- const String tooltip_remove = is_builtin_input ? TTR("Built-in actions can't be removed as they're used for UI navigation.") : TTR("Remove");
- item->add_button(2, input_editor->get_theme_icon("Add", "EditorIcons"), 1, false, TTR("Add Event"));
- item->add_button(2, input_editor->get_theme_icon("Remove", "EditorIcons"), 2, false, tooltip_remove);
-
- if (is_builtin_input) {
- item->set_button_disabled(2, 1, true);
- } else {
- item->set_editable(0, true);
- }
-
- Dictionary action = ProjectSettings::get_singleton()->get(property_name);
- Array events = action["events"];
- item->set_range(1, action["deadzone"]);
-
- for (int i = 0; i < events.size(); i++) {
- Ref<InputEvent> event = events[i];
- if (event.is_null()) {
- continue;
- }
-
- TreeItem *action2 = input_editor->create_item(item);
-
- Ref<InputEventKey> k = event;
- if (k.is_valid()) {
- if (k->get_keycode() != 0) {
- action2->set_text(0, keycode_get_string(k->get_keycode_with_modifiers()));
- action2->set_icon(0, input_editor->get_theme_icon("Keyboard", "EditorIcons"));
- } else {
- action2->set_text(0, keycode_get_string(k->get_physical_keycode_with_modifiers()) + TTR(" (Physical)"));
- action2->set_icon(0, input_editor->get_theme_icon("KeyboardPhysical", "EditorIcons"));
- }
- }
-
- Ref<InputEventJoypadButton> jb = event;
- if (jb.is_valid()) {
- action2->set_text(0, jb->as_text());
- action2->set_icon(0, input_editor->get_theme_icon("JoyButton", "EditorIcons"));
- }
-
- Ref<InputEventMouseButton> mb = event;
- if (mb.is_valid()) {
- String str = _get_device_string(mb->get_device()) + ", ";
- switch (mb->get_button_index()) {
- case BUTTON_LEFT:
- str += TTR("Left Button");
- break;
- case BUTTON_RIGHT:
- str += TTR("Right Button");
- break;
- case BUTTON_MIDDLE:
- str += TTR("Middle Button");
- break;
- case BUTTON_WHEEL_UP:
- str += TTR("Wheel Up");
- break;
- case BUTTON_WHEEL_DOWN:
- str += TTR("Wheel Down");
- break;
- default:
- str += vformat(TTR("%d Button"), mb->get_button_index());
- }
-
- action2->set_text(0, str);
- action2->set_icon(0, input_editor->get_theme_icon("Mouse", "EditorIcons"));
- }
-
- Ref<InputEventJoypadMotion> jm = event;
- if (jm.is_valid()) {
- device_index->add_item(_get_joypad_motion_event_text(jm));
- action2->set_text(0, jm->as_text());
- action2->set_icon(0, input_editor->get_theme_icon("JoyAxis", "EditorIcons"));
- }
- action2->set_metadata(0, i);
- action2->set_meta("__input", event);
-
- action2->add_button(2, input_editor->get_theme_icon("Edit", "EditorIcons"), 3, false, TTR("Edit"));
- action2->add_button(2, input_editor->get_theme_icon("Remove", "EditorIcons"), 2, false, TTR("Remove"));
- // Fade out the individual event buttons slightly to make the
- // Add/Remove buttons stand out more.
- action2->set_button_color(2, 0, Color(1, 1, 1, 0.75));
- action2->set_button_color(2, 1, Color(1, 1, 1, 0.75));
- }
- }
-
- _action_check(action_name->get_text());
-}
-
-void InputMapEditor::_action_check(String p_action) {
- if (p_action == "") {
- action_add->set_disabled(true);
- } else {
- if (!_validate_action_name(p_action)) {
- action_add_error->set_text(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'."));
- action_add_error->show();
- action_add->set_disabled(true);
- return;
- }
- if (ProjectSettings::get_singleton()->has_setting("input/" + p_action)) {
- action_add_error->set_text(vformat(TTR("An action with the name '%s' already exists."), p_action));
- action_add_error->show();
- action_add->set_disabled(true);
- return;
- }
-
- action_add->set_disabled(false);
- }
-
- action_add_error->hide();
-}
-
-void InputMapEditor::_action_adds(String) {
- if (!action_add->is_disabled()) {
- _action_add();
- }
-}
-
-void InputMapEditor::_action_add() {
- Dictionary action;
- action["events"] = Array();
- action["deadzone"] = 0.5f;
- String name = "input/" + action_name->get_text();
- undo_redo->create_action(TTR("Add Input Action"));
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name);
- undo_redo->add_do_method(this, "_update_actions");
- undo_redo->add_undo_method(this, "_update_actions");
- undo_redo->add_do_method(this, "emit_signal", inputmap_changed);
- undo_redo->add_undo_method(this, "emit_signal", inputmap_changed);
- undo_redo->commit_action();
-
- TreeItem *r = input_editor->get_root();
-
- if (!r) {
- return;
- }
- r = r->get_children();
- if (!r) {
- return;
- }
- while (r->get_next()) {
- r = r->get_next();
- }
-
- r->select(0);
- input_editor->ensure_cursor_is_visible();
- action_add_error->hide();
- action_name->clear();
-}
-
-Variant InputMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
- TreeItem *selected = input_editor->get_selected();
- if (!selected || selected->get_parent() != input_editor->get_root()) {
- return Variant();
- }
-
- String name = selected->get_text(0);
- VBoxContainer *vb = memnew(VBoxContainer);
- HBoxContainer *hb = memnew(HBoxContainer);
- Label *label = memnew(Label(name));
- hb->set_modulate(Color(1, 1, 1, 1.0f));
- hb->add_child(label);
- vb->add_child(hb);
- input_editor->set_drag_preview(vb);
-
- Dictionary drag_data;
- drag_data["type"] = "nodes";
-
- input_editor->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
-
- return drag_data;
-}
-
-bool InputMapEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
- Dictionary d = p_data;
- if (!d.has("type") || d["type"] != "nodes") {
- return false;
- }
-
- TreeItem *selected = input_editor->get_selected();
- TreeItem *item = input_editor->get_item_at_position(p_point);
- if (!selected || !item || item == selected || item->get_parent() == selected) {
- return false;
- }
-
- return true;
-}
-
-void InputMapEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
- if (!can_drop_data_fw(p_point, p_data, p_from)) {
- return;
- }
-
- TreeItem *selected = input_editor->get_selected();
- TreeItem *item = input_editor->get_item_at_position(p_point);
- if (!item) {
- return;
- }
- TreeItem *target = item->get_parent() == input_editor->get_root() ? item : item->get_parent();
-
- String selected_name = "input/" + selected->get_text(0);
- int old_order = ProjectSettings::get_singleton()->get_order(selected_name);
- String target_name = "input/" + target->get_text(0);
- int target_order = ProjectSettings::get_singleton()->get_order(target_name);
-
- int order = old_order;
- bool is_below = target_order > old_order;
- TreeItem *iterator = is_below ? selected->get_next() : selected->get_prev();
-
- undo_redo->create_action(TTR("Moved Input Action Event"));
- while (iterator != target) {
- String iterator_name = "input/" + iterator->get_text(0);
- int iterator_order = ProjectSettings::get_singleton()->get_order(iterator_name);
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", iterator_name, order);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", iterator_name, iterator_order);
- order = iterator_order;
- iterator = is_below ? iterator->get_next() : iterator->get_prev();
- }
-
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", target_name, order);
- undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", selected_name, target_order);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", target_name, target_order);
- undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", selected_name, old_order);
-
- undo_redo->add_do_method(this, "_update_actions");
- undo_redo->add_undo_method(this, "_update_actions");
- undo_redo->add_do_method(this, "emit_signal", inputmap_changed);
- undo_redo->add_undo_method(this, "emit_signal", inputmap_changed);
- undo_redo->commit_action();
-}
-
-void InputMapEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_update_actions"), &InputMapEditor::_update_actions);
-
- ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &InputMapEditor::get_drag_data_fw);
- ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &InputMapEditor::can_drop_data_fw);
- ClassDB::bind_method(D_METHOD("drop_data_fw"), &InputMapEditor::drop_data_fw);
-
- ADD_SIGNAL(MethodInfo("inputmap_changed"));
-}
-
-InputMapEditor::InputMapEditor() {
- undo_redo = EditorNode::get_undo_redo();
- press_a_key_physical = false;
- inputmap_changed = "inputmap_changed";
-
- VBoxContainer *vbc = memnew(VBoxContainer);
- vbc->set_anchor_and_offset(SIDE_TOP, Control::ANCHOR_BEGIN, 0);
- vbc->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_END, 0);
- vbc->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 0);
- vbc->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, 0);
- add_child(vbc);
-
- HBoxContainer *hbc = memnew(HBoxContainer);
- vbc->add_child(hbc);
-
- Label *l = memnew(Label);
- l->set_text(TTR("Action:"));
- hbc->add_child(l);
-
- action_name = memnew(LineEdit);
- action_name->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- action_name->connect("text_entered", callable_mp(this, &InputMapEditor::_action_adds));
- action_name->connect("text_changed", callable_mp(this, &InputMapEditor::_action_check));
- hbc->add_child(action_name);
-
- action_add_error = memnew(Label);
- action_add_error->hide();
- hbc->add_child(action_add_error);
-
- Button *add = memnew(Button);
- add->set_text(TTR("Add"));
- add->set_disabled(true);
- add->connect("pressed", callable_mp(this, &InputMapEditor::_action_add));
- hbc->add_child(add);
- action_add = add;
-
- input_editor = memnew(Tree);
- input_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- input_editor->set_columns(3);
- input_editor->set_column_titles_visible(true);
- input_editor->set_column_title(0, TTR("Action"));
- input_editor->set_column_title(1, TTR("Deadzone"));
- input_editor->set_column_expand(1, false);
- input_editor->set_column_min_width(1, 80 * EDSCALE);
- input_editor->set_column_expand(2, false);
- input_editor->set_column_min_width(2, 50 * EDSCALE);
- input_editor->connect("item_edited", callable_mp(this, &InputMapEditor::_action_edited));
- input_editor->connect("item_activated", callable_mp(this, &InputMapEditor::_action_activated));
- input_editor->connect("cell_selected", callable_mp(this, &InputMapEditor::_action_selected));
- input_editor->connect("button_pressed", callable_mp(this, &InputMapEditor::_action_button_pressed));
-#ifndef _MSC_VER
-#warning need to make drag data forwarding to non controls happen
-#endif
- //input_editor->set_drag_forwarding(this);
- vbc->add_child(input_editor);
-
- // Popups
-
- popup_add = memnew(PopupMenu);
- popup_add->connect("id_pressed", callable_mp(this, &InputMapEditor::_add_item), make_binds(Ref<InputEvent>()));
- add_child(popup_add);
-
- press_a_key = memnew(ConfirmationDialog);
- press_a_key->get_ok_button()->set_disabled(true);
- //press_a_key->set_focus_mode(Control::FOCUS_ALL);
- press_a_key->connect("window_input", callable_mp(this, &InputMapEditor::_wait_for_key));
- press_a_key->connect("confirmed", callable_mp(this, &InputMapEditor::_press_a_key_confirm));
- add_child(press_a_key);
-
- l = memnew(Label);
- l->set_text(TTR("Press a Key..."));
- l->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
- l->set_align(Label::ALIGN_CENTER);
- l->set_offset(SIDE_TOP, 20);
- l->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_BEGIN, 30);
- press_a_key->add_child(l);
- press_a_key_label = l;
-
- device_input = memnew(ConfirmationDialog);
- device_input->get_ok_button()->set_text(TTR("Add"));
- device_input->connect("confirmed", callable_mp(this, &InputMapEditor::_device_input_add));
- add_child(device_input);
-
- hbc = memnew(HBoxContainer);
- device_input->add_child(hbc);
-
- VBoxContainer *vbc_left = memnew(VBoxContainer);
- hbc->add_child(vbc_left);
-
- l = memnew(Label);
- l->set_text(TTR("Device:"));
- vbc_left->add_child(l);
-
- device_id = memnew(OptionButton);
- for (int i = -1; i < 8; i++) {
- device_id->add_item(_get_device_string(i));
- }
- _set_current_device(0);
- vbc_left->add_child(device_id);
-
- VBoxContainer *vbc_right = memnew(VBoxContainer);
- vbc_right->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- hbc->add_child(vbc_right);
-
- l = memnew(Label);
- l->set_text(TTR("Index:"));
- vbc_right->add_child(l);
-
- device_index_label = l;
- device_index = memnew(OptionButton);
- device_index->set_clip_text(true);
- vbc_right->add_child(device_index);
-
- message = memnew(AcceptDialog);
- add_child(message);
-}
diff --git a/editor/input_map_editor.h b/editor/input_map_editor.h
deleted file mode 100644
index b59eb97e1d..0000000000
--- a/editor/input_map_editor.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*************************************************************************/
-/* input_map_editor.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef INPUT_MAP_EDITOR_H
-#define INPUT_MAP_EDITOR_H
-
-#include "core/object/undo_redo.h"
-#include "editor/editor_data.h"
-
-class InputMapEditor : public Control {
- GDCLASS(InputMapEditor, Control);
-
- enum InputType {
- INPUT_KEY,
- INPUT_KEY_PHYSICAL,
- INPUT_JOY_BUTTON,
- INPUT_JOY_MOTION,
- INPUT_MOUSE_BUTTON
- };
-
- Tree *input_editor;
- LineEdit *action_name;
- Button *action_add;
- Label *action_add_error;
-
- InputType add_type;
- String add_at;
- int edit_idx;
-
- PopupMenu *popup_add;
- ConfirmationDialog *press_a_key;
- bool press_a_key_physical;
- Label *press_a_key_label;
- ConfirmationDialog *device_input;
- OptionButton *device_id;
- OptionButton *device_index;
- Label *device_index_label;
- MenuButton *popup_copy_to_feature;
-
- Ref<InputEventKey> last_wait_for_key;
-
- AcceptDialog *message;
- UndoRedo *undo_redo;
- String inputmap_changed;
- bool setting = false;
-
- void _update_actions();
- void _add_item(int p_item, Ref<InputEvent> p_exiting_event = Ref<InputEvent>());
- void _edit_item(Ref<InputEvent> p_exiting_event);
-
- void _action_check(String p_action);
- void _action_adds(String);
- void _action_add();
- void _device_input_add();
-
- void _action_selected();
- void _action_edited();
- void _action_activated();
- void _action_button_pressed(Object *p_obj, int p_column, int p_id);
- void _wait_for_key(const Ref<InputEvent> &p_event);
- void _press_a_key_confirm();
- void _show_last_added(const Ref<InputEvent> &p_event, const String &p_name);
-
- String _get_joypad_motion_event_text(const Ref<InputEventJoypadMotion> &p_event);
-
- Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
- bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
- void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
-
-protected:
- int _get_current_device();
- void _set_current_device(int i_device);
- String _get_device_string(int i_device);
-
- void _notification(int p_what);
- static void _bind_methods();
-
-public:
- InputMapEditor();
-};
-
-#endif // INPUT_MAP_EDITOR_H
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index e0ba50fe4f..fbcd76a95f 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -270,14 +270,13 @@ void InspectorDock::_select_history(int p_idx) {
}
void InspectorDock::_resource_created() {
- Object *c = new_resource_dialog->instance_selected();
+ Variant c = new_resource_dialog->instance_selected();
ERR_FAIL_COND(!c);
Resource *r = Object::cast_to<Resource>(c);
ERR_FAIL_COND(!r);
- REF res(r);
- editor->push_item(c);
+ editor->push_item(r);
}
void InspectorDock::_resource_selected(const RES &p_res, const String &p_property) {
@@ -452,7 +451,7 @@ void InspectorDock::update(Object *p_object) {
List<MethodInfo> methods;
p_object->get_method_list(&methods);
- if (!methods.empty()) {
+ if (!methods.is_empty()) {
bool found = false;
List<MethodInfo>::Element *I = methods.front();
int i = 0;
diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h
index b2dabf19c5..6a3f8c679c 100644
--- a/editor/inspector_dock.h
+++ b/editor/inspector_dock.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp
index 2a21885c4c..0e68af06f0 100644
--- a/editor/localization_editor.cpp
+++ b/editor/localization_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,20 +78,23 @@ void LocalizationEditor::_notification(int p_what) {
}
void LocalizationEditor::add_translation(const String &p_translation) {
- _translation_add(p_translation);
+ PackedStringArray translations;
+ translations.push_back(p_translation);
+ _translation_add(translations);
}
-void LocalizationEditor::_translation_add(const String &p_path) {
- PackedStringArray translations = ProjectSettings::get_singleton()->get("locale/translations");
- if (translations.has(p_path)) {
- return;
+void LocalizationEditor::_translation_add(const PackedStringArray &p_paths) {
+ PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations");
+ for (int i = 0; i < p_paths.size(); i++) {
+ if (!translations.has(p_paths[i])) {
+ // Don't add duplicate translation paths.
+ translations.push_back(p_paths[i]);
+ }
}
- translations.push_back(p_path);
-
- undo_redo->create_action(TTR("Add Translation"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations", translations);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations", ProjectSettings::get_singleton()->get("locale/translations"));
+ undo_redo->create_action(vformat(TTR("Add %d Translations"), p_paths.size()));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", translations);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", ProjectSettings::get_singleton()->get("internationalization/locale/translations"));
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -109,15 +112,15 @@ void LocalizationEditor::_translation_delete(Object *p_item, int p_column, int p
int idx = ti->get_metadata(0);
- PackedStringArray translations = ProjectSettings::get_singleton()->get("locale/translations");
+ PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations");
ERR_FAIL_INDEX(idx, translations.size());
translations.remove(idx);
undo_redo->create_action(TTR("Remove Translation"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations", translations);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations", ProjectSettings::get_singleton()->get("locale/translations"));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", translations);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", ProjectSettings::get_singleton()->get("internationalization/locale/translations"));
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -129,24 +132,25 @@ void LocalizationEditor::_translation_res_file_open() {
translation_res_file_open_dialog->popup_file_dialog();
}
-void LocalizationEditor::_translation_res_add(const String &p_path) {
+void LocalizationEditor::_translation_res_add(const PackedStringArray &p_paths) {
Variant prev;
Dictionary remaps;
- if (ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
- remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
+ if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) {
+ remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps");
prev = remaps;
}
- if (remaps.has(p_path)) {
- return; //pointless already has it
+ for (int i = 0; i < p_paths.size(); i++) {
+ if (!remaps.has(p_paths[i])) {
+ // Don't overwrite with an empty remap array if an array already exists for the given path.
+ remaps[p_paths[i]] = PackedStringArray();
+ }
}
- remaps[p_path] = PackedStringArray();
-
- undo_redo->create_action(TTR("Add Remapped Path"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", prev);
+ undo_redo->create_action(vformat(TTR("Translation Resource Remap: Add %d Path(s)"), p_paths.size()));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", prev);
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -158,10 +162,10 @@ void LocalizationEditor::_translation_res_option_file_open() {
translation_res_option_file_open_dialog->popup_file_dialog();
}
-void LocalizationEditor::_translation_res_option_add(const String &p_path) {
- ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps"));
+void LocalizationEditor::_translation_res_option_add(const PackedStringArray &p_paths) {
+ ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps"));
- Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
+ Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps");
TreeItem *k = translation_remap->get_selected();
ERR_FAIL_COND(!k);
@@ -170,12 +174,14 @@ void LocalizationEditor::_translation_res_option_add(const String &p_path) {
ERR_FAIL_COND(!remaps.has(key));
PackedStringArray r = remaps[key];
- r.push_back(p_path + ":" + "en");
+ for (int i = 0; i < p_paths.size(); i++) {
+ r.push_back(p_paths[i] + ":" + "en");
+ }
remaps[key] = r;
- undo_redo->create_action(TTR("Resource Remap Add Remap"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps"));
+ undo_redo->create_action(vformat(TTR("Translation Resource Remap: Add %d Remap(s)"), p_paths.size()));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"));
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -196,11 +202,11 @@ void LocalizationEditor::_translation_res_option_changed() {
return;
}
- if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
+ if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) {
return;
}
- Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
+ Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps");
TreeItem *k = translation_remap->get_selected();
ERR_FAIL_COND(!k);
@@ -228,8 +234,8 @@ void LocalizationEditor::_translation_res_option_changed() {
updating_translations = true;
undo_redo->create_action(TTR("Change Resource Remap Language"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps"));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"));
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -243,11 +249,11 @@ void LocalizationEditor::_translation_res_delete(Object *p_item, int p_column, i
return;
}
- if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
+ if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) {
return;
}
- Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
+ Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps");
TreeItem *k = Object::cast_to<TreeItem>(p_item);
@@ -257,8 +263,8 @@ void LocalizationEditor::_translation_res_delete(Object *p_item, int p_column, i
remaps.erase(key);
undo_redo->create_action(TTR("Remove Resource Remap"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps"));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"));
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -271,11 +277,11 @@ void LocalizationEditor::_translation_res_option_delete(Object *p_item, int p_co
return;
}
- if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
+ if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) {
return;
}
- Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
+ Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps");
TreeItem *k = translation_remap->get_selected();
ERR_FAIL_COND(!k);
@@ -292,8 +298,8 @@ void LocalizationEditor::_translation_res_option_delete(Object *p_item, int p_co
remaps[key] = r;
undo_redo->create_action(TTR("Remove Resource Remap Option"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translation_remaps", remaps);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translation_remaps", ProjectSettings::get_singleton()->get("locale/translation_remaps"));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps"));
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -310,8 +316,8 @@ void LocalizationEditor::_translation_filter_option_changed() {
Variant prev;
Array f_locales_all;
- if (ProjectSettings::get_singleton()->has_setting("locale/locale_filter")) {
- f_locales_all = ProjectSettings::get_singleton()->get("locale/locale_filter");
+ if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter")) {
+ f_locales_all = ProjectSettings::get_singleton()->get("internationalization/locale/locale_filter");
prev = f_locales_all;
if (f_locales_all.size() != 2) {
@@ -340,8 +346,8 @@ void LocalizationEditor::_translation_filter_option_changed() {
f_locales.sort();
undo_redo->create_action(TTR("Changed Locale Filter"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/locale_filter", f_locales_all);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/locale_filter", prev);
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter", f_locales_all);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter", prev);
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -355,8 +361,8 @@ void LocalizationEditor::_translation_filter_mode_changed(int p_mode) {
Variant prev;
Array f_locales_all;
- if (ProjectSettings::get_singleton()->has_setting("locale/locale_filter")) {
- f_locales_all = ProjectSettings::get_singleton()->get("locale/locale_filter");
+ if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter")) {
+ f_locales_all = ProjectSettings::get_singleton()->get("internationalization/locale/locale_filter");
prev = f_locales_all;
if (f_locales_all.size() != 2) {
@@ -372,8 +378,8 @@ void LocalizationEditor::_translation_filter_mode_changed(int p_mode) {
}
undo_redo->create_action(TTR("Changed Locale Filter Mode"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/locale_filter", f_locales_all);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/locale_filter", prev);
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter", f_locales_all);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter", prev);
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -381,19 +387,22 @@ void LocalizationEditor::_translation_filter_mode_changed(int p_mode) {
undo_redo->commit_action();
}
-void LocalizationEditor::_pot_add(const String &p_path) {
- PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("locale/translations_pot_files");
+void LocalizationEditor::_pot_add(const PackedStringArray &p_paths) {
+ PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files");
- for (int i = 0; i < pot_translations.size(); i++) {
- if (pot_translations[i] == p_path) {
- return; //exists
+ for (int i = 0; i < p_paths.size(); i++) {
+ for (int j = 0; j < pot_translations.size(); j++) {
+ if (pot_translations[j] == p_paths[i]) {
+ continue; //exists
+ }
}
+
+ pot_translations.push_back(p_paths[i]);
}
- pot_translations.push_back(p_path);
- undo_redo->create_action(TTR("Add files for POT generation"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations_pot_files", pot_translations);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations_pot_files", ProjectSettings::get_singleton()->get("locale/translations_pot_files"));
+ undo_redo->create_action(vformat(TTR("Add %d file(s) for POT generation"), p_paths.size()));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", pot_translations);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"));
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -407,15 +416,15 @@ void LocalizationEditor::_pot_delete(Object *p_item, int p_column, int p_button)
int idx = ti->get_metadata(0);
- PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("locale/translations_pot_files");
+ PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files");
ERR_FAIL_INDEX(idx, pot_translations.size());
pot_translations.remove(idx);
undo_redo->create_action(TTR("Remove file from POT generation"));
- undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/translations_pot_files", pot_translations);
- undo_redo->add_undo_property(ProjectSettings::get_singleton(), "locale/translations_pot_files", ProjectSettings::get_singleton()->get("locale/translations_pot_files"));
+ undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", pot_translations);
+ undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files"));
undo_redo->add_do_method(this, "update_translations");
undo_redo->add_undo_method(this, "update_translations");
undo_redo->add_do_method(this, "emit_signal", localization_changed);
@@ -454,8 +463,8 @@ void LocalizationEditor::update_translations() {
translation_list->clear();
TreeItem *root = translation_list->create_item(nullptr);
translation_list->set_hide_root(true);
- if (ProjectSettings::get_singleton()->has_setting("locale/translations")) {
- PackedStringArray translations = ProjectSettings::get_singleton()->get("locale/translations");
+ if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translations")) {
+ PackedStringArray translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations");
for (int i = 0; i < translations.size(); i++) {
TreeItem *t = translation_list->create_item(root);
t->set_editable(0, false);
@@ -473,8 +482,8 @@ void LocalizationEditor::update_translations() {
Array l_filter_all;
bool is_arr_empty = true;
- if (ProjectSettings::get_singleton()->has_setting("locale/locale_filter")) {
- l_filter_all = ProjectSettings::get_singleton()->get("locale/locale_filter");
+ if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/locale_filter")) {
+ l_filter_all = ProjectSettings::get_singleton()->get("internationalization/locale/locale_filter");
if (l_filter_all.size() == 2) {
translation_locale_filter_mode->select(l_filter_all[0]);
@@ -564,8 +573,8 @@ void LocalizationEditor::update_translations() {
}
}
- if (ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
- Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
+ if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translation_remaps")) {
+ Dictionary remaps = ProjectSettings::get_singleton()->get("internationalization/locale/translation_remaps");
List<Variant> rk;
remaps.get_key_list(&rk);
Vector<String> keys;
@@ -622,8 +631,8 @@ void LocalizationEditor::update_translations() {
translation_pot_list->clear();
root = translation_pot_list->create_item(nullptr);
translation_pot_list->set_hide_root(true);
- if (ProjectSettings::get_singleton()->has_setting("locale/translations_pot_files")) {
- PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("locale/translations_pot_files");
+ if (ProjectSettings::get_singleton()->has_setting("internationalization/locale/translations_pot_files")) {
+ PackedStringArray pot_translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files");
for (int i = 0; i < pot_translations.size(); i++) {
TreeItem *t = translation_pot_list->create_item(root);
t->set_editable(0, false);
@@ -685,8 +694,8 @@ LocalizationEditor::LocalizationEditor() {
translations->add_child(tvb);
HBoxContainer *thb = memnew(HBoxContainer);
- thb->add_spacer();
thb->add_child(memnew(Label(TTR("Translations:"))));
+ thb->add_spacer();
tvb->add_child(thb);
Button *addtr = memnew(Button(TTR("Add...")));
@@ -702,8 +711,8 @@ LocalizationEditor::LocalizationEditor() {
tmc->add_child(translation_list);
translation_file_open = memnew(EditorFileDialog);
- translation_file_open->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
- translation_file_open->connect("file_selected", callable_mp(this, &LocalizationEditor::_translation_add));
+ translation_file_open->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
+ translation_file_open->connect("files_selected", callable_mp(this, &LocalizationEditor::_translation_add));
add_child(translation_file_open);
}
@@ -732,8 +741,8 @@ LocalizationEditor::LocalizationEditor() {
tmc->add_child(translation_remap);
translation_res_file_open_dialog = memnew(EditorFileDialog);
- translation_res_file_open_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
- translation_res_file_open_dialog->connect("file_selected", callable_mp(this, &LocalizationEditor::_translation_res_add));
+ translation_res_file_open_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
+ translation_res_file_open_dialog->connect("files_selected", callable_mp(this, &LocalizationEditor::_translation_res_add));
add_child(translation_res_file_open_dialog);
thb = memnew(HBoxContainer);
@@ -764,8 +773,8 @@ LocalizationEditor::LocalizationEditor() {
tmc->add_child(translation_remap_options);
translation_res_option_file_open_dialog = memnew(EditorFileDialog);
- translation_res_option_file_open_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
- translation_res_option_file_open_dialog->connect("file_selected", callable_mp(this, &LocalizationEditor::_translation_res_option_add));
+ translation_res_option_file_open_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
+ translation_res_option_file_open_dialog->connect("files_selected", callable_mp(this, &LocalizationEditor::_translation_res_option_add));
add_child(translation_res_option_file_open_dialog);
}
@@ -825,8 +834,8 @@ LocalizationEditor::LocalizationEditor() {
add_child(pot_generate_dialog);
pot_file_open_dialog = memnew(EditorFileDialog);
- pot_file_open_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
- pot_file_open_dialog->connect("file_selected", callable_mp(this, &LocalizationEditor::_pot_add));
+ pot_file_open_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
+ pot_file_open_dialog->connect("files_selected", callable_mp(this, &LocalizationEditor::_pot_add));
add_child(pot_file_open_dialog);
}
diff --git a/editor/localization_editor.h b/editor/localization_editor.h
index 43b6bb60f6..6e0d7ce61f 100644
--- a/editor/localization_editor.h
+++ b/editor/localization_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -72,22 +72,22 @@ class LocalizationEditor : public VBoxContainer {
String localization_changed;
void _translation_file_open();
- void _translation_add(const String &p_path);
+ void _translation_add(const PackedStringArray &p_paths);
void _translation_delete(Object *p_item, int p_column, int p_button);
void _translation_res_file_open();
- void _translation_res_add(const String &p_path);
+ void _translation_res_add(const PackedStringArray &p_paths);
void _translation_res_delete(Object *p_item, int p_column, int p_button);
void _translation_res_select();
void _translation_res_option_file_open();
- void _translation_res_option_add(const String &p_path);
+ void _translation_res_option_add(const PackedStringArray &p_paths);
void _translation_res_option_changed();
void _translation_res_option_delete(Object *p_item, int p_column, int p_button);
void _translation_filter_option_changed();
void _translation_filter_mode_changed(int p_mode);
- void _pot_add(const String &p_path);
+ void _pot_add(const PackedStringArray &p_paths);
void _pot_delete(Object *p_item, int p_column, int p_button);
void _pot_file_open();
void _pot_generate_open();
diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp
index a7d5e5149e..b714109af7 100644
--- a/editor/multi_node_edit.cpp
+++ b/editor/multi_node_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/multi_node_edit.h b/editor/multi_node_edit.h
index 7f0fb625ef..0544eb2d50 100644
--- a/editor/multi_node_edit.h
+++ b/editor/multi_node_edit.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp
index 1f6c32ed70..16eefb1ad3 100644
--- a/editor/node_3d_editor_gizmos.cpp
+++ b/editor/node_3d_editor_gizmos.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -198,7 +198,11 @@ void EditorNode3DGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard,
}
void EditorNode3DGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard, const Color &p_modulate) {
- if (p_lines.empty()) {
+ add_vertices(p_lines, p_material, Mesh::PRIMITIVE_LINES, p_billboard, p_modulate);
+}
+
+void EditorNode3DGizmo::add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard, const Color &p_modulate) {
+ if (p_vertices.is_empty()) {
return;
}
@@ -209,13 +213,13 @@ void EditorNode3DGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mate
Array a;
a.resize(Mesh::ARRAY_MAX);
- a[Mesh::ARRAY_VERTEX] = p_lines;
+ a[Mesh::ARRAY_VERTEX] = p_vertices;
Vector<Color> color;
- color.resize(p_lines.size());
+ color.resize(p_vertices.size());
{
Color *w = color.ptrw();
- for (int i = 0; i < p_lines.size(); i++) {
+ for (int i = 0; i < p_vertices.size(); i++) {
if (is_selected()) {
w[i] = Color(1, 1, 1, 0.8) * p_modulate;
} else {
@@ -226,13 +230,13 @@ void EditorNode3DGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mate
a[Mesh::ARRAY_COLOR] = color;
- mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
+ mesh->add_surface_from_arrays(p_primitive_type, a);
mesh->surface_set_material(0, p_material);
if (p_billboard) {
float md = 0;
- for (int i = 0; i < p_lines.size(); i++) {
- md = MAX(0, p_lines[i].length());
+ for (int i = 0; i < p_vertices.size(); i++) {
+ md = MAX(0, p_vertices[i].length());
}
if (md) {
mesh->set_custom_aabb(AABB(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0));
@@ -557,7 +561,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
Transform t = spatial_node->get_global_transform();
Vector3 camera_position = p_camera->get_camera_transform().origin;
if (camera_position.distance_squared_to(t.origin) > 0.01) {
- t.set_look_at(t.origin, camera_position, Vector3(0, 1, 0));
+ t.set_look_at(t.origin, camera_position);
}
float scale = t.origin.distance_to(p_camera->get_camera_transform().origin);
@@ -574,7 +578,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
if (orig_camera_transform.origin.distance_squared_to(t.origin) > 0.01 &&
ABS(orig_camera_transform.basis.get_axis(Vector3::AXIS_Z).dot(Vector3(0, 1, 0))) < 0.99) {
- p_camera->look_at(t.origin, Vector3(0, 1, 0));
+ p_camera->look_at(t.origin);
}
Vector3 c0 = t.xform(Vector3(selectable_icon_size, selectable_icon_size, 0) * scale);
@@ -633,7 +637,7 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
tcp = a;
}
- if (camp.distance_to(tcp) < p_camera->get_znear()) {
+ if (camp.distance_to(tcp) < p_camera->get_near()) {
continue;
}
cp = tcp;
@@ -844,7 +848,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec
//min_p = p_arc_xform.affine_inverse().xform(min_p);
float a = (Math_PI * 0.5) - Vector2(min_p.x, -min_p.z).angle();
- return a * 180.0 / Math_PI;
+ return Math::rad2deg(a);
}
void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
@@ -863,7 +867,7 @@ void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer
float d = -ra.z;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d <= 0) { // Equal is here for negative zero.
@@ -878,7 +882,7 @@ void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer
if (cp.intersects_ray(ray_from, ray_dir, &inters)) {
float r = inters.distance_to(gt.origin);
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- r = Math::stepify(r, Node3DEditor::get_singleton()->get_translate_snap());
+ r = Math::snapped(r, Node3DEditor::get_singleton()->get_translate_snap());
}
light->set_param(Light3D::PARAM_RANGE, r);
@@ -1033,12 +1037,9 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_lines(points_primary, material_primary, false, color);
p_gizmo->add_lines(points_secondary, material_secondary, false, color);
- const float ra = 16 * Math_PI * 2.0 / 64.0;
- const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
-
Vector<Vector3> handles;
handles.push_back(Vector3(0, 0, -r));
- handles.push_back(Vector3(a.x, a.y, -d));
+ handles.push_back(Vector3(w, 0, -d));
p_gizmo->add_handles(handles, get_material("handles"));
p_gizmo->add_unscaled_billboard(icon, 0.05, color);
@@ -1095,8 +1096,8 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int
float closest_angle = 1e20;
for (int i = 0; i < 180; i++) {
- float a = i * Math_PI / 180.0;
- float an = (i + 1) * Math_PI / 180.0;
+ float a = Math::deg2rad((float)i);
+ float an = Math::deg2rad((float)(i + 1));
Vector3 from(Math::sin(a), 0, -Math::cos(a));
Vector3 to(Math::sin(an), 0, -Math::cos(an));
@@ -1145,9 +1146,10 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> points_primary;
points_primary.resize(200);
+ real_t step = Math_TAU / 100.0;
for (int i = 0; i < 100; i++) {
- const float a = i * 2.0 * Math_PI / 100.0;
- const float an = (i + 1) * 2.0 * Math_PI / 100.0;
+ const float a = i * step;
+ const float an = (i + 1) * step;
const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
const Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
@@ -1163,7 +1165,7 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
points_secondary.resize(16);
for (int i = 0; i < 8; i++) {
- const float a = i * 2.0 * Math_PI / 8.0;
+ const float a = i * (Math_TAU / 8.0);
const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
points_secondary.write[i * 2 + 0] = from;
@@ -1243,7 +1245,7 @@ void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Came
Geometry3D::get_closest_points_between_segments(Vector3(0, 0, -1), Vector3(4096, 0, -1), s[0], s[1], ra, rb);
float d = ra.x * 2.0;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
d = CLAMP(d, 0.1, 16384);
@@ -1357,7 +1359,7 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
case Camera3D::PROJECTION_FRUSTUM: {
float hsize = camera->get_size() / 2.0;
- Vector3 side = Vector3(hsize, 0, -camera->get_znear()).normalized();
+ Vector3 side = Vector3(hsize, 0, -camera->get_near()).normalized();
Vector3 nside = side;
nside.x = -nside.x;
Vector3 up = Vector3(0, side.x, 0);
@@ -1908,16 +1910,15 @@ void RayCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->clear();
- Vector<Vector3> lines;
+ const Ref<StandardMaterial3D> material = raycast->is_enabled() ? raycast->get_debug_material() : get_material("shape_material_disabled");
- lines.push_back(Vector3());
- lines.push_back(raycast->get_target_position());
+ p_gizmo->add_lines(raycast->get_debug_line_vertices(), material);
- const Ref<StandardMaterial3D> material =
- get_material(raycast->is_enabled() ? "shape_material" : "shape_material_disabled", p_gizmo);
+ if (raycast->get_debug_shape_thickness() > 1) {
+ p_gizmo->add_vertices(raycast->get_debug_shape_vertices(), material, Mesh::PRIMITIVE_TRIANGLE_STRIP);
+ }
- p_gizmo->add_lines(lines, material);
- p_gizmo->add_collision_segments(lines);
+ p_gizmo->add_collision_segments(raycast->get_debug_line_vertices());
}
/////
@@ -2173,7 +2174,7 @@ void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int
float d = ra[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5;
@@ -2185,7 +2186,7 @@ void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int
float d = ra[p_idx] - ofs[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -2364,7 +2365,7 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx
float d = ra[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5;
@@ -2376,7 +2377,7 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx
float d = ra[p_idx] - ofs[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -2521,7 +2522,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo,
Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
float d = ra.x;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -2538,7 +2539,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo,
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -2616,8 +2617,8 @@ void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> collision_segments;
for (int i = 0; i < 64; i++) {
- float ra = i * Math_PI * 2.0 / 64.0;
- float rb = (i + 1) * Math_PI * 2.0 / 64.0;
+ float ra = i * (Math_TAU / 64.0);
+ float rb = (i + 1) * (Math_TAU / 64.0);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
@@ -2786,7 +2787,7 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -2814,7 +2815,7 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id
// Adjust the actual position to account for the gizmo handle position
float d = ra[p_idx] + 0.25;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
origin[p_idx] = d;
@@ -2964,7 +2965,7 @@ void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -3105,7 +3106,7 @@ void GIProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -3317,7 +3318,7 @@ void BakedLightmapGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
int stack_count = 8;
int sector_count = 16;
- float sector_step = 2 * Math_PI / sector_count;
+ float sector_step = (Math_PI * 2.0) / sector_count;
float stack_step = Math_PI / stack_count;
Vector<Vector3> vertices;
@@ -3454,7 +3455,7 @@ void LightmapProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
int stack_count = 8;
int sector_count = 16;
- float sector_step = 2 * Math_PI / sector_count;
+ float sector_step = (Math_PI * 2.0) / sector_count;
float stack_step = Math_PI / stack_count;
Vector<Vector3> vertices;
@@ -3507,6 +3508,57 @@ void LightmapProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
////
+CollisionObject3DGizmoPlugin::CollisionObject3DGizmoPlugin() {
+ const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
+ create_material("shape_material", gizmo_color);
+ const float gizmo_value = gizmo_color.get_v();
+ const Color gizmo_color_disabled = Color(gizmo_value, gizmo_value, gizmo_value, 0.65);
+ create_material("shape_material_disabled", gizmo_color_disabled);
+}
+
+bool CollisionObject3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
+ return Object::cast_to<CollisionObject3D>(p_spatial) != nullptr;
+}
+
+String CollisionObject3DGizmoPlugin::get_gizmo_name() const {
+ return "CollisionObject3D";
+}
+
+int CollisionObject3DGizmoPlugin::get_priority() const {
+ return -1;
+}
+
+void CollisionObject3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
+ CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_gizmo->get_spatial_node());
+
+ p_gizmo->clear();
+
+ List<uint32_t> owners;
+ co->get_shape_owners(&owners);
+ for (List<uint32_t>::Element *E = owners.front(); E; E = E->next()) {
+ uint32_t owner_id = E->get();
+ Transform xform = co->shape_owner_get_transform(owner_id);
+ Object *owner = co->shape_owner_get_owner(owner_id);
+ // Exclude CollisionShape3D and CollisionPolygon3D as they have their gizmo.
+ if (!Object::cast_to<CollisionShape3D>(owner) && !Object::cast_to<CollisionPolygon3D>(owner)) {
+ Ref<Material> material = get_material(!co->is_shape_owner_disabled(owner_id) ? "shape_material" : "shape_material_disabled", p_gizmo);
+ for (int shape_id = 0; shape_id < co->shape_owner_get_shape_count(owner_id); shape_id++) {
+ Ref<Shape3D> s = co->shape_owner_get_shape(owner_id, shape_id);
+ if (s.is_null()) {
+ continue;
+ }
+ SurfaceTool st;
+ st.append_from(s->get_debug_mesh(), 0, xform);
+
+ p_gizmo->add_mesh(st.commit(), false, Ref<SkinReference>(), material);
+ p_gizmo->add_collision_segments(s->get_debug_mesh_lines());
+ }
+ }
+ }
+}
+
+////
+
CollisionShape3DGizmoPlugin::CollisionShape3DGizmoPlugin() {
const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
create_material("shape_material", gizmo_color);
@@ -3541,7 +3593,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g
}
if (Object::cast_to<BoxShape3D>(*s)) {
- return "Extents";
+ return "Size";
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
@@ -3574,7 +3626,7 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo
if (Object::cast_to<BoxShape3D>(*s)) {
Ref<BoxShape3D> bs = s;
- return bs->get_extents();
+ return bs->get_size();
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
@@ -3617,7 +3669,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
float d = ra.x;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -3633,7 +3685,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb);
float d = ra.z;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -3651,16 +3703,16 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
d = 0.001;
}
- Vector3 he = bs->get_extents();
- he[p_idx] = d;
- bs->set_extents(he);
+ Vector3 he = bs->get_size();
+ he[p_idx] = d * 2;
+ bs->set_size(he);
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
@@ -3675,7 +3727,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
}
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -3697,7 +3749,7 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -3737,14 +3789,14 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int
if (Object::cast_to<BoxShape3D>(*s)) {
Ref<BoxShape3D> ss = s;
if (p_cancel) {
- ss->set_extents(p_restore);
+ ss->set_size(p_restore);
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Change Box Shape Extents"));
- ur->add_do_method(ss.ptr(), "set_extents", ss->get_extents());
- ur->add_undo_method(ss.ptr(), "set_extents", p_restore);
+ ur->create_action(TTR("Change Box Shape Size"));
+ ur->add_do_method(ss.ptr(), "set_size", ss->get_size());
+ ur->add_undo_method(ss.ptr(), "set_size", p_restore);
ur->commit_action();
}
@@ -3854,8 +3906,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> collision_segments;
for (int i = 0; i < 64; i++) {
- float ra = i * Math_PI * 2.0 / 64.0;
- float rb = (i + 1) * Math_PI * 2.0 / 64.0;
+ float ra = i * (Math_TAU / 64.0);
+ float rb = (i + 1) * (Math_TAU / 64.0);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
@@ -3878,8 +3930,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Ref<BoxShape3D> bs = s;
Vector<Vector3> lines;
AABB aabb;
- aabb.position = -bs->get_extents();
- aabb.size = aabb.position * -2;
+ aabb.position = -bs->get_size() / 2;
+ aabb.size = bs->get_size();
for (int i = 0; i < 12; i++) {
Vector3 a, b;
@@ -3892,7 +3944,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
for (int i = 0; i < 3; i++) {
Vector3 ax;
- ax[i] = bs->get_extents()[i];
+ ax[i] = bs->get_size()[i] / 2;
handles.push_back(ax);
}
@@ -3939,8 +3991,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> collision_segments;
for (int i = 0; i < 64; i++) {
- float ra = i * Math_PI * 2.0 / 64.0;
- float rb = (i + 1) * Math_PI * 2.0 / 64.0;
+ float ra = i * (Math_TAU / 64.0);
+ float rb = (i + 1) * (Math_TAU / 64.0);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius;
@@ -4002,8 +4054,8 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> collision_segments;
for (int i = 0; i < 64; i++) {
- float ra = i * Math_PI * 2.0 / 64.0;
- float rb = (i + 1) * Math_PI * 2.0 / 64.0;
+ float ra = i * (Math_TAU / 64.0);
+ float rb = (i + 1) * (Math_TAU / 64.0);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius;
@@ -4205,7 +4257,7 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
}
- if (faces.empty()) {
+ if (faces.is_empty()) {
return;
}
@@ -4521,7 +4573,7 @@ Joint3DGizmoPlugin::Joint3DGizmoPlugin() {
}
void Joint3DGizmoPlugin::incremental_update_gizmos() {
- if (!current_gizmos.empty()) {
+ if (!current_gizmos.is_empty()) {
update_idx++;
update_idx = update_idx % current_gizmos.size();
redraw(current_gizmos[update_idx]);
diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h
index e418456d60..6f98d3a08c 100644
--- a/editor/node_3d_editor_gizmos.h
+++ b/editor/node_3d_editor_gizmos.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -355,6 +355,18 @@ public:
LightmapProbeGizmoPlugin();
};
+class CollisionObject3DGizmoPlugin : public EditorNode3DGizmoPlugin {
+ GDCLASS(CollisionObject3DGizmoPlugin, EditorNode3DGizmoPlugin);
+
+public:
+ bool has_gizmo(Node3D *p_spatial) override;
+ String get_gizmo_name() const override;
+ int get_priority() const override;
+ void redraw(EditorNode3DGizmo *p_gizmo) override;
+
+ CollisionObject3DGizmoPlugin();
+};
+
class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(CollisionShape3DGizmoPlugin, EditorNode3DGizmoPlugin);
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index 2c89517008..43c9cabe01 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/node_dock.h b/editor/node_dock.h
index 8e10db5eb3..280369bb09 100644
--- a/editor/node_dock.h
+++ b/editor/node_dock.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index a780750633..2a0e7d0732 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -112,7 +112,7 @@ void PluginConfigDialog::_on_confirmed() {
}
#endif
- emit_signal("plugin_ready", script.operator->(), active_edit->is_pressed() ? subfolder_edit->get_text() : "");
+ emit_signal("plugin_ready", script.operator->(), active_edit->is_pressed() ? _to_absolute_plugin_path(subfolder_edit->get_text()) : "");
} else {
EditorNode::get_singleton()->get_project_settings()->update_plugins();
}
@@ -126,7 +126,11 @@ void PluginConfigDialog::_on_cancelled() {
void PluginConfigDialog::_on_required_text_changed(const String &) {
int lang_idx = script_option_edit->get_selected();
String ext = ScriptServer::get_language(lang_idx)->get_extension();
- get_ok_button()->set_disabled(script_edit->get_text().get_basename().empty() || script_edit->get_text().get_extension() != ext || name_edit->get_text().empty());
+ get_ok_button()->set_disabled(script_edit->get_text().get_basename().is_empty() || script_edit->get_text().get_extension() != ext || name_edit->get_text().is_empty());
+}
+
+String PluginConfigDialog::_to_absolute_plugin_path(const String &p_plugin_name) {
+ return "res://addons/" + p_plugin_name + "/plugin.cfg";
}
void PluginConfigDialog::_notification(int p_what) {
diff --git a/editor/plugin_config_dialog.h b/editor/plugin_config_dialog.h
index 93c8c01c70..f49f14c881 100644
--- a/editor/plugin_config_dialog.h
+++ b/editor/plugin_config_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,6 +56,8 @@ class PluginConfigDialog : public ConfirmationDialog {
void _on_cancelled();
void _on_required_text_changed(const String &p_text);
+ static String _to_absolute_plugin_path(const String &p_plugin_name);
+
protected:
virtual void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 281b1d79af..876b67fa77 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 527803150d..4f9adfff25 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp
index 223484044a..d69913cc46 100644
--- a/editor/plugins/animation_blend_space_1d_editor.cpp
+++ b/editor/plugins/animation_blend_space_1d_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -106,7 +106,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
add_point_pos += blend_space->get_min_space();
if (snap->is_pressed()) {
- add_point_pos = Math::stepify(add_point_pos, blend_space->get_snap());
+ add_point_pos = Math::snapped(add_point_pos, blend_space->get_snap());
}
}
@@ -139,7 +139,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
point += drag_ofs.x;
if (snap->is_pressed()) {
- point = Math::stepify(point, blend_space->get_snap());
+ point = Math::snapped(point, blend_space->get_snap());
}
updating = true;
@@ -253,7 +253,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
if (dragging_selected && selected_point == i) {
point += drag_ofs.x;
if (snap->is_pressed()) {
- point = Math::stepify(point, blend_space->get_snap());
+ point = Math::snapped(point, blend_space->get_snap());
}
}
@@ -454,7 +454,7 @@ void AnimationNodeBlendSpace1DEditor::_update_edited_point_pos() {
pos += drag_ofs.x;
if (snap->is_pressed()) {
- pos = Math::stepify(pos, blend_space->get_snap());
+ pos = Math::snapped(pos, blend_space->get_snap());
}
}
diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h
index 5ff5da47c0..24c950fdee 100644
--- a/editor/plugins/animation_blend_space_1d_editor.h
+++ b/editor/plugins/animation_blend_space_1d_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 94785a5422..6a57463dbc 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -129,8 +129,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
add_point_pos += blend_space->get_min_space();
if (snap->is_pressed()) {
- add_point_pos.x = Math::stepify(add_point_pos.x, blend_space->get_snap().x);
- add_point_pos.y = Math::stepify(add_point_pos.y, blend_space->get_snap().y);
+ add_point_pos.x = Math::snapped(add_point_pos.x, blend_space->get_snap().x);
+ add_point_pos.y = Math::snapped(add_point_pos.y, blend_space->get_snap().y);
}
}
@@ -215,8 +215,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
Vector2 point = blend_space->get_blend_point_position(selected_point);
point += drag_ofs;
if (snap->is_pressed()) {
- point.x = Math::stepify(point.x, blend_space->get_snap().x);
- point.y = Math::stepify(point.y, blend_space->get_snap().y);
+ point.x = Math::snapped(point.x, blend_space->get_snap().x);
+ point.y = Math::snapped(point.y, blend_space->get_snap().y);
}
updating = true;
@@ -467,8 +467,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
if (dragging_selected && selected_point == point_idx) {
point += drag_ofs;
if (snap->is_pressed()) {
- point.x = Math::stepify(point.x, blend_space->get_snap().x);
- point.y = Math::stepify(point.y, blend_space->get_snap().y);
+ point.x = Math::snapped(point.x, blend_space->get_snap().x);
+ point.y = Math::snapped(point.y, blend_space->get_snap().y);
}
}
point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space());
@@ -503,8 +503,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
if (dragging_selected && selected_point == i) {
point += drag_ofs;
if (snap->is_pressed()) {
- point.x = Math::stepify(point.x, blend_space->get_snap().x);
- point.y = Math::stepify(point.y, blend_space->get_snap().y);
+ point.x = Math::snapped(point.x, blend_space->get_snap().x);
+ point.y = Math::snapped(point.y, blend_space->get_snap().y);
}
}
point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space());
@@ -702,8 +702,8 @@ void AnimationNodeBlendSpace2DEditor::_update_edited_point_pos() {
if (dragging_selected) {
pos += drag_ofs;
if (snap->is_pressed()) {
- pos.x = Math::stepify(pos.x, blend_space->get_snap().x);
- pos.y = Math::stepify(pos.y, blend_space->get_snap().y);
+ pos.x = Math::snapped(pos.x, blend_space->get_snap().x);
+ pos.y = Math::snapped(pos.y, blend_space->get_snap().y);
}
}
updating = true;
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index 64885aeaca..3b8b78b2b5 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index a20bbd2b62..e7e069e8b6 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -255,6 +255,9 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
graph->connect_node(from, 0, to, to_idx);
}
+
+ float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity");
+ graph->set_minimap_opacity(graph_minimap_opacity);
}
void AnimationNodeBlendTreeEditor::_file_opened(const String &p_file) {
@@ -416,7 +419,7 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request() {
}
}
- if (to_erase.empty()) {
+ if (to_erase.is_empty()) {
return;
}
@@ -537,7 +540,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
default: {
} break;
}
- if (!track_type_name.empty()) {
+ if (!track_type_name.is_empty()) {
types[track_path].insert(track_type_name);
}
}
@@ -888,6 +891,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
graph->connect("scroll_offset_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_scroll_changed));
graph->connect("delete_nodes_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_nodes_request));
graph->connect("popup_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_popup_request));
+ float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity");
+ graph->set_minimap_opacity(graph_minimap_opacity);
VSeparator *vs = memnew(VSeparator);
graph->get_zoom_hbox()->add_child(vs);
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index 3ebf623eef..9f09069719 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 4b97dacbc1..7c623505b5 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,7 +78,6 @@ void AnimationPlayerEditor::_notification(int p_what) {
}
frame->set_value(player->get_current_animation_position());
track_editor->set_anim_pos(player->get_current_animation_position());
- EditorNode::get_singleton()->get_inspector()->refresh();
} else if (!player->is_valid()) {
// Reset timeline when the player has been stopped externally
@@ -680,7 +679,7 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
if (p_state.has("animation")) {
String anim = p_state["animation"];
- if (!anim.empty() && player->has_animation(anim)) {
+ if (!anim.is_empty() && player->has_animation(anim)) {
_select_anim_by_name(anim);
_animation_edit();
}
@@ -1013,7 +1012,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
float pos = CLAMP(anim->get_length() * (p_value / frame->get_max()), 0, anim->get_length());
if (track_editor->is_snap_enabled()) {
- pos = Math::stepify(pos, _get_editor_step());
+ pos = Math::snapped(pos, _get_editor_step());
}
if (player->is_valid() && !p_set) {
@@ -1069,11 +1068,9 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag)
}
updating = true;
- frame->set_value(Math::stepify(p_pos, _get_editor_step()));
+ frame->set_value(Math::snapped(p_pos, _get_editor_step()));
updating = false;
_seek_value_changed(p_pos, !p_drag);
-
- EditorNode::get_singleton()->get_inspector()->refresh();
}
void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
@@ -1400,7 +1397,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
// Render every past/future step with the capture shader.
RS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, onion.capture.material->get_rid());
- onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/default_clear_color"));
+ onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
onion.capture.material->set_shader_param("differences_only", onion.differences_only);
onion.capture.material->set_shader_param("present", onion.differences_only ? RS::get_singleton()->viewport_get_texture(present_rid) : RID());
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index ab3feb115f..2f6bf55e4c 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 6fa1792c67..c6d2faf849 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -520,7 +520,7 @@ void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, co
Transform2D xf;
xf.elements[0] = (p_to - p_from).normalized();
- xf.elements[1] = xf.elements[0].tangent();
+ xf.elements[1] = xf.elements[0].orthogonal();
xf.elements[2] = (p_from + p_to) * 0.5 - xf.elements[1] * icon->get_height() * 0.5 - xf.elements[0] * icon->get_height() * 0.5;
state_machine_draw->draw_set_transform_matrix(xf);
@@ -690,7 +690,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
tl.width = tr_bidi_offset;
if (state_machine->has_transition(tl.to_node, tl.from_node)) { //offset if same exists
- Vector2 offset = -(tl.from - tl.to).normalized().tangent() * tr_bidi_offset;
+ Vector2 offset = -(tl.from - tl.to).normalized().orthogonal() * tr_bidi_offset;
tl.from += offset;
tl.to += offset;
}
diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h
index 119feb417d..a969ddd26b 100644
--- a/editor/plugins/animation_state_machine_editor.h
+++ b/editor/plugins/animation_state_machine_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp
index 800df12199..c33b06ff32 100644
--- a/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h
index fd3a449487..de3d89ae17 100644
--- a/editor/plugins/animation_tree_editor_plugin.h
+++ b/editor/plugins/animation_tree_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index bd70e649e6..030ce4655d 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -350,7 +350,7 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
if (sha256 != download_sha256) {
error_text = TTR("Bad download hash, assuming file has been tampered with.") + "\n";
error_text += TTR("Expected:") + " " + sha256 + "\n" + TTR("Got:") + " " + download_sha256;
- status->set_text(TTR("Failed sha256 hash check"));
+ status->set_text(TTR("Failed SHA-256 hash check"));
}
}
} break;
@@ -359,6 +359,8 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
if (error_text != String()) {
download_error->set_text(TTR("Asset Download Error:") + "\n" + error_text);
download_error->popup_centered();
+ // Let the user retry the download.
+ retry->show();
return;
}
@@ -459,6 +461,9 @@ void EditorAssetLibraryItemDownload::_install() {
}
void EditorAssetLibraryItemDownload::_make_request() {
+ // Hide the Retry button if we've just pressed it.
+ retry->hide();
+
download->cancel_request();
download->set_download_file(EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_asset_" + itos(asset_id)) + ".zip");
@@ -516,6 +521,8 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
retry = memnew(Button);
retry->set_text(TTR("Retry"));
retry->connect("pressed", callable_mp(this, &EditorAssetLibraryItemDownload::_make_request));
+ // Only show the Retry button in case of a failure.
+ retry->hide();
hb2->add_child(retry);
hb2->add_child(install);
@@ -702,7 +709,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PackedB
}
}
- if (!image->empty()) {
+ if (!image->is_empty()) {
switch (image_queue[p_queue_id].image_type) {
case IMAGE_QUEUE_ICON:
@@ -900,7 +907,7 @@ void EditorAssetLibrary::_search(int p_page) {
}
if (filter->get_text() != String()) {
- args += "&filter=" + filter->get_text().http_escape();
+ args += "&filter=" + filter->get_text().uri_encode();
}
if (p_page > 0) {
@@ -962,14 +969,16 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
for (int i = from; i < to; i++) {
if (i == p_page) {
Button *current = memnew(Button);
- current->set_text(itos(i + 1));
+ // Keep the extended padding for the currently active page (see below).
+ current->set_text(vformat(" %d ", i + 1));
current->set_disabled(true);
current->set_focus_mode(Control::FOCUS_NONE);
hbc->add_child(current);
} else {
Button *current = memnew(Button);
- current->set_text(itos(i + 1));
+ // Add padding to make page number buttons easier to click.
+ current->set_text(vformat(" %d ", i + 1));
current->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(i));
hbc->add_child(current);
@@ -1151,7 +1160,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
asset_bottom_page = _make_pages(page, pages, page_len, total_items, result.size());
library_vb->add_child(asset_bottom_page);
- if (result.empty()) {
+ if (result.is_empty()) {
if (filter->get_text() != String()) {
library_error->set_text(
vformat(TTR("No results for \"%s\"."), filter->get_text()));
@@ -1188,7 +1197,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
}
}
- if (!result.empty()) {
+ if (!result.is_empty()) {
library_scroll->set_v_scroll(0);
}
} break;
@@ -1364,10 +1373,18 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
search_hb2->add_child(memnew(Label(TTR("Site:") + " ")));
repository = memnew(OptionButton);
- repository->add_item("godotengine.org");
- repository->set_item_metadata(0, "https://godotengine.org/asset-library/api");
- repository->add_item("localhost");
- repository->set_item_metadata(1, "http://127.0.0.1/asset-library/api");
+ {
+ Dictionary default_urls;
+ default_urls["godotengine.org"] = "https://godotengine.org/asset-library/api";
+ default_urls["localhost"] = "http://127.0.0.1/asset-library/api";
+ Dictionary available_urls = _EDITOR_DEF("asset_library/available_urls", default_urls, true);
+ Array keys = available_urls.keys();
+ for (int i = 0; i < available_urls.size(); i++) {
+ String key = keys[i];
+ repository->add_item(key);
+ repository->set_item_metadata(i, available_urls[key]);
+ }
+ }
repository->connect("item_selected", callable_mp(this, &EditorAssetLibrary::_repository_changed));
@@ -1379,6 +1396,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
support = memnew(MenuButton);
search_hb2->add_child(support);
support->set_text(TTR("Support"));
+ support->get_popup()->set_hide_on_checkable_item_selection(false);
support->get_popup()->add_check_item(TTR("Official"), SUPPORT_OFFICIAL);
support->get_popup()->add_check_item(TTR("Community"), SUPPORT_COMMUNITY);
support->get_popup()->add_check_item(TTR("Testing"), SUPPORT_TESTING);
@@ -1492,7 +1510,7 @@ AssetLibraryEditorPlugin::AssetLibraryEditorPlugin(EditorNode *p_node) {
editor = p_node;
addon_library = memnew(EditorAssetLibrary);
addon_library->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor->get_viewport()->add_child(addon_library);
+ editor->get_main_control()->add_child(addon_library);
addon_library->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
addon_library->hide();
}
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index b69dfc208e..0509145673 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index 5041cf9f32..5963092860 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -96,7 +96,7 @@ void AudioStreamEditor::_preview_changed(ObjectID p_which) {
}
}
-void AudioStreamEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+void AudioStreamEditor::_audio_changed() {
if (!is_visible()) {
return;
}
@@ -172,7 +172,7 @@ void AudioStreamEditor::_seek_to(real_t p_x) {
void AudioStreamEditor::edit(Ref<AudioStream> p_stream) {
if (!stream.is_null()) {
- stream->remove_change_receptor(this);
+ stream->disconnect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed));
}
stream = p_stream;
@@ -182,7 +182,7 @@ void AudioStreamEditor::edit(Ref<AudioStream> p_stream) {
_duration_label->set_text(text);
if (!stream.is_null()) {
- stream->add_change_receptor(this);
+ stream->connect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed));
update();
} else {
hide();
diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/plugins/audio_stream_editor_plugin.h
index 5936b91fa1..aa906a6a05 100644
--- a/editor/plugins/audio_stream_editor_plugin.h
+++ b/editor/plugins/audio_stream_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,6 +53,8 @@ class AudioStreamEditor : public ColorRect {
float _current;
bool _dragging;
+ void _audio_changed();
+
protected:
void _notification(int p_what);
void _preview_changed(ObjectID p_which);
@@ -63,7 +65,6 @@ protected:
void _draw_indicator();
void _on_input_indicator(Ref<InputEvent> p_event);
void _seek_to(real_t p_x);
- void _changed_callback(Object *p_changed, const char *p_prop) override;
static void _bind_methods();
public:
diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp
index e5d4e4a761..470b61bf40 100644
--- a/editor/plugins/baked_lightmap_editor_plugin.cpp
+++ b/editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/baked_lightmap_editor_plugin.h b/editor/plugins/baked_lightmap_editor_plugin.h
index b4c7c07562..d291c377d9 100644
--- a/editor/plugins/baked_lightmap_editor_plugin.h
+++ b/editor/plugins/baked_lightmap_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/camera_3d_editor_plugin.cpp b/editor/plugins/camera_3d_editor_plugin.cpp
index 9a5cfd35cd..8583e95b25 100644
--- a/editor/plugins/camera_3d_editor_plugin.cpp
+++ b/editor/plugins/camera_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -98,7 +98,7 @@ void Camera3DEditorPlugin::make_visible(bool p_visible) {
Camera3DEditorPlugin::Camera3DEditorPlugin(EditorNode *p_node) {
editor = p_node;
/* camera_editor = memnew( CameraEditor );
- editor->get_viewport()->add_child(camera_editor);
+ editor->get_main_control()->add_child(camera_editor);
camera_editor->set_anchor(SIDE_LEFT,Control::ANCHOR_END);
camera_editor->set_anchor(SIDE_RIGHT,Control::ANCHOR_END);
diff --git a/editor/plugins/camera_3d_editor_plugin.h b/editor/plugins/camera_3d_editor_plugin.h
index 023f1866df..e087dd22a8 100644
--- a/editor/plugins/camera_3d_editor_plugin.h
+++ b/editor/plugins/camera_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 5073cbd0b9..bac6f3cd79 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -216,8 +216,8 @@ public:
grid_step_x->set_value(p_grid_step.x);
grid_step_y->set_value(p_grid_step.y);
primary_grid_steps->set_value(p_primary_grid_steps);
- rotation_offset->set_value(p_rotation_offset * (180 / Math_PI));
- rotation_step->set_value(p_rotation_step * (180 / Math_PI));
+ rotation_offset->set_value(Math::rad2deg(p_rotation_offset));
+ rotation_step->set_value(Math::rad2deg(p_rotation_step));
scale_step->set_value(p_scale_step);
}
@@ -225,8 +225,8 @@ public:
p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value());
p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value());
p_primary_grid_steps = int(primary_grid_steps->get_value());
- p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI);
- p_rotation_step = rotation_step->get_value() / (180 / Math_PI);
+ p_rotation_offset = Math::deg2rad(rotation_offset->get_value());
+ p_rotation_step = Math::deg2rad(rotation_step->get_value());
p_scale_step = scale_step->get_value();
}
};
@@ -444,8 +444,8 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig
}
}
Point2 grid_output;
- grid_output.x = Math::stepify(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x;
- grid_output.y = Math::stepify(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y;
+ grid_output.x = Math::snapped(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x;
+ grid_output.y = Math::snapped(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y;
_snap_if_closer_point(p_target, output, snap_target, grid_output, SNAP_TARGET_GRID, 0.0, -1.0);
}
@@ -462,9 +462,9 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig
float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
if (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) {
if (snap_relative) {
- return Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step);
+ return Math::snapped(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step);
} else {
- return Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset;
+ return Math::snapped(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset;
}
} else {
return p_target;
@@ -518,7 +518,7 @@ void CanvasItemEditor::_keying_changed() {
}
Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List<CanvasItem *> p_list) {
- ERR_FAIL_COND_V(p_list.empty(), Rect2());
+ ERR_FAIL_COND_V(p_list.is_empty(), Rect2());
// Handles the first element
CanvasItem *canvas_item = p_list.front()->get();
@@ -629,9 +629,9 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel
Node *node = r_items[i].item;
// Make sure the selected node is in the current scene, or editable
- while (node && node != get_tree()->get_edited_scene_root() && node->get_owner() != scene && !scene->is_editable_instance(node->get_owner())) {
- node = node->get_parent();
- };
+ if (node && node != get_tree()->get_edited_scene_root()) {
+ node = scene->get_deepest_editable_node(node);
+ }
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(node);
if (!p_allow_locked) {
@@ -727,7 +727,7 @@ bool CanvasItemEditor::_get_bone_shape(Vector<Vector2> *shape, Vector<Vector2> *
}
Vector2 rel = to - from;
- Vector2 relt = rel.tangent().normalized() * bone_width;
+ Vector2 relt = rel.orthogonal().normalized() * bone_width;
Vector2 reln = rel.normalized();
Vector2 reltn = relt.normalized();
@@ -762,7 +762,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
Node *scene = editor->get_edited_scene();
- bool editable = p_node == scene || p_node->get_owner() == scene || scene->is_editable_instance(p_node->get_owner());
+ bool editable = p_node == scene || p_node->get_owner() == scene || p_node == scene->get_deepest_editable_node(p_node);
bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_");
bool locked = _is_node_locked(p_node);
@@ -955,25 +955,44 @@ void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_it
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
- canvas_item->_edit_set_state(se->undo_state);
- if (restore_bones) {
- _restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state));
+ if (se) {
+ canvas_item->_edit_set_state(se->undo_state);
+ if (restore_bones) {
+ _restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state));
+ }
}
}
}
void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones) {
- undo_redo->create_action(action_name);
+ List<CanvasItem *> modified_canvas_items;
for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
+ Dictionary old_state = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item)->undo_state;
+ Dictionary new_state = canvas_item->_edit_get_state();
+
+ if (old_state.hash() != new_state.hash()) {
+ modified_canvas_items.push_back(canvas_item);
+ }
+ }
+
+ if (modified_canvas_items.is_empty()) {
+ return;
+ }
+
+ undo_redo->create_action(action_name);
+ for (List<CanvasItem *>::Element *E = modified_canvas_items.front(); E; E = E->next()) {
+ CanvasItem *canvas_item = E->get();
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
- undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state());
- undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state);
- if (commit_bones) {
- for (List<Dictionary>::Element *F = se->pre_drag_bones_undo_state.front(); F; F = F->next()) {
- canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent());
- undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state());
- undo_redo->add_undo_method(canvas_item, "_edit_set_state", F->get());
+ if (se) {
+ undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state());
+ undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state);
+ if (commit_bones) {
+ for (List<Dictionary>::Element *F = se->pre_drag_bones_undo_state.front(); F; F = F->next()) {
+ canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent());
+ undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state());
+ undo_redo->add_undo_method(canvas_item, "_edit_set_state", F->get());
+ }
}
}
}
@@ -1006,6 +1025,32 @@ void CanvasItemEditor::_selection_menu_hide() {
selection_menu->set_size(Vector2(0, 0));
}
+void CanvasItemEditor::_add_node_pressed(int p_result) {
+ if (p_result == AddNodeOption::ADD_NODE) {
+ editor->get_scene_tree_dock()->open_add_child_dialog();
+ } else if (p_result == AddNodeOption::ADD_INSTANCE) {
+ editor->get_scene_tree_dock()->open_instance_child_dialog();
+ }
+}
+
+void CanvasItemEditor::_node_created(Node *p_node) {
+ if (node_create_position == Point2()) {
+ return;
+ }
+
+ CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
+ if (c) {
+ Transform2D xform = c->get_global_transform_with_canvas().affine_inverse() * c->get_transform();
+ c->_edit_set_position(xform.xform(node_create_position));
+ }
+
+ call_deferred("_reset_create_position"); // Defer the call in case more than one node is added.
+}
+
+void CanvasItemEditor::_reset_create_position() {
+ node_create_position = Point2();
+}
+
bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> b = p_event;
Ref<InputEventMouseMotion> m = p_event;
@@ -1147,7 +1192,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve
if (dragged_guide_index >= 0) {
vguides.remove(dragged_guide_index);
undo_redo->create_action(TTR("Remove Vertical Guide"));
- if (vguides.empty()) {
+ if (vguides.is_empty()) {
undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "remove_meta", "_edit_vertical_guides_");
} else {
undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides);
@@ -1180,7 +1225,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve
if (dragged_guide_index >= 0) {
hguides.remove(dragged_guide_index);
undo_redo->create_action(TTR("Remove Horizontal Guide"));
- if (hguides.empty()) {
+ if (hguides.is_empty()) {
undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "remove_meta", "_edit_horizontal_guides_");
} else {
undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides);
@@ -1808,7 +1853,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
}
ofs = (endpoints[i] + endpoints[next]) / 2;
- ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2);
+ ofs += (endpoints[next] - endpoints[i]).orthogonal().normalized() * (select_handle->get_size().width / 2);
if (ofs.distance_to(b->get_position()) < radius) {
resize_drag = dragger[i * 2 + 1];
}
@@ -1931,8 +1976,8 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
vformat(
TTR("Scale Node2D \"%s\" to (%s, %s)"),
drag_selection[0]->get_name(),
- Math::stepify(drag_selection[0]->_edit_get_scale().x, 0.01),
- Math::stepify(drag_selection[0]->_edit_get_scale().y, 0.01)),
+ Math::snapped(drag_selection[0]->_edit_get_scale().x, 0.01),
+ Math::snapped(drag_selection[0]->_edit_get_scale().y, 0.01)),
true);
} else {
// Extends from Control.
@@ -2083,8 +2128,8 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
drag_selection,
vformat(TTR("Scale CanvasItem \"%s\" to (%s, %s)"),
drag_selection[0]->get_name(),
- Math::stepify(drag_selection[0]->_edit_get_scale().x, 0.01),
- Math::stepify(drag_selection[0]->_edit_get_scale().y, 0.01)),
+ Math::snapped(drag_selection[0]->_edit_get_scale().x, 0.01),
+ Math::snapped(drag_selection[0]->_edit_get_scale().y, 0.01)),
true);
}
if (key_auto_insert_button->is_pressed()) {
@@ -2197,17 +2242,19 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
- Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform();
-
- Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
- if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) {
- real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
- _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
- real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
- node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
- _solve_IK(node2d, new_pos);
- } else {
- canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
+ if (se) {
+ Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform();
+
+ Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
+ if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) {
+ real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
+ _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
+ real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
+ node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
+ _solve_IK(node2d, new_pos);
+ } else {
+ canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
+ }
}
index++;
}
@@ -2331,17 +2378,19 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
- Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform();
-
- Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
- if (node2d && se->pre_drag_bones_undo_state.size() > 0) {
- real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
- _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
- real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
- node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
- _solve_IK(node2d, new_pos);
- } else {
- canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
+ if (se) {
+ Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform();
+
+ Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
+ if (node2d && se->pre_drag_bones_undo_state.size() > 0) {
+ real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
+ _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
+ real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
+ node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
+ _solve_IK(node2d, new_pos);
+ } else {
+ canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
+ }
}
index++;
}
@@ -2400,7 +2449,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
_select_click_on_item(item, click, b->get_shift());
return true;
- } else if (!selection_results.empty()) {
+ } else if (!selection_results.is_empty()) {
// Sorts items according the their z-index
selection_results.sort();
@@ -2448,6 +2497,14 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
}
+ if (b.is_valid() && b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && b->get_control()) {
+ add_node_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
+ add_node_menu->set_size(Vector2(1, 1));
+ add_node_menu->popup();
+ node_create_position = transform.affine_inverse().xform((get_local_mouse_position()));
+ return true;
+ }
+
if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && tool == TOOL_SELECT) {
// Single item selection
Point2 click = transform.affine_inverse().xform(b->get_position());
@@ -2463,13 +2520,13 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
// Retrieve the bones
Vector<_SelectResult> selection = Vector<_SelectResult>();
_get_bones_at_pos(click, selection);
- if (!selection.empty()) {
+ if (!selection.is_empty()) {
canvas_item = selection[0].item;
} else {
// Retrieve the canvas items
selection = Vector<_SelectResult>();
_get_canvas_items_at_pos(click, selection);
- if (!selection.empty()) {
+ if (!selection.is_empty()) {
canvas_item = selection[0].item;
}
}
@@ -2853,21 +2910,22 @@ void CanvasItemEditor::_draw_guides() {
// Dragged guide
Color text_color = get_theme_color("font_color", "Editor");
- text_color.a = 0.5;
+ Color outline_color = text_color.inverted();
+ const float outline_size = 2;
if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_V_GUIDE) {
String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).x)));
- Ref<Font> font = get_theme_font("font", "Label");
- int font_size = get_theme_font_size("font_size", "Label");
+ Ref<Font> font = get_theme_font("bold", "EditorFonts");
+ int font_size = get_theme_font_size("bold_size", "EditorFonts");
Size2 text_size = font->get_string_size(str, font_size);
- viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color);
+ viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color, outline_size, outline_color);
viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE));
}
if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) {
String str = TS->format_number(vformat("%d px", Math::round(xform.affine_inverse().xform(dragged_guide_pos).y)));
- Ref<Font> font = get_theme_font("font", "Label");
- int font_size = get_theme_font_size("font_size", "Label");
+ Ref<Font> font = get_theme_font("bold", "EditorFonts");
+ int font_size = get_theme_font_size("bold_size", "EditorFonts");
Size2 text_size = font->get_string_size(str, font_size);
- viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color);
+ viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, HALIGN_LEFT, -1, font_size, text_color, outline_size, outline_color);
viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color, Math::round(EDSCALE));
}
}
@@ -3134,16 +3192,16 @@ void CanvasItemEditor::_draw_ruler_tool() {
float arc_1_start_angle =
end_to_begin.x < 0 ?
- (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 - vertical_angle_rad : Math_PI / 2.0) :
- (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 : Math_PI / 2.0 - vertical_angle_rad);
+ (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 - vertical_angle_rad : Math_PI / 2.0) :
+ (end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 : Math_PI / 2.0 - vertical_angle_rad);
float arc_1_end_angle = arc_1_start_angle + vertical_angle_rad;
// Constrain arc to triangle height & max size
float arc_1_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.y)), arc_max_radius);
float arc_2_start_angle =
end_to_begin.x < 0 ?
- (end_to_begin.y < 0 ? 0.0 : -horizontal_angle_rad) :
- (end_to_begin.y < 0 ? Math_PI - horizontal_angle_rad : Math_PI);
+ (end_to_begin.y < 0 ? 0.0 : -horizontal_angle_rad) :
+ (end_to_begin.y < 0 ? Math_PI - horizontal_angle_rad : Math_PI);
float arc_2_end_angle = arc_2_start_angle + horizontal_angle_rad;
// Constrain arc to triangle width & max size
float arc_2_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.x)), arc_max_radius);
@@ -3498,7 +3556,7 @@ void CanvasItemEditor::_draw_selection() {
select_handle->draw(ci, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor());
ofs = (endpoints[i] + endpoints[next]) / 2;
- ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2);
+ ofs += (endpoints[next] - endpoints[i]).orthogonal().normalized() * (select_handle->get_size().width / 2);
select_handle->draw(ci, (ofs - (select_handle->get_size() / 2)).floor());
}
@@ -3852,7 +3910,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
Node *scene = editor->get_edited_scene();
- if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner()))) {
+ if (!canvas_item || !canvas_item->is_visible() || (canvas_item != scene && canvas_item->get_owner() != scene && canvas_item != scene->get_deepest_editable_node(canvas_item))) {
return false;
}
@@ -3916,7 +3974,7 @@ void CanvasItemEditor::_draw_viewport() {
bool all_locked = true;
bool all_group = true;
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.empty()) {
+ if (selection.is_empty()) {
all_locked = false;
all_group = false;
} else {
@@ -3935,10 +3993,10 @@ void CanvasItemEditor::_draw_viewport() {
}
lock_button->set_visible(!all_locked);
- lock_button->set_disabled(selection.empty());
+ lock_button->set_disabled(selection.is_empty());
unlock_button->set_visible(all_locked);
group_button->set_visible(!all_group);
- group_button->set_disabled(selection.empty());
+ group_button->set_disabled(selection.is_empty());
ungroup_button->set_visible(all_group);
info_overlay->set_offset(SIDE_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
@@ -3956,11 +4014,11 @@ void CanvasItemEditor::_draw_viewport() {
RenderingServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D());
EditorPluginList *over_plugin_list = editor->get_editor_plugins_over();
- if (!over_plugin_list->empty()) {
+ if (!over_plugin_list->is_empty()) {
over_plugin_list->forward_canvas_draw_over_viewport(viewport);
}
EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over();
- if (!force_over_plugin_list->empty()) {
+ if (!force_over_plugin_list->is_empty()) {
force_over_plugin_list->forward_canvas_force_draw_over_viewport(viewport);
}
@@ -4148,7 +4206,7 @@ void CanvasItemEditor::_notification(int p_what) {
// the icon will be dark, so we need to lighten it before blending it
// with the red color.
const Color key_auto_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25);
- key_auto_insert_button->add_theme_color_override("icon_color_pressed", key_auto_color.lerp(Color(1, 0, 0), 0.55));
+ key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55));
animation_menu->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons"));
zoom_minus->set_icon(get_theme_icon("ZoomLess", "EditorIcons"));
@@ -4446,7 +4504,7 @@ void CanvasItemEditor::_set_anchors_and_offsets_preset(Control::LayoutPreset p_p
case PRESET_CENTER_RIGHT:
case PRESET_CENTER_BOTTOM:
case PRESET_CENTER:
- undo_redo->add_do_method(control, "set_margins_preset", p_preset, Control::PRESET_MODE_KEEP_SIZE);
+ undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_KEEP_SIZE);
break;
case PRESET_LEFT_WIDE:
case PRESET_TOP_WIDE:
@@ -4455,7 +4513,7 @@ void CanvasItemEditor::_set_anchors_and_offsets_preset(Control::LayoutPreset p_p
case PRESET_VCENTER_WIDE:
case PRESET_HCENTER_WIDE:
case PRESET_WIDE:
- undo_redo->add_do_method(control, "set_margins_preset", p_preset, Control::PRESET_MODE_MINSIZE);
+ undo_redo->add_do_method(control, "set_offsets_preset", p_preset, Control::PRESET_MODE_MINSIZE);
break;
}
undo_redo->add_undo_method(control, "_edit_set_state", control->_edit_get_state());
@@ -4576,7 +4634,7 @@ void CanvasItemEditor::_update_zoom_label() {
// Don't show a decimal when the zoom level is higher than 1000 %.
zoom_text = TS->format_number(rtos(Math::round((zoom / MAX(1, EDSCALE)) * 100))) + " " + TS->percent_sign();
} else {
- zoom_text = TS->format_number(rtos(Math::stepify((zoom / MAX(1, EDSCALE)) * 100, 0.1))) + " " + TS->percent_sign();
+ zoom_text = TS->format_number(rtos(Math::snapped((zoom / MAX(1, EDSCALE)) * 100, 0.1))) + " " + TS->percent_sign();
}
zoom_reset->set_text(zoom_text);
@@ -5348,6 +5406,7 @@ void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input);
ClassDB::bind_method("_queue_update_bone_list", &CanvasItemEditor::_update_bone_list);
ClassDB::bind_method("_update_bone_list", &CanvasItemEditor::_update_bone_list);
+ ClassDB::bind_method("_reset_create_position", &CanvasItemEditor::_reset_create_position);
ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state);
ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport);
@@ -5623,7 +5682,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
primary_grid_steps = 8; // A power-of-two value works better as a default
grid_step_multiplier = 0;
snap_rotation_offset = 0;
- snap_rotation_step = 15 / (180 / Math_PI);
+ snap_rotation_step = Math::deg2rad(15.0);
snap_scale_step = 0.1f;
smart_snap_active = false;
grid_snap_active = false;
@@ -5669,6 +5728,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::update));
editor_selection->connect("selection_changed", callable_mp(this, &CanvasItemEditor::_selection_changed));
+ editor->get_scene_tree_dock()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created));
+ editor->get_scene_tree_dock()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position));
+
editor->call_deferred("connect", "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true));
editor->call_deferred("connect", "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false));
@@ -5764,7 +5826,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
zoom_reset->set_flat(true);
zoom_hb->add_child(zoom_reset);
zoom_reset->add_theme_constant_override("outline_size", 1);
- zoom_reset->add_theme_color_override("font_outline_modulate", Color(0, 0, 0));
+ zoom_reset->add_theme_color_override("font_outline_color", Color(0, 0, 0));
zoom_reset->add_theme_color_override("font_color", Color(1, 1, 1));
zoom_reset->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_zoom_reset));
zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KEY_MASK_CMD | KEY_0));
@@ -6090,6 +6152,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
selection_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_selection_result_pressed));
selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide));
+ add_node_menu = memnew(PopupMenu);
+ add_child(add_node_menu);
+ add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon("Add", "EditorIcons"), TTR("Add Node Here"));
+ add_node_menu->add_icon_item(editor->get_scene_tree_dock()->get_theme_icon("Instance", "EditorIcons"), TTR("Instance Scene Here"));
+ add_node_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_add_node_pressed));
+
multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), KEY_KP_MULTIPLY);
divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), KEY_KP_DIVIDE);
pan_view_shortcut = ED_SHORTCUT("canvas_item_editor/pan_view", TTR("Pan View"), KEY_SPACE);
@@ -6139,7 +6207,7 @@ CanvasItemEditorPlugin::CanvasItemEditorPlugin(EditorNode *p_node) {
editor = p_node;
canvas_item_editor = memnew(CanvasItemEditor(editor));
canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor->get_viewport()->add_child(canvas_item_editor);
+ editor->get_main_control()->add_child(canvas_item_editor);
canvas_item_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
canvas_item_editor->hide();
}
@@ -6598,7 +6666,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
}
label = memnew(Label);
- label->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 1));
+ label->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 1));
label->add_theme_constant_override("shadow_as_outline", 1 * EDSCALE);
label->hide();
canvas_item_editor->get_controls_container()->add_child(label);
@@ -6606,7 +6674,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
label_desc = memnew(Label);
label_desc->set_text(TTR("Drag & drop + Shift : Add node as sibling\nDrag & drop + Alt : Change node type"));
label_desc->add_theme_color_override("font_color", Color(0.6f, 0.6f, 0.6f, 1));
- label_desc->add_theme_color_override("font_color_shadow", Color(0.2f, 0.2f, 0.2f, 1));
+ label_desc->add_theme_color_override("font_shadow_color", Color(0.2f, 0.2f, 0.2f, 1));
label_desc->add_theme_constant_override("shadow_as_outline", 1 * EDSCALE);
label_desc->add_theme_constant_override("line_spacing", 0);
label_desc->hide();
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index f5da953810..62a9b1e162 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -79,6 +79,11 @@ public:
TOOL_MAX
};
+ enum AddNodeOption {
+ ADD_NODE,
+ ADD_INSTANCE,
+ };
+
private:
EditorNode *editor;
@@ -284,6 +289,7 @@ private:
bool ruler_tool_active;
Point2 ruler_tool_origin;
+ Point2 node_create_position;
MenuOption last_option;
@@ -376,6 +382,7 @@ private:
Button *key_auto_insert_button;
PopupMenu *selection_menu;
+ PopupMenu *add_node_menu;
Control *top_ruler;
Control *left_ruler;
@@ -436,6 +443,9 @@ private:
void _snap_changed();
void _selection_result_pressed(int);
void _selection_menu_hide();
+ void _add_node_pressed(int p_result);
+ void _node_created(Node *p_node);
+ void _reset_create_position();
UndoRedo *undo_redo;
bool _build_bones_list(Node *p_node);
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index 08d6fc966d..8e340b28ef 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h
index 482f00a7f7..e78c486a39 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp
index 6eb17685f6..0c18975258 100644
--- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.h b/editor/plugins/collision_polygon_3d_editor_plugin.h
index bb4ee2185e..c66518e3e5 100644
--- a/editor/plugins/collision_polygon_3d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 23ab6a9de2..141ee35cdb 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -98,7 +98,7 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const {
Ref<RectangleShape2D> rect = node->get_shape();
if (idx < 3) {
- return rect->get_extents().abs();
+ return rect->get_size().abs();
}
} break;
@@ -179,13 +179,13 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
if (idx < 3) {
Ref<RectangleShape2D> rect = node->get_shape();
- Vector2 extents = rect->get_extents();
+ Vector2 size = rect->get_size();
if (idx == 2) {
- extents = p_point;
+ size = p_point * 2;
} else {
- extents[idx] = p_point[idx];
+ size[idx] = p_point[idx] * 2;
}
- rect->set_extents(extents.abs());
+ rect->set_size(size.abs());
canvas_item_editor->update_viewport();
}
@@ -207,7 +207,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
} break;
}
- node->get_shape()->_change_notify();
+ node->get_shape()->notify_property_list_changed();
}
void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
@@ -279,9 +279,9 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
case RECTANGLE_SHAPE: {
Ref<RectangleShape2D> rect = node->get_shape();
- undo_redo->add_do_method(rect.ptr(), "set_extents", rect->get_extents());
+ undo_redo->add_do_method(rect.ptr(), "set_size", rect->get_size());
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
- undo_redo->add_undo_method(rect.ptr(), "set_extents", p_org);
+ undo_redo->add_undo_method(rect.ptr(), "set_size", p_org);
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
} break;
@@ -493,7 +493,7 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla
Ref<RectangleShape2D> shape = node->get_shape();
handles.resize(3);
- Vector2 ext = shape->get_extents();
+ Vector2 ext = shape->get_size() / 2;
handles.write[0] = Point2(ext.x, 0);
handles.write[1] = Point2(0, ext.y);
handles.write[2] = Point2(ext.x, ext.y);
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h
index 083ceb4b38..054db1a61b 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.h
+++ b/editor/plugins/collision_shape_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index 32f7d02af2..3403aeceba 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.h b/editor/plugins/cpu_particles_2d_editor_plugin.h
index 58984d6d16..b188df8e96 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
index d44e487ae4..f41ccfa86b 100644
--- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -122,7 +122,7 @@ void CPUParticles3DEditorPlugin::make_visible(bool p_visible) {
CPUParticles3DEditorPlugin::CPUParticles3DEditorPlugin(EditorNode *p_node) {
editor = p_node;
particles_editor = memnew(CPUParticles3DEditor);
- editor->get_viewport()->add_child(particles_editor);
+ editor->get_main_control()->add_child(particles_editor);
particles_editor->hide();
}
diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.h b/editor/plugins/cpu_particles_3d_editor_plugin.h
index d6886a24dc..9dced3ea86 100644
--- a/editor/plugins/cpu_particles_3d_editor_plugin.h
+++ b/editor/plugins/cpu_particles_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 4768cac217..bff5cb8d2a 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -353,8 +353,8 @@ void CurveEditor::open_context_menu(Vector2 pos) {
_context_menu->add_check_item(TTR("Linear"), CONTEXT_LINEAR);
bool is_linear = _selected_tangent == TANGENT_LEFT ?
- _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR :
- _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR;
+ _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR :
+ _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR;
_context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_LINEAR), is_linear);
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
index 2872f65730..2e8dd43d7e 100644
--- a/editor/plugins/curve_editor_plugin.h
+++ b/editor/plugins/curve_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp
index 0747e42045..1512e1817a 100644
--- a/editor/plugins/debugger_editor_plugin.cpp
+++ b/editor/plugins/debugger_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/debugger_editor_plugin.h b/editor/plugins/debugger_editor_plugin.h
index c5ae4cd8a9..a6fab01c29 100644
--- a/editor/plugins/debugger_editor_plugin.h
+++ b/editor/plugins/debugger_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/editor_debugger_plugin.cpp b/editor/plugins/editor_debugger_plugin.cpp
index b775e871e2..85114d88ae 100644
--- a/editor/plugins/editor_debugger_plugin.cpp
+++ b/editor/plugins/editor_debugger_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/editor_debugger_plugin.h b/editor/plugins/editor_debugger_plugin.h
index 10fd1151de..b33a8ed925 100644
--- a/editor/plugins/editor_debugger_plugin.h
+++ b/editor/plugins/editor_debugger_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 2fc0e35f82..eb3c06fba1 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -106,7 +106,7 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const RES &p_from, const Siz
}
}
- if (img.is_null() || img->empty()) {
+ if (img.is_null() || img->is_empty()) {
return Ref<Texture2D>();
}
@@ -150,7 +150,7 @@ bool EditorImagePreviewPlugin::handles(const String &p_type) const {
Ref<Texture2D> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
Ref<Image> img = p_from;
- if (img.is_null() || img->empty()) {
+ if (img.is_null() || img->is_empty()) {
return Ref<Image>();
}
@@ -301,7 +301,7 @@ EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() {
//////////////////////////////////////////////////////////////////
void EditorMaterialPreviewPlugin::_preview_done(const Variant &p_udata) {
- preview_done = true;
+ preview_done.set();
}
void EditorMaterialPreviewPlugin::_bind_methods() {
@@ -325,10 +325,10 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Si
RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
- preview_done = false;
+ preview_done.clear();
RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMaterialPreviewPlugin *>(this), "_preview_done", Variant());
- while (!preview_done) {
+ while (!preview_done.is_set()) {
OS::get_singleton()->delay_usec(10);
}
@@ -382,7 +382,9 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
int lats = 32;
int lons = 32;
- float radius = 1.0;
+ const double lat_step = Math_TAU / lats;
+ const double lon_step = Math_TAU / lons;
+ real_t radius = 1.0;
Vector<Vector3> vertices;
Vector<Vector3> normals;
@@ -391,20 +393,20 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
Basis tt = Basis(Vector3(0, 1, 0), Math_PI * 0.5);
for (int i = 1; i <= lats; i++) {
- double lat0 = Math_PI * (-0.5 + (double)(i - 1) / lats);
+ double lat0 = lat_step * (i - 1) - Math_TAU / 4;
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
- double lat1 = Math_PI * (-0.5 + (double)i / lats);
+ double lat1 = lat_step * i - Math_TAU / 4;
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
for (int j = lons; j >= 1; j--) {
- double lng0 = 2 * Math_PI * (double)(j - 1) / lons;
+ double lng0 = lon_step * (j - 1);
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
- double lng1 = 2 * Math_PI * (double)(j) / lons;
+ double lng1 = lon_step * j;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
@@ -675,7 +677,7 @@ EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
void EditorMeshPreviewPlugin::_preview_done(const Variant &p_udata) {
- preview_done = true;
+ preview_done.set();
}
void EditorMeshPreviewPlugin::_bind_methods() {
@@ -712,10 +714,10 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2
RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
- preview_done = false;
+ preview_done.clear();
RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorMeshPreviewPlugin *>(this), "_preview_done", Variant());
- while (!preview_done) {
+ while (!preview_done.is_set()) {
OS::get_singleton()->delay_usec(10);
}
@@ -790,7 +792,7 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
void EditorFontPreviewPlugin::_preview_done(const Variant &p_udata) {
- preview_done = true;
+ preview_done.set();
}
void EditorFontPreviewPlugin::_bind_methods() {
@@ -881,11 +883,11 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path,
font->draw_string(canvas_item, pos, sample, HALIGN_LEFT, -1.f, 50, Color(1, 1, 1));
- preview_done = false;
+ preview_done.clear();
RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
RS::get_singleton()->request_frame_drawn_callback(const_cast<EditorFontPreviewPlugin *>(this), "_preview_done", Variant());
- while (!preview_done) {
+ while (!preview_done.is_set()) {
OS::get_singleton()->delay_usec(10);
}
diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h
index 04e6be2354..6e8b9a34cf 100644
--- a/editor/plugins/editor_preview_plugins.h
+++ b/editor/plugins/editor_preview_plugins.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,8 @@
#include "editor/editor_resource_preview.h"
+#include "core/templates/safe_refcount.h"
+
void post_process_preview(Ref<Image> p_image);
class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator {
@@ -90,7 +92,7 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator {
RID light2;
RID light_instance2;
RID camera;
- mutable volatile bool preview_done = false;
+ mutable SafeFlag preview_done;
void _preview_done(const Variant &p_udata);
@@ -134,7 +136,7 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator {
RID light2;
RID light_instance2;
RID camera;
- mutable volatile bool preview_done = false;
+ mutable SafeFlag preview_done;
void _preview_done(const Variant &p_udata);
@@ -156,7 +158,7 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator {
RID viewport_texture;
RID canvas;
RID canvas_item;
- mutable volatile bool preview_done = false;
+ mutable SafeFlag preview_done;
void _preview_done(const Variant &p_udata);
diff --git a/editor/plugins/font_editor_plugin.cpp b/editor/plugins/font_editor_plugin.cpp
index a82547182c..fa58eb5480 100644
--- a/editor/plugins/font_editor_plugin.cpp
+++ b/editor/plugins/font_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -216,7 +216,7 @@ void FontDataEditor::init_script_edit() {
void FontDataEditor::add_lang() {
FontData *fd = Object::cast_to<FontData>(get_edited_object());
- if (fd != nullptr && !le->get_text().empty()) {
+ if (fd != nullptr && !le->get_text().is_empty()) {
fd->set_language_support_override(le->get_text(), chk->is_pressed());
le->set_text("");
chk->set_pressed(false);
diff --git a/editor/plugins/font_editor_plugin.h b/editor/plugins/font_editor_plugin.h
index 1d3ffc8857..04e6c1dac7 100644
--- a/editor/plugins/font_editor_plugin.h
+++ b/editor/plugins/font_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp
index 2f5dd36ef1..f309c5da01 100644
--- a/editor/plugins/gi_probe_editor_plugin.cpp
+++ b/editor/plugins/gi_probe_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/gi_probe_editor_plugin.h
index 85d2b6f449..fdf0623561 100644
--- a/editor/plugins/gi_probe_editor_plugin.h
+++ b/editor/plugins/gi_probe_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index d27df1d063..b447304a3f 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -81,7 +81,7 @@ void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) {
cpu_particles->set_name(particles->get_name());
cpu_particles->set_transform(particles->get_transform());
cpu_particles->set_visible(particles->is_visible());
- cpu_particles->set_pause_mode(particles->get_pause_mode());
+ cpu_particles->set_process_mode(particles->get_process_mode());
cpu_particles->set_z_index(particles->get_z_index());
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.h b/editor/plugins/gpu_particles_2d_editor_plugin.h
index f3ca20b71a..0b2028b745 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
index 0de52b3930..433a5ae51c 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -263,7 +263,7 @@ void GPUParticles3DEditor::_menu_option(int p_option) {
cpu_particles->set_name(node->get_name());
cpu_particles->set_transform(node->get_transform());
cpu_particles->set_visible(node->is_visible());
- cpu_particles->set_pause_mode(node->get_pause_mode());
+ cpu_particles->set_process_mode(node->get_process_mode());
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Convert to CPUParticles3D"));
@@ -454,7 +454,7 @@ void GPUParticles3DEditorPlugin::make_visible(bool p_visible) {
GPUParticles3DEditorPlugin::GPUParticles3DEditorPlugin(EditorNode *p_node) {
editor = p_node;
particles_editor = memnew(GPUParticles3DEditor);
- editor->get_viewport()->add_child(particles_editor);
+ editor->get_main_control()->add_child(particles_editor);
particles_editor->hide();
}
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.h b/editor/plugins/gpu_particles_3d_editor_plugin.h
index ce376e4386..bd10895459 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
index 0288645f91..8c4928b7cb 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
index 0cdc70a62b..5a71fc44ef 100644
--- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
+++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp
index 13b5c8cef5..46fa00f730 100644
--- a/editor/plugins/gradient_editor_plugin.cpp
+++ b/editor/plugins/gradient_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h
index 4d3fc0d8a9..bcbb86e422 100644
--- a/editor/plugins/gradient_editor_plugin.h
+++ b/editor/plugins/gradient_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp
index b4dcbdfe20..1ea6630622 100644
--- a/editor/plugins/item_list_editor_plugin.cpp
+++ b/editor/plugins/item_list_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -145,7 +145,7 @@ int ItemListOptionButtonPlugin::get_flags() const {
void ItemListOptionButtonPlugin::add_item() {
ob->add_item(vformat(TTR("Item %d"), ob->get_item_count()));
- _change_notify();
+ notify_property_list_changed();
}
int ItemListOptionButtonPlugin::get_item_count() const {
@@ -154,7 +154,7 @@ int ItemListOptionButtonPlugin::get_item_count() const {
void ItemListOptionButtonPlugin::erase(int p_idx) {
ob->remove_item(p_idx);
- _change_notify();
+ notify_property_list_changed();
}
ItemListOptionButtonPlugin::ItemListOptionButtonPlugin() {
@@ -181,7 +181,7 @@ int ItemListPopupMenuPlugin::get_flags() const {
void ItemListPopupMenuPlugin::add_item() {
pp->add_item(vformat(TTR("Item %d"), pp->get_item_count()));
- _change_notify();
+ notify_property_list_changed();
}
int ItemListPopupMenuPlugin::get_item_count() const {
@@ -190,7 +190,7 @@ int ItemListPopupMenuPlugin::get_item_count() const {
void ItemListPopupMenuPlugin::erase(int p_idx) {
pp->remove_item(p_idx);
- _change_notify();
+ notify_property_list_changed();
}
ItemListPopupMenuPlugin::ItemListPopupMenuPlugin() {
@@ -213,7 +213,7 @@ int ItemListItemListPlugin::get_flags() const {
void ItemListItemListPlugin::add_item() {
pp->add_item(vformat(TTR("Item %d"), pp->get_item_count()));
- _change_notify();
+ notify_property_list_changed();
}
int ItemListItemListPlugin::get_item_count() const {
@@ -222,7 +222,7 @@ int ItemListItemListPlugin::get_item_count() const {
void ItemListItemListPlugin::erase(int p_idx) {
pp->remove_item(p_idx);
- _change_notify();
+ notify_property_list_changed();
}
ItemListItemListPlugin::ItemListItemListPlugin() {
diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h
index fa5e802869..8c77f3d952 100644
--- a/editor/plugins/item_list_editor_plugin.h
+++ b/editor/plugins/item_list_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index e422140efa..3d555d7eba 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index e034a41ddc..eb1ce04788 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp
index 77eeb19d26..08c5ef02a4 100644
--- a/editor/plugins/line_2d_editor_plugin.cpp
+++ b/editor/plugins/line_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h
index b3bc9df3a5..769109583a 100644
--- a/editor/plugins/line_2d_editor_plugin.h
+++ b/editor/plugins/line_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index e45344b427..ad99ad7808 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index 570ba9ae03..a4532b58b3 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 79dbf7d522..1e4553a967 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h
index 1fb0babb10..455fcb5fe9 100644
--- a/editor/plugins/mesh_editor_plugin.h
+++ b/editor/plugins/mesh_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index 2a08e3a8b5..0d2b2ea2f5 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,7 +63,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.empty()) {
+ if (selection.is_empty()) {
Ref<Shape3D> shape = mesh->create_trimesh_shape();
if (shape.is_null()) {
err_dialog->set_text(TTR("Couldn't create a Trimesh collision shape."));
@@ -505,7 +505,7 @@ void MeshInstance3DEditorPlugin::make_visible(bool p_visible) {
MeshInstance3DEditorPlugin::MeshInstance3DEditorPlugin(EditorNode *p_node) {
editor = p_node;
mesh_editor = memnew(MeshInstance3DEditor);
- editor->get_viewport()->add_child(mesh_editor);
+ editor->get_main_control()->add_child(mesh_editor);
mesh_editor->options->hide();
}
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h
index f42136942b..69f494de7f 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.h
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index fb34f4064a..f8932cd534 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -297,7 +297,7 @@ MeshLibraryEditorPlugin::MeshLibraryEditorPlugin(EditorNode *p_node) {
EDITOR_DEF("editors/grid_map/preview_size", 64);
mesh_library_editor = memnew(MeshLibraryEditor(p_node));
- p_node->get_viewport()->add_child(mesh_library_editor);
+ p_node->get_main_control()->add_child(mesh_library_editor);
mesh_library_editor->set_anchors_and_offsets_preset(Control::PRESET_TOP_WIDE);
mesh_library_editor->set_end(Point2(0, 22));
mesh_library_editor->hide();
diff --git a/editor/plugins/mesh_library_editor_plugin.h b/editor/plugins/mesh_library_editor_plugin.h
index fafbce9243..6c33c8bb9e 100644
--- a/editor/plugins/mesh_library_editor_plugin.h
+++ b/editor/plugins/mesh_library_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index 59ab622994..19c6dcf402 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -378,7 +378,7 @@ void MultiMeshEditorPlugin::make_visible(bool p_visible) {
MultiMeshEditorPlugin::MultiMeshEditorPlugin(EditorNode *p_node) {
editor = p_node;
multimesh_editor = memnew(MultiMeshEditor);
- editor->get_viewport()->add_child(multimesh_editor);
+ editor->get_main_control()->add_child(multimesh_editor);
multimesh_editor->options->hide();
}
diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h
index 6a80fd4d16..2cdd7cf504 100644
--- a/editor/plugins/multimesh_editor_plugin.h
+++ b/editor/plugins/multimesh_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp
index 8cf9f01fa0..9971d3111d 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.cpp
+++ b/editor/plugins/navigation_polygon_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h
index 3c5a7c2829..0f5928d416 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.h
+++ b/editor/plugins/navigation_polygon_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 610645eb9e..9643881f96 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,6 +48,7 @@
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/3d/visual_instance_3d.h"
+#include "scene/gui/center_container.h"
#include "scene/gui/subviewport_container.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/surface_tool.h"
@@ -535,8 +536,8 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b
if (dist < closest_dist) {
item = Object::cast_to<Node>(spat);
- while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) {
- item = item->get_owner();
+ if (item != edited_scene) {
+ item = edited_scene->get_deepest_editable_node(item);
}
closest = item->get_instance_id();
@@ -612,7 +613,7 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_inclu
results.push_back(res);
}
- if (results.empty()) {
+ if (results.is_empty()) {
return;
}
@@ -697,8 +698,8 @@ void Node3DEditorViewport::_select_region() {
}
Node *item = Object::cast_to<Node>(sp);
- while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) {
- item = item->get_owner();
+ if (item != edited_scene) {
+ item = edited_scene->get_deepest_editable_node(item);
}
// Replace the node by the group if grouped
@@ -1027,7 +1028,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
for (int i = 0; i < selection_results.size(); i++) {
Node3D *item = selection_results[i].item;
- if (item != scene && item->get_owner() != scene && !scene->is_editable_instance(item->get_owner())) {
+ if (item != scene && item->get_owner() != scene && item != scene->get_deepest_editable_node(item)) {
//invalid result
selection_results.remove(i);
i--;
@@ -1045,7 +1046,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
clicked = ObjectID();
}
- } else if (!selection_results.empty()) {
+ } else if (!selection_results.is_empty()) {
NodePath root_path = get_tree()->get_edited_scene_root()->get_path();
StringName root_name = root_path.get_name(root_path.get_name_count() - 1);
@@ -1097,7 +1098,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
{
EditorNode *en = editor;
EditorPluginList *force_input_forwarding_list = en->get_editor_plugins_force_input_forwarding();
- if (!force_input_forwarding_list->empty()) {
+ if (!force_input_forwarding_list->is_empty()) {
bool discard = force_input_forwarding_list->forward_spatial_gui_input(camera, p_event, true);
if (discard) {
return;
@@ -1107,7 +1108,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
{
EditorNode *en = editor;
EditorPluginList *over_plugin_list = en->get_editor_plugins_over();
- if (!over_plugin_list->empty()) {
+ if (!over_plugin_list->is_empty()) {
bool discard = over_plugin_list->forward_spatial_gui_input(camera, p_event, false);
if (discard) {
return;
@@ -2210,8 +2211,8 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) {
}
void Node3DEditorViewport::scale_cursor_distance(real_t scale) {
- real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
- real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX);
+ real_t min_distance = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN);
+ real_t max_distance = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX);
if (unlikely(min_distance > max_distance)) {
cursor.distance = (min_distance + max_distance) / 2;
} else {
@@ -2223,8 +2224,8 @@ void Node3DEditorViewport::scale_cursor_distance(real_t scale) {
}
void Node3DEditorViewport::scale_freelook_speed(real_t scale) {
- real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
- real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX);
+ real_t min_speed = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN);
+ real_t max_speed = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX);
if (unlikely(min_speed > max_speed)) {
freelook_speed = (min_speed + max_speed) / 2;
} else {
@@ -2335,7 +2336,43 @@ void Node3DEditorPlugin::edited_scene_changed() {
}
}
+void Node3DEditorViewport::_project_settings_changed() {
+ //update shadow atlas if changed
+ int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/size");
+ bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/16_bits");
+ int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_0_subdiv");
+ int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_1_subdiv");
+ int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_2_subdiv");
+ int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/shadows/shadow_atlas/quadrant_3_subdiv");
+
+ viewport->set_shadow_atlas_size(shadowmap_size);
+ viewport->set_shadow_atlas_16_bits(shadowmap_16_bits);
+ viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
+ viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
+ viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
+ viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
+
+ bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION));
+
+ if (shrink != (subviewport_container->get_stretch_shrink() > 1)) {
+ subviewport_container->set_stretch_shrink(shrink ? 2 : 1);
+ }
+
+ // Update MSAA, screen-space AA and debanding if changed
+
+ const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/anti_aliasing/quality/msaa");
+ viewport->set_msaa(Viewport::MSAA(msaa_mode));
+ const int ssaa_mode = GLOBAL_GET("rendering/anti_aliasing/quality/screen_space_aa");
+ viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));
+ const bool use_debanding = GLOBAL_GET("rendering/anti_aliasing/quality/use_debanding");
+ viewport->set_use_debanding(use_debanding);
+}
+
void Node3DEditorViewport::_notification(int p_what) {
+ if (p_what == NOTIFICATION_READY) {
+ EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &Node3DEditorViewport::_project_settings_changed));
+ }
+
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
bool visible = is_visible_in_tree();
@@ -2442,35 +2479,6 @@ void Node3DEditorViewport::_notification(int p_what) {
}
}
- //update shadow atlas if changed
-
- int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size");
- int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv");
- int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv");
- int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv");
- int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv");
-
- viewport->set_shadow_atlas_size(shadowmap_size);
- viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
- viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
- viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
- viewport->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
-
- bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION));
-
- if (shrink != (subviewport_container->get_stretch_shrink() > 1)) {
- subviewport_container->set_stretch_shrink(shrink ? 2 : 1);
- }
-
- // Update MSAA, screen-space AA and debanding if changed
-
- const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa");
- viewport->set_msaa(Viewport::MSAA(msaa_mode));
- const int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa");
- viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));
- const bool use_debanding = GLOBAL_GET("rendering/quality/screen_filters/use_debanding");
- viewport->set_use_debanding(use_debanding);
-
bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
if (show_info != info_label->is_visible()) {
info_label->set_visible(show_info);
@@ -2491,6 +2499,13 @@ void Node3DEditorViewport::_notification(int p_what) {
text += "Z: " + rtos(current_camera->get_translation().z).pad_decimals(1) + "\n";
text += TTR("Pitch") + ": " + itos(Math::round(current_camera->get_rotation_degrees().x)) + "\n";
text += TTR("Yaw") + ": " + itos(Math::round(current_camera->get_rotation_degrees().y)) + "\n\n";
+
+ text += TTR("Size") +
+ vformat(
+ ": %dx%d (%.1fMP)\n",
+ viewport->get_size().x,
+ viewport->get_size().y,
+ viewport->get_size().x * viewport->get_size().y * 0.000'001);
text += TTR("Objects Drawn") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_OBJECTS_IN_FRAME)) + "\n";
text += TTR("Material Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_MATERIAL_CHANGES_IN_FRAME)) + "\n";
text += TTR("Shader Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SHADER_CHANGES_IN_FRAME)) + "\n";
@@ -2505,6 +2520,8 @@ void Node3DEditorViewport::_notification(int p_what) {
bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
if (show_fps != fps_label->is_visible()) {
+ cpu_time_label->set_visible(show_fps);
+ gpu_time_label->set_visible(show_fps);
fps_label->set_visible(show_fps);
RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps);
for (int i = 0; i < FRAME_TIME_HISTORY; i++) {
@@ -2531,12 +2548,28 @@ void Node3DEditorViewport::_notification(int p_what) {
}
gpu_time /= FRAME_TIME_HISTORY;
- String text;
- text += TTR("CPU Time") + ": " + String::num(cpu_time, 1) + " ms\n";
- text += TTR("GPU Time") + ": " + String::num(gpu_time, 1) + " ms\n";
- text += TTR("FPS") + ": " + itos(1000.0 / gpu_time);
-
- fps_label->set_text(text);
+ // Color labels depending on performance level ("good" = green, "OK" = yellow, "bad" = red).
+ // Middle point is at 15 ms.
+ cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), String::num(cpu_time, 1)));
+ cpu_time_label->add_theme_color_override(
+ "font_color",
+ frame_time_gradient->get_color_at_offset(
+ Math::range_lerp(cpu_time, 0, 30, 0, 1)));
+
+ gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), String::num(gpu_time, 1)));
+ // Middle point is at 15 ms.
+ gpu_time_label->add_theme_color_override(
+ "font_color",
+ frame_time_gradient->get_color_at_offset(
+ Math::range_lerp(gpu_time, 0, 30, 0, 1)));
+
+ const float fps = 1000.0 / gpu_time;
+ fps_label->set_text(vformat(TTR("FPS: %d"), fps));
+ // Middle point is at 60 FPS.
+ fps_label->add_theme_color_override(
+ "font_color",
+ frame_time_gradient->get_color_at_offset(
+ Math::range_lerp(fps, 110, 10, 0, 1)));
}
bool show_cinema = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
@@ -2583,7 +2616,13 @@ void Node3DEditorViewport::_notification(int p_what) {
preview_camera->add_theme_style_override("focus", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles"));
preview_camera->add_theme_style_override("disabled", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles"));
+ frame_time_gradient->set_color(0, get_theme_color("success_color", "Editor"));
+ frame_time_gradient->set_color(1, get_theme_color("warning_color", "Editor"));
+ frame_time_gradient->set_color(2, get_theme_color("error_color", "Editor"));
+
info_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles"));
+ cpu_time_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles"));
+ gpu_time_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles"));
fps_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles"));
cinema_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles"));
locked_label->add_theme_style_override("normal", editor->get_gui_base()->get_theme_stylebox("Information3dViewport", "EditorStyles"));
@@ -2615,12 +2654,12 @@ static void draw_indicator_bar(Control &surface, real_t fill, const Ref<Texture2
void Node3DEditorViewport::_draw() {
EditorPluginList *over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_over();
- if (!over_plugin_list->empty()) {
+ if (!over_plugin_list->is_empty()) {
over_plugin_list->forward_spatial_draw_over_viewport(surface);
}
EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over();
- if (!force_over_plugin_list->empty()) {
+ if (!force_over_plugin_list->is_empty()) {
force_over_plugin_list->forward_spatial_force_draw_over_viewport(surface);
}
@@ -2674,7 +2713,8 @@ void Node3DEditorViewport::_draw() {
break;
}
handle_color.a = 1.0;
- handle_color *= Color(1.3, 1.3, 1.3, 1.0);
+ const float brightness = 1.3;
+ handle_color *= Color(brightness, brightness, brightness);
RenderingServer::get_singleton()->canvas_item_add_line(
ci,
@@ -2714,8 +2754,8 @@ void Node3DEditorViewport::_draw() {
if (is_freelook_active()) {
// Show speed
- real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
- real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX);
+ real_t min_speed = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN);
+ real_t max_speed = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX);
real_t scale_length = (max_speed - min_speed);
if (!Math::is_zero_approx(scale_length)) {
@@ -2735,8 +2775,8 @@ void Node3DEditorViewport::_draw() {
} else {
// Show zoom
- real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
- real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX);
+ real_t min_distance = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN);
+ real_t max_distance = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX);
real_t scale_length = (max_distance - min_distance);
if (!Math::is_zero_approx(scale_length)) {
@@ -2797,7 +2837,7 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_FRONT: {
cursor.x_rot = 0;
- cursor.y_rot = 0;
+ cursor.y_rot = Math_PI;
set_message(TTR("Front View."), 2);
name = TTR("Front");
_set_auto_orthogonal();
@@ -2806,7 +2846,7 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_REAR: {
cursor.x_rot = 0;
- cursor.y_rot = Math_PI;
+ cursor.y_rot = 0;
set_message(TTR("Rear View."), 2);
name = TTR("Rear");
_set_auto_orthogonal();
@@ -3018,7 +3058,11 @@ void Node3DEditorViewport::_menu_option(int p_option) {
case VIEW_DISPLAY_DEBUG_SDFGI:
case VIEW_DISPLAY_DEBUG_SDFGI_PROBES:
case VIEW_DISPLAY_DEBUG_GI_BUFFER:
- case VIEW_DISPLAY_DEBUG_DISABLE_LOD: {
+ case VIEW_DISPLAY_DEBUG_DISABLE_LOD:
+ case VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS:
+ case VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS:
+ case VIEW_DISPLAY_DEBUG_CLUSTER_DECALS:
+ case VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES: {
static const int display_options[] = {
VIEW_DISPLAY_NORMAL,
VIEW_DISPLAY_WIREFRAME,
@@ -3040,6 +3084,10 @@ void Node3DEditorViewport::_menu_option(int p_option) {
VIEW_DISPLAY_DEBUG_DECAL_ATLAS,
VIEW_DISPLAY_DEBUG_SDFGI,
VIEW_DISPLAY_DEBUG_SDFGI_PROBES,
+ VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS,
+ VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS,
+ VIEW_DISPLAY_DEBUG_CLUSTER_DECALS,
+ VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES,
VIEW_MAX
};
static const Viewport::DebugDraw debug_draw_modes[] = {
@@ -3063,6 +3111,10 @@ void Node3DEditorViewport::_menu_option(int p_option) {
Viewport::DEBUG_DRAW_DECAL_ATLAS,
Viewport::DEBUG_DRAW_SDFGI,
Viewport::DEBUG_DRAW_SDFGI_PROBES,
+ Viewport::DEBUG_DRAW_CLUSTER_OMNI_LIGHTS,
+ Viewport::DEBUG_DRAW_CLUSTER_SPOT_LIGHTS,
+ Viewport::DEBUG_DRAW_CLUSTER_DECALS,
+ Viewport::DEBUG_DRAW_CLUSTER_REFLECTION_PROBES,
};
int idx = 0;
@@ -3190,6 +3242,8 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) {
void Node3DEditorViewport::_toggle_cinema_preview(bool p_activate) {
previewing_cinema = p_activate;
+ rotation_control->set_visible(!p_activate);
+
if (!previewing_cinema) {
if (previewing != nullptr) {
previewing->disconnect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
@@ -3280,6 +3334,21 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
xform.basis.scale(scale);
+ // if the determinant is zero, we should disable the gizmo from being rendered
+ // this prevents supplying bad values to the renderer and then having to filter it out again
+ if (xform.basis.determinant() == 0) {
+ for (int i = 0; i < 3; i++) {
+ RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], false);
+ RenderingServer::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], false);
+ RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], false);
+ RenderingServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false);
+ RenderingServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false);
+ }
+ // Rotation white outline
+ RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], false);
+ return;
+ }
+
for (int i = 0; i < 3; i++) {
RenderingServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform);
RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE));
@@ -3964,6 +4033,12 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
display_submenu->add_radio_check_item(TTR("GI Buffer"), VIEW_DISPLAY_DEBUG_GI_BUFFER);
display_submenu->add_separator();
display_submenu->add_radio_check_item(TTR("Disable LOD"), VIEW_DISPLAY_DEBUG_DISABLE_LOD);
+ display_submenu->add_separator();
+ display_submenu->add_radio_check_item(TTR("Omni Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS);
+ display_submenu->add_radio_check_item(TTR("Spot Light Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS);
+ display_submenu->add_radio_check_item(TTR("Decal Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_DECALS);
+ display_submenu->add_radio_check_item(TTR("Reflection Probe Cluster"), VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES);
+
display_submenu->set_name("display_advanced");
view_menu->get_popup()->add_submenu_item(TTR("Display Advanced..."), "display_advanced", VIEW_DISPLAY_ADVANCED);
view_menu->get_popup()->add_separator();
@@ -4042,16 +4117,6 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
surface->add_child(info_label);
info_label->hide();
- fps_label = memnew(Label);
- fps_label->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -90 * EDSCALE);
- fps_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
- fps_label->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, -10 * EDSCALE);
- fps_label->set_h_grow_direction(GROW_DIRECTION_BEGIN);
- fps_label->set_tooltip(TTR("Note: The FPS is estimated on a 60hz refresh rate."));
- fps_label->set_mouse_filter(MOUSE_FILTER_PASS); // Otherwise tooltip doesn't show.
- surface->add_child(fps_label);
- fps_label->hide();
-
cinema_label = memnew(Label);
cinema_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
cinema_label->set_h_grow_direction(GROW_DIRECTION_END);
@@ -4071,9 +4136,17 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
locked_label->set_text(TTR("View Rotation Locked"));
locked_label->hide();
+ frame_time_gradient = memnew(Gradient);
+ // The color is set when the theme changes.
+ frame_time_gradient->add_point(0.5, Color());
+
top_right_vbox = memnew(VBoxContainer);
top_right_vbox->set_anchors_and_offsets_preset(PRESET_TOP_RIGHT, PRESET_MODE_MINSIZE, 2.0 * EDSCALE);
top_right_vbox->set_h_grow_direction(GROW_DIRECTION_BEGIN);
+ // Make sure frame time labels don't touch the viewport's edge.
+ top_right_vbox->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
+ // Prevent visible spacing between frame time labels.
+ top_right_vbox->add_theme_constant_override("separation", 0);
rotation_control = memnew(ViewportRotationControl);
rotation_control->set_custom_minimum_size(Size2(80, 80) * EDSCALE);
@@ -4081,13 +4154,16 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
rotation_control->set_viewport(this);
top_right_vbox->add_child(rotation_control);
+ // Individual Labels are used to allow coloring each label with its own color.
+ cpu_time_label = memnew(Label);
+ top_right_vbox->add_child(cpu_time_label);
+ cpu_time_label->hide();
+
+ gpu_time_label = memnew(Label);
+ top_right_vbox->add_child(gpu_time_label);
+ gpu_time_label->hide();
+
fps_label = memnew(Label);
- fps_label->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -90 * EDSCALE);
- fps_label->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
- fps_label->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, -10 * EDSCALE);
- fps_label->set_h_grow_direction(GROW_DIRECTION_BEGIN);
- fps_label->set_tooltip(TTR("Note: The FPS value displayed is the editor's framerate.\nIt cannot be used as a reliable indication of in-game performance."));
- fps_label->set_mouse_filter(MOUSE_FILTER_PASS); // Otherwise tooltip doesn't show.
top_right_vbox->add_child(fps_label);
fps_label->hide();
@@ -4115,6 +4191,10 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Node3DEditorViewport::update_transform_gizmo_view));
}
+Node3DEditorViewport::~Node3DEditorViewport() {
+ memdelete(frame_time_gradient);
+}
+
//////////////////////////////////////////////////////////////
void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
@@ -4573,8 +4653,8 @@ void Node3DEditor::_generate_selection_boxes() {
Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D);
mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
- // Use a similar color to the 2D editor selection.
- mat->set_albedo(Color(1, 0.5, 0));
+ const Color selection_box_color = EDITOR_GET("editors/3d/selection_box_color");
+ mat->set_albedo(selection_box_color);
mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
st->set_material(mat);
selection_box = st->commit();
@@ -4582,7 +4662,7 @@ void Node3DEditor::_generate_selection_boxes() {
Ref<StandardMaterial3D> mat_xray = memnew(StandardMaterial3D);
mat_xray->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
mat_xray->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true);
- mat_xray->set_albedo(Color(1, 0.5, 0, 0.15));
+ mat_xray->set_albedo(selection_box_color * Color(1, 1, 1, 0.15));
mat_xray->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
st_xray->set_material(mat_xray);
selection_box_xray = st_xray->commit();
@@ -4633,11 +4713,33 @@ Dictionary Node3DEditor::get_state() const {
continue;
}
int state = gizmos_menu->get_item_state(gizmos_menu->get_item_index(i));
- String name = gizmo_plugins_by_name[i]->get_name();
+ String name = gizmo_plugins_by_name[i]->get_gizmo_name();
gizmos_status[name] = state;
}
d["gizmos_status"] = gizmos_status;
+ {
+ Dictionary pd;
+
+ pd["sun_rotation"] = sun_rotation;
+
+ pd["environ_sky_color"] = environ_sky_color->get_pick_color();
+ pd["environ_ground_color"] = environ_ground_color->get_pick_color();
+ pd["environ_energy"] = environ_energy->get_value();
+ pd["environ_glow_enabled"] = environ_glow_button->is_pressed();
+ pd["environ_tonemap_enabled"] = environ_tonemap_button->is_pressed();
+ pd["environ_ao_enabled"] = environ_ao_button->is_pressed();
+ pd["environ_gi_enabled"] = environ_gi_button->is_pressed();
+ pd["sun_max_distance"] = sun_max_distance->get_value();
+
+ pd["sun_color"] = sun_color->get_pick_color();
+ pd["sun_energy"] = sun_energy->get_value();
+
+ pd["sun_disabled"] = sun_button->is_pressed();
+ pd["environ_disabled"] = environ_button->is_pressed();
+
+ d["preview_sun_env"] = pd;
+ }
return d;
}
@@ -4737,7 +4839,7 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
}
int state = EditorNode3DGizmoPlugin::VISIBLE;
for (int i = 0; i < keys.size(); i++) {
- if (gizmo_plugins_by_name.write[j]->get_name() == String(keys[i])) {
+ if (gizmo_plugins_by_name.write[j]->get_gizmo_name() == String(keys[i])) {
state = gizmos_status[keys[i]];
break;
}
@@ -4747,6 +4849,38 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
}
_update_gizmos_menu();
}
+
+ if (d.has("preview_sun_env")) {
+ sun_environ_updating = true;
+ Dictionary pd = d["preview_sun_env"];
+ sun_rotation = pd["sun_rotation"];
+
+ environ_sky_color->set_pick_color(pd["environ_sky_color"]);
+ environ_ground_color->set_pick_color(pd["environ_ground_color"]);
+ environ_energy->set_value(pd["environ_energy"]);
+ environ_glow_button->set_pressed(pd["environ_glow_enabled"]);
+ environ_tonemap_button->set_pressed(pd["environ_tonemap_enabled"]);
+ environ_ao_button->set_pressed(pd["environ_ao_enabled"]);
+ environ_gi_button->set_pressed(pd["environ_gi_enabled"]);
+ sun_max_distance->set_value(pd["sun_max_distance"]);
+
+ sun_color->set_pick_color(pd["sun_color"]);
+ sun_energy->set_value(pd["sun_energy"]);
+
+ sun_button->set_pressed(pd["sun_disabled"]);
+ environ_button->set_pressed(pd["environ_disabled"]);
+
+ sun_environ_updating = false;
+
+ _preview_settings_changed();
+ _update_preview_environment();
+ } else {
+ _load_default_preview_settings();
+ sun_button->set_pressed(false);
+ environ_button->set_pressed(false);
+ _preview_settings_changed();
+ _update_preview_environment();
+ }
}
void Node3DEditor::edit(Node3D *p_spatial) {
@@ -5192,6 +5326,42 @@ void Node3DEditor::_init_indicators() {
origin_points.push_back(axis * -1048576);
}
+ Ref<Shader> grid_shader = memnew(Shader);
+ grid_shader->set_code(
+ "\n"
+ "shader_type spatial; \n"
+ "render_mode unshaded; \n"
+ "uniform bool orthogonal; \n"
+ "uniform float grid_size; \n"
+ "\n"
+ "void vertex() { \n"
+ " // From FLAG_SRGB_VERTEX_COLOR \n"
+ " if (!OUTPUT_IS_SRGB) { \n"
+ " COLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045))); \n"
+ " } \n"
+ "} \n"
+ "\n"
+ "void fragment() { \n"
+ " ALBEDO = COLOR.rgb; \n"
+ " vec3 dir = orthogonal ? -vec3(0, 0, 1) : VIEW; \n"
+ " float angle_fade = abs(dot(dir, NORMAL)); \n"
+ " angle_fade = smoothstep(0.05, 0.2, angle_fade); \n"
+ " \n"
+ " vec3 world_pos = (CAMERA_MATRIX * vec4(VERTEX, 1.0)).xyz; \n"
+ " vec3 world_normal = (CAMERA_MATRIX * vec4(NORMAL, 0.0)).xyz; \n"
+ " vec3 camera_world_pos = CAMERA_MATRIX[3].xyz; \n"
+ " vec3 camera_world_pos_on_plane = camera_world_pos * (1.0 - world_normal); \n"
+ " float dist_fade = 1.0 - (distance(world_pos, camera_world_pos_on_plane) / grid_size); \n"
+ " dist_fade = smoothstep(0.02, 0.3, dist_fade); \n"
+ " \n"
+ " ALPHA = COLOR.a * dist_fade * angle_fade; \n"
+ "}");
+
+ for (int i = 0; i < 3; i++) {
+ grid_mat[i].instance();
+ grid_mat[i]->set_shader(grid_shader);
+ }
+
grid_enable[0] = EditorSettings::get_singleton()->get("editors/3d/grid_xy_plane");
grid_enable[1] = EditorSettings::get_singleton()->get("editors/3d/grid_yz_plane");
grid_enable[2] = EditorSettings::get_singleton()->get("editors/3d/grid_xz_plane");
@@ -5252,7 +5422,9 @@ void Node3DEditor::_init_indicators() {
gizmo_color[i] = mat;
Ref<StandardMaterial3D> mat_hl = mat->duplicate();
- mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3, 1.0));
+ const float brightness = 1.3;
+ const Color albedo = Color(col.r * brightness, col.g * brightness, col.b * brightness);
+ mat_hl->set_albedo(albedo);
gizmo_color_hl[i] = mat_hl;
Vector3 ivec;
@@ -5282,9 +5454,10 @@ void Node3DEditor::_init_indicators() {
int arrow_sides = 16;
+ const real_t arrow_sides_step = Math_TAU / arrow_sides;
for (int k = 0; k < arrow_sides; k++) {
- Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides);
- Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides);
+ Basis ma(ivec, k * arrow_sides_step);
+ Basis mb(ivec, (k + 1) * arrow_sides_step);
for (int j = 0; j < arrow_points - 1; j++) {
Vector3 points[4] = {
@@ -5347,7 +5520,7 @@ void Node3DEditor::_init_indicators() {
surftool->commit(move_plane_gizmo[i]);
Ref<StandardMaterial3D> plane_mat_hl = plane_mat->duplicate();
- plane_mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3, 1.0));
+ plane_mat_hl->set_albedo(albedo);
plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides
}
@@ -5359,13 +5532,14 @@ void Node3DEditor::_init_indicators() {
int n = 128; // number of circle segments
int m = 6; // number of thickness segments
+ real_t step = Math_TAU / n;
for (int j = 0; j < n; ++j) {
- Basis basis = Basis(ivec, (Math_PI * 2.0f * j) / n);
+ Basis basis = Basis(ivec, j * step);
Vector3 vertex = basis.xform(ivec2 * GIZMO_CIRCLE_SIZE);
for (int k = 0; k < m; ++k) {
- Vector2 ofs = Vector2(Math::cos((Math_PI * 2.0 * k) / m), Math::sin((Math_PI * 2.0 * k) / m));
+ Vector2 ofs = Vector2(Math::cos((Math_TAU * k) / m), Math::sin((Math_TAU * k) / m));
Vector3 normal = ivec * ofs.x + ivec2 * ofs.y;
surftool->set_normal(basis.xform(normal));
@@ -5392,32 +5566,33 @@ void Node3DEditor::_init_indicators() {
Ref<Shader> rotate_shader = memnew(Shader);
- rotate_shader->set_code("\n"
- "shader_type spatial; \n"
- "render_mode unshaded, depth_test_disabled; \n"
- "uniform vec4 albedo; \n"
- "\n"
- "mat3 orthonormalize(mat3 m) { \n"
- " vec3 x = normalize(m[0]); \n"
- " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
- " vec3 z = m[2] - x * dot(x, m[2]); \n"
- " z = normalize(z - y * (dot(y,m[2]))); \n"
- " return mat3(x,y,z); \n"
- "} \n"
- "\n"
- "void vertex() { \n"
- " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
- " vec3 n = mv * VERTEX; \n"
- " float orientation = dot(vec3(0,0,-1),n); \n"
- " if (orientation <= 0.005) { \n"
- " VERTEX += NORMAL*0.02; \n"
- " } \n"
- "} \n"
- "\n"
- "void fragment() { \n"
- " ALBEDO = albedo.rgb; \n"
- " ALPHA = albedo.a; \n"
- "}");
+ rotate_shader->set_code(
+ "\n"
+ "shader_type spatial; \n"
+ "render_mode unshaded, depth_test_disabled; \n"
+ "uniform vec4 albedo; \n"
+ "\n"
+ "mat3 orthonormalize(mat3 m) { \n"
+ " vec3 x = normalize(m[0]); \n"
+ " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
+ " vec3 z = m[2] - x * dot(x, m[2]); \n"
+ " z = normalize(z - y * (dot(y,m[2]))); \n"
+ " return mat3(x,y,z); \n"
+ "} \n"
+ "\n"
+ "void vertex() { \n"
+ " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
+ " vec3 n = mv * VERTEX; \n"
+ " float orientation = dot(vec3(0,0,-1),n); \n"
+ " if (orientation <= 0.005) { \n"
+ " VERTEX += NORMAL*0.02; \n"
+ " } \n"
+ "} \n"
+ "\n"
+ "void fragment() { \n"
+ " ALBEDO = albedo.rgb; \n"
+ " ALPHA = albedo.a; \n"
+ "}");
Ref<ShaderMaterial> rotate_mat = memnew(ShaderMaterial);
rotate_mat->set_render_priority(Material::RENDER_PRIORITY_MAX);
@@ -5430,40 +5605,41 @@ void Node3DEditor::_init_indicators() {
rotate_gizmo[i]->surface_set_material(0, rotate_mat);
Ref<ShaderMaterial> rotate_mat_hl = rotate_mat->duplicate();
- rotate_mat_hl->set_shader_param("albedo", Color(col.r * 1.3, col.g * 1.3, col.b * 1.3, 1.0));
+ rotate_mat_hl->set_shader_param("albedo", albedo);
rotate_gizmo_color_hl[i] = rotate_mat_hl;
if (i == 2) { // Rotation white outline
Ref<ShaderMaterial> border_mat = rotate_mat->duplicate();
Ref<Shader> border_shader = memnew(Shader);
- border_shader->set_code("\n"
- "shader_type spatial; \n"
- "render_mode unshaded, depth_test_disabled; \n"
- "uniform vec4 albedo; \n"
- "\n"
- "mat3 orthonormalize(mat3 m) { \n"
- " vec3 x = normalize(m[0]); \n"
- " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
- " vec3 z = m[2] - x * dot(x, m[2]); \n"
- " z = normalize(z - y * (dot(y,m[2]))); \n"
- " return mat3(x,y,z); \n"
- "} \n"
- "\n"
- "void vertex() { \n"
- " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
- " mv = inverse(mv); \n"
- " VERTEX += NORMAL*0.008; \n"
- " vec3 camera_dir_local = mv * vec3(0,0,1); \n"
- " vec3 camera_up_local = mv * vec3(0,1,0); \n"
- " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n"
- " VERTEX = rotation_matrix * VERTEX; \n"
- "} \n"
- "\n"
- "void fragment() { \n"
- " ALBEDO = albedo.rgb; \n"
- " ALPHA = albedo.a; \n"
- "}");
+ border_shader->set_code(
+ "\n"
+ "shader_type spatial; \n"
+ "render_mode unshaded, depth_test_disabled; \n"
+ "uniform vec4 albedo; \n"
+ "\n"
+ "mat3 orthonormalize(mat3 m) { \n"
+ " vec3 x = normalize(m[0]); \n"
+ " vec3 y = normalize(m[1] - x * dot(x, m[1])); \n"
+ " vec3 z = m[2] - x * dot(x, m[2]); \n"
+ " z = normalize(z - y * (dot(y,m[2]))); \n"
+ " return mat3(x,y,z); \n"
+ "} \n"
+ "\n"
+ "void vertex() { \n"
+ " mat3 mv = orthonormalize(mat3(MODELVIEW_MATRIX)); \n"
+ " mv = inverse(mv); \n"
+ " VERTEX += NORMAL*0.008; \n"
+ " vec3 camera_dir_local = mv * vec3(0,0,1); \n"
+ " vec3 camera_up_local = mv * vec3(0,1,0); \n"
+ " mat3 rotation_matrix = mat3(cross(camera_dir_local, camera_up_local), camera_up_local, camera_dir_local); \n"
+ " VERTEX = rotation_matrix * VERTEX; \n"
+ "} \n"
+ "\n"
+ "void fragment() { \n"
+ " ALBEDO = albedo.rgb; \n"
+ " ALPHA = albedo.a; \n"
+ "}");
border_mat->set_shader(border_shader);
border_mat->set_shader_param("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0));
@@ -5492,9 +5668,10 @@ void Node3DEditor::_init_indicators() {
int arrow_sides = 4;
+ const real_t arrow_sides_step = Math_TAU / arrow_sides;
for (int k = 0; k < 4; k++) {
- Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides);
- Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides);
+ Basis ma(ivec, k * arrow_sides_step);
+ Basis mb(ivec, (k + 1) * arrow_sides_step);
for (int j = 0; j < arrow_points - 1; j++) {
Vector3 points[4] = {
@@ -5557,7 +5734,7 @@ void Node3DEditor::_init_indicators() {
surftool->commit(scale_plane_gizmo[i]);
Ref<StandardMaterial3D> plane_mat_hl = plane_mat->duplicate();
- plane_mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3, 1.0));
+ plane_mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3));
plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides
}
}
@@ -5573,7 +5750,7 @@ void Node3DEditor::_update_gizmos_menu() {
if (!gizmo_plugins_by_name[i]->can_be_hidden()) {
continue;
}
- String plugin_name = gizmo_plugins_by_name[i]->get_name();
+ String plugin_name = gizmo_plugins_by_name[i]->get_gizmo_name();
const int plugin_state = gizmo_plugins_by_name[i]->get_state();
gizmos_menu->add_multistate_item(plugin_name, 3, plugin_state, i);
const int idx = gizmos_menu->get_item_index(i);
@@ -5625,8 +5802,11 @@ void Node3DEditor::_init_grid() {
return; // Camera3D is invalid, don't draw the grid.
}
+ bool orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL;
+
Vector<Color> grid_colors[3];
Vector<Vector3> grid_points[3];
+ Vector<Vector3> grid_normals[3];
Color primary_grid_color = EditorSettings::get_singleton()->get("editors/3d/primary_grid_color");
Color secondary_grid_color = EditorSettings::get_singleton()->get("editors/3d/secondary_grid_color");
@@ -5662,10 +5842,26 @@ void Node3DEditor::_init_grid() {
int b = (a + 1) % 3;
int c = (a + 2) % 3;
- real_t division_level = Math::log(Math::abs(camera_position[c])) / Math::log((double)primary_grid_steps) + division_level_bias;
- division_level = CLAMP(division_level, division_level_min, division_level_max);
- real_t division_level_floored = Math::floor(division_level);
- real_t division_level_decimals = division_level - division_level_floored;
+ Vector3 normal;
+ normal[c] = 1.0;
+
+ real_t camera_distance = Math::abs(camera_position[c]);
+
+ if (orthogonal) {
+ camera_distance = camera->get_size() / 2.0;
+ Vector3 camera_direction = -camera->get_global_transform().get_basis().get_axis(2);
+ Plane grid_plane = Plane(Vector3(), normal);
+ Vector3 intersection;
+ if (grid_plane.intersects_ray(camera_position, camera_direction, &intersection)) {
+ camera_position = intersection;
+ }
+ }
+
+ real_t division_level = Math::log(Math::abs(camera_distance)) / Math::log((double)primary_grid_steps) + division_level_bias;
+
+ real_t clamped_division_level = CLAMP(division_level, division_level_min, division_level_max);
+ real_t division_level_floored = Math::floor(clamped_division_level);
+ real_t division_level_decimals = clamped_division_level - division_level_floored;
real_t small_step_size = Math::pow(primary_grid_steps, division_level_floored);
real_t large_step_size = small_step_size * primary_grid_steps;
@@ -5677,6 +5873,15 @@ void Node3DEditor::_init_grid() {
real_t bgn_b = center_b - grid_size * small_step_size;
real_t end_b = center_b + grid_size * small_step_size;
+ real_t fade_size = Math::pow(primary_grid_steps, division_level - 1.0);
+ real_t min_fade_size = Math::pow(primary_grid_steps, float(division_level_min));
+ real_t max_fade_size = Math::pow(primary_grid_steps, float(division_level_max));
+ fade_size = CLAMP(fade_size, min_fade_size, max_fade_size);
+
+ real_t grid_fade_size = (grid_size - primary_grid_steps) * fade_size;
+ grid_mat[c]->set_shader_param("grid_size", grid_fade_size);
+ grid_mat[c]->set_shader_param("orthogonal", orthogonal);
+
// In each iteration of this loop, draw one line in each direction (so two lines per loop, in each if statement).
for (int i = -grid_size; i <= grid_size; i++) {
Color line_color;
@@ -5687,11 +5892,6 @@ void Node3DEditor::_init_grid() {
line_color = secondary_grid_color;
line_color.a = line_color.a * (1 - division_level_decimals);
}
- // Makes lines farther from the center fade out.
- // Due to limitations of lines, any that come near the camera have full opacity always.
- // This should eventually be replaced by some kind of "distance fade" system, outside of this function.
- // But the effect is still somewhat convincing...
- line_color.a *= 1 - (1 - division_level_decimals * 0.9) * (Math::abs(i / (float)grid_size));
real_t position_a = center_a + i * small_step_size;
real_t position_b = center_b + i * small_step_size;
@@ -5708,6 +5908,8 @@ void Node3DEditor::_init_grid() {
grid_points[c].push_back(line_end);
grid_colors[c].push_back(line_color);
grid_colors[c].push_back(line_color);
+ grid_normals[c].push_back(normal);
+ grid_normals[c].push_back(normal);
}
if (!(origin_enabled && Math::is_zero_approx(position_b))) {
@@ -5721,6 +5923,8 @@ void Node3DEditor::_init_grid() {
grid_points[c].push_back(line_end);
grid_colors[c].push_back(line_color);
grid_colors[c].push_back(line_color);
+ grid_normals[c].push_back(normal);
+ grid_normals[c].push_back(normal);
}
}
@@ -5730,8 +5934,9 @@ void Node3DEditor::_init_grid() {
d.resize(RS::ARRAY_MAX);
d[RenderingServer::ARRAY_VERTEX] = grid_points[c];
d[RenderingServer::ARRAY_COLOR] = grid_colors[c];
+ d[RenderingServer::ARRAY_NORMAL] = grid_normals[c];
RenderingServer::get_singleton()->mesh_add_surface_from_arrays(grid[c], RenderingServer::PRIMITIVE_LINES, d);
- RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, indicator_mat->get_rid());
+ RenderingServer::get_singleton()->mesh_surface_set_material(grid[c], 0, grid_mat[c]->get_rid());
grid_instance[c] = RenderingServer::get_singleton()->instance_create2(grid[c], get_tree()->get_root()->get_world_3d()->get_scenario());
// Yes, the end of this line is supposed to be a.
@@ -5775,7 +5980,7 @@ void Node3DEditor::_refresh_menu_icons() {
List<Node *> &selection = editor_selection->get_selected_node_list();
- if (selection.empty()) {
+ if (selection.is_empty()) {
all_locked = false;
all_grouped = false;
} else {
@@ -5794,11 +5999,11 @@ void Node3DEditor::_refresh_menu_icons() {
}
tool_button[TOOL_LOCK_SELECTED]->set_visible(!all_locked);
- tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.empty());
+ tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.is_empty());
tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked);
tool_button[TOOL_GROUP_SELECTED]->set_visible(!all_grouped);
- tool_button[TOOL_GROUP_SELECTED]->set_disabled(selection.empty());
+ tool_button[TOOL_GROUP_SELECTED]->set_disabled(selection.is_empty());
tool_button[TOOL_UNGROUP_SELECTED]->set_visible(all_grouped);
}
@@ -5848,17 +6053,20 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
// Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin
Set<VisualInstance3D *> vi = _get_child_nodes<VisualInstance3D>(sp);
Set<CollisionShape3D *> cs = _get_child_nodes<CollisionShape3D>(sp);
+ bool found_valid_shape = false;
if (cs.size()) {
AABB aabb;
- bool found_valid_shape = false;
- if (cs.front()->get()->get_shape().is_valid()) {
- aabb = sp->get_global_transform().xform(cs.front()->get()->get_shape()->get_debug_mesh()->get_aabb());
+ Set<CollisionShape3D *>::Element *I = cs.front();
+ if (I->get()->get_shape().is_valid()) {
+ CollisionShape3D *collision_shape = cs.front()->get();
+ aabb = collision_shape->get_global_transform().xform(collision_shape->get_shape()->get_debug_mesh()->get_aabb());
found_valid_shape = true;
}
- for (Set<CollisionShape3D *>::Element *I = cs.front(); I; I = I->next()) {
- if (I->get()->get_shape().is_valid()) {
- aabb.merge_with(sp->get_global_transform().xform(I->get()->get_shape()->get_debug_mesh()->get_aabb()));
+ for (I = I->next(); I; I = I->next()) {
+ CollisionShape3D *col_shape = I->get();
+ if (col_shape->get_shape().is_valid()) {
+ aabb.merge_with(col_shape->get_global_transform().xform(col_shape->get_shape()->get_debug_mesh()->get_aabb()));
found_valid_shape = true;
}
}
@@ -5866,10 +6074,9 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5);
from = aabb.position + size;
position_offset.y = from.y - sp->get_global_transform().origin.y;
- } else {
- from = sp->get_global_transform().origin;
}
- } else if (vi.size()) {
+ }
+ if (!found_valid_shape && vi.size()) {
AABB aabb = vi.front()->get()->get_transformed_aabb();
for (Set<VisualInstance3D *>::Element *I = vi.front(); I; I = I->next()) {
aabb.merge_with(I->get()->get_transformed_aabb());
@@ -5877,7 +6084,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5);
from = aabb.position + size;
position_offset.y = from.y - sp->get_global_transform().origin.y;
- } else {
+ } else if (!found_valid_shape) {
from = sp->get_global_transform().origin;
}
@@ -5960,6 +6167,51 @@ void Node3DEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
}
+void Node3DEditor::_sun_environ_settings_pressed() {
+ Vector2 pos = sun_environ_settings->get_screen_position() + sun_environ_settings->get_size();
+ sun_environ_popup->set_position(pos - Vector2(sun_environ_popup->get_contents_minimum_size().width / 2, 0));
+ sun_environ_popup->popup();
+}
+
+void Node3DEditor::_add_sun_to_scene() {
+ sun_environ_popup->hide();
+
+ Node *base = get_tree()->get_edited_scene_root();
+ if (!base) {
+ EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation"));
+ return;
+ }
+ ERR_FAIL_COND(!base);
+ Node *new_sun = preview_sun->duplicate();
+
+ undo_redo->create_action("Add Preview Sun to Scene");
+ undo_redo->add_do_method(base, "add_child", new_sun);
+ undo_redo->add_do_method(new_sun, "set_owner", base);
+ undo_redo->add_undo_method(base, "remove_child", new_sun);
+ undo_redo->add_do_reference(new_sun);
+ undo_redo->commit_action();
+}
+void Node3DEditor::_add_environment_to_scene() {
+ sun_environ_popup->hide();
+
+ Node *base = get_tree()->get_edited_scene_root();
+ if (!base) {
+ EditorNode::get_singleton()->show_warning(TTR("A root node is needed for this operation"));
+ return;
+ }
+ ERR_FAIL_COND(!base);
+
+ WorldEnvironment *new_env = memnew(WorldEnvironment);
+ new_env->set_environment(preview_environment->get_environment()->duplicate(true));
+
+ undo_redo->create_action("Add Preview Environment to Scene");
+ undo_redo->add_do_method(base, "add_child", new_env);
+ undo_redo->add_do_method(new_env, "set_owner", base);
+ undo_redo->add_undo_method(base, "remove_child", new_env);
+ undo_redo->add_do_reference(new_env);
+ undo_redo->commit_action();
+}
+
void Node3DEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
tool_button[Node3DEditor::TOOL_MODE_SELECT]->set_icon(get_theme_icon("ToolSelect", "EditorIcons"));
@@ -5988,17 +6240,31 @@ void Node3DEditor::_notification(int p_what) {
_refresh_menu_icons();
get_tree()->connect("node_removed", callable_mp(this, &Node3DEditor::_node_removed));
+ get_tree()->connect("node_added", callable_mp(this, &Node3DEditor::_node_added));
EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons));
editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons));
editor->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false));
editor->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(true));
+
+ sun_button->set_icon(get_theme_icon("DirectionalLight3D", "EditorIcons"));
+ environ_button->set_icon(get_theme_icon("WorldEnvironment", "EditorIcons"));
+ sun_environ_settings->set_icon(get_theme_icon("GuiTabMenuHl", "EditorIcons"));
+
+ _update_preview_environment();
+ sun_title->add_theme_font_override("font", get_theme_font("title_font", "Window"));
+ environ_title->add_theme_font_override("font", get_theme_font("title_font", "Window"));
+
+ sun_state->set_custom_minimum_size(sun_vb->get_combined_minimum_size());
+ environ_state->set_custom_minimum_size(environ_vb->get_combined_minimum_size());
} else if (p_what == NOTIFICATION_ENTER_TREE) {
_register_all_gizmos();
_update_gizmos_menu();
_init_indicators();
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
_update_gizmos_menu_theme();
+ sun_title->add_theme_font_override("font", get_theme_font("title_font", "Window"));
+ environ_title->add_theme_font_override("font", get_theme_font("title_font", "Window"));
} else if (p_what == NOTIFICATION_EXIT_TREE) {
_finish_indicators();
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
@@ -6135,7 +6401,37 @@ void Node3DEditor::_toggle_maximize_view(Object *p_viewport) {
}
}
+void Node3DEditor::_node_added(Node *p_node) {
+ if (EditorNode::get_singleton()->get_scene_root()->is_a_parent_of(p_node)) {
+ if (Object::cast_to<WorldEnvironment>(p_node)) {
+ world_env_count++;
+ if (world_env_count == 1) {
+ _update_preview_environment();
+ }
+ } else if (Object::cast_to<DirectionalLight3D>(p_node)) {
+ directional_light_count++;
+ if (directional_light_count == 1) {
+ _update_preview_environment();
+ }
+ }
+ }
+}
+
void Node3DEditor::_node_removed(Node *p_node) {
+ if (EditorNode::get_singleton()->get_scene_root()->is_a_parent_of(p_node)) {
+ if (Object::cast_to<WorldEnvironment>(p_node)) {
+ world_env_count--;
+ if (world_env_count == 0) {
+ _update_preview_environment();
+ }
+ } else if (Object::cast_to<DirectionalLight3D>(p_node)) {
+ directional_light_count--;
+ if (directional_light_count == 0) {
+ _update_preview_environment();
+ }
+ }
+ }
+
if (p_node == selected) {
selected = nullptr;
}
@@ -6162,6 +6458,7 @@ void Node3DEditor::_register_all_gizmos() {
add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
add_gizmo_plugin(Ref<BakedLightmapGizmoPlugin>(memnew(BakedLightmapGizmoPlugin)));
add_gizmo_plugin(Ref<LightmapProbeGizmoPlugin>(memnew(LightmapProbeGizmoPlugin)));
+ add_gizmo_plugin(Ref<CollisionObject3DGizmoPlugin>(memnew(CollisionObject3DGizmoPlugin)));
add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin)));
add_gizmo_plugin(Ref<CollisionPolygon3DGizmoPlugin>(memnew(CollisionPolygon3DGizmoPlugin)));
add_gizmo_plugin(Ref<NavigationRegion3DGizmoPlugin>(memnew(NavigationRegion3DGizmoPlugin)));
@@ -6205,6 +6502,128 @@ void Node3DEditor::clear() {
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true);
}
+void Node3DEditor::_sun_direction_draw() {
+ sun_direction->draw_rect(Rect2(Vector2(), sun_direction->get_size()), Color(1, 1, 1, 1));
+ sun_direction_material->set_shader_param("sun_direction", -preview_sun->get_transform().basis.get_axis(Vector3::AXIS_Z));
+ float nrg = sun_energy->get_value();
+ sun_direction_material->set_shader_param("sun_color", Vector3(sun_color->get_pick_color().r * nrg, sun_color->get_pick_color().g * nrg, sun_color->get_pick_color().b * nrg));
+}
+
+void Node3DEditor::_preview_settings_changed() {
+ if (sun_environ_updating) {
+ return;
+ }
+
+ { // preview sun
+ Transform t;
+ t.basis = sun_rotation;
+ preview_sun->set_transform(t);
+ sun_direction->update();
+ preview_sun->set_param(Light3D::PARAM_ENERGY, sun_energy->get_value());
+ preview_sun->set_param(Light3D::PARAM_SHADOW_MAX_DISTANCE, sun_max_distance->get_value());
+ preview_sun->set_color(sun_color->get_pick_color());
+ }
+
+ { //preview env
+ sky_material->set_sky_energy(environ_energy->get_value());
+ Color hz_color = environ_sky_color->get_pick_color().lerp(environ_ground_color->get_pick_color(), 0.5).lerp(Color(1, 1, 1), 0.5);
+ sky_material->set_sky_top_color(environ_sky_color->get_pick_color());
+ sky_material->set_sky_horizon_color(hz_color);
+ sky_material->set_ground_bottom_color(environ_ground_color->get_pick_color());
+ sky_material->set_ground_horizon_color(hz_color);
+
+ environment->set_ssao_enabled(environ_ao_button->is_pressed());
+ environment->set_glow_enabled(environ_glow_button->is_pressed());
+ environment->set_sdfgi_enabled(environ_gi_button->is_pressed());
+ environment->set_tonemapper(environ_tonemap_button->is_pressed() ? Environment::TONE_MAPPER_FILMIC : Environment::TONE_MAPPER_LINEAR);
+ }
+}
+void Node3DEditor::_load_default_preview_settings() {
+ sun_environ_updating = true;
+
+ sun_rotation = Basis(Vector3(0, 1, 0), Math_PI * 3.0 / 4) * Basis(Vector3(1, 0, 0), -Math_PI / 4);
+
+ sun_direction->update();
+ environ_sky_color->set_pick_color(Color::hex(0x91b2ceff));
+ environ_ground_color->set_pick_color(Color::hex(0x1f1f21ff));
+ environ_energy->set_value(1.0);
+ environ_glow_button->set_pressed(true);
+ environ_tonemap_button->set_pressed(true);
+ environ_ao_button->set_pressed(false);
+ environ_gi_button->set_pressed(false);
+ sun_max_distance->set_value(250);
+
+ sun_color->set_pick_color(Color(1, 1, 1));
+ sun_energy->set_value(1.0);
+
+ sun_environ_updating = false;
+}
+
+void Node3DEditor::_update_preview_environment() {
+ bool disable_light = directional_light_count > 0 || sun_button->is_pressed();
+
+ sun_button->set_disabled(directional_light_count > 0);
+
+ if (disable_light) {
+ if (preview_sun->get_parent()) {
+ preview_sun->get_parent()->remove_child(preview_sun);
+ sun_state->show();
+ sun_vb->hide();
+ }
+
+ if (directional_light_count > 0) {
+ sun_state->set_text(TTR("Scene contains\nDirectionalLight3D.\nPreview disabled."));
+ } else {
+ sun_state->set_text(TTR("Preview disabled."));
+ }
+
+ } else {
+ if (!preview_sun->get_parent()) {
+ add_child(preview_sun);
+ sun_state->hide();
+ sun_vb->show();
+ }
+ }
+
+ bool disable_env = world_env_count > 0 || environ_button->is_pressed();
+
+ environ_button->set_disabled(world_env_count > 0);
+
+ if (disable_env) {
+ if (preview_environment->get_parent()) {
+ preview_environment->get_parent()->remove_child(preview_environment);
+ environ_state->show();
+ environ_vb->hide();
+ }
+ if (world_env_count > 0) {
+ environ_state->set_text(TTR("Scene contains\nWorldEnvironment.\nPreview disabled."));
+ } else {
+ environ_state->set_text(TTR("Preview disabled."));
+ }
+
+ } else {
+ if (!preview_environment->get_parent()) {
+ add_child(preview_environment);
+ environ_state->hide();
+ environ_vb->show();
+ }
+ }
+}
+
+void Node3DEditor::_sun_direction_input(const Ref<InputEvent> &p_event) {
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
+ float x = -mm->get_relative().y * 0.02 * EDSCALE;
+ float y = mm->get_relative().x * 0.02 * EDSCALE;
+
+ Basis rot = Basis(Vector3(0, 1, 0), y) * Basis(Vector3(1, 0, 0), x);
+
+ sun_rotation = rot * sun_rotation;
+ sun_rotation.orthonormalize();
+ _preview_settings_changed();
+ }
+}
+
Node3DEditor::Node3DEditor(EditorNode *p_editor) {
gizmo.visible = true;
gizmo.scale = 1.0;
@@ -6342,6 +6761,32 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
_update_camera_override_button(false);
hbc_menu->add_child(memnew(VSeparator));
+ sun_button = memnew(Button);
+ sun_button->set_tooltip(TTR("Toggle preview sunlight.\nIf a DirectionalLight3D node is added to the scene, preview sunlight is disabled."));
+ sun_button->set_toggle_mode(true);
+ sun_button->set_flat(true);
+ sun_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED);
+ sun_button->set_disabled(true);
+
+ hbc_menu->add_child(sun_button);
+
+ environ_button = memnew(Button);
+ environ_button->set_tooltip(TTR("Toggle preview environment.\nIf a WorldEnvironment node is added to the scene, preview environment is disabled."));
+ environ_button->set_toggle_mode(true);
+ environ_button->set_flat(true);
+ environ_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED);
+ environ_button->set_disabled(true);
+
+ hbc_menu->add_child(environ_button);
+
+ sun_environ_settings = memnew(Button);
+ sun_environ_settings->set_tooltip(TTR("Edit Sun and Environment settings."));
+ sun_environ_settings->set_flat(true);
+ sun_environ_settings->connect("pressed", callable_mp(this, &Node3DEditor::_sun_environ_settings_pressed));
+
+ hbc_menu->add_child(sun_environ_settings);
+
+ hbc_menu->add_child(memnew(VSeparator));
// Drag and drop support;
preview_node = memnew(Node3D);
@@ -6571,6 +7016,152 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
EDITOR_DEF("editors/3d/navigation/show_viewport_rotation_gizmo", true);
over_gizmo_handle = -1;
+ {
+ //sun popup
+
+ sun_environ_popup = memnew(PopupPanel);
+ add_child(sun_environ_popup);
+
+ HBoxContainer *sun_environ_hb = memnew(HBoxContainer);
+
+ sun_environ_popup->add_child(sun_environ_hb);
+
+ sun_vb = memnew(VBoxContainer);
+ sun_environ_hb->add_child(sun_vb);
+ sun_vb->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
+ sun_vb->hide();
+
+ sun_title = memnew(Label);
+ sun_vb->add_child(sun_title);
+ sun_title->set_text(TTR("Preview Sun"));
+ sun_title->set_align(Label::ALIGN_CENTER);
+
+ CenterContainer *sun_direction_center = memnew(CenterContainer);
+ sun_direction = memnew(Control);
+ sun_direction->set_custom_minimum_size(Size2i(128, 128) * EDSCALE);
+ sun_direction_center->add_child(sun_direction);
+ sun_vb->add_margin_child(TTR("Sun Direction"), sun_direction_center);
+ sun_direction->connect("gui_input", callable_mp(this, &Node3DEditor::_sun_direction_input));
+ sun_direction->connect("draw", callable_mp(this, &Node3DEditor::_sun_direction_draw));
+ sun_direction->set_default_cursor_shape(CURSOR_MOVE);
+
+ String sun_dir_shader_code = "shader_type canvas_item; uniform vec3 sun_direction; uniform vec3 sun_color; void fragment() { vec3 n; n.xy = UV * 2.0 - 1.0; n.z = sqrt(max(0.0, 1.0 - dot(n.xy, n.xy))); COLOR.rgb = dot(n,sun_direction) * sun_color; COLOR.a = 1.0 - smoothstep(0.99,1.0,length(n.xy)); }";
+ sun_direction_shader.instance();
+ sun_direction_shader->set_code(sun_dir_shader_code);
+ sun_direction_material.instance();
+ sun_direction_material->set_shader(sun_direction_shader);
+ sun_direction_material->set_shader_param("sun_direction", Vector3(0, 0, 1));
+ sun_direction_material->set_shader_param("sun_color", Vector3(1, 1, 1));
+ sun_direction->set_material(sun_direction_material);
+
+ sun_color = memnew(ColorPickerButton);
+ sun_color->set_edit_alpha(false);
+ sun_vb->add_margin_child(TTR("Sun Color"), sun_color);
+ sun_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
+
+ sun_energy = memnew(EditorSpinSlider);
+ sun_vb->add_margin_child(TTR("Sun Energy"), sun_energy);
+ sun_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
+ sun_energy->set_max(64.0);
+
+ sun_max_distance = memnew(EditorSpinSlider);
+ sun_vb->add_margin_child(TTR("Shadow Max Distance"), sun_max_distance);
+ sun_max_distance->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
+ sun_max_distance->set_min(1);
+ sun_max_distance->set_max(4096);
+
+ sun_add_to_scene = memnew(Button);
+ sun_add_to_scene->set_text(TTR("Add Sun to Scene"));
+ sun_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_sun_to_scene));
+ sun_vb->add_spacer();
+ sun_vb->add_child(sun_add_to_scene);
+
+ sun_state = memnew(Label);
+ sun_environ_hb->add_child(sun_state);
+ sun_state->set_align(Label::ALIGN_CENTER);
+ sun_state->set_valign(Label::VALIGN_CENTER);
+ sun_state->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ VSeparator *sc = memnew(VSeparator);
+ sc->set_custom_minimum_size(Size2(50 * EDSCALE, 0));
+ sc->set_v_size_flags(SIZE_EXPAND_FILL);
+ sun_environ_hb->add_child(sc);
+
+ environ_vb = memnew(VBoxContainer);
+ sun_environ_hb->add_child(environ_vb);
+ environ_vb->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
+ environ_vb->hide();
+
+ environ_title = memnew(Label);
+ environ_vb->add_child(environ_title);
+ environ_title->set_text(TTR("Preview Environment"));
+ environ_title->set_align(Label::ALIGN_CENTER);
+
+ environ_sky_color = memnew(ColorPickerButton);
+ environ_sky_color->set_edit_alpha(false);
+ environ_sky_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
+ environ_vb->add_margin_child(TTR("Sky Color"), environ_sky_color);
+ environ_ground_color = memnew(ColorPickerButton);
+ environ_ground_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
+ environ_ground_color->set_edit_alpha(false);
+ environ_vb->add_margin_child(TTR("Ground Color"), environ_ground_color);
+ environ_energy = memnew(EditorSpinSlider);
+ environ_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1));
+ environ_energy->set_max(8.0);
+ environ_vb->add_margin_child(TTR("Sky Energy"), environ_energy);
+ HBoxContainer *fx_vb = memnew(HBoxContainer);
+ fx_vb->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ environ_ao_button = memnew(Button);
+ environ_ao_button->set_text(TTR("AO"));
+ environ_ao_button->set_toggle_mode(true);
+ environ_ao_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED);
+ fx_vb->add_child(environ_ao_button);
+ environ_glow_button = memnew(Button);
+ environ_glow_button->set_text(TTR("Glow"));
+ environ_glow_button->set_toggle_mode(true);
+ environ_glow_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED);
+ fx_vb->add_child(environ_glow_button);
+ environ_tonemap_button = memnew(Button);
+ environ_tonemap_button->set_text(TTR("Tonemap"));
+ environ_tonemap_button->set_toggle_mode(true);
+ environ_tonemap_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED);
+ fx_vb->add_child(environ_tonemap_button);
+ environ_gi_button = memnew(Button);
+ environ_gi_button->set_text(TTR("GI"));
+ environ_gi_button->set_toggle_mode(true);
+ environ_gi_button->connect("pressed", callable_mp(this, &Node3DEditor::_preview_settings_changed), varray(), CONNECT_DEFERRED);
+ fx_vb->add_child(environ_gi_button);
+ environ_vb->add_margin_child(TTR("Post Process"), fx_vb);
+
+ environ_add_to_scene = memnew(Button);
+ environ_add_to_scene->set_text(TTR("Add Environment to Scene"));
+ environ_add_to_scene->connect("pressed", callable_mp(this, &Node3DEditor::_add_environment_to_scene));
+ environ_vb->add_spacer();
+ environ_vb->add_child(environ_add_to_scene);
+
+ environ_state = memnew(Label);
+ sun_environ_hb->add_child(environ_state);
+ environ_state->set_align(Label::ALIGN_CENTER);
+ environ_state->set_valign(Label::VALIGN_CENTER);
+ environ_state->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ preview_sun = memnew(DirectionalLight3D);
+ preview_sun->set_shadow(true);
+ preview_sun->set_shadow_mode(DirectionalLight3D::SHADOW_PARALLEL_4_SPLITS);
+ preview_environment = memnew(WorldEnvironment);
+ environment.instance();
+ preview_environment->set_environment(environment);
+ Ref<Sky> sky;
+ sky.instance();
+ sky_material.instance();
+ sky->set_material(sky_material);
+ environment->set_sky(sky);
+ environment->set_background(Environment::BG_SKY);
+
+ _load_default_preview_settings();
+ _preview_settings_changed();
+ }
}
Node3DEditor::~Node3DEditor() {
@@ -6661,7 +7252,7 @@ void Node3DEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) {
struct _GizmoPluginPriorityComparator {
bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const {
if (p_a->get_priority() == p_b->get_priority()) {
- return p_a->get_name() < p_b->get_name();
+ return p_a->get_gizmo_name() < p_b->get_gizmo_name();
}
return p_a->get_priority() > p_b->get_priority();
}
@@ -6669,7 +7260,7 @@ struct _GizmoPluginPriorityComparator {
struct _GizmoPluginNameComparator {
bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const {
- return p_a->get_name() < p_b->get_name();
+ return p_a->get_gizmo_name() < p_b->get_gizmo_name();
}
};
@@ -6696,7 +7287,7 @@ Node3DEditorPlugin::Node3DEditorPlugin(EditorNode *p_node) {
editor = p_node;
spatial_editor = memnew(Node3DEditor(p_node));
spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor->get_viewport()->add_child(spatial_editor);
+ editor->get_main_control()->add_child(spatial_editor);
spatial_editor->hide();
spatial_editor->connect("transform_key_request", Callable(editor->get_inspector_dock(), "_transform_keyed"));
@@ -6880,7 +7471,7 @@ void EditorNode3DGizmoPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_material", "name", "gizmo"), &EditorNode3DGizmoPlugin::get_material, DEFVAL(Ref<EditorNode3DGizmo>()));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "get_name"));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "get_gizmo_name"));
BIND_VMETHOD(MethodInfo(Variant::INT, "get_priority"));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_be_hidden"));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_selectable_when_hidden"));
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 079c86ceb4..ff4a941b06 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,7 +37,10 @@
#include "scene/3d/immediate_geometry_3d.h"
#include "scene/3d/light_3d.h"
#include "scene/3d/visual_instance_3d.h"
+#include "scene/3d/world_environment.h"
#include "scene/gui/panel_container.h"
+#include "scene/resources/environment.h"
+#include "scene/resources/sky_material.h"
class Camera3D;
class Node3DEditor;
@@ -96,6 +99,7 @@ protected:
public:
void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1));
+ void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1));
void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>(), const Ref<Material> &p_material = Ref<Material>());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
@@ -213,6 +217,11 @@ class Node3DEditorViewport : public Control {
VIEW_DISPLAY_DEBUG_SDFGI_PROBES,
VIEW_DISPLAY_DEBUG_GI_BUFFER,
VIEW_DISPLAY_DEBUG_DISABLE_LOD,
+ VIEW_DISPLAY_DEBUG_CLUSTER_OMNI_LIGHTS,
+ VIEW_DISPLAY_DEBUG_CLUSTER_SPOT_LIGHTS,
+ VIEW_DISPLAY_DEBUG_CLUSTER_DECALS,
+ VIEW_DISPLAY_DEBUG_CLUSTER_REFLECTION_PROBES,
+
VIEW_LOCK_ROTATION,
VIEW_CINEMATIC_PREVIEW,
VIEW_AUTO_ORTHOGONAL,
@@ -289,6 +298,9 @@ private:
VBoxContainer *top_right_vbox;
ViewportRotationControl *rotation_control;
+ Gradient *frame_time_gradient;
+ Label *cpu_time_label;
+ Label *gpu_time_label;
Label *fps_label;
struct _RayResult {
@@ -455,6 +467,8 @@ private:
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
+ void _project_settings_changed();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -480,6 +494,7 @@ public:
Camera3D *get_camera() { return camera; } // return the default camera object.
Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index);
+ ~Node3DEditorViewport();
};
class Node3DEditorSelectedItem : public Object {
@@ -581,7 +596,6 @@ private:
/////
ToolMode tool_mode;
- bool orthogonal;
RenderingServer::ScenarioDebugMode scenario_debug;
@@ -614,6 +628,7 @@ private:
RID cursor_mesh;
RID cursor_instance;
Ref<StandardMaterial3D> indicator_mat;
+ Ref<ShaderMaterial> grid_mat[3];
Ref<StandardMaterial3D> cursor_material;
// Scene drag and drop support
@@ -721,6 +736,7 @@ private:
static Node3DEditor *singleton;
+ void _node_added(Node *p_node);
void _node_removed(Node *p_node);
Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_priority;
Vector<Ref<EditorNode3DGizmoPlugin>> gizmo_plugins_by_name;
@@ -733,6 +749,61 @@ private:
void _refresh_menu_icons();
+ // Preview Sun and Environment
+
+ uint32_t world_env_count = 0;
+ uint32_t directional_light_count = 0;
+
+ Button *sun_button;
+ Label *sun_state;
+ Label *sun_title;
+ VBoxContainer *sun_vb;
+ Popup *sun_environ_popup;
+ Control *sun_direction;
+ ColorPickerButton *sun_color;
+ EditorSpinSlider *sun_energy;
+ EditorSpinSlider *sun_max_distance;
+ Button *sun_add_to_scene;
+
+ void _sun_direction_draw();
+ void _sun_direction_input(const Ref<InputEvent> &p_event);
+
+ Basis sun_rotation;
+
+ Ref<Shader> sun_direction_shader;
+ Ref<ShaderMaterial> sun_direction_material;
+
+ Button *environ_button;
+ Label *environ_state;
+ Label *environ_title;
+ VBoxContainer *environ_vb;
+ ColorPickerButton *environ_sky_color;
+ ColorPickerButton *environ_ground_color;
+ EditorSpinSlider *environ_energy;
+ Button *environ_ao_button;
+ Button *environ_glow_button;
+ Button *environ_tonemap_button;
+ Button *environ_gi_button;
+ Button *environ_add_to_scene;
+
+ Button *sun_environ_settings;
+
+ DirectionalLight3D *preview_sun;
+ WorldEnvironment *preview_environment;
+ Ref<Environment> environment;
+ Ref<ProceduralSkyMaterial> sky_material;
+
+ bool sun_environ_updating = false;
+
+ void _load_default_preview_settings();
+ void _update_preview_environment();
+
+ void _preview_settings_changed();
+ void _sun_environ_settings_pressed();
+
+ void _add_sun_to_scene();
+ void _add_environment_to_scene();
+
protected:
void _notification(int p_what);
//void _gui_input(InputEvent p_event);
diff --git a/editor/plugins/ot_features_plugin.cpp b/editor/plugins/ot_features_plugin.cpp
index 3478148521..ebfdf2c7cd 100644
--- a/editor/plugins/ot_features_plugin.cpp
+++ b/editor/plugins/ot_features_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/ot_features_plugin.h b/editor/plugins/ot_features_plugin.h
index 5b5f367b24..9559a6c0c3 100644
--- a/editor/plugins/ot_features_plugin.h
+++ b/editor/plugins/ot_features_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp
index 608b5c3104..0a949c8610 100644
--- a/editor/plugins/packed_scene_translation_parser_plugin.cpp
+++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,7 +42,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
// These properties are translated with the tr() function in the C++ code when being set or updated.
Error err;
- RES loaded_res = ResourceLoader::load(p_path, "PackedScene", false, &err);
+ RES loaded_res = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
if (err) {
ERR_PRINT("Failed to load " + p_path);
return err;
@@ -81,14 +81,14 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
Vector<String> str_values = property_value;
for (int k = 0; k < str_values.size(); k++) {
String desc = str_values[k].get_slice(";", 1).strip_edges();
- if (!desc.empty()) {
+ if (!desc.is_empty()) {
parsed_strings.push_back(desc);
}
}
} else if (property_value.get_type() == Variant::STRING) {
String str_value = String(property_value);
// Prevent reading text containing only spaces.
- if (!str_value.strip_edges().empty()) {
+ if (!str_value.strip_edges().is_empty()) {
parsed_strings.push_back(str_value);
}
}
diff --git a/editor/plugins/packed_scene_translation_parser_plugin.h b/editor/plugins/packed_scene_translation_parser_plugin.h
index a0ffdf692c..e51d65414e 100644
--- a/editor/plugins/packed_scene_translation_parser_plugin.h
+++ b/editor/plugins/packed_scene_translation_parser_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index f79098ce5d..908235f89f 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 8a420d7c8d..867e0ce74f 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index 043693801e..3783af8fc6 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -609,7 +609,7 @@ Path3DEditorPlugin::Path3DEditorPlugin(EditorNode *p_node) {
curve_edit->set_pressed(true);
/*
collision_polygon_editor = memnew( PathEditor(p_node) );
- editor->get_viewport()->add_child(collision_polygon_editor);
+ editor->get_main_control()->add_child(collision_polygon_editor);
collision_polygon_editor->set_margin(MARGIN_LEFT,200);
collision_polygon_editor->set_margin(MARGIN_RIGHT,230);
collision_polygon_editor->set_margin(MARGIN_TOP,0);
diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h
index 3b92a59143..13870d7591 100644
--- a/editor/plugins/path_3d_editor_plugin.h
+++ b/editor/plugins/path_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp
index 30bf827b3c..4b52512933 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.cpp
+++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.h b/editor/plugins/physical_bone_3d_editor_plugin.h
index bdfcca8878..248aad9298 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.h
+++ b/editor/plugins/physical_bone_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 0584ee894b..3d7b01c149 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1052,8 +1052,6 @@ void Polygon2DEditor::_uv_draw() {
if (i < uv_draw_max /*&& polygons.size() == 0 && polygon_create.size() == 0*/) { //if using or creating polygons, do not show outline (will show polygons instead)
uv_edit_draw->draw_line(mtx.xform(uvs[i]), mtx.xform(next_point), poly_line_color, Math::round(EDSCALE));
}
-
- rect.expand_to(mtx.basis_xform(uvs[i]));
}
for (int i = 0; i < polygons.size(); i++) {
@@ -1160,8 +1158,8 @@ void Polygon2DEditor::_uv_draw() {
uv_edit_draw->draw_circle(bone_paint_pos, bone_paint_radius->get_value() * EDSCALE, Color(1, 1, 1, 0.1));
}
- rect.position -= uv_edit_draw->get_size();
- rect.size += uv_edit_draw->get_size() * 2.0;
+ rect.position = -uv_edit_draw->get_size();
+ rect.size = uv_edit_draw->get_size() * 2.0 + base_tex->get_size() * uv_draw_zoom;
updating_uv_scroll = true;
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index 77580a5604..af3b2f5aef 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index 684d43e963..b4b8e82124 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h
index ddfb54c40b..bc10b48a16 100644
--- a/editor/plugins/resource_preloader_editor_plugin.h
+++ b/editor/plugins/resource_preloader_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index e107435373..50f4d8493f 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h
index cc19228470..c70fff7db7 100644
--- a/editor/plugins/root_motion_editor_plugin.h
+++ b/editor/plugins/root_motion_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 7607ab482c..8bf5d0611d 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -587,7 +587,7 @@ void ScriptEditor::_go_to_tab(int p_idx) {
}
void ScriptEditor::_add_recent_script(String p_path) {
- if (p_path.empty()) {
+ if (p_path.is_empty()) {
return;
}
@@ -702,7 +702,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
}
}
if (script.is_valid()) {
- if (!script->get_path().empty()) {
+ if (!script->get_path().is_empty()) {
// Only saved scripts can be restored.
previous_scripts.push_back(script->get_path());
}
@@ -755,8 +755,8 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
_save_layout();
}
-void ScriptEditor::_close_current_tab() {
- _close_tab(tab_container->get_current_tab());
+void ScriptEditor::_close_current_tab(bool p_save) {
+ _close_tab(tab_container->get_current_tab(), p_save);
}
void ScriptEditor::_close_discard_current_tab(const String &p_str) {
@@ -802,7 +802,7 @@ void ScriptEditor::_close_other_tabs() {
}
}
- _close_current_tab();
+ _close_current_tab(false);
}
}
@@ -820,7 +820,7 @@ void ScriptEditor::_close_all_tabs() {
}
}
- _close_current_tab();
+ _close_current_tab(false);
}
}
@@ -894,7 +894,7 @@ void ScriptEditor::_reload_scripts() {
Ref<Script> script = edited_res;
if (script != nullptr) {
- Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true);
+ Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE);
ERR_CONTINUE(!rel_script.is_valid());
script->set_source_code(rel_script->get_source_code());
script->set_last_modified_time(rel_script->get_last_modified_time());
@@ -1129,7 +1129,7 @@ void ScriptEditor::_menu_option(int p_option) {
return;
} break;
case FILE_REOPEN_CLOSED: {
- if (previous_scripts.empty()) {
+ if (previous_scripts.is_empty()) {
return;
}
@@ -1372,7 +1372,7 @@ void ScriptEditor::_menu_option(int p_option) {
if (current->is_unsaved()) {
_ask_close_current_unsaved_tab(current);
} else {
- _close_current_tab();
+ _close_current_tab(false);
}
} break;
case FILE_COPY_PATH: {
@@ -1381,7 +1381,7 @@ void ScriptEditor::_menu_option(int p_option) {
case SHOW_IN_FILE_SYSTEM: {
const RES script = current->get_edited_resource();
const String path = script->get_path();
- if (!path.empty()) {
+ if (!path.is_empty()) {
FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock();
file_system_dock->navigate_to_path(path);
// Ensure that the FileSystem dock is visible.
@@ -1887,7 +1887,7 @@ void ScriptEditor::_update_script_names() {
if (se) {
Ref<Texture2D> icon = se->get_theme_icon();
String path = se->get_edited_resource()->get_path();
- bool saved = !path.empty();
+ bool saved = !path.is_empty();
if (saved) {
// The script might be deleted, moved, or renamed, so make sure
// to update original path to previously edited resource.
@@ -1934,7 +1934,7 @@ void ScriptEditor::_update_script_names() {
sd.name = name;
} break;
case DISPLAY_DIR_AND_NAME: {
- if (!path.get_base_dir().get_file().empty()) {
+ if (!path.get_base_dir().get_file().is_empty()) {
sd.name = path.get_base_dir().get_file().plus_file(name);
} else {
sd.name = name;
@@ -1954,7 +1954,20 @@ void ScriptEditor::_update_script_names() {
Vector<String> disambiguated_script_names;
Vector<String> full_script_paths;
for (int j = 0; j < sedata.size(); j++) {
- disambiguated_script_names.append(sedata[j].name.replace("(*)", "").get_file());
+ String name = sedata[j].name.replace("(*)", "");
+ ScriptListName script_display = (ScriptListName)(int)EditorSettings::get_singleton()->get("text_editor/script_list/list_script_names_as");
+ switch (script_display) {
+ case DISPLAY_NAME: {
+ name = name.get_file();
+ } break;
+ case DISPLAY_DIR_AND_NAME: {
+ name = name.get_base_dir().get_file().plus_file(name.get_file());
+ } break;
+ default:
+ break;
+ }
+
+ disambiguated_script_names.append(name);
full_script_paths.append(sedata[j].tooltip);
}
@@ -1988,7 +2001,7 @@ void ScriptEditor::_update_script_names() {
}
}
- if (_sort_list_on_update && !sedata.empty()) {
+ if (_sort_list_on_update && !sedata.is_empty()) {
sedata.sort();
// change actual order of tab_container so that the order can be rearranged by user
@@ -2052,7 +2065,7 @@ void ScriptEditor::_update_script_names() {
_update_help_overview_visibility();
_update_script_colors();
- file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(FILE_REOPEN_CLOSED), previous_scripts.empty());
+ file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(FILE_REOPEN_CLOSED), previous_scripts.is_empty());
}
void ScriptEditor::_update_script_connections() {
@@ -2198,7 +2211,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
args.push_back(script_path);
}
- Error err = OS::get_singleton()->execute(path, args, false);
+ Error err = OS::get_singleton()->create_process(path, args);
if (err == OK) {
return false;
}
@@ -2806,7 +2819,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
String path = scripts[i];
Dictionary script_info = scripts[i];
- if (!script_info.empty()) {
+ if (!script_info.is_empty()) {
path = script_info["path"];
}
@@ -2833,7 +2846,7 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
}
}
- if (!script_info.empty()) {
+ if (!script_info.is_empty()) {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(tab_container->get_tab_count() - 1));
if (se) {
se->set_edit_state(script_info["state"]);
@@ -3484,7 +3497,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
erase_tab_confirm = memnew(ConfirmationDialog);
erase_tab_confirm->get_ok_button()->set_text(TTR("Save"));
erase_tab_confirm->add_button(TTR("Discard"), DisplayServer::get_singleton()->get_swap_cancel_ok(), "discard");
- erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab));
+ erase_tab_confirm->connect("confirmed", callable_mp(this, &ScriptEditor::_close_current_tab), varray(true));
erase_tab_confirm->connect("custom_action", callable_mp(this, &ScriptEditor::_close_discard_current_tab));
add_child(erase_tab_confirm);
@@ -3646,7 +3659,7 @@ void ScriptEditorPlugin::edited_scene_changed() {
ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
editor = p_node;
script_editor = memnew(ScriptEditor(p_node));
- editor->get_viewport()->add_child(script_editor);
+ editor->get_main_control()->add_child(script_editor);
script_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
script_editor->hide();
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index aafd8cba18..b2172e7f10 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -325,7 +325,7 @@ class ScriptEditor : public PanelContainer {
void _close_tab(int p_idx, bool p_save = true, bool p_history_back = true);
- void _close_current_tab();
+ void _close_current_tab(bool p_save = true);
void _close_discard_current_tab(const String &p_str);
void _close_docs_tab();
void _close_other_tabs();
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index ed2c0c9f26..b6df66b8af 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -214,7 +214,7 @@ void ScriptTextEditor::_load_theme_settings() {
text_edit->add_theme_color_override("line_number_color", line_number_color);
text_edit->add_theme_color_override("caret_color", caret_color);
text_edit->add_theme_color_override("caret_background_color", caret_background_color);
- text_edit->add_theme_color_override("font_color_selected", text_selected_color);
+ text_edit->add_theme_color_override("font_selected_color", text_selected_color);
text_edit->add_theme_color_override("selection_color", selection_color);
text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color);
text_edit->add_theme_color_override("current_line_color", current_line_color);
@@ -349,7 +349,7 @@ void ScriptTextEditor::update_settings() {
bool ScriptTextEditor::is_unsaved() {
const bool unsaved =
code_editor->get_text_editor()->get_version() != code_editor->get_text_editor()->get_saved_version() ||
- script->get_path().empty(); // In memory.
+ script->get_path().is_empty(); // In memory.
return unsaved;
}
@@ -427,7 +427,7 @@ String ScriptTextEditor::get_name() {
if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
name = script->get_path().get_file();
if (is_unsaved()) {
- if (script->get_path().empty()) {
+ if (script->get_path().is_empty()) {
name = TTR("[unsaved]");
}
name += "(*)";
@@ -551,7 +551,7 @@ void ScriptTextEditor::_validate_script() {
if (safe_lines.has(i + 1)) {
te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
last_is_safe = true;
- } else if (last_is_safe && (te->is_line_comment(i) || te->get_line(i).strip_edges().empty())) {
+ } else if (last_is_safe && (te->is_line_comment(i) || te->get_line(i).strip_edges().is_empty())) {
te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
} else {
te->set_line_gutter_item_color(i, line_number_gutter, default_line_number_color);
@@ -688,7 +688,7 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo
uint64_t date = FileAccess::get_modified_time(script->get_path());
if (last_date != date) {
- Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true);
+ Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE);
ERR_CONTINUE(!rel_script.is_valid());
script->set_source_code(rel_script->get_source_code());
script->set_last_modified_time(rel_script->get_last_modified_time());
@@ -1066,7 +1066,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
return;
}
- tx->indent_left();
+ tx->indent_selected_lines_left();
} break;
case EDIT_INDENT_RIGHT: {
Ref<Script> scr = script;
@@ -1074,7 +1074,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
return;
}
- tx->indent_right();
+ tx->indent_selected_lines_right();
} break;
case EDIT_DELETE_LINE: {
code_editor->delete_lines();
@@ -1632,16 +1632,16 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition, Vector2 p_pos) {
context_menu->clear();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO);
context_menu->add_separator();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE);
context_menu->add_separator();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL);
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
@@ -1743,14 +1743,14 @@ void ScriptTextEditor::_enable_code_editor() {
search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option));
edit_hb->add_child(edit_menu);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE);
edit_menu->get_popup()->add_separator();
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN);
@@ -1763,7 +1763,7 @@ void ScriptTextEditor::_enable_code_editor() {
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
@@ -1915,12 +1915,6 @@ static ScriptEditorBase *create_editor(const RES &p_resource) {
}
void ScriptTextEditor::register_editor() {
- ED_SHORTCUT("script_text_editor/undo", TTR("Undo"), KEY_MASK_CMD | KEY_Z);
- ED_SHORTCUT("script_text_editor/redo", TTR("Redo"), KEY_MASK_CMD | KEY_Y);
- ED_SHORTCUT("script_text_editor/cut", TTR("Cut"), KEY_MASK_CMD | KEY_X);
- ED_SHORTCUT("script_text_editor/copy", TTR("Copy"), KEY_MASK_CMD | KEY_C);
- ED_SHORTCUT("script_text_editor/paste", TTR("Paste"), KEY_MASK_CMD | KEY_V);
- ED_SHORTCUT("script_text_editor/select_all", TTR("Select All"), KEY_MASK_CMD | KEY_A);
ED_SHORTCUT("script_text_editor/move_up", TTR("Move Up"), KEY_MASK_ALT | KEY_UP);
ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT | KEY_DOWN);
ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K);
@@ -1936,10 +1930,8 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0);
#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C);
- ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE);
#else
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D);
- ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
#endif
ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E);
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T);
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 1e436fbe65..17abfcf4cc 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 9bb34f4489..c8a46715ad 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -117,7 +117,7 @@ void ShaderTextEditor::_load_theme_settings() {
get_text_editor()->add_theme_color_override("line_number_color", line_number_color);
get_text_editor()->add_theme_color_override("caret_color", caret_color);
get_text_editor()->add_theme_color_override("caret_background_color", caret_background_color);
- get_text_editor()->add_theme_color_override("font_color_selected", text_selected_color);
+ get_text_editor()->add_theme_color_override("font_selected_color", text_selected_color);
get_text_editor()->add_theme_color_override("selection_color", selection_color);
get_text_editor()->add_theme_color_override("brace_mismatch_color", brace_mismatch_color);
get_text_editor()->add_theme_color_override("current_line_color", current_line_color);
@@ -282,7 +282,7 @@ void ShaderEditor::_menu_option(int p_option) {
}
CodeEdit *tx = shader_editor->get_text_editor();
- tx->indent_left();
+ tx->indent_selected_lines_left();
} break;
case EDIT_INDENT_RIGHT: {
@@ -291,7 +291,7 @@ void ShaderEditor::_menu_option(int p_option) {
}
CodeEdit *tx = shader_editor->get_text_editor();
- tx->indent_right();
+ tx->indent_selected_lines_right();
} break;
case EDIT_DELETE_LINE: {
@@ -339,7 +339,7 @@ void ShaderEditor::_menu_option(int p_option) {
shader_editor->remove_all_bookmarks();
} break;
case HELP_DOCS: {
- OS::get_singleton()->shell_open("https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html");
+ OS::get_singleton()->shell_open("https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/index.html");
} break;
}
if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) {
@@ -405,7 +405,7 @@ void ShaderEditor::_check_for_external_edit() {
}
void ShaderEditor::_reload_shader_from_disk() {
- Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), true);
+ Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE);
ERR_FAIL_COND(!rel_shader.is_valid());
shader->set_code(rel_shader->get_code());
@@ -533,15 +533,15 @@ void ShaderEditor::_bookmark_item_pressed(int p_idx) {
void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) {
context_menu->clear();
if (p_selection) {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY);
}
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE);
context_menu->add_separator();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO);
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
@@ -585,14 +585,14 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
edit_menu->set_text(TTR("Edit"));
edit_menu->set_switch_on_hover(true);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE);
edit_menu->get_popup()->add_separator();
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN);
@@ -602,7 +602,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
edit_menu->get_popup()->add_separator();
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE);
edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditor::_menu_option));
search_menu = memnew(MenuButton);
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index e81a782ac8..731c0a5b7e 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp
index f15a801530..47d7f8204b 100644
--- a/editor/plugins/shader_file_editor_plugin.cpp
+++ b/editor/plugins/shader_file_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,7 +59,7 @@ void ShaderFileEditor::_version_selected(int p_option) {
ERR_FAIL_COND(bytecode.is_null());
for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
- if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) {
+ if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).is_empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) {
stages[i]->set_icon(Ref<Texture2D>());
continue;
}
@@ -182,7 +182,7 @@ void ShaderFileEditor::_update_options() {
for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
Vector<uint8_t> bc = bytecode->get_stage_bytecode(RD::ShaderStage(i));
String error = bytecode->get_stage_compile_error(RD::ShaderStage(i));
- bool disable = error == String() && bc.empty();
+ bool disable = error == String() && bc.is_empty();
stages[i]->set_disabled(disable);
if (!disable) {
if (stages[i]->is_pressed()) {
diff --git a/editor/plugins/shader_file_editor_plugin.h b/editor/plugins/shader_file_editor_plugin.h
index 6858f7d933..7d6e503b6c 100644
--- a/editor/plugins/shader_file_editor_plugin.h
+++ b/editor/plugins/shader_file_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp
index a198e4ff8f..44916e1d46 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -129,7 +129,7 @@ void Skeleton2DEditorPlugin::make_visible(bool p_visible) {
Skeleton2DEditorPlugin::Skeleton2DEditorPlugin(EditorNode *p_node) {
editor = p_node;
sprite_editor = memnew(Skeleton2DEditor);
- editor->get_viewport()->add_child(sprite_editor);
+ editor->get_main_control()->add_child(sprite_editor);
make_visible(false);
//sprite_editor->options->hide();
diff --git a/editor/plugins/skeleton_2d_editor_plugin.h b/editor/plugins/skeleton_2d_editor_plugin.h
index b8377fc914..dacd8fe43f 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.h
+++ b/editor/plugins/skeleton_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 22f50c0689..121ccfa417 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -293,7 +293,7 @@ void BoneTransformEditor::_key_button_pressed() {
const BoneId bone_id = property.get_slicec('/', 1).to_int();
const String name = skeleton->get_bone_name(bone_id);
- if (name.empty())
+ if (name.is_empty())
return;
// Need to normalize the basis before you key it
@@ -383,8 +383,12 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi
CollisionShape3D *bone_shape = memnew(CollisionShape3D);
bone_shape->set_shape(bone_shape_capsule);
+ Transform capsule_transform;
+ capsule_transform.basis = Basis(Vector3(1, 0, 0), Vector3(0, 0, 1), Vector3(0, -1, 0));
+ bone_shape->set_transform(capsule_transform);
+
Transform body_transform;
- body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin, Vector3(0, 1, 0));
+ body_transform.set_look_at(Vector3(0, 0, 0), child_rest.origin);
body_transform.origin = body_transform.basis.xform(Vector3(0, 0, -half_height));
Transform joint_transform;
diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h
index 44dc1bc36e..14c213f7b2 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
index 8fc789b94a..2da49c1c0b 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.h b/editor/plugins/skeleton_ik_3d_editor_plugin.h
index c1585ea670..b0d2138115 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp
index 1be6b979b1..4949d2b9b7 100644
--- a/editor/plugins/sprite_2d_editor_plugin.cpp
+++ b/editor/plugins/sprite_2d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -173,6 +173,11 @@ void Sprite2DEditor::_update_mesh_data() {
Ref<Image> image = texture->get_data();
ERR_FAIL_COND(image.is_null());
+
+ if (image->is_compressed()) {
+ image->decompress();
+ }
+
Rect2 rect;
if (node->is_region()) {
rect = node->get_region_rect();
@@ -340,7 +345,7 @@ void Sprite2DEditor::_convert_to_mesh_2d_node() {
}
void Sprite2DEditor::_convert_to_polygon_2d_node() {
- if (computed_outline_lines.empty()) {
+ if (computed_outline_lines.is_empty()) {
err_dialog->set_text(TTR("Invalid geometry, can't create polygon."));
err_dialog->popup_centered();
return;
@@ -398,7 +403,7 @@ void Sprite2DEditor::_convert_to_polygon_2d_node() {
}
void Sprite2DEditor::_create_collision_polygon_2d_node() {
- if (computed_outline_lines.empty()) {
+ if (computed_outline_lines.is_empty()) {
err_dialog->set_text(TTR("Invalid geometry, can't create collision polygon."));
err_dialog->popup_centered();
return;
@@ -420,7 +425,7 @@ void Sprite2DEditor::_create_collision_polygon_2d_node() {
}
void Sprite2DEditor::_create_light_occluder_2d_node() {
- if (computed_outline_lines.empty()) {
+ if (computed_outline_lines.is_empty()) {
err_dialog->set_text(TTR("Invalid geometry, can't create light occluder."));
err_dialog->popup_centered();
return;
@@ -583,7 +588,7 @@ void Sprite2DEditorPlugin::make_visible(bool p_visible) {
Sprite2DEditorPlugin::Sprite2DEditorPlugin(EditorNode *p_node) {
editor = p_node;
sprite_editor = memnew(Sprite2DEditor);
- editor->get_viewport()->add_child(sprite_editor);
+ editor->get_main_control()->add_child(sprite_editor);
make_visible(false);
//sprite_editor->options->hide();
diff --git a/editor/plugins/sprite_2d_editor_plugin.h b/editor/plugins/sprite_2d_editor_plugin.h
index 8769f19b5c..d4a1ef4312 100644
--- a/editor/plugins/sprite_2d_editor_plugin.h
+++ b/editor/plugins/sprite_2d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index b79d829c34..0547f99079 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/io/resource_loader.h"
+#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "scene/3d/sprite_3d.h"
@@ -318,7 +319,7 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_
resources.push_back(resource);
}
- if (resources.empty()) {
+ if (resources.is_empty()) {
return;
}
@@ -952,7 +953,11 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
if (String(d["type"]) == "files") {
Vector<String> files = d["files"];
- _file_load_request(files, at_pos);
+ if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ _prepare_sprite_sheet(files[0]);
+ } else {
+ _file_load_request(files, at_pos);
+ }
}
}
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index 0dce93f55a..bbc26ca726 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp
index 3641052a4e..64df982d5d 100644
--- a/editor/plugins/style_box_editor_plugin.cpp
+++ b/editor/plugins/style_box_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h
index 41daa662db..d4a235cd10 100644
--- a/editor/plugins/style_box_editor_plugin.h
+++ b/editor/plugins/style_box_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index b95abe8994..b88f1c91e6 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -96,7 +96,7 @@ void TextEditor::_load_theme_settings() {
text_edit->add_theme_color_override("line_number_color", line_number_color);
text_edit->add_theme_color_override("caret_color", caret_color);
text_edit->add_theme_color_override("caret_background_color", caret_background_color);
- text_edit->add_theme_color_override("font_color_selected", text_selected_color);
+ text_edit->add_theme_color_override("font_selected_color", text_selected_color);
text_edit->add_theme_color_override("selection_color", selection_color);
text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color);
text_edit->add_theme_color_override("current_line_color", current_line_color);
@@ -119,7 +119,7 @@ String TextEditor::get_name() {
if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) {
name = text_file->get_path().get_file();
if (is_unsaved()) {
- if (text_file->get_path().empty()) {
+ if (text_file->get_path().is_empty()) {
name = TTR("[unsaved]");
}
name += "(*)";
@@ -242,7 +242,7 @@ void TextEditor::apply_code() {
bool TextEditor::is_unsaved() {
const bool unsaved =
code_editor->get_text_editor()->get_version() != code_editor->get_text_editor()->get_saved_version() ||
- text_file->get_path().empty(); // In memory.
+ text_file->get_path().is_empty(); // In memory.
return unsaved;
}
@@ -363,10 +363,10 @@ void TextEditor::_edit_option(int p_op) {
code_editor->move_lines_down();
} break;
case EDIT_INDENT_LEFT: {
- tx->indent_left();
+ tx->indent_selected_lines_left();
} break;
case EDIT_INDENT_RIGHT: {
- tx->indent_right();
+ tx->indent_selected_lines_right();
} break;
case EDIT_DELETE_LINE: {
code_editor->delete_lines();
@@ -514,15 +514,15 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded, Vector2 p_position) {
context_menu->clear();
if (p_selection) {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY);
}
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE);
context_menu->add_separator();
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO);
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
@@ -584,14 +584,14 @@ TextEditor::TextEditor() {
edit_menu->set_switch_on_hover(true);
edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &TextEditor::_edit_option));
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("un_redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE);
edit_menu->get_popup()->add_separator();
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN);
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index ea425bd033..c066d51b18 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp
index d13a865534..36297c8a4a 100644
--- a/editor/plugins/texture_3d_editor_plugin.cpp
+++ b/editor/plugins/texture_3d_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,7 +57,7 @@ void Texture3DEditor::_notification(int p_what) {
}
}
-void Texture3DEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+void Texture3DEditor::_texture_changed() {
if (!is_visible()) {
return;
}
@@ -118,7 +118,7 @@ void Texture3DEditor::_texture_rect_update_area() {
void Texture3DEditor::edit(Ref<Texture3D> p_texture) {
if (!texture.is_null()) {
- texture->remove_change_receptor(this);
+ texture->disconnect("changed", callable_mp(this, &Texture3DEditor::_texture_changed));
}
texture = p_texture;
@@ -128,7 +128,7 @@ void Texture3DEditor::edit(Ref<Texture3D> p_texture) {
_make_shaders();
}
- texture->add_change_receptor(this);
+ texture->connect("changed", callable_mp(this, &Texture3DEditor::_texture_changed));
update();
texture_rect->set_material(material);
setting = true;
@@ -173,8 +173,7 @@ Texture3DEditor::Texture3DEditor() {
info->set_h_grow_direction(GROW_DIRECTION_BEGIN);
info->set_v_grow_direction(GROW_DIRECTION_BEGIN);
info->add_theme_color_override("font_color", Color(1, 1, 1, 1));
- info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5));
- info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5));
+ info->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.5));
info->add_theme_constant_override("shadow_as_outline", 1);
info->add_theme_constant_override("shadow_offset_x", 2);
info->add_theme_constant_override("shadow_offset_y", 2);
@@ -185,7 +184,7 @@ Texture3DEditor::Texture3DEditor() {
Texture3DEditor::~Texture3DEditor() {
if (!texture.is_null()) {
- texture->remove_change_receptor(this);
+ texture->disconnect("changed", callable_mp(this, &Texture3DEditor::_texture_changed));
}
}
diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h
index 4fbf47ecfe..9d90d3653f 100644
--- a/editor/plugins/texture_3d_editor_plugin.h
+++ b/editor/plugins/texture_3d_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -61,10 +61,12 @@ class Texture3DEditor : public Control {
void _texture_rect_update_area();
void _texture_rect_draw();
+ void _texture_changed();
+
protected:
void _notification(int p_what);
void _gui_input(Ref<InputEvent> p_event);
- void _changed_callback(Object *p_changed, const char *p_prop) override;
+
static void _bind_methods();
public:
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 9b760c0e50..253f8878d2 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -104,7 +104,7 @@ void TextureEditor::_notification(int p_what) {
}
}
-void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+void TextureEditor::_texture_changed() {
if (!is_visible()) {
return;
}
@@ -113,13 +113,13 @@ void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) {
void TextureEditor::edit(Ref<Texture2D> p_texture) {
if (!texture.is_null()) {
- texture->remove_change_receptor(this);
+ texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed));
}
texture = p_texture;
if (!texture.is_null()) {
- texture->add_change_receptor(this);
+ texture->connect("changed", callable_mp(this, &TextureEditor::_texture_changed));
update();
} else {
hide();
@@ -137,7 +137,7 @@ TextureEditor::TextureEditor() {
TextureEditor::~TextureEditor() {
if (!texture.is_null()) {
- texture->remove_change_receptor(this);
+ texture->disconnect("changed", callable_mp(this, &TextureEditor::_texture_changed));
}
}
diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h
index 0d4452c662..ebe8882194 100644
--- a/editor/plugins/texture_editor_plugin.h
+++ b/editor/plugins/texture_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,7 @@ class TextureEditor : public Control {
protected:
void _notification(int p_what);
void _gui_input(Ref<InputEvent> p_event);
- void _changed_callback(Object *p_changed, const char *p_prop) override;
+ void _texture_changed();
static void _bind_methods();
public:
diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp
index a807e8e99b..254ad3d56e 100644
--- a/editor/plugins/texture_layered_editor_plugin.cpp
+++ b/editor/plugins/texture_layered_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,7 +63,7 @@ void TextureLayeredEditor::_notification(int p_what) {
}
}
-void TextureLayeredEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+void TextureLayeredEditor::_texture_changed() {
if (!is_visible()) {
return;
}
@@ -173,7 +173,7 @@ void TextureLayeredEditor::_texture_rect_update_area() {
void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) {
if (!texture.is_null()) {
- texture->remove_change_receptor(this);
+ texture->disconnect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed));
}
texture = p_texture;
@@ -183,7 +183,7 @@ void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) {
_make_shaders();
}
- texture->add_change_receptor(this);
+ texture->connect("changed", callable_mp(this, &TextureLayeredEditor::_texture_changed));
update();
texture_rect->set_material(materials[texture->get_layered_type()]);
setting = true;
@@ -238,8 +238,7 @@ TextureLayeredEditor::TextureLayeredEditor() {
info->set_h_grow_direction(GROW_DIRECTION_BEGIN);
info->set_v_grow_direction(GROW_DIRECTION_BEGIN);
info->add_theme_color_override("font_color", Color(1, 1, 1, 1));
- info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5));
- info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5));
+ info->add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.5));
info->add_theme_constant_override("shadow_as_outline", 1);
info->add_theme_constant_override("shadow_offset_x", 2);
info->add_theme_constant_override("shadow_offset_y", 2);
@@ -249,9 +248,6 @@ TextureLayeredEditor::TextureLayeredEditor() {
}
TextureLayeredEditor::~TextureLayeredEditor() {
- if (!texture.is_null()) {
- texture->remove_change_receptor(this);
- }
}
//
diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h
index 9a28d2dff8..c4ced62fb9 100644
--- a/editor/plugins/texture_layered_editor_plugin.h
+++ b/editor/plugins/texture_layered_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,10 +63,11 @@ class TextureLayeredEditor : public Control {
void _texture_rect_update_area();
void _texture_rect_draw();
+ void _texture_changed();
+
protected:
void _notification(int p_what);
void _gui_input(Ref<InputEvent> p_event);
- void _changed_callback(Object *p_changed, const char *p_prop) override;
static void _bind_methods();
public:
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 15d5c615bd..63255e6547 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,8 +42,21 @@
void draw_margin_line(Control *edit_draw, Vector2 from, Vector2 to) {
Vector2 line = (to - from).normalized() * 10;
+
+ // Draw a translucent background line to make the foreground line visible on any background.
+ edit_draw->draw_line(
+ from,
+ to,
+ EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor").inverted() * Color(1, 1, 1, 0.5),
+ Math::round(2 * EDSCALE));
+
while ((to - from).length_squared() > 200) {
- edit_draw->draw_line(from, from + line, EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor"), 2);
+ edit_draw->draw_line(
+ from,
+ from + line,
+ EditorNode::get_singleton()->get_theme_base()->get_theme_color("mono_color", "Editor"),
+ Math::round(2 * EDSCALE));
+
from += line * 2;
}
}
@@ -177,7 +190,7 @@ void TextureRegionEditor::_region_draw() {
}
ofs = (endpoints[next] - endpoints[i]) / 2;
- ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2);
+ ofs += (endpoints[next] - endpoints[i]).orthogonal().normalized() * (select_handle->get_size().width / 2);
if (snap_mode != SNAP_AUTOSLICE) {
edit_draw->draw_texture(select_handle, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor() - draw_ofs * draw_zoom);
@@ -467,20 +480,41 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom);
hscroll->set_value(hscroll->get_value() - dragged.x);
vscroll->set_value(vscroll->get_value() - dragged.y);
-
} else if (drag) {
if (edited_margin >= 0) {
float new_margin = 0;
- if (edited_margin == 0) {
- new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom;
- } else if (edited_margin == 1) {
- new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom;
- } else if (edited_margin == 2) {
- new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom;
- } else if (edited_margin == 3) {
- new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom;
+
+ if (snap_mode != SNAP_GRID) {
+ if (edited_margin == 0) {
+ new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom;
+ } else if (edited_margin == 1) {
+ new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom;
+ } else if (edited_margin == 2) {
+ new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom;
+ } else if (edited_margin == 3) {
+ new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom;
+ } else {
+ ERR_PRINT("Unexpected edited_margin");
+ }
+
+ if (snap_mode == SNAP_PIXEL) {
+ new_margin = Math::round(new_margin);
+ }
} else {
- ERR_PRINT("Unexpected edited_margin");
+ Vector2 pos_snapped = snap_point(mtx.affine_inverse().xform(mm->get_position()));
+ Rect2 rect_rounded = Rect2(rect.position.round(), rect.size.round());
+
+ if (edited_margin == 0) {
+ new_margin = pos_snapped.y - rect_rounded.position.y;
+ } else if (edited_margin == 1) {
+ new_margin = rect_rounded.size.y + rect_rounded.position.y - pos_snapped.y;
+ } else if (edited_margin == 2) {
+ new_margin = pos_snapped.x - rect_rounded.position.x;
+ } else if (edited_margin == 3) {
+ new_margin = rect_rounded.size.x + rect_rounded.position.x - pos_snapped.x;
+ } else {
+ ERR_PRINT("Unexpected edited_margin");
+ }
}
if (new_margin < 0) {
@@ -829,19 +863,19 @@ Sprite2D *TextureRegionEditor::get_sprite() {
void TextureRegionEditor::edit(Object *p_obj) {
if (node_sprite) {
- node_sprite->remove_change_receptor(this);
+ node_sprite->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed));
}
if (node_sprite_3d) {
- node_sprite_3d->remove_change_receptor(this);
+ node_sprite_3d->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed));
}
if (node_ninepatch) {
- node_ninepatch->remove_change_receptor(this);
+ node_ninepatch->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed));
}
if (obj_styleBox.is_valid()) {
- obj_styleBox->remove_change_receptor(this);
+ obj_styleBox->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed));
}
if (atlas_tex.is_valid()) {
- atlas_tex->remove_change_receptor(this);
+ atlas_tex->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed));
}
if (p_obj) {
node_sprite = Object::cast_to<Sprite2D>(p_obj);
@@ -853,7 +887,7 @@ void TextureRegionEditor::edit(Object *p_obj) {
if (Object::cast_to<AtlasTexture>(p_obj)) {
atlas_tex = Ref<AtlasTexture>(Object::cast_to<AtlasTexture>(p_obj));
}
- p_obj->add_change_receptor(this);
+ p_obj->connect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed));
_edit_region();
} else {
node_sprite = nullptr;
@@ -871,14 +905,11 @@ void TextureRegionEditor::edit(Object *p_obj) {
}
}
-void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+void TextureRegionEditor::_texture_changed() {
if (!is_visible()) {
return;
}
- String prop = p_prop;
- if (prop == "atlas" || prop == "texture" || prop == "region") {
- _edit_region();
- }
+ _edit_region();
}
void TextureRegionEditor::_edit_region() {
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index e9f58006a4..d3db0a08a9 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -117,6 +117,8 @@ class TextureRegionEditor : public VBoxContainer {
void _update_rect();
void _update_autoslice();
+ void _texture_changed();
+
protected:
void _notification(int p_what);
void _node_removed(Object *p_obj);
@@ -124,8 +126,6 @@ protected:
Vector2 snap_point(Vector2 p_target) const;
- virtual void _changed_callback(Object *p_changed, const char *p_prop) override;
-
public:
void _edit_region();
void _region_draw();
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index e6fb6ba22a..dfa8c04145 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index e374dd8714..ab199f8e51 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 49eb68c93a..74b01b3c36 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,7 +39,13 @@
#include "scene/gui/split_container.h"
void TileMapEditor::_node_removed(Node *p_node) {
- if (p_node == node) {
+ if (p_node == node && node) {
+ Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed);
+
+ if (node->is_connected("settings_changed", callable_tileset_settings_changed)) {
+ // Fixes #44824, which describes a situation where you can reselect a TileMap node without first de-selecting it when switching scenes.
+ node->disconnect("settings_changed", callable_tileset_settings_changed);
+ }
node = nullptr;
}
}
@@ -262,7 +268,7 @@ Vector<int> TileMapEditor::get_selected_tiles() const {
}
void TileMapEditor::set_selected_tiles(Vector<int> p_tiles) {
- palette->unselect_all();
+ palette->deselect_all();
for (int i = p_tiles.size() - 1; i >= 0; i--) {
int idx = palette->find_metadata(p_tiles[i]);
@@ -449,7 +455,7 @@ void TileMapEditor::_update_palette() {
List<int> tiles;
tileset->get_tile_list(&tiles);
- if (tiles.empty()) {
+ if (tiles.is_empty()) {
return;
}
@@ -1779,7 +1785,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
return;
}
- if (paint_undo.empty()) {
+ if (paint_undo.is_empty()) {
return;
}
@@ -1810,7 +1816,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
}
} else if (tool == TOOL_PASTING) {
- if (copydata.empty()) {
+ if (copydata.is_empty()) {
return;
}
@@ -1867,7 +1873,11 @@ void TileMapEditor::edit(Node *p_tile_map) {
}
if (node) {
- node->disconnect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed));
+ Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed);
+
+ if (node->is_connected("settings_changed", callable_tileset_settings_changed)) {
+ node->disconnect("settings_changed", callable_tileset_settings_changed);
+ }
}
if (p_tile_map) {
node = Object::cast_to<TileMap>(p_tile_map);
@@ -1894,7 +1904,11 @@ void TileMapEditor::edit(Node *p_tile_map) {
}
if (node) {
- node->connect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed));
+ Callable callable_tileset_settings_changed = callable_mp(this, &TileMapEditor::_tileset_settings_changed);
+
+ if (!node->is_connected("settings_changed", callable_tileset_settings_changed)) {
+ node->connect("settings_changed", callable_tileset_settings_changed);
+ }
}
_clear_bucket_cache();
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index 3a4cb22ac1..421a3b3f68 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 900a2c75a0..c628fe8367 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,7 +39,6 @@
void TileSetEditor::edit(const Ref<TileSet> &p_tileset) {
tileset = p_tileset;
- tileset->add_change_receptor(this);
texture_list->clear();
texture_map.clear();
@@ -1859,7 +1858,7 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
_update_toggle_shape_button();
workspace->update();
workspace_container->update();
- helper->_change_notify("");
+ helper->notify_property_list_changed();
}
} else if (p_tool == SELECT_NEXT) {
_select_next_shape();
@@ -2173,7 +2172,7 @@ Array TileSetEditor::_get_tiles_in_current_texture(bool sorted) {
}
}
if (sorted) {
- a.sort_custom(this, "_sort_tiles");
+ a.sort_custom(callable_mp(this, &TileSetEditor::_sort_tiles));
}
return a;
}
@@ -2287,7 +2286,7 @@ void TileSetEditor::_select_next_shape() {
}
workspace->update();
workspace_container->update();
- helper->_change_notify("");
+ helper->notify_property_list_changed();
}
}
@@ -2349,7 +2348,7 @@ void TileSetEditor::_select_previous_shape() {
}
workspace->update();
workspace_container->update();
- helper->_change_notify("");
+ helper->notify_property_list_changed();
}
}
@@ -3012,7 +3011,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
undo_redo->add_undo_method(this, "_select_edited_shape_coord");
undo_redo->commit_action();
}
- tileset->_change_notify("");
+ tileset->notify_property_list_changed();
}
void TileSetEditor::select_coord(const Vector2 &coord) {
@@ -3115,7 +3114,7 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
}
workspace->update();
workspace_container->update();
- helper->_change_notify("");
+ helper->notify_property_list_changed();
}
Vector2 TileSetEditor::snap_point(const Vector2 &point) {
@@ -3225,7 +3224,7 @@ void TileSetEditor::update_texture_list() {
workspace_overlay->update();
}
update_texture_list_icon();
- helper->_change_notify("");
+ helper->notify_property_list_changed();
}
void TileSetEditor::update_texture_list_icon() {
@@ -3389,7 +3388,7 @@ int TileSetEditor::get_current_tile() const {
void TileSetEditor::set_current_tile(int p_id) {
if (current_tile != p_id) {
current_tile = p_id;
- helper->_change_notify("");
+ helper->notify_property_list_changed();
select_coord(Vector2(0, 0));
update_workspace_tile_mode();
if (p_id == -1) {
@@ -3414,7 +3413,7 @@ void TilesetEditorContext::set_tileset(const Ref<TileSet> &p_tileset) {
void TilesetEditorContext::set_snap_options_visible(bool p_visible) {
snap_options_visible = p_visible;
- _change_notify("");
+ notify_property_list_changed();
}
bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value) {
@@ -3450,7 +3449,7 @@ bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value
tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/" + name2, p_value, &v);
}
if (v) {
- tileset->_change_notify("");
+ tileset->notify_property_list_changed();
tileset_editor->workspace->update();
tileset_editor->workspace_overlay->update();
}
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 72eb14941c..e778c18f44 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index 7747c740df..0af3b936cb 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h
index 3f107ddffb..7d7c66a7ee 100644
--- a/editor/plugins/version_control_editor_plugin.h
+++ b/editor/plugins/version_control_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 3820416c76..a63e641c2b 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,6 +44,7 @@
#include "scene/gui/panel.h"
#include "scene/main/window.h"
#include "scene/resources/visual_shader_nodes.h"
+#include "scene/resources/visual_shader_sdf_nodes.h"
#include "servers/display_server.h"
#include "servers/rendering/shader_types.h"
@@ -618,7 +619,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
if (vsnode->get_input_port_default_hint(i) != "" && !port_left_used) {
Label *hint_label = memnew(Label);
hint_label->set_text("[" + vsnode->get_input_port_default_hint(i) + "]");
- hint_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color("font_color_readonly", "TextEdit"));
+ hint_label->add_theme_color_override("font_color", VisualShaderEditor::get_singleton()->get_theme_color("font_readonly_color", "TextEdit"));
hint_label->add_theme_style_override("normal", label_style);
hb->add_child(hint_label);
}
@@ -1015,14 +1016,14 @@ void VisualShaderEditor::_update_options_menu() {
TreeItem *root = members->create_item();
String filter = node_filter->get_text().strip_edges();
- bool use_filter = !filter.empty();
+ bool use_filter = !filter.is_empty();
bool is_first_item = true;
Color unsupported_color = get_theme_color("error_color", "Editor");
Color supported_color = get_theme_color("warning_color", "Editor");
- static bool low_driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES2";
+ static bool low_driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "GLES2";
Map<String, TreeItem *> folders;
@@ -1281,6 +1282,9 @@ void VisualShaderEditor::_update_graph() {
graph->connect_node(itos(from), from_idx, itos(to), to_idx);
}
+
+ float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity");
+ graph->set_minimap_opacity(graph_minimap_opacity);
}
VisualShader::Type VisualShaderEditor::get_current_shader_type() const {
@@ -1733,114 +1737,220 @@ void VisualShaderEditor::_add_curve_node(const String &p_path) {
curve->set_texture(ResourceLoader::load(p_path));
}
-VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
- ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr);
+void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
+ // FLOAT_OP
+ {
+ VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(p_node);
- Ref<VisualShaderNode> vsnode;
+ if (floatOp) {
+ floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx);
+ return;
+ }
+ }
- bool is_custom = add_options[p_idx].is_custom;
+ // FLOAT_FUNC
+ {
+ VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(p_node);
- if (!is_custom && add_options[p_idx].type != String()) {
- VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type));
- ERR_FAIL_COND_V(!vsn, nullptr);
+ if (floatFunc) {
+ floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn);
+ // VECTOR_OP
+ {
+ VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(p_node);
- if (constant) {
- if ((int)add_options[p_idx].value != -1) {
- constant->set_constant(add_options[p_idx].value);
- }
+ if (vecOp) {
+ vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx);
+ return;
}
+ }
- if (p_op_idx != -1) {
- VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn);
+ // VECTOR_FUNC
+ {
+ VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(p_node);
- if (input) {
- input->set_input_name(add_options[p_idx].sub_func_str);
- }
+ if (vecFunc) {
+ vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(vsn);
+ // COLOR_OP
+ {
+ VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(p_node);
- if (is) {
- is->set_function((VisualShaderNodeIs::Function)p_op_idx);
- }
+ if (colorOp) {
+ colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(vsn);
+ // COLOR_FUNC
+ {
+ VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(p_node);
- if (cmp) {
- cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx);
- }
+ if (colorFunc) {
+ colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(vsn);
+ // INT_OP
+ {
+ VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(p_node);
- if (colorOp) {
- colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx);
- }
+ if (intOp) {
+ intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(vsn);
+ // INT_FUNC
+ {
+ VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(p_node);
- if (colorFunc) {
- colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx);
- }
+ if (intFunc) {
+ intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(vsn);
+ // TRANSFORM_FUNC
+ {
+ VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(p_node);
- if (floatOp) {
- floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx);
- }
+ if (matFunc) {
+ matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(vsn);
+ // IS
+ {
+ VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(p_node);
- if (intOp) {
- intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx);
- }
+ if (is) {
+ is->set_function((VisualShaderNodeIs::Function)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(vsn);
+ // COMPARE
+ {
+ VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(p_node);
- if (floatFunc) {
- floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx);
- }
+ if (cmp) {
+ cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(vsn);
+ // DERIVATIVE
+ {
+ VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(p_node);
- if (intFunc) {
- intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx);
- }
+ if (sderFunc) {
+ sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx);
+ return;
+ }
- VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(vsn);
+ VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(p_node);
- if (vecOp) {
- vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx);
- }
+ if (vderFunc) {
+ vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(vsn);
+ // MIX
+ {
+ VisualShaderNodeMix *mix = Object::cast_to<VisualShaderNodeMix>(p_node);
- if (vecFunc) {
- vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx);
- }
+ if (mix) {
+ mix->set_op_type((VisualShaderNodeMix::OpType)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(vsn);
+ // CLAMP
+ {
+ VisualShaderNodeClamp *clampFunc = Object::cast_to<VisualShaderNodeClamp>(p_node);
- if (matFunc) {
- matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx);
- }
+ if (clampFunc) {
+ clampFunc->set_op_type((VisualShaderNodeClamp::OpType)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(vsn);
+ // SWITCH
+ {
+ VisualShaderNodeSwitch *switchFunc = Object::cast_to<VisualShaderNodeSwitch>(p_node);
- if (sderFunc) {
- sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx);
- }
+ if (switchFunc) {
+ switchFunc->set_op_type((VisualShaderNodeSwitch::OpType)p_op_idx);
+ return;
+ }
+ }
- VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(vsn);
+ // SMOOTHSTEP
+ {
+ VisualShaderNodeSmoothStep *smoothStepFunc = Object::cast_to<VisualShaderNodeSmoothStep>(p_node);
- if (vderFunc) {
- vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx);
- }
+ if (smoothStepFunc) {
+ smoothStepFunc->set_op_type((VisualShaderNodeSmoothStep::OpType)p_op_idx);
+ return;
+ }
+ }
+
+ // STEP
+ {
+ VisualShaderNodeStep *stepFunc = Object::cast_to<VisualShaderNodeStep>(p_node);
+
+ if (stepFunc) {
+ stepFunc->set_op_type((VisualShaderNodeStep::OpType)p_op_idx);
+ return;
+ }
+ }
+
+ // MULTIPLY_ADD
+ {
+ VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(p_node);
+
+ if (fmaFunc) {
+ fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx);
+ }
+ }
+}
+
+VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
+ ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr);
+
+ Ref<VisualShaderNode> vsnode;
- VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(vsn);
+ bool is_custom = add_options[p_idx].is_custom;
- if (fmaFunc) {
- fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx);
+ if (!is_custom && add_options[p_idx].type != String()) {
+ VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type));
+ ERR_FAIL_COND_V(!vsn, nullptr);
+
+ VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn);
+
+ if (constant) {
+ if ((int)add_options[p_idx].value != -1) {
+ constant->set_constant(add_options[p_idx].value);
+ }
+ } else {
+ if (p_op_idx != -1) {
+ VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn);
+
+ if (input) {
+ input->set_input_name(add_options[p_idx].sub_func_str);
+ } else {
+ _setup_node(vsn, p_op_idx);
+ }
}
}
@@ -1879,28 +1989,95 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
undo_redo->add_do_method(expr, "set_size", Size2(250 * EDSCALE, 150 * EDSCALE));
}
+ bool created_expression_port = false;
+
if (to_node != -1 && to_slot != -1) {
- if (vsnode->get_output_port_count() > 0) {
+ VisualShaderNode::PortType input_port_type = visual_shader->get_node(type, to_node)->get_input_port_type(to_slot);
+
+ if (expr && expr->is_editable() && input_port_type != VisualShaderNode::PORT_TYPE_SAMPLER) {
+ undo_redo->add_do_method(expr, "add_output_port", 0, input_port_type, "output0");
+ undo_redo->add_undo_method(expr, "remove_output_port", 0);
+
+ String initial_expression_code;
+
+ switch (input_port_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR:
+ initial_expression_code = "output0 = 1.0;";
+ break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT:
+ initial_expression_code = "output0 = 1;";
+ break;
+ case VisualShaderNode::PORT_TYPE_VECTOR:
+ initial_expression_code = "output0 = vec3(1.0, 1.0, 1.0);";
+ break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN:
+ initial_expression_code = "output0 = true;";
+ break;
+ case VisualShaderNode::PORT_TYPE_TRANSFORM:
+ initial_expression_code = "output0 = mat4(1.0);";
+ break;
+ default:
+ break;
+ }
+
+ undo_redo->add_do_method(expr, "set_expression", initial_expression_code);
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, id_to_use);
+
+ created_expression_port = true;
+ }
+ if (vsnode->get_output_port_count() > 0 || created_expression_port) {
int _from_node = id_to_use;
int _from_slot = 0;
- if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(_from_slot), visual_shader->get_node(type, to_node)->get_input_port_type(to_slot))) {
+ if (created_expression_port) {
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot);
undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot);
undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, _from_slot, to_node, to_slot);
undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, _from_slot, to_node, to_slot);
+ } else {
+ // Attempting to connect to the first correct port.
+ for (int i = 0; i < vsnode->get_output_port_count(); i++) {
+ if (visual_shader->is_port_types_compatible(vsnode->get_output_port_type(i), input_port_type)) {
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot);
+ undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot);
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, _from_node, i, to_node, to_slot);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, _from_node, i, to_node, to_slot);
+ break;
+ }
+ }
}
}
} else if (from_node != -1 && from_slot != -1) {
- if (vsnode->get_input_port_count() > 0) {
+ VisualShaderNode::PortType output_port_type = visual_shader->get_node(type, from_node)->get_output_port_type(from_slot);
+
+ if (expr && expr->is_editable()) {
+ undo_redo->add_do_method(expr, "add_input_port", 0, output_port_type, "input0");
+ undo_redo->add_undo_method(expr, "remove_input_port", 0);
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, id_to_use);
+
+ created_expression_port = true;
+ }
+
+ if (vsnode->get_input_port_count() > 0 || created_expression_port) {
int _to_node = id_to_use;
int _to_slot = 0;
- if (visual_shader->is_port_types_compatible(visual_shader->get_node(type, from_node)->get_output_port_type(from_slot), vsnode->get_input_port_type(_to_slot))) {
+ if (created_expression_port) {
undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ } else {
+ // Attempting to connect to the first correct port.
+ for (int i = 0; i < vsnode->get_input_port_count(); i++) {
+ if (visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(i))) {
+ undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i);
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i);
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i);
+ break;
+ }
+ }
}
}
}
@@ -2087,6 +2264,197 @@ void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) {
}
}
+void VisualShaderEditor::_replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to) {
+ undo_redo->add_do_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_to);
+ undo_redo->add_undo_method(visual_shader.ptr(), "replace_node", p_type_id, p_node_id, p_from);
+}
+
+void VisualShaderEditor::_update_constant(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port) {
+ Ref<VisualShaderNode> node = visual_shader->get_node(p_type_id, p_node_id);
+ ERR_FAIL_COND(!node.is_valid());
+ ERR_FAIL_COND(!node->has_method("set_constant"));
+ node->call("set_constant", p_var);
+ if (p_preview_port != -1) {
+ node->set_output_port_for_preview(p_preview_port);
+ }
+}
+
+void VisualShaderEditor::_update_uniform(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port) {
+ Ref<VisualShaderNodeUniform> uniform = visual_shader->get_node(p_type_id, p_node_id);
+ ERR_FAIL_COND(!uniform.is_valid());
+
+ String valid_name = visual_shader->validate_uniform_name(uniform->get_uniform_name(), uniform);
+ uniform->set_uniform_name(valid_name);
+ graph_plugin->set_uniform_name(p_type_id, p_node_id, valid_name);
+
+ if (uniform->has_method("set_default_value_enabled")) {
+ uniform->call("set_default_value_enabled", true);
+ uniform->call("set_default_value", p_var);
+ }
+ if (p_preview_port != -1) {
+ uniform->set_output_port_for_preview(p_preview_port);
+ }
+}
+
+void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) {
+ VisualShader::Type type_id = get_current_shader_type();
+
+ if (!p_vice_versa) {
+ undo_redo->create_action(TTR("Convert Constant Node(s) To Uniform(s)"));
+ } else {
+ undo_redo->create_action(TTR("Convert Uniform Node(s) To Constant(s)"));
+ }
+
+ const Set<int> &current_set = p_vice_versa ? selected_uniforms : selected_constants;
+ Set<String> deleted_names;
+
+ for (Set<int>::Element *E = current_set.front(); E; E = E->next()) {
+ int node_id = E->get();
+ Ref<VisualShaderNode> node = visual_shader->get_node(type_id, node_id);
+ bool catched = false;
+ Variant var;
+
+ // float
+ if (!p_vice_versa) {
+ Ref<VisualShaderNodeFloatConstant> float_const = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr());
+ if (float_const.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeFloatConstant", "VisualShaderNodeFloatUniform");
+ var = float_const->get_constant();
+ catched = true;
+ }
+ } else {
+ Ref<VisualShaderNodeFloatUniform> float_uniform = Object::cast_to<VisualShaderNodeFloatUniform>(node.ptr());
+ if (float_uniform.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeFloatUniform", "VisualShaderNodeFloatConstant");
+ var = float_uniform->get_default_value();
+ catched = true;
+ }
+ }
+
+ // int
+ if (!catched) {
+ if (!p_vice_versa) {
+ Ref<VisualShaderNodeIntConstant> int_const = Object::cast_to<VisualShaderNodeIntConstant>(node.ptr());
+ if (int_const.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeIntConstant", "VisualShaderNodeIntUniform");
+ var = int_const->get_constant();
+ catched = true;
+ }
+ } else {
+ Ref<VisualShaderNodeIntUniform> int_uniform = Object::cast_to<VisualShaderNodeIntUniform>(node.ptr());
+ if (int_uniform.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeIntUniform", "VisualShaderNodeIntConstant");
+ var = int_uniform->get_default_value();
+ catched = true;
+ }
+ }
+ }
+
+ // boolean
+ if (!catched) {
+ if (!p_vice_versa) {
+ Ref<VisualShaderNodeBooleanConstant> boolean_const = Object::cast_to<VisualShaderNodeBooleanConstant>(node.ptr());
+ if (boolean_const.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeBooleanConstant", "VisualShaderNodeBooleanUniform");
+ var = boolean_const->get_constant();
+ catched = true;
+ }
+ } else {
+ Ref<VisualShaderNodeBooleanUniform> boolean_uniform = Object::cast_to<VisualShaderNodeBooleanUniform>(node.ptr());
+ if (boolean_uniform.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeBooleanUniform", "VisualShaderNodeBooleanConstant");
+ var = boolean_uniform->get_default_value();
+ catched = true;
+ }
+ }
+ }
+
+ // vec3
+ if (!catched) {
+ if (!p_vice_versa) {
+ Ref<VisualShaderNodeVec3Constant> vec3_const = Object::cast_to<VisualShaderNodeVec3Constant>(node.ptr());
+ if (vec3_const.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeVec3Constant", "VisualShaderNodeVec3Uniform");
+ var = vec3_const->get_constant();
+ catched = true;
+ }
+ } else {
+ Ref<VisualShaderNodeVec3Uniform> vec3_uniform = Object::cast_to<VisualShaderNodeVec3Uniform>(node.ptr());
+ if (vec3_uniform.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeVec3Uniform", "VisualShaderNodeVec3Constant");
+ var = vec3_uniform->get_default_value();
+ catched = true;
+ }
+ }
+ }
+
+ // color
+ if (!catched) {
+ if (!p_vice_versa) {
+ Ref<VisualShaderNodeColorConstant> color_const = Object::cast_to<VisualShaderNodeColorConstant>(node.ptr());
+ if (color_const.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeColorConstant", "VisualShaderNodeColorUniform");
+ var = color_const->get_constant();
+ catched = true;
+ }
+ } else {
+ Ref<VisualShaderNodeColorUniform> color_uniform = Object::cast_to<VisualShaderNodeColorUniform>(node.ptr());
+ if (color_uniform.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeColorUniform", "VisualShaderNodeColorConstant");
+ var = color_uniform->get_default_value();
+ catched = true;
+ }
+ }
+ }
+
+ // transform
+ if (!catched) {
+ if (!p_vice_versa) {
+ Ref<VisualShaderNodeTransformConstant> transform_const = Object::cast_to<VisualShaderNodeTransformConstant>(node.ptr());
+ if (transform_const.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeTransformConstant", "VisualShaderNodeTransformUniform");
+ var = transform_const->get_constant();
+ catched = true;
+ }
+ } else {
+ Ref<VisualShaderNodeTransformUniform> transform_uniform = Object::cast_to<VisualShaderNodeTransformUniform>(node.ptr());
+ if (transform_uniform.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeTransformUniform", "VisualShaderNodeTransformConstant");
+ var = transform_uniform->get_default_value();
+ catched = true;
+ }
+ }
+ }
+ ERR_CONTINUE(!catched);
+ int preview_port = node->get_output_port_for_preview();
+
+ if (!p_vice_versa) {
+ undo_redo->add_do_method(this, "_update_uniform", type_id, node_id, var, preview_port);
+ undo_redo->add_undo_method(this, "_update_constant", type_id, node_id, var, preview_port);
+ } else {
+ undo_redo->add_do_method(this, "_update_constant", type_id, node_id, var, preview_port);
+ undo_redo->add_undo_method(this, "_update_uniform", type_id, node_id, var, preview_port);
+
+ Ref<VisualShaderNodeUniform> uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr());
+ ERR_CONTINUE(!uniform.is_valid());
+
+ deleted_names.insert(uniform->get_uniform_name());
+ }
+
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type_id, node_id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type_id, node_id);
+ }
+
+ undo_redo->add_do_method(this, "_update_uniforms", true);
+ undo_redo->add_undo_method(this, "_update_uniforms", true);
+
+ if (deleted_names.size() > 0) {
+ _update_uniform_refs(deleted_names);
+ }
+
+ undo_redo->commit_action();
+}
+
void VisualShaderEditor::_delete_node_request(int p_type, int p_node) {
List<int> to_erase;
to_erase.push_back(p_node);
@@ -2108,7 +2476,7 @@ void VisualShaderEditor::_delete_nodes_request() {
}
}
- if (to_erase.empty()) {
+ if (to_erase.is_empty()) {
return;
}
@@ -2134,27 +2502,69 @@ void VisualShaderEditor::_node_selected(Object *p_node) {
void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
+ VisualShader::Type type = get_current_shader_type();
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
+ selected_constants.clear();
+ selected_uniforms.clear();
+
List<int> to_change;
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn) {
if (gn->is_selected() && gn->is_close_button_visible()) {
- to_change.push_back(gn->get_name().operator String().to_int());
+ int id = gn->get_name().operator String().to_int();
+ to_change.push_back(id);
+
+ Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
+ VisualShaderNodeConstant *cnode = Object::cast_to<VisualShaderNodeConstant>(node.ptr());
+ if (cnode != nullptr) {
+ selected_constants.insert(id);
+ }
+ VisualShaderNodeUniform *unode = Object::cast_to<VisualShaderNodeUniform>(node.ptr());
+ if (unode != nullptr) {
+ selected_uniforms.insert(id);
+ }
}
}
}
- if (to_change.empty() && copy_nodes_buffer.empty()) {
+ if (to_change.is_empty() && copy_nodes_buffer.is_empty()) {
_show_members_dialog(true);
} else {
- popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.empty());
- popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_nodes_buffer.empty());
- popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.empty());
- popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_nodes_buffer.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.is_empty());
+ popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.is_empty());
+
+ int temp = popup_menu->get_item_index(NodeMenuOptions::SEPARATOR2);
+ if (temp != -1) {
+ popup_menu->remove_item(temp);
+ }
+ temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS);
+ if (temp != -1) {
+ popup_menu->remove_item(temp);
+ }
+ temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS);
+ if (temp != -1) {
+ popup_menu->remove_item(temp);
+ }
+
+ if (selected_constants.size() > 0 || selected_uniforms.size() > 0) {
+ popup_menu->add_separator("", NodeMenuOptions::SEPARATOR2);
+
+ if (selected_constants.size() > 0) {
+ popup_menu->add_item(TTR("Convert Constant(s) to Uniform(s)"), NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS);
+ }
+
+ if (selected_uniforms.size() > 0) {
+ popup_menu->add_item(TTR("Convert Uniforms(s) to Constant(s)"), NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS);
+ }
+ }
+
menu_point = graph->get_local_mouse_position();
Point2 gpos = Input::get_singleton()->get_mouse_position();
popup_menu->set_position(gpos);
+ popup_menu->set_size(Size2(-1, -1));
popup_menu->popup();
}
}
@@ -2445,7 +2855,7 @@ void VisualShaderEditor::_duplicate_nodes() {
_dup_copy_nodes(type, nodes, excluded);
- if (nodes.empty()) {
+ if (nodes.is_empty()) {
return;
}
@@ -2463,7 +2873,7 @@ void VisualShaderEditor::_copy_nodes() {
}
void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2 &p_custom_position) {
- if (copy_nodes_buffer.empty()) {
+ if (copy_nodes_buffer.is_empty()) {
return;
}
@@ -2695,6 +3105,14 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) {
case NodeMenuOptions::DUPLICATE:
_duplicate_nodes();
break;
+ case NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS:
+ _convert_constants_to_uniforms(false);
+ break;
+ case NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS:
+ _convert_constants_to_uniforms(true);
+ break;
+ default:
+ break;
}
}
@@ -2799,15 +3217,35 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
void VisualShaderEditor::_show_preview_text() {
preview_showed = !preview_showed;
- preview_vbox->set_visible(preview_showed);
if (preview_showed) {
+ if (preview_first) {
+ preview_window->set_size(Size2(400 * EDSCALE, 600 * EDSCALE));
+ preview_window->popup_centered();
+ preview_first = false;
+ } else {
+ preview_window->popup();
+ }
+ _preview_size_changed();
+
if (pending_update_preview) {
_update_preview();
pending_update_preview = false;
}
+ } else {
+ preview_window->hide();
}
}
+void VisualShaderEditor::_preview_close_requested() {
+ preview_showed = false;
+ preview_window->hide();
+ preview_shader->set_pressed(false);
+}
+
+void VisualShaderEditor::_preview_size_changed() {
+ preview_vbox->set_custom_minimum_size(preview_window->get_size());
+}
+
static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) {
RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable);
return RS::global_variable_type_get_shader_datatype(gvt);
@@ -2843,6 +3281,16 @@ void VisualShaderEditor::_update_preview() {
}
}
+void VisualShaderEditor::_visibility_changed() {
+ if (!is_visible()) {
+ if (preview_window->is_visible()) {
+ preview_shader->set_pressed(false);
+ preview_window->hide();
+ preview_showed = false;
+ }
+ }
+}
+
void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph);
ClassDB::bind_method("_update_options_menu", &VisualShaderEditor::_update_options_menu);
@@ -2856,6 +3304,8 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_set_mode", &VisualShaderEditor::_set_mode);
ClassDB::bind_method("_nodes_dragged", &VisualShaderEditor::_nodes_dragged);
ClassDB::bind_method("_float_constant_selected", &VisualShaderEditor::_float_constant_selected);
+ ClassDB::bind_method("_update_constant", &VisualShaderEditor::_update_constant);
+ ClassDB::bind_method("_update_uniform", &VisualShaderEditor::_update_uniform);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
@@ -2873,7 +3323,6 @@ VisualShaderEditor::VisualShaderEditor() {
saved_node_pos = Point2(0, 0);
ShaderLanguage::get_keyword_list(&keyword_list);
- preview_showed = false;
pending_update_preview = false;
shader_error = false;
@@ -2882,17 +3331,14 @@ VisualShaderEditor::VisualShaderEditor() {
from_node = -1;
from_slot = -1;
- main_box = memnew(HSplitContainer);
- main_box->set_v_size_flags(SIZE_EXPAND_FILL);
- main_box->set_h_size_flags(SIZE_EXPAND_FILL);
- add_child(main_box);
-
graph = memnew(GraphEdit);
graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL);
graph->set_v_size_flags(SIZE_EXPAND_FILL);
graph->set_h_size_flags(SIZE_EXPAND_FILL);
- main_box->add_child(graph);
+ add_child(graph);
graph->set_drag_forwarding(this);
+ float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity");
+ graph->set_minimap_opacity(graph_minimap_opacity);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN);
@@ -2912,6 +3358,7 @@ VisualShaderEditor::VisualShaderEditor() {
graph->connect("gui_input", callable_mp(this, &VisualShaderEditor::_graph_gui_input));
graph->connect("connection_to_empty", callable_mp(this, &VisualShaderEditor::_connection_to_empty));
graph->connect("connection_from_empty", callable_mp(this, &VisualShaderEditor::_connection_from_empty));
+ graph->connect("visibility_changed", callable_mp(this, &VisualShaderEditor::_visibility_changed));
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR);
@@ -2966,29 +3413,35 @@ VisualShaderEditor::VisualShaderEditor() {
preview_shader = memnew(Button);
preview_shader->set_flat(true);
preview_shader->set_toggle_mode(true);
- preview_shader->set_tooltip(TTR("Show resulted shader code."));
+ preview_shader->set_tooltip(TTR("Show generated shader code."));
graph->get_zoom_hbox()->add_child(preview_shader);
preview_shader->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_preview_text));
///////////////////////////////////////
- // PREVIEW PANEL
+ // PREVIEW WINDOW
///////////////////////////////////////
+ preview_window = memnew(Window);
+ preview_window->set_title(TTR("Generated shader code"));
+ preview_window->set_visible(preview_showed);
+ preview_window->connect("close_requested", callable_mp(this, &VisualShaderEditor::_preview_close_requested));
+ preview_window->connect("size_changed", callable_mp(this, &VisualShaderEditor::_preview_size_changed));
+ add_child(preview_window);
+
preview_vbox = memnew(VBoxContainer);
- preview_vbox->set_visible(preview_showed);
- main_box->add_child(preview_vbox);
+ preview_window->add_child(preview_vbox);
+
preview_text = memnew(CodeEdit);
syntax_highlighter.instance();
preview_vbox->add_child(preview_text);
- preview_text->set_h_size_flags(SIZE_EXPAND_FILL);
- preview_text->set_v_size_flags(SIZE_EXPAND_FILL);
- preview_text->set_custom_minimum_size(Size2(400 * EDSCALE, 0));
+ preview_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
preview_text->set_syntax_highlighter(syntax_highlighter);
preview_text->set_draw_line_numbers(true);
preview_text->set_readonly(true);
error_text = memnew(Label);
preview_vbox->add_child(error_text);
+ error_text->set_autowrap(true);
error_text->set_visible(false);
///////////////////////////////////////
@@ -2997,12 +3450,12 @@ VisualShaderEditor::VisualShaderEditor() {
popup_menu = memnew(PopupMenu);
add_child(popup_menu);
- popup_menu->add_item("Add Node", NodeMenuOptions::ADD);
+ popup_menu->add_item(TTR("Add Node"), NodeMenuOptions::ADD);
popup_menu->add_separator();
- popup_menu->add_item("Copy", NodeMenuOptions::COPY);
- popup_menu->add_item("Paste", NodeMenuOptions::PASTE);
- popup_menu->add_item("Delete", NodeMenuOptions::DELETE);
- popup_menu->add_item("Duplicate", NodeMenuOptions::DUPLICATE);
+ popup_menu->add_item(TTR("Copy"), NodeMenuOptions::COPY);
+ popup_menu->add_item(TTR("Paste"), NodeMenuOptions::PASTE);
+ popup_menu->add_item(TTR("Delete"), NodeMenuOptions::DELETE);
+ popup_menu->add_item(TTR("Duplicate"), NodeMenuOptions::DUPLICATE);
popup_menu->connect("id_pressed", callable_mp(this, &VisualShaderEditor::_node_menu_id_pressed));
///////////////////////////////////////
@@ -3121,8 +3574,11 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), VisualShaderNodeCompare::FUNC_LESS_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), VisualShaderNodeCompare::FUNC_NOT_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SwitchS", "Conditional", "Functions", "VisualShaderNodeScalarSwitch", TTR("Returns an associated scalar if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SwitchBool", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("SwitchFloat", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("SwitchInt", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated integer scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("SwitchTransform", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated transform if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
@@ -3345,8 +3801,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeScalarClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Constrains a value to lie between two further values."), VisualShaderNodeIntFunc::FUNC_CLAMP, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeFloatFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -3359,7 +3815,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 logarithm."), VisualShaderNodeFloatFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Max", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the greater of two values."), VisualShaderNodeFloatOp::OP_MAX, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Min", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the lesser of two values."), VisualShaderNodeFloatOp::OP_MIN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeScalarInterp", TTR("Linear interpolation between two scalars."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two scalars."), VisualShaderNodeMix::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("MultiplyAdd", "Scalar", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on scalars."), VisualShaderNodeMultiplyAdd::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeFloatFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeIntFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR_INT));
@@ -3375,8 +3831,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeFloatFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeFloatOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeFloatFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -3397,7 +3853,17 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ // SDF
+ {
+ add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ }
+
// TEXTURES
+
cubemap_node_option_idx = add_options.size();
add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1));
curve_node_option_idx = add_options.size();
@@ -3450,7 +3916,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeVectorClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNode::PORT_TYPE_VECTOR));
@@ -3468,8 +3934,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), VisualShaderNodeVectorOp::OP_MAX, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), VisualShaderNodeVectorOp::OP_MIN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeVectorInterp", TTR("Linear interpolation between two vectors."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeVectorScalarMix", TTR("Linear interpolation between two vectors using scalar."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), VisualShaderNodeMix::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), VisualShaderNodeMix::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNode::PORT_TYPE_VECTOR));
@@ -3486,10 +3952,10 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR));
@@ -4007,10 +4473,17 @@ void VisualShaderNodePortPreview::_shader_changed() {
for (int i = EditorNode::get_singleton()->get_editor_history()->get_path_size() - 1; i >= 0; i--) {
Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(i));
+ ShaderMaterial *src_mat;
if (!object) {
continue;
}
- ShaderMaterial *src_mat = Object::cast_to<ShaderMaterial>(object);
+ if (object->has_method("get_material_override")) { // trying getting material from MeshInstance
+ src_mat = Object::cast_to<ShaderMaterial>(object->call("get_material_override"));
+ } else if (object->has_method("get_material")) { // from CanvasItem/Node2D
+ src_mat = Object::cast_to<ShaderMaterial>(object->call("get_material"));
+ } else {
+ src_mat = Object::cast_to<ShaderMaterial>(object);
+ }
if (src_mat && src_mat->get_shader().is_valid()) {
List<PropertyInfo> params;
src_mat->get_shader()->get_param_list(&params);
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index a5983410f9..182bed6ba6 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -134,7 +134,6 @@ class VisualShaderEditor : public VBoxContainer {
int editing_port;
Ref<VisualShader> visual_shader;
- HSplitContainer *main_box;
GraphEdit *graph;
Button *add_node;
Button *preview_shader;
@@ -148,6 +147,7 @@ class VisualShaderEditor : public VBoxContainer {
bool pending_update_preview;
bool shader_error;
+ Window *preview_window;
VBoxContainer *preview_vbox;
CodeEdit *preview_text;
Ref<CodeHighlighter> syntax_highlighter;
@@ -161,7 +161,8 @@ class VisualShaderEditor : public VBoxContainer {
PopupMenu *popup_menu;
MenuButton *tools;
- bool preview_showed;
+ bool preview_first = true;
+ bool preview_showed = false;
bool particles_mode;
enum TypeFlags {
@@ -188,6 +189,9 @@ class VisualShaderEditor : public VBoxContainer {
PASTE,
DELETE,
DUPLICATE,
+ SEPARATOR2, // ignore
+ CONVERT_CONSTANTS_TO_UNIFORMS,
+ CONVERT_UNIFORMS_TO_CONSTANTS,
};
Tree *members;
@@ -272,11 +276,14 @@ class VisualShaderEditor : public VBoxContainer {
void _add_texture3d_node(const String &p_path);
void _add_curve_node(const String &p_path);
+ void _setup_node(VisualShaderNode *p_node, int p_op_idx);
VisualShaderNode *_add_node(int p_idx, int p_op_idx = -1);
void _update_options_menu();
void _set_mode(int p_which);
void _show_preview_text();
+ void _preview_close_requested();
+ void _preview_size_changed();
void _update_preview();
String _get_description(int p_idx);
@@ -316,6 +323,14 @@ class VisualShaderEditor : public VBoxContainer {
int from_node;
int from_slot;
+ Set<int> selected_constants;
+ Set<int> selected_uniforms;
+
+ void _convert_constants_to_uniforms(bool p_vice_versa);
+ void _replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to);
+ void _update_constant(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port);
+ void _update_uniform(VisualShader::Type p_type_id, int p_node_id, Variant p_var, int p_preview_port);
+
void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position);
void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position);
@@ -388,6 +403,8 @@ class VisualShaderEditor : public VBoxContainer {
void _update_uniforms(bool p_update_refs);
void _update_uniform_refs(Set<String> &p_names);
+ void _visibility_changed();
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/pot_generator.cpp b/editor/pot_generator.cpp
index 9b3227ad28..497cc0cbdc 100644
--- a/editor/pot_generator.cpp
+++ b/editor/pot_generator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,7 +55,7 @@ void POTGenerator::_print_all_translation_strings() {
#endif
void POTGenerator::generate_pot(const String &p_file) {
- if (!ProjectSettings::get_singleton()->has_setting("locale/translations_pot_files")) {
+ if (!ProjectSettings::get_singleton()->has_setting("internationalization/locale/translations_pot_files")) {
WARN_PRINT("No files selected for POT generation.");
return;
}
@@ -63,7 +63,7 @@ void POTGenerator::generate_pot(const String &p_file) {
// Clear all_translation_strings of the previous round.
all_translation_strings.clear();
- Vector<String> files = ProjectSettings::get_singleton()->get("locale/translations_pot_files");
+ Vector<String> files = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files");
// Collect all translatable strings according to files order in "POT Generation" setting.
for (int i = 0; i < files.size(); i++) {
@@ -100,7 +100,7 @@ void POTGenerator::_write_to_pot(const String &p_file) {
}
String project_name = ProjectSettings::get_singleton()->get("application/config/name");
- Vector<String> files = ProjectSettings::get_singleton()->get("locale/translations_pot_files");
+ Vector<String> files = ProjectSettings::get_singleton()->get("internationalization/locale/translations_pot_files");
String extracted_files = "";
for (int i = 0; i < files.size(); i++) {
extracted_files += "# " + files[i] + "\n";
@@ -135,7 +135,7 @@ void POTGenerator::_write_to_pot(const String &p_file) {
}
// Write context.
- if (!context.empty()) {
+ if (!context.is_empty()) {
file->store_line("msgctxt \"" + context + "\"");
}
@@ -143,7 +143,7 @@ void POTGenerator::_write_to_pot(const String &p_file) {
_write_msgid(file, msgid, false);
// Write msgid_plural
- if (!plural.empty()) {
+ if (!plural.is_empty()) {
_write_msgid(file, plural, true);
file->store_line("msgstr[0] \"\"");
file->store_line("msgstr[1] \"\"\n");
@@ -185,7 +185,7 @@ void POTGenerator::_add_new_msgid(const String &p_msgid, const String &p_context
Vector<MsgidData> &v_mdata = all_translation_strings[p_msgid];
for (int i = 0; i < v_mdata.size(); i++) {
if (v_mdata[i].ctx == p_context) {
- if (!v_mdata[i].plural.empty() && !p_plural.empty() && v_mdata[i].plural != p_plural) {
+ if (!v_mdata[i].plural.is_empty() && !p_plural.is_empty() && v_mdata[i].plural != p_plural) {
WARN_PRINT("Redefinition of plural message (msgid_plural), under the same message (msgid) and context (msgctxt)");
}
v_mdata.write[i].locations.insert(p_location);
diff --git a/editor/pot_generator.h b/editor/pot_generator.h
index 1fd2956445..ab055e0c0e 100644
--- a/editor/pot_generator.h
+++ b/editor/pot_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp
index a37f4776ac..0b6a3798b3 100644
--- a/editor/progress_dialog.cpp
+++ b/editor/progress_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -111,7 +111,7 @@ void BackgroundProgress::task_step(const String &p_task, int p_step) {
bool no_updates = true;
{
_THREAD_SAFE_METHOD_
- no_updates = updates.empty();
+ no_updates = updates.is_empty();
}
if (no_updates) {
@@ -218,7 +218,7 @@ void ProgressDialog::end_task(const String &p_task) {
memdelete(t.vb);
tasks.erase(p_task);
- if (tasks.empty()) {
+ if (tasks.is_empty()) {
hide();
} else {
_popup();
diff --git a/editor/progress_dialog.h b/editor/progress_dialog.h
index d8a33cc2cc..3f4b1d2944 100644
--- a/editor/progress_dialog.h
+++ b/editor/progress_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 68710920a5..4bcb616fbd 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -196,7 +196,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
export_path->hide();
runnable->set_disabled(true);
parameters->edit(nullptr);
- presets->unselect_all();
+ presets->deselect_all();
duplicate_preset->set_disabled(true);
delete_preset->set_disabled(true);
sections->hide();
@@ -516,7 +516,7 @@ void ProjectExportDialog::_script_encryption_key_changed(const String &p_key) {
bool ProjectExportDialog::_validate_script_encryption_key(const String &p_key) {
bool is_valid = false;
- if (!p_key.empty() && p_key.is_valid_hex_number(false) && p_key.length() == 64) {
+ if (!p_key.is_empty() && p_key.is_valid_hex_number(false) && p_key.length() == 64) {
is_valid = true;
}
return is_valid;
@@ -830,6 +830,12 @@ void ProjectExportDialog::_refresh_parent_checks(TreeItem *p_item) {
}
void ProjectExportDialog::_export_pck_zip() {
+ Ref<EditorExportPreset> current = get_current_preset();
+ ERR_FAIL_COND(current.is_null());
+
+ String dir = current->get_export_path().get_base_dir();
+ export_pck_zip->set_current_dir(dir);
+
export_pck_zip->popup_file_dialog();
}
diff --git a/editor/project_export.h b/editor/project_export.h
index b8ca0dd9f2..cfd4934c34 100644
--- a/editor/project_export.h
+++ b/editor/project_export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 3068bdd672..7d421bdf81 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -474,15 +474,15 @@ private:
}
ProjectSettings::CustomMap initial_settings;
if (rasterizer_button_group->get_pressed_button()->get_meta("driver_name") == "Vulkan") {
- initial_settings["rendering/quality/driver/driver_name"] = "Vulkan";
+ initial_settings["rendering/driver/driver_name"] = "Vulkan";
} else {
- initial_settings["rendering/quality/driver/driver_name"] = "GLES2";
- initial_settings["rendering/vram_compression/import_etc2"] = false;
- initial_settings["rendering/vram_compression/import_etc"] = true;
+ initial_settings["rendering/driver/driver_name"] = "GLES2";
+ initial_settings["rendering/textures/vram_compression/import_etc2"] = false;
+ initial_settings["rendering/textures/vram_compression/import_etc"] = true;
}
initial_settings["application/config/name"] = project_name->get_text();
initial_settings["application/config/icon"] = "res://icon.png";
- initial_settings["rendering/environment/default_environment"] = "res://default_env.tres";
+ initial_settings["rendering/environment/defaults/default_environment"] = "res://default_env.tres";
if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector<String>(), false) != OK) {
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
@@ -1297,9 +1297,7 @@ void ProjectList::_global_menu_new_window(const Variant &p_tag) {
List<String> args;
args.push_back("-p");
String exec = OS::get_singleton()->get_executable_path();
-
- OS::ProcessID pid = 0;
- OS::get_singleton()->execute(exec, args, false, &pid);
+ OS::get_singleton()->create_process(exec, args);
}
void ProjectList::_global_menu_open_project(const Variant &p_tag) {
@@ -1310,9 +1308,7 @@ void ProjectList::_global_menu_open_project(const Variant &p_tag) {
List<String> args;
args.push_back(conf);
String exec = OS::get_singleton()->get_executable_path();
-
- OS::ProcessID pid = 0;
- OS::get_singleton()->execute(exec, args, false, &pid);
+ OS::get_singleton()->create_process(exec, args);
}
}
@@ -1379,11 +1375,10 @@ void ProjectList::create_project_item_control(int p_index) {
vb->add_child(path_hb);
Button *show = memnew(Button);
- // Display a folder icon if the project directory can be opened, or a "broken file" icon if it can't
+ // Display a folder icon if the project directory can be opened, or a "broken file" icon if it can't.
show->set_icon(get_theme_icon(!item.missing ? "Load" : "FileBroken", "EditorIcons"));
- show->set_flat(true);
if (!item.grayed) {
- // Don't make the icon less prominent if the parent is already grayed out
+ // Don't make the icon less prominent if the parent is already grayed out.
show->set_modulate(Color(1, 1, 1, 0.5));
}
path_hb->add_child(show);
@@ -1545,7 +1540,7 @@ bool ProjectList::is_any_project_missing() const {
}
void ProjectList::erase_missing_projects() {
- if (_projects.empty()) {
+ if (_projects.is_empty()) {
return;
}
@@ -1875,7 +1870,7 @@ void ProjectManager::_dim_window() {
void ProjectManager::_update_project_buttons() {
Vector<ProjectList::Item> selected_projects = _project_list->get_selected_projects();
- bool empty_selection = selected_projects.empty();
+ bool empty_selection = selected_projects.is_empty();
bool is_missing_project_selected = false;
for (int i = 0; i < selected_projects.size(); ++i) {
@@ -2020,6 +2015,10 @@ void ProjectManager::_confirm_update_settings() {
}
void ProjectManager::_open_selected_projects() {
+ // Show loading text to tell the user that the project manager is busy loading.
+ // This is especially important for the HTML5 project manager.
+ loading_label->set_modulate(Color(1, 1, 1));
+
const Set<String> &selected_list = _project_list->get_selected_project_keys();
for (const Set<String>::Element *E = selected_list.front(); E; E = E->next()) {
@@ -2055,9 +2054,7 @@ void ProjectManager::_open_selected_projects() {
}
String exec = OS::get_singleton()->get_executable_path();
-
- OS::ProcessID pid = 0;
- Error err = OS::get_singleton()->execute(exec, args, false, &pid);
+ Error err = OS::get_singleton()->create_process(exec, args);
ERR_FAIL_COND(err);
}
@@ -2143,9 +2140,7 @@ void ProjectManager::_run_project_confirm() {
}
String exec = OS::get_singleton()->get_executable_path();
-
- OS::ProcessID pid = 0;
- Error err = OS::get_singleton()->execute(exec, args, false, &pid);
+ Error err = OS::get_singleton()->create_process(exec, args);
ERR_FAIL_COND(err);
}
}
@@ -2166,8 +2161,9 @@ void ProjectManager::_run_project() {
}
void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) {
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->change_dir(path);
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ Error error = da->change_dir(path);
+ ERR_FAIL_COND_MSG(error != OK, "Could not scan directory at: " + path);
da->list_dir_begin();
String n = da->get_next();
while (n != String()) {
@@ -2179,7 +2175,6 @@ void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) {
n = da->get_next();
}
da->list_dir_end();
- memdelete(da);
}
void ProjectManager::_scan_begin(const String &p_base) {
@@ -2270,19 +2265,13 @@ void ProjectManager::_language_selected(int p_id) {
void ProjectManager::_restart_confirm() {
List<String> args = OS::get_singleton()->get_cmdline_args();
String exec = OS::get_singleton()->get_executable_path();
- OS::ProcessID pid = 0;
- Error err = OS::get_singleton()->execute(exec, args, false, &pid);
+ Error err = OS::get_singleton()->create_process(exec, args);
ERR_FAIL_COND(err);
_dim_window();
get_tree()->quit();
}
-void ProjectManager::_exit_dialog() {
- _dim_window();
- get_tree()->quit();
-}
-
void ProjectManager::_install_project(const String &p_zip_path, const String &p_title) {
npdialog->set_mode(ProjectDialog::MODE_INSTALL);
npdialog->set_zip_path(p_zip_path);
@@ -2291,6 +2280,11 @@ void ProjectManager::_install_project(const String &p_zip_path, const String &p_
}
void ProjectManager::_files_dropped(PackedStringArray p_files, int p_screen) {
+ if (p_files.size() == 1 && p_files[0].ends_with(".zip")) {
+ const String file = p_files[0].get_file();
+ _install_project(p_files[0], file.substr(0, file.length() - 4).capitalize());
+ return;
+ }
Set<String> folders_set;
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < p_files.size(); i++) {
@@ -2356,7 +2350,6 @@ void ProjectManager::_on_search_term_changed(const String &p_term) {
}
void ProjectManager::_bind_methods() {
- ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog);
ClassDB::bind_method("_unhandled_key_input", &ProjectManager::_unhandled_key_input);
ClassDB::bind_method("_update_project_buttons", &ProjectManager::_update_project_buttons);
}
@@ -2380,6 +2373,8 @@ ProjectManager::ProjectManager() {
switch (display_scale) {
case 0: {
// Try applying a suitable display scale automatically.
+ // The code below is adapted in `editor/editor_settings.cpp` and `editor/editor_node.cpp`.
+ // Make sure to update those when modifying the code below.
#ifdef OSX_ENABLED
editor_set_scale(DisplayServer::get_singleton()->screen_get_max_scale());
#else
@@ -2388,6 +2383,10 @@ ProjectManager::ProjectManager() {
if (DisplayServer::get_singleton()->screen_get_dpi(screen) >= 192 && DisplayServer::get_singleton()->screen_get_size(screen).y >= 1400) {
// hiDPI display.
scale = 2.0;
+ } else if (DisplayServer::get_singleton()->screen_get_size(screen).y >= 1700) {
+ // Likely a hiDPI display, but we aren't certain due to the returned DPI.
+ // Use an intermediate scale to handle this situation.
+ scale = 1.5;
} else if (DisplayServer::get_singleton()->screen_get_size(screen).y <= 800) {
// Small loDPI display. Use a smaller display scale so that editor elements fit more easily.
// Icons won't look great, but this is better than having editor elements overflow from its window.
@@ -2433,9 +2432,9 @@ ProjectManager::ProjectManager() {
// TRANSLATORS: This refers to the application where users manage their Godot projects.
if (TS->is_locale_right_to_left(TranslationServer::get_singleton()->get_tool_locale())) {
// For RTL languages, embed translated part of the title (using control characters) to ensure correct order.
- DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + String::chr(0x202B) + TTR("Project Manager") + String::chr(0x202C) + String::chr(0x200E) + " - " + String::chr(0xA9) + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors");
+ DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + String::chr(0x202B) + TTR("Project Manager") + String::chr(0x202C) + String::chr(0x200E) + " - " + String::chr(0xA9) + " 2007-2021 Juan Linietsky, Ariel Manzur & Godot Contributors");
} else {
- DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + String::chr(0xA9) + " 2007-2020 Juan Linietsky, Ariel Manzur & Godot Contributors");
+ DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + String::chr(0xA9) + " 2007-2021 Juan Linietsky, Ariel Manzur & Godot Contributors");
}
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
@@ -2484,7 +2483,12 @@ ProjectManager::ProjectManager() {
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hb->add_child(search_box);
- hb->add_spacer();
+ loading_label = memnew(Label(TTR("Loading, please wait...")));
+ loading_label->add_theme_font_override("font", get_theme_font("bold", "EditorFonts"));
+ loading_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ hb->add_child(loading_label);
+ // Hide the label but make it still take up space. This prevents reflows when showing the label.
+ loading_label->set_modulate(Color(0, 0, 0, 0));
Label *sort_label = memnew(Label);
sort_label->set_text(TTR("Sort:"));
@@ -2691,8 +2695,26 @@ ProjectManager::ProjectManager() {
_load_recent_projects();
- if (EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path")) {
- _scan_begin(EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path"));
+ DirAccessRef dir_access = DirAccess::create(DirAccess::AccessType::ACCESS_FILESYSTEM);
+
+ String default_project_path = EditorSettings::get_singleton()->get("filesystem/directories/default_project_path");
+ if (!dir_access->dir_exists(default_project_path)) {
+ Error error = dir_access->make_dir_recursive(default_project_path);
+ if (error != OK) {
+ ERR_PRINT("Could not create default project directory at: " + default_project_path);
+ }
+ }
+
+ String autoscan_path = EditorSettings::get_singleton()->get("filesystem/directories/autoscan_project_path");
+ if (autoscan_path != "") {
+ if (dir_access->dir_exists(autoscan_path)) {
+ _scan_begin(autoscan_path);
+ } else {
+ Error error = dir_access->make_dir_recursive(autoscan_path);
+ if (error != OK) {
+ ERR_PRINT("Could not create project autoscan directory at: " + autoscan_path);
+ }
+ }
}
SceneTree::get_singleton()->get_root()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped));
diff --git a/editor/project_manager.h b/editor/project_manager.h
index 0eb063e196..6dc0e67cba 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,6 +54,7 @@ class ProjectManager : public Control {
ProjectList *_project_list;
LineEdit *search_box;
+ Label *loading_label;
OptionButton *filter_option;
Button *run_btn;
@@ -98,7 +99,6 @@ class ProjectManager : public Control {
void _update_project_buttons();
void _language_selected(int p_id);
void _restart_confirm();
- void _exit_dialog();
void _confirm_update_settings();
void _nonempty_confirmation_ok_pressed();
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 9995c6ad65..de7996eaa2 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -52,9 +52,11 @@ void ProjectSettingsEditor::popup_project_settings() {
localization_editor->update_translations();
autoload_settings->update_autoload();
plugin_settings->update_plugins();
+ import_defaults_editor->clear();
}
void ProjectSettingsEditor::queue_save() {
+ EditorNode::get_singleton()->notify_settings_changed();
timer->start();
}
@@ -74,8 +76,12 @@ void ProjectSettingsEditor::_advanced_pressed() {
if (advanced->is_pressed()) {
_update_advanced_bar();
advanced_bar->show();
+ EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", true);
+ inspector->set_restrict_to_basic_settings(false);
} else {
advanced_bar->hide();
+ EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", false);
+ inspector->set_restrict_to_basic_settings(true);
}
}
@@ -156,7 +162,7 @@ void ProjectSettingsEditor::_update_advanced_bar() {
bool disable_add = true;
bool disable_del = true;
- if (!property_box->get_text().empty()) {
+ if (!property_box->get_text().is_empty()) {
const String setting = _get_setting_name();
bool setting_exists = ps->has_setting(setting);
if (setting_exists) {
@@ -190,14 +196,11 @@ void ProjectSettingsEditor::_update_advanced_bar() {
add_button->set_disabled(disable_add);
del_button->set_disabled(disable_del);
-
- error_label->set_text(error_msg);
- error_label->set_visible(error_msg != "");
}
String ProjectSettingsEditor::_get_setting_name() const {
const String cat = category_box->get_text();
- const String name = (cat.empty() ? "global" : cat.strip_edges()).plus_file(property_box->get_text().strip_edges());
+ const String name = (cat.is_empty() ? "global" : cat.strip_edges()).plus_file(property_box->get_text().strip_edges());
const String feature = feature_override->get_item_text(feature_override->get_selected());
return (feature == "") ? name : (name + "." + feature);
@@ -255,6 +258,7 @@ void ProjectSettingsEditor::_add_feature_overrides() {
}
void ProjectSettingsEditor::_editor_restart() {
+ ProjectSettings::get_singleton()->save();
EditorNode::get_singleton()->save_all_scenes();
EditorNode::get_singleton()->restart_editor();
}
@@ -267,21 +271,216 @@ void ProjectSettingsEditor::_editor_restart_close() {
restart_container->hide();
}
+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;
+ }
+
+ Dictionary action;
+ action["events"] = Array();
+ action["deadzone"] = 0.5f;
+
+ undo_redo->create_action(TTR("Add Input Action"));
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name);
+
+ undo_redo->add_do_method(this, "_update_action_map_editor");
+ undo_redo->add_undo_method(this, "_update_action_map_editor");
+ undo_redo->add_do_method(this, "queue_save");
+ undo_redo->add_undo_method(this, "queue_save");
+ undo_redo->commit_action();
+}
+
+void ProjectSettingsEditor::_action_edited(const String &p_name, const Dictionary &p_action) {
+ const String property_name = "input/" + p_name;
+ Dictionary old_val = ProjectSettings::get_singleton()->get(property_name);
+
+ if (old_val["deadzone"] != p_action["deadzone"]) {
+ // Deadzone Changed
+ undo_redo->create_action(TTR("Change Action deadzone"));
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", property_name, p_action);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val);
+
+ } else {
+ // Events changed
+ int event_count = ((Array)p_action["events"]).size();
+ int old_event_count = ((Array)old_val["events"]).size();
+
+ if (event_count == old_event_count) {
+ undo_redo->create_action(TTR("Edit Input Action Event"));
+ } else if (event_count > old_event_count) {
+ undo_redo->create_action(TTR("Add Input Action Event"));
+ } else if (event_count < old_event_count) {
+ undo_redo->create_action(TTR("Remove Input Action Event"));
+ }
+
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", property_name, p_action);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val);
+ }
+
+ undo_redo->add_do_method(this, "_update_action_map_editor");
+ undo_redo->add_undo_method(this, "_update_action_map_editor");
+ undo_redo->add_do_method(this, "queue_save");
+ undo_redo->add_undo_method(this, "queue_save");
+ undo_redo->commit_action();
+}
+
+void ProjectSettingsEditor::_action_removed(const String &p_name) {
+ const String property_name = "input/" + p_name;
+
+ Dictionary old_val = ProjectSettings::get_singleton()->get(property_name);
+ int order = ProjectSettings::get_singleton()->get_order(property_name);
+
+ undo_redo->create_action(TTR("Erase Input Action"));
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", property_name);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", property_name, order);
+
+ undo_redo->add_do_method(this, "_update_action_map_editor");
+ undo_redo->add_undo_method(this, "_update_action_map_editor");
+ undo_redo->add_do_method(this, "queue_save");
+ undo_redo->add_undo_method(this, "queue_save");
+ undo_redo->commit_action();
+}
+
+void ProjectSettingsEditor::_action_renamed(const String &p_old_name, const String &p_new_name) {
+ 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;
+ }
+
+ int order = ProjectSettings::get_singleton()->get_order(old_property_name);
+ Dictionary action = ProjectSettings::get_singleton()->get(old_property_name);
+
+ undo_redo->create_action(TTR("Rename Input Action Event"));
+ // Do: clear old, set new
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", old_property_name);
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", new_property_name, action);
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", new_property_name, order);
+ // Undo: clear new, set old
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", new_property_name);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", old_property_name, action);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set_order", old_property_name, order);
+
+ undo_redo->add_do_method(this, "_update_action_map_editor");
+ undo_redo->add_undo_method(this, "_update_action_map_editor");
+ undo_redo->add_do_method(this, "queue_save");
+ undo_redo->add_undo_method(this, "queue_save");
+ undo_redo->commit_action();
+}
+
+void ProjectSettingsEditor::_action_reordered(const String &p_action_name, const String &p_relative_to, bool p_before) {
+ const String action_name = "input/" + p_action_name;
+ const String target_name = "input/" + p_relative_to;
+
+ // It is much easier to rebuild the custom "input" properties rather than messing around with the "order" values of them.
+ Variant action_value = ps->get(action_name);
+ Variant target_value = ps->get(target_name);
+
+ List<PropertyInfo> props;
+ OrderedHashMap<String, Variant> action_values;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+
+ undo_redo->create_action(TTR("Update Input Action Order"));
+
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ PropertyInfo prop = E->get();
+ // Skip builtins and non-inputs
+ if (ProjectSettings::get_singleton()->is_builtin_setting(prop.name) || !prop.name.begins_with("input/")) {
+ continue;
+ }
+
+ action_values.insert(prop.name, ps->get(prop.name));
+
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", prop.name);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", prop.name);
+ }
+
+ for (OrderedHashMap<String, Variant>::Element E = action_values.front(); E; E = E.next()) {
+ String name = E.key();
+ Variant value = E.get();
+
+ if (name == target_name) {
+ if (p_before) {
+ // Insert before target
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", action_name, action_value);
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", target_name, target_value);
+
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", target_name, target_value);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", action_name, action_value);
+ } else {
+ // Insert after target
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", target_name, target_value);
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", action_name, action_value);
+
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", action_name, action_value);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", target_name, target_value);
+ }
+
+ } else if (name != action_name) {
+ undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, value);
+ undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", name, value);
+ }
+ }
+
+ undo_redo->add_do_method(this, "_update_action_map_editor");
+ undo_redo->add_undo_method(this, "_update_action_map_editor");
+ undo_redo->add_do_method(this, "queue_save");
+ undo_redo->add_undo_method(this, "queue_save");
+ undo_redo->commit_action();
+}
+
+void ProjectSettingsEditor::_update_action_map_editor() {
+ Vector<ActionMapEditor::ActionInfo> actions;
+
+ List<PropertyInfo> props;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+
+ const Ref<Texture2D> builtin_icon = get_theme_icon("PinPressed", "EditorIcons");
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ const String property_name = E->get().name;
+
+ if (!property_name.begins_with("input/")) {
+ continue;
+ }
+
+ // Strip the "input/" from the left.
+ String display_name = property_name.substr(String("input/").size() - 1);
+ Dictionary action = ProjectSettings::get_singleton()->get(property_name);
+
+ ActionMapEditor::ActionInfo action_info;
+ action_info.action = action;
+ action_info.editable = true;
+ action_info.name = display_name;
+
+ const bool is_builtin_input = ProjectSettings::get_singleton()->get_input_presets().find(property_name) != nullptr;
+ if (is_builtin_input) {
+ action_info.editable = false;
+ action_info.icon = builtin_icon;
+ }
+
+ actions.push_back(action_info);
+ }
+
+ action_map->update_action_list(actions);
+}
+
void ProjectSettingsEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible()) {
EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "project_settings", Rect2(get_position(), get_size()));
- if (advanced->is_pressed()) {
- advanced->set_pressed(false);
- advanced_bar->hide();
- }
}
} break;
case NOTIFICATION_ENTER_TREE: {
inspector->edit(ps);
- error_label->add_theme_color_override("font_color", error_label->get_theme_color("error_color", "Editor"));
add_button->set_icon(get_theme_icon("Add", "EditorIcons"));
del_button->set_icon(get_theme_icon("Remove", "EditorIcons"));
@@ -292,6 +491,8 @@ void ProjectSettingsEditor::_notification(int p_what) {
restart_container->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
restart_icon->set_texture(get_theme_icon("StatusWarning", "EditorIcons"));
restart_label->add_theme_color_override("font_color", get_theme_color("warning_color", "Editor"));
+
+ _update_action_map_editor();
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
search_box->set_right_icon(get_theme_icon("Search", "EditorIcons"));
@@ -302,6 +503,8 @@ void ProjectSettingsEditor::_notification(int p_what) {
void ProjectSettingsEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("queue_save"), &ProjectSettingsEditor::queue_save);
+
+ ClassDB::bind_method(D_METHOD("_update_action_map_editor"), &ProjectSettingsEditor::_update_action_map_editor);
}
ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
@@ -339,23 +542,19 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
search_bar->add_child(search_box);
advanced = memnew(CheckButton);
- advanced->set_text(TTR("Advanced"));
+ advanced->set_text(TTR("Advanced Settings"));
advanced->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_advanced_pressed));
search_bar->add_child(advanced);
}
{
// Advanced bar.
- advanced_bar = memnew(VBoxContainer);
- advanced_bar->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ advanced_bar = memnew(HBoxContainer);
advanced_bar->hide();
header->add_child(advanced_bar);
- advanced_bar->add_child(memnew(HSeparator));
-
- HBoxContainer *hbc = memnew(HBoxContainer);
+ HBoxContainer *hbc = advanced_bar;
hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- advanced_bar->add_margin_child(TTR("Add or Remove Custom Project Settings:"), hbc, true);
category_box = memnew(LineEdit);
category_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
@@ -364,7 +563,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
hbc->add_child(category_box);
Label *l = memnew(Label);
- l->set_text("/");
+ l->set_text(" / ");
hbc->add_child(l);
property_box = memnew(LineEdit);
@@ -381,9 +580,12 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
type->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
hbc->add_child(type);
- // Start at 1 to avoid adding "Nil" as an option
- for (int i = 1; i < Variant::VARIANT_MAX; i++) {
- type->add_item(Variant::get_type_name(Variant::Type(i)));
+ for (int i = 0; i < Variant::VARIANT_MAX; i++) {
+ // There's no point in adding Nil types, and Object types
+ // can't be serialized correctly in the project settings.
+ if (i != Variant::NIL && i != Variant::OBJECT) {
+ type->add_item(Variant::get_type_name(Variant::Type(i)));
+ }
}
l = memnew(Label);
@@ -404,9 +606,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
del_button->set_flat(true);
del_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_delete_setting), varray(false));
hbc->add_child(del_button);
-
- error_label = memnew(Label);
- advanced_bar->add_child(error_label);
}
inspector = memnew(SectionedInspector);
@@ -444,10 +643,16 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
restart_close_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_editor_restart_close));
restart_hb->add_child(restart_close_button);
- inputmap_editor = memnew(InputMapEditor);
- inputmap_editor->set_name(TTR("Input Map"));
- inputmap_editor->connect("inputmap_changed", callable_mp(this, &ProjectSettingsEditor::queue_save));
- tab_container->add_child(inputmap_editor);
+ action_map = memnew(ActionMapEditor);
+ action_map->set_name(TTR("Input Map"));
+ action_map->connect("action_added", callable_mp(this, &ProjectSettingsEditor::_action_added));
+ action_map->connect("action_edited", callable_mp(this, &ProjectSettingsEditor::_action_edited));
+ action_map->connect("action_removed", callable_mp(this, &ProjectSettingsEditor::_action_removed));
+ action_map->connect("action_renamed", callable_mp(this, &ProjectSettingsEditor::_action_renamed));
+ action_map->connect("action_reordered", callable_mp(this, &ProjectSettingsEditor::_action_reordered));
+ action_map->set_toggle_editable_label(TTR("Show Built-in Actions"));
+ action_map->set_show_uneditable(false);
+ tab_container->add_child(action_map);
localization_editor = memnew(LocalizationEditor);
localization_editor->set_name(TTR("Localization"));
@@ -480,4 +685,18 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
get_ok_button()->set_text(TTR("Close"));
set_hide_on_ok(true);
+
+ bool use_advanced = EditorSettings::get_singleton()->get_project_metadata("project_settings", "advanced_mode", false);
+
+ if (use_advanced) {
+ advanced->set_pressed(true);
+ advanced_bar->show();
+ }
+
+ inspector->set_restrict_to_basic_settings(!use_advanced);
+
+ import_defaults_editor = memnew(ImportDefaultsEditor);
+ import_defaults_editor->set_name(TTR("Import Defaults"));
+ tab_container->add_child(import_defaults_editor);
+ import_defaults_editor->connect("project_settings_changed", callable_mp(this, &ProjectSettingsEditor::queue_save));
}
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index 73e96d7b03..cde46ac4c4 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,10 +32,11 @@
#define PROJECT_SETTINGS_EDITOR_H
#include "core/object/undo_redo.h"
+#include "editor/action_map_editor.h"
#include "editor/editor_data.h"
#include "editor/editor_plugin_settings.h"
#include "editor/editor_sectioned_inspector.h"
-#include "editor/input_map_editor.h"
+#include "editor/import_defaults_editor.h"
#include "editor/localization_editor.h"
#include "editor/shader_globals_editor.h"
#include "editor_autoload_settings.h"
@@ -44,38 +45,29 @@
class ProjectSettingsEditor : public AcceptDialog {
GDCLASS(ProjectSettingsEditor, AcceptDialog);
- enum InputType {
- INPUT_KEY,
- INPUT_KEY_PHYSICAL,
- INPUT_JOY_BUTTON,
- INPUT_JOY_MOTION,
- INPUT_MOUSE_BUTTON
- };
-
static ProjectSettingsEditor *singleton;
ProjectSettings *ps;
Timer *timer;
TabContainer *tab_container;
SectionedInspector *inspector;
- InputMapEditor *inputmap_editor;
LocalizationEditor *localization_editor;
EditorAutoloadSettings *autoload_settings;
ShaderGlobalsEditor *shaders_global_variables_editor;
EditorPluginSettings *plugin_settings;
+ ActionMapEditor *action_map;
HBoxContainer *search_bar;
LineEdit *search_box;
CheckButton *advanced;
- VBoxContainer *advanced_bar;
+ HBoxContainer *advanced_bar;
LineEdit *category_box;
LineEdit *property_box;
Button *add_button;
Button *del_button;
OptionButton *type;
OptionButton *feature_override;
- Label *error_label;
ConfirmationDialog *del_confirmation;
@@ -84,6 +76,7 @@ class ProjectSettingsEditor : public AcceptDialog {
PanelContainer *restart_container;
Button *restart_close_button;
+ ImportDefaultsEditor *import_defaults_editor;
EditorData *data;
UndoRedo *undo_redo;
@@ -103,6 +96,14 @@ class ProjectSettingsEditor : public AcceptDialog {
void _editor_restart_close();
void _add_feature_overrides();
+
+ void _action_added(const String &p_name);
+ void _action_edited(const String &p_name, const Dictionary &p_action);
+ void _action_removed(const String &p_name);
+ void _action_renamed(const String &p_old_name, const String &p_new_name);
+ void _action_reordered(const String &p_action_name, const String &p_relative_to, bool p_before);
+ void _update_action_map_editor();
+
ProjectSettingsEditor();
protected:
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index d45ee1eae1..8ce7153355 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -251,7 +251,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
emit_signal("variant_changed");
break;
}
- ERR_FAIL_COND(inheritors_array.empty());
+ ERR_FAIL_COND(inheritors_array.is_empty());
String intype = inheritors_array[p_which - TYPE_BASE_ID];
@@ -262,7 +262,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
return;
}
- Object *obj = ClassDB::instance(intype);
+ Variant obj = ClassDB::instance(intype);
if (!obj) {
if (ScriptServer::is_global_class(intype)) {
@@ -280,7 +280,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
res->call("set_instance_base_type", owner->get_class());
}
- v = res;
+ v = obj;
emit_signal("variant_changed");
} break;
@@ -367,18 +367,18 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
int c = hint_text.get_slice_count(",");
float min = 0, max = 100, step = type == Variant::FLOAT ? .01 : 1;
if (c >= 1) {
- if (!hint_text.get_slice(",", 0).empty()) {
+ if (!hint_text.get_slice(",", 0).is_empty()) {
min = hint_text.get_slice(",", 0).to_float();
}
}
if (c >= 2) {
- if (!hint_text.get_slice(",", 1).empty()) {
+ if (!hint_text.get_slice(",", 1).is_empty()) {
max = hint_text.get_slice(",", 1).to_float();
}
}
if (c >= 3) {
- if (!hint_text.get_slice(",", 2).empty()) {
+ if (!hint_text.get_slice(",", 2).is_empty()) {
step = hint_text.get_slice(",", 2).to_float();
}
}
@@ -417,7 +417,12 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
updating = false;
return false;
- } else if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || hint == PROPERTY_HINT_LAYERS_2D_RENDER || hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || hint == PROPERTY_HINT_LAYERS_3D_RENDER) {
+ } else if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS ||
+ hint == PROPERTY_HINT_LAYERS_2D_RENDER ||
+ hint == PROPERTY_HINT_LAYERS_2D_NAVIGATION ||
+ hint == PROPERTY_HINT_LAYERS_3D_PHYSICS ||
+ hint == PROPERTY_HINT_LAYERS_3D_RENDER ||
+ hint == PROPERTY_HINT_LAYERS_3D_NAVIGATION) {
String basename;
switch (hint) {
case PROPERTY_HINT_LAYERS_2D_RENDER:
@@ -426,12 +431,18 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
case PROPERTY_HINT_LAYERS_2D_PHYSICS:
basename = "layer_names/2d_physics";
break;
+ case PROPERTY_HINT_LAYERS_2D_NAVIGATION:
+ basename = "layer_names/2d_navigation";
+ break;
case PROPERTY_HINT_LAYERS_3D_RENDER:
basename = "layer_names/3d_render";
break;
case PROPERTY_HINT_LAYERS_3D_PHYSICS:
basename = "layer_names/3d_physics";
break;
+ case PROPERTY_HINT_LAYERS_3D_NAVIGATION:
+ basename = "layer_names/3d_navigation";
+ break;
}
checks20gc->show();
@@ -882,7 +893,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
bool is_custom_resource = false;
Ref<Texture2D> icon;
- if (!custom_resources.empty()) {
+ if (!custom_resources.is_empty()) {
for (int k = 0; k < custom_resources.size(); k++) {
if (custom_resources[k].name == t) {
is_custom_resource = true;
@@ -1064,7 +1075,7 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) {
String intype = inheritors_array[p_idx];
- Object *obj = ClassDB::instance(intype);
+ Variant obj = ClassDB::instance(intype);
if (!obj) {
if (ScriptServer::is_global_class(intype)) {
@@ -1075,11 +1086,9 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) {
}
ERR_FAIL_COND(!obj);
+ ERR_FAIL_COND(!Object::cast_to<Resource>(obj));
- Resource *res = Object::cast_to<Resource>(obj);
- ERR_FAIL_COND(!res);
-
- v = res;
+ v = obj;
emit_signal("variant_changed");
hide();
}
@@ -1155,7 +1164,12 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
emit_signal("variant_changed");
} break;
case Variant::INT: {
- if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || hint == PROPERTY_HINT_LAYERS_2D_RENDER || hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || hint == PROPERTY_HINT_LAYERS_3D_RENDER) {
+ if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS ||
+ hint == PROPERTY_HINT_LAYERS_2D_RENDER ||
+ hint == PROPERTY_HINT_LAYERS_2D_NAVIGATION ||
+ hint == PROPERTY_HINT_LAYERS_3D_PHYSICS ||
+ hint == PROPERTY_HINT_LAYERS_3D_RENDER ||
+ hint == PROPERTY_HINT_LAYERS_3D_NAVIGATION) {
uint32_t f = v;
if (checks20[p_which]->is_pressed()) {
f |= (1 << p_which);
@@ -1246,12 +1260,12 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
} break;
case Variant::OBJECT: {
if (p_which == 0) {
- ERR_FAIL_COND(inheritors_array.empty());
+ ERR_FAIL_COND(inheritors_array.is_empty());
String intype = inheritors_array[0];
if (hint == PROPERTY_HINT_RESOURCE_TYPE) {
- Object *obj = ClassDB::instance(intype);
+ Variant obj = ClassDB::instance(intype);
if (!obj) {
if (ScriptServer::is_global_class(intype)) {
@@ -1262,10 +1276,9 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
}
ERR_BREAK(!obj);
- Resource *res = Object::cast_to<Resource>(obj);
- ERR_BREAK(!res);
+ ERR_BREAK(!Object::cast_to<Resource>(obj));
- v = res;
+ v = obj;
emit_signal("variant_changed");
hide();
}
diff --git a/editor/property_editor.h b/editor/property_editor.h
index 75c6fd372b..c6929f3b42 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 220031d2dc..da798962e5 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/property_selector.h b/editor/property_selector.h
index f579c0404c..37b00e938b 100644
--- a/editor/property_selector.h
+++ b/editor/property_selector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 7ffe5bc9a7..7f720d65d0 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/quick_open.h b/editor/quick_open.h
index a507a0da9c..f1787d522b 100644
--- a/editor/quick_open.h
+++ b/editor/quick_open.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/register_exporters.h b/editor/register_exporters.h
index 27071f4a51..5091292b1a 100644
--- a/editor/register_exporters.h
+++ b/editor/register_exporters.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index a60937a86b..48aa0471c9 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -572,7 +572,7 @@ void RenameDialog::rename() {
// Forward recursive as opposed to the actual renaming.
_iterate_scene(root_node, selected_node_list, &global_count);
- if (undo_redo && !to_rename.empty()) {
+ if (undo_redo && !to_rename.is_empty()) {
undo_redo->create_action(TTR("Batch Rename"));
// Make sure to iterate reversed so that child nodes will find parents.
diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h
index 164d7ab1b0..76e99e3b66 100644
--- a/editor/rename_dialog.h
+++ b/editor/rename_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp
index c7f1a1b45d..aab046c235 100644
--- a/editor/reparent_dialog.cpp
+++ b/editor/reparent_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/reparent_dialog.h b/editor/reparent_dialog.h
index 4566e3a02a..5c3a65a522 100644
--- a/editor/reparent_dialog.h
+++ b/editor/reparent_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 91ae81dea2..2cdab83d90 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,10 +57,7 @@ void SceneTreeDock::_nodes_drag_begin() {
}
void SceneTreeDock::_quick_open() {
- Vector<String> files = quick_open->get_selected_files();
- for (int i = 0; i < files.size(); i++) {
- instance(files[i]);
- }
+ instance_scenes(quick_open->get_selected_files(), scene_tree->get_selected());
}
void SceneTreeDock::_input(Ref<InputEvent> p_event) {
@@ -90,6 +87,12 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
_tool_selected(TOOL_INSTANCE);
} else if (ED_IS_SHORTCUT("scene_tree/expand_collapse_all", p_event)) {
_tool_selected(TOOL_EXPAND_COLLAPSE);
+ } else if (ED_IS_SHORTCUT("scene_tree/cut_node", p_event)) {
+ _tool_selected(TOOL_CUT);
+ } else if (ED_IS_SHORTCUT("scene_tree/copy_node", p_event)) {
+ _tool_selected(TOOL_COPY);
+ } else if (ED_IS_SHORTCUT("scene_tree/paste_node", p_event)) {
+ _tool_selected(TOOL_PASTE);
} else if (ED_IS_SHORTCUT("scene_tree/change_node_type", p_event)) {
_tool_selected(TOOL_REPLACE);
} else if (ED_IS_SHORTCUT("scene_tree/duplicate", p_event)) {
@@ -104,8 +107,6 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
_tool_selected(TOOL_MOVE_DOWN);
} else if (ED_IS_SHORTCUT("scene_tree/reparent", p_event)) {
_tool_selected(TOOL_REPARENT);
- } else if (ED_IS_SHORTCUT("scene_tree/merge_from_scene", p_event)) {
- _tool_selected(TOOL_MERGE_FROM_SCENE);
} else if (ED_IS_SHORTCUT("scene_tree/save_branch_as_scene", p_event)) {
_tool_selected(TOOL_NEW_SCENE_FROM);
} else if (ED_IS_SHORTCUT("scene_tree/delete_no_confirm", p_event)) {
@@ -123,24 +124,9 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
}
void SceneTreeDock::instance(const String &p_file) {
- Node *parent = scene_tree->get_selected();
-
- if (!parent) {
- parent = edited_scene;
- };
-
- if (!edited_scene) {
- current_option = -1;
- accept->set_text(TTR("No parent to instance a child at."));
- accept->popup_centered();
- return;
- };
-
- ERR_FAIL_COND(!parent);
-
Vector<String> scenes;
scenes.push_back(p_file);
- _perform_instance_scenes(scenes, parent, -1);
+ instance_scenes(scenes, scene_tree->get_selected());
}
void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_parent) {
@@ -151,7 +137,11 @@ void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_paren
}
if (!parent || !edited_scene) {
- accept->set_text(TTR("No parent to instance the scenes at."));
+ if (p_files.size() == 1) {
+ accept->set_text(TTR("No parent to instance a child at."));
+ } else {
+ accept->set_text(TTR("No parent to instance the scenes at."));
+ }
accept->popup_centered();
return;
};
@@ -228,6 +218,10 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
}
editor_data->get_undo_redo().commit_action();
+ editor->push_item(instances[instances.size() - 1]);
+ for (int i = 0; i < instances.size(); i++) {
+ emit_signal("node_created", instances[i]);
+ }
}
void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) {
@@ -356,12 +350,17 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
+ if (reset_create_dialog) {
+ create_dialog->set_base_type("Node");
+ reset_create_dialog = false;
+ }
+
// Prefer nodes that inherit from the current scene root.
Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene();
if (current_edited_scene_root) {
String root_class = current_edited_scene_root->get_class_name();
static Vector<String> preferred_types;
- if (preferred_types.empty()) {
+ if (preferred_types.is_empty()) {
preferred_types.push_back("Control");
preferred_types.push_back("Node2D");
preferred_types.push_back("Node3D");
@@ -376,6 +375,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
create_dialog->popup_create(true);
+ if (!p_confirm_override) {
+ emit_signal("add_node_used");
+ }
} break;
case TOOL_INSTANCE: {
if (!profile_allow_editing) {
@@ -390,7 +392,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
quick_open->popup_dialog("PackedScene", true);
quick_open->set_title(TTR("Instance Child Scene"));
-
+ if (!p_confirm_override) {
+ emit_signal("add_node_used");
+ }
} break;
case TOOL_EXPAND_COLLAPSE: {
if (!scene_tree->get_selected()) {
@@ -410,13 +414,129 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
tree->ensure_cursor_is_visible();
} break;
+ case TOOL_CUT:
+ case TOOL_COPY: {
+ if (!edited_scene || !_validate_no_foreign()) {
+ break;
+ }
+
+ List<Node *> selection = editor_selection->get_selected_node_list();
+ if (selection.size() == 0) {
+ break;
+ }
+
+ if (!node_clipboard.is_empty()) {
+ _clear_clipboard();
+ }
+ clipboard_source_scene = editor->get_edited_scene()->get_filename();
+
+ selection.sort_custom<Node::Comparator>();
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ Node *node = E->get();
+ Map<const Node *, Node *> duplimap;
+ Node *dup = node->duplicate_from_editor(duplimap);
+
+ ERR_CONTINUE(!dup);
+
+ node_clipboard.push_back(dup);
+ }
+
+ if (p_tool == TOOL_CUT) {
+ _delete_confirm(true);
+ }
+ } break;
+ case TOOL_PASTE: {
+ if (node_clipboard.is_empty() || !edited_scene) {
+ break;
+ }
+
+ bool has_cycle = false;
+ if (edited_scene->get_filename() != String()) {
+ for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) {
+ if (edited_scene->get_filename() == E->get()->get_filename()) {
+ has_cycle = true;
+ break;
+ }
+ }
+ }
+
+ if (has_cycle) {
+ current_option = -1;
+ accept->set_text(TTR("Can't paste root node into the same scene."));
+ accept->popup_centered();
+ break;
+ }
+
+ Node *paste_parent = edited_scene;
+ List<Node *> selection = editor_selection->get_selected_node_list();
+ if (selection.size() > 0) {
+ paste_parent = selection.back()->get();
+ }
+
+ Node *owner = paste_parent->get_owner();
+ if (!owner) {
+ owner = paste_parent;
+ }
+
+ editor_data->get_undo_redo().create_action(TTR("Paste Node(s)"));
+ editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
+
+ Map<RES, RES> resource_remap;
+ String target_scene = editor->get_edited_scene()->get_filename();
+ if (target_scene != clipboard_source_scene) {
+ if (!clipboard_resource_remap.has(target_scene)) {
+ Map<RES, RES> remap;
+ for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) {
+ _create_remap_for_node(E->get(), remap);
+ }
+ clipboard_resource_remap[target_scene] = remap;
+ }
+ resource_remap = clipboard_resource_remap[target_scene];
+ }
+
+ for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) {
+ Node *node = E->get();
+ Map<const Node *, Node *> duplimap;
+
+ Node *dup = node->duplicate_from_editor(duplimap, resource_remap);
+
+ ERR_CONTINUE(!dup);
+
+ editor_data->get_undo_redo().add_do_method(paste_parent, "add_child", dup);
+
+ for (Map<const Node *, Node *>::Element *E2 = duplimap.front(); E2; E2 = E2->next()) {
+ Node *d = E2->value();
+ editor_data->get_undo_redo().add_do_method(d, "set_owner", owner);
+ }
+
+ editor_data->get_undo_redo().add_do_method(dup, "set_owner", owner);
+ editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", dup);
+ editor_data->get_undo_redo().add_undo_method(paste_parent, "remove_child", dup);
+ editor_data->get_undo_redo().add_do_reference(dup);
+
+ if (node_clipboard.size() == 1) {
+ editor_data->get_undo_redo().add_do_method(editor, "push_item", dup);
+ }
+ }
+
+ editor_data->get_undo_redo().commit_action();
+ } break;
case TOOL_REPLACE: {
if (!profile_allow_editing) {
break;
}
+ if (!_validate_no_foreign()) {
+ break;
+ }
+
+ if (!_validate_no_instance()) {
+ break;
+ }
+
Node *selected = scene_tree->get_selected();
- if (!selected && !editor_selection->get_selected_node_list().empty()) {
+ if (!selected && !editor_selection->get_selected_node_list().is_empty()) {
selected = editor_selection->get_selected_node_list().front()->get();
}
@@ -438,7 +558,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Array selection = editor_selection->get_selected_nodes();
- if (selection.empty()) {
+ if (selection.is_empty()) {
return;
}
@@ -565,7 +685,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
Node *dupsingle = nullptr;
- List<Node *> editable_children;
selection.sort_custom<Node::Comparator>();
@@ -581,10 +700,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Map<const Node *, Node *> duplimap;
Node *dup = node->duplicate_from_editor(duplimap);
- if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node)) {
- editable_children.push_back(dup);
- }
-
ERR_CONTINUE(!dup);
if (selection.size() == 1) {
@@ -619,11 +734,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (dupsingle) {
editor->push_item(dupsingle);
}
-
- for (List<Node *>::Element *E = editable_children.back(); E; E = E->prev()) {
- _toggle_editable_children(E->get());
- }
-
} break;
case TOOL_REPARENT: {
if (!profile_allow_editing) {
@@ -737,7 +847,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
List<Node *> remove_list = editor_selection->get_selected_node_list();
- if (remove_list.empty()) {
+ if (remove_list.is_empty()) {
return;
}
@@ -779,13 +889,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
} break;
- case TOOL_MERGE_FROM_SCENE: {
- if (!profile_allow_editing) {
- break;
- }
-
- EditorNode::get_singleton()->merge_from_scene();
- } break;
case TOOL_NEW_SCENE_FROM: {
if (!profile_allow_editing) {
break;
@@ -1523,13 +1626,27 @@ bool SceneTreeDock::_validate_no_foreign() {
return true;
}
+bool SceneTreeDock::_validate_no_instance() {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ if (E->get() != edited_scene && E->get()->get_filename() != "") {
+ accept->set_text(TTR("This operation can't be done on instanced scenes."));
+ accept->popup_centered();
+ return false;
+ }
+ }
+
+ return true;
+}
+
void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) {
Node *new_parent = scene_root->get_node(p_path);
ERR_FAIL_COND(!new_parent);
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.empty()) {
+ if (selection.is_empty()) {
return; // Nothing to reparent.
}
@@ -1703,7 +1820,7 @@ bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const {
List<TreeItem *> needs_check;
needs_check.push_back(p_item);
- while (!needs_check.empty()) {
+ while (!needs_check.is_empty()) {
TreeItem *item = needs_check.back()->get();
needs_check.pop_back();
@@ -1725,7 +1842,7 @@ void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed)
List<TreeItem *> to_collapse;
to_collapse.push_back(p_item);
- while (!to_collapse.empty()) {
+ while (!to_collapse.is_empty()) {
TreeItem *item = to_collapse.back()->get();
to_collapse.pop_back();
@@ -1742,7 +1859,7 @@ void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed)
void SceneTreeDock::_script_created(Ref<Script> p_script) {
List<Node *> selected = editor_selection->get_selected_node_list();
- if (selected.empty()) {
+ if (selected.is_empty()) {
return;
}
@@ -1808,16 +1925,20 @@ void SceneTreeDock::_toggle_editable_children(Node *p_node) {
}
}
-void SceneTreeDock::_delete_confirm() {
+void SceneTreeDock::_delete_confirm(bool p_cut) {
List<Node *> remove_list = editor_selection->get_selected_node_list();
- if (remove_list.empty()) {
+ if (remove_list.is_empty()) {
return;
}
editor->get_editor_plugins_over()->make_visible(false);
- editor_data->get_undo_redo().create_action(TTR("Remove Node(s)"));
+ if (p_cut) {
+ editor_data->get_undo_redo().create_action(TTR("Cut Node(s)"));
+ } else {
+ editor_data->get_undo_redo().create_action(TTR("Remove Node(s)"));
+ }
bool entire_scene = false;
@@ -1935,7 +2056,7 @@ void SceneTreeDock::_selection_changed() {
}
void SceneTreeDock::_do_create(Node *p_parent) {
- Object *c = create_dialog->instance_selected();
+ Variant c = create_dialog->instance_selected();
ERR_FAIL_COND(!c);
Node *child = Object::cast_to<Node>(c);
@@ -1983,6 +2104,8 @@ void SceneTreeDock::_do_create(Node *p_parent) {
}
ct->set_size(ms);
}
+
+ emit_signal("node_created", c);
}
void SceneTreeDock::_create() {
@@ -2015,7 +2138,7 @@ void SceneTreeDock::_create() {
Node *n = E->get();
ERR_FAIL_COND(!n);
- Object *c = create_dialog->instance_selected();
+ Variant c = create_dialog->instance_selected();
ERR_FAIL_COND(!c);
Node *newnode = Object::cast_to<Node>(c);
@@ -2153,7 +2276,6 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop
if (n == edited_scene) {
edited_scene = newnode;
editor->set_edited_scene(newnode);
- newnode->set_editable_instances(n->get_editable_instances());
}
//small hack to make collisionshapes and other kind of nodes to work
@@ -2187,21 +2309,6 @@ void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected) {
scene_tree->set_selected(p_node, p_emit_selected);
}
-void SceneTreeDock::import_subscene() {
- import_subscene_dialog->popup_centered_clamped(Size2(500, 800) * EDSCALE, 0.8);
-}
-
-void SceneTreeDock::_import_subscene() {
- Node *parent = scene_tree->get_selected();
- if (!parent) {
- parent = editor_data->get_edited_scene_root();
- ERR_FAIL_COND(!parent);
- }
-
- import_subscene_dialog->move(parent, edited_scene);
- editor_data->get_undo_redo().clear_history(); //no undo for now..
-}
-
void SceneTreeDock::_new_scene_from(String p_file) {
List<Node *> selection = editor_selection->get_selected_node_list();
@@ -2219,10 +2326,14 @@ void SceneTreeDock::_new_scene_from(String p_file) {
Node *base = selection.front()->get();
- Map<Node *, Node *> reown;
- reown[editor_data->get_edited_scene_root()] = base;
- Node *copy = base->duplicate_and_reown(reown);
+ Map<const Node *, Node *> duplimap;
+ Node *copy = base->duplicate_from_editor(duplimap);
+
if (copy) {
+ for (int i = 0; i < copy->get_child_count(); i++) {
+ _set_node_owner_recursive(copy->get_child(i), copy);
+ }
+
Ref<PackedScene> sdata = memnew(PackedScene);
Error err = sdata->pack(copy);
memdelete(copy);
@@ -2252,6 +2363,16 @@ void SceneTreeDock::_new_scene_from(String p_file) {
}
}
+void SceneTreeDock::_set_node_owner_recursive(Node *p_node, Node *p_owner) {
+ if (!p_node->get_owner()) {
+ p_node->set_owner(p_owner);
+ }
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _set_node_owner_recursive(p_node->get_child(i), p_owner);
+ }
+}
+
static bool _is_node_visible(Node *p_node) {
if (!p_node->get_owner()) {
return false;
@@ -2349,7 +2470,7 @@ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) {
void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) {
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.empty()) {
+ if (selection.is_empty()) {
return; //nothing to reparent
}
@@ -2458,6 +2579,13 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}
if (profile_allow_script_editing) {
+ menu->add_shortcut(ED_GET_SHORTCUT("scene_tree/cut_node"), TOOL_CUT);
+ menu->add_shortcut(ED_GET_SHORTCUT("scene_tree/copy_node"), TOOL_COPY);
+ if (selection.size() == 1 && !node_clipboard.is_empty()) {
+ menu->add_shortcut(ED_GET_SHORTCUT("scene_tree/paste_node"), TOOL_PASTE);
+ }
+ menu->add_separator();
+
bool add_separator = false;
if (full_selection.size() == 1) {
@@ -2494,7 +2622,18 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (full_selection.size() == 1) {
menu->add_icon_shortcut(get_theme_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
}
- menu->add_icon_shortcut(get_theme_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
+
+ bool can_replace = true;
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ if (E->get() != edited_scene && (E->get()->get_owner() != edited_scene || E->get()->get_filename() != "")) {
+ can_replace = false;
+ break;
+ }
+ }
+
+ if (can_replace) {
+ menu->add_icon_shortcut(get_theme_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
+ }
if (scene_tree->get_selected() != edited_scene) {
menu->add_separator();
@@ -2511,7 +2650,6 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (selection.size() == 1) {
if (profile_allow_editing) {
menu->add_separator();
- menu->add_icon_shortcut(get_theme_icon("Blend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE);
menu->add_icon_shortcut(get_theme_icon("CreateNewSceneFrom", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM);
}
if (full_selection.size() == 1) {
@@ -2601,7 +2739,7 @@ void SceneTreeDock::attach_script_to_selected(bool p_extend) {
}
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.empty()) {
+ if (selection.is_empty()) {
return;
}
@@ -2657,6 +2795,16 @@ void SceneTreeDock::open_script_dialog(Node *p_for_node, bool p_extend) {
}
}
+void SceneTreeDock::open_add_child_dialog() {
+ create_dialog->set_base_type("CanvasItem");
+ _tool_selected(TOOL_NEW, true);
+ reset_create_dialog = true;
+}
+
+void SceneTreeDock::open_instance_child_dialog() {
+ _tool_selected(TOOL_INSTANCE, true);
+}
+
void SceneTreeDock::add_remote_tree_editor(Control *p_remote) {
ERR_FAIL_COND(remote_tree != nullptr);
add_child(p_remote);
@@ -2789,6 +2937,62 @@ void SceneTreeDock::_feature_profile_changed() {
_update_script_button();
}
+void SceneTreeDock::_clear_clipboard() {
+ for (List<Node *>::Element *E = node_clipboard.front(); E; E = E->next()) {
+ memdelete(E->get());
+ }
+ node_clipboard.clear();
+ clipboard_resource_remap.clear();
+}
+
+void SceneTreeDock::_create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap) {
+ List<PropertyInfo> props;
+ p_node->get_property_list(&props);
+
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
+ continue;
+ }
+
+ Variant v = p_node->get(E->get().name);
+ if (v.is_ref()) {
+ RES res = v;
+ if (res.is_valid()) {
+ if ((res->get_path() == "" || res->get_path().find("::") > -1) && !r_remap.has(res)) {
+ _create_remap_for_resource(res, r_remap);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _create_remap_for_node(p_node->get_child(i), r_remap);
+ }
+}
+
+void SceneTreeDock::_create_remap_for_resource(RES p_resource, Map<RES, RES> &r_remap) {
+ r_remap[p_resource] = p_resource->duplicate();
+
+ List<PropertyInfo> props;
+ p_resource->get_property_list(&props);
+
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
+ continue;
+ }
+
+ Variant v = p_resource->get(E->get().name);
+ if (v.is_ref()) {
+ RES res = v;
+ if (res.is_valid()) {
+ if ((res->get_path() == "" || res->get_path().find("::") > -1) && !r_remap.has(res)) {
+ _create_remap_for_resource(res, r_remap);
+ }
+ }
+ }
+ }
+}
+
void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_owners"), &SceneTreeDock::_set_owners);
ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &SceneTreeDock::_unhandled_key_input);
@@ -2800,6 +3004,8 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("replace_node"), &SceneTreeDock::replace_node);
ADD_SIGNAL(MethodInfo("remote_tree_selected"));
+ ADD_SIGNAL(MethodInfo("add_node_used"));
+ ADD_SIGNAL(MethodInfo("node_created", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
}
SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data) {
@@ -2820,6 +3026,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KEY_MASK_CMD | KEY_A);
ED_SHORTCUT("scene_tree/instance_scene", TTR("Instance Child Scene"));
ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse All"));
+ ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KEY_MASK_CMD | KEY_X);
+ ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KEY_MASK_CMD | KEY_C);
+ ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KEY_MASK_CMD | KEY_V);
ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
@@ -2830,9 +3039,8 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
ED_SHORTCUT("scene_tree/reparent", TTR("Reparent"));
ED_SHORTCUT("scene_tree/reparent_to_new_node", TTR("Reparent to New Node"));
ED_SHORTCUT("scene_tree/make_root", TTR("Make Scene Root"));
- ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene"));
ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene"));
- ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD | KEY_C);
+ ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_C);
ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KEY_MASK_SHIFT | KEY_DELETE);
ED_SHORTCUT("scene_tree/delete", TTR("Delete"), KEY_DELETE);
@@ -2855,7 +3063,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
filter->set_h_size_flags(SIZE_EXPAND_FILL);
filter->set_placeholder(TTR("Filter nodes"));
filter_hbc->add_child(filter);
- filter->add_theme_constant_override("minimum_spaces", 0);
+ filter->add_theme_constant_override("minimum_character_width", 0);
filter->connect("text_changed", callable_mp(this, &SceneTreeDock::_filter_changed));
button_create_script = memnew(Button);
@@ -2950,7 +3158,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
delete_dialog = memnew(ConfirmationDialog);
add_child(delete_dialog);
- delete_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_delete_confirm));
+ delete_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_delete_confirm), varray(false));
editable_instance_remove_dialog = memnew(ConfirmationDialog);
add_child(editable_instance_remove_dialog);
@@ -2960,10 +3168,6 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
add_child(placeholder_editable_instance_remove_dialog);
placeholder_editable_instance_remove_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_toggle_placeholder_from_selection));
- import_subscene_dialog = memnew(EditorSubScene);
- add_child(import_subscene_dialog);
- import_subscene_dialog->connect("subscene_selected", callable_mp(this, &SceneTreeDock::_import_subscene));
-
new_scene_from_dialog = memnew(EditorFileDialog);
new_scene_from_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
add_child(new_scene_from_dialog);
@@ -2995,3 +3199,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
EDITOR_DEF("interface/editors/derive_script_globals_by_name", true);
EDITOR_DEF("_use_favorites_root_selection", false);
}
+
+SceneTreeDock::~SceneTreeDock() {
+ if (!node_clipboard.is_empty()) {
+ _clear_clipboard();
+ }
+}
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 2b3593358e..aa62c93cb5 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,7 +34,6 @@
#include "editor/connections_dialog.h"
#include "editor/create_dialog.h"
#include "editor/editor_data.h"
-#include "editor/editor_sub_scene.h"
#include "editor/groups_editor.h"
#include "editor/quick_open.h"
#include "editor/rename_dialog.h"
@@ -58,6 +57,9 @@ class SceneTreeDock : public VBoxContainer {
TOOL_NEW,
TOOL_INSTANCE,
TOOL_EXPAND_COLLAPSE,
+ TOOL_CUT,
+ TOOL_COPY,
+ TOOL_PASTE,
TOOL_RENAME,
TOOL_BATCH_RENAME,
TOOL_REPLACE,
@@ -71,7 +73,6 @@ class SceneTreeDock : public VBoxContainer {
TOOL_REPARENT_TO_NEW_NODE,
TOOL_MAKE_ROOT,
TOOL_NEW_SCENE_FROM,
- TOOL_MERGE_FROM_SCENE,
TOOL_MULTI_EDIT,
TOOL_ERASE,
TOOL_COPY_NODE_PATH,
@@ -99,6 +100,7 @@ class SceneTreeDock : public VBoxContainer {
Vector<ObjectID> subresources;
bool restore_script_editor_on_drag;
+ bool reset_create_dialog = false;
int current_option;
CreateDialog *create_dialog;
@@ -126,6 +128,10 @@ class SceneTreeDock : public VBoxContainer {
EditorData *editor_data;
EditorSelection *editor_selection;
+ List<Node *> node_clipboard;
+ String clipboard_source_scene;
+ HashMap<String, Map<RES, RES>> clipboard_resource_remap;
+
ScriptCreateDialog *script_create_dialog;
AcceptDialog *accept;
ConfirmationDialog *delete_dialog;
@@ -134,7 +140,6 @@ class SceneTreeDock : public VBoxContainer {
ReparentDialog *reparent_dialog;
EditorQuickOpen *quick_open;
- EditorSubScene *import_subscene_dialog;
EditorFileDialog *new_scene_from_dialog;
LineEdit *filter;
@@ -183,7 +188,7 @@ class SceneTreeDock : public VBoxContainer {
void _script_created(Ref<Script> p_script);
void _script_creation_closed();
- void _delete_confirm();
+ void _delete_confirm(bool p_cut = false);
void _toggle_editable_children_from_selection();
void _toggle_editable_children(Node *p_node);
@@ -199,8 +204,10 @@ class SceneTreeDock : public VBoxContainer {
void _import_subscene();
void _new_scene_from(String p_file);
+ void _set_node_owner_recursive(Node *p_node, Node *p_owner);
bool _validate_no_foreign();
+ bool _validate_no_instance();
void _selection_changed();
void _update_script_button();
@@ -230,6 +237,10 @@ class SceneTreeDock : public VBoxContainer {
void _feature_profile_changed();
+ void _clear_clipboard();
+ void _create_remap_for_node(Node *p_node, Map<RES, RES> &r_remap);
+ void _create_remap_for_resource(RES p_resource, Map<RES, RES> &r_remap);
+
bool profile_allow_editing;
bool profile_allow_script_editing;
@@ -264,9 +275,13 @@ public:
void attach_script_to_selected(bool p_extend);
void open_script_dialog(Node *p_for_node, bool p_extend);
+ void open_add_child_dialog();
+ void open_instance_child_dialog();
+
ScriptCreateDialog *get_script_create_dialog() { return script_create_dialog; }
SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data);
+ ~SceneTreeDock();
};
#endif // SCENE_TREE_DOCK_H
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 40fc5c02fc..2d739202fb 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -156,7 +156,7 @@ void SceneTreeEditor::_toggle_visible(Node *p_node) {
}
}
-bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
+bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll_to_selected) {
if (!p_node) {
return false;
}
@@ -236,6 +236,8 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
item->set_text(0, node_name);
item->set_selectable(0, marked_selectable);
item->set_custom_color(0, get_theme_color("accent_color", "Editor"));
+ } else if (!p_node->can_process()) {
+ item->set_custom_color(0, get_theme_color("disabled_font_color", "Editor"));
} else if (!marked_selectable && !marked_children_selectable) {
Node *node = p_node;
while (node) {
@@ -251,7 +253,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
if (can_rename) { //should be can edit..
String warning = p_node->get_configuration_warning();
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
item->add_button(0, get_theme_icon("NodeWarning", "EditorIcons"), BUTTON_WARNING, false, TTR("Node configuration warning:") + "\n" + p_node->get_configuration_warning());
}
@@ -391,15 +393,19 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
}
+ bool scroll = false;
+
if (editor_selection) {
if (editor_selection->is_selected(p_node)) {
item->select(0);
+ scroll = p_scroll_to_selected;
}
}
if (selected == p_node) {
if (!editor_selection) {
item->select(0);
+ scroll = p_scroll_to_selected;
}
item->set_as_cursor(0);
}
@@ -407,7 +413,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
bool keep = (filter.is_subsequence_ofi(String(p_node->get_name())));
for (int i = 0; i < p_node->get_child_count(); i++) {
- bool child_keep = _add_nodes(p_node->get_child(i), item);
+ bool child_keep = _add_nodes(p_node->get_child(i), item, p_scroll_to_selected);
keep = keep || child_keep;
}
@@ -438,6 +444,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
memdelete(item);
return false;
} else {
+ if (scroll) {
+ tree->scroll_to_item(item);
+ }
return true;
}
}
@@ -525,7 +534,7 @@ void SceneTreeEditor::_node_renamed(Node *p_node) {
}
}
-void SceneTreeEditor::_update_tree() {
+void SceneTreeEditor::_update_tree(bool p_scroll_to_selected) {
if (!is_inside_tree()) {
tree_dirty = false;
return;
@@ -534,7 +543,7 @@ void SceneTreeEditor::_update_tree() {
updating_tree = true;
tree->clear();
if (get_scene_node()) {
- _add_nodes(get_scene_node(), nullptr);
+ _add_nodes(get_scene_node(), nullptr, p_scroll_to_selected);
last_hash = hash_djb2_one_64(0);
_compute_hash(get_scene_node(), last_hash);
}
@@ -578,6 +587,11 @@ void SceneTreeEditor::_test_update_tree() {
tree_dirty = true;
}
+void SceneTreeEditor::_tree_process_mode_changed() {
+ MessageQueue::get_singleton()->push_call(this, "_update_tree");
+ tree_dirty = true;
+}
+
void SceneTreeEditor::_tree_changed() {
if (EditorNode::get_singleton()->is_exiting()) {
return; //speed up exit
@@ -648,6 +662,7 @@ void SceneTreeEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
get_tree()->connect("tree_changed", callable_mp(this, &SceneTreeEditor::_tree_changed));
+ get_tree()->connect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed));
get_tree()->connect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed));
get_tree()->connect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed));
get_tree()->connect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed));
@@ -658,6 +673,7 @@ void SceneTreeEditor::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
get_tree()->disconnect("tree_changed", callable_mp(this, &SceneTreeEditor::_tree_changed));
+ get_tree()->disconnect("tree_process_mode_changed", callable_mp(this, &SceneTreeEditor::_tree_process_mode_changed));
get_tree()->disconnect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed));
get_tree()->disconnect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed));
tree->disconnect("item_collapsed", callable_mp(this, &SceneTreeEditor::_cell_collapsed));
@@ -754,18 +770,20 @@ void SceneTreeEditor::_renamed() {
ERR_FAIL_COND(!n);
// Empty node names are not allowed, so resets it to previous text and show warning
- if (which->get_text(0).strip_edges().empty()) {
+ if (which->get_text(0).strip_edges().is_empty()) {
which->set_text(0, n->get_name());
EditorNode::get_singleton()->show_warning(TTR("No name provided."));
return;
}
- String new_name = which->get_text(0);
- if (!Node::_validate_node_name(new_name)) {
- error->set_text(TTR("Invalid node name, the following characters are not allowed:") + "\n" + Node::invalid_character);
+ String raw_new_name = which->get_text(0);
+ String new_name = raw_new_name.validate_node_name();
+
+ if (new_name != raw_new_name) {
+ error->set_text(TTR("Invalid node name, the following characters are not allowed:") + "\n" + String::invalid_node_name_characters);
error->popup_centered();
- if (new_name.empty()) {
+ if (new_name.is_empty()) {
which->set_text(0, n->get_name());
return;
}
@@ -817,7 +835,7 @@ void SceneTreeEditor::set_marked(Node *p_marked, bool p_selectable, bool p_child
void SceneTreeEditor::set_filter(const String &p_filter) {
filter = p_filter;
- _update_tree();
+ _update_tree(true);
}
String SceneTreeEditor::get_filter() const {
@@ -931,7 +949,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
next = tree->get_next_selected(next);
}
- if (selected.empty()) {
+ if (selected.is_empty()) {
return Variant();
}
@@ -1103,7 +1121,7 @@ void SceneTreeEditor::set_connecting_signal(bool p_enable) {
}
void SceneTreeEditor::_bind_methods() {
- ClassDB::bind_method("_update_tree", &SceneTreeEditor::_update_tree); // Still used by some connect_compat.
+ ClassDB::bind_method(D_METHOD("_update_tree", "scroll_to_selected"), &SceneTreeEditor::_update_tree, DEFVAL(false)); // Still used by some connect_compat.
ClassDB::bind_method("_rename_node", &SceneTreeEditor::_rename_node);
ClassDB::bind_method("_test_update_tree", &SceneTreeEditor::_test_update_tree);
@@ -1187,7 +1205,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
blocked = 0;
update_timer = memnew(Timer);
- update_timer->connect("timeout", callable_mp(this, &SceneTreeEditor::_update_tree));
+ update_timer->connect("timeout", callable_mp(this, &SceneTreeEditor::_update_tree), varray(false));
update_timer->set_one_shot(true);
update_timer->set_wait_time(0.5);
add_child(update_timer);
@@ -1253,7 +1271,7 @@ SceneTreeDialog::SceneTreeDialog() {
filter = memnew(LineEdit);
filter->set_h_size_flags(Control::SIZE_EXPAND_FILL);
filter->set_placeholder(TTR("Filter nodes"));
- filter->add_theme_constant_override("minimum_spaces", 0);
+ filter->add_theme_constant_override("minimum_character_width", 0);
filter->connect("text_changed", callable_mp(this, &SceneTreeDialog::_filter_changed));
vbc->add_child(filter);
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index e2bf9bc41d..6b505a6784 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,10 +71,11 @@ class SceneTreeEditor : public Control {
void _compute_hash(Node *p_node, uint64_t &hash);
- bool _add_nodes(Node *p_node, TreeItem *p_parent);
+ bool _add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll_to_selected = false);
void _test_update_tree();
- void _update_tree();
+ void _update_tree(bool p_scroll_to_selected = false);
void _tree_changed();
+ void _tree_process_mode_changed();
void _node_removed(Node *p_node);
void _node_renamed(Node *p_node);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 9c3e381dc8..b707f6c353 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,7 +50,7 @@ void ScriptCreateDialog::_theme_changed() {
}
String last_lang = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_language", "");
- if (!last_lang.empty()) {
+ if (!last_lang.is_empty()) {
for (int i = 0; i < language_menu->get_item_count(); i++) {
if (language_menu->get_item_text(i) == last_lang) {
language_menu->select(i);
@@ -568,6 +568,8 @@ void ScriptCreateDialog::_create() {
void ScriptCreateDialog::_browse_class_in_tree() {
select_class->set_base_type(base_type);
select_class->popup_create(true);
+ select_class->set_title(vformat(TTR("Inherit %s"), base_type));
+ select_class->get_ok_button()->set_text(TTR("Inherit"));
}
void ScriptCreateDialog::_path_changed(const String &p_path) {
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index a73be29259..e898b6f927 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index c152c2625f..3852c389c7 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,6 +31,7 @@
#include "settings_config_dialog.h"
#include "core/config/project_settings.h"
+#include "core/input/input_map.h"
#include "core/os/keyboard.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor_file_system.h"
@@ -143,7 +144,7 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
if (k.is_valid() && k->is_pressed()) {
bool handled = false;
- if (ED_IS_SHORTCUT("editor/undo", p_event)) {
+ if (ED_IS_SHORTCUT("ui_undo", p_event)) {
String action = undo_redo->get_current_action_name();
if (action != "") {
EditorNode::get_log()->add_message("Undo: " + action, EditorLog::MSG_TYPE_EDITOR);
@@ -152,7 +153,7 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
handled = true;
}
- if (ED_IS_SHORTCUT("editor/redo", p_event)) {
+ if (ED_IS_SHORTCUT("ui_redo", p_event)) {
undo_redo->redo();
String action = undo_redo->get_current_action_name();
if (action != "") {
@@ -184,7 +185,52 @@ void EditorSettingsDialog::_update_icons() {
restart_label->add_theme_color_override("font_color", shortcuts->get_theme_color("warning_color", "Editor"));
}
+void EditorSettingsDialog::_event_config_confirmed() {
+ Ref<InputEventKey> k = shortcut_editor->get_event();
+ if (k.is_null()) {
+ return;
+ }
+
+ if (editing_action) {
+ if (current_action_event_index == -1) {
+ // Add new event
+ current_action_events.push_back(k);
+ } else {
+ // Edit existing event
+ current_action_events[current_action_event_index] = k;
+ }
+
+ _update_builtin_action(current_action, current_action_events);
+ } else {
+ k = k->duplicate();
+ Ref<Shortcut> current_sc = EditorSettings::get_singleton()->get_shortcut(shortcut_being_edited);
+
+ undo_redo->create_action(TTR("Change Shortcut") + " '" + shortcut_being_edited + "'");
+ undo_redo->add_do_method(current_sc.ptr(), "set_shortcut", k);
+ undo_redo->add_undo_method(current_sc.ptr(), "set_shortcut", current_sc->get_shortcut());
+ undo_redo->add_do_method(this, "_update_shortcuts");
+ undo_redo->add_undo_method(this, "_update_shortcuts");
+ undo_redo->add_do_method(this, "_settings_changed");
+ undo_redo->add_undo_method(this, "_settings_changed");
+ undo_redo->commit_action();
+ }
+}
+
+void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Array &p_events) {
+ Array old_input_array = EditorSettings::get_singleton()->get_builtin_action_overrides(current_action);
+
+ undo_redo->create_action(TTR("Edit Built-in Action"));
+ undo_redo->add_do_method(EditorSettings::get_singleton(), "set_builtin_action_override", p_name, p_events);
+ undo_redo->add_undo_method(EditorSettings::get_singleton(), "set_builtin_action_override", p_name, old_input_array);
+ undo_redo->add_do_method(this, "_settings_changed");
+ undo_redo->add_undo_method(this, "_settings_changed");
+ undo_redo->commit_action();
+
+ _update_shortcuts();
+}
+
void EditorSettingsDialog::_update_shortcuts() {
+ // Before clearing the tree, take note of which categories are collapsed so that this state can be maintained when the tree is repopulated.
Map<String, bool> collapsed;
if (shortcuts->get_root() && shortcuts->get_root()->get_children()) {
@@ -192,15 +238,93 @@ void EditorSettingsDialog::_update_shortcuts() {
collapsed[item->get_text(0)] = item->is_collapsed();
}
}
-
shortcuts->clear();
- List<String> slist;
- EditorSettings::get_singleton()->get_shortcut_list(&slist);
TreeItem *root = shortcuts->create_item();
-
Map<String, TreeItem *> sections;
+ // Set up section for Common/Built-in actions
+ TreeItem *common_section = shortcuts->create_item(root);
+
+ sections["Common"] = common_section;
+ common_section->set_text(0, TTR("Common"));
+ if (collapsed.has("Common")) {
+ common_section->set_collapsed(collapsed["Common"]);
+ }
+ common_section->set_custom_bg_color(0, shortcuts->get_theme_color("prop_subsection", "Editor"));
+ common_section->set_custom_bg_color(1, shortcuts->get_theme_color("prop_subsection", "Editor"));
+
+ // Get the action map for the editor, and add each item to the "Common" section.
+ OrderedHashMap<StringName, InputMap::Action> action_map = InputMap::get_singleton()->get_action_map();
+ for (OrderedHashMap<StringName, InputMap::Action>::Element E = action_map.front(); E; E = E.next()) {
+ String action_name = E.key();
+
+ if (!shortcut_filter.is_subsequence_ofi(action_name)) {
+ continue;
+ }
+
+ InputMap::Action action = E.get();
+
+ Array events; // Need to get the list of events into an array so it can be set as metadata on the item.
+ Vector<String> event_strings;
+
+ List<Ref<InputEvent>> defaults = InputMap::get_singleton()->get_builtins().find(action_name).value();
+ // Remove all non-key events from the defaults.
+ for (List<Ref<InputEvent>>::Element *I = defaults.front(); I; I = I->next()) {
+ Ref<InputEventKey> k = I->get();
+ if (k.is_null()) {
+ I->erase();
+ }
+ }
+
+ bool same_as_defaults = defaults.size() == action.inputs.size(); // Initially this is set to just whether the arrays are equal. Later we check the events if needed.
+
+ int count = 0;
+ for (List<Ref<InputEvent>>::Element *I = action.inputs.front(); I; I = I->next()) {
+ // Add event and event text to respective arrays.
+ events.push_back(I->get());
+ event_strings.push_back(I->get()->as_text());
+
+ // Only check if the events have been the same so far - once one fails, we don't need to check any more.
+ if (same_as_defaults) {
+ Ref<InputEventKey> k = defaults[count];
+ // Only check keys, since we are in the editor.
+ if (k.is_valid() && !defaults[count]->shortcut_match(I->get())) {
+ same_as_defaults = false;
+ }
+ }
+ count++;
+ }
+
+ // Join the text of the events with a delimiter so they can all be displayed in one cell.
+ String events_display_string = event_strings.is_empty() ? "None" : String("; ").join(event_strings);
+
+ TreeItem *item = shortcuts->create_item(common_section);
+ item->set_text(0, action_name);
+ item->set_text(1, events_display_string);
+
+ if (!same_as_defaults) {
+ item->add_button(1, shortcuts->get_theme_icon("Reload", "EditorIcons"), 2);
+ }
+
+ if (events_display_string == "None") {
+ // Fade out unassigned shortcut labels for easier visual grepping.
+ item->set_custom_color(1, shortcuts->get_theme_color("font_color", "Label") * Color(1, 1, 1, 0.5));
+ }
+
+ item->add_button(1, shortcuts->get_theme_icon("Edit", "EditorIcons"), 0);
+ item->add_button(1, shortcuts->get_theme_icon("Close", "EditorIcons"), 1);
+ item->set_tooltip(0, action_name);
+ item->set_tooltip(1, events_display_string);
+ item->set_metadata(0, "Common");
+ item->set_metadata(1, events);
+ }
+
+ // Editor Shortcuts
+
+ List<String> slist;
+ EditorSettings::get_singleton()->get_shortcut_list(&slist);
+
for (List<String>::Element *E = slist.front(); E; E = E->next()) {
Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(E->get());
if (!sc->has_meta("original")) {
@@ -267,84 +391,119 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!ti);
- String item = ti->get_metadata(0);
- Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(item);
-
- if (p_idx == 0) {
- press_a_key_label->set_text(TTR("Press a Key..."));
- last_wait_for_key = Ref<InputEventKey>();
- press_a_key->popup_centered(Size2(250, 80) * EDSCALE);
- //press_a_key->grab_focus();
- press_a_key->get_ok_button()->set_focus_mode(Control::FOCUS_NONE);
- press_a_key->get_cancel_button()->set_focus_mode(Control::FOCUS_NONE);
- shortcut_configured = item;
-
- } else if (p_idx == 1) { //erase
- if (!sc.is_valid()) {
- return; //pointless, there is nothing
+ if (ti->get_metadata(0) == "Common") {
+ // Editing a Built-in action, which can have multiple bindings.
+ button_idx = p_idx;
+ editing_action = true;
+ current_action = ti->get_text(0);
+
+ switch (button_idx) {
+ case SHORTCUT_REVERT: {
+ Array events;
+ List<Ref<InputEvent>> defaults = InputMap::get_singleton()->get_builtins()[current_action];
+
+ // Convert the list to an array, and only keep key events as this is for the editor.
+ for (List<Ref<InputEvent>>::Element *E = defaults.front(); E; E = E->next()) {
+ Ref<InputEventKey> k = E->get();
+ if (k.is_valid()) {
+ events.append(E->get());
+ }
+ }
+
+ _update_builtin_action(current_action, events);
+ } break;
+ case SHORTCUT_EDIT:
+ case SHORTCUT_ERASE: {
+ // For Edit end Delete, we will show a popup which displays each event so the user can select which one to edit/delete.
+ current_action_events = ti->get_metadata(1);
+ action_popup->clear();
+
+ for (int i = 0; i < current_action_events.size(); i++) {
+ Ref<InputEvent> ie = current_action_events[i];
+ action_popup->add_item(ie->as_text());
+ action_popup->set_item_metadata(i, ie);
+ }
+
+ if (button_idx == SHORTCUT_EDIT) {
+ // If editing, add a button which can be used to add an additional event.
+ action_popup->add_icon_item(get_theme_icon("Add", "EditorIcons"), TTR("Add"));
+ }
+
+ action_popup->set_position(get_position() + get_mouse_position());
+ action_popup->take_mouse_focus();
+ action_popup->popup();
+ action_popup->set_as_minsize();
+ } break;
+ default:
+ break;
}
-
- undo_redo->create_action(TTR("Erase Shortcut"));
- undo_redo->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>());
- undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
- undo_redo->add_do_method(this, "_update_shortcuts");
- undo_redo->add_undo_method(this, "_update_shortcuts");
- undo_redo->add_do_method(this, "_settings_changed");
- undo_redo->add_undo_method(this, "_settings_changed");
- undo_redo->commit_action();
- } else if (p_idx == 2) { //revert to original
- if (!sc.is_valid()) {
- return; //pointless, there is nothing
+ } else {
+ // Editing an Editor Shortcut, which can only have 1 binding.
+ String item = ti->get_metadata(0);
+ Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(item);
+ editing_action = false;
+
+ switch (button_idx) {
+ case EditorSettingsDialog::SHORTCUT_EDIT:
+ shortcut_editor->popup_and_configure(sc->get_shortcut());
+ shortcut_being_edited = item;
+ break;
+ case EditorSettingsDialog::SHORTCUT_ERASE: {
+ if (!sc.is_valid()) {
+ return; //pointless, there is nothing
+ }
+
+ undo_redo->create_action(TTR("Erase Shortcut"));
+ undo_redo->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>());
+ undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
+ undo_redo->add_do_method(this, "_update_shortcuts");
+ undo_redo->add_undo_method(this, "_update_shortcuts");
+ undo_redo->add_do_method(this, "_settings_changed");
+ undo_redo->add_undo_method(this, "_settings_changed");
+ undo_redo->commit_action();
+ } break;
+ case EditorSettingsDialog::SHORTCUT_REVERT: {
+ if (!sc.is_valid()) {
+ return; //pointless, there is nothing
+ }
+
+ Ref<InputEvent> original = sc->get_meta("original");
+
+ undo_redo->create_action(TTR("Restore Shortcut"));
+ undo_redo->add_do_method(sc.ptr(), "set_shortcut", original);
+ undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
+ undo_redo->add_do_method(this, "_update_shortcuts");
+ undo_redo->add_undo_method(this, "_update_shortcuts");
+ undo_redo->add_do_method(this, "_settings_changed");
+ undo_redo->add_undo_method(this, "_settings_changed");
+ undo_redo->commit_action();
+ } break;
+ default:
+ break;
}
-
- Ref<InputEvent> original = sc->get_meta("original");
-
- undo_redo->create_action(TTR("Restore Shortcut"));
- undo_redo->add_do_method(sc.ptr(), "set_shortcut", original);
- undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
- undo_redo->add_do_method(this, "_update_shortcuts");
- undo_redo->add_undo_method(this, "_update_shortcuts");
- undo_redo->add_do_method(this, "_settings_changed");
- undo_redo->add_undo_method(this, "_settings_changed");
- undo_redo->commit_action();
}
}
-void EditorSettingsDialog::_wait_for_key(const Ref<InputEvent> &p_event) {
- Ref<InputEventKey> k = p_event;
-
- if (k.is_valid() && k->is_pressed() && k->get_keycode() != 0) {
- last_wait_for_key = k;
- const String str = keycode_get_string(k->get_keycode_with_modifiers());
-
- press_a_key_label->set_text(str);
- press_a_key->set_input_as_handled();
- }
-}
-
-void EditorSettingsDialog::_press_a_key_confirm() {
- if (last_wait_for_key.is_null()) {
- return;
+void EditorSettingsDialog::_builtin_action_popup_index_pressed(int p_index) {
+ switch (button_idx) {
+ case SHORTCUT_EDIT: {
+ if (p_index == action_popup->get_item_count() - 1) {
+ // Selected last item in list (Add button), therefore add new
+ current_action_event_index = -1;
+ shortcut_editor->popup_and_configure();
+ } else {
+ // Configure existing
+ current_action_event_index = p_index;
+ shortcut_editor->popup_and_configure(action_popup->get_item_metadata(p_index));
+ }
+ } break;
+ case SHORTCUT_ERASE: {
+ current_action_events.remove(p_index);
+ _update_builtin_action(current_action, current_action_events);
+ } break;
+ default:
+ break;
}
-
- Ref<InputEventKey> ie;
- ie.instance();
- ie->set_keycode(last_wait_for_key->get_keycode());
- ie->set_shift(last_wait_for_key->get_shift());
- ie->set_control(last_wait_for_key->get_control());
- ie->set_alt(last_wait_for_key->get_alt());
- ie->set_metakey(last_wait_for_key->get_metakey());
-
- Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured);
-
- undo_redo->create_action(TTR("Change Shortcut") + " '" + shortcut_configured + "'");
- undo_redo->add_do_method(sc.ptr(), "set_shortcut", ie);
- undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
- undo_redo->add_do_method(this, "_update_shortcuts");
- undo_redo->add_undo_method(this, "_update_shortcuts");
- undo_redo->add_do_method(this, "_settings_changed");
- undo_redo->add_undo_method(this, "_settings_changed");
- undo_redo->commit_action();
}
void EditorSettingsDialog::_tabs_tab_changed(int p_tab) {
@@ -382,9 +541,14 @@ void EditorSettingsDialog::_editor_restart_close() {
void EditorSettingsDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorSettingsDialog::_unhandled_input);
ClassDB::bind_method(D_METHOD("_update_shortcuts"), &EditorSettingsDialog::_update_shortcuts);
+ ClassDB::bind_method(D_METHOD("_settings_changed"), &EditorSettingsDialog::_settings_changed);
}
EditorSettingsDialog::EditorSettingsDialog() {
+ action_popup = memnew(PopupMenu);
+ action_popup->connect("index_pressed", callable_mp(this, &EditorSettingsDialog::_builtin_action_popup_index_pressed));
+ add_child(action_popup);
+
set_title(TTR("Editor Settings"));
undo_redo = memnew(UndoRedo);
@@ -442,21 +606,17 @@ EditorSettingsDialog::EditorSettingsDialog() {
// Shortcuts Tab
tab_shortcuts = memnew(VBoxContainer);
+
tabs->add_child(tab_shortcuts);
tab_shortcuts->set_name(TTR("Shortcuts"));
- hbc = memnew(HBoxContainer);
- hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- tab_shortcuts->add_child(hbc);
-
shortcut_search_box = memnew(LineEdit);
shortcut_search_box->set_placeholder(TTR("Search"));
shortcut_search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- hbc->add_child(shortcut_search_box);
+ tab_shortcuts->add_child(shortcut_search_box);
shortcut_search_box->connect("text_changed", callable_mp(this, &EditorSettingsDialog::_filter_shortcuts));
shortcuts = memnew(Tree);
- tab_shortcuts->add_child(shortcuts, true);
shortcuts->set_v_size_flags(Control::SIZE_EXPAND_FILL);
shortcuts->set_columns(2);
shortcuts->set_hide_root(true);
@@ -464,21 +624,13 @@ EditorSettingsDialog::EditorSettingsDialog() {
shortcuts->set_column_title(0, TTR("Name"));
shortcuts->set_column_title(1, TTR("Binding"));
shortcuts->connect("button_pressed", callable_mp(this, &EditorSettingsDialog::_shortcut_button_pressed));
+ tab_shortcuts->add_child(shortcuts);
- press_a_key = memnew(ConfirmationDialog);
- //press_a_key->set_focus_mode(Control::FOCUS_ALL);
- add_child(press_a_key);
-
- Label *l = memnew(Label);
- l->set_text(TTR("Press a Key..."));
- l->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
- l->set_align(Label::ALIGN_CENTER);
- l->set_offset(SIDE_TOP, 20);
- l->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_BEGIN, 30);
- press_a_key_label = l;
- press_a_key->add_child(l);
- press_a_key->connect("window_input", callable_mp(this, &EditorSettingsDialog::_wait_for_key));
- press_a_key->connect("confirmed", callable_mp(this, &EditorSettingsDialog::_press_a_key_confirm));
+ // Adding event dialog
+ shortcut_editor = memnew(InputEventConfigurationDialog);
+ shortcut_editor->connect("confirmed", callable_mp(this, &EditorSettingsDialog::_event_config_confirmed));
+ shortcut_editor->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY);
+ add_child(shortcut_editor);
set_hide_on_ok(true);
diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h
index 044519cb4d..c38fceedf1 100644
--- a/editor/settings_config_dialog.h
+++ b/editor/settings_config_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,6 +31,7 @@
#ifndef SETTINGS_CONFIG_DIALOG_H
#define SETTINGS_CONFIG_DIALOG_H
+#include "editor/action_map_editor.h"
#include "editor/editor_sectioned_inspector.h"
#include "editor_inspector.h"
#include "scene/gui/dialogs.h"
@@ -52,16 +53,28 @@ class EditorSettingsDialog : public AcceptDialog {
LineEdit *shortcut_search_box;
SectionedInspector *inspector;
+ enum ShortcutButton {
+ SHORTCUT_EDIT,
+ SHORTCUT_ERASE,
+ SHORTCUT_REVERT
+ };
+
+ int button_idx;
+ int current_action_event_index = -1;
+ bool editing_action = false;
+ String current_action;
+ Array current_action_events;
+ PopupMenu *action_popup;
+
Timer *timer;
UndoRedo *undo_redo;
- Tree *shortcuts;
- ConfirmationDialog *press_a_key;
- Label *press_a_key_label;
- Ref<InputEventKey> last_wait_for_key;
- String shortcut_configured;
+ // Shortcuts
String shortcut_filter;
+ Tree *shortcuts;
+ InputEventConfigurationDialog *shortcut_editor;
+ String shortcut_being_edited;
virtual void cancel_pressed() override;
virtual void ok_pressed() override;
@@ -74,20 +87,20 @@ class EditorSettingsDialog : public AcceptDialog {
void _notification(int p_what);
void _update_icons();
- void _press_a_key_confirm();
- void _wait_for_key(const Ref<InputEvent> &p_event);
+ void _event_config_confirmed();
+
+ void _update_builtin_action(const String &p_name, const Array &p_events);
void _tabs_tab_changed(int p_tab);
void _focus_current_search_box();
- void _clear_shortcut_search_box();
- void _clear_search_box();
-
void _filter_shortcuts(const String &p_filter);
void _update_shortcuts();
void _shortcut_button_pressed(Object *p_item, int p_column, int p_idx);
+ void _builtin_action_popup_index_pressed(int p_index);
+
static void _undo_redo_callback(void *p_self, const String &p_name);
Label *restart_label;
diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp
index 8345c49a92..ebef5be9ed 100644
--- a/editor/shader_globals_editor.cpp
+++ b/editor/shader_globals_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -427,7 +427,7 @@ void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) {
void ShaderGlobalsEditor::_changed() {
emit_signal("globals_changed");
if (!interface->block_update) {
- interface->_change_notify();
+ interface->notify_property_list_changed();
}
}
@@ -483,8 +483,5 @@ ShaderGlobalsEditor::ShaderGlobalsEditor() {
}
ShaderGlobalsEditor::~ShaderGlobalsEditor() {
- if (is_visible_in_tree()) {
- inspector->edit(nullptr);
- }
memdelete(interface);
}
diff --git a/editor/shader_globals_editor.h b/editor/shader_globals_editor.h
index 00b6cdef9f..84ab6ac063 100644
--- a/editor/shader_globals_editor.h
+++ b/editor/shader_globals_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/translations/af.po b/editor/translations/af.po
index a42302460b..bda0eed750 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -1,6 +1,6 @@
# Afrikaans translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Ray West <the.raxar@gmail.com>, 2017.
# Julius Stopforth <jjstopforth@gmail.com>, 2018.
@@ -659,7 +659,7 @@ msgstr "Stel Oorgange na:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1913,8 +1913,8 @@ msgid "Open a File or Directory"
msgstr "Open 'n Lêer of Gids"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Stoor"
@@ -2011,10 +2011,6 @@ msgstr "Voorskou:"
msgid "File:"
msgstr "Lêer:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Moet 'n geldige uitbreiding gebruik."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "SkandeerBronne"
@@ -2442,6 +2438,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2486,18 +2486,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2546,6 +2534,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2589,7 +2581,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2989,14 +2981,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Soek"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3151,6 +3135,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3357,7 +3357,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3927,8 +3927,18 @@ msgstr "Soek"
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "Deursoek Teks"
+msgid "%d match in %d file."
+msgstr "Geen Pasmaats"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "Geen Pasmaats"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Geen Pasmaats"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4069,6 +4079,21 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Skep Vouer"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Ek sien..."
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Laai Verstek"
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -5067,7 +5092,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5176,7 +5201,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5208,8 +5232,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5223,9 +5246,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Skep Vouer"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6314,6 +6357,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Hernoem AutoLaai"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6374,10 +6422,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6984,6 +7028,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Soek"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7036,16 +7088,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7145,8 +7187,8 @@ msgstr "Skep"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7380,6 +7422,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8649,10 +8695,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8715,10 +8757,6 @@ msgid "Stage All"
msgstr "Vervang Alles"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -10003,6 +10041,11 @@ msgid "Projects"
msgstr "Projek Stigters"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Laai"
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10368,6 +10411,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Laai Verstek"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10618,6 +10666,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Anim Dupliseer Sleutels"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Deursoek Hulp"
@@ -10744,6 +10801,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Anim Dupliseer Sleutels"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11559,6 +11621,35 @@ msgstr "Eienskappe"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Beskrywing"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12075,11 +12166,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12091,11 +12184,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12103,9 +12196,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12341,6 +12444,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12507,27 +12618,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12587,14 +12698,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12804,6 +12914,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Moet 'n geldige uitbreiding gebruik."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12845,6 +12963,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
@@ -12873,6 +12997,10 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "Deursoek Teks"
+
+#, fuzzy
#~ msgid "Move pivot"
#~ msgstr "Skuif Gunsteling Op"
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 2bd95e230b..5c03984e01 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -1,6 +1,6 @@
# Arabic translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Adel <dragonhunter250@gmail.com>, 2018.
# athomield <athomield@hotmail.com>, 2017.
@@ -46,12 +46,14 @@
# Musab Alasaifer <mousablasefer@gmail.com>, 2020.
# Yassine Oudjana <y.oudjana@protonmail.com>, 2020.
# bruvzg <bruvzg13@gmail.com>, 2020.
+# StarlkYT <mrsstarlkps4@gmail.com>, 2020, 2021.
+# Games Toon <xxtvgoodxx@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-07 08:11+0000\n"
-"Last-Translator: Musab Alasaifer <mousablasefer@gmail.com>\n"
+"PO-Revision-Date: 2021-03-07 06:04+0000\n"
+"Last-Translator: StarlkYT <mrsstarlkps4@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
"Language: ar\n"
@@ -60,7 +62,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -683,7 +685,7 @@ msgstr "إختر المقاطع المراد نسخها"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "نسخ"
@@ -1648,7 +1650,6 @@ msgstr ""
"'Import Etc 2' او 'Import Pvrtc' ÙÙŠ إعدادات المشروع."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'PVRTC' texture compression for the driver fallback "
"to GLES2.\n"
@@ -1657,7 +1658,7 @@ msgid ""
msgstr ""
"تتطلب المنصة Ø§Ù„Ù…Ø³ØªÙ‡Ø¯ÙØ© ضغط الرسومات النقشية 'ETC' texture ليرجع المعرّ٠إلى "
"GLES2.\n"
-"مكّن 'استيراد Etc' ÙÙŠ إعدادات المشروع، أو عطّل 'تمكين التواÙÙ‚ الرجعي Ù„Ù„ØªØ¹Ø±ÙŠÙØ§Øª "
+"مَكّÙÙ† 'استيراد Etc' ÙÙŠ إعدادات المشروع، أو عطّل 'تمكين التواÙÙ‚ الرجعي Ù„Ù„ØªØ¹Ø±ÙŠÙØ§Øª "
"Driver Fallback Enabled'."
#: editor/editor_export.cpp platform/android/export/export.cpp
@@ -1701,9 +1702,8 @@ msgid "Node Dock"
msgstr "رصي٠العÙقد"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem Dock"
-msgstr "نظام Ø§Ù„Ù…Ù„ÙØ§Øª"
+msgstr "قوائم نظام Ø§Ù„Ù…Ù„ÙØ§Øª"
#: editor/editor_feature_profile.cpp
msgid "Import Dock"
@@ -1885,8 +1885,8 @@ msgid "Open a File or Directory"
msgstr "Ø¥ÙØªØ­ مل٠أو وجهة"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Ø­ÙØ¸"
@@ -1977,10 +1977,6 @@ msgstr "إستعراض:"
msgid "File:"
msgstr "الملÙ:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "يجب أن يستخدم صيغة صحيحة."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "ÙØ­Øµ المصادر"
@@ -2337,6 +2333,8 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"حدث خطأ ما عند المحاوله Ù„Ø­ÙØ¸ المحرر.\n"
+"تأكد من عنوان بيانات المستخدم للمحرر قابله للكتابه."
#: editor/editor_node.cpp
msgid ""
@@ -2344,6 +2342,9 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"تم تجاوز اعدادات المحرر الاساسيه.\n"
+"لإستعادة اعدادات المحرر, اذهب إلى خيار 'Delete Layout' من ثم Ø¥Ø­ÙØ¸ الاعدادات "
+"الاساسيه."
#: editor/editor_node.cpp
msgid "Layout name not found!"
@@ -2407,6 +2408,10 @@ msgid "There is no defined scene to run."
msgstr "ليس هناك مشهد محدد ليتم تشغيله."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Ø§Ø­ÙØ¸ المشهد قبل التشغيل..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "لا يمكن بدء عملية جانبية!"
@@ -2450,18 +2455,6 @@ msgstr "يتطلب Ø­ÙØ¸ المشهد ØªÙˆØ§ÙØ± عÙقدة رئيسة."
msgid "Save Scene As..."
msgstr "Ø­ÙØ¸ المشهد كـ…"
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "لا"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "نعم"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "هذا المشهد لم يتم Ø­ÙØ¸Ù‡. هل تود Ø­ÙØ¸Ù‡ قبل تشغيله؟"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "هذه العملية لا يمكن الإكتمال من غير مشهد."
@@ -2511,6 +2504,10 @@ msgid "Quit"
msgstr "إنهاء"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "نعم"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "خروج من Ø§Ù„Ù…ÙØ¹Ø¯Ù„ØŸ"
@@ -2557,7 +2554,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "غير قادر علي ØªÙØ¹ÙŠÙ„ Ø¥Ø¶Ø§ÙØ© البرنامج Ø§Ù„Ù…ÙØ³Ø§Ø¹Ø¯ ÙÙŠ: '%s' تحميل الظبط ÙØ´Ù„."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"غير قادر علي إيجاد منطقة النص البرمجي من أجل Ø¥Ø¶Ø§ÙØ© البرنامج ÙÙŠ: 'res://"
"addons/%s'."
@@ -2989,14 +2987,6 @@ msgid "Help"
msgstr "مساعدة"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "بحث"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "مستندات الإنترنت"
@@ -3160,6 +3150,24 @@ msgid "Open & Run a Script"
msgstr "ÙØªØ­ Ùˆ تشغيل كود"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Ø§Ù„Ù…Ù„ÙØ§Øª التالية أحدث على القرص.\n"
+"ما الإجراء الذي ينبغي اتخاذه؟"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "إعادة تحميل"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "إعادة Ø­ÙØ¸"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "موروث جديد"
@@ -3369,7 +3377,7 @@ msgstr "إجعلة مميزاً"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "لصق"
@@ -3920,8 +3928,19 @@ msgid "Searching..."
msgstr "جاري البحث..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "إكتمل البحث"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d تطابقات."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d تطابقات."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d تطابقات."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4057,6 +4076,21 @@ msgstr "هل قمت بإرجاع كائن مشتق من العقدة ÙÙŠ دال
msgid "Saving..."
msgstr "جاري Ø§Ù„Ø­ÙØ¸..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "تحديد الوضع"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "إستيراد"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "تحميل Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Ù…Ù„ÙØ§Øª"
@@ -5023,7 +5057,8 @@ msgid "Got:"
msgstr "ما تم الحصول عليه:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "ÙØ´Ù„ التاكد من ترميز sha256"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5127,7 +5162,6 @@ msgid "Sort:"
msgstr "ترتيب:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Ø§Ù„ÙØ¦Ø©:"
@@ -5156,10 +5190,10 @@ msgid "Assets ZIP File"
msgstr "مل٠أصول مضغوط"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"لا يمكن تحديد مسار Ø­ÙØ¸ لصور خرائط الضوء.\n"
"Ø§Ø­ÙØ¸ مشهدك (لكي ØªØ­ÙØ¸ الصور ÙÙŠ المسار ذاته), او اختر مسار Ø­ÙØ¸ لخصائص خرائط "
@@ -5178,9 +5212,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "لا يمكن انشاء خرائط الضوء, تاكد من ان المسار صحيح."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "إعداد خرائط الضوء"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "حدد مل٠القالب"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6271,6 +6325,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "لا يمكن إنشاء سوى نقطة وحيدة داخل ParticlesMaterial معالج المواد"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "تحويل إلى %s"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "وقت التوليد (تانية):"
@@ -6331,10 +6390,6 @@ msgstr "توليد AABB"
msgid "Generate Visibility AABB"
msgstr "ولد رؤية AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "ولد AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "إزالة نقطة من المنحنى"
@@ -6929,6 +6984,14 @@ msgstr "إغلاق المستندات"
msgid "Run"
msgstr "تشغيل"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "بحث"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "اخط خطوة ضمن"
@@ -6982,16 +7045,6 @@ msgstr ""
"Ø§Ù„Ù…Ù„ÙØ§Øª التالية أحدث على القرص.\n"
"ما الإجراء الذي ينبغي اتخاذه؟:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "إعادة تحميل"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "إعادة Ø­ÙØ¸"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Ù…Ùنقح الأخطاء"
@@ -7085,8 +7138,8 @@ msgstr "نقاط التكسّر"
msgid "Go To"
msgstr "التوجه إلى"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "قص"
@@ -7309,6 +7362,10 @@ msgid "Yaw"
msgstr "الإنحرا٠Yaw"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "الحجم"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "كائنات مرسومة"
@@ -8559,10 +8616,6 @@ msgid "Error"
msgstr "خطأ"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "لم يتم تقديم رسالة ارتكاب commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "لم يتم Ø¥Ø¶Ø§ÙØ© Ù…Ù„ÙØ§Øª إلى المرحلة"
@@ -8619,10 +8672,6 @@ msgid "Stage All"
msgstr "Ù…ÙØ¬Ù…Ù„ المراحل"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Ø¥Ø¶Ø§ÙØ© رسالة إجراء"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "اقترا٠التعديلا"
@@ -10005,6 +10054,11 @@ msgid "Projects"
msgstr "المشاريع"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "يستقبل المرايا، من ÙØ¶Ù„Ùƒ إنتظر..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "آخر ما تم تعديله"
@@ -10374,6 +10428,11 @@ msgstr "تحميل تلقائي"
msgid "Plugins"
msgstr "Ø¥Ø¶Ø§ÙØ§Øª"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "تحميل Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "إعداد Ù…ÙØ³Ø¨Ù‚..."
@@ -10435,9 +10494,8 @@ msgid "Batch Rename"
msgstr "إعادة تسمية Ø§Ù„Ø¯ÙØ¹Ø©"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Replace:"
-msgstr "إستبدال: "
+msgstr "إستبدال:"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10626,6 +10684,16 @@ msgid "Instance Child Scene"
msgstr "نمذجة المشهد الابن"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "لا يمكن تنÙيذ الإجراء على عÙقدة من مشهد أجنبي!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "لصق العÙقد"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "ÙØµÙ„ النص البرمجي"
@@ -10753,6 +10821,11 @@ msgid "Attach Script"
msgstr "إلحاق نص برمجي"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "قص العÙقد"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "إزالة عÙقدة (عÙقد)"
@@ -11558,6 +11631,39 @@ msgstr ""
"امنح مكتبة السطوح MeshLibrary وصولاً لخريطة الشبكة لتستخدم السطوح المجسمة "
"الخاصة بها meshes."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "ولد AABB"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "الاتجاهات"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "Ø§Ù„Ù…Ø³Ø§ÙØ© البادئة يميناً"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "المعالجة-اللاحقة Post-Process"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "تخطيط الإضاءات:"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "لا يمكن أن يكون اسم الص٠كلمة محجوزة"
@@ -12066,14 +12172,15 @@ msgid "Select device from the list"
msgstr "اختر جهازاً من القائمة"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "لم يتم تهيئة Ù…ÙÙ†Ùّذ ADB ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
+msgid "Unable to find the 'apksigner' tool."
+msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
-"‌مÙوقّع Ù…Ù„ÙØ§Øª الجار jarsigner Ø§Ù„Ù…ÙØªÙˆØ­ الخاص بحزمة التطوير OpenJDK غير Ù…Ùهيّئ ÙÙŠ "
-"إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
+"لم يتم تنزيل قالب بناء Android لهذا المشروع. نزّل واحداً من قائمة المشروع."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12086,12 +12193,14 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "تحرر مخزن Ø§Ù„Ù…ÙØ§ØªÙŠØ­ غير Ù…Ùهيئ بشكل صحيح ÙÙŠ إعدادت المسبقة للتصدير."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#, fuzzy
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"البÙنى المخصوصة تتطلب مساراً لحزمة تطوير Android SDK صالحة ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
+"مسار حزمة تطوير Android SDK للبÙنى المخصوصة، غير صالح ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+#, fuzzy
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
"مسار حزمة تطوير Android SDK للبÙنى المخصوصة، غير صالح ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
@@ -12100,11 +12209,22 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+#, fuzzy
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"مسار حزمة تطوير Android SDK للبÙنى المخصوصة، غير صالح ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
-"لم يتم تنزيل قالب بناء Android لهذا المشروع. نزّل واحداً من قائمة المشروع."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12362,6 +12482,14 @@ msgstr ""
"Ù…ÙØ¶Ù„ع تصادم ثنائي الأبعاد (CollisionPolygon2D) Ø§Ù„ÙØ§Ø±Øº ليس له أي تأثير على "
"التصادم."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12584,28 +12712,32 @@ msgstr ""
"(KinematicBody2D)، وما إلى ذلك لمنحهم شكلاً."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(الوقت المتبقي: %d:%02d ثانية)"
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "توزيع الأشكال الهندسية..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "تخطيط المجسمات: "
+#, fuzzy
+msgid "Preparing environment"
+msgstr "عرض البيئة"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "تخطيط الإضاءات:"
+#, fuzzy
+msgid "Generating capture"
+msgstr "انشاء خارطة الضوء"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "الانتهاء من التخطيط"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "انشاء خارطة الضوء"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "إضاءة المجسمات: "
+msgid "Done"
+msgstr "تم"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12683,6 +12815,10 @@ msgid "Plotting Meshes"
msgstr "تخطيط المجسمات"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "الانتهاء من التخطيط"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12690,11 +12826,6 @@ msgstr ""
"GIProbes لا يدعم برنامج تشغيل الÙيديو GLES2.\n"
"استخدم BakedLightmap بدلاً من ذلك."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "بقعة الضوء بزاوية أكبر من 90 درجة لا يمكنها إلقاء الظلال."
@@ -12939,6 +13070,15 @@ msgstr "تنبيه!"
msgid "Please Confirm..."
msgstr "ÙŠÙØ±Ø¬Ù‰ التأكيد..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "يجب أن يستخدم صيغة صحيحة."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "تمكين المحاذاة"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12991,6 +13131,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "ينبغي أن يكون حجم إطار العرض أكبر من 0 ليتم الإخراج البصري لأي شيء."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "مصدر غير صالح للمعاينة."
@@ -13018,6 +13164,46 @@ msgstr "يمكن تعيين المتغيرات Ùقط ÙÙŠ الذروة ."
msgid "Constants cannot be modified."
msgstr "لا يمكن تعديل الثوابت."
+#~ msgid "No"
+#~ msgstr "لا"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "هذا المشهد لم يتم Ø­ÙØ¸Ù‡. هل تود Ø­ÙØ¸Ù‡ قبل تشغيله؟"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "لم يتم تهيئة Ù…ÙÙ†Ùّذ ADB ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr ""
+#~ "‌مÙوقّع Ù…Ù„ÙØ§Øª الجار jarsigner Ø§Ù„Ù…ÙØªÙˆØ­ الخاص بحزمة التطوير OpenJDK غير Ù…Ùهيّئ "
+#~ "ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "البÙنى المخصوصة تتطلب مساراً لحزمة تطوير Android SDK صالحة ÙÙŠ إعدادات "
+#~ "Ø§Ù„Ù…ÙØ­Ø±Ø±."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(الوقت المتبقي: %d:%02d ثانية)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "تخطيط المجسمات: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "إضاءة المجسمات: "
+
+#~ msgid "Search complete"
+#~ msgstr "إكتمل البحث"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "لم يتم تقديم رسالة ارتكاب commit"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Ø¥Ø¶Ø§ÙØ© رسالة إجراء"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "يوجد Ø¨Ø§Ù„ÙØ¹Ù„ مل٠أو مجلد Ø¨Ù†ÙØ³ الاسم ÙÙŠ هذا المكان."
@@ -13243,9 +13429,6 @@ msgstr "لا يمكن تعديل الثوابت."
#~ msgid "Failed to save solution."
#~ msgstr "ÙØ´Ù„ Ø­ÙØ¸ الحل."
-#~ msgid "Done"
-#~ msgstr "تم"
-
#~ msgid "Failed to create C# project."
#~ msgstr "ÙØ´Ù„ إنشاء مشروع C#‎."
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 2f1a9145e4..47fd10411a 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -1,6 +1,6 @@
# Bulgarian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Bojidar Marinov <bojidar.marinov.bg@gmail.com>, 2016.
# Иван Пенев (Ðдмирал ÐнимЕ) <aeternus.arcis@gmail.com>, 2016-2017.
@@ -11,13 +11,13 @@
# Whod <whodizhod@gmail.com>, 2020.
# Stoyan <stoyan.stoyanov99@protonmail.com>, 2020.
# zooid <the.zooid@gmail.com>, 2020.
-# Любомир ВаÑилев <lyubomirv@gmx.com>, 2020.
+# Любомир ВаÑилев <lyubomirv@gmx.com>, 2020, 2021.
# Ziv D <wizdavid@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-07 08:11+0000\n"
+"PO-Revision-Date: 2021-02-15 10:51+0000\n"
"Last-Translator: Любомир ВаÑилев <lyubomirv@gmx.com>\n"
"Language-Team: Bulgarian <https://hosted.weblate.org/projects/godot-engine/"
"godot/bg/>\n"
@@ -26,7 +26,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -640,7 +640,7 @@ msgstr "Изберете пътечки за копиране"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Копиране"
@@ -681,13 +681,12 @@ msgid "Line Number:"
msgstr "Ðомер на реда:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "ЗамÑна..."
+msgstr "%d заменени."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr ""
+msgstr "%d Ñъвпадение."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d matches."
@@ -695,7 +694,7 @@ msgstr "%d ÑъвпадениÑ."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
-msgstr ""
+msgstr "Различаване на малки и главни букви"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Whole Words"
@@ -1812,8 +1811,8 @@ msgid "Open a File or Directory"
msgstr "ОтварÑне на файл или папка"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Запазване"
@@ -1904,10 +1903,6 @@ msgstr ""
msgid "File:"
msgstr "Файл:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "ТрÑбва да Ñе използва правилно разширение."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2237,11 +2232,11 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
-msgstr ""
+msgstr "Ðе може да Ñе зареди библиотеката Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи за Ñливане!"
#: editor/editor_node.cpp
msgid "Error saving MeshLibrary!"
-msgstr ""
+msgstr "Грешка при запазването на библиотеката Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи!"
#: editor/editor_node.cpp
msgid "Can't load TileSet for merging!"
@@ -2311,6 +2306,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2354,25 +2353,13 @@ msgstr ""
msgid "Save Scene As..."
msgstr "Запазване на Ñцената като..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Ðе"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Тази Ñцена не е била запазвана преди. Запазване преди изпълнението?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "ОперациÑта не може да Ñе извърши без Ñцена."
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr ""
+msgstr "ИзнаÑÑне на библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
@@ -2413,6 +2400,10 @@ msgid "Quit"
msgstr "Изход"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2455,8 +2446,9 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "Ðе може да Ñе зареди Ñкриптът на добавка от: „%s“."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2650,7 +2642,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr ""
+msgstr "Библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи…"
#: editor/editor_node.cpp
msgid "TileSet..."
@@ -2767,6 +2759,8 @@ msgid ""
"When this option is enabled, navigation meshes and polygons will be visible "
"in the running project."
msgstr ""
+"Ðко тази наÑтройка е включено, навигационните полигони и мрежи ще бъдат "
+"видими в изпълнÑÐ²Ð°Ñ‰Ð¸Ñ Ñе проект."
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
@@ -2845,14 +2839,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "ТърÑене"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3007,6 +2993,25 @@ msgstr ""
#: editor/editor_node.cpp
#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Следните файлове Ñа по-нови на диÑка.\n"
+"Кое дейÑтвие трÑбва да Ñе предприеме?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Презареждане"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "ПрезапиÑване"
+
+#: editor/editor_node.cpp
+#, fuzzy
msgid "New Inherited"
msgstr "Ðов Ñкрипт"
@@ -3209,7 +3214,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "ПоÑтавÑне"
@@ -3745,8 +3750,16 @@ msgid "Searching..."
msgstr "ТърÑене..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "ТърÑенето е завършено"
+msgid "%d match in %d file."
+msgstr "%d Ñъвпадение в %d файл."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d ÑÑŠÐ²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ð² %d файл."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d ÑÑŠÐ²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ð² %d файла."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -3856,7 +3869,7 @@ msgstr ""
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
-msgstr ""
+msgstr "Създаване за полигонна мрежа: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
@@ -3882,6 +3895,21 @@ msgstr ""
msgid "Saving..."
msgstr "Запазване..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Режим на избиране"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "ВнаÑÑне"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Задаване на входен порт по подразбиране"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Файлове"
@@ -3970,15 +3998,15 @@ msgstr ""
#: editor/inspector_dock.cpp
msgid "Save the currently edited resource."
-msgstr ""
+msgstr "Запазване на текущо Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ð¸Ñ Ñ€ÐµÑурÑ."
#: editor/inspector_dock.cpp
msgid "Go to the previous edited object in history."
-msgstr ""
+msgstr "Преминаване към Ð¿Ñ€ÐµÐ´Ñ…Ð¾Ð´Ð½Ð¸Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½ обект в иÑториÑта."
#: editor/inspector_dock.cpp
msgid "Go to the next edited object in history."
-msgstr ""
+msgstr "Преминаване към ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½ обект в иÑториÑта."
#: editor/inspector_dock.cpp
msgid "History of recently edited objects."
@@ -4002,7 +4030,7 @@ msgstr ""
#: editor/node_dock.cpp
msgid "Select a single node to edit its signals and groups."
-msgstr ""
+msgstr "Изберете един възел, за да редактирате Ñигналите и групите му."
#: editor/plugin_config_dialog.cpp
msgid "Edit a Plugin"
@@ -4064,11 +4092,11 @@ msgstr "Редактиране на полигона"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Insert Point"
-msgstr ""
+msgstr "Вмъкване на точка"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Edit Polygon (Remove Point)"
-msgstr ""
+msgstr "Редактиране на полигона (премахване на точка)"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Remove Polygon And Point"
@@ -4107,6 +4135,7 @@ msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
msgid "This type of node can't be used. Only root nodes are allowed."
msgstr ""
+"Този тип възел не може да бъде използван. Разрешени Ñа Ñамо коренни възли."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4134,11 +4163,14 @@ msgid ""
"AnimationTree is inactive.\n"
"Activate to enable playback, check node warnings if activation fails."
msgstr ""
+"AnimationTree не е активен.\n"
+"Ðктивирайте го, за да включите възпроизвеждането. Ðко не Ñтане, проверете "
+"дали има предупредителни ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾Ñно възлите."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Set the blending position within the space"
-msgstr ""
+msgstr "Задаване на точката на ÑмеÑване в проÑтранÑтвото"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4148,12 +4180,12 @@ msgstr "Избиране и премеÑтване на точки; Ñъздав
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
msgid "Enable snap and show grid."
-msgstr ""
+msgstr "Включване на прилепването и показване на решетката."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Point"
-msgstr ""
+msgstr "Точка"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4198,7 +4230,7 @@ msgstr "BlendSpace2D не принадлежи на възел от тип Anima
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "No triangles exist, so no blending can take place."
-msgstr ""
+msgstr "СмеÑването е невъзможно, тъй като нÑма нито един триъгълник."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Toggle Auto Triangles"
@@ -4206,24 +4238,24 @@ msgstr "Превключване на автоматичните триъгълÐ
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Create triangles by connecting points."
-msgstr ""
+msgstr "Създаване на триъгълници чрез Ñвързване на точки."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Erase points and triangles."
-msgstr ""
+msgstr "Изтриване на точки и триъгълници."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Generate blend triangles automatically (instead of manually)"
-msgstr ""
+msgstr "Създаване на триъгълници за ÑмеÑване автоматично (а не ръчно)"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend:"
-msgstr ""
+msgstr "СмеÑване:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Parameter Changed"
-msgstr ""
+msgstr "Параметърът е променен"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -4245,6 +4277,8 @@ msgstr "Възелът е премеÑтен"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
msgstr ""
+"Свързването е невъзможно. Портът може би е зает, или връзката да е "
+"неправилна."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -4268,7 +4302,7 @@ msgstr "Изтриване на възела"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
msgid "Delete Node(s)"
-msgstr ""
+msgstr "Изтриване на възела/възлите"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Toggle Filter On/Off"
@@ -4276,7 +4310,7 @@ msgstr "Превключване на филтъра ВКЛ/ИЗКЛ"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Change Filter"
-msgstr ""
+msgstr "ПромÑна на филтъра"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
@@ -4334,7 +4368,7 @@ msgstr "Ðово име на анимациÑта:"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Anim"
-msgstr ""
+msgstr "Ðова анимациÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
@@ -4348,20 +4382,20 @@ msgstr "Изтриване на анимациÑта?"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Remove Animation"
-msgstr ""
+msgstr "Премахване на анимациÑта"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Invalid animation name!"
-msgstr ""
+msgstr "Ðеправилно име на анимациÑта!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation name already exists!"
-msgstr ""
+msgstr "Вече ÑъщеÑтвува Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ñ Ñ‚Ð¾Ð²Ð° име!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Rename Animation"
-msgstr ""
+msgstr "Преименуване на анимациÑта"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Next Changed"
@@ -4369,19 +4403,19 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Blend Time"
-msgstr ""
+msgstr "ПромÑна на времето на ÑмеÑване"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Load Animation"
-msgstr ""
+msgstr "Зареждане на анимациÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
-msgstr ""
+msgstr "Дублиране на анимациÑта"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation to copy!"
-msgstr ""
+msgstr "ÐÑма Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° копиране!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation resource on clipboard!"
@@ -4389,11 +4423,11 @@ msgstr "ÐÑма реÑурÑâ€“Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð² буфера за обмен
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
-msgstr ""
+msgstr "ПоÑтавена анимациÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Paste Animation"
-msgstr ""
+msgstr "ПоÑтавÑне на анимациÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation to edit!"
@@ -4402,30 +4436,32 @@ msgstr "ÐÑма Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° редактиране!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
msgstr ""
+"Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾ от текущата позициÑ. (A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from end. (Shift+A)"
-msgstr ""
+msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð°Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾ от краÑ. (Shift+A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Stop animation playback. (S)"
-msgstr ""
+msgstr "Спиране на възпроизвеждането на анимациÑта. (S)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from start. (Shift+D)"
-msgstr ""
+msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ началото. (Shift+D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from current pos. (D)"
-msgstr ""
+msgstr "Възпроизвеждане на избраната Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ текущата позициÑ. (D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation position (in seconds)."
-msgstr ""
+msgstr "ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð² анимациÑта (в Ñекунди)."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Scale animation playback globally for the node."
msgstr ""
+"Скалиране на ÑкороÑтта на възпроизвеждане на анимациÑта глобално за възела."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Tools"
@@ -4433,7 +4469,7 @@ msgstr "ИнÑтрументи за анимациите"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation"
-msgstr ""
+msgstr "ÐнимациÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Edit Transitions..."
@@ -4441,7 +4477,7 @@ msgstr "Редактиране на преходите..."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Open in Inspector"
-msgstr ""
+msgstr "ОтварÑне в инÑпектора"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
@@ -4449,52 +4485,51 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Autoplay on Load"
-msgstr ""
+msgstr "Ðвт. възпроизвеждане при зареждане"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Enable Onion Skinning"
-msgstr ""
+msgstr "Показване на избледнÑващи кадри"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Onion Skinning Options"
-msgstr ""
+msgstr "ÐаÑтройки на режима Ñ Ð¸Ð·Ð±Ð»ÐµÐ´Ð½Ñващи кадри"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Directions"
msgstr "ÐаправлениÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Past"
-msgstr "ПоÑтавÑне"
+msgstr "Минало"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Future"
-msgstr ""
+msgstr "Бъдеще"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
-msgstr ""
+msgstr "Дълбочина"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "1 step"
-msgstr ""
+msgstr "1 Ñтъпка"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "2 steps"
-msgstr ""
+msgstr "2 Ñтъпки"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "3 steps"
-msgstr ""
+msgstr "3 Ñтъпки"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Differences Only"
-msgstr ""
+msgstr "Само разликите"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Force White Modulate"
-msgstr ""
+msgstr "Принудително модулиране на бÑлото"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Include Gizmos (3D)"
@@ -4506,11 +4541,11 @@ msgstr "Закачане на AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Create New Animation"
-msgstr ""
+msgstr "Създаване на нова анимациÑ"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
-msgstr ""
+msgstr "Име на анимациÑта:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
@@ -4521,15 +4556,15 @@ msgstr "Грешка!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Times:"
-msgstr ""
+msgstr "Времена на ÑмеÑване:"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Next (Auto Queue):"
-msgstr ""
+msgstr "Следваща (авт. опашка):"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Cross-Animation Blend Times"
-msgstr ""
+msgstr "Времена на ÑмеÑване между анимациите"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Move Node"
@@ -4546,23 +4581,23 @@ msgstr "ДобавÑне на преход"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node"
-msgstr ""
+msgstr "ДобавÑне на възел"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "End"
-msgstr ""
+msgstr "Край"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Immediate"
-msgstr ""
+msgstr "Ðезабавно"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Sync"
-msgstr ""
+msgstr "Синхронизиране"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "At End"
-msgstr ""
+msgstr "Ðа краÑ"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Travel"
@@ -4790,17 +4825,15 @@ msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, return code:"
-msgstr "ЗаÑвката Ñе провали. Код:"
+msgstr "ЗаÑвката беше неуÑпешна. Код:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Request failed."
-msgstr "Запитване..."
+msgstr "ЗаÑвката беше неуÑпешна."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Cannot save response to:"
-msgstr "Ðе може да Ñе премахне:"
+msgstr "Отговорът не може да бъде запазен в:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Write error."
@@ -4835,7 +4868,8 @@ msgid "Got:"
msgstr "Получено:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "ÐеуÑпешна проверка на хеш от вид „sha256“"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4895,14 +4929,12 @@ msgid "Name (Z-A)"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (A-Z)"
-msgstr "Лиценз"
+msgstr "Лиценз (Ð-Я)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (Z-A)"
-msgstr "Лиценз"
+msgstr "Лиценз (Я-Ð)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "First"
@@ -4941,7 +4973,6 @@ msgid "Sort:"
msgstr "Сортиране:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "КатегориÑ:"
@@ -4962,9 +4993,8 @@ msgid "Testing"
msgstr "ТеÑтово"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Loading..."
-msgstr "Зареди..."
+msgstr "Зареждане…"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -4973,23 +5003,54 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
+"Ðе може да Ñе уÑтанови пътÑÑ‚ за запазване на Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ ÐºÐ°Ñ€Ñ‚Ð¸ на "
+"оÑветеноÑÑ‚.\n"
+"Запазете Ñцената и опитайте отново."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake "
"Light' flag is on."
msgstr ""
+"ÐÑма полигонни мрежи за изпичане. Уверете Ñе, че те Ñъдържат канал UV2 и че "
+"флагът „Изпичане на Ñветлината“ е включен."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
+"Грешка при Ñъздаването на Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ ÐºÐ°Ñ€Ñ‚Ð¸ на оÑветеноÑÑ‚. Уверете Ñе, че "
+"пътÑÑ‚ е доÑтъпен за запиÑ."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
-msgid "Bake Lightmaps"
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
msgstr ""
+"Ðе може да Ñе определи размерът на картата на оÑветеноÑÑ‚. Твърде малък ли е "
+"макÑималниÑÑ‚ размер?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Има неподходÑща полигонна мрежа. Уверете Ñе, че ÑтойноÑтите в канала UV2 Ñе "
+"принадлежат на квадратната облаÑÑ‚ [0.0,1.0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Редакторът на Godot е бил компилиран без поддръжка за траÑиране на лъчи. Ðе "
+"могат да Ñе изпичат карти на оÑветеноÑÑ‚."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Bake Lightmaps"
+msgstr "Изпичане на карти на оÑветеноÑÑ‚"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Изберете файл за изпичане на карта на оÑветеноÑÑ‚:"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -4998,71 +5059,63 @@ msgstr "Преглед"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
-msgstr ""
+msgstr "ÐаÑтройване на прилепването"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Offset:"
-msgstr ""
+msgstr "ОтмеÑтване на мрежата:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Step:"
-msgstr ""
+msgstr "Стъпка на мрежата:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Primary Line Every:"
-msgstr ""
+msgstr "ОÑновна Ð»Ð¸Ð½Ð¸Ñ Ð½Ð° вÑеки:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "steps"
-msgstr ""
+msgstr "Ñтъпки"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
-msgstr "ИзмеÑтване на въртенето:"
+msgstr "ОтмеÑтване при завъртане:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Step:"
msgstr "Стъпка при завъртане:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale Step:"
-msgstr "Мащаб:"
+msgstr "Стъпка на мащабиране:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move Vertical Guide"
-msgstr "ПемеÑти вертикална помощна линиÑ"
+msgstr "ПремеÑтване на Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»Ð½Ð¸Ñ Ð²Ð¾Ð´Ð°Ñ‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Vertical Guide"
-msgstr "Създай нова вертикална помощна линиÑ"
+msgstr "Създаване на нов вертикален водач"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Vertical Guide"
-msgstr "Премахни вертикална помощна линиÑ"
+msgstr "Премахване на Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»Ð½Ð¸Ñ Ð²Ð¾Ð´Ð°Ñ‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move Horizontal Guide"
-msgstr "ПремеÑти хоризонтална помощна линиÑ"
+msgstr "ПремеÑтване на Ñ…Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»Ð½Ð¸Ñ Ð²Ð¾Ð´Ð°Ñ‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Horizontal Guide"
-msgstr "Създай нова хоризонтална помощна линиÑ"
+msgstr "Създаване на нов хоризонтален водач"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Horizontal Guide"
-msgstr "Премахни хоризонтална помощна линиÑ"
+msgstr "Премахване на Ñ…Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»Ð½Ð¸Ñ Ð²Ð¾Ð´Ð°Ñ‡"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Horizontal and Vertical Guides"
-msgstr "Създай нова хоризонтална и вертикална помощна линиÑ"
+msgstr "Създаване на нов хоризонтален и вертикален водач"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
@@ -5121,44 +5174,36 @@ msgid ""
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Left"
-msgstr "Режим на Завъртане"
+msgstr "Горе влÑво"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Right"
-msgstr "Завъртане на Полигон"
+msgstr "Горе вдÑÑно"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Right"
-msgstr "Завъртане на Полигон"
+msgstr "Долу вдÑÑно"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Left"
-msgstr "Режим на Завъртане"
+msgstr "Долу влÑво"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Left"
-msgstr "Центрирай върху СелекциÑта"
+msgstr "По Ñредата влÑво"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Top"
-msgstr "Центрирай върху СелекциÑта"
+msgstr "По Ñредата горе"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Right"
-msgstr "Завъртане на Полигон"
+msgstr "По Ñредата вдÑÑно"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Bottom"
-msgstr "Центрирай върху СелекциÑта"
+msgstr "По Ñредата долу"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center"
@@ -5224,9 +5269,8 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected"
-msgstr "Изберете метод"
+msgstr "Заключване на избраното"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5235,29 +5279,25 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected"
-msgstr "Ðова Ñцена"
+msgstr "Групиране на избраното"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected"
-msgstr "Ðова Ñцена"
+msgstr "Разгрупиране на избраното"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Guides"
-msgstr "Възпроизвеждане на Ñцена по избор"
+msgstr "ИзчиÑтване на водачите"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
-msgstr "Възпроизвеждане на Ñцена по избор"
+msgstr "Създаване на перÑонализирана(и) коÑÑ‚(и) от възела(възлите)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Bones"
@@ -5452,7 +5492,7 @@ msgstr "Преглед"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Always Show Grid"
-msgstr ""
+msgstr "Винаги да Ñе показва решетката"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
@@ -5460,11 +5500,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Rulers"
-msgstr ""
+msgstr "Показване на линиите"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Guides"
-msgstr ""
+msgstr "Показване на водачите"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Origin"
@@ -5659,12 +5699,12 @@ msgstr ""
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emission Points From Mesh"
-msgstr ""
+msgstr "Създаване на излъчващи точки от полигонната мрежа"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emission Points From Node"
-msgstr ""
+msgstr "Създаване на излъчващи точки от възела"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Flat 0"
@@ -5761,7 +5801,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh is empty!"
-msgstr ""
+msgstr "Полигонната мрежа е празна!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
#, fuzzy
@@ -5806,19 +5846,21 @@ msgstr "Създаване на нÑколко изпъкнали форми"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
-msgstr ""
+msgstr "Създаване на навигационна полигонна мрежа"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Contained Mesh is not of type ArrayMesh."
-msgstr ""
+msgstr "Съдържащата Ñе полигонна мрежа не е от тип ArrayMesh."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "UV Unwrap failed, mesh may not be manifold?"
msgstr ""
+"Разгъването на UV беше неуÑпешно. Възможно ли е полигонната мрежа да Ñе "
+"ÑÑŠÑтои от повече от една форма?"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "No mesh to debug."
-msgstr ""
+msgstr "ÐÑма полигонна мрежа за дебъгване."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Model has no UV in this layer"
@@ -5826,15 +5868,15 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "MeshInstance lacks a Mesh!"
-msgstr ""
+msgstr "Ð’ MeshInstance нÑма полигонна мрежа!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh has not surface to create outlines from!"
-msgstr ""
+msgstr "Полигонната мрежа нÑма повърхноÑÑ‚, от коÑто да Ñе Ñъздадат контури!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
-msgstr ""
+msgstr "ПримитивниÑÑ‚ тип на полигонната мрежа не е PRIMITIVE_TRIANGLES!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Could not create outline!"
@@ -5846,7 +5888,7 @@ msgstr "Създаване на контур"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr ""
+msgstr "Полигонна мрежа"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -5893,7 +5935,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh..."
-msgstr ""
+msgstr "Създаване на контурна полигонна мрежа…"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -5902,6 +5944,10 @@ msgid ""
"This can be used instead of the SpatialMaterial Grow property when using "
"that property isn't possible."
msgstr ""
+"Създава Ñтатична полигонна мрежа за контура. Ðормалите на контурната "
+"полигонна мрежа ще бъдат автоматично обърнати.\n"
+"Това може да Ñе използва вмеÑто ÑвойÑтвото Grow на SpatialMaterial, когато "
+"това ÑвойÑтво не може да Ñе променÑ."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "View UV1"
@@ -5917,7 +5963,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh"
-msgstr ""
+msgstr "Създаване на контурна полигонна мрежа"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Outline Size:"
@@ -5940,9 +5986,8 @@ msgstr ""
"%s"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid "Mesh Library"
-msgstr "ИзнаÑÑне на библиотеката"
+msgstr "Библиотека Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð¸ мрежи"
#: editor/plugins/mesh_library_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
@@ -5964,22 +6009,27 @@ msgstr "ОбновÑване от Ñцена"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and no MultiMesh set in node)."
msgstr ""
+"ÐÑма поÑочен източник за полигонна мрежа (и във възела нÑма MultiMesh)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and MultiMesh contains no Mesh)."
msgstr ""
+"ÐÑма поÑочен източник за полигонна мрежа (и MultiMesh не Ñъдържа полигонна "
+"мрежа)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (invalid path)."
-msgstr ""
+msgstr "Източникът за полигонна мрежа е неправилен (грешен път)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (not a MeshInstance)."
-msgstr ""
+msgstr "Източникът за полигонна мрежа е неправилен (не е MeshInstance)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (contains no Mesh resource)."
msgstr ""
+"Източникът за полигонна мрежа е неправилен (не Ñъдържа реÑурÑ, който е "
+"полигонна мрежа)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No surface source specified."
@@ -5999,7 +6049,7 @@ msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
-msgstr ""
+msgstr "Изберете източник за полигонна мрежа:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Target Surface:"
@@ -6019,7 +6069,7 @@ msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Source Mesh:"
-msgstr ""
+msgstr "Източник за полигонна мрежа:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "X-Axis"
@@ -6035,7 +6085,7 @@ msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh Up Axis:"
-msgstr ""
+msgstr "ÐžÑ Ñочеща нагоре за полигонната мрежа:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Random Rotation:"
@@ -6076,6 +6126,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Преобразуване в CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6085,9 +6139,8 @@ msgid "The geometry's faces don't contain any area."
msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "The geometry doesn't contain any faces."
-msgstr "Възелът не Ñъдържа Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ (лица)."
+msgstr "ГеометриÑта не Ñъдържа Ñтрани."
#: editor/plugins/particles_editor_plugin.cpp
msgid "\"%s\" doesn't inherit from Spatial."
@@ -6098,9 +6151,8 @@ msgid "\"%s\" doesn't contain geometry."
msgstr "„%s“ не Ñъдържа геометриÑ."
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "\"%s\" doesn't contain face geometry."
-msgstr "Възелът не Ñъдържа геометриÑ."
+msgstr "„%s“ не Ñъдържа Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ ÑÑŠÑ Ñтрани."
#: editor/plugins/particles_editor_plugin.cpp
msgid "Create Emitter"
@@ -6108,15 +6160,15 @@ msgstr ""
#: editor/plugins/particles_editor_plugin.cpp
msgid "Emission Points:"
-msgstr ""
+msgstr "Излъчващи точки:"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Surface Points"
-msgstr ""
+msgstr "Точки на повърхноÑтта"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Surface Points+Normal (Directed)"
-msgstr ""
+msgstr "Точки на повърхноÑтта + нормали (наÑочени)"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Volume"
@@ -6124,7 +6176,7 @@ msgstr "Обем"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Emission Source: "
-msgstr ""
+msgstr "Източник на излъчването: "
#: editor/plugins/particles_editor_plugin.cpp
msgid "A processor material of type 'ParticlesMaterial' is required."
@@ -6138,10 +6190,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6723,6 +6771,14 @@ msgstr "ЗатварÑне на документациÑта"
msgid "Run"
msgstr "ПуÑкане"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "ТърÑене"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6776,16 +6832,6 @@ msgstr ""
"Следните файлове Ñа по-нови на диÑка.\n"
"Кое дейÑтвие трÑбва да Ñе предприеме?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Презареждане"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "ПрезапиÑване"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Дебъгер"
@@ -6878,8 +6924,8 @@ msgstr "Точки на прекъÑване"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "ИзрÑзване"
@@ -7102,6 +7148,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -7274,9 +7324,8 @@ msgid "Freelook Speed Modifier"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Freelook Slow Modifier"
-msgstr "Свободен Изглед Отпред"
+msgstr "Модификатор за забавÑне на ÑÐ²Ð¾Ð±Ð¾Ð´Ð½Ð¸Ñ Ð¸Ð·Ð³Ð»ÐµÐ´"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Rotation Locked"
@@ -7528,15 +7577,15 @@ msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't replace by mesh."
-msgstr ""
+msgstr "Ðеправилна геометриÑ. Ðе може да Ñе замени Ñ Ð¿Ð¾Ð»Ð¸Ð³Ð¾Ð½Ð½Ð° мрежа."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Convert to Mesh2D"
-msgstr ""
+msgstr "Преобразуване в Mesh2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
-msgstr ""
+msgstr "Ðеправилна геометриÑ, не може да Ñе Ñъздаде полигон."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Convert to Polygon2D"
@@ -7544,7 +7593,7 @@ msgstr "Превръщане в Polygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create collision polygon."
-msgstr ""
+msgstr "Ðеправилна геометриÑ, не може да Ñе Ñъздаде полигон за колизии."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create CollisionPolygon2D Sibling"
@@ -7556,7 +7605,7 @@ msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create LightOccluder2D Sibling"
-msgstr ""
+msgstr "Създаване на ÑÑŠÑеден LightOccluder2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite"
@@ -7564,15 +7613,15 @@ msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Simplification: "
-msgstr ""
+msgstr "ОпроÑÑ‚Ñване: "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Shrink (Pixels): "
-msgstr ""
+msgstr "СмалÑване (пикÑели): "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Grow (Pixels): "
-msgstr ""
+msgstr "УголемÑване (пикÑели): "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Update Preview"
@@ -7588,11 +7637,11 @@ msgstr "ÐÑма избрани кадри"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add %d Frame(s)"
-msgstr ""
+msgstr "ДобавÑне на %d кадър/кадри"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
-msgstr ""
+msgstr "ДобавÑне на кадър"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Unable to load images"
@@ -7600,27 +7649,27 @@ msgstr "ИзображениÑта не могат да бъдат заредеÐ
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
-msgstr ""
+msgstr "ГРЕШКÐ: Ðе може да Ñе зареди реÑурÑÑŠÑ‚ Ñ ÐºÐ°Ð´ÑŠÑ€Ð°!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Resource clipboard is empty or not a texture!"
-msgstr ""
+msgstr "Буферът за обмен на реÑурÑи е празен или не Ñъдържа текÑтура!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Paste Frame"
-msgstr ""
+msgstr "ПоÑтавÑне на кадър"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Empty"
-msgstr ""
+msgstr "ДобавÑне на празен"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation FPS"
-msgstr ""
+msgstr "ПромÑна на ÑкороÑтта (кадри/Ñек) на анимациÑта"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "(empty)"
-msgstr ""
+msgstr "(празно)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move Frame"
@@ -7640,7 +7689,7 @@ msgstr "СкороÑÑ‚:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Loop"
-msgstr ""
+msgstr "ПовтарÑне"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Animation Frames:"
@@ -7656,11 +7705,11 @@ msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
-msgstr ""
+msgstr "Вмъкване на празен (преди)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (After)"
-msgstr ""
+msgstr "Вмъкване на празен (Ñлед)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move (Before)"
@@ -7668,7 +7717,7 @@ msgstr "ПремеÑтване (преди)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move (After)"
-msgstr ""
+msgstr "ПремеÑтване (Ñлед)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Select Frames"
@@ -7676,11 +7725,11 @@ msgstr "Избиране на кадри"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
-msgstr ""
+msgstr "Хоризонтала:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Vertical:"
-msgstr ""
+msgstr "Вертикала:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Select/Clear All Frames"
@@ -7700,57 +7749,56 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Margin"
-msgstr ""
+msgstr "Задаване на отÑтъп"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
-msgstr ""
+msgstr "Режим на прилепване:"
#: editor/plugins/texture_region_editor_plugin.cpp
#: scene/resources/visual_shader.cpp
msgid "None"
-msgstr ""
+msgstr "ÐÑма"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Pixel Snap"
-msgstr ""
+msgstr "Прилепване към пикÑелите"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Grid Snap"
-msgstr ""
+msgstr "Прилепване към решетката"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Auto Slice"
-msgstr ""
+msgstr "Ðвтоматично отрÑзване"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Offset:"
-msgstr ""
+msgstr "ОтмеÑтване:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Step:"
-msgstr ""
+msgstr "Стъпка:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Sep.:"
-msgstr ""
+msgstr "Разделител:"
#: editor/plugins/texture_region_editor_plugin.cpp
-#, fuzzy
msgid "TextureRegion"
-msgstr "Двуизмерна текÑтура"
+msgstr "ТекÑтурна облаÑÑ‚"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
-msgstr ""
+msgstr "ДобавÑне на вÑички елементи"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All"
-msgstr ""
+msgstr "ДобавÑне на вÑичко"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove All Items"
-msgstr ""
+msgstr "Премахване на вÑички елементи"
#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
msgid "Remove All"
@@ -7762,7 +7810,7 @@ msgstr "Редактиране на темата"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme editing menu."
-msgstr ""
+msgstr "Меню за редактиране на темата."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add Class Items"
@@ -7794,7 +7842,7 @@ msgstr "Заключен бутон"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Item"
-msgstr ""
+msgstr "Елемент"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Disabled Item"
@@ -7802,11 +7850,11 @@ msgstr "Заключен елемент"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Check Item"
-msgstr ""
+msgstr "Елемент за отметка"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Checked Item"
-msgstr ""
+msgstr "Отметнат елемент"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Radio Item"
@@ -7818,27 +7866,27 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Named Sep."
-msgstr ""
+msgstr "Именуван разд."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
-msgstr ""
+msgstr "Подменю"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subitem 1"
-msgstr ""
+msgstr "Поделемент 1"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subitem 2"
-msgstr ""
+msgstr "Поделемент 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
-msgstr ""
+msgstr "Има"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Many"
-msgstr ""
+msgstr "Много"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Disabled LineEdit"
@@ -7846,15 +7894,15 @@ msgstr "Заключено текÑтово поле"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 1"
-msgstr ""
+msgstr "Раздел 1"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 2"
-msgstr ""
+msgstr "Раздел 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Tab 3"
-msgstr ""
+msgstr "Раздел 3"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Editable Item"
@@ -7862,32 +7910,32 @@ msgstr "Редактируем елемент"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
-msgstr ""
+msgstr "Поддърво"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has,Many,Options"
-msgstr ""
+msgstr "Има,Много,Опции"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Data Type:"
-msgstr ""
+msgstr "Тип на данните:"
#: editor/plugins/theme_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Icon"
-msgstr ""
+msgstr "Иконка"
#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Style"
-msgstr ""
+msgstr "Стил"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Font"
-msgstr ""
+msgstr "Шрифт"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Color"
-msgstr ""
+msgstr "Цват"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme File"
@@ -7895,11 +7943,11 @@ msgstr "Файл Ñ Ñ‚ÐµÐ¼Ð°"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase Selection"
-msgstr ""
+msgstr "Изтриване на избраното"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Fix Invalid Tiles"
-msgstr ""
+msgstr "Поправка на неправилните плочки"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
@@ -7995,9 +8043,8 @@ msgid "Add Texture(s) to TileSet."
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected Texture from TileSet."
-msgstr "ПремеÑтване на пътечката нагоре."
+msgstr "Изтриване на избраната текÑтура от Ð¿Ð»Ð¾Ñ‡Ð½Ð¸Ñ Ð½Ð°Ð±Ð¾Ñ€."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
@@ -8012,9 +8059,8 @@ msgid "New Single Tile"
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Autotile"
-msgstr "Ðов TextFile"
+msgstr "Ðова авт. плочка"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "New Atlas"
@@ -8249,9 +8295,8 @@ msgid "Edit Collision Polygon"
msgstr "Редактиране на полигона за колизии"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Occlusion Polygon"
-msgstr "ПриÑтавки"
+msgstr "Редактиране на полигона за прикриване"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Navigation Polygon"
@@ -8282,9 +8327,8 @@ msgid "Remove Collision Polygon"
msgstr "Премахване на полигона за колизии"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Occlusion Polygon"
-msgstr "ПремеÑтване на Полигон"
+msgstr "Премахване на полигона за прикриване"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove Navigation Polygon"
@@ -8331,10 +8375,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8393,10 +8433,6 @@ msgid "Stage All"
msgstr "Запази Ð’Ñичко"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9650,6 +9686,11 @@ msgid "Projects"
msgstr "Проекти"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Зареждане…"
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10010,6 +10051,11 @@ msgstr ""
msgid "Plugins"
msgstr "ПриÑтавки"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "ВнаÑÑне на преводи"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10253,6 +10299,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "ПоÑтавÑне на възлите"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Разкачане на Ñкрипта"
@@ -10373,6 +10428,11 @@ msgid "Attach Script"
msgstr "Закачане на Ñкрипт"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "ИзрÑзване на възлите"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -10438,9 +10498,8 @@ msgid "Reparent to New Node"
msgstr "ПремеÑтване под нов възел"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make Scene Root"
-msgstr "Запазване на Ñцената"
+msgstr "Превръщане на Ñцената в коренна"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
@@ -10459,9 +10518,8 @@ msgid "Delete (No Confirm)"
msgstr "Изтриване (без потвърждение)"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "Създай нови възли."
+msgstr "ДобавÑне/Ñъздаване на нов възел."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -10478,9 +10536,8 @@ msgid "Detach the script from the selected node."
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Remote"
-msgstr "ЗатварÑне на вÑичко"
+msgstr "Отдалечен"
#: editor/scene_tree_dock.cpp
msgid "Local"
@@ -10495,14 +10552,12 @@ msgid "Toggle Visible"
msgstr ""
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Unlock Node"
-msgstr "Избиране на вÑичко"
+msgstr "Отключване на възела"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Button Group"
-msgstr "Копче 7"
+msgstr "Група бутони"
#: editor/scene_tree_editor.cpp
msgid "(Connecting From)"
@@ -10586,38 +10641,35 @@ msgstr ""
#: editor/script_create_dialog.cpp
msgid "Path is not local."
-msgstr ""
+msgstr "ПътÑÑ‚ не е локален."
#: editor/script_create_dialog.cpp
msgid "Invalid base path."
msgstr "Ðеправилен базов път."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "Вече ÑъщеÑтвува файл или папка Ñ Ñ‚Ð¾Ð²Ð° име."
+msgstr "Вече ÑъщеÑтвува папка Ñ Ñ‚Ð¾Ð²Ð° име."
#: editor/script_create_dialog.cpp
msgid "File does not exist."
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid extension."
-msgstr "ТрÑбва да Ñе използва правилно разширение."
+msgstr "Ðеправилно разширение."
#: editor/script_create_dialog.cpp
msgid "Wrong extension chosen."
-msgstr ""
+msgstr "Избрано е грешно разширение."
#: editor/script_create_dialog.cpp
msgid "Error loading template '%s'"
msgstr "Грешка при зареждане на шаблона „%s“"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Error - Could not create script in filesystem."
-msgstr "ÐеуÑпешно Ñъздаване на папка."
+msgstr "Грешка: Ñкриптът не може да бъде Ñъздаден във файловата ÑиÑтема."
#: editor/script_create_dialog.cpp
msgid "Error loading script from %s"
@@ -10636,9 +10688,8 @@ msgid "Open Script / Choose Location"
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script"
-msgstr "Ðова Ñцена"
+msgstr "ОтварÑне на Ñкрипта"
#: editor/script_create_dialog.cpp
msgid "File exists, it will be reused."
@@ -10649,9 +10700,8 @@ msgid "Invalid path."
msgstr "Ðеправилен път."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid class name."
-msgstr "невалидно име на Група."
+msgstr "Ðеправилно име на клаÑ."
#: editor/script_create_dialog.cpp
msgid "Invalid inherited parent name or path."
@@ -10678,9 +10728,8 @@ msgid "Will load an existing script file."
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script file already exists."
-msgstr "Група Ñ Ñ‚Ð¾Ð²Ð° име вече ÑъщеÑтвува."
+msgstr "СкриптовиÑÑ‚ файл вече ÑъщеÑтвува."
#: editor/script_create_dialog.cpp
msgid ""
@@ -10689,9 +10738,8 @@ msgid ""
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Class Name:"
-msgstr "КлаÑ:"
+msgstr "Име на клаÑа:"
#: editor/script_create_dialog.cpp
msgid "Template:"
@@ -10702,9 +10750,8 @@ msgid "Built-in Script:"
msgstr "Вграден Ñкрипт:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Attach Node Script"
-msgstr "Ðова Ñцена"
+msgstr "Закачане на Ñкрипт"
#: editor/script_editor_debugger.cpp
msgid "Remote "
@@ -10783,9 +10830,8 @@ msgid "Profiler"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Network Profiler"
-msgstr "ИзнаÑÑне на проекта"
+msgstr "Профилиране на мрежата"
#: editor/script_editor_debugger.cpp
msgid "Monitor"
@@ -10812,9 +10858,8 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Export list to a CSV file"
-msgstr "ИзнаÑÑне на профила"
+msgstr "ИзнаÑÑне на ÑпиÑъка като файл CSV"
#: editor/script_editor_debugger.cpp
msgid "Resource Path"
@@ -10985,9 +11030,8 @@ msgid "Add an architecture entry"
msgstr ""
#: modules/gdnative/gdnative_library_editor_plugin.cpp
-#, fuzzy
msgid "GDNativeLibrary"
-msgstr "ИзнаÑÑне на библиотеката"
+msgstr "Библиотека GDNative"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Enabled GDNative Singleton"
@@ -11019,66 +11063,59 @@ msgid "Not a script with an instance"
msgstr "Скриптът нÑма инÑтанциÑ"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Not based on a script"
-msgstr "Обектът не е базиран на Ñкрипт"
+msgstr "Ðе Ñе базира на Ñкрипт"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Not based on a resource file"
-msgstr "Обектът не е базиран на реÑурÑен файл"
+msgstr "Ðе Ñе базира на реÑурÑен файл"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Invalid instance dictionary format (missing @path)"
-msgstr "Ðевалиден формат на инÑтанциÑта в речника (липÑва @path)"
+msgstr "Ðеправилен формат в речника на инÑтанциите (липÑва @path)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (can't load script at @path)"
msgstr ""
-"Ðеправилен формат на инÑтанциÑта в речника (Ñкриптът в @path не може да бъде "
+"Ðеправилен формат в речника на инÑтанциите (Ñкриптът в @path не може да бъде "
"зареден)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (invalid script at @path)"
msgstr ""
-"Ðеправилен формат на инÑтанциÑта в речника (Ñкриптът в @path е невалиден)"
+"Ðеправилен формат в речника на инÑтанциите (Ñкриптът в @path е невалиден)"
#: modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Invalid instance dictionary (invalid subclasses)"
-msgstr "Ðевалиден формат на инÑтанциÑта в речника (невалиден подклаÑ)"
+msgstr "Ðеправилен формат в речника на инÑтанциите (невалиден подклаÑ)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Object can't provide a length."
msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Next Plane"
-msgstr "Следващ подпрозорец"
+msgstr "Следваща равнина"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Previous Plane"
-msgstr "Предишен подпрозорец"
+msgstr "Предходна равнина"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Plane:"
-msgstr ""
+msgstr "Равнина:"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Next Floor"
-msgstr ""
+msgstr "Следващ под"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Previous Floor"
-msgstr "Предишен подпрозорец"
+msgstr "Предходен под"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Floor:"
-msgstr ""
+msgstr "Под:"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Delete Selection"
@@ -11161,37 +11198,63 @@ msgid "Cursor Clear Rotation"
msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Paste Selects"
-msgstr "ÐаÑтройки"
+msgstr "ПоÑтавÑне на избраното"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Clear Selection"
-msgstr "Ðова Ñцена"
+msgstr "ИзчиÑтване на избраното"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Fill Selection"
-msgstr "Ðова Ñцена"
+msgstr "Запълване на избраното"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Settings"
-msgstr "ÐаÑтройки"
+msgstr "ÐаÑтройки на GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Pick Distance:"
msgstr ""
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Filter meshes"
-msgstr "ПоÑтавÑне на възелите"
+msgstr "Филтриране на полигонните мрежи"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+"Задайте реÑÑƒÑ€Ñ Ð¾Ñ‚ тип MeshLibrary в този GridMap, за да можете да използвате "
+"полигонните му мрежи."
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Директно оÑветÑване"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Задаване на израз"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
@@ -11203,11 +11266,11 @@ msgstr ""
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Bake NavMesh"
-msgstr ""
+msgstr "Изпичане на NavMesh"
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Clear the navigation mesh."
-msgstr ""
+msgstr "ИзчиÑтване на навигационната полигонна мрежа."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Setting up Configuration..."
@@ -11243,15 +11306,15 @@ msgstr ""
#: modules/recast/navigation_mesh_generator.cpp
msgid "Creating polymesh..."
-msgstr ""
+msgstr "Създаване на полигонна мрежа…"
#: modules/recast/navigation_mesh_generator.cpp
msgid "Converting to native navigation mesh..."
-msgstr ""
+msgstr "Преобразуване на навигационната полигонна мрежа в ÑобÑÑ‚Ð²ÐµÐ½Ð¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚â€¦"
#: modules/recast/navigation_mesh_generator.cpp
msgid "Navigation Mesh Generator Setup:"
-msgstr ""
+msgstr "ÐаÑтройка на генератора на навигационни полигонни мрежи:"
#: modules/recast/navigation_mesh_generator.cpp
msgid "Parsing Geometry..."
@@ -11324,86 +11387,80 @@ msgid "Override an existing built-in function."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new function."
-msgstr "Създай нови възли."
+msgstr "Създаване на нова функциÑ."
#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
-msgstr ""
+msgstr "Променливи:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new variable."
-msgstr "Създай нови възли."
+msgstr "Създаване на нова променлива."
#: modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
-msgstr ""
+msgstr "Сигнали:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new signal."
-msgstr "Създай нов полигон от нулата."
+msgstr "Създаване на нов Ñигнал."
#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
-msgstr ""
+msgstr "Името не е правилен идентификатор:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Name already in use by another func/var/signal:"
-msgstr ""
+msgstr "Името вече е заето от друга функциÑ/променлива/Ñигнал:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Function"
-msgstr ""
+msgstr "Преименуване на функциÑта"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Variable"
-msgstr ""
+msgstr "Преименуване на променливата"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Signal"
-msgstr ""
+msgstr "Преименуване на Ñигнала"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Function"
-msgstr ""
+msgstr "ДобавÑне на функциÑ"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Delete input port"
-msgstr "ЗатварÑне на вÑичко"
+msgstr "Изтриване на входÑÑ‰Ð¸Ñ Ð¿Ð¾Ñ€Ñ‚"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Variable"
-msgstr ""
+msgstr "ДобавÑне на променлива"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Signal"
-msgstr ""
+msgstr "ДобавÑне на Ñигнал"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Input Port"
-msgstr "ЗатварÑне на вÑичко"
+msgstr "Премахване на входÑÑ‰Ð¸Ñ Ð¿Ð¾Ñ€Ñ‚"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Output Port"
-msgstr "ВнаÑÑне на текÑтури"
+msgstr "Премахване на изходÑÑ‰Ð¸Ñ Ð¿Ð¾Ñ€Ñ‚"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Expression"
-msgstr ""
+msgstr "ПромÑна на израза"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Nodes"
-msgstr ""
+msgstr "Премахване на възлите Ñ VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Duplicate VisualScript Nodes"
-msgstr ""
+msgstr "Дублиране на възлите Ñ VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
@@ -11456,23 +11513,20 @@ msgid "Change Base Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Move Node(s)"
-msgstr "ПоÑтавÑне на възелите"
+msgstr "ПремеÑтване на възела(възлите)"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Node"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Connect Nodes"
-msgstr "ИзрÑзване на възелите"
+msgstr "Свързване на възлите"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Disconnect Nodes"
-msgstr "ИзрÑзване на възелите"
+msgstr "Разкачане на възлите"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -11493,9 +11547,8 @@ msgid "Change Input Value"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Resize Comment"
-msgstr "Вкарай Коментар"
+msgstr "ПреоразмерÑване на коментара"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't copy the function node."
@@ -11506,9 +11559,8 @@ msgid "Clipboard is empty!"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Paste VisualScript Nodes"
-msgstr "ПоÑтавÑне на възелите"
+msgstr "ПоÑтавÑне на възлите Ñ VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't create function with a function node."
@@ -11527,9 +11579,8 @@ msgid "Try to only have one sequence input in selection."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create Function"
-msgstr "Създай Очертание"
+msgstr "Създаване на функциÑ"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Function"
@@ -11564,9 +11615,8 @@ msgid "Change Base Type:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Nodes..."
-msgstr "Добави Възел..."
+msgstr "ДобавÑне на възли…"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Function..."
@@ -11597,9 +11647,8 @@ msgid "Cut Nodes"
msgstr "ИзрÑзване на възлите"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Function"
-msgstr "Отиди на Ред"
+msgstr "Преобразуване във функциÑ"
#: modules/visual_script/visual_script_editor.cpp
msgid "Refresh Graph"
@@ -11664,9 +11713,8 @@ msgid ""
msgstr ""
#: modules/visual_script/visual_script_property_selector.cpp
-#, fuzzy
msgid "Search VisualScript"
-msgstr "ПоÑтавÑне на възелите"
+msgstr "ТърÑене във VisualScript"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Get %s"
@@ -11705,11 +11753,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11721,11 +11771,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11733,9 +11783,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11875,9 +11935,8 @@ msgid "Could not read boot splash image file:"
msgstr "Ðе може да Ñе прочете файл Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ при Ñтартиране:"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Using default boot splash image."
-msgstr "ÐеуÑпешно Ñъздаване на папка."
+msgstr "Използва Ñе Ñтандартното изображение при Ñтартиране."
#: platform/uwp/export/export.cpp
msgid "Invalid package short name."
@@ -11893,16 +11952,15 @@ msgstr "Ðеправилно име за показване на издателÑ
#: platform/uwp/export/export.cpp
msgid "Invalid product GUID."
-msgstr "Ðевалиден продуктов GUID."
+msgstr "Ðеправилен продуктов GUID."
#: platform/uwp/export/export.cpp
msgid "Invalid publisher GUID."
-msgstr ""
+msgstr "Ðеправилен GUID на издател."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid background color."
-msgstr "невалидно име на Група."
+msgstr "Ðеправилен фонов цвÑÑ‚."
#: platform/uwp/export/export.cpp
msgid "Invalid Store Logo image dimensions (should be 50x50)."
@@ -11933,22 +11991,21 @@ msgid "Invalid splash screen image dimensions (should be 620x300)."
msgstr ""
#: scene/2d/animated_sprite.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite to display frames."
msgstr ""
-"За да може AnimatedSprite да показва кадри, първо трÑбва да му Ñе даде "
-"SpriteFrames реÑÑƒÑ€Ñ Ð² парамертъра 'Frames'."
+"За да може AnimatedSprite да показва кадри, първо трÑбва Ñе Ñъздаде или "
+"зададе реÑÑƒÑ€Ñ Ð¾Ñ‚ тип SpriteFrames в ÑвойÑтвото „Frames“."
#: scene/2d/canvas_modulate.cpp
-#, fuzzy
msgid ""
"Only one visible CanvasModulate is allowed per scene (or set of instanced "
"scenes). The first created one will work, while the rest will be ignored."
msgstr ""
-"Може да има Ñамо един видим CanvasModulate на Ñцене (или нÑколко "
-"инÑтанцирани Ñцени). Само първиÑÑ‚ ще работи, а вÑички оÑтанали - игнорирани."
+"Може да има Ñамо един видим CanvasModulate на Ñцена (или нÑколко "
+"инÑтанцирани Ñцени). Само първиÑÑ‚ ще работи, а вÑички оÑтанали ще бъдат "
+"пренебрегнати."
#: scene/2d/collision_object_2d.cpp
msgid ""
@@ -11972,6 +12029,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Празен CollisionPolygon2D не влиÑе на колизиите."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12024,13 +12089,12 @@ msgid "Node A and Node B must be different PhysicsBody2Ds"
msgstr ""
#: scene/2d/light_2d.cpp
-#, fuzzy
msgid ""
"A texture with the shape of the light must be supplied to the \"Texture\" "
"property."
msgstr ""
-"ТеÑктура Ñ Ð½ÑƒÐ¶Ð½Ð°Ñ‚Ð° форма на Ñветлината трÑбва да бъде дадена в параметъра "
-"'texture'."
+"Ð’ ÑвойÑтвото „Texture“ трÑбва да бъде зададена текÑтура Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° на "
+"Ñветлината."
#: scene/2d/light_occluder_2d.cpp
msgid ""
@@ -12040,9 +12104,10 @@ msgstr ""
"работи прикриването."
#: scene/2d/light_occluder_2d.cpp
-#, fuzzy
msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
-msgstr "ЗатъмнÑващиÑÑ‚ многоъгълник е празен. МолÑ, нариÑувайте един."
+msgstr ""
+"ПрикриващиÑÑ‚ полигон за този прикриващ обект е празен. МолÑ, нариÑувайте "
+"полигон."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -12114,15 +12179,15 @@ msgid ""
msgstr ""
#: scene/2d/tile_map.cpp
-#, fuzzy
msgid ""
"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes "
"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
"KinematicBody2D, etc. to give them a shape."
msgstr ""
-"CollisionShape2D Ñлужи Ñамо за да даде форма за колизии на "
-"CollisionObject2D. МолÑ, използвайте го Ñамо като наÑледник на Area2D, "
-"StaticBody2D, RigidBody2D, KinematicBody2D, и т.н. за да им дадете форма."
+"Възел от типа TileMap Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¾ ÑвойÑтво „Use Parent“ трÑбва да има "
+"родителÑки елемент от тип CollisionShape2D, на който да придаде форма. МолÑ, "
+"използвайте го Ñамо като дъщерен елемент на Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D и т.н., за да им придадете форма."
#: scene/2d/visibility_notifier_2d.cpp
msgid ""
@@ -12159,28 +12224,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr ""
+msgid "Finding meshes and lights"
+msgstr "ТърÑене на полигонни мрежи и Ñветлини"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr ""
+msgid "Done"
+msgstr "Готово"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12208,13 +12273,12 @@ msgid ""
msgstr ""
#: scene/3d/collision_shape.cpp
-#, fuzzy
msgid ""
"A shape must be provided for CollisionShape to function. Please create a "
"shape resource for it."
msgstr ""
"За да работи CollisionShape2D, е нужно да му Ñе даде форма. МолÑ, Ñъздайте "
-"му Shape2D реÑурÑ."
+"му реÑурÑ-форма."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -12229,7 +12293,7 @@ msgstr ""
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
-msgstr ""
+msgstr "Ðе Ñе вижда нищо, той като нÑма зададена полигонна мрежа."
#: scene/3d/cpu_particles.cpp
msgid ""
@@ -12239,6 +12303,10 @@ msgstr ""
#: scene/3d/gi_probe.cpp
msgid "Plotting Meshes"
+msgstr "ПоÑтроÑване на полигонните мрежи"
+
+#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
msgstr ""
#: scene/3d/gi_probe.cpp
@@ -12247,11 +12315,6 @@ msgid ""
"Use a BakedLightmap instead."
msgstr ""
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12259,12 +12322,16 @@ msgstr ""
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
msgstr ""
+"ТрÑбва да Ñе зададе или Ñъздаде реÑÑƒÑ€Ñ Ð¾Ñ‚ тип NavigationMesh, за може да "
+"работи този възел."
#: scene/3d/navigation_mesh.cpp
msgid ""
"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
"It only provides navigation data."
msgstr ""
+"NavigationMeshInstance трÑбва да бъде дъщерен или под-дъщерен на възел от "
+"тип Navigation. Той Ñамо предоÑÑ‚Ð°Ð²Ñ Ð´Ð°Ð½Ð½Ð¸Ñ‚Ðµ за навигирането."
#: scene/3d/particles.cpp
msgid ""
@@ -12277,6 +12344,8 @@ msgstr ""
msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
+"Ðе Ñе вижда нищо, тъй като полигонните мрежи не Ñа били Ñвързани към Ñтъпки "
+"на изчертаване."
#: scene/3d/particles.cpp
msgid ""
@@ -12285,9 +12354,8 @@ msgid ""
msgstr ""
#: scene/3d/path.cpp
-#, fuzzy
msgid "PathFollow only works when set as a child of a Path node."
-msgstr "PathFollow2D работи Ñамо когато е наÑледник на Path2D."
+msgstr "PathFollow работи Ñамо когато е дъщерен елемент на възел от тип Path."
#: scene/3d/path.cpp
msgid ""
@@ -12323,17 +12391,16 @@ msgid "Node A and Node B must be different PhysicsBodies"
msgstr ""
#: scene/3d/remote_transform.cpp
-#, fuzzy
msgid ""
"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
"derived node to work."
msgstr ""
-"Параметърът 'Path' трÑбва да Ñочи към дейÑтвителен възел Particles2D, за да "
-"работи."
+"СвойÑтвото „Remote Path“ трÑбва да Ñочи към дейÑтвителен възел от тип "
+"Spatial или негов наÑледник, за да работи."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
-msgstr ""
+msgstr "Това Ñ‚Ñло ще бъде игнорирано, докато не зададете полигонна мрежа."
#: scene/3d/soft_body.cpp
msgid ""
@@ -12343,13 +12410,12 @@ msgid ""
msgstr ""
#: scene/3d/sprite_3d.cpp
-#, fuzzy
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite3D to display frames."
msgstr ""
-"За да може AnimatedSprite да показва кадри, първо трÑбва да му Ñе даде "
-"SpriteFrames реÑÑƒÑ€Ñ Ð² парамертъра 'Frames'."
+"За да може AnimatedSprite3D да показва кадри, първо трÑбва Ñе Ñъздаде или "
+"зададе реÑÑƒÑ€Ñ Ð¾Ñ‚ тип SpriteFrames в ÑвойÑтвото „Frames“."
#: scene/3d/vehicle_body.cpp
msgid ""
@@ -12462,6 +12528,14 @@ msgstr "Тревога!"
msgid "Please Confirm..."
msgstr "МолÑ, потвърдете..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "ТрÑбва да Ñе използва правилно разширение."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12503,6 +12577,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
@@ -12530,6 +12610,15 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "КонÑтантите не могат да бъдат променени."
+#~ msgid "No"
+#~ msgstr "Ðе"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Тази Ñцена не е била запазвана преди. Запазване преди изпълнението?"
+
+#~ msgid "Search complete"
+#~ msgstr "ТърÑенето е завършено"
+
#~ msgid "UV->Polygon"
#~ msgstr "UV -> Полигон"
@@ -12817,9 +12906,6 @@ msgstr "КонÑтантите не могат да бъдат промененÐ
#~ msgid "Import Large Texture"
#~ msgstr "ВнаÑÑне на голÑма текÑтура"
-#~ msgid "Import Translations"
-#~ msgstr "ВнаÑÑне на преводи"
-
#~ msgid "Couldn't import!"
#~ msgstr "ÐеуÑпешно внаÑÑне!"
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 4526860a7a..ca8fff0724 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -1,6 +1,6 @@
# Bengali translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Abu Md. Maruf Sarker <maruf.webdev@gmail.com>, 2016-2017.
# Abdullah Zubair <abdullahzubair109@gmail.com>, 2017.
@@ -8,13 +8,14 @@
# Tawhid H. <Tawhidk757@yahoo.com>, 2019.
# Hasibul Hasan <hasibeng78@gmail.com>, 2019.
# Oymate <dhruboadittya96@gmail.com>, 2020.
-# Mokarrom Hossain <mhb2016.bzs@gmail.com>, 2020.
+# Mokarrom Hossain <mhb2016.bzs@gmail.com>, 2020, 2021.
# Sagen Soren <sagensoren03@gmail.com>, 2020.
+# Hasibul Hasan <d1hasib@yahoo.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-26 08:43+0000\n"
+"PO-Revision-Date: 2021-02-15 10:51+0000\n"
"Last-Translator: Mokarrom Hossain <mhb2016.bzs@gmail.com>\n"
"Language-Team: Bengali <https://hosted.weblate.org/projects/godot-engine/"
"godot/bn/>\n"
@@ -23,13 +24,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
-#, fuzzy
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "অবৈধ পà§à¦°à¦•ার রূপানà§à¦¤à¦° করার যà§à¦•à§à¦¤à¦¿(),use TYPE_* constants."
+msgstr "অবৈধ পà§à¦°à¦•ার রূপানà§à¦¤à¦° করার যà§à¦•à§à¦¤à¦¿ , TYPE_* constants বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -265,10 +265,9 @@ msgstr "ইনà§à¦Ÿà¦¾à¦°à¦ªà§‹à¦²à§‡à¦¶à¦¨ মোড"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
-msgstr ""
+msgstr "লà§à¦ª Wrap মোড (লà§à¦ª দিয়ে শà§à¦°à§ দিয়ে ইনà§à¦Ÿà¦¾à¦°à¦ªà§‹à¦²à§‡à¦Ÿ শেষ)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Remove this track."
msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ টà§à¦°à§à¦¯à¦¾à¦•/পথ অপসারণ করà§à¦¨à¥¤"
@@ -277,9 +276,8 @@ msgid "Time (s): "
msgstr "সময় (সেঃ): "
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Toggle Track Enabled"
-msgstr "সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨"
+msgstr "টà§à¦°à§à¦¯à¦¾à¦• সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨"
#: editor/animation_track_editor.cpp
msgid "Continuous"
@@ -397,7 +395,7 @@ msgstr "টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ পà§à¦¨à¦°à§à¦¬à¦¿à¦¨à§à¦¯à¦¸à§à¦
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr ""
+msgstr "রূপানà§à¦¤à¦° টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ কেবল Spatial-based নোডগà§à¦²à¦¿à¦¤à§‡ পà§à¦°à¦¯à§‹à¦œà§à¦¯à¥¤"
#: editor/animation_track_editor.cpp
msgid ""
@@ -406,10 +404,15 @@ msgid ""
"-AudioStreamPlayer2D\n"
"-AudioStreamPlayer3D"
msgstr ""
+"রূপানà§à¦¤à¦° টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ কেবল সà§à¦¥à¦¾à¦¨à¦¿à¦• ভিতà§à¦¤à¦¿à¦• নোডগà§à¦²à¦¿à¦¤à§‡ পà§à¦°à¦¯à§‹à¦œà§à¦¯à¥¤ অডিও টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ কেবল "
+"পà§à¦°à¦•ারের নোডগà§à¦²à¦¿à¦¤à§‡ নিরà§à¦¦à§‡à¦¶ করতে পারে:\n"
+"-অডিও সà§à¦Ÿà§à¦°à¦¿à¦®à¦ªà§à¦²à§‡à¦¯à¦¼à¦¾à¦°\n"
+"-অডিও সà§à¦Ÿà§à¦°à¦¿à¦®à¦ªà§à¦²à§‡à¦¯à¦¼à¦¾à¦° 2 ডি\n"
+"-অডিওসà§à¦Ÿà§à¦°à¦¿à¦ªà¦ªà§à¦²à§‡à¦¯à¦¼à¦¾à¦° 3 ডি"
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr ""
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ কেবল অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦ªà§à¦²à§‡à¦¯à¦¼à¦¾à¦° নোডগà§à¦²à¦¿à¦¤à§‡ নিরà§à¦¦à§‡à¦¶ করতে পারে।"
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
@@ -417,48 +420,43 @@ msgstr "à¦à¦•টি অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ পà§à¦²à§‡à¦¯à¦¼à¦¾à¦° ন
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr ""
+msgstr "মূল ছাড়া নতà§à¦¨ টà§à¦°à§à¦¯à¦¾à¦• যà§à¦•à§à¦¤ করা সমà§à¦­à¦¬ নয়"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr ""
+msgstr "বেজিয়ারের জনà§à¦¯ অবৈধ টà§à¦°à§à¦¯à¦¾à¦• (উপযà§à¦•à§à¦¤ উপ-বৈশিষà§à¦Ÿà§à¦¯ নেই)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Bezier Track"
-msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à§à¦¯à¦¾à¦• যোগ করà§à¦¨"
+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 ""
+msgstr "টà§à¦°à§à¦¯à¦¾à¦• Spatial টাইপের নয়, কী সনà§à¦¨à¦¿à¦¬à§‡à¦¶ করতে পারে না"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Transform Track Key"
-msgstr "রà§à¦ªà¦¾à¦¨à§à¦¤à¦°à§‡à¦° ধরণ"
+msgstr "টà§à¦°à¦¾à¦¨à§à¦¸à¦«à¦°à§à¦® টà§à¦°à§à¦¯à¦¾à¦• কী যà§à¦•à§à¦¤ করà§à¦¨"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track Key"
-msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à§à¦¯à¦¾à¦• যোগ করà§à¦¨"
+msgstr "টà§à¦°à§à¦¯à¦¾à¦• কী যà§à¦•à§à¦¤ করà§à¦¨"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
-msgstr ""
+msgstr "টà§à¦°à§à¦¯à¦¾à¦• পাথটি অবৈধ, সà§à¦¤à¦°à¦¾à¦‚ কোনও পদà§à¦§à¦¤à¦¿ key যà§à¦•à§à¦¤ করতে পারে না।"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Method Track Key"
-msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡ (Anim) টà§à¦°à§à¦¯à¦¾à¦•/পথ à¦à¦¬à¦‚ চাবি যোগ করà§à¦¨"
+msgstr "Method Track Key যà§à¦•à§à¦¤ করà§à¦¨"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Method not found in object: "
-msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡ চলক-পà§à¦°à¦¾à¦ªà¦• (VariableGet) পাওয়া যায়নি: "
+msgstr "Object ঠMethod পাওয়া যায় নি: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
@@ -469,7 +467,6 @@ msgid "Clipboard is empty"
msgstr "কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Paste Tracks"
msgstr "মানসমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨"
@@ -481,6 +478,7 @@ msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° (Anim) চাবিসমূহেà
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
msgstr ""
+"à¦à¦‡ বিকলà§à¦ªà¦Ÿà¦¿ বেজিয়ার সমà§à¦ªà¦¾à¦¦à¦¨à¦¾à¦° জনà§à¦¯ কাজ করে না, কারণ à¦à¦Ÿà¦¿ কেবলমাতà§à¦° Single টà§à¦°à§à¦¯à¦¾à¦•।"
#: editor/animation_track_editor.cpp
msgid ""
@@ -494,34 +492,39 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"à¦à¦‡ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦Ÿà¦¿ আমদানি করা দৃশà§à¦¯à§‡à¦° সাথে সমà§à¦ªà¦°à§à¦•িত, তাই আমদানি করা টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿à¦¤à§‡ "
+"পরিবরà§à¦¤à¦¨à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করা হবে না।\n"
+"\n"
+"কাসà§à¦Ÿà¦® টà§à¦°à§à¦¯à¦¾à¦• যà§à¦•à§à¦¤ করার কà§à¦·à¦®à¦¤à¦¾ সকà§à¦·à¦® করতে, দৃশà§à¦¯à§‡à¦° আমদানি সেটিংসে নেভিগেট করà§à¦¨ à¦à¦¬à¦‚ "
+"সেট করà§à¦¨\n"
+"\"ফাইলগà§à¦²à¦¿\" ঠ\"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨> সঞà§à¦šà¦¯à¦¼à¦¸à§à¦¥à¦¾à¦¨\", \"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨> কাসà§à¦Ÿà¦® টà§à¦°à§à¦¯à¦¾à¦• রাখà§à¦¨\" সকà§à¦·à¦® "
+"করà§à¦¨, তারপরে পà§à¦¨à¦°à¦¾à¦¯à¦¼ আমদানি করà§à¦¨à¥¤\n"
+"বিকলà§à¦ªà¦­à¦¾à¦¬à§‡, à¦à¦•টি আমদানি পà§à¦°à¦¿à¦¸à§‡à¦Ÿ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨ যা পৃথক ফাইলগà§à¦²à¦¿à¦¤à§‡ অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦—à§à¦²à¦¿ "
+"আমদানি করে।"
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
-msgstr ""
+msgstr "সতরà§à¦•তা: Imported অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করা হচà§à¦›à§‡"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select an AnimationPlayer node to create and edit animations."
-msgstr ""
-"অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦¸à¦®à§‚হ সমà§à¦ªà¦¾à¦¦à¦¨ করতে দৃশà§à¦¯à§‡à¦° তালিকা থেকে à¦à¦•টি AnimationPlayer নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨à¥¤"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ তৈরি à¦à¦¬à¦‚ সমà§à¦ªà¦¾à¦¦à¦¨à¦¾ করতে à¦à¦•টি অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à¦ªà§à¦²à§‡à¦¯à¦¼à¦¾à¦° নোড নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨à¥¤"
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
-msgstr ""
+msgstr "Tree মধà§à¦¯à§‡ নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ নোডগà§à¦²à¦¿ থেকে কেবল টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ দেখান।"
#: editor/animation_track_editor.cpp
msgid "Group tracks by node or display them as plain list."
-msgstr ""
+msgstr "নোড দà§à¦¬à¦¾à¦°à¦¾ গà§à¦°à§à¦ª টà§à¦°à§à¦¯à¦¾à¦• করà§à¦¨ বা তাদের সরল তালিকা হিসাবে পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করà§à¦¨à¥¤"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Snap:"
-msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª"
+msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª :"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation step value."
-msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° তালিকাটি কারà§à¦¯à¦•র।"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ পদকà§à¦·à§‡à¦ªà§‡à¦° মান।"
#: editor/animation_track_editor.cpp
msgid "Seconds"
@@ -544,12 +547,11 @@ msgstr "সমà§à¦ªà¦¾à¦¦à¦¨ করà§à¦¨ (Edit)"
#: editor/animation_track_editor.cpp
msgid "Animation properties."
-msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ বৈশিষà§à¦Ÿà§à¦¯"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ বৈশিষà§à¦Ÿà§à¦¯à¥¤"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Copy Tracks"
-msgstr "মানসমূহ পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿/কপি করà§à¦¨"
+msgstr "টà§à¦°à§à¦¯à¦¾à¦•গà§à¦²à¦¿ অনà§à¦²à¦¿à¦ªà¦¿ করà§à¦¨"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
@@ -568,9 +570,8 @@ msgid "Duplicate Transposed"
msgstr "পকà§à¦·à¦¾à¦¨à§à¦¤à¦°à¦¿à¦¤ (Transposed) সমূহ অনà§à¦²à¦¿à¦ªà¦¿ করà§à¦¨"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Selection"
-msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨"
+msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ Delete করà§à¦¨"
#: editor/animation_track_editor.cpp
msgid "Go to Next Step"
@@ -594,7 +595,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
-msgstr ""
+msgstr "বেজিয়ার কারà§à¦­ বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
@@ -641,16 +642,15 @@ msgid "Scale Ratio:"
msgstr "সà§à¦•েল/মাপের অনà§à¦ªà¦¾à¦¤:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select Tracks to Copy"
-msgstr "গà§à¦£à¦¾à¦—à§à¦£/বৈশিষà§à¦Ÿà§à¦¯ বাছাই করà§à¦¨"
+msgstr "গà§à¦£à¦¾à¦—à§à¦£/বৈশিষà§à¦Ÿà§à¦¯ copy করà§à¦¨"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "পà§à¦°à¦¤à¦¿à¦²à¦¿à¦ªà¦¿/কপি করà§à¦¨"
@@ -1486,14 +1486,12 @@ msgstr ""
"পারবে না।"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing built-in type name."
msgstr ""
"অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম। নামটি অবশà§à¦¯à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨ পূরà§à¦¬à¦¨à¦¿à¦°à§à¦®à¦¿à¦¤ ধরণের নামের সাথে পরমà§à¦ªà¦°à¦¬à¦¿à¦°à§‡à¦¾à¦§à§€ "
"হতে পারবে না।"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing global constant name."
msgstr ""
"অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম। নামটি অবশà§à¦¯à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨ সারà§à¦¬à¦œà¦¨à§€à¦¨ ধà§à¦°à§à¦¬à¦•ের নামের সাথে পরমà§à¦ªà¦°à¦¬à¦¿à¦°à§‡à¦¾à¦§à§€ "
@@ -1773,14 +1771,12 @@ msgid "Enabled Properties:"
msgstr "পà§à¦°à§‹à¦ªà¦¾à¦°à§à¦Ÿà¦¿-সমূহ:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Features:"
-msgstr "গঠনবিনà§à¦¯à¦¾à¦¸"
+msgstr "গঠনবিনà§à¦¯à¦¾à¦¸ :"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Classes:"
-msgstr "কà§à¦²à¦¾à¦¸à§‡à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
+msgstr "Enabled কà§à¦²à¦¾à¦¸:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
@@ -1930,8 +1926,8 @@ msgid "Open a File or Directory"
msgstr "ফাইল বা পথ/ডিরেকà§à¦Ÿà¦°à¦¿ খà§à¦²à§à¦¨"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "সংরকà§à¦·à¦¨ করà§à¦¨"
@@ -2030,10 +2026,6 @@ msgstr "পà§à¦°à¦¿à¦­à¦¿à¦‰:"
msgid "File:"
msgstr "ফাইল:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "à¦à¦•টি কারà§à¦¯à¦•র à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা আবশà§à¦¯à¦•।"
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "উৎসসমূহ সà§à¦•à§à¦¯à¦¾à¦¨ করà§à¦¨"
@@ -2497,6 +2489,10 @@ msgid "There is no defined scene to run."
msgstr "চালানোর জনà§à¦¯ কোনো দৃশà§à¦¯ নিরà§à¦¦à¦¿à¦·à§à¦Ÿ করা নেই।"
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "উপ-পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾à¦•ে শà§à¦°à§ করা সমà§à¦­à¦¬ হয়নি!"
@@ -2544,19 +2540,6 @@ msgstr "বৃহৎ গঠনবিনà§à¦¯à¦¾à¦¸à§‡à¦° জনà§à¦¯ শà§à¦§
msgid "Save Scene As..."
msgstr "দৃশà§à¦¯ à¦à¦‡à¦°à§‚পে সংরকà§à¦·à¦£ করà§à¦¨..."
-#: editor/editor_node.cpp
-#, fuzzy
-msgid "No"
-msgstr "নোড"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "হà§à¦¯à¦¾à¦"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "à¦à¦‡ দৃশà§à¦¯à¦Ÿà¦¿ কখনোই সংরকà§à¦·à¦£ করা হয় নি। চালানোর পূরà§à¦¬à§‡ সংরকà§à¦·à¦£ করবেন?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "দৃশà§à¦¯ ছাড়া à¦à¦Ÿà¦¿ করা সমà§à¦­à¦¬ হবে না।"
@@ -2607,6 +2590,10 @@ msgid "Quit"
msgstr "পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করà§à¦¨"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "হà§à¦¯à¦¾à¦"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "à¦à¦¡à¦¿à¦Ÿà¦° হতে পà§à¦°à¦¸à§à¦¥à¦¾à¦¨ করবেন?"
@@ -2654,7 +2641,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "অà§à¦¯à¦¾à¦¡-অন পà§à¦²à¦¾à¦—ইন à¦à¦¨à¦¾à¦¬à¦² করা সমà§à¦­à¦¬ হয় নি। কনফিগার পারà§à¦¸à¦¿à¦‚ ('%s') বà§à¦¯à¦°à§à¦¥ হয়েছে।"
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"'res://addons/%s' লোকেশনে অà§à¦¯à¦¾à¦¡-অন পà§à¦²à¦¾à¦—ইনের সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ ফাইল খà§à¦à¦œà§‡ পাওয়া যায়নি।"
@@ -3118,14 +3106,6 @@ msgid "Help"
msgstr "হেলà§à¦ª"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
msgid "Online Docs"
@@ -3145,12 +3125,14 @@ msgid "Send Docs Feedback"
msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Community"
-msgstr "কমিউনিটি/যৌথ-সামাজিক উৎস"
+msgstr "সমà§à¦ªà§à¦°à¦¦à¦¾à§Ÿ"
#: editor/editor_node.cpp
+#, fuzzy
msgid "About"
-msgstr "সমà§à¦¬à¦¨à§à¦§à§‡/সমà§à¦ªà¦°à§à¦•ে"
+msgstr "সমà§à¦¬à¦¨à§à¦§à§‡"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -3290,6 +3272,25 @@ msgstr "à¦à¦•টি সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ খà§à¦²à§à¦¨ à¦à¦¬à¦‚ চà¦
#: editor/editor_node.cpp
#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"নিমà§à¦¨à§‹à¦•à§à¦¤ ফাইলসমূহ ডিসà§à¦•ে নতà§à¦¨à¦¤à¦°à¥¤\n"
+"কোন সিধানà§à¦¤à¦Ÿà¦¿ নেয়া উচিত হবে?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "রিলোড"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "পà§à¦¨à¦ƒà¦¸à¦‚রকà§à¦·à¦£"
+
+#: editor/editor_node.cpp
+#, fuzzy
msgid "New Inherited"
msgstr "নতà§à¦¨ উতà§à¦¤à¦°à¦¾à¦§à¦¿à¦•ারী দৃশà§à¦¯..."
@@ -3515,7 +3516,7 @@ msgstr "বোনà§â€Œ/হাড় তৈরি করà§à¦¨"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨"
@@ -4145,8 +4146,18 @@ msgstr "সংরকà§à¦·à¦¿à¦¤ হচà§à¦›à§‡..."
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "টেকà§à¦¸à¦Ÿ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
+msgid "%d match in %d file."
+msgstr "কোনো মিল নেই"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "কোনো মিল নেই"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "কোনো মিল নেই"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4296,6 +4307,21 @@ msgstr ""
msgid "Saving..."
msgstr "সংরকà§à¦·à¦¿à¦¤ হচà§à¦›à§‡..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "মোড (Mode) বাছাই করà§à¦¨"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "ইমà§à¦ªà§‹à¦°à§à¦Ÿ"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• sRGB বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨"
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -5340,7 +5366,8 @@ msgid "Got:"
msgstr "পà§à¦°à¦¾à¦ªà§à¦¤:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "sha256 হà§à¦¯à¦¾à¦¶ চেক বà§à¦¯à¦°à§à¦¥ হয়েছে"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5456,7 +5483,6 @@ msgid "Sort:"
msgstr "সাজান:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "বিভাগ:"
@@ -5489,8 +5515,7 @@ msgstr "পà§à¦°à¦¯à¦¼à§‡à¦¾à¦œà¦¨à§€à¦¯à¦¼ উপকরণসমূহের Z
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5504,10 +5529,30 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
#, fuzzy
msgid "Bake Lightmaps"
msgstr "লাইটà§à¦®à§à¦¯à¦¾à¦ªà§‡ হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨:"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ ফাইলসমূহ অপসারণ করবেন?"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6672,6 +6717,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° ParticlesMaterial পà§à¦°à¦¸à§‡à¦¸ মà§à¦¯à¦¾à¦Ÿà§‡à¦°à¦¿à§Ÿà¦¾à¦²à§‡ বিনà§à¦¦à§ সà§à¦¥à¦¾à¦ªà¦¨ সমà§à¦­à¦¬"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "à¦à¦¤à§‡ রূপানà§à¦¤à¦° করà§à¦¨..."
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
#, fuzzy
msgid "Generation Time (sec):"
@@ -6741,10 +6791,6 @@ msgstr "AABB উৎপনà§à¦¨ করà§à¦¨"
msgid "Generate Visibility AABB"
msgstr "AABB উৎপনà§à¦¨ করà§à¦¨"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "AABB উৎপনà§à¦¨ করà§à¦¨"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "বকà§à¦°à¦°à§‡à¦–া হতে বিনà§à¦¦à§ অপসারণ করà§à¦¨"
@@ -7384,6 +7430,14 @@ msgstr "ডকà§à¦®à§‡à¦¨à§à¦Ÿà¦¸à¦®à§‚হ বনà§à¦§ করà§à¦¨"
msgid "Run"
msgstr "চালান"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "পদারà§à¦ªà¦£ করà§à¦¨"
@@ -7440,16 +7494,6 @@ msgstr ""
"নিমà§à¦¨à§‹à¦•à§à¦¤ ফাইলসমূহ ডিসà§à¦•ে নতà§à¦¨à¦¤à¦°à¥¤\n"
"কোন সিধানà§à¦¤à¦Ÿà¦¿ নেয়া উচিত হবে?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "রিলোড"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "পà§à¦¨à¦ƒà¦¸à¦‚রকà§à¦·à¦£"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "ডিবাগার"
@@ -7552,8 +7596,8 @@ msgstr "বিনà§à¦¦à§ অপসারণ করà§à¦¨"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "করà§à¦¤à¦¨/কাট করà§à¦¨"
@@ -7799,6 +7843,11 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "সেল (Cell)-à¦à¦° আকার:"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "অবজেকà§à¦Ÿ আà¦à¦•া হয়েছে"
@@ -9158,11 +9207,6 @@ msgid "Error"
msgstr "সমসà§à¦¯à¦¾/ভà§à¦²"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "No commit message was provided"
-msgstr "কোন নাম বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করা হয়নি"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -9228,10 +9272,6 @@ msgid "Stage All"
msgstr "সকলà§à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করà§à¦¨"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡à¦° পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ সà§à¦¸à¦‚গত/সমনà§à¦¬à§Ÿ করà§à¦¨"
@@ -10596,6 +10636,11 @@ msgid "Projects"
msgstr "নতà§à¦¨ পà§à¦°à¦•লà§à¦ª"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "মিরর রিটà§à¦°à¦¾à¦‡à¦­ করা হচà§à¦›à§‡, দযা করে অপেকà§à¦·à¦¾ করà§à¦¨..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10887,7 +10932,7 @@ msgstr "পà§à¦°à¦•লà§à¦ªà§‡à¦° সেটিংস (engine.cfg)"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
-msgstr "জেনেরাল"
+msgstr "সাধারণ"
#: editor/project_settings_editor.cpp
msgid "Override For..."
@@ -10982,6 +11027,11 @@ msgstr "সà§à¦¬à§Ÿà¦‚কà§à¦°à¦¿à§Ÿ-লোড"
msgid "Plugins"
msgstr "পà§à¦²à¦¾à¦—ইন-সমূহ"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "লোড ডিফলà§à¦Ÿ"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "পà§à¦°à¦¿à¦¸à§‡à¦Ÿ..."
@@ -11247,6 +11297,16 @@ msgstr "শীষà§à¦¯ নোড ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸ করà§à¦¨
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "বাহিরের দৃশà§à¦¯à§‡à¦° নোডে à¦à¦Ÿà¦¿ করা সমà§à¦­à¦¬ হবে না!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "নোড-সমূহ পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨/পেসà§à¦Ÿ করà§à¦¨"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Detach Script"
msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ সংযà§à¦•à§à¦¤ করà§à¦¨"
@@ -11378,6 +11438,11 @@ msgid "Attach Script"
msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ সংযà§à¦•à§à¦¤ করà§à¦¨"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "নোড-সমূহ করà§à¦¤à¦¨/কাট করà§à¦¨"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "নোড(সমূহ) অপসারণ করà§à¦¨"
@@ -12274,6 +12339,39 @@ msgstr "ফিলà§à¦Ÿà¦¾à¦°à¦¸à¦®à§‚হ"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "AABB উৎপনà§à¦¨ করà§à¦¨"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "অংশাদি:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "ডানে মাতà§à¦°à¦¾ দিন"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾-পরবরà§à¦¤à§€ সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12837,11 +12935,13 @@ msgid "Select device from the list"
msgstr "লিসà§à¦Ÿ থেকে ডিভাইস সিলেকà§à¦Ÿ করà§à¦¨"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12853,11 +12953,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12865,9 +12965,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -13113,6 +13223,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "সংঘরà§à¦·à§‡ ফাà¦à¦•া/শà§à¦¨à§à¦¯ CollisionPolygon2D-à¦à¦° কোনো পà§à¦°à¦­à¦¾à¦¬ নেই।"
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -13300,31 +13418,33 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr ""
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "জà§à¦¯à¦¾à¦®à¦¿à¦¤à¦¿à¦•-আকার বিশà§à¦²à§‡à¦·à¦£ করা হচà§à¦›à§‡"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "Plotting Meshes: "
-msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡"
+msgid "Preparing environment"
+msgstr "পরিবেশ (Environment)"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "Plotting Lights:"
-msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡"
+msgid "Generating capture"
+msgstr "লাইটà§à¦®à§à¦¯à¦¾à¦ªà§‡ হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨:"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "লাইটà§à¦®à§à¦¯à¦¾à¦ªà§‡ হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨:"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "Lighting Meshes: "
-msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡"
+msgid "Done"
+msgstr "সমà§à¦ªà¦¨à§à¦¨ হয়েছে!"
#: scene/3d/collision_object.cpp
msgid ""
@@ -13393,14 +13513,13 @@ msgid "Plotting Meshes"
msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡"
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -13623,6 +13742,15 @@ msgstr "সতরà§à¦•তা!"
msgid "Please Confirm..."
msgstr "অনà§à¦—à§à¦°à¦¹ করে নিশà§à¦šà¦¿à¦¤ করà§à¦¨..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "à¦à¦•টি কারà§à¦¯à¦•র à¦à¦•à§à¦¸à¦Ÿà§‡à¦¨à¦¶à¦¨ বà§à¦¯à¦¬à¦¹à¦¾à¦° করা আবশà§à¦¯à¦•।"
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "সà§à¦¨à§à¦¯à¦¾à¦ª সকà§à¦°à¦¿à§Ÿ করà§à¦¨"
+
#: scene/gui/popup.cpp
#, fuzzy
msgid ""
@@ -13672,6 +13800,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "অকারà§à¦¯à¦•র উৎস!"
@@ -13703,6 +13837,29 @@ msgid "Constants cannot be modified."
msgstr ""
#, fuzzy
+#~ msgid "No"
+#~ msgstr "নোড"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "à¦à¦‡ দৃশà§à¦¯à¦Ÿà¦¿ কখনোই সংরকà§à¦·à¦£ করা হয় নি। চালানোর পূরà§à¦¬à§‡ সংরকà§à¦·à¦£ করবেন?"
+
+#, fuzzy
+#~ msgid "Plotting Meshes: "
+#~ msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡"
+
+#, fuzzy
+#~ msgid "Lighting Meshes: "
+#~ msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡"
+
+#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "টেকà§à¦¸à¦Ÿ অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨"
+
+#, fuzzy
+#~ msgid "No commit message was provided"
+#~ msgstr "কোন নাম বà§à¦¯à¦¾à¦¬à¦¹à¦¾à¦° করা হয়নি"
+
+#, fuzzy
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "গà§à¦°à§à¦ªà§‡à¦° নাম ইতিমধà§à¦¯à§‡à¦‡ আছে!"
@@ -14028,10 +14185,6 @@ msgstr ""
#~ msgstr "রিসোরà§à¦¸ লোড বà§à¦¯à¦°à§à¦¥ হয়েছে।"
#, fuzzy
-#~ msgid "Done"
-#~ msgstr "সমà§à¦ªà¦¨à§à¦¨ হয়েছে!"
-
-#, fuzzy
#~ msgid "Failed to create C# project."
#~ msgstr "রিসোরà§à¦¸ লোড বà§à¦¯à¦°à§à¦¥ হয়েছে।"
@@ -15309,9 +15462,6 @@ msgstr ""
#~ msgid "Use Default Light"
#~ msgstr "পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• লাইট বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨"
-#~ msgid "Use Default sRGB"
-#~ msgstr "পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• sRGB বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨"
-
#~ msgid "Default Light Normal:"
#~ msgstr "লাইটের পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• নরমাল:"
diff --git a/editor/translations/br.po b/editor/translations/br.po
new file mode 100644
index 0000000000..7600dd4eb1
--- /dev/null
+++ b/editor/translations/br.po
@@ -0,0 +1,12481 @@
+# Breton translation of the Godot Engine editor
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
+# This file is distributed under the same license as the Godot source code.
+#
+# Feufoll <feufoll@gmail.com>, 2020.
+msgid ""
+msgstr ""
+"Project-Id-Version: Godot Engine editor\n"
+"PO-Revision-Date: 2020-12-29 15:03+0000\n"
+"Last-Translator: Feufoll <feufoll@gmail.com>\n"
+"Language-Team: Breton <https://hosted.weblate.org/projects/godot-engine/"
+"godot/br/>\n"
+"Language: br\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+"Plural-Forms: nplurals=5; plural=(n % 10 == 1 && n % 100 != 11 && n % 100 != "
+"71 && n % 100 != 91) ? 0 : ((n % 10 == 2 && n % 100 != 12 && n % 100 != 72 "
+"&& n % 100 != 92) ? 1 : ((((n % 10 == 3 || n % 10 == 4) || n % 10 == 9) && "
+"(n % 100 < 10 || n % 100 > 19) && (n % 100 < 70 || n % 100 > 79) && (n % 100 "
+"< 90 || n % 100 > 99)) ? 2 : ((n != 0 && n % 1000000 == 0) ? 3 : 4)));\n"
+"X-Generator: Weblate 4.4.1-dev\n"
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Invalid type argument to convert(), use TYPE_* constants."
+msgstr "Argumant a dip fall e convert(), implijit koñstantennoù TYPE_*."
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+msgid "Expected a string of length 1 (a character)."
+msgstr "O c'hortozh ur chadenn a hirder 1 (ul lizherenn)."
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/mono/glue/gd_glue.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Not enough bytes for decoding bytes, or invalid format."
+msgstr "Re nebeut a oktedoù evit diskodiñ, pe formad fall."
+
+#: core/math/expression.cpp
+msgid "Invalid input %i (not passed) in expression"
+msgstr "Enkas fall %i (ket tremenet) en eztaol"
+
+#: core/math/expression.cpp
+msgid "self can't be used because instance is null (not passed)"
+msgstr "self n'hall ket bezhañ implijet dre eo nul an istañs (ket tremened)"
+
+#: core/math/expression.cpp
+msgid "Invalid operands to operator %s, %s and %s."
+msgstr "Oberantennoù fall en oberantenn %s, %s ha %s."
+
+#: core/math/expression.cpp
+msgid "Invalid index of type %s for base type %s"
+msgstr "Indeks fall a dip %s evit an tip diazez %s"
+
+#: core/math/expression.cpp
+msgid "Invalid named index '%s' for base type %s"
+msgstr "Anv fall d'an indeks '%s' evit an tip orin %s"
+
+#: core/math/expression.cpp
+msgid "Invalid arguments to construct '%s'"
+msgstr "Argumant fall evit sevel '%s'"
+
+#: core/math/expression.cpp
+msgid "On call to '%s':"
+msgstr "O gervel '%s' :"
+
+#: core/ustring.cpp
+msgid "B"
+msgstr "B"
+
+#: core/ustring.cpp
+msgid "KiB"
+msgstr "KiB"
+
+#: core/ustring.cpp
+msgid "MiB"
+msgstr "MiB"
+
+#: core/ustring.cpp
+msgid "GiB"
+msgstr "GiB"
+
+#: core/ustring.cpp
+msgid "TiB"
+msgstr "TiB"
+
+#: core/ustring.cpp
+msgid "PiB"
+msgstr "PiB"
+
+#: core/ustring.cpp
+msgid "EiB"
+msgstr "EiB"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Free"
+msgstr "Dieub"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Balanced"
+msgstr "Kempouezet"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Mirror"
+msgstr "Melezour"
+
+#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
+msgid "Time:"
+msgstr "Amzer :"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Value:"
+msgstr "Talvoud :"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Insert Key Here"
+msgstr "Enlakaat an Alc'hwezh Amañ"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Duplicate Selected Key(s)"
+msgstr "Eilskoueriañ an Alc'whezh(ioù) Uhelsklaeriet"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Delete Selected Key(s)"
+msgstr "Dilemel an Alc'hwez(ioù) Uhelsklaeriet"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Add Bezier Point"
+msgstr "Ouzhpenn ur Poent Bezier"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Move Bezier Points"
+msgstr "Fiñval ar Poentoù Bezier"
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Duplicate Keys"
+msgstr "Eilskloueriañ an Alc'hwezhioù Fiñvskeudenn"
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Delete Keys"
+msgstr "Dilemel Alc'hwezhioù Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Time"
+msgstr "Cheñch Amzer ar Skeudenn-alc'hwezh Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transition"
+msgstr "Cheñch Tremenadur ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transform"
+msgstr "Cheñch Treuzfurmadur ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Value"
+msgstr "Cheñch Talvoud ar Skeudenn-alc'hwez Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Call"
+msgstr "Cheñch Galv ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Cheñch Meur a Amzer Skeudenn-alc'hwez Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Cheñch Meur a Tremenadur Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Cheñch Meur a Treuzfurmadur Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Cheñch Meur Talvoud Skeudenn-alc'hwez Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Cheñch Meur Galv Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Length"
+msgstr "Cheñch Hirder ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation Loop"
+msgstr "Cheñch Tro ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Property Track"
+msgstr "Roudenn Perzhioù"
+
+#: editor/animation_track_editor.cpp
+msgid "3D Transform Track"
+msgstr "Roudenn Treuzfurmadur 3D"
+
+#: editor/animation_track_editor.cpp
+msgid "Call Method Track"
+msgstr "Roudenn Galv Metodenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Bezier Curve Track"
+msgstr "Roudenn Krommenn Bezier"
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Playback Track"
+msgstr "Roudenn Lenn Audio"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Playback Track"
+msgstr "Roudenn Lenn Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (frames)"
+msgstr "Hirder ar Fiñvskeudenn (e skeudennoù)"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (seconds)"
+msgstr "Hirder Fiñvskeudenn (e sekondennoù)"
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track"
+msgstr "Ouzhpenn Roudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Looping"
+msgstr "Tro Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Functions:"
+msgstr "Fonksionoù :"
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Clips:"
+msgstr "Lodenn Audio :"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Clips:"
+msgstr "Lodennoù Fiñvskeudenn :"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Track Path"
+msgstr "Cheñch Hent ar Roudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle this track on/off."
+msgstr "Aktivañ/Diaktivañ ar roudenn-se."
+
+#: editor/animation_track_editor.cpp
+msgid "Update Mode (How this property is set)"
+msgstr "Mod Bremenadur (Penaos eo termenet ar perzh-se)"
+
+#: editor/animation_track_editor.cpp
+msgid "Interpolation Mode"
+msgstr "Mod Interpoladur"
+
+#: editor/animation_track_editor.cpp
+msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
+msgstr "Mod Treiñ (Interpoliñ ar fin gant penn-kentañ an tro)"
+
+#: editor/animation_track_editor.cpp
+msgid "Remove this track."
+msgstr "Dilemel ar roudenn-se."
+
+#: editor/animation_track_editor.cpp
+msgid "Time (s): "
+msgstr "Amzer (s) : "
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle Track Enabled"
+msgstr "Aktivañ ar Roudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Continuous"
+msgstr "Kendalc'hus"
+
+#: editor/animation_track_editor.cpp
+msgid "Discrete"
+msgstr "Diskretel"
+
+#: editor/animation_track_editor.cpp
+msgid "Trigger"
+msgstr "Deraouer"
+
+#: editor/animation_track_editor.cpp
+msgid "Capture"
+msgstr "Tapout"
+
+#: editor/animation_track_editor.cpp
+msgid "Nearest"
+msgstr "Tostañ"
+
+#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
+#: editor/property_editor.cpp
+msgid "Linear"
+msgstr "Lineel"
+
+#: editor/animation_track_editor.cpp
+msgid "Cubic"
+msgstr "Kubek"
+
+#: editor/animation_track_editor.cpp
+msgid "Clamp Loop Interp"
+msgstr "Herzel Interpoladur an Tro"
+
+#: editor/animation_track_editor.cpp
+msgid "Wrap Loop Interp"
+msgstr "Goloiñ Interp. an Tro"
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key"
+msgstr "Enlakaat Alc'hwez"
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Key(s)"
+msgstr "Eilskoueriañ Alc'hwez(ioù)"
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Key(s)"
+msgstr "Dilemel Alc'hwez(ioù)"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Update Mode"
+msgstr "Cheñch Mod Bremenadur ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Interpolation Mode"
+msgstr "Cheñch Mod Interpoliñ ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Loop Mode"
+msgstr "Cheñch Mod Treiñ ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Remove Anim Track"
+msgstr "Dilemel ar Roudenn Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Create NEW track for %s and insert key?"
+msgstr "Krouiñ ur roudenn NEVEZ evit %s ha enlakaat an alc'hwez ?"
+
+#: editor/animation_track_editor.cpp
+msgid "Create %d NEW tracks and insert keys?"
+msgstr "Krouiñ %d roudenn NEVEZ hag enlakaat alc'hwezioù ?"
+
+#: editor/animation_track_editor.cpp editor/create_dialog.cpp
+#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create"
+msgstr "Krouiñ"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert"
+msgstr "Enlakaat Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "AnimationPlayer can't animate itself, only other players."
+msgstr ""
+"AnimationPlayer n'hall ket en em lakaat de fiñval, met nemet al lennerezhioù "
+"all."
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Create & Insert"
+msgstr "Krouiñ & Enlakaat Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Track & Key"
+msgstr "Enlakaat Roudenn & Alc'hwez er Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Key"
+msgstr "Enlakaat an Alc'hwez er Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Step"
+msgstr "Cheñch Pazenn ar Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Rearrange Tracks"
+msgstr "Adrenkañ Roudennoù"
+
+#: editor/animation_track_editor.cpp
+msgid "Transform tracks only apply to Spatial-based nodes."
+msgstr ""
+"Roudennoù treuzfurmadur ne c'hall nemet bezañ implijet gant skoulmoù "
+"diazezet war Spatial."
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"Audio tracks can only point to nodes of type:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
+msgstr ""
+"Roudennoù Audio a c'hell poentañ nemetken da skoulmoù eus tip :\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation tracks can only point to AnimationPlayer nodes."
+msgstr ""
+"Roudennoù Fiñvskeudenn a c'hell poentañ nemetken da skoulmoù AnimationPlayer."
+
+#: editor/animation_track_editor.cpp
+msgid "An animation player can't animate itself, only other players."
+msgstr ""
+"Ul lennerezh fiñvskeudenn ne c'hell ket em lakaat da fiñval, nemet "
+"lennerezhioù all."
+
+#: editor/animation_track_editor.cpp
+msgid "Not possible to add a new track without a root"
+msgstr "Dibosupl ouzhpenn ur roudenn nevez hep ur gwrizienn"
+
+#: editor/animation_track_editor.cpp
+msgid "Invalid track for Bezier (no suitable sub-properties)"
+msgstr "Roudenn fall evit Bezier (iz-perzh mat ebet)"
+
+#: editor/animation_track_editor.cpp
+msgid "Add Bezier Track"
+msgstr "Ouzhpenn Roudenn Bezier"
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a key."
+msgstr "Hentad roudenn fall, neuze eo dibosupl ouzhpenn un alc'hwez."
+
+#: editor/animation_track_editor.cpp
+msgid "Track is not of type Spatial, can't insert key"
+msgstr "N'eo ket ar roudenn deus tip Spatial, dibosupl enakaat un alc'hwez"
+
+#: editor/animation_track_editor.cpp
+msgid "Add Transform Track Key"
+msgstr "Ouzhpenn Alc'hwez Roudenn Treuzfurmadur"
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track Key"
+msgstr "Ouzhpenn Alc'hwez Roudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a method key."
+msgstr "Hentad roudenn fall, dibosupl ouzhpenn un alc'hwez metodenn."
+
+#: editor/animation_track_editor.cpp
+msgid "Add Method Track Key"
+msgstr "Ouzhpenn Alc'hwez Roudenn Metodenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Method not found in object: "
+msgstr "N'eus ket deus ar metodenn en objed : "
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Move Keys"
+msgstr "Fiñval Alc'hwezioù Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid "Clipboard is empty"
+msgstr "Goullo ar gwask-paper"
+
+#: editor/animation_track_editor.cpp
+msgid "Paste Tracks"
+msgstr "Pegañ ar Roudennoù"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Scale Keys"
+msgstr "Cheñch Skeul Alc'hwezioù Fiñvskeudenn"
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This option does not work for Bezier editing, as it's only a single track."
+msgstr ""
+"An opsion-se ne dro ket evit editañ Bezier, dre eo ur roudenn nemetken."
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This animation belongs to an imported scene, so changes to imported tracks "
+"will not be saved.\n"
+"\n"
+"To enable the ability to add custom tracks, navigate to the scene's import "
+"settings and set\n"
+"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks"
+"\", then re-import.\n"
+"Alternatively, use an import preset that imports animations to separate "
+"files."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Warning: Editing imported animation"
+msgstr "Diwallit : Oc'h editañ ur fiñvskeudenn emporzhiet"
+
+#: editor/animation_track_editor.cpp
+msgid "Select an AnimationPlayer node to create and edit animations."
+msgstr ""
+"Choazit ur skoulm AnimationPlayer evit krouiñ hag editañ fiñvskeudennoù ."
+
+#: editor/animation_track_editor.cpp
+msgid "Only show tracks from nodes selected in tree."
+msgstr "Diskouez nemet roudennoù ar skoulmoù choazet er wezenn ."
+
+#: editor/animation_track_editor.cpp
+msgid "Group tracks by node or display them as plain list."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Snap:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation step value."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Seconds"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "FPS"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_properties.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation properties."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Copy Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale From Cursor"
+msgstr ""
+
+#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Duplicate Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Transposed"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Next Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Previous Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Pick the node that will be animated:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Use Bezier Curves"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim. Optimizer"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Linear Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Angular Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max Optimizable Angle:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove invalid keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove unresolved and empty tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-up all animations"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation(s) (NO UNDO!)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Ratio:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Select Tracks to Copy"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_log.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Copy"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Select All/None"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Add Audio Track Clip"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip Start Offset"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip End Offset"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Resize Array"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value Type"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Go to Line"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line Number:"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "%d replaced."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Match Case"
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Whole Words"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replace"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replace All"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Selection Only"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
+#: editor/plugins/text_editor.cpp
+msgid "Standard"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Toggle Scripts Panel"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom In"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Out"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Reset Zoom"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Warnings"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line and column numbers."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Method in target node must be specified."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Method name must be a valid identifier."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Target method not found. Specify a valid method or attach a script to the "
+"target node."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Node:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Script:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "From Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Scene does not contain any script."
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
+#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+msgid "Add"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp
+msgid "Remove"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Add Extra Call Argument:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Extra Call Arguments:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Receiver Method:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Advanced"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Deferred"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Defers the signal, storing it in a queue and only firing it at idle time."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Oneshot"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnects the signal after its first emission."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Cannot connect signal"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/export_template_manager.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Close"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect '%s' to '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect '%s' from '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect all from signal: '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Disconnect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect a Signal to a Method"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit Connection:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
+msgid "Signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from this signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect All"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Go To Method"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Change %s Type"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/project_settings_editor.cpp
+msgid "Change"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Create New %s"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp
+msgid "Favorites:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+msgid "Recent:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Matches:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp
+#: editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Description:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Scene '%s' is currently being edited.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Resource '%s' is in use.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resource"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
+msgid "Path"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Broken"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependency Editor"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement Resource:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Open"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owners Of:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Remove selected files from the project? (no undo)\n"
+"You can find the removed files in the system trash to restore them."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"The files being removed are required by other resources in order for them to "
+"work.\n"
+"Remove them anyway? (no undo)\n"
+"You can find the removed files in the system trash to restore them."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Cannot remove:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Error loading:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Load failed due to missing dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_node.cpp
+msgid "Open Anyway"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Which action should be taken?"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Errors loading!"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Permanently delete %d item(s)? (No undo!)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Show Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Orphan Resource Explorer"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
+msgid "Delete"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owns"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resources Without Explicit Ownership:"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Key"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Value"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Thanks from the Godot community!"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Godot Engine contributors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Project Founders"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Lead Developer"
+msgstr ""
+
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
+#: editor/editor_about.cpp
+msgid "Project Manager "
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Developers"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Authors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Platinum Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Mini Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Silver Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "License"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Third-party Licenses"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid ""
+"Godot Engine relies on a number of third-party free and open source "
+"libraries, all compatible with the terms of its MIT license. The following "
+"is an exhaustive list of all such third-party components with their "
+"respective copyright statements and license terms."
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "All Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Licenses"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Error opening package file, not in ZIP format."
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "%s (Already Exists)"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Uncompressing Assets"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "The following files failed extraction from package:"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "And %s more files."
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Package installed successfully!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Success!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Contents:"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/editor_node.cpp
+msgid "Install"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Installer"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Speakers"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Rename Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Change Audio Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Bypass Effects"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Select Audio Bus Send"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Drag & drop to rearrange."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bypass"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bus options"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Duplicate"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Master bus can't be deleted!"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Duplicate Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save Audio Bus Layout As..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Location for New Layout..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Open Audio Bus Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "There is no '%s' file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Invalid file, not an audio bus layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Error saving file: %s"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add a new Audio Bus to this layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Load"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load an existing Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save As"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save this Bus Layout to a file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/import_dock.cpp
+msgid "Load Default"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load the default Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Create a new Bus Layout."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Invalid name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Valid characters:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing engine class name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing built-in type name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing global constant name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Keyword cannot be used as an autoload name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Autoload '%s' already exists!"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rename Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Toggle AutoLoad Globals"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Move Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Remove Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
+msgid "Enable"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rearrange Autoloads"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Can't add autoload:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Add AutoLoad"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Path:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Node Name:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Name"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Singleton"
+msgstr ""
+
+#: editor/editor_data.cpp editor/inspector_dock.cpp
+msgid "Paste Params"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating Scene"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Storing local changes..."
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating scene..."
+msgstr ""
+
+#: editor/editor_data.cpp editor/editor_properties.cpp
+msgid "[empty]"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "[unsaved]"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Please select a base directory first."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose a Directory"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Create Folder"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
+#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp
+msgid "Name:"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
+msgid "Could not create folder."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Storing File:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "No export template found at the expected path:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Packing"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
+"Etc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' texture compression for GLES3. Enable "
+"'Import Etc 2' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'PVRTC' texture compression for GLES2. Enable "
+"'Import Pvrtc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
+"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'PVRTC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom debug template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom release template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/javascript/export/export.cpp
+msgid "Template file not found:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "3D Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Script Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Asset Library"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Scene Tree Editing"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Node Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "FileSystem Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase profile '%s'? (no undo)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile must be a valid filename and must not contain '.'"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile with this name already exists."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled, Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enable Contextual Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Properties:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Features:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Classes:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "File '%s' format is invalid, import aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid ""
+"Profile '%s' already exists. Remove it first before importing, import "
+"aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Error saving profile to path: '%s'."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Unset"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Current Profile:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Make Current"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "New"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/editor_node.cpp
+#: editor/project_manager.cpp
+msgid "Import"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
+msgid "Export"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Available Profiles:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "New profile name:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Godot Feature Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Profile(s)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Export Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Manage Editor Feature Profiles"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select Current Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File Exists, Overwrite?"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select This Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Copy Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Open in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+msgid "Show in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "New Folder..."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Refresh"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Recognized"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Files (*)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open File(s)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File or Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Save"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Save a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Back"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Forward"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Hidden Files"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Favorite"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Mode"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Focus Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Down"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to previous folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to next folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Go to parent folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "(Un)favorite current folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a grid of thumbnails."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a list."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Directories & Files:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
+#: editor/plugins/style_box_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Preview:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File:"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "ScanSources"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid ""
+"There are multiple importers for different types pointing to file %s, import "
+"aborted"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "(Re)Importing Assets"
+msgstr ""
+
+#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
+msgid "Top"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class:"
+msgstr ""
+
+#: editor/editor_help.cpp editor/scene_tree_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Inherits:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Inherited by:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Description"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Online Tutorials"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "override:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "default:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Methods"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Theme Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Enumerations"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "(value)"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this property. Please help us by "
+"[color=$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this method. Please help us by [color="
+"$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Help"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Case Sensitive"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Show Hierarchy"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Display All"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Classes Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Methods Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Signals Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Constants Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Theme Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Member Type"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Class"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Method"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
+msgid "Signal"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
+msgid "Constant"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Property"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Theme Property"
+msgstr ""
+
+#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
+msgid "Property:"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set Multiple:"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Output:"
+msgstr ""
+
+#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Copy Selection"
+msgstr ""
+
+#: editor/editor_log.cpp editor/editor_network_profiler.cpp
+#: editor/editor_profiler.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/property_editor.cpp editor/scene_tree_dock.cpp
+#: editor/script_editor_debugger.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Clear"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Clear Output"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp editor/editor_node.cpp
+#: editor/editor_profiler.cpp
+msgid "Stop"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
+#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
+msgid "Start"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "%s/s"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Down"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Up"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp editor/editor_node.cpp
+msgid "Node"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Incoming RPC"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Incoming RSET"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Outgoing RPC"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Outgoing RSET"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Imported resources can't be saved."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: scene/gui/dialogs.cpp
+msgid "OK"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Error saving resource!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource can't be saved because it does not belong to the edited scene. "
+"Make it unique first."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Save Resource As..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't open file for writing:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Requested file format unknown:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while saving."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Can't open '%s'. The file could have been moved or deleted."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while parsing '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unexpected end of file '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Missing '%s' or its dependencies."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while loading '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saving Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Analyzing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Creating Thumbnail"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a tree root."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene can't be saved because there is a cyclic instancing inclusion.\n"
+"Please resolve it and then attempt to save again."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
+"be satisfied."
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "Can't overwrite scene that is still open!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load MeshLibrary for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving MeshLibrary!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load TileSet for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving TileSet!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"An error occurred while trying to save the editor layout.\n"
+"Make sure the editor's user data path is writable."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Default editor layout overridden.\n"
+"To restore the Default layout to its base settings, use the Delete Layout "
+"option and delete the Default layout."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Layout name not found!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Restored the Default layout to its base settings."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was imported, so it's not editable.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was instanced or inherited.\n"
+"Changes to it won't be kept when saving the current scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource was imported, so it's not editable. Change its settings in the "
+"import panel and then re-import."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene was imported, so changes to it won't be kept.\n"
+"Instancing it or inheriting will allow making changes to it.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This is a remote object, so changes to it won't be kept.\n"
+"Please read the documentation relevant to debugging to better understand "
+"this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "There is no defined scene to run."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Could not start subprocess!"
+msgstr ""
+
+#: editor/editor_node.cpp editor/filesystem_dock.cpp
+msgid "Open Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Base Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Script..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Close"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to '%s' before closing?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saved %s modified resource(s)."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "A root node is required to save the scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene As..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "This operation can't be done without a scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Mesh Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a root node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Tile Set"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a selected node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Current scene not saved. Open anyway?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't reload a scene that was never saved."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reload Saved Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"The current scene has unsaved changes.\n"
+"Reload the saved scene anyway? This action cannot be undone."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Run Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Exit the editor?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to the following scene(s) before quitting?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes the following scene(s) before opening Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This option is deprecated. Situations where refresh must be forced are now "
+"considered a bug. Please report."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pick a Main Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' There seems to be an error in "
+"the code, please check the syntax."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Scene '%s' was automatically imported, so it can't be modified.\n"
+"To make changes to it, a new inherited scene can be created."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Error loading scene, it must be inside the project path. Use 'Import' to "
+"open the scene, then save it inside the project path."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene '%s' has broken dependencies:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Clear Recent Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"No main scene has ever been defined, select one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' does not exist, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' is not a scene file, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Delete Layout"
+msgstr ""
+
+#: editor/editor_node.cpp editor/import_dock.cpp
+#: editor/script_create_dialog.cpp
+msgid "Default"
+msgstr ""
+
+#: editor/editor_node.cpp editor/editor_properties.cpp
+#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
+msgid "Show in FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play This Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Close Other Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tabs to the Right"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close All Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Switch Scene Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files or folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Dock Position"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Distraction Free Mode"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle distraction-free mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Add a new scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Go to previously opened scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Next tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Previous tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Filter Files..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Operations with scene files."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save All Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Convert To..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "MeshLibrary..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "TileSet..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Undo"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Redo"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Miscellaneous project or scene-wide tools."
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+#: editor/script_create_dialog.cpp
+msgid "Project"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Project Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
+msgid "Version Control"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
+msgid "Set Up Version Control"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Shut Down Version Control"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Orphan Resource Explorer..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit to Project List"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/project_export.cpp
+msgid "Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Deploy with Remote Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Small Deploy with Network Filesystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
+"The filesystem will be provided from the project by the editor over the "
+"network.\n"
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Visible Collision Shapes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Visible Navigation"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Synchronize Scene Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Synchronize Script Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
+msgstr ""
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Take Screenshot"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Screenshots are stored in the Editor Data/Settings Folder."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle Fullscreen"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle System Console"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data/Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Editor Features..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
+msgid "Help"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Online Docs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Q&A"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+msgid "Community"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "About"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause the scene execution for debugging."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Stop the scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the edited scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play custom scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Custom Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Changing the video driver requires restarting the editor."
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_settings_editor.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Save & Restart"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Spins when the editor window redraws."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update Continuously"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update When Changed"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Hide Update Spinner"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Inspector"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Expand Bottom Panel"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Output"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Don't Save"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Android build template is missing, please install relevant templates."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Templates"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This will set up your project for custom Android builds by installing the "
+"source template to \"res://android/build\".\n"
+"You can then apply modifications and build your own custom APK on export "
+"(adding modules, changing the AndroidManifest.xml, etc.).\n"
+"Note that in order to make custom builds instead of using pre-built APKs, "
+"the \"Use Custom Build\" option should be enabled in the Android export "
+"preset."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"The Android build template is already installed in this project and it won't "
+"be overwritten.\n"
+"Remove the \"res://android/build\" directory manually before attempting this "
+"operation again."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Import Templates From ZIP File"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Template Package"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Merge With Existing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open & Run a Script"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Load Errors"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Select"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 2D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 3D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Script Editor"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "Open Asset Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the next Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the previous Editor"
+msgstr ""
+
+#: editor/editor_node.h
+msgid "Warning!"
+msgstr ""
+
+#: editor/editor_path.cpp
+msgid "No sub-resources found."
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Creating Mesh Previews"
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Thumbnail..."
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Main Script:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit Plugin"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Installed Plugins:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Update"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Version:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Author:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Status:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Measure:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Average Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Physics Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Inclusive"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Self"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame #:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Time"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Calls"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/script_create_dialog.cpp
+msgid "On"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Layer"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Bit %d, value %d"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "[Empty]"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
+msgid "Assign..."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Invalid RID"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"The selected resource (%s) does not match any type expected for this "
+"property (%s)."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on resources saved as a file.\n"
+"Resource needs to belong to a scene."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on this resource because it's not set as "
+"local to scene.\n"
+"Please switch on the 'local to scene' property on it (and all resources "
+"containing it up to a node)."
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Pick a Viewport"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New Script"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
+msgid "Extend Script"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New %s"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Make Unique"
+msgstr ""
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Paste"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Convert To %s"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Selected node is not a Viewport!"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Size: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Page: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Item"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Key:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Value:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Add Key/Value Pair"
+msgstr ""
+
+#: editor/editor_run_native.cpp
+msgid ""
+"No runnable export preset found for this platform.\n"
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Write your logic in the _run() method."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "There is an edited scene already."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't instance script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the 'tool' keyword?"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't run script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the '_run' method?"
+msgstr ""
+
+#: editor/editor_spin_slider.cpp
+msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes."
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Select Node(s) to Import"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp editor/project_manager.cpp
+msgid "Browse"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Scene Path:"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Import From Node:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redownload"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uninstall"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Installed)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Missing)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Current)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Retrieving mirrors, please wait..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove template version '%s'?"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't open export templates zip."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Invalid version.txt format inside templates: %s."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "No version.txt found inside templates."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error creating path for templates:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Extracting Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Importing:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error getting the list of mirrors."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error parsing JSON of mirror list. Please report this issue!"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"No download links found for this version. Direct download is only available "
+"for official releases."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Request Failed."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redirect Loop."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Complete."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error requesting URL:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connecting to Mirror..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Disconnected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Resolving"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Resolve"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connecting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Connect"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Requesting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Downloading"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connection Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "SSL Handshake Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uncompressing Android Build Sources"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Current Version:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Installed Versions:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Install From File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove Template"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select Template File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Godot Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Export Template Manager"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select mirror from list: (Shift+Click: Open in Browser)"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Status: Import of file failed. Please fix file and reimport manually."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move/rename resources root."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move a folder into itself."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error moving:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error duplicating:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Unable to update dependencies:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
+msgid "No name provided."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Provided name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "A file or folder with this name already exists."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"The following files or folders conflict with items in the target location "
+"'%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Do you wish to overwrite them?"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Inherited Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Set As Main Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Open Scenes"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Instance"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Add to Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Remove from Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Edit Dependencies..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "View Owners..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move To..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "New Script..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Resource..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Expand All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Collapse All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicate..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move to Trash"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Rename..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Previous Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Next Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Re-Scan Filesystem"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Toggle Split Mode"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Search files"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"Scanning Files,\n"
+"Please Wait..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/project_manager.cpp editor/rename_dialog.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Rename"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Overwrite"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Create Script"
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Find in Files"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Folder:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Filters:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid ""
+"Include the files with the following extensions. Add or remove them in "
+"ProjectSettings."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
+msgid "Replace..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
+msgid "Cancel"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace all (no undo)"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Searching..."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group name already exists."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Invalid group name."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/node_dock.cpp
+msgid "Groups"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes Not in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Filter nodes"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Empty groups will be automatically removed."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group Editor"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Manage Groups"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Single Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Importing Scene..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating Lightmaps"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating for Mesh: "
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Running Custom Script..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Couldn't load post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Invalid/broken script for post-import (check console):"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Error running post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Did you return a Node-derived object in the `post_import()` method?"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Saving..."
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "%d Files"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Set as Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Clear Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Import As:"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Preset"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Reimport"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Save Scenes, Re-Import, and Restart"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Changing the type of an imported file requires editor restart."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid ""
+"WARNING: Assets exist that use this resource, they may stop loading properly."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Failed to load resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Expand All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Collapse All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save As..."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Params"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Edit Resource Clipboard"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Resource"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Built-In"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Sub-Resources Unique"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Open in Help"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Create a new resource in memory and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Load an existing resource from disk and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Save the currently edited resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the previous edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the next edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "History of recently edited objects."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Object properties."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Filter properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Changes may be lost!"
+msgstr ""
+
+#: editor/multi_node_edit.cpp
+msgid "MultiNode Set"
+msgstr ""
+
+#: editor/node_dock.cpp
+msgid "Select a single node to edit its signals and groups."
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Edit a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Create a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Plugin Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Subfolder:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp
+msgid "Language:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Script Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Activate now?"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid ""
+"Edit points.\n"
+"LMB: Move Point\n"
+"RMB: Erase Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Erase points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Insert Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon (Remove Point)"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Remove Polygon And Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Load..."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Move Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "This type of node can't be used. Only root nodes are allowed."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Animation Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Remove BlendSpace1D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Move BlendSpace1D Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"AnimationTree is inactive.\n"
+"Activate to enable playback, check node warnings if activation fails."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Set the blending position within the space"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Select and move points, create points with RMB."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
+msgid "Enable snap and show grid."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Open Editor"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Open Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Triangle already exists."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "BlendSpace2D does not belong to an AnimationTree node."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "No triangles exist, so no blending can take place."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Toggle Auto Triangles"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create triangles by connecting points."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Erase points and triangles."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Generate blend triangles automatically (instead of manually)"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Parameter Changed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Filters"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Output node can't be added to the blend tree."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Add Node to BlendTree"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Node Moved"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Unable to connect, port may be in use or connection may be invalid."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Connected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Disconnected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Set Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Toggle Filter On/Off"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Change Filter"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "No animation player set, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Player path set is invalid, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid ""
+"Animation player has no valid root node path, so unable to retrieve track "
+"names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Anim Clips"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Audio Clips"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Functions"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Renamed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node..."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Edit Filtered Tracks:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Enable Filtering"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Toggle Autoplay"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Anim"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Animation?"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Remove Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Invalid animation name!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation name already exists!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Next Changed"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Blend Time"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Load Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Duplicate Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to copy!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation resource on clipboard!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pasted Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Paste Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to edit!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from current pos. (A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from end. (Shift+A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Stop animation playback. (S)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from start. (Shift+D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from current pos. (D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation position (in seconds)."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Scale animation playback globally for the node."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Tools"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Edit Transitions..."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Open in Inspector"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Display list of animations in player."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Autoplay on Load"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Enable Onion Skinning"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Onion Skinning Options"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Directions"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Past"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Future"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Depth"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "1 step"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "2 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "3 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Differences Only"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Force White Modulate"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Include Gizmos (3D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pin AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+msgid "Error!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Times:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Next (Auto Queue):"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Cross-Animation Blend Times"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Move Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition exists!"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Add Transition"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Immediate"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Sync"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "At End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Travel"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Start and end nodes are needed for a sub-transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "No playback resource set at path: %s."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set Start Node (Autoplay)"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"Select and move nodes.\n"
+"RMB to add new nodes.\n"
+"Shift+LMB to create connections."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Create new nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Connect nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Remove selected node or transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Toggle autoplay this animation on start, restart or seek to zero."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set the end animation. This is useful for sub-transitions."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition: "
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Play Mode:"
+msgstr ""
+
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "AnimationTree"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "New name:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Scale:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade In (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade Out (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Auto Restart:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Random Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Start!"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Amount:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 0:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 1:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "X-Fade Time (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Current:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Input"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Clear Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Set Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Delete Input"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is valid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is invalid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "OneShot Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend2 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend3 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend4 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeScale Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeSeek Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Transition Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Import Animations..."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Node Filters"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Filters..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Contents:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "View Files"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connection error, please try again."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect to host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response from host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, return code:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, too many redirects"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Bad download hash, assuming file has been tampered with."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Expected:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Got:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed SHA-256 hash check"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Asset Download Error:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading (%s / %s)..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Resolving..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Error making request"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Idle"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Retry"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download Error"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download for this asset is already in progress!"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Recently Updated"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Least Recently Updated"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Name (A-Z)"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Name (Z-A)"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "License (A-Z)"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "License (Z-A)"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "First"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Previous"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Next"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Last"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "All"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No results for \"%s\"."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+msgid "Sort:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Category:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Site:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Support"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Official"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Testing"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Assets ZIP File"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Can't determine a save path for lightmap images.\n"
+"Save your scene and try again."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake "
+"Light' flag is on."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed creating lightmap images, make sure path is writable."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Bake Lightmaps"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
+#: editor/plugins/camera_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Preview"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Configure Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Primary Line Every:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "steps"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal and Vertical Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate CanvasItem \"%s\" to %d degrees"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem \"%s\" Anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale Node2D \"%s\" to (%s, %s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Resize Control \"%s\" to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale CanvasItem \"%s\" to (%s, %s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem \"%s\" to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Children of containers have their anchors and margins values overridden by "
+"their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Presets for the anchors and margins values of a Control node."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"When active, moving Control nodes changes their anchors instead of their "
+"margins."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Left"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Right"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Right"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Left"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Left"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Top"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Right"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Bottom"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Left Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Right Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "VCenter Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "HCenter Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Full Rect"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Keep Ratio"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Anchors only"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors and Margins"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Game Camera Override\n"
+"Overrides game camera with editor viewport camera."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Game Camera Override\n"
+"No game instance running."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Group Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Ungroup Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Paste Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Warning: Children of a container get their position and size determined only "
+"by their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Reset"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Select Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Drag: Rotate"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+Drag: Move"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Move Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Show a list of all objects at the position clicked\n"
+"(same as Alt+RMB in select mode)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Click to change object's rotation pivot."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Ruler Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle smart snapping."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Smart Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle grid snapping."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Grid Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snapping Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Rotation Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Scale Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap Relative"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Pixel Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Smart Snapping"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Parent"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Sides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Center"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Other Nodes"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock the selected object in place (can't be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock the selected object (can be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Makes sure the object's children are not selectable."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Restores the object's children's ability to be selected."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Skeleton Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Custom Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Always Show Grid"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Helpers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Rulers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Origin"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Viewport"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Group And Lock Icons"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Frame Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Preview Canvas Scale"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Translation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert keys (based on mask)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Auto insert keys when objects are translated, rotated or scaled (based on "
+"mask).\n"
+"Keys are only added to existing tracks, no new tracks will be created.\n"
+"Keys must be inserted manually for the first time."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Auto Insert Key"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Animation Key and Pose Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key (Existing Tracks)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Copy Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Multiply grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Divide grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Add %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Adding %s..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Cannot instantiate multiple nodes without root."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Create Node"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Error instancing scene from %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Default Type"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Drag & drop + Shift : Add node as sibling\n"
+"Drag & drop + Alt : Change node type"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Create Polygon3D"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly (Remove Point)"
+msgstr ""
+
+#: editor/plugins/collision_shape_2d_editor_plugin.cpp
+msgid "Set Handle"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Load Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Restart"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Clear Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Particles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generated Point Count:"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Solid Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Border Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Directed Border Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Capture from Pixel"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Colors"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+msgid "CPUParticles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Mesh"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Node"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 0"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 1"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease In"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease Out"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Smoothstep"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Curve Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Add Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Left Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Toggle Curve Linear Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Hold Shift to edit tangents individually"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right click to add point"
+msgstr ""
+
+#: editor/plugins/gi_probe_editor_plugin.cpp
+msgid "Bake GI Probe"
+msgstr ""
+
+#: editor/plugins/gradient_editor_plugin.cpp
+msgid "Gradient Edited"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item %d"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Items"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item List Editor"
+msgstr ""
+
+#: editor/plugins/light_occluder_2d_editor_plugin.cpp
+msgid "Create Occluder Polygon"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh is empty!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create a Trimesh collision shape."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Trimesh Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "This doesn't work on scene root!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Can't create a single convex collision shape for the scene root."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create a single convex collision shape."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Single Convex Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Can't create multiple convex collision shapes for the scene root."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create any collision shapes."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Multiple Convex Shapes"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Navigation Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Contained Mesh is not of type ArrayMesh."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Unwrap failed, mesh may not be manifold?"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "No mesh to debug."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Model has no UV in this layer"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "MeshInstance lacks a Mesh!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh has not surface to create outlines from!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Could not create outline!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a StaticBody and assigns a polygon-based collision shape to it "
+"automatically.\n"
+"This is the most accurate (but slowest) option for collision detection."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a polygon-based collision shape.\n"
+"This is the most accurate (but slowest) option for collision detection."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Single Convex Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a single convex collision shape.\n"
+"This is the fastest (but least accurate) option for collision detection."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Multiple Convex Collision Siblings"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a polygon-based collision shape.\n"
+"This is a performance middle-ground between the two above options."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh..."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a static outline mesh. The outline mesh will have its normals "
+"flipped automatically.\n"
+"This can be used instead of the SpatialMaterial Grow property when using "
+"that property isn't possible."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV1"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV2"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Unwrap UV2 for Lightmap/AO"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Outline Size:"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Channel Debug"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove item %d?"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid ""
+"Update from existing scene?:\n"
+"%s"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Mesh Library"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove Selected Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import from Scene"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Update from Scene"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and no MultiMesh set in node)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and MultiMesh contains no Mesh)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (not a MeshInstance)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (contains no Mesh resource)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No surface source specified."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no geometry)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no faces)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate Surface"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate MultiMesh"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "X-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Y-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Z-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh Up Axis:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Rotation:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Tilt:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Scale:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate"
+msgstr ""
+
+#: editor/plugins/navigation_polygon_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Convert to CPUParticles"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generating Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generate Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Can only set point into a ParticlesMaterial process material"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generation Time (sec):"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emitter"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Points:"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points+Normal (Directed)"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Volume"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Source: "
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "A processor material of type 'ParticlesMaterial' is required."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generating AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate Visibility AABB"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Point from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Out-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove In-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point to Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Split Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Point in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move In-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Out-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Select Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Shift+Drag: Select Control Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Click: Add Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Left Click: Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Right Click: Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Select Control Points (Shift+Drag)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point (in empty space)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Close Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp
+msgid "Options"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Angles"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Lengths"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Curve Point #"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Point Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve In Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Out Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Path"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Path Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Out-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove In-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/physical_bone_plugin.cpp
+msgid "Move Joint"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"No texture in this polygon.\n"
+"Set a texture to be able to edit UV."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Polygon 2D has internal vertices, so it can no longer be edited in the "
+"viewport."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon & UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Invalid Polygon (need 3 different vertices)"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Add Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint Bone Weights"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Open Polygon 2D UV editor."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon 2D UV Editor"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygons"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Command: Rotate"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift: Move All"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Command: Scale"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Ctrl: Rotate"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Ctrl: Scale"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Rotate Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Scale Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create a custom polygon. Enables custom polygon rendering."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Remove a custom polygon. If none remain, custom polygon rendering is "
+"disabled."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Unpaint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Radius:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Copy Polygon to UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Copy UV to Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Clear UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Settings"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Enable Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Show Grid"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Configure Grid:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones to Polygon"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ERROR: Couldn't load resource!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Add Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Rename Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Resource clipboard is empty!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Paste Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Instance:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Type:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
+msgid "Open in Editor"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Load Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ResourcePreloader"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "AnimationTree has no path set to an AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Path to AnimationPlayer is invalid"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Files"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close and save changes?"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error writing TextFile:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Could not load file at:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving file!"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error importing theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Importing"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "New Text File..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save File As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Can't obtain the script for running."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Script failed reloading, check console for errors."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Script is not in tool mode, will not be able to run."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"To run this script, it must inherit EditorScript and be set to tool mode."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "%s Class Reference"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Previous"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter scripts"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle alphabetical sorting of the method list."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter methods"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Sort"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Up"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Down"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Next script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Previous script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Soft Reload Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Copy Script Path"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Previous"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reload Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+msgid "Run"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Into"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Over"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Break"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Continue"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Keep Debugger Open"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Debug with External Editor"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open Godot online documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search the reference documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to previous edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to next edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Discard"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Debugger"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Results"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Connections to method:"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp
+msgid "Source"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Target"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid ""
+"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "[Ignore]"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Only resources from filesystem can be dropped."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't drop nodes because script '%s' is not used in this scene."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Lookup Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Pick Color"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Convert Case"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Uppercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Lowercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Capitalize"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Syntax Highlighter"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "Bookmarks"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "Go To"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Cut"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Select All"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Delete Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Left"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Right"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Comment"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold/Unfold Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Unfold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Clone Down"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Complete Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Evaluate Selection"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Spaces"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Tabs"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Auto Indent"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Line..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid ""
+"This shader has been modified on on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Shader"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "This skeleton has no bones, create some children Bone2D nodes."
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Create Rest Pose from Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Rest Pose to Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Skeleton2D"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Make Rest Pose (From Bones)"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Bones to Rest Pose"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical bones"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_ik_editor_plugin.cpp
+msgid "Play IK"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Orthogonal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Aborted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "X-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Y-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Z-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Plane Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scaling: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translating: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotating %s degrees."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Keying is disabled (no key inserted)."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Animation Key Inserted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pitch"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Yaw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Objects Drawn"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Material Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Shader Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Surface Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Draw Calls"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Vertices"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "No parent to instance a child at."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "This operation requires a single selected node."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock View Rotation"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Normal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Wireframe"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Overdraw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Unshaded"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Environment"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Information"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View FPS"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Half Resolution"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Audio Listener"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Enable Doppler"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Cinematic Preview"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Not available when using the GLES2 renderer."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Forward"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Backwards"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Up"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Down"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Speed Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Slow Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "XForm Dialog"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Click to toggle between visibility states.\n"
+"\n"
+"Open eye: Gizmo is visible.\n"
+"Closed eye: Gizmo is hidden.\n"
+"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Nodes To Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Drag: Rotate\n"
+"Alt+Drag: Move\n"
+"Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Local Space"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Snap"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Switch Perspective/Orthogonal View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Insert Animation Key"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Toggle Freelook"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Object to Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Dialog..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "1 Viewport"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "4 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Grid"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Settings..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate Snap:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Snap (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Snap (%):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Viewport Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective FOV (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Near:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Far:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Change"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale (ratio):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Type"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pre"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Post"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Nameless gizmo"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Mesh2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Polygon2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "CollisionPolygon2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "LightOccluder2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite is empty!"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Can't convert a sprite using animation frames to mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't replace by mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create collision polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create light occluder."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Simplification: "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Shrink (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Grow (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Update Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Settings:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "No Frames Selected"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add %d Frame(s)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Unable to load images"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "ERROR: Couldn't load frame resource!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Resource clipboard is empty or not a texture!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Paste Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Empty"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation FPS"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "(empty)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animations:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "New Animation"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Speed:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Loop"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animation Frames:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add a Texture from File"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frames from a Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Horizontal:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Vertical:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select/Clear All Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Create Frames from Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "SpriteFrames"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Region Rect"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Margin"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Snap Mode:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: scene/resources/visual_shader.cpp
+msgid "None"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Pixel Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Grid Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Auto Slice"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Offset:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Step:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Sep.:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "TextureRegion"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
+msgid "Remove All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Edit Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme editing menu."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Editor Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create From Current Editor Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Toggle Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Check Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Named Sep."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Submenu"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Many"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled LineEdit"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 3"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Editable Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subtree"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has,Many,Options"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Data Type:"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Style"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Font"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Color"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme File"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Fix Invalid Tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cut Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Line Draw"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Bucket Fill"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Find Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Transpose"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Disable Autotile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Enable Priority"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Filter tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Give a TileSet resource to this TileMap to use its tiles."
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Command+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Pick Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Left"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Right"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Horizontally"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Vertically"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Clear Transform"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Add Texture(s) to TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected Texture from TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Single Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Autotile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Atlas"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Next Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the next shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Previous Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the previous shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Copy bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Erase bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new rectangle."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Rectangle"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete Selected Shape"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Keep polygon inside region Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Enable snap and show grid (configurable via the Inspector)."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Display Tile Names (Hold Alt Key)"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Add or select a texture on the left panel to edit the tiles bound to it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected texture? This will remove all tiles which use it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "You haven't selected a texture to remove."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from scene? This will overwrite all current tiles."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from scene?"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Texture"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "%s file(s) were not added because was already on the list."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Drag handles to edit Rect.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete selected Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select current edited sub-tile.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"LMB: Set bit on.\n"
+"RMB: Set bit off.\n"
+"Shift+LMB: Set wildcard bit.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to use as icon, this will be also used on invalid autotile "
+"bindings.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its priority.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its z index.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Region"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Icon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Clear Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Priority"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "This property can't be changed."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "TileSet"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No VCS addons are available."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Error"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No files added to stage"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "VCS Addon is not initialized"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Version Control System"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Initialize"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Staging area"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Stage Selected"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Stage All"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Status"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View file diffs before committing them to the latest version"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No file diff is active"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect changes in file diff"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Output"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sampler"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set expression"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Resize VisualShader node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Uniform Name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Input Default Port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node to Visual Shader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Node(s) Moved"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Duplicate Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Input Type Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "UniformRef Name Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vertex"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Fragment"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Light"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Create Shader Node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Grayscale function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts HSV vector to RGB equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts RGB vector to HSV equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sepia function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Burn operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Darken operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Difference operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Dodge operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "HardLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Lighten operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Overlay operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Screen operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "SoftLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided scalars are equal, greater or "
+"less."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated scalar if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for all shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Input parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment and light shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for light shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "E constant (2.718282). Represents the base of the natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Epsilon constant (0.00001). Smallest possible scalar number."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Phi constant (1.618034). Golden ratio."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/4 constant (0.785398) or 45 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/2 constant (1.570796) or 90 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi constant (3.141593) or 180 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Tau constant (6.283185) or 360 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sqrt2 constant (1.414214). Square root of 2."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the absolute value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Finds the nearest integer that is greater than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Constrains a value to lie between two further values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in radians to degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-e Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer less than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Computes the fractional part of the argument."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse of the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the greater of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the lesser of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the opposite value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the value of the first parameter raised to the power of the second."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in degrees to radians."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest even integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Clamps the value between 0.0 and 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Extracts the sign of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the truncated value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds scalar to scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts scalar from scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the cubic texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Calculate the outer product of a pair of vectors.\n"
+"\n"
+"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
+"one column) and the second parameter 'r' as a row vector (matrix with one "
+"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix "
+"whose number of rows is the number of components in 'c' and whose number of "
+"columns is the number of components in 'r'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes transform from four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes transform to four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the determinant of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the inverse of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the transpose of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies transform by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes vector from three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes vector to three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the cross product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the distance between two points."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the dot product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the same direction as a reference vector. "
+"The function has three vector parameters : N, the vector to orient, I, the "
+"incident vector, and Nref, the reference vector. If the dot product of I and "
+"Nref is smaller than zero the return value is N. Otherwise -N is returned."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the length of a vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the normalize product of vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the direction of reflection ( a : incident "
+"vector, b : normal vector )."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the vector that points in the direction of refraction."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( vector(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds vector to vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts vector from vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, with custom amount of input and "
+"output ports. This is a direct injection of code into the vertex/fragment/"
+"light function, do not use it to write the function declarations inside."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns falloff based on the dot product of surface normal and view "
+"direction of camera (pass associated inputs to it)."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, which is placed on top of the "
+"resulted shader. You can place various function definitions inside and call "
+"it later in the Expressions. You can also declare varyings, uniforms and "
+"constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "A reference to an existing uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "VisualShader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Edit Visual Property"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Mode Changed"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Runnable"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Delete preset '%s'?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"Export templates seem to be missing or invalid."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"This might be due to a configuration issue in the export preset or your "
+"export settings."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Release"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Exporting All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "The given export path doesn't exist:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing/corrupted:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Presets"
+msgstr ""
+
+#: editor/project_export.cpp editor/project_settings_editor.cpp
+msgid "Add..."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"If checked, the preset will be available for use in one-click deploy.\n"
+"Only one preset per platform may be marked as runnable."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Path"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export all resources in the project"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected scenes (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected resources (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources to export:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to export non-resource files/folders\n"
+"(comma-separated, e.g: *.json, *.txt, docs/*)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to exclude files/folders from project\n"
+"(comma-separated, e.g: *.json, *.txt, docs/*)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Features"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Custom (comma-separated):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Feature List:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Text"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Compiled"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Encrypted (Provide Key Below)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Invalid Encryption Key (must be 64 characters long)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Encryption Key (256-bits as hex):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export PCK/Zip"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Project"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export mode?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export All"
+msgstr ""
+
+#: editor/project_export.cpp editor/project_manager.cpp
+msgid "ZIP File"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Godot Game Pack"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export With Debug"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The path specified doesn't exist."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error opening package file (it's not in ZIP format)."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose an empty folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose a \"project.godot\" or \".zip\" file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "This directory already contains a Godot project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Game Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Imported Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid Project Name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "There is already a folder in this path with the specified name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "It would be a good idea to name your project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid project path (changed anything?)."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Couldn't load project.godot in project path (error %d). It may be missing or "
+"corrupted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't edit project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Rename Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import Existing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install Project:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Name:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Installation Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 3.0"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Not supported by your GPU drivers."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Higher visual quality\n"
+"All features available\n"
+"Incompatible with older hardware\n"
+"Not recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 2.0"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Lower visual quality\n"
+"Some features not available\n"
+"Works on most hardware\n"
+"Recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer can be changed later, but scenes may need to be adjusted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Unnamed Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't open project at '%s'."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to open more than one project?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file does not specify the version of Godot "
+"through which it was created.\n"
+"\n"
+"%s\n"
+"\n"
+"If you proceed with opening it, it will be converted to Godot's current "
+"configuration file format.\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file was generated by an older engine "
+"version, and needs to be converted for this version:\n"
+"\n"
+"%s\n"
+"\n"
+"Do you want to convert it?\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The project settings were created by a newer engine version, whose settings "
+"are not compatible with this version."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: no main scene defined.\n"
+"Please edit the project and set the main scene in the Project Settings under "
+"the \"Application\" category."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: Assets need to be imported.\n"
+"Please edit the project to trigger the initial import."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to run %d projects at once?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove %d projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove this project from the list?\n"
+"The project folder's contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Language changed.\n"
+"The interface will update after restarting the editor or project manager."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Are you sure to scan %s folders for existing Godot projects?\n"
+"This could take a while."
+msgstr ""
+
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
+#: editor/project_manager.cpp
+msgid "Project Manager"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Projects"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Select a Folder to Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Remove Missing"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Templates"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Restart Now"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't run project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"You currently don't have any projects.\n"
+"Would you like to explore official example projects in the Asset Library?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Key "
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "An action with the name '%s' already exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Rename Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Action deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "All Devices"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Press a Key..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 1"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 2"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Axis Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Global Property"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Select a setting item first!"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "No property '%s' exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Setting '%s' is internal, and it can't be deleted."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Delete Item"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Error saving settings."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Settings saved OK."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Moved Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override for Feature"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Remapped Path"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resource Remap Add Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Resource Remap Language"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap Option"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter Mode"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Project Settings (project.godot)"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "General"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override For..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "The editor must be restarted for changes to take effect."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Input Map"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Localization"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resources:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps by Locale:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locale"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show All Locales"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show Selected Locales Only"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Filter mode:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "AutoLoad"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Preset..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Zero"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing In-Out"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing Out-In"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "File..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Dir..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Assign"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Select Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Error loading file: Not a resource!"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Pick a Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Bit %d, val %d."
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Property"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Virtual Method"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Method"
+msgstr ""
+
+#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Batch Rename"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Replace:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Use Regular Expressions"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Advanced Options"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Substitute"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node's parent name, if available"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node type"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Current scene name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Root node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Sequential integer counter.\n"
+"Compare counter options."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Per-level Counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "If set, the counter restarts for each group of child nodes."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Initial value for the counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Step"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Amount by which counter is incremented for each node"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Padding"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Minimum number of digits for the counter.\n"
+"Missing digits are padded with leading zeros."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Post-Process"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Keep"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "PascalCase to snake_case"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "snake_case to PascalCase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Case"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Lowercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Uppercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Reset"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Regular Expression Error:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "At character %s"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent Node"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Reparent Location (Select new Parent):"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Keep Global Transform"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Run Mode:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Current Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene Arguments:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Scene Run Settings"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "No parent to instance the scenes at."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error loading scene from %s"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot instance the scene '%s' because the current scene exists within one "
+"of its nodes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Scene(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Replace with Branch Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Child Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Detach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on the tree root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Node In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Nodes In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Duplicate Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Node must belong to the edited scene to become root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instantiated scenes can't become root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make node as Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete %d nodes and any children?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete %d nodes?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete the root node \"%s\"?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete node \"%s\" and its children?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete node \"%s\"?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can not perform with the root node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on instanced scenes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Save New Scene As..."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Disabling \"editable_instance\" will cause all properties of the node to be "
+"reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Enabling \"Load As Placeholder\" will disable \"Editable Children\" and "
+"cause all properties of the node to be reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "New Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Create Root Node:"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "2D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "3D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "User Interface"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Other Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes from a foreign scene!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes the current scene inherits from!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remove Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Couldn't save new scene. Likely dependencies (instances) couldn't be "
+"satisfied."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error saving scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error duplicating scene to save it."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Sub-Resources"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Editable Children"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Load As Placeholder"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Open Documentation"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot attach a script: there are no languages registered.\n"
+"This is probably because this editor was built with all language modules "
+"disabled."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add Child Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Expand/Collapse All"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change Type"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Merge From Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Save Branch as Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Copy Node Path"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete (No Confirm)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add/Create a New Node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Instance a scene file as a Node. Creates an inherited scene if no root node "
+"exists."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach a new or existing script to the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Detach the script from the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remote"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance? (No Undo!)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visible"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Unlock Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Button Group"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "(Connecting From)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node configuration warning:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s) and %s group(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is in %s group(s).\n"
+"Click to show groups dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Open Script:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is locked.\n"
+"Click to unlock it."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Children are not selectable.\n"
+"Click to make selectable."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visibility"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"AnimationPlayer is pinned.\n"
+"Click to unpin."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Invalid node name, the following characters are not allowed:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Rename Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Scene Tree (Nodes):"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node Configuration Warning!"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Select a Node"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Filename is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is not local."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid base path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "A directory with the same name exists."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "File does not exist."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid extension."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Wrong extension chosen."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading template '%s'"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error - Could not create script in filesystem."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading script from %s"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "N/A"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script / Choose Location"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "File exists, it will be reused."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid class name."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid inherited parent name or path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Script path/name is valid."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in script (into scene file)."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will create a new script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will load an existing script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Script file already exists."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Class Name:"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Template:"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in Script:"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Attach Node Script"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Remote "
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Bytes:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Warning:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Error:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Error"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Error:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Source"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Source:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Source:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Trace"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Errors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Child process connected."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Copy Error"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Video RAM"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Skip Breakpoints"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Previous Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Next Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Frames"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Profiler"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Network Profiler"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitor"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Value"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Pick one or more items from the list to display the graph."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "List of Video Memory Usage by Resource:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Total:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Resource Path"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Type"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Format"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Usage"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Misc"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control Type:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Live Edit Root:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Set From Tree"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Export measures as CSV"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Erase Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Restore Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Change Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Shortcuts"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Binding"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Light Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change AudioStreamPlayer3D Emission Angle"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera FOV"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera Size"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Notifier AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Particles AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Probe Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Sphere Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Box Shape Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Ray Shape Length"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Height"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Inner Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Outer Radius"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select the dynamic library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select dependencies of the library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Remove current entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Double click to create a new entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform:"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dynamic Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Add an architecture entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "GDNativeLibrary"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Enabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Disabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Libraries: "
+msgstr ""
+
+#: modules/gdnative/register_types.cpp
+msgid "GDNative"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Step argument is zero!"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not a script with an instance"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a script"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a resource file"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (missing @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (can't load script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (invalid script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary (invalid subclasses)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Object can't provide a length."
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Plane:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Floor:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Delete Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paste Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paint"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Grid Map"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Snap View"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Disabled"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Above"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Below"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit X Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Y Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Z Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Clear Rotation"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Paste Selects"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clear Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Settings"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Pick Distance:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Filter meshes"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
+#: modules/mono/csharp_script.cpp
+msgid "Class name can't be a reserved keyword"
+msgstr ""
+
+#: modules/mono/mono_gd/gd_mono_utils.cpp
+msgid "End of inner exception stack trace"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Bake NavMesh"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Clear the navigation mesh."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Setting up Configuration..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Calculating grid size..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Marking walkable triangles..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Constructing compact heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Eroding walkable area..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Partitioning..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating contours..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating polymesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Converting to native navigation mesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Navigation Mesh Generator Setup:"
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Parsing Geometry..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Done!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"A node yielded without working memory, please read the docs on how to yield "
+"properly!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Node yielded, but did not return a function state in the first working "
+"memory."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Return value must be assigned to first element of node working memory! Fix "
+"your node please."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Node returned an invalid sequence output: "
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Found sequence bit but not the node in the stack, report bug!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Stack overflow with stack depth: "
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Signal Arguments"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument name"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Default Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Input Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Output Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Variables:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Signals:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name is not a valid identifier:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name already in use by another func/var/signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete input port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Input Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Output Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Duplicate VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Preload Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node(s) From Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid ""
+"Can't drop properties because script '%s' is not used in this scene.\n"
+"Drop holding 'Shift' to just copy the signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Getter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Setter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Move Node(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Disconnect Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Data"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Script already has function '%s'"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Input Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Resize Comment"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't copy the function node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't create function with a function node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't create function of nodes from nodes of multiple functions."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select at least one node with sequence port."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Try to only have one sequence input in selection."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Variable:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Make Tool:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Members:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Nodes..."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function..."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "function_name"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select or create a function to edit its graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete Selected"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Find Node Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Copy Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Cut Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Make Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Refresh Graph"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit Member"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Input type not iterable: "
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid: "
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name."
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Base object is not a Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Path does not lead Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name '%s' in node %s."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid argument of type: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid arguments: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableGet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableSet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Custom node has no _step() method, can't process graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ""
+"Invalid return value from _step(), must be integer (seq out), or string "
+"(error)."
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search VisualScript"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Set %s"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package name is missing."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package segments must be of non-zero length."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' is not allowed in Android application package names."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "A digit cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The package must have at least one '.' separator."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Select device from the list"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find the 'apksigner' tool."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Debug keystore not configured in the Editor Settings nor in the preset."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Release keystore incorrectly configured in the export preset."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'platform-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid public key for APK expansion."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid package name:"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" "
+"project setting (changed in Godot 3.2.2).\n"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "\"Use Custom Build\" must be enabled to use the plugins."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR"
+"\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid filename! Android App Bundle requires the *.aab extension."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "APK Expansion not compatible with Android App Bundle."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid filename! Android APK requires the *.apk extension."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Trying to build from a custom built template, but no version info for it "
+"exists. Please reinstall from the 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build version mismatch:\n"
+" Template installed: %s\n"
+" Godot Version: %s\n"
+"Please reinstall Android build template from 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Building Android Project (gradle)"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Building of Android project failed, check output for the error.\n"
+"Alternatively visit docs.godotengine.org for Android build documentation."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Moving output"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Unable to copy and rename export file, check gradle project directory for "
+"outputs."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier is missing."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The character '%s' is not allowed in Identifier."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "App Store Team ID not specified - cannot configure the project."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Invalid Identifier:"
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Required icon is not specified in the preset."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Stop HTTP Server"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run in Browser"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run exported HTML in the system's default browser."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not write file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not open template for export:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Invalid export template:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read custom HTML shell:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read boot splash image file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Using default boot splash image."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package short name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package unique name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package publisher display name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid product GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid publisher GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid background color."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid Store Logo image dimensions (should be 50x50)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid splash screen image dimensions (should be 620x300)."
+msgstr ""
+
+#: scene/2d/animated_sprite.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite to display frames."
+msgstr ""
+
+#: scene/2d/canvas_modulate.cpp
+msgid ""
+"Only one visible CanvasModulate is allowed per scene (or set of instanced "
+"scenes). The first created one will work, while the rest will be ignored."
+msgstr ""
+
+#: scene/2d/collision_object_2d.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
+"define its shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid ""
+"CollisionPolygon2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "An empty CollisionPolygon2D has no effect on collision."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"CollisionShape2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"A shape must be provided for CollisionShape2D to function. Please create a "
+"shape resource for it!"
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"Polygon-based shapes are not meant be used nor edited directly through the "
+"CollisionShape2D node. Please use the CollisionPolygon2D node instead."
+msgstr ""
+
+#: scene/2d/cpu_particles_2d.cpp
+msgid ""
+"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A and Node B must be PhysicsBody2Ds"
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A must be a PhysicsBody2D"
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node B must be a PhysicsBody2D"
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Joint is not connected to two PhysicsBody2Ds"
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A and Node B must be different PhysicsBody2Ds"
+msgstr ""
+
+#: scene/2d/light_2d.cpp
+msgid ""
+"A texture with the shape of the light must be supplied to the \"Texture\" "
+"property."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid ""
+"An occluder polygon must be set (or drawn) for this occluder to take effect."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"A NavigationPolygon resource must be set or created for this node to work. "
+"Please set a property or draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"NavigationPolygonInstance must be a child or grandchild to a Navigation2D "
+"node. It only provides navigation data."
+msgstr ""
+
+#: scene/2d/parallax_layer.cpp
+msgid ""
+"ParallaxLayer node only works when set as child of a ParallaxBackground node."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles2D node instead. You can use the \"Convert to "
+"CPUParticles\" option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
+msgid ""
+"A material to process the particles is not assigned, so no behavior is "
+"imprinted."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"Particles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/path_2d.cpp
+msgid "PathFollow2D only works when set as a child of a Path2D node."
+msgstr ""
+
+#: scene/2d/physics_body_2d.cpp
+msgid ""
+"Size changes to RigidBody2D (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/2d/remote_transform_2d.cpp
+msgid "Path property must point to a valid Node2D node to work."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "This Bone2D chain should end at a Skeleton2D node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid ""
+"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
+msgstr ""
+
+#: scene/2d/tile_map.cpp
+msgid ""
+"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes "
+"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
+"KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/visibility_notifier_2d.cpp
+msgid ""
+"VisibilityEnabler2D works best when used with the edited scene root directly "
+"as parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRCamera must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRController must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The controller ID must not be 0 or this controller won't be bound to an "
+"actual controller."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRAnchor must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The anchor ID must not be 0 or this anchor won't be bound to an actual "
+"anchor."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVROrigin requires an ARVRCamera child node."
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Finding meshes and lights"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Preparing geometry (%d/%d)"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Preparing environment"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Generating capture"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Done"
+msgstr ""
+
+#: scene/3d/collision_object.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape or CollisionPolygon as a child to define "
+"its shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid ""
+"CollisionPolygon only serves to provide a collision shape to a "
+"CollisionObject derived node. Please only use it as a child of Area, "
+"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid "An empty CollisionPolygon has no effect on collision."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"CollisionShape only serves to provide a collision shape to a CollisionObject "
+"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
+"KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"A shape must be provided for CollisionShape to function. Please create a "
+"shape resource for it."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"Plane shapes don't work well and will be removed in future versions. Please "
+"don't use them."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"ConcavePolygonShape doesn't support RigidBody in another mode than static."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid "Nothing is visible because no mesh has been assigned."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid ""
+"CPUParticles animation requires the usage of a SpatialMaterial whose "
+"Billboard Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Plotting Meshes"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid ""
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
+msgstr ""
+
+#: scene/3d/light.cpp
+msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
+msgstr ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid "A NavigationMesh resource must be set or created for this node to work."
+msgstr ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid ""
+"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
+"It only provides navigation data."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
+"\" option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Nothing is visible because meshes have not been assigned to draw passes."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Particles animation requires the usage of a SpatialMaterial whose Billboard "
+"Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid "PathFollow only works when set as a child of a Path node."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid ""
+"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
+"parent Path's Curve resource."
+msgstr ""
+
+#: scene/3d/physics_body.cpp
+msgid ""
+"Size changes to RigidBody (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A and Node B must be PhysicsBodies"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A must be a PhysicsBody"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node B must be a PhysicsBody"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Joint is not connected to any PhysicsBodies"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A and Node B must be different PhysicsBodies"
+msgstr ""
+
+#: scene/3d/remote_transform.cpp
+msgid ""
+"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
+"derived node to work."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid "This body will be ignored until you set a mesh."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid ""
+"Size changes to SoftBody will be overridden by the physics engine when "
+"running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/sprite_3d.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite3D to display frames."
+msgstr ""
+
+#: scene/3d/vehicle_body.cpp
+msgid ""
+"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use "
+"it as a child of a VehicleBody."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"WorldEnvironment requires its \"Environment\" property to contain an "
+"Environment to have a visible effect."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set "
+"this environment's Background Mode to Canvas (for 2D scenes)."
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "On BlendTree node '%s', animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "Animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "In node '%s', invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Nothing connected to input '%s' of node '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "No root AnimationNode for the graph is set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path to an AnimationPlayer node containing animations is not set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "The AnimationPlayer root node is not a valid node."
+msgstr ""
+
+#: scene/animation/animation_tree_player.cpp
+msgid "This node has been deprecated. Use AnimationTree instead."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid ""
+"Color: #%s\n"
+"LMB: Set color\n"
+"RMB: Remove preset"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Pick a color from the editor window."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "HSV"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Raw"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Switch between hexadecimal and code values."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Add current color as a preset."
+msgstr ""
+
+#: scene/gui/container.cpp
+msgid ""
+"Container by itself serves no purpose unless a script configures its "
+"children placement behavior.\n"
+"If you don't intend to add a script, use a plain Control node instead."
+msgstr ""
+
+#: scene/gui/control.cpp
+msgid ""
+"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
+"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Alert!"
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Please Confirm..."
+msgstr ""
+
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
+#: scene/gui/popup.cpp
+msgid ""
+"Popups will hide by default unless you call popup() or any of the popup*() "
+"functions. Making them visible for editing is fine, but they will hide upon "
+"running."
+msgstr ""
+
+#: scene/gui/range.cpp
+msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
+msgstr ""
+
+#: scene/gui/scroll_container.cpp
+msgid ""
+"ScrollContainer is intended to work with a single child control.\n"
+"Use a container as child (VBox, HBox, etc.), or a Control and set the custom "
+"minimum size manually."
+msgstr ""
+
+#: scene/gui/tree.cpp
+msgid "(Other)"
+msgstr ""
+
+#: scene/main/scene_tree.cpp
+msgid ""
+"Default Environment as specified in Project Settings (Rendering -> "
+"Environment -> Default Environment) could not be loaded."
+msgstr ""
+
+#: scene/main/viewport.cpp
+msgid ""
+"This viewport is not set as render target. If you intend for it to display "
+"its contents directly to the screen, make it a child of a Control so it can "
+"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
+"texture to some node for display."
+msgstr ""
+
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid source for preview."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid source for shader."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to uniform."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Varyings can only be assigned in vertex function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Constants cannot be modified."
+msgstr ""
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index d0921e2a61..141f2cd58f 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -1,6 +1,6 @@
# Catalan translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# BennyBeat <bennybeat@gmail.com>, 2017.
# Javier Ocampos <xavier.ocampos@gmail.com>, 2018.
@@ -655,7 +655,7 @@ msgstr "Seleccioneu les Pistes a Copiar"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Copiar"
@@ -1871,8 +1871,8 @@ msgid "Open a File or Directory"
msgstr "Obre un Fitxer o Directori"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Desa"
@@ -1963,10 +1963,6 @@ msgstr "Vista prèvia:"
msgid "File:"
msgstr "Fitxer:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Cal utilitzar una extensió vàlida."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Escaneja Fonts"
@@ -2400,6 +2396,10 @@ msgid "There is no defined scene to run."
msgstr "No s'ha definit cap escena per executar."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "No s'ha pogut començar el subprocés!"
@@ -2443,19 +2443,6 @@ msgstr "Es requereix un node arrel per a guardar l'escena."
msgid "Save Scene As..."
msgstr "Anomena i Desa l'Escena..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "No"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Sí"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-"Aquesta escena no s'ha desat mai encara. Voleu desar-la abans d'executar-la?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Aquesta operació no pot dur-se a terme sense cap escena."
@@ -2508,6 +2495,10 @@ msgid "Quit"
msgstr "Surt"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Sí"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Voleu Sortir de l'editor?"
@@ -2556,7 +2547,8 @@ msgstr ""
"configuració."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"No s'ha pogut trobar el camp d'Script per al complement a: 'res: // addons /"
"%s'."
@@ -2996,14 +2988,6 @@ msgid "Help"
msgstr "Ajuda"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Cerca"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentació en línia"
@@ -3175,6 +3159,25 @@ msgid "Open & Run a Script"
msgstr "Obre i Executa un Script"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"El disc conté versions més recents dels fitxer següents. \n"
+"Quina acció voleu seguir?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Torna a Carregar"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Torna a Desar"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Nou Heretat"
@@ -3388,7 +3391,7 @@ msgstr "Fes-lo Únic"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Enganxa"
@@ -3950,8 +3953,19 @@ msgid "Searching..."
msgstr "Cercant..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Cerca completa"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d coincidències."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d coincidències."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d coincidències."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4091,6 +4105,21 @@ msgstr ""
msgid "Saving..."
msgstr "Desant..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Mode de selecció"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importa"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Carrega Valors predeterminats"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Fitxers"
@@ -5073,7 +5102,8 @@ msgid "Got:"
msgstr "Rebut:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Ha fallat la comprovació del hash sha256"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5182,7 +5212,6 @@ msgid "Sort:"
msgstr "Ordena:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Categoria:"
@@ -5211,10 +5240,10 @@ msgid "Assets ZIP File"
msgstr "Arxiu ZIP d'Actius"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"No es pot determinar un camí per desar les imatges corresponents als "
"lightmaps.\n"
@@ -5236,9 +5265,29 @@ msgstr ""
"permisos d'escriptura."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Precalcular Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Seleccioneu un Fitxer de Plantilla"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6376,6 +6425,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Només es poden establir punts en materials de procés ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Convertir a ParticulesCPU"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Temps de generació (s):"
@@ -6440,10 +6494,6 @@ msgstr "Generant AABB"
msgid "Generate Visibility AABB"
msgstr "Genera un AABB de Visibilitat"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Genera AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Elimina un Punt de la Corba"
@@ -7048,6 +7098,14 @@ msgstr "Tanca la Documentació"
msgid "Run"
msgstr "Executar"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Cerca"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Pas a Pas (per instruccions)"
@@ -7101,16 +7159,6 @@ msgstr ""
"El disc conté versions més recents dels fitxer següents. \n"
"Quina acció voleu seguir?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Torna a Carregar"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Torna a Desar"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Depurador"
@@ -7209,8 +7257,8 @@ msgstr "Punts d’interrupció"
msgid "Go To"
msgstr "Anar a"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Talla"
@@ -7443,6 +7491,11 @@ msgid "Yaw"
msgstr "Guinyada"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Mida: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objectes Dibuixats"
@@ -8764,11 +8817,6 @@ msgid "Error"
msgstr "Error"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "No commit message was provided"
-msgstr "Manca Nom"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "No hi ha fitxers afegits a l'escenari"
@@ -8835,11 +8883,6 @@ msgstr "Desa-ho Tot"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Add a commit message"
-msgstr "Afegir un missatge de commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Commit Changes"
msgstr "Sincronitzar Canvis en Scripts"
@@ -10279,6 +10322,11 @@ msgstr "Projecte"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Loading, please wait..."
+msgstr "S'estan buscant rèpliques..."
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Last Modified"
msgstr "Última modificació"
@@ -10651,6 +10699,11 @@ msgstr "Càrrega Automàtica"
msgid "Plugins"
msgstr "Connectors"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Carrega Valors predeterminats"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Configuració..."
@@ -10912,6 +10965,16 @@ msgstr "Instancia una Escena Filla"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "No es pot operar en Nodes d'una escena externa!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Enganxa els Nodes"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Detach Script"
msgstr "Adjunta-li un Script"
@@ -11046,6 +11109,11 @@ msgid "Attach Script"
msgstr "Adjunta-li un Script"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Talla els Nodes"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Elimina els Nodes"
@@ -11889,6 +11957,39 @@ msgstr "Filtrar malles"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "Genera AABB"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Direccions"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "Sagnia Dreta"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Post-Processat"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "S'està traçant l'Il·luminació:"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "El nom de la classe no pot ser una paraula clau reservada"
@@ -12431,14 +12532,17 @@ msgid "Select device from the list"
msgstr "Selecciona un dispositiu de la llista"
#: platform/android/export/export.cpp
-#, fuzzy
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "L'executable ADB no està configurat a la configuració de l'editor."
+msgid "Unable to find the 'apksigner' tool."
+msgstr ""
#: platform/android/export/export.cpp
#, fuzzy
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK Jarsigner no està configurat en la configuració de l'editor."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"El projecte Android no està instal·lat per a la compilació. Instal·leu-lo "
+"des del menú Editor."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12450,14 +12554,14 @@ msgstr ""
#: platform/android/export/export.cpp
#, fuzzy
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"La compilació personalitzada requereix un camí d'Android SDK vàlid en la "
-"configuració de l'editor."
+"El camí de l'SDK d'Android no és vàlid per a la compilació personalitzada en "
+"la configuració de l'editor."
#: platform/android/export/export.cpp
#, fuzzy
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
"El camí de l'SDK d'Android no és vàlid per a la compilació personalitzada en "
"la configuració de l'editor."
@@ -12467,13 +12571,23 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
#, fuzzy
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"El camí de l'SDK d'Android no és vàlid per a la compilació personalitzada en "
+"la configuració de l'editor."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
-"El projecte Android no està instal·lat per a la compilació. Instal·leu-lo "
-"des del menú Editor."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12732,6 +12846,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Un CollisionPolygon2D buit no té cap efecte en la col·lisió."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12940,28 +13062,32 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "El node ARVROrigin requreix un node Fill del tipus ARVRCamera"
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Temps restant: %d:%02d s)"
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "Analitzant la Geometria..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "S'estàn traçant les Malles: "
+#, fuzzy
+msgid "Preparing environment"
+msgstr "Mostra l'Entorn"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "S'està traçant l'Il·luminació:"
+#, fuzzy
+msgid "Generating capture"
+msgstr "S'estan generant els Lightmaps"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "S'està finalitzant el Traçat"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "S'estan generant els Lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Il·luminant les Malles: "
+msgid "Done"
+msgstr "Fet"
#: scene/3d/collision_object.cpp
#, fuzzy
@@ -13037,6 +13163,10 @@ msgid "Plotting Meshes"
msgstr "S'estàn traçant les Malles"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "S'està finalitzant el Traçat"
+
+#: scene/3d/gi_probe.cpp
#, fuzzy
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
@@ -13045,11 +13175,6 @@ msgstr ""
"Les GIProbes no estan suportades pel controlador de vídeo GLES2.\n"
"Utilitzeu un BakedLightmap en el seu lloc."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-
#: scene/3d/light.cpp
#, fuzzy
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
@@ -13292,6 +13417,15 @@ msgstr "Ep!"
msgid "Please Confirm..."
msgstr "Confirmeu..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Cal utilitzar una extensió vàlida."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "Activar Ajustament"
+
#: scene/gui/popup.cpp
#, fuzzy
msgid ""
@@ -13348,6 +13482,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Font no vàlida pel Shader."
@@ -13377,6 +13517,52 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Les constants no es poden modificar."
+#~ msgid "No"
+#~ msgstr "No"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr ""
+#~ "Aquesta escena no s'ha desat mai encara. Voleu desar-la abans d'executar-"
+#~ "la?"
+
+#, fuzzy
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "L'executable ADB no està configurat a la configuració de l'editor."
+
+#, fuzzy
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr ""
+#~ "OpenJDK Jarsigner no està configurat en la configuració de l'editor."
+
+#, fuzzy
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "La compilació personalitzada requereix un camí d'Android SDK vàlid en la "
+#~ "configuració de l'editor."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Temps restant: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "S'estàn traçant les Malles: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Il·luminant les Malles: "
+
+#~ msgid "Search complete"
+#~ msgstr "Cerca completa"
+
+#, fuzzy
+#~ msgid "No commit message was provided"
+#~ msgstr "Manca Nom"
+
+#, fuzzy
+#~ msgid "Add a commit message"
+#~ msgstr "Afegir un missatge de commit"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Ja hi existex un fitxer o directori amb aquest nom."
@@ -13706,9 +13892,6 @@ msgstr "Les constants no es poden modificar."
#~ msgid "Failed to save solution."
#~ msgstr "No s'ha pogut desar la solució."
-#~ msgid "Done"
-#~ msgstr "Fet"
-
#~ msgid "Failed to create C# project."
#~ msgstr "No s'ha pogut crear el projecte en C#."
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 4dd0050197..2c21fc0e63 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -1,6 +1,6 @@
# Czech translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Fadex <vitekpaulik@gmail.com>, 2017.
# Jan 'spl!te' Kondelík <j.kondelik@centrum.cz>, 2016, 2018.
@@ -9,26 +9,26 @@
# Luděk Novotný <gladosicek@gmail.com>, 2016, 2018.
# Martin Novák <maidx@seznam.cz>, 2017, 2019.
# zxey <r.hozak@seznam.cz>, 2018.
-# Vojtěch Šamla <auzkok@seznam.cz>, 2018, 2019, 2020.
+# Vojtěch Šamla <auzkok@seznam.cz>, 2018, 2019, 2020, 2021.
# Peeter Angelo <contact@peeterangelo.com>, 2019.
-# VojtechBrezina <vojta.brezina@gmail.com>, 2019.
+# VojtechBrezina <vojta.brezina@gmail.com>, 2019, 2021.
# Garrom Orc Shaman <garromorcshaman@gmail.com>, 2019.
# David HusiÄka <davidek251@seznam.cz>, 2019.
# LuboÅ¡ NeÄas <lubosnecas506@seznam.cz>, 2019.
# David Kubeš <kubesdavid@email.cz>, 2019.
-# Emil Jiří Tywoniak <emil.tywoniak@gmail.com>, 2020.
+# Emil Jiří Tywoniak <emil.tywoniak@gmail.com>, 2020, 2021.
# Filip Vincůrek <vincurek.f@gmail.com>, 2020.
# Ondrej Pavelka <ondrej.pavelka@outlook.com>, 2020.
# Zbyněk <zbynek.fiala@gmail.com>, 2020.
# Daniel Kříž <Daniel.kriz@protonmail.com>, 2020.
# VladimirBlazek <vblazek042@gmail.com>, 2020.
# kubajz22 <til.jakubesko@seznam.cz>, 2020.
-# Václav Blažej <vaclavblazej@seznam.cz>, 2020.
+# Václav Blažej <vaclavblazej@seznam.cz>, 2020, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-29 08:28+0000\n"
+"PO-Revision-Date: 2021-03-08 15:33+0000\n"
"Last-Translator: Václav Blažej <vaclavblazej@seznam.cz>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/"
"cs/>\n"
@@ -37,7 +37,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -186,11 +186,11 @@ msgstr "Animace: ZmÄ›na Äasu klíÄových snímků"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Transition"
-msgstr "Animace: změna přechodů"
+msgstr "Animace: Změna přechodů"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Transform"
-msgstr "Animace: změna transformací"
+msgstr "Animace: Změna transformací"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Value"
@@ -198,7 +198,7 @@ msgstr "Animace: ZmÄ›nit hodnotu klíÄových snímků"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Call"
-msgstr "Animace: změna volání"
+msgstr "Animace: Změna více volání"
#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
@@ -292,7 +292,7 @@ msgstr "ÄŒas (s): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
-msgstr "Přepínací stopa povolena"
+msgstr "Povolit stopu"
#: editor/animation_track_editor.cpp
msgid "Continuous"
@@ -666,7 +666,7 @@ msgstr "Vybrat stopy ke kopírování"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopírovat"
@@ -676,7 +676,7 @@ msgstr "Vybrat vše/nic"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
-msgstr "Přidat klip audio stopy"
+msgstr "Přidat audio klip"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
@@ -1299,7 +1299,7 @@ msgstr "Přepnout bypass efektů na zvukové sběrnice"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
-msgstr "Vybrat přenos zvukové sběrnice"
+msgstr "Vybrat cíl zvukové sběrnice"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
@@ -1867,8 +1867,8 @@ msgid "Open a File or Directory"
msgstr "Otevřít soubor nebo složku"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Uložit"
@@ -1959,10 +1959,6 @@ msgstr "Náhled:"
msgid "File:"
msgstr "Soubor:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Je nutné použít platnou příponu."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Sken zdrojů"
@@ -2397,6 +2393,10 @@ msgid "There is no defined scene to run."
msgstr "Neexistuje žádná scéna pro spuštění."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Uložit scénu před spuštěním..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Nelze spustit podproces!"
@@ -2440,18 +2440,6 @@ msgstr "Pro uložení scény je vyžadován kořenový uzel."
msgid "Save Scene As..."
msgstr "Uložit scénu jako..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Ne"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Ano"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Tato scéna nebyla nikdy uložena. Uložit před spuštěním?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Tato operace nemůže být provedena bez scény."
@@ -2489,7 +2477,7 @@ msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
-"Tato scéna obsahuje neuložené změny.\n"
+"Aktuální scéna obsahuje neuložené změny.\n"
"PÅ™esto znovu naÄíst? Tuto akci nelze vrátit zpÄ›t."
#: editor/editor_node.cpp
@@ -2501,6 +2489,10 @@ msgid "Quit"
msgstr "UkonÄit"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Ano"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "UkonÄit editor?"
@@ -2546,9 +2538,8 @@ msgstr ""
"Nelze povolit rozšiřující plugin: '%s' parsování konfigurace se nezdařilo."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
-"Nelze najít záznam skriptu pro rozšiřující plugin v: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "Nelze najít záznam skriptu pro rozšiřující plugin v: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2975,14 +2966,6 @@ msgid "Help"
msgstr "Nápověda"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Hledat"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online dokumentace"
@@ -3147,6 +3130,24 @@ msgid "Open & Run a Script"
msgstr "Otevřít a spustit skript"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Následující soubory mají novější verzi na disku.\n"
+"Jaká akce se má vykonat?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Znovu naÄíst"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Znovu uložit"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Nové zděděné"
@@ -3357,7 +3358,7 @@ msgstr "Vytvořit unikátní"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Vložit"
@@ -3717,6 +3718,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Následující soubory nebo složky jsou v konfliktu s položkami v cílovém "
+"umístění '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Přejete si je přepsat?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3909,8 +3916,16 @@ msgid "Searching..."
msgstr "Hledám..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Vyhledávání dokonÄeno"
+msgid "%d match in %d file."
+msgstr "%d shoda v %d souboru."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d shod v %d souboru."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d shod v %d souborech."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4046,6 +4061,21 @@ msgstr "Vrátili jste objekt, který dědí z Node metodou `post_import()`?"
msgid "Saving..."
msgstr "Ukládání..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Režim výběru"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Import"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "NaÄíst výchozí"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d souborů"
@@ -5008,8 +5038,8 @@ msgid "Got:"
msgstr "Staženo:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Neúspěšná kontrola sha256 hashe"
+msgid "Failed SHA-256 hash check"
+msgstr "Neúspěšná kontrola SHA-256 hashe"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5112,7 +5142,6 @@ msgid "Sort:"
msgstr "Řadit podle:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategorie:"
@@ -5141,10 +5170,10 @@ msgid "Assets ZIP File"
msgstr "ZIP soubor asetů"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Nelze urÄit cestu uložení pro svÄ›telnou mapu obrázku.\n"
"Uložte scénu (obrázky se uloží do stejného adresáře) nebo vyberte cestu pro "
@@ -5165,9 +5194,32 @@ msgstr ""
"Ätení."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Nebylo možné urÄit velikost svÄ›telné mapy. Maximální velikost je příliÅ¡ malá?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Některé sítě jsou neplatné. Ujistěte se, že hodnoty kanálu UV2 jsou ve "
+"Ätvercové oblasti [0.0, 1.0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Godot byl sestaven bez podpory ray tracingu, světelné mapy nelze zapéct."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Zapéct lightmapy"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Vybrat soubor pro zapeÄení svÄ›telných map:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6260,6 +6312,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Bod lze vložit pouze do process materiálu ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Převést na CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Čas generování (sec):"
@@ -6320,10 +6376,6 @@ msgstr "Generování AABB"
msgid "Generate Visibility AABB"
msgstr "Generovat viditelnostní AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Vygenerovat AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Odstranit bod z křivky"
@@ -6911,6 +6963,14 @@ msgstr "Zavřít dokumentaci"
msgid "Run"
msgstr "Spustit"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Hledat"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Vstoupit do"
@@ -6964,16 +7024,6 @@ msgstr ""
"Následující soubory mají novější verzi na disku.\n"
"Jaká akce se má vykonat?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Znovu naÄíst"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Znovu uložit"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Ladicí program"
@@ -7066,8 +7116,8 @@ msgstr "Breakpointy"
msgid "Go To"
msgstr "Přejít na"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Vyjmout"
@@ -7290,6 +7340,11 @@ msgid "Yaw"
msgstr "Náklon"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Velikost: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objekty vykreslené"
@@ -8534,10 +8589,6 @@ msgid "Error"
msgstr "Chyba"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Nebyla poskytnuta commit message"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Zádné soubory nebyly přidány k zápisu"
@@ -8594,10 +8645,6 @@ msgid "Stage All"
msgstr "Připravit k zapsání vše"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Přidat zprávu commitu"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Commitnout změny"
@@ -9794,7 +9841,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Nepodporováno vaÅ¡imi ovladaÄi GPU."
#: editor/project_manager.cpp
msgid ""
@@ -9968,6 +10015,10 @@ msgid "Projects"
msgstr "Projekty"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "NaÄítání, prosím Äekejte..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Datum modifikace"
@@ -10338,6 +10389,11 @@ msgstr "Autoload"
msgid "Plugins"
msgstr "Pluginy"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "NaÄíst výchozí"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Předvolba..."
@@ -10586,6 +10642,15 @@ msgid "Instance Child Scene"
msgstr "Přidat instanci scény"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Nelze manipulovat s uzly z cizí scény!"
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Vložit uzly"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Odpojit skript"
@@ -10712,6 +10777,10 @@ msgid "Attach Script"
msgstr "Připojit skript"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Vyjmout uzly"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Odstranit uzel/uzly"
@@ -11516,6 +11585,35 @@ msgstr "Filtrovat meshe"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "PÅ™iÅ™aÄte uzlu GridMap zdroj MeshLibrary k použití jeho sítÄ›."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "ZaÄít zapeÄení"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Připravování datových struktur"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Vygenerovat buffery"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Přímé osvětlení"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Nepřímé osvětlení"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Následné zpracování"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Vykreslení světel:"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Název třídy nemůže být rezervované klíÄové slovo"
@@ -12021,12 +12119,16 @@ msgid "Select device from the list"
msgstr "Vyberte zařízení ze seznamu"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Spustitelný ADB není nakonfigurovaný v Nastavení Editoru."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Nelze najít nástroj 'apksigner'."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner není nakonfigurovaný v Nastavení Editoru."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Šablona sestavení Androidu není pro projekt nainstalována. Nainstalujte jej "
+"z nabídky Projekt."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12040,26 +12142,32 @@ msgstr ""
"ÚložiÅ¡tÄ› klíÄů pro vydání je nakonfigurováno nesprávnÄ› v profilu exportu."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr ""
-"Vlastní sestavení vyžaduje správnou cestu k sadě Android SDK v nastavení "
-"editoru."
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "Je vyžadována platná cesta Android SDK v Nastavení editoru."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr "Nesprávná cesta Android SDK pro vlastní sestavení v Nastavení editoru."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Neplatná cesta k Android SDK v Nastavení editoru."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "Chybí složka \"platform-tools\"!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
-msgstr ""
-"Šablona sestavení Androidu není pro projekt nainstalována. Nainstalujte jej "
-"z nabídky Projekt."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "Nelze najít příkaz adb z nástrojů platformy Android SDK."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr "Zkontrolujte ve složce Android SDK uvedené v Nastavení editoru."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "Chybí složka \"build-tools\"!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "Nelze najít apksigner, nástrojů Android SDK."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12317,6 +12425,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Prázdný CollisionPolygon2D nemá při kolizi žádný efekt."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12353,23 +12469,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Uzel A a uzel B musí být PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Uzel A musí být PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Uzel B musí být PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Kloub není připojen ke dvěma PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Uzel A a uzel B musí být různé PhysicsBody2D"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12519,28 +12635,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin musí mít uzel ARVRCamera jako potomka."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Hledat mřížky a světla"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Zbývající Äas: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Připravuji geometrii (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Vykreslení mřížek: "
+msgid "Preparing environment"
+msgstr "Připravuji prostředí"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Vykreslení světel:"
+msgid "Generating capture"
+msgstr "Generování snímání"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "DokonÄování vykreslení"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Ukládám světelné mapy"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Osvětlení sítí: "
+msgid "Done"
+msgstr "Hotovo"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12615,6 +12731,10 @@ msgid "Plotting Meshes"
msgstr "Vykreslení sítí"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "DokonÄování vykreslení"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12622,11 +12742,6 @@ msgstr ""
"Video driver GLES2 nepodporuje GIProby.\n"
"Místo toho použijte BakedLightmap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "Uzel InterpolatedCamera je zastaralý a bude odstraněn v Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight s úhlem širším než 90 stupňů nemůže vrhat stíny."
@@ -12693,23 +12808,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Uzel A a uzel B musí být PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Uzel A musí být PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Uzel B musí být PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Kloub není připojen k PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Uzel A a uzel B musí být odlišné PhysicsBody"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12868,6 +12983,14 @@ msgstr "Pozor!"
msgid "Please Confirm..."
msgstr "PotvrÄte prosím..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Je nutné použít platnou příponu."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Povolit minimapu mřížky."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12923,6 +13046,12 @@ msgstr ""
"Velikost pohledu musí být větší než 0, aby bylo možné cokoliv renderovat."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Neplatný zdroj pro náhled."
@@ -12950,14 +13079,50 @@ msgstr "Odlišnosti mohou být přiřazeny pouze ve vertex funkci."
msgid "Constants cannot be modified."
msgstr "Konstanty není možné upravovat."
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "Soubor nebo složka se stejným názvem již na tomto místě existuje."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "Uzel InterpolatedCamera je zastaralý a bude odstraněn v Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "Ne"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Tato scéna nebyla nikdy uložena. Uložit před spuštěním?"
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "Chybí složka \"build-tools\"!"
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "Spustitelný ADB není nakonfigurovaný v Nastavení Editoru."
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "Nelze najít nástroj zipalign."
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner není nakonfigurovaný v Nastavení Editoru."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Vlastní sestavení vyžaduje správnou cestu k sadě Android SDK v nastavení "
+#~ "editoru."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Zbývající Äas: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Vykreslení mřížek: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Osvětlení sítí: "
+
+#~ msgid "Search complete"
+#~ msgstr "Vyhledávání dokonÄeno"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Nebyla poskytnuta commit message"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Přidat zprávu commitu"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "Soubor nebo složka se stejným názvem již na tomto místě existuje."
#~ msgid "Aligning APK..."
#~ msgstr "Zarovnávání APK..."
@@ -13243,9 +13408,6 @@ msgstr "Konstanty není možné upravovat."
#~ msgid "Failed to save solution."
#~ msgstr "Nepodařilo se uložit řešení."
-#~ msgid "Done"
-#~ msgstr "Hotovo"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Vytvoření C# projektu selhalo."
diff --git a/editor/translations/da.po b/editor/translations/da.po
index b8dfa199e8..bc00612eae 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -1,6 +1,6 @@
# Danish translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Dankse Memes <purplelops@gmail.com>, 2018.
# David Lamhauge <davidlamhauge@gmail.com>, 2016, 2018.
@@ -15,14 +15,15 @@
# Mads K. Bredager <mbredager@gmail.com>, 2019.
# Kristoffer Andersen <kjaa@google.com>, 2019.
# Joe Osborne <reachjoe.o@gmail.com>, 2020.
-# Autowinto <happymansi@hotmail.com>, 2020.
-# Mikkel Mouridsen <mikkelmouridsen@me.com>, 2020.
+# Autowinto <happymansi@hotmail.com>, 2020, 2021.
+# Mikkel Mouridsen <mikkelmouridsen@me.com>, 2020, 2021.
+# snakatk <snaqii@live.dk>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-06-22 06:40+0000\n"
-"Last-Translator: Mikkel Mouridsen <mikkelmouridsen@me.com>\n"
+"PO-Revision-Date: 2021-02-05 09:20+0000\n"
+"Last-Translator: snakatk <snaqii@live.dk>\n"
"Language-Team: Danish <https://hosted.weblate.org/projects/godot-engine/"
"godot/da/>\n"
"Language: da\n"
@@ -30,7 +31,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -141,7 +142,7 @@ msgstr "Tilføj Bezier-punkt"
#: editor/animation_bezier_editor.cpp
msgid "Move Bezier Points"
-msgstr "Flyt punkt"
+msgstr "Flyt Bezier-punkter"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -197,9 +198,8 @@ msgid "Anim Multi Change Call"
msgstr "Anim Skift Call"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Length"
-msgstr "Ændre Animation Navn:"
+msgstr "Ændre Animationslængde"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -334,7 +334,7 @@ msgstr "Vikle Løkke Interpolation"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr "Indsæt nøgle"
+msgstr "Indsæt Nøgle"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
@@ -680,7 +680,7 @@ msgstr "Vælg spor til kopiering:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopier"
@@ -762,8 +762,9 @@ msgid "Standard"
msgstr "Standard"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
+#, fuzzy
msgid "Toggle Scripts Panel"
-msgstr ""
+msgstr "Slå til/fra Scripts Panel"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
@@ -825,7 +826,7 @@ msgstr "Fra signal:"
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
-msgstr ""
+msgstr "Scenen indeholder ikke noget script."
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
@@ -867,22 +868,23 @@ msgid "Deferred"
msgstr "Udskudt"
#: editor/connections_dialog.cpp
+#, fuzzy
msgid ""
"Defers the signal, storing it in a queue and only firing it at idle time."
-msgstr ""
+msgstr "Udskyder signalet, gemmer det i en kø og anvender det ved spildtid."
#: editor/connections_dialog.cpp
msgid "Oneshot"
msgstr "OneShot"
#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Disconnects the signal after its first emission."
-msgstr ""
+msgstr "Frakobler signalet efter dets første aktivering."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Cannot connect signal"
-msgstr "Forbind Signal: "
+msgstr "Kan ikke forbinde signal"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/export_template_manager.cpp editor/groups_editor.cpp
@@ -1429,12 +1431,14 @@ msgid "Open Audio Bus Layout"
msgstr "Ã…ben Audio Bus Layout"
#: editor/editor_audio_buses.cpp
+#, fuzzy
msgid "There is no '%s' file."
-msgstr ""
+msgstr "Der er ingen '%s' fil."
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Layout"
-msgstr ""
+msgstr "Layout"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
@@ -1513,8 +1517,9 @@ msgstr ""
"Ugyldigt navn. Må ikke være i konflikt med eksisterende global constant navn."
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Keyword cannot be used as an autoload name."
-msgstr ""
+msgstr "Nøgleord kan ikke bruges som autoload navn."
#: editor/editor_autoload_settings.cpp
msgid "Autoload '%s' already exists!"
@@ -1545,8 +1550,9 @@ msgid "Rearrange Autoloads"
msgstr "Flytte om på Autoloads"
#: editor/editor_autoload_settings.cpp
+#, fuzzy
msgid "Can't add autoload:"
-msgstr ""
+msgstr "Kan ikke tilføje autoload:"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -1633,8 +1639,9 @@ msgid "Storing File:"
msgstr "Lagrings Fil:"
#: editor/editor_export.cpp
+#, fuzzy
msgid "No export template found at the expected path:"
-msgstr ""
+msgstr "Ingen eksporterings-skabelon fundet ved den forventede sti:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1931,8 +1938,8 @@ msgid "Open a File or Directory"
msgstr "Ã…ben en Fil eller Mappe"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Gem"
@@ -2031,10 +2038,6 @@ msgstr "Forhåndsvisning:"
msgid "File:"
msgstr "Fil:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Du skal bruge en gyldig udvidelse."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Skan Kilder"
@@ -2475,6 +2478,10 @@ msgid "There is no defined scene to run."
msgstr "Der er ingen defineret scene at køre."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Kunne ikke starte underproces!"
@@ -2520,18 +2527,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr "Gem Scene Som..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nej"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Ja"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Denne scene er aldrig blevet gemt. Gem før kørsel?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Denne handling kan ikke udføres uden en scene."
@@ -2580,6 +2575,10 @@ msgid "Quit"
msgstr "Afslut"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Ja"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Forlad editor?"
@@ -2627,7 +2626,8 @@ msgstr ""
"mislykkedes."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "Kan ikke finde scriptfelt for addon plugin på: 'res://addons/%s'."
#: editor/editor_node.cpp
@@ -3073,14 +3073,6 @@ msgid "Help"
msgstr "Hjælp"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Søg"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentation"
@@ -3241,6 +3233,23 @@ msgid "Open & Run a Script"
msgstr "Åben & Kør et Script"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr "De følgende filer kunne ikke trækkes ud af pakken:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Ny Arved"
@@ -3449,7 +3458,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Indsæt"
@@ -4035,8 +4044,18 @@ msgstr "Gemmer..."
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "Søg Tekst"
+msgid "%d match in %d file."
+msgstr "Ingen Match"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "Ingen Match"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Ingen Match"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4180,6 +4199,21 @@ msgstr ""
msgid "Saving..."
msgstr "Gemmer..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Vælg Node"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importer"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Indlæs Default"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Filer"
@@ -4774,17 +4808,18 @@ msgid "Scale animation playback globally for the node."
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+#, fuzzy
msgid "Animation Tools"
-msgstr ""
+msgstr "Animation Værktøjer"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation"
-msgstr ""
+msgstr "Animation"
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
msgid "Edit Transitions..."
-msgstr "Overgange"
+msgstr "Rediger Overgange..."
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
@@ -4822,20 +4857,21 @@ msgid "Future"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+#, fuzzy
msgid "Depth"
-msgstr ""
+msgstr "Dybde"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "1 step"
-msgstr ""
+msgstr "1 trin"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "2 steps"
-msgstr ""
+msgstr "2 trin"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "3 steps"
-msgstr ""
+msgstr "3 trin"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Differences Only"
@@ -4852,30 +4888,31 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
msgid "Pin AnimationPlayer"
-msgstr "Ændre Animation Navn:"
+msgstr "Fastgør AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Create New Animation"
-msgstr ""
+msgstr "Opret Ny Animation"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
-msgstr ""
+msgstr "Animation Navn:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
msgid "Error!"
-msgstr ""
+msgstr "Fejl!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Times:"
msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
+#, fuzzy
msgid "Next (Auto Queue):"
-msgstr ""
+msgstr "Næste (Auto Kø):"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Cross-Animation Blend Times"
@@ -4887,14 +4924,12 @@ msgid "Move Node"
msgstr "Flyt Node(s)"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition exists!"
-msgstr "Overgang"
+msgstr "Overgang eksisterer!"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Add Transition"
-msgstr "Overgang"
+msgstr "Tilføj Overgang"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -4931,14 +4966,12 @@ msgid "No playback resource set at path: %s."
msgstr "Ikke i stien for ressource."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Removed"
-msgstr "Fjern"
+msgstr "Node Fjernet"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition Removed"
-msgstr "Overgang"
+msgstr "Overgang Fjernet"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
@@ -4975,9 +5008,8 @@ msgid "Set the end animation. This is useful for sub-transitions."
msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition: "
-msgstr "Overgang"
+msgstr "Overgang: "
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -4992,7 +5024,7 @@ msgstr "Animation Zoom."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
-msgstr ""
+msgstr "Nyt navn:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/multimesh_editor_plugin.cpp
@@ -5016,8 +5048,9 @@ msgid "Mix"
msgstr ""
#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#, fuzzy
msgid "Auto Restart:"
-msgstr ""
+msgstr "Auto Genstart:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Restart (s):"
@@ -5033,8 +5066,9 @@ msgstr ""
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/multimesh_editor_plugin.cpp
+#, fuzzy
msgid "Amount:"
-msgstr ""
+msgstr "Mængde:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend 0:"
@@ -5050,13 +5084,14 @@ msgstr ""
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Current:"
-msgstr ""
+msgstr "Nuværende:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
msgid "Add Input"
-msgstr ""
+msgstr "Tilføj Input"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Clear Auto-Advance"
@@ -5067,8 +5102,9 @@ msgid "Set Auto-Advance"
msgstr ""
#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#, fuzzy
msgid "Delete Input"
-msgstr ""
+msgstr "Fjern Input"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation tree is valid."
@@ -5115,16 +5151,19 @@ msgid "Transition Node"
msgstr ""
#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#, fuzzy
msgid "Import Animations..."
-msgstr ""
+msgstr "Importer Animationer..."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#, fuzzy
msgid "Edit Node Filters"
-msgstr ""
+msgstr "Rediger Node Filtre"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#, fuzzy
msgid "Filters..."
-msgstr ""
+msgstr "Filtre..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Contents:"
@@ -5135,8 +5174,9 @@ msgid "View Files"
msgstr "Vis filer"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Connection error, please try again."
-msgstr ""
+msgstr "Forbindelsesfejl, prøv venligst igen."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Can't connect to host:"
@@ -5144,15 +5184,16 @@ msgstr "Kan ikke forbinde til host:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No response from host:"
-msgstr ""
+msgstr "Ingen respons fra host:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Can't resolve hostname:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Request failed, return code:"
-msgstr ""
+msgstr "Forespørgsel mislykkedes, returkode:"
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
@@ -5162,11 +5203,12 @@ msgstr "Forespørgsel mislykkedes."
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Cannot save response to:"
-msgstr "Kan ikke fjerne:"
+msgstr "Kan ikke gemme respons i:"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Write error."
-msgstr ""
+msgstr "Skrivefejl."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
@@ -5180,12 +5222,12 @@ msgstr "Omdiriger Løkke."
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Request failed, timeout"
-msgstr "Forespørgsel mislykkedes."
+msgstr "Forespørgsel mislykkedes, tiden udløb."
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Timeout."
-msgstr "Tid"
+msgstr "Tiden udløb."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
@@ -5200,7 +5242,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5208,14 +5250,12 @@ msgid "Asset Download Error:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Downloading (%s / %s)..."
-msgstr "Indlæser"
+msgstr "Downloader (%s / %s)..."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Downloading..."
-msgstr "Indlæser"
+msgstr "Downloader..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Resolving..."
@@ -5232,11 +5272,12 @@ msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
msgid "Install..."
-msgstr "Installér"
+msgstr "Installér..."
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Retry"
-msgstr ""
+msgstr "Prøv igen"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download Error"
@@ -5256,25 +5297,23 @@ msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (A-Z)"
-msgstr ""
+msgstr "Navn (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (Z-A)"
-msgstr ""
+msgstr "Navn (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (A-Z)"
-msgstr "Licens"
+msgstr "Licens (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (Z-A)"
-msgstr "Licens"
+msgstr "Licens (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "First"
-msgstr ""
+msgstr "Første"
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
@@ -5287,7 +5326,7 @@ msgstr "Næste"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Last"
-msgstr ""
+msgstr "Sidste"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "All"
@@ -5298,9 +5337,8 @@ msgid "No results for \"%s\"."
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Import..."
-msgstr "Importer"
+msgstr "Importer..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Plugins..."
@@ -5311,7 +5349,6 @@ msgid "Sort:"
msgstr "Sorter:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategori:"
@@ -5320,9 +5357,8 @@ msgid "Site:"
msgstr "Websted:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Support"
-msgstr "Støtte..."
+msgstr "Support"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -5333,9 +5369,8 @@ msgid "Testing"
msgstr "Tester"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Loading..."
-msgstr "Indlæs"
+msgstr "Indlæser..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -5344,8 +5379,7 @@ msgstr "Assets zipfil"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5359,9 +5393,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Vælg template fil"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5385,7 +5439,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "steps"
-msgstr ""
+msgstr "trin"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
@@ -6467,6 +6521,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Konverter Til %s"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6527,10 +6586,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -7149,6 +7204,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Søg"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7202,16 +7265,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7312,8 +7365,8 @@ msgstr "Slet points"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Cut"
@@ -7552,6 +7605,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8847,11 +8904,6 @@ msgid "Error"
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
msgid "No files added to stage"
msgstr ""
@@ -8916,10 +8968,6 @@ msgid "Stage All"
msgstr "Vælg alle"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Synkroniser Script Ændringer"
@@ -10227,6 +10275,11 @@ msgid "Projects"
msgstr "Projekt"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Henter spejle, vent venligst ..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10599,6 +10652,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Indlæs Default"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Forudindstillet..."
@@ -10854,6 +10912,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Indsæt Node"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Ryd Script"
@@ -10984,6 +11051,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Indsæt Node"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11825,6 +11897,37 @@ msgstr "Filter mode:"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Beskrivelse"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Skift udtryk"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Generering af lightmaps"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12355,11 +12458,13 @@ msgid "Select device from the list"
msgstr "Vælg enhed fra listen"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12371,11 +12476,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12383,9 +12488,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12634,6 +12749,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "En tom CollisionPolygon2D har ingen effekt på kollision."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12823,27 +12946,29 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "Generering af lightmaps"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Generering af lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12912,14 +13037,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -13142,6 +13266,14 @@ msgstr "Advarsel!"
msgid "Please Confirm..."
msgstr "Bekræft venligst..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Du skal bruge en gyldig udvidelse."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
#, fuzzy
msgid ""
@@ -13191,6 +13323,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Ugyldig skriftstørrelse."
@@ -13221,6 +13359,20 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanter kan ikke ændres."
+#~ msgid "No"
+#~ msgstr "Nej"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Denne scene er aldrig blevet gemt. Gem før kørsel?"
+
+#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "Søg Tekst"
+
+#, fuzzy
+#~ msgid "No commit message was provided"
+#~ msgstr "Intet navn angivet"
+
#, fuzzy
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "En fil eller mappe med dette navn findes allerede."
@@ -13451,10 +13603,6 @@ msgstr "Konstanter kan ikke ændres."
#~ msgid "Create folder"
#~ msgstr "Opret mappe"
-#, fuzzy
-#~ msgid "Custom Node"
-#~ msgstr "Indsæt Node"
-
#~ msgid "Invalid Path"
#~ msgstr "Ugyldig sti"
diff --git a/editor/translations/de.po b/editor/translations/de.po
index a7c6f3dddc..bf3c01ae14 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -1,6 +1,6 @@
# German translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Alexander Mahr <alex.mahr@gmail.com>, 2016, 2019.
# Andreas Esau <andreasesau@gmail.com>, 2016.
@@ -23,7 +23,7 @@
# Peter Friedland <peter_friedland@gmx.de>, 2016.
# No need for a name <endoplasmatik@gmx.net>, 2016.
# Sönke <me@eknoes.de>, 2018.
-# So Wieso <sowieso@dukun.de>, 2016-2018, 2019, 2020.
+# So Wieso <sowieso@dukun.de>, 2016-2018, 2019, 2020, 2021.
# Tim Schellenberg <smwleod@gmail.com>, 2017.
# Timo Schwarzer <account@timoschwarzer.com>, 2016-2018.
# viernullvier <hannes.breul+github@gmail.com>, 2016.
@@ -36,7 +36,7 @@
# asyncial <mahlburg@posteo.de>, 2018.
# ssantos <ssantos@web.de>, 2018.
# Rémi Verschelde <akien@godotengine.org>, 2019.
-# Martin <martinreininger@gmx.net>, 2019.
+# Martin <martinreininger@gmx.net>, 2019, 2021.
# Andreas During <anduring@web.de>, 2019.
# Arthur S. Muszynski <artism90@gmail.com>, 2019.
# Andreas Binczyk <andreas.binczyk@gmail.com>, 2019.
@@ -62,12 +62,17 @@
# Patric Wust <patric.wust@gmx.de>, 2020.
# Jonathan Hassel <jonathan.hassel@icloud.com>, 2020.
# Artur Schönfeld <schoenfeld.artur@ymail.com>, 2020.
+# kidinashell <kidinashell@protonmail.com>, 2021.
+# Daniel Glocker <mystboy666@gmail.com>, 2021.
+# Raphipod <podraphi@googlemail.com>, 2021.
+# Daniel Plaster <danimineiromc@googlemail.com>, 2021.
+# El Captian <elcaptian@posteo.me>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-01 20:29+0000\n"
-"Last-Translator: So Wieso <sowieso@dukun.de>\n"
+"PO-Revision-Date: 2021-03-07 06:04+0000\n"
+"Last-Translator: El Captian <elcaptian@posteo.me>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
"Language: de\n"
@@ -75,7 +80,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -707,7 +712,7 @@ msgstr "Zu kopierende Spuren auswählen"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopieren"
@@ -1920,8 +1925,8 @@ msgid "Open a File or Directory"
msgstr "Datei oder Verzeichnis öffnen"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Speichern"
@@ -2012,10 +2017,6 @@ msgstr "Vorschau:"
msgid "File:"
msgstr "Datei:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Eine gültige Datei-Endung muss verwendet werden."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Lese Quellen"
@@ -2446,7 +2447,7 @@ msgid ""
"Please read the documentation relevant to debugging to better understand "
"this workflow."
msgstr ""
-"Dies ist ein nicht-lokales Objekt, Änderungen an ihm werden nicht "
+"Dies ist ein Laufzeit-Objekt Objekt, Änderungen an ihm werden nicht "
"gespeichert.\n"
"Die Dokumentation zum Debugging beschreibt den nötigen Arbeitsablauf."
@@ -2455,6 +2456,10 @@ msgid "There is no defined scene to run."
msgstr "Es ist keine abzuspielende Szene definiert."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Szene vor dem Abspielen speichern..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Unterprozess konnte nicht gestartet werden!"
@@ -2498,18 +2503,6 @@ msgstr "Ein Wurzel-Node wird benötigt um diese Szene zu speichern."
msgid "Save Scene As..."
msgstr "Szene speichern als..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nein"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Ja"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Diese Szene wurde nie gespeichert. Speichern vorm Starten?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Diese Aktion kann nicht ohne eine Szene ausgeführt werden."
@@ -2561,6 +2554,10 @@ msgid "Quit"
msgstr "Verlassen"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Ja"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Editor verlassen?"
@@ -2609,7 +2606,7 @@ msgstr ""
"fehlgeschlagen."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"Skript-Feld für Erweiterung in ‚res://addons/%s‘ konnte nicht gefunden "
"werden."
@@ -3050,14 +3047,6 @@ msgid "Help"
msgstr "Hilfe"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Suchen"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Internetdokumentation"
@@ -3076,7 +3065,7 @@ msgstr "Dokumentationsvorschläge senden"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr "Community"
+msgstr "Gemeinschaft"
#: editor/editor_node.cpp
msgid "About"
@@ -3223,6 +3212,24 @@ msgid "Open & Run a Script"
msgstr "Skript öffnen und ausführen"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Die folgenden Dateien wurden im Dateisystem verändert.\n"
+"Wie soll weiter vorgegangen werden?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Neu laden"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Erneut speichern"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Neu Geerbte"
@@ -3434,7 +3441,7 @@ msgstr "Einzigartig machen"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Einfügen"
@@ -3795,6 +3802,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Die folgenen Dateien oder Ordner stehen im Konflikt mit Objekten im Zielpfad "
+"‚%s‘:\n"
+"\n"
+"%s\n"
+"\n"
+"Soll überschrieben werden?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3987,8 +4000,16 @@ msgid "Searching..."
msgstr "Am suchen..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Suche abgeschlossen"
+msgid "%d match in %d file."
+msgstr "%d Übereinstimmung in %d Datei gefunden."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d Übereinstimmungen in %d Datei gefunden."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d Übereinstimmungen in %d Dateien gefunden."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4126,6 +4147,21 @@ msgstr ""
msgid "Saving..."
msgstr "Speichere..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Auswahlmodus"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Import"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Nutze Standard-sRGB"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Dateien"
@@ -4756,7 +4792,7 @@ msgstr "Weißmodulation erzwingen"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Include Gizmos (3D)"
-msgstr "Griffe (3D) einbeziehen"
+msgstr "3D-Manipulator einbeziehen"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pin AnimationPlayer"
@@ -4889,7 +4925,7 @@ msgstr "Abspielmodus:"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "AnimationTree"
-msgstr "AnimationTree"
+msgstr "AnimationsBaum"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
@@ -5096,8 +5132,8 @@ msgid "Got:"
msgstr "Erhalten:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Sha256-Prüfung fehlgeschlagen"
+msgid "Failed SHA-256 hash check"
+msgstr "Sha256 Checksummen prüfung fehlgeschlagen"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5200,7 +5236,6 @@ msgid "Sort:"
msgstr "Sortiere:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategorie:"
@@ -5231,12 +5266,10 @@ msgstr "Nutzerinhalte als ZIP-Datei"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"Der Speicherpfad für Lightmap-Bilder kann nicht bestimmt werden.\n"
-"Speichern Sie die Szene (Bilder werden im gleichen Ordner gespeichert) oder "
-"legen Sie den Speicherpfad in den BakedLightmap-Eigenschaften fest."
+"Ein Speicherpfad für Lightmap-Bilder kann nicht bestimmt werden.\n"
+"Ein Speichern der Szene sollte dieses Problem beheben."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5254,9 +5287,34 @@ msgstr ""
"Speicherpfad beschreibbar ist."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Die Größe des Lightmaps kann nicht bestimmt werden. Möglicherweise ist die "
+"maximale Lightmap-Größe zu klein?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Ein Mesh ist ungültig. Es muss sichergestellt sein dass alle Werte das UV2-"
+"Kanals im Bereich von 0.0 bis 1.0 liegen."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Diese Godot-Version wurde ohne Raytracing-Unterstützung erstellt, Lightmaps "
+"können damit nicht gebacken werden."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Lightmaps vorrendern"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Lightmap-Bake-Datei auswählen:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6358,6 +6416,10 @@ msgstr ""
"werden"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Zu CPUParticles2D konvertieren"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Erzeugungszeit (s):"
@@ -6418,10 +6480,6 @@ msgstr "Erzeuge AABB"
msgid "Generate Visibility AABB"
msgstr "Erzeuge Sichtbarkeits-AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Erzeuge AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Punkt von Kurve entfernen"
@@ -7013,6 +7071,14 @@ msgstr "Dokumentation schließen"
msgid "Run"
msgstr "Ausführen"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Suchen"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Hineinspringen"
@@ -7066,16 +7132,6 @@ msgstr ""
"Die folgenden Dateien wurden im Dateisystem verändert.\n"
"Wie soll weiter vorgegangen werden?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Neu laden"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Erneut speichern"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Debugger"
@@ -7171,8 +7227,8 @@ msgstr "Haltepunkte"
msgid "Go To"
msgstr "Springe zu"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Ausschneiden"
@@ -7314,7 +7370,7 @@ msgstr "Knochen in Ruhe-Pose setzen"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Skeleton2D"
-msgstr "Skeleton2D"
+msgstr "Skelett2D"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Make Rest Pose (From Bones)"
@@ -7397,6 +7453,10 @@ msgid "Yaw"
msgstr "Gieren"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Größe"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Gezeichnete Objekte"
@@ -7418,7 +7478,7 @@ msgstr "Zeichenaufrufe"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Vertices"
-msgstr "Vertices"
+msgstr "Eckpunkte"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View."
@@ -7511,7 +7571,7 @@ msgstr "Umgebung anzeigen"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Gizmos"
-msgstr "Griffe anzeigen"
+msgstr "Manipulator anzeigen"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Information"
@@ -7599,9 +7659,9 @@ msgid ""
msgstr ""
"Klicken um zwischen Sichtbarkeitsmodi umzuschalten.\n"
"\n"
-"Offenes Auge: Griffe sind sichtbar.\n"
-"Geschlossenes Auge: Griffe sind unsichtbar.\n"
-"Halb offenes Auge: Griffe sind auch durch deckende Oberflächen sichtbar "
+"Offenes Auge: Manipulator ist sichtbar.\n"
+"Geschlossenes Auge: Manipulator ist unsichtbar.\n"
+"Halb offenes Auge: Manipulator ist auch durch deckende Oberflächen sichtbar "
"(\"Röntgenblick\")."
#: editor/plugins/spatial_editor_plugin.cpp
@@ -7715,7 +7775,7 @@ msgstr "Vier Ansichten"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Gizmos"
-msgstr "Griffe"
+msgstr "Manipulator"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Origin"
@@ -7792,7 +7852,7 @@ msgstr "Nachher"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Nameless gizmo"
-msgstr "Namenloser Anfasser"
+msgstr "Namenloser Manipulator"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create Mesh2D"
@@ -8471,7 +8531,7 @@ msgstr "Keine Textur zum Entfernen ausgewählt."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from scene? This will overwrite all current tiles."
-msgstr "Aus Szene erstellen? Alle aktuellen Kacheln werden überschrieben!"
+msgstr "Aus Szene erstellen? Alle aktuellen Kacheln werden überschrieben."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Merge from scene?"
@@ -8650,10 +8710,6 @@ msgid "Error"
msgstr "Fehler"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Es wurde keine Protokollnachricht angegeben"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Es wurden keine Dateien zum protokollieren vorgemerkt"
@@ -8710,10 +8766,6 @@ msgid "Stage All"
msgstr "Alles zum speichern vormerken"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Protokollnachricht hinzufügen"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Änderungen als Speicherpunkt sichern"
@@ -9613,7 +9665,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
-msgstr "VisualShader"
+msgstr "VisuellerShader"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Edit Visual Property"
@@ -9921,7 +9973,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Nicht unterstützt durch gegenwärtigen GPU-Treiber."
#: editor/project_manager.cpp
msgid ""
@@ -10102,6 +10154,10 @@ msgid "Projects"
msgstr "Projekte"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Projekte werden geladen, bitte warten..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Zuletzt bearbeitet"
@@ -10271,7 +10327,7 @@ msgstr "Ereignis hinzufügen"
#: editor/project_settings_editor.cpp
msgid "Button"
-msgstr "Schaltfläche (Button)"
+msgstr "Knopf"
#: editor/project_settings_editor.cpp
msgid "Left Button."
@@ -10474,6 +10530,11 @@ msgstr "Autoload"
msgid "Plugins"
msgstr "Erweiterungen"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Standard laden"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Voreinstellungen..."
@@ -10725,6 +10786,14 @@ msgid "Instance Child Scene"
msgstr "Szene hier instantiieren"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "Einfügen der Wurzelnode in dieselbe Szene nicht möglich."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Node(s) einfügen"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Skript loslösen"
@@ -10852,6 +10921,10 @@ msgid "Attach Script"
msgstr "Skript hinzufügen"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Node(s) trennen"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Entferne Node(s)"
@@ -11491,7 +11564,7 @@ msgstr "Bibliotheken: "
#: modules/gdnative/register_types.cpp
msgid "GDNative"
-msgstr "GDNative"
+msgstr "GDNativ"
#: modules/gdscript/gdscript_functions.cpp
msgid "Step argument is zero!"
@@ -11659,6 +11732,34 @@ msgstr "Meshes filtern"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "GridMap zu MeshLibrary hinzufügen um ihre Meshes benutzen zu können."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Backen beginnen"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Datenstrukturen werden vorbereitet"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Puffer generieren"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Direct-Lighting"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Indirect-Lighting"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Nachbearbeitung"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Lightmaps auftragen"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Der Klassenname kann nicht ein reserviertes Schlüsselwort sein"
@@ -12177,12 +12278,16 @@ msgid "Select device from the list"
msgstr "Gerät aus Liste auswählen"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Das ADB-Programm wurde nicht in den Editoreinstellungen konfiguriert."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Das ‚apksigner‘-Hilfswerkzeug konnte nicht gefunden werden."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK-Jarsigner wurde nicht in den Editoreinstellungen konfiguriert."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Es wurde keine Android-Buildvorlage für dieses Projekt installiert. Es kann "
+"im Projektmenü installiert werden."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12196,26 +12301,38 @@ msgstr ""
"Release-Keystore wurde nicht korrekt konfiguriert in den Exporteinstellungen."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"Eigene Builds erfordern gültigen Android-SDK-Pfad in den Editoreinstellungen."
+"Es wird ein gültiger Android-SDK-Pfad in den Editoreinstellungen benötigt."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Ungültiger Android-SDK-Pfad für eigene Builds in den Editoreinstellungen."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Ungültiger Android-SDK-Pfad in den Editoreinstellungen."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "‚platform-tools‘-Verzeichnis fehlt!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
msgstr ""
-"Es wurde keine Android-Buildvorlage für dieses Projekt installiert. Es kann "
-"im Projektmenü installiert werden."
+"‚adb‘-Anwendung der Android-SDK-Platform-Tools konnte nicht gefunden werden."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"Schauen Sie im Android-SDK-Verzeichnis das in den Editoreinstellungen "
+"angegeben wurde nach."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "‚build-tools‘-Verzeichnis fehlt!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+"‚apksigner‘-Anwendung der Android-SDK-Build-Tools konnte nicht gefunden "
+"werden."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12478,6 +12595,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Ein leeres CollisionPolygon2D hat keinen Effekt auf Kollisionen."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12516,23 +12641,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A und Node B müssen PhysicsBody2D-Nodes sein"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node A muss ein PhysicsBody2D-Node sein"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node B muss ein PhysicsBody2D-Node sein"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Das Gelenk ist nicht mit zwei PhysicsBody2D-Nodes verbunden"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A und Node B müssen unterschiedliche PhysicsBody2D-Nodes sein"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12698,28 +12823,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin benötigt ein ARVRCamera-Unterobjekt."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Am Suchen nach Meshes und Lichtern"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Verbleibende Zeit: %d:%20d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Am Vorbereiten der Geometrie (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Plotte Meshe: "
+msgid "Preparing environment"
+msgstr "Am Vorbereiten der Umgebung"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Plotte Lichter:"
+msgid "Generating capture"
+msgstr "Am Generieren eines Schnappschusses"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Stelle Plot fertig"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Am Speichern der Lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Beleuchte Meshe: "
+msgid "Done"
+msgstr "Fertig"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12796,6 +12921,10 @@ msgid "Plotting Meshes"
msgstr "Plotte Mesh"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Stelle Plot fertig"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12803,11 +12932,6 @@ msgstr ""
"GIProbes werden vom GLES2-Videotreiber nicht unterstützt.\n"
"BakedLightmaps können als Alternative verwendet werden."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera ist veraltet und wird in Godot 4.0 entfernt werden."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12879,23 +13003,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Node A und Node B müssen PhysicsBody-Nodes sein"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Node A muss ein PhysicsBody-Node sein"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Node B muss ein PhysicsBody-Node sein"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Gelenk ist nicht mit einem PhysicsBody-Node verbunden"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Node A und Node B müssen unterschiedliche PhysicsBody-Nodes sein"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -13065,6 +13189,14 @@ msgstr "Warnung!"
msgid "Please Confirm..."
msgstr "Bitte bestätigen..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Eine gültige Datei-Endung muss verwendet werden."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Gitterübersichtskarte aktivieren."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13123,6 +13255,14 @@ msgstr ""
"Die Größe des Viewports muss größer als 0 sein um etwas rendern zu können."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"Der Sampler-Port ist verbunden wird aber nicht benutzt. Die Quelle sollte "
+"möglicherweise auf ‚SamplerPort‘ gestellt werden."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Ungültige Quelle für Vorschau."
@@ -13150,17 +13290,56 @@ msgstr "Varyings können nur in Vertex-Funktion zugewiesen werden."
msgid "Constants cannot be modified."
msgstr "Konstanten können nicht verändert werden."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "InterpolatedCamera ist veraltet und wird in Godot 4.0 entfernt werden."
+
+#~ msgid "No"
+#~ msgstr "Nein"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Diese Szene wurde nie gespeichert. Speichern vorm Starten?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr ""
+#~ "Das ADB-Programm wurde nicht in den Editoreinstellungen konfiguriert."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr ""
+#~ "OpenJDK-Jarsigner wurde nicht in den Editoreinstellungen konfiguriert."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Eigene Builds erfordern gültigen Android-SDK-Pfad in den "
+#~ "Editoreinstellungen."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Verbleibende Zeit: %d:%20d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Plotte Meshe: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Beleuchte Meshe: "
+
+#~ msgid "Search complete"
+#~ msgstr "Suche abgeschlossen"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Es wurde keine Protokollnachricht angegeben"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Protokollnachricht hinzufügen"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr ""
#~ "Es existiert bereits eine Datei oder ein Ordner an diesem Pfad mit dem "
#~ "angegebenen Namen."
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "‚build-tools‘-Verzeichnis fehlt!"
-
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "Das zipalign Hilfswerkzeug konnte nicht gefunden werden."
-
#~ msgid "Aligning APK..."
#~ msgstr "Richte APK aus..."
@@ -13510,9 +13689,6 @@ msgstr "Konstanten können nicht verändert werden."
#~ msgid "Failed to save solution."
#~ msgstr "Fehler beim Speichern der Lösung."
-#~ msgid "Done"
-#~ msgstr "Fertig"
-
#~ msgid "Failed to create C# project."
#~ msgstr "C#-Projekt-Erzeugen fehlgeschlagen."
@@ -14962,9 +15138,6 @@ msgstr "Konstanten können nicht verändert werden."
#~ msgid "Use Default Light"
#~ msgstr "Nutze Standardlicht"
-#~ msgid "Use Default sRGB"
-#~ msgstr "Nutze Standard-sRGB"
-
#~ msgid "Default Light Normal:"
#~ msgstr "Standardlichtnormale:"
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 23a0ea8480..d11d4f42ac 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -1,6 +1,6 @@
-# LANGUAGE translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# LANGUAGE translation of the Godot Engine editor.
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
@@ -621,7 +621,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1790,8 +1790,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1882,10 +1882,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2289,6 +2285,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2332,18 +2332,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2391,6 +2379,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2433,7 +2425,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2823,14 +2815,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2984,6 +2968,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3186,7 +3186,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3722,7 +3722,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3859,6 +3867,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4806,7 +4826,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4910,7 +4930,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4941,8 +4960,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4956,9 +4974,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6014,6 +6051,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6074,10 +6115,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6659,6 +6696,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6710,16 +6755,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6812,8 +6847,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7034,6 +7069,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8245,10 +8284,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8305,10 +8340,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9562,6 +9593,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9922,6 +9957,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10165,6 +10204,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10285,6 +10332,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11069,6 +11120,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11564,11 +11643,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11580,11 +11661,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11592,9 +11673,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11819,6 +11910,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -11985,27 +12084,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12065,14 +12164,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12278,6 +12376,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12319,6 +12425,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index fde979b618..8cd3397399 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -1,6 +1,6 @@
# Greek translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# George Tsiamasiotis <gtsiam@windowslive.com>, 2017-2018, 2019, 2020.
# Georgios Katsanakis <geo.elgeo@gmail.com>, 2019.
@@ -10,12 +10,13 @@
# pandektis <pandektis@gmail.com>, 2020.
# KostasMSC <kargyris@athtech.gr>, 2020.
# lawfulRobot <czavantias@gmail.com>, 2020.
+# Michalis <michalisntovas@yahoo.gr>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-09-30 12:32+0000\n"
-"Last-Translator: lawfulRobot <czavantias@gmail.com>\n"
+"PO-Revision-Date: 2021-03-03 15:50+0000\n"
+"Last-Translator: Michalis <michalisntovas@yahoo.gr>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/"
"el/>\n"
"Language: el\n"
@@ -23,7 +24,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.3-dev\n"
+"X-Generator: Weblate 4.5.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -656,7 +657,7 @@ msgstr "Επιλογή Κομματιών για ΑντιγÏαφή"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "ΑντιγÏαφή"
@@ -1866,8 +1867,8 @@ msgid "Open a File or Directory"
msgstr "Άνοιγμα αÏχείου ή φακέλου"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Αποθήκευση"
@@ -1878,7 +1879,7 @@ msgstr "Αποθήκευση αÏχείου"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
-msgstr "Πήγαινε πίσω"
+msgstr "ΕπιστÏοφή"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
@@ -1958,10 +1959,6 @@ msgstr "ΠÏοεπισκόπηση:"
msgid "File:"
msgstr "ΑÏχείο:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Απαιτείται η χÏήση έγκυÏης επέκτασης."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "ΣάÏωση πηγών"
@@ -2396,6 +2393,10 @@ msgid "There is no defined scene to run."
msgstr "Δεν υπάÏχει καθοÏισμένη σκηνή για εκτελέση."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "ΑδÏνατη η εκκίνηση της υπό-εÏγασίας!"
@@ -2439,18 +2440,6 @@ msgstr "Απαιτείται Ïιζικός κόμβος για την αποθÎ
msgid "Save Scene As..."
msgstr "Αποθήκευση σκηνή ως..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Όχι"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Îαι"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Αυτή η σκηνή δεν έχει αποθηκευτεί. Αποθήκευση Ï€Ïιν από την εκτέλεση;"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Αυτή η λειτουÏγία δεν μποÏεί να γίνει χωÏίς σκηνή."
@@ -2502,6 +2491,10 @@ msgid "Quit"
msgstr "Έξοδος"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Îαι"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "ΤεÏματισμός του Ï€ÏογÏάμματος επεξεÏγασίας;"
@@ -2550,7 +2543,8 @@ msgstr ""
"αÏχείου ÏÏθμισης."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"ΑδÏνατη η έυÏεση του πεδίου 'script' για την Ï€Ïόσθετη επέκταση στο: 'res://"
"addons/%s'."
@@ -2991,14 +2985,6 @@ msgid "Help"
msgstr "Βοήθεια"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Αναζήτηση"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "ΗλεκτÏονική τεκμηÏίωση"
@@ -3166,6 +3152,25 @@ msgid "Open & Run a Script"
msgstr "Άνοιξε & ΤÏέξε μία δέσμη ενεÏγειών"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Τα ακόλουθα αÏχεία είναι νεότεÏα στον δίσκο.\n"
+"Τι δÏάση να ληφθεί;:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "ΕπαναφόÏτωση"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Επαναποθήκευση"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Îέα κληÏονομημένη"
@@ -3376,7 +3381,7 @@ msgstr "Κάνε μοναδικό"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Επικόλληση"
@@ -3913,7 +3918,7 @@ msgstr "Αντικατάσταση..."
#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
msgid "Cancel"
-msgstr "ΑκÏÏωση"
+msgstr "ΆκυÏο"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -3932,8 +3937,19 @@ msgid "Searching..."
msgstr "Αναζήτηση..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "ΟλοκλήÏωση αναζήτησης"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d αποτελέσματα."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d αποτελέσματα."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d αποτελέσματα."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4072,6 +4088,21 @@ msgstr ""
msgid "Saving..."
msgstr "Αποθήκευση..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Επιλογή ΛειτουÏγίας"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Εισαγωγή"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "ΧÏήση Ï€Ïοεπιλεγμένου sRGB"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d αÏχεία"
@@ -5042,7 +5073,8 @@ msgid "Got:"
msgstr "Δοσμένο:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Η δοκιμή κατακεÏÎ¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï sha256 απέτυχε"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5146,7 +5178,6 @@ msgid "Sort:"
msgstr "Ταξινόμηση:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "ΚατηγοÏία:"
@@ -5175,10 +5206,10 @@ msgid "Assets ZIP File"
msgstr "ΑÏχείο ZIP των Στοιχείων"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Δεν ήταν δυνατός ο Ï€ÏοσδιοÏισμός διαδÏομής αποθήκευσης για εικόνες "
"lightmap.\n"
@@ -5201,9 +5232,29 @@ msgstr ""
"είναι εγγÏάψιμη."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "ΠÏοετοιμασία Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Επιλογή ΑÏχείου ΠÏοτÏπων"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6313,6 +6364,11 @@ msgstr ""
"ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "ΜετατÏοπή σε σωματίδια CPU"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "ΧÏόνος ΠαÏαγωγής (sec):"
@@ -6373,10 +6429,6 @@ msgstr "ΔημιουÏία AABB"
msgid "Generate Visibility AABB"
msgstr "ΔημιουÏία AABB οÏατότητας"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "ΔημιουÏία AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "ΑφαίÏεση σημείου από την καμπÏλη"
@@ -6976,6 +7028,14 @@ msgstr "Κλείσιμο ΤεκμηÏίωσης"
msgid "Run"
msgstr "Εκτέλεση"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Αναζήτηση"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Βήμα μέσα"
@@ -6991,7 +7051,7 @@ msgstr "Διακοπή"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
msgid "Continue"
-msgstr "Συνέχιση"
+msgstr "Συνέχεια"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
@@ -7029,16 +7089,6 @@ msgstr ""
"Τα ακόλουθα αÏχεία είναι νεότεÏα στον δίσκο.\n"
"Τι δÏάση να ληφθεί;:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "ΕπαναφόÏτωση"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Επαναποθήκευση"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Αποσφαλματωτής"
@@ -7135,8 +7185,8 @@ msgstr "Σημεία Διακοπής"
msgid "Go To"
msgstr "Πήγαινε Σε"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Αποκοπή"
@@ -7361,6 +7411,11 @@ msgid "Yaw"
msgstr "ΠαÏέκκλιση"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Μέγεθος: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "ΖωγÏαφισμένα αντικείμενα"
@@ -8616,16 +8671,12 @@ msgid "Error"
msgstr "Σφάλμα"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Κανένα δεσμευμένο μήνυμα δεν παÏασχέθηκε"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Κανένα αÏχείο δεν Ï€Ïοστέθηκε στο στάδιο"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
-msgstr "Δέσμευση"
+msgstr "Υποβολή"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "VCS Addon is not initialized"
@@ -8676,10 +8727,6 @@ msgid "Stage All"
msgstr "Διεξαγωγή Όλων"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "ΠÏοσθέστε ένα μήνυμα δέσμευσης"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Αλλαγές Δέσμευσης"
@@ -10065,6 +10112,11 @@ msgid "Projects"
msgstr "ΈÏγα"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Ανάκτηση δεδοένων κατοπτÏισμοÏ, παÏακαλώ πεÏιμένετε..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Τελευταία ΤÏοποποιημένα"
@@ -10435,6 +10487,11 @@ msgstr "Αυτόματη φόÏτωση"
msgid "Plugins"
msgstr "ΠÏόσθετα"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "ΦόÏτωση Ï€Ïοεπιλογής"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "ΔιαμόÏφωση..."
@@ -10684,6 +10741,16 @@ msgid "Instance Child Scene"
msgstr "ΑÏχικοποίηση σκηνής ως παιδί"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Δεν είναι δυνατή η λειτουÏγία σε κόμβους από ξένη σκηνή!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Επικόλληση κόμβων"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "ΑποσÏνδεση Δέσμης ΕνεÏγειών"
@@ -10816,6 +10883,11 @@ msgid "Attach Script"
msgstr "ΣÏνδεση Δέσμης ΕνεÏγειών"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Αποκοπή κόμβων"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "ΑφαίÏεση κόμβων"
@@ -11625,6 +11697,39 @@ msgstr "ΦιλτÏάÏισμα πλεγμάτων"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "ΟÏίστε έναν πόÏο MeshLibrary στο GridMap για χÏήση των πλεγμάτων του."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "ΔημιουÏία AABB"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Κατευθήνσεις"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "Στοιχειοθέτηση Δεξιά"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "ΜετεπεξεÏγασία"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Τοποθέτηση φώτων:"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Το όνομα της κλάσης δεν μποÏεί να είναι λέξη-κλειδί"
@@ -12146,13 +12251,16 @@ msgid "Select device from the list"
msgstr "Επιλέξτε συσκευή από την λίστα"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
-"Το εκτελέσιμο αÏχείο ADB δεν έχει Ïυθμιστεί στις Ρυθμίσεις ΕπεξεÏγαστή."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "Το OpenJDK jarsigner δεν έχει Ïυθμιστεί στις Ρυθμίσεις ΕπεξεÏγαστή."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Λείπει το Ï€Ïότυπο δόμησης Android από το έÏγο. Εγκαταστήστε το από το Î¼ÎµÎ½Î¿Ï "
+"«ΈÏγο»."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12166,13 +12274,15 @@ msgstr ""
"Εσφαλμένη ÏÏθμιση αποθετηÏίου κλειδιών διανομής στην διαμόÏφωση εξαγωγής."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#, fuzzy
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"Η Ï€ÏοσαÏμοσμένη δόμηση απαιτεί μια έγκυÏη διαδÏομή για το Android SDK στις "
-"Ρυθμίσεις ΕπεξεÏγαστή."
+"Μη έγκυÏη διαδÏομή Android SDK για Ï€ÏοσαÏμοσμένη δόμηση στις Ρυθμίσεις "
+"ΕπεξεÏγαστή."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+#, fuzzy
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
"Μη έγκυÏη διαδÏομή Android SDK για Ï€ÏοσαÏμοσμένη δόμηση στις Ρυθμίσεις "
"ΕπεξεÏγαστή."
@@ -12182,12 +12292,23 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+#, fuzzy
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"Μη έγκυÏη διαδÏομή Android SDK για Ï€ÏοσαÏμοσμένη δόμηση στις Ρυθμίσεις "
+"ΕπεξεÏγαστή."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
-"Λείπει το Ï€Ïότυπο δόμησης Android από το έÏγο. Εγκαταστήστε το από το Î¼ÎµÎ½Î¿Ï "
-"«ΈÏγο»."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12445,6 +12566,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Ένα άδειο ColisionPollygon2D δεν επηÏεάζει τη σÏγκÏουση."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12657,28 +12786,32 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "Το ARVROrigin απαιτεί γονικό κόμβο ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(ΟλοκλήÏωση σε: %d:%02d s)"
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "Ανάλυση γεωμετÏίας..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Τοποθέτηση πλεγμάτων: "
+#, fuzzy
+msgid "Preparing environment"
+msgstr "Εμφάνιση πεÏιβάλλοντος"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Τοποθέτηση φώτων:"
+#, fuzzy
+msgid "Generating capture"
+msgstr "ΔημιουÏγία χαÏτών φωτός"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "ΟλοκλήÏωση σχεδιαγÏάμματος"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "ΔημιουÏγία χαÏτών φωτός"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Φώτηση πλεγμάτων: "
+msgid "Done"
+msgstr "Τέλος"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12757,6 +12890,10 @@ msgid "Plotting Meshes"
msgstr "Τοποθέτηση πλεγμάτων"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "ΟλοκλήÏωση σχεδιαγÏάμματος"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12764,11 +12901,6 @@ msgstr ""
"Τα GIProbes δεν υποστηÏίζονται από το Ï€ÏόγÏαμμα οδήγησης οθόνης GLES2.\n"
"Εναλλακτικά, χÏησιμοποιήστε ένα BakedLightmap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "Η InterpolatedCamera έχει καταÏγηθεί και θα αφαιÏεθεί στο Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -13016,6 +13148,15 @@ msgstr "Ειδοποίηση!"
msgid "Please Confirm..."
msgstr "ΠαÏακαλώ επιβεβαιώστε..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Απαιτείται η χÏήση έγκυÏης επέκτασης."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "ΕνεÏγοποίηση κουμπώματος"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13074,6 +13215,12 @@ msgstr ""
"απόδοση."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "ΆκυÏη πηγή για Ï€Ïοεπισκόπηση."
@@ -13101,6 +13248,51 @@ msgstr "Τα «varying» μποÏοÏν να ανατεθοÏν μόνο στηÎ
msgid "Constants cannot be modified."
msgstr "Οι σταθεÏές δεν μποÏοÏν να Ï„ÏοποποιηθοÏν."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "Η InterpolatedCamera έχει καταÏγηθεί και θα αφαιÏεθεί στο Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "Όχι"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr ""
+#~ "Αυτή η σκηνή δεν έχει αποθηκευτεί. Αποθήκευση Ï€Ïιν από την εκτέλεση;"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr ""
+#~ "Το εκτελέσιμο αÏχείο ADB δεν έχει Ïυθμιστεί στις Ρυθμίσεις ΕπεξεÏγαστή."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "Το OpenJDK jarsigner δεν έχει Ïυθμιστεί στις Ρυθμίσεις ΕπεξεÏγαστή."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Η Ï€ÏοσαÏμοσμένη δόμηση απαιτεί μια έγκυÏη διαδÏομή για το Android SDK "
+#~ "στις Ρυθμίσεις ΕπεξεÏγαστή."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(ΟλοκλήÏωση σε: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Τοποθέτηση πλεγμάτων: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Φώτηση πλεγμάτων: "
+
+#~ msgid "Search complete"
+#~ msgstr "ΟλοκλήÏωση αναζήτησης"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Κανένα δεσμευμένο μήνυμα δεν παÏασχέθηκε"
+
+#~ msgid "Add a commit message"
+#~ msgstr "ΠÏοσθέστε ένα μήνυμα δέσμευσης"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "ΥπάÏχει ήδη αÏχείο ή φάκελος με το ίδιο όνομα στη διαδÏομή."
@@ -13445,9 +13637,6 @@ msgstr "Οι σταθεÏές δεν μποÏοÏν να Ï„ÏοποποιηθοÏ
#~ msgid "Failed to save solution."
#~ msgstr "Απέτυχε η αποθήκευση της λÏσης."
-#~ msgid "Done"
-#~ msgstr "Τέλος"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Απέτυχε η δημιουÏγία έÏγου C#."
@@ -14892,9 +15081,6 @@ msgstr "Οι σταθεÏές δεν μποÏοÏν να Ï„ÏοποποιηθοÏ
#~ msgid "Use Default Light"
#~ msgstr "ΧÏήση Ï€Ïοεπιλεγμέου φωτός"
-#~ msgid "Use Default sRGB"
-#~ msgstr "ΧÏήση Ï€Ïοεπιλεγμένου sRGB"
-
#~ msgid "Default Light Normal:"
#~ msgstr "ΠÏοεπιλεγμένο διάνυσμα κανονικής ανάκλασης φωτός:"
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index c4b2e447f1..46e3a6b28d 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -1,6 +1,6 @@
# Esperanto translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Scott Starkey <yekrats@gmail.com>, 2019.
# AlexHoratio <yukithetupper@gmail.com>, 2019.
@@ -10,18 +10,19 @@
# Sr Half <flavio05@outlook.com>, 2020.
# Cristian Yepez <cristianyepez@gmail.com>, 2020.
# BinotaLIU <me@binota.org>, 2020.
+# Jakub Fabijan <animatorzPolski@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2020-11-20 23:08+0000\n"
-"Last-Translator: BinotaLIU <me@binota.org>\n"
+"PO-Revision-Date: 2021-02-21 10:51+0000\n"
+"Last-Translator: Jakub Fabijan <animatorzPolski@gmail.com>\n"
"Language-Team: Esperanto <https://hosted.weblate.org/projects/godot-engine/"
"godot/eo/>\n"
"Language: eo\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -646,14 +647,13 @@ msgstr "Elekti vojetojn por duplikati"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Duplikati"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select All/None"
-msgstr "Elektaro nur"
+msgstr "Elekti Ĉiuj/Neniuj"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
@@ -1836,8 +1836,8 @@ msgid "Open a File or Directory"
msgstr "Malfermi dosieron aÅ­ dosierujon"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Konservi"
@@ -1930,10 +1930,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2350,6 +2346,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2393,19 +2393,6 @@ msgstr "Radika nodo estas necesita por konservi la scenon."
msgid "Save Scene As..."
msgstr "Konservi sceno kiel..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Ne"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Jes"
-
-#: editor/editor_node.cpp
-#, fuzzy
-msgid "This scene has never been saved. Save before running?"
-msgstr "Ĉi tiu sceno konservis neniam. Konservi antaŭ ruli?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
#, fuzzy
msgid "This operation can't be done without a scene."
@@ -2458,6 +2445,10 @@ msgid "Quit"
msgstr "Foriri"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Jes"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Eliri la editilo?"
@@ -2500,7 +2491,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2920,14 +2911,6 @@ msgid "Help"
msgstr "Helpo"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Serĉo"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
msgid "Online Docs"
@@ -3084,6 +3067,22 @@ msgid "Open & Run a Script"
msgstr "Malfermi & ruli skripto"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3288,7 +3287,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3829,8 +3828,19 @@ msgid "Searching..."
msgstr "Serĉas..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Serĉo finiÄis"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "Trovis %d matĉo(j)n."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "Trovis %d matĉo(j)n."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Trovis %d matĉo(j)n."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -3969,6 +3979,20 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Selektu nodo(j)n por enporti"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Enporti"
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -4922,7 +4946,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5026,7 +5050,6 @@ msgid "Sort:"
msgstr "Ordigi:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5057,8 +5080,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5072,9 +5094,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6139,6 +6180,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6200,10 +6245,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6786,6 +6827,14 @@ msgstr ""
msgid "Run"
msgstr "Ruli"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Serĉo"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6838,16 +6887,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6940,8 +6979,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7163,6 +7202,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8378,10 +8421,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8443,10 +8482,6 @@ msgid "Stage All"
msgstr "Elektaro ĉiuj"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "ÅœanÄu"
@@ -9715,6 +9750,10 @@ msgid "Projects"
msgstr "Projektoj"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
#, fuzzy
msgid "Last Modified"
msgstr "Modifita"
@@ -10076,6 +10115,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Enporti dokon"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10320,6 +10364,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Skali Elektaron"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Krei skripton"
@@ -10444,6 +10497,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11236,6 +11293,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11741,11 +11826,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11757,11 +11844,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11769,9 +11856,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11997,6 +12094,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12163,27 +12268,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12243,14 +12348,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12456,6 +12560,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12497,6 +12609,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Nevalida fonto por ombrigilo."
@@ -12526,6 +12644,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstantoj ne povas esti modifitaj."
+#~ msgid "No"
+#~ msgstr "Ne"
+
+#, fuzzy
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Ĉi tiu sceno konservis neniam. Konservi antaŭ ruli?"
+
+#~ msgid "Search complete"
+#~ msgstr "Serĉo finiÄis"
+
#, fuzzy
#~ msgid "Default editor layout overridden."
#~ msgstr "Automatan aranÄon de editilo transpasis."
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 6920aa1bf7..85b79a7605 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -1,6 +1,6 @@
# Spanish translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Addiel Lucena Perez <addiell2017@gmail.com>, 2017.
# Aleix Sanchis <aleixsanchis@hotmail.com>, 2017, 2018.
@@ -14,11 +14,11 @@
# Diego López <diegodario21@gmail.com>, 2017.
# eon-s <emanuel.segretin@gmail.com>, 2018, 2019, 2020.
# Gustavo Leon <gleondiaz@gmail.com>, 2017-2018.
-# Javier Ocampos <xavier.ocampos@gmail.com>, 2018, 2019, 2020.
+# Javier Ocampos <xavier.ocampos@gmail.com>, 2018, 2019, 2020, 2021.
# Jose Maria Martinez <josemar1992@hotmail.com>, 2018.
# Juan Quiroga <juanquiroga9@gmail.com>, 2017.
# Kiji Pixel <raccoon.fella@gmail.com>, 2017.
-# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2017, 2019, 2020.
+# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2017, 2019, 2020, 2021.
# Lonsfor <lotharw@protonmail.com>, 2017-2018.
# Mario Nachbaur <manachbaur@gmail.com>, 2018.
# Oscar Carballal <oscar.carballal@protonmail.com>, 2017-2018.
@@ -55,12 +55,16 @@
# Skarline <lihue-molina@hotmail.com>, 2020.
# Oxixes <oxixes@protonmail.com>, 2020.
# David Aroca Rojas <arocarojasdavid@gmail.com>, 2020.
+# Ricardo Pérez <ricpelo@gmail.com>, 2021.
+# A <kaieltroll@gmail.com>, 2021.
+# Lucasdelpiero <lucasdelpiero98@gmail.com>, 2021.
+# SteamGoblin <SteamGoblin860@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-07 08:11+0000\n"
-"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n"
+"PO-Revision-Date: 2021-02-27 00:47+0000\n"
+"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -68,7 +72,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -574,7 +578,7 @@ msgstr "Agrupar las pistas por nodo o mostrarlas como una lista plana."
#: editor/animation_track_editor.cpp
msgid "Snap:"
-msgstr "Snap:"
+msgstr "Ajuste:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
@@ -704,7 +708,7 @@ msgstr "Selecciona las Pistas a Copiar"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Copiar"
@@ -1638,7 +1642,7 @@ msgid ""
"Etc' in Project Settings."
msgstr ""
"La plataforma de destino requiere compresión de texturas 'ETC' para GLES2. "
-"Activa 'Import Etc' en Ajustes del Proyecto."
+"Activa 'Import Etc' en Configuración del Proyecto."
#: editor/editor_export.cpp
msgid ""
@@ -1646,7 +1650,7 @@ msgid ""
"'Import Etc 2' in Project Settings."
msgstr ""
"La plataforma de destino requiere compresión de texturas 'ETC2' para GLES3. "
-"Activa 'Import Etc 2' en Ajustes del Proyecto."
+"Activa 'Import Etc 2' en Configuración del Proyecto."
#: editor/editor_export.cpp
msgid ""
@@ -1657,8 +1661,8 @@ msgid ""
msgstr ""
"La plataforma de destino requiere compresión de texturas 'ETC' para usar "
"GLES2 como controlador de respaldo.\n"
-"Activa 'Import Etc' en Ajustes del Proyecto, o desactiva 'Driver Fallback "
-"Enabled'."
+"Activa 'Import Etc' en Configuración del Proyecto, o desactiva 'Driver "
+"Fallback Enabled'."
#: editor/editor_export.cpp
msgid ""
@@ -1666,7 +1670,7 @@ msgid ""
"'Import Pvrtc' in Project Settings."
msgstr ""
"La plataforma de destino requiere compresión de texturas 'PVRTC' para GLES2. "
-"Activa 'Import Pvrtc' en Ajustes del Proyecto."
+"Activa 'Import Pvrtc' en Configuración del Proyecto."
#: editor/editor_export.cpp
msgid ""
@@ -1674,7 +1678,8 @@ msgid ""
"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
msgstr ""
"La plataforma de destino requiere compresión de texturas 'ETC2' o 'PVRTC' "
-"para GLES3. Activa 'Import Etc 2' o 'Import Pvrtc' en Ajustes del Proyecto."
+"para GLES3. Activa 'Import Etc 2' o 'Import Pvrtc' en Configuración del "
+"Proyecto."
#: editor/editor_export.cpp
msgid ""
@@ -1685,7 +1690,7 @@ msgid ""
msgstr ""
"La plataforma del objetivo requiere compresión de texturas 'PVRTC' para el "
"driver fallback de GLES2.\n"
-"Activa Import Pvrtc' en la Ajustes del Proyecto, o desactiva 'Driver "
+"Activa Import Pvrtc' en Configuración del Proyecto, o desactiva 'Driver "
"Fallback Enabled'."
#: editor/editor_export.cpp platform/android/export/export.cpp
@@ -1917,8 +1922,8 @@ msgid "Open a File or Directory"
msgstr "Abrir un archivo o directorio"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Guardar"
@@ -1989,7 +1994,7 @@ msgstr "Mostrar/Ocultar archivos ocultos."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
-msgstr "Ver ítems como un grid de miniaturas."
+msgstr "Ver ítems como una cuadrícula de miniaturas."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a list."
@@ -2009,10 +2014,6 @@ msgstr "Vista Previa:"
msgid "File:"
msgstr "Archivo:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Debe tener una extensión válida."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Escanear Fuentes"
@@ -2451,6 +2452,10 @@ msgid "There is no defined scene to run."
msgstr "No hay escena definida para ejecutar."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Guarda escena antes de ejecutar..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "¡No se pudo comenzar el subproceso!"
@@ -2494,19 +2499,6 @@ msgstr "Se necesita un nodo raíz para guardar la escena."
msgid "Save Scene As..."
msgstr "Guardar Escena Como..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "No"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Sí"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-"Esta escena nunca se ha guardado. ¿Quieres guardarla antes de ejecutarla?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Esta operación no puede realizarse sin una escena."
@@ -2557,6 +2549,10 @@ msgid "Quit"
msgstr "Salir"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Sí"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "¿Salir del editor?"
@@ -2605,10 +2601,8 @@ msgstr ""
"configuración de '%s'."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
-"No se pudo encontrar el campo del script para el plugin addon en: 'res://"
-"addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "No se pudo encontrar el campo script para el plugin de addon en: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2668,8 +2662,8 @@ msgid ""
"category."
msgstr ""
"No se ha definido ninguna escena principal, ¿seleccionar una?\n"
-"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categoría "
-"'application'."
+"Es posible cambiarla más tarde en \"Configuración del Proyecto\" bajo la "
+"categoría 'application'."
#: editor/editor_node.cpp
msgid ""
@@ -2678,8 +2672,8 @@ msgid ""
"category."
msgstr ""
"La escena seleccionada '%s' no existe, ¿seleccionar una válida?\n"
-"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categoría "
-"'application'."
+"Es posible cambiarla más tarde en \"Configuración del Proyecto\" bajo la "
+"categoría 'application'."
#: editor/editor_node.cpp
msgid ""
@@ -2689,8 +2683,8 @@ msgid ""
msgstr ""
"La escena '%s' seleccionada no es un archivo de escena, ¿seleccionar uno "
"válido?\n"
-"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categoría "
-"'application'."
+"Es posible cambiarla más tarde en \"Configuración del Proyecto\" bajo la "
+"categoría 'application'."
#: editor/editor_node.cpp
msgid "Save Layout"
@@ -2851,7 +2845,7 @@ msgstr "Proyecto"
#: editor/editor_node.cpp
msgid "Project Settings..."
-msgstr "Ajustes del Proyecto..."
+msgstr "Configuración del Proyecto..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
@@ -3045,14 +3039,6 @@ msgid "Help"
msgstr "Ayuda"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Buscar"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentación Online"
@@ -3220,6 +3206,24 @@ msgid "Open & Run a Script"
msgstr "Abrir y Ejecutar un Script"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Los siguientes archivos son nuevos en disco.\n"
+"¿Qué acción se debería tomar?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Recargar"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Volver a Guardar"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Nueva Escena Heredada"
@@ -3431,7 +3435,7 @@ msgstr "Hacer Único"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Pegar"
@@ -3796,6 +3800,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Los siguientes archivos o carpetas entran en conflicto con los elementos de "
+"la ubicación del objetivo '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"¿Deseas sobrescribirlos?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3956,7 +3966,7 @@ msgid ""
"ProjectSettings."
msgstr ""
"Incluye los archivos con las siguientes extensiones. Añádelos o elimínalos "
-"en Ajustes del proyecto."
+"en Configuración del Proyecto."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
@@ -3988,8 +3998,16 @@ msgid "Searching..."
msgstr "Buscando..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Búsqueda completa"
+msgid "%d match in %d file."
+msgstr "%d coincidencias en el archivo %d."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d coincidencias en el archivo %d."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d coincidencias en %d archivos."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4126,6 +4144,21 @@ msgstr "¿Devolviste un objeto derivado de Node en el método `post_import()`?"
msgid "Saving..."
msgstr "Guardando..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Modo de Selección"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importación"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Usar sRGB predeterminado"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d archivos"
@@ -4398,7 +4431,7 @@ msgstr "Seleccionar y mover puntos, crear puntos con clic derecho."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
msgid "Enable snap and show grid."
-msgstr "Activar snap y mostrar grid."
+msgstr "Activar ajuste y mostrar cuadrícula."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -5098,8 +5131,8 @@ msgid "Got:"
msgstr "Tiene:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Fallo en la comprobación del hash sha256"
+msgid "Failed SHA-256 hash check"
+msgstr "Fallo en la comprobación del hash SHA-256"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5202,7 +5235,6 @@ msgid "Sort:"
msgstr "Ordenar:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Categoría:"
@@ -5233,12 +5265,11 @@ msgstr "Archivo ZIP de elementos"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"No se puede encontrar una ruta válida para las imágenes \"lightmap\".\n"
-"Guarda la escena (para que las imágenes se guarden en el mismo directorio), "
-"o selecciona otra ruta desde las propiedades del \"BackedLightmap\"."
+"No se puede determinar una ruta de guardado para las imágenes de los "
+"lightmaps.\n"
+"Guarda tu escena e inténtalo de nuevo."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5255,9 +5286,34 @@ msgstr ""
"escribir en la ruta."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Falló al determinar el tamaño del lightmap ¿El tamaño máximo del lightmap es "
+"demasiado pequeño?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Alguna malla es inválida. Asegúrate de que los valores del canal de UV2 "
+"están contenidos dentro de la región cuadrangular [0,0,1,0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"El editor de Godot se construyó sin soporte de trazado de rayos, los "
+"lightmaps no pueden ser bakeados."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Bake Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Selecciona un archivo lightmap bakeado:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5265,15 +5321,15 @@ msgstr "Vista Previa"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
-msgstr "Configurar Snap"
+msgstr "Configurar Ajuste"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Offset:"
-msgstr "Grid Offset:"
+msgstr "Desplazamiento de Cuadrícula:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Step:"
-msgstr "Grid Step:"
+msgstr "Paso de Cuadrícula:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Primary Line Every:"
@@ -5437,11 +5493,11 @@ msgstr "Ancho Inferior"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "VCenter Wide"
-msgstr "Ancho Centro Vert."
+msgstr "Centro Vert. Ancho"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "HCenter Wide"
-msgstr "Ancho Centro Horiz."
+msgstr "Centro Horiz. Ancho"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Full Rect"
@@ -5601,48 +5657,48 @@ msgstr "Modo de Regla"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle smart snapping."
-msgstr "Alternar acople inteligente."
+msgstr "Act./Desact. ajuste inteligente."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Smart Snap"
-msgstr "Usar Snap Inteligente"
+msgstr "Usar Ajuste Inteligente"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle grid snapping."
-msgstr "Act./Desact. grid snapping."
+msgstr "Act./Desact. ajuste de cuadrícula."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Grid Snap"
-msgstr "Usar Grid Snap"
+msgstr "Usar Ajuste de Cuadrícula"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snapping Options"
-msgstr "Opciones de Snapping"
+msgstr "Opciones de Ajuste"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Rotation Snap"
-msgstr "Usar Snap de Rotación"
+msgstr "Usar Ajuste de Rotación"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Scale Snap"
-msgstr "Usar Snap de Escalado"
+msgstr "Usar Ajuste de Escalado"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
-msgstr "Snap Relativo"
+msgstr "Ajuste Relativo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Pixel Snap"
-msgstr "Usar Pixel Snap"
+msgstr "Usar Ajuste de Píxeles"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Smart Snapping"
-msgstr "Snapping Inteligente"
+msgstr "Ajuste Inteligente"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Configure Snap..."
-msgstr "Configurar Snap..."
+msgstr "Configurar Ajuste..."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
@@ -5711,7 +5767,7 @@ msgstr "Ver"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Always Show Grid"
-msgstr "Mostrar Siempre el Grid"
+msgstr "Mostrar Siempre la Cuadrícula"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
@@ -5800,11 +5856,11 @@ msgstr "Limpiar Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Multiply grid step by 2"
-msgstr "Multiplicar grid step por 2"
+msgstr "Multiplicar paso de cuadrícula por 2"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Divide grid step by 2"
-msgstr "Dividir grid step por 2"
+msgstr "Dividir paso de cuadrícula por 2"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Pan View"
@@ -6360,6 +6416,10 @@ msgstr ""
"Solo se puede asignar un punto a un material de procesado ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Convertir a CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Tiempo de Generación (seg):"
@@ -6420,10 +6480,6 @@ msgstr "Generando AABB"
msgid "Generate Visibility AABB"
msgstr "Generar AABB de visibilidad"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Generar AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Borrar Punto de la Curva"
@@ -6721,43 +6777,43 @@ msgstr "Limpiar UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Settings"
-msgstr "Configuración del Grid"
+msgstr "Configuración de la Cuadrícula"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Snap"
-msgstr "Snap"
+msgstr "Ajuste"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Enable Snap"
-msgstr "Activar Snap"
+msgstr "Activar Ajuste"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid"
-msgstr "Grid"
+msgstr "Cuadrícula"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Show Grid"
-msgstr "Ver Grid"
+msgstr "Ver Cuadrícula"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Configure Grid:"
-msgstr "Configurar Grid:"
+msgstr "Configurar Cuadrícula:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset X:"
-msgstr "Grid Offset X:"
+msgstr "Desplazamiento de Cuadrícula en X:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset Y:"
-msgstr "Grid Offset Y:"
+msgstr "Desplazamiento de Cuadrícula en Y:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Step X:"
-msgstr "Grid Step X:"
+msgstr "Paso de Cuadrícula en X:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Step Y:"
-msgstr "Grid Step Y:"
+msgstr "Paso de Cuadrícula en Y:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Sync Bones to Polygon"
@@ -7015,6 +7071,14 @@ msgstr "Cerrar Documentación"
msgid "Run"
msgstr "Ejecutar"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Buscar"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Entrar En"
@@ -7068,16 +7132,6 @@ msgstr ""
"Los siguientes archivos son nuevos en disco.\n"
"¿Qué es lo que quieres hacer?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Recargar"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Volver a Guardar"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Depurador"
@@ -7173,8 +7227,8 @@ msgstr "Breakpoints"
msgid "Go To"
msgstr "Ir A"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Cortar"
@@ -7394,7 +7448,11 @@ msgstr "Altura"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Yaw"
-msgstr "Yaw"
+msgstr "Guiñada"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Tamaño"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
@@ -7720,7 +7778,7 @@ msgstr "Ver Origen"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Grid"
-msgstr "Ver Grid"
+msgstr "Ver Cuadrícula"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
@@ -7729,19 +7787,19 @@ msgstr "Configuración..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
-msgstr "Ajustes de Snap"
+msgstr "Configuración de Ajuste"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate Snap:"
-msgstr "Snap de Traslación:"
+msgstr "Ajuste de Traslación:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Snap (deg.):"
-msgstr "Snap de Rotación (grados):"
+msgstr "Ajuste de Rotación (grados):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Snap (%):"
-msgstr "Snap de Escala (%):"
+msgstr "Ajuste de Escala (%):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Viewport Settings"
@@ -8010,7 +8068,7 @@ msgstr "Asignar Margen"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
-msgstr "Modo Snap:"
+msgstr "Modo de Ajuste:"
#: editor/plugins/texture_region_editor_plugin.cpp
#: scene/resources/visual_shader.cpp
@@ -8019,11 +8077,11 @@ msgstr "Ninguno"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Pixel Snap"
-msgstr "Pixel Snap"
+msgstr "Ajuste de Píxeles"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Grid Snap"
-msgstr "Grid Snap"
+msgstr "Ajuste de Cuadrícula"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Auto Slice"
@@ -8441,7 +8499,8 @@ msgstr "Mantener el polígono dentro del region Rect."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
-msgstr "Activar snap y mostrar grid (configurable a través del Inspector)."
+msgstr ""
+"Activar ajuste y mostrar cuadrícula (configurable a través del Inspector)."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Display Tile Names (Hold Alt Key)"
@@ -8643,10 +8702,6 @@ msgid "Error"
msgstr "Error"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "No se indicó ningún mensaje de confirmación"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "No se agregaron archivos al stage"
@@ -8703,10 +8758,6 @@ msgid "Stage All"
msgstr "Hacer Staging de Todo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Añadir un mensaje de confirmación"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Confirmar Cambios"
@@ -9640,7 +9691,7 @@ msgid ""
msgstr ""
"No se pudo exportar el proyecto para la plataforma '%s'.\n"
"Esto puede ser debido a un problema de configuración en el preset de "
-"exportación o en los ajustes de exportación."
+"exportación o en la configuración de exportación."
#: editor/project_export.cpp
msgid "Release"
@@ -9738,7 +9789,7 @@ msgstr "Script"
#: editor/project_export.cpp
msgid "Script Export Mode:"
-msgstr "Modo de Exportación de Scipts:"
+msgstr "Modo de exportación de scripts:"
#: editor/project_export.cpp
msgid "Text"
@@ -9917,7 +9968,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "No es soportado por los controladores de tu GPU."
#: editor/project_manager.cpp
msgid ""
@@ -10030,8 +10081,8 @@ msgid ""
"the \"Application\" category."
msgstr ""
"No se puede ejecutar el proyecto: no hay una escena principal definida.\n"
-"Por favor, edita el proyecto y configura la escena principal en los Ajustes "
-"del proyecto, en la categoría \"Application\"."
+"Por favor, edita el proyecto y configura la escena principal en "
+"Configuración del Proyecto, en la categoría \"Application\"."
#: editor/project_manager.cpp
msgid ""
@@ -10097,6 +10148,10 @@ msgid "Projects"
msgstr "Proyectos"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Cargando, espera por favor..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Ultima Modificación"
@@ -10373,7 +10428,7 @@ msgstr "Cambiar Modo de Filtro Local"
#: editor/project_settings_editor.cpp
msgid "Project Settings (project.godot)"
-msgstr "Ajustes del Proyecto (project.godot)"
+msgstr "Configuración del Proyecto (project.godot)"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
@@ -10467,6 +10522,11 @@ msgstr "AutoLoad"
msgid "Plugins"
msgstr "Plugins"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Cargar Valores por Defecto"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Preset..."
@@ -10717,6 +10777,14 @@ msgid "Instance Child Scene"
msgstr "Instanciar Escena Hija"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "No se puede pegar el nodo raíz en la misma escena."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Pegar Nodo(s)"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Sustraer Script"
@@ -10844,6 +10912,10 @@ msgid "Attach Script"
msgstr "Añadir Script"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Cortar Nodos(s)"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Eliminar Nodo(s)"
@@ -11552,7 +11624,7 @@ msgstr "Plano:"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Delete Selection"
-msgstr "GridMap Eliminar Seleccionados"
+msgstr "Eliminar Selección de GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Fill Selection"
@@ -11560,7 +11632,7 @@ msgstr "Rellenar Selección en GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Paste Selection"
-msgstr "Pegar lo Seleccionado en GridMap"
+msgstr "Pegar Selección en GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Paint"
@@ -11568,7 +11640,7 @@ msgstr "Pintar GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Grid Map"
-msgstr "Grid Map"
+msgstr "Mapeo de Cuadrícula"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Snap View"
@@ -11655,6 +11727,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
"Proporciona un recurso MeshLibrary a este GridMap para usar sus mallas."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Empezar a Bakear"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Preparar estructuras de datos"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Generar buffers"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Iluminación directa"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Iluminación indirecta"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Post procesado"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Trazar lightmaps"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "El nombre de la clase no puede ser una palabra reservada"
@@ -11677,7 +11777,7 @@ msgstr "Estableciendo la configuración..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Calculating grid size..."
-msgstr "Calculando tamaño de grid..."
+msgstr "Calculando tamaño la cuadrícula..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Creating heightfield..."
@@ -12173,12 +12273,16 @@ msgid "Select device from the list"
msgstr "Seleccionar dispositivo de la lista"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Ejecutable ADB no configurado en Configuración del Editor."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "No se pudo encontrar la herramienta 'apksigner'."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner no configurado en Configuración del Editor."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"La plantilla de exportación de Android no esta instalada en el proyecto. "
+"Instalala desde el menú de Proyecto."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12192,28 +12296,40 @@ msgstr ""
"exportación."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"La compilación personalizada requiere una ruta de Android SDK válida en "
-"Configuración del Editor."
+"Se requiere una ruta válida del SDK de Android en la Configuración del "
+"Editor."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Ruta del SDK de Android inválida para la compilación personalizada en "
-"Configuración del Editor."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Ruta del SDK de Android inválida en la Configuración del Editor."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "¡No se encontró el directorio 'platform-tools'!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
msgstr ""
-"La plantilla de exportación de Android no esta instalada en el proyecto. "
-"Instalala desde el menú de Proyecto."
+"No se pudo encontrar el comando adb de las herramientas de la plataforma SDK "
+"de Android."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"Por favor, comprueba el directorio del SDK de Android especificado en la "
+"Configuración del Editor."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "¡No se encontró el directorio 'build-tools'!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+"No se pudo encontrar el comando apksigner de las herramientas de "
+"construcción del SDK de Android."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12486,6 +12602,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Un CollisionPolygon2D vacío no tiene ningún efecto en las colisiones."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12523,23 +12647,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "El nodo A y el nodo B deben ser PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "El nodo A debe ser un PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "El nodo B debe ser un PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "La unión no está conectada a dos PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "El Nodo A y el Nodo B deben ser diferentes PhysicsBody2D"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12698,28 +12822,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin requiere un nodo hijo ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Encontrando mallas y luces"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Tiempo restante: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Preparando geometría (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Trazando Mallas: "
+msgid "Preparing environment"
+msgstr "Preparar entorno"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Trazando Iluminación:"
+msgid "Generating capture"
+msgstr "Generar captura"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Finalizar Trazado"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Guardar lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Iluminación de Mallas: "
+msgid "Done"
+msgstr "Hecho"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12795,6 +12919,10 @@ msgid "Plotting Meshes"
msgstr "Trazando Mallas"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Finalizar Trazado"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12802,11 +12930,6 @@ msgstr ""
"Las GIProbes no están soportadas por el controlador de vídeo GLES2.\n"
"Usa un BakedLightmap en su lugar."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera ha sido desaprobado y será eliminado en Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12877,23 +13000,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "El nodo A y el nodo B deben ser PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "El nodo A debe ser un PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "El nodo B debe ser un PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "La unión no está conectada a ningún PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "El nodo A y el nodo B deben ser diferentes PhysicsBody"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -13057,6 +13180,14 @@ msgstr "¡Alerta!"
msgid "Please Confirm..."
msgstr "Por favor, Confirma..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Debe tener una extensión válida."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Activar minimapa de cuadrícula."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13090,7 +13221,7 @@ msgid ""
"Default Environment as specified in Project Settings (Rendering -> "
"Environment -> Default Environment) could not be loaded."
msgstr ""
-"El Entorno por Defecto como se especifica en los Ajustes del Proyecto "
+"El Entorno por Defecto como se especifica en Configuración del Proyecto "
"(Rendering -> Environment -> Default Environment) no se ha podido cargar."
#: scene/main/viewport.cpp
@@ -13113,6 +13244,14 @@ msgstr ""
"cosa."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"El puerto de muestreo está conectado, pero no se utiliza. Considera la "
+"posibilidad de cambiar la fuente a \"SamplerPort\"."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fuente inválida para la vista previa."
@@ -13140,14 +13279,52 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "Ya hay un archivo o carpeta con el mismo nombre en esta ubicación."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "InterpolatedCamera ha sido desaprobado y será eliminado en Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "No"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr ""
+#~ "Esta escena nunca se ha guardado. ¿Quieres guardarla antes de ejecutarla?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "Ejecutable ADB no configurado en Configuración del Editor."
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "¡No se encontró el directorio 'build-tools'!"
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner no configurado en Configuración del Editor."
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "No se pudo encontrar la herramienta zipalign."
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "La compilación personalizada requiere una ruta de Android SDK válida en "
+#~ "Configuración del Editor."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Tiempo restante: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Trazando Mallas: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Iluminación de Mallas: "
+
+#~ msgid "Search complete"
+#~ msgstr "Búsqueda completa"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "No se indicó ningún mensaje de confirmación"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Añadir un mensaje de confirmación"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "Ya hay un archivo o carpeta con el mismo nombre en esta ubicación."
#~ msgid "Aligning APK..."
#~ msgstr "Alineando APK..."
@@ -13493,9 +13670,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Failed to save solution."
#~ msgstr "Fallo al guardar solución."
-#~ msgid "Done"
-#~ msgstr "Hecho"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Fallo al crear proyecto C#."
@@ -14994,9 +15168,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Use Default Light"
#~ msgstr "Usar iluminación predeterminada"
-#~ msgid "Use Default sRGB"
-#~ msgstr "Usar sRGB predeterminado"
-
#~ msgid "Default Light Normal:"
#~ msgstr "Iluminación por normales predeterminada:"
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 49b2358aed..5f9231e891 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -1,9 +1,9 @@
# Spanish (Argentina) translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Diego López <diegodario21@gmail.com>, 2017.
-# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2018, 2019, 2020.
+# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2018, 2019, 2020, 2021.
# Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018.
# Sebastian Silva <sebastian@sugarlabs.org>, 2016.
# Jose Luis Bossio <joseluisbossio@gmail.com>, 2018.
@@ -16,11 +16,12 @@
# Nicolas Zirulnik <nicolaszirulnik@gmail.com>, 2020.
# Cristian Yepez <cristianyepez@gmail.com>, 2020.
# Skarline <lihue-molina@hotmail.com>, 2020.
+# Joakker <joaquinandresleon108@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-07 08:11+0000\n"
+"PO-Revision-Date: 2021-02-27 00:47+0000\n"
"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n"
"Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/"
"godot-engine/godot/es_AR/>\n"
@@ -29,7 +30,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -663,7 +664,7 @@ msgstr "Elegir Pistas a Copiar"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Copiar"
@@ -1164,11 +1165,11 @@ msgstr "Autores"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
-msgstr "Sponsor Platino"
+msgstr "Sponsors Platino"
#: editor/editor_about.cpp
msgid "Gold Sponsors"
-msgstr "Sponsor Oro"
+msgstr "Sponsors Oro"
#: editor/editor_about.cpp
msgid "Silver Sponsors"
@@ -1631,7 +1632,8 @@ msgid ""
"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
msgstr ""
"La plataforma de destino requiere compresión de texturas 'ETC2' o 'PVRTC' "
-"para GLES3. Activá 'Import Etc 2' o 'Import Pvrtc' en Ajustes del Proyecto."
+"para GLES3. Activá 'Importar Etc 2' o 'Importar Pvrtc' en Ajustes del "
+"Proyecto."
#: editor/editor_export.cpp
msgid ""
@@ -1874,8 +1876,8 @@ msgid "Open a File or Directory"
msgstr "Abrir un Archivo o Directorio"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Guardar"
@@ -1966,10 +1968,6 @@ msgstr "Vista Previa:"
msgid "File:"
msgstr "Archivo:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Debe ser una extensión válida."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Escanear Fuentes"
@@ -2227,7 +2225,7 @@ msgstr "OK"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr "Error al guardar el recurso!"
+msgstr "¡Error al guardar el recurso!"
#: editor/editor_node.cpp
msgid ""
@@ -2260,7 +2258,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
-msgstr "Error parsear '%s'."
+msgstr "Error al parsear '%s'."
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
@@ -2409,6 +2407,10 @@ msgid "There is no defined scene to run."
msgstr "No hay escena definida para ejecutar."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Guardar escena antes de ejecutar..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "No se pudo comenzar el subproceso!"
@@ -2452,18 +2454,6 @@ msgstr "Se necesita un nodo raíz para guardar la escena."
msgid "Save Scene As..."
msgstr "Guardar Escena Como..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "No"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Si"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Esta escena nunca ha sido guardada. Guardar antes de ejecutar?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Esta operación no puede hacerse sin una escena."
@@ -2514,6 +2504,10 @@ msgid "Quit"
msgstr "Salir"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Si"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Salir del editor?"
@@ -2562,10 +2556,8 @@ msgstr ""
"configuración."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
-"No se pudo encontrar el campo script para el plugin de addon en: 'res://"
-"addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "No se pudo encontrar el campo script para el plugin de addon en: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2867,8 +2859,8 @@ msgstr ""
"Cuando esta opción está activada, al utilizar el deploy en un click, el "
"ejecutable intentará conectarse a la IP de este equipo para que el proyecto "
"en ejecución pueda ser depurado.\n"
-"Esta opción está pensada para ser usada en la depuración remota "
-"( normalmente con un dispositivo móvil).\n"
+"Esta opción está pensada para ser usada en la depuración remota (normalmente "
+"con un dispositivo móvil).\n"
"No es necesario habilitarla para usar el depurador GDScript localmente."
#: editor/editor_node.cpp
@@ -2889,7 +2881,7 @@ msgstr ""
"El sistema de archivos será proporcionado desde el proyecto por el editor a "
"través de la red.\n"
"En Android, el deploy usará el cable USB para un rendimiento más rápido. "
-"Esta opción acelera las pruebas de los proyectos con recursos grandes."
+"Esta opción acelera el testeo de los proyectos con recursos grandes."
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
@@ -3000,14 +2992,6 @@ msgid "Help"
msgstr "Ayuda"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Buscar"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentación Online"
@@ -3175,6 +3159,24 @@ msgid "Open & Run a Script"
msgstr "Abrir y Correr un Script"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Los siguientes archivos son nuevos en disco.\n"
+"¿Qué acción se debería tomar?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Volver a Cargar"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Volver a Guardar"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Nuevo Heredado"
@@ -3385,7 +3387,7 @@ msgstr "Convertir en Unico"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Pegar"
@@ -3549,7 +3551,7 @@ msgstr "Error al obtener la lista de mirrors."
#: editor/export_template_manager.cpp
msgid "Error parsing JSON of mirror list. Please report this issue!"
msgstr ""
-"Error al parsear el JSON de la lista de mirrors. Por favor reportá este "
+"Error al parsear el JSON de la lista de mirrors. ¡Por favor reportá este "
"problema!"
#: editor/export_template_manager.cpp
@@ -3750,6 +3752,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Los siguientes archivos o carpetas entran en conflicto con los elementos de "
+"la ubicación del objetivo '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"¿Querés sobrescribirlos?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3942,8 +3950,16 @@ msgid "Searching..."
msgstr "Buscando..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Búsqueda completa"
+msgid "%d match in %d file."
+msgstr "%d coincidencia en %d archivo."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d coincidencias en %d archivo."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d coincidencias en %d archivos."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4079,6 +4095,21 @@ msgstr "¿Devolviste un objeto derivado de Node en el método `post_import()`?"
msgid "Saving..."
msgstr "Guardando..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Modo Seleccionar"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importar"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Usar sRGB por Defecto"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Archivos"
@@ -5052,8 +5083,8 @@ msgid "Got:"
msgstr "Recibido:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Fallo el chequeo del hash sha256"
+msgid "Failed SHA-256 hash check"
+msgstr "Fallo el chequeo del hash SHA-256"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5156,7 +5187,6 @@ msgid "Sort:"
msgstr "Ordenar:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Categoría:"
@@ -5187,12 +5217,11 @@ msgstr "Archivo ZIP de Assets"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"No se pudo determinar una ruta de guardado para las imagenes de lightmap.\n"
-"Guardá tu escena (para imagenes a ser guardadas en el mismo directorio), o "
-"elegí una ruta de guardado desde las propiedades de BakedLightmap."
+"No se puede determinar una ruta de guardado para las imágenes de los "
+"lightmaps.\n"
+"Guardá tu escena e inténtalo de nuevo."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5209,9 +5238,34 @@ msgstr ""
"escritura."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Falló al determinar el tamaño del lightmap ¿El tamaño máximo de lightmap es "
+"demasiado pequeño?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Alguna malla es inválida. Asegurate de que los valores del canal UV2 estén "
+"contenidos dentro de la región cuadrada [0,0,1,0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"El editor de Godot se compiló sin soporte de ray tracing, los lightmaps no "
+"pueden ser bakeados."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Bake Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Selecciona un archivo de lightmap bakeado:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6308,6 +6362,10 @@ msgstr ""
"Solo se puede setear un punto en un material de proceso ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Convertir a CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Tiempo de Generación (seg):"
@@ -6368,10 +6426,6 @@ msgstr "Generando AABB"
msgid "Generate Visibility AABB"
msgstr "Generar AABB de Visibilidad"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Generar AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Remover Punto de Curva"
@@ -6963,6 +7017,14 @@ msgstr "Cerrar Docs"
msgid "Run"
msgstr "Ejecutar"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Buscar"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Step Into"
@@ -7016,16 +7078,6 @@ msgstr ""
"Los siguientes archivos son nuevos en disco.\n"
"¿Qué acción se debería tomar?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Volver a Cargar"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Volver a Guardar"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Depurador"
@@ -7121,8 +7173,8 @@ msgstr "Puntos de interrupción"
msgid "Go To"
msgstr "Ir A"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Cortar"
@@ -7345,6 +7397,10 @@ msgid "Yaw"
msgstr "Yaw"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Tamaño"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objetos Dibujados"
@@ -8589,10 +8645,6 @@ msgid "Error"
msgstr "Error"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "No se indicó ningún mensaje de commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "No se agregaron archivos al stage"
@@ -8649,10 +8701,6 @@ msgid "Stage All"
msgstr "Hacer Staging de Todo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Agregar mensaje de commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Commitear Cambios"
@@ -9863,7 +9911,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "No soportado por tus drivers de GPU."
#: editor/project_manager.cpp
msgid ""
@@ -10044,6 +10092,10 @@ msgid "Projects"
msgstr "Proyectos"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Cargando, esperá, por favor..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Ultima Modificación"
@@ -10414,6 +10466,11 @@ msgstr "AutoLoad"
msgid "Plugins"
msgstr "Plugins"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Cargar Valores por Defecto"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Preseteo..."
@@ -10664,6 +10721,14 @@ msgid "Instance Child Scene"
msgstr "Instanciar Escena Hija"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "No se puede pegar el nodo raiz en la misma escena."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Pegar Nodo(s)"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Desasignar Script"
@@ -10792,6 +10857,10 @@ msgid "Attach Script"
msgstr "Adjuntar Script"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Cortar Nodo(s)"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Quitar Nodo(s)"
@@ -11601,6 +11670,34 @@ msgstr "Filtrar meshes"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "Asignar un recurso MeshLibrary a este GridMap para usar sus meshes."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Iniciar Bake"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Preparando estructuras de datos"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Generar buffers"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Iluminación directa"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Iluminación indirecta"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Post procesado"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Trazando lightmatps"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "El nombre de la clase no puede ser una palabra reservada"
@@ -12118,12 +12215,16 @@ msgid "Select device from the list"
msgstr "Seleccionar dispositivo de la lista"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Ejecutable ADB no configurado en Configuración del Editor."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "No se pudo encontrar la herramienta 'apksigner'."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner no configurado en Configuración del Editor."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"La plantilla de exportación de Android no esta instalada en el proyecto. "
+"Instalala desde el menú de Proyecto."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12137,28 +12238,36 @@ msgstr ""
"exportación."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"La compilación personalizada requiere una ruta de Android SDK válida en "
-"Configuración del Editor."
+"Se requiere una ruta válida al SDK de Android en la Configuración del Editor."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Ruta del SDK de Android inválida para la compilación personalizada en "
-"Configuración del Editor."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Ruta del SDK de Android inválida en la Configuración del Editor."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "¡No se encontró el directorio 'platform-tools'!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "No se pudo encontrar el comando adb en las Android SDK platform-tools."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
msgstr ""
-"La plantilla de exportación de Android no esta instalada en el proyecto. "
-"Instalala desde el menú de Proyecto."
+"Por favor, comprueba el directorio del SDK de Android especificado en la "
+"Configuración del Editor."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "¡No se encontró el directorio 'build-tools'!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+"No se pudo encontrar el comando apksigner en las Android SDK build-tools."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12333,7 +12442,7 @@ msgstr "Nombre único de paquete inválido."
#: platform/uwp/export/export.cpp
msgid "Invalid package publisher display name."
-msgstr "Nombre de paquete de publisher inválido."
+msgstr "Nombre de paquete de editor inválido."
#: platform/uwp/export/export.cpp
msgid "Invalid product GUID."
@@ -12428,6 +12537,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Un CollisionPolygon2D vacío no tiene efecto en la colisión."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12465,23 +12582,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "El nodo A y el nodo B deben ser PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "El nodo A debe ser un PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "El nodo B debe ser un PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "La unión no está conectada a dos PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "El Nodo A y el Nodo B deben ser diferentes PhysicsBody2D"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12640,28 +12757,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin requiere un nodo hijo ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Encontrar mallas y luces"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Tiempo Restante: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Preparando geometría (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Trazando Meshes: "
+msgid "Preparing environment"
+msgstr "Preparando entorno"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Trazando Luces:"
+msgid "Generating capture"
+msgstr "Generando capturas"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Finalizar Trazado"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Guardando lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Iluminando Meshes: "
+msgid "Done"
+msgstr "Hecho"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12737,6 +12854,10 @@ msgid "Plotting Meshes"
msgstr "Trazando Meshes"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Finalizar Trazado"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12744,11 +12865,6 @@ msgstr ""
"Las GIProbes no están soportadas por el controlador de video GLES2.\n"
"Usá un BakedLightmap en su lugar."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera ha sido deprecado y será eliminado en Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12817,23 +12933,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "El nodo A y el nodo B deben ser PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "El nodo A debe ser un PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "El nodo B debe ser un PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "La unión no está conectada a ningún PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "El nodo A y el nodo B deben ser diferentes PhysicsBody"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12997,6 +13113,14 @@ msgstr "Alerta!"
msgid "Please Confirm..."
msgstr "Confirmá, por favor..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Debe ser una extensión válida."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Activar minimapa de grilla."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13050,6 +13174,14 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "El tamaño del viewport debe ser mayor a 0 para poder renderizar."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"El puerto de muestreo está conectado, pero no se utiliza. Considerá la "
+"posibilidad de cambiar la fuente a \"SamplerPort\"."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fuente inválida para la vista previa."
@@ -13077,6 +13209,48 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice."
msgid "Constants cannot be modified."
msgstr "Las constantes no pueden modificarse."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "InterpolatedCamera ha sido deprecado y será eliminado en Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "No"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Esta escena nunca ha sido guardada. Guardar antes de ejecutar?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "Ejecutable ADB no configurado en Configuración del Editor."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner no configurado en Configuración del Editor."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "La compilación personalizada requiere una ruta de Android SDK válida en "
+#~ "Configuración del Editor."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Tiempo Restante: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Trazando Meshes: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Iluminando Meshes: "
+
+#~ msgid "Search complete"
+#~ msgstr "Búsqueda completa"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "No se indicó ningún mensaje de commit"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Agregar mensaje de commit"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Ya hay un archivo o carpeta con el mismo nombre en esta ubicación."
@@ -13417,9 +13591,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Failed to save solution."
#~ msgstr "No se pudo guardar la solución."
-#~ msgid "Done"
-#~ msgstr "Hecho"
-
#~ msgid "Failed to create C# project."
#~ msgstr "No se pudo crear el proyecto en C#"
@@ -14710,9 +14881,6 @@ msgstr "Las constantes no pueden modificarse."
#~ msgid "Use Default Light"
#~ msgstr "Usar Luz por Defecto"
-#~ msgid "Use Default sRGB"
-#~ msgstr "Usar sRGB por Defecto"
-
#~ msgid "Default Light Normal:"
#~ msgstr "Normales de Luces por Defecto:"
diff --git a/editor/translations/et.po b/editor/translations/et.po
index 9ede0a7465..ba7272db84 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -1,23 +1,24 @@
# Estonian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Jens <arrkiin@gmail.com>, 2019.
# Mattias Aabmets <mattias.aabmets@gmail.com>, 2019.
-# StReef <streef.gtx@gmail.com>, 2020.
+# StReef <streef.gtx@gmail.com>, 2020, 2021.
# René <renepiik@gmail.com>, 2020.
+# Kritzmensch <streef.gtx@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2020-12-02 09:52+0000\n"
-"Last-Translator: StReef <streef.gtx@gmail.com>\n"
+"PO-Revision-Date: 2021-03-07 06:04+0000\n"
+"Last-Translator: Kritzmensch <streef.gtx@gmail.com>\n"
"Language-Team: Estonian <https://hosted.weblate.org/projects/godot-engine/"
"godot/et/>\n"
"Language: et\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -634,7 +635,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopeeri"
@@ -696,7 +697,7 @@ msgstr ""
#: editor/code_editor.cpp
msgid "Replace"
-msgstr ""
+msgstr "Asenda"
#: editor/code_editor.cpp
msgid "Replace All"
@@ -813,7 +814,7 @@ msgstr ""
#: editor/connections_dialog.cpp
msgid "Oneshot"
-msgstr ""
+msgstr "Ainulaadne"
#: editor/connections_dialog.cpp
msgid "Disconnects the signal after its first emission."
@@ -839,7 +840,7 @@ msgstr "Sulge"
#: editor/connections_dialog.cpp
msgid "Connect"
-msgstr ""
+msgstr "Ühenda"
#: editor/connections_dialog.cpp
msgid "Signal:"
@@ -859,12 +860,12 @@ msgstr ""
#: editor/connections_dialog.cpp
msgid "Connect..."
-msgstr ""
+msgstr "Ühenda..."
#: editor/connections_dialog.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Disconnect"
-msgstr ""
+msgstr "Katkesta ühendus"
#: editor/connections_dialog.cpp
msgid "Connect a Signal to a Method"
@@ -897,7 +898,7 @@ msgstr ""
#: editor/connections_dialog.cpp
msgid "Edit..."
-msgstr ""
+msgstr "Muuda..."
#: editor/connections_dialog.cpp
msgid "Go To Method"
@@ -909,7 +910,7 @@ msgstr ""
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
msgid "Change"
-msgstr ""
+msgstr "Muuda"
#: editor/create_dialog.cpp
msgid "Create New %s"
@@ -967,20 +968,20 @@ msgstr ""
#: editor/dependency_editor.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Dependencies"
-msgstr ""
+msgstr "Sõltuvused"
#: editor/dependency_editor.cpp
msgid "Resource"
-msgstr ""
+msgstr "Ressurss"
#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
#: editor/project_manager.cpp editor/project_settings_editor.cpp
msgid "Path"
-msgstr ""
+msgstr "Tee"
#: editor/dependency_editor.cpp
msgid "Dependencies:"
-msgstr ""
+msgstr "Sõltuvused:"
#: editor/dependency_editor.cpp
msgid "Fix Broken"
@@ -1126,14 +1127,12 @@ msgid "Gold Sponsors"
msgstr "Kuldsponsorid"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Silver Sponsors"
-msgstr "Hõbennetajad"
+msgstr "Hõbesponsorid"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Bronze Sponsors"
-msgstr "Pronksannetajad"
+msgstr "Pronkssponsorid"
#: editor/editor_about.cpp
msgid "Mini Sponsors"
@@ -1214,7 +1213,7 @@ msgstr ""
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Success!"
-msgstr ""
+msgstr "Õnnestus!"
#: editor/editor_asset_installer.cpp
msgid "Package Contents:"
@@ -1222,7 +1221,7 @@ msgstr ""
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
-msgstr ""
+msgstr "Paigalda"
#: editor/editor_asset_installer.cpp
msgid "Package Installer"
@@ -1278,15 +1277,15 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Solo"
-msgstr ""
+msgstr "Soolo"
#: editor/editor_audio_buses.cpp
msgid "Mute"
-msgstr ""
+msgstr "Vaigista"
#: editor/editor_audio_buses.cpp
msgid "Bypass"
-msgstr ""
+msgstr "Jäta vahele"
#: editor/editor_audio_buses.cpp
msgid "Bus options"
@@ -1299,7 +1298,7 @@ msgstr "Duplikeeri"
#: editor/editor_audio_buses.cpp
msgid "Reset Volume"
-msgstr ""
+msgstr "Lähtesta valjus"
#: editor/editor_audio_buses.cpp
msgid "Delete Effect"
@@ -1307,7 +1306,7 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Audio"
-msgstr ""
+msgstr "Heli"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
@@ -1327,7 +1326,7 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
-msgstr ""
+msgstr "Lähtesta siini valjus"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
@@ -1633,7 +1632,7 @@ msgstr "Skriptiredaktor"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr ""
+msgstr "Vadade kogum"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
@@ -1808,7 +1807,7 @@ msgstr "Värskenda"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
-msgstr ""
+msgstr "Kõik tuvastatud"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
@@ -1831,8 +1830,8 @@ msgid "Open a File or Directory"
msgstr "Ava kaust või kataloog"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Salvesta"
@@ -1895,11 +1894,11 @@ msgstr "Värskenda faile."
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
-msgstr ""
+msgstr "Lisa praegune kaust lemmikute sekka."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Toggle the visibility of hidden files."
-msgstr ""
+msgstr "Näita peidetud faile."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -1923,10 +1922,6 @@ msgstr "Eelvaade:"
msgid "File:"
msgstr "Fail:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Peab kasutama kehtivat laiendit."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2176,7 +2171,7 @@ msgstr "Imporditud ressursse ei saa salvestada."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
msgid "OK"
-msgstr ""
+msgstr "Olgu"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
@@ -2337,6 +2332,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2380,25 +2379,13 @@ msgstr ""
msgid "Save Scene As..."
msgstr "Salvesta stseen kui..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr ""
+msgstr "Ekspordi võrgu kogum"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
@@ -2439,6 +2426,10 @@ msgid "Quit"
msgstr "Välju"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Jah"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Välju redaktorist?"
@@ -2481,8 +2472,9 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "Lisa-skripti ei olnud võimalik laadida teelt: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2745,7 +2737,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Quit to Project List"
-msgstr ""
+msgstr "Välju ja kuva projektide loetelu"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
@@ -2801,9 +2793,8 @@ msgid ""
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Synchronize Scene Changes"
-msgstr "Pinna muutused"
+msgstr "Sünkroniseeri stseeni muudatused"
#: editor/editor_node.cpp
msgid ""
@@ -2879,14 +2870,6 @@ msgid "Help"
msgstr "Abi"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Otsi"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Veebidokumentatsioonid"
@@ -3033,13 +3016,29 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Merge With Existing"
-msgstr ""
+msgstr "Liida olemasolevaga"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3049,7 +3048,7 @@ msgstr "Laadimisvead"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
msgid "Select"
-msgstr ""
+msgstr "Vali"
#: editor/editor_node.cpp
msgid "Open 2D Editor"
@@ -3089,7 +3088,7 @@ msgstr ""
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
-msgstr ""
+msgstr "Pisipilt..."
#: editor/editor_plugin_settings.cpp
msgid "Main Script:"
@@ -3146,7 +3145,7 @@ msgstr ""
#: editor/editor_profiler.cpp
msgid "Inclusive"
-msgstr ""
+msgstr "Kaasav"
#: editor/editor_profiler.cpp
msgid "Self"
@@ -3170,11 +3169,11 @@ msgstr ""
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
-msgstr ""
+msgstr "Sees"
#: editor/editor_properties.cpp
msgid "Layer"
-msgstr ""
+msgstr "Kiht"
#: editor/editor_properties.cpp
msgid "Bit %d, value %d"
@@ -3182,11 +3181,11 @@ msgstr ""
#: editor/editor_properties.cpp
msgid "[Empty]"
-msgstr ""
+msgstr "[Tühi]"
#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
msgid "Assign..."
-msgstr ""
+msgstr "Määra..."
#: editor/editor_properties.cpp
msgid "Invalid RID"
@@ -3242,9 +3241,9 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
-msgstr ""
+msgstr "Kleebi"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Convert To %s"
@@ -3256,7 +3255,7 @@ msgstr ""
#: editor/editor_properties_array_dict.cpp
msgid "Size: "
-msgstr ""
+msgstr "Suurus: "
#: editor/editor_properties_array_dict.cpp
msgid "Page: "
@@ -3324,7 +3323,7 @@ msgstr ""
#: editor/editor_sub_scene.cpp
msgid "Scene Path:"
-msgstr ""
+msgstr "Stseeni tee:"
#: editor/editor_sub_scene.cpp
msgid "Import From Node:"
@@ -3340,7 +3339,7 @@ msgstr ""
#: editor/export_template_manager.cpp
msgid "(Installed)"
-msgstr ""
+msgstr "(Paigaldatud)"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -3353,11 +3352,11 @@ msgstr ""
#: editor/export_template_manager.cpp
msgid "(Missing)"
-msgstr ""
+msgstr "(Puudub)"
#: editor/export_template_manager.cpp
msgid "(Current)"
-msgstr ""
+msgstr "(Praegune)"
#: editor/export_template_manager.cpp
msgid "Retrieving mirrors, please wait..."
@@ -3478,7 +3477,7 @@ msgstr ""
#: editor/export_template_manager.cpp
msgid "Connected"
-msgstr ""
+msgstr "Ühendatud"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -3539,7 +3538,7 @@ msgstr ""
#: editor/filesystem_dock.cpp
msgid "Favorites"
-msgstr ""
+msgstr "Lemmikud"
#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
@@ -3778,7 +3777,15 @@ msgid "Searching..."
msgstr "Otsin..."
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3915,6 +3922,21 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Valimisrežiim"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Impordi"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Laadi vaikimisi"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4862,7 +4884,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4955,7 +4977,7 @@ msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Import..."
-msgstr ""
+msgstr "Impordi..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Plugins..."
@@ -4966,7 +4988,6 @@ msgid "Sort:"
msgstr "Sordi:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategooria:"
@@ -4997,8 +5018,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5012,9 +5032,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6070,6 +6109,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6130,10 +6173,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6715,13 +6754,21 @@ msgstr ""
msgid "Run"
msgstr "Käivita"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Otsi"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
-msgstr ""
+msgstr "Trepi sissepoole"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Over"
-msgstr ""
+msgstr "Trepi üle"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Break"
@@ -6766,16 +6813,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Siluja"
@@ -6861,15 +6898,15 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
msgid "Breakpoints"
-msgstr ""
+msgstr "Katkepunktid"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -6969,19 +7006,19 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Toggle Breakpoint"
-msgstr ""
+msgstr "Lülita katkepunkt sisse/välja"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Breakpoints"
-msgstr ""
+msgstr "Eemalda kõik katkepunktid"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Next Breakpoint"
-msgstr ""
+msgstr "Liigu järgmise katkepunkti juurde"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Previous Breakpoint"
-msgstr ""
+msgstr "Naase eelmise katkepunkti juurde"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -7090,6 +7127,10 @@ msgid "Yaw"
msgstr "Sagitaal"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objekte kuvatud"
@@ -7179,7 +7220,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
-msgstr ""
+msgstr "Lukusta vaateakna pöördenurk"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Normal"
@@ -7267,7 +7308,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Rotation Locked"
-msgstr ""
+msgstr "Vaateakna pöördenurk on lukustatud"
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -8303,10 +8344,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8365,10 +8402,6 @@ msgid "Stage All"
msgstr "Vali Kõik"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9571,12 +9604,17 @@ msgid ""
"Please edit the project and set the main scene in the Project Settings under "
"the \"Application\" category."
msgstr ""
+"Projekti ei saa käivitada: peastseeni ei ole määratud.\n"
+"Redigeerige project.godot faili ja määrake projekti peastseen \"application"
+"\" alajaotuses."
#: editor/project_manager.cpp
msgid ""
"Can't run project: Assets need to be imported.\n"
"Please edit the project to trigger the initial import."
msgstr ""
+"Projekti ei saa käivitada: varad tuleb importida.\n"
+"Redigeerige projekti käivitama algset importimise protsessi."
#: editor/project_manager.cpp
msgid "Are you sure to run %d projects at once?"
@@ -9622,6 +9660,10 @@ msgid "Projects"
msgstr "Projektid"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9639,7 +9681,7 @@ msgstr "Uus projekt"
#: editor/project_manager.cpp
msgid "Remove Missing"
-msgstr ""
+msgstr "Eemalda puuduvad"
#: editor/project_manager.cpp
msgid "Templates"
@@ -9651,7 +9693,7 @@ msgstr ""
#: editor/project_manager.cpp
msgid "Can't run project"
-msgstr ""
+msgstr "Projekti ei saa käivitada"
#: editor/project_manager.cpp
msgid ""
@@ -9982,6 +10024,11 @@ msgstr ""
msgid "Plugins"
msgstr "Pistikprogrammid"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Laadi vaikimisi"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10225,6 +10272,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Kustuta sõlm(ed)"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10346,6 +10402,11 @@ msgid "Attach Script"
msgstr "Manusta skript"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Kustuta sõlm(ed)"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -10724,7 +10785,7 @@ msgstr "Videomälu"
#: editor/script_editor_debugger.cpp
msgid "Skip Breakpoints"
-msgstr ""
+msgstr "Jäta katkepunktid vahele"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
@@ -10740,11 +10801,11 @@ msgstr "Virnakaadrid"
#: editor/script_editor_debugger.cpp
msgid "Profiler"
-msgstr ""
+msgstr "Profileerija"
#: editor/script_editor_debugger.cpp
msgid "Network Profiler"
-msgstr ""
+msgstr "Võrgu profileerija"
#: editor/script_editor_debugger.cpp
msgid "Monitor"
@@ -10780,7 +10841,7 @@ msgstr "Ressursi tee"
#: editor/script_editor_debugger.cpp
msgid "Type"
-msgstr ""
+msgstr "Tüüp"
#: editor/script_editor_debugger.cpp
msgid "Format"
@@ -10813,7 +10874,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
#, fuzzy
msgid "Export measures as CSV"
-msgstr "Ekspordi mõõtmed/meetmed CSV-vormingus"
+msgstr "Ekspordi mõõtmed CSV-vormingus"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
@@ -11131,6 +11192,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11275,7 +11364,7 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
-msgstr ""
+msgstr "Signaalid:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Create a new signal."
@@ -11626,11 +11715,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11642,11 +11733,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11654,9 +11745,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11881,6 +11982,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12047,27 +12156,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr ""
+#, fuzzy
+msgid "Preparing environment"
+msgstr "Kuva keskkond"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12127,14 +12237,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12334,12 +12443,20 @@ msgstr ""
#: scene/gui/dialogs.cpp
msgid "Alert!"
-msgstr ""
+msgstr "Tähelepanu!"
#: scene/gui/dialogs.cpp
msgid "Please Confirm..."
msgstr "Palun kinnita..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Peab kasutama kehtivat laiendit."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12360,7 +12477,7 @@ msgstr ""
#: scene/gui/tree.cpp
msgid "(Other)"
-msgstr ""
+msgstr "(Muu)"
#: scene/main/scene_tree.cpp
msgid ""
@@ -12381,6 +12498,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "Vaateakne suurus peab olema suurem kui 0, et kuvada."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Vigane eelvaate lähe."
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index e27515849d..95e87167e5 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -1,6 +1,6 @@
# Basque translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Julen Irazoki <rktzbkr.julen@gmail.com>, 2019.
# Osoitz <oelkoro@gmail.com>, 2019, 2020.
@@ -626,7 +626,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1804,8 +1804,8 @@ msgid "Open a File or Directory"
msgstr "Ireki fitxategia edo direktorioa"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Gorde"
@@ -1896,10 +1896,6 @@ msgstr "Aurrebista:"
msgid "File:"
msgstr "Fitxategia:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Baliozko luzapena erabili behar du."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2303,6 +2299,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2346,18 +2346,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2406,6 +2394,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2448,7 +2440,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2838,14 +2830,6 @@ msgid "Help"
msgstr "Laguntza"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Bilatu"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Lineako dokumentuak"
@@ -2999,6 +2983,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3201,7 +3201,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3741,7 +3741,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3878,6 +3886,20 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Hautatu inportatu nahi dituzun nodoak"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Inportatu azala"
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d fitxategi"
@@ -4827,7 +4849,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4931,7 +4953,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4962,8 +4983,7 @@ msgstr "Aktiboen ZIP fitxategia"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4977,9 +4997,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Hautatu txantiloi fitxategia"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6035,6 +6075,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6095,10 +6139,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6680,6 +6720,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Bilatu"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6731,16 +6779,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6833,8 +6871,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7055,6 +7093,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8268,10 +8310,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8328,10 +8366,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9587,6 +9621,13 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr ""
+"Fitxategiak arakatzen,\n"
+"Itxaron mesedez..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9949,6 +9990,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Inportatu profila(k)"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10193,6 +10239,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Scripta"
@@ -10314,6 +10368,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11100,6 +11158,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11595,11 +11681,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11611,11 +11699,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11623,9 +11711,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11850,6 +11948,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12016,27 +12122,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12096,14 +12202,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12309,6 +12414,15 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Baliozko luzapena erabili behar du."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "Gaitu atxikitzea"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12350,6 +12464,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/extract.py b/editor/translations/extract.py
index 93124ec30c..8702ac664c 100755
--- a/editor/translations/extract.py
+++ b/editor/translations/extract.py
@@ -36,8 +36,8 @@ unique_loc = {}
ctx_group = {} # Store msgctx, msg, and locations.
main_po = """
# LANGUAGE translation of the Godot Engine editor.
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index f7bef53811..910212f856 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -1,6 +1,6 @@
# Persian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# alabd14313 <alabd14313@yahoo.com>, 2016.
# Dante Marshal <Marshal.Devilhunter@gmail.com>, 2018.
@@ -658,7 +658,7 @@ msgstr "انتخاب میسرها جهت تکثیر"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "کپی"
@@ -1846,8 +1846,8 @@ msgid "Open a File or Directory"
msgstr "یک پرونده یا پوشه را باز کن"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "ذخیره"
@@ -1938,10 +1938,6 @@ msgstr ""
msgid "File:"
msgstr "پرونده:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "باید یک پسوند معتبر بکار گیرید."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2345,6 +2341,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2388,18 +2388,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr "ذخیره صحنه در ..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "نه"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "بله"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "این صحنه هرگز ذخیره نشده است. ذخیره قبل از اجرا؟"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "این عملیات بدون یک صحنه انجام نمی شود."
@@ -2447,6 +2435,10 @@ msgid "Quit"
msgstr "خروج"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "بله"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "خروج از ویرایشگر؟"
@@ -2489,8 +2481,9 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "امکان بارگیری اسکریپت Ø§ÙØ²ÙˆÙ†Ù‡ از مسیر وجود ندارد: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2887,14 +2880,6 @@ msgid "Help"
msgstr "راهنما"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "جستجو"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3054,6 +3039,23 @@ msgid "Open & Run a Script"
msgstr "گشودن و اجرای یک اسکریپت"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr "استخراج پرونده های زیر از بسته بندی انجام نشد:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "وارث جدید"
@@ -3266,7 +3268,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "چسباندن"
@@ -3847,8 +3849,18 @@ msgstr "جستجو"
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "جستجوی متن"
+msgid "%d match in %d file."
+msgstr "%d هم‌خوانی."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d هم‌خوانی."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d هم‌خوانی."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -3989,6 +4001,21 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "انتخاب حالت"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "وارد کردن"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "بارگیری پیش ÙØ±Ø¶"
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -5001,7 +5028,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5113,7 +5140,6 @@ msgid "Sort:"
msgstr "مرتب‌سازی:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "طبقه‌بندی:"
@@ -5146,8 +5172,7 @@ msgstr "ÙØ§ÛŒÙ„ های ZIP‌ منابع بازی"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5161,9 +5186,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "انتخاب پرونده قالب"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6270,6 +6315,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "اتصال به گره:"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6330,10 +6380,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6952,6 +6998,14 @@ msgstr ""
msgid "Run"
msgstr "اجرا"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "جستجو"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7006,16 +7060,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7116,8 +7160,8 @@ msgstr "حذ٠کن"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "برش"
@@ -7357,6 +7401,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8665,10 +8713,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8733,10 +8777,6 @@ msgid "Stage All"
msgstr "انتخاب همه"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "تغییر بده"
@@ -10045,6 +10085,11 @@ msgid "Projects"
msgstr "طرح ها"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "بارگیری"
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10423,6 +10468,11 @@ msgstr "AutoLoad"
msgid "Plugins"
msgstr "Ø§ÙØ²ÙˆÙ†Ù‡â€ŒÙ‡Ø§"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "بارگیری پیش ÙØ±Ø¶"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10681,6 +10731,15 @@ msgid "Instance Child Scene"
msgstr "ارث‌بری صحنهٔ ÙØ±Ø²Ù†Ø¯"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "مسیر به سمت گره:"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "پیوست کردن اسکریپت"
@@ -10812,6 +10871,11 @@ msgid "Attach Script"
msgstr "پیوست کردن اسکریپت"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "ساختن گره"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "حذ٠گره(ها)"
@@ -11663,6 +11727,36 @@ msgstr "حالت صاÙÛŒ:"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "توضیح"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "انتقال را در انیمیشن تغییر بده"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12202,11 +12296,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12218,11 +12314,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12230,9 +12326,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12482,6 +12588,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "یک CollisionPolygon2D خالی جلوه بر برخورد ندارد."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12672,27 +12786,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12763,14 +12877,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12994,6 +13107,14 @@ msgstr "هشدار!"
msgid "Please Confirm..."
msgstr "Ù„Ø·ÙØ§Ù‹ تأیید کنید…"
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "باید یک پسوند معتبر بکار گیرید."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
#, fuzzy
msgid ""
@@ -13043,6 +13164,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "اندازهٔ قلم نامعتبر."
@@ -13073,6 +13200,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "ثوابت قابل تغییر نیستند."
+#~ msgid "No"
+#~ msgstr "نه"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "این صحنه هرگز ذخیره نشده است. ذخیره قبل از اجرا؟"
+
+#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "جستجوی متن"
+
#, fuzzy
#~ msgid "Move pivot"
#~ msgstr "برداشتن نقطه"
@@ -13266,10 +13403,6 @@ msgstr "ثوابت قابل تغییر نیستند."
#~ msgstr "ساختن پوشه"
#, fuzzy
-#~ msgid "Custom Node"
-#~ msgstr "ساختن گره"
-
-#, fuzzy
#~ msgid "Invalid Path"
#~ msgstr "مسیر نامعتبر."
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index 7a47df373d..36e6c631be 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -1,6 +1,6 @@
# Finnish translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# basse <basse@roiske.org>, 2017.
# Bastian Salmela <bastian.salmela@gmail.com>, 2017, 2018.
@@ -8,14 +8,14 @@
# Jarmo Riikonen <amatrelan@gmail.com>, 2017.
# Nuutti Varvikko <nvarvikko@gmail.com>, 2018.
# Sami Lehtilä <sami.lehtila@gmail.com>, 2018.
-# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020.
+# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020, 2021.
# Tuomas Lähteenmäki <lahtis@gmail.com>, 2019.
# Matti Niskanen <matti.t.niskanen@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-29 08:29+0000\n"
+"PO-Revision-Date: 2021-02-27 00:47+0000\n"
"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n"
"Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/"
"godot/fi/>\n"
@@ -24,7 +24,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -648,7 +648,7 @@ msgstr "Valitse kopioitavat raidat"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopioi"
@@ -1857,8 +1857,8 @@ msgid "Open a File or Directory"
msgstr "Avaa tiedosto tai hakemisto"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Tallenna"
@@ -1949,10 +1949,6 @@ msgstr "Esikatselu:"
msgid "File:"
msgstr "Tiedosto:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Käytä sopivaa tiedostopäätettä."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Selaa lähdetiedostoja"
@@ -2387,6 +2383,10 @@ msgid "There is no defined scene to run."
msgstr "Suoritettavaa skeneä ei ole määritetty."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Tallenna skene ennen ajamista..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Aliprosessia ei voitu käynnistää!"
@@ -2430,18 +2430,6 @@ msgstr "Skenen tallentaminen edellyttää, että sillä on juurisolmu."
msgid "Save Scene As..."
msgstr "Tallenna skene nimellä..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Ei"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Kyllä"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Tätä skeneä ei ole koskaan tallennettu. Tallenna ennen suorittamista?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Tätä toimintoa ei voi tehdä ilman skeneä."
@@ -2492,6 +2480,10 @@ msgid "Quit"
msgstr "Lopeta"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Kyllä"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Poistu editorista?"
@@ -2538,8 +2530,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "Lisäosan '%s' aktivointi epäonnistui, virheellinen asetustiedosto."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr "Skriptikenttää ei löytynyt lisäosan tiedostosta: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "Skriptikenttää ei löytynyt lisäosan tiedostosta: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2965,14 +2957,6 @@ msgid "Help"
msgstr "Ohje"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Hae"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Dokumentaatio"
@@ -3137,6 +3121,24 @@ msgid "Open & Run a Script"
msgstr "Avaa ja suorita skripti"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Seuraavat tiedostot ovat uudempia levyllä.\n"
+"Mikä toimenpide tulisi suorittaa?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Lataa uudelleen"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Tallenna uudelleen"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Uusi peritty skene"
@@ -3348,7 +3350,7 @@ msgstr "Tee yksilölliseksi"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Liitä"
@@ -3708,6 +3710,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Seuraavat tiedostot tai kansiot ovat ristiriidassa kohdesijainnissa '%s' "
+"olevien kanssa:\n"
+"\n"
+"%s\n"
+"\n"
+"Haluatko ylikirjoittaa ne?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3900,8 +3908,16 @@ msgid "Searching..."
msgstr "Haetaan..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Haku valmis"
+msgid "%d match in %d file."
+msgstr "%d osuma %d tiedostossa."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d osumaa %d tiedostossa."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d osumaa %d tiedostossa."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4039,6 +4055,21 @@ msgstr ""
msgid "Saving..."
msgstr "Tallennetaan..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Valintatila"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Tuonti"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Lataa oletus"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d tiedostoa"
@@ -5008,8 +5039,8 @@ msgid "Got:"
msgstr "Saatiin:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "sha256-hajautusarvon tarkistus epäonnistui"
+msgid "Failed SHA-256 hash check"
+msgstr "SHA-256 hajautusarvon tarkistus epäonnistui"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5112,7 +5143,6 @@ msgid "Sort:"
msgstr "Lajittele:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategoria:"
@@ -5143,12 +5173,10 @@ msgstr "Assettien zip-tiedosto"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Lightmap-kuvien tallennuspolun määrittäminen ei onnistu.\n"
-"Tallenna skenesi (jotta kuvat tallentuisivat samaan hakemistoon), tai "
-"valitse tallennuspolku BakedLightmapin asetuksista."
+"Tallenna skenesi ja yritä uudelleen."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5165,9 +5193,34 @@ msgstr ""
"kirjoituskelpoinen."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Lightmapin koon määrittäminen epäonnistui. Suurin lightmapin koko liian "
+"pieni?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Jokin mesh on virheellinen. Varmista, että UV2-kanavan arvot ovat [0.0, 1.0] "
+"välisen neliön alueella."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Godot-editori on käännetty ilman ray tracing -tukea, joten lightmappeja ei "
+"voi kehittää."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Kehitä Lightmapit"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Valitse lightmapin kehitystiedosto:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6262,6 +6315,10 @@ msgstr ""
"Piste voidaan asettaa ainoastaan ParticlesMaterial käsittelyn materiaaliin"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Muunna CPUParticles2D solmuksi"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Luontiaika (s):"
@@ -6322,10 +6379,6 @@ msgstr "Luodaan AABB"
msgid "Generate Visibility AABB"
msgstr "Kartoita näkyvä alue"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Luo AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Poista pisteet käyrästä"
@@ -6917,6 +6970,14 @@ msgstr "Sulje dokumentaatio"
msgid "Run"
msgstr "Suorita"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Hae"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Siirry sisään"
@@ -6970,16 +7031,6 @@ msgstr ""
"Seuraavat tiedostot ovat uudempia levyllä.\n"
"Mikä toimenpide tulisi suorittaa?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Lataa uudelleen"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Tallenna uudelleen"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Debuggeri"
@@ -7074,8 +7125,8 @@ msgstr "Keskeytyskohdat"
msgid "Go To"
msgstr "Mene"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Leikkaa"
@@ -7298,6 +7349,10 @@ msgid "Yaw"
msgstr "Käännös (yaw)"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Koko"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objekteja piirretty"
@@ -8544,10 +8599,6 @@ msgid "Error"
msgstr "Virhe"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Muutosviestiä ei annettu"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Tiedostoja ei ole lisätty valmisteluun"
@@ -8604,10 +8655,6 @@ msgid "Stage All"
msgstr "Valmistele kaikki"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Lisää muutosviesti"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Vahvista muutokset"
@@ -9812,7 +9859,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Ei ole tuettu asennettujen GPU-ajureiden kanssa."
#: editor/project_manager.cpp
msgid ""
@@ -9988,6 +10035,10 @@ msgid "Projects"
msgstr "Projektit"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Ladataan, hetkinen..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Viimeksi muutettu"
@@ -10357,6 +10408,11 @@ msgstr "Automaattilataus"
msgid "Plugins"
msgstr "Liitännäiset"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Lataa oletus"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Esiasetus..."
@@ -10606,6 +10662,14 @@ msgid "Instance Child Scene"
msgstr "Luo aliskenen ilmentymä"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "Juurisolmua ei voida liittää samaan skeneen."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Liitä solmu(t)"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Irrota skripti"
@@ -10735,6 +10799,10 @@ msgid "Attach Script"
msgstr "Liitä skripti"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Leikkaa solmu(t)"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Poista solmu(t)"
@@ -11545,6 +11613,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
"Anna MeshLibrary resurssi tälle GridMap solmulle käyttääksesi sen meshejä."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Aloita kehitys"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Valmistellaan tietorakenteita"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Luo puskurit"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Suora valaistus"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Epäsuora valaistus"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Jälkikäsittely"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Piirretään lightmappeja"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Luokan nimi ei voi olla varattu avainsana"
@@ -12057,12 +12153,16 @@ msgid "Select device from the list"
msgstr "Valitse laite listasta"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "ADB käynnistystiedostoa ei ole määritetty editorin asetuksissa."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "'apksigner' työkalua ei löydy."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner ei ole määritettynä editorin asetuksissa."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Android-käännösmallia ei ole asennettu projektiin. Asenna se Projekti-"
+"valikosta."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12074,28 +12174,33 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "Release keystore on konfiguroitu väärin viennin esiasetuksissa."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr ""
-"Mukautettu käännös edellyttää kelvollista Android SDK -polkua editorin "
-"asetuksissa."
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "Editorin asetuksiin tarvitaan kelvollinen Android SDK -polku."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Virheellinen Android SDK -polku mukautettu käännöstä varten editorin "
-"asetuksissa."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Editorin asetuksissa on virheellinen Android SDK -polku."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "'platform-tools' hakemisto puuttuu!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "Android SDK platform-tools adb-komentoa ei löydy."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
msgstr ""
-"Android-käännösmallia ei ole asennettu projektiin. Asenna se Projekti-"
-"valikosta."
+"Ole hyvä ja tarkista editorin asetuksissa määritelty Android SDK -hakemisto."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "'build-tools' hakemisto puuttuu!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "Android SDK build-tools apksigner-komentoa ei löydy."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12358,6 +12463,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Tyhjällä CollisionPolygon2D solmulla ei ole vaikutusta törmäyksessä."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12395,23 +12508,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Solmujen A ja B tulee olla PhysicsBody2D tyyppisiä"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Solmun A tulee olla PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Solmun B tulee olla PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Liitos ei ole yhdistetty kahteen PhysicsBody2D solmuun"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Solmujen A ja B tulee olla eri PhysicsBody2D solmut"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12568,28 +12681,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin solmu tarvitsee ARVRCamera alisolmun."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Etsitään meshejä ja valoja"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Aikaa jäljellä: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Valmistellaan geometriaa (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Piirretään meshejä: "
+msgid "Preparing environment"
+msgstr "Valmistellaan ympäristöä"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Piirretään valoja:"
+msgid "Generating capture"
+msgstr "Luodaan kaappausta"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Viimeistellään piirto"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Tallennetaan lightmappeja"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Valaistaan meshejä: "
+msgid "Done"
+msgstr "Valmis"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12665,6 +12778,10 @@ msgid "Plotting Meshes"
msgstr "Piirretään meshejä"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Viimeistellään piirto"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12672,11 +12789,6 @@ msgstr ""
"GIProbe ei ole tuettu GLES2 näyttöajurissa.\n"
"Käytä sen sijaan BakedLightmap resurssia."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera on vanhentunut ja poistetaan Godot 4.0 versiossa."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12745,23 +12857,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Solmujen A ja B tulee olla PhysicsBody tyyppisiä"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Solmun A tulee olla PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Solmun B tulee olla PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Liitos ei ole yhdistetty mihinkään PhysicsBody solmuun"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Solmujen A ja B tulee olla eri PhysicsBody solmut"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12923,6 +13035,14 @@ msgstr "Huomio!"
msgid "Please Confirm..."
msgstr "Ole hyvä ja vahvista..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Käytä sopivaa tiedostopäätettä."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Käytä ruudukon pienoiskarttaa."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12977,6 +13097,14 @@ msgstr ""
"Näyttöruudun koko on oltava suurempi kuin 0, jotta mitään renderöidään."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"Näytteistysportti on yhdistetty mutta ei käytössä. Harkitse lähteen "
+"vaihtamista 'SamplerPort' asetukseen."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Virheellinen lähde esikatselulle."
@@ -13004,14 +13132,52 @@ msgstr "Varying tyypin voi sijoittaa vain vertex-funktiossa."
msgid "Constants cannot be modified."
msgstr "Vakioita ei voi muokata."
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "Tästä sijainnista löytyy jo samanniminen tiedosto tai kansio."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "InterpolatedCamera on vanhentunut ja poistetaan Godot 4.0 versiossa."
+
+#~ msgid "No"
+#~ msgstr "Ei"
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "'build-tools' hakemisto puuttuu!"
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr ""
+#~ "Tätä skeneä ei ole koskaan tallennettu. Tallenna ennen suorittamista?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "ADB käynnistystiedostoa ei ole määritetty editorin asetuksissa."
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "zipalign työkalua ei löydy."
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner ei ole määritettynä editorin asetuksissa."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Mukautettu käännös edellyttää kelvollista Android SDK -polkua editorin "
+#~ "asetuksissa."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Aikaa jäljellä: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Piirretään meshejä: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Valaistaan meshejä: "
+
+#~ msgid "Search complete"
+#~ msgstr "Haku valmis"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Muutosviestiä ei annettu"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Lisää muutosviesti"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "Tästä sijainnista löytyy jo samanniminen tiedosto tai kansio."
#~ msgid "Aligning APK..."
#~ msgstr "Tasataan APK:ta..."
@@ -13354,9 +13520,6 @@ msgstr "Vakioita ei voi muokata."
#~ msgid "Failed to save solution."
#~ msgstr "Ratkaisun tallennus epäonnistui."
-#~ msgid "Done"
-#~ msgstr "Valmis"
-
#~ msgid "Failed to create C# project."
#~ msgstr "C# projektin luonti epäonnistui."
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index c430475062..e9c24cf0f2 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -1,6 +1,6 @@
# Filipino translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Marco Santos <enum.scima@gmail.com>, 2019.
# Amado Wilkins <epicalert68@gmail.com>, 2019.
@@ -634,7 +634,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopya"
@@ -1804,8 +1804,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1896,10 +1896,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2304,6 +2300,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2347,18 +2347,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Hindi"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Oo"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2406,6 +2394,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Oo"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2448,7 +2440,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2838,14 +2830,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3000,6 +2984,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3203,7 +3203,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3739,7 +3739,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3876,6 +3884,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4824,7 +4844,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4928,7 +4948,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4959,8 +4978,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4974,9 +4992,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6035,6 +6072,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6095,10 +6136,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6681,6 +6718,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6732,16 +6777,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6834,8 +6869,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7056,6 +7091,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8269,10 +8308,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8330,10 +8365,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9588,6 +9619,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9948,6 +9983,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10192,6 +10231,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Burahin ang (mga) Napiling Key"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10312,6 +10360,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11098,6 +11150,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11596,11 +11676,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11612,11 +11694,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11624,9 +11706,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11851,6 +11943,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12017,27 +12117,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12097,14 +12197,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12310,6 +12409,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12351,6 +12458,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
@@ -12377,3 +12490,6 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
msgstr ""
+
+#~ msgid "No"
+#~ msgstr "Hindi"
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 3085e78d7b..7b9d411e6d 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -1,6 +1,6 @@
# French translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Antoine Carrier <ac.g392@gmail.com>, 2017-2018.
# ARocherVj <a.rocher.vj@gmail.com>, 2017.
@@ -69,7 +69,7 @@
# Sofiane <Sofiane-77@caramail.fr>, 2019.
# Camille Mohr-Daurat <pouleyketchoup@gmail.com>, 2019.
# Pierre Stempin <pierre.stempin@gmail.com>, 2019.
-# Pierre Caye <pierrecaye@laposte.net>, 2020.
+# Pierre Caye <pierrecaye@laposte.net>, 2020, 2021.
# Kevin Bouancheau <kevin.bouancheau@gmail.com>, 2020.
# LaurentOngaro <laurent@gameamea.com>, 2020.
# Julien Humbert <julroy67@gmail.com>, 2020.
@@ -77,12 +77,13 @@
# Léo Vincent <l009.vincent@gmail.com>, 2020.
# Joseph Boudou <joseph.boudou@matabio.net>, 2020.
# Vincent Foulon <vincent.foulon80@gmail.com>, 2020.
+# TechnoPorg <jonah.janzen@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-10 14:11+0100\n"
-"Last-Translator: Rémi Verschelde <akien@godotengine.org>\n"
+"PO-Revision-Date: 2021-01-22 10:21+0000\n"
+"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -90,7 +91,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Poedit 2.4.2\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -727,7 +728,7 @@ msgstr "Sélectionner les pistes à copier"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Copier"
@@ -1937,8 +1938,8 @@ msgid "Open a File or Directory"
msgstr "Ouvrir un fichier ou un répertoire"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Enregistrer"
@@ -2029,10 +2030,6 @@ msgstr "Aperçu :"
msgid "File:"
msgstr "Fichier :"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Utilisez une extension valide."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Scanner les sources"
@@ -2475,6 +2472,10 @@ msgid "There is no defined scene to run."
msgstr "Il n'y a pas de scène définie pour être lancée."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Enregistrer la scène avant de l'exécuter..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Impossible de démarrer le sous-processus !"
@@ -2518,19 +2519,6 @@ msgstr "Un nœud racine est nécessaire pour sauvegarder la scène."
msgid "Save Scene As..."
msgstr "Enregistrer la scène sous…"
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Non"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Oui"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-"Cette scène n'a jamais été enregistrée. L'enregistrer avant de la lancer ?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Cette opération ne peut être réalisée sans une scène."
@@ -2580,6 +2568,10 @@ msgid "Quit"
msgstr "Quitter"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Oui"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Quitter l'éditeur ?"
@@ -2627,14 +2619,12 @@ msgstr "Réouvrir la scène fermée"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
-"Impossible d'activer le greffon depuis : « %s », l’analyse syntaxique de la "
+"Impossible d'activer le plugin depuis : « %s », l’analyse syntaxique de la "
"configuration a échoué."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
-"Impossible de trouver le champ de script pour le plugin dans : « res://"
-"addons/%s »."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "Impossible de trouver le champ de script pour le plugin dans : « %s »."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -3073,14 +3063,6 @@ msgid "Help"
msgstr "Aide"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Rechercher"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentation en ligne"
@@ -3247,6 +3229,24 @@ msgid "Open & Run a Script"
msgstr "Ouvrir et exécuter un script"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Les fichiers suivants sont plus récents sur le disque.\n"
+"Quelle action doit être prise ?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Recharger"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Ré-enregistrer"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Nouveau hérité"
@@ -3458,7 +3458,7 @@ msgstr "Rendre unique"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Coller"
@@ -4021,8 +4021,16 @@ msgid "Searching..."
msgstr "Recherche…"
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Recherche terminée"
+msgid "%d match in %d file."
+msgstr "%d correspondance dans %d fichier."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d correspondances dans %d fichier."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d correspondances dans %d fichiers."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4159,17 +4167,29 @@ msgstr ""
msgid "Saving..."
msgstr "Enregistrement…"
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr "Sélectionnez un importeur"
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr "Importeur :"
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr "Réinitialiser"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d fichiers"
#: editor/import_dock.cpp
msgid "Set as Default for '%s'"
-msgstr "Définir comme défaut pour « %s »"
+msgstr "Définir comme préréglage pour « %s »"
#: editor/import_dock.cpp
msgid "Clear Default for '%s'"
-msgstr "Effacer le préréglage par défaut pour « %s »"
+msgstr "Effacer le préréglage pour « %s »"
#: editor/import_dock.cpp
msgid "Import As:"
@@ -4177,7 +4197,7 @@ msgstr "Importer comme :"
#: editor/import_dock.cpp
msgid "Preset"
-msgstr "Pré-réglage"
+msgstr "Préréglage"
#: editor/import_dock.cpp
msgid "Reimport"
@@ -4290,7 +4310,7 @@ msgstr "Modifier un plugin"
#: editor/plugin_config_dialog.cpp
msgid "Create a Plugin"
-msgstr "Créer un Plugin"
+msgstr "Créer un plugin"
#: editor/plugin_config_dialog.cpp
msgid "Plugin Name:"
@@ -5134,8 +5154,8 @@ msgid "Got:"
msgstr "A :"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Vérification de brouillage sha256 échouée"
+msgid "Failed SHA-256 hash check"
+msgstr "Vérification du hachage SHA-256 échouée"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5238,7 +5258,6 @@ msgid "Sort:"
msgstr "Trier :"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Catégorie :"
@@ -5269,13 +5288,10 @@ msgstr "Fichier ZIP de données"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"Ne peut pas déterminer un chemin de sauvegarde pour les images lightmap.\n"
-"Sauvegarder votre scène (pour que les images soient sauvegardées dans le "
-"même répertoire), ou choisissez un répertoire de sauvegarde à partir des "
-"propriétés BakedLightmap."
+"Impossible de déterminer un chemin de sauvegarde pour les images lightmap.\n"
+"Enregistrez votre scène et réessayez."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5292,9 +5308,34 @@ msgstr ""
"accessible en écriture."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Échec de la détermination de la taille de la lightmap. Taille maximale de "
+"lightmap trop petite ?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Un maillage n'est pas valide. Assurez-vous que les valeurs du canal UV2 sont "
+"contenues dans la région carrée [0.0,1.0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"L'éditeur Godot a été compilé sans support du ray tracing, les lightmaps ne "
+"peuvent pas être pré-calculées."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Précalculer les lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Sélectionnez le fichier de pré-calcul de lightmap :"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5999,7 +6040,7 @@ msgstr "Modifier la tangente de courbes"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Load Curve Preset"
-msgstr "Charger un pré-réglage de courbe"
+msgstr "Charger un préréglage de courbe"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Add Point"
@@ -6403,6 +6444,10 @@ msgstr ""
"Ne peut définir qu'un point dans un matériau de processus ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Convertir en CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Temps de Génération (sec) :"
@@ -6463,10 +6508,6 @@ msgstr "Générer AABB"
msgid "Generate Visibility AABB"
msgstr "Générer AABB de Visibilité"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Générer AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Supprimer Point de la Courbe"
@@ -7058,6 +7099,14 @@ msgstr "Fermer les documentations"
msgid "Run"
msgstr "Lancer"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Rechercher"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Rentrer"
@@ -7111,16 +7160,6 @@ msgstr ""
"Les fichiers suivants sont plus récents sur le disque.\n"
"Quelle action doit être prise ? :"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Recharger"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Ré-enregistrer"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Débogueur"
@@ -7217,8 +7256,8 @@ msgstr "Point d'arrêts"
msgid "Go To"
msgstr "Atteindre"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Couper"
@@ -7441,6 +7480,10 @@ msgid "Yaw"
msgstr "Lacet (hauteur)"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Taille"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objets dessinés"
@@ -8692,10 +8735,6 @@ msgid "Error"
msgstr "Erreur"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Aucun message de livraison n'a été fourni"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Aucun fichier à ajouter"
@@ -8752,10 +8791,6 @@ msgid "Stage All"
msgstr "Tout ajouter"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Ajouter un message de livraison"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Commiter les changements"
@@ -9675,7 +9710,7 @@ msgstr "Exécutable"
#: editor/project_export.cpp
msgid "Delete preset '%s'?"
-msgstr "Supprimer le pré-réglage « %s » ?"
+msgstr "Supprimer le préréglage « %s » ?"
#: editor/project_export.cpp
msgid ""
@@ -9713,7 +9748,7 @@ msgstr "Modèles d'exportation manquants ou corrompus pour cette plateforme :"
#: editor/project_export.cpp
msgid "Presets"
-msgstr "Pré-réglages"
+msgstr "Préréglages"
#: editor/project_export.cpp editor/project_settings_editor.cpp
msgid "Add..."
@@ -9724,9 +9759,9 @@ msgid ""
"If checked, the preset will be available for use in one-click deploy.\n"
"Only one preset per platform may be marked as runnable."
msgstr ""
-"Si cette option est activée, le pré-réglage sera disponible pour le "
+"Si cette option est activée, le préréglage sera disponible pour le "
"déploiement en un clic.\n"
-"Un seul pré-réglage par plateforme peut être marqué comme exécutable."
+"Un seul préréglage par plateforme peut être marqué comme exécutable."
#: editor/project_export.cpp
msgid "Export Path"
@@ -10152,6 +10187,10 @@ msgid "Projects"
msgstr "Projets"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Chargement en cours, veuillez patienter..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Dernière modification"
@@ -10522,9 +10561,13 @@ msgstr "AutoLoad"
msgid "Plugins"
msgstr "Extensions"
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr "Préréglage des importeurs"
+
#: editor/property_editor.cpp
msgid "Preset..."
-msgstr "Pré-réglage…"
+msgstr "Préréglage…"
#: editor/property_editor.cpp
msgid "Zero"
@@ -10771,6 +10814,14 @@ msgid "Instance Child Scene"
msgstr "Instancier une scène enfant"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "Impossible de copier le nœud racine dans la même scène."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Coller le(s) nœud(s)"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Détacher le script"
@@ -10897,6 +10948,10 @@ msgid "Attach Script"
msgstr "Attacher un script"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Couper le(s) nœud(s)"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Supprimer le(s) nœud(s)"
@@ -11709,6 +11764,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
"Donnez une ressource MeshLibrary à cette GridMap pour utiliser ses maillages."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Commencer le pré-calcul"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Préparation des structures de données"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Générer des tampons"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Éclairage direct"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Éclairage indirect"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Post-traitement"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Tracer des lightmaps"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Le nom de classe ne peut pas être un mot-clé réservé"
@@ -12230,13 +12313,16 @@ msgid "Select device from the list"
msgstr "Sélectionner appareil depuis la liste"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "L'exécutable ADB n'est pas configuré dans les Paramètres de l'éditeur."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Impossible de trouver l'outil 'apksigner'."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
-"Le jarsigner OpenJDK n'est pas configuré dans les Paramètres de l'éditeur."
+"Le modèle de compilation Android n'est pas installé dans le projet. "
+"Installez-le à partir du menu Projet."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12251,28 +12337,38 @@ msgstr ""
"d'exportation."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"La création d'une version personnalisée nécessite un chemin d'accès Android "
-"SDK valide dans les paramètres de l'éditeur."
+"Un chemin d'accès valide au SDK Android est requis dans les paramètres de "
+"l'éditeur."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
-"Chemin d'accès invalide au SDK Android pour le build custom dans les "
-"paramètres de l'éditeur."
+"Chemin d'accès invalide au SDK Android dans les paramètres de l'éditeur."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "Dossier « platform-tools » manquant !"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "Impossible de trouver la commande adb du SDK Android platform-tools."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
msgstr ""
-"Le modèle de compilation Android n'est pas installé dans le projet. "
-"Installez-le à partir du menu Projet."
+"Veuillez vérifier le répertoire du SDK Android spécifié dans les paramètres "
+"de l'éditeur."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "Dossier « build-tools » manquant !"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+"Impossible de trouver la commande apksigner du SDK Android build-tools."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12549,6 +12645,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Un CollisionPolygon2D vide n'a pas d'effet sur les collisions."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12598,11 +12702,11 @@ msgstr "Node B doit être un PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Le Joint n'est pas connecté à deux PhysicsBody2Ds"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A et Node B doivent être des PhysicsBody2D différents"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12766,28 +12870,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin requiert un nœud enfant ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Recherche de maillages et de lumières"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Temps restant : %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Préparation de la géométrie (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Tracer les maillages : "
+msgid "Preparing environment"
+msgstr "Préparation de l'environnement"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Tracer les lumières :"
+msgid "Generating capture"
+msgstr "Génération de capture"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Finalisation du tracer"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Enregistrement des lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Tracer les maillages : "
+msgid "Done"
+msgstr "Terminé"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12862,6 +12966,10 @@ msgid "Plotting Meshes"
msgstr "Tracer les maillages"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Finalisation du tracer"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12869,11 +12977,6 @@ msgstr ""
"Les GIProps ne sont pas supporter par le pilote de vidéos GLES2.\n"
"A la place utilisez une BakedLightMap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera a été déprécié et sera supprimé dans Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -13077,7 +13180,7 @@ msgid ""
msgstr ""
"Couleur : #%s\n"
"Clic gauche : Définir la couleur\n"
-"Clic droit : Supprimer le pré-réglage"
+"Clic droit : Supprimer le préréglage"
#: scene/gui/color_picker.cpp
msgid "Pick a color from the editor window."
@@ -13097,7 +13200,7 @@ msgstr "Alterner entre les valeurs hexadécimales ou brutes."
#: scene/gui/color_picker.cpp
msgid "Add current color as a preset."
-msgstr "Ajouter la couleur courante comme pré-réglage."
+msgstr "Ajouter la couleur courante comme préréglage."
#: scene/gui/container.cpp
msgid ""
@@ -13127,6 +13230,14 @@ msgstr "Alerte !"
msgid "Please Confirm..."
msgstr "Veuillez confirmer…"
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Utilisez une extension valide."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Activer l'alignement."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13184,6 +13295,14 @@ msgstr ""
"afficher quoi que ce soit."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"Le port de l'échantillonneur est connecté mais n'est pas utilisé. Pensez à "
+"changer la source en 'SamplerPort'."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Source invalide pour la prévisualisation."
@@ -13211,17 +13330,56 @@ msgstr "Les variations ne peuvent être affectées que dans la fonction vertex."
msgid "Constants cannot be modified."
msgstr "Les constantes ne peuvent être modifiées."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "InterpolatedCamera a été déprécié et sera supprimé dans Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "Non"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr ""
+#~ "Cette scène n'a jamais été enregistrée. L'enregistrer avant de la lancer ?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr ""
+#~ "L'exécutable ADB n'est pas configuré dans les Paramètres de l'éditeur."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr ""
+#~ "Le jarsigner OpenJDK n'est pas configuré dans les Paramètres de l'éditeur."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "La création d'une version personnalisée nécessite un chemin d'accès "
+#~ "Android SDK valide dans les paramètres de l'éditeur."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Temps restant : %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Tracer les maillages : "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Tracer les maillages : "
+
+#~ msgid "Search complete"
+#~ msgstr "Recherche terminée"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Aucun message de livraison n'a été fourni"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Ajouter un message de livraison"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr ""
#~ "Il existe déjà un fichier ou un dossier ayant le même nom à cet "
#~ "emplacement."
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "Dossier « build-tools » manquant !"
-
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "Impossible de trouver l'outil zipalign."
-
#~ msgid "Aligning APK..."
#~ msgstr "Alignement de l'APK…"
@@ -13569,9 +13727,6 @@ msgstr "Les constantes ne peuvent être modifiées."
#~ msgid "Failed to save solution."
#~ msgstr "Impossible de sauvegarder la solution."
-#~ msgid "Done"
-#~ msgstr "Terminé"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Impossible de créer le projet C#."
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index 971c0b0bec..4e537d9882 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -1,6 +1,6 @@
# Irish translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Rónán Quill <ronan085@gmail.com>, 2019, 2020.
msgid ""
@@ -627,7 +627,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1798,8 +1798,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1890,10 +1890,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2298,6 +2294,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2341,18 +2341,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2401,6 +2389,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2443,7 +2435,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2833,14 +2825,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2994,6 +2978,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3196,7 +3196,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3733,7 +3733,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3871,6 +3879,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -4821,7 +4841,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4925,7 +4945,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4956,8 +4975,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4971,9 +4989,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6030,6 +6067,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6090,10 +6131,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6675,6 +6712,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6726,16 +6771,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6828,8 +6863,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7050,6 +7085,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8263,10 +8302,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8325,10 +8360,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9583,6 +9614,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9943,6 +9978,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10186,6 +10225,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10306,6 +10353,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11093,6 +11144,34 @@ msgstr "Scagairí..."
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11592,11 +11671,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11608,11 +11689,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11620,9 +11701,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11847,6 +11938,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12013,27 +12112,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12093,14 +12192,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12306,6 +12404,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12347,6 +12453,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/gl.po b/editor/translations/gl.po
new file mode 100644
index 0000000000..5559444f0c
--- /dev/null
+++ b/editor/translations/gl.po
@@ -0,0 +1,12861 @@
+# Galician translation of the Godot Engine editor.
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
+# This file is distributed under the same license as the Godot source code.
+#
+# Andy Barcia <andybarcia4@gmail.com>, 2021.
+# PokeGalaico <abloodyfreaks@gmail.com>, 2021.
+msgid ""
+msgstr ""
+"Project-Id-Version: Godot Engine editor\n"
+"PO-Revision-Date: 2021-02-15 10:51+0000\n"
+"Last-Translator: Andy Barcia <andybarcia4@gmail.com>\n"
+"Language-Team: Galician <https://hosted.weblate.org/projects/godot-engine/"
+"godot/gl/>\n"
+"Language: gl\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 4.5-dev\n"
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Invalid type argument to convert(), use TYPE_* constants."
+msgstr "Tipo de argumento inválido para convert(), utiliza constantes TYPE_*."
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+msgid "Expected a string of length 1 (a character)."
+msgstr "Esperábase un string de lonxitude 1 (un carácter)."
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/mono/glue/gd_glue.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Not enough bytes for decoding bytes, or invalid format."
+msgstr ""
+"Non hai insuficientes \"bytes\" para descodificar, ou o formato é inválido."
+
+#: core/math/expression.cpp
+msgid "Invalid input %i (not passed) in expression"
+msgstr "Entrada inválida %i (non recibida) na expresión"
+
+#: core/math/expression.cpp
+msgid "self can't be used because instance is null (not passed)"
+msgstr "Non se pode usar \"self\" porque a instancia é nula (non recibida)"
+
+#: core/math/expression.cpp
+msgid "Invalid operands to operator %s, %s and %s."
+msgstr "Operandos inválidos para o operador %s, %s e %s."
+
+#: core/math/expression.cpp
+msgid "Invalid index of type %s for base type %s"
+msgstr "Ãndice de tipo %s inválido para tipo base %s"
+
+#: core/math/expression.cpp
+msgid "Invalid named index '%s' for base type %s"
+msgstr "O índice do nome '%s' non é válido para o tipo de base %s"
+
+#: core/math/expression.cpp
+msgid "Invalid arguments to construct '%s'"
+msgstr "Argumentos inválidos para construir '%s'"
+
+#: core/math/expression.cpp
+msgid "On call to '%s':"
+msgstr "En chamada a '%s':"
+
+#: core/ustring.cpp
+msgid "B"
+msgstr "B"
+
+#: core/ustring.cpp
+msgid "KiB"
+msgstr "KiB"
+
+#: core/ustring.cpp
+msgid "MiB"
+msgstr "MiB"
+
+#: core/ustring.cpp
+msgid "GiB"
+msgstr "GiB"
+
+#: core/ustring.cpp
+msgid "TiB"
+msgstr "TiB"
+
+#: core/ustring.cpp
+msgid "PiB"
+msgstr "PiB"
+
+#: core/ustring.cpp
+msgid "EiB"
+msgstr "EiB"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Free"
+msgstr "Libre"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Balanced"
+msgstr "Balanceado"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Mirror"
+msgstr "Espello"
+
+#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
+msgid "Time:"
+msgstr "Tempo:"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Value:"
+msgstr "Valor:"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Insert Key Here"
+msgstr "Introducir Clave Aquí"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Duplicate Selected Key(s)"
+msgstr "Duplicar Clave(s) Seleccionadas(s)"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Delete Selected Key(s)"
+msgstr "Eliminar Clave(s) Seleccionada(s)"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Add Bezier Point"
+msgstr "Engadir Punto Bezier"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Move Bezier Points"
+msgstr "Mover Punto Bezier"
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Duplicate Keys"
+msgstr "Duplicar Claves de Animación"
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Delete Keys"
+msgstr "Eliminar Claves de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Time"
+msgstr "Cambiar Tempo do Fotograma Clave"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transition"
+msgstr "Cambiar Transición de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transform"
+msgstr "Cambiar Transformación da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Value"
+msgstr "Cambiar Valor do Fotograma Clave da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Call"
+msgstr "Cambiar Chamada da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr "Cambiar Tempo de Múltiples Fotogramas Claves de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Cambiar Múltiples Transicións da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr "Cambiar Múltiples Transformacións da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr "Cambiar Múltiples Valores do Fotograma Clave da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr "Cambiar Múltiples Chamadas da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Length"
+msgstr "Cambiar Lonxitude da Animación"
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation Loop"
+msgstr "Cambiar Ciclo da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Property Track"
+msgstr "Pista de Propiedades"
+
+#: editor/animation_track_editor.cpp
+msgid "3D Transform Track"
+msgstr "Pista de Transformación 3D"
+
+#: editor/animation_track_editor.cpp
+msgid "Call Method Track"
+msgstr "Pista de Chamadas de Métodos"
+
+#: editor/animation_track_editor.cpp
+msgid "Bezier Curve Track"
+msgstr "Pista de Curva Bezier"
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Playback Track"
+msgstr "Pista de Reprodución de Audio"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Playback Track"
+msgstr "Pista de Reprodución de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (frames)"
+msgstr "Lonxitude da Animacion (en fotogramas)"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (seconds)"
+msgstr "Lonxitude da Animación (en segundos)"
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track"
+msgstr "Engadir Pista"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Looping"
+msgstr "Animación en Bucle"
+
+#: editor/animation_track_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Functions:"
+msgstr "Funciones:"
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Clips:"
+msgstr "Clips de Audio:"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Clips:"
+msgstr "Clips de Animación:"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Track Path"
+msgstr "Cambiar Ruta da Pista"
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle this track on/off."
+msgstr "Act./Desact. esta pista."
+
+#: editor/animation_track_editor.cpp
+msgid "Update Mode (How this property is set)"
+msgstr "Modo de Actualización (cómo se establece esta propiedade)"
+
+#: editor/animation_track_editor.cpp
+msgid "Interpolation Mode"
+msgstr "Modo de Interpolación"
+
+#: editor/animation_track_editor.cpp
+msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
+msgstr "Modo de Bucle Envolvente (interpola o final co comezo do bucle)"
+
+#: editor/animation_track_editor.cpp
+msgid "Remove this track."
+msgstr "Eliminar esta pista."
+
+#: editor/animation_track_editor.cpp
+msgid "Time (s): "
+msgstr "Tempo (s): "
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle Track Enabled"
+msgstr "Act./Desact. Pista"
+
+#: editor/animation_track_editor.cpp
+msgid "Continuous"
+msgstr "Continuo"
+
+#: editor/animation_track_editor.cpp
+msgid "Discrete"
+msgstr "Discreto"
+
+#: editor/animation_track_editor.cpp
+msgid "Trigger"
+msgstr "Detonante (Trigger)"
+
+#: editor/animation_track_editor.cpp
+msgid "Capture"
+msgstr "Captura"
+
+#: editor/animation_track_editor.cpp
+msgid "Nearest"
+msgstr "Máis Cercano"
+
+#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
+#: editor/property_editor.cpp
+msgid "Linear"
+msgstr "Lineal"
+
+#: editor/animation_track_editor.cpp
+msgid "Cubic"
+msgstr "Cúbica"
+
+#: editor/animation_track_editor.cpp
+msgid "Clamp Loop Interp"
+msgstr "Interpolación de Bucle Recortado"
+
+#: editor/animation_track_editor.cpp
+msgid "Wrap Loop Interp"
+msgstr "Interpolación de Bucle Envolvente"
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key"
+msgstr "Engadir Chave"
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Key(s)"
+msgstr "Duplicar Chave(s)"
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Key(s)"
+msgstr "Eliminar Chave(s)"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Update Mode"
+msgstr "Cambiar Modo de Actualización da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Interpolation Mode"
+msgstr "Cambiar Modo de Interpolación da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Loop Mode"
+msgstr "Cambiar Modo de Bucle da Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Remove Anim Track"
+msgstr "Eliminar Pista de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Create NEW track for %s and insert key?"
+msgstr "Crear nova pista para %s e engadir chave?"
+
+#: editor/animation_track_editor.cpp
+msgid "Create %d NEW tracks and insert keys?"
+msgstr "Crear %d novas pistas e engadir chaves?"
+
+#: editor/animation_track_editor.cpp editor/create_dialog.cpp
+#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create"
+msgstr "Crear"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert"
+msgstr "Engadir Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "AnimationPlayer can't animate itself, only other players."
+msgstr "Un AnimationPlayer non pode animarse a si mesmo, só a outros players."
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Create & Insert"
+msgstr "Crear e Engadir Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Track & Key"
+msgstr "Engadir Pista e Chave de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Key"
+msgstr "Engadir Chave de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Step"
+msgstr "Cambiar Paso de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Rearrange Tracks"
+msgstr "Reordenar Pistas"
+
+#: editor/animation_track_editor.cpp
+msgid "Transform tracks only apply to Spatial-based nodes."
+msgstr "As pistas de transformación só aplícanse a nodos basados en Spatial."
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"Audio tracks can only point to nodes of type:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
+msgstr ""
+"As pistas de audio só poden apuntar a nodos de tipo:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation tracks can only point to AnimationPlayer nodes."
+msgstr "As pistas de animación só poden apuntar a nodos AnimationPlayer."
+
+#: editor/animation_track_editor.cpp
+msgid "An animation player can't animate itself, only other players."
+msgstr ""
+"Un reproductor de animacións non pode animarse a si mesmo, só a outros "
+"reproductores."
+
+#: editor/animation_track_editor.cpp
+msgid "Not possible to add a new track without a root"
+msgstr "Non é posible engadir unha nova pista sen unha raíz"
+
+#: editor/animation_track_editor.cpp
+msgid "Invalid track for Bezier (no suitable sub-properties)"
+msgstr "Pista inválida para Bezier (non hai sub-propiedades axeitadas)"
+
+#: editor/animation_track_editor.cpp
+msgid "Add Bezier Track"
+msgstr "Engadir Pista Bezier"
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a key."
+msgstr "A ruta á pista é inválida, polo que non se poden engadir chaves."
+
+#: editor/animation_track_editor.cpp
+msgid "Track is not of type Spatial, can't insert key"
+msgstr "A pista non é de tipo Spatial, e non se pode engadir chave"
+
+#: editor/animation_track_editor.cpp
+msgid "Add Transform Track Key"
+msgstr "Engadir Chave de Pista de Transformación"
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track Key"
+msgstr "Engadir Chave de Pista"
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a method key."
+msgstr ""
+"A ruta á pista é inválida, polo que non se pode engadir unha clave de método."
+
+#: editor/animation_track_editor.cpp
+msgid "Add Method Track Key"
+msgstr "Engadir Chave de Pista de Método"
+
+#: editor/animation_track_editor.cpp
+msgid "Method not found in object: "
+msgstr "Método non encontrado no obxecto: "
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Move Keys"
+msgstr "Mover Claves de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Clipboard is empty"
+msgstr "O portapapeis está baleiro"
+
+#: editor/animation_track_editor.cpp
+msgid "Paste Tracks"
+msgstr "Pegar Pistas"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Scale Keys"
+msgstr "Escalar Chaves de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This option does not work for Bezier editing, as it's only a single track."
+msgstr ""
+"Esta opción non funciona con edición Bezier, xa que é unha única pista."
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This animation belongs to an imported scene, so changes to imported tracks "
+"will not be saved.\n"
+"\n"
+"To enable the ability to add custom tracks, navigate to the scene's import "
+"settings and set\n"
+"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks"
+"\", then re-import.\n"
+"Alternatively, use an import preset that imports animations to separate "
+"files."
+msgstr ""
+"Esta animación pertence a unha escena importada, polo que os cambios nas "
+"pistas importadas non quedaran gardados.\n"
+"\n"
+"Para habilitar a capacidade de engadir pistas personalizadas, vai á "
+"configuración de importación da escena e establece\n"
+"\"Animación > Almacenamento\" a \"Arquivos\", activa \"Animación > Manter "
+"Pistas Personalizadas\", e logo reimportaa.\n"
+"Tamén poder usar un preset de importación que importa animacións para "
+"separar arquivos."
+
+#: editor/animation_track_editor.cpp
+msgid "Warning: Editing imported animation"
+msgstr "Advertencia: Estase editando unha animación importada"
+
+#: editor/animation_track_editor.cpp
+msgid "Select an AnimationPlayer node to create and edit animations."
+msgstr "Selecciona un nodo AnimationPlayer para crear e editar animacións."
+
+#: editor/animation_track_editor.cpp
+msgid "Only show tracks from nodes selected in tree."
+msgstr "Só mostrar pistas de nodos seleccionados na árbore."
+
+#: editor/animation_track_editor.cpp
+msgid "Group tracks by node or display them as plain list."
+msgstr "Agrupar pistas por nodo ou mostralas coma unha simple lista."
+
+#: editor/animation_track_editor.cpp
+msgid "Snap:"
+msgstr "Axuste de Cuadrícula:"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation step value."
+msgstr "Valor de paso de animación."
+
+#: editor/animation_track_editor.cpp
+msgid "Seconds"
+msgstr "Segundos"
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "FPS"
+msgstr "FPS"
+
+#: editor/animation_track_editor.cpp editor/editor_properties.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit"
+msgstr "Editar"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation properties."
+msgstr "Propiedades de Animación."
+
+#: editor/animation_track_editor.cpp
+msgid "Copy Tracks"
+msgstr "Copiar Pistas"
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Selection"
+msgstr "Escalar Selección"
+
+#: editor/animation_track_editor.cpp
+msgid "Scale From Cursor"
+msgstr "Escalar desde o Cursor"
+
+#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Duplicate Selection"
+msgstr "Duplicar Selección"
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Transposed"
+msgstr "Duplicar Transposto"
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Selection"
+msgstr "Eliminar Selección"
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Next Step"
+msgstr "Ir ao Seguinte Paso"
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Previous Step"
+msgstr "Ir ao Anterior Paso"
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize Animation"
+msgstr "Optimizar Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation"
+msgstr "Limpiar Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Pick the node that will be animated:"
+msgstr "Elixe o nodo que será animado:"
+
+#: editor/animation_track_editor.cpp
+msgid "Use Bezier Curves"
+msgstr "Usar Curvas Bezier"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim. Optimizer"
+msgstr "Optimizador de Animación"
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Linear Error:"
+msgstr "Erro Lineal Máximo:"
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Angular Error:"
+msgstr "Erro Angular Máximo:"
+
+#: editor/animation_track_editor.cpp
+msgid "Max Optimizable Angle:"
+msgstr "Ãngulo Optimizable Máximo:"
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize"
+msgstr "Optimizar"
+
+#: editor/animation_track_editor.cpp
+msgid "Remove invalid keys"
+msgstr "Eliminar chaves inválidas"
+
+#: editor/animation_track_editor.cpp
+msgid "Remove unresolved and empty tracks"
+msgstr "Eliminar pistas baleiras e sen resolver"
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-up all animations"
+msgstr "Limpiar tódolas animacións"
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation(s) (NO UNDO!)"
+msgstr "Limpiar Animación(s) (NON HAI VOLTA ATRÃS!)"
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up"
+msgstr "Limpiar"
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Ratio:"
+msgstr "Relación de Escalado:"
+
+#: editor/animation_track_editor.cpp
+msgid "Select Tracks to Copy"
+msgstr "Selecciona as Pistas a Copiar"
+
+#: editor/animation_track_editor.cpp editor/editor_log.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Copy"
+msgstr "Copiar"
+
+#: editor/animation_track_editor.cpp
+msgid "Select All/None"
+msgstr "Seleccionar Todas/Ningunha"
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Add Audio Track Clip"
+msgstr "Engadir Clip de Pista de Audio"
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip Start Offset"
+msgstr "Cambiar Inicio do Clip na Pista de Audio"
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip End Offset"
+msgstr "Cambiar Final do Clip na Pista de Audio"
+
+#: editor/array_property_edit.cpp
+msgid "Resize Array"
+msgstr "Redimensionar Array"
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value Type"
+msgstr "Cambiar Tipo do Valor do Array"
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value"
+msgstr "Cambiar Valor do Array"
+
+#: editor/code_editor.cpp
+msgid "Go to Line"
+msgstr "Ir a Liña"
+
+#: editor/code_editor.cpp
+msgid "Line Number:"
+msgstr "Número de Liña:"
+
+#: editor/code_editor.cpp
+msgid "%d replaced."
+msgstr "%d substituído."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
+msgstr "%d coincidencia."
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
+msgstr "%d coincidencias."
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Match Case"
+msgstr "Coincidir Maiús./Minús."
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Whole Words"
+msgstr "Palabras Completas"
+
+#: editor/code_editor.cpp
+msgid "Replace"
+msgstr "Substituír"
+
+#: editor/code_editor.cpp
+msgid "Replace All"
+msgstr "Substituír Todo"
+
+#: editor/code_editor.cpp
+msgid "Selection Only"
+msgstr "Só a Selección"
+
+#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
+#: editor/plugins/text_editor.cpp
+msgid "Standard"
+msgstr "Estándar"
+
+#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Toggle Scripts Panel"
+msgstr "Act./Desact. Panel de Scripts"
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom In"
+msgstr "Aumentar Zoom"
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Out"
+msgstr "Diminuír Zoom"
+
+#: editor/code_editor.cpp
+msgid "Reset Zoom"
+msgstr "Reiniciar Zoom"
+
+#: editor/code_editor.cpp
+msgid "Warnings"
+msgstr "Avisos"
+
+#: editor/code_editor.cpp
+msgid "Line and column numbers."
+msgstr "Números de liña e columna."
+
+#: editor/connections_dialog.cpp
+msgid "Method in target node must be specified."
+msgstr "Debe especificarse o método no nodo receptor."
+
+#: editor/connections_dialog.cpp
+msgid "Method name must be a valid identifier."
+msgstr "O nome do método debe ser un identificador válido."
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Target method not found. Specify a valid method or attach a script to the "
+"target node."
+msgstr ""
+"Non se encontrou o método receptor. Especifique un método válido ou engada "
+"un script ao nodo receptor."
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Node:"
+msgstr "Conectar ao Nodo:"
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Script:"
+msgstr "Conectar ao Script:"
+
+#: editor/connections_dialog.cpp
+msgid "From Signal:"
+msgstr "Desde a Sinal:"
+
+#: editor/connections_dialog.cpp
+msgid "Scene does not contain any script."
+msgstr "A escena non conteñe ningún script."
+
+#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
+#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+msgid "Add"
+msgstr "Engadir"
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp
+msgid "Remove"
+msgstr "Eliminar"
+
+#: editor/connections_dialog.cpp
+msgid "Add Extra Call Argument:"
+msgstr "Engadir Argumento Extra á Chamada:"
+
+#: editor/connections_dialog.cpp
+msgid "Extra Call Arguments:"
+msgstr "Argumentos Extra da Chamada:"
+
+#: editor/connections_dialog.cpp
+msgid "Receiver Method:"
+msgstr "Método Receptor:"
+
+#: editor/connections_dialog.cpp
+msgid "Advanced"
+msgstr "Avanzado"
+
+#: editor/connections_dialog.cpp
+msgid "Deferred"
+msgstr "Diferido"
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Defers the signal, storing it in a queue and only firing it at idle time."
+msgstr ""
+"Difire a sinal, almacenándoa nunha cola é só executándoa en tempo de "
+"inactividade."
+
+#: editor/connections_dialog.cpp
+msgid "Oneshot"
+msgstr "Execución Única (Oneshot)"
+
+#: editor/connections_dialog.cpp
+msgid "Disconnects the signal after its first emission."
+msgstr "Desconecta a sinal unha vez foi emitida por primeira vez."
+
+#: editor/connections_dialog.cpp
+msgid "Cannot connect signal"
+msgstr "No se pode conectar a sinal"
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/export_template_manager.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Close"
+msgstr "Pechar"
+
+#: editor/connections_dialog.cpp
+msgid "Connect"
+msgstr "Conectar"
+
+#: editor/connections_dialog.cpp
+msgid "Signal:"
+msgstr "Sinal:"
+
+#: editor/connections_dialog.cpp
+msgid "Connect '%s' to '%s'"
+msgstr "Conectar '%s' con '%s'"
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect '%s' from '%s'"
+msgstr "Desconectar '%s' de '%s'"
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect all from signal: '%s'"
+msgstr "Desconectar todo da sinal: '%s'"
+
+#: editor/connections_dialog.cpp
+msgid "Connect..."
+msgstr "Conectar..."
+
+#: editor/connections_dialog.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Disconnect"
+msgstr "Desconectar"
+
+#: editor/connections_dialog.cpp
+msgid "Connect a Signal to a Method"
+msgstr "Conectar unha Sinal a un Método"
+
+#: editor/connections_dialog.cpp
+msgid "Edit Connection:"
+msgstr "Editar Conexión:"
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
+msgstr "Está seguro de que quere eliminar tódalas conexións da sinal '%s'?"
+
+#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
+msgid "Signals"
+msgstr "Sinais"
+
+#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr "Filtrar sinais"
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from this signal?"
+msgstr "Está seguro de que quere eliminar tódalas conexións desta sinal?"
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect All"
+msgstr "Desconectar Todas"
+
+#: editor/connections_dialog.cpp
+msgid "Edit..."
+msgstr "Editar..."
+
+#: editor/connections_dialog.cpp
+msgid "Go To Method"
+msgstr "Ir ao Método"
+
+#: editor/create_dialog.cpp
+msgid "Change %s Type"
+msgstr "Cambiar o Tipo de %s"
+
+#: editor/create_dialog.cpp editor/project_settings_editor.cpp
+msgid "Change"
+msgstr "Cambiar"
+
+#: editor/create_dialog.cpp
+msgid "Create New %s"
+msgstr "Crear Novo %s"
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp
+msgid "Favorites:"
+msgstr "Favoritos:"
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+msgid "Recent:"
+msgstr "Recente:"
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search:"
+msgstr "Buscar:"
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Matches:"
+msgstr "Coincidencias:"
+
+#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp
+#: editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Description:"
+msgstr "Descrición:"
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement For:"
+msgstr "Buscar Substitución Para:"
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies For:"
+msgstr "Dependencias De:"
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Scene '%s' is currently being edited.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+"A escena '%s' agora mesmo está sendo editada.\n"
+"Os cambios só terán efecto cando sexa recargada."
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Resource '%s' is in use.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+"O recurso '%s' agora mesmo está sendo usado.\n"
+"Os cambios só terán efecto cando sexa recargado."
+
+#: editor/dependency_editor.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dependencies"
+msgstr "Dependencias"
+
+#: editor/dependency_editor.cpp
+msgid "Resource"
+msgstr "Recurso"
+
+#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
+msgid "Path"
+msgstr "Ruta"
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies:"
+msgstr "Dependencias:"
+
+#: editor/dependency_editor.cpp
+msgid "Fix Broken"
+msgstr "Corrixir Erros"
+
+#: editor/dependency_editor.cpp
+msgid "Dependency Editor"
+msgstr "Editor de Dependencias"
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement Resource:"
+msgstr "Buscar Recurso de Substitución:"
+
+#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Open"
+msgstr "Abrir"
+
+#: editor/dependency_editor.cpp
+msgid "Owners Of:"
+msgstr "Dono De:"
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Remove selected files from the project? (no undo)\n"
+"You can find the removed files in the system trash to restore them."
+msgstr ""
+"Eliminar do proxecto os arquivos seleccionados? (non se pode reverter)\n"
+"Podes encontrar os arquivos eliminados na papeleira de reciclaxe do sistema "
+"para restaurarlos."
+
+#: editor/dependency_editor.cpp
+msgid ""
+"The files being removed are required by other resources in order for them to "
+"work.\n"
+"Remove them anyway? (no undo)\n"
+"You can find the removed files in the system trash to restore them."
+msgstr ""
+"Os arquivos sendo eliminados están requeridos por outros recursos para poder "
+"funcionar.\n"
+"Eliminalos de todas formas? (non se pode reverter)\n"
+"Podes encontrar os arquivos eliminados na papeleira de reciclaxe do sistema "
+"para restaurarlos."
+
+#: editor/dependency_editor.cpp
+msgid "Cannot remove:"
+msgstr "Non se pode eliminar:"
+
+#: editor/dependency_editor.cpp
+msgid "Error loading:"
+msgstr "Erro cargando:"
+
+#: editor/dependency_editor.cpp
+msgid "Load failed due to missing dependencies:"
+msgstr "Fallou a carga debido a dependencias ausentes:"
+
+#: editor/dependency_editor.cpp editor/editor_node.cpp
+msgid "Open Anyway"
+msgstr "Abrir de Todos Modos"
+
+#: editor/dependency_editor.cpp
+msgid "Which action should be taken?"
+msgstr "Que acción debería de tomarse?"
+
+#: editor/dependency_editor.cpp
+msgid "Fix Dependencies"
+msgstr "Corrixir Dependencias"
+
+#: editor/dependency_editor.cpp
+msgid "Errors loading!"
+msgstr "Erros na carga!"
+
+#: editor/dependency_editor.cpp
+msgid "Permanently delete %d item(s)? (No undo!)"
+msgstr "Eliminar permanentemente %d obxectos? (Non se pode reverter!)"
+
+#: editor/dependency_editor.cpp
+msgid "Show Dependencies"
+msgstr "Amosar Dependencias"
+
+#: editor/dependency_editor.cpp
+msgid "Orphan Resource Explorer"
+msgstr "Explorador de Recursos Orfos"
+
+#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
+msgid "Delete"
+msgstr "Eliminar"
+
+#: editor/dependency_editor.cpp
+msgid "Owns"
+msgstr "É Dono de"
+
+#: editor/dependency_editor.cpp
+msgid "Resources Without Explicit Ownership:"
+msgstr "Recursos Sen Dono Explícito:"
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Key"
+msgstr "Cambiar Chave do Dicionario"
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Value"
+msgstr "Cambiar Valor do Dicionario"
+
+#: editor/editor_about.cpp
+msgid "Thanks from the Godot community!"
+msgstr "Moitas grazas de parte da comunidade de Godot!"
+
+#: editor/editor_about.cpp
+msgid "Godot Engine contributors"
+msgstr "Colaboradores de Godot Engine"
+
+#: editor/editor_about.cpp
+msgid "Project Founders"
+msgstr "Fundadores do Proxecto"
+
+#: editor/editor_about.cpp
+msgid "Lead Developer"
+msgstr "Desenvolvedor Líder"
+
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
+#: editor/editor_about.cpp
+msgid "Project Manager "
+msgstr "Xestor do Proxecto "
+
+#: editor/editor_about.cpp
+msgid "Developers"
+msgstr "Desenvolvedores"
+
+#: editor/editor_about.cpp
+msgid "Authors"
+msgstr "Autores"
+
+#: editor/editor_about.cpp
+msgid "Platinum Sponsors"
+msgstr "Patrocinadores Platino"
+
+#: editor/editor_about.cpp
+msgid "Gold Sponsors"
+msgstr "Patrocinadores Ouro"
+
+#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr "Patrocinadores Prata"
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr "Patrocinadores Bronce"
+
+#: editor/editor_about.cpp
+msgid "Mini Sponsors"
+msgstr "Patrocinadores Mini"
+
+#: editor/editor_about.cpp
+msgid "Gold Donors"
+msgstr "Doadores Ouro"
+
+#: editor/editor_about.cpp
+msgid "Silver Donors"
+msgstr "Doadores Prata"
+
+#: editor/editor_about.cpp
+msgid "Bronze Donors"
+msgstr "Doadores Bronce"
+
+#: editor/editor_about.cpp
+msgid "Donors"
+msgstr "Doadores"
+
+#: editor/editor_about.cpp
+msgid "License"
+msgstr "Licenza"
+
+#: editor/editor_about.cpp
+msgid "Third-party Licenses"
+msgstr "Licenzas de Terceiros"
+
+#: editor/editor_about.cpp
+msgid ""
+"Godot Engine relies on a number of third-party free and open source "
+"libraries, all compatible with the terms of its MIT license. The following "
+"is an exhaustive list of all such third-party components with their "
+"respective copyright statements and license terms."
+msgstr ""
+"Godot Engine depende dun número de bibliotecas de terceiros, gratis e open "
+"source; todas compatibles cos termos da licenza MIT. A seguinte e unha lista "
+"exhaustiva dos devanditos compoñentes de terceiros, coas suas respectivas "
+"declaracións de copyright e termos de licenza."
+
+#: editor/editor_about.cpp
+msgid "All Components"
+msgstr "Todos os Compoñentes"
+
+#: editor/editor_about.cpp
+msgid "Components"
+msgstr "Compoñentes"
+
+#: editor/editor_about.cpp
+msgid "Licenses"
+msgstr "Licenzas"
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Error opening package file, not in ZIP format."
+msgstr "Erro ao abrir o arquivo comprimido, non está en formato ZIP."
+
+#: editor/editor_asset_installer.cpp
+msgid "%s (Already Exists)"
+msgstr "%s (Xa Existe)"
+
+#: editor/editor_asset_installer.cpp
+msgid "Uncompressing Assets"
+msgstr "Descomprimindo Assets"
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "The following files failed extraction from package:"
+msgstr "Os seguintes arquivos non se poideron extraer do paquete:"
+
+#: editor/editor_asset_installer.cpp
+msgid "And %s more files."
+msgstr "E %s arquivos máis."
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Package installed successfully!"
+msgstr "Paquete instalado correctamente!"
+
+#: editor/editor_asset_installer.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Success!"
+msgstr "Éxito!"
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Contents:"
+msgstr "Contenido do Paquete:"
+
+#: editor/editor_asset_installer.cpp editor/editor_node.cpp
+msgid "Install"
+msgstr "Instalar"
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Installer"
+msgstr "Instalador de Paquetes"
+
+#: editor/editor_audio_buses.cpp
+msgid "Speakers"
+msgstr "Altofalantes"
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Effect"
+msgstr "Engadir Efecto"
+
+#: editor/editor_audio_buses.cpp
+msgid "Rename Audio Bus"
+msgstr "Renomear Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Change Audio Bus Volume"
+msgstr "Cambiar Volume do Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Solo"
+msgstr "Act./Desact. Solo do Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Mute"
+msgstr "Act./Desact. Silencio do Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Bypass Effects"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Select Audio Bus Send"
+msgstr "Seleccionar Envío do Bus de Audio"
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus Effect"
+msgstr "Engadir Efecto ao Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Bus Effect"
+msgstr "Mover Efecto do Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Bus Effect"
+msgstr "Eliminar Efecto do Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Drag & drop to rearrange."
+msgstr "Arrastrar e soltar para reordenar."
+
+#: editor/editor_audio_buses.cpp
+msgid "Solo"
+msgstr "Solo"
+
+#: editor/editor_audio_buses.cpp
+msgid "Mute"
+msgstr "Silenciar"
+
+#: editor/editor_audio_buses.cpp
+msgid "Bypass"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bus options"
+msgstr "Opcións de Bus"
+
+#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Duplicate"
+msgstr "Duplicar"
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Volume"
+msgstr "Restablecer Volume"
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Effect"
+msgstr "Eliminar Efecto"
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio"
+msgstr "Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus"
+msgstr "Engadir Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Master bus can't be deleted!"
+msgstr "Non se pode eliminar o Bus mestre!"
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Audio Bus"
+msgstr "Eliminar Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Duplicate Audio Bus"
+msgstr "Duplicar Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Bus Volume"
+msgstr "Restablecer Volume do Bus"
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Audio Bus"
+msgstr "Mover Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "Save Audio Bus Layout As..."
+msgstr "Gardar Disposición do Bus de Son Como..."
+
+#: editor/editor_audio_buses.cpp
+msgid "Location for New Layout..."
+msgstr "Localización para a Nova Disposición..."
+
+#: editor/editor_audio_buses.cpp
+msgid "Open Audio Bus Layout"
+msgstr "Abrir Disposición do Bus de Son"
+
+#: editor/editor_audio_buses.cpp
+msgid "There is no '%s' file."
+msgstr "Non hai ningún arquivo '%s'."
+
+#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Layout"
+msgstr "Disposición"
+
+#: editor/editor_audio_buses.cpp
+msgid "Invalid file, not an audio bus layout."
+msgstr "Arquivo invalido; non é unha disposición dun Bus de son."
+
+#: editor/editor_audio_buses.cpp
+msgid "Error saving file: %s"
+msgstr "Erro gardando o arquivo: %s"
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Bus"
+msgstr "Engadir Bus"
+
+#: editor/editor_audio_buses.cpp
+msgid "Add a new Audio Bus to this layout."
+msgstr "Engadir un novo Bus de Son a esta disposición."
+
+#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Load"
+msgstr "Cargar"
+
+#: editor/editor_audio_buses.cpp
+msgid "Load an existing Bus Layout."
+msgstr "Cargar unha disposición de Bus xa existente."
+
+#: editor/editor_audio_buses.cpp
+msgid "Save As"
+msgstr "Gardar Como"
+
+#: editor/editor_audio_buses.cpp
+msgid "Save this Bus Layout to a file."
+msgstr "Gardar esta disposición de Bus a un arquivo."
+
+#: editor/editor_audio_buses.cpp editor/import_dock.cpp
+msgid "Load Default"
+msgstr "Cargar Valores por Defecto"
+
+#: editor/editor_audio_buses.cpp
+msgid "Load the default Bus Layout."
+msgstr "Cargar a disposición de Bus por defecto."
+
+#: editor/editor_audio_buses.cpp
+msgid "Create a new Bus Layout."
+msgstr "Crear unha nova Disposición de Bus."
+
+#: editor/editor_autoload_settings.cpp
+msgid "Invalid name."
+msgstr "Nome inválido."
+
+#: editor/editor_autoload_settings.cpp
+msgid "Valid characters:"
+msgstr "Caracteres válidos:"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing engine class name."
+msgstr "Non debe coincidir co nome dunha clase xa existente no engine."
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing built-in type name."
+msgstr "Non debe coincidir co nome dun tipo xa existente no engine."
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing global constant name."
+msgstr "Non debe coincidir co nome dunha constante global xa existente."
+
+#: editor/editor_autoload_settings.cpp
+msgid "Keyword cannot be used as an autoload name."
+msgstr "Unha palabra clave non pode usarse como nome dun AutoCargador."
+
+#: editor/editor_autoload_settings.cpp
+msgid "Autoload '%s' already exists!"
+msgstr "Xa existe un AutoCargador nomeado '%s'!"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rename Autoload"
+msgstr "Renomear AutoCargador"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Toggle AutoLoad Globals"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Move Autoload"
+msgstr "Mover AutoCargador"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Remove Autoload"
+msgstr "Eliminar AutoCargador"
+
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
+msgid "Enable"
+msgstr "Activar"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rearrange Autoloads"
+msgstr "Reordenar AutoCargadores"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Can't add autoload:"
+msgstr "Non se puido engadir AutoCargador:"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Add AutoLoad"
+msgstr "Engadir AutoCargador"
+
+#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Path:"
+msgstr "Ruta:"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Node Name:"
+msgstr "Nome do Nodo:"
+
+#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Name"
+msgstr "Nome"
+
+#: editor/editor_autoload_settings.cpp
+msgid "Singleton"
+msgstr ""
+
+#: editor/editor_data.cpp editor/inspector_dock.cpp
+msgid "Paste Params"
+msgstr "Pegar Parámetros"
+
+#: editor/editor_data.cpp
+msgid "Updating Scene"
+msgstr "Actualizando Escena"
+
+#: editor/editor_data.cpp
+msgid "Storing local changes..."
+msgstr "Gardando cambios locales..."
+
+#: editor/editor_data.cpp
+msgid "Updating scene..."
+msgstr "Actualizando escena..."
+
+#: editor/editor_data.cpp editor/editor_properties.cpp
+msgid "[empty]"
+msgstr "[baleiro]"
+
+#: editor/editor_data.cpp
+msgid "[unsaved]"
+msgstr "[non gardado]"
+
+#: editor/editor_dir_dialog.cpp
+msgid "Please select a base directory first."
+msgstr "Por favor, seleccione primeiro un directorio base."
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose a Directory"
+msgstr "Elixir un Directorio"
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Create Folder"
+msgstr "Crear Cartafol"
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
+#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp
+msgid "Name:"
+msgstr "Nome:"
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
+msgid "Could not create folder."
+msgstr "Non se puido crear cartafol."
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose"
+msgstr "Elixir"
+
+#: editor/editor_export.cpp
+msgid "Storing File:"
+msgstr "Gardando Arquivo:"
+
+#: editor/editor_export.cpp
+msgid "No export template found at the expected path:"
+msgstr "Non se encontrou ningún modelo de exportación na ruta esperada:"
+
+#: editor/editor_export.cpp
+msgid "Packing"
+msgstr "Empaquetando"
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
+"Etc' in Project Settings."
+msgstr ""
+"A plataforma actual require compresión de texturas 'ETC' para GLES2. Active "
+"'Importar Etc' na 'Configuración do Proxecto'."
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' texture compression for GLES3. Enable "
+"'Import Etc 2' in Project Settings."
+msgstr ""
+"A plataforma actual require compresión de texturas 'ETC2' para GLES3. Active "
+"'Importar Etc 2' na 'Configuración do Proxecto'."
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+"A plataforma actual require unha compresión de texturas 'ETC' para o "
+"controlador de respaldo a GLES2.\n"
+"Active 'Importar Etc' na 'Configuración do Proxecto' ou desactive "
+"'Controlador de Respaldo Activado'."
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'PVRTC' texture compression for GLES2. Enable "
+"'Import Pvrtc' in Project Settings."
+msgstr ""
+"A plataforma actual require compresión de texturas 'PVRTC' para GLES2. "
+"Active 'Importar Pvrtc' na 'Configuración do Proxecto'."
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
+"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
+msgstr ""
+"A plataforma actual require compresión de texturas 'ETC2' ou 'PVRTC' para "
+"GLES3. Active 'Importar Etc 2' ou 'Importar Pvrtc' na 'Configuración do "
+"Proxecto'."
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'PVRTC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+"A plataforma actual require unha compresión de texturas 'PVRTC' para o "
+"controlador de respaldo a GLES2.\n"
+"Active 'Importar Pvrtc' na 'Configuración do Proxecto' ou desactive "
+"'Controlador de Respaldo Activado'."
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom debug template not found."
+msgstr "Non se encontrou un modelo de depuración personalizado."
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom release template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/javascript/export/export.cpp
+msgid "Template file not found:"
+msgstr "Non se encontrou o arquivo do modelo:"
+
+#: editor/editor_export.cpp
+msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
+msgstr "Na exportación de 32 bits o PCK integrado non pode ser maior de 4 GiB."
+
+#: editor/editor_feature_profile.cpp
+msgid "3D Editor"
+msgstr "Editor 3D"
+
+#: editor/editor_feature_profile.cpp
+msgid "Script Editor"
+msgstr "Editor de Scripts"
+
+#: editor/editor_feature_profile.cpp
+msgid "Asset Library"
+msgstr "Biblioteca de Assets"
+
+#: editor/editor_feature_profile.cpp
+msgid "Scene Tree Editing"
+msgstr "Edición de Ãrbore de Escenas"
+
+#: editor/editor_feature_profile.cpp
+msgid "Node Dock"
+msgstr "Panel de Nodos"
+
+#: editor/editor_feature_profile.cpp
+msgid "FileSystem Dock"
+msgstr "Panel de Sistema de Arquivos"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr "Panel de Importación"
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase profile '%s'? (no undo)"
+msgstr "Eliminar perfil '%s'? (non se pode deshacer)"
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile must be a valid filename and must not contain '.'"
+msgstr "Un perfil debe ter un nome de arquivo válido, e non pode conter '.'"
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile with this name already exists."
+msgstr "Un perfil con este nome xa existe."
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled, Properties Disabled)"
+msgstr "(Editor Desactivado, Propiedades Desactivadas)"
+
+#: editor/editor_feature_profile.cpp
+msgid "(Properties Disabled)"
+msgstr "(Propiedades Desactivadas)"
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled)"
+msgstr "(Editor Desactivado)"
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options:"
+msgstr "Opcións de Clase:"
+
+#: editor/editor_feature_profile.cpp
+msgid "Enable Contextual Editor"
+msgstr "Activar o Editor Contextual"
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Properties:"
+msgstr "Propiedades Activadas:"
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Features:"
+msgstr "Características Activadas:"
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Classes:"
+msgstr "Clases Activadas:"
+
+#: editor/editor_feature_profile.cpp
+msgid "File '%s' format is invalid, import aborted."
+msgstr "O formato '%s' do arquivo non é válido, a importación foi cancelada."
+
+#: editor/editor_feature_profile.cpp
+msgid ""
+"Profile '%s' already exists. Remove it first before importing, import "
+"aborted."
+msgstr ""
+"O perfil '%s' xa existe. Elimínao antes de importar; importación abortada."
+
+#: editor/editor_feature_profile.cpp
+msgid "Error saving profile to path: '%s'."
+msgstr "Erro gardando o perfil á ruta: '%s'."
+
+#: editor/editor_feature_profile.cpp
+msgid "Unset"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Current Profile:"
+msgstr "Perfil Actual:"
+
+#: editor/editor_feature_profile.cpp
+msgid "Make Current"
+msgstr "Convertelo no Actual"
+
+#: editor/editor_feature_profile.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "New"
+msgstr "Novo"
+
+#: editor/editor_feature_profile.cpp editor/editor_node.cpp
+#: editor/project_manager.cpp
+msgid "Import"
+msgstr "Importación"
+
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
+msgid "Export"
+msgstr "Exportación"
+
+#: editor/editor_feature_profile.cpp
+msgid "Available Profiles:"
+msgstr "Perfils Dispoñibles:"
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options"
+msgstr "Opcións de Clase"
+
+#: editor/editor_feature_profile.cpp
+msgid "New profile name:"
+msgstr "Nome do novo perfil:"
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase Profile"
+msgstr "Eliminar Perfil"
+
+#: editor/editor_feature_profile.cpp
+msgid "Godot Feature Profile"
+msgstr "Perfil de Características de Godot"
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Profile(s)"
+msgstr "Importar Perfil(s)"
+
+#: editor/editor_feature_profile.cpp
+msgid "Export Profile"
+msgstr "Exportar Perfil"
+
+#: editor/editor_feature_profile.cpp
+msgid "Manage Editor Feature Profiles"
+msgstr "Administrar Perfils de Características de Godot"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select Current Folder"
+msgstr "Seleccionar Cartafol Actual"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File Exists, Overwrite?"
+msgstr "O arquivo xa existe ¿Queres sobreescribilo?"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select This Folder"
+msgstr "Seleccionar Este Cartafol"
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Copy Path"
+msgstr "Copiar Ruta"
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Open in File Manager"
+msgstr "Abrir no Explorador de Arquivos"
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+msgid "Show in File Manager"
+msgstr "Amosar no Explorador de Arquivos"
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+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"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Recognized"
+msgstr "Todos Recoñecidos"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Files (*)"
+msgstr "Todos os Arquivos (*)"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File"
+msgstr "Abrir un Arquivo"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open File(s)"
+msgstr "Abrir Arquivo(s)"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a Directory"
+msgstr "Abrir un Directorio"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File or Directory"
+msgstr "Abrir un Arquivo ou Directorio"
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Save"
+msgstr "Gardar"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Save a File"
+msgstr "Gardar un Arquivo"
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Back"
+msgstr "Retroceder"
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Forward"
+msgstr "Avanzar"
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Up"
+msgstr "Subir"
+
+#: editor/editor_file_dialog.cpp
+#, fuzzy
+msgid "Toggle Hidden Files"
+msgstr "Amosar/Ocultar Arquivos Ocultos"
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Favorite"
+msgstr "Act./Desact. Favorito"
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Mode"
+msgstr "Act./Desact. Modo"
+
+#: editor/editor_file_dialog.cpp
+msgid "Focus Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Up"
+msgstr "Subir Favorito"
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Down"
+msgstr "Baixar Favorito"
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to previous folder."
+msgstr "Ir ao cartafol anterior."
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to next folder."
+msgstr "Ir ao cartafol seguinte."
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Go to parent folder."
+msgstr "Ir ao cartafol padre."
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr "Actualizar Arquivos."
+
+#: editor/editor_file_dialog.cpp
+msgid "(Un)favorite current folder."
+msgstr "Quitar cartafol actual de favoritos."
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr "Amosar/Ocultar arquivos ocultos."
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a grid of thumbnails."
+msgstr "Ver elementos coma unha cuadrícula de miniaturas."
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a list."
+msgstr "Ver elementos coma unha lista."
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Directories & Files:"
+msgstr "Directorios e Arquivos:"
+
+#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
+#: editor/plugins/style_box_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Preview:"
+msgstr "Vista Previa:"
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File:"
+msgstr "Arquivo:"
+
+#: editor/editor_file_system.cpp
+msgid "ScanSources"
+msgstr "Escanear Fontes"
+
+#: editor/editor_file_system.cpp
+msgid ""
+"There are multiple importers for different types pointing to file %s, import "
+"aborted"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "(Re)Importing Assets"
+msgstr "(Re)Importando Assets"
+
+#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
+msgid "Top"
+msgstr "Superior"
+
+#: editor/editor_help.cpp
+msgid "Class:"
+msgstr "Clase:"
+
+#: editor/editor_help.cpp editor/scene_tree_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Inherits:"
+msgstr "Herda de:"
+
+#: editor/editor_help.cpp
+msgid "Inherited by:"
+msgstr "Herdado de:"
+
+#: editor/editor_help.cpp
+msgid "Description"
+msgstr "Descrición"
+
+#: editor/editor_help.cpp
+msgid "Online Tutorials"
+msgstr "Tutoriales en liña"
+
+#: editor/editor_help.cpp
+msgid "Properties"
+msgstr "Propiedades"
+
+#: editor/editor_help.cpp
+msgid "override:"
+msgstr "sobrescribir:"
+
+#: editor/editor_help.cpp
+msgid "default:"
+msgstr "por defecto:"
+
+#: editor/editor_help.cpp
+msgid "Methods"
+msgstr "Métodos"
+
+#: editor/editor_help.cpp
+#, fuzzy
+msgid "Theme Properties"
+msgstr "Propiedades do Tema"
+
+#: editor/editor_help.cpp
+msgid "Enumerations"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants"
+msgstr "Constantes"
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions"
+msgstr "Descrición de Propiedades"
+
+#: editor/editor_help.cpp
+msgid "(value)"
+msgstr "(valor)"
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this property. Please help us by "
+"[color=$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+"Actualmente non hai unha descripción desta propiedade. Axúdanos [color="
+"$color][url=$url]contribuíndo cunha descripción[/url][/color]!"
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions"
+msgstr "Descrición de Métodos"
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this method. Please help us by [color="
+"$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+"Actualmente non hai unha descripción deste método. Axúdanos [color=$color]"
+"[url=$url]contribuíndo cunha descripción[/url][/color]!"
+
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Help"
+msgstr "Buscar na Axuda"
+
+#: editor/editor_help_search.cpp
+msgid "Case Sensitive"
+msgstr "Distinguir Maíusculas e Minúsculas"
+
+#: editor/editor_help_search.cpp
+msgid "Show Hierarchy"
+msgstr "Amosar Xerarquía"
+
+#: editor/editor_help_search.cpp
+msgid "Display All"
+msgstr "Amosar Todo"
+
+#: editor/editor_help_search.cpp
+msgid "Classes Only"
+msgstr "Só Clases"
+
+#: editor/editor_help_search.cpp
+msgid "Methods Only"
+msgstr "Só Métodos"
+
+#: editor/editor_help_search.cpp
+msgid "Signals Only"
+msgstr "Só Sinais"
+
+#: editor/editor_help_search.cpp
+msgid "Constants Only"
+msgstr "Só Constantes"
+
+#: editor/editor_help_search.cpp
+msgid "Properties Only"
+msgstr "Só Propiedades"
+
+#: editor/editor_help_search.cpp
+msgid "Theme Properties Only"
+msgstr "Só Propiedades de Temas"
+
+#: editor/editor_help_search.cpp
+msgid "Member Type"
+msgstr "Tipo do Membro"
+
+#: editor/editor_help_search.cpp
+msgid "Class"
+msgstr "Clase"
+
+#: editor/editor_help_search.cpp
+msgid "Method"
+msgstr "Método"
+
+#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
+msgid "Signal"
+msgstr "Sinal"
+
+#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
+msgid "Constant"
+msgstr "Constante"
+
+#: editor/editor_help_search.cpp
+msgid "Property"
+msgstr "Propiedade"
+
+#: editor/editor_help_search.cpp
+msgid "Theme Property"
+msgstr "Propiedade de Temas"
+
+#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
+msgid "Property:"
+msgstr "Propiedade:"
+
+#: editor/editor_inspector.cpp
+msgid "Set"
+msgstr "Establecer"
+
+#: editor/editor_inspector.cpp
+msgid "Set Multiple:"
+msgstr "Establecer Varios:"
+
+#: editor/editor_log.cpp
+msgid "Output:"
+msgstr "Saída:"
+
+#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Copy Selection"
+msgstr "Copiar Selección"
+
+#: editor/editor_log.cpp editor/editor_network_profiler.cpp
+#: editor/editor_profiler.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/property_editor.cpp editor/scene_tree_dock.cpp
+#: editor/script_editor_debugger.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Clear"
+msgstr "Limpar"
+
+#: editor/editor_log.cpp
+msgid "Clear Output"
+msgstr "Limpar Saída"
+
+#: editor/editor_network_profiler.cpp editor/editor_node.cpp
+#: editor/editor_profiler.cpp
+msgid "Stop"
+msgstr "Deter"
+
+#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
+#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
+msgid "Start"
+msgstr "Iniciar"
+
+#: editor/editor_network_profiler.cpp
+msgid "%s/s"
+msgstr "%s/s"
+
+#: editor/editor_network_profiler.cpp
+msgid "Down"
+msgstr "Baixada"
+
+#: editor/editor_network_profiler.cpp
+msgid "Up"
+msgstr "Subida"
+
+#: editor/editor_network_profiler.cpp editor/editor_node.cpp
+msgid "Node"
+msgstr "Nodo"
+
+#: editor/editor_network_profiler.cpp
+msgid "Incoming RPC"
+msgstr "RPC Entrante"
+
+#: editor/editor_network_profiler.cpp
+msgid "Incoming RSET"
+msgstr "RSET Entrante"
+
+#: editor/editor_network_profiler.cpp
+msgid "Outgoing RPC"
+msgstr "RPC Saínte"
+
+#: editor/editor_network_profiler.cpp
+msgid "Outgoing RSET"
+msgstr "RSET Saínte"
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr "Nova Xanela"
+
+#: editor/editor_node.cpp
+msgid "Imported resources can't be saved."
+msgstr "Os recursos importados non se poden gardar."
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: scene/gui/dialogs.cpp
+msgid "OK"
+msgstr "Vale"
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Error saving resource!"
+msgstr "Erro gardando o recurso!"
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource can't be saved because it does not belong to the edited scene. "
+"Make it unique first."
+msgstr ""
+"Este recurso non pode gardarse porque non pertence á escena actual. Primero "
+"fágao único."
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Save Resource As..."
+msgstr "Gardar Recurso Como..."
+
+#: editor/editor_node.cpp
+msgid "Can't open file for writing:"
+msgstr "Non se puido abrir o arquivo para escritura:"
+
+#: editor/editor_node.cpp
+msgid "Requested file format unknown:"
+msgstr "O formato do arquivo solicitado é descoñecido:"
+
+#: editor/editor_node.cpp
+msgid "Error while saving."
+msgstr "Erro ao gardar."
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Can't open '%s'. The file could have been moved or deleted."
+msgstr ""
+"Non se puido abrir '%s'. Pode ser que o arquivo fose movido ou eliminado."
+
+#: editor/editor_node.cpp
+msgid "Error while parsing '%s'."
+msgstr "Erro ao analizar sintacticamente '%s'."
+
+#: editor/editor_node.cpp
+msgid "Unexpected end of file '%s'."
+msgstr "Fin de arquivo inesperado en '%s'."
+
+#: editor/editor_node.cpp
+msgid "Missing '%s' or its dependencies."
+msgstr "Non se encontrou '%s' ou as súas dependencias."
+
+#: editor/editor_node.cpp
+msgid "Error while loading '%s'."
+msgstr "Erro ao cargar '%s'."
+
+#: editor/editor_node.cpp
+msgid "Saving Scene"
+msgstr "Gardando Escena"
+
+#: editor/editor_node.cpp
+msgid "Analyzing"
+msgstr "Analizando"
+
+#: editor/editor_node.cpp
+msgid "Creating Thumbnail"
+msgstr "Creando Miniatura"
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a tree root."
+msgstr "Esta operación non pode realizarse sen un nodo raíz."
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene can't be saved because there is a cyclic instancing inclusion.\n"
+"Please resolve it and then attempt to save again."
+msgstr ""
+"Esta escena non pode gardarse porque hai unha relación de instanciación "
+"cíclica con outra escena.\n"
+"Por favor, solucione o problema e inténteo de novo."
+
+#: editor/editor_node.cpp
+msgid ""
+"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
+"be satisfied."
+msgstr ""
+"Non se puido gardar a escena. Posiblemente as dependencias (instancias ou "
+"herenzas) non puideron satisfacerse."
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "Can't overwrite scene that is still open!"
+msgstr "Non se pode sobreescribir escena que sigue aberta!"
+
+#: editor/editor_node.cpp
+msgid "Can't load MeshLibrary for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving MeshLibrary!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load TileSet for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving TileSet!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"An error occurred while trying to save the editor layout.\n"
+"Make sure the editor's user data path is writable."
+msgstr ""
+"Produciuse un erro mentres se trataba de gardar a disposición das ventás do "
+"editor.\n"
+"Asegúrese de que o cartafol do editor ten dereitos de escritura."
+
+#: editor/editor_node.cpp
+msgid ""
+"Default editor layout overridden.\n"
+"To restore the Default layout to its base settings, use the Delete Layout "
+"option and delete the Default layout."
+msgstr ""
+"A disposición por defecto do editor foi sobreescrita.\n"
+"Para devolver a disposición por defecto a súa configuración orixinal, usa a "
+"opción 'Eliminar Disposición' e elimina a Disposición por defecto."
+
+#: editor/editor_node.cpp
+msgid "Layout name not found!"
+msgstr "Nome de disposición non encontrada!"
+
+#: editor/editor_node.cpp
+msgid "Restored the Default layout to its base settings."
+msgstr "Restableceuse a disposición por defecto aos seus valores orixinais."
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was imported, so it's not editable.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+"Este recurso pertence a unha escena importada, polo que non é editable.\n"
+"Por favor; lea a documentación referente a importación de escenas para "
+"entender o fluxo de traballo."
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was instanced or inherited.\n"
+"Changes to it won't be kept when saving the current scene."
+msgstr ""
+"Este recurso pertence a unha escena instanciada ou herdada.\n"
+"Os cambios que lle faga non se gardarán cando garde a escena actual."
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource was imported, so it's not editable. Change its settings in the "
+"import panel and then re-import."
+msgstr ""
+"Este recurso foi importado, polo que non é editable. Cambia a súa "
+"configuración no panel de importación, e reimportao."
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene was imported, so changes to it won't be kept.\n"
+"Instancing it or inheriting will allow making changes to it.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+"Esta escena foi importada, polo que cambios na escena non serán gardados.\n"
+"Instanciala ou herdala permitirá facerlle cambios permanentes.\n"
+"Por favor, lea a documentación referente a importación de escenas para "
+"entender o fluxo de traballo."
+
+#: editor/editor_node.cpp
+msgid ""
+"This is a remote object, so changes to it won't be kept.\n"
+"Please read the documentation relevant to debugging to better understand "
+"this workflow."
+msgstr ""
+"Este é un obxecto remoto, polo que os cambios que lle faga non serán "
+"permanentes.\n"
+"Por favor; lea a documentación referente a depuración para entender o fluxo "
+"de traballo."
+
+#: editor/editor_node.cpp
+msgid "There is no defined scene to run."
+msgstr "Non hai unha escena definida para executar."
+
+#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Garda a escena antes de executala..."
+
+#: editor/editor_node.cpp
+msgid "Could not start subprocess!"
+msgstr "Non se puido iniciar subproceso!"
+
+#: editor/editor_node.cpp editor/filesystem_dock.cpp
+msgid "Open Scene"
+msgstr "Abrir Escena"
+
+#: editor/editor_node.cpp
+msgid "Open Base Scene"
+msgstr "Abrir Escena Base"
+
+#: editor/editor_node.cpp
+msgid "Quick Open..."
+msgstr "Apertura Rápida..."
+
+#: editor/editor_node.cpp
+msgid "Quick Open Scene..."
+msgstr "Apertura Rápida de Escena..."
+
+#: editor/editor_node.cpp
+msgid "Quick Open Script..."
+msgstr "Apertura Rápida de Script..."
+
+#: editor/editor_node.cpp
+msgid "Save & Close"
+msgstr "Gardar e Pechar"
+
+#: editor/editor_node.cpp
+msgid "Save changes to '%s' before closing?"
+msgstr "Gardar os cambios de '%s' antes de pechar?"
+
+#: editor/editor_node.cpp
+msgid "Saved %s modified resource(s)."
+msgstr "Gardado(s) %s recurso(s) modificado(s)."
+
+#: editor/editor_node.cpp
+msgid "A root node is required to save the scene."
+msgstr "Necesítase un nodo raíz para gardar a escena."
+
+#: editor/editor_node.cpp
+msgid "Save Scene As..."
+msgstr "Gardar Escena Como..."
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "This operation can't be done without a scene."
+msgstr "Esta operación non pode realizarse se unha escena."
+
+#: editor/editor_node.cpp
+msgid "Export Mesh Library"
+msgstr "Exportar Biblioteca de Mallas"
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a root node."
+msgstr "Esta operación non pode realizarse sen un nodo raíz."
+
+#: editor/editor_node.cpp
+msgid "Export Tile Set"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a selected node."
+msgstr "Esta operación non pode realizarse sen un nodo seleccionado."
+
+#: editor/editor_node.cpp
+msgid "Current scene not saved. Open anyway?"
+msgstr "Escena actual non gardada ¿Abrir de todos os modos?"
+
+#: editor/editor_node.cpp
+msgid "Can't reload a scene that was never saved."
+msgstr "Non se pode volver a cargar unha escena que nunca foi gardada."
+
+#: editor/editor_node.cpp
+msgid "Reload Saved Scene"
+msgstr "Recargar Escena Gardada"
+
+#: editor/editor_node.cpp
+msgid ""
+"The current scene has unsaved changes.\n"
+"Reload the saved scene anyway? This action cannot be undone."
+msgstr ""
+"A escena actual ten cambios non gardados.\n"
+"Quere volver a cargar a escena cargada de todos os modos? Esta acción non se "
+"pode deshacer."
+
+#: editor/editor_node.cpp
+msgid "Quick Run Scene..."
+msgstr "Execución Rápida de Escena..."
+
+#: editor/editor_node.cpp
+msgid "Quit"
+msgstr "Saír"
+
+#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Si"
+
+#: editor/editor_node.cpp
+msgid "Exit the editor?"
+msgstr "Saír do editor?"
+
+#: editor/editor_node.cpp
+msgid "Open Project Manager?"
+msgstr "Abrir o Administrador de Proxectos?"
+
+#: editor/editor_node.cpp
+msgid "Save & Quit"
+msgstr "Gardar e Saír"
+
+#: editor/editor_node.cpp
+msgid "Save changes to the following scene(s) before quitting?"
+msgstr "Gardar os cambios nas seguintes escenas antes de saír?"
+
+#: editor/editor_node.cpp
+msgid "Save changes the following scene(s) before opening Project Manager?"
+msgstr ""
+"Gardar os cambios nas seguintes escenas antes de abrir o Administrador de "
+"Proxectos?"
+
+#: editor/editor_node.cpp
+msgid ""
+"This option is deprecated. Situations where refresh must be forced are now "
+"considered a bug. Please report."
+msgstr ""
+"Esta opción está anticuada. As situacións nas que a actualización debe ser "
+"forzada agora considéranse un erro. Por favor, repórtao."
+
+#: editor/editor_node.cpp
+msgid "Pick a Main Scene"
+msgstr "Elexir unha Escena Principal"
+
+#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr "Pechar Escena"
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr "Reabrir Escena Pechada"
+
+#: editor/editor_node.cpp
+msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
+msgstr ""
+"Non se puido activar a característica adicional (Plugin): Fallou a análise "
+"sintáctica da configuración de '%s'."
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr ""
+"Non se puido encontrar o campo do Script na característica adicional "
+"(Plugin) en 'res://addons/%s'."
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s'."
+msgstr ""
+"Non se puido cargar Script de característica adicional (Addon) na ruta: '%s'."
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' There seems to be an error in "
+"the code, please check the syntax."
+msgstr ""
+"Non se puido cargar Script de característica adicional (Addon) na ruta: "
+"'%s'. Parece que hai un erro no código; por favor, comproba a sintaxe."
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
+msgstr ""
+"Non se puido cargar o Script da característica adicional (Plugin): O tipo "
+"base de %s non é EditorPlugin."
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
+msgstr ""
+"Non se puido cargar Script de característica adicional (Addon) na ruta: "
+"'%s'. O script non está en modo ferramenta (tool)."
+
+#: editor/editor_node.cpp
+msgid ""
+"Scene '%s' was automatically imported, so it can't be modified.\n"
+"To make changes to it, a new inherited scene can be created."
+msgstr ""
+"A escena '%s' foi automáticamente importada, polo que non pode modificarse.\n"
+"Para facerlle cambios pódese crear unha nova escena herdada."
+
+#: editor/editor_node.cpp
+msgid ""
+"Error loading scene, it must be inside the project path. Use 'Import' to "
+"open the scene, then save it inside the project path."
+msgstr ""
+"Erro cargando a escena: debe estar dentro da ruta do proxecto. Usa \"Importar"
+"\" para abrir a escena, e despois gardala dentro da ruta do proxecto."
+
+#: editor/editor_node.cpp
+msgid "Scene '%s' has broken dependencies:"
+msgstr "A escena '%s' ten dependencias rotas:"
+
+#: editor/editor_node.cpp
+msgid "Clear Recent Scenes"
+msgstr "Limpar Escenas Recentes"
+
+#: editor/editor_node.cpp
+msgid ""
+"No main scene has ever been defined, select one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+"Nunca se definiu unha escena principal. Seleccionar unha?\n"
+"Podes cambialo despois na \"Configuración do Proxecto\", na categoría "
+"\"Aplicación\"."
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' does not exist, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+"A escena seleccionada '%s' non existe. Seleccionar unha válida?\n"
+"Podes cambiala despois en \"Configuración do Proxecto\" na categoría "
+"\"aplicación\"."
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' is not a scene file, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+"A escena seleccionada '%s' non é un arquivo de escenas. Seleccionar un "
+"arquivo válido?\n"
+"Podes cambialo despois en \"Configuración do Proxecto\" na categoría "
+"\"aplicación\"."
+
+#: editor/editor_node.cpp
+msgid "Save Layout"
+msgstr "Gardar Disposición"
+
+#: editor/editor_node.cpp
+msgid "Delete Layout"
+msgstr "Eliminar Dispoción"
+
+#: editor/editor_node.cpp editor/import_dock.cpp
+#: editor/script_create_dialog.cpp
+msgid "Default"
+msgstr "Por Defecto"
+
+#: editor/editor_node.cpp editor/editor_properties.cpp
+#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
+msgid "Show in FileSystem"
+msgstr "Amosar no Sistema de Arquivos"
+
+#: editor/editor_node.cpp
+msgid "Play This Scene"
+msgstr "Reproducir Esta Escena"
+
+#: editor/editor_node.cpp
+msgid "Close Tab"
+msgstr "Pechar Pestana"
+
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr "Desfacer Pechar Pestana"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Close Other Tabs"
+msgstr "Pechar Outras Pestanas"
+
+#: editor/editor_node.cpp
+msgid "Close Tabs to the Right"
+msgstr "Pechar Pestanas á Dereita"
+
+#: editor/editor_node.cpp
+msgid "Close All Tabs"
+msgstr "Pechar Todas as Pestanas"
+
+#: editor/editor_node.cpp
+msgid "Switch Scene Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files or folders"
+msgstr "%d arquivos ou cartafois máis"
+
+#: editor/editor_node.cpp
+msgid "%d more folders"
+msgstr "%d cartafois máis"
+
+#: editor/editor_node.cpp
+msgid "%d more files"
+msgstr "%d arquivos máis"
+
+#: editor/editor_node.cpp
+msgid "Dock Position"
+msgstr "Posición do Panel"
+
+#: editor/editor_node.cpp
+msgid "Distraction Free Mode"
+msgstr "Modo Sen Distraccións"
+
+#: editor/editor_node.cpp
+msgid "Toggle distraction-free mode."
+msgstr "Act./Desact. modo sen distraccións."
+
+#: editor/editor_node.cpp
+msgid "Add a new scene."
+msgstr "Engadir unha nova escena."
+
+#: editor/editor_node.cpp
+msgid "Scene"
+msgstr "Escena"
+
+#: editor/editor_node.cpp
+msgid "Go to previously opened scene."
+msgstr "Ir á escena aberta previamente."
+
+#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr "Copiar Texto"
+
+#: editor/editor_node.cpp
+msgid "Next tab"
+msgstr "Seguinte pestana"
+
+#: editor/editor_node.cpp
+msgid "Previous tab"
+msgstr "Anterior Pestana"
+
+#: editor/editor_node.cpp
+msgid "Filter Files..."
+msgstr "Filtrar Arquivos..."
+
+#: editor/editor_node.cpp
+msgid "Operations with scene files."
+msgstr "Operacións con arquivos de escenas."
+
+#: editor/editor_node.cpp
+msgid "New Scene"
+msgstr "Nova Escena"
+
+#: editor/editor_node.cpp
+msgid "New Inherited Scene..."
+msgstr "Nova Escena Herdada..."
+
+#: editor/editor_node.cpp
+msgid "Open Scene..."
+msgstr "Abrir Escena..."
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr "Abrir Recente"
+
+#: editor/editor_node.cpp
+msgid "Save Scene"
+msgstr "Gardar Escena"
+
+#: editor/editor_node.cpp
+msgid "Save All Scenes"
+msgstr "Gardar Todas as Escenas"
+
+#: editor/editor_node.cpp
+msgid "Convert To..."
+msgstr "Converter a..."
+
+#: editor/editor_node.cpp
+msgid "MeshLibrary..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "TileSet..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Undo"
+msgstr "Desfacer"
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Redo"
+msgstr "Refacer"
+
+#: editor/editor_node.cpp
+msgid "Miscellaneous project or scene-wide tools."
+msgstr "Ferramentas varias do proxecto ou escena."
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+#: editor/script_create_dialog.cpp
+msgid "Project"
+msgstr "Proxecto"
+
+#: editor/editor_node.cpp
+msgid "Project Settings..."
+msgstr "Axustes do Proxecto..."
+
+#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
+msgid "Version Control"
+msgstr "Control de Versións"
+
+#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
+msgid "Set Up Version Control"
+msgstr "Configurar Control de Versións"
+
+#: editor/editor_node.cpp
+msgid "Shut Down Version Control"
+msgstr "Desactivar Control de Versións"
+
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr "Exportar..."
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Data Folder"
+msgstr "Abrir Cartafol de Datos do Proxecto"
+
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr "Ferramentas"
+
+#: editor/editor_node.cpp
+msgid "Orphan Resource Explorer..."
+msgstr "Explorador de Recursos Orfos..."
+
+#: editor/editor_node.cpp
+msgid "Quit to Project List"
+msgstr "Saír á Lista de Proxectos"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/project_export.cpp
+msgid "Debug"
+msgstr "Depuración"
+
+#: editor/editor_node.cpp
+msgid "Deploy with Remote Debug"
+msgstr "Exportar con Depuración Remota"
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
+msgstr ""
+"Cando esta opción está activada, usar o despregue dun só clic fará que o "
+"executable intente conectarse a IP deste computador, para poder depurar o "
+"proxecto mentres este está executandose no dispositivo.\n"
+"Esta opción está pensada para ser utilizada coa depuración remota "
+"(normalmente nun dispositivo móbil).\n"
+"Non necesita activar esta opción para utilizar o depurador de GDScript de "
+"forma local."
+
+#: editor/editor_node.cpp
+msgid "Small Deploy with Network Filesystem"
+msgstr "Exportación Reducida co Sistema de Arquivos en Rede"
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
+"The filesystem will be provided from the project by the editor over the "
+"network.\n"
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
+msgstr ""
+"Cando esta opción está activada, usar o despregue don só clic para Android "
+"exportará só o executable, sen os datos do proxecto.\n"
+"O sistema de arquivos proporcionarase por o editor na rede.\n"
+"En Android ao despregar a aplicación usarase o USB para obter maior "
+"rendemento. Esta opción acelera o proceso de proba en proxectos con gran "
+"cantidade de Assets."
+
+#: editor/editor_node.cpp
+msgid "Visible Collision Shapes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Visible Navigation"
+msgstr "Navegación Visible"
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Synchronize Scene Changes"
+msgstr "Sincronizar Cambios na Escena"
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
+msgstr ""
+"Cando esta opción está activada, calquera cambio na escena no editor verase "
+"reflectido no proxecto en execución.\n"
+"Cando é usado remotamente nun dispositivo, é máis eficiente cando o sistema "
+"de arquivos en rede está activado."
+
+#: editor/editor_node.cpp
+msgid "Synchronize Script Changes"
+msgstr "Sincronizar Cambios nos Scripts"
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
+msgstr ""
+"Cando esta opción está activada, calquera script gardada será recargada no "
+"proxecto mentras este está en execución.\n"
+"Cando é usado remotamente nun dispositivo, é máis eficiente cando o sistema "
+"de arquivos en rede está activado."
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Editor"
+msgstr "Editor"
+
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
+msgstr "Configuración do Editor..."
+
+#: editor/editor_node.cpp
+msgid "Editor Layout"
+msgstr "Disposición das Ventás do Editor"
+
+#: editor/editor_node.cpp
+msgid "Take Screenshot"
+msgstr "Captura de Pantalla"
+
+#: editor/editor_node.cpp
+msgid "Screenshots are stored in the Editor Data/Settings Folder."
+msgstr ""
+"As capturas de pantalla gárdanse no cartafol de Datos/Configuración do "
+"Editor."
+
+#: editor/editor_node.cpp
+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"
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data Folder"
+msgstr "Abrir Cartafol de Datos do Editor"
+
+#: editor/editor_node.cpp
+msgid "Open Editor Settings Folder"
+msgstr "Abrir Cartafol de Configuración do Editor"
+
+#: editor/editor_node.cpp
+msgid "Manage Editor Features..."
+msgstr "Administrar Características do Editor..."
+
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
+msgid "Help"
+msgstr "Axuda"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Online Docs"
+msgstr "Documentación En Liña"
+
+#: editor/editor_node.cpp
+msgid "Q&A"
+msgstr "Preguntas e Respostas"
+
+#: editor/editor_node.cpp
+msgid "Report a Bug"
+msgstr "Reportar un Erro"
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr "Reportar Problema ca Documentación"
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+msgid "Community"
+msgstr "Comunidade"
+
+#: editor/editor_node.cpp
+msgid "About"
+msgstr "Acerca De"
+
+#: editor/editor_node.cpp
+msgid "Play the project."
+msgstr "Reproduce o proxecto."
+
+#: editor/editor_node.cpp
+msgid "Play"
+msgstr "Executar"
+
+#: editor/editor_node.cpp
+msgid "Pause the scene execution for debugging."
+msgstr "Pausa a execución da escena para a depuración."
+
+#: editor/editor_node.cpp
+msgid "Pause Scene"
+msgstr "Pausar Escena"
+
+#: editor/editor_node.cpp
+msgid "Stop the scene."
+msgstr "Detén a escena."
+
+#: editor/editor_node.cpp
+msgid "Play the edited scene."
+msgstr "Reproduce a escena actual."
+
+#: editor/editor_node.cpp
+msgid "Play Scene"
+msgstr "Executar Escena"
+
+#: editor/editor_node.cpp
+msgid "Play custom scene"
+msgstr "Executar escena a elixir"
+
+#: editor/editor_node.cpp
+msgid "Play Custom Scene"
+msgstr "Executar Escena a Elixir"
+
+#: editor/editor_node.cpp
+msgid "Changing the video driver requires restarting the editor."
+msgstr "Cambiar o controlador de vídeo require reiniciar o editor."
+
+#: editor/editor_node.cpp editor/project_settings_editor.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Save & Restart"
+msgstr "Gardar e Reinicar"
+
+#: editor/editor_node.cpp
+msgid "Spins when the editor window redraws."
+msgstr "Xira cando o editor actualiza a pantalla."
+
+#: editor/editor_node.cpp
+msgid "Update Continuously"
+msgstr "Actualizar de Maneira Continua"
+
+#: editor/editor_node.cpp
+msgid "Update When Changed"
+msgstr "Actualizar Cando Sexa Necesario"
+
+#: editor/editor_node.cpp
+msgid "Hide Update Spinner"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "FileSystem"
+msgstr "Sistema de Arquivos"
+
+#: editor/editor_node.cpp
+msgid "Inspector"
+msgstr "Inspector"
+
+#: editor/editor_node.cpp
+msgid "Expand Bottom Panel"
+msgstr "Estender Panel Inferior"
+
+#: editor/editor_node.cpp
+msgid "Output"
+msgstr "Saída"
+
+#: editor/editor_node.cpp
+msgid "Don't Save"
+msgstr "Non Gardar"
+
+#: editor/editor_node.cpp
+msgid "Android build template is missing, please install relevant templates."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Templates"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This will set up your project for custom Android builds by installing the "
+"source template to \"res://android/build\".\n"
+"You can then apply modifications and build your own custom APK on export "
+"(adding modules, changing the AndroidManifest.xml, etc.).\n"
+"Note that in order to make custom builds instead of using pre-built APKs, "
+"the \"Use Custom Build\" option should be enabled in the Android export "
+"preset."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"The Android build template is already installed in this project and it won't "
+"be overwritten.\n"
+"Remove the \"res://android/build\" directory manually before attempting this "
+"operation again."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Import Templates From ZIP File"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Template Package"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Library"
+msgstr "Biblioteca de Exportación"
+
+#: editor/editor_node.cpp
+msgid "Merge With Existing"
+msgstr "Combinar Con Existentes"
+
+#: editor/editor_node.cpp
+msgid "Open & Run a Script"
+msgstr "Abrir e Executar un Script"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Este shader foi modificado en disco.\n"
+"Que acción deberían de tomarse?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Recargar"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Volver a Gardar"
+
+#: editor/editor_node.cpp
+msgid "New Inherited"
+msgstr "Nova Escena Herdada"
+
+#: editor/editor_node.cpp
+msgid "Load Errors"
+msgstr "Erros durante a Carga"
+
+#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Select"
+msgstr "Elixir"
+
+#: editor/editor_node.cpp
+msgid "Open 2D Editor"
+msgstr "Abrir Editor 2D"
+
+#: editor/editor_node.cpp
+msgid "Open 3D Editor"
+msgstr "Abrir Editor 3D"
+
+#: editor/editor_node.cpp
+msgid "Open Script Editor"
+msgstr "Abrir Editor de Scripts"
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "Open Asset Library"
+msgstr "Abrir Biblioteca de Assets"
+
+#: editor/editor_node.cpp
+msgid "Open the next Editor"
+msgstr "Abrir o seguinte editor"
+
+#: editor/editor_node.cpp
+msgid "Open the previous Editor"
+msgstr "Abrir o anterior editor"
+
+#: editor/editor_node.h
+msgid "Warning!"
+msgstr "Aviso!"
+
+#: editor/editor_path.cpp
+msgid "No sub-resources found."
+msgstr "Non se atopou ningún sub-recurso."
+
+#: editor/editor_plugin.cpp
+msgid "Creating Mesh Previews"
+msgstr "Creando Previsualización de Mallas"
+
+#: editor/editor_plugin.cpp
+msgid "Thumbnail..."
+msgstr "Miniatura..."
+
+#: editor/editor_plugin_settings.cpp
+msgid "Main Script:"
+msgstr "Script Principal:"
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit Plugin"
+msgstr "Editar Característica Adicional (Plugin)"
+
+#: editor/editor_plugin_settings.cpp
+msgid "Installed Plugins:"
+msgstr "Características Adicionais (Plugins) Instalados:"
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Update"
+msgstr "Actualizar"
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Version:"
+msgstr "Versión:"
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Author:"
+msgstr "Autor:"
+
+#: editor/editor_plugin_settings.cpp
+msgid "Status:"
+msgstr "Estado:"
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit:"
+msgstr "Editar:"
+
+#: editor/editor_profiler.cpp
+msgid "Measure:"
+msgstr "Medida:"
+
+#: editor/editor_profiler.cpp
+msgid "Frame Time (sec)"
+msgstr "Duración de Fotograma (seg)"
+
+#: editor/editor_profiler.cpp
+msgid "Average Time (sec)"
+msgstr "Tempo Medio (seg)"
+
+#: editor/editor_profiler.cpp
+msgid "Frame %"
+msgstr "Fotograma %"
+
+#: editor/editor_profiler.cpp
+msgid "Physics Frame %"
+msgstr "Fotograma de Física %"
+
+#: editor/editor_profiler.cpp
+msgid "Inclusive"
+msgstr "Inclusivo"
+
+#: editor/editor_profiler.cpp
+msgid "Self"
+msgstr "Propio"
+
+#: editor/editor_profiler.cpp
+msgid "Frame #:"
+msgstr "Fotograma #:"
+
+#: editor/editor_profiler.cpp
+msgid "Time"
+msgstr "Tempo"
+
+#: editor/editor_profiler.cpp
+msgid "Calls"
+msgstr "Chamadas"
+
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr "Editar Texto:"
+
+#: editor/editor_properties.cpp editor/script_create_dialog.cpp
+msgid "On"
+msgstr "Activado"
+
+#: editor/editor_properties.cpp
+msgid "Layer"
+msgstr "Capa"
+
+#: editor/editor_properties.cpp
+msgid "Bit %d, value %d"
+msgstr "Bit %d, valor %d"
+
+#: editor/editor_properties.cpp
+msgid "[Empty]"
+msgstr "[Baleiro]"
+
+#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
+msgid "Assign..."
+msgstr "Asignar..."
+
+#: editor/editor_properties.cpp
+msgid "Invalid RID"
+msgstr "Identificador de Recurso (RID) inválido"
+
+#: editor/editor_properties.cpp
+msgid ""
+"The selected resource (%s) does not match any type expected for this "
+"property (%s)."
+msgstr ""
+"O recurso seleccionado (%s) non coincide con ningún tipo esperado para esta "
+"propiedade (%s)."
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on resources saved as a file.\n"
+"Resource needs to belong to a scene."
+msgstr ""
+"Non se pode crear un ViewportTexture nun recurso gardado coma un arquivo.\n"
+"O recurso ten que pertencer a unha escena."
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on this resource because it's not set as "
+"local to scene.\n"
+"Please switch on the 'local to scene' property on it (and all resources "
+"containing it up to a node)."
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Pick a Viewport"
+msgstr "Selecciona unha Mini-Ventá (Viewport)"
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New Script"
+msgstr "Novo Script"
+
+#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
+msgid "Extend Script"
+msgstr "Estender Script"
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New %s"
+msgstr "Novo %s"
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Make Unique"
+msgstr "Facer Único"
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Paste"
+msgstr "Pegar"
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Convert To %s"
+msgstr "Converter a %s"
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Selected node is not a Viewport!"
+msgstr "O nodo seleccionado non é unha Mini-Ventá (Viewport)!"
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Size: "
+msgstr "Tamaño: "
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Page: "
+msgstr "Páxina: "
+
+#: editor/editor_properties_array_dict.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Item"
+msgstr "Eliminar Elemento"
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Key:"
+msgstr "Nova Chave:"
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Value:"
+msgstr "Novo Valor:"
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Add Key/Value Pair"
+msgstr "Engadir Parella Chave/Valor"
+
+#: editor/editor_run_native.cpp
+msgid ""
+"No runnable export preset found for this platform.\n"
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
+msgstr ""
+"Non se encontraron axustes de exportación executables para esta plataforma.\n"
+"Engade uns axustes de exportación executables, ou define algún xa existente "
+"como executable."
+
+#: editor/editor_run_script.cpp
+msgid "Write your logic in the _run() method."
+msgstr "Escribe a túa lóxica no método '_run()'."
+
+#: editor/editor_run_script.cpp
+msgid "There is an edited scene already."
+msgstr "Xa hai unha escena editada."
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't instance script:"
+msgstr "Non se puido instanciar o script:"
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the 'tool' keyword?"
+msgstr "Olvidaches a palabra clave 'tool'?"
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't run script:"
+msgstr "Non se puido executar o script:"
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the '_run' method?"
+msgstr "Olvidaches o método '_run'?"
+
+#: editor/editor_spin_slider.cpp
+msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes."
+msgstr ""
+"Mantén pulsado Ctrl para redondear a enteiros. Mantén pulsado Shift para "
+"cambios máis precisos."
+
+#: editor/editor_sub_scene.cpp
+msgid "Select Node(s) to Import"
+msgstr "Selecciona o(s) Nodo(s) a Importar"
+
+#: editor/editor_sub_scene.cpp editor/project_manager.cpp
+msgid "Browse"
+msgstr "Examinar"
+
+#: editor/editor_sub_scene.cpp
+msgid "Scene Path:"
+msgstr "Ruta da Escena:"
+
+#: editor/editor_sub_scene.cpp
+msgid "Import From Node:"
+msgstr "Importar Desde Nodo:"
+
+#: editor/export_template_manager.cpp
+msgid "Redownload"
+msgstr "Volver a Descargar"
+
+#: editor/export_template_manager.cpp
+msgid "Uninstall"
+msgstr "Desinstalar"
+
+#: editor/export_template_manager.cpp
+msgid "(Installed)"
+msgstr "(Instalado)"
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download"
+msgstr "Descargar"
+
+#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Missing)"
+msgstr "(Non encontrado)"
+
+#: editor/export_template_manager.cpp
+msgid "(Current)"
+msgstr "(Actual)"
+
+#: editor/export_template_manager.cpp
+msgid "Retrieving mirrors, please wait..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove template version '%s'?"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't open export templates zip."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Invalid version.txt format inside templates: %s."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "No version.txt found inside templates."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error creating path for templates:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Extracting Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Importing:"
+msgstr "Importando:"
+
+#: editor/export_template_manager.cpp
+msgid "Error getting the list of mirrors."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error parsing JSON of mirror list. Please report this issue!"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"No download links found for this version. Direct download is only available "
+"for official releases."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect."
+msgstr "Non se pode conectar."
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response."
+msgstr "Sen resposta."
+
+#: editor/export_template_manager.cpp
+msgid "Request Failed."
+msgstr "A Petición Fracasou."
+
+#: editor/export_template_manager.cpp
+msgid "Redirect Loop."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed:"
+msgstr "Fracasado:"
+
+#: editor/export_template_manager.cpp
+msgid "Download Complete."
+msgstr "Descarga Completa."
+
+#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr "Non se pode eliminar o arquivo temporal:"
+
+#: editor/export_template_manager.cpp
+msgid ""
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error requesting URL:"
+msgstr "Erro ao solicitar a URL:"
+
+#: editor/export_template_manager.cpp
+msgid "Connecting to Mirror..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Disconnected"
+msgstr "Desconectado"
+
+#: editor/export_template_manager.cpp
+msgid "Resolving"
+msgstr "Resolvendo"
+
+#: editor/export_template_manager.cpp
+msgid "Can't Resolve"
+msgstr "Non se puido Resolver"
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connecting..."
+msgstr "Conectando..."
+
+#: editor/export_template_manager.cpp
+msgid "Can't Connect"
+msgstr "Non se Pode Conectar"
+
+#: editor/export_template_manager.cpp
+msgid "Connected"
+msgstr "Conectado"
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Requesting..."
+msgstr "Solicitando..."
+
+#: editor/export_template_manager.cpp
+msgid "Downloading"
+msgstr "Descargando"
+
+#: editor/export_template_manager.cpp
+msgid "Connection Error"
+msgstr "Erro de Conexión"
+
+#: editor/export_template_manager.cpp
+msgid "SSL Handshake Error"
+msgstr "Erro SSL Handshake"
+
+#: editor/export_template_manager.cpp
+msgid "Uncompressing Android Build Sources"
+msgstr "Descomprimindo Recursos de Compilación de Android"
+
+#: editor/export_template_manager.cpp
+msgid "Current Version:"
+msgstr "Versión Actual:"
+
+#: editor/export_template_manager.cpp
+msgid "Installed Versions:"
+msgstr "Versións Instaladas:"
+
+#: editor/export_template_manager.cpp
+msgid "Install From File"
+msgstr "Instalar Dende Arquivo"
+
+#: editor/export_template_manager.cpp
+msgid "Remove Template"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select Template File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Godot Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Export Template Manager"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select mirror from list: (Shift+Click: Open in Browser)"
+msgstr "Seleccione un mirror da lista: (Shift+Clic: Abrir no Navegador)"
+
+#: editor/filesystem_dock.cpp
+msgid "Favorites"
+msgstr "Favoritos"
+
+#: editor/filesystem_dock.cpp
+msgid "Status: Import of file failed. Please fix file and reimport manually."
+msgstr ""
+"Estado: Fallou a importación do arquivo. Por favor, amaña o arquivo e "
+"impórtao manualmente."
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move/rename resources root."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move a folder into itself."
+msgstr "Non se pode mover un cartafol dentro de sí mesmo."
+
+#: editor/filesystem_dock.cpp
+msgid "Error moving:"
+msgstr "Erro ao mover:"
+
+#: editor/filesystem_dock.cpp
+msgid "Error duplicating:"
+msgstr "Erro ao duplicar:"
+
+#: editor/filesystem_dock.cpp
+msgid "Unable to update dependencies:"
+msgstr "Incapaz de actualizar dependencias:"
+
+#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
+msgid "No name provided."
+msgstr "Nome non proporcionado."
+
+#: editor/filesystem_dock.cpp
+msgid "Provided name contains invalid characters."
+msgstr "O nome proporcionado contén caracteres inválidos."
+
+#: editor/filesystem_dock.cpp
+msgid "A file or folder with this name already exists."
+msgstr "Xa existe un arquivo ou cartafol con este nome."
+
+#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr "O nome contén caracteres inválidos."
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"The following files or folders conflict with items in the target location "
+"'%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Do you wish to overwrite them?"
+msgstr ""
+"Os seguintes arquivos ou cartafois entran en conflicto con elementos da "
+"ubicación de destino '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Queres sobreescribilos?"
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming file:"
+msgstr "Renomeando Arquivo:"
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming folder:"
+msgstr "Renomeando Cartafol:"
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating file:"
+msgstr "Duplicando Arquivo:"
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating folder:"
+msgstr "Duplicando Cartafol:"
+
+#: editor/filesystem_dock.cpp
+msgid "New Inherited Scene"
+msgstr "Nova Escena Herdada"
+
+#: editor/filesystem_dock.cpp
+msgid "Set As Main Scene"
+msgstr "Establecer coma Escena Principal"
+
+#: editor/filesystem_dock.cpp
+msgid "Open Scenes"
+msgstr "Abrir Escenas"
+
+#: editor/filesystem_dock.cpp
+msgid "Instance"
+msgstr "Instanciar"
+
+#: editor/filesystem_dock.cpp
+msgid "Add to Favorites"
+msgstr "Engadir a Favoritos"
+
+#: editor/filesystem_dock.cpp
+msgid "Remove from Favorites"
+msgstr "Eliminar de Favoritos"
+
+#: editor/filesystem_dock.cpp
+msgid "Edit Dependencies..."
+msgstr "Editar Dependencias..."
+
+#: editor/filesystem_dock.cpp
+msgid "View Owners..."
+msgstr "Ver Donos..."
+
+#: editor/filesystem_dock.cpp
+msgid "Move To..."
+msgstr "Mover a..."
+
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr "Nova Escena..."
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "New Script..."
+msgstr "Novo Script..."
+
+#: editor/filesystem_dock.cpp
+msgid "New Resource..."
+msgstr "Novo Recurso..."
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Expand All"
+msgstr "Expandir Todo"
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Collapse All"
+msgstr "Colapsar Todo"
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicate..."
+msgstr "Duplicar..."
+
+#: editor/filesystem_dock.cpp
+msgid "Move to Trash"
+msgstr "Mover á Papeleira"
+
+#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Rename..."
+msgstr "Renomear..."
+
+#: editor/filesystem_dock.cpp
+msgid "Previous Folder/File"
+msgstr "Anterior Cartafol/Arquivo"
+
+#: editor/filesystem_dock.cpp
+msgid "Next Folder/File"
+msgstr "Seguinte Cartafol/Arquivo"
+
+#: editor/filesystem_dock.cpp
+msgid "Re-Scan Filesystem"
+msgstr "Reexaminar Sistema de Arquivos"
+
+#: editor/filesystem_dock.cpp
+msgid "Toggle Split Mode"
+msgstr "Act./Desact. Modo Dividido"
+
+#: editor/filesystem_dock.cpp
+msgid "Search files"
+msgstr "Buscar arquivos"
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"Scanning Files,\n"
+"Please Wait..."
+msgstr ""
+"Examinando arquivos,\n"
+"Por favor, espere..."
+
+#: editor/filesystem_dock.cpp
+msgid "Move"
+msgstr "Mover"
+
+#: editor/filesystem_dock.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/project_manager.cpp editor/rename_dialog.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Rename"
+msgstr "Renomear"
+
+#: editor/filesystem_dock.cpp
+msgid "Overwrite"
+msgstr "Sobreescribir"
+
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr "Crear Escena"
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Create Script"
+msgstr "Crear Script"
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Find in Files"
+msgstr "Buscar en Arquivos"
+
+#: editor/find_in_files.cpp
+msgid "Find:"
+msgstr "Buscar:"
+
+#: editor/find_in_files.cpp
+msgid "Folder:"
+msgstr "Cartafol:"
+
+#: editor/find_in_files.cpp
+msgid "Filters:"
+msgstr "Filtros:"
+
+#: editor/find_in_files.cpp
+msgid ""
+"Include the files with the following extensions. Add or remove them in "
+"ProjectSettings."
+msgstr ""
+"Inclúe os arquivos coas seguintes extensións. Engádeos ou elimínaos na "
+"Configuración do proxecto."
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find..."
+msgstr "Buscar..."
+
+#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
+msgid "Replace..."
+msgstr "Substituír..."
+
+#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: editor/find_in_files.cpp
+msgid "Find: "
+msgstr "Buscar: "
+
+#: editor/find_in_files.cpp
+msgid "Replace: "
+msgstr "Substituír: "
+
+#: editor/find_in_files.cpp
+msgid "Replace all (no undo)"
+msgstr "Substituír todo (non se pode defacer)"
+
+#: editor/find_in_files.cpp
+msgid "Searching..."
+msgstr "Procurando..."
+
+#: editor/find_in_files.cpp
+msgid "%d match in %d file."
+msgstr "%d coincidencia en %d arquivo."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d coincidencias en %d arquivo."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d coincidencias en %d arquivos."
+
+#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr "Engadir ao Grupo"
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr "Eliminar do Grupo"
+
+#: editor/groups_editor.cpp
+msgid "Group name already exists."
+msgstr "Este nome de grupo xa existe."
+
+#: editor/groups_editor.cpp
+msgid "Invalid group name."
+msgstr "Nome de grupo inválido."
+
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr "Renomear Grupo"
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr "Eliminar Grupo"
+
+#: editor/groups_editor.cpp editor/node_dock.cpp
+msgid "Groups"
+msgstr "Grupos"
+
+#: editor/groups_editor.cpp
+msgid "Nodes Not in Group"
+msgstr "Nodos Fora do Grupo"
+
+#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Filter nodes"
+msgstr "Filtrar nodos"
+
+#: editor/groups_editor.cpp
+msgid "Nodes in Group"
+msgstr "Nodos no Grupo"
+
+#: editor/groups_editor.cpp
+msgid "Empty groups will be automatically removed."
+msgstr "Os grupos baleiros serán automaticamente eliminados."
+
+#: editor/groups_editor.cpp
+msgid "Group Editor"
+msgstr "Editor de Grupos"
+
+#: editor/groups_editor.cpp
+msgid "Manage Groups"
+msgstr "Administrar Grupos"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Single Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Animations"
+msgstr "Importar con Animacións Separadas"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials"
+msgstr "Importar con Materiais Separados"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects"
+msgstr "Importar con Obxectos Separados"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials"
+msgstr "Importar con Obxectos e Materiais Separados"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Animations"
+msgstr "Importar con Obxectos e Animacións Separadas"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials+Animations"
+msgstr "Importar con Materiais e Animacións Separadas"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials+Animations"
+msgstr "Importar con Obxectos, Materiais, e Animacións Separados"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes+Materials"
+msgstr "Importar como Escenas e Materiales Múltiples"
+
+#: editor/import/resource_importer_scene.cpp
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import Scene"
+msgstr "Importar Escena"
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Importing Scene..."
+msgstr "Importando Escena..."
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating Lightmaps"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating for Mesh: "
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Running Custom Script..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Couldn't load post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Invalid/broken script for post-import (check console):"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Error running post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Did you return a Node-derived object in the `post_import()` method?"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Saving..."
+msgstr "Gardando..."
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Elixir Modo"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importación"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Cargar Valores por Defecto"
+
+#: editor/import_dock.cpp
+msgid "%d Files"
+msgstr "%d Arquivos"
+
+#: editor/import_dock.cpp
+msgid "Set as Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Clear Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Import As:"
+msgstr "Importar Como:"
+
+#: editor/import_dock.cpp
+msgid "Preset"
+msgstr "Axustes de Importación"
+
+#: editor/import_dock.cpp
+msgid "Reimport"
+msgstr "Reimportar"
+
+#: editor/import_dock.cpp
+msgid "Save Scenes, Re-Import, and Restart"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Changing the type of an imported file requires editor restart."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid ""
+"WARNING: Assets exist that use this resource, they may stop loading properly."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Failed to load resource."
+msgstr "Fallou a carga do Recurso."
+
+#: editor/inspector_dock.cpp
+msgid "Expand All Properties"
+msgstr "Expandir Tódalas Propiedades"
+
+#: editor/inspector_dock.cpp
+msgid "Collapse All Properties"
+msgstr "Colapsar Tódalas Propiedades"
+
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save As..."
+msgstr "Gardar Como..."
+
+#: editor/inspector_dock.cpp
+msgid "Copy Params"
+msgstr "Copiar Parámetros"
+
+#: editor/inspector_dock.cpp
+msgid "Edit Resource Clipboard"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Resource"
+msgstr "Copiar Recurso"
+
+#: editor/inspector_dock.cpp
+msgid "Make Built-In"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Sub-Resources Unique"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Open in Help"
+msgstr "Abrir na Axuda"
+
+#: editor/inspector_dock.cpp
+msgid "Create a new resource in memory and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Load an existing resource from disk and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Save the currently edited resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the previous edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the next edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "History of recently edited objects."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Object properties."
+msgstr "Propiedade de Obxectos."
+
+#: editor/inspector_dock.cpp
+msgid "Filter properties"
+msgstr "Filtrar propiedades"
+
+#: editor/inspector_dock.cpp
+msgid "Changes may be lost!"
+msgstr "Os cambios poderían perderse!"
+
+#: editor/multi_node_edit.cpp
+msgid "MultiNode Set"
+msgstr ""
+
+#: editor/node_dock.cpp
+msgid "Select a single node to edit its signals and groups."
+msgstr "Seleccione un nodo para editar as súas sinais e grupos."
+
+#: editor/plugin_config_dialog.cpp
+msgid "Edit a Plugin"
+msgstr "Editar unha Característica Adicional (Plugin)"
+
+#: editor/plugin_config_dialog.cpp
+msgid "Create a Plugin"
+msgstr "Crear unha Característica Adicional (Plugin)"
+
+#: editor/plugin_config_dialog.cpp
+msgid "Plugin Name:"
+msgstr "Nome do Plugin:"
+
+#: editor/plugin_config_dialog.cpp
+msgid "Subfolder:"
+msgstr "Subcartafol:"
+
+#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp
+msgid "Language:"
+msgstr "Linguaxe:"
+
+#: editor/plugin_config_dialog.cpp
+msgid "Script Name:"
+msgstr "Nome do Script:"
+
+#: editor/plugin_config_dialog.cpp
+msgid "Activate now?"
+msgstr "Activar agora?"
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon"
+msgstr "Crear Polígono"
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create points."
+msgstr "Crear puntos."
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid ""
+"Edit points.\n"
+"LMB: Move Point\n"
+"RMB: Erase Point"
+msgstr ""
+"Editar puntos.\n"
+"Clic Izq: Mover Punto\n"
+"Clic Der: Eliminar Punto"
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Erase points."
+msgstr "Borrar puntos."
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon"
+msgstr "Editar Polígono"
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Insert Point"
+msgstr "Inserir Punto"
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon (Remove Point)"
+msgstr "Editar Polígono (Eliminar Punto)"
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Remove Polygon And Point"
+msgstr "Eliminar Polígono e Punto"
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Animation"
+msgstr "Engadir Animación"
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Load..."
+msgstr "Cargar..."
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Move Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "This type of node can't be used. Only root nodes are allowed."
+msgstr "Non se pode usar este tipo de nodo. Só nodos raíz están permitidos."
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Animation Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Remove BlendSpace1D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Move BlendSpace1D Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"AnimationTree is inactive.\n"
+"Activate to enable playback, check node warnings if activation fails."
+msgstr ""
+"O AnimationTree está inactivo.\n"
+"Actívao para permitir a reprodución; e comproba os avisos do nodo se hai un "
+"erro na activación."
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Set the blending position within the space"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Select and move points, create points with RMB."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
+msgid "Enable snap and show grid."
+msgstr "Activar axuste de cuadrícula e amosar cuadrícula."
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Point"
+msgstr "Punto"
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Open Editor"
+msgstr "Abrir Editor"
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Open Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Triangle already exists."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Triangle"
+msgstr "Engadir Triángulo"
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "BlendSpace2D does not belong to an AnimationTree node."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "No triangles exist, so no blending can take place."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Toggle Auto Triangles"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create triangles by connecting points."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Erase points and triangles."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Generate blend triangles automatically (instead of manually)"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend:"
+msgstr "Mezcla:"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Parameter Changed"
+msgstr "Parámetro Cambiado"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Filters"
+msgstr "Editar Flitros"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Output node can't be added to the blend tree."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Add Node to BlendTree"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Node Moved"
+msgstr "Nodo Movido"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Unable to connect, port may be in use or connection may be invalid."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Connected"
+msgstr "Nodos Conectado"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Disconnected"
+msgstr "Nodos Desconectados"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Set Animation"
+msgstr "Establecer Animación"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Node"
+msgstr "Eliminar Nodo"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)"
+msgstr "Eliminar Nodo(s)"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Toggle Filter On/Off"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Change Filter"
+msgstr "Cambiar Filtro"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "No animation player set, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Player path set is invalid, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid ""
+"Animation player has no valid root node path, so unable to retrieve track "
+"names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Anim Clips"
+msgstr "Clips de Animación"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Audio Clips"
+msgstr "Clips de Audio"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Functions"
+msgstr "Funcións"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Renamed"
+msgstr "Nodo Renomeado"
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node..."
+msgstr "Engadir Nodo..."
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Edit Filtered Tracks:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Enable Filtering"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Toggle Autoplay"
+msgstr "Act./Desact. Auto-reproducción"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Anim"
+msgstr "Nova Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Animation?"
+msgstr "Eliminar Animación?"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Remove Animation"
+msgstr "Eliminar Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Invalid animation name!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation name already exists!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr "Renomear Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Next Changed"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Blend Time"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Load Animation"
+msgstr "Cargar Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Duplicate Animation"
+msgstr "Duplicar Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to copy!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation resource on clipboard!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pasted Animation"
+msgstr "Animación Pegada"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Paste Animation"
+msgstr "Pegar Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to edit!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from current pos. (A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from end. (Shift+A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Stop animation playback. (S)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from start. (Shift+D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from current pos. (D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation position (in seconds)."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Scale animation playback globally for the node."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Tools"
+msgstr "Ferramentas de Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation"
+msgstr "Animación"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Edit Transitions..."
+msgstr "Editar Transicións..."
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Open in Inspector"
+msgstr "Abrir no Inspector"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Display list of animations in player."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Autoplay on Load"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Enable Onion Skinning"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Onion Skinning Options"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Directions"
+msgstr "Direccións"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Past"
+msgstr "Pasado"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Future"
+msgstr "Futuro"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Depth"
+msgstr "Profundidad"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "1 step"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "2 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "3 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Differences Only"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Force White Modulate"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Include Gizmos (3D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pin AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Name:"
+msgstr "Nome da Animación:"
+
+#: 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 "Erro!"
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Times:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Next (Auto Queue):"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Cross-Animation Blend Times"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Move Node"
+msgstr "Mover Nodo"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition exists!"
+msgstr "Existe transición!"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Add Transition"
+msgstr "Engadir Transición"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node"
+msgstr "Engadir Nodo"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "End"
+msgstr "Fin"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Immediate"
+msgstr "Inmediata"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Sync"
+msgstr "Sincronizar"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "At End"
+msgstr "Ao Final"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Travel"
+msgstr "Viaxe"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Start and end nodes are needed for a sub-transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "No playback resource set at path: %s."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Removed"
+msgstr "Nodo Eliminado"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition Removed"
+msgstr "Transición Eliminada"
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set Start Node (Autoplay)"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"Select and move nodes.\n"
+"RMB to add new nodes.\n"
+"Shift+LMB to create connections."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Create new nodes."
+msgstr "Crear novos nodos."
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Connect nodes."
+msgstr "Conectar nodos."
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Remove selected node or transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Toggle autoplay this animation on start, restart or seek to zero."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set the end animation. This is useful for sub-transitions."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition: "
+msgstr "Transición: "
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Play Mode:"
+msgstr "Modo de Reprodución:"
+
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "AnimationTree"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "New name:"
+msgstr "Novo nome:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Scale:"
+msgstr "Escala:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade In (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade Out (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend"
+msgstr "Mezcla"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix"
+msgstr "Mezcla"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Auto Restart:"
+msgstr "Auto Reinicio:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Restart (s):"
+msgstr "Reiniciar (s):"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Random Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Start!"
+msgstr "Comezar!"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Amount:"
+msgstr "Cantidade:"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 0:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 1:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "X-Fade Time (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Current:"
+msgstr "Actual:"
+
+#: 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 "Engadir Entrada"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Clear Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Set Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Delete Input"
+msgstr "Eliminar Entrada"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is valid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is invalid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation Node"
+msgstr "Nodo de Animación"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "OneShot Node"
+msgstr "Nodo de Execución Única (Oneshot)"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend2 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend3 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend4 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeScale Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeSeek Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Transition Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Import Animations..."
+msgstr "Importar Animacións..."
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Node Filters"
+msgstr "Editar Filtros do Nodo"
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Filters..."
+msgstr "Filtros..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Contents:"
+msgstr "Contidos:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "View Files"
+msgstr "Ver Arquivos"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connection error, please try again."
+msgstr "Houbo un erro na conexión; por favor, inténtao de novo."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect to host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response from host:"
+msgstr "Non houbo respota por parte do host:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, return code:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr "A petición fallou."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr "Erro de escritura."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, too many redirects"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr "Timeout."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Bad download hash, assuming file has been tampered with."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Expected:"
+msgstr "Esperado:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Got:"
+msgstr "Recibido:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed SHA-256 hash check"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Asset Download Error:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading (%s / %s)..."
+msgstr "Descargando (%s / %s)..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading..."
+msgstr "Descargando..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Resolving..."
+msgstr "Resolvendo..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Error making request"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Idle"
+msgstr "Ocioso"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr "Instalar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Retry"
+msgstr "Reintentar"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download Error"
+msgstr "Erro na Descarga"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download for this asset is already in progress!"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Recently Updated"
+msgstr "Actualizado Recentemente"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Least Recently Updated"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Name (A-Z)"
+msgstr "Nome (A-Z)"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Name (Z-A)"
+msgstr "Nome (Z-A)"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "License (A-Z)"
+msgstr "Licenza (A-Z)"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "License (Z-A)"
+msgstr "Licenza (Z-A)"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "First"
+msgstr "Primeiro"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Previous"
+msgstr "Anterior"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Next"
+msgstr "Seguinte"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Last"
+msgstr "Derradeiro"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "All"
+msgstr "Todos"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No results for \"%s\"."
+msgstr "Non houbo resultado para \"%s\"."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Import..."
+msgstr "Importar..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
+msgstr "Características Adicionais (Plugins)..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+msgid "Sort:"
+msgstr "Ordenar:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Category:"
+msgstr "Categoría:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Site:"
+msgstr "Sitio:"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Support"
+msgstr "Soporte"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Official"
+msgstr "Oficial"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Testing"
+msgstr "Probas"
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr "Cargando..."
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Assets ZIP File"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Can't determine a save path for lightmap images.\n"
+"Save your scene and try again."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake "
+"Light' flag is on."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed creating lightmap images, make sure path is writable."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Algunha malla é inválida. Asegúrese de que o os valores do canle UV2 están "
+"contidos dentro da rexión cadrada ([0.0,1.0], [0.0,1.0])."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Bake Lightmaps"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
+#: editor/plugins/camera_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Preview"
+msgstr "Vista Previa"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Configure Snap"
+msgstr "Configurar Axuste de Cuadrícula"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Primary Line Every:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "steps"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Vertical Guide"
+msgstr "Mover Guía Vertical"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Vertical Guide"
+msgstr "Crear Guía Vertical"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Vertical Guide"
+msgstr "Eliminar Guía Vertical"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Horizontal Guide"
+msgstr "Mover Guía Horizontal"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal Guide"
+msgstr "Crear Guía Horizontal"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Horizontal Guide"
+msgstr "Eliminar Guía Horizontal"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal and Vertical Guides"
+msgstr "Crear Guías Horizontais e Verticais"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate CanvasItem \"%s\" to %d degrees"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem \"%s\" Anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale Node2D \"%s\" to (%s, %s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Resize Control \"%s\" to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale CanvasItem \"%s\" to (%s, %s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem \"%s\" to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Children of containers have their anchors and margins values overridden by "
+"their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Presets for the anchors and margins values of a Control node."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"When active, moving Control nodes changes their anchors instead of their "
+"margins."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Left"
+msgstr "Arriba á Esquerda"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Right"
+msgstr "Arriba á Dereita"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Right"
+msgstr "Abaixo á Dereita"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Left"
+msgstr "Abaixo á Esquerda"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Left"
+msgstr "Centro á Esquerda"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Top"
+msgstr "Centro Arriba"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Right"
+msgstr "Centro á Dereita"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Bottom"
+msgstr "Centro Abaixo"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center"
+msgstr "Centro"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Left Wide"
+msgstr "Esquerdo Alto"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Wide"
+msgstr "Arriba Ancho"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Right Wide"
+msgstr "Dereito Alto"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Wide"
+msgstr "Abaixo Ancho"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "VCenter Wide"
+msgstr "CentradoV Alto"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "HCenter Wide"
+msgstr "CentradoH Ancho"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Full Rect"
+msgstr "Recta Completa"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Keep Ratio"
+msgstr "Manter Relación de Aspecto"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Anchors only"
+msgstr "Só Ãncoras"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors and Margins"
+msgstr "Cambiar Ãncoras e Marxes"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors"
+msgstr "Cambiar Ãncoras"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Game Camera Override\n"
+"Overrides game camera with editor viewport camera."
+msgstr ""
+"Substituír a Cámara do Xogo\n"
+"Substitue a cámara do xogo pola cámara da Mini-ventá (Viewport) do editor."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Game Camera Override\n"
+"No game instance running."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Group Selected"
+msgstr "Agrupar Selección"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Ungroup Selected"
+msgstr "Desagrupar Selección"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Paste Pose"
+msgstr "Pegar Pose"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr "Limpar Guías"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Bones"
+msgstr "Limpar Ósos"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Warning: Children of a container get their position and size determined only "
+"by their parent."
+msgstr ""
+"Aviso: Os nodos fillos dun contedor (Container) teñen determinada a súa "
+"posición e tamaño unicamente polo seu padre."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Reset"
+msgstr "Restablecer Zoom"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Select Mode"
+msgstr "Elixir Modo"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Drag: Rotate"
+msgstr "Arrastrar: Rotar"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+Drag: Move"
+msgstr "Alt+Arrastrar: Mover"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Move Mode"
+msgstr "Mover Modo"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Mode"
+msgstr "Modo Rotación"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Mode"
+msgstr "Modo Escalado"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Show a list of all objects at the position clicked\n"
+"(same as Alt+RMB in select mode)."
+msgstr ""
+"Amosa unha lista de obxectos na posición na que se fixo clic\n"
+"(O mesmo que usar Alt+Clic Dereito en modo selección)."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Click to change object's rotation pivot."
+msgstr "Faga clic para cambiar o pivote de rotación do obxecto."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Ruler Mode"
+msgstr "Modo Regra"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle smart snapping."
+msgstr "Act./Desact. axuste intelixente."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Smart Snap"
+msgstr "Usar Axuste Intelixente"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle grid snapping."
+msgstr "Act./Desact. axuste de cuadrícula."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Grid Snap"
+msgstr "Usar Axuste de Cuadrícula"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snapping Options"
+msgstr "Opcións de Axuste de Cuadrícula"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Rotation Snap"
+msgstr "Empregar Axuste de Rotación"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Scale Snap"
+msgstr "Empregar Axuste de Escalado"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap Relative"
+msgstr "Axuste Relativo"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Pixel Snap"
+msgstr "Empregar Axuste aos Píxeles"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Smart Snapping"
+msgstr "Axuste Intelixente"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr "Configurar Axuste de Cuadrícula..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Parent"
+msgstr "Axustar ao Pai"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Anchor"
+msgstr "Axustar á Ãncora do Nodo"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Sides"
+msgstr "Axustar aos Laterais do Nodo"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Center"
+msgstr "Axustar ao Centro do Nodo"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Other Nodes"
+msgstr "Axustar a Outros Nodos"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Guides"
+msgstr "Axustar as Guías"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock the selected object in place (can't be moved)."
+msgstr "Fixar o obxecto no sitio (non se poderá mover)."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock the selected object (can be moved)."
+msgstr "Liberar o obxecto seleccionado (pode moverse)."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Makes sure the object's children are not selectable."
+msgstr "Asegúrase de que os fillos do obxecto non sexan seleccionables."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Restores the object's children's ability to be selected."
+msgstr "Volve a permitir seleccionar os fillos do obxecto."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Skeleton Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Bones"
+msgstr "Amosar Ósos"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make Custom Bone(s) from Node(s)"
+msgstr "Crear Óso(s) Personalizados a partir de Nodo(s)"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Custom Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View"
+msgstr "Ver"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Always Show Grid"
+msgstr "Sempre Amosar a Cuadrícula"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Helpers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Rulers"
+msgstr "Amosar Regras"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Guides"
+msgstr "Amosar Guías"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Origin"
+msgstr "Amosar Orixe"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Viewport"
+msgstr "Amosar Mini-Ventá (Viewport)"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Group And Lock Icons"
+msgstr "Amosar Grupo e Bloquear Iconas"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Selection"
+msgstr "Centrar Selección"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Frame Selection"
+msgstr "Encadrar Selección"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Preview Canvas Scale"
+msgstr "Vista Previa da Escala do Lenzo (Canvas)"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Translation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert keys (based on mask)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Auto insert keys when objects are translated, rotated or scaled (based on "
+"mask).\n"
+"Keys are only added to existing tracks, no new tracks will be created.\n"
+"Keys must be inserted manually for the first time."
+msgstr ""
+"Inserción automática de claves cando os obxectos son trasladados, rotados, "
+"ou escalados (depenendo da Máscara).\n"
+"As chaves só engádense a pistas xa existentes; nunca se crean novas pistas.\n"
+"As chaves teñen que insertarse manualmente cando se utiliza por primeira vez."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Auto Insert Key"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Animation Key and Pose Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key (Existing Tracks)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Copy Pose"
+msgstr "Copiar Pose"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Pose"
+msgstr "Restablecer Pose"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Multiply grid step by 2"
+msgstr "Multiplicar Dimensión da Cuadrícula por 2"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Divide grid step by 2"
+msgstr "Dividir Dimensión da Cuadrícula por 2"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Add %s"
+msgstr "Engadir %s"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Adding %s..."
+msgstr "Engadindo %s..."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Cannot instantiate multiple nodes without root."
+msgstr "Non se pode instanciar varios nodos sen un nodo raíz."
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Create Node"
+msgstr "Crear Nodo"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Error instancing scene from %s"
+msgstr "Erro instanciado escena desde %s"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Default Type"
+msgstr "Cambiar Tipo por Defecto"
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Drag & drop + Shift : Add node as sibling\n"
+"Drag & drop + Alt : Change node type"
+msgstr ""
+"Arrastrar e Soltar + Shift : Engade nodo como irmán\n"
+"Arrastrar e Soltar + Alt : Cambiar tipo de nodo"
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Create Polygon3D"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly"
+msgstr "Editar Polígono"
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly (Remove Point)"
+msgstr "Editar Polígono (Eliminar Punto)"
+
+#: editor/plugins/collision_shape_2d_editor_plugin.cpp
+msgid "Set Handle"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Load Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Restart"
+msgstr "Reiniciar"
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Clear Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Particles"
+msgstr "Partículas"
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generated Point Count:"
+msgstr "Número de Puntos Xerados:"
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Solid Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Border Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Directed Border Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Capture from Pixel"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Colors"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+msgid "CPUParticles"
+msgstr "CPUParticles"
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Mesh"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Node"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 0"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 1"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease In"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease Out"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Smoothstep"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Curve Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Add Point"
+msgstr "Engadir Punto"
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Point"
+msgstr "Eliminar Punto"
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Left Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Toggle Curve Linear Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Hold Shift to edit tangents individually"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right click to add point"
+msgstr ""
+
+#: editor/plugins/gi_probe_editor_plugin.cpp
+msgid "Bake GI Probe"
+msgstr ""
+
+#: editor/plugins/gradient_editor_plugin.cpp
+msgid "Gradient Edited"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item %d"
+msgstr "Elemento %d"
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Items"
+msgstr "Elementos"
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item List Editor"
+msgstr ""
+
+#: editor/plugins/light_occluder_2d_editor_plugin.cpp
+msgid "Create Occluder Polygon"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh is empty!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create a Trimesh collision shape."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Trimesh Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "This doesn't work on scene root!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Can't create a single convex collision shape for the scene root."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create a single convex collision shape."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Single Convex Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Can't create multiple convex collision shapes for the scene root."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create any collision shapes."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Multiple Convex Shapes"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Navigation Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Contained Mesh is not of type ArrayMesh."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Unwrap failed, mesh may not be manifold?"
+msgstr ""
+"Fallo no Unwrap de UV. Posiblemente a malla non é unha variedade (é dicir, "
+"que a malla non forma unha superficie conexa, contínua, e con dous caras "
+"diferenciables). En programas de modelaxe 3D pódese eliminar xeometría que "
+"non sexa unha variedade (\"Non Manifold\") fácilmente."
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "No mesh to debug."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Model has no UV in this layer"
+msgstr "O modelo non ten UVs nesta capa"
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "MeshInstance lacks a Mesh!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh has not surface to create outlines from!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Could not create outline!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh"
+msgstr "Malla"
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a StaticBody and assigns a polygon-based collision shape to it "
+"automatically.\n"
+"This is the most accurate (but slowest) option for collision detection."
+msgstr ""
+"Crear un nodo StaticBody e asígnalle automáticamente unha forma física "
+"baseada en polígonos.\n"
+"Esta é a forma máis precisa (e máis lenta) de detección de colisións."
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a polygon-based collision shape.\n"
+"This is the most accurate (but slowest) option for collision detection."
+msgstr ""
+"Crea unha formá física baseada en polígonos.\n"
+"Esta é a forma máis precisa (pero máis lenta) de detectar colisións."
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Single Convex Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a single convex collision shape.\n"
+"This is the fastest (but least accurate) option for collision detection."
+msgstr ""
+"Crea unha única forma física convexa.\n"
+"Esta é a maneira más eficiente (pero menos precisa) de detectar colisións."
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Multiple Convex Collision Siblings"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a polygon-based collision shape.\n"
+"This is a performance middle-ground between the two above options."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh..."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a static outline mesh. The outline mesh will have its normals "
+"flipped automatically.\n"
+"This can be used instead of the SpatialMaterial Grow property when using "
+"that property isn't possible."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV1"
+msgstr "Amosar UV1"
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV2"
+msgstr "Amosar UV2"
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Unwrap UV2 for Lightmap/AO"
+msgstr "Facer Unwrap do UV2 para Lightmap/AO"
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Outline Size:"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Channel Debug"
+msgstr "Depuración do Canle UV"
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove item %d?"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid ""
+"Update from existing scene?:\n"
+"%s"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Mesh Library"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Item"
+msgstr "Engadir Elemento"
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove Selected Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import from Scene"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Update from Scene"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and no MultiMesh set in node)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and MultiMesh contains no Mesh)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (not a MeshInstance)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (contains no Mesh resource)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No surface source specified."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no geometry)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no faces)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate Surface"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate MultiMesh"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "X-Axis"
+msgstr "Eixe X"
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Y-Axis"
+msgstr "Eixe Y"
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Z-Axis"
+msgstr "Eixe Z"
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh Up Axis:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Rotation:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Tilt:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Scale:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate"
+msgstr "Encher"
+
+#: editor/plugins/navigation_polygon_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Convert to CPUParticles"
+msgstr "Converter a CPUParticles"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generating Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generate Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Can only set point into a ParticlesMaterial process material"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Converter a CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generation Time (sec):"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emitter"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Points:"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points+Normal (Directed)"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Volume"
+msgstr "Volume"
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Source: "
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "A processor material of type 'ParticlesMaterial' is required."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generating AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate Visibility AABB"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Point from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Out-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove In-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point to Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Split Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Point in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move In-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Out-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Select Points"
+msgstr "Seleccionar Puntos"
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Shift+Drag: Select Control Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Click: Add Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Left Click: Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Right Click: Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Select Control Points (Shift+Drag)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point (in empty space)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Delete Point"
+msgstr "Eliminar Puntos"
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Close Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp
+msgid "Options"
+msgstr "Opcións"
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Angles"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Lengths"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Curve Point #"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Point Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve In Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Out Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Path"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Path Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Out-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove In-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/physical_bone_plugin.cpp
+msgid "Move Joint"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"No texture in this polygon.\n"
+"Set a texture to be able to edit UV."
+msgstr ""
+"Non hai unha textura neste polígono.\n"
+"Engada unha textura para editar o UV."
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create UV Map"
+msgstr "Crear Mapa UV"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Polygon 2D has internal vertices, so it can no longer be edited in the "
+"viewport."
+msgstr ""
+"O polígono 2D ten vértices internos, polo que xa non se pode editar na Mini-"
+"Ventá (Viewport)."
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon & UV"
+msgstr "Crear Polígono e UV"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Invalid Polygon (need 3 different vertices)"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Add Custom Polygon"
+msgstr "Engadir Polígono Personalizado"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Custom Polygon"
+msgstr "Eliminar Polígono Personalizado"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform UV Map"
+msgstr "Transformar Mapa UV"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint Bone Weights"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Open Polygon 2D UV editor."
+msgstr "Abrir Editor UV de Polígonos 2D."
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon 2D UV Editor"
+msgstr "Editor UV de Polígonos 2D"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV"
+msgstr "UV"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Points"
+msgstr "Puntos"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygons"
+msgstr "Polígonos"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Bones"
+msgstr "Ósos"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Points"
+msgstr "Mover Puntos"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Command: Rotate"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift: Move All"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Command: Scale"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Ctrl: Rotate"
+msgstr "Ctrl: Rotar"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Ctrl: Scale"
+msgstr "Shift+Ctrl: Escalar"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Polygon"
+msgstr "Mover Polígono"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Rotate Polygon"
+msgstr "Rotar Polígono"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Scale Polygon"
+msgstr "Escalar Polígono"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create a custom polygon. Enables custom polygon rendering."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Remove a custom polygon. If none remain, custom polygon rendering is "
+"disabled."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Unpaint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Radius:"
+msgstr "Radio:"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Copy Polygon to UV"
+msgstr "Copiar Polígono a UV"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Copy UV to Polygon"
+msgstr "Copiar UV a Polígono"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Clear UV"
+msgstr "Limpar UV"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Settings"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Snap"
+msgstr "Axuste de Cuadrícula"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Enable Snap"
+msgstr "Activar Axuste"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid"
+msgstr "Cuadrícula"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Show Grid"
+msgstr "Amosar Cuadrícula"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Configure Grid:"
+msgstr "Configurar Cuadrícula:"
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones to Polygon"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ERROR: Couldn't load resource!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Add Resource"
+msgstr "Engadir Recurso"
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Rename Resource"
+msgstr "Renomear Recurso"
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Resource"
+msgstr "Eliminar Recurso"
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Resource clipboard is empty!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Paste Resource"
+msgstr "Pegar Recurso"
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Instance:"
+msgstr "Instancia:"
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Type:"
+msgstr "Tipo:"
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
+msgid "Open in Editor"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Load Resource"
+msgstr "Cargar Recurso"
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ResourcePreloader"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "AnimationTree has no path set to an AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Path to AnimationPlayer is invalid"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Files"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close and save changes?"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error writing TextFile:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Could not load file at:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving file!"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Saving"
+msgstr "Erro ao Gardar"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error importing theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Importing"
+msgstr "Erro ao Importar"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "New Text File..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open File"
+msgstr "Abrir Arquivo"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save File As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Can't obtain the script for running."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Script failed reloading, check console for errors."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Script is not in tool mode, will not be able to run."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"To run this script, it must inherit EditorScript and be set to tool mode."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme"
+msgstr "Importar Tema"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving"
+msgstr "Erro ao gardar"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "%s Class Reference"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Next"
+msgstr "Atopar Seguinte"
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Previous"
+msgstr "Atopar Anterior"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter scripts"
+msgstr "Filtrar scripts"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle alphabetical sorting of the method list."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter methods"
+msgstr "Filtrar métodos"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Sort"
+msgstr "Ordenar"
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Up"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Down"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Next script"
+msgstr "Seguinte script"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Previous script"
+msgstr "Anterior script"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "File"
+msgstr "Arquivo"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open..."
+msgstr "Abrir..."
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save All"
+msgstr "Gardar Todo"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Soft Reload Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Copy Script Path"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Previous"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme"
+msgstr "Tema"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme..."
+msgstr "Importar Tema..."
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reload Theme"
+msgstr "Volver a Cargar Tema"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme"
+msgstr "Gardar Tema"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close All"
+msgstr "Pechar Todo"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr "Pechar Documentación"
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+msgid "Run"
+msgstr "Executar"
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Buscar"
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Into"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Over"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Break"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Continue"
+msgstr "Continuar"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Keep Debugger Open"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Debug with External Editor"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open Godot online documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search the reference documentation."
+msgstr "Buscar na documentación de referencia."
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to previous edited document."
+msgstr "Ir ao anterior documento editado."
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to next edited document."
+msgstr "Ir ao seguinte documento editado."
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Discard"
+msgstr "Descartar"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Debugger"
+msgstr "Depurador"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Results"
+msgstr "Resultados de Búsqueda"
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Connections to method:"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp
+msgid "Source"
+msgstr "Fonte"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Target"
+msgstr "Obxectivo"
+
+#: editor/plugins/script_text_editor.cpp
+msgid ""
+"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "[Ignore]"
+msgstr "[Ignorar]"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Line"
+msgstr "Liña"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function"
+msgstr "Ir a Función"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Only resources from filesystem can be dropped."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't drop nodes because script '%s' is not used in this scene."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Lookup Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Pick Color"
+msgstr "Elexir Cor"
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Convert Case"
+msgstr "Converter Maiús./Minús."
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Uppercase"
+msgstr "Maiúscula"
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Lowercase"
+msgstr "Minúscula"
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Capitalize"
+msgstr "Capitalizar"
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Syntax Highlighter"
+msgstr "Marcador de Sintaxe"
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "Bookmarks"
+msgstr "Marcadores"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "Go To"
+msgstr "Ir a"
+
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Cut"
+msgstr "Cortar"
+
+#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Select All"
+msgstr "Seleccionar Todo"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Delete Line"
+msgstr "Eliminar Liña"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Left"
+msgstr "Sangrado á Esquerda"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Right"
+msgstr "Sangrado á Dereita"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Comment"
+msgstr "Comentar/Descomentar"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold/Unfold Line"
+msgstr "Expandir/Colapsar Liña"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold All Lines"
+msgstr "Colapsar Tódalas Liñas"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Unfold All Lines"
+msgstr "Expandir Tódalas Liñas"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Clone Down"
+msgstr "Clonar Liña"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Complete Symbol"
+msgstr "Completar Símbolo"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Evaluate Selection"
+msgstr "Evaluar Selección"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
+msgstr "Eliminar Espazos ao Final da Liña"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Spaces"
+msgstr "Convertir Indentación a Espazos"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Tabs"
+msgstr "Convertir Identación a Tabulacións"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Auto Indent"
+msgstr "Auto Indentar"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find in Files..."
+msgstr "Buscar en Arquivos.."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr "Axuda Contextual"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
+msgstr "Act./Desact. Marcapáxinas"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Bookmark"
+msgstr "Ir ao Seguinte Marcapáxinas"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Bookmark"
+msgstr "Ir ao Anterior Marcapáxinas"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr "Eliminar Tódolos Marcapáxinas"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function..."
+msgstr "Ir a Función..."
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Line..."
+msgstr "Ir a Liña..."
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr "Act./Desact. Punto de Interrupción (Breakpoint)"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr "Eliminar Tódolos Puntos de Interrupción (Breakpoints)"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr "Ir ao Seguinte Punto de Interrupción"
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr "Ir ao Anterior Punto de Interrupción"
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid ""
+"This shader has been modified on on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Este shader foi modificado en disco.\n"
+"Que acción deberían de tomarse?"
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Shader"
+msgstr "Shader"
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "This skeleton has no bones, create some children Bone2D nodes."
+msgstr "Este esqueleto non ten ósos; crea uns nodos fillo Bone2D."
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Create Rest Pose from Bones"
+msgstr "Crear Pose de Repouso a partir dos Ósos"
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Rest Pose to Bones"
+msgstr "Asignar Pose de Repouso aos Ósos"
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Skeleton2D"
+msgstr "Skeleton2D"
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Make Rest Pose (From Bones)"
+msgstr "Crear Pose de Repouso (a partir dos Ósos)"
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Bones to Rest Pose"
+msgstr "Asignar Pose de Repouso aos Ósos"
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical bones"
+msgstr "Crear ósos físicos"
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Skeleton"
+msgstr "Esqueleto"
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical skeleton"
+msgstr "Crear esqueleto físico"
+
+#: editor/plugins/skeleton_ik_editor_plugin.cpp
+msgid "Play IK"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Orthogonal"
+msgstr "Ortogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective"
+msgstr "Perspetiva"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Aborted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "X-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Y-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Z-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Plane Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scaling: "
+msgstr "Escalado: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translating: "
+msgstr "Trasladando: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotating %s degrees."
+msgstr "Rotando % graos."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Keying is disabled (no key inserted)."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Animation Key Inserted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pitch"
+msgstr "Cabeceo"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Yaw"
+msgstr "Guiñada"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Tamaño"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Objects Drawn"
+msgstr "Obxectos Debuxados"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Material Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Shader Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Surface Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Draw Calls"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Vertices"
+msgstr "Vértices"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View."
+msgstr "Vista Superior."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View."
+msgstr "Vista Inferior."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom"
+msgstr "Inferior"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View."
+msgstr "Vista Esquerda."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left"
+msgstr "Esquerda"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View."
+msgstr "Vista Dereita."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right"
+msgstr "Dereita"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View."
+msgstr "Vista Frontal."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front"
+msgstr "Frontal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View."
+msgstr "Vista Traseria."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear"
+msgstr "Traseira"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Transform with View"
+msgstr "Aliñar Transformación con Perspectiva"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr "Aliñar Rotación con Perspectiva"
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "No parent to instance a child at."
+msgstr "Non hai un pai ao que instanciarlle un fillo."
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "This operation requires a single selected node."
+msgstr "Esta operación precisa un único nodo seleccionado."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr "Auto Ortogonal Activado"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock View Rotation"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Normal"
+msgstr "Mostrar de Forma Normal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Wireframe"
+msgstr "Mostrar Malla"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Overdraw"
+msgstr "Mostrar Zonas Redebuxadas (Overdraw)"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Unshaded"
+msgstr "Mostrar Sen Sombreado"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Environment"
+msgstr "Amosar Entorno"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Gizmos"
+msgstr "Amosar Gizmos"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Information"
+msgstr "Amosar Información"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View FPS"
+msgstr "Ver FPS"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Half Resolution"
+msgstr "Resolución á Metade"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Audio Listener"
+msgstr "Oínte de Son"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Enable Doppler"
+msgstr "Activar Efecto Doppler"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Cinematic Preview"
+msgstr "Vista Previa Cinemática"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Not available when using the GLES2 renderer."
+msgstr "Non dispoñible cando se está usando o renderizador GLES2."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Forward"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Backwards"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Up"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Down"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Speed Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Slow Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
+msgstr ""
+"Nota: o valor dos FPS corresponde aos fotogramas por segundo do editor.\n"
+"Non pode usarse como unha forma fiable de medir o rendemento do xogo."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "XForm Dialog"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Click to toggle between visibility states.\n"
+"\n"
+"Open eye: Gizmo is visible.\n"
+"Closed eye: Gizmo is hidden.\n"
+"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")."
+msgstr ""
+"Faga clic para cambiar entre estados de visibilidade.\n"
+"\n"
+"Ollo aberto: Gizmo visible.\n"
+"Ollo pechado: Gizmo oculto.\n"
+"Ollo medio aberto, medio pechado: Gizmo visible ao través de superficies "
+"opacas (\"raios x\")."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Nodes To Floor"
+msgstr "Axustar Nodos ao Chan"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr "Non se puido encontrar chan sólido no que poder axustar a selección."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Drag: Rotate\n"
+"Alt+Drag: Move\n"
+"Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Local Space"
+msgstr "Usar Espazo Local"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Snap"
+msgstr "Usar Axuste de Cuadrícula"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View"
+msgstr "Vista Inferior"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View"
+msgstr "Vista Superior"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View"
+msgstr "Vista Traseira"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View"
+msgstr "Vista Frontal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View"
+msgstr "Vista Esquerda"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View"
+msgstr "Vista Dereita"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Switch Perspective/Orthogonal View"
+msgstr "Vista Perspectiva/Ortogonal"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Insert Animation Key"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Toggle Freelook"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform"
+msgstr "Transformación"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Object to Floor"
+msgstr "Axustar Obxecto ao Chan"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Dialog..."
+msgstr "Aplicar Transformación..."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "1 Viewport"
+msgstr "1 Ventá"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports"
+msgstr "2 Ventás"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports (Alt)"
+msgstr "2 Ventás (Alt)"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports"
+msgstr "3 Ventás"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports (Alt)"
+msgstr "3 Ventás (Alt)"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "4 Viewports"
+msgstr "4 Ventás"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Origin"
+msgstr "Amosar Orixe"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Grid"
+msgstr "Amosar Cuadrícula"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Settings..."
+msgstr "Axustes..."
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Settings"
+msgstr "Configuración de Axuste"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate Snap:"
+msgstr "Axuste de Translación:"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Snap (deg.):"
+msgstr "Axuste de Rotación (graos):"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Snap (%):"
+msgstr "Axuste de Escalado (%):"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Viewport Settings"
+msgstr "Axustes de Visión"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective FOV (deg.):"
+msgstr "Campo de Visión (graos):"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Near:"
+msgstr "Plano Próximo:"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Far:"
+msgstr "Plano Afastado:"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Change"
+msgstr "Cambio de Transformación"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate:"
+msgstr "Trasladar:"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate (deg.):"
+msgstr "Rotar (graos):"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale (ratio):"
+msgstr "Escalar (Razón):"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Type"
+msgstr "Tipo de Transformación"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pre"
+msgstr "Anterior (Pre)"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Post"
+msgstr "Posterior (Post)"
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Nameless gizmo"
+msgstr "Gizmo sen nome"
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Mesh2D"
+msgstr "Crear Mesh2D"
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Mesh2D Preview"
+msgstr "Vista Previa de Mesh2D"
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Polygon2D"
+msgstr "Crear Polygon2D"
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Polygon2D Preview"
+msgstr "Vista Previa Polygon2D"
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "CollisionPolygon2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "LightOccluder2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite is empty!"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Can't convert a sprite using animation frames to mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't replace by mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Polygon2D"
+msgstr "Convertir a Polygon2D"
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create collision polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create light occluder."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Simplification: "
+msgstr "Simplificación: "
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Shrink (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Grow (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Update Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Settings:"
+msgstr "Axustes:"
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "No Frames Selected"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add %d Frame(s)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Unable to load images"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "ERROR: Couldn't load frame resource!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Resource clipboard is empty or not a texture!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Paste Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Empty"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation FPS"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "(empty)"
+msgstr "(baleiro)"
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animations:"
+msgstr "Animacións:"
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "New Animation"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Speed:"
+msgstr "Velocidade:"
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Loop"
+msgstr "Bucle"
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animation Frames:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add a Texture from File"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frames from a Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Horizontal:"
+msgstr "Horizontal:"
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Vertical:"
+msgstr "Vertical:"
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select/Clear All Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Create Frames from Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "SpriteFrames"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Region Rect"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Margin"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Snap Mode:"
+msgstr "Modo de Axuste:"
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: scene/resources/visual_shader.cpp
+msgid "None"
+msgstr "Ningún"
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Pixel Snap"
+msgstr "Axustar aos Píxeles"
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Grid Snap"
+msgstr "Axuste de Cuadrícula"
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Auto Slice"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Offset:"
+msgstr "Offset:"
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Step:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Sep.:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "TextureRegion"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
+msgid "Remove All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Edit Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme editing menu."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Editor Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create From Current Editor Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Toggle Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Check Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Named Sep."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Submenu"
+msgstr "Submenú"
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has"
+msgstr "Ten"
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Many"
+msgstr "Moitas"
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled LineEdit"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 3"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Editable Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subtree"
+msgstr "Subárbore"
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has,Many,Options"
+msgstr "Ten,Moitas,Opcións"
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Data Type:"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon"
+msgstr "Icona"
+
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Style"
+msgstr "Estilo"
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Font"
+msgstr "Fonte"
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Color"
+msgstr "Cor"
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme File"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Fix Invalid Tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cut Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Line Draw"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Bucket Fill"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Find Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Transpose"
+msgstr "Transpoñer"
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Disable Autotile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Enable Priority"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Filter tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Give a TileSet resource to this TileMap to use its tiles."
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Command+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Pick Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Left"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Right"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Horizontally"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Vertically"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Clear Transform"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Add Texture(s) to TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected Texture from TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Single Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Autotile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Atlas"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Next Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the next shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Previous Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the previous shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region"
+msgstr "Rexión"
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision"
+msgstr "Colisión"
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion"
+msgstr "Oclusión"
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation"
+msgstr "Navegación"
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask"
+msgstr "Máscara de Bits"
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority"
+msgstr "Prioridade"
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Copy bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Erase bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new rectangle."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Rectangle"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete Selected Shape"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Keep polygon inside region Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Enable snap and show grid (configurable via the Inspector)."
+msgstr ""
+"Activar axuste de cuadrícula e amosar cuadrícula (configurable no inspector)."
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Display Tile Names (Hold Alt Key)"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Add or select a texture on the left panel to edit the tiles bound to it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected texture? This will remove all tiles which use it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "You haven't selected a texture to remove."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from scene? This will overwrite all current tiles."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from scene?"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Texture"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "%s file(s) were not added because was already on the list."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Drag handles to edit Rect.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete selected Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select current edited sub-tile.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"LMB: Set bit on.\n"
+"RMB: Set bit off.\n"
+"Shift+LMB: Set wildcard bit.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to use as icon, this will be also used on invalid autotile "
+"bindings.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its priority.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its z index.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Region"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Icon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Clear Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Priority"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "This property can't be changed."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "TileSet"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No VCS addons are available."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Error"
+msgstr "Erro"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No files added to stage"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "VCS Addon is not initialized"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Version Control System"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Initialize"
+msgstr "Inicializar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Staging area"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Changes"
+msgstr "Cambios"
+
+#: 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 "Stage Selected"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Stage All"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Status"
+msgstr "Estado"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View file diffs before committing them to the latest version"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No file diff is active"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect changes in file diff"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Output"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar"
+msgstr "Escalar"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector"
+msgstr "Vector"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean"
+msgstr "Booleano"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sampler"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set expression"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Resize VisualShader node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Uniform Name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Input Default Port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node to Visual Shader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Node(s) Moved"
+msgstr "Nodo(s) Movido(s)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Duplicate Nodes"
+msgstr "Duplicar Nodos"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr "Pegar Nodos"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Nodes"
+msgstr "Eliminar Nodos"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Input Type Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "UniformRef Name Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vertex"
+msgstr "Vertex"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Fragment"
+msgstr "Fragment"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Light"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Create Shader Node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Grayscale function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts HSV vector to RGB equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts RGB vector to HSV equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sepia function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Burn operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Darken operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Difference operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Dodge operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "HardLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Lighten operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Overlay operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Screen operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "SoftLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided scalars are equal, greater or "
+"less."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated scalar if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for all shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Input parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment and light shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for light shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "E constant (2.718282). Represents the base of the natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Epsilon constant (0.00001). Smallest possible scalar number."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Phi constant (1.618034). Golden ratio."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/4 constant (0.785398) or 45 degrees."
+msgstr "Constante Pi/4 (0.785398), ou 45 graos."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/2 constant (1.570796) or 90 degrees."
+msgstr "Constante Pi/2 (1.570796), ou 90 graos."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi constant (3.141593) or 180 degrees."
+msgstr "Constante Pi (3.141593), ou 180 graos."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Tau constant (6.283185) or 360 degrees."
+msgstr "Constante Tau (6.283185), ou 360 graos."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sqrt2 constant (1.414214). Square root of 2."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the absolute value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Finds the nearest integer that is greater than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Constrains a value to lie between two further values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in radians to degrees."
+msgstr "Converte unha cantidade de radiáns a graos."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-e Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer less than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Computes the fractional part of the argument."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse of the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the greater of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the lesser of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the opposite value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the value of the first parameter raised to the power of the second."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in degrees to radians."
+msgstr "Converte unha cantidade de graos a radiáns."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest even integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Clamps the value between 0.0 and 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Extracts the sign of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"Devolve 0.0 se 'x' é menor que 'edge0' e 1.0 se x é maior que 'edge1'. En "
+"caso contrario devólvese un valor interpolado entre 0.0 e 1.0 usando "
+"polinomios de Hermite."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Devolve 0.0 se 'x' e menor que 'edge'; e 1.0 en caso contrario."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the truncated value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds scalar to scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts scalar from scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the cubic texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Calculate the outer product of a pair of vectors.\n"
+"\n"
+"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
+"one column) and the second parameter 'r' as a row vector (matrix with one "
+"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix "
+"whose number of rows is the number of components in 'c' and whose number of "
+"columns is the number of components in 'r'."
+msgstr ""
+"Calcula o produto exterior dun par de vectores.\n"
+"\n"
+"OuterProduct trata o primeiro parámetro 'c' coma un vector columna (matriz "
+"con unha soa columna), e o segundo parámetro 'r' coma un vector fila (matriz "
+"con unha soa fila), e fai a multiplicación alxebráica 'c * r'. Esto devolve "
+"unha matriz cun número de filas igual ao número de compoñentes en 'c', e cun "
+"número de columnas igual ao número de compoñentes en 'r'."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes transform from four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes transform to four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the determinant of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the inverse of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the transpose of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies transform by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes vector from three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes vector to three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the cross product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the distance between two points."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the dot product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the same direction as a reference vector. "
+"The function has three vector parameters : N, the vector to orient, I, the "
+"incident vector, and Nref, the reference vector. If the dot product of I and "
+"Nref is smaller than zero the return value is N. Otherwise -N is returned."
+msgstr ""
+"Devolve o vector que ten a mesma dirección que o vector de referencia. A "
+"función ten tres vector como parámetros: N, o vector a orientar; I, o vector "
+"incidente; e Nref, o vector de referencia. Se o produto escalar de I e Nref "
+"é menor que cero (forman un ángulo maior que 90 graos) entón devolve N. En "
+"caso contrario devolve -N."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the length of a vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the normalize product of vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the direction of reflection ( a : incident "
+"vector, b : normal vector )."
+msgstr ""
+"Devolve o vector que apunta na dirección de reflexo ( a : vector incidente, "
+"b : vector normal)."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the vector that points in the direction of refraction."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"Devolve 0.0 se 'x' é menor que 'edge0' e 1.0 se x é maior que 'edge1'. En "
+"caso contrario devólvese un valor interpolado entre 0.0 e 1.0 usando "
+"polinomios de Hermite."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"Devolve 0.0 se 'x' é menor que 'edge0' e 1.0 se x é maior que 'edge1'. En "
+"caso contrario devólvese un valor interpolado entre 0.0 e 1.0 usando "
+"polinomios de Hermite."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( vector(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+"Step function( vector(edge), vector(x) ).\n"
+"\n"
+"Devolve 0.0 se 'x' e menor que 'edge'; e 1.0 en caso contrario."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+"Step function( scalar(edge), vector(x) ).\n"
+"\n"
+"Devolve 0.0 se 'x' e menor que 'edge'; e 1.0 en caso contrario."
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds vector to vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts vector from vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, with custom amount of input and "
+"output ports. This is a direct injection of code into the vertex/fragment/"
+"light function, do not use it to write the function declarations inside."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns falloff based on the dot product of surface normal and view "
+"direction of camera (pass associated inputs to it)."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, which is placed on top of the "
+"resulted shader. You can place various function definitions inside and call "
+"it later in the Expressions. You can also declare varyings, uniforms and "
+"constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "A reference to an existing uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "VisualShader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Edit Visual Property"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Mode Changed"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Runnable"
+msgstr "Executable"
+
+#: editor/project_export.cpp
+msgid "Delete preset '%s'?"
+msgstr "Eliminar axustes de exportación '%s'?"
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"Export templates seem to be missing or invalid."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"This might be due to a configuration issue in the export preset or your "
+"export settings."
+msgstr ""
+"Fallou a exportación do proxecto á plataforma '%s'.\n"
+"Esto pode deberse a un problema cos axustes de exportación."
+
+#: editor/project_export.cpp
+msgid "Release"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Exporting All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "The given export path doesn't exist:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing/corrupted:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Presets"
+msgstr "Axustes de Exportación"
+
+#: editor/project_export.cpp editor/project_settings_editor.cpp
+msgid "Add..."
+msgstr "Engadir..."
+
+#: editor/project_export.cpp
+msgid ""
+"If checked, the preset will be available for use in one-click deploy.\n"
+"Only one preset per platform may be marked as runnable."
+msgstr ""
+"Ao estar activado, estes axustes de exportación estarán dispoñibles para o "
+"usar co despregue dun só clic.\n"
+"Só uns axustes de exportación por plataforma poden marcarse como executables."
+
+#: editor/project_export.cpp
+msgid "Export Path"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources"
+msgstr "Recursos"
+
+#: editor/project_export.cpp
+msgid "Export all resources in the project"
+msgstr "Exportar tódolos recursos no proxecto"
+
+#: editor/project_export.cpp
+msgid "Export selected scenes (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected resources (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources to export:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to export non-resource files/folders\n"
+"(comma-separated, e.g: *.json, *.txt, docs/*)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to exclude files/folders from project\n"
+"(comma-separated, e.g: *.json, *.txt, docs/*)"
+msgstr ""
+"Filtros para excluír arquivos/cartafois de proxectos\n"
+"(separados por coma; exemplo: *json, *.txt, docs*)"
+
+#: editor/project_export.cpp
+msgid "Features"
+msgstr "Características"
+
+#: editor/project_export.cpp
+msgid "Custom (comma-separated):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Feature List:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script"
+msgstr "Script"
+
+#: editor/project_export.cpp
+msgid "Script Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Text"
+msgstr "Texto"
+
+#: editor/project_export.cpp
+msgid "Compiled"
+msgstr "Compilado"
+
+#: editor/project_export.cpp
+msgid "Encrypted (Provide Key Below)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Invalid Encryption Key (must be 64 characters long)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Encryption Key (256-bits as hex):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export PCK/Zip"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Project"
+msgstr "Exportar Proxecto"
+
+#: editor/project_export.cpp
+msgid "Export mode?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export All"
+msgstr ""
+
+#: editor/project_export.cpp editor/project_manager.cpp
+msgid "ZIP File"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Godot Game Pack"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export With Debug"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The path specified doesn't exist."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error opening package file (it's not in ZIP format)."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."
+msgstr ""
+"O arquivo de proxecto '.zip' non é válido; non conteñe ningún arquivo de "
+"configuración 'project.godot'."
+
+#: editor/project_manager.cpp
+msgid "Please choose an empty folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose a \"project.godot\" or \".zip\" file."
+msgstr "Por favor, elixa un arquivo de tipo 'project.godot' ou '.zip'."
+
+#: editor/project_manager.cpp
+msgid "This directory already contains a Godot project."
+msgstr "O directorio xa contén un proxecto Godot."
+
+#: editor/project_manager.cpp
+msgid "New Game Project"
+msgstr "Novo Proxecto de Xogo"
+
+#: editor/project_manager.cpp
+msgid "Imported Project"
+msgstr "Proxecto Importado"
+
+#: editor/project_manager.cpp
+msgid "Invalid Project Name."
+msgstr "Nome de Proxecto Inválido."
+
+#: editor/project_manager.cpp
+msgid "Couldn't create folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "There is already a folder in this path with the specified name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "It would be a good idea to name your project."
+msgstr "Sería unha boa idea nomear o teu proxecto."
+
+#: editor/project_manager.cpp
+msgid "Invalid project path (changed anything?)."
+msgstr "A ruta ao proxecto non é valida. Cambiaches algo?"
+
+#: editor/project_manager.cpp
+msgid ""
+"Couldn't load project.godot in project path (error %d). It may be missing or "
+"corrupted."
+msgstr ""
+"Non se pudo cargar o arquivo de configuración 'project.godot' na ruta do "
+"proxecto (erro %d). Pode ser que o arquivo non exista; ou que esté "
+"corrompido."
+
+#: editor/project_manager.cpp
+msgid "Couldn't edit project.godot in project path."
+msgstr "Non se pudo editar o arquivo 'project.godot' na ruta do proxecto."
+
+#: editor/project_manager.cpp
+msgid "Couldn't create project.godot in project path."
+msgstr "Non se pudo crear o arquivo 'project.godot' na ruta do proxecto."
+
+#: editor/project_manager.cpp
+msgid "Rename Project"
+msgstr "Renomear Proxecto"
+
+#: editor/project_manager.cpp
+msgid "Import Existing Project"
+msgstr "Importar Proxecto Existente"
+
+#: editor/project_manager.cpp
+msgid "Import & Edit"
+msgstr "Importar e Editar"
+
+#: editor/project_manager.cpp
+msgid "Create New Project"
+msgstr "Crear Novo Proxecto"
+
+#: editor/project_manager.cpp
+msgid "Create & Edit"
+msgstr "Crear e Editar"
+
+#: editor/project_manager.cpp
+msgid "Install Project:"
+msgstr "Instalar Proxecto:"
+
+#: editor/project_manager.cpp
+msgid "Install & Edit"
+msgstr "Instalar e Editar"
+
+#: editor/project_manager.cpp
+msgid "Project Name:"
+msgstr "Nome do Proxecto:"
+
+#: editor/project_manager.cpp
+msgid "Project Path:"
+msgstr "Ruta do Proxecto:"
+
+#: editor/project_manager.cpp
+msgid "Project Installation Path:"
+msgstr "Ruta de Instalación do Proxecto:"
+
+#: editor/project_manager.cpp
+msgid "Renderer:"
+msgstr "Renderizador:"
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 3.0"
+msgstr "OpenGL ES 3.0"
+
+#: editor/project_manager.cpp
+msgid "Not supported by your GPU drivers."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Higher visual quality\n"
+"All features available\n"
+"Incompatible with older hardware\n"
+"Not recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 2.0"
+msgstr "OpenGL ES 2.0"
+
+#: editor/project_manager.cpp
+msgid ""
+"Lower visual quality\n"
+"Some features not available\n"
+"Works on most hardware\n"
+"Recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer can be changed later, but scenes may need to be adjusted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Unnamed Project"
+msgstr "Proxecto Sen Nome"
+
+#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr "Proxecto Faltante"
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr "Erro: O proxecto non se pode encontrar no sistema de arquivos."
+
+#: editor/project_manager.cpp
+msgid "Can't open project at '%s'."
+msgstr "Non se pode abrir proxecto en '%s'."
+
+#: editor/project_manager.cpp
+msgid "Are you sure to open more than one project?"
+msgstr "Está seguro de que quere abrir máis dun proxecto?"
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file does not specify the version of Godot "
+"through which it was created.\n"
+"\n"
+"%s\n"
+"\n"
+"If you proceed with opening it, it will be converted to Godot's current "
+"configuration file format.\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+"O arquivo de configuración do seguinte proxecto non especifica a versión de "
+"Godot ca cal foi creado.\n"
+"\n"
+"%s\n"
+"\n"
+"Se o abres o arquivo de configuración será convertido ao formato utilizado "
+"na versión actual de Godot.\n"
+"Aviso: Xa non poderás volver a abrir este proxecto con versións anteriores "
+"de Godot."
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file was generated by an older engine "
+"version, and needs to be converted for this version:\n"
+"\n"
+"%s\n"
+"\n"
+"Do you want to convert it?\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+"O arquivo de configuración do seguinte proxecto foi xerado por unha versión "
+"antiga de Godot, e é necesario convertelo á versión actual:\n"
+"\n"
+"%s\n"
+"\n"
+"Queres convertelo?\n"
+"Aviso: Xa non poderás abrir o proxecto con versións anteriores de Godot."
+
+#: editor/project_manager.cpp
+msgid ""
+"The project settings were created by a newer engine version, whose settings "
+"are not compatible with this version."
+msgstr ""
+"A configuración do proxecto foi creada por versións máis novas de Godot; "
+"facéndoa incompatible con esta versión."
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: no main scene defined.\n"
+"Please edit the project and set the main scene in the Project Settings under "
+"the \"Application\" category."
+msgstr ""
+"Non se pode executar o proxecto: non hai unha escena principal definida.\n"
+"Por favor, selecciona unha escena principal en \"Configuración do Proxecto"
+"\", na categoría \"Aplicación\"."
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: Assets need to be imported.\n"
+"Please edit the project to trigger the initial import."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to run %d projects at once?"
+msgstr "Seguro que queres executar %d proxectos ao mesmo tempo?"
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove %d projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+"Eliminar %d proxectos da lista?\n"
+"Os contidos da carpeta de proxectos non serán modificados."
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove this project from the list?\n"
+"The project folder's contents won't be modified."
+msgstr ""
+"Eliminar este proxecto da lista?\n"
+"Os contidos da carpeta de proxectos non serán modificados."
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+"Eliminar todos os proxectos faltantes da lista?\n"
+"Os contidos da carpeta de proxectos non serán modificados."
+
+#: editor/project_manager.cpp
+msgid ""
+"Language changed.\n"
+"The interface will update after restarting the editor or project manager."
+msgstr ""
+"Linguaxe cambiada.\n"
+"A interface actualizarase despois de reiniciar o editor ou administrador de "
+"proxectos."
+
+#: editor/project_manager.cpp
+msgid ""
+"Are you sure to scan %s folders for existing Godot projects?\n"
+"This could take a while."
+msgstr ""
+"Seguro que quere escanear proxectos de Godot en %s cartafois?\n"
+"Esto podería demorarse un tempo."
+
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
+#: editor/project_manager.cpp
+msgid "Project Manager"
+msgstr "Administrador de Proxectos"
+
+#: editor/project_manager.cpp
+msgid "Projects"
+msgstr "Proxectos"
+
+#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr ""
+"Examinando arquivos,\n"
+"Por favor, espere..."
+
+#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr "Derradeira Modificación"
+
+#: editor/project_manager.cpp
+msgid "Scan"
+msgstr "Escanear"
+
+#: editor/project_manager.cpp
+msgid "Select a Folder to Scan"
+msgstr "Seleccionar un Cartafol para Escanear"
+
+#: editor/project_manager.cpp
+msgid "New Project"
+msgstr "Novo Proxecto"
+
+#: editor/project_manager.cpp
+msgid "Remove Missing"
+msgstr "Eliminar Faltantes"
+
+#: editor/project_manager.cpp
+msgid "Templates"
+msgstr "Proxectos Modelo"
+
+#: editor/project_manager.cpp
+msgid "Restart Now"
+msgstr "Reiniciar Agora"
+
+#: editor/project_manager.cpp
+msgid "Can't run project"
+msgstr "Non se pode executar proxecto"
+
+#: editor/project_manager.cpp
+msgid ""
+"You currently don't have any projects.\n"
+"Would you like to explore official example projects in the Asset Library?"
+msgstr ""
+"Actualmente non tes ningún proxecto.\n"
+"Gustaríalle buscar proxectos de exemplo oficiais na biblioteca de Assets?"
+
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"A barra de búsqueda filtra os proxectos por nome e último compoñente da súa "
+"ruta.\n"
+"Se quere filtrar proxectos por nome e ruta completa, a consulta debe conter "
+"polo menos un carácter '/'."
+
+#: editor/project_settings_editor.cpp
+msgid "Key "
+msgstr "Botón: "
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Button"
+msgstr "Botón Joystick"
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Axis"
+msgstr "Eixe Joystick"
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button"
+msgstr "Botón do Rato"
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'"
+msgstr ""
+"Nome de acción inválido. O nome non pode estar baleiro, nin conter '/', ':', "
+"'=', '\\' ou '\"'"
+
+#: editor/project_settings_editor.cpp
+msgid "An action with the name '%s' already exists."
+msgstr "Xa existe unha acción co nome '%s'."
+
+#: editor/project_settings_editor.cpp
+msgid "Rename Input Action Event"
+msgstr "Renomear Evento de Entrada"
+
+#: editor/project_settings_editor.cpp
+msgid "Change Action deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action Event"
+msgstr "Engadir Evento de Entrada"
+
+#: editor/project_settings_editor.cpp
+msgid "All Devices"
+msgstr "Tódolos Dispositivos"
+
+#: editor/project_settings_editor.cpp
+msgid "Device"
+msgstr "Dispositivo"
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Press a Key..."
+msgstr "Pulse algún botón..."
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button Index:"
+msgstr "Ãndice do Botón do Rato:"
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button"
+msgstr "Botón Esquerdo"
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button"
+msgstr "Botón Dereito"
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button"
+msgstr "Botón Central"
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up Button"
+msgstr "Mover Roda cara Arriba"
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down Button"
+msgstr "Mover Roda cara Abaixo"
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Left Button"
+msgstr "Mover Roda cara a Esquerda"
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Right Button"
+msgstr "Mover Roda cara a Dereita"
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 1"
+msgstr "Botón X 1"
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 2"
+msgstr "Botón X 2"
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Axis Index:"
+msgstr "Ãndice do Eixe do Joystick:"
+
+#: editor/project_settings_editor.cpp
+msgid "Axis"
+msgstr "Eixe"
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Button Index:"
+msgstr "Ãndice do Botón do Joystick:"
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action"
+msgstr "Eliminar Acción de Entrada"
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action Event"
+msgstr "Eliminar Evento de Entrada"
+
+#: editor/project_settings_editor.cpp
+msgid "Add Event"
+msgstr "Engadir Evento"
+
+#: editor/project_settings_editor.cpp
+msgid "Button"
+msgstr "Botón"
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button."
+msgstr "Botón Esquerdo."
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button."
+msgstr "Botón Dereito."
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button."
+msgstr "Botón Central."
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up."
+msgstr "Roda cara Arriba."
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down."
+msgstr "Roda cara Abaixo."
+
+#: editor/project_settings_editor.cpp
+msgid "Add Global Property"
+msgstr "Engadir Propiedade Global"
+
+#: editor/project_settings_editor.cpp
+msgid "Select a setting item first!"
+msgstr "Primeiro seleccione un elemento!"
+
+#: editor/project_settings_editor.cpp
+msgid "No property '%s' exists."
+msgstr "Non existe a propiedade '%s'."
+
+#: editor/project_settings_editor.cpp
+msgid "Setting '%s' is internal, and it can't be deleted."
+msgstr "A propiedade '%s' é interna, e non pode ser eliminada."
+
+#: editor/project_settings_editor.cpp
+msgid "Delete Item"
+msgstr "Eliminar Elemento"
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'."
+msgstr ""
+"Nome de acción inválido. Non pode estar baleiro, nin pode conter '/', ':', "
+"'=', '\\' ou '\"'."
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action"
+msgstr "Engadir Acción de Entrada"
+
+#: editor/project_settings_editor.cpp
+msgid "Error saving settings."
+msgstr "Erro gardando os axustes."
+
+#: editor/project_settings_editor.cpp
+msgid "Settings saved OK."
+msgstr "Axustes gardados correctamente."
+
+#: editor/project_settings_editor.cpp
+msgid "Moved Input Action Event"
+msgstr "Evento de Entrada Movido"
+
+#: editor/project_settings_editor.cpp
+msgid "Override for Feature"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Translation"
+msgstr "Engadir Tradución"
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Translation"
+msgstr "Eliminar Tradución"
+
+#: editor/project_settings_editor.cpp
+msgid "Add Remapped Path"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resource Remap Add Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Resource Remap Language"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap Option"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter Mode"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Project Settings (project.godot)"
+msgstr "Configuración do Proxecto (project.godot)"
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "General"
+msgstr "Xeral"
+
+#: editor/project_settings_editor.cpp
+msgid "Override For..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "The editor must be restarted for changes to take effect."
+msgstr "O editor ten que reiniciarse para que os cambios teñan efecto."
+
+#: editor/project_settings_editor.cpp
+msgid "Input Map"
+msgstr "Mapeado de Entradas"
+
+#: editor/project_settings_editor.cpp
+msgid "Action:"
+msgstr "Acción:"
+
+#: editor/project_settings_editor.cpp
+msgid "Action"
+msgstr "Acción"
+
+#: editor/project_settings_editor.cpp
+msgid "Deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device:"
+msgstr "Dispositivo:"
+
+#: editor/project_settings_editor.cpp
+msgid "Index:"
+msgstr "Ãndice:"
+
+#: editor/project_settings_editor.cpp
+msgid "Localization"
+msgstr "Linguaxe"
+
+#: editor/project_settings_editor.cpp
+msgid "Translations"
+msgstr "Traducións"
+
+#: editor/project_settings_editor.cpp
+msgid "Translations:"
+msgstr "Traducións:"
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resources:"
+msgstr "Recursos:"
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps by Locale:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locale"
+msgstr "Linguaxe"
+
+#: editor/project_settings_editor.cpp
+msgid "Locales Filter"
+msgstr "Filtrar Linguaxes"
+
+#: editor/project_settings_editor.cpp
+msgid "Show All Locales"
+msgstr "Amosar Tódolos Linguaxes"
+
+#: editor/project_settings_editor.cpp
+msgid "Show Selected Locales Only"
+msgstr "Amosar só os Linguaxes Seleccionados"
+
+#: editor/project_settings_editor.cpp
+msgid "Filter mode:"
+msgstr "Modo de Filtrado:"
+
+#: editor/project_settings_editor.cpp
+msgid "Locales:"
+msgstr "Linguaxes:"
+
+#: editor/project_settings_editor.cpp
+msgid "AutoLoad"
+msgstr "AutoCargador"
+
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr "Características Adicionais (Plugins)"
+
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Cargar Valores por Defecto"
+
+#: editor/property_editor.cpp
+msgid "Preset..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Zero"
+msgstr "Cero"
+
+#: editor/property_editor.cpp
+msgid "Easing In-Out"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing Out-In"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "File..."
+msgstr "Arquivo..."
+
+#: editor/property_editor.cpp
+msgid "Dir..."
+msgstr "Directorio..."
+
+#: editor/property_editor.cpp
+msgid "Assign"
+msgstr "Asignar"
+
+#: editor/property_editor.cpp
+msgid "Select Node"
+msgstr "Seleccionar Nodos"
+
+#: editor/property_editor.cpp
+msgid "Error loading file: Not a resource!"
+msgstr "Erro cargando arquivo: Non é un recurso!"
+
+#: editor/property_editor.cpp
+msgid "Pick a Node"
+msgstr "Elixe un Nodo"
+
+#: editor/property_editor.cpp
+msgid "Bit %d, val %d."
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Property"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Virtual Method"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Method"
+msgstr ""
+
+#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Batch Rename"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Replace:"
+msgstr "Substituír:"
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
+msgstr "Prefixo:"
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
+msgstr "Sufixo:"
+
+#: editor/rename_dialog.cpp
+msgid "Use Regular Expressions"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Advanced Options"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Substitute"
+msgstr "Substituír"
+
+#: editor/rename_dialog.cpp
+msgid "Node name"
+msgstr "Nome do nodo"
+
+#: editor/rename_dialog.cpp
+msgid "Node's parent name, if available"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node type"
+msgstr "Tipo de nodo"
+
+#: editor/rename_dialog.cpp
+msgid "Current scene name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Root node name"
+msgstr "Nome do nodo raíz"
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Sequential integer counter.\n"
+"Compare counter options."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Per-level Counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "If set, the counter restarts for each group of child nodes."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Initial value for the counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Step"
+msgstr "Paso"
+
+#: editor/rename_dialog.cpp
+msgid "Amount by which counter is incremented for each node"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Padding"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Minimum number of digits for the counter.\n"
+"Missing digits are padded with leading zeros."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Post-Process"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Keep"
+msgstr "Manter"
+
+#: editor/rename_dialog.cpp
+msgid "PascalCase to snake_case"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "snake_case to PascalCase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Case"
+msgstr "Maiús./Minús."
+
+#: editor/rename_dialog.cpp
+msgid "To Lowercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Uppercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Reset"
+msgstr "Restablecer"
+
+#: editor/rename_dialog.cpp
+msgid "Regular Expression Error:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "At character %s"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent Node"
+msgstr "Remparentar Nodo"
+
+#: editor/reparent_dialog.cpp
+msgid "Reparent Location (Select new Parent):"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Keep Global Transform"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent"
+msgstr "Remparentar"
+
+#: editor/run_settings_dialog.cpp
+msgid "Run Mode:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Current Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene Arguments:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Scene Run Settings"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "No parent to instance the scenes at."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error loading scene from %s"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot instance the scene '%s' because the current scene exists within one "
+"of its nodes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Scene(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Replace with Branch Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Child Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Pegar Nodos"
+
+#: editor/scene_tree_dock.cpp
+msgid "Detach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on the tree root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Node In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Nodes In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Duplicate Node(s)"
+msgstr "Duplicar Nodo(s)"
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Node must belong to the edited scene to become root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instantiated scenes can't become root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make node as Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete %d nodes and any children?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete %d nodes?"
+msgstr "Eliminar %d nodos?"
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete the root node \"%s\"?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete node \"%s\" and its children?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete node \"%s\"?"
+msgstr "Eliminar nodo \"%s\"?"
+
+#: editor/scene_tree_dock.cpp
+msgid "Can not perform with the root node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on instanced scenes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Save New Scene As..."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Disabling \"editable_instance\" will cause all properties of the node to be "
+"reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Enabling \"Load As Placeholder\" will disable \"Editable Children\" and "
+"cause all properties of the node to be reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "New Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Create Root Node:"
+msgstr "Crear nodo raíz:"
+
+#: editor/scene_tree_dock.cpp
+msgid "2D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "3D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "User Interface"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Other Node"
+msgstr "Outro Nodo"
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes from a foreign scene!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes the current scene inherits from!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Cortar Nodos"
+
+#: editor/scene_tree_dock.cpp
+msgid "Remove Node(s)"
+msgstr "Eliminar Nodo(s)"
+
+#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Couldn't save new scene. Likely dependencies (instances) couldn't be "
+"satisfied."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error saving scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error duplicating scene to save it."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Sub-Resources"
+msgstr "Sub-Recursos"
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Editable Children"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Load As Placeholder"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Open Documentation"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot attach a script: there are no languages registered.\n"
+"This is probably because this editor was built with all language modules "
+"disabled."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add Child Node"
+msgstr "Engadir Nodo Fillo"
+
+#: editor/scene_tree_dock.cpp
+msgid "Expand/Collapse All"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change Type"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Merge From Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Save Branch as Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Copy Node Path"
+msgstr "Copiar Ruta do Nodo"
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete (No Confirm)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add/Create a New Node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Instance a scene file as a Node. Creates an inherited scene if no root node "
+"exists."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach a new or existing script to the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Detach the script from the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remote"
+msgstr "Remoto"
+
+#: editor/scene_tree_dock.cpp
+msgid "Local"
+msgstr "Local"
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance? (No Undo!)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visible"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Unlock Node"
+msgstr "Desbloquear Nodo"
+
+#: editor/scene_tree_editor.cpp
+msgid "Button Group"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "(Connecting From)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node configuration warning:"
+msgstr "Aviso sobre a configuración do nodo:"
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s) and %s group(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is in %s group(s).\n"
+"Click to show groups dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Open Script:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is locked.\n"
+"Click to unlock it."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Children are not selectable.\n"
+"Click to make selectable."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visibility"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"AnimationPlayer is pinned.\n"
+"Click to unpin."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Invalid node name, the following characters are not allowed:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Rename Node"
+msgstr "Renomear Nodo"
+
+#: editor/scene_tree_editor.cpp
+msgid "Scene Tree (Nodes):"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node Configuration Warning!"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Select a Node"
+msgstr "Seleccione un Nodo"
+
+#: editor/script_create_dialog.cpp
+msgid "Path is empty."
+msgstr "A ruta está baleira."
+
+#: editor/script_create_dialog.cpp
+msgid "Filename is empty."
+msgstr "O nome de arquivo está baleiro."
+
+#: editor/script_create_dialog.cpp
+msgid "Path is not local."
+msgstr "A ruta non é local."
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid base path."
+msgstr "Ruta base inválida."
+
+#: editor/script_create_dialog.cpp
+msgid "A directory with the same name exists."
+msgstr "Xa existe un directorio co mesmo nome."
+
+#: editor/script_create_dialog.cpp
+msgid "File does not exist."
+msgstr "O arquivo non existe."
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid extension."
+msgstr "Extensión inválida."
+
+#: editor/script_create_dialog.cpp
+msgid "Wrong extension chosen."
+msgstr "Extensión incorrecta elixida."
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading template '%s'"
+msgstr "Erro cargando o modelo '%s'"
+
+#: editor/script_create_dialog.cpp
+msgid "Error - Could not create script in filesystem."
+msgstr "Erro - Non se puido gardar o Script no sistema de arquivos."
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading script from %s"
+msgstr "Erro cargando script desde %s"
+
+#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "N/A"
+msgstr "N/A"
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script / Choose Location"
+msgstr "Abrir Script / Elixir Ubicación"
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script"
+msgstr "Abrir Script"
+
+#: editor/script_create_dialog.cpp
+msgid "File exists, it will be reused."
+msgstr "O arquivo xa existe; será reutilizado."
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid path."
+msgstr "Ruta inválida."
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid class name."
+msgstr "Nome de clase inválido."
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid inherited parent name or path."
+msgstr "A ruta ou o nome do pai herdado é inválido."
+
+#: editor/script_create_dialog.cpp
+msgid "Script path/name is valid."
+msgstr "A ruta e nome do script son válidos."
+
+#: editor/script_create_dialog.cpp
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr "Permitido: a-z, A-Z, 0-9,_ e ."
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in script (into scene file)."
+msgstr "Script integrada na escena."
+
+#: editor/script_create_dialog.cpp
+msgid "Will create a new script file."
+msgstr "Crearase un novo arquivo de script."
+
+#: editor/script_create_dialog.cpp
+msgid "Will load an existing script file."
+msgstr "Cargarase un arquivo de script xa existente."
+
+#: editor/script_create_dialog.cpp
+msgid "Script file already exists."
+msgstr "Xa existe un arquivo script na mesma ruta."
+
+#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+"Nota: Os scripts integrados teñen algunhas limitacións, e non poden editarse "
+"usando editores externos."
+
+#: editor/script_create_dialog.cpp
+msgid "Class Name:"
+msgstr "Nome da Clase:"
+
+#: editor/script_create_dialog.cpp
+msgid "Template:"
+msgstr "Modelo:"
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in Script:"
+msgstr "Script Integrado:"
+
+#: editor/script_create_dialog.cpp
+msgid "Attach Node Script"
+msgstr "Adxuntar Script de Nodo"
+
+#: editor/script_editor_debugger.cpp
+msgid "Remote "
+msgstr "Remoto "
+
+#: editor/script_editor_debugger.cpp
+msgid "Bytes:"
+msgstr "Bytes:"
+
+#: editor/script_editor_debugger.cpp
+msgid "Warning:"
+msgstr "Aviso:"
+
+#: editor/script_editor_debugger.cpp
+msgid "Error:"
+msgstr "Erro:"
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Error"
+msgstr "Erro de C++"
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Error:"
+msgstr "Erro de C++:"
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Source"
+msgstr "Fonte C++"
+
+#: editor/script_editor_debugger.cpp
+msgid "Source:"
+msgstr "Fonte:"
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Source:"
+msgstr "Fonte C++:"
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Trace"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Errors"
+msgstr "Erros"
+
+#: editor/script_editor_debugger.cpp
+msgid "Child process connected."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Copy Error"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Video RAM"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Skip Breakpoints"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Previous Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Next Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Frames"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Profiler"
+msgstr "Analítica de Rendemento"
+
+#: editor/script_editor_debugger.cpp
+msgid "Network Profiler"
+msgstr "Analítica de Rendemento de Rede"
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitor"
+msgstr "Monitor"
+
+#: editor/script_editor_debugger.cpp
+msgid "Value"
+msgstr "Valor"
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitors"
+msgstr "Monitores"
+
+#: editor/script_editor_debugger.cpp
+msgid "Pick one or more items from the list to display the graph."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "List of Video Memory Usage by Resource:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Total:"
+msgstr "Total:"
+
+#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Resource Path"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Type"
+msgstr "Tipo"
+
+#: editor/script_editor_debugger.cpp
+msgid "Format"
+msgstr "Formato"
+
+#: editor/script_editor_debugger.cpp
+msgid "Usage"
+msgstr "Uso"
+
+#: editor/script_editor_debugger.cpp
+msgid "Misc"
+msgstr "Outros"
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control Type:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Live Edit Root:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Set From Tree"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Export measures as CSV"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Erase Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Restore Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Change Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Shortcuts"
+msgstr "Atallos"
+
+#: editor/settings_config_dialog.cpp
+msgid "Binding"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Light Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change AudioStreamPlayer3D Emission Angle"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera FOV"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera Size"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Notifier AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Particles AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Probe Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Sphere Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Box Shape Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Ray Shape Length"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Height"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Inner Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Outer Radius"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select the dynamic library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select dependencies of the library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Remove current entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Double click to create a new entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform:"
+msgstr "Plataforma:"
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform"
+msgstr "Plataforma"
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dynamic Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Add an architecture entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "GDNativeLibrary"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Enabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Disabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Library"
+msgstr "Biblioteca"
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Libraries: "
+msgstr "Bibliotecas: "
+
+#: modules/gdnative/register_types.cpp
+msgid "GDNative"
+msgstr "GDNative"
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Step argument is zero!"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not a script with an instance"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a script"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a resource file"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (missing @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (can't load script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (invalid script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary (invalid subclasses)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Object can't provide a length."
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Plane:"
+msgstr "Plano:"
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Floor:"
+msgstr "Chan:"
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Delete Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paste Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paint"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Grid Map"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Snap View"
+msgstr "Axustar Vista"
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Disabled"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Above"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Below"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit X Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Y Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Z Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Clear Rotation"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Paste Selects"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clear Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Settings"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Pick Distance:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Filter meshes"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
+#: modules/mono/csharp_script.cpp
+msgid "Class name can't be a reserved keyword"
+msgstr ""
+
+#: modules/mono/mono_gd/gd_mono_utils.cpp
+msgid "End of inner exception stack trace"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Bake NavMesh"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Clear the navigation mesh."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Setting up Configuration..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Calculating grid size..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Marking walkable triangles..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Constructing compact heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Eroding walkable area..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Partitioning..."
+msgstr "Particionando..."
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating contours..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating polymesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Converting to native navigation mesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Navigation Mesh Generator Setup:"
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Parsing Geometry..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Done!"
+msgstr "Feito!"
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"A node yielded without working memory, please read the docs on how to yield "
+"properly!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Node yielded, but did not return a function state in the first working "
+"memory."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Return value must be assigned to first element of node working memory! Fix "
+"your node please."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Node returned an invalid sequence output: "
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Found sequence bit but not the node in the stack, report bug!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Stack overflow with stack depth: "
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Signal Arguments"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument name"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Default Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Input Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Output Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Variables:"
+msgstr "Variables:"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Signals:"
+msgstr "Sinais:"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name is not a valid identifier:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name already in use by another func/var/signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete input port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Input Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Output Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Duplicate VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Preload Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node(s) From Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid ""
+"Can't drop properties because script '%s' is not used in this scene.\n"
+"Drop holding 'Shift' to just copy the signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Getter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Setter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Move Node(s)"
+msgstr "Mover Nodo(s)"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Nodes"
+msgstr "Conectar Nodos"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Disconnect Nodes"
+msgstr "Desconectar Nodos"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Data"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Script already has function '%s'"
+msgstr "O script xa ten unha función chamada '%s'"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Input Value"
+msgstr "Cambiar Valor de Entrada"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Resize Comment"
+msgstr "Cambiar Tamaño do Comentario"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't copy the function node."
+msgstr "Non se pode copiar o nodo función."
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr "O portapapeis está baleiro!"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste VisualScript Nodes"
+msgstr "Pegar Nodos VisualScript"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't create function with a function node."
+msgstr "Non se pode crear unha función cun nodo función."
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't create function of nodes from nodes of multiple functions."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select at least one node with sequence port."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Try to only have one sequence input in selection."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create Function"
+msgstr "Crear Función"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Function"
+msgstr "Eliminar Función"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Variable"
+msgstr "Eliminar Variable"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Variable:"
+msgstr "Editando Variable:"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Signal"
+msgstr "Eliminar Sinal"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Signal:"
+msgstr "Editando Sinal:"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Make Tool:"
+msgstr "Ferramenta:"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Members:"
+msgstr "Membros:"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type:"
+msgstr "Cambiar Tipo Base:"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Nodes..."
+msgstr "Engadir Nodos..."
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function..."
+msgstr "Engadir Función..."
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "function_name"
+msgstr "nome_da_funcion"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select or create a function to edit its graph."
+msgstr "Seleccione ou cree unha función para editar a sua gráfica."
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete Selected"
+msgstr "Eliminar Selección"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Find Node Type"
+msgstr "Encontrar Tipo de Nodo"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Copy Nodes"
+msgstr "Copiar Nodos"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Cut Nodes"
+msgstr "Cortar Nodos"
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Make Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Refresh Graph"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit Member"
+msgstr "Editar Membro"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Input type not iterable: "
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid: "
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name."
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Base object is not a Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Path does not lead Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name '%s' in node %s."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid argument of type: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid arguments: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableGet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableSet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Custom node has no _step() method, can't process graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ""
+"Invalid return value from _step(), must be integer (seq out), or string "
+"(error)."
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search VisualScript"
+msgstr "Buscar en VisualScript"
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Set %s"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package name is missing."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package segments must be of non-zero length."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' is not allowed in Android application package names."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "A digit cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The package must have at least one '.' separator."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Select device from the list"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find the 'apksigner' tool."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Debug keystore not configured in the Editor Settings nor in the preset."
+msgstr ""
+"Non está configurado o Keystore de depuración nin na configuración do "
+"editor, nin nos axustes de exportación."
+
+#: platform/android/export/export.cpp
+msgid "Release keystore incorrectly configured in the export preset."
+msgstr ""
+"O Keystore Release non está configurado correctamente nos axustes de "
+"exportación."
+
+#: platform/android/export/export.cpp
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'platform-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid public key for APK expansion."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid package name:"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" "
+"project setting (changed in Godot 3.2.2).\n"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "\"Use Custom Build\" must be enabled to use the plugins."
+msgstr ""
+"\"Use Custom Build\" debe estar activado para usar estas características "
+"adicionais (plugins)."
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR"
+"\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid filename! Android App Bundle requires the *.aab extension."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "APK Expansion not compatible with Android App Bundle."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid filename! Android APK requires the *.apk extension."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Trying to build from a custom built template, but no version info for it "
+"exists. Please reinstall from the 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build version mismatch:\n"
+" Template installed: %s\n"
+" Godot Version: %s\n"
+"Please reinstall Android build template from 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Building Android Project (gradle)"
+msgstr "Construir Proxecto Android (gradle)"
+
+#: platform/android/export/export.cpp
+msgid ""
+"Building of Android project failed, check output for the error.\n"
+"Alternatively visit docs.godotengine.org for Android build documentation."
+msgstr ""
+"A creación do proxecto para Android fallou; comproba a saída para encontrar "
+"o erro.\n"
+"Ou visita docs.godotengine.org para ver a documentación sobre compilación "
+"para Android."
+
+#: platform/android/export/export.cpp
+msgid "Moving output"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Unable to copy and rename export file, check gradle project directory for "
+"outputs."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier is missing."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The character '%s' is not allowed in Identifier."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "App Store Team ID not specified - cannot configure the project."
+msgstr ""
+"ID de App Store Team non especificado - non se pode configurar o proxecto."
+
+#: platform/iphone/export/export.cpp
+msgid "Invalid Identifier:"
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Required icon is not specified in the preset."
+msgstr ""
+"As iconas requeridas non están especificadas nos axustes de exportación."
+
+#: platform/javascript/export/export.cpp
+msgid "Stop HTTP Server"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run in Browser"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run exported HTML in the system's default browser."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not write file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not open template for export:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Invalid export template:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read custom HTML shell:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read boot splash image file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Using default boot splash image."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package short name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package unique name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package publisher display name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid product GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid publisher GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid background color."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid Store Logo image dimensions (should be 50x50)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid splash screen image dimensions (should be 620x300)."
+msgstr ""
+
+#: scene/2d/animated_sprite.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite to display frames."
+msgstr ""
+
+#: scene/2d/canvas_modulate.cpp
+msgid ""
+"Only one visible CanvasModulate is allowed per scene (or set of instanced "
+"scenes). The first created one will work, while the rest will be ignored."
+msgstr ""
+
+#: scene/2d/collision_object_2d.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
+"define its shape."
+msgstr ""
+"Este nodo non ten unha forma física definida, polo que non pode colisionar "
+"ou interactuar con outros obxectos.\n"
+"Engade un nodo CollisionShape2D ou CollisionPolygon2D como fillo para "
+"definir a sua forma."
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid ""
+"CollisionPolygon2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+"O nodo CollisionPolygon2D só serve para darlle unha forma física a nodos "
+"derivados de CollisionObject2D. É decir, do tipo Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D, etc."
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "An empty CollisionPolygon2D has no effect on collision."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"CollisionShape2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+"O nodo CollisionShape2D só serve para darlle unha forma física a nodos "
+"derivados de CollisionObject2D. É decir, do tipo Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D, etc."
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"A shape must be provided for CollisionShape2D to function. Please create a "
+"shape resource for it!"
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"Polygon-based shapes are not meant be used nor edited directly through the "
+"CollisionShape2D node. Please use the CollisionPolygon2D node instead."
+msgstr ""
+"As formas físicas baseadas en polígonos non están pensadas para editarse "
+"directamente mediante o nodo CollisionShape2D. Por favor, usa o nodo "
+"CollisionPolygon2D no seu lugar."
+
+#: scene/2d/cpu_particles_2d.cpp
+msgid ""
+"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A and Node B must be PhysicsBody2Ds"
+msgstr "Os nodo A e B teñen que ser do tipo PhysicsBody2D"
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A must be a PhysicsBody2D"
+msgstr "O nodo A ten que ser un nodo PhysicsBody2D"
+
+#: scene/2d/joints_2d.cpp
+msgid "Node B must be a PhysicsBody2D"
+msgstr "O nodo B ten que ser un nodo PhysicsBody2D"
+
+#: scene/2d/joints_2d.cpp
+msgid "Joint is not connected to two PhysicsBody2Ds"
+msgstr "A articulación non está conectada a dous nodos PhysicsBody2D"
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A and Node B must be different PhysicsBody2Ds"
+msgstr "Os nodos A e B teñen que ser nodos PhysicsBody2D distintos"
+
+#: scene/2d/light_2d.cpp
+msgid ""
+"A texture with the shape of the light must be supplied to the \"Texture\" "
+"property."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid ""
+"An occluder polygon must be set (or drawn) for this occluder to take effect."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"A NavigationPolygon resource must be set or created for this node to work. "
+"Please set a property or draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"NavigationPolygonInstance must be a child or grandchild to a Navigation2D "
+"node. It only provides navigation data."
+msgstr ""
+
+#: scene/2d/parallax_layer.cpp
+msgid ""
+"ParallaxLayer node only works when set as child of a ParallaxBackground node."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles2D node instead. You can use the \"Convert to "
+"CPUParticles\" option for this purpose."
+msgstr ""
+"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 scene/3d/particles.cpp
+msgid ""
+"A material to process the particles is not assigned, so no behavior is "
+"imprinted."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"Particles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/path_2d.cpp
+msgid "PathFollow2D only works when set as a child of a Path2D node."
+msgstr ""
+
+#: scene/2d/physics_body_2d.cpp
+msgid ""
+"Size changes to RigidBody2D (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+"Os cambios ao tamaño do RigidBody2D (en modo ríxido ou modo personaxe) serán "
+"sobreescritos por o motor físico cando a aplicación estea executándose.\n"
+"Cambia o tamaño dos nodos fillos (CollisionShape2D e CollisionPolygon2D) no "
+"seu lugar."
+
+#: scene/2d/remote_transform_2d.cpp
+msgid "Path property must point to a valid Node2D node to work."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "This Bone2D chain should end at a Skeleton2D node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid ""
+"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
+msgstr ""
+
+#: scene/2d/tile_map.cpp
+msgid ""
+"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes "
+"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
+"KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/visibility_notifier_2d.cpp
+msgid ""
+"VisibilityEnabler2D works best when used with the edited scene root directly "
+"as parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRCamera must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRController must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The controller ID must not be 0 or this controller won't be bound to an "
+"actual controller."
+msgstr ""
+"O ID do controlador non pode ser 0, ou o controlador non estará asociado a "
+"ningún controlador real."
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRAnchor must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The anchor ID must not be 0 or this anchor won't be bound to an actual "
+"anchor."
+msgstr ""
+"O ID da áncora non pode ser 0, ou esta áncora non estará asociada a ningunha "
+"áncora real."
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVROrigin requires an ARVRCamera child node."
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Finding meshes and lights"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Preparing geometry (%d/%d)"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Preparing environment"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Generating capture"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Done"
+msgstr "Feito"
+
+#: scene/3d/collision_object.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape or CollisionPolygon as a child to define "
+"its shape."
+msgstr ""
+"Este nodo non ten unha forma física definida, polo que non pode colisionar "
+"ou interactuar con outros obxectos.\n"
+"Engade un nodo CollisionShape ou CollisionPolygon como fillo para definir a "
+"sua forma."
+
+#: scene/3d/collision_polygon.cpp
+msgid ""
+"CollisionPolygon only serves to provide a collision shape to a "
+"CollisionObject derived node. Please only use it as a child of Area, "
+"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
+msgstr ""
+"O nodo CollisionPolygon só serve para darlle unha forma física a nodos "
+"derivados de CollisionObject. É decir, do tipo Area, StaticBody, RigidBody, "
+"KinematicBody, etc."
+
+#: scene/3d/collision_polygon.cpp
+msgid "An empty CollisionPolygon has no effect on collision."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"CollisionShape only serves to provide a collision shape to a CollisionObject "
+"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
+"KinematicBody, etc. to give them a shape."
+msgstr ""
+"O nodo CollisionShape só serve para darlle unha forma física a nodos "
+"derivados de CollisionObject. É decir, do tipo Area, StaticBody, RigidBody, "
+"KinematicBody, etc."
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"A shape must be provided for CollisionShape to function. Please create a "
+"shape resource for it."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"Plane shapes don't work well and will be removed in future versions. Please "
+"don't use them."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"ConcavePolygonShape doesn't support RigidBody in another mode than static."
+msgstr ""
+"A forma física ConcavePolygonShape non está soportada en nodos RigidBody en "
+"ningún outro modo que non sexa o estático."
+
+#: scene/3d/cpu_particles.cpp
+msgid "Nothing is visible because no mesh has been assigned."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid ""
+"CPUParticles animation requires the usage of a SpatialMaterial whose "
+"Billboard Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Plotting Meshes"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid ""
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
+msgstr ""
+
+#: scene/3d/light.cpp
+msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
+msgstr ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid "A NavigationMesh resource must be set or created for this node to work."
+msgstr ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid ""
+"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
+"It only provides navigation data."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
+"\" option for this purpose."
+msgstr ""
+"As partículas baseadas na GPU non están soportas por o controlador de vídeo "
+"de GLES2.\n"
+"Usa o nodo CPUParticles no seu lugar. Podes usar a opción \"Converter a "
+"CPUParticles\" con tal motivo."
+
+#: scene/3d/particles.cpp
+msgid ""
+"Nothing is visible because meshes have not been assigned to draw passes."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Particles animation requires the usage of a SpatialMaterial whose Billboard "
+"Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid "PathFollow only works when set as a child of a Path node."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid ""
+"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
+"parent Path's Curve resource."
+msgstr ""
+
+#: scene/3d/physics_body.cpp
+msgid ""
+"Size changes to RigidBody (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+"Os cambios ao tamaño do RigidBody (en modo ríxido ou modo personaxe) serán "
+"sobreescritos por o motor físico cando a aplicación estea executándose.\n"
+"Cambia o tamaño dos nodos fillos (CollisionShape e CollisionPolygon) no seu "
+"lugar."
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A and Node B must be PhysicsBodies"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A must be a PhysicsBody"
+msgstr "O nodo A ten que ser un nodo PhysicsBody"
+
+#: scene/3d/physics_joint.cpp
+msgid "Node B must be a PhysicsBody"
+msgstr "O nodo B ten que ser un nodo PhysicsBody"
+
+#: scene/3d/physics_joint.cpp
+msgid "Joint is not connected to any PhysicsBodies"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A and Node B must be different PhysicsBodies"
+msgstr ""
+
+#: scene/3d/remote_transform.cpp
+msgid ""
+"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
+"derived node to work."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid "This body will be ignored until you set a mesh."
+msgstr "Este corpo será ignorado ata que se lle sea asignado unha malla."
+
+#: scene/3d/soft_body.cpp
+msgid ""
+"Size changes to SoftBody will be overridden by the physics engine when "
+"running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+"Os cambios ao tamaño do SoftBody serán sobreescritos por o motor físico "
+"cando a aplicación estea executándose.\n"
+"Cambia o tamaño dos nodos fillos (CollisionShape e CollisionPolygon) no seu "
+"lugar."
+
+#: scene/3d/sprite_3d.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite3D to display frames."
+msgstr ""
+
+#: scene/3d/vehicle_body.cpp
+msgid ""
+"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use "
+"it as a child of a VehicleBody."
+msgstr ""
+"O nodo VehicleWheel (Roda de Vehículo) serve para proporcionar un sistema de "
+"rodas a un nodo VehicleBody. Por favor; úsao como fillo dun nodo VehicleBody."
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"WorldEnvironment requires its \"Environment\" property to contain an "
+"Environment to have a visible effect."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set "
+"this environment's Background Mode to Canvas (for 2D scenes)."
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "On BlendTree node '%s', animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "Animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "In node '%s', invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Nothing connected to input '%s' of node '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "No root AnimationNode for the graph is set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path to an AnimationPlayer node containing animations is not set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "The AnimationPlayer root node is not a valid node."
+msgstr ""
+
+#: scene/animation/animation_tree_player.cpp
+msgid "This node has been deprecated. Use AnimationTree instead."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid ""
+"Color: #%s\n"
+"LMB: Set color\n"
+"RMB: Remove preset"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Pick a color from the editor window."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "HSV"
+msgstr "HSV"
+
+#: scene/gui/color_picker.cpp
+msgid "Raw"
+msgstr "Sen Procesar (Raw)"
+
+#: scene/gui/color_picker.cpp
+msgid "Switch between hexadecimal and code values."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Add current color as a preset."
+msgstr ""
+
+#: scene/gui/container.cpp
+msgid ""
+"Container by itself serves no purpose unless a script configures its "
+"children placement behavior.\n"
+"If you don't intend to add a script, use a plain Control node instead."
+msgstr ""
+"Un nodo contedor (Container) por sí mesmo non ten ningunha utilidade, salvo "
+"que se lle engada algún Script que configure a colocación dos seus nodos "
+"fillos.\n"
+"Se non tes pensado engadir un Script, utilizada un nodo Control no seu lugar."
+
+#: scene/gui/control.cpp
+msgid ""
+"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
+"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Alert!"
+msgstr "Alerta!"
+
+#: scene/gui/dialogs.cpp
+msgid "Please Confirm..."
+msgstr "Por favor, confirma..."
+
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
+#: scene/gui/popup.cpp
+msgid ""
+"Popups will hide by default unless you call popup() or any of the popup*() "
+"functions. Making them visible for editing is fine, but they will hide upon "
+"running."
+msgstr ""
+"As ventás emerxentes (Popups) están ocultas por defecto, a non ser que "
+"chames a popup() ou calquera das funcións popup*(). Podes facelas visibles "
+"para editalas, pero ocultarasen ao iniciar a execución."
+
+#: scene/gui/range.cpp
+msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
+msgstr ""
+
+#: scene/gui/scroll_container.cpp
+msgid ""
+"ScrollContainer is intended to work with a single child control.\n"
+"Use a container as child (VBox, HBox, etc.), or a Control and set the custom "
+"minimum size manually."
+msgstr ""
+
+#: scene/gui/tree.cpp
+msgid "(Other)"
+msgstr "(Outros)"
+
+#: scene/main/scene_tree.cpp
+msgid ""
+"Default Environment as specified in Project Settings (Rendering -> "
+"Environment -> Default Environment) could not be loaded."
+msgstr ""
+
+#: scene/main/viewport.cpp
+msgid ""
+"This viewport is not set as render target. If you intend for it to display "
+"its contents directly to the screen, make it a child of a Control so it can "
+"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
+"texture to some node for display."
+msgstr ""
+"Esta Mini-Ventá (Viewport) no está configurada como obxectivo de "
+"renderizado. Se quere que o seu contido se mostre directamente na pantalla, "
+"convértao nun nodo fillo dun nodo Control para que poida recibir dimensións. "
+"Ou ben, fágao un RenderTarget e asigne a súa textura a algún nodo."
+
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+"As dimensións da Mini-Ventá (Viewport) deben de ser maior que 0 para poder "
+"renderizar nada."
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid source for preview."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid source for shader."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to uniform."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Varyings can only be assigned in vertex function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Constants cannot be modified."
+msgstr ""
diff --git a/editor/translations/he.po b/editor/translations/he.po
index ebccec8d4b..ab97d97c0a 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -1,6 +1,6 @@
# Hebrew translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Daniel <lorddaniel09@gmail.com>, 2018.
# Ben Golan <golanben4@gmail.com>, 2017.
@@ -18,12 +18,13 @@
# yariv benj <yariv4400@gmail.com>, 2020.
# Guy Dadon <guydadon14@gmail.com>, 2020.
# bruvzg <bruvzg13@gmail.com>, 2020.
+# Omer I.S. <omeritzicschwartz@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-03 19:28+0000\n"
-"Last-Translator: Ziv D <wizdavid@gmail.com>\n"
+"PO-Revision-Date: 2021-02-21 10:51+0000\n"
+"Last-Translator: Omer I.S. <omeritzicschwartz@gmail.com>\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/"
"godot/he/>\n"
"Language: he\n"
@@ -32,7 +33,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && "
"n % 10 == 0) ? 2 : 3));\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -379,9 +380,8 @@ msgid "Anim Insert"
msgstr "הוסף הנפשה"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "AnimationPlayer can't animate itself, only other players."
-msgstr "נגן הנפשות ×œ× ×™×›×•×œ להנפיש ×ת עצמו, רק ×©×—×§× ×™× ×חרי×."
+msgstr "נגן ההנפשות ×œ× ×™×›×•×œ להנפיש ×ת עצמו, רק ×©×—×§× ×™× ×חרי×."
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
@@ -662,7 +662,7 @@ msgstr "בחירת רצועות להעתקה"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "העתקה"
@@ -900,9 +900,8 @@ msgid "Connect a Signal to a Method"
msgstr "שגי×ת חיבור"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Edit Connection:"
-msgstr "שגי×ת חיבור"
+msgstr "עריכת חיבור:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
@@ -1102,7 +1101,7 @@ msgstr "דפדפן מש××‘×™× ×™×ª×•×ž×™×"
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
msgid "Delete"
-msgstr "למחוק"
+msgstr "מחיקה"
#: editor/dependency_editor.cpp
msgid "Owns"
@@ -1194,9 +1193,8 @@ msgid "License"
msgstr "רישיון"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Third-party Licenses"
-msgstr "רישיון צד שלישי"
+msgstr "רשיונות צד שלישי"
#: editor/editor_about.cpp
msgid ""
@@ -1657,9 +1655,8 @@ msgid "Script Editor"
msgstr "פתיחת עורך סקריפטי×"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Asset Library"
-msgstr "×™×™×¦×•× ×¡×¤×¨×™×”"
+msgstr "ספריית מש×בי×"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
@@ -1874,8 +1871,8 @@ msgid "Open a File or Directory"
msgstr "פתיחת קובץ ×ו תיקייה"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "שמירה"
@@ -1966,10 +1963,6 @@ msgstr "תצוגה מקדימה:"
msgid "File:"
msgstr "קובץ:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "יש להשתמש בסיומת תקנית."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "סריקת מקורות"
@@ -2392,6 +2385,10 @@ msgid "There is no defined scene to run."
msgstr "×ין סצנה מוגדרת להרצה."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "×œ× × ×™×ª×Ÿ להפעיל תהליך משנה!"
@@ -2435,18 +2432,6 @@ msgstr "דרוש מפרק שורש כדי לשמור ×ת הסצינה."
msgid "Save Scene As..."
msgstr "שמירת סצנה בש×…"
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "ל×"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "כן"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "סצנה ×–×ת ×ž×¢×•×œ× ×œ× × ×©×ž×¨×”. לשמור לפני ההרצה?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "×œ× × ×™×ª×Ÿ לבצע פעולה זו ×œ×œ× ×¡×¦× ×”."
@@ -2496,6 +2481,10 @@ msgid "Quit"
msgstr "יצי××”"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "כן"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "לצ×ת מהעורך?"
@@ -2540,7 +2529,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "×œ× × ×™×ª×Ÿ לפתוח ×ת תוסף ההרחבות בנתיב: '%s' פענוח ההגדרות נכשל."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "×œ× × ×™×ª×Ÿ ×œ×ž×¦×•× ×©×“×” סקריפט עבור תוסף הרחבה בנתיב 'res://addons/%s'."
#: editor/editor_node.cpp
@@ -2960,14 +2950,6 @@ msgid "Help"
msgstr "עזרה"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "חיפוש"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "×ž×¡×ž×›×™× ×ž×§×•×•× ×™×"
@@ -3128,6 +3110,24 @@ msgid "Open & Run a Script"
msgstr "פתיחה והרצה של סקריפט"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"×”×§×‘×¦×™× ×”×‘××™× ×”× ×—×“×©×™× ×‘×›×•× ×Ÿ.\n"
+"ב×ילו פעולות לנקוט?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "רענון"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "שמירה מחדש"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "חדש בירושה"
@@ -3336,7 +3336,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "הדבקה"
@@ -3901,8 +3901,18 @@ msgstr "שמירה…"
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "חיפוש טקסט"
+msgid "%d match in %d file."
+msgstr "%d הת×מות."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d הת×מות."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d הת×מות."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4045,6 +4055,21 @@ msgstr ""
msgid "Saving..."
msgstr "שמירה…"
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "× × ×œ×‘×—×•×¨ ×ž×¤×¨×§×™× ×œ×™×™×¦×•×"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "ייבו×"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "טעינת בררת המחדל"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d קבצי×"
@@ -5028,7 +5053,8 @@ msgid "Got:"
msgstr "התקבל:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "בדיקת ×”×ש sha256 נכשלה"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5132,7 +5158,6 @@ msgid "Sort:"
msgstr "מיון:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "קטגוריה:"
@@ -5161,10 +5186,10 @@ msgid "Assets ZIP File"
msgstr "קובץ ZIP של נכסי×"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"×ין ×פשרות לקבוע נתיב שמירה עבור תמונות lightmap.\n"
"שמור/×™ ×ת הסצינה שלך (כדי שתמונות יישמרו ב×ותה תיקייה), ×ו בחר/×™ נתיב שמירה "
@@ -5181,9 +5206,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "יצירת תמונות lightmap נכשלה, וד×/×™ שהנתיב ניתן לכתיבה."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "×פיית Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "בחירת קובץ תבנית"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5476,9 +5521,8 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
-#, fuzzy
msgid "Zoom Reset"
-msgstr "להתרחק"
+msgstr "×יפוס התקריב"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6296,6 +6340,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "המרה ל×ותיות גדולות"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6356,10 +6405,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6964,6 +7009,14 @@ msgstr "סגירת מסמכי×"
msgid "Run"
msgstr "הרצה"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "חיפוש"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "לצעוד לתוך"
@@ -7019,16 +7072,6 @@ msgstr ""
"×”×§×‘×¦×™× ×”×‘××™× ×”× ×—×“×©×™× ×‘×›×•× ×Ÿ.\n"
"ב×ילו פעולות לנקוט?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "רענון"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "שמירה מחדש"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "ניפוי שגי×ות"
@@ -7127,8 +7170,8 @@ msgstr "מחיקת נקודות"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "גזירה"
@@ -7255,13 +7298,12 @@ msgid "Go to Previous Breakpoint"
msgstr "מעבר לנקודת העצירה הקודמת"
#: editor/plugins/shader_editor_plugin.cpp
-#, fuzzy
msgid ""
"This shader has been modified on on disk.\n"
"What action should be taken?"
msgstr ""
"×”×§×‘×¦×™× ×”×‘××™× ×”× ×—×“×©×™× ×‘×›×•× ×Ÿ.\n"
-"ב×ילו פעולות לנקוט?:"
+"ב×ילו פעולות לנקוט?"
#: editor/plugins/shader_editor_plugin.cpp
msgid "Shader"
@@ -7369,6 +7411,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8669,11 +8715,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "No commit message was provided"
-msgstr "×œ× ×¦×•×™×Ÿ ש×"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8739,10 +8780,6 @@ msgid "Stage All"
msgstr "לשמור הכול"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "סנכרון ×”×©×™× ×•×™×™× ×‘×¡×§×¨×™×¤×˜"
@@ -10039,6 +10076,13 @@ msgid "Projects"
msgstr "מיז×"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr ""
+"×”×§×‘×¦×™× × ×¡×¨×§×™×,\n"
+"× × ×œ×”×ž×ª×™×Ÿâ€¦"
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10409,6 +10453,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "טעינת בררת המחדל"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "ערכה מוגדרת…"
@@ -10668,6 +10717,16 @@ msgid "Instance Child Scene"
msgstr "יצירת מופע לסצנה הצ×צ×ית"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "×œ× ×™×›×•×œ לפעול על ×ž×¤×¨×§×™× ×ž×¡×¦× ×” זרה!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "הדבקת מפרקי×"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "ניתוק סקריפט"
@@ -10791,6 +10850,11 @@ msgid "Attach Script"
msgstr "חיבור סקריפט"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "גזירת מפרקי×"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "הסרת מפרק(×™×)"
@@ -11591,6 +11655,38 @@ msgstr "סינון רשתות"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "יש לחבר מש×ב MeshLibrary ל- GridMap ×”×–×” כדי להשתמש ברשתות שלו."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "כיווני×"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "הזחה מימין"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "גרסה נוכחית:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "מדפיס ת×ורות:"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "×©× ×ž×—×œ×§×” ×œ× ×™×›×•×œ להיות מילת מפתח שמורה"
@@ -12094,12 +12190,14 @@ msgid "Select device from the list"
msgstr "× × ×œ×‘×—×•×¨ התקן מהרשימה"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "קובץ ההפעלה של ADB ×œ× × ×§×‘×¢ בהגדרות העורך."
+msgid "Unable to find the 'apksigner' tool."
+msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner ×œ× × ×§×‘×¢ בהגדרות העורך."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr "תבנית בנייה ל×נדרו×יד ×œ× ×ž×•×ª×§× ×ª בפרוייקט. ההתקנה ×”×™× ×ž×ª×¤×¨×™×˜ המיז×."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12110,12 +12208,14 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "מפתח גירסת שיחרור נקבע ב×ופן שגוי בהגדרות הייצו×."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#, fuzzy
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"בנייה מות×מת ×ישית דורשת נתיב חוקי של ערכת פיתוח ל×נדרו×יד בהגדרות העורך."
+"נתיב ×œ× ×—×•×§×™ לערכת פיתוח ×נדרו×יד עבור בנייה מות×מת ×ישית בהגדרות העורך."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+#, fuzzy
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
"נתיב ×œ× ×—×•×§×™ לערכת פיתוח ×נדרו×יד עבור בנייה מות×מת ×ישית בהגדרות העורך."
@@ -12124,10 +12224,22 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
-msgstr "תבנית בנייה ל×נדרו×יד ×œ× ×ž×•×ª×§× ×ª בפרוייקט. ההתקנה ×”×™× ×ž×ª×¤×¨×™×˜ המיז×."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+#, fuzzy
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"נתיב ×œ× ×—×•×§×™ לערכת פיתוח ×נדרו×יד עבור בנייה מות×מת ×ישית בהגדרות העורך."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12377,6 +12489,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "ל־CollisionPolygon2D ריק ×ין השפעה על התנגשות."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12568,28 +12688,32 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin דורש צ××¦× ×ž×¡×•×’ ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(זמן שנותר: %d:%02d שנ׳)"
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "ניתוח ×’×™×ומטרי..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "מדפיס רשתות: "
+#, fuzzy
+msgid "Preparing environment"
+msgstr "צפייה בסביבה"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "מדפיס ת×ורות:"
+#, fuzzy
+msgid "Generating capture"
+msgstr "נוצרות מפות ת×ורה"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "×ž×¡×™×™× ×”×“×¤×¡×”"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "נוצרות מפות ת×ורה"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "רשתות ת×ורה: "
+msgid "Done"
+msgstr "בוצע"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12659,6 +12783,10 @@ msgid "Plotting Meshes"
msgstr "הדפסת רשתות"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "×ž×¡×™×™× ×”×“×¤×¡×”"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12666,11 +12794,6 @@ msgstr ""
"מנהל הוויד×ו GLES2 ×ינו תומך ב- GIProbes.\n"
"השתמש ב-BakedLightmap במקו×."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight ×¢× ×–×•×•×™×ª רחבה מ-90 מעלות ×ינו יכול להטיל צללי×."
@@ -12905,6 +13028,15 @@ msgstr "×זהרה!"
msgid "Please Confirm..."
msgstr "× × ×œ×שר…"
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "יש להשתמש בסיומת תקנית."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "הפעלת הצמדה"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12956,6 +13088,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "גודל חלון התצוגה חייב להיות גדול מ-0 על מנת להציג משהו."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "מקור ×œ× ×ª×§×™×Ÿ לתצוגה מקדימה."
@@ -12983,6 +13121,42 @@ msgstr "ניתן להקצות ×©×™× ×•×™×™× ×¨×§ בפונקצית vertex."
msgid "Constants cannot be modified."
msgstr "××™ ×פשר לשנות קבועי×."
+#~ msgid "No"
+#~ msgstr "ל×"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "סצנה ×–×ת ×ž×¢×•×œ× ×œ× × ×©×ž×¨×”. לשמור לפני ההרצה?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "קובץ ההפעלה של ADB ×œ× × ×§×‘×¢ בהגדרות העורך."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner ×œ× × ×§×‘×¢ בהגדרות העורך."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "בנייה מות×מת ×ישית דורשת נתיב חוקי של ערכת פיתוח ל×נדרו×יד בהגדרות העורך."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(זמן שנותר: %d:%02d שנ׳)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "מדפיס רשתות: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "רשתות ת×ורה: "
+
+#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "חיפוש טקסט"
+
+#, fuzzy
+#~ msgid "No commit message was provided"
+#~ msgstr "×œ× ×¦×•×™×Ÿ ש×"
+
#, fuzzy
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "כבר ×§×™×™×ž×™× ×§×•×‘×¥ ×ו תיקייה ×‘×©× ×”×–×”."
@@ -13160,9 +13334,6 @@ msgstr "××™ ×פשר לשנות קבועי×."
#~ msgid "Failed to save solution."
#~ msgstr "שמירת הפתרון נכשלה."
-#~ msgid "Done"
-#~ msgstr "בוצע"
-
#~ msgid "Failed to create C# project."
#~ msgstr "יצירת ×ž×™×–× C#‎ נכשלה."
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 03fbdc1971..034451542b 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -1,6 +1,6 @@
# Hindi translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Abhas Kumar Sinha <abhaskumarsinha@gmail.com>, 2017.
# Suryansh5545 <suryanshpathak5545@gmail.com>, 2018, 2020.
@@ -9,15 +9,16 @@
# Abhay Patel <abhay111patel@gmail.com>, 2019.
# Lakshmi-Jayakumar <lakshmi.jayakumar.tkm@gmail.com>, 2019.
# Devashishsingh98 <devashishsingh98@gmail.com>, 2019.
-# Shirious <sad3119823@gmail.com>, 2020.
+# Shirious <sad3119823@gmail.com>, 2020, 2021.
# Abhay Patel <Traumaticbean@protonmail.com>, 2020.
# Bishwajeet Parhi <bishwajeet.techmaster@gmail.com>, 2020.
+# l4KKY <greenforcesave@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-20 23:08+0000\n"
-"Last-Translator: Bishwajeet Parhi <bishwajeet.techmaster@gmail.com>\n"
+"PO-Revision-Date: 2021-01-06 18:29+0000\n"
+"Last-Translator: Shirious <sad3119823@gmail.com>\n"
"Language-Team: Hindi <https://hosted.weblate.org/projects/godot-engine/godot/"
"hi/>\n"
"Language: hi\n"
@@ -25,7 +26,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -648,7 +649,7 @@ msgstr "कॉपी करने के लिठटà¥à¤°à¥ˆà¤• का चय
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "कॉपी"
@@ -1151,9 +1152,8 @@ msgid "Gold Sponsors"
msgstr "गोलà¥à¤¡ पà¥à¤°à¤¾à¤¯à¥‹à¤œà¤•"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Silver Sponsors"
-msgstr "रजत दाताओं"
+msgstr "रजत पà¥à¤°à¤¾à¤¯à¥‹à¤œà¤•"
#: editor/editor_about.cpp
#, fuzzy
@@ -1477,7 +1477,7 @@ msgstr "औटोलोड पà¥à¤¨à¤°à¥à¤µà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ करेà
#: editor/editor_autoload_settings.cpp
msgid "Can't add autoload:"
-msgstr ""
+msgstr "औटोलोड नहीं डाल सकते:"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -1852,8 +1852,8 @@ msgid "Open a File or Directory"
msgstr "फ़ाइल या डायरेकà¥à¤Ÿà¤°à¥€ खोलिये"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "सेव कीजिये"
@@ -1944,10 +1944,6 @@ msgstr "पूरà¥à¤µ दरà¥à¤¶à¤¨:"
msgid "File:"
msgstr "फ़ाइल:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "मानà¥à¤¯ à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤¨à¤¶à¤¨ इसà¥à¤¤à¥‡à¤®à¤¾à¤² कीजिये."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "सà¥à¤°à¥‹à¤¤à¤¸à¥à¤•ैन कीजिये"
@@ -2303,6 +2299,8 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"लेआउट सेव करते वक़à¥à¤¤ à¤à¤°à¤° आ रहा है|\n"
+"à¤à¤¡à¥€à¤Ÿà¤° का पाथ writeable है ये सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ किजिये|"
#: editor/editor_node.cpp
msgid ""
@@ -2310,6 +2308,8 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"मूल à¤à¤¡à¥€à¤Ÿà¤° लेआउट ओवराईड हो चà¥à¤•ा है.\n"
+"मूल लेआउट को पà¥à¤¨: सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करने के लिये, डिलिट लेआउट परà¥à¤¯à¤¾à¤¯ का पà¥à¤°à¤¯à¥‹à¤— करे."
#: editor/editor_node.cpp
msgid "Layout name not found!"
@@ -2373,6 +2373,10 @@ msgid "There is no defined scene to run."
msgstr "चलाने के लिठकोई परिभाषित दृशà¥à¤¯ नहीं है ।"
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "उपपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ शà¥à¤°à¥‚ नहीं कर सका!"
@@ -2416,18 +2420,6 @@ msgstr "दृशà¥à¤¯ को बचाने के लिठà¤à¤• रूट
msgid "Save Scene As..."
msgstr "दृशà¥à¤¯ के रूप में सहेजें ..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "नहीं"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "हाà¤"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "इस सीन को कभी नहीं बचाया गया। दौड़ने से पहले सहेजें?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "यह ऑपरेशन बिना किसी दृशà¥à¤¯ के नहीं किया जा सकता है।"
@@ -2466,6 +2458,8 @@ msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
+"वरà¥à¤¤à¤®à¤¾à¤¨ सीन मे कà¥à¤› अनसेवà¥à¤¡ बदलाव है|\n"
+"फिर भी सीन रेलोड करे? यह कà¥à¤°à¤¿à¤¯à¤¾ पूरà¥à¤µà¤µà¤¤ नहीं की जा सकती|"
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
@@ -2476,6 +2470,10 @@ msgid "Quit"
msgstr "छोड़ना"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "हाà¤"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "संपादक से बाहर निकलें?"
@@ -2520,7 +2518,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन को सकà¥à¤·à¤® करने में असमरà¥à¤¥: '%' कॉनà¥à¤«à¤¿à¤— का पारà¥à¤¸à¤¿à¤‚ग विफल रहा।"
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन के लिठसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ फ़ीलà¥à¤¡ खोजने में असमरà¥à¤¥: 'res://addons/% s'।"
#: editor/editor_node.cpp
@@ -2810,6 +2809,10 @@ msgid ""
"mobile device).\n"
"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
+"जब यह परà¥à¤¯à¤¾à¤¯ सकà¥à¤°à¤¿à¤¯ होता है, तब यह one-click deploy à¤à¤•à¥à¤¸à¤¯à¥à¤Ÿà¥‡à¤¬à¤² को इस कोमà¥à¤ªà¥à¤Ÿà¤° के IP "
+"को जोडने कि कोशिश करेगा ताकि चालॠपà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ डिबग हो सके|\n"
+"यह परà¥à¤¯à¤¾à¤¯ रिमोट डिबगींग (कोई और मशीन, आम तौर पर मोबाईल) के लिये उदà¥à¤¦à¥‡à¤¶à¤¿à¤¤ है|\n"
+"इसे GDScript इसि मशीन पर डिबग करने के लिये इसे सकà¥à¤°à¤¿à¤¯ करने कि जरà¥à¤°à¤¤ नही|"
#: editor/editor_node.cpp
#, fuzzy
@@ -2944,14 +2947,6 @@ msgid "Help"
msgstr "मदद"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "ढूंढें"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "ऑनलाइन डॉकà¥à¤¸"
@@ -3115,6 +3110,23 @@ msgid "Open & Run a Script"
msgstr "ओपन à¤à¤‚ड रन à¤à¤• सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr "निमà¥à¤¨ फ़ाइलों का निसà¥à¤¸à¤¾à¤°à¤£ नहीं हो पाया:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "नई विरासत में मिली"
@@ -3322,7 +3334,7 @@ msgstr "अदà¥à¤µà¤¿à¤¤à¥€à¤¯ बनाओ"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "चिपकाà¤à¤"
@@ -3395,7 +3407,7 @@ msgstr "कà¥à¤¯à¤¾ आप '_run' विधि को भूल गà¤?"
#: editor/editor_spin_slider.cpp
msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes."
-msgstr ""
+msgstr "पूरà¥à¤£à¤¾à¤‚क के लिठCtrl दबाठरखें. सटीक अंक के लिये Shift दबाठरखें."
#: editor/editor_sub_scene.cpp
msgid "Select Node(s) to Import"
@@ -3678,6 +3690,11 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"निमà¥à¤¨à¤²à¤¿à¤–ित फ़ाइले या फ़ोलà¥à¤¡à¤° दिये हà¥à¤ जगह '%s' के समान है:\n"
+"\n"
+"%s\n"
+"\n"
+"कà¥à¤¯à¤¾ आप उस पर लिखना चाहते है ?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3709,7 +3726,7 @@ msgstr "खà¥à¤²à¥‡ दृशà¥à¤¯"
#: editor/filesystem_dock.cpp
msgid "Instance"
-msgstr ""
+msgstr "इनसà¥à¤Ÿà¤¨à¥à¤¸"
#: editor/filesystem_dock.cpp
msgid "Add to Favorites"
@@ -3725,11 +3742,11 @@ msgstr "निरà¥à¤­à¤°à¤¿à¤¤ फ़ाइलें संपादित क
#: editor/filesystem_dock.cpp
msgid "View Owners..."
-msgstr ""
+msgstr "ओनरà¥à¤¸ देखे..."
#: editor/filesystem_dock.cpp
msgid "Move To..."
-msgstr ""
+msgstr "मे ले जाà¤à¤..."
#: editor/filesystem_dock.cpp
msgid "New Scene..."
@@ -3737,7 +3754,7 @@ msgstr "नया दृशà¥à¤¯..."
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
-msgstr ""
+msgstr "नई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ..."
#: editor/filesystem_dock.cpp
msgid "New Resource..."
@@ -3746,12 +3763,12 @@ msgstr "नया संसाधन..."
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
msgid "Expand All"
-msgstr ""
+msgstr "सभी बढाय"
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
msgid "Collapse All"
-msgstr ""
+msgstr "सभी ढहाय"
#: editor/filesystem_dock.cpp
msgid "Duplicate..."
@@ -3764,23 +3781,23 @@ msgstr "औटोलोड हिलाइये"
#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Rename..."
-msgstr ""
+msgstr "नाम बदली..."
#: editor/filesystem_dock.cpp
msgid "Previous Folder/File"
-msgstr ""
+msgstr "पिछला फ़ोलà¥à¤¡à¤°/फ़ाइल"
#: editor/filesystem_dock.cpp
msgid "Next Folder/File"
-msgstr ""
+msgstr "अâ€à¤—ला फ़ोलà¥à¤¡à¤°/फ़ाइल"
#: editor/filesystem_dock.cpp
msgid "Re-Scan Filesystem"
-msgstr ""
+msgstr "फाइलसिसà¥à¤Ÿà¥‡à¤® पà¥à¤¨:सà¥à¤•ैन करे"
#: editor/filesystem_dock.cpp
msgid "Toggle Split Mode"
-msgstr ""
+msgstr "सà¥à¤ªà¥à¤²à¤¿à¤Ÿ मोड टॉगल कीजिये"
#: editor/filesystem_dock.cpp
msgid "Search files"
@@ -3791,96 +3808,110 @@ msgid ""
"Scanning Files,\n"
"Please Wait..."
msgstr ""
+"फ़ाइले सà¥à¤•ैन कर रहा है,\n"
+"कृपया रà¥à¤•िये..."
#: editor/filesystem_dock.cpp
msgid "Move"
-msgstr ""
+msgstr "हिलाइये"
#: editor/filesystem_dock.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/project_manager.cpp editor/rename_dialog.cpp
#: editor/scene_tree_dock.cpp
msgid "Rename"
-msgstr ""
+msgstr "नाम बदली"
#: editor/filesystem_dock.cpp
msgid "Overwrite"
-msgstr ""
+msgstr "मौजूदा के ऊपर लिखे"
#: editor/filesystem_dock.cpp
msgid "Create Scene"
-msgstr "दृशà¥à¤¯ बनाà¤à¤‚"
+msgstr "सीन बनाà¤à¤‚"
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
-msgstr ""
+msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ बनाइये"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
msgid "Find in Files"
-msgstr ""
+msgstr "फ़ाइलों मे तलाशिये"
#: editor/find_in_files.cpp
msgid "Find:"
-msgstr ""
+msgstr "तलाशिये:"
#: editor/find_in_files.cpp
msgid "Folder:"
-msgstr ""
+msgstr "फ़ोलà¥à¤¡à¤°:"
#: editor/find_in_files.cpp
msgid "Filters:"
-msgstr ""
+msgstr "फिलà¥à¤Ÿà¤°:"
#: editor/find_in_files.cpp
msgid ""
"Include the files with the following extensions. Add or remove them in "
"ProjectSettings."
msgstr ""
+"निमà¥à¤¨à¤²à¤¿à¤–ित à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤‚शन कि फ़ाइले शामिल कि गई है. इनà¥à¤¹à¥‡ पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸ मे डालिये या निकालिये."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find..."
-msgstr ""
+msgstr "तलाशिये..."
#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
msgid "Replace..."
-msgstr ""
+msgstr "बदली करे..."
#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
msgid "Cancel"
-msgstr ""
+msgstr "रदà¥à¤¦ करें"
#: editor/find_in_files.cpp
msgid "Find: "
-msgstr ""
+msgstr "तलाशिये: "
#: editor/find_in_files.cpp
msgid "Replace: "
-msgstr ""
+msgstr "बदली करे: "
#: editor/find_in_files.cpp
msgid "Replace all (no undo)"
-msgstr ""
+msgstr "सभी बदली करे (इसे अंडू नहीं किया जा सकता है)"
#: editor/find_in_files.cpp
msgid "Searching..."
msgstr "खोज..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr ""
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d मिल गया।"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d मिल गया।"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d मिल गया।"
#: editor/groups_editor.cpp
msgid "Add to Group"
-msgstr ""
+msgstr "गà¥à¤°à¥à¤ª मे à¤à¤¡ करे"
#: editor/groups_editor.cpp
msgid "Remove from Group"
-msgstr ""
+msgstr "गà¥à¤°à¥à¤ª मे से निकालिये"
#: editor/groups_editor.cpp
msgid "Group name already exists."
-msgstr ""
+msgstr "गà¥à¤°à¥à¤ª इस नाम से पहले से मौजूद."
#: editor/groups_editor.cpp
msgid "Invalid group name."
@@ -3896,24 +3927,24 @@ msgstr "गà¥à¤°à¥à¤ª डिलीट करें"
#: editor/groups_editor.cpp editor/node_dock.cpp
msgid "Groups"
-msgstr ""
+msgstr "अनेक गà¥à¤°à¥à¤ª"
#: editor/groups_editor.cpp
msgid "Nodes Not in Group"
-msgstr ""
+msgstr "नोड गà¥à¤°à¥à¤ª मे नहीं"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
#: editor/scene_tree_editor.cpp
msgid "Filter nodes"
-msgstr ""
+msgstr "नोड फिलà¥à¤Ÿà¤° किजिये"
#: editor/groups_editor.cpp
msgid "Nodes in Group"
-msgstr ""
+msgstr "गà¥à¤°à¥à¤ª मे से नोड"
#: editor/groups_editor.cpp
msgid "Empty groups will be automatically removed."
-msgstr ""
+msgstr "खाली गà¥à¤°à¥à¤ª अपनेआप निकाले जायेंगे."
#: editor/groups_editor.cpp
msgid "Group Editor"
@@ -3921,72 +3952,72 @@ msgstr "समूह संपादक"
#: editor/groups_editor.cpp
msgid "Manage Groups"
-msgstr ""
+msgstr "गà¥à¤°à¥à¤ª वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾à¤ªà¤¨ कीजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Single Scene"
-msgstr ""
+msgstr "अकेले सीन कि तरह इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Animations"
-msgstr ""
+msgstr "अलग अलग अâ€à¥…निमेशन के साथ इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Materials"
-msgstr ""
+msgstr "अलग अलग मटेरियल के साथ इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects"
-msgstr ""
+msgstr "अलग अलग ओबà¥à¤œà¥‡à¤•à¥à¤Ÿ के साथ इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects+Materials"
-msgstr ""
+msgstr "अलग अलग ओबà¥à¤œà¥‡à¤•à¥à¤Ÿ+मटेरियल के साथ इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects+Animations"
-msgstr ""
+msgstr "अलग अलग ओबà¥à¤œà¥‡à¤•à¥à¤Ÿ+अâ€à¥…निमेशन के साथ इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Materials+Animations"
-msgstr ""
+msgstr "अलग अलग मटेरियल+अâ€à¥…निमेशन के साथ इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects+Materials+Animations"
-msgstr ""
+msgstr "अलग अलग ओबà¥à¤œà¥‡à¤•à¥à¤Ÿ+मटेरियल+अâ€à¥…निमेशन के साथ इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Multiple Scenes"
-msgstr ""
+msgstr "अनेक सीन के रà¥à¤ª इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Multiple Scenes+Materials"
-msgstr ""
+msgstr "अनेक सीन+मटेरियल के रà¥à¤ª इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Import Scene"
-msgstr ""
+msgstr "सीन इंपोरà¥à¤Ÿ किजिये"
#: editor/import/resource_importer_scene.cpp
msgid "Importing Scene..."
-msgstr ""
+msgstr "सीन इंपोरà¥à¤Ÿ कर रहा है..."
#: editor/import/resource_importer_scene.cpp
msgid "Generating Lightmaps"
-msgstr ""
+msgstr "लाईटमॅप बना रहा है"
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
-msgstr ""
+msgstr "मेश के लिये बना रहा है: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
-msgstr ""
+msgstr "कसà¥à¤Ÿà¤® सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ चला रहा है..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
-msgstr ""
+msgstr "इंपोरà¥à¤Ÿ-पशà¥à¤šà¤¾à¤¤ कि सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं लोड कर पाय:"
#: editor/import/resource_importer_scene.cpp
msgid "Invalid/broken script for post-import (check console):"
@@ -4004,6 +4035,21 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "आयात करने के लिठनोड (à¤à¤¸) का चयन करें"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "इंपोरà¥à¤Ÿ"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤• लोड कीजिये"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4951,7 +4997,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5055,7 +5101,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5086,8 +5131,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5101,9 +5145,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ फ़ाइल का चयन करें"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6164,6 +6228,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6224,10 +6293,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6822,6 +6887,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "ढूंढें"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6873,16 +6946,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6979,8 +7042,8 @@ msgstr "à¤à¤• नया बनाà¤à¤‚"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7203,6 +7266,11 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "आकार: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8458,10 +8526,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8523,10 +8587,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9471,7 +9531,7 @@ msgstr ""
#: editor/project_export.cpp
msgid "Features"
-msgstr ""
+msgstr "सà¥à¤µà¤¿à¤§à¤¾à¤à¤‚"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -9801,6 +9861,11 @@ msgid "Projects"
msgstr "परियोजना के संसà¥à¤¥à¤¾à¤ªà¤•"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "दरà¥à¤ªà¤£ को पà¥à¤¨à¤ƒ पà¥à¤°à¤¾à¤ªà¥à¤¤ करना, कृपया पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करें ..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10163,6 +10228,11 @@ msgstr ""
msgid "Plugins"
msgstr "पà¥à¤²à¤—इनà¥à¤¸"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤• लोड कीजिये"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10408,6 +10478,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "नई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ"
@@ -10534,6 +10613,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11339,6 +11423,36 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "निरà¥à¤¦à¥‡à¤¶à¥‹à¤‚"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "लाईटमॅप बना रहा है"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11848,11 +11962,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11864,11 +11980,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11876,9 +11992,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12110,6 +12236,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12276,27 +12410,29 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "लाईटमॅप बना रहा है"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "लाईटमॅप बना रहा है"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12356,14 +12492,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12571,6 +12706,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "मानà¥à¤¯ à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤¨à¤¶à¤¨ इसà¥à¤¤à¥‡à¤®à¤¾à¤² कीजिये."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12612,6 +12755,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "गलत फॉणà¥à¤Ÿ का आकार |"
@@ -12642,6 +12791,12 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No"
+#~ msgstr "नहीं"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "इस सीन को कभी नहीं बचाया गया। दौड़ने से पहले सहेजें?"
+
#~ msgid "Error trying to save layout!"
#~ msgstr "लेआउट को बचाने की कोशिश कर रहा तà¥à¤°à¥à¤Ÿà¤¿!"
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index c762ff0562..047363db63 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -1,6 +1,6 @@
# Croatian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Unlimited Creativity <marinosah1@gmail.com>, 2019.
# Patik <patrikfs5@gmail.com>, 2019.
@@ -631,7 +631,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopiraj"
@@ -1812,8 +1812,8 @@ msgid "Open a File or Directory"
msgstr "Otvori datoteku ili direktorij"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Spremi"
@@ -1904,10 +1904,6 @@ msgstr "Pregled:"
msgid "File:"
msgstr "Datoteka:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Nastavak mora biti ispravan."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2311,6 +2307,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2354,18 +2354,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2413,6 +2401,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2455,7 +2447,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2845,14 +2837,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3006,6 +2990,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3208,7 +3208,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3745,8 +3745,19 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr ""
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d pojavljivanja."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d pojavljivanja."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d pojavljivanja."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -3882,6 +3893,21 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Odaberi Sve/Ništa"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Uvoz"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "UÄitaj Zadano"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Fajlovi"
@@ -4829,7 +4855,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4933,7 +4959,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4964,8 +4989,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4979,9 +5003,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6037,6 +6080,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6097,10 +6144,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6682,6 +6725,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6733,16 +6784,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6835,8 +6876,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7057,6 +7098,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8272,10 +8317,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8338,10 +8379,6 @@ msgid "Stage All"
msgstr "Zamijeni sve"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Promijeni"
@@ -9598,6 +9635,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9958,6 +9999,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "UÄitaj Zadano"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10201,6 +10247,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Brisati odabrani kljuÄ/odabrane kljuÄeve"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Odspoji Skriptu"
@@ -10321,6 +10376,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11107,6 +11166,35 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Direkcije"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11608,11 +11696,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11624,11 +11714,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11636,9 +11726,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11863,6 +11963,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12029,27 +12137,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12109,14 +12217,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12322,6 +12429,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Nastavak mora biti ispravan."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12363,6 +12478,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index bd67e49dfd..3966959f91 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -1,6 +1,6 @@
# Hungarian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Ãrpád Horváth <horvatha4@googlemail.com>, 2018.
# Nagy Lajos <neutron9707@gmail.com>, 2017.
@@ -14,12 +14,13 @@
# cefrebevalo <szmarci711@gmail.com>, 2020.
# thekeymethod <csokan.andras87@protonmail.ch>, 2020.
# Czmorek Dávid <czmdav.soft@gmail.com>, 2020.
+# Újvári Marcell <mmarci72@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-07 08:11+0000\n"
-"Last-Translator: Czmorek Dávid <czmdav.soft@gmail.com>\n"
+"PO-Revision-Date: 2021-01-22 10:21+0000\n"
+"Last-Translator: Újvári Marcell <mmarci72@gmail.com>\n"
"Language-Team: Hungarian <https://hosted.weblate.org/projects/godot-engine/"
"godot/hu/>\n"
"Language: hu\n"
@@ -27,7 +28,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -662,7 +663,7 @@ msgstr "Másolandó nyomvonalak kiválasztása"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Másolás"
@@ -738,10 +739,9 @@ msgstr "Csak a kijelölés"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
msgid "Standard"
-msgstr ""
+msgstr "Alapértelmezett"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Scripts Panel"
msgstr "Szkript panel váltása"
@@ -1855,8 +1855,8 @@ msgid "Open a File or Directory"
msgstr "Fájl vagy Könyvtár Megnyitása"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Mentés"
@@ -1948,10 +1948,6 @@ msgstr "Előnézet:"
msgid "File:"
msgstr "Fájl:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Használjon érvényes kiterjesztést."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Források Vizsgálata"
@@ -2385,6 +2381,10 @@ msgid "There is no defined scene to run."
msgstr "Nincs meghatározva Scene a futtatáshoz."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Az alprocesszt nem lehetett elindítani!"
@@ -2428,18 +2428,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr "Scene mentés másként..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nem"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Igen"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Ez a Scene még soha nem volt mentve. Menti futtatás előtt?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Ezt a műveletet nem lehet végrehajtani egy Scene nélkül."
@@ -2489,6 +2477,10 @@ msgid "Quit"
msgstr "Kilépés"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Igen"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Kilép a szerkesztőből?"
@@ -2538,7 +2530,8 @@ msgstr ""
"megbukott."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"Nem található szkript mező az addon pluginnak a következő helyen: 'res://"
"addons/%s'."
@@ -2978,14 +2971,6 @@ msgid "Help"
msgstr "Súgó"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Keresés"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentáció"
@@ -3141,6 +3126,25 @@ msgid "Open & Run a Script"
msgstr "Szkriptet Megnyit és Futtat"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"A alábbi fájlok újabbak a lemezen.\n"
+"Mit szeretne lépni?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Újratöltés"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Újramentés"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Új Örökölt"
@@ -3343,7 +3347,7 @@ msgstr "Egyedivé tétel"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Beillesztés"
@@ -3894,8 +3898,19 @@ msgid "Searching..."
msgstr "Keresés…"
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "A keresés kész"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d egyezés."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d egyezés."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d egyezés."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4032,6 +4047,21 @@ msgstr ""
msgid "Saving..."
msgstr "Mentés..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Kiválasztó Mód"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importálás"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Alapértelmezett Betöltése"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d fájl"
@@ -4990,7 +5020,8 @@ msgid "Got:"
msgstr "Kapott:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "sha256 hash ellenőrzés megbukott"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5094,7 +5125,6 @@ msgid "Sort:"
msgstr "Rendezés:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategória:"
@@ -5123,10 +5153,10 @@ msgid "Assets ZIP File"
msgstr "Eszköz ZIP Fájl"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Nem lehet megállapítani mentési útvonalat a fénytérképeknek.\n"
"Mentse el a jelenetét (hogy aztán a képek ugyanabba a mappába legyenek "
@@ -5149,9 +5179,29 @@ msgstr ""
"írható."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Fény Besütése"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Válasszon sablonfájlt"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6229,6 +6279,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Csak egy ParticlesMaterial feldolgozó anyagba állíthat pontot"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Konvertálás CPU-részecskékké"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Generálási Idő (mp):"
@@ -6289,10 +6344,6 @@ msgstr "AABB Generálása"
msgid "Generate Visibility AABB"
msgstr "Láthatósági AABB Generálása"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "AABB Generálása"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Pont Eltávolítása Görbéről"
@@ -6880,6 +6931,14 @@ msgstr "Dokumentációs Lapok Bezárása"
msgid "Run"
msgstr "Futtatás"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Keresés"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Belépés"
@@ -6933,16 +6992,6 @@ msgstr ""
"A alábbi fájlok újabbak a lemezen.\n"
"Mit szeretne lépni?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Újratöltés"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Újramentés"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Hibakereső"
@@ -7035,8 +7084,8 @@ msgstr "Töréspontok"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Kivágás"
@@ -7223,7 +7272,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Z-Axis Transform."
-msgstr ""
+msgstr "Z-Tengely transzformáció"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Plane Transform."
@@ -7258,6 +7307,11 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Méret: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Rajzolt objektumok"
@@ -8480,10 +8534,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8540,10 +8590,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9815,6 +9861,11 @@ msgid "Projects"
msgstr "Projektek"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Tükrök letöltése, kérjük várjon..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10178,6 +10229,11 @@ msgstr ""
msgid "Plugins"
msgstr "Bővítmények"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Alapértelmezett Betöltése"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Beépített Beállítások..."
@@ -10422,6 +10478,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Node-ok beillesztése"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Szkript leválasztása"
@@ -10542,6 +10607,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Node-ok kivágása"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11331,6 +11401,39 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "AABB Generálása"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Irányok"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "Behúzás Jobbra"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Kifejezés beállítása"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Fénytérképek Létrehozása"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11832,11 +11935,13 @@ msgid "Select device from the list"
msgstr "Válasszon készüléket a listából"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11848,11 +11953,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11860,9 +11965,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12091,6 +12206,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12257,28 +12380,33 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr ""
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "Geometria Elemzése…"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr ""
+#, fuzzy
+msgid "Preparing environment"
+msgstr "Geometria Elemzése…"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "Fénytérképek Létrehozása"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Fénytérképek Létrehozása"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr ""
+#, fuzzy
+msgid "Done"
+msgstr "Kész!"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12337,14 +12465,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12550,6 +12677,15 @@ msgstr "Figyelem!"
msgid "Please Confirm..."
msgstr "Kérjük erősítse meg..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Használjon érvényes kiterjesztést."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "Illesztés Engedélyezése"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12595,6 +12731,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Érvénytelen forrás az előnézethez."
@@ -12623,6 +12765,15 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No"
+#~ msgstr "Nem"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Ez a Scene még soha nem volt mentve. Menti futtatás előtt?"
+
+#~ msgid "Search complete"
+#~ msgstr "A keresés kész"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Ezen a helyen már van azonos nevű fájl vagy mappa."
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 1e88404be4..5dc5b9751a 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -1,6 +1,6 @@
# Indonesian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Abdul Aziz Muslim Alqudsy <abdul.aziz.muslim.alqudsy@gmail.com>, 2016.
# Andevid Dynmyn <doyan4forum@gmail.com>, 2016.
@@ -28,12 +28,13 @@
# Richard Urban <redasuio1@gmail.com>, 2020.
# yusuf afandi <afandi.yusuf.04@gmail.com>, 2020.
# Habib Rohman <revolusi147id@gmail.com>, 2020.
+# Hanz <hanzhaxors@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-13 22:59+0000\n"
-"Last-Translator: Habib Rohman <revolusi147id@gmail.com>\n"
+"PO-Revision-Date: 2021-03-08 15:33+0000\n"
+"Last-Translator: Hanz <hanzhaxors@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -41,7 +42,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -57,7 +58,8 @@ msgstr "String dengan panjang 1 (karakter) yang diharapkan."
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr "Tidak cukup bytes untuk mendekode bytes, atau format tidak valid."
+msgstr ""
+"Tidak cukup bytes untuk merubah bytes ke nilai asal, atau format tidak valid."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -65,8 +67,7 @@ msgstr "Masukkan tidak sah %i (tidak diberikan) dalam ekspresi"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr ""
-"self tidak dapat digunakan karena tidak memiliki instance (tidak lolos)"
+msgstr "self tidak dapat digunakan karena instance adalah null"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -74,7 +75,7 @@ msgstr "operan salah untuk operator %s, %s dan %s."
#: core/math/expression.cpp
msgid "Invalid index of type %s for base type %s"
-msgstr "Tipe index %s tidak valid untuk tipe dasar %s"
+msgstr "Tipe indeks %s tidak valid untuk tipe dasar %s"
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
@@ -671,7 +672,7 @@ msgstr "Pilih Trek untuk Disalin"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopy"
@@ -1052,14 +1053,14 @@ msgid "Owners Of:"
msgstr "Pemilik Dari:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "Hapus berkas yang dipilih dari proyek? (tidak bisa dibatalkan)"
+msgstr ""
+"Hapus berkas yang dipilih dari proyek? (tidak bisa dibatalkan)\n"
+"Anda bisa menemukan berkas yang telah dihapus di tong sampah."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
@@ -1068,7 +1069,8 @@ msgid ""
msgstr ""
"File-file yang telah dihapus diperlukan oleh resource lain agar mereka dapat "
"bekerja.\n"
-"Hapus saja? (tidak bisa dibatalkan/undo)"
+"Hapus saja? (tidak bisa dibatalkan)\n"
+"Anda bisa menemukan berkas yang telah dihapus di tong sampah."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1621,34 +1623,31 @@ msgstr ""
"Enabled'."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'PVRTC' texture compression for GLES2. Enable "
"'Import Pvrtc' in Project Settings."
msgstr ""
-"Platform target membutuhkan kompresi tekstur 'ETC' untuk GLES2. Aktifkan "
-"'Impor Lainnya' di Pengaturan Proyek."
+"Platform target membutuhkan kompresi tekstur 'PVRTC' untuk GLES2. Aktifkan "
+"'Impor Pvrtc' di Pengaturan Proyek."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
msgstr ""
-"Platform target membutuhkan kompresi tekstur 'ETC2' untuk GLES3. Aktifkan "
-"'Impor Lainnya 2' di Pengaturan Proyek."
+"Platform target membutuhkan kompresi tekstur 'ETC2' atau 'PVRTC' untuk "
+"GLES3. Aktifkan 'Impor Lainnya 2' atau 'Import Pvrtc' di Pengaturan Proyek."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'PVRTC' texture compression for the driver fallback "
"to GLES2.\n"
"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
-"Platform target membutuhkan kompressi tekstur 'ETC' untuk mengembalikan "
+"Platform target membutuhkan kompressi tekstur 'PVRTC' untuk mengembalikan "
"driver ke GLES2. \n"
-"Aktifkan 'Impor Lainnya' di Pengaturan Proyek, atau matikan 'Driver Fallback "
+"Aktifkan 'Impor Pvrtc' di Pengaturan Proyek, atau matikan 'Driver Fallback "
"Enabled'."
#: editor/editor_export.cpp platform/android/export/export.cpp
@@ -1877,8 +1876,8 @@ msgid "Open a File or Directory"
msgstr "Buka sebuah File atau Direktori"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Simpan"
@@ -1969,10 +1968,6 @@ msgstr "Pratinjau:"
msgid "File:"
msgstr "File:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Harus menggunakan ekstensi yang sah."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Sumber Pemindaian"
@@ -2334,6 +2329,8 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"Terjadi kesalahan ketika mencoba menyimpan layout editor.\n"
+"Pastikan jalur data pengguna editor dapat ditulis."
#: editor/editor_node.cpp
msgid ""
@@ -2341,13 +2338,15 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"Penataan editor default telah dirubah.\n"
+"Untuk mengembalikan penataan editor default ke asalnya, gunakan opsi Hapus "
+"Penataan dan hapus Penataan Default."
#: editor/editor_node.cpp
msgid "Layout name not found!"
msgstr "Nama layout tidak ditemukan!"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Restored the Default layout to its base settings."
msgstr "Mengembalikan semula layout default ke pengaturan-pengaturan awal."
@@ -2405,6 +2404,10 @@ msgid "There is no defined scene to run."
msgstr "Tidak ada skena yang didefinisikan untuk dijalankan."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Simpan skena sebelum menjalankan..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Tidak dapat memulai subproses!"
@@ -2448,18 +2451,6 @@ msgstr "Node akar diperlukan untuk menyimpan skena."
msgid "Save Scene As..."
msgstr "Simpan Skena Sebagai..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Tidak"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Ya"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Skena ini belum pernah disimpan. Simpan sebelum menjalankan?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Operasi ini tidak dapat diselesaikan tanpa skena."
@@ -2493,7 +2484,6 @@ msgid "Reload Saved Scene"
msgstr "Muat ulang scene yang sudah disimpan"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
@@ -2510,6 +2500,10 @@ msgid "Quit"
msgstr "Keluar"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Ya"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Keluar editor?"
@@ -2556,9 +2550,9 @@ msgstr ""
"gagal."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
-"Tidak dapat mencari bidang script untuk addon plugin pada: 'res://addons/%s'."
+"Tidak dapat mencari bidang skrip untuk addon plugin pada: 'res://addons/%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2862,12 +2856,10 @@ msgstr ""
"lokal."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Small Deploy with Network Filesystem"
-msgstr "Deploy Kecil dengan Jaringan FS"
+msgstr "Deploy Kecil dengan Jaringan Berkas"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, using one-click deploy for Android will only "
"export an executable without the project data.\n"
@@ -2876,9 +2868,9 @@ msgid ""
"On Android, deploying will use the USB cable for faster performance. This "
"option speeds up testing for projects with large assets."
msgstr ""
-"Ketika opsi ini aktif, ekspor atau deploy akan menghasilkan minimal "
-"executable.\n"
-"Berkas sistem akan tersedia dari proyek dari editor melalui jaringan.\n"
+"Ketika opsi ini aktif, menggunakan 'one-click deploy' hanya akan mengekspor "
+"executable tanpa data proyek.\n"
+"Berkas sistem akan tersedia dari proyek oleh editor melalui jaringan.\n"
"Pada Android, deploy akan menggunakan kabel USB untuk performa yang lebih "
"cepat. Opsi ini mempercepat pengujian dengan jejak kaki yang besar."
@@ -2887,34 +2879,29 @@ msgid "Visible Collision Shapes"
msgstr "Collision Shapes Terlihat"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, collision shapes and raycast nodes (for 2D and "
"3D) will be visible in the running project."
msgstr ""
"Collision shapes dan raycast nodes (untuk 2D dan 3D) akan terlihat pada saat "
-"permainan berjalan jika opsi ini aktif."
+"proyek berjalan jika opsi ini aktif."
#: editor/editor_node.cpp
msgid "Visible Navigation"
msgstr "Navigasi Terlihat"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, navigation meshes and polygons will be visible "
"in the running project."
msgstr ""
-"Navigasi meshes dan poligon akan terlihat saat game berjalan jika opsi ini "
-"aktif."
+"Navigasi dan poligon akan terlihat saat game berjalan jika opsi ini aktif."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Synchronize Scene Changes"
msgstr "Sinkronkan Perubahan Skena"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, any changes made to the scene in the editor "
"will be replicated in the running project.\n"
@@ -2922,17 +2909,15 @@ msgid ""
"filesystem option is enabled."
msgstr ""
"Ketika opsi ini aktif, perubahan yang dibuat pada skena melalui editor akan "
-"direplika pada gim yang sedang berjalan.\n"
+"direplika pada proyek yang sedang berjalan.\n"
"Ketika penggunaan remote pada sebuah perangkat, akan lebih efisien dengan "
-"berkas sistem jaringan."
+"opsi berkas sistem jaringan."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Synchronize Script Changes"
-msgstr "Sinkronkan Perubahan Script"
+msgstr "Sinkronkan Perubahan skrip"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, any script that is saved will be reloaded in "
"the running project.\n"
@@ -2941,8 +2926,8 @@ msgid ""
msgstr ""
"Ketika opsi ini aktif, perubahan script yang tersimpan akan di muat kembali "
"pada permainan yang sedang berjalan.\n"
-"Ketika penggunaan remote pada sebuah perngakat, akan lebih efisien jika "
-"jaringan filesystem."
+"Ketika penggunaan remote pada sebuah perangakat, akan lebih efisien dengan "
+"opsi jaringan berkas-berkas."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
@@ -2997,14 +2982,6 @@ msgid "Help"
msgstr "Bantuan"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Cari"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentasi"
@@ -3169,6 +3146,24 @@ msgid "Open & Run a Script"
msgstr "Buka & Jalankan Skrip"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Berkas berikut lebih baru dalam disk.\n"
+"Aksi apa yang ingin diambil?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Muat Ulang"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Simpan Ulang"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Turunan Baru"
@@ -3380,7 +3375,7 @@ msgstr "Jadikan Unik"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Tempel"
@@ -3418,7 +3413,6 @@ msgid "Add Key/Value Pair"
msgstr "Tambahkan pasangan Key/Value"
#: editor/editor_run_native.cpp
-#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
"Please add a runnable preset in the Export menu or define an existing preset "
@@ -3452,11 +3446,10 @@ msgid "Did you forget the '_run' method?"
msgstr "Apakah anda lupa dengan fungsi '_run' ?"
#: editor/editor_spin_slider.cpp
-#, fuzzy
msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes."
msgstr ""
-"Tahan Ctrl untuk meletakkan Getter. Tahan Shift untuk meletakkan generic "
-"signature."
+"Tahan Ctrl untuk membulatkan bilangan. Tahan Shift untuk meletakkan bilangan "
+"yang lebih presisi."
#: editor/editor_sub_scene.cpp
msgid "Select Node(s) to Import"
@@ -3740,6 +3733,11 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"file dan/atau berkas-berkas berikut mempunyai konflik di '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Apakah Anda ingin melanjutkan (overwrite)?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3771,7 +3769,7 @@ msgstr "Buka Skena"
#: editor/filesystem_dock.cpp
msgid "Instance"
-msgstr "Instansi"
+msgstr "hal"
#: editor/filesystem_dock.cpp
msgid "Add to Favorites"
@@ -3820,9 +3818,8 @@ msgid "Duplicate..."
msgstr "Gandakan..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Move to Trash"
-msgstr "Pindahkan Autoload"
+msgstr "Pindahkan ke tong sampah"
#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Rename..."
@@ -3933,8 +3930,17 @@ msgid "Searching..."
msgstr "Mencari..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Pencarian selesai"
+msgid "%d match in %d file."
+msgstr "Ditemukan %d kecocokan."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "Ditemukan %d kecocokan."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Ditemukan %d kecocokan."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4070,6 +4076,21 @@ msgstr ""
msgid "Saving..."
msgstr "Menyimpan..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Mode Seleksi"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Impor"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Muat Default"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Berkas"
@@ -5033,7 +5054,8 @@ msgid "Got:"
msgstr "Yang Didapat:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Gagal mengecek hash sha256"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5137,7 +5159,6 @@ msgid "Sort:"
msgstr "Sortir:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategori:"
@@ -5166,10 +5187,10 @@ msgid "Assets ZIP File"
msgstr "Berkas Aset ZIP"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Tidak dapat menentukan lokasi penyimpanan untuk gambar lightmap.\n"
"Simpan skena Anda (untuk gambar yang akan disimpan di direktori yang sama), "
@@ -5188,9 +5209,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "Gagal membuat gambar lightmap, pastikan path dapat ditulis."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Panggang Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Pilih berkas templat"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6294,6 +6335,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Hanya dapat mengatur titik ke dalam material proses ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Konversikan menjadi CPUParticles"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Waktu Pembuatan (detik):"
@@ -6354,10 +6400,6 @@ msgstr "Membuat AABB"
msgid "Generate Visibility AABB"
msgstr "Buat Penampakan AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Buat AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Hapus Titik dari Kurva"
@@ -6951,6 +6993,14 @@ msgstr "Tutup Dokumentasi"
msgid "Run"
msgstr "Jalankan"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Cari"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Masuki"
@@ -7004,16 +7054,6 @@ msgstr ""
"Berkas berikut lebih baru dalam diska.\n"
"Aksi apa yang ingin diambil?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Muat Ulang"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Simpan Ulang"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Pengawakutu"
@@ -7111,8 +7151,8 @@ msgstr "Breakpoint"
msgid "Go To"
msgstr "Pergi Ke"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Potong"
@@ -7336,6 +7376,11 @@ msgid "Yaw"
msgstr "Oleng"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Ukuran: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objek Digambar"
@@ -8583,10 +8628,6 @@ msgid "Error"
msgstr "Galat"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Tidak ada pesan komit yang diberikan"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Tidak ada berkas yang ditambahkan ke staging"
@@ -8643,10 +8684,6 @@ msgid "Stage All"
msgstr "Stage Semua"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Tambahkan pesan komit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Komit Perubahan"
@@ -10037,6 +10074,11 @@ msgid "Projects"
msgstr "Proyek"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Mendapatkan informasi cermin, silakan tunggu..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Terakhir Diubah"
@@ -10407,6 +10449,11 @@ msgstr "Muat Otomatis"
msgid "Plugins"
msgstr "Pengaya"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Muat Default"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Prasetel..."
@@ -10662,6 +10709,16 @@ msgstr "Instansi Skena Anak"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Tidak dapat bekerja pada node dari skena luar!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Rekatkan Node"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Detach Script"
msgstr "Lampirkan Skrip"
@@ -10792,6 +10849,11 @@ msgid "Attach Script"
msgstr "Lampirkan Skrip"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Potong Node"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Hapus Node"
@@ -11600,6 +11662,39 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
"Berikan resource MeshLibrary ke GridMap ini untuk menggunakan mesh-nya."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "Buat AABB"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Arah"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "Indentasi Kanan"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Pasca Proses"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Plotting Lights:"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Nama kelas tidak boleh reserved keyword"
@@ -12113,12 +12208,16 @@ msgid "Select device from the list"
msgstr "Pilih perangkat pada daftar"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Lokasi executable ADB belum dikonfigurasi dalam Pengaturan Editor."
+msgid "Unable to find the 'apksigner' tool."
+msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "Lokasi jarsigner OpenJDK belum dikonfigurasi dalam Pengaturan Editor."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Templat build Android belum terpasang dalam proyek. Pasanglah dari menu "
+"Proyek."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12134,13 +12233,15 @@ msgstr ""
"prasetel proyek."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#, fuzzy
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"Membangun kustom APK memerlukan lokasi Android SDK yang valid dalam "
-"Pengaturan Editor."
+"Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan "
+"Editor."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+#, fuzzy
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
"Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan "
"Editor."
@@ -12150,12 +12251,23 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+#, fuzzy
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan "
+"Editor."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
-"Templat build Android belum terpasang dalam proyek. Pasanglah dari menu "
-"Proyek."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12402,6 +12514,14 @@ msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
"Sebuah CollisionPolygon2D yang kosong tidak memiliki efek pada collision."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12615,29 +12735,33 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin membutuhkan node anak ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Waktu tersisa: %d:%02d s)"
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "Mengurai Geometri..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Plotting Meshes: "
+#, fuzzy
+msgid "Preparing environment"
+msgstr "Tampilkan Lingkungan"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Plotting Lights:"
+#, fuzzy
+msgid "Generating capture"
+msgstr "Membuat Pemetaan Cahaya"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Menyelesaikan Pemetaan"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Membuat Pemetaan Cahaya"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "Lighting Meshes: "
-msgstr "Lighting Meshes: "
+msgid "Done"
+msgstr "Selesai!"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12707,6 +12831,10 @@ msgid "Plotting Meshes"
msgstr "Memetakan Mesh"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Menyelesaikan Pemetaan"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12714,11 +12842,6 @@ msgstr ""
"GIProbes tidak didukung oleh driver video GLES2.\n"
"Gunakan BakedLightmap sebagai gantinya."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12954,6 +13077,15 @@ msgstr "Peringatan!"
msgid "Please Confirm..."
msgstr "Mohon konfirmasi..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Harus menggunakan ekstensi yang sah."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "Aktifkan Pengancingan"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13011,6 +13143,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "Ukuran viewport harus lebih besar dari 0 untuk me-render apa pun."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Sumber tidak sah untuk pratinjau."
@@ -13038,6 +13176,46 @@ msgstr "Variasi hanya bisa ditetapkan dalam fungsi vertex."
msgid "Constants cannot be modified."
msgstr "Konstanta tidak dapat dimodifikasi."
+#~ msgid "No"
+#~ msgstr "Tidak"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Skena ini belum pernah disimpan. Simpan sebelum menjalankan?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "Lokasi executable ADB belum dikonfigurasi dalam Pengaturan Editor."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr ""
+#~ "Lokasi jarsigner OpenJDK belum dikonfigurasi dalam Pengaturan Editor."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Membangun kustom APK memerlukan lokasi Android SDK yang valid dalam "
+#~ "Pengaturan Editor."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Waktu tersisa: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Plotting Meshes: "
+
+#, fuzzy
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Lighting Meshes: "
+
+#~ msgid "Search complete"
+#~ msgstr "Pencarian selesai"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Tidak ada pesan komit yang diberikan"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Tambahkan pesan komit"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Sudah ada nama berkas atau folder seperti itu di lokasi ini."
diff --git a/editor/translations/is.po b/editor/translations/is.po
index e6f66312bc..8d36556c04 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -1,6 +1,6 @@
# Icelandic translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Jóhannes G. Þorsteinsson <johannesg@johannesg.com>, 2017, 2018, 2020.
# Kaan Gül <qaantum@hotmail.com>, 2018.
@@ -659,7 +659,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1835,8 +1835,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1927,10 +1927,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2335,6 +2331,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2378,18 +2378,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2437,6 +2425,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2480,7 +2472,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2873,14 +2865,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3035,6 +3019,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3238,7 +3238,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3776,7 +3776,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3915,6 +3923,19 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Afrita val"
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4876,7 +4897,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4980,7 +5001,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5011,8 +5031,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5026,9 +5045,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6095,6 +6133,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6155,10 +6197,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6745,6 +6783,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6796,16 +6842,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6898,8 +6934,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7121,6 +7157,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8361,10 +8401,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8424,10 +8460,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9693,6 +9725,10 @@ msgid "Projects"
msgstr "Verkefna Stjóri"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10055,6 +10091,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10299,6 +10339,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Tvíteknir lyklar"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10423,6 +10472,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Tvíteknir lyklar"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11212,6 +11266,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11717,11 +11799,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11733,11 +11817,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11745,9 +11829,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11972,6 +12066,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12138,27 +12240,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12218,14 +12320,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12431,6 +12532,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12472,6 +12581,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 8eefe1b29d..1d399091c3 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -1,6 +1,6 @@
# Italian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Alessio Corridori <alessiocorridori@hotmail.com>, 2018.
# Dario Bonfanti <bonfi.96@hotmail.it>, 2016-2017.
@@ -36,7 +36,7 @@
# Davide Giuliano <davidegiuliano00@gmail.com>, 2019.
# Stefano Merazzi <asso99@hotmail.com>, 2019.
# Sinapse X <sinapsex13@gmail.com>, 2019.
-# Micila Micillotto <micillotto@gmail.com>, 2019, 2020.
+# Micila Micillotto <micillotto@gmail.com>, 2019, 2020, 2021.
# Mirko Soppelsa <miknsop@gmail.com>, 2019, 2020.
# No <kingofwizards.kw7@gmail.com>, 2019.
# StarFang208 <polaritymanx@yahoo.it>, 2019.
@@ -52,15 +52,16 @@
# Anonymous <noreply@weblate.org>, 2020.
# riccardo boffelli <riccardo.boffelli.96@gmail.com>, 2020.
# Lorenzo Asolan <brixiumx@gmail.com>, 2020.
-# Lorenzo Cerqua <lorenzocerqua@tutanota.com>, 2020.
+# Lorenzo Cerqua <lorenzocerqua@tutanota.com>, 2020, 2021.
# Federico Manzella <ferdiu.manzella@gmail.com>, 2020.
# Ziv D <wizdavid@gmail.com>, 2020.
+# Riteo Siuga <lorenzocerqua@tutanota.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-07 08:11+0000\n"
-"Last-Translator: Mirko <miknsop@gmail.com>\n"
+"PO-Revision-Date: 2021-03-07 06:04+0000\n"
+"Last-Translator: Riteo Siuga <lorenzocerqua@tutanota.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -68,12 +69,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "Tipo argomento non valido per convert(), usa le costanti TYPE_*."
+msgstr "Tipo dell'argomento di convert() non valido, usa le costanti TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -83,17 +84,15 @@ msgstr "Prevista una stringa di lunghezza 1 (un singolo carattere)."
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr ""
-"Non ci sono abbastanza byte per decodificarli, oppure il formato non è "
-"valido."
+msgstr "Byte insufficienti per decodificarli o formato non valido."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr "Input non valido %i (assente) nell'espressione"
+msgstr "Input %i non valido (assente) nell'espressione"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "self non può essere usato perché l'istanza è nulla (non passata)"
+msgstr "self non può essere utilizzato perché l'istanza è nulla (non passata)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -105,7 +104,7 @@ msgstr "Indice di tipo %s non valido per il tipo base %s"
#: core/math/expression.cpp
msgid "Invalid named index '%s' for base type %s"
-msgstr "Nome indice '%s' non valido per il tipo base %s"
+msgstr "Nome dell'indice '%s' non valido per il tipo base %s"
#: core/math/expression.cpp
msgid "Invalid arguments to construct '%s'"
@@ -145,15 +144,15 @@ msgstr "EiB"
#: editor/animation_bezier_editor.cpp
msgid "Free"
-msgstr "Libero"
+msgstr "Libere"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr "Bilanciato"
+msgstr "Bilanciate"
#: editor/animation_bezier_editor.cpp
msgid "Mirror"
-msgstr "Rifletti"
+msgstr "Specchiate"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
@@ -177,80 +176,80 @@ msgstr "Elimina le chiavi selezionate"
#: editor/animation_bezier_editor.cpp
msgid "Add Bezier Point"
-msgstr "Aggiungi Punto Bezier"
+msgstr "Inserisci un punto di controllo di Bézier"
#: editor/animation_bezier_editor.cpp
msgid "Move Bezier Points"
-msgstr "Sposta Punti Bezier"
+msgstr "Sposta dei punti di controllo di Bézier"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
-msgstr "Duplica chiavi d'animazione"
+msgstr "Duplica delle chiavi d'animazione"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Delete Keys"
-msgstr "Elimina chiavi d'animazione"
+msgstr "Elimina delle chiavi d'animazione"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Time"
-msgstr "Anim Cambia Tempo Keyframe"
+msgstr "Cambia il tempo di un fotogramma chiave"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transition"
-msgstr "Cambia transizione dell'animazione"
+msgstr "Cambia la transizione di un'animazione"
#: editor/animation_track_editor.cpp
msgid "Anim Change Transform"
-msgstr "Cambia trasformazione dell'animazione"
+msgstr "Cambia la trasformazione di un'animazione"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Value"
-msgstr "Cambia valore fotogramma chiave dell'animazione"
+msgstr "Cambia il valore del fotogramma chiave di un'animazione"
#: editor/animation_track_editor.cpp
msgid "Anim Change Call"
-msgstr "Cambia chiamata animazione"
+msgstr "Cambia la chiamata di un'animazione"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Time"
-msgstr "Anim Cambio Multiplo Tempo Keyframe"
+msgstr "Cambia il tempo di più fotogrammi chiave"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Transition"
-msgstr "Animazione Cambio Multiplo Transizione"
+msgstr "Cambia la transizione di più animazioni"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Transform"
-msgstr "Animazione Cambio Multiplo Trasformazione"
+msgstr "Cambia le trasformazioni di più animazioni"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Value"
-msgstr "Animazione Cambio Multiplo Valore Keyframe"
+msgstr "Cambia il valore di più fotogrammi chiave di un'Animazione"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Call"
-msgstr "Animazione Cambio Multiplo Chiamata"
+msgstr "Cambia la chiamata di metodo di più animazioni"
#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
-msgstr "Cambia lunghezza dell'animazione"
+msgstr "Cambia la durata dell'animazione"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr "Modifica ciclicità animazione"
+msgstr "Commuta ciclicità animazione"
#: editor/animation_track_editor.cpp
msgid "Property Track"
-msgstr "Traccia proprietà"
+msgstr "Traccia di proprietà"
#: editor/animation_track_editor.cpp
msgid "3D Transform Track"
-msgstr "Traccia trasformazione 3D"
+msgstr "Traccia di trasformazioni 3D"
#: editor/animation_track_editor.cpp
msgid "Call Method Track"
-msgstr "Traccia chiamata metodo"
+msgstr "Traccia di chiamate di metodo"
#: editor/animation_track_editor.cpp
msgid "Bezier Curve Track"
@@ -258,19 +257,19 @@ msgstr "Traccia curva di Bézier"
#: editor/animation_track_editor.cpp
msgid "Audio Playback Track"
-msgstr "Traccia Riproduzione Audio"
+msgstr "Traccia di riproduzione audio"
#: editor/animation_track_editor.cpp
msgid "Animation Playback Track"
-msgstr "Traccia di riproduzione animazione"
+msgstr "Traccia di riproduzione di animazioni"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
-msgstr "Durata animazione (fotogrammi)"
+msgstr "Durata dell'animazione (fotogrammi)"
#: editor/animation_track_editor.cpp
msgid "Animation length (seconds)"
-msgstr "Durata Animazione (secondi)"
+msgstr "Durata dell'animazione (secondi)"
#: editor/animation_track_editor.cpp
msgid "Add Track"
@@ -278,7 +277,7 @@ msgstr "Aggiungi Traccia"
#: editor/animation_track_editor.cpp
msgid "Animation Looping"
-msgstr "Ripeti Ciclicamente Animazione"
+msgstr "Ciclicità Animazione"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -295,15 +294,15 @@ msgstr "Clip Animazione:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
-msgstr "Cambia percorso traccia"
+msgstr "Cambia Percorso Traccia"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr "Attiva/disattiva la traccia."
+msgstr "Attiva/Disattiva questa traccia."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr "Modalità di aggiornamento (Come viene impostata questa proprietà)"
+msgstr "Modalità Aggiornamento (come viene impostata questa proprietà)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
@@ -311,7 +310,7 @@ msgstr "Modalità Interpolazione"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
-msgstr "Modalità Ciclo ad Anello (Interpola la fine con l'inizio del ciclo)"
+msgstr "Modalità Ciclo ad Anello (interpola la fine con l'inizio a ciclo)"
#: editor/animation_track_editor.cpp
msgid "Remove this track."
@@ -323,19 +322,19 @@ msgstr "Tempo (s): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
-msgstr "Abilita/disabilita tracce"
+msgstr "Abilita/DisabilitaTraccia"
#: editor/animation_track_editor.cpp
msgid "Continuous"
-msgstr "Continuo"
+msgstr "Continua"
#: editor/animation_track_editor.cpp
msgid "Discrete"
-msgstr "Discreto"
+msgstr "Discreta"
#: editor/animation_track_editor.cpp
msgid "Trigger"
-msgstr "Attivazione"
+msgstr "Attivatore"
#: editor/animation_track_editor.cpp
msgid "Capture"
@@ -352,52 +351,53 @@ msgstr "Lineare"
#: editor/animation_track_editor.cpp
msgid "Cubic"
-msgstr "Cubico"
+msgstr "Cubica"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
-msgstr "Blocca interpolazione ciclo"
+msgstr "Blocca Interpolazione Ciclo"
#: editor/animation_track_editor.cpp
msgid "Wrap Loop Interp"
-msgstr "Continua interpolazione ciclo"
+msgstr "Avvolgi Interpolazione Ciclo"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr "Inserisci chiave"
+msgstr "Inserisci Fotogramma Chiave"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
-msgstr "Duplica chiave(i)"
+msgstr "Duplica Fotogrammi Chiave Selezionati"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
-msgstr "Elimina chiave(i)"
+msgstr "Elimina Fotogrammi Chiave Selezionati"
#: editor/animation_track_editor.cpp
msgid "Change Animation Update Mode"
-msgstr "Cambia modalità di aggiornamento animazione"
+msgstr "Cambia Modalità Aggiornamento Animazione"
#: editor/animation_track_editor.cpp
msgid "Change Animation Interpolation Mode"
-msgstr "Cambia modalità di interpolazione animazione"
+msgstr "Cambia Modalità Interpolazione Animazione"
#: editor/animation_track_editor.cpp
msgid "Change Animation Loop Mode"
-msgstr "Cambia modalità di ciclo animazione"
+msgstr "Cambia Modalità Loop Animazione"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
-msgstr "Rimuovi traccia animazione"
+msgstr "Rimuovi una traccia d'animazione"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Create NEW track for %s and insert key?"
-msgstr "Crea NUOVA traccia per %s e inserire la chiave?"
+msgstr "Creare una NUOVA traccia per %s e inserirci la chiave?"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
-msgstr "Creare %d NUOVE tracce e inserire la chiave?"
+msgstr "Crea %d NUOVE tracce ed inserire fotogrammi chiave?"
#: editor/animation_track_editor.cpp editor/create_dialog.cpp
#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
@@ -413,23 +413,23 @@ msgstr "Crea"
#: editor/animation_track_editor.cpp
msgid "Anim Insert"
-msgstr "Inserisci Animazione"
+msgstr "Inserisci un'animazione"
#: editor/animation_track_editor.cpp
msgid "AnimationPlayer can't animate itself, only other players."
-msgstr "AnimationPlayer non può animare se stesso, solo altri nodi."
+msgstr "AnimationPlayer può solo animare altri riproduttori, non se stesso."
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
-msgstr "Crea e inserisci un'animazione"
+msgstr "Crea & Inserisci Animazione"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Track & Key"
-msgstr "Inserisci traccia e chiave animazione"
+msgstr "Inserisci Traccia e Fotogramma Chiave Animazione"
#: editor/animation_track_editor.cpp
msgid "Anim Insert Key"
-msgstr "Inserisci una chiave d'animazione"
+msgstr "Inserisci Fotogramma Chiave Animazione"
#: editor/animation_track_editor.cpp
msgid "Change Animation Step"
@@ -437,11 +437,13 @@ msgstr "Cambia passo animazione"
#: editor/animation_track_editor.cpp
msgid "Rearrange Tracks"
-msgstr "Riordina tracce"
+msgstr "Riordina delle tracce"
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr "Le tracce Transform si applicano solo a nodi di tipo Spatial."
+msgstr ""
+"Le tracce di trasformazione possono essere applicate soltanto ai nodi basati "
+"sul nodo Spatial."
#: editor/animation_track_editor.cpp
msgid ""
@@ -457,27 +459,31 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Animation tracks can only point to AnimationPlayer nodes."
-msgstr "Le tracce Animation possono puntare solo a nodi AnimationPlayer."
+msgstr ""
+"Le tracce di riproduzione di animazioni possono puntare solo a nodi di tipo "
+"AnimationPlayer."
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
-msgstr "Un AnimationPlayer non può animare se stesso, solo altri oggetti."
+msgstr ""
+"Un riproduttore di animazioni può solo animare altri riproduttori, non se "
+"stesso."
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr "Non è possibile aggiungere una nuova traccia senza un nodo root"
+msgstr "Non è possibile aggiungere una nuova traccia senza un nodo radice"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr "Traccia non valida per la curva Bézier (nessuna sottoproprietà adatta)"
+msgstr "Traccia non valida per Bezier (nessuna sotto-proprietà valida)"
#: editor/animation_track_editor.cpp
msgid "Add Bezier Track"
-msgstr "Aggiungi traccia Bézier"
+msgstr "Aggiungi una traccia di curve di Bézier"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr "Il tracciato non è valido, non è possibile aggiungere una chiave."
+msgstr "La traccia non è valida, quindi è impossibile aggiungere una chiave."
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
@@ -485,21 +491,21 @@ msgstr "La traccia non è di tipo Spatial, impossibile aggiungere la chiave"
#: editor/animation_track_editor.cpp
msgid "Add Transform Track Key"
-msgstr "Aggiungi chiave traccia Transform"
+msgstr "Aggiungi una chiave a una traccia di trasformazioni"
#: editor/animation_track_editor.cpp
msgid "Add Track Key"
-msgstr "Aggiungi chiave traccia"
+msgstr "Aggiungi una chiave a una traccia"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
msgstr ""
-"Il tracciato non è valido, non è possibile aggiungere una chiave di chiamata "
-"di funzione."
+"La traccia non è valida, quindi, non è stato possibile aggiungere una chiave "
+"chiamata metodo."
#: editor/animation_track_editor.cpp
msgid "Add Method Track Key"
-msgstr "Aggiungi chiave alla traccia metodo"
+msgstr "Aggiungi una chiave a una traccia di chiamate di metodi"
#: editor/animation_track_editor.cpp
msgid "Method not found in object: "
@@ -507,7 +513,7 @@ msgstr "Metodo non trovato nell'oggetto: "
#: editor/animation_track_editor.cpp
msgid "Anim Move Keys"
-msgstr "Sposta chiavi animazione"
+msgstr "Sposta delle chiavi d'animazione"
#: editor/animation_track_editor.cpp
msgid "Clipboard is empty"
@@ -515,18 +521,18 @@ msgstr "Gli appunti sono vuoti"
#: editor/animation_track_editor.cpp
msgid "Paste Tracks"
-msgstr "Incolla tracce"
+msgstr "Incolla Tracce"
#: editor/animation_track_editor.cpp
msgid "Anim Scale Keys"
-msgstr "Scala chiavi animazione"
+msgstr "Scala Chiavi Animazione"
#: editor/animation_track_editor.cpp
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
msgstr ""
-"Questa opzione non funziona per modificare curve di Bézier, dato che si "
-"tratta di una traccia singola."
+"Questa opzione non funziona per modificare delle curve di Bézier, dato che "
+"si tratta di una singola traccia."
#: editor/animation_track_editor.cpp
msgid ""
@@ -540,14 +546,14 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
-"Questa animazione appartiene a una scena importata, eventuali modifiche alle "
-"tracce importate non saranno salvate.\n"
+"Questa animazione appartiene ad una scena importata, quindi i cambiamenti "
+"alle tracce importate non saranno salvate.\n"
"\n"
-"Per abilitare la possibilità di aggiungere ulteriori tracce, vai alle "
-"impostazioni di importazione della scena e imposta\n"
-"\"Animation > Storage\" su \"Files\", abilita \"Animation > Keep Custom "
-"Tracks\", e infine reimporta la scena.\n"
-"Altrimenti, usa un preset di importazione che importa le animazioni in file "
+"Per abilitare l'aggiunta di tracce personalizzate, naviga alle impostazioni "
+"d'importazione della scena ed imposta\n"
+"\"Animation > Storage\" a \"Files\", abilita \"Animation > Keep Custom Tracks"
+"\", e poi re-importa.\n"
+"In alternativa, usa un preset d'importo che importa le animazioni da file "
"separati."
#: editor/animation_track_editor.cpp
@@ -564,11 +570,11 @@ msgstr "Mostra solo le tracce dei nodi selezionati nell'albero."
#: editor/animation_track_editor.cpp
msgid "Group tracks by node or display them as plain list."
-msgstr "Raggruppa le tracce per nodo o mostra una lista semplice."
+msgstr "Raggruppa le tracce per nodo o le visualizza in una lista semplice."
#: editor/animation_track_editor.cpp
msgid "Snap:"
-msgstr "Snap:"
+msgstr "Scatto:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
@@ -595,27 +601,27 @@ msgstr "Modifica"
#: editor/animation_track_editor.cpp
msgid "Animation properties."
-msgstr "Proprietà animazione."
+msgstr "Proprietà dell'animazione."
#: editor/animation_track_editor.cpp
msgid "Copy Tracks"
-msgstr "Copia tracce"
+msgstr "Copia le tracce"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
-msgstr "Scala selezione"
+msgstr "Scala la selezione"
#: editor/animation_track_editor.cpp
msgid "Scale From Cursor"
-msgstr "Scala da cursore"
+msgstr "Scala a partire dal cursore"
#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
msgid "Duplicate Selection"
-msgstr "Duplica selezione"
+msgstr "Duplica la selezione"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr "Duplica trasposto"
+msgstr "Duplica Trasposto"
#: editor/animation_track_editor.cpp
msgid "Delete Selection"
@@ -623,19 +629,19 @@ msgstr "Elimina la selezione"
#: editor/animation_track_editor.cpp
msgid "Go to Next Step"
-msgstr "Va' al passo successivo"
+msgstr "Vai allo Step Successivo"
#: editor/animation_track_editor.cpp
msgid "Go to Previous Step"
-msgstr "Va' al passo precedente"
+msgstr "Vai allo Step Precedente"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
-msgstr "Ottimizza animazione"
+msgstr "Ottimizza l'animazione"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation"
-msgstr "Pulisci animazione"
+msgstr "Pulisci l'animazione"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
@@ -643,7 +649,7 @@ msgstr "Seleziona il nodo che verrà animato:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
-msgstr "Usa curve di Bézier"
+msgstr "Usa le curve di Bézier"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
@@ -651,15 +657,15 @@ msgstr "Ottimizzatore anim."
#: editor/animation_track_editor.cpp
msgid "Max. Linear Error:"
-msgstr "Max. errore lineare:"
+msgstr "Max Errore Lineare:"
#: editor/animation_track_editor.cpp
msgid "Max. Angular Error:"
-msgstr "Max. errore angolare:"
+msgstr "Max Errore Angolare:"
#: editor/animation_track_editor.cpp
msgid "Max Optimizable Angle:"
-msgstr "Max. angolo ottimizzabile:"
+msgstr "Max Angolo Ottimizzabile:"
#: editor/animation_track_editor.cpp
msgid "Optimize"
@@ -667,11 +673,11 @@ msgstr "Ottimizza"
#: editor/animation_track_editor.cpp
msgid "Remove invalid keys"
-msgstr "Rimuovi chiavi non valide"
+msgstr "Rimuovi le chiavi non valide"
#: editor/animation_track_editor.cpp
msgid "Remove unresolved and empty tracks"
-msgstr "Rimuovi tracce irrisolte e vuote"
+msgstr "Rimuovi le tracce irrisolte e vuote"
#: editor/animation_track_editor.cpp
msgid "Clean-up all animations"
@@ -679,7 +685,7 @@ msgstr "Pulisci tutte le animazioni"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr "Pulisci animazione(i) (NON ANNULLABILE!)"
+msgstr "Pulisci le animazioni (NON ANNULLABILE!)"
#: editor/animation_track_editor.cpp
msgid "Clean-Up"
@@ -698,45 +704,45 @@ msgstr "Seleziona le tracce da copiare"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Copia"
#: editor/animation_track_editor.cpp
msgid "Select All/None"
-msgstr "Seleziona Tutto/Nulla"
+msgstr "De/Seleziona Tutto"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
-msgstr "Aggiungi traccia clip audio"
+msgstr "Aggiungi audio in una traccia di riproduzione audio"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr "Cambia Offset di Inizio della Clip della Traccia Audio"
+msgstr "Cambia Offset Inizio Clip Traccia Audio"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
-msgstr "Cambia offset di fine della clip della traccia audio"
+msgstr "Cambia Offset Fine Clip Traccia Audio"
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr "Ridimensiona array"
+msgstr "Ridimensiona Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr "Cambia tipo del valore dell'array"
+msgstr "Cambia Tipo Valore Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
-msgstr "Cambia valore array"
+msgstr "Cambia Valore Array"
#: editor/code_editor.cpp
msgid "Go to Line"
-msgstr "Vai alla linea"
+msgstr "Vai alla Linea"
#: editor/code_editor.cpp
msgid "Line Number:"
-msgstr "Numero linea:"
+msgstr "Numero Linea:"
#: editor/code_editor.cpp
msgid "%d replaced."
@@ -748,15 +754,15 @@ msgstr "%d corrispondenza."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d matches."
-msgstr "%d corrispondenza/e."
+msgstr "%d corrispondenze."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
-msgstr "Distingui maiuscole"
+msgstr "Distingui Maiuscole"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Whole Words"
-msgstr "Parole intere"
+msgstr "Parole Intere"
#: editor/code_editor.cpp
msgid "Replace"
@@ -764,11 +770,11 @@ msgstr "Sostituisci"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr "Rimpiazza tutti"
+msgstr "Rimpiazza Tutti"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr "Solo selezione"
+msgstr "Solo Selezione"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
@@ -777,7 +783,7 @@ msgstr "Standard"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
-msgstr "Commuta pannello degli script"
+msgstr "Toggle Pannello Script"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
@@ -793,23 +799,23 @@ msgstr "Rimpicciolisci"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr "Resetta ingrandimento"
+msgstr "Reimposta ingrandimento"
#: editor/code_editor.cpp
msgid "Warnings"
-msgstr "Avvertenze"
+msgstr "Avvisi"
#: editor/code_editor.cpp
msgid "Line and column numbers."
-msgstr "Numeri di riga e colonna."
+msgstr "Numeri di riga e di colonna."
#: editor/connections_dialog.cpp
msgid "Method in target node must be specified."
-msgstr "Il metodo del nodo designato deve essere specificato."
+msgstr "Il metodo del nodo selezionato deve essere specificato."
#: editor/connections_dialog.cpp
msgid "Method name must be a valid identifier."
-msgstr "Il nome del metodo dev'essere un identificatore valido."
+msgstr "Il nome del metodo deve essere un identificatore valido."
#: editor/connections_dialog.cpp
msgid ""
@@ -1907,8 +1913,8 @@ msgid "Open a File or Directory"
msgstr "Apri un file o una cartella"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Salva"
@@ -1999,10 +2005,6 @@ msgstr "Anteprima:"
msgid "File:"
msgstr "File:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "È necessaria un'estensione valida."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Scansiona sorgenti"
@@ -2174,7 +2176,6 @@ msgid "Property:"
msgstr "Proprietà:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Set"
msgstr "Imposta"
@@ -2445,6 +2446,10 @@ msgid "There is no defined scene to run."
msgstr "Non c'è nessuna scena definita da eseguire."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Salva scena prima di eseguire..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Impossibile avviare il sottoprocesso!"
@@ -2488,18 +2493,6 @@ msgstr "È necessario un nodo radice per salvare la scena."
msgid "Save Scene As..."
msgstr "Salva scena come…"
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "No"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Sì"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Questa scena non è mai stata salvata. Salvarla prima di eseguirla?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Questa operazione non può essere eseguita senza una scena."
@@ -2549,6 +2542,10 @@ msgid "Quit"
msgstr "Esci"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Sì"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Uscire dall'editor?"
@@ -2597,10 +2594,9 @@ msgstr ""
"configurazione fallita."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
-"Impossibile trovare il campo dello script per il componente aggiuntivo in: "
-"'res://addons/%s'."
+"Impossibile trovare il campo script per il plugin addon in posizione: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -3036,14 +3032,6 @@ msgid "Help"
msgstr "Aiuto"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Cerca"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentazione online"
@@ -3169,13 +3157,13 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
-"Questo imposterà il tuo progetto per le build custom per Android, "
-"installando i source templates in \"res://android/build\".\n"
-"Puoi, allora, applicare le modifiche e costruire il tuo APK custom durante "
-"l'esportazione (aggiungere moduli, cambiare il AndroidManifest.xml, ed "
-"altro).\n"
-"Nota che, in ordine per creare le build custom invece di usare gli APK pre-"
-"costruiti, l'opzione \"Use Custom Build\" sarà abilitata nel preset "
+"Questo predisporrà il progetto per le build personalizzate per Android "
+"installando i template sorgente in \"res://android/build\".\n"
+"Potrai allora applicare le modifiche e costruire il tuo APK personalizzato "
+"durante l'esportazione (aggiungere moduli, cambiare l'AndroidManifest.xml, "
+"eccetera).\n"
+"Nota che per creare delle build personalizzate, invece di usare gli APK pre-"
+"costruiti, l'opzione \"Use Custom Build\" va attivata nella preimpostazione "
"d'esportazione per Android."
#: editor/editor_node.cpp
@@ -3185,30 +3173,48 @@ msgid ""
"Remove the \"res://android/build\" directory manually before attempting this "
"operation again."
msgstr ""
-"Il modello della build Android è già installato in questo progetto e non "
-"sarà sovrascritto.\n"
-"Rimuovi la cartella \"res://android/build\" manualmente prima di ritentare "
+"Il template della build Android è già installato in questo progetto e non "
+"verrà sovrascritto.\n"
+"Rimuovi manualmente la cartella \"res://android/build\" prima di ritentare "
"questa operazione."
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
-msgstr "Importa template da un file ZIP"
+msgstr "Importa Template Da File ZIP"
#: editor/editor_node.cpp
msgid "Template Package"
-msgstr "Pacchetto Modello"
+msgstr "Pacchetto Template"
#: editor/editor_node.cpp
msgid "Export Library"
-msgstr "Esporta libreria"
+msgstr "Esporta Libreria"
#: editor/editor_node.cpp
msgid "Merge With Existing"
-msgstr "Unisci con esistente"
+msgstr "Unisci Con Esistente"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
-msgstr "Apri ed esegui uno script"
+msgstr "Apri ed Esegui uno Script"
+
+#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"I seguenti file sono più recenti sul disco.\n"
+"Quale azione dovrebbe essere presa?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Ricarica"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Risalva"
#: editor/editor_node.cpp
msgid "New Inherited"
@@ -3421,7 +3427,7 @@ msgstr "Rendi Unico"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Incolla"
@@ -3784,6 +3790,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"I seguenti file o cartelle vanno in conflitto con gli oggetti nel percorso "
+"di destinazione '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Desideri sovrascriverli?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3976,8 +3988,16 @@ msgid "Searching..."
msgstr "Ricerca..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Ricerca completata"
+msgid "%d match in %d file."
+msgstr "%d corrispondenza in %d file."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d corrispondenze in %d file."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d corrispondenze in %d file."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4114,6 +4134,21 @@ msgstr ""
msgid "Saving..."
msgstr "Salvataggio..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Modalità di selezione"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importare"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Usa sRGB Default"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d File"
@@ -5086,8 +5121,8 @@ msgid "Got:"
msgstr "Ottenuto:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Check hash sha256 fallito"
+msgid "Failed SHA-256 hash check"
+msgstr "Check has SHA-256 fallito"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5190,7 +5225,6 @@ msgid "Sort:"
msgstr "Ordina:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Categoria:"
@@ -5221,13 +5255,11 @@ msgstr "ZIP File degli Asset"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"Impossibile determinare un percorso di salvataggio per le immagini di "
+"Impossibile determinare un percorso di salvataggio per le immagini "
"lightmap.\n"
-"Salva la scena (per salvare le immagini nella stessa directory), o scegli un "
-"percorso di salvataggio nelle proprietà di BackedLightmap."
+"Salva la scena e riprova."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5244,9 +5276,34 @@ msgstr ""
"il percorso dei file sia scrivibile."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Impossibile determinare la dimensione della lightmap. La dimensione massima "
+"(della lightmap) è troppo piccola?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Alcune mesh non sono valide. Sii sicuro che i valori dei canali UV2 siano "
+"all'interno nella regione [0.0,1.0] quadra."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Godot Editor è stato costruito senza il supporto per il ray tracing, quindi "
+"il baking delle lightmaps non è possibile."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Preprocessa Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Seleziona il file bake della lightmap:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6351,6 +6408,10 @@ msgstr ""
"ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Converti in CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Tempo di Generazione (sec):"
@@ -6411,10 +6472,6 @@ msgstr "Generando AABB"
msgid "Generate Visibility AABB"
msgstr "Genera Visibilità AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Genera AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Rimuovi Punto da Curva"
@@ -7007,6 +7064,14 @@ msgstr "Chiudi la documentazione"
msgid "Run"
msgstr "Esegui"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Cerca"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Passo dentro all'istruzione"
@@ -7060,16 +7125,6 @@ msgstr ""
"I file seguenti sono più recenti su disco.\n"
"Che azione deve essere intrapresa?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Ricarica"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Risalva"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Debugger"
@@ -7165,8 +7220,8 @@ msgstr "Punti di interruzione"
msgid "Go To"
msgstr "Vai a"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Taglia"
@@ -7321,7 +7376,6 @@ msgid "Create physical bones"
msgstr "Crea ossa fisiche"
#: editor/plugins/skeleton_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton"
msgstr "Scheletro"
@@ -7390,6 +7444,10 @@ msgid "Yaw"
msgstr "Imbardata"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Dimensione"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Oggetti disegnati"
@@ -7669,7 +7727,6 @@ msgstr "Abilita/Disabilita Vista libera"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform"
msgstr "Trasforma"
@@ -8642,10 +8699,6 @@ msgid "Error"
msgstr "Errore"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Non è stato inserito alcun messaggio di commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Nessun file aggiunto allo stage"
@@ -8702,10 +8755,6 @@ msgid "Stage All"
msgstr "Stage Tutto"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Aggiungi un messaggio di commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Commit Cambiamenti"
@@ -8741,9 +8790,8 @@ msgid "Scalar"
msgstr "Scalare"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector"
-msgstr "Vector"
+msgstr "Vettore"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
@@ -9920,7 +9968,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Non supportato dai tuoi driver GPU."
#: editor/project_manager.cpp
msgid ""
@@ -10100,6 +10148,10 @@ msgid "Projects"
msgstr "Progetti"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Caricamento, per favore attendere..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Ultima Modifica"
@@ -10470,6 +10522,11 @@ msgstr "AutoLoad"
msgid "Plugins"
msgstr "Plugins"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Carica Predefiniti"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Preset…"
@@ -10720,6 +10777,14 @@ msgid "Instance Child Scene"
msgstr "Istanzia Scena Figlia"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "Non si può incollare il noto root nella stessa scena."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Incolla Nodo(i)"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Rimuovi Script"
@@ -10846,6 +10911,10 @@ msgid "Attach Script"
msgstr "Allega Script"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Taglia Nodo(i)"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Rimuovi nodo(i)"
@@ -11276,7 +11345,6 @@ msgid "Value"
msgstr "Valore"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Monitors"
msgstr "Monitor"
@@ -11653,6 +11721,34 @@ msgstr "Filtra mesh"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "Dai una risorsa MeshLibrary a questa GridMap per usare le sue mesh."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Inizia il Baking"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Preparando le strutture dati"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Genera buffers"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Luci dirette"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Luci indirette"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Post processing"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Stampando le lightmap"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Il nome della classe non può essere una parola chiave riservata"
@@ -12170,12 +12266,16 @@ msgid "Select device from the list"
msgstr "Seleziona il dispositivo dall'elenco"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Eseguibile ADB non configurato nelle Impostazioni dell'Editor."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Impossibile trovare lo strumento 'apksigner'."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner non configurato nelle Impostazioni dell'Editor."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Il template build di Android non è installato in questo progetto. Installalo "
+"dal menu Progetto."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12188,28 +12288,39 @@ msgstr ""
"Release keystore non configurato correttamente nel preset di esportazione."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"Le build personalizzate richiedono un percorso per un Android SDK valido "
-"nelle impostazioni dell'editor."
+"Un percorso valido per il SDK Android è richiesto nelle Impostazioni Editor."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Percorso per Android SDK per build personalizzata nelle impostazioni "
-"dell'editor non è valido."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Un percorso invalido per il SDK Android nelle Impostazioni Editor."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "Cartella 'platform-tools' inesistente!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
msgstr ""
-"Il template build di Android non è installato in questo progetto. Installalo "
-"dal menu Progetto."
+"Impossibile trovare il comando adb negli strumenti di piattaforma del SDK "
+"Android."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"Per favore, controlla la directory specificata del SDK Android nelle "
+"Impostazioni Editor."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "Cartella 'build-tools' inesistente!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+"Impossibile trovare il comando apksigner negli strumenti di piattaforma del "
+"SDK Android."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12482,6 +12593,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Un CollisionPolygon2D vuoto non ha effetti sulla collisione."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12520,23 +12639,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Nodo A e Nodo B devono essere PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Nodo A deve essere un PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Nodo B deve essere un PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Il giunto non è collegato a due PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Il Nodo A e il Nodo B devono essere PhysicsBody2D diversi"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12697,28 +12816,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin richiede un nodo figlio di tipo ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Cercando mesh e luci"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Tempo Rimanente: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Elaborazione Geometria (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Stampa Meshes: "
+msgid "Preparing environment"
+msgstr "Preparazione Ambiente"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Stampando Luci:"
+msgid "Generating capture"
+msgstr "Generando cattura"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Trama di Finitura"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Salvando Lightmap"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Illuminando Meshes: "
+msgid "Done"
+msgstr "Fatto"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12795,6 +12914,10 @@ msgid "Plotting Meshes"
msgstr "Tracciando Meshes"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Trama di Finitura"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12802,11 +12925,6 @@ msgstr ""
"Le GIProbes non sono supportate dal driver video GLES2.\n"
"In alternativa, usa una BakedLightmap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "\"InterpolatedCamera\" è stata deprecata e sarà rimossa in Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12873,23 +12991,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Il Nodo A e il Nodo B devono essere PhysicsBodies"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Il Nodo A deve essere un PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Il Nodo B deve essere un PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Il giunto non è collegato a dei PhysicsBodies"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Il Nodo A e il Nodo B devono essere PhysicsBodies diversi"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -13051,15 +13169,23 @@ msgstr "Attenzione!"
msgid "Please Confirm..."
msgstr "Per Favore Conferma..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "È necessaria un'estensione valida."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Abilita mini-mappa griglia."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
"functions. Making them visible for editing is fine, but they will hide upon "
"running."
msgstr ""
-"I popup saranno nascosti di predefinita finchè non chiami popup() o una "
-"delle qualsiasi funzioni popup*(). Farli diventare visibili per modificarli "
-"va bene, ma scompariranno all'esecuzione."
+"I popup saranno nascosti di default finchè non chiami popup(), o una delle "
+"qualsiasi funzioni popup*(). Farli diventare visibili per modificarli va "
+"bene, ma scompariranno durante l'esecuzione."
#: scene/gui/range.cpp
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
@@ -13106,6 +13232,14 @@ msgstr ""
"visibile."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"La porta del sampler è connessa ma mai usata. Considera cambiare la sorgente "
+"a 'SamplerPort'."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fonte non valida per l'anteprima."
@@ -13134,6 +13268,49 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Le constanti non possono essere modificate."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "\"InterpolatedCamera\" è stata deprecata e sarà rimossa in Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "No"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Questa scena non è mai stata salvata. Salvarla prima di eseguirla?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "Eseguibile ADB non configurato nelle Impostazioni dell'Editor."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner non configurato nelle Impostazioni dell'Editor."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Le build personalizzate richiedono un percorso per un Android SDK valido "
+#~ "nelle impostazioni dell'editor."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Tempo Rimanente: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Stampa Meshes: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Illuminando Meshes: "
+
+#~ msgid "Search complete"
+#~ msgstr "Ricerca completata"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Non è stato inserito alcun messaggio di commit"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Aggiungi un messaggio di commit"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr ""
#~ "C'è già un file o una cartella con lo stesso nome in questo percorso."
@@ -13476,9 +13653,6 @@ msgstr "Le constanti non possono essere modificate."
#~ msgid "Failed to save solution."
#~ msgstr "Impossibile salvare la soluzione."
-#~ msgid "Done"
-#~ msgstr "Fatto"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Impossibile creare il progetto C#."
@@ -14762,9 +14936,6 @@ msgstr "Le constanti non possono essere modificate."
#~ msgid "Use Default Light"
#~ msgstr "Usa Luce Default"
-#~ msgid "Use Default sRGB"
-#~ msgstr "Usa sRGB Default"
-
#~ msgid "Default Light Normal:"
#~ msgstr "Normale Luce di Default:"
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index 0ec6a58ed9..8afa2de349 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -1,6 +1,6 @@
# Japanese translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# akirakido <achts.y@gmail.com>, 2016-2017, 2018, 2019.
# D_first <dntk.daisei@gmail.com>, 2017, 2018.
@@ -18,7 +18,7 @@
# sugusan <sugusan.development@gmail.com>, 2018, 2019.
# Nathan Lovato <nathan.lovato.art@gmail.com>, 2018.
# nyanode <akaruooyagi@yahoo.co.jp>, 2018.
-# nitenook <admin@alterbaum.net>, 2018, 2019.
+# nitenook <admin@alterbaum.net>, 2018, 2019, 2020, 2021.
# Rob Matych <robertsmatych@gmail.com>, 2018.
# Hidetsugu Takahashi <manzyun@gmail.com>, 2019.
# Wataru Onuki <watonu@magadou.com>, 2019.
@@ -29,14 +29,14 @@
# Tarou Yamada <mizuningyou@yahoo.co.jp>, 2019.
# kazuma kondo <kazmax7@gmail.com>, 2019.
# Akihiro Ogoshi <technical@palsystem-game.com>, 2019, 2020.
-# Wataru Onuki <bettawat@yahoo.co.jp>, 2020.
+# Wataru Onuki <bettawat@yahoo.co.jp>, 2020, 2021.
# sporeball <sporeballdev@gmail.com>, 2020.
-# BinotaLIU <me@binota.org>, 2020.
+# BinotaLIU <me@binota.org>, 2020, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-01 20:29+0000\n"
+"PO-Revision-Date: 2021-03-08 15:33+0000\n"
"Last-Translator: Wataru Onuki <bettawat@yahoo.co.jp>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/"
"godot/ja/>\n"
@@ -45,12 +45,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "convert() ã®å¼•æ•°ã®åž‹ãŒç„¡åйã§ã™ã€‚TYPE_* 定数を使ã£ã¦ãã ã•ã„。"
+msgstr "convert() ã®å¼•æ•°ã®åž‹ãŒç„¡åйã§ã™ã€‚TYPE_* 定数を使用ã—ã¦ãã ã•ã„。"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -278,7 +278,7 @@ msgstr "ã“ã®ãƒˆãƒ©ãƒƒã‚¯ã® オン/オフ を切り替ãˆã€‚"
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
-msgstr "Update モード(ã“ã®ãƒ—ロパティã®è¨­å®šæ–¹æ³•)"
+msgstr "Update モード (ã“ã®ãƒ—ロパティã®è¨­å®šæ–¹æ³•)"
#: editor/animation_track_editor.cpp
msgid "Interpolation Mode"
@@ -286,7 +286,7 @@ msgstr "補間モード"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
-msgstr "ループラップモード(ループã®å…ˆé ­ã§è£œé–“を終了ã™ã‚‹ï¼‰"
+msgstr "ループラップモード (ループã®å…ˆé ­ã§è£œé–“を終了ã™ã‚‹)"
#: editor/animation_track_editor.cpp
msgid "Remove this track."
@@ -676,7 +676,7 @@ msgstr "コピーã™ã‚‹ãƒˆãƒ©ãƒƒã‚¯ã‚’é¸æŠž"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "コピー"
@@ -1590,7 +1590,7 @@ msgstr "ファイルã®ä¿å­˜:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
-msgstr "エクスãƒãƒ¼ãƒˆ テンプレートãŒäºˆæƒ³ã•れãŸãƒ‘スã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“:"
+msgstr "エクスãƒãƒ¼ãƒˆ テンプレートãŒäºˆæœŸã•れãŸãƒ‘スã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1881,8 +1881,8 @@ msgid "Open a File or Directory"
msgstr "ファイルã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é–‹ã"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "ä¿å­˜"
@@ -1973,10 +1973,6 @@ msgstr "プレビュー:"
msgid "File:"
msgstr "ファイル:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "æœ‰åŠ¹ãªæ‹¡å¼µå­ã‚’使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "スキャンソース"
@@ -2310,7 +2306,7 @@ msgid ""
"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
"be satisfied."
msgstr ""
-"シーンをä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãŠãらãã€ä¾å­˜é–¢ä¿‚(インスタンスã¾ãŸã¯ç¶™æ‰¿ï¼‰ã‚’"
+"シーンをä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãŠãらãã€ä¾å­˜é–¢ä¿‚ (インスタンスã¾ãŸã¯ç¶™æ‰¿) ã‚’"
"満ãŸã›ã¾ã›ã‚“ã§ã—ãŸã€‚"
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
@@ -2413,6 +2409,10 @@ msgid "There is no defined scene to run."
msgstr "実行ã™ã‚‹ã‚·ãƒ¼ãƒ³ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“。"
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "実行å‰ã«ã‚·ãƒ¼ãƒ³ã‚’ä¿å­˜..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "サブプロセスを開始ã§ãã¾ã›ã‚“ã§ã—ãŸ!"
@@ -2456,18 +2456,6 @@ msgstr "シーンをä¿å­˜ã™ã‚‹ã«ã¯ãƒ«ãƒ¼ãƒˆãƒŽãƒ¼ãƒ‰ãŒå¿…è¦ã§ã™ã€‚"
msgid "Save Scene As..."
msgstr "åå‰ã‚’付ã‘ã¦ã‚·ãƒ¼ãƒ³ã‚’ä¿å­˜..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "ã„ã„ãˆ"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "ã¯ã„"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "ã“ã®ã‚·ãƒ¼ãƒ³ã¯ä¸€åº¦ã‚‚ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“。実行ã™ã‚‹å‰ã«ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "ã“ã®æ“作ã«ã¯ã‚·ãƒ¼ãƒ³ãŒå¿…è¦ã§ã™ã€‚"
@@ -2517,6 +2505,10 @@ msgid "Quit"
msgstr "終了"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "ã¯ã„"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "エディタを終了ã—ã¾ã™ã‹ï¼Ÿ"
@@ -2562,10 +2554,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "アドオンプラグインを有効ã«ã§ãã¾ã›ã‚“: '%s' 設定ã®è§£æžã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
-"アドオンプラグインã®ã‚¹ã‚¯ãƒªãƒ—トフィールド㌠'res://addons/%s' ã‹ã‚‰è¦‹ã¤ã‹ã‚Šã¾ã›"
-"ん。"
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "アドオンプラグインã®ã‚¹ã‚¯ãƒªãƒ—トフィールド㌠'%s' ã§è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2996,14 +2986,6 @@ msgid "Help"
msgstr "ヘルプ"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "検索"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "オンラインドキュメント"
@@ -3129,13 +3111,13 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
-"ã“ã®æ“作㯠\"res://android/build\" ã«ã‚½ãƒ¼ã‚¹ãƒ†ãƒ³ãƒ—レートをインストールã—ã€ã‚¢ãƒ³"
-"ドロイドã®ã‚«ã‚¹ã‚¿ãƒ ãƒ“ルドを設定ã—ã¾ã™ã€‚\n"
+"ã“ã®æ“作㯠\"res://android/build\" ã«ã‚½ãƒ¼ã‚¹ãƒ†ãƒ³ãƒ—レートをインストールã—ã€"
+"Androidã®ã‚«ã‚¹ã‚¿ãƒ ãƒ“ルドを設定ã—ã¾ã™ã€‚\n"
"後ã‹ã‚‰è¨­å®šã«å¤‰æ›´ã‚’加ãˆãŸã‚Šã€ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆæ™‚ã«ã‚«ã‚¹ã‚¿ãƒ APKをビルドã§ãã¾ã™ (モ"
"ジュールを追加ã™ã‚‹ã€AndroidManifest.xmlを変更ã™ã‚‹ç­‰)。\n"
-"APKビルドã®åˆæœŸè¨­å®šã®ä»£ã‚りã«ã‚«ã‚¹ã‚¿ãƒ ãƒ“ルド設定を使ã†ãŸã‚ã«ã¯ã€ã‚¢ãƒ³ãƒ‰ãƒ­ã‚¤ãƒ‰ã®"
-"エクスãƒãƒ¼ãƒˆè¨­å®šã®ã€ŒUse Custom Build (カスタムビルドを使用ã™ã‚‹)ã€ã®ã‚ªãƒ—ション"
-"ãŒæœ‰åŠ¹åŒ–ã•れã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。"
+"APKビルドã®åˆæœŸè¨­å®šã®ä»£ã‚りã«ã‚«ã‚¹ã‚¿ãƒ ãƒ“ルド設定を使ã†ãŸã‚ã«ã¯ã€Androidã®ã‚¨ã‚¯"
+"スãƒãƒ¼ãƒˆè¨­å®šã®ã€ŒUse Custom Build (カスタムビルドを使用ã™ã‚‹)ã€ã®ã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæœ‰"
+"効化ã•れã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。"
#: editor/editor_node.cpp
msgid ""
@@ -3169,6 +3151,24 @@ msgid "Open & Run a Script"
msgstr "スクリプトを開ã„ã¦å®Ÿè¡Œ"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"以下ã®ãƒ•ァイルより新ã—ã„ã‚‚ã®ãŒãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«å­˜åœ¨ã—ã¾ã™ã€‚\n"
+"ã©ã†ã—ã¾ã™ã‹?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "å†èª­è¾¼"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "å†ä¿å­˜"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "æ–°è¦ã®ç¶™æ‰¿"
@@ -3379,7 +3379,7 @@ msgstr "ユニーク化"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "貼り付ã‘"
@@ -3736,6 +3736,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"以下ã®ãƒ•ァイルã¾ãŸã¯ãƒ•ォルダã¯ã€å¯¾è±¡ã®å ´æ‰€ '%s' ã«ã‚ã‚‹é …ç›®ã¨ç«¶åˆã—ã¦ã„ã¾"
+"ã™ã€‚\n"
+"\n"
+"%s\n"
+"\n"
+"上書ãã—ã¾ã™ã‹ï¼Ÿ"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3927,8 +3933,16 @@ msgid "Searching..."
msgstr "検索中..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "検索完了"
+msgid "%d match in %d file."
+msgstr "%d ä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠(%d 個ã®ãƒ•ァイル内)。"
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d ä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠(%d 個ã®ãƒ•ァイル内)。"
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d ä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠(%d 個ã®ãƒ•ァイル内)。"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4065,6 +4079,21 @@ msgstr ""
msgid "Saving..."
msgstr "ä¿å­˜ä¸­..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "é¸æŠžãƒ¢ãƒ¼ãƒ‰"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "インãƒãƒ¼ãƒˆ"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "デフォルトを読込む"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d ファイル"
@@ -5029,8 +5058,8 @@ msgid "Got:"
msgstr "å–å¾—:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "sha256 ãƒãƒƒã‚·ãƒ¥ãƒã‚§ãƒƒã‚¯å¤±æ•—"
+msgid "Failed SHA-256 hash check"
+msgstr "SHA-256 ãƒãƒƒã‚·ãƒ¥ãƒã‚§ãƒƒã‚¯å¤±æ•—"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5133,7 +5162,6 @@ msgid "Sort:"
msgstr "ソート:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "カテゴリー:"
@@ -5164,12 +5192,10 @@ msgstr "アセットã®zipファイル"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"ライトマップ画åƒã®ä¿å­˜ãƒ‘スを確定ã§ãã¾ã›ã‚“。\n"
-"シーンをä¿å­˜ã™ã‚‹ (ç”»åƒãŒåŒã˜ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ä¿å­˜ã•れる) ã‹ã€BakedLightmapプロパ"
-"ティã‹ã‚‰ä¿å­˜ãƒ‘ã‚¹ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
+"シーンをä¿å­˜ã—ã¦ã‹ã‚‰å†åº¦è¡Œã£ã¦ãã ã•ã„。"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5186,9 +5212,34 @@ msgstr ""
"ãã ã•ã„。"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"ライトマップサイズã®ç¢ºå®šã«å¤±æ•—ã—ã¾ã—ãŸã€‚ãƒ©ã‚¤ãƒˆãƒžãƒƒãƒ—ã®æœ€å¤§ã‚µã‚¤ã‚ºãŒå°ã•ã™ãŽã¾"
+"ã™ã‹ï¼Ÿ"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"一部ã®ãƒ¡ãƒƒã‚·ãƒ¥ãŒç„¡åйã§ã™ã€‚UV2ãƒãƒ£ãƒ³ãƒãƒ«ã®å€¤ãŒ [0.0,1.0] ã®æ­£æ–¹å½¢é ˜åŸŸå†…ã«ã‚ã‚‹"
+"ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"GodotエディタãŒãƒ¬ã‚¤ãƒˆãƒ¬ãƒ¼ã‚·ãƒ³ã‚°ã«å¯¾å¿œã›ãšã«ãƒ“ルドã•れã¦ãŠã‚Šã€ãƒ©ã‚¤ãƒˆãƒžãƒƒãƒ—ã®ãƒ™"
+"イクãŒã§ãã¾ã›ã‚“。"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "ライトマップを焼ã込む"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "ãƒ©ã‚¤ãƒˆãƒžãƒƒãƒ—ãƒ™ã‚¤ã‚¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6281,6 +6332,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "ParticlesMaterialプロセスマテリアルã«ã®ã¿ç‚¹ã‚’設定ã§ãã¾ã™"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "CPUParticles2D ã«å¤‰æ›"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "ç”Ÿæˆæ™‚é–“ (ç§’):"
@@ -6341,10 +6396,6 @@ msgstr "AABBを生æˆä¸­"
msgid "Generate Visibility AABB"
msgstr "å¯è¦–性ã®AABBを生æˆ"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "AABBを生æˆ"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "曲線ã‹ã‚‰ãƒã‚¤ãƒ³ãƒˆã‚’除去"
@@ -6933,6 +6984,14 @@ msgstr "ドキュメントを閉ã˜ã‚‹"
msgid "Run"
msgstr "実行"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "検索"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "ステップイン"
@@ -6986,16 +7045,6 @@ msgstr ""
"以下ã®ãƒ•ァイルより新ã—ã„ã‚‚ã®ãŒãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«å­˜åœ¨ã—ã¾ã™ã€‚\n"
"ã©ã†ã—ã¾ã™ã‹?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "å†èª­è¾¼"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "å†ä¿å­˜"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "デãƒãƒƒã‚¬"
@@ -7024,7 +7073,7 @@ msgstr "ターゲット"
msgid ""
"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
msgstr ""
-"メソッド'%s' (シグナル'ï¼…s'用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€ã“れã¯ãƒŽãƒ¼ãƒ‰'%s'ã‹ã‚‰ãƒŽãƒ¼"
+"メソッド'%s' (シグナル'%s'用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€ã“れã¯ãƒŽãƒ¼ãƒ‰'%s'ã‹ã‚‰ãƒŽãƒ¼"
"ド'%s'ã¸ã®ã‚·ã‚°ãƒŠãƒ«ç”¨ã§ã™ã€‚"
#: editor/plugins/script_text_editor.cpp
@@ -7092,8 +7141,8 @@ msgstr "ブレークãƒã‚¤ãƒ³ãƒˆ"
msgid "Go To"
msgstr "å‚ç…§"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "切りå–り"
@@ -7316,6 +7365,10 @@ msgid "Yaw"
msgstr "ヨー"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "サイズ"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "æç”»ã•れãŸã‚ªãƒ–ジェクト"
@@ -7449,7 +7502,7 @@ msgstr "オーディオリスナー"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Enable Doppler"
-msgstr "ドップラー効果を有効化ã™ã‚‹"
+msgstr "ドップラー効果を有効化"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Cinematic Preview"
@@ -8563,10 +8616,6 @@ msgid "Error"
msgstr "エラー"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯æä¾›ã•れã¾ã›ã‚“ã§ã—ãŸ"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "ステージã«è¿½åŠ ã•れã¦ã„るファイルãŒã‚りã¾ã›ã‚“"
@@ -8623,10 +8672,6 @@ msgid "Stage All"
msgstr "ã™ã¹ã¦ã‚’ステージã™ã‚‹"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "コミットメッセージを追加ã™ã‚‹"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "変更をコミットã™ã‚‹"
@@ -9629,7 +9674,7 @@ msgstr ""
#: editor/project_export.cpp
msgid "Features"
-msgstr "特徴"
+msgstr "機能"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -9825,7 +9870,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "ãŠä½¿ã„ã®GPUドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。"
#: editor/project_manager.cpp
msgid ""
@@ -10000,6 +10045,10 @@ msgid "Projects"
msgstr "プロジェクト"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "読ã¿è¾¼ã¿ä¸­ã€ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "最終更新"
@@ -10204,7 +10253,7 @@ msgstr "プロパティ '%s' ã¯å­˜åœ¨ã—ã¾ã›ã‚“。"
#: editor/project_settings_editor.cpp
msgid "Setting '%s' is internal, and it can't be deleted."
-msgstr "設定 'ï¼…s'ã¯å†…部的ãªã‚‚ã®ã§ã‚りã€å‰Šé™¤ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
+msgstr "設定 '%s'ã¯å†…部的ãªã‚‚ã®ã§ã‚りã€å‰Šé™¤ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
#: editor/project_settings_editor.cpp
msgid "Delete Item"
@@ -10370,6 +10419,11 @@ msgstr "自動読ã¿è¾¼ã¿"
msgid "Plugins"
msgstr "プラグイン"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "デフォルトを読込む"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "プリセット..."
@@ -10619,6 +10673,14 @@ msgid "Instance Child Scene"
msgstr "å­ã‚·ãƒ¼ãƒ³ã‚’インスタンス化"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "ルートノードã¯åŒã˜ã‚·ãƒ¼ãƒ³ã«è²¼ã‚Šä»˜ã‘ã§ãã¾ã›ã‚“。"
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "ノードを貼り付ã‘"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "スクリプトをデタッãƒ"
@@ -10744,6 +10806,10 @@ msgid "Attach Script"
msgstr "スクリプトをアタッãƒ"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "ノードを切りå–り"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "ノードを除去"
@@ -10815,7 +10881,7 @@ msgstr "親ノードを新è¦ãƒŽãƒ¼ãƒ‰ã«å¤‰æ›´"
#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
-msgstr "シーンをルートã«ã™ã‚‹"
+msgstr "シーンã®ãƒ«ãƒ¼ãƒˆã«ã™ã‚‹"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
@@ -11551,6 +11617,35 @@ msgstr ""
"メッシュを使ã†ã«ã¯ãƒ¡ãƒƒã‚·ãƒ¥ãƒ©ã‚¤ãƒ–ラリリソースをã“ã®ã‚°ãƒªãƒƒãƒ‰ãƒžãƒƒãƒ—ã«è¨­å®šã—ã¦ã"
"ã ã•ã„。"
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "ベイク開始"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "ãƒ‡ãƒ¼ã‚¿æ§‹é€ ã®æº–å‚™"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "ãƒãƒƒãƒ•ァを生æˆ"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "直接光"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "間接光"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "後処ç†"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "å…‰æºã‚’æç”»ä¸­:"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "クラスåを予約キーワードã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
@@ -11808,8 +11903,8 @@ msgid ""
"Can't drop properties because script '%s' is not used in this scene.\n"
"Drop holding 'Shift' to just copy the signature."
msgstr ""
-"ã“ã®ã‚·ãƒ¼ãƒ³ã§ã¯ã‚¹ã‚¯ãƒªãƒ—ト 'ï¼…s'ãŒä½¿ç”¨ã•れã¦ã„ãªã„ãŸã‚ã€ãƒ—ロパティを削除ã§ãã¾"
-"ã›ã‚“。\n"
+"ã“ã®ã‚·ãƒ¼ãƒ³ã§ã¯ã‚¹ã‚¯ãƒªãƒ—ト '%s'ãŒä½¿ç”¨ã•れã¦ã„ãªã„ãŸã‚ã€ãƒ—ロパティを削除ã§ãã¾ã›"
+"ん。\n"
"「Shiftã€ã‚’押ã—ãªãŒã‚‰ãƒ‰ãƒ­ãƒƒãƒ—ã™ã‚‹ã¨ã€ç½²åãŒã‚³ãƒ”ーã•れã¾ã™ã€‚"
#: modules/visual_script/visual_script_editor.cpp
@@ -12065,12 +12160,16 @@ msgid "Select device from the list"
msgstr "一覧ã‹ã‚‰ãƒ‡ãƒã‚¤ã‚¹ã‚’é¸æŠž"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "ADB実行å¯èƒ½ãƒ•ァイルãŒã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§è¨­å®šã•れã¦ã„ã¾ã›ã‚“。"
+msgid "Unable to find the 'apksigner' tool."
+msgstr "'apksigner' ツールãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§è¨­å®šã•れã¦ã„ã¾ã›ã‚“。"
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Android ビルド テンプレートãŒãƒ—ロジェクトã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“。[プロ"
+"ジェクト] メニューã‹ã‚‰ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã€‚"
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12081,24 +12180,32 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "エクスãƒãƒ¼ãƒˆè¨­å®šã«ã¦ãƒªãƒªãƒ¼ã‚¹ キーストアãŒèª¤ã£ã¦è¨­å®šã•れã¦ã„ã¾ã™ã€‚"
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr "カスタムビルドã«ã¯ã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§æœ‰åйãªAndroid SDKパスãŒå¿…è¦ã§ã™ã€‚"
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "エディタ設定ã§Android SDKãƒ‘ã‚¹ã®æŒ‡å®šãŒå¿…è¦ã§ã™ã€‚"
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr "エディタ設定ã®ã‚«ã‚¹ã‚¿ãƒ ãƒ“ルドã®Android SDKパスãŒç„¡åйã§ã™ã€‚"
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "エディタ設定ã®Android SDKパスãŒç„¡åйã§ã™ã€‚"
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "'platform-tools' ディレクトリãŒã‚りã¾ã›ã‚“ï¼"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
-msgstr ""
-"Android ビルド テンプレートãŒãƒ—ロジェクトã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“。[プロ"
-"ジェクト] メニューã‹ã‚‰ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã€‚"
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "Android SDK platform-toolsã®adbコマンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr "ã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§æŒ‡å®šã•れãŸAndroid SDKã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’確èªã—ã¦ãã ã•ã„。"
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "'build-tools' ディレクトリãŒã‚りã¾ã›ã‚“ï¼"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "Android SDK build-toolsã®apksignerコマンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12362,6 +12469,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "空㮠CollisionPolygon2D ã¯ã€è¡çªåˆ¤å®šã‚’æŒã¡ã¾ã›ã‚“。"
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12398,23 +12513,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Node Aã¨Node B㯠PhysicsBody2D ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node A 㯠PhysicsBody2D ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node B 㯠PhysicsBody2D ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Joint ãŒ2ã¤ã® PhysicsBody2D ã«æŽ¥ç¶šã•れã¦ã¾ã›ã‚“"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A 㨠Node B ã¯ç•°ãªã‚‹ PhysicsBody2D ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12571,28 +12686,31 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROriginã¯å­ãƒŽãƒ¼ãƒ‰ã«ARVRCameraãŒå¿…è¦ã§ã™ã€‚"
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Time Left: %d分%02d秒)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "ジオメトリを解æžã—ã¦ã„ã¾ã™ (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "メッシュをæç”»ä¸­: "
+#, fuzzy
+msgid "Preparing environment"
+msgstr "環境を表示"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "å…‰æºã‚’æç”»ä¸­:"
+#, fuzzy
+msgid "Generating capture"
+msgstr "ライトマップã®ç”Ÿæˆ"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "æç”»å®Œäº†"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "ライトマップã®ç”Ÿæˆ"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "ライティングメッシュ: "
+msgid "Done"
+msgstr "完了"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12669,6 +12787,10 @@ msgid "Plotting Meshes"
msgstr "メッシュã®ãƒ—ロット"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "æç”»å®Œäº†"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12676,11 +12798,6 @@ msgstr ""
"GIProbesã¯GLES2ビデオドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。\n"
"代ã‚りã«BakedLightmapを使用ã—ã¦ãã ã•ã„。"
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera ã¯å»ƒæ­¢äºˆå®šã§ã‚りã€Godot 4.0ã§é™¤åŽ»ã•れã¾ã™ã€‚"
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "90度を超ãˆã‚‹è§’度ã®ã‚¹ãƒãƒƒãƒˆãƒ©ã‚¤ãƒˆã¯ã€ã‚·ãƒ£ãƒ‰ã‚¦ã‚’投影ã§ãã¾ã›ã‚“。"
@@ -12746,23 +12863,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Node A 㨠Node B 㯠PhysicsBody ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Node A 㯠PhysicsBody ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Node B 㯠PhysicsBody ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Joint ã¨æŽ¥ç¶šã—ã¦ã„ã‚‹ PhysicsBody ãŒã‚りã¾ã›ã‚“"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Node A 㨠Node B ã¯ç•°ãªã‚‹ PhysicsBody ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12827,7 +12944,7 @@ msgstr ""
#: scene/animation/animation_blend_tree.cpp
msgid "On BlendTree node '%s', animation not found: '%s'"
-msgstr "BlendTreeノード 'ï¼…s' ã§ã¯ã€ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: 'ï¼…s'"
+msgstr "BlendTreeノード '%s' ã§ã¯ã€ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: '%s'"
#: scene/animation/animation_blend_tree.cpp
msgid "Animation not found: '%s'"
@@ -12843,7 +12960,7 @@ msgstr "無効ãªã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³: '%s'。"
#: scene/animation/animation_tree.cpp
msgid "Nothing connected to input '%s' of node '%s'."
-msgstr "入力 'ï¼…s'(ノード 'ï¼…s')ã«æŽ¥ç¶šã•れã¦ã„ã‚‹ã‚‚ã®ã¯ã‚りã¾ã›ã‚“。"
+msgstr "入力 '%s'(ノード '%s')ã«æŽ¥ç¶šã•れã¦ã„ã‚‹ã‚‚ã®ã¯ã‚りã¾ã›ã‚“。"
#: scene/animation/animation_tree.cpp
msgid "No root AnimationNode for the graph is set."
@@ -12925,6 +13042,14 @@ msgstr "警告!"
msgid "Please Confirm..."
msgstr "確èª..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "æœ‰åŠ¹ãªæ‹¡å¼µå­ã‚’使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚"
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "グリッドミニマップを有効ã«ã™ã‚‹ã€‚"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12978,6 +13103,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "レンダーã™ã‚‹ã«ã¯ãƒ“ューãƒãƒ¼ãƒˆã®ã‚µã‚¤ã‚ºãŒ 0 より大ãã„å¿…è¦ãŒã‚りã¾ã™ã€‚"
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "プレビューã®ã‚½ãƒ¼ã‚¹ãŒç„¡åйã§ã™ã€‚"
@@ -13005,14 +13136,48 @@ msgstr "Varying変数ã¯é ‚点関数ã«ã®ã¿å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã
msgid "Constants cannot be modified."
msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "ã“ã®ãƒ‘スã«ã¯ã€æ—¢ã«åŒåã®ãƒ•ァイルã‹ãƒ•ォルダãŒã‚りã¾ã™ã€‚"
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "InterpolatedCamera ã¯å»ƒæ­¢äºˆå®šã§ã‚りã€Godot 4.0ã§é™¤åŽ»ã•れã¾ã™ã€‚"
+
+#~ msgid "No"
+#~ msgstr "ã„ã„ãˆ"
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "'build-tools' ディレクトリãŒã‚りã¾ã›ã‚“ï¼"
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "ã“ã®ã‚·ãƒ¼ãƒ³ã¯ä¸€åº¦ã‚‚ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“。実行ã™ã‚‹å‰ã«ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ"
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "zipalign ツールãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "ADB実行å¯èƒ½ãƒ•ァイルãŒã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§è¨­å®šã•れã¦ã„ã¾ã›ã‚“。"
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§è¨­å®šã•れã¦ã„ã¾ã›ã‚“。"
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr "カスタムビルドã«ã¯ã‚¨ãƒ‡ã‚£ã‚¿è¨­å®šã§æœ‰åйãªAndroid SDKパスãŒå¿…è¦ã§ã™ã€‚"
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Time Left: %d分%02d秒)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "メッシュをæç”»ä¸­: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "ライティングメッシュ: "
+
+#~ msgid "Search complete"
+#~ msgstr "検索完了"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯æä¾›ã•れã¾ã›ã‚“ã§ã—ãŸ"
+
+#~ msgid "Add a commit message"
+#~ msgstr "コミットメッセージを追加ã™ã‚‹"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "ã“ã®ãƒ‘スã«ã¯ã€æ—¢ã«åŒåã®ãƒ•ァイルã‹ãƒ•ォルダãŒã‚りã¾ã™ã€‚"
#~ msgid "Aligning APK..."
#~ msgstr "APKを最é©åŒ–..."
@@ -13359,9 +13524,6 @@ msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。"
#~ msgid "Failed to save solution."
#~ msgstr "ソリューションã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
-#~ msgid "Done"
-#~ msgstr "完了"
-
#~ msgid "Failed to create C# project."
#~ msgstr "C#プロジェクトã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index ae770dc05a..6828baf211 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -1,6 +1,6 @@
# Georgian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Giorgi Beriashvili <giorgi.beriashvili@outlook.com>, 2018.
# George Dzavashvili <dzavashviligeorge@gmail.com>, 2018.
@@ -675,7 +675,7 @@ msgstr "დáƒáƒ§áƒ”ნდეს გáƒáƒ“áƒáƒ¡áƒ•ლები შემდეá
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1900,8 +1900,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1995,10 +1995,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2413,6 +2409,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2457,18 +2457,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2517,6 +2505,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2560,7 +2552,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2957,14 +2949,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3119,6 +3103,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3324,7 +3324,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3876,8 +3876,19 @@ msgid "Searching..."
msgstr "ძებნáƒ:"
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr ""
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "áƒáƒ  áƒáƒ áƒ¡áƒ”ბáƒáƒ‘ს ტáƒáƒšáƒ˜"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "áƒáƒ  áƒáƒ áƒ¡áƒ”ბáƒáƒ‘ს ტáƒáƒšáƒ˜"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "áƒáƒ  áƒáƒ áƒ¡áƒ”ბáƒáƒ‘ს ტáƒáƒšáƒ˜"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4017,6 +4028,19 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "წáƒáƒ•შáƒáƒšáƒáƒ— მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ ფáƒáƒ˜áƒšáƒ”ბი?"
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4995,7 +5019,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5102,7 +5126,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5134,8 +5157,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5149,9 +5171,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "წáƒáƒ•შáƒáƒšáƒáƒ— მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ ფáƒáƒ˜áƒšáƒ”ბი?"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6236,6 +6278,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "შექმნáƒ"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6296,10 +6343,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6895,6 +6938,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6946,16 +6997,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7055,8 +7096,8 @@ msgstr "შექმნáƒ"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7284,6 +7325,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8544,10 +8589,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8611,10 +8652,6 @@ msgid "Stage All"
msgstr "ყველáƒáƒ¡ ჩáƒáƒœáƒáƒªáƒ•ლებáƒ"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "ცვლილებáƒ"
@@ -9893,6 +9930,11 @@ msgid "Projects"
msgstr "პრáƒáƒ”ქტის დáƒáƒ›áƒ¤áƒ£áƒ«áƒœáƒ”ბლები"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "ძებნáƒ:"
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10257,6 +10299,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10504,6 +10550,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულებების შემსწáƒáƒ áƒ”ბელი"
@@ -10630,6 +10685,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11437,6 +11497,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11949,11 +12037,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11965,11 +12055,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11977,9 +12067,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12211,6 +12311,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12377,27 +12485,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12457,14 +12565,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12674,6 +12781,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12715,6 +12830,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ."
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index 14f197d86e..b898f397f4 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -1,6 +1,6 @@
# Korean translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Ch <ccwpc@hanmail.net>, 2017.
# paijai 송 (fivejobi) <xotjq237@gmail.com>, 2018.
@@ -16,7 +16,7 @@
# Jiyoon Kim <kimjiy@dickinson.edu>, 2019.
# Ervin <zetsmart@gmail.com>, 2019.
# Tilto_ <tilto0822@develable.xyz>, 2020.
-# Myeongjin Lee <aranet100@gmail.com>, 2020.
+# Myeongjin Lee <aranet100@gmail.com>, 2020, 2021.
# Doyun Kwon <caen4516@gmail.com>, 2020.
# Jun Hyung Shin <shmishmi79@gmail.com>, 2020.
# Yongjin Jo <wnrhd114@gmail.com>, 2020.
@@ -25,8 +25,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-10-31 23:15+0000\n"
-"Last-Translator: Yungjoong Song <yungjoong.song@gmail.com>\n"
+"PO-Revision-Date: 2021-03-08 15:33+0000\n"
+"Last-Translator: Myeongjin Lee <aranet100@gmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
"Language: ko\n"
@@ -34,7 +34,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.3.2-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -662,7 +662,7 @@ msgstr "복사할 트랙 ì„ íƒ"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "복사"
@@ -704,7 +704,7 @@ msgstr "행 번호:"
#: editor/code_editor.cpp
msgid "%d replaced."
-msgstr "%d개가 바뀌었습니다."
+msgstr "%d개 찾아 바꿈."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
@@ -1044,22 +1044,23 @@ msgid "Owners Of:"
msgstr "소유ìž:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "프로ì íЏì—서 ì„ íƒí•œ 파ì¼ì„ 삭제할까요? (ë˜ëŒë¦´ 수 없습니다)"
+msgstr ""
+"프로ì íЏì—서 ì„ íƒëœ 파ì¼ì„ 제거하시겠습니다? (ë˜ëŒë¦´ 수 ì—†ìŒ)\n"
+"시스템 휴지통ì—서 ì œê±°ëœ íŒŒì¼ì„ 찾고 ë³µì›í•  수 있습니다."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
"Remove them anyway? (no undo)\n"
"You can find the removed files in the system trash to restore them."
msgstr ""
-"삭제하려는 파ì¼ì€ 다른 리소스가 ë™ìž‘하기 위해 필요한 파ì¼ìž…니다.\n"
-"무시하고 삭제할까요? (ë˜ëŒë¦´ 수 없습니다)"
+"제거하려는 파ì¼ì€ 다른 리소스가 ë™ìž‘하기 위해 필요합니다.\n"
+"무시하고 제거하시겠습니까? (ë˜ëŒë¦´ 수 ì—†ìŒ)\n"
+"시스템 휴지통ì—서 ì œê±°ëœ íŒŒì¼ì„ 찾고 ë³µì›í•  수 있습니다."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1864,8 +1865,8 @@ msgid "Open a File or Directory"
msgstr "디렉토리 ë˜ëŠ” íŒŒì¼ ì—´ê¸°"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "저장"
@@ -1956,10 +1957,6 @@ msgstr "미리 보기:"
msgid "File:"
msgstr "파ì¼:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "올바른 확장ìžë¥¼ 사용해야 합니다."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "소스 스캔중"
@@ -2318,6 +2315,8 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"편집기 ë ˆì´ì•„ì›ƒì˜ ì €ìž¥ì„ í•˜ë ¤ëŠ” ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤.\n"
+"íŽ¸ì§‘ê¸°ì˜ ì‚¬ìš©ìž ë°ì´í„° 경로가 쓰기 가능한지 확ì¸í•´ì£¼ì„¸ìš”."
#: editor/editor_node.cpp
msgid ""
@@ -2325,15 +2324,17 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"기본 편집기 ë ˆì´ì•„ì›ƒì´ ë®ì–´ 쓰여져 있습니디.\n"
+"기본 ë ˆì´ì•„ì›ƒì„ ì›ëž˜ 설정으로 복구하려면, ë ˆì´ì•„웃 ì‚­ì œ ì˜µì…˜ì„ ì‚¬ìš©í•˜ì—¬ 기본 "
+"ë ˆì´ì•„ì›ƒì„ ì‚­ì œí•˜ì„¸ìš”."
#: editor/editor_node.cpp
msgid "Layout name not found!"
msgstr "ë ˆì´ì•„웃 ì´ë¦„ì„ ì°¾ì„ ìˆ˜ 없습니다!"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Restored the Default layout to its base settings."
-msgstr "기본 ë ˆì´ì•„ì›ƒì„ ì´ˆê¸°í™”í•˜ì˜€ìŠµë‹ˆë‹¤."
+msgstr "기본 ë ˆì´ì•„ì›ƒì„ ì›ëž˜ 설정으로 복구하였습니다."
#: editor/editor_node.cpp
msgid ""
@@ -2387,6 +2388,10 @@ msgid "There is no defined scene to run."
msgstr "실행할 ì”¬ì´ ì„¤ì •ë˜ì§€ 않았습니다."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "ì”¬ì„ ì‹¤í–‰í•˜ê¸° ì „ì— ì €ìž¥..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "하위 프로세스를 시작할 수 없습니다!"
@@ -2430,18 +2435,6 @@ msgstr "ì”¬ì„ ì €ìž¥í•˜ë ¤ë©´ 루트 노드가 필요합니다."
msgid "Save Scene As..."
msgstr "ì”¬ì„ ë‹¤ë¥¸ ì´ë¦„으로 저장..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "아니오"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "예"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "ì´ ì”¬ì€ ì•„ì§ ì €ìž¥í•˜ì§€ 않았습니다. 실행하기 ì „ì— ì €ìž¥í• ê¹Œìš”?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "ì´ ìž‘ì—…ì—는 ì”¬ì´ í•„ìš”í•©ë‹ˆë‹¤."
@@ -2491,6 +2484,10 @@ msgid "Quit"
msgstr "종료"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "예"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "편집기를 ëŒê¹Œìš”?"
@@ -2515,8 +2512,8 @@ msgid ""
"This option is deprecated. Situations where refresh must be forced are now "
"considered a bug. Please report."
msgstr ""
-"ì´ ì„¤ì •ì€ ì œê±°ë˜ì—ˆìŠµë‹ˆë‹¤. 강제로 새로고침해야 하는 ìƒí™©ì€ ì´ì œ 버그입니다. ì‹ "
-"고해주세요."
+"ì´ ì˜µì…˜ì€ ì‚¬ìš©ë˜ì§€ 않습니다. 강제로 새로 고침해야 하는 ìƒí™©ì€ ì´ì œ 버그로 ê°„"
+"주ë©ë‹ˆë‹¤. 신고해주세요."
#: editor/editor_node.cpp
msgid "Pick a Main Scene"
@@ -2537,8 +2534,9 @@ msgstr ""
"실패했습니다."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr "ë‹¤ìŒ ê²½ë¡œì—서 애드온 플러그ì¸ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr ""
+"ë‹¤ìŒ ê²½ë¡œì—서 애드온 플러그ì¸ì„ 위한 스í¬ë¦½íЏ 필드를 ì°¾ì„ ìˆ˜ 없습니다: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2901,17 +2899,16 @@ msgid "Synchronize Script Changes"
msgstr "스í¬ë¦½íЏ 변경사항 ë™ê¸°í™”"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, any script that is saved will be reloaded in "
"the running project.\n"
"When used remotely on a device, this is more efficient when the network "
"filesystem option is enabled."
msgstr ""
-"ì´ ì„¤ì •ì´ í™œì„±í™”ëœ ê²½ìš°, ì–´ë–¤ 스í¬ë¦½íŠ¸ë“  저장하면 ì‹¤í–‰ì¤‘ì¸ ê²Œìž„ì—ë„ ìƒˆë¡œê³ ì¹¨"
-"ë˜ì–´ ë°˜ì˜ë©ë‹ˆë‹¤.\n"
-"ì›ê²© 장치ì—서 ì‚¬ìš©ì¤‘ì¸ ê²½ìš° ë„¤íŠ¸ì›Œí¬ íŒŒì¼ ì‹œìŠ¤í…œ ê¸°ëŠ¥ì„ í™œì„±í™”í•˜ë©´ ë”ìš± 효율"
-"ì ìž…니다."
+"ì´ ì˜µì…˜ì´ í™œì„±í™”ëœ ê²½ìš°, ì–´ë–¤ 스í¬ë¦½íŠ¸ë“ ì§€ 저장ë˜ë©´ 실행 ì¤‘ì¸ í”„ë¡œì íŠ¸ë¥¼ 다"
+"시 불러오게 ë©ë‹ˆë‹¤.\n"
+"기기ì—서 ì›ê²©ìœ¼ë¡œ 사용 ì¤‘ì¸ ê²½ìš°, ë„¤íŠ¸ì›Œí¬ íŒŒì¼ ì‹œìŠ¤í…œ ì˜µì…˜ì´ í™œì„±í™”ë˜ì–´ 있다"
+"ë©´ ë”ìš± 효율ì ìž…니다."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
@@ -2966,14 +2963,6 @@ msgid "Help"
msgstr "ë„움ë§"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "검색"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "온ë¼ì¸ 문서"
@@ -3135,6 +3124,24 @@ msgid "Open & Run a Script"
msgstr "스í¬ë¦½íЏ 열기 & 실행"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"ë‹¤ìŒ íŒŒì¼ì€ 디스í¬ì— 있는 게 ë” ìµœì‹ ìž…ë‹ˆë‹¤.\n"
+"ì¡°ì¹˜ì„ ì–´ë–»ê²Œ 취해야 합니까?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "새로고침"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "다시 저장"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "새 ìƒì† 씬"
@@ -3343,7 +3350,7 @@ msgstr "유ì¼í•˜ê²Œ 만들기"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "붙여넣기"
@@ -3381,14 +3388,14 @@ msgid "Add Key/Value Pair"
msgstr "키/ê°’ ìŒ ì¶”ê°€"
#: editor/editor_run_native.cpp
-#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
"Please add a runnable preset in the Export menu or define an existing preset "
"as runnable."
msgstr ""
-"ì´ í”Œëž«í¼ìœ¼ë¡œ 실행할 수 있는 내보내기 í”„ë¦¬ì…‹ì´ ì—†ìŠµë‹ˆë‹¤.\n"
-"내보내기 메뉴ì—서 실행할 수 있는 í”„ë¦¬ì…‹ì„ ì¶”ê°€í•´ì£¼ì„¸ìš”."
+"ì´ í”Œëž«í¼ì„ 위한 실행할 수 있는 내보내기 í”„ë¦¬ì…‹ì´ ì—†ìŠµë‹ˆë‹¤.\n"
+"내보내기 메뉴ì—서 실행할 수 있는 í”„ë¦¬ì…‹ì„ ì¶”ê°€í•˜ê±°ë‚˜ 기존 í”„ë¦¬ì…‹ì„ ì‹¤í–‰í•  수 "
+"있ë„ë¡ ì§€ì •í•´ì£¼ì„¸ìš”."
#: editor/editor_run_script.cpp
msgid "Write your logic in the _run() method."
@@ -3701,6 +3708,11 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"ë‹¤ìŒ íŒŒì¼ì´ë‚˜ í´ë”ê°€ ëŒ€ìƒ ìœ„ì¹˜ '%s'ì˜ í•­ëª©ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤:\n"
+"\n"
+"%s\n"
+"\n"
+"ì´ë¥¼ ë®ì–´ì“°ì‹œê² ìŠµë‹ˆê¹Œ?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3781,9 +3793,8 @@ msgid "Duplicate..."
msgstr "복제..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Move to Trash"
-msgstr "오토로드 ì´ë™"
+msgstr "휴지통으로 ì´ë™"
#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Rename..."
@@ -3894,8 +3905,16 @@ msgid "Searching..."
msgstr "검색 중..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "검색 완료"
+msgid "%d match in %d file."
+msgstr "íŒŒì¼ %d$2ê°œ 중 %d$1ê°œ ì¼ì¹˜."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "íŒŒì¼ %d$2ê°œ 중 %d$1ê°œ ì¼ì¹˜."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "íŒŒì¼ %d$2ê°œ 중 %d$1ê°œ ì¼ì¹˜."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4031,6 +4050,21 @@ msgstr "`post_import()` 메소드ì—서 Nodeì—서 ìƒì†ë°›ì€ ê°ì²´ë¥¼ 반환
msgid "Saving..."
msgstr "저장 중..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "모드 ì„ íƒ"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "가져오기"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "기본 sRGB 사용"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "íŒŒì¼ %dê°œ"
@@ -4994,8 +5028,8 @@ msgid "Got:"
msgstr "ë°›ìŒ:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "sha256 해시 í™•ì¸ ì‹¤íŒ¨"
+msgid "Failed SHA-256 hash check"
+msgstr "SHA-256 해시 í™•ì¸ ì‹¤íŒ¨"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5098,7 +5132,6 @@ msgid "Sort:"
msgstr "ì •ë ¬:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "카테고리:"
@@ -5129,12 +5162,10 @@ msgstr "ì• ì…‹ ZIP 파ì¼"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"ë¼ì´íŠ¸ë§µ ì´ë¯¸ì§€ì˜ 저장 경로를 파악할 수 없습니다.\n"
-"(ê°™ì€ ê²½ë¡œì— ì´ë¯¸ì§€ë¥¼ 저장할 수 있ë„ë¡) ì”¬ì„ ì €ìž¥í•˜ê±°ë‚˜, BakedLightmap ì†ì„±ì—"
-"서 저장 경로를 지정하세요."
+"ë¼ì´íŠ¸ë§µ ì´ë¯¸ì§€ë¥¼ 위한 저장 경로를 ê²°ì •í•  수 없습니다.\n"
+"ë‹¹ì‹ ì˜ ì”¬ì„ ì €ìž¥í•˜ê³  다시 시ë„하세요."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5149,9 +5180,33 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "ë¼ì´íŠ¸ë§µ ì´ë¯¸ì§€ ìƒì„± 실패. 작성 가능한 경로ì¸ì§€ 확ì¸í•´ì£¼ì„¸ìš”."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"ë¼ì´íŠ¸ë§µ í¬ê¸°ë¥¼ 결정하는 ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤. 최대 ë¼ì´íŠ¸ë§µ í¬ê¸°ê°€ 너무 작나요?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"ì¼ë¶€ 메시가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤. UV2 ì±„ë„ ê°’ì´ [0.0,1.0] 정사ê°í˜• ì˜ì—­ ì•ˆì— í¬í•¨ë˜"
+"ì–´ 있는지 확ì¸í•´ì£¼ì„¸ìš”."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Godot 편집기가 ë ˆì´ íŠ¸ë ˆì´ì‹± ì§€ì› ì—†ì´ ë¹Œë“œë˜ì–´ 있어, ë¼ì´íŠ¸ë§µì´ êµ¬ì›Œì§ˆ 수 ì—†"
+"습니다."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "ë¼ì´íŠ¸ë§µ 굽기"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "ë¼ì´íŠ¸ë§µì„ êµ¬ìš¸ íŒŒì¼ ì„ íƒ:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5219,50 +5274,43 @@ 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
-#, fuzzy
msgid "Rotate %d CanvasItems"
-msgstr "CanvasItem 회전"
+msgstr "CanvasItem %d개 회전"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate CanvasItem \"%s\" to %d degrees"
-msgstr "CanvasItem 회전"
+msgstr "CanvasItem \"%s\"를 %dë„로 회전"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" Anchor"
-msgstr "CanvasItem ì´ë™"
+msgstr "CanvasItem \"%s\" 앵커 ì´ë™"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale Node2D \"%s\" to (%s, %s)"
-msgstr ""
+msgstr "Node2D \"%s\"를 (%s, %s)로 í¬ê¸° ì¡°ì ˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Resize Control \"%s\" to (%d, %d)"
-msgstr ""
+msgstr "컨트롤 \"%s\"를 (%d, %d)로 í¬ê¸° ì¡°ì ˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale %d CanvasItems"
-msgstr "CanvasItem 규모"
+msgstr "CanvasItem %dê°œ í¬ê¸° ì¡°ì ˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale CanvasItem \"%s\" to (%s, %s)"
-msgstr "CanvasItem 규모"
+msgstr "CanvasItem \"%s\"를 (%s, %s)로 í¬ê¸° ì¡°ì ˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move %d CanvasItems"
-msgstr "CanvasItem ì´ë™"
+msgstr "CanvasItem %dê°œ ì´ë™"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" to (%d, %d)"
-msgstr "CanvasItem ì´ë™"
+msgstr "CanvasItem \"%s\"를 (%d, %d)로 ì´ë™"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5468,7 +5516,7 @@ msgstr "회전모드"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
-msgstr "í¬ê¸°ì¡°ì ˆ 모드"
+msgstr "í¬ê¸° ì¡°ì ˆ 모드"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5517,7 +5565,7 @@ msgstr "회전 스냅 사용"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Scale Snap"
-msgstr "스마트 스냅 사용"
+msgstr "í¬ê¸° ì¡°ì ˆ 스냅 사용"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
@@ -5635,11 +5683,11 @@ msgstr "ì„ íƒ í•­ëª© 중앙으로"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
-msgstr "ì„ íƒ í•­ëª© ì „ì²´ 화면으로"
+msgstr "프레임 ì„ íƒ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
-msgstr "캔버스 규모 미리 보기"
+msgstr "캔버스 í¬ê¸° ì¡°ì ˆ 미리 보기"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Translation mask for inserting keys."
@@ -5901,7 +5949,7 @@ msgstr "기울기 편집ë¨"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
-msgstr "항목 %d"
+msgstr "항목 %d개"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Items"
@@ -6241,6 +6289,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "ParticlesMaterial 프로세스 머티리얼 안ì—ë§Œ ì ì„ 설정할 수 있습니다"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "CPUParticles2D로 변환"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "ìƒì„± 시간 (ì´ˆ):"
@@ -6301,10 +6353,6 @@ msgstr "AABB 만드는 중"
msgid "Generate Visibility AABB"
msgstr "가시성 AABB 만들기"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "AABB 만들기"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "곡선ì—서 ì  ì‚­ì œ"
@@ -6530,18 +6578,16 @@ msgid "Move Points"
msgstr "ì  ì´ë™"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Command: Rotate"
-msgstr "드래그: 회전"
+msgstr "Command: 회전"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift: Move All"
msgstr "Shift: ëª¨ë‘ ì´ë™"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Shift+Command: Scale"
-msgstr "Shift+Ctrl: í¬ê¸° ì¡°ì ˆ"
+msgstr "Shift+Command: í¬ê¸° ì¡°ì ˆ"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Ctrl: Rotate"
@@ -6588,14 +6634,12 @@ msgid "Radius:"
msgstr "반지름:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Copy Polygon to UV"
-msgstr "í´ë¦¬ê³¤ & UV 만들기"
+msgstr "í´ë¦¬ê³¤ì„ UV로 복사"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Copy UV to Polygon"
-msgstr "Polygon2D로 변환"
+msgstr "UV를 í´ë¦¬ê³¤ìœ¼ë¡œ 복사"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Clear UV"
@@ -6854,7 +6898,7 @@ msgstr "ëª¨ë‘ ì €ìž¥"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
-msgstr "스í¬ë¦½íЏ 새로고침"
+msgstr "스í¬ë¦½íЏ ì¼ë°˜ 새로고침"
#: editor/plugins/script_editor_plugin.cpp
msgid "Copy Script Path"
@@ -6897,6 +6941,14 @@ msgstr "문서 닫기"
msgid "Run"
msgstr "실행"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "검색"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "프로시저 단위 실행"
@@ -6950,16 +7002,6 @@ msgstr ""
"해당 파ì¼ì€ 디스í¬ì— 있는 게 ë” ìµœì‹ ìž…ë‹ˆë‹¤.\n"
"어떻게 할 건가요?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "새로고침"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "다시 저장"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "디버거"
@@ -7055,8 +7097,8 @@ msgstr "중단ì "
msgid "Go To"
msgstr "ì´ë™"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "잘ë¼ë‚´ê¸°"
@@ -7083,7 +7125,7 @@ msgstr "ì£¼ì„ í† ê¸€"
#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
-msgstr "행 펼치기/접기"
+msgstr "행 접기/펼치기"
#: editor/plugins/script_text_editor.cpp
msgid "Fold All Lines"
@@ -7127,7 +7169,7 @@ msgstr "파ì¼ì—서 찾기..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
-msgstr "ìƒí™©ì— 맞는 ë„움"
+msgstr "ìƒí™©ì— 맞는 ë„움ë§"
#: editor/plugins/script_text_editor.cpp
msgid "Toggle Bookmark"
@@ -7143,7 +7185,7 @@ msgstr "ì´ì „ ë¶ë§ˆí¬ë¡œ ì´ë™"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Bookmarks"
-msgstr "모든 ë¶ë§ˆí¬ ì‚­ì œ"
+msgstr "모든 ë¶ë§ˆí¬ 제거"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function..."
@@ -7160,7 +7202,7 @@ msgstr "ì¤‘ë‹¨ì  í† ê¸€"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Breakpoints"
-msgstr "ì¤‘ë‹¨ì  ëª¨ë‘ ì‚­ì œ"
+msgstr "ì¤‘ë‹¨ì  ëª¨ë‘ ì œê±°"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Next Breakpoint"
@@ -7279,6 +7321,10 @@ msgid "Yaw"
msgstr "ìš”"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "í¬ê¸°"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "그려진 ê°ì²´"
@@ -7504,7 +7550,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Local Space"
-msgstr "로컬 스페ì´ìФ 사용"
+msgstr "로컬 공간 사용"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
@@ -7561,7 +7607,7 @@ msgstr "변형"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Object to Floor"
-msgstr "ê°ì²´ë¥¼ ë°”ë‹¥ì— ìŠ¤ëƒ…"
+msgstr "개체를 ë°”ë‹¥ì— ìŠ¤ëƒ…"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
@@ -7774,7 +7820,7 @@ msgstr "ì„ íƒí•œ 프레임 ì—†ìŒ"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add %d Frame(s)"
-msgstr "%dê°œì˜ í”„ë ˆìž„ 추가"
+msgstr "프레임 %d개 추가"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
@@ -7821,9 +7867,8 @@ msgid "New Animation"
msgstr "새 애니메ì´ì…˜"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Speed:"
-msgstr "ì†ë„ (FPS):"
+msgstr "ì†ë„:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Loop"
@@ -8081,7 +8126,7 @@ msgstr "테마 파ì¼"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase Selection"
-msgstr "ì„ íƒ ì§€ìš°ê¸°"
+msgstr "ì„ íƒ í•­ëª© 지우기"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Fix Invalid Tiles"
@@ -8141,13 +8186,12 @@ msgid "Paint Tile"
msgstr "íƒ€ì¼ ì¹ í•˜ê¸°"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid ""
"Shift+LMB: Line Draw\n"
"Shift+Command+LMB: Rectangle Paint"
msgstr ""
-"Shift+ìš°í´ë¦­: ì„  그리기\n"
-"Shift+Ctrl+ìš°í´ë¦­: ì‚¬ê° ì˜ì—­ 페ì¸íЏ"
+"Shift+좌í´ë¦­: ì„  그리기\n"
+"Shift+Command+좌í´ë¦­: ì‚¬ê° ì˜ì—­ 페ì¸íЏ"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
@@ -8187,7 +8231,7 @@ msgstr "TileSetì— í…스처를 추가합니다."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove selected Texture from TileSet."
-msgstr "ì„ íƒí•œ í…스처를 TileSetì—서 ì‚­ì œ."
+msgstr "ì„ íƒí•œ í…스처를 TileSetì—서 제거합니다."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
@@ -8302,23 +8346,20 @@ msgid "Create a new rectangle."
msgstr "새로운 사ê°í˜•ì„ ë§Œë“­ë‹ˆë‹¤."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Rectangle"
-msgstr "ì‚¬ê° ì˜ì—­ 칠하기"
+msgstr "새 ì‚¬ê° ì˜ì—­"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create a new polygon."
msgstr "새로운 í´ë¦¬ê³¤ì„ 만듭니다."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Polygon"
-msgstr "í´ë¦¬ê³¤ ì´ë™"
+msgstr "새 í´ë¦¬ê³¤"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete Selected Shape"
-msgstr "ì„ íƒ í•­ëª© ì‚­ì œ"
+msgstr "ì„ íƒëœ 모양 ì‚­ì œ"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
@@ -8526,10 +8567,6 @@ msgid "Error"
msgstr "오류"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "커밋 메시지를 제공하지 않았습니다"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "스테ì´ì§€ì— ì¶”ê°€ëœ íŒŒì¼ì´ 없습니다"
@@ -8586,10 +8623,6 @@ msgid "Stage All"
msgstr "ëª¨ë‘ ìŠ¤í…Œì´ì§€ë¡œ 보내기"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "커밋 메시지 추가"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "커밋 변경 사항"
@@ -8687,7 +8720,6 @@ msgid "Add Node to Visual Shader"
msgstr "노드를 비주얼 ì…°ì´ë”ì— ì¶”ê°€"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node(s) Moved"
msgstr "노드 ì´ë™ë¨"
@@ -8709,9 +8741,8 @@ msgid "Visual Shader Input Type Changed"
msgstr "비주얼 ì…°ì´ë” ìž…ë ¥ 유형 변경ë¨"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "UniformRef Name Changed"
-msgstr "Uniform ì´ë¦„ 설정"
+msgstr "UniformRef ì´ë¦„ 변경ë¨"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
@@ -8892,7 +8923,7 @@ msgstr "ê¼­ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매ê
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr "ê¼­ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수."
+msgstr "프래그먼트과 조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment shader mode."
@@ -8985,7 +9016,7 @@ msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì—­ìŒê³¡íƒ„젠트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
-msgstr "매개변수보다 í¬ê±°ë‚˜ ê°™ì€ ê°€ìž¥ 가까운 정수를 찾아요."
+msgstr "매개변수보다 í¬ê±°ë‚˜ ê°™ì€ ê°€ìž¥ 가까운 정수를 찾습니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Constrains a value to lie between two further values."
@@ -9013,7 +9044,7 @@ msgstr "2ê°€ ë°‘ì¸ ì§€ìˆ˜ 함수."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer less than or equal to the parameter."
-msgstr "매개변수보다 ì ê±°ë‚˜ ê°™ì€ ê°€ìž¥ 가까운 정수를 찾아요."
+msgstr "매개변수보다 ì ê±°ë‚˜ ê°™ì€ ê°€ìž¥ 가까운 정수를 찾습니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Computes the fractional part of the argument."
@@ -9066,11 +9097,11 @@ msgstr "1.0 / 스칼ë¼"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer to the parameter."
-msgstr "매개변수ì—서 가장 가까운 정수를 찾아요."
+msgstr "매개변수ì—서 가장 가까운 정수를 찾습니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest even integer to the parameter."
-msgstr "매개변수ì—서 가장 가까운 ì§ìˆ˜ 정수를 찾아요."
+msgstr "매개변수ì—서 가장 가까운 ì§ìˆ˜ 정수를 찾습니다."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
@@ -9709,8 +9740,8 @@ msgid ""
"Couldn't load project.godot in project path (error %d). It may be missing or "
"corrupted."
msgstr ""
-"프로ì íЏ 경로ì—서 project.godotì„ ë¶ˆëŸ¬ì˜¬ 수 없습니다 (error %d). 누ë½ë˜ê±°ë‚˜ "
-"ì†ìƒëœ 모양입니다."
+"프로ì íЏ 경로ì—서 project.godotì„ ë¶ˆëŸ¬ì˜¬ 수 없습니다 (오류 %d). 누ë½ë˜ê±°ë‚˜ ì†"
+"ìƒëœ 모양입니다."
#: editor/project_manager.cpp
msgid "Couldn't edit project.godot in project path."
@@ -9770,7 +9801,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "ë‹¹ì‹ ì˜ GPU 드ë¼ì´ë²„ì— ì˜í•´ ì§€ì›ë˜ì§€ 않습니다."
#: editor/project_manager.cpp
msgid ""
@@ -9942,6 +9973,10 @@ msgid "Projects"
msgstr "프로ì íЏ"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "로드 중, 기다려 주세요..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "마지막으로 수정ë¨"
@@ -10311,6 +10346,11 @@ msgstr "오토로드"
msgid "Plugins"
msgstr "플러그ì¸(Plugin)"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "기본값 불러오기"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "프리셋..."
@@ -10389,7 +10429,7 @@ msgstr "ì •ê·œ í‘œí˜„ì‹ ì‚¬ìš©"
#: editor/rename_dialog.cpp
msgid "Advanced Options"
-msgstr "고급 설정"
+msgstr "고급 옵션"
#: editor/rename_dialog.cpp
msgid "Substitute"
@@ -10421,7 +10461,7 @@ msgid ""
"Compare counter options."
msgstr ""
"순차 정수 카운터.\n"
-"ì¹´ìš´í„° 설정과 비êµí•©ë‹ˆë‹¤."
+"ì¹´ìš´í„° 옵션과 비êµí•©ë‹ˆë‹¤."
#: editor/rename_dialog.cpp
msgid "Per-level Counter"
@@ -10558,6 +10598,14 @@ msgid "Instance Child Scene"
msgstr "ìžì‹ 씬 ì¸ìŠ¤í„´ìŠ¤í™”"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "루트 노드를 ê°™ì€ ì”¬ 안으로 ë¶™ì—¬ë„£ì„ ìˆ˜ 없습니다."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "노드 붙여넣기"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "스í¬ë¦½íЏ 떼기"
@@ -10683,6 +10731,10 @@ msgid "Attach Script"
msgstr "스í¬ë¦½íЏ ë¶™ì´ê¸°"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "노드 잘ë¼ë‚´ê¸°"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "노드 삭제"
@@ -11485,6 +11537,34 @@ msgstr "메시 필터"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "메시를 사용하려면 ì´ GridMapì— MeshLibrary 리소스를 주세요."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "굽기 시작"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "ë°ì´í„° 구조 준비 중"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "ë²„í¼ ìƒì„±"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "조명 방향"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "간접 조명"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "후처리"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "구분하는 조명"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "í´ëž˜ìФ ì´ë¦„ì€ í‚¤ì›Œë“œê°€ ë  ìˆ˜ 없습니다"
@@ -11495,11 +11575,11 @@ msgstr "ë‚´ë¶€ 예외 ìŠ¤íƒ ì¶”ì ì˜ ë"
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Bake NavMesh"
-msgstr "NavMesh ë² ì´í¬"
+msgstr "NavMesh 굽기"
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Clear the navigation mesh."
-msgstr "내비게ì´ì…˜ 메시 지우기."
+msgstr "내비게ì´ì…˜ 메시를 ì§€ì›ë‹ˆë‹¤."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Setting up Configuration..."
@@ -11996,12 +12076,16 @@ msgid "Select device from the list"
msgstr "목ë¡ì—서 기기 ì„ íƒ"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "ADB 실행 파ì¼ì„ 편집기 설정ì—서 설정하지 않았습니다."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "'apksigner' ë„구를 ì°¾ì„ ìˆ˜ 없습니다."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner를 편집기 설정ì—서 설정하지 않았습니다."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"프로ì íŠ¸ì— Android 빌드 í…œí”Œë¦¿ì„ ì„¤ì¹˜í•˜ì§€ 않았습니다. 프로ì íЏ 메뉴ì—서 설치"
+"하세요."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12012,24 +12096,32 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "내보내기 í”„ë¦¬ì…‹ì— ë°°í¬ keystorkeê°€ 잘못 설정ë˜ì–´ 있습니다."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr "맞춤 빌드ì—는 편집기 설정ì—서 올바른 안드로ì´ë“œ SDK 경로가 필요합니다."
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "편집기 설정ì—서 올바른 Android SDK 경로가 필요합니다."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr "편집기 설정ì—서 맞춤 ë¹Œë“œì— ìž˜ëª»ëœ ì•ˆë“œë¡œì´ë“œ SDK 경로입니다."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "편집기 설정ì—서 ìž˜ëª»ëœ Android SDK 경로입니다."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
-msgstr ""
+msgstr "'platform-tools' 디렉터리가 없습니다!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
-msgstr ""
-"프로ì íŠ¸ì— ì•ˆë“œë¡œì´ë“œ 빌드 í…œí”Œë¦¿ì„ ì„¤ì¹˜í•˜ì§€ 않았습니다. 프로ì íЏ 메뉴ì—서 설"
-"치하세요."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "Android SDK platform-toolsì˜ adb ëª…ë ¹ì„ ì°¾ì„ ìˆ˜ 없습니다."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr "편집기 설정ì—서 ì§€ì •ëœ Android SDK 디렉터리를 확ì¸í•´ì£¼ì„¸ìš”."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "'build-tools' 디렉터리가 없습니다!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "Android SDK build-toolsì˜ apksigner ëª…ë ¹ì„ ì°¾ì„ ìˆ˜ 없습니다."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12093,8 +12185,8 @@ msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
-"맞춤 빌드 템플릿으로 빌드하려 했으나, 버전 정보가가 없습니다. '프로ì íЏ' 메뉴"
-"ì—서 다시 설치해주세요."
+"맞춤 빌드 템플릿으로 빌드하려 했으나, 버전 ì •ë³´ê°€ 없습니다. '프로ì íЏ' 메뉴ì—"
+"서 다시 설치해주세요."
#: platform/android/export/export.cpp
msgid ""
@@ -12103,32 +12195,34 @@ msgid ""
" Godot Version: %s\n"
"Please reinstall Android build template from 'Project' menu."
msgstr ""
-"안드로ì´ë“œ 빌드 ë²„ì „ì´ ë§žì§€ 않ìŒ:\n"
-" 설치한 템플릿: %s\n"
+"Android 빌드 ë²„ì „ì´ ë§žì§€ 않ìŒ:\n"
+" ì„¤ì¹˜ëœ í…œí”Œë¦¿: %s\n"
" Godot 버전: %s\n"
-"'프로ì íЏ' 메뉴ì—서 안드로ì´ë“œ 빌드 í…œí”Œë¦¿ì„ ë‹¤ì‹œ 설치해주세요."
+"'프로ì íЏ' 메뉴ì—서 Android 빌드 í…œí”Œë¦¿ì„ ë‹¤ì‹œ 설치해주세요."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr "안드로ì´ë“œ 프로ì íЏ 빌드 중 (gradle)"
+msgstr "Android 프로ì íЏ 빌드 중 (gradle)"
#: platform/android/export/export.cpp
msgid ""
"Building of Android project failed, check output for the error.\n"
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
-"안드로ì´ë“œ 프로ì íŠ¸ì˜ ë¹Œë“œì— ì‹¤íŒ¨í–ˆ, 출력한 오류를 확ì¸í•˜ì„¸ìš”.\n"
-"ë˜ëŠ” docs.godotengine.orgì—서 안드로ì´ë“œ 빌드 문서를 찾아 보세요."
+"Android 프로ì íŠ¸ì˜ ë¹Œë“œì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤, ì¶œë ¥ëœ ì˜¤ë¥˜ë¥¼ 확ì¸í•˜ì„¸ìš”.\n"
+"ë˜ëŠ” docs.godotengine.orgì—서 Andoid 빌드 문서를 찾아보세요."
#: platform/android/export/export.cpp
msgid "Moving output"
-msgstr ""
+msgstr "출력 ì´ë™ 중"
#: platform/android/export/export.cpp
msgid ""
"Unable to copy and rename export file, check gradle project directory for "
"outputs."
msgstr ""
+"내보내기 파ì¼ì„ 복사하고 ì´ë¦„ì„ ë°”ê¿€ 수 없습니다, ì¶œë ¥ì— ëŒ€í•œ gradle 프로ì "
+"트 디렉터리를 확ì¸í•˜ì„¸ìš”."
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
@@ -12278,6 +12372,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "빈 CollisionPolygon2D는 ì¶©ëŒì— ì˜í–¥ì„ 주지 않습니다."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12314,23 +12416,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "노드 A와 노드 B는 PhysicsBody2D여야 합니다"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "노드 A는 PhysicsBody2D여야 합니다"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "노드 B는 PhysicsBody2D여야 합니다"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "ê´€ì ˆì´ PhysicsBody2D ë‘ ê³³ê³¼ ì—°ê²°ë˜ì–´ 있지 않습니다"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "노드 A와 노드 B는 서로 다른 PhysicsBody2D여야 합니다"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12478,28 +12580,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROriginì€ ìžì‹ìœ¼ë¡œ ARVRCamera 노드가 필요합니다."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "메시 ë° ì¡°ëª… 찾는 중"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(ë‚¨ì€ ì‹œê°„: %d:%02d ì´ˆ)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "형태 준비 중 (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "구분하는 메시: "
+msgid "Preparing environment"
+msgstr "환경 준비 중"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "구분하는 조명:"
+msgid "Generating capture"
+msgstr "캡처 ìƒì„± 중"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "구분 ë남"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "ë¼ì´íŠ¸ë§µ 저장 중"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "조명 메시: "
+msgid "Done"
+msgstr "완료"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12575,6 +12677,10 @@ msgid "Plotting Meshes"
msgstr "메시 구분"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "구분 ë남"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12582,11 +12688,6 @@ msgstr ""
"GIProbe는 GLES2 비디오 드ë¼ì´ë²„ì—서 ì§€ì›í•˜ì§€ 않습니다.\n"
"대신 BakedLightmapì„ ì‚¬ìš©í•˜ì„¸ìš”."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera는 ë” ì´ìƒ 사용ë˜ì§€ 않으며 Godot 4.0ì—서 제거ë©ë‹ˆë‹¤."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLightì˜ ê°ë„를 90ë„ ì´ìƒìœ¼ë¡œ 잡게ë˜ë©´ 그림ìžë¥¼ 투ì˜í•  수 없습니다."
@@ -12651,23 +12752,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "노드 A와 노드 B는 PhysicsBody여야 합니다"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "노드 A는 PhysicsBody여야 합니다"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "노드 B는 PhysicsBodies여야 합니다"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "ê´€ì ˆì´ ì–´ë– í•œ PhysicsBodyì—ë„ ì—°ê²°ë˜ì–´ 있지 않습니다"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "노드 A와 노드 B는 서로 다른 PhysicsBody여야 합니다"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12827,6 +12928,14 @@ msgstr "경고!"
msgid "Please Confirm..."
msgstr "확ì¸í•´ì£¼ì„¸ìš”..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "올바른 확장ìžë¥¼ 사용해야 합니다."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "그리드 ë¯¸ë‹ˆë§µì„ í™œì„±í™”í•©ë‹ˆë‹¤."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12879,6 +12988,14 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "무엇ì´ë“  ë Œë”ë§í•˜ë ¤ë©´ ë·°í¬íЏ í¬ê¸°ê°€ 0보다 커야 합니다."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"샘플러 í¬íŠ¸ê°€ ì—°ê²°ë˜ì–´ 있지만 사용ë˜ì§€ 않습ì´ë‹¤. 소스를 'SamplerPort'로 변경"
+"하는 ê²ƒì„ ê³ ë ¤í•´ì£¼ì„¸ìš”."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "미리 ë³´ê¸°ì— ìž˜ëª»ëœ ì†ŒìŠ¤."
@@ -12906,6 +13023,48 @@ msgstr "Varyingì€ ê¼­ì§“ì  í•¨ìˆ˜ì—ë§Œ 지정할 수 있습니다."
msgid "Constants cannot be modified."
msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "InterpolatedCamera는 ë” ì´ìƒ 사용ë˜ì§€ 않으며 Godot 4.0ì—서 제거ë©ë‹ˆë‹¤."
+
+#~ msgid "No"
+#~ msgstr "아니오"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "ì´ ì”¬ì€ ì•„ì§ ì €ìž¥í•˜ì§€ 않았습니다. 실행하기 ì „ì— ì €ìž¥í• ê¹Œìš”?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "ADB 실행 파ì¼ì„ 편집기 설정ì—서 설정하지 않았습니다."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner를 편집기 설정ì—서 설정하지 않았습니다."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "맞춤 빌드ì—는 편집기 설정ì—서 올바른 안드로ì´ë“œ SDK 경로가 필요합니다."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(ë‚¨ì€ ì‹œê°„: %d:%02d ì´ˆ)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "구분하는 메시: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "조명 메시: "
+
+#~ msgid "Search complete"
+#~ msgstr "검색 완료"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "커밋 메시지를 제공하지 않았습니다"
+
+#~ msgid "Add a commit message"
+#~ msgstr "커밋 메시지 추가"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "ì´ ìœ„ì¹˜ì—는 ê°™ì€ ì´ë¦„ì˜ íŒŒì¼ì´ë‚˜ í´ë”ê°€ 있습니다."
@@ -13236,9 +13395,6 @@ msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
#~ msgid "Failed to save solution."
#~ msgstr "솔루션 저장 실패."
-#~ msgid "Done"
-#~ msgstr "완료"
-
#~ msgid "Failed to create C# project."
#~ msgstr "C# 프로ì íЏ ìƒì„± 실패."
@@ -14658,9 +14814,6 @@ msgstr "ìƒìˆ˜ëŠ” 수정할 수 없습니다."
#~ msgid "Use Default Light"
#~ msgstr "기본 Light 사용"
-#~ msgid "Use Default sRGB"
-#~ msgstr "기본 sRGB 사용"
-
#~ msgid "Default Light Normal:"
#~ msgstr "기본 ë¼ì´íЏ ë…¸ë§:"
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index 6dafdd84e0..585e4d4447 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -1,16 +1,16 @@
# Lithuanian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Ignas Kiela <ignaskiela@super.lt>, 2017.
# Kornelijus <kornelijus.github@gmail.com>, 2017, 2018.
# Ignotas Gražys <ignotas.gr@gmail.com>, 2020.
-# Kornelijus TvarijanaviÄius <kornelitvari@protonmail.com>, 2020.
+# Kornelijus TvarijanaviÄius <kornelitvari@protonmail.com>, 2020, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-09-28 11:18+0000\n"
+"PO-Revision-Date: 2021-02-21 10:51+0000\n"
"Last-Translator: Kornelijus TvarijanaviÄius <kornelitvari@protonmail.com>\n"
"Language-Team: Lithuanian <https://hosted.weblate.org/projects/godot-engine/"
"godot/lt/>\n"
@@ -20,7 +20,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n%10>=2 && (n%100<10 || n"
"%100>=20) ? 1 : n%10==0 || (n%100>10 && n%100<20) ? 2 : 3;\n"
-"X-Generator: Weblate 4.3-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -650,7 +650,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1854,8 +1854,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1948,10 +1948,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2365,6 +2361,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2409,18 +2409,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2469,6 +2457,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2512,7 +2504,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2909,14 +2901,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3070,6 +3054,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3279,7 +3279,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3838,7 +3838,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3978,6 +3986,20 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Pasirinkite Nodus, kuriuos norite importuoti"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importuoti Animacijas..."
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -4762,7 +4784,6 @@ msgstr "Naujas pavadinimas:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/multimesh_editor_plugin.cpp
-#, fuzzy
msgid "Scale:"
msgstr "SkalÄ—:"
@@ -4964,7 +4985,7 @@ msgid "Got:"
msgstr "Gauta:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5073,7 +5094,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategorija:"
@@ -5105,8 +5125,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5120,9 +5139,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Pasirinkite Nodus, kuriuos norite importuoti"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6200,6 +6239,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Keisti Poligono SkalÄ™"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6260,10 +6304,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6868,6 +6908,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6919,16 +6967,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7025,8 +7063,8 @@ msgstr "Sukurti"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7249,6 +7287,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8520,10 +8562,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8585,10 +8623,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9869,6 +9903,11 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Atsiųsti"
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10231,6 +10270,10 @@ msgstr ""
msgid "Plugins"
msgstr "Priedai"
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10478,6 +10521,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Duplikuoti"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Atidaryti Skriptų Editorių"
@@ -10602,6 +10654,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Transition Nodas"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11409,6 +11466,35 @@ msgstr "Filtrai..."
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Aprašymas:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11920,11 +12006,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11936,11 +12024,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11948,9 +12036,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12182,6 +12280,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12348,27 +12454,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12428,14 +12534,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12648,6 +12753,14 @@ msgstr "Įspėjimas!"
msgid "Please Confirm..."
msgstr "Prašome Patvirtinti..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12689,6 +12802,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Netinkamas šrifto dydis."
@@ -12762,10 +12881,6 @@ msgstr ""
#~ msgid "Path to Node:"
#~ msgstr "Kelias iki Nodo:"
-#, fuzzy
-#~ msgid "Custom Node"
-#~ msgstr "Transition Nodas"
-
#~ msgid "Line:"
#~ msgstr "Linija:"
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index 64a29939e9..5512d59238 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -1,6 +1,6 @@
# Latvian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Gustavs Porietis (pg829-) <porietisgustavs@gmail.com>, 2018.
# Martch Zagorski <martchzagorski@gmail.com>, 2018, 2020.
@@ -649,7 +649,7 @@ msgstr "Izvēlēties Celiņus ko Kopēt"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopēt"
@@ -1841,8 +1841,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1933,10 +1933,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2340,6 +2336,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2383,18 +2383,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2443,6 +2431,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2485,7 +2477,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2875,14 +2867,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3036,6 +3020,23 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr "Sekojošie faili netika izvilkti no paketes:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3238,7 +3239,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3774,8 +3775,19 @@ msgid "Searching..."
msgstr "Meklē..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr ""
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d sakritības."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d sakritības."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d sakritības."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -3911,6 +3923,20 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Izvēlēties Šablona Failu"
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "IelÄdÄ“t NoklusÄ“jumu"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d FailÄ"
@@ -4858,7 +4884,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4962,7 +4988,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4993,8 +5018,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5008,9 +5032,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Izvēlēties Šablona Failu"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6066,6 +6110,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Izveidot"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6126,10 +6175,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6719,6 +6764,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6770,16 +6823,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6876,8 +6919,8 @@ msgstr "Izveidot"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7103,6 +7146,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8356,10 +8403,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8422,10 +8465,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Nomainīt"
@@ -9689,6 +9728,11 @@ msgid "Projects"
msgstr "Projekta DibinÄtÄji"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "IelÄdÄ“t..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10051,6 +10095,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "IelÄdÄ“t NoklusÄ“jumu"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10296,6 +10345,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Dublicēt atslēgvietnes"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Galvenais Skripts:"
@@ -10419,6 +10477,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Dublicēt atslēgvietnes"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11216,6 +11279,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11719,11 +11810,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11735,11 +11828,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11747,9 +11840,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11980,6 +12083,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12146,27 +12257,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12226,14 +12337,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12440,6 +12550,14 @@ msgstr "BrÄ«dinÄjums!"
msgid "Please Confirm..."
msgstr "Lūdzu Apstipriniet..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12481,6 +12599,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Nederīgs fonta izmērs."
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index df5a0dcf55..260543a475 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -1,6 +1,6 @@
-# LANGUAGE translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# MÄori translation of the Godot Engine editor
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# follower <follower@rancidbacon.com>, 2019.
msgid ""
@@ -619,7 +619,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1788,8 +1788,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1880,10 +1880,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2287,6 +2283,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2330,18 +2330,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2389,6 +2377,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2431,7 +2423,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2821,14 +2813,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2982,6 +2966,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3184,7 +3184,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3720,7 +3720,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3857,6 +3865,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4804,7 +4824,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4908,7 +4928,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4939,8 +4958,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4954,9 +4972,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6012,6 +6049,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6072,10 +6113,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6657,6 +6694,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6708,16 +6753,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6810,8 +6845,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7032,6 +7067,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8243,10 +8282,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8303,10 +8338,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9560,6 +9591,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9920,6 +9955,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10163,6 +10202,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10283,6 +10330,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11067,6 +11118,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11562,11 +11641,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11578,11 +11659,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11590,9 +11671,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11817,6 +11908,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -11983,27 +12082,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12063,14 +12162,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12276,6 +12374,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12317,6 +12423,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/mk.po b/editor/translations/mk.po
new file mode 100644
index 0000000000..cd72ecd259
--- /dev/null
+++ b/editor/translations/mk.po
@@ -0,0 +1,12464 @@
+# Macedonian translation of the Godot Engine editor
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
+# This file is distributed under the same license as the Godot source code.
+#
+# Kristijan Fremen Velkovski <me@krisfremen.com>, 2021.
+msgid ""
+msgstr ""
+"Project-Id-Version: Godot Engine editor\n"
+"PO-Revision-Date: 2021-01-22 10:21+0000\n"
+"Last-Translator: Kristijan Fremen Velkovski <me@krisfremen.com>\n"
+"Language-Team: Macedonian <https://hosted.weblate.org/projects/godot-engine/"
+"godot/mk/>\n"
+"Language: mk\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+"Plural-Forms: nplurals=2; plural=n==1 || n%10==1 ? 0 : 1;\n"
+"X-Generator: Weblate 4.5-dev\n"
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Invalid type argument to convert(), use TYPE_* constants."
+msgstr "Погрешен тип на аргумент до convert(), кориÑтите TYPE_* конÑтанти."
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+msgid "Expected a string of length 1 (a character)."
+msgstr "Очекува Ñтринг од должина 1 (карактер)."
+
+#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
+#: modules/mono/glue/gd_glue.cpp
+#: modules/visual_script/visual_script_builtin_funcs.cpp
+msgid "Not enough bytes for decoding bytes, or invalid format."
+msgstr "Ðема доволно бајти за декодирање бајтови, или невалиден формат."
+
+#: core/math/expression.cpp
+msgid "Invalid input %i (not passed) in expression"
+msgstr "Ðевалидено внеÑување %i (не додадено) во израз"
+
+#: core/math/expression.cpp
+msgid "self can't be used because instance is null (not passed)"
+msgstr "self неможе да Ñе кориÑти зашто инÑтанцата е нула(не дадена)"
+
+#: core/math/expression.cpp
+msgid "Invalid operands to operator %s, %s and %s."
+msgstr "Ðевалиден операнд на операторите %s, %s и %s."
+
+#: core/math/expression.cpp
+msgid "Invalid index of type %s for base type %s"
+msgstr "Ðевалиден Ð¸Ð½Ð´ÐµÐºÑ Ð¾Ð´ тип %s за оÑновен тип %s"
+
+#: core/math/expression.cpp
+msgid "Invalid named index '%s' for base type %s"
+msgstr "Ðевалиден именуван Ð¸Ð½Ð´ÐµÐºÑ Ð¾Ð´ тип %s за оÑновен тип %s"
+
+#: core/math/expression.cpp
+msgid "Invalid arguments to construct '%s'"
+msgstr "Ðевалидни аргументи на конÑтрукт '%s'"
+
+#: core/math/expression.cpp
+msgid "On call to '%s':"
+msgstr "Ðа јавување до '%s':"
+
+#: core/ustring.cpp
+msgid "B"
+msgstr "Б"
+
+#: core/ustring.cpp
+msgid "KiB"
+msgstr "КиБ"
+
+#: core/ustring.cpp
+msgid "MiB"
+msgstr "МиБ"
+
+#: core/ustring.cpp
+msgid "GiB"
+msgstr "ГиБ"
+
+#: core/ustring.cpp
+msgid "TiB"
+msgstr "ТиБ"
+
+#: core/ustring.cpp
+msgid "PiB"
+msgstr "ПиБ"
+
+#: core/ustring.cpp
+msgid "EiB"
+msgstr "ЕиБ"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Free"
+msgstr "Слободно"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Balanced"
+msgstr "БаланÑирано"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Mirror"
+msgstr "Огледало"
+
+#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
+msgid "Time:"
+msgstr "Време:"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Value:"
+msgstr "ВредноÑÑ‚:"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Insert Key Here"
+msgstr "ВнеÑи клуч тука"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Duplicate Selected Key(s)"
+msgstr "Дуплирај избран(и) клуч(еви)"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Delete Selected Key(s)"
+msgstr "Избриши избран(и) клуч(еви)"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Add Bezier Point"
+msgstr "Додади Безиер Точка"
+
+#: editor/animation_bezier_editor.cpp
+msgid "Move Bezier Points"
+msgstr "ПромеÑти Безиер Точка"
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Duplicate Keys"
+msgstr "Дуплицирај клучеви"
+
+#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
+msgid "Anim Delete Keys"
+msgstr "Избриши Клучеви"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Time"
+msgstr "Ðнимација Промени Време на клучниот кадар"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transition"
+msgstr "Ðнимација Промени Прелаз"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Keyframe Value"
+msgstr "Ðнимација Промени Клучен Кадар ВредноÑÑ‚"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Change Call"
+msgstr "Ðнимација Промени Позив"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Time"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transition"
+msgstr "Ðнимација Многукратно Променување на Прелози"
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Transform"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Keyframe Value"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Multi Change Call"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Length"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation Loop"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Property Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "3D Transform Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Call Method Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Bezier Curve Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Playback Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Playback Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (frames)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation length (seconds)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation Looping"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Functions:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Audio Clips:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Clips:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Track Path"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle this track on/off."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Update Mode (How this property is set)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Interpolation Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove this track."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Time (s): "
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Toggle Track Enabled"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Continuous"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Discrete"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Trigger"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Capture"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Nearest"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
+#: editor/property_editor.cpp
+msgid "Linear"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Cubic"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clamp Loop Interp"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Wrap Loop Interp"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Key(s)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Key(s)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Update Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Interpolation Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Loop Mode"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Remove Anim Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Create NEW track for %s and insert key?"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Create %d NEW tracks and insert keys?"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/create_dialog.cpp
+#: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "AnimationPlayer can't animate itself, only other players."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Create & Insert"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Track & Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Insert Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Change Animation Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Rearrange Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Transform tracks only apply to Spatial-based nodes."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"Audio tracks can only point to nodes of type:\n"
+"-AudioStreamPlayer\n"
+"-AudioStreamPlayer2D\n"
+"-AudioStreamPlayer3D"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation tracks can only point to AnimationPlayer nodes."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "An animation player can't animate itself, only other players."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Not possible to add a new track without a root"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Invalid track for Bezier (no suitable sub-properties)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Bezier Track"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a key."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track is not of type Spatial, can't insert key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Transform Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Track path is invalid, so can't add a method key."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Add Method Track Key"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Method not found in object: "
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Move Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clipboard is empty"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Paste Tracks"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim Scale Keys"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This option does not work for Bezier editing, as it's only a single track."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid ""
+"This animation belongs to an imported scene, so changes to imported tracks "
+"will not be saved.\n"
+"\n"
+"To enable the ability to add custom tracks, navigate to the scene's import "
+"settings and set\n"
+"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks"
+"\", then re-import.\n"
+"Alternatively, use an import preset that imports animations to separate "
+"files."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Warning: Editing imported animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Select an AnimationPlayer node to create and edit animations."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Only show tracks from nodes selected in tree."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Group tracks by node or display them as plain list."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Snap:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Animation step value."
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Seconds"
+msgstr "Секунди"
+
+#: editor/animation_track_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "FPS"
+msgstr "ФПС"
+
+#: editor/animation_track_editor.cpp editor/editor_properties.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit"
+msgstr "Уреди"
+
+#: editor/animation_track_editor.cpp
+msgid "Animation properties."
+msgstr "СвојÑтва на анимацијата."
+
+#: editor/animation_track_editor.cpp
+msgid "Copy Tracks"
+msgstr "Копирај Траки"
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale From Cursor"
+msgstr ""
+
+#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Duplicate Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Duplicate Transposed"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Delete Selection"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Next Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Go to Previous Step"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Pick the node that will be animated:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Use Bezier Curves"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Anim. Optimizer"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Linear Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max. Angular Error:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Max Optimizable Angle:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Optimize"
+msgstr "Оптимизирај"
+
+#: editor/animation_track_editor.cpp
+msgid "Remove invalid keys"
+msgstr "Избриши невалидни клучеви"
+
+#: editor/animation_track_editor.cpp
+msgid "Remove unresolved and empty tracks"
+msgstr "Избриши нерешени и празни траки"
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-up all animations"
+msgstr "ИÑчиÑти Ñите анимации"
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up Animation(s) (NO UNDO!)"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Clean-Up"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Scale Ratio:"
+msgstr ""
+
+#: editor/animation_track_editor.cpp
+msgid "Select Tracks to Copy"
+msgstr ""
+
+#: editor/animation_track_editor.cpp editor/editor_log.cpp
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Copy"
+msgstr "Копирај"
+
+#: editor/animation_track_editor.cpp
+msgid "Select All/None"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Add Audio Track Clip"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip Start Offset"
+msgstr ""
+
+#: editor/animation_track_editor_plugins.cpp
+msgid "Change Audio Track Clip End Offset"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Resize Array"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value Type"
+msgstr ""
+
+#: editor/array_property_edit.cpp
+msgid "Change Array Value"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Go to Line"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line Number:"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "%d replaced."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d match."
+msgstr ""
+
+#: editor/code_editor.cpp editor/editor_help.cpp
+msgid "%d matches."
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Match Case"
+msgstr ""
+
+#: editor/code_editor.cpp editor/find_in_files.cpp
+msgid "Whole Words"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replace"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Replace All"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Selection Only"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
+#: editor/plugins/text_editor.cpp
+msgid "Standard"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Toggle Scripts Panel"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom In"
+msgstr ""
+
+#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Out"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Reset Zoom"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Warnings"
+msgstr ""
+
+#: editor/code_editor.cpp
+msgid "Line and column numbers."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Method in target node must be specified."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Method name must be a valid identifier."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Target method not found. Specify a valid method or attach a script to the "
+"target node."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Node:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect to Script:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "From Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Scene does not contain any script."
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
+#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+msgid "Add"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/editor_feature_profile.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp
+msgid "Remove"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Add Extra Call Argument:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Extra Call Arguments:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Receiver Method:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Advanced"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Deferred"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid ""
+"Defers the signal, storing it in a queue and only firing it at idle time."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Oneshot"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnects the signal after its first emission."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Cannot connect signal"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/dependency_editor.cpp
+#: editor/export_template_manager.cpp editor/groups_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/property_editor.cpp
+#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Close"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Signal:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect '%s' to '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect '%s' from '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect all from signal: '%s'"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Disconnect"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Connect a Signal to a Method"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit Connection:"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
+msgid "Signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Filter signals"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Are you sure you want to remove all connections from this signal?"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Disconnect All"
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Edit..."
+msgstr ""
+
+#: editor/connections_dialog.cpp
+msgid "Go To Method"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Change %s Type"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/project_settings_editor.cpp
+msgid "Change"
+msgstr ""
+
+#: editor/create_dialog.cpp
+msgid "Create New %s"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp
+msgid "Favorites:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_file_dialog.cpp
+msgid "Recent:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Matches:"
+msgstr ""
+
+#: editor/create_dialog.cpp editor/editor_plugin_settings.cpp
+#: editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/property_selector.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Description:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies For:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Scene '%s' is currently being edited.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Resource '%s' is in use.\n"
+"Changes will only take effect when reloaded."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resource"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp
+#: editor/project_manager.cpp editor/project_settings_editor.cpp
+msgid "Path"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Broken"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Dependency Editor"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Search Replacement Resource:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/property_selector.cpp editor/quick_open.cpp
+#: editor/script_create_dialog.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Open"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owners Of:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"Remove selected files from the project? (no undo)\n"
+"You can find the removed files in the system trash to restore them."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid ""
+"The files being removed are required by other resources in order for them to "
+"work.\n"
+"Remove them anyway? (no undo)\n"
+"You can find the removed files in the system trash to restore them."
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Cannot remove:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Error loading:"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Load failed due to missing dependencies:"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_node.cpp
+msgid "Open Anyway"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Which action should be taken?"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Fix Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Errors loading!"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Permanently delete %d item(s)? (No undo!)"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Show Dependencies"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Orphan Resource Explorer"
+msgstr ""
+
+#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/plugins/item_list_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
+#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
+msgid "Delete"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Owns"
+msgstr ""
+
+#: editor/dependency_editor.cpp
+msgid "Resources Without Explicit Ownership:"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Key"
+msgstr ""
+
+#: editor/dictionary_property_edit.cpp
+msgid "Change Dictionary Value"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Thanks from the Godot community!"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Godot Engine contributors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Project Founders"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Lead Developer"
+msgstr ""
+
+#. TRANSLATORS: This refers to a job title.
+#. The trailing space is used to distinguish with the project list application,
+#. you do not have to keep it in your translation.
+#: editor/editor_about.cpp
+msgid "Project Manager "
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Developers"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Authors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Platinum Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Silver Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Mini Sponsors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Gold Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Silver Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Bronze Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Donors"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "License"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Third-party Licenses"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid ""
+"Godot Engine relies on a number of third-party free and open source "
+"libraries, all compatible with the terms of its MIT license. The following "
+"is an exhaustive list of all such third-party components with their "
+"respective copyright statements and license terms."
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "All Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Components"
+msgstr ""
+
+#: editor/editor_about.cpp
+msgid "Licenses"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Error opening package file, not in ZIP format."
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "%s (Already Exists)"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Uncompressing Assets"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "The following files failed extraction from package:"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "And %s more files."
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/project_manager.cpp
+msgid "Package installed successfully!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Success!"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Contents:"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp editor/editor_node.cpp
+msgid "Install"
+msgstr ""
+
+#: editor/editor_asset_installer.cpp
+msgid "Package Installer"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Speakers"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Rename Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Change Audio Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Toggle Audio Bus Bypass Effects"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Select Audio Bus Send"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Bus Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Drag & drop to rearrange."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Solo"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Mute"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bypass"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Bus options"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Duplicate"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Effect"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Audio"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Master bus can't be deleted!"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Delete Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Duplicate Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Reset Bus Volume"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Move Audio Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save Audio Bus Layout As..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Location for New Layout..."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Open Audio Bus Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "There is no '%s' file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Layout"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Invalid file, not an audio bus layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Error saving file: %s"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add Bus"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Add a new Audio Bus to this layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Load"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load an existing Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save As"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Save this Bus Layout to a file."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp editor/import_dock.cpp
+msgid "Load Default"
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Load the default Bus Layout."
+msgstr ""
+
+#: editor/editor_audio_buses.cpp
+msgid "Create a new Bus Layout."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Invalid name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Valid characters:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing engine class name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing built-in type name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Must not collide with an existing global constant name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Keyword cannot be used as an autoload name."
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Autoload '%s' already exists!"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rename Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Toggle AutoLoad Globals"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Move Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Remove Autoload"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
+msgid "Enable"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Rearrange Autoloads"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Can't add autoload:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Add AutoLoad"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Path:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Node Name:"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
+#: editor/editor_profiler.cpp editor/project_manager.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Name"
+msgstr ""
+
+#: editor/editor_autoload_settings.cpp
+msgid "Singleton"
+msgstr ""
+
+#: editor/editor_data.cpp editor/inspector_dock.cpp
+msgid "Paste Params"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating Scene"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Storing local changes..."
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "Updating scene..."
+msgstr ""
+
+#: editor/editor_data.cpp editor/editor_properties.cpp
+msgid "[empty]"
+msgstr ""
+
+#: editor/editor_data.cpp
+msgid "[unsaved]"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Please select a base directory first."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose a Directory"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+#: scene/gui/file_dialog.cpp
+msgid "Create Folder"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
+#: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp
+msgid "Name:"
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
+#: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp
+msgid "Could not create folder."
+msgstr ""
+
+#: editor/editor_dir_dialog.cpp
+msgid "Choose"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Storing File:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "No export template found at the expected path:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "Packing"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
+"Etc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' texture compression for GLES3. Enable "
+"'Import Etc 2' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'PVRTC' texture compression for GLES2. Enable "
+"'Import Pvrtc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
+"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid ""
+"Target platform requires 'PVRTC' texture compression for the driver fallback "
+"to GLES2.\n"
+"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
+"Enabled'."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom debug template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/android/export/export.cpp
+#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
+#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+msgid "Custom release template not found."
+msgstr ""
+
+#: editor/editor_export.cpp platform/javascript/export/export.cpp
+msgid "Template file not found:"
+msgstr ""
+
+#: editor/editor_export.cpp
+msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "3D Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Script Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Asset Library"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Scene Tree Editing"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Node Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "FileSystem Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Dock"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase profile '%s'? (no undo)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile must be a valid filename and must not contain '.'"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Profile with this name already exists."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled, Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Properties Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "(Editor Disabled)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enable Contextual Editor"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Properties:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Features:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Enabled Classes:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "File '%s' format is invalid, import aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid ""
+"Profile '%s' already exists. Remove it first before importing, import "
+"aborted."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Error saving profile to path: '%s'."
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Unset"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Current Profile:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Make Current"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "New"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/editor_node.cpp
+#: editor/project_manager.cpp
+msgid "Import"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp editor/project_export.cpp
+msgid "Export"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Available Profiles:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Class Options"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "New profile name:"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Erase Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Godot Feature Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Import Profile(s)"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Export Profile"
+msgstr ""
+
+#: editor/editor_feature_profile.cpp
+msgid "Manage Editor Feature Profiles"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select Current Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File Exists, Overwrite?"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Select This Folder"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Copy Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "Open in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/filesystem_dock.cpp editor/project_manager.cpp
+msgid "Show in File Manager"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "New Folder..."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Refresh"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Recognized"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "All Files (*)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open File(s)"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Open a File or Directory"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/editor_node.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
+msgid "Save"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Save a File"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Back"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Forward"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Hidden Files"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Favorite"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Toggle Mode"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Focus Path"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Up"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Move Favorite Down"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to previous folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "Go to next folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Go to parent folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Refresh files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp
+msgid "(Un)favorite current folder."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Toggle the visibility of hidden files."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a grid of thumbnails."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
+msgid "View items as a list."
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "Directories & Files:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp
+#: editor/plugins/style_box_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Preview:"
+msgstr ""
+
+#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+msgid "File:"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "ScanSources"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid ""
+"There are multiple importers for different types pointing to file %s, import "
+"aborted"
+msgstr ""
+
+#: editor/editor_file_system.cpp
+msgid "(Re)Importing Assets"
+msgstr ""
+
+#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
+msgid "Top"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Class:"
+msgstr ""
+
+#: editor/editor_help.cpp editor/scene_tree_editor.cpp
+#: editor/script_create_dialog.cpp
+msgid "Inherits:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Inherited by:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Description"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Online Tutorials"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "override:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "default:"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Methods"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Theme Properties"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Enumerations"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Constants"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Property Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "(value)"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this property. Please help us by "
+"[color=$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid "Method Descriptions"
+msgstr ""
+
+#: editor/editor_help.cpp
+msgid ""
+"There is currently no description for this method. Please help us by [color="
+"$color][url=$url]contributing one[/url][/color]!"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/editor_node.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Help"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Case Sensitive"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Show Hierarchy"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Display All"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Classes Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Methods Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Signals Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Constants Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Theme Properties Only"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Member Type"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Class"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Method"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
+msgid "Signal"
+msgstr ""
+
+#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
+msgid "Constant"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Property"
+msgstr ""
+
+#: editor/editor_help_search.cpp
+msgid "Theme Property"
+msgstr ""
+
+#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
+msgid "Property:"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set"
+msgstr ""
+
+#: editor/editor_inspector.cpp
+msgid "Set Multiple:"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Output:"
+msgstr ""
+
+#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Copy Selection"
+msgstr ""
+
+#: editor/editor_log.cpp editor/editor_network_profiler.cpp
+#: editor/editor_profiler.cpp editor/editor_properties.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/property_editor.cpp editor/scene_tree_dock.cpp
+#: editor/script_editor_debugger.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Clear"
+msgstr ""
+
+#: editor/editor_log.cpp
+msgid "Clear Output"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp editor/editor_node.cpp
+#: editor/editor_profiler.cpp
+msgid "Stop"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
+#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
+msgid "Start"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "%s/s"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Down"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Up"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp editor/editor_node.cpp
+msgid "Node"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Incoming RPC"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Incoming RSET"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Outgoing RPC"
+msgstr ""
+
+#: editor/editor_network_profiler.cpp
+msgid "Outgoing RSET"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "New Window"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Imported resources can't be saved."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: scene/gui/dialogs.cpp
+msgid "OK"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Error saving resource!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource can't be saved because it does not belong to the edited scene. "
+"Make it unique first."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Save Resource As..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't open file for writing:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Requested file format unknown:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while saving."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Can't open '%s'. The file could have been moved or deleted."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while parsing '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unexpected end of file '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Missing '%s' or its dependencies."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error while loading '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saving Scene"
+msgstr "Зачувување на Ñцената"
+
+#: editor/editor_node.cpp
+msgid "Analyzing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Creating Thumbnail"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a tree root."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene can't be saved because there is a cyclic instancing inclusion.\n"
+"Please resolve it and then attempt to save again."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
+"be satisfied."
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "Can't overwrite scene that is still open!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load MeshLibrary for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving MeshLibrary!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't load TileSet for merging!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Error saving TileSet!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"An error occurred while trying to save the editor layout.\n"
+"Make sure the editor's user data path is writable."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Default editor layout overridden.\n"
+"To restore the Default layout to its base settings, use the Delete Layout "
+"option and delete the Default layout."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Layout name not found!"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Restored the Default layout to its base settings."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was imported, so it's not editable.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource belongs to a scene that was instanced or inherited.\n"
+"Changes to it won't be kept when saving the current scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This resource was imported, so it's not editable. Change its settings in the "
+"import panel and then re-import."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This scene was imported, so changes to it won't be kept.\n"
+"Instancing it or inheriting will allow making changes to it.\n"
+"Please read the documentation relevant to importing scenes to better "
+"understand this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This is a remote object, so changes to it won't be kept.\n"
+"Please read the documentation relevant to debugging to better understand "
+"this workflow."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "There is no defined scene to run."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Could not start subprocess!"
+msgstr ""
+
+#: editor/editor_node.cpp editor/filesystem_dock.cpp
+msgid "Open Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Base Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Open Script..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Close"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to '%s' before closing?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Saved %s modified resource(s)."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "A root node is required to save the scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene As..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/scene_tree_dock.cpp
+msgid "This operation can't be done without a scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Mesh Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a root node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Tile Set"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "This operation can't be done without a selected node."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Current scene not saved. Open anyway?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Can't reload a scene that was never saved."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reload Saved Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"The current scene has unsaved changes.\n"
+"Reload the saved scene anyway? This action cannot be undone."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quick Run Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Exit the editor?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save & Quit"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes to the following scene(s) before quitting?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save changes the following scene(s) before opening Project Manager?"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This option is deprecated. Situations where refresh must be forced are now "
+"considered a bug. Please report."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pick a Main Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Reopen Closed Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s'."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' There seems to be an error in "
+"the code, please check the syntax."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Scene '%s' was automatically imported, so it can't be modified.\n"
+"To make changes to it, a new inherited scene can be created."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Error loading scene, it must be inside the project path. Use 'Import' to "
+"open the scene, then save it inside the project path."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene '%s' has broken dependencies:"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Clear Recent Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"No main scene has ever been defined, select one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' does not exist, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"Selected scene '%s' is not a scene file, select a valid one?\n"
+"You can change it later in \"Project Settings\" under the 'application' "
+"category."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Delete Layout"
+msgstr ""
+
+#: editor/editor_node.cpp editor/import_dock.cpp
+#: editor/script_create_dialog.cpp
+msgid "Default"
+msgstr ""
+
+#: editor/editor_node.cpp editor/editor_properties.cpp
+#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
+msgid "Show in FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play This Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Undo Close Tab"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Close Other Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close Tabs to the Right"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Close All Tabs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Switch Scene Tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files or folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more folders"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "%d more files"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Dock Position"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Distraction Free Mode"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle distraction-free mode."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Add a new scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Go to previously opened scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Copy Text"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Next tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Previous tab"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Filter Files..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Operations with scene files."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Scene..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Open Recent"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Save All Scenes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Convert To..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "MeshLibrary..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "TileSet..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Undo"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Redo"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Miscellaneous project or scene-wide tools."
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+#: editor/script_create_dialog.cpp
+msgid "Project"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Project Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
+msgid "Version Control"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
+msgid "Set Up Version Control"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Shut Down Version Control"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Install Android Build Template..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Project Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
+msgid "Tools"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Orphan Resource Explorer..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Quit to Project List"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/project_export.cpp
+msgid "Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Deploy with Remote Debug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, using one-click deploy will make the executable "
+"attempt to connect to this computer's IP so the running project can be "
+"debugged.\n"
+"This option is intended to be used for remote debugging (typically with a "
+"mobile device).\n"
+"You don't need to enable it to use the GDScript debugger locally."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Small Deploy with Network Filesystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, using one-click deploy for Android will only "
+"export an executable without the project data.\n"
+"The filesystem will be provided from the project by the editor over the "
+"network.\n"
+"On Android, deploying will use the USB cable for faster performance. This "
+"option speeds up testing for projects with large assets."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Visible Collision Shapes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, collision shapes and raycast nodes (for 2D and "
+"3D) will be visible in the running project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Visible Navigation"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, navigation meshes and polygons will be visible "
+"in the running project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Synchronize Scene Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, any changes made to the scene in the editor "
+"will be replicated in the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Synchronize Script Changes"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"When this option is enabled, any script that is saved will be reloaded in "
+"the running project.\n"
+"When used remotely on a device, this is more efficient when the network "
+"filesystem option is enabled."
+msgstr ""
+
+#: editor/editor_node.cpp editor/script_create_dialog.cpp
+msgid "Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Settings..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Editor Layout"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Take Screenshot"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Screenshots are stored in the Editor Data/Settings Folder."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle Fullscreen"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Toggle System Console"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data/Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Data Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Editor Settings Folder"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Editor Features..."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Export Templates..."
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
+msgid "Help"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Online Docs"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Q&A"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Report a Bug"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Send Docs Feedback"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
+msgid "Community"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "About"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the project."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause the scene execution for debugging."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Pause Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Stop the scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play the edited scene."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play custom scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Play Custom Scene"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Changing the video driver requires restarting the editor."
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_settings_editor.cpp
+#: editor/settings_config_dialog.cpp
+msgid "Save & Restart"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Spins when the editor window redraws."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update Continuously"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Update When Changed"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Hide Update Spinner"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "FileSystem"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Inspector"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Expand Bottom Panel"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Output"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Don't Save"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Android build template is missing, please install relevant templates."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Manage Templates"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"This will set up your project for custom Android builds by installing the "
+"source template to \"res://android/build\".\n"
+"You can then apply modifications and build your own custom APK on export "
+"(adding modules, changing the AndroidManifest.xml, etc.).\n"
+"Note that in order to make custom builds instead of using pre-built APKs, "
+"the \"Use Custom Build\" option should be enabled in the Android export "
+"preset."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"The Android build template is already installed in this project and it won't "
+"be overwritten.\n"
+"Remove the \"res://android/build\" directory manually before attempting this "
+"operation again."
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Import Templates From ZIP File"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Template Package"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Export Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Merge With Existing"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open & Run a Script"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "New Inherited"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Load Errors"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+msgid "Select"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 2D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open 3D Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open Script Editor"
+msgstr ""
+
+#: editor/editor_node.cpp editor/project_manager.cpp
+msgid "Open Asset Library"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the next Editor"
+msgstr ""
+
+#: editor/editor_node.cpp
+msgid "Open the previous Editor"
+msgstr ""
+
+#: editor/editor_node.h
+msgid "Warning!"
+msgstr ""
+
+#: editor/editor_path.cpp
+msgid "No sub-resources found."
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Creating Mesh Previews"
+msgstr ""
+
+#: editor/editor_plugin.cpp
+msgid "Thumbnail..."
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Main Script:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit Plugin"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Installed Plugins:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Update"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Version:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+msgid "Author:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Status:"
+msgstr ""
+
+#: editor/editor_plugin_settings.cpp
+msgid "Edit:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Measure:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Average Time (sec)"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Physics Frame %"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Inclusive"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Self"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Frame #:"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Time"
+msgstr ""
+
+#: editor/editor_profiler.cpp
+msgid "Calls"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Edit Text:"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/script_create_dialog.cpp
+msgid "On"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Layer"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Bit %d, value %d"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "[Empty]"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
+msgid "Assign..."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid "Invalid RID"
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"The selected resource (%s) does not match any type expected for this "
+"property (%s)."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on resources saved as a file.\n"
+"Resource needs to belong to a scene."
+msgstr ""
+
+#: editor/editor_properties.cpp
+msgid ""
+"Can't create a ViewportTexture on this resource because it's not set as "
+"local to scene.\n"
+"Please switch on the 'local to scene' property on it (and all resources "
+"containing it up to a node)."
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Pick a Viewport"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New Script"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
+msgid "Extend Script"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "New %s"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Make Unique"
+msgstr ""
+
+#: editor/editor_properties.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Paste"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Convert To %s"
+msgstr ""
+
+#: editor/editor_properties.cpp editor/property_editor.cpp
+msgid "Selected node is not a Viewport!"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Size: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Page: "
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Item"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Key:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "New Value:"
+msgstr ""
+
+#: editor/editor_properties_array_dict.cpp
+msgid "Add Key/Value Pair"
+msgstr ""
+
+#: editor/editor_run_native.cpp
+msgid ""
+"No runnable export preset found for this platform.\n"
+"Please add a runnable preset in the Export menu or define an existing preset "
+"as runnable."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Write your logic in the _run() method."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "There is an edited scene already."
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't instance script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the 'tool' keyword?"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Couldn't run script:"
+msgstr ""
+
+#: editor/editor_run_script.cpp
+msgid "Did you forget the '_run' method?"
+msgstr ""
+
+#: editor/editor_spin_slider.cpp
+msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes."
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Select Node(s) to Import"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp editor/project_manager.cpp
+msgid "Browse"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Scene Path:"
+msgstr ""
+
+#: editor/editor_sub_scene.cpp
+msgid "Import From Node:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redownload"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uninstall"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Installed)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Official export templates aren't available for development builds."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Missing)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "(Current)"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Retrieving mirrors, please wait..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove template version '%s'?"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't open export templates zip."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Invalid version.txt format inside templates: %s."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "No version.txt found inside templates."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error creating path for templates:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Extracting Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Importing:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error getting the list of mirrors."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error parsing JSON of mirror list. Please report this issue!"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"No download links found for this version. Direct download is only available "
+"for official releases."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Request Failed."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Redirect Loop."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Complete."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Cannot remove temporary file:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid ""
+"Templates installation failed.\n"
+"The problematic templates archives can be found at '%s'."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Error requesting URL:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connecting to Mirror..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Disconnected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Resolving"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Resolve"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connecting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Can't Connect"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connected"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Requesting..."
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Downloading"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Connection Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "SSL Handshake Error"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Uncompressing Android Build Sources"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Current Version:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Installed Versions:"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Install From File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Remove Template"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select Template File"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Godot Export Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Export Template Manager"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Download Templates"
+msgstr ""
+
+#: editor/export_template_manager.cpp
+msgid "Select mirror from list: (Shift+Click: Open in Browser)"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Status: Import of file failed. Please fix file and reimport manually."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move/rename resources root."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Cannot move a folder into itself."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error moving:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Error duplicating:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Unable to update dependencies:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
+msgid "No name provided."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Provided name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "A file or folder with this name already exists."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Name contains invalid characters."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"The following files or folders conflict with items in the target location "
+"'%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Do you wish to overwrite them?"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Renaming folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating file:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicating folder:"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Inherited Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Set As Main Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Open Scenes"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Instance"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Add to Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Remove from Favorites"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Edit Dependencies..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "View Owners..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move To..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Scene..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "New Script..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "New Resource..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Expand All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Collapse All"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Duplicate..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move to Trash"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+msgid "Rename..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Previous Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Next Folder/File"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Re-Scan Filesystem"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Toggle Split Mode"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Search files"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"Scanning Files,\n"
+"Please Wait..."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Move"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/project_manager.cpp editor/rename_dialog.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Rename"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Overwrite"
+msgstr ""
+
+#: editor/filesystem_dock.cpp
+msgid "Create Scene"
+msgstr ""
+
+#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Create Script"
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+msgid "Find in Files"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Folder:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Filters:"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid ""
+"Include the files with the following extensions. Add or remove them in "
+"ProjectSettings."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
+msgid "Replace..."
+msgstr ""
+
+#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
+msgid "Cancel"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Find: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace: "
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Replace all (no undo)"
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "Searching..."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Add to Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Remove from Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group name already exists."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Invalid group name."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Rename Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Delete Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/node_dock.cpp
+msgid "Groups"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes Not in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Filter nodes"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Nodes in Group"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Empty groups will be automatically removed."
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Group Editor"
+msgstr ""
+
+#: editor/groups_editor.cpp
+msgid "Manage Groups"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Single Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import with Separate Objects+Materials+Animations"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Import as Multiple Scenes+Materials"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import Scene"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Importing Scene..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating Lightmaps"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Generating for Mesh: "
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Running Custom Script..."
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Couldn't load post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Invalid/broken script for post-import (check console):"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Error running post-import script:"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Did you return a Node-derived object in the `post_import()` method?"
+msgstr ""
+
+#: editor/import/resource_importer_scene.cpp
+msgid "Saving..."
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "%d Files"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Set as Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Clear Default for '%s'"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Import As:"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Preset"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Reimport"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Save Scenes, Re-Import, and Restart"
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid "Changing the type of an imported file requires editor restart."
+msgstr ""
+
+#: editor/import_dock.cpp
+msgid ""
+"WARNING: Assets exist that use this resource, they may stop loading properly."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Failed to load resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Expand All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Collapse All Properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save As..."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Params"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Edit Resource Clipboard"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Copy Resource"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Built-In"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Make Sub-Resources Unique"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Open in Help"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Create a new resource in memory and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Load an existing resource from disk and edit it."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Save the currently edited resource."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the previous edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Go to the next edited object in history."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "History of recently edited objects."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Object properties."
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Filter properties"
+msgstr ""
+
+#: editor/inspector_dock.cpp
+msgid "Changes may be lost!"
+msgstr ""
+
+#: editor/multi_node_edit.cpp
+msgid "MultiNode Set"
+msgstr ""
+
+#: editor/node_dock.cpp
+msgid "Select a single node to edit its signals and groups."
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Edit a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Create a Plugin"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Plugin Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Subfolder:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp
+msgid "Language:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Script Name:"
+msgstr ""
+
+#: editor/plugin_config_dialog.cpp
+msgid "Activate now?"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid ""
+"Edit points.\n"
+"LMB: Move Point\n"
+"RMB: Erase Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Erase points."
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Insert Point"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Edit Polygon (Remove Point)"
+msgstr ""
+
+#: editor/plugins/abstract_polygon_2d_editor.cpp
+msgid "Remove Polygon And Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Load..."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Move Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Change BlendSpace1D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "This type of node can't be used. Only root nodes are allowed."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Animation Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Remove BlendSpace1D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+msgid "Move BlendSpace1D Node Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"AnimationTree is inactive.\n"
+"Activate to enable playback, check node warnings if activation fails."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Set the blending position within the space"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Select and move points, create points with RMB."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
+msgid "Enable snap and show grid."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Open Editor"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_1d_editor.cpp
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Open Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Triangle already exists."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Add Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Limits"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Change BlendSpace2D Labels"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Point"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Remove BlendSpace2D Triangle"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "BlendSpace2D does not belong to an AnimationTree node."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "No triangles exist, so no blending can take place."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Toggle Auto Triangles"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Create triangles by connecting points."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Erase points and triangles."
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+msgid "Generate blend triangles automatically (instead of manually)"
+msgstr ""
+
+#: editor/plugins/animation_blend_space_2d_editor.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Parameter Changed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Filters"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Output node can't be added to the blend tree."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Add Node to BlendTree"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Node Moved"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Unable to connect, port may be in use or connection may be invalid."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Connected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Nodes Disconnected"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Set Animation"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Node"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp
+msgid "Delete Node(s)"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Toggle Filter On/Off"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Change Filter"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "No animation player set, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Player path set is invalid, so unable to retrieve track names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid ""
+"Animation player has no valid root node path, so unable to retrieve track "
+"names."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Anim Clips"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Audio Clips"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Functions"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Renamed"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node..."
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Edit Filtered Tracks:"
+msgstr ""
+
+#: editor/plugins/animation_blend_tree_editor_plugin.cpp
+msgid "Enable Filtering"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Toggle Autoplay"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "New Anim"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Animation?"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Remove Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Invalid animation name!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation name already exists!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Rename Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Next Changed"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Change Blend Time"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Load Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Duplicate Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to copy!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation resource on clipboard!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pasted Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Paste Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "No animation to edit!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from current pos. (A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation backwards from end. (Shift+A)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Stop animation playback. (S)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from start. (Shift+D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Play selected animation from current pos. (D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation position (in seconds)."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Scale animation playback globally for the node."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Tools"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Edit Transitions..."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Open in Inspector"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Display list of animations in player."
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Autoplay on Load"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Enable Onion Skinning"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Onion Skinning Options"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Directions"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Past"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Future"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Depth"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "1 step"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "2 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "3 steps"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Differences Only"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Force White Modulate"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Include Gizmos (3D)"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Pin AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Create New Animation"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Animation Name:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
+msgid "Error!"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Blend Times:"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Next (Auto Queue):"
+msgstr ""
+
+#: editor/plugins/animation_player_editor_plugin.cpp
+msgid "Cross-Animation Blend Times"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Move Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition exists!"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Add Transition"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Immediate"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Sync"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "At End"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Travel"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Start and end nodes are needed for a sub-transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "No playback resource set at path: %s."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Node Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition Removed"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set Start Node (Autoplay)"
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid ""
+"Select and move nodes.\n"
+"RMB to add new nodes.\n"
+"Shift+LMB to create connections."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Create new nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Connect nodes."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Remove selected node or transition."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Toggle autoplay this animation on start, restart or seek to zero."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Set the end animation. This is useful for sub-transitions."
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Transition: "
+msgstr ""
+
+#: editor/plugins/animation_state_machine_editor.cpp
+msgid "Play Mode:"
+msgstr ""
+
+#: editor/plugins/animation_tree_editor_plugin.cpp
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "AnimationTree"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "New name:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Scale:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade In (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Fade Out (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Auto Restart:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Random Restart (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Start!"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Amount:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 0:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend 1:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "X-Fade Time (s):"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Current:"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Input"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Clear Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Set Auto-Advance"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Delete Input"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is valid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation tree is invalid."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Animation Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "OneShot Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Mix Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend2 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend3 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Blend4 Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeScale Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "TimeSeek Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Transition Node"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Import Animations..."
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Edit Node Filters"
+msgstr ""
+
+#: editor/plugins/animation_tree_player_editor_plugin.cpp
+msgid "Filters..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Contents:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "View Files"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Connection error, please try again."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't connect to host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No response from host:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Can't resolve hostname:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, return code:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Cannot save response to:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Write error."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, too many redirects"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Redirect loop."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Request failed, timeout"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Timeout."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Bad download hash, assuming file has been tampered with."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Expected:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Got:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Failed SHA-256 hash check"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Asset Download Error:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading (%s / %s)..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Downloading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Resolving..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Error making request"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Idle"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Install..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Retry"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download Error"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Download for this asset is already in progress!"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Recently Updated"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Least Recently Updated"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Name (A-Z)"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Name (Z-A)"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "License (A-Z)"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "License (Z-A)"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "First"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Previous"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Next"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Last"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "All"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "No results for \"%s\"."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Import..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Plugins..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
+msgid "Sort:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Category:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Site:"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Support"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Official"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Testing"
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Loading..."
+msgstr ""
+
+#: editor/plugins/asset_library_editor_plugin.cpp
+msgid "Assets ZIP File"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Can't determine a save path for lightmap images.\n"
+"Save your scene and try again."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake "
+"Light' flag is on."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed creating lightmap images, make sure path is writable."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Bake Lightmaps"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
+#: editor/plugins/camera_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Preview"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Configure Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Grid Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Primary Line Every:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "steps"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Offset:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale Step:"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Vertical Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Remove Horizontal Guide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Horizontal and Vertical Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotate CanvasItem \"%s\" to %d degrees"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem \"%s\" Anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale Node2D \"%s\" to (%s, %s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Resize Control \"%s\" to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale CanvasItem \"%s\" to (%s, %s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move %d CanvasItems"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Move CanvasItem \"%s\" to (%d, %d)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Children of containers have their anchors and margins values overridden by "
+"their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Presets for the anchors and margins values of a Control node."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"When active, moving Control nodes changes their anchors instead of their "
+"margins."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Left"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Right"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Right"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Left"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Left"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Top"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Right"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Bottom"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Left Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Top Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Right Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Bottom Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "VCenter Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "HCenter Wide"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Full Rect"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Keep Ratio"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Anchors only"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors and Margins"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Anchors"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Game Camera Override\n"
+"Overrides game camera with editor viewport camera."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Game Camera Override\n"
+"No game instance running."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Group Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Ungroup Selected"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Paste Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Create Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear IK Chain"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Warning: Children of a container get their position and size determined only "
+"by their parent."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
+msgid "Zoom Reset"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Select Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Drag: Rotate"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+Drag: Move"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Move Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Show a list of all objects at the position clicked\n"
+"(same as Alt+RMB in select mode)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Click to change object's rotation pivot."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Ruler Mode"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle smart snapping."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Smart Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Toggle grid snapping."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Grid Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snapping Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Rotation Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Scale Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap Relative"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Use Pixel Snap"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Smart Snapping"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Configure Snap..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Parent"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Anchor"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Sides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Node Center"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Other Nodes"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Snap to Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock the selected object in place (can't be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Unlock the selected object (can be moved)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Makes sure the object's children are not selectable."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Restores the object's children's ability to be selected."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Skeleton Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Make Custom Bone(s) from Node(s)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Custom Bones"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Always Show Grid"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Helpers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Rulers"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Guides"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Origin"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Viewport"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Show Group And Lock Icons"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Center Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Frame Selection"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Preview Canvas Scale"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Translation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Rotation mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Scale mask for inserting keys."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert keys (based on mask)."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Auto insert keys when objects are translated, rotated or scaled (based on "
+"mask).\n"
+"Keys are only added to existing tracks, no new tracks will be created.\n"
+"Keys must be inserted manually for the first time."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Auto Insert Key"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Animation Key and Pose Options"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Insert Key (Existing Tracks)"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Copy Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Clear Pose"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Multiply grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Divide grid step by 2"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Pan View"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Add %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Adding %s..."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Cannot instantiate multiple nodes without root."
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Create Node"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "Error instancing scene from %s"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid "Change Default Type"
+msgstr ""
+
+#: editor/plugins/canvas_item_editor_plugin.cpp
+msgid ""
+"Drag & drop + Shift : Add node as sibling\n"
+"Drag & drop + Alt : Change node type"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Create Polygon3D"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly"
+msgstr ""
+
+#: editor/plugins/collision_polygon_editor_plugin.cpp
+msgid "Edit Poly (Remove Point)"
+msgstr ""
+
+#: editor/plugins/collision_shape_2d_editor_plugin.cpp
+msgid "Set Handle"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Load Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Restart"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Clear Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Particles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generated Point Count:"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Mask"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Solid Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Border Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Directed Border Pixels"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Capture from Pixel"
+msgstr ""
+
+#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Emission Colors"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+msgid "CPUParticles"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Mesh"
+msgstr ""
+
+#: editor/plugins/cpu_particles_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emission Points From Node"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 0"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Flat 1"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease In"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+msgid "Ease Out"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Smoothstep"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Modify Curve Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Curve Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Add Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Left Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right Linear"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Load Preset"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Remove Curve Point"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Toggle Curve Linear Tangent"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Hold Shift to edit tangents individually"
+msgstr ""
+
+#: editor/plugins/curve_editor_plugin.cpp
+msgid "Right click to add point"
+msgstr ""
+
+#: editor/plugins/gi_probe_editor_plugin.cpp
+msgid "Bake GI Probe"
+msgstr ""
+
+#: editor/plugins/gradient_editor_plugin.cpp
+msgid "Gradient Edited"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item %d"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Items"
+msgstr ""
+
+#: editor/plugins/item_list_editor_plugin.cpp
+msgid "Item List Editor"
+msgstr ""
+
+#: editor/plugins/light_occluder_2d_editor_plugin.cpp
+msgid "Create Occluder Polygon"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh is empty!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create a Trimesh collision shape."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Static Trimesh Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "This doesn't work on scene root!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Can't create a single convex collision shape for the scene root."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create a single convex collision shape."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Single Convex Shape"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Can't create multiple convex collision shapes for the scene root."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Couldn't create any collision shapes."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Multiple Convex Shapes"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Navigation Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Contained Mesh is not of type ArrayMesh."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Unwrap failed, mesh may not be manifold?"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "No mesh to debug."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Model has no UV in this layer"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "MeshInstance lacks a Mesh!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh has not surface to create outlines from!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Could not create outline!"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Static Body"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a StaticBody and assigns a polygon-based collision shape to it "
+"automatically.\n"
+"This is the most accurate (but slowest) option for collision detection."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Trimesh Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a polygon-based collision shape.\n"
+"This is the most accurate (but slowest) option for collision detection."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Single Convex Collision Sibling"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a single convex collision shape.\n"
+"This is the fastest (but least accurate) option for collision detection."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Multiple Convex Collision Siblings"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a polygon-based collision shape.\n"
+"This is a performance middle-ground between the two above options."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh..."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid ""
+"Creates a static outline mesh. The outline mesh will have its normals "
+"flipped automatically.\n"
+"This can be used instead of the SpatialMaterial Grow property when using "
+"that property isn't possible."
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV1"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "View UV2"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Unwrap UV2 for Lightmap/AO"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Create Outline Mesh"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "Outline Size:"
+msgstr ""
+
+#: editor/plugins/mesh_instance_editor_plugin.cpp
+msgid "UV Channel Debug"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove item %d?"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid ""
+"Update from existing scene?:\n"
+"%s"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Mesh Library"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Remove Selected Item"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Import from Scene"
+msgstr ""
+
+#: editor/plugins/mesh_library_editor_plugin.cpp
+msgid "Update from Scene"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and no MultiMesh set in node)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No mesh source specified (and MultiMesh contains no Mesh)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (not a MeshInstance)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh source is invalid (contains no Mesh resource)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "No surface source specified."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (invalid path)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no geometry)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Surface source is invalid (no faces)."
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Select a Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate Surface"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate MultiMesh"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Target Surface:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Source Mesh:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "X-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Y-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Z-Axis"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Mesh Up Axis:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Rotation:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Tilt:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Random Scale:"
+msgstr ""
+
+#: editor/plugins/multimesh_editor_plugin.cpp
+msgid "Populate"
+msgstr ""
+
+#: editor/plugins/navigation_polygon_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Convert to CPUParticles"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generating Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Generate Visibility Rect"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Can only set point into a ParticlesMaterial process material"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generation Time (sec):"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry's faces don't contain any area."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "The geometry doesn't contain any faces."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't inherit from Spatial."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "\"%s\" doesn't contain face geometry."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Create Emitter"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Points:"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Surface Points+Normal (Directed)"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Volume"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Emission Source: "
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "A processor material of type 'ParticlesMaterial' is required."
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generating AABB"
+msgstr ""
+
+#: editor/plugins/particles_editor_plugin.cpp
+msgid "Generate Visibility AABB"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Point from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove Out-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Remove In-Control from Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point to Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Split Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Point in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move In-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Move Out-Control in Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Select Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Shift+Drag: Select Control Points"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Click: Add Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Left Click: Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Right Click: Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+msgid "Select Control Points (Shift+Drag)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Add Point (in empty space)"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Delete Point"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Close Curve"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp
+msgid "Options"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Angles"
+msgstr ""
+
+#: editor/plugins/path_2d_editor_plugin.cpp
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Mirror Handle Lengths"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Curve Point #"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Point Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve In Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Set Curve Out Position"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Path"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Path Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove Out-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Remove In-Control Point"
+msgstr ""
+
+#: editor/plugins/path_editor_plugin.cpp
+msgid "Split Segment (in curve)"
+msgstr ""
+
+#: editor/plugins/physical_bone_plugin.cpp
+msgid "Move Joint"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"No texture in this polygon.\n"
+"Set a texture to be able to edit UV."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Polygon 2D has internal vertices, so it can no longer be edited in the "
+"viewport."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Polygon & UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Internal Vertex"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Invalid Polygon (need 3 different vertices)"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Add Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Remove Custom Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform UV Map"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Transform Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint Bone Weights"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Open Polygon 2D UV editor."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygon 2D UV Editor"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Polygons"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Bones"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Points"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Command: Rotate"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift: Move All"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Command: Scale"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Ctrl: Rotate"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Shift+Ctrl: Scale"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Move Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Rotate Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Scale Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Create a custom polygon. Enables custom polygon rendering."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid ""
+"Remove a custom polygon. If none remain, custom polygon rendering is "
+"disabled."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Paint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Unpaint weights with specified intensity."
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Radius:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Copy Polygon to UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Copy UV to Polygon"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Clear UV"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Settings"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Enable Snap"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Show Grid"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Configure Grid:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Offset Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step X:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Grid Step Y:"
+msgstr ""
+
+#: editor/plugins/polygon_2d_editor_plugin.cpp
+msgid "Sync Bones to Polygon"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ERROR: Couldn't load resource!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Add Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Rename Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Delete Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Resource clipboard is empty!"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Paste Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_editor.cpp
+msgid "Instance:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
+#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Type:"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
+msgid "Open in Editor"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "Load Resource"
+msgstr ""
+
+#: editor/plugins/resource_preloader_editor_plugin.cpp
+msgid "ResourcePreloader"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "AnimationTree has no path set to an AnimationPlayer"
+msgstr ""
+
+#: editor/plugins/root_motion_editor_plugin.cpp
+msgid "Path to AnimationPlayer is invalid"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Files"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close and save changes?"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error writing TextFile:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Could not load file at:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving file!"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error importing theme."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error Importing"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "New Text File..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save File As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Can't obtain the script for running."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Script failed reloading, check console for errors."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Script is not in tool mode, will not be able to run."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"To run this script, it must inherit EditorScript and be set to tool mode."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error while saving theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Error saving"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme As..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "%s Class Reference"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+msgid "Find Previous"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter scripts"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Toggle alphabetical sorting of the method list."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Filter methods"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Sort"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Up"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Move Down"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Next script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Previous script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "File"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reopen Closed Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Soft Reload Script"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Copy Script Path"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Previous"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "History Next"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Import Theme..."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Reload Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Save Theme"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close All"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Close Docs"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+msgid "Run"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Into"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Step Over"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Break"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
+#: editor/script_editor_debugger.cpp
+msgid "Continue"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Keep Debugger Open"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Debug with External Editor"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Open Godot online documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search the reference documentation."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to previous edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Go to next edited document."
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Discard"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?:"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
+msgid "Debugger"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Search Results"
+msgstr ""
+
+#: editor/plugins/script_editor_plugin.cpp
+msgid "Clear Recent Scripts"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Connections to method:"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp
+msgid "Source"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Target"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid ""
+"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "[Ignore]"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Only resources from filesystem can be dropped."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't drop nodes because script '%s' is not used in this scene."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Lookup Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Pick Color"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Convert Case"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Uppercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Lowercase"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Capitalize"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
+msgid "Syntax Highlighter"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "Bookmarks"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+msgid "Go To"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+msgid "Cut"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
+#: scene/gui/text_edit.cpp
+msgid "Select All"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Delete Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Left"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Indent Right"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Comment"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold/Unfold Line"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Fold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Unfold All Lines"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Clone Down"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Complete Symbol"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Evaluate Selection"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Trim Trailing Whitespace"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Spaces"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Convert Indent to Tabs"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Auto Indent"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Find in Files..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Contextual Help"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Toggle Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Bookmark"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Bookmarks"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Function..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Line..."
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Toggle Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Remove All Breakpoints"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Next Breakpoint"
+msgstr ""
+
+#: editor/plugins/script_text_editor.cpp
+msgid "Go to Previous Breakpoint"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid ""
+"This shader has been modified on on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Shader"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "This skeleton has no bones, create some children Bone2D nodes."
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Create Rest Pose from Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Rest Pose to Bones"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Skeleton2D"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Make Rest Pose (From Bones)"
+msgstr ""
+
+#: editor/plugins/skeleton_2d_editor_plugin.cpp
+msgid "Set Bones to Rest Pose"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical bones"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_editor_plugin.cpp
+msgid "Create physical skeleton"
+msgstr ""
+
+#: editor/plugins/skeleton_ik_editor_plugin.cpp
+msgid "Play IK"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Orthogonal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Aborted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "X-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Y-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Z-Axis Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Plane Transform."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scaling: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translating: "
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotating %s degrees."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Keying is disabled (no key inserted)."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Animation Key Inserted."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pitch"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Yaw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Objects Drawn"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Material Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Shader Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Surface Changes"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Draw Calls"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Vertices"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Transform with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Align Rotation with View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "No parent to instance a child at."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
+msgid "This operation requires a single selected node."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Auto Orthogonal Enabled"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Lock View Rotation"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Normal"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Wireframe"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Overdraw"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Display Unshaded"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Environment"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Information"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View FPS"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Half Resolution"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Audio Listener"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Enable Doppler"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Cinematic Preview"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Not available when using the GLES2 renderer."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Left"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Right"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Forward"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Backwards"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Up"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Down"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Speed Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Freelook Slow Modifier"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Rotation Locked"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Note: The FPS value displayed is the editor's framerate.\n"
+"It cannot be used as a reliable indication of in-game performance."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "XForm Dialog"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Click to toggle between visibility states.\n"
+"\n"
+"Open eye: Gizmo is visible.\n"
+"Closed eye: Gizmo is hidden.\n"
+"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Nodes To Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Couldn't find a solid floor to snap the selection to."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid ""
+"Drag: Rotate\n"
+"Alt+Drag: Move\n"
+"Alt+RMB: Depth list selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Local Space"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Use Snap"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Bottom View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Top View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rear View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Front View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Left View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Right View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Switch Perspective/Orthogonal View"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Insert Animation Key"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Focus Selection"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Toggle Freelook"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Object to Floor"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Dialog..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "1 Viewport"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "2 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "3 Viewports (Alt)"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "4 Viewports"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Gizmos"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Origin"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Grid"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Settings..."
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Snap Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate Snap:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate Snap (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale Snap (%):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Viewport Settings"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Perspective FOV (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Near:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "View Z-Far:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Change"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Translate:"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Rotate (deg.):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Scale (ratio):"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Transform Type"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Pre"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Post"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Nameless gizmo"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Mesh2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Polygon2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "CollisionPolygon2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "LightOccluder2D Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite is empty!"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Can't convert a sprite using animation frames to mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't replace by mesh."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Mesh2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Convert to Polygon2D"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create collision polygon."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create CollisionPolygon2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Invalid geometry, can't create light occluder."
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Create LightOccluder2D Sibling"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Sprite"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Simplification: "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Shrink (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Grow (Pixels): "
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Update Preview"
+msgstr ""
+
+#: editor/plugins/sprite_editor_plugin.cpp
+msgid "Settings:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "No Frames Selected"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add %d Frame(s)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Unable to load images"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "ERROR: Couldn't load frame resource!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Resource clipboard is empty or not a texture!"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Paste Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Empty"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Change Animation FPS"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "(empty)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move Frame"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animations:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "New Animation"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Speed:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Loop"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Animation Frames:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add a Texture from File"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Add Frames from a Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Insert Empty (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (Before)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Move (After)"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Horizontal:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Vertical:"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Select/Clear All Frames"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "Create Frames from Sprite Sheet"
+msgstr ""
+
+#: editor/plugins/sprite_frames_editor_plugin.cpp
+msgid "SpriteFrames"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Region Rect"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Set Margin"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Snap Mode:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+#: scene/resources/visual_shader.cpp
+msgid "None"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Pixel Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Grid Snap"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Auto Slice"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Offset:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Step:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "Sep.:"
+msgstr ""
+
+#: editor/plugins/texture_region_editor_plugin.cpp
+msgid "TextureRegion"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove All Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
+msgid "Remove All"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Edit Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme editing menu."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Add Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Remove Class Items"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create Empty Editor Template"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Create From Current Editor Theme"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Toggle Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Button"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Check Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Checked Radio Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Named Sep."
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Submenu"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subitem 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Many"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Disabled LineEdit"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 1"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 2"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Tab 3"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Editable Item"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Subtree"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Has,Many,Options"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Data Type:"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
+msgid "Style"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Font"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Color"
+msgstr ""
+
+#: editor/plugins/theme_editor_plugin.cpp
+msgid "Theme File"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Fix Invalid Tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cut Selection"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Line Draw"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Bucket Fill"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Erase TileMap"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Find Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Transpose"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Disable Autotile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Enable Priority"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Filter tiles"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Give a TileSet resource to this TileMap to use its tiles."
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Paint Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Command+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid ""
+"Shift+LMB: Line Draw\n"
+"Shift+Ctrl+LMB: Rectangle Paint"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Pick Tile"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Left"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Rotate Right"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Horizontally"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Flip Vertically"
+msgstr ""
+
+#: editor/plugins/tile_map_editor_plugin.cpp
+msgid "Clear Transform"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Add Texture(s) to TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected Texture from TileSet."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from Scene"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Single Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Autotile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Atlas"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Next Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the next shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Previous Coordinate"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Select the previous shape, subtile, or Tile."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Region Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Collision Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Occlusion Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Navigation Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Bitmask Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Priority Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Icon Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Z Index Mode"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Copy bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Erase bitmask."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new rectangle."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Rectangle"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create a new polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "New Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete Selected Shape"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Keep polygon inside region Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Enable snap and show grid (configurable via the Inspector)."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Display Tile Names (Hold Alt Key)"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Add or select a texture on the left panel to edit the tiles bound to it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove selected texture? This will remove all tiles which use it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "You haven't selected a texture to remove."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create from scene? This will overwrite all current tiles."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Merge from scene?"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Texture"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "%s file(s) were not added because was already on the list."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Drag handles to edit Rect.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete selected Rect."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select current edited sub-tile.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Delete polygon."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"LMB: Set bit on.\n"
+"RMB: Set bit off.\n"
+"Shift+LMB: Set wildcard bit.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to use as icon, this will be also used on invalid autotile "
+"bindings.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its priority.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid ""
+"Select sub-tile to change its z index.\n"
+"Click on another Tile to edit it."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Region"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Set Tile Icon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Paste Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Clear Tile Bitmask"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Polygon Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Tile"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Remove Navigation Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Priority"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Edit Tile Z Index"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Convex"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Make Concave"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Collision Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "Create Occlusion Polygon"
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "This property can't be changed."
+msgstr ""
+
+#: editor/plugins/tile_set_editor_plugin.cpp
+msgid "TileSet"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No VCS addons are available."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Error"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No files added to stage"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "VCS Addon is not initialized"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Version Control System"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Initialize"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Staging area"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Stage Selected"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Stage All"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Status"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View file diffs before committing them to the latest version"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No file diff is active"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect changes in file diff"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(GLES3 only)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Output"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sampler"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port type"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change input port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Change output port name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove input port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Remove output port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set expression"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Resize VisualShader node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Uniform Name"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Set Input Default Port"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Add Node to Visual Shader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Node(s) Moved"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Duplicate Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Delete Nodes"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Input Type Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "UniformRef Name Changed"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vertex"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Fragment"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Light"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Show resulted shader code."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Create Shader Node"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Grayscale function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts HSV vector to RGB equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts RGB vector to HSV equivalent."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sepia function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Burn operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Darken operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Difference operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Dodge operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "HardLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Lighten operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Overlay operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Screen operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "SoftLight operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Color uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the %s comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Equal (==)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than (>)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Greater Than or Equal (>=)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided scalars are equal, greater or "
+"less."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between NaN and a scalar "
+"parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than (<)"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Less Than or Equal (<=)"
+msgstr "Помалку или еднакво (<=)"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Not Equal (!=)"
+msgstr "Ðееднакво"
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated vector if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns an associated scalar if the provided boolean value is true or false."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the boolean result of the comparison between two parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the boolean result of the comparison between INF (or NaN) and a "
+"scalar parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Boolean uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for all shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Input parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment and light shader modes."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for light shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "'%s' input parameter for vertex and fragment shader mode."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "E constant (2.718282). Represents the base of the natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Epsilon constant (0.00001). Smallest possible scalar number."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Phi constant (1.618034). Golden ratio."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/4 constant (0.785398) or 45 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi/2 constant (1.570796) or 90 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Pi constant (3.141593) or 180 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Tau constant (6.283185) or 360 degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Sqrt2 constant (1.414214). Square root of 2."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the absolute value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the arc-tangent of the parameters."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Finds the nearest integer that is greater than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Constrains a value to lie between two further values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic cosine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in radians to degrees."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-e Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 Exponential."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer less than or equal to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Computes the fractional part of the argument."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the inverse of the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Natural logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Base-2 logarithm."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the greater of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the lesser of two values."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the opposite value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the value of the first parameter raised to the power of the second."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Converts a quantity in degrees to radians."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / scalar"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the nearest even integer to the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Clamps the value between 0.0 and 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Extracts the sign of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic sine of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the square root of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), scalar(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the hyperbolic tangent of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Finds the truncated value of the parameter."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds scalar to scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies scalar by scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts scalar from scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Scalar uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the cubic texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Perform the texture lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Cubic texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "2D texture uniform lookup with triplanar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Calculate the outer product of a pair of vectors.\n"
+"\n"
+"OuterProduct treats the first parameter 'c' as a column vector (matrix with "
+"one column) and the second parameter 'r' as a row vector (matrix with one "
+"row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix "
+"whose number of rows is the number of components in 'c' and whose number of "
+"columns is the number of components in 'r'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes transform from four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes transform to four vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the determinant of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the inverse of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the transpose of a transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies transform by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by transform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Transform uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector operator."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Composes vector from three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Decomposes vector to three scalars."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the cross product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the distance between two points."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the dot product of two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the same direction as a reference vector. "
+"The function has three vector parameters : N, the vector to orient, I, the "
+"incident vector, and Nref, the reference vector. If the dot product of I and "
+"Nref is smaller than zero the return value is N. Otherwise -N is returned."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the length of a vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Linear interpolation between two vectors using scalar."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Calculates the normalize product of vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 - vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "1.0 / vector"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns the vector that points in the direction of reflection ( a : incident "
+"vector, b : normal vector )."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the vector that points in the direction of refraction."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than "
+"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
+"using Hermite polynomials."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( vector(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Step function( scalar(edge), vector(x) ).\n"
+"\n"
+"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Adds vector to vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Divides vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Multiplies vector by vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Returns the remainder of the two vectors."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Subtracts vector from vector."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector constant."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Vector uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, with custom amount of input and "
+"output ports. This is a direct injection of code into the vertex/fragment/"
+"light function, do not use it to write the function declarations inside."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Returns falloff based on the dot product of surface normal and view "
+"direction of camera (pass associated inputs to it)."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"Custom Godot Shader Language expression, which is placed on top of the "
+"resulted shader. You can place various function definitions inside and call "
+"it later in the Expressions. You can also declare varyings, uniforms and "
+"constants."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "A reference to an existing uniform."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Scalar derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "(Fragment/Light mode only) Vector derivative function."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'x' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Derivative in 'y' using local "
+"differencing."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid ""
+"(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and "
+"'y'."
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "VisualShader"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Edit Visual Property"
+msgstr ""
+
+#: editor/plugins/visual_shader_editor_plugin.cpp
+msgid "Visual Shader Mode Changed"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Runnable"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Delete preset '%s'?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"Export templates seem to be missing or invalid."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Failed to export the project for platform '%s'.\n"
+"This might be due to a configuration issue in the export preset or your "
+"export settings."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Release"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Exporting All"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "The given export path doesn't exist:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing/corrupted:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Presets"
+msgstr ""
+
+#: editor/project_export.cpp editor/project_settings_editor.cpp
+msgid "Add..."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"If checked, the preset will be available for use in one-click deploy.\n"
+"Only one preset per platform may be marked as runnable."
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Path"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export all resources in the project"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected scenes (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export selected resources (and dependencies)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Resources to export:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to export non-resource files/folders\n"
+"(comma-separated, e.g: *.json, *.txt, docs/*)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid ""
+"Filters to exclude files/folders from project\n"
+"(comma-separated, e.g: *.json, *.txt, docs/*)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Features"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Custom (comma-separated):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Feature List:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Export Mode:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Text"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Compiled"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Encrypted (Provide Key Below)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Invalid Encryption Key (must be 64 characters long)"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Script Encryption Key (256-bits as hex):"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export PCK/Zip"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export Project"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export mode?"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export All"
+msgstr ""
+
+#: editor/project_export.cpp editor/project_manager.cpp
+msgid "ZIP File"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Godot Game Pack"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export templates for this platform are missing:"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Manage Export Templates"
+msgstr ""
+
+#: editor/project_export.cpp
+msgid "Export With Debug"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "The path specified doesn't exist."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error opening package file (it's not in ZIP format)."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose an empty folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Please choose a \"project.godot\" or \".zip\" file."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "This directory already contains a Godot project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Game Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Imported Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid Project Name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create folder."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "There is already a folder in this path with the specified name."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "It would be a good idea to name your project."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Invalid project path (changed anything?)."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Couldn't load project.godot in project path (error %d). It may be missing or "
+"corrupted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't edit project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Couldn't create project.godot in project path."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Rename Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import Existing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Import & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Create & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install Project:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Install & Edit"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Name:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Project Installation Path:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer:"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 3.0"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Not supported by your GPU drivers."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Higher visual quality\n"
+"All features available\n"
+"Incompatible with older hardware\n"
+"Not recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "OpenGL ES 2.0"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Lower visual quality\n"
+"Some features not available\n"
+"Works on most hardware\n"
+"Recommended for web games"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Renderer can be changed later, but scenes may need to be adjusted."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Unnamed Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Missing Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Error: Project is missing on the filesystem."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't open project at '%s'."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to open more than one project?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file does not specify the version of Godot "
+"through which it was created.\n"
+"\n"
+"%s\n"
+"\n"
+"If you proceed with opening it, it will be converted to Godot's current "
+"configuration file format.\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The following project settings file was generated by an older engine "
+"version, and needs to be converted for this version:\n"
+"\n"
+"%s\n"
+"\n"
+"Do you want to convert it?\n"
+"Warning: You won't be able to open the project with previous versions of the "
+"engine anymore."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The project settings were created by a newer engine version, whose settings "
+"are not compatible with this version."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: no main scene defined.\n"
+"Please edit the project and set the main scene in the Project Settings under "
+"the \"Application\" category."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Can't run project: Assets need to be imported.\n"
+"Please edit the project to trigger the initial import."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Are you sure to run %d projects at once?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove %d projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove this project from the list?\n"
+"The project folder's contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Remove all missing projects from the list?\n"
+"The project folders' contents won't be modified."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Language changed.\n"
+"The interface will update after restarting the editor or project manager."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"Are you sure to scan %s folders for existing Godot projects?\n"
+"This could take a while."
+msgstr ""
+
+#. TRANSLATORS: This refers to the application where users manage their Godot projects.
+#: editor/project_manager.cpp
+msgid "Project Manager"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Projects"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Last Modified"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Select a Folder to Scan"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "New Project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Remove Missing"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Templates"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Restart Now"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid "Can't run project"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"You currently don't have any projects.\n"
+"Would you like to explore official example projects in the Asset Library?"
+msgstr ""
+
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Key "
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joy Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "An action with the name '%s' already exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Rename Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Action deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "All Devices"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Press a Key..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Mouse Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Left Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Right Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 1"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "X Button 2"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Axis Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Axis"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Joypad Button Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Erase Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Button"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Left Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Right Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Middle Button."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Up."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Wheel Down."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Global Property"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Select a setting item first!"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "No property '%s' exists."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Setting '%s' is internal, and it can't be deleted."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Delete Item"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid ""
+"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
+"'\"'."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Input Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Error saving settings."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Settings saved OK."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Moved Input Action Event"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override for Feature"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Translation"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Add Remapped Path"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resource Remap Add Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Change Resource Remap Language"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remove Resource Remap Option"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Changed Locale Filter Mode"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Project Settings (project.godot)"
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "General"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Override For..."
+msgstr ""
+
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "The editor must be restarted for changes to take effect."
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Input Map"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Action"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Deadzone"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Device:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Index:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Localization"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Translations:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Resources:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Remaps by Locale:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locale"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales Filter"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show All Locales"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Show Selected Locales Only"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Filter mode:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Locales:"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "AutoLoad"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Plugins"
+msgstr ""
+
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Preset..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Zero"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing In-Out"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Easing Out-In"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "File..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Dir..."
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Assign"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Select Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Error loading file: Not a resource!"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Pick a Node"
+msgstr ""
+
+#: editor/property_editor.cpp
+msgid "Bit %d, val %d."
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Property"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Virtual Method"
+msgstr ""
+
+#: editor/property_selector.cpp
+msgid "Select Method"
+msgstr ""
+
+#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Batch Rename"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Replace:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Prefix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Suffix:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Use Regular Expressions"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Advanced Options"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Substitute"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node's parent name, if available"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Node type"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Current scene name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Root node name"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Sequential integer counter.\n"
+"Compare counter options."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Per-level Counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "If set, the counter restarts for each group of child nodes."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Initial value for the counter"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Step"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Amount by which counter is incremented for each node"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Padding"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid ""
+"Minimum number of digits for the counter.\n"
+"Missing digits are padded with leading zeros."
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Post-Process"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Keep"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "PascalCase to snake_case"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "snake_case to PascalCase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Case"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Lowercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "To Uppercase"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Reset"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "Regular Expression Error:"
+msgstr ""
+
+#: editor/rename_dialog.cpp
+msgid "At character %s"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent Node"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Reparent Location (Select new Parent):"
+msgstr ""
+
+#: editor/reparent_dialog.cpp
+msgid "Keep Global Transform"
+msgstr ""
+
+#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
+msgid "Reparent"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Run Mode:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Current Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Main Scene Arguments:"
+msgstr ""
+
+#: editor/run_settings_dialog.cpp
+msgid "Scene Run Settings"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "No parent to instance the scenes at."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error loading scene from %s"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot instance the scene '%s' because the current scene exists within one "
+"of its nodes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Scene(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Replace with Branch Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instance Child Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Detach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on the tree root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Node In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Move Nodes In Parent"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Duplicate Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Node must belong to the edited scene to become root."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Instantiated scenes can't become root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make node as Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete %d nodes and any children?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete %d nodes?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete the root node \"%s\"?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete node \"%s\" and its children?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete node \"%s\"?"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can not perform with the root node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "This operation can't be done on instanced scenes."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Save New Scene As..."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Disabling \"editable_instance\" will cause all properties of the node to be "
+"reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Enabling \"Load As Placeholder\" will disable \"Editable Children\" and "
+"cause all properties of the node to be reverted to their default."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "New Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Create Root Node:"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "2D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "3D Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "User Interface"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Other Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes from a foreign scene!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Can't operate on nodes the current scene inherits from!"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach Script"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remove Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change type of node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Couldn't save new scene. Likely dependencies (instances) couldn't be "
+"satisfied."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error saving scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Error duplicating scene to save it."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Sub-Resources"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Editable Children"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Load As Placeholder"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Open Documentation"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Cannot attach a script: there are no languages registered.\n"
+"This is probably because this editor was built with all language modules "
+"disabled."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add Child Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Expand/Collapse All"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Change Type"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Reparent to New Node"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Make Scene Root"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Merge From Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Save Branch as Scene"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
+msgid "Copy Node Path"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Delete (No Confirm)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Add/Create a New Node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid ""
+"Instance a scene file as a Node. Creates an inherited scene if no root node "
+"exists."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Attach a new or existing script to the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Detach the script from the selected node."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Remote"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Local"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Clear Inheritance? (No Undo!)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visible"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Unlock Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Button Group"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "(Connecting From)"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node configuration warning:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s) and %s group(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node has %s connection(s).\n"
+"Click to show signals dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is in %s group(s).\n"
+"Click to show groups dock."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Open Script:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Node is locked.\n"
+"Click to unlock it."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"Children are not selectable.\n"
+"Click to make selectable."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Toggle Visibility"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid ""
+"AnimationPlayer is pinned.\n"
+"Click to unpin."
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Invalid node name, the following characters are not allowed:"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Rename Node"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Scene Tree (Nodes):"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Node Configuration Warning!"
+msgstr ""
+
+#: editor/scene_tree_editor.cpp
+msgid "Select a Node"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Filename is empty."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Path is not local."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid base path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "A directory with the same name exists."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "File does not exist."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid extension."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Wrong extension chosen."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading template '%s'"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error - Could not create script in filesystem."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Error loading script from %s"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Overrides"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "N/A"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script / Choose Location"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Open Script"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "File exists, it will be reused."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid class name."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Invalid inherited parent name or path."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Script path/name is valid."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Allowed: a-z, A-Z, 0-9, _ and ."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in script (into scene file)."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will create a new script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Will load an existing script file."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Script file already exists."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid ""
+"Note: Built-in scripts have some limitations and can't be edited using an "
+"external editor."
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Class Name:"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Template:"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Built-in Script:"
+msgstr ""
+
+#: editor/script_create_dialog.cpp
+msgid "Attach Node Script"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Remote "
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Bytes:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Warning:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Error:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Error"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Error:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Source"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Source:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "C++ Source:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Trace"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Errors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Child process connected."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Copy Error"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Video RAM"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Skip Breakpoints"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Previous Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Inspect Next Instance"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Stack Frames"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Profiler"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Network Profiler"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitor"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Value"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Monitors"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Pick one or more items from the list to display the graph."
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "List of Video Memory Usage by Resource:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Total:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Resource Path"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Type"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Format"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Usage"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Misc"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Clicked Control Type:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Live Edit Root:"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Set From Tree"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
+msgid "Export measures as CSV"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Erase Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Restore Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Change Shortcut"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Editor Settings"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Shortcuts"
+msgstr ""
+
+#: editor/settings_config_dialog.cpp
+msgid "Binding"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Light Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change AudioStreamPlayer3D Emission Angle"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera FOV"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Camera Size"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Notifier AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Particles AABB"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Probe Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Sphere Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+msgid "Change Box Shape Extents"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Capsule Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Radius"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Cylinder Shape Height"
+msgstr ""
+
+#: editor/spatial_editor_gizmos.cpp
+msgid "Change Ray Shape Length"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Cylinder Height"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Inner Radius"
+msgstr ""
+
+#: modules/csg/csg_gizmos.cpp
+msgid "Change Torus Outer Radius"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select the dynamic library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Select dependencies of the library for this entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Remove current entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Double click to create a new entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform:"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Platform"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Dynamic Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "Add an architecture entry"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_editor_plugin.cpp
+msgid "GDNativeLibrary"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Enabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Disabled GDNative Singleton"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Library"
+msgstr ""
+
+#: modules/gdnative/gdnative_library_singleton_editor.cpp
+msgid "Libraries: "
+msgstr "Библиотеки: "
+
+#: modules/gdnative/register_types.cpp
+msgid "GDNative"
+msgstr "GDNative(ГДДомороден)"
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Step argument is zero!"
+msgstr "Корак аргумент е нула!"
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not a script with an instance"
+msgstr "Ðе е Ñкрипта Ñо инÑтанца"
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a script"
+msgstr "Ðе е оÑновано на Ñкрипта"
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Not based on a resource file"
+msgstr "Ðе е оÑновано на реÑÑƒÑ€Ñ Ñ„Ð°Ñ˜Ð»"
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (missing @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (can't load script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary format (invalid script at @path)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Invalid instance dictionary (invalid subclasses)"
+msgstr ""
+
+#: modules/gdscript/gdscript_functions.cpp
+msgid "Object can't provide a length."
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Plane"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Plane:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Next Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Previous Floor"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Floor:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Delete Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paste Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Paint"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Grid Map"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Snap View"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Disabled"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Above"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clip Below"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit X Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Y Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Edit Z Axis"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate X"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Y"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Back Rotate Z"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Cursor Clear Rotation"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Paste Selects"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Clear Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Fill Selection"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "GridMap Settings"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Pick Distance:"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Filter meshes"
+msgstr ""
+
+#: modules/gridmap/grid_map_editor_plugin.cpp
+msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
+#: modules/mono/csharp_script.cpp
+msgid "Class name can't be a reserved keyword"
+msgstr ""
+
+#: modules/mono/mono_gd/gd_mono_utils.cpp
+msgid "End of inner exception stack trace"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Bake NavMesh"
+msgstr ""
+
+#: modules/recast/navigation_mesh_editor_plugin.cpp
+msgid "Clear the navigation mesh."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Setting up Configuration..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Calculating grid size..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Marking walkable triangles..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Constructing compact heightfield..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Eroding walkable area..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Partitioning..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating contours..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Creating polymesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Converting to native navigation mesh..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Navigation Mesh Generator Setup:"
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Parsing Geometry..."
+msgstr ""
+
+#: modules/recast/navigation_mesh_generator.cpp
+msgid "Done!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"A node yielded without working memory, please read the docs on how to yield "
+"properly!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Node yielded, but did not return a function state in the first working "
+"memory."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid ""
+"Return value must be assigned to first element of node working memory! Fix "
+"your node please."
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Node returned an invalid sequence output: "
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Found sequence bit but not the node in the stack, report bug!"
+msgstr ""
+
+#: modules/visual_script/visual_script.cpp
+msgid "Stack overflow with stack depth: "
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Signal Arguments"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Argument name"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Default Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Set Variable Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Input Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Output Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Override an existing built-in function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new function."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Variables:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new variable."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Signals:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create a new signal."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name is not a valid identifier:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Name already in use by another func/var/signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Rename Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete input port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Input Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Output Port"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Duplicate VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a simple reference to the node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold %s to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Hold Ctrl to drop a Variable Setter."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Preload Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Node(s) From Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid ""
+"Can't drop properties because script '%s' is not used in this scene.\n"
+"Drop holding 'Shift' to just copy the signature."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Getter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Setter Property"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Move Node(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove VisualScript Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Disconnect Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Data"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Connect Node Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Script already has function '%s'"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Input Value"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Resize Comment"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't copy the function node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Clipboard is empty!"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Paste VisualScript Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't create function with a function node."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Can't create function of nodes from nodes of multiple functions."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select at least one node with sequence port."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Try to only have one sequence input in selection."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Create Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Variable"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Variable:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Remove Signal"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Editing Signal:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Make Tool:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Members:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Change Base Type:"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Nodes..."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Add Function..."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "function_name"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Select or create a function to edit its graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Delete Selected"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Find Node Type"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Copy Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Cut Nodes"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Make Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Refresh Graph"
+msgstr ""
+
+#: modules/visual_script/visual_script_editor.cpp
+msgid "Edit Member"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Input type not iterable: "
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator became invalid: "
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name."
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Base object is not a Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Path does not lead Node!"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Invalid index property name '%s' in node %s."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid argument of type: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ": Invalid arguments: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableGet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "VariableSet not found in script: "
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Custom node has no _step() method, can't process graph."
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid ""
+"Invalid return value from _step(), must be integer (seq out), or string "
+"(error)."
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Search VisualScript"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Set %s"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package name is missing."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Package segments must be of non-zero length."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' is not allowed in Android application package names."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "A digit cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The character '%s' cannot be the first character in a package segment."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "The package must have at least one '.' separator."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Select device from the list"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find the 'apksigner' tool."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Debug keystore not configured in the Editor Settings nor in the preset."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Release keystore incorrectly configured in the export preset."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'platform-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid public key for APK expansion."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid package name:"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" "
+"project setting (changed in Godot 3.2.2).\n"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "\"Use Custom Build\" must be enabled to use the plugins."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR"
+"\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid filename! Android App Bundle requires the *.aab extension."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "APK Expansion not compatible with Android App Bundle."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Invalid filename! Android APK requires the *.apk extension."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Trying to build from a custom built template, but no version info for it "
+"exists. Please reinstall from the 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Android build version mismatch:\n"
+" Template installed: %s\n"
+" Godot Version: %s\n"
+"Please reinstall Android build template from 'Project' menu."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Building Android Project (gradle)"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Building of Android project failed, check output for the error.\n"
+"Alternatively visit docs.godotengine.org for Android build documentation."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Moving output"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid ""
+"Unable to copy and rename export file, check gradle project directory for "
+"outputs."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Identifier is missing."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "The character '%s' is not allowed in Identifier."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "App Store Team ID not specified - cannot configure the project."
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Invalid Identifier:"
+msgstr ""
+
+#: platform/iphone/export/export.cpp
+msgid "Required icon is not specified in the preset."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Stop HTTP Server"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run in Browser"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Run exported HTML in the system's default browser."
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not write file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not open template for export:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Invalid export template:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read custom HTML shell:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Could not read boot splash image file:"
+msgstr ""
+
+#: platform/javascript/export/export.cpp
+msgid "Using default boot splash image."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package short name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package unique name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid package publisher display name."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid product GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid publisher GUID."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid background color."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid Store Logo image dimensions (should be 50x50)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
+msgstr ""
+
+#: platform/uwp/export/export.cpp
+msgid "Invalid splash screen image dimensions (should be 620x300)."
+msgstr ""
+
+#: scene/2d/animated_sprite.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite to display frames."
+msgstr ""
+
+#: scene/2d/canvas_modulate.cpp
+msgid ""
+"Only one visible CanvasModulate is allowed per scene (or set of instanced "
+"scenes). The first created one will work, while the rest will be ignored."
+msgstr ""
+
+#: scene/2d/collision_object_2d.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
+"define its shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid ""
+"CollisionPolygon2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "An empty CollisionPolygon2D has no effect on collision."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"CollisionShape2D only serves to provide a collision shape to a "
+"CollisionObject2D derived node. Please only use it as a child of Area2D, "
+"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"A shape must be provided for CollisionShape2D to function. Please create a "
+"shape resource for it!"
+msgstr ""
+
+#: scene/2d/collision_shape_2d.cpp
+msgid ""
+"Polygon-based shapes are not meant be used nor edited directly through the "
+"CollisionShape2D node. Please use the CollisionPolygon2D node instead."
+msgstr ""
+
+#: scene/2d/cpu_particles_2d.cpp
+msgid ""
+"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A and Node B must be PhysicsBody2Ds"
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A must be a PhysicsBody2D"
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node B must be a PhysicsBody2D"
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Joint is not connected to two PhysicsBody2Ds"
+msgstr ""
+
+#: scene/2d/joints_2d.cpp
+msgid "Node A and Node B must be different PhysicsBody2Ds"
+msgstr ""
+
+#: scene/2d/light_2d.cpp
+msgid ""
+"A texture with the shape of the light must be supplied to the \"Texture\" "
+"property."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid ""
+"An occluder polygon must be set (or drawn) for this occluder to take effect."
+msgstr ""
+
+#: scene/2d/light_occluder_2d.cpp
+msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"A NavigationPolygon resource must be set or created for this node to work. "
+"Please set a property or draw a polygon."
+msgstr ""
+
+#: scene/2d/navigation_polygon.cpp
+msgid ""
+"NavigationPolygonInstance must be a child or grandchild to a Navigation2D "
+"node. It only provides navigation data."
+msgstr ""
+
+#: scene/2d/parallax_layer.cpp
+msgid ""
+"ParallaxLayer node only works when set as child of a ParallaxBackground node."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles2D node instead. You can use the \"Convert to "
+"CPUParticles\" option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
+msgid ""
+"A material to process the particles is not assigned, so no behavior is "
+"imprinted."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"Particles2D animation requires the usage of a CanvasItemMaterial with "
+"\"Particles Animation\" enabled."
+msgstr ""
+
+#: scene/2d/path_2d.cpp
+msgid "PathFollow2D only works when set as a child of a Path2D node."
+msgstr ""
+
+#: scene/2d/physics_body_2d.cpp
+msgid ""
+"Size changes to RigidBody2D (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/2d/remote_transform_2d.cpp
+msgid "Path property must point to a valid Node2D node to work."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "This Bone2D chain should end at a Skeleton2D node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
+msgstr ""
+
+#: scene/2d/skeleton_2d.cpp
+msgid ""
+"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
+msgstr ""
+
+#: scene/2d/tile_map.cpp
+msgid ""
+"TileMap with Use Parent on needs a parent CollisionObject2D to give shapes "
+"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
+"KinematicBody2D, etc. to give them a shape."
+msgstr ""
+
+#: scene/2d/visibility_notifier_2d.cpp
+msgid ""
+"VisibilityEnabler2D works best when used with the edited scene root directly "
+"as parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRCamera must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRController must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The controller ID must not be 0 or this controller won't be bound to an "
+"actual controller."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVRAnchor must have an ARVROrigin node as its parent."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid ""
+"The anchor ID must not be 0 or this anchor won't be bound to an actual "
+"anchor."
+msgstr ""
+
+#: scene/3d/arvr_nodes.cpp
+msgid "ARVROrigin requires an ARVRCamera child node."
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Finding meshes and lights"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Preparing geometry (%d/%d)"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Preparing environment"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Generating capture"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr ""
+
+#: scene/3d/baked_lightmap.cpp
+msgid "Done"
+msgstr ""
+
+#: scene/3d/collision_object.cpp
+msgid ""
+"This node has no shape, so it can't collide or interact with other objects.\n"
+"Consider adding a CollisionShape or CollisionPolygon as a child to define "
+"its shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid ""
+"CollisionPolygon only serves to provide a collision shape to a "
+"CollisionObject derived node. Please only use it as a child of Area, "
+"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_polygon.cpp
+msgid "An empty CollisionPolygon has no effect on collision."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"CollisionShape only serves to provide a collision shape to a CollisionObject "
+"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
+"KinematicBody, etc. to give them a shape."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"A shape must be provided for CollisionShape to function. Please create a "
+"shape resource for it."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"Plane shapes don't work well and will be removed in future versions. Please "
+"don't use them."
+msgstr ""
+
+#: scene/3d/collision_shape.cpp
+msgid ""
+"ConcavePolygonShape doesn't support RigidBody in another mode than static."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid "Nothing is visible because no mesh has been assigned."
+msgstr ""
+
+#: scene/3d/cpu_particles.cpp
+msgid ""
+"CPUParticles animation requires the usage of a SpatialMaterial whose "
+"Billboard Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Plotting Meshes"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr ""
+
+#: scene/3d/gi_probe.cpp
+msgid ""
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
+msgstr ""
+
+#: scene/3d/light.cpp
+msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
+msgstr ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid "A NavigationMesh resource must be set or created for this node to work."
+msgstr ""
+
+#: scene/3d/navigation_mesh.cpp
+msgid ""
+"NavigationMeshInstance must be a child or grandchild to a Navigation node. "
+"It only provides navigation data."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"GPU-based particles are not supported by the GLES2 video driver.\n"
+"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
+"\" option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Nothing is visible because meshes have not been assigned to draw passes."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"Particles animation requires the usage of a SpatialMaterial whose Billboard "
+"Mode is set to \"Particle Billboard\"."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid "PathFollow only works when set as a child of a Path node."
+msgstr ""
+
+#: scene/3d/path.cpp
+msgid ""
+"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
+"parent Path's Curve resource."
+msgstr ""
+
+#: scene/3d/physics_body.cpp
+msgid ""
+"Size changes to RigidBody (in character or rigid modes) will be overridden "
+"by the physics engine when running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A and Node B must be PhysicsBodies"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A must be a PhysicsBody"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node B must be a PhysicsBody"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Joint is not connected to any PhysicsBodies"
+msgstr ""
+
+#: scene/3d/physics_joint.cpp
+msgid "Node A and Node B must be different PhysicsBodies"
+msgstr ""
+
+#: scene/3d/remote_transform.cpp
+msgid ""
+"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
+"derived node to work."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid "This body will be ignored until you set a mesh."
+msgstr ""
+
+#: scene/3d/soft_body.cpp
+msgid ""
+"Size changes to SoftBody will be overridden by the physics engine when "
+"running.\n"
+"Change the size in children collision shapes instead."
+msgstr ""
+
+#: scene/3d/sprite_3d.cpp
+msgid ""
+"A SpriteFrames resource must be created or set in the \"Frames\" property in "
+"order for AnimatedSprite3D to display frames."
+msgstr ""
+
+#: scene/3d/vehicle_body.cpp
+msgid ""
+"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use "
+"it as a child of a VehicleBody."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"WorldEnvironment requires its \"Environment\" property to contain an "
+"Environment to have a visible effect."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."
+msgstr ""
+
+#: scene/3d/world_environment.cpp
+msgid ""
+"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set "
+"this environment's Background Mode to Canvas (for 2D scenes)."
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "On BlendTree node '%s', animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_blend_tree.cpp
+msgid "Animation not found: '%s'"
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "In node '%s', invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Invalid animation: '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Nothing connected to input '%s' of node '%s'."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "No root AnimationNode for the graph is set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path to an AnimationPlayer node containing animations is not set."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
+msgstr ""
+
+#: scene/animation/animation_tree.cpp
+msgid "The AnimationPlayer root node is not a valid node."
+msgstr ""
+
+#: scene/animation/animation_tree_player.cpp
+msgid "This node has been deprecated. Use AnimationTree instead."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid ""
+"Color: #%s\n"
+"LMB: Set color\n"
+"RMB: Remove preset"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Pick a color from the editor window."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "HSV"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Raw"
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Switch between hexadecimal and code values."
+msgstr ""
+
+#: scene/gui/color_picker.cpp
+msgid "Add current color as a preset."
+msgstr ""
+
+#: scene/gui/container.cpp
+msgid ""
+"Container by itself serves no purpose unless a script configures its "
+"children placement behavior.\n"
+"If you don't intend to add a script, use a plain Control node instead."
+msgstr ""
+
+#: scene/gui/control.cpp
+msgid ""
+"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to "
+"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Alert!"
+msgstr ""
+
+#: scene/gui/dialogs.cpp
+msgid "Please Confirm..."
+msgstr ""
+
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
+#: scene/gui/popup.cpp
+msgid ""
+"Popups will hide by default unless you call popup() or any of the popup*() "
+"functions. Making them visible for editing is fine, but they will hide upon "
+"running."
+msgstr ""
+
+#: scene/gui/range.cpp
+msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
+msgstr ""
+
+#: scene/gui/scroll_container.cpp
+msgid ""
+"ScrollContainer is intended to work with a single child control.\n"
+"Use a container as child (VBox, HBox, etc.), or a Control and set the custom "
+"minimum size manually."
+msgstr ""
+
+#: scene/gui/tree.cpp
+msgid "(Other)"
+msgstr ""
+
+#: scene/main/scene_tree.cpp
+msgid ""
+"Default Environment as specified in Project Settings (Rendering -> "
+"Environment -> Default Environment) could not be loaded."
+msgstr ""
+
+#: scene/main/viewport.cpp
+msgid ""
+"This viewport is not set as render target. If you intend for it to display "
+"its contents directly to the screen, make it a child of a Control so it can "
+"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
+"texture to some node for display."
+msgstr ""
+
+#: scene/main/viewport.cpp
+msgid "Viewport size must be greater than 0 to render anything."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid source for preview."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid source for shader."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
+msgid "Invalid comparison function for that type."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Assignment to uniform."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Varyings can only be assigned in vertex function."
+msgstr ""
+
+#: servers/visual/shader_language.cpp
+msgid "Constants cannot be modified."
+msgstr "КонÑтантите неможат да Ñе променат."
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index 346d52b331..fb9de4a419 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -1,6 +1,6 @@
# Malayalam translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# christy james <jkuttu@gmail.com>, 2018.
# Lakshmi-Jayakumar <lakshmi.jayakumar.tkm@gmail.com>, 2019.
@@ -629,7 +629,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1798,8 +1798,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1890,10 +1890,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2299,6 +2295,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2342,18 +2342,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2401,6 +2389,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2443,7 +2435,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2833,14 +2825,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2994,6 +2978,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3196,7 +3196,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3732,7 +3732,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3869,6 +3877,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4819,7 +4839,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4923,7 +4943,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4954,8 +4973,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4969,9 +4987,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6028,6 +6065,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6088,10 +6129,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6673,6 +6710,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6724,16 +6769,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6826,8 +6861,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7048,6 +7083,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8260,10 +8299,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8320,10 +8355,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9577,6 +9608,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9937,6 +9972,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10180,6 +10219,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10300,6 +10347,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11084,6 +11135,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11580,11 +11659,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11596,11 +11677,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11608,9 +11689,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11835,6 +11926,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12001,27 +12100,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12081,14 +12180,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12294,6 +12392,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12335,6 +12441,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/mr.po b/editor/translations/mr.po
index 8f588050ab..cf3a24a739 100644
--- a/editor/translations/mr.po
+++ b/editor/translations/mr.po
@@ -1,21 +1,21 @@
# Marathi translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Prachi Joshi <josprachi@yahoo.com>, 2019, 2020.
# Shirious <sad3119823@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2020-05-05 14:01+0000\n"
-"Last-Translator: Shirious <sad3119823@gmail.com>\n"
+"PO-Revision-Date: 2020-12-23 22:57+0000\n"
+"Last-Translator: Prachi Joshi <josprachi@yahoo.com>\n"
"Language-Team: Marathi <https://hosted.weblate.org/projects/godot-engine/"
"godot/mr/>\n"
"Language: mr\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.1-dev\n"
+"X-Generator: Weblate 4.4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -626,7 +626,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1795,8 +1795,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1887,10 +1887,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2294,6 +2290,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2337,18 +2337,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2396,6 +2384,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2438,7 +2430,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2828,14 +2820,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2854,11 +2838,11 @@ msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr ""
+msgstr "समà¥à¤¦à¤¾à¤¯"
#: editor/editor_node.cpp
msgid "About"
-msgstr ""
+msgstr "आमचà¥à¤¯à¤¾ बदà¥à¤¦à¤²"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -2989,6 +2973,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3191,7 +3191,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3727,7 +3727,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3864,6 +3872,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4811,7 +4831,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4915,7 +4935,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4946,8 +4965,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4961,9 +4979,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6019,6 +6056,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6079,10 +6120,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6664,6 +6701,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6715,16 +6760,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6817,8 +6852,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7039,6 +7074,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8250,10 +8289,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8310,10 +8345,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9568,6 +9599,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9838,7 +9873,7 @@ msgstr ""
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
-msgstr ""
+msgstr "सामानà¥à¤¯"
#: editor/project_settings_editor.cpp
msgid "Override For..."
@@ -9928,6 +9963,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10171,6 +10210,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10291,6 +10338,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11075,6 +11126,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11570,11 +11649,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11586,11 +11667,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11598,9 +11679,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11825,6 +11916,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -11991,27 +12090,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12071,14 +12170,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12284,6 +12382,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12325,6 +12431,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index d00dfd659f..c0a7f7cea2 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -1,6 +1,6 @@
# Malay translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Sam Vanguard <syafz119@gmail.com>, 2018.
# Shaqir Rafiq <moshamoradev@gmail.com>, 2018.
@@ -8,12 +8,12 @@
# Nafis Ibrahim <thepreciousnafis@gmail.com>, 2018.
# Muhammad Hazim bin Hafizalshah <muhammadhazimhafizalshah@gmail.com>, 2020.
# keviinx <keviinx@yahoo.com>, 2020.
-# Keviindran Ramachandran <keviinx@yahoo.com>, 2020.
+# Keviindran Ramachandran <keviinx@yahoo.com>, 2020, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-02 09:52+0000\n"
+"PO-Revision-Date: 2021-01-12 13:32+0000\n"
"Last-Translator: Keviindran Ramachandran <keviinx@yahoo.com>\n"
"Language-Team: Malay <https://hosted.weblate.org/projects/godot-engine/godot/"
"ms/>\n"
@@ -22,7 +22,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -649,7 +649,7 @@ msgstr "Pilih Trek untuk Disalin"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Salin"
@@ -1865,8 +1865,8 @@ msgid "Open a File or Directory"
msgstr "Buka Fail atau Direktori"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Simpan"
@@ -1957,10 +1957,6 @@ msgstr "Pratonton:"
msgid "File:"
msgstr "Fail:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Mesti menggunakan sambungan yang sah."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Sumber Imbas"
@@ -2323,6 +2319,8 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"Ralat berlaku semasa cubaan menyimpan susun atur editor.\n"
+"Pastikan laluan data pengguna editor dapat ditulis."
#: editor/editor_node.cpp
msgid ""
@@ -2330,6 +2328,9 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"Susun atur editor lalai diganti.\n"
+"Untuk mengembalikan susun atur Lalai ke tetapan asasnya, gunakan pilihan "
+"Hapus Tata Letak dan hapus susun atur Lalai."
#: editor/editor_node.cpp
msgid "Layout name not found!"
@@ -2394,6 +2395,10 @@ msgid "There is no defined scene to run."
msgstr "Tiada adegan yang didefinisikan untuk dijalankan."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Tidak dapat memulakan subproses!"
@@ -2437,18 +2442,6 @@ msgstr "Nod akar diperlukan untuk menyimpan adegan."
msgid "Save Scene As..."
msgstr "Simpan Adegan Sebagai..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Tidak"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Ya"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Adegan ini tidak pernah disimpan. Simpan sebelum menjalankan?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Operasi ini tidak boleh dilakukan tanpa adegan."
@@ -2499,6 +2492,10 @@ msgid "Quit"
msgstr "Keluar"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Ya"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Keluar dari editor?"
@@ -2541,49 +2538,64 @@ msgstr "Buka Semula Adegan Tertutup"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
+"Tidak dapat mengaktifkan pemalam addon pada: penghuraian konfigurasi '%s' "
+"gagal."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
+"Tidak dapat mencari medan skrip untuk pemalam addon di: 'res://addons/%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr ""
+msgstr "Tidak dapat memuatkan skrip addon dari laluan: '%s'."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
+"Tidak dapat memuat skrip addon dari laluan: '%s' Nampaknya terdapat ralat "
+"dalam kod, sila periksa sintaksnya."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
+"Tidak dapat memuatkan skrip addon dari laluan: '%s' Jenis Asas bukan "
+"EditorPlugin."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
msgstr ""
+"Tidak dapat memuat skrip addon dari laluan: Skrip '%s' tidak berada dalam "
+"mod alat."
#: editor/editor_node.cpp
msgid ""
"Scene '%s' was automatically imported, so it can't be modified.\n"
"To make changes to it, a new inherited scene can be created."
msgstr ""
+"Adegan '%s' diimport secara automatik, maka ia tidak dapat diubah.\n"
+"Untuk membuat perubahan, pemandangan baru yang diwarisi dapat dibuat."
#: editor/editor_node.cpp
msgid ""
"Error loading scene, it must be inside the project path. Use 'Import' to "
"open the scene, then save it inside the project path."
msgstr ""
+"Ralat memuatkan adegan, ia mesti berada di dalam laluan projek. Gunakan "
+"'Import' untuk membuka adegan, kemudian simpan di dalam laluan projek."
#: editor/editor_node.cpp
msgid "Scene '%s' has broken dependencies:"
-msgstr ""
+msgstr "Adegan '%s' mengandungi kebergantungan yang pecah:"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Clear Recent Scenes"
-msgstr ""
+msgstr "Kosongkan Adegan Terbaru"
#: editor/editor_node.cpp
msgid ""
@@ -2591,13 +2603,20 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"Tiada adegan utama yang pernah didefinasikan, pilih satu?\n"
+"Anda boleh mengubahnya kemudian dalam \"Tetapan Projek\" di bawah kategori "
+"'aplikasi'."
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
"Selected scene '%s' does not exist, select a valid one?\n"
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"Adegan terpilih '%s' tidak wujud, pilih satu yang sah?\n"
+"Anda boleh mengubahnya kemudian dalam \"Tetapan Projek\" di bawah kategori "
+"'aplikasi'."
#: editor/editor_node.cpp
msgid ""
@@ -2605,88 +2624,106 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"Adegan terpilih '%s' bukan fail adegan, pilih satu yang sah?\n"
+"Anda boleh mengubahnya kemudian dalam \"Tetapan Projek\" di bawah kategori "
+"'aplikasi'."
#: editor/editor_node.cpp
msgid "Save Layout"
-msgstr ""
+msgstr "Simpan Susun Atur"
#: editor/editor_node.cpp
msgid "Delete Layout"
-msgstr ""
+msgstr "Padam Susun Atur"
#: editor/editor_node.cpp editor/import_dock.cpp
#: editor/script_create_dialog.cpp
msgid "Default"
-msgstr ""
+msgstr "Lalai"
#: editor/editor_node.cpp editor/editor_properties.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
msgid "Show in FileSystem"
-msgstr ""
+msgstr "Tunjukkan dalam FileSystem"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Play This Scene"
-msgstr ""
+msgstr "Mainkan Adegan Ini"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Close Tab"
-msgstr ""
+msgstr "Tutup Tab"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Undo Close Tab"
-msgstr ""
+msgstr "Buat Asal Tutup Tab"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#, fuzzy
msgid "Close Other Tabs"
-msgstr ""
+msgstr "Tutup Tab Lain"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "Tutup Tab-tab ke Kanan"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Close All Tabs"
-msgstr ""
+msgstr "Tutup Semua Tab"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Switch Scene Tab"
-msgstr ""
+msgstr "Tukar Tab Adegan"
#: editor/editor_node.cpp
+#, fuzzy
msgid "%d more files or folders"
-msgstr ""
+msgstr "%d lebih banyak fail atau folder"
#: editor/editor_node.cpp
+#, fuzzy
msgid "%d more folders"
-msgstr ""
+msgstr "%d lebih banyak folder"
#: editor/editor_node.cpp
+#, fuzzy
msgid "%d more files"
-msgstr ""
+msgstr "%d lebih banyak fail"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Dock Position"
-msgstr ""
+msgstr "Kedudukan Dok"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Distraction Free Mode"
-msgstr ""
+msgstr "Mod Bebas Gangguan"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Toggle distraction-free mode."
-msgstr ""
+msgstr "Togol mod bebas gangguan."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Add a new scene."
-msgstr ""
+msgstr "Tambah adegan baru."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Scene"
-msgstr ""
+msgstr "Adegan"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Go to previously opened scene."
-msgstr ""
+msgstr "Pergi ke adegan yang dibuka sebelum ini."
#: editor/editor_node.cpp
#, fuzzy
@@ -2694,124 +2731,142 @@ msgid "Copy Text"
msgstr "Semua Pilihan"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Next tab"
-msgstr ""
+msgstr "Tab seterusnya"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Previous tab"
-msgstr ""
+msgstr "Tab terdahulu"
#: editor/editor_node.cpp
msgid "Filter Files..."
-msgstr ""
+msgstr "Tapis Fail-fail..."
#: editor/editor_node.cpp
msgid "Operations with scene files."
-msgstr ""
+msgstr "Operasi dengan fail adegan."
#: editor/editor_node.cpp
+#, fuzzy
msgid "New Scene"
-msgstr ""
+msgstr "Adegan Baru"
#: editor/editor_node.cpp
+#, fuzzy
msgid "New Inherited Scene..."
-msgstr ""
+msgstr "Adegan Baru Diwarisi..."
#: editor/editor_node.cpp
msgid "Open Scene..."
-msgstr ""
+msgstr "Buka Adegan..."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#, fuzzy
msgid "Open Recent"
-msgstr ""
+msgstr "Buka Terkini"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Save Scene"
-msgstr ""
+msgstr "Simpan Adegan"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Save All Scenes"
-msgstr ""
+msgstr "Simpan Semua Adegan"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Convert To..."
-msgstr ""
+msgstr "Tukar Kepada..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr ""
+msgstr "PerpustakaanMesh..."
#: editor/editor_node.cpp
msgid "TileSet..."
-msgstr ""
+msgstr "SetJubin..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Undo"
-msgstr ""
+msgstr "Buat Asal"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#, fuzzy
msgid "Redo"
-msgstr ""
+msgstr "Buat Semula"
#: editor/editor_node.cpp
msgid "Miscellaneous project or scene-wide tools."
-msgstr ""
+msgstr "Pelbagai projek atau alatan seluruh adegan."
#: editor/editor_node.cpp editor/project_manager.cpp
#: editor/script_create_dialog.cpp
+#, fuzzy
msgid "Project"
-msgstr ""
+msgstr "Projek"
#: editor/editor_node.cpp
msgid "Project Settings..."
-msgstr ""
+msgstr "Tetapan Projek..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Version Control"
-msgstr ""
+msgstr "Kawalan Versi"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Set Up Version Control"
-msgstr ""
+msgstr "Sediakan Kawalan Versi"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "Tutup Kawalan Versi"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Export..."
-msgstr ""
+msgstr "Eksport..."
#: editor/editor_node.cpp
msgid "Install Android Build Template..."
-msgstr ""
+msgstr "Pasang Templat Binaan Android..."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open Project Data Folder"
-msgstr ""
+msgstr "Buka Folder Data Projek"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
-msgstr ""
+msgstr "Alatan"
#: editor/editor_node.cpp
msgid "Orphan Resource Explorer..."
-msgstr ""
+msgstr "Penjelajah Sumber Yatim..."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Quit to Project List"
-msgstr ""
+msgstr "Keluar ke Senarai Projek"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
+#, fuzzy
msgid "Debug"
-msgstr ""
+msgstr "Nyahpepijat"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Deploy with Remote Debug"
-msgstr ""
+msgstr "Gunakan Nyahpepijat Jauh"
#: editor/editor_node.cpp
msgid ""
@@ -2822,12 +2877,20 @@ msgid ""
"mobile device).\n"
"You don't need to enable it to use the GDScript debugger locally."
msgstr ""
+"Apabila pilihan ini diaktifkan, penggunaan satu klik akan membuat percubaan "
+"yang dapat dilaksanakan untuk menyambung ke IP komputer ini sehingga projek "
+"yang sedang berjalan dapat dinyahpepijat.\n"
+"Pilihan ini bertujuan untuk digunakan untuk penyahpepijatan jauh (biasanya "
+"dengan peranti mudah alih).\n"
+"Anda tidak perlu mengaktifkannya untuk menggunakan debugger GDScript secara "
+"tempatan."
#: editor/editor_node.cpp
msgid "Small Deploy with Network Filesystem"
-msgstr ""
+msgstr "Penggunaan Kecil dengan Sistem Fail Rangkaian"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
"When this option is enabled, using one-click deploy for Android will only "
"export an executable without the project data.\n"
@@ -2836,30 +2899,43 @@ msgid ""
"On Android, deploying will use the USB cable for faster performance. This "
"option speeds up testing for projects with large assets."
msgstr ""
+"Apabila pilihan ini diaktifkan, menggunakan satu klik untuk Android hanya "
+"akan mengeksport yang dapat dilaksanakan tanpa data projek.\n"
+"Sistem fail akan disediakan dari projek oleh editor melalui rangkaian.\n"
+"Pada Android, penggunaan akan menggunakan kabel USB untuk prestasi yang "
+"lebih pantas. Pilihan ini mempercepat pengujian untuk projek dengan aset "
+"besar."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Visible Collision Shapes"
-msgstr ""
+msgstr "Bentuk Perlanggaran Yang Boleh Dilihat"
#: editor/editor_node.cpp
msgid ""
"When this option is enabled, collision shapes and raycast nodes (for 2D and "
"3D) will be visible in the running project."
msgstr ""
+"Apabila pilihan ini diaktifkan, bentuk perlanggaran dan nod raycast (untuk "
+"2D dan 3D) akan dapat dilihat dalam projek yang sedang berjalan."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Visible Navigation"
-msgstr ""
+msgstr "Navigasi Yang Boleh Dilihat"
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
"When this option is enabled, navigation meshes and polygons will be visible "
"in the running project."
msgstr ""
+"Apabila pilihan ini diaktifkan, jejaring navigasi dan poligon akan kelihatan "
+"dalam projek yang sedang berjalan."
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
-msgstr ""
+msgstr "Segerakkan Perubahan Adegan"
#: editor/editor_node.cpp
msgid ""
@@ -2868,10 +2944,15 @@ msgid ""
"When used remotely on a device, this is more efficient when the network "
"filesystem option is enabled."
msgstr ""
+"Apabila pilihan ini diaktifkan, setiap perubahan yang dibuat ke adegan di "
+"editor akan direplikasi dalam projek yang sedang berjalan.\n"
+"Apabila digunakan dari jauh pada peranti, ini lebih efisien apabila pilihan "
+"sistem fail rangkaian diaktifkan."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Synchronize Script Changes"
-msgstr ""
+msgstr "Segerakkan Perubahan Skrip"
#: editor/editor_node.cpp
msgid ""
@@ -2880,10 +2961,15 @@ msgid ""
"When used remotely on a device, this is more efficient when the network "
"filesystem option is enabled."
msgstr ""
+"Apabila pilihan ini diaktifkan, skrip yang disimpan akan dimuat semula dalam "
+"projek yang sedang berjalan.\n"
+"Apabila digunakan dari jauh pada peranti, ini lebih efisien apabila pilihan "
+"sistem fail rangkaian diaktifkan."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
+#, fuzzy
msgid "Editor"
-msgstr ""
+msgstr "Editor"
#: editor/editor_node.cpp
msgid "Editor Settings..."
@@ -2891,72 +2977,71 @@ msgstr "Tetapan Editor..."
#: editor/editor_node.cpp
msgid "Editor Layout"
-msgstr ""
+msgstr "Editor Susun Atur"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Take Screenshot"
-msgstr ""
+msgstr "Ambil Tangkapan Skrin"
#: editor/editor_node.cpp
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr ""
+msgstr "Tangkapan skrin disimpan dalam Folder Data/Tetapan Editor."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Toggle Fullscreen"
-msgstr ""
+msgstr "Togol Skrin Penuh"
#: editor/editor_node.cpp
msgid "Toggle System Console"
-msgstr ""
+msgstr "Togol Konsol Sistem"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
-msgstr ""
+msgstr "Buka Folder Data/Tetapan Editor"
#: editor/editor_node.cpp
msgid "Open Editor Data Folder"
-msgstr ""
+msgstr "Buka Folder Data Editor"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open Editor Settings Folder"
-msgstr ""
+msgstr "Buka Folder Tetapan Editor"
#: editor/editor_node.cpp
msgid "Manage Editor Features..."
-msgstr ""
+msgstr "Urus Ciri-ciri Penyunting..."
#: editor/editor_node.cpp
msgid "Manage Export Templates..."
-msgstr ""
+msgstr "Urus Templat-templat Eksport..."
#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
+msgstr "Bantuan"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
+#, fuzzy
msgid "Online Docs"
-msgstr ""
+msgstr "Dokumen Dalam Talian"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Q&A"
-msgstr ""
+msgstr "Soal Jawab"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Report a Bug"
-msgstr ""
+msgstr "Laporkan Pepijat"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Hantar Maklum Balas Dokumen"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -2967,93 +3052,102 @@ msgid "About"
msgstr "Tentang"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Play the project."
-msgstr ""
+msgstr "Main projek."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Play"
-msgstr ""
+msgstr "Main"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr ""
+msgstr "Jeda pelaksanaan adegan untuk nyahpepijat."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Pause Scene"
-msgstr ""
+msgstr "Jeda Adegan"
#: editor/editor_node.cpp
msgid "Stop the scene."
-msgstr ""
+msgstr "Hentikan adegan."
#: editor/editor_node.cpp
msgid "Play the edited scene."
-msgstr ""
+msgstr "Mainkan adegan yang diedit."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr ""
+msgstr "Main Adegan"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Play custom scene"
-msgstr ""
+msgstr "Main adegan tersuai"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Play Custom Scene"
-msgstr ""
+msgstr "Main Adegan Tersuai"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
-msgstr ""
+msgstr "Menukar pemacu video memerlukan editor dimulakan semula."
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
msgid "Save & Restart"
-msgstr ""
+msgstr "Simpan & Mula Semula"
#: editor/editor_node.cpp
msgid "Spins when the editor window redraws."
-msgstr ""
+msgstr "Berputar apabila tingkap editor dilukis semula."
#: editor/editor_node.cpp
msgid "Update Continuously"
-msgstr ""
+msgstr "Kemas Kini Secara Berterusan"
#: editor/editor_node.cpp
msgid "Update When Changed"
-msgstr ""
+msgstr "Kemas Kini Apabila Diubah"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Hide Update Spinner"
-msgstr ""
+msgstr "Sembunyi Spinner Kemas Kini"
#: editor/editor_node.cpp
msgid "FileSystem"
-msgstr ""
+msgstr "SistemFail"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Inspector"
-msgstr ""
+msgstr "Pemeriksa"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Expand Bottom Panel"
-msgstr ""
+msgstr "Kembangkan Panel Bawah"
#: editor/editor_node.cpp
msgid "Output"
-msgstr ""
+msgstr "Keluaran"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Don't Save"
-msgstr ""
+msgstr "Jangan Simpan"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
-msgstr ""
+msgstr "Templat binaan Android hilang, sila pasang templat yang berkaitan."
#: editor/editor_node.cpp
msgid "Manage Templates"
-msgstr ""
+msgstr "Urus Templat-templat"
#: editor/editor_node.cpp
msgid ""
@@ -3065,6 +3159,14 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
+"Ini akan menyiapkan projek anda untuk binaan Android khas dengan memasang "
+"templat sumber pada \"res://android/build\".\n"
+"Anda kemudian boleh menerapkan pengubahsuaian dan membina APK tersuai anda "
+"sendiri pada eksport (menambah modul, menukar AndroidManifest.xml, dan lain-"
+"lain).\n"
+"Perhatikan bahawa untuk membuat binaan tersuai dan bukannya menggunakan APK "
+"pra-dibina, pilihan \"Gunakan Bina Tersuai\" harus diaktifkan dalam pratetap "
+"eksport Android."
#: editor/editor_node.cpp
msgid ""
@@ -3073,191 +3175,251 @@ msgid ""
"Remove the \"res://android/build\" directory manually before attempting this "
"operation again."
msgstr ""
+"Templat binaan Android telah dipasang dalam projek ini dan ia tidak akan "
+"ditimpa.\n"
+"Keluarkan direktori \"res://android/build\" secara manual sebelum mencuba "
+"operasi ini semula."
#: editor/editor_node.cpp
+#, fuzzy
msgid "Import Templates From ZIP File"
-msgstr ""
+msgstr "Import Templat Dari Fail ZIP"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Template Package"
-msgstr ""
+msgstr "Pakej Templat"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Export Library"
-msgstr ""
+msgstr "Eksport Perpustakaan"
#: editor/editor_node.cpp
msgid "Merge With Existing"
-msgstr ""
+msgstr "Gabung Dengan Sedia Ada"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open & Run a Script"
+msgstr "Buka & Jalankan Skrip"
+
+#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr "Fail berikut gagal diekstrak dari pakej:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
msgstr ""
#: editor/editor_node.cpp
+#, fuzzy
msgid "New Inherited"
-msgstr ""
+msgstr "Baru Diwarisi"
#: editor/editor_node.cpp
msgid "Load Errors"
-msgstr ""
+msgstr "Muatkan Ralat-ralat"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#, fuzzy
msgid "Select"
-msgstr ""
+msgstr "Pilih"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open 2D Editor"
-msgstr ""
+msgstr "Buka Editor 2D"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open 3D Editor"
-msgstr ""
+msgstr "Buka Editor 3D"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open Script Editor"
-msgstr ""
+msgstr "Buka Editor Skrip"
#: editor/editor_node.cpp editor/project_manager.cpp
+#, fuzzy
msgid "Open Asset Library"
-msgstr ""
+msgstr "Buka Perpustakaan Aset"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open the next Editor"
-msgstr ""
+msgstr "Buka Editor seterusnya"
#: editor/editor_node.cpp
+#, fuzzy
msgid "Open the previous Editor"
-msgstr ""
+msgstr "Buka Editor terdahulu"
#: editor/editor_node.h
+#, fuzzy
msgid "Warning!"
-msgstr ""
+msgstr "Amaran!"
#: editor/editor_path.cpp
msgid "No sub-resources found."
-msgstr ""
+msgstr "Tiada sub-sumber dijumpai."
#: editor/editor_plugin.cpp
+#, fuzzy
msgid "Creating Mesh Previews"
-msgstr ""
+msgstr "Mencipta Pratonton Mesh"
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
-msgstr ""
+msgstr "Gambar kecil..."
#: editor/editor_plugin_settings.cpp
+#, fuzzy
msgid "Main Script:"
-msgstr ""
+msgstr "Skrip Utama:"
#: editor/editor_plugin_settings.cpp
msgid "Edit Plugin"
-msgstr ""
+msgstr "Sunting Plugin"
#: editor/editor_plugin_settings.cpp
msgid "Installed Plugins:"
-msgstr ""
+msgstr "Plugin yang Dipasang:"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#, fuzzy
msgid "Update"
-msgstr ""
+msgstr "Kemas kini"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Version:"
-msgstr ""
+msgstr "Versi:"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
+#, fuzzy
msgid "Author:"
-msgstr ""
+msgstr "Pengarang:"
#: editor/editor_plugin_settings.cpp
+#, fuzzy
msgid "Status:"
-msgstr ""
+msgstr "Status:"
#: editor/editor_plugin_settings.cpp
msgid "Edit:"
-msgstr ""
+msgstr "Sunting:"
#: editor/editor_profiler.cpp
msgid "Measure:"
-msgstr ""
+msgstr "Ukur:"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Frame Time (sec)"
-msgstr ""
+msgstr "Masa Bingkai (saat)"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Average Time (sec)"
-msgstr ""
+msgstr "Masa Purata (saat)"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Frame %"
-msgstr ""
+msgstr "Bingkai %"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Physics Frame %"
-msgstr ""
+msgstr "Bingkai Fizik %"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Inclusive"
-msgstr ""
+msgstr "Inklusif"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Self"
-msgstr ""
+msgstr "Diri"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Frame #:"
-msgstr ""
+msgstr "Bingkai #:"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Time"
-msgstr ""
+msgstr "Masa"
#: editor/editor_profiler.cpp
+#, fuzzy
msgid "Calls"
-msgstr ""
+msgstr "Panggilan"
#: editor/editor_properties.cpp
msgid "Edit Text:"
-msgstr ""
+msgstr "Sunting Teks:"
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
-msgstr ""
+msgstr "Hidupkan"
#: editor/editor_properties.cpp
+#, fuzzy
msgid "Layer"
-msgstr ""
+msgstr "Lapisan"
#: editor/editor_properties.cpp
+#, fuzzy
msgid "Bit %d, value %d"
-msgstr ""
+msgstr "Bit %d, nilai %d"
#: editor/editor_properties.cpp
+#, fuzzy
msgid "[Empty]"
-msgstr ""
+msgstr "[Kosong]"
#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
+#, fuzzy
msgid "Assign..."
-msgstr ""
+msgstr "Menguntukkan..."
#: editor/editor_properties.cpp
+#, fuzzy
msgid "Invalid RID"
-msgstr ""
+msgstr "RID tidak sah"
#: editor/editor_properties.cpp
msgid ""
"The selected resource (%s) does not match any type expected for this "
"property (%s)."
msgstr ""
+"Sumber yang dipilih (%s) tidak sesuai dengan jenis yang diharapkan untuk "
+"sifat ini (%s)."
#: editor/editor_properties.cpp
+#, fuzzy
msgid ""
"Can't create a ViewportTexture on resources saved as a file.\n"
"Resource needs to belong to a scene."
msgstr ""
+"Tidak dapat mencipta ViewportTexture pada sumber yang disimpan sebagai "
+"fail.\n"
+"Sumber perlu tergolong dalam adegan."
#: editor/editor_properties.cpp
msgid ""
@@ -3266,26 +3428,34 @@ msgid ""
"Please switch on the 'local to scene' property on it (and all resources "
"containing it up to a node)."
msgstr ""
+"Tidak dapat mencipta ViewportTexture pada sumber ini kerana ia tidak "
+"disetkan sebagai adegan tempatan.\n"
+"Sila hidupkan sifat 'tempatan ke tempat kejadian' di atasnya (dan semua "
+"sumber yang mengandunginya sehingga ke nod)."
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Pick a Viewport"
-msgstr ""
+msgstr "Pilih Viewport"
#: editor/editor_properties.cpp editor/property_editor.cpp
+#, fuzzy
msgid "New Script"
-msgstr ""
+msgstr "Skrip Baru"
#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Extend Script"
-msgstr ""
+msgstr "Lanjutkan Skrip"
#: editor/editor_properties.cpp editor/property_editor.cpp
+#, fuzzy
msgid "New %s"
-msgstr ""
+msgstr "%s baru"
#: editor/editor_properties.cpp editor/property_editor.cpp
+#, fuzzy
msgid "Make Unique"
-msgstr ""
+msgstr "Buat Unik"
#: editor/editor_properties.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
@@ -3297,42 +3467,49 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#, fuzzy
msgid "Paste"
-msgstr ""
+msgstr "Tampal"
#: editor/editor_properties.cpp editor/property_editor.cpp
+#, fuzzy
msgid "Convert To %s"
-msgstr ""
+msgstr "Tukar Kepada %s"
#: editor/editor_properties.cpp editor/property_editor.cpp
+#, fuzzy
msgid "Selected node is not a Viewport!"
-msgstr ""
+msgstr "Node yang dipilih bukan Viewport!"
#: editor/editor_properties_array_dict.cpp
+#, fuzzy
msgid "Size: "
-msgstr ""
+msgstr "Saiz: "
#: editor/editor_properties_array_dict.cpp
+#, fuzzy
msgid "Page: "
-msgstr ""
+msgstr "Halaman: "
#: editor/editor_properties_array_dict.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove Item"
-msgstr ""
+msgstr "Keluarkan Item"
#: editor/editor_properties_array_dict.cpp
+#, fuzzy
msgid "New Key:"
-msgstr ""
+msgstr "Kunci Baru:"
#: editor/editor_properties_array_dict.cpp
+#, fuzzy
msgid "New Value:"
-msgstr ""
+msgstr "Nilai Baru:"
#: editor/editor_properties_array_dict.cpp
msgid "Add Key/Value Pair"
-msgstr ""
+msgstr "Tambah Pasangan Kunci/Nilai"
#: editor/editor_run_native.cpp
msgid ""
@@ -3340,157 +3517,189 @@ msgid ""
"Please add a runnable preset in the Export menu or define an existing preset "
"as runnable."
msgstr ""
+"Tiada pratetap eksport yang dapat dijalankan untuk platform ini.\n"
+"Sila tambah pratetap yang dapat dijalankan di menu Eksport atau tentukan "
+"pratetap yang ada sebagai yang dapat dijalankan."
#: editor/editor_run_script.cpp
+#, fuzzy
msgid "Write your logic in the _run() method."
-msgstr ""
+msgstr "Tulis logik anda dalam kaedah _run()."
#: editor/editor_run_script.cpp
msgid "There is an edited scene already."
-msgstr ""
+msgstr "Sudah ada adegan yang diedit."
#: editor/editor_run_script.cpp
msgid "Couldn't instance script:"
-msgstr ""
+msgstr "Tidak dapat meng-instance skrip:"
#: editor/editor_run_script.cpp
msgid "Did you forget the 'tool' keyword?"
-msgstr ""
+msgstr "Adakah anda lupa kata kunci 'tool'?"
#: editor/editor_run_script.cpp
+#, fuzzy
msgid "Couldn't run script:"
-msgstr ""
+msgstr "Tidak dapat menjalankan skrip:"
#: editor/editor_run_script.cpp
+#, fuzzy
msgid "Did you forget the '_run' method?"
-msgstr ""
+msgstr "Adakah anda lupa kaedah '_run'?"
#: editor/editor_spin_slider.cpp
msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes."
msgstr ""
+"Tahan Ctrl untuk bundarkan ke integer. Tahan Shift untuk perubahan yang "
+"lebih tepat."
#: editor/editor_sub_scene.cpp
msgid "Select Node(s) to Import"
-msgstr ""
+msgstr "Pilih Nod(Nod-nod) untuk Diimport"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
+#, fuzzy
msgid "Browse"
-msgstr ""
+msgstr "Layari"
#: editor/editor_sub_scene.cpp
+#, fuzzy
msgid "Scene Path:"
-msgstr ""
+msgstr "Laluan Adegan:"
#: editor/editor_sub_scene.cpp
+#, fuzzy
msgid "Import From Node:"
-msgstr ""
+msgstr "Import Dari Nod:"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Redownload"
-msgstr ""
+msgstr "Muat turun semula"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Uninstall"
-msgstr ""
+msgstr "Nyahpasang"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "(Installed)"
-msgstr ""
+msgstr "(Dipasang)"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Download"
-msgstr ""
+msgstr "Muat turun"
#: editor/export_template_manager.cpp
msgid "Official export templates aren't available for development builds."
-msgstr ""
+msgstr "Templat eksport rasmi tidak tersedia untuk binaan pembangunan."
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "(Missing)"
-msgstr ""
+msgstr "(Hilang)"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "(Current)"
-msgstr ""
+msgstr "(Semasa)"
#: editor/export_template_manager.cpp
msgid "Retrieving mirrors, please wait..."
-msgstr ""
+msgstr "Mengambil maklumat cermin, sila tunggu..."
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Remove template version '%s'?"
-msgstr ""
+msgstr "Alih keluar versi templat '%s'?"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Can't open export templates zip."
-msgstr ""
+msgstr "Tidak dapat membuka zip templat eksport."
#: editor/export_template_manager.cpp
msgid "Invalid version.txt format inside templates: %s."
-msgstr ""
+msgstr "Format version.txt tidak sah di dalam templat: %s."
#: editor/export_template_manager.cpp
msgid "No version.txt found inside templates."
-msgstr ""
+msgstr "Tiada version.txt dijumpai di dalam templat."
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Error creating path for templates:"
-msgstr ""
+msgstr "Ralat mencipta laluan untuk templat:"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Extracting Export Templates"
-msgstr ""
+msgstr "Mengekstrak Templat Eksport"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Importing:"
-msgstr ""
+msgstr "Mengimport:"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Error getting the list of mirrors."
-msgstr ""
+msgstr "Ralat mendapatkan senarai cermin."
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Error parsing JSON of mirror list. Please report this issue!"
-msgstr ""
+msgstr "Ralat menghuraikan JSON senarai cermin. Sila laporkan isu ini!"
#: editor/export_template_manager.cpp
msgid ""
"No download links found for this version. Direct download is only available "
"for official releases."
msgstr ""
+"Tiada pautan muat turun ditemui untuk versi ini. Muat turun langsung hanya "
+"tersedia untuk siaran rasmi."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Can't resolve."
-msgstr ""
+msgstr "Tidak dapat menyelesaikan."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Can't connect."
-msgstr ""
+msgstr "Tidak dapat menyambung."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "No response."
-msgstr ""
+msgstr "Tiada jawapan."
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Request Failed."
-msgstr ""
+msgstr "Permintaan Gagal."
#: editor/export_template_manager.cpp
msgid "Redirect Loop."
-msgstr ""
+msgstr "Ubah Hala Gelung."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Failed:"
-msgstr ""
+msgstr "Gagal:"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Download Complete."
-msgstr ""
+msgstr "Muat turun Selesai."
#: editor/export_template_manager.cpp
msgid "Cannot remove temporary file:"
@@ -3834,8 +4043,19 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr ""
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d padan."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d padan."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d padan."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -3972,6 +4192,21 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Pilih Nod(Nod-nod) untuk Diimport"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Import"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Muatkan Lalai"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4922,7 +5157,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5028,7 +5263,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5059,8 +5293,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5074,9 +5307,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6138,6 +6390,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6198,10 +6454,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6783,6 +7035,15 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+#, fuzzy
+msgid "Search"
+msgstr "Cari"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6834,16 +7095,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6936,8 +7187,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7159,6 +7410,11 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Saiz: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8379,10 +8635,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8443,10 +8695,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9703,6 +9951,11 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Mengambil maklumat cermin, sila tunggu..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10063,6 +10316,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Muatkan Lalai"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10125,9 +10383,8 @@ msgid "Batch Rename"
msgstr "Ubah Nama Trek Anim"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Replace:"
-msgstr "Ganti"
+msgstr "Ganti:"
#: editor/rename_dialog.cpp
msgid "Prefix:"
@@ -10308,6 +10565,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Anim Menduakan Kunci"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10429,6 +10695,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Anim Menduakan Kunci"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11217,6 +11488,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11716,11 +12015,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11732,11 +12033,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11744,9 +12045,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11971,6 +12282,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12137,27 +12456,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12217,14 +12536,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12430,6 +12748,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Mesti menggunakan sambungan yang sah."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12471,6 +12797,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
@@ -12498,6 +12830,12 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No"
+#~ msgstr "Tidak"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Adegan ini tidak pernah disimpan. Simpan sebelum menjalankan?"
+
#~ msgid "Error trying to save layout!"
#~ msgstr "Ralat semasa menyimpan susun atur!"
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index b1bb5ead4b..9e69510739 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -1,26 +1,27 @@
# Norwegian Bokmål translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
-# Allan Nordhøy <epost@anotheragency.no>, 2017-2018, 2019, 2020.
-# Anonymous <GentleSaucepan@protonmail.com>, 2017.
+# Allan Nordhøy <epost@anotheragency.no>, 2017-2018, 2019, 2020, 2021.
+# Anonymous <GentleSaucepan@protonmail.com>, 2017, 2021.
# Elias <eliasnykrem@gmail.com>, 2018.
# flesk <eivindkn@gmail.com>, 2017, 2019.
-# Frank T. Rambol <frank@d-fect.com>, 2018.
+# Frank T. Rambol <frank@d-fect.com>, 2018, 2021.
# Jørgen Aarmo Lund <jorgen.aarmo@gmail.com>, 2016, 2019.
-# NicolaiF <nico-fre@hotmail.com>, 2017-2018, 2019.
+# NicolaiF <nico-fre@hotmail.com>, 2017-2018, 2019, 2021.
# Norwegian Disaster <stian.furu.overbye@gmail.com>, 2017.
# passeride <lukas@passeride.com>, 2017.
# Byzantin <kasper-hoel@hotmail.com>, 2018.
# Hans-Marius Øverås <hansmariusoveras@gmail.com>, 2019.
# Revolution <revosw@gmail.com>, 2019.
# Petter Reinholdtsen <pere-weblate@hungry.com>, 2019, 2020.
+# Patrick Sletvold <patricksletvold@hotmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-10-09 05:49+0000\n"
-"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
+"PO-Revision-Date: 2021-02-27 00:47+0000\n"
+"Last-Translator: Anonymous <GentleSaucepan@protonmail.com>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/godot-"
"engine/godot/nb_NO/>\n"
"Language: nb\n"
@@ -28,7 +29,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.3-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -200,7 +201,6 @@ msgid "Change Animation Loop"
msgstr "Endre Animasjonssløyfe"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Property Track"
msgstr "Egenskapsspor"
@@ -209,24 +209,20 @@ msgid "3D Transform Track"
msgstr "3D transformasjonsspor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Call Method Track"
msgstr "Kall metode-spor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Bezier Curve Track"
-msgstr "Bezier-kurvespor"
+msgstr "Bézier-kurvespor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Audio Playback Track"
msgstr "Lydavspillingsspor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Playback Track"
-msgstr "Stopp avspilling av animasjon. (S)"
+msgstr "Animasjonavspillingspor"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
@@ -241,7 +237,6 @@ msgid "Add Track"
msgstr "Legg til Spor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Looping"
msgstr "Animasjonsløkke"
@@ -260,23 +255,20 @@ msgid "Anim Clips:"
msgstr "Anim-klipp:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Track Path"
-msgstr "Endre Array-verdi"
+msgstr "Endre sporsti"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Toggle this track on/off."
-msgstr "Vis/skjul distraksjonsfri modus."
+msgstr "Slå spor på/av."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
msgstr "Oppdateringsmodus (Hvordan denne egenskapen settes)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Interpolation Mode"
-msgstr "Animasjonsnode"
+msgstr "Interpolasjonsmodus"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
@@ -334,7 +326,7 @@ msgstr "Pakk Inn Sløyfeinterp"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr "Sett inn Nøkkel"
+msgstr "Sett inn nøkkel"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
@@ -345,19 +337,16 @@ msgid "Delete Key(s)"
msgstr "Fjern Nøkler"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Update Mode"
-msgstr "Endre Animasjonsnavn:"
+msgstr "Endre oppdateringsmetode for animasjon"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Interpolation Mode"
-msgstr "Animasjonsnode"
+msgstr "Endre interpolasjonsmodus for animasjon"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Change Animation Loop Mode"
-msgstr "Endre Anim-Løkke"
+msgstr "Endre løkkemodus for animasjon"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
@@ -412,9 +401,8 @@ msgid "Rearrange Tracks"
msgstr "Omorganiser Spor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr "Transformasjonsspor kan kun brukes på Spatial-baserte noder."
+msgstr "Transformeringsspor virker kun på Spatial-baserte noder."
#: editor/animation_track_editor.cpp
msgid ""
@@ -438,47 +426,40 @@ msgstr ""
"En animansjonsavspiller kan ikke animere seg selv, kun andre avspillere."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Not possible to add a new track without a root"
msgstr "Ikke mulig å legge til et nytt spor uten en rot"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr ""
+msgstr "Ugyldig spor for Bézier (ingen passende underegenskaper)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Bezier Track"
-msgstr "Anim Legg til Spor"
+msgstr "Legg til Bézier-spor"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Track path is invalid, so can't add a key."
msgstr "Sporsti er ugyldig, så kan ikke legge til en nøkkel."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Track is not of type Spatial, can't insert key"
-msgstr "Spor er ikke av type Spatial, kan ikke legge til nøkkel"
+msgstr "Spor er ikke av typen Spatial, kan ikke sette inn nøkkel"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Transform Track Key"
-msgstr "3D transformasjonsspor"
+msgstr "Legg til transformasjons-spornøkkel"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track Key"
-msgstr "Anim Legg til Spor"
+msgstr "Legg til spornøkkel"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a method key."
msgstr "Sporsti er ugyldig, så kan ikke legge til en metodenøkkel."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Method Track Key"
-msgstr "Kall metode-spor"
+msgstr "Legg til metode-spornøkkel"
#: editor/animation_track_editor.cpp
msgid "Method not found in object: "
@@ -489,26 +470,22 @@ msgid "Anim Move Keys"
msgstr "Anim Flytt Nøkler"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Clipboard is empty"
-msgstr "Ressurs-utklippstavle er tom!"
+msgstr "Utklippstavlen er tom"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Paste Tracks"
-msgstr "Lim inn Parametre"
+msgstr "Sett in spor"
#: editor/animation_track_editor.cpp
msgid "Anim Scale Keys"
msgstr "Anim Skalér Nøkler"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
msgstr ""
-"Dette valget virker ikke på Bezier-redigering, siden det kun er ett enkelt "
-"spor."
+"Dette valget virker ikke på Bézier-redigering, da det kun er ett enkelt spor."
#: editor/animation_track_editor.cpp
msgid ""
@@ -522,10 +499,19 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"Denne animasjonen hører til en importert scene, så endringer på importerte "
+"spor vil ikke bli lagret.\n"
+"\n"
+"For å legge til egendefinerte spor, gå til scenens importinstillinger og "
+"sett\n"
+"\"Animasjon > Lagring\" til \"Filer\", aktiver \"Animasjon > Behold egne spor"
+"\", og importer på nytt.\n"
+"Alternativt, bruk et importoppsett som importerer animasjonen som separate "
+"filer."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
-msgstr ""
+msgstr "Advarsel: Redigerer importert animasjon"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -570,9 +556,8 @@ msgid "Edit"
msgstr "Rediger"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation properties."
-msgstr "Animasjon"
+msgstr "Animasjon egenskaper."
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -589,26 +574,23 @@ msgstr "Skaler Fra Peker"
#: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp
msgid "Duplicate Selection"
-msgstr "Dupliser Utvalg"
+msgstr "Dupliser utvalg"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr "Dupliser Transponert"
+msgstr "Dupliser transponert"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Delete Selection"
-msgstr "Slett Valgte"
+msgstr "Slett valgte"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Next Step"
-msgstr "GÃ¥ til Neste Steg"
+msgstr "GÃ¥ til neste steg"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Go to Previous Step"
-msgstr "GÃ¥ til Forrige Steg"
+msgstr "GÃ¥ til forrige steg"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
@@ -671,16 +653,15 @@ msgid "Scale Ratio:"
msgstr "Skaler Størrelsesforhold:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select Tracks to Copy"
-msgstr "Velg spor å kopiere:"
+msgstr "Velg spor å kopiere"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Lim inn"
@@ -690,9 +671,8 @@ msgid "Select All/None"
msgstr "Kutt Noder"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "Lydklipp:"
+msgstr "Legg til lyd-spor klipp"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
@@ -723,19 +703,16 @@ msgid "Line Number:"
msgstr "Linjenummer:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "Erstatt..."
+msgstr "%d erstattet."
#: editor/code_editor.cpp editor/editor_help.cpp
-#, fuzzy
msgid "%d match."
-msgstr "%d samsvar."
+msgstr "%d samsvarer."
#: editor/code_editor.cpp editor/editor_help.cpp
-#, fuzzy
msgid "%d matches."
-msgstr "Ingen Treff"
+msgstr "%d sammsvarer."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -760,7 +737,7 @@ msgstr "Kun Valgte"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
msgid "Standard"
-msgstr ""
+msgstr "Standard"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
@@ -791,9 +768,8 @@ msgid "Line and column numbers."
msgstr "Linje- og kolonnenummer."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method in target node must be specified."
-msgstr "Metode i mål-Node må spesifiseres!"
+msgstr "Metode i målnoden må spesifiseres."
#: editor/connections_dialog.cpp
#, fuzzy
@@ -820,13 +796,12 @@ msgid "Connect to Script:"
msgstr "Kan ikke koble til tjener:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "From Signal:"
-msgstr "Signaler:"
+msgstr "Fra signal:"
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
-msgstr ""
+msgstr "Scenen inneholder ikke noen skript."
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
@@ -854,14 +829,12 @@ msgid "Extra Call Arguments:"
msgstr "Ekstra Call Argumenter:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Receiver Method:"
-msgstr "Lim inn Noder"
+msgstr "Mottakermetode:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Advanced"
-msgstr "Snapping innstillinger"
+msgstr "Avansert"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -1064,9 +1037,8 @@ msgid "Fix Broken"
msgstr "Reparer Ødelagt"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Dependency Editor"
-msgstr "Avhengighetsredigeringsverktøy"
+msgstr "Redigeringsverktøy for avhengigheter"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
@@ -1087,14 +1059,15 @@ msgid "Owners Of:"
msgstr "Eiere Av:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "Fjerne valgte filer fra prosjektet? (kan ikke angres)"
+msgstr ""
+"Fjerne valgte filer fra prosjektet? (kan ikke angres)\n"
+"Du kan finne de fjernede filene i systemets papirkurv, og gjenopprette dem "
+"derfra."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
@@ -1102,7 +1075,9 @@ msgid ""
"You can find the removed files in the system trash to restore them."
msgstr ""
"Filene som fjernes kreves for at andre ressurser skal virke.\n"
-"Fjern dem likevel? (kan ikke angres)"
+"Fjerne dem likevel? (kan ikke angres)\n"
+"Du kan finne de fjernede filene i systemets papirkurv, og gjenopprette dem "
+"derfra."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1163,14 +1138,12 @@ msgid "Resources Without Explicit Ownership:"
msgstr "Ressurser uten eksplisitt eierskap:"
#: editor/dictionary_property_edit.cpp
-#, fuzzy
msgid "Change Dictionary Key"
-msgstr "Endre Ordboksnøkkel"
+msgstr "Endre listenøkkel"
#: editor/dictionary_property_edit.cpp
-#, fuzzy
msgid "Change Dictionary Value"
-msgstr "Endre Ordboksverdi"
+msgstr "Endre listeverdi"
#: editor/editor_about.cpp
msgid "Thanks from the Godot community!"
@@ -1444,7 +1417,6 @@ msgid "There is no '%s' file."
msgstr "Det finnes ingen «%s»-fil"
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Layout"
msgstr "Layout"
@@ -1453,9 +1425,8 @@ msgid "Invalid file, not an audio bus layout."
msgstr "Ugyldig fil, ikke et audio bus oppsett."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Error saving file: %s"
-msgstr "Error ved lagring av TileSet!"
+msgstr "Feil ved lagring av filen: %s"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
@@ -1643,7 +1614,6 @@ msgid "Storing File:"
msgstr "Lagrer Fil:"
#: editor/editor_export.cpp
-#, fuzzy
msgid "No export template found at the expected path:"
msgstr "Ingen eksportmal funnet på forventet søkesti:"
@@ -1770,7 +1740,7 @@ msgstr "Erstatt Alle"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
-msgstr ""
+msgstr "Profil må være et gyldig filnavn, og kan ikke inneholde '.'"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1797,9 +1767,8 @@ msgid "Class Options:"
msgstr "Beskrivelse:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enable Contextual Editor"
-msgstr "Ã…pne den neste Editoren"
+msgstr "Aktiver kontekstavhengig redigeringsverktøy"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1817,7 +1786,7 @@ msgstr "Søk i klasser"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
-msgstr ""
+msgstr "Filformatet til '%s' er ugyldig, importen ble avbrutt."
#: editor/editor_feature_profile.cpp
msgid ""
@@ -1826,9 +1795,8 @@ msgid ""
msgstr ""
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Error saving profile to path: '%s'."
-msgstr "Error ved lagring av TileSet!"
+msgstr "Feil ved lagring av profilen til stien: '%s'."
#: editor/editor_feature_profile.cpp
msgid "Unset"
@@ -1961,8 +1929,8 @@ msgid "Open a File or Directory"
msgstr "Ã…pne ei fil eller mappe"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Lagre"
@@ -2059,10 +2027,6 @@ msgstr "Forhåndsvisning:"
msgid "File:"
msgstr "Fil:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "MÃ¥ ha en gyldig filutvidelse."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Gjennomsøk kilder"
@@ -2256,9 +2220,8 @@ msgid "Set"
msgstr "Sett"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Set Multiple:"
-msgstr "Sett Mange:"
+msgstr "Sett mange:"
#: editor/editor_log.cpp
msgid "Output:"
@@ -2290,9 +2253,8 @@ msgstr "Stopp"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
-#, fuzzy
msgid "Start"
-msgstr "Start!"
+msgstr "Start"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
@@ -2374,7 +2336,7 @@ msgstr "Kan ikke åpne '%s'. Filen kan ha blitt flyttet eller slettet."
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
-msgstr "Error ved parsing av '%s'."
+msgstr "Feil ved parsing av '%s'."
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
@@ -2405,7 +2367,6 @@ msgid "This operation can't be done without a tree root."
msgstr "Denne operasjonen kan ikke gjennomføres uten en trerot."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"This scene can't be saved because there is a cyclic instancing inclusion.\n"
"Please resolve it and then attempt to save again."
@@ -2432,7 +2393,7 @@ msgstr "Kan ikke laste MeshLibrary for sammenslåing!"
#: editor/editor_node.cpp
msgid "Error saving MeshLibrary!"
-msgstr "Error ved lagring av MeshLibrary!"
+msgstr "Feil ved lagring av MeshLibrary!"
#: editor/editor_node.cpp
msgid "Can't load TileSet for merging!"
@@ -2440,7 +2401,7 @@ msgstr "Kan ikke laste TileSet for sammenslåing!"
#: editor/editor_node.cpp
msgid "Error saving TileSet!"
-msgstr "Error ved lagring av TileSet!"
+msgstr "Feil ved lagring av TileSet!"
#: editor/editor_node.cpp
msgid ""
@@ -2521,6 +2482,10 @@ msgid "There is no defined scene to run."
msgstr "Det er ingen definert scene å kjøre."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Kunne ikke starta subprosess!"
@@ -2566,18 +2531,6 @@ msgstr "En rotnode kreves for å lagre scenen."
msgid "Save Scene As..."
msgstr "Lagre Scene Som..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nei"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Ja"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Denne scene har aldri blitt lagret. Lagre før kjøring?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Denne operasjonen kan ikke gjøres uten en scene."
@@ -2626,8 +2579,12 @@ msgid "Quit"
msgstr "Avslutt"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Ja"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
-msgstr "Avslutt editoren?"
+msgstr "Avslutt redigeringsverktøyet?"
#: editor/editor_node.cpp
msgid "Open Project Manager?"
@@ -2674,7 +2631,8 @@ msgstr ""
"mislyktes."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "Kunne ikke finne skriptfelt for addon-plugin i: 'res://addons/%s'."
#: editor/editor_node.cpp
@@ -2693,7 +2651,8 @@ msgstr ""
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
-"Kan ikke laste addon skript fra bane: Basistype '%s' er ikke en EditorPlugin."
+"Kan ikke laste addon-skript fra stien: Basistypen '%s' er ikke en "
+"EditorPlugin."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
@@ -2745,14 +2704,14 @@ msgstr ""
"'applikasjon'."
#: editor/editor_node.cpp
+#, fuzzy
msgid ""
"Selected scene '%s' is not a scene file, select a valid one?\n"
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
-"Valgte scene '%s' er ikke en scenefil, velg en gyldig én?\n"
-"Du kan endre dette senere i \"Prosjekt Instillinger\" under 'applikasjon' "
-"kategorien."
+"Den valgte scenen «%s» er ikke en scenefil, velg en gyldig scenefil?\n"
+"Du kan endre dette senere i «Prosjektinnstillinger» i «program»-kategorien."
#: editor/editor_node.cpp
msgid "Save Layout"
@@ -2931,7 +2890,7 @@ msgstr "Versjon:"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "Sett opp versjonskontroll"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
@@ -2947,9 +2906,8 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Project Data Folder"
-msgstr "Ã…pne ProsjektManager?"
+msgstr "Ã…pne prosjektdatamappe"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3036,17 +2994,16 @@ msgid "Synchronize Scene Changes"
msgstr "Synkroniser Sceneendringer"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, any changes made to the scene in the editor "
"will be replicated in the running project.\n"
"When used remotely on a device, this is more efficient when the network "
"filesystem option is enabled."
msgstr ""
-"NÃ¥r denne innstillingen er aktivert, alle endringer gjort til scenen i "
-"editoren vil bli replikert i det kjørende spillet.\n"
-"Når det brukes eksternt på en enhet, dette er mer effektivt med et "
-"nettverksfilsystem."
+"NÃ¥r denne innstillingen er aktivert, vil alle endringer gjort i scenen i "
+"redigeringsverktøyet bli gjenspeilet i det kjørende spillet.\n"
+"Når det brukes eksternt på en enhet, er dette mer effektivt med et "
+"nettverksfilsystem aktivert."
#: editor/editor_node.cpp
#, fuzzy
@@ -3071,9 +3028,8 @@ msgid "Editor"
msgstr "Redigeringsverktøy"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "Redigeringsverktøy-instillinger"
+msgstr "Innstillinger for redigeringsverktøy …"
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -3085,9 +3041,8 @@ msgid "Take Screenshot"
msgstr "Lagre Scene"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr "Redigeringsverktøy-instillinger"
+msgstr "Skjermavbildninger lagres i redigeringsdata/innstillingsmappen."
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
@@ -3099,18 +3054,16 @@ msgid "Toggle System Console"
msgstr "Veksle modus"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
-msgstr "Redigeringsverktøy-instillinger"
+msgstr "Åpne data for redigeringsverktøy/innstillingsmappe"
#: editor/editor_node.cpp
msgid "Open Editor Data Folder"
msgstr "Ã…pne Redigererdatamappen"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Settings Folder"
-msgstr "Redigeringsverktøy-instillinger"
+msgstr "Åpne mappe for redigeringsverktøyinnstillinger"
#: editor/editor_node.cpp
#, fuzzy
@@ -3127,14 +3080,6 @@ msgid "Help"
msgstr "Hjelp"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Søk"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentasjon"
@@ -3208,9 +3153,8 @@ msgid "Save & Restart"
msgstr "Lagre & Avslutt"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Spins when the editor window redraws."
-msgstr "Snurrer når editorvinduet rendrer om!"
+msgstr "Snurrer når redigeringsvinduet tegner opp på nytt."
#: editor/editor_node.cpp
#, fuzzy
@@ -3298,13 +3242,31 @@ msgid "Open & Run a Script"
msgstr "Åpne & Kjør et Skript"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Følgende filer er nyere på disken.\n"
+"Hvilken handling skal utføres?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Gjeninnlat"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Lagre på nytt"
+
+#: editor/editor_node.cpp
#, fuzzy
msgid "New Inherited"
msgstr "Ny Arvet"
#: editor/editor_node.cpp
msgid "Load Errors"
-msgstr "Last Errors"
+msgstr "Last feil"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
msgid "Select"
@@ -3312,11 +3274,11 @@ msgstr "Velg"
#: editor/editor_node.cpp
msgid "Open 2D Editor"
-msgstr "Ã…pne 2D Editor"
+msgstr "Åpne 2D-redigeringsverktøy"
#: editor/editor_node.cpp
msgid "Open 3D Editor"
-msgstr "Ã…pne 3D Editor"
+msgstr "Åpne 3D-redigeringsverktøy"
#: editor/editor_node.cpp
msgid "Open Script Editor"
@@ -3328,16 +3290,15 @@ msgstr "Ã…pne Assets-Bibliotek"
#: editor/editor_node.cpp
msgid "Open the next Editor"
-msgstr "Ã…pne den neste Editoren"
+msgstr "Åpne det neste redigeringsverktøyet"
#: editor/editor_node.cpp
msgid "Open the previous Editor"
-msgstr "Ã…pne den forrige Editoren"
+msgstr "Åpne det forrige redigeringsverktøy"
#: editor/editor_node.h
-#, fuzzy
msgid "Warning!"
-msgstr "Advarsler"
+msgstr "Advarsel!"
#: editor/editor_path.cpp
#, fuzzy
@@ -3401,9 +3362,8 @@ msgid "Average Time (sec)"
msgstr "Gjennomsnittstid (sek)"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Frame %"
-msgstr "Frame %"
+msgstr "Bilde %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
@@ -3418,9 +3378,8 @@ msgid "Self"
msgstr "Selv"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Frame #:"
-msgstr "Frame #:"
+msgstr "Bilde #:"
#: editor/editor_profiler.cpp
#, fuzzy
@@ -3518,7 +3477,7 @@ msgstr "Gjør Unik"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Lim inn"
@@ -3597,7 +3556,7 @@ msgstr ""
#: editor/editor_sub_scene.cpp
msgid "Select Node(s) to Import"
-msgstr "Velg Node(r) for Importering"
+msgstr "Velg node(r) som skal importeres"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
#, fuzzy
@@ -3647,9 +3606,8 @@ msgid "Retrieving mirrors, please wait..."
msgstr "Henter fillager, vennligst vent..."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Remove template version '%s'?"
-msgstr "Fjern mal versjon '%s'?"
+msgstr "Fjern malversjon '%s'?"
#: editor/export_template_manager.cpp
msgid "Can't open export templates zip."
@@ -3665,9 +3623,8 @@ msgid "No version.txt found inside templates."
msgstr "Ingen version.txt funnet i mal."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error creating path for templates:"
-msgstr "Feil ved laging av sti for mal:\n"
+msgstr "Feil ved laging av sti for maler:"
#: editor/export_template_manager.cpp
msgid "Extracting Export Templates"
@@ -3852,14 +3809,12 @@ msgid "Cannot move/rename resources root."
msgstr "Kan ikke flytte/endre navn ressursrot"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Cannot move a folder into itself."
-msgstr "Kan ikke flytte mappe inn i seg selv.\n"
+msgstr "Kan ikke flytte en mappe inn i seg selv."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Error moving:"
-msgstr "Error ved flytting:\n"
+msgstr "Feil ved flytting:"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3867,9 +3822,8 @@ msgid "Error duplicating:"
msgstr "Feil ved innlasting:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Unable to update dependencies:"
-msgstr "Kan ikke oppdatere av avhengigheter:\n"
+msgstr "Kan ikke oppdatere avhengigheter:"
#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
msgid "No name provided."
@@ -4113,8 +4067,18 @@ msgstr "Lagrer..."
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "Søk Tekst"
+msgid "%d match in %d file."
+msgstr "Ingen Treff"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "Ingen Treff"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Ingen Treff"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4125,9 +4089,8 @@ msgid "Remove from Group"
msgstr "Fjern fra Gruppe"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Group name already exists."
-msgstr "ERROR: Animasjonsnavnet finnes allerede!"
+msgstr "Gruppenavnet finnes allerede."
#: editor/groups_editor.cpp
#, fuzzy
@@ -4169,9 +4132,8 @@ msgid "Empty groups will be automatically removed."
msgstr ""
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Group Editor"
-msgstr "Ã…pne SkriptEditor"
+msgstr "Redigeringsverktøy for grupper"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4229,7 +4191,7 @@ msgstr "Importerer Scene..."
#: editor/import/resource_importer_scene.cpp
msgid "Generating Lightmaps"
-msgstr "Genererer Lyskart"
+msgstr "Genererer lyskart"
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
@@ -4250,7 +4212,7 @@ msgstr "Ugyldig/ødelagt skript for post-import (sjekk konsoll):"
#: editor/import/resource_importer_scene.cpp
msgid "Error running post-import script:"
-msgstr "Error ved kjøring av post-import script:"
+msgstr "Feil ved kjøring av post-import script:"
#: editor/import/resource_importer_scene.cpp
msgid "Did you return a Node-derived object in the `post_import()` method?"
@@ -4260,6 +4222,21 @@ msgstr ""
msgid "Saving..."
msgstr "Lagrer..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Velg Modus"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importer"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Last Standard"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Filer"
@@ -4326,9 +4303,8 @@ msgid "Copy Params"
msgstr "Kopier Parametre"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Edit Resource Clipboard"
-msgstr "Ressurs-utklippstavle er tom!"
+msgstr "Rediger ressurs-utklippstavlen"
#: editor/inspector_dock.cpp
msgid "Copy Resource"
@@ -4439,16 +4415,14 @@ msgid "Create points."
msgstr "Slett punkter"
#: editor/plugins/abstract_polygon_2d_editor.cpp
-#, fuzzy
msgid ""
"Edit points.\n"
"LMB: Move Point\n"
"RMB: Erase Point"
msgstr ""
-"Endre eksisterende polygon:\n"
-"Venstreklikk: Flytt Punkt.\n"
-"Ctrl+Venstreklikk: Splitt Segment.\n"
-"Høyreklikk: Fjern Punkt."
+"Rediger punkter.\n"
+"Venstreklikk: Flytt punkt\n"
+"Høyreklikk: Fjern punkt"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
@@ -4463,7 +4437,7 @@ msgstr "Rediger Poly"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Insert Point"
-msgstr "Sett inn Punkt"
+msgstr "Sett inn punkt"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#, fuzzy
@@ -4580,9 +4554,8 @@ msgid "Open Animation Node"
msgstr "Animasjonsnode"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Triangle already exists."
-msgstr "ERROR: Animasjonsnavnet finnes allerede!"
+msgstr "Triangelet finnes allerede."
#: editor/plugins/animation_blend_space_2d_editor.cpp
#, fuzzy
@@ -4784,14 +4757,12 @@ msgid "Remove Animation"
msgstr "Fjern Animasjon"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Invalid animation name!"
-msgstr "ERROR: Ugyldig animasjonsnavn!"
+msgstr "Ugyldig animasjonsnavn!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Animation name already exists!"
-msgstr "ERROR: Animasjonsnavnet finnes allerede!"
+msgstr "Animasjonsnavnet finnes allerede!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
@@ -4816,14 +4787,12 @@ msgid "Duplicate Animation"
msgstr "Dupliser Animasjon"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to copy!"
-msgstr "ERROR: Ingen animasjon å kopiere!"
+msgstr "Ingen animasjon å kopiere!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation resource on clipboard!"
-msgstr "ERROR: Ingen animasjonsressurs på utklippstavlen!"
+msgstr "Ingen animasjonsressurs på utklippstavlen!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
@@ -4834,9 +4803,8 @@ msgid "Paste Animation"
msgstr "Lim inn Animasjon"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to edit!"
-msgstr "ERROR: Ingen animasjon å endre!"
+msgstr "Ingen animasjon å redigere!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
@@ -4960,7 +4928,7 @@ msgstr "Animasjonsnavn:"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
msgid "Error!"
-msgstr "Error!"
+msgstr "Feil!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Times:"
@@ -4982,9 +4950,8 @@ msgid "Move Node"
msgstr "Flytt Modus"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition exists!"
-msgstr "Overgang"
+msgstr "Overgang eksisterer!"
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -4994,7 +4961,7 @@ msgstr "Overgang"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node"
-msgstr ""
+msgstr "Legg til node"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "End"
@@ -5300,10 +5267,12 @@ msgid "Got:"
msgstr "Fikk:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Feilet sha256 hash-sjekk"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Asset Download Error:"
msgstr "Asset Nedlasting Error:"
@@ -5341,7 +5310,7 @@ msgstr "Prøv på nytt"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download Error"
-msgstr "Nedlastningserror"
+msgstr "Nedlastningsfeil"
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
@@ -5415,7 +5384,6 @@ msgid "Sort:"
msgstr "Sorter:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategori:"
@@ -5448,8 +5416,7 @@ msgstr "Assets ZIP-Fil"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5463,9 +5430,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "Laging av lysmapbilder feilet, forsikre om at stien er skrivbar."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Velg malfil"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5998,7 +5985,7 @@ msgstr "Plasser Utvalg I Midten"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
-msgstr ""
+msgstr "Bildeutvalg"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
@@ -6084,7 +6071,7 @@ msgstr "Lag Node"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Error instancing scene from %s"
-msgstr "Error ved instansiering av scene fra %s"
+msgstr "Feil ved instansiering av scene fra %s"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -6110,7 +6097,7 @@ msgstr "Rediger Poly"
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly (Remove Point)"
-msgstr "Rediger Poly (Fjern Punkt)"
+msgstr "Rediger Poly (fjern punkt)"
#: editor/plugins/collision_shape_2d_editor_plugin.cpp
#, fuzzy
@@ -6470,11 +6457,12 @@ msgid "Remove item %d?"
msgstr "Fjern element %d?"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid ""
"Update from existing scene?:\n"
"%s"
-msgstr "Oppdater fra Scene"
+msgstr ""
+"Oppdater fra eksisterende scene?:\n"
+"%s"
#: editor/plugins/mesh_library_editor_plugin.cpp
#, fuzzy
@@ -6614,6 +6602,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Konverter til store versaler"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6674,10 +6667,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6886,9 +6875,8 @@ msgid "Paint Bone Weights"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Open Polygon 2D UV editor."
-msgstr "Ã…pne 2D Editor"
+msgstr "Åpne 2D-redigeringsverktøy for polygon-UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon 2D UV Editor"
@@ -6989,9 +6977,8 @@ msgid "Clear UV"
msgstr "Fjern UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Settings"
-msgstr "Redigeringsverktøy-instillinger"
+msgstr "Rutenettsinnstillinger"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Snap"
@@ -7041,7 +7028,7 @@ msgstr "Skaler Polygon"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ERROR: Couldn't load resource!"
-msgstr "ERROR: Kunne ikke laste ressurs!"
+msgstr "FEIL: Kunne ikke laste ressurs!"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Add Resource"
@@ -7104,16 +7091,12 @@ msgid "Clear Recent Files"
msgstr "Fjern Nylige Filer"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Close and save changes?"
-msgstr ""
-"Lukk og lagre endringer?\n"
-"\""
+msgstr "Lukke og lagre endringer?"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error writing TextFile:"
-msgstr "Error ved lagring av TileSet!"
+msgstr "Feil ved lagring av TextFile:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7121,29 +7104,24 @@ msgid "Could not load file at:"
msgstr "Kunne ikke opprette mappe."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error saving file!"
-msgstr "Error ved lagring av TileSet!"
+msgstr "Feil ved lagring av filen!"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error while saving theme."
-msgstr "Error ved lasting av tema"
+msgstr "Feil ved lagring av tema"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Saving"
-msgstr "Error ved lagring"
+msgstr "Feil ved lagring"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error importing theme."
-msgstr "Error ved importering av tema"
+msgstr "Feil ved importering av tema."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Importing"
-msgstr "Error ved importering"
+msgstr "Feil ved importering"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7183,11 +7161,11 @@ msgstr "Importer Tema"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error while saving theme"
-msgstr "Error ved lasting av tema"
+msgstr "Feil ved lagring av tema"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving"
-msgstr "Error ved lagring"
+msgstr "Feil ved lagring"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme As..."
@@ -7311,6 +7289,14 @@ msgstr "Lukk Dokumentasjon"
msgid "Run"
msgstr "Kjør"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Søk"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Tre inn i"
@@ -7364,16 +7350,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Gjeninnlat"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Lagre på nytt"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Feilsøking"
@@ -7474,8 +7450,8 @@ msgstr "Slett punkter"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: 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"
@@ -7715,6 +7691,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Størrelse"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8040,9 +8020,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Settings..."
-msgstr "Redigeringsverktøy-instillinger"
+msgstr "Innstillinger …"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -8212,9 +8191,8 @@ msgid "Update Preview"
msgstr "Forhåndsvis"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Settings:"
-msgstr "Redigeringsverktøy-instillinger"
+msgstr "Innstillinger:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -8875,11 +8853,12 @@ msgid "Delete selected Rect."
msgstr "Slett valgte filer?"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select current edited sub-tile.\n"
"Click on another Tile to edit it."
-msgstr "Velg Gjeldende Mappe"
+msgstr ""
+"Velg gjeldende redigerte underflis.\n"
+"Klikk på en annen flis for å redigere den."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8887,13 +8866,16 @@ msgid "Delete polygon."
msgstr "Slett punkter"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"LMB: Set bit on.\n"
"RMB: Set bit off.\n"
"Shift+LMB: Set wildcard bit.\n"
"Click on another Tile to edit it."
-msgstr "Velg Gjeldende Mappe"
+msgstr ""
+"Venstreklikk: Sett bit på.\n"
+"Høyreklikk: Sett bit av.\n"
+"Skift+venstreklikk: Sett jokertegn-bit.\n"
+"Klikk på en annen flis for å redigere den."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8909,11 +8891,12 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select sub-tile to change its z index.\n"
"Click on another Tile to edit it."
-msgstr "Velg Gjeldende Mappe"
+msgstr ""
+"Velg underflis for å endre z-indeksen.\n"
+"Klikk på en annen flis for å redigere den."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Region"
@@ -9035,11 +9018,6 @@ msgid "Error"
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 "No files added to stage"
msgstr ""
@@ -9105,10 +9083,6 @@ msgid "Stage All"
msgstr "Lagre Alle"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Synkroniser Skriptforandringer"
@@ -10123,9 +10097,8 @@ msgid "Export Project"
msgstr "Eksporter Prosjekt"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export mode?"
-msgstr "Eksporter Prosjekt"
+msgstr "Eksportmodus?"
#: editor/project_export.cpp
#, fuzzy
@@ -10215,8 +10188,8 @@ msgid ""
"Couldn't load project.godot in project path (error %d). It may be missing or "
"corrupted."
msgstr ""
-"Kunne ikke laste project.godot i prosjekt sti (error %d). Den kan være "
-"manglet eller korruptert."
+"Kunne ikke laste project.godot i prosjektstien (feil %d). Den kan mangle "
+"eller være korrupt."
#: editor/project_manager.cpp
msgid "Couldn't edit project.godot in project path."
@@ -10387,25 +10360,28 @@ msgid "Are you sure to run %d projects at once?"
msgstr "Er du sikker på at du vil kjøre mer enn ett prosjekt?"
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove %d projects from the list?\n"
"The project folders' contents won't be modified."
-msgstr "Fjern prosjekt fra listen? (Mappeinnhold vil ikke bli modifisert)"
+msgstr ""
+"Fjern %s prosjekter fra listen?\n"
+"Innhold i prosjektmappene vil ikke påvirkes."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove this project from the list?\n"
"The project folder's contents won't be modified."
-msgstr "Fjern prosjekt fra listen? (Mappeinnhold vil ikke bli modifisert)"
+msgstr ""
+"Fjern dette prosjektet fra listen?\n"
+"Innhold i prosjektmappen vil ikke påvirkes."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Remove all missing projects from the list?\n"
"The project folders' contents won't be modified."
-msgstr "Fjern prosjekt fra listen? (Mappeinnhold vil ikke bli modifisert)"
+msgstr ""
+"Fjern alle manglende prosjekter fra listen?\n"
+"Innhold i prosjektmappene vil ikke påvirkes."
#: editor/project_manager.cpp
msgid ""
@@ -10432,6 +10408,11 @@ msgid "Projects"
msgstr "Prosjekter"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Henter fillager, vennligst vent..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10500,9 +10481,8 @@ msgid ""
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "An action with the name '%s' already exists."
-msgstr "ERROR: Animasjonsnavnet finnes allerede!"
+msgstr "En handling med navnet '%s' finnes allerede."
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
@@ -10803,10 +10783,14 @@ msgstr ""
msgid "Plugins"
msgstr "Innstikkmoduler"
-#: editor/property_editor.cpp
+#: editor/project_settings_editor.cpp
#, fuzzy
+msgid "Import Defaults"
+msgstr "Last Standard"
+
+#: editor/property_editor.cpp
msgid "Preset..."
-msgstr "Preset..."
+msgstr "Forhåndsinnstilt..."
#: editor/property_editor.cpp
msgid "Zero"
@@ -10867,9 +10851,8 @@ msgid "Batch Rename"
msgstr "Endre navn"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Replace:"
-msgstr "Erstatt: "
+msgstr "Erstatt:"
#: editor/rename_dialog.cpp
msgid "Prefix:"
@@ -10908,9 +10891,8 @@ msgid "Node type"
msgstr "Finn Node Type"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Current scene name"
-msgstr "Gjeldende scene er ikke lagret. Ã…pne likevel?"
+msgstr "Navn på gjeldende scene"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -11062,6 +11044,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Lim inn Noder"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Nytt Skript"
@@ -11100,14 +11091,12 @@ msgid "Make node as Root"
msgstr "Lagre Scene"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes and any children?"
-msgstr "Kutt Noder"
+msgstr "Slett %d noder og eventuelle barn?"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes?"
-msgstr "Kutt Noder"
+msgstr "Slett %d noder?"
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
@@ -11118,9 +11107,8 @@ msgid "Delete node \"%s\" and its children?"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete node \"%s\"?"
-msgstr "Kutt Noder"
+msgstr "Slett noden \"%s\"?"
#: editor/scene_tree_dock.cpp
msgid "Can not perform with the root node."
@@ -11191,6 +11179,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Kutt Noder"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11407,19 +11400,16 @@ msgid "Select a Node"
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is empty."
-msgstr "Ressurs-utklippstavle er tom!"
+msgstr "Stien er tom."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Filename is empty."
-msgstr "Ressurs-utklippstavle er tom!"
+msgstr "Filnavnet er tomt."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is not local."
-msgstr "Sti leder ikke Node!"
+msgstr "Stien er ikke lokal."
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11466,9 +11456,8 @@ msgid "N/A"
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Open Script / Choose Location"
-msgstr "Ã…pne SkriptEditor"
+msgstr "Ã…pne skript / Velg plassering"
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11563,19 +11552,16 @@ msgid "Warning:"
msgstr "Advarsler:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Error:"
-msgstr "Error!"
+msgstr "Feil:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error"
-msgstr "Last Errors"
+msgstr "C++-feil"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error:"
-msgstr "Last Errors"
+msgstr "C++-feil:"
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -11606,9 +11592,8 @@ msgid "Child process connected."
msgstr "Frakoblet"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Copy Error"
-msgstr "Last Errors"
+msgstr "Kopier feil"
#: editor/script_editor_debugger.cpp
msgid "Video RAM"
@@ -11724,7 +11709,7 @@ msgstr "Endre Anker"
#: editor/settings_config_dialog.cpp
msgid "Editor Settings"
-msgstr "Redigeringsverktøy-instillinger"
+msgstr "Innstillinger for redigeringsverktøy"
#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
@@ -11873,7 +11858,7 @@ msgstr ""
#: modules/gdscript/gdscript_functions.cpp
msgid "Not a script with an instance"
-msgstr ""
+msgstr "Ikke et skript med en instans"
#: modules/gdscript/gdscript_functions.cpp
msgid "Not based on a script"
@@ -12041,6 +12026,38 @@ msgstr "Lim inn Noder"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Retninger"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "Innrykk Høyre"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Gjeldende Versjon:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Genererer Lyskart"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12207,25 +12224,24 @@ msgid "Name is not a valid identifier:"
msgstr "Navn er ikke en gyldig identifikator:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Name already in use by another func/var/signal:"
-msgstr "Navn er allerede i bruk av en annen func/var/signal:"
+msgstr "Navnet er allerede i bruk av annen funk/var/signal:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Function"
-msgstr ""
+msgstr "Endre navn på funksjonen"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Variable"
-msgstr ""
+msgstr "Endre navn på variabelen"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Signal"
-msgstr ""
+msgstr "Endre navn på signalet"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Function"
-msgstr ""
+msgstr "Legg til funksjon"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -12234,11 +12250,11 @@ msgstr "Fjern punkt"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Variable"
-msgstr ""
+msgstr "Legg til variabel"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Signal"
-msgstr ""
+msgstr "Legg til signal"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -12252,7 +12268,7 @@ msgstr "Fjern punkt"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Expression"
-msgstr ""
+msgstr "Endre uttrykk"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Nodes"
@@ -12272,6 +12288,8 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."
msgstr ""
+"Hold Ctrl for å slippe en Getter. Hold Skift for å slippe en generisk "
+"signatur."
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -12280,7 +12298,7 @@ msgstr "Hold Meta for å slippe en enkel referanse til noden."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a simple reference to the node."
-msgstr "Hold Ctrl for å slippe en simpel referanse til noden."
+msgstr "Hold Ctrl for å slippe en enkel referanse til noden."
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -12400,19 +12418,19 @@ msgstr "Fjern Funksjon"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Variable"
-msgstr ""
+msgstr "Fjern variabel"
#: modules/visual_script/visual_script_editor.cpp
msgid "Editing Variable:"
-msgstr ""
+msgstr "Redigerer variabel:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Signal"
-msgstr ""
+msgstr "Fjern signal"
#: modules/visual_script/visual_script_editor.cpp
msgid "Editing Signal:"
-msgstr ""
+msgstr "Redigerer signal:"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -12506,7 +12524,7 @@ msgstr "Sti leder ikke Node!"
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name '%s' in node %s."
-msgstr "Ugyldig indeks egenskap navn '%s' i node %s."
+msgstr "Ugyldig navn for indeksegenskap '%s' i noden %s."
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
@@ -12576,11 +12594,13 @@ msgid "Select device from the list"
msgstr "Velg enhet fra listen"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12592,11 +12612,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12604,9 +12624,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12844,6 +12874,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -13010,28 +13048,30 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "Genererer Lyskart"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Genererer Lyskart"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr ""
+msgid "Done"
+msgstr "Ferdig"
#: scene/3d/collision_object.cpp
msgid ""
@@ -13090,14 +13130,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -13229,9 +13268,8 @@ msgid "In node '%s', invalid animation: '%s'."
msgstr ""
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Invalid animation: '%s'."
-msgstr "ERROR: Ugyldig animasjonsnavn!"
+msgstr "Ugyldig animasjon: '%s'."
#: scene/animation/animation_tree.cpp
#, fuzzy
@@ -13308,6 +13346,15 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "MÃ¥ ha en gyldig filutvidelse."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "Aktiver Snap"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13349,6 +13396,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Ugyldig fontstørrelse."
@@ -13378,6 +13431,20 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstanter kan ikke endres."
+#~ msgid "No"
+#~ msgstr "Nei"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Denne scene har aldri blitt lagret. Lagre før kjøring?"
+
+#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "Søk Tekst"
+
+#, fuzzy
+#~ msgid "No commit message was provided"
+#~ msgstr "Ingen navn gitt"
+
#, fuzzy
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "En fil eller mappe med dette navnet eksisterer allerede."
@@ -13600,10 +13667,6 @@ msgstr "Konstanter kan ikke endres."
#~ msgstr "Kunne ikke laste ressurs."
#, fuzzy
-#~ msgid "Done"
-#~ msgstr "Ferdig!"
-
-#, fuzzy
#~ msgid "Failed to create C# project."
#~ msgstr "Kunne ikke laste ressurs."
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 2b0d754edd..52c63ffa85 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -1,6 +1,6 @@
# Dutch translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# aelspire <aelspire@gmail.com>, 2017.
# Aram Nap <xyphex.aram@gmail.com>, 2017.
@@ -28,7 +28,7 @@
# rxadmin <r.van.eeghem@gmail.com>, 2018.
# Peter Goelst <muis24@gmail.com>, 2019.
# Wouter Buckens <wou.buc@gmail.com>, 2019.
-# Stijn Hinlopen <f.a.hinlopen@gmail.com>, 2019, 2020.
+# Stijn Hinlopen <f.a.hinlopen@gmail.com>, 2019, 2020, 2021.
# jef dered <themen098s@vivaldi.net>, 2019.
# Alex H. <sandertjeh13@hotmail.com>, 2019.
# edouardgr <edouard.gruyters@gmail.com>, 2019.
@@ -47,7 +47,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-29 08:28+0000\n"
+"PO-Revision-Date: 2021-02-05 23:44+0000\n"
"Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/"
"nl/>\n"
@@ -56,7 +56,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -686,7 +686,7 @@ msgstr "Selecteer sporen om te kopieren"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopiëren"
@@ -1703,7 +1703,7 @@ msgstr "Script Editor"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr "Asset bibliotheek"
+msgstr "Materiaalbibliotheek"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
@@ -1899,8 +1899,8 @@ msgid "Open a File or Directory"
msgstr "Bestand of map openen"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Opslaan"
@@ -1991,10 +1991,6 @@ msgstr "Voorbeeld:"
msgid "File:"
msgstr "Bestand:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Een geldige extensie moet gebruikt worden."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Scan Bronnen"
@@ -2433,6 +2429,10 @@ msgid "There is no defined scene to run."
msgstr "Er is geen startscène ingesteld."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Scène opslaan voor het afspelen..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Kon het subproces niet opstarten!"
@@ -2476,18 +2476,6 @@ msgstr "Een wortelknoop is nodig om de scène op te slaan."
msgid "Save Scene As..."
msgstr "Scène opslaan als..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nee"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Ja"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Deze scene is nooit opgeslagen. Sla op voor het uitvoeren?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Deze operatie kan niet uitgevoerd worden zonder scène."
@@ -2538,6 +2526,10 @@ msgid "Quit"
msgstr "Afsluiten"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Ja"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Editor afsluiten?"
@@ -2585,7 +2577,8 @@ msgstr ""
"mislukt."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"Onmogelijk om scriptveld te vinden voor de plugin op: 'res://addons/%s'."
@@ -2909,7 +2902,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
-msgstr "Toon collision shapes"
+msgstr "Botsingsvormen tonen"
#: editor/editor_node.cpp
#, fuzzy
@@ -3019,14 +3012,6 @@ msgid "Help"
msgstr "Help"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Zoeken"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Documentatie"
@@ -3193,6 +3178,25 @@ msgid "Open & Run a Script"
msgstr "Voer Een Script Uit"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"De volgende bestanden zijn nieuwer op de schijf.\n"
+"Welke aktie moet worden genomen?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Herladen"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Heropslaan"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Nieuw afgeleid type"
@@ -3218,7 +3222,7 @@ msgstr "Open Script Bewerker"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
-msgstr "Open Asset Bibliotheek"
+msgstr "Open Materiaalbibliotheek"
#: editor/editor_node.cpp
msgid "Open the next Editor"
@@ -3404,7 +3408,7 @@ msgstr "Maak Uniek"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Plakken"
@@ -3766,6 +3770,11 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"De volgende bestanden of mappen conflicteren met elementen in '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Wil je deze overschrijven?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3958,8 +3967,16 @@ msgid "Searching..."
msgstr "Aan het zoeken..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Zoek Compleet"
+msgid "%d match in %d file."
+msgstr "%d overeenkomst in %d bestand."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d overeenkomsten in %d bestand."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d overeenkomsten in %d bestanden."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4096,6 +4113,21 @@ msgstr ""
msgid "Saving..."
msgstr "Opslaan..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Selecteermodus"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importeren"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Laad standaard"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Bestanden"
@@ -5063,7 +5095,8 @@ msgid "Got:"
msgstr "Gekregen:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "SHA256-proef mislukt"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5167,7 +5200,6 @@ msgid "Sort:"
msgstr "Sorteren op:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Categorie:"
@@ -5196,10 +5228,10 @@ msgid "Assets ZIP File"
msgstr "Assets ZIP Bestand"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Kan geen opslag pad voor de lichtmappen bepalen.\n"
"Sla jouw scène op (om lichtmappen op te slaan in dezelfde map) of kies een "
@@ -5220,9 +5252,28 @@ msgstr ""
"beschrijfbaar is."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Bak Lichtmappen"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Selecteer lightmap bake-bestand"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5290,7 +5341,7 @@ msgstr "Maak nieuwe horizontale en verticale gidsen"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
-msgstr ""
+msgstr "Draaipuntverschuiving van het CanvasItem „%s“ op (%d, %d) zetten"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotate %d CanvasItems"
@@ -5313,24 +5364,20 @@ msgid "Resize Control \"%s\" to (%d, %d)"
msgstr "Control \"%s\" vergrootten tot (%d, %d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale %d CanvasItems"
-msgstr "Schaal CanvasItem"
+msgstr "Schaal %d CanvasItems"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale CanvasItem \"%s\" to (%s, %s)"
-msgstr "Schaal CanvasItem"
+msgstr "Schaal CanvasItem \"%s\" naar (%s, %s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move %d CanvasItems"
-msgstr "Verplaats CanvasItem"
+msgstr "Verplaats %d CanvasItems"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" to (%d, %d)"
-msgstr "Verplaats CanvasItem"
+msgstr "CanvasItem \"%s\" naar (%d, %d) verplaatsen"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -6324,6 +6371,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Kan punt alleen plaatsen in een PartikelsMateriaal proces materiaal"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Omzetten naar CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Genereer Tijd (sec):"
@@ -6384,10 +6435,6 @@ msgstr "AABB Genereren"
msgid "Generate Visibility AABB"
msgstr "Genereer Zichtbaarheid AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Genereer AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Verwijder Punt van Curve"
@@ -6616,9 +6663,8 @@ msgid "Move Points"
msgstr "Beweeg Punten"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Command: Rotate"
-msgstr "Sleep: Roteer"
+msgstr "Ctrl: Roteer"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift: Move All"
@@ -6676,14 +6722,12 @@ msgid "Radius:"
msgstr "Radius:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Copy Polygon to UV"
-msgstr "Creëer Polygon & UV"
+msgstr "Kopieer Polygon naar UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Copy UV to Polygon"
-msgstr "Naar Polygon2D omzetten"
+msgstr "Kopieer UV naar Polygon2D"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Clear UV"
@@ -6985,6 +7029,14 @@ msgstr "Sluit Docs"
msgid "Run"
msgstr "Uitvoeren"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Zoeken"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Stap In"
@@ -7038,16 +7090,6 @@ msgstr ""
"De volgende bestanden zijn nieuwer op de schijf.\n"
"Welke aktie moet worden genomen?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Herladen"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Heropslaan"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Debugger"
@@ -7141,8 +7183,8 @@ msgstr "Breekpunten"
msgid "Go To"
msgstr "Ga Naar"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Knippen"
@@ -7261,7 +7303,7 @@ msgid ""
"This shader has been modified on on disk.\n"
"What action should be taken?"
msgstr ""
-"Deze Shader is aangepast op de schijf.\n"
+"Deze shader is aangepast op de schijf.\n"
"Welke actie moet worden genomen?"
#: editor/plugins/shader_editor_plugin.cpp
@@ -7365,6 +7407,11 @@ msgid "Yaw"
msgstr "Yaw"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Grootte: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objecten Getekend"
@@ -7777,7 +7824,7 @@ msgstr "Polygon2D Voorbeeldweergave"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create CollisionPolygon2D"
-msgstr "Creëer CollisionPolygon2D"
+msgstr "CollisionPolygon2D aanmaken"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "CollisionPolygon2D Preview"
@@ -7819,11 +7866,11 @@ msgstr "Naar Polygon2D omzetten"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create collision polygon."
-msgstr "Ongeldige geometrie, kan geen collision polygoon creëren."
+msgstr "Ongeldige geometrie, kan geen botsingspolygoon aanmaken."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create CollisionPolygon2D Sibling"
-msgstr "Creëer CollisionPolygon2D Sibling"
+msgstr "CollisionPolygon2D aanmaken"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create light occluder."
@@ -8229,13 +8276,12 @@ msgid "Paint Tile"
msgstr "Teken Tegel"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid ""
"Shift+LMB: Line Draw\n"
"Shift+Command+LMB: Rectangle Paint"
msgstr ""
-"Shift+LMB: Lijn Tekenen\n"
-"Shift+Ctrl+LMB: Vierkant Tekenen"
+"Shift+LMB: Lijn tekenen\n"
+"Shift+Ctrl+LMB: Vierkant tekenen"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
@@ -8390,23 +8436,20 @@ msgid "Create a new rectangle."
msgstr "Creëer nieuwe driehoek."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Rectangle"
-msgstr "Teken Driehoek"
+msgstr "Nieuwe rechthoek"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create a new polygon."
msgstr "Nieuwe veelhoek aanmaken."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Polygon"
-msgstr "Beweeg Polygon"
+msgstr "Nieuwe veelhoek"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete Selected Shape"
-msgstr "Geselecteerde Verwijderen"
+msgstr "Geselecteerde vormen verwijderen"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
@@ -8533,7 +8576,7 @@ msgstr "Tegelbitmasker bewerken"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Collision Polygon"
-msgstr "Bewerk Collision Polygon"
+msgstr "Botsingspolygoon aanpassen"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Occlusion Polygon"
@@ -8565,7 +8608,7 @@ msgstr "Verwijder Tile"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove Collision Polygon"
-msgstr "Verwijder Collision Polygon"
+msgstr "Botsingsvorm verwijderen"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove Occlusion Polygon"
@@ -8593,7 +8636,7 @@ msgstr "Maak concaaf"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create Collision Polygon"
-msgstr "Creëer Collision Polygon"
+msgstr "Botsingsvorm aanmaken"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create Occlusion Polygon"
@@ -8616,10 +8659,6 @@ msgid "Error"
msgstr "Fout"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Geen commitbericht was gegeven"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Geen bestanden toegevoegd aan stage"
@@ -8676,10 +8715,6 @@ msgid "Stage All"
msgstr "Stage Alles"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Voeg een vastleggingsbericht toe"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Commit veranderingen"
@@ -8779,9 +8814,8 @@ msgid "Add Node to Visual Shader"
msgstr "VisualShader-knoop toevoegen"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node(s) Moved"
-msgstr "Knoop verplaatst"
+msgstr "Knoop/knopen verplaatst"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Duplicate Nodes"
@@ -8801,9 +8835,8 @@ msgid "Visual Shader Input Type Changed"
msgstr "Visuele Shader Invoertype Gewijzigd"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "UniformRef Name Changed"
-msgstr "Uniforme naam instellen"
+msgstr "UniformRef naam veranderd"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
@@ -8896,7 +8929,7 @@ msgstr "Kleur uniform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the %s comparison between two parameters."
msgstr ""
-"Geeft de booleaanse resultaat van de %s-vergelijking tussen twee parameters."
+"Geeft het booleaanse resultaat van de %s-vergelijking tussen twee parameters."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Equal (==)"
@@ -9531,7 +9564,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "A reference to an existing uniform."
-msgstr ""
+msgstr "Een verwijzing naar een bestaande uniform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(Fragment/Light mode only) Scalar derivative function."
@@ -9898,7 +9931,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Niet ondersteund door de GPU drivers op dit systeem."
#: editor/project_manager.cpp
msgid ""
@@ -10077,6 +10110,11 @@ msgid "Projects"
msgstr "Projecten"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Mirrors ophalen, even wachten a.u.b..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Laatst bewerkt"
@@ -10114,7 +10152,7 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
"U heeft momenteel geen projecten.\n"
-"Wilt u de officiële voorbeeldprojecten verkennen in de Asset Library?"
+"Wilt u officiële voorbeeldprojecten verkennen in de Materiaalbibliotheek?"
#: editor/project_manager.cpp
msgid ""
@@ -10447,6 +10485,11 @@ msgstr "Automatisch Laden"
msgid "Plugins"
msgstr "Plugins"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Laad standaard"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Voorinstelling..."
@@ -10508,19 +10551,16 @@ msgid "Batch Rename"
msgstr "Bulk hernoemen"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Replace:"
-msgstr "Vervangen: "
+msgstr "Vervangen:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Prefix:"
-msgstr "Voorvoegsel"
+msgstr "Voorvoegsel:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Suffix:"
-msgstr "Achtervoegsel"
+msgstr "Achtervoegsel:"
#: editor/rename_dialog.cpp
msgid "Use Regular Expressions"
@@ -10567,11 +10607,10 @@ msgid "Per-level Counter"
msgstr "Per niveau teller"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "If set, the counter restarts for each group of child nodes."
msgstr ""
-"Indien ingesteld: herstart de teller voor iedere groep van onderliggende "
-"knopen"
+"Indien ingesteld, zal de teller voor iedere groep van onderliggende knopen "
+"opnieuw starten."
#: editor/rename_dialog.cpp
msgid "Initial value for the counter"
@@ -10630,9 +10669,8 @@ msgid "Reset"
msgstr "Resetten"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Regular Expression Error:"
-msgstr "Fout in reguliere expressie"
+msgstr "Fout in reguliere expressie:"
#: editor/rename_dialog.cpp
msgid "At character %s"
@@ -10703,6 +10741,16 @@ msgid "Instance Child Scene"
msgstr "Scène instantiëren"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Kan deze operatie niet uitvoeren op knopen uit een vreemde scène!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Knopen plakken"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Script losmaken"
@@ -10830,6 +10878,11 @@ msgid "Attach Script"
msgstr "Script toevoegen"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Knopen knippen"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Verwijder knoop/knopen"
@@ -11635,6 +11688,34 @@ msgstr "Filter Meshes"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "Voeg een MeshLibrary aan deze GridMap toe om meshes te gebruiken."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Begin lichtberekening"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Datastructuren worden voorbereid"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Genereer buffers"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Directe verlichting"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Indirecte verlichting"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Nabewerking"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Lightmaps plotten"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Klassennaam kan geen gereserveerd sleutelwoord zijn"
@@ -12152,12 +12233,16 @@ msgid "Select device from the list"
msgstr "Selecteer apparaat uit de lijst"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "ADB niet ingesteld in Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Het hulpmiddel 'apksigner' kon niet gevonden worden."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK niet ingesteld in Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Geen Android bouwsjabloon geïnstalleerd in dit project. Vanuit het "
+"projectmenu kan het geïnstalleerd worden."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12168,25 +12253,34 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "Release-Keystore is verkeerd ingesteld in de exportinstelingen."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"Eigen build vereist een geldige Android SDK pad in de Editorinstellingen."
+"Een geldig Android SDK-pad moet in de Editorinstellingen ingesteld zijn."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr "Ongeldig Android SDK pad voor custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Ongeldig Android SDK-pad in Editorinstellingen."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
+msgstr "'platform-tools' map ontbreekt!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK platform-tools' adb command."
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+#, fuzzy
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr "Ongeldig Android SDK pad voor custom build in Editor Settings."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
-"Geen Android bouwsjabloon geïnstalleerd in dit project. Vanuit het "
-"projectmenu kan het geïnstalleerd worden."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12428,10 +12522,10 @@ msgid ""
"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
"define its shape."
msgstr ""
-"Deze knoop heeft geen vorm (Shape), dus kan het niet met andere objecten "
-"botsen of interactie hebben.\n"
-"Overweeg om een CollisionShape2D of CollisionPolygon2D als kind toe te "
-"voegen om de vorm ervan vast te leggen."
+"Deze knoop heeft geen botsingsvorm als onderliggende knoop en kan dus niet "
+"met andere objecten botsen of interageren.\n"
+"Plaats hieronder een knoop als CollisionShape2D of CollisionPolygon2D om "
+"deze vorm vast te leggen."
#: scene/2d/collision_polygon_2d.cpp
msgid ""
@@ -12439,13 +12533,22 @@ msgid ""
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
msgstr ""
-"CollisionPolygon2D dient enkel om een botsingsvorm te koppelen aan een knoop "
-"afgeleid van CollisionObject2D. Plaats hem onder een Area2D-, StaticBody2D-, "
-"RigidBody2D- of KinematicBody2D-knoop."
+"Een knooppunt van het type CollisionPolygon2D kan alleen een botsingsvorm "
+"keveren aan knopen die zijn afgeleid van CollisionObject2D. Plaats het dus "
+"alleen onder een knoop als Area2D, StaticBody2D, RigidBody2D of "
+"KinematicBody2D."
#: scene/2d/collision_polygon_2d.cpp
msgid "An empty CollisionPolygon2D has no effect on collision."
-msgstr "Een lege CollisionPolygon2D heeft geen effect op botsingen."
+msgstr "Lege CollisionPolygon2D hebben geen botsingsfunctie."
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -12453,15 +12556,16 @@ msgid ""
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
msgstr ""
-"CollisionShape2D dient enkel om een botsingsvorm te koppelen aan een knoop "
-"afgeleid van CollisionObject2D. Plaats hem onder een Area2D-, StaticBody2D-, "
-"RigidBody2D- of KinematicBody2D-knoop."
+"Een knooppunt van het type CollisionShape2D kan alleen een botsingsvorm "
+"keveren aan knopen die zijn afgeleid van CollisionObject2D. Plaats het dus "
+"alleen onder een knoop als Area2D, StaticBody2D, RigidBody2D of "
+"KinematicBody2D."
#: scene/2d/collision_shape_2d.cpp
msgid ""
"A shape must be provided for CollisionShape2D to function. Please create a "
"shape resource for it!"
-msgstr "Een CollisionShape2D heeft een vorm nodig in de Shape-eigenschap!"
+msgstr "Een CollisionShape2D heeft een vorm nodig."
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -12577,9 +12681,9 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
-"Grootteveranderingen van een RigidBody2D (in Character- of Rigidmodus) zal "
-"overschreven worden door de physics engine als het spel start.\n"
-"Verander in plaats daarvan de grootte van CollisionShapes in de kinderen."
+"De grootte van een RigidBody2D (in Character- of Rigidmodus) wordt "
+"overschreven wanneer het spel start.\n"
+"Verander in plaats daarvan de grootte van de onderliggende botsingsvormen."
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
@@ -12608,10 +12712,9 @@ msgid ""
"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
"KinematicBody2D, etc. to give them a shape."
msgstr ""
-"TileMap met de optie \"Use Parent\" aan heeft een CollisionShape2D-ouder "
-"nodig om vormen aan te geven. De TileMap hoort een kind van een Area2D, "
-"StaticBody2D, RigidBody2D, KinematicBody2D enz. knoop te zijn om ze een vorm "
-"te geven."
+"Een TileMap met de optie \"Use Parent\" ingeschakeld moet knoop afgeleid van "
+"CollisionObject2D (Area2D, StaticBody2D, RigidBody2D of KinematicBody2D) als "
+"ouder hebben."
#: scene/2d/visibility_notifier_2d.cpp
msgid ""
@@ -12654,28 +12757,33 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin heeft een ARVRCamera nodig als kind."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Tijd resterend: %d:%02d s)"
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "Geometrie aan het ontleden..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Plotten Meshes: "
+#, fuzzy
+msgid "Preparing environment"
+msgstr "Bekijk Omgeving"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Plotten Light:"
+#, fuzzy
+msgid "Generating capture"
+msgstr "Bouw Lightmappen"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Plotten Voltooid"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Bouw Lightmappen"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Light Meshes: "
+#, fuzzy
+msgid "Done"
+msgstr "Klaar!"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12683,10 +12791,10 @@ msgid ""
"Consider adding a CollisionShape or CollisionPolygon as a child to define "
"its shape."
msgstr ""
-"Deze knoop heeft geen vorm (Shape), dus het kan niet met andere objecten "
-"botsen of interactie hebben.\n"
-"Overweeg om een CollisionShape of CollisionPolygon als kind toe te voegen om "
-"de vorm ervan vast te leggen."
+"Deze knoop heeft geen botsingsvorm als onderliggende knoop en kan dus niet "
+"met andere objecten botsen of interageren.\n"
+"Plaats hieronder een knoop als CollisionShape of CollisionPolygon om deze "
+"vorm vast te leggen."
#: scene/3d/collision_polygon.cpp
msgid ""
@@ -12694,13 +12802,13 @@ msgid ""
"CollisionObject derived node. Please only use it as a child of Area, "
"StaticBody, RigidBody, KinematicBody, etc. to give them a shape."
msgstr ""
-"CollisionPolygon dient enkel om een botsingsvorm te koppelen aan een knoop "
-"afgeleid van CollisionObject. Plaats hem onder een Area-, StaticBody-, "
-"RigidBody- of KinematicBody-knoop."
+"Een knooppunt van het type CollisionPolygon kan alleen een botsingsvorm "
+"keveren aan knopen die zijn afgeleid van CollisionObject. Plaats het dus "
+"alleen onder een knoop als Area, StaticBody, RigidBody of KinematicBody."
#: scene/3d/collision_polygon.cpp
msgid "An empty CollisionPolygon has no effect on collision."
-msgstr "Een lege CollisionPolygon heeft geen effect op botsingen."
+msgstr "Lege CollisionPolygon hebben geen botsingsfunctie."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -12708,17 +12816,15 @@ msgid ""
"derived node. Please only use it as a child of Area, StaticBody, RigidBody, "
"KinematicBody, etc. to give them a shape."
msgstr ""
-"CollisionShape dient enkel om een botsingsvorm te koppelen aan een knoop "
-"afgeleid van CollisionObject. Plaats hem onder een Area-, StaticBody-, "
-"RigidBody- of KinematicBody-knoop."
+"Een knooppunt van het type CollisionShape kan alleen een botsingsvorm "
+"keveren aan knopen die zijn afgeleid van CollisionObject2D. Plaats het dus "
+"alleen onder een knoop als Area, StaticBody, RigidBody of KinematicBody."
#: scene/3d/collision_shape.cpp
msgid ""
"A shape must be provided for CollisionShape to function. Please create a "
"shape resource for it."
-msgstr ""
-"Om CollisionShape te laten werken, hoort het een Shape te hebben. Maak "
-"hiervoor alstublieft een Shape bron aan."
+msgstr "Een CollisionShape heeft een vorm nodig."
#: scene/3d/collision_shape.cpp
msgid ""
@@ -12750,6 +12856,10 @@ msgid "Plotting Meshes"
msgstr "Plotten van Meshes"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Plotten Voltooid"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12757,11 +12867,6 @@ msgstr ""
"GIProbes worden niet ondersteund door het GLES2 grafische stuurprogramma.\n"
"Gebruik in plaats daarvan een BakedLightmap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
@@ -12823,9 +12928,9 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
-"Grootteveranderingen van een RigidBody (in Character- of Rigidmodus) zal "
-"overschreven worden door de physics engine als het spel start.\n"
-"Verander in plaats daarvan de grootte van CollisionShapes in de kinderen."
+"De grootte van een RigidBody (in Character- of Rigidmodus) wordt "
+"overschreven wanneer het spel start.\n"
+"Verander in plaats daarvan de grootte van de onderliggende botsingsvormen."
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
@@ -12865,9 +12970,8 @@ msgid ""
"running.\n"
"Change the size in children collision shapes instead."
msgstr ""
-"Grootteveranderingen van een SoftBody (in Character- of Rigidmodus) zal "
-"overschreven worden door de physics engine als het spel start.\n"
-"Verander de grootte van CollisionShapes in de kinderen."
+"De grootte van een SoftBody wordt overschreven wanneer het spel start.\n"
+"Verander in plaats daarvan de grootte van de onderliggende botsingsvormen."
#: scene/3d/sprite_3d.cpp
msgid ""
@@ -13007,6 +13111,14 @@ msgstr "Alarm!"
msgid "Please Confirm..."
msgstr "Bevestig alstublieft..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Een geldige extensie moet gebruikt worden."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Rasteroverzicht inschakelen."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13061,6 +13173,12 @@ msgstr ""
"De grootte van een Viewport moet groter zijn dan 0 om iets weer te geven."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Ongeldige bron voor voorvertoning."
@@ -13088,6 +13206,43 @@ msgstr "Varyings kunnen alleen worden toegewezenin vertex functies."
msgid "Constants cannot be modified."
msgstr "Constanten kunnen niet worden aangepast."
+#~ msgid "No"
+#~ msgstr "Nee"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Deze scene is nooit opgeslagen. Sla op voor het uitvoeren?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "ADB niet ingesteld in Editor Settings."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK niet ingesteld in Editor Settings."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Eigen build vereist een geldige Android SDK pad in de Editorinstellingen."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Tijd resterend: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Plotten Meshes: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Light Meshes: "
+
+#~ msgid "Search complete"
+#~ msgstr "Zoek Compleet"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Geen commitbericht was gegeven"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Voeg een vastleggingsbericht toe"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Er is al een bestand of map met dezelfde naam op dit pad."
diff --git a/editor/translations/or.po b/editor/translations/or.po
index ba12c5c7eb..19b87260d6 100644
--- a/editor/translations/or.po
+++ b/editor/translations/or.po
@@ -1,6 +1,6 @@
# Odia translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Pro Neon <proneon267@gmail.com>, 2019.
msgid ""
@@ -625,7 +625,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1794,8 +1794,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1886,10 +1886,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2293,6 +2289,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2336,18 +2336,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2395,6 +2383,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2437,7 +2429,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2827,14 +2819,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2988,6 +2972,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3190,7 +3190,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3726,7 +3726,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3863,6 +3871,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4810,7 +4830,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4914,7 +4934,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4945,8 +4964,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4960,9 +4978,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6018,6 +6055,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6078,10 +6119,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6663,6 +6700,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6714,16 +6759,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6816,8 +6851,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7038,6 +7073,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8249,10 +8288,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8309,10 +8344,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9566,6 +9597,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9926,6 +9961,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10169,6 +10208,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10289,6 +10336,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11073,6 +11124,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11568,11 +11647,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11584,11 +11665,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11596,9 +11677,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11823,6 +11914,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -11989,27 +12088,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12069,14 +12168,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12282,6 +12380,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12323,6 +12429,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index 3e67b723b5..173e86753f 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -1,6 +1,6 @@
# Polish translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# 8-bit Pixel <dawdejw@gmail.com>, 2016.
# Adam Wolanski <adam.wolanski94@gmail.com>, 2017.
@@ -24,7 +24,7 @@
# Sebastian Pasich <sebastian.pasich@gmail.com>, 2017, 2019, 2020.
# siatek papieros <sbigneu@gmail.com>, 2016.
# Zatherz <zatherz@linux.pl>, 2017, 2020.
-# Tomek <kobewi4e@gmail.com>, 2018, 2019, 2020.
+# Tomek <kobewi4e@gmail.com>, 2018, 2019, 2020, 2021.
# Wojcieh Er Zet <wojcieh.rzepecki@gmail.com>, 2018.
# Dariusz Siek <dariuszynski@gmail.com>, 2018, 2019, 2020.
# Szymon Nowakowski <smnbdg13@gmail.com>, 2019.
@@ -45,12 +45,14 @@
# Piotr Grodzki <ziemniakglados@gmail.com>, 2020.
# Dzejkop <jakubtrad@gmail.com>, 2020.
# Mateusz Grzonka <alpinus4@gmail.com>, 2020.
+# gnu-ewm <gnu.ewm@protonmail.com>, 2021.
+# vrid <patryksoon@live.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-01 20:29+0000\n"
-"Last-Translator: Mateusz Grzonka <alpinus4@gmail.com>\n"
+"PO-Revision-Date: 2021-02-27 00:47+0000\n"
+"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
"Language: pl\n"
@@ -59,7 +61,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -687,7 +689,7 @@ msgstr "Wybierz ścieżki do skopiowania"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopiuj"
@@ -903,7 +905,7 @@ msgstr "Sygnał:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
-msgstr "Połącz \"%s\" z \"%s\""
+msgstr "Połącz '%s' z '%s'"
#: editor/connections_dialog.cpp
msgid "Disconnect '%s' from '%s'"
@@ -1889,8 +1891,8 @@ msgid "Open a File or Directory"
msgstr "Otwórz plik lub katalog"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Zapisz"
@@ -1981,10 +1983,6 @@ msgstr "PodglÄ…d:"
msgid "File:"
msgstr "Plik:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Rozszerzenie musi być poprawne."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Przeszukaj źródła"
@@ -2419,6 +2417,10 @@ msgid "There is no defined scene to run."
msgstr "Nie ma zdefiniowanej sceny do uruchomienia."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Zapisz scenÄ™ przed uruchomieniem..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Nie można było uruchomić podprocesu!"
@@ -2462,18 +2464,6 @@ msgstr "Scena musi posiadać korzeń, by ją zapisać."
msgid "Save Scene As..."
msgstr "Zapisz scenÄ™ jako..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nie"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Tak"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Ta scena nie została zapisana. Zapisać przed uruchomieniem?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Ta operacja nie może zostać wykonana bez sceny."
@@ -2523,6 +2513,10 @@ msgid "Quit"
msgstr "Wyjdź"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Tak"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Zamknąć edytor?"
@@ -2569,8 +2563,8 @@ msgstr ""
"Nie można włączyć dodatku: \"%s\" - parsowanie konfiguracji nie powiodło się."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr "Nie można odnaleźć pola skryptu w dodatku: \"res://addons/%s\"."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "Nie można odnaleźć pola skryptu w dodatku: \"%s\"."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -3000,14 +2994,6 @@ msgid "Help"
msgstr "Pomoc"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Szukaj"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Dokumentacja online"
@@ -3171,6 +3157,24 @@ msgid "Open & Run a Script"
msgstr "Otwórz i Uruchom Skrypt"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Następujące pliki są nowsze na dysku.\n"
+"Jakie działanie powinno zostać podjęte?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Przeładuj"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Zapisz ponownie"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Nowa dziedziczÄ…ca scena"
@@ -3381,7 +3385,7 @@ msgstr "Zrób unikalny"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Wklej"
@@ -3742,6 +3746,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Następujące pliki lub foldery konfliktują z pozycjami w lokalizacji "
+"docelowej \"%s\":\n"
+"\n"
+"%s\n"
+"\n"
+"Czy chcesz je nadpisać?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3934,8 +3944,16 @@ msgid "Searching..."
msgstr "Wyszukiwanie..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Wyszukiwanie zakończone"
+msgid "%d match in %d file."
+msgstr "%d dopasowanie w %d pliku."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d dopasowań w %d pliku."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d dopasowań w %d plikach."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4073,6 +4091,21 @@ msgstr "Czy zwracasz obiekt dziedziczÄ…cy po Node w metodzie `post_import()`?"
msgid "Saving..."
msgstr "Zapisywanie..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Tryb zaznaczenia"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importuj"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Użyj domyślnie sRGB"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d plików"
@@ -4191,7 +4224,7 @@ msgstr "Zmiany mogą zostać utracone!"
#: editor/multi_node_edit.cpp
msgid "MultiNode Set"
-msgstr "Zestaw wielowęzłowy"
+msgstr "Ustaw wielu węzłom"
#: editor/node_dock.cpp
msgid "Select a single node to edit its signals and groups."
@@ -5041,8 +5074,8 @@ msgid "Got:"
msgstr "Otrzymano:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Nie udało się przeprowadzić testu integralności sha256"
+msgid "Failed SHA-256 hash check"
+msgstr "Test SHA-256 nieudany"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5145,7 +5178,6 @@ msgid "Sort:"
msgstr "Sortuj:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategoria:"
@@ -5176,12 +5208,10 @@ msgstr "Plik ZIP assetów"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"Nie można określić ścieżki zapisu dla lightmapy obrazu.\n"
-"Zapisz scenę (obrazy będą zapisane w tym samym katalogu), lub przepisz "
-"ścieżkę zapisu z właściwości BakedLightmap."
+"Nie można określić ścieżki zapisu dla obrazów mapy światła.\n"
+"Zapisz scenę i spróbuj ponownie."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5198,9 +5228,34 @@ msgstr ""
"jedynie do odczytu."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Nie udało się określić rozmiaru mapy światła. Maksymalny rozmiar jest za "
+"mały?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Jakaś siatka jest nieprawidłowa. Upewnij się, że wartości kanału UV2 "
+"mieszczÄ… siÄ™ w kwadratowym obszarze [0.0, 1.0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Godot został zbudowany bez wsparcia ray tracingu, mapy światła nie mogą być "
+"wypalone."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Stwórz Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Wybierz plik wypalenia mapy światła:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6296,6 +6351,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Punkt można wstawić tylko w materiał przetwarzania ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Przekonwertuj na CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Czas generowania (sek):"
@@ -6356,10 +6415,6 @@ msgstr "Generowanie AABB"
msgid "Generate Visibility AABB"
msgstr "Generuj AABB widoczności"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Generuj AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Usuń punkt z krzywej"
@@ -6949,6 +7004,14 @@ msgstr "Zamknij pliki pomocy"
msgid "Run"
msgstr "Uruchom"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Szukaj"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Krok w"
@@ -7002,16 +7065,6 @@ msgstr ""
"Następujące pliki są nowsze na dysku.\n"
"Jakie działania powinny zostać podjęte?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Przeładuj"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Zapisz ponownie"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Debugger"
@@ -7107,8 +7160,8 @@ msgstr "Punkty wstrzymania"
msgid "Go To"
msgstr "Idź do"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Wytnij"
@@ -7331,6 +7384,10 @@ msgid "Yaw"
msgstr "Odchylenie"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Rozmiar"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Narysowane obiekty"
@@ -8506,7 +8563,7 @@ msgstr "Edytuj wielokÄ…t nawigacji"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Paste Tile Bitmask"
-msgstr "Wklej maskÄ™ bitowÄ… Kafelka"
+msgstr "Wklej maskÄ™ bitowÄ… kafelka"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Clear Tile Bitmask"
@@ -8577,10 +8634,6 @@ msgid "Error"
msgstr "Błąd"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Nie podano wiadomości commitu"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Brak plików dodanych do stage'a"
@@ -8637,10 +8690,6 @@ msgid "Stage All"
msgstr "Stage'uj wszystko"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Dodaj wiadomość comittu"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Commituj zmiany"
@@ -9845,7 +9894,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Nie obsługiwany przez twój sterownik GPU."
#: editor/project_manager.cpp
msgid ""
@@ -10024,6 +10073,10 @@ msgid "Projects"
msgstr "Projekty"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Wczytywanie, proszę czekać..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Data modyfikacji"
@@ -10132,15 +10185,15 @@ msgstr "Indeks przycisku myszy:"
#: editor/project_settings_editor.cpp
msgid "Left Button"
-msgstr "Lewy guzik"
+msgstr "Lewy przycisk"
#: editor/project_settings_editor.cpp
msgid "Right Button"
-msgstr "Prawy guzik"
+msgstr "Prawy przycisk"
#: editor/project_settings_editor.cpp
msgid "Middle Button"
-msgstr "Åšrodkowy guzik"
+msgstr "Åšrodkowy przycisk"
#: editor/project_settings_editor.cpp
msgid "Wheel Up Button"
@@ -10394,6 +10447,11 @@ msgstr "Autoładowanie"
msgid "Plugins"
msgstr "Wtyczki"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Wczytaj domyślny"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Ustawienie predefiniowane..."
@@ -10643,6 +10701,14 @@ msgid "Instance Child Scene"
msgstr "Dodaj instancjÄ™ sceny"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "Nie można wkleić korzenia do tej samej sceny."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Wklej węzeł/y"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Odłącz skrypt"
@@ -10769,6 +10835,10 @@ msgid "Attach Script"
msgstr "Dołącz skrypt"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Wytnij węzeł/y"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Usuń węzeł(y)"
@@ -11576,6 +11646,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
"Przypisz temu węzłowi GridMap zasób MeshLibrary, aby korzystać z jego siatek."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Zacznij wypalanie"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Przygotowywanie struktur danych"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Generuj bufory"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Oświetlenie bezpośrednie"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Oświetlenie pośrednie"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Przetwarzanie końcowe"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Kreślenie map światła"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Nazwa klasy nie może być słowem zastrzeżonym"
@@ -12087,12 +12185,16 @@ msgid "Select device from the list"
msgstr "Wybierz urzÄ…dzenie z listy"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Plik wykonywalny ADB nie skonfigurowany w Ustawieniach Edytora."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Nie udało się znaleźć narzędzia \"apksigner\"."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "Jarsigner OpenJDK nie skonfigurowany w Ustawieniach Edytora."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Szablon budowania Androida nie jest zainstalowany dla projektu. Zainstaluj "
+"go z menu Projekt."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12106,27 +12208,33 @@ msgstr ""
"Wydaniowy keystore jest niepoprawnie skonfigurowany w profilu eksportu."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr ""
-"Własny build wymaga poprawnej ścieżki do SDK Androida w Ustawieniach Edytora."
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "Wymagana jest poprawna ścieżka SDK Androida w Ustawieniach Edytora."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Niepoprawna ścieżka do SDK Androida dla własnego builda w Ustawieniach "
-"Edytora."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Niepoprawna ścieżka do SDK Androida w Ustawieniach Edytora."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "Folder \"platform-tools\" nie istnieje!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
msgstr ""
-"Szablon budowania Androida nie jest zainstalowany dla projektu. Zainstaluj "
-"go z menu Projekt."
+"Nie udało się znaleźć komendy adb z narzędzi platformowych SDK Androida."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr "Sprawdź w folderze SDK Androida podanych w Ustawieniach Edytora."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "Brakuje folderu \"build-tools\"!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "Nie udało się znaleźć komendy apksigner z narzędzi SDK Androida."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12392,6 +12500,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Pusty CollisionPolygon2D nie ma wpływu na kolizje."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12430,23 +12546,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A i Node B muszą być węzłami PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node A musi być węzłem PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node B musi być węzłem PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Złącze nie jest połączone do dwóch węzłów PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A i Node B muszą być różnymi węzłami PhysicsBody2D"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12603,28 +12719,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin wymaga węzła potomnego typu ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Szukanie siatek i świateł"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Pozostały czas: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Przygotowywanie geometrii (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Kreślenie siatek: "
+msgid "Preparing environment"
+msgstr "Przygotowywanie środowiska"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Kreślenie świateł:"
+msgid "Generating capture"
+msgstr "Generowanie przechwycenia"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Kończenie kreślenia"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Zapisywanie map światła"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Oświetlanie siatek: "
+msgid "Done"
+msgstr "Gotowe"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12702,6 +12818,10 @@ msgid "Plotting Meshes"
msgstr "Kreślenie siatek"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Kończenie kreślenia"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12709,12 +12829,6 @@ msgstr ""
"GIProbes nie są obsługiwane przez sterownik wideo GLES2.\n"
"Zamiast tego użyj BakedLightmap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-"Węzeł InterpolatedCamera jest przestarzały i będzie usunięty w Godocie 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight z kątem szerszym niż 90 stopni nie może rzucać cieni."
@@ -12781,23 +12895,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Node A i Node B muszą być węzłami PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Node A musi być węzłem PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Node B musi być węzłem PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Złącze nie jest połączone z żadnym węzłem PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Node A i Node B muszą być różnymi węzłami PhysicsBody"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12958,6 +13072,14 @@ msgstr "Alarm!"
msgid "Please Confirm..."
msgstr "Proszę potwierdzić..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Rozszerzenie musi być poprawne."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Włącz minimapę siatki."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13011,6 +13133,14 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "Rozmiar węzła Viewport musi być większy niż 0, by coś wyrenderować."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"Port samplera jest podłączony, ale nieużyty. Rozważ zmianę źródła na "
+"\"SamplerPort\"."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Nieprawidłowe źródło do podglądu."
@@ -13038,14 +13168,52 @@ msgstr "Varying może być przypisane tylko w funkcji wierzchołków."
msgid "Constants cannot be modified."
msgstr "Stałe nie mogą być modyfikowane."
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "W tej lokalizacji istnieje już plik lub folder o podanej nazwie."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "Węzeł InterpolatedCamera jest przestarzały i będzie usunięty w Godocie "
+#~ "4.0."
+
+#~ msgid "No"
+#~ msgstr "Nie"
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "Brakuje folderu \"build-tools\"!"
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Ta scena nie została zapisana. Zapisać przed uruchomieniem?"
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "Nie udało się znaleźć narzędzia zipalign."
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "Plik wykonywalny ADB nie skonfigurowany w Ustawieniach Edytora."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "Jarsigner OpenJDK nie skonfigurowany w Ustawieniach Edytora."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Własny build wymaga poprawnej ścieżki do SDK Androida w Ustawieniach "
+#~ "Edytora."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Pozostały czas: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Kreślenie siatek: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Oświetlanie siatek: "
+
+#~ msgid "Search complete"
+#~ msgstr "Wyszukiwanie zakończone"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Nie podano wiadomości commitu"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Dodaj wiadomość comittu"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "W tej lokalizacji istnieje już plik lub folder o podanej nazwie."
#~ msgid "Aligning APK..."
#~ msgstr "Uzgadnianie APK..."
@@ -13388,9 +13556,6 @@ msgstr "Stałe nie mogą być modyfikowane."
#~ msgid "Failed to save solution."
#~ msgstr "Nie udało się zapisać solucji."
-#~ msgid "Done"
-#~ msgstr "Gotowe"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Nie udało się utworzyć projektu języka C#."
@@ -14629,9 +14794,6 @@ msgstr "Stałe nie mogą być modyfikowane."
#~ msgid "Use Default Light"
#~ msgstr "Użyj domyślnego światła"
-#~ msgid "Use Default sRGB"
-#~ msgstr "Użyj domyślnie sRGB"
-
#~ msgid "Ambient Light Color:"
#~ msgstr "Kolor światła otoczenia:"
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index ca0f2d5f7e..09d967e01d 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -1,6 +1,6 @@
# Pirate translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Calum Knott <calum@calumk.com>, 2017.
# Zion Nimchuk <zionnimchuk@gmail.com>, 2016-2017.
@@ -656,7 +656,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1862,8 +1862,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1956,10 +1956,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2373,6 +2369,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2416,18 +2416,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2476,6 +2464,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2518,7 +2510,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2919,14 +2911,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3083,6 +3067,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3291,7 +3291,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3854,7 +3854,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3996,6 +4004,19 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Slit th' Node"
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -4979,7 +5000,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5083,7 +5104,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5114,8 +5134,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5129,9 +5148,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Slit th' Node"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6215,6 +6254,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Discharge ye' Function"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6275,10 +6319,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6881,6 +6921,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6933,16 +6981,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7039,8 +7077,8 @@ msgstr "Yar, Blow th' Selected Down!"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7273,6 +7311,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8552,10 +8594,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8618,10 +8656,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Change"
@@ -9899,6 +9933,10 @@ msgid "Projects"
msgstr "Rename Function"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10265,6 +10303,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10513,6 +10555,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Paste yer Node"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Discharge ye' Variable"
@@ -10638,6 +10689,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Slit th' Node"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11461,6 +11517,36 @@ msgstr "Paste yer Node"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Yer functions:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Swap yer Expression"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12002,11 +12088,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12018,11 +12106,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12030,9 +12118,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12264,6 +12362,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12430,27 +12536,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12510,14 +12616,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12724,6 +12829,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12765,6 +12878,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Yer Calligraphy be wrongly sized."
diff --git a/editor/translations/pt.po b/editor/translations/pt.po
index b675b90e75..28325d59bc 100644
--- a/editor/translations/pt.po
+++ b/editor/translations/pt.po
@@ -1,12 +1,12 @@
# Portuguese translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# António Sarmento <antonio.luis.sarmento@gmail.com>, 2016.
# Carlos Vieira <carlos.vieira@gmail.com>, 2017.
# João <joao@nogordio.com>, 2018.
# João Graça <jgraca95@gmail.com>, 2017.
-# João Lopes <linux-man@hotmail.com>, 2017-2018, 2019, 2020.
+# João Lopes <linux-man@hotmail.com>, 2017-2018, 2019, 2020, 2021.
# Miguel Gomes <miggas09@gmail.com>, 2017.
# Paulo Caldeira <paucal@gmail.com>, 2018.
# Pedro Gomes <pedrogomes1698@gmail.com>, 2017.
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-01 20:29+0000\n"
+"PO-Revision-Date: 2021-01-26 03:28+0000\n"
"Last-Translator: João Lopes <linux-man@hotmail.com>\n"
"Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/"
"godot/pt/>\n"
@@ -31,7 +31,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -566,7 +566,7 @@ msgstr "Copiar Pistas"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
-msgstr "Escalar Selecção"
+msgstr "Escalar Seleção"
#: editor/animation_track_editor.cpp
msgid "Scale From Cursor"
@@ -622,7 +622,7 @@ msgstr "Máximo de Erros Angulares:"
#: editor/animation_track_editor.cpp
msgid "Max Optimizable Angle:"
-msgstr "Angulo Máximo Otimizável:"
+msgstr "Ângulo Máximo Otimizável:"
#: editor/animation_track_editor.cpp
msgid "Optimize"
@@ -630,7 +630,7 @@ msgstr "Otimizar"
#: editor/animation_track_editor.cpp
msgid "Remove invalid keys"
-msgstr "Remover Chaves inválidas"
+msgstr "Remover chaves inválidas"
#: editor/animation_track_editor.cpp
msgid "Remove unresolved and empty tracks"
@@ -661,7 +661,7 @@ msgstr "Selecionar Pistas a Copiar"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Copiar"
@@ -1132,7 +1132,7 @@ msgstr "Agradecimentos da Comunidade Godot!"
#: editor/editor_about.cpp
msgid "Godot Engine contributors"
-msgstr "Contribuidores da engine Godot"
+msgstr "Contribuidores do Godot Engine"
#: editor/editor_about.cpp
msgid "Project Founders"
@@ -1867,8 +1867,8 @@ msgid "Open a File or Directory"
msgstr "Abrir um Ficheiro ou Diretoria"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Guardar"
@@ -1959,10 +1959,6 @@ msgstr "Pré-visualização:"
msgid "File:"
msgstr "Ficheiro:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Deve usar uma extensão válida."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Analisar fontes"
@@ -2272,7 +2268,7 @@ msgstr "A guardar Cena"
#: editor/editor_node.cpp
msgid "Analyzing"
-msgstr "A analizar"
+msgstr "A analisar"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
@@ -2400,6 +2396,10 @@ msgid "There is no defined scene to run."
msgstr "Não existe cena definida para execução."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Guardar cena antes de executar..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Não consegui iniciar o subprocesso!"
@@ -2443,18 +2443,6 @@ msgstr "É necessário um nó raiz para guardar a cena."
msgid "Save Scene As..."
msgstr "Guardar Cena Como..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Não"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Sim"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Esta cena nunca foi guardada. Guardar antes de executar?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Esta operação não pode ser efetuada sem uma cena."
@@ -2504,6 +2492,10 @@ msgid "Quit"
msgstr "Sair"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Sim"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Sair do Editor?"
@@ -2550,7 +2542,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "Incapaz de ativar plugin em: '%s' falha de análise ou configuração."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "Incapaz de localizar campo Script para plugin em: 'res://addons/%s'."
#: editor/editor_node.cpp
@@ -2764,7 +2757,7 @@ msgstr "Converter Para..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr "Bib. de Meshes..."
+msgstr "MeshLibrary..."
#: editor/editor_node.cpp
msgid "TileSet..."
@@ -2894,7 +2887,7 @@ msgid ""
"When this option is enabled, navigation meshes and polygons will be visible "
"in the running project."
msgstr ""
-"Com esta opção ativa, Meshes e Polígonos de navegação serão visíveis no "
+"Com esta opção ativa, malhas de navegação e polígonos serão visíveis no "
"projeto em execução."
#: editor/editor_node.cpp
@@ -2915,7 +2908,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Synchronize Script Changes"
-msgstr "Sicronizar alterações de script"
+msgstr "Sincronizar Alterações de Script"
#: editor/editor_node.cpp
msgid ""
@@ -2983,14 +2976,6 @@ msgid "Help"
msgstr "Ajuda"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Procurar"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentação Online"
@@ -3155,6 +3140,25 @@ msgid "Open & Run a Script"
msgstr "Abrir & Executar um Script"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Os seguintes Ficheiros são mais recentes no disco.\n"
+"Que ação deve ser tomada?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Recarregar"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Guardar novamente"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Novo Herdado"
@@ -3200,7 +3204,7 @@ msgstr "Sub-recurso não encontrado."
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
-msgstr "A criar pré-visualizações de Malha"
+msgstr "A criar Pré-visualizações de Malha"
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
@@ -3365,7 +3369,7 @@ msgstr "Fazer único"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Colar"
@@ -3435,7 +3439,7 @@ msgstr "Não consegui executar o script:"
#: editor/editor_run_script.cpp
msgid "Did you forget the '_run' method?"
-msgstr "Esqueceu-se do médodo '_run'?"
+msgstr "Esqueceu-se do método '_run'?"
#: editor/editor_spin_slider.cpp
msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes."
@@ -3729,6 +3733,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Os seguintes ficheiros ou pastas estão em conflito com os itens na "
+"localização '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Deseja sobrescrevê-los?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3921,8 +3931,16 @@ msgid "Searching..."
msgstr "A procurar..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Pesquisa completa"
+msgid "%d match in %d file."
+msgstr "Correspondência de %d no ficheiro %d."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "Correspondências de %d no ficheiro %d."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "Correspondências de %d em %d ficheiros."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4058,6 +4076,21 @@ msgstr "Devolveu um objeto derivado de Nó no método `post_import()`?"
msgid "Saving..."
msgstr "A guardar..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Modo Seleção"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importar"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Carregar Predefinição"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Ficheiros"
@@ -4313,7 +4346,7 @@ msgid ""
"Activate to enable playback, check node warnings if activation fails."
msgstr ""
"AnimationTree está inativa.\n"
-"Active-a para permitir a reprodução, verifique avisos do nó se a ativação "
+"Ative-a para permitir a reprodução, verifique avisos do nó se a ativação "
"falhar."
#: editor/plugins/animation_blend_space_1d_editor.cpp
@@ -5013,7 +5046,7 @@ msgstr "Tempo expirado."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
-msgstr "Mau hash na transferência, assume-se que o Ficheiro foi manipulado."
+msgstr "Mau hash na transferência, assume-se que o ficheiro foi manipulado."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Expected:"
@@ -5024,7 +5057,8 @@ msgid "Got:"
msgstr "Obtido:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Verificação hash sha256 falhada"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5128,7 +5162,6 @@ msgid "Sort:"
msgstr "Ordenar:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Categoria:"
@@ -5159,19 +5192,17 @@ msgstr "Ficheiro ZIP de Ativos"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Não consigo determinar um caminho para guardar imagens lightmap.\n"
-"Guarde a sua cena (para as imagens serem guardadas na mesma diretoria), ou "
-"escolha um caminho nas propriedades BakedLightmap."
+"Guarde a sua cena e tente novamente."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake "
"Light' flag is on."
msgstr ""
-"Não há Meshes para consolidar. Assegure-se que contêm um canal UV2 e que a "
+"Não há malhas para consolidar. Assegure-se que contêm um canal UV2 e que a "
"referência 'Bake Light' flag está on."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5179,9 +5210,34 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "Falha ao criar imagens lightmap, assegure-se que o caminho é gravável."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Falha na determinação do tamanho do lightmap. Tamanho máximo do lightmap "
+"demasiado pequeno?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Alguma malha é inválida. Certifique-se que os valores do canal UV2 estão "
+"contidos na região quadrada [0.0,1.0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Editor Godot foi compilado sem suporte para ray tracing, lightmaps não podem "
+"ser consolidados."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Consolidar Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Selecionar ficheiro de consolidação de lightmap:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5293,7 +5349,7 @@ msgid ""
"their parent."
msgstr ""
"As âncoras e margens de filhos de um contentores são sobrescritas pelo seu "
-"pai."
+"progenitor."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Presets for the anchors and margins values of a Control node."
@@ -5393,8 +5449,8 @@ msgid ""
"Game Camera Override\n"
"Overrides game camera with editor viewport camera."
msgstr ""
-"Sobreposição de Câmara de Jogo\n"
-"Sobrepõe câmara de jogo com câmara viewport do editor."
+"Sobreposição de Câmera de Jogo\n"
+"Sobrepõe câmara de jogo com câmera viewport do editor."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5402,7 +5458,7 @@ msgid ""
"Game Camera Override\n"
"No game instance running."
msgstr ""
-"Sobreposição de Câmara de Jogo\n"
+"Sobreposição de Câmera de Jogo\n"
"Nenhuma instância de jogo em execução."
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5455,7 +5511,7 @@ msgid ""
"by their parent."
msgstr ""
"Atenção: as crianças de um contentor obtêm a sua posição e tamanho "
-"determinados apenas pelos seus pais."
+"determinados apenas pelos seus progenitores."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
@@ -5568,7 +5624,7 @@ msgstr "Configurar Ajuste..."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
-msgstr "Ajustar ao Parente"
+msgstr "Ajustar ao Progenitor"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Node Anchor"
@@ -5956,7 +6012,7 @@ msgstr "Não consegui criar uma forma de colisão Trimesh."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Static Trimesh Body"
-msgstr "Criar corpo estático Trimesh"
+msgstr "Criar Corpo Estático Trimesh"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "This doesn't work on scene root!"
@@ -6001,7 +6057,7 @@ msgstr "Malha contida não é do tipo ArrayMesh."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "UV Unwrap failed, mesh may not be manifold?"
-msgstr "Falhou o desempacotamento UV, a Malha pode não ser múltipla?"
+msgstr "Falhou o desempacotamento UV, a malha pode não ser múltipla?"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "No mesh to debug."
@@ -6021,7 +6077,7 @@ msgstr "A Malha não tem superfície para criar contornos!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!"
-msgstr "Tipo primitivo de Malha não é PRIMITIVE_TRIANGLES!"
+msgstr "Tipo primitivo de malha não é PRIMITIVE_TRIANGLES!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Could not create outline!"
@@ -6037,7 +6093,7 @@ msgstr "Malha"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
-msgstr "Criar corpo estático Trimesh"
+msgstr "Criar Corpo Estático Trimesh"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6123,7 +6179,7 @@ msgstr "Tamanho do contorno:"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "UV Channel Debug"
-msgstr "Debug Canal UV"
+msgstr "Depuração Canal UV"
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Remove item %d?"
@@ -6139,7 +6195,7 @@ msgstr ""
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Mesh Library"
-msgstr "Bib. de Meshes"
+msgstr "Bib. de Malhas"
#: editor/plugins/mesh_library_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
@@ -6160,11 +6216,11 @@ msgstr "Atualizar a partir da Cena"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and no MultiMesh set in node)."
-msgstr "Fonte da Malha não especificada (nem MultiMesh no nó)."
+msgstr "Fonte da malha não especificada (nem MultiMesh definido no nó)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and MultiMesh contains no Mesh)."
-msgstr "Fonte da Malha não especificada (e MultiMesh não contêm Malha)."
+msgstr "Fonte da malha não especificada (e MultiMesh não contêm Malha)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (invalid path)."
@@ -6196,7 +6252,7 @@ msgstr "A fonte de superfície é inválida (sem faces)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Source Mesh:"
-msgstr "Selecione uma fonte Malha:"
+msgstr "Selecione uma Fonte Malha:"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Select a Target Surface:"
@@ -6273,6 +6329,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Só pode definir um Ponto num Material ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Converter em CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Tempo de geração (s):"
@@ -6333,10 +6393,6 @@ msgstr "A gerar AABB"
msgid "Generate Visibility AABB"
msgstr "Gerar visibilidade AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Gerar AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Remover Ponto da curva"
@@ -6494,7 +6550,7 @@ msgstr "Criar mapa UV"
msgid ""
"Polygon 2D has internal vertices, so it can no longer be edited in the "
"viewport."
-msgstr "Polygon 2D tem vértices internos, não poder ser editado no viewport."
+msgstr "Polígono 2D tem vértices internos, não pode ser editado no viewport."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create Polygon & UV"
@@ -6534,7 +6590,7 @@ msgstr "Pintar pesos dos ossos"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Open Polygon 2D UV editor."
-msgstr "Abrir editor UV de Polygon2D."
+msgstr "Abrir editor UV de Polígono 2D."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon 2D UV Editor"
@@ -6786,7 +6842,7 @@ msgstr "Não consigo obter o script para executar."
#: editor/plugins/script_editor_plugin.cpp
msgid "Script failed reloading, check console for errors."
-msgstr "Falhou a re-leitura do script, analise os erros na consola."
+msgstr "Falhou a releitura do script, analise os erros na consola."
#: editor/plugins/script_editor_plugin.cpp
msgid "Script is not in tool mode, will not be able to run."
@@ -6926,6 +6982,14 @@ msgstr "Fechar documentos"
msgid "Run"
msgstr "Executar"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Procurar"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Passar Dentro"
@@ -6979,16 +7043,6 @@ msgstr ""
"Os seguintes Ficheiros são mais recentes no disco.\n"
"Que ação deve ser tomada?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Recarregar"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Reguardar"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Depurador"
@@ -7003,7 +7057,7 @@ msgstr "Limpar Scripts Recentes"
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
-msgstr "Conecções ao método:"
+msgstr "Conexões ao método:"
#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp
msgid "Source"
@@ -7081,8 +7135,8 @@ msgstr "Pontos de paragem"
msgid "Go To"
msgstr "Ir Para"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Cortar"
@@ -7305,6 +7359,11 @@ msgid "Yaw"
msgstr "Direção"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Tamanho: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objetos desenhados"
@@ -7382,7 +7441,7 @@ msgstr "Alinhar Rotação com Vista"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
-msgstr "Sem parente para criar instância de filho."
+msgstr "Sem progenitor para criar instância de filho."
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "This operation requires a single selected node."
@@ -7402,7 +7461,7 @@ msgstr "Vista normal"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Wireframe"
-msgstr "Vista wireframe"
+msgstr "Vista Wireframe"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Overdraw"
@@ -7954,7 +8013,7 @@ msgstr "TextureRegion"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
-msgstr "Adicionar todos os itens"
+msgstr "Adicionar Todos os Itens"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All"
@@ -7962,7 +8021,7 @@ msgstr "Adicionar tudo"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove All Items"
-msgstr "Remover todos os itens"
+msgstr "Remover Todos os Itens"
#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
msgid "Remove All"
@@ -7978,11 +8037,11 @@ msgstr "Menu edição de tema."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add Class Items"
-msgstr "Adicionar itens de classe"
+msgstr "Adicionar Itens de Classe"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove Class Items"
-msgstr "Remover itens de classe"
+msgstr "Remover Itens de Classe"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create Empty Template"
@@ -8372,7 +8431,7 @@ msgstr "Não selecionou uma textura para remover."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from scene? This will overwrite all current tiles."
-msgstr "Criar a partir de cena? Irá substituir todos os tiles atuais."
+msgstr "Criar a partir de cena? Irá sobrescrever todos os tiles atuais."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Merge from scene?"
@@ -8396,7 +8455,7 @@ msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Delete selected Rect."
-msgstr "Eliminar Rect seleccionado."
+msgstr "Eliminar Rect selecionado."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8549,10 +8608,6 @@ msgid "Error"
msgstr "Erro"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Nenhuma mensagem de gravação foi fornecida"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Nenhum ficheiro adicionado ao palco"
@@ -8609,10 +8664,6 @@ msgid "Stage All"
msgstr "Tudo no Palco"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Adicionar mensagem de gravação"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Gravar Alterações"
@@ -9130,8 +9181,8 @@ msgstr ""
"Função SmoothStep( escalar(limite0), escalar(limite1), escalar(x) ).\n"
"\n"
"Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que "
-"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 "
-"a usar polinomiais Hermite."
+"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 e 1.0 "
+"usando polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9348,8 +9399,8 @@ msgstr ""
"Função SmoothStep( vetor(limite0), vetor(limite1), vetor(x) ).\n"
"\n"
"Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que "
-"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 "
-"a usar polinomiais Hermite."
+"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 e 1.0 "
+"usando polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9362,8 +9413,8 @@ msgstr ""
"Função SmoothStep( escalar(limite0), escalar(limite1), vetor(x) ).\n"
"\n"
"Devolve 0.0 se 'x' for menor que 'limite0' e 1.0 se 'x' for maior que "
-"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 and 1.0 "
-"a usar polinomiais Hermite."
+"'limite1'. Caso contrário o valor devolvido é interpolado entre 0.0 e 1.0 "
+"usando polinomiais Hermite."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9430,7 +9481,7 @@ msgid ""
"direction of camera (pass associated inputs to it)."
msgstr ""
"Devolve queda baseada no produto escalar da normal à superfície e da direção "
-"da câmara (passa entradas associadas)."
+"da câmera (passa entradas associadas)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9813,7 +9864,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Não suportado pelos seus drivers GPU."
#: editor/project_manager.cpp
msgid ""
@@ -9992,6 +10043,11 @@ msgid "Projects"
msgstr "Projetos"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "A readquirir servidores, espere por favor..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Última modificação"
@@ -10362,6 +10418,11 @@ msgstr "Carregamento automático"
msgid "Plugins"
msgstr "Plugins"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Carregar Predefinição"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Predefinição..."
@@ -10452,7 +10513,7 @@ msgstr "Nome do nó"
#: editor/rename_dialog.cpp
msgid "Node's parent name, if available"
-msgstr "Nome do parente do nó, se disponível"
+msgstr "Nome do progenitor do nó, se disponível"
#: editor/rename_dialog.cpp
msgid "Node type"
@@ -10548,11 +10609,11 @@ msgstr "No carácter %s"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent Node"
-msgstr "Repôr Nó"
+msgstr "Reassociar Nó"
#: editor/reparent_dialog.cpp
msgid "Reparent Location (Select new Parent):"
-msgstr "Repôr localização (selecionar novo Parente):"
+msgstr "Reassociar Localização (Selecionar novo Progenitor):"
#: editor/reparent_dialog.cpp
msgid "Keep Global Transform"
@@ -10560,7 +10621,7 @@ msgstr "Manter transformação global"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent"
-msgstr "Repôr"
+msgstr "Reassociar"
#: editor/run_settings_dialog.cpp
msgid "Run Mode:"
@@ -10584,7 +10645,7 @@ msgstr "Configurações de Execução da Cena"
#: editor/scene_tree_dock.cpp
msgid "No parent to instance the scenes at."
-msgstr "Nenhum parente para instância das cenas."
+msgstr "Nenhum progenitor para instância das cenas."
#: editor/scene_tree_dock.cpp
msgid "Error loading scene from %s"
@@ -10611,6 +10672,16 @@ msgid "Instance Child Scene"
msgstr "Instanciar Cena Filha"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Não consigo operar em nós de uma cena externa!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Colar Nós"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Separar Script"
@@ -10620,11 +10691,11 @@ msgstr "Esta operação não pode ser feita na raiz da árvore."
#: editor/scene_tree_dock.cpp
msgid "Move Node In Parent"
-msgstr "Mover Nó no Parente"
+msgstr "Mover Nó no Progenitor"
#: editor/scene_tree_dock.cpp
msgid "Move Nodes In Parent"
-msgstr "Mover Nós no Parente"
+msgstr "Mover Nós no Progenitor"
#: editor/scene_tree_dock.cpp
msgid "Duplicate Node(s)"
@@ -10633,7 +10704,7 @@ msgstr "Duplicar Nó(s)"
#: editor/scene_tree_dock.cpp
msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
msgstr ""
-"Não consigo mudar nó em cenas herdadas, a ordem dos nós não pode mudar."
+"Não consigo reassociar nós em cenas herdadas, a ordem dos nós não pode mudar."
#: editor/scene_tree_dock.cpp
msgid "Node must belong to the edited scene to become root."
@@ -10737,6 +10808,11 @@ msgid "Attach Script"
msgstr "Anexar Script"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Cortar Nós"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Remover Nó(s)"
@@ -10804,7 +10880,7 @@ msgstr "Mudar tipo"
#: editor/scene_tree_dock.cpp
msgid "Reparent to New Node"
-msgstr "Repôr o Novo Nó"
+msgstr "Reassociar a Novo Nó"
#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
@@ -11028,7 +11104,7 @@ msgstr "Nome de classe inválido."
#: editor/script_create_dialog.cpp
msgid "Invalid inherited parent name or path."
-msgstr "Nome ou caminho de parente herdado inválido."
+msgstr "Nome ou caminho herdado do progenitor inválido."
#: editor/script_create_dialog.cpp
msgid "Script path/name is valid."
@@ -11152,11 +11228,11 @@ msgstr "Empilhar Frames"
#: editor/script_editor_debugger.cpp
msgid "Profiler"
-msgstr "Profiler"
+msgstr "Analisador"
#: editor/script_editor_debugger.cpp
msgid "Network Profiler"
-msgstr "Traçador de Rede"
+msgstr "Analisador de Rede"
#: editor/script_editor_debugger.cpp
msgid "Monitor"
@@ -11260,11 +11336,11 @@ msgstr "Mudar ângulo de emissão de AudioStreamPlayer3D"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Camera FOV"
-msgstr "Mudar FOV da câmara"
+msgstr "Mudar FOV da Câmera"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Camera Size"
-msgstr "Mudar tamanho da câmara"
+msgstr "Mudar tamanho da Câmera"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Notifier AABB"
@@ -11312,7 +11388,7 @@ msgstr "Mudar Raio do Cilindro"
#: modules/csg/csg_gizmos.cpp
msgid "Change Cylinder Height"
-msgstr "Mudar Altura do CIlindro"
+msgstr "Mudar Altura do Cilindro"
#: modules/csg/csg_gizmos.cpp
msgid "Change Torus Inner Radius"
@@ -11538,11 +11614,39 @@ msgstr "Distância de escolha:"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Filter meshes"
-msgstr "Meshes de filtro"
+msgstr "Filtrar malhas"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
-msgstr "Dá um recurso MeshLibrary a este GridMap para usar os seus meshes."
+msgstr "Dê um recurso MeshLibrary a este GridMap para usar as suas malhas."
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Começar Consolidação"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "A preparar estruturas de dados"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Gerar buffers"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Iluminação direta"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Iluminação indireta"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Pós-processamento"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "A Traçar lightmaps"
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
@@ -11558,7 +11662,7 @@ msgstr "Consolidar NavMesh"
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Clear the navigation mesh."
-msgstr "Limpar a Malha de navegação."
+msgstr "Limpar a malha de navegação."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Setting up Configuration..."
@@ -11582,7 +11686,7 @@ msgstr "A construir heightfield compacto..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Eroding walkable area..."
-msgstr "A corroer a Ãrea caminhável..."
+msgstr "A corroer a área caminhável..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Partitioning..."
@@ -11598,11 +11702,11 @@ msgstr "A criar polymesh..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Converting to native navigation mesh..."
-msgstr "A converter para Malha de navegação nativa..."
+msgstr "A converter para malha de navegação nativa..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Navigation Mesh Generator Setup:"
-msgstr "Configuração do gerador da Malha de navegação:"
+msgstr "Configuração do Gerador da Malha de Navegação:"
#: modules/recast/navigation_mesh_generator.cpp
msgid "Parsing Geometry..."
@@ -12058,17 +12162,21 @@ msgid "Select device from the list"
msgstr "Selecionar aparelho da lista"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "O executável ADB não está configurado nas Configurações do Editor."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Incapaz de localizar a ferramenta 'apksigner'."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "O jarsigner do OpenJDK não está configurado nas Definições do Editor."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Modelo de compilação Android não está instalado neste projeto. Instale-o no "
+"menu Projeto."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
msgstr ""
-"Depuração de keystore não configurada nas Configurações do Editor e nem na "
+"Keystore de depuração não configurada nas Configurações do Editor e nem na "
"predefinição."
#: platform/android/export/export.cpp
@@ -12077,28 +12185,35 @@ msgstr ""
"Lançamento de keystore configurado incorretamente na predefinição exportada."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"Compilação personalizada necessita de um caminho válido para Android SDK no "
-"Editor de Configurações."
+"É necessário um caminho válido para o Android SDK no Editor de Configurações."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Caminho inválido de Android SDK para compilação personalizada no Editor de "
-"Configurações."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Caminho inválido para o Android SDK no Editor de Configurações."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "Diretoria 'platform-tools' em falta!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "Incapaz de encontrar o comando adb das ferramentas Android SDK."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
msgstr ""
-"Modelo de compilação Android não está instalado neste projeto. Instale-o no "
-"menu Projeto."
+"Por favor confirme a pasta do Android SDK especificada no Editor de "
+"Configurações."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "Diretoria 'build-tools' em falta!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "Incapaz de encontrar o comando apksigner das ferramentas Android SDK."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12290,7 +12405,7 @@ msgstr "Cor de fundo inválida."
#: platform/uwp/export/export.cpp
msgid "Invalid Store Logo image dimensions (should be 50x50)."
-msgstr "Inválidas dimensões da imagem do logotipo do Store (deve ser 50x50)."
+msgstr "Dimensões inválidas da imagem do logotipo do Store (deve ser 50x50)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
@@ -12363,6 +12478,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Um CollisionPolygon2D vazio não tem efeito na colisão."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12399,23 +12522,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Nó A e Nó B têm de ser PhysicsBody2Ds"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Nó A tem de ser um PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Nó B tem de ser um PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Junção não está conectada a dois PhysicsBody2Ds"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Nó A e Nó B têm de ser PhysicsBody2Ds diferentes"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12512,7 +12635,7 @@ msgstr "Esta corrente de Bone2D deve terminar num nó Skeleton2D."
#: scene/2d/skeleton_2d.cpp
msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
-msgstr "Um Bone2D só funciona com um nó parente Skeleton2D ou Bone2D."
+msgstr "Um Bone2D só funciona com um nó progenitor Skeleton2D ou Bone2D."
#: scene/2d/skeleton_2d.cpp
msgid ""
@@ -12525,25 +12648,25 @@ msgid ""
"to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, "
"KinematicBody2D, etc. to give them a shape."
msgstr ""
-"TileMap com Usar Parente ativo precisa de um parente CollisionObject2D para "
-"lhe dar formas. Use-o como um filho de Area2D, StaticBody2D, RigidBody2D, "
-"KinematicBody2D, etc. para lhes dar uma forma."
+"TileMap com Usar Progenitor ativo precisa de um progenitor CollisionObject2D "
+"para lhe dar formas. Use-o como um filho de Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D, etc. para lhes dar uma forma."
#: scene/2d/visibility_notifier_2d.cpp
msgid ""
"VisibilityEnabler2D works best when used with the edited scene root directly "
"as parent."
msgstr ""
-"VisibilityEnabler2D funciona melhor quando usado diretamente como parente na "
-"cena raiz editada."
+"VisibilityEnabler2D funciona melhor quando usado diretamente como progenitor "
+"na cena raiz editada."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRCamera must have an ARVROrigin node as its parent."
-msgstr "ARVRCamera precisa de um nó ARVROrigin como parente."
+msgstr "ARVRCamera precisa de um nó ARVROrigin como progenitor."
#: scene/3d/arvr_nodes.cpp
msgid "ARVRController must have an ARVROrigin node as its parent."
-msgstr "ARVRController precisa de um nó ARVROrigin como parente."
+msgstr "ARVRController precisa de um nó ARVROrigin como progenitor."
#: scene/3d/arvr_nodes.cpp
msgid ""
@@ -12555,7 +12678,7 @@ msgstr ""
#: scene/3d/arvr_nodes.cpp
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr "ARVRAnchor precisa de um nó ARVROrigin como parente."
+msgstr "ARVRAnchor precisa de um nó ARVROrigin como progenitor."
#: scene/3d/arvr_nodes.cpp
msgid ""
@@ -12570,28 +12693,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin exige um nó filho ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "A procurar malhas e luzes"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Tempo restante: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "A preparar geometria (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "A traçar Meshes: "
+msgid "Preparing environment"
+msgstr "A preparar ambiente"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "A traçar Luzes:"
+msgid "Generating capture"
+msgstr "A gerar captura"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "A concluir desenho"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "A guardar lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "A iluminar Meshes: "
+msgid "Done"
+msgstr "Feito"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12650,7 +12773,7 @@ msgstr "ConcavePolygonShape apenas suporta RigidBody no modo estático."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
-msgstr "Nada é visível porque nenhuma Malha foi atribuída."
+msgstr "Nada é visível porque nenhuma malha foi atribuída."
#: scene/3d/cpu_particles.cpp
msgid ""
@@ -12662,7 +12785,11 @@ msgstr ""
#: scene/3d/gi_probe.cpp
msgid "Plotting Meshes"
-msgstr "A desenhar Meshes"
+msgstr "A Traçar Malhas"
+
+#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "A concluir desenho"
#: scene/3d/gi_probe.cpp
msgid ""
@@ -12672,11 +12799,6 @@ msgstr ""
"Sondas GI não são suportadas pelo driver vídeo GLES2.\n"
"Em vez disso, use um BakedLightmap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "A InterpolatedCamerda foi deprecada e será removida no Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "Uma SpotLight com ângulo superior a 90 graus não cria sombras."
@@ -12709,7 +12831,7 @@ msgstr ""
msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
-"Nada é visível porque não foram atribuídas Meshes aos passos de desenho."
+"Nada é visível porque não foram atribuídas malhas aos passos de desenho."
#: scene/3d/particles.cpp
msgid ""
@@ -12729,7 +12851,7 @@ msgid ""
"parent Path's Curve resource."
msgstr ""
"ROTATION_ORIENTED de PathFollow requer \"Up Vector\" ativado no recurso de "
-"Curva do Caminho do seu pai."
+"Curva do Caminho do seu progenitor."
#: scene/3d/physics_body.cpp
msgid ""
@@ -12743,23 +12865,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Nó A e Nó B têm de ser PhysicsBodies"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Nó A tem de ser um PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Nó B tem de ser um PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Junção não está conectada a quaisquer PhysicsBodies"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Nó A e Nó B têm de ser PhysicsBodies diferentes"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12819,7 +12941,7 @@ msgid ""
"This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set "
"this environment's Background Mode to Canvas (for 2D scenes)."
msgstr ""
-"Este WorldEnvironment Ä— ignorado. Pode adicionar uma Camera (para cenas 3D) "
+"Este WorldEnvironment é ignorado. Pode adicionar uma Câmera (para cenas 3D) "
"ou definir o Modo Background deste ambiente como Canvas (para cenas 2D)."
#: scene/animation/animation_blend_tree.cpp
@@ -12921,6 +13043,14 @@ msgstr "Alerta!"
msgid "Please Confirm..."
msgstr "Confirme por favor..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Deve usar uma extensão válida."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Ativar grelha do minimapa."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12974,6 +13104,14 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "O tamanho do viewport tem de ser maior do que 0 para renderizar."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"A porta coletora está conectada mas não é usada. Considere mudar a origem "
+"para 'SamplerPort'."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fonte inválida para pré-visualização."
@@ -13001,14 +13139,51 @@ msgstr "Variações só podem ser atribuídas na função vértice."
msgid "Constants cannot be modified."
msgstr "Constantes não podem ser modificadas."
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "Já existe um ficheiro ou pasta com o mesmo nome nesta localização."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "InterpolatedCamerda foi descontinuada e será removida no Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "Não"
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "Diretoria 'build-tools' em falta!"
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Esta cena nunca foi guardada. Guardar antes de executar?"
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "Incapaz de localizar a ferramenta zipalign."
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "O executável ADB não está configurado nas Configurações do Editor."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr ""
+#~ "O jarsigner do OpenJDK não está configurado nas Definições do Editor."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Compilação personalizada necessita de um caminho válido para Android SDK "
+#~ "no Editor de Configurações."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Tempo restante: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "A traçar Meshes: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "A iluminar Meshes: "
+
+#~ msgid "Search complete"
+#~ msgstr "Pesquisa completa"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Nenhuma mensagem de gravação foi fornecida"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Adicionar mensagem de gravação"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "Já existe um ficheiro ou pasta com o mesmo nome nesta localização."
#~ msgid "Aligning APK..."
#~ msgstr "A alinhar APK..."
@@ -13352,9 +13527,6 @@ msgstr "Constantes não podem ser modificadas."
#~ msgid "Failed to save solution."
#~ msgstr "Falha ao guardar solução."
-#~ msgid "Done"
-#~ msgstr "Feito"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Falha ao criar projeto C#."
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 90d332c743..4270648266 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -1,6 +1,6 @@
# Portuguese (Brazil) translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Allyson Souza <allyson_as@outlook.com>, 2017.
# Anderson Araujo <anderson.araujoprog@gmail.com>, 2018.
@@ -104,12 +104,20 @@
# NogardRyuu <nogardryuu@gmail.com>, 2020.
# Elton <eltondeoliveira@outlook.com>, 2020.
# ThiagoCTN <thiagocampostn@gmail.com>, 2020.
+# Alec Santos <alecsantos96@gmail.com>, 2020.
+# Augusto Milão <augusto.milao01@gmail.com>, 2021.
+# Gabriel Gavazzi Felix <mutcholoko32@gmail.com>, 2021.
+# Lucas Dantas <lucas.lucantas38@gmail.com>, 2021.
+# Carlos Bonifacio <carlosboni.sa@gmail.com>, 2021.
+# Lucas Castro <castroclucas@gmail.com>, 2021.
+# Ricardo Zamarrenho Carvalho Correa <ricardozcc17@gmail.com>, 2021.
+# Diego dos Reis Macedo <diego_dragon97@hotmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2020-12-07 08:11+0000\n"
-"Last-Translator: ThiagoCTN <thiagocampostn@gmail.com>\n"
+"PO-Revision-Date: 2021-02-15 10:51+0000\n"
+"Last-Translator: Carlos Bonifacio <carlosboni.sa@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -117,7 +125,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -745,7 +753,7 @@ msgstr "Selecionar Trilhas para Copiar"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Copiar"
@@ -1854,7 +1862,7 @@ msgstr "Novo"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
msgid "Import"
-msgstr "Import"
+msgstr "Importar"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
@@ -1951,8 +1959,8 @@ msgid "Open a File or Directory"
msgstr "Abrir Arquivo ou Diretório"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Salvar"
@@ -2043,10 +2051,6 @@ msgstr "Previsualização:"
msgid "File:"
msgstr "Arquivo:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Deve usar uma extensão válida."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "BuscarFontes"
@@ -2483,6 +2487,10 @@ msgid "There is no defined scene to run."
msgstr "Não há cena definida para rodar."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Salvar a cena antes de executar..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Não se pôde iniciar sub-processo!"
@@ -2526,18 +2534,6 @@ msgstr "Um nó raiz é requerido para salvar a cena."
msgid "Save Scene As..."
msgstr "Salvar Cena Como..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Não"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Sim"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Esta cena nunca foi salva. Salvar antes de rodar?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Essa operação não pode ser realizada sem uma cena."
@@ -2587,6 +2583,10 @@ msgid "Quit"
msgstr "Sair"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Sim"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Sair do editor?"
@@ -2635,7 +2635,8 @@ msgstr ""
"falhou."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"Não foi possível encontrar o campo de script para o plugin em: 'res://addons/"
"%s'."
@@ -3070,14 +3071,6 @@ msgid "Help"
msgstr "Ajuda"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Pesquisar"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentação Online"
@@ -3243,6 +3236,25 @@ msgid "Open & Run a Script"
msgstr "Abrir e Rodar um Script"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Os seguintes arquivos são mais recentes no disco.\n"
+"Que ação deve ser tomada?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Recarregar"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Salve novamente"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Novo Herdado"
@@ -3454,7 +3466,7 @@ msgstr "Tornar Único"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Colar"
@@ -3818,6 +3830,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Os seguintes arquivos ou pastas entram em conflito com os itens do local "
+"'%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Deseja sobreescrever?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -4010,8 +4028,16 @@ msgid "Searching..."
msgstr "Procurando..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Pesquisa concluída"
+msgid "%d match in %d file."
+msgstr "%d correspondência em %d arquivo."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d correspondências em %d arquivo."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d correspondências em %d arquivos."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4147,6 +4173,21 @@ msgstr "Você retornou um objeto derivado de Nó no método `post_import()`?"
msgid "Saving..."
msgstr "Salvando..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Modo de Seleção"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importar"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Usar sRGB Padrão"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Arquivos"
@@ -5119,7 +5160,8 @@ msgid "Got:"
msgstr "Obtido:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Falha na verificação da hash sha256"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5223,7 +5265,6 @@ msgid "Sort:"
msgstr "Ordenar:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Categoria:"
@@ -5254,12 +5295,10 @@ msgstr "Arquivo ZIP de Assets"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Não foi possível determinar um caminho para salvar as imagens do lightmap.\n"
-"Salve sua cena (para que as imagens sejam salvas no mesmo diretório), ou "
-"escolha um caminho nas propriedades do BakedLightmap."
+"Salve sua cena e tente novamente."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5276,8 +5315,33 @@ msgstr ""
"permissões de escrita."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Falha ao determinar o tamanho do lightmap. Tamanho máximo do lightmap é "
+"muito baixo?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Alguma malha é inválida. Certifique-se de que os valores do canal UV2 estão "
+"contidos na região quadrada [0.0,1.0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"O editor Godot foi construído sem suporte à ray tracing, os lightmaps não "
+"podem ser bakeados."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
-msgstr "Preparar Lightmaps"
+msgstr "Bake Lightmaps"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Selecione o arquivo de lightmap bake:"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6373,6 +6437,10 @@ msgstr ""
"Só é permitido colocar um ponto em um material processador ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Converter para CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Gerando Tempo (seg):"
@@ -6433,10 +6501,6 @@ msgstr "Gerando AABB"
msgid "Generate Visibility AABB"
msgstr "Gerar AABB de Visibilidade"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Gerar AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Remover Ponto da Curva"
@@ -7028,6 +7092,14 @@ msgstr "Fechar Docs"
msgid "Run"
msgstr "Rodar"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Pesquisar"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Passo para dentro"
@@ -7081,16 +7153,6 @@ msgstr ""
"Os seguintes arquivos são mais recentes no disco.\n"
"Que ação deve ser tomada?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Recarregar"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Salve novamente"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Depurador"
@@ -7184,8 +7246,8 @@ msgstr "Breakpoints"
msgid "Go To"
msgstr "Ir Para"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Recortar"
@@ -7408,6 +7470,11 @@ msgid "Yaw"
msgstr "Guinada"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Tamanho: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Objetos Desenhados"
@@ -8652,10 +8719,6 @@ msgid "Error"
msgstr "Erro"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Nenhuma mensagem de confirmação foi fornecida"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Nenhum arquivo em espera"
@@ -8712,10 +8775,6 @@ msgid "Stage All"
msgstr "Salvar Tudo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Adicione uma mensagem ao commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Confirmar Mudanças"
@@ -8834,9 +8893,8 @@ msgid "Visual Shader Input Type Changed"
msgstr "Tipo de Entrada de Shader Visual Alterado"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "UniformRef Name Changed"
-msgstr "Definir Nome Uniforme"
+msgstr "UniformRef Name foi altearado"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
@@ -9551,7 +9609,6 @@ msgstr ""
"uniformes e constantes."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "A reference to an existing uniform."
msgstr "Uma referência a um uniforme existente."
@@ -9921,7 +9978,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Não suportado pelos seus drivers de GPU."
#: editor/project_manager.cpp
msgid ""
@@ -10101,6 +10158,11 @@ msgid "Projects"
msgstr "Projetos"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Reconectando, por favor aguarde."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Ultima Modificação"
@@ -10471,6 +10533,11 @@ msgstr "O AutoLoad"
msgid "Plugins"
msgstr "Plugins"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Carregar Padrão"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Predefinição..."
@@ -10720,6 +10787,16 @@ msgid "Instance Child Scene"
msgstr "Instânciar Cena Filha"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Não é possível operar em nós de uma cena externa!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Colar Nodes"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Remover Script"
@@ -10846,6 +10923,11 @@ msgid "Attach Script"
msgstr "Adicionar Script"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Recortar Nós"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Remover Nó(s)"
@@ -11653,6 +11735,36 @@ msgstr "Filtrar malhas"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "Atribua um recurso MeshLibrary a este GridMap para usar seus meshes."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Iniciar pré-cálculo"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Preparando estruturas de dados"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Gerar buffers"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Direct lightning"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Iluminação indireta"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Pós-processamento"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Traçando mapas de luz"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Nome da classe não pode ser uma palavra reservada"
@@ -12169,12 +12281,16 @@ msgid "Select device from the list"
msgstr "Selecione um dispositivo da lista"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Executável ADB não configurado nas opções do Editor."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Não foi possível encontrar a ferramenta 'apksigner'."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner não configurado nas opções do Editor."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"O modelo de compilação do Android não foi instalado no projeto. Instale "
+"através do menu Projeto."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12189,28 +12305,37 @@ msgstr ""
"exportação."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "Um caminho Android SDK é necessário nas Configurações do Editor."
+
+#: platform/android/export/export.cpp
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Caminho do Android SDK está inválido para Configurações do Editor."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'platform-tools' directory!"
+msgstr "Diretório 'ferramentas-da-plataforma' ausente!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK platform-tools' adb command."
msgstr ""
-"Build personalizada precisa de um caminho Android SDK válido em "
-"Configurações do Editor."
+"Não foi possível encontrar o comando adb nas ferramentas do Android SDK."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Please check in the Android SDK directory specified in Editor Settings."
msgstr ""
-"Caminho do Android SDK inválido para o build personalizado em Configurações "
+"Por favor, verifique o caminho do Android SDK especificado nas Configurações "
"do Editor."
#: platform/android/export/export.cpp
-msgid "Missing 'platform-tools' directory!"
-msgstr ""
+msgid "Missing 'build-tools' directory!"
+msgstr "Diretório 'ferramentas-da-plataforma' está faltando !"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
-"O modelo de compilação do Android não foi instalado no projeto. Instale "
-"através do menu Projeto."
+"Não foi possível encontrar o comando apksigner nas ferramentas de build do "
+"Android SDK."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12225,13 +12350,14 @@ msgid ""
"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" "
"project setting (changed in Godot 3.2.2).\n"
msgstr ""
-"Módulo inválido \"GodotPaymentV3\" incluido na configuração de projeto "
-"\"android/modules\" (changed in Godot 3.2.2).\n"
+"Módulo \"GodotPaymentV3\" inválido incluido na configuração de projeto "
+"\"android/modules\" (alterado em Godot 3.2.2).\n"
#: platform/android/export/export.cpp
msgid "\"Use Custom Build\" must be enabled to use the plugins."
msgstr ""
-"\"Use Custom Build\" precisa estar ativo para ser possível utilizar plugins."
+"\"Usar Compilação Customizada\" precisa estar ativo para ser possível "
+"utilizar plugins."
#: platform/android/export/export.cpp
msgid ""
@@ -12257,18 +12383,20 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
msgstr ""
+"\"Exportar AAB\" só é válido quando \"Usar Compilação Customizada\" está "
+"habilitado."
#: platform/android/export/export.cpp
msgid "Invalid filename! Android App Bundle requires the *.aab extension."
-msgstr ""
+msgstr "Nome de arquivo invalido! Android App Bunlde requer a extensão *.aab."
#: platform/android/export/export.cpp
msgid "APK Expansion not compatible with Android App Bundle."
-msgstr ""
+msgstr "A expansão APK não é compatível com o Android App Bundle."
#: platform/android/export/export.cpp
msgid "Invalid filename! Android APK requires the *.apk extension."
-msgstr ""
+msgstr "Nome de arquivo inválido! Android APK requer a extensão *.apk."
#: platform/android/export/export.cpp
msgid ""
@@ -12306,13 +12434,15 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Moving output"
-msgstr ""
+msgstr "Movendo saída"
#: platform/android/export/export.cpp
msgid ""
"Unable to copy and rename export file, check gradle project directory for "
"outputs."
msgstr ""
+"Não foi possível copiar e renomear o arquivo de exportação, verifique o "
+"diretório do projeto gradle por saídas."
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
@@ -12465,6 +12595,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Um nó CollisionPolygon2D vazio não é efetivo para colisão."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12501,23 +12639,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "O Nó A e o Nó B devem ser PhysicsBody2Ds"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "O Nó A deve ser um PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "O Nó A deve ser um PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "A Junta não está conectada a dois PhysicsBody2Ds"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "O Nó A e o Nó B devem ser diferentes PhysicsBody2Ds"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12674,28 +12812,30 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin necessita um nó ARVRCamera como filho."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Encontrando malhas e luzes"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Tempo Restante: %d:%02d s)"
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "Analisando Geometria..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Planejando Malhas: "
+msgid "Preparing environment"
+msgstr "Preparando ambiente"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Planejando Luzes:"
+msgid "Generating capture"
+msgstr "Gerando captura"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Terminando de Plotar"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Salvando mapas de luz"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Iluminando Malhas: "
+msgid "Done"
+msgstr "Pronto"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12771,6 +12911,10 @@ msgid "Plotting Meshes"
msgstr "Planejando Malhas"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Terminando de Plotar"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12778,11 +12922,6 @@ msgstr ""
"GIProbes não são suportados pelo driver de vídeo GLES2.\n"
"Use um BakedLightmap em vez disso."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "IntepolatedCamera foi depreciada e será removida no Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "Um SpotLight com um ângulo maior que 90 graus não pode criar sombras."
@@ -12849,23 +12988,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Nó A e Nó B devem ser PhysicsBodys"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Nó A deve ser PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Nó B deve ser um PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "A junta não está conectada a nenhum PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Nó A e Nó B devem ser diferente PhysicsBodies"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -13028,6 +13167,14 @@ msgstr "Alerta!"
msgid "Please Confirm..."
msgstr "Confirme Por Favor..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Deve usar uma extensão válida."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Ativar minimapa de grade."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13083,6 +13230,14 @@ msgstr ""
"O tamanho da Viewport deve ser maior do que 0 para renderizar qualquer coisa."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"A porta sampler está conectada mas não está sendo usada. Considere alterar a "
+"fonte para 'SamplerPort'."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Fonte inválida para a prévia."
@@ -13110,6 +13265,48 @@ msgstr "Variáveis só podem ser atribuídas na função de vértice."
msgid "Constants cannot be modified."
msgstr "Constantes não podem serem modificadas."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "IntepolatedCamera foi depreciada e será removida no Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "Não"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Esta cena nunca foi salva. Salvar antes de rodar?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "Executável ADB não configurado nas opções do Editor."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner não configurado nas opções do Editor."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Build personalizada precisa de um caminho Android SDK válido em "
+#~ "Configurações do Editor."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Tempo Restante: %d:%02d s)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Planejando Malhas: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Iluminando Malhas: "
+
+#~ msgid "Search complete"
+#~ msgstr "Pesquisa concluída"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Nenhuma mensagem de confirmação foi fornecida"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Adicione uma mensagem ao commit"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Já há uma pasta ou arquivo neste caminho com o nome especificado."
@@ -13444,9 +13641,6 @@ msgstr "Constantes não podem serem modificadas."
#~ msgid "Failed to save solution."
#~ msgstr "Falha ao salvar solução."
-#~ msgid "Done"
-#~ msgstr "Pronto"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Falha ao criar projeto C#."
@@ -14734,9 +14928,6 @@ msgstr "Constantes não podem serem modificadas."
#~ msgid "Use Default Light"
#~ msgstr "Usar Luz Padrão"
-#~ msgid "Use Default sRGB"
-#~ msgstr "Usar sRGB Padrão"
-
#~ msgid "Default Light Normal:"
#~ msgstr "Luz Normal Padrão:"
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index 95bca8b085..33f5264d71 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -1,6 +1,6 @@
# Romanian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Calin Sopterean <csopterean@gmail.com>, 2018.
# Filip <filipanton@tutanota.com>, 2018, 2020.
@@ -661,7 +661,7 @@ msgstr "Selectează Pistele de Copiat"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Copiază"
@@ -1874,8 +1874,8 @@ msgid "Open a File or Directory"
msgstr "Deschideți un Fişier sau Director"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Salvați"
@@ -1966,10 +1966,6 @@ msgstr "Previzualizați:"
msgid "File:"
msgstr "Fișier:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Trebuie să utilizaţi o extensie valida."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "SurseScan"
@@ -2404,6 +2400,10 @@ msgid "There is no defined scene to run."
msgstr "Nu există nici o scenă definită pentru a execuție."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Nu s-a putut porni subprocesul!"
@@ -2447,18 +2447,6 @@ msgstr "Un nod rădăcină este necesar pentru a salva scena."
msgid "Save Scene As..."
msgstr "Salvează scena ca..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nu"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Da"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Această scenă nu a fost salvată niciodata. Salvați înainte de rulare?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Această operație nu se poate face fără o scenă."
@@ -2508,6 +2496,10 @@ msgid "Quit"
msgstr "ÃŽnchide"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Da"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Ieși din editor?"
@@ -2556,7 +2548,8 @@ msgstr ""
"Nu se poate inițializa plugin-ul la: '%s' analizarea configurației a eșuat."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"Nu a putut fi găsit câmpul scriptului pentru plugin la: 'res://addons/%s'."
@@ -2993,14 +2986,6 @@ msgid "Help"
msgstr "Ajutor"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Căutare"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Documentație Online"
@@ -3156,6 +3141,23 @@ msgid "Open & Run a Script"
msgstr "Deschide și Execută un Script"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr "Următoarele file au eșuat extragerea din pachet:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Derivare Nouă"
@@ -3358,7 +3360,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3906,8 +3908,19 @@ msgid "Searching..."
msgstr "Caut..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Căutare completă"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d potriviri."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d potriviri."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d potriviri."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4043,6 +4056,21 @@ msgstr ""
msgid "Saving..."
msgstr "Se Salvează..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Selectare mod"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importare"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Încărcați Implicit"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Fișiere"
@@ -5030,7 +5058,8 @@ msgid "Got:"
msgstr "Primit:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Verificare hash sha256 eșuată"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5139,7 +5168,6 @@ msgid "Sort:"
msgstr "Sorare:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Categorie:"
@@ -5168,10 +5196,10 @@ msgid "Assets ZIP File"
msgstr "Fișier ZIP cu Asset-uri"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Nu se poate determina p cale de salvare pentru imaginile lightmap.\n"
"Salvează scena (imaginile vor fi salvate în acelasi director), sau alege o "
@@ -5192,9 +5220,29 @@ msgstr ""
"ele."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Procesează Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Selectare fișier șablon"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6327,6 +6375,11 @@ msgstr ""
"ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Conversie în Mesh2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Timp de Generare (sec):"
@@ -6390,10 +6443,6 @@ msgstr "Generare AABB"
msgid "Generate Visibility AABB"
msgstr "Generare Vizibilitate AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Generare AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Ștergere Punt din Curbă"
@@ -7007,6 +7056,14 @@ msgstr ""
msgid "Run"
msgstr "Execută"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Căutare"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7059,16 +7116,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7169,8 +7216,8 @@ msgstr "Șterge puncte"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7403,6 +7450,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8694,11 +8745,6 @@ msgid "Error"
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
msgid "No files added to stage"
msgstr ""
@@ -8763,10 +8809,6 @@ msgid "Stage All"
msgstr "Înlocuiți Tot"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Sincronizează Modificările Scriptului"
@@ -10050,6 +10092,11 @@ msgid "Projects"
msgstr "Proiect"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Se recuperează oglinzile, te rog așteaptă..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10418,6 +10465,11 @@ msgstr ""
msgid "Plugins"
msgstr "Plugin-uri"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Încărcați Implicit"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Presetare..."
@@ -10667,6 +10719,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Lipește Postura"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Curăță Scriptul"
@@ -10796,6 +10857,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Creează Nod"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11613,6 +11679,38 @@ msgstr "Filtru meshuri"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "Generare AABB"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Direcții"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Setare expresie"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Se Genereaza Lightmaps"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12125,11 +12223,13 @@ msgid "Select device from the list"
msgstr "Selectează un dispozitiv din listă"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12141,11 +12241,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12153,9 +12253,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12386,6 +12496,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12552,28 +12670,33 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr ""
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "Analiza geometriei..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr ""
+#, fuzzy
+msgid "Preparing environment"
+msgstr "Analiza geometriei..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "Se Genereaza Lightmaps"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Se Genereaza Lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr ""
+#, fuzzy
+msgid "Done"
+msgstr "Efectuat!"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12632,14 +12755,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12848,6 +12970,15 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Trebuie să utilizaţi o extensie valida."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "Activează aliniere"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12889,6 +13020,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
@@ -12916,6 +13053,20 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No"
+#~ msgstr "Nu"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr ""
+#~ "Această scenă nu a fost salvată niciodata. Salvați înainte de rulare?"
+
+#~ msgid "Search complete"
+#~ msgstr "Căutare completă"
+
+#, fuzzy
+#~ msgid "No commit message was provided"
+#~ msgstr "Niciun nume furnizat"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr ""
#~ "Există deja un fișier sau un dosar cu același nume în această locație."
@@ -13157,10 +13308,6 @@ msgstr ""
#~ msgstr "Creează un Corp Static Convex"
#, fuzzy
-#~ msgid "Custom Node"
-#~ msgstr "Creează Nod"
-
-#, fuzzy
#~ msgid "Snap (s): "
#~ msgstr "Pas (s):"
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 7a6d423212..eec73e585a 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -1,6 +1,6 @@
# Russian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Ðркадий ÐÐ²Ð°Ñ <savvot@gmail.com>, 2018.
# Artem Varaksa <aymfst@gmail.com>, 2018.
@@ -56,7 +56,7 @@
# КонÑтантин Рин <email.to.rean@gmail.com>, 2019, 2020.
# Maxim Samburskiy <alpacones@outlook.com>, 2019.
# Dima Koshel <form.eater@gmail.com>, 2019.
-# Danil Alexeev <danil@alexeev.xyz>, 2019, 2020.
+# Danil Alexeev <danil@alexeev.xyz>, 2019, 2020, 2021.
# Ravager <al.porkhunov@gmail.com>, 2019.
# ÐлекÑандр <akonn7@mail.ru>, 2019.
# Rei <clxgamer12@gmail.com>, 2019.
@@ -89,11 +89,14 @@
# Nikita Epifanov <nikgreens@protonmail.com>, 2020.
# Cube Show <griiv.06@gmail.com>, 2020.
# Roman Tolkachyov <roman@tolkachyov.name>, 2020.
+# Igor Grachev <igorecha.9999@gmail.com>, 2020.
+# Dmytro Meleshko <dmytro.meleshko@gmail.com>, 2021.
+# narrnika <narr13niki@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-01 20:29+0000\n"
+"PO-Revision-Date: 2021-02-27 00:47+0000\n"
"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
@@ -103,7 +106,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -731,7 +734,7 @@ msgstr "Выбрать треки Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Копировать"
@@ -1117,8 +1120,8 @@ msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
msgstr ""
-"Удалить выбранные файлы из проекта? (ÐÐµÐ»ÑŒÐ·Ñ Ð²Ð¾ÑÑтановить)\n"
-"Ð’Ñ‹ можете найти удалённые файлы в Корзине, чтобы воÑÑтановить их."
+"Удалить выбранные файлы из проекта? (ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ)\n"
+"Ð’Ñ‹ можете найти удалённые файлы в корзине, чтобы воÑÑтановить их."
#: editor/dependency_editor.cpp
msgid ""
@@ -1128,8 +1131,8 @@ msgid ""
"You can find the removed files in the system trash to restore them."
msgstr ""
"УдалÑемые файлы требуютÑÑ Ð´Ð»Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð¹ работы других реÑурÑов.\n"
-"Ð’ÑÑ‘ равно удалить их? (ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!)\n"
-"Ð’Ñ‹ можете найти удалённые файлы в Корзине, чтобы воÑÑтановить их."
+"Ð’ÑÑ‘ равно удалить их? (ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ)\n"
+"Ð’Ñ‹ можете найти удалённые файлы в корзине, чтобы воÑÑтановить их."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1936,8 +1939,8 @@ msgid "Open a File or Directory"
msgstr "Открыть каталог или файл"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Сохранить"
@@ -2028,10 +2031,6 @@ msgstr "ПредпроÑмотр:"
msgid "File:"
msgstr "Файл:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Ðужно иÑпользовать доÑтупное раÑширение."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Сканировать иÑходники"
@@ -2469,6 +2468,10 @@ msgid "There is no defined scene to run."
msgstr "Ðет открытой Ñцены Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Сохранение Ñцены перед запуÑком..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Ðе удаётÑÑ Ð·Ð°Ð¿ÑƒÑтить подпроцеÑÑ!"
@@ -2512,18 +2515,6 @@ msgstr "Ð”Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñцены требуетÑÑ ÐºÐ¾Ñ€Ð½ÐµÐ²Ð¾
msgid "Save Scene As..."
msgstr "Сохранить Ñцену как..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Ðет"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Да"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Эта Ñцена никогда не была Ñохранена. Сохранить перед запуÑком?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Эта Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ðµ может быть выполнена без Ñцены."
@@ -2573,6 +2564,10 @@ msgid "Quit"
msgstr "Выход"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Да"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Выйти из редактора?"
@@ -2620,8 +2615,8 @@ msgstr ""
"конфигурации."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr "Ðе удаётÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ поле script Ð´Ð»Ñ Ð¿Ð»Ð°Ð³Ð¸Ð½Ð°: «res://addons/%s»."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "Ðе удаётÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ поле script Ð´Ð»Ñ Ð¿Ð»Ð°Ð³Ð¸Ð½Ð°: «%s»."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2671,7 +2666,7 @@ msgstr "Сцена «%s» имеет иÑпорченные завиÑимоÑÑ‚
#: editor/editor_node.cpp
msgid "Clear Recent Scenes"
-msgstr "ОчиÑтить поÑледние Ñцены"
+msgstr "ОчиÑтить недавние Ñцены"
#: editor/editor_node.cpp
msgid ""
@@ -2817,7 +2812,7 @@ msgstr "Открыть Ñцену..."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Open Recent"
-msgstr "Открыть поÑледнее"
+msgstr "Открыть недавнее"
#: editor/editor_node.cpp
msgid "Save Scene"
@@ -3051,14 +3046,6 @@ msgid "Help"
msgstr "Справка"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "ПоиÑк"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Онлайн документациÑ"
@@ -3113,7 +3100,7 @@ msgstr "ЗапуÑтить Ñцену"
#: editor/editor_node.cpp
msgid "Play custom scene"
-msgstr "ЗапуÑтить выборочную Ñцену"
+msgstr "ЗапуÑтить произвольную Ñцену"
#: editor/editor_node.cpp
msgid "Play Custom Scene"
@@ -3225,6 +3212,24 @@ msgid "Open & Run a Script"
msgstr "Открыть и запуÑтить Ñкрипт"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Следующие файлы изменены на диÑке.\n"
+"Какое дейÑтвие Ñледует выполнить?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Перезагрузить"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "ПереÑохранить"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "ÐÐ¾Ð²Ð°Ñ ÑƒÐ½Ð°ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñцена"
@@ -3435,7 +3440,7 @@ msgstr "Сделать уникальным"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Ð’Ñтавить"
@@ -3559,7 +3564,7 @@ msgstr "(Текущий)"
#: editor/export_template_manager.cpp
msgid "Retrieving mirrors, please wait..."
-msgstr "Получение зеркал, пожалуйÑта подождите..."
+msgstr "Получение зеркал, пожалуйÑта, подождите..."
#: editor/export_template_manager.cpp
msgid "Remove template version '%s'?"
@@ -3795,6 +3800,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Обнаружен конфликт Ñледующих файлов (или папок) Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°Ð¼Ð¸ находÑщимиÑÑ Ð² "
+"целевой директории '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Ð’Ñ‹ хотите их перезапиÑать?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3876,7 +3887,7 @@ msgstr "Дублировать..."
#: editor/filesystem_dock.cpp
msgid "Move to Trash"
-msgstr "Удалить в Корзину"
+msgstr "Удалить в корзину"
#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Rename..."
@@ -3980,15 +3991,23 @@ msgstr "Заменить: "
#: editor/find_in_files.cpp
msgid "Replace all (no undo)"
-msgstr "Заменить вÑÑ‘ (без возможноÑти отмены)"
+msgstr "Заменить вÑÑ‘ (Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ)"
#: editor/find_in_files.cpp
msgid "Searching..."
msgstr "ПоиÑк..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "ПоиÑк завершен"
+msgid "%d match in %d file."
+msgstr "%d Ñовпадение в %d файле."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d ÑовпадениÑ(ий) в %d файле."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d ÑовпадениÑ(ий) в %d файле(ах)."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4124,6 +4143,21 @@ msgstr "Ð’Ñ‹ вернули производный от Node объект в мÐ
msgid "Saving..."
msgstr "Сохранение..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Режим выделениÑ"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Импорт"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "ИÑпользовать sRGB"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d файлов"
@@ -4226,7 +4260,7 @@ msgstr "Перейти к Ñледующему редактируемому об
#: editor/inspector_dock.cpp
msgid "History of recently edited objects."
-msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¿Ð¾Ñледних отредактированных объектов."
+msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð½ÐµÐ´Ð°Ð²Ð½Ð¾ отредактированных объектов."
#: editor/inspector_dock.cpp
msgid "Object properties."
@@ -5080,7 +5114,7 @@ msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
-msgstr "ÐеÑовпадение Ñ…Ñша загрузки, возможно файл был изменён."
+msgstr "ÐеÑовпадение хеша загрузки, возможно файл был изменён."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Expected:"
@@ -5091,8 +5125,8 @@ msgid "Got:"
msgstr "Получено:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Ðе удалоÑÑŒ проверить sha256 Ñ…Ñш"
+msgid "Failed SHA-256 hash check"
+msgstr "Ðе удалоÑÑŒ проверить хеш SHA-256"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5195,7 +5229,6 @@ msgid "Sort:"
msgstr "Сортировка:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "КатегориÑ:"
@@ -5226,12 +5259,10 @@ msgstr "ZIP файл аÑÑетов"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"Ðе удаетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ путь Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ lightmap.\n"
-"Сохраните ваши Ñцены (чтобы Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð¸ Ñохранены в том же разделе), "
-"или выберите путь ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð² ÑвойÑтвах BakedLightmap."
+"Ðе удалоÑÑŒ определить путь Ð´Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ карты оÑвещениÑ.\n"
+"Сохраните Ñцену и попробуйте ещё раз."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5247,9 +5278,34 @@ msgstr ""
"Сбой ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ оÑвещенноÑти, убедитеÑÑŒ, что путь доÑтупен Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Ðе удалоÑÑŒ определить размер карты оÑвещениÑ. МакÑимальный размер карты "
+"оÑÐ²ÐµÑ‰ÐµÐ½Ð¸Ñ Ñлишком мал?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"ÐÐµÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñетка некорректна. УбедитеÑÑŒ, что Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð° UV2 "
+"находÑÑ‚ÑÑ Ð² квадратной облаÑти [0.0,1.0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Редактор Godot был Ñобран без поддержки траÑÑировки лучей, карты оÑÐ²ÐµÑ‰ÐµÐ½Ð¸Ñ "
+"невозможно запечь."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Запекать карты оÑвещениÑ"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Выберите файл Ð·Ð°Ð¿ÐµÐºÐ°Ð½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ оÑвещениÑ:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5696,7 +5752,7 @@ msgstr "ОчиÑтить пользовательÑкие коÑти"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View"
-msgstr "Обзор"
+msgstr "Вид"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Always Show Grid"
@@ -5736,7 +5792,7 @@ msgstr "Кадрировать выбранное"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
-msgstr "ПроÑмотреть Canvas Scale"
+msgstr "ПредпроÑмотр Canvas Scale"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Translation mask for inserting keys."
@@ -6340,6 +6396,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Возможно уÑтановить точку только в ParticlesMaterial материал"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Преобразовать в CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ð¸ (Ñек):"
@@ -6400,10 +6460,6 @@ msgstr "Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ AABB"
msgid "Generate Visibility AABB"
msgstr "Генерировать AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Генерировать AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Удалить точку Ñ ÐºÑ€Ð¸Ð²Ð¾Ð¹"
@@ -6708,7 +6764,7 @@ msgstr "ПривÑзка"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Enable Snap"
-msgstr "Ðктивировать привÑзку"
+msgstr "Включить привÑзку"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid"
@@ -6951,7 +7007,7 @@ msgstr "Сохранить вÑÑ‘"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
-msgstr "МÑÐ³ÐºÐ°Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° Ñкрипта"
+msgstr "МÑгко перезагрузить Ñкрипт"
#: editor/plugins/script_editor_plugin.cpp
msgid "Copy Script Path"
@@ -6994,6 +7050,14 @@ msgstr "Закрыть документацию"
msgid "Run"
msgstr "ЗапуÑтить"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "ПоиÑк"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Шаг в"
@@ -7047,16 +7111,6 @@ msgstr ""
"Следующие файлы новее на диÑке.\n"
"Какие меры должны быть принÑты?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Перезагрузить"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "ПереÑохранить"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Отладчик"
@@ -7153,8 +7207,8 @@ msgstr "Точки оÑтанова"
msgid "Go To"
msgstr "Перейти к"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Вырезать"
@@ -7181,7 +7235,7 @@ msgstr "Переключить комментарий"
#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
-msgstr "Свернуть/Развернуть Ñтроку"
+msgstr "Свернуть/развернуть Ñтроку"
#: editor/plugins/script_text_editor.cpp
msgid "Fold All Lines"
@@ -7213,11 +7267,11 @@ msgstr "Преобразовать отÑтуп в пробелы"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Indent to Tabs"
-msgstr "Преобразовать отÑтупы в табулÑторы"
+msgstr "Преобразовать отÑтупы в табулÑцию"
#: editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
-msgstr "Ðвто-отÑтуп"
+msgstr "ÐвтоотÑтуп"
#: editor/plugins/script_text_editor.cpp
msgid "Find in Files..."
@@ -7377,8 +7431,12 @@ msgid "Yaw"
msgstr "РыÑкание"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Размер"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
-msgstr "ÐариÑовано обьектов"
+msgstr "ÐариÑовано объектов"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Material Changes"
@@ -8624,10 +8682,6 @@ msgid "Error"
msgstr "Ошибка"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Ðе указано Ñообщение коммита"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Ðе добавлены файлы Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð°"
@@ -8684,10 +8738,6 @@ msgid "Stage All"
msgstr "ИндекÑ. вÑÑ‘"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Добавьте Ñообщение коммита"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Закоммитить изменениÑ"
@@ -9891,7 +9941,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Ðе поддерживаетÑÑ Ð²Ð°ÑˆÐ¸Ð¼Ð¸ драйверами GPU."
#: editor/project_manager.cpp
msgid ""
@@ -10068,6 +10118,10 @@ msgid "Projects"
msgstr "Проекты"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Загрузка, пожалуйÑта, ждите..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "ПоÑледнее изменение"
@@ -10437,6 +10491,11 @@ msgstr "Ðвтозагрузка"
msgid "Plugins"
msgstr "Плагины"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Загрузить по умолчанию"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "ПредуÑтановка..."
@@ -10688,6 +10747,14 @@ msgid "Instance Child Scene"
msgstr "Добавить дочернюю Ñцену"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "Ðевозможно вÑтавить корневой узел в ту же Ñцену."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Ð’Ñтавить узел(узлы)"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Открепить Ñкрипт"
@@ -10815,6 +10882,10 @@ msgid "Attach Script"
msgstr "Прикрепить Ñкрипт"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Вырезать узел(узлы)"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Удалить узел(узлы)"
@@ -11623,6 +11694,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
"ПредоÑтавьте реÑÑƒÑ€Ñ MeshLibrary Ñтой GridMap, чтобы иÑпользовать его Ñетки."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Ðачать запекание"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Подготовка Ñтруктур данных"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Генерировать буфферы"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "ПрÑмое оÑвещение"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "ÐепрÑмое оÑвещение"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "ПоÑтобработка"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "ПоÑтроение карт оÑвещениÑ"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Ð˜Ð¼Ñ ÐºÐ»Ð°ÑÑа не может быть зарезервированным ключевым Ñловом"
@@ -12135,12 +12234,15 @@ msgid "Select device from the list"
msgstr "Выберите уÑтройÑтво из ÑпиÑка"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "ИÑполнÑемый файл ADB не Ñконфигурирован в наÑтройках редактора."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Ðе удалоÑÑŒ найти инÑтрумент «apksigner»."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner не наÑтроен в ÐаÑтройках Редактора."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Шаблон Ñборки Android не уÑтановлен в проекте. УÑтановите его в меню проекта."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12154,27 +12256,34 @@ msgstr ""
"Хранилище ключей не наÑтроено ни в наÑтройках редактора, ни в предуÑтановках."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"ПользовательÑÐºÐ°Ñ Ñборка требует Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð³Ð¾ пути к Android SDK в "
-"наÑтройках редактора."
+"ТребуетÑÑ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ дейÑтвительный путь к Android SDK в ÐаÑтройках редактора."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Ðеправильный путь к Android SDK Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑкой Ñборки в наÑтройках "
-"редактора."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "ÐедейÑтвительный путь Android SDK в ÐаÑтройках редактора."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Â«platform-tools» отÑутÑтвует!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "Ðе удалоÑÑŒ найти команду adb в Android SDK platform-tools."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
msgstr ""
-"Шаблон Ñборки Android не уÑтановлен в проекте. УÑтановите его в меню проекта."
+"ПожалуйÑта, проверьте каталог Android SDK, указанный в ÐаÑтройках редактора."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Â«build-tools» отÑутÑтвует!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "Ðе удалоÑÑŒ найти команду apksigner в Android SDK build-tools."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12431,6 +12540,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "ПуÑтой CollisionPolygon2D не влиÑет на ÑтолкновениÑ."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12469,23 +12586,26 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Узел Ри Узел B должны быть ÑкземплÑрами клаÑÑа PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Узел Рдолжен быть ÑкземплÑром клаÑÑа PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Узел B должен быть ÑкземплÑром клаÑÑа PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
msgstr ""
+"СуÑтав должен быть ÑвÑзан Ñ Ð´Ð²ÑƒÐ¼Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°Ð¼Ð¸ ÑвлÑющимиÑÑ ÑкземплÑрами клаÑÑа "
+"PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
msgstr ""
+"Узел Ри Узел B должны быть различными ÑкземплÑрами клаÑÑа PhysicsBody2D"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12643,28 +12763,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin требует дочерний узел ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "ПоиÑк полиÑеток и иÑточников Ñвета"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(ОÑталоÑÑŒ: %d:%02d Ñек)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Подготовка геометрии (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "ПоÑтроение полиÑетки: "
+msgid "Preparing environment"
+msgstr "Подготовка окружениÑ"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "ПоÑтроение Ñвета:"
+msgid "Generating capture"
+msgstr "Создание захвата"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Завершение поÑтроениÑ"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Сохранение карт оÑвещениÑ"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "ОÑвещение полиÑетки: "
+msgid "Done"
+msgstr "Готово"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12739,6 +12859,10 @@ msgid "Plotting Meshes"
msgstr "ПоÑтроение полиÑетки"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Завершение поÑтроениÑ"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12746,11 +12870,6 @@ msgstr ""
"GIProbes не поддерживаютÑÑ Ð²Ð¸Ð´ÐµÐ¾Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð¾Ð¼ GLES2.\n"
"ВмеÑто Ñтого иÑпользуйте BakedLightmap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera уÑтарела и будет удалена в Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight Ñ ÑƒÐ³Ð»Ð¾Ð¼ более 90 градуÑов не может отбраÑывать тени."
@@ -12815,23 +12934,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Узел Ри Узел Ð’ должны быть наÑледниками клаÑÑа PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Узел Рдолжен быть наÑледником клаÑÑа PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Узел Ð’ должен быть наÑледником клаÑÑа PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "СуÑтав не Ñоединён ни Ñ Ð¾Ð´Ð½Ð¸Ð¼ ÑкземплÑром клаÑÑа PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Узел Ри Узел Ð’ должны быть различными объектами клаÑÑа PhysicsBody"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12993,6 +13112,14 @@ msgstr "Внимание!"
msgid "Please Confirm..."
msgstr "Подтверждение..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Ðужно иÑпользовать доÑтупное раÑширение."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Включить миникарту Ñетки."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13048,6 +13175,14 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "Размер окна проÑмотра должен быть больше 0 Ð´Ð»Ñ Ñ€ÐµÐ½Ð´ÐµÑ€Ð¸Ð½Ð³Ð°."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"Порт ÑÑмплера подключен, но не иÑпользуетÑÑ. РаÑÑмотрите возможноÑть "
+"Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ñточника на «SamplerPort»."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Ðеверный иÑточник Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра."
@@ -13075,14 +13210,50 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть назначены только Ð
msgid "Constants cannot be modified."
msgstr "КонÑтанты не могут быть изменены."
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "По Ñтому пути уже ÑущеÑтвует файл или папка Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ñ‹Ð¼ именем."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "InterpolatedCamera уÑтарела и будет удалена в Godot 4.0."
+
+#~ msgid "No"
+#~ msgstr "Ðет"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Эта Ñцена никогда не была Ñохранена. Сохранить перед запуÑком?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "ИÑполнÑемый файл ADB не Ñконфигурирован в наÑтройках редактора."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner не наÑтроен в ÐаÑтройках Редактора."
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Â«build-tools» отÑутÑтвует!"
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "ПользовательÑÐºÐ°Ñ Ñборка требует Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð³Ð¾ пути к Android SDK в "
+#~ "наÑтройках редактора."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(ОÑталоÑÑŒ: %d:%02d Ñек)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "ПоÑтроение полиÑетки: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "ОÑвещение полиÑетки: "
+
+#~ msgid "Search complete"
+#~ msgstr "ПоиÑк завершен"
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "Ðе удалоÑÑŒ найти инÑтрумент zipalign."
+#~ msgid "No commit message was provided"
+#~ msgstr "Ðе указано Ñообщение коммита"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Добавьте Ñообщение коммита"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "По Ñтому пути уже ÑущеÑтвует файл или папка Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ñ‹Ð¼ именем."
#~ msgid "Aligning APK..."
#~ msgstr "Выравнивание APK..."
@@ -13426,9 +13597,6 @@ msgstr "КонÑтанты не могут быть изменены."
#~ msgid "Failed to save solution."
#~ msgstr "Ðе удалоÑÑŒ Ñохранить решение."
-#~ msgid "Done"
-#~ msgstr "Готово"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Ðе удалоÑÑŒ Ñоздать C# проект."
@@ -14709,9 +14877,6 @@ msgstr "КонÑтанты не могут быть изменены."
#~ msgid "Use Default Light"
#~ msgstr "ИÑпользовать Ñтандартный Ñвет"
-#~ msgid "Use Default sRGB"
-#~ msgstr "ИÑпользовать sRGB"
-
#~ msgid "Default Light Normal:"
#~ msgstr "Образец Ñтандартного оÑвещениÑ:"
diff --git a/editor/translations/si.po b/editor/translations/si.po
index e1675c412f..0c3a01f0e4 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -1,14 +1,15 @@
# Sinhala translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Yohan Sandun <Yohan99ysk@gmail.com>, 2018.
+# thushariii <thusharipahalage@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2018-12-13 14:42+0100\n"
-"Last-Translator: Yohan Sandun <Yohan99ysk@gmail.com>\n"
+"PO-Revision-Date: 2021-02-05 09:20+0000\n"
+"Last-Translator: thushariii <thusharipahalage@gmail.com>\n"
"Language-Team: Sinhala <https://hosted.weblate.org/projects/godot-engine/"
"godot/si/>\n"
"Language: si\n"
@@ -16,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Poedit 2.2\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -103,11 +104,11 @@ msgstr "à¶šà·à¶©à¶´à¶­"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
-msgstr ""
+msgstr "à¶šà·à¶½à¶º:"
#: editor/animation_bezier_editor.cpp
msgid "Value:"
-msgstr ""
+msgstr "වටිනà·à¶šà¶¸:"
#: editor/animation_bezier_editor.cpp
msgid "Insert Key Here"
@@ -190,7 +191,7 @@ msgstr "සජීවීකරණ පුනරà·à·€à¶»à·Šà¶®à¶±à¶º"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr ""
+msgstr "සජීවිකරණ ලූපය වෙනස් කරන්න"
#: editor/animation_track_editor.cpp
msgid "Property Track"
@@ -249,7 +250,7 @@ msgstr "Anim පසුරු:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
-msgstr ""
+msgstr "පථය වෙනස් කරන්න"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
@@ -331,7 +332,7 @@ msgstr "යතුරු මක෠දමන්න"
#: editor/animation_track_editor.cpp
msgid "Change Animation Update Mode"
-msgstr ""
+msgstr "සජීවිකරණ යà·à·€à¶­à·Šà¶šà·à¶½à·“à¶± à¶´à·Šâ€à¶»à¶šà·à¶»à¶º වෙනස් කරන්න"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -435,7 +436,7 @@ msgstr "ලුහුබදින්නෙක් එක් කරන්න"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr ""
+msgstr "පථය අවලංගු à¶¶à·à·€à·’න් යතුරක් à¶‘à¶šà·Š à¶šà·… නොහà·à¶š."
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
@@ -646,7 +647,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1817,8 +1818,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1909,10 +1910,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2317,6 +2314,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2360,18 +2361,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2420,6 +2409,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2462,7 +2455,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2852,14 +2845,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3014,6 +2999,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3216,7 +3217,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3753,7 +3754,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3891,6 +3900,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4849,7 +4870,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4953,7 +4974,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4984,8 +5004,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4999,9 +5018,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6070,6 +6108,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6130,10 +6172,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6715,6 +6753,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6766,16 +6812,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6869,8 +6905,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7091,6 +7127,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8317,10 +8357,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8379,10 +8415,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9644,6 +9676,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10004,6 +10040,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10247,6 +10287,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "යතුරු පිටපත් කරන්න"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10371,6 +10420,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "යතුරු පිටපත් කරන්න"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11157,6 +11211,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11663,11 +11745,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11679,11 +11763,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11691,9 +11775,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11918,6 +12012,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12084,27 +12186,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12164,14 +12266,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12377,6 +12478,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12418,6 +12527,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index db612cbd65..68da1b1221 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -1,6 +1,6 @@
# Slovak translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# J08nY <johnenter@gmail.com>, 2016.
# MineGame 159 <minegame459@gmail.com>, 2018.
@@ -647,7 +647,7 @@ msgstr "Vybrať Track-y na skopírovanie"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopírovať"
@@ -1851,8 +1851,8 @@ msgid "Open a File or Directory"
msgstr "OtvoriÅ¥ súbor / prieÄinok"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Uložiť"
@@ -1943,10 +1943,6 @@ msgstr "Predzobraziť:"
msgid "File:"
msgstr "Súbor:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Musíte použiť platné rozšírenie."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "SkenZdrojov"
@@ -2378,6 +2374,10 @@ msgid "There is no defined scene to run."
msgstr "Nieje definovaná žiadna scéna na spustenie."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Subprocess sa nedá spustiť!"
@@ -2421,20 +2421,6 @@ msgstr "Na uloženie scény je potrebný root node."
msgid "Save Scene As..."
msgstr "Uložiť Scénu Ako..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nie"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "ÃNO"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-"Táto scéna ešte nikdy nebola uložená. Chcete ju uložiť predtým ako ju "
-"zapnete?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Táto operácia nemôže byÅ¥ dokonÄená bez scény."
@@ -2484,6 +2470,10 @@ msgid "Quit"
msgstr "Odísť"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "ÃNO"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Odísť z editora?"
@@ -2529,7 +2519,8 @@ msgstr ""
"Addon plugin nie je možné povoliť pri: '% s' analýze konfigurácie zlyhalo."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"Nepodarilo sa nájsť script field pre addon plugin v: 'res://addons/%s'."
@@ -2960,14 +2951,6 @@ msgid "Help"
msgstr "Pomoc"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Vyhľadať"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Online Dokumentácie"
@@ -3132,6 +3115,23 @@ msgid "Open & Run a Script"
msgstr "Otvoriť a vykonať skript"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr "Nasledovné súbory sa nepodarilo extrahovať z balíka:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Novo Zdedené"
@@ -3341,7 +3341,7 @@ msgstr "SpraviÅ¥ JedineÄným"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Vložiť"
@@ -3892,8 +3892,19 @@ msgid "Searching..."
msgstr "Vyhľadávam..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Vyhľadávanie bolo dokonÄené"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d zhody."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d zhody."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d zhody."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4029,6 +4040,21 @@ msgstr "Vrátili ste Node-derived objekt v `post_import()` metóde?"
msgid "Saving..."
msgstr "Ukladám..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Vybrať Režim"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Import"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "NaÄítaÅ¥ predvolené"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Súbory"
@@ -4993,7 +5019,8 @@ msgid "Got:"
msgstr "Má:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Zlyhalo sha256 hash check"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5097,7 +5124,6 @@ msgid "Sort:"
msgstr "Zoradiť:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategória:"
@@ -5126,10 +5152,10 @@ msgid "Assets ZIP File"
msgstr "Prostriedky Súboru ZIP"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Nedá sa urÄiÅ¥ cesta pre uloženie lightmap obrázkov.\n"
"Uložte svoju scénu (Aby sa obrázky na to isté miesto), alebo vyberte cestu "
@@ -5150,9 +5176,29 @@ msgstr ""
"zapisovateľná."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Bake Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Vybrať Súbor Šablóny"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6241,6 +6287,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Všetky vybrané"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6301,10 +6352,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6910,6 +6957,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Vyhľadať"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6962,16 +7017,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7070,8 +7115,8 @@ msgstr "Všetky vybrané"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7299,6 +7344,11 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Veľkosť: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8588,10 +8638,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8655,10 +8701,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Zmeniť"
@@ -9944,6 +9986,11 @@ msgid "Projects"
msgstr "Zakladatelia Projektu"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "NaÄítavanie zrkadiel, prosím Äakajte..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10313,6 +10360,11 @@ msgstr ""
msgid "Plugins"
msgstr "Pluginy"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "NaÄítaÅ¥ predvolené"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10558,6 +10610,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Vložiť"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Popis:"
@@ -10682,6 +10743,11 @@ msgid "Attach Script"
msgstr "Popis:"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Vložiť"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11500,6 +11566,36 @@ msgstr "Filter:"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Smery"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Generovanie Lightmaps"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12019,11 +12115,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12035,11 +12133,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12047,9 +12145,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12282,6 +12390,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Prázdny CollisionPolygon2D nemá žiaden efekt na kolíziu."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12460,27 +12576,29 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "Generovanie Lightmaps"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Generovanie Lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12542,14 +12660,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12756,6 +12873,15 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Musíte použiť platné rozšírenie."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "Povoliť Prichytávanie"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12797,6 +12923,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Neplatný zdroj pre predzobrazenie."
@@ -12826,6 +12958,17 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No"
+#~ msgstr "Nie"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr ""
+#~ "Táto scéna ešte nikdy nebola uložená. Chcete ju uložiť predtým ako ju "
+#~ "zapnete?"
+
+#~ msgid "Search complete"
+#~ msgstr "Vyhľadávanie bolo dokonÄené"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Už tu je súbor alebo prieÄinok pomenovaný rovnako."
@@ -12952,10 +13095,6 @@ msgstr ""
#~ msgstr "Vytvoriť adresár"
#, fuzzy
-#~ msgid "Custom Node"
-#~ msgstr "Vložiť"
-
-#, fuzzy
#~ msgid "Create Area"
#~ msgstr "Vytvoriť adresár"
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index 0326de6a9f..69819f0a36 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -1,6 +1,6 @@
# Slovenian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# matevž lapajne <sivar.lapajne@gmail.com>, 2016-2018.
# Matjaž Vitas <matjaz.vitas@gmail.com>, 2017-2018.
@@ -12,12 +12,13 @@
# Arnold Marko <arnold.marko@gmail.com>, 2019.
# Alex <alexrixhardson@gmail.com>, 2019.
# Andrew Poženel <andrej.pozenel@outlook.com>, 2020.
+# Jakob Tadej VrtaÄnik <minecraftalka2@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-07-15 02:42+0000\n"
-"Last-Translator: Andrew Poženel <andrej.pozenel@outlook.com>\n"
+"PO-Revision-Date: 2021-02-01 20:54+0000\n"
+"Last-Translator: Jakob Tadej VrtaÄnik <minecraftalka2@gmail.com>\n"
"Language-Team: Slovenian <https://hosted.weblate.org/projects/godot-engine/"
"godot/sl/>\n"
"Language: sl\n"
@@ -26,7 +27,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -370,7 +371,7 @@ msgstr "Odstrani animacijsko sled"
#: editor/animation_track_editor.cpp
msgid "Create NEW track for %s and insert key?"
-msgstr "Ustvarim NOVO sled za %s in vstavim kljuÄ?"
+msgstr "Ustvarim NOVO sled za %s in vstavi kljuÄ?"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
@@ -680,7 +681,7 @@ msgstr "Izberi Lastnost"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1935,8 +1936,8 @@ msgid "Open a File or Directory"
msgstr "Odpri Datoteko ali Mapo"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Shrani"
@@ -2035,10 +2036,6 @@ msgstr "Predogled:"
msgid "File:"
msgstr "Datoteka:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Uporabiti moraš valjavno razširitev."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "BranjeVirov"
@@ -2488,6 +2485,10 @@ msgid "There is no defined scene to run."
msgstr "Ni doloÄene scene za zagon."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Nemorem zaÄeti podprocesa!"
@@ -2533,18 +2534,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr "Shrani Sceno Kot..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Ne"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Da"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Ta scena ni bila nikoli shranjena. Shranim pred zagonom?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Ta operacija ni mogoÄa brez scene."
@@ -2593,6 +2582,10 @@ msgid "Quit"
msgstr "Zapri"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Da"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Zaprem urejevalnik?"
@@ -2641,7 +2634,8 @@ msgstr ""
"konfiguracije ni uspelo."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"Ni mogoÄe najti polja skripte za dodatni vtiÄnik na: 'res://addons/%s'."
@@ -3093,14 +3087,6 @@ msgid "Help"
msgstr "PomoÄ"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Iskanje"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Spletna Dokumentacija"
@@ -3263,6 +3249,22 @@ msgid "Open & Run a Script"
msgstr "Odpri & Zaženi Skripto"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Novo Podedovano"
@@ -3471,7 +3473,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -4052,8 +4054,18 @@ msgstr "Shranjevanje..."
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "IÅ¡Äi Besedilo"
+msgid "%d match in %d file."
+msgstr "Ni Zadetkov"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "Ni Zadetkov"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Ni Zadetkov"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4197,6 +4209,21 @@ msgstr ""
msgid "Saving..."
msgstr "Shranjevanje..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Izberi NaÄin"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Uvozi"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Naložite Prevzeto"
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -5222,7 +5249,8 @@ msgid "Got:"
msgstr "Dobil:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Neuspešno preverjanje preizkusa sha256"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5336,7 +5364,6 @@ msgid "Sort:"
msgstr "Razvrsti:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategorija:"
@@ -5367,10 +5394,10 @@ msgid "Assets ZIP File"
msgstr "Dodatki v ZIP Datoteki"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Ni mogoÄe doloÄiti poti shranjevanja slik svetlobnih kart.\n"
"Shrani prizor (za slike, da bodo shranjene v isti mapi), ali izberi pot za "
@@ -5390,9 +5417,29 @@ msgstr ""
"Napaka pri izdelavi slik, svetlobnih kart. Poskrbite, da je pot zapisljiva."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "ZapeÄi Svetlobne karte"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Izberi datoteko predloge"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6521,6 +6568,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Pretvori V..."
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6581,10 +6633,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -7204,6 +7252,14 @@ msgstr ""
msgid "Run"
msgstr "Zaženi"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Iskanje"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7257,16 +7313,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "RazhroÅ¡Äevalnik"
@@ -7367,8 +7413,8 @@ msgstr "IzbriÅ¡i toÄke"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7603,6 +7649,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8910,11 +8960,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "No commit message was provided"
-msgstr "Ime ni na voljo"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8979,10 +9024,6 @@ msgid "Stage All"
msgstr "Zamenjaj Vse"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Usklajuj Spremembe Skript"
@@ -10287,6 +10328,11 @@ msgid "Projects"
msgstr "Projekt"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Pridobivanje virov, poÄakajte..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10655,6 +10701,11 @@ msgstr ""
msgid "Plugins"
msgstr "VtiÄniki"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Naložite Prevzeto"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Prednastavitev..."
@@ -10910,6 +10961,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Prilepi Pozicijo"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Odstrani Gradnik VizualnaSkripta"
@@ -11040,6 +11100,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Gradnik Prehod"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11877,6 +11942,37 @@ msgstr "Lastnosti objekta."
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Smeri"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Trenutna RazliÄica:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Ustvarjanje Svetlobnih Kart"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12405,11 +12501,13 @@ msgid "Select device from the list"
msgstr "Izberite napravo s seznama"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12421,11 +12519,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12433,9 +12531,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12678,6 +12786,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Prazen CollisionPolygon2D nima vpliva na collision."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12853,27 +12969,29 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "Ustvarjanje Svetlobnih Kart"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Ustvarjanje Svetlobnih Kart"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12933,14 +13051,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -13156,6 +13273,14 @@ msgstr "Opozorilo!"
msgid "Please Confirm..."
msgstr "Prosimo Potrdite..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Uporabiti moraš valjavno razširitev."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
#, fuzzy
msgid ""
@@ -13201,6 +13326,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Neveljaven vir za shader."
@@ -13230,6 +13361,20 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Konstante ni možno spreminjati."
+#~ msgid "No"
+#~ msgstr "Ne"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Ta scena ni bila nikoli shranjena. Shranim pred zagonom?"
+
+#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "IÅ¡Äi Besedilo"
+
+#, fuzzy
+#~ msgid "No commit message was provided"
+#~ msgstr "Ime ni na voljo"
+
#, fuzzy
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Datoteka ali mapa s tem imenom že obstaja."
@@ -13473,10 +13618,6 @@ msgstr "Konstante ni možno spreminjati."
#~ msgid "Create folder"
#~ msgstr "Ustvarite mapo"
-#, fuzzy
-#~ msgid "Custom Node"
-#~ msgstr "Gradnik Prehod"
-
#~ msgid "Invalid Path"
#~ msgstr "Neveljavna Pot"
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index 434fd72854..f53d0b630a 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -1,6 +1,6 @@
# Albanian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Igli <iglibh@outlook.com>, 2018.
# Enrik Qose <enrikqose@gmail.com>, 2019.
@@ -632,7 +632,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1887,8 +1887,8 @@ msgid "Open a File or Directory"
msgstr "Hap një Skedar ose Direktori"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Ruaj"
@@ -1983,10 +1983,6 @@ msgstr "Shikim paraprak:"
msgid "File:"
msgstr "Skedar:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Duhet të perdorësh një shtesë të lejuar."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "SkanoBurimet"
@@ -2432,6 +2428,10 @@ msgid "There is no defined scene to run."
msgstr "Nuk ka një skenë të përcaktuar për të filluar."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Nuk mund të fillojë subprocess-in!"
@@ -2476,18 +2476,6 @@ msgstr "Një nyje rrënjë është e kërkuar para se të ruash skenën."
msgid "Save Scene As..."
msgstr "Ruaje Skenën Si..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Jo"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Po"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Kjo skenë nuk është ruajtur më parë. Ruaje para se të fillosh?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Ky veprim nuk mund të kryhet pa një skenë."
@@ -2536,6 +2524,10 @@ msgid "Quit"
msgstr "Dil"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Po"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Dil nga editori?"
@@ -2585,7 +2577,8 @@ msgstr ""
"dështoi."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "I paaftë te gjej fushën e shkrimit për shtojcën në: 'res://addons/%s'."
#: editor/editor_node.cpp
@@ -3031,14 +3024,6 @@ msgid "Help"
msgstr "Ndihmë"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Kërko"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Dokumentimi Online"
@@ -3199,6 +3184,22 @@ msgid "Open & Run a Script"
msgstr "Hap & Fillo një Shkrim"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "E Trashëguar e Re"
@@ -3412,7 +3413,7 @@ msgstr "Bëje Unik"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Ngjit"
@@ -3978,8 +3979,19 @@ msgid "Searching..."
msgstr "Duke kërkuar..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Kërkimi u kompletua"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "Përputhjet:"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "Përputhjet:"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Përputhjet:"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4120,6 +4132,21 @@ msgstr ""
msgid "Saving..."
msgstr "Duke Ruajtur..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Zgjidh Nyjet Për ti Importuar"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importo"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Ngarko të Parazgjedhur"
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -5085,7 +5112,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5193,7 +5220,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5226,8 +5252,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5241,9 +5266,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Zgjidh skedarin e shabllonit"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6321,6 +6366,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Konverto në %s"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6381,10 +6431,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6973,6 +7019,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Kërko"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7024,16 +7078,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7130,8 +7174,8 @@ msgstr "Krijo pika."
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7357,6 +7401,11 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Madhësia: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8596,10 +8645,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8663,10 +8708,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Sinkronizo Ndryshimet e Shkrimit"
@@ -9943,6 +9984,11 @@ msgid "Projects"
msgstr "Projekti"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Duke marrë pasqyrat, ju lutem prisni..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10305,6 +10351,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Ngarko të Parazgjedhur"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10552,6 +10603,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Dyfisho Nyjet"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Shkrim i Ri"
@@ -10677,6 +10737,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Dyfisho Nyjet"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11494,6 +11559,36 @@ msgstr "Nyjet filtruese"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Versioni Aktual:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Duke Gjeneruar Hartat e Dritës"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12005,11 +12100,13 @@ msgid "Select device from the list"
msgstr "Zgjidh paisjen nga lista"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12021,11 +12118,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12033,9 +12130,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12262,6 +12369,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12428,27 +12543,29 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "Duke Gjeneruar Hartat e Dritës"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Duke Gjeneruar Hartat e Dritës"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12508,14 +12625,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12721,6 +12837,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Duhet të perdorësh një shtesë të lejuar."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12762,6 +12886,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
@@ -12789,6 +12919,15 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No"
+#~ msgstr "Jo"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Kjo skenë nuk është ruajtur më parë. Ruaje para se të fillosh?"
+
+#~ msgid "Search complete"
+#~ msgstr "Kërkimi u kompletua"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr ""
#~ "Ekziston që më parë një skedar ose folder me të njëjtin emër në këtë "
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index d5b4d28f95..4fe901f414 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -1,6 +1,6 @@
# Serbian (cyrillic) translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# ÐлекÑандар Урошевић <nicecubedude@gmail.com>, 2017.
@@ -720,7 +720,7 @@ msgstr "ПоÑтави прелаз на:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Копирај"
@@ -2030,8 +2030,8 @@ msgid "Open a File or Directory"
msgstr "Отвори датотеку или директоријум"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Сачувај"
@@ -2130,10 +2130,6 @@ msgstr "Преглед:"
msgid "File:"
msgstr "Датотека:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Мора Ñе кориÑтити важећа екÑтензија."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Скенирање извора"
@@ -2609,6 +2605,10 @@ msgid "There is no defined scene to run."
msgstr "Ðе поÑтоји дефиниÑана Ñцена за покретање."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Ðе могу покренути подпроцеÑ!"
@@ -2655,18 +2655,6 @@ msgstr "За памћене Ñцене неопходан је корени но
msgid "Save Scene As..."
msgstr "Сачувај Ñцену као..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Ðе"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Да"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Ова Ñцена није Ñачувана. Сачувај пре покретања?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Ова операција Ñе не може обавити без Ñцене."
@@ -2715,6 +2703,10 @@ msgid "Quit"
msgstr "Изађи"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Да"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Изађи из уредника?"
@@ -2760,7 +2752,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "ÐеуÑпех при прикључивању додатка због конфигурационе датотеке: '%s'."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "ÐеуÑпех при налажењу поља за Ñкриптицу у додатку „res://addons/%s“."
#: editor/editor_node.cpp
@@ -3221,14 +3214,6 @@ msgid "Help"
msgstr "Помоћ"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Тражи"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Онлајн документација"
@@ -3408,6 +3393,25 @@ msgid "Open & Run a Script"
msgstr "Отвори и покрени Ñкриптицу"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Следеће датотеке Ñу нове на диÑку.\n"
+"Која акција Ñе треба предузети?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "ОÑвежи"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Поново Ñачувај"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Ðова наÑлеђена"
@@ -3639,7 +3643,7 @@ msgstr "Учини ЈединÑтвеним"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Ðалепи"
@@ -4252,8 +4256,18 @@ msgstr "Чување..."
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "Потражи текÑÑ‚"
+msgid "%d match in %d file."
+msgstr "Ðема подударања."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "Ðема подударања."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Ðема подударања."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4401,6 +4415,21 @@ msgstr ""
msgid "Saving..."
msgstr "Чување..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Одабери режим"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Увоз"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Учитај уобичајено"
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -5478,7 +5507,8 @@ msgid "Got:"
msgstr "Добијено:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "ÐеуÑпела провера sha256 Ñуме"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5597,7 +5627,6 @@ msgid "Sort:"
msgstr "Сортирање:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Категорија:"
@@ -5631,8 +5660,7 @@ msgstr "РеÑурÑи ЗИП датотека"
#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"ÐеуÑпело одређивање путање памћења за Ñлике МапеСенчења.\n"
"Упамти Ñцену (за Ñлике да буду Ñачуване у иÑтом директоријуму), или одабери "
@@ -5654,10 +5682,30 @@ msgstr ""
"ÐеуÑпешно креирање Ñлике МапеСенчења, провери да ли могуће упиÑивање путање."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
#, fuzzy
msgid "Bake Lightmaps"
msgstr "Изпеци МапеСенчења"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Одабери шаблонÑку датотеку"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6868,6 +6916,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Тачка Ñе Ñамо може поÑтавити у ParticlesMaterial процеÑни материјал"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Претвори у CPU чеÑтице"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Време генериÑања (Ñек.):"
@@ -6933,10 +6986,6 @@ msgstr "ГенериÑање оÑног поравнаног граничниоÐ
msgid "Generate Visibility AABB"
msgstr "Генериши оÑно поравнан гранични оквир (AABB) видљивоÑти"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Генериши оÑно поравнан гранични оквир (AABB)"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Обриши тачку из криве"
@@ -7597,6 +7646,14 @@ msgstr "Затвори документацију"
msgid "Run"
msgstr "Покрени"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Тражи"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Корак у"
@@ -7652,16 +7709,6 @@ msgstr ""
"Следеће датотеке Ñу нове на диÑку.\n"
"Која акција Ñе треба предузети?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "ОÑвежи"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Поново Ñачувај"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Дебагер"
@@ -7769,8 +7816,8 @@ msgstr "Тачке прекида"
msgid "Go To"
msgstr "Иди Ðа"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "ИÑеци"
@@ -8019,6 +8066,11 @@ msgid "Yaw"
msgstr "Горе-Доле"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Величина:"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Ðацртани објекти"
@@ -9422,11 +9474,6 @@ 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 "No files added to stage"
msgstr "Ðи један фајл није додат на позорницу"
@@ -9497,11 +9544,6 @@ msgstr "Сачувај Ñве"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Add a commit message"
-msgstr "Додај предајну поруку"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Commit Changes"
msgstr "Синхронизуј промене Ñкриптица"
@@ -11130,6 +11172,11 @@ msgstr "Пројекти"
#: editor/project_manager.cpp
#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Прихватам одредишта, молим Ñачекајте..."
+
+#: editor/project_manager.cpp
+#, fuzzy
msgid "Last Modified"
msgstr "Задњи Измењен"
@@ -11584,6 +11631,11 @@ msgstr "Ðуто-Учитавање"
msgid "Plugins"
msgstr "Прикључци"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Учитај уобичајено"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "ПоÑтавке..."
@@ -11890,6 +11942,16 @@ msgstr "ИнÑтанца Сцена Дете"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Ðемогуће опериÑати на чвору из Ñтране Ñцене!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Ðалепи Чворове"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Detach Script"
msgstr "Припој Скрипту"
@@ -12045,6 +12107,11 @@ msgstr "Припој Скрипту"
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Ðаправи чвор"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Remove Node(s)"
msgstr "Уклони Чвор/ове"
@@ -13029,6 +13096,39 @@ msgstr "Пробери мреже"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "Дај БиблиотециМрежа реÑÑƒÑ€Ñ Ð¾Ð²Ðµ МапеМреже да кориÑти њене мреже."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "Генериши оÑно поравнан гранични оквир (AABB)"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Смерови"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "Увучи деÑно"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Ðакон-Обраде"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Скована Светла:"
+
#: modules/mono/csharp_script.cpp
#, fuzzy
msgid "Class name can't be a reserved keyword"
@@ -13593,14 +13693,17 @@ msgid "Select device from the list"
msgstr "Одабери уређај Ñа лиÑте"
#: platform/android/export/export.cpp
-#, fuzzy
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "ADB извршна датотека није подешена у Подешавањима Уредника."
+msgid "Unable to find the 'apksigner' tool."
+msgstr ""
#: platform/android/export/export.cpp
#, fuzzy
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jar потпиÑник није подешен у Подешавањима Уредника."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Android нацрт изградње није инÑталиран у пројекат. ИнÑталирај га из Пројекат "
+"менија."
#: platform/android/export/export.cpp
#, fuzzy
@@ -13618,14 +13721,13 @@ msgstr ""
#: platform/android/export/export.cpp
#, fuzzy
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"Произвољна изградња захтева важећу путању до Android SDK у Подешавањима "
-"Уредника."
+"Ðеважећа Android SDK путања за произвољну изградњу у Подешавањима Уредника."
#: platform/android/export/export.cpp
#, fuzzy
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
"Ðеважећа Android SDK путања за произвољну изградњу у Подешавањима Уредника."
@@ -13634,13 +13736,22 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
#, fuzzy
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"Ðеважећа Android SDK путања за произвољну изградњу у Подешавањима Уредника."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
-"Android нацрт изградње није инÑталиран у пројекат. ИнÑталирај га из Пројекат "
-"менија."
#: platform/android/export/export.cpp
#, fuzzy
@@ -13921,6 +14032,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Ðепријатењ СударниМногоугао2Д нема утицаја на Ñудар."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
#, fuzzy
msgid ""
@@ -14149,34 +14268,33 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin захтева ARVRCamera дете чвор."
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Време преоÑтало: %d:%02d Ñ)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Ðнализирање геометрије..."
#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "Plotting Meshes: "
-msgstr "Сковане Мреже:"
+msgid "Preparing environment"
+msgstr "Прикажи околину"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "Plotting Lights:"
-msgstr "Скована Светла:"
+msgid "Generating capture"
+msgstr "ГенериÑање оÑног поравнаног граничниог оквира (AABB)"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
+#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "Finishing Plot"
-msgstr "Завршни Ков"
+msgid "Saving lightmaps"
+msgstr "ГенериÑање оÑног поравнаног граничниог оквира (AABB)"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
-msgid "Lighting Meshes: "
-msgstr "СветлоÑне Мреже:"
+msgid "Done"
+msgstr "Готово!"
#: scene/3d/collision_object.cpp
#, fuzzy
@@ -14263,6 +14381,11 @@ msgstr "Сковане Мреже"
#: scene/3d/gi_probe.cpp
#, fuzzy
+msgid "Finishing Plot"
+msgstr "Завршни Ков"
+
+#: scene/3d/gi_probe.cpp
+#, fuzzy
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -14271,11 +14394,6 @@ msgstr ""
" \n"
"Као замену кориÑти ИÑпеченеСенкеМапу."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-
#: scene/3d/light.cpp
#, fuzzy
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
@@ -14547,6 +14665,15 @@ msgstr "Узбуна!"
msgid "Please Confirm..."
msgstr "Молимо Потврди..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Мора Ñе кориÑтити важећа екÑтензија."
+
+#: scene/gui/graph_edit.cpp
+#, fuzzy
+msgid "Enable grid minimap."
+msgstr "Укључи лепљење"
+
#: scene/gui/popup.cpp
#, fuzzy
msgid ""
@@ -14608,6 +14735,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "Величина Viewport-а мора бити већа од 0 да би Ñе нешто иÑцртало."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Ðеважећи извор за преглед."
@@ -14642,6 +14775,54 @@ msgstr "Варијације могу Ñамо бити одређене у фу
msgid "Constants cannot be modified."
msgstr "КонÑтанте није могуће мењати."
+#~ msgid "No"
+#~ msgstr "Ðе"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Ова Ñцена није Ñачувана. Сачувај пре покретања?"
+
+#, fuzzy
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "ADB извршна датотека није подешена у Подешавањима Уредника."
+
+#, fuzzy
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jar потпиÑник није подешен у Подешавањима Уредника."
+
+#, fuzzy
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Произвољна изградња захтева важећу путању до Android SDK у Подешавањима "
+#~ "Уредника."
+
+#, fuzzy
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#, fuzzy
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Време преоÑтало: %d:%02d Ñ)"
+
+#, fuzzy
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Сковане Мреже:"
+
+#, fuzzy
+#~ msgid "Lighting Meshes: "
+#~ msgstr "СветлоÑне Мреже:"
+
+#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "Потражи текÑÑ‚"
+
+#, fuzzy
+#~ msgid "No commit message was provided"
+#~ msgstr "Име није дато"
+
+#, fuzzy
+#~ msgid "Add a commit message"
+#~ msgstr "Додај предајну поруку"
+
#, fuzzy
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Датотека или директоријум Ñа овим именом већ поÑтоји."
@@ -14906,10 +15087,6 @@ msgstr "КонÑтанте није могуће мењати."
#~ msgstr "Грешка при учитавању реÑурÑа."
#, fuzzy
-#~ msgid "Done"
-#~ msgstr "Готово!"
-
-#, fuzzy
#~ msgid "Failed to create C# project."
#~ msgstr "Грешка при учитавању реÑурÑа."
@@ -14968,10 +15145,6 @@ msgstr "КонÑтанте није могуће мењати."
#~ msgstr "CheckBox Radio2"
#, fuzzy
-#~ msgid "Custom Node"
-#~ msgstr "Ðаправи чвор"
-
-#, fuzzy
#~ msgid "Snap (s): "
#~ msgstr "Један корак (Ñек.):"
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 3343da96fc..3d979c3fc6 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -1,6 +1,6 @@
# Serbian (latin) translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Milos Ponjavusic <brane@branegames.com>, 2018.
# BLu <blmasfon@gmail.com>, 2018.
@@ -654,7 +654,7 @@ msgstr "Postavi tranzicije na:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1827,8 +1827,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1921,10 +1921,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2331,6 +2327,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2374,18 +2374,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2434,6 +2422,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2476,7 +2468,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2868,14 +2860,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3030,6 +3014,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3233,7 +3233,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3770,7 +3770,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3908,6 +3916,19 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Uduplaj Selekciju"
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4873,7 +4894,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4977,7 +4998,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5008,8 +5028,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5023,9 +5042,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6101,6 +6139,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Napravi"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6161,10 +6204,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6752,6 +6791,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6803,16 +6850,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6907,8 +6944,8 @@ msgstr "Napravi"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7134,6 +7171,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8388,10 +8429,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8453,10 +8490,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9722,6 +9755,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10085,6 +10122,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10329,6 +10370,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Animacija Uduplaj KljuÄeve"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10453,6 +10503,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Animacija Uduplaj KljuÄeve"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11246,6 +11301,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11754,11 +11837,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11770,11 +11855,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11782,9 +11867,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12009,6 +12104,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12175,27 +12278,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12255,14 +12358,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12468,6 +12570,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12509,6 +12619,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index faab1ec8ed..a7bc3d6288 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -1,6 +1,6 @@
# Swedish translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# bergmarklund <davemcgroin@gmail.com>, 2017, 2018.
# Christoffer Sundbom <christoffer_karlsson@live.se>, 2017.
@@ -662,7 +662,7 @@ msgstr "Välj Spår att Kopiera"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopiera"
@@ -1899,8 +1899,8 @@ msgid "Open a File or Directory"
msgstr "Öppna en Fil eller Katalog"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Spara"
@@ -1996,10 +1996,6 @@ msgstr "Förhandsvisning:"
msgid "File:"
msgstr "Fil:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Måste använda en giltigt filändelse."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "ScanSources"
@@ -2451,6 +2447,10 @@ msgid "There is no defined scene to run."
msgstr "Det finns ingen definierad scen att köra."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Kunde inte starta underprocess!"
@@ -2498,18 +2498,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr "Spara Scen Som..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Nej"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Ja"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Denna scenen har aldrig sparats. Spara innan körning?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Åtgärden kan inte göras utan en scen."
@@ -2559,6 +2547,10 @@ msgid "Quit"
msgstr "Avsluta"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Ja"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Stäng redigeraren?"
@@ -2606,7 +2598,8 @@ msgstr ""
"Kunde inte aktivera addon plugin vid: '%s' parsning av config misslyckades."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "Kan inte hitta skriptfältet för addon plugin vid: 'res://addons/%s'."
#: editor/editor_node.cpp
@@ -3034,14 +3027,6 @@ msgid "Help"
msgstr "Hjälp"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Sök"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Dokumentation Online"
@@ -3201,6 +3186,23 @@ msgid "Open & Run a Script"
msgstr "Öppna & Kör ett Skript"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr "Följande filer gick inte att packa upp från tillägget:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Ladda om"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Spara om"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3413,7 +3415,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Klistra in"
@@ -3995,8 +3997,18 @@ msgstr "Sparar..."
#: editor/find_in_files.cpp
#, fuzzy
-msgid "Search complete"
-msgstr "Söktext"
+msgid "%d match in %d file."
+msgstr "%d matchningar."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d matchningar."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d matchningar."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4140,6 +4152,21 @@ msgstr ""
msgid "Saving..."
msgstr "Sparar..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Välj Node"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Importera"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Ladda Standard"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Filer"
@@ -5150,7 +5177,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5254,7 +5281,6 @@ msgid "Sort:"
msgstr "Sortera:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategori:"
@@ -5285,8 +5311,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5300,9 +5325,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Välj mall-fil"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6413,6 +6458,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Konvertera till Versaler"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6473,10 +6523,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -7092,6 +7138,14 @@ msgstr ""
msgid "Run"
msgstr "Kör"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Sök"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7144,16 +7198,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Ladda om"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Spara om"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7254,8 +7298,8 @@ msgstr "Radera punkter"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: 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"
@@ -7493,6 +7537,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8794,10 +8842,6 @@ msgid "Error"
msgstr "Fel"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8862,10 +8906,6 @@ msgid "Stage All"
msgstr "Spara Alla"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Synkronisera Skript-ändringar"
@@ -10178,6 +10218,11 @@ msgid "Projects"
msgstr "Projekt"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "Laddar..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Senast Ändrad"
@@ -10545,6 +10590,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Ladda Standard"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10802,6 +10852,15 @@ msgid "Instance Child Scene"
msgstr "Instansiera Barn-Scen"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Klistra in Noder"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "Fäst Skript"
@@ -10932,6 +10991,11 @@ msgid "Attach Script"
msgstr "Fäst Skript"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Klipp ut Noder"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Ta bort Nod(er)"
@@ -11772,6 +11836,37 @@ msgstr "Filtrera noder"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Sektioner:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Nuvarande Version:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "Genererar Lightmaps"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12291,11 +12386,13 @@ msgid "Select device from the list"
msgstr "Välj enhet från listan"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12307,11 +12404,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12319,9 +12416,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12558,6 +12665,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "En tom CollisionPolygon2D har ingen effekt på kollision."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12738,28 +12853,31 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin kräver en ARVRCamera Barn-Node"
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "Genererar Lightmaps"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "Genererar Lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr ""
+#, fuzzy
+msgid "Done"
+msgstr "Klar!"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12824,14 +12942,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -13045,6 +13162,14 @@ msgstr "Varning!"
msgid "Please Confirm..."
msgstr "Vänligen Bekräfta..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Måste använda en giltigt filändelse."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13086,6 +13211,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "Ogiltig teckenstorlek."
@@ -13116,6 +13247,16 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No"
+#~ msgstr "Nej"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Denna scenen har aldrig sparats. Spara innan körning?"
+
+#, fuzzy
+#~ msgid "Search complete"
+#~ msgstr "Söktext"
+
#, fuzzy
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "En fil eller mapp med detta namn finns redan."
@@ -13303,10 +13444,6 @@ msgstr ""
#~ msgstr "Misslyckades att ladda resurs."
#, fuzzy
-#~ msgid "Done"
-#~ msgstr "Klar!"
-
-#, fuzzy
#~ msgid "Failed to create C# project."
#~ msgstr "Misslyckades att ladda resurs."
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index c89be893b8..9f9f40b54b 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -1,6 +1,6 @@
# Tamil translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Senthil Kumar K <logickumar@gmail.com>, 2017.
@@ -650,7 +650,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1823,8 +1823,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1915,10 +1915,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2323,6 +2319,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2366,18 +2366,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2425,6 +2413,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2467,7 +2459,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2859,14 +2851,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3020,6 +3004,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3223,7 +3223,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3761,7 +3761,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3899,6 +3907,19 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯"
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4858,7 +4879,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4962,7 +4983,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4993,8 +5013,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5008,9 +5027,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6073,6 +6111,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6133,10 +6175,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6720,6 +6758,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6771,16 +6817,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6873,8 +6909,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7096,6 +7132,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8319,10 +8359,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8382,10 +8418,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9644,6 +9676,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10005,6 +10041,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10249,6 +10289,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "அசைவூடà¯à®Ÿà¯ போலிபசà¯à®šà®¾à®µà®¿à®•ளà¯"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10373,6 +10422,11 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "அசைவூடà¯à®Ÿà¯ போலிபசà¯à®šà®¾à®µà®¿à®•ளà¯"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11162,6 +11216,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11663,11 +11745,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11679,11 +11763,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11691,9 +11775,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11918,6 +12012,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12084,27 +12186,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12164,14 +12266,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12377,6 +12478,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12418,6 +12527,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index 806a6bb133..50c0fb5a4b 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -1,6 +1,6 @@
# Telugu translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# suresh p <suresh9247@gmail.com>, 2019, 2020.
msgid ""
@@ -628,7 +628,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1797,8 +1797,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1889,10 +1889,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2296,6 +2292,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2339,18 +2339,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2398,6 +2386,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2440,7 +2432,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2830,14 +2822,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2991,6 +2975,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3193,7 +3193,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3729,7 +3729,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3866,6 +3874,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4813,7 +4833,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4917,7 +4937,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4948,8 +4967,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4963,9 +4981,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6021,6 +6058,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6081,10 +6122,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6666,6 +6703,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6717,16 +6762,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6819,8 +6854,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7041,6 +7076,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8252,10 +8291,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8313,10 +8348,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9570,6 +9601,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9930,6 +9965,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10173,6 +10212,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10293,6 +10340,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11077,6 +11128,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11572,11 +11651,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11588,11 +11669,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11600,9 +11681,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11827,6 +11918,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -11993,27 +12092,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12073,14 +12172,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12286,6 +12384,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12327,6 +12433,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 1a36ecf42b..76a2d3c125 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -1,18 +1,18 @@
# Thai translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Kaveeta Vivatchai <goodytong@gmail.com>, 2017.
# Poommetee Ketson (Noshyaar) <poommetee@protonmail.com>, 2017-2018.
# Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020.
# Anonymous <noreply@weblate.org>, 2020.
# Lon3r <mptube.p@gmail.com>, 2020.
-# Kongfa Warorot <gongpha@hotmail.com>, 2020.
+# Kongfa Warorot <gongpha@hotmail.com>, 2020, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-01 20:29+0000\n"
+"PO-Revision-Date: 2021-02-15 10:51+0000\n"
"Last-Translator: Kongfa Warorot <gongpha@hotmail.com>\n"
"Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/"
"th/>\n"
@@ -21,7 +21,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -643,7 +643,7 @@ msgstr "เลือà¸à¹à¸—ร็à¸à¸—ี่จะคัดลอà¸"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "คัดลอà¸"
@@ -1836,8 +1836,8 @@ msgid "Open a File or Directory"
msgstr "เปิดไฟล์หรือโฟลเดอร์"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "บันทึà¸"
@@ -1928,10 +1928,6 @@ msgstr "ตัวอย่าง:"
msgid "File:"
msgstr "ไฟล์:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "นามสà¸à¸¸à¸¥à¹„ฟล์ไม่ถูà¸à¸•้อง"
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "สà¹à¸à¸™à¸•้นฉบับ"
@@ -2350,6 +2346,10 @@ msgid "There is no defined scene to run."
msgstr "ยังไม่ได้เลือà¸à¸‰à¸²à¸à¸—ี่จะเล่น"
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "บันทึà¸à¸‰à¸²à¸à¸à¹ˆà¸­à¸™à¸—ี่จะทำงาน..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "ไม่สามารถเริ่มขั้นตอนย่อย!"
@@ -2393,18 +2393,6 @@ msgstr "โหนดà¹à¸¡à¹ˆà¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้องทำà¸à¸²à¸£à¸šà¸±
msgid "Save Scene As..."
msgstr "บันทึà¸à¸‰à¸²à¸à¹€à¸›à¹‡à¸™..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "ไม่"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "ใช่"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "ฉาà¸à¸™à¸µà¹‰à¸¢à¸±à¸‡à¹„ม่ได้บันทึภบันทึà¸à¸à¹ˆà¸­à¸™à¹€à¸£à¸´à¹ˆà¸¡?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "ทำไม่ได้ถ้าไม่มีฉาà¸"
@@ -2454,6 +2442,10 @@ msgid "Quit"
msgstr "ออà¸"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "ใช่"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "ออà¸à¹‚ปรà¹à¸à¸£à¸¡?"
@@ -2497,7 +2489,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "ไม่สามารถเปิดใช้งานปลั๊à¸à¸­à¸´à¸™: '%s'"
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "ไม่พบชื่อสคริปต์ในปลั๊à¸à¸­à¸´à¸™: 'res://addons/%s'"
#: editor/editor_node.cpp
@@ -2915,14 +2908,6 @@ msgid "Help"
msgstr "ช่วยเหลือ"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "ค้นหา"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "คู่มือ"
@@ -3084,6 +3069,25 @@ msgid "Open & Run a Script"
msgstr "เปิดà¹à¸¥à¸°à¸£à¸±à¸™à¸ªà¸„ริปต์"
#: editor/editor_node.cpp
+#, fuzzy
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"ไฟล์ต่อไปนี้ในดิสà¸à¹Œà¹ƒà¸«à¸¡à¹ˆà¸à¸§à¹ˆà¸²\n"
+"จะทำอย่างไรต่อไป?:"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "โหลดใหม่"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "บันทึà¸à¸­à¸µà¸à¸„รั้ง"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "สืบทอด"
@@ -3290,7 +3294,7 @@ msgstr "ไม่ใช้ร่วมà¸à¸±à¸šà¸§à¸±à¸•ถุอื่น"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "วาง"
@@ -3643,6 +3647,11 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"ไฟล์หรือโฟลเดอร์ต่อไปนี้มีความขัดà¹à¸¢à¹‰à¸‡à¸à¸±à¸šà¸£à¸²à¸¢à¸à¸²à¸£à¹ƒà¸™à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¹€à¸›à¹‰à¸²à¸«à¸¡à¸²à¸¢ '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"คุณต้องà¸à¸²à¸£à¸—ี่จะเขียนทับหรือไม่?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3833,8 +3842,16 @@ msgid "Searching..."
msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„้นหา..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "ค้นหาสำเร็จ"
+msgid "%d match in %d file."
+msgstr "%d ตรงà¸à¸±à¸šà¹„ฟล์ %d"
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d ตรงà¸à¸±à¸šà¹„ฟล์ %d"
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d ตรงà¸à¸±à¸šà¹„ฟล์ %d"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -3970,6 +3987,21 @@ msgstr "คุณส่งคืนออบเจà¸à¸•์โหนดย่อ
msgid "Saving..."
msgstr "à¸à¸³à¸¥à¸±à¸‡à¸šà¸±à¸™à¸—ึà¸..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "โหมดเลือà¸"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "นำเข้า"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "โหลดค่าเริ่มต้น"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "ไฟล์ %d"
@@ -4078,7 +4110,7 @@ msgstr "คุณสมบัติออบเจà¸à¸•์"
#: editor/inspector_dock.cpp
msgid "Filter properties"
-msgstr "คุà¸à¸ªà¸¡à¸šà¸±à¸•ิตัวà¸à¸£à¸­à¸‡"
+msgstr "คุณสมบัติตัวà¸à¸£à¸­à¸‡"
#: editor/inspector_dock.cpp
msgid "Changes may be lost!"
@@ -4925,7 +4957,8 @@ msgid "Got:"
msgstr "ที่ได้รับ:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "ผิดพลาดในà¸à¸²à¸£à¸•รวจสอบà¹à¸®à¸Š SHA256"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5029,7 +5062,6 @@ msgid "Sort:"
msgstr "เรียงตาม:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "หมวดหมู่:"
@@ -5058,10 +5090,10 @@ msgid "Assets ZIP File"
msgstr "ทรัพยาà¸à¸£à¹„ฟล์ ZIP"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"ไม่สามารถเลือà¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่จะบันทึà¸à¸ à¸²à¸ž lightmap\n"
"à¸à¸£à¸¸à¸“าบันทึà¸à¸‰à¸²à¸ (เพื่อบันทึà¸à¸ à¸²à¸žà¹ƒà¸™à¹‚ฟลเดอร์เดียวà¸à¸±à¸™) หรือระบุตำà¹à¸«à¸™à¹ˆà¸‡à¹ƒà¸™à¸„ุณสมบัติของ BakedLightmap"
@@ -5078,9 +5110,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "ผิดพลาดขณะสร้างภาพ lightmap à¸à¸£à¸¸à¸“าตรวจสอบว่าสามารถเขียนไฟล์ในตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่บันทึà¸à¹„ด้"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "สร้าง Lightmaps"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "เลือà¸à¹„ฟล์เทมเพลต"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6159,6 +6211,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "สามารถà¸à¸³à¸«à¸™à¸”จุดให้à¹à¸à¹ˆ ParticlesMaterial เท่านั้น"
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ CPUParticles"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "เวลาในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡ (วินาที):"
@@ -6219,10 +6276,6 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ AABB"
msgid "Generate Visibility AABB"
msgstr "สร้างà¸à¸²à¸£à¸¡à¸­à¸‡à¹€à¸«à¹‡à¸™ AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "สร้าง AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "ลบจุดในเส้นโค้ง"
@@ -6808,6 +6861,14 @@ msgstr "ปิดคู่มือ"
msgid "Run"
msgstr "เริ่ม"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "ค้นหา"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "คำสั่งต่อไป"
@@ -6861,16 +6922,6 @@ msgstr ""
"ไฟล์ต่อไปนี้ในดิสà¸à¹Œà¹ƒà¸«à¸¡à¹ˆà¸à¸§à¹ˆà¸²\n"
"จะทำอย่างไรต่อไป?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "โหลดใหม่"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "บันทึà¸à¸­à¸µà¸à¸„รั้ง"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "ตัวดีบัà¸"
@@ -6963,8 +7014,8 @@ msgstr "เบรà¸à¸žà¸­à¸¢à¸•์"
msgid "Go To"
msgstr "ไปยัง"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "ตัด"
@@ -7187,6 +7238,11 @@ msgid "Yaw"
msgstr "Yaw"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "ขนาด: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "ออบเจà¸à¸•์ที่วาด"
@@ -8426,10 +8482,6 @@ msgid "Error"
msgstr "ผิดพลาด"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "ไม่ได้ระบุข้อความ commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "ไม่มีไฟล์เพิ่มไฟยัง stage"
@@ -8486,10 +8538,6 @@ msgid "Stage All"
msgstr "Stage ทั้งหมด"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "เพิ่มข้อความ commit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ commit"
@@ -9659,7 +9707,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "ไม่รองรับโดยไดรเวอร์ GPU ของคุณ"
#: editor/project_manager.cpp
msgid ""
@@ -9828,6 +9876,11 @@ msgid "Projects"
msgstr "โปรเจà¸à¸•์"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸£à¸µà¸¢à¸à¸‚้อมูล โปรดรอ..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "à¹à¸à¹‰à¹„ขล่าสุด"
@@ -10192,6 +10245,11 @@ msgstr "ออโต้โหลด"
msgid "Plugins"
msgstr "ปลั๊à¸à¸­à¸´à¸™"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "โหลดค่าเริ่มต้น"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "พรีเซ็ต..."
@@ -10439,6 +10497,16 @@ msgid "Instance Child Scene"
msgstr "อินสà¹à¸•นซ์ฉาà¸à¸¥à¸¹à¸"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "ทำà¸à¸±à¸šà¹‚หนดของฉาà¸à¸­à¸·à¹ˆà¸™à¹„ม่ได้!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "วางโหนด"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "ค้นพบสคริปต์"
@@ -10564,6 +10632,11 @@ msgid "Attach Script"
msgstr "à¹à¸™à¸šà¸ªà¸„ริปต์"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "ตัดโหนด"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "ลบโหนด"
@@ -11362,6 +11435,39 @@ msgstr "ตัวà¸à¸£à¸­à¸‡ mesh"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "มอบทรัพยาà¸à¸£ MeshLibrary ให้à¸à¸±à¸š GridMap นี้เพื่อใช้ mesh"
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Generate buffers"
+msgstr "สร้าง AABB"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "ทิศทาง"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Indirect lighting"
+msgstr "ย่อหน้าขวา"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "หลังประมวลผล"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "วางà¹à¸™à¸§à¹à¸ªà¸‡:"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "ชื่อคลาสไม่สามารถมีคีย์เวิร์ดได้"
@@ -11860,12 +11966,15 @@ msgid "Select device from the list"
msgstr "เลือà¸à¸­à¸¸à¸›à¸à¸£à¸“์จาà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "ADB executable ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเอดิเตอร์"
+#, fuzzy
+msgid "Unable to find the 'apksigner' tool."
+msgstr "ไม่สามารถหา zipalign tool"
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarsigner ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเอดิเตอร์"
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr "เทมเพลตà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¹à¸­à¸™à¸”รอยด์ไม่ถูà¸à¸•ิดตั้ง สามารถติดตั้งจาà¸à¹€à¸¡à¸™à¸¹à¹‚ปรเจà¸à¸•์"
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -11876,11 +11985,13 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "Release keystore à¸à¸³à¸«à¸™à¸”ค่าไว้อย่างไม่ถูà¸à¸•้องในพรีเซ็ตสำหรับà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸"
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr "à¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เองต้องมีที่อยู่ Android SDK ในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
+#, fuzzy
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "ที่อยู่ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เองในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+#, fuzzy
+msgid "Invalid Android SDK path in Editor Settings."
msgstr "ที่อยู่ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เองในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
#: platform/android/export/export.cpp
@@ -11888,10 +11999,21 @@ msgid "Missing 'platform-tools' directory!"
msgstr "ไดเร็à¸à¸—อรี 'platform-tools' หายไป!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
-msgstr "เทมเพลตà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸³à¸«à¸£à¸±à¸šà¹à¸­à¸™à¸”รอยด์ไม่ถูà¸à¸•ิดตั้ง สามารถติดตั้งจาà¸à¹€à¸¡à¸™à¸¹à¹‚ปรเจà¸à¸•์"
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+#, fuzzy
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr "ที่อยู่ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เองในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "ไดเร็à¸à¸—อรี 'build-tools' หายไป!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12137,6 +12259,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "CollisionPolygon2D ที่ว่างเปล่าจะไม่มีผลทางà¸à¸²à¸¢à¸ à¸²à¸ž"
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12171,23 +12301,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "โหนด A à¹à¸¥à¸° โหนด B จะต้องเป็น PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node A จะต้องเป็น PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node B จะต้องเป็น PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "ข้อต่อไม่ได้เชื่อมโยงà¸à¸±à¸š PhysicsBody2D สองโหนด"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "โหนด A à¹à¸¥à¸°à¹‚หนด B จะต้องเป็น PhysicsBody2D ที่à¹à¸•à¸à¸•่างà¸à¸±à¸™"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12323,28 +12453,32 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin จำเป็นต้องมี ARVRCamera เป็นโหนดลูà¸"
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(เหลืออีà¸: %d:%02d วิ)"
+#, fuzzy
+msgid "Preparing geometry (%d/%d)"
+msgstr "วิเคราะห์พื้นผิว..."
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "วางà¹à¸™à¸§ meshes: "
+#, fuzzy
+msgid "Preparing environment"
+msgstr "à¹à¸ªà¸”งสภาพà¹à¸§à¸”ล้อม"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "วางà¹à¸™à¸§à¹à¸ªà¸‡:"
+#, fuzzy
+msgid "Generating capture"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ Lightmaps"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "เสร็จสิ้นà¸à¸²à¸£à¸§à¸²à¸‡à¹à¸™à¸§"
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ Lightmaps"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "ส่องà¹à¸ªà¸‡à¸šà¸™à¸žà¸·à¹‰à¸™à¸œà¸´à¸§: "
+msgid "Done"
+msgstr "เสร็จสิ้น"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12411,6 +12545,10 @@ msgid "Plotting Meshes"
msgstr "วางà¹à¸™à¸§ meshes"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "เสร็จสิ้นà¸à¸²à¸£à¸§à¸²à¸‡à¹à¸™à¸§"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12418,11 +12556,6 @@ msgstr ""
"ไดรเวอร์วีดีโอ GLES2 ไม่สนับสนุน GIProbe\n"
"ใช้ BakedLightmap à¹à¸—น"
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera เลิà¸à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹à¸¥à¹‰à¸§à¹à¸¥à¸°à¸ˆà¸°à¸–ูà¸à¸¥à¸šà¸­à¸­à¸à¹ƒà¸™ Godot 4.0"
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight ที่มีมุมมาà¸à¸à¸§à¹ˆà¸² 90 ไม่สามารถสร้างเงา"
@@ -12485,23 +12618,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "โหนด A à¹à¸¥à¸°à¹‚หนด B จะต้องเป็น PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Node A จะต้องเป็น PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Node A จะต้องเป็น PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "ข้อต่อไม่ได้เชื่อมโยงà¸à¸±à¸š PhysicsBody ใด ๆ"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "โหนด A à¹à¸¥à¸°à¹‚หนด B จะต้องเป็น PhysicsBody ที่à¹à¸•à¸à¸•่างà¸à¸±à¸™"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12652,6 +12785,14 @@ msgstr "à¹à¸ˆà¹‰à¸‡à¹€à¸•ือน!"
msgid "Please Confirm..."
msgstr "à¸à¸£à¸¸à¸“ายืนยัน..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "นามสà¸à¸¸à¸¥à¹„ฟล์ไม่ถูà¸à¸•้อง"
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "เปิดเส้นà¸à¸£à¸´à¸”มินิà¹à¸¡à¸ž"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12702,6 +12843,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "ขนาดวิวพอร์ตจะต้องมาà¸à¸à¸§à¹ˆà¸² 0 เพื่อที่จะเรนเดอร์ได้"
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "à¹à¸«à¸¥à¹ˆà¸‡à¸—ี่มาไม่ถูà¸à¸•้องสำหรับà¸à¸²à¸£à¹à¸ªà¸”งตัวอย่าง"
@@ -12729,14 +12876,48 @@ msgstr "Varyings สามารถà¸à¸³à¸«à¸™à¸”ในังà¸à¹Œà¸Šà¸±à¸™à¹€
msgid "Constants cannot be modified."
msgstr "ค่าคงที่ไม่สามารถà¹à¸à¹‰à¹„ขได้"
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "มีไฟล์หรือโฟลเดอร์ชื่อเดียวà¸à¸±à¸™à¸­à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§"
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "InterpolatedCamera เลิà¸à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹à¸¥à¹‰à¸§à¹à¸¥à¸°à¸ˆà¸°à¸–ูà¸à¸¥à¸šà¸­à¸­à¸à¹ƒà¸™ Godot 4.0"
+
+#~ msgid "No"
+#~ msgstr "ไม่"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "ฉาà¸à¸™à¸µà¹‰à¸¢à¸±à¸‡à¹„ม่ได้บันทึภบันทึà¸à¸à¹ˆà¸­à¸™à¹€à¸£à¸´à¹ˆà¸¡?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "ADB executable ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเอดิเตอร์"
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarsigner ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเอดิเตอร์"
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr "à¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เองต้องมีที่อยู่ Android SDK ในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(เหลืออีà¸: %d:%02d วิ)"
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "ไดเร็à¸à¸—อรี 'build-tools' หายไป!"
+#~ msgid "Plotting Meshes: "
+#~ msgstr "วางà¹à¸™à¸§ meshes: "
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "ไม่สามารถหา zipalign tool"
+#~ msgid "Lighting Meshes: "
+#~ msgstr "ส่องà¹à¸ªà¸‡à¸šà¸™à¸žà¸·à¹‰à¸™à¸œà¸´à¸§: "
+
+#~ msgid "Search complete"
+#~ msgstr "ค้นหาสำเร็จ"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "ไม่ได้ระบุข้อความ commit"
+
+#~ msgid "Add a commit message"
+#~ msgstr "เพิ่มข้อความ commit"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "มีไฟล์หรือโฟลเดอร์ชื่อเดียวà¸à¸±à¸™à¸­à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§"
#~ msgid "Aligning APK..."
#~ msgstr "จัดเรียง APK..."
@@ -13055,9 +13236,6 @@ msgstr "ค่าคงที่ไม่สามารถà¹à¸à¹‰à¹„ขได
#~ msgid "Failed to save solution."
#~ msgstr "ผิดพลาดในà¸à¸²à¸£à¸šà¸±à¸™à¸—ึภsolution"
-#~ msgid "Done"
-#~ msgstr "เสร็จสิ้น"
-
#~ msgid "Failed to create C# project."
#~ msgstr "ผิดพลาดในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹‚ปรเจà¸à¸•์ C#"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 0d0c2ff2ee..ecd57ee2cd 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -1,6 +1,6 @@
# Turkish translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Aprın Çor Tigin <kabusturk38@gmail.com>, 2016-2017.
# Aykut YILDIRIM <aykutyildirim@windowslive.com>, 2018.
@@ -46,7 +46,7 @@
# Kaan Genç <kaan@kaangenc.me>, 2020.
# Anonymous <noreply@weblate.org>, 2020.
# Güneş Gümüş <gunes.gumus.001@gmail.com>, 2020.
-# OÄŸuz Ersen <oguzersen@protonmail.com>, 2020.
+# OÄŸuz Ersen <oguzersen@protonmail.com>, 2020, 2021.
# Vedat Günel <gunel15@itu.edu.tr>, 2020.
# Ahmet Elgün <ahmetelgn@gmail.com>, 2020.
# Efruz Yıldırır <efruzyildirir@gmail.com>, 2020.
@@ -55,12 +55,14 @@
# Yusuf Osman YILMAZ <wolfkan4219@gmail.com>, 2020.
# furkan atalar <fatalar55@gmail.com>, 2020.
# Suleyman Poyraz <zaryob.dev@gmail.com>, 2020.
+# Çağlar KOPARIR <ckoparir@gmail.com>, 2021.
+# Cem Eren Fukara <cefukara@hotmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-29 08:29+0000\n"
-"Last-Translator: Zsosu Ktosu <zktosu@gmail.com>\n"
+"PO-Revision-Date: 2021-03-03 15:50+0000\n"
+"Last-Translator: OÄŸuz Ersen <oguzersen@protonmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
@@ -68,7 +70,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -697,7 +699,7 @@ msgstr "Kopyalanacak izleri seç"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Kopyala"
@@ -1719,7 +1721,7 @@ msgstr "Dock Nod"
#: editor/editor_feature_profile.cpp
msgid "FileSystem Dock"
-msgstr "Dosya sistemi"
+msgstr "Dosya Sistemi"
#: editor/editor_feature_profile.cpp
msgid "Import Dock"
@@ -1902,8 +1904,8 @@ msgid "Open a File or Directory"
msgstr "Bir Dosya ya da Dizin Aç"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Kaydet"
@@ -1994,10 +1996,6 @@ msgstr "Önizleme:"
msgid "File:"
msgstr "Dosya:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Geçerli bir uzantı kullanılmalı."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "KaynaklarıTara"
@@ -2041,7 +2039,7 @@ msgstr "Çevrimiçi Rehberler"
#: editor/editor_help.cpp
msgid "Properties"
-msgstr "Özellikler"
+msgstr "Özellikleri"
#: editor/editor_help.cpp
msgid "override:"
@@ -2053,7 +2051,7 @@ msgstr "varsayılan:"
#: editor/editor_help.cpp
msgid "Methods"
-msgstr "Yöntemler"
+msgstr "Metotlar"
#: editor/editor_help.cpp
msgid "Theme Properties"
@@ -2433,6 +2431,10 @@ msgid "There is no defined scene to run."
msgstr "Çalıştırmak için herhangi bir sahne seçilmedi."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Çalıştırmadan önce sahneyi kaydedin..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Alt işlem başlatılamadı!"
@@ -2476,18 +2478,6 @@ msgstr "Sahneyi kaydedilmesi için kök düğüm gerekiyor."
msgid "Save Scene As..."
msgstr "Sahneyi Farklı Kaydet..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Hayır"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Evet"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Sahne hiç kaydedilmedi. Çalıştırmadan önce kaydedilsin mi?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Bu işlem bir sahne olmadan yapılamaz."
@@ -2537,6 +2527,10 @@ msgid "Quit"
msgstr "Çıkış"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Evet"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Düzenleyiciden çık?"
@@ -2585,7 +2579,8 @@ msgstr ""
"başarısız oldu."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr "Eklentideki betik alanı bulunamıyor: 'res://addons/%s'."
#: editor/editor_node.cpp
@@ -3016,14 +3011,6 @@ msgid "Help"
msgstr "Yardım"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Ara"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Çevrimiçi Belgeler"
@@ -3189,6 +3176,24 @@ msgid "Open & Run a Script"
msgstr "Aç & Bir Betik Çalıştır"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Aşağıdaki dosyalar diskte daha yeni.\n"
+"Hangi eylem yapılsın?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Yeniden Yükle"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Yeniden Kaydet"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Yeni Örnekleme"
@@ -3400,7 +3405,7 @@ msgstr "Benzersiz Yap"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Yapıştır"
@@ -3761,6 +3766,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Aşağıdaki dosyalar veya klasörler '%s' hedef konumundaki ögelerle "
+"çakışıyor:\n"
+"\n"
+"%s\n"
+"\n"
+"Bunların üzerine yazmak ister misiniz?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3953,8 +3964,16 @@ msgid "Searching..."
msgstr "Aranıyor..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Arama tamamlandı"
+msgid "%d match in %d file."
+msgstr "%d eÅŸleÅŸme %d dosyada."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d eÅŸleÅŸme %d dosyada."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d eÅŸleÅŸme %d dosyada."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4092,6 +4111,21 @@ msgstr "`Post_import ()` yönteminde Node türevi bir nesne döndürdünüz mü?
msgid "Saving..."
msgstr "Kaydediliyor..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Kip Seç"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "İçe Aktar"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Önyüklü sRGB'yi Kullan"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Dosya"
@@ -5059,7 +5093,8 @@ msgid "Got:"
msgstr "Alınan:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+#, fuzzy
+msgid "Failed SHA-256 hash check"
msgstr "Başarısız sha256 hash sınaması"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5163,7 +5198,6 @@ msgid "Sort:"
msgstr "Sırala:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Kategori:"
@@ -5194,12 +5228,10 @@ msgstr "Varlıkların ZIP Dosyası"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
-"Lightmap resimleri için kaydetme yolu belirlenemiyor.\n"
-"Sahneni kaydet (resimler aynı klasöre kaydedilmeli), ya da BakedLightmap "
-"özelliklerinden bir kayıt yolu seçin."
+"Lightmap dosyaları için kaydetme yolu belirlenemiyor.\n"
+"Sahneyi kaydedip tekrar deneyin."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5216,9 +5248,32 @@ msgstr ""
"olduÄŸundan emin olun."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr "Lightmap boyutu belirlenemedi. Lightmap boyutu mu çok küçuk?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"Bazı örgüler geçersiz. [0.0,1.0] bölgesinin UV2 kanal değerlerini "
+"içerdiğinden emin olun."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Godot editör ışın yansıma desteği olmadan derlenmiş, ışık haritaları "
+"piÅŸirilemez."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Işık-Haritalarını Pişir"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Işık Haritası pişirme dosyası seçiniz:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6309,6 +6364,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Nokta sadece ParçacıkMateryal işlem materyalinin içinde ayarlanabilir"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "2BİşlemciPartikül'e dönüştür"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Nesil Süresi (sn):"
@@ -6369,10 +6428,6 @@ msgstr "AABB Üretimi"
msgid "Generate Visibility AABB"
msgstr "Görünebilirlik AABB'si Üret"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "AABB Üret"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Noktayı Eğriden Kaldır"
@@ -6962,6 +7017,14 @@ msgstr "Belgeleri Kapat"
msgid "Run"
msgstr "Çalıştır"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Ara"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "İçeri Adımla"
@@ -7015,16 +7078,6 @@ msgstr ""
"Aşağıdaki dosyalar diskte daha yeni.\n"
"Hangi eylem yapılsın?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Yeniden Yükle"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "Yeniden Kaydet"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Hata Ayıklayıcı"
@@ -7119,8 +7172,8 @@ msgstr "Hata ayıklama noktaları"
msgid "Go To"
msgstr "Åžuna Git"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Kes"
@@ -7343,6 +7396,10 @@ msgid "Yaw"
msgstr "Yalpala"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Boyut"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Çizilmiş Nesneler"
@@ -8592,10 +8649,6 @@ msgid "Error"
msgstr "Hata"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Hiçbir işleme mesajı sağlanmadı"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Sahneye hiç dosya eklenmedi"
@@ -8652,10 +8705,6 @@ msgid "Stage All"
msgstr "Tümünü Sahneye Al"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "İşleme Mesajı Ekle"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "Değişiklikleri İşle"
@@ -9853,7 +9902,7 @@ msgstr "OpenGL ES 3"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "GPU sürücüleriniz tarafından desteklenmiyor."
#: editor/project_manager.cpp
msgid ""
@@ -10031,6 +10080,10 @@ msgid "Projects"
msgstr "Projeler"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "Yükleniyor, lütfen bekleyin..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "Son DeÄŸiÅŸiklik"
@@ -10400,6 +10453,11 @@ msgstr "Otomatik Yükle"
msgid "Plugins"
msgstr "Eklentiler"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Varsayılanı Yükle"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Ön ayar..."
@@ -10649,6 +10707,16 @@ msgid "Instance Child Scene"
msgstr "Çocuk Sahnesini Örnekle"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Yad bir sahnedeki düğümler üzerinde çalışamaz!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Düğümleri Yapıştır"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Betiği Ayır"
@@ -10776,6 +10844,11 @@ msgid "Attach Script"
msgstr "Betik İliştir"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Düğümleri Kes"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Düğümleri Kaldır"
@@ -11579,6 +11652,34 @@ msgstr "Modelleri Süz"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "Model olarak kullanması için bu GridMap'e MeshLibrary kaynağı atayın."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "PiÅŸirmeye BaÅŸla"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Veri yapıları hazırlanıyor"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Arabellek OluÅŸtur"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "Doğrudan aydınlatma"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "Dolaylı aydınlatma"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "Rötuş"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "Işık haritalarını çizme"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Sınıf ismi ayrılmış anahtar kelime olamaz"
@@ -12089,12 +12190,15 @@ msgid "Select device from the list"
msgstr "Listeden aygıt seç"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "Editör Ayarlarında ADB uygulaması tayin edilmemiş."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "'apksigner' aracı bulunamıyor."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "OpenJDK jarimzalayıcı Editör Ayarlarında yapılandırılmamış."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"Android derleme şablonu projede yüklü değil. Proje menüsünden yükleyin."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12109,24 +12213,33 @@ msgstr ""
"serbest bırakın."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr ""
-"Özel derleme için Editör Ayarları'nda geçerli bir Android SDK yolu gerekir."
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "Editör Ayarlarında geçerli bir Android SDK yolu gerekli."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr "Editör Ayarlarında özel derleme için geçersiz Android SDK yolu."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Editör Ayarlarında geçersiz Android SDK yolu."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "Eksik 'platform araçları' dizini!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "Android SDK platform-tools'un adb komutu bulunamıyor."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
msgstr ""
-"Android derleme şablonu projede yüklü değil. Proje menüsünden yükleyin."
+"Lütfen Editör Ayarlarında girilen Android SDK klasörünü kontrol ediniz."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "Eksik 'inşa-araçları' dizini!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "Android SDK platform-tools'un apksigner komutu bulunamıyor."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12386,6 +12499,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Boş bir CollisionPolygon2D'nin çarpışmaya hiçbir etkisi yoktur."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12424,23 +12545,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Düğüm A ve Düğüm B, PhysicsBody2D olmalıdır"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Düğüm A bir PhysicsBody2D olmalıdır"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Düğüm B bir PhysicsBody2D olmalıdır"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Kesişim, iki PhysicsBody2D'ye bağlı değil"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Düğüm A ve Düğüm B, farklı PhysicsBody2D olmalıdır"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12597,28 +12718,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin bir ARVRCamera alt düğümü gerektirir."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Örgü ve ışıkları bulmak"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(Kalan Zaman:%d:%02d sn)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "Geometri hazırlanıyor (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Örüntüler Haritalanıyor: "
+msgid "Preparing environment"
+msgstr "Ortam hazırlanıyor"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Örüntüler Haritalanıyor:"
+msgid "Generating capture"
+msgstr "Yakalama oluÅŸturuluyor"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Haritalama Bitiriliyor"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Işık-haritaları kaydediliyor"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "Örüntüler Haritalanıyor: "
+msgid "Done"
+msgstr "Oldu"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12694,6 +12815,10 @@ msgid "Plotting Meshes"
msgstr "Örüntüler Haritalanıyor"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Haritalama Bitiriliyor"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12701,13 +12826,6 @@ msgstr ""
"GIProbes GLES2 video sürücüsü tarafından desteklenmez.\n"
"Bunun yerine bir BakedLightmap kullanın."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-"InterpolatedCamera kullanımdan kaldırılmıştır ve Godot 4.0'da "
-"kaldırılacaktır."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "90 dereceden geniş açılı SpotIşık gölge oluşturamaz."
@@ -12775,23 +12893,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Düğüm A ve Düğüm B, PhysicsBody olmalıdır"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Düğüm A bir PhysicsBody olmalıdır"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Düğüm B bir PhysicsBody olmalıdır"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Kesişim, herhangi bir PhysicsBody'ye bağlı değil"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Düğüm A ve Düğüm B, farklı PhysicsBody olmalıdır"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12954,6 +13072,14 @@ msgstr "Uyarı!"
msgid "Please Confirm..."
msgstr "Lütfen Doğrulayın..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Geçerli bir uzantı kullanılmalı."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Izgara haritasını etkinleştir."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13008,6 +13134,14 @@ msgstr ""
"Herhangi bir şeyi işlemek için görüntükapısı boyutu 0'dan büyük olmalıdır."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"Örnekleyici bağlantı noktası bağlandı ama kullanılmadı. Kaynağı "
+"'ÖrnekleyiciBağlantıNoktası' olarak değiştirmeyi düşünün."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Önizleme için geçersiz kaynak."
@@ -13035,14 +13169,52 @@ msgstr "varyings yalnızca vertex işlevinde atanabilir."
msgid "Constants cannot be modified."
msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez."
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "Bu konumda zaten aynı ada sahip bir dosya veya klasör var."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "InterpolatedCamera kullanımdan kaldırılmıştır ve Godot 4.0'da "
+#~ "kaldırılacaktır."
+
+#~ msgid "No"
+#~ msgstr "Hayır"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Sahne hiç kaydedilmedi. Çalıştırmadan önce kaydedilsin mi?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "Editör Ayarlarında ADB uygulaması tayin edilmemiş."
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "Eksik 'inşa-araçları' dizini!"
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "OpenJDK jarimzalayıcı Editör Ayarlarında yapılandırılmamış."
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "Zipalign aracı bulunamıyor."
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Özel derleme için Editör Ayarları'nda geçerli bir Android SDK yolu "
+#~ "gerekir."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(Kalan Zaman:%d:%02d sn)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Örüntüler Haritalanıyor: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "Örüntüler Haritalanıyor: "
+
+#~ msgid "Search complete"
+#~ msgstr "Arama tamamlandı"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Hiçbir işleme mesajı sağlanmadı"
+
+#~ msgid "Add a commit message"
+#~ msgstr "İşleme Mesajı Ekle"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "Bu konumda zaten aynı ada sahip bir dosya veya klasör var."
#~ msgid "Aligning APK..."
#~ msgstr "APK hizalanıyor ..."
@@ -13371,9 +13543,6 @@ msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez."
#~ msgid "Failed to save solution."
#~ msgstr "Çözüm kaydetme başarısız."
-#~ msgid "Done"
-#~ msgstr "Oldu"
-
#~ msgid "Failed to create C# project."
#~ msgstr "C# projesi oluşturma başarısız."
@@ -14639,9 +14808,6 @@ msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez."
#~ msgid "Use Default Light"
#~ msgstr "Önyüklü Işık Kullan"
-#~ msgid "Use Default sRGB"
-#~ msgstr "Önyüklü sRGB'yi Kullan"
-
#~ msgid "Default Light Normal:"
#~ msgstr "Önyüklü Işığın Olağanı:"
diff --git a/editor/translations/tzm.po b/editor/translations/tzm.po
index b9c48c5b34..c4614c7eb3 100644
--- a/editor/translations/tzm.po
+++ b/editor/translations/tzm.po
@@ -1,6 +1,6 @@
# Central Atlas Tamazight translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Hakim Oubouali <hakim.oubouali.skr@gmail.com>, 2020.
@@ -626,7 +626,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1795,8 +1795,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1887,10 +1887,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2294,6 +2290,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2337,18 +2337,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2396,6 +2384,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2438,7 +2430,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2828,14 +2820,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -2989,6 +2973,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr ""
@@ -3191,7 +3191,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3727,7 +3727,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3864,6 +3872,18 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+msgid "Select Importer"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Importer:"
+msgstr ""
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
@@ -4811,7 +4831,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -4915,7 +4935,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -4946,8 +4965,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -4961,9 +4979,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr ""
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6019,6 +6056,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr ""
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6079,10 +6120,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6664,6 +6701,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6715,16 +6760,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6817,8 +6852,8 @@ msgstr ""
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7039,6 +7074,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8250,10 +8289,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8310,10 +8345,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9567,6 +9598,10 @@ msgid "Projects"
msgstr ""
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -9927,6 +9962,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10170,6 +10209,14 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr ""
@@ -10290,6 +10337,10 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11074,6 +11125,34 @@ msgstr ""
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11569,11 +11648,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11585,11 +11666,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11597,9 +11678,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -11824,6 +11915,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -11990,27 +12089,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12070,14 +12169,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12283,6 +12381,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12324,6 +12430,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index dd03dac3cf..4cdbe25d02 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -1,9 +1,9 @@
# Ukrainian translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Aleksandr <XpycT.TOP@gmail.com>, 2017.
-# Yuri Chornoivan <yurchor@ukr.net>, 2018, 2019, 2020.
+# Yuri Chornoivan <yurchor@ukr.net>, 2018, 2019, 2020, 2021.
# Ðндрій Бандура <andriykopanytsia@gmail.com>, 2018.
# Гидеон Теон <t.kudely94@gmail.com>, 2017.
# МакÑим Якимчук <xpinovo@gmail.com>, 2018, 2019.
@@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ukrainian (Godot Engine)\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-29 08:29+0000\n"
+"PO-Revision-Date: 2021-02-22 21:30+0000\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/"
"godot/uk/>\n"
@@ -30,7 +30,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -666,7 +666,7 @@ msgstr "Виберіть доріжки Ð´Ð»Ñ ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Копіювати"
@@ -1873,8 +1873,8 @@ msgid "Open a File or Directory"
msgstr "Відкрити файл або каталог"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Зберегти"
@@ -1965,10 +1965,6 @@ msgstr "Попередній переглÑд:"
msgid "File:"
msgstr "Файл:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Ðеобхідно викориÑтовувати допуÑтиме розширеннÑ."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Сканувати Ñирці"
@@ -2404,6 +2400,10 @@ msgid "There is no defined scene to run."
msgstr "Ðемає визначеної Ñцени Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "Зберегти Ñцену перед запуÑком…"
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити підпроцеÑ!"
@@ -2447,18 +2447,6 @@ msgstr "Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб можна було зберегти Ñцену,
msgid "Save Scene As..."
msgstr "Зберегти Ñцену Ñк..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "ÐÑ–"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Так"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Ð¦Ñ Ñцена ніколи не була збережена. Зберегти перед запуÑком?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ може бути виконана без Ñцени."
@@ -2509,6 +2497,10 @@ msgid "Quit"
msgstr "Вийти"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Так"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Вийти з редактора?"
@@ -2556,9 +2548,8 @@ msgstr ""
"налаштуваннÑ."
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
-"Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ поле Ñкрипт Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð»Ð°Ð³Ñ–Ð½Ñƒ в: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ поле Ñкрипту Ð´Ð»Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ° тут: «%s»."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2992,14 +2983,6 @@ msgid "Help"
msgstr "Довідка"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Пошук"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Онлайн документаціÑ"
@@ -3165,6 +3148,24 @@ msgid "Open & Run a Script"
msgstr "Відкрити Ñ– запуÑтити Ñкрипт"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Ðа диÑку зберігаютьÑÑ Ð½Ð¾Ð²Ñ–ÑˆÑ– верÑÑ–Ñ— вказаних нижче файлів.\n"
+"Що Ñлід зробити?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Перезавантажити"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "ПерезапиÑати"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Ðовий уÑпадкований"
@@ -3376,7 +3377,7 @@ msgstr "Зробити унікальним"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Ð’Ñтавити"
@@ -3738,6 +3739,12 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Вказані нижче файли або теки мають такі Ñамі назви, що Ñ– запиÑи у міÑці "
+"Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«%s»:\n"
+"\n"
+"%s\n"
+"\n"
+"Хочете виконати Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ñ… даних?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3930,8 +3937,16 @@ msgid "Searching..."
msgstr "Шукаємо…"
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Пошук завершено"
+msgid "%d match in %d file."
+msgstr "%d відповдіник у %d файлі."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d відповідників у %d файлі."
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d відповідників у %d файлах."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4067,6 +4082,21 @@ msgstr "Повернули об'єкт, що походить від Node, у м
msgid "Saving..."
msgstr "ЗбереженнÑ..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Режим виділеннÑ"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Імпорт"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Завантажити типовий"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d файлів"
@@ -5039,8 +5069,8 @@ msgid "Got:"
msgstr "Отримав:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
-msgstr "Помилка перевірки Ñ…ÐµÑˆÑƒÐ²Ð°Ð½Ð½Ñ sha256"
+msgid "Failed SHA-256 hash check"
+msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ð¹Ñ‚Ð¸ перевірку хешу SHA-256"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5143,7 +5173,6 @@ msgid "Sort:"
msgstr "Сортувати:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "КатегоріÑ:"
@@ -5174,12 +5203,10 @@ msgstr "ZIP файл реÑурÑів"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"Ðе вдаєтьÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ шлÑÑ… Ð´Ð»Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚ оÑвітленнÑ.\n"
-"Збережіть вашу Ñцену (щоб Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¸ збережені в одній теці), або "
-"виберіть шлÑÑ… Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ñƒ влаÑтивоÑÑ‚ÑÑ… BakedLightmap."
+"Збережіть вашу Ñцену Ñ– повторіть Ñпробу."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5196,9 +5223,34 @@ msgstr ""
"запиÑу."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+"Ðе вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ розмір карти оÑвітленнÑ. МакÑимальний розмір карти "
+"оÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ñ” надто малим?"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+"ЧаÑтина Ñітки Ñ” некоректною. ПереконайтеÑÑ, що Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñ–Ð² UV2 "
+"потраплÑють до квадратної облаÑті [0.0,1.0]."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Редактор Godot було зібрано без підтримки траÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ–Ð². Карти "
+"оÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ð½Ðµ вдаÑтьÑÑ Ð¿Ð¾Ð±ÑƒÐ´ÑƒÐ²Ð°Ñ‚Ð¸."
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Запікати карти оÑвітленнÑ"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "Виберіть файл Ð¿Ñ€Ð¸Ð³Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ð¸ оÑвітленнÑ:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6292,6 +6344,10 @@ msgstr ""
"ПоÑтавити точку можна тільки в процедурному матеріалі ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "Перетворити на CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "Ð§Ð°Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ— (Ñек):"
@@ -6352,10 +6408,6 @@ msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ AABB"
msgid "Generate Visibility AABB"
msgstr "Генерувати AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "Генерувати AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "Видалити точку з кривої"
@@ -6948,6 +7000,14 @@ msgstr "Закрити документацію"
msgid "Run"
msgstr "ЗапуÑтити"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Пошук"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "Крок в"
@@ -7001,16 +7061,6 @@ msgstr ""
"Такі файли на диÑку новіші.\n"
"Що робити?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "Перезавантажити"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "ПерезапиÑати"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "Зневаджувач"
@@ -7107,8 +7157,8 @@ msgstr "Точки зупину"
msgid "Go To"
msgstr "Перейти"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Вирізати"
@@ -7331,6 +7381,10 @@ msgid "Yaw"
msgstr "ВідхиленнÑ"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "Розмір"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "Ðамальовано об'єктів"
@@ -8581,10 +8635,6 @@ msgid "Error"
msgstr "Помилка"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "Ðе було вказано Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ внеÑку"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "Ðе додано жодних файлів Ð´Ð»Ñ Ð²Ð½ÐµÑку"
@@ -8641,10 +8691,6 @@ msgid "Stage All"
msgstr "ВнеÑти вÑе"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "Додати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ внеÑку"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "ВнеÑти зміни"
@@ -9850,7 +9896,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "У ваших драйверах підтримки не передбачено."
#: editor/project_manager.cpp
msgid ""
@@ -10030,6 +10076,10 @@ msgid "Projects"
msgstr "Проєкти"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "ЗавантаженнÑ. Будь лаÑка, зачекайте..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "ВоÑтаннє змінено"
@@ -10399,6 +10449,11 @@ msgstr "ÐвтозавантаженнÑ"
msgid "Plugins"
msgstr "Плаґіни (додатки)"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Завантажити типовий"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Заздалегідь уÑтановлений..."
@@ -10650,6 +10705,14 @@ msgid "Instance Child Scene"
msgstr "Створити екземплÑÑ€ дочірньої Ñцени"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "Ðе можна вÑтавлÑти кореневий вузол до Ñцени цього кореневого вузла."
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "Ð’Ñтавити вузли"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "Від'єднати Ñкрипт"
@@ -10776,6 +10839,10 @@ msgid "Attach Script"
msgstr "Долучити Ñкрипт"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "Вирізати вузли"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Вилучити вузли"
@@ -11584,6 +11651,34 @@ msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
"Додайте реÑÑƒÑ€Ñ MeshLibrary до цього GridMap, щоб ÑкориÑтатиÑÑ Ð¹Ð¾Ð³Ð¾ Ñітками."
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "Почати обробку"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "Готуємо Ñтруктури даних"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "Створити буфери"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "БезпоÑереднє оÑвітленнÑ"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "ОпоÑередковане оÑвітленнÑ"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "ПоÑÑ‚-обробка"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "КреÑÐ»ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚ оÑвітленнÑ"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "Ðазвою клаÑу не може бути зарезервоване ключове Ñлово"
@@ -12098,12 +12193,16 @@ msgid "Select device from the list"
msgstr "Вибрати приÑтрій зі ÑпиÑку"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "У параметрах редактора не налаштовано виконуваного файла ADB."
+msgid "Unable to find the 'apksigner' tool."
+msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ програму apksigner."
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "У параметрах редактора не налаштовано jarsigner з OpenJDK."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr ""
+"У проєкті не вÑтановлено шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Android. Ð’Ñтановіть його за "
+"допомогою меню «Проєкт»."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12117,28 +12216,37 @@ msgstr ""
"У шаблоні екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾ налаштовано Ñховище ключів випуÑку."
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
-"Ðетипове Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” коректного шлÑху до SDK Ð´Ð»Ñ Android у параметрах "
-"редактора."
+"У параметрах редактора має бути вказано коректний шлÑÑ… до SDK Ð´Ð»Ñ Android."
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr ""
-"Ðекоректний шлÑÑ… до SDK Ð´Ð»Ñ Android Ð´Ð»Ñ Ð½ÐµÑ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð³Ð¾ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ñƒ параметрах "
-"редактора."
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "Ðекоректний шлÑÑ… до SDK Ð´Ð»Ñ Android у параметрах редактора."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "Ðе знайдено каталогу «platform-tools»!"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
msgstr ""
-"У проєкті не вÑтановлено шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Android. Ð’Ñтановіть його за "
-"допомогою меню «Проєкт»."
+"Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ програми adb із інÑтрументів платформи SDK Ð´Ð»Ñ Android."
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+"Будь лаÑка, перевірте, чи правильно вказано каталог SDK Ð´Ð»Ñ Android у "
+"параметрах редактора."
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "Ðе знайдено каталогу «build-tools»!"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr ""
+"Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ програми apksigner з інÑтрументів Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ SDK Ð´Ð»Ñ Android."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12413,6 +12521,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "Порожній CollisionPolygon2D ніÑк не вплине на зіткненнÑ."
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12450,23 +12566,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Вузол A і вузол B мають бути PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Вузол A має бути PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Вузол B має бути PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ðµ з'єднано із двома PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Вузол A і вузол B мають бути різними PhysicsBody2D"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12625,28 +12741,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin повинен мати дочірній вузол ARVRCamera."
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "Пошук Ñіток та джерел Ñвітла"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(ЛишилоÑÑ Ñ‡Ð°Ñу: %d:%02d Ñ)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "ÐŸÑ€Ð¸Ð³Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð³ÐµÐ¾Ð¼ÐµÑ‚Ñ€Ñ–Ñ— (%d з %d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "Побудова Ñітки: "
+msgid "Preparing environment"
+msgstr "ÐŸÑ€Ð¸Ð³Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñередовища"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "Побудова Ñвітла:"
+msgid "Generating capture"
+msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð°Ñ…Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "Завершальна ділÑнка"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÐ°Ñ€Ñ‚ оÑвітленнÑ"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "ОÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ñітки: "
+msgid "Done"
+msgstr "Зроблено"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12723,6 +12839,10 @@ msgid "Plotting Meshes"
msgstr "Побудова Ñітки"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "Завершальна ділÑнка"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12730,12 +12850,6 @@ msgstr ""
"У драйвері GLES2 не передбачено підтримки GIProbes.\n"
"СкориÑтайтеÑÑ Ð·Ð°Ð¼Ñ–Ñть них BakedLightmap."
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr ""
-"InterpolatedCamera вважаєтьÑÑ Ð·Ð°Ñтарілою, Ñ—Ñ— буде вилучено у Godot 4.0."
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "SpotLight з кутом, Ñкий Ñ” більшим за 90 градуÑів, не може давати тіні."
@@ -12803,23 +12917,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Вузол A і вузол B мають належати до типу PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Вузол A має належати до типу PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Вузол B має належати до типу PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ðµ з'єднано із жодним PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Вузол A і вузол B має бути різними PhysicsBody"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12982,6 +13096,14 @@ msgstr "Увага!"
msgid "Please Confirm..."
msgstr "Будь лаÑка, підтвердьте..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Ðеобхідно викориÑтовувати допуÑтиме розширеннÑ."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "Увімкнути мінікарту ґратки."
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13038,6 +13160,14 @@ msgstr ""
"за 0."
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+"Порт заÑобу ÑÐµÐ¼Ð¿Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð·'єднано, але не викориÑтано. Вам варто змінити "
+"джерело на «SamplerPort»."
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "Ðекоректне джерело Ð´Ð»Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду."
@@ -13065,14 +13195,51 @@ msgstr "Змінні величини можна пов'Ñзувати лише
msgid "Constants cannot be modified."
msgstr "Сталі не можна змінювати."
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "У вказаному каталозі вже міÑтитьÑÑ Ñ‚ÐµÐºÐ° або файл із вказано назвою."
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr ""
+#~ "InterpolatedCamera вважаєтьÑÑ Ð·Ð°Ñтарілою, Ñ—Ñ— буде вилучено у Godot 4.0."
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "Ðе знайдено каталогу «build-tools»!"
+#~ msgid "No"
+#~ msgstr "ÐÑ–"
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ програму zipalign."
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Ð¦Ñ Ñцена ніколи не була збережена. Зберегти перед запуÑком?"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "У параметрах редактора не налаштовано виконуваного файла ADB."
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "У параметрах редактора не налаштовано jarsigner з OpenJDK."
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr ""
+#~ "Ðетипове Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” коректного шлÑху до SDK Ð´Ð»Ñ Android у "
+#~ "параметрах редактора."
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(ЛишилоÑÑ Ñ‡Ð°Ñу: %d:%02d Ñ)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "Побудова Ñітки: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "ОÑÐ²Ñ–Ñ‚Ð»ÐµÐ½Ð½Ñ Ñітки: "
+
+#~ msgid "Search complete"
+#~ msgstr "Пошук завершено"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "Ðе було вказано Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ внеÑку"
+
+#~ msgid "Add a commit message"
+#~ msgstr "Додати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ внеÑку"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "У вказаному каталозі вже міÑтитьÑÑ Ñ‚ÐµÐºÐ° або файл із вказано назвою."
#~ msgid "Aligning APK..."
#~ msgstr "Вирівнюємо APK..."
@@ -13421,9 +13588,6 @@ msgstr "Сталі не можна змінювати."
#~ msgid "Failed to save solution."
#~ msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ розв'Ñзок."
-#~ msgid "Done"
-#~ msgstr "Зроблено"
-
#~ msgid "Failed to create C# project."
#~ msgstr "Ðе вдалоÑÑ Ñтворити проєкт C#."
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index a87c4865c2..a2e1decab6 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -1,6 +1,6 @@
# Urdu (Pakistan) translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
#
# Muhammad Ali <ali@codeonion.com>, 2016.
@@ -636,7 +636,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr ""
@@ -1829,8 +1829,8 @@ msgid "Open a File or Directory"
msgstr ""
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr ""
@@ -1926,10 +1926,6 @@ msgstr ""
msgid "File:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr ""
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2341,6 +2337,10 @@ msgid "There is no defined scene to run."
msgstr ""
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2384,18 +2384,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr ""
-#: editor/editor_node.cpp
-msgid "No"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr ""
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr ""
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2444,6 +2432,10 @@ msgid "Quit"
msgstr ""
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr ""
@@ -2488,7 +2480,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2882,14 +2874,6 @@ msgid "Help"
msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr ""
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr ""
@@ -3045,6 +3029,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
#, fuzzy
msgid "New Inherited"
msgstr "سب سکریپشن بنائیں"
@@ -3252,7 +3252,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr ""
@@ -3802,7 +3802,15 @@ msgid "Searching..."
msgstr ""
#: editor/find_in_files.cpp
-msgid "Search complete"
+msgid "%d match in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr ""
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
msgstr ""
#: editor/groups_editor.cpp
@@ -3942,6 +3950,20 @@ msgstr ""
msgid "Saving..."
msgstr ""
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr ".تمام کا انتخاب"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr ".سپورٹ"
+
+#: editor/import_defaults_editor.cpp
+msgid "Reset to Defaults"
+msgstr ""
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -4913,7 +4935,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5018,7 +5040,6 @@ msgid "Sort:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr ""
@@ -5050,8 +5071,7 @@ msgstr "Ø§Ø«Ø§Ø«Û Ú©ÛŒ زپ ÙØ§Ø¦Ù„"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5065,9 +5085,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr ".تمام کا انتخاب"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6152,6 +6192,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr ".تمام کا انتخاب"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6212,10 +6257,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6815,6 +6856,14 @@ msgstr ""
msgid "Run"
msgstr ""
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr ""
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -6866,16 +6915,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -6972,8 +7011,8 @@ msgstr ".تمام کا انتخاب"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr ""
@@ -7198,6 +7237,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8466,10 +8509,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8532,10 +8571,6 @@ msgid "Stage All"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
@@ -9810,6 +9845,10 @@ msgid "Projects"
msgstr ".تمام کا انتخاب"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr ""
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10175,6 +10214,10 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+msgid "Import Defaults"
+msgstr ""
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10418,6 +10461,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "ایکشن منتقل کریں"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "سب سکریپشن بنائیں"
@@ -10545,6 +10597,11 @@ msgid "Attach Script"
msgstr "سب سکریپشن بنائیں"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "ایکشن منتقل کریں"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11356,6 +11413,35 @@ msgstr "سب سکریپشن بنائیں"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "سب سکریپشن بنائیں"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -11870,11 +11956,13 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -11886,11 +11974,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -11898,9 +11986,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12126,6 +12224,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12292,27 +12398,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12372,14 +12478,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12585,6 +12690,14 @@ msgstr ""
msgid "Please Confirm..."
msgstr ""
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr ""
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12626,6 +12739,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index f08207bd30..94692dc9b2 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -1,6 +1,6 @@
# Vietnamese translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# 01lifeleft <01lifeleft@gmail.com>, 2018.
# Dlean Jeans <dleanjeans@gmail.com>, 2018.
@@ -15,13 +15,15 @@
# Steve Dang <bynguu@outlook.com>, 2020.
# Harry Mitchell <minhyh0987@gmail.com>, 2020.
# HSGamer <huynhqtienvtag@gmail.com>, 2020.
-# LetterC67 <hoangdeptoong@gmail.com>, 2020.
+# LetterC67 <hoangdeptoong@gmail.com>, 2020, 2021.
+# Rev <revolnoom7801@gmail.com>, 2021.
+# SyliawDeV <thanhlongstranger@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-08-11 14:04+0000\n"
-"Last-Translator: LetterC67 <hoangdeptoong@gmail.com>\n"
+"PO-Revision-Date: 2021-03-08 15:33+0000\n"
+"Last-Translator: Rev <revolnoom7801@gmail.com>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/godot-engine/"
"godot/vi/>\n"
"Language: vi\n"
@@ -29,12 +31,13 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.2-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "Hàm convert() có loại đối số không hợp lệ, sử dụng các hằng TYPE_*."
+msgstr ""
+"Hàm convert() có loại đối số không hợp lệ, hãy sử dụng các hằng TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -171,9 +174,8 @@ msgid "Anim Change Call"
msgstr "Äổi Function Gá»i Animation"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Keyframe Time"
-msgstr "Äổi thá»i gian khung hình"
+msgstr "Äổi nhiá»u thá»i gian khung hình"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -206,26 +208,25 @@ msgstr "Chỉnh Vòng Lặp Hoạt Ảnh"
#: editor/animation_track_editor.cpp
msgid "Property Track"
-msgstr ""
+msgstr "Theo dõi đặc tính"
#: editor/animation_track_editor.cpp
msgid "3D Transform Track"
-msgstr ""
+msgstr "Theo dõi chuyển đổi 3D"
#: editor/animation_track_editor.cpp
msgid "Call Method Track"
-msgstr ""
+msgstr "Gá»i phương thức theo dõi"
#: editor/animation_track_editor.cpp
msgid "Bezier Curve Track"
-msgstr ""
+msgstr "Theo dõi đưá»ng cong Bezier"
#: editor/animation_track_editor.cpp
msgid "Audio Playback Track"
-msgstr ""
+msgstr "Bản nhạc phát lại âm thanh"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Playback Track"
msgstr "Ngưng chạy animation. (S)"
@@ -238,7 +239,6 @@ msgid "Animation length (seconds)"
msgstr "Äá»™ dài hoạt ảnh (giây)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Track"
msgstr "Thêm Track Animation"
@@ -257,7 +257,7 @@ msgstr "Âm thanh:"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
-msgstr ""
+msgstr "Hoạt ảnh:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
@@ -265,7 +265,7 @@ msgstr "Thay đổi đưá»ng dẫn Track"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr "Bật tắt track này on/off."
+msgstr "Bật hoặc tắt track này, on/off"
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
@@ -383,7 +383,7 @@ msgstr "Chèn Anim"
#: editor/animation_track_editor.cpp
msgid "AnimationPlayer can't animate itself, only other players."
-msgstr "AnimationPlayer không thể tự tạo hoạt ảnh, chỉ các player khác."
+msgstr "AnimationPlayer không thể tự tạo hoạt ảnh, phải nhỠcác Player khác."
#: editor/animation_track_editor.cpp
msgid "Anim Create & Insert"
@@ -407,7 +407,7 @@ msgstr "Sắp xếp lại Tracks"
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr ""
+msgstr "Các chuyển đổi chỉ có thể áp dụng cho các node Spatial"
#: editor/animation_track_editor.cpp
msgid ""
@@ -416,7 +416,7 @@ msgid ""
"-AudioStreamPlayer2D\n"
"-AudioStreamPlayer3D"
msgstr ""
-"Các bản âm thanh chỉ có thể trỠđến các nút:\n"
+"Các bản âm thanh chỉ có thể trỠđến các loại:\n"
"-AudioStreamPlayer\n"
"-AudioStreamPlayer2D\n"
"-AudioStreamPlayer3D"
@@ -428,10 +428,11 @@ msgstr "Các bản hoạt ảnh chỉ có thể trỠtới các nút AnimationP
#: editor/animation_track_editor.cpp
msgid "An animation player can't animate itself, only other players."
msgstr ""
+"Animation player không tự tạo hoạt ảnh được, phải thông qua các player khác."
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr ""
+msgstr "Không thể thêm track mới mà không có root."
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
@@ -482,14 +483,13 @@ msgid "Paste Tracks"
msgstr "Dán Tracks"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Scale Keys"
-msgstr "Anim Scale Keys"
+msgstr "Key để scale hoạt ảnh"
#: editor/animation_track_editor.cpp
msgid ""
"This option does not work for Bezier editing, as it's only a single track."
-msgstr ""
+msgstr "Tùy chá»n này không áp lên Bezier được, vì nó chỉ là má»™t track."
#: editor/animation_track_editor.cpp
msgid ""
@@ -503,6 +503,16 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
+"Cáianimation này thuộc vỠmột cảnh đã nhập, vì vậy những thay đổi đối với "
+"các bản nhạc đã nhập sẽ không được lưu.\n"
+"\n"
+"Äể bật khả năng thêm các bản nhạc tùy chỉnh, hãy Ä‘iá»u hướng đến cài đặt nhập "
+"của cảnh và đặt\n"
+"\"animation > Lưu trữ\" thành \"Tệp\", bật \"Hoạt hình> Giữ các bản nhạc tùy "
+"chỉnh\", sau đó nhập lại.(vn)\n"
+"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks"
+"\", sau đó nhập lại (english).\n"
+"Hoặc, sử dụng cài đặt trước nhập khẩu nhập hình ảnh động để tách các tệp."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
@@ -536,7 +546,7 @@ msgstr "Giây"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "FPS"
-msgstr ""
+msgstr "Khung hình(FPS)"
#: editor/animation_track_editor.cpp editor/editor_properties.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -554,7 +564,7 @@ msgstr "Thuộc tính hoạt cảnh."
#: editor/animation_track_editor.cpp
msgid "Copy Tracks"
-msgstr ""
+msgstr "Sao Chép Tracks"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
@@ -570,7 +580,7 @@ msgstr "Nhân đôi lá»±a chá»n"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr ""
+msgstr "Chuyển đổi trùng lặp"
#: editor/animation_track_editor.cpp
msgid "Delete Selection"
@@ -598,7 +608,7 @@ msgstr "Chá»n node để được làm diá»…n hoạt:"
#: editor/animation_track_editor.cpp
msgid "Use Bezier Curves"
-msgstr ""
+msgstr "Sá»­ dụng đưá»ng cong Bezier"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
@@ -606,15 +616,15 @@ msgstr "Tối ưu hóa Animation"
#: editor/animation_track_editor.cpp
msgid "Max. Linear Error:"
-msgstr ""
+msgstr "Sai lệch tuyến tính lớn nhất:"
#: editor/animation_track_editor.cpp
msgid "Max. Angular Error:"
-msgstr ""
+msgstr "Sai lệch góc lớn nhất:"
#: editor/animation_track_editor.cpp
msgid "Max Optimizable Angle:"
-msgstr ""
+msgstr "Góc lớn nhất có thể tối ưu:"
#: editor/animation_track_editor.cpp
msgid "Optimize"
@@ -622,7 +632,7 @@ msgstr "Tối ưu"
#: editor/animation_track_editor.cpp
msgid "Remove invalid keys"
-msgstr "Gỡ bỠcác khoá không hợp lệ"
+msgstr "Xóa các khoá không hợp lệ"
#: editor/animation_track_editor.cpp
msgid "Remove unresolved and empty tracks"
@@ -654,14 +664,13 @@ msgstr "Chá»n các Track để sao chép:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "Sao chép"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select All/None"
-msgstr "Chá»n Không có"
+msgstr "Chá»n tất cả/ hoặc không"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
@@ -669,19 +678,19 @@ msgstr "Thêm Track Âm thanh"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr ""
+msgstr "Thay đổi thá»i Ä‘iểm bắt đầu phát track âm thanh."
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
-msgstr ""
+msgstr "Thay đổi thá»i Ä‘iểm kết thúc track âm thanh"
#: editor/array_property_edit.cpp
msgid "Resize Array"
-msgstr "Äổi lại size Array"
+msgstr "Thay đổi kích thước mảng"
#: editor/array_property_edit.cpp
msgid "Change Array Value Type"
-msgstr "Äổi loại giá trị Array"
+msgstr "Äổi kiểu giá trị Array"
#: editor/array_property_edit.cpp
msgid "Change Array Value"
@@ -768,9 +777,8 @@ msgid "Method in target node must be specified."
msgstr "Phương thức trong nút đích phải được chỉ định."
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Method name must be a valid identifier."
-msgstr "Phương thức trong nút đích phải được chỉ định."
+msgstr "Tên phương thức phải được chỉ định."
#: editor/connections_dialog.cpp
msgid ""
@@ -822,9 +830,8 @@ msgid "Extra Call Arguments:"
msgstr "Mở rá»™ng Äối số được gá»i:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Receiver Method:"
-msgstr "Lá»c các nút"
+msgstr "Hàm nhận:"
#: editor/connections_dialog.cpp
msgid "Advanced"
@@ -846,7 +853,7 @@ msgstr "Một lần"
#: editor/connections_dialog.cpp
msgid "Disconnects the signal after its first emission."
-msgstr "Ngắt kết nối tín hiệu sau lần phát xạ đầu tiên."
+msgstr "Ngắt kết nối tín hiệu sau lần phát đầu tiên."
#: editor/connections_dialog.cpp
msgid "Cannot connect signal"
@@ -864,7 +871,7 @@ msgstr "Không thể kết nối tín hiệu"
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Close"
-msgstr "Tắt"
+msgstr "Äóng"
#: editor/connections_dialog.cpp
msgid "Connect"
@@ -912,9 +919,8 @@ msgid "Signals"
msgstr "Tín hiệu (Signal)"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Filter signals"
-msgstr "Lá»c tệp tin ..."
+msgstr "Lá»c tín hiệu"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
@@ -978,7 +984,6 @@ msgid "Search Replacement For:"
msgstr "Tìm kiếm thay thế cho:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Dependencies For:"
msgstr "Phần phụ thuộc cho:"
@@ -1026,7 +1031,7 @@ msgstr "Trình chỉnh sửa Phụ thuộc"
#: editor/dependency_editor.cpp
msgid "Search Replacement Resource:"
-msgstr ""
+msgstr "Tìm kiếm tài nguyên thay thế:"
#: editor/dependency_editor.cpp editor/editor_file_dialog.cpp
#: editor/editor_help_search.cpp editor/editor_node.cpp
@@ -1090,13 +1095,12 @@ msgid "Permanently delete %d item(s)? (No undo!)"
msgstr "Xoá vĩnh viễn các đối tượng %d? (Không thể hoàn lại!)"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Show Dependencies"
-msgstr "Phần phụ thuộc cho:"
+msgstr "Hiện các phần phụ thuộc"
#: editor/dependency_editor.cpp
msgid "Orphan Resource Explorer"
-msgstr ""
+msgstr "Tìm tài nguyên mất gốc"
#: editor/dependency_editor.cpp editor/editor_audio_buses.cpp
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
@@ -1464,15 +1468,15 @@ msgstr ""
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
-msgstr ""
+msgstr "Từ khóa không thể dùng làm tên một nạp tự động."
#: editor/editor_autoload_settings.cpp
msgid "Autoload '%s' already exists!"
-msgstr ""
+msgstr "Nạp tự động '%s' đã tồn tại!"
#: editor/editor_autoload_settings.cpp
msgid "Rename Autoload"
-msgstr ""
+msgstr "Äổi tên"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
@@ -1875,8 +1879,8 @@ msgid "Open a File or Directory"
msgstr "Mở một tệp tin hoặc thư mục"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "Lưu"
@@ -1971,10 +1975,6 @@ msgstr "Xem thá»­:"
msgid "File:"
msgstr "Tệp tin:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "Sử dụng phần mở rộng hợp lệ."
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "Quét nguồn"
@@ -2410,6 +2410,10 @@ msgid "There is no defined scene to run."
msgstr "Không có cảnh được xác định để chạy."
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "Không thể bắt đầu quá trình nhá»!"
@@ -2453,18 +2457,6 @@ msgstr "Yêu cầu một nút gốc khi lưu cảnh."
msgid "Save Scene As..."
msgstr "Lưu Scene với tên..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "Không"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "Có"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "Scene này chưa được lưu. Lưu trước khi chạy?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "Thao tác này phải có scene mới làm được."
@@ -2513,6 +2505,10 @@ msgid "Quit"
msgstr "Thoát"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "Có"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "Thoát trình biên tập?"
@@ -2558,7 +2554,7 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
+msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
#: editor/editor_node.cpp
@@ -2795,9 +2791,8 @@ msgid "Project Settings..."
msgstr "Cài đặt Dá»± Ãn"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Version Control"
-msgstr "Phiên bản:"
+msgstr "Theo dõi phiên bản"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
@@ -2974,14 +2969,6 @@ msgid "Help"
msgstr "Trợ giúp"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "Tìm kiếm"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "Tài liệu trực tuyến"
@@ -2991,9 +2978,8 @@ msgid "Q&A"
msgstr "Há»i và Äáp"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Nhập vào lại"
+msgstr "Báo lỗi"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
@@ -3005,7 +2991,7 @@ msgstr "Cộng đồng"
#: editor/editor_node.cpp
msgid "About"
-msgstr "Thông tin chúng tôi"
+msgstr "VỠchúng tôi"
#: editor/editor_node.cpp
msgid "Play the project."
@@ -3017,7 +3003,7 @@ msgstr "Chạy"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr ""
+msgstr "Dừng chạy Cảnh để gỡ lỗi."
#: editor/editor_node.cpp
msgid "Pause Scene"
@@ -3045,7 +3031,7 @@ msgstr "Chạy Cảnh Tuỳ Chá»n"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
-msgstr "Thay đổi trình Ä‘iá»u kiển Video, yêu cầu khởi động lại Trình biên tập."
+msgstr "Thay đổi trình Ä‘iá»u khiển Video cần phải khởi động lại Trình biên tập."
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
@@ -3057,14 +3043,12 @@ msgid "Spins when the editor window redraws."
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Liên tục"
+msgstr "Cập nhật Liên tục"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "Äối số đã thay đổi"
+msgstr "Cập nhật khi có thay đổi"
#: editor/editor_node.cpp
msgid "Hide Update Spinner"
@@ -3080,7 +3064,7 @@ msgstr "Quan Sát Viên"
#: editor/editor_node.cpp
msgid "Expand Bottom Panel"
-msgstr "Mở rá»™ng bảng Ä‘iá»u khiển phía dưới"
+msgstr "Mở rá»™ng bảng Ä‘iá»u khiển dưới"
#: editor/editor_node.cpp
msgid "Output"
@@ -3109,7 +3093,7 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
-"Äiá»u này sẽ thiết lập dá»± án cá»§a bạn cho các bản dá»±ng Android tùy chỉnh bằng "
+"Việc này sẽ thiết lập dự án của bạn cho các bản dựng Android tùy chỉnh bằng "
"cách cài đặt nguồn mẫu thành \"res://android/build\".\n"
"Bạn có thể áp dụng các sửa đổi và xây dựng APK tùy chỉnh khi xuất (thêm các "
"mô-đun, thay đổi AndroidManifest.xml, ...).\n"
@@ -3148,6 +3132,24 @@ msgid "Open & Run a Script"
msgstr "Mở & Chạy mã lệnh"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"Các tệp sau xuất hiện trên ổ cứng gần đây hơn.\n"
+"Bạn muốn làm gì đây?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "Tải lại"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "Lưu lại"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "Kế thừa mới"
@@ -3184,9 +3186,8 @@ msgid "Open the previous Editor"
msgstr ""
#: editor/editor_node.h
-#, fuzzy
msgid "Warning!"
-msgstr "Cảnh báo"
+msgstr "Cảnh báo!"
#: editor/editor_path.cpp
msgid "No sub-resources found."
@@ -3201,9 +3202,8 @@ msgid "Thumbnail..."
msgstr ""
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Main Script:"
-msgstr "Tạo Script"
+msgstr "Mã lệnh chính:"
#: editor/editor_plugin_settings.cpp
msgid "Edit Plugin"
@@ -3244,7 +3244,7 @@ msgstr ""
#: editor/editor_profiler.cpp
msgid "Average Time (sec)"
-msgstr ""
+msgstr "Thá»i gian trung bình (giây)"
#: editor/editor_profiler.cpp
msgid "Frame %"
@@ -3289,7 +3289,7 @@ msgstr ""
#: editor/editor_properties.cpp
msgid "Bit %d, value %d"
-msgstr ""
+msgstr "Bit %d, giá trị %d"
#: editor/editor_properties.cpp
msgid "[Empty]"
@@ -3355,7 +3355,7 @@ msgstr "Duy nhất"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "Dán"
@@ -3906,8 +3906,19 @@ msgid "Searching..."
msgstr "Äang tìm kiếm ..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "Tìm kiếm hoàn tất"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "Tìm thấy %d khớp."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "Tìm thấy %d khớp."
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "Tìm thấy %d khớp."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4046,6 +4057,21 @@ msgstr ""
msgid "Saving..."
msgstr "Äang lưu ..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "Chế độ chá»n"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "Nhập vào"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "Nạp mặc định"
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -5024,7 +5050,7 @@ msgid "Got:"
msgstr "Nhận được:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5132,7 +5158,6 @@ msgid "Sort:"
msgstr "Sắp xếp:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "Danh mục:"
@@ -5165,8 +5190,7 @@ msgstr "Tệp tin ZIP Nguyên liệu"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5180,9 +5204,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "Chá»n file template"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6282,6 +6326,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "Xóa Animation"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6343,10 +6392,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -6951,6 +6996,14 @@ msgstr "Äóng Docs"
msgid "Run"
msgstr "Chạy"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "Tìm kiếm"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7002,16 +7055,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7110,8 +7153,8 @@ msgstr "Tạo các điểm."
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "Cắt"
@@ -7343,6 +7386,11 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
+msgid "Size"
+msgstr "Kích thước: "
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8617,10 +8665,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8684,10 +8728,6 @@ msgid "Stage All"
msgstr "Chá»n Toàn Bá»™"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "Äổi"
@@ -10011,6 +10051,13 @@ msgid "Projects"
msgstr "Dự án"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr ""
+"Äang quét các tệp tin,\n"
+"ChỠmột chút ..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10381,6 +10428,11 @@ msgstr ""
msgid "Plugins"
msgstr ""
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "Nạp mặc định"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "Cài sẵn ..."
@@ -10635,6 +10687,16 @@ msgstr ""
#: editor/scene_tree_dock.cpp
#, fuzzy
+msgid "Can't paste root node into the same scene."
+msgstr "Không thể hoạt động trên các nút từ ngoại cảnh!"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "Dán các nút"
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Detach Script"
msgstr "Äính kèm Script"
@@ -10762,6 +10824,11 @@ msgid "Attach Script"
msgstr "Äính kèm Script"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "Cắt các nút"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "Xóa các nút"
@@ -11590,6 +11657,36 @@ msgstr "Lá»c các nút"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "Hướng đi"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Post processing"
+msgstr "Phiên bản hiện tại:"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr ""
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12102,12 +12199,16 @@ msgid "Select device from the list"
msgstr ""
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
+"Mẫu xuất bản cho Android chưa được cài đặt trong dự án. Cài đặt nó từ menu "
+"Dá»± Ãn."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -12118,11 +12219,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12130,12 +12231,20 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
-"Mẫu xuất bản cho Android chưa được cài đặt trong dự án. Cài đặt nó từ menu "
-"Dá»± Ãn."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12375,6 +12484,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12541,27 +12658,27 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
+msgid "Generating capture"
msgstr ""
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12621,14 +12738,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -12836,6 +12952,14 @@ msgstr "Cảnh báo!"
msgid "Please Confirm..."
msgstr "Xin hãy xác nhận..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "Sử dụng phần mở rộng hợp lệ."
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
#, fuzzy
msgid ""
@@ -12883,6 +13007,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "nguồn vô hiệu cho xem trước"
@@ -12911,6 +13041,15 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr "Không thể chỉnh sửa hằng số."
+#~ msgid "No"
+#~ msgstr "Không"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "Scene này chưa được lưu. Lưu trước khi chạy?"
+
+#~ msgid "Search complete"
+#~ msgstr "Tìm kiếm hoàn tất"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "Äã có tệp tin hoặc thư mục cùng tên tại vị trí này."
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index bd6c730382..ac2d4a61f6 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -1,6 +1,6 @@
# Chinese (Simplified) translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# 360119124 <360119124@qq.com>, 2018.
# æŸ æª¬æ€æ‰‹ <lemonkiller@gmail.com>, 2018, 2020.
@@ -43,7 +43,7 @@
# Song DongHui <14729626293@163.com>, 2019.
# simano clio <sim2cle@gmail.com>, 2019.
# ByonkoGalilei <byonko@qq.com>, 2019.
-# qjyqjyqjyqjy <qjyqjyqjyqjy@sina.com.cn>, 2019.
+# qjyqjyqjyqjy <qjyqjyqjyqjy@sina.com.cn>, 2019, 2021.
# liushuyu011 <liushuyu011@gmail.com>, 2019.
# DS <dseqrasd@126.com>, 2019.
# ZeroAurora <zeroaurora@qq.com>, 2019.
@@ -58,7 +58,7 @@
# idleman <1524328475@qq.com>, 2019.
# king <wangding1992@126.com>, 2019.
# silentbird <silentbird520@outlook.com>, 2019.
-# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020.
+# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020, 2021.
# Revan Ji <jiruifancr@gmail.com>, 2020.
# nieyuanhong <15625988003@163.com>, 2020.
# binotaliu <binota@protonmail.ch>, 2020.
@@ -71,13 +71,17 @@
# MintSoda <lionlxh@qq.com>, 2020.
# Gardner Belgrade <hapenia@sina.com>, 2020.
# godhidden <z2zz2zz@yahoo.com>, 2020.
-# BinotaLIU <me@binota.org>, 2020.
+# BinotaLIU <me@binota.org>, 2020, 2021.
# TakWolf <takwolf@foxmail.com>, 2020.
+# twoBornottwoB <305766341@qq.com>, 2021.
+# Magian <magian1127@gmail.com>, 2021.
+# Weiduo Xie <xwditfr@gmail.com>, 2021.
+# suplife <2634557184@qq.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2020-11-29 08:29+0000\n"
+"PO-Revision-Date: 2021-03-08 15:33+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
@@ -86,7 +90,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -95,13 +99,13 @@ 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 的字符串(1 字符)。"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr "没有足够的字节å¯è§£ç æˆ–æ ¼å¼æ— æ•ˆã€‚"
+msgstr "è§£ç å­—节数ä¸å¤Ÿï¼Œæˆ–æ ¼å¼æ— æ•ˆã€‚"
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -707,7 +711,7 @@ msgstr "选择è¦å¤åˆ¶çš„轨é“"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "å¤åˆ¶"
@@ -1895,8 +1899,8 @@ msgid "Open a File or Directory"
msgstr "打开文件或目录"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "ä¿å­˜"
@@ -1987,10 +1991,6 @@ msgstr "预览:"
msgid "File:"
msgstr "文件:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "必须使用有效的扩展å。"
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "æ‰«ææºæ–‡ä»¶"
@@ -2242,7 +2242,7 @@ msgstr "å¯¼å…¥çš„èµ„æºæ— æ³•ä¿å­˜ã€‚"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
msgid "OK"
-msgstr "好"
+msgstr "确定"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
@@ -2413,6 +2413,10 @@ msgid "There is no defined scene to run."
msgstr "没有设置è¦è¿è¡Œçš„场景。"
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "è¿è¡Œå‰ä¿å­˜åœºæ™¯..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "无法å¯åЍå­è¿›ç¨‹ï¼"
@@ -2456,18 +2460,6 @@ msgstr "必须有根节点æ‰å¯ä¿å­˜åœºæ™¯ã€‚"
msgid "Save Scene As..."
msgstr "场景å¦å­˜ä¸º..."
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "å¦"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "是"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "此场景尚未ä¿å­˜ã€‚是å¦åœ¨è¿è¡Œå‰ä¿å­˜ï¼Ÿ"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "必须先打开一个场景æ‰èƒ½å®Œæˆæ­¤æ“作。"
@@ -2517,6 +2509,10 @@ msgid "Quit"
msgstr "退出"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "是"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "确定è¦é€€å‡ºç¼–辑器å—?"
@@ -2559,8 +2555,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "无法在 “%s†上å¯ç”¨åŠ è½½é¡¹æ’件:é…置解æžå¤±è´¥ã€‚"
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr "无法在 “res://addons/%s†中找到加载项æ’件的脚本字段。"
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "无法在 “%s†上找到加载项的 script 字段。"
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2971,14 +2967,6 @@ msgid "Help"
msgstr "帮助"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "æœç´¢"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "在线文档"
@@ -3070,7 +3058,7 @@ msgstr "文件系统"
#: editor/editor_node.cpp
msgid "Inspector"
-msgstr "属性检查器"
+msgstr "检查器"
#: editor/editor_node.cpp
msgid "Expand Bottom Panel"
@@ -3140,6 +3128,24 @@ msgid "Open & Run a Script"
msgstr "打开并è¿è¡Œè„šæœ¬"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"ç£ç›˜ä¸­çš„下列文件较新。\n"
+"应该执行什么æ“作?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "釿–°åŠ è½½"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "釿–°ä¿å­˜"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "新建继承"
@@ -3346,7 +3352,7 @@ msgstr "唯一化"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "粘贴"
@@ -3698,6 +3704,11 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"下列文件或文件夹与目标路径 “%s†中的项目冲çªï¼š\n"
+"\n"
+"%s\n"
+"\n"
+"è¦å¤å†™è¿™äº›æ–‡ä»¶æˆ–文件夹å—?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3775,7 +3786,7 @@ msgstr "全部折å "
#: editor/filesystem_dock.cpp
msgid "Duplicate..."
-msgstr "é‡å¤..."
+msgstr "å¤åˆ¶ä¸º..."
#: editor/filesystem_dock.cpp
msgid "Move to Trash"
@@ -3888,8 +3899,16 @@ msgid "Searching..."
msgstr "æœç´¢ä¸­..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "æœç´¢å®Œæ¯•"
+msgid "%d match in %d file."
+msgstr "%d 处匹é…,共 %d 个文件。"
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d 处匹é…,共 %d 个文件。"
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d 处匹é…,共 %d 个文件。"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4025,6 +4044,21 @@ msgstr "有在 `post_import()` 方法中返回继承了 Node 的对象å—?"
msgid "Saving..."
msgstr "ä¿å­˜ä¸­..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "选择模å¼"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "导入"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "使用默认sRGB"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d 个文件"
@@ -4586,7 +4620,7 @@ msgstr "编辑过渡方å¼..."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Open in Inspector"
-msgstr "在属性检查器中打开"
+msgstr "在检查器中打开"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
@@ -4685,7 +4719,7 @@ msgstr "过渡已存在ï¼"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Add Transition"
-msgstr "添加转æ¢"
+msgstr "添加过渡"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -4726,7 +4760,7 @@ msgstr "节点已移除"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Transition Removed"
-msgstr "转æ¢å·²ç§»é™¤"
+msgstr "过渡已移除"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
@@ -4949,7 +4983,7 @@ msgstr "无法将å“应ä¿å­˜åˆ°ï¼š"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Write error."
-msgstr "写错误。"
+msgstr "写入错误。"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
@@ -4980,7 +5014,7 @@ msgid "Got:"
msgstr "获得:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr "SHA-256 哈希值校验失败"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5084,7 +5118,6 @@ msgid "Sort:"
msgstr "排åºï¼š"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "分类:"
@@ -5115,8 +5148,7 @@ msgstr "ç´ æ ZIP 文件"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"无法确定光照贴图的ä¿å­˜è·¯å¾„。\n"
"请先ä¿å­˜åœºæ™¯ï¼ˆå…‰ç…§è´´å›¾å°†è¢«å­˜åœ¨åŒä¸€ç›®å½•ä¸‹ï¼‰æˆ–ä»Žå±žæ€§é¢æ¿ä¸­æ‰‹åЍä¿å­˜ "
@@ -5133,9 +5165,28 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "åˆ›å»ºå…‰ç…§è´´å›¾å¤±è´¥ï¼Œåˆ‡ç¡®ä¿æ–‡ä»¶æ˜¯å¯å†™çš„。"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr "无法确定光照贴图大å°ã€‚最大光照贴图大å°å¤ªå°ï¼Ÿ"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr "æŸäº›ç½‘格无效。确ä¿UV2通é“值包å«åœ¨[0.0,1.0]平方区域内。"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr "Godot编辑器是在没有光线跟踪支æŒçš„æƒ…况下构建的,光照贴图无法烘焙。"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "烘焙光照贴图"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "选择光照贴图烘焙文件:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -5787,7 +5838,7 @@ msgstr "å‘射色彩"
#: editor/plugins/cpu_particles_editor_plugin.cpp
msgid "CPUParticles"
-msgstr "CPUParticles"
+msgstr "CPUç²’å­"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
@@ -5801,11 +5852,11 @@ msgstr "从节点创建å‘射点"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Flat 0"
-msgstr "Flat 0"
+msgstr "å¹³é¢ 0"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Flat 1"
-msgstr "Flat 1"
+msgstr "å¹³é¢ 1"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease In"
@@ -6214,6 +6265,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "åªå¯è®¾ä¸ºæŒ‡å‘ ParticlesMaterial å¤„ç†ææ–™"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "转æ¢ä¸ºCPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "ç”Ÿæˆæ—¶é—´ï¼ˆç§’):"
@@ -6274,10 +6329,6 @@ msgstr "æ­£åœ¨ç”Ÿæˆ AABB"
msgid "Generate Visibility AABB"
msgstr "生æˆå¯è§çš„ AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "ç”Ÿæˆ AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "从曲线中移除顶点"
@@ -6861,6 +6912,14 @@ msgstr "关闭文档"
msgid "Run"
msgstr "è¿è¡Œ"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "æœç´¢"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "啿­¥è¿›å…¥"
@@ -6914,16 +6973,6 @@ msgstr ""
"ç£ç›˜ä¸­çš„下列文件已更新。\n"
"请选择执行哪项æ“作?:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "釿–°åŠ è½½"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "釿–°ä¿å­˜"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "调试器"
@@ -7016,8 +7065,8 @@ msgstr "断点"
msgid "Go To"
msgstr "转到"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "剪切"
@@ -7240,6 +7289,10 @@ msgid "Yaw"
msgstr "å航角"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "大å°"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "绘制对象"
@@ -8282,7 +8335,7 @@ msgstr "ä¿æŒå¤šè¾¹å½¢ä½äºŽçº¹ç†åŒºåŸŸä¸­ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
-msgstr "å¯ç”¨å¸é™„并显示网格(å¯é€šè¿‡å±žæ€§æ£€æŸ¥å™¨è®¾ç½®ï¼‰ã€‚"
+msgstr "å¯ç”¨å¸é™„并显示网格(å¯é€šè¿‡æ£€æŸ¥å™¨è®¾ç½®ï¼‰ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Display Tile Names (Hold Alt Key)"
@@ -8479,10 +8532,6 @@ msgid "Error"
msgstr "错误"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "没有æä¾›æäº¤æ¶ˆæ¯"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "没有文件被添加到暂存区"
@@ -8539,10 +8588,6 @@ msgid "Stage All"
msgstr "暂存全部"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "添加æäº¤æ¶ˆæ¯"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "æäº¤å˜æ›´"
@@ -9705,7 +9750,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "所使用的 GPU é©±åŠ¨ä¸æ”¯æŒã€‚"
#: editor/project_manager.cpp
msgid ""
@@ -9873,6 +9918,10 @@ msgid "Projects"
msgstr "项目"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "正在加载,请ç¨å€™..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "修改时间"
@@ -10238,6 +10287,11 @@ msgstr "自动加载"
msgid "Plugins"
msgstr "æ’ä»¶"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "加载默认"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "预设..."
@@ -10485,6 +10539,14 @@ msgid "Instance Child Scene"
msgstr "实例化å­åœºæ™¯"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "ä¸èƒ½å°†æ ¹èŠ‚ç‚¹ç²˜è´´è¿›ç›¸åŒåœºæ™¯ã€‚"
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "粘贴节点"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "分离脚本"
@@ -10607,6 +10669,10 @@ msgid "Attach Script"
msgstr "添加脚本"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "剪切节点"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "移除节点"
@@ -11405,6 +11471,34 @@ msgstr "筛选网格"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "呿­¤ GridMap æä¾›ç½‘格库资æºä»¥ä½¿ç”¨å…¶ç½‘格。"
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "开始烘焙"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "准备数æ®ç»“æž„"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "生æˆç¼“冲区"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "直接照明"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "间接照明"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "åŽå¤„ç†"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "绘制光照图"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "ç±»åä¸èƒ½æ˜¯ä¿ç•™å…³é”®å­—"
@@ -11904,12 +11998,14 @@ msgid "Select device from the list"
msgstr "从列表中选择设备"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "未在编辑器设置中é…ç½® ADB 坿‰§è¡Œæ–‡ä»¶ã€‚"
+msgid "Unable to find the 'apksigner' tool."
+msgstr "找ä¸åˆ°â€œapksignerâ€å·¥å…·ã€‚"
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "未在编辑器设置中é…ç½® OpenJDK Jarsigner。"
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr "未在项目中安装 Android 构建模æ¿ã€‚从项目èœå•安装它。"
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -11920,22 +12016,32 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "用于å‘布的密钥存储在导出预设中未被正确设置。"
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr "自定义构建需è¦åœ¨ “编辑器设置†中使用有效的 Android SDK 路径。"
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "ç¼–è¾‘å™¨è®¾ç½®ä¸­éœ€è¦æœ‰æ•ˆçš„Android SDK路径。"
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr "用于 “编辑器设置†中自定义构建的 Android SDK 路径是无效的。"
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "编辑器设置中的Android SDK路径无效。"
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "缺失“platform-toolsâ€ç›®å½•ï¼"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
-msgstr "未在项目中安装 Android 构建模æ¿ã€‚从项目èœå•安装它。"
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "找ä¸åˆ°Android SDKå¹³å°å·¥å…·çš„adb命令。"
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr "请签入编辑器设置中指定的Android SDK目录。"
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "缺失“build-toolsâ€ç›®å½•ï¼"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "找ä¸åˆ°Android SDK生æˆå·¥å…·çš„apksigner命令。"
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12178,6 +12284,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "空的 CollisionPolygon2D ä¸èµ·ä»»ä½•碰撞检测作用。"
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12211,23 +12325,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A 与 Node B 必须为 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node A 必须为 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node B 必须为 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Joint 未连结到 2 个 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A 与 Node B 必须为ä¸åŒçš„ PhysicsBody2D"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12364,28 +12478,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin 需è¦ä¸€ä¸ª ARVRCamera å­èŠ‚ç‚¹ã€‚"
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "正在查找网格和ç¯å…‰"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(剩余时间:%d:%02d 秒)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "正在准备几何体(%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "正在绘制网格: "
+msgid "Preparing environment"
+msgstr "正在准备环境"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "正在绘制ç¯å…‰ï¼š"
+msgid "Generating capture"
+msgstr "æ­£åœ¨ç”Ÿæˆæ•获"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "正在完æˆåˆ’分"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "正在ä¿å­˜å…‰ç…§è´´å›¾"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "正在对网格进行照明 "
+msgid "Done"
+msgstr "完æˆ"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12453,6 +12567,10 @@ msgid "Plotting Meshes"
msgstr "正在绘制网格"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "正在完æˆåˆ’分"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12460,11 +12578,6 @@ msgstr ""
"GLES2 视频驱动程åºä¸æ”¯æŒ GIProbes。\n"
"请改用 BakedLightmap。"
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera 已废弃,将在 Godot 4.0 中删除。"
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "角度宽于 90 度的 SpotLight 无法投射出阴影。"
@@ -12527,23 +12640,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Node A 与 Node B 必须为 PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Node A 必须为 PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Node B 必须为 PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Joint 未连结到任何 PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Node A 与 Node B 必须为ä¸åŒçš„ PhysicsBody"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12697,6 +12810,14 @@ msgstr "警告ï¼"
msgid "Please Confirm..."
msgstr "请确认..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "必须使用有效的扩展å。"
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "å¯ç”¨ç½‘æ ¼å°åœ°å›¾ã€‚"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12748,6 +12869,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "Viewport 大å°å¤§äºŽ 0 æ—¶æ‰èƒ½è¿›è¡Œæ¸²æŸ“。"
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr "采样器端å£å·²è¿žæŽ¥ä½†æœªä½¿ç”¨ã€‚è€ƒè™‘å°†æºæ›´æ”¹ä¸ºâ€œSamplerPortâ€ã€‚"
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "预览的æºèµ„æºæ— æ•ˆã€‚"
@@ -12775,14 +12902,48 @@ msgstr "å˜é‡åªèƒ½åœ¨é¡¶ç‚¹å‡½æ•°ä¸­æŒ‡å®šã€‚"
msgid "Constants cannot be modified."
msgstr "ä¸å…许修改常é‡ã€‚"
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "当å‰ä½ç½®å·²å­˜åœ¨åŒå文件或文件夹。"
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "InterpolatedCamera 已废弃,将在 Godot 4.0 中删除。"
+
+#~ msgid "No"
+#~ msgstr "å¦"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "此场景尚未ä¿å­˜ã€‚是å¦åœ¨è¿è¡Œå‰ä¿å­˜ï¼Ÿ"
+
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "未在编辑器设置中é…ç½® ADB 坿‰§è¡Œæ–‡ä»¶ã€‚"
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "未在编辑器设置中é…ç½® OpenJDK Jarsigner。"
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "缺失“build-toolsâ€ç›®å½•ï¼"
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr "自定义构建需è¦åœ¨ “编辑器设置†中使用有效的 Android SDK 路径。"
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "未找到 zipalign 工具。"
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(剩余时间:%d:%02d 秒)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "正在绘制网格: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "正在对网格进行照明 "
+
+#~ msgid "Search complete"
+#~ msgstr "æœç´¢å®Œæ¯•"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "没有æä¾›æäº¤æ¶ˆæ¯"
+
+#~ msgid "Add a commit message"
+#~ msgstr "添加æäº¤æ¶ˆæ¯"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "当å‰ä½ç½®å·²å­˜åœ¨åŒå文件或文件夹。"
#~ msgid "Aligning APK..."
#~ msgstr "å¯¹é½ APK..."
@@ -13117,9 +13278,6 @@ msgstr "ä¸å…许修改常é‡ã€‚"
#~ msgid "Failed to save solution."
#~ msgstr "ä¿å­˜è§£å†³æ–¹æ¡ˆå¤±è´¥ã€‚"
-#~ msgid "Done"
-#~ msgstr "完æˆ"
-
#~ msgid "Failed to create C# project."
#~ msgstr "创建C#项目失败。"
@@ -14395,9 +14553,6 @@ msgstr "ä¸å…许修改常é‡ã€‚"
#~ msgid "Use Default Light"
#~ msgstr "使用默认光照"
-#~ msgid "Use Default sRGB"
-#~ msgstr "使用默认sRGB"
-
#~ msgid "Default Light Normal:"
#~ msgstr "默认光照法线:"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index b3faa76c3c..2009ba8f20 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -1,6 +1,6 @@
# Chinese (Hong Kong) translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Wesley (zx-wt) <ZX_WT@ymail.com>, 2016-2017, 2020.
# cnieFIT <dtotncq@gmail.com>, 2019.
@@ -682,7 +682,7 @@ msgstr "鏿“‡æ¨¡å¼"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "複製"
@@ -1922,8 +1922,8 @@ msgid "Open a File or Directory"
msgstr "鏿“‡è³‡æ–™å¤¾/檔案"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "儲存"
@@ -2022,10 +2022,6 @@ msgstr "é è¦½:"
msgid "File:"
msgstr "檔案:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "請用有效的副檔å。"
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr ""
@@ -2452,6 +2448,10 @@ msgid "There is no defined scene to run."
msgstr "沒有å¯ä»¥å·²å®šç¾©çš„場景å¯ä»¥é‹è¡Œã€‚"
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr ""
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr ""
@@ -2499,18 +2499,6 @@ msgstr ""
msgid "Save Scene As..."
msgstr "把場景å¦å­˜ç‚º"
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "å¦"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "是"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "此場景從未儲存。è¦åœ¨é‹è¡Œå‰å„²å­˜å—Ž?"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr ""
@@ -2559,6 +2547,10 @@ msgid "Quit"
msgstr "離開"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "是"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "è¦é›¢é–‹ç·¨è¼¯å™¨å—Ž?"
@@ -2606,8 +2598,9 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr ""
+#, fuzzy
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "載入字形出ç¾éŒ¯èª¤"
#: editor/editor_node.cpp
#, fuzzy
@@ -3037,14 +3030,6 @@ msgid "Help"
msgstr "幫助"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "æœå°‹"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
#, fuzzy
msgid "Online Docs"
@@ -3207,6 +3192,22 @@ msgid "Open & Run a Script"
msgstr ""
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr ""
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr ""
+
+#: editor/editor_node.cpp
#, fuzzy
msgid "New Inherited"
msgstr "下一個腳本"
@@ -3424,7 +3425,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "貼上"
@@ -4017,8 +4018,19 @@ msgid "Searching..."
msgstr "æœå°‹ä¸­..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "æœå°‹å®Œæˆ"
+#, fuzzy
+msgid "%d match in %d file."
+msgstr "%d 相åŒã€‚"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d file."
+msgstr "%d 相åŒã€‚"
+
+#: editor/find_in_files.cpp
+#, fuzzy
+msgid "%d matches in %d files."
+msgstr "%d 相åŒã€‚"
#: editor/groups_editor.cpp
#, fuzzy
@@ -4161,6 +4173,21 @@ msgstr ""
msgid "Saving..."
msgstr "儲存中..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "鏿“‡æ¨¡å¼"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "å°Žå…¥"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "é è¨­"
+
#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
@@ -5187,7 +5214,7 @@ msgid "Got:"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5301,7 +5328,6 @@ msgid "Sort:"
msgstr "排åºï¼š"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "分類:"
@@ -5334,8 +5360,7 @@ msgstr "Assets ZIP 檔"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -5349,9 +5374,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr ""
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+#, fuzzy
+msgid "Select lightmap bake file:"
+msgstr "é¸å–Template檔案"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6458,6 +6503,11 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
+#, fuzzy
+msgid "Convert to CPUParticles2D"
+msgstr "轉為..."
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr ""
@@ -6518,10 +6568,6 @@ msgstr ""
msgid "Generate Visibility AABB"
msgstr ""
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr ""
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr ""
@@ -7141,6 +7187,14 @@ msgstr "關閉場景"
msgid "Run"
msgstr "é‹è¡Œ"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "æœå°‹"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr ""
@@ -7195,16 +7249,6 @@ msgid ""
"What action should be taken?:"
msgstr ""
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr ""
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr ""
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr ""
@@ -7306,8 +7350,8 @@ msgstr "刪除"
msgid "Go To"
msgstr ""
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "剪下"
@@ -7546,6 +7590,10 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr ""
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr ""
@@ -8858,10 +8906,6 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr ""
@@ -8926,10 +8970,6 @@ msgid "Stage All"
msgstr "å…¨é¸"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Commit Changes"
msgstr "åŒæ­¥æ›´æ–°è…³æœ¬"
@@ -10236,6 +10276,11 @@ msgid "Projects"
msgstr "專案"
#: editor/project_manager.cpp
+#, fuzzy
+msgid "Loading, please wait..."
+msgstr "接收 mirrors中, è«‹ç¨ä¾¯..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr ""
@@ -10612,6 +10657,11 @@ msgstr ""
msgid "Plugins"
msgstr "æ’ä»¶"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "é è¨­"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr ""
@@ -10870,6 +10920,15 @@ msgid "Instance Child Scene"
msgstr ""
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr ""
+
+#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Paste Node(s)"
+msgstr "貼上"
+
+#: editor/scene_tree_dock.cpp
#, fuzzy
msgid "Detach Script"
msgstr "腳本"
@@ -11004,6 +11063,11 @@ msgid "Attach Script"
msgstr "腳本"
#: editor/scene_tree_dock.cpp
+#, fuzzy
+msgid "Cut Node(s)"
+msgstr "貼上"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr ""
@@ -11849,6 +11913,36 @@ msgstr "篩é¸:"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr ""
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Direct lighting"
+msgstr "æè¿°ï¼š"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr ""
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+#, fuzzy
+msgid "Plotting lightmaps"
+msgstr "光照圖生æˆä¸­"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr ""
@@ -12378,11 +12472,13 @@ msgid "Select device from the list"
msgstr "從列表é¸å–設備"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
+msgid "Unable to find the 'apksigner' tool."
msgstr ""
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
msgstr ""
#: platform/android/export/export.cpp
@@ -12394,11 +12490,11 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
+msgid "A valid Android SDK path is required in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
+msgid "Invalid Android SDK path in Editor Settings."
msgstr ""
#: platform/android/export/export.cpp
@@ -12406,9 +12502,19 @@ msgid "Missing 'platform-tools' directory!"
msgstr ""
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr ""
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
msgstr ""
#: platform/android/export/export.cpp
@@ -12648,6 +12754,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr ""
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12814,27 +12928,29 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
+msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
+msgid "Preparing geometry (%d/%d)"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
+msgid "Preparing environment"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr ""
+#, fuzzy
+msgid "Generating capture"
+msgstr "光照圖生æˆä¸­"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr ""
+#: scene/3d/baked_lightmap.cpp
+#, fuzzy
+msgid "Saving lightmaps"
+msgstr "光照圖生æˆä¸­"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
+msgid "Done"
msgstr ""
#: scene/3d/collision_object.cpp
@@ -12894,14 +13010,13 @@ msgid "Plotting Meshes"
msgstr ""
#: scene/3d/gi_probe.cpp
-msgid ""
-"GIProbes are not supported by the GLES2 video driver.\n"
-"Use a BakedLightmap instead."
+msgid "Finishing Plot"
msgstr ""
-#: scene/3d/interpolated_camera.cpp
+#: scene/3d/gi_probe.cpp
msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+"GIProbes are not supported by the GLES2 video driver.\n"
+"Use a BakedLightmap instead."
msgstr ""
#: scene/3d/light.cpp
@@ -13111,6 +13226,14 @@ msgstr "警告!"
msgid "Please Confirm..."
msgstr "請確èª..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "請用有效的副檔å。"
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr ""
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -13153,6 +13276,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "viewport大å°å¿…須大於ï¼ä»¥æ¸²æŸ“任何æ±è¥¿ã€‚"
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr ""
+
+#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
msgstr "é è¦½ä¾†è‡ªç„¡æ•ˆä¾†æºã€‚"
@@ -13181,6 +13310,15 @@ msgstr ""
msgid "Constants cannot be modified."
msgstr ""
+#~ msgid "No"
+#~ msgstr "å¦"
+
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "此場景從未儲存。è¦åœ¨é‹è¡Œå‰å„²å­˜å—Ž?"
+
+#~ msgid "Search complete"
+#~ msgstr "æœå°‹å®Œæˆ"
+
#~ msgid "There is already file or folder with the same name in this location."
#~ msgstr "æ­¤ä½ç½®å·²å­˜åœ¨åŒå的檔案或資料夾。"
@@ -13365,10 +13503,6 @@ msgstr ""
#~ msgstr "新增資料夾"
#, fuzzy
-#~ msgid "Custom Node"
-#~ msgstr "貼上"
-
-#, fuzzy
#~ msgid "Invalid Path"
#~ msgstr "有效的路徑"
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index dc3c1f49f7..5708d11522 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -1,6 +1,6 @@
# Chinese (Taiwan) translation of the Godot Engine editor
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Allen H <w84miracle@gmail.com>, 2017.
# Billy SU <g4691821@gmail.com>, 2018.
@@ -23,13 +23,13 @@
# binotaliu <binota@protonmail.ch>, 2020.
# Allen H. <w84miracle@gmail.com>, 2020.
# BinotaLIU <binota@protonmail.ch>, 2020.
-# BinotaLIU <me@binota.org>, 2020.
+# BinotaLIU <me@binota.org>, 2020, 2021.
# MintSoda <lionlxh@qq.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-07 08:11+0000\n"
+"PO-Revision-Date: 2021-02-27 00:47+0000\n"
"Last-Translator: BinotaLIU <me@binota.org>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hant/>\n"
@@ -38,7 +38,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -659,7 +659,7 @@ msgstr "鏿“‡è»Œé“以複製"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
msgstr "複製"
@@ -1851,8 +1851,8 @@ msgid "Open a File or Directory"
msgstr "開啟檔案或資料夾"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
-#: editor/editor_properties.cpp editor/inspector_dock.cpp
-#: editor/plugins/animation_player_editor_plugin.cpp
+#: editor/editor_properties.cpp editor/import_defaults_editor.cpp
+#: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "Save"
msgstr "ä¿å­˜"
@@ -1943,10 +1943,6 @@ msgstr "é è¦½ï¼š"
msgid "File:"
msgstr "檔案:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-msgid "Must use a valid extension."
-msgstr "必須使用有效的副檔å。"
-
#: editor/editor_file_system.cpp
msgid "ScanSources"
msgstr "掃æåŽŸå§‹æª”"
@@ -2367,6 +2363,10 @@ msgid "There is no defined scene to run."
msgstr "未定義欲執行之場景。"
#: editor/editor_node.cpp
+msgid "Save scene before running..."
+msgstr "執行å‰å…ˆä¿å­˜å ´æ™¯..."
+
+#: editor/editor_node.cpp
msgid "Could not start subprocess!"
msgstr "無法啟動å­è™•ç†ç¨‹åºï¼"
@@ -2410,18 +2410,6 @@ msgstr "必須有根節點æ‰å¯ä¿å­˜å ´æ™¯ã€‚"
msgid "Save Scene As..."
msgstr "å¦å­˜å ´æ™¯ç‚ºâ€¦"
-#: editor/editor_node.cpp
-msgid "No"
-msgstr "å¦"
-
-#: editor/editor_node.cpp
-msgid "Yes"
-msgstr "是"
-
-#: editor/editor_node.cpp
-msgid "This scene has never been saved. Save before running?"
-msgstr "此場景從未被ä¿å­˜ã€‚æ˜¯å¦æ–¼åŸ·è¡Œå‰å…ˆä¿å­˜ï¼Ÿ"
-
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
msgstr "å¿…é ˆè¦æœ‰å ´æ™¯æ‰å¯å®Œæˆè©²æ“作。"
@@ -2471,6 +2459,10 @@ msgid "Quit"
msgstr "離開"
#: editor/editor_node.cpp
+msgid "Yes"
+msgstr "是"
+
+#: editor/editor_node.cpp
msgid "Exit the editor?"
msgstr "è¦çµæŸç·¨è¼¯å™¨å—Žï¼Ÿ"
@@ -2513,8 +2505,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "無法在「%sã€ä¸Šå•Ÿç”¨æ“´å……功能,解æžçµ„態設定失敗。"
#: editor/editor_node.cpp
-msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
-msgstr "無法在擴充功能「res://addons/%sã€ä¸­ç„¡æ³•找到腳本欄ä½ã€‚"
+msgid "Unable to find script field for addon plugin at: '%s'."
+msgstr "無法在擴充功能「r%sã€ä¸­æ‰¾åˆ°è…³æœ¬æ¬„ä½ã€‚"
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -2925,14 +2917,6 @@ msgid "Help"
msgstr "說明"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/script_text_editor.cpp
-#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
-#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
-#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
-msgid "Search"
-msgstr "æœå°‹"
-
-#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
msgstr "線上說明文件"
@@ -3094,6 +3078,24 @@ msgid "Open & Run a Script"
msgstr "開啟並執行腳本"
#: editor/editor_node.cpp
+msgid ""
+"The following files are newer on disk.\n"
+"What action should be taken?"
+msgstr ""
+"ç£ç¢Ÿä¸­çš„下列檔案已更新。\n"
+"è¦åŸ·è¡Œä»€éº¼æ“作?"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Reload"
+msgstr "釿–°è¼‰å…¥"
+
+#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/shader_editor_plugin.cpp
+msgid "Resave"
+msgstr "釿–°ä¿å­˜"
+
+#: editor/editor_node.cpp
msgid "New Inherited"
msgstr "新增繼承"
@@ -3300,7 +3302,7 @@ msgstr "ç¨ç«‹åŒ–"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
-#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
+#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
msgstr "貼上"
@@ -3652,6 +3654,11 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"以下檔案或資料夾與目標路徑「%sã€ä¸­çš„é …ç›®è¡çªï¼š\n"
+"\n"
+"%s\n"
+"\n"
+"è¦è¦†è“‹é€™äº›æª”案或資料夾嗎?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3842,8 +3849,16 @@ msgid "Searching..."
msgstr "正在æœå°‹..."
#: editor/find_in_files.cpp
-msgid "Search complete"
-msgstr "æœå°‹å®Œæˆ"
+msgid "%d match in %d file."
+msgstr "%d 件相符åˆçš„çµæžœï¼ˆæ–¼ %d 個檔案內)。"
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d file."
+msgstr "%d 件相符åˆçš„çµæžœï¼ˆæ–¼ %d 個檔案內)。"
+
+#: editor/find_in_files.cpp
+msgid "%d matches in %d files."
+msgstr "%d 件相符åˆçš„çµæžœï¼ˆæ–¼ %d 個檔案內)。"
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -3979,6 +3994,21 @@ msgstr "æ˜¯å¦æœ‰åœ¨ `post_import()` 方法內回傳繼承 Node 之物件?"
msgid "Saving..."
msgstr "正在ä¿å­˜..."
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Select Importer"
+msgstr "鏿“‡æ¨¡å¼"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Importer:"
+msgstr "匯入"
+
+#: editor/import_defaults_editor.cpp
+#, fuzzy
+msgid "Reset to Defaults"
+msgstr "載入é è¨­"
+
#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d 個檔案"
@@ -4934,7 +4964,7 @@ msgid "Got:"
msgstr "ç²å¾—:"
#: editor/plugins/asset_library_editor_plugin.cpp
-msgid "Failed sha256 hash check"
+msgid "Failed SHA-256 hash check"
msgstr "SHA-256 雜湊檢查失敗"
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -5038,7 +5068,6 @@ msgid "Sort:"
msgstr "排åºï¼š"
#: editor/plugins/asset_library_editor_plugin.cpp
-#: editor/project_settings_editor.cpp
msgid "Category:"
msgstr "分類:"
@@ -5069,12 +5098,10 @@ msgstr "ç´ æ ZIP 檔"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Can't determine a save path for lightmap images.\n"
-"Save your scene (for images to be saved in the same dir), or pick a save "
-"path from the BakedLightmap properties."
+"Save your scene and try again."
msgstr ""
"無法判斷光照圖的ä¿å­˜è·¯å¾‘。\n"
-"è«‹ä¿å­˜å ´æ™¯ï¼ˆåœ–片將ä¿å­˜æ–¼ç›¸åŒè³‡æ–™å¤¾ï¼‰ï¼Œæˆ–是在 BackedLightmap å±¬æ€§å…§é¸æ“‡ä¸€å€‹ä¿"
-"存路徑。"
+"è«‹ä¿å­˜å ´æ™¯ä¸¦é‡è©¦ã€‚"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5088,9 +5115,29 @@ msgid "Failed creating lightmap images, make sure path is writable."
msgstr "建立光照圖失敗,請確ä¿è©²è·¯å¾‘å¯å¯«å…¥ã€‚"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Failed determining lightmap size. Maximum lightmap size too small?"
+msgstr "無法判斷光照圖大å°ã€‚æœ€å¤§å…‰ç…§åœ–å¤§å°æ˜¯å¦éŽå°ï¼Ÿ"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Some mesh is invalid. Make sure the UV2 channel values are contained within "
+"the [0.0,1.0] square region."
+msgstr "éƒ¨åˆ†ç¶²æ ¼ç„¡æ•ˆã€‚è«‹ç¢ºä¿ UV2 通é“çš„å€¼ä½æ–¼ [0.0,1.0] 矩形內。"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid ""
+"Godot editor was built without ray tracing support, lightmaps can't be baked."
+msgstr ""
+"Godot 編輯器在建制時未啟用光線追蹤 (Ray Tracing) 支æ´ï¼Œç„¡æ³•烘焙光照圖。"
+
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "烘焙光照圖"
+#: editor/plugins/baked_lightmap_editor_plugin.cpp
+msgid "Select lightmap bake file:"
+msgstr "鏿“‡å…‰ç…§åœ–烘焙檔案:"
+
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
@@ -6169,6 +6216,10 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "僅å¯è¨­ç‚ºæŒ‡å‘ ProticlesMaterial è™•ç†ææ–™"
#: editor/plugins/particles_2d_editor_plugin.cpp
+msgid "Convert to CPUParticles2D"
+msgstr "轉æ›ç‚º CPUParticles2D"
+
+#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
msgstr "產生時間(秒):"
@@ -6229,10 +6280,6 @@ msgstr "正在產生 AABB"
msgid "Generate Visibility AABB"
msgstr "產生å¯è¦‹æ€§ AABB"
-#: editor/plugins/particles_editor_plugin.cpp
-msgid "Generate AABB"
-msgstr "產生 AABB"
-
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
msgstr "自曲線中刪除控制點"
@@ -6816,6 +6863,14 @@ msgstr "關閉說明文件"
msgid "Run"
msgstr "執行"
+#: editor/plugins/script_editor_plugin.cpp
+#: editor/plugins/script_text_editor.cpp
+#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
+#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
+#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
+msgid "Search"
+msgstr "æœå°‹"
+
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
msgstr "逿­¥åŸ·è¡Œ"
@@ -6869,16 +6924,6 @@ msgstr ""
"ç£ç¢Ÿä¸­çš„下列檔案已更新。\n"
"è«‹é¸æ“‡æ–¼åŸ·è¡Œä¹‹æ“作:"
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Reload"
-msgstr "釿–°è¼‰å…¥"
-
-#: editor/plugins/script_editor_plugin.cpp
-#: editor/plugins/shader_editor_plugin.cpp
-msgid "Resave"
-msgstr "釿–°ä¿å­˜"
-
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
msgstr "除錯工具"
@@ -6971,8 +7016,8 @@ msgstr "中斷點"
msgid "Go To"
msgstr "跳至"
-#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
-#: scene/gui/text_edit.cpp
+#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
+#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
msgstr "剪下"
@@ -7195,6 +7240,10 @@ msgid "Yaw"
msgstr "å航"
#: editor/plugins/spatial_editor_plugin.cpp
+msgid "Size"
+msgstr "大å°"
+
+#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
msgstr "繪製的物件"
@@ -8434,10 +8483,6 @@ msgid "Error"
msgstr "錯誤"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No commit message was provided"
-msgstr "未æä¾›æäº¤è¨Šæ¯"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
msgstr "é å­˜å€ç„¡æª”案"
@@ -8494,10 +8539,6 @@ msgid "Stage All"
msgstr "é å­˜å…¨éƒ¨"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Add a commit message"
-msgstr "新增一個æäº¤è¨Šæ¯"
-
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr "æäº¤æ”¹å‹•"
@@ -9660,7 +9701,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "所使用的 GPU 驅動程å¼ä¸æ”¯æ´ã€‚"
#: editor/project_manager.cpp
msgid ""
@@ -9829,6 +9870,10 @@ msgid "Projects"
msgstr "專案"
#: editor/project_manager.cpp
+msgid "Loading, please wait..."
+msgstr "載入中,請ç¨å¾Œ..."
+
+#: editor/project_manager.cpp
msgid "Last Modified"
msgstr "最後修改時間"
@@ -10193,6 +10238,11 @@ msgstr "Autoload"
msgid "Plugins"
msgstr "外掛"
+#: editor/project_settings_editor.cpp
+#, fuzzy
+msgid "Import Defaults"
+msgstr "載入é è¨­"
+
#: editor/property_editor.cpp
msgid "Preset..."
msgstr "é è¨­è¨­å®š..."
@@ -10440,6 +10490,14 @@ msgid "Instance Child Scene"
msgstr "實體化å­å ´æ™¯"
#: editor/scene_tree_dock.cpp
+msgid "Can't paste root node into the same scene."
+msgstr "無法將跟節點貼到相åŒçš„場景中。"
+
+#: editor/scene_tree_dock.cpp
+msgid "Paste Node(s)"
+msgstr "貼上節點"
+
+#: editor/scene_tree_dock.cpp
msgid "Detach Script"
msgstr "å–æ¶ˆé™„加腳本"
@@ -10562,6 +10620,10 @@ msgid "Attach Script"
msgstr "附加腳本"
#: editor/scene_tree_dock.cpp
+msgid "Cut Node(s)"
+msgstr "剪下節點"
+
+#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
msgstr "移除節點"
@@ -11360,6 +11422,34 @@ msgstr "篩é¸ç¶²æ ¼"
msgid "Give a MeshLibrary resource to this GridMap to use its meshes."
msgstr "æä¾› MeshLibrary 予該 GridMap 以使用其網格。"
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Begin Bake"
+msgstr "開始烘焙"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Preparing data structures"
+msgstr "æ­£åœ¨æº–å‚™è³‡æ–™çµæ§‹"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Generate buffers"
+msgstr "產生緩è¡"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Direct lighting"
+msgstr "呿€§å…‰ç…§"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Indirect lighting"
+msgstr "éžå‘性光照"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Post processing"
+msgstr "後處ç†"
+
+#: modules/lightmapper_cpu/lightmapper_cpu.cpp
+msgid "Plotting lightmaps"
+msgstr "正在繪製光照"
+
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
msgstr "類別å稱ä¸èƒ½ç‚ºä¿ç•™é—œéµå­—"
@@ -11858,12 +11948,14 @@ msgid "Select device from the list"
msgstr "è‡ªæ¸…å–®ä¸­é¸æ“‡è£ç½®"
#: platform/android/export/export.cpp
-msgid "ADB executable not configured in the Editor Settings."
-msgstr "尚未於編輯器設定中設定 ADB å¯åŸ·è¡Œæª”。"
+msgid "Unable to find the 'apksigner' tool."
+msgstr "找ä¸åˆ°ã€Œapksignerã€å·¥å…·ã€‚"
#: platform/android/export/export.cpp
-msgid "OpenJDK jarsigner not configured in the Editor Settings."
-msgstr "尚未於編輯器設定中設定 OpenJDK Jarsigner。"
+msgid ""
+"Android build template not installed in the project. Install it from the "
+"Project menu."
+msgstr "å°šæœªæ–¼å°ˆæ¡ˆä¸­å®‰è£ Android 建置樣æ¿ã€‚請先於專案目錄中進行安è£ã€‚"
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
@@ -11874,22 +11966,32 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "發行金鑰儲存å€ä¸­ä¸æ­£ç¢ºä¹‹çµ„態設定至匯出é è¨­è¨­å®šã€‚"
#: platform/android/export/export.cpp
-msgid "Custom build requires a valid Android SDK path in Editor Settings."
-msgstr "è‡ªå®šå»ºç½®éœ€è¦æœ‰åœ¨ç·¨è¼¯å™¨è¨­å®šä¸­è¨­å®šä¸€å€‹æœ‰æ•ˆçš„ Android SDK ä½ç½®ã€‚"
+msgid "A valid Android SDK path is required in Editor Settings."
+msgstr "必須於 [編輯器設定] 中æä¾›ä¸€å€‹æœ‰æ•ˆçš„ Android SDK 路徑。"
#: platform/android/export/export.cpp
-msgid "Invalid Android SDK path for custom build in Editor Settings."
-msgstr "編輯器設定中用於自定義設定之 Android SDK 路徑無效。"
+msgid "Invalid Android SDK path in Editor Settings."
+msgstr "[編輯器設定] 中所指定的 Android SDK 路徑無效。"
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
msgstr "缺少「platform-toolsã€è³‡æ–™å¤¾ï¼"
#: platform/android/export/export.cpp
-msgid ""
-"Android build template not installed in the project. Install it from the "
-"Project menu."
-msgstr "å°šæœªæ–¼å°ˆæ¡ˆä¸­å®‰è£ Android 建置樣æ¿ã€‚請先於專案目錄中進行安è£ã€‚"
+msgid "Unable to find Android SDK platform-tools' adb command."
+msgstr "找ä¸åˆ° Android SDK platform-tools çš„ adb 指令。"
+
+#: platform/android/export/export.cpp
+msgid "Please check in the Android SDK directory specified in Editor Settings."
+msgstr "請檢查 [編輯器設定] 中所指定的 Android SDK 資料夾。"
+
+#: platform/android/export/export.cpp
+msgid "Missing 'build-tools' directory!"
+msgstr "缺少「build-toolsã€è³‡æ–™å¤¾ï¼"
+
+#: platform/android/export/export.cpp
+msgid "Unable to find Android SDK build-tools' apksigner command."
+msgstr "找ä¸åˆ° Android SDK build-tools çš„ apksigner 指令。"
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12137,6 +12239,14 @@ msgstr ""
msgid "An empty CollisionPolygon2D has no effect on collision."
msgstr "空白的 CollisionPolygon2D 䏿œƒç”¢ç”Ÿä»»ä½•碰撞效果。"
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
+msgstr ""
+
+#: scene/2d/collision_polygon_2d.cpp
+msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
+msgstr ""
+
#: scene/2d/collision_shape_2d.cpp
msgid ""
"CollisionShape2D only serves to provide a collision shape to a "
@@ -12171,23 +12281,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A 與 Node B 必須為 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node A 必須為 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node B 必須為 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Joint 未連çµè‡³ 2 個 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A 與 Node B 必須為ä¸åŒçš„ PhysicsBody2D"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12323,28 +12433,28 @@ msgid "ARVROrigin requires an ARVRCamera child node."
msgstr "ARVROrigin 必須有一個 ARVRCamera å­ç¯€é»žã€‚"
#: scene/3d/baked_lightmap.cpp
-msgid "%d%%"
-msgstr "%d%%"
+msgid "Finding meshes and lights"
+msgstr "正在尋找網格與光照"
#: scene/3d/baked_lightmap.cpp
-msgid "(Time Left: %d:%02d s)"
-msgstr "(剩餘時間:%d:%02d 秒)"
+msgid "Preparing geometry (%d/%d)"
+msgstr "正在解æžå¹¾ä½• (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Meshes: "
-msgstr "正在繪製網格: "
+msgid "Preparing environment"
+msgstr "正在準備環境"
#: scene/3d/baked_lightmap.cpp
-msgid "Plotting Lights:"
-msgstr "正在繪製光照:"
+msgid "Generating capture"
+msgstr "æ­£åœ¨ç”¢ç”Ÿæ•æ‰"
-#: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp
-msgid "Finishing Plot"
-msgstr "繪製完æˆ"
+#: scene/3d/baked_lightmap.cpp
+msgid "Saving lightmaps"
+msgstr "正在ä¿å­˜å…‰ç…§åœ–"
#: scene/3d/baked_lightmap.cpp
-msgid "Lighting Meshes: "
-msgstr "正在照明網格: "
+msgid "Done"
+msgstr "完æˆ"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12411,6 +12521,10 @@ msgid "Plotting Meshes"
msgstr "正在繪製網格"
#: scene/3d/gi_probe.cpp
+msgid "Finishing Plot"
+msgstr "繪製完æˆ"
+
+#: scene/3d/gi_probe.cpp
msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
@@ -12418,11 +12532,6 @@ msgstr ""
"GLES2 視訊驅動程å¼ä¸æ”¯æ´ GIProbes。\n"
"請改為使用 BakedLightmap。"
-#: scene/3d/interpolated_camera.cpp
-msgid ""
-"InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
-msgstr "InterpolatedCamera å·²åœæ­¢ç¶­è­·ï¼Œä¸”將於 Godot 4.0 中移除。"
-
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr "角度大於 90 度的 SpotLight 無法投射出陰影。"
@@ -12485,23 +12594,23 @@ msgstr ""
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Node A 與 Node B 必須為 PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Node A 必須為 PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Node B 必須為 PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Joint 尚未連çµè‡³ä»»ä½• PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Node A 與 Node B 必須為ä¸åŒçš„ PhysicsBody"
#: scene/3d/remote_transform.cpp
msgid ""
@@ -12656,6 +12765,14 @@ msgstr "警告ï¼"
msgid "Please Confirm..."
msgstr "請確èª..."
+#: scene/gui/file_dialog.cpp
+msgid "Must use a valid extension."
+msgstr "必須使用有效的副檔å。"
+
+#: scene/gui/graph_edit.cpp
+msgid "Enable grid minimap."
+msgstr "啟用網格迷你地圖。"
+
#: scene/gui/popup.cpp
msgid ""
"Popups will hide by default unless you call popup() or any of the popup*() "
@@ -12707,6 +12824,12 @@ msgid "Viewport size must be greater than 0 to render anything."
msgstr "Viewport 大å°å¿…須大於 0 æ‰å¯é€²è¡Œç®—繪。"
#: scene/resources/visual_shader_nodes.cpp
+msgid ""
+"The sampler port is connected but not used. Consider changing the source to "
+"'SamplerPort'."
+msgstr "å·²é€£ç·šè‡³å–æ¨£å™¨é€£çµåŸ ä½†ä¸¦æœªä½¿ç”¨ã€‚建議將來æºè¨­ç‚ºã€ŒSamplerPortã€ã€‚"
+
+#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
msgstr "無效的é è¦½ä¾†æºã€‚"
@@ -12734,14 +12857,48 @@ msgstr "Varying 變數åªå¯åœ¨é ‚點函å¼ä¸­æŒ‡æ´¾ã€‚"
msgid "Constants cannot be modified."
msgstr "ä¸å¯ä¿®æ”¹å¸¸æ•¸ã€‚"
-#~ msgid "There is already file or folder with the same name in this location."
-#~ msgstr "該ä½ç½®å·²æœ‰ç›¸åŒå稱的檔案或資料夾。"
+#~ msgid ""
+#~ "InterpolatedCamera has been deprecated and will be removed in Godot 4.0."
+#~ msgstr "InterpolatedCamera å·²åœæ­¢ç¶­è­·ï¼Œä¸”將於 Godot 4.0 中移除。"
+
+#~ msgid "No"
+#~ msgstr "å¦"
-#~ msgid "Missing 'build-tools' directory!"
-#~ msgstr "缺少「build-toolsã€è³‡æ–™å¤¾ï¼"
+#~ msgid "This scene has never been saved. Save before running?"
+#~ msgstr "此場景從未被ä¿å­˜ã€‚æ˜¯å¦æ–¼åŸ·è¡Œå‰å…ˆä¿å­˜ï¼Ÿ"
-#~ msgid "Unable to find the zipalign tool."
-#~ msgstr "找ä¸åˆ° zipalign 工具。"
+#~ msgid "ADB executable not configured in the Editor Settings."
+#~ msgstr "尚未於編輯器設定中設定 ADB å¯åŸ·è¡Œæª”。"
+
+#~ msgid "OpenJDK jarsigner not configured in the Editor Settings."
+#~ msgstr "尚未於編輯器設定中設定 OpenJDK Jarsigner。"
+
+#~ msgid "Custom build requires a valid Android SDK path in Editor Settings."
+#~ msgstr "è‡ªå®šå»ºç½®éœ€è¦æœ‰åœ¨ç·¨è¼¯å™¨è¨­å®šä¸­è¨­å®šä¸€å€‹æœ‰æ•ˆçš„ Android SDK ä½ç½®ã€‚"
+
+#~ msgid "%d%%"
+#~ msgstr "%d%%"
+
+#~ msgid "(Time Left: %d:%02d s)"
+#~ msgstr "(剩餘時間:%d:%02d 秒)"
+
+#~ msgid "Plotting Meshes: "
+#~ msgstr "正在繪製網格: "
+
+#~ msgid "Lighting Meshes: "
+#~ msgstr "正在照明網格: "
+
+#~ msgid "Search complete"
+#~ msgstr "æœå°‹å®Œæˆ"
+
+#~ msgid "No commit message was provided"
+#~ msgstr "未æä¾›æäº¤è¨Šæ¯"
+
+#~ msgid "Add a commit message"
+#~ msgstr "新增一個æäº¤è¨Šæ¯"
+
+#~ msgid "There is already file or folder with the same name in this location."
+#~ msgstr "該ä½ç½®å·²æœ‰ç›¸åŒå稱的檔案或資料夾。"
#~ msgid "Aligning APK..."
#~ msgstr "正在å°é½Š APK…"
diff --git a/main/main.cpp b/main/main.cpp
index c492cfaad7..9c8909f8fb 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,7 +71,6 @@
#include "servers/physics_server_3d.h"
#include "servers/register_server_types.h"
#include "servers/rendering/rendering_server_default.h"
-#include "servers/rendering/rendering_server_wrap_mt.h"
#include "servers/text_server.h"
#include "servers/xr_server.h"
@@ -124,7 +123,9 @@ static bool _start_success = false;
// Drivers
+String tablet_driver = "";
String text_driver = "";
+
static int text_driver_idx = -1;
static int display_driver_idx = -1;
static int audio_driver_idx = -1;
@@ -171,6 +172,8 @@ static bool disable_render_loop = false;
static int fixed_fps = -1;
static bool print_fps = false;
+bool profile_gpu = false;
+
/* Helper methods */
// Used by Mono module, should likely be registered in Engine singleton instead
@@ -256,34 +259,34 @@ void finalize_navigation_server() {
void Main::print_help(const char *p_binary) {
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
OS::get_singleton()->print("Free and open source software under the terms of the MIT license.\n");
- OS::get_singleton()->print("(c) 2007-2020 Juan Linietsky, Ariel Manzur.\n");
- OS::get_singleton()->print("(c) 2014-2020 Godot Engine contributors.\n");
+ OS::get_singleton()->print("(c) 2007-2021 Juan Linietsky, Ariel Manzur.\n");
+ OS::get_singleton()->print("(c) 2014-2021 Godot Engine contributors.\n");
OS::get_singleton()->print("\n");
OS::get_singleton()->print("Usage: %s [options] [path to scene or 'project.godot' file]\n", p_binary);
OS::get_singleton()->print("\n");
OS::get_singleton()->print("General options:\n");
- OS::get_singleton()->print(" -h, --help Display this help message.\n");
- OS::get_singleton()->print(" --version Display the version string.\n");
- OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n");
- OS::get_singleton()->print(" --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n");
+ OS::get_singleton()->print(" -h, --help Display this help message.\n");
+ OS::get_singleton()->print(" --version Display the version string.\n");
+ OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n");
+ OS::get_singleton()->print(" --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n");
OS::get_singleton()->print("\n");
OS::get_singleton()->print("Run options:\n");
#ifdef TOOLS_ENABLED
- OS::get_singleton()->print(" -e, --editor Start the editor instead of running the scene.\n");
- OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n");
+ OS::get_singleton()->print(" -e, --editor Start the editor instead of running the scene.\n");
+ OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n");
#endif
- OS::get_singleton()->print(" -q, --quit Quit after the first iteration.\n");
- OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n");
- OS::get_singleton()->print(" --path <directory> Path to a project (<directory> must contain a 'project.godot' file).\n");
- OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n");
- OS::get_singleton()->print(" --main-pack <file> Path to a pack (.pck) file to load.\n");
- OS::get_singleton()->print(" --render-thread <mode> Render thread mode ('unsafe', 'safe', 'separate').\n");
- OS::get_singleton()->print(" --remote-fs <address> Remote filesystem (<host/IP>[:<port>] address).\n");
- OS::get_singleton()->print(" --remote-fs-password <password> Password for remote filesystem.\n");
-
- OS::get_singleton()->print(" --audio-driver <driver> Audio driver [");
+ OS::get_singleton()->print(" -q, --quit Quit after the first iteration.\n");
+ OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n");
+ OS::get_singleton()->print(" --path <directory> Path to a project (<directory> must contain a 'project.godot' file).\n");
+ OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n");
+ OS::get_singleton()->print(" --main-pack <file> Path to a pack (.pck) file to load.\n");
+ OS::get_singleton()->print(" --render-thread <mode> Render thread mode ('unsafe', 'safe', 'separate').\n");
+ OS::get_singleton()->print(" --remote-fs <address> Remote filesystem (<host/IP>[:<port>] address).\n");
+ OS::get_singleton()->print(" --remote-fs-password <password> Password for remote filesystem.\n");
+
+ OS::get_singleton()->print(" --audio-driver <driver> Audio driver [");
for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
if (i > 0) {
OS::get_singleton()->print(", ");
@@ -292,7 +295,7 @@ void Main::print_help(const char *p_binary) {
}
OS::get_singleton()->print("].\n");
- OS::get_singleton()->print(" --display-driver <driver> Display driver (and rendering driver) [");
+ OS::get_singleton()->print(" --display-driver <driver> Display driver (and rendering driver) [");
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
if (i > 0) {
OS::get_singleton()->print(", ");
@@ -309,72 +312,68 @@ void Main::print_help(const char *p_binary) {
}
OS::get_singleton()->print("].\n");
- OS::get_singleton()->print(" --rendering-driver <driver> Rendering driver (depends on display driver).\n");
+ OS::get_singleton()->print(" --rendering-driver <driver> Rendering driver (depends on display driver).\n");
- OS::get_singleton()->print(" --text-driver <driver> Text driver (Fonts, BiDi, shaping)\n");
+ OS::get_singleton()->print(" --text-driver <driver> Text driver (Fonts, BiDi, shaping)\n");
OS::get_singleton()->print("\n");
#ifndef SERVER_ENABLED
OS::get_singleton()->print("Display options:\n");
- OS::get_singleton()->print(" -f, --fullscreen Request fullscreen mode.\n");
- OS::get_singleton()->print(" -m, --maximized Request a maximized window.\n");
- OS::get_singleton()->print(" -w, --windowed Request windowed mode.\n");
- OS::get_singleton()->print(" -t, --always-on-top Request an always-on-top window.\n");
- OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n");
- OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n");
- OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n");
- OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n");
- OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n");
- OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n");
- OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n");
- OS::get_singleton()->print(" --tablet-driver Tablet input driver (");
- for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) {
- if (i != 0)
- OS::get_singleton()->print(", ");
- OS::get_singleton()->print("'%s'", OS::get_singleton()->get_tablet_driver_name(i).utf8().get_data());
- }
- OS::get_singleton()->print(") (Windows only).\n");
+ OS::get_singleton()->print(" -f, --fullscreen Request fullscreen mode.\n");
+ OS::get_singleton()->print(" -m, --maximized Request a maximized window.\n");
+ OS::get_singleton()->print(" -w, --windowed Request windowed mode.\n");
+ OS::get_singleton()->print(" -t, --always-on-top Request an always-on-top window.\n");
+ OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n");
+ OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n");
+ OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n");
+ OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n");
+ OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n");
+ OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n");
+ OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n");
+ OS::get_singleton()->print(" --tablet-driver Pen tablet input driver.\n");
OS::get_singleton()->print("\n");
#endif
OS::get_singleton()->print("Debug options:\n");
- OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n");
- OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
- OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n");
- OS::get_singleton()->print(" --vk-layers Enable Vulkan Validation layers for debugging.\n");
+ OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n");
+ OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
+ OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n");
+ OS::get_singleton()->print(" --vk-layers Enable Vulkan Validation layers for debugging.\n");
#if DEBUG_ENABLED
- OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n");
+ OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n");
#endif
- OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
+ OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
#if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED)
- OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
- OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
+ OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
+ OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
#endif
- OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
- OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n");
- OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n");
- OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n");
- OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n");
- OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n");
+ OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
+ OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n");
+ OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n");
+ OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n");
+ OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n");
+ OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n");
+ OS::get_singleton()->print(" --profile-gpu Show a simple profile of the tasks that took more time during frame rendering.\n");
OS::get_singleton()->print("\n");
OS::get_singleton()->print("Standalone tools:\n");
- OS::get_singleton()->print(" -s, --script <script> Run a script.\n");
- OS::get_singleton()->print(" --check-only Only parse for errors and quit (use with --script).\n");
+ OS::get_singleton()->print(" -s, --script <script> Run a script.\n");
+ OS::get_singleton()->print(" --check-only Only parse for errors and quit (use with --script).\n");
#ifdef TOOLS_ENABLED
- OS::get_singleton()->print(" --export <preset> <path> Export the project using the given preset and matching release template. The preset name should match one defined in export_presets.cfg.\n");
- OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe'). The target directory should exist.\n");
- OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n");
- OS::get_singleton()->print(" --export-pack <preset> <path> Same as --export, but only export the game pack for the given preset. The <path> extension determines whether it will be in PCK or ZIP format.\n");
- OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n");
- OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n");
- OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n");
+ OS::get_singleton()->print(" --export <preset> <path> Export the project using the given preset and matching release template. The preset name should match one defined in export_presets.cfg.\n");
+ OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe'). The target directory should exist.\n");
+ OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n");
+ OS::get_singleton()->print(" --export-pack <preset> <path> Same as --export, but only export the game pack for the given preset. The <path> extension determines whether it will be in PCK or ZIP format.\n");
+ OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n");
+ OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n");
+ OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n");
#ifdef DEBUG_METHODS_ENABLED
- OS::get_singleton()->print(" --gdnative-generate-json-api Generate JSON dump of the Godot API for GDNative bindings.\n");
+ OS::get_singleton()->print(" --gdnative-generate-json-api <path> Generate JSON dump of the Godot API for GDNative bindings and save it on the file specified in <path>.\n");
+ OS::get_singleton()->print(" --gdnative-generate-json-builtin-api <path> Generate JSON dump of the Godot API of the builtin Variant types and utility functions for GDNative bindings and save it on the file specified in <path>.\n");
#endif
#ifdef TESTS_ENABLED
- OS::get_singleton()->print(" --test [--help] Run unit tests. Use --test --help for more information.\n");
+ OS::get_singleton()->print(" --test [--help] Run unit tests. Use --test --help for more information.\n");
#endif
OS::get_singleton()->print("\n");
#endif
@@ -388,8 +387,6 @@ Error Main::test_setup() {
engine = memnew(Engine);
- ClassDB::init();
-
register_core_types();
register_core_driver_types();
@@ -398,6 +395,8 @@ Error Main::test_setup() {
GLOBAL_DEF("debug/settings/crash_handler/message",
String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues"));
+ translation_server = memnew(TranslationServer);
+
// From `Main::setup2()`.
preregister_module_types();
preregister_server_types();
@@ -405,6 +404,16 @@ Error Main::test_setup() {
register_core_singletons();
register_server_types();
+
+ translation_server->setup(); //register translations, load them, etc.
+ if (locale != "") {
+ translation_server->set_locale(locale);
+ }
+ translation_server->load_translations();
+ ResourceLoader::load_translation_remaps(); //load remaps for resources
+
+ ResourceLoader::load_path_remaps();
+
register_scene_types();
#ifdef TOOLS_ENABLED
@@ -444,6 +453,9 @@ void Main::test_cleanup() {
OS::get_singleton()->finalize();
+ if (translation_server) {
+ memdelete(translation_server);
+ }
if (globals) {
memdelete(globals);
}
@@ -507,8 +519,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
engine = memnew(Engine);
- ClassDB::init();
-
MAIN_PRINT("Main: Initialize CORE");
register_core_types();
@@ -516,10 +526,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
MAIN_PRINT("Main: Initialize Globals");
- Thread::_main_thread_id = Thread::get_caller_id();
-
- globals = memnew(ProjectSettings);
input_map = memnew(InputMap);
+ globals = memnew(ProjectSettings);
register_core_settings(); //here globals is present
@@ -528,6 +536,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ClassDB::register_class<Performance>();
engine->add_singleton(Engine::Singleton("Performance", performance));
+ // Only flush stdout in debug builds by default, as spamming `print()` will
+ // decrease performance if this is enabled.
+ GLOBAL_DEF_RST("application/run/flush_stdout_on_print", false);
+ GLOBAL_DEF_RST("application/run/flush_stdout_on_print.debug", true);
+
GLOBAL_DEF("debug/settings/crash_handler/message",
String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues"));
@@ -554,7 +567,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
String display_driver = "";
String audio_driver = "";
- String tablet_driver = "";
String project_path = ".";
bool upwards = false;
String debug_uri = "";
@@ -723,19 +735,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--tablet-driver") {
if (I->next()) {
tablet_driver = I->next()->get();
- bool found = false;
- for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) {
- if (tablet_driver == OS::get_singleton()->get_tablet_driver_name(i)) {
- found = true;
- }
- }
-
- if (!found) {
- OS::get_singleton()->print("Unknown tablet driver '%s', aborting.\n",
- tablet_driver.utf8().get_data());
- goto error;
- }
-
N = I->next()->next();
} else {
OS::get_singleton()->print("Missing tablet driver argument, aborting.\n");
@@ -875,7 +874,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
auto_build_solutions = true;
editor = true;
#ifdef DEBUG_METHODS_ENABLED
- } else if (I->get() == "--gdnative-generate-json-api") {
+ } else if (I->get() == "--gdnative-generate-json-api" || I->get() == "--gdnative-generate-json-builtin-api") {
// Register as an editor instance to use low-end fallback if relevant.
editor = true;
@@ -1005,6 +1004,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
} else if (I->get() == "--print-fps") {
print_fps = true;
+ } else if (I->get() == "--profile-gpu") {
+ profile_gpu = true;
} else if (I->get() == "--disable-crash-handler") {
OS::get_singleton()->disable_crash_handler();
} else if (I->get() == "--skip-breakpoints") {
@@ -1121,34 +1122,29 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
#endif
- // Only flush stdout in debug builds by default, as spamming `print()` will
- // decrease performance if this is enabled.
- GLOBAL_DEF("application/run/flush_stdout_on_print", false);
- GLOBAL_DEF("application/run/flush_stdout_on_print.debug", true);
-
- GLOBAL_DEF("logging/file_logging/enable_file_logging", false);
+ GLOBAL_DEF("debug/file_logging/enable_file_logging", false);
// Only file logging by default on desktop platforms as logs can't be
// accessed easily on mobile/Web platforms (if at all).
// This also prevents logs from being created for the editor instance, as feature tags
// are disabled while in the editor (even if they should logically apply).
- GLOBAL_DEF("logging/file_logging/enable_file_logging.pc", true);
- GLOBAL_DEF("logging/file_logging/log_path", "user://logs/godot.log");
- GLOBAL_DEF("logging/file_logging/max_log_files", 5);
- ProjectSettings::get_singleton()->set_custom_property_info("logging/file_logging/max_log_files",
+ GLOBAL_DEF("debug/file_logging/enable_file_logging.pc", true);
+ GLOBAL_DEF("debug/file_logging/log_path", "user://logs/godot.log");
+ GLOBAL_DEF("debug/file_logging/max_log_files", 5);
+ ProjectSettings::get_singleton()->set_custom_property_info("debug/file_logging/max_log_files",
PropertyInfo(Variant::INT,
- "logging/file_logging/max_log_files",
+ "debug/file_logging/max_log_files",
PROPERTY_HINT_RANGE,
"0,20,1,or_greater")); //no negative numbers
if (!project_manager && !editor && FileAccess::get_create_func(FileAccess::ACCESS_USERDATA) &&
- GLOBAL_GET("logging/file_logging/enable_file_logging")) {
+ GLOBAL_GET("debug/file_logging/enable_file_logging")) {
// Don't create logs for the project manager as they would be written to
// the current working directory, which is inconvenient.
- String base_path = GLOBAL_GET("logging/file_logging/log_path");
- int max_files = GLOBAL_GET("logging/file_logging/max_log_files");
+ String base_path = GLOBAL_GET("debug/file_logging/log_path");
+ int max_files = GLOBAL_GET("debug/file_logging/max_log_files");
OS::get_singleton()->add_logger(memnew(RotatedFileLogger(base_path, max_files)));
}
- if (main_args.size() == 0 && String(GLOBAL_DEF("application/run/main_scene", "")) == "") {
+ if (main_args.size() == 0 && String(GLOBAL_GET("application/run/main_scene")) == "") {
#ifdef TOOLS_ENABLED
if (!editor && !project_manager) {
#endif
@@ -1178,30 +1174,32 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
_print_line_enabled = false;
}
+ Logger::set_flush_stdout_on_print(ProjectSettings::get_singleton()->get("application/run/flush_stdout_on_print"));
+
OS::get_singleton()->set_cmdline(execpath, main_args);
- GLOBAL_DEF("rendering/quality/driver/driver_name", "Vulkan");
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name",
+ GLOBAL_DEF("rendering/driver/driver_name", "Vulkan");
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/driver/driver_name",
PropertyInfo(Variant::STRING,
- "rendering/quality/driver/driver_name",
+ "rendering/driver/driver_name",
PROPERTY_HINT_ENUM, "Vulkan"));
if (display_driver == "") {
- display_driver = GLOBAL_GET("rendering/quality/driver/driver_name");
+ display_driver = GLOBAL_GET("rendering/driver/driver_name");
}
- GLOBAL_DEF("display/window/size/width", 1024);
+ GLOBAL_DEF_BASIC("display/window/size/width", 1024);
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width",
PropertyInfo(Variant::INT, "display/window/size/width",
PROPERTY_HINT_RANGE,
"0,7680,or_greater")); // 8K resolution
- GLOBAL_DEF("display/window/size/height", 600);
+ GLOBAL_DEF_BASIC("display/window/size/height", 600);
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/height",
PropertyInfo(Variant::INT, "display/window/size/height",
PROPERTY_HINT_RANGE,
"0,4320,or_greater")); // 8K resolution
- GLOBAL_DEF("display/window/size/resizable", true);
- GLOBAL_DEF("display/window/size/borderless", false);
- GLOBAL_DEF("display/window/size/fullscreen", false);
+ GLOBAL_DEF_BASIC("display/window/size/resizable", true);
+ GLOBAL_DEF_BASIC("display/window/size/borderless", false);
+ GLOBAL_DEF_BASIC("display/window/size/fullscreen", false);
GLOBAL_DEF("display/window/size/always_on_top", false);
GLOBAL_DEF("display/window/size/test_width", 0);
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_width",
@@ -1249,7 +1247,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
}
- GLOBAL_DEF("display/window/force_right_to_left_layout_direction", false);
+ GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false);
if (!force_lowdpi) {
OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false);
@@ -1268,28 +1266,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->_vsync_via_compositor = window_vsync_via_compositor;
- if (tablet_driver == "") { // specified in project.godot
- tablet_driver = GLOBAL_DEF_RST_NOVAL("display/window/tablet_driver", OS::get_singleton()->get_tablet_driver_name(0));
- }
-
- for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) {
- if (tablet_driver == OS::get_singleton()->get_tablet_driver_name(i)) {
- OS::get_singleton()->set_current_tablet_driver(OS::get_singleton()->get_tablet_driver_name(i));
- break;
- }
- }
-
- if (tablet_driver == "") {
- OS::get_singleton()->set_current_tablet_driver(OS::get_singleton()->get_tablet_driver_name(0));
- }
-
/* todo restore
OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false);
video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false);
*/
- GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation", 2);
- GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_allocation.mobile", 3);
-
if (editor || project_manager) {
// The editor and project manager always detect and use hiDPI if needed
OS::get_singleton()->_allow_hidpi = true;
@@ -1298,7 +1278,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->_keep_screen_on = GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true);
if (rtm == -1) {
- rtm = GLOBAL_DEF("rendering/threads/thread_model", OS::RENDER_THREAD_SAFE);
+ rtm = GLOBAL_DEF("rendering/driver/threads/thread_model", OS::RENDER_THREAD_SAFE);
}
if (rtm >= 0 && rtm < 3) {
@@ -1326,7 +1306,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
if (audio_driver == "") { // specified in project.godot
- audio_driver = GLOBAL_DEF_RST_NOVAL("audio/driver", AudioDriverManager::get_driver(0)->get_name());
+ audio_driver = GLOBAL_DEF_RST_NOVAL("audio/driver/driver", AudioDriverManager::get_driver(0)->get_name());
}
for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
@@ -1360,7 +1340,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
}
- Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/common/physics_fps", 60));
+ Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF_BASIC("physics/common/physics_fps", 60));
ProjectSettings::get_singleton()->set_custom_property_info("physics/common/physics_fps",
PropertyInfo(Variant::INT, "physics/common/physics_fps",
PROPERTY_HINT_RANGE, "1,120,1,or_greater"));
@@ -1469,15 +1449,16 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
// Print engine name and version
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
+#if !defined(NO_THREADS)
if (p_main_tid_override) {
- Thread::_main_thread_id = p_main_tid_override;
+ Thread::main_thread_id = p_main_tid_override;
}
+#endif
/* Determine text driver */
- GLOBAL_DEF("display/window/text_name", "");
if (text_driver == "") {
- text_driver = GLOBAL_GET("display/window/text_name");
+ text_driver = GLOBAL_GET("internationalization/rendering/text_driver");
}
if (text_driver != "") {
@@ -1506,7 +1487,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
}
}
}
- printf("Using %s text server...\n", TextServerManager::get_interface_name(text_driver_idx).utf8().get_data());
+ print_verbose("Using \"" + TextServerManager::get_interface_name(text_driver_idx) + "\" text server...");
/* Initialize Text Server */
@@ -1566,18 +1547,45 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
display_server->screen_set_orientation(window_orientation);
}
- /* Initialize Visual Server */
+ /* Initialize Pen Table Driver */
- rendering_server = memnew(RenderingServerDefault);
- if (OS::get_singleton()->get_render_thread_mode() != OS::RENDER_THREAD_UNSAFE) {
- rendering_server = memnew(RenderingServerWrapMT(rendering_server,
- OS::get_singleton()->get_render_thread_mode() ==
- OS::RENDER_SEPARATE_THREAD));
+ {
+ GLOBAL_DEF_RST_NOVAL("input_devices/pen_tablet/driver", "");
+ GLOBAL_DEF_RST_NOVAL("input_devices/pen_tablet/driver.windows", "");
+ ProjectSettings::get_singleton()->set_custom_property_info("input_devices/pen_tablet/driver.windows", PropertyInfo(Variant::STRING, "input_devices/pen_tablet/driver.windows", PROPERTY_HINT_ENUM, "wintab,winink"));
}
+ if (tablet_driver == "") { // specified in project.godot
+ tablet_driver = GLOBAL_GET("input_devices/pen_tablet/driver");
+ if (tablet_driver == "") {
+ tablet_driver = DisplayServer::get_singleton()->tablet_get_driver_name(0);
+ }
+ }
+
+ for (int i = 0; i < DisplayServer::get_singleton()->tablet_get_driver_count(); i++) {
+ if (tablet_driver == DisplayServer::get_singleton()->tablet_get_driver_name(i)) {
+ DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(i));
+ break;
+ }
+ }
+
+ if (DisplayServer::get_singleton()->tablet_get_current_driver() == "") {
+ DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(0));
+ }
+
+ print_verbose("Using \"" + tablet_driver + "\" pen tablet driver...");
+
+ /* Initialize Visual Server */
+
+ rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD));
+
rendering_server->init();
rendering_server->set_render_loop_enabled(!disable_render_loop);
+ if (profile_gpu) {
+ rendering_server->set_print_gpu_profile(true);
+ }
+
OS::get_singleton()->initialize_joypads();
/* Initialize Audio Driver */
@@ -1602,7 +1610,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
MAIN_PRINT("Main: Setup Logo");
-#ifdef JAVASCRIPT_ENABLED
+#if defined(JAVASCRIPT_ENABLED) || defined(ANDROID_ENABLED)
bool show_logo = false;
#else
bool show_logo = true;
@@ -1628,9 +1636,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
register_server_types();
- MAIN_PRINT("Main: Load Remaps");
+ MAIN_PRINT("Main: Load Boot Image");
- Color clear = GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3));
+ Color clear = GLOBAL_DEF("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3));
RenderingServer::get_singleton()->set_default_clear_color(clear);
if (show_logo) { //boot logo!
@@ -1683,8 +1691,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
MAIN_PRINT("Main: DCC");
RenderingServer::get_singleton()->set_default_clear_color(
- GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3)));
- MAIN_PRINT("Main: END");
+ GLOBAL_DEF("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3)));
GLOBAL_DEF("application/config/icon", String());
ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon",
@@ -1722,12 +1729,34 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input_devices/pointing/emulate_mouse_from_touch", true)));
}
- MAIN_PRINT("Main: Load Remaps");
+ MAIN_PRINT("Main: Load Translations and Remaps");
+
+ translation_server->setup(); //register translations, load them, etc.
+ if (locale != "") {
+ translation_server->set_locale(locale);
+ }
+ translation_server->load_translations();
+ ResourceLoader::load_translation_remaps(); //load remaps for resources
+
+ ResourceLoader::load_path_remaps();
MAIN_PRINT("Main: Load Scene Types");
register_scene_types();
+#ifdef TOOLS_ENABLED
+ ClassDB::set_current_api(ClassDB::API_EDITOR);
+ EditorNode::register_editor_types();
+
+ ClassDB::set_current_api(ClassDB::API_CORE);
+
+#endif
+
+ MAIN_PRINT("Main: Load Modules, Physics, Drivers, Scripts");
+
+ register_platform_apis();
+ register_module_types();
+
GLOBAL_DEF("display/mouse_cursor/custom_image", String());
GLOBAL_DEF("display/mouse_cursor/custom_image_hotspot", Vector2());
GLOBAL_DEF("display/mouse_cursor/tooltip_position_offset", Point2(10, 10));
@@ -1744,18 +1773,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
Input::get_singleton()->set_custom_mouse_cursor(cursor, Input::CURSOR_ARROW, hotspot);
}
}
-#ifdef TOOLS_ENABLED
- ClassDB::set_current_api(ClassDB::API_EDITOR);
- EditorNode::register_editor_types();
-
- ClassDB::set_current_api(ClassDB::API_CORE);
-
-#endif
-
- MAIN_PRINT("Main: Load Modules, Physics, Drivers, Scripts");
-
- register_platform_apis();
- register_module_types();
camera_server = CameraServer::create();
@@ -1768,17 +1785,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
// This loads global classes, so it must happen before custom loaders and savers are registered
ScriptServer::init_languages();
- MAIN_PRINT("Main: Load Translations");
-
- translation_server->setup(); //register translations, load them, etc.
- if (locale != "") {
- translation_server->set_locale(locale);
- }
- translation_server->load_translations();
- ResourceLoader::load_translation_remaps(); //load remaps for resources
-
- ResourceLoader::load_path_remaps();
-
audio_server->load_default_bus_layout();
if (use_debug_profiler && EngineDebugger::is_active()) {
@@ -1973,8 +1979,8 @@ bool Main::start() {
#endif
- if (script == "" && game_path == "" && String(GLOBAL_DEF("application/run/main_scene", "")) != "") {
- game_path = GLOBAL_DEF("application/run/main_scene", "");
+ if (script == "" && game_path == "" && String(GLOBAL_GET("application/run/main_scene")) != "") {
+ game_path = GLOBAL_GET("application/run/main_scene");
}
MainLoop *main_loop = nullptr;
@@ -1989,7 +1995,7 @@ bool Main::start() {
if (check_only) {
if (!script_res->is_valid()) {
- OS::get_singleton()->set_exit_code(1);
+ OS::get_singleton()->set_exit_code(EXIT_FAILURE);
}
return false;
}
@@ -2007,7 +2013,7 @@ bool Main::start() {
script));
}
- script_loop->set_init_script(script_res);
+ script_loop->set_initialize_script(script_res);
main_loop = script_loop;
} else {
return false;
@@ -2026,7 +2032,7 @@ bool Main::start() {
DisplayServer::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base);
ERR_FAIL_V_MSG(false, vformat("The global class %s does not inherit from SceneTree or MainLoop.", main_loop_type));
}
- script_loop->set_init_script(script_res);
+ script_loop->set_initialize_script(script_res);
main_loop = script_loop;
}
}
@@ -2146,18 +2152,13 @@ bool Main::start() {
}
#endif
- {
- int directional_atlas_size = GLOBAL_GET("rendering/quality/directional_shadow/size");
- RenderingServer::get_singleton()->directional_shadow_atlas_set_size(directional_atlas_size);
- }
-
if (!editor && !project_manager) {
//standard helpers that can be changed from main config
- String stretch_mode = GLOBAL_DEF("display/window/stretch/mode", "disabled");
- String stretch_aspect = GLOBAL_DEF("display/window/stretch/aspect", "ignore");
- Size2i stretch_size = Size2i(GLOBAL_DEF("display/window/size/width", 0),
- GLOBAL_DEF("display/window/size/height", 0));
+ String stretch_mode = GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled");
+ String stretch_aspect = GLOBAL_DEF_BASIC("display/window/stretch/aspect", "ignore");
+ Size2i stretch_size = Size2i(GLOBAL_DEF_BASIC("display/window/size/width", 0),
+ GLOBAL_DEF_BASIC("display/window/size/height", 0));
Window::ContentScaleMode cs_sm = Window::CONTENT_SCALE_MODE_DISABLED;
if (stretch_mode == "canvas_items") {
@@ -2194,49 +2195,33 @@ bool Main::start() {
DisplayServer::get_singleton()->window_set_title(appname);
#endif
- int shadow_atlas_size = GLOBAL_GET("rendering/quality/shadow_atlas/size");
- int shadow_atlas_q0_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_0_subdiv");
- int shadow_atlas_q1_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_1_subdiv");
- int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv");
- int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv");
-
- sml->get_root()->set_shadow_atlas_size(shadow_atlas_size);
- sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(
- shadow_atlas_q0_subdiv));
- sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(
- shadow_atlas_q1_subdiv));
- sml->get_root()->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(
- shadow_atlas_q2_subdiv));
- sml->get_root()->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(
- shadow_atlas_q3_subdiv));
-
bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
sml->get_root()->set_snap_controls_to_pixels(snap_controls);
- bool font_oversampling = GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", true);
+ bool font_oversampling = GLOBAL_DEF("gui/fonts/dynamic_fonts/use_oversampling", true);
sml->get_root()->set_use_font_oversampling(font_oversampling);
- int texture_filter = GLOBAL_DEF("rendering/canvas_textures/default_texture_filter", 1);
- int texture_repeat = GLOBAL_DEF("rendering/canvas_textures/default_texture_repeat", 0);
+ int texture_filter = GLOBAL_DEF("rendering/textures/canvas_textures/default_texture_filter", 1);
+ int texture_repeat = GLOBAL_DEF("rendering/textures/canvas_textures/default_texture_repeat", 0);
sml->get_root()->set_default_canvas_item_texture_filter(
Viewport::DefaultCanvasItemTextureFilter(texture_filter));
sml->get_root()->set_default_canvas_item_texture_repeat(
Viewport::DefaultCanvasItemTextureRepeat(texture_repeat));
} else {
- GLOBAL_DEF("display/window/stretch/mode", "disabled");
+ GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode",
PropertyInfo(Variant::STRING,
"display/window/stretch/mode",
PROPERTY_HINT_ENUM,
"disabled,canvas_items,viewport"));
- GLOBAL_DEF("display/window/stretch/aspect", "ignore");
+ GLOBAL_DEF_BASIC("display/window/stretch/aspect", "ignore");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect",
PropertyInfo(Variant::STRING,
"display/window/stretch/aspect",
PROPERTY_HINT_ENUM,
"ignore,keep,keep_width,keep_height,expand"));
- GLOBAL_DEF("display/window/stretch/shrink", 1.0);
+ GLOBAL_DEF_BASIC("display/window/stretch/shrink", 1.0);
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink",
PropertyInfo(Variant::FLOAT,
"display/window/stretch/shrink",
@@ -2244,18 +2229,18 @@ bool Main::start() {
"1.0,8.0,0.1"));
sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
- GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
- GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", true);
+ GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true);
+ GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true);
- GLOBAL_DEF("rendering/canvas_textures/default_texture_filter", 1);
+ GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_filter", 1);
ProjectSettings::get_singleton()->set_custom_property_info(
- "rendering/canvas_textures/default_texture_filter",
- PropertyInfo(Variant::INT, "rendering/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM,
+ "rendering/textures/canvas_textures/default_texture_filter",
+ PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM,
"Nearest,Linear,MipmapLinear,MipmapNearest"));
- GLOBAL_DEF("rendering/canvas_textures/default_texture_repeat", 0);
+ GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_repeat", 0);
ProjectSettings::get_singleton()->set_custom_property_info(
- "rendering/canvas_textures/default_texture_repeat",
- PropertyInfo(Variant::INT, "rendering/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM,
+ "rendering/textures/canvas_textures/default_texture_repeat",
+ PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM,
"Disable,Enable,Mirror"));
}
@@ -2422,7 +2407,7 @@ bool Main::is_iterating() {
// For performance metrics.
static uint64_t physics_process_max = 0;
-static uint64_t idle_process_max = 0;
+static uint64_t process_max = 0;
bool Main::iteration() {
//for now do not error on this
@@ -2438,19 +2423,19 @@ bool Main::iteration() {
uint64_t ticks_elapsed = ticks - last_ticks;
int physics_fps = Engine::get_singleton()->get_iterations_per_second();
- float frame_slice = 1.0 / physics_fps;
+ float physics_step = 1.0 / physics_fps;
float time_scale = Engine::get_singleton()->get_time_scale();
- MainFrameTime advance = main_timer_sync.advance(frame_slice, physics_fps);
- double step = advance.idle_step;
- double scaled_step = step * time_scale;
+ MainFrameTime advance = main_timer_sync.advance(physics_step, physics_fps);
+ double process_step = advance.process_step;
+ double scaled_step = process_step * time_scale;
- Engine::get_singleton()->_frame_step = step;
+ Engine::get_singleton()->_process_step = process_step;
Engine::get_singleton()->_physics_interpolation_fraction = advance.interpolation_fraction;
uint64_t physics_process_ticks = 0;
- uint64_t idle_process_ticks = 0;
+ uint64_t process_ticks = 0;
frame += ticks_elapsed;
@@ -2458,7 +2443,7 @@ bool Main::iteration() {
static const int max_physics_steps = 8;
if (fixed_fps == -1 && advance.physics_steps > max_physics_steps) {
- step -= (advance.physics_steps - max_physics_steps) * frame_slice;
+ process_step -= (advance.physics_steps - max_physics_steps) * physics_step;
advance.physics_steps = max_physics_steps;
}
@@ -2469,38 +2454,39 @@ bool Main::iteration() {
for (int iters = 0; iters < advance.physics_steps; ++iters) {
uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();
+ PhysicsServer3D::get_singleton()->sync();
PhysicsServer3D::get_singleton()->flush_queries();
PhysicsServer2D::get_singleton()->sync();
PhysicsServer2D::get_singleton()->flush_queries();
- if (OS::get_singleton()->get_main_loop()->iteration(frame_slice * time_scale)) {
+ if (OS::get_singleton()->get_main_loop()->physics_process(physics_step * time_scale)) {
exit = true;
break;
}
- NavigationServer3D::get_singleton_mut()->process(frame_slice * time_scale);
+ NavigationServer3D::get_singleton_mut()->process(physics_step * time_scale);
message_queue->flush();
- PhysicsServer3D::get_singleton()->step(frame_slice * time_scale);
+ PhysicsServer3D::get_singleton()->end_sync();
+ PhysicsServer3D::get_singleton()->step(physics_step * time_scale);
PhysicsServer2D::get_singleton()->end_sync();
- PhysicsServer2D::get_singleton()->step(frame_slice * time_scale);
+ PhysicsServer2D::get_singleton()->step(physics_step * time_scale);
message_queue->flush();
- physics_process_ticks = MAX(physics_process_ticks, OS::get_singleton()->get_ticks_usec() -
- physics_begin); // keep the largest one for reference
+ physics_process_ticks = MAX(physics_process_ticks, OS::get_singleton()->get_ticks_usec() - physics_begin); // keep the largest one for reference
physics_process_max = MAX(OS::get_singleton()->get_ticks_usec() - physics_begin, physics_process_max);
Engine::get_singleton()->_physics_frames++;
}
Engine::get_singleton()->_in_physics = false;
- uint64_t idle_begin = OS::get_singleton()->get_ticks_usec();
+ uint64_t process_begin = OS::get_singleton()->get_ticks_usec();
- if (OS::get_singleton()->get_main_loop()->idle(step * time_scale)) {
+ if (OS::get_singleton()->get_main_loop()->process(process_step * time_scale)) {
exit = true;
}
message_queue->flush();
@@ -2521,8 +2507,8 @@ bool Main::iteration() {
}
}
- idle_process_ticks = OS::get_singleton()->get_ticks_usec() - idle_begin;
- idle_process_max = MAX(idle_process_ticks, idle_process_max);
+ process_ticks = OS::get_singleton()->get_ticks_usec() - process_begin;
+ process_max = MAX(process_ticks, process_max);
uint64_t frame_time = OS::get_singleton()->get_ticks_usec() - ticks;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@@ -2532,11 +2518,11 @@ bool Main::iteration() {
AudioServer::get_singleton()->update();
if (EngineDebugger::is_active()) {
- EngineDebugger::get_singleton()->iteration(frame_time, idle_process_ticks, physics_process_ticks, frame_slice);
+ EngineDebugger::get_singleton()->iteration(frame_time, process_ticks, physics_process_ticks, physics_step);
}
frames++;
- Engine::get_singleton()->_idle_frames++;
+ Engine::get_singleton()->_process_frames++;
if (frame > 1000000) {
if (editor || project_manager) {
@@ -2548,9 +2534,9 @@ bool Main::iteration() {
}
Engine::get_singleton()->_fps = frames;
- performance->set_process_time(USEC_TO_SEC(idle_process_max));
+ performance->set_process_time(USEC_TO_SEC(process_max));
performance->set_physics_process_time(USEC_TO_SEC(physics_process_max));
- idle_process_max = 0;
+ process_max = 0;
physics_process_max = 0;
frame %= 1000000;
@@ -2593,8 +2579,10 @@ void Main::force_redraw() {
* so that the engine closes cleanly without leaking memory or crashing.
* The order matters as some of those steps are linked with each other.
*/
-void Main::cleanup() {
- ERR_FAIL_COND(!_start_success);
+void Main::cleanup(bool p_force) {
+ if (!p_force) {
+ ERR_FAIL_COND(!_start_success);
+ }
EngineDebugger::deinitialize();
@@ -2687,8 +2675,7 @@ void Main::cleanup() {
//attempt to restart with arguments
String exec = OS::get_singleton()->get_executable_path();
List<String> args = OS::get_singleton()->get_restart_on_exit_arguments();
- OS::ProcessID pid = 0;
- OS::get_singleton()->execute(exec, args, false, &pid);
+ OS::get_singleton()->create_process(exec, args);
OS::get_singleton()->set_restart_on_exit(false, List<String>()); //clear list (uses memory)
}
diff --git a/main/main.h b/main/main.h
index 168b2e5e86..f4fff6b97e 100644
--- a/main/main.h
+++ b/main/main.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,7 +59,7 @@ public:
static bool is_iterating();
- static void cleanup();
+ static void cleanup(bool p_force = false);
};
// Test main override is for the testing behaviour.
diff --git a/main/main_timer_sync.cpp b/main/main_timer_sync.cpp
index 5252ea005b..93448d0904 100644
--- a/main/main_timer_sync.cpp
+++ b/main/main_timer_sync.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,17 +30,17 @@
#include "main_timer_sync.h"
-void MainFrameTime::clamp_idle(float min_idle_step, float max_idle_step) {
- if (idle_step < min_idle_step) {
- idle_step = min_idle_step;
- } else if (idle_step > max_idle_step) {
- idle_step = max_idle_step;
+void MainFrameTime::clamp_process_step(float min_process_step, float max_process_step) {
+ if (process_step < min_process_step) {
+ process_step = min_process_step;
+ } else if (process_step > max_process_step) {
+ process_step = max_process_step;
}
}
/////////////////////////////////
-// returns the fraction of p_frame_slice required for the timer to overshoot
+// returns the fraction of p_physics_step required for the timer to overshoot
// before advance_core considers changing the physics_steps return from
// the typical values as defined by typical_physics_steps
float MainTimerSync::get_physics_jitter_fix() {
@@ -72,15 +72,15 @@ int MainTimerSync::get_average_physics_steps(float &p_min, float &p_max) {
return CONTROL_STEPS;
}
-// advance physics clock by p_idle_step, return appropriate number of steps to simulate
-MainFrameTime MainTimerSync::advance_core(float p_frame_slice, int p_iterations_per_second, float p_idle_step) {
+// advance physics clock by p_process_step, return appropriate number of steps to simulate
+MainFrameTime MainTimerSync::advance_core(float p_physics_step, int p_physics_fps, float p_process_step) {
MainFrameTime ret;
- ret.idle_step = p_idle_step;
+ ret.process_step = p_process_step;
// simple determination of number of physics iteration
- time_accum += ret.idle_step;
- ret.physics_steps = floor(time_accum * p_iterations_per_second);
+ time_accum += ret.process_step;
+ ret.physics_steps = floor(time_accum * p_physics_fps);
int min_typical_steps = typical_physics_steps[0];
int max_typical_steps = min_typical_steps + 1;
@@ -107,7 +107,7 @@ MainFrameTime MainTimerSync::advance_core(float p_frame_slice, int p_iterations_
// try to keep it consistent with previous iterations
if (ret.physics_steps < min_typical_steps) {
- const int max_possible_steps = floor((time_accum)*p_iterations_per_second + get_physics_jitter_fix());
+ const int max_possible_steps = floor((time_accum)*p_physics_fps + get_physics_jitter_fix());
if (max_possible_steps < min_typical_steps) {
ret.physics_steps = max_possible_steps;
update_typical = true;
@@ -115,7 +115,7 @@ MainFrameTime MainTimerSync::advance_core(float p_frame_slice, int p_iterations_
ret.physics_steps = min_typical_steps;
}
} else if (ret.physics_steps > max_typical_steps) {
- const int min_possible_steps = floor((time_accum)*p_iterations_per_second - get_physics_jitter_fix());
+ const int min_possible_steps = floor((time_accum)*p_physics_fps - get_physics_jitter_fix());
if (min_possible_steps > max_typical_steps) {
ret.physics_steps = min_possible_steps;
update_typical = true;
@@ -124,7 +124,7 @@ MainFrameTime MainTimerSync::advance_core(float p_frame_slice, int p_iterations_
}
}
- time_accum -= ret.physics_steps * p_frame_slice;
+ time_accum -= ret.physics_steps * p_physics_step;
// keep track of accumulated step counts
for (int i = CONTROL_STEPS - 2; i >= 0; --i) {
@@ -146,52 +146,52 @@ MainFrameTime MainTimerSync::advance_core(float p_frame_slice, int p_iterations_
}
// calls advance_core, keeps track of deficit it adds to animaption_step, make sure the deficit sum stays close to zero
-MainFrameTime MainTimerSync::advance_checked(float p_frame_slice, int p_iterations_per_second, float p_idle_step) {
+MainFrameTime MainTimerSync::advance_checked(float p_physics_step, int p_physics_fps, float p_process_step) {
if (fixed_fps != -1) {
- p_idle_step = 1.0 / fixed_fps;
+ p_process_step = 1.0 / fixed_fps;
}
// compensate for last deficit
- p_idle_step += time_deficit;
+ p_process_step += time_deficit;
- MainFrameTime ret = advance_core(p_frame_slice, p_iterations_per_second, p_idle_step);
+ MainFrameTime ret = advance_core(p_physics_step, p_physics_fps, p_process_step);
- // we will do some clamping on ret.idle_step and need to sync those changes to time_accum,
+ // we will do some clamping on ret.process_step and need to sync those changes to time_accum,
// that's easiest if we just remember their fixed difference now
- const double idle_minus_accum = ret.idle_step - time_accum;
+ const double process_minus_accum = ret.process_step - time_accum;
- // first, least important clamping: keep ret.idle_step consistent with typical_physics_steps.
- // this smoothes out the idle steps and culls small but quick variations.
+ // first, least important clamping: keep ret.process_step consistent with typical_physics_steps.
+ // this smoothes out the process steps and culls small but quick variations.
{
float min_average_physics_steps, max_average_physics_steps;
int consistent_steps = get_average_physics_steps(min_average_physics_steps, max_average_physics_steps);
if (consistent_steps > 3) {
- ret.clamp_idle(min_average_physics_steps * p_frame_slice, max_average_physics_steps * p_frame_slice);
+ ret.clamp_process_step(min_average_physics_steps * p_physics_step, max_average_physics_steps * p_physics_step);
}
}
// second clamping: keep abs(time_deficit) < jitter_fix * frame_slise
- float max_clock_deviation = get_physics_jitter_fix() * p_frame_slice;
- ret.clamp_idle(p_idle_step - max_clock_deviation, p_idle_step + max_clock_deviation);
+ float max_clock_deviation = get_physics_jitter_fix() * p_physics_step;
+ ret.clamp_process_step(p_process_step - max_clock_deviation, p_process_step + max_clock_deviation);
- // last clamping: make sure time_accum is between 0 and p_frame_slice for consistency between physics and idle
- ret.clamp_idle(idle_minus_accum, idle_minus_accum + p_frame_slice);
+ // last clamping: make sure time_accum is between 0 and p_physics_step for consistency between physics and process
+ ret.clamp_process_step(process_minus_accum, process_minus_accum + p_physics_step);
// restore time_accum
- time_accum = ret.idle_step - idle_minus_accum;
+ time_accum = ret.process_step - process_minus_accum;
// track deficit
- time_deficit = p_idle_step - ret.idle_step;
+ time_deficit = p_process_step - ret.process_step;
- // p_frame_slice is 1.0 / iterations_per_sec
+ // p_physics_step is 1.0 / iterations_per_sec
// i.e. the time in seconds taken by a physics tick
- ret.interpolation_fraction = time_accum / p_frame_slice;
+ ret.interpolation_fraction = time_accum / p_physics_step;
return ret;
}
// determine wall clock step since last iteration
-float MainTimerSync::get_cpu_idle_step() {
+float MainTimerSync::get_cpu_process_step() {
uint64_t cpu_ticks_elapsed = current_cpu_ticks_usec - last_cpu_ticks_usec;
last_cpu_ticks_usec = current_cpu_ticks_usec;
@@ -219,9 +219,9 @@ void MainTimerSync::set_fixed_fps(int p_fixed_fps) {
fixed_fps = p_fixed_fps;
}
-// advance one frame, return timesteps to take
-MainFrameTime MainTimerSync::advance(float p_frame_slice, int p_iterations_per_second) {
- float cpu_idle_step = get_cpu_idle_step();
+// advance one physics frame, return timesteps to take
+MainFrameTime MainTimerSync::advance(float p_physics_step, int p_physics_fps) {
+ float cpu_process_step = get_cpu_process_step();
- return advance_checked(p_frame_slice, p_iterations_per_second, cpu_idle_step);
+ return advance_checked(p_physics_step, p_physics_fps, cpu_process_step);
}
diff --git a/main/main_timer_sync.h b/main/main_timer_sync.h
index f8497140cd..884978bf96 100644
--- a/main/main_timer_sync.h
+++ b/main/main_timer_sync.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,11 +34,11 @@
#include "core/config/engine.h"
struct MainFrameTime {
- float idle_step; // time to advance idles for (argument to process())
+ float process_step; // delta time to advance during process()
int physics_steps; // number of times to iterate the physics engine
float interpolation_fraction; // fraction through the current physics tick
- void clamp_idle(float min_idle_step, float max_idle_step);
+ void clamp_process_step(float min_process_step, float max_process_step);
};
class MainTimerSync {
@@ -49,7 +49,7 @@ class MainTimerSync {
// logical game time since last physics timestep
float time_accum = 0;
- // current difference between wall clock time and reported sum of idle_steps
+ // current difference between wall clock time and reported sum of process_steps
float time_deficit = 0;
// number of frames back for keeping accumulated physics steps roughly constant.
@@ -67,7 +67,7 @@ class MainTimerSync {
int fixed_fps = 0;
protected:
- // returns the fraction of p_frame_slice required for the timer to overshoot
+ // returns the fraction of p_physics_step required for the timer to overshoot
// before advance_core considers changing the physics_steps return from
// the typical values as defined by typical_physics_steps
float get_physics_jitter_fix();
@@ -76,14 +76,14 @@ protected:
// return value: number of frames back this data is consistent
int get_average_physics_steps(float &p_min, float &p_max);
- // advance physics clock by p_idle_step, return appropriate number of steps to simulate
- MainFrameTime advance_core(float p_frame_slice, int p_iterations_per_second, float p_idle_step);
+ // advance physics clock by p_process_step, return appropriate number of steps to simulate
+ MainFrameTime advance_core(float p_physics_step, int p_physics_fps, float p_process_step);
// calls advance_core, keeps track of deficit it adds to animaption_step, make sure the deficit sum stays close to zero
- MainFrameTime advance_checked(float p_frame_slice, int p_iterations_per_second, float p_idle_step);
+ MainFrameTime advance_checked(float p_physics_step, int p_physics_fps, float p_process_step);
// determine wall clock step since last iteration
- float get_cpu_idle_step();
+ float get_cpu_process_step();
public:
MainTimerSync();
@@ -96,7 +96,7 @@ public:
void set_fixed_fps(int p_fixed_fps);
// advance one frame, return timesteps to take
- MainFrameTime advance(float p_frame_slice, int p_iterations_per_second);
+ MainFrameTime advance(float p_physics_step, int p_physics_fps);
};
#endif // MAIN_TIMER_SYNC_H
diff --git a/main/performance.cpp b/main/performance.cpp
index 9de269ba5f..a2e53f2ee2 100644
--- a/main/performance.cpp
+++ b/main/performance.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -119,7 +119,7 @@ String Performance::get_monitor_name(Monitor p_monitor) const {
"physics_3d/active_objects",
"physics_3d/collision_pairs",
"physics_3d/islands",
- "audio/output_latency",
+ "audio/driver/output_latency",
};
diff --git a/main/performance.h b/main/performance.h
index 40f1d5cb05..122e5a4f9a 100644
--- a/main/performance.h
+++ b/main/performance.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/methods.py b/methods.py
index 15eb82ae74..9b29eadc16 100644
--- a/methods.py
+++ b/methods.py
@@ -6,9 +6,11 @@ from collections import OrderedDict
# We need to define our own `Action` method to control the verbosity of output
# and whenever we need to run those commands in a subprocess on some platforms.
-from SCons.Script import Action
from SCons import Node
+from SCons.Script import Action
+from SCons.Script import ARGUMENTS
from SCons.Script import Glob
+from SCons.Variables.BoolVariable import _text2bool
from platform_methods import run_in_subprocess
@@ -145,34 +147,97 @@ def parse_cg_file(fname, uniforms, sizes, conditionals):
fs.close()
-def detect_modules(at_path):
- module_list = OrderedDict() # name : path
+def get_cmdline_bool(option, default):
+ """We use `ARGUMENTS.get()` to check if options were manually overridden on the command line,
+ and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings.
+ """
+ cmdline_val = ARGUMENTS.get(option)
+ if cmdline_val is not None:
+ return _text2bool(cmdline_val)
+ else:
+ return default
- modules_glob = os.path.join(at_path, "*")
- files = glob.glob(modules_glob)
- files.sort() # so register_module_types does not change that often, and also plugins are registered in alphabetic order
- for x in files:
- if not is_module(x):
- continue
- name = os.path.basename(x)
- path = x.replace("\\", "/") # win32
- module_list[name] = path
+def detect_modules(search_path, recursive=False):
+ """Detects and collects a list of C++ modules at specified path
- return module_list
+ `search_path` - a directory path containing modules. The path may point to
+ a single module, which may have other nested modules. A module must have
+ "register_types.h", "SCsub", "config.py" files created to be detected.
+
+ `recursive` - if `True`, then all subdirectories are searched for modules as
+ specified by the `search_path`, otherwise collects all modules under the
+ `search_path` directory. If the `search_path` is a module, it is collected
+ in all cases.
+
+ Returns an `OrderedDict` with module names as keys, and directory paths as
+ values. If a path is relative, then it is a built-in module. If a path is
+ absolute, then it is a custom module collected outside of the engine source.
+ """
+ modules = OrderedDict()
+
+ def add_module(path):
+ module_name = os.path.basename(path)
+ module_path = path.replace("\\", "/") # win32
+ modules[module_name] = module_path
+
+ def is_engine(path):
+ # Prevent recursively detecting modules in self and other
+ # Godot sources when using `custom_modules` build option.
+ version_path = os.path.join(path, "version.py")
+ if os.path.exists(version_path):
+ with open(version_path) as f:
+ if 'short_name = "godot"' in f.read():
+ return True
+ return False
+
+ def get_files(path):
+ files = glob.glob(os.path.join(path, "*"))
+ # Sort so that `register_module_types` does not change that often,
+ # and plugins are registered in alphabetic order as well.
+ files.sort()
+ return files
+
+ if not recursive:
+ if is_module(search_path):
+ add_module(search_path)
+ for path in get_files(search_path):
+ if is_engine(path):
+ continue
+ if is_module(path):
+ add_module(path)
+ else:
+ to_search = [search_path]
+ while to_search:
+ path = to_search.pop()
+ if is_module(path):
+ add_module(path)
+ for child in get_files(path):
+ if not os.path.isdir(child):
+ continue
+ if is_engine(child):
+ continue
+ to_search.insert(0, child)
+ return modules
def is_module(path):
- return os.path.isdir(path) and os.path.exists(os.path.join(path, "SCsub"))
+ if not os.path.isdir(path):
+ return False
+ must_exist = ["register_types.h", "SCsub", "config.py"]
+ for f in must_exist:
+ if not os.path.exists(os.path.join(path, f)):
+ return False
+ return True
-def write_modules(module_list):
+def write_modules(modules):
includes_cpp = ""
preregister_cpp = ""
register_cpp = ""
unregister_cpp = ""
- for name, path in module_list.items():
+ for name, path in modules.items():
try:
with open(os.path.join(path, "register_types.h")):
includes_cpp += '#include "' + path + '/register_types.h"\n'
@@ -230,8 +295,6 @@ def convert_custom_modules_path(path):
raise ValueError(err_msg % "point to an existing directory.")
if path == os.path.realpath("modules"):
raise ValueError(err_msg % "be a directory other than built-in `modules` directory.")
- if is_module(path):
- raise ValueError(err_msg % "point to a directory with modules, not a single module.")
return path
diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html
index bf608dfa49..3bf87f3506 100644
--- a/misc/dist/html/editor.html
+++ b/misc/dist/html/editor.html
@@ -2,10 +2,27 @@
<html xmlns='http://www.w3.org/1999/xhtml' lang='' xml:lang=''>
<head>
<meta charset='utf-8' />
- <meta name='viewport' content='width=device-width, user-scalable=no' />
+ <meta name='viewport' content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no' />
+ <meta name="mobile-web-app-capable" content="yes" />
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <meta name="application-name" content="Godot" />
+ <meta name="apple-mobile-web-app-title" content="Godot" />
+ <meta name="theme-color" content="#478cbf" />
+ <meta name="msapplication-navbutton-color" content="#478cbf" />
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+ <meta name="msapplication-starturl" content="/latest" />
<link id='-gd-engine-icon' rel='icon' type='image/png' href='favicon.png' />
- <title></title>
- <style type='text/css'>
+ <link rel="apple-touch-icon" type="image/png" href="favicon.png" />
+ <link rel="manifest" href="manifest.json" />
+ <title>Godot Engine Web Editor (@GODOT_VERSION@)</title>
+ <style>
+ *:focus {
+ /* More visible outline for better keyboard navigation. */
+ outline: 0.125rem solid hsl(220, 100%, 62.5%);
+ /* Make the outline always appear above other elements. */
+ /* Otherwise, one of its sides can be hidden by tabs in the Download and More layouts. */
+ position: relative;
+ }
body {
touch-action: none;
@@ -18,13 +35,44 @@
overflow: hidden;
}
+ a {
+ color: hsl(205, 100%, 75%);
+ text-decoration-color: hsla(205, 100%, 75%, 0.3);
+ text-decoration-thickness: 0.125rem;
+ }
+
+ a:hover {
+ filter: brightness(117.5%);
+ }
+
+ a:active {
+ filter: brightness(82.5%);
+ }
+
+ #tabs-buttons {
+ /* Match the default background color of the editor window for a seamless appearance. */
+ background-color: #202531;
+ }
+
+ #tab-game {
+ /* Use a pure black background to better distinguish the running project */
+ /* from the editor window, and to use a more neutral background color (no tint). */
+ background-color: black;
+ /* Make the background span the entire page height. */
+ min-height: 100vh;
+ }
+
#canvas, #gameCanvas {
display: block;
margin: 0;
color: white;
}
- #canvas:focus, #gameCanvas:focus {
+ /* Don't show distracting focus outlines for the main tabs' contents. */
+ #tab-editor canvas:focus,
+ #tab-game canvas:focus,
+ #canvas:focus,
+ #gameCanvas:focus {
outline: none;
}
@@ -45,10 +93,6 @@
margin: 0 0.5rem;
}
- .btn:focus {
- outline: 1px solid #699ce8;
- }
-
.btn:not(:disabled):hover {
color: #e0e1e5;
border-color: #666c7b;
@@ -169,13 +213,24 @@
<option value="GLES3">WebGL 2</option>
</select>
<br />
- <img src="logo.svg">
+ <img src="logo.svg" width="1024" height="414" style="width: auto; height: auto; max-width: 85%; max-height: 250px" />
+ <br />
+ @GODOT_VERSION@
+ <br />
+ <a href="releases/">Need an old version?</a>
+ <br />
+ <br />
<br />
<label for="zip-file" style="margin-right: 1rem">Preload project ZIP:</label> <input id="zip-file" type="file" id="files" name="files" style="margin-bottom: 1rem"/>
<br />
- <button id="startButton" class="btn" style="margin-bottom: 4rem">Start Godot editor</button>
+<a href="demo.zip">(Try this for example)</a>
+ <br />
+ <br />
+ <button id="startButton" class="btn" style="margin-bottom: 4rem; font-weight: 700">Start Godot editor</button>
<br />
- <button class="btn" onclick="clearPersistence()">Clear persistent data</button>
+ <button class="btn" onclick="clearPersistence()" style="margin-bottom: 1.5rem">Clear persistent data</button>
+ <br />
+ <a href="https://docs.godotengine.org/en/latest/tutorials/editor/using_the_web_editor.html">Web editor documentation</a>
</div>
</div>
<div id='tab-editor' style="display: none;">
@@ -205,11 +260,17 @@
<div id='status-notice' class='godot' style='display: none;'></div>
</div>
</div>
+ <script>
+ window.addEventListener("load", () => {
+ if ("serviceWorker" in navigator) {
+ navigator.serviceWorker.register("service.worker.js");
+ }
+ });
+ </script>
+ <script src='godot.tools.js'></script>
+ <script>//<![CDATA[
- <script type='text/javascript' src='godot.tools.js'></script>
- <script type='text/javascript'>//<![CDATA[
-
- var engine = new Engine;
+ var editor = null;
var game = null;
var setStatusMode;
var setStatusNotice;
@@ -231,13 +292,11 @@
});
}
- if (!window.confirm("Are you sure you want to delete all the locally stored files?")) {
+ if (!window.confirm("Are you sure you want to delete all the locally stored files?\nClicking \"OK\" will permanently remove your projects and editor settings!")) {
return;
}
Promise.all([
- deleteDB("/home/web_user/projects"),
- deleteDB("/home/web_user/.config"),
- deleteDB("/home/web_user/.cache"),
+ deleteDB("/home/web_user"),
]).then(function(results) {
alert("Done.");
}).catch(function (err) {
@@ -259,6 +318,10 @@
tabs.forEach(function (elem) {
if (elem.id == 'tab-' + name) {
elem.style.display = 'block';
+ if (name == 'editor' || name == 'game') {
+ const canvas = document.getElementById(name + '-canvas');
+ canvas.focus();
+ }
} else {
elem.style.display = 'none';
}
@@ -292,14 +355,14 @@
function closeEditor() {
closeGame();
- if (engine) {
- engine.requestQuit();
+ if (editor) {
+ editor.requestQuit();
}
}
function startEditor(zip) {
const INDETERMINATE_STATUS_STEP_MS = 100;
- const persistentPaths = ['/home/web_user/.config', '/home/web_user/.cache', '/home/web_user/projects'];
+ const persistentPaths = ['/home/web_user'];
var editorCanvas = document.getElementById('editor-canvas');
var gameCanvas = document.getElementById('game-canvas');
@@ -307,6 +370,7 @@
var statusProgressInner = document.getElementById('status-progress-inner');
var statusIndeterminate = document.getElementById('status-indeterminate');
var statusNotice = document.getElementById('status-notice');
+ var headerDiv = document.getElementById('tabs-buttons');
var initializing = true;
var statusMode = 'hidden';
@@ -320,16 +384,23 @@
}
requestAnimationFrame(animate);
+ var lastScale = 0;
+ var lastWidth = 0;
+ var lastHeight = 0;
function adjustCanvasDimensions() {
var scale = window.devicePixelRatio || 1;
- var header = document.getElementById('tabs-buttons');
- var headerHeight = header.offsetHeight + 1;
+ var headerHeight = headerDiv.offsetHeight + 1;
var width = window.innerWidth;
var height = window.innerHeight - headerHeight;
- editorCanvas.width = width * scale;
- editorCanvas.height = height * scale;
- editorCanvas.style.width = width + "px";
- editorCanvas.style.height = height + "px";
+ if (lastScale !== scale || lastWidth !== width || lastHeight !== height) {
+ editorCanvas.width = width * scale;
+ editorCanvas.height = height * scale;
+ editorCanvas.style.width = width + "px";
+ editorCanvas.style.height = height + "px";
+ lastScale = scale;
+ lastWidth = width;
+ lastHeight = height;
+ }
}
animationCallbacks.push(adjustCanvasDimensions);
adjustCanvasDimensions();
@@ -383,24 +454,23 @@
});
};
- engine.setProgressFunc((current, total) => {
- if (total > 0) {
- statusProgressInner.style.width = current/total * 100 + '%';
- setStatusMode('progress');
- if (current === total) {
- // wait for progress bar animation
- setTimeout(() => {
- setStatusMode('indeterminate');
- }, 100);
- }
- } else {
- setStatusMode('indeterminate');
- }
- });
-
- engine.setPersistentPaths(persistentPaths);
+ const gameConfig = {
+ 'persistentPaths': persistentPaths,
+ 'unloadAfterInit': false,
+ 'canvas': gameCanvas,
+ 'canvasResizePolicy': 1,
+ 'onExit': function () {
+ setGameTabEnabled(false);
+ showTab('editor');
+ game = null;
+ },
+ };
- engine.setOnExecute(function(args) {
+ var OnEditorExit = function () {
+ showTab('loader');
+ setLoaderEnabled(true);
+ };
+ function Execute(args) {
const is_editor = args.filter(function(v) { return v == '--editor' || v == '-e' }).length != 0;
const is_project_manager = args.filter(function(v) { return v == '--project-manager' }).length != 0;
const is_game = !is_editor && !is_project_manager;
@@ -413,42 +483,60 @@
return;
}
setGameTabEnabled(true);
- game = new Engine();
- game.setPersistentPaths(persistentPaths);
- game.setUnloadAfterInit(false);
- game.setOnExecute(engine.onExecute);
- game.setCanvas(gameCanvas);
- game.setCanvasResizedOnStart(true);
- game.setOnExit(function() {
- setGameTabEnabled(false);
- showTab('editor');
- game = null;
- });
+ game = new Engine(gameConfig);
showTab('game');
game.init().then(function() {
requestAnimationFrame(function() {
- game.start.apply(game, args).then(function() {
+ game.start({'args': args}).then(function() {
gameCanvas.focus();
});
});
});
} else { // New editor instances will be run in the same canvas. We want to wait for it to exit.
- engine.setOnExit(function(code) {
+ OnEditorExit = function(code) {
setLoaderEnabled(true);
setTimeout(function() {
- engine.init().then(function() {
+ editor.init().then(function() {
setLoaderEnabled(false);
- engine.setOnExit(function() {
+ OnEditorExit = function() {
showTab('loader');
setLoaderEnabled(true);
- });
- engine.start.apply(engine, args);
+ };
+ editor.start({'args': args});
});
}, 0);
- engine.setOnExit(null);
- });
+ OnEditorExit = null;
+ };
}
- });
+ }
+
+ const editorConfig = {
+ 'unloadAfterInit': false,
+ 'onProgress': function progressFunction (current, total) {
+ if (total > 0) {
+ statusProgressInner.style.width = current/total * 100 + '%';
+ setStatusMode('progress');
+ if (current === total) {
+ // wait for progress bar animation
+ setTimeout(() => {
+ setStatusMode('indeterminate');
+ }, 100);
+ }
+ } else {
+ setStatusMode('indeterminate');
+ }
+ },
+ 'canvas': editorCanvas,
+ 'canvasResizePolicy': 0,
+ 'onExit': function() {
+ if (OnEditorExit) {
+ OnEditorExit();
+ }
+ },
+ 'onExecute': Execute,
+ 'persistentPaths': persistentPaths,
+ };
+ editor = new Engine(editorConfig);
function displayFailureNotice(err) {
var msg = err.message || err;
@@ -462,26 +550,20 @@
displayFailureNotice('WebGL not available');
} else {
setStatusMode('indeterminate');
- engine.setCanvas(editorCanvas);
- engine.setUnloadAfterInit(false); // Don't want to reload when starting game.
- engine.init('godot.tools').then(function() {
+ editor.init('godot.tools').then(function() {
if (zip) {
- engine.copyToFS("/home/web_user/preload.zip", zip);
+ editor.copyToFS("/tmp/preload.zip", zip);
}
try {
// Avoid user creating project in the persistent root folder.
- engine.copyToFS("/home/web_user/projects/keep", new Uint8Array());
+ editor.copyToFS("/home/web_user/keep", new Uint8Array());
} catch(e) {
// File exists
}
//selectVideoMode();
showTab('editor');
setLoaderEnabled(false);
- engine.setOnExit(function() {
- showTab('loader');
- setLoaderEnabled(true);
- });
- engine.start('--video-driver', video_driver).then(function() {
+ editor.start({'args': ['--video-driver', video_driver]}).then(function() {
setStatusMode('hidden');
initializing = false;
});
diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html
index 85c5305b85..abc0479739 100644
--- a/misc/dist/html/full-size.html
+++ b/misc/dist/html/full-size.html
@@ -134,22 +134,14 @@ $GODOT_HEAD_INCLUDE
<div id='status-notice' class='godot' style='display: none;'></div>
</div>
- <script type='text/javascript' src='$GODOT_BASENAME.js'></script>
+ <script type='text/javascript' src='$GODOT_URL'></script>
<script type='text/javascript'>//<![CDATA[
- var engine = new Engine;
- var setStatusMode;
- var setStatusNotice;
+ const GODOT_CONFIG = $GODOT_CONFIG;
+ var engine = new Engine(GODOT_CONFIG);
(function() {
- const EXECUTABLE_NAME = '$GODOT_BASENAME';
- const MAIN_PACK = '$GODOT_BASENAME.pck';
- const EXTRA_ARGS = JSON.parse('$GODOT_ARGS');
- const GDNATIVE_LIBS = [$GODOT_GDNATIVE_LIBS];
const INDETERMINATE_STATUS_STEP_MS = 100;
- const FULL_WINDOW = $GODOT_FULL_WINDOW;
-
- var canvas = document.getElementById('canvas');
var statusProgress = document.getElementById('status-progress');
var statusProgressInner = document.getElementById('status-progress-inner');
var statusIndeterminate = document.getElementById('status-indeterminate');
@@ -157,9 +149,6 @@ $GODOT_HEAD_INCLUDE
var initializing = true;
var statusMode = 'hidden';
- var lastWidth = 0;
- var lastHeight = 0;
- var lastScale = 0;
var animationCallbacks = [];
function animate(time) {
@@ -168,26 +157,8 @@ $GODOT_HEAD_INCLUDE
}
requestAnimationFrame(animate);
- function adjustCanvasDimensions() {
- const scale = window.devicePixelRatio || 1;
- if (lastWidth != window.innerWidth || lastHeight != window.innerHeight || lastScale != scale) {
- lastScale = scale;
- lastWidth = window.innerWidth;
- lastHeight = window.innerHeight;
- canvas.width = Math.floor(lastWidth * scale);
- canvas.height = Math.floor(lastHeight * scale);
- canvas.style.width = lastWidth + "px";
- canvas.style.height = lastHeight + "px";
- }
- }
- if (FULL_WINDOW) {
- animationCallbacks.push(adjustCanvasDimensions);
- adjustCanvasDimensions();
- } else {
- engine.setCanvasResizedOnStart(true);
- }
+ function setStatusMode(mode) {
- setStatusMode = function setStatusMode(mode) {
if (statusMode === mode || !initializing)
return;
[statusProgress, statusIndeterminate, statusNotice].forEach(elem => {
@@ -213,7 +184,7 @@ $GODOT_HEAD_INCLUDE
throw new Error('Invalid status mode');
}
statusMode = mode;
- };
+ }
function animateStatusIndeterminate(ms) {
var i = Math.floor(ms / INDETERMINATE_STATUS_STEP_MS % 8);
@@ -225,7 +196,7 @@ $GODOT_HEAD_INCLUDE
}
}
- setStatusNotice = function setStatusNotice(text) {
+ function setStatusNotice(text) {
while (statusNotice.lastChild) {
statusNotice.removeChild(statusNotice.lastChild);
}
@@ -236,21 +207,6 @@ $GODOT_HEAD_INCLUDE
});
};
- engine.setProgressFunc((current, total) => {
- if (total > 0) {
- statusProgressInner.style.width = current/total * 100 + '%';
- setStatusMode('progress');
- if (current === total) {
- // wait for progress bar animation
- setTimeout(() => {
- setStatusMode('indeterminate');
- }, 500);
- }
- } else {
- setStatusMode('indeterminate');
- }
- });
-
function displayFailureNotice(err) {
var msg = err.message || err;
console.error(msg);
@@ -263,9 +219,22 @@ $GODOT_HEAD_INCLUDE
displayFailureNotice('WebGL not available');
} else {
setStatusMode('indeterminate');
- engine.setCanvas(canvas);
- engine.setGDNativeLibraries(GDNATIVE_LIBS);
- engine.startGame(EXECUTABLE_NAME, MAIN_PACK, EXTRA_ARGS).then(() => {
+ engine.startGame({
+ 'onProgress': function (current, total) {
+ if (total > 0) {
+ statusProgressInner.style.width = current/total * 100 + '%';
+ setStatusMode('progress');
+ if (current === total) {
+ // wait for progress bar animation
+ setTimeout(() => {
+ setStatusMode('indeterminate');
+ }, 500);
+ }
+ } else {
+ setStatusMode('indeterminate');
+ }
+ },
+ }).then(() => {
setStatusMode('hidden');
initializing = false;
}, displayFailureNotice);
diff --git a/misc/dist/html/manifest.json b/misc/dist/html/manifest.json
new file mode 100644
index 0000000000..6e0053c23c
--- /dev/null
+++ b/misc/dist/html/manifest.json
@@ -0,0 +1,18 @@
+{
+ "name": "Godot Engine",
+ "short_name": "Godot",
+ "description": "Multi-platform 2D and 3D game engine with a feature-rich editor",
+ "lang": "en",
+ "start_url": "/godot.tools.html",
+ "display": "standalone",
+ "orientation": "landscape",
+ "theme_color": "#478cbf",
+ "icons": [
+ {
+ "src": "favicon.png",
+ "sizes": "256x256",
+ "type": "image/png"
+ }
+ ],
+ "background_color": "#333b4f"
+}
diff --git a/misc/dist/html/offline.html b/misc/dist/html/offline.html
new file mode 100644
index 0000000000..000c21b4d3
--- /dev/null
+++ b/misc/dist/html/offline.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <title>You are offline</title>
+ <style>
+ html {
+ background-color: #333b4f;
+ color: #e0e0e0;
+ }
+
+ body {
+ font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ margin: 2rem;
+ }
+
+ p {
+ margin-block: 1rem;
+ }
+
+ button {
+ display: block;
+ padding: 1rem 2rem;
+ margin: 3rem auto 0;
+ }
+ </style>
+</head>
+<body>
+ <h1>You are offline</h1>
+ <p>This application requires an Internet connection to run for the first time.</p>
+ <p>Press the button below to try reloading:</p>
+ <button type="button">Reload</button>
+
+ <script>
+ document.querySelector("button").addEventListener("click", () => {
+ window.location.reload();
+ });
+ </script>
+</body>
+</html>
diff --git a/misc/dist/html/service-worker.js b/misc/dist/html/service-worker.js
new file mode 100644
index 0000000000..d4eaed2b17
--- /dev/null
+++ b/misc/dist/html/service-worker.js
@@ -0,0 +1,84 @@
+// This service worker is required to expose an exported Godot project as a
+// Progressive Web App. It provides an offline fallback page telling the user
+// that they need an Internet conneciton to run the project if desired.
+// Incrementing CACHE_VERSION will kick off the install event and force
+// previously cached resources to be updated from the network.
+const CACHE_VERSION = "@GODOT_VERSION@";
+const CACHE_NAME = "@GODOT_NAME@-cache";
+const OFFLINE_URL = "offline.html";
+// Files that will be cached on load.
+const CACHED_FILES = [
+ "godot.tools.html",
+ "offline.html",
+ "godot.tools.js",
+ "godot.tools.worker.js",
+ "godot.tools.audio.worklet.js",
+ "logo.svg",
+ "favicon.png",
+];
+
+// Files that we might not want the user to preload, and will only be cached on first load.
+const CACHABLE_FILES = [
+ "godot.tools.wasm",
+];
+const FULL_CACHE = CACHED_FILES.concat(CACHABLE_FILES);
+
+self.addEventListener("install", (event) => {
+ event.waitUntil(async function () {
+ const cache = await caches.open(CACHE_NAME);
+ // Clear old cache (including optionals).
+ await Promise.all(FULL_CACHE.map(path => cache.delete(path)));
+ // Insert new one.
+ const done = await cache.addAll(CACHED_FILES);
+ return done;
+ }());
+});
+
+self.addEventListener("activate", (event) => {
+ event.waitUntil(async function () {
+ if ("navigationPreload" in self.registration) {
+ await self.registration.navigationPreload.enable();
+ }
+ }());
+ // Tell the active service worker to take control of the page immediately.
+ self.clients.claim();
+});
+
+self.addEventListener("fetch", (event) => {
+ const isNavigate = event.request.mode === "navigate";
+ const url = event.request.url || "";
+ const referrer = event.request.referrer || "";
+ const base = referrer.slice(0, referrer.lastIndexOf("/") + 1);
+ const local = url.startsWith(base) ? url.replace(base, "") : "";
+ const isCachable = FULL_CACHE.some(v => v === local) || (base === referrer && base.endsWith(CACHED_FILES[0]));
+ if (isNavigate || isCachable) {
+ event.respondWith(async function () {
+ try {
+ // Use the preloaded response, if it's there
+ let request = event.request.clone();
+ let response = await event.preloadResponse;
+ if (!response) {
+ // Or, go over network.
+ response = await fetch(event.request);
+ }
+ if (isCachable) {
+ // Update the cache
+ const cache = await caches.open(CACHE_NAME);
+ cache.put(request, response.clone());
+ }
+ return response;
+ } catch (error) {
+ const cache = await caches.open(CACHE_NAME);
+ if (event.request.mode === "navigate") {
+ // Check if we have full cache.
+ const cached = await Promise.all(FULL_CACHE.map(name => cache.match(name)));
+ const missing = cached.some(v => v === undefined);
+ const cachedResponse = missing ? await caches.match(OFFLINE_URL) : await caches.match(CACHED_FILES[0]);
+ return cachedResponse;
+ }
+ const cachedResponse = await caches.match(event.request);
+ return cachedResponse;
+ }
+ }());
+ }
+});
diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
index bd21883259..b9ad431e6e 100644
--- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
+++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
@@ -8,11 +8,11 @@
/* Begin PBXBuildFile section */
1F1575721F582BE20003B888 /* dylibs in Resources */ = {isa = PBXBuildFile; fileRef = 1F1575711F582BE20003B888 /* dylibs */; };
- DEADBEEF2F582BE20003B888 /* $binary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.a */; };
+ DEADBEEF2F582BE20003B888 /* $binary.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.xcframework */; };
$modules_buildfile
1FF8DBB11FBA9DE1009DE660 /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */; };
D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; };
- 9039D3BE24C093AC0020482C /* MoltenVK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9039D3BD24C093AC0020482C /* MoltenVK.a */; };
+ 9039D3BE24C093AC0020482C /* MoltenVK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9039D3BD24C093AC0020482C /* MoltenVK.xcframework */; };
9073252C24BF980B0063BCD4 /* vulkan in Resources */ = {isa = PBXBuildFile; fileRef = 905036DC24BF932E00301046 /* vulkan */; };
D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */; };
D0BCFE7818AEBFEB004A7AAE /* $binary.pck in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7718AEBFEB004A7AAE /* $binary.pck */; };
@@ -35,11 +35,11 @@
/* Begin PBXFileReference section */
1F1575711F582BE20003B888 /* dylibs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dylibs; path = "$binary/dylibs"; sourceTree = "<group>"; };
- DEADBEEF1F582BE20003B888 /* $binary.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot; path = "$binary.a"; sourceTree = "<group>"; };
+ DEADBEEF1F582BE20003B888 /* $binary.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = godot; path = "$binary.xcframework"; sourceTree = "<group>"; };
$modules_fileref
1FF4C1881F584E6300A41E41 /* $binary.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "$binary.entitlements"; sourceTree = "<group>"; };
1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dummy.cpp; sourceTree = "<group>"; };
- 9039D3BD24C093AC0020482C /* MoltenVK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = MoltenVK; path = MoltenVK.a; sourceTree = "<group>"; };
+ 9039D3BD24C093AC0020482C /* MoltenVK.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MoltenVK; path = MoltenVK.xcframework; sourceTree = "<group>"; };
905036DC24BF932E00301046 /* vulkan */ = {isa = PBXFileReference; lastKnownFileType = folder; name = vulkan; path = "$binary/vulkan"; sourceTree = "<group>"; };
D07CD44D1C5D589C00B7FB28 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
D0BCFE3418AEBDA2004A7AAE /* $binary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "$binary.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -56,8 +56,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 9039D3BE24C093AC0020482C /* MoltenVK.a in Frameworks */,
- DEADBEEF2F582BE20003B888 /* $binary.a */,
+ 9039D3BE24C093AC0020482C /* MoltenVK.xcframework in Frameworks */,
+ DEADBEEF2F582BE20003B888 /* $binary.xcframework */,
$modules_buildphase
$additional_pbx_frameworks_build
);
@@ -90,8 +90,8 @@
D0BCFE3618AEBDA2004A7AAE /* Frameworks */ = {
isa = PBXGroup;
children = (
- 9039D3BD24C093AC0020482C /* MoltenVK.a */,
- DEADBEEF1F582BE20003B888 /* $binary.a */,
+ 9039D3BD24C093AC0020482C /* MoltenVK.xcframework */,
+ DEADBEEF1F582BE20003B888 /* $binary.xcframework */,
$modules_buildgrp
$additional_pbx_frameworks_refs
);
diff --git a/misc/dist/ios_xcode/godot_ios/dummy.cpp b/misc/dist/ios_xcode/godot_ios/dummy.cpp
index 0fcbf227b5..acbf7f03d1 100644
--- a/misc/dist/ios_xcode/godot_ios/dummy.cpp
+++ b/misc/dist/ios_xcode/godot_ios/dummy.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.fat.a b/misc/dist/ios_xcode/libgodot.iphone.debug.fat.a
deleted file mode 100644
index e69de29bb2..0000000000
--- a/misc/dist/ios_xcode/libgodot.iphone.debug.fat.a
+++ /dev/null
diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist
new file mode 100644
index 0000000000..846533594f
--- /dev/null
+++ b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>AvailableLibraries</key>
+ <array>
+ <dict>
+ <key>LibraryIdentifier</key>
+ <string>ios-arm64</string>
+ <key>LibraryPath</key>
+ <string>libgodot.a</string>
+ <key>SupportedArchitectures</key>
+ <array>
+ <string>arm64</string>
+ </array>
+ <key>SupportedPlatform</key>
+ <string>ios</string>
+ </dict>
+ <dict>
+ <key>LibraryIdentifier</key>
+ <string>ios-arm64_x86_64-simulator</string>
+ <key>LibraryPath</key>
+ <string>libgodot.a</string>
+ <key>SupportedArchitectures</key>
+ <array>
+ <string>arm64</string>
+ <string>x86_64</string>
+ </array>
+ <key>SupportedPlatform</key>
+ <string>ios</string>
+ <key>SupportedPlatformVariant</key>
+ <string>simulator</string>
+ </dict>
+ </array>
+ <key>CFBundlePackageType</key>
+ <string>XFWK</string>
+ <key>XCFrameworkFormatVersion</key>
+ <string>1.0</string>
+</dict>
+</plist>
diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty
new file mode 100644
index 0000000000..bd3e894333
--- /dev/null
+++ b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty
new file mode 100644
index 0000000000..bd3e894333
--- /dev/null
+++ b/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.fat.a b/misc/dist/ios_xcode/libgodot.iphone.release.fat.a
deleted file mode 100644
index e69de29bb2..0000000000
--- a/misc/dist/ios_xcode/libgodot.iphone.release.fat.a
+++ /dev/null
diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist
new file mode 100644
index 0000000000..846533594f
--- /dev/null
+++ b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>AvailableLibraries</key>
+ <array>
+ <dict>
+ <key>LibraryIdentifier</key>
+ <string>ios-arm64</string>
+ <key>LibraryPath</key>
+ <string>libgodot.a</string>
+ <key>SupportedArchitectures</key>
+ <array>
+ <string>arm64</string>
+ </array>
+ <key>SupportedPlatform</key>
+ <string>ios</string>
+ </dict>
+ <dict>
+ <key>LibraryIdentifier</key>
+ <string>ios-arm64_x86_64-simulator</string>
+ <key>LibraryPath</key>
+ <string>libgodot.a</string>
+ <key>SupportedArchitectures</key>
+ <array>
+ <string>arm64</string>
+ <string>x86_64</string>
+ </array>
+ <key>SupportedPlatform</key>
+ <string>ios</string>
+ <key>SupportedPlatformVariant</key>
+ <string>simulator</string>
+ </dict>
+ </array>
+ <key>CFBundlePackageType</key>
+ <string>XFWK</string>
+ <key>XCFrameworkFormatVersion</key>
+ <string>1.0</string>
+</dict>
+</plist>
diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty
new file mode 100644
index 0000000000..bd3e894333
--- /dev/null
+++ b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty
new file mode 100644
index 0000000000..bd3e894333
--- /dev/null
+++ b/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/linux/org.godotengine.Godot.appdata.xml b/misc/dist/linux/org.godotengine.Godot.appdata.xml
index 2b30036006..d0fb17433a 100644
--- a/misc/dist/linux/org.godotengine.Godot.appdata.xml
+++ b/misc/dist/linux/org.godotengine.Godot.appdata.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright 2017-2020 Rémi Verschelde <remi@godotengine.org> -->
+<!-- Copyright 2017-2021 Rémi Verschelde <remi@godotengine.org> -->
<component type="desktop">
<id>org.godotengine.Godot</id>
<metadata_license>CC0-1.0</metadata_license>
diff --git a/misc/dist/linux/org.godotengine.Godot.xml b/misc/dist/linux/org.godotengine.Godot.xml
new file mode 100644
index 0000000000..2f647f71a6
--- /dev/null
+++ b/misc/dist/linux/org.godotengine.Godot.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+ <mime-type type="application/x-godot-project">
+ <comment>Godot Engine project</comment>
+ <icon name="x-godot-project" />
+ <glob pattern="*.godot"/>
+ </mime-type>
+
+ <mime-type type="application/x-godot-resource">
+ <comment>Godot Engine resource</comment>
+ <icon name="x-godot-resource" />
+ <glob pattern="*.res"/>
+ <glob pattern="*.tres"/>
+ </mime-type>
+
+ <mime-type type="application/x-godot-scene">
+ <comment>Godot Engine scene</comment>
+ <icon name="x-godot-scene" />
+ <glob pattern="*.scn"/>
+ <glob pattern="*.tscn"/>
+ <glob pattern="*.escn"/>
+ </mime-type>
+
+ <mime-type type="application/x-gdscript">
+ <comment>GDScript script</comment>
+ <icon name="x-gdscript" />
+ <glob pattern="*.gd"/>
+ </mime-type>
+</mime-info>
diff --git a/misc/dist/linux/x-godot-project.xml b/misc/dist/linux/x-godot-project.xml
deleted file mode 100644
index 9f28bab2ae..0000000000
--- a/misc/dist/linux/x-godot-project.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
- <mime-type type="application/x-godot-project">
- <comment>Godot Engine project</comment>
- <icon name="godot" />
- <glob pattern="*.godot" weight="100" />
- </mime-type>
-</mime-info>
diff --git a/misc/dist/osx_template.app/Contents/Info.plist b/misc/dist/osx_template.app/Contents/Info.plist
index aad24935d0..aad24935d0 100755..100644
--- a/misc/dist/osx_template.app/Contents/Info.plist
+++ b/misc/dist/osx_template.app/Contents/Info.plist
diff --git a/misc/dist/osx_tools.app/Contents/Info.plist b/misc/dist/osx_tools.app/Contents/Info.plist
index 508586904c..1c682f339f 100755..100644
--- a/misc/dist/osx_tools.app/Contents/Info.plist
+++ b/misc/dist/osx_tools.app/Contents/Info.plist
@@ -9,7 +9,7 @@
<key>CFBundleName</key>
<string>Godot</string>
<key>CFBundleGetInfoString</key>
- <string>(c) 2007-2020 Juan Linietsky, Ariel Manzur &amp; Godot Engine contributors</string>
+ <string>(c) 2007-2021 Juan Linietsky, Ariel Manzur &amp; Godot Engine contributors</string>
<key>CFBundleIconFile</key>
<string>Godot.icns</string>
<key>CFBundleIdentifier</key>
@@ -31,7 +31,7 @@
<key>NSRequiresAquaSystemAppearance</key>
<false/>
<key>NSHumanReadableCopyright</key>
- <string>© 2007-2020 Juan Linietsky, Ariel Manzur &amp; Godot Engine contributors</string>
+ <string>© 2007-2021 Juan Linietsky, Ariel Manzur &amp; Godot Engine contributors</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
diff --git a/misc/dist/project_icon.svg b/misc/dist/project_icon.svg
index cece381340..39a8cd6332 100644
--- a/misc/dist/project_icon.svg
+++ b/misc/dist/project_icon.svg
@@ -1 +1 @@
-<svg height="1024" width="1024" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -98.519719)"><rect fill="#1e1a21" height="1008" rx="176.28572" stroke="#2e2832" stroke-width="16" width="1008" x="8" y="106.51972"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164712 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426581-6.973693 9.2079704-13.9828879 13.621-19.449z" fill="#478cbf" transform="matrix(4.2343801 0 0 -4.2343764 97.676491 522.86238)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.2343801 0 0 -4.2343764 788.7623 819.22103)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.2343801 0 0 -4.2343764 387.09785 624.34645)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.2343801 0 0 -4.2343764 364.87318 629.82505)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.2343801 0 0 -4.2343764 511.99324 725.12292)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.2343801 0 0 -4.2343764 636.90407 624.34645)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.2343801 0 0 -4.2343764 659.13434 629.82505)"/></g></svg>
+<svg height="1024" width="1024" xmlns="http://www.w3.org/2000/svg"><rect fill="#1e1a21" height="1008" rx="176.28572" stroke="#2e2832" stroke-width="16" width="1008" x="8" y="8.000001"/><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(4.23438024 0 0 -4.23438024 926.261959 674.345124)"/><path d="m0 0v-47.514-6.035-5.492c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325c5.09692 6.4164715 9.92323 13.494208 13.621 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.4426579-6.973692 9.2079702-13.9828876 13.621-19.449z" fill="#478cbf" transform="matrix(4.23438024 0 0 -4.23438024 97.676501 424.342903)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.066.067c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.23438024 0 0 -4.23438024 788.762303 720.701811)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.23438024 0 0 -4.23438024 387.097823 525.827045)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.23438024 0 0 -4.23438024 364.873153 531.305653)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.23438024 0 0 -4.23438024 511.993216 626.603625)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.23438024 0 0 -4.23438024 636.904052 525.827045)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.23438024 0 0 -4.23438024 659.134337 531.305653)"/></svg>
diff --git a/misc/dist/shell/_godot.zsh-completion b/misc/dist/shell/_godot.zsh-completion
index 1a699e50cb..8e14240b53 100644
--- a/misc/dist/shell/_godot.zsh-completion
+++ b/misc/dist/shell/_godot.zsh-completion
@@ -4,8 +4,8 @@
# To use it, install this file as `_godot` in a directory specified in your
# `fpath` environment variable then restart your shell.
#
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/misc/dist/shell/godot.bash-completion b/misc/dist/shell/godot.bash-completion
index 99d6dc52e0..14f2be37b1 100644
--- a/misc/dist/shell/godot.bash-completion
+++ b/misc/dist/shell/godot.bash-completion
@@ -4,8 +4,8 @@
# To use it, install this file in `/etc/bash_completion.d` then restart your shell.
# You can also `source` this file directly in your shell startup file.
#
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/misc/dist/shell/godot.fish b/misc/dist/shell/godot.fish
index 3cffcfa3b8..a485a1dcdb 100644
--- a/misc/dist/shell/godot.fish
+++ b/misc/dist/shell/godot.fish
@@ -2,8 +2,8 @@
# To use it, install this file in `~/.config/fish/completions` then restart your shell.
# You can also `source` this file directly in your shell startup file.
#
-# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
+# Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
+# Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format
index 4e1fbdeb20..1cbc576565 100755
--- a/misc/hooks/pre-commit-clang-format
+++ b/misc/hooks/pre-commit-clang-format
@@ -74,25 +74,39 @@ else
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
+# To get consistent formatting, we recommend contributors to use the same
+# clang-format version as CI.
+RECOMMENDED_CLANG_FORMAT_MAJOR="11"
+
if [ ! -x "$CLANG_FORMAT" ] ; then
+ message="Error: clang-format executable not found. Please install clang-format $RECOMMENDED_CLANG_FORMAT_MAJOR.x.x."
+
if [ ! -t 1 ] ; then
if [ -x "$ZENITY" ] ; then
- $ZENITY --error --title="Error" --text="Error: clang-format executable not found."
+ $ZENITY --error --title="Error" --text="$message"
exit 1
elif [ -x "$XMSG" ] ; then
- $XMSG -center -title "Error" "Error: clang-format executable not found."
+ $XMSG -center -title "Error" "$message"
exit 1
elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
- $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "Error: clang-format executable not found."
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "$message"
exit 1
fi
fi
- printf "Error: clang-format executable not found.\n"
+ printf "$message\n"
printf "Set the correct path in $(canonicalize_filename "$0").\n"
exit 1
fi
+CLANG_FORMAT_VERSION="$(clang-format --version | cut -d' ' -f3)"
+CLANG_FORMAT_MAJOR="$(echo "$CLANG_FORMAT_VERSION" | cut -d'.' -f1)"
+
+if [ "$CLANG_FORMAT_MAJOR" != "$RECOMMENDED_CLANG_FORMAT_MAJOR" ]; then
+ echo "Warning: Your clang-format binary is the wrong version ($CLANG_FORMAT_VERSION, expected $CLANG_FORMAT_MAJOR.x.x)."
+ echo " Consider upgrading or downgrading clang-format as formatting may not be applied correctly."
+fi
+
# create a random filename to store our generated patch
prefix="pre-commit-clang-format"
suffix="$(date +%s)"
@@ -111,6 +125,9 @@ do
if grep -q "platform/android/java/lib/src/com" <<< $file; then
continue;
fi
+ if grep -q "\-so_wrap." <<< $file; then
+ continue;
+ fi
# ignore file if we do check for file extensions and the file
# does not match any of the extensions specified in $FILE_EXTS
diff --git a/misc/hooks/winmessage.ps1 b/misc/hooks/winmessage.ps1
index 3672579544..3672579544 100755..100644
--- a/misc/hooks/winmessage.ps1
+++ b/misc/hooks/winmessage.ps1
diff --git a/misc/scripts/clang_format.sh b/misc/scripts/clang_format.sh
index e686305dea..63c66d41c3 100755
--- a/misc/scripts/clang_format.sh
+++ b/misc/scripts/clang_format.sh
@@ -16,6 +16,8 @@ while IFS= read -rd '' f; do
continue
elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then
continue
+ elif [[ "$f" == *"-so_wrap."* ]]; then
+ continue
fi
for extension in ${CLANG_FORMAT_FILE_EXTS[@]}; do
diff --git a/misc/scripts/copyright_headers.py b/misc/scripts/copyright_headers.py
index bf1e0d3f9c..2f3e4a1b6a 100755
--- a/misc/scripts/copyright_headers.py
+++ b/misc/scripts/copyright_headers.py
@@ -11,8 +11,8 @@ header = """\
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/misc/scripts/file_format.sh b/misc/scripts/file_format.sh
index 0e9db68a90..795431cd28 100755
--- a/misc/scripts/file_format.sh
+++ b/misc/scripts/file_format.sh
@@ -30,6 +30,8 @@ while IFS= read -rd '' f; do
continue
elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then
continue
+ elif [[ "$f" == *"-so_wrap."* ]]; then
+ continue
fi
# Ensure that files are UTF-8 formatted.
recode UTF-8 "$f" 2> /dev/null
@@ -38,15 +40,6 @@ while IFS= read -rd '' f; do
# Remove trailing space characters and ensures that files end
# with newline characters. -l option handles newlines conveniently.
perl -i -ple 's/\s*$//g' "$f"
- # Remove the character sequence "== true" if it has a leading space.
- perl -i -pe 's/\x20== true//g' "$f"
-
- if [[ $(uname) == "Linux" ]] && [[ "$f" != *"xml" ]]; then
- # Remove empty lines after the opening brace of indented blocks.
- sed -z -i 's/\x7B\x0A\x0A\x09/\x7B\x0A\x09/g' "$f"
- # Remove empty lines before the closing brace (in some cases).
- sed -z -i 's/\x0A\x0A\x7D/\x0A\x7D/g' "$f"
- fi
done
git diff > patch.patch
diff --git a/modules/SCsub b/modules/SCsub
index 24598f4b28..64da3bd0be 100644
--- a/modules/SCsub
+++ b/modules/SCsub
@@ -45,18 +45,6 @@ for name, path in env.module_list.items():
else:
SConscript(path + "/SCsub") # Custom.
- # Some modules are not linked automatically but can be enabled optionally
- # on iOS, so we handle those specially.
- if env["platform"] == "iphone" and name in [
- "arkit",
- "camera",
- "camera_iphone",
- "gamecenter",
- "inappstore",
- "icloud",
- ]:
- continue
-
lib = env_modules.add_library("module_%s" % name, env.modules_sources)
env.Prepend(LIBS=[lib])
if env["vsproj"]:
diff --git a/modules/arkit/SCsub b/modules/arkit/SCsub
deleted file mode 100644
index 7e103d6565..0000000000
--- a/modules/arkit/SCsub
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-Import("env_modules")
-
-env_arkit = env_modules.Clone()
-
-# (iOS) Enable module support
-env_arkit.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
-
-# (iOS) Build as separate static library
-modules_sources = []
-env_arkit.add_source_files(modules_sources, "*.cpp")
-env_arkit.add_source_files(modules_sources, "*.mm")
-mod_lib = env_modules.add_library("#bin/libgodot_arkit_module" + env["LIBSUFFIX"], modules_sources)
diff --git a/modules/arkit/arkit.gdip b/modules/arkit/arkit.gdip
deleted file mode 100644
index 22c0a07e26..0000000000
--- a/modules/arkit/arkit.gdip
+++ /dev/null
@@ -1,18 +0,0 @@
-[config]
-name="ARKit"
-binary="arkit_lib.a"
-
-initialization="register_arkit_types"
-deinitialization="unregister_arkit_types"
-
-[dependencies]
-linked=[]
-embedded=[]
-system=["AVFoundation.framework", "ARKit.framework"]
-
-capabilities=["arkit"]
-
-files=[]
-
-[plist]
-NSCameraUsageDescription="Device camera is used for some functionality"
diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm
deleted file mode 100644
index 1c42e6e008..0000000000
--- a/modules/arkit/arkit_interface.mm
+++ /dev/null
@@ -1,791 +0,0 @@
-/*************************************************************************/
-/* arkit_interface.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "core/input/input.h"
-#include "core/os/os.h"
-#include "scene/resources/surface_tool.h"
-#include "servers/rendering/rendering_server_globals.h"
-
-#import <ARKit/ARKit.h>
-#import <UIKit/UIKit.h>
-
-#include <dlfcn.h>
-
-#include "arkit_interface.h"
-#include "arkit_session_delegate.h"
-
-// just a dirty workaround for now, declare these as globals. I'll probably encapsulate ARSession and associated logic into an mm object and change ARKitInterface to a normal cpp object that consumes it.
-API_AVAILABLE(ios(11.0))
-ARSession *ar_session;
-
-ARKitSessionDelegate *ar_delegate;
-NSTimeInterval last_timestamp;
-
-/* this is called when we initialize or when we come back from having our app pushed to the background, just (re)start our session */
-void ARKitInterface::start_session() {
- // We're active...
- session_was_started = true;
-
- // Ignore this if we're not initialized...
- if (initialized) {
- print_line("Starting ARKit session");
-
- if (@available(iOS 11, *)) {
- Class ARWorldTrackingConfigurationClass = NSClassFromString(@"ARWorldTrackingConfiguration");
- ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfigurationClass new];
-
- configuration.lightEstimationEnabled = light_estimation_is_enabled;
- if (plane_detection_is_enabled) {
- if (@available(iOS 11.3, *)) {
- configuration.planeDetection = ARPlaneDetectionVertical | ARPlaneDetectionHorizontal;
- } else {
- configuration.planeDetection = ARPlaneDetectionHorizontal;
- }
- } else {
- configuration.planeDetection = 0;
- }
-
- // make sure our camera is on
- if (feed.is_valid()) {
- feed->set_active(true);
- }
-
- [ar_session runWithConfiguration:configuration];
- }
- }
-}
-
-void ARKitInterface::stop_session() {
- session_was_started = false;
-
- // Ignore this if we're not initialized...
- if (initialized) {
- // make sure our camera is off
- if (feed.is_valid()) {
- feed->set_active(false);
- }
-
- if (@available(iOS 11.0, *)) {
- [ar_session pause];
- }
- }
-}
-
-void ARKitInterface::notification(int p_what) {
- // TODO, this is not being called, need to find out why, possibly because this is not a node.
- // in that case we need to find a way to get these notifications!
- switch (p_what) {
- case DisplayServer::WINDOW_EVENT_FOCUS_IN: {
- print_line("Focus in");
-
- start_session();
- }; break;
- case DisplayServer::WINDOW_EVENT_FOCUS_OUT: {
- print_line("Focus out");
-
- stop_session();
- }; break;
- default:
- break;
- }
-}
-
-bool ARKitInterface::get_anchor_detection_is_enabled() const {
- return plane_detection_is_enabled;
-}
-
-void ARKitInterface::set_anchor_detection_is_enabled(bool p_enable) {
- if (plane_detection_is_enabled != p_enable) {
- plane_detection_is_enabled = p_enable;
-
- // Restart our session (this will be ignore if we're not initialised)
- if (session_was_started) {
- start_session();
- }
- }
-}
-
-int ARKitInterface::get_camera_feed_id() {
- if (feed.is_null()) {
- return 0;
- } else {
- return feed->get_id();
- }
-}
-
-bool ARKitInterface::get_light_estimation_is_enabled() const {
- return light_estimation_is_enabled;
-}
-
-void ARKitInterface::set_light_estimation_is_enabled(bool p_enable) {
- if (light_estimation_is_enabled != p_enable) {
- light_estimation_is_enabled = p_enable;
-
- // Restart our session (this will be ignore if we're not initialised)
- if (session_was_started) {
- start_session();
- }
- }
-}
-
-real_t ARKitInterface::get_ambient_intensity() const {
- return ambient_intensity;
-}
-
-real_t ARKitInterface::get_ambient_color_temperature() const {
- return ambient_color_temperature;
-}
-
-StringName ARKitInterface::get_name() const {
- return "ARKit";
-}
-
-int ARKitInterface::get_capabilities() const {
- return ARKitInterface::XR_MONO + ARKitInterface::XR_AR;
-}
-
-Array ARKitInterface::raycast(Vector2 p_screen_coord) {
- if (@available(iOS 11, *)) {
- Array arr;
- Size2 screen_size = DisplayServer::get_singleton()->screen_get_size();
- CGPoint point;
- point.x = p_screen_coord.x / screen_size.x;
- point.y = p_screen_coord.y / screen_size.y;
-
- ///@TODO maybe give more options here, for now we're taking just ARAchors into account that were found during plane detection keeping their size into account
-
- NSArray<ARHitTestResult *> *results = [ar_session.currentFrame hitTest:point types:ARHitTestResultTypeExistingPlaneUsingExtent];
-
- for (ARHitTestResult *result in results) {
- Transform transform;
-
- matrix_float4x4 m44 = result.worldTransform;
- transform.basis.elements[0].x = m44.columns[0][0];
- transform.basis.elements[1].x = m44.columns[0][1];
- transform.basis.elements[2].x = m44.columns[0][2];
- transform.basis.elements[0].y = m44.columns[1][0];
- transform.basis.elements[1].y = m44.columns[1][1];
- transform.basis.elements[2].y = m44.columns[1][2];
- transform.basis.elements[0].z = m44.columns[2][0];
- transform.basis.elements[1].z = m44.columns[2][1];
- transform.basis.elements[2].z = m44.columns[2][2];
- transform.origin.x = m44.columns[3][0];
- transform.origin.y = m44.columns[3][1];
- transform.origin.z = m44.columns[3][2];
-
- /* important, NOT scaled to world_scale !! */
- arr.push_back(transform);
- }
-
- return arr;
- } else {
- return Array();
- }
-}
-
-void ARKitInterface::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_notification", "what"), &ARKitInterface::_notification);
-
- ClassDB::bind_method(D_METHOD("set_light_estimation_is_enabled", "enable"), &ARKitInterface::set_light_estimation_is_enabled);
- ClassDB::bind_method(D_METHOD("get_light_estimation_is_enabled"), &ARKitInterface::get_light_estimation_is_enabled);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_estimation"), "set_light_estimation_is_enabled", "get_light_estimation_is_enabled");
-
- ClassDB::bind_method(D_METHOD("get_ambient_intensity"), &ARKitInterface::get_ambient_intensity);
- ClassDB::bind_method(D_METHOD("get_ambient_color_temperature"), &ARKitInterface::get_ambient_color_temperature);
-
- ClassDB::bind_method(D_METHOD("raycast", "screen_coord"), &ARKitInterface::raycast);
-}
-
-bool ARKitInterface::is_stereo() {
- // this is a mono device...
- return false;
-}
-
-bool ARKitInterface::is_initialized() const {
- return initialized;
-}
-
-bool ARKitInterface::initialize() {
- XRServer *xr_server = XRServer::get_singleton();
- ERR_FAIL_NULL_V(xr_server, false);
-
- if (@available(iOS 11, *)) {
- if (!initialized) {
- print_line("initializing ARKit");
-
- // create our ar session and delegate
- Class ARSessionClass = NSClassFromString(@"ARSession");
- if (ARSessionClass == Nil) {
- void *arkit_handle = dlopen("/System/Library/Frameworks/ARKit.framework/ARKit", RTLD_NOW);
- if (arkit_handle) {
- ARSessionClass = NSClassFromString(@"ARSession");
- } else {
- print_line("ARKit init failed");
- return false;
- }
- }
- ar_session = [ARSessionClass new];
- ar_delegate = [ARKitSessionDelegate new];
- ar_delegate.arkit_interface = this;
- ar_session.delegate = ar_delegate;
-
- // reset our transform
- transform = Transform();
-
- // make this our primary interface
- xr_server->set_primary_interface(this);
-
- // make sure we have our feed setup
- if (feed.is_null()) {
- feed.instance();
- feed->set_name("ARKit");
-
- CameraServer *cs = CameraServer::get_singleton();
- if (cs != NULL) {
- cs->add_feed(feed);
- }
- }
- feed->set_active(true);
-
- // yeah!
- initialized = true;
-
- // Start our session...
- start_session();
- }
-
- return true;
- } else {
- return false;
- }
-}
-
-void ARKitInterface::uninitialize() {
- if (initialized) {
- XRServer *xr_server = XRServer::get_singleton();
- if (xr_server != NULL) {
- // no longer our primary interface
- xr_server->clear_primary_interface_if(this);
- }
-
- if (feed.is_valid()) {
- CameraServer *cs = CameraServer::get_singleton();
- if ((cs != NULL)) {
- cs->remove_feed(feed);
- }
- feed.unref();
- }
-
- remove_all_anchors();
-
- if (@available(iOS 11.0, *)) {
- ar_session = nil;
- }
-
- ar_delegate = nil;
- initialized = false;
- session_was_started = false;
- }
-}
-
-Size2 ARKitInterface::get_render_targetsize() {
- // _THREAD_SAFE_METHOD_
-
- Size2 target_size = DisplayServer::get_singleton()->screen_get_size();
-
- return target_size;
-}
-
-Transform ARKitInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) {
- // _THREAD_SAFE_METHOD_
-
- Transform transform_for_eye;
-
- XRServer *xr_server = XRServer::get_singleton();
- ERR_FAIL_NULL_V(xr_server, transform_for_eye);
-
- if (initialized) {
- float world_scale = xr_server->get_world_scale();
-
- // just scale our origin point of our transform, note that we really shouldn't be using world_scale in ARKit but....
- transform_for_eye = transform;
- transform_for_eye.origin *= world_scale;
-
- transform_for_eye = p_cam_transform * xr_server->get_reference_frame() * transform_for_eye;
- } else {
- // huh? well just return what we got....
- transform_for_eye = p_cam_transform;
- }
-
- return transform_for_eye;
-}
-
-CameraMatrix ARKitInterface::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
- // Remember our near and far, it will be used in process when we obtain our projection from our ARKit session.
- z_near = p_z_near;
- z_far = p_z_far;
-
- return projection;
-}
-
-void ARKitInterface::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
- // _THREAD_SAFE_METHOD_
-
- // We must have a valid render target
- ERR_FAIL_COND(!p_render_target.is_valid());
-
- // Because we are rendering to our device we must use our main viewport!
- ERR_FAIL_COND(p_screen_rect == Rect2());
-
- // get the size of our screen
- // Rect2 screen_rect = p_screen_rect;
-
- // screen_rect.position.x += screen_rect.size.x;
- // screen_rect.size.x = -screen_rect.size.x;
- // screen_rect.position.y += screen_rect.size.y;
- // screen_rect.size.y = -screen_rect.size.y;
-
- // VSG::rasterizer->set_current_render_target(RID());
- // VSG::rasterizer->blit_render_target_to_screen(p_render_target, screen_rect, 0);
-}
-
-XRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *p_uuid) {
- if (anchors == NULL) {
- num_anchors = 0;
- max_anchors = 10;
- anchors = (anchor_map *)malloc(sizeof(anchor_map) * max_anchors);
- }
-
- ERR_FAIL_NULL_V(anchors, NULL);
-
- for (unsigned int i = 0; i < num_anchors; i++) {
- if (memcmp(anchors[i].uuid, p_uuid, 16) == 0) {
- return anchors[i].tracker;
- }
- }
-
- if (num_anchors + 1 == max_anchors) {
- max_anchors += 10;
- anchors = (anchor_map *)realloc(anchors, sizeof(anchor_map) * max_anchors);
- ERR_FAIL_NULL_V(anchors, NULL);
- }
-
- XRPositionalTracker *new_tracker = memnew(XRPositionalTracker);
- new_tracker->set_tracker_type(XRServer::TRACKER_ANCHOR);
-
- char tracker_name[256];
- sprintf(tracker_name, "Anchor %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p_uuid[0], p_uuid[1], p_uuid[2], p_uuid[3], p_uuid[4], p_uuid[5], p_uuid[6], p_uuid[7], p_uuid[8], p_uuid[9], p_uuid[10], p_uuid[11], p_uuid[12], p_uuid[13], p_uuid[14], p_uuid[15]);
-
- String name = tracker_name;
- print_line("Adding tracker " + name);
- new_tracker->set_tracker_name(name);
-
- // add our tracker
- XRServer::get_singleton()->add_tracker(new_tracker);
- anchors[num_anchors].tracker = new_tracker;
- memcpy(anchors[num_anchors].uuid, p_uuid, 16);
- num_anchors++;
-
- return new_tracker;
-}
-
-void ARKitInterface::remove_anchor_for_uuid(const unsigned char *p_uuid) {
- if (anchors != NULL) {
- for (unsigned int i = 0; i < num_anchors; i++) {
- if (memcmp(anchors[i].uuid, p_uuid, 16) == 0) {
- // remove our tracker
- XRServer::get_singleton()->remove_tracker(anchors[i].tracker);
- memdelete(anchors[i].tracker);
-
- // bring remaining forward
- for (unsigned int j = i + 1; j < num_anchors; j++) {
- anchors[j - 1] = anchors[j];
- };
-
- // decrease count
- num_anchors--;
- return;
- }
- }
- }
-}
-
-void ARKitInterface::remove_all_anchors() {
- if (anchors != NULL) {
- for (unsigned int i = 0; i < num_anchors; i++) {
- // remove our tracker
- XRServer::get_singleton()->remove_tracker(anchors[i].tracker);
- memdelete(anchors[i].tracker);
- };
-
- free(anchors);
- anchors = NULL;
- num_anchors = 0;
- }
-}
-
-void ARKitInterface::process() {
- // _THREAD_SAFE_METHOD_
-
- if (@available(iOS 11.0, *)) {
- if (initialized) {
- // get our next ARFrame
- ARFrame *current_frame = ar_session.currentFrame;
- if (last_timestamp != current_frame.timestamp) {
- // only process if we have a new frame
- last_timestamp = current_frame.timestamp;
-
- // get some info about our screen and orientation
- Size2 screen_size = DisplayServer::get_singleton()->screen_get_size();
- UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown;
-
- if (@available(iOS 13, *)) {
- orientation = [UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation;
-#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR
- } else {
- orientation = [[UIApplication sharedApplication] statusBarOrientation];
-#endif
- }
-
- // Grab our camera image for our backbuffer
- CVPixelBufferRef pixelBuffer = current_frame.capturedImage;
- if ((CVPixelBufferGetPlaneCount(pixelBuffer) == 2) && (feed != NULL)) {
- // Plane 0 is our Y and Plane 1 is our CbCr buffer
-
- // ignored, we check each plane separately
- // image_width = CVPixelBufferGetWidth(pixelBuffer);
- // image_height = CVPixelBufferGetHeight(pixelBuffer);
-
- // printf("Pixel buffer %i - %i\n", image_width, image_height);
-
- CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
-
- // get our buffers
- unsigned char *dataY = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
- unsigned char *dataCbCr = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
-
- if (dataY == NULL) {
- print_line("Couldn't access Y pixel buffer data");
- } else if (dataCbCr == NULL) {
- print_line("Couldn't access CbCr pixel buffer data");
- } else {
- Ref<Image> img[2];
- size_t extraLeft, extraRight, extraTop, extraBottom;
-
- CVPixelBufferGetExtendedPixels(pixelBuffer, &extraLeft, &extraRight, &extraTop, &extraBottom);
-
- {
- // do Y
- size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
- size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
- size_t bytes_per_row = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0);
-
- if ((image_width[0] != new_width) || (image_height[0] != new_height)) {
- printf("- Camera padding l:%lu r:%lu t:%lu b:%lu\n", extraLeft, extraRight, extraTop, extraBottom);
- printf("- Camera Y plane size: %lu, %lu - %lu\n", new_width, new_height, bytes_per_row);
-
- image_width[0] = new_width;
- image_height[0] = new_height;
- img_data[0].resize(new_width * new_height);
- }
-
- uint8_t *w = img_data[0].ptrw();
- if (new_width == bytes_per_row) {
- memcpy(w, dataY, new_width * new_height);
- } else {
- size_t offset_a = 0;
- size_t offset_b = extraLeft + (extraTop * bytes_per_row);
- for (size_t r = 0; r < new_height; r++) {
- memcpy(w + offset_a, dataY + offset_b, new_width);
- offset_a += new_width;
- offset_b += bytes_per_row;
- }
- }
-
- img[0].instance();
- img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]);
- }
-
- {
- // do CbCr
- size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1);
- size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
- size_t bytes_per_row = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0);
-
- if ((image_width[1] != new_width) || (image_height[1] != new_height)) {
- printf("- Camera CbCr plane size: %lu, %lu - %lu\n", new_width, new_height, bytes_per_row);
-
- image_width[1] = new_width;
- image_height[1] = new_height;
- img_data[1].resize(2 * new_width * new_height);
- }
-
- uint8_t *w = img_data[1].ptrw();
- if ((2 * new_width) == bytes_per_row) {
- memcpy(w, dataCbCr, 2 * new_width * new_height);
- } else {
- size_t offset_a = 0;
- size_t offset_b = extraLeft + (extraTop * bytes_per_row);
- for (size_t r = 0; r < new_height; r++) {
- memcpy(w + offset_a, dataCbCr + offset_b, 2 * new_width);
- offset_a += 2 * new_width;
- offset_b += bytes_per_row;
- }
- }
-
- img[1].instance();
- img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]);
- }
-
- // set our texture...
- feed->set_YCbCr_imgs(img[0], img[1]);
-
- // now build our transform to display this as a background image that matches our camera
- CGAffineTransform affine_transform = [current_frame displayTransformForOrientation:orientation viewportSize:CGSizeMake(screen_size.width, screen_size.height)];
-
- // we need to invert this, probably row v.s. column notation
- affine_transform = CGAffineTransformInvert(affine_transform);
-
- if (orientation != UIInterfaceOrientationPortrait) {
- affine_transform.b = -affine_transform.b;
- affine_transform.d = -affine_transform.d;
- affine_transform.ty = 1.0 - affine_transform.ty;
- } else {
- affine_transform.c = -affine_transform.c;
- affine_transform.a = -affine_transform.a;
- affine_transform.tx = 1.0 - affine_transform.tx;
- }
-
- Transform2D display_transform = Transform2D(
- affine_transform.a, affine_transform.b,
- affine_transform.c, affine_transform.d,
- affine_transform.tx, affine_transform.ty);
-
- feed->set_transform(display_transform);
- }
-
- // and unlock
- CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
- }
-
- // Record light estimation to apply to our scene
- if (light_estimation_is_enabled) {
- ambient_intensity = current_frame.lightEstimate.ambientIntensity;
-
- ///@TODO it's there, but not there.. what to do with this...
- // https://developer.apple.com/documentation/arkit/arlightestimate?language=objc
- // ambient_color_temperature = current_frame.lightEstimate.ambientColorTemperature;
- }
-
- // Process our camera
- ARCamera *camera = current_frame.camera;
-
- // strangely enough we have to states, rolling them up into one
- if (camera.trackingState == ARTrackingStateNotAvailable) {
- // no tracking, would be good if we black out the screen or something...
- tracking_state = XRInterface::XR_NOT_TRACKING;
- } else {
- if (camera.trackingState == ARTrackingStateNormal) {
- tracking_state = XRInterface::XR_NORMAL_TRACKING;
- } else if (camera.trackingStateReason == ARTrackingStateReasonExcessiveMotion) {
- tracking_state = XRInterface::XR_EXCESSIVE_MOTION;
- } else if (camera.trackingStateReason == ARTrackingStateReasonInsufficientFeatures) {
- tracking_state = XRInterface::XR_INSUFFICIENT_FEATURES;
- } else {
- tracking_state = XRInterface::XR_UNKNOWN_TRACKING;
- }
-
- // copy our current frame transform
- matrix_float4x4 m44 = camera.transform;
- if (orientation == UIInterfaceOrientationLandscapeLeft) {
- transform.basis.elements[0].x = m44.columns[0][0];
- transform.basis.elements[1].x = m44.columns[0][1];
- transform.basis.elements[2].x = m44.columns[0][2];
- transform.basis.elements[0].y = m44.columns[1][0];
- transform.basis.elements[1].y = m44.columns[1][1];
- transform.basis.elements[2].y = m44.columns[1][2];
- } else if (orientation == UIInterfaceOrientationPortrait) {
- transform.basis.elements[0].x = m44.columns[1][0];
- transform.basis.elements[1].x = m44.columns[1][1];
- transform.basis.elements[2].x = m44.columns[1][2];
- transform.basis.elements[0].y = -m44.columns[0][0];
- transform.basis.elements[1].y = -m44.columns[0][1];
- transform.basis.elements[2].y = -m44.columns[0][2];
- } else if (orientation == UIInterfaceOrientationLandscapeRight) {
- transform.basis.elements[0].x = -m44.columns[0][0];
- transform.basis.elements[1].x = -m44.columns[0][1];
- transform.basis.elements[2].x = -m44.columns[0][2];
- transform.basis.elements[0].y = -m44.columns[1][0];
- transform.basis.elements[1].y = -m44.columns[1][1];
- transform.basis.elements[2].y = -m44.columns[1][2];
- } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
- // this may not be correct
- transform.basis.elements[0].x = m44.columns[1][0];
- transform.basis.elements[1].x = m44.columns[1][1];
- transform.basis.elements[2].x = m44.columns[1][2];
- transform.basis.elements[0].y = m44.columns[0][0];
- transform.basis.elements[1].y = m44.columns[0][1];
- transform.basis.elements[2].y = m44.columns[0][2];
- }
- transform.basis.elements[0].z = m44.columns[2][0];
- transform.basis.elements[1].z = m44.columns[2][1];
- transform.basis.elements[2].z = m44.columns[2][2];
- transform.origin.x = m44.columns[3][0];
- transform.origin.y = m44.columns[3][1];
- transform.origin.z = m44.columns[3][2];
-
- // copy our current frame projection, investigate using projectionMatrixWithViewportSize:orientation:zNear:zFar: so we can set our own near and far
- m44 = [camera projectionMatrixForOrientation:orientation viewportSize:CGSizeMake(screen_size.width, screen_size.height) zNear:z_near zFar:z_far];
- projection.matrix[0][0] = m44.columns[0][0];
- projection.matrix[1][0] = m44.columns[1][0];
- projection.matrix[2][0] = m44.columns[2][0];
- projection.matrix[3][0] = m44.columns[3][0];
- projection.matrix[0][1] = m44.columns[0][1];
- projection.matrix[1][1] = m44.columns[1][1];
- projection.matrix[2][1] = m44.columns[2][1];
- projection.matrix[3][1] = m44.columns[3][1];
- projection.matrix[0][2] = m44.columns[0][2];
- projection.matrix[1][2] = m44.columns[1][2];
- projection.matrix[2][2] = m44.columns[2][2];
- projection.matrix[3][2] = m44.columns[3][2];
- projection.matrix[0][3] = m44.columns[0][3];
- projection.matrix[1][3] = m44.columns[1][3];
- projection.matrix[2][3] = m44.columns[2][3];
- projection.matrix[3][3] = m44.columns[3][3];
- }
- }
- }
- }
-}
-
-void ARKitInterface::_add_or_update_anchor(GodotARAnchor *p_anchor) {
- // _THREAD_SAFE_METHOD_
-
- if (@available(iOS 11.0, *)) {
- ARAnchor *anchor = (ARAnchor *)p_anchor;
-
- unsigned char uuid[16];
- [anchor.identifier getUUIDBytes:uuid];
-
- XRPositionalTracker *tracker = get_anchor_for_uuid(uuid);
- if (tracker != NULL) {
- // lets update our mesh! (using Arjens code as is for now)
- // we should also probably limit how often we do this...
-
- // can we safely cast this?
- ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor;
-
- if (@available(iOS 11.3, *)) {
- if (planeAnchor.geometry.triangleCount > 0) {
- Ref<SurfaceTool> surftool;
- surftool.instance();
- surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
-
- for (int j = planeAnchor.geometry.triangleCount * 3 - 1; j >= 0; j--) {
- int16_t index = planeAnchor.geometry.triangleIndices[j];
- simd_float3 vrtx = planeAnchor.geometry.vertices[index];
- simd_float2 textcoord = planeAnchor.geometry.textureCoordinates[index];
- surftool->set_uv(Vector2(textcoord[0], textcoord[1]));
- surftool->set_color(Color(0.8, 0.8, 0.8));
- surftool->add_vertex(Vector3(vrtx[0], vrtx[1], vrtx[2]));
- }
-
- surftool->generate_normals();
- tracker->set_mesh(surftool->commit());
- } else {
- Ref<Mesh> nomesh;
- tracker->set_mesh(nomesh);
- }
- } else {
- Ref<Mesh> nomesh;
- tracker->set_mesh(nomesh);
- }
-
- // Note, this also contains a scale factor which gives us an idea of the size of the anchor
- // We may extract that in our XRAnchor class
- Basis b;
- matrix_float4x4 m44 = anchor.transform;
- b.elements[0].x = m44.columns[0][0];
- b.elements[1].x = m44.columns[0][1];
- b.elements[2].x = m44.columns[0][2];
- b.elements[0].y = m44.columns[1][0];
- b.elements[1].y = m44.columns[1][1];
- b.elements[2].y = m44.columns[1][2];
- b.elements[0].z = m44.columns[2][0];
- b.elements[1].z = m44.columns[2][1];
- b.elements[2].z = m44.columns[2][2];
- tracker->set_orientation(b);
- tracker->set_rw_position(Vector3(m44.columns[3][0], m44.columns[3][1], m44.columns[3][2]));
- }
- }
-}
-
-void ARKitInterface::_remove_anchor(GodotARAnchor *p_anchor) {
- // _THREAD_SAFE_METHOD_
-
- if (@available(iOS 11.0, *)) {
- ARAnchor *anchor = (ARAnchor *)p_anchor;
-
- unsigned char uuid[16];
- [anchor.identifier getUUIDBytes:uuid];
-
- remove_anchor_for_uuid(uuid);
- }
-}
-
-ARKitInterface::ARKitInterface() {
- initialized = false;
- session_was_started = false;
- plane_detection_is_enabled = false;
- light_estimation_is_enabled = false;
- if (@available(iOS 11.0, *)) {
- ar_session = nil;
- }
- z_near = 0.01;
- z_far = 1000.0;
- projection.set_perspective(60.0, 1.0, z_near, z_far, false);
- anchors = NULL;
- num_anchors = 0;
- ambient_intensity = 1.0;
- ambient_color_temperature = 1.0;
- image_width[0] = 0;
- image_width[1] = 0;
- image_height[0] = 0;
- image_height[1] = 0;
-}
-
-ARKitInterface::~ARKitInterface() {
- remove_all_anchors();
-
- // and make sure we cleanup if we haven't already
- if (is_initialized()) {
- uninitialize();
- }
-}
diff --git a/modules/arkit/arkit_module.h b/modules/arkit/arkit_module.h
deleted file mode 100644
index 8aa8175ed5..0000000000
--- a/modules/arkit/arkit_module.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*************************************************************************/
-/* arkit_module.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef ARKIT_REGISTER_TYPES_H
-#define ARKIT_REGISTER_TYPES_H
-
-void register_arkit_types();
-void unregister_arkit_types();
-
-#endif // ARKIT_REGISTER_TYPES_H
diff --git a/modules/arkit/config.py b/modules/arkit/config.py
deleted file mode 100644
index e68603fc93..0000000000
--- a/modules/arkit/config.py
+++ /dev/null
@@ -1,6 +0,0 @@
-def can_build(env, platform):
- return platform == "iphone"
-
-
-def configure(env):
- pass
diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp
index 27b299a65d..cf5581265b 100644
--- a/modules/basis_universal/register_types.cpp
+++ b/modules/basis_universal/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -216,7 +216,7 @@ static Ref<Image> basis_universal_unpacker(const Vector<uint8_t> &p_buffer) {
format = basist::transcoder_texture_format::cTFETC2; // get this from renderer
imgfmt = Image::FORMAT_ETC2_RGBA8;
} else {
- //gles2 most likely, bad for normalmaps, nothing to do about this.
+ //gles2 most likely, bad for normal maps, nothing to do about this.
format = basist::transcoder_texture_format::cTFRGBA32;
imgfmt = Image::FORMAT_RGBA8;
}
diff --git a/modules/basis_universal/register_types.h b/modules/basis_universal/register_types.h
index 5053dc27ce..30b465e344 100644
--- a/modules/basis_universal/register_types.h
+++ b/modules/basis_universal/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/basis_universal/texture_basisu.cpp b/modules/basis_universal/texture_basisu.cpp
index 5831d3de2a..92882a1cc8 100644
--- a/modules/basis_universal/texture_basisu.cpp
+++ b/modules/basis_universal/texture_basisu.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -207,7 +207,6 @@ Vector<uint8_t> TextureBasisU::get_basisu_data() const {
};
TextureBasisU::TextureBasisU() {
- flags = FLAGS_DEFAULT;
texture = RenderingServer::get_singleton()->texture_create();
};
diff --git a/modules/basis_universal/texture_basisu.h b/modules/basis_universal/texture_basisu.h
index 99248f9162..282a0dfc8a 100644
--- a/modules/basis_universal/texture_basisu.h
+++ b/modules/basis_universal/texture_basisu.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,7 @@ class TextureBasisU : public Texture {
RID texture;
Size2 tex_size;
- uint32_t flags;
+ uint32_t flags = FLAGS_DEFAULT;
Vector<uint8_t> data;
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index b08970d110..c7fdf56af4 100644
--- a/modules/bmp/image_loader_bmp.cpp
+++ b/modules/bmp/image_loader_bmp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h
index 3f10a1c598..379e971458 100644
--- a/modules/bmp/image_loader_bmp.h
+++ b/modules/bmp/image_loader_bmp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,24 +55,24 @@ protected:
struct bmp_header_s {
struct bmp_file_header_s {
- uint16_t bmp_signature;
- uint32_t bmp_file_size;
- uint32_t bmp_file_padding;
- uint32_t bmp_file_offset;
+ uint16_t bmp_signature = 0;
+ uint32_t bmp_file_size = 0;
+ uint32_t bmp_file_padding = 0;
+ uint32_t bmp_file_offset = 0;
} bmp_file_header;
struct bmp_info_header_s {
- uint32_t bmp_header_size;
- uint32_t bmp_width;
- uint32_t bmp_height;
- uint16_t bmp_planes;
- uint16_t bmp_bit_count;
- uint32_t bmp_compression;
- uint32_t bmp_size_image;
- uint32_t bmp_pixels_per_meter_x;
- uint32_t bmp_pixels_per_meter_y;
- uint32_t bmp_colors_used;
- uint32_t bmp_important_colors;
+ uint32_t bmp_header_size = 0;
+ uint32_t bmp_width = 0;
+ uint32_t bmp_height = 0;
+ uint16_t bmp_planes = 0;
+ uint16_t bmp_bit_count = 0;
+ uint32_t bmp_compression = 0;
+ uint32_t bmp_size_image = 0;
+ uint32_t bmp_pixels_per_meter_x = 0;
+ uint32_t bmp_pixels_per_meter_y = 0;
+ uint32_t bmp_colors_used = 0;
+ uint32_t bmp_important_colors = 0;
} bmp_info_header;
};
diff --git a/modules/bmp/register_types.cpp b/modules/bmp/register_types.cpp
index 6220e956d6..d36ce9cdaf 100644
--- a/modules/bmp/register_types.cpp
+++ b/modules/bmp/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bmp/register_types.h b/modules/bmp/register_types.h
index e7561dc32d..3ce81eba1b 100644
--- a/modules/bmp/register_types.h
+++ b/modules/bmp/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index f8f7d79a11..c3bd84c329 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index 152fd785c0..7cf666c119 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,18 +80,18 @@ public:
private:
// These are used by function callEvent. Instead to create this each call I create if one time.
Variant call_event_res[5];
- Variant *call_event_res_ptr[5];
+ Variant *call_event_res_ptr[5] = {};
- btGhostObject *btGhost;
+ btGhostObject *btGhost = nullptr;
Vector<OverlappingObjectData> overlappingObjects;
bool monitorable = true;
PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
bool spOv_gravityPoint = false;
- real_t spOv_gravityPointDistanceScale = 0;
- real_t spOv_gravityPointAttenuation = 1;
+ real_t spOv_gravityPointDistanceScale = 0.0;
+ real_t spOv_gravityPointAttenuation = 1.0;
Vector3 spOv_gravityVec = Vector3(0, -1, 0);
- real_t spOv_gravityMag = 10;
+ real_t spOv_gravityMag = 10.0;
real_t spOv_linearDump = 0.1;
real_t spOv_angularDump = 0.1;
int spOv_priority = 0;
diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp
index a754ca6a89..109854c9dd 100644
--- a/modules/bullet/btRayShape.cpp
+++ b/modules/bullet/btRayShape.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,11 +39,9 @@
*/
btRayShape::btRayShape(btScalar length) :
- btConvexInternalShape(),
- m_shapeAxis(0, 0, 1) {
+ btConvexInternalShape() {
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE;
setLength(length);
- slipsOnSlope = false;
}
btRayShape::~btRayShape() {
diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h
index d9ecde81e6..330755aa31 100644
--- a/modules/bullet/btRayShape.h
+++ b/modules/bullet/btRayShape.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,10 +42,10 @@
/// Ray shape around z axis
ATTRIBUTE_ALIGNED16(class)
btRayShape : public btConvexInternalShape {
- btScalar m_length;
- bool slipsOnSlope;
+ btScalar m_length = 0;
+ bool slipsOnSlope = false;
/// The default axis is the z
- btVector3 m_shapeAxis;
+ btVector3 m_shapeAxis = btVector3(0, 0, 1);
btTransform m_cacheSupportPoint;
btScalar m_cacheScaledLength;
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 3b548b7faa..26e9f5a044 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -625,14 +625,14 @@ uint32_t BulletPhysicsServer3D::body_get_user_flags(RID p_body) const {
return 0;
}
-void BulletPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, float p_value) {
+void BulletPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, real_t p_value) {
RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_param(p_param, p_value);
}
-float BulletPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const {
+real_t BulletPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const {
RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -807,11 +807,11 @@ int BulletPhysicsServer3D::body_get_max_contacts_reported(RID p_body) const {
return body->get_max_collisions_detection();
}
-void BulletPhysicsServer3D::body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) {
+void BulletPhysicsServer3D::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) {
// Not supported by bullet and even Godot
}
-float BulletPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_body) const {
+real_t BulletPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_body) const {
// Not supported by bullet and even Godot
return 0.;
}
@@ -862,7 +862,7 @@ bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform &p_from
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes);
}
-int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
+int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) {
RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
ERR_FAIL_COND_V(!body->get_space(), 0);
@@ -1059,16 +1059,16 @@ real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) {
return body->get_linear_stiffness();
}
-void BulletPhysicsServer3D::soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) {
+void BulletPhysicsServer3D::soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) {
SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- body->set_areaAngular_stiffness(p_stiffness);
+ body->set_angular_stiffness(p_stiffness);
}
-real_t BulletPhysicsServer3D::soft_body_get_areaAngular_stiffness(RID p_body) {
+real_t BulletPhysicsServer3D::soft_body_get_angular_stiffness(RID p_body) {
SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
- return body->get_areaAngular_stiffness();
+ return body->get_angular_stiffness();
}
void BulletPhysicsServer3D::soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) {
@@ -1221,7 +1221,7 @@ RID BulletPhysicsServer3D::joint_create_pin(RID p_body_A, const Vector3 &p_local
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) {
+void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
@@ -1229,7 +1229,7 @@ void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_par
pin_joint->set_param(p_param, p_value);
}
-float BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
+real_t BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0);
@@ -1309,7 +1309,7 @@ RID BulletPhysicsServer3D::joint_create_hinge_simple(RID p_body_A, const Vector3
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) {
+void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_HINGE);
@@ -1317,7 +1317,7 @@ void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p
hinge_joint->set_param(p_param, p_value);
}
-float BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {
+real_t BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0);
@@ -1361,7 +1361,7 @@ RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform &p_
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) {
+void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER);
@@ -1369,7 +1369,7 @@ void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam
slider_joint->set_param(p_param, p_value);
}
-float BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {
+real_t BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_SLIDER, 0);
@@ -1395,7 +1395,7 @@ RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) {
+void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST);
@@ -1403,7 +1403,7 @@ void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJoi
coneTwist_joint->set_param(p_param, p_value);
}
-float BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {
+real_t BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0.);
ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0.);
@@ -1431,7 +1431,7 @@ RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transfo
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value) {
+void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_6DOF);
@@ -1439,7 +1439,7 @@ void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::A
generic_6dof_joint->set_param(p_axis, p_param, p_value);
}
-float BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) {
+real_t BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) {
JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0);
@@ -1525,7 +1525,7 @@ void BulletPhysicsServer3D::init() {
BulletPhysicsDirectBodyState3D::initSingleton();
}
-void BulletPhysicsServer3D::step(float p_deltaTime) {
+void BulletPhysicsServer3D::step(real_t p_deltaTime) {
if (!active) {
return;
}
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index 07a32e510c..97b719ae8e 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -207,8 +207,8 @@ public:
/// This is not supported by physics server
virtual uint32_t body_get_user_flags(RID p_body) const override;
- virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) override;
- virtual float body_get_param(RID p_body, BodyParameter p_param) const override;
+ virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) override;
+ virtual real_t body_get_param(RID p_body, BodyParameter p_param) const override;
virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) override;
virtual real_t body_get_kinematic_safe_margin(RID p_body) const override;
@@ -241,8 +241,8 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) override;
virtual int body_get_max_contacts_reported(RID p_body) const override;
- virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) override;
- virtual float body_get_contacts_reported_depth_threshold(RID p_body) const override;
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) override;
+ virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const override;
virtual void body_set_omit_force_integration(RID p_body, bool p_omit) override;
virtual bool body_is_omitting_force_integration(RID p_body) const override;
@@ -256,7 +256,7 @@ public:
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override;
virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override;
- virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) override;
+ virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override;
/* SOFT BODY API */
@@ -298,8 +298,8 @@ public:
virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override;
virtual real_t soft_body_get_linear_stiffness(RID p_body) override;
- virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) override;
- virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) override;
+ virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) override;
+ virtual real_t soft_body_get_angular_stiffness(RID p_body) override;
virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) override;
virtual real_t soft_body_get_volume_stiffness(RID p_body) override;
@@ -337,8 +337,8 @@ public:
virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override;
- virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) override;
- virtual float pin_joint_get_param(RID p_joint, PinJointParam p_param) const override;
+ virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override;
+ virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override;
virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) override;
virtual Vector3 pin_joint_get_local_a(RID p_joint) const override;
@@ -349,8 +349,8 @@ public:
virtual RID joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) override;
virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override;
- virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) override;
- virtual float hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override;
+ virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override;
+ virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override;
virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) override;
virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override;
@@ -358,20 +358,20 @@ public:
/// Reference frame is A
virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override;
- virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) override;
- virtual float slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override;
+ virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override;
+ virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override;
/// Reference frame is A
virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override;
- virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) override;
- virtual float cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override;
+ virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override;
+ virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override;
/// Reference frame is A
virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override;
- virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value) override;
- virtual float generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) override;
+ virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) override;
+ virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) override;
virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) override;
virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) override;
@@ -393,7 +393,7 @@ public:
}
virtual void init() override;
- virtual void step(float p_deltaTime) override;
+ virtual void step(real_t p_deltaTime) override;
virtual void flush_queries() override;
virtual void finish() override;
diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp
index 09b90fe09e..7b21e4e4b2 100644
--- a/modules/bullet/bullet_types_converter.cpp
+++ b/modules/bullet/bullet_types_converter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h
index fef07c55b7..ca9b7175dd 100644
--- a/modules/bullet/bullet_types_converter.h
+++ b/modules/bullet/bullet_types_converter.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h
index a5e33d9829..a7c0fafbea 100644
--- a/modules/bullet/bullet_utilities.h
+++ b/modules/bullet/bullet_utilities.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index a3158a15e5..d9f5beb5a1 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -148,6 +148,9 @@ void CollisionObjectBullet::add_collision_exception(const CollisionObjectBullet
void CollisionObjectBullet::remove_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) {
exceptions.erase(p_ignoreCollisionObject->get_self());
+ if (!bt_collision_object) {
+ return;
+ }
bt_collision_object->setIgnoreCollisionCheck(p_ignoreCollisionObject->bt_collision_object, false);
if (space) {
space->get_broadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bt_collision_object->getBroadphaseHandle(), space->get_dispatcher());
@@ -155,11 +158,14 @@ void CollisionObjectBullet::remove_collision_exception(const CollisionObjectBull
}
bool CollisionObjectBullet::has_collision_exception(const CollisionObjectBullet *p_otherCollisionObject) const {
- return !bt_collision_object->checkCollideWith(p_otherCollisionObject->bt_collision_object);
+ return exceptions.has(p_otherCollisionObject->get_self());
}
void CollisionObjectBullet::set_collision_enabled(bool p_enabled) {
collisionsEnabled = p_enabled;
+ if (!bt_collision_object) {
+ return;
+ }
if (collisionsEnabled) {
bt_collision_object->setCollisionFlags(bt_collision_object->getCollisionFlags() & (~btCollisionObject::CF_NO_CONTACT_RESPONSE));
} else {
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
index e2d05f2c38..c8081a53f1 100644
--- a/modules/bullet/collision_object_bullet.h
+++ b/modules/bullet/collision_object_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -110,7 +110,7 @@ public:
};
protected:
- Type type;
+ Type type = TYPE_AREA;
ObjectID instance_id;
uint32_t collisionLayer = 0;
uint32_t collisionMask = 0;
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
index b4735fa9e9..e785780c5b 100644
--- a/modules/bullet/cone_twist_joint_bullet.cpp
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h
index ed4baa9d1b..7d6bafd292 100644
--- a/modules/bullet/cone_twist_joint_bullet.h
+++ b/modules/bullet/cone_twist_joint_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/config.py b/modules/bullet/config.py
index d22f9454ed..be7cf74f6f 100644
--- a/modules/bullet/config.py
+++ b/modules/bullet/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return True
+ # API Changed and bullet is disabled at the moment
+ return False
def configure(env):
diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp
index c47a23e75f..e610727685 100644
--- a/modules/bullet/constraint_bullet.cpp
+++ b/modules/bullet/constraint_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h
index 538808be51..6afd8c9b52 100644
--- a/modules/bullet/constraint_bullet.h
+++ b/modules/bullet/constraint_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
index d75bf1fb98..43ad6c56d5 100644
--- a/modules/bullet/generic_6dof_joint_bullet.cpp
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h
index ed25337745..62b8e85a81 100644
--- a/modules/bullet/generic_6dof_joint_bullet.h
+++ b/modules/bullet/generic_6dof_joint_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp
index ec7a1dbd9a..94f150b712 100644
--- a/modules/bullet/godot_collision_configuration.cpp
+++ b/modules/bullet/godot_collision_configuration.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/godot_collision_configuration.h b/modules/bullet/godot_collision_configuration.h
index ffad1b1bda..8ed55cb1da 100644
--- a/modules/bullet/godot_collision_configuration.h
+++ b/modules/bullet/godot_collision_configuration.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/godot_collision_dispatcher.cpp b/modules/bullet/godot_collision_dispatcher.cpp
index d919c85469..5d1e4d34d8 100644
--- a/modules/bullet/godot_collision_dispatcher.cpp
+++ b/modules/bullet/godot_collision_dispatcher.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/godot_collision_dispatcher.h b/modules/bullet/godot_collision_dispatcher.h
index 13e7255abf..77472a9432 100644
--- a/modules/bullet/godot_collision_dispatcher.h
+++ b/modules/bullet/godot_collision_dispatcher.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h
index 90d1614a77..ca17349130 100644
--- a/modules/bullet/godot_motion_state.h
+++ b/modules/bullet/godot_motion_state.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,7 +51,7 @@ class GodotMotionState : public btMotionState {
/// This data is used to store last world position
btTransform bodyCurrentWorldTransform;
- RigidBodyBullet *owner;
+ RigidBodyBullet *owner = nullptr;
public:
GodotMotionState(RigidBodyBullet *p_owner) :
diff --git a/modules/bullet/godot_ray_world_algorithm.cpp b/modules/bullet/godot_ray_world_algorithm.cpp
index a84f3511ba..a8291d4ab4 100644
--- a/modules/bullet/godot_ray_world_algorithm.cpp
+++ b/modules/bullet/godot_ray_world_algorithm.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/godot_ray_world_algorithm.h b/modules/bullet/godot_ray_world_algorithm.h
index 9786732d40..25798aecb4 100644
--- a/modules/bullet/godot_ray_world_algorithm.h
+++ b/modules/bullet/godot_ray_world_algorithm.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,7 @@ class GodotRayWorldAlgorithm : public btActivatingCollisionAlgorithm {
const btDiscreteDynamicsWorld *m_world;
btPersistentManifold *m_manifoldPtr;
bool m_ownManifold = false;
- bool m_isSwapped;
+ bool m_isSwapped = false;
public:
GodotRayWorldAlgorithm(const btDiscreteDynamicsWorld *world, btPersistentManifold *mf, const btCollisionAlgorithmConstructionInfo &ci, const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, bool isSwapped);
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index f82648d6ff..15d625afeb 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 1325542973..f92665f3e4 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,8 +59,8 @@ struct GodotClosestRayResultCallback : public btCollisionWorld::ClosestRayResult
bool m_pickRay = false;
int m_shapeId = 0;
- bool collide_with_bodies;
- bool collide_with_areas;
+ bool collide_with_bodies = false;
+ bool collide_with_areas = false;
public:
GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
@@ -84,8 +84,8 @@ public:
// store all colliding object
struct GodotAllConvexResultCallback : public btCollisionWorld::ConvexResultCallback {
public:
- PhysicsDirectSpaceState3D::ShapeResult *m_results;
- int m_resultMax;
+ PhysicsDirectSpaceState3D::ShapeResult *m_results = nullptr;
+ int m_resultMax = 0;
const Set<RID> *m_exclude;
int count = 0;
@@ -117,8 +117,8 @@ public:
const Set<RID> *m_exclude;
int m_shapeId = 0;
- bool collide_with_bodies;
- bool collide_with_areas;
+ bool collide_with_bodies = false;
+ bool collide_with_areas = false;
GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld),
@@ -134,13 +134,13 @@ public:
struct GodotAllContactResultCallback : public btCollisionWorld::ContactResultCallback {
public:
const btCollisionObject *m_self_object;
- PhysicsDirectSpaceState3D::ShapeResult *m_results;
- int m_resultMax;
+ PhysicsDirectSpaceState3D::ShapeResult *m_results = nullptr;
+ int m_resultMax = 0;
const Set<RID> *m_exclude;
int m_count = 0;
- bool collide_with_bodies;
- bool collide_with_areas;
+ bool collide_with_bodies = false;
+ bool collide_with_areas = false;
GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
m_self_object(p_self_object),
@@ -159,13 +159,13 @@ public:
struct GodotContactPairContactResultCallback : public btCollisionWorld::ContactResultCallback {
public:
const btCollisionObject *m_self_object;
- Vector3 *m_results;
- int m_resultMax;
+ Vector3 *m_results = nullptr;
+ int m_resultMax = 0;
const Set<RID> *m_exclude;
int m_count = 0;
- bool collide_with_bodies;
- bool collide_with_areas;
+ bool collide_with_bodies = false;
+ bool collide_with_areas = false;
GodotContactPairContactResultCallback(btCollisionObject *p_self_object, Vector3 *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
m_self_object(p_self_object),
@@ -183,14 +183,14 @@ public:
struct GodotRestInfoContactResultCallback : public btCollisionWorld::ContactResultCallback {
public:
const btCollisionObject *m_self_object;
- PhysicsDirectSpaceState3D::ShapeRestInfo *m_result;
+ PhysicsDirectSpaceState3D::ShapeRestInfo *m_result = nullptr;
const Set<RID> *m_exclude;
bool m_collided = false;
- real_t m_min_distance = 0;
- const btCollisionObject *m_rest_info_collision_object;
+ real_t m_min_distance = 0.0;
+ const btCollisionObject *m_rest_info_collision_object = nullptr;
btVector3 m_rest_info_bt_point;
- bool collide_with_bodies;
- bool collide_with_areas;
+ bool collide_with_bodies = false;
+ bool collide_with_areas = false;
GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeRestInfo *p_result, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
m_self_object(p_self_object),
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index 2338277565..4ceb98729f 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/hinge_joint_bullet.h b/modules/bullet/hinge_joint_bullet.h
index 120c40e5c0..06a95be374 100644
--- a/modules/bullet/hinge_joint_bullet.h
+++ b/modules/bullet/hinge_joint_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/joint_bullet.cpp b/modules/bullet/joint_bullet.cpp
index 6257ff0058..ac371658f5 100644
--- a/modules/bullet/joint_bullet.cpp
+++ b/modules/bullet/joint_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h
index c70cea817e..5bb8b50961 100644
--- a/modules/bullet/joint_bullet.h
+++ b/modules/bullet/joint_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
index 1cfbc65c78..8e8ff57f11 100644
--- a/modules/bullet/pin_joint_bullet.cpp
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/pin_joint_bullet.h b/modules/bullet/pin_joint_bullet.h
index e7d05f34d4..6fbb6f7e02 100644
--- a/modules/bullet/pin_joint_bullet.h
+++ b/modules/bullet/pin_joint_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp
index d29b699ecd..b5ad5749a6 100644
--- a/modules/bullet/register_types.cpp
+++ b/modules/bullet/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/register_types.h b/modules/bullet/register_types.h
index 5a01a1422e..e405996705 100644
--- a/modules/bullet/register_types.h
+++ b/modules/bullet/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h
index 0db09b2b78..face6b4861 100644
--- a/modules/bullet/rid_bullet.h
+++ b/modules/bullet/rid_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,7 +41,7 @@ class BulletPhysicsServer3D;
class RIDBullet {
RID self;
- BulletPhysicsServer3D *physicsServer;
+ BulletPhysicsServer3D *physicsServer = nullptr;
public:
_FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; }
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 284a22717b..a5093afe9d 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,11 +56,11 @@ Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const {
return gVec;
}
-float BulletPhysicsDirectBodyState3D::get_total_angular_damp() const {
+real_t BulletPhysicsDirectBodyState3D::get_total_angular_damp() const {
return body->btBody->getAngularDamping();
}
-float BulletPhysicsDirectBodyState3D::get_total_linear_damp() const {
+real_t BulletPhysicsDirectBodyState3D::get_total_linear_damp() const {
return body->btBody->getLinearDamping();
}
@@ -74,7 +74,7 @@ Basis BulletPhysicsDirectBodyState3D::get_principal_inertia_axes() const {
return Basis();
}
-float BulletPhysicsDirectBodyState3D::get_inverse_mass() const {
+real_t BulletPhysicsDirectBodyState3D::get_inverse_mass() const {
return body->btBody->getInvMass();
}
@@ -158,7 +158,7 @@ Vector3 BulletPhysicsDirectBodyState3D::get_contact_local_normal(int p_contact_i
return body->collisions[p_contact_idx].hitNormal;
}
-float BulletPhysicsDirectBodyState3D::get_contact_impulse(int p_contact_idx) const {
+real_t BulletPhysicsDirectBodyState3D::get_contact_impulse(int p_contact_idx) const {
return body->collisions[p_contact_idx].appliedImpulse;
}
@@ -322,7 +322,8 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) {
if (space) {
can_integrate_forces = false;
isScratchedSpaceOverrideModificator = false;
-
+ // Remove any constraints
+ space->remove_rigid_body_constraints(this);
// Remove this object form the physics world
space->remove_rigid_body(this);
}
@@ -411,7 +412,7 @@ void RigidBodyBullet::on_collision_checker_end() {
isTransformChanged = btBody->isActive() && !btBody->isStaticOrKinematicObject();
}
-bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) {
+bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const real_t &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) {
if (collisionsCount >= maxCollisionsDetection) {
return false;
}
@@ -709,12 +710,12 @@ bool RigidBodyBullet::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const {
}
void RigidBodyBullet::reload_axis_lock() {
- btBody->setLinearFactor(btVector3(float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z))));
+ btBody->setLinearFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z))));
if (PhysicsServer3D::BODY_MODE_CHARACTER == mode) {
/// When character angular is always locked
btBody->setAngularFactor(btVector3(0., 0., 0.));
} else {
- btBody->setAngularFactor(btVector3(float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_X)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Y)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Z))));
+ btBody->setAngularFactor(btVector3(btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_X)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Y)), btScalar(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Z))));
}
}
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 8ff96577b6..a4be7f9e07 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -81,21 +81,21 @@ public:
}
public:
- RigidBodyBullet *body;
- real_t deltaTime;
+ RigidBodyBullet *body = nullptr;
+ real_t deltaTime = 0.0;
private:
BulletPhysicsDirectBodyState3D() {}
public:
virtual Vector3 get_total_gravity() const override;
- virtual float get_total_angular_damp() const override;
- virtual float get_total_linear_damp() const override;
+ virtual real_t get_total_angular_damp() const override;
+ virtual real_t get_total_linear_damp() const override;
virtual Vector3 get_center_of_mass() const override;
virtual Basis get_principal_inertia_axes() const override;
// get the mass
- virtual float get_inverse_mass() const override;
+ virtual real_t get_inverse_mass() const override;
// get density of this body space
virtual Vector3 get_inverse_inertia() const override;
// get density of this body space
@@ -124,7 +124,7 @@ public:
virtual Vector3 get_contact_local_position(int p_contact_idx) const override;
virtual Vector3 get_contact_local_normal(int p_contact_idx) const override;
- virtual float get_contact_impulse(int p_contact_idx) const override;
+ virtual real_t get_contact_impulse(int p_contact_idx) const override;
virtual int get_contact_local_shape(int p_contact_idx) const override;
virtual RID get_contact_collider(int p_contact_idx) const override;
@@ -144,13 +144,13 @@ public:
class RigidBodyBullet : public RigidCollisionObjectBullet {
public:
struct CollisionData {
- RigidBodyBullet *otherObject;
- int other_object_shape;
- int local_shape;
+ RigidBodyBullet *otherObject = nullptr;
+ int other_object_shape = 0;
+ int local_shape = 0;
Vector3 hitLocalLocation;
Vector3 hitWorldLocation;
Vector3 hitNormal;
- float appliedImpulse;
+ real_t appliedImpulse = 0.0;
};
struct ForceIntegrationCallback {
@@ -169,7 +169,7 @@ public:
};
struct KinematicUtilities {
- RigidBodyBullet *owner;
+ RigidBodyBullet *owner = nullptr;
btScalar safe_margin;
Vector<KinematicShape> shapes;
@@ -194,10 +194,10 @@ private:
GodotMotionState *godotMotionState;
btRigidBody *btBody;
uint16_t locked_axis = 0;
- real_t mass = 1;
- real_t gravity_scale = 1;
- real_t linearDamp = 0;
- real_t angularDamp = 0;
+ real_t mass = 1.0;
+ real_t gravity_scale = 1.0;
+ real_t linearDamp = 0.0;
+ real_t angularDamp = 0.0;
bool can_sleep = true;
bool omit_forces_integration = false;
bool can_integrate_forces = false;
@@ -264,7 +264,7 @@ public:
}
bool can_add_collision() { return collisionsCount < maxCollisionsDetection; }
- bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index);
+ bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const real_t &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index);
bool was_colliding(RigidBodyBullet *p_other_object);
void set_activation_state(bool p_active);
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index c7b761e92a..82876ab77c 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -480,7 +480,11 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
Vector<real_t> l_heights;
Variant l_heights_v = d["heights"];
+#ifdef REAL_T_IS_DOUBLE
+ if (l_heights_v.get_type() == Variant::PACKED_FLOAT64_ARRAY) {
+#else
if (l_heights_v.get_type() == Variant::PACKED_FLOAT32_ARRAY) {
+#endif
// Ready-to-use heights can be passed
l_heights = l_heights_v;
@@ -503,7 +507,7 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
real_t *w = l_heights.ptrw();
const uint8_t *r = im_data.ptr();
- float *rp = (float *)r;
+ real_t *rp = (real_t *)r;
// At this point, `rp` could be used directly for Bullet, but I don't know how safe it would be.
for (int i = 0; i < l_heights.size(); ++i) {
@@ -511,7 +515,11 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
}
} else {
+#ifdef REAL_T_IS_DOUBLE
+ ERR_FAIL_MSG("Expected PackedFloat64Array or float Image.");
+#else
ERR_FAIL_MSG("Expected PackedFloat32Array or float Image.");
+#endif
}
ERR_FAIL_COND(l_width <= 0);
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
index 1c29dc1b1f..bfd95747eb 100644
--- a/modules/bullet/shape_bullet.h
+++ b/modules/bullet/shape_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -213,10 +213,10 @@ private:
class HeightMapShapeBullet : public ShapeBullet {
public:
Vector<real_t> heights;
- int width;
- int depth;
- real_t min_height;
- real_t max_height;
+ int width = 0;
+ int depth = 0;
+ real_t min_height = 0.0;
+ real_t max_height = 0.0;
HeightMapShapeBullet();
@@ -231,7 +231,7 @@ private:
class RayShapeBullet : public ShapeBullet {
public:
- real_t length = 1;
+ real_t length = 1.0;
bool slips_on_slope = false;
RayShapeBullet();
diff --git a/modules/bullet/shape_owner_bullet.cpp b/modules/bullet/shape_owner_bullet.cpp
index d63096d9a3..ea8821eaec 100644
--- a/modules/bullet/shape_owner_bullet.cpp
+++ b/modules/bullet/shape_owner_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/shape_owner_bullet.h b/modules/bullet/shape_owner_bullet.h
index f909632c99..4bd583e096 100644
--- a/modules/bullet/shape_owner_bullet.h
+++ b/modules/bullet/shape_owner_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp
index 6d5d95d07a..45c892851b 100644
--- a/modules/bullet/slider_joint_bullet.cpp
+++ b/modules/bullet/slider_joint_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/slider_joint_bullet.h b/modules/bullet/slider_joint_bullet.h
index 6410b952ed..90964671c2 100644
--- a/modules/bullet/slider_joint_bullet.h
+++ b/modules/bullet/slider_joint_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp
index 6794d6c313..91a1934e07 100644
--- a/modules/bullet/soft_body_bullet.cpp
+++ b/modules/bullet/soft_body_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -259,10 +259,10 @@ void SoftBodyBullet::set_linear_stiffness(real_t p_val) {
}
}
-void SoftBodyBullet::set_areaAngular_stiffness(real_t p_val) {
- areaAngular_stiffness = p_val;
+void SoftBodyBullet::set_angular_stiffness(real_t p_val) {
+ angular_stiffness = p_val;
if (bt_soft_body) {
- mat0->m_kAST = areaAngular_stiffness;
+ mat0->m_kAST = angular_stiffness;
}
}
@@ -409,7 +409,7 @@ void SoftBodyBullet::setup_soft_body() {
bt_soft_body->generateBendingConstraints(2, mat0);
mat0->m_kLST = linear_stiffness;
- mat0->m_kAST = areaAngular_stiffness;
+ mat0->m_kAST = angular_stiffness;
mat0->m_kVST = volume_stiffness;
// Clusters allow to have Soft vs Soft collision but doesn't work well right now
diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h
index da8a2412ed..23f6fba9a6 100644
--- a/modules/bullet/soft_body_bullet.h
+++ b/modules/bullet/soft_body_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,7 +59,7 @@ class SoftBodyBullet : public CollisionObjectBullet {
private:
btSoftBody *bt_soft_body = nullptr;
Vector<Vector<int>> indices_table;
- btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody
+ btSoftBody::Material *mat0 = nullptr; // This is just a copy of pointer managed by btSoftBody
bool isScratched = false;
Ref<Mesh> soft_mesh;
@@ -67,7 +67,7 @@ private:
int simulation_precision = 5;
real_t total_mass = 1.;
real_t linear_stiffness = 0.5; // [0,1]
- real_t areaAngular_stiffness = 0.5; // [0,1]
+ real_t angular_stiffness = 0.5; // [0,1]
real_t volume_stiffness = 0.5; // [0,1]
real_t pressure_coefficient = 0.; // [-inf,+inf]
real_t pose_matching_coefficient = 0.; // [0,1]
@@ -129,8 +129,8 @@ public:
void set_linear_stiffness(real_t p_val);
_FORCE_INLINE_ real_t get_linear_stiffness() const { return linear_stiffness; }
- void set_areaAngular_stiffness(real_t p_val);
- _FORCE_INLINE_ real_t get_areaAngular_stiffness() const { return areaAngular_stiffness; }
+ void set_angular_stiffness(real_t p_val);
+ _FORCE_INLINE_ real_t get_angular_stiffness() const { return angular_stiffness; }
void set_volume_stiffness(real_t p_val);
_FORCE_INLINE_ real_t get_volume_stiffness() const { return volume_stiffness; }
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 3bfcd83606..7d337bc4d0 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -117,7 +117,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V
}
}
-int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
+int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
if (p_result_max <= 0) {
return 0;
}
@@ -152,7 +152,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
return btQuery.m_count;
}
-bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
+bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
r_closest_safe = 0.0f;
r_closest_unsafe = 0.0f;
btVector3 bt_motion;
@@ -177,8 +177,10 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
bt_xform_to.getOrigin() += bt_motion;
if ((bt_xform_to.getOrigin() - bt_xform_from.getOrigin()).fuzzyZero()) {
+ r_closest_safe = 1.0f;
+ r_closest_unsafe = 1.0f;
bulletdelete(btShape);
- return false;
+ return true;
}
GodotClosestConvexResultCallback btResult(bt_xform_from.getOrigin(), bt_xform_to.getOrigin(), &p_exclude, p_collide_with_bodies, p_collide_with_areas);
@@ -212,7 +214,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
}
/// Returns the list of contacts pairs in this order: Local contact, other body contact
-bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
+bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
if (p_result_max <= 0) {
return false;
}
@@ -248,7 +250,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
return btQuery.m_count;
}
-bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
+bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
ERR_FAIL_COND_V(!shape, false);
@@ -477,16 +479,20 @@ void SpaceBullet::add_rigid_body(RigidBodyBullet *p_body) {
}
}
-void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) {
+void SpaceBullet::remove_rigid_body_constraints(RigidBodyBullet *p_body) {
btRigidBody *btBody = p_body->get_bt_rigid_body();
int constraints = btBody->getNumConstraintRefs();
if (constraints > 0) {
- WARN_PRINT("A body connected to joints was removed. Ensure bodies are disconnected from joints before removing them.");
+ ERR_PRINT("A body connected to joints was removed.");
for (int i = 0; i < constraints; i++) {
dynamicsWorld->removeConstraint(btBody->getConstraintRef(i));
}
}
+}
+
+void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) {
+ btRigidBody *btBody = p_body->get_bt_rigid_body();
if (p_body->is_static()) {
dynamicsWorld->removeCollisionObject(btBody);
@@ -835,20 +841,32 @@ void SpaceBullet::check_body_collision() {
Vector3 collisionWorldPosition;
Vector3 collisionLocalPosition;
Vector3 normalOnB;
- float appliedImpulse = pt.m_appliedImpulse;
+ real_t appliedImpulse = pt.m_appliedImpulse;
B_TO_G(pt.m_normalWorldOnB, normalOnB);
+ // The pt.m_index only contains the shape index when more than one collision shape is used
+ // and only if the collision shape is not a concave collision shape.
+ // A value of -1 in pt.m_partId indicates the pt.m_index is a shape index.
+ int shape_index_a = 0;
+ if (bodyA->get_shape_count() > 1 && pt.m_partId0 == -1) {
+ shape_index_a = pt.m_index0;
+ }
+ int shape_index_b = 0;
+ if (bodyB->get_shape_count() > 1 && pt.m_partId1 == -1) {
+ shape_index_b = pt.m_index1;
+ }
+
if (bodyA->can_add_collision()) {
B_TO_G(pt.getPositionWorldOnB(), collisionWorldPosition);
/// pt.m_localPointB Doesn't report the exact point in local space
B_TO_G(pt.getPositionWorldOnB() - contactManifold->getBody1()->getWorldTransform().getOrigin(), collisionLocalPosition);
- bodyA->add_collision_object(bodyB, collisionWorldPosition, collisionLocalPosition, normalOnB, appliedImpulse, pt.m_index1, pt.m_index0);
+ bodyA->add_collision_object(bodyB, collisionWorldPosition, collisionLocalPosition, normalOnB, appliedImpulse, shape_index_b, shape_index_a);
}
if (bodyB->can_add_collision()) {
B_TO_G(pt.getPositionWorldOnA(), collisionWorldPosition);
/// pt.m_localPointA Doesn't report the exact point in local space
B_TO_G(pt.getPositionWorldOnA() - contactManifold->getBody0()->getWorldTransform().getOrigin(), collisionLocalPosition);
- bodyB->add_collision_object(bodyA, collisionWorldPosition, collisionLocalPosition, normalOnB * -1, appliedImpulse * -1, pt.m_index0, pt.m_index1);
+ bodyB->add_collision_object(bodyA, collisionWorldPosition, collisionLocalPosition, normalOnB * -1, appliedImpulse * -1, shape_index_a, shape_index_b);
}
#ifdef DEBUG_ENABLED
@@ -1044,7 +1062,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
return has_penetration;
}
-int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin) {
+int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin) {
btTransform body_transform;
G_TO_B(p_transform, body_transform);
UNSCALE_BT_BASIS(body_transform);
@@ -1074,13 +1092,13 @@ private:
btDbvtVolume bounds;
const btCollisionObject *self_collision_object;
- uint32_t collision_layer;
- uint32_t collision_mask;
+ uint32_t collision_layer = 0;
+ uint32_t collision_mask = 0;
struct CompoundLeafCallback : btDbvt::ICollide {
private:
- RecoverPenetrationBroadPhaseCallback *parent_callback;
- btCollisionObject *collision_object;
+ RecoverPenetrationBroadPhaseCallback *parent_callback = nullptr;
+ btCollisionObject *collision_object = nullptr;
public:
CompoundLeafCallback(RecoverPenetrationBroadPhaseCallback *p_parent_callback, btCollisionObject *p_collision_object) :
@@ -1098,8 +1116,8 @@ private:
public:
struct BroadphaseResult {
- btCollisionObject *collision_object;
- int compound_child_index;
+ btCollisionObject *collision_object = nullptr;
+ int compound_child_index = 0;
};
Vector<BroadphaseResult> results;
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index e362f27d39..87aa2b9e93 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,11 +78,11 @@ public:
virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override;
virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) override;
- virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override;
- virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override;
+ virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override;
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &r_closest_safe, real_t &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) override;
/// Returns the list of contacts pairs in this order: Local contact, other body contact
- virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override;
- virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override;
+ virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override;
+ virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) override;
virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override;
};
@@ -100,12 +100,12 @@ class SpaceBullet : public RIDBullet {
btGhostPairCallback *ghostPairCallback = nullptr;
GodotFilterCallback *godotFilterCallback = nullptr;
- btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver;
- btVoronoiSimplexSolver *gjk_simplex_solver;
+ btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver = nullptr;
+ btVoronoiSimplexSolver *gjk_simplex_solver = nullptr;
BulletPhysicsDirectSpaceState *direct_access;
Vector3 gravityDirection = Vector3(0, -1, 0);
- real_t gravityMagnitude = 10;
+ real_t gravityMagnitude = 10.0;
real_t linear_damp = 0.0;
real_t angular_damp = 0.0;
@@ -151,6 +151,7 @@ public:
void reload_collision_filters(AreaBullet *p_area);
void add_rigid_body(RigidBodyBullet *p_body);
+ void remove_rigid_body_constraints(RigidBodyBullet *p_body);
void remove_rigid_body(RigidBodyBullet *p_body);
void reload_collision_filters(RigidBodyBullet *p_body);
@@ -167,7 +168,7 @@ public:
BulletPhysicsDirectSpaceState *get_direct_state();
void set_debug_contacts(int p_amount) { contactDebug.resize(p_amount); }
- _FORCE_INLINE_ bool is_debugging_contacts() const { return !contactDebug.empty(); }
+ _FORCE_INLINE_ bool is_debugging_contacts() const { return !contactDebug.is_empty(); }
_FORCE_INLINE_ void reset_debug_contact_count() {
contactDebugCount = 0;
}
@@ -188,7 +189,7 @@ public:
real_t get_angular_damp() const { return angular_damp; }
bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes);
- int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin);
+ int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin);
private:
void create_empty_world(bool p_create_soft_world);
diff --git a/modules/camera/camera_osx.h b/modules/camera/camera_osx.h
index a07b83c6af..964b7c1edc 100644
--- a/modules/camera/camera_osx.h
+++ b/modules/camera/camera_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_osx.mm
index 306632a016..3d2053ad23 100644
--- a/modules/camera/camera_osx.mm
+++ b/modules/camera/camera_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/camera/camera_win.cpp b/modules/camera/camera_win.cpp
index 1646644be3..226a642dcf 100644
--- a/modules/camera/camera_win.cpp
+++ b/modules/camera/camera_win.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/camera/camera_win.h b/modules/camera/camera_win.h
index bbc8880c12..671e7d5beb 100644
--- a/modules/camera/camera_win.h
+++ b/modules/camera/camera_win.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/camera/register_types.cpp b/modules/camera/register_types.cpp
index 9479310a13..0d33ff9ddc 100644
--- a/modules/camera/register_types.cpp
+++ b/modules/camera/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/camera/register_types.h b/modules/camera/register_types.h
index e34f84bf2c..0ae9aa2c0b 100644
--- a/modules/camera/register_types.h
+++ b/modules/camera/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/camera_iphone/SCsub b/modules/camera_iphone/SCsub
deleted file mode 100644
index 0a37d9a6f5..0000000000
--- a/modules/camera_iphone/SCsub
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-Import("env_modules")
-
-env_camera = env_modules.Clone()
-
-# (iOS) Enable module support
-env_camera.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
-
-# (iOS) Build as separate static library
-modules_sources = []
-env_camera.add_source_files(modules_sources, "*.cpp")
-env_camera.add_source_files(modules_sources, "*.mm")
-mod_lib = env_modules.add_library("#bin/libgodot_camera_module" + env["LIBSUFFIX"], modules_sources)
diff --git a/modules/camera_iphone/camera.gdip b/modules/camera_iphone/camera.gdip
deleted file mode 100644
index 09017b8d27..0000000000
--- a/modules/camera_iphone/camera.gdip
+++ /dev/null
@@ -1,18 +0,0 @@
-[config]
-name="Camera"
-binary="camera_lib.a"
-
-initialization="register_camera_types"
-deinitialization="unregister_camera_types"
-
-[dependencies]
-linked=[]
-embedded=[]
-system=["AVFoundation.framework"]
-
-capabilities=[]
-
-files=[]
-
-[plist]
-NSCameraUsageDescription="Device camera is used for some functionality"
diff --git a/modules/camera_iphone/camera_ios.mm b/modules/camera_iphone/camera_ios.mm
deleted file mode 100644
index e4cb928805..0000000000
--- a/modules/camera_iphone/camera_ios.mm
+++ /dev/null
@@ -1,445 +0,0 @@
-/*************************************************************************/
-/* camera_ios.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-///@TODO this is a near duplicate of CameraOSX, we should find a way to combine those to minimize code duplication!!!!
-// If you fix something here, make sure you fix it there as wel!
-
-#include "camera_ios.h"
-#include "servers/camera/camera_feed.h"
-
-#import <AVFoundation/AVFoundation.h>
-#import <UIKit/UIKit.h>
-
-//////////////////////////////////////////////////////////////////////////
-// MyCaptureSession - This is a little helper class so we can capture our frames
-
-@interface MyCaptureSession : AVCaptureSession <AVCaptureVideoDataOutputSampleBufferDelegate> {
- Ref<CameraFeed> feed;
- size_t width[2];
- size_t height[2];
- Vector<uint8_t> img_data[2];
-
- AVCaptureDeviceInput *input;
- AVCaptureVideoDataOutput *output;
-}
-
-@end
-
-@implementation MyCaptureSession
-
-- (id)initForFeed:(Ref<CameraFeed>)p_feed andDevice:(AVCaptureDevice *)p_device {
- if (self = [super init]) {
- NSError *error;
- feed = p_feed;
- width[0] = 0;
- height[0] = 0;
- width[1] = 0;
- height[1] = 0;
-
- // prepare our device
- [p_device lockForConfiguration:&error];
-
- [p_device setFocusMode:AVCaptureFocusModeLocked];
- [p_device setExposureMode:AVCaptureExposureModeLocked];
- [p_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked];
-
- [p_device unlockForConfiguration];
-
- [self beginConfiguration];
-
- // setup our capture
- self.sessionPreset = AVCaptureSessionPreset1280x720;
-
- input = [AVCaptureDeviceInput deviceInputWithDevice:p_device error:&error];
- if (!input) {
- print_line("Couldn't get input device for camera");
- } else {
- [self addInput:input];
- }
-
- output = [AVCaptureVideoDataOutput new];
- if (!output) {
- print_line("Couldn't get output device for camera");
- } else {
- NSDictionary *settings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) };
- output.videoSettings = settings;
-
- // discard if the data output queue is blocked (as we process the still image)
- [output setAlwaysDiscardsLateVideoFrames:YES];
-
- // now set ourselves as the delegate to receive new frames. Note that we're doing this on the main thread at the moment, we may need to change this..
- [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
-
- [self addOutput:output];
- }
-
- [self commitConfiguration];
-
- // kick off our session..
- [self startRunning];
- };
- return self;
-}
-
-- (void)cleanup {
- // stop running
- [self stopRunning];
-
- // cleanup
- [self beginConfiguration];
-
- if (input) {
- [self removeInput:input];
- // don't release this
- input = nil;
- }
-
- if (output) {
- [self removeOutput:output];
- [output setSampleBufferDelegate:nil queue:NULL];
- output = nil;
- }
-
- [self commitConfiguration];
-}
-
-- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
- // This gets called every time our camera has a new image for us to process.
- // May need to investigate in a way to throttle this if we get more images then we're rendering frames..
-
- // For now, version 1, we're just doing the bare minimum to make this work...
-
- CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
- // int width = CVPixelBufferGetWidth(pixelBuffer);
- // int height = CVPixelBufferGetHeight(pixelBuffer);
-
- // It says that we need to lock this on the documentation pages but it's not in the samples
- // need to lock our base address so we can access our pixel buffers, better safe then sorry?
- CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
-
- // get our buffers
- unsigned char *dataY = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
- unsigned char *dataCbCr = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
- if (dataY == NULL) {
- print_line("Couldn't access Y pixel buffer data");
- } else if (dataCbCr == NULL) {
- print_line("Couldn't access CbCr pixel buffer data");
- } else {
- UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown;
-
- if (@available(iOS 13, *)) {
- orientation = [UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation;
-#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR
- } else {
- orientation = [[UIApplication sharedApplication] statusBarOrientation];
-#endif
- }
-
- Ref<Image> img[2];
-
- {
- // do Y
- size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
- size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
-
- if ((width[0] != new_width) || (height[0] != new_height)) {
- width[0] = new_width;
- height[0] = new_height;
- img_data[0].resize(new_width * new_height);
- }
-
- uint8_t *w = img_data[0].ptrw();
- memcpy(w, dataY, new_width * new_height);
-
- img[0].instance();
- img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]);
- }
-
- {
- // do CbCr
- size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1);
- size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
-
- if ((width[1] != new_width) || (height[1] != new_height)) {
- width[1] = new_width;
- height[1] = new_height;
- img_data[1].resize(2 * new_width * new_height);
- }
-
- uint8_t *w = img_data[1].ptrw();
- memcpy(w, dataCbCr, 2 * new_width * new_height);
-
- ///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion
- img[1].instance();
- img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]);
- }
-
- // set our texture...
- feed->set_YCbCr_imgs(img[0], img[1]);
-
- // update our matrix to match the orientation, note, before changing anything
- // here, be aware that the project orientation settings must match your xcode
- // settings or this will go wrong!
- Transform2D display_transform;
- switch (orientation) {
- case UIInterfaceOrientationPortrait: {
- display_transform = Transform2D(0.0, -1.0, -1.0, 0.0, 1.0, 1.0);
- } break;
- case UIInterfaceOrientationLandscapeRight: {
- display_transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0);
- } break;
- case UIInterfaceOrientationLandscapeLeft: {
- display_transform = Transform2D(-1.0, 0.0, 0.0, 1.0, 1.0, 0.0);
- } break;
- default: {
- display_transform = Transform2D(0.0, 1.0, 1.0, 0.0, 0.0, 0.0);
- } break;
- }
-
- //TODO: this is correct for the camera on the back, I have a feeling this needs to be inversed for the camera on the front!
- feed->set_transform(display_transform);
- }
-
- // and unlock
- CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
-}
-
-@end
-
-//////////////////////////////////////////////////////////////////////////
-// CameraFeedIOS - Subclass for camera feeds in iOS
-
-class CameraFeedIOS : public CameraFeed {
-private:
- AVCaptureDevice *device;
- MyCaptureSession *capture_session;
-
-public:
- bool get_is_arkit() const;
- AVCaptureDevice *get_device() const;
-
- CameraFeedIOS();
- ~CameraFeedIOS();
-
- void set_device(AVCaptureDevice *p_device);
-
- bool activate_feed();
- void deactivate_feed();
-};
-
-AVCaptureDevice *CameraFeedIOS::get_device() const {
- return device;
-};
-
-CameraFeedIOS::CameraFeedIOS() {
- capture_session = NULL;
- device = NULL;
- transform = Transform2D(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); /* should re-orientate this based on device orientation */
-};
-
-void CameraFeedIOS::set_device(AVCaptureDevice *p_device) {
- device = p_device;
-
- // get some info
- NSString *device_name = p_device.localizedName;
- name = device_name.UTF8String;
- position = CameraFeed::FEED_UNSPECIFIED;
- if ([p_device position] == AVCaptureDevicePositionBack) {
- position = CameraFeed::FEED_BACK;
- } else if ([p_device position] == AVCaptureDevicePositionFront) {
- position = CameraFeed::FEED_FRONT;
- };
-};
-
-CameraFeedIOS::~CameraFeedIOS() {
- if (capture_session) {
- capture_session = nil;
- };
-
- if (device) {
- device = nil;
- };
-};
-
-bool CameraFeedIOS::activate_feed() {
- if (capture_session) {
- // already recording!
- } else {
- // start camera capture
- capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device];
- };
-
- return true;
-};
-
-void CameraFeedIOS::deactivate_feed() {
- // end camera capture if we have one
- if (capture_session) {
- [capture_session cleanup];
- capture_session = nil;
- };
-};
-
-//////////////////////////////////////////////////////////////////////////
-// MyDeviceNotifications - This is a little helper class gets notifications
-// when devices are connected/disconnected
-
-@interface MyDeviceNotifications : NSObject {
- CameraIOS *camera_server;
-}
-
-@end
-
-@implementation MyDeviceNotifications
-
-- (void)devices_changed:(NSNotification *)notification {
- camera_server->update_feeds();
-}
-
-- (id)initForServer:(CameraIOS *)p_server {
- if (self = [super init]) {
- camera_server = p_server;
-
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasConnectedNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasDisconnectedNotification object:nil];
- };
- return self;
-}
-
-- (void)dealloc {
- // remove notifications
- [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil];
-}
-
-@end
-
-MyDeviceNotifications *device_notifications = nil;
-
-//////////////////////////////////////////////////////////////////////////
-// CameraIOS - Subclass for our camera server on iPhone
-
-void CameraIOS::update_feeds() {
- // this way of doing things is deprecated but still works,
- // rewrite to using AVCaptureDeviceDiscoverySession
-
- NSMutableArray *deviceTypes = [NSMutableArray array];
-
- if (@available(iOS 10, *)) {
- [deviceTypes addObject:AVCaptureDeviceTypeBuiltInWideAngleCamera];
- [deviceTypes addObject:AVCaptureDeviceTypeBuiltInTelephotoCamera];
-
- if (@available(iOS 10.2, *)) {
- [deviceTypes addObject:AVCaptureDeviceTypeBuiltInDualCamera];
- }
-
- if (@available(iOS 11.1, *)) {
- [deviceTypes addObject:AVCaptureDeviceTypeBuiltInTrueDepthCamera];
- }
-
- AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession
- discoverySessionWithDeviceTypes:deviceTypes
- mediaType:AVMediaTypeVideo
- position:AVCaptureDevicePositionUnspecified];
-
- // remove devices that are gone..
- for (int i = feeds.size() - 1; i >= 0; i--) {
- Ref<CameraFeedIOS> feed(feeds[i]);
-
- if (feed.is_null()) {
- // feed not managed by us
- } else if (![session.devices containsObject:feed->get_device()]) {
- // remove it from our array, this will also destroy it ;)
- remove_feed(feed);
- };
- };
-
- // add new devices..
- for (AVCaptureDevice *device in session.devices) {
- bool found = false;
-
- for (int i = 0; i < feeds.size() && !found; i++) {
- Ref<CameraFeedIOS> feed(feeds[i]);
-
- if (feed.is_null()) {
- // feed not managed by us
- } else if (feed->get_device() == device) {
- found = true;
- };
- };
-
- if (!found) {
- Ref<CameraFeedIOS> newfeed;
- newfeed.instance();
- newfeed->set_device(device);
- add_feed(newfeed);
- };
- };
- }
-};
-
-CameraIOS::CameraIOS() {
- // check if we have our usage description
- NSString *usage_desc = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSCameraUsageDescription"];
- if (usage_desc == NULL) {
- // don't initialise if we don't get anything
- print_line("No NSCameraUsageDescription key in pList, no access to cameras.");
- return;
- } else if (usage_desc.length == 0) {
- // don't initialise if we don't get anything
- print_line("Empty NSCameraUsageDescription key in pList, no access to cameras.");
- return;
- }
-
- // now we'll request access.
- // If this is the first time the user will be prompted with the string (iOS will read it).
- // Once a decision is made it is returned. If the user wants to change it later on they
- // need to go into setting.
- print_line("Requesting Camera permissions");
-
- [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
- completionHandler:^(BOOL granted) {
- if (granted) {
- print_line("Access to cameras granted!");
-
- // Find available cameras we have at this time
- update_feeds();
-
- // should only have one of these....
- device_notifications = [[MyDeviceNotifications alloc] initForServer:this];
- } else {
- print_line("No access to cameras!");
- }
- }];
-};
-
-CameraIOS::~CameraIOS() {
- device_notifications = nil;
-};
diff --git a/modules/camera_iphone/camera_module.h b/modules/camera_iphone/camera_module.h
deleted file mode 100644
index d123071a70..0000000000
--- a/modules/camera_iphone/camera_module.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*************************************************************************/
-/* camera_module.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-void register_camera_types();
-void unregister_camera_types();
diff --git a/modules/camera_iphone/config.py b/modules/camera_iphone/config.py
deleted file mode 100644
index e68603fc93..0000000000
--- a/modules/camera_iphone/config.py
+++ /dev/null
@@ -1,6 +0,0 @@
-def can_build(env, platform):
- return platform == "iphone"
-
-
-def configure(env):
- pass
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 04e1c4de35..f0a2f17ba9 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/csg/csg.h b/modules/csg/csg.h
index ef1103e1ac..3fbed66e5c 100644
--- a/modules/csg/csg.h
+++ b/modules/csg/csg.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,9 +48,9 @@ struct CSGBrush {
Vector3 vertices[3];
Vector2 uvs[3];
AABB aabb;
- bool smooth;
- bool invert;
- int material;
+ bool smooth = false;
+ bool invert = false;
+ int material = 0;
};
Vector<Face> faces;
@@ -74,20 +74,20 @@ struct CSGBrushOperation {
struct MeshMerge {
struct Face {
- bool from_b;
- bool inside;
- int points[3];
+ bool from_b = false;
+ bool inside = false;
+ int points[3] = {};
Vector2 uvs[3];
- bool smooth;
- bool invert;
- int material_idx;
+ bool smooth = false;
+ bool invert = false;
+ int material_idx = 0;
};
struct FaceBVH {
- int face;
- int left;
- int right;
- int next;
+ int face = 0;
+ int left = 0;
+ int right = 0;
+ int next = 0;
Vector3 center;
AABB aabb;
};
@@ -142,7 +142,7 @@ struct CSGBrushOperation {
Map<Ref<Material>, int> materials;
Map<Vector3, int> vertex_map;
OAHashMap<VertexKey, int, VertexKeyHash> snap_cache;
- float vertex_snap;
+ float vertex_snap = 0.0;
inline void _add_distance(List<real_t> &r_intersectionsA, List<real_t> &r_intersectionsB, bool p_from_B, real_t p_distance) const;
inline bool _bvh_inside(FaceBVH *facebvhptr, int p_max_depth, int p_bvh_first, int p_face_idx) const;
@@ -159,7 +159,7 @@ struct CSGBrushOperation {
};
struct Face2D {
- int vertex_idx[3];
+ int vertex_idx[3] = {};
};
Vector<Vertex2D> vertices;
@@ -167,7 +167,7 @@ struct CSGBrushOperation {
Plane plane;
Transform to_2D;
Transform to_3D;
- float vertex_snap2;
+ float vertex_snap2 = 0.0;
inline int _get_point_idx(const Vector2 &p_point);
inline int _add_vertex(const Vertex2D &p_vertex);
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index f8c05761bb..e23442ef99 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,8 +56,7 @@ String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo,
}
if (Object::cast_to<CSGBox3D>(cs)) {
- static const char *hname[3] = { "Width", "Height", "Depth" };
- return hname[p_idx];
+ return "Size";
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
@@ -81,14 +80,7 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int
if (Object::cast_to<CSGBox3D>(cs)) {
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
- switch (p_idx) {
- case 0:
- return s->get_width();
- case 1:
- return s->get_height();
- case 2:
- return s->get_depth();
- }
+ return s->get_size();
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
@@ -123,7 +115,7 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
Geometry3D::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
float d = ra.x;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -142,24 +134,16 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
d = 0.001;
}
- switch (p_idx) {
- case 0:
- s->set_width(d * 2);
- break;
- case 1:
- s->set_height(d * 2);
- break;
- case 2:
- s->set_depth(d * 2);
- break;
- }
+ Vector3 h = s->get_size();
+ h[p_idx] = d * 2;
+ s->set_size(h);
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
@@ -171,7 +155,7 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -194,7 +178,7 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001) {
@@ -229,38 +213,14 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
if (Object::cast_to<CSGBox3D>(cs)) {
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
if (p_cancel) {
- switch (p_idx) {
- case 0:
- s->set_width(p_restore);
- break;
- case 1:
- s->set_height(p_restore);
- break;
- case 2:
- s->set_depth(p_restore);
- break;
- }
+ s->set_size(p_restore);
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Change Box Shape Extents"));
- static const char *method[3] = { "set_width", "set_height", "set_depth" };
- float current = 0;
- switch (p_idx) {
- case 0:
- current = s->get_width();
- break;
- case 1:
- current = s->get_height();
- break;
- case 2:
- current = s->get_depth();
- break;
- }
-
- ur->add_do_method(s, method[p_idx], current);
- ur->add_undo_method(s, method[p_idx], p_restore);
+ ur->create_action(TTR("Change Box Shape Size"));
+ ur->add_do_method(s, "set_size", s->get_size());
+ ur->add_undo_method(s, "set_size", p_restore);
ur->commit_action();
}
@@ -408,9 +368,13 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
Vector<Vector3> handles;
- handles.push_back(Vector3(s->get_width() * 0.5, 0, 0));
- handles.push_back(Vector3(0, s->get_height() * 0.5, 0));
- handles.push_back(Vector3(0, 0, s->get_depth() * 0.5));
+
+ for (int i = 0; i < 3; i++) {
+ Vector3 h;
+ h[i] = s->get_size()[i] / 2;
+ handles.push_back(h);
+ }
+
p_gizmo->add_handles(handles, handles_material);
}
diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h
index cf44f76f37..8f7da35de3 100644
--- a/modules/csg/csg_gizmos.h
+++ b/modules/csg/csg_gizmos.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 8f2ebc7232..40ba457e43 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,8 @@ void CSGShape3D::set_use_collision(bool p_enable) {
if (use_collision) {
root_collision_shape.instance();
- root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
+ root_collision_instance = PhysicsServer3D::get_singleton()->body_create();
+ PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC);
PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space());
@@ -58,7 +59,7 @@ void CSGShape3D::set_use_collision(bool p_enable) {
root_collision_instance = RID();
root_collision_shape.unref();
}
- _change_notify();
+ notify_property_list_changed();
}
bool CSGShape3D::is_using_collision() const {
@@ -494,7 +495,8 @@ void CSGShape3D::_notification(int p_what) {
if (use_collision && is_root_shape()) {
root_collision_shape.instance();
- root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
+ root_collision_instance = PhysicsServer3D::get_singleton()->body_create();
+ PhysicsServer3D::get_singleton()->body_set_mode(root_collision_instance, PhysicsServer3D::BODY_MODE_STATIC);
PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space());
@@ -625,15 +627,6 @@ void CSGShape3D::_bind_methods() {
}
CSGShape3D::CSGShape3D() {
- operation = OPERATION_UNION;
- parent = nullptr;
- brush = nullptr;
- dirty = false;
- snap = 0.001;
- use_collision = false;
- collision_layer = 1;
- collision_mask = 1;
- calculate_tangents = true;
set_notify_local_transform(true);
}
@@ -701,7 +694,7 @@ CSGPrimitive3D::CSGPrimitive3D() {
CSGBrush *CSGMesh3D::_build_brush() {
if (!mesh.is_valid()) {
- return nullptr;
+ return memnew(CSGBrush);
}
Vector<Vector3> vertices;
@@ -719,7 +712,7 @@ CSGBrush *CSGMesh3D::_build_brush() {
if (arrays.size() == 0) {
_make_dirty();
- ERR_FAIL_COND_V(arrays.size() == 0, nullptr);
+ ERR_FAIL_COND_V(arrays.size() == 0, memnew(CSGBrush));
}
Vector<Vector3> avertices = arrays[Mesh::ARRAY_VERTEX];
@@ -840,7 +833,7 @@ CSGBrush *CSGMesh3D::_build_brush() {
}
if (vertices.size() == 0) {
- return nullptr;
+ return memnew(CSGBrush);
}
return _create_brush_from_arrays(vertices, uvs, smooth, materials);
@@ -927,25 +920,27 @@ CSGBrush *CSGSphere3D::_build_brush() {
bool *invertw = invert.ptrw();
int face = 0;
+ const double lat_step = Math_TAU / rings;
+ const double lon_step = Math_TAU / radial_segments;
for (int i = 1; i <= rings; i++) {
- double lat0 = Math_PI * (-0.5 + (double)(i - 1) / rings);
+ double lat0 = lat_step * (i - 1) - Math_TAU / 4;
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
double u0 = double(i - 1) / rings;
- double lat1 = Math_PI * (-0.5 + (double)i / rings);
+ double lat1 = lat_step * i - Math_TAU / 4;
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
double u1 = double(i) / rings;
for (int j = radial_segments; j >= 1; j--) {
- double lng0 = 2 * Math_PI * (double)(j - 1) / radial_segments;
+ double lng0 = lon_step * (j - 1);
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
double v0 = double(i - 1) / radial_segments;
- double lng1 = 2 * Math_PI * (double)(j) / radial_segments;
+ double lng1 = lon_step * j;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
double v1 = double(i) / radial_segments;
@@ -1038,7 +1033,6 @@ void CSGSphere3D::set_radius(const float p_radius) {
radius = p_radius;
_make_dirty();
update_gizmo();
- _change_notify("radius");
}
float CSGSphere3D::get_radius() const {
@@ -1125,7 +1119,7 @@ CSGBrush *CSGBox3D::_build_brush() {
int face = 0;
- Vector3 vertex_mul(width * 0.5, height * 0.5, depth * 0.5);
+ Vector3 vertex_mul = size / 2;
{
for (int i = 0; i < 6; i++) {
@@ -1194,55 +1188,24 @@ CSGBrush *CSGBox3D::_build_brush() {
}
void CSGBox3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_width", "width"), &CSGBox3D::set_width);
- ClassDB::bind_method(D_METHOD("get_width"), &CSGBox3D::get_width);
-
- ClassDB::bind_method(D_METHOD("set_height", "height"), &CSGBox3D::set_height);
- ClassDB::bind_method(D_METHOD("get_height"), &CSGBox3D::get_height);
-
- ClassDB::bind_method(D_METHOD("set_depth", "depth"), &CSGBox3D::set_depth);
- ClassDB::bind_method(D_METHOD("get_depth"), &CSGBox3D::get_depth);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &CSGBox3D::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &CSGBox3D::get_size);
ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGBox3D::set_material);
ClassDB::bind_method(D_METHOD("get_material"), &CSGBox3D::get_material);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_width", "get_width");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_height", "get_height");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
-void CSGBox3D::set_width(const float p_width) {
- width = p_width;
- _make_dirty();
- update_gizmo();
- _change_notify("width");
-}
-
-float CSGBox3D::get_width() const {
- return width;
-}
-
-void CSGBox3D::set_height(const float p_height) {
- height = p_height;
+void CSGBox3D::set_size(const Vector3 &p_size) {
+ size = p_size;
_make_dirty();
update_gizmo();
- _change_notify("height");
}
-float CSGBox3D::get_height() const {
- return height;
-}
-
-void CSGBox3D::set_depth(const float p_depth) {
- depth = p_depth;
- _make_dirty();
- update_gizmo();
- _change_notify("depth");
-}
-
-float CSGBox3D::get_depth() const {
- return depth;
+Vector3 CSGBox3D::get_size() const {
+ return size;
}
void CSGBox3D::set_material(const Ref<Material> &p_material) {
@@ -1255,13 +1218,6 @@ Ref<Material> CSGBox3D::get_material() const {
return material;
}
-CSGBox3D::CSGBox3D() {
- // defaults
- width = 2.0;
- height = 2.0;
- depth = 2.0;
-}
-
///////////////
CSGBrush *CSGCylinder3D::_build_brush() {
@@ -1303,8 +1259,8 @@ CSGBrush *CSGCylinder3D::_build_brush() {
float inc = float(i) / sides;
float inc_n = float((i + 1)) / sides;
- float ang = inc * Math_PI * 2.0;
- float ang_n = inc_n * Math_PI * 2.0;
+ float ang = inc * Math_TAU;
+ float ang_n = inc_n * Math_TAU;
Vector3 base(Math::cos(ang), 0, Math::sin(ang));
Vector3 base_n(Math::cos(ang_n), 0, Math::sin(ang_n));
@@ -1427,7 +1383,6 @@ void CSGCylinder3D::set_radius(const float p_radius) {
radius = p_radius;
_make_dirty();
update_gizmo();
- _change_notify("radius");
}
float CSGCylinder3D::get_radius() const {
@@ -1438,7 +1393,6 @@ void CSGCylinder3D::set_height(const float p_height) {
height = p_height;
_make_dirty();
update_gizmo();
- _change_notify("height");
}
float CSGCylinder3D::get_height() const {
@@ -1502,7 +1456,7 @@ CSGBrush *CSGTorus3D::_build_brush() {
float max_radius = outer_radius;
if (min_radius == max_radius) {
- return nullptr; //sorry, can't
+ return memnew(CSGBrush); //sorry, can't
}
if (min_radius > max_radius) {
@@ -1545,8 +1499,8 @@ CSGBrush *CSGTorus3D::_build_brush() {
float inci = float(i) / sides;
float inci_n = float((i + 1)) / sides;
- float angi = inci * Math_PI * 2.0;
- float angi_n = inci_n * Math_PI * 2.0;
+ float angi = inci * Math_TAU;
+ float angi_n = inci_n * Math_TAU;
Vector3 normali = Vector3(Math::cos(angi), 0, Math::sin(angi));
Vector3 normali_n = Vector3(Math::cos(angi_n), 0, Math::sin(angi_n));
@@ -1555,8 +1509,8 @@ CSGBrush *CSGTorus3D::_build_brush() {
float incj = float(j) / ring_sides;
float incj_n = float((j + 1)) / ring_sides;
- float angj = incj * Math_PI * 2.0;
- float angj_n = incj_n * Math_PI * 2.0;
+ float angj = incj * Math_TAU;
+ float angj_n = incj_n * Math_TAU;
Vector2 normalj = Vector2(Math::cos(angj), Math::sin(angj)) * radius + Vector2(min_radius + radius, 0);
Vector2 normalj_n = Vector2(Math::cos(angj_n), Math::sin(angj_n)) * radius + Vector2(min_radius + radius, 0);
@@ -1648,7 +1602,6 @@ void CSGTorus3D::set_inner_radius(const float p_inner_radius) {
inner_radius = p_inner_radius;
_make_dirty();
update_gizmo();
- _change_notify("inner_radius");
}
float CSGTorus3D::get_inner_radius() const {
@@ -1659,7 +1612,6 @@ void CSGTorus3D::set_outer_radius(const float p_outer_radius) {
outer_radius = p_outer_radius;
_make_dirty();
update_gizmo();
- _change_notify("outer_radius");
}
float CSGTorus3D::get_outer_radius() const {
@@ -1721,7 +1673,7 @@ CSGBrush *CSGPolygon3D::_build_brush() {
// set our bounding box
if (polygon.size() < 3) {
- return nullptr;
+ return memnew(CSGBrush);
}
Vector<Point2> final_polygon = polygon;
@@ -1733,7 +1685,7 @@ CSGBrush *CSGPolygon3D::_build_brush() {
Vector<int> triangles = Geometry2D::triangulate_polygon(final_polygon);
if (triangles.size() < 3) {
- return nullptr;
+ return memnew(CSGBrush);
}
Path3D *path = nullptr;
@@ -1767,15 +1719,15 @@ CSGBrush *CSGPolygon3D::_build_brush() {
if (mode == MODE_PATH) {
if (!has_node(path_node)) {
- return nullptr;
+ return memnew(CSGBrush);
}
Node *n = get_node(path_node);
if (!n) {
- return nullptr;
+ return memnew(CSGBrush);
}
path = Object::cast_to<Path3D>(n);
if (!path) {
- return nullptr;
+ return memnew(CSGBrush);
}
if (path != path_cache) {
@@ -1793,10 +1745,10 @@ CSGBrush *CSGPolygon3D::_build_brush() {
}
curve = path->get_curve();
if (curve.is_null()) {
- return nullptr;
+ return memnew(CSGBrush);
}
if (curve->get_baked_length() <= 0) {
- return nullptr;
+ return memnew(CSGBrush);
}
}
CSGBrush *brush = memnew(CSGBrush);
@@ -1928,8 +1880,8 @@ CSGBrush *CSGPolygon3D::_build_brush() {
float inci = float(i) / spin_sides;
float inci_n = float((i + 1)) / spin_sides;
- float angi = -(inci * spin_degrees / 360.0) * Math_PI * 2.0;
- float angi_n = -(inci_n * spin_degrees / 360.0) * Math_PI * 2.0;
+ float angi = -Math::deg2rad(inci * spin_degrees);
+ float angi_n = -Math::deg2rad(inci_n * spin_degrees);
Vector3 normali = Vector3(Math::cos(angi), 0, Math::sin(angi));
Vector3 normali_n = Vector3(Math::cos(angi_n), 0, Math::sin(angi_n));
@@ -2306,7 +2258,7 @@ void CSGPolygon3D::set_mode(Mode p_mode) {
mode = p_mode;
_make_dirty();
update_gizmo();
- _change_notify();
+ notify_property_list_changed();
}
CSGPolygon3D::Mode CSGPolygon3D::get_mode() const {
diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h
index d93693f145..de7de09f00 100644
--- a/modules/csg/csg_shape.h
+++ b/modules/csg/csg_shape.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,23 +50,23 @@ public:
};
private:
- Operation operation;
- CSGShape3D *parent;
+ Operation operation = OPERATION_UNION;
+ CSGShape3D *parent = nullptr;
- CSGBrush *brush;
+ CSGBrush *brush = nullptr;
AABB node_aabb;
- bool dirty;
- float snap;
+ bool dirty = false;
+ float snap = 0.001;
- bool use_collision;
- uint32_t collision_layer;
- uint32_t collision_mask;
+ bool use_collision = false;
+ uint32_t collision_layer = 1;
+ uint32_t collision_mask = 1;
Ref<ConcavePolygonShape3D> root_collision_shape;
RID root_collision_instance;
- bool calculate_tangents;
+ bool calculate_tangents = true;
Ref<ArrayMesh> root_mesh;
@@ -85,12 +85,12 @@ private:
Vector<Vector2> uvs;
Vector<float> tans;
Ref<Material> material;
- int last_added;
+ int last_added = 0;
- Vector3 *verticesw;
- Vector3 *normalsw;
- Vector2 *uvsw;
- float *tansw;
+ Vector3 *verticesw = nullptr;
+ Vector3 *normalsw = nullptr;
+ Vector2 *uvsw = nullptr;
+ float *tansw = nullptr;
};
//mikktspace callbacks
@@ -240,27 +240,19 @@ class CSGBox3D : public CSGPrimitive3D {
virtual CSGBrush *_build_brush() override;
Ref<Material> material;
- float width;
- float height;
- float depth;
+ Vector3 size = Vector3(2, 2, 2);
protected:
static void _bind_methods();
public:
- void set_width(const float p_width);
- float get_width() const;
-
- void set_height(const float p_height);
- float get_height() const;
-
- void set_depth(const float p_depth);
- float get_depth() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
void set_material(const Ref<Material> &p_material);
Ref<Material> get_material() const;
- CSGBox3D();
+ CSGBox3D() {}
};
class CSGCylinder3D : public CSGPrimitive3D {
diff --git a/modules/csg/doc_classes/CSGBox3D.xml b/modules/csg/doc_classes/CSGBox3D.xml
index 492bf68c44..b1d0454b76 100644
--- a/modules/csg/doc_classes/CSGBox3D.xml
+++ b/modules/csg/doc_classes/CSGBox3D.xml
@@ -11,17 +11,11 @@
<methods>
</methods>
<members>
- <member name="depth" type="float" setter="set_depth" getter="get_depth" default="2.0">
- Depth of the box measured from the center of the box.
- </member>
- <member name="height" type="float" setter="set_height" getter="get_height" default="2.0">
- Height of the box measured from the center of the box.
- </member>
<member name="material" type="Material" setter="set_material" getter="get_material">
The material used to render the box.
</member>
- <member name="width" type="float" setter="set_width" getter="get_width" default="2.0">
- Width of the box measured from the center of the box.
+ <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3( 2, 2, 2 )">
+ The box's width, height and depth.
</member>
</members>
<constants>
diff --git a/modules/csg/register_types.cpp b/modules/csg/register_types.cpp
index a8bcc2fed1..e28f44d1eb 100644
--- a/modules/csg/register_types.cpp
+++ b/modules/csg/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/csg/register_types.h b/modules/csg/register_types.h
index 926e598561..8747b3fade 100644
--- a/modules/csg/register_types.h
+++ b/modules/csg/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp
index 5d97164dbf..3beca3d12a 100644
--- a/modules/cvtt/image_compress_cvtt.cpp
+++ b/modules/cvtt/image_compress_cvtt.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,30 +33,31 @@
#include "core/os/os.h"
#include "core/os/thread.h"
#include "core/string/print_string.h"
+#include "core/templates/safe_refcount.h"
#include <ConvectionKernels.h>
struct CVTTCompressionJobParams {
- bool is_hdr;
- bool is_signed;
- int bytes_per_pixel;
+ bool is_hdr = false;
+ bool is_signed = false;
+ int bytes_per_pixel = 0;
cvtt::Options options;
};
struct CVTTCompressionRowTask {
const uint8_t *in_mm_bytes;
- uint8_t *out_mm_bytes;
- int y_start;
- int width;
- int height;
+ uint8_t *out_mm_bytes = nullptr;
+ int y_start = 0;
+ int width = 0;
+ int height = 0;
};
struct CVTTCompressionJobQueue {
CVTTCompressionJobParams job_params;
const CVTTCompressionRowTask *job_tasks;
- uint32_t num_tasks;
- uint32_t current_task;
+ uint32_t num_tasks = 0;
+ SafeNumeric<uint32_t> current_task;
};
static void _digest_row_task(const CVTTCompressionJobParams &p_job_params, const CVTTCompressionRowTask &p_row_task) {
@@ -131,7 +132,7 @@ static void _digest_row_task(const CVTTCompressionJobParams &p_job_params, const
static void _digest_job_queue(void *p_job_queue) {
CVTTCompressionJobQueue *job_queue = static_cast<CVTTCompressionJobQueue *>(p_job_queue);
- for (uint32_t next_task = atomic_increment(&job_queue->current_task); next_task <= job_queue->num_tasks; next_task = atomic_increment(&job_queue->current_task)) {
+ for (uint32_t next_task = job_queue->current_task.increment(); next_task <= job_queue->num_tasks; next_task = job_queue->current_task.increment()) {
_digest_row_task(job_queue->job_params, job_queue->job_tasks[next_task - 1]);
}
}
@@ -168,9 +169,10 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann
flags |= cvtt::Flags::BC7_RespectPunchThrough;
- if (p_channels == Image::USED_CHANNELS_RG) { //guessing this is a normalmap
+ if (p_channels == Image::USED_CHANNELS_RG) { //guessing this is a normal map
flags |= cvtt::Flags::Uniform;
}
+ options.flags = flags;
Image::Format target_format = Image::FORMAT_BPTC_RGBA;
@@ -262,16 +264,17 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann
const CVTTCompressionRowTask *tasks_rb = tasks.ptr();
job_queue.job_tasks = &tasks_rb[0];
- job_queue.current_task = 0;
+ job_queue.current_task.set(0);
job_queue.num_tasks = static_cast<uint32_t>(tasks.size());
for (int i = 0; i < num_job_threads; i++) {
- threads_wb[i] = Thread::create(_digest_job_queue, &job_queue);
+ threads_wb[i] = memnew(Thread);
+ threads_wb[i]->start(_digest_job_queue, &job_queue);
}
_digest_job_queue(&job_queue);
for (int i = 0; i < num_job_threads; i++) {
- Thread::wait_to_finish(threads_wb[i]);
+ threads_wb[i]->wait_to_finish();
memdelete(threads_wb[i]);
}
}
diff --git a/modules/cvtt/image_compress_cvtt.h b/modules/cvtt/image_compress_cvtt.h
index 483fb876a6..bef5653fa9 100644
--- a/modules/cvtt/image_compress_cvtt.h
+++ b/modules/cvtt/image_compress_cvtt.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/cvtt/register_types.cpp b/modules/cvtt/register_types.cpp
index e4a01cc787..055b5dc6e3 100644
--- a/modules/cvtt/register_types.cpp
+++ b/modules/cvtt/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/cvtt/register_types.h b/modules/cvtt/register_types.h
index 36b5e332d6..e62e8c0e9a 100644
--- a/modules/cvtt/register_types.h
+++ b/modules/cvtt/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/dds/register_types.cpp b/modules/dds/register_types.cpp
index 3991964a28..1444d33171 100644
--- a/modules/dds/register_types.cpp
+++ b/modules/dds/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/dds/register_types.h b/modules/dds/register_types.h
index 3cb7b5c2a6..b84bcd06c8 100644
--- a/modules/dds/register_types.h
+++ b/modules/dds/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index 627153fbc8..2fef576b77 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -69,11 +69,11 @@ enum DDSFormat {
struct DDSFormatInfo {
const char *name;
- bool compressed;
- bool palette;
- uint32_t divisor;
- uint32_t block_size;
- Image::Format format;
+ bool compressed = false;
+ bool palette = false;
+ uint32_t divisor = 0;
+ uint32_t block_size = 0;
+ Image::Format format = Image::Format::FORMAT_BPTC_RGBA;
};
static const DDSFormatInfo dds_format_info[DDS_MAX] = {
@@ -94,7 +94,7 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = {
{ "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 }
};
-RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h
index ef08967df7..cf93156423 100644
--- a/modules/dds/texture_loader_dds.h
+++ b/modules/dds/texture_loader_dds.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class ResourceFormatDDS : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/denoise/denoise_wrapper.cpp b/modules/denoise/denoise_wrapper.cpp
index c12c6d9c31..e71fce5958 100644
--- a/modules/denoise/denoise_wrapper.cpp
+++ b/modules/denoise/denoise_wrapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/denoise/denoise_wrapper.h b/modules/denoise/denoise_wrapper.h
index 2107df09c1..25e342bc93 100644
--- a/modules/denoise/denoise_wrapper.h
+++ b/modules/denoise/denoise_wrapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/denoise/lightmap_denoiser.cpp b/modules/denoise/lightmap_denoiser.cpp
index 29d02e8ee2..003bc832b0 100644
--- a/modules/denoise/lightmap_denoiser.cpp
+++ b/modules/denoise/lightmap_denoiser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/denoise/lightmap_denoiser.h b/modules/denoise/lightmap_denoiser.h
index f4e4335d9b..f1992a1733 100644
--- a/modules/denoise/lightmap_denoiser.h
+++ b/modules/denoise/lightmap_denoiser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/denoise/register_types.cpp b/modules/denoise/register_types.cpp
index 552495ed87..936e5f604d 100644
--- a/modules/denoise/register_types.cpp
+++ b/modules/denoise/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/denoise/register_types.h b/modules/denoise/register_types.h
index f0f1f44bfe..516a91b134 100644
--- a/modules/denoise/register_types.h
+++ b/modules/denoise/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
index f46ef2d812..c8f32ffde6 100644
--- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
+++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
@@ -5,6 +5,8 @@
</brief_description>
<description>
A PacketPeer implementation that should be passed to [member SceneTree.network_peer] after being initialized as either a client or server. Events can then be handled by connecting to [SceneTree] signals.
+ ENet's purpose is to provide a relatively thin, simple and robust network communication layer on top of UDP (User Datagram Protocol).
+ [b]Note:[/b] ENet only uses UDP, not TCP. When forwarding the server port to make your server accessible on the public Internet, you only need to forward the server port in UDP. You can use the [UPNP] class to try to forward the server port automatically when starting the server.
</description>
<tutorials>
<link title="High-level multiplayer">https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html</link>
@@ -122,6 +124,22 @@
Configure the [CryptoKey] to use when [member use_dtls] is [code]true[/code]. Remember to also call [method set_dtls_certificate] to setup your [X509Certificate].
</description>
</method>
+ <method name="set_peer_timeout">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="timeout_limit" type="int">
+ </argument>
+ <argument index="2" name="timeout_min" type="int">
+ </argument>
+ <argument index="3" name="timeout_max" type="int">
+ </argument>
+ <description>
+ Sets the timeout parameters for a peer. The timeout parameters control how and when a peer will timeout from a failure to acknowledge reliable traffic. Timeout values are expressed in milliseconds.
+ The [code]timeout_limit[/code] is a factor that, multiplied by a value based on the avarage round trip time, will determine the timeout limit for a reliable packet. When that limit is reached, the timeout will be doubled, and the peer will be disconnected if that limit has reached [code]timeout_min[/code]. The [code]timeout_max[/code] parameter, on the other hand, defines a fixed timeout for which any packet must be acknowledged or the peer will be dropped.
+ </description>
+ </method>
</methods>
<members>
<member name="always_ordered" type="bool" setter="set_always_ordered" getter="is_always_ordered" default="false">
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index 64977ad237..276f13e553 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -784,6 +784,14 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
#endif
}
+void NetworkedMultiplayerENet::set_peer_timeout(int p_peer_id, int p_timeout_limit, int p_timeout_min, int p_timeout_max) {
+ ERR_FAIL_COND_MSG(!peer_map.has(p_peer_id), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
+ ERR_FAIL_COND_MSG(!is_server() && p_peer_id != 1, "Can't change the timeout of peers other then the server when acting as a client.");
+ ERR_FAIL_COND_MSG(peer_map[p_peer_id] == nullptr, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
+ ERR_FAIL_COND_MSG(p_timeout_limit > p_timeout_min || p_timeout_min > p_timeout_max, "Timeout limit must be less than minimum timeout, which itself must be less then maximum timeout");
+ enet_peer_timeout(peer_map[p_peer_id], p_timeout_limit, p_timeout_min, p_timeout_max);
+}
+
void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
ERR_FAIL_COND_MSG(p_channel < -1 || p_channel >= channel_count, vformat("The transfer channel must be set between 0 and %d, inclusive (got %d).", channel_count - 1, p_channel));
ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, vformat("The channel %d is reserved.", SYSCH_CONFIG));
@@ -838,6 +846,7 @@ void NetworkedMultiplayerENet::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_dtls_verify_enabled"), &NetworkedMultiplayerENet::is_dtls_verify_enabled);
ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &NetworkedMultiplayerENet::get_peer_address);
ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &NetworkedMultiplayerENet::get_peer_port);
+ ClassDB::bind_method(D_METHOD("set_peer_timeout", "id", "timeout_limit", "timeout_min", "timeout_max"), &NetworkedMultiplayerENet::set_peer_timeout);
ClassDB::bind_method(D_METHOD("get_packet_channel"), &NetworkedMultiplayerENet::get_packet_channel);
ClassDB::bind_method(D_METHOD("get_last_packet_channel"), &NetworkedMultiplayerENet::get_last_packet_channel);
@@ -866,28 +875,12 @@ void NetworkedMultiplayerENet::_bind_methods() {
}
NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
- active = false;
- server = false;
- refuse_connections = false;
- server_relay = true;
- unique_id = 0;
- target_peer = 0;
- current_packet.packet = nullptr;
- transfer_mode = TRANSFER_MODE_RELIABLE;
- channel_count = SYSCH_MAX;
- transfer_channel = -1;
- always_ordered = false;
- connection_status = CONNECTION_DISCONNECTED;
- compression_mode = COMPRESS_NONE;
enet_compressor.context = this;
enet_compressor.compress = enet_compress;
enet_compressor.decompress = enet_decompress;
enet_compressor.destroy = enet_compressor_destroy;
bind_ip = IP_Address("*");
-
- dtls_enabled = false;
- dtls_verify = true;
}
NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h
index 722c7001fd..b99b14d218 100644
--- a/modules/enet/networked_multiplayer_enet.h
+++ b/modules/enet/networked_multiplayer_enet.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -62,35 +62,35 @@ private:
SYSCH_MAX
};
- bool active;
- bool server;
+ bool active = false;
+ bool server = false;
- uint32_t unique_id;
+ uint32_t unique_id = 0;
- int target_peer;
- TransferMode transfer_mode;
- int transfer_channel;
- int channel_count;
- bool always_ordered;
+ int target_peer = 0;
+ TransferMode transfer_mode = TRANSFER_MODE_RELIABLE;
+ int transfer_channel = -1;
+ int channel_count = SYSCH_MAX;
+ bool always_ordered = false;
ENetEvent event;
- ENetPeer *peer;
- ENetHost *host;
+ ENetPeer *peer = nullptr;
+ ENetHost *host = nullptr;
- bool refuse_connections;
- bool server_relay;
+ bool refuse_connections = false;
+ bool server_relay = true;
- ConnectionStatus connection_status;
+ ConnectionStatus connection_status = CONNECTION_DISCONNECTED;
Map<int, ENetPeer *> peer_map;
struct Packet {
- ENetPacket *packet;
- int from;
- int channel;
+ ENetPacket *packet = nullptr;
+ int from = 0;
+ int channel = 0;
};
- CompressionMode compression_mode;
+ CompressionMode compression_mode = COMPRESS_NONE;
List<Packet> incoming_packets;
@@ -110,10 +110,10 @@ private:
IP_Address bind_ip;
- bool dtls_enabled;
+ bool dtls_enabled = false;
Ref<CryptoKey> dtls_key;
Ref<X509Certificate> dtls_cert;
- bool dtls_verify;
+ bool dtls_verify = true;
protected:
static void _bind_methods();
@@ -127,6 +127,7 @@ public:
virtual IP_Address get_peer_address(int p_peer_id) const;
virtual int get_peer_port(int p_peer_id) const;
+ void set_peer_timeout(int p_peer_id, int p_timeout_limit, int p_timeout_min, int p_timeout_max);
Error create_server(int p_port, int p_max_clients = 32, int p_in_bandwidth = 0, int p_out_bandwidth = 0);
Error create_client(const String &p_address, int p_port, int p_in_bandwidth = 0, int p_out_bandwidth = 0, int p_client_port = 0);
diff --git a/modules/enet/register_types.cpp b/modules/enet/register_types.cpp
index 2683f3155b..8da2d17e13 100644
--- a/modules/enet/register_types.cpp
+++ b/modules/enet/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/enet/register_types.h b/modules/enet/register_types.h
index cac0a4f7ee..75f4cba61b 100644
--- a/modules/enet/register_types.h
+++ b/modules/enet/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/etc/image_compress_etc.cpp b/modules/etc/image_compress_etc.cpp
index bcdea41b43..41cbbe3f54 100644
--- a/modules/etc/image_compress_etc.cpp
+++ b/modules/etc/image_compress_etc.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -166,12 +166,12 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
int encoding_time = 0;
float effort = 0.0; //default, reasonable time
- if (p_lossy_quality > 0.75) {
- effort = 0.4;
+ if (p_lossy_quality > 0.95) {
+ effort = 80;
} else if (p_lossy_quality > 0.85) {
- effort = 0.6;
- } else if (p_lossy_quality > 0.95) {
- effort = 0.8;
+ effort = 60;
+ } else if (p_lossy_quality > 0.75) {
+ effort = 40;
}
Etc::ErrorMetric error_metric = Etc::ErrorMetric::RGBX; // NOTE: we can experiment with other error metrics
diff --git a/modules/etc/image_compress_etc.h b/modules/etc/image_compress_etc.h
index 016e64e4fc..44a06194e9 100644
--- a/modules/etc/image_compress_etc.h
+++ b/modules/etc/image_compress_etc.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/etc/register_types.cpp b/modules/etc/register_types.cpp
index 225ba6b954..b165bccb3e 100644
--- a/modules/etc/register_types.cpp
+++ b/modules/etc/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/etc/register_types.h b/modules/etc/register_types.h
index 247c7213af..e8cbb635ae 100644
--- a/modules/etc/register_types.h
+++ b/modules/etc/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp
index c40e9612a8..95db9315d5 100644
--- a/modules/etc/texture_loader_pkm.cpp
+++ b/modules/etc/texture_loader_pkm.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,14 +35,14 @@
struct ETC1Header {
char tag[6]; // "PKM 10"
- uint16_t format; // Format == number of mips (== zero)
- uint16_t texWidth; // Texture dimensions, multiple of 4 (big-endian)
- uint16_t texHeight;
- uint16_t origWidth; // Original dimensions (big-endian)
- uint16_t origHeight;
+ uint16_t format = 0; // Format == number of mips (== zero)
+ uint16_t texWidth = 0; // Texture dimensions, multiple of 4 (big-endian)
+ uint16_t texHeight = 0;
+ uint16_t origWidth = 0; // Original dimensions (big-endian)
+ uint16_t origHeight = 0;
};
-RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h
index 6507e0bdec..2ed5e75807 100644
--- a/modules/etc/texture_loader_pkm.h
+++ b/modules/etc/texture_loader_pkm.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class ResourceFormatPKM : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/fbx/data/fbx_anim_container.h b/modules/fbx/data/fbx_anim_container.h
index e45dd84d6a..8c25d65871 100644
--- a/modules/fbx/data/fbx_anim_container.h
+++ b/modules/fbx/data/fbx_anim_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/data/fbx_bone.cpp b/modules/fbx/data/fbx_bone.cpp
index 7ccb0b3717..38dada33af 100644
--- a/modules/fbx/data/fbx_bone.cpp
+++ b/modules/fbx/data/fbx_bone.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/data/fbx_bone.h b/modules/fbx/data/fbx_bone.h
index 5d797da24f..efba147b89 100644
--- a/modules/fbx/data/fbx_bone.h
+++ b/modules/fbx/data/fbx_bone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/data/fbx_material.cpp b/modules/fbx/data/fbx_material.cpp
index b00ac2083e..5995097b2f 100644
--- a/modules/fbx/data/fbx_material.cpp
+++ b/modules/fbx/data/fbx_material.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,7 +42,7 @@ void FBXMaterial::set_imported_material(FBXDocParser::Material *p_material) {
}
void FBXMaterial::add_search_string(String p_filename, String p_current_directory, String search_directory, Vector<String> &texture_search_paths) {
- if (search_directory.empty()) {
+ if (search_directory.is_empty()) {
texture_search_paths.push_back(p_current_directory.get_base_dir().plus_file(p_filename));
} else {
texture_search_paths.push_back(p_current_directory.get_base_dir().plus_file(search_directory + "/" + p_filename));
@@ -188,7 +188,7 @@ Ref<StandardMaterial3D> FBXMaterial::import_material(ImportState &state) {
spatial_material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA);
}
- ERR_CONTINUE_MSG(file_extension.empty(), "your texture has no file extension so we had to ignore it, let us know if you think this is wrong file an issue on github! " + debug_string);
+ ERR_CONTINUE_MSG(file_extension.is_empty(), "your texture has no file extension so we had to ignore it, let us know if you think this is wrong file an issue on github! " + debug_string);
ERR_CONTINUE_MSG(fbx_texture_map.count(fbx_mapping_name) <= 0, "This material has a texture with mapping name: " + String(fbx_mapping_name.c_str()) + " which is not yet supported by this importer. Consider opening an issue so we can support it.");
ERR_CONTINUE_MSG(
file_extension_uppercase != "PNG" &&
@@ -211,7 +211,7 @@ Ref<StandardMaterial3D> FBXMaterial::import_material(ImportState &state) {
texture = state.cached_image_searches[texture_name];
} else {
String path = find_texture_path_by_filename(texture_name, p_fbx_current_directory);
- if (!path.empty()) {
+ if (!path.is_empty()) {
Ref<Texture2D> image_texture = ResourceLoader::load(path);
ERR_CONTINUE(image_texture.is_null());
diff --git a/modules/fbx/data/fbx_material.h b/modules/fbx/data/fbx_material.h
index 08b93ac01b..23310b8e1d 100644
--- a/modules/fbx/data/fbx_material.h
+++ b/modules/fbx/data/fbx_material.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -217,9 +217,6 @@ struct FBXMaterial : public Reference {
{ "TransparencyFactor", PROPERTY_DESC_TRANSPARENT },
{ "Maya|opacity", PROPERTY_DESC_TRANSPARENT },
- /* Metallic */
- { "Shininess", PROPERTY_DESC_METALLIC },
- { "Reflectivity", PROPERTY_DESC_METALLIC },
{ "Maya|metalness", PROPERTY_DESC_METALLIC },
{ "Maya|metallic", PROPERTY_DESC_METALLIC },
@@ -241,6 +238,8 @@ struct FBXMaterial : public Reference {
{ "Maya|emissionColor", PROPERTY_DESC_EMISSIVE_COLOR },
/* Ignore */
+ { "Shininess", PROPERTY_DESC_IGNORE },
+ { "Reflectivity", PROPERTY_DESC_IGNORE },
{ "Maya|diffuseRoughness", PROPERTY_DESC_IGNORE },
{ "Maya", PROPERTY_DESC_IGNORE },
{ "Diffuse", PROPERTY_DESC_ALBEDO_COLOR },
diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp
index 0728866adb..883651943e 100644
--- a/modules/fbx/data/fbx_mesh_data.cpp
+++ b/modules/fbx/data/fbx_mesh_data.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,11 +34,11 @@
#include "scene/resources/mesh.h"
#include "scene/resources/surface_tool.h"
-#include "thirdparty/misc/triangulator.h"
+#include "thirdparty/misc/polypartition.h"
template <class T>
T collect_first(const Vector<VertexData<T>> *p_data, T p_fall_back) {
- if (p_data->empty()) {
+ if (p_data->is_empty()) {
return p_fall_back;
}
@@ -47,7 +47,7 @@ T collect_first(const Vector<VertexData<T>> *p_data, T p_fall_back) {
template <class T>
HashMap<int, T> collect_all(const Vector<VertexData<T>> *p_data, HashMap<int, T> p_fall_back) {
- if (p_data->empty()) {
+ if (p_data->is_empty()) {
return p_fall_back;
}
@@ -61,7 +61,7 @@ HashMap<int, T> collect_all(const Vector<VertexData<T>> *p_data, HashMap<int, T>
template <class T>
T collect_average(const Vector<VertexData<T>> *p_data, T p_fall_back) {
- if (p_data->empty()) {
+ if (p_data->is_empty()) {
return p_fall_back;
}
@@ -76,7 +76,7 @@ T collect_average(const Vector<VertexData<T>> *p_data, T p_fall_back) {
}
HashMap<int, Vector3> collect_normal(const Vector<VertexData<Vector3>> *p_data, HashMap<int, Vector3> p_fall_back) {
- if (p_data->empty()) {
+ if (p_data->is_empty()) {
return p_fall_back;
}
@@ -89,7 +89,7 @@ HashMap<int, Vector3> collect_normal(const Vector<VertexData<Vector3>> *p_data,
}
HashMap<int, Vector2> collect_uv(const Vector<VertexData<Vector2>> *p_data, HashMap<int, Vector2> p_fall_back) {
- if (p_data->empty()) {
+ if (p_data->is_empty()) {
return p_fall_back;
}
@@ -135,26 +135,6 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s
&collect_all,
HashMap<int, Vector3>());
- // List<int> keys;
- // normals.get_key_list(&keys);
- //
- // const std::vector<Assimp::FBX::MeshGeometry::Edge>& edges = mesh_geometry->get_edge_map();
- // for (int index = 0; index < keys.size(); index++) {
- // const int key = keys[index];
- // const int v1 = edges[key].vertex_0;
- // const int v2 = edges[key].vertex_1;
- // const Vector3& n1 = normals.get(v1);
- // const Vector3& n2 = normals.get(v2);
- // print_verbose("[" + itos(v1) + "] n1: " + n1 + "\n[" + itos(v2) + "] n2: " + n2);
- // //print_verbose("[" + itos(key) + "] n1: " + n1 + ", n2: " + n2) ;
- // //print_verbose("vindex: " + itos(edges[key].vertex_0) + ", vindex2: " + itos(edges[key].vertex_1));
- // //Vector3 ver1 = vertices[edges[key].vertex_0];
- // //Vector3 ver2 = vertices[edges[key].vertex_1];
- // /*real_t angle1 = Math::rad2deg(n1.angle_to(n2));
- // real_t angle2 = Math::rad2deg(n2.angle_to(n1));
- // print_verbose("angle of normals: " + rtos(angle1) + " angle 2" + rtos(angle2));*/
- // }
-
HashMap<int, Vector2> uvs_0;
HashMap<int, HashMap<int, Vector2>> uvs_0_raw = extract_per_vertex_data(
vertices.size(),
@@ -231,7 +211,7 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s
// Phase 2. For each material create a surface tool (So a different mesh).
{
- if (polygon_surfaces.empty()) {
+ if (polygon_surfaces.is_empty()) {
// No material, just use the default one with index -1.
// Set -1 to all polygons.
const int polygon_count = count_polygons(polygon_indices);
@@ -371,6 +351,9 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s
normals_ptr[vertex]);
}
+ if (state.is_blender_fbx) {
+ morph_st->generate_normals();
+ }
morph_st->generate_tangents();
surface->morphs.push_back(morph_st->commit_to_arrays());
}
@@ -393,6 +376,9 @@ EditorSceneImporterMeshNode3D *FBXMeshData::create_fbx_mesh(const ImportState &s
for (const SurfaceId *surface_id = surfaces.next(nullptr); surface_id != nullptr; surface_id = surfaces.next(surface_id)) {
SurfaceData *surface = surfaces.getptr(*surface_id);
+ if (state.is_blender_fbx) {
+ surface->surface_tool->generate_normals();
+ }
// you can't generate them without a valid uv map.
if (uvs_0_raw.size() > 0) {
surface->surface_tool->generate_tangents();
@@ -785,7 +771,7 @@ void FBXMeshData::add_vertex(
const Vector3 &p_morph_normal) {
ERR_FAIL_INDEX_MSG(p_vertex, (Vertex)p_vertices_position.size(), "FBX file is corrupted, the position of the vertex can't be retrieved.");
- if (p_normals.has(p_vertex)) {
+ if (p_normals.has(p_vertex) && !state.is_blender_fbx) {
p_surface_tool->set_normal(p_normals[p_vertex] + p_morph_normal);
}
@@ -944,30 +930,30 @@ void FBXMeshData::triangulate_polygon(Ref<SurfaceTool> st, Vector<int> p_polygon
}
}
- TriangulatorPoly triangulator_poly;
- triangulator_poly.Init(polygon_vertex_count);
+ TPPLPoly tppl_poly;
+ tppl_poly.Init(polygon_vertex_count);
std::vector<Vector2> projected_vertices(polygon_vertex_count);
for (int i = 0; i < polygon_vertex_count; i += 1) {
const Vector2 pv(poly_vertices[i][axis_1_coord], poly_vertices[i][axis_2_coord]);
projected_vertices[i] = pv;
- triangulator_poly.GetPoint(i) = pv;
+ tppl_poly.GetPoint(i) = pv;
}
- triangulator_poly.SetOrientation(TRIANGULATOR_CCW);
+ tppl_poly.SetOrientation(TPPL_ORIENTATION_CCW);
- List<TriangulatorPoly> out_poly;
+ List<TPPLPoly> out_poly;
- TriangulatorPartition triangulator_partition;
- if (triangulator_partition.Triangulate_OPT(&triangulator_poly, &out_poly) == 0) { // Good result.
- if (triangulator_partition.Triangulate_EC(&triangulator_poly, &out_poly) == 0) { // Medium result.
- if (triangulator_partition.Triangulate_MONO(&triangulator_poly, &out_poly) == 0) { // Really poor result.
+ TPPLPartition tppl_partition;
+ if (tppl_partition.Triangulate_OPT(&tppl_poly, &out_poly) == 0) { // Good result.
+ if (tppl_partition.Triangulate_EC(&tppl_poly, &out_poly) == 0) { // Medium result.
+ if (tppl_partition.Triangulate_MONO(&tppl_poly, &out_poly) == 0) { // Really poor result.
ERR_FAIL_MSG("The triangulation of this polygon failed, please try to triangulate your mesh or check if it has broken polygons.");
}
}
}
std::vector<Vector2> tris(out_poly.size());
- for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
- TriangulatorPoly &tp = I->get();
+ for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
+ TPPLPoly &tp = I->get();
ERR_FAIL_COND_MSG(tp.GetNumPoints() != 3, "The triangulator retuned more points, how this is possible?");
// Find Index
@@ -990,7 +976,7 @@ void FBXMeshData::triangulate_polygon(Ref<SurfaceTool> st, Vector<int> p_polygon
}
void FBXMeshData::gen_weight_info(Ref<SurfaceTool> st, Vertex vertex_id) const {
- if (vertex_weights.empty()) {
+ if (vertex_weights.is_empty()) {
return;
}
@@ -1417,7 +1403,7 @@ void FBXMeshData::extract_morphs(const FBXDocParser::MeshGeometry *mesh_geometry
const std::vector<const FBXDocParser::ShapeGeometry *> &shape_geometries = blend_shape_channel->GetShapeGeometries();
for (const FBXDocParser::ShapeGeometry *shape_geometry : shape_geometries) {
String morph_name = ImportUtils::FBXAnimMeshName(shape_geometry->Name()).c_str();
- if (morph_name.empty()) {
+ if (morph_name.is_empty()) {
morph_name = "morph";
}
diff --git a/modules/fbx/data/fbx_mesh_data.h b/modules/fbx/data/fbx_mesh_data.h
index b6e87bb9e2..77510ff2ec 100644
--- a/modules/fbx/data/fbx_mesh_data.h
+++ b/modules/fbx/data/fbx_mesh_data.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/data/fbx_node.h b/modules/fbx/data/fbx_node.h
index d8efcaa982..a6f62f3388 100644
--- a/modules/fbx/data/fbx_node.h
+++ b/modules/fbx/data/fbx_node.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/data/fbx_skeleton.cpp b/modules/fbx/data/fbx_skeleton.cpp
index 93aeffc132..622b589feb 100644
--- a/modules/fbx/data/fbx_skeleton.cpp
+++ b/modules/fbx/data/fbx_skeleton.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/data/fbx_skeleton.h b/modules/fbx/data/fbx_skeleton.h
index a2e330114c..df937cde49 100644
--- a/modules/fbx/data/fbx_skeleton.h
+++ b/modules/fbx/data/fbx_skeleton.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/data/import_state.h b/modules/fbx/data/import_state.h
index 34021ca7b1..83bc43faff 100644
--- a/modules/fbx/data/import_state.h
+++ b/modules/fbx/data/import_state.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,6 +64,7 @@ struct FBXSkeleton;
struct ImportState {
bool enable_material_import = true;
bool enable_animation_import = true;
+ bool is_blender_fbx = false;
Map<StringName, Ref<Texture>> cached_image_searches;
Map<uint64_t, Ref<Material>> cached_materials;
diff --git a/modules/fbx/data/model_abstraction.h b/modules/fbx/data/model_abstraction.h
index b21ab0badb..528960ab49 100644
--- a/modules/fbx/data/model_abstraction.h
+++ b/modules/fbx/data/model_abstraction.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/data/pivot_transform.cpp b/modules/fbx/data/pivot_transform.cpp
index c12e94097f..1895af6f9f 100644
--- a/modules/fbx/data/pivot_transform.cpp
+++ b/modules/fbx/data/pivot_transform.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -76,12 +76,14 @@ void PivotTransform::ReadTransformChain() {
const Vector3 &Scaling = ImportUtils::safe_import_vector3(FBXDocParser::PropertyGet<Vector3>(props, "Lcl Scaling", ok));
if (ok) {
scaling = Scaling;
+ } else {
+ scaling = Vector3(1, 1, 1);
}
const Vector3 &GeometricScaling = ImportUtils::safe_import_vector3(FBXDocParser::PropertyGet<Vector3>(props, "GeometricScaling", ok));
if (ok) {
geometric_scaling = GeometricScaling;
} else {
- geometric_scaling = Vector3(0, 0, 0);
+ geometric_scaling = Vector3(1, 1, 1);
}
const Vector3 &GeometricRotation = ImportUtils::safe_import_vector3(FBXDocParser::PropertyGet<Vector3>(props, "GeometricRotation", ok));
@@ -207,6 +209,8 @@ Transform PivotTransform::ComputeGlobalTransform(Vector3 p_translation, Quat p_r
Transform local_transform = T * Roff * Rp * Rpre * R * Rpost.affine_inverse() * Rp.affine_inverse() * Soff * Sp * S * Sp.affine_inverse();
//Transform local_translation_pivoted = Transform(Basis(), LocalTransform.origin);
+ ERR_FAIL_COND_V_MSG(local_transform.basis.determinant() == 0, Transform(), "Det == 0 prevented in scene file");
+
// manual hack to force SSC not to be compensated for - until we can handle it properly with tests
return parent_global_xform * local_transform;
}
@@ -290,5 +294,14 @@ void PivotTransform::Execute() {
ComputePivotTransform();
ImportUtils::debug_xform("global xform: ", GlobalTransform);
+
+ if (LocalTransform.basis.determinant() == 0) {
+ print_error("Serious det == 0!");
+ }
+
+ if (GlobalTransform.basis.determinant() == 0) {
+ print_error("Serious! node has det == 0!");
+ }
+
computed_global_xform = true;
}
diff --git a/modules/fbx/data/pivot_transform.h b/modules/fbx/data/pivot_transform.h
index 025c8dd58d..9996027870 100644
--- a/modules/fbx/data/pivot_transform.h
+++ b/modules/fbx/data/pivot_transform.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/doc_classes/EditorSceneImporterFBX.xml b/modules/fbx/doc_classes/EditorSceneImporterFBX.xml
index 72b6e0f5fd..da1a68c27c 100644
--- a/modules/fbx/doc_classes/EditorSceneImporterFBX.xml
+++ b/modules/fbx/doc_classes/EditorSceneImporterFBX.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="EditorSceneImporterFBX" inherits="EditorSceneImporter" version="3.2">
+<class name="EditorSceneImporterFBX" inherits="EditorSceneImporter" version="4.0">
<brief_description>
FBX 3D asset importer.
</brief_description>
diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp
index d37befbbfd..6576147b2b 100644
--- a/modules/fbx/editor_scene_importer_fbx.cpp
+++ b/modules/fbx/editor_scene_importer_fbx.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,8 +63,7 @@ void EditorSceneImporterFBX::get_extensions(List<String> *r_extensions) const {
const String fbx_str = "fbx";
Vector<String> exts;
exts.push_back(fbx_str);
- _register_project_setting_import(fbx_str, import_setting_string, exts, r_extensions,
- true);
+ _register_project_setting_import(fbx_str, import_setting_string, exts, r_extensions, true);
}
void EditorSceneImporterFBX::_register_project_setting_import(const String generic,
@@ -181,10 +180,12 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl
}
if (is_blender_fbx) {
- WARN_PRINT("Blender FBX files will not work properly with keyframes or skeletons until we make fixes stand by.");
+ WARN_PRINT("We don't officially support Blender FBX animations yet, due to issues with upstream Blender,\n"
+ "so please wait for us to work around remaining issues. We will continue to import the file but it may be broken.\n"
+ "For minimal breakage, please export FBX from Blender with -Z forward, and Y up.");
}
- Node3D *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8);
+ Node3D *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8, is_blender_fbx);
// todo: move to document shutdown (will need to be validated after moving; this code has been validated already)
for (FBXDocParser::TokenPtr token : tokens) {
if (token) {
@@ -196,7 +197,7 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl
return spatial;
} else {
- print_error("Cannot import file: " + p_path + " version of file is unsupported, please re-export in your modelling package file version is: " + itos(doc.FBXVersion()));
+ ERR_PRINT(vformat("Cannot import FBX file: %s. It uses file format %d which is unsupported by Godot. Please re-export it or convert it to a newer format.", p_path, doc.FBXVersion()));
}
}
@@ -328,8 +329,10 @@ Node3D *EditorSceneImporterFBX::_generate_scene(
const FBXDocParser::Document *p_document,
const uint32_t p_flags,
int p_bake_fps,
- const int32_t p_max_bone_weights) {
+ const int32_t p_max_bone_weights,
+ bool p_is_blender_fbx) {
ImportState state;
+ state.is_blender_fbx = p_is_blender_fbx;
state.path = p_path;
state.animation_player = NULL;
@@ -550,8 +553,8 @@ Node3D *EditorSceneImporterFBX::_generate_scene(
print_verbose("populating skeleton with bone: " + bone->bone_name);
- // // populate bone skeleton - since fbx has no DOM for the skeleton just a node.
- // bone->bone_skeleton = fbx_skeleton_inst;
+ //// populate bone skeleton - since fbx has no DOM for the skeleton just a node.
+ //bone->bone_skeleton = fbx_skeleton_inst;
// now populate bone on the armature node list
fbx_skeleton_inst->skeleton_bones.push_back(bone);
@@ -688,8 +691,8 @@ Node3D *EditorSceneImporterFBX::_generate_scene(
//
// Get Mesh Node Xform only
//
- // ERR_CONTINUE_MSG(!state.fbx_target_map.has(mesh_id), "invalid xform for the skin pose: " + itos(mesh_id));
- // Ref<FBXNode> mesh_node_xform_data = state.fbx_target_map[mesh_id];
+ //ERR_CONTINUE_MSG(!state.fbx_target_map.has(mesh_id), "invalid xform for the skin pose: " + itos(mesh_id));
+ //Ref<FBXNode> mesh_node_xform_data = state.fbx_target_map[mesh_id];
if (!mesh_skin) {
continue; // not a deformer.
diff --git a/modules/fbx/editor_scene_importer_fbx.h b/modules/fbx/editor_scene_importer_fbx.h
index ff1d243ede..39f8648b0f 100644
--- a/modules/fbx/editor_scene_importer_fbx.h
+++ b/modules/fbx/editor_scene_importer_fbx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -114,7 +114,9 @@ private:
Node3D *_generate_scene(const String &p_path, const FBXDocParser::Document *p_document,
const uint32_t p_flags,
- int p_bake_fps, const int32_t p_max_bone_weights);
+ int p_bake_fps,
+ const int32_t p_max_bone_weights,
+ bool p_is_blender_fbx);
template <class T>
T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp);
diff --git a/modules/fbx/fbx_parser/ByteSwapper.h b/modules/fbx/fbx_parser/ByteSwapper.h
index 0a46a7df26..f759c9117c 100644
--- a/modules/fbx/fbx_parser/ByteSwapper.h
+++ b/modules/fbx/fbx_parser/ByteSwapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXAnimation.cpp b/modules/fbx/fbx_parser/FBXAnimation.cpp
index bfd3e97314..b11e2c7f55 100644
--- a/modules/fbx/fbx_parser/FBXAnimation.cpp
+++ b/modules/fbx/fbx_parser/FBXAnimation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp b/modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp
index 0fc66b13cd..1d2b7765c5 100644
--- a/modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp
+++ b/modules/fbx/fbx_parser/FBXBinaryTokenizer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXCommon.h b/modules/fbx/fbx_parser/FBXCommon.h
index 98a3d78f0d..641d6d351e 100644
--- a/modules/fbx/fbx_parser/FBXCommon.h
+++ b/modules/fbx/fbx_parser/FBXCommon.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXDeformer.cpp b/modules/fbx/fbx_parser/FBXDeformer.cpp
index 325641bc32..4b774e6b2a 100644
--- a/modules/fbx/fbx_parser/FBXDeformer.cpp
+++ b/modules/fbx/fbx_parser/FBXDeformer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXDocument.cpp b/modules/fbx/fbx_parser/FBXDocument.cpp
index 74798a655a..bcf7fa1565 100644
--- a/modules/fbx/fbx_parser/FBXDocument.cpp
+++ b/modules/fbx/fbx_parser/FBXDocument.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXDocument.h b/modules/fbx/fbx_parser/FBXDocument.h
index 7c08f3de65..b810197d7e 100644
--- a/modules/fbx/fbx_parser/FBXDocument.h
+++ b/modules/fbx/fbx_parser/FBXDocument.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXDocumentUtil.cpp b/modules/fbx/fbx_parser/FBXDocumentUtil.cpp
index 70b2b3bbe9..835b66ab23 100644
--- a/modules/fbx/fbx_parser/FBXDocumentUtil.cpp
+++ b/modules/fbx/fbx_parser/FBXDocumentUtil.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXDocumentUtil.h b/modules/fbx/fbx_parser/FBXDocumentUtil.h
index fb6eb04aea..daa9de4a33 100644
--- a/modules/fbx/fbx_parser/FBXDocumentUtil.h
+++ b/modules/fbx/fbx_parser/FBXDocumentUtil.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXImportSettings.h b/modules/fbx/fbx_parser/FBXImportSettings.h
index 4abca6b990..97ce496eaf 100644
--- a/modules/fbx/fbx_parser/FBXImportSettings.h
+++ b/modules/fbx/fbx_parser/FBXImportSettings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXMaterial.cpp b/modules/fbx/fbx_parser/FBXMaterial.cpp
index 5d25809d7b..9970a2b0b1 100644
--- a/modules/fbx/fbx_parser/FBXMaterial.cpp
+++ b/modules/fbx/fbx_parser/FBXMaterial.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
index 4fa5fc0ac9..ccc06550fe 100644
--- a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
+++ b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXMeshGeometry.h b/modules/fbx/fbx_parser/FBXMeshGeometry.h
index 666da46edd..710e644c68 100644
--- a/modules/fbx/fbx_parser/FBXMeshGeometry.h
+++ b/modules/fbx/fbx_parser/FBXMeshGeometry.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXModel.cpp b/modules/fbx/fbx_parser/FBXModel.cpp
index 5867f59d6a..767994441f 100644
--- a/modules/fbx/fbx_parser/FBXModel.cpp
+++ b/modules/fbx/fbx_parser/FBXModel.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXNodeAttribute.cpp b/modules/fbx/fbx_parser/FBXNodeAttribute.cpp
index c5051bd147..2749fc9f4d 100644
--- a/modules/fbx/fbx_parser/FBXNodeAttribute.cpp
+++ b/modules/fbx/fbx_parser/FBXNodeAttribute.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXParseTools.h b/modules/fbx/fbx_parser/FBXParseTools.h
index edc52009b3..21472f5b7b 100644
--- a/modules/fbx/fbx_parser/FBXParseTools.h
+++ b/modules/fbx/fbx_parser/FBXParseTools.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXParser.cpp b/modules/fbx/fbx_parser/FBXParser.cpp
index 208358f55e..44c24ff926 100644
--- a/modules/fbx/fbx_parser/FBXParser.cpp
+++ b/modules/fbx/fbx_parser/FBXParser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXParser.h b/modules/fbx/fbx_parser/FBXParser.h
index 3cba81ff83..37d27d3dca 100644
--- a/modules/fbx/fbx_parser/FBXParser.h
+++ b/modules/fbx/fbx_parser/FBXParser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXPose.cpp b/modules/fbx/fbx_parser/FBXPose.cpp
index 1bee2fa2f0..6d80b85e38 100644
--- a/modules/fbx/fbx_parser/FBXPose.cpp
+++ b/modules/fbx/fbx_parser/FBXPose.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXProperties.cpp b/modules/fbx/fbx_parser/FBXProperties.cpp
index 2994a84dbd..8ab94e1ef4 100644
--- a/modules/fbx/fbx_parser/FBXProperties.cpp
+++ b/modules/fbx/fbx_parser/FBXProperties.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXProperties.h b/modules/fbx/fbx_parser/FBXProperties.h
index a007660c45..27cacfaf76 100644
--- a/modules/fbx/fbx_parser/FBXProperties.h
+++ b/modules/fbx/fbx_parser/FBXProperties.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXTokenizer.cpp b/modules/fbx/fbx_parser/FBXTokenizer.cpp
index 3748bfabf8..ea4568fe32 100644
--- a/modules/fbx/fbx_parser/FBXTokenizer.cpp
+++ b/modules/fbx/fbx_parser/FBXTokenizer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXTokenizer.h b/modules/fbx/fbx_parser/FBXTokenizer.h
index 1761869c69..1e7e5e6535 100644
--- a/modules/fbx/fbx_parser/FBXTokenizer.h
+++ b/modules/fbx/fbx_parser/FBXTokenizer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXUtil.cpp b/modules/fbx/fbx_parser/FBXUtil.cpp
index 508407ea51..80ea5fab4c 100644
--- a/modules/fbx/fbx_parser/FBXUtil.cpp
+++ b/modules/fbx/fbx_parser/FBXUtil.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/fbx_parser/FBXUtil.h b/modules/fbx/fbx_parser/FBXUtil.h
index 553d5fbc6b..efc131831b 100644
--- a/modules/fbx/fbx_parser/FBXUtil.h
+++ b/modules/fbx/fbx_parser/FBXUtil.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/register_types.cpp b/modules/fbx/register_types.cpp
index 28fa69282e..c0591dbc77 100644
--- a/modules/fbx/register_types.cpp
+++ b/modules/fbx/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/register_types.h b/modules/fbx/register_types.h
index 26328c4c15..e5741afd72 100644
--- a/modules/fbx/register_types.h
+++ b/modules/fbx/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/tools/import_utils.cpp b/modules/fbx/tools/import_utils.cpp
index 5c9e433ab8..c87dd1fd3a 100644
--- a/modules/fbx/tools/import_utils.cpp
+++ b/modules/fbx/tools/import_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/tools/import_utils.h b/modules/fbx/tools/import_utils.h
index 98a0cef908..6261138812 100644
--- a/modules/fbx/tools/import_utils.h
+++ b/modules/fbx/tools/import_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/tools/validation_tools.cpp b/modules/fbx/tools/validation_tools.cpp
index 0c4d7abe8d..9dbd8bf544 100644
--- a/modules/fbx/tools/validation_tools.cpp
+++ b/modules/fbx/tools/validation_tools.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/fbx/tools/validation_tools.h b/modules/fbx/tools/validation_tools.h
index 649842a1cb..ced100aed2 100644
--- a/modules/fbx/tools/validation_tools.h
+++ b/modules/fbx/tools/validation_tools.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/freetype/register_types.cpp b/modules/freetype/register_types.cpp
index 15fa193183..e4e6a4c146 100644
--- a/modules/freetype/register_types.cpp
+++ b/modules/freetype/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/freetype/register_types.h b/modules/freetype/register_types.h
index aa8088d2e8..7a4f64b54b 100644
--- a/modules/freetype/register_types.h
+++ b/modules/freetype/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/freetype/uwpdef.h b/modules/freetype/uwpdef.h
index 2f9b2f4a53..f829edea67 100644
--- a/modules/freetype/uwpdef.h
+++ b/modules/freetype/uwpdef.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gamecenter/SCsub b/modules/gamecenter/SCsub
deleted file mode 100644
index 72fbf7ab0e..0000000000
--- a/modules/gamecenter/SCsub
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-Import("env_modules")
-
-env_gamecenter = env_modules.Clone()
-
-# (iOS) Enable module support
-env_gamecenter.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
-
-# (iOS) Build as separate static library
-modules_sources = []
-env_gamecenter.add_source_files(modules_sources, "*.cpp")
-env_gamecenter.add_source_files(modules_sources, "*.mm")
-mod_lib = env_modules.add_library("#bin/libgodot_gamecenter_module" + env["LIBSUFFIX"], modules_sources)
diff --git a/modules/gamecenter/config.py b/modules/gamecenter/config.py
deleted file mode 100644
index e68603fc93..0000000000
--- a/modules/gamecenter/config.py
+++ /dev/null
@@ -1,6 +0,0 @@
-def can_build(env, platform):
- return platform == "iphone"
-
-
-def configure(env):
- pass
diff --git a/modules/gamecenter/game_center.mm b/modules/gamecenter/game_center.mm
deleted file mode 100644
index 114f639a32..0000000000
--- a/modules/gamecenter/game_center.mm
+++ /dev/null
@@ -1,380 +0,0 @@
-/*************************************************************************/
-/* game_center.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "game_center.h"
-#import "platform/iphone/app_delegate.h"
-
-#import "game_center_delegate.h"
-#import "platform/iphone/view_controller.h"
-#import <GameKit/GameKit.h>
-
-GameCenter *GameCenter::instance = NULL;
-GodotGameCenterDelegate *gameCenterDelegate = nil;
-
-void GameCenter::_bind_methods() {
- ClassDB::bind_method(D_METHOD("authenticate"), &GameCenter::authenticate);
- ClassDB::bind_method(D_METHOD("is_authenticated"), &GameCenter::is_authenticated);
-
- ClassDB::bind_method(D_METHOD("post_score"), &GameCenter::post_score);
- ClassDB::bind_method(D_METHOD("award_achievement", "achievement"), &GameCenter::award_achievement);
- ClassDB::bind_method(D_METHOD("reset_achievements"), &GameCenter::reset_achievements);
- ClassDB::bind_method(D_METHOD("request_achievements"), &GameCenter::request_achievements);
- ClassDB::bind_method(D_METHOD("request_achievement_descriptions"), &GameCenter::request_achievement_descriptions);
- ClassDB::bind_method(D_METHOD("show_game_center"), &GameCenter::show_game_center);
- ClassDB::bind_method(D_METHOD("request_identity_verification_signature"), &GameCenter::request_identity_verification_signature);
-
- ClassDB::bind_method(D_METHOD("get_pending_event_count"), &GameCenter::get_pending_event_count);
- ClassDB::bind_method(D_METHOD("pop_pending_event"), &GameCenter::pop_pending_event);
-};
-
-Error GameCenter::authenticate() {
- //if this class isn't available, game center isn't implemented
- if ((NSClassFromString(@"GKLocalPlayer")) == nil) {
- return ERR_UNAVAILABLE;
- }
-
- GKLocalPlayer *player = [GKLocalPlayer localPlayer];
- ERR_FAIL_COND_V(![player respondsToSelector:@selector(authenticateHandler)], ERR_UNAVAILABLE);
-
- UIViewController *root_controller = [[UIApplication sharedApplication] delegate].window.rootViewController;
- ERR_FAIL_COND_V(!root_controller, FAILED);
-
- // This handler is called several times. First when the view needs to be shown, then again
- // after the view is cancelled or the user logs in. Or if the user's already logged in, it's
- // called just once to confirm they're authenticated. This is why no result needs to be specified
- // in the presentViewController phase. In this case, more calls to this function will follow.
- _weakify(root_controller);
- _weakify(player);
- player.authenticateHandler = (^(UIViewController *controller, NSError *error) {
- _strongify(root_controller);
- _strongify(player);
-
- if (controller) {
- [root_controller presentViewController:controller animated:YES completion:nil];
- } else {
- Dictionary ret;
- ret["type"] = "authentication";
- if (player.isAuthenticated) {
- ret["result"] = "ok";
- if (@available(iOS 13, *)) {
- ret["player_id"] = [player.teamPlayerID UTF8String];
-#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR
- } else {
- ret["player_id"] = [player.playerID UTF8String];
-#endif
- }
-
- GameCenter::get_singleton()->authenticated = true;
- } else {
- ret["result"] = "error";
- ret["error_code"] = (int64_t)error.code;
- ret["error_description"] = [error.localizedDescription UTF8String];
- GameCenter::get_singleton()->authenticated = false;
- };
-
- pending_events.push_back(ret);
- };
- });
-
- return OK;
-};
-
-bool GameCenter::is_authenticated() {
- return authenticated;
-};
-
-Error GameCenter::post_score(Dictionary p_score) {
- ERR_FAIL_COND_V(!p_score.has("score") || !p_score.has("category"), ERR_INVALID_PARAMETER);
- float score = p_score["score"];
- String category = p_score["category"];
-
- NSString *cat_str = [[NSString alloc] initWithUTF8String:category.utf8().get_data()];
- GKScore *reporter = [[GKScore alloc] initWithLeaderboardIdentifier:cat_str];
- reporter.value = score;
-
- ERR_FAIL_COND_V([GKScore respondsToSelector:@selector(reportScores)], ERR_UNAVAILABLE);
-
- [GKScore reportScores:@[ reporter ]
- withCompletionHandler:^(NSError *error) {
- Dictionary ret;
- ret["type"] = "post_score";
- if (error == nil) {
- ret["result"] = "ok";
- } else {
- ret["result"] = "error";
- ret["error_code"] = (int64_t)error.code;
- ret["error_description"] = [error.localizedDescription UTF8String];
- };
-
- pending_events.push_back(ret);
- }];
-
- return OK;
-};
-
-Error GameCenter::award_achievement(Dictionary p_params) {
- ERR_FAIL_COND_V(!p_params.has("name") || !p_params.has("progress"), ERR_INVALID_PARAMETER);
- String name = p_params["name"];
- float progress = p_params["progress"];
-
- NSString *name_str = [[NSString alloc] initWithUTF8String:name.utf8().get_data()];
- GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier:name_str];
- ERR_FAIL_COND_V(!achievement, FAILED);
-
- ERR_FAIL_COND_V([GKAchievement respondsToSelector:@selector(reportAchievements)], ERR_UNAVAILABLE);
-
- achievement.percentComplete = progress;
- achievement.showsCompletionBanner = NO;
- if (p_params.has("show_completion_banner")) {
- achievement.showsCompletionBanner = p_params["show_completion_banner"] ? YES : NO;
- }
-
- [GKAchievement reportAchievements:@[ achievement ]
- withCompletionHandler:^(NSError *error) {
- Dictionary ret;
- ret["type"] = "award_achievement";
- if (error == nil) {
- ret["result"] = "ok";
- } else {
- ret["result"] = "error";
- ret["error_code"] = (int64_t)error.code;
- };
-
- pending_events.push_back(ret);
- }];
-
- return OK;
-};
-
-void GameCenter::request_achievement_descriptions() {
- [GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) {
- Dictionary ret;
- ret["type"] = "achievement_descriptions";
- if (error == nil) {
- ret["result"] = "ok";
- PackedStringArray names;
- PackedStringArray titles;
- PackedStringArray unachieved_descriptions;
- PackedStringArray achieved_descriptions;
- PackedInt32Array maximum_points;
- Array hidden;
- Array replayable;
-
- for (NSUInteger i = 0; i < [descriptions count]; i++) {
- GKAchievementDescription *description = [descriptions objectAtIndex:i];
-
- const char *str = [description.identifier UTF8String];
- names.push_back(String::utf8(str != NULL ? str : ""));
-
- str = [description.title UTF8String];
- titles.push_back(String::utf8(str != NULL ? str : ""));
-
- str = [description.unachievedDescription UTF8String];
- unachieved_descriptions.push_back(String::utf8(str != NULL ? str : ""));
-
- str = [description.achievedDescription UTF8String];
- achieved_descriptions.push_back(String::utf8(str != NULL ? str : ""));
-
- maximum_points.push_back(description.maximumPoints);
-
- hidden.push_back(description.hidden == YES);
-
- replayable.push_back(description.replayable == YES);
- }
-
- ret["names"] = names;
- ret["titles"] = titles;
- ret["unachieved_descriptions"] = unachieved_descriptions;
- ret["achieved_descriptions"] = achieved_descriptions;
- ret["maximum_points"] = maximum_points;
- ret["hidden"] = hidden;
- ret["replayable"] = replayable;
-
- } else {
- ret["result"] = "error";
- ret["error_code"] = (int64_t)error.code;
- };
-
- pending_events.push_back(ret);
- }];
-};
-
-void GameCenter::request_achievements() {
- [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) {
- Dictionary ret;
- ret["type"] = "achievements";
- if (error == nil) {
- ret["result"] = "ok";
- PackedStringArray names;
- PackedFloat32Array percentages;
-
- for (NSUInteger i = 0; i < [achievements count]; i++) {
- GKAchievement *achievement = [achievements objectAtIndex:i];
- const char *str = [achievement.identifier UTF8String];
- names.push_back(String::utf8(str != NULL ? str : ""));
-
- percentages.push_back(achievement.percentComplete);
- }
-
- ret["names"] = names;
- ret["progress"] = percentages;
-
- } else {
- ret["result"] = "error";
- ret["error_code"] = (int64_t)error.code;
- };
-
- pending_events.push_back(ret);
- }];
-};
-
-void GameCenter::reset_achievements() {
- [GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error) {
- Dictionary ret;
- ret["type"] = "reset_achievements";
- if (error == nil) {
- ret["result"] = "ok";
- } else {
- ret["result"] = "error";
- ret["error_code"] = (int64_t)error.code;
- };
-
- pending_events.push_back(ret);
- }];
-};
-
-Error GameCenter::show_game_center(Dictionary p_params) {
- ERR_FAIL_COND_V(!NSProtocolFromString(@"GKGameCenterControllerDelegate"), FAILED);
-
- GKGameCenterViewControllerState view_state = GKGameCenterViewControllerStateDefault;
- if (p_params.has("view")) {
- String view_name = p_params["view"];
- if (view_name == "default") {
- view_state = GKGameCenterViewControllerStateDefault;
- } else if (view_name == "leaderboards") {
- view_state = GKGameCenterViewControllerStateLeaderboards;
- } else if (view_name == "achievements") {
- view_state = GKGameCenterViewControllerStateAchievements;
- } else if (view_name == "challenges") {
- view_state = GKGameCenterViewControllerStateChallenges;
- } else {
- return ERR_INVALID_PARAMETER;
- }
- }
-
- GKGameCenterViewController *controller = [[GKGameCenterViewController alloc] init];
- ERR_FAIL_COND_V(!controller, FAILED);
-
- UIViewController *root_controller = [[UIApplication sharedApplication] delegate].window.rootViewController;
- ERR_FAIL_COND_V(!root_controller, FAILED);
-
- controller.gameCenterDelegate = gameCenterDelegate;
- controller.viewState = view_state;
- if (view_state == GKGameCenterViewControllerStateLeaderboards) {
- controller.leaderboardIdentifier = nil;
- if (p_params.has("leaderboard_name")) {
- String name = p_params["leaderboard_name"];
- NSString *name_str = [[NSString alloc] initWithUTF8String:name.utf8().get_data()];
- controller.leaderboardIdentifier = name_str;
- }
- }
-
- [root_controller presentViewController:controller animated:YES completion:nil];
-
- return OK;
-};
-
-Error GameCenter::request_identity_verification_signature() {
- ERR_FAIL_COND_V(!is_authenticated(), ERR_UNAUTHORIZED);
-
- GKLocalPlayer *player = [GKLocalPlayer localPlayer];
- [player generateIdentityVerificationSignatureWithCompletionHandler:^(NSURL *publicKeyUrl, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error) {
- Dictionary ret;
- ret["type"] = "identity_verification_signature";
- if (error == nil) {
- ret["result"] = "ok";
- ret["public_key_url"] = [publicKeyUrl.absoluteString UTF8String];
- ret["signature"] = [[signature base64EncodedStringWithOptions:0] UTF8String];
- ret["salt"] = [[salt base64EncodedStringWithOptions:0] UTF8String];
- ret["timestamp"] = timestamp;
- if (@available(iOS 13, *)) {
- ret["player_id"] = [player.teamPlayerID UTF8String];
-#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR
- } else {
- ret["player_id"] = [player.playerID UTF8String];
-#endif
- }
- } else {
- ret["result"] = "error";
- ret["error_code"] = (int64_t)error.code;
- ret["error_description"] = [error.localizedDescription UTF8String];
- };
-
- pending_events.push_back(ret);
- }];
-
- return OK;
-};
-
-void GameCenter::game_center_closed() {
- Dictionary ret;
- ret["type"] = "show_game_center";
- ret["result"] = "ok";
- pending_events.push_back(ret);
-}
-
-int GameCenter::get_pending_event_count() {
- return pending_events.size();
-};
-
-Variant GameCenter::pop_pending_event() {
- Variant front = pending_events.front()->get();
- pending_events.pop_front();
-
- return front;
-};
-
-GameCenter *GameCenter::get_singleton() {
- return instance;
-};
-
-GameCenter::GameCenter() {
- ERR_FAIL_COND(instance != NULL);
- instance = this;
- authenticated = false;
-
- gameCenterDelegate = [[GodotGameCenterDelegate alloc] init];
-};
-
-GameCenter::~GameCenter() {
- if (gameCenterDelegate) {
- gameCenterDelegate = nil;
- }
-}
diff --git a/modules/gamecenter/game_center_delegate.mm b/modules/gamecenter/game_center_delegate.mm
deleted file mode 100644
index 9a10c439c6..0000000000
--- a/modules/gamecenter/game_center_delegate.mm
+++ /dev/null
@@ -1,45 +0,0 @@
-/*************************************************************************/
-/* game_center_delegate.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#import "game_center_delegate.h"
-
-#include "game_center.h"
-
-@implementation GodotGameCenterDelegate
-
-- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController {
- //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone
- if (GameCenter::get_singleton()) {
- GameCenter::get_singleton()->game_center_closed();
- }
- [gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
-}
-
-@end
diff --git a/modules/gamecenter/game_center_module.h b/modules/gamecenter/game_center_module.h
deleted file mode 100644
index 8da3ae02ee..0000000000
--- a/modules/gamecenter/game_center_module.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*************************************************************************/
-/* game_center_module.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-void register_gamecenter_types();
-void unregister_gamecenter_types();
diff --git a/modules/gamecenter/gamecenter.gdip b/modules/gamecenter/gamecenter.gdip
deleted file mode 100644
index eb44effbdd..0000000000
--- a/modules/gamecenter/gamecenter.gdip
+++ /dev/null
@@ -1,17 +0,0 @@
-[config]
-name="GameCenter"
-binary="gamecenter_lib.a"
-
-initialization="register_gamecenter_types"
-deinitialization="unregister_gamecenter_types"
-
-[dependencies]
-linked=[]
-embedded=[]
-system=["GameKit.framework"]
-
-capabilities=["gamekit"]
-
-files=[]
-
-[plist]
diff --git a/modules/gdnative/android/android_gdn.cpp b/modules/gdnative/android/android_gdn.cpp
index bc39be1813..fe3b3e7e12 100644
--- a/modules/gdnative/android/android_gdn.cpp
+++ b/modules/gdnative/android/android_gdn.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,7 +48,7 @@ extern "C" {
JNIEnv *GDAPI godot_android_get_env() {
#ifdef __ANDROID__
- return ThreadAndroid::get_env();
+ return get_jni_env();
#else
return nullptr;
#endif
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index f397ee96c5..86bd8b820d 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -110,6 +110,16 @@ bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_property) const
return false;
}
+void GDNativeLibrary::reset_state() {
+ config_file.instance();
+ current_library_path = "";
+ current_dependencies.clear();
+ symbol_prefix = default_symbol_prefix;
+ load_once = default_load_once;
+ singleton = default_singleton;
+ reloadable = default_reloadable;
+}
+
void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
// set entries
List<String> entry_key_list;
@@ -286,7 +296,7 @@ bool GDNative::initialize() {
}
String lib_path = library->get_current_library_path();
- if (lib_path.empty()) {
+ if (lib_path.is_empty()) {
ERR_PRINT("No library set for this platform");
return false;
}
@@ -508,7 +518,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_
return result;
}
-RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
Ref<GDNativeLibrary> lib;
lib.instance();
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index bba2c04a2a..a28c58ec0d 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,6 +63,8 @@ class GDNativeLibrary : public Resource {
bool reloadable;
public:
+ virtual void reset_state() override;
+
GDNativeLibrary();
~GDNativeLibrary();
@@ -166,7 +168,7 @@ public:
class GDNativeLibraryResourceLoader : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/gdnative/aabb.cpp b/modules/gdnative/gdnative/aabb.cpp
index dc1b79b9e5..5d3f224adc 100644
--- a/modules/gdnative/gdnative/aabb.cpp
+++ b/modules/gdnative/gdnative/aabb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,195 +31,15 @@
#include "gdnative/aabb.h"
#include "core/math/aabb.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_aabb) == sizeof(AABB), "AABB size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_aabb) == sizeof(AABB), "AABB size mismatch");
-
-void GDAPI godot_aabb_new(godot_aabb *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size) {
- const Vector3 *pos = (const Vector3 *)p_pos;
- const Vector3 *size = (const Vector3 *)p_size;
- AABB *dest = (AABB *)r_dest;
- *dest = AABB(*pos, *size);
-}
-
-godot_vector3 GDAPI godot_aabb_get_position(const godot_aabb *p_self) {
- godot_vector3 raw_ret;
- const AABB *self = (const AABB *)p_self;
- Vector3 *ret = (Vector3 *)&raw_ret;
- *ret = self->position;
- return raw_ret;
-}
-
-void GDAPI godot_aabb_set_position(const godot_aabb *p_self, const godot_vector3 *p_v) {
- AABB *self = (AABB *)p_self;
- const Vector3 *v = (const Vector3 *)p_v;
- self->position = *v;
-}
-
-godot_vector3 GDAPI godot_aabb_get_size(const godot_aabb *p_self) {
- godot_vector3 raw_ret;
- const AABB *self = (const AABB *)p_self;
- Vector3 *ret = (Vector3 *)&raw_ret;
- *ret = self->size;
- return raw_ret;
-}
-
-void GDAPI godot_aabb_set_size(const godot_aabb *p_self, const godot_vector3 *p_v) {
- AABB *self = (AABB *)p_self;
- const Vector3 *v = (const Vector3 *)p_v;
- self->size = *v;
-}
-
-godot_string GDAPI godot_aabb_as_string(const godot_aabb *p_self) {
- godot_string ret;
- const AABB *self = (const AABB *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_aabb GDAPI godot_aabb_abs(const godot_aabb *p_self) {
- godot_aabb dest;
- const AABB *self = (const AABB *)p_self;
- *((AABB *)&dest) = self->abs();
- return dest;
-}
-
-godot_real GDAPI godot_aabb_get_area(const godot_aabb *p_self) {
- const AABB *self = (const AABB *)p_self;
- return self->get_area();
-}
-
-godot_bool GDAPI godot_aabb_has_no_area(const godot_aabb *p_self) {
- const AABB *self = (const AABB *)p_self;
- return self->has_no_area();
-}
-
-godot_bool GDAPI godot_aabb_has_no_surface(const godot_aabb *p_self) {
- const AABB *self = (const AABB *)p_self;
- return self->has_no_surface();
-}
-
-godot_bool GDAPI godot_aabb_intersects(const godot_aabb *p_self, const godot_aabb *p_with) {
- const AABB *self = (const AABB *)p_self;
- const AABB *with = (const AABB *)p_with;
- return self->intersects(*with);
-}
-
-godot_bool GDAPI godot_aabb_encloses(const godot_aabb *p_self, const godot_aabb *p_with) {
- const AABB *self = (const AABB *)p_self;
- const AABB *with = (const AABB *)p_with;
- return self->encloses(*with);
-}
-
-godot_aabb GDAPI godot_aabb_merge(const godot_aabb *p_self, const godot_aabb *p_with) {
- godot_aabb dest;
- const AABB *self = (const AABB *)p_self;
- const AABB *with = (const AABB *)p_with;
- *((AABB *)&dest) = self->merge(*with);
- return dest;
-}
-
-godot_aabb GDAPI godot_aabb_intersection(const godot_aabb *p_self, const godot_aabb *p_with) {
- godot_aabb dest;
- const AABB *self = (const AABB *)p_self;
- const AABB *with = (const AABB *)p_with;
- *((AABB *)&dest) = self->intersection(*with);
- return dest;
-}
-
-godot_bool GDAPI godot_aabb_intersects_plane(const godot_aabb *p_self, const godot_plane *p_plane) {
- const AABB *self = (const AABB *)p_self;
- const Plane *plane = (const Plane *)p_plane;
- return self->intersects_plane(*plane);
-}
-
-godot_bool GDAPI godot_aabb_intersects_segment(const godot_aabb *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to) {
- const AABB *self = (const AABB *)p_self;
- const Vector3 *from = (const Vector3 *)p_from;
- const Vector3 *to = (const Vector3 *)p_to;
- return self->intersects_segment(*from, *to);
-}
-
-godot_bool GDAPI godot_aabb_has_point(const godot_aabb *p_self, const godot_vector3 *p_point) {
- const AABB *self = (const AABB *)p_self;
- const Vector3 *point = (const Vector3 *)p_point;
- return self->has_point(*point);
-}
-
-godot_vector3 GDAPI godot_aabb_get_support(const godot_aabb *p_self, const godot_vector3 *p_dir) {
- godot_vector3 dest;
- const AABB *self = (const AABB *)p_self;
- const Vector3 *dir = (const Vector3 *)p_dir;
- *((Vector3 *)&dest) = self->get_support(*dir);
- return dest;
-}
-
-godot_vector3 GDAPI godot_aabb_get_longest_axis(const godot_aabb *p_self) {
- godot_vector3 dest;
- const AABB *self = (const AABB *)p_self;
- *((Vector3 *)&dest) = self->get_longest_axis();
- return dest;
-}
-
-godot_int GDAPI godot_aabb_get_longest_axis_index(const godot_aabb *p_self) {
- const AABB *self = (const AABB *)p_self;
- return self->get_longest_axis_index();
-}
-
-godot_real GDAPI godot_aabb_get_longest_axis_size(const godot_aabb *p_self) {
- const AABB *self = (const AABB *)p_self;
- return self->get_longest_axis_size();
-}
-
-godot_vector3 GDAPI godot_aabb_get_shortest_axis(const godot_aabb *p_self) {
- godot_vector3 dest;
- const AABB *self = (const AABB *)p_self;
- *((Vector3 *)&dest) = self->get_shortest_axis();
- return dest;
-}
-
-godot_int GDAPI godot_aabb_get_shortest_axis_index(const godot_aabb *p_self) {
- const AABB *self = (const AABB *)p_self;
- return self->get_shortest_axis_index();
-}
-
-godot_real GDAPI godot_aabb_get_shortest_axis_size(const godot_aabb *p_self) {
- const AABB *self = (const AABB *)p_self;
- return self->get_shortest_axis_size();
-}
-
-godot_aabb GDAPI godot_aabb_expand(const godot_aabb *p_self, const godot_vector3 *p_to_point) {
- godot_aabb dest;
- const AABB *self = (const AABB *)p_self;
- const Vector3 *to_point = (const Vector3 *)p_to_point;
- *((AABB *)&dest) = self->expand(*to_point);
- return dest;
-}
-
-godot_aabb GDAPI godot_aabb_grow(const godot_aabb *p_self, const godot_real p_by) {
- godot_aabb dest;
- const AABB *self = (const AABB *)p_self;
-
- *((AABB *)&dest) = self->grow(p_by);
- return dest;
-}
-
-godot_vector3 GDAPI godot_aabb_get_endpoint(const godot_aabb *p_self, const godot_int p_idx) {
- godot_vector3 dest;
- const AABB *self = (const AABB *)p_self;
-
- *((Vector3 *)&dest) = self->get_endpoint(p_idx);
- return dest;
-}
-
-godot_bool GDAPI godot_aabb_operator_equal(const godot_aabb *p_self, const godot_aabb *p_b) {
- const AABB *self = (const AABB *)p_self;
- const AABB *b = (const AABB *)p_b;
- return *self == *b;
+void GDAPI godot_aabb_new(godot_aabb *p_self) {
+ memnew_placement(p_self, AABB);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp
index 863889acbc..e68b60c5e6 100644
--- a/modules/gdnative/gdnative/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,367 +33,28 @@
#include "core/os/memory.h"
#include "core/variant/array.h"
-#include "core/math/color.h"
-
-#include "core/variant/variant.h"
+static_assert(sizeof(godot_array) == sizeof(Array), "Array size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_array) == sizeof(Array), "Array size mismatch");
-
-void GDAPI godot_array_new(godot_array *r_dest) {
- Array *dest = (Array *)r_dest;
- memnew_placement(dest, Array);
-}
-
-void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src) {
- Array *dest = (Array *)r_dest;
- const Array *src = (const Array *)p_src;
- memnew_placement(dest, Array(*src));
-}
-
-void GDAPI godot_array_new_packed_color_array(godot_array *r_dest, const godot_packed_color_array *p_pca) {
- Array *dest = (Array *)r_dest;
- Vector<Color> *pca = (Vector<Color> *)p_pca;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_vector3_array(godot_array *r_dest, const godot_packed_vector3_array *p_pv3a) {
- Array *dest = (Array *)r_dest;
- Vector<Vector3> *pca = (Vector<Vector3> *)p_pv3a;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_vector2_array(godot_array *r_dest, const godot_packed_vector2_array *p_pv2a) {
- Array *dest = (Array *)r_dest;
- Vector<Vector2> *pca = (Vector<Vector2> *)p_pv2a;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_vector2i_array(godot_array *r_dest, const godot_packed_vector2i_array *p_pv2a) {
- Array *dest = (Array *)r_dest;
- Vector<Vector2i> *pca = (Vector<Vector2i> *)p_pv2a;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_string_array(godot_array *r_dest, const godot_packed_string_array *p_psa) {
- Array *dest = (Array *)r_dest;
- Vector<String> *pca = (Vector<String> *)p_psa;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_float32_array(godot_array *r_dest, const godot_packed_float32_array *p_pra) {
- Array *dest = (Array *)r_dest;
- Vector<float> *pca = (Vector<float> *)p_pra;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_float64_array(godot_array *r_dest, const godot_packed_float64_array *p_pra) {
- Array *dest = (Array *)r_dest;
- Vector<double> *pca = (Vector<double> *)p_pra;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_int32_array(godot_array *r_dest, const godot_packed_int32_array *p_pia) {
- Array *dest = (Array *)r_dest;
- Vector<int32_t> *pca = (Vector<int32_t> *)p_pia;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_int64_array(godot_array *r_dest, const godot_packed_int64_array *p_pia) {
- Array *dest = (Array *)r_dest;
- Vector<int64_t> *pca = (Vector<int64_t> *)p_pia;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_new_packed_byte_array(godot_array *r_dest, const godot_packed_byte_array *p_pba) {
- Array *dest = (Array *)r_dest;
- Vector<uint8_t> *pca = (Vector<uint8_t> *)p_pba;
- memnew_placement(dest, Array);
- dest->resize(pca->size());
-
- for (int i = 0; i < dest->size(); i++) {
- Variant v = pca->operator[](i);
- dest->operator[](i) = v;
- }
-}
-
-void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value) {
- Array *self = (Array *)p_self;
- Variant *val = (Variant *)p_value;
- self->operator[](p_idx) = *val;
-}
-
-godot_variant GDAPI godot_array_get(const godot_array *p_self, const godot_int p_idx) {
- godot_variant raw_dest;
- Variant *dest = (Variant *)&raw_dest;
- const Array *self = (const Array *)p_self;
- memnew_placement(dest, Variant(self->operator[](p_idx)));
- return raw_dest;
-}
-
-godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot_int p_idx) {
- Array *self = (Array *)p_self;
- return (godot_variant *)&self->operator[](p_idx);
-}
-
-const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, const godot_int p_idx) {
- const Array *self = (const Array *)p_self;
- return (const godot_variant *)&self->operator[](p_idx);
-}
-
-void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value) {
- Array *self = (Array *)p_self;
- Variant *val = (Variant *)p_value;
- self->append(*val);
-}
-
-void GDAPI godot_array_clear(godot_array *p_self) {
- Array *self = (Array *)p_self;
- self->clear();
-}
-
-godot_int GDAPI godot_array_count(const godot_array *p_self, const godot_variant *p_value) {
- const Array *self = (const Array *)p_self;
- const Variant *val = (const Variant *)p_value;
- return self->count(*val);
-}
-
-godot_bool GDAPI godot_array_empty(const godot_array *p_self) {
- const Array *self = (const Array *)p_self;
- return self->empty();
-}
-
-void GDAPI godot_array_erase(godot_array *p_self, const godot_variant *p_value) {
- Array *self = (Array *)p_self;
- const Variant *val = (const Variant *)p_value;
- self->erase(*val);
-}
-
-godot_variant GDAPI godot_array_front(const godot_array *p_self) {
- const Array *self = (const Array *)p_self;
- godot_variant v;
- Variant *val = (Variant *)&v;
- memnew_placement(val, Variant);
- *val = self->front();
- return v;
-}
-
-godot_variant GDAPI godot_array_back(const godot_array *p_self) {
- const Array *self = (const Array *)p_self;
- godot_variant v;
- Variant *val = (Variant *)&v;
- memnew_placement(val, Variant);
- *val = self->back();
- return v;
-}
-
-godot_int GDAPI godot_array_find(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from) {
- const Array *self = (const Array *)p_self;
- const Variant *val = (const Variant *)p_what;
- return self->find(*val, p_from);
-}
-
-godot_int GDAPI godot_array_find_last(const godot_array *p_self, const godot_variant *p_what) {
- const Array *self = (const Array *)p_self;
- const Variant *val = (const Variant *)p_what;
- return self->find_last(*val);
-}
-
-godot_bool GDAPI godot_array_has(const godot_array *p_self, const godot_variant *p_value) {
- const Array *self = (const Array *)p_self;
- const Variant *val = (const Variant *)p_value;
- return self->has(*val);
-}
-
-godot_int GDAPI godot_array_hash(const godot_array *p_self) {
- const Array *self = (const Array *)p_self;
- return self->hash();
-}
-
-void GDAPI godot_array_insert(godot_array *p_self, const godot_int p_pos, const godot_variant *p_value) {
- Array *self = (Array *)p_self;
- const Variant *val = (const Variant *)p_value;
- self->insert(p_pos, *val);
-}
-
-void GDAPI godot_array_invert(godot_array *p_self) {
- Array *self = (Array *)p_self;
- self->invert();
-}
-
-godot_variant GDAPI godot_array_pop_back(godot_array *p_self) {
- Array *self = (Array *)p_self;
- godot_variant v;
- Variant *val = (Variant *)&v;
- memnew_placement(val, Variant);
- *val = self->pop_back();
- return v;
-}
-
-godot_variant GDAPI godot_array_pop_front(godot_array *p_self) {
- Array *self = (Array *)p_self;
- godot_variant v;
- Variant *val = (Variant *)&v;
- memnew_placement(val, Variant);
- *val = self->pop_front();
- return v;
-}
-
-void GDAPI godot_array_push_back(godot_array *p_self, const godot_variant *p_value) {
- Array *self = (Array *)p_self;
- const Variant *val = (const Variant *)p_value;
- self->push_back(*val);
-}
-
-void GDAPI godot_array_push_front(godot_array *p_self, const godot_variant *p_value) {
- Array *self = (Array *)p_self;
- const Variant *val = (const Variant *)p_value;
- self->push_front(*val);
-}
-
-void GDAPI godot_array_remove(godot_array *p_self, const godot_int p_idx) {
- Array *self = (Array *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_array_resize(godot_array *p_self, const godot_int p_size) {
- Array *self = (Array *)p_self;
- self->resize(p_size);
-}
-
-godot_int GDAPI godot_array_rfind(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from) {
- const Array *self = (const Array *)p_self;
- const Variant *val = (const Variant *)p_what;
- return self->rfind(*val, p_from);
-}
-
-godot_int GDAPI godot_array_size(const godot_array *p_self) {
- const Array *self = (const Array *)p_self;
- return self->size();
-}
-
-void GDAPI godot_array_sort(godot_array *p_self) {
- Array *self = (Array *)p_self;
- self->sort();
-}
-
-void GDAPI godot_array_sort_custom(godot_array *p_self, godot_object *p_obj, const godot_string *p_func) {
- Array *self = (Array *)p_self;
- const String *func = (const String *)p_func;
- self->sort_custom((Object *)p_obj, *func);
-}
-
-godot_int GDAPI godot_array_bsearch(godot_array *p_self, const godot_variant *p_value, const godot_bool p_before) {
- Array *self = (Array *)p_self;
- return self->bsearch(*(const Variant *)p_value, p_before);
-}
-
-godot_int GDAPI godot_array_bsearch_custom(godot_array *p_self, const godot_variant *p_value, godot_object *p_obj, const godot_string *p_func, const godot_bool p_before) {
- Array *self = (Array *)p_self;
- const String *func = (const String *)p_func;
- return self->bsearch_custom(*(const Variant *)p_value, (Object *)p_obj, *func, p_before);
+void GDAPI godot_array_new(godot_array *p_self) {
+ memnew_placement(p_self, Array);
}
void GDAPI godot_array_destroy(godot_array *p_self) {
((Array *)p_self)->~Array();
}
-godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep) {
- const Array *self = (const Array *)p_self;
- godot_array res;
- Array *val = (Array *)&res;
- memnew_placement(val, Array);
- *val = self->duplicate(p_deep);
- return res;
-}
-
-godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_step, const godot_bool p_deep) {
- const Array *self = (const Array *)p_self;
- godot_array res;
- Array *val = (Array *)&res;
- memnew_placement(val, Array);
- *val = self->slice(p_begin, p_end, p_step, p_deep);
- return res;
-}
-
-godot_variant GDAPI godot_array_max(const godot_array *p_self) {
- const Array *self = (const Array *)p_self;
- godot_variant v;
- Variant *val = (Variant *)&v;
- memnew_placement(val, Variant);
- *val = self->max();
- return v;
+godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, godot_int p_index) {
+ Array *self = (Array *)p_self;
+ return (godot_variant *)&self->operator[](p_index);
}
-godot_variant GDAPI godot_array_min(const godot_array *p_self) {
+const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, godot_int p_index) {
const Array *self = (const Array *)p_self;
- godot_variant v;
- Variant *val = (Variant *)&v;
- memnew_placement(val, Variant);
- *val = self->min();
- return v;
-}
-
-void GDAPI godot_array_shuffle(godot_array *p_self) {
- Array *self = (Array *)p_self;
- self->shuffle();
+ return (const godot_variant *)&self->operator[](p_index);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp
index e5891562a1..df3e1255ac 100644
--- a/modules/gdnative/gdnative/basis.cpp
+++ b/modules/gdnative/gdnative/basis.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,266 +31,25 @@
#include "gdnative/basis.h"
#include "core/math/basis.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_basis) == sizeof(Basis), "Basis size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_basis) == sizeof(Basis), "Basis size mismatch");
-
-void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis) {
- const Vector3 *x_axis = (const Vector3 *)p_x_axis;
- const Vector3 *y_axis = (const Vector3 *)p_y_axis;
- const Vector3 *z_axis = (const Vector3 *)p_z_axis;
- Basis *dest = (Basis *)r_dest;
- *dest = Basis(*x_axis, *y_axis, *z_axis);
-}
-
-void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi) {
- const Vector3 *axis = (const Vector3 *)p_axis;
- Basis *dest = (Basis *)r_dest;
- *dest = Basis(*axis, p_phi);
-}
-
-void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler) {
- const Vector3 *euler = (const Vector3 *)p_euler;
- Basis *dest = (Basis *)r_dest;
- *dest = Basis(*euler);
-}
-
-godot_string GDAPI godot_basis_as_string(const godot_basis *p_self) {
- godot_string ret;
- const Basis *self = (const Basis *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_basis GDAPI godot_basis_inverse(const godot_basis *p_self) {
- godot_basis dest;
- const Basis *self = (const Basis *)p_self;
- *((Basis *)&dest) = self->inverse();
- return dest;
-}
-
-godot_basis GDAPI godot_basis_transposed(const godot_basis *p_self) {
- godot_basis dest;
- const Basis *self = (const Basis *)p_self;
- *((Basis *)&dest) = self->transposed();
- return dest;
-}
-
-godot_basis GDAPI godot_basis_orthonormalized(const godot_basis *p_self) {
- godot_basis dest;
- const Basis *self = (const Basis *)p_self;
- *((Basis *)&dest) = self->orthonormalized();
- return dest;
-}
-
-godot_real GDAPI godot_basis_determinant(const godot_basis *p_self) {
- const Basis *self = (const Basis *)p_self;
- return self->determinant();
-}
-
-godot_basis GDAPI godot_basis_rotated(const godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_phi) {
- godot_basis dest;
- const Basis *self = (const Basis *)p_self;
- const Vector3 *axis = (const Vector3 *)p_axis;
- *((Basis *)&dest) = self->rotated(*axis, p_phi);
- return dest;
-}
-
-godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vector3 *p_scale) {
- godot_basis dest;
- const Basis *self = (const Basis *)p_self;
- const Vector3 *scale = (const Vector3 *)p_scale;
- *((Basis *)&dest) = self->scaled(*scale);
- return dest;
-}
-
-godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self) {
- godot_vector3 dest;
- const Basis *self = (const Basis *)p_self;
- *((Vector3 *)&dest) = self->get_scale();
- return dest;
-}
-
-godot_quat GDAPI godot_basis_get_quat(const godot_basis *p_self) {
- godot_quat dest;
- const Basis *self = (const Basis *)p_self;
- *((Quat *)&dest) = self->get_quat();
- return dest;
-}
-
-void GDAPI godot_basis_set_quat(godot_basis *p_self, const godot_quat *p_quat) {
- Basis *self = (Basis *)p_self;
- const Quat *quat = (const Quat *)p_quat;
- self->set_quat(*quat);
+void GDAPI godot_basis_new(godot_basis *p_self) {
+ memnew_placement(p_self, Basis);
}
-void GDAPI godot_basis_set_axis_angle_scale(godot_basis *p_self, const godot_vector3 *p_axis, godot_real p_phi, const godot_vector3 *p_scale) {
+godot_vector3 GDAPI *godot_basis_operator_index(godot_basis *p_self, godot_int p_index) {
Basis *self = (Basis *)p_self;
- const Vector3 *axis = (const Vector3 *)p_axis;
- const Vector3 *scale = (const Vector3 *)p_scale;
- self->set_axis_angle_scale(*axis, p_phi, *scale);
-}
-
-void GDAPI godot_basis_set_euler_scale(godot_basis *p_self, const godot_vector3 *p_euler, const godot_vector3 *p_scale) {
- Basis *self = (Basis *)p_self;
- const Vector3 *euler = (const Vector3 *)p_euler;
- const Vector3 *scale = (const Vector3 *)p_scale;
- self->set_euler_scale(*euler, *scale);
-}
-
-void GDAPI godot_basis_set_quat_scale(godot_basis *p_self, const godot_quat *p_quat, const godot_vector3 *p_scale) {
- Basis *self = (Basis *)p_self;
- const Quat *quat = (const Quat *)p_quat;
- const Vector3 *scale = (const Vector3 *)p_scale;
- self->set_quat_scale(*quat, *scale);
-}
-
-godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self) {
- godot_vector3 dest;
- const Basis *self = (const Basis *)p_self;
- *((Vector3 *)&dest) = self->get_euler();
- return dest;
-}
-
-godot_real GDAPI godot_basis_tdotx(const godot_basis *p_self, const godot_vector3 *p_with) {
- const Basis *self = (const Basis *)p_self;
- const Vector3 *with = (const Vector3 *)p_with;
- return self->tdotx(*with);
-}
-
-godot_real GDAPI godot_basis_tdoty(const godot_basis *p_self, const godot_vector3 *p_with) {
- const Basis *self = (const Basis *)p_self;
- const Vector3 *with = (const Vector3 *)p_with;
- return self->tdoty(*with);
-}
-
-godot_real GDAPI godot_basis_tdotz(const godot_basis *p_self, const godot_vector3 *p_with) {
- const Basis *self = (const Basis *)p_self;
- const Vector3 *with = (const Vector3 *)p_with;
- return self->tdotz(*with);
-}
-
-godot_vector3 GDAPI godot_basis_xform(const godot_basis *p_self, const godot_vector3 *p_v) {
- godot_vector3 dest;
- const Basis *self = (const Basis *)p_self;
- const Vector3 *v = (const Vector3 *)p_v;
- *((Vector3 *)&dest) = self->xform(*v);
- return dest;
-}
-
-godot_vector3 GDAPI godot_basis_xform_inv(const godot_basis *p_self, const godot_vector3 *p_v) {
- godot_vector3 dest;
- const Basis *self = (const Basis *)p_self;
- const Vector3 *v = (const Vector3 *)p_v;
- *((Vector3 *)&dest) = self->xform_inv(*v);
- return dest;
-}
-
-godot_int GDAPI godot_basis_get_orthogonal_index(const godot_basis *p_self) {
- const Basis *self = (const Basis *)p_self;
- return self->get_orthogonal_index();
-}
-
-void GDAPI godot_basis_new(godot_basis *r_dest) {
- Basis *dest = (Basis *)r_dest;
- *dest = Basis();
-}
-
-void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler) {
- Basis *dest = (Basis *)r_dest;
- const Quat *euler = (const Quat *)p_euler;
- *dest = Basis(*euler);
-}
-
-// p_elements is a pointer to an array of 3 (!!) vector3
-void GDAPI godot_basis_get_elements(const godot_basis *p_self, godot_vector3 *p_elements) {
- const Basis *self = (const Basis *)p_self;
- Vector3 *elements = (Vector3 *)p_elements;
- elements[0] = self->elements[0];
- elements[1] = self->elements[1];
- elements[2] = self->elements[2];
-}
-
-godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_self, const godot_int p_axis) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Basis *self = (const Basis *)p_self;
- *d = self->get_axis(p_axis);
- return dest;
-}
-
-void GDAPI godot_basis_set_axis(godot_basis *p_self, const godot_int p_axis, const godot_vector3 *p_value) {
- Basis *self = (Basis *)p_self;
- const Vector3 *value = (const Vector3 *)p_value;
- self->set_axis(p_axis, *value);
-}
-
-godot_vector3 GDAPI godot_basis_get_row(const godot_basis *p_self, const godot_int p_row) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Basis *self = (const Basis *)p_self;
- *d = self->get_row(p_row);
- return dest;
-}
-
-void GDAPI godot_basis_set_row(godot_basis *p_self, const godot_int p_row, const godot_vector3 *p_value) {
- Basis *self = (Basis *)p_self;
- const Vector3 *value = (const Vector3 *)p_value;
- self->set_row(p_row, *value);
-}
-
-godot_bool GDAPI godot_basis_operator_equal(const godot_basis *p_self, const godot_basis *p_b) {
- const Basis *self = (const Basis *)p_self;
- const Basis *b = (const Basis *)p_b;
- return *self == *b;
-}
-
-godot_basis GDAPI godot_basis_operator_add(const godot_basis *p_self, const godot_basis *p_b) {
- godot_basis raw_dest;
- Basis *dest = (Basis *)&raw_dest;
- const Basis *self = (const Basis *)p_self;
- const Basis *b = (const Basis *)p_b;
- *dest = *self + *b;
- return raw_dest;
-}
-
-godot_basis GDAPI godot_basis_operator_subtract(const godot_basis *p_self, const godot_basis *p_b) {
- godot_basis raw_dest;
- Basis *dest = (Basis *)&raw_dest;
- const Basis *self = (const Basis *)p_self;
- const Basis *b = (const Basis *)p_b;
- *dest = *self - *b;
- return raw_dest;
-}
-
-godot_basis GDAPI godot_basis_operator_multiply_vector(const godot_basis *p_self, const godot_basis *p_b) {
- godot_basis raw_dest;
- Basis *dest = (Basis *)&raw_dest;
- const Basis *self = (const Basis *)p_self;
- const Basis *b = (const Basis *)p_b;
- *dest = *self * *b;
- return raw_dest;
-}
-
-godot_basis GDAPI godot_basis_operator_multiply_scalar(const godot_basis *p_self, const godot_real p_b) {
- godot_basis raw_dest;
- Basis *dest = (Basis *)&raw_dest;
- const Basis *self = (const Basis *)p_self;
- *dest = *self * p_b;
- return raw_dest;
+ return (godot_vector3 *)&self->operator[](p_index);
}
-godot_basis GDAPI godot_basis_slerp(const godot_basis *p_self, const godot_basis *p_b, const godot_real p_t) {
- godot_basis raw_dest;
- Basis *dest = (Basis *)&raw_dest;
+const godot_vector3 GDAPI *godot_basis_operator_index_const(const godot_basis *p_self, godot_int p_index) {
const Basis *self = (const Basis *)p_self;
- const Basis *b = (const Basis *)p_b;
- *dest = self->slerp(*b, p_t);
- return raw_dest;
+ return (const godot_vector3 *)&self->operator[](p_index);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/callable.cpp b/modules/gdnative/gdnative/callable.cpp
index f200e9f171..7c62b5928f 100644
--- a/modules/gdnative/gdnative/callable.cpp
+++ b/modules/gdnative/gdnative/callable.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,36 +30,17 @@
#include "gdnative/callable.h"
-#include "core/io/resource.h"
#include "core/variant/callable.h"
#include "core/variant/variant.h"
+static_assert(sizeof(godot_callable) == sizeof(Callable), "Callable size mismatch");
+
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_callable) == sizeof(Callable), "Callable size mismatch");
-static_assert(sizeof(godot_signal) == sizeof(Signal), "Signal size mismatch");
-
-// Callable
-
-void GDAPI godot_callable_new_with_object(godot_callable *r_dest, const godot_object *p_object, const godot_string_name *p_method) {
- Callable *dest = (Callable *)r_dest;
- const Object *object = (const Object *)p_object;
- const StringName *method = (const StringName *)p_method;
- memnew_placement(dest, Callable(object, *method));
-}
-
-void GDAPI godot_callable_new_with_object_id(godot_callable *r_dest, uint64_t p_objectid, const godot_string_name *p_method) {
- Callable *dest = (Callable *)r_dest;
- const StringName *method = (const StringName *)p_method;
- memnew_placement(dest, Callable(ObjectID(p_objectid), *method));
-}
-
-void GDAPI godot_callable_new_copy(godot_callable *r_dest, const godot_callable *p_src) {
- Callable *dest = (Callable *)r_dest;
- const Callable *src = (const Callable *)p_src;
- memnew_placement(dest, Callable(*src));
+void GDAPI godot_callable_new(godot_callable *p_self) {
+ memnew_placement(p_self, Callable);
}
void GDAPI godot_callable_destroy(godot_callable *p_self) {
@@ -67,186 +48,6 @@ void GDAPI godot_callable_destroy(godot_callable *p_self) {
self->~Callable();
}
-godot_int GDAPI godot_callable_call(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount, godot_variant *r_return_value) {
- const Callable *self = (const Callable *)p_self;
- const Variant **arguments = (const Variant **)p_arguments;
- Variant *return_value = (Variant *)r_return_value;
- Variant ret;
- Callable::CallError err;
- self->call(arguments, p_argcount, ret, err);
- if (return_value)
- (*return_value) = ret;
- return (godot_int)err.error;
-}
-
-void GDAPI godot_callable_call_deferred(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount) {
- const Callable *self = (const Callable *)p_self;
- const Variant **arguments = (const Variant **)p_arguments;
- self->call_deferred(arguments, p_argcount);
-}
-
-godot_bool GDAPI godot_callable_is_null(const godot_callable *p_self) {
- const Callable *self = (const Callable *)p_self;
- return self->is_null();
-}
-
-godot_bool GDAPI godot_callable_is_custom(const godot_callable *p_self) {
- const Callable *self = (const Callable *)p_self;
- return self->is_custom();
-}
-
-godot_bool GDAPI godot_callable_is_standard(const godot_callable *p_self) {
- const Callable *self = (const Callable *)p_self;
- return self->is_standard();
-}
-
-godot_object GDAPI *godot_callable_get_object(const godot_callable *p_self) {
- const Callable *self = (const Callable *)p_self;
- return (godot_object *)self->get_object();
-}
-
-uint64_t GDAPI godot_callable_get_object_id(const godot_callable *p_self) {
- const Callable *self = (const Callable *)p_self;
- return (uint64_t)self->get_object_id();
-}
-
-godot_string_name GDAPI godot_callable_get_method(const godot_callable *p_self) {
- godot_string_name raw_dest;
- const Callable *self = (const Callable *)p_self;
- StringName *dest = (StringName *)&raw_dest;
- memnew_placement(dest, StringName(self->get_method()));
- return raw_dest;
-}
-
-uint32_t GDAPI godot_callable_hash(const godot_callable *p_self) {
- const Callable *self = (const Callable *)p_self;
- return self->hash();
-}
-
-godot_string GDAPI godot_callable_as_string(const godot_callable *p_self) {
- godot_string ret;
- const Callable *self = (const Callable *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_bool GDAPI godot_callable_operator_equal(const godot_callable *p_self, const godot_callable *p_other) {
- const Callable *self = (const Callable *)p_self;
- const Callable *other = (const Callable *)p_other;
- return *self == *other;
-}
-
-godot_bool GDAPI godot_callable_operator_less(const godot_callable *p_self, const godot_callable *p_other) {
- const Callable *self = (const Callable *)p_self;
- const Callable *other = (const Callable *)p_other;
- return *self < *other;
-}
-
-// Signal
-
-void GDAPI godot_signal_new_with_object(godot_signal *r_dest, const godot_object *p_object, const godot_string_name *p_name) {
- Signal *dest = (Signal *)r_dest;
- const Object *object = (const Object *)p_object;
- const StringName *name = (const StringName *)p_name;
- memnew_placement(dest, Signal(object, *name));
-}
-
-void GDAPI godot_signal_new_with_object_id(godot_signal *r_dest, uint64_t p_objectid, const godot_string_name *p_name) {
- Signal *dest = (Signal *)r_dest;
- const StringName *name = (const StringName *)p_name;
- memnew_placement(dest, Signal(ObjectID(p_objectid), *name));
-}
-
-void GDAPI godot_signal_new_copy(godot_signal *r_dest, const godot_signal *p_src) {
- Signal *dest = (Signal *)r_dest;
- const Signal *src = (const Signal *)p_src;
- memnew_placement(dest, Signal(*src));
-}
-
-void GDAPI godot_signal_destroy(godot_signal *p_self) {
- Signal *self = (Signal *)p_self;
- self->~Signal();
-}
-
-godot_int GDAPI godot_signal_emit(const godot_signal *p_self, const godot_variant **p_arguments, godot_int p_argcount) {
- const Signal *self = (const Signal *)p_self;
- const Variant **arguments = (const Variant **)p_arguments;
- return (godot_int)self->emit(arguments, p_argcount);
-}
-
-godot_int GDAPI godot_signal_connect(godot_signal *p_self, const godot_callable *p_callable, const godot_array *p_binds, uint32_t p_flags) {
- Signal *self = (Signal *)p_self;
- const Callable *callable = (const Callable *)p_callable;
- const Array *binds_ar = (const Array *)p_binds;
- Vector<Variant> binds;
- for (int i = 0; i < binds_ar->size(); i++) {
- binds.push_back(binds_ar->get(i));
- }
- return (godot_int)self->connect(*callable, binds, p_flags);
-}
-
-void GDAPI godot_signal_disconnect(godot_signal *p_self, const godot_callable *p_callable) {
- Signal *self = (Signal *)p_self;
- const Callable *callable = (const Callable *)p_callable;
- self->disconnect(*callable);
-}
-
-godot_bool GDAPI godot_signal_is_null(const godot_signal *p_self) {
- const Signal *self = (const Signal *)p_self;
- return self->is_null();
-}
-
-godot_bool GDAPI godot_signal_is_connected(const godot_signal *p_self, const godot_callable *p_callable) {
- const Signal *self = (const Signal *)p_self;
- const Callable *callable = (const Callable *)p_callable;
- return self->is_connected(*callable);
-}
-
-godot_array GDAPI godot_signal_get_connections(const godot_signal *p_self) {
- godot_array raw_dest;
- const Signal *self = (const Signal *)p_self;
- Array *dest = (Array *)&raw_dest;
- memnew_placement(dest, Array(self->get_connections()));
- return raw_dest;
-}
-
-godot_object GDAPI *godot_signal_get_object(const godot_signal *p_self) {
- const Signal *self = (const Signal *)p_self;
- return (godot_object *)self->get_object();
-}
-
-uint64_t GDAPI godot_signal_get_object_id(const godot_signal *p_self) {
- const Signal *self = (const Signal *)p_self;
- return (uint64_t)self->get_object_id();
-}
-
-godot_string_name GDAPI godot_signal_get_name(const godot_signal *p_self) {
- godot_string_name raw_dest;
- const Signal *self = (const Signal *)p_self;
- StringName *dest = (StringName *)&raw_dest;
- memnew_placement(dest, StringName(self->get_name()));
- return raw_dest;
-}
-
-godot_string GDAPI godot_signal_as_string(const godot_signal *p_self) {
- godot_string ret;
- const Signal *self = (const Signal *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_bool GDAPI godot_signal_operator_equal(const godot_signal *p_self, const godot_signal *p_other) {
- const Signal *self = (const Signal *)p_self;
- const Signal *other = (const Signal *)p_other;
- return *self == *other;
-}
-
-godot_bool GDAPI godot_signal_operator_less(const godot_signal *p_self, const godot_signal *p_other) {
- const Signal *self = (const Signal *)p_self;
- const Signal *other = (const Signal *)p_other;
- return *self < *other;
-}
-
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp
index a93181e142..12a800d333 100644
--- a/modules/gdnative/gdnative/color.cpp
+++ b/modules/gdnative/gdnative/color.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,178 +31,25 @@
#include "gdnative/color.h"
#include "core/math/color.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_color) == sizeof(Color), "Color size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_color) == sizeof(Color), "Color size mismatch");
-
-void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a) {
- Color *dest = (Color *)r_dest;
- *dest = Color(p_r, p_g, p_b, p_a);
-}
-
-void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b) {
- Color *dest = (Color *)r_dest;
- *dest = Color(p_r, p_g, p_b);
-}
-
-godot_real godot_color_get_r(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->r;
-}
-
-void godot_color_set_r(godot_color *p_self, const godot_real val) {
- Color *self = (Color *)p_self;
- self->r = val;
-}
-
-godot_real godot_color_get_g(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->g;
-}
-
-void godot_color_set_g(godot_color *p_self, const godot_real val) {
- Color *self = (Color *)p_self;
- self->g = val;
-}
-
-godot_real godot_color_get_b(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->b;
+void GDAPI godot_color_new(godot_color *p_self) {
+ memnew_placement(p_self, Color);
}
-void godot_color_set_b(godot_color *p_self, const godot_real val) {
+float GDAPI *godot_color_operator_index(godot_color *p_self, godot_int p_index) {
Color *self = (Color *)p_self;
- self->b = val;
-}
-
-godot_real godot_color_get_a(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->a;
-}
-
-void godot_color_set_a(godot_color *p_self, const godot_real val) {
- Color *self = (Color *)p_self;
- self->a = val;
-}
-
-godot_real godot_color_get_h(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->get_h();
-}
-
-godot_real godot_color_get_s(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->get_s();
-}
-
-godot_real godot_color_get_v(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->get_v();
-}
-
-godot_string GDAPI godot_color_as_string(const godot_color *p_self) {
- godot_string ret;
- const Color *self = (const Color *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_int GDAPI godot_color_to_rgba32(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->to_rgba32();
-}
-
-godot_int GDAPI godot_color_to_abgr32(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->to_abgr32();
-}
-
-godot_int GDAPI godot_color_to_abgr64(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->to_abgr64();
-}
-
-godot_int GDAPI godot_color_to_argb64(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->to_argb64();
-}
-
-godot_int GDAPI godot_color_to_rgba64(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->to_rgba64();
-}
-
-godot_int GDAPI godot_color_to_argb32(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->to_argb32();
-}
-
-godot_color GDAPI godot_color_inverted(const godot_color *p_self) {
- godot_color dest;
- const Color *self = (const Color *)p_self;
- *((Color *)&dest) = self->inverted();
- return dest;
-}
-
-godot_color GDAPI godot_color_lerp(const godot_color *p_self, const godot_color *p_b, const godot_real p_t) {
- godot_color dest;
- const Color *self = (const Color *)p_self;
- const Color *b = (const Color *)p_b;
- *((Color *)&dest) = self->lerp(*b, p_t);
- return dest;
-}
-
-godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over) {
- godot_color dest;
- const Color *self = (const Color *)p_self;
- const Color *over = (const Color *)p_over;
- *((Color *)&dest) = self->blend(*over);
- return dest;
-}
-
-godot_color GDAPI godot_color_darkened(const godot_color *p_self, const godot_real p_amount) {
- godot_color dest;
- const Color *self = (const Color *)p_self;
- *((Color *)&dest) = self->darkened(p_amount);
- return dest;
-}
-
-godot_color GDAPI godot_color_from_hsv(const godot_color *p_self, const godot_real p_h, const godot_real p_s, const godot_real p_v, const godot_real p_a) {
- godot_color dest;
- const Color *self = (const Color *)p_self;
- *((Color *)&dest) = self->from_hsv(p_h, p_s, p_v, p_a);
- return dest;
-}
-
-godot_color GDAPI godot_color_lightened(const godot_color *p_self, const godot_real p_amount) {
- godot_color dest;
- const Color *self = (const Color *)p_self;
- *((Color *)&dest) = self->lightened(p_amount);
- return dest;
-}
-
-godot_string GDAPI godot_color_to_html(const godot_color *p_self, const godot_bool p_with_alpha) {
- godot_string dest;
- const Color *self = (const Color *)p_self;
-
- memnew_placement(&dest, String(self->to_html(p_with_alpha)));
- return dest;
-}
-
-godot_bool GDAPI godot_color_operator_equal(const godot_color *p_self, const godot_color *p_b) {
- const Color *self = (const Color *)p_self;
- const Color *b = (const Color *)p_b;
- return *self == *b;
+ return (float *)&self->operator[](p_index);
}
-godot_bool GDAPI godot_color_operator_less(const godot_color *p_self, const godot_color *p_b) {
+const float GDAPI *godot_color_operator_index_const(const godot_color *p_self, godot_int p_index) {
const Color *self = (const Color *)p_self;
- const Color *b = (const Color *)p_b;
- return *self < *b;
+ return (const float *)&self->operator[](p_index);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp
index b6900b28bb..9fa4a27a83 100644
--- a/modules/gdnative/gdnative/dictionary.cpp
+++ b/modules/gdnative/gdnative/dictionary.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,26 +30,17 @@
#include "gdnative/dictionary.h"
-#include "core/variant/variant.h"
-// core/variant/variant.h before to avoid compile errors with MSVC
-#include "core/io/json.h"
#include "core/variant/dictionary.h"
+#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_dictionary) == sizeof(Dictionary), "Dictionary size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_dictionary) == sizeof(Dictionary), "Dictionary size mismatch");
-
-void GDAPI godot_dictionary_new(godot_dictionary *r_dest) {
- Dictionary *dest = (Dictionary *)r_dest;
- memnew_placement(dest, Dictionary);
-}
-
-void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src) {
- Dictionary *dest = (Dictionary *)r_dest;
- const Dictionary *src = (const Dictionary *)p_src;
- memnew_placement(dest, Dictionary(*src));
+void GDAPI godot_dictionary_new(godot_dictionary *p_self) {
+ memnew_placement(p_self, Dictionary);
}
void GDAPI godot_dictionary_destroy(godot_dictionary *p_self) {
@@ -57,133 +48,14 @@ void GDAPI godot_dictionary_destroy(godot_dictionary *p_self) {
self->~Dictionary();
}
-godot_dictionary GDAPI godot_dictionary_duplicate(const godot_dictionary *p_self, const godot_bool p_deep) {
- const Dictionary *self = (const Dictionary *)p_self;
- godot_dictionary res;
- Dictionary *val = (Dictionary *)&res;
- memnew_placement(val, Dictionary);
- *val = self->duplicate(p_deep);
- return res;
-}
-
-godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_self) {
- const Dictionary *self = (const Dictionary *)p_self;
- return self->size();
-}
-
-godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_self) {
- const Dictionary *self = (const Dictionary *)p_self;
- return self->empty();
-}
-
-void GDAPI godot_dictionary_clear(godot_dictionary *p_self) {
- Dictionary *self = (Dictionary *)p_self;
- self->clear();
-}
-
-godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_self, const godot_variant *p_key) {
- const Dictionary *self = (const Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- return self->has(*key);
-}
-
-godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_self, const godot_array *p_keys) {
- const Dictionary *self = (const Dictionary *)p_self;
- const Array *keys = (const Array *)p_keys;
- return self->has_all(*keys);
-}
-
-void GDAPI godot_dictionary_erase(godot_dictionary *p_self, const godot_variant *p_key) {
- Dictionary *self = (Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- self->erase(*key);
-}
-
-godot_int GDAPI godot_dictionary_hash(const godot_dictionary *p_self) {
- const Dictionary *self = (const Dictionary *)p_self;
- return self->hash();
-}
-
-godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_self) {
- godot_array dest;
- const Dictionary *self = (const Dictionary *)p_self;
- memnew_placement(&dest, Array(self->keys()));
- return dest;
-}
-
-godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_self) {
- godot_array dest;
- const Dictionary *self = (const Dictionary *)p_self;
- memnew_placement(&dest, Array(self->values()));
- return dest;
-}
-
-godot_variant GDAPI godot_dictionary_get(const godot_dictionary *p_self, const godot_variant *p_key) {
- godot_variant raw_dest;
- Variant *dest = (Variant *)&raw_dest;
- const Dictionary *self = (const Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- memnew_placement(dest, Variant(self->operator[](*key)));
- return raw_dest;
-}
-
-void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_value) {
- Dictionary *self = (Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- const Variant *value = (const Variant *)p_value;
- self->operator[](*key) = *value;
-}
-
godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key) {
Dictionary *self = (Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- return (godot_variant *)&self->operator[](*key);
+ return (godot_variant *)&self->operator[](*((const Variant *)p_key));
}
const godot_variant GDAPI *godot_dictionary_operator_index_const(const godot_dictionary *p_self, const godot_variant *p_key) {
const Dictionary *self = (const Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- return (const godot_variant *)&self->operator[](*key);
-}
-
-godot_variant GDAPI *godot_dictionary_next(const godot_dictionary *p_self, const godot_variant *p_key) {
- Dictionary *self = (Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- return (godot_variant *)self->next(key);
-}
-
-godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b) {
- const Dictionary *self = (const Dictionary *)p_self;
- const Dictionary *b = (const Dictionary *)p_b;
- return *self == *b;
-}
-
-godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self) {
- godot_string raw_dest;
- String *dest = (String *)&raw_dest;
- const Dictionary *self = (const Dictionary *)p_self;
- memnew_placement(dest, String(JSON::print(Variant(*self))));
- return raw_dest;
-}
-
-// GDNative core 1.1
-
-godot_bool GDAPI godot_dictionary_erase_with_return(godot_dictionary *p_self, const godot_variant *p_key) {
- Dictionary *self = (Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- return self->erase(*key);
-}
-
-godot_variant GDAPI godot_dictionary_get_with_default(const godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_default) {
- const Dictionary *self = (const Dictionary *)p_self;
- const Variant *key = (const Variant *)p_key;
- const Variant *def = (const Variant *)p_default;
-
- godot_variant raw_dest;
- Variant *dest = (Variant *)&raw_dest;
- memnew_placement(dest, Variant(self->get(*key, *def)));
-
- return raw_dest;
+ return (const godot_variant *)&self->operator[](*((const Variant *)p_key));
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index 4142ea892b..b84ce2d192 100644
--- a/modules/gdnative/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -99,7 +99,7 @@ godot_class_constructor GDAPI godot_get_class_constructor(const char *p_classnam
godot_dictionary GDAPI godot_get_global_constants() {
godot_dictionary constants;
- godot_dictionary_new(&constants);
+ memnew_placement(&constants, Dictionary);
Dictionary *p_constants = (Dictionary *)&constants;
const int constants_count = CoreConstants::get_global_constant_count();
for (int i = 0; i < constants_count; ++i) {
@@ -127,16 +127,15 @@ void GDAPI godot_free(void *p_ptr) {
memfree(p_ptr);
}
+// Helper print functions.
void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line) {
_err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_ERROR);
}
-
void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line) {
_err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_WARNING);
}
-
-void GDAPI godot_print(const godot_string *p_message) {
- print_line(*(String *)p_message);
+void GDAPI godot_print_script_error(const char *p_description, const char *p_function, const char *p_file, int p_line) {
+ _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_SCRIPT);
}
void _gdnative_report_version_mismatch(const godot_object *p_library, const char *p_ext, godot_gdnative_api_version p_want, godot_gdnative_api_version p_have) {
diff --git a/modules/gdnative/gdnative/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp
index c031498612..02c2f9b22b 100644
--- a/modules/gdnative/gdnative/node_path.cpp
+++ b/modules/gdnative/gdnative/node_path.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,24 +31,15 @@
#include "gdnative/node_path.h"
#include "core/string/node_path.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_node_path) == sizeof(NodePath), "NodePath size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_node_path) == sizeof(NodePath), "NodePath size mismatch");
-
-void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from) {
- NodePath *dest = (NodePath *)r_dest;
- const String *from = (const String *)p_from;
- memnew_placement(dest, NodePath(*from));
-}
-
-void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src) {
- NodePath *dest = (NodePath *)r_dest;
- const NodePath *src = (const NodePath *)p_src;
- memnew_placement(dest, NodePath(*src));
+void GDAPI godot_node_path_new(godot_node_path *p_self) {
+ memnew_placement(p_self, NodePath);
}
void GDAPI godot_node_path_destroy(godot_node_path *p_self) {
@@ -56,71 +47,6 @@ void GDAPI godot_node_path_destroy(godot_node_path *p_self) {
self->~NodePath();
}
-godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_self) {
- godot_string ret;
- const NodePath *self = (const NodePath *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_self) {
- const NodePath *self = (const NodePath *)p_self;
- return self->is_absolute();
-}
-
-godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_self) {
- const NodePath *self = (const NodePath *)p_self;
- return self->get_name_count();
-}
-
-godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_self, const godot_int p_idx) {
- godot_string dest;
- const NodePath *self = (const NodePath *)p_self;
-
- memnew_placement(&dest, String(self->get_name(p_idx)));
- return dest;
-}
-
-godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_self) {
- const NodePath *self = (const NodePath *)p_self;
- return self->get_subname_count();
-}
-
-godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_self, const godot_int p_idx) {
- godot_string dest;
- const NodePath *self = (const NodePath *)p_self;
-
- memnew_placement(&dest, String(self->get_subname(p_idx)));
- return dest;
-}
-
-godot_string GDAPI godot_node_path_get_concatenated_subnames(const godot_node_path *p_self) {
- godot_string dest;
- const NodePath *self = (const NodePath *)p_self;
- memnew_placement(&dest, String(self->get_concatenated_subnames()));
- return dest;
-}
-
-godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_self) {
- const NodePath *self = (const NodePath *)p_self;
- return self->is_empty();
-}
-
-godot_bool GDAPI godot_node_path_operator_equal(const godot_node_path *p_self, const godot_node_path *p_b) {
- const NodePath *self = (const NodePath *)p_self;
- const NodePath *b = (const NodePath *)p_b;
- return *self == *b;
-}
-
-godot_node_path godot_node_path_get_as_property_path(const godot_node_path *p_self) {
- const NodePath *self = (const NodePath *)p_self;
- godot_node_path res;
- NodePath *val = (NodePath *)&res;
- memnew_placement(val, NodePath);
- *val = self->get_as_property_path();
- return res;
-}
-
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/packed_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp
index cc1e05b8a4..63a2425b87 100644
--- a/modules/gdnative/gdnative/packed_arrays.cpp
+++ b/modules/gdnative/gdnative/packed_arrays.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,1110 +30,247 @@
#include "gdnative/packed_arrays.h"
-#include "core/variant/array.h"
-
#include "core/variant/variant.h"
-#include "core/math/color.h"
#include "core/math/vector2.h"
-#include "core/math/vector3.h"
+#include "core/math/vector3i.h"
+
+static_assert(sizeof(godot_packed_byte_array) == sizeof(PackedByteArray), "PackedByteArray size mismatch");
+static_assert(sizeof(godot_packed_int32_array) == sizeof(PackedInt32Array), "PackedInt32Array size mismatch");
+static_assert(sizeof(godot_packed_int64_array) == sizeof(PackedInt64Array), "PackedInt64Array size mismatch");
+static_assert(sizeof(godot_packed_float32_array) == sizeof(PackedFloat32Array), "PackedFloat32Array size mismatch");
+static_assert(sizeof(godot_packed_float64_array) == sizeof(PackedFloat64Array), "PackedFloat64Array size mismatch");
+static_assert(sizeof(godot_packed_string_array) == sizeof(PackedStringArray), "PackedStringArray size mismatch");
+static_assert(sizeof(godot_packed_vector2_array) == sizeof(PackedVector2Array), "PackedVector2Array size mismatch");
+static_assert(sizeof(godot_packed_vector2i_array) == sizeof(Vector<Vector2i>), "Vector<Vector2i> size mismatch");
+static_assert(sizeof(godot_packed_vector3_array) == sizeof(PackedVector3Array), "PackedVector3Array size mismatch");
+static_assert(sizeof(godot_packed_vector3i_array) == sizeof(Vector<Vector3i>), "Vector<Vector3i> size mismatch");
+static_assert(sizeof(godot_packed_color_array) == sizeof(PackedColorArray), "PackedColorArray size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_packed_byte_array) == sizeof(Vector<uint8_t>), "Vector<uint8_t> size mismatch");
-static_assert(sizeof(godot_packed_int32_array) == sizeof(Vector<int32_t>), "Vector<int32_t> size mismatch");
-static_assert(sizeof(godot_packed_int64_array) == sizeof(Vector<int64_t>), "Vector<int64_t> size mismatch");
-static_assert(sizeof(godot_packed_float32_array) == sizeof(Vector<float>), "Vector<float> size mismatch");
-static_assert(sizeof(godot_packed_float64_array) == sizeof(Vector<double>), "Vector<double> size mismatch");
-static_assert(sizeof(godot_packed_string_array) == sizeof(Vector<String>), "Vector<String> size mismatch");
-static_assert(sizeof(godot_packed_vector2_array) == sizeof(Vector<Vector2>), "Vector<Vector2> size mismatch");
-static_assert(sizeof(godot_packed_vector2i_array) == sizeof(Vector<Vector2i>), "Vector<Vector2i> size mismatch");
-static_assert(sizeof(godot_packed_vector3_array) == sizeof(Vector<Vector3>), "Vector<Vector3> size mismatch");
-static_assert(sizeof(godot_packed_color_array) == sizeof(Vector<Color>), "Vector<Color> size mismatch");
-
#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
// byte
-void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *r_dest) {
- Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest;
- memnew_placement(dest, Vector<uint8_t>);
-}
-
-void GDAPI godot_packed_byte_array_new_copy(godot_packed_byte_array *r_dest, const godot_packed_byte_array *p_src) {
- Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest;
- const Vector<uint8_t> *src = (const Vector<uint8_t> *)p_src;
- memnew_placement(dest, Vector<uint8_t>(*src));
-}
-
-void GDAPI godot_packed_byte_array_new_with_array(godot_packed_byte_array *r_dest, const godot_array *p_a) {
- Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<uint8_t>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
-}
-
-const uint8_t GDAPI *godot_packed_byte_array_ptr(const godot_packed_byte_array *p_self) {
- const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self;
- return self->ptr();
-}
-
-uint8_t GDAPI *godot_packed_byte_array_ptrw(godot_packed_byte_array *p_self) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- return self->ptrw();
-}
-
-void GDAPI godot_packed_byte_array_append(godot_packed_byte_array *p_self, const uint8_t p_data) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- self->push_back(p_data);
-}
-
-void GDAPI godot_packed_byte_array_append_array(godot_packed_byte_array *p_self, const godot_packed_byte_array *p_array) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- Vector<uint8_t> *array = (Vector<uint8_t> *)p_array;
- self->append_array(*array);
-}
-
-godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- return (godot_error)self->insert(p_idx, p_data);
-}
-
-godot_bool GDAPI godot_packed_byte_array_has(godot_packed_byte_array *p_self, const uint8_t p_value) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- return (godot_bool)self->has(p_value);
-}
-
-void GDAPI godot_packed_byte_array_sort(godot_packed_byte_array *p_self) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- self->sort();
-}
-
-void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- self->invert();
-}
-
-void GDAPI godot_packed_byte_array_push_back(godot_packed_byte_array *p_self, const uint8_t p_data) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- self->push_back(p_data);
-}
-
-void GDAPI godot_packed_byte_array_remove(godot_packed_byte_array *p_self, const godot_int p_idx) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_byte_array_resize(godot_packed_byte_array *p_self, const godot_int p_size) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_byte_array_set(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
- Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
- self->set(p_idx, p_data);
-}
-
-uint8_t GDAPI godot_packed_byte_array_get(const godot_packed_byte_array *p_self, const godot_int p_idx) {
- const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self;
- return self->get(p_idx);
-}
-
-godot_int GDAPI godot_packed_byte_array_size(const godot_packed_byte_array *p_self) {
- const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self;
- return self->size();
-}
-
-godot_bool GDAPI godot_packed_byte_array_empty(const godot_packed_byte_array *p_self) {
- const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self;
- return self->empty();
+void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *p_self) {
+ memnew_placement(p_self, PackedByteArray);
}
void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self) {
- ((Vector<uint8_t> *)p_self)->~Vector();
+ ((PackedByteArray *)p_self)->~PackedByteArray();
}
-// int32
-
-void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *r_dest) {
- Vector<int32_t> *dest = (Vector<int32_t> *)r_dest;
- memnew_placement(dest, Vector<int32_t>);
+uint8_t GDAPI *godot_packed_byte_array_operator_index(godot_packed_byte_array *p_self, godot_int p_index) {
+ PackedByteArray *self = (PackedByteArray *)p_self;
+ return (uint8_t *)&self->operator[](p_index);
}
-void GDAPI godot_packed_int32_array_new_copy(godot_packed_int32_array *r_dest, const godot_packed_int32_array *p_src) {
- Vector<int32_t> *dest = (Vector<int32_t> *)r_dest;
- const Vector<int32_t> *src = (const Vector<int32_t> *)p_src;
- memnew_placement(dest, Vector<int32_t>(*src));
+const uint8_t GDAPI *godot_packed_byte_array_operator_index_const(const godot_packed_byte_array *p_self, godot_int p_index) {
+ const PackedByteArray *self = (const PackedByteArray *)p_self;
+ return (const uint8_t *)&self->operator[](p_index);
}
-void GDAPI godot_packed_int32_array_new_with_array(godot_packed_int32_array *r_dest, const godot_array *p_a) {
- Vector<int32_t> *dest = (Vector<int32_t> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<int32_t>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
-}
-
-const int32_t GDAPI *godot_packed_int32_array_ptr(const godot_packed_int32_array *p_self) {
- const Vector<int32_t> *self = (const Vector<int32_t> *)p_self;
- return self->ptr();
-}
-
-int32_t GDAPI *godot_packed_int32_array_ptrw(godot_packed_int32_array *p_self) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- return self->ptrw();
-}
-
-void GDAPI godot_packed_int32_array_append(godot_packed_int32_array *p_self, const int32_t p_data) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- self->push_back(p_data);
-}
-
-void GDAPI godot_packed_int32_array_append_array(godot_packed_int32_array *p_self, const godot_packed_int32_array *p_array) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- Vector<int32_t> *array = (Vector<int32_t> *)p_array;
- self->append_array(*array);
-}
-
-godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- return (godot_error)self->insert(p_idx, p_data);
-}
-
-godot_bool GDAPI godot_packed_int32_array_has(godot_packed_int32_array *p_self, const int32_t p_value) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- return (godot_bool)self->has(p_value);
-}
-
-void GDAPI godot_packed_int32_array_sort(godot_packed_int32_array *p_self) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- self->sort();
-}
-
-void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- self->invert();
-}
-
-void GDAPI godot_packed_int32_array_push_back(godot_packed_int32_array *p_self, const int32_t p_data) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- self->push_back(p_data);
-}
-
-void GDAPI godot_packed_int32_array_remove(godot_packed_int32_array *p_self, const godot_int p_idx) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_int32_array_resize(godot_packed_int32_array *p_self, const godot_int p_size) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_int32_array_set(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data) {
- Vector<int32_t> *self = (Vector<int32_t> *)p_self;
- self->set(p_idx, p_data);
-}
-
-int32_t GDAPI godot_packed_int32_array_get(const godot_packed_int32_array *p_self, const godot_int p_idx) {
- const Vector<int32_t> *self = (const Vector<int32_t> *)p_self;
- return self->get(p_idx);
-}
-
-godot_int GDAPI godot_packed_int32_array_size(const godot_packed_int32_array *p_self) {
- const Vector<int32_t> *self = (const Vector<int32_t> *)p_self;
- return self->size();
-}
+// int32
-godot_bool GDAPI godot_packed_int32_array_empty(const godot_packed_int32_array *p_self) {
- const Vector<int32_t> *self = (const Vector<int32_t> *)p_self;
- return self->empty();
+void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *p_self) {
+ memnew_placement(p_self, PackedInt32Array);
}
void GDAPI godot_packed_int32_array_destroy(godot_packed_int32_array *p_self) {
- ((Vector<int32_t> *)p_self)->~Vector();
-}
-
-// int64
-
-void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *r_dest) {
- Vector<int64_t> *dest = (Vector<int64_t> *)r_dest;
- memnew_placement(dest, Vector<int64_t>);
-}
-
-void GDAPI godot_packed_int64_array_new_copy(godot_packed_int64_array *r_dest, const godot_packed_int64_array *p_src) {
- Vector<int64_t> *dest = (Vector<int64_t> *)r_dest;
- const Vector<int64_t> *src = (const Vector<int64_t> *)p_src;
- memnew_placement(dest, Vector<int64_t>(*src));
-}
-
-void GDAPI godot_packed_int64_array_new_with_array(godot_packed_int64_array *r_dest, const godot_array *p_a) {
- Vector<int64_t> *dest = (Vector<int64_t> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<int64_t>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
-}
-
-const int64_t GDAPI *godot_packed_int64_array_ptr(const godot_packed_int64_array *p_self) {
- const Vector<int64_t> *self = (const Vector<int64_t> *)p_self;
- return self->ptr();
-}
-
-int64_t GDAPI *godot_packed_int64_array_ptrw(godot_packed_int64_array *p_self) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- return self->ptrw();
+ ((PackedInt32Array *)p_self)->~PackedInt32Array();
}
-void GDAPI godot_packed_int64_array_append(godot_packed_int64_array *p_self, const int64_t p_data) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- self->push_back(p_data);
+int32_t GDAPI *godot_packed_int32_array_operator_index(godot_packed_int32_array *p_self, godot_int p_index) {
+ PackedInt32Array *self = (PackedInt32Array *)p_self;
+ return (int32_t *)&self->operator[](p_index);
}
-void GDAPI godot_packed_int64_array_append_array(godot_packed_int64_array *p_self, const godot_packed_int64_array *p_array) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- Vector<int64_t> *array = (Vector<int64_t> *)p_array;
- self->append_array(*array);
+const int32_t GDAPI *godot_packed_int32_array_operator_index_const(const godot_packed_int32_array *p_self, godot_int p_index) {
+ const PackedInt32Array *self = (const PackedInt32Array *)p_self;
+ return (const int32_t *)&self->operator[](p_index);
}
-godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- return (godot_error)self->insert(p_idx, p_data);
-}
-
-godot_bool GDAPI godot_packed_int64_array_has(godot_packed_int64_array *p_self, const int64_t p_value) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- return (godot_bool)self->has(p_value);
-}
-
-void GDAPI godot_packed_int64_array_sort(godot_packed_int64_array *p_self) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- self->sort();
-}
-
-void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- self->invert();
-}
-
-void GDAPI godot_packed_int64_array_push_back(godot_packed_int64_array *p_self, const int64_t p_data) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- self->push_back(p_data);
-}
-
-void GDAPI godot_packed_int64_array_remove(godot_packed_int64_array *p_self, const godot_int p_idx) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_int64_array_resize(godot_packed_int64_array *p_self, const godot_int p_size) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_int64_array_set(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data) {
- Vector<int64_t> *self = (Vector<int64_t> *)p_self;
- self->set(p_idx, p_data);
-}
-
-int64_t GDAPI godot_packed_int64_array_get(const godot_packed_int64_array *p_self, const godot_int p_idx) {
- const Vector<int64_t> *self = (const Vector<int64_t> *)p_self;
- return self->get(p_idx);
-}
-
-godot_int GDAPI godot_packed_int64_array_size(const godot_packed_int64_array *p_self) {
- const Vector<int64_t> *self = (const Vector<int64_t> *)p_self;
- return self->size();
-}
+// int64
-godot_bool GDAPI godot_packed_int64_array_empty(const godot_packed_int64_array *p_self) {
- const Vector<int64_t> *self = (const Vector<int64_t> *)p_self;
- return self->empty();
+void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *p_self) {
+ memnew_placement(p_self, PackedInt64Array);
}
void GDAPI godot_packed_int64_array_destroy(godot_packed_int64_array *p_self) {
- ((Vector<int64_t> *)p_self)->~Vector();
-}
-
-// float32
-
-void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *r_dest) {
- Vector<float> *dest = (Vector<float> *)r_dest;
- memnew_placement(dest, Vector<float>);
-}
-
-void GDAPI godot_packed_float32_array_new_copy(godot_packed_float32_array *r_dest, const godot_packed_float32_array *p_src) {
- Vector<float> *dest = (Vector<float> *)r_dest;
- const Vector<float> *src = (const Vector<float> *)p_src;
- memnew_placement(dest, Vector<float>(*src));
-}
-
-void GDAPI godot_packed_float32_array_new_with_array(godot_packed_float32_array *r_dest, const godot_array *p_a) {
- Vector<float> *dest = (Vector<float> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<float>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
-}
-
-const float GDAPI *godot_packed_float32_array_ptr(const godot_packed_float32_array *p_self) {
- const Vector<float> *self = (const Vector<float> *)p_self;
- return self->ptr();
-}
-
-float GDAPI *godot_packed_float32_array_ptrw(godot_packed_float32_array *p_self) {
- Vector<float> *self = (Vector<float> *)p_self;
- return self->ptrw();
-}
-
-void GDAPI godot_packed_float32_array_append(godot_packed_float32_array *p_self, const float p_data) {
- Vector<float> *self = (Vector<float> *)p_self;
- self->push_back(p_data);
-}
-
-void GDAPI godot_packed_float32_array_append_array(godot_packed_float32_array *p_self, const godot_packed_float32_array *p_array) {
- Vector<float> *self = (Vector<float> *)p_self;
- Vector<float> *array = (Vector<float> *)p_array;
- self->append_array(*array);
-}
-
-godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data) {
- Vector<float> *self = (Vector<float> *)p_self;
- return (godot_error)self->insert(p_idx, p_data);
-}
-
-godot_bool GDAPI godot_packed_float32_array_has(godot_packed_float32_array *p_self, const float p_value) {
- Vector<float> *self = (Vector<float> *)p_self;
- return (godot_bool)self->has(p_value);
-}
-
-void GDAPI godot_packed_float32_array_sort(godot_packed_float32_array *p_self) {
- Vector<float> *self = (Vector<float> *)p_self;
- self->sort();
+ ((PackedInt64Array *)p_self)->~PackedInt64Array();
}
-void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self) {
- Vector<float> *self = (Vector<float> *)p_self;
- self->invert();
+int64_t GDAPI *godot_packed_int64_array_operator_index(godot_packed_int64_array *p_self, godot_int p_index) {
+ PackedInt64Array *self = (PackedInt64Array *)p_self;
+ return (int64_t *)&self->operator[](p_index);
}
-void GDAPI godot_packed_float32_array_push_back(godot_packed_float32_array *p_self, const float p_data) {
- Vector<float> *self = (Vector<float> *)p_self;
- self->push_back(p_data);
+const int64_t GDAPI *godot_packed_int64_array_operator_index_const(const godot_packed_int64_array *p_self, godot_int p_index) {
+ const PackedInt64Array *self = (const PackedInt64Array *)p_self;
+ return (const int64_t *)&self->operator[](p_index);
}
-void GDAPI godot_packed_float32_array_remove(godot_packed_float32_array *p_self, const godot_int p_idx) {
- Vector<float> *self = (Vector<float> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_float32_array_resize(godot_packed_float32_array *p_self, const godot_int p_size) {
- Vector<float> *self = (Vector<float> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_float32_array_set(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data) {
- Vector<float> *self = (Vector<float> *)p_self;
- self->set(p_idx, p_data);
-}
-
-float GDAPI godot_packed_float32_array_get(const godot_packed_float32_array *p_self, const godot_int p_idx) {
- const Vector<float> *self = (const Vector<float> *)p_self;
- return self->get(p_idx);
-}
-
-godot_int GDAPI godot_packed_float32_array_size(const godot_packed_float32_array *p_self) {
- const Vector<float> *self = (const Vector<float> *)p_self;
- return self->size();
-}
+// float32
-godot_bool GDAPI godot_packed_float32_array_empty(const godot_packed_float32_array *p_self) {
- const Vector<float> *self = (const Vector<float> *)p_self;
- return self->empty();
+void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *p_self) {
+ memnew_placement(p_self, PackedFloat32Array);
}
void GDAPI godot_packed_float32_array_destroy(godot_packed_float32_array *p_self) {
- ((Vector<float> *)p_self)->~Vector();
-}
-
-// float64
-
-void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *r_dest) {
- Vector<double> *dest = (Vector<double> *)r_dest;
- memnew_placement(dest, Vector<double>);
-}
-
-void GDAPI godot_packed_float64_array_new_copy(godot_packed_float64_array *r_dest, const godot_packed_float64_array *p_src) {
- Vector<double> *dest = (Vector<double> *)r_dest;
- const Vector<double> *src = (const Vector<double> *)p_src;
- memnew_placement(dest, Vector<double>(*src));
-}
-
-void GDAPI godot_packed_float64_array_new_with_array(godot_packed_float64_array *r_dest, const godot_array *p_a) {
- Vector<double> *dest = (Vector<double> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<double>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
-}
-
-const double GDAPI *godot_packed_float64_array_ptr(const godot_packed_float64_array *p_self) {
- const Vector<double> *self = (const Vector<double> *)p_self;
- return self->ptr();
+ ((PackedFloat32Array *)p_self)->~PackedFloat32Array();
}
-double GDAPI *godot_packed_float64_array_ptrw(godot_packed_float64_array *p_self) {
- Vector<double> *self = (Vector<double> *)p_self;
- return self->ptrw();
+float GDAPI *godot_packed_float32_array_operator_index(godot_packed_float32_array *p_self, godot_int p_index) {
+ PackedFloat32Array *self = (PackedFloat32Array *)p_self;
+ return (float *)&self->operator[](p_index);
}
-void GDAPI godot_packed_float64_array_append(godot_packed_float64_array *p_self, const double p_data) {
- Vector<double> *self = (Vector<double> *)p_self;
- self->push_back(p_data);
+const float GDAPI *godot_packed_float32_array_operator_index_const(const godot_packed_float32_array *p_self, godot_int p_index) {
+ const PackedFloat32Array *self = (const PackedFloat32Array *)p_self;
+ return (const float *)&self->operator[](p_index);
}
-void GDAPI godot_packed_float64_array_append_array(godot_packed_float64_array *p_self, const godot_packed_float64_array *p_array) {
- Vector<double> *self = (Vector<double> *)p_self;
- Vector<double> *array = (Vector<double> *)p_array;
- self->append_array(*array);
-}
-
-godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data) {
- Vector<double> *self = (Vector<double> *)p_self;
- return (godot_error)self->insert(p_idx, p_data);
-}
-
-godot_bool GDAPI godot_packed_float64_array_has(godot_packed_float64_array *p_self, const double p_value) {
- Vector<double> *self = (Vector<double> *)p_self;
- return (godot_bool)self->has(p_value);
-}
-
-void GDAPI godot_packed_float64_array_sort(godot_packed_float64_array *p_self) {
- Vector<double> *self = (Vector<double> *)p_self;
- self->sort();
-}
-
-void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self) {
- Vector<double> *self = (Vector<double> *)p_self;
- self->invert();
-}
-
-void GDAPI godot_packed_float64_array_push_back(godot_packed_float64_array *p_self, const double p_data) {
- Vector<double> *self = (Vector<double> *)p_self;
- self->push_back(p_data);
-}
-
-void GDAPI godot_packed_float64_array_remove(godot_packed_float64_array *p_self, const godot_int p_idx) {
- Vector<double> *self = (Vector<double> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_float64_array_resize(godot_packed_float64_array *p_self, const godot_int p_size) {
- Vector<double> *self = (Vector<double> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_float64_array_set(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data) {
- Vector<double> *self = (Vector<double> *)p_self;
- self->set(p_idx, p_data);
-}
-
-double GDAPI godot_packed_float64_array_get(const godot_packed_float64_array *p_self, const godot_int p_idx) {
- const Vector<double> *self = (const Vector<double> *)p_self;
- return self->get(p_idx);
-}
-
-godot_int GDAPI godot_packed_float64_array_size(const godot_packed_float64_array *p_self) {
- const Vector<double> *self = (const Vector<double> *)p_self;
- return self->size();
-}
+// float64
-godot_bool GDAPI godot_packed_float64_array_empty(const godot_packed_float64_array *p_self) {
- const Vector<double> *self = (const Vector<double> *)p_self;
- return self->empty();
+void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *p_self) {
+ memnew_placement(p_self, PackedFloat64Array);
}
void GDAPI godot_packed_float64_array_destroy(godot_packed_float64_array *p_self) {
- ((Vector<double> *)p_self)->~Vector();
-}
-
-// string
-
-void GDAPI godot_packed_string_array_new(godot_packed_string_array *r_dest) {
- Vector<String> *dest = (Vector<String> *)r_dest;
- memnew_placement(dest, Vector<String>);
-}
-
-void GDAPI godot_packed_string_array_new_copy(godot_packed_string_array *r_dest, const godot_packed_string_array *p_src) {
- Vector<String> *dest = (Vector<String> *)r_dest;
- const Vector<String> *src = (const Vector<String> *)p_src;
- memnew_placement(dest, Vector<String>(*src));
-}
-
-void GDAPI godot_packed_string_array_new_with_array(godot_packed_string_array *r_dest, const godot_array *p_a) {
- Vector<String> *dest = (Vector<String> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<String>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
-}
-
-const godot_string GDAPI *godot_packed_string_array_ptr(const godot_packed_string_array *p_self) {
- const Vector<String> *self = (const Vector<String> *)p_self;
- return (const godot_string *)self->ptr();
-}
-
-godot_string GDAPI *godot_packed_string_array_ptrw(godot_packed_string_array *p_self) {
- Vector<String> *self = (Vector<String> *)p_self;
- return (godot_string *)self->ptrw();
-}
-
-void GDAPI godot_packed_string_array_append(godot_packed_string_array *p_self, const godot_string *p_data) {
- Vector<String> *self = (Vector<String> *)p_self;
- String &s = *(String *)p_data;
- self->push_back(s);
-}
-
-void GDAPI godot_packed_string_array_append_array(godot_packed_string_array *p_self, const godot_packed_string_array *p_array) {
- Vector<String> *self = (Vector<String> *)p_self;
- Vector<String> *array = (Vector<String> *)p_array;
- self->append_array(*array);
-}
-
-godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
- Vector<String> *self = (Vector<String> *)p_self;
- String &s = *(String *)p_data;
- return (godot_error)self->insert(p_idx, s);
-}
-
-godot_bool GDAPI godot_packed_string_array_has(godot_packed_string_array *p_self, const godot_string *p_value) {
- Vector<String> *self = (Vector<String> *)p_self;
- String &s = *(String *)p_value;
- return (godot_bool)self->has(s);
+ ((PackedFloat64Array *)p_self)->~PackedFloat64Array();
}
-void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self) {
- Vector<String> *self = (Vector<String> *)p_self;
- self->sort();
+double GDAPI *godot_packed_float64_array_operator_index(godot_packed_float64_array *p_self, godot_int p_index) {
+ PackedFloat64Array *self = (PackedFloat64Array *)p_self;
+ return (double *)&self->operator[](p_index);
}
-void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self) {
- Vector<String> *self = (Vector<String> *)p_self;
- self->invert();
+const double GDAPI *godot_packed_float64_array_operator_index_const(const godot_packed_float64_array *p_self, godot_int p_index) {
+ const PackedFloat64Array *self = (const PackedFloat64Array *)p_self;
+ return (const double *)&self->operator[](p_index);
}
-void GDAPI godot_packed_string_array_push_back(godot_packed_string_array *p_self, const godot_string *p_data) {
- Vector<String> *self = (Vector<String> *)p_self;
- String &s = *(String *)p_data;
- self->push_back(s);
-}
-
-void GDAPI godot_packed_string_array_remove(godot_packed_string_array *p_self, const godot_int p_idx) {
- Vector<String> *self = (Vector<String> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_string_array_resize(godot_packed_string_array *p_self, const godot_int p_size) {
- Vector<String> *self = (Vector<String> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_string_array_set(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
- Vector<String> *self = (Vector<String> *)p_self;
- String &s = *(String *)p_data;
- self->set(p_idx, s);
-}
-
-godot_string GDAPI godot_packed_string_array_get(const godot_packed_string_array *p_self, const godot_int p_idx) {
- const Vector<String> *self = (const Vector<String> *)p_self;
- godot_string str;
- String *s = (String *)&str;
- memnew_placement(s, String);
- *s = self->get(p_idx);
- return str;
-}
-
-godot_int GDAPI godot_packed_string_array_size(const godot_packed_string_array *p_self) {
- const Vector<String> *self = (const Vector<String> *)p_self;
- return self->size();
-}
+// string
-godot_bool GDAPI godot_packed_string_array_empty(const godot_packed_string_array *p_self) {
- const Vector<String> *self = (const Vector<String> *)p_self;
- return self->empty();
+void GDAPI godot_packed_string_array_new(godot_packed_string_array *p_self) {
+ memnew_placement(p_self, PackedStringArray);
}
void GDAPI godot_packed_string_array_destroy(godot_packed_string_array *p_self) {
- ((Vector<String> *)p_self)->~Vector();
-}
-
-// vector2
-
-void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *r_dest) {
- Vector<Vector2> *dest = (Vector<Vector2> *)r_dest;
- memnew_placement(dest, Vector<Vector2>);
-}
-
-void GDAPI godot_packed_vector2_array_new_copy(godot_packed_vector2_array *r_dest, const godot_packed_vector2_array *p_src) {
- Vector<Vector2> *dest = (Vector<Vector2> *)r_dest;
- const Vector<Vector2> *src = (const Vector<Vector2> *)p_src;
- memnew_placement(dest, Vector<Vector2>(*src));
-}
-
-void GDAPI godot_packed_vector2_array_new_with_array(godot_packed_vector2_array *r_dest, const godot_array *p_a) {
- Vector<Vector2> *dest = (Vector<Vector2> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<Vector2>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
+ ((PackedStringArray *)p_self)->~PackedStringArray();
}
-const godot_vector2 GDAPI *godot_packed_vector2_array_ptr(const godot_packed_vector2_array *p_self) {
- const Vector<Vector2> *self = (const Vector<Vector2> *)p_self;
- return (const godot_vector2 *)self->ptr();
+godot_string GDAPI *godot_packed_string_array_operator_index(godot_packed_string_array *p_self, godot_int p_index) {
+ PackedStringArray *self = (PackedStringArray *)p_self;
+ return (godot_string *)&self->operator[](p_index);
}
-godot_vector2 GDAPI *godot_packed_vector2_array_ptrw(godot_packed_vector2_array *p_self) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- return (godot_vector2 *)self->ptrw();
+const godot_string GDAPI *godot_packed_string_array_operator_index_const(const godot_packed_string_array *p_self, godot_int p_index) {
+ const PackedStringArray *self = (const PackedStringArray *)p_self;
+ return (const godot_string *)&self->operator[](p_index);
}
-void GDAPI godot_packed_vector2_array_append(godot_packed_vector2_array *p_self, const godot_vector2 *p_data) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- Vector2 &s = *(Vector2 *)p_data;
- self->push_back(s);
-}
-
-void GDAPI godot_packed_vector2_array_append_array(godot_packed_vector2_array *p_self, const godot_packed_vector2_array *p_array) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- Vector<Vector2> *array = (Vector<Vector2> *)p_array;
- self->append_array(*array);
-}
-
-godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- Vector2 &s = *(Vector2 *)p_data;
- return (godot_error)self->insert(p_idx, s);
-}
-
-godot_bool GDAPI godot_packed_vector2_array_has(godot_packed_vector2_array *p_self, const godot_vector2 *p_value) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- Vector2 &v = *(Vector2 *)p_value;
- return (godot_bool)self->has(v);
-}
-
-void GDAPI godot_packed_vector2_array_sort(godot_packed_vector2_array *p_self) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- self->sort();
-}
-
-void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- self->invert();
-}
-
-void GDAPI godot_packed_vector2_array_push_back(godot_packed_vector2_array *p_self, const godot_vector2 *p_data) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- Vector2 &s = *(Vector2 *)p_data;
- self->push_back(s);
-}
-
-void GDAPI godot_packed_vector2_array_remove(godot_packed_vector2_array *p_self, const godot_int p_idx) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_vector2_array_resize(godot_packed_vector2_array *p_self, const godot_int p_size) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_vector2_array_set(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
- Vector<Vector2> *self = (Vector<Vector2> *)p_self;
- Vector2 &s = *(Vector2 *)p_data;
- self->set(p_idx, s);
-}
-
-godot_vector2 GDAPI godot_packed_vector2_array_get(const godot_packed_vector2_array *p_self, const godot_int p_idx) {
- const Vector<Vector2> *self = (const Vector<Vector2> *)p_self;
- godot_vector2 v;
- Vector2 *s = (Vector2 *)&v;
- *s = self->get(p_idx);
- return v;
-}
-
-godot_int GDAPI godot_packed_vector2_array_size(const godot_packed_vector2_array *p_self) {
- const Vector<Vector2> *self = (const Vector<Vector2> *)p_self;
- return self->size();
-}
+// vector2
-godot_bool GDAPI godot_packed_vector2_array_empty(const godot_packed_vector2_array *p_self) {
- const Vector<Vector2> *self = (const Vector<Vector2> *)p_self;
- return self->empty();
+void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *p_self) {
+ memnew_placement(p_self, PackedVector2Array);
}
void GDAPI godot_packed_vector2_array_destroy(godot_packed_vector2_array *p_self) {
- ((Vector<Vector2> *)p_self)->~Vector();
-}
-
-// vector2i
-
-void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *r_dest) {
- Vector<Vector2i> *dest = (Vector<Vector2i> *)r_dest;
- memnew_placement(dest, Vector<Vector2i>);
-}
-
-void GDAPI godot_packed_vector2i_array_new_copy(godot_packed_vector2i_array *r_dest, const godot_packed_vector2i_array *p_src) {
- Vector<Vector2i> *dest = (Vector<Vector2i> *)r_dest;
- const Vector<Vector2i> *src = (const Vector<Vector2i> *)p_src;
- memnew_placement(dest, Vector<Vector2i>(*src));
-}
-
-void GDAPI godot_packed_vector2i_array_new_with_array(godot_packed_vector2i_array *r_dest, const godot_array *p_a) {
- Vector<Vector2i> *dest = (Vector<Vector2i> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<Vector2i>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
-}
-
-const godot_vector2i GDAPI *godot_packed_vector2i_array_ptr(const godot_packed_vector2i_array *p_self) {
- const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self;
- return (const godot_vector2i *)self->ptr();
-}
-
-godot_vector2i GDAPI *godot_packed_vector2i_array_ptrw(godot_packed_vector2i_array *p_self) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- return (godot_vector2i *)self->ptrw();
-}
-
-void GDAPI godot_packed_vector2i_array_append(godot_packed_vector2i_array *p_self, const godot_vector2i *p_data) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- Vector2i &s = *(Vector2i *)p_data;
- self->push_back(s);
+ ((PackedVector2Array *)p_self)->~PackedVector2Array();
}
-void GDAPI godot_packed_vector2i_array_append_array(godot_packed_vector2i_array *p_self, const godot_packed_vector2i_array *p_array) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- Vector<Vector2i> *array = (Vector<Vector2i> *)p_array;
- self->append_array(*array);
-}
-
-godot_error GDAPI godot_packed_vector2i_array_insert(godot_packed_vector2i_array *p_self, const godot_int p_idx, const godot_vector2i *p_data) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- Vector2i &s = *(Vector2i *)p_data;
- return (godot_error)self->insert(p_idx, s);
+godot_vector2 GDAPI *godot_packed_vector2_array_operator_index(godot_packed_vector2_array *p_self, godot_int p_index) {
+ PackedVector2Array *self = (PackedVector2Array *)p_self;
+ return (godot_vector2 *)&self->operator[](p_index);
}
-godot_bool GDAPI godot_packed_vector2i_array_has(godot_packed_vector2i_array *p_self, const godot_vector2i *p_value) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- Vector2i &v = *(Vector2i *)p_value;
- return (godot_bool)self->has(v);
-}
-
-void GDAPI godot_packed_vector2i_array_sort(godot_packed_vector2i_array *p_self) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- self->sort();
-}
-
-void GDAPI godot_packed_vector2i_array_invert(godot_packed_vector2i_array *p_self) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- self->invert();
+const godot_vector2 GDAPI *godot_packed_vector2_array_operator_index_const(const godot_packed_vector2_array *p_self, godot_int p_index) {
+ const PackedVector2Array *self = (const PackedVector2Array *)p_self;
+ return (const godot_vector2 *)&self->operator[](p_index);
}
-void GDAPI godot_packed_vector2i_array_push_back(godot_packed_vector2i_array *p_self, const godot_vector2i *p_data) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- Vector2i &s = *(Vector2i *)p_data;
- self->push_back(s);
-}
+// vector2i
-void GDAPI godot_packed_vector2i_array_remove(godot_packed_vector2i_array *p_self, const godot_int p_idx) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- self->remove(p_idx);
+void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *p_self) {
+ memnew_placement(p_self, Vector<Vector2i>);
}
-void GDAPI godot_packed_vector2i_array_resize(godot_packed_vector2i_array *p_self, const godot_int p_size) {
- Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- self->resize(p_size);
+void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_self) {
+ ((Vector<Vector2i> *)p_self)->~Vector();
}
-void GDAPI godot_packed_vector2i_array_set(godot_packed_vector2i_array *p_self, const godot_int p_idx, const godot_vector2i *p_data) {
+godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index(godot_packed_vector2i_array *p_self, godot_int p_index) {
Vector<Vector2i> *self = (Vector<Vector2i> *)p_self;
- Vector2i &s = *(Vector2i *)p_data;
- self->set(p_idx, s);
+ return (godot_vector2i *)&self->operator[](p_index);
}
-godot_vector2i GDAPI godot_packed_vector2i_array_get(const godot_packed_vector2i_array *p_self, const godot_int p_idx) {
+const godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index_const(const godot_packed_vector2i_array *p_self, godot_int p_index) {
const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self;
- godot_vector2i v;
- Vector2i *s = (Vector2i *)&v;
- *s = self->get(p_idx);
- return v;
-}
-
-godot_int GDAPI godot_packed_vector2i_array_size(const godot_packed_vector2i_array *p_self) {
- const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self;
- return self->size();
-}
-
-godot_bool GDAPI godot_packed_vector2i_array_empty(const godot_packed_vector2i_array *p_self) {
- const Vector<Vector2i> *self = (const Vector<Vector2i> *)p_self;
- return self->empty();
-}
-
-void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_self) {
- ((Vector<Vector2i> *)p_self)->~Vector();
+ return (const godot_vector2i *)&self->operator[](p_index);
}
// vector3
-void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *r_dest) {
- Vector<Vector3> *dest = (Vector<Vector3> *)r_dest;
- memnew_placement(dest, Vector<Vector3>);
-}
-
-void GDAPI godot_packed_vector3_array_new_copy(godot_packed_vector3_array *r_dest, const godot_packed_vector3_array *p_src) {
- Vector<Vector3> *dest = (Vector<Vector3> *)r_dest;
- const Vector<Vector3> *src = (const Vector<Vector3> *)p_src;
- memnew_placement(dest, Vector<Vector3>(*src));
-}
-
-void GDAPI godot_packed_vector3_array_new_with_array(godot_packed_vector3_array *r_dest, const godot_array *p_a) {
- Vector<Vector3> *dest = (Vector<Vector3> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<Vector3>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
-}
-
-const godot_vector3 GDAPI *godot_packed_vector3_array_ptr(const godot_packed_vector3_array *p_self) {
- const Vector<Vector3> *self = (const Vector<Vector3> *)p_self;
- return (const godot_vector3 *)self->ptr();
-}
-
-godot_vector3 GDAPI *godot_packed_vector3_array_ptrw(godot_packed_vector3_array *p_self) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- return (godot_vector3 *)self->ptrw();
-}
-
-void GDAPI godot_packed_vector3_array_append(godot_packed_vector3_array *p_self, const godot_vector3 *p_data) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- Vector3 &s = *(Vector3 *)p_data;
- self->push_back(s);
-}
-
-void GDAPI godot_packed_vector3_array_append_array(godot_packed_vector3_array *p_self, const godot_packed_vector3_array *p_array) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- Vector<Vector3> *array = (Vector<Vector3> *)p_array;
- self->append_array(*array);
-}
-
-godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- Vector3 &s = *(Vector3 *)p_data;
- return (godot_error)self->insert(p_idx, s);
-}
-
-godot_bool GDAPI godot_packed_vector3_array_has(godot_packed_vector3_array *p_self, const godot_vector3 *p_value) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- Vector3 &v = *(Vector3 *)p_value;
- return (godot_bool)self->has(v);
-}
-
-void GDAPI godot_packed_vector3_array_sort(godot_packed_vector3_array *p_self) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- self->sort();
-}
-
-void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- self->invert();
-}
-
-void GDAPI godot_packed_vector3_array_push_back(godot_packed_vector3_array *p_self, const godot_vector3 *p_data) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- Vector3 &s = *(Vector3 *)p_data;
- self->push_back(s);
-}
-
-void GDAPI godot_packed_vector3_array_remove(godot_packed_vector3_array *p_self, const godot_int p_idx) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_vector3_array_resize(godot_packed_vector3_array *p_self, const godot_int p_size) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_vector3_array_set(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
- Vector<Vector3> *self = (Vector<Vector3> *)p_self;
- Vector3 &s = *(Vector3 *)p_data;
- self->set(p_idx, s);
-}
-
-godot_vector3 GDAPI godot_packed_vector3_array_get(const godot_packed_vector3_array *p_self, const godot_int p_idx) {
- const Vector<Vector3> *self = (const Vector<Vector3> *)p_self;
- godot_vector3 v;
- Vector3 *s = (Vector3 *)&v;
- *s = self->get(p_idx);
- return v;
-}
-
-godot_int GDAPI godot_packed_vector3_array_size(const godot_packed_vector3_array *p_self) {
- const Vector<Vector3> *self = (const Vector<Vector3> *)p_self;
- return self->size();
-}
-
-godot_bool GDAPI godot_packed_vector3_array_empty(const godot_packed_vector3_array *p_self) {
- const Vector<Vector3> *self = (const Vector<Vector3> *)p_self;
- return self->empty();
+void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *p_self) {
+ memnew_placement(p_self, PackedVector3Array);
}
void GDAPI godot_packed_vector3_array_destroy(godot_packed_vector3_array *p_self) {
- ((Vector<Vector3> *)p_self)->~Vector();
-}
-
-// color
-
-void GDAPI godot_packed_color_array_new(godot_packed_color_array *r_dest) {
- Vector<Color> *dest = (Vector<Color> *)r_dest;
- memnew_placement(dest, Vector<Color>);
+ ((PackedVector3Array *)p_self)->~PackedVector3Array();
}
-void GDAPI godot_packed_color_array_new_copy(godot_packed_color_array *r_dest, const godot_packed_color_array *p_src) {
- Vector<Color> *dest = (Vector<Color> *)r_dest;
- const Vector<Color> *src = (const Vector<Color> *)p_src;
- memnew_placement(dest, Vector<Color>(*src));
-}
-
-void GDAPI godot_packed_color_array_new_with_array(godot_packed_color_array *r_dest, const godot_array *p_a) {
- Vector<Color> *dest = (Vector<Color> *)r_dest;
- Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<Color>);
-
- dest->resize(a->size());
- for (int i = 0; i < a->size(); i++) {
- dest->set(i, (*a)[i]);
- }
+godot_vector3 GDAPI *godot_packed_vector3_array_operator_index(godot_packed_vector3_array *p_self, godot_int p_index) {
+ PackedVector3Array *self = (PackedVector3Array *)p_self;
+ return (godot_vector3 *)&self->operator[](p_index);
}
-const godot_color GDAPI *godot_packed_color_array_ptr(const godot_packed_color_array *p_self) {
- const Vector<Color> *self = (const Vector<Color> *)p_self;
- return (const godot_color *)self->ptr();
+const godot_vector3 GDAPI *godot_packed_vector3_array_operator_index_const(const godot_packed_vector3_array *p_self, godot_int p_index) {
+ const PackedVector3Array *self = (const PackedVector3Array *)p_self;
+ return (const godot_vector3 *)&self->operator[](p_index);
}
-godot_color GDAPI *godot_packed_color_array_ptrw(godot_packed_color_array *p_self) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- return (godot_color *)self->ptrw();
-}
-
-void GDAPI godot_packed_color_array_append(godot_packed_color_array *p_self, const godot_color *p_data) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- Color &s = *(Color *)p_data;
- self->push_back(s);
-}
-
-void GDAPI godot_packed_color_array_append_array(godot_packed_color_array *p_self, const godot_packed_color_array *p_array) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- Vector<Color> *array = (Vector<Color> *)p_array;
- self->append_array(*array);
-}
+// vector3i
-godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- Color &s = *(Color *)p_data;
- return (godot_error)self->insert(p_idx, s);
+void GDAPI godot_packed_vector3i_array_new(godot_packed_vector3i_array *p_self) {
+ memnew_placement(p_self, Vector<Vector3i>);
}
-godot_bool GDAPI godot_packed_color_array_has(godot_packed_color_array *p_self, const godot_color *p_value) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- Color &c = *(Color *)p_value;
- return (godot_bool)self->has(c);
+void GDAPI godot_packed_vector3i_array_destroy(godot_packed_vector3i_array *p_self) {
+ ((Vector<Vector3i> *)p_self)->~Vector();
}
-void GDAPI godot_packed_color_array_sort(godot_packed_color_array *p_self) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- self->sort();
+godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index(godot_packed_vector3i_array *p_self, godot_int p_index) {
+ Vector<Vector3i> *self = (Vector<Vector3i> *)p_self;
+ return (godot_vector3i *)&self->operator[](p_index);
}
-void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- self->invert();
+const godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index_const(const godot_packed_vector3i_array *p_self, godot_int p_index) {
+ const Vector<Vector3i> *self = (const Vector<Vector3i> *)p_self;
+ return (const godot_vector3i *)&self->operator[](p_index);
}
-void GDAPI godot_packed_color_array_push_back(godot_packed_color_array *p_self, const godot_color *p_data) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- Color &s = *(Color *)p_data;
- self->push_back(s);
-}
-
-void GDAPI godot_packed_color_array_remove(godot_packed_color_array *p_self, const godot_int p_idx) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- self->remove(p_idx);
-}
-
-void GDAPI godot_packed_color_array_resize(godot_packed_color_array *p_self, const godot_int p_size) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- self->resize(p_size);
-}
-
-void GDAPI godot_packed_color_array_set(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
- Vector<Color> *self = (Vector<Color> *)p_self;
- Color &s = *(Color *)p_data;
- self->set(p_idx, s);
-}
+// color
-godot_color GDAPI godot_packed_color_array_get(const godot_packed_color_array *p_self, const godot_int p_idx) {
- const Vector<Color> *self = (const Vector<Color> *)p_self;
- godot_color v;
- Color *s = (Color *)&v;
- *s = self->get(p_idx);
- return v;
+void GDAPI godot_packed_color_array_new(godot_packed_color_array *p_self) {
+ memnew_placement(p_self, PackedColorArray);
}
-godot_int GDAPI godot_packed_color_array_size(const godot_packed_color_array *p_self) {
- const Vector<Color> *self = (const Vector<Color> *)p_self;
- return self->size();
+void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self) {
+ ((PackedColorArray *)p_self)->~PackedColorArray();
}
-godot_bool GDAPI godot_packed_color_array_empty(const godot_packed_color_array *p_self) {
- const Vector<Color> *self = (const Vector<Color> *)p_self;
- return self->empty();
+godot_color GDAPI *godot_packed_color_array_operator_index(godot_packed_color_array *p_self, godot_int p_index) {
+ PackedColorArray *self = (PackedColorArray *)p_self;
+ return (godot_color *)&self->operator[](p_index);
}
-void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self) {
- ((Vector<Color> *)p_self)->~Vector();
+const godot_color GDAPI *godot_packed_color_array_operator_index_const(const godot_packed_color_array *p_self, godot_int p_index) {
+ const PackedColorArray *self = (const PackedColorArray *)p_self;
+ return (const godot_color *)&self->operator[](p_index);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/plane.cpp b/modules/gdnative/gdnative/plane.cpp
index 99fb5ff10a..61d5e09fad 100644
--- a/modules/gdnative/gdnative/plane.cpp
+++ b/modules/gdnative/gdnative/plane.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,139 +31,15 @@
#include "gdnative/plane.h"
#include "core/math/plane.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_plane) == sizeof(Plane), "Plane size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_plane) == sizeof(Plane), "Plane size mismatch");
-
-void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d) {
- Plane *dest = (Plane *)r_dest;
- *dest = Plane(p_a, p_b, p_c, p_d);
-}
-
-void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3) {
- const Vector3 *v1 = (const Vector3 *)p_v1;
- const Vector3 *v2 = (const Vector3 *)p_v2;
- const Vector3 *v3 = (const Vector3 *)p_v3;
- Plane *dest = (Plane *)r_dest;
- *dest = Plane(*v1, *v2, *v3);
-}
-
-void GDAPI godot_plane_new_with_normal(godot_plane *r_dest, const godot_vector3 *p_normal, const godot_real p_d) {
- const Vector3 *normal = (const Vector3 *)p_normal;
- Plane *dest = (Plane *)r_dest;
- *dest = Plane(*normal, p_d);
-}
-
-godot_string GDAPI godot_plane_as_string(const godot_plane *p_self) {
- godot_string ret;
- const Plane *self = (const Plane *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_plane GDAPI godot_plane_normalized(const godot_plane *p_self) {
- godot_plane dest;
- const Plane *self = (const Plane *)p_self;
- *((Plane *)&dest) = self->normalized();
- return dest;
-}
-
-godot_vector3 GDAPI godot_plane_center(const godot_plane *p_self) {
- godot_vector3 dest;
- const Plane *self = (const Plane *)p_self;
- *((Vector3 *)&dest) = self->center();
- return dest;
-}
-
-godot_bool GDAPI godot_plane_is_point_over(const godot_plane *p_self, const godot_vector3 *p_point) {
- const Plane *self = (const Plane *)p_self;
- const Vector3 *point = (const Vector3 *)p_point;
- return self->is_point_over(*point);
-}
-
-godot_real GDAPI godot_plane_distance_to(const godot_plane *p_self, const godot_vector3 *p_point) {
- const Plane *self = (const Plane *)p_self;
- const Vector3 *point = (const Vector3 *)p_point;
- return self->distance_to(*point);
-}
-
-godot_bool GDAPI godot_plane_has_point(const godot_plane *p_self, const godot_vector3 *p_point, const godot_real p_epsilon) {
- const Plane *self = (const Plane *)p_self;
- const Vector3 *point = (const Vector3 *)p_point;
- return self->has_point(*point, p_epsilon);
-}
-
-godot_vector3 GDAPI godot_plane_project(const godot_plane *p_self, const godot_vector3 *p_point) {
- godot_vector3 dest;
- const Plane *self = (const Plane *)p_self;
- const Vector3 *point = (const Vector3 *)p_point;
- *((Vector3 *)&dest) = self->project(*point);
- return dest;
-}
-
-godot_bool GDAPI godot_plane_intersect_3(const godot_plane *p_self, godot_vector3 *r_dest, const godot_plane *p_b, const godot_plane *p_c) {
- const Plane *self = (const Plane *)p_self;
- const Plane *b = (const Plane *)p_b;
- const Plane *c = (const Plane *)p_c;
- Vector3 *dest = (Vector3 *)r_dest;
- return self->intersect_3(*b, *c, dest);
-}
-
-godot_bool GDAPI godot_plane_intersects_ray(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_from, const godot_vector3 *p_dir) {
- const Plane *self = (const Plane *)p_self;
- const Vector3 *from = (const Vector3 *)p_from;
- const Vector3 *dir = (const Vector3 *)p_dir;
- Vector3 *dest = (Vector3 *)r_dest;
- return self->intersects_ray(*from, *dir, dest);
-}
-
-godot_bool GDAPI godot_plane_intersects_segment(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_begin, const godot_vector3 *p_end) {
- const Plane *self = (const Plane *)p_self;
- const Vector3 *begin = (const Vector3 *)p_begin;
- const Vector3 *end = (const Vector3 *)p_end;
- Vector3 *dest = (Vector3 *)r_dest;
- return self->intersects_segment(*begin, *end, dest);
-}
-
-godot_plane GDAPI godot_plane_operator_neg(const godot_plane *p_self) {
- godot_plane raw_dest;
- Plane *dest = (Plane *)&raw_dest;
- const Plane *self = (const Plane *)p_self;
- *dest = -(*self);
- return raw_dest;
-}
-
-godot_bool GDAPI godot_plane_operator_equal(const godot_plane *p_self, const godot_plane *p_b) {
- const Plane *self = (const Plane *)p_self;
- const Plane *b = (const Plane *)p_b;
- return *self == *b;
-}
-
-void GDAPI godot_plane_set_normal(godot_plane *p_self, const godot_vector3 *p_normal) {
- Plane *self = (Plane *)p_self;
- const Vector3 *normal = (const Vector3 *)p_normal;
- self->set_normal(*normal);
-}
-
-godot_vector3 GDAPI godot_plane_get_normal(const godot_plane *p_self) {
- const Plane *self = (const Plane *)p_self;
- const Vector3 normal = self->get_normal();
- godot_vector3 *v3 = (godot_vector3 *)&normal;
- return *v3;
-}
-
-godot_real GDAPI godot_plane_get_d(const godot_plane *p_self) {
- const Plane *self = (const Plane *)p_self;
- return self->d;
-}
-
-void GDAPI godot_plane_set_d(godot_plane *p_self, const godot_real p_d) {
- Plane *self = (Plane *)p_self;
- self->d = p_d;
+void GDAPI godot_plane_new(godot_plane *p_self) {
+ memnew_placement(p_self, Plane);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp
index a41886e780..836d6390d6 100644
--- a/modules/gdnative/gdnative/quat.cpp
+++ b/modules/gdnative/gdnative/quat.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,205 +31,25 @@
#include "gdnative/quat.h"
#include "core/math/quat.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_quat) == sizeof(Quat), "Quat size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_quat) == sizeof(Quat), "Quat size mismatch");
-
-void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w) {
- Quat *dest = (Quat *)r_dest;
- *dest = Quat(p_x, p_y, p_z, p_w);
-}
-
-void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle) {
- const Vector3 *axis = (const Vector3 *)p_axis;
- Quat *dest = (Quat *)r_dest;
- *dest = Quat(*axis, p_angle);
+void GDAPI godot_quat_new(godot_quat *p_self) {
+ memnew_placement(p_self, Quat);
}
-void GDAPI godot_quat_new_with_basis(godot_quat *r_dest, const godot_basis *p_basis) {
- const Basis *basis = (const Basis *)p_basis;
- Quat *dest = (Quat *)r_dest;
- *dest = Quat(*basis);
-}
-
-void GDAPI godot_quat_new_with_euler(godot_quat *r_dest, const godot_vector3 *p_euler) {
- const Vector3 *euler = (const Vector3 *)p_euler;
- Quat *dest = (Quat *)r_dest;
- *dest = Quat(*euler);
-}
-
-godot_real GDAPI godot_quat_get_x(const godot_quat *p_self) {
- const Quat *self = (const Quat *)p_self;
- return self->x;
-}
-
-void GDAPI godot_quat_set_x(godot_quat *p_self, const godot_real val) {
- Quat *self = (Quat *)p_self;
- self->x = val;
-}
-
-godot_real GDAPI godot_quat_get_y(const godot_quat *p_self) {
- const Quat *self = (const Quat *)p_self;
- return self->y;
-}
-
-void GDAPI godot_quat_set_y(godot_quat *p_self, const godot_real val) {
+godot_real_t GDAPI *godot_quat_operator_index(godot_quat *p_self, godot_int p_index) {
Quat *self = (Quat *)p_self;
- self->y = val;
-}
-
-godot_real GDAPI godot_quat_get_z(const godot_quat *p_self) {
- const Quat *self = (const Quat *)p_self;
- return self->z;
-}
-
-void GDAPI godot_quat_set_z(godot_quat *p_self, const godot_real val) {
- Quat *self = (Quat *)p_self;
- self->z = val;
-}
-
-godot_real GDAPI godot_quat_get_w(const godot_quat *p_self) {
- const Quat *self = (const Quat *)p_self;
- return self->w;
-}
-
-void GDAPI godot_quat_set_w(godot_quat *p_self, const godot_real val) {
- Quat *self = (Quat *)p_self;
- self->w = val;
-}
-
-godot_string GDAPI godot_quat_as_string(const godot_quat *p_self) {
- godot_string ret;
- const Quat *self = (const Quat *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_real GDAPI godot_quat_length(const godot_quat *p_self) {
- const Quat *self = (const Quat *)p_self;
- return self->length();
-}
-
-godot_real GDAPI godot_quat_length_squared(const godot_quat *p_self) {
- const Quat *self = (const Quat *)p_self;
- return self->length_squared();
-}
-
-godot_quat GDAPI godot_quat_normalized(const godot_quat *p_self) {
- godot_quat dest;
- const Quat *self = (const Quat *)p_self;
- *((Quat *)&dest) = self->normalized();
- return dest;
-}
-
-godot_bool GDAPI godot_quat_is_normalized(const godot_quat *p_self) {
- const Quat *self = (const Quat *)p_self;
- return self->is_normalized();
-}
-
-godot_quat GDAPI godot_quat_inverse(const godot_quat *p_self) {
- godot_quat dest;
- const Quat *self = (const Quat *)p_self;
- *((Quat *)&dest) = self->inverse();
- return dest;
-}
-
-godot_real GDAPI godot_quat_dot(const godot_quat *p_self, const godot_quat *p_b) {
- const Quat *self = (const Quat *)p_self;
- const Quat *b = (const Quat *)p_b;
- return self->dot(*b);
+ return (godot_real_t *)&self->operator[](p_index);
}
-godot_vector3 GDAPI godot_quat_xform(const godot_quat *p_self, const godot_vector3 *p_v) {
- godot_vector3 dest;
+const godot_real_t GDAPI *godot_quat_operator_index_const(const godot_quat *p_self, godot_int p_index) {
const Quat *self = (const Quat *)p_self;
- const Vector3 *v = (const Vector3 *)p_v;
- *((Vector3 *)&dest) = self->xform(*v);
- return dest;
-}
-
-godot_quat GDAPI godot_quat_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t) {
- godot_quat dest;
- const Quat *self = (const Quat *)p_self;
- const Quat *b = (const Quat *)p_b;
- *((Quat *)&dest) = self->slerp(*b, p_t);
- return dest;
-}
-
-godot_quat GDAPI godot_quat_slerpni(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t) {
- godot_quat dest;
- const Quat *self = (const Quat *)p_self;
- const Quat *b = (const Quat *)p_b;
- *((Quat *)&dest) = self->slerpni(*b, p_t);
- return dest;
-}
-
-godot_quat GDAPI godot_quat_cubic_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_quat *p_pre_a, const godot_quat *p_post_b, const godot_real p_t) {
- godot_quat dest;
- const Quat *self = (const Quat *)p_self;
- const Quat *b = (const Quat *)p_b;
- const Quat *pre_a = (const Quat *)p_pre_a;
- const Quat *post_b = (const Quat *)p_post_b;
- *((Quat *)&dest) = self->cubic_slerp(*b, *pre_a, *post_b, p_t);
- return dest;
-}
-
-godot_quat GDAPI godot_quat_operator_multiply(const godot_quat *p_self, const godot_real p_b) {
- godot_quat raw_dest;
- Quat *dest = (Quat *)&raw_dest;
- const Quat *self = (const Quat *)p_self;
- *dest = *self * p_b;
- return raw_dest;
-}
-
-godot_quat GDAPI godot_quat_operator_add(const godot_quat *p_self, const godot_quat *p_b) {
- godot_quat raw_dest;
- Quat *dest = (Quat *)&raw_dest;
- const Quat *self = (const Quat *)p_self;
- const Quat *b = (const Quat *)p_b;
- *dest = *self + *b;
- return raw_dest;
-}
-
-godot_quat GDAPI godot_quat_operator_subtract(const godot_quat *p_self, const godot_quat *p_b) {
- godot_quat raw_dest;
- Quat *dest = (Quat *)&raw_dest;
- const Quat *self = (const Quat *)p_self;
- const Quat *b = (const Quat *)p_b;
- *dest = *self - *b;
- return raw_dest;
-}
-
-godot_quat GDAPI godot_quat_operator_divide(const godot_quat *p_self, const godot_real p_b) {
- godot_quat raw_dest;
- Quat *dest = (Quat *)&raw_dest;
- const Quat *self = (const Quat *)p_self;
- *dest = *self / p_b;
- return raw_dest;
-}
-
-godot_bool GDAPI godot_quat_operator_equal(const godot_quat *p_self, const godot_quat *p_b) {
- const Quat *self = (const Quat *)p_self;
- const Quat *b = (const Quat *)p_b;
- return *self == *b;
-}
-
-godot_quat GDAPI godot_quat_operator_neg(const godot_quat *p_self) {
- godot_quat raw_dest;
- Quat *dest = (Quat *)&raw_dest;
- const Quat *self = (const Quat *)p_self;
- *dest = -(*self);
- return raw_dest;
-}
-
-void GDAPI godot_quat_set_axis_angle(godot_quat *p_self, const godot_vector3 *p_axis, const godot_real p_angle) {
- Quat *self = (Quat *)p_self;
- const Vector3 *axis = (const Vector3 *)p_axis;
- self->set_axis_angle(*axis, p_angle);
+ return (const godot_real_t *)&self->operator[](p_index);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp
index 9897b96c09..086592ec22 100644
--- a/modules/gdnative/gdnative/rect2.cpp
+++ b/modules/gdnative/gdnative/rect2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,300 +30,21 @@
#include "gdnative/rect2.h"
-#include "core/math/transform_2d.h"
-#include "core/variant/variant.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "core/math/rect2.h"
static_assert(sizeof(godot_rect2) == sizeof(Rect2), "Rect2 size mismatch");
static_assert(sizeof(godot_rect2i) == sizeof(Rect2i), "Rect2i size mismatch");
-// Rect2
-
-void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size) {
- const Vector2 *position = (const Vector2 *)p_pos;
- const Vector2 *size = (const Vector2 *)p_size;
- Rect2 *dest = (Rect2 *)r_dest;
- *dest = Rect2(*position, *size);
-}
-
-void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height) {
- Rect2 *dest = (Rect2 *)r_dest;
- *dest = Rect2(p_x, p_y, p_width, p_height);
-}
-
-godot_string GDAPI godot_rect2_as_string(const godot_rect2 *p_self) {
- godot_string ret;
- const Rect2 *self = (const Rect2 *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_rect2i GDAPI godot_rect2_as_rect2i(const godot_rect2 *p_self) {
- godot_rect2i dest;
- const Rect2 *self = (const Rect2 *)p_self;
- *((Rect2i *)&dest) = Rect2i(*self);
- return dest;
-}
-
-godot_real GDAPI godot_rect2_get_area(const godot_rect2 *p_self) {
- const Rect2 *self = (const Rect2 *)p_self;
- return self->get_area();
-}
-
-godot_bool GDAPI godot_rect2_intersects(const godot_rect2 *p_self, const godot_rect2 *p_b) {
- const Rect2 *self = (const Rect2 *)p_self;
- const Rect2 *b = (const Rect2 *)p_b;
- return self->intersects(*b);
-}
-
-godot_bool GDAPI godot_rect2_encloses(const godot_rect2 *p_self, const godot_rect2 *p_b) {
- const Rect2 *self = (const Rect2 *)p_self;
- const Rect2 *b = (const Rect2 *)p_b;
- return self->encloses(*b);
-}
-
-godot_bool GDAPI godot_rect2_has_no_area(const godot_rect2 *p_self) {
- const Rect2 *self = (const Rect2 *)p_self;
- return self->has_no_area();
-}
-
-godot_rect2 GDAPI godot_rect2_intersection(const godot_rect2 *p_self, const godot_rect2 *p_b) {
- godot_rect2 dest;
- const Rect2 *self = (const Rect2 *)p_self;
- const Rect2 *b = (const Rect2 *)p_b;
- *((Rect2 *)&dest) = self->intersection(*b);
- return dest;
-}
-
-godot_rect2 GDAPI godot_rect2_merge(const godot_rect2 *p_self, const godot_rect2 *p_b) {
- godot_rect2 dest;
- const Rect2 *self = (const Rect2 *)p_self;
- const Rect2 *b = (const Rect2 *)p_b;
- *((Rect2 *)&dest) = self->merge(*b);
- return dest;
-}
-
-godot_bool GDAPI godot_rect2_has_point(const godot_rect2 *p_self, const godot_vector2 *p_point) {
- const Rect2 *self = (const Rect2 *)p_self;
- const Vector2 *point = (const Vector2 *)p_point;
- return self->has_point(*point);
-}
-
-godot_rect2 GDAPI godot_rect2_grow(const godot_rect2 *p_self, const godot_real p_by) {
- godot_rect2 dest;
- const Rect2 *self = (const Rect2 *)p_self;
-
- *((Rect2 *)&dest) = self->grow(p_by);
- return dest;
-}
-
-godot_rect2 GDAPI godot_rect2_grow_individual(const godot_rect2 *p_self, const godot_real p_left, const godot_real p_top, const godot_real p_right, const godot_real p_bottom) {
- godot_rect2 dest;
- const Rect2 *self = (const Rect2 *)p_self;
- *((Rect2 *)&dest) = self->grow_individual(p_left, p_top, p_right, p_bottom);
- return dest;
-}
-
-godot_rect2 GDAPI godot_rect2_grow_margin(const godot_rect2 *p_self, const godot_int p_side, const godot_real p_by) {
- godot_rect2 dest;
- const Rect2 *self = (const Rect2 *)p_self;
- *((Rect2 *)&dest) = self->grow_margin((Side)p_side, p_by);
- return dest;
-}
-
-godot_rect2 GDAPI godot_rect2_abs(const godot_rect2 *p_self) {
- godot_rect2 dest;
- const Rect2 *self = (const Rect2 *)p_self;
- *((Rect2 *)&dest) = self->abs();
- return dest;
-}
-
-godot_rect2 GDAPI godot_rect2_expand(const godot_rect2 *p_self, const godot_vector2 *p_to) {
- godot_rect2 dest;
- const Rect2 *self = (const Rect2 *)p_self;
- const Vector2 *to = (const Vector2 *)p_to;
- *((Rect2 *)&dest) = self->expand(*to);
- return dest;
-}
-
-godot_bool GDAPI godot_rect2_operator_equal(const godot_rect2 *p_self, const godot_rect2 *p_b) {
- const Rect2 *self = (const Rect2 *)p_self;
- const Rect2 *b = (const Rect2 *)p_b;
- return *self == *b;
-}
-
-godot_vector2 GDAPI godot_rect2_get_position(const godot_rect2 *p_self) {
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Rect2 *self = (const Rect2 *)p_self;
- *d = self->get_position();
- return dest;
-}
-
-godot_vector2 GDAPI godot_rect2_get_size(const godot_rect2 *p_self) {
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Rect2 *self = (const Rect2 *)p_self;
- *d = self->get_size();
- return dest;
-}
-
-void GDAPI godot_rect2_set_position(godot_rect2 *p_self, const godot_vector2 *p_pos) {
- Rect2 *self = (Rect2 *)p_self;
- const Vector2 *position = (const Vector2 *)p_pos;
- self->set_position(*position);
-}
-
-void GDAPI godot_rect2_set_size(godot_rect2 *p_self, const godot_vector2 *p_size) {
- Rect2 *self = (Rect2 *)p_self;
- const Vector2 *size = (const Vector2 *)p_size;
- self->set_size(*size);
-}
-
-// Rect2i
-
-void GDAPI godot_rect2i_new_with_position_and_size(godot_rect2i *r_dest, const godot_vector2i *p_pos, const godot_vector2i *p_size) {
- const Vector2i *position = (const Vector2i *)p_pos;
- const Vector2i *size = (const Vector2i *)p_size;
- Rect2i *dest = (Rect2i *)r_dest;
- *dest = Rect2i(*position, *size);
-}
-
-void GDAPI godot_rect2i_new(godot_rect2i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_width, const godot_int p_height) {
- Rect2i *dest = (Rect2i *)r_dest;
- *dest = Rect2i(p_x, p_y, p_width, p_height);
-}
-
-godot_string GDAPI godot_rect2i_as_string(const godot_rect2i *p_self) {
- godot_string ret;
- const Rect2i *self = (const Rect2i *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_rect2 GDAPI godot_rect2i_as_rect2(const godot_rect2i *p_self) {
- godot_rect2 dest;
- const Rect2i *self = (const Rect2i *)p_self;
- *((Rect2 *)&dest) = Rect2(*self);
- return dest;
-}
-
-godot_int GDAPI godot_rect2i_get_area(const godot_rect2i *p_self) {
- const Rect2i *self = (const Rect2i *)p_self;
- return self->get_area();
-}
-
-godot_bool GDAPI godot_rect2i_intersects(const godot_rect2i *p_self, const godot_rect2i *p_b) {
- const Rect2i *self = (const Rect2i *)p_self;
- const Rect2i *b = (const Rect2i *)p_b;
- return self->intersects(*b);
-}
-
-godot_bool GDAPI godot_rect2i_encloses(const godot_rect2i *p_self, const godot_rect2i *p_b) {
- const Rect2i *self = (const Rect2i *)p_self;
- const Rect2i *b = (const Rect2i *)p_b;
- return self->encloses(*b);
-}
-
-godot_bool GDAPI godot_rect2i_has_no_area(const godot_rect2i *p_self) {
- const Rect2i *self = (const Rect2i *)p_self;
- return self->has_no_area();
-}
-
-godot_rect2i GDAPI godot_rect2i_intersection(const godot_rect2i *p_self, const godot_rect2i *p_b) {
- godot_rect2i dest;
- const Rect2i *self = (const Rect2i *)p_self;
- const Rect2i *b = (const Rect2i *)p_b;
- *((Rect2i *)&dest) = self->intersection(*b);
- return dest;
-}
-
-godot_rect2i GDAPI godot_rect2i_merge(const godot_rect2i *p_self, const godot_rect2i *p_b) {
- godot_rect2i dest;
- const Rect2i *self = (const Rect2i *)p_self;
- const Rect2i *b = (const Rect2i *)p_b;
- *((Rect2i *)&dest) = self->merge(*b);
- return dest;
-}
-
-godot_bool GDAPI godot_rect2i_has_point(const godot_rect2i *p_self, const godot_vector2i *p_point) {
- const Rect2i *self = (const Rect2i *)p_self;
- const Vector2i *point = (const Vector2i *)p_point;
- return self->has_point(*point);
-}
-
-godot_rect2i GDAPI godot_rect2i_grow(const godot_rect2i *p_self, const godot_int p_by) {
- godot_rect2i dest;
- const Rect2i *self = (const Rect2i *)p_self;
-
- *((Rect2i *)&dest) = self->grow(p_by);
- return dest;
-}
-
-godot_rect2i GDAPI godot_rect2i_grow_individual(const godot_rect2i *p_self, const godot_int p_left, const godot_int p_top, const godot_int p_right, const godot_int p_bottom) {
- godot_rect2i dest;
- const Rect2i *self = (const Rect2i *)p_self;
- *((Rect2i *)&dest) = self->grow_individual(p_left, p_top, p_right, p_bottom);
- return dest;
-}
-
-godot_rect2i GDAPI godot_rect2i_grow_margin(const godot_rect2i *p_self, const godot_int p_side, const godot_int p_by) {
- godot_rect2i dest;
- const Rect2i *self = (const Rect2i *)p_self;
- *((Rect2i *)&dest) = self->grow_margin((Side)p_side, p_by);
- return dest;
-}
-
-godot_rect2i GDAPI godot_rect2i_abs(const godot_rect2i *p_self) {
- godot_rect2i dest;
- const Rect2i *self = (const Rect2i *)p_self;
- *((Rect2i *)&dest) = self->abs();
- return dest;
-}
-
-godot_rect2i GDAPI godot_rect2i_expand(const godot_rect2i *p_self, const godot_vector2i *p_to) {
- godot_rect2i dest;
- const Rect2i *self = (const Rect2i *)p_self;
- const Vector2i *to = (const Vector2i *)p_to;
- *((Rect2i *)&dest) = self->expand(*to);
- return dest;
-}
-
-godot_bool GDAPI godot_rect2i_operator_equal(const godot_rect2i *p_self, const godot_rect2i *p_b) {
- const Rect2i *self = (const Rect2i *)p_self;
- const Rect2i *b = (const Rect2i *)p_b;
- return *self == *b;
-}
-
-godot_vector2i GDAPI godot_rect2i_get_position(const godot_rect2i *p_self) {
- godot_vector2i dest;
- Vector2i *d = (Vector2i *)&dest;
- const Rect2i *self = (const Rect2i *)p_self;
- *d = self->get_position();
- return dest;
-}
-
-godot_vector2i GDAPI godot_rect2i_get_size(const godot_rect2i *p_self) {
- godot_vector2i dest;
- Vector2i *d = (Vector2i *)&dest;
- const Rect2i *self = (const Rect2i *)p_self;
- *d = self->get_size();
- return dest;
-}
+#ifdef __cplusplus
+extern "C" {
+#endif
-void GDAPI godot_rect2i_set_position(godot_rect2i *p_self, const godot_vector2i *p_pos) {
- Rect2i *self = (Rect2i *)p_self;
- const Vector2i *position = (const Vector2i *)p_pos;
- self->set_position(*position);
+void GDAPI godot_rect2_new(godot_rect2 *p_self) {
+ memnew_placement(p_self, Rect2);
}
-void GDAPI godot_rect2i_set_size(godot_rect2i *p_self, const godot_vector2i *p_size) {
- Rect2i *self = (Rect2i *)p_self;
- const Vector2i *size = (const Vector2i *)p_size;
- self->set_size(*size);
+void GDAPI godot_rect2i_new(godot_rect2i *p_self) {
+ memnew_placement(p_self, Rect2i);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/rid.cpp b/modules/gdnative/gdnative/rid.cpp
index 24af04558b..5cab9a21ed 100644
--- a/modules/gdnative/gdnative/rid.cpp
+++ b/modules/gdnative/gdnative/rid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,45 +30,17 @@
#include "gdnative/rid.h"
-#include "core/io/resource.h"
+#include "core/os/memory.h"
#include "core/templates/rid.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_rid) == sizeof(RID), "RID size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_rid) == sizeof(RID), "RID size mismatch");
-
-void GDAPI godot_rid_new(godot_rid *r_dest) {
- RID *dest = (RID *)r_dest;
- memnew_placement(dest, RID);
-}
-
-godot_int GDAPI godot_rid_get_id(const godot_rid *p_self) {
- const RID *self = (const RID *)p_self;
- return self->get_id();
-}
-
-void GDAPI godot_rid_new_with_resource(godot_rid *r_dest, const godot_object *p_from) {
- const Resource *res_from = Object::cast_to<Resource>((Object *)p_from);
- godot_rid_new(r_dest);
- if (res_from) {
- RID *dest = (RID *)r_dest;
- *dest = RID(res_from->get_rid());
- }
-}
-
-godot_bool GDAPI godot_rid_operator_equal(const godot_rid *p_self, const godot_rid *p_b) {
- const RID *self = (const RID *)p_self;
- const RID *b = (const RID *)p_b;
- return *self == *b;
-}
-
-godot_bool GDAPI godot_rid_operator_less(const godot_rid *p_self, const godot_rid *p_b) {
- const RID *self = (const RID *)p_self;
- const RID *b = (const RID *)p_b;
- return *self < *b;
+void GDAPI godot_rid_new(godot_rid *p_self) {
+ memnew_placement(p_self, RID);
}
#ifdef __cplusplus
diff --git a/modules/gamecenter/game_center_module.cpp b/modules/gdnative/gdnative/signal.cpp
index 6c5157345f..bcb4c93b62 100644
--- a/modules/gamecenter/game_center_module.cpp
+++ b/modules/gdnative/gdnative/signal.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* game_center_module.cpp */
+/* signal.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,21 +28,26 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "game_center_module.h"
+#include "gdnative/signal.h"
-#include "core/config/engine.h"
+#include "core/variant/callable.h"
+#include "core/variant/variant.h"
-#include "game_center.h"
+static_assert(sizeof(godot_signal) == sizeof(Signal), "Signal size mismatch");
-GameCenter *game_center;
+#ifdef __cplusplus
+extern "C" {
+#endif
-void register_gamecenter_types() {
- game_center = memnew(GameCenter);
- Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center));
+void GDAPI godot_signal_new(godot_signal *p_self) {
+ memnew_placement(p_self, Signal);
}
-void unregister_gamecenter_types() {
- if (game_center) {
- memdelete(game_center);
- }
+void GDAPI godot_signal_destroy(godot_signal *p_self) {
+ Signal *self = (Signal *)p_self;
+ self->~Signal();
}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 47c7f7b6e7..19d95f2048 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,57 +30,15 @@
#include "gdnative/string.h"
-#include "core/string/string_name.h"
#include "core/string/ustring.h"
-#include "core/variant/variant.h"
-#include <string.h>
+static_assert(sizeof(godot_string) == sizeof(String), "String size mismatch");
+static_assert(sizeof(godot_char_type) == sizeof(char32_t), "char32_t size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_char16_string) == sizeof(Char16String), "Char16String size mismatch");
-static_assert(sizeof(godot_char_string) == sizeof(CharString), "CharString size mismatch");
-static_assert(sizeof(godot_string) == sizeof(String), "String size mismatch");
-static_assert(sizeof(godot_char_type) == sizeof(char32_t), "char32_t size mismatch");
-
-godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs) {
- const CharString *cs = (const CharString *)p_cs;
-
- return cs->length();
-}
-
-const char GDAPI *godot_char_string_get_data(const godot_char_string *p_cs) {
- const CharString *cs = (const CharString *)p_cs;
-
- return cs->get_data();
-}
-
-void GDAPI godot_char_string_destroy(godot_char_string *p_cs) {
- CharString *cs = (CharString *)p_cs;
-
- cs->~CharString();
-}
-
-godot_int GDAPI godot_char16_string_length(const godot_char16_string *p_cs) {
- const Char16String *cs = (const Char16String *)p_cs;
-
- return cs->length();
-}
-
-const char16_t GDAPI *godot_char16_string_get_data(const godot_char16_string *p_cs) {
- const Char16String *cs = (const Char16String *)p_cs;
-
- return cs->get_data();
-}
-
-void GDAPI godot_char16_string_destroy(godot_char16_string *p_cs) {
- Char16String *cs = (Char16String *)p_cs;
-
- cs->~Char16String();
-}
-
void GDAPI godot_string_new(godot_string *r_dest) {
String *dest = (String *)r_dest;
memnew_placement(dest, String);
@@ -167,1206 +125,11 @@ void GDAPI godot_string_new_with_wide_chars_and_len(godot_string *r_dest, const
}
}
-const godot_char_type GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx) {
- String *self = (String *)p_self;
- return &(self->operator[](p_idx));
-}
-
-godot_char_type GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx) {
- const String *self = (const String *)p_self;
- return self->operator[](p_idx);
-}
-
-const godot_char_type GDAPI *godot_string_get_data(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- return self->get_data();
-}
-
-godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b) {
- const String *self = (const String *)p_self;
- const String *b = (const String *)p_b;
- return *self == *b;
-}
-
-godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b) {
- const String *self = (const String *)p_self;
- const String *b = (const String *)p_b;
- return *self < *b;
-}
-
-godot_string GDAPI godot_string_operator_plus(const godot_string *p_self, const godot_string *p_b) {
- godot_string ret;
- const String *self = (const String *)p_self;
- const String *b = (const String *)p_b;
- memnew_placement(&ret, String(*self + *b));
- return ret;
-}
-
void GDAPI godot_string_destroy(godot_string *p_self) {
String *self = (String *)p_self;
self->~String();
}
-/* Standard size stuff */
-
-godot_int GDAPI godot_string_length(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->length();
-}
-
-/* Helpers */
-
-signed char GDAPI godot_string_casecmp_to(const godot_string *p_self, const godot_string *p_str) {
- const String *self = (const String *)p_self;
- const String *str = (const String *)p_str;
-
- return self->casecmp_to(*str);
-}
-
-signed char GDAPI godot_string_nocasecmp_to(const godot_string *p_self, const godot_string *p_str) {
- const String *self = (const String *)p_self;
- const String *str = (const String *)p_str;
-
- return self->nocasecmp_to(*str);
-}
-
-signed char GDAPI godot_string_naturalnocasecmp_to(const godot_string *p_self, const godot_string *p_str) {
- const String *self = (const String *)p_self;
- const String *str = (const String *)p_str;
-
- return self->naturalnocasecmp_to(*str);
-}
-
-godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string) {
- const String *self = (const String *)p_self;
- const String *string = (const String *)p_string;
-
- return self->begins_with(*string);
-}
-
-godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self, const char *p_char_array) {
- const String *self = (const String *)p_self;
-
- return self->begins_with(p_char_array);
-}
-
-godot_packed_string_array GDAPI godot_string_bigrams(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_packed_string_array ret;
- memnew_placement(&ret, Vector<String>(self->bigrams()));
- return ret;
-};
-
-godot_string GDAPI godot_string_chr(godot_char_type p_character) {
- godot_string result;
- memnew_placement(&result, String(String::chr(p_character)));
-
- return result;
-}
-
-godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string) {
- const String *self = (const String *)p_self;
- const String *string = (const String *)p_string;
-
- return self->ends_with(*string);
-}
-
-godot_bool GDAPI godot_string_ends_with_char_array(const godot_string *p_self, const char *p_char_array) {
- const String *self = (const String *)p_self;
-
- return self->ends_with(p_char_array);
-}
-
-godot_int GDAPI godot_string_count(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->count(*what, p_from, p_to);
-}
-
-godot_int GDAPI godot_string_countn(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->countn(*what, p_from, p_to);
-}
-
-godot_int GDAPI godot_string_find(const godot_string *p_self, const godot_string *p_what) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->find(*what);
-}
-
-godot_int GDAPI godot_string_find_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->find(*what, p_from);
-}
-
-godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_packed_string_array *p_keys) {
- const String *self = (const String *)p_self;
- const Vector<String> *keys = (const Vector<String> *)p_keys;
- return self->findmk(*keys);
-}
-
-godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from) {
- const String *self = (const String *)p_self;
- const Vector<String> *keys = (const Vector<String> *)p_keys;
- return self->findmk(*keys, p_from);
-}
-
-godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from, godot_int *r_key) {
- const String *self = (const String *)p_self;
- const Vector<String> *keys = (const Vector<String> *)p_keys;
- int key;
- int ret = self->findmk(*keys, p_from, &key);
- if (r_key) {
- *r_key = key;
- }
- return ret;
-}
-
-godot_int GDAPI godot_string_findn(const godot_string *p_self, const godot_string *p_what) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->findn(*what);
-}
-
-godot_int GDAPI godot_string_findn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->findn(*what, p_from);
-}
-
-godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values) {
- const String *self = (const String *)p_self;
- const Variant *values = (const Variant *)p_values;
- godot_string result;
- memnew_placement(&result, String(self->format(*values)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder) {
- const String *self = (const String *)p_self;
- const Variant *values = (const Variant *)p_values;
- String placeholder = String(p_placeholder);
- godot_string result;
- memnew_placement(&result, String(self->format(*values, placeholder)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len) {
- godot_string result;
- memnew_placement(&result, String(String::hex_encode_buffer(p_buffer, p_len)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, const godot_string *p_string) {
- const String *self = (const String *)p_self;
- const String *content = (const String *)p_string;
- godot_string result;
- memnew_placement(&result, String(self->insert(p_at_pos, *content)));
-
- return result;
-}
-
-godot_bool GDAPI godot_string_is_numeric(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_numeric();
-}
-
-godot_bool GDAPI godot_string_is_subsequence_of(const godot_string *p_self, const godot_string *p_string) {
- const String *self = (const String *)p_self;
- const String *string = (const String *)p_string;
-
- return self->is_subsequence_of(*string);
-}
-
-godot_bool GDAPI godot_string_is_subsequence_ofi(const godot_string *p_self, const godot_string *p_string) {
- const String *self = (const String *)p_self;
- const String *string = (const String *)p_string;
-
- return self->is_subsequence_ofi(*string);
-}
-
-godot_string GDAPI godot_string_lpad(const godot_string *p_self, godot_int p_min_length) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->lpad(p_min_length)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_lpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character) {
- const String *self = (const String *)p_self;
- const String *character = (const String *)p_character;
- godot_string result;
- memnew_placement(&result, String(self->lpad(p_min_length, *character)));
-
- return result;
-}
-
-godot_bool GDAPI godot_string_match(const godot_string *p_self, const godot_string *p_wildcard) {
- const String *self = (const String *)p_self;
- const String *wildcard = (const String *)p_wildcard;
-
- return self->match(*wildcard);
-}
-
-godot_bool GDAPI godot_string_matchn(const godot_string *p_self, const godot_string *p_wildcard) {
- const String *self = (const String *)p_self;
- const String *wildcard = (const String *)p_wildcard;
-
- return self->matchn(*wildcard);
-}
-
-godot_string GDAPI godot_string_md5(const uint8_t *p_md5) {
- godot_string result;
- memnew_placement(&result, String(String::md5(p_md5)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_num(double p_num) {
- godot_string result;
- memnew_placement(&result, String(String::num(p_num)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_num_int64(int64_t p_num, godot_int p_base) {
- godot_string result;
- memnew_placement(&result, String(String::num_int64(p_num, p_base)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_num_int64_capitalized(int64_t p_num, godot_int p_base, godot_bool p_capitalize_hex) {
- godot_string result;
- memnew_placement(&result, String(String::num_int64(p_num, p_base, true)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_num_real(double p_num) {
- godot_string result;
- memnew_placement(&result, String(String::num_real(p_num)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_num_scientific(double p_num) {
- godot_string result;
- memnew_placement(&result, String(String::num_scientific(p_num)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_num_with_decimals(double p_num, godot_int p_decimals) {
- godot_string result;
- memnew_placement(&result, String(String::num(p_num, p_decimals)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_pad_decimals(const godot_string *p_self, godot_int p_digits) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->pad_decimals(p_digits)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_pad_zeros(const godot_string *p_self, godot_int p_digits) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->pad_zeros(p_digits)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_replace(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) {
- const String *self = (const String *)p_self;
- const String *key = (const String *)p_key;
- const String *with = (const String *)p_with;
- godot_string result;
- memnew_placement(&result, String(self->replace(*key, *with)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_replacen(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) {
- const String *self = (const String *)p_self;
- const String *key = (const String *)p_key;
- const String *with = (const String *)p_with;
- godot_string result;
- memnew_placement(&result, String(self->replacen(*key, *with)));
-
- return result;
-}
-
-godot_int GDAPI godot_string_rfind(const godot_string *p_self, const godot_string *p_what) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->rfind(*what);
-}
-
-godot_int GDAPI godot_string_rfindn(const godot_string *p_self, const godot_string *p_what) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->rfindn(*what);
-}
-
-godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->rfind(*what, p_from);
-}
-
-godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from) {
- const String *self = (const String *)p_self;
- const String *what = (const String *)p_what;
-
- return self->rfindn(*what, p_from);
-}
-
-godot_string GDAPI godot_string_replace_first(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with) {
- const String *self = (const String *)p_self;
- const String *key = (const String *)p_key;
- const String *with = (const String *)p_with;
- godot_string result;
- memnew_placement(&result, String(self->replace_first(*key, *with)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_rpad(const godot_string *p_self, godot_int p_min_length) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->rpad(p_min_length)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_rpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character) {
- const String *self = (const String *)p_self;
- const String *character = (const String *)p_character;
- godot_string result;
- memnew_placement(&result, String(self->rpad(p_min_length, *character)));
-
- return result;
-}
-
-godot_real GDAPI godot_string_similarity(const godot_string *p_self, const godot_string *p_string) {
- const String *self = (const String *)p_self;
- const String *string = (const String *)p_string;
-
- return self->similarity(*string);
-}
-
-godot_string GDAPI godot_string_sprintf(const godot_string *p_self, const godot_array *p_values, godot_bool *p_error) {
- const String *self = (const String *)p_self;
- const Array *values = (const Array *)p_values;
-
- godot_string result;
- String return_value = self->sprintf(*values, p_error);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_substr(const godot_string *p_self, godot_int p_from, godot_int p_chars) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->substr(p_from, p_chars)));
-
- return result;
-}
-
-godot_int GDAPI godot_string_to_int(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->to_int();
-}
-
-double GDAPI godot_string_to_float(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->to_float();
-}
-
-godot_string GDAPI godot_string_capitalize(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->capitalize()));
-
- return result;
-}
-
-godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->camelcase_to_underscore(false)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->camelcase_to_underscore()));
-
- return result;
-}
-
-double GDAPI godot_string_char_to_float(const char *p_what) {
- return String::to_float(p_what);
-}
-
-double GDAPI godot_string_wchar_to_float(const wchar_t *p_str, const wchar_t **r_end) {
- return String::to_float(p_str, r_end);
-}
-
-godot_int GDAPI godot_string_char_to_int(const char *p_what) {
- return String::to_int(p_what);
-}
-
-godot_int GDAPI godot_string_wchar_to_int(const wchar_t *p_str) {
- return String::to_int(p_str);
-}
-
-godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int p_len) {
- return String::to_int(p_what, p_len);
-}
-
-godot_int GDAPI godot_string_wchar_to_int_with_len(const wchar_t *p_str, int p_len) {
- return String::to_int(p_str, p_len);
-}
-
-godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->hex_to_int(false);
-}
-
-godot_int GDAPI godot_string_hex_to_int_with_prefix(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->hex_to_int();
-}
-
-godot_string GDAPI godot_string_get_slice(const godot_string *p_self, const godot_string *p_splitter, godot_int p_slice) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
- godot_string result;
- memnew_placement(&result, String(self->get_slice(*splitter, p_slice)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, godot_char_type p_splitter, godot_int p_slice) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->get_slicec(p_splitter, p_slice)));
-
- return result;
-}
-
-godot_packed_string_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
- godot_packed_string_array ret;
- memnew_placement(&ret, Vector<String>(self->split(*splitter, false)));
- return ret;
-}
-
-godot_packed_string_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
- godot_packed_string_array ret;
- memnew_placement(&ret, Vector<String>(self->split(*splitter, true)));
- return ret;
-}
-
-godot_packed_string_array GDAPI godot_string_split_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
- godot_packed_string_array ret;
- memnew_placement(&ret, Vector<String>(self->split(*splitter, p_allow_empty, p_maxsplit)));
- return ret;
-}
-
-godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
-
- godot_packed_string_array ret;
- memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, false)));
- return ret;
-}
-
-godot_packed_string_array GDAPI godot_string_rsplit_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
-
- godot_packed_string_array ret;
- memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, true)));
- return ret;
-}
-
-godot_packed_string_array GDAPI godot_string_rsplit_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
-
- godot_packed_string_array ret;
- memnew_placement(&ret, Vector<String>(self->rsplit(*splitter, p_allow_empty, p_maxsplit)));
- return ret;
-}
-
-godot_packed_float32_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
-
- godot_packed_float32_array ret;
- memnew_placement(&ret, Vector<float>(self->split_floats(*splitter, false)));
- return ret;
-}
-
-godot_packed_float32_array GDAPI godot_string_split_floats_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
-
- godot_packed_float32_array ret;
- memnew_placement(&ret, Vector<float>(self->split_floats(*splitter, true)));
- return ret;
-}
-
-godot_packed_float32_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters) {
- const String *self = (const String *)p_self;
- const Vector<String> *splitters = (const Vector<String> *)p_splitters;
-
- godot_packed_float32_array ret;
- memnew_placement(&ret, Vector<float>(self->split_floats_mk(*splitters, false)));
- return ret;
-}
-
-godot_packed_float32_array GDAPI godot_string_split_floats_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters) {
- const String *self = (const String *)p_self;
- const Vector<String> *splitters = (const Vector<String> *)p_splitters;
-
- godot_packed_float32_array ret;
- memnew_placement(&ret, Vector<float>(self->split_floats_mk(*splitters, true)));
- return ret;
-}
-
-godot_packed_int32_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
-
- godot_packed_int32_array ret;
- memnew_placement(&ret, Vector<int>(self->split_ints(*splitter, false)));
- return ret;
-}
-
-godot_packed_int32_array GDAPI godot_string_split_ints_allow_empty(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
-
- godot_packed_int32_array ret;
- memnew_placement(&ret, Vector<int>(self->split_ints(*splitter, true)));
- return ret;
-}
-
-godot_packed_int32_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters) {
- const String *self = (const String *)p_self;
- const Vector<String> *splitters = (const Vector<String> *)p_splitters;
-
- godot_packed_int32_array ret;
- memnew_placement(&ret, Vector<int>(self->split_ints_mk(*splitters, false)));
- return ret;
-}
-
-godot_packed_int32_array GDAPI godot_string_split_ints_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters) {
- const String *self = (const String *)p_self;
- const Vector<String> *splitters = (const Vector<String> *)p_splitters;
-
- godot_packed_int32_array ret;
- memnew_placement(&ret, Vector<int>(self->split_ints_mk(*splitters, true)));
- return ret;
-}
-
-godot_packed_string_array GDAPI godot_string_split_spaces(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- godot_packed_string_array ret;
- memnew_placement(&ret, Vector<String>(self->split_spaces()));
- return ret;
-}
-
-godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, const godot_string *p_splitter) {
- const String *self = (const String *)p_self;
- const String *splitter = (const String *)p_splitter;
-
- return self->get_slice_count(*splitter);
-}
-
-godot_char_type GDAPI godot_string_char_lowercase(godot_char_type p_char) {
- return String::char_lowercase(p_char);
-}
-
-godot_char_type GDAPI godot_string_char_uppercase(godot_char_type p_char) {
- return String::char_uppercase(p_char);
-}
-
-godot_string GDAPI godot_string_to_lower(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->to_lower()));
-
- return result;
-}
-
-godot_string GDAPI godot_string_to_upper(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->to_upper()));
-
- return result;
-}
-
-godot_string GDAPI godot_string_get_basename(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->get_basename()));
-
- return result;
-}
-
-godot_string GDAPI godot_string_get_extension(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->get_extension()));
-
- return result;
-}
-
-godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->left(p_pos)));
-
- return result;
-}
-
-godot_char_type GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx) {
- const String *self = (const String *)p_self;
-
- return self->ord_at(p_idx);
-}
-
-godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godot_string *p_file) {
- const String *self = (const String *)p_self;
- const String *file = (const String *)p_file;
- godot_string result;
- memnew_placement(&result, String(self->plus_file(*file)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_pos) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->right(p_pos)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_repeat(const godot_string *p_self, godot_int p_count) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->repeat(p_count)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->strip_edges(p_left, p_right)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->strip_escapes()));
-
- return result;
-}
-
-void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars) {
- String *self = (String *)p_self;
-
- return self->erase(p_pos, p_chars);
-}
-
-godot_char_string GDAPI godot_string_ascii(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_char_string result;
-
- memnew_placement(&result, CharString(self->ascii()));
-
- return result;
-}
-
-godot_char_string GDAPI godot_string_latin1(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- godot_char_string result;
-
- memnew_placement(&result, CharString(self->ascii(true)));
-
- return result;
-}
-
-godot_char_string GDAPI godot_string_utf8(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- godot_char_string result;
-
- memnew_placement(&result, CharString(self->utf8()));
-
- return result;
-}
-
-godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8) {
- String *self = (String *)p_self;
-
- return self->parse_utf8(p_utf8);
-}
-
-godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len) {
- String *self = (String *)p_self;
-
- return self->parse_utf8(p_utf8, p_len);
-}
-
-godot_string GDAPI godot_string_chars_to_utf8(const char *p_utf8) {
- godot_string result;
- memnew_placement(&result, String(String::utf8(p_utf8)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_chars_to_utf8_with_len(const char *p_utf8, godot_int p_len) {
- godot_string result;
- memnew_placement(&result, String(String::utf8(p_utf8, p_len)));
-
- return result;
-}
-
-godot_char16_string GDAPI godot_string_utf16(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- godot_char16_string result;
-
- memnew_placement(&result, Char16String(self->utf16()));
-
- return result;
-}
-
-godot_bool GDAPI godot_string_parse_utf16(godot_string *p_self, const char16_t *p_utf16) {
- String *self = (String *)p_self;
-
- return self->parse_utf16(p_utf16);
-}
-
-godot_bool GDAPI godot_string_parse_utf16_with_len(godot_string *p_self, const char16_t *p_utf16, godot_int p_len) {
- String *self = (String *)p_self;
-
- return self->parse_utf16(p_utf16, p_len);
-}
-
-godot_string GDAPI godot_string_chars_to_utf16(const char16_t *p_utf16) {
- godot_string result;
- memnew_placement(&result, String(String::utf16(p_utf16)));
-
- return result;
-}
-
-godot_string GDAPI godot_string_chars_to_utf16_with_len(const char16_t *p_utf16, godot_int p_len) {
- godot_string result;
- memnew_placement(&result, String(String::utf16(p_utf16, p_len)));
-
- return result;
-}
-
-uint32_t GDAPI godot_string_hash(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->hash();
-}
-
-uint64_t GDAPI godot_string_hash64(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->hash64();
-}
-
-uint32_t GDAPI godot_string_hash_chars(const char *p_cstr) {
- return String::hash(p_cstr);
-}
-
-uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len) {
- return String::hash(p_cstr, p_len);
-}
-
-uint32_t GDAPI godot_string_hash_wide_chars(const wchar_t *p_str) {
- return String::hash(p_str);
-}
-
-uint32_t GDAPI godot_string_hash_wide_chars_with_len(const wchar_t *p_str, godot_int p_len) {
- return String::hash(p_str, p_len);
-}
-
-godot_packed_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_packed_byte_array result;
- memnew_placement(&result, PackedByteArray(self->md5_buffer()));
- return result;
-}
-
-godot_string GDAPI godot_string_md5_text(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->md5_text()));
-
- return result;
-}
-
-godot_packed_byte_array GDAPI godot_string_sha1_buffer(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_packed_byte_array result;
- memnew_placement(&result, PackedByteArray(self->sha1_buffer()));
- return result;
-}
-
-godot_string GDAPI godot_string_sha1_text(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->sha1_text()));
-
- return result;
-}
-
-godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_packed_byte_array result;
- memnew_placement(&result, PackedByteArray(self->sha256_buffer()));
- return result;
-}
-
-godot_string GDAPI godot_string_sha256_text(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- memnew_placement(&result, String(self->sha256_text()));
-
- return result;
-}
-
-godot_bool godot_string_empty(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->empty();
-}
-
-// path functions
-godot_string GDAPI godot_string_get_base_dir(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->get_base_dir();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_get_file(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->get_file();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_humanize_size(size_t p_size) {
- godot_string result;
- String return_value = String::humanize_size(p_size);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_bool GDAPI godot_string_is_abs_path(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_abs_path();
-}
-
-godot_bool GDAPI godot_string_is_rel_path(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_rel_path();
-}
-
-godot_bool GDAPI godot_string_is_resource_file(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_resource_file();
-}
-
-godot_string GDAPI godot_string_path_to(const godot_string *p_self, const godot_string *p_path) {
- const String *self = (const String *)p_self;
- String *path = (String *)p_path;
- godot_string result;
- String return_value = self->path_to(*path);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_path_to_file(const godot_string *p_self, const godot_string *p_path) {
- const String *self = (const String *)p_self;
- String *path = (String *)p_path;
- godot_string result;
- String return_value = self->path_to_file(*path);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_simplify_path(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->simplify_path();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_c_escape(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->c_escape();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->c_escape_multiline();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_c_unescape(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->c_unescape();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_http_escape(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->http_escape();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_http_unescape(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->http_unescape();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_json_escape(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->json_escape();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_xml_escape(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->xml_escape();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->xml_escape(true);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->xml_unescape();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_percent_decode(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->percent_decode();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_percent_encode(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->percent_encode();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_join(const godot_string *p_self, const godot_packed_string_array *p_parts) {
- const String *self = (const String *)p_self;
- const Vector<String> *parts = (const Vector<String> *)p_parts;
- godot_string result;
- String return_value = self->join(*parts);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_bool GDAPI godot_string_is_valid_filename(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_valid_filename();
-}
-
-godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_valid_float();
-}
-
-godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix) {
- const String *self = (const String *)p_self;
-
- return self->is_valid_hex_number(p_with_prefix);
-}
-
-godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_valid_html_color();
-}
-
-godot_bool GDAPI godot_string_is_valid_identifier(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_valid_identifier();
-}
-
-godot_bool GDAPI godot_string_is_valid_integer(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_valid_integer();
-}
-
-godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self) {
- const String *self = (const String *)p_self;
-
- return self->is_valid_ip_address();
-}
-
-godot_string GDAPI godot_string_dedent(const godot_string *p_self) {
- const String *self = (const String *)p_self;
- godot_string result;
- String return_value = self->dedent();
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_trim_prefix(const godot_string *p_self, const godot_string *p_prefix) {
- const String *self = (const String *)p_self;
- String *prefix = (String *)p_prefix;
- godot_string result;
- String return_value = self->trim_prefix(*prefix);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const godot_string *p_suffix) {
- const String *self = (const String *)p_self;
- String *suffix = (String *)p_suffix;
- godot_string result;
- String return_value = self->trim_suffix(*suffix);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_lstrip(const godot_string *p_self, const godot_string *p_chars) {
- const String *self = (const String *)p_self;
- String *chars = (String *)p_chars;
- godot_string result;
- String return_value = self->lstrip(*chars);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
-godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars) {
- const String *self = (const String *)p_self;
- String *chars = (String *)p_chars;
- godot_string result;
- String return_value = self->rstrip(*chars);
- memnew_placement(&result, String(return_value));
-
- return result;
-}
-
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp
index a840d74e18..c9d2dd5bc3 100644
--- a/modules/gdnative/gdnative/string_name.cpp
+++ b/modules/gdnative/gdnative/string_name.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,54 +31,27 @@
#include "gdnative/string_name.h"
#include "core/string/string_name.h"
-#include "core/string/ustring.h"
-#include <string.h>
+static_assert(sizeof(godot_string_name) == sizeof(StringName), "StringName size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_string_name) == sizeof(StringName), "StringName size mismatch");
-
-void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name) {
+void GDAPI godot_string_name_new(godot_string_name *r_dest) {
StringName *dest = (StringName *)r_dest;
- const String *name = (const String *)p_name;
- memnew_placement(dest, StringName(*name));
+ memnew_placement(dest, StringName);
}
-void GDAPI godot_string_name_new_data(godot_string_name *r_dest, const char *p_name) {
+void GDAPI godot_string_name_new_copy(godot_string_name *r_dest, const godot_string_name *p_src) {
StringName *dest = (StringName *)r_dest;
- memnew_placement(dest, StringName(p_name));
-}
-
-godot_string GDAPI godot_string_name_get_name(const godot_string_name *p_self) {
- godot_string ret;
- const StringName *self = (const StringName *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-uint32_t GDAPI godot_string_name_get_hash(const godot_string_name *p_self) {
- const StringName *self = (const StringName *)p_self;
- return self->hash();
-}
-
-const void GDAPI *godot_string_name_get_data_unique_pointer(const godot_string_name *p_self) {
- const StringName *self = (const StringName *)p_self;
- return self->data_unique_pointer();
+ const StringName *src = (const StringName *)p_src;
+ memnew_placement(dest, StringName(*src));
}
-godot_bool GDAPI godot_string_name_operator_equal(const godot_string_name *p_self, const godot_string_name *p_other) {
- const StringName *self = (const StringName *)p_self;
- const StringName *other = (const StringName *)p_other;
- return self == other;
-}
-
-godot_bool GDAPI godot_string_name_operator_less(const godot_string_name *p_self, const godot_string_name *p_other) {
- const StringName *self = (const StringName *)p_self;
- const StringName *other = (const StringName *)p_other;
- return self < other;
+void GDAPI godot_string_name_new_with_latin1_chars(godot_string_name *r_dest, const char *p_contents) {
+ StringName *dest = (StringName *)r_dest;
+ memnew_placement(dest, StringName(p_contents));
}
void GDAPI godot_string_name_destroy(godot_string_name *p_self) {
diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp
index b17d6f8d4c..eae981bd07 100644
--- a/modules/gdnative/gdnative/transform.cpp
+++ b/modules/gdnative/gdnative/transform.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,198 +31,15 @@
#include "gdnative/transform.h"
#include "core/math/transform.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_transform) == sizeof(Transform), "Transform size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_transform) == sizeof(Transform), "Transform size mismatch");
-
-void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin) {
- const Vector3 *x_axis = (const Vector3 *)p_x_axis;
- const Vector3 *y_axis = (const Vector3 *)p_y_axis;
- const Vector3 *z_axis = (const Vector3 *)p_z_axis;
- const Vector3 *origin = (const Vector3 *)p_origin;
- Transform *dest = (Transform *)r_dest;
- dest->basis.set_axis(0, *x_axis);
- dest->basis.set_axis(1, *y_axis);
- dest->basis.set_axis(2, *z_axis);
- dest->origin = *origin;
-}
-
-void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin) {
- const Basis *basis = (const Basis *)p_basis;
- const Vector3 *origin = (const Vector3 *)p_origin;
- Transform *dest = (Transform *)r_dest;
- *dest = Transform(*basis, *origin);
-}
-
-void GDAPI godot_transform_new_with_quat(godot_transform *r_dest, const godot_quat *p_quat) {
- const Quat *quat = (const Quat *)p_quat;
- Transform *dest = (Transform *)r_dest;
- *dest = Transform(*quat);
-}
-
-godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self) {
- godot_basis dest;
- const Transform *self = (const Transform *)p_self;
- *((Basis *)&dest) = self->basis;
- return dest;
-}
-
-void GDAPI godot_transform_set_basis(godot_transform *p_self, const godot_basis *p_v) {
- Transform *self = (Transform *)p_self;
- const Basis *v = (const Basis *)p_v;
- self->basis = *v;
-}
-
-godot_vector3 GDAPI godot_transform_get_origin(const godot_transform *p_self) {
- godot_vector3 dest;
- const Transform *self = (const Transform *)p_self;
- *((Vector3 *)&dest) = self->origin;
- return dest;
-}
-
-void GDAPI godot_transform_set_origin(godot_transform *p_self, const godot_vector3 *p_v) {
- Transform *self = (Transform *)p_self;
- const Vector3 *v = (const Vector3 *)p_v;
- self->origin = *v;
-}
-
-godot_string GDAPI godot_transform_as_string(const godot_transform *p_self) {
- godot_string ret;
- const Transform *self = (const Transform *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_transform GDAPI godot_transform_inverse(const godot_transform *p_self) {
- godot_transform dest;
- const Transform *self = (const Transform *)p_self;
- *((Transform *)&dest) = self->inverse();
- return dest;
-}
-
-godot_transform GDAPI godot_transform_affine_inverse(const godot_transform *p_self) {
- godot_transform dest;
- const Transform *self = (const Transform *)p_self;
- *((Transform *)&dest) = self->affine_inverse();
- return dest;
-}
-
-godot_transform GDAPI godot_transform_orthonormalized(const godot_transform *p_self) {
- godot_transform dest;
- const Transform *self = (const Transform *)p_self;
- *((Transform *)&dest) = self->orthonormalized();
- return dest;
-}
-
-godot_transform GDAPI godot_transform_rotated(const godot_transform *p_self, const godot_vector3 *p_axis, const godot_real p_phi) {
- godot_transform dest;
- const Transform *self = (const Transform *)p_self;
- const Vector3 *axis = (const Vector3 *)p_axis;
- *((Transform *)&dest) = self->rotated(*axis, p_phi);
- return dest;
-}
-
-godot_transform GDAPI godot_transform_scaled(const godot_transform *p_self, const godot_vector3 *p_scale) {
- godot_transform dest;
- const Transform *self = (const Transform *)p_self;
- const Vector3 *scale = (const Vector3 *)p_scale;
- *((Transform *)&dest) = self->scaled(*scale);
- return dest;
-}
-
-godot_transform GDAPI godot_transform_translated(const godot_transform *p_self, const godot_vector3 *p_ofs) {
- godot_transform dest;
- const Transform *self = (const Transform *)p_self;
- const Vector3 *ofs = (const Vector3 *)p_ofs;
- *((Transform *)&dest) = self->translated(*ofs);
- return dest;
-}
-
-godot_transform GDAPI godot_transform_looking_at(const godot_transform *p_self, const godot_vector3 *p_target, const godot_vector3 *p_up) {
- godot_transform dest;
- const Transform *self = (const Transform *)p_self;
- const Vector3 *target = (const Vector3 *)p_target;
- const Vector3 *up = (const Vector3 *)p_up;
- *((Transform *)&dest) = self->looking_at(*target, *up);
- return dest;
-}
-
-godot_plane GDAPI godot_transform_xform_plane(const godot_transform *p_self, const godot_plane *p_v) {
- godot_plane raw_dest;
- Plane *dest = (Plane *)&raw_dest;
- const Transform *self = (const Transform *)p_self;
- const Plane *v = (const Plane *)p_v;
- *dest = self->xform(*v);
- return raw_dest;
-}
-
-godot_plane GDAPI godot_transform_xform_inv_plane(const godot_transform *p_self, const godot_plane *p_v) {
- godot_plane raw_dest;
- Plane *dest = (Plane *)&raw_dest;
- const Transform *self = (const Transform *)p_self;
- const Plane *v = (const Plane *)p_v;
- *dest = self->xform_inv(*v);
- return raw_dest;
-}
-
-void GDAPI godot_transform_new_identity(godot_transform *r_dest) {
- Transform *dest = (Transform *)r_dest;
- *dest = Transform();
-}
-
-godot_bool GDAPI godot_transform_operator_equal(const godot_transform *p_self, const godot_transform *p_b) {
- const Transform *self = (const Transform *)p_self;
- const Transform *b = (const Transform *)p_b;
- return *self == *b;
-}
-
-godot_transform GDAPI godot_transform_operator_multiply(const godot_transform *p_self, const godot_transform *p_b) {
- godot_transform raw_dest;
- Transform *dest = (Transform *)&raw_dest;
- const Transform *self = (const Transform *)p_self;
- const Transform *b = (const Transform *)p_b;
- *dest = *self * *b;
- return raw_dest;
-}
-
-godot_vector3 GDAPI godot_transform_xform_vector3(const godot_transform *p_self, const godot_vector3 *p_v) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- const Transform *self = (const Transform *)p_self;
- const Vector3 *v = (const Vector3 *)p_v;
- *dest = self->xform(*v);
- return raw_dest;
-}
-
-godot_vector3 GDAPI godot_transform_xform_inv_vector3(const godot_transform *p_self, const godot_vector3 *p_v) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- const Transform *self = (const Transform *)p_self;
- const Vector3 *v = (const Vector3 *)p_v;
- *dest = self->xform_inv(*v);
- return raw_dest;
-}
-
-godot_aabb GDAPI godot_transform_xform_aabb(const godot_transform *p_self, const godot_aabb *p_v) {
- godot_aabb raw_dest;
- AABB *dest = (AABB *)&raw_dest;
- const Transform *self = (const Transform *)p_self;
- const AABB *v = (const AABB *)p_v;
- *dest = self->xform(*v);
- return raw_dest;
-}
-
-godot_aabb GDAPI godot_transform_xform_inv_aabb(const godot_transform *p_self, const godot_aabb *p_v) {
- godot_aabb raw_dest;
- AABB *dest = (AABB *)&raw_dest;
- const Transform *self = (const Transform *)p_self;
- const AABB *v = (const AABB *)p_v;
- *dest = self->xform_inv(*v);
- return raw_dest;
+void GDAPI godot_transform_new(godot_transform *p_self) {
+ memnew_placement(p_self, Transform);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp
index 3c1105e323..679174d5a5 100644
--- a/modules/gdnative/gdnative/transform2d.cpp
+++ b/modules/gdnative/gdnative/transform2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,179 +31,25 @@
#include "gdnative/transform2d.h"
#include "core/math/transform_2d.h"
-#include "core/variant/variant.h"
+
+static_assert(sizeof(godot_transform2d) == sizeof(Transform2D), "Transform2D size mismatch");
#ifdef __cplusplus
extern "C" {
#endif
-static_assert(sizeof(godot_transform2d) == sizeof(Transform2D), "Transform2D size mismatch");
-
-void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos) {
- const Vector2 *pos = (const Vector2 *)p_pos;
- Transform2D *dest = (Transform2D *)r_dest;
- *dest = Transform2D(p_rot, *pos);
-}
-
-void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin) {
- const Vector2 *x_axis = (const Vector2 *)p_x_axis;
- const Vector2 *y_axis = (const Vector2 *)p_y_axis;
- const Vector2 *origin = (const Vector2 *)p_origin;
- Transform2D *dest = (Transform2D *)r_dest;
- *dest = Transform2D(x_axis->x, x_axis->y, y_axis->x, y_axis->y, origin->x, origin->y);
-}
-
-godot_string GDAPI godot_transform2d_as_string(const godot_transform2d *p_self) {
- godot_string ret;
- const Transform2D *self = (const Transform2D *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_transform2d GDAPI godot_transform2d_inverse(const godot_transform2d *p_self) {
- godot_transform2d dest;
- const Transform2D *self = (const Transform2D *)p_self;
- *((Transform2D *)&dest) = self->inverse();
- return dest;
-}
-
-godot_transform2d GDAPI godot_transform2d_affine_inverse(const godot_transform2d *p_self) {
- godot_transform2d dest;
- const Transform2D *self = (const Transform2D *)p_self;
- *((Transform2D *)&dest) = self->affine_inverse();
- return dest;
-}
-
-godot_real GDAPI godot_transform2d_get_rotation(const godot_transform2d *p_self) {
- const Transform2D *self = (const Transform2D *)p_self;
- return self->get_rotation();
-}
-
-godot_vector2 GDAPI godot_transform2d_get_origin(const godot_transform2d *p_self) {
- godot_vector2 dest;
- const Transform2D *self = (const Transform2D *)p_self;
- *((Vector2 *)&dest) = self->get_origin();
- return dest;
-}
-
-godot_vector2 GDAPI godot_transform2d_get_scale(const godot_transform2d *p_self) {
- godot_vector2 dest;
- const Transform2D *self = (const Transform2D *)p_self;
- *((Vector2 *)&dest) = self->get_scale();
- return dest;
-}
-
-godot_transform2d GDAPI godot_transform2d_orthonormalized(const godot_transform2d *p_self) {
- godot_transform2d dest;
- const Transform2D *self = (const Transform2D *)p_self;
- *((Transform2D *)&dest) = self->orthonormalized();
- return dest;
-}
-
-godot_transform2d GDAPI godot_transform2d_rotated(const godot_transform2d *p_self, const godot_real p_phi) {
- godot_transform2d dest;
- const Transform2D *self = (const Transform2D *)p_self;
-
- *((Transform2D *)&dest) = self->rotated(p_phi);
- return dest;
+void GDAPI godot_transform2d_new(godot_transform2d *p_self) {
+ memnew_placement(p_self, Transform2D);
}
-godot_transform2d GDAPI godot_transform2d_scaled(const godot_transform2d *p_self, const godot_vector2 *p_scale) {
- godot_transform2d dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Vector2 *scale = (const Vector2 *)p_scale;
- *((Transform2D *)&dest) = self->scaled(*scale);
- return dest;
-}
-
-godot_transform2d GDAPI godot_transform2d_translated(const godot_transform2d *p_self, const godot_vector2 *p_offset) {
- godot_transform2d dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Vector2 *offset = (const Vector2 *)p_offset;
- *((Transform2D *)&dest) = self->translated(*offset);
- return dest;
-}
-
-godot_vector2 GDAPI godot_transform2d_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Vector2 *v = (const Vector2 *)p_v;
- *dest = self->xform(*v);
- return raw_dest;
-}
-
-godot_vector2 GDAPI godot_transform2d_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Vector2 *v = (const Vector2 *)p_v;
- *dest = self->xform_inv(*v);
- return raw_dest;
-}
-
-godot_vector2 GDAPI godot_transform2d_basis_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Vector2 *v = (const Vector2 *)p_v;
- *dest = self->basis_xform(*v);
- return raw_dest;
-}
-
-godot_vector2 GDAPI godot_transform2d_basis_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Vector2 *v = (const Vector2 *)p_v;
- *dest = self->basis_xform_inv(*v);
- return raw_dest;
-}
-
-godot_transform2d GDAPI godot_transform2d_interpolate_with(const godot_transform2d *p_self, const godot_transform2d *p_m, const godot_real p_c) {
- godot_transform2d dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Transform2D *m = (const Transform2D *)p_m;
- *((Transform2D *)&dest) = self->interpolate_with(*m, p_c);
- return dest;
-}
-
-godot_bool GDAPI godot_transform2d_operator_equal(const godot_transform2d *p_self, const godot_transform2d *p_b) {
- const Transform2D *self = (const Transform2D *)p_self;
- const Transform2D *b = (const Transform2D *)p_b;
- return *self == *b;
-}
-
-godot_transform2d GDAPI godot_transform2d_operator_multiply(const godot_transform2d *p_self, const godot_transform2d *p_b) {
- godot_transform2d raw_dest;
- Transform2D *dest = (Transform2D *)&raw_dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Transform2D *b = (const Transform2D *)p_b;
- *dest = *self * *b;
- return raw_dest;
-}
-
-void GDAPI godot_transform2d_new_identity(godot_transform2d *r_dest) {
- Transform2D *dest = (Transform2D *)r_dest;
- *dest = Transform2D();
-}
-
-godot_rect2 GDAPI godot_transform2d_xform_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v) {
- godot_rect2 raw_dest;
- Rect2 *dest = (Rect2 *)&raw_dest;
- const Transform2D *self = (const Transform2D *)p_self;
- const Rect2 *v = (const Rect2 *)p_v;
- *dest = self->xform(*v);
- return raw_dest;
+godot_vector2 GDAPI *godot_transform2d_operator_index(godot_transform2d *p_self, godot_int p_index) {
+ Transform2D *self = (Transform2D *)p_self;
+ return (godot_vector2 *)&self->operator[](p_index);
}
-godot_rect2 GDAPI godot_transform2d_xform_inv_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v) {
- godot_rect2 raw_dest;
- Rect2 *dest = (Rect2 *)&raw_dest;
+const godot_vector2 GDAPI *godot_transform2d_operator_index_const(const godot_transform2d *p_self, godot_int p_index) {
const Transform2D *self = (const Transform2D *)p_self;
- const Rect2 *v = (const Rect2 *)p_v;
- *dest = self->xform_inv(*v);
- return raw_dest;
+ return (const godot_vector2 *)&self->operator[](p_index);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp
index 417abeaad3..ee4353bb48 100644
--- a/modules/gdnative/gdnative/variant.cpp
+++ b/modules/gdnative/gdnative/variant.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,16 +55,11 @@ static_assert(sizeof(godot_variant) == sizeof(Variant), "Variant size mismatch")
#pragma GCC pop_options
#endif
-// Constructors
-
-godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_self) {
- const Variant *self = (const Variant *)p_self;
- return (godot_variant_type)self->get_type();
-}
+// Memory
void GDAPI godot_variant_new_copy(godot_variant *p_dest, const godot_variant *p_src) {
Variant *dest = (Variant *)p_dest;
- Variant *src = (Variant *)p_src;
+ const Variant *src = (const Variant *)p_src;
memnew_placement(dest, Variant(*src));
}
@@ -78,139 +73,134 @@ void GDAPI godot_variant_new_bool(godot_variant *r_dest, const godot_bool p_b) {
memnew_placement_custom(dest, Variant, Variant(p_b));
}
-void GDAPI godot_variant_new_uint(godot_variant *r_dest, const uint64_t p_i) {
+void GDAPI godot_variant_new_int(godot_variant *r_dest, const godot_int p_i) {
Variant *dest = (Variant *)r_dest;
memnew_placement_custom(dest, Variant, Variant(p_i));
}
-void GDAPI godot_variant_new_int(godot_variant *r_dest, const int64_t p_i) {
- Variant *dest = (Variant *)r_dest;
- memnew_placement_custom(dest, Variant, Variant(p_i));
-}
-
-void GDAPI godot_variant_new_real(godot_variant *r_dest, const double p_r) {
+void GDAPI godot_variant_new_float(godot_variant *r_dest, const godot_float p_r) {
Variant *dest = (Variant *)r_dest;
memnew_placement_custom(dest, Variant, Variant(p_r));
}
void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p_s) {
Variant *dest = (Variant *)r_dest;
- String *s = (String *)p_s;
+ const String *s = (const String *)p_s;
memnew_placement_custom(dest, Variant, Variant(*s));
}
void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s) {
Variant *dest = (Variant *)r_dest;
- StringName *s = (StringName *)p_s;
+ const StringName *s = (const StringName *)p_s;
memnew_placement_custom(dest, Variant, Variant(*s));
}
void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2) {
Variant *dest = (Variant *)r_dest;
- Vector2 *v2 = (Vector2 *)p_v2;
+ const Vector2 *v2 = (const Vector2 *)p_v2;
memnew_placement_custom(dest, Variant, Variant(*v2));
}
void GDAPI godot_variant_new_vector2i(godot_variant *r_dest, const godot_vector2i *p_v2) {
Variant *dest = (Variant *)r_dest;
- Vector2i *v2 = (Vector2i *)p_v2;
+ const Vector2i *v2 = (const Vector2i *)p_v2;
memnew_placement_custom(dest, Variant, Variant(*v2));
}
void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2) {
Variant *dest = (Variant *)r_dest;
- Rect2 *rect2 = (Rect2 *)p_rect2;
+ const Rect2 *rect2 = (const Rect2 *)p_rect2;
memnew_placement_custom(dest, Variant, Variant(*rect2));
}
void GDAPI godot_variant_new_rect2i(godot_variant *r_dest, const godot_rect2i *p_rect2) {
Variant *dest = (Variant *)r_dest;
- Rect2i *rect2 = (Rect2i *)p_rect2;
+ const Rect2i *rect2 = (const Rect2i *)p_rect2;
memnew_placement_custom(dest, Variant, Variant(*rect2));
}
void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 *p_v3) {
Variant *dest = (Variant *)r_dest;
- Vector3 *v3 = (Vector3 *)p_v3;
+ const Vector3 *v3 = (const Vector3 *)p_v3;
memnew_placement_custom(dest, Variant, Variant(*v3));
}
void GDAPI godot_variant_new_vector3i(godot_variant *r_dest, const godot_vector3i *p_v3) {
Variant *dest = (Variant *)r_dest;
- Vector3i *v3 = (Vector3i *)p_v3;
+ const Vector3i *v3 = (const Vector3i *)p_v3;
memnew_placement_custom(dest, Variant, Variant(*v3));
}
void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d) {
Variant *dest = (Variant *)r_dest;
- Transform2D *t2d = (Transform2D *)p_t2d;
+ const Transform2D *t2d = (const Transform2D *)p_t2d;
memnew_placement_custom(dest, Variant, Variant(*t2d));
}
void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_plane) {
Variant *dest = (Variant *)r_dest;
- Plane *plane = (Plane *)p_plane;
+ const Plane *plane = (const Plane *)p_plane;
memnew_placement_custom(dest, Variant, Variant(*plane));
}
void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_quat) {
Variant *dest = (Variant *)r_dest;
- Quat *quat = (Quat *)p_quat;
+ const Quat *quat = (const Quat *)p_quat;
memnew_placement_custom(dest, Variant, Variant(*quat));
}
void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aabb) {
Variant *dest = (Variant *)r_dest;
- AABB *aabb = (AABB *)p_aabb;
+ const AABB *aabb = (const AABB *)p_aabb;
memnew_placement_custom(dest, Variant, Variant(*aabb));
}
void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis) {
Variant *dest = (Variant *)r_dest;
- Basis *basis = (Basis *)p_basis;
+ const Basis *basis = (const Basis *)p_basis;
memnew_placement_custom(dest, Variant, Variant(*basis));
}
void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans) {
Variant *dest = (Variant *)r_dest;
- Transform *trans = (Transform *)p_trans;
+ const Transform *trans = (const Transform *)p_trans;
memnew_placement_custom(dest, Variant, Variant(*trans));
}
void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color) {
Variant *dest = (Variant *)r_dest;
- Color *color = (Color *)p_color;
+ const Color *color = (const Color *)p_color;
memnew_placement_custom(dest, Variant, Variant(*color));
}
void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np) {
Variant *dest = (Variant *)r_dest;
- NodePath *np = (NodePath *)p_np;
+ const NodePath *np = (const NodePath *)p_np;
memnew_placement_custom(dest, Variant, Variant(*np));
}
void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid) {
Variant *dest = (Variant *)r_dest;
- RID *rid = (RID *)p_rid;
+ const RID *rid = (const RID *)p_rid;
memnew_placement_custom(dest, Variant, Variant(*rid));
}
void GDAPI godot_variant_new_callable(godot_variant *r_dest, const godot_callable *p_cb) {
Variant *dest = (Variant *)r_dest;
- Callable *cb = (Callable *)p_cb;
+ const Callable *cb = (const Callable *)p_cb;
memnew_placement_custom(dest, Variant, Variant(*cb));
}
void GDAPI godot_variant_new_signal(godot_variant *r_dest, const godot_signal *p_signal) {
Variant *dest = (Variant *)r_dest;
- Signal *signal = (Signal *)p_signal;
+ const Signal *signal = (const Signal *)p_signal;
memnew_placement_custom(dest, Variant, Variant(*signal));
}
void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj) {
Variant *dest = (Variant *)r_dest;
- Object *obj = (Object *)p_obj;
- Reference *reference = Object::cast_to<Reference>(obj);
+ const Object *obj = (const Object *)p_obj;
+ const Reference *reference = Object::cast_to<Reference>(obj);
REF ref;
if (reference) {
ref = REF(reference);
@@ -229,67 +219,67 @@ void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p
void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict) {
Variant *dest = (Variant *)r_dest;
- Dictionary *dict = (Dictionary *)p_dict;
+ const Dictionary *dict = (const Dictionary *)p_dict;
memnew_placement_custom(dest, Variant, Variant(*dict));
}
void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr) {
Variant *dest = (Variant *)r_dest;
- Array *arr = (Array *)p_arr;
+ const Array *arr = (const Array *)p_arr;
memnew_placement_custom(dest, Variant, Variant(*arr));
}
void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godot_packed_byte_array *p_pba) {
Variant *dest = (Variant *)r_dest;
- PackedByteArray *pba = (PackedByteArray *)p_pba;
+ const PackedByteArray *pba = (const PackedByteArray *)p_pba;
memnew_placement_custom(dest, Variant, Variant(*pba));
}
void GDAPI godot_variant_new_packed_int32_array(godot_variant *r_dest, const godot_packed_int32_array *p_pia) {
Variant *dest = (Variant *)r_dest;
- PackedInt32Array *pia = (PackedInt32Array *)p_pia;
+ const PackedInt32Array *pia = (const PackedInt32Array *)p_pia;
memnew_placement_custom(dest, Variant, Variant(*pia));
}
void GDAPI godot_variant_new_packed_int64_array(godot_variant *r_dest, const godot_packed_int64_array *p_pia) {
Variant *dest = (Variant *)r_dest;
- PackedInt64Array *pia = (PackedInt64Array *)p_pia;
+ const PackedInt64Array *pia = (const PackedInt64Array *)p_pia;
memnew_placement_custom(dest, Variant, Variant(*pia));
}
void GDAPI godot_variant_new_packed_float32_array(godot_variant *r_dest, const godot_packed_float32_array *p_pra) {
Variant *dest = (Variant *)r_dest;
- PackedFloat32Array *pra = (PackedFloat32Array *)p_pra;
+ const PackedFloat32Array *pra = (const PackedFloat32Array *)p_pra;
memnew_placement_custom(dest, Variant, Variant(*pra));
}
void GDAPI godot_variant_new_packed_float64_array(godot_variant *r_dest, const godot_packed_float64_array *p_pra) {
Variant *dest = (Variant *)r_dest;
- PackedFloat64Array *pra = (PackedFloat64Array *)p_pra;
+ const PackedFloat64Array *pra = (const PackedFloat64Array *)p_pra;
memnew_placement_custom(dest, Variant, Variant(*pra));
}
void GDAPI godot_variant_new_packed_string_array(godot_variant *r_dest, const godot_packed_string_array *p_psa) {
Variant *dest = (Variant *)r_dest;
- PackedStringArray *psa = (PackedStringArray *)p_psa;
+ const PackedStringArray *psa = (const PackedStringArray *)p_psa;
memnew_placement_custom(dest, Variant, Variant(*psa));
}
void GDAPI godot_variant_new_packed_vector2_array(godot_variant *r_dest, const godot_packed_vector2_array *p_pv2a) {
Variant *dest = (Variant *)r_dest;
- PackedVector2Array *pv2a = (PackedVector2Array *)p_pv2a;
+ const PackedVector2Array *pv2a = (const PackedVector2Array *)p_pv2a;
memnew_placement_custom(dest, Variant, Variant(*pv2a));
}
void GDAPI godot_variant_new_packed_vector3_array(godot_variant *r_dest, const godot_packed_vector3_array *p_pv3a) {
Variant *dest = (Variant *)r_dest;
- PackedVector3Array *pv3a = (PackedVector3Array *)p_pv3a;
+ const PackedVector3Array *pv3a = (const PackedVector3Array *)p_pv3a;
memnew_placement_custom(dest, Variant, Variant(*pv3a));
}
void GDAPI godot_variant_new_packed_color_array(godot_variant *r_dest, const godot_packed_color_array *p_pca) {
Variant *dest = (Variant *)r_dest;
- PackedColorArray *pca = (PackedColorArray *)p_pca;
+ const PackedColorArray *pca = (const PackedColorArray *)p_pca;
memnew_placement_custom(dest, Variant, Variant(*pca));
}
@@ -298,17 +288,12 @@ godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_self) {
return self->operator bool();
}
-uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_self) {
- const Variant *self = (const Variant *)p_self;
- return self->operator uint64_t();
-}
-
-int64_t GDAPI godot_variant_as_int(const godot_variant *p_self) {
+godot_int GDAPI godot_variant_as_int(const godot_variant *p_self) {
const Variant *self = (const Variant *)p_self;
return self->operator int64_t();
}
-double GDAPI godot_variant_as_real(const godot_variant *p_self) {
+godot_float GDAPI godot_variant_as_float(const godot_variant *p_self) {
const Variant *self = (const Variant *)p_self;
return self->operator double();
}
@@ -569,47 +554,137 @@ godot_packed_color_array GDAPI godot_variant_as_packed_color_array(const godot_v
return raw_dest;
}
-godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant_call_error *r_error) {
+void GDAPI godot_variant_destroy(godot_variant *p_self) {
+ Variant *self = (Variant *)p_self;
+ self->~Variant();
+}
+
+// Dynamic interaction.
+
+void GDAPI godot_variant_call(godot_variant *p_self, const godot_string_name *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant *r_return, godot_variant_call_error *r_error) {
Variant *self = (Variant *)p_self;
- String *method = (String *)p_method;
+ const StringName *method = (const StringName *)p_method;
const Variant **args = (const Variant **)p_args;
- godot_variant raw_dest;
- Variant *dest = (Variant *)&raw_dest;
- Callable::CallError error;
Variant ret;
+ Callable::CallError error;
self->call(*method, args, p_argcount, ret, error);
- memnew_placement_custom(dest, Variant, Variant(ret));
+ memnew_placement_custom(r_return, Variant, Variant(ret));
+
if (r_error) {
r_error->error = (godot_variant_call_error_error)error.error;
r_error->argument = error.argument;
r_error->expected = (godot_variant_type)error.expected;
}
- return raw_dest;
}
-godot_bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string *p_method) {
+void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_variant *p_a, const godot_variant *p_b, godot_variant *r_return, bool *r_valid) {
+ Variant::Operator op = (Variant::Operator)p_op;
+ const Variant *a = (const Variant *)p_a;
+ const Variant *b = (const Variant *)p_b;
+ Variant *ret = (Variant *)r_return;
+ Variant::evaluate(op, *a, *b, *ret, *r_valid);
+}
+
+void GDAPI godot_variant_set(godot_variant *p_self, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid) {
+ Variant *self = (Variant *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ const Variant *value = (const Variant *)p_value;
+
+ self->set(*key, *value, r_valid);
+}
+
+void GDAPI godot_variant_set_named(godot_variant *p_self, const godot_string_name *p_name, const godot_variant *p_value, bool *r_valid) {
+ Variant *self = (Variant *)p_self;
+ const StringName *name = (const StringName *)p_name;
+ const Variant *value = (const Variant *)p_value;
+
+ self->set_named(*name, *value, *r_valid);
+}
+
+void GDAPI godot_variant_set_keyed(godot_variant *p_self, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid) {
+ Variant *self = (Variant *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ const Variant *value = (const Variant *)p_value;
+
+ self->set_keyed(*key, *value, *r_valid);
+}
+
+void GDAPI godot_variant_set_indexed(godot_variant *p_self, godot_int p_index, const godot_variant *p_value, bool *r_valid, bool *r_oob) {
+ Variant *self = (Variant *)p_self;
+ const Variant *value = (const Variant *)p_value;
+
+ self->set_indexed(p_index, value, *r_valid, *r_oob);
+}
+
+godot_variant GDAPI godot_variant_get(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid) {
const Variant *self = (const Variant *)p_self;
- const String *method = (const String *)p_method;
- return self->has_method(*method);
+ const Variant *key = (const Variant *)p_key;
+ Variant ret;
+
+ ret = self->get(*key, r_valid);
+ godot_variant result;
+ memnew_placement_custom(&result, Variant, Variant(ret));
+ return result;
}
-godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_self, const godot_variant *p_other) {
+godot_variant GDAPI godot_variant_get_named(const godot_variant *p_self, const godot_string_name *p_key, bool *r_valid) {
const Variant *self = (const Variant *)p_self;
- const Variant *other = (const Variant *)p_other;
- return self->operator==(*other);
+ const StringName *key = (const StringName *)p_key;
+ Variant ret;
+
+ ret = self->get_named(*key, *r_valid);
+ godot_variant result;
+ memnew_placement_custom(&result, Variant, Variant(ret));
+ return result;
}
-godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const godot_variant *p_other) {
+godot_variant GDAPI godot_variant_get_keyed(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid) {
const Variant *self = (const Variant *)p_self;
- const Variant *other = (const Variant *)p_other;
- return self->operator<(*other);
+ const Variant *key = (const Variant *)p_key;
+ Variant ret;
+
+ ret = self->get_keyed(*key, *r_valid);
+ godot_variant result;
+ memnew_placement_custom(&result, Variant, Variant(ret));
+ return result;
+}
+
+godot_variant GDAPI godot_variant_get_indexed(const godot_variant *p_self, godot_int p_index, bool *r_valid, bool *r_oob) {
+ const Variant *self = (const Variant *)p_self;
+ Variant ret;
+
+ ret = self->get_indexed(p_index, *r_valid, *r_oob);
+ godot_variant result;
+ memnew_placement_custom(&result, Variant, Variant(ret));
+ return result;
}
-uint32_t GDAPI godot_variant_hash(const godot_variant *p_self) {
+/// Iteration.
+bool GDAPI godot_variant_iter_init(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid) {
const Variant *self = (const Variant *)p_self;
- return self->hash();
+ Variant *iter = (Variant *)r_iter;
+
+ return self->iter_init(*iter, *r_valid);
}
+bool GDAPI godot_variant_iter_next(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid) {
+ const Variant *self = (const Variant *)p_self;
+ Variant *iter = (Variant *)r_iter;
+
+ return self->iter_next(*iter, *r_valid);
+}
+
+godot_variant GDAPI godot_variant_iter_get(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid) {
+ const Variant *self = (const Variant *)p_self;
+ Variant *iter = (Variant *)r_iter;
+
+ Variant result = self->iter_next(*iter, *r_valid);
+ godot_variant ret;
+ memnew_placement_custom(&ret, Variant, Variant(result));
+ return ret;
+}
+
+/// Variant functions.
godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other) {
const Variant *self = (const Variant *)p_self;
const Variant *other = (const Variant *)p_other;
@@ -621,27 +696,503 @@ godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self) {
return self->booleanize();
}
-void GDAPI godot_variant_destroy(godot_variant *p_self) {
- Variant *self = (Variant *)p_self;
- self->~Variant();
+void GDAPI godot_variant_blend(const godot_variant *p_a, const godot_variant *p_b, float p_c, godot_variant *r_dst) {
+ const Variant *a = (const Variant *)p_a;
+ const Variant *b = (const Variant *)p_b;
+ Variant *dst = (Variant *)r_dst;
+ Variant::blend(*a, *b, p_c, *dst);
}
-// GDNative core 1.1
+void GDAPI godot_variant_interpolate(const godot_variant *p_a, const godot_variant *p_b, float p_c, godot_variant *r_dst) {
+ const Variant *a = (const Variant *)p_a;
+ const Variant *b = (const Variant *)p_b;
+ Variant *dst = (Variant *)r_dst;
+ Variant::interpolate(*a, *b, p_c, *dst);
+}
-godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_op) {
- Variant::Operator op = (Variant::Operator)p_op;
- godot_string raw_dest;
- String *dest = (String *)&raw_dest;
- memnew_placement(dest, String(Variant::get_operator_name(op))); // operator = is overloaded by String
- return raw_dest;
+godot_variant GDAPI godot_variant_duplicate(const godot_variant *p_self, godot_bool p_deep) {
+ const Variant *self = (const Variant *)p_self;
+ Variant result = self->duplicate(p_deep);
+ godot_variant ret;
+ memnew_placement_custom(&ret, Variant, Variant(result));
+ return ret;
}
-void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_variant *p_a, const godot_variant *p_b, godot_variant *r_ret, godot_bool *r_valid) {
- Variant::Operator op = (Variant::Operator)p_op;
- const Variant *a = (const Variant *)p_a;
- const Variant *b = (const Variant *)p_b;
+godot_string GDAPI godot_variant_stringify(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ String result = *self;
+ godot_string ret;
+ memnew_placement_custom(&ret, String, String(result));
+ return ret;
+}
+
+// Discovery API
+
+/// Operators
+godot_validated_operator_evaluator GDAPI godot_variant_get_validated_operator_evaluator(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b) {
+ return (godot_validated_operator_evaluator)Variant::get_validated_operator_evaluator((Variant::Operator)p_operator, (Variant::Type)p_type_a, (Variant::Type)p_type_b);
+}
+
+godot_ptr_operator_evaluator GDAPI godot_variant_get_ptr_operator_evaluator(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b) {
+ return (godot_ptr_operator_evaluator)Variant::get_ptr_operator_evaluator((Variant::Operator)p_operator, (Variant::Type)p_type_a, (Variant::Type)p_type_b);
+}
+
+godot_variant_type GDAPI godot_variant_get_operator_return_type(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b) {
+ return (godot_variant_type)Variant::get_operator_return_type((Variant::Operator)p_operator, (Variant::Type)p_type_a, (Variant::Type)p_type_b);
+}
+
+godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_operator) {
+ String op_name = Variant::get_operator_name((Variant::Operator)p_operator);
+ godot_string ret;
+ memnew_placement_custom(&ret, String, String(op_name));
+ return ret;
+}
+
+/// Built-in Methods
+
+bool GDAPI godot_variant_has_builtin_method(godot_variant_type p_type, const godot_string_name *p_method) {
+ return Variant::has_builtin_method((Variant::Type)p_type, *((const StringName *)p_method));
+}
+
+bool GDAPI godot_variant_has_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method) {
+ return Variant::has_builtin_method((Variant::Type)p_type, StringName(p_method));
+}
+
+godot_validated_builtin_method GDAPI godot_variant_get_validated_builtin_method(godot_variant_type p_type, const godot_string_name *p_method) {
+ return (godot_validated_builtin_method)Variant::get_validated_builtin_method((Variant::Type)p_type, *((const StringName *)p_method));
+}
+
+godot_validated_builtin_method GDAPI godot_variant_get_validated_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method) {
+ return (godot_validated_builtin_method)Variant::get_validated_builtin_method((Variant::Type)p_type, StringName(p_method));
+}
+
+godot_ptr_builtin_method GDAPI godot_variant_get_ptr_builtin_method(godot_variant_type p_type, const godot_string_name *p_method) {
+ return (godot_ptr_builtin_method)Variant::get_ptr_builtin_method((Variant::Type)p_type, *((const StringName *)p_method));
+}
+
+godot_ptr_builtin_method GDAPI godot_variant_get_ptr_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method) {
+ return (godot_ptr_builtin_method)Variant::get_ptr_builtin_method((Variant::Type)p_type, StringName(p_method));
+}
+
+int GDAPI godot_variant_get_builtin_method_argument_count(godot_variant_type p_type, const godot_string_name *p_method) {
+ return Variant::get_builtin_method_argument_count((Variant::Type)p_type, *((const StringName *)p_method));
+}
+
+int GDAPI godot_variant_get_builtin_method_argument_count_with_cstring(godot_variant_type p_type, const char *p_method) {
+ return Variant::get_builtin_method_argument_count((Variant::Type)p_type, StringName(p_method));
+}
+
+godot_variant_type GDAPI godot_variant_get_builtin_method_argument_type(godot_variant_type p_type, const godot_string_name *p_method, int p_argument) {
+ return (godot_variant_type)Variant::get_builtin_method_argument_type((Variant::Type)p_type, *((const StringName *)p_method), p_argument);
+}
+
+godot_variant_type GDAPI godot_variant_get_builtin_method_argument_type_with_cstring(godot_variant_type p_type, const char *p_method, int p_argument) {
+ return (godot_variant_type)Variant::get_builtin_method_argument_type((Variant::Type)p_type, StringName(p_method), p_argument);
+}
+
+godot_string GDAPI godot_variant_get_builtin_method_argument_name(godot_variant_type p_type, const godot_string_name *p_method, int p_argument) {
+ String name = Variant::get_builtin_method_argument_name((Variant::Type)p_type, *((const StringName *)p_method), p_argument);
+ return *(godot_string *)&name;
+}
+
+godot_string GDAPI godot_variant_get_builtin_method_argument_name_with_cstring(godot_variant_type p_type, const char *p_method, int p_argument) {
+ String name = Variant::get_builtin_method_argument_name((Variant::Type)p_type, StringName(p_method), p_argument);
+ return *(godot_string *)&name;
+}
+
+bool GDAPI godot_variant_has_builtin_method_return_value(godot_variant_type p_type, const godot_string_name *p_method) {
+ return Variant::has_builtin_method_return_value((Variant::Type)p_type, *((const StringName *)p_method));
+}
+
+bool GDAPI godot_variant_has_builtin_method_return_value_with_cstring(godot_variant_type p_type, const char *p_method) {
+ return Variant::has_builtin_method_return_value((Variant::Type)p_type, StringName(p_method));
+}
+
+godot_variant_type GDAPI godot_variant_get_builtin_method_return_type(godot_variant_type p_type, const godot_string_name *p_method) {
+ return (godot_variant_type)Variant::get_builtin_method_return_type((Variant::Type)p_type, *((const StringName *)p_method));
+}
+
+godot_variant_type GDAPI godot_variant_get_builtin_method_return_type_with_cstring(godot_variant_type p_type, const char *p_method) {
+ return (godot_variant_type)Variant::get_builtin_method_return_type((Variant::Type)p_type, StringName(p_method));
+}
+
+bool GDAPI godot_variant_is_builtin_method_const(godot_variant_type p_type, const godot_string_name *p_method) {
+ return Variant::is_builtin_method_const((Variant::Type)p_type, *((const StringName *)p_method));
+}
+
+bool GDAPI godot_variant_is_builtin_method_const_with_cstring(godot_variant_type p_type, const char *p_method) {
+ return Variant::is_builtin_method_const((Variant::Type)p_type, StringName(p_method));
+}
+
+bool GDAPI godot_variant_is_builtin_method_vararg(godot_variant_type p_type, const godot_string_name *p_method) {
+ return Variant::is_builtin_method_vararg((Variant::Type)p_type, *((const StringName *)p_method));
+}
+
+bool GDAPI godot_variant_is_builtin_method_vararg_with_cstring(godot_variant_type p_type, const char *p_method) {
+ return Variant::is_builtin_method_vararg((Variant::Type)p_type, StringName(p_method));
+}
+
+int GDAPI godot_variant_get_builtin_method_count(godot_variant_type p_type) {
+ return Variant::get_builtin_method_count((Variant::Type)p_type);
+}
+
+void GDAPI godot_variant_get_builtin_method_list(godot_variant_type p_type, godot_string_name *r_list) {
+ List<StringName> list;
+ Variant::get_builtin_method_list((Variant::Type)p_type, &list);
+ int i = 0;
+ for (const List<StringName>::Element *E = list.front(); E; E = E->next()) {
+ memnew_placement_custom(&r_list[i], StringName, StringName(E->get()));
+ }
+}
+
+/// Constructors
+
+int GDAPI godot_variant_get_constructor_count(godot_variant_type p_type) {
+ return Variant::get_constructor_count((Variant::Type)p_type);
+}
+
+godot_validated_constructor GDAPI godot_variant_get_validated_constructor(godot_variant_type p_type, int p_constructor) {
+ return (godot_validated_constructor)Variant::get_validated_constructor((Variant::Type)p_type, p_constructor);
+}
+
+godot_ptr_constructor GDAPI godot_variant_get_ptr_constructor(godot_variant_type p_type, int p_constructor) {
+ return (godot_ptr_constructor)Variant::get_ptr_constructor((Variant::Type)p_type, p_constructor);
+}
+
+int GDAPI godot_variant_get_constructor_argument_count(godot_variant_type p_type, int p_constructor) {
+ return Variant::get_constructor_argument_count((Variant::Type)p_type, p_constructor);
+}
+
+godot_variant_type GDAPI godot_variant_get_constructor_argument_type(godot_variant_type p_type, int p_constructor, int p_argument) {
+ return (godot_variant_type)Variant::get_constructor_argument_type((Variant::Type)p_type, p_constructor, p_argument);
+}
+
+godot_string GDAPI godot_variant_get_constructor_argument_name(godot_variant_type p_type, int p_constructor, int p_argument) {
+ String name = Variant::get_constructor_argument_name((Variant::Type)p_type, p_constructor, p_argument);
+ godot_string ret;
+ memnew_placement(&ret, String(name));
+ return ret;
+}
+
+void GDAPI godot_variant_construct(godot_variant_type p_type, godot_variant *p_base, const godot_variant **p_args, int p_argcount, godot_variant_call_error *r_error) {
+ Variant::construct((Variant::Type)p_type, *((Variant *)p_base), (const Variant **)p_args, p_argcount, *((Callable::CallError *)r_error));
+}
+
+/// Properties.
+godot_variant_type GDAPI godot_variant_get_member_type(godot_variant_type p_type, const godot_string_name *p_member) {
+ return (godot_variant_type)Variant::get_member_type((Variant::Type)p_type, *((const StringName *)p_member));
+}
+
+godot_variant_type GDAPI godot_variant_get_member_type_with_cstring(godot_variant_type p_type, const char *p_member) {
+ return (godot_variant_type)Variant::get_member_type((Variant::Type)p_type, StringName(p_member));
+}
+
+int GDAPI godot_variant_get_member_count(godot_variant_type p_type) {
+ return Variant::get_member_count((Variant::Type)p_type);
+}
+
+void GDAPI godot_variant_get_member_list(godot_variant_type p_type, godot_string_name *r_list) {
+ List<StringName> members;
+ Variant::get_member_list((Variant::Type)p_type, &members);
+ int i = 0;
+ for (const List<StringName>::Element *E = members.front(); E; E = E->next()) {
+ memnew_placement_custom(&r_list[i++], StringName, StringName(E->get()));
+ }
+}
+
+godot_validated_setter GDAPI godot_variant_get_validated_setter(godot_variant_type p_type, const godot_string_name *p_member) {
+ return (godot_validated_setter)Variant::get_member_validated_setter((Variant::Type)p_type, *((const StringName *)p_member));
+}
+
+godot_validated_setter GDAPI godot_variant_get_validated_setter_with_cstring(godot_variant_type p_type, const char *p_member) {
+ return (godot_validated_setter)Variant::get_member_validated_setter((Variant::Type)p_type, StringName(p_member));
+}
+
+godot_validated_getter GDAPI godot_variant_get_validated_getter(godot_variant_type p_type, const godot_string_name *p_member) {
+ return (godot_validated_getter)Variant::get_member_validated_getter((Variant::Type)p_type, *((const StringName *)p_member));
+}
+
+godot_validated_getter GDAPI godot_variant_get_validated_getter_with_cstring(godot_variant_type p_type, const char *p_member) {
+ return (godot_validated_getter)Variant::get_member_validated_getter((Variant::Type)p_type, StringName(p_member));
+}
+
+godot_ptr_setter GDAPI godot_variant_get_ptr_setter(godot_variant_type p_type, const godot_string_name *p_member) {
+ return (godot_ptr_setter)Variant::get_member_ptr_setter((Variant::Type)p_type, *((const StringName *)p_member));
+}
+
+godot_ptr_setter GDAPI godot_variant_get_ptr_setter_with_cstring(godot_variant_type p_type, const char *p_member) {
+ return (godot_ptr_setter)Variant::get_member_ptr_setter((Variant::Type)p_type, StringName(p_member));
+}
+
+godot_ptr_getter GDAPI godot_variant_get_ptr_getter(godot_variant_type p_type, const godot_string_name *p_member) {
+ return (godot_ptr_getter)Variant::get_member_ptr_getter((Variant::Type)p_type, *((const StringName *)p_member));
+}
+
+godot_ptr_getter GDAPI godot_variant_get_ptr_getter_with_cstring(godot_variant_type p_type, const char *p_member) {
+ return (godot_ptr_getter)Variant::get_member_ptr_getter((Variant::Type)p_type, StringName(p_member));
+}
+
+/// Indexing.
+bool GDAPI godot_variant_has_indexing(godot_variant_type p_type) {
+ return Variant::has_indexing((Variant::Type)p_type);
+}
+
+godot_variant_type GDAPI godot_variant_get_indexed_element_type(godot_variant_type p_type) {
+ return (godot_variant_type)Variant::get_indexed_element_type((Variant::Type)p_type);
+}
+
+godot_validated_indexed_setter GDAPI godot_variant_get_validated_indexed_setter(godot_variant_type p_type) {
+ return (godot_validated_indexed_setter)Variant::get_member_validated_indexed_setter((Variant::Type)p_type);
+}
+
+godot_validated_indexed_getter GDAPI godot_variant_get_validated_indexed_getter(godot_variant_type p_type) {
+ return (godot_validated_indexed_getter)Variant::get_member_validated_indexed_getter((Variant::Type)p_type);
+}
+
+godot_ptr_indexed_setter GDAPI godot_variant_get_ptr_indexed_setter(godot_variant_type p_type) {
+ return (godot_ptr_indexed_setter)Variant::get_member_ptr_indexed_setter((Variant::Type)p_type);
+}
+
+godot_ptr_indexed_getter GDAPI godot_variant_get_ptr_indexed_getter(godot_variant_type p_type) {
+ return (godot_ptr_indexed_getter)Variant::get_member_ptr_indexed_getter((Variant::Type)p_type);
+}
+
+uint64_t GDAPI godot_variant_get_indexed_size(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return self->get_indexed_size();
+}
+
+/// Keying.
+bool GDAPI godot_variant_is_keyed(godot_variant_type p_type) {
+ return Variant::is_keyed((Variant::Type)p_type);
+}
+
+godot_validated_keyed_setter GDAPI godot_variant_get_validated_keyed_setter(godot_variant_type p_type) {
+ return (godot_validated_keyed_setter)Variant::get_member_validated_keyed_setter((Variant::Type)p_type);
+}
+
+godot_validated_keyed_getter GDAPI godot_variant_get_validated_keyed_getter(godot_variant_type p_type) {
+ return (godot_validated_keyed_getter)Variant::get_member_validated_keyed_getter((Variant::Type)p_type);
+}
+
+godot_validated_keyed_checker GDAPI godot_variant_get_validated_keyed_checker(godot_variant_type p_type) {
+ return (godot_validated_keyed_checker)Variant::get_member_validated_keyed_checker((Variant::Type)p_type);
+}
+
+godot_ptr_keyed_setter GDAPI godot_variant_get_ptr_keyed_setter(godot_variant_type p_type) {
+ return (godot_ptr_keyed_setter)Variant::get_member_ptr_keyed_setter((Variant::Type)p_type);
+}
+
+godot_ptr_keyed_getter GDAPI godot_variant_get_ptr_keyed_getter(godot_variant_type p_type) {
+ return (godot_ptr_keyed_getter)Variant::get_member_ptr_keyed_getter((Variant::Type)p_type);
+}
+
+godot_ptr_keyed_checker GDAPI godot_variant_get_ptr_keyed_checker(godot_variant_type p_type) {
+ return (godot_ptr_keyed_checker)Variant::get_member_ptr_keyed_checker((Variant::Type)p_type);
+}
+
+/// Constants.
+int GDAPI godot_variant_get_constants_count(godot_variant_type p_type) {
+ return Variant::get_constants_count_for_type((Variant::Type)p_type);
+}
+
+void GDAPI godot_variant_get_constants_list(godot_variant_type p_type, godot_string_name *r_list) {
+ List<StringName> constants;
+ int i = 0;
+ Variant::get_constants_for_type((Variant::Type)p_type, &constants);
+ for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) {
+ memnew_placement_custom(&r_list[i++], StringName, StringName(E->get()));
+ }
+}
+
+bool GDAPI godot_variant_has_constant(godot_variant_type p_type, const godot_string_name *p_constant) {
+ return Variant::has_constant((Variant::Type)p_type, *((const StringName *)p_constant));
+}
+
+bool GDAPI godot_variant_has_constant_with_cstring(godot_variant_type p_type, const char *p_constant) {
+ return Variant::has_constant((Variant::Type)p_type, StringName(p_constant));
+}
+
+godot_variant GDAPI godot_variant_get_constant_value(godot_variant_type p_type, const godot_string_name *p_constant) {
+ Variant constant = Variant::get_constant_value((Variant::Type)p_type, *((const StringName *)p_constant));
+ godot_variant ret;
+ memnew_placement_custom(&ret, Variant, Variant(constant));
+ return ret;
+}
+
+godot_variant GDAPI godot_variant_get_constant_value_with_cstring(godot_variant_type p_type, const char *p_constant) {
+ Variant constant = Variant::get_constant_value((Variant::Type)p_type, StringName(p_constant));
+ godot_variant ret;
+ memnew_placement_custom(&ret, Variant, Variant(constant));
+ return ret;
+}
+
+/// Utilities.
+bool GDAPI godot_variant_has_utility_function(const godot_string_name *p_function) {
+ return Variant::has_utility_function(*((const StringName *)p_function));
+}
+
+bool GDAPI godot_variant_has_utility_function_with_cstring(const char *p_function) {
+ return Variant::has_utility_function(StringName(p_function));
+}
+
+void GDAPI godot_variant_call_utility_function(const godot_string_name *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error) {
+ const StringName *function = (const StringName *)p_function;
Variant *ret = (Variant *)r_ret;
- Variant::evaluate(op, *a, *b, *ret, *r_valid);
+ const Variant **args = (const Variant **)p_args;
+ Callable::CallError error;
+
+ Variant::call_utility_function(*function, ret, args, p_argument_count, error);
+
+ if (r_error) {
+ r_error->error = (godot_variant_call_error_error)error.error;
+ r_error->argument = error.argument;
+ r_error->expected = (godot_variant_type)error.expected;
+ }
+}
+
+void GDAPI godot_variant_call_utility_function_with_cstring(const char *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error) {
+ Variant *ret = (Variant *)r_ret;
+ const Variant **args = (const Variant **)p_args;
+ Callable::CallError error;
+
+ Variant::call_utility_function(StringName(p_function), ret, args, p_argument_count, error);
+
+ if (r_error) {
+ r_error->error = (godot_variant_call_error_error)error.error;
+ r_error->argument = error.argument;
+ r_error->expected = (godot_variant_type)error.expected;
+ }
+}
+
+godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function(const godot_string_name *p_function) {
+ return (godot_ptr_utility_function)Variant::get_ptr_utility_function(*((const StringName *)p_function));
+}
+
+godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function_with_cstring(const char *p_function) {
+ return (godot_ptr_utility_function)Variant::get_ptr_utility_function(StringName(p_function));
+}
+
+godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function(const godot_string_name *p_function) {
+ return (godot_validated_utility_function)Variant::get_validated_utility_function(*((const StringName *)p_function));
+}
+
+godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function_with_cstring(const char *p_function) {
+ return (godot_validated_utility_function)Variant::get_validated_utility_function(StringName(p_function));
+}
+
+godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type(const godot_string_name *p_function) {
+ return (godot_variant_utility_function_type)Variant::get_utility_function_type(*((const StringName *)p_function));
+}
+
+godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type_with_cstring(const char *p_function) {
+ return (godot_variant_utility_function_type)Variant::get_utility_function_type(StringName(p_function));
+}
+
+int GDAPI godot_variant_get_utility_function_argument_count(const godot_string_name *p_function) {
+ return Variant::get_utility_function_argument_count(*((const StringName *)p_function));
+}
+
+int GDAPI godot_variant_get_utility_function_argument_count_with_cstring(const char *p_function) {
+ return Variant::get_utility_function_argument_count(StringName(p_function));
+}
+
+godot_variant_type GDAPI godot_variant_get_utility_function_argument_type(const godot_string_name *p_function, int p_argument) {
+ return (godot_variant_type)Variant::get_utility_function_argument_type(*((const StringName *)p_function), p_argument);
+}
+
+godot_variant_type GDAPI godot_variant_get_utility_function_argument_type_with_cstring(const char *p_function, int p_argument) {
+ return (godot_variant_type)Variant::get_utility_function_argument_type(StringName(p_function), p_argument);
+}
+
+godot_string GDAPI godot_variant_get_utility_function_argument_name(const godot_string_name *p_function, int p_argument) {
+ String argument_name = Variant::get_utility_function_argument_name(*((const StringName *)p_function), p_argument);
+ godot_string ret;
+ memnew_placement_custom(&ret, String, String(argument_name));
+ return ret;
+}
+
+godot_string GDAPI godot_variant_get_utility_function_argument_name_with_cstring(const char *p_function, int p_argument) {
+ String argument_name = Variant::get_utility_function_argument_name(StringName(p_function), p_argument);
+ godot_string ret;
+ memnew_placement_custom(&ret, String, String(argument_name));
+ return ret;
+}
+
+bool GDAPI godot_variant_has_utility_function_return_value(const godot_string_name *p_function) {
+ return Variant::has_utility_function_return_value(*((const StringName *)p_function));
+}
+
+bool GDAPI godot_variant_has_utility_function_return_value_with_cstring(const char *p_function) {
+ return Variant::has_utility_function_return_value(StringName(p_function));
+}
+
+godot_variant_type GDAPI godot_variant_get_utility_function_return_type(const godot_string_name *p_function) {
+ return (godot_variant_type)Variant::get_utility_function_return_type(*((const StringName *)p_function));
+}
+
+godot_variant_type GDAPI godot_variant_get_utility_function_return_type_with_cstring(const char *p_function) {
+ return (godot_variant_type)Variant::get_utility_function_return_type(StringName(p_function));
+}
+
+bool GDAPI godot_variant_is_utility_function_vararg(const godot_string_name *p_function) {
+ return Variant::is_utility_function_vararg(*((const StringName *)p_function));
+}
+
+bool GDAPI godot_variant_is_utility_function_vararg_with_cstring(const char *p_function) {
+ return Variant::is_utility_function_vararg(StringName(p_function));
+}
+
+int GDAPI godot_variant_get_utility_function_count() {
+ return Variant::get_utility_function_count();
+}
+
+void GDAPI godot_variant_get_utility_function_list(godot_string_name *r_functions) {
+ List<StringName> functions;
+ godot_string_name *func = r_functions;
+ Variant::get_utility_function_list(&functions);
+
+ for (const List<StringName>::Element *E = functions.front(); E; E = E->next()) {
+ memnew_placement_custom(func++, StringName, StringName(E->get()));
+ }
+}
+
+// Introspection.
+
+godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return (godot_variant_type)self->get_type();
+}
+
+bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string_name *p_method) {
+ const Variant *self = (const Variant *)p_self;
+ const StringName *method = (const StringName *)p_method;
+ return self->has_method(*method);
+}
+
+bool GDAPI godot_variant_has_member(godot_variant_type p_type, const godot_string_name *p_member) {
+ return Variant::has_member((Variant::Type)p_type, *((const StringName *)p_member));
+}
+
+bool GDAPI godot_variant_has_key(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid) {
+ const Variant *self = (const Variant *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ return self->has_key(*key, *r_valid);
+}
+
+godot_string GDAPI godot_variant_get_type_name(godot_variant_type p_type) {
+ String name = Variant::get_type_name((Variant::Type)p_type);
+ godot_string ret;
+ memnew_placement_custom(&ret, String, String(name));
+ return ret;
+}
+
+bool GDAPI godot_variant_can_convert(godot_variant_type p_from, godot_variant_type p_to) {
+ return Variant::can_convert((Variant::Type)p_from, (Variant::Type)p_to);
+}
+
+bool GDAPI godot_variant_can_convert_strict(godot_variant_type p_from, godot_variant_type p_to) {
+ return Variant::can_convert_strict((Variant::Type)p_from, (Variant::Type)p_to);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp
index 1ba846d315..ebb1996649 100644
--- a/modules/gdnative/gdnative/vector2.cpp
+++ b/modules/gdnative/gdnative/vector2.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,430 +31,40 @@
#include "gdnative/vector2.h"
#include "core/math/vector2.h"
-#include "core/variant/variant.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
static_assert(sizeof(godot_vector2) == sizeof(Vector2), "Vector2 size mismatch");
static_assert(sizeof(godot_vector2i) == sizeof(Vector2i), "Vector2i size mismatch");
-// Vector2
-
-void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y) {
- Vector2 *dest = (Vector2 *)r_dest;
- *dest = Vector2(p_x, p_y);
-}
-
-godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self) {
- godot_string ret;
- const Vector2 *self = (const Vector2 *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_vector2i GDAPI godot_vector2_as_vector2i(const godot_vector2 *p_self) {
- godot_vector2i dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *((Vector2i *)&dest) = Vector2i(*self);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_self) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *((Vector2 *)&dest) = self->normalized();
- return dest;
-}
-
-godot_real GDAPI godot_vector2_length(const godot_vector2 *p_self) {
- const Vector2 *self = (const Vector2 *)p_self;
- return self->length();
-}
-
-godot_real GDAPI godot_vector2_angle(const godot_vector2 *p_self) {
- const Vector2 *self = (const Vector2 *)p_self;
- return self->angle();
-}
-
-godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_self) {
- const Vector2 *self = (const Vector2 *)p_self;
- return self->length_squared();
-}
-
-godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self) {
- const Vector2 *self = (const Vector2 *)p_self;
- return self->is_normalized();
-}
-
-godot_vector2 GDAPI godot_vector2_direction_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *to = (const Vector2 *)p_to;
- *((Vector2 *)&dest) = self->direction_to(*to);
- return dest;
-}
-
-godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *to = (const Vector2 *)p_to;
- return self->distance_to(*to);
-}
-
-godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *to = (const Vector2 *)p_to;
- return self->distance_squared_to(*to);
-}
-
-godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *to = (const Vector2 *)p_to;
- return self->angle_to(*to);
-}
-
-godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_self, const godot_vector2 *p_to) {
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *to = (const Vector2 *)p_to;
- return self->angle_to_point(*to);
-}
-
-godot_vector2 GDAPI godot_vector2_lerp(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *b = (const Vector2 *)p_b;
- *((Vector2 *)&dest) = self->lerp(*b, p_t);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_vector2 *p_pre_a, const godot_vector2 *p_post_b, const godot_real p_t) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *b = (const Vector2 *)p_b;
- const Vector2 *pre_a = (const Vector2 *)p_pre_a;
- const Vector2 *post_b = (const Vector2 *)p_post_b;
- *((Vector2 *)&dest) = self->cubic_interpolate(*b, *pre_a, *post_b, p_t);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_move_toward(const godot_vector2 *p_self, const godot_vector2 *p_to, const godot_real p_delta) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *to = (const Vector2 *)p_to;
- *((Vector2 *)&dest) = self->move_toward(*to, p_delta);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_self, const godot_real p_phi) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
-
- *((Vector2 *)&dest) = self->rotated(p_phi);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_tangent(const godot_vector2 *p_self) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *((Vector2 *)&dest) = self->tangent();
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_self) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *((Vector2 *)&dest) = self->floor();
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_sign(const godot_vector2 *p_self) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *((Vector2 *)&dest) = self->sign();
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_self, const godot_vector2 *p_by) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *by = (const Vector2 *)p_by;
- *((Vector2 *)&dest) = self->snapped(*by);
- return dest;
-}
-
-godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_self) {
- const Vector2 *self = (const Vector2 *)p_self;
- return self->aspect();
-}
-
-godot_real GDAPI godot_vector2_dot(const godot_vector2 *p_self, const godot_vector2 *p_with) {
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *with = (const Vector2 *)p_with;
- return self->dot(*with);
-}
-
-godot_vector2 GDAPI godot_vector2_slide(const godot_vector2 *p_self, const godot_vector2 *p_n) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *n = (const Vector2 *)p_n;
- *((Vector2 *)&dest) = self->slide(*n);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_bounce(const godot_vector2 *p_self, const godot_vector2 *p_n) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *n = (const Vector2 *)p_n;
- *((Vector2 *)&dest) = self->bounce(*n);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_reflect(const godot_vector2 *p_self, const godot_vector2 *p_n) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *n = (const Vector2 *)p_n;
- *((Vector2 *)&dest) = self->reflect(*n);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_abs(const godot_vector2 *p_self) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *((Vector2 *)&dest) = self->abs();
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_self, const godot_real p_length) {
- godot_vector2 dest;
- const Vector2 *self = (const Vector2 *)p_self;
-
- *((Vector2 *)&dest) = self->clamped(p_length);
- return dest;
-}
-
-godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_self, const godot_vector2 *p_b) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *b = (const Vector2 *)p_b;
- *dest = *self + *b;
- return raw_dest;
-}
-
-godot_vector2 GDAPI godot_vector2_operator_subtract(const godot_vector2 *p_self, const godot_vector2 *p_b) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *b = (const Vector2 *)p_b;
- *dest = *self - *b;
- return raw_dest;
-}
-
-godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_self, const godot_vector2 *p_b) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *b = (const Vector2 *)p_b;
- *dest = *self * *b;
- return raw_dest;
-}
-
-godot_vector2 GDAPI godot_vector2_operator_multiply_scalar(const godot_vector2 *p_self, const godot_real p_b) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *dest = *self * p_b;
- return raw_dest;
-}
-
-godot_vector2 GDAPI godot_vector2_operator_divide_vector(const godot_vector2 *p_self, const godot_vector2 *p_b) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *b = (const Vector2 *)p_b;
- *dest = *self / *b;
- return raw_dest;
-}
-
-godot_vector2 GDAPI godot_vector2_operator_divide_scalar(const godot_vector2 *p_self, const godot_real p_b) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *dest = *self / p_b;
- return raw_dest;
-}
-
-godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_self, const godot_vector2 *p_b) {
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *b = (const Vector2 *)p_b;
- return *self == *b;
-}
-
-godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_self, const godot_vector2 *p_b) {
- const Vector2 *self = (const Vector2 *)p_self;
- const Vector2 *b = (const Vector2 *)p_b;
- return *self < *b;
-}
+#ifdef __cplusplus
+extern "C" {
+#endif
-godot_vector2 GDAPI godot_vector2_operator_neg(const godot_vector2 *p_self) {
- godot_vector2 raw_dest;
- Vector2 *dest = (Vector2 *)&raw_dest;
- const Vector2 *self = (const Vector2 *)p_self;
- *dest = -(*self);
- return raw_dest;
+void GDAPI godot_vector2_new(godot_vector2 *p_self) {
+ memnew_placement(p_self, Vector2);
}
-void GDAPI godot_vector2_set_x(godot_vector2 *p_self, const godot_real p_x) {
- Vector2 *self = (Vector2 *)p_self;
- self->x = p_x;
+void GDAPI godot_vector2i_new(godot_vector2i *p_self) {
+ memnew_placement(p_self, Vector2i);
}
-void GDAPI godot_vector2_set_y(godot_vector2 *p_self, const godot_real p_y) {
+godot_real_t GDAPI *godot_vector2_operator_index(godot_vector2 *p_self, godot_int p_index) {
Vector2 *self = (Vector2 *)p_self;
- self->y = p_y;
+ return (godot_real_t *)&self->operator[](p_index);
}
-godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_self) {
+const godot_real_t GDAPI *godot_vector2_operator_index_const(const godot_vector2 *p_self, godot_int p_index) {
const Vector2 *self = (const Vector2 *)p_self;
- return self->x;
-}
-
-godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_self) {
- const Vector2 *self = (const Vector2 *)p_self;
- return self->y;
-}
-
-// Vector2i
-
-void GDAPI godot_vector2i_new(godot_vector2i *r_dest, const godot_int p_x, const godot_int p_y) {
- Vector2i *dest = (Vector2i *)r_dest;
- *dest = Vector2i(p_x, p_y);
-}
-
-godot_string GDAPI godot_vector2i_as_string(const godot_vector2i *p_self) {
- godot_string ret;
- const Vector2i *self = (const Vector2i *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_vector2 GDAPI godot_vector2i_as_vector2(const godot_vector2i *p_self) {
- godot_vector2 dest;
- const Vector2i *self = (const Vector2i *)p_self;
- *((Vector2 *)&dest) = Vector2(*self);
- return dest;
-}
-
-godot_real GDAPI godot_vector2i_aspect(const godot_vector2i *p_self) {
- const Vector2i *self = (const Vector2i *)p_self;
- return self->aspect();
-}
-
-godot_vector2i GDAPI godot_vector2i_abs(const godot_vector2i *p_self) {
- godot_vector2i dest;
- const Vector2i *self = (const Vector2i *)p_self;
- *((Vector2i *)&dest) = self->abs();
- return dest;
-}
-
-godot_vector2i GDAPI godot_vector2i_sign(const godot_vector2i *p_self) {
- godot_vector2i dest;
- const Vector2i *self = (const Vector2i *)p_self;
- *((Vector2i *)&dest) = self->sign();
- return dest;
-}
-
-godot_vector2i GDAPI godot_vector2i_operator_add(const godot_vector2i *p_self, const godot_vector2i *p_b) {
- godot_vector2i raw_dest;
- Vector2i *dest = (Vector2i *)&raw_dest;
- const Vector2i *self = (const Vector2i *)p_self;
- const Vector2i *b = (const Vector2i *)p_b;
- *dest = *self + *b;
- return raw_dest;
-}
-
-godot_vector2i GDAPI godot_vector2i_operator_subtract(const godot_vector2i *p_self, const godot_vector2i *p_b) {
- godot_vector2i raw_dest;
- Vector2i *dest = (Vector2i *)&raw_dest;
- const Vector2i *self = (const Vector2i *)p_self;
- const Vector2i *b = (const Vector2i *)p_b;
- *dest = *self - *b;
- return raw_dest;
-}
-
-godot_vector2i GDAPI godot_vector2i_operator_multiply_vector(const godot_vector2i *p_self, const godot_vector2i *p_b) {
- godot_vector2i raw_dest;
- Vector2i *dest = (Vector2i *)&raw_dest;
- const Vector2i *self = (const Vector2i *)p_self;
- const Vector2i *b = (const Vector2i *)p_b;
- *dest = *self * *b;
- return raw_dest;
-}
-
-godot_vector2i GDAPI godot_vector2i_operator_multiply_scalar(const godot_vector2i *p_self, const godot_int p_b) {
- godot_vector2i raw_dest;
- Vector2i *dest = (Vector2i *)&raw_dest;
- const Vector2i *self = (const Vector2i *)p_self;
- *dest = *self * p_b;
- return raw_dest;
+ return (const godot_real_t *)&self->operator[](p_index);
}
-godot_vector2i GDAPI godot_vector2i_operator_divide_vector(const godot_vector2i *p_self, const godot_vector2i *p_b) {
- godot_vector2i raw_dest;
- Vector2i *dest = (Vector2i *)&raw_dest;
- const Vector2i *self = (const Vector2i *)p_self;
- const Vector2i *b = (const Vector2i *)p_b;
- *dest = *self / *b;
- return raw_dest;
-}
-
-godot_vector2i GDAPI godot_vector2i_operator_divide_scalar(const godot_vector2i *p_self, const godot_int p_b) {
- godot_vector2i raw_dest;
- Vector2i *dest = (Vector2i *)&raw_dest;
- const Vector2i *self = (const Vector2i *)p_self;
- *dest = *self / p_b;
- return raw_dest;
-}
-
-godot_bool GDAPI godot_vector2i_operator_equal(const godot_vector2i *p_self, const godot_vector2i *p_b) {
- const Vector2i *self = (const Vector2i *)p_self;
- const Vector2i *b = (const Vector2i *)p_b;
- return *self == *b;
-}
-
-godot_bool GDAPI godot_vector2i_operator_less(const godot_vector2i *p_self, const godot_vector2i *p_b) {
- const Vector2i *self = (const Vector2i *)p_self;
- const Vector2i *b = (const Vector2i *)p_b;
- return *self < *b;
-}
-
-godot_vector2i GDAPI godot_vector2i_operator_neg(const godot_vector2i *p_self) {
- godot_vector2i raw_dest;
- Vector2i *dest = (Vector2i *)&raw_dest;
- const Vector2i *self = (const Vector2i *)p_self;
- *dest = -(*self);
- return raw_dest;
-}
-
-void GDAPI godot_vector2i_set_x(godot_vector2i *p_self, const godot_int p_x) {
- Vector2i *self = (Vector2i *)p_self;
- self->x = p_x;
-}
-
-void GDAPI godot_vector2i_set_y(godot_vector2i *p_self, const godot_int p_y) {
+int32_t GDAPI *godot_vector2i_operator_index(godot_vector2i *p_self, godot_int p_index) {
Vector2i *self = (Vector2i *)p_self;
- self->y = p_y;
-}
-
-godot_int GDAPI godot_vector2i_get_x(const godot_vector2i *p_self) {
- const Vector2i *self = (const Vector2i *)p_self;
- return self->x;
+ return (int32_t *)&self->operator[](p_index);
}
-godot_int GDAPI godot_vector2i_get_y(const godot_vector2i *p_self) {
+const int32_t GDAPI *godot_vector2i_operator_index_const(const godot_vector2i *p_self, godot_int p_index) {
const Vector2i *self = (const Vector2i *)p_self;
- return self->y;
+ return (const int32_t *)&self->operator[](p_index);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp
index 3284afdc31..0fe1b292a7 100644
--- a/modules/gdnative/gdnative/vector3.cpp
+++ b/modules/gdnative/gdnative/vector3.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,433 +30,41 @@
#include "gdnative/vector3.h"
-#include "core/templates/vector.h"
-#include "core/variant/variant.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "core/math/vector3.h"
static_assert(sizeof(godot_vector3) == sizeof(Vector3), "Vector3 size mismatch");
static_assert(sizeof(godot_vector3i) == sizeof(Vector3i), "Vector3i size mismatch");
-// Vector3
-
-void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z) {
- Vector3 *dest = (Vector3 *)r_dest;
- *dest = Vector3(p_x, p_y, p_z);
-}
-
-godot_string GDAPI godot_vector3_as_string(const godot_vector3 *p_self) {
- godot_string ret;
- const Vector3 *self = (const Vector3 *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_vector3i GDAPI godot_vector3_as_vector3i(const godot_vector3 *p_self) {
- godot_vector3i dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *((Vector3i *)&dest) = Vector3i(*self);
- return dest;
-}
-
-godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_self) {
- const Vector3 *self = (const Vector3 *)p_self;
- return self->min_axis();
-}
-
-godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_self) {
- const Vector3 *self = (const Vector3 *)p_self;
- return self->max_axis();
-}
-
-godot_real GDAPI godot_vector3_length(const godot_vector3 *p_self) {
- const Vector3 *self = (const Vector3 *)p_self;
- return self->length();
-}
-
-godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_self) {
- const Vector3 *self = (const Vector3 *)p_self;
- return self->length_squared();
-}
-
-godot_bool GDAPI godot_vector3_is_normalized(const godot_vector3 *p_self) {
- const Vector3 *self = (const Vector3 *)p_self;
- return self->is_normalized();
-}
-
-godot_vector3 GDAPI godot_vector3_normalized(const godot_vector3 *p_self) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *((Vector3 *)&dest) = self->normalized();
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_inverse(const godot_vector3 *p_self) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *((Vector3 *)&dest) = self->inverse();
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_snapped(const godot_vector3 *p_self, const godot_vector3 *p_by) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *snap_axis = (const Vector3 *)p_by;
-
- *((Vector3 *)&dest) = self->snapped(*snap_axis);
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_self, const godot_vector3 *p_axis, const godot_real p_phi) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *axis = (const Vector3 *)p_axis;
- *((Vector3 *)&dest) = self->rotated(*axis, p_phi);
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_lerp(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- *((Vector3 *)&dest) = self->lerp(*b, p_t);
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_vector3 *p_pre_a, const godot_vector3 *p_post_b, const godot_real p_t) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- const Vector3 *pre_a = (const Vector3 *)p_pre_a;
- const Vector3 *post_b = (const Vector3 *)p_post_b;
- *((Vector3 *)&dest) = self->cubic_interpolate(*b, *pre_a, *post_b, p_t);
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_move_toward(const godot_vector3 *p_self, const godot_vector3 *p_to, const godot_real p_delta) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *to = (const Vector3 *)p_to;
- *((Vector3 *)&dest) = self->move_toward(*to, p_delta);
- return dest;
-}
-
-godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- return self->dot(*b);
-}
-
-godot_vector3 GDAPI godot_vector3_cross(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- *((Vector3 *)&dest) = self->cross(*b);
- return dest;
-}
-
-godot_basis GDAPI godot_vector3_outer(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- godot_basis dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- *((Basis *)&dest) = self->outer(*b);
- return dest;
-}
-
-godot_basis GDAPI godot_vector3_to_diagonal_matrix(const godot_vector3 *p_self) {
- godot_basis dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *((Basis *)&dest) = self->to_diagonal_matrix();
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_self) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *((Vector3 *)&dest) = self->abs();
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_sign(const godot_vector3 *p_self) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *((Vector3 *)&dest) = self->sign();
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *((Vector3 *)&dest) = self->floor();
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *((Vector3 *)&dest) = self->ceil();
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_direction_to(const godot_vector3 *p_self, const godot_vector3 *p_to) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *to = (const Vector3 *)p_to;
- *((Vector3 *)&dest) = self->direction_to(*to);
- return dest;
-}
-
-godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- return self->distance_to(*b);
-}
-
-godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- return self->distance_squared_to(*b);
-}
-
-godot_real GDAPI godot_vector3_angle_to(const godot_vector3 *p_self, const godot_vector3 *p_to) {
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *to = (const Vector3 *)p_to;
- return self->angle_to(*to);
-}
-
-godot_vector3 GDAPI godot_vector3_slide(const godot_vector3 *p_self, const godot_vector3 *p_n) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *n = (const Vector3 *)p_n;
- *((Vector3 *)&dest) = self->slide(*n);
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_bounce(const godot_vector3 *p_self, const godot_vector3 *p_n) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *n = (const Vector3 *)p_n;
- *((Vector3 *)&dest) = self->bounce(*n);
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_reflect(const godot_vector3 *p_self, const godot_vector3 *p_n) {
- godot_vector3 dest;
- const Vector3 *self = (const Vector3 *)p_self;
- const Vector3 *n = (const Vector3 *)p_n;
- *((Vector3 *)&dest) = self->reflect(*n);
- return dest;
-}
-
-godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- Vector3 *self = (Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- *dest = *self + *b;
- return raw_dest;
-}
-
-godot_vector3 GDAPI godot_vector3_operator_subtract(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- Vector3 *self = (Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- *dest = *self - *b;
- return raw_dest;
-}
-
-godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- Vector3 *self = (Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- *dest = *self * *b;
- return raw_dest;
-}
-
-godot_vector3 GDAPI godot_vector3_operator_multiply_scalar(const godot_vector3 *p_self, const godot_real p_b) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- Vector3 *self = (Vector3 *)p_self;
- *dest = *self * p_b;
- return raw_dest;
-}
-
-godot_vector3 GDAPI godot_vector3_operator_divide_vector(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- Vector3 *self = (Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- *dest = *self / *b;
- return raw_dest;
-}
-
-godot_vector3 GDAPI godot_vector3_operator_divide_scalar(const godot_vector3 *p_self, const godot_real p_b) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- Vector3 *self = (Vector3 *)p_self;
- *dest = *self / p_b;
- return raw_dest;
-}
-
-godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- Vector3 *self = (Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- return *self == *b;
-}
+#ifdef __cplusplus
+extern "C" {
+#endif
-godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_self, const godot_vector3 *p_b) {
- Vector3 *self = (Vector3 *)p_self;
- const Vector3 *b = (const Vector3 *)p_b;
- return *self < *b;
+void GDAPI godot_vector3_new(godot_vector3 *p_self) {
+ memnew_placement(p_self, Vector3);
}
-godot_vector3 GDAPI godot_vector3_operator_neg(const godot_vector3 *p_self) {
- godot_vector3 raw_dest;
- Vector3 *dest = (Vector3 *)&raw_dest;
- const Vector3 *self = (const Vector3 *)p_self;
- *dest = -(*self);
- return raw_dest;
+void GDAPI godot_vector3i_new(godot_vector3i *p_self) {
+ memnew_placement(p_self, Vector3i);
}
-void GDAPI godot_vector3_set_axis(godot_vector3 *p_self, const godot_vector3_axis p_axis, const godot_real p_val) {
+godot_real_t GDAPI *godot_vector3_operator_index(godot_vector3 *p_self, godot_int p_index) {
Vector3 *self = (Vector3 *)p_self;
- self->set_axis(p_axis, p_val);
+ return (godot_real_t *)&self->operator[](p_index);
}
-godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot_vector3_axis p_axis) {
+const godot_real_t GDAPI *godot_vector3_operator_index_const(const godot_vector3 *p_self, godot_int p_index) {
const Vector3 *self = (const Vector3 *)p_self;
- return self->get_axis(p_axis);
-}
-
-// Vector3i
-
-void GDAPI godot_vector3i_new(godot_vector3i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_z) {
- Vector3i *dest = (Vector3i *)r_dest;
- *dest = Vector3i(p_x, p_y, p_z);
-}
-
-godot_string GDAPI godot_vector3i_as_string(const godot_vector3i *p_self) {
- godot_string ret;
- const Vector3i *self = (const Vector3i *)p_self;
- memnew_placement(&ret, String(*self));
- return ret;
-}
-
-godot_vector3 GDAPI godot_vector3i_as_vector3(const godot_vector3i *p_self) {
- godot_vector3 dest;
- const Vector3i *self = (const Vector3i *)p_self;
- *((Vector3 *)&dest) = Vector3(*self);
- return dest;
-}
-
-godot_int GDAPI godot_vector3i_min_axis(const godot_vector3i *p_self) {
- const Vector3i *self = (const Vector3i *)p_self;
- return self->min_axis();
-}
-
-godot_int GDAPI godot_vector3i_max_axis(const godot_vector3i *p_self) {
- const Vector3i *self = (const Vector3i *)p_self;
- return self->max_axis();
-}
-
-godot_vector3i GDAPI godot_vector3i_abs(const godot_vector3i *p_self) {
- godot_vector3i dest;
- const Vector3i *self = (const Vector3i *)p_self;
- *((Vector3i *)&dest) = self->abs();
- return dest;
-}
-
-godot_vector3i GDAPI godot_vector3i_sign(const godot_vector3i *p_self) {
- godot_vector3i dest;
- const Vector3i *self = (const Vector3i *)p_self;
- *((Vector3i *)&dest) = self->sign();
- return dest;
-}
-
-godot_vector3i GDAPI godot_vector3i_operator_add(const godot_vector3i *p_self, const godot_vector3i *p_b) {
- godot_vector3i raw_dest;
- Vector3i *dest = (Vector3i *)&raw_dest;
- Vector3i *self = (Vector3i *)p_self;
- const Vector3i *b = (const Vector3i *)p_b;
- *dest = *self + *b;
- return raw_dest;
-}
-
-godot_vector3i GDAPI godot_vector3i_operator_subtract(const godot_vector3i *p_self, const godot_vector3i *p_b) {
- godot_vector3i raw_dest;
- Vector3i *dest = (Vector3i *)&raw_dest;
- Vector3i *self = (Vector3i *)p_self;
- const Vector3i *b = (const Vector3i *)p_b;
- *dest = *self - *b;
- return raw_dest;
-}
-
-godot_vector3i GDAPI godot_vector3i_operator_multiply_vector(const godot_vector3i *p_self, const godot_vector3i *p_b) {
- godot_vector3i raw_dest;
- Vector3i *dest = (Vector3i *)&raw_dest;
- Vector3i *self = (Vector3i *)p_self;
- const Vector3i *b = (const Vector3i *)p_b;
- *dest = *self * *b;
- return raw_dest;
-}
-
-godot_vector3i GDAPI godot_vector3i_operator_multiply_scalar(const godot_vector3i *p_self, const godot_int p_b) {
- godot_vector3i raw_dest;
- Vector3i *dest = (Vector3i *)&raw_dest;
- Vector3i *self = (Vector3i *)p_self;
- *dest = *self * p_b;
- return raw_dest;
-}
-
-godot_vector3i GDAPI godot_vector3i_operator_divide_vector(const godot_vector3i *p_self, const godot_vector3i *p_b) {
- godot_vector3i raw_dest;
- Vector3i *dest = (Vector3i *)&raw_dest;
- Vector3i *self = (Vector3i *)p_self;
- const Vector3i *b = (const Vector3i *)p_b;
- *dest = *self / *b;
- return raw_dest;
-}
-
-godot_vector3i GDAPI godot_vector3i_operator_divide_scalar(const godot_vector3i *p_self, const godot_int p_b) {
- godot_vector3i raw_dest;
- Vector3i *dest = (Vector3i *)&raw_dest;
- Vector3i *self = (Vector3i *)p_self;
- *dest = *self / p_b;
- return raw_dest;
-}
-
-godot_bool GDAPI godot_vector3i_operator_equal(const godot_vector3i *p_self, const godot_vector3i *p_b) {
- Vector3i *self = (Vector3i *)p_self;
- const Vector3i *b = (const Vector3i *)p_b;
- return *self == *b;
-}
-
-godot_bool GDAPI godot_vector3i_operator_less(const godot_vector3i *p_self, const godot_vector3i *p_b) {
- Vector3i *self = (Vector3i *)p_self;
- const Vector3i *b = (const Vector3i *)p_b;
- return *self < *b;
-}
-
-godot_vector3i GDAPI godot_vector3i_operator_neg(const godot_vector3i *p_self) {
- godot_vector3i raw_dest;
- Vector3i *dest = (Vector3i *)&raw_dest;
- const Vector3i *self = (const Vector3i *)p_self;
- *dest = -(*self);
- return raw_dest;
+ return (const godot_real_t *)&self->operator[](p_index);
}
-void GDAPI godot_vector3i_set_axis(godot_vector3i *p_self, const godot_vector3_axis p_axis, const godot_int p_val) {
+int32_t GDAPI *godot_vector3i_operator_index(godot_vector3i *p_self, godot_int p_index) {
Vector3i *self = (Vector3i *)p_self;
- self->set_axis(p_axis, p_val);
+ return (int32_t *)&self->operator[](p_index);
}
-godot_int GDAPI godot_vector3i_get_axis(const godot_vector3i *p_self, const godot_vector3_axis p_axis) {
+const int32_t GDAPI *godot_vector3i_operator_index_const(const godot_vector3i *p_self, godot_int p_index) {
const Vector3i *self = (const Vector3i *)p_self;
- return self->get_axis(p_axis);
+ return (const int32_t *)&self->operator[](p_index);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index b3fd033e6c..c163fbbc1b 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -1,8074 +1,5249 @@
{
- "core": {
- "type": "CORE",
- "version": {
- "major": 4,
- "minor": 0
- },
- "next": null,
- "api": [
- {
- "name": "godot_aabb_new",
- "return_type": "void",
- "arguments": [
- ["godot_aabb *", "r_dest"],
- ["const godot_vector3 *", "p_pos"],
- ["const godot_vector3 *", "p_size"]
- ]
- },
- {
- "name": "godot_aabb_get_position",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_set_position",
- "return_type": "void",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_aabb_get_size",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_set_size",
- "return_type": "void",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_aabb_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_abs",
- "return_type": "godot_aabb",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_get_area",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_has_no_area",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_has_no_surface",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_intersects",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_aabb *", "p_with"]
- ]
- },
- {
- "name": "godot_aabb_encloses",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_aabb *", "p_with"]
- ]
- },
- {
- "name": "godot_aabb_merge",
- "return_type": "godot_aabb",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_aabb *", "p_with"]
- ]
- },
- {
- "name": "godot_aabb_intersection",
- "return_type": "godot_aabb",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_aabb *", "p_with"]
- ]
- },
- {
- "name": "godot_aabb_intersects_plane",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_plane *", "p_plane"]
- ]
- },
- {
- "name": "godot_aabb_intersects_segment",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_vector3 *", "p_from"],
- ["const godot_vector3 *", "p_to"]
- ]
- },
- {
- "name": "godot_aabb_has_point",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_vector3 *", "p_point"]
- ]
- },
- {
- "name": "godot_aabb_get_support",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_vector3 *", "p_dir"]
- ]
- },
- {
- "name": "godot_aabb_get_longest_axis",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_get_longest_axis_index",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_get_longest_axis_size",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_get_shortest_axis",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_get_shortest_axis_index",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_get_shortest_axis_size",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_aabb *", "p_self"]
- ]
- },
- {
- "name": "godot_aabb_expand",
- "return_type": "godot_aabb",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_vector3 *", "p_to_point"]
- ]
- },
- {
- "name": "godot_aabb_grow",
- "return_type": "godot_aabb",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_real", "p_by"]
- ]
- },
- {
- "name": "godot_aabb_get_endpoint",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_aabb_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_aabb *", "p_self"],
- ["const godot_aabb *", "p_b"]
- ]
- },
- {
- "name": "godot_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_array *", "p_src"]
- ]
- },
- {
- "name": "godot_array_new_packed_color_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_color_array *", "p_pca"]
- ]
- },
- {
- "name": "godot_array_new_packed_vector3_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_vector3_array *", "p_pv3a"]
- ]
- },
- {
- "name": "godot_array_new_packed_vector2_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_vector2_array *", "p_pv2a"]
- ]
- },
- {
- "name": "godot_array_new_packed_vector2i_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_vector2i_array *", "p_pv2a"]
- ]
- },
- {
- "name": "godot_array_new_packed_string_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_string_array *", "p_psa"]
- ]
- },
- {
- "name": "godot_array_new_packed_float32_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_float32_array *", "p_pra"]
- ]
- },
- {
- "name": "godot_array_new_packed_float64_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_float64_array *", "p_pra"]
- ]
- },
- {
- "name": "godot_array_new_packed_int32_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_int32_array *", "p_pia"]
- ]
- },
- {
- "name": "godot_array_new_packed_int64_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_int64_array *", "p_pia"]
- ]
- },
- {
- "name": "godot_array_new_packed_byte_array",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "r_dest"],
- ["const godot_packed_byte_array *", "p_pba"]
- ]
- },
- {
- "name": "godot_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_get",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_array_operator_index",
- "return_type": "godot_variant *",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_array_operator_index_const",
- "return_type": "const godot_variant *",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_clear",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_duplicate",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_bool", "p_deep"]
- ]
- },
- {
- "name": "godot_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_erase",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_front",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_back",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_find",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_what"],
- ["const godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_array_find_last",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_what"]
- ]
- },
- {
- "name": "godot_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_hash",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_insert",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_pos"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_max",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_min",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_pop_back",
- "return_type": "godot_variant",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_pop_front",
- "return_type": "godot_variant",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_push_front",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_array_rfind",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_variant *", "p_what"],
- ["const godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_shuffle",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_slice",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_array *", "p_self"],
- ["const godot_int", "p_begin"],
- ["const godot_int", "p_end"],
- ["const godot_int", "p_step"],
- ["const godot_bool", "p_deep"]
- ]
- },
- {
- "name": "godot_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_array_sort_custom",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"],
- ["godot_object *", "p_obj"],
- ["const godot_string *", "p_func"]
- ]
- },
- {
- "name": "godot_array_bsearch",
- "return_type": "godot_int",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"],
- ["const godot_bool", "p_before"]
- ]
- },
- {
- "name": "godot_array_bsearch_custom",
- "return_type": "godot_int",
- "arguments": [
- ["godot_array *", "p_self"],
- ["const godot_variant *", "p_value"],
- ["godot_object *", "p_obj"],
- ["const godot_string *", "p_func"],
- ["const godot_bool", "p_before"]
- ]
- },
- {
- "name": "godot_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_array *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_new_with_rows",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"],
- ["const godot_vector3 *", "p_x_axis"],
- ["const godot_vector3 *", "p_y_axis"],
- ["const godot_vector3 *", "p_z_axis"]
- ]
- },
- {
- "name": "godot_basis_new_with_axis_and_angle",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_basis_new_with_euler",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"],
- ["const godot_vector3 *", "p_euler"]
- ]
- },
- {
- "name": "godot_basis_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_inverse",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_transposed",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_orthonormalized",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_determinant",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_rotated",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_basis_scaled",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_scale"]
- ]
- },
- {
- "name": "godot_basis_get_scale",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_get_euler",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_tdotx",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_with"]
- ]
- },
- {
- "name": "godot_basis_tdoty",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_with"]
- ]
- },
- {
- "name": "godot_basis_tdotz",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_with"]
- ]
- },
- {
- "name": "godot_basis_xform",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_basis_xform_inv",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_basis_get_orthogonal_index",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_new",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"]
- ]
- },
- {
- "name": "godot_basis_new_with_euler_quat",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "r_dest"],
- ["const godot_quat *", "p_euler"]
- ]
- },
- {
- "name": "godot_basis_get_elements",
- "return_type": "void",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["godot_vector3 *", "p_elements"]
- ]
- },
- {
- "name": "godot_basis_get_axis",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_int", "p_axis"]
- ]
- },
- {
- "name": "godot_basis_set_axis",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["const godot_int", "p_axis"],
- ["const godot_vector3 *", "p_value"]
- ]
- },
- {
- "name": "godot_basis_get_row",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_int", "p_row"]
- ]
- },
- {
- "name": "godot_basis_set_row",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["const godot_int", "p_row"],
- ["const godot_vector3 *", "p_value"]
- ]
- },
- {
- "name": "godot_basis_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"]
- ]
- },
- {
- "name": "godot_basis_operator_add",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"]
- ]
- },
- {
- "name": "godot_basis_operator_subtract",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"]
- ]
- },
- {
- "name": "godot_basis_operator_multiply_vector",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"]
- ]
- },
- {
- "name": "godot_basis_operator_multiply_scalar",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_basis_slerp",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_basis *", "p_self"],
- ["const godot_basis *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_basis_get_quat",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_basis *", "p_self"]
- ]
- },
- {
- "name": "godot_basis_set_quat",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["const godot_quat *", "p_quat"]
- ]
- },
- {
- "name": "godot_basis_set_axis_angle_scale",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_axis"],
- ["godot_real", "p_phi"],
- ["const godot_vector3 *", "p_scale"]
- ]
- },
- {
- "name": "godot_basis_set_euler_scale",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["const godot_vector3 *", "p_euler"],
- ["const godot_vector3 *", "p_scale"]
- ]
- },
- {
- "name": "godot_basis_set_quat_scale",
- "return_type": "void",
- "arguments": [
- ["godot_basis *", "p_self"],
- ["const godot_quat *", "p_quat"],
- ["const godot_vector3 *", "p_scale"]
- ]
- },
- {
- "name": "godot_callable_new_with_object",
- "return_type": "void",
- "arguments": [
- ["godot_callable *", "r_dest"],
- ["const godot_object *", "p_object"],
- ["const godot_string_name *", "p_method"]
- ]
- },
- {
- "name": "godot_callable_new_with_object_id",
- "return_type": "void",
- "arguments": [
- ["godot_callable *", "r_dest"],
- ["uint64_t", "p_objectid"],
- ["const godot_string_name *", "p_method"]
- ]
- },
- {
- "name": "godot_callable_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_callable *", "r_dest"],
- ["const godot_callable *", "p_src"]
- ]
- },
- {
- "name": "godot_callable_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_call",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_callable *", "p_self"],
- ["const godot_variant **", "p_arguments"],
- ["godot_int", "p_argcount"],
- ["godot_variant *", "r_return_value"]
- ]
- },
- {
- "name": "godot_callable_call_deferred",
- "return_type": "void",
- "arguments": [
- ["const godot_callable *", "p_self"],
- ["const godot_variant **", "p_arguments"],
- ["godot_int", "p_argcount"]
- ]
- },
- {
- "name": "godot_callable_is_null",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_is_custom",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_is_standard",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_get_object",
- "return_type": "godot_object *",
- "arguments": [
- ["const godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_get_object_id",
- "return_type": "uint64_t",
- "arguments": [
- ["const godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_get_method",
- "return_type": "godot_string_name",
- "arguments": [
- ["const godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_hash",
- "return_type": "uint32_t",
- "arguments": [
- ["const godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_callable *", "p_self"]
- ]
- },
- {
- "name": "godot_callable_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_callable *", "p_self"],
- ["const godot_callable *", "p_other"]
- ]
- },
- {
- "name": "godot_callable_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_callable *", "p_self"],
- ["const godot_callable *", "p_other"]
- ]
- },
- {
- "name": "godot_signal_new_with_object",
- "return_type": "void",
- "arguments": [
- ["godot_signal *", "r_dest"],
- ["const godot_object *", "p_object"],
- ["const godot_string_name *", "p_method"]
- ]
- },
- {
- "name": "godot_signal_new_with_object_id",
- "return_type": "void",
- "arguments": [
- ["godot_signal *", "r_dest"],
- ["uint64_t", "p_objectid"],
- ["const godot_string_name *", "p_method"]
- ]
- },
- {
- "name": "godot_signal_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_signal *", "r_dest"],
- ["const godot_signal *", "p_src"]
- ]
- },
- {
- "name": "godot_signal_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_signal *", "p_self"]
- ]
- },
- {
- "name": "godot_signal_emit",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_signal *", "p_self"],
- ["const godot_variant **", "p_arguments"],
- ["godot_int", "p_argcount"]
- ]
- },
- {
- "name": "godot_signal_connect",
- "return_type": "godot_int",
- "arguments": [
- ["godot_signal *", "p_self"],
- ["const godot_callable *", "p_callable"],
- ["const godot_array *", "p_binds"],
- ["uint32_t", "p_flags"]
- ]
- },
- {
- "name": "godot_signal_disconnect",
- "return_type": "void",
- "arguments": [
- ["godot_signal *", "p_self"],
- ["const godot_callable *", "p_callable"]
- ]
- },
- {
- "name": "godot_signal_is_null",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_signal *", "p_self"]
- ]
- },
- {
- "name": "godot_signal_is_connected",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_signal *", "p_self"],
- ["const godot_callable *", "p_callable"]
- ]
- },
- {
- "name": "godot_signal_get_connections",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_signal *", "p_self"]
- ]
- },
- {
- "name": "godot_signal_get_object",
- "return_type": "godot_object *",
- "arguments": [
- ["const godot_signal *", "p_self"]
- ]
- },
- {
- "name": "godot_signal_get_object_id",
- "return_type": "uint64_t",
- "arguments": [
- ["const godot_signal *", "p_self"]
- ]
- },
- {
- "name": "godot_signal_get_name",
- "return_type": "godot_string_name",
- "arguments": [
- ["const godot_signal *", "p_self"]
- ]
- },
- {
- "name": "godot_signal_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_signal *", "p_self"]
- ]
- },
- {
- "name": "godot_signal_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_signal *", "p_self"],
- ["const godot_signal *", "p_other"]
- ]
- },
- {
- "name": "godot_signal_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_signal *", "p_self"],
- ["const godot_signal *", "p_other"]
- ]
- },
- {
- "name": "godot_color_new_rgba",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "r_dest"],
- ["const godot_real", "p_r"],
- ["const godot_real", "p_g"],
- ["const godot_real", "p_b"],
- ["const godot_real", "p_a"]
- ]
- },
- {
- "name": "godot_color_new_rgb",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "r_dest"],
- ["const godot_real", "p_r"],
- ["const godot_real", "p_g"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_color_get_r",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_set_r",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "p_self"],
- ["const godot_real", "r"]
- ]
- },
- {
- "name": "godot_color_get_g",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_set_g",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "p_self"],
- ["const godot_real", "g"]
- ]
- },
- {
- "name": "godot_color_get_b",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_set_b",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "p_self"],
- ["const godot_real", "b"]
- ]
- },
- {
- "name": "godot_color_get_a",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_set_a",
- "return_type": "void",
- "arguments": [
- ["godot_color *", "p_self"],
- ["const godot_real", "a"]
- ]
- },
- {
- "name": "godot_color_get_h",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_get_s",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_get_v",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_to_rgba32",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_to_argb32",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_inverted",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_lerp",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_color *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_color_blend",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_color *", "p_over"]
- ]
- },
- {
- "name": "godot_color_to_html",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_bool", "p_with_alpha"]
- ]
- },
- {
- "name": "godot_color_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_color *", "p_b"]
- ]
- },
- {
- "name": "godot_color_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_color *", "p_b"]
- ]
- },
- {
- "name": "godot_color_to_abgr32",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_to_abgr64",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_to_argb64",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_to_rgba64",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
- "name": "godot_color_darkened",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_real", "p_amount"]
- ]
- },
- {
- "name": "godot_color_from_hsv",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_real", "p_h"],
- ["const godot_real", "p_s"],
- ["const godot_real", "p_v"],
- ["const godot_real", "p_a"]
- ]
- },
- {
- "name": "godot_color_lightened",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_color *", "p_self"],
- ["const godot_real", "p_amount"]
- ]
- },
- {
- "name": "godot_dictionary_new",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "r_dest"]
- ]
- },
- {
- "name": "godot_dictionary_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "r_dest"],
- ["const godot_dictionary *", "p_src"]
- ]
- },
- {
- "name": "godot_dictionary_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_clear",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_has",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_has_all",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_array *", "p_keys"]
- ]
- },
- {
- "name": "godot_dictionary_erase",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_hash",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_keys",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_values",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_get",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_set",
- "return_type": "void",
- "arguments": [
- ["godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"],
- ["const godot_variant *", "p_value"]
- ]
- },
- {
- "name": "godot_dictionary_operator_index",
- "return_type": "godot_variant *",
- "arguments": [
- ["godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_operator_index_const",
- "return_type": "const godot_variant *",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_next",
- "return_type": "godot_variant *",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_dictionary_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_dictionary *", "p_b"]
- ]
- },
- {
- "name": "godot_dictionary_to_json",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_dictionary *", "p_self"]
- ]
- },
- {
- "name": "godot_dictionary_duplicate",
- "return_type": "godot_dictionary",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_bool", "p_deep"]
- ]
- },
- {
- "name": "godot_dictionary_get_with_default",
- "return_type": "godot_variant",
- "arguments": [
- ["const godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"],
- ["const godot_variant *", "p_default"]
- ]
- },
- {
- "name": "godot_dictionary_erase_with_return",
- "return_type": "bool",
- "arguments": [
- ["godot_dictionary *", "p_self"],
- ["const godot_variant *", "p_key"]
- ]
- },
- {
- "name": "godot_node_path_new",
- "return_type": "void",
- "arguments": [
- ["godot_node_path *", "r_dest"],
- ["const godot_string *", "p_from"]
- ]
- },
- {
- "name": "godot_node_path_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_node_path *", "r_dest"],
- ["const godot_node_path *", "p_src"]
- ]
- },
- {
- "name": "godot_node_path_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_is_absolute",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_get_name_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_get_name",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_node_path *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_node_path_get_subname_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_get_subname",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_node_path *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_node_path_get_concatenated_subnames",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_is_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_node_path_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_node_path *", "p_self"],
- ["const godot_node_path *", "p_b"]
- ]
- },
- {
- "name": "godot_node_path_get_as_property_path",
- "return_type": "godot_node_path",
- "arguments": [
- ["const godot_node_path *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_byte_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_byte_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "r_dest"],
- ["const godot_packed_byte_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_byte_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_byte_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_byte_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"],
- ["const uint8_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_byte_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"],
- ["const godot_packed_byte_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_byte_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const uint8_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_byte_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"],
- ["const uint8_t", "p_value"]
- ]
- },
- {
- "name": "godot_packed_byte_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_byte_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_byte_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"],
- ["const uint8_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_byte_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_byte_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_byte_array_ptr",
- "return_type": "const uint8_t *",
- "arguments": [
- ["const godot_packed_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_byte_array_ptrw",
- "return_type": "uint8_t *",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_byte_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const uint8_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_byte_array_get",
- "return_type": "uint8_t",
- "arguments": [
- ["const godot_packed_byte_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_byte_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_byte_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int32_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_int32_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "r_dest"],
- ["const godot_packed_int32_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_int32_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_int32_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_int32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int32_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"],
- ["const int32_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_int32_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"],
- ["const godot_packed_int32_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_int32_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const int32_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_int32_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"],
- ["const int32_t", "p_value"]
- ]
- },
- {
- "name": "godot_packed_int32_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int32_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int32_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"],
- ["const int32_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_int32_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_int32_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_int32_array_ptr",
- "return_type": "const int32_t *",
- "arguments": [
- ["const godot_packed_int32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int32_array_ptrw",
- "return_type": "int32_t *",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int32_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const int32_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_int32_array_get",
- "return_type": "int32_t",
- "arguments": [
- ["const godot_packed_int32_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_int32_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_int32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int32_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int64_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_int64_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "r_dest"],
- ["const godot_packed_int64_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_int64_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_int64_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_int64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int64_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"],
- ["const int64_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_int64_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"],
- ["const godot_packed_int64_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_int64_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const int64_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_int64_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"],
- ["const int64_t", "p_value"]
- ]
- },
- {
- "name": "godot_packed_int64_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int64_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int64_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"],
- ["const int64_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_int64_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_int64_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_int64_array_ptr",
- "return_type": "const int64_t *",
- "arguments": [
- ["const godot_packed_int64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int64_array_ptrw",
- "return_type": "int64_t *",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int64_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const int64_t", "p_data"]
- ]
- },
- {
- "name": "godot_packed_int64_array_get",
- "return_type": "int64_t",
- "arguments": [
- ["const godot_packed_int64_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_int64_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_int64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_int64_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_int64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float32_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_float32_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "r_dest"],
- ["const godot_packed_float32_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_float32_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_float32_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_float32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float32_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"],
- ["const float", "p_data"]
- ]
- },
- {
- "name": "godot_packed_float32_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"],
- ["const godot_packed_float32_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_float32_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const float", "p_data"]
- ]
- },
- {
- "name": "godot_packed_float32_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"],
- ["const float", "p_value"]
- ]
- },
- {
- "name": "godot_packed_float32_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float32_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float32_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"],
- ["const float", "p_data"]
- ]
- },
- {
- "name": "godot_packed_float32_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_float32_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_float32_array_ptr",
- "return_type": "const float *",
- "arguments": [
- ["const godot_packed_float32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float32_array_ptrw",
- "return_type": "float *",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float32_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const float", "p_data"]
- ]
- },
- {
- "name": "godot_packed_float32_array_get",
- "return_type": "float",
- "arguments": [
- ["const godot_packed_float32_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_float32_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_float32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float32_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float32_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float64_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_float64_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "r_dest"],
- ["const godot_packed_float64_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_float64_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_float64_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_float64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float64_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"],
- ["const double", "p_data"]
- ]
- },
- {
- "name": "godot_packed_float64_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"],
- ["const godot_packed_float64_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_float64_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const double", "p_data"]
- ]
- },
- {
- "name": "godot_packed_float64_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"],
- ["const double", "p_value"]
- ]
- },
- {
- "name": "godot_packed_float64_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float64_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float64_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"],
- ["const double", "p_data"]
- ]
- },
- {
- "name": "godot_packed_float64_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_float64_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_float64_array_ptr",
- "return_type": "const double *",
- "arguments": [
- ["const godot_packed_float64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float64_array_ptrw",
- "return_type": "double *",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float64_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const double", "p_data"]
- ]
- },
- {
- "name": "godot_packed_float64_array_get",
- "return_type": "double",
- "arguments": [
- ["const godot_packed_float64_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_float64_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_float64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_float64_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_float64_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_string_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_string_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "r_dest"],
- ["const godot_packed_string_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_string_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_string_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_string_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"],
- ["const godot_string *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_string_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"],
- ["const godot_packed_string_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_string_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_string_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_string *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_string_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_string_array *", "p_self"],
- ["const godot_string *", "p_value"]
- ]
- },
- {
- "name": "godot_packed_string_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_string_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_string_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"],
- ["const godot_string *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_string_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_string_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_string_array_ptr",
- "return_type": "const godot_string *",
- "arguments": [
- ["const godot_packed_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_string_array_ptrw",
- "return_type": "godot_string *",
- "arguments": [
- ["godot_packed_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_string_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_string *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_string_array_get",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_packed_string_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_string_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_string_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "r_dest"],
- ["const godot_packed_vector2_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"],
- ["const godot_vector2 *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"],
- ["const godot_packed_vector2_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector2 *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"],
- ["const godot_vector2 *", "p_value"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"],
- ["const godot_vector2 *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_ptr",
- "return_type": "const godot_vector2 *",
- "arguments": [
- ["const godot_packed_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_ptrw",
- "return_type": "godot_vector2 *",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector2 *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_get",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_packed_vector2_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "r_dest"],
- ["const godot_packed_vector2i_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_vector2i_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"],
- ["const godot_vector2i *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"],
- ["const godot_packed_vector2i_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector2i *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"],
- ["const godot_vector2i *", "p_value"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"],
- ["const godot_vector2i *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_ptr",
- "return_type": "const godot_vector2i *",
- "arguments": [
- ["const godot_packed_vector2i_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_ptrw",
- "return_type": "godot_vector2i *",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector2i *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_get",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_packed_vector2i_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_vector2i_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector2i_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector2i_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "r_dest"],
- ["const godot_packed_vector3_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"],
- ["const godot_vector3 *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"],
- ["const godot_packed_vector3_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector3 *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"],
- ["const godot_vector3 *", "p_value"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"],
- ["const godot_vector3 *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_ptr",
- "return_type": "const godot_vector3 *",
- "arguments": [
- ["const godot_packed_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_ptrw",
- "return_type": "godot_vector3 *",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_vector3 *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_get",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_packed_vector3_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_vector3_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_color_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_color_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "r_dest"],
- ["const godot_packed_color_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_color_array_new_with_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "r_dest"],
- ["const godot_array *", "p_a"]
- ]
- },
- {
- "name": "godot_packed_color_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_color_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"],
- ["const godot_color *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_color_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"],
- ["const godot_packed_color_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_color_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_color_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_color *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_color_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_color_array *", "p_self"],
- ["const godot_color *", "p_value"]
- ]
- },
- {
- "name": "godot_packed_color_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_color_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_color_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"],
- ["const godot_color *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_color_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_color_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_color_array_ptr",
- "return_type": "const godot_color *",
- "arguments": [
- ["const godot_packed_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_color_array_ptrw",
- "return_type": "godot_color *",
- "arguments": [
- ["godot_packed_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_color_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_color *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_color_array_get",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_packed_color_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_color_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_color_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_new_with_reals",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "r_dest"],
- ["const godot_real", "p_a"],
- ["const godot_real", "p_b"],
- ["const godot_real", "p_c"],
- ["const godot_real", "p_d"]
- ]
- },
- {
- "name": "godot_plane_new_with_vectors",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "r_dest"],
- ["const godot_vector3 *", "p_v1"],
- ["const godot_vector3 *", "p_v2"],
- ["const godot_vector3 *", "p_v3"]
- ]
- },
- {
- "name": "godot_plane_new_with_normal",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "r_dest"],
- ["const godot_vector3 *", "p_normal"],
- ["const godot_real", "p_d"]
- ]
- },
- {
- "name": "godot_plane_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_normalized",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_center",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_is_point_over",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_point"]
- ]
- },
- {
- "name": "godot_plane_distance_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_point"]
- ]
- },
- {
- "name": "godot_plane_has_point",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_point"],
- ["const godot_real", "p_epsilon"]
- ]
- },
- {
- "name": "godot_plane_project",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_point"]
- ]
- },
- {
- "name": "godot_plane_intersect_3",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["godot_vector3 *", "r_dest"],
- ["const godot_plane *", "p_b"],
- ["const godot_plane *", "p_c"]
- ]
- },
- {
- "name": "godot_plane_intersects_ray",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["godot_vector3 *", "r_dest"],
- ["const godot_vector3 *", "p_from"],
- ["const godot_vector3 *", "p_dir"]
- ]
- },
- {
- "name": "godot_plane_intersects_segment",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["godot_vector3 *", "r_dest"],
- ["const godot_vector3 *", "p_begin"],
- ["const godot_vector3 *", "p_end"]
- ]
- },
- {
- "name": "godot_plane_operator_neg",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_plane *", "p_self"],
- ["const godot_plane *", "p_b"]
- ]
- },
- {
- "name": "godot_plane_set_normal",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "p_self"],
- ["const godot_vector3 *", "p_normal"]
- ]
- },
- {
- "name": "godot_plane_get_normal",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_get_d",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_plane *", "p_self"]
- ]
- },
- {
- "name": "godot_plane_set_d",
- "return_type": "void",
- "arguments": [
- ["godot_plane *", "p_self"],
- ["const godot_real", "p_d"]
- ]
- },
- {
- "name": "godot_quat_new",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "r_dest"],
- ["const godot_real", "p_x"],
- ["const godot_real", "p_y"],
- ["const godot_real", "p_z"],
- ["const godot_real", "p_w"]
- ]
- },
- {
- "name": "godot_quat_new_with_axis_angle",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "r_dest"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_angle"]
- ]
- },
- {
- "name": "godot_quat_new_with_basis",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "r_dest"],
- ["const godot_basis *", "p_basis"]
- ]
- },
- {
- "name": "godot_quat_new_with_euler",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "r_dest"],
- ["const godot_vector3 *", "p_euler"]
- ]
- },
- {
- "name": "godot_quat_get_x",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_set_x",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_real", "val"]
- ]
- },
- {
- "name": "godot_quat_get_y",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_set_y",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_real", "val"]
- ]
- },
- {
- "name": "godot_quat_get_z",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_set_z",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_real", "val"]
- ]
- },
- {
- "name": "godot_quat_get_w",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_set_w",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_real", "val"]
- ]
- },
- {
- "name": "godot_quat_set_axis_angle",
- "return_type": "void",
- "arguments": [
- ["godot_quat *", "p_self"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_angle"]
- ]
- },
- {
- "name": "godot_quat_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_length",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_length_squared",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_normalized",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_is_normalized",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_inverse",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_quat_dot",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"]
- ]
- },
- {
- "name": "godot_quat_xform",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_quat_slerp",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_quat_slerpni",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_quat_cubic_slerp",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"],
- ["const godot_quat *", "p_pre_a"],
- ["const godot_quat *", "p_post_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_quat_operator_multiply",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_add",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_subtract",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_divide",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_quat *", "p_self"],
- ["const godot_quat *", "p_b"]
- ]
- },
- {
- "name": "godot_quat_operator_neg",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_quat *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_new_with_position_and_size",
- "return_type": "void",
- "arguments": [
- ["godot_rect2 *", "r_dest"],
- ["const godot_vector2 *", "p_pos"],
- ["const godot_vector2 *", "p_size"]
- ]
- },
- {
- "name": "godot_rect2_new",
- "return_type": "void",
- "arguments": [
- ["godot_rect2 *", "r_dest"],
- ["const godot_real", "p_x"],
- ["const godot_real", "p_y"],
- ["const godot_real", "p_width"],
- ["const godot_real", "p_height"]
- ]
- },
- {
- "name": "godot_rect2_as_rect2i",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_get_area",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_grow_individual",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_real", "p_left"],
- ["const godot_real", "p_top"],
- ["const godot_real", "p_right"],
- ["const godot_real", "p_bottom"]
- ]
- },
- {
- "name": "godot_rect2_grow_margin",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_int", "p_margin"],
- ["const godot_real", "p_by"]
- ]
- },
- {
- "name": "godot_rect2_abs",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_intersects",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_encloses",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_has_no_area",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_intersection",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_merge",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_has_point",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_vector2 *", "p_point"]
- ]
- },
- {
- "name": "godot_rect2_grow",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_real", "p_by"]
- ]
- },
- {
- "name": "godot_rect2_expand",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_rect2_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2 *", "p_self"],
- ["const godot_rect2 *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2_get_position",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_get_size",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_rect2 *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2_set_position",
- "return_type": "void",
- "arguments": [
- ["godot_rect2 *", "p_self"],
- ["const godot_vector2 *", "p_pos"]
- ]
- },
- {
- "name": "godot_rect2_set_size",
- "return_type": "void",
- "arguments": [
- ["godot_rect2 *", "p_self"],
- ["const godot_vector2 *", "p_size"]
- ]
- },
- {
- "name": "godot_rect2i_new_with_position_and_size",
- "return_type": "void",
- "arguments": [
- ["godot_rect2i *", "r_dest"],
- ["const godot_vector2i *", "p_pos"],
- ["const godot_vector2i *", "p_size"]
- ]
- },
- {
- "name": "godot_rect2i_new",
- "return_type": "void",
- "arguments": [
- ["godot_rect2i *", "r_dest"],
- ["const godot_int", "p_x"],
- ["const godot_int", "p_y"],
- ["const godot_int", "p_width"],
- ["const godot_int", "p_height"]
- ]
- },
- {
- "name": "godot_rect2i_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_rect2i *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2i_as_rect2",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_rect2i *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2i_get_area",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_rect2i *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2i_intersects",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_rect2i *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2i_encloses",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_rect2i *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2i_has_no_area",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2i *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2i_intersection",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_rect2i *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2i_merge",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_rect2i *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2i_has_point",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_vector2i *", "p_point"]
- ]
- },
- {
- "name": "godot_rect2i_grow",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_int", "p_by"]
- ]
- },
- {
- "name": "godot_rect2i_grow_individual",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_int", "p_left"],
- ["const godot_int", "p_top"],
- ["const godot_int", "p_right"],
- ["const godot_int", "p_bottom"]
- ]
- },
- {
- "name": "godot_rect2i_grow_margin",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_int", "p_margin"],
- ["const godot_int", "p_by"]
- ]
- },
- {
- "name": "godot_rect2i_abs",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2i_expand",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_vector2i *", "p_to"]
- ]
- },
- {
- "name": "godot_rect2i_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rect2i *", "p_self"],
- ["const godot_rect2i *", "p_b"]
- ]
- },
- {
- "name": "godot_rect2i_get_position",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2i_get_size",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_rect2i *", "p_self"]
- ]
- },
- {
- "name": "godot_rect2i_set_position",
- "return_type": "void",
- "arguments": [
- ["godot_rect2i *", "p_self"],
- ["const godot_vector2i *", "p_pos"]
- ]
- },
- {
- "name": "godot_rect2i_set_size",
- "return_type": "void",
- "arguments": [
- ["godot_rect2i *", "p_self"],
- ["const godot_vector2i *", "p_size"]
- ]
- },
- {
- "name": "godot_rid_new",
- "return_type": "void",
- "arguments": [
- ["godot_rid *", "r_dest"]
- ]
- },
- {
- "name": "godot_rid_get_id",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_rid *", "p_self"]
- ]
- },
- {
- "name": "godot_rid_new_with_resource",
- "return_type": "void",
- "arguments": [
- ["godot_rid *", "r_dest"],
- ["const godot_object *", "p_from"]
- ]
- },
- {
- "name": "godot_rid_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rid *", "p_self"],
- ["const godot_rid *", "p_b"]
- ]
- },
- {
- "name": "godot_rid_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_rid *", "p_self"],
- ["const godot_rid *", "p_b"]
- ]
- },
- {
- "name": "godot_char_string_length",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_char_string *", "p_cs"]
- ]
- },
- {
- "name": "godot_char_string_get_data",
- "return_type": "const char *",
- "arguments": [
- ["const godot_char_string *", "p_cs"]
- ]
- },
- {
- "name": "godot_char_string_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_char_string *", "p_cs"]
- ]
- },
- {
- "name": "godot_char16_string_length",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_char16_string *", "p_cs"]
- ]
- },
- {
- "name": "godot_char16_string_get_data",
- "return_type": "const char16_t *",
- "arguments": [
- ["const godot_char16_string *", "p_cs"]
- ]
- },
- {
- "name": "godot_char16_string_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_char16_string *", "p_cs"]
- ]
- },
- {
- "name": "godot_string_new",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"]
- ]
- },
- {
- "name": "godot_string_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const godot_string *", "p_src"]
- ]
- },
- {
- "name": "godot_string_new_with_latin1_chars",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char *", "p_contents"]
- ]
- },
- {
- "name": "godot_string_new_with_utf8_chars",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char *", "p_contents"]
- ]
- },
- {
- "name": "godot_string_new_with_utf16_chars",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char16_t *", "p_contents"]
- ]
- },
- {
- "name": "godot_string_new_with_utf32_chars",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char32_t *", "p_contents"]
- ]
- },
- {
- "name": "godot_string_new_with_wide_chars",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const wchar_t *", "p_contents"]
- ]
- },
- {
- "name": "godot_string_new_with_latin1_chars_and_len",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char *", "p_contents"],
- ["const int", "p_size"]
- ]
- },
- {
- "name": "godot_string_new_with_utf8_chars_and_len",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char *", "p_contents"],
- ["const int", "p_size"]
- ]
- },
- {
- "name": "godot_string_new_with_utf16_chars_and_len",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char16_t *", "p_contents"],
- ["const int", "p_size"]
- ]
- },
- {
- "name": "godot_string_new_with_utf32_chars_and_len",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const char32_t *", "p_contents"],
- ["const int", "p_size"]
- ]
- },
- {
- "name": "godot_string_new_with_wide_chars_and_len",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "r_dest"],
- ["const wchar_t *", "p_contents"],
- ["const int", "p_size"]
- ]
- },
- {
- "name": "godot_string_operator_index",
- "return_type": "const godot_char_type *",
- "arguments": [
- ["godot_string *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_string_operator_index_const",
- "return_type": "godot_char_type",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_string_get_data",
- "return_type": "const godot_char_type *",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_b"]
- ]
- },
- {
- "name": "godot_string_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_b"]
- ]
- },
- {
- "name": "godot_string_operator_plus",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_b"]
- ]
- },
- {
- "name": "godot_string_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"],
- ["godot_int", "p_from"],
- ["godot_int", "p_to"]
- ]
- },
- {
- "name": "godot_string_countn",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"],
- ["godot_int", "p_from"],
- ["godot_int", "p_to"]
- ]
- },
- {
- "name": "godot_string_dedent",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_length",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_casecmp_to",
- "return_type": "signed char",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_str"]
- ]
- },
- {
- "name": "godot_string_nocasecmp_to",
- "return_type": "signed char",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_str"]
- ]
- },
- {
- "name": "godot_string_naturalnocasecmp_to",
- "return_type": "signed char",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_str"]
- ]
- },
- {
- "name": "godot_string_begins_with",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_begins_with_char_array",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const char *", "p_char_array"]
- ]
- },
- {
- "name": "godot_string_bigrams",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_chr",
- "return_type": "godot_string",
- "arguments": [
- ["godot_char_type", "p_character"]
- ]
- },
- {
- "name": "godot_string_ends_with",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_ends_with_char_array",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const char *", "p_char_array"]
- ]
- },
- {
- "name": "godot_string_find",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"]
- ]
- },
- {
- "name": "godot_string_find_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_findmk",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_packed_string_array *", "p_keys"]
- ]
- },
- {
- "name": "godot_string_findmk_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_packed_string_array *", "p_keys"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_findmk_from_in_place",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_packed_string_array *", "p_keys"],
- ["godot_int", "p_from"],
- ["godot_int *", "r_key"]
- ]
- },
- {
- "name": "godot_string_findn",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"]
- ]
- },
- {
- "name": "godot_string_findn_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_format",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_variant *", "p_values"]
- ]
- },
- {
- "name": "godot_string_format_with_custom_placeholder",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_variant *", "p_values"],
- ["const char *", "p_placeholder"]
- ]
- },
- {
- "name": "godot_string_hex_encode_buffer",
- "return_type": "godot_string",
- "arguments": [
- ["const uint8_t *", "p_buffer"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_insert",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_at_pos"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_is_numeric",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_subsequence_of",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_is_subsequence_ofi",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_lpad",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_min_length"]
- ]
- },
- {
- "name": "godot_string_lpad_with_custom_character",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_min_length"],
- ["const godot_string *", "p_character"]
- ]
- },
- {
- "name": "godot_string_match",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_wildcard"]
- ]
- },
- {
- "name": "godot_string_matchn",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_wildcard"]
- ]
- },
- {
- "name": "godot_string_md5",
- "return_type": "godot_string",
- "arguments": [
- ["const uint8_t *", "p_md5"]
- ]
- },
- {
- "name": "godot_string_num",
- "return_type": "godot_string",
- "arguments": [
- ["double", "p_num"]
- ]
- },
- {
- "name": "godot_string_num_int64",
- "return_type": "godot_string",
- "arguments": [
- ["int64_t", "p_num"],
- ["godot_int", "p_base"]
- ]
- },
- {
- "name": "godot_string_num_int64_capitalized",
- "return_type": "godot_string",
- "arguments": [
- ["int64_t", "p_num"],
- ["godot_int", "p_base"],
- ["godot_bool", "p_capitalize_hex"]
- ]
- },
- {
- "name": "godot_string_num_real",
- "return_type": "godot_string",
- "arguments": [
- ["double", "p_num"]
- ]
- },
- {
- "name": "godot_string_num_scientific",
- "return_type": "godot_string",
- "arguments": [
- ["double", "p_num"]
- ]
- },
- {
- "name": "godot_string_num_with_decimals",
- "return_type": "godot_string",
- "arguments": [
- ["double", "p_num"],
- ["godot_int", "p_decimals"]
- ]
- },
- {
- "name": "godot_string_pad_decimals",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_digits"]
- ]
- },
- {
- "name": "godot_string_pad_zeros",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_digits"]
- ]
- },
- {
- "name": "godot_string_replace_first",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_key"],
- ["const godot_string *", "p_with"]
- ]
- },
- {
- "name": "godot_string_replace",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_key"],
- ["const godot_string *", "p_with"]
- ]
- },
- {
- "name": "godot_string_replacen",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_key"],
- ["const godot_string *", "p_with"]
- ]
- },
- {
- "name": "godot_string_rfind",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"]
- ]
- },
- {
- "name": "godot_string_rfindn",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"]
- ]
- },
- {
- "name": "godot_string_rfind_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_rfindn_from",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_what"],
- ["godot_int", "p_from"]
- ]
- },
- {
- "name": "godot_string_rpad",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_min_length"]
- ]
- },
- {
- "name": "godot_string_rpad_with_custom_character",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_min_length"],
- ["const godot_string *", "p_character"]
- ]
- },
- {
- "name": "godot_string_similarity",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_string"]
- ]
- },
- {
- "name": "godot_string_sprintf",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_array *", "p_values"],
- ["godot_bool *", "p_error"]
- ]
- },
- {
- "name": "godot_string_substr",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_from"],
- ["godot_int", "p_chars"]
- ]
- },
- {
- "name": "godot_string_to_int",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_to_float",
- "return_type": "double",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_camelcase_to_underscore",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_camelcase_to_underscore_lowercased",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_capitalize",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_char_to_float",
- "return_type": "double",
- "arguments": [
- ["const char *", "p_what"]
- ]
- },
- {
- "name": "godot_string_wchar_to_float",
- "return_type": "double",
- "arguments": [
- ["const wchar_t *", "p_str"],
- ["const wchar_t **", "r_end"]
- ]
- },
- {
- "name": "godot_string_char_to_int",
- "return_type": "godot_int",
- "arguments": [
- ["const char *", "p_what"]
- ]
- },
- {
- "name": "godot_string_wchar_to_int",
- "return_type": "godot_int",
- "arguments": [
- ["const wchar_t *", "p_str"]
- ]
- },
- {
- "name": "godot_string_char_to_int_with_len",
- "return_type": "godot_int",
- "arguments": [
- ["const char *", "p_what"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_wchar_to_int_with_len",
- "return_type": "godot_int",
- "arguments": [
- ["const wchar_t *", "p_str"],
- ["int", "p_len"]
- ]
- },
- {
- "name": "godot_string_hex_to_int",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hex_to_int_with_prefix",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_slice_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_get_slice",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"],
- ["godot_int", "p_slice"]
- ]
- },
- {
- "name": "godot_string_get_slicec",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_char_type", "p_splitter"],
- ["godot_int", "p_slice"]
- ]
- },
- {
- "name": "godot_string_split",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_allow_empty",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_with_maxsplit",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"],
- ["const godot_bool", "p_allow_empty"],
- ["const godot_int", "p_maxsplit"]
- ]
- },
- {
- "name": "godot_string_rsplit",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_rsplit_allow_empty",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_rsplit_with_maxsplit",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"],
- ["const godot_bool", "p_allow_empty"],
- ["const godot_int", "p_maxsplit"]
- ]
- },
- {
- "name": "godot_string_split_floats",
- "return_type": "godot_packed_float32_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_floats_allow_empty",
- "return_type": "godot_packed_float32_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_floats_mk",
- "return_type": "godot_packed_float32_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_packed_string_array *", "p_splitters"]
- ]
- },
- {
- "name": "godot_string_split_floats_mk_allow_empty",
- "return_type": "godot_packed_float32_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_packed_string_array *", "p_splitters"]
- ]
- },
- {
- "name": "godot_string_split_ints",
- "return_type": "godot_packed_int32_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_ints_allow_empty",
- "return_type": "godot_packed_int32_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_splitter"]
- ]
- },
- {
- "name": "godot_string_split_ints_mk",
- "return_type": "godot_packed_int32_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_packed_string_array *", "p_splitters"]
- ]
- },
- {
- "name": "godot_string_split_ints_mk_allow_empty",
- "return_type": "godot_packed_int32_array",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_packed_string_array *", "p_splitters"]
- ]
- },
- {
- "name": "godot_string_split_spaces",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_lstrip",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_chars"]
- ]
- },
- {
- "name": "godot_string_rstrip",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_chars"]
- ]
- },
- {
- "name": "godot_string_trim_prefix",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_prefix"]
- ]
- },
- {
- "name": "godot_string_trim_suffix",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_suffix"]
- ]
- },
- {
- "name": "godot_string_char_lowercase",
- "return_type": "godot_char_type",
- "arguments": [
- ["godot_char_type", "p_char"]
- ]
- },
- {
- "name": "godot_string_char_uppercase",
- "return_type": "godot_char_type",
- "arguments": [
- ["godot_char_type", "p_char"]
- ]
- },
- {
- "name": "godot_string_to_lower",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_to_upper",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_basename",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_extension",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_left",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_pos"]
- ]
- },
- {
- "name": "godot_string_ord_at",
- "return_type": "godot_char_type",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_string_plus_file",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_file"]
- ]
- },
- {
- "name": "godot_string_right",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_pos"]
- ]
- },
- {
- "name": "godot_string_repeat",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_int", "p_count"]
- ]
- },
- {
- "name": "godot_string_strip_edges",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_bool", "p_left"],
- ["godot_bool", "p_right"]
- ]
- },
- {
- "name": "godot_string_strip_escapes",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_erase",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "p_self"],
- ["godot_int", "p_pos"],
- ["godot_int", "p_chars"]
- ]
- },
- {
- "name": "godot_string_ascii",
- "return_type": "godot_char_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_latin1",
- "return_type": "godot_char_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_utf8",
- "return_type": "godot_char_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_parse_utf8",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_string *", "p_self"],
- ["const char *", "p_utf8"]
- ]
- },
- {
- "name": "godot_string_parse_utf8_with_len",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_string *", "p_self"],
- ["const char *", "p_utf8"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_utf16",
- "return_type": "godot_char16_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_parse_utf16",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_string *", "p_self"],
- ["const char16_t *", "p_utf16"]
- ]
- },
- {
- "name": "godot_string_parse_utf16_with_len",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_string *", "p_self"],
- ["const char16_t *", "p_utf16"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_hash",
- "return_type": "uint32_t",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hash64",
- "return_type": "uint64_t",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_hash_chars",
- "return_type": "uint32_t",
- "arguments": [
- ["const char *", "p_cstr"]
- ]
- },
- {
- "name": "godot_string_hash_chars_with_len",
- "return_type": "uint32_t",
- "arguments": [
- ["const char *", "p_cstr"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_hash_wide_chars",
- "return_type": "uint32_t",
- "arguments": [
- ["const wchar_t *", "p_str"]
- ]
- },
- {
- "name": "godot_string_hash_wide_chars_with_len",
- "return_type": "uint32_t",
- "arguments": [
- ["const wchar_t *", "p_str"],
- ["godot_int", "p_len"]
- ]
- },
- {
- "name": "godot_string_md5_buffer",
- "return_type": "godot_packed_byte_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_md5_text",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_sha1_buffer",
- "return_type": "godot_packed_byte_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_sha1_text",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_sha256_buffer",
- "return_type": "godot_packed_byte_array",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_sha256_text",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_base_dir",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_get_file",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_humanize_size",
- "return_type": "godot_string",
- "arguments": [
- ["size_t", "p_size"]
- ]
- },
- {
- "name": "godot_string_is_abs_path",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_rel_path",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_resource_file",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_path_to",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_path"]
- ]
- },
- {
- "name": "godot_string_path_to_file",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_string *", "p_path"]
- ]
- },
- {
- "name": "godot_string_simplify_path",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_c_escape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_c_escape_multiline",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_c_unescape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_http_escape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_http_unescape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_json_escape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_xml_escape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_xml_escape_with_quotes",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_xml_unescape",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_percent_decode",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_percent_encode",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_join",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["const godot_packed_string_array *", "p_parts"]
- ]
- },
- {
- "name": "godot_string_is_valid_filename",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_float",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_hex_number",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"],
- ["godot_bool", "p_with_prefix"]
- ]
- },
- {
- "name": "godot_string_is_valid_html_color",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_identifier",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_integer",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_is_valid_ip_address",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_string *", "p_self"]
- ]
- },
- {
- "name": "godot_string_name_new",
- "return_type": "void",
- "arguments": [
- ["godot_string_name *", "r_dest"],
- ["const godot_string *", "p_name"]
- ]
- },
- {
- "name": "godot_string_name_new_data",
- "return_type": "void",
- "arguments": [
- ["godot_string_name *", "r_dest"],
- ["const char *", "p_name"]
- ]
- },
- {
- "name": "godot_string_name_get_name",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_string_name *", "p_self"]
- ]
- },
- {
- "name": "godot_string_name_get_hash",
- "return_type": "uint32_t",
- "arguments": [
- ["const godot_string_name *", "p_self"]
- ]
- },
- {
- "name": "godot_string_name_get_data_unique_pointer",
- "return_type": "const void *",
- "arguments": [
- ["const godot_string_name *", "p_self"]
- ]
- },
- {
- "name": "godot_string_name_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string_name *", "p_self"],
- ["const godot_string_name *", "p_other"]
- ]
- },
- {
- "name": "godot_string_name_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_string_name *", "p_self"],
- ["const godot_string_name *", "p_other"]
- ]
- },
- {
- "name": "godot_string_name_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_string_name *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_new_with_axis_origin",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "r_dest"],
- ["const godot_vector3 *", "p_x_axis"],
- ["const godot_vector3 *", "p_y_axis"],
- ["const godot_vector3 *", "p_z_axis"],
- ["const godot_vector3 *", "p_origin"]
- ]
- },
- {
- "name": "godot_transform_new_with_quat",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "r_dest"],
- ["const godot_quat *", "p_quat"]
- ]
- },
- {
- "name": "godot_transform_new",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "r_dest"],
- ["const godot_basis *", "p_basis"],
- ["const godot_vector3 *", "p_origin"]
- ]
- },
- {
- "name": "godot_transform_get_basis",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_set_basis",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "p_self"],
- ["const godot_basis *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_get_origin",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_set_origin",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_inverse",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_affine_inverse",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_orthonormalized",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"]
- ]
- },
- {
- "name": "godot_transform_rotated",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_transform_scaled",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_scale"]
- ]
- },
- {
- "name": "godot_transform_translated",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_ofs"]
- ]
- },
- {
- "name": "godot_transform_looking_at",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_target"],
- ["const godot_vector3 *", "p_up"]
- ]
- },
- {
- "name": "godot_transform_xform_plane",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_plane *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_xform_inv_plane",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_plane *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_new_identity",
- "return_type": "void",
- "arguments": [
- ["godot_transform *", "r_dest"]
- ]
- },
- {
- "name": "godot_transform_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_transform *", "p_b"]
- ]
- },
- {
- "name": "godot_transform_operator_multiply",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_transform *", "p_b"]
- ]
- },
- {
- "name": "godot_transform_xform_vector3",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_xform_inv_vector3",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_vector3 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_xform_aabb",
- "return_type": "godot_aabb",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_aabb *", "p_v"]
- ]
- },
- {
- "name": "godot_transform_xform_inv_aabb",
- "return_type": "godot_aabb",
- "arguments": [
- ["const godot_transform *", "p_self"],
- ["const godot_aabb *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_new",
- "return_type": "void",
- "arguments": [
- ["godot_transform2d *", "r_dest"],
- ["const godot_real", "p_rot"],
- ["const godot_vector2 *", "p_pos"]
- ]
- },
- {
- "name": "godot_transform2d_new_axis_origin",
- "return_type": "void",
- "arguments": [
- ["godot_transform2d *", "r_dest"],
- ["const godot_vector2 *", "p_x_axis"],
- ["const godot_vector2 *", "p_y_axis"],
- ["const godot_vector2 *", "p_origin"]
- ]
- },
- {
- "name": "godot_transform2d_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_inverse",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_affine_inverse",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_get_rotation",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_get_origin",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_get_scale",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_orthonormalized",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"]
- ]
- },
- {
- "name": "godot_transform2d_rotated",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_transform2d_scaled",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_scale"]
- ]
- },
- {
- "name": "godot_transform2d_translated",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_offset"]
- ]
- },
- {
- "name": "godot_transform2d_xform_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_xform_inv_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_basis_xform_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_basis_xform_inv_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_vector2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_interpolate_with",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_transform2d *", "p_m"],
- ["const godot_real", "p_c"]
- ]
- },
- {
- "name": "godot_transform2d_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_transform2d *", "p_b"]
- ]
- },
- {
- "name": "godot_transform2d_operator_multiply",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_transform2d *", "p_b"]
- ]
- },
- {
- "name": "godot_transform2d_new_identity",
- "return_type": "void",
- "arguments": [
- ["godot_transform2d *", "r_dest"]
- ]
- },
- {
- "name": "godot_transform2d_xform_rect2",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_rect2 *", "p_v"]
- ]
- },
- {
- "name": "godot_transform2d_xform_inv_rect2",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_transform2d *", "p_self"],
- ["const godot_rect2 *", "p_v"]
- ]
- },
- {
- "name": "godot_variant_get_type",
- "return_type": "godot_variant_type",
- "arguments": [
- ["const godot_variant *", "p_v"]
- ]
- },
- {
- "name": "godot_variant_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_variant *", "p_src"]
- ]
- },
- {
- "name": "godot_variant_new_nil",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"]
- ]
- },
- {
- "name": "godot_variant_new_bool",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_bool", "p_b"]
- ]
- },
- {
- "name": "godot_variant_new_uint",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const uint64_t", "p_i"]
- ]
- },
- {
- "name": "godot_variant_new_int",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const int64_t", "p_i"]
- ]
- },
- {
- "name": "godot_variant_new_real",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const double", "p_r"]
- ]
- },
- {
- "name": "godot_variant_new_string",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_string *", "p_s"]
- ]
- },
- {
- "name": "godot_variant_new_string_name",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_string_name *", "p_s"]
- ]
- },
- {
- "name": "godot_variant_new_vector2",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_vector2 *", "p_v2"]
- ]
- },
- {
- "name": "godot_variant_new_vector2i",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_vector2i *", "p_v2"]
- ]
- },
- {
- "name": "godot_variant_new_rect2",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_rect2 *", "p_rect2"]
- ]
- },
- {
- "name": "godot_variant_new_rect2i",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_rect2i *", "p_rect2"]
- ]
- },
- {
- "name": "godot_variant_new_vector3",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_vector3 *", "p_v3"]
- ]
- },
- {
- "name": "godot_variant_new_vector3i",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_vector3i *", "p_v3"]
- ]
- },
- {
- "name": "godot_variant_new_transform2d",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_transform2d *", "p_t2d"]
- ]
- },
- {
- "name": "godot_variant_new_plane",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_plane *", "p_plane"]
- ]
- },
- {
- "name": "godot_variant_new_quat",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_quat *", "p_quat"]
- ]
- },
- {
- "name": "godot_variant_new_aabb",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_aabb *", "p_aabb"]
- ]
- },
- {
- "name": "godot_variant_new_basis",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_basis *", "p_basis"]
- ]
- },
- {
- "name": "godot_variant_new_transform",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_transform *", "p_trans"]
- ]
- },
- {
- "name": "godot_variant_new_color",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_color *", "p_color"]
- ]
- },
- {
- "name": "godot_variant_new_node_path",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_node_path *", "p_np"]
- ]
- },
- {
- "name": "godot_variant_new_rid",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_rid *", "p_rid"]
- ]
- },
- {
- "name": "godot_variant_new_object",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_object *", "p_obj"]
- ]
- },
- {
- "name": "godot_variant_new_callable",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_callable *", "p_cb"]
- ]
- },
- {
- "name": "godot_variant_new_signal",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_signal *", "p_signal"]
- ]
- },
- {
- "name": "godot_variant_new_dictionary",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_dictionary *", "p_dict"]
- ]
- },
- {
- "name": "godot_variant_new_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_array *", "p_arr"]
- ]
- },
- {
- "name": "godot_variant_new_packed_byte_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_byte_array *", "p_pba"]
- ]
- },
- {
- "name": "godot_variant_new_packed_int32_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_int32_array *", "p_pia"]
- ]
- },
- {
- "name": "godot_variant_new_packed_int64_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_int64_array *", "p_pia"]
- ]
- },
- {
- "name": "godot_variant_new_packed_float32_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_float32_array *", "p_pra"]
- ]
- },
- {
- "name": "godot_variant_new_packed_float64_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_float64_array *", "p_pra"]
- ]
- },
- {
- "name": "godot_variant_new_packed_string_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_string_array *", "p_psa"]
- ]
- },
- {
- "name": "godot_variant_new_packed_vector2_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_vector2_array *", "p_pv2a"]
- ]
- },
- {
- "name": "godot_variant_new_packed_vector3_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_vector3_array *", "p_pv3a"]
- ]
- },
- {
- "name": "godot_variant_new_packed_color_array",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "r_dest"],
- ["const godot_packed_color_array *", "p_pca"]
- ]
- },
- {
- "name": "godot_variant_as_bool",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_uint",
- "return_type": "uint64_t",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_int",
- "return_type": "int64_t",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_real",
- "return_type": "double",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_string_name",
- "return_type": "godot_string_name",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_vector2i",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_rect2",
- "return_type": "godot_rect2",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_rect2i",
- "return_type": "godot_rect2i",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_vector3",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_vector3i",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_transform2d",
- "return_type": "godot_transform2d",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_plane",
- "return_type": "godot_plane",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_quat",
- "return_type": "godot_quat",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_aabb",
- "return_type": "godot_aabb",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_basis",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_transform",
- "return_type": "godot_transform",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_color",
- "return_type": "godot_color",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_node_path",
- "return_type": "godot_node_path",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_rid",
- "return_type": "godot_rid",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_object",
- "return_type": "godot_object *",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_callable",
- "return_type": "godot_callable",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_signal",
- "return_type": "godot_signal",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_dictionary",
- "return_type": "godot_dictionary",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_array",
- "return_type": "godot_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_byte_array",
- "return_type": "godot_packed_byte_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_int32_array",
- "return_type": "godot_packed_int32_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_int64_array",
- "return_type": "godot_packed_int64_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_float32_array",
- "return_type": "godot_packed_float32_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_float64_array",
- "return_type": "godot_packed_float64_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_string_array",
- "return_type": "godot_packed_string_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_vector2_array",
- "return_type": "godot_packed_vector2_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_vector3_array",
- "return_type": "godot_packed_vector3_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_as_packed_color_array",
- "return_type": "godot_packed_color_array",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_call",
- "return_type": "godot_variant",
- "arguments": [
- ["godot_variant *", "p_self"],
- ["const godot_string *", "p_method"],
- ["const godot_variant **", "p_args"],
- ["const godot_int", "p_argcount"],
- ["godot_variant_call_error *", "r_error"]
- ]
- },
- {
- "name": "godot_variant_has_method",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"],
- ["const godot_string *", "p_method"]
- ]
- },
- {
- "name": "godot_variant_hash",
- "return_type": "uint32_t",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"],
- ["const godot_variant *", "p_other"]
- ]
- },
- {
- "name": "godot_variant_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"],
- ["const godot_variant *", "p_other"]
- ]
- },
- {
- "name": "godot_variant_get_operator_name",
- "return_type": "godot_string",
- "arguments": [
- ["godot_variant_operator", "p_op"]
- ]
- },
- {
- "name": "godot_variant_evaluate",
- "return_type": "void",
- "arguments": [
- ["godot_variant_operator", "p_op"],
- ["const godot_variant *", "p_a"],
- ["const godot_variant *", "p_b"],
- ["godot_variant *", "r_ret"],
- ["godot_bool *", "r_valid"]
- ]
- },
- {
- "name": "godot_variant_hash_compare",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"],
- ["const godot_variant *", "p_other"]
- ]
- },
- {
- "name": "godot_variant_booleanize",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_variant_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_variant *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_as_vector2i",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_sign",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_move_toward",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"],
- ["const godot_real", "p_delta"]
- ]
- },
- {
- "name": "godot_vector2_direction_to",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_new",
- "return_type": "void",
- "arguments": [
- ["godot_vector2 *", "r_dest"],
- ["const godot_real", "p_x"],
- ["const godot_real", "p_y"]
- ]
- },
- {
- "name": "godot_vector2_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_normalized",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_length",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_angle",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_length_squared",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_is_normalized",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_distance_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_distance_squared_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_angle_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_angle_to_point",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector2_lerp",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_vector2_cubic_interpolate",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"],
- ["const godot_vector2 *", "p_pre_a"],
- ["const godot_vector2 *", "p_post_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_vector2_rotated",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_vector2_tangent",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_floor",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_snapped",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_by"]
- ]
- },
- {
- "name": "godot_vector2_aspect",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_dot",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_with"]
- ]
- },
- {
- "name": "godot_vector2_slide",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector2_bounce",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector2_reflect",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector2_abs",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_clamped",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_real", "p_length"]
- ]
- },
- {
- "name": "godot_vector2_operator_add",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_subtract",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_multiply_vector",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_multiply_scalar",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_divide_vector",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_divide_scalar",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector2 *", "p_self"],
- ["const godot_vector2 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2_operator_neg",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_set_x",
- "return_type": "void",
- "arguments": [
- ["godot_vector2 *", "p_self"],
- ["const godot_real", "p_x"]
- ]
- },
- {
- "name": "godot_vector2_set_y",
- "return_type": "void",
- "arguments": [
- ["godot_vector2 *", "p_self"],
- ["const godot_real", "p_y"]
- ]
- },
- {
- "name": "godot_vector2_get_x",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2_get_y",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2i_new",
- "return_type": "void",
- "arguments": [
- ["godot_vector2i *", "r_dest"],
- ["const godot_int", "p_x"],
- ["const godot_int", "p_y"]
- ]
- },
- {
- "name": "godot_vector2i_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_vector2i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2i_as_vector2",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_vector2i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2i_aspect",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector2i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2i_abs",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2i_sign",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2i_operator_add",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"],
- ["const godot_vector2i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2i_operator_subtract",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"],
- ["const godot_vector2i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2i_operator_multiply_vector",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"],
- ["const godot_vector2i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2i_operator_multiply_scalar",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"],
- ["const godot_int", "p_b"]
- ]
- },
- {
- "name": "godot_vector2i_operator_divide_vector",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"],
- ["const godot_vector2i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2i_operator_divide_scalar",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"],
- ["const godot_int", "p_b"]
- ]
- },
- {
- "name": "godot_vector2i_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector2i *", "p_self"],
- ["const godot_vector2i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2i_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector2i *", "p_self"],
- ["const godot_vector2i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector2i_operator_neg",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_vector2i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2i_set_x",
- "return_type": "void",
- "arguments": [
- ["godot_vector2i *", "p_self"],
- ["const godot_int", "p_x"]
- ]
- },
- {
- "name": "godot_vector2i_set_y",
- "return_type": "void",
- "arguments": [
- ["godot_vector2i *", "p_self"],
- ["const godot_int", "p_y"]
- ]
- },
- {
- "name": "godot_vector2i_get_x",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector2i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector2i_get_y",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector2i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_as_vector3i",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_sign",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_move_toward",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_to"],
- ["const godot_real", "p_delta"]
- ]
- },
- {
- "name": "godot_vector3_direction_to",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector3_new",
- "return_type": "void",
- "arguments": [
- ["godot_vector3 *", "r_dest"],
- ["const godot_real", "p_x"],
- ["const godot_real", "p_y"],
- ["const godot_real", "p_z"]
- ]
- },
- {
- "name": "godot_vector3_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_min_axis",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_max_axis",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_length",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_length_squared",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_is_normalized",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_normalized",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_inverse",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_snapped",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_by"]
- ]
- },
- {
- "name": "godot_vector3_rotated",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_axis"],
- ["const godot_real", "p_phi"]
- ]
- },
- {
- "name": "godot_vector3_lerp",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_vector3_cubic_interpolate",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"],
- ["const godot_vector3 *", "p_pre_a"],
- ["const godot_vector3 *", "p_post_b"],
- ["const godot_real", "p_t"]
- ]
- },
- {
- "name": "godot_vector3_dot",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_cross",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_outer",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_to_diagonal_matrix",
- "return_type": "godot_basis",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_abs",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_floor",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_ceil",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_distance_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_distance_squared_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_angle_to",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_to"]
- ]
- },
- {
- "name": "godot_vector3_slide",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector3_bounce",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector3_reflect",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_n"]
- ]
- },
- {
- "name": "godot_vector3_operator_add",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_subtract",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_multiply_vector",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_multiply_scalar",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_divide_vector",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_divide_scalar",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_real", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3 *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3_operator_neg",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3 *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3_set_axis",
- "return_type": "void",
- "arguments": [
- ["godot_vector3 *", "p_self"],
- ["const godot_vector3_axis", "p_axis"],
- ["const godot_real", "p_val"]
- ]
- },
- {
- "name": "godot_vector3_get_axis",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_vector3 *", "p_self"],
- ["const godot_vector3_axis", "p_axis"]
- ]
- },
- {
- "name": "godot_vector3i_new",
- "return_type": "void",
- "arguments": [
- ["godot_vector3i *", "r_dest"],
- ["const godot_int", "p_x"],
- ["const godot_int", "p_y"],
- ["const godot_int", "p_z"]
- ]
- },
- {
- "name": "godot_vector3i_as_string",
- "return_type": "godot_string",
- "arguments": [
- ["const godot_vector3i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3i_as_vector3",
- "return_type": "godot_vector3",
- "arguments": [
- ["const godot_vector3i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3i_min_axis",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector3i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3i_max_axis",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector3i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3i_abs",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3i_sign",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3i_operator_add",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_vector3i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3i_operator_subtract",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_vector3i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3i_operator_multiply_vector",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_vector3i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3i_operator_multiply_scalar",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_int", "p_b"]
- ]
- },
- {
- "name": "godot_vector3i_operator_divide_vector",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_vector3i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3i_operator_divide_scalar",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_int", "p_b"]
- ]
- },
- {
- "name": "godot_vector3i_operator_equal",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_vector3i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3i_operator_less",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_vector3i *", "p_b"]
- ]
- },
- {
- "name": "godot_vector3i_operator_neg",
- "return_type": "godot_vector3i",
- "arguments": [
- ["const godot_vector3i *", "p_self"]
- ]
- },
- {
- "name": "godot_vector3i_set_axis",
- "return_type": "void",
- "arguments": [
- ["godot_vector3i *", "p_self"],
- ["const godot_vector3_axis", "p_axis"],
- ["const godot_int", "p_val"]
- ]
- },
- {
- "name": "godot_vector3i_get_axis",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_vector3i *", "p_self"],
- ["const godot_vector3_axis", "p_axis"]
- ]
- },
- {
- "name": "godot_global_get_singleton",
- "return_type": "godot_object *",
- "arguments": [
- ["char *", "p_name"]
- ]
- },
- {
- "name": "godot_get_class_tag",
- "return_type": "void *",
- "arguments": [
- ["const godot_string_name *", "p_class"]
- ]
- },
- {
- "name": "godot_object_cast_to",
- "return_type": "godot_object *",
- "arguments": [
- ["const godot_object *", "p_object"],
- ["void *", "p_class_tag"]
- ]
- },
- {
- "name": "godot_object_get_instance_id",
- "return_type": "uint64_t",
- "arguments": [
- ["const godot_object *", "p_object"]
- ]
- },
- {
- "name": "godot_instance_from_id",
- "return_type": "godot_object *",
- "arguments": [
- ["uint64_t", "p_instance_id"]
- ]
- },
- {
- "name": "godot_object_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_object *", "p_o"]
- ]
- },
- {
- "name": "godot_method_bind_get_method",
- "return_type": "godot_method_bind *",
- "arguments": [
- ["const char *", "p_classname"],
- ["const char *", "p_methodname"]
- ]
- },
- {
- "name": "godot_method_bind_ptrcall",
- "return_type": "void",
- "arguments": [
- ["godot_method_bind *", "p_method_bind"],
- ["godot_object *", "p_instance"],
- ["const void **", "p_args"],
- ["void *", "p_ret"]
- ]
- },
- {
- "name": "godot_method_bind_call",
- "return_type": "godot_variant",
- "arguments": [
- ["godot_method_bind *", "p_method_bind"],
- ["godot_object *", "p_instance"],
- ["const godot_variant **", "p_args"],
- ["const int", "p_arg_count"],
- ["godot_variant_call_error *", "p_call_error"]
- ]
- },
- {
- "name": "godot_get_class_constructor",
- "return_type": "godot_class_constructor",
- "arguments": [
- ["const char *", "p_classname"]
- ]
- },
- {
- "name": "godot_get_global_constants",
- "return_type": "godot_dictionary",
- "arguments": [
- ]
- },
- {
- "name": "godot_register_native_call_type",
- "return_type": "void",
- "arguments": [
- ["const char *", "call_type"],
- ["native_call_cb", "p_callback"]
- ]
- },
- {
- "name": "godot_alloc",
- "return_type": "void *",
- "arguments": [
- ["int", "p_bytes"]
- ]
- },
- {
- "name": "godot_realloc",
- "return_type": "void *",
- "arguments": [
- ["void *", "p_ptr"],
- ["int", "p_bytes"]
- ]
- },
- {
- "name": "godot_free",
- "return_type": "void",
- "arguments": [
- ["void *", "p_ptr"]
- ]
- },
- {
- "name": "godot_print_error",
- "return_type": "void",
- "arguments": [
- ["const char *", "p_description"],
- ["const char *", "p_function"],
- ["const char *", "p_file"],
- ["int", "p_line"]
- ]
- },
- {
- "name": "godot_print_warning",
- "return_type": "void",
- "arguments": [
- ["const char *", "p_description"],
- ["const char *", "p_function"],
- ["const char *", "p_file"],
- ["int", "p_line"]
- ]
- },
- {
- "name": "godot_print",
- "return_type": "void",
- "arguments": [
- ["const godot_string *", "p_message"]
- ]
- }
- ]
- },
- "extensions": [
- {
- "name": "nativescript",
- "type": "NATIVESCRIPT",
- "version": {
- "major": 4,
- "minor": 0
- },
- "next": null,
- "api": [
- {
- "name": "godot_nativescript_register_class",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_base"],
- ["godot_nativescript_instance_create_func", "p_create_func"],
- ["godot_nativescript_instance_destroy_func", "p_destroy_func"]
- ]
- },
- {
- "name": "godot_nativescript_register_tool_class",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_base"],
- ["godot_nativescript_instance_create_func", "p_create_func"],
- ["godot_nativescript_instance_destroy_func", "p_destroy_func"]
- ]
- },
- {
- "name": "godot_nativescript_register_method",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_function_name"],
- ["godot_nativescript_method_attributes", "p_attr"],
- ["godot_nativescript_instance_method", "p_method"]
- ]
- },
- {
- "name": "godot_nativescript_set_method_argument_information",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_function_name"],
- ["int", "p_num_args"],
- ["const godot_nativescript_method_argument *", "p_args"]
- ]
- },
- {
- "name": "godot_nativescript_register_property",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_path"],
- ["godot_nativescript_property_attributes *", "p_attr"],
- ["godot_nativescript_property_set_func", "p_set_func"],
- ["godot_nativescript_property_get_func", "p_get_func"]
- ]
- },
- {
- "name": "godot_nativescript_register_signal",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const godot_nativescript_signal *", "p_signal"]
- ]
- },
- {
- "name": "godot_nativescript_get_userdata",
- "return_type": "void *",
- "arguments": [
- ["godot_object *", "p_instance"]
- ]
- },
- {
- "name": "godot_nativescript_set_class_documentation",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["godot_string", "p_documentation"]
- ]
- },
- {
- "name": "godot_nativescript_set_method_documentation",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_function_name"],
- ["godot_string", "p_documentation"]
- ]
- },
- {
- "name": "godot_nativescript_set_property_documentation",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_path"],
- ["godot_string", "p_documentation"]
- ]
- },
- {
- "name": "godot_nativescript_set_signal_documentation",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const char *", "p_signal_name"],
- ["godot_string", "p_documentation"]
- ]
- },
- {
- "name": "godot_nativescript_set_global_type_tag",
- "return_type": "void",
- "arguments": [
- ["int", "p_idx"],
- ["const char *", "p_name"],
- ["const void *", "p_type_tag"]
- ]
- },
- {
- "name": "godot_nativescript_get_global_type_tag",
- "return_type": "const void *",
- "arguments": [
- ["int", "p_idx"],
- ["const char *", "p_name"]
- ]
- },
- {
- "name": "godot_nativescript_set_type_tag",
- "return_type": "void",
- "arguments": [
- ["void *", "p_gdnative_handle"],
- ["const char *", "p_name"],
- ["const void *", "p_type_tag"]
- ]
- },
- {
- "name": "godot_nativescript_get_type_tag",
- "return_type": "const void *",
- "arguments": [
- ["const godot_object *", "p_object"]
- ]
- },
- {
- "name": "godot_nativescript_register_instance_binding_data_functions",
- "return_type": "int",
- "arguments": [
- ["godot_nativescript_instance_binding_functions", "p_binding_functions"]
- ]
- },
- {
- "name": "godot_nativescript_unregister_instance_binding_data_functions",
- "return_type": "void",
- "arguments": [
- ["int", "p_idx"]
- ]
- },
- {
- "name": "godot_nativescript_get_instance_binding_data",
- "return_type": "void *",
- "arguments": [
- ["int", "p_idx"],
- ["godot_object *", "p_object"]
- ]
- },
- {
- "name": "godot_nativescript_profiling_add_data",
- "return_type": "void",
- "arguments": [
- ["const char *", "p_signature"],
- ["uint64_t", "p_line"]
- ]
- }
- ]
- },
- {
- "name": "pluginscript",
- "type": "PLUGINSCRIPT",
- "version": {
- "major": 1,
- "minor": 0
- },
- "next": null,
- "api": [
- {
- "name": "godot_pluginscript_register_language",
- "return_type": "void",
- "arguments": [
- ["const godot_pluginscript_language_desc *", "language_desc"]
- ]
- }
- ]
- },
- {
- "name": "android",
- "type": "ANDROID",
- "version": {
- "major": 1,
- "minor": 1
- },
- "next": null,
- "api": [
- {
- "name": "godot_android_get_env",
- "return_type": "JNIEnv*",
- "arguments": [
- ]
- },
- {
- "name": "godot_android_get_activity",
- "return_type": "jobject",
- "arguments": [
- ]
- },
- {
- "name": "godot_android_get_surface",
- "return_type": "jobject",
- "arguments": [
- ]
- },
- {
- "name": "godot_android_is_activity_resumed",
- "return_type": "bool",
- "arguments": [
- ]
- }
- ]
- },
- {
- "name": "xr",
- "type": "XR",
- "version": {
- "major": 1,
- "minor": 1
- },
- "next": null,
- "api": [
- {
- "name": "godot_xr_register_interface",
- "return_type": "void",
- "arguments": [
- ["const godot_xr_interface_gdnative *", "p_interface"]
- ]
- },
- {
- "name": "godot_xr_get_worldscale",
- "return_type": "godot_real",
- "arguments": []
- },
- {
- "name": "godot_xr_get_reference_frame",
- "return_type": "godot_transform",
- "arguments": []
- },
- {
- "name": "godot_xr_blit",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_eye"],
- ["godot_rid *", "p_render_target"],
- ["godot_rect2 *", "p_screen_rect"]
- ]
- },
- {
- "name": "godot_xr_get_texid",
- "return_type": "godot_int",
- "arguments": [
- ["godot_rid *", "p_render_target"]
- ]
- },
- {
- "name": "godot_xr_add_controller",
- "return_type": "godot_int",
- "arguments": [
- ["char *", "p_device_name"],
- ["godot_int", "p_hand"],
- ["godot_bool", "p_tracks_orientation"],
- ["godot_bool", "p_tracks_position"]
- ]
- },
- {
- "name": "godot_xr_remove_controller",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_controller_id"]
- ]
- },
- {
- "name": "godot_xr_set_controller_transform",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_controller_id"],
- ["godot_transform *", "p_transform"],
- ["godot_bool", "p_tracks_orientation"],
- ["godot_bool", "p_tracks_position"]
- ]
- },
- {
- "name": "godot_xr_set_controller_button",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_controller_id"],
- ["godot_int", "p_button"],
- ["godot_bool", "p_is_pressed"]
- ]
- },
- {
- "name": "godot_xr_set_controller_axis",
- "return_type": "void",
- "arguments": [
- ["godot_int", "p_controller_id"],
- ["godot_int", "p_exis"],
- ["godot_real", "p_value"],
- ["godot_bool", "p_can_be_negative"]
- ]
- },
- {
- "name": "godot_xr_get_controller_rumble",
- "return_type": "godot_real",
- "arguments": [
- ["godot_int", "p_controller_id"]
- ]
- }
- ]
- },
- {
- "name": "videodecoder",
- "type": "VIDEODECODER",
- "version": {
- "major": 0,
- "minor": 1
- },
- "next": null,
- "api": [
- {
- "name": "godot_videodecoder_file_read",
- "return_type": "godot_int",
- "arguments": [
- ["void *", "file_ptr"],
- ["uint8_t *", "buf"],
- ["int", "buf_size"]
- ]
- },
- {
- "name": "godot_videodecoder_file_seek",
- "return_type": "int64_t",
- "arguments": [
- [ "void *", "file_ptr"],
- ["int64_t", "pos"],
- ["int", "whence"]
- ]
- },
- {
- "name": "godot_videodecoder_register_decoder",
- "return_type": "void",
- "arguments": [
- ["const godot_videodecoder_interface_gdnative *", "p_interface"]
- ]
- }
- ]
- },
- {
- "name": "net",
- "type": "NET",
- "version": {
- "major": 4,
- "minor": 0
- },
- "next": null,
- "api": [
- {
- "name": "godot_net_bind_stream_peer",
- "return_type": "void",
- "arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_stream_peer *", "p_interface"]
- ]
- },
- {
- "name": "godot_net_bind_packet_peer",
- "return_type": "void",
- "arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_packet_peer *", "p_interface"]
- ]
- },
- {
- "name": "godot_net_bind_multiplayer_peer",
- "return_type": "void",
- "arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_multiplayer_peer *", "p_interface"]
- ]
- },
- {
- "name": "godot_net_set_webrtc_library",
- "return_type": "godot_error",
- "arguments": [
- ["const godot_net_webrtc_library *", "p_library"]
- ]
- },
- {
- "name": "godot_net_bind_webrtc_peer_connection",
- "return_type": "void",
- "arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_webrtc_peer_connection *", "p_interface"]
- ]
- },
- {
- "name": "godot_net_bind_webrtc_data_channel",
- "return_type": "void",
- "arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_webrtc_data_channel *", "p_interface"]
- ]
- }
- ]
- },
- {
- "name": "text",
- "type": "TEXT",
- "version": {
- "major": 1,
- "minor": 0
- },
- "next": null,
- "api": [
- {
- "name": "godot_text_register_interface",
- "return_type": "void",
- "arguments": [
- ["const godot_text_interface_gdnative *", "p_interface"],
- ["const godot_string *", "p_name"],
- ["uint32_t", "p_features"]
- ]
- },
- {
- "name": "godot_glyph_new",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "r_dest"]
- ]
- },
- {
- "name": "godot_glyph_get_range",
- "return_type": "godot_vector2i",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_range",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["const godot_vector2i *", "p_range"]
- ]
- },
- {
- "name": "godot_glyph_get_count",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_count",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["godot_int", "p_count"]
- ]
- },
- {
- "name": "godot_glyph_get_repeat",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_repeat",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["godot_int", "p_repeat"]
- ]
- },
- {
- "name": "godot_glyph_get_flags",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_flags",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["godot_int", "p_flags"]
- ]
- },
- {
- "name": "godot_glyph_get_offset",
- "return_type": "godot_vector2",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_offset",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["const godot_vector2 *", "p_offset"]
- ]
- },
- {
- "name": "godot_glyph_get_advance",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_advance",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["godot_real", "p_advance"]
- ]
- },
- {
- "name": "godot_glyph_get_font",
- "return_type": "godot_rid",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_font",
- "return_type": "void ",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["godot_rid *", "p_font"]
- ]
- },
- {
- "name": "godot_glyph_get_font_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_font_size",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_glyph_get_index",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_glyph *", "p_self"]
- ]
- },
- {
- "name": "godot_glyph_set_index",
- "return_type": "void",
- "arguments": [
- ["godot_glyph *", "p_self"],
- ["godot_int", "p_index"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_new",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "r_dest"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_new_copy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "r_dest"],
- ["const godot_packed_glyph_array *", "p_src"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_empty",
- "return_type": "godot_bool",
- "arguments": [
- ["const godot_packed_glyph_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_append",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"],
- ["const godot_glyph *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_append_array",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"],
- ["const godot_packed_glyph_array *", "p_array"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_insert",
- "return_type": "godot_error",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_glyph *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_has",
- "return_type": "godot_bool",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"],
- ["const godot_glyph *", "p_value"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_sort",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_invert",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_push_back",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"],
- ["const godot_glyph *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_remove",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_resize",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"],
- ["const godot_int", "p_size"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_ptr",
- "return_type": "const godot_glyph *",
- "arguments": [
- ["const godot_packed_glyph_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_ptrw",
- "return_type": "godot_glyph *",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_set",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"],
- ["const godot_int", "p_idx"],
- ["const godot_glyph *", "p_data"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_get",
- "return_type": "godot_glyph",
- "arguments": [
- ["const godot_packed_glyph_array *", "p_self"],
- ["const godot_int", "p_idx"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_size",
- "return_type": "godot_int",
- "arguments": [
- ["const godot_packed_glyph_array *", "p_self"]
- ]
- },
- {
- "name": "godot_packed_glyph_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_packed_glyph_array *", "p_self"]
- ]
- }
- ]
- }
- ]
+ "core": {
+ "type": "CORE",
+ "version": {
+ "major": 4,
+ "minor": 0
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_object_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_object *",
+ "p_o"
+ ]
+ ]
+ },
+ {
+ "name": "godot_global_get_singleton",
+ "return_type": "godot_object *",
+ "arguments": [
+ [
+ "char *",
+ "p_name"
+ ]
+ ]
+ },
+ {
+ "name": "godot_method_bind_get_method",
+ "return_type": "godot_method_bind *",
+ "arguments": [
+ [
+ "const char *",
+ "p_classname"
+ ],
+ [
+ "const char *",
+ "p_methodname"
+ ]
+ ]
+ },
+ {
+ "name": "godot_method_bind_ptrcall",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_method_bind *",
+ "p_method_bind"
+ ],
+ [
+ "godot_object *",
+ "p_instance"
+ ],
+ [
+ "const void **",
+ "p_args"
+ ],
+ [
+ "void *",
+ "p_ret"
+ ]
+ ]
+ },
+ {
+ "name": "godot_method_bind_call",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "godot_method_bind *",
+ "p_method_bind"
+ ],
+ [
+ "godot_object *",
+ "p_instance"
+ ],
+ [
+ "const godot_variant **",
+ "p_args"
+ ],
+ [
+ "const int",
+ "p_arg_count"
+ ],
+ [
+ "godot_variant_call_error *",
+ "p_call_error"
+ ]
+ ]
+ },
+ {
+ "name": "godot_get_class_constructor",
+ "return_type": "godot_class_constructor",
+ "arguments": [
+ [
+ "const char *",
+ "p_classname"
+ ]
+ ]
+ },
+ {
+ "name": "godot_get_global_constants",
+ "return_type": "godot_dictionary",
+ "arguments": []
+ },
+ {
+ "name": "godot_register_native_call_type",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const char *",
+ "call_type"
+ ],
+ [
+ "native_call_cb",
+ "p_callback"
+ ]
+ ]
+ },
+ {
+ "name": "godot_alloc",
+ "return_type": "void *",
+ "arguments": [
+ [
+ "int",
+ "p_bytes"
+ ]
+ ]
+ },
+ {
+ "name": "godot_realloc",
+ "return_type": "void *",
+ "arguments": [
+ [
+ "void *",
+ "p_ptr"
+ ],
+ [
+ "int",
+ "p_bytes"
+ ]
+ ]
+ },
+ {
+ "name": "godot_free",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_ptr"
+ ]
+ ]
+ },
+ {
+ "name": "godot_print_error",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const char *",
+ "p_description"
+ ],
+ [
+ "const char *",
+ "p_function"
+ ],
+ [
+ "const char *",
+ "p_file"
+ ],
+ [
+ "int",
+ "p_line"
+ ]
+ ]
+ },
+ {
+ "name": "godot_print_warning",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const char *",
+ "p_description"
+ ],
+ [
+ "const char *",
+ "p_function"
+ ],
+ [
+ "const char *",
+ "p_file"
+ ],
+ [
+ "int",
+ "p_line"
+ ]
+ ]
+ },
+ {
+ "name": "godot_print_script_error",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const char *",
+ "p_description"
+ ],
+ [
+ "const char *",
+ "p_function"
+ ],
+ [
+ "const char *",
+ "p_file"
+ ],
+ [
+ "int",
+ "p_line"
+ ]
+ ]
+ },
+ {
+ "name": "godot_get_class_tag",
+ "return_type": "void *",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_class"
+ ]
+ ]
+ },
+ {
+ "name": "godot_object_cast_to",
+ "return_type": "godot_object *",
+ "arguments": [
+ [
+ "const godot_object *",
+ "p_object"
+ ],
+ [
+ "void *",
+ "p_class_tag"
+ ]
+ ]
+ },
+ {
+ "name": "godot_instance_from_id",
+ "return_type": "godot_object *",
+ "arguments": [
+ [
+ "uint64_t",
+ "p_instance_id"
+ ]
+ ]
+ },
+ {
+ "name": "godot_object_get_instance_id",
+ "return_type": "uint64_t",
+ "arguments": [
+ [
+ "const godot_object *",
+ "p_object"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_copy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_variant *",
+ "p_src"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_nil",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_bool",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_bool",
+ "p_b"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_int",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const int64_t",
+ "p_i"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_float",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const double",
+ "p_f"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_string",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_string *",
+ "p_s"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_string_name",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_string_name *",
+ "p_s"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_vector2",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_vector2 *",
+ "p_v2"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_vector2i",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_vector2i *",
+ "p_v2"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_rect2",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_rect2 *",
+ "p_rect2"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_rect2i",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_rect2i *",
+ "p_rect2"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_vector3",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_vector3 *",
+ "p_v3"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_vector3i",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_vector3i *",
+ "p_v3"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_transform2d",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_transform2d *",
+ "p_t2d"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_plane",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_plane *",
+ "p_plane"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_quat",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_quat *",
+ "p_quat"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_aabb",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_aabb *",
+ "p_aabb"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_basis",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_basis *",
+ "p_basis"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_transform",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_transform *",
+ "p_trans"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_color",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_color *",
+ "p_color"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_node_path",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_node_path *",
+ "p_np"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_rid",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_rid *",
+ "p_rid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_object",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_object *",
+ "p_obj"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_callable",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_callable *",
+ "p_cb"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_signal",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_signal *",
+ "p_signal"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_dictionary",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_dictionary *",
+ "p_dict"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_array *",
+ "p_arr"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_byte_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_byte_array *",
+ "p_pba"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_int32_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_int32_array *",
+ "p_pia"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_int64_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_int64_array *",
+ "p_pia"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_float32_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_float32_array *",
+ "p_pra"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_float64_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_float64_array *",
+ "p_pra"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_string_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_string_array *",
+ "p_psa"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_vector2_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_vector2_array *",
+ "p_pv2a"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_vector3_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_vector3_array *",
+ "p_pv3a"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_color_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_color_array *",
+ "p_pca"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_bool",
+ "return_type": "godot_bool",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_int",
+ "return_type": "int64_t",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_float",
+ "return_type": "double",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_string_name",
+ "return_type": "godot_string_name",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_vector2",
+ "return_type": "godot_vector2",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_vector2i",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_rect2",
+ "return_type": "godot_rect2",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_rect2i",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_vector3",
+ "return_type": "godot_vector3",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_vector3i",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_transform2d",
+ "return_type": "godot_transform2d",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_plane",
+ "return_type": "godot_plane",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_quat",
+ "return_type": "godot_quat",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_aabb",
+ "return_type": "godot_aabb",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_basis",
+ "return_type": "godot_basis",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_transform",
+ "return_type": "godot_transform",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_color",
+ "return_type": "godot_color",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_node_path",
+ "return_type": "godot_node_path",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_rid",
+ "return_type": "godot_rid",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_object",
+ "return_type": "godot_object *",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_callable",
+ "return_type": "godot_callable",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_signal",
+ "return_type": "godot_signal",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_dictionary",
+ "return_type": "godot_dictionary",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_array",
+ "return_type": "godot_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_byte_array",
+ "return_type": "godot_packed_byte_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_int32_array",
+ "return_type": "godot_packed_int32_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_int64_array",
+ "return_type": "godot_packed_int64_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_float32_array",
+ "return_type": "godot_packed_float32_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_float64_array",
+ "return_type": "godot_packed_float64_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_string_array",
+ "return_type": "godot_packed_string_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_vector2_array",
+ "return_type": "godot_packed_vector2_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_vector3_array",
+ "return_type": "godot_packed_vector3_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_color_array",
+ "return_type": "godot_packed_color_array",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_call",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ],
+ [
+ "const godot_variant **",
+ "p_args"
+ ],
+ [
+ "const godot_int",
+ "p_argument_count"
+ ],
+ [
+ "godot_variant *",
+ "r_return"
+ ],
+ [
+ "godot_variant_call_error *",
+ "r_error"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_evaluate",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant_operator",
+ "p_op"
+ ],
+ [
+ "const godot_variant *",
+ "p_a"
+ ],
+ [
+ "const godot_variant *",
+ "p_b"
+ ],
+ [
+ "godot_variant *",
+ "r_return"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_set",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_variant *",
+ "p_key"
+ ],
+ [
+ "const godot_variant *",
+ "p_value"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_set_named",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_string_name *",
+ "p_name"
+ ],
+ [
+ "const godot_variant *",
+ "p_value"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_set_keyed",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_variant *",
+ "p_key"
+ ],
+ [
+ "const godot_variant *",
+ "p_value"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_set_indexed",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ],
+ [
+ "const godot_variant *",
+ "p_value"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ],
+ [
+ "bool *",
+ "r_oob"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_variant *",
+ "p_key"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_named",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_string_name *",
+ "p_key"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_keyed",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_variant *",
+ "p_key"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_indexed",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ],
+ [
+ "bool *",
+ "r_oob"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_iter_init",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "godot_variant *",
+ "r_iter"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_iter_next",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "godot_variant *",
+ "r_iter"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_iter_get",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "godot_variant *",
+ "r_iter"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_hash_compare",
+ "return_type": "godot_bool",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_variant *",
+ "p_other"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_booleanize",
+ "return_type": "godot_bool",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_blend",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_a"
+ ],
+ [
+ "const godot_variant *",
+ "p_b"
+ ],
+ [
+ "float",
+ "p_c"
+ ],
+ [
+ "godot_variant *",
+ "r_dst"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_interpolate",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_a"
+ ],
+ [
+ "const godot_variant *",
+ "p_b"
+ ],
+ [
+ "float",
+ "p_c"
+ ],
+ [
+ "godot_variant *",
+ "r_dst"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_duplicate",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "godot_bool",
+ "p_deep"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_stringify",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_operator_evaluator",
+ "return_type": "godot_validated_operator_evaluator",
+ "arguments": [
+ [
+ "godot_variant_operator",
+ "p_operator"
+ ],
+ [
+ "godot_variant_type",
+ "p_type_a"
+ ],
+ [
+ "godot_variant_type",
+ "p_type_b"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_operator_evaluator",
+ "return_type": "godot_ptr_operator_evaluator",
+ "arguments": [
+ [
+ "godot_variant_operator",
+ "p_operator"
+ ],
+ [
+ "godot_variant_type",
+ "p_type_a"
+ ],
+ [
+ "godot_variant_type",
+ "p_type_b"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_operator_return_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_operator",
+ "p_operator"
+ ],
+ [
+ "godot_variant_type",
+ "p_type_a"
+ ],
+ [
+ "godot_variant_type",
+ "p_type_b"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_operator_name",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "godot_variant_operator",
+ "p_operator"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_builtin_method",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_builtin_method_with_cstring",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_builtin_method",
+ "return_type": "godot_validated_builtin_method",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_builtin_method_with_cstring",
+ "return_type": "godot_validated_builtin_method",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_builtin_method",
+ "return_type": "godot_ptr_builtin_method",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_builtin_method_with_cstring",
+ "return_type": "godot_ptr_builtin_method",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_argument_count",
+ "return_type": "int",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_argument_count_with_cstring",
+ "return_type": "int",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_argument_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_argument_type_with_cstring",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_argument_name",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_argument_name_with_cstring",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_builtin_method_return_value",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_builtin_method_return_value_with_cstring",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_return_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_return_type_with_cstring",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_is_builtin_method_const",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_is_builtin_method_const_with_cstring",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_is_builtin_method_vararg",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_is_builtin_method_vararg_with_cstring",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_count",
+ "return_type": "int",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_builtin_method_list",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "godot_string_name *",
+ "r_list"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_constructor_count",
+ "return_type": "int",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_constructor",
+ "return_type": "godot_validated_constructor",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "int",
+ "p_constructor"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_constructor",
+ "return_type": "godot_ptr_constructor",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "int",
+ "p_constructor"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_constructor_argument_count",
+ "return_type": "int",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "int",
+ "p_constructor"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_constructor_argument_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "int",
+ "p_constructor"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_constructor_argument_name",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "int",
+ "p_constructor"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_construct",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "godot_variant *",
+ "p_base"
+ ],
+ [
+ "const godot_variant **",
+ "p_args"
+ ],
+ [
+ "int",
+ "p_argument_count"
+ ],
+ [
+ "godot_variant_call_error *",
+ "r_error"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_member_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_member_type_with_cstring",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_member_count",
+ "return_type": "int",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_member_list",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "godot_string_name *",
+ "r_list"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_setter",
+ "return_type": "godot_validated_setter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_setter_with_cstring",
+ "return_type": "godot_validated_setter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_getter",
+ "return_type": "godot_validated_getter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_getter_with_cstring",
+ "return_type": "godot_validated_getter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_setter",
+ "return_type": "godot_ptr_setter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_setter_with_cstring",
+ "return_type": "godot_ptr_setter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_getter",
+ "return_type": "godot_ptr_getter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_getter_with_cstring",
+ "return_type": "godot_ptr_getter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_indexing",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_indexed_element_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_indexed_setter",
+ "return_type": "godot_validated_indexed_setter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_indexed_getter",
+ "return_type": "godot_validated_indexed_getter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_indexed_setter",
+ "return_type": "godot_ptr_indexed_setter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_indexed_getter",
+ "return_type": "godot_ptr_indexed_getter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_indexed_size",
+ "return_type": "uint64_t",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_is_keyed",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_keyed_setter",
+ "return_type": "godot_validated_keyed_setter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_keyed_getter",
+ "return_type": "godot_validated_keyed_getter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_keyed_checker",
+ "return_type": "godot_validated_keyed_checker",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_keyed_setter",
+ "return_type": "godot_ptr_keyed_setter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_keyed_getter",
+ "return_type": "godot_ptr_keyed_getter",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_keyed_checker",
+ "return_type": "godot_ptr_keyed_checker",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_constants_count",
+ "return_type": "int",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_constants_list",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "godot_string_name *",
+ "r_list"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_constant",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_constant"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_constant_with_cstring",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_constant"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_constant_value",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_constant"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_constant_value_with_cstring",
+ "return_type": "godot_variant",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const char *",
+ "p_constant"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_utility_function",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_utility_function_with_cstring",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_call_utility_function",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ],
+ [
+ "godot_variant *",
+ "r_ret"
+ ],
+ [
+ "const godot_variant **",
+ "p_args"
+ ],
+ [
+ "int",
+ "p_argument_count"
+ ],
+ [
+ "godot_variant_call_error *",
+ "r_error"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_call_utility_function_with_cstring",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ],
+ [
+ "godot_variant *",
+ "r_ret"
+ ],
+ [
+ "const godot_variant **",
+ "p_args"
+ ],
+ [
+ "int",
+ "p_argument_count"
+ ],
+ [
+ "godot_variant_call_error *",
+ "r_error"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_utility_function",
+ "return_type": "godot_ptr_utility_function",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_ptr_utility_function_with_cstring",
+ "return_type": "godot_ptr_utility_function",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_utility_function",
+ "return_type": "godot_validated_utility_function",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_validated_utility_function_with_cstring",
+ "return_type": "godot_validated_utility_function",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_type",
+ "return_type": "godot_variant_utility_function_type",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_type_with_cstring",
+ "return_type": "godot_variant_utility_function_type",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_argument_count",
+ "return_type": "int",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_argument_count_with_cstring",
+ "return_type": "int",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_argument_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_argument_type_with_cstring",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_argument_name",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_argument_name_with_cstring",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ],
+ [
+ "int",
+ "p_argument"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_utility_function_return_value",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_utility_function_return_value_with_cstring",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_return_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_return_type_with_cstring",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_is_utility_function_vararg",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const godot_string_name *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_is_utility_function_vararg_with_cstring",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const char *",
+ "p_function"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_utility_function_count",
+ "return_type": "int",
+ "arguments": []
+ },
+ {
+ "name": "godot_variant_get_utility_function_list",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string_name *",
+ "r_functions"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_type",
+ "return_type": "godot_variant_type",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_method",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_string_name *",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_member",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ],
+ [
+ "const godot_string_name *",
+ "p_member"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_has_key",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "const godot_variant *",
+ "p_self"
+ ],
+ [
+ "const godot_variant *",
+ "p_key"
+ ],
+ [
+ "bool *",
+ "r_valid"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_get_type_name",
+ "return_type": "godot_string",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_type"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_can_convert",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_from"
+ ],
+ [
+ "godot_variant_type",
+ "p_to"
+ ]
+ ]
+ },
+ {
+ "name": "godot_variant_can_convert_strict",
+ "return_type": "bool",
+ "arguments": [
+ [
+ "godot_variant_type",
+ "p_from"
+ ],
+ [
+ "godot_variant_type",
+ "p_to"
+ ]
+ ]
+ },
+ {
+ "name": "godot_aabb_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_aabb *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_array_operator_index",
+ "return_type": "godot_variant *",
+ "arguments": [
+ [
+ "godot_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_array_operator_index_const",
+ "return_type": "const godot_variant *",
+ "arguments": [
+ [
+ "const godot_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_basis_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_basis *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_basis_operator_index",
+ "return_type": "godot_vector3 *",
+ "arguments": [
+ [
+ "godot_basis *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_basis_operator_index_const",
+ "return_type": "const godot_vector3 *",
+ "arguments": [
+ [
+ "const godot_basis *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_callable_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_callable *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_callable_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_callable *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_color_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_color *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_color_operator_index",
+ "return_type": "float *",
+ "arguments": [
+ [
+ "godot_color *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_color_operator_index_const",
+ "return_type": "const float *",
+ "arguments": [
+ [
+ "const godot_color *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_dictionary_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_dictionary *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_dictionary_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_dictionary *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_dictionary_operator_index",
+ "return_type": "godot_variant *",
+ "arguments": [
+ [
+ "godot_dictionary *",
+ "p_self"
+ ],
+ [
+ "const godot_variant *",
+ "p_key"
+ ]
+ ]
+ },
+ {
+ "name": "godot_dictionary_operator_index_const",
+ "return_type": "const godot_variant *",
+ "arguments": [
+ [
+ "const godot_dictionary *",
+ "p_self"
+ ],
+ [
+ "const godot_variant *",
+ "p_key"
+ ]
+ ]
+ },
+ {
+ "name": "godot_node_path_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_node_path *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_node_path_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_node_path *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_byte_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_byte_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_byte_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_byte_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_byte_array_operator_index",
+ "return_type": "uint8_t *",
+ "arguments": [
+ [
+ "godot_packed_byte_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_byte_array_operator_index_const",
+ "return_type": "const uint8_t *",
+ "arguments": [
+ [
+ "const godot_packed_byte_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_int32_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_int32_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_int32_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_int32_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_int32_array_operator_index",
+ "return_type": "int32_t *",
+ "arguments": [
+ [
+ "godot_packed_int32_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_int32_array_operator_index_const",
+ "return_type": "const int32_t *",
+ "arguments": [
+ [
+ "const godot_packed_int32_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_int64_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_int64_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_operator_index",
+ "return_type": "int64_t *",
+ "arguments": [
+ [
+ "godot_packed_int64_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_operator_index_const",
+ "return_type": "const int64_t *",
+ "arguments": [
+ [
+ "const godot_packed_int64_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_float32_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_float32_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_float32_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_float32_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_float32_array_operator_index",
+ "return_type": "float *",
+ "arguments": [
+ [
+ "godot_packed_float32_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_float32_array_operator_index_const",
+ "return_type": "const float *",
+ "arguments": [
+ [
+ "const godot_packed_float32_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_float64_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_float64_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_operator_index",
+ "return_type": "double *",
+ "arguments": [
+ [
+ "godot_packed_float64_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_operator_index_const",
+ "return_type": "const double *",
+ "arguments": [
+ [
+ "const godot_packed_float64_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_string_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_string_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_string_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_string_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_string_array_operator_index",
+ "return_type": "godot_string *",
+ "arguments": [
+ [
+ "godot_packed_string_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_string_array_operator_index_const",
+ "return_type": "const godot_string *",
+ "arguments": [
+ [
+ "const godot_packed_string_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector2_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_vector2_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector2_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_vector2_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector2_array_operator_index",
+ "return_type": "godot_vector2 *",
+ "arguments": [
+ [
+ "godot_packed_vector2_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector2_array_operator_index_const",
+ "return_type": "const godot_vector2 *",
+ "arguments": [
+ [
+ "const godot_packed_vector2_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector2i_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_vector2i_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector2i_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_vector2i_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector2i_array_operator_index",
+ "return_type": "godot_vector2i *",
+ "arguments": [
+ [
+ "godot_packed_vector2i_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector2i_array_operator_index_const",
+ "return_type": "const godot_vector2i *",
+ "arguments": [
+ [
+ "const godot_packed_vector2i_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector3_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_vector3_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector3_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_vector3_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector3_array_operator_index",
+ "return_type": "godot_vector3 *",
+ "arguments": [
+ [
+ "godot_packed_vector3_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector3_array_operator_index_const",
+ "return_type": "const godot_vector3 *",
+ "arguments": [
+ [
+ "const godot_packed_vector3_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector3i_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_vector3i_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector3i_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_vector3i_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector3i_array_operator_index",
+ "return_type": "godot_vector3i *",
+ "arguments": [
+ [
+ "godot_packed_vector3i_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_vector3i_array_operator_index_const",
+ "return_type": "const godot_vector3i *",
+ "arguments": [
+ [
+ "const godot_packed_vector3i_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_color_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_color_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_color_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_color_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_color_array_operator_index",
+ "return_type": "godot_color *",
+ "arguments": [
+ [
+ "godot_packed_color_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_color_array_operator_index_const",
+ "return_type": "const godot_color *",
+ "arguments": [
+ [
+ "const godot_packed_color_array *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_plane_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_plane *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_quat_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_quat *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_quat_operator_index",
+ "return_type": "godot_real_t *",
+ "arguments": [
+ [
+ "godot_quat *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_quat_operator_index_const",
+ "return_type": "const godot_real_t *",
+ "arguments": [
+ [
+ "const godot_quat *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_rect2_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_rect2 *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_rect2i_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_rect2i *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_rid_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_rid *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_signal_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_signal *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_signal_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_signal *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_copy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const godot_string *",
+ "p_src"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_latin1_chars",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const char *",
+ "p_contents"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf8_chars",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const char *",
+ "p_contents"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf16_chars",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const char16_t *",
+ "p_contents"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf32_chars",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const char32_t *",
+ "p_contents"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_wide_chars",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const wchar_t *",
+ "p_contents"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_latin1_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const char *",
+ "p_contents"
+ ],
+ [
+ "const int",
+ "p_size"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf8_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const char *",
+ "p_contents"
+ ],
+ [
+ "const int",
+ "p_size"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf16_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const char16_t *",
+ "p_contents"
+ ],
+ [
+ "const int",
+ "p_size"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_utf32_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const char32_t *",
+ "p_contents"
+ ],
+ [
+ "const int",
+ "p_size"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_new_with_wide_chars_and_len",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string *",
+ "r_dest"
+ ],
+ [
+ "const wchar_t *",
+ "p_contents"
+ ],
+ [
+ "const int",
+ "p_size"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_name_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string_name *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_name_new_copy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string_name *",
+ "r_dest"
+ ],
+ [
+ "const godot_string_name *",
+ "p_src"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_name_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string_name *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_string_name_new_with_latin1_chars",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_string_name *",
+ "r_dest"
+ ],
+ [
+ "const char *",
+ "p_contents"
+ ]
+ ]
+ },
+ {
+ "name": "godot_transform_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_transform *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_transform2d_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_transform2d *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_transform2d_operator_index",
+ "return_type": "godot_vector2 *",
+ "arguments": [
+ [
+ "godot_transform2d *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_transform2d_operator_index_const",
+ "return_type": "const godot_vector2 *",
+ "arguments": [
+ [
+ "const godot_transform2d *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector2_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_vector2 *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_index",
+ "return_type": "godot_real_t *",
+ "arguments": [
+ [
+ "godot_vector2 *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector2_operator_index_const",
+ "return_type": "const godot_real_t *",
+ "arguments": [
+ [
+ "const godot_vector2 *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector2i_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_vector2i *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_index",
+ "return_type": "int32_t *",
+ "arguments": [
+ [
+ "godot_vector2i *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_index_const",
+ "return_type": "const int32_t *",
+ "arguments": [
+ [
+ "const godot_vector2i *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector3_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_vector3 *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_index",
+ "return_type": "godot_real_t *",
+ "arguments": [
+ [
+ "godot_vector3 *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector3_operator_index_const",
+ "return_type": "const godot_real_t *",
+ "arguments": [
+ [
+ "const godot_vector3 *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector3i_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_vector3i *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_index",
+ "return_type": "int32_t *",
+ "arguments": [
+ [
+ "godot_vector3i *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_index_const",
+ "return_type": "const int32_t *",
+ "arguments": [
+ [
+ "const godot_vector3i *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ }
+ ]
+ },
+ "extensions": [
+ {
+ "name": "nativescript",
+ "type": "NATIVESCRIPT",
+ "version": {
+ "major": 4,
+ "minor": 0
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_nativescript_register_class",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const char *",
+ "p_base"
+ ],
+ [
+ "godot_nativescript_instance_create_func",
+ "p_create_func"
+ ],
+ [
+ "godot_nativescript_instance_destroy_func",
+ "p_destroy_func"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_tool_class",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const char *",
+ "p_base"
+ ],
+ [
+ "godot_nativescript_instance_create_func",
+ "p_create_func"
+ ],
+ [
+ "godot_nativescript_instance_destroy_func",
+ "p_destroy_func"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_method",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const char *",
+ "p_function_name"
+ ],
+ [
+ "godot_nativescript_method_attributes",
+ "p_attr"
+ ],
+ [
+ "godot_nativescript_instance_method",
+ "p_method"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_set_method_argument_information",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const char *",
+ "p_function_name"
+ ],
+ [
+ "int",
+ "p_num_args"
+ ],
+ [
+ "const godot_nativescript_method_argument *",
+ "p_args"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_property",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const char *",
+ "p_path"
+ ],
+ [
+ "godot_nativescript_property_attributes *",
+ "p_attr"
+ ],
+ [
+ "godot_nativescript_property_set_func",
+ "p_set_func"
+ ],
+ [
+ "godot_nativescript_property_get_func",
+ "p_get_func"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_signal",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const godot_nativescript_signal *",
+ "p_signal"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_get_userdata",
+ "return_type": "void *",
+ "arguments": [
+ [
+ "godot_object *",
+ "p_instance"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_set_class_documentation",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "godot_string",
+ "p_documentation"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_set_method_documentation",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const char *",
+ "p_function_name"
+ ],
+ [
+ "godot_string",
+ "p_documentation"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_set_property_documentation",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const char *",
+ "p_path"
+ ],
+ [
+ "godot_string",
+ "p_documentation"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_set_signal_documentation",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const char *",
+ "p_signal_name"
+ ],
+ [
+ "godot_string",
+ "p_documentation"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_set_global_type_tag",
+ "return_type": "void",
+ "arguments": [
+ [
+ "int",
+ "p_idx"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const void *",
+ "p_type_tag"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_get_global_type_tag",
+ "return_type": "const void *",
+ "arguments": [
+ [
+ "int",
+ "p_idx"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_set_type_tag",
+ "return_type": "void",
+ "arguments": [
+ [
+ "void *",
+ "p_gdnative_handle"
+ ],
+ [
+ "const char *",
+ "p_name"
+ ],
+ [
+ "const void *",
+ "p_type_tag"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_get_type_tag",
+ "return_type": "const void *",
+ "arguments": [
+ [
+ "const godot_object *",
+ "p_object"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_register_instance_binding_data_functions",
+ "return_type": "int",
+ "arguments": [
+ [
+ "godot_nativescript_instance_binding_functions",
+ "p_binding_functions"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_unregister_instance_binding_data_functions",
+ "return_type": "void",
+ "arguments": [
+ [
+ "int",
+ "p_idx"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_get_instance_binding_data",
+ "return_type": "void *",
+ "arguments": [
+ [
+ "int",
+ "p_idx"
+ ],
+ [
+ "godot_object *",
+ "p_object"
+ ]
+ ]
+ },
+ {
+ "name": "godot_nativescript_profiling_add_data",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const char *",
+ "p_signature"
+ ],
+ [
+ "uint64_t",
+ "p_line"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "name": "pluginscript",
+ "type": "PLUGINSCRIPT",
+ "version": {
+ "major": 1,
+ "minor": 0
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_pluginscript_register_language",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const godot_pluginscript_language_desc *",
+ "language_desc"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "name": "android",
+ "type": "ANDROID",
+ "version": {
+ "major": 1,
+ "minor": 1
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_android_get_env",
+ "return_type": "JNIEnv*",
+ "arguments": []
+ },
+ {
+ "name": "godot_android_get_activity",
+ "return_type": "jobject",
+ "arguments": []
+ },
+ {
+ "name": "godot_android_get_surface",
+ "return_type": "jobject",
+ "arguments": []
+ },
+ {
+ "name": "godot_android_is_activity_resumed",
+ "return_type": "bool",
+ "arguments": []
+ }
+ ]
+ },
+ {
+ "name": "xr",
+ "type": "XR",
+ "version": {
+ "major": 1,
+ "minor": 1
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_xr_register_interface",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const godot_xr_interface_gdnative *",
+ "p_interface"
+ ]
+ ]
+ },
+ {
+ "name": "godot_xr_get_worldscale",
+ "return_type": "godot_float",
+ "arguments": []
+ },
+ {
+ "name": "godot_xr_get_reference_frame",
+ "return_type": "godot_transform",
+ "arguments": []
+ },
+ {
+ "name": "godot_xr_blit",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_int",
+ "p_eye"
+ ],
+ [
+ "godot_rid *",
+ "p_render_target"
+ ],
+ [
+ "godot_rect2 *",
+ "p_screen_rect"
+ ]
+ ]
+ },
+ {
+ "name": "godot_xr_get_texid",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "godot_rid *",
+ "p_render_target"
+ ]
+ ]
+ },
+ {
+ "name": "godot_xr_add_controller",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "char *",
+ "p_device_name"
+ ],
+ [
+ "godot_int",
+ "p_hand"
+ ],
+ [
+ "godot_bool",
+ "p_tracks_orientation"
+ ],
+ [
+ "godot_bool",
+ "p_tracks_position"
+ ]
+ ]
+ },
+ {
+ "name": "godot_xr_remove_controller",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_int",
+ "p_controller_id"
+ ]
+ ]
+ },
+ {
+ "name": "godot_xr_set_controller_transform",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_int",
+ "p_controller_id"
+ ],
+ [
+ "godot_transform *",
+ "p_transform"
+ ],
+ [
+ "godot_bool",
+ "p_tracks_orientation"
+ ],
+ [
+ "godot_bool",
+ "p_tracks_position"
+ ]
+ ]
+ },
+ {
+ "name": "godot_xr_set_controller_button",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_int",
+ "p_controller_id"
+ ],
+ [
+ "godot_int",
+ "p_button"
+ ],
+ [
+ "godot_bool",
+ "p_is_pressed"
+ ]
+ ]
+ },
+ {
+ "name": "godot_xr_set_controller_axis",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_int",
+ "p_controller_id"
+ ],
+ [
+ "godot_int",
+ "p_exis"
+ ],
+ [
+ "godot_float",
+ "p_value"
+ ],
+ [
+ "godot_bool",
+ "p_can_be_negative"
+ ]
+ ]
+ },
+ {
+ "name": "godot_xr_get_controller_rumble",
+ "return_type": "godot_float",
+ "arguments": [
+ [
+ "godot_int",
+ "p_controller_id"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "name": "videodecoder",
+ "type": "VIDEODECODER",
+ "version": {
+ "major": 0,
+ "minor": 1
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_videodecoder_file_read",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "void *",
+ "file_ptr"
+ ],
+ [
+ "uint8_t *",
+ "buf"
+ ],
+ [
+ "int",
+ "buf_size"
+ ]
+ ]
+ },
+ {
+ "name": "godot_videodecoder_file_seek",
+ "return_type": "int64_t",
+ "arguments": [
+ [
+ "void *",
+ "file_ptr"
+ ],
+ [
+ "int64_t",
+ "pos"
+ ],
+ [
+ "int",
+ "whence"
+ ]
+ ]
+ },
+ {
+ "name": "godot_videodecoder_register_decoder",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const godot_videodecoder_interface_gdnative *",
+ "p_interface"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "name": "net",
+ "type": "NET",
+ "version": {
+ "major": 4,
+ "minor": 0
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_net_bind_stream_peer",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_object *",
+ "p_obj"
+ ],
+ [
+ "const godot_net_stream_peer *",
+ "p_interface"
+ ]
+ ]
+ },
+ {
+ "name": "godot_net_bind_packet_peer",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_object *",
+ "p_obj"
+ ],
+ [
+ "const godot_net_packet_peer *",
+ "p_interface"
+ ]
+ ]
+ },
+ {
+ "name": "godot_net_bind_multiplayer_peer",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_object *",
+ "p_obj"
+ ],
+ [
+ "const godot_net_multiplayer_peer *",
+ "p_interface"
+ ]
+ ]
+ },
+ {
+ "name": "godot_net_set_webrtc_library",
+ "return_type": "godot_error",
+ "arguments": [
+ [
+ "const godot_net_webrtc_library *",
+ "p_library"
+ ]
+ ]
+ },
+ {
+ "name": "godot_net_bind_webrtc_peer_connection",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_object *",
+ "p_obj"
+ ],
+ [
+ "const godot_net_webrtc_peer_connection *",
+ "p_interface"
+ ]
+ ]
+ },
+ {
+ "name": "godot_net_bind_webrtc_data_channel",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_object *",
+ "p_obj"
+ ],
+ [
+ "const godot_net_webrtc_data_channel *",
+ "p_interface"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "name": "text",
+ "type": "TEXT",
+ "version": {
+ "major": 1,
+ "minor": 0
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_text_register_interface",
+ "return_type": "void",
+ "arguments": [
+ [
+ "const godot_text_interface_gdnative *",
+ "p_interface"
+ ],
+ [
+ "const godot_string *",
+ "p_name"
+ ],
+ [
+ "uint32_t",
+ "p_features"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_range",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_range",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "const godot_vector2i *",
+ "p_range"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_count",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_count",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_count"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_repeat",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_repeat",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_repeat"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_flags",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_flags",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_flags"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_offset",
+ "return_type": "godot_vector2",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_offset",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "const godot_vector2 *",
+ "p_offset"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_advance",
+ "return_type": "godot_float",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_advance",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "godot_float",
+ "p_advance"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_font",
+ "return_type": "godot_rid",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_font",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "godot_rid *",
+ "p_font"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_font_size",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_font_size",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_size"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_get_index",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "const godot_glyph *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_glyph_set_index",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_glyph *",
+ "p_self"
+ ],
+ [
+ "godot_int",
+ "p_index"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_new",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "r_dest"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "r_dest"
+ ],
+ [
+ "const godot_packed_glyph_array *",
+ "p_src"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_is_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ [
+ "const godot_packed_glyph_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_append",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_glyph *",
+ "p_data"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_packed_glyph_array *",
+ "p_array"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_int",
+ "p_idx"
+ ],
+ [
+ "const godot_glyph *",
+ "p_data"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_has",
+ "return_type": "godot_bool",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_glyph *",
+ "p_value"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_sort",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_invert",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_glyph *",
+ "p_data"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_remove",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_int",
+ "p_idx"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_resize",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_int",
+ "p_size"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_ptr",
+ "return_type": "const godot_glyph *",
+ "arguments": [
+ [
+ "const godot_packed_glyph_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_ptrw",
+ "return_type": "godot_glyph *",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_set",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_int",
+ "p_idx"
+ ],
+ [
+ "const godot_glyph *",
+ "p_data"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_get",
+ "return_type": "godot_glyph",
+ "arguments": [
+ [
+ "const godot_packed_glyph_array *",
+ "p_self"
+ ],
+ [
+ "const godot_int",
+ "p_idx"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ [
+ "const godot_packed_glyph_array *",
+ "p_self"
+ ]
+ ]
+ },
+ {
+ "name": "godot_packed_glyph_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ [
+ "godot_packed_glyph_array *",
+ "p_self"
+ ]
+ ]
+ }
+ ]
+ }
+ ]
}
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index 5ea5c8ee8d..dfb26c13e3 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,7 +65,7 @@ void GDNativeLibraryEditor::_update_tree() {
continue;
}
Map<String, NativePlatformConfig>::Element *E = platforms.find(filter_list->get_item_metadata(i));
- if (!text.empty()) {
+ if (!text.is_empty()) {
text += ", ";
}
text += E->get().name;
@@ -91,7 +91,7 @@ void GDNativeLibraryEditor::_update_tree() {
bit->add_button(1, get_theme_icon("Folder", "EditorIcons"), BUTTON_SELECT_LIBRARY, false, TTR("Select the dynamic library for this entry"));
String file = entry_configs[target].library;
- if (!file.empty()) {
+ if (!file.is_empty()) {
bit->add_button(1, get_theme_icon("Clear", "EditorIcons"), BUTTON_CLEAR_LIBRARY, false, TTR("Clear"));
}
bit->set_text(1, file);
@@ -195,7 +195,7 @@ void GDNativeLibraryEditor::_on_item_activated() {
void GDNativeLibraryEditor::_on_create_new_entry() {
String platform = new_architecture_dialog->get_meta("platform");
String entry = new_architecture_input->get_text().strip_edges();
- if (!entry.empty()) {
+ if (!entry.is_empty()) {
platforms[platform].entries.push_back(entry);
_update_tree();
}
@@ -248,7 +248,7 @@ void GDNativeLibraryEditor::_translate_to_config_file() {
for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) {
String target = E->key() + "." + it->get();
- if (entry_configs[target].library.empty() && entry_configs[target].dependencies.empty()) {
+ if (entry_configs[target].library.is_empty() && entry_configs[target].dependencies.is_empty()) {
continue;
}
@@ -257,7 +257,7 @@ void GDNativeLibraryEditor::_translate_to_config_file() {
}
}
- library->_change_notify();
+ library->notify_property_list_changed();
}
}
diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h
index 180ab7707c..61afb1aaaa 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.h
+++ b/modules/gdnative/gdnative_library_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -95,9 +95,9 @@ public:
class GDNativeLibraryEditorPlugin : public EditorPlugin {
GDCLASS(GDNativeLibraryEditorPlugin, EditorPlugin);
- GDNativeLibraryEditor *library_editor;
- EditorNode *editor;
- Button *button;
+ GDNativeLibraryEditor *library_editor = nullptr;
+ EditorNode *editor = nullptr;
+ Button *button = nullptr;
public:
virtual String get_name() const override { return "GDNativeLibrary"; }
diff --git a/modules/gdnative/gdnative_library_singleton_editor.cpp b/modules/gdnative/gdnative_library_singleton_editor.cpp
index 409b6cbffe..f1b4a9a81b 100644
--- a/modules/gdnative/gdnative_library_singleton_editor.cpp
+++ b/modules/gdnative/gdnative_library_singleton_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/gdnative_library_singleton_editor.h b/modules/gdnative/gdnative_library_singleton_editor.h
index 1a213d8094..5bb823d920 100644
--- a/modules/gdnative/gdnative_library_singleton_editor.h
+++ b/modules/gdnative/gdnative_library_singleton_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/include/android/godot_android.h b/modules/gdnative/include/android/godot_android.h
index 45d4eaff37..867ef9e03a 100644
--- a/modules/gdnative/include/android/godot_android.h
+++ b/modules/gdnative/include/android/godot_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/include/gdnative/aabb.h b/modules/gdnative/include/gdnative/aabb.h
index c776297944..be0235221f 100644
--- a/modules/gdnative/include/gdnative/aabb.h
+++ b/modules/gdnative/include/gdnative/aabb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,9 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_AABB_SIZE 24
+#define GODOT_AABB_SIZE (sizeof(godot_real_t) * 6)
#ifndef GODOT_CORE_API_GODOT_AABB_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_AABB_TYPE_DEFINED
@@ -46,72 +46,9 @@ typedef struct {
} godot_aabb;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/plane.h>
-#include <gdnative/vector3.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_aabb_new(godot_aabb *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size);
-
-godot_vector3 GDAPI godot_aabb_get_position(const godot_aabb *p_self);
-void GDAPI godot_aabb_set_position(const godot_aabb *p_self, const godot_vector3 *p_v);
-
-godot_vector3 GDAPI godot_aabb_get_size(const godot_aabb *p_self);
-void GDAPI godot_aabb_set_size(const godot_aabb *p_self, const godot_vector3 *p_v);
-
-godot_string GDAPI godot_aabb_as_string(const godot_aabb *p_self);
-
-godot_aabb GDAPI godot_aabb_abs(const godot_aabb *p_self);
-
-godot_real GDAPI godot_aabb_get_area(const godot_aabb *p_self);
-
-godot_bool GDAPI godot_aabb_has_no_area(const godot_aabb *p_self);
-
-godot_bool GDAPI godot_aabb_has_no_surface(const godot_aabb *p_self);
-
-godot_bool GDAPI godot_aabb_intersects(const godot_aabb *p_self, const godot_aabb *p_with);
-
-godot_bool GDAPI godot_aabb_encloses(const godot_aabb *p_self, const godot_aabb *p_with);
-
-godot_aabb GDAPI godot_aabb_merge(const godot_aabb *p_self, const godot_aabb *p_with);
-
-godot_aabb GDAPI godot_aabb_intersection(const godot_aabb *p_self, const godot_aabb *p_with);
-
-godot_bool GDAPI godot_aabb_intersects_plane(const godot_aabb *p_self, const godot_plane *p_plane);
-
-godot_bool GDAPI godot_aabb_intersects_segment(const godot_aabb *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to);
-
-godot_bool GDAPI godot_aabb_has_point(const godot_aabb *p_self, const godot_vector3 *p_point);
-
-godot_vector3 GDAPI godot_aabb_get_support(const godot_aabb *p_self, const godot_vector3 *p_dir);
-
-godot_vector3 GDAPI godot_aabb_get_longest_axis(const godot_aabb *p_self);
-
-godot_int GDAPI godot_aabb_get_longest_axis_index(const godot_aabb *p_self);
-
-godot_real GDAPI godot_aabb_get_longest_axis_size(const godot_aabb *p_self);
-
-godot_vector3 GDAPI godot_aabb_get_shortest_axis(const godot_aabb *p_self);
-
-godot_int GDAPI godot_aabb_get_shortest_axis_index(const godot_aabb *p_self);
-
-godot_real GDAPI godot_aabb_get_shortest_axis_size(const godot_aabb *p_self);
-
-godot_aabb GDAPI godot_aabb_expand(const godot_aabb *p_self, const godot_vector3 *p_to_point);
-
-godot_aabb GDAPI godot_aabb_grow(const godot_aabb *p_self, const godot_real p_by);
-
-godot_vector3 GDAPI godot_aabb_get_endpoint(const godot_aabb *p_self, const godot_int p_idx);
-godot_bool GDAPI godot_aabb_operator_equal(const godot_aabb *p_self, const godot_aabb *p_b);
+void GDAPI godot_aabb_new(godot_aabb *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h
index 7a59493b7d..7603edaa73 100644
--- a/modules/gdnative/include/gdnative/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,102 +46,13 @@ typedef struct {
} godot_array;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
-#include <gdnative/packed_arrays.h>
-#include <gdnative/variant.h>
-
#include <gdnative/gdnative.h>
+#include <gdnative/variant_struct.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_array_new(godot_array *r_dest);
-void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src);
-void GDAPI godot_array_new_packed_color_array(godot_array *r_dest, const godot_packed_color_array *p_pca);
-void GDAPI godot_array_new_packed_vector3_array(godot_array *r_dest, const godot_packed_vector3_array *p_pv3a);
-void GDAPI godot_array_new_packed_vector2_array(godot_array *r_dest, const godot_packed_vector2_array *p_pv2a);
-void GDAPI godot_array_new_packed_vector2i_array(godot_array *r_dest, const godot_packed_vector2i_array *p_pv2a);
-void GDAPI godot_array_new_packed_string_array(godot_array *r_dest, const godot_packed_string_array *p_psa);
-void GDAPI godot_array_new_packed_float32_array(godot_array *r_dest, const godot_packed_float32_array *p_pra);
-void GDAPI godot_array_new_packed_float64_array(godot_array *r_dest, const godot_packed_float64_array *p_pra);
-void GDAPI godot_array_new_packed_int32_array(godot_array *r_dest, const godot_packed_int32_array *p_pia);
-void GDAPI godot_array_new_packed_int64_array(godot_array *r_dest, const godot_packed_int64_array *p_pia);
-void GDAPI godot_array_new_packed_byte_array(godot_array *r_dest, const godot_packed_byte_array *p_pba);
-
-void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value);
-
-godot_variant GDAPI godot_array_get(const godot_array *p_self, const godot_int p_idx);
-
-godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot_int p_idx);
-
-const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value);
-
-void GDAPI godot_array_clear(godot_array *p_self);
-
-godot_int GDAPI godot_array_count(const godot_array *p_self, const godot_variant *p_value);
-
-godot_bool GDAPI godot_array_empty(const godot_array *p_self);
-
-void GDAPI godot_array_erase(godot_array *p_self, const godot_variant *p_value);
-
-godot_variant GDAPI godot_array_front(const godot_array *p_self);
-
-godot_variant GDAPI godot_array_back(const godot_array *p_self);
-
-godot_int GDAPI godot_array_find(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from);
-
-godot_int GDAPI godot_array_find_last(const godot_array *p_self, const godot_variant *p_what);
-
-godot_bool GDAPI godot_array_has(const godot_array *p_self, const godot_variant *p_value);
-
-godot_int GDAPI godot_array_hash(const godot_array *p_self);
-
-void GDAPI godot_array_insert(godot_array *p_self, const godot_int p_pos, const godot_variant *p_value);
-
-void GDAPI godot_array_invert(godot_array *p_self);
-
-godot_variant GDAPI godot_array_pop_back(godot_array *p_self);
-
-godot_variant GDAPI godot_array_pop_front(godot_array *p_self);
-
-void GDAPI godot_array_push_back(godot_array *p_self, const godot_variant *p_value);
-
-void GDAPI godot_array_push_front(godot_array *p_self, const godot_variant *p_value);
-
-void GDAPI godot_array_remove(godot_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_array_resize(godot_array *p_self, const godot_int p_size);
-
-godot_int GDAPI godot_array_rfind(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from);
-
-godot_int GDAPI godot_array_size(const godot_array *p_self);
-
-void GDAPI godot_array_sort(godot_array *p_self);
-
-void GDAPI godot_array_sort_custom(godot_array *p_self, godot_object *p_obj, const godot_string *p_func);
-
-godot_int GDAPI godot_array_bsearch(godot_array *p_self, const godot_variant *p_value, const godot_bool p_before);
-
-godot_int GDAPI godot_array_bsearch_custom(godot_array *p_self, const godot_variant *p_value, godot_object *p_obj, const godot_string *p_func, const godot_bool p_before);
-
+void GDAPI godot_array_new(godot_array *p_self);
void GDAPI godot_array_destroy(godot_array *p_self);
-
-godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep);
-
-godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_step, const godot_bool p_deep);
-
-godot_variant GDAPI godot_array_max(const godot_array *p_self);
-
-godot_variant GDAPI godot_array_min(const godot_array *p_self);
-
-void GDAPI godot_array_shuffle(godot_array *p_self);
+godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, godot_int p_index);
+const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, godot_int p_index);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h
index c7425ebbfa..af8d7cbdd3 100644
--- a/modules/gdnative/include/gdnative/basis.h
+++ b/modules/gdnative/include/gdnative/basis.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,9 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_BASIS_SIZE 36
+#define GODOT_BASIS_SIZE (sizeof(godot_real_t) * 9)
#ifndef GODOT_CORE_API_GODOT_BASIS_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_BASIS_TYPE_DEFINED
@@ -46,88 +46,11 @@ typedef struct {
} godot_basis;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/quat.h>
-#include <gdnative/vector3.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis);
-void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi);
-void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler);
-void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler);
-
-godot_string GDAPI godot_basis_as_string(const godot_basis *p_self);
-
-godot_basis GDAPI godot_basis_inverse(const godot_basis *p_self);
-
-godot_basis GDAPI godot_basis_transposed(const godot_basis *p_self);
-
-godot_basis GDAPI godot_basis_orthonormalized(const godot_basis *p_self);
-
-godot_real GDAPI godot_basis_determinant(const godot_basis *p_self);
-
-godot_basis GDAPI godot_basis_rotated(const godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_phi);
-
-godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vector3 *p_scale);
-
-godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self);
-
-godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self);
-
-godot_quat GDAPI godot_basis_get_quat(const godot_basis *p_self);
-
-void GDAPI godot_basis_set_quat(godot_basis *p_self, const godot_quat *p_quat);
-
-void GDAPI godot_basis_set_axis_angle_scale(godot_basis *p_self, const godot_vector3 *p_axis, godot_real p_phi, const godot_vector3 *p_scale);
-
-void GDAPI godot_basis_set_euler_scale(godot_basis *p_self, const godot_vector3 *p_euler, const godot_vector3 *p_scale);
-
-void GDAPI godot_basis_set_quat_scale(godot_basis *p_self, const godot_quat *p_quat, const godot_vector3 *p_scale);
-
-godot_real GDAPI godot_basis_tdotx(const godot_basis *p_self, const godot_vector3 *p_with);
-
-godot_real GDAPI godot_basis_tdoty(const godot_basis *p_self, const godot_vector3 *p_with);
-
-godot_real GDAPI godot_basis_tdotz(const godot_basis *p_self, const godot_vector3 *p_with);
-
-godot_vector3 GDAPI godot_basis_xform(const godot_basis *p_self, const godot_vector3 *p_v);
-
-godot_vector3 GDAPI godot_basis_xform_inv(const godot_basis *p_self, const godot_vector3 *p_v);
-
-godot_int GDAPI godot_basis_get_orthogonal_index(const godot_basis *p_self);
-
-void GDAPI godot_basis_new(godot_basis *r_dest);
-
-// p_elements is a pointer to an array of 3 (!!) vector3
-void GDAPI godot_basis_get_elements(const godot_basis *p_self, godot_vector3 *p_elements);
-
-godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_self, const godot_int p_axis);
-
-void GDAPI godot_basis_set_axis(godot_basis *p_self, const godot_int p_axis, const godot_vector3 *p_value);
-
-godot_vector3 GDAPI godot_basis_get_row(const godot_basis *p_self, const godot_int p_row);
-
-void GDAPI godot_basis_set_row(godot_basis *p_self, const godot_int p_row, const godot_vector3 *p_value);
-
-godot_bool GDAPI godot_basis_operator_equal(const godot_basis *p_self, const godot_basis *p_b);
-
-godot_basis GDAPI godot_basis_operator_add(const godot_basis *p_self, const godot_basis *p_b);
-
-godot_basis GDAPI godot_basis_operator_subtract(const godot_basis *p_self, const godot_basis *p_b);
-
-godot_basis GDAPI godot_basis_operator_multiply_vector(const godot_basis *p_self, const godot_basis *p_b);
-
-godot_basis GDAPI godot_basis_operator_multiply_scalar(const godot_basis *p_self, const godot_real p_b);
-godot_basis GDAPI godot_basis_slerp(const godot_basis *p_self, const godot_basis *p_b, const godot_real p_t);
+void GDAPI godot_basis_new(godot_basis *p_self);
+godot_vector3 GDAPI *godot_basis_operator_index(godot_basis *p_self, godot_int p_index);
+const godot_vector3 GDAPI *godot_basis_operator_index_const(const godot_basis *p_self, godot_int p_index);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/callable.h b/modules/gdnative/include/gdnative/callable.h
index dbb5d02590..6f359ada5e 100644
--- a/modules/gdnative/include/gdnative/callable.h
+++ b/modules/gdnative/include/gdnative/callable.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,79 +46,11 @@ typedef struct {
} godot_callable;
#endif
-#define GODOT_SIGNAL_SIZE (16)
-
-#ifndef GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED
-typedef struct {
- uint8_t _dont_touch_that[GODOT_SIGNAL_SIZE];
-} godot_signal;
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/string_name.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Callable
-
-void GDAPI godot_callable_new_with_object(godot_callable *r_dest, const godot_object *p_object, const godot_string_name *p_method);
-void GDAPI godot_callable_new_with_object_id(godot_callable *r_dest, uint64_t p_objectid, const godot_string_name *p_method);
-void GDAPI godot_callable_new_copy(godot_callable *r_dest, const godot_callable *p_src);
+void GDAPI godot_callable_new(godot_callable *p_self);
void GDAPI godot_callable_destroy(godot_callable *p_self);
-godot_int GDAPI godot_callable_call(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount, godot_variant *r_return_value);
-void GDAPI godot_callable_call_deferred(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount);
-
-godot_bool GDAPI godot_callable_is_null(const godot_callable *p_self);
-godot_bool GDAPI godot_callable_is_custom(const godot_callable *p_self);
-godot_bool GDAPI godot_callable_is_standard(const godot_callable *p_self);
-
-godot_object GDAPI *godot_callable_get_object(const godot_callable *p_self);
-uint64_t GDAPI godot_callable_get_object_id(const godot_callable *p_self);
-godot_string_name GDAPI godot_callable_get_method(const godot_callable *p_self);
-
-uint32_t GDAPI godot_callable_hash(const godot_callable *p_self);
-
-godot_string GDAPI godot_callable_as_string(const godot_callable *p_self);
-
-godot_bool GDAPI godot_callable_operator_equal(const godot_callable *p_self, const godot_callable *p_other);
-godot_bool GDAPI godot_callable_operator_less(const godot_callable *p_self, const godot_callable *p_other);
-
-// Signal
-
-void GDAPI godot_signal_new_with_object(godot_signal *r_dest, const godot_object *p_object, const godot_string_name *p_name);
-void GDAPI godot_signal_new_with_object_id(godot_signal *r_dest, uint64_t p_objectid, const godot_string_name *p_name);
-void GDAPI godot_signal_new_copy(godot_signal *r_dest, const godot_signal *p_src);
-
-void GDAPI godot_signal_destroy(godot_signal *p_self);
-
-godot_int GDAPI godot_signal_emit(const godot_signal *p_self, const godot_variant **p_arguments, godot_int p_argcount);
-
-godot_int GDAPI godot_signal_connect(godot_signal *p_self, const godot_callable *p_callable, const godot_array *p_binds, uint32_t p_flags);
-void GDAPI godot_signal_disconnect(godot_signal *p_self, const godot_callable *p_callable);
-
-godot_bool GDAPI godot_signal_is_null(const godot_signal *p_self);
-godot_bool GDAPI godot_signal_is_connected(const godot_signal *p_self, const godot_callable *p_callable);
-
-godot_array GDAPI godot_signal_get_connections(const godot_signal *p_self);
-
-godot_object GDAPI *godot_signal_get_object(const godot_signal *p_self);
-uint64_t GDAPI godot_signal_get_object_id(const godot_signal *p_self);
-godot_string_name GDAPI godot_signal_get_name(const godot_signal *p_self);
-
-godot_string GDAPI godot_signal_as_string(const godot_signal *p_self);
-
-godot_bool GDAPI godot_signal_operator_equal(const godot_signal *p_self, const godot_signal *p_other);
-godot_bool GDAPI godot_signal_operator_less(const godot_signal *p_self, const godot_signal *p_other);
-
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h
index e64097ef57..17a021e6ea 100644
--- a/modules/gdnative/include/gdnative/color.h
+++ b/modules/gdnative/include/gdnative/color.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,10 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_COLOR_SIZE 16
+// Colors should always use 32-bit floats, so don't use real_t here.
+#define GODOT_COLOR_SIZE (sizeof(float) * 4)
#ifndef GODOT_CORE_API_GODOT_COLOR_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_COLOR_TYPE_DEFINED
@@ -46,68 +47,11 @@ typedef struct {
} godot_color;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a);
-void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b);
-
-godot_real godot_color_get_r(const godot_color *p_self);
-void godot_color_set_r(godot_color *p_self, const godot_real r);
-
-godot_real godot_color_get_g(const godot_color *p_self);
-void godot_color_set_g(godot_color *p_self, const godot_real g);
-
-godot_real godot_color_get_b(const godot_color *p_self);
-void godot_color_set_b(godot_color *p_self, const godot_real b);
-
-godot_real godot_color_get_a(const godot_color *p_self);
-void godot_color_set_a(godot_color *p_self, const godot_real a);
-
-godot_real godot_color_get_h(const godot_color *p_self);
-godot_real godot_color_get_s(const godot_color *p_self);
-godot_real godot_color_get_v(const godot_color *p_self);
-
-godot_string GDAPI godot_color_as_string(const godot_color *p_self);
-
-godot_int GDAPI godot_color_to_rgba32(const godot_color *p_self);
-
-godot_int GDAPI godot_color_to_abgr32(const godot_color *p_self);
-
-godot_int GDAPI godot_color_to_abgr64(const godot_color *p_self);
-
-godot_int GDAPI godot_color_to_argb64(const godot_color *p_self);
-
-godot_int GDAPI godot_color_to_rgba64(const godot_color *p_self);
-
-godot_int GDAPI godot_color_to_argb32(const godot_color *p_self);
-
-godot_color GDAPI godot_color_inverted(const godot_color *p_self);
-
-godot_color GDAPI godot_color_lerp(const godot_color *p_self, const godot_color *p_b, const godot_real p_t);
-
-godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over);
-
-godot_color GDAPI godot_color_darkened(const godot_color *p_self, const godot_real p_amount);
-
-godot_color GDAPI godot_color_from_hsv(const godot_color *p_self, const godot_real p_h, const godot_real p_s, const godot_real p_v, const godot_real p_a);
-
-godot_color GDAPI godot_color_lightened(const godot_color *p_self, const godot_real p_amount);
-
-godot_string GDAPI godot_color_to_html(const godot_color *p_self, const godot_bool p_with_alpha);
-
-godot_bool GDAPI godot_color_operator_equal(const godot_color *p_self, const godot_color *p_b);
-godot_bool GDAPI godot_color_operator_less(const godot_color *p_self, const godot_color *p_b);
+void GDAPI godot_color_new(godot_color *p_self);
+float GDAPI *godot_color_operator_index(godot_color *p_self, godot_int p_index);
+const float GDAPI *godot_color_operator_index_const(const godot_color *p_self, godot_int p_index);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h
index 873efaa9bf..d2afbc4c94 100644
--- a/modules/gdnative/include/gdnative/dictionary.h
+++ b/modules/gdnative/include/gdnative/dictionary.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,62 +46,14 @@ typedef struct {
} godot_dictionary;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
-#include <gdnative/array.h>
#include <gdnative/gdnative.h>
-#include <gdnative/variant.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <gdnative/variant_struct.h>
-void GDAPI godot_dictionary_new(godot_dictionary *r_dest);
-void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src);
+void GDAPI godot_dictionary_new(godot_dictionary *p_self);
void GDAPI godot_dictionary_destroy(godot_dictionary *p_self);
-
-godot_dictionary GDAPI godot_dictionary_duplicate(const godot_dictionary *p_self, const godot_bool p_deep);
-
-godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_self);
-
-godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_self);
-
-void GDAPI godot_dictionary_clear(godot_dictionary *p_self);
-
-godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_self, const godot_variant *p_key);
-
-godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_self, const godot_array *p_keys);
-
-void GDAPI godot_dictionary_erase(godot_dictionary *p_self, const godot_variant *p_key);
-
-godot_int GDAPI godot_dictionary_hash(const godot_dictionary *p_self);
-
-godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_self);
-
-godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_self);
-
-godot_variant GDAPI godot_dictionary_get(const godot_dictionary *p_self, const godot_variant *p_key);
-void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_value);
-
godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key);
-
const godot_variant GDAPI *godot_dictionary_operator_index_const(const godot_dictionary *p_self, const godot_variant *p_key);
-godot_variant GDAPI *godot_dictionary_next(const godot_dictionary *p_self, const godot_variant *p_key);
-
-godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b);
-
-godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self);
-
-// GDNative core 1.1
-
-godot_bool GDAPI godot_dictionary_erase_with_return(godot_dictionary *p_self, const godot_variant *p_key);
-
-godot_variant GDAPI godot_dictionary_get_with_default(const godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_default);
-
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 7ceb4fb81c..9af9226a79 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,8 +64,6 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
-#define GODOT_API_VERSION 1
-
////// Error
typedef enum {
@@ -120,21 +118,6 @@ typedef enum {
GODOT_ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames
} godot_error;
-////// bool
-
-typedef bool godot_bool;
-
-#define GODOT_TRUE 1
-#define GODOT_FALSE 0
-
-/////// int
-
-typedef int64_t godot_int;
-
-/////// real
-
-typedef float godot_real;
-
/////// Object (forward declared)
typedef void godot_object;
@@ -217,7 +200,7 @@ void GDAPI godot_object_destroy(godot_object *p_o);
////// Singleton API
-godot_object GDAPI *godot_global_get_singleton(char *p_name); // result shouldn't be freed
+godot_object GDAPI *godot_global_get_singleton(char *p_name); // Result shouldn't be freed.
////// MethodBind API
@@ -283,12 +266,10 @@ void GDAPI *godot_alloc(int p_bytes);
void GDAPI *godot_realloc(void *p_ptr, int p_bytes);
void GDAPI godot_free(void *p_ptr);
-//print using Godot's error handler list
+// Helper print functions.
void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line);
void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line);
-void GDAPI godot_print(const godot_string *p_message);
-
-// GDNATIVE CORE 1.0.2?
+void GDAPI godot_print_script_error(const char *p_description, const char *p_function, const char *p_file, int p_line);
//tags used for safe dynamic casting
void GDAPI *godot_get_class_tag(const godot_string_name *p_class);
@@ -303,4 +284,4 @@ uint64_t GDAPI godot_object_get_instance_id(const godot_object *p_object);
}
#endif
-#endif // GODOT_C_H
+#endif // GODOT_GDNATIVE_H
diff --git a/modules/gdnative/include/gdnative/math_defs.h b/modules/gdnative/include/gdnative/math_defs.h
new file mode 100644
index 0000000000..b5cf389506
--- /dev/null
+++ b/modules/gdnative/include/gdnative/math_defs.h
@@ -0,0 +1,66 @@
+/*************************************************************************/
+/* math_defs.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GODOT_GDNATIVE_MATH_DEFS_H
+#define GODOT_GDNATIVE_MATH_DEFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+
+////// bool
+
+typedef bool godot_bool;
+
+#define GODOT_TRUE 1
+#define GODOT_FALSE 0
+
+/////// int
+
+typedef int64_t godot_int;
+
+/////// float
+
+typedef double godot_float;
+
+#ifdef REAL_T_IS_DOUBLE
+typedef double godot_real_t;
+#else
+typedef float godot_real_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_C_H
diff --git a/modules/gdnative/include/gdnative/node_path.h b/modules/gdnative/include/gdnative/node_path.h
index 0cd0c3cb9c..3c31b9a98f 100644
--- a/modules/gdnative/include/gdnative/node_path.h
+++ b/modules/gdnative/include/gdnative/node_path.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,42 +46,11 @@ typedef struct {
} godot_node_path;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/string.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from);
-void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src);
+void GDAPI godot_node_path_new(godot_node_path *p_self);
void GDAPI godot_node_path_destroy(godot_node_path *p_self);
-godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_self);
-
-godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_self);
-
-godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_self);
-
-godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_self);
-
-godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_self, const godot_int p_idx);
-
-godot_string GDAPI godot_node_path_get_concatenated_subnames(const godot_node_path *p_self);
-
-godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_self);
-
-godot_bool GDAPI godot_node_path_operator_equal(const godot_node_path *p_self, const godot_node_path *p_b);
-
-godot_node_path godot_node_path_get_as_property_path(const godot_node_path *p_self);
-
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/packed_arrays.h b/modules/gdnative/include/gdnative/packed_arrays.h
index ce9579f307..621ed60cdf 100644
--- a/modules/gdnative/include/gdnative/packed_arrays.h
+++ b/modules/gdnative/include/gdnative/packed_arrays.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -136,6 +136,17 @@ typedef struct {
} godot_packed_vector3_array;
#endif
+/////// PackedVector3iArray
+
+#define GODOT_PACKED_VECTOR3I_ARRAY_SIZE (2 * sizeof(void *))
+
+#ifndef GODOT_CORE_API_GODOT_PACKED_VECTOR3I_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_VECTOR3I_ARRAY_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_PACKED_VECTOR3I_ARRAY_SIZE];
+} godot_packed_vector3i_array;
+#endif
+
/////// PackedColorArray
#define GODOT_PACKED_COLOR_ARRAY_SIZE (2 * sizeof(void *))
@@ -147,384 +158,87 @@ typedef struct {
} godot_packed_color_array;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
-#include <gdnative/array.h>
-#include <gdnative/color.h>
-#include <gdnative/vector2.h>
-#include <gdnative/vector3.h>
-
#include <gdnative/gdnative.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// byte
-
-void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *r_dest);
-void GDAPI godot_packed_byte_array_new_copy(godot_packed_byte_array *r_dest, const godot_packed_byte_array *p_src);
-void GDAPI godot_packed_byte_array_new_with_array(godot_packed_byte_array *r_dest, const godot_array *p_a);
-
-const uint8_t GDAPI *godot_packed_byte_array_ptr(const godot_packed_byte_array *p_self);
-uint8_t GDAPI *godot_packed_byte_array_ptrw(godot_packed_byte_array *p_self);
-
-void GDAPI godot_packed_byte_array_append(godot_packed_byte_array *p_self, const uint8_t p_data);
-
-void GDAPI godot_packed_byte_array_append_array(godot_packed_byte_array *p_self, const godot_packed_byte_array *p_array);
-
-godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
-
-godot_bool GDAPI godot_packed_byte_array_has(godot_packed_byte_array *p_self, const uint8_t p_value);
-
-void GDAPI godot_packed_byte_array_sort(godot_packed_byte_array *p_self);
-
-void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self);
-
-void GDAPI godot_packed_byte_array_push_back(godot_packed_byte_array *p_self, const uint8_t p_data);
-
-void GDAPI godot_packed_byte_array_remove(godot_packed_byte_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_byte_array_resize(godot_packed_byte_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_byte_array_set(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
-uint8_t GDAPI godot_packed_byte_array_get(const godot_packed_byte_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_byte_array_size(const godot_packed_byte_array *p_self);
-
-godot_bool GDAPI godot_packed_byte_array_empty(const godot_packed_byte_array *p_self);
+// Byte.
+void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *p_self);
void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self);
+uint8_t GDAPI *godot_packed_byte_array_operator_index(godot_packed_byte_array *p_self, godot_int p_index);
+const uint8_t GDAPI *godot_packed_byte_array_operator_index_const(const godot_packed_byte_array *p_self, godot_int p_index);
-// int32
-
-void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *r_dest);
-void GDAPI godot_packed_int32_array_new_copy(godot_packed_int32_array *r_dest, const godot_packed_int32_array *p_src);
-void GDAPI godot_packed_int32_array_new_with_array(godot_packed_int32_array *r_dest, const godot_array *p_a);
-
-const int32_t GDAPI *godot_packed_int32_array_ptr(const godot_packed_int32_array *p_self);
-int32_t GDAPI *godot_packed_int32_array_ptrw(godot_packed_int32_array *p_self);
-
-void GDAPI godot_packed_int32_array_append(godot_packed_int32_array *p_self, const int32_t p_data);
-
-void GDAPI godot_packed_int32_array_append_array(godot_packed_int32_array *p_self, const godot_packed_int32_array *p_array);
-
-godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data);
-
-godot_bool GDAPI godot_packed_int32_array_has(godot_packed_int32_array *p_self, const int32_t p_value);
-
-void GDAPI godot_packed_int32_array_sort(godot_packed_int32_array *p_self);
-
-void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self);
-
-void GDAPI godot_packed_int32_array_push_back(godot_packed_int32_array *p_self, const int32_t p_data);
-
-void GDAPI godot_packed_int32_array_remove(godot_packed_int32_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_int32_array_resize(godot_packed_int32_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_int32_array_set(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data);
-int32_t GDAPI godot_packed_int32_array_get(const godot_packed_int32_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_int32_array_size(const godot_packed_int32_array *p_self);
-
-godot_bool GDAPI godot_packed_int32_array_empty(const godot_packed_int32_array *p_self);
+// Int32.
+void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *p_self);
void GDAPI godot_packed_int32_array_destroy(godot_packed_int32_array *p_self);
+int32_t GDAPI *godot_packed_int32_array_operator_index(godot_packed_int32_array *p_self, godot_int p_index);
+const int32_t GDAPI *godot_packed_int32_array_operator_index_const(const godot_packed_int32_array *p_self, godot_int p_index);
-// int64
-
-void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *r_dest);
-void GDAPI godot_packed_int64_array_new_copy(godot_packed_int64_array *r_dest, const godot_packed_int64_array *p_src);
-void GDAPI godot_packed_int64_array_new_with_array(godot_packed_int64_array *r_dest, const godot_array *p_a);
-
-const int64_t GDAPI *godot_packed_int64_array_ptr(const godot_packed_int64_array *p_self);
-int64_t GDAPI *godot_packed_int64_array_ptrw(godot_packed_int64_array *p_self);
-
-void GDAPI godot_packed_int64_array_append(godot_packed_int64_array *p_self, const int64_t p_data);
-
-void GDAPI godot_packed_int64_array_append_array(godot_packed_int64_array *p_self, const godot_packed_int64_array *p_array);
-
-godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data);
-
-godot_bool GDAPI godot_packed_int64_array_has(godot_packed_int64_array *p_self, const int64_t p_value);
-
-void GDAPI godot_packed_int64_array_sort(godot_packed_int64_array *p_self);
-
-void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self);
-
-void GDAPI godot_packed_int64_array_push_back(godot_packed_int64_array *p_self, const int64_t p_data);
-
-void GDAPI godot_packed_int64_array_remove(godot_packed_int64_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_int64_array_resize(godot_packed_int64_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_int64_array_set(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data);
-int64_t GDAPI godot_packed_int64_array_get(const godot_packed_int64_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_int64_array_size(const godot_packed_int64_array *p_self);
-
-godot_bool GDAPI godot_packed_int64_array_empty(const godot_packed_int64_array *p_self);
+// Int64.
+void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *p_self);
void GDAPI godot_packed_int64_array_destroy(godot_packed_int64_array *p_self);
+int64_t GDAPI *godot_packed_int64_array_operator_index(godot_packed_int64_array *p_self, godot_int p_index);
+const int64_t GDAPI *godot_packed_int64_array_operator_index_const(const godot_packed_int64_array *p_self, godot_int p_index);
-// float32
-
-void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *r_dest);
-void GDAPI godot_packed_float32_array_new_copy(godot_packed_float32_array *r_dest, const godot_packed_float32_array *p_src);
-void GDAPI godot_packed_float32_array_new_with_array(godot_packed_float32_array *r_dest, const godot_array *p_a);
-
-const float GDAPI *godot_packed_float32_array_ptr(const godot_packed_float32_array *p_self);
-float GDAPI *godot_packed_float32_array_ptrw(godot_packed_float32_array *p_self);
-
-void GDAPI godot_packed_float32_array_append(godot_packed_float32_array *p_self, const float p_data);
-
-void GDAPI godot_packed_float32_array_append_array(godot_packed_float32_array *p_self, const godot_packed_float32_array *p_array);
-
-godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data);
-
-godot_bool GDAPI godot_packed_float32_array_has(godot_packed_float32_array *p_self, const float p_value);
-
-void GDAPI godot_packed_float32_array_sort(godot_packed_float32_array *p_self);
-
-void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self);
-
-void GDAPI godot_packed_float32_array_push_back(godot_packed_float32_array *p_self, const float p_data);
-
-void GDAPI godot_packed_float32_array_remove(godot_packed_float32_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_float32_array_resize(godot_packed_float32_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_float32_array_set(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data);
-float GDAPI godot_packed_float32_array_get(const godot_packed_float32_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_float32_array_size(const godot_packed_float32_array *p_self);
-
-godot_bool GDAPI godot_packed_float32_array_empty(const godot_packed_float32_array *p_self);
+// Float32.
+void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *p_self);
void GDAPI godot_packed_float32_array_destroy(godot_packed_float32_array *p_self);
+float GDAPI *godot_packed_float32_array_operator_index(godot_packed_float32_array *p_self, godot_int p_index);
+const float GDAPI *godot_packed_float32_array_operator_index_const(const godot_packed_float32_array *p_self, godot_int p_index);
-// float64
-
-void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *r_dest);
-void GDAPI godot_packed_float64_array_new_copy(godot_packed_float64_array *r_dest, const godot_packed_float64_array *p_src);
-void GDAPI godot_packed_float64_array_new_with_array(godot_packed_float64_array *r_dest, const godot_array *p_a);
-
-const double GDAPI *godot_packed_float64_array_ptr(const godot_packed_float64_array *p_self);
-double GDAPI *godot_packed_float64_array_ptrw(godot_packed_float64_array *p_self);
-
-void GDAPI godot_packed_float64_array_append(godot_packed_float64_array *p_self, const double p_data);
-
-void GDAPI godot_packed_float64_array_append_array(godot_packed_float64_array *p_self, const godot_packed_float64_array *p_array);
-
-godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data);
-
-godot_bool GDAPI godot_packed_float64_array_has(godot_packed_float64_array *p_self, const double p_value);
-
-void GDAPI godot_packed_float64_array_sort(godot_packed_float64_array *p_self);
-
-void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self);
-
-void GDAPI godot_packed_float64_array_push_back(godot_packed_float64_array *p_self, const double p_data);
-
-void GDAPI godot_packed_float64_array_remove(godot_packed_float64_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_float64_array_resize(godot_packed_float64_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_float64_array_set(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data);
-double GDAPI godot_packed_float64_array_get(const godot_packed_float64_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_float64_array_size(const godot_packed_float64_array *p_self);
-
-godot_bool GDAPI godot_packed_float64_array_empty(const godot_packed_float64_array *p_self);
+// Float64.
+void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *p_self);
void GDAPI godot_packed_float64_array_destroy(godot_packed_float64_array *p_self);
+double GDAPI *godot_packed_float64_array_operator_index(godot_packed_float64_array *p_self, godot_int p_index);
+const double GDAPI *godot_packed_float64_array_operator_index_const(const godot_packed_float64_array *p_self, godot_int p_index);
-// string
-
-void GDAPI godot_packed_string_array_new(godot_packed_string_array *r_dest);
-void GDAPI godot_packed_string_array_new_copy(godot_packed_string_array *r_dest, const godot_packed_string_array *p_src);
-void GDAPI godot_packed_string_array_new_with_array(godot_packed_string_array *r_dest, const godot_array *p_a);
-
-const godot_string GDAPI *godot_packed_string_array_ptr(const godot_packed_string_array *p_self);
-godot_string GDAPI *godot_packed_string_array_ptrw(godot_packed_string_array *p_self);
-
-void GDAPI godot_packed_string_array_append(godot_packed_string_array *p_self, const godot_string *p_data);
-
-void GDAPI godot_packed_string_array_append_array(godot_packed_string_array *p_self, const godot_packed_string_array *p_array);
-
-godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
-
-godot_bool GDAPI godot_packed_string_array_has(godot_packed_string_array *p_self, const godot_string *p_value);
-
-void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self);
-
-void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self);
-
-void GDAPI godot_packed_string_array_push_back(godot_packed_string_array *p_self, const godot_string *p_data);
-
-void GDAPI godot_packed_string_array_remove(godot_packed_string_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_string_array_resize(godot_packed_string_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_string_array_set(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
-godot_string GDAPI godot_packed_string_array_get(const godot_packed_string_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_string_array_size(const godot_packed_string_array *p_self);
-
-godot_bool GDAPI godot_packed_string_array_empty(const godot_packed_string_array *p_self);
+// String.
+void GDAPI godot_packed_string_array_new(godot_packed_string_array *p_self);
void GDAPI godot_packed_string_array_destroy(godot_packed_string_array *p_self);
+godot_string GDAPI *godot_packed_string_array_operator_index(godot_packed_string_array *p_self, godot_int p_index);
+const godot_string GDAPI *godot_packed_string_array_operator_index_const(const godot_packed_string_array *p_self, godot_int p_index);
-// vector2
-
-void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *r_dest);
-void GDAPI godot_packed_vector2_array_new_copy(godot_packed_vector2_array *r_dest, const godot_packed_vector2_array *p_src);
-void GDAPI godot_packed_vector2_array_new_with_array(godot_packed_vector2_array *r_dest, const godot_array *p_a);
-
-const godot_vector2 GDAPI *godot_packed_vector2_array_ptr(const godot_packed_vector2_array *p_self);
-godot_vector2 GDAPI *godot_packed_vector2_array_ptrw(godot_packed_vector2_array *p_self);
-
-void GDAPI godot_packed_vector2_array_append(godot_packed_vector2_array *p_self, const godot_vector2 *p_data);
-
-void GDAPI godot_packed_vector2_array_append_array(godot_packed_vector2_array *p_self, const godot_packed_vector2_array *p_array);
-
-godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
-
-godot_bool GDAPI godot_packed_vector2_array_has(godot_packed_vector2_array *p_self, const godot_vector2 *p_value);
-
-void GDAPI godot_packed_vector2_array_sort(godot_packed_vector2_array *p_self);
-
-void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self);
-
-void GDAPI godot_packed_vector2_array_push_back(godot_packed_vector2_array *p_self, const godot_vector2 *p_data);
-
-void GDAPI godot_packed_vector2_array_remove(godot_packed_vector2_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_vector2_array_resize(godot_packed_vector2_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_vector2_array_set(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
-godot_vector2 GDAPI godot_packed_vector2_array_get(const godot_packed_vector2_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_vector2_array_size(const godot_packed_vector2_array *p_self);
-
-godot_bool GDAPI godot_packed_vector2_array_empty(const godot_packed_vector2_array *p_self);
+// Vector2.
+void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *p_self);
void GDAPI godot_packed_vector2_array_destroy(godot_packed_vector2_array *p_self);
+godot_vector2 GDAPI *godot_packed_vector2_array_operator_index(godot_packed_vector2_array *p_self, godot_int p_index);
+const godot_vector2 GDAPI *godot_packed_vector2_array_operator_index_const(const godot_packed_vector2_array *p_self, godot_int p_index);
-// vector2i
-
-void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *r_dest);
-void GDAPI godot_packed_vector2i_array_new_copy(godot_packed_vector2i_array *r_dest, const godot_packed_vector2i_array *p_src);
-void GDAPI godot_packed_vector2i_array_new_with_array(godot_packed_vector2i_array *r_dest, const godot_array *p_a);
-
-const godot_vector2i GDAPI *godot_packed_vector2i_array_ptr(const godot_packed_vector2i_array *p_self);
-godot_vector2i GDAPI *godot_packed_vector2i_array_ptrw(godot_packed_vector2i_array *p_self);
-
-void GDAPI godot_packed_vector2i_array_append(godot_packed_vector2i_array *p_self, const godot_vector2i *p_data);
-
-void GDAPI godot_packed_vector2i_array_append_array(godot_packed_vector2i_array *p_self, const godot_packed_vector2i_array *p_array);
-
-godot_error GDAPI godot_packed_vector2i_array_insert(godot_packed_vector2i_array *p_self, const godot_int p_idx, const godot_vector2i *p_data);
-
-godot_bool GDAPI godot_packed_vector2i_array_has(godot_packed_vector2i_array *p_self, const godot_vector2i *p_value);
-
-void GDAPI godot_packed_vector2i_array_sort(godot_packed_vector2i_array *p_self);
-
-void GDAPI godot_packed_vector2i_array_invert(godot_packed_vector2i_array *p_self);
-
-void GDAPI godot_packed_vector2i_array_push_back(godot_packed_vector2i_array *p_self, const godot_vector2i *p_data);
-
-void GDAPI godot_packed_vector2i_array_remove(godot_packed_vector2i_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_vector2i_array_resize(godot_packed_vector2i_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_vector2i_array_set(godot_packed_vector2i_array *p_self, const godot_int p_idx, const godot_vector2i *p_data);
-godot_vector2i GDAPI godot_packed_vector2i_array_get(const godot_packed_vector2i_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_vector2i_array_size(const godot_packed_vector2i_array *p_self);
-
-godot_bool GDAPI godot_packed_vector2i_array_empty(const godot_packed_vector2i_array *p_self);
+// Vector2i.
+void GDAPI godot_packed_vector2i_array_new(godot_packed_vector2i_array *p_self);
void GDAPI godot_packed_vector2i_array_destroy(godot_packed_vector2i_array *p_self);
+godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index(godot_packed_vector2i_array *p_self, godot_int p_index);
+const godot_vector2i GDAPI *godot_packed_vector2i_array_operator_index_const(const godot_packed_vector2i_array *p_self, godot_int p_index);
-// vector3
-
-void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *r_dest);
-void GDAPI godot_packed_vector3_array_new_copy(godot_packed_vector3_array *r_dest, const godot_packed_vector3_array *p_src);
-void GDAPI godot_packed_vector3_array_new_with_array(godot_packed_vector3_array *r_dest, const godot_array *p_a);
-
-const godot_vector3 GDAPI *godot_packed_vector3_array_ptr(const godot_packed_vector3_array *p_self);
-godot_vector3 GDAPI *godot_packed_vector3_array_ptrw(godot_packed_vector3_array *p_self);
-
-void GDAPI godot_packed_vector3_array_append(godot_packed_vector3_array *p_self, const godot_vector3 *p_data);
-
-void GDAPI godot_packed_vector3_array_append_array(godot_packed_vector3_array *p_self, const godot_packed_vector3_array *p_array);
-
-godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
-
-godot_bool GDAPI godot_packed_vector3_array_has(godot_packed_vector3_array *p_self, const godot_vector3 *p_value);
-
-void GDAPI godot_packed_vector3_array_sort(godot_packed_vector3_array *p_self);
-
-void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self);
-
-void GDAPI godot_packed_vector3_array_push_back(godot_packed_vector3_array *p_self, const godot_vector3 *p_data);
-
-void GDAPI godot_packed_vector3_array_remove(godot_packed_vector3_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_vector3_array_resize(godot_packed_vector3_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_vector3_array_set(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
-godot_vector3 GDAPI godot_packed_vector3_array_get(const godot_packed_vector3_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_packed_vector3_array_size(const godot_packed_vector3_array *p_self);
-
-godot_bool GDAPI godot_packed_vector3_array_empty(const godot_packed_vector3_array *p_self);
+// Vector3.
+void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *p_self);
void GDAPI godot_packed_vector3_array_destroy(godot_packed_vector3_array *p_self);
+godot_vector3 GDAPI *godot_packed_vector3_array_operator_index(godot_packed_vector3_array *p_self, godot_int p_index);
+const godot_vector3 GDAPI *godot_packed_vector3_array_operator_index_const(const godot_packed_vector3_array *p_self, godot_int p_index);
-// color
-
-void GDAPI godot_packed_color_array_new(godot_packed_color_array *r_dest);
-void GDAPI godot_packed_color_array_new_copy(godot_packed_color_array *r_dest, const godot_packed_color_array *p_src);
-void GDAPI godot_packed_color_array_new_with_array(godot_packed_color_array *r_dest, const godot_array *p_a);
-
-const godot_color GDAPI *godot_packed_color_array_ptr(const godot_packed_color_array *p_self);
-godot_color GDAPI *godot_packed_color_array_ptrw(godot_packed_color_array *p_self);
-
-void GDAPI godot_packed_color_array_append(godot_packed_color_array *p_self, const godot_color *p_data);
-
-void GDAPI godot_packed_color_array_append_array(godot_packed_color_array *p_self, const godot_packed_color_array *p_array);
-
-godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
-
-godot_bool GDAPI godot_packed_color_array_has(godot_packed_color_array *p_self, const godot_color *p_value);
-
-void GDAPI godot_packed_color_array_sort(godot_packed_color_array *p_self);
-
-void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self);
-
-void GDAPI godot_packed_color_array_push_back(godot_packed_color_array *p_self, const godot_color *p_data);
-
-void GDAPI godot_packed_color_array_remove(godot_packed_color_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_packed_color_array_resize(godot_packed_color_array *p_self, const godot_int p_size);
-
-void GDAPI godot_packed_color_array_set(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
-godot_color GDAPI godot_packed_color_array_get(const godot_packed_color_array *p_self, const godot_int p_idx);
+// Vector3i.
-godot_int GDAPI godot_packed_color_array_size(const godot_packed_color_array *p_self);
+void GDAPI godot_packed_vector3i_array_new(godot_packed_vector3i_array *p_self);
+void GDAPI godot_packed_vector3i_array_destroy(godot_packed_vector3i_array *p_self);
+godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index(godot_packed_vector3i_array *p_self, godot_int p_index);
+const godot_vector3i GDAPI *godot_packed_vector3i_array_operator_index_const(const godot_packed_vector3i_array *p_self, godot_int p_index);
-godot_bool GDAPI godot_packed_color_array_empty(const godot_packed_color_array *p_self);
+// Color.
+void GDAPI godot_packed_color_array_new(godot_packed_color_array *p_self);
void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self);
+godot_color GDAPI *godot_packed_color_array_operator_index(godot_packed_color_array *p_self, godot_int p_index);
+const godot_color GDAPI *godot_packed_color_array_operator_index_const(const godot_packed_color_array *p_self, godot_int p_index);
#ifdef __cplusplus
}
#endif
-#endif // GODOT_POOL_ARRAYS_H
+#endif // GODOT_PACKED_ARRAYS_H
diff --git a/modules/gdnative/include/gdnative/plane.h b/modules/gdnative/include/gdnative/plane.h
index 9843056489..ed10955e5f 100644
--- a/modules/gdnative/include/gdnative/plane.h
+++ b/modules/gdnative/include/gdnative/plane.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,9 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_PLANE_SIZE 16
+#define GODOT_PLANE_SIZE (sizeof(godot_real_t) * 4)
#ifndef GODOT_CORE_API_GODOT_PLANE_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_PLANE_TYPE_DEFINED
@@ -46,53 +46,9 @@ typedef struct {
} godot_plane;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/vector3.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d);
-void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3);
-void GDAPI godot_plane_new_with_normal(godot_plane *r_dest, const godot_vector3 *p_normal, const godot_real p_d);
-
-godot_string GDAPI godot_plane_as_string(const godot_plane *p_self);
-
-godot_plane GDAPI godot_plane_normalized(const godot_plane *p_self);
-
-godot_vector3 GDAPI godot_plane_center(const godot_plane *p_self);
-
-godot_bool GDAPI godot_plane_is_point_over(const godot_plane *p_self, const godot_vector3 *p_point);
-
-godot_real GDAPI godot_plane_distance_to(const godot_plane *p_self, const godot_vector3 *p_point);
-
-godot_bool GDAPI godot_plane_has_point(const godot_plane *p_self, const godot_vector3 *p_point, const godot_real p_epsilon);
-
-godot_vector3 GDAPI godot_plane_project(const godot_plane *p_self, const godot_vector3 *p_point);
-
-godot_bool GDAPI godot_plane_intersect_3(const godot_plane *p_self, godot_vector3 *r_dest, const godot_plane *p_b, const godot_plane *p_c);
-
-godot_bool GDAPI godot_plane_intersects_ray(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_from, const godot_vector3 *p_dir);
-
-godot_bool GDAPI godot_plane_intersects_segment(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_begin, const godot_vector3 *p_end);
-
-godot_plane GDAPI godot_plane_operator_neg(const godot_plane *p_self);
-
-godot_bool GDAPI godot_plane_operator_equal(const godot_plane *p_self, const godot_plane *p_b);
-
-void GDAPI godot_plane_set_normal(godot_plane *p_self, const godot_vector3 *p_normal);
-
-godot_vector3 GDAPI godot_plane_get_normal(const godot_plane *p_self);
-
-godot_real GDAPI godot_plane_get_d(const godot_plane *p_self);
-void GDAPI godot_plane_set_d(godot_plane *p_self, const godot_real p_d);
+void GDAPI godot_plane_new(godot_plane *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quat.h
index d315b2d754..69bf427611 100644
--- a/modules/gdnative/include/gdnative/quat.h
+++ b/modules/gdnative/include/gdnative/quat.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,9 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_QUAT_SIZE 16
+#define GODOT_QUAT_SIZE (sizeof(godot_real_t) * 4)
#ifndef GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED
@@ -46,70 +46,11 @@ typedef struct {
} godot_quat;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/vector3.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w);
-void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle);
-void GDAPI godot_quat_new_with_basis(godot_quat *r_dest, const godot_basis *p_basis);
-void GDAPI godot_quat_new_with_euler(godot_quat *r_dest, const godot_vector3 *p_euler);
-
-godot_real GDAPI godot_quat_get_x(const godot_quat *p_self);
-void GDAPI godot_quat_set_x(godot_quat *p_self, const godot_real val);
-
-godot_real GDAPI godot_quat_get_y(const godot_quat *p_self);
-void GDAPI godot_quat_set_y(godot_quat *p_self, const godot_real val);
-
-godot_real GDAPI godot_quat_get_z(const godot_quat *p_self);
-void GDAPI godot_quat_set_z(godot_quat *p_self, const godot_real val);
-
-godot_real GDAPI godot_quat_get_w(const godot_quat *p_self);
-void GDAPI godot_quat_set_w(godot_quat *p_self, const godot_real val);
-
-godot_string GDAPI godot_quat_as_string(const godot_quat *p_self);
-
-godot_real GDAPI godot_quat_length(const godot_quat *p_self);
-
-godot_real GDAPI godot_quat_length_squared(const godot_quat *p_self);
-
-godot_quat GDAPI godot_quat_normalized(const godot_quat *p_self);
-
-godot_bool GDAPI godot_quat_is_normalized(const godot_quat *p_self);
-
-godot_quat GDAPI godot_quat_inverse(const godot_quat *p_self);
-
-godot_real GDAPI godot_quat_dot(const godot_quat *p_self, const godot_quat *p_b);
-
-godot_vector3 GDAPI godot_quat_xform(const godot_quat *p_self, const godot_vector3 *p_v);
-
-godot_quat GDAPI godot_quat_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t);
-
-godot_quat GDAPI godot_quat_slerpni(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t);
-
-godot_quat GDAPI godot_quat_cubic_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_quat *p_pre_a, const godot_quat *p_post_b, const godot_real p_t);
-
-godot_quat GDAPI godot_quat_operator_multiply(const godot_quat *p_self, const godot_real p_b);
-
-godot_quat GDAPI godot_quat_operator_add(const godot_quat *p_self, const godot_quat *p_b);
-
-godot_quat GDAPI godot_quat_operator_subtract(const godot_quat *p_self, const godot_quat *p_b);
-
-godot_quat GDAPI godot_quat_operator_divide(const godot_quat *p_self, const godot_real p_b);
-
-godot_bool GDAPI godot_quat_operator_equal(const godot_quat *p_self, const godot_quat *p_b);
-
-godot_quat GDAPI godot_quat_operator_neg(const godot_quat *p_self);
-void GDAPI godot_quat_set_axis_angle(godot_quat *p_self, const godot_vector3 *p_axis, const godot_real p_angle);
+void GDAPI godot_quat_new(godot_quat *p_self);
+godot_real_t GDAPI *godot_quat_operator_index(godot_quat *p_self, godot_int p_index);
+const godot_real_t GDAPI *godot_quat_operator_index_const(const godot_quat *p_self, godot_int p_index);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/rect2.h b/modules/gdnative/include/gdnative/rect2.h
index 2c8f836d16..9e51254cfe 100644
--- a/modules/gdnative/include/gdnative/rect2.h
+++ b/modules/gdnative/include/gdnative/rect2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,119 +35,30 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
+
+#define GODOT_RECT2_SIZE (sizeof(godot_real_t) * 4)
#ifndef GODOT_CORE_API_GODOT_RECT2_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_RECT2_TYPE_DEFINED
typedef struct godot_rect2 {
- uint8_t _dont_touch_that[16];
+ uint8_t _dont_touch_that[GODOT_RECT2_SIZE];
} godot_rect2;
#endif
+#define GODOT_RECT2I_SIZE (sizeof(int32_t) * 4)
+
#ifndef GODOT_CORE_API_GODOT_RECT2I_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_RECT2I_TYPE_DEFINED
typedef struct godot_rect2i {
- uint8_t _dont_touch_that[16];
+ uint8_t _dont_touch_that[GODOT_RECT2I_SIZE];
} godot_rect2i;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/vector2.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Rect2
-
-void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size);
-void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height);
-
-godot_string GDAPI godot_rect2_as_string(const godot_rect2 *p_self);
-
-godot_rect2i GDAPI godot_rect2_as_rect2i(const godot_rect2 *p_self);
-
-godot_real GDAPI godot_rect2_get_area(const godot_rect2 *p_self);
-
-godot_bool GDAPI godot_rect2_intersects(const godot_rect2 *p_self, const godot_rect2 *p_b);
-
-godot_bool GDAPI godot_rect2_encloses(const godot_rect2 *p_self, const godot_rect2 *p_b);
-
-godot_bool GDAPI godot_rect2_has_no_area(const godot_rect2 *p_self);
-
-godot_rect2 GDAPI godot_rect2_intersection(const godot_rect2 *p_self, const godot_rect2 *p_b);
-
-godot_rect2 GDAPI godot_rect2_merge(const godot_rect2 *p_self, const godot_rect2 *p_b);
-
-godot_bool GDAPI godot_rect2_has_point(const godot_rect2 *p_self, const godot_vector2 *p_point);
-
-godot_rect2 GDAPI godot_rect2_grow(const godot_rect2 *p_self, const godot_real p_by);
-
-godot_rect2 GDAPI godot_rect2_grow_individual(const godot_rect2 *p_self, const godot_real p_left, const godot_real p_top, const godot_real p_right, const godot_real p_bottom);
-
-godot_rect2 GDAPI godot_rect2_grow_margin(const godot_rect2 *p_self, const godot_int p_margin, const godot_real p_by);
-
-godot_rect2 GDAPI godot_rect2_abs(const godot_rect2 *p_self);
-
-godot_rect2 GDAPI godot_rect2_expand(const godot_rect2 *p_self, const godot_vector2 *p_to);
-
-godot_bool GDAPI godot_rect2_operator_equal(const godot_rect2 *p_self, const godot_rect2 *p_b);
-
-godot_vector2 GDAPI godot_rect2_get_position(const godot_rect2 *p_self);
-
-godot_vector2 GDAPI godot_rect2_get_size(const godot_rect2 *p_self);
-
-void GDAPI godot_rect2_set_position(godot_rect2 *p_self, const godot_vector2 *p_pos);
-
-void GDAPI godot_rect2_set_size(godot_rect2 *p_self, const godot_vector2 *p_size);
-
-// Rect2I
-
-void GDAPI godot_rect2i_new_with_position_and_size(godot_rect2i *r_dest, const godot_vector2i *p_pos, const godot_vector2i *p_size);
-void GDAPI godot_rect2i_new(godot_rect2i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_width, const godot_int p_height);
-
-godot_string GDAPI godot_rect2i_as_string(const godot_rect2i *p_self);
-
-godot_rect2 GDAPI godot_rect2i_as_rect2(const godot_rect2i *p_self);
-
-godot_int GDAPI godot_rect2i_get_area(const godot_rect2i *p_self);
-
-godot_bool GDAPI godot_rect2i_intersects(const godot_rect2i *p_self, const godot_rect2i *p_b);
-
-godot_bool GDAPI godot_rect2i_encloses(const godot_rect2i *p_self, const godot_rect2i *p_b);
-
-godot_bool GDAPI godot_rect2i_has_no_area(const godot_rect2i *p_self);
-
-godot_rect2i GDAPI godot_rect2i_intersection(const godot_rect2i *p_self, const godot_rect2i *p_b);
-
-godot_rect2i GDAPI godot_rect2i_merge(const godot_rect2i *p_self, const godot_rect2i *p_b);
-
-godot_bool GDAPI godot_rect2i_has_point(const godot_rect2i *p_self, const godot_vector2i *p_point);
-
-godot_rect2i GDAPI godot_rect2i_grow(const godot_rect2i *p_self, const godot_int p_by);
-
-godot_rect2i GDAPI godot_rect2i_grow_individual(const godot_rect2i *p_self, const godot_int p_left, const godot_int p_top, const godot_int p_right, const godot_int p_bottom);
-
-godot_rect2i GDAPI godot_rect2i_grow_margin(const godot_rect2i *p_self, const godot_int p_margin, const godot_int p_by);
-
-godot_rect2i GDAPI godot_rect2i_abs(const godot_rect2i *p_self);
-
-godot_rect2i GDAPI godot_rect2i_expand(const godot_rect2i *p_self, const godot_vector2i *p_to);
-
-godot_bool GDAPI godot_rect2i_operator_equal(const godot_rect2i *p_self, const godot_rect2i *p_b);
-
-godot_vector2i GDAPI godot_rect2i_get_position(const godot_rect2i *p_self);
-
-godot_vector2i GDAPI godot_rect2i_get_size(const godot_rect2i *p_self);
-
-void GDAPI godot_rect2i_set_position(godot_rect2i *p_self, const godot_vector2i *p_pos);
-void GDAPI godot_rect2i_set_size(godot_rect2i *p_self, const godot_vector2i *p_size);
+void GDAPI godot_rect2_new(godot_rect2 *p_self);
+void GDAPI godot_rect2i_new(godot_rect2i *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/rid.h b/modules/gdnative/include/gdnative/rid.h
index 73b601dc04..7ea8cfd174 100644
--- a/modules/gdnative/include/gdnative/rid.h
+++ b/modules/gdnative/include/gdnative/rid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,26 +46,9 @@ typedef struct {
} godot_rid;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_rid_new(godot_rid *r_dest);
-
-godot_int GDAPI godot_rid_get_id(const godot_rid *p_self);
-
-void GDAPI godot_rid_new_with_resource(godot_rid *r_dest, const godot_object *p_from);
-
-godot_bool GDAPI godot_rid_operator_equal(const godot_rid *p_self, const godot_rid *p_b);
-
-godot_bool GDAPI godot_rid_operator_less(const godot_rid *p_self, const godot_rid *p_b);
+void GDAPI godot_rid_new(godot_rid *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/signal.h b/modules/gdnative/include/gdnative/signal.h
new file mode 100644
index 0000000000..ad84542677
--- /dev/null
+++ b/modules/gdnative/include/gdnative/signal.h
@@ -0,0 +1,58 @@
+/*************************************************************************/
+/* signal.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GODOT_SIGNAL_H
+#define GODOT_SIGNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define GODOT_SIGNAL_SIZE (16)
+
+#ifndef GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_SIGNAL_SIZE];
+} godot_signal;
+#endif
+
+#include <gdnative/gdnative.h>
+
+void GDAPI godot_signal_new(godot_signal *p_self);
+void GDAPI godot_signal_destroy(godot_signal *p_self);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index 6043351e84..10fbb2c078 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,61 +39,26 @@ extern "C" {
#include <stdint.h>
#ifndef __cplusplus
-typedef uint32_t char32_t;
typedef uint16_t char16_t;
+typedef uint32_t char32_t;
#endif
typedef char32_t godot_char_type;
#define GODOT_STRING_SIZE sizeof(void *)
-#define GODOT_CHAR_STRING_SIZE sizeof(void *)
-#define GODOT_CHAR16_STRING_SIZE sizeof(void *)
#ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
typedef struct {
uint8_t _dont_touch_that[GODOT_STRING_SIZE];
} godot_string;
-
-#endif
-
-#ifndef GODOT_CORE_API_GODOT_CHAR_STRING_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_CHAR_STRING_TYPE_DEFINED
-typedef struct {
- uint8_t _dont_touch_that[GODOT_CHAR_STRING_SIZE];
-} godot_char_string;
-#endif
-
-#ifndef GODOT_CORE_API_GODOT_CHAR16_STRING_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_CHAR16_STRING_TYPE_DEFINED
-typedef struct {
- uint8_t _dont_touch_that[GODOT_CHAR16_STRING_SIZE];
-} godot_char16_string;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
-#include <gdnative/array.h>
#include <gdnative/gdnative.h>
-#include <gdnative/variant.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs);
-const char GDAPI *godot_char_string_get_data(const godot_char_string *p_cs);
-void GDAPI godot_char_string_destroy(godot_char_string *p_cs);
-
-godot_int GDAPI godot_char16_string_length(const godot_char16_string *p_cs);
-const char16_t GDAPI *godot_char16_string_get_data(const godot_char16_string *p_cs);
-void GDAPI godot_char16_string_destroy(godot_char16_string *p_cs);
void GDAPI godot_string_new(godot_string *r_dest);
void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src);
+void GDAPI godot_string_destroy(godot_string *p_self);
void GDAPI godot_string_new_with_latin1_chars(godot_string *r_dest, const char *p_contents);
void GDAPI godot_string_new_with_utf8_chars(godot_string *r_dest, const char *p_contents);
@@ -107,198 +72,6 @@ void GDAPI godot_string_new_with_utf16_chars_and_len(godot_string *r_dest, const
void GDAPI godot_string_new_with_utf32_chars_and_len(godot_string *r_dest, const char32_t *p_contents, const int p_size);
void GDAPI godot_string_new_with_wide_chars_and_len(godot_string *r_dest, const wchar_t *p_contents, const int p_size);
-const godot_char_type GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx);
-godot_char_type GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx);
-const godot_char_type GDAPI *godot_string_get_data(const godot_string *p_self);
-
-godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b);
-godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b);
-godot_string GDAPI godot_string_operator_plus(const godot_string *p_self, const godot_string *p_b);
-
-/* Standard size stuff */
-
-/*+++*/ godot_int GDAPI godot_string_length(const godot_string *p_self);
-
-/* Helpers */
-
-signed char GDAPI godot_string_casecmp_to(const godot_string *p_self, const godot_string *p_str);
-signed char GDAPI godot_string_nocasecmp_to(const godot_string *p_self, const godot_string *p_str);
-signed char GDAPI godot_string_naturalnocasecmp_to(const godot_string *p_self, const godot_string *p_str);
-
-godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string);
-godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self, const char *p_char_array);
-godot_packed_string_array GDAPI godot_string_bigrams(const godot_string *p_self);
-godot_string GDAPI godot_string_chr(godot_char_type p_character);
-godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string);
-godot_bool GDAPI godot_string_ends_with_char_array(const godot_string *p_self, const char *p_char_array);
-godot_int GDAPI godot_string_count(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to);
-godot_int GDAPI godot_string_countn(const godot_string *p_self, const godot_string *p_what, godot_int p_from, godot_int p_to);
-godot_int GDAPI godot_string_find(const godot_string *p_self, const godot_string *p_what);
-godot_int GDAPI godot_string_find_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from);
-godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_packed_string_array *p_keys);
-godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from);
-godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_packed_string_array *p_keys, godot_int p_from, godot_int *r_key);
-godot_int GDAPI godot_string_findn(const godot_string *p_self, const godot_string *p_what);
-godot_int GDAPI godot_string_findn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from);
-godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values);
-godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder);
-godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len);
-godot_int GDAPI godot_string_hex_to_int(const godot_string *p_self);
-godot_int GDAPI godot_string_hex_to_int_with_prefix(const godot_string *p_self);
-godot_string GDAPI godot_string_insert(const godot_string *p_self, godot_int p_at_pos, const godot_string *p_string);
-godot_bool GDAPI godot_string_is_numeric(const godot_string *p_self);
-godot_bool GDAPI godot_string_is_subsequence_of(const godot_string *p_self, const godot_string *p_string);
-godot_bool GDAPI godot_string_is_subsequence_ofi(const godot_string *p_self, const godot_string *p_string);
-godot_string GDAPI godot_string_lpad(const godot_string *p_self, godot_int p_min_length);
-godot_string GDAPI godot_string_lpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character);
-godot_bool GDAPI godot_string_match(const godot_string *p_self, const godot_string *p_wildcard);
-godot_bool GDAPI godot_string_matchn(const godot_string *p_self, const godot_string *p_wildcard);
-godot_string GDAPI godot_string_md5(const uint8_t *p_md5);
-godot_string GDAPI godot_string_num(double p_num);
-godot_string GDAPI godot_string_num_int64(int64_t p_num, godot_int p_base);
-godot_string GDAPI godot_string_num_int64_capitalized(int64_t p_num, godot_int p_base, godot_bool p_capitalize_hex);
-godot_string GDAPI godot_string_num_real(double p_num);
-godot_string GDAPI godot_string_num_scientific(double p_num);
-godot_string GDAPI godot_string_num_with_decimals(double p_num, godot_int p_decimals);
-godot_string GDAPI godot_string_pad_decimals(const godot_string *p_self, godot_int p_digits);
-godot_string GDAPI godot_string_pad_zeros(const godot_string *p_self, godot_int p_digits);
-godot_string GDAPI godot_string_replace_first(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with);
-godot_string GDAPI godot_string_replace(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with);
-godot_string GDAPI godot_string_replacen(const godot_string *p_self, const godot_string *p_key, const godot_string *p_with);
-godot_int GDAPI godot_string_rfind(const godot_string *p_self, const godot_string *p_what);
-godot_int GDAPI godot_string_rfindn(const godot_string *p_self, const godot_string *p_what);
-godot_int GDAPI godot_string_rfind_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from);
-godot_int GDAPI godot_string_rfindn_from(const godot_string *p_self, const godot_string *p_what, godot_int p_from);
-godot_string GDAPI godot_string_rpad(const godot_string *p_self, godot_int p_min_length);
-godot_string GDAPI godot_string_rpad_with_custom_character(const godot_string *p_self, godot_int p_min_length, const godot_string *p_character);
-godot_real GDAPI godot_string_similarity(const godot_string *p_self, const godot_string *p_string);
-godot_string GDAPI godot_string_sprintf(const godot_string *p_self, const godot_array *p_values, godot_bool *p_error);
-godot_string GDAPI godot_string_substr(const godot_string *p_self, godot_int p_from, godot_int p_chars);
-double GDAPI godot_string_to_float(const godot_string *p_self);
-godot_int GDAPI godot_string_to_int(const godot_string *p_self);
-
-godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_self);
-godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_string *p_self);
-godot_string GDAPI godot_string_capitalize(const godot_string *p_self);
-
-double GDAPI godot_string_char_to_float(const char *p_what);
-double GDAPI godot_string_wchar_to_float(const wchar_t *p_str, const wchar_t **r_end);
-
-godot_int GDAPI godot_string_char_to_int(const char *p_what);
-godot_int GDAPI godot_string_wchar_to_int(const wchar_t *p_str);
-
-godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int p_len);
-godot_int GDAPI godot_string_wchar_to_int_with_len(const wchar_t *p_str, int p_len);
-
-godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, const godot_string *p_splitter);
-godot_string GDAPI godot_string_get_slice(const godot_string *p_self, const godot_string *p_splitter, godot_int p_slice);
-godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, godot_char_type p_splitter, godot_int p_slice);
-
-godot_packed_string_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter);
-godot_packed_string_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
-godot_packed_string_array GDAPI godot_string_split_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit);
-
-godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_splitter);
-godot_packed_string_array GDAPI godot_string_rsplit_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
-godot_packed_string_array GDAPI godot_string_rsplit_with_maxsplit(const godot_string *p_self, const godot_string *p_splitter, const godot_bool p_allow_empty, const godot_int p_maxsplit);
-
-godot_packed_float32_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter);
-godot_packed_float32_array GDAPI godot_string_split_floats_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
-godot_packed_float32_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters);
-godot_packed_float32_array GDAPI godot_string_split_floats_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters);
-godot_packed_int32_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter);
-godot_packed_int32_array GDAPI godot_string_split_ints_allow_empty(const godot_string *p_self, const godot_string *p_splitter);
-godot_packed_int32_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_packed_string_array *p_splitters);
-godot_packed_int32_array GDAPI godot_string_split_ints_mk_allow_empty(const godot_string *p_self, const godot_packed_string_array *p_splitters);
-
-godot_packed_string_array GDAPI godot_string_split_spaces(const godot_string *p_self);
-
-godot_char_type GDAPI godot_string_char_lowercase(godot_char_type p_char);
-godot_char_type GDAPI godot_string_char_uppercase(godot_char_type p_char);
-godot_string GDAPI godot_string_to_lower(const godot_string *p_self);
-godot_string GDAPI godot_string_to_upper(const godot_string *p_self);
-
-godot_string GDAPI godot_string_get_basename(const godot_string *p_self);
-godot_string GDAPI godot_string_get_extension(const godot_string *p_self);
-godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos);
-godot_char_type GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx);
-godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godot_string *p_file);
-godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_pos);
-godot_string GDAPI godot_string_repeat(const godot_string *p_self, godot_int p_count);
-godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right);
-godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self);
-
-void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars);
-
-godot_char_string GDAPI godot_string_ascii(const godot_string *p_self);
-godot_char_string GDAPI godot_string_latin1(const godot_string *p_self);
-
-godot_char_string GDAPI godot_string_utf8(const godot_string *p_self);
-godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8);
-godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len);
-
-godot_char16_string GDAPI godot_string_utf16(const godot_string *p_self);
-godot_bool GDAPI godot_string_parse_utf16(godot_string *p_self, const char16_t *p_utf16);
-godot_bool GDAPI godot_string_parse_utf16_with_len(godot_string *p_self, const char16_t *p_utf16, godot_int p_len);
-
-uint32_t GDAPI godot_string_hash(const godot_string *p_self);
-uint64_t GDAPI godot_string_hash64(const godot_string *p_self);
-
-uint32_t GDAPI godot_string_hash_chars(const char *p_cstr);
-uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len);
-uint32_t GDAPI godot_string_hash_wide_chars(const wchar_t *p_str);
-uint32_t GDAPI godot_string_hash_wide_chars_with_len(const wchar_t *p_str, godot_int p_len);
-
-godot_packed_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self);
-godot_string GDAPI godot_string_md5_text(const godot_string *p_self);
-godot_packed_byte_array GDAPI godot_string_sha1_buffer(const godot_string *p_self);
-godot_string GDAPI godot_string_sha1_text(const godot_string *p_self);
-godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self);
-godot_string GDAPI godot_string_sha256_text(const godot_string *p_self);
-
-godot_bool godot_string_empty(const godot_string *p_self);
-
-// path functions
-godot_string GDAPI godot_string_get_base_dir(const godot_string *p_self);
-godot_string GDAPI godot_string_get_file(const godot_string *p_self);
-godot_string GDAPI godot_string_humanize_size(size_t p_size);
-godot_bool GDAPI godot_string_is_abs_path(const godot_string *p_self);
-godot_bool GDAPI godot_string_is_rel_path(const godot_string *p_self);
-godot_bool GDAPI godot_string_is_resource_file(const godot_string *p_self);
-godot_string GDAPI godot_string_path_to(const godot_string *p_self, const godot_string *p_path);
-godot_string GDAPI godot_string_path_to_file(const godot_string *p_self, const godot_string *p_path);
-godot_string GDAPI godot_string_simplify_path(const godot_string *p_self);
-
-godot_string GDAPI godot_string_c_escape(const godot_string *p_self);
-godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self);
-godot_string GDAPI godot_string_c_unescape(const godot_string *p_self);
-godot_string GDAPI godot_string_http_escape(const godot_string *p_self);
-godot_string GDAPI godot_string_http_unescape(const godot_string *p_self);
-godot_string GDAPI godot_string_json_escape(const godot_string *p_self);
-godot_string GDAPI godot_string_xml_escape(const godot_string *p_self);
-godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self);
-godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self);
-
-godot_string GDAPI godot_string_percent_decode(const godot_string *p_self);
-godot_string GDAPI godot_string_percent_encode(const godot_string *p_self);
-godot_string GDAPI godot_string_join(const godot_string *p_self, const godot_packed_string_array *p_parts);
-
-godot_bool GDAPI godot_string_is_valid_filename(const godot_string *p_self);
-godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self);
-godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix);
-godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self);
-godot_bool GDAPI godot_string_is_valid_identifier(const godot_string *p_self);
-godot_bool GDAPI godot_string_is_valid_integer(const godot_string *p_self);
-godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self);
-
-godot_string GDAPI godot_string_dedent(const godot_string *p_self);
-godot_string GDAPI godot_string_trim_prefix(const godot_string *p_self, const godot_string *p_prefix);
-godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const godot_string *p_suffix);
-godot_string GDAPI godot_string_lstrip(const godot_string *p_self, const godot_string *p_chars);
-godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars);
-
-void GDAPI godot_string_destroy(godot_string *p_self);
-
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/string_name.h b/modules/gdnative/include/gdnative/string_name.h
index f2555ab98f..346f626e81 100644
--- a/modules/gdnative/include/gdnative/string_name.h
+++ b/modules/gdnative/include/gdnative/string_name.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,30 +47,14 @@ typedef struct {
} godot_string_name;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name);
-void GDAPI godot_string_name_new_data(godot_string_name *r_dest, const char *p_name);
-
-godot_string GDAPI godot_string_name_get_name(const godot_string_name *p_self);
-
-uint32_t GDAPI godot_string_name_get_hash(const godot_string_name *p_self);
-const void GDAPI *godot_string_name_get_data_unique_pointer(const godot_string_name *p_self);
-
-godot_bool GDAPI godot_string_name_operator_equal(const godot_string_name *p_self, const godot_string_name *p_other);
-godot_bool GDAPI godot_string_name_operator_less(const godot_string_name *p_self, const godot_string_name *p_other);
-
+void GDAPI godot_string_name_new(godot_string_name *r_dest);
+void GDAPI godot_string_name_new_copy(godot_string_name *r_dest, const godot_string_name *p_src);
void GDAPI godot_string_name_destroy(godot_string_name *p_self);
+void GDAPI godot_string_name_new_with_latin1_chars(godot_string_name *r_dest, const char *p_contents);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/transform.h b/modules/gdnative/include/gdnative/transform.h
index bc51438b17..e67862d140 100644
--- a/modules/gdnative/include/gdnative/transform.h
+++ b/modules/gdnative/include/gdnative/transform.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,9 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_TRANSFORM_SIZE 48
+#define GODOT_TRANSFORM_SIZE (sizeof(godot_real_t) * 12)
#ifndef GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED
@@ -46,63 +46,9 @@ typedef struct {
} godot_transform;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
-#include <gdnative/basis.h>
#include <gdnative/gdnative.h>
-#include <gdnative/variant.h>
-#include <gdnative/vector3.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin);
-void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin);
-void GDAPI godot_transform_new_with_quat(godot_transform *r_dest, const godot_quat *p_quat);
-
-godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self);
-void GDAPI godot_transform_set_basis(godot_transform *p_self, const godot_basis *p_v);
-
-godot_vector3 GDAPI godot_transform_get_origin(const godot_transform *p_self);
-void GDAPI godot_transform_set_origin(godot_transform *p_self, const godot_vector3 *p_v);
-
-godot_string GDAPI godot_transform_as_string(const godot_transform *p_self);
-
-godot_transform GDAPI godot_transform_inverse(const godot_transform *p_self);
-
-godot_transform GDAPI godot_transform_affine_inverse(const godot_transform *p_self);
-
-godot_transform GDAPI godot_transform_orthonormalized(const godot_transform *p_self);
-
-godot_transform GDAPI godot_transform_rotated(const godot_transform *p_self, const godot_vector3 *p_axis, const godot_real p_phi);
-
-godot_transform GDAPI godot_transform_scaled(const godot_transform *p_self, const godot_vector3 *p_scale);
-
-godot_transform GDAPI godot_transform_translated(const godot_transform *p_self, const godot_vector3 *p_ofs);
-
-godot_transform GDAPI godot_transform_looking_at(const godot_transform *p_self, const godot_vector3 *p_target, const godot_vector3 *p_up);
-
-godot_plane GDAPI godot_transform_xform_plane(const godot_transform *p_self, const godot_plane *p_v);
-
-godot_plane GDAPI godot_transform_xform_inv_plane(const godot_transform *p_self, const godot_plane *p_v);
-
-void GDAPI godot_transform_new_identity(godot_transform *r_dest);
-
-godot_bool GDAPI godot_transform_operator_equal(const godot_transform *p_self, const godot_transform *p_b);
-
-godot_transform GDAPI godot_transform_operator_multiply(const godot_transform *p_self, const godot_transform *p_b);
-
-godot_vector3 GDAPI godot_transform_xform_vector3(const godot_transform *p_self, const godot_vector3 *p_v);
-
-godot_vector3 GDAPI godot_transform_xform_inv_vector3(const godot_transform *p_self, const godot_vector3 *p_v);
-
-godot_aabb GDAPI godot_transform_xform_aabb(const godot_transform *p_self, const godot_aabb *p_v);
-godot_aabb GDAPI godot_transform_xform_inv_aabb(const godot_transform *p_self, const godot_aabb *p_v);
+void GDAPI godot_transform_new(godot_transform *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h
index 6b414ca7b2..4a2bca7cfc 100644
--- a/modules/gdnative/include/gdnative/transform2d.h
+++ b/modules/gdnative/include/gdnative/transform2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,9 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_TRANSFORM2D_SIZE 24
+#define GODOT_TRANSFORM2D_SIZE (sizeof(godot_real_t) * 6)
#ifndef GODOT_CORE_API_GODOT_TRANSFORM2D_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_TRANSFORM2D_TYPE_DEFINED
@@ -46,61 +46,11 @@ typedef struct {
} godot_transform2d;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#include <gdnative/variant.h>
-#include <gdnative/vector2.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos);
-void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin);
-
-godot_string GDAPI godot_transform2d_as_string(const godot_transform2d *p_self);
-
-godot_transform2d GDAPI godot_transform2d_inverse(const godot_transform2d *p_self);
-
-godot_transform2d GDAPI godot_transform2d_affine_inverse(const godot_transform2d *p_self);
-
-godot_real GDAPI godot_transform2d_get_rotation(const godot_transform2d *p_self);
-
-godot_vector2 GDAPI godot_transform2d_get_origin(const godot_transform2d *p_self);
-
-godot_vector2 GDAPI godot_transform2d_get_scale(const godot_transform2d *p_self);
-
-godot_transform2d GDAPI godot_transform2d_orthonormalized(const godot_transform2d *p_self);
-
-godot_transform2d GDAPI godot_transform2d_rotated(const godot_transform2d *p_self, const godot_real p_phi);
-
-godot_transform2d GDAPI godot_transform2d_scaled(const godot_transform2d *p_self, const godot_vector2 *p_scale);
-
-godot_transform2d GDAPI godot_transform2d_translated(const godot_transform2d *p_self, const godot_vector2 *p_offset);
-
-godot_vector2 GDAPI godot_transform2d_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v);
-
-godot_vector2 GDAPI godot_transform2d_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v);
-
-godot_vector2 GDAPI godot_transform2d_basis_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v);
-
-godot_vector2 GDAPI godot_transform2d_basis_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v);
-
-godot_transform2d GDAPI godot_transform2d_interpolate_with(const godot_transform2d *p_self, const godot_transform2d *p_m, const godot_real p_c);
-
-godot_bool GDAPI godot_transform2d_operator_equal(const godot_transform2d *p_self, const godot_transform2d *p_b);
-
-godot_transform2d GDAPI godot_transform2d_operator_multiply(const godot_transform2d *p_self, const godot_transform2d *p_b);
-
-void GDAPI godot_transform2d_new_identity(godot_transform2d *r_dest);
-
-godot_rect2 GDAPI godot_transform2d_xform_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v);
-godot_rect2 GDAPI godot_transform2d_xform_inv_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v);
+void GDAPI godot_transform2d_new(godot_transform2d *p_self);
+godot_vector2 GDAPI *godot_transform2d_operator_index(godot_transform2d *p_self, godot_int p_index);
+const godot_vector2 GDAPI *godot_transform2d_operator_index_const(const godot_transform2d *p_self, godot_int p_index);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h
index 2e803d602b..329a6faf51 100644
--- a/modules/gdnative/include/gdnative/variant.h
+++ b/modules/gdnative/include/gdnative/variant.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,16 +35,8 @@
extern "C" {
#endif
-#include <stdint.h>
-
-#define GODOT_VARIANT_SIZE (16 + sizeof(int64_t))
-
-#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
-typedef struct {
- uint8_t _dont_touch_that[GODOT_VARIANT_SIZE];
-} godot_variant;
-#endif
+#include <gdnative/math_defs.h>
+#include <gdnative/variant_struct.h>
typedef enum godot_variant_type {
GODOT_VARIANT_TYPE_NIL,
@@ -146,10 +138,35 @@ typedef enum godot_variant_operator {
GODOT_VARIANT_OP_MAX,
} godot_variant_operator;
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
+typedef enum godot_variant_utility_function_type {
+ GODOT_UTILITY_FUNC_TYPE_MATH,
+ GODOT_UTILITY_FUNC_TYPE_RANDOM,
+ GODOT_UTILITY_FUNC_TYPE_GENERAL,
+} godot_variant_utility_function_type;
+
+// Types for function pointers.
+typedef void (*godot_validated_operator_evaluator)(const godot_variant *p_left, const godot_variant *p_right, godot_variant *r_result);
+typedef void (*godot_ptr_operator_evaluator)(const void *p_left, const void *p_right, void *r_result);
+typedef void (*godot_validated_builtin_method)(godot_variant *p_base, const godot_variant **p_args, int p_argument_count, godot_variant *r_return);
+typedef void (*godot_ptr_builtin_method)(void *p_base, const void **p_args, void *r_return, int p_argument_count);
+typedef void (*godot_validated_constructor)(godot_variant *p_base, const godot_variant **p_args);
+typedef void (*godot_ptr_constructor)(void *p_base, const void **p_args);
+typedef void (*godot_validated_setter)(godot_variant *p_base, const godot_variant *p_value);
+typedef void (*godot_validated_getter)(const godot_variant *p_base, godot_variant *r_value);
+typedef void (*godot_ptr_setter)(void *p_base, const void *p_value);
+typedef void (*godot_ptr_getter)(const void *p_base, void *r_value);
+typedef void (*godot_validated_indexed_setter)(godot_variant *p_base, godot_int p_index, const godot_variant *p_value, bool *r_oob);
+typedef void (*godot_validated_indexed_getter)(const godot_variant *p_base, godot_int p_index, godot_variant *r_value, bool *r_oob);
+typedef void (*godot_ptr_indexed_setter)(void *p_base, godot_int p_index, const void *p_value);
+typedef void (*godot_ptr_indexed_getter)(const void *p_base, godot_int p_index, void *r_value);
+typedef void (*godot_validated_keyed_setter)(godot_variant *p_base, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid);
+typedef void (*godot_validated_keyed_getter)(const godot_variant *p_base, const godot_variant *p_key, godot_variant *r_value, bool *r_valid);
+typedef bool (*godot_validated_keyed_checker)(const godot_variant *p_base, const godot_variant *p_key, bool *r_valid);
+typedef void (*godot_ptr_keyed_setter)(void *p_base, const void *p_key, const void *p_value);
+typedef void (*godot_ptr_keyed_getter)(const void *p_base, const void *p_key, void *r_value);
+typedef bool (*godot_ptr_keyed_checker)(const godot_variant *p_base, const godot_variant *p_key);
+typedef void (*godot_validated_utility_function)(godot_variant *r_return, const godot_variant **p_arguments, int p_argument_count);
+typedef void (*godot_ptr_utility_function)(void *r_return, const void **p_arguments, int p_argument_count);
#include <gdnative/aabb.h>
#include <gdnative/array.h>
@@ -163,6 +180,7 @@ typedef enum godot_variant_operator {
#include <gdnative/quat.h>
#include <gdnative/rect2.h>
#include <gdnative/rid.h>
+#include <gdnative/signal.h>
#include <gdnative/string.h>
#include <gdnative/string_name.h>
#include <gdnative/transform.h>
@@ -173,22 +191,15 @@ typedef enum godot_variant_operator {
#include <gdnative/gdnative.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v);
+// Memory.
void GDAPI godot_variant_new_copy(godot_variant *r_dest, const godot_variant *p_src);
void GDAPI godot_variant_new_nil(godot_variant *r_dest);
-
void GDAPI godot_variant_new_bool(godot_variant *r_dest, const godot_bool p_b);
-void GDAPI godot_variant_new_uint(godot_variant *r_dest, const uint64_t p_i);
-void GDAPI godot_variant_new_int(godot_variant *r_dest, const int64_t p_i);
-void GDAPI godot_variant_new_real(godot_variant *r_dest, const double p_r);
+void GDAPI godot_variant_new_int(godot_variant *r_dest, const godot_int p_i);
+void GDAPI godot_variant_new_float(godot_variant *r_dest, const godot_float p_f);
void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p_s);
-void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s);
void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2);
void GDAPI godot_variant_new_vector2i(godot_variant *r_dest, const godot_vector2i *p_v2);
void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2);
@@ -202,11 +213,12 @@ void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aab
void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis);
void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans);
void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color);
+void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s);
void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np);
void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid);
+void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj);
void GDAPI godot_variant_new_callable(godot_variant *r_dest, const godot_callable *p_callable);
void GDAPI godot_variant_new_signal(godot_variant *r_dest, const godot_signal *p_signal);
-void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj);
void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict);
void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr);
void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godot_packed_byte_array *p_pba);
@@ -220,11 +232,9 @@ void GDAPI godot_variant_new_packed_vector3_array(godot_variant *r_dest, const g
void GDAPI godot_variant_new_packed_color_array(godot_variant *r_dest, const godot_packed_color_array *p_pca);
godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_self);
-uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_self);
-int64_t GDAPI godot_variant_as_int(const godot_variant *p_self);
-double GDAPI godot_variant_as_real(const godot_variant *p_self);
+godot_int GDAPI godot_variant_as_int(const godot_variant *p_self);
+godot_float GDAPI godot_variant_as_float(const godot_variant *p_self);
godot_string GDAPI godot_variant_as_string(const godot_variant *p_self);
-godot_string_name GDAPI godot_variant_as_string_name(const godot_variant *p_self);
godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_self);
godot_vector2i GDAPI godot_variant_as_vector2i(const godot_variant *p_self);
godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_self);
@@ -238,11 +248,12 @@ godot_aabb GDAPI godot_variant_as_aabb(const godot_variant *p_self);
godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_self);
godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_self);
godot_color GDAPI godot_variant_as_color(const godot_variant *p_self);
+godot_string_name GDAPI godot_variant_as_string_name(const godot_variant *p_self);
godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_self);
godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_self);
+godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self);
godot_callable GDAPI godot_variant_as_callable(const godot_variant *p_self);
godot_signal GDAPI godot_variant_as_signal(const godot_variant *p_self);
-godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self);
godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_self);
godot_array GDAPI godot_variant_as_array(const godot_variant *p_self);
godot_packed_byte_array GDAPI godot_variant_as_packed_byte_array(const godot_variant *p_self);
@@ -255,24 +266,153 @@ godot_packed_vector2_array GDAPI godot_variant_as_packed_vector2_array(const god
godot_packed_vector3_array GDAPI godot_variant_as_packed_vector3_array(const godot_variant *p_self);
godot_packed_color_array GDAPI godot_variant_as_packed_color_array(const godot_variant *p_self);
-godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant_call_error *r_error);
-
-godot_bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string *p_method);
-
-godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_self, const godot_variant *p_other);
-godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const godot_variant *p_other);
+void GDAPI godot_variant_destroy(godot_variant *p_self);
-uint32_t GDAPI godot_variant_hash(const godot_variant *p_self);
+// Dynamic interaction.
+
+void GDAPI godot_variant_call(godot_variant *p_self, const godot_string_name *p_method, const godot_variant **p_args, const godot_int p_argument_count, godot_variant *r_return, godot_variant_call_error *r_error);
+void GDAPI godot_variant_call_with_cstring(godot_variant *p_self, const char *p_method, const godot_variant **p_args, const godot_int p_argument_count, godot_variant *r_return, godot_variant_call_error *r_error);
+void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_variant *p_a, const godot_variant *p_b, godot_variant *r_return, bool *r_valid);
+void GDAPI godot_variant_set(godot_variant *p_self, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid);
+void GDAPI godot_variant_set_named(godot_variant *p_self, const godot_string_name *p_name, const godot_variant *p_value, bool *r_valid);
+void GDAPI godot_variant_set_named_with_cstring(godot_variant *p_self, const char *p_name, const godot_variant *p_value, bool *r_valid);
+void GDAPI godot_variant_set_keyed(godot_variant *p_self, const godot_variant *p_key, const godot_variant *p_value, bool *r_valid);
+void GDAPI godot_variant_set_indexed(godot_variant *p_self, godot_int p_index, const godot_variant *p_value, bool *r_valid, bool *r_oob);
+godot_variant GDAPI godot_variant_get(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid);
+godot_variant GDAPI godot_variant_get_named(const godot_variant *p_self, const godot_string_name *p_key, bool *r_valid);
+godot_variant GDAPI godot_variant_get_named_with_cstring(const godot_variant *p_self, const char *p_key, bool *r_valid);
+godot_variant GDAPI godot_variant_get_keyed(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid);
+godot_variant GDAPI godot_variant_get_indexed(const godot_variant *p_self, godot_int p_index, bool *r_valid, bool *r_oob);
+/// Iteration.
+bool GDAPI godot_variant_iter_init(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid);
+bool GDAPI godot_variant_iter_next(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid);
+godot_variant GDAPI godot_variant_iter_get(const godot_variant *p_self, godot_variant *r_iter, bool *r_valid);
+
+/// Variant functions.
godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other);
-
godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self);
-
-void GDAPI godot_variant_destroy(godot_variant *p_self);
-
-// GDNative core 1.1
-
-godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_op);
-void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_variant *p_a, const godot_variant *p_b, godot_variant *r_ret, godot_bool *r_valid);
+void GDAPI godot_variant_blend(const godot_variant *p_a, const godot_variant *p_b, float p_c, godot_variant *r_dst);
+void GDAPI godot_variant_interpolate(const godot_variant *p_a, const godot_variant *p_b, float p_c, godot_variant *r_dst);
+godot_variant GDAPI godot_variant_duplicate(const godot_variant *p_self, godot_bool p_deep);
+godot_string GDAPI godot_variant_stringify(const godot_variant *p_self);
+
+// Discovery API.
+
+/// Operators.
+godot_validated_operator_evaluator GDAPI godot_variant_get_validated_operator_evaluator(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b);
+godot_ptr_operator_evaluator GDAPI godot_variant_get_ptr_operator_evaluator(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b);
+godot_variant_type GDAPI godot_variant_get_operator_return_type(godot_variant_operator p_operator, godot_variant_type p_type_a, godot_variant_type p_type_b);
+godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_operator);
+
+/// Built-in methods.
+bool GDAPI godot_variant_has_builtin_method(godot_variant_type p_type, const godot_string_name *p_method);
+bool GDAPI godot_variant_has_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method);
+godot_validated_builtin_method GDAPI godot_variant_get_validated_builtin_method(godot_variant_type p_type, const godot_string_name *p_method);
+godot_validated_builtin_method GDAPI godot_variant_get_validated_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method);
+godot_ptr_builtin_method GDAPI godot_variant_get_ptr_builtin_method(godot_variant_type p_type, const godot_string_name *p_method);
+godot_ptr_builtin_method GDAPI godot_variant_get_ptr_builtin_method_with_cstring(godot_variant_type p_type, const char *p_method);
+int GDAPI godot_variant_get_builtin_method_argument_count(godot_variant_type p_type, const godot_string_name *p_method);
+int GDAPI godot_variant_get_builtin_method_argument_count_with_cstring(godot_variant_type p_type, const char *p_method);
+godot_variant_type GDAPI godot_variant_get_builtin_method_argument_type(godot_variant_type p_type, const godot_string_name *p_method, int p_argument);
+godot_variant_type GDAPI godot_variant_get_builtin_method_argument_type_with_cstring(godot_variant_type p_type, const char *p_method, int p_argument);
+godot_string GDAPI godot_variant_get_builtin_method_argument_name(godot_variant_type p_type, const godot_string_name *p_method, int p_argument);
+godot_string GDAPI godot_variant_get_builtin_method_argument_name_with_cstring(godot_variant_type p_type, const char *p_method, int p_argument);
+bool GDAPI godot_variant_has_builtin_method_return_value(godot_variant_type p_type, const godot_string_name *p_method);
+bool GDAPI godot_variant_has_builtin_method_return_value_with_cstring(godot_variant_type p_type, const char *p_method);
+godot_variant_type GDAPI godot_variant_get_builtin_method_return_type(godot_variant_type p_type, const godot_string_name *p_method);
+godot_variant_type GDAPI godot_variant_get_builtin_method_return_type_with_cstring(godot_variant_type p_type, const char *p_method);
+bool GDAPI godot_variant_is_builtin_method_const(godot_variant_type p_type, const godot_string_name *p_method);
+bool GDAPI godot_variant_is_builtin_method_const_with_cstring(godot_variant_type p_type, const char *p_method);
+bool GDAPI godot_variant_is_builtin_method_vararg(godot_variant_type p_type, const godot_string_name *p_method);
+bool GDAPI godot_variant_is_builtin_method_vararg_with_cstring(godot_variant_type p_type, const char *p_method);
+int GDAPI godot_variant_get_builtin_method_count(godot_variant_type p_type);
+void GDAPI godot_variant_get_builtin_method_list(godot_variant_type p_type, godot_string_name *r_list);
+
+/// Constructors.
+int GDAPI godot_variant_get_constructor_count(godot_variant_type p_type);
+godot_validated_constructor GDAPI godot_variant_get_validated_constructor(godot_variant_type p_type, int p_constructor);
+godot_ptr_constructor GDAPI godot_variant_get_ptr_constructor(godot_variant_type p_type, int p_constructor);
+int GDAPI godot_variant_get_constructor_argument_count(godot_variant_type p_type, int p_constructor);
+godot_variant_type GDAPI godot_variant_get_constructor_argument_type(godot_variant_type p_type, int p_constructor, int p_argument);
+godot_string GDAPI godot_variant_get_constructor_argument_name(godot_variant_type p_type, int p_constructor, int p_argument);
+void GDAPI godot_variant_construct(godot_variant_type p_type, godot_variant *p_base, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error);
+
+/// Properties.
+godot_variant_type GDAPI godot_variant_get_member_type(godot_variant_type p_type, const godot_string_name *p_member);
+godot_variant_type GDAPI godot_variant_get_member_type_with_cstring(godot_variant_type p_type, const char *p_member);
+int GDAPI godot_variant_get_member_count(godot_variant_type p_type);
+void GDAPI godot_variant_get_member_list(godot_variant_type p_type, godot_string_name *r_list);
+godot_validated_setter GDAPI godot_variant_get_validated_setter(godot_variant_type p_type, const godot_string_name *p_member);
+godot_validated_setter GDAPI godot_variant_get_validated_setter_with_cstring(godot_variant_type p_type, const char *p_member);
+godot_validated_getter GDAPI godot_variant_get_validated_getter(godot_variant_type p_type, const godot_string_name *p_member);
+godot_validated_getter GDAPI godot_variant_get_validated_getter_with_cstring(godot_variant_type p_type, const char *p_member);
+godot_ptr_setter GDAPI godot_variant_get_ptr_setter(godot_variant_type p_type, const godot_string_name *p_member);
+godot_ptr_setter GDAPI godot_variant_get_ptr_setter_with_cstring(godot_variant_type p_type, const char *p_member);
+godot_ptr_getter GDAPI godot_variant_get_ptr_getter(godot_variant_type p_type, const godot_string_name *p_member);
+godot_ptr_getter GDAPI godot_variant_get_ptr_getter_with_cstring(godot_variant_type p_type, const char *p_member);
+
+/// Indexing.
+bool GDAPI godot_variant_has_indexing(godot_variant_type p_type);
+godot_variant_type GDAPI godot_variant_get_indexed_element_type(godot_variant_type p_type);
+godot_validated_indexed_setter GDAPI godot_variant_get_validated_indexed_setter(godot_variant_type p_type);
+godot_validated_indexed_getter GDAPI godot_variant_get_validated_indexed_getter(godot_variant_type p_type);
+godot_ptr_indexed_setter GDAPI godot_variant_get_ptr_indexed_setter(godot_variant_type p_type);
+godot_ptr_indexed_getter GDAPI godot_variant_get_ptr_indexed_getter(godot_variant_type p_type);
+uint64_t GDAPI godot_variant_get_indexed_size(const godot_variant *p_self);
+
+/// Keying.
+bool GDAPI godot_variant_is_keyed(godot_variant_type p_type);
+godot_validated_keyed_setter GDAPI godot_variant_get_validated_keyed_setter(godot_variant_type p_type);
+godot_validated_keyed_getter GDAPI godot_variant_get_validated_keyed_getter(godot_variant_type p_type);
+godot_validated_keyed_checker GDAPI godot_variant_get_validated_keyed_checker(godot_variant_type p_type);
+godot_ptr_keyed_setter GDAPI godot_variant_get_ptr_keyed_setter(godot_variant_type p_type);
+godot_ptr_keyed_getter GDAPI godot_variant_get_ptr_keyed_getter(godot_variant_type p_type);
+godot_ptr_keyed_checker GDAPI godot_variant_get_ptr_keyed_checker(godot_variant_type p_type);
+
+/// Constants.
+int GDAPI godot_variant_get_constants_count(godot_variant_type p_type);
+void GDAPI godot_variant_get_constants_list(godot_variant_type p_type, godot_string_name *r_list);
+bool GDAPI godot_variant_has_constant(godot_variant_type p_type, const godot_string_name *p_constant);
+bool GDAPI godot_variant_has_constant_with_cstring(godot_variant_type p_type, const char *p_constant);
+godot_variant GDAPI godot_variant_get_constant_value(godot_variant_type p_type, const godot_string_name *p_constant);
+godot_variant GDAPI godot_variant_get_constant_value_with_cstring(godot_variant_type p_type, const char *p_constant);
+
+/// Utilities.
+bool GDAPI godot_variant_has_utility_function(const godot_string_name *p_function);
+bool GDAPI godot_variant_has_utility_function_with_cstring(const char *p_function);
+void GDAPI godot_variant_call_utility_function(const godot_string_name *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error);
+void GDAPI godot_variant_call_utility_function_with_cstring(const char *p_function, godot_variant *r_ret, const godot_variant **p_args, int p_argument_count, godot_variant_call_error *r_error);
+godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function(const godot_string_name *p_function);
+godot_ptr_utility_function GDAPI godot_variant_get_ptr_utility_function_with_cstring(const char *p_function);
+godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function(const godot_string_name *p_function);
+godot_validated_utility_function GDAPI godot_variant_get_validated_utility_function_with_cstring(const char *p_function);
+godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type(const godot_string_name *p_function);
+godot_variant_utility_function_type GDAPI godot_variant_get_utility_function_type_with_cstring(const char *p_function);
+int GDAPI godot_variant_get_utility_function_argument_count(const godot_string_name *p_function);
+int GDAPI godot_variant_get_utility_function_argument_count_with_cstring(const char *p_function);
+godot_variant_type GDAPI godot_variant_get_utility_function_argument_type(const godot_string_name *p_function, int p_argument);
+godot_variant_type GDAPI godot_variant_get_utility_function_argument_type_with_cstring(const char *p_function, int p_argument);
+godot_string GDAPI godot_variant_get_utility_function_argument_name(const godot_string_name *p_function, int p_argument);
+godot_string GDAPI godot_variant_get_utility_function_argument_name_with_cstring(const char *p_function, int p_argument);
+bool GDAPI godot_variant_has_utility_function_return_value(const godot_string_name *p_function);
+bool GDAPI godot_variant_has_utility_function_return_value_with_cstring(const char *p_function);
+godot_variant_type GDAPI godot_variant_get_utility_function_return_type(const godot_string_name *p_function);
+godot_variant_type GDAPI godot_variant_get_utility_function_return_type_with_cstring(const char *p_function);
+bool GDAPI godot_variant_is_utility_function_vararg(const godot_string_name *p_function);
+bool GDAPI godot_variant_is_utility_function_vararg_with_cstring(const char *p_function);
+int GDAPI godot_variant_get_utility_function_count();
+void GDAPI godot_variant_get_utility_function_list(godot_string_name *r_functions);
+
+// Introspection.
+
+godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_self);
+bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string_name *p_method);
+bool GDAPI godot_variant_has_member(godot_variant_type p_type, const godot_string_name *p_member);
+bool GDAPI godot_variant_has_key(const godot_variant *p_self, const godot_variant *p_key, bool *r_valid);
+
+godot_string GDAPI godot_variant_get_type_name(godot_variant_type p_type);
+bool GDAPI godot_variant_can_convert(godot_variant_type p_from, godot_variant_type p_to);
+bool GDAPI godot_variant_can_convert_strict(godot_variant_type p_from, godot_variant_type p_to);
#ifdef __cplusplus
}
diff --git a/core/os/thread_dummy.cpp b/modules/gdnative/include/gdnative/variant_struct.h
index 2672cd7ad9..321c76c206 100644
--- a/core/os/thread_dummy.cpp
+++ b/modules/gdnative/include/gdnative/variant_struct.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* thread_dummy.cpp */
+/* variant_struct.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,22 +28,26 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "thread_dummy.h"
+#ifndef GODOT_VARIANT_STRUCT_H
+#define GODOT_VARIANT_STRUCT_H
-#include "core/os/memory.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
-Thread *ThreadDummy::create(ThreadCreateCallback p_callback, void *p_user, const Thread::Settings &p_settings) {
- return memnew(ThreadDummy);
-}
+#include <gdnative/math_defs.h>
-void ThreadDummy::make_default() {
- Thread::create_func = &ThreadDummy::create;
-}
+#define GODOT_VARIANT_SIZE (sizeof(godot_real_t) * 4 + sizeof(int64_t))
-RWLock *RWLockDummy::create() {
- return memnew(RWLockDummy);
-}
+#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_VARIANT_SIZE];
+} godot_variant;
+#endif
-void RWLockDummy::make_default() {
- RWLock::create_func = &RWLockDummy::create;
+#ifdef __cplusplus
}
+#endif
+
+#endif
diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 35b02c5a75..5ebb705ba4 100644
--- a/modules/gdnative/include/gdnative/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,9 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_VECTOR2_SIZE 8
+#define GODOT_VECTOR2_SIZE (sizeof(godot_real_t) * 2)
#ifndef GODOT_CORE_API_GODOT_VECTOR2_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_VECTOR2_TYPE_DEFINED
@@ -46,7 +46,7 @@ typedef struct {
} godot_vector2;
#endif
-#define GODOT_VECTOR2I_SIZE 8
+#define GODOT_VECTOR2I_SIZE (sizeof(int32_t) * 2)
#ifndef GODOT_CORE_API_GODOT_VECTOR2I_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_VECTOR2I_TYPE_DEFINED
@@ -55,140 +55,14 @@ typedef struct {
} godot_vector2i;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
#include <gdnative/gdnative.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Vector2
-
-void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y);
-
-godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self);
-
-godot_vector2i GDAPI godot_vector2_as_vector2i(const godot_vector2 *p_self);
-
-godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_self);
-
-godot_real GDAPI godot_vector2_length(const godot_vector2 *p_self);
-
-godot_real GDAPI godot_vector2_angle(const godot_vector2 *p_self);
-
-godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_self);
-
-godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self);
-
-godot_vector2 GDAPI godot_vector2_direction_to(const godot_vector2 *p_self, const godot_vector2 *p_b);
-
-godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
-
-godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
-
-godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
-
-godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_self, const godot_vector2 *p_to);
-
-godot_vector2 GDAPI godot_vector2_lerp(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t);
-
-godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_vector2 *p_pre_a, const godot_vector2 *p_post_b, const godot_real p_t);
-
-godot_vector2 GDAPI godot_vector2_move_toward(const godot_vector2 *p_self, const godot_vector2 *p_to, const godot_real p_delta);
-
-godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_self, const godot_real p_phi);
-
-godot_vector2 GDAPI godot_vector2_tangent(const godot_vector2 *p_self);
-
-godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_self);
-
-godot_vector2 GDAPI godot_vector2_sign(const godot_vector2 *p_self);
-
-godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_self, const godot_vector2 *p_by);
-
-godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_self);
-
-godot_real GDAPI godot_vector2_dot(const godot_vector2 *p_self, const godot_vector2 *p_with);
-
-godot_vector2 GDAPI godot_vector2_slide(const godot_vector2 *p_self, const godot_vector2 *p_n);
-
-godot_vector2 GDAPI godot_vector2_bounce(const godot_vector2 *p_self, const godot_vector2 *p_n);
-
-godot_vector2 GDAPI godot_vector2_reflect(const godot_vector2 *p_self, const godot_vector2 *p_n);
-
-godot_vector2 GDAPI godot_vector2_abs(const godot_vector2 *p_self);
-
-godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_self, const godot_real p_length);
-
-godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_self, const godot_vector2 *p_b);
-
-godot_vector2 GDAPI godot_vector2_operator_subtract(const godot_vector2 *p_self, const godot_vector2 *p_b);
-
-godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_self, const godot_vector2 *p_b);
-
-godot_vector2 GDAPI godot_vector2_operator_multiply_scalar(const godot_vector2 *p_self, const godot_real p_b);
-
-godot_vector2 GDAPI godot_vector2_operator_divide_vector(const godot_vector2 *p_self, const godot_vector2 *p_b);
-
-godot_vector2 GDAPI godot_vector2_operator_divide_scalar(const godot_vector2 *p_self, const godot_real p_b);
-
-godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_self, const godot_vector2 *p_b);
-
-godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_self, const godot_vector2 *p_b);
-
-godot_vector2 GDAPI godot_vector2_operator_neg(const godot_vector2 *p_self);
-
-void GDAPI godot_vector2_set_x(godot_vector2 *p_self, const godot_real p_x);
-
-void GDAPI godot_vector2_set_y(godot_vector2 *p_self, const godot_real p_y);
-
-godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_self);
-
-godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_self);
-
-// Vector2i
-
-void GDAPI godot_vector2i_new(godot_vector2i *r_dest, const godot_int p_x, const godot_int p_y);
-
-godot_string GDAPI godot_vector2i_as_string(const godot_vector2i *p_self);
-
-godot_vector2 GDAPI godot_vector2i_as_vector2(const godot_vector2i *p_self);
-
-godot_real GDAPI godot_vector2i_aspect(const godot_vector2i *p_self);
-
-godot_vector2i GDAPI godot_vector2i_abs(const godot_vector2i *p_self);
-
-godot_vector2i GDAPI godot_vector2i_sign(const godot_vector2i *p_self);
-
-godot_vector2i GDAPI godot_vector2i_operator_add(const godot_vector2i *p_self, const godot_vector2i *p_b);
-
-godot_vector2i GDAPI godot_vector2i_operator_subtract(const godot_vector2i *p_self, const godot_vector2i *p_b);
-
-godot_vector2i GDAPI godot_vector2i_operator_multiply_vector(const godot_vector2i *p_self, const godot_vector2i *p_b);
-
-godot_vector2i GDAPI godot_vector2i_operator_multiply_scalar(const godot_vector2i *p_self, const godot_int p_b);
-
-godot_vector2i GDAPI godot_vector2i_operator_divide_vector(const godot_vector2i *p_self, const godot_vector2i *p_b);
-
-godot_vector2i GDAPI godot_vector2i_operator_divide_scalar(const godot_vector2i *p_self, const godot_int p_b);
-
-godot_bool GDAPI godot_vector2i_operator_equal(const godot_vector2i *p_self, const godot_vector2i *p_b);
-
-godot_bool GDAPI godot_vector2i_operator_less(const godot_vector2i *p_self, const godot_vector2i *p_b);
-
-godot_vector2i GDAPI godot_vector2i_operator_neg(const godot_vector2i *p_self);
-
-void GDAPI godot_vector2i_set_x(godot_vector2i *p_self, const godot_int p_x);
-
-void GDAPI godot_vector2i_set_y(godot_vector2i *p_self, const godot_int p_y);
-
-godot_int GDAPI godot_vector2i_get_x(const godot_vector2i *p_self);
-
-godot_int GDAPI godot_vector2i_get_y(const godot_vector2i *p_self);
+void GDAPI godot_vector2_new(godot_vector2 *p_self);
+void GDAPI godot_vector2i_new(godot_vector2i *p_self);
+godot_real_t GDAPI *godot_vector2_operator_index(godot_vector2 *p_self, godot_int p_index);
+const godot_real_t GDAPI *godot_vector2_operator_index_const(const godot_vector2 *p_self, godot_int p_index);
+int32_t GDAPI *godot_vector2i_operator_index(godot_vector2i *p_self, godot_int p_index);
+const int32_t GDAPI *godot_vector2i_operator_index_const(const godot_vector2i *p_self, godot_int p_index);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index 5127b8789b..d37ebd3cc9 100644
--- a/modules/gdnative/include/gdnative/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,9 @@
extern "C" {
#endif
-#include <stdint.h>
+#include <gdnative/math_defs.h>
-#define GODOT_VECTOR3_SIZE 12
+#define GODOT_VECTOR3_SIZE (sizeof(godot_real_t) * 3)
#ifndef GODOT_CORE_API_GODOT_VECTOR3_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_VECTOR3_TYPE_DEFINED
@@ -46,7 +46,7 @@ typedef struct {
} godot_vector3;
#endif
-#define GODOT_VECTOR3I_SIZE 12
+#define GODOT_VECTOR3I_SIZE (sizeof(int32_t) * 3)
#ifndef GODOT_CORE_API_GODOT_VECTOR3I_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_VECTOR3I_TYPE_DEFINED
@@ -55,145 +55,14 @@ typedef struct {
} godot_vector3i;
#endif
-// reduce extern "C" nesting for VS2013
-#ifdef __cplusplus
-}
-#endif
-
-#include <gdnative/basis.h>
#include <gdnative/gdnative.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- GODOT_VECTOR3_AXIS_X,
- GODOT_VECTOR3_AXIS_Y,
- GODOT_VECTOR3_AXIS_Z,
-} godot_vector3_axis;
-
-// Vector3
-
-void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z);
-
-godot_string GDAPI godot_vector3_as_string(const godot_vector3 *p_self);
-
-godot_vector3i GDAPI godot_vector3_as_vector3i(const godot_vector3 *p_self);
-
-godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_self);
-
-godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_self);
-
-godot_real GDAPI godot_vector3_length(const godot_vector3 *p_self);
-
-godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_self);
-
-godot_bool GDAPI godot_vector3_is_normalized(const godot_vector3 *p_self);
-
-godot_vector3 GDAPI godot_vector3_normalized(const godot_vector3 *p_self);
-
-godot_vector3 GDAPI godot_vector3_inverse(const godot_vector3 *p_self);
-
-godot_vector3 GDAPI godot_vector3_snapped(const godot_vector3 *p_self, const godot_vector3 *p_by);
-
-godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_self, const godot_vector3 *p_axis, const godot_real p_phi);
-
-godot_vector3 GDAPI godot_vector3_lerp(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t);
-
-godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_vector3 *p_pre_a, const godot_vector3 *p_post_b, const godot_real p_t);
-
-godot_vector3 GDAPI godot_vector3_move_toward(const godot_vector3 *p_self, const godot_vector3 *p_to, const godot_real p_delta);
-
-godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_vector3 GDAPI godot_vector3_cross(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_basis GDAPI godot_vector3_outer(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_basis GDAPI godot_vector3_to_diagonal_matrix(const godot_vector3 *p_self);
-
-godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_self);
-
-godot_vector3 GDAPI godot_vector3_sign(const godot_vector3 *p_self);
-
-godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self);
-
-godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self);
-
-godot_vector3 GDAPI godot_vector3_direction_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_real GDAPI godot_vector3_angle_to(const godot_vector3 *p_self, const godot_vector3 *p_to);
-
-godot_vector3 GDAPI godot_vector3_slide(const godot_vector3 *p_self, const godot_vector3 *p_n);
-
-godot_vector3 GDAPI godot_vector3_bounce(const godot_vector3 *p_self, const godot_vector3 *p_n);
-
-godot_vector3 GDAPI godot_vector3_reflect(const godot_vector3 *p_self, const godot_vector3 *p_n);
-
-godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_vector3 GDAPI godot_vector3_operator_subtract(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_vector3 GDAPI godot_vector3_operator_multiply_scalar(const godot_vector3 *p_self, const godot_real p_b);
-
-godot_vector3 GDAPI godot_vector3_operator_divide_vector(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_vector3 GDAPI godot_vector3_operator_divide_scalar(const godot_vector3 *p_self, const godot_real p_b);
-
-godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_self, const godot_vector3 *p_b);
-
-godot_vector3 GDAPI godot_vector3_operator_neg(const godot_vector3 *p_self);
-
-void GDAPI godot_vector3_set_axis(godot_vector3 *p_self, const godot_vector3_axis p_axis, const godot_real p_val);
-
-godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot_vector3_axis p_axis);
-
-// Vector3i
-
-void GDAPI godot_vector3i_new(godot_vector3i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_z);
-
-godot_string GDAPI godot_vector3i_as_string(const godot_vector3i *p_self);
-
-godot_vector3 GDAPI godot_vector3i_as_vector3(const godot_vector3i *p_self);
-
-godot_int GDAPI godot_vector3i_min_axis(const godot_vector3i *p_self);
-
-godot_int GDAPI godot_vector3i_max_axis(const godot_vector3i *p_self);
-
-godot_vector3i GDAPI godot_vector3i_abs(const godot_vector3i *p_self);
-
-godot_vector3i GDAPI godot_vector3i_sign(const godot_vector3i *p_self);
-
-godot_vector3i GDAPI godot_vector3i_operator_add(const godot_vector3i *p_self, const godot_vector3i *p_b);
-
-godot_vector3i GDAPI godot_vector3i_operator_subtract(const godot_vector3i *p_self, const godot_vector3i *p_b);
-
-godot_vector3i GDAPI godot_vector3i_operator_multiply_vector(const godot_vector3i *p_self, const godot_vector3i *p_b);
-
-godot_vector3i GDAPI godot_vector3i_operator_multiply_scalar(const godot_vector3i *p_self, const godot_int p_b);
-
-godot_vector3i GDAPI godot_vector3i_operator_divide_vector(const godot_vector3i *p_self, const godot_vector3i *p_b);
-
-godot_vector3i GDAPI godot_vector3i_operator_divide_scalar(const godot_vector3i *p_self, const godot_int p_b);
-
-godot_bool GDAPI godot_vector3i_operator_equal(const godot_vector3i *p_self, const godot_vector3i *p_b);
-
-godot_bool GDAPI godot_vector3i_operator_less(const godot_vector3i *p_self, const godot_vector3i *p_b);
-
-godot_vector3i GDAPI godot_vector3i_operator_neg(const godot_vector3i *p_self);
-
-void GDAPI godot_vector3i_set_axis(godot_vector3i *p_self, const godot_vector3_axis p_axis, const godot_int p_val);
-
-godot_int GDAPI godot_vector3i_get_axis(const godot_vector3i *p_self, const godot_vector3_axis p_axis);
+void GDAPI godot_vector3_new(godot_vector3 *p_self);
+void GDAPI godot_vector3i_new(godot_vector3i *p_self);
+godot_real_t GDAPI *godot_vector3_operator_index(godot_vector3 *p_self, godot_int p_index);
+const godot_real_t GDAPI *godot_vector3_operator_index_const(const godot_vector3 *p_self, godot_int p_index);
+int32_t GDAPI *godot_vector3i_operator_index(godot_vector3i *p_self, godot_int p_index);
+const int32_t GDAPI *godot_vector3i_operator_index_const(const godot_vector3i *p_self, godot_int p_index);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index cc12d58037..c97f5f0389 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,8 +58,10 @@ typedef enum {
GODOT_PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
GODOT_PROPERTY_HINT_LAYERS_2D_RENDER,
GODOT_PROPERTY_HINT_LAYERS_2D_PHYSICS,
+ GODOT_PROPERTY_HINT_LAYERS_2D_NAVIGATION,
GODOT_PROPERTY_HINT_LAYERS_3D_RENDER,
GODOT_PROPERTY_HINT_LAYERS_3D_PHYSICS,
+ GODOT_PROPERTY_HINT_LAYERS_3D_NAVIGATION,
GODOT_PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
GODOT_PROPERTY_HINT_DIR, ///< a directory path must be passed
GODOT_PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
diff --git a/modules/gdnative/include/net/godot_net.h b/modules/gdnative/include/net/godot_net.h
index 42804112f2..2fa576a5bf 100644
--- a/modules/gdnative/include/net/godot_net.h
+++ b/modules/gdnative/include/net/godot_net.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/include/net/godot_webrtc.h b/modules/gdnative/include/net/godot_webrtc.h
index 15e2df85cc..25aa72dae1 100644
--- a/modules/gdnative/include/net/godot_webrtc.h
+++ b/modules/gdnative/include/net/godot_webrtc.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h
index e4b1fd5eb0..cbd65e3772 100644
--- a/modules/gdnative/include/pluginscript/godot_pluginscript.h
+++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/include/text/godot_text.h b/modules/gdnative/include/text/godot_text.h
index 6885f2463d..86fc745134 100644
--- a/modules/gdnative/include/text/godot_text.h
+++ b/modules/gdnative/include/text/godot_text.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -74,11 +74,19 @@ typedef struct {
godot_rid (*create_font_system)(void *, const godot_string *, int);
godot_rid (*create_font_resource)(void *, const godot_string *, int);
godot_rid (*create_font_memory)(void *, const uint8_t *, size_t, godot_string *, int);
+ godot_rid (*create_font_bitmap)(void *, float, float, int);
+ void (*font_bitmap_add_texture)(void *, godot_rid *, const godot_object *);
+ void (*font_bitmap_add_char)(void *, godot_rid *, char32_t, int, const godot_rect2 *, const godot_vector2 *, float);
+ void (*font_bitmap_add_kerning_pair)(void *, godot_rid *, char32_t, char32_t, int);
float (*font_get_height)(void *, godot_rid *, int);
float (*font_get_ascent)(void *, godot_rid *, int);
float (*font_get_descent)(void *, godot_rid *, int);
float (*font_get_underline_position)(void *, godot_rid *, int);
float (*font_get_underline_thickness)(void *, godot_rid *, int);
+ int (*font_get_spacing_space)(void *, godot_rid *);
+ void (*font_set_spacing_space)(void *, godot_rid *, int);
+ int (*font_get_spacing_glyph)(void *, godot_rid *);
+ void (*font_set_spacing_glyph)(void *, godot_rid *, int);
void (*font_set_antialiased)(void *, godot_rid *, bool);
bool (*font_get_antialiased)(void *, godot_rid *);
godot_dictionary (*font_get_feature_list)(void *, godot_rid *);
@@ -175,8 +183,8 @@ void GDAPI godot_glyph_set_flags(godot_glyph *p_self, godot_int p_flags);
godot_vector2 GDAPI godot_glyph_get_offset(const godot_glyph *p_self);
void GDAPI godot_glyph_set_offset(godot_glyph *p_self, const godot_vector2 *p_offset);
-godot_real GDAPI godot_glyph_get_advance(const godot_glyph *p_self);
-void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_real p_advance);
+godot_float GDAPI godot_glyph_get_advance(const godot_glyph *p_self);
+void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_float p_advance);
godot_rid GDAPI godot_glyph_get_font(const godot_glyph *p_self);
void GDAPI godot_glyph_set_font(godot_glyph *p_self, godot_rid *p_font);
@@ -218,7 +226,7 @@ godot_glyph GDAPI godot_packed_glyph_array_get(const godot_packed_glyph_array *p
godot_int GDAPI godot_packed_glyph_array_size(const godot_packed_glyph_array *p_self);
-godot_bool GDAPI godot_packed_glyph_array_empty(const godot_packed_glyph_array *p_self);
+godot_bool GDAPI godot_packed_glyph_array_is_empty(const godot_packed_glyph_array *p_self);
void GDAPI godot_packed_glyph_array_destroy(godot_packed_glyph_array *p_self);
diff --git a/modules/gdnative/include/videodecoder/godot_videodecoder.h b/modules/gdnative/include/videodecoder/godot_videodecoder.h
index 16c92abd22..dc2cf5ec07 100644
--- a/modules/gdnative/include/videodecoder/godot_videodecoder.h
+++ b/modules/gdnative/include/videodecoder/godot_videodecoder.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,11 +49,11 @@ typedef struct
const char *(*get_plugin_name)();
const char **(*get_supported_extensions)(int *count);
godot_bool (*open_file)(void *, void *); // data struct, and a FileAccess pointer
- godot_real (*get_length)(const void *);
- godot_real (*get_playback_position)(const void *);
- void (*seek)(void *, godot_real);
+ godot_float (*get_length)(const void *);
+ godot_float (*get_playback_position)(const void *);
+ void (*seek)(void *, godot_float);
void (*set_audio_track)(void *, godot_int);
- void (*update)(void *, godot_real);
+ void (*update)(void *, godot_float);
godot_packed_byte_array *(*get_videoframe)(void *);
godot_int (*get_audioframe)(void *, float *, int);
godot_int (*get_channels)(const void *);
diff --git a/modules/gdnative/include/xr/godot_xr.h b/modules/gdnative/include/xr/godot_xr.h
index 22f7f021c4..7eaf1c7ec3 100644
--- a/modules/gdnative/include/xr/godot_xr.h
+++ b/modules/gdnative/include/xr/godot_xr.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,7 +58,7 @@ typedef struct {
void (*uninitialize)(void *);
godot_vector2 (*get_render_targetsize)(const void *);
godot_transform (*get_transform_for_eye)(void *, godot_int, godot_transform *);
- void (*fill_projection_for_eye)(void *, godot_real *, godot_int, godot_real, godot_real, godot_real);
+ void (*fill_projection_for_eye)(void *, godot_float *, godot_int, godot_float, godot_float, godot_float);
void (*commit_for_eye)(void *, godot_int, godot_rid *, godot_rect2 *);
void (*process)(void *);
godot_int (*get_external_texture_for_eye)(void *, godot_int);
@@ -69,7 +69,7 @@ typedef struct {
void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_interface);
// helper functions to access XRServer data
-godot_real GDAPI godot_xr_get_worldscale();
+godot_float GDAPI godot_xr_get_worldscale();
godot_transform GDAPI godot_xr_get_reference_frame();
// helper functions for rendering
@@ -81,8 +81,8 @@ godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, g
void GDAPI godot_xr_remove_controller(godot_int p_controller_id);
void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed);
-void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative);
-godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id);
+void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_float p_value, godot_bool p_can_be_negative);
+godot_float GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 6f2f9bfea9..3e75478cd8 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,6 +36,7 @@
#include "core/core_constants.h"
#include "core/object/class_db.h"
#include "core/os/file_access.h"
+#include "core/string/string_builder.h"
#include "core/templates/pair.h"
// helper stuff
@@ -65,14 +66,14 @@ struct MethodAPI {
Map<int, Variant> default_arguments;
- int argument_count;
- bool has_varargs;
- bool is_editor;
- bool is_noscript;
- bool is_const;
- bool is_reverse;
- bool is_virtual;
- bool is_from_script;
+ int argument_count = 0;
+ bool has_varargs = false;
+ bool is_editor = false;
+ bool is_noscript = false;
+ bool is_const = false;
+ bool is_reverse = false;
+ bool is_virtual = false;
+ bool is_from_script = false;
};
struct PropertyAPI {
@@ -80,12 +81,14 @@ struct PropertyAPI {
String getter;
String setter;
String type;
- int index;
+ int index = 0;
};
struct ConstantAPI {
String constant_name;
- int constant_value;
+ int constant_value = 0;
+ Variant builtin_constant_value; // For builtin types;
+ String builtin_constant_type; // For builtin types;
};
struct SignalAPI {
@@ -100,23 +103,35 @@ struct EnumAPI {
List<Pair<int, String>> values;
};
+struct OperatorAPI { // For builtin types;
+ String name;
+ int oper = Variant::OP_MAX;
+ String other_type;
+ String return_type;
+};
+
struct ClassAPI {
String class_name;
String super_class_name;
- ClassDB::APIType api_type;
+ ClassDB::APIType api_type = ClassDB::API_NONE;
- bool is_singleton;
+ bool is_singleton = false;
String singleton_name;
- bool is_instanciable;
+ bool is_instantiable = false;
// @Unclear
- bool is_reference;
+ bool is_reference = false;
+ bool has_indexing = false; // For builtin types.
+ String indexed_type; // For builtin types.
+ bool is_keyed = false; // For builtin types.
List<MethodAPI> methods;
+ List<MethodAPI> constructors; // For builtin types.
List<PropertyAPI> properties;
List<ConstantAPI> constants;
List<SignalAPI> signals_;
List<EnumAPI> enums;
+ List<OperatorAPI> operators; // For builtin types.
};
static String get_type_name(const PropertyInfo &info) {
@@ -127,7 +142,7 @@ static String get_type_name(const PropertyInfo &info) {
return info.class_name;
}
if (info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
- return info.hint_string;
+ return info.class_name;
}
if (info.type == Variant::NIL && (info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) {
return "Variant";
@@ -180,13 +195,34 @@ List<ClassAPI> generate_c_api_classes() {
global_constants_api.api_type = ClassDB::API_CORE;
global_constants_api.is_singleton = true;
global_constants_api.singleton_name = "CoreConstants";
- global_constants_api.is_instanciable = false;
+ global_constants_api.is_instantiable = false;
const int constants_count = CoreConstants::get_global_constant_count();
+
+ Map<StringName, EnumAPI> enum_api_map;
for (int i = 0; i < constants_count; ++i) {
- ConstantAPI constant_api;
- constant_api.constant_name = CoreConstants::get_global_constant_name(i);
- constant_api.constant_value = CoreConstants::get_global_constant_value(i);
- global_constants_api.constants.push_back(constant_api);
+ StringName enum_name = CoreConstants::get_global_constant_enum(i);
+ String name = String(CoreConstants::get_global_constant_name(i));
+ int value = CoreConstants::get_global_constant_value(i);
+
+ if (enum_name == StringName()) {
+ ConstantAPI constant_api;
+ constant_api.constant_name = name;
+ constant_api.constant_value = value;
+ global_constants_api.constants.push_back(constant_api);
+ } else {
+ EnumAPI enum_api;
+ if (enum_api_map.has(enum_name)) {
+ enum_api = enum_api_map[enum_name];
+ } else {
+ enum_api.name = String(enum_name);
+ }
+ enum_api.values.push_back(Pair(value, name));
+
+ enum_api_map[enum_name] = enum_api;
+ }
+ }
+ for (const Map<StringName, EnumAPI>::Element *E = enum_api_map.front(); E; E = E->next()) {
+ global_constants_api.enums.push_back(E->get());
}
global_constants_api.constants.sort_custom<ConstantAPIComparator>();
api.push_back(global_constants_api);
@@ -195,6 +231,10 @@ List<ClassAPI> generate_c_api_classes() {
for (List<StringName>::Element *e = classes.front(); e != nullptr; e = e->next()) {
StringName class_name = e->get();
+ if (!ClassDB::is_class_exposed(class_name)) {
+ continue;
+ }
+
ClassAPI class_api;
class_api.api_type = ClassDB::get_api_type(e->get());
class_api.class_name = class_name;
@@ -209,7 +249,7 @@ List<ClassAPI> generate_c_api_classes() {
class_api.singleton_name = name;
}
}
- class_api.is_instanciable = !class_api.is_singleton && ClassDB::can_instance(class_name);
+ class_api.is_instantiable = !class_api.is_singleton && ClassDB::can_instance(class_name);
{
List<StringName> inheriters;
@@ -290,12 +330,14 @@ List<ClassAPI> generate_c_api_classes() {
property_api.type = p->get().name.get_slice(":", 1);
property_api.name = p->get().name.get_slice(":", 0);
} else {
- property_api.type = get_type_name(p->get());
+ MethodInfo minfo;
+ ClassDB::get_method_info(class_name, property_api.getter, &minfo, true, false);
+ property_api.type = get_type_name(minfo.return_val);
}
property_api.index = ClassDB::get_property_index(class_name, p->get().name);
- if (!property_api.setter.empty() || !property_api.getter.empty()) {
+ if (!property_api.setter.is_empty() || !property_api.getter.is_empty()) {
class_api.properties.push_back(property_api);
}
}
@@ -352,7 +394,7 @@ List<ClassAPI> generate_c_api_classes() {
arg_type = arg_info.name.get_slice(":", 1);
arg_name = arg_info.name.get_slice(":", 0);
} else if (arg_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
- arg_type = arg_info.hint_string;
+ arg_type = arg_info.class_name;
} else if (arg_info.type == Variant::NIL) {
arg_type = "Variant";
} else if (arg_info.type == Variant::OBJECT) {
@@ -402,6 +444,192 @@ List<ClassAPI> generate_c_api_classes() {
}
/*
+ * Reads the builtin Variant API to a list
+ */
+List<ClassAPI> generate_c_builtin_api_types() {
+ List<ClassAPI> api;
+
+ // Special class for the utility methods.
+ {
+ ClassAPI utility_api;
+ utility_api.class_name = "Utilities";
+ utility_api.is_instantiable = false;
+
+ List<StringName> utility_functions;
+ Variant::get_utility_function_list(&utility_functions);
+ for (const List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) {
+ const StringName &function_name = E->get();
+
+ MethodAPI function_api;
+ function_api.method_name = function_name;
+ function_api.has_varargs = Variant::is_utility_function_vararg(function_name);
+ function_api.argument_count = function_api.has_varargs ? 0 : Variant::get_utility_function_argument_count(function_name);
+ function_api.is_const = Variant::get_utility_function_type(function_name) == Variant::UTILITY_FUNC_TYPE_MATH;
+
+ for (int i = 0; i < function_api.argument_count; i++) {
+ function_api.argument_names.push_back(Variant::get_utility_function_argument_name(function_name, i));
+ Variant::Type arg_type = Variant::get_utility_function_argument_type(function_name, i);
+ function_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type));
+ }
+
+ if (Variant::has_utility_function_return_value(function_name)) {
+ Variant::Type ret_type = Variant::get_utility_function_return_type(function_name);
+ function_api.return_type = ret_type == Variant::NIL ? "Variant" : Variant::get_type_name(ret_type);
+ } else {
+ function_api.return_type = "void";
+ }
+
+ utility_api.methods.push_back(function_api);
+ }
+
+ api.push_back(utility_api);
+ }
+
+ for (int t = 0; t < Variant::VARIANT_MAX; t++) {
+ Variant::Type type = (Variant::Type)t;
+
+ ClassAPI class_api;
+ class_api.class_name = Variant::get_type_name(type);
+ class_api.is_instantiable = true;
+ class_api.has_indexing = Variant::has_indexing(type);
+ class_api.indexed_type = Variant::get_type_name(Variant::get_indexed_element_type(type));
+ class_api.is_keyed = Variant::is_keyed(type);
+ // Types that are passed by reference.
+ switch (type) {
+ case Variant::OBJECT:
+ case Variant::DICTIONARY:
+ case Variant::ARRAY:
+ case Variant::PACKED_BYTE_ARRAY:
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
+ case Variant::PACKED_VECTOR2_ARRAY:
+ case Variant::PACKED_VECTOR3_ARRAY:
+ case Variant::PACKED_COLOR_ARRAY:
+ class_api.is_reference = true;
+ break;
+ default:
+ class_api.is_reference = false;
+ break;
+ }
+
+ // Methods.
+
+ List<StringName> methods;
+ Variant::get_builtin_method_list(type, &methods);
+ for (const List<StringName>::Element *E = methods.front(); E; E = E->next()) {
+ const StringName &method_name = E->get();
+
+ MethodAPI method_api;
+
+ method_api.method_name = method_name;
+ method_api.argument_count = Variant::get_builtin_method_argument_count(type, method_name);
+ method_api.has_varargs = Variant::is_builtin_method_vararg(type, method_name);
+ method_api.is_const = Variant::is_builtin_method_const(type, method_name);
+
+ for (int i = 0; i < method_api.argument_count; i++) {
+ method_api.argument_names.push_back(Variant::get_builtin_method_argument_name(type, method_name, i));
+ Variant::Type arg_type = Variant::get_builtin_method_argument_type(type, method_name, i);
+ method_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type));
+ }
+
+ Vector<Variant> default_arguments = Variant::get_builtin_method_default_arguments(type, method_name);
+
+ int default_start = method_api.argument_names.size() - default_arguments.size();
+
+ for (int i = 0; i < default_arguments.size(); i++) {
+ method_api.default_arguments[default_start + i] = default_arguments[i];
+ }
+
+ if (Variant::has_builtin_method_return_value(type, method_name)) {
+ Variant::Type ret_type = Variant::get_builtin_method_return_type(type, method_name);
+ method_api.return_type = ret_type == Variant::NIL ? "Variant" : Variant::get_type_name(ret_type);
+ } else {
+ method_api.return_type = "void";
+ }
+
+ class_api.methods.push_back(method_api);
+ }
+
+ // Constructors.
+
+ for (int c = 0; c < Variant::get_constructor_count(type); c++) {
+ MethodAPI constructor_api;
+
+ constructor_api.method_name = Variant::get_type_name(type);
+ constructor_api.argument_count = Variant::get_constructor_argument_count(type, c);
+ constructor_api.return_type = Variant::get_type_name(type);
+
+ for (int i = 0; i < constructor_api.argument_count; i++) {
+ constructor_api.argument_names.push_back(Variant::get_constructor_argument_name(type, c, i));
+ Variant::Type arg_type = Variant::get_constructor_argument_type(type, c, i);
+ constructor_api.argument_types.push_back(arg_type == Variant::NIL ? "Variant" : Variant::get_type_name(arg_type));
+ }
+
+ class_api.constructors.push_back(constructor_api);
+ }
+
+ // Constants.
+
+ List<StringName> constants;
+ Variant::get_constants_for_type(type, &constants);
+ for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) {
+ const StringName &constant_name = E->get();
+ ConstantAPI constant_api;
+
+ constant_api.constant_name = constant_name;
+ constant_api.builtin_constant_value = Variant::get_constant_value(type, constant_name);
+ constant_api.builtin_constant_type = Variant::get_type_name(constant_api.builtin_constant_value.get_type());
+
+ class_api.constants.push_back(constant_api);
+ }
+
+ // Members.
+
+ List<StringName> members;
+ Variant::get_member_list(type, &members);
+ for (const List<StringName>::Element *E = members.front(); E; E = E->next()) {
+ const StringName &member_name = E->get();
+
+ PropertyAPI member_api;
+ member_api.name = member_name;
+ Variant::Type member_type = Variant::get_member_type(type, member_name);
+ member_api.type = member_type == Variant::NIL ? "Variant" : Variant::get_type_name(member_type);
+
+ class_api.properties.push_back(member_api);
+ }
+
+ // Operators.
+
+ for (int op = 0; op < Variant::OP_MAX; op++) {
+ Variant::Operator oper = (Variant::Operator)op;
+
+ for (int ot = 0; ot < Variant::VARIANT_MAX; ot++) {
+ Variant::Type other_type = (Variant::Type)ot;
+
+ if (!Variant::get_validated_operator_evaluator(oper, type, other_type)) {
+ continue;
+ }
+
+ OperatorAPI oper_api;
+ oper_api.name = Variant::get_operator_name(oper);
+ oper_api.oper = oper;
+ oper_api.other_type = Variant::get_type_name(other_type);
+ oper_api.return_type = Variant::get_type_name(Variant::get_operator_return_type(oper, type, other_type));
+
+ class_api.operators.push_back(oper_api);
+ }
+ }
+
+ api.push_back(class_api);
+ }
+
+ return api;
+}
+
+/*
* Generates the JSON source from the API in p_api
*/
static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
@@ -421,9 +649,8 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
source.push_back(String("\t\t\"api_type\": \"") + (api.api_type == ClassDB::API_CORE ? "core" : (api.api_type == ClassDB::API_EDITOR ? "tools" : "none")) + "\",\n");
source.push_back(String("\t\t\"singleton\": ") + (api.is_singleton ? "true" : "false") + ",\n");
source.push_back("\t\t\"singleton_name\": \"" + api.singleton_name + "\",\n");
- source.push_back(String("\t\t\"instanciable\": ") + (api.is_instanciable ? "true" : "false") + ",\n");
+ source.push_back(String("\t\t\"instantiable\": ") + (api.is_instantiable ? "true" : "false") + ",\n");
source.push_back(String("\t\t\"is_reference\": ") + (api.is_reference ? "true" : "false") + ",\n");
- // @Unclear
source.push_back("\t\t\"constants\": {\n");
for (List<ConstantAPI>::Element *e = api.constants.front(); e; e = e->next()) {
@@ -508,6 +735,165 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
return source;
}
+static int indent_level = 0;
+
+static void append_indented(StringBuilder &p_source, const String &p_text) {
+ for (int i = 0; i < indent_level; i++) {
+ p_source.append("\t");
+ }
+ p_source.append(p_text);
+ p_source.append("\n");
+}
+
+static void append_indented(StringBuilder &p_source, const char *p_text) {
+ for (int i = 0; i < indent_level; i++) {
+ p_source.append("\t");
+ }
+ p_source.append(p_text);
+ p_source.append("\n");
+}
+
+static void write_builtin_method(StringBuilder &p_source, const MethodAPI &p_method) {
+ append_indented(p_source, vformat(R"("name": "%s",)", p_method.method_name));
+ append_indented(p_source, vformat(R"("return_type": "%s",)", p_method.return_type));
+ append_indented(p_source, vformat(R"("is_const": %s,)", p_method.is_const ? "true" : "false"));
+ append_indented(p_source, vformat(R"("has_varargs": %s,)", p_method.has_varargs ? "true" : "false"));
+
+ append_indented(p_source, R"("arguments": [)");
+ indent_level++;
+ for (int i = 0; i < p_method.argument_count; i++) {
+ append_indented(p_source, "{");
+ indent_level++;
+
+ append_indented(p_source, vformat(R"("name": "%s",)", p_method.argument_names[i]));
+ append_indented(p_source, vformat(R"("type": "%s",)", p_method.argument_types[i]));
+ append_indented(p_source, vformat(R"("has_default_value": %s,)", p_method.default_arguments.has(i) ? "true" : "false"));
+ append_indented(p_source, vformat(R"("default_value": "%s")", p_method.default_arguments.has(i) ? p_method.default_arguments[i].operator String() : ""));
+
+ indent_level--;
+ append_indented(p_source, i < p_method.argument_count - 1 ? "}," : "}");
+ }
+ indent_level--;
+ append_indented(p_source, "]");
+}
+
+static List<String> generate_c_builtin_api_json(const List<ClassAPI> &p_api) {
+ StringBuilder source;
+
+ source.append("[\n");
+
+ indent_level = 1;
+
+ for (const List<ClassAPI>::Element *C = p_api.front(); C; C = C->next()) {
+ const ClassAPI &class_api = C->get();
+ append_indented(source, "{");
+ indent_level++;
+
+ append_indented(source, vformat(R"("name": "%s",)", class_api.class_name));
+ append_indented(source, vformat(R"("is_instantiable": %s,)", class_api.is_instantiable ? "true" : "false"));
+ append_indented(source, vformat(R"("is_reference": %s,)", class_api.is_reference ? "true" : "false"));
+ append_indented(source, vformat(R"("has_indexing": %s,)", class_api.has_indexing ? "true" : "false"));
+ append_indented(source, vformat(R"("indexed_type": "%s",)", class_api.has_indexing && class_api.indexed_type == "Nil" ? "Variant" : class_api.indexed_type));
+ append_indented(source, vformat(R"("is_keyed": %s,)", class_api.is_keyed ? "true" : "false"));
+
+ // Constructors.
+ append_indented(source, R"("constructors": [)");
+ indent_level++;
+ for (const List<MethodAPI>::Element *E = class_api.constructors.front(); E; E = E->next()) {
+ const MethodAPI &constructor = E->get();
+ append_indented(source, "{");
+ indent_level++;
+
+ write_builtin_method(source, constructor);
+
+ indent_level--;
+ append_indented(source, E->next() ? "}," : "}");
+ }
+ indent_level--;
+ append_indented(source, "],");
+
+ // Constants.
+ append_indented(source, R"("constants": [)");
+ indent_level++;
+ for (const List<ConstantAPI>::Element *E = class_api.constants.front(); E; E = E->next()) {
+ const ConstantAPI &constant = E->get();
+ append_indented(source, "{");
+ indent_level++;
+
+ append_indented(source, vformat(R"("name": "%s",)", constant.constant_name));
+ append_indented(source, vformat(R"("type": "%s",)", constant.builtin_constant_type));
+ append_indented(source, vformat(R"("value": "%s")", constant.builtin_constant_value.operator String()));
+
+ indent_level--;
+ append_indented(source, E->next() ? "}," : "}");
+ }
+ indent_level--;
+ append_indented(source, "],");
+
+ // Methods.
+ append_indented(source, R"("methods": [)");
+ indent_level++;
+ for (const List<MethodAPI>::Element *E = class_api.methods.front(); E; E = E->next()) {
+ const MethodAPI &method = E->get();
+ append_indented(source, "{");
+ indent_level++;
+
+ write_builtin_method(source, method);
+
+ indent_level--;
+ append_indented(source, E->next() ? "}," : "}");
+ }
+ indent_level--;
+ append_indented(source, "],");
+
+ // Members.
+ append_indented(source, R"("members": [)");
+ indent_level++;
+ for (const List<PropertyAPI>::Element *E = class_api.properties.front(); E; E = E->next()) {
+ const PropertyAPI &member = E->get();
+ append_indented(source, "{");
+ indent_level++;
+
+ append_indented(source, vformat(R"("name": "%s",)", member.name));
+ append_indented(source, vformat(R"("type": "%s")", member.type));
+
+ indent_level--;
+ append_indented(source, E->next() ? "}," : "}");
+ }
+ indent_level--;
+ append_indented(source, "],");
+
+ // Operators.
+ append_indented(source, R"("operators": [)");
+ indent_level++;
+ for (const List<OperatorAPI>::Element *E = class_api.operators.front(); E; E = E->next()) {
+ const OperatorAPI &oper = E->get();
+ append_indented(source, "{");
+ indent_level++;
+
+ append_indented(source, vformat(R"("name": "%s",)", oper.name));
+ append_indented(source, vformat(R"("operator": %d,)", oper.oper));
+ append_indented(source, vformat(R"("other_type": "%s",)", oper.other_type));
+ append_indented(source, vformat(R"("return_type": "%s")", oper.return_type));
+
+ indent_level--;
+ append_indented(source, E->next() ? "}," : "}");
+ }
+ indent_level--;
+ append_indented(source, "]");
+
+ indent_level--;
+ append_indented(source, C->next() ? "}," : "}");
+ }
+
+ indent_level--;
+ source.append("]\n");
+
+ List<String> result;
+ result.push_back(source.as_string());
+ return result;
+}
+
#endif
/*
@@ -526,3 +912,19 @@ Error generate_c_api(const String &p_path) {
return save_file(p_path, json_source);
#endif
}
+/*
+ * Saves the builtin Godot API to a JSON file located at
+ * p_path
+ */
+Error generate_c_builtin_api(const String &p_path) {
+#ifndef TOOLS_ENABLED
+ return ERR_BUG;
+#else
+
+ List<ClassAPI> api = generate_c_builtin_api_types();
+
+ List<String> json_source = generate_c_builtin_api_json(api);
+
+ return save_file(p_path, json_source);
+#endif
+}
diff --git a/modules/gdnative/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h
index 8555af5215..611abb2a2d 100644
--- a/modules/gdnative/nativescript/api_generator.h
+++ b/modules/gdnative/nativescript/api_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,5 +35,6 @@
#include "core/typedefs.h"
Error generate_c_api(const String &p_path);
+Error generate_c_builtin_api(const String &p_path);
#endif // API_GENERATOR_H
diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp
index 411acbe1ad..b2abf8b8ae 100644
--- a/modules/gdnative/nativescript/godot_nativescript.cpp
+++ b/modules/gdnative/nativescript/godot_nativescript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 0939cfd06a..1bdbb0b03b 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -717,7 +717,7 @@ String NativeScript::get_property_documentation(const StringName &p_path) const
}
Variant NativeScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- if (lib_path.empty() || class_name.empty() || library.is_null()) {
+ if (lib_path.is_empty() || class_name.is_empty() || library.is_null()) {
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
@@ -1196,13 +1196,6 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) {
NativeScriptLanguage::NativeScriptLanguage() {
NativeScriptLanguage::singleton = this;
-#ifndef NO_THREADS
- has_objects_to_register = false;
-#endif
-
-#ifdef DEBUG_ENABLED
- profiling = false;
-#endif
_init_call_type = "nativescript_init";
_init_call_name = "nativescript_init";
@@ -1257,6 +1250,15 @@ void NativeScriptLanguage::init() {
}
exit(0);
}
+
+ E = args.find("--gdnative-generate-json-builtin-api");
+
+ if (E && E->next()) {
+ if (generate_c_builtin_api(E->next()->get()) != OK) {
+ ERR_PRINT("Failed to generate C builtin API\n");
+ }
+ exit(0);
+ }
#endif
#ifdef TOOLS_ENABLED
@@ -1668,7 +1670,7 @@ void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeSc
MutexLock lock(mutex);
libs_to_init.insert(lib);
scripts_to_register.insert(script);
- has_objects_to_register = true;
+ has_objects_to_register.set();
}
#endif
@@ -1724,6 +1726,12 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) {
S->get().erase(script);
if (S->get().size() == 0) {
library_script_users.erase(S);
+
+ Map<String, Ref<GDNative>>::Element *G = library_gdnatives.find(script->lib_path);
+ if (G && G->get()->get_library()->is_reloadable()) {
+ G->get()->terminate();
+ library_gdnatives.erase(G);
+ }
}
}
#ifndef NO_THREADS
@@ -1751,7 +1759,7 @@ void NativeScriptLanguage::call_libraries_cb(const StringName &name) {
void NativeScriptLanguage::frame() {
#ifndef NO_THREADS
- if (has_objects_to_register) {
+ if (has_objects_to_register.is_set()) {
MutexLock lock(mutex);
for (Set<Ref<GDNativeLibrary>>::Element *L = libs_to_init.front(); L; L = L->next()) {
init_library(L->get());
@@ -1761,7 +1769,7 @@ void NativeScriptLanguage::frame() {
register_script(S->get());
}
scripts_to_register.clear();
- has_objects_to_register = false;
+ has_objects_to_register.clear();
}
#endif
@@ -1800,7 +1808,7 @@ bool NativeScriptLanguage::handles_global_class_type(const String &p_type) const
}
String NativeScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const {
- if (!p_path.empty()) {
+ if (!p_path.is_empty()) {
Ref<NativeScript> script = ResourceLoader::load(p_path, "NativeScript");
if (script.is_valid()) {
if (r_base_type) {
@@ -1932,7 +1940,7 @@ void NativeReloadNode::_notification(int p_what) {
#endif
}
-RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_no_cache) {
return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error);
}
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index e91d9b7bfb..d6ba2bbec1 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,6 +40,7 @@
#include "core/os/thread_safe.h"
#include "core/templates/oa_hash_map.h"
#include "core/templates/ordered_hash_map.h"
+#include "core/templates/safe_refcount.h"
#include "core/templates/self_list.h"
#include "scene/main/node.h"
@@ -51,8 +52,8 @@ struct NativeScriptDesc {
struct Method {
godot_nativescript_instance_method method;
MethodInfo info;
- int rpc_mode;
- uint16_t rpc_method_id;
+ int rpc_mode = 0;
+ uint16_t rpc_method_id = 0;
String documentation;
};
@@ -61,7 +62,7 @@ struct NativeScriptDesc {
godot_nativescript_property_get_func getter;
PropertyInfo info;
Variant default_value;
- int rset_mode;
+ int rset_mode = 0;
uint16_t rset_property_id;
String documentation;
};
@@ -78,7 +79,7 @@ struct NativeScriptDesc {
Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals
StringName base;
StringName base_native_type;
- NativeScriptDesc *base_data;
+ NativeScriptDesc *base_data = nullptr;
godot_nativescript_instance_create_func create_func;
godot_nativescript_instance_destroy_func destroy_func;
@@ -86,7 +87,7 @@ struct NativeScriptDesc {
const void *type_tag = nullptr;
- bool is_tool;
+ bool is_tool = false;
inline NativeScriptDesc() {
zeromem(&create_func, sizeof(godot_nativescript_instance_create_func));
@@ -254,7 +255,7 @@ class NativeScriptLanguage : public ScriptLanguage {
private:
static NativeScriptLanguage *singleton;
- int lang_idx;
+ int lang_idx = 0;
void _unload_stuff(bool p_reload = false);
@@ -262,7 +263,7 @@ private:
#ifndef NO_THREADS
Set<Ref<GDNativeLibrary>> libs_to_init;
Set<NativeScript *> scripts_to_register;
- volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed
+ SafeFlag has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed
void defer_init_library(Ref<GDNativeLibrary> lib, NativeScript *script);
#endif
@@ -279,19 +280,19 @@ private:
struct ProfileData {
StringName signature;
- uint64_t call_count;
- uint64_t self_time;
- uint64_t total_time;
- uint64_t frame_call_count;
- uint64_t frame_self_time;
- uint64_t frame_total_time;
- uint64_t last_frame_call_count;
- uint64_t last_frame_self_time;
- uint64_t last_frame_total_time;
+ uint64_t call_count = 0;
+ uint64_t self_time = 0;
+ uint64_t total_time = 0;
+ uint64_t frame_call_count = 0;
+ uint64_t frame_self_time = 0;
+ uint64_t frame_total_time = 0;
+ uint64_t last_frame_call_count = 0;
+ uint64_t last_frame_self_time = 0;
+ uint64_t last_frame_total_time = 0;
};
Map<StringName, ProfileData> profile_data;
- bool profiling;
+ bool profiling = false;
public:
// These two maps must only be touched on the main thread
@@ -402,7 +403,7 @@ public:
class ResourceFormatLoaderNativeScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp
index ac8c7ab2fd..0353ab2092 100644
--- a/modules/gdnative/nativescript/register_types.cpp
+++ b/modules/gdnative/nativescript/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/nativescript/register_types.h b/modules/gdnative/nativescript/register_types.h
index 088bf38dd5..d12ac9eda3 100644
--- a/modules/gdnative/nativescript/register_types.h
+++ b/modules/gdnative/nativescript/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.cpp b/modules/gdnative/net/multiplayer_peer_gdnative.cpp
index 997eec6425..8b5fc8db5c 100644
--- a/modules/gdnative/net/multiplayer_peer_gdnative.cpp
+++ b/modules/gdnative/net/multiplayer_peer_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.h b/modules/gdnative/net/multiplayer_peer_gdnative.h
index 64d764029f..593b2534dd 100644
--- a/modules/gdnative/net/multiplayer_peer_gdnative.h
+++ b/modules/gdnative/net/multiplayer_peer_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/packet_peer_gdnative.cpp b/modules/gdnative/net/packet_peer_gdnative.cpp
index 6bb21cb48d..3bcdfed8ff 100644
--- a/modules/gdnative/net/packet_peer_gdnative.cpp
+++ b/modules/gdnative/net/packet_peer_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/packet_peer_gdnative.h b/modules/gdnative/net/packet_peer_gdnative.h
index 00de8f7f4c..29013f9367 100644
--- a/modules/gdnative/net/packet_peer_gdnative.h
+++ b/modules/gdnative/net/packet_peer_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/register_types.cpp b/modules/gdnative/net/register_types.cpp
index 4e48a43210..645c43b7e3 100644
--- a/modules/gdnative/net/register_types.cpp
+++ b/modules/gdnative/net/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/register_types.h b/modules/gdnative/net/register_types.h
index 70b266f9b9..c99c6f6fbf 100644
--- a/modules/gdnative/net/register_types.h
+++ b/modules/gdnative/net/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/stream_peer_gdnative.cpp b/modules/gdnative/net/stream_peer_gdnative.cpp
index 9dcb184115..72ab72323d 100644
--- a/modules/gdnative/net/stream_peer_gdnative.cpp
+++ b/modules/gdnative/net/stream_peer_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/stream_peer_gdnative.h b/modules/gdnative/net/stream_peer_gdnative.h
index 302fb48012..dd5abceb83 100644
--- a/modules/gdnative/net/stream_peer_gdnative.h
+++ b/modules/gdnative/net/stream_peer_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/net/webrtc_gdnative.cpp b/modules/gdnative/net/webrtc_gdnative.cpp
index d8c3ddc5f8..76ccbad009 100644
--- a/modules/gdnative/net/webrtc_gdnative.cpp
+++ b/modules/gdnative/net/webrtc_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp
index 0942fb40a8..432aa80325 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h
index 76ff9f7097..536eb550e0 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.h
+++ b/modules/gdnative/pluginscript/pluginscript_instance.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,10 +44,10 @@ class PluginScriptInstance : public ScriptInstance {
private:
Ref<PluginScript> _script;
- Object *_owner;
+ Object *_owner = nullptr;
Variant _owner_variant;
- godot_pluginscript_instance_data *_data;
- const godot_pluginscript_instance_desc *_desc;
+ godot_pluginscript_instance_data *_data = nullptr;
+ const godot_pluginscript_instance_desc *_desc = nullptr;
public:
_FORCE_INLINE_ Object *get_owner() { return _owner; }
diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp
index df685e716f..3ed1dcaca9 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_language.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -407,7 +407,7 @@ bool PluginScriptLanguage::handles_global_class_type(const String &p_type) const
}
String PluginScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const {
- if (!p_path.empty()) {
+ if (!p_path.is_empty()) {
Ref<PluginScript> script = ResourceLoader::load(p_path, "PluginScript");
if (script.is_valid()) {
if (r_base_type) {
diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h
index 7548eba4a0..226b039265 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.h
+++ b/modules/gdnative/pluginscript/pluginscript_language.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp
index 4feee4f4a5..f2165cd225 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,7 +39,7 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL
_language = language;
}
-RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h
index 7d80f4c733..e5d665c186 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.h
+++ b/modules/gdnative/pluginscript/pluginscript_loader.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,7 @@ class ResourceFormatLoaderPluginScript : public ResourceFormatLoader {
public:
ResourceFormatLoaderPluginScript(PluginScriptLanguage *language);
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
index d69ab2fcb7..31e6a81975 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h
index 12d93cc407..1c86f2056d 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.h
+++ b/modules/gdnative/pluginscript/pluginscript_script.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp
index b354c23a9e..b94538b2f7 100644
--- a/modules/gdnative/pluginscript/register_types.cpp
+++ b/modules/gdnative/pluginscript/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/pluginscript/register_types.h b/modules/gdnative/pluginscript/register_types.h
index c6a64b4f40..2118f668e9 100644
--- a/modules/gdnative/pluginscript/register_types.h
+++ b/modules/gdnative/pluginscript/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index b88bf58256..31f4fecb19 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/register_types.h b/modules/gdnative/register_types.h
index b5c182f8b7..662c638442 100644
--- a/modules/gdnative/register_types.h
+++ b/modules/gdnative/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/tests/test_string.h b/modules/gdnative/tests/test_string.h
deleted file mode 100644
index 2b1aa5bf28..0000000000
--- a/modules/gdnative/tests/test_string.h
+++ /dev/null
@@ -1,1979 +0,0 @@
-/*************************************************************************/
-/* test_string.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef TEST_GDNATIVE_STRING_H
-#define TEST_GDNATIVE_STRING_H
-
-namespace TestGDNativeString {
-
-#include "gdnative/string.h"
-
-#include "tests/test_macros.h"
-
-int u32scmp(const char32_t *l, const char32_t *r) {
- for (; *l == *r && *l && *r; l++, r++)
- ;
- return *l - *r;
-}
-
-TEST_CASE("[GDNative String] Construct from Latin-1 char string") {
- godot_string s;
-
- godot_string_new_with_latin1_chars(&s, "Hello");
- CHECK(u32scmp(godot_string_get_data(&s), U"Hello") == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_latin1_chars_and_len(&s, "Hello", 3);
- CHECK(u32scmp(godot_string_get_data(&s), U"Hel") == 0);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Construct from wchar_t string") {
- godot_string s;
-
- godot_string_new_with_wide_chars(&s, L"Give me");
- CHECK(u32scmp(godot_string_get_data(&s), U"Give me") == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_wide_chars_and_len(&s, L"Give me", 3);
- CHECK(u32scmp(godot_string_get_data(&s), U"Giv") == 0);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Construct from UTF-8 char string") {
- static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
- static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x304A, 0 };
- static const uint8_t u8str[] = { 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
-
- godot_string s;
-
- godot_string_new_with_utf8_chars(&s, (const char *)u8str);
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_utf8_chars_and_len(&s, (const char *)u8str, 5);
- CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_utf32_chars(&s, u32str);
- godot_char_string cs = godot_string_utf8(&s);
- godot_string_parse_utf8(&s, godot_char_string_get_data(&cs));
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
- godot_char_string_destroy(&cs);
-
- godot_string_new_with_utf32_chars(&s, u32str);
- cs = godot_string_utf8(&s);
- godot_string_parse_utf8_with_len(&s, godot_char_string_get_data(&cs), godot_char_string_length(&cs));
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
- godot_char_string_destroy(&cs);
-}
-
-TEST_CASE("[GDNative String] Construct from UTF-8 string with BOM") {
- static const char32_t u32str[] = { 0x0045, 0x0020, 0x304A, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
- static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x304A, 0 };
- static const uint8_t u8str[] = { 0xEF, 0xBB, 0xBF, 0x45, 0x20, 0xE3, 0x81, 0x8A, 0xE3, 0x98, 0x8F, 0xE3, 0x82, 0x88, 0xE3, 0x81, 0x86, 0xF0, 0x9F, 0x8E, 0xA4, 0 };
-
- godot_string s;
-
- godot_string_new_with_utf8_chars(&s, (const char *)u8str);
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_utf8_chars_and_len(&s, (const char *)u8str, 8);
- CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Construct from UTF-16 string") {
- static const char32_t u32str[] = { 0x0045, 0x0020, 0x1F3A4, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
- static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x1F3A4, 0 };
- static const char16_t u16str[] = { 0x0045, 0x0020, 0xD83C, 0xDFA4, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
-
- godot_string s;
-
- godot_string_new_with_utf16_chars(&s, u16str);
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_utf16_chars_and_len(&s, u16str, 4);
- CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_utf32_chars(&s, u32str);
- godot_char16_string cs = godot_string_utf16(&s);
- godot_string_parse_utf16(&s, godot_char16_string_get_data(&cs));
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
- godot_char16_string_destroy(&cs);
-
- godot_string_new_with_utf32_chars(&s, u32str);
- cs = godot_string_utf16(&s);
- godot_string_parse_utf16_with_len(&s, godot_char16_string_get_data(&cs), godot_char16_string_length(&cs));
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
- godot_char16_string_destroy(&cs);
-}
-
-TEST_CASE("[GDNative String] Construct from UTF-16 string with BOM ") {
- static const char32_t u32str[] = { 0x0045, 0x0020, 0x1F3A4, 0x360F, 0x3088, 0x3046, 0x1F3A4, 0 };
- static const char32_t u32str_short[] = { 0x0045, 0x0020, 0x1F3A4, 0 };
- static const char16_t u16str[] = { 0xFEFF, 0x0045, 0x0020, 0xD83C, 0xDFA4, 0x360F, 0x3088, 0x3046, 0xD83C, 0xDFA4, 0 };
- static const char16_t u16str_swap[] = { 0xFFFE, 0x4500, 0x2000, 0x3CD8, 0xA4DF, 0x0F36, 0x8830, 0x4630, 0x3CD8, 0xA4DF, 0 };
-
- godot_string s;
-
- godot_string_new_with_utf16_chars(&s, u16str);
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_utf16_chars(&s, u16str_swap);
- CHECK(u32scmp(godot_string_get_data(&s), u32str) == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_utf16_chars_and_len(&s, u16str, 5);
- CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
- godot_string_destroy(&s);
-
- godot_string_new_with_utf16_chars_and_len(&s, u16str_swap, 5);
- CHECK(u32scmp(godot_string_get_data(&s), u32str_short) == 0);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Construct string copy") {
- godot_string s, t;
-
- godot_string_new_with_latin1_chars(&s, "Hello");
- godot_string_new_copy(&t, &s);
- CHECK(u32scmp(godot_string_get_data(&t), U"Hello") == 0);
- godot_string_destroy(&t);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Construct empty string") {
- godot_string s;
-
- godot_string_new(&s);
- CHECK(u32scmp(godot_string_get_data(&s), U"") == 0);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] ASCII/Latin-1") {
- godot_string s;
- godot_string_new_with_utf32_chars(&s, U"Primero Leche");
-
- godot_char_string cs = godot_string_ascii(&s);
- CHECK(strcmp(godot_char_string_get_data(&cs), "Primero Leche") == 0);
- godot_char_string_destroy(&cs);
-
- cs = godot_string_latin1(&s);
- CHECK(strcmp(godot_char_string_get_data(&cs), "Primero Leche") == 0);
- godot_char_string_destroy(&cs);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Comparisons (equal)") {
- godot_string s, t;
-
- godot_string_new_with_latin1_chars(&s, "Test Compare");
- godot_string_new_with_latin1_chars(&t, "Test Compare");
- CHECK(godot_string_operator_equal(&s, &t));
- godot_string_destroy(&s);
- godot_string_destroy(&t);
-}
-
-TEST_CASE("[GDNative String] Comparisons (operator <)") {
- godot_string s, t;
-
- godot_string_new_with_latin1_chars(&s, "Bees");
-
- godot_string_new_with_latin1_chars(&t, "Elephant");
- CHECK(godot_string_operator_less(&s, &t));
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "Amber");
- CHECK(!godot_string_operator_less(&s, &t));
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "Beatrix");
- CHECK(!godot_string_operator_less(&s, &t));
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Concatenation (operator +)") {
- godot_string s, t, x;
-
- godot_string_new_with_latin1_chars(&s, "Hel");
- godot_string_new_with_latin1_chars(&t, "lo");
- x = godot_string_operator_plus(&s, &t);
- CHECK(u32scmp(godot_string_get_data(&x), U"Hello") == 0);
- godot_string_destroy(&x);
- godot_string_destroy(&s);
- godot_string_destroy(&t);
-}
-
-TEST_CASE("[GDNative String] Testing size and length of string") {
- godot_string s;
-
- godot_string_new_with_latin1_chars(&s, "Mellon");
- CHECK(godot_string_length(&s) == 6);
- godot_string_destroy(&s);
-
- godot_string_new_with_latin1_chars(&s, "Mellon1");
- CHECK(godot_string_length(&s) == 7);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Testing for empty string") {
- godot_string s;
-
- godot_string_new_with_latin1_chars(&s, "Mellon");
- CHECK(!godot_string_empty(&s));
- godot_string_destroy(&s);
-
- godot_string_new_with_latin1_chars(&s, "");
- CHECK(godot_string_empty(&s));
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Test chr") {
- godot_string s;
-
- s = godot_string_chr('H');
- CHECK(u32scmp(godot_string_get_data(&s), U"H") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_chr(0x3012);
- CHECK(godot_string_operator_index_const(&s, 0) == 0x3012);
- godot_string_destroy(&s);
-
- ERR_PRINT_OFF
- s = godot_string_chr(0xd812);
- CHECK(godot_string_operator_index_const(&s, 0) == 0xfffd); // Unpaired UTF-16 surrogate
- godot_string_destroy(&s);
-
- s = godot_string_chr(0x20d812);
- CHECK(godot_string_operator_index_const(&s, 0) == 0xfffd); // Outside UTF-32 range
- godot_string_destroy(&s);
- ERR_PRINT_ON
-}
-
-TEST_CASE("[GDNative String] Operator []") {
- godot_string s;
-
- godot_string_new_with_latin1_chars(&s, "Hello");
- CHECK(*godot_string_operator_index(&s, 1) == 'e');
- CHECK(godot_string_operator_index_const(&s, 0) == 'H');
- CHECK(godot_string_ord_at(&s, 0) == 'H');
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Case function test") {
- godot_string s, t;
-
- godot_string_new_with_latin1_chars(&s, "MoMoNgA");
-
- t = godot_string_to_upper(&s);
- CHECK(u32scmp(godot_string_get_data(&t), U"MOMONGA") == 0);
- godot_string_destroy(&t);
-
- t = godot_string_to_lower(&s);
- CHECK(u32scmp(godot_string_get_data(&t), U"momonga") == 0);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Case compare function test") {
- godot_string s, t;
-
- godot_string_new_with_latin1_chars(&s, "MoMoNgA");
- godot_string_new_with_latin1_chars(&t, "momonga");
-
- CHECK(godot_string_casecmp_to(&s, &t) != 0);
- CHECK(godot_string_nocasecmp_to(&s, &t) == 0);
-
- godot_string_destroy(&s);
- godot_string_destroy(&t);
-}
-
-TEST_CASE("[GDNative String] Natural compare function test") {
- godot_string s, t;
-
- godot_string_new_with_latin1_chars(&s, "img2.png");
- godot_string_new_with_latin1_chars(&t, "img10.png");
-
- CHECK(godot_string_nocasecmp_to(&s, &t) > 0);
- CHECK(godot_string_naturalnocasecmp_to(&s, &t) < 0);
-
- godot_string_destroy(&s);
- godot_string_destroy(&t);
-}
-
-TEST_CASE("[GDNative String] hex_encode_buffer") {
- static const uint8_t u8str[] = { 0x45, 0xE3, 0x81, 0x8A, 0x8F, 0xE3 };
- godot_string s = godot_string_hex_encode_buffer(u8str, 6);
- CHECK(u32scmp(godot_string_get_data(&s), U"45e3818a8fe3") == 0);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Substr") {
- godot_string s, t;
- godot_string_new_with_latin1_chars(&s, "Killer Baby");
- t = godot_string_substr(&s, 3, 4);
- CHECK(u32scmp(godot_string_get_data(&t), U"ler ") == 0);
- godot_string_destroy(&t);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Find") {
- godot_string s, t;
- godot_string_new_with_latin1_chars(&s, "Pretty Woman Woman");
-
- godot_string_new_with_latin1_chars(&t, "Revenge of the Monster Truck");
- CHECK(godot_string_find(&s, &t) == -1);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "tty");
- CHECK(godot_string_find(&s, &t) == 3);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "Wo");
- CHECK(godot_string_find_from(&s, &t, 9) == 13);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "man");
- CHECK(godot_string_rfind(&s, &t) == 15);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Find no case") {
- godot_string s, t;
- godot_string_new_with_latin1_chars(&s, "Pretty Whale Whale");
-
- godot_string_new_with_latin1_chars(&t, "WHA");
- CHECK(godot_string_findn(&s, &t) == 7);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "WHA");
- CHECK(godot_string_findn_from(&s, &t, 9) == 13);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "WHA");
- CHECK(godot_string_rfindn(&s, &t) == 13);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "Revenge of the Monster SawFish");
- CHECK(godot_string_findn(&s, &t) == -1);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Find MK") {
- godot_packed_string_array keys;
- godot_packed_string_array_new(&keys);
-
-#define PUSH_KEY(x) \
- { \
- godot_string t; \
- godot_string_new_with_latin1_chars(&t, x); \
- godot_packed_string_array_push_back(&keys, &t); \
- godot_string_destroy(&t); \
- }
-
- PUSH_KEY("sty")
- PUSH_KEY("tty")
- PUSH_KEY("man")
-
- godot_string s;
- godot_string_new_with_latin1_chars(&s, "Pretty Woman");
- godot_int key = 0;
-
- CHECK(godot_string_findmk(&s, &keys) == 3);
- CHECK(godot_string_findmk_from_in_place(&s, &keys, 0, &key) == 3);
- CHECK(key == 1);
-
- CHECK(godot_string_findmk_from(&s, &keys, 5) == 9);
- CHECK(godot_string_findmk_from_in_place(&s, &keys, 5, &key) == 9);
- CHECK(key == 2);
-
- godot_string_destroy(&s);
- godot_packed_string_array_destroy(&keys);
-
-#undef PUSH_KEY
-}
-
-TEST_CASE("[GDNative String] Find and replace") {
- godot_string s, c, w;
- godot_string_new_with_latin1_chars(&s, "Happy Birthday, Anna!");
- godot_string_new_with_latin1_chars(&c, "Birthday");
- godot_string_new_with_latin1_chars(&w, "Halloween");
- godot_string t = godot_string_replace(&s, &c, &w);
- CHECK(u32scmp(godot_string_get_data(&t), U"Happy Halloween, Anna!") == 0);
- godot_string_destroy(&s);
- godot_string_destroy(&c);
- godot_string_destroy(&w);
-
- godot_string_new_with_latin1_chars(&c, "H");
- godot_string_new_with_latin1_chars(&w, "W");
- s = godot_string_replace_first(&t, &c, &w);
- godot_string_destroy(&t);
- godot_string_destroy(&c);
- godot_string_destroy(&w);
-
- CHECK(u32scmp(godot_string_get_data(&s), U"Wappy Halloween, Anna!") == 0);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Insertion") {
- godot_string s, t, r, u;
- godot_string_new_with_latin1_chars(&s, "Who is Frederic?");
- godot_string_new_with_latin1_chars(&t, "?");
- godot_string_new_with_latin1_chars(&r, " Chopin");
-
- u = godot_string_insert(&s, godot_string_find(&s, &t), &r);
- CHECK(u32scmp(godot_string_get_data(&u), U"Who is Frederic Chopin?") == 0);
-
- godot_string_destroy(&s);
- godot_string_destroy(&t);
- godot_string_destroy(&r);
- godot_string_destroy(&u);
-}
-
-TEST_CASE("[GDNative String] Number to string") {
- godot_string s;
- s = godot_string_num(3.141593);
- CHECK(u32scmp(godot_string_get_data(&s), U"3.141593") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_num_with_decimals(3.141593, 3);
- CHECK(u32scmp(godot_string_get_data(&s), U"3.142") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_num_real(3.141593);
- CHECK(u32scmp(godot_string_get_data(&s), U"3.141593") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_num_scientific(30000000);
- CHECK(u32scmp(godot_string_get_data(&s), U"3e+07") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_num_int64(3141593, 10);
- CHECK(u32scmp(godot_string_get_data(&s), U"3141593") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_num_int64(0xA141593, 16);
- CHECK(u32scmp(godot_string_get_data(&s), U"a141593") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_num_int64_capitalized(0xA141593, 16, true);
- CHECK(u32scmp(godot_string_get_data(&s), U"A141593") == 0);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] String to integer") {
- static const wchar_t *wnums[4] = { L"1237461283", L"- 22", L"0", L" - 1123412" };
- static const char *nums[4] = { "1237461283", "- 22", "0", " - 1123412" };
- static const int num[4] = { 1237461283, -22, 0, -1123412 };
-
- for (int i = 0; i < 4; i++) {
- godot_string s;
- godot_string_new_with_latin1_chars(&s, nums[i]);
- CHECK(godot_string_to_int(&s) == num[i]);
- godot_string_destroy(&s);
-
- CHECK(godot_string_char_to_int(nums[i]) == num[i]);
- CHECK(godot_string_wchar_to_int(wnums[i]) == num[i]);
- }
-}
-
-TEST_CASE("[GDNative String] Hex to integer") {
- static const char *nums[4] = { "0xFFAE", "22", "0", "AADDAD" };
- static const int64_t num[4] = { 0xFFAE, 0x22, 0, 0xAADDAD };
- static const bool wo_prefix[4] = { false, true, true, true };
- static const bool w_prefix[4] = { true, false, true, false };
-
- for (int i = 0; i < 4; i++) {
- godot_string s;
- godot_string_new_with_latin1_chars(&s, nums[i]);
- CHECK((godot_string_hex_to_int_with_prefix(&s) == num[i]) == w_prefix[i]);
- CHECK((godot_string_hex_to_int(&s) == num[i]) == wo_prefix[i]);
- godot_string_destroy(&s);
- }
-}
-
-TEST_CASE("[GDNative String] String to float") {
- static const wchar_t *wnums[4] = { L"-12348298412.2", L"0.05", L"2.0002", L" -0.0001" };
- static const char *nums[4] = { "-12348298412.2", "0.05", "2.0002", " -0.0001" };
- static const double num[4] = { -12348298412.2, 0.05, 2.0002, -0.0001 };
-
- for (int i = 0; i < 4; i++) {
- godot_string s;
- godot_string_new_with_latin1_chars(&s, nums[i]);
- CHECK(!(ABS(godot_string_to_float(&s) - num[i]) > 0.00001));
- godot_string_destroy(&s);
-
- CHECK(!(ABS(godot_string_char_to_float(nums[i]) - num[i]) > 0.00001));
- CHECK(!(ABS(godot_string_wchar_to_float(wnums[i], nullptr) - num[i]) > 0.00001));
- }
-}
-
-TEST_CASE("[GDNative String] CamelCase to underscore") {
- godot_string s, t;
- godot_string_new_with_latin1_chars(&s, "TestTestStringGD");
-
- t = godot_string_camelcase_to_underscore(&s);
- CHECK(u32scmp(godot_string_get_data(&t), U"Test_Test_String_GD") == 0);
- godot_string_destroy(&t);
-
- t = godot_string_camelcase_to_underscore_lowercased(&s);
- CHECK(u32scmp(godot_string_get_data(&t), U"test_test_string_gd") == 0);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Slicing") {
- godot_string s, c;
- godot_string_new_with_latin1_chars(&s, "Mars,Jupiter,Saturn,Uranus");
- godot_string_new_with_latin1_chars(&c, ",");
-
- const char32_t *slices[4] = { U"Mars", U"Jupiter", U"Saturn", U"Uranus" };
- for (int i = 0; i < godot_string_get_slice_count(&s, &c); i++) {
- godot_string t;
- t = godot_string_get_slice(&s, &c, i);
- CHECK(u32scmp(godot_string_get_data(&t), slices[i]) == 0);
- godot_string_destroy(&t);
-
- t = godot_string_get_slicec(&s, U',', i);
- CHECK(u32scmp(godot_string_get_data(&t), slices[i]) == 0);
- godot_string_destroy(&t);
- }
-
- godot_string_destroy(&c);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Splitting") {
- godot_string s, c;
- godot_string_new_with_latin1_chars(&s, "Mars,Jupiter,Saturn,Uranus");
- godot_string_new_with_latin1_chars(&c, ",");
-
- godot_packed_string_array l;
-
- const char32_t *slices_l[3] = { U"Mars", U"Jupiter", U"Saturn,Uranus" };
- const char32_t *slices_r[3] = { U"Mars,Jupiter", U"Saturn", U"Uranus" };
-
- l = godot_string_split_with_maxsplit(&s, &c, true, 2);
- CHECK(godot_packed_string_array_size(&l) == 3);
- for (int i = 0; i < godot_packed_string_array_size(&l); i++) {
- godot_string t = godot_packed_string_array_get(&l, i);
- CHECK(u32scmp(godot_string_get_data(&t), slices_l[i]) == 0);
- godot_string_destroy(&t);
- }
- godot_packed_string_array_destroy(&l);
-
- l = godot_string_rsplit_with_maxsplit(&s, &c, true, 2);
- CHECK(godot_packed_string_array_size(&l) == 3);
- for (int i = 0; i < godot_packed_string_array_size(&l); i++) {
- godot_string t = godot_packed_string_array_get(&l, i);
- CHECK(u32scmp(godot_string_get_data(&t), slices_r[i]) == 0);
- godot_string_destroy(&t);
- }
- godot_packed_string_array_destroy(&l);
- godot_string_destroy(&s);
-
- godot_string_new_with_latin1_chars(&s, "Mars Jupiter Saturn Uranus");
- const char32_t *slices_s[4] = { U"Mars", U"Jupiter", U"Saturn", U"Uranus" };
- l = godot_string_split_spaces(&s);
- for (int i = 0; i < godot_packed_string_array_size(&l); i++) {
- godot_string t = godot_packed_string_array_get(&l, i);
- CHECK(u32scmp(godot_string_get_data(&t), slices_s[i]) == 0);
- godot_string_destroy(&t);
- }
- godot_packed_string_array_destroy(&l);
- godot_string_destroy(&s);
-
- godot_string c1, c2;
- godot_string_new_with_latin1_chars(&c1, ";");
- godot_string_new_with_latin1_chars(&c2, " ");
-
- godot_string_new_with_latin1_chars(&s, "1.2;2.3 4.5");
- const double slices_d[3] = { 1.2, 2.3, 4.5 };
-
- godot_packed_float32_array lf = godot_string_split_floats_allow_empty(&s, &c1);
- CHECK(godot_packed_float32_array_size(&lf) == 2);
- for (int i = 0; i < godot_packed_float32_array_size(&lf); i++) {
- CHECK(ABS(godot_packed_float32_array_get(&lf, i) - slices_d[i]) <= 0.00001);
- }
- godot_packed_float32_array_destroy(&lf);
-
- godot_packed_string_array keys;
- godot_packed_string_array_new(&keys);
- godot_packed_string_array_push_back(&keys, &c1);
- godot_packed_string_array_push_back(&keys, &c2);
-
- lf = godot_string_split_floats_mk_allow_empty(&s, &keys);
- CHECK(godot_packed_float32_array_size(&lf) == 3);
- for (int i = 0; i < godot_packed_float32_array_size(&lf); i++) {
- CHECK(ABS(godot_packed_float32_array_get(&lf, i) - slices_d[i]) <= 0.00001);
- }
- godot_packed_float32_array_destroy(&lf);
-
- godot_string_destroy(&s);
- godot_string_new_with_latin1_chars(&s, "1;2 4");
- const int slices_i[3] = { 1, 2, 4 };
-
- godot_packed_int32_array li = godot_string_split_ints_allow_empty(&s, &c1);
- CHECK(godot_packed_int32_array_size(&li) == 2);
- for (int i = 0; i < godot_packed_int32_array_size(&li); i++) {
- CHECK(godot_packed_int32_array_get(&li, i) == slices_i[i]);
- }
- godot_packed_int32_array_destroy(&li);
-
- li = godot_string_split_ints_mk_allow_empty(&s, &keys);
- CHECK(godot_packed_int32_array_size(&li) == 3);
- for (int i = 0; i < godot_packed_int32_array_size(&li); i++) {
- CHECK(godot_packed_int32_array_get(&li, i) == slices_i[i]);
- }
- godot_packed_int32_array_destroy(&li);
-
- godot_string_destroy(&s);
- godot_string_destroy(&c);
- godot_string_destroy(&c1);
- godot_string_destroy(&c2);
- godot_packed_string_array_destroy(&keys);
-}
-
-TEST_CASE("[GDNative String] Erasing") {
- godot_string s, t;
- godot_string_new_with_latin1_chars(&s, "Josephine is such a cute girl!");
- godot_string_new_with_latin1_chars(&t, "cute ");
-
- godot_string_erase(&s, godot_string_find(&s, &t), godot_string_length(&t));
-
- CHECK(u32scmp(godot_string_get_data(&s), U"Josephine is such a girl!") == 0);
-
- godot_string_destroy(&s);
- godot_string_destroy(&t);
-}
-
-struct test_27_data {
- char const *data;
- char const *part;
- bool expected;
-};
-
-TEST_CASE("[GDNative String] Begins with") {
- test_27_data tc[] = {
- { "res://foobar", "res://", true },
- { "res", "res://", false },
- { "abc", "abc", true }
- };
- size_t count = sizeof(tc) / sizeof(tc[0]);
- bool state = true;
- for (size_t i = 0; state && i < count; ++i) {
- godot_string s;
- godot_string_new_with_latin1_chars(&s, tc[i].data);
-
- state = godot_string_begins_with_char_array(&s, tc[i].part) == tc[i].expected;
- if (state) {
- godot_string t;
- godot_string_new_with_latin1_chars(&t, tc[i].part);
- state = godot_string_begins_with(&s, &t) == tc[i].expected;
- godot_string_destroy(&t);
- }
- godot_string_destroy(&s);
-
- CHECK(state);
- if (!state) {
- break;
- }
- };
- CHECK(state);
-}
-
-TEST_CASE("[GDNative String] Ends with") {
- test_27_data tc[] = {
- { "res://foobar", "foobar", true },
- { "res", "res://", false },
- { "abc", "abc", true }
- };
- size_t count = sizeof(tc) / sizeof(tc[0]);
- bool state = true;
- for (size_t i = 0; state && i < count; ++i) {
- godot_string s;
- godot_string_new_with_latin1_chars(&s, tc[i].data);
-
- state = godot_string_ends_with_char_array(&s, tc[i].part) == tc[i].expected;
- if (state) {
- godot_string t;
- godot_string_new_with_latin1_chars(&t, tc[i].part);
- state = godot_string_ends_with(&s, &t) == tc[i].expected;
- godot_string_destroy(&t);
- }
- godot_string_destroy(&s);
-
- CHECK(state);
- if (!state) {
- break;
- }
- };
- CHECK(state);
-}
-
-TEST_CASE("[GDNative String] format") {
- godot_string value_format, t;
- godot_string_new_with_latin1_chars(&value_format, "red=\"$red\" green=\"$green\" blue=\"$blue\" alpha=\"$alpha\"");
-
- godot_variant key_v, val_v;
- godot_dictionary value_dictionary;
- godot_dictionary_new(&value_dictionary);
-
- godot_string_new_with_latin1_chars(&t, "red");
- godot_variant_new_string(&key_v, &t);
- godot_string_destroy(&t);
- godot_variant_new_int(&val_v, 10);
- godot_dictionary_set(&value_dictionary, &key_v, &val_v);
- godot_variant_destroy(&key_v);
- godot_variant_destroy(&val_v);
-
- godot_string_new_with_latin1_chars(&t, "green");
- godot_variant_new_string(&key_v, &t);
- godot_string_destroy(&t);
- godot_variant_new_int(&val_v, 20);
- godot_dictionary_set(&value_dictionary, &key_v, &val_v);
- godot_variant_destroy(&key_v);
- godot_variant_destroy(&val_v);
-
- godot_string_new_with_latin1_chars(&t, "blue");
- godot_variant_new_string(&key_v, &t);
- godot_string_destroy(&t);
- godot_string_new_with_latin1_chars(&t, "bla");
- godot_variant_new_string(&val_v, &t);
- godot_string_destroy(&t);
- godot_dictionary_set(&value_dictionary, &key_v, &val_v);
- godot_variant_destroy(&key_v);
- godot_variant_destroy(&val_v);
-
- godot_string_new_with_latin1_chars(&t, "alpha");
- godot_variant_new_string(&key_v, &t);
- godot_string_destroy(&t);
- godot_variant_new_real(&val_v, 0.4);
- godot_dictionary_set(&value_dictionary, &key_v, &val_v);
- godot_variant_destroy(&key_v);
- godot_variant_destroy(&val_v);
-
- godot_variant dict_v;
- godot_variant_new_dictionary(&dict_v, &value_dictionary);
- godot_string s = godot_string_format_with_custom_placeholder(&value_format, &dict_v, "$_");
-
- CHECK(u32scmp(godot_string_get_data(&s), U"red=\"10\" green=\"20\" blue=\"bla\" alpha=\"0.4\"") == 0);
-
- godot_dictionary_destroy(&value_dictionary);
- godot_string_destroy(&s);
- godot_variant_destroy(&dict_v);
- godot_string_destroy(&value_format);
-}
-
-TEST_CASE("[GDNative String] sprintf") {
- //godot_string GDAPI (const godot_string *p_self, const godot_array *p_values, godot_bool *p_error);
- godot_string format, output;
- godot_array args;
- bool error;
-
-#define ARRAY_PUSH_STRING(x) \
- { \
- godot_variant v; \
- godot_string t; \
- godot_string_new_with_latin1_chars(&t, x); \
- godot_variant_new_string(&v, &t); \
- godot_string_destroy(&t); \
- godot_array_push_back(&args, &v); \
- godot_variant_destroy(&v); \
- }
-
-#define ARRAY_PUSH_INT(x) \
- { \
- godot_variant v; \
- godot_variant_new_int(&v, x); \
- godot_array_push_back(&args, &v); \
- godot_variant_destroy(&v); \
- }
-
-#define ARRAY_PUSH_REAL(x) \
- { \
- godot_variant v; \
- godot_variant_new_real(&v, x); \
- godot_array_push_back(&args, &v); \
- godot_variant_destroy(&v); \
- }
-
- godot_array_new(&args);
-
- // %%
- godot_string_new_with_latin1_chars(&format, "fish %% frog");
- godot_array_clear(&args);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish % frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
- //////// INTS
-
- // Int
- godot_string_new_with_latin1_chars(&format, "fish %d frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(5);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Int left padded with zeroes.
- godot_string_new_with_latin1_chars(&format, "fish %05d frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(5);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 00005 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Int left padded with spaces.
- godot_string_new_with_latin1_chars(&format, "fish %5d frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(5);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Int right padded with spaces.
- godot_string_new_with_latin1_chars(&format, "fish %-5d frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(5);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 5 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Int with sign (positive).
- godot_string_new_with_latin1_chars(&format, "fish %+d frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(5);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish +5 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Negative int.
- godot_string_new_with_latin1_chars(&format, "fish %d frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(-5);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish -5 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Hex (lower)
- godot_string_new_with_latin1_chars(&format, "fish %x frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(45);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 2d frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Hex (upper)
- godot_string_new_with_latin1_chars(&format, "fish %X frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(45);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 2D frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Octal
- godot_string_new_with_latin1_chars(&format, "fish %o frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 143 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
- ////// REALS
-
- // Real
- godot_string_new_with_latin1_chars(&format, "fish %f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Real left-padded
- godot_string_new_with_latin1_chars(&format, "fish %11f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Real right-padded
- godot_string_new_with_latin1_chars(&format, "fish %-11f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Real given int.
- godot_string_new_with_latin1_chars(&format, "fish %f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.000000 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Real with sign (positive).
- godot_string_new_with_latin1_chars(&format, "fish %+f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish +99.990000 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Real with 1 decimals.
- godot_string_new_with_latin1_chars(&format, "fish %.1f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 100.0 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Real with 12 decimals.
- godot_string_new_with_latin1_chars(&format, "fish %.12f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990000000000 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Real with no decimals.
- godot_string_new_with_latin1_chars(&format, "fish %.f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 100 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- /////// Strings.
-
- // String
- godot_string_new_with_latin1_chars(&format, "fish %s frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("cheese");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // String left-padded
- godot_string_new_with_latin1_chars(&format, "fish %10s frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("cheese");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // String right-padded
- godot_string_new_with_latin1_chars(&format, "fish %-10s frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("cheese");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- ///// Characters
-
- // Character as string.
- godot_string_new_with_latin1_chars(&format, "fish %c frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("A");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish A frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Character as int.
- godot_string_new_with_latin1_chars(&format, "fish %c frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(65);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish A frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- ///// Dynamic width
-
- // String dynamic width
- godot_string_new_with_latin1_chars(&format, "fish %*s frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(10);
- ARRAY_PUSH_STRING("cheese");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- REQUIRE(u32scmp(godot_string_get_data(&output), U"fish cheese frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Int dynamic width
- godot_string_new_with_latin1_chars(&format, "fish %*d frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(10);
- ARRAY_PUSH_INT(99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- REQUIRE(u32scmp(godot_string_get_data(&output), U"fish 99 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Float dynamic width
- godot_string_new_with_latin1_chars(&format, "fish %*.*f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_INT(10);
- ARRAY_PUSH_INT(3);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error == false);
- CHECK(u32scmp(godot_string_get_data(&output), U"fish 99.990 frog") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- ///// Errors
-
- // More formats than arguments.
- godot_string_new_with_latin1_chars(&format, "fish %s %s frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("cheese");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error);
- CHECK(u32scmp(godot_string_get_data(&output), U"not enough arguments for format string") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // More arguments than formats.
- godot_string_new_with_latin1_chars(&format, "fish %s frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("hello");
- ARRAY_PUSH_STRING("cheese");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error);
- CHECK(u32scmp(godot_string_get_data(&output), U"not all arguments converted during string formatting") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Incomplete format.
- godot_string_new_with_latin1_chars(&format, "fish %10");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("cheese");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error);
- CHECK(u32scmp(godot_string_get_data(&output), U"incomplete format") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Bad character in format string
- godot_string_new_with_latin1_chars(&format, "fish %&f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("cheese");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error);
- CHECK(u32scmp(godot_string_get_data(&output), U"unsupported format character") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Too many decimals.
- godot_string_new_with_latin1_chars(&format, "fish %2.2.2f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error);
- CHECK(u32scmp(godot_string_get_data(&output), U"too many decimal points in format") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // * not a number
- godot_string_new_with_latin1_chars(&format, "fish %*f frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("cheese");
- ARRAY_PUSH_REAL(99.99);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error);
- CHECK(u32scmp(godot_string_get_data(&output), U"* wants number") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Character too long.
- godot_string_new_with_latin1_chars(&format, "fish %c frog");
- godot_array_clear(&args);
- ARRAY_PUSH_STRING("sc");
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error);
- CHECK(u32scmp(godot_string_get_data(&output), U"%c requires number or single-character string") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- // Character bad type.
- godot_string_new_with_latin1_chars(&format, "fish %c frog");
- godot_array_clear(&args);
- godot_array t;
- godot_array_new(&t);
- godot_variant v;
- godot_variant_new_array(&v, &t);
- godot_array_destroy(&t);
- godot_array_push_back(&args, &v);
- godot_variant_destroy(&v);
- output = godot_string_sprintf(&format, &args, &error);
- REQUIRE(error);
- CHECK(u32scmp(godot_string_get_data(&output), U"%c requires number or single-character string") == 0);
- godot_string_destroy(&format);
- godot_string_destroy(&output);
-
- godot_array_destroy(&args);
-#undef ARRAY_PUSH_INT
-#undef ARRAY_PUSH_REAL
-#undef ARRAY_PUSH_STRING
-}
-
-TEST_CASE("[GDNative String] is_numeric") {
-#define IS_NUM_TEST(x, r) \
- { \
- godot_string t; \
- godot_string_new_with_latin1_chars(&t, x); \
- CHECK(godot_string_is_numeric(&t) == r); \
- godot_string_destroy(&t); \
- }
-
- IS_NUM_TEST("12", true);
- IS_NUM_TEST("1.2", true);
- IS_NUM_TEST("AF", false);
- IS_NUM_TEST("-12", true);
- IS_NUM_TEST("-1.2", true);
-
-#undef IS_NUM_TEST
-}
-
-TEST_CASE("[GDNative String] pad") {
- godot_string s, c;
- godot_string_new_with_latin1_chars(&s, "test");
- godot_string_new_with_latin1_chars(&c, "x");
-
- godot_string l = godot_string_lpad_with_custom_character(&s, 10, &c);
- CHECK(u32scmp(godot_string_get_data(&l), U"xxxxxxtest") == 0);
- godot_string_destroy(&l);
-
- godot_string r = godot_string_rpad_with_custom_character(&s, 10, &c);
- CHECK(u32scmp(godot_string_get_data(&r), U"testxxxxxx") == 0);
- godot_string_destroy(&r);
-
- godot_string_destroy(&s);
- godot_string_destroy(&c);
-
- godot_string_new_with_latin1_chars(&s, "10.10");
- c = godot_string_pad_decimals(&s, 4);
- CHECK(u32scmp(godot_string_get_data(&c), U"10.1000") == 0);
- godot_string_destroy(&c);
- c = godot_string_pad_zeros(&s, 4);
- CHECK(u32scmp(godot_string_get_data(&c), U"0010.10") == 0);
- godot_string_destroy(&c);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] is_subsequence_of") {
- godot_string a, t;
- godot_string_new_with_latin1_chars(&a, "is subsequence of");
-
- godot_string_new_with_latin1_chars(&t, "sub");
- CHECK(godot_string_is_subsequence_of(&t, &a));
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "Sub");
- CHECK(!godot_string_is_subsequence_of(&t, &a));
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "Sub");
- CHECK(godot_string_is_subsequence_ofi(&t, &a));
- godot_string_destroy(&t);
-
- godot_string_destroy(&a);
-}
-
-TEST_CASE("[GDNative String] match") {
- godot_string s, t;
- godot_string_new_with_latin1_chars(&s, "*.png");
-
- godot_string_new_with_latin1_chars(&t, "img1.png");
- CHECK(godot_string_match(&t, &s));
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "img1.jpeg");
- CHECK(!godot_string_match(&t, &s));
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "img1.Png");
- CHECK(!godot_string_match(&t, &s));
- CHECK(godot_string_matchn(&t, &s));
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] IPVX address to string") {
- godot_string ip;
-
- godot_string_new_with_latin1_chars(&ip, "192.168.0.1");
- CHECK(godot_string_is_valid_ip_address(&ip));
- godot_string_destroy(&ip);
-
- godot_string_new_with_latin1_chars(&ip, "192.368.0.1");
- CHECK(!godot_string_is_valid_ip_address(&ip));
- godot_string_destroy(&ip);
-
- godot_string_new_with_latin1_chars(&ip, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
- CHECK(godot_string_is_valid_ip_address(&ip));
- godot_string_destroy(&ip);
-
- godot_string_new_with_latin1_chars(&ip, "2001:0db8:85j3:0000:0000:8a2e:0370:7334");
- CHECK(!godot_string_is_valid_ip_address(&ip));
- godot_string_destroy(&ip);
-
- godot_string_new_with_latin1_chars(&ip, "2001:0db8:85f345:0000:0000:8a2e:0370:7334");
- CHECK(!godot_string_is_valid_ip_address(&ip));
- godot_string_destroy(&ip);
-
- godot_string_new_with_latin1_chars(&ip, "2001:0db8::0:8a2e:370:7334");
- CHECK(godot_string_is_valid_ip_address(&ip));
- godot_string_destroy(&ip);
-
- godot_string_new_with_latin1_chars(&ip, "::ffff:192.168.0.1");
- CHECK(godot_string_is_valid_ip_address(&ip));
- godot_string_destroy(&ip);
-}
-
-TEST_CASE("[GDNative String] Capitalize against many strings") {
-#define CAP_TEST(i, o) \
- godot_string_new_with_latin1_chars(&input, i); \
- godot_string_new_with_latin1_chars(&output, o); \
- test = godot_string_capitalize(&input); \
- CHECK(u32scmp(godot_string_get_data(&output), godot_string_get_data(&test)) == 0); \
- godot_string_destroy(&input); \
- godot_string_destroy(&output); \
- godot_string_destroy(&test);
-
- godot_string input, output, test;
-
- CAP_TEST("bytes2var", "Bytes 2 Var");
- CAP_TEST("linear2db", "Linear 2 Db");
- CAP_TEST("vector3", "Vector 3");
- CAP_TEST("sha256", "Sha 256");
- CAP_TEST("2db", "2 Db");
- CAP_TEST("PascalCase", "Pascal Case");
- CAP_TEST("PascalPascalCase", "Pascal Pascal Case");
- CAP_TEST("snake_case", "Snake Case");
- CAP_TEST("snake_snake_case", "Snake Snake Case");
- CAP_TEST("sha256sum", "Sha 256 Sum");
- CAP_TEST("cat2dog", "Cat 2 Dog");
- CAP_TEST("function(name)", "Function(name)");
- CAP_TEST("snake_case_function(snake_case_arg)", "Snake Case Function(snake Case Arg)");
- CAP_TEST("snake_case_function( snake_case_arg )", "Snake Case Function( Snake Case Arg )");
-
-#undef CAP_TEST
-}
-
-TEST_CASE("[GDNative String] lstrip and rstrip") {
-#define LSTRIP_TEST(x, y, z) \
- { \
- godot_string xx, yy, zz, rr; \
- godot_string_new_with_latin1_chars(&xx, x); \
- godot_string_new_with_latin1_chars(&yy, y); \
- godot_string_new_with_latin1_chars(&zz, z); \
- rr = godot_string_lstrip(&xx, &yy); \
- state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \
- godot_string_destroy(&xx); \
- godot_string_destroy(&yy); \
- godot_string_destroy(&zz); \
- godot_string_destroy(&rr); \
- }
-
-#define RSTRIP_TEST(x, y, z) \
- { \
- godot_string xx, yy, zz, rr; \
- godot_string_new_with_latin1_chars(&xx, x); \
- godot_string_new_with_latin1_chars(&yy, y); \
- godot_string_new_with_latin1_chars(&zz, z); \
- rr = godot_string_rstrip(&xx, &yy); \
- state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \
- godot_string_destroy(&xx); \
- godot_string_destroy(&yy); \
- godot_string_destroy(&zz); \
- godot_string_destroy(&rr); \
- }
-
-#define LSTRIP_UTF8_TEST(x, y, z) \
- { \
- godot_string xx, yy, zz, rr; \
- godot_string_new_with_utf8_chars(&xx, x); \
- godot_string_new_with_utf8_chars(&yy, y); \
- godot_string_new_with_utf8_chars(&zz, z); \
- rr = godot_string_lstrip(&xx, &yy); \
- state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \
- godot_string_destroy(&xx); \
- godot_string_destroy(&yy); \
- godot_string_destroy(&zz); \
- godot_string_destroy(&rr); \
- }
-
-#define RSTRIP_UTF8_TEST(x, y, z) \
- { \
- godot_string xx, yy, zz, rr; \
- godot_string_new_with_utf8_chars(&xx, x); \
- godot_string_new_with_utf8_chars(&yy, y); \
- godot_string_new_with_utf8_chars(&zz, z); \
- rr = godot_string_rstrip(&xx, &yy); \
- state = state && (u32scmp(godot_string_get_data(&rr), godot_string_get_data(&zz)) == 0); \
- godot_string_destroy(&xx); \
- godot_string_destroy(&yy); \
- godot_string_destroy(&zz); \
- godot_string_destroy(&rr); \
- }
-
- bool state = true;
-
- // strip none
- LSTRIP_TEST("abc", "", "abc");
- RSTRIP_TEST("abc", "", "abc");
- // strip one
- LSTRIP_TEST("abc", "a", "bc");
- RSTRIP_TEST("abc", "c", "ab");
- // strip lots
- LSTRIP_TEST("bababbababccc", "ab", "ccc");
- RSTRIP_TEST("aaabcbcbcbbcbbc", "cb", "aaa");
- // strip empty string
- LSTRIP_TEST("", "", "");
- RSTRIP_TEST("", "", "");
- // strip to empty string
- LSTRIP_TEST("abcabcabc", "bca", "");
- RSTRIP_TEST("abcabcabc", "bca", "");
- // don't strip wrong end
- LSTRIP_TEST("abc", "c", "abc");
- LSTRIP_TEST("abca", "a", "bca");
- RSTRIP_TEST("abc", "a", "abc");
- RSTRIP_TEST("abca", "a", "abc");
- // in utf-8 "¿" (\u00bf) has the same first byte as "µ" (\u00b5)
- // and the same second as "ÿ" (\u00ff)
- LSTRIP_UTF8_TEST("¿", "µÿ", "¿");
- RSTRIP_UTF8_TEST("¿", "µÿ", "¿");
- LSTRIP_UTF8_TEST("µ¿ÿ", "µÿ", "¿ÿ");
- RSTRIP_UTF8_TEST("µ¿ÿ", "µÿ", "µ¿");
-
- // the above tests repeated with additional superfluous strip chars
-
- // strip none
- LSTRIP_TEST("abc", "qwjkl", "abc");
- RSTRIP_TEST("abc", "qwjkl", "abc");
- // strip one
- LSTRIP_TEST("abc", "qwajkl", "bc");
- RSTRIP_TEST("abc", "qwcjkl", "ab");
- // strip lots
- LSTRIP_TEST("bababbababccc", "qwabjkl", "ccc");
- RSTRIP_TEST("aaabcbcbcbbcbbc", "qwcbjkl", "aaa");
- // strip empty string
- LSTRIP_TEST("", "qwjkl", "");
- RSTRIP_TEST("", "qwjkl", "");
- // strip to empty string
- LSTRIP_TEST("abcabcabc", "qwbcajkl", "");
- RSTRIP_TEST("abcabcabc", "qwbcajkl", "");
- // don't strip wrong end
- LSTRIP_TEST("abc", "qwcjkl", "abc");
- LSTRIP_TEST("abca", "qwajkl", "bca");
- RSTRIP_TEST("abc", "qwajkl", "abc");
- RSTRIP_TEST("abca", "qwajkl", "abc");
- // in utf-8 "¿" (\u00bf) has the same first byte as "µ" (\u00b5)
- // and the same second as "ÿ" (\u00ff)
- LSTRIP_UTF8_TEST("¿", "qwaµÿjkl", "¿");
- RSTRIP_UTF8_TEST("¿", "qwaµÿjkl", "¿");
- LSTRIP_UTF8_TEST("µ¿ÿ", "qwaµÿjkl", "¿ÿ");
- RSTRIP_UTF8_TEST("µ¿ÿ", "qwaµÿjkl", "µ¿");
-
- CHECK(state);
-
-#undef LSTRIP_TEST
-#undef RSTRIP_TEST
-#undef LSTRIP_UTF8_TEST
-#undef RSTRIP_UTF8_TEST
-}
-
-TEST_CASE("[GDNative String] Cyrillic to_lower()") {
- godot_string upper, lower, test;
- godot_string_new_with_utf8_chars(&upper, "ÐБВГДЕÐЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯ");
- godot_string_new_with_utf8_chars(&lower, "абвгдеёжзийклмнопрÑтуфхцчшщъыьÑÑŽÑ");
-
- test = godot_string_to_lower(&upper);
-
- CHECK((u32scmp(godot_string_get_data(&test), godot_string_get_data(&lower)) == 0));
-
- godot_string_destroy(&upper);
- godot_string_destroy(&lower);
- godot_string_destroy(&test);
-}
-
-TEST_CASE("[GDNative String] Count and countn functionality") {
-#define COUNT_TEST(x, y, r) \
- { \
- godot_string s, t; \
- godot_string_new_with_latin1_chars(&s, x); \
- godot_string_new_with_latin1_chars(&t, y); \
- state = state && (godot_string_count(&s, &t, 0, 0) == r); \
- godot_string_destroy(&s); \
- godot_string_destroy(&t); \
- }
-
-#define COUNTR_TEST(x, y, a, b, r) \
- { \
- godot_string s, t; \
- godot_string_new_with_latin1_chars(&s, x); \
- godot_string_new_with_latin1_chars(&t, y); \
- state = state && (godot_string_count(&s, &t, a, b) == r); \
- godot_string_destroy(&s); \
- godot_string_destroy(&t); \
- }
-
-#define COUNTN_TEST(x, y, r) \
- { \
- godot_string s, t; \
- godot_string_new_with_latin1_chars(&s, x); \
- godot_string_new_with_latin1_chars(&t, y); \
- state = state && (godot_string_countn(&s, &t, 0, 0) == r); \
- godot_string_destroy(&s); \
- godot_string_destroy(&t); \
- }
-
-#define COUNTNR_TEST(x, y, a, b, r) \
- { \
- godot_string s, t; \
- godot_string_new_with_latin1_chars(&s, x); \
- godot_string_new_with_latin1_chars(&t, y); \
- state = state && (godot_string_countn(&s, &t, a, b) == r); \
- godot_string_destroy(&s); \
- godot_string_destroy(&t); \
- }
- bool state = true;
-
- COUNT_TEST("", "Test", 0);
- COUNT_TEST("Test", "", 0);
- COUNT_TEST("Test", "test", 0);
- COUNT_TEST("Test", "TEST", 0);
- COUNT_TEST("TEST", "TEST", 1);
- COUNT_TEST("Test", "Test", 1);
- COUNT_TEST("aTest", "Test", 1);
- COUNT_TEST("Testa", "Test", 1);
- COUNT_TEST("TestTestTest", "Test", 3);
- COUNT_TEST("TestTestTest", "TestTest", 1);
- COUNT_TEST("TestGodotTestGodotTestGodot", "Test", 3);
-
- COUNTR_TEST("TestTestTestTest", "Test", 4, 8, 1);
- COUNTR_TEST("TestTestTestTest", "Test", 4, 12, 2);
- COUNTR_TEST("TestTestTestTest", "Test", 4, 16, 3);
- COUNTR_TEST("TestTestTestTest", "Test", 4, 0, 3);
-
- COUNTN_TEST("Test", "test", 1);
- COUNTN_TEST("Test", "TEST", 1);
- COUNTN_TEST("testTest-Testatest", "tEst", 4);
- COUNTNR_TEST("testTest-TeStatest", "tEsT", 4, 16, 2);
-
- CHECK(state);
-
-#undef COUNT_TEST
-#undef COUNTR_TEST
-#undef COUNTN_TEST
-#undef COUNTNR_TEST
-}
-
-TEST_CASE("[GDNative String] Bigrams") {
- godot_string s, t;
- godot_string_new_with_latin1_chars(&s, "abcd");
- godot_packed_string_array bigr = godot_string_bigrams(&s);
- godot_string_destroy(&s);
-
- CHECK(godot_packed_string_array_size(&bigr) == 3);
-
- t = godot_packed_string_array_get(&bigr, 0);
- CHECK(u32scmp(godot_string_get_data(&t), U"ab") == 0);
- godot_string_destroy(&t);
-
- t = godot_packed_string_array_get(&bigr, 1);
- CHECK(u32scmp(godot_string_get_data(&t), U"bc") == 0);
- godot_string_destroy(&t);
-
- t = godot_packed_string_array_get(&bigr, 2);
- CHECK(u32scmp(godot_string_get_data(&t), U"cd") == 0);
- godot_string_destroy(&t);
-
- godot_packed_string_array_destroy(&bigr);
-}
-
-TEST_CASE("[GDNative String] c-escape/unescape") {
- godot_string s;
- godot_string_new_with_latin1_chars(&s, "\\1\a2\b\f3\n45\r6\t7\v8\'9\?0\"");
- godot_string t = godot_string_c_escape(&s);
- godot_string u = godot_string_c_unescape(&t);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] dedent") {
- godot_string s, t;
- godot_string_new_with_latin1_chars(&s, " aaa\n bbb");
- godot_string_new_with_latin1_chars(&t, "aaa\nbbb");
- godot_string u = godot_string_dedent(&s);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Path functions") {
- static const char *path[4] = { "C:\\Godot\\project\\test.tscn", "/Godot/project/test.xscn", "../Godot/project/test.scn", "Godot\\test.doc" };
- static const char *base_dir[4] = { "C:\\Godot\\project", "/Godot/project", "../Godot/project", "Godot" };
- static const char *base_name[4] = { "C:\\Godot\\project\\test", "/Godot/project/test", "../Godot/project/test", "Godot\\test" };
- static const char *ext[4] = { "tscn", "xscn", "scn", "doc" };
- static const char *file[4] = { "test.tscn", "test.xscn", "test.scn", "test.doc" };
- static const bool abs[4] = { true, true, false, false };
-
- for (int i = 0; i < 4; i++) {
- godot_string s, t, u, f;
- godot_string_new_with_latin1_chars(&s, path[i]);
-
- t = godot_string_get_base_dir(&s);
- godot_string_new_with_latin1_chars(&u, base_dir[i]);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- t = godot_string_get_basename(&s);
- godot_string_new_with_latin1_chars(&u, base_name[i]);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- t = godot_string_get_extension(&s);
- godot_string_new_with_latin1_chars(&u, ext[i]);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- t = godot_string_get_file(&s);
- godot_string_new_with_latin1_chars(&u, file[i]);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- godot_string s_simp;
- s_simp = godot_string_simplify_path(&s);
- t = godot_string_get_base_dir(&s_simp);
- godot_string_new_with_latin1_chars(&u, file[i]);
- f = godot_string_plus_file(&t, &u);
- CHECK(u32scmp(godot_string_get_data(&f), godot_string_get_data(&s_simp)) == 0);
- godot_string_destroy(&f);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
- godot_string_destroy(&s_simp);
-
- CHECK(godot_string_is_abs_path(&s) == abs[i]);
- CHECK(godot_string_is_rel_path(&s) != abs[i]);
-
- godot_string_destroy(&s);
- }
-
- static const char *file_name[3] = { "test.tscn", "test://.xscn", "?tes*t.scn" };
- static const bool valid[3] = { true, false, false };
- for (int i = 0; i < 3; i++) {
- godot_string s;
- godot_string_new_with_latin1_chars(&s, file_name[i]);
- CHECK(godot_string_is_valid_filename(&s) == valid[i]);
- godot_string_destroy(&s);
- }
-}
-
-TEST_CASE("[GDNative String] hash") {
- godot_string a, b, c;
- godot_string_new_with_latin1_chars(&a, "Test");
- godot_string_new_with_latin1_chars(&b, "Test");
- godot_string_new_with_latin1_chars(&c, "West");
- CHECK(godot_string_hash(&a) == godot_string_hash(&b));
- CHECK(godot_string_hash(&a) != godot_string_hash(&c));
-
- CHECK(godot_string_hash64(&a) == godot_string_hash64(&b));
- CHECK(godot_string_hash64(&a) != godot_string_hash64(&c));
-
- godot_string_destroy(&a);
- godot_string_destroy(&b);
- godot_string_destroy(&c);
-}
-
-TEST_CASE("[GDNative String] http_escape/unescape") {
- godot_string s, t, u;
- godot_string_new_with_latin1_chars(&s, "Godot Engine:'docs'");
- godot_string_new_with_latin1_chars(&t, "Godot%20Engine%3A%27docs%27");
-
- u = godot_string_http_escape(&s);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
-
- u = godot_string_http_unescape(&t);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
- godot_string_destroy(&u);
-
- godot_string_destroy(&s);
- godot_string_destroy(&t);
-}
-
-TEST_CASE("[GDNative String] percent_encode/decode") {
- godot_string s, t, u;
- godot_string_new_with_latin1_chars(&s, "Godot Engine:'docs'");
- godot_string_new_with_latin1_chars(&t, "Godot%20Engine%3a%27docs%27");
-
- u = godot_string_percent_encode(&s);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
-
- u = godot_string_percent_decode(&t);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
- godot_string_destroy(&u);
-
- godot_string_destroy(&s);
- godot_string_destroy(&t);
-}
-
-TEST_CASE("[GDNative String] xml_escape/unescape") {
- godot_string s, t, u;
- godot_string_new_with_latin1_chars(&s, "\"Test\" <test@test&'test'>");
-
- t = godot_string_xml_escape_with_quotes(&s);
- u = godot_string_xml_unescape(&t);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- t = godot_string_xml_escape(&s);
- u = godot_string_xml_unescape(&t);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Strip escapes") {
- godot_string s, t, u;
- godot_string_new_with_latin1_chars(&s, "\t\tTest Test\r\n Test");
- godot_string_new_with_latin1_chars(&t, "Test Test Test");
-
- u = godot_string_strip_escapes(&s);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
-
- godot_string_destroy(&t);
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Strip edges") {
- godot_string s, t, u;
- godot_string_new_with_latin1_chars(&s, "\t Test Test ");
-
- godot_string_new_with_latin1_chars(&t, "Test Test ");
- u = godot_string_strip_edges(&s, true, false);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "\t Test Test");
- u = godot_string_strip_edges(&s, false, true);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "Test Test");
- u = godot_string_strip_edges(&s, true, true);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Similarity") {
- godot_string a, b, c;
- godot_string_new_with_latin1_chars(&a, "Test");
- godot_string_new_with_latin1_chars(&b, "West");
- godot_string_new_with_latin1_chars(&c, "Toad");
-
- CHECK(godot_string_similarity(&a, &b) > godot_string_similarity(&a, &c));
-
- godot_string_destroy(&a);
- godot_string_destroy(&b);
- godot_string_destroy(&c);
-}
-
-TEST_CASE("[GDNative String] Trim") {
- godot_string s, t, u, p;
- godot_string_new_with_latin1_chars(&s, "aaaTestbbb");
-
- godot_string_new_with_latin1_chars(&p, "aaa");
- godot_string_new_with_latin1_chars(&t, "Testbbb");
- u = godot_string_trim_prefix(&s, &p);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
- godot_string_destroy(&p);
-
- godot_string_new_with_latin1_chars(&p, "bbb");
- godot_string_new_with_latin1_chars(&t, "aaaTest");
- u = godot_string_trim_suffix(&s, &p);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
- godot_string_destroy(&p);
-
- godot_string_new_with_latin1_chars(&p, "Test");
- u = godot_string_trim_suffix(&s, &p);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&s)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&p);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Right/Left") {
- godot_string s, t, u;
- godot_string_new_with_latin1_chars(&s, "aaaTestbbb");
- // ^
-
- godot_string_new_with_latin1_chars(&t, "tbbb");
- u = godot_string_right(&s, 6);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&t, "aaaTes");
- u = godot_string_left(&s, 6);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
-}
-
-TEST_CASE("[GDNative String] Repeat") {
- godot_string t, u;
- godot_string_new_with_latin1_chars(&t, "ab");
-
- u = godot_string_repeat(&t, 4);
- CHECK(u32scmp(godot_string_get_data(&u), U"abababab") == 0);
- godot_string_destroy(&u);
-
- godot_string_destroy(&t);
-}
-
-TEST_CASE("[GDNative String] SHA1/SHA256/MD5") {
- godot_string s, t, sha1, sha256, md5;
- godot_string_new_with_latin1_chars(&s, "Godot");
- godot_string_new_with_latin1_chars(&sha1, "a1e91f39b9fce6a9998b14bdbe2aa2b39dc2d201");
- static uint8_t sha1_buf[20] = {
- 0xA1, 0xE9, 0x1F, 0x39, 0xB9, 0xFC, 0xE6, 0xA9, 0x99, 0x8B, 0x14, 0xBD, 0xBE, 0x2A, 0xA2, 0xB3,
- 0x9D, 0xC2, 0xD2, 0x01
- };
- godot_string_new_with_latin1_chars(&sha256, "2a02b2443f7985d89d09001086ae3dcfa6eb0f55c6ef170715d42328e16e6cb8");
- static uint8_t sha256_buf[32] = {
- 0x2A, 0x02, 0xB2, 0x44, 0x3F, 0x79, 0x85, 0xD8, 0x9D, 0x09, 0x00, 0x10, 0x86, 0xAE, 0x3D, 0xCF,
- 0xA6, 0xEB, 0x0F, 0x55, 0xC6, 0xEF, 0x17, 0x07, 0x15, 0xD4, 0x23, 0x28, 0xE1, 0x6E, 0x6C, 0xB8
- };
- godot_string_new_with_latin1_chars(&md5, "4a336d087aeb0390da10ee2ea7cb87f8");
- static uint8_t md5_buf[16] = {
- 0x4A, 0x33, 0x6D, 0x08, 0x7A, 0xEB, 0x03, 0x90, 0xDA, 0x10, 0xEE, 0x2E, 0xA7, 0xCB, 0x87, 0xF8
- };
-
- godot_packed_byte_array buf = godot_string_sha1_buffer(&s);
- CHECK(memcmp(sha1_buf, godot_packed_byte_array_ptr(&buf), 20) == 0);
- godot_packed_byte_array_destroy(&buf);
-
- t = godot_string_sha1_text(&s);
- CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&sha1)) == 0);
- godot_string_destroy(&t);
-
- buf = godot_string_sha256_buffer(&s);
- CHECK(memcmp(sha256_buf, godot_packed_byte_array_ptr(&buf), 32) == 0);
- godot_packed_byte_array_destroy(&buf);
-
- t = godot_string_sha256_text(&s);
- CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&sha256)) == 0);
- godot_string_destroy(&t);
-
- buf = godot_string_md5_buffer(&s);
- CHECK(memcmp(md5_buf, godot_packed_byte_array_ptr(&buf), 16) == 0);
- godot_packed_byte_array_destroy(&buf);
-
- t = godot_string_md5_text(&s);
- CHECK(u32scmp(godot_string_get_data(&t), godot_string_get_data(&md5)) == 0);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
- godot_string_destroy(&sha1);
- godot_string_destroy(&sha256);
- godot_string_destroy(&md5);
-}
-
-TEST_CASE("[GDNative String] Join") {
- godot_string s, t, u;
- godot_string_new_with_latin1_chars(&s, ", ");
-
- godot_packed_string_array parts;
- godot_packed_string_array_new(&parts);
- godot_string_new_with_latin1_chars(&t, "One");
- godot_packed_string_array_push_back(&parts, &t);
- godot_string_destroy(&t);
- godot_string_new_with_latin1_chars(&t, "B");
- godot_packed_string_array_push_back(&parts, &t);
- godot_string_destroy(&t);
- godot_string_new_with_latin1_chars(&t, "C");
- godot_packed_string_array_push_back(&parts, &t);
- godot_string_destroy(&t);
-
- godot_string_new_with_latin1_chars(&u, "One, B, C");
- t = godot_string_join(&s, &parts);
- CHECK(u32scmp(godot_string_get_data(&u), godot_string_get_data(&t)) == 0);
- godot_string_destroy(&u);
- godot_string_destroy(&t);
-
- godot_string_destroy(&s);
- godot_packed_string_array_destroy(&parts);
-}
-
-TEST_CASE("[GDNative String] Is_*") {
- static const char *data[12] = { "-30", "100", "10.1", "10,1", "1e2", "1e-2", "1e2e3", "0xAB", "AB", "Test1", "1Test", "Test*1" };
- static bool isnum[12] = { true, true, true, false, false, false, false, false, false, false, false, false };
- static bool isint[12] = { true, true, false, false, false, false, false, false, false, false, false, false };
- static bool ishex[12] = { true, true, false, false, true, false, true, false, true, false, false, false };
- static bool ishex_p[12] = { false, false, false, false, false, false, false, true, false, false, false, false };
- static bool isflt[12] = { true, true, true, false, true, true, false, false, false, false, false, false };
- static bool isid[12] = { false, false, false, false, false, false, false, false, true, true, false, false };
-
- for (int i = 0; i < 12; i++) {
- godot_string s;
- godot_string_new_with_latin1_chars(&s, data[i]);
- CHECK(godot_string_is_numeric(&s) == isnum[i]);
- CHECK(godot_string_is_valid_integer(&s) == isint[i]);
- CHECK(godot_string_is_valid_hex_number(&s, false) == ishex[i]);
- CHECK(godot_string_is_valid_hex_number(&s, true) == ishex_p[i]);
- CHECK(godot_string_is_valid_float(&s) == isflt[i]);
- CHECK(godot_string_is_valid_identifier(&s) == isid[i]);
- godot_string_destroy(&s);
- }
-}
-
-TEST_CASE("[GDNative String] humanize_size") {
- godot_string s;
-
- s = godot_string_humanize_size(1000);
- CHECK(u32scmp(godot_string_get_data(&s), U"1000 B") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_humanize_size(1025);
- CHECK(u32scmp(godot_string_get_data(&s), U"1.00 KiB") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_humanize_size(1025300);
- CHECK(u32scmp(godot_string_get_data(&s), U"1001.2 KiB") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_humanize_size(100523550);
- CHECK(u32scmp(godot_string_get_data(&s), U"95.86 MiB") == 0);
- godot_string_destroy(&s);
-
- s = godot_string_humanize_size(5345555000);
- CHECK(u32scmp(godot_string_get_data(&s), U"4.97 GiB") == 0);
- godot_string_destroy(&s);
-}
-} // namespace TestGDNativeString
-
-#endif // TEST_GDNATIVE_STRING_H
diff --git a/modules/gdnative/tests/test_variant.h b/modules/gdnative/tests/test_variant.h
new file mode 100644
index 0000000000..aeceb6e68f
--- /dev/null
+++ b/modules/gdnative/tests/test_variant.h
@@ -0,0 +1,205 @@
+/*************************************************************************/
+/* test_variant.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_GDNATIVE_VARIANT_H
+#define TEST_GDNATIVE_VARIANT_H
+
+#include <gdnative/gdnative.h>
+#include <gdnative/variant.h>
+
+#include "tests/test_macros.h"
+
+namespace TestGDNativeVariant {
+
+TEST_CASE("[GDNative Variant] New Variant with copy") {
+ godot_variant src;
+ godot_variant_new_int(&src, 42);
+
+ godot_variant copy;
+ godot_variant_new_copy(&copy, &src);
+
+ CHECK(godot_variant_as_int(&copy) == 42);
+ CHECK(godot_variant_get_type(&copy) == GODOT_VARIANT_TYPE_INT);
+
+ godot_variant_destroy(&src);
+ godot_variant_destroy(&copy);
+}
+
+TEST_CASE("[GDNative Variant] New Variant with Nil") {
+ godot_variant val;
+ godot_variant_new_nil(&val);
+
+ CHECK(godot_variant_get_type(&val) == GODOT_VARIANT_TYPE_NIL);
+
+ godot_variant_destroy(&val);
+}
+
+TEST_CASE("[GDNative Variant] New Variant with bool") {
+ godot_variant val;
+ godot_variant_new_bool(&val, true);
+
+ CHECK(godot_variant_as_bool(&val));
+ CHECK(godot_variant_get_type(&val) == GODOT_VARIANT_TYPE_BOOL);
+
+ godot_variant_destroy(&val);
+}
+
+TEST_CASE("[GDNative Variant] New Variant with float") {
+ godot_variant val;
+ godot_variant_new_float(&val, 4.2);
+
+ CHECK(godot_variant_as_float(&val) == 4.2);
+ CHECK(godot_variant_get_type(&val) == GODOT_VARIANT_TYPE_FLOAT);
+
+ godot_variant_destroy(&val);
+}
+
+TEST_CASE("[GDNative Variant] New Variant with String") {
+ String str = "something";
+
+ godot_variant val;
+ godot_variant_new_string(&val, (godot_string *)&str);
+ godot_string gd_str = godot_variant_as_string(&val);
+ String *result = (String *)&gd_str;
+
+ CHECK(*result == String("something"));
+ CHECK(godot_variant_get_type(&val) == GODOT_VARIANT_TYPE_STRING);
+
+ godot_variant_destroy(&val);
+ godot_string_destroy(&gd_str);
+}
+
+TEST_CASE("[GDNative Variant] Variant call") {
+ String str("something");
+ godot_variant self;
+ godot_variant_new_string(&self, (godot_string *)&str);
+
+ godot_variant ret;
+
+ godot_string_name method;
+ godot_string_name_new_with_latin1_chars(&method, "is_valid_identifier");
+
+ godot_variant_call_error error;
+ godot_variant_call(&self, &method, NULL, 0, &ret, &error);
+
+ CHECK(godot_variant_get_type(&ret) == GODOT_VARIANT_TYPE_BOOL);
+ CHECK(godot_variant_as_bool(&ret));
+
+ godot_variant_destroy(&ret);
+ godot_variant_destroy(&self);
+ godot_string_name_destroy(&method);
+}
+
+TEST_CASE("[GDNative Variant] Variant evaluate") {
+ godot_variant one;
+ godot_variant_new_int(&one, 1);
+ godot_variant two;
+ godot_variant_new_int(&two, 2);
+
+ godot_variant three;
+ godot_variant_new_nil(&three);
+ bool valid = false;
+
+ godot_variant_evaluate(GODOT_VARIANT_OP_ADD, &one, &two, &three, &valid);
+
+ CHECK(godot_variant_get_type(&three) == GODOT_VARIANT_TYPE_INT);
+ CHECK(godot_variant_as_int(&three) == 3);
+ CHECK(valid);
+
+ godot_variant_destroy(&one);
+ godot_variant_destroy(&two);
+ godot_variant_destroy(&three);
+}
+
+TEST_CASE("[GDNative Variant] Variant set/get named") {
+ godot_string_name x;
+ godot_string_name_new_with_latin1_chars(&x, "x");
+
+ Vector2 vec(0, 0);
+ godot_variant self;
+ godot_variant_new_vector2(&self, (godot_vector2 *)&vec);
+
+ godot_variant set;
+ godot_variant_new_float(&set, 1.0);
+
+ bool set_valid = false;
+ godot_variant_set_named(&self, &x, &set, &set_valid);
+
+ bool get_valid = false;
+ godot_variant get = godot_variant_get_named(&self, &x, &get_valid);
+
+ CHECK(get_valid);
+ CHECK(set_valid);
+ CHECK(godot_variant_get_type(&get) == GODOT_VARIANT_TYPE_FLOAT);
+ CHECK(godot_variant_as_float(&get) == 1.0);
+
+ godot_string_name_destroy(&x);
+ godot_variant_destroy(&self);
+ godot_variant_destroy(&set);
+ godot_variant_destroy(&get);
+}
+
+TEST_CASE("[GDNative Variant] Get utility function argument name") {
+ godot_string_name function;
+ godot_string_name_new_with_latin1_chars(&function, "pow");
+
+ godot_string arg_name = godot_variant_get_utility_function_argument_name(&function, 0);
+
+ String *arg_name_str = (String *)&arg_name;
+
+ CHECK(*arg_name_str == "base");
+
+ godot_string_destroy(&arg_name);
+ godot_string_name_destroy(&function);
+}
+
+TEST_CASE("[GDNative Variant] Get utility function list") {
+ int count = godot_variant_get_utility_function_count();
+
+ godot_string_name *c_list = (godot_string_name *)godot_alloc(count * sizeof(godot_string_name));
+ godot_variant_get_utility_function_list(c_list);
+
+ List<StringName> cpp_list;
+ Variant::get_utility_function_list(&cpp_list);
+
+ godot_string_name *cur = c_list;
+
+ for (const List<StringName>::Element *E = cpp_list.front(); E; E = E->next()) {
+ const StringName &cpp_name = E->get();
+ StringName *c_name = (StringName *)cur++;
+
+ CHECK(*c_name == cpp_name);
+ }
+
+ godot_free(c_list);
+}
+} // namespace TestGDNativeVariant
+
+#endif // TEST_GDNATIVE_VARIANT_H
diff --git a/modules/gdnative/text/register_types.cpp b/modules/gdnative/text/register_types.cpp
index e1d4547aa0..67385d2fbf 100644
--- a/modules/gdnative/text/register_types.cpp
+++ b/modules/gdnative/text/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/text/register_types.h b/modules/gdnative/text/register_types.h
index 027653e58e..cd4f2a3089 100644
--- a/modules/gdnative/text/register_types.h
+++ b/modules/gdnative/text/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/text/text_server_gdnative.cpp b/modules/gdnative/text/text_server_gdnative.cpp
index cb87adafe8..7cd8de5f2e 100644
--- a/modules/gdnative/text/text_server_gdnative.cpp
+++ b/modules/gdnative/text/text_server_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -113,6 +113,28 @@ RID TextServerGDNative::create_font_memory(const uint8_t *p_data, size_t p_size,
return rid;
}
+RID TextServerGDNative::create_font_bitmap(float p_height, float p_ascent, int p_base_size) {
+ ERR_FAIL_COND_V(interface == nullptr, RID());
+ godot_rid result = interface->create_font_bitmap(data, p_height, p_ascent, p_base_size);
+ RID rid = *(RID *)&result;
+ return rid;
+}
+
+void TextServerGDNative::font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) {
+ ERR_FAIL_COND(interface == nullptr);
+ interface->font_bitmap_add_texture(data, (godot_rid *)&p_font, (const godot_object *)p_texture.ptr());
+}
+
+void TextServerGDNative::font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
+ ERR_FAIL_COND(interface == nullptr);
+ interface->font_bitmap_add_char(data, (godot_rid *)&p_font, p_char, p_texture_idx, (const godot_rect2 *)&p_rect, (const godot_vector2 *)&p_align, p_advance);
+}
+
+void TextServerGDNative::font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) {
+ ERR_FAIL_COND(interface == nullptr);
+ interface->font_bitmap_add_kerning_pair(data, (godot_rid *)&p_font, p_A, p_B, p_kerning);
+}
+
float TextServerGDNative::font_get_height(RID p_font, int p_size) const {
ERR_FAIL_COND_V(interface == nullptr, 0.f);
return interface->font_get_height(data, (godot_rid *)&p_font, p_size);
@@ -138,6 +160,26 @@ float TextServerGDNative::font_get_underline_thickness(RID p_font, int p_size) c
return interface->font_get_underline_thickness(data, (godot_rid *)&p_font, p_size);
}
+int TextServerGDNative::font_get_spacing_space(RID p_font) const {
+ ERR_FAIL_COND_V(interface == nullptr, 0);
+ return interface->font_get_spacing_space(data, (godot_rid *)&p_font);
+}
+
+void TextServerGDNative::font_set_spacing_space(RID p_font, int p_value) {
+ ERR_FAIL_COND(interface == nullptr);
+ interface->font_set_spacing_space(data, (godot_rid *)&p_font, p_value);
+}
+
+int TextServerGDNative::font_get_spacing_glyph(RID p_font) const {
+ ERR_FAIL_COND_V(interface == nullptr, 0);
+ return interface->font_get_spacing_glyph(data, (godot_rid *)&p_font);
+}
+
+void TextServerGDNative::font_set_spacing_glyph(RID p_font, int p_value) {
+ ERR_FAIL_COND(interface == nullptr);
+ interface->font_set_spacing_glyph(data, (godot_rid *)&p_font, p_value);
+}
+
void TextServerGDNative::font_set_antialiased(RID p_font, bool p_antialiased) {
ERR_FAIL_COND(interface == nullptr);
interface->font_set_antialiased(data, (godot_rid *)&p_font, p_antialiased);
@@ -703,12 +745,12 @@ void GDAPI godot_glyph_set_offset(godot_glyph *p_self, const godot_vector2 *p_of
self->y_off = offset->y;
}
-godot_real GDAPI godot_glyph_get_advance(const godot_glyph *p_self) {
+godot_float GDAPI godot_glyph_get_advance(const godot_glyph *p_self) {
const TextServer::Glyph *self = (const TextServer::Glyph *)p_self;
return self->advance;
}
-void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_real p_advance) {
+void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_float p_advance) {
TextServer::Glyph *self = (TextServer::Glyph *)p_self;
self->advance = p_advance;
}
@@ -839,9 +881,9 @@ godot_int GDAPI godot_packed_glyph_array_size(const godot_packed_glyph_array *p_
return self->size();
}
-godot_bool GDAPI godot_packed_glyph_array_empty(const godot_packed_glyph_array *p_self) {
+godot_bool GDAPI godot_packed_glyph_array_is_empty(const godot_packed_glyph_array *p_self) {
const Vector<TextServer::Glyph> *self = (const Vector<TextServer::Glyph> *)p_self;
- return self->empty();
+ return self->is_empty();
}
void GDAPI godot_packed_glyph_array_destroy(godot_packed_glyph_array *p_self) {
diff --git a/modules/gdnative/text/text_server_gdnative.h b/modules/gdnative/text/text_server_gdnative.h
index 959302aaf4..931bb44885 100644
--- a/modules/gdnative/text/text_server_gdnative.h
+++ b/modules/gdnative/text/text_server_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,6 +64,11 @@ public:
virtual RID create_font_system(const String &p_name, int p_base_size = 16) override;
virtual RID create_font_resource(const String &p_filename, int p_base_size = 16) override;
virtual RID create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16) override;
+ virtual RID create_font_bitmap(float p_height, float p_ascent, int p_base_size = 16) override;
+
+ virtual void font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) override;
+ virtual void font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override;
+ virtual void font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) override;
virtual float font_get_height(RID p_font, int p_size) const override;
virtual float font_get_ascent(RID p_font, int p_size) const override;
@@ -72,6 +77,12 @@ public:
virtual float font_get_underline_position(RID p_font, int p_size) const override;
virtual float font_get_underline_thickness(RID p_font, int p_size) const override;
+ virtual int font_get_spacing_space(RID p_font) const override;
+ virtual void font_set_spacing_space(RID p_font, int p_value) override;
+
+ virtual int font_get_spacing_glyph(RID p_font) const override;
+ virtual void font_set_spacing_glyph(RID p_font, int p_value) override;
+
virtual void font_set_antialiased(RID p_font, bool p_antialiased) override;
virtual bool font_get_antialiased(RID p_font) const override;
diff --git a/modules/gdnative/videodecoder/register_types.cpp b/modules/gdnative/videodecoder/register_types.cpp
index 8ee1c8d183..394831daeb 100644
--- a/modules/gdnative/videodecoder/register_types.cpp
+++ b/modules/gdnative/videodecoder/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/videodecoder/register_types.h b/modules/gdnative/videodecoder/register_types.h
index b1a83d4071..809225c925 100644
--- a/modules/gdnative/videodecoder/register_types.h
+++ b/modules/gdnative/videodecoder/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
index 61e882f2fe..f2fb0a2fdc 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -250,7 +250,7 @@ void VideoStreamPlaybackGDNative::play() {
playing = true;
- delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms");
+ delay_compensation = ProjectSettings::get_singleton()->get("audio/video/video_delay_compensation_ms");
delay_compensation /= 1000.0;
}
@@ -360,7 +360,7 @@ void VideoStreamGDNative::set_audio_track(int p_track) {
/* --- NOTE ResourceFormatLoaderVideoStreamGDNative starts here. ----- */
-RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h
index 408d4a2454..140888cd4b 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.h
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -118,7 +118,7 @@ class VideoStreamPlaybackGDNative : public VideoStreamPlayback {
AudioMixCallback mix_callback = nullptr;
int num_channels = -1;
- float time = 0;
+ float time = 0.0;
bool seek_backward = false;
int mix_rate = 0;
double delay_compensation = 0;
@@ -196,7 +196,7 @@ public:
class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/xr/register_types.cpp b/modules/gdnative/xr/register_types.cpp
index da3a7dc4b8..b60a04f470 100644
--- a/modules/gdnative/xr/register_types.cpp
+++ b/modules/gdnative/xr/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/xr/register_types.h b/modules/gdnative/xr/register_types.h
index 2501d28651..4e7469abe9 100644
--- a/modules/gdnative/xr/register_types.h
+++ b/modules/gdnative/xr/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnative/xr/xr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp
index d1d575db62..5bbf70174c 100644
--- a/modules/gdnative/xr/xr_interface_gdnative.cpp
+++ b/modules/gdnative/xr/xr_interface_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -190,7 +190,7 @@ CameraMatrix XRInterfaceGDNative::get_projection_for_eye(XRInterface::Eyes p_eye
ERR_FAIL_COND_V(interface == nullptr, CameraMatrix());
- interface->fill_projection_for_eye(data, (godot_real *)cm.matrix, (godot_int)p_eye, p_aspect, p_z_near, p_z_far);
+ interface->fill_projection_for_eye(data, (godot_float *)cm.matrix, (godot_int)p_eye, p_aspect, p_z_near, p_z_far);
return cm;
}
@@ -234,7 +234,7 @@ void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_inte
XRServer::get_singleton()->add_interface(new_interface);
}
-godot_real GDAPI godot_xr_get_worldscale() {
+godot_float GDAPI godot_xr_get_worldscale() {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 1.0);
@@ -249,7 +249,7 @@ godot_transform GDAPI godot_xr_get_reference_frame() {
if (xr_server != nullptr) {
*reference_frame_ptr = xr_server->get_reference_frame();
} else {
- godot_transform_new_identity(&reference_frame);
+ memnew_placement(&reference_frame, Transform);
}
return reference_frame;
@@ -387,7 +387,7 @@ void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p
}
}
-void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) {
+void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_float p_value, godot_bool p_can_be_negative) {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server);
@@ -406,7 +406,7 @@ void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_a
}
}
-godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) {
+godot_float GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 0.0);
diff --git a/modules/gdnative/xr/xr_interface_gdnative.h b/modules/gdnative/xr/xr_interface_gdnative.h
index de96487397..84bd8fc731 100644
--- a/modules/gdnative/xr/xr_interface_gdnative.h
+++ b/modules/gdnative/xr/xr_interface_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp
index c80cdcfeab..af76d9a4cc 100644
--- a/modules/gdnavigation/gd_navigation_server.cpp
+++ b/modules/gdnavigation/gd_navigation_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -200,11 +200,11 @@ real_t GdNavigationServer::map_get_edge_connection_margin(RID p_map) const {
return map->get_edge_connection_margin();
}
-Vector<Vector3> GdNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) const {
+Vector<Vector3> GdNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>());
- return map->get_path(p_origin, p_destination, p_optimize);
+ return map->get_path(p_origin, p_destination, p_optimize, p_layers);
}
Vector3 GdNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
@@ -273,6 +273,20 @@ COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform) {
region->set_transform(p_transform);
}
+COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers) {
+ NavRegion *region = region_owner.getornull(p_region);
+ ERR_FAIL_COND(region == nullptr);
+
+ region->set_layers(p_layers);
+}
+
+uint32_t GdNavigationServer::region_get_layers(RID p_region) const {
+ NavRegion *region = region_owner.getornull(p_region);
+ ERR_FAIL_COND_V(region == nullptr, 0);
+
+ return region->get_layers();
+}
+
COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh) {
NavRegion *region = region_owner.getornull(p_region);
ERR_FAIL_COND(region == nullptr);
diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h
index c00d60ced7..8bc65eccab 100644
--- a/modules/gdnavigation/gd_navigation_server.h
+++ b/modules/gdnavigation/gd_navigation_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -100,7 +100,7 @@ public:
COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin);
virtual real_t map_get_edge_connection_margin(RID p_map) const;
- virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) const;
+ virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers = 1) const;
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const;
virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const;
@@ -109,6 +109,8 @@ public:
virtual RID region_create() const;
COMMAND_2(region_set_map, RID, p_region, RID, p_map);
+ COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers);
+ virtual uint32_t region_get_layers(RID p_region) const;
COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform);
COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh);
virtual void region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const;
diff --git a/modules/gdnavigation/nav_map.cpp b/modules/gdnavigation/nav_map.cpp
index c8c1b422e8..5289975e4b 100644
--- a/modules/gdnavigation/nav_map.cpp
+++ b/modules/gdnavigation/nav_map.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -70,7 +70,7 @@ gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
return p;
}
-Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const {
+Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const {
const gd::Polygon *begin_poly = nullptr;
const gd::Polygon *end_poly = nullptr;
Vector3 begin_point;
@@ -82,6 +82,11 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
for (size_t i(0); i < polygons.size(); i++) {
const gd::Polygon &p = polygons[i];
+ // Only consider the polygon if it in a region with compatible layers.
+ if ((p_layers & p.owner->get_layers()) == 0) {
+ continue;
+ }
+
// For each point cast a face and check the distance between the origin/destination
for (size_t point_id = 2; point_id < p.points.size(); point_id++) {
Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
@@ -144,6 +149,11 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) {
gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id];
+ // Only consider the polygon if it in a region with compatible layers.
+ if ((p_layers & least_cost_poly->poly->owner->get_layers()) == 0) {
+ continue;
+ }
+
const gd::Edge &edge = least_cost_poly->poly->edges[i];
if (!edge.other_polygon) {
continue;
@@ -629,7 +639,7 @@ void NavMap::sync() {
connection->get().B->edges[connection->get().B_edge].other_edge = connection->get().A_edge;
} else {
// The edge is already connected with another edge, skip.
- ERR_PRINT("Attempted to merge a navigation mesh triangle edge with another already-merged edge. This happens when the Navigation3D's `cell_size` is different from the one used to generate the navigation mesh. This will cause navigation problem.");
+ ERR_PRINT("Attempted to merge a navigation mesh triangle edge with another already-merged edge. This happens when the current `cell_size` is different from the one used to generate the navigation mesh. This will cause navigation problem.");
}
}
}
diff --git a/modules/gdnavigation/nav_map.h b/modules/gdnavigation/nav_map.h
index 892755f3f9..6b7cfae324 100644
--- a/modules/gdnavigation/nav_map.h
+++ b/modules/gdnavigation/nav_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -102,7 +102,7 @@ public:
gd::PointKey get_point_key(const Vector3 &p_pos) const;
- Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const;
+ Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers = 1) const;
Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const;
Vector3 get_closest_point(const Vector3 &p_point) const;
Vector3 get_closest_point_normal(const Vector3 &p_point) const;
diff --git a/modules/gdnavigation/nav_region.cpp b/modules/gdnavigation/nav_region.cpp
index 51fba67cc3..a07995bc11 100644
--- a/modules/gdnavigation/nav_region.cpp
+++ b/modules/gdnavigation/nav_region.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,6 +41,14 @@ void NavRegion::set_map(NavMap *p_map) {
polygons_dirty = true;
}
+void NavRegion::set_layers(uint32_t p_layers) {
+ layers = p_layers;
+}
+
+uint32_t NavRegion::get_layers() const {
+ return layers;
+}
+
void NavRegion::set_transform(Transform p_transform) {
transform = p_transform;
polygons_dirty = true;
diff --git a/modules/gdnavigation/nav_region.h b/modules/gdnavigation/nav_region.h
index 731855bfb5..fff7843fde 100644
--- a/modules/gdnavigation/nav_region.h
+++ b/modules/gdnavigation/nav_region.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,10 +31,10 @@
#ifndef NAV_REGION_H
#define NAV_REGION_H
-#include "nav_rid.h"
+#include "scene/resources/navigation_mesh.h"
+#include "nav_rid.h"
#include "nav_utils.h"
-#include "scene/3d/navigation_3d.h"
#include <vector>
/**
@@ -48,6 +48,7 @@ class NavRegion : public NavRid {
NavMap *map = nullptr;
Transform transform;
Ref<NavigationMesh> mesh;
+ uint32_t layers = 1;
bool polygons_dirty = true;
@@ -66,6 +67,9 @@ public:
return map;
}
+ void set_layers(uint32_t p_layers);
+ uint32_t get_layers() const;
+
void set_transform(Transform transform);
const Transform &get_transform() const {
return transform;
diff --git a/modules/gdnavigation/nav_rid.h b/modules/gdnavigation/nav_rid.h
index b727fceb04..a0a60a3643 100644
--- a/modules/gdnavigation/nav_rid.h
+++ b/modules/gdnavigation/nav_rid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnavigation/nav_utils.h b/modules/gdnavigation/nav_utils.h
index 40e54df553..d257a95ef1 100644
--- a/modules/gdnavigation/nav_utils.h
+++ b/modules/gdnavigation/nav_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,7 +51,7 @@ union PointKey {
int64_t z : 21;
};
- uint64_t key;
+ uint64_t key = 0;
bool operator<(const PointKey &p_key) const { return key < p_key.key; }
};
@@ -86,8 +86,6 @@ struct Edge {
/// The other `Polygon` at this edge id has this `Polygon`.
int other_edge = -1;
-
- Edge() {}
};
struct Polygon {
@@ -111,8 +109,6 @@ struct Connection {
int A_edge = -1;
Polygon *B = nullptr;
int B_edge = -1;
-
- Connection() {}
};
struct NavigationPoly {
@@ -141,12 +137,12 @@ struct NavigationPoly {
};
struct FreeEdge {
- bool is_free;
- Polygon *poly;
- uint32_t edge_id;
+ bool is_free = false;
+ Polygon *poly = nullptr;
+ uint32_t edge_id = 0;
Vector3 edge_center;
Vector3 edge_dir;
- float edge_len_squared;
+ float edge_len_squared = 0.0;
};
} // namespace gd
diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
index 648f4f7cdd..aa9248d2a1 100644
--- a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
+++ b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -142,7 +142,7 @@ void NavigationMeshEditorPlugin::make_visible(bool p_visible) {
NavigationMeshEditorPlugin::NavigationMeshEditorPlugin(EditorNode *p_node) {
editor = p_node;
navigation_mesh_editor = memnew(NavigationMeshEditor);
- editor->get_viewport()->add_child(navigation_mesh_editor);
+ editor->get_main_control()->add_child(navigation_mesh_editor);
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, navigation_mesh_editor->bake_hbox);
navigation_mesh_editor->hide();
navigation_mesh_editor->bake_hbox->hide();
diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.h b/modules/gdnavigation/navigation_mesh_editor_plugin.h
index f09182fff4..c39269865b 100644
--- a/modules/gdnavigation/navigation_mesh_editor_plugin.h
+++ b/modules/gdnavigation/navigation_mesh_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnavigation/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp
index 3310123ca9..a7d4e79148 100644
--- a/modules/gdnavigation/navigation_mesh_generator.cpp
+++ b/modules/gdnavigation/navigation_mesh_generator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -151,7 +151,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform,
if (Object::cast_to<CSGShape3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
CSGShape3D *csg_shape = Object::cast_to<CSGShape3D>(p_node);
Array meshes = csg_shape->get_meshes();
- if (!meshes.empty()) {
+ if (!meshes.is_empty()) {
Ref<Mesh> mesh = meshes[1];
if (mesh.is_valid()) {
_add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_verticies, p_indices);
@@ -178,7 +178,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform,
if (box) {
Ref<BoxMesh> box_mesh;
box_mesh.instance();
- box_mesh->set_size(box->get_extents() * 2.0);
+ box_mesh->set_size(box->get_size());
mesh = box_mesh;
}
diff --git a/modules/gdnavigation/navigation_mesh_generator.h b/modules/gdnavigation/navigation_mesh_generator.h
index c5f7b2ab81..88ccdb1c41 100644
--- a/modules/gdnavigation/navigation_mesh_generator.h
+++ b/modules/gdnavigation/navigation_mesh_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnavigation/register_types.cpp b/modules/gdnavigation/register_types.cpp
index 1ae19ebe47..8443d3d242 100644
--- a/modules/gdnavigation/register_types.cpp
+++ b/modules/gdnavigation/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnavigation/register_types.h b/modules/gdnavigation/register_types.h
index cdbff1b937..c2bb08c649 100644
--- a/modules/gdnavigation/register_types.h
+++ b/modules/gdnavigation/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnavigation/rvo_agent.cpp b/modules/gdnavigation/rvo_agent.cpp
index 1e1bdbd07d..21e43d08c1 100644
--- a/modules/gdnavigation/rvo_agent.cpp
+++ b/modules/gdnavigation/rvo_agent.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdnavigation/rvo_agent.h b/modules/gdnavigation/rvo_agent.h
index de36508edb..369cb1f9a3 100644
--- a/modules/gdnavigation/rvo_agent.h
+++ b/modules/gdnavigation/rvo_agent.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,7 +53,7 @@ class RvoAgent : public NavRid {
NavMap *map = nullptr;
RVO::Agent agent;
AvoidanceComputedCallback callback;
- uint32_t map_update_id;
+ uint32_t map_update_id = 0;
public:
RvoAgent();
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 4ed129b3ff..9e974b6fdc 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -32,59 +32,6 @@
[/codeblock]
</description>
</method>
- <method name="ColorN">
- <return type="Color">
- </return>
- <argument index="0" name="name" type="String">
- </argument>
- <argument index="1" name="alpha" type="float" default="1.0">
- </argument>
- <description>
- Returns a color according to the standardized [code]name[/code] with [code]alpha[/code] ranging from 0 to 1.
- [codeblock]
- red = ColorN("red", 1)
- [/codeblock]
- Supported color names are the same as the constants defined in [Color].
- </description>
- </method>
- <method name="abs">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the absolute value of parameter [code]s[/code] (i.e. positive value).
- [codeblock]
- a = abs(-1) # a is 1
- [/codeblock]
- </description>
- </method>
- <method name="acos">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the arc cosine of [code]s[/code] in radians. Use to get the angle of cosine [code]s[/code].
- [codeblock]
- # c is 0.523599 or 30 degrees if converted with rad2deg(s)
- c = acos(0.866025)
- [/codeblock]
- </description>
- </method>
- <method name="asin">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the arc sine of [code]s[/code] in radians. Use to get the angle of sine [code]s[/code].
- [codeblock]
- # s is 0.523599 or 30 degrees if converted with rad2deg(s)
- s = asin(0.5)
- [/codeblock]
- </description>
- </method>
<method name="assert">
<return type="void">
</return>
@@ -93,7 +40,7 @@
<argument index="1" name="message" type="String" default="&quot;&quot;">
</argument>
<description>
- Asserts that the [code]condition[/code] is [code]true[/code]. If the [code]condition[/code] is [code]false[/code], an error is generated. When running from the editor, the running project will also be paused until you resume it. This can be used as a stronger form of [method push_error] for reporting errors to project developers or add-on users.
+ Asserts that the [code]condition[/code] is [code]true[/code]. If the [code]condition[/code] is [code]false[/code], an error is generated. When running from the editor, the running project will also be paused until you resume it. This can be used as a stronger form of [method @GlobalScope.push_error] for reporting errors to project developers or add-on users.
[b]Note:[/b] For performance reasons, the code inside [method assert] is only executed in debug builds or when running the project from the editor. Don't include code that has side effects in an [method assert] call. Otherwise, the project will behave differently when exported in release mode.
The optional [code]message[/code] argument, if given, is shown in addition to the generic "Assertion failed" message. You can use this to provide additional details about why the assertion failed.
[codeblock]
@@ -106,75 +53,10 @@
[/codeblock]
</description>
</method>
- <method name="atan">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the arc tangent of [code]s[/code] in radians. Use it to get the angle from an angle's tangent in trigonometry: [code]atan(tan(angle)) == angle[/code].
- The method cannot know in which quadrant the angle should fall. See [method atan2] if you have both [code]y[/code] and [code]x[/code].
- [codeblock]
- a = atan(0.5) # a is 0.463648
- [/codeblock]
- </description>
- </method>
- <method name="atan2">
- <return type="float">
- </return>
- <argument index="0" name="y" type="float">
- </argument>
- <argument index="1" name="x" type="float">
- </argument>
- <description>
- Returns the arc tangent of [code]y/x[/code] in radians. Use to get the angle of tangent [code]y/x[/code]. To compute the value, the method takes into account the sign of both arguments in order to determine the quadrant.
- Important note: The Y coordinate comes first, by convention.
- [codeblock]
- a = atan2(0, -1) # a is 3.141593
- [/codeblock]
- </description>
- </method>
- <method name="bytes2var">
- <return type="Variant">
- </return>
- <argument index="0" name="bytes" type="PackedByteArray">
- </argument>
- <argument index="1" name="allow_objects" type="bool" default="false">
- </argument>
- <description>
- Decodes a byte array back to a value. When [code]allow_objects[/code] is [code]true[/code] decoding objects is allowed.
- [b]WARNING:[/b] Deserialized object can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats (remote code execution).
- </description>
- </method>
- <method name="cartesian2polar">
- <return type="Vector2">
- </return>
- <argument index="0" name="x" type="float">
- </argument>
- <argument index="1" name="y" type="float">
- </argument>
- <description>
- Converts a 2D point expressed in the cartesian coordinate system (X and Y axis) to the polar coordinate system (a distance from the origin and an angle).
- </description>
- </method>
- <method name="ceil">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Rounds [code]s[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]s[/code].
- [codeblock]
- a = ceil(1.45) # a is 2.0
- a = ceil(1.001) # a is 2.0
- [/codeblock]
- See also [method floor], [method round], [method stepify], and [int].
- </description>
- </method>
<method name="char">
<return type="String">
</return>
- <argument index="0" name="code" type="int">
+ <argument index="0" name="char" type="int">
</argument>
<description>
Returns a character as a String of the given Unicode code point (which is compatible with ASCII code).
@@ -183,25 +65,6 @@
a = char(65 + 32) # a is "a"
a = char(8364) # a is "€"
[/codeblock]
- This is the inverse of [method ord].
- </description>
- </method>
- <method name="clamp">
- <return type="float">
- </return>
- <argument index="0" name="value" type="float">
- </argument>
- <argument index="1" name="min" type="float">
- </argument>
- <argument index="2" name="max" type="float">
- </argument>
- <description>
- Clamps [code]value[/code] and returns a value not less than [code]min[/code] and not more than [code]max[/code].
- [codeblock]
- a = clamp(1000, 1, 20) # a is 20
- a = clamp(-10, 1, 20) # a is 1
- a = clamp(15, 1, 20) # a is 15
- [/codeblock]
</description>
</method>
<method name="convert">
@@ -223,159 +86,15 @@
[/codeblock]
</description>
</method>
- <method name="cos">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the cosine of angle [code]s[/code] in radians.
- [codeblock]
- a = cos(TAU) # a is 1.0
- a = cos(PI) # a is -1.0
- [/codeblock]
- </description>
- </method>
- <method name="cosh">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the hyperbolic cosine of [code]s[/code] in radians.
- [codeblock]
- print(cosh(1)) # Prints 1.543081
- [/codeblock]
- </description>
- </method>
- <method name="db2linear">
- <return type="float">
- </return>
- <argument index="0" name="db" type="float">
- </argument>
- <description>
- Converts from decibels to linear energy (audio).
- </description>
- </method>
- <method name="dectime">
- <return type="float">
- </return>
- <argument index="0" name="value" type="float">
- </argument>
- <argument index="1" name="amount" type="float">
- </argument>
- <argument index="2" name="step" type="float">
- </argument>
- <description>
- Returns the result of [code]value[/code] decreased by [code]step[/code] * [code]amount[/code].
- [codeblock]
- a = dectime(60, 10, 0.1)) # a is 59.0
- [/codeblock]
- </description>
- </method>
- <method name="deg2rad">
- <return type="float">
- </return>
- <argument index="0" name="deg" type="float">
- </argument>
- <description>
- Converts an angle expressed in degrees to radians.
- [codeblock]
- r = deg2rad(180) # r is 3.141593
- [/codeblock]
- </description>
- </method>
<method name="dict2inst">
<return type="Object">
</return>
- <argument index="0" name="dict" type="Dictionary">
+ <argument index="0" name="dictionary" type="Dictionary">
</argument>
<description>
Converts a dictionary (previously created with [method inst2dict]) back to an instance. Useful for deserializing.
</description>
</method>
- <method name="ease">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <argument index="1" name="curve" type="float">
- </argument>
- <description>
- Easing function, based on exponent. The curve values are: 0 is constant, 1 is linear, 0 to 1 is ease-in, 1+ is ease out. Negative values are in-out/out in.
- </description>
- </method>
- <method name="exp">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- The natural exponential function. It raises the mathematical constant [b]e[/b] to the power of [code]s[/code] and returns it.
- [b]e[/b] has an approximate value of 2.71828, and can be obtained with [code]exp(1)[/code].
- For exponents to other bases use the method [method pow].
- [codeblock]
- a = exp(2) # Approximately 7.39
- [/codeblock]
- </description>
- </method>
- <method name="floor">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Rounds [code]s[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]s[/code].
- [codeblock]
- a = floor(2.45) # a is 2.0
- a = floor(2.99) # a is 2.0
- a = floor(-2.99) # a is -3.0
- [/codeblock]
- See also [method ceil], [method round], [method stepify], and [int].
- [b]Note:[/b] This method returns a float. If you need an integer and [code]s[/code] is a non-negative number, you can use [code]int(s)[/code] directly.
- </description>
- </method>
- <method name="fmod">
- <return type="float">
- </return>
- <argument index="0" name="a" type="float">
- </argument>
- <argument index="1" name="b" type="float">
- </argument>
- <description>
- Returns the floating-point remainder of [code]a/b[/code], keeping the sign of [code]a[/code].
- [codeblock]
- r = fmod(7, 5.5) # r is 1.5
- [/codeblock]
- For the integer remainder operation, use the % operator.
- </description>
- </method>
- <method name="fposmod">
- <return type="float">
- </return>
- <argument index="0" name="a" type="float">
- </argument>
- <argument index="1" name="b" type="float">
- </argument>
- <description>
- Returns the floating-point modulus of [code]a/b[/code] that wraps equally in positive and negative.
- [codeblock]
- for i in 7:
- var x = 0.5 * i - 1.5
- print("%4.1f %4.1f %4.1f" % [x, fmod(x, 1.5), fposmod(x, 1.5)])
- [/codeblock]
- Produces:
- [codeblock]
- -1.5 -0.0 0.0
- -1.0 -1.0 0.5
- -0.5 -0.5 1.0
- 0.0 0.0 0.0
- 0.5 0.5 0.5
- 1.0 1.0 1.0
- 1.5 0.0 0.0
- [/codeblock]
- </description>
- </method>
<method name="get_stack">
<return type="Array">
</return>
@@ -397,22 +116,10 @@
[/codeblock]
</description>
</method>
- <method name="hash">
- <return type="int">
- </return>
- <argument index="0" name="var" type="Variant">
- </argument>
- <description>
- Returns the integer hash of the variable passed.
- [codeblock]
- print(hash("a")) # Prints 177670
- [/codeblock]
- </description>
- </method>
<method name="inst2dict">
<return type="Dictionary">
</return>
- <argument index="0" name="inst" type="Object">
+ <argument index="0" name="instance" type="Object">
</argument>
<description>
Returns the passed instance converted to a dictionary (useful for serializing).
@@ -430,92 +137,6 @@
[/codeblock]
</description>
</method>
- <method name="instance_from_id">
- <return type="Object">
- </return>
- <argument index="0" name="instance_id" type="int">
- </argument>
- <description>
- Returns the Object that corresponds to [code]instance_id[/code]. All Objects have a unique instance ID.
- [codeblock]
- var foo = "bar"
- func _ready():
- var id = get_instance_id()
- var inst = instance_from_id(id)
- print(inst.foo) # Prints bar
- [/codeblock]
- </description>
- </method>
- <method name="inverse_lerp">
- <return type="float">
- </return>
- <argument index="0" name="from" type="float">
- </argument>
- <argument index="1" name="to" type="float">
- </argument>
- <argument index="2" name="weight" type="float">
- </argument>
- <description>
- Returns a normalized value considering the given range. This is the opposite of [method lerp].
- [codeblock]
- var middle = lerp(20, 30, 0.75)
- # `middle` is now 27.5.
- # Now, we pretend to have forgotten the original ratio and want to get it back.
- var ratio = inverse_lerp(20, 30, 27.5)
- # `ratio` is now 0.75.
- [/codeblock]
- </description>
- </method>
- <method name="is_equal_approx">
- <return type="bool">
- </return>
- <argument index="0" name="a" type="float">
- </argument>
- <argument index="1" name="b" type="float">
- </argument>
- <description>
- Returns [code]true[/code] if [code]a[/code] and [code]b[/code] are approximately equal to each other.
- Here, approximately equal means that [code]a[/code] and [code]b[/code] are within a small internal epsilon of each other, which scales with the magnitude of the numbers.
- Infinity values of the same sign are considered equal.
- </description>
- </method>
- <method name="is_inf">
- <return type="bool">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns whether [code]s[/code] is an infinity value (either positive infinity or negative infinity).
- </description>
- </method>
- <method name="is_instance_valid">
- <return type="bool">
- </return>
- <argument index="0" name="instance" type="Object">
- </argument>
- <description>
- Returns whether [code]instance[/code] is a valid object (e.g. has not been deleted from memory).
- </description>
- </method>
- <method name="is_nan">
- <return type="bool">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns whether [code]s[/code] is a NaN ("Not a Number" or invalid) value.
- </description>
- </method>
- <method name="is_zero_approx">
- <return type="bool">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns [code]true[/code] if [code]s[/code] is zero or almost zero.
- This method is faster than using [method is_equal_approx] with one value as zero.
- </description>
- </method>
<method name="len">
<return type="int">
</return>
@@ -530,63 +151,6 @@
[/codeblock]
</description>
</method>
- <method name="lerp">
- <return type="Variant">
- </return>
- <argument index="0" name="from" type="Variant">
- </argument>
- <argument index="1" name="to" type="Variant">
- </argument>
- <argument index="2" name="weight" type="float">
- </argument>
- <description>
- Linearly interpolates between two values by a normalized value. This is the opposite of [method inverse_lerp].
- If the [code]from[/code] and [code]to[/code] arguments are of type [int] or [float], the return value is a [float].
- If both are of the same vector type ([Vector2], [Vector3] or [Color]), the return value will be of the same type ([code]lerp[/code] then calls the vector type's [code]lerp[/code] method).
- [codeblock]
- lerp(0, 4, 0.75) # Returns 3.0
- lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Returns Vector2(2, 3.5)
- [/codeblock]
- </description>
- </method>
- <method name="lerp_angle">
- <return type="float">
- </return>
- <argument index="0" name="from" type="float">
- </argument>
- <argument index="1" name="to" type="float">
- </argument>
- <argument index="2" name="weight" type="float">
- </argument>
- <description>
- Linearly interpolates between two angles (in radians) by a normalized value.
- Similar to [method lerp], but interpolates correctly when the angles wrap around [constant @GDScript.TAU].
- [codeblock]
- extends Sprite
- var elapsed = 0.0
- func _process(delta):
- var min_angle = deg2rad(0.0)
- var max_angle = deg2rad(90.0)
- rotation = lerp_angle(min_angle, max_angle, elapsed)
- elapsed += delta
- [/codeblock]
- </description>
- </method>
- <method name="linear2db">
- <return type="float">
- </return>
- <argument index="0" name="nrg" type="float">
- </argument>
- <description>
- Converts from linear energy to decibels (audio). This can be used to implement volume sliders that behave as expected (since volume isn't linear). Example:
- [codeblock]
- # "Slider" refers to a node that inherits Range such as HSlider or VSlider.
- # Its range must be configured to go from 0 to 1.
- # Change the bus name if you'd like to change the volume of a specific bus only.
- AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear2db($Slider.value))
- [/codeblock]
- </description>
- </method>
<method name="load">
<return type="Resource">
</return>
@@ -603,172 +167,6 @@
This method is a simplified version of [method ResourceLoader.load], which can be used for more advanced scenarios.
</description>
</method>
- <method name="log">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Natural logarithm. The amount of time needed to reach a certain level of continuous growth.
- [b]Note:[/b] This is not the same as the "log" function on most calculators, which uses a base 10 logarithm.
- [codeblock]
- log(10) # Returns 2.302585
- [/codeblock]
- [b]Note:[/b] The logarithm of [code]0[/code] returns [code]-inf[/code], while negative values return [code]-nan[/code].
- </description>
- </method>
- <method name="max">
- <return type="float">
- </return>
- <argument index="0" name="a" type="float">
- </argument>
- <argument index="1" name="b" type="float">
- </argument>
- <description>
- Returns the maximum of two values.
- [codeblock]
- max(1, 2) # Returns 2
- max(-3.99, -4) # Returns -3.99
- [/codeblock]
- </description>
- </method>
- <method name="min">
- <return type="float">
- </return>
- <argument index="0" name="a" type="float">
- </argument>
- <argument index="1" name="b" type="float">
- </argument>
- <description>
- Returns the minimum of two values.
- [codeblock]
- min(1, 2) # Returns 1
- min(-3.99, -4) # Returns -4
- [/codeblock]
- </description>
- </method>
- <method name="move_toward">
- <return type="float">
- </return>
- <argument index="0" name="from" type="float">
- </argument>
- <argument index="1" name="to" type="float">
- </argument>
- <argument index="2" name="delta" type="float">
- </argument>
- <description>
- Moves [code]from[/code] toward [code]to[/code] by the [code]delta[/code] value.
- Use a negative [code]delta[/code] value to move away.
- [codeblock]
- move_toward(5, 10, 4) # Returns 9
- move_toward(10, 5, 4) # Returns 6
- move_toward(10, 5, -1.5) # Returns 11.5
- [/codeblock]
- </description>
- </method>
- <method name="nearest_po2">
- <return type="int">
- </return>
- <argument index="0" name="value" type="int">
- </argument>
- <description>
- Returns the nearest equal or larger power of 2 for integer [code]value[/code].
- In other words, returns the smallest value [code]a[/code] where [code]a = pow(2, n)[/code] such that [code]value &lt;= a[/code] for some non-negative integer [code]n[/code].
- [codeblock]
- nearest_po2(3) # Returns 4
- nearest_po2(4) # Returns 4
- nearest_po2(5) # Returns 8
-
- nearest_po2(0) # Returns 0 (this may not be what you expect)
- nearest_po2(-1) # Returns 0 (this may not be what you expect)
- [/codeblock]
- [b]WARNING:[/b] Due to the way it is implemented, this function returns [code]0[/code] rather than [code]1[/code] for non-positive values of [code]value[/code] (in reality, 1 is the smallest integer power of 2).
- </description>
- </method>
- <method name="ord">
- <return type="int">
- </return>
- <argument index="0" name="char" type="String">
- </argument>
- <description>
- Returns an integer representing the Unicode code point of the given Unicode character [code]char[/code].
- [codeblock]
- a = ord("A") # a is 65
- a = ord("a") # a is 97
- a = ord("€") # a is 8364
- [/codeblock]
- This is the inverse of [method char].
- </description>
- </method>
- <method name="parse_json">
- <return type="Variant">
- </return>
- <argument index="0" name="json" type="String">
- </argument>
- <description>
- Parse JSON text to a Variant. (Use [method typeof] to check if the Variant's type is what you expect.)
- [b]Note:[/b] The JSON specification does not define integer or float types, but only a [i]number[/i] type. Therefore, parsing a JSON text will convert all numerical values to [float] types.
- [b]Note:[/b] JSON objects do not preserve key order like Godot dictionaries, thus, you should not rely on keys being in a certain order if a dictionary is constructed from JSON. In contrast, JSON arrays retain the order of their elements:
- [codeblock]
- var p = JSON.parse('["hello", "world", "!"]')
- if typeof(p.result) == TYPE_ARRAY:
- print(p.result[0]) # Prints "hello"
- else:
- push_error("Unexpected results.")
- [/codeblock]
- See also [JSON] for an alternative way to parse JSON text.
- </description>
- </method>
- <method name="polar2cartesian">
- <return type="Vector2">
- </return>
- <argument index="0" name="r" type="float">
- </argument>
- <argument index="1" name="th" type="float">
- </argument>
- <description>
- Converts a 2D point expressed in the polar coordinate system (a distance from the origin [code]r[/code] and an angle [code]th[/code]) to the cartesian coordinate system (X and Y axis).
- </description>
- </method>
- <method name="posmod">
- <return type="int">
- </return>
- <argument index="0" name="a" type="int">
- </argument>
- <argument index="1" name="b" type="int">
- </argument>
- <description>
- Returns the integer modulus of [code]a/b[/code] that wraps equally in positive and negative.
- [codeblock]
- for i in range(-3, 4):
- print("%2d %2d %2d" % [i, i % 3, posmod(i, 3)])
- [/codeblock]
- Produces:
- [codeblock]
- -3 0 0
- -2 -2 1
- -1 -1 2
- 0 0 0
- 1 1 1
- 2 2 2
- 3 0 0
- [/codeblock]
- </description>
- </method>
- <method name="pow">
- <return type="float">
- </return>
- <argument index="0" name="base" type="float">
- </argument>
- <argument index="1" name="exp" type="float">
- </argument>
- <description>
- Returns the result of [code]base[/code] raised to the power of [code]exp[/code].
- [codeblock]
- pow(2, 5) # Returns 32.0
- [/codeblock]
- </description>
- </method>
<method name="preload">
<return type="Resource">
</return>
@@ -783,23 +181,11 @@
[/codeblock]
</description>
</method>
- <method name="print" qualifiers="vararg">
- <return type="void">
- </return>
- <description>
- Converts one or more arguments to strings in the best way possible and prints them to the console.
- [codeblock]
- a = [1, 2, 3]
- print("a", "=", a) # Prints a=[1, 2, 3]
- [/codeblock]
- [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed.
- </description>
- </method>
<method name="print_debug" qualifiers="vararg">
<return type="void">
</return>
<description>
- Like [method print], but prints only when used in debug mode.
+ Like [method @GlobalScope.print], but prints only when used in debug mode.
</description>
</method>
<method name="print_stack">
@@ -813,158 +199,6 @@
[/codeblock]
</description>
</method>
- <method name="printerr" qualifiers="vararg">
- <return type="void">
- </return>
- <description>
- Prints one or more arguments to strings in the best way possible to standard error line.
- [codeblock]
- printerr("prints to stderr")
- [/codeblock]
- </description>
- </method>
- <method name="printraw" qualifiers="vararg">
- <return type="void">
- </return>
- <description>
- Prints one or more arguments to strings in the best way possible to console. No newline is added at the end.
- [codeblock]
- printraw("A")
- printraw("B")
- # Prints AB
- [/codeblock]
- [b]Note:[/b] Due to limitations with Godot's built-in console, this only prints to the terminal. If you need to print in the editor, use another method, such as [method print].
- </description>
- </method>
- <method name="prints" qualifiers="vararg">
- <return type="void">
- </return>
- <description>
- Prints one or more arguments to the console with a space between each argument.
- [codeblock]
- prints("A", "B", "C") # Prints A B C
- [/codeblock]
- </description>
- </method>
- <method name="printt" qualifiers="vararg">
- <return type="void">
- </return>
- <description>
- Prints one or more arguments to the console with a tab between each argument.
- [codeblock]
- printt("A", "B", "C") # Prints A B C
- [/codeblock]
- </description>
- </method>
- <method name="push_error">
- <return type="void">
- </return>
- <argument index="0" name="message" type="String">
- </argument>
- <description>
- Pushes an error message to Godot's built-in debugger and to the OS terminal.
- [codeblock]
- push_error("test error") # Prints "test error" to debugger and terminal as error call
- [/codeblock]
- [b]Note:[/b] Errors printed this way will not pause project execution. To print an error message and pause project execution in debug builds, use [code]assert(false, "test error")[/code] instead.
- </description>
- </method>
- <method name="push_warning">
- <return type="void">
- </return>
- <argument index="0" name="message" type="String">
- </argument>
- <description>
- Pushes a warning message to Godot's built-in debugger and to the OS terminal.
- [codeblock]
- push_warning("test warning") # Prints "test warning" to debugger and terminal as warning call
- [/codeblock]
- </description>
- </method>
- <method name="rad2deg">
- <return type="float">
- </return>
- <argument index="0" name="rad" type="float">
- </argument>
- <description>
- Converts an angle expressed in radians to degrees.
- [codeblock]
- rad2deg(0.523599) # Returns 30.0
- [/codeblock]
- </description>
- </method>
- <method name="rand_seed">
- <return type="Array">
- </return>
- <argument index="0" name="seed" type="int">
- </argument>
- <description>
- Random from seed: pass a [code]seed[/code], and an array with both number and new seed is returned. "Seed" here refers to the internal state of the pseudo random number generator. The internal state of the current implementation is 64 bits.
- </description>
- </method>
- <method name="randf">
- <return type="float">
- </return>
- <description>
- Returns a random floating point value on the interval [code][0, 1][/code].
- [codeblock]
- randf() # Returns e.g. 0.375671
- [/codeblock]
- </description>
- </method>
- <method name="randf_range">
- <return type="float">
- </return>
- <argument index="0" name="from" type="float">
- </argument>
- <argument index="1" name="to" type="float">
- </argument>
- <description>
- Random range, any floating point value between [code]from[/code] and [code]to[/code].
- [codeblock]
- prints(randf_range(-10, 10), randf_range(-10, 10)) # Prints e.g. -3.844535 7.45315
- [/codeblock]
- </description>
- </method>
- <method name="randi">
- <return type="int">
- </return>
- <description>
- Returns a random unsigned 32 bit integer. Use remainder to obtain a random value in the interval [code][0, N - 1][/code] (where N is smaller than 2^32).
- [codeblock]
- randi() # Returns random integer between 0 and 2^32 - 1
- randi() % 20 # Returns random integer between 0 and 19
- randi() % 100 # Returns random integer between 0 and 99
- randi() % 100 + 1 # Returns random integer between 1 and 100
- [/codeblock]
- </description>
- </method>
- <method name="randi_range">
- <return type="int">
- </return>
- <argument index="0" name="from" type="int">
- </argument>
- <argument index="1" name="to" type="int">
- </argument>
- <description>
- Random range, any 32-bit integer value between [code]from[/code] and [code]to[/code] (inclusive). If [code]to[/code] is lesser than [code]from[/code] they are swapped.
- [codeblock]
- print(randi_range(0, 1)) # Prints 0 or 1
- print(randi_range(-10, 1000)) # Prints any number from -10 to 1000
- [/codeblock]
- </description>
- </method>
- <method name="randomize">
- <return type="void">
- </return>
- <description>
- Randomizes the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time.
- [codeblock]
- func _ready():
- randomize()
- [/codeblock]
- </description>
- </method>
<method name="range" qualifiers="vararg">
<return type="Array">
</return>
@@ -983,157 +217,6 @@
[/codeblock]
</description>
</method>
- <method name="range_lerp">
- <return type="float">
- </return>
- <argument index="0" name="value" type="float">
- </argument>
- <argument index="1" name="istart" type="float">
- </argument>
- <argument index="2" name="istop" type="float">
- </argument>
- <argument index="3" name="ostart" type="float">
- </argument>
- <argument index="4" name="ostop" type="float">
- </argument>
- <description>
- Maps a [code]value[/code] from range [code][istart, istop][/code] to [code][ostart, ostop][/code].
- [codeblock]
- range_lerp(75, 0, 100, -1, 1) # Returns 0.5
- [/codeblock]
- </description>
- </method>
- <method name="round">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Rounds [code]s[/code] to the nearest whole number, with halfway cases rounded away from zero.
- [codeblock]
- a = round(2.49) # a is 2.0
- a = round(2.5) # a is 3.0
- a = round(2.51) # a is 3.0
- [/codeblock]
- See also [method floor], [method ceil], [method stepify], and [int].
- </description>
- </method>
- <method name="seed">
- <return type="void">
- </return>
- <argument index="0" name="seed" type="int">
- </argument>
- <description>
- Sets seed for the random number generator.
- [codeblock]
- my_seed = "Godot Rocks"
- seed(my_seed.hash())
- [/codeblock]
- </description>
- </method>
- <method name="sign">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the sign of [code]s[/code]: -1 or 1. Returns 0 if [code]s[/code] is 0.
- [codeblock]
- sign(-6) # Returns -1
- sign(0) # Returns 0
- sign(6) # Returns 1
- [/codeblock]
- </description>
- </method>
- <method name="sin">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the sine of angle [code]s[/code] in radians.
- [codeblock]
- sin(0.523599) # Returns 0.5
- [/codeblock]
- </description>
- </method>
- <method name="sinh">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the hyperbolic sine of [code]s[/code].
- [codeblock]
- a = log(2.0) # Returns 0.693147
- sinh(a) # Returns 0.75
- [/codeblock]
- </description>
- </method>
- <method name="smoothstep">
- <return type="float">
- </return>
- <argument index="0" name="from" type="float">
- </argument>
- <argument index="1" name="to" type="float">
- </argument>
- <argument index="2" name="s" type="float">
- </argument>
- <description>
- Returns the result of smoothly interpolating the value of [code]s[/code] between [code]0[/code] and [code]1[/code], based on the where [code]s[/code] lies with respect to the edges [code]from[/code] and [code]to[/code].
- The return value is [code]0[/code] if [code]s &lt;= from[/code], and [code]1[/code] if [code]s &gt;= to[/code]. If [code]s[/code] lies between [code]from[/code] and [code]to[/code], the returned value follows an S-shaped curve that maps [code]s[/code] between [code]0[/code] and [code]1[/code].
- This S-shaped curve is the cubic Hermite interpolator, given by [code]f(s) = 3*s^2 - 2*s^3[/code].
- [codeblock]
- smoothstep(0, 2, -5.0) # Returns 0.0
- smoothstep(0, 2, 0.5) # Returns 0.15625
- smoothstep(0, 2, 1.0) # Returns 0.5
- smoothstep(0, 2, 2.0) # Returns 1.0
- [/codeblock]
- </description>
- </method>
- <method name="sqrt">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the square root of [code]s[/code], where [code]s[/code] is a non-negative number.
- [codeblock]
- sqrt(9) # Returns 3
- [/codeblock]
- [b]Note:[/b]Negative values of [code]s[/code] return NaN. If you need negative inputs, use [code]System.Numerics.Complex[/code] in C#.
- </description>
- </method>
- <method name="step_decimals">
- <return type="int">
- </return>
- <argument index="0" name="step" type="float">
- </argument>
- <description>
- Returns the position of the first non-zero digit, after the decimal point. Note that the maximum return value is 10, which is a design decision in the implementation.
- [codeblock]
- n = step_decimals(5) # n is 0
- n = step_decimals(1.0005) # n is 4
- n = step_decimals(0.000000005) # n is 9
- [/codeblock]
- </description>
- </method>
- <method name="stepify">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <argument index="1" name="step" type="float">
- </argument>
- <description>
- Snaps float value [code]s[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals.
- [codeblock]
- stepify(100, 32) # Returns 96.0
- stepify(3.14159, 0.01) # Returns 3.14
- [/codeblock]
- See also [method ceil], [method floor], [method round], and [int].
- </description>
- </method>
<method name="str" qualifiers="vararg">
<return type="String">
</return>
@@ -1147,200 +230,12 @@
[/codeblock]
</description>
</method>
- <method name="str2var">
- <return type="Variant">
- </return>
- <argument index="0" name="string" type="String">
- </argument>
- <description>
- Converts a formatted string that was returned by [method var2str] to the original value.
- [codeblock]
- a = '{ "a": 1, "b": 2 }'
- b = str2var(a)
- print(b["a"]) # Prints 1
- [/codeblock]
- </description>
- </method>
- <method name="tan">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the tangent of angle [code]s[/code] in radians.
- [codeblock]
- tan(deg2rad(45)) # Returns 1
- [/codeblock]
- </description>
- </method>
- <method name="tanh">
- <return type="float">
- </return>
- <argument index="0" name="s" type="float">
- </argument>
- <description>
- Returns the hyperbolic tangent of [code]s[/code].
- [codeblock]
- a = log(2.0) # a is 0.693147
- b = tanh(a) # b is 0.6
- [/codeblock]
- </description>
- </method>
- <method name="to_json">
- <return type="String">
- </return>
- <argument index="0" name="var" type="Variant">
- </argument>
- <description>
- Converts a [Variant] [code]var[/code] to JSON text and return the result. Useful for serializing data to store or send over the network.
- [codeblock]
- # Both numbers below are integers.
- a = { "a": 1, "b": 2 }
- b = to_json(a)
- print(b) # {"a":1, "b":2}
- # Both numbers above are floats, even if they display without any decimal places.
- [/codeblock]
- [b]Note:[/b] The JSON specification does not define integer or float types, but only a [i]number[/i] type. Therefore, converting a [Variant] to JSON text will convert all numerical values to [float] types.
- See also [JSON] for an alternative way to convert a [Variant] to JSON text.
- </description>
- </method>
<method name="type_exists">
<return type="bool">
</return>
- <argument index="0" name="type" type="String">
- </argument>
- <description>
- Returns whether the given class exists in [ClassDB].
- [codeblock]
- type_exists("Sprite2D") # Returns true
- type_exists("Variant") # Returns false
- [/codeblock]
- </description>
- </method>
- <method name="typeof">
- <return type="int">
- </return>
- <argument index="0" name="what" type="Variant">
- </argument>
- <description>
- Returns the internal type of the given Variant object, using the [enum Variant.Type] values.
- [codeblock]
- p = parse_json('["a", "b", "c"]')
- if typeof(p) == TYPE_ARRAY:
- print(p[0]) # Prints a
- else:
- print("unexpected results")
- [/codeblock]
- </description>
- </method>
- <method name="validate_json">
- <return type="String">
- </return>
- <argument index="0" name="json" type="String">
- </argument>
- <description>
- Checks that [code]json[/code] is valid JSON data. Returns an empty string if valid, or an error message otherwise.
- [codeblock]
- j = to_json([1, 2, 3])
- v = validate_json(j)
- if not v:
- print("Valid JSON.")
- else:
- push_error("Invalid JSON: " + v)
- [/codeblock]
- </description>
- </method>
- <method name="var2bytes">
- <return type="PackedByteArray">
- </return>
- <argument index="0" name="var" type="Variant">
- </argument>
- <argument index="1" name="full_objects" type="bool" default="false">
- </argument>
- <description>
- Encodes a variable value to a byte array. When [code]full_objects[/code] is [code]true[/code] encoding objects is allowed (and can potentially include code).
- </description>
- </method>
- <method name="var2str">
- <return type="String">
- </return>
- <argument index="0" name="var" type="Variant">
- </argument>
- <description>
- Converts a Variant [code]var[/code] to a formatted string that can later be parsed using [method str2var].
- [codeblock]
- a = { "a": 1, "b": 2 }
- print(var2str(a))
- [/codeblock]
- prints
- [codeblock]
- {
- "a": 1,
- "b": 2
- }
- [/codeblock]
- </description>
- </method>
- <method name="weakref">
- <return type="WeakRef">
- </return>
- <argument index="0" name="obj" type="Object">
- </argument>
- <description>
- Returns a weak reference to an object.
- A weak reference to an object is not enough to keep the object alive: when the only remaining references to a referent are weak references, garbage collection is free to destroy the referent and reuse its memory for something else. However, until the object is actually destroyed the weak reference may return the object even if there are no strong references to it.
- </description>
- </method>
- <method name="wrapf">
- <return type="float">
- </return>
- <argument index="0" name="value" type="float">
- </argument>
- <argument index="1" name="min" type="float">
- </argument>
- <argument index="2" name="max" type="float">
+ <argument index="0" name="type" type="StringName">
</argument>
<description>
- Wraps float [code]value[/code] between [code]min[/code] and [code]max[/code].
- Usable for creating loop-alike behavior or infinite surfaces.
- [codeblock]
- # Infinite loop between 5.0 and 9.9
- value = wrapf(value + 0.1, 5.0, 10.0)
- [/codeblock]
- [codeblock]
- # Infinite rotation (in radians)
- angle = wrapf(angle + 0.1, 0.0, TAU)
- [/codeblock]
- [codeblock]
- # Infinite rotation (in radians)
- angle = wrapf(angle + 0.1, -PI, PI)
- [/codeblock]
- [b]Note:[/b] If [code]min[/code] is [code]0[/code], this is equivalent to [method fposmod], so prefer using that instead.
- [code]wrapf[/code] is more flexible than using the [method fposmod] approach by giving the user control over the minimum value.
- </description>
- </method>
- <method name="wrapi">
- <return type="int">
- </return>
- <argument index="0" name="value" type="int">
- </argument>
- <argument index="1" name="min" type="int">
- </argument>
- <argument index="2" name="max" type="int">
- </argument>
- <description>
- Wraps integer [code]value[/code] between [code]min[/code] and [code]max[/code].
- Usable for creating loop-alike behavior or infinite surfaces.
- [codeblock]
- # Infinite loop between 5 and 9
- frame = wrapi(frame + 1, 5, 10)
- [/codeblock]
- [codeblock]
- # result is -2
- var result = wrapi(-6, -5, -1)
- [/codeblock]
- [b]Note:[/b] If [code]min[/code] is [code]0[/code], this is equivalent to [method posmod], so prefer using that instead.
- [code]wrapi[/code] is more flexible than using the [method posmod] approach by giving the user control over the minimum value.
</description>
</method>
</methods>
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 7f7410a92c..ccc942d86b 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -269,19 +269,21 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line)
col = keywords[word];
} else if (member_keywords.has(word)) {
col = member_keywords[word];
+ }
+
+ if (col != Color()) {
for (int k = j - 1; k >= 0; k--) {
if (str[k] == '.') {
- col = Color(); //member indexing not allowed
+ col = Color(); // keyword & member indexing not allowed
break;
} else if (str[k] > 32) {
break;
}
}
- }
-
- if (col != Color()) {
- in_keyword = true;
- keyword_color = col;
+ if (col != Color()) {
+ in_keyword = true;
+ keyword_color = col;
+ }
}
}
diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h
index e38647eaab..1b57cb1923 100644
--- a/modules/gdscript/editor/gdscript_highlighter.h
+++ b/modules/gdscript/editor/gdscript_highlighter.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
index 944ed859f5..9d0d91162c 100644
--- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
+++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,7 +44,7 @@ Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Ve
// Search strings in AssignmentNode -> text = "__", hint_tooltip = "__" etc.
Error err;
- RES loaded_res = ResourceLoader::load(p_path, "", false, &err);
+ RES loaded_res = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
if (err) {
ERR_PRINT("Failed to load " + p_path);
return err;
diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h
index d763df01f5..fcf438422a 100644
--- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h
+++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,8 +39,8 @@
class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlugin {
GDCLASS(GDScriptEditorTranslationParserPlugin, EditorTranslationParserPlugin);
- Vector<String> *ids;
- Vector<Vector<String>> *ids_ctx_plural;
+ Vector<String> *ids = nullptr;
+ Vector<Vector<String>> *ids_ctx_plural = nullptr;
// List of patterns used for extracting translation strings.
StringName tr_func = "tr";
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 8fa2de7063..a129b73c1a 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -219,7 +219,7 @@ StringName GDScript::get_instance_base_type() const {
}
struct _GDScriptMemberSort {
- int index;
+ int index = 0;
StringName name;
_FORCE_INLINE_ bool operator<(const _GDScriptMemberSort &p_member) const { return index < p_member.index; }
};
@@ -425,7 +425,7 @@ void GDScript::_update_doc() {
_clear_doc();
doc.script_path = "\"" + get_path().get_slice("://", 1) + "\"";
- if (!name.empty()) {
+ if (!name.is_empty()) {
doc.name = name;
} else {
doc.name = doc.script_path;
@@ -793,10 +793,10 @@ Error GDScript::reload(bool p_keep_state) {
{
String source_path = path;
- if (source_path.empty()) {
+ if (source_path.is_empty()) {
source_path = get_path();
}
- if (!source_path.empty()) {
+ if (!source_path.is_empty()) {
MutexLock lock(GDScriptCache::singleton->lock);
if (!GDScriptCache::singleton->shallow_gdscript_cache.has(source_path)) {
GDScriptCache::singleton->shallow_gdscript_cache[source_path] = this;
@@ -812,7 +812,7 @@ Error GDScript::reload(bool p_keep_state) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message);
}
// TODO: Show all error messages.
- _err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT);
+ _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT);
ERR_FAIL_V(ERR_PARSE_ERROR);
}
@@ -826,7 +826,7 @@ Error GDScript::reload(bool p_keep_state) {
const List<GDScriptParser::ParserError>::Element *e = parser.get_errors().front();
while (e != nullptr) {
- _err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT);
+ _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), ERR_HANDLER_SCRIPT);
e = e->next();
}
ERR_FAIL_V(ERR_PARSE_ERROR);
@@ -846,7 +846,7 @@ Error GDScript::reload(bool p_keep_state) {
if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error());
}
- _err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
+ _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
ERR_FAIL_V(ERR_COMPILATION_FAILED);
} else {
return err;
@@ -1162,17 +1162,6 @@ String GDScript::_get_gdscript_reference_class_name(const GDScript *p_gdscript)
GDScript::GDScript() :
script_list(this) {
- valid = false;
- subclass_count = 0;
- initializer = nullptr;
- _base = nullptr;
- _owner = nullptr;
- tool = false;
-#ifdef TOOLS_ENABLED
- source_changed_cache = false;
- placeholder_fallback_enabled = false;
-#endif
-
#ifdef DEBUG_ENABLED
{
MutexLock lock(GDScriptLanguage::get_singleton()->lock);
@@ -2151,7 +2140,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
if (err == OK) {
const GDScriptParser::ClassNode *c = parser.get_tree();
if (r_icon_path) {
- if (c->icon_path.empty() || c->icon_path.is_abs_path()) {
+ if (c->icon_path.is_empty() || c->icon_path.is_abs_path()) {
*r_icon_path = c->icon_path;
} else if (c->icon_path.is_rel_path()) {
*r_icon_path = p_path.get_base_dir().plus_file(c->icon_path).simplify_path();
@@ -2163,7 +2152,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
GDScriptParser subparser;
while (subclass) {
if (subclass->extends_used) {
- if (!subclass->extends_path.empty()) {
+ if (!subclass->extends_path.is_empty()) {
if (subclass->extends.size() == 0) {
get_global_class_name(subclass->extends_path, r_base_type);
subclass = nullptr;
@@ -2177,7 +2166,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
}
String subsource = subfile->get_as_utf8_string();
- if (subsource.empty()) {
+ if (subsource.is_empty()) {
break;
}
String subpath = subclass->extends_path;
@@ -2327,7 +2316,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
@@ -2374,7 +2363,7 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S
ERR_FAIL_COND_MSG(!file, "Cannot open file '" + p_path + "'.");
String source = file->get_as_utf8_string();
- if (source.empty()) {
+ if (source.is_empty()) {
return;
}
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 11c449c5f2..12c909fd4f 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,11 +57,11 @@ public:
class GDScript : public Script {
GDCLASS(GDScript, Script);
- bool tool;
- bool valid;
+ bool tool = false;
+ bool valid = false;
struct MemberInfo {
- int index;
+ int index = 0;
StringName setter;
StringName getter;
MultiplayerAPI::RPCMode rpc_mode;
@@ -77,8 +77,8 @@ class GDScript : public Script {
Ref<GDScriptNativeClass> native;
Ref<GDScript> base;
- GDScript *_base; //fast pointer access
- GDScript *_owner; //for subclasses
+ GDScript *_base = nullptr; //fast pointer access
+ GDScript *_owner = nullptr; //for subclasses
Set<StringName> members; //members are just indices to the instanced script.
Map<StringName, Variant> constants;
@@ -97,8 +97,8 @@ class GDScript : public Script {
Map<StringName, Variant> member_default_values_cache;
Ref<GDScript> base_cache;
Set<ObjectID> inheriters_cache;
- bool source_changed_cache;
- bool placeholder_fallback_enabled;
+ bool source_changed_cache = false;
+ bool placeholder_fallback_enabled = false;
void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames);
DocData::ClassDoc doc;
@@ -121,7 +121,7 @@ class GDScript : public Script {
GDScriptFunction *implicit_initializer = nullptr;
GDScriptFunction *initializer = nullptr; //direct pointer to new , faster to locate
- int subclass_count;
+ int subclass_count = 0;
Set<Object *> instances;
//exported members
String source;
@@ -529,7 +529,7 @@ public:
class ResourceFormatLoaderGDScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 19951ff17d..a6138cc564 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -60,7 +60,7 @@ static const char *underscore_classes[] = {
nullptr,
};
static StringName get_real_class_name(const StringName &p_source) {
- if (underscore_map.empty()) {
+ if (underscore_map.is_empty()) {
const char **class_name = underscore_classes;
while (*class_name != nullptr) {
underscore_map[*class_name] = String("_") + *class_name;
@@ -209,7 +209,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
int extends_index = 0;
- if (!p_class->extends_path.empty()) {
+ if (!p_class->extends_path.is_empty()) {
Ref<GDScriptParserRef> parser = get_parser_for(p_class->extends_path);
if (parser.is_null()) {
push_error(vformat(R"(Could not resolve super class path "%s".)", p_class->extends_path), p_class);
@@ -224,7 +224,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
base = parser->get_parser()->head->get_datatype();
} else {
- if (p_class->extends.empty()) {
+ if (p_class->extends.is_empty()) {
return ERR_PARSE_ERROR;
}
const StringName &name = p_class->extends[extends_index++];
@@ -376,7 +376,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
result.type_source = result.ANNOTATED_EXPLICIT;
result.builtin_type = Variant::OBJECT;
- if (p_type->type_chain.empty()) {
+ if (p_type->type_chain.is_empty()) {
// void.
result.kind = GDScriptParser::DataType::BUILTIN;
result.builtin_type = Variant::NIL;
@@ -1163,24 +1163,26 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable
void GDScriptAnalyzer::resolve_constant(GDScriptParser::ConstantNode *p_constant) {
GDScriptParser::DataType type;
- reduce_expression(p_constant->initializer);
- if (p_constant->initializer->type == GDScriptParser::Node::ARRAY) {
- const_fold_array(static_cast<GDScriptParser::ArrayNode *>(p_constant->initializer));
- } else if (p_constant->initializer->type == GDScriptParser::Node::DICTIONARY) {
- const_fold_dictionary(static_cast<GDScriptParser::DictionaryNode *>(p_constant->initializer));
- }
+ if (p_constant->initializer != nullptr) {
+ reduce_expression(p_constant->initializer);
+ if (p_constant->initializer->type == GDScriptParser::Node::ARRAY) {
+ const_fold_array(static_cast<GDScriptParser::ArrayNode *>(p_constant->initializer));
+ } else if (p_constant->initializer->type == GDScriptParser::Node::DICTIONARY) {
+ const_fold_dictionary(static_cast<GDScriptParser::DictionaryNode *>(p_constant->initializer));
+ }
- if (!p_constant->initializer->is_constant) {
- push_error(vformat(R"(Assigned value for constant "%s" isn't a constant expression.)", p_constant->identifier->name), p_constant->initializer);
- }
+ if (!p_constant->initializer->is_constant) {
+ push_error(vformat(R"(Assigned value for constant "%s" isn't a constant expression.)", p_constant->identifier->name), p_constant->initializer);
+ }
- type = p_constant->initializer->get_datatype();
+ type = p_constant->initializer->get_datatype();
#ifdef DEBUG_ENABLED
- if (p_constant->initializer->type == GDScriptParser::Node::CALL && type.kind == GDScriptParser::DataType::BUILTIN && type.builtin_type == Variant::NIL) {
- parser->push_warning(p_constant->initializer, GDScriptWarning::VOID_ASSIGNMENT, static_cast<GDScriptParser::CallNode *>(p_constant->initializer)->function_name);
- }
+ if (p_constant->initializer->type == GDScriptParser::Node::CALL && type.kind == GDScriptParser::DataType::BUILTIN && type.builtin_type == Variant::NIL) {
+ parser->push_warning(p_constant->initializer, GDScriptWarning::VOID_ASSIGNMENT, static_cast<GDScriptParser::CallNode *>(p_constant->initializer)->function_name);
+ }
#endif
+ }
if (p_constant->datatype_specifier != nullptr) {
GDScriptParser::DataType explicit_type = resolve_datatype(p_constant->datatype_specifier);
@@ -1215,7 +1217,10 @@ void GDScriptAnalyzer::resolve_constant(GDScriptParser::ConstantNode *p_constant
void GDScriptAnalyzer::resolve_assert(GDScriptParser::AssertNode *p_assert) {
reduce_expression(p_assert->condition);
if (p_assert->message != nullptr) {
- reduce_literal(p_assert->message);
+ reduce_expression(p_assert->message);
+ if (!p_assert->message->is_constant || p_assert->message->reduced_value.get_type() != Variant::STRING) {
+ push_error(R"(Expected constant string for assert error message.)", p_assert->message);
+ }
}
p_assert->set_datatype(p_assert->condition->get_datatype());
@@ -1752,6 +1757,8 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa
// Those are stored by reference so not suited for compile-time construction.
// Because in this case they would be the same reference in all constructed values.
case Variant::OBJECT:
+ case Variant::DICTIONARY:
+ case Variant::ARRAY:
case Variant::PACKED_BYTE_ARRAY:
case Variant::PACKED_INT32_ARRAY:
case Variant::PACKED_INT64_ARRAY:
@@ -2029,14 +2036,14 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa
push_error(vformat(R"*(Name "%s" called as a function but is a "%s".)*", p_call->function_name, callee_datatype.to_string()), p_call->callee);
}
#ifdef DEBUG_ENABLED
- } else if (!is_self) {
+ } else if (!is_self && !(base_type.is_hard_type() && base_type.kind == GDScriptParser::DataType::BUILTIN)) {
parser->push_warning(p_call, GDScriptWarning::UNSAFE_METHOD_ACCESS, p_call->function_name, base_type.to_string());
mark_node_unsafe(p_call);
#endif
}
}
}
- if (!found && is_self) {
+ if (!found && (is_self || (base_type.is_hard_type() && base_type.kind == GDScriptParser::DataType::BUILTIN))) {
String base_name = is_self && !p_call->is_super ? "self" : base_type.to_string();
push_error(vformat(R"*(Function "%s()" not found in base %s.)*", p_call->function_name, base_name), p_call->is_super ? p_call : p_call->callee);
}
@@ -3402,12 +3409,12 @@ Error GDScriptAnalyzer::resolve_inheritance() {
Error GDScriptAnalyzer::resolve_interface() {
resolve_class_interface(parser->head);
- return parser->errors.empty() ? OK : ERR_PARSE_ERROR;
+ return parser->errors.is_empty() ? OK : ERR_PARSE_ERROR;
}
Error GDScriptAnalyzer::resolve_body() {
resolve_class_body(parser->head);
- return parser->errors.empty() ? OK : ERR_PARSE_ERROR;
+ return parser->errors.is_empty() ? OK : ERR_PARSE_ERROR;
}
Error GDScriptAnalyzer::resolve_program() {
@@ -3422,7 +3429,7 @@ Error GDScriptAnalyzer::resolve_program() {
}
depended_parsers[E->get()]->raise_status(GDScriptParserRef::FULLY_SOLVED);
}
- return parser->errors.empty() ? OK : ERR_PARSE_ERROR;
+ return parser->errors.is_empty() ? OK : ERR_PARSE_ERROR;
}
Error GDScriptAnalyzer::analyze() {
diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h
index 9925167856..dab5b032a3 100644
--- a/modules/gdscript/gdscript_analyzer.h
+++ b/modules/gdscript/gdscript_analyzer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp
index a5d96077d9..58c6b31a77 100644
--- a/modules/gdscript/gdscript_byte_codegen.cpp
+++ b/modules/gdscript/gdscript_byte_codegen.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -899,6 +899,17 @@ void GDScriptByteCodeGenerator::write_call_self(const Address &p_target, const S
append(p_function_name);
}
+void GDScriptByteCodeGenerator::write_call_self_async(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) {
+ append(GDScriptFunction::OPCODE_CALL_ASYNC, 2 + p_arguments.size());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
+ append(p_target);
+ append(p_arguments.size());
+ append(p_function_name);
+}
+
void GDScriptByteCodeGenerator::write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) {
append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN, 2 + p_arguments.size());
for (int i = 0; i < p_arguments.size(); i++) {
diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h
index 21576b08a4..1e66af269a 100644
--- a/modules/gdscript/gdscript_byte_codegen.h
+++ b/modules/gdscript/gdscript_byte_codegen.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -441,6 +441,7 @@ public:
virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override;
virtual void write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override;
virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
+ virtual void write_call_self_async(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
virtual void write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) override;
virtual void write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) override;
diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp
index 95d24a8b08..113d36be98 100644
--- a/modules/gdscript/gdscript_cache.cpp
+++ b/modules/gdscript/gdscript_cache.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h
index 90c5884985..d1d2a2abbf 100644
--- a/modules/gdscript/gdscript_cache.h
+++ b/modules/gdscript/gdscript_cache.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h
index e776007bd7..d72bd12033 100644
--- a/modules/gdscript/gdscript_codegen.h
+++ b/modules/gdscript/gdscript_codegen.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -133,6 +133,7 @@ public:
virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
virtual void write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
+ virtual void write_call_self_async(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
virtual void write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) = 0;
virtual void write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) = 0;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index af6991041e..06d628d23f 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -107,7 +107,7 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
// Locate class by constructing the path to it and following that path
GDScriptParser::ClassNode *class_type = p_datatype.class_type;
if (class_type) {
- if (class_type->fqcn.begins_with(main_script->path) || (!main_script->name.empty() && class_type->fqcn.begins_with(main_script->name))) {
+ if (class_type->fqcn.begins_with(main_script->path) || (!main_script->name.is_empty() && class_type->fqcn.begins_with(main_script->name))) {
// Local class.
List<StringName> names;
while (class_type->outer) {
@@ -255,36 +255,59 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
}
// Try class constants.
- GDScript *owner = codegen.script;
- while (owner) {
- GDScript *scr = owner;
- GDScriptNativeClass *nc = nullptr;
- while (scr) {
- if (scr->constants.has(identifier)) {
- return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here.
+ {
+ GDScript *owner = codegen.script;
+ while (owner) {
+ GDScript *scr = owner;
+ GDScriptNativeClass *nc = nullptr;
+ while (scr) {
+ if (scr->constants.has(identifier)) {
+ return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here.
+ }
+ if (scr->native.is_valid()) {
+ nc = scr->native.ptr();
+ }
+ scr = scr->_base;
}
- if (scr->native.is_valid()) {
- nc = scr->native.ptr();
+
+ // Class C++ integer constant.
+ if (nc) {
+ bool success = false;
+ int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success);
+ if (success) {
+ return codegen.add_constant(constant);
+ }
}
- scr = scr->_base;
+
+ owner = owner->_owner;
}
+ }
- // Class C++ integer constant.
- if (nc) {
- bool success = false;
- int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success);
- if (success) {
- return codegen.add_constant(constant);
+ // Try signals and methods (can be made callables).
+ {
+ if (codegen.class_node->members_indices.has(identifier)) {
+ const GDScriptParser::ClassNode::Member &member = codegen.class_node->members[codegen.class_node->members_indices[identifier]];
+ if (member.type == GDScriptParser::ClassNode::Member::FUNCTION || member.type == GDScriptParser::ClassNode::Member::SIGNAL) {
+ // Get like it was a property.
+ GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here.
+ GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF);
+
+ gen->write_get_named(temp, identifier, self);
+ return temp;
}
}
- owner = owner->_owner;
- }
+ // Try in native base.
+ GDScript *scr = codegen.script;
+ GDScriptNativeClass *nc = nullptr;
+ while (scr) {
+ if (scr->native.is_valid()) {
+ nc = scr->native.ptr();
+ }
+ scr = scr->_base;
+ }
- // Try signals and methods (can be made callables);
- if (codegen.class_node->members_indices.has(identifier)) {
- const GDScriptParser::ClassNode::Member &member = codegen.class_node->members[codegen.class_node->members_indices[identifier]];
- if (member.type == GDScriptParser::ClassNode::Member::FUNCTION || member.type == GDScriptParser::ClassNode::Member::SIGNAL) {
+ if (nc && (ClassDB::has_signal(nc->get_name(), identifier) || ClassDB::has_method(nc->get_name(), identifier))) {
// Get like it was a property.
GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here.
GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF);
@@ -494,9 +517,17 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
} else if ((codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") {
GDScriptCodeGenerator::Address self;
self.mode = GDScriptCodeGenerator::Address::CLASS;
- gen->write_call(result, self, call->function_name, arguments);
+ if (within_await) {
+ gen->write_call_async(result, self, call->function_name, arguments);
+ } else {
+ gen->write_call(result, self, call->function_name, arguments);
+ }
} else {
- gen->write_call_self(result, call->function_name, arguments);
+ if (within_await) {
+ gen->write_call_self_async(result, call->function_name, arguments);
+ } else {
+ gen->write_call_self(result, call->function_name, arguments);
+ }
}
} else if (callee->type == GDScriptParser::Node::SUBSCRIPT) {
const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(call->callee);
@@ -1145,7 +1176,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c
codegen.generator->write_and_left_operand(result_addr);
// Check value equality.
- codegen.generator->write_binary_operator(result_addr, Variant::OP_EQUAL, p_value_addr, expr_addr);
+ codegen.generator->write_binary_operator(equality_test_addr, Variant::OP_EQUAL, p_value_addr, expr_addr);
codegen.generator->write_and_right_operand(equality_test_addr);
// AND both type and value equality.
@@ -2231,7 +2262,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
}
p_script->_signals[name] = parameters_names;
#ifdef TOOLS_ENABLED
- if (!signal->doc_description.empty()) {
+ if (!signal->doc_description.is_empty()) {
p_script->doc_signals[name] = signal->doc_description;
}
#endif
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 157c801f56..651391f972 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -133,8 +133,8 @@ class GDScriptCompiler {
Error _parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
Error _parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
void _make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
- int err_line;
- int err_column;
+ int err_line = 0;
+ int err_column = 0;
StringName source;
String error;
bool within_await = false;
diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp
index 5938cfd7b2..17cb5e3c96 100644
--- a/modules/gdscript/gdscript_disassembler.cpp
+++ b/modules/gdscript/gdscript_disassembler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 2181d17cf0..a9975c8602 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -123,10 +123,10 @@ static void get_function_names_recursively(const GDScriptParser::ClassNode *p_cl
for (int i = 0; i < p_class->members.size(); i++) {
if (p_class->members[i].type == GDScriptParser::ClassNode::Member::FUNCTION) {
const GDScriptParser::FunctionNode *function = p_class->members[i].function;
- r_funcs[function->start_line] = p_prefix.empty() ? String(function->identifier->name) : p_prefix + "." + String(function->identifier->name);
+ r_funcs[function->start_line] = p_prefix.is_empty() ? String(function->identifier->name) : p_prefix + "." + String(function->identifier->name);
} else if (p_class->members[i].type == GDScriptParser::ClassNode::Member::CLASS) {
String new_prefix = p_class->members[i].m_class->identifier->name;
- get_function_names_recursively(p_class->members[i].m_class, p_prefix.empty() ? new_prefix : p_prefix + "." + new_prefix, r_funcs);
+ get_function_names_recursively(p_class->members[i].m_class, p_prefix.is_empty() ? new_prefix : p_prefix + "." + new_prefix, r_funcs);
}
}
}
@@ -476,7 +476,7 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na
s += p_args[i].get_slice(":", 0);
if (th) {
String type = p_args[i].get_slice(":", 1);
- if (!type.empty() && type != "var") {
+ if (!type.is_empty() && type != "var") {
s += ": " + type;
}
}
@@ -2261,10 +2261,9 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
}
r_arghint = _make_arguments_hint(info, p_argidx);
- return;
}
- if (ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node") && p_argidx == 0) {
+ if (p_argidx == 0 && ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node")) {
// Get autoloads
List<PropertyInfo> props;
ProjectSettings::get_singleton()->get_property_list(&props);
@@ -2345,7 +2344,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
GDScriptParser::DataType base_type;
bool _static = false;
const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_call);
- GDScriptParser::Node::Type callee_type = GDScriptParser::Node::NONE;
+ GDScriptParser::Node::Type callee_type = call->get_callee_type();
GDScriptCompletionIdentifier connect_base;
@@ -2511,7 +2510,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
break;
}
- if (!type.enumeration.empty()) {
+ if (!type.enumeration.is_empty()) {
_find_enumeration_candidates(completion_context, type.enumeration, options);
r_forced = options.size() > 0;
} else {
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 32372439c5..c6c9a439df 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -77,14 +77,14 @@ int GDScriptFunction::get_max_stack_size() const {
}
struct _GDFKC {
- int order;
+ int order = 0;
List<int> pos;
};
struct _GDFKCS {
- int order;
+ int order = 0;
StringName id;
- int pos;
+ int pos = 0;
bool operator<(const _GDFKCS &p_r) const {
return order < p_r.order;
@@ -114,7 +114,7 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String
ERR_CONTINUE(!sdmap.has(sd.identifier));
sdmap[sd.identifier].pos.pop_back();
- if (sdmap[sd.identifier].pos.empty()) {
+ if (sdmap[sd.identifier].pos.is_empty()) {
sdmap.erase(sd.identifier);
}
}
@@ -294,7 +294,6 @@ void GDScriptFunctionState::_bind_methods() {
GDScriptFunctionState::GDScriptFunctionState() :
scripts_list(this),
instances_list(this) {
- function = nullptr;
}
GDScriptFunctionState::~GDScriptFunctionState() {
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index b669870b51..e64630a743 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -420,19 +420,19 @@ private:
public:
struct CallState {
- GDScript *script;
- GDScriptInstance *instance;
+ GDScript *script = nullptr;
+ GDScriptInstance *instance = nullptr;
#ifdef DEBUG_ENABLED
StringName function_name;
String script_path;
#endif
Vector<uint8_t> stack;
- int stack_size;
+ int stack_size = 0;
Variant self;
- uint32_t alloca_size;
- int ip;
- int line;
- int defarg;
+ uint32_t alloca_size = 0;
+ int ip = 0;
+ int line = 0;
+ int defarg = 0;
Variant result;
};
@@ -488,7 +488,7 @@ public:
class GDScriptFunctionState : public Reference {
GDCLASS(GDScriptFunctionState, Reference);
friend class GDScriptFunction;
- GDScriptFunction *function;
+ GDScriptFunction *function = nullptr;
GDScriptFunction::CallState state;
Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
Ref<GDScriptFunctionState> first_state;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 2c735049b6..15cb3146ee 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,7 @@
static HashMap<StringName, Variant::Type> builtin_types;
Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) {
- if (builtin_types.empty()) {
+ if (builtin_types.is_empty()) {
builtin_types["bool"] = Variant::BOOL;
builtin_types["int"] = Variant::INT;
builtin_types["float"] = Variant::FLOAT;
@@ -130,8 +130,10 @@ GDScriptParser::GDScriptParser() {
register_annotation(MethodInfo("@export_flags", { Variant::STRING, "names" }), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FLAGS, Variant::INT>, 0, true);
register_annotation(MethodInfo("@export_flags_2d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_RENDER, Variant::INT>);
register_annotation(MethodInfo("@export_flags_2d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_PHYSICS, Variant::INT>);
+ register_annotation(MethodInfo("@export_flags_2d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_NAVIGATION, Variant::INT>);
register_annotation(MethodInfo("@export_flags_3d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_RENDER, Variant::INT>);
register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>);
+ register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>);
// Networking.
register_annotation(MethodInfo("@remote"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_REMOTE>);
register_annotation(MethodInfo("@master"), AnnotationInfo::VARIABLE | AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<MultiplayerAPI::RPC_MODE_MASTER>);
@@ -177,16 +179,16 @@ void GDScriptParser::push_error(const String &p_message, const Node *p_origin) {
void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_code, const String &p_symbol1, const String &p_symbol2, const String &p_symbol3, const String &p_symbol4) {
ERR_FAIL_COND(p_source == nullptr);
Vector<String> symbols;
- if (!p_symbol1.empty()) {
+ if (!p_symbol1.is_empty()) {
symbols.push_back(p_symbol1);
}
- if (!p_symbol2.empty()) {
+ if (!p_symbol2.is_empty()) {
symbols.push_back(p_symbol2);
}
- if (!p_symbol3.empty()) {
+ if (!p_symbol3.is_empty()) {
symbols.push_back(p_symbol3);
}
- if (!p_symbol4.empty()) {
+ if (!p_symbol4.is_empty()) {
symbols.push_back(p_symbol4);
}
push_warning(p_source, p_code, symbols);
@@ -284,7 +286,7 @@ void GDScriptParser::pop_completion_call() {
if (!for_completion) {
return;
}
- ERR_FAIL_COND_MSG(completion_call_stack.empty(), "Trying to pop empty completion call stack");
+ ERR_FAIL_COND_MSG(completion_call_stack.is_empty(), "Trying to pop empty completion call stack");
completion_call_stack.pop_back();
}
@@ -292,7 +294,7 @@ void GDScriptParser::set_last_completion_call_arg(int p_argument) {
if (!for_completion || passed_cursor) {
return;
}
- ERR_FAIL_COND_MSG(completion_call_stack.empty(), "Trying to set argument on empty completion call stack");
+ ERR_FAIL_COND_MSG(completion_call_stack.is_empty(), "Trying to set argument on empty completion call stack");
completion_call_stack.back()->get().argument = p_argument;
}
@@ -358,7 +360,7 @@ Error GDScriptParser::parse(const String &p_source_code, const String &p_script_
}
#endif
- if (errors.empty()) {
+ if (errors.is_empty()) {
return OK;
} else {
return ERR_PARSE_ERROR;
@@ -369,7 +371,7 @@ GDScriptTokenizer::Token GDScriptParser::advance() {
if (current.type == GDScriptTokenizer::Token::TK_EOF) {
ERR_FAIL_COND_V_MSG(current.type == GDScriptTokenizer::Token::TK_EOF, current, "GDScript parser bug: Trying to advance past the end of stream.");
}
- if (for_completion && !completion_call_stack.empty()) {
+ if (for_completion && !completion_call_stack.is_empty()) {
if (completion_call.call == nullptr && tokenizer.is_past_cursor()) {
completion_call = completion_call_stack.back()->get();
passed_cursor = true;
@@ -500,7 +502,7 @@ void GDScriptParser::parse_program() {
// Order here doesn't matter, but there should be only one of each at most.
switch (current.type) {
case GDScriptTokenizer::Token::CLASS_NAME:
- if (!annotation_stack.empty()) {
+ if (!annotation_stack.is_empty()) {
push_error(R"("class_name" should be used before annotations.)");
}
advance();
@@ -511,7 +513,7 @@ void GDScriptParser::parse_program() {
}
break;
case GDScriptTokenizer::Token::EXTENDS:
- if (!annotation_stack.empty()) {
+ if (!annotation_stack.is_empty()) {
push_error(R"("extends" should be used before annotations.)");
}
advance();
@@ -675,7 +677,7 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)()
#endif // TOOLS_ENABLED
// Consume annotations.
- while (!annotation_stack.empty()) {
+ while (!annotation_stack.is_empty()) {
AnnotationNode *last_annotation = annotation_stack.back()->get();
if (last_annotation->applies_to(p_target)) {
last_annotation->apply(this, member);
@@ -976,6 +978,8 @@ GDScriptParser::ConstantNode *GDScriptParser::parse_constant() {
push_error(R"(Expected initializer expression for constant.)");
return nullptr;
}
+ } else {
+ return nullptr;
}
end_statement("constant declaration");
@@ -1501,12 +1505,9 @@ GDScriptParser::AssertNode *GDScriptParser::parse_assert() {
if (match(GDScriptTokenizer::Token::COMMA)) {
// Error message.
- if (consume(GDScriptTokenizer::Token::LITERAL, R"(Expected error message for assert after ",".)")) {
- assert->message = parse_literal();
- if (assert->message->value.get_type() != Variant::STRING) {
- push_error(R"(Expected string for assert error message.)");
- }
- } else {
+ assert->message = parse_expression(false);
+ if (assert->message == nullptr) {
+ push_error(R"(Expected error message for assert after ",".)");
return nullptr;
}
}
@@ -1698,7 +1699,7 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() {
branch->patterns.push_back(pattern);
} while (match(GDScriptTokenizer::Token::COMMA));
- if (branch->patterns.empty()) {
+ if (branch->patterns.is_empty()) {
push_error(R"(No pattern found for "match" branch.)");
}
@@ -2081,6 +2082,17 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_unary_operator(ExpressionN
return operation;
}
+GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_not_in_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {
+ // check that NOT is followed by IN by consuming it before calling parse_binary_operator which will only receive a plain IN
+ consume(GDScriptTokenizer::Token::IN, R"(Expected "in" after "not" in content-test operator.)");
+ ExpressionNode *in_operation = parse_binary_operator(p_previous_operand, p_can_assign);
+ UnaryOpNode *operation = alloc_node<UnaryOpNode>();
+ operation->operation = UnaryOpNode::OP_LOGIC_NOT;
+ operation->variant_op = Variant::OP_NOT;
+ operation->operand = in_operation;
+ return operation;
+}
+
GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_operator(ExpressionNode *p_previous_operand, bool p_can_assign) {
GDScriptTokenizer::Token op = previous;
BinaryOpNode *operation = alloc_node<BinaryOpNode>();
@@ -2751,7 +2763,7 @@ String GDScriptParser::get_doc_comment(int p_line, bool p_single_line) {
}
String line_join = (in_codeblock) ? "\n" : " ";
- doc = (doc.empty()) ? doc_line : doc + line_join + doc_line;
+ doc = (doc.is_empty()) ? doc_line : doc + line_join + doc_line;
line++;
}
@@ -2845,7 +2857,7 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String &
mode = TUTORIALS;
in_codeblock = false;
- } else if (striped_line.empty()) {
+ } else if (striped_line.is_empty()) {
continue;
} else {
// Tutorial docs are single line, we need a @tag after it.
@@ -2907,7 +2919,7 @@ GDScriptParser::ParseRule *GDScriptParser::get_rule(GDScriptTokenizer::Token::Ty
// Logical
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_LOGIC_AND }, // AND,
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_LOGIC_OR }, // OR,
- { &GDScriptParser::parse_unary_operator, nullptr, PREC_NONE }, // NOT,
+ { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_not_in_operator, PREC_CONTENT_TEST }, // NOT,
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_LOGIC_AND }, // AMPERSAND_AMPERSAND,
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_LOGIC_OR }, // PIPE_PIPE,
{ &GDScriptParser::parse_unary_operator, nullptr, PREC_NONE }, // BANG,
@@ -2919,8 +2931,8 @@ GDScriptParser::ParseRule *GDScriptParser::get_rule(GDScriptTokenizer::Token::Ty
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_BIT_SHIFT }, // LESS_LESS,
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_BIT_SHIFT }, // GREATER_GREATER,
// Math
- { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_ADDITION }, // PLUS,
- { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_SUBTRACTION }, // MINUS,
+ { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_ADDITION_SUBTRACTION }, // PLUS,
+ { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_operator, PREC_ADDITION_SUBTRACTION }, // MINUS,
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_FACTOR }, // STAR,
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_FACTOR }, // SLASH,
{ nullptr, &GDScriptParser::parse_binary_operator, PREC_FACTOR }, // PERCENT,
@@ -3158,11 +3170,16 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
push_error(R"(Cannot use "@export" annotation with variable without type or initializer, since type can't be inferred.)", p_annotation);
return false;
}
- if (variable->initializer->type != Node::LITERAL) {
+ if (variable->initializer->type == Node::LITERAL) {
+ variable->export_info.type = static_cast<LiteralNode *>(variable->initializer)->value.get_type();
+ } else if (variable->initializer->type == Node::ARRAY) {
+ variable->export_info.type = Variant::ARRAY;
+ } else if (variable->initializer->type == Node::DICTIONARY) {
+ variable->export_info.type = Variant::DICTIONARY;
+ } else {
push_error(R"(To use "@export" annotation with type-less variable, the default value must be a literal.)", p_annotation);
return false;
}
- variable->export_info.type = static_cast<LiteralNode *>(variable->initializer)->value.get_type();
} // else: Actual type will be set by the analyzer, which can infer the proper type.
}
@@ -3280,11 +3297,11 @@ String GDScriptParser::DataType::to_string() const {
return script_type->get_class_name().operator String();
}
String name = script_type->get_name();
- if (!name.empty()) {
+ if (!name.is_empty()) {
return name;
}
name = script_path;
- if (!name.empty()) {
+ if (!name.is_empty()) {
return name;
}
return native_type.operator String();
@@ -3329,7 +3346,7 @@ void GDScriptParser::TreePrinter::decrease_indent() {
}
void GDScriptParser::TreePrinter::push_line(const String &p_line) {
- if (!p_line.empty()) {
+ if (!p_line.is_empty()) {
push_text(p_line);
}
printed += "\n";
@@ -3538,7 +3555,7 @@ void GDScriptParser::TreePrinter::print_class(ClassNode *p_class) {
if (p_class->extends_used) {
bool first = true;
push_text(" Extends ");
- if (!p_class->extends_path.empty()) {
+ if (!p_class->extends_path.is_empty()) {
push_text(vformat(R"("%s")", p_class->extends_path));
first = false;
}
@@ -4000,7 +4017,7 @@ void GDScriptParser::TreePrinter::print_ternary_op(TernaryOpNode *p_ternary_op)
}
void GDScriptParser::TreePrinter::print_type(TypeNode *p_type) {
- if (p_type->type_chain.empty()) {
+ if (p_type->type_chain.is_empty()) {
push_text("Void");
} else {
for (int i = 0; i < p_type->type_chain.size(); i++) {
@@ -4120,7 +4137,7 @@ void GDScriptParser::TreePrinter::print_tree(const GDScriptParser &p_parser) {
if (p_parser.is_tool()) {
push_line("@tool");
}
- if (!p_parser.get_tree()->icon_path.empty()) {
+ if (!p_parser.get_tree()->icon_path.is_empty()) {
push_text(R"(@icon (")");
push_text(p_parser.get_tree()->icon_path);
push_line("\")");
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 4cecdc6970..a4b1d4c866 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -286,7 +286,7 @@ public:
struct AssertNode : public Node {
ExpressionNode *condition = nullptr;
- LiteralNode *message = nullptr;
+ ExpressionNode *message = nullptr;
AssertNode() {
type = ASSERT;
@@ -351,7 +351,7 @@ public:
OP_COMP_GREATER_EQUAL,
};
- OpType operation;
+ OpType operation = OpType::OP_ADDITION;
Variant::Operator variant_op = Variant::OP_MAX;
ExpressionNode *left_operand = nullptr;
ExpressionNode *right_operand = nullptr;
@@ -753,7 +753,7 @@ public:
struct MatchBranchNode : public Node {
Vector<PatternNode *> patterns;
- SuiteNode *block;
+ SuiteNode *block = nullptr;
bool has_wildcard = false;
MatchBranchNode() {
@@ -1001,7 +1001,7 @@ public:
OP_LOGIC_NOT,
};
- OpType operation;
+ OpType operation = OP_POSITIVE;
Variant::Operator variant_op = Variant::OP_MAX;
ExpressionNode *operand = nullptr;
@@ -1172,8 +1172,7 @@ private:
PREC_BIT_XOR,
PREC_BIT_AND,
PREC_BIT_SHIFT,
- PREC_SUBTRACTION,
- PREC_ADDITION,
+ PREC_ADDITION_SUBTRACTION,
PREC_FACTOR,
PREC_SIGN,
PREC_BIT_NOT,
@@ -1286,6 +1285,7 @@ private:
ExpressionNode *parse_builtin_constant(ExpressionNode *p_previous_operand, bool p_can_assign);
ExpressionNode *parse_unary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);
ExpressionNode *parse_binary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);
+ ExpressionNode *parse_binary_not_in_operator(ExpressionNode *p_previous_operand, bool p_can_assign);
ExpressionNode *parse_ternary_operator(ExpressionNode *p_previous_operand, bool p_can_assign);
ExpressionNode *parse_assignment(ExpressionNode *p_previous_operand, bool p_can_assign);
ExpressionNode *parse_array(ExpressionNode *p_previous_operand, bool p_can_assign);
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index ac43105254..315b8ee3b4 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -221,7 +221,7 @@ String GDScriptTokenizer::get_token_name(Token::Type p_token_type) {
void GDScriptTokenizer::set_source_code(const String &p_source_code) {
source = p_source_code;
- if (source.empty()) {
+ if (source.is_empty()) {
_source = U"";
} else {
_source = source.ptr();
@@ -287,7 +287,7 @@ void GDScriptTokenizer::push_paren(char32_t p_char) {
}
bool GDScriptTokenizer::pop_paren(char32_t p_expected) {
- if (paren_stack.empty()) {
+ if (paren_stack.is_empty()) {
return false;
}
char32_t actual = paren_stack.back()->get();
@@ -405,7 +405,7 @@ void GDScriptTokenizer::push_error(const Token &p_error) {
}
GDScriptTokenizer::Token GDScriptTokenizer::make_paren_error(char32_t p_paren) {
- if (paren_stack.empty()) {
+ if (paren_stack.is_empty()) {
return make_error(vformat("Closing \"%c\" doesn't have an opening counterpart.", p_paren));
}
Token error = make_error(vformat("Closing \"%c\" doesn't match the opening \"%c\".", p_paren, paren_stack.back()->get()));
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index f236c86f9f..bea4b14019 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -178,7 +178,6 @@ public:
}
Token() {
- type = EMPTY;
}
};
@@ -230,7 +229,7 @@ private:
_FORCE_INLINE_ bool _is_at_end() { return position >= length; }
_FORCE_INLINE_ char32_t _peek(int p_offset = 0) { return position + p_offset >= 0 && position + p_offset < length ? _current[p_offset] : '\0'; }
int indent_level() const { return indent_stack.size(); }
- bool has_error() const { return !error_stack.empty(); }
+ bool has_error() const { return !error_stack.is_empty(); }
Token pop_error();
char32_t _advance();
void _skip_whitespace();
diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp
index b1780446d0..348d221352 100644
--- a/modules/gdscript/gdscript_utility_functions.cpp
+++ b/modules/gdscript/gdscript_utility_functions.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_utility_functions.h b/modules/gdscript/gdscript_utility_functions.h
index 50867438d9..c6d3718844 100644
--- a/modules/gdscript/gdscript_utility_functions.h
+++ b/modules/gdscript/gdscript_utility_functions.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index b8e1791467..4e098d7a6d 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -476,11 +476,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (p_instance) {
- if (p_instance->base_ref && static_cast<Reference *>(p_instance->owner)->is_referenced()) {
- self = REF(static_cast<Reference *>(p_instance->owner));
- } else {
- self = p_instance->owner;
- }
+ self = p_instance->owner;
script = p_instance->script.ptr();
} else {
script = _script;
@@ -2282,7 +2278,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
VariantInternal::initialize(counter, Variant::INT);
*VariantInternal::get_int(counter) = 0;
- if (!str->empty()) {
+ if (!str->is_empty()) {
GET_INSTRUCTION_ARG(iterator, 2);
VariantInternal::initialize(iterator, Variant::STRING);
*VariantInternal::get_string(iterator) = str->substr(0, 1);
@@ -2306,10 +2302,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
Dictionary *dict = VariantInternal::get_dictionary(container);
const Variant *next = dict->next(nullptr);
- *counter = *next;
- if (!dict->empty()) {
+ if (!dict->is_empty()) {
GET_INSTRUCTION_ARG(iterator, 2);
+ *counter = *next;
*iterator = *next;
// Skip regular iterate.
@@ -2334,7 +2330,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
VariantInternal::initialize(counter, Variant::INT);
*VariantInternal::get_int(counter) = 0;
- if (!array->empty()) {
+ if (!array->is_empty()) {
GET_INSTRUCTION_ARG(iterator, 2);
*iterator = array->get(0);
@@ -2357,7 +2353,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
Vector<m_elem_type> *array = VariantInternal::m_get_func(container); \
VariantInternal::initialize(counter, Variant::INT); \
*VariantInternal::get_int(counter) = 0; \
- if (!array->empty()) { \
+ if (!array->is_empty()) { \
GET_INSTRUCTION_ARG(iterator, 2); \
VariantInternal::initialize(iterator, Variant::m_var_ret_type); \
m_ret_type *it = VariantInternal::m_ret_get_func(iterator); \
@@ -2781,7 +2777,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GET_INSTRUCTION_ARG(message, 1);
message_str = *message;
}
- if (message_str.empty()) {
+ if (message_str.is_empty()) {
err_text = "Assertion failed.";
} else {
err_text = "Assertion failed: " + message_str;
diff --git a/modules/gdscript/gdscript_warning.cpp b/modules/gdscript/gdscript_warning.cpp
index 56704d3e0a..ad41b60a4e 100644
--- a/modules/gdscript/gdscript_warning.cpp
+++ b/modules/gdscript/gdscript_warning.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h
index e0857703d8..4b295b5eb8 100644
--- a/modules/gdscript/gdscript_warning.h
+++ b/modules/gdscript/gdscript_warning.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index bd2d170e52..e63b6ab20e 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -147,7 +147,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
r_symbol.script_path = path;
r_symbol.children.clear();
r_symbol.name = p_class->identifier != nullptr ? String(p_class->identifier->name) : String();
- if (r_symbol.name.empty()) {
+ if (r_symbol.name.is_empty()) {
r_symbol.name = path.get_file();
}
r_symbol.kind = lsp::SymbolKind::Class;
@@ -215,9 +215,9 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
String value_text;
if (default_value.get_type() == Variant::OBJECT) {
RES res = default_value;
- if (res.is_valid() && !res->get_path().empty()) {
+ if (res.is_valid() && !res->get_path().is_empty()) {
value_text = "preload(\"" + res->get_path() + "\")";
- if (symbol.documentation.empty()) {
+ if (symbol.documentation.is_empty()) {
if (Map<String, ExtendGDScriptParser *>::Element *S = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.find(res->get_path())) {
symbol.documentation = S->get()->class_symbol.documentation;
}
@@ -228,7 +228,7 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
} else {
value_text = JSON::print(default_value);
}
- if (!value_text.empty()) {
+ if (!value_text.is_empty()) {
symbol.detail += " = " + value_text;
}
@@ -453,7 +453,7 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c
String line = lines[i];
String first_part = line.substr(0, p_cursor.character);
String last_part = line.substr(p_cursor.character + 1, lines[i].length());
- if (!p_symbol.empty()) {
+ if (!p_symbol.is_empty()) {
String left_cursor_text;
for (int c = p_cursor.character - 1; c >= 0; c--) {
left_cursor_text = line.substr(c, p_cursor.character - c);
@@ -589,7 +589,7 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::get_symbol_defined_at_line(int
}
const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String &p_name, const String &p_subclass) const {
- if (p_subclass.empty()) {
+ if (p_subclass.is_empty()) {
const lsp::DocumentSymbol *const *ptr = members.getptr(p_name);
if (ptr) {
return *ptr;
@@ -611,7 +611,7 @@ const List<lsp::DocumentLink> &ExtendGDScriptParser::get_document_links() const
}
const Array &ExtendGDScriptParser::get_member_completions() {
- if (member_completions.empty()) {
+ if (member_completions.is_empty()) {
const String *name = members.next(nullptr);
while (name) {
const lsp::DocumentSymbol *symbol = members.get(*name);
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h
index bb02d3dc99..28b9b3c82a 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.h
+++ b/modules/gdscript/language_server/gdscript_extend_parser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp
index 729be237ec..912c9a174e 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.cpp
+++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -96,7 +96,7 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
// Response
String output = GDScriptLanguageProtocol::get_singleton()->process_message(msg);
- if (!output.empty()) {
+ if (!output.is_empty()) {
res_queue.push_back(output.utf8());
}
}
@@ -105,7 +105,7 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
Error GDScriptLanguageProtocol::LSPeer::send_data() {
int sent = 0;
- if (!res_queue.empty()) {
+ if (!res_queue.is_empty()) {
CharString c_res = res_queue[0];
if (res_sent < c_res.size()) {
Error err = connection->put_partial_data((const uint8_t *)c_res.get_data() + res_sent, c_res.size() - res_sent - 1, sent);
@@ -141,7 +141,7 @@ void GDScriptLanguageProtocol::on_client_disconnected(const int &p_client_id) {
String GDScriptLanguageProtocol::process_message(const String &p_text) {
String ret = process_string(p_text);
- if (ret.empty()) {
+ if (ret.is_empty()) {
return ret;
} else {
return format_output(ret);
@@ -163,7 +163,7 @@ void GDScriptLanguageProtocol::_bind_methods() {
ClassDB::bind_method(D_METHOD("initialized", "params"), &GDScriptLanguageProtocol::initialized);
ClassDB::bind_method(D_METHOD("on_client_connected"), &GDScriptLanguageProtocol::on_client_connected);
ClassDB::bind_method(D_METHOD("on_client_disconnected"), &GDScriptLanguageProtocol::on_client_disconnected);
- ClassDB::bind_method(D_METHOD("notify_client", "method", "params"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("notify_client", "method", "params", "client_id"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("is_smart_resolve_enabled"), &GDScriptLanguageProtocol::is_smart_resolve_enabled);
ClassDB::bind_method(D_METHOD("get_text_document"), &GDScriptLanguageProtocol::get_text_document);
ClassDB::bind_method(D_METHOD("get_workspace"), &GDScriptLanguageProtocol::get_workspace);
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h
index cf5242e8c5..8b08ae0655 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.h
+++ b/modules/gdscript/language_server/gdscript_language_protocol.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp
index 3387d262f8..98ada9de4d 100644
--- a/modules/gdscript/language_server/gdscript_language_server.cpp
+++ b/modules/gdscript/language_server/gdscript_language_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,12 +36,6 @@
#include "editor/editor_node.h"
GDScriptLanguageServer::GDScriptLanguageServer() {
- thread = nullptr;
- thread_running = false;
- started = false;
-
- use_thread = false;
- port = 6008;
_EDITOR_DEF("network/language_server/remote_port", port);
_EDITOR_DEF("network/language_server/enable_smart_resolve", true);
_EDITOR_DEF("network/language_server/show_native_symbols_in_editor", false);
@@ -87,9 +81,8 @@ void GDScriptLanguageServer::start() {
if (protocol.start(port, IP_Address("127.0.0.1")) == OK) {
EditorNode::get_log()->add_message("--- GDScript language server started ---", EditorLog::MSG_TYPE_EDITOR);
if (use_thread) {
- ERR_FAIL_COND(thread != nullptr);
thread_running = true;
- thread = Thread::create(GDScriptLanguageServer::thread_main, this);
+ thread.start(GDScriptLanguageServer::thread_main, this);
}
set_process_internal(!use_thread);
started = true;
@@ -98,11 +91,9 @@ void GDScriptLanguageServer::start() {
void GDScriptLanguageServer::stop() {
if (use_thread) {
- ERR_FAIL_COND(nullptr == thread);
+ ERR_FAIL_COND(!thread.is_started());
thread_running = false;
- Thread::wait_to_finish(thread);
- memdelete(thread);
- thread = nullptr;
+ thread.wait_to_finish();
}
protocol.stop();
started = false;
diff --git a/modules/gdscript/language_server/gdscript_language_server.h b/modules/gdscript/language_server/gdscript_language_server.h
index 228d29bf42..29c5ddd70e 100644
--- a/modules/gdscript/language_server/gdscript_language_server.h
+++ b/modules/gdscript/language_server/gdscript_language_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,11 +40,11 @@ class GDScriptLanguageServer : public EditorPlugin {
GDScriptLanguageProtocol protocol;
- Thread *thread;
- bool thread_running;
- bool started;
- bool use_thread;
- int port;
+ Thread thread;
+ bool thread_running = false;
+ bool started = false;
+ bool use_thread = false;
+ int port = 6008;
static void thread_main(void *p_userdata);
private:
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index c6fe3169dc..9f2373bf56 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -147,7 +147,7 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
List<ScriptCodeCompletionOption> options;
GDScriptLanguageProtocol::get_singleton()->get_workspace()->completion(params, &options);
- if (!options.empty()) {
+ if (!options.is_empty()) {
int i = 0;
arr.resize(options.size());
@@ -257,7 +257,7 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
if ((item.kind == lsp::CompletionItemKind::Method || item.kind == lsp::CompletionItemKind::Function) && !item.label.ends_with("):")) {
item.insertText = item.label + "(";
- if (symbol && symbol->children.empty()) {
+ if (symbol && symbol->children.is_empty()) {
item.insertText += ")";
}
} else if (item.kind == lsp::CompletionItemKind::Event) {
@@ -341,7 +341,7 @@ Variant GDScriptTextDocument::declaration(const Dictionary &p_params) {
params.load(p_params);
List<const lsp::DocumentSymbol *> symbols;
Array arr = this->find_symbols(params, symbols);
- if (arr.empty() && !symbols.empty() && !symbols.front()->get()->native_class.empty()) { // Find a native symbol
+ if (arr.is_empty() && !symbols.is_empty() && !symbols.front()->get()->native_class.is_empty()) { // Find a native symbol
const lsp::DocumentSymbol *symbol = symbols.front()->get();
if (GDScriptLanguageProtocol::get_singleton()->is_goto_native_symbols_enabled()) {
String id;
@@ -425,7 +425,7 @@ Array GDScriptTextDocument::find_symbols(const lsp::TextDocumentPositionParams &
GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(p_location, list);
for (List<const lsp::DocumentSymbol *>::Element *E = list.front(); E; E = E->next()) {
if (const lsp::DocumentSymbol *s = E->get()) {
- if (!s->uri.empty()) {
+ if (!s->uri.is_empty()) {
lsp::Location location;
location.uri = s->uri;
location.range = s->range;
diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h
index 2a5755bec6..792e601bc1 100644
--- a/modules/gdscript/language_server/gdscript_text_document.h
+++ b/modules/gdscript/language_server/gdscript_text_document.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
index 60668e7b31..69cad1a335 100644
--- a/modules/gdscript/language_server/gdscript_workspace.cpp
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,7 +80,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::get_native_symbol(const String &p_
if (const Map<StringName, lsp::DocumentSymbol>::Element *E = native_symbols.find(class_name)) {
const lsp::DocumentSymbol &class_symbol = E->value();
- if (p_member.empty()) {
+ if (p_member.is_empty()) {
return &class_symbol;
} else {
for (int i = 0; i < class_symbol.children.size(); i++) {
@@ -171,7 +171,7 @@ ExtendGDScriptParser *GDScriptWorkspace::get_parse_result(const String &p_path)
Array GDScriptWorkspace::symbol(const Dictionary &p_params) {
String query = p_params["query"];
Array arr;
- if (!query.empty()) {
+ if (!query.is_empty()) {
for (Map<String, ExtendGDScriptParser *>::Element *E = scripts.front(); E; E = E->next()) {
Vector<lsp::DocumentedSymbolInformation> script_symbols;
E->get()->get_symbols().symbol_tree_as_list(E->key(), script_symbols);
@@ -199,7 +199,7 @@ Error GDScriptWorkspace::initialize() {
class_symbol.native_class = class_name;
class_symbol.kind = lsp::SymbolKind::Class;
class_symbol.detail = String("<Native> class ") + class_name;
- if (!class_data.inherits.empty()) {
+ if (!class_data.inherits.is_empty()) {
class_symbol.detail += " extends " + class_data.inherits;
}
class_symbol.documentation = class_data.brief_description + "\n" + class_data.description;
@@ -263,7 +263,7 @@ Error GDScriptWorkspace::initialize() {
symbol_arg.kind = lsp::SymbolKind::Variable;
symbol_arg.detail = arg.type;
- if (!arg_default_value_started && !arg.default_value.empty()) {
+ if (!arg_default_value_started && !arg.default_value.is_empty()) {
arg_default_value_started = true;
}
String arg_str = arg.name + ": " + arg.type;
@@ -278,11 +278,11 @@ Error GDScriptWorkspace::initialize() {
symbol.children.push_back(symbol_arg);
}
if (data.qualifiers.find("vararg") != -1) {
- params += params.empty() ? "..." : ", ...";
+ params += params.is_empty() ? "..." : ", ...";
}
String return_type = data.return_type;
- if (return_type.empty()) {
+ if (return_type.is_empty()) {
return_type = "void";
}
symbol.detail = "func " + class_name + "." + data.name + "(" + params + ") -> " + return_type;
@@ -350,7 +350,7 @@ Error GDScriptWorkspace::parse_local_script(const String &p_path) {
String GDScriptWorkspace::get_file_path(const String &p_uri) const {
String path = p_uri;
path = path.replace(root_uri + "/", "res://");
- path = path.http_unescape();
+ path = path.uri_decode();
return path;
}
@@ -448,13 +448,13 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
}
lsp::Position pos = p_doc_pos.position;
- if (symbol_identifier.empty()) {
+ if (symbol_identifier.is_empty()) {
Vector2i offset;
symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset);
pos.character += offset.y;
}
- if (!symbol_identifier.empty()) {
+ if (!symbol_identifier.is_empty()) {
if (ScriptServer::is_global_class(symbol_identifier)) {
String class_path = ScriptServer::get_global_class_path(symbol_identifier);
symbol = get_script_symbol(class_path);
@@ -474,7 +474,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
} else {
String member = ret.class_member;
- if (member.empty() && symbol_identifier != ret.class_name) {
+ if (member.is_empty() && symbol_identifier != ret.class_name) {
member = symbol_identifier;
}
symbol = get_native_symbol(ret.class_name, member);
@@ -529,7 +529,7 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
const lsp::DocumentSymbol *GDScriptWorkspace::resolve_native_symbol(const lsp::NativeSymbolInspectParams &p_params) {
if (Map<StringName, lsp::DocumentSymbol>::Element *E = native_symbols.find(p_params.native_class)) {
const lsp::DocumentSymbol &symbol = E->get();
- if (p_params.symbol_name.empty() || p_params.symbol_name == symbol.name) {
+ if (p_params.symbol_name.is_empty() || p_params.symbol_name == symbol.name) {
return &symbol;
}
diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h
index fc244c6357..7fd8bfcf20 100644
--- a/modules/gdscript/language_server/gdscript_workspace.h
+++ b/modules/gdscript/language_server/gdscript_workspace.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp
index 1029c53bbf..6635098be2 100644
--- a/modules/gdscript/language_server/lsp.hpp
+++ b/modules/gdscript/language_server/lsp.hpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -547,7 +547,7 @@ struct TextDocumentItem {
* The version number of this document (it will increase after each
* change, including undo/redo).
*/
- int version;
+ int version = 0;
/**
* The content of the opened text document.
@@ -584,7 +584,7 @@ struct TextDocumentContentChangeEvent {
/**
* The length of the range that got replaced.
*/
- int rangeLength;
+ int rangeLength = 0;
/**
* The new text of the range/document.
@@ -656,12 +656,12 @@ struct Diagnostic {
* The diagnostic's severity. Can be omitted. If omitted it is up to the
* client to interpret diagnostics as error, warning, info or hint.
*/
- int severity;
+ int severity = 0;
/**
* The diagnostic's code, which might appear in the user interface.
*/
- int code;
+ int code = 0;
/**
* A human-readable string describing the source of this
@@ -687,7 +687,7 @@ struct Diagnostic {
dict["severity"] = severity;
dict["message"] = message;
dict["source"] = source;
- if (!relatedInformation.empty()) {
+ if (!relatedInformation.is_empty()) {
Array arr;
arr.resize(relatedInformation.size());
for (int i = 0; i < relatedInformation.size(); i++) {
@@ -833,7 +833,7 @@ struct CompletionItem {
* an icon is chosen by the editor. The standardized set
* of available values is defined in `CompletionItemKind`.
*/
- int kind;
+ int kind = 0;
/**
* A human-readable string with additional information
@@ -891,7 +891,7 @@ struct CompletionItem {
* The format of the insert text. The format applies to both the `insertText` property
* and the `newText` property of a provided `textEdit`.
*/
- int insertTextFormat;
+ int insertTextFormat = 0;
/**
* An edit which is applied to a document when selecting this completion. When an edit is provided the value of
@@ -1003,7 +1003,7 @@ struct CompletionList {
* This list it not complete. Further typing should result in recomputing
* this list.
*/
- bool isIncomplete;
+ bool isIncomplete = false;
/**
* The completion items.
@@ -1191,7 +1191,7 @@ struct DocumentSymbol {
void symbol_tree_as_list(const String &p_uri, Vector<DocumentedSymbolInformation> &r_list, const String &p_container = "", bool p_join_name = false) const {
DocumentedSymbolInformation si;
- if (p_join_name && !p_container.empty()) {
+ if (p_join_name && !p_container.is_empty()) {
si.name = p_container + ">" + name;
} else {
si.name = name;
@@ -1661,7 +1661,7 @@ struct ServerCapabilities {
signatureHelpProvider.triggerCharacters.push_back(",");
signatureHelpProvider.triggerCharacters.push_back("(");
dict["signatureHelpProvider"] = signatureHelpProvider.to_json();
- dict["codeLensProvider"] = false; // codeLensProvider.to_json();
+ //dict["codeLensProvider"] = codeLensProvider.to_json();
dict["documentOnTypeFormattingProvider"] = documentOnTypeFormattingProvider.to_json();
dict["renameProvider"] = renameProvider.to_json();
dict["documentLinkProvider"] = documentLinkProvider.to_json();
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 0c4996e9bb..e90475a60e 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/register_types.h b/modules/gdscript/register_types.h
index 18e57c1211..ce1c03d1d0 100644
--- a/modules/gdscript/register_types.h
+++ b/modules/gdscript/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp
index 643c2f10a2..898ac653f5 100644
--- a/modules/gdscript/tests/test_gdscript.cpp
+++ b/modules/gdscript/tests/test_gdscript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -239,7 +239,7 @@ void init_autoloads() {
void test(TestType p_type) {
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
- if (cmdlargs.empty()) {
+ if (cmdlargs.is_empty()) {
return;
}
diff --git a/modules/gdscript/tests/test_gdscript.h b/modules/gdscript/tests/test_gdscript.h
index 6182629802..bbda46cdad 100644
--- a/modules/gdscript/tests/test_gdscript.h
+++ b/modules/gdscript/tests/test_gdscript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp
index 3238e0108e..545aa68747 100644
--- a/modules/glslang/register_types.cpp
+++ b/modules/glslang/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,7 +53,7 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_0;
- glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0;
+ glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_3;
glslang::TShader::ForbidIncluder includer;
glslang::TShader shader(stages[p_stage]);
diff --git a/modules/glslang/register_types.h b/modules/glslang/register_types.h
index 2437e2b27a..a1264b77c9 100644
--- a/modules/glslang/register_types.h
+++ b/modules/glslang/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp
index 0680b124b4..4cdaccde6f 100644
--- a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp
+++ b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -82,7 +82,7 @@ void SceneExporterGLTFPlugin::convert_scene_to_gltf2() {
return;
}
String filename = String(root->get_filename().get_file().get_basename());
- if (filename.empty()) {
+ if (filename.is_empty()) {
filename = root->get_name();
}
file_export_lib->set_current_file(filename + String(".gltf"));
diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.h b/modules/gltf/editor_scene_exporter_gltf_plugin.h
index 1a8910d866..d952894c16 100644
--- a/modules/gltf/editor_scene_exporter_gltf_plugin.h
+++ b/modules/gltf/editor_scene_exporter_gltf_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/editor_scene_importer_gltf.cpp b/modules/gltf/editor_scene_importer_gltf.cpp
index 51cb3a6d2e..6ea722a216 100644
--- a/modules/gltf/editor_scene_importer_gltf.cpp
+++ b/modules/gltf/editor_scene_importer_gltf.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/editor_scene_importer_gltf.h b/modules/gltf/editor_scene_importer_gltf.h
index 3da987493c..db961e591d 100644
--- a/modules/gltf/editor_scene_importer_gltf.h
+++ b/modules/gltf/editor_scene_importer_gltf.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_accessor.cpp b/modules/gltf/gltf_accessor.cpp
index 9267c58598..daeb084916 100644
--- a/modules/gltf/gltf_accessor.cpp
+++ b/modules/gltf/gltf_accessor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_accessor.h b/modules/gltf/gltf_accessor.h
index 7317928848..949a601730 100644
--- a/modules/gltf/gltf_accessor.h
+++ b/modules/gltf/gltf_accessor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_animation.cpp b/modules/gltf/gltf_animation.cpp
index 85ba117627..889a8e8870 100644
--- a/modules/gltf/gltf_animation.cpp
+++ b/modules/gltf/gltf_animation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_animation.h b/modules/gltf/gltf_animation.h
index 37fd1a2007..a494e6bd67 100644
--- a/modules/gltf/gltf_animation.h
+++ b/modules/gltf/gltf_animation.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_buffer_view.cpp b/modules/gltf/gltf_buffer_view.cpp
index edfdad40bb..ba38a11c4c 100644
--- a/modules/gltf/gltf_buffer_view.cpp
+++ b/modules/gltf/gltf_buffer_view.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_buffer_view.h b/modules/gltf/gltf_buffer_view.h
index 0b0c8af173..63af5e7c0d 100644
--- a/modules/gltf/gltf_buffer_view.h
+++ b/modules/gltf/gltf_buffer_view.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_camera.cpp b/modules/gltf/gltf_camera.cpp
index e5cfc1cbb1..efa7c5d6d7 100644
--- a/modules/gltf/gltf_camera.cpp
+++ b/modules/gltf/gltf_camera.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_camera.h b/modules/gltf/gltf_camera.h
index 7e167af7be..bf94b80bef 100644
--- a/modules/gltf/gltf_camera.h
+++ b/modules/gltf/gltf_camera.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,8 +38,8 @@ class GLTFCamera : public Resource {
private:
bool perspective = true;
- float fov_size = 75;
- float zfar = 4000;
+ float fov_size = 75.0;
+ float zfar = 4000.0;
float znear = 0.05;
protected:
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 675f5002f7..0a4d4055b4 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,6 +29,9 @@
/*************************************************************************/
#include "gltf_document.h"
+#include "core/error/error_list.h"
+#include "core/error/error_macros.h"
+#include "core/variant/variant.h"
#include "gltf_accessor.h"
#include "gltf_animation.h"
#include "gltf_camera.h"
@@ -54,8 +57,12 @@
#include "core/version_hash.gen.h"
#include "drivers/png/png_driver_common.h"
#include "editor/import/resource_importer_scene.h"
+#ifdef MODULE_CSG_ENABLED
#include "modules/csg/csg_shape.h"
+#endif // MODULE_CSG_ENABLED
+#ifdef MODULE_GRIDMAP_ENABLED
#include "modules/gridmap/grid_map.h"
+#endif // MODULE_GRIDMAP_ENABLED
#include "modules/regex/regex.h"
#include "scene/2d/node_2d.h"
#include "scene/3d/bone_attachment_3d.h"
@@ -65,6 +72,7 @@
#include "scene/3d/node_3d.h"
#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
+#include "scene/main/node.h"
#include "scene/resources/surface_tool.h"
#include <limits>
@@ -178,7 +186,7 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &
}
uint64_t elapsed = OS::get_singleton()->get_ticks_usec() - begin_time;
float elapsed_sec = double(elapsed) / 1000000.0;
- elapsed_sec = Math::stepify(elapsed_sec, 0.01f);
+ elapsed_sec = Math::snapped(elapsed_sec, 0.01f);
print_line("glTF: Export time elapsed seconds " + rtos(elapsed_sec).pad_decimals(2));
return OK;
@@ -204,7 +212,7 @@ Error GLTFDocument::_serialize_scenes(Ref<GLTFState> state) {
if (state->nodes.size()) {
Dictionary s;
- if (!state->scene_name.empty()) {
+ if (!state->scene_name.is_empty()) {
s["name"] = state->scene_name;
}
@@ -395,7 +403,7 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> state) {
Ref<GLTFNode> n = state->nodes[i];
Dictionary extensions;
node["extensions"] = extensions;
- if (!n->get_name().empty()) {
+ if (!n->get_name().is_empty()) {
node["name"] = n->get_name();
}
if (n->camera != -1) {
@@ -442,14 +450,8 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> state) {
return OK;
}
-String GLTFDocument::_sanitize_scene_name(const String &name) {
- RegEx regex("([^a-zA-Z0-9_ -]+)");
- String p_name = regex.sub(name, "", true);
- return p_name;
-}
-
String GLTFDocument::_gen_unique_name(Ref<GLTFState> state, const String &p_name) {
- const String s_name = _sanitize_scene_name(p_name);
+ const String s_name = p_name.validate_node_name();
String name;
int index = 1;
@@ -457,7 +459,7 @@ String GLTFDocument::_gen_unique_name(Ref<GLTFState> state, const String &p_name
name = s_name;
if (index > 1) {
- name += " " + itos(index);
+ name += itos(index);
}
if (!state->unique_names.has(name)) {
break;
@@ -470,6 +472,39 @@ String GLTFDocument::_gen_unique_name(Ref<GLTFState> state, const String &p_name
return name;
}
+String GLTFDocument::_sanitize_animation_name(const String &p_name) {
+ // Animations disallow the normal node invalid characters as well as "," and "["
+ // (See animation/animation_player.cpp::add_animation)
+
+ // TODO: Consider adding invalid_characters or a validate_animation_name to animation_player to mirror Node.
+ String name = p_name.validate_node_name();
+ name = name.replace(",", "");
+ name = name.replace("[", "");
+ return name;
+}
+
+String GLTFDocument::_gen_unique_animation_name(Ref<GLTFState> state, const String &p_name) {
+ const String s_name = _sanitize_animation_name(p_name);
+
+ String name;
+ int index = 1;
+ while (true) {
+ name = s_name;
+
+ if (index > 1) {
+ name += itos(index);
+ }
+ if (!state->unique_animation_names.has(name)) {
+ break;
+ }
+ index++;
+ }
+
+ state->unique_animation_names.insert(name);
+
+ return name;
+}
+
String GLTFDocument::_sanitize_bone_name(const String &name) {
String p_name = name.camelcase_to_underscore(true);
@@ -493,7 +528,7 @@ String GLTFDocument::_sanitize_bone_name(const String &name) {
String GLTFDocument::_gen_unique_bone_name(Ref<GLTFState> state, const GLTFSkeletonIndex skel_i, const String &p_name) {
String s_name = _sanitize_bone_name(p_name);
- if (s_name.empty()) {
+ if (s_name.is_empty()) {
s_name = "bone";
}
String name;
@@ -802,7 +837,9 @@ Error GLTFDocument::_encode_buffer_views(Ref<GLTFState> state) {
}
Error GLTFDocument::_parse_buffer_views(Ref<GLTFState> state) {
- ERR_FAIL_COND_V(!state->json.has("bufferViews"), ERR_FILE_CORRUPT);
+ if (!state->json.has("bufferViews")) {
+ return OK;
+ }
const Array &buffers = state->json["bufferViews"];
for (GLTFBufferViewIndex i = 0; i < buffers.size(); i++) {
const Dictionary &d = buffers[i];
@@ -846,6 +883,7 @@ Error GLTFDocument::_encode_accessors(Ref<GLTFState> state) {
d["count"] = accessor->count;
d["type"] = _get_accessor_type_name(accessor->type);
d["byteOffset"] = accessor->byte_offset;
+ d["normalized"] = accessor->normalized;
d["max"] = accessor->max;
d["min"] = accessor->min;
d["bufferView"] = accessor->buffer_view; //optional because it may be sparse...
@@ -938,7 +976,9 @@ GLTFDocument::GLTFType GLTFDocument::_get_type_from_str(const String &p_string)
}
Error GLTFDocument::_parse_accessors(Ref<GLTFState> state) {
- ERR_FAIL_COND_V(!state->json.has("accessors"), ERR_FILE_CORRUPT);
+ if (!state->json.has("accessors")) {
+ return OK;
+ }
const Array &accessors = state->json["accessors"];
for (GLTFAccessorIndex i = 0; i < accessors.size(); i++) {
const Dictionary &d = accessors[i];
@@ -961,6 +1001,10 @@ Error GLTFDocument::_parse_accessors(Ref<GLTFState> state) {
accessor->byte_offset = d["byteOffset"];
}
+ if (d.has("normalized")) {
+ accessor->normalized = d["normalized"];
+ }
+
if (d.has("max")) {
accessor->max = d["max"];
}
@@ -1455,7 +1499,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> state, c
Vector<double> type_min;
type_min.resize(element_count);
for (int i = 0; i < p_attribs.size(); i++) {
- attribs.write[i] = Math::stepify(p_attribs[i], 1.0);
+ attribs.write[i] = Math::snapped(p_attribs[i], 1.0);
if (i == 0) {
for (int32_t type_i = 0; type_i < element_count; type_i++) {
type_max.write[type_i] = attribs[(i * element_count) + type_i];
@@ -1547,8 +1591,8 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> state, c
for (int i = 0; i < p_attribs.size(); i++) {
Vector2 attrib = p_attribs[i];
- attribs.write[(i * element_count) + 0] = Math::stepify(attrib.x, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 1] = Math::stepify(attrib.y, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 0] = Math::snapped(attrib.x, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 1] = Math::snapped(attrib.y, CMP_NORMALIZE_TOLERANCE);
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
}
@@ -1593,10 +1637,10 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> state,
type_min.resize(element_count);
for (int i = 0; i < p_attribs.size(); i++) {
Color attrib = p_attribs[i];
- attribs.write[(i * element_count) + 0] = Math::stepify(attrib.r, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 1] = Math::stepify(attrib.g, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 2] = Math::stepify(attrib.b, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 3] = Math::stepify(attrib.a, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 0] = Math::snapped(attrib.r, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 1] = Math::snapped(attrib.g, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 2] = Math::snapped(attrib.b, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 3] = Math::snapped(attrib.a, CMP_NORMALIZE_TOLERANCE);
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
}
@@ -1658,10 +1702,10 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> state
type_min.resize(element_count);
for (int i = 0; i < p_attribs.size(); i++) {
Color attrib = p_attribs[i];
- attribs.write[(i * element_count) + 0] = Math::stepify(attrib.r, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 1] = Math::stepify(attrib.g, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 2] = Math::stepify(attrib.b, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 3] = Math::stepify(attrib.a, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 0] = Math::snapped(attrib.r, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 1] = Math::snapped(attrib.g, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 2] = Math::snapped(attrib.b, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 3] = Math::snapped(attrib.a, CMP_NORMALIZE_TOLERANCE);
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
}
@@ -1707,10 +1751,10 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> state,
type_min.resize(element_count);
for (int i = 0; i < p_attribs.size(); i++) {
Color attrib = p_attribs[i];
- attribs.write[(i * element_count) + 0] = Math::stepify(attrib.r, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 1] = Math::stepify(attrib.g, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 2] = Math::stepify(attrib.b, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 3] = Math::stepify(attrib.a, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 0] = Math::snapped(attrib.r, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 1] = Math::snapped(attrib.g, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 2] = Math::snapped(attrib.b, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 3] = Math::snapped(attrib.a, CMP_NORMALIZE_TOLERANCE);
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
}
ERR_FAIL_COND_V(attribs.size() % element_count != 0, -1);
@@ -1754,10 +1798,10 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quats(Ref<GLTFState> state,
type_min.resize(element_count);
for (int i = 0; i < p_attribs.size(); i++) {
Quat quat = p_attribs[i];
- attribs.write[(i * element_count) + 0] = Math::stepify(quat.x, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 1] = Math::stepify(quat.y, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 2] = Math::stepify(quat.z, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 3] = Math::stepify(quat.w, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 0] = Math::snapped(quat.x, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 1] = Math::snapped(quat.y, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 2] = Math::snapped(quat.z, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 3] = Math::snapped(quat.w, CMP_NORMALIZE_TOLERANCE);
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
}
@@ -1821,7 +1865,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> state,
type_min.resize(element_count);
for (int i = 0; i < p_attribs.size(); i++) {
- attribs.write[i] = Math::stepify(p_attribs[i], CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i] = Math::snapped(p_attribs[i], CMP_NORMALIZE_TOLERANCE);
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
}
@@ -1866,9 +1910,9 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> state, c
type_min.resize(element_count);
for (int i = 0; i < p_attribs.size(); i++) {
Vector3 attrib = p_attribs[i];
- attribs.write[(i * element_count) + 0] = Math::stepify(attrib.x, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 1] = Math::stepify(attrib.y, CMP_NORMALIZE_TOLERANCE);
- attribs.write[(i * element_count) + 2] = Math::stepify(attrib.z, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 0] = Math::snapped(attrib.x, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 1] = Math::snapped(attrib.y, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[(i * element_count) + 2] = Math::snapped(attrib.z, CMP_NORMALIZE_TOLERANCE);
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
}
@@ -1915,27 +1959,27 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> state,
Basis basis = attrib.get_basis();
Vector3 axis_0 = basis.get_axis(Vector3::AXIS_X);
- attribs.write[i * element_count + 0] = Math::stepify(axis_0.x, CMP_NORMALIZE_TOLERANCE);
- attribs.write[i * element_count + 1] = Math::stepify(axis_0.y, CMP_NORMALIZE_TOLERANCE);
- attribs.write[i * element_count + 2] = Math::stepify(axis_0.z, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 0] = Math::snapped(axis_0.x, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 1] = Math::snapped(axis_0.y, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 2] = Math::snapped(axis_0.z, CMP_NORMALIZE_TOLERANCE);
attribs.write[i * element_count + 3] = 0.0;
Vector3 axis_1 = basis.get_axis(Vector3::AXIS_Y);
- attribs.write[i * element_count + 4] = Math::stepify(axis_1.x, CMP_NORMALIZE_TOLERANCE);
- attribs.write[i * element_count + 5] = Math::stepify(axis_1.y, CMP_NORMALIZE_TOLERANCE);
- attribs.write[i * element_count + 6] = Math::stepify(axis_1.z, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 4] = Math::snapped(axis_1.x, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 5] = Math::snapped(axis_1.y, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 6] = Math::snapped(axis_1.z, CMP_NORMALIZE_TOLERANCE);
attribs.write[i * element_count + 7] = 0.0;
Vector3 axis_2 = basis.get_axis(Vector3::AXIS_Z);
- attribs.write[i * element_count + 8] = Math::stepify(axis_2.x, CMP_NORMALIZE_TOLERANCE);
- attribs.write[i * element_count + 9] = Math::stepify(axis_2.y, CMP_NORMALIZE_TOLERANCE);
- attribs.write[i * element_count + 10] = Math::stepify(axis_2.z, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 8] = Math::snapped(axis_2.x, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 9] = Math::snapped(axis_2.y, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 10] = Math::snapped(axis_2.z, CMP_NORMALIZE_TOLERANCE);
attribs.write[i * element_count + 11] = 0.0;
Vector3 origin = attrib.get_origin();
- attribs.write[i * element_count + 12] = Math::stepify(origin.x, CMP_NORMALIZE_TOLERANCE);
- attribs.write[i * element_count + 13] = Math::stepify(origin.y, CMP_NORMALIZE_TOLERANCE);
- attribs.write[i * element_count + 14] = Math::stepify(origin.z, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 12] = Math::snapped(origin.x, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 13] = Math::snapped(origin.y, CMP_NORMALIZE_TOLERANCE);
+ attribs.write[i * element_count + 14] = Math::snapped(origin.z, CMP_NORMALIZE_TOLERANCE);
attribs.write[i * element_count + 15] = 1.0;
_calc_accessor_min_max(i, element_count, type_max, attribs, type_min);
@@ -2194,33 +2238,81 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
}
}
{
- Array a = array[Mesh::ARRAY_BONES];
- if (a.size()) {
- const int ret_size = a.size() / 4;
+ const Array &a = array[Mesh::ARRAY_BONES];
+ const Vector<Vector3> &vertex_array = array[Mesh::ARRAY_VERTEX];
+ if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) {
+ const int ret_size = a.size() / JOINT_GROUP_SIZE;
Vector<Color> attribs;
attribs.resize(ret_size);
{
for (int array_i = 0; array_i < attribs.size(); array_i++) {
- int32_t joint_0 = a[(array_i * 4) + 0];
- int32_t joint_1 = a[(array_i * 4) + 1];
- int32_t joint_2 = a[(array_i * 4) + 2];
- int32_t joint_3 = a[(array_i * 4) + 3];
+ int32_t joint_0 = a[(array_i * JOINT_GROUP_SIZE) + 0];
+ int32_t joint_1 = a[(array_i * JOINT_GROUP_SIZE) + 1];
+ int32_t joint_2 = a[(array_i * JOINT_GROUP_SIZE) + 2];
+ int32_t joint_3 = a[(array_i * JOINT_GROUP_SIZE) + 3];
attribs.write[array_i] = Color(joint_0, joint_1, joint_2, joint_3);
}
}
attributes["JOINTS_0"] = _encode_accessor_as_joints(state, attribs, true);
+ } else if ((a.size() / (JOINT_GROUP_SIZE * 2)) >= vertex_array.size()) {
+ int32_t vertex_count = vertex_array.size();
+ Vector<Color> joints_0;
+ joints_0.resize(vertex_count);
+ Vector<Color> joints_1;
+ joints_1.resize(vertex_count);
+ int32_t weights_8_count = JOINT_GROUP_SIZE * 2;
+ for (int32_t vertex_i = 0; vertex_i < vertex_count; vertex_i++) {
+ Color joint_0;
+ joint_0.r = a[vertex_i * weights_8_count + 0];
+ joint_0.g = a[vertex_i * weights_8_count + 1];
+ joint_0.b = a[vertex_i * weights_8_count + 2];
+ joint_0.a = a[vertex_i * weights_8_count + 3];
+ joints_0.write[vertex_i] = joint_0;
+ Color joint_1;
+ joint_1.r = a[vertex_i * weights_8_count + 4];
+ joint_1.g = a[vertex_i * weights_8_count + 5];
+ joint_1.b = a[vertex_i * weights_8_count + 6];
+ joint_1.a = a[vertex_i * weights_8_count + 7];
+ joints_1.write[vertex_i] = joint_1;
+ }
+ attributes["JOINTS_0"] = _encode_accessor_as_joints(state, joints_0, true);
+ attributes["JOINTS_1"] = _encode_accessor_as_joints(state, joints_1, true);
}
}
{
- Array a = array[Mesh::ARRAY_WEIGHTS];
- if (a.size()) {
- const int ret_size = a.size() / 4;
+ const Array &a = array[Mesh::ARRAY_WEIGHTS];
+ const Vector<Vector3> &vertex_array = array[Mesh::ARRAY_VERTEX];
+ if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) {
+ const int ret_size = a.size() / JOINT_GROUP_SIZE;
Vector<Color> attribs;
attribs.resize(ret_size);
for (int i = 0; i < ret_size; i++) {
- attribs.write[i] = Color(a[(i * 4) + 0], a[(i * 4) + 1], a[(i * 4) + 2], a[(i * 4) + 3]);
+ attribs.write[i] = Color(a[(i * JOINT_GROUP_SIZE) + 0], a[(i * JOINT_GROUP_SIZE) + 1], a[(i * JOINT_GROUP_SIZE) + 2], a[(i * JOINT_GROUP_SIZE) + 3]);
}
attributes["WEIGHTS_0"] = _encode_accessor_as_weights(state, attribs, true);
+ } else if ((a.size() / (JOINT_GROUP_SIZE * 2)) >= vertex_array.size()) {
+ int32_t vertex_count = vertex_array.size();
+ Vector<Color> weights_0;
+ weights_0.resize(vertex_count);
+ Vector<Color> weights_1;
+ weights_1.resize(vertex_count);
+ int32_t weights_8_count = JOINT_GROUP_SIZE * 2;
+ for (int32_t vertex_i = 0; vertex_i < vertex_count; vertex_i++) {
+ Color weight_0;
+ weight_0.r = a[vertex_i * weights_8_count + 0];
+ weight_0.g = a[vertex_i * weights_8_count + 1];
+ weight_0.b = a[vertex_i * weights_8_count + 2];
+ weight_0.a = a[vertex_i * weights_8_count + 3];
+ weights_0.write[vertex_i] = weight_0;
+ Color weight_1;
+ weight_1.r = a[vertex_i * weights_8_count + 4];
+ weight_1.g = a[vertex_i * weights_8_count + 5];
+ weight_1.b = a[vertex_i * weights_8_count + 6];
+ weight_1.a = a[vertex_i * weights_8_count + 7];
+ weights_1.write[vertex_i] = weight_1;
+ }
+ attributes["WEIGHTS_0"] = _encode_accessor_as_weights(state, weights_0, true);
+ attributes["WEIGHTS_1"] = _encode_accessor_as_weights(state, weights_1, true);
}
}
{
@@ -2327,7 +2419,7 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
e["targetNames"] = target_names;
for (int j = 0; j < target_names.size(); j++) {
- real_t weight = 0;
+ real_t weight = 0.0;
if (j < state->meshes.write[gltf_mesh_i]->get_blend_weights().size()) {
weight = state->meshes.write[gltf_mesh_i]->get_blend_weights()[j];
}
@@ -2423,10 +2515,29 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
array[Mesh::ARRAY_COLOR] = _decode_accessor_as_color(state, a["COLOR_0"], true);
has_vertex_color = true;
}
- if (a.has("JOINTS_0")) {
+ if (a.has("JOINTS_0") && !a.has("JOINTS_1")) {
array[Mesh::ARRAY_BONES] = _decode_accessor_as_ints(state, a["JOINTS_0"], true);
+ } else if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
+ PackedInt32Array joints_0 = _decode_accessor_as_ints(state, a["JOINTS_0"], true);
+ PackedInt32Array joints_1 = _decode_accessor_as_ints(state, a["JOINTS_1"], true);
+ ERR_FAIL_COND_V(joints_0.size() != joints_0.size(), ERR_INVALID_DATA);
+ int32_t weight_8_count = JOINT_GROUP_SIZE * 2;
+ int32_t vertex_count = joints_0.size() / JOINT_GROUP_SIZE;
+ Vector<int> joints;
+ joints.resize(vertex_count * weight_8_count);
+ for (int32_t vertex_i = 0; vertex_i < vertex_count; vertex_i++) {
+ joints.write[vertex_i * weight_8_count + 0] = joints_0[vertex_i * JOINT_GROUP_SIZE + 0];
+ joints.write[vertex_i * weight_8_count + 1] = joints_0[vertex_i * JOINT_GROUP_SIZE + 1];
+ joints.write[vertex_i * weight_8_count + 2] = joints_0[vertex_i * JOINT_GROUP_SIZE + 2];
+ joints.write[vertex_i * weight_8_count + 3] = joints_0[vertex_i * JOINT_GROUP_SIZE + 3];
+ joints.write[vertex_i * weight_8_count + 4] = joints_1[vertex_i * JOINT_GROUP_SIZE + 0];
+ joints.write[vertex_i * weight_8_count + 5] = joints_1[vertex_i * JOINT_GROUP_SIZE + 1];
+ joints.write[vertex_i * weight_8_count + 6] = joints_1[vertex_i * JOINT_GROUP_SIZE + 2];
+ joints.write[vertex_i * weight_8_count + 7] = joints_1[vertex_i * JOINT_GROUP_SIZE + 3];
+ }
+ array[Mesh::ARRAY_BONES] = joints;
}
- if (a.has("WEIGHTS_0")) {
+ if (a.has("WEIGHTS_0") && !a.has("WEIGHTS_1")) {
Vector<float> weights = _decode_accessor_as_floats(state, a["WEIGHTS_0"], true);
{ //gltf does not seem to normalize the weights for some reason..
int wc = weights.size();
@@ -2447,6 +2558,51 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
}
}
array[Mesh::ARRAY_WEIGHTS] = weights;
+ } else if (a.has("WEIGHTS_0") && a.has("WEIGHTS_1")) {
+ Vector<float> weights_0 = _decode_accessor_as_floats(state, a["WEIGHTS_0"], true);
+ Vector<float> weights_1 = _decode_accessor_as_floats(state, a["WEIGHTS_1"], true);
+ Vector<float> weights;
+ ERR_FAIL_COND_V(weights_0.size() != weights_1.size(), ERR_INVALID_DATA);
+ int32_t weight_8_count = JOINT_GROUP_SIZE * 2;
+ int32_t vertex_count = weights_0.size() / JOINT_GROUP_SIZE;
+ weights.resize(vertex_count * weight_8_count);
+ for (int32_t vertex_i = 0; vertex_i < vertex_count; vertex_i++) {
+ weights.write[vertex_i * weight_8_count + 0] = weights_0[vertex_i * JOINT_GROUP_SIZE + 0];
+ weights.write[vertex_i * weight_8_count + 1] = weights_0[vertex_i * JOINT_GROUP_SIZE + 1];
+ weights.write[vertex_i * weight_8_count + 2] = weights_0[vertex_i * JOINT_GROUP_SIZE + 2];
+ weights.write[vertex_i * weight_8_count + 3] = weights_0[vertex_i * JOINT_GROUP_SIZE + 3];
+ weights.write[vertex_i * weight_8_count + 4] = weights_1[vertex_i * JOINT_GROUP_SIZE + 0];
+ weights.write[vertex_i * weight_8_count + 5] = weights_1[vertex_i * JOINT_GROUP_SIZE + 1];
+ weights.write[vertex_i * weight_8_count + 6] = weights_1[vertex_i * JOINT_GROUP_SIZE + 2];
+ weights.write[vertex_i * weight_8_count + 7] = weights_1[vertex_i * JOINT_GROUP_SIZE + 3];
+ }
+ { //gltf does not seem to normalize the weights for some reason..
+ int wc = weights.size();
+ float *w = weights.ptrw();
+
+ for (int k = 0; k < wc; k += weight_8_count) {
+ float total = 0.0;
+ total += w[k + 0];
+ total += w[k + 1];
+ total += w[k + 2];
+ total += w[k + 3];
+ total += w[k + 4];
+ total += w[k + 5];
+ total += w[k + 6];
+ total += w[k + 7];
+ if (total > 0.0) {
+ w[k + 0] /= total;
+ w[k + 1] /= total;
+ w[k + 2] /= total;
+ w[k + 3] /= total;
+ w[k + 4] /= total;
+ w[k + 5] /= total;
+ w[k + 6] /= total;
+ w[k + 7] /= total;
+ }
+ }
+ }
+ array[Mesh::ARRAY_WEIGHTS] = weights;
}
if (p.has("indices")) {
@@ -2487,6 +2643,9 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
//must generate mikktspace tangents.. ergh..
Ref<SurfaceTool> st;
st.instance();
+ if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
+ st->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS);
+ }
st->create_from_triangle_arrays(array);
st->generate_tangents();
array = st->commit_to_arrays();
@@ -2603,6 +2762,9 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
if (generate_tangents) {
Ref<SurfaceTool> st;
st.instance();
+ if (a.has("JOINTS_0") && a.has("JOINTS_1")) {
+ st->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS);
+ }
st->create_from_triangle_arrays(array_copy);
st->deindex();
st->generate_tangents();
@@ -2644,6 +2806,9 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
if (d.has("weights")) {
const Array &weights = d["weights"];
for (int j = 0; j < weights.size(); j++) {
+ if (j >= blend_weights.size()) {
+ break;
+ }
blend_weights.write[j] = weights[j];
}
mesh->set_blend_weights(blend_weights);
@@ -2698,7 +2863,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path
d["mimeType"] = "image/png";
} else {
String name = state->images[i]->get_name();
- if (name.empty()) {
+ if (name.is_empty()) {
name = itos(i);
}
name = _gen_unique_name(state, name);
@@ -2780,7 +2945,7 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat
data_ptr = data.ptr();
data_size = data.size();
// mimeType is optional, but if we have it defined in the URI, let's use it.
- if (mimetype.empty()) {
+ if (mimetype.is_empty()) {
if (uri.begins_with("data:image/png;base64")) {
mimetype = "image/png";
} else if (uri.begins_with("data:image/jpeg;base64")) {
@@ -2789,27 +2954,36 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> state, const String &p_base_pat
}
} else { // Relative path to an external image file.
uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows.
- // The spec says that if mimeType is defined, we should enforce it.
- // So we should only rely on ResourceLoader::load if mimeType is not defined,
- // otherwise we should use the same logic as for buffers.
- if (mimetype == "image/png" || mimetype == "image/jpeg") {
- // Load data buffer and rely on PNG and JPEG-specific logic below to load the image.
- // This makes it possible to load a file with a wrong extension but correct MIME type,
- // e.g. "foo.jpg" containing PNG data and with MIME type "image/png". ResourceLoader would fail.
+ // ResourceLoader will rely on the file extension to use the relevant loader.
+ // The spec says that if mimeType is defined, it should take precedence (e.g.
+ // there could be a `.png` image which is actually JPEG), but there's no easy
+ // API for that in Godot, so we'd have to load as a buffer (i.e. embedded in
+ // the material), so we do this only as fallback.
+ Ref<Texture2D> texture = ResourceLoader::load(uri);
+ if (texture.is_valid()) {
+ state->images.push_back(texture);
+ continue;
+ } else if (mimetype == "image/png" || mimetype == "image/jpeg") {
+ // Fallback to loading as byte array.
+ // This enables us to support the spec's requirement that we honor mimetype
+ // regardless of file URI.
data = FileAccess::get_file_as_array(uri);
- ERR_FAIL_COND_V_MSG(data.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load image file as an array: " + uri);
+ if (data.size() == 0) {
+ WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded as a buffer of MIME type '%s' from URI: %s. Skipping it.", i, mimetype, uri));
+ state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
+ continue;
+ }
data_ptr = data.ptr();
data_size = data.size();
} else {
- // Good old ResourceLoader will rely on file extension.
- Ref<Texture2D> texture = ResourceLoader::load(uri);
- state->images.push_back(texture);
+ WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded from URI: %s. Skipping it.", i, uri));
+ state->images.push_back(Ref<Texture2D>()); // Placeholder to keep count.
continue;
}
}
} else if (d.has("bufferView")) {
// Handles the third bullet point from the spec (bufferView).
- ERR_FAIL_COND_V_MSG(mimetype.empty(), ERR_FILE_CORRUPT,
+ ERR_FAIL_COND_V_MSG(mimetype.is_empty(), ERR_FILE_CORRUPT,
vformat("glTF: Image index '%d' specifies 'bufferView' but no 'mimeType', which is invalid.", i));
const GLTFBufferViewIndex bvi = d["bufferView"];
@@ -2931,7 +3105,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
materials.push_back(d);
continue;
}
- if (!material->get_name().empty()) {
+ if (!material->get_name().is_empty()) {
d["name"] = _gen_unique_name(state, material->get_name());
}
{
@@ -4066,7 +4240,7 @@ Error GLTFDocument::_create_skeletons(Ref<GLTFState> state) {
// a sorted order, and DEPTH FIRST
bones.sort();
- while (!bones.empty()) {
+ while (!bones.is_empty()) {
const GLTFNodeIndex node_i = bones.front()->get();
bones.pop_front();
@@ -4091,7 +4265,7 @@ Error GLTFDocument::_create_skeletons(Ref<GLTFState> state) {
const int bone_index = skeleton->get_bone_count();
- if (node->get_name().empty()) {
+ if (node->get_name().is_empty()) {
node->set_name("bone");
}
@@ -4148,7 +4322,7 @@ Error GLTFDocument::_create_skins(Ref<GLTFState> state) {
skin.instance();
// Some skins don't have IBM's! What absolute monsters!
- const bool has_ibms = !gltf_skin->inverse_binds.empty();
+ const bool has_ibms = !gltf_skin->inverse_binds.is_empty();
for (int joint_i = 0; joint_i < gltf_skin->joints_original.size(); ++joint_i) {
GLTFNodeIndex node = gltf_skin->joints_original[joint_i];
@@ -4176,7 +4350,7 @@ Error GLTFDocument::_create_skins(Ref<GLTFState> state) {
// Create unique names now, after removing duplicates
for (GLTFSkinIndex skin_i = 0; skin_i < state->skins.size(); ++skin_i) {
Ref<Skin> skin = state->skins.write[skin_i]->godot_skin;
- if (skin->get_name().empty()) {
+ if (skin->get_name().is_empty()) {
// Make a unique name, no gltf node represents this skin
skin->set_name(_gen_unique_name(state, "Skin"));
}
@@ -4442,7 +4616,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) {
continue;
}
- if (!gltf_animation->get_name().empty()) {
+ if (!gltf_animation->get_name().is_empty()) {
d["name"] = gltf_animation->get_name();
}
Array channels;
@@ -4583,7 +4757,7 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) {
if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) {
animation->set_loop(true);
}
- animation->set_name(_sanitize_scene_name(name));
+ animation->set_name(_gen_unique_animation_name(state, name));
}
for (int j = 0; j < channels.size(); j++) {
@@ -4702,7 +4876,7 @@ void GLTFDocument::_assign_scene_names(Ref<GLTFState> state) {
if (n->skeleton >= 0)
continue;
- if (n->get_name().empty()) {
+ if (n->get_name().is_empty()) {
if (n->mesh >= 0) {
n->set_name(_gen_unique_name(state, "Mesh"));
} else if (n->camera >= 0) {
@@ -4883,12 +5057,12 @@ GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> state, Camera3D *p_
if (p_camera->get_projection() == Camera3D::Projection::PROJECTION_PERSPECTIVE) {
c->set_perspective(true);
c->set_fov_size(p_camera->get_fov());
- c->set_zfar(p_camera->get_zfar());
- c->set_znear(p_camera->get_znear());
+ c->set_zfar(p_camera->get_far());
+ c->set_znear(p_camera->get_near());
} else {
c->set_fov_size(p_camera->get_fov());
- c->set_zfar(p_camera->get_zfar());
- c->set_znear(p_camera->get_znear());
+ c->set_zfar(p_camera->get_far());
+ c->set_znear(p_camera->get_near());
}
GLTFCameraIndex camera_index = state->cameras.size();
state->cameras.push_back(c);
@@ -4959,7 +5133,6 @@ Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, Node *scene_parent
}
void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, Node *p_root, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) {
bool retflag = true;
- Node3D *spatial = cast_to<Node3D>(p_current);
_check_visibility(p_current, retflag);
if (retflag) {
return;
@@ -4968,9 +5141,11 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, No
gltf_node.instance();
gltf_node->set_name(_gen_unique_name(state, p_current->get_name()));
if (cast_to<Node3D>(p_current)) {
+ Node3D *spatial = cast_to<Node3D>(p_current);
_convert_spatial(state, spatial, gltf_node);
}
if (cast_to<MeshInstance3D>(p_current)) {
+ Node3D *spatial = cast_to<Node3D>(p_current);
_convert_mesh_to_gltf(p_current, state, spatial, gltf_node);
} else if (cast_to<BoneAttachment3D>(p_current)) {
_convert_bone_attachment_to_gltf(p_current, state, gltf_node, retflag);
@@ -4982,18 +5157,22 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, No
return;
} else if (cast_to<MultiMeshInstance3D>(p_current)) {
_convert_mult_mesh_instance_to_gltf(p_current, p_gltf_parent, p_gltf_root, gltf_node, state, p_root);
+#ifdef MODULE_CSG_ENABLED
} else if (cast_to<CSGShape3D>(p_current)) {
if (p_current->get_parent() && cast_to<CSGShape3D>(p_current)->is_root_shape()) {
_convert_csg_shape_to_gltf(p_current, p_gltf_parent, gltf_node, state);
}
+#endif // MODULE_CSG_ENABLED
+#ifdef MODULE_GRIDMAP_ENABLED
} else if (cast_to<GridMap>(p_current)) {
_convert_grid_map_to_gltf(p_current, p_gltf_parent, p_gltf_root, gltf_node, state, p_root);
+#endif // MODULE_GRIDMAP_ENABLED
} else if (cast_to<Camera3D>(p_current)) {
Camera3D *camera = Object::cast_to<Camera3D>(p_current);
- _convert_camera_to_gltf(camera, state, spatial, gltf_node);
+ _convert_camera_to_gltf(camera, state, camera, gltf_node);
} else if (cast_to<Light3D>(p_current)) {
Light3D *light = Object::cast_to<Light3D>(p_current);
- _convert_light_to_gltf(light, state, spatial, gltf_node);
+ _convert_light_to_gltf(light, state, light, gltf_node);
} else if (cast_to<AnimationPlayer>(p_current)) {
AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_current);
_convert_animation_player_to_gltf(animation_player, state, p_gltf_parent, p_gltf_root, gltf_node, p_current, p_root);
@@ -5012,6 +5191,7 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, No
}
}
+#ifdef MODULE_CSG_ENABLED
void GLTFDocument::_convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state) {
CSGShape3D *csg = Object::cast_to<CSGShape3D>(p_current);
csg->call("_update_shape");
@@ -5038,6 +5218,7 @@ void GLTFDocument::_convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_g
gltf_node->xform = csg->get_meshes()[0];
gltf_node->set_name(_gen_unique_name(state, csg->get_name()));
}
+#endif // MODULE_CSG_ENABLED
void GLTFDocument::_create_gltf_node(Ref<GLTFState> state, Node *p_scene_parent, GLTFNodeIndex current_node_i,
GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_gltf_node, Ref<GLTFNode> gltf_node) {
@@ -5087,6 +5268,7 @@ void GLTFDocument::_convert_light_to_gltf(Light3D *light, Ref<GLTFState> state,
}
}
+#ifdef MODULE_GRIDMAP_ENABLED
void GLTFDocument::_convert_grid_map_to_gltf(Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node) {
GridMap *grid_map = Object::cast_to<GridMap>(p_scene_parent);
ERR_FAIL_COND(!grid_map);
@@ -5118,6 +5300,7 @@ void GLTFDocument::_convert_grid_map_to_gltf(Node *p_scene_parent, const GLTFNod
new_gltf_node->set_name(_gen_unique_name(state, grid_map->get_mesh_library()->get_item_name(cell)));
}
}
+#endif // MODULE_GRIDMAP_ENABLED
void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node) {
MultiMeshInstance3D *multi_mesh_instance = Object::cast_to<MultiMeshInstance3D>(p_scene_parent);
@@ -5133,8 +5316,7 @@ void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, con
transform.origin =
Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y);
real_t rotation = xform_2d.get_rotation();
- Quat quat;
- quat.set_axis_angle(Vector3(0, 1, 0), rotation);
+ Quat quat(Vector3(0, 1, 0), rotation);
Size2 scale = xform_2d.get_scale();
transform.basis.set_quat_scale(quat,
Vector3(scale.x, 0, scale.y));
@@ -5402,7 +5584,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap,
Ref<GLTFAnimation> anim = state->animations[index];
String name = anim->get_name();
- if (name.empty()) {
+ if (name.is_empty()) {
// No node represent these, and they are not in the hierarchy, so just make a unique name
name = _gen_unique_name(state, "Animation");
}
@@ -5415,7 +5597,7 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap,
animation->set_loop(true);
}
- float length = 0;
+ float length = 0.0;
for (Map<int, GLTFAnimation::Track>::Element *track_i = anim->get_tracks().front(); track_i; track_i = track_i->next()) {
const GLTFAnimation::Track &track = track_i->get();
@@ -5647,7 +5829,7 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) {
Ref<GLTFSkeleton> gltf_skeleton = state->skeletons.write[skeleton_gltf_i];
for (int32_t bind_i = 0; bind_i < skin->get_bind_count(); bind_i++) {
String godot_bone_name = skin->get_bind_name(bind_i);
- if (godot_bone_name.empty()) {
+ if (godot_bone_name.is_empty()) {
int32_t bone = skin->get_bind_bone(bind_i);
godot_bone_name = skeleton->get_bone_name(bone);
}
@@ -5886,14 +6068,12 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
p_track.rotation_track.interpolation = gltf_interpolation;
for (int32_t key_i = 0; key_i < key_count; key_i++) {
- Quat rotation;
Vector3 rotation_degrees = p_animation->track_get_key_value(p_track_i, key_i);
Vector3 rotation_radian;
rotation_radian.x = Math::deg2rad(rotation_degrees.x);
rotation_radian.y = Math::deg2rad(rotation_degrees.y);
rotation_radian.z = Math::deg2rad(rotation_degrees.z);
- rotation.set_euler(rotation_radian);
- p_track.rotation_track.values.write[key_i] = rotation;
+ p_track.rotation_track.values.write[key_i] = Quat(rotation_radian);
}
} else if (path.find(":scale") != -1) {
p_track.scale_track.times = times;
@@ -6145,18 +6325,22 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
}
}
} else if (String(orig_track_path).find(":") == -1) {
- const Node *node = ap->get_parent()->get_node_or_null(orig_track_path);
- for (Map<GLTFNodeIndex, Node *>::Element *scene_node_i = state->scene_nodes.front(); scene_node_i; scene_node_i = scene_node_i->next()) {
- if (scene_node_i->get() == node) {
- GLTFNodeIndex node_index = scene_node_i->key();
- Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_index);
- GLTFAnimation::Track track;
- if (node_track_i) {
- track = node_track_i->get();
+ ERR_CONTINUE(!ap->get_parent());
+ for (int32_t node_i = 0; node_i < ap->get_parent()->get_child_count(); node_i++) {
+ const Node *child = ap->get_parent()->get_child(node_i);
+ const Node *node = child->get_node_or_null(orig_track_path);
+ for (Map<GLTFNodeIndex, Node *>::Element *scene_node_i = state->scene_nodes.front(); scene_node_i; scene_node_i = scene_node_i->next()) {
+ if (scene_node_i->get() == node) {
+ GLTFNodeIndex node_index = scene_node_i->key();
+ Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_index);
+ GLTFAnimation::Track track;
+ if (node_track_i) {
+ track = node_track_i->get();
+ }
+ track = _convert_animation_track(state, track, animation, Transform(), track_i, node_index);
+ gltf_animation->get_tracks().insert(node_index, track);
+ break;
}
- track = _convert_animation_track(state, track, animation, Transform(), track_i, node_index);
- gltf_animation->get_tracks().insert(node_index, track);
- break;
}
}
}
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 0f4772cd26..bda1ce87d6 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,6 +34,7 @@
#include "editor/import/resource_importer_scene.h"
#include "editor/import/scene_importer_mesh_node_3d.h"
#include "gltf_animation.h"
+#include "modules/modules_enabled.gen.h"
#include "scene/2d/node_2d.h"
#include "scene/3d/bone_attachment_3d.h"
#include "scene/3d/light_3d.h"
@@ -71,6 +72,7 @@ class GLTFDocument : public Resource {
friend class GLTFSkeleton;
public:
+ const int32_t JOINT_GROUP_SIZE = 4;
enum GLTFType {
TYPE_SCALAR,
TYPE_VEC2,
@@ -160,8 +162,9 @@ private:
Error _parse_nodes(Ref<GLTFState> state);
String _get_type_name(const GLTFType p_component);
String _get_accessor_type_name(const GLTFDocument::GLTFType p_type);
- String _sanitize_scene_name(const String &name);
String _gen_unique_name(Ref<GLTFState> state, const String &p_name);
+ String _sanitize_animation_name(const String &name);
+ String _gen_unique_animation_name(Ref<GLTFState> state, const String &p_name);
String _sanitize_bone_name(const String &name);
String _gen_unique_bone_name(Ref<GLTFState> state,
const GLTFSkeletonIndex skel_i,
@@ -376,7 +379,9 @@ public:
const GLTFNodeIndex p_gltf_current,
const GLTFNodeIndex p_gltf_root);
+#ifdef MODULE_CSG_ENABLED
void _convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state);
+#endif // MODULE_CSG_ENABLED
void _create_gltf_node(Ref<GLTFState> state,
Node *p_scene_parent,
@@ -394,12 +399,14 @@ public:
void _convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> state,
Node3D *spatial,
Ref<GLTFNode> gltf_node);
+#ifdef MODULE_GRIDMAP_ENABLED
void _convert_grid_map_to_gltf(
Node *p_scene_parent,
const GLTFNodeIndex &p_parent_node_index,
const GLTFNodeIndex &p_root_node_index,
Ref<GLTFNode> gltf_node, Ref<GLTFState> state,
Node *p_root_node);
+#endif // MODULE_GRIDMAP_ENABLED
void _convert_mult_mesh_instance_to_gltf(
Node *p_scene_parent,
const GLTFNodeIndex &p_parent_node_index,
diff --git a/modules/gltf/gltf_light.cpp b/modules/gltf/gltf_light.cpp
index da0e504474..95cca9cf71 100644
--- a/modules/gltf/gltf_light.cpp
+++ b/modules/gltf/gltf_light.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_light.h b/modules/gltf/gltf_light.h
index 966ef5dd44..a859ca1833 100644
--- a/modules/gltf/gltf_light.h
+++ b/modules/gltf/gltf_light.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_mesh.cpp b/modules/gltf/gltf_mesh.cpp
index 09995faab3..8c10e42c89 100644
--- a/modules/gltf/gltf_mesh.cpp
+++ b/modules/gltf/gltf_mesh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_mesh.h b/modules/gltf/gltf_mesh.h
index 5fb3069ad2..0fc750fc9f 100644
--- a/modules/gltf/gltf_mesh.h
+++ b/modules/gltf/gltf_mesh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_node.cpp b/modules/gltf/gltf_node.cpp
index 2fbd3f85d4..777c6fbd9a 100644
--- a/modules/gltf/gltf_node.cpp
+++ b/modules/gltf/gltf_node.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_node.h b/modules/gltf/gltf_node.h
index b96e700ec2..ce8aff8944 100644
--- a/modules/gltf/gltf_node.h
+++ b/modules/gltf/gltf_node.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_skeleton.cpp b/modules/gltf/gltf_skeleton.cpp
index 35671335d3..d6c7a25eaf 100644
--- a/modules/gltf/gltf_skeleton.cpp
+++ b/modules/gltf/gltf_skeleton.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,7 +41,7 @@ void GLTFSkeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_godot_bone_node"), &GLTFSkeleton::get_godot_bone_node);
ClassDB::bind_method(D_METHOD("set_godot_bone_node", "godot_bone_node"), &GLTFSkeleton::set_godot_bone_node);
ClassDB::bind_method(D_METHOD("get_bone_attachment_count"), &GLTFSkeleton::get_bone_attachment_count);
- ClassDB::bind_method(D_METHOD("get_bone_attachment"), &GLTFSkeleton::get_bone_attachment);
+ ClassDB::bind_method(D_METHOD("get_bone_attachment", "idx"), &GLTFSkeleton::get_bone_attachment);
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "joints"), "set_joints", "get_joints"); // Vector<GLTFNodeIndex>
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "roots"), "set_roots", "get_roots"); // Vector<GLTFNodeIndex>
diff --git a/modules/gltf/gltf_skeleton.h b/modules/gltf/gltf_skeleton.h
index 6263fa3c5d..d6986eb35a 100644
--- a/modules/gltf/gltf_skeleton.h
+++ b/modules/gltf/gltf_skeleton.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_skin.cpp b/modules/gltf/gltf_skin.cpp
index 1b94b9d106..5a61e5778c 100644
--- a/modules/gltf/gltf_skin.cpp
+++ b/modules/gltf/gltf_skin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -142,7 +142,7 @@ void GLTFSkin::set_joint_i_to_name(Dictionary p_joint_i_to_name) {
joint_i_to_name = Map<int, StringName>();
Array keys = p_joint_i_to_name.keys();
for (int i = 0; i < keys.size(); i++) {
- joint_i_to_name[keys[i]] = joint_i_to_name[keys[i]];
+ joint_i_to_name[keys[i]] = p_joint_i_to_name[keys[i]];
}
}
diff --git a/modules/gltf/gltf_skin.h b/modules/gltf/gltf_skin.h
index 09e1a37a55..7cc09d85bc 100644
--- a/modules/gltf/gltf_skin.h
+++ b/modules/gltf/gltf_skin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_spec_gloss.cpp b/modules/gltf/gltf_spec_gloss.cpp
index 7f27805d62..70b182da52 100644
--- a/modules/gltf/gltf_spec_gloss.cpp
+++ b/modules/gltf/gltf_spec_gloss.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_spec_gloss.h b/modules/gltf/gltf_spec_gloss.h
index e06c6c14f3..3cc6fb09ed 100644
--- a/modules/gltf/gltf_spec_gloss.h
+++ b/modules/gltf/gltf_spec_gloss.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp
index 403ae26bd3..ff9778e7d8 100644
--- a/modules/gltf/gltf_state.cpp
+++ b/modules/gltf/gltf_state.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,8 +51,8 @@ void GLTFState::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_accessors", "accessors"), &GLTFState::set_accessors);
ClassDB::bind_method(D_METHOD("get_meshes"), &GLTFState::get_meshes);
ClassDB::bind_method(D_METHOD("set_meshes", "meshes"), &GLTFState::set_meshes);
- ClassDB::bind_method(D_METHOD("get_animation_players_count"), &GLTFState::get_animation_players_count);
- ClassDB::bind_method(D_METHOD("get_animation_player"), &GLTFState::get_animation_player);
+ ClassDB::bind_method(D_METHOD("get_animation_players_count", "idx"), &GLTFState::get_animation_players_count);
+ ClassDB::bind_method(D_METHOD("get_animation_player", "idx"), &GLTFState::get_animation_player);
ClassDB::bind_method(D_METHOD("get_materials"), &GLTFState::get_materials);
ClassDB::bind_method(D_METHOD("set_materials", "materials"), &GLTFState::set_materials);
ClassDB::bind_method(D_METHOD("get_scene_name"), &GLTFState::get_scene_name);
@@ -71,13 +71,15 @@ void GLTFState::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_lights", "lights"), &GLTFState::set_lights);
ClassDB::bind_method(D_METHOD("get_unique_names"), &GLTFState::get_unique_names);
ClassDB::bind_method(D_METHOD("set_unique_names", "unique_names"), &GLTFState::set_unique_names);
+ ClassDB::bind_method(D_METHOD("get_unique_animation_names"), &GLTFState::get_unique_animation_names);
+ ClassDB::bind_method(D_METHOD("set_unique_animation_names", "unique_animation_names"), &GLTFState::set_unique_animation_names);
ClassDB::bind_method(D_METHOD("get_skeletons"), &GLTFState::get_skeletons);
ClassDB::bind_method(D_METHOD("set_skeletons", "skeletons"), &GLTFState::set_skeletons);
ClassDB::bind_method(D_METHOD("get_skeleton_to_node"), &GLTFState::get_skeleton_to_node);
ClassDB::bind_method(D_METHOD("set_skeleton_to_node", "skeleton_to_node"), &GLTFState::set_skeleton_to_node);
ClassDB::bind_method(D_METHOD("get_animations"), &GLTFState::get_animations);
ClassDB::bind_method(D_METHOD("set_animations", "animations"), &GLTFState::set_animations);
- ClassDB::bind_method(D_METHOD("get_scene_node"), &GLTFState::get_scene_node);
+ ClassDB::bind_method(D_METHOD("get_scene_node", "idx"), &GLTFState::get_scene_node);
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "json"), "set_json", "get_json"); // Dictionary
ADD_PROPERTY(PropertyInfo(Variant::INT, "major_version"), "set_major_version", "get_major_version"); // int
@@ -98,6 +100,7 @@ void GLTFState::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "cameras", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_cameras", "get_cameras"); // Vector<Ref<GLTFCamera>>
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "lights", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_lights", "get_lights"); // Vector<Ref<GLTFLight>>
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "unique_names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_unique_names", "get_unique_names"); // Set<String>
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "unique_animation_names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_unique_animation_names", "get_unique_animation_names"); // Set<String>
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "skeletons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_skeletons", "get_skeletons"); // Vector<Ref<GLTFSkeleton>>
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "skeleton_to_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_skeleton_to_node", "get_skeleton_to_node"); // Map<GLTFSkeletonIndex,
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_animations", "get_animations"); // Vector<Ref<GLTFAnimation>>
@@ -255,6 +258,14 @@ void GLTFState::set_unique_names(Array p_unique_names) {
GLTFDocument::set_from_array(unique_names, p_unique_names);
}
+Array GLTFState::get_unique_animation_names() {
+ return GLTFDocument::to_array(unique_animation_names);
+}
+
+void GLTFState::set_unique_animation_names(Array p_unique_animation_names) {
+ GLTFDocument::set_from_array(unique_animation_names, p_unique_animation_names);
+}
+
Array GLTFState::get_skeletons() {
return GLTFDocument::to_array(skeletons);
}
diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h
index f21472ad1b..9030962b03 100644
--- a/modules/gltf/gltf_state.h
+++ b/modules/gltf/gltf_state.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,6 +80,7 @@ class GLTFState : public Resource {
Vector<Ref<GLTFCamera>> cameras;
Vector<Ref<GLTFLight>> lights;
Set<String> unique_names;
+ Set<String> unique_animation_names;
Vector<Ref<GLTFSkeleton>> skeletons;
Map<GLTFSkeletonIndex, GLTFNodeIndex> skeleton_to_node;
@@ -147,6 +148,9 @@ public:
Array get_unique_names();
void set_unique_names(Array p_unique_names);
+ Array get_unique_animation_names();
+ void set_unique_animation_names(Array p_unique_names);
+
Array get_skeletons();
void set_skeletons(Array p_skeletons);
diff --git a/modules/gltf/gltf_texture.cpp b/modules/gltf/gltf_texture.cpp
index 55434a5047..0482c1064e 100644
--- a/modules/gltf/gltf_texture.cpp
+++ b/modules/gltf/gltf_texture.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/gltf_texture.h b/modules/gltf/gltf_texture.h
index 5e0c9c307b..e1d0407fb4 100644
--- a/modules/gltf/gltf_texture.h
+++ b/modules/gltf/gltf_texture.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp
index bd5775af34..dc995c9249 100644
--- a/modules/gltf/register_types.cpp
+++ b/modules/gltf/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -60,9 +60,10 @@ static void _editor_init() {
void register_gltf_types() {
#ifndef _3D_DISABLED
#ifdef TOOLS_ENABLED
- ClassDB::register_class<EditorSceneImporterGLTF>();
ClassDB::APIType prev_api = ClassDB::get_current_api();
ClassDB::set_current_api(ClassDB::API_EDITOR);
+ ClassDB::register_class<EditorSceneImporterGLTF>();
+ ClassDB::register_class<GLTFMesh>();
EditorPlugins::add_by_type<SceneExporterGLTFPlugin>();
ClassDB::set_current_api(prev_api);
EditorNode::add_init_callback(_editor_init);
@@ -75,7 +76,6 @@ void register_gltf_types() {
ClassDB::register_class<GLTFTexture>();
ClassDB::register_class<GLTFSkeleton>();
ClassDB::register_class<GLTFSkin>();
- ClassDB::register_class<GLTFMesh>();
ClassDB::register_class<GLTFCamera>();
ClassDB::register_class<GLTFLight>();
ClassDB::register_class<GLTFState>();
diff --git a/modules/gltf/register_types.h b/modules/gltf/register_types.h
index ffbc586ade..fefacb1106 100644
--- a/modules/gltf/register_types.h
+++ b/modules/gltf/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index 4dccb03369..25776b1f6d 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -8,6 +8,7 @@
GridMaps use a [MeshLibrary] which contains a list of tiles. Each tile is a mesh with materials plus optional collision and navigation shapes.
A GridMap contains a collection of cells. Each grid cell refers to a tile in the [MeshLibrary]. All cells in the map have the same dimensions.
Internally, a GridMap is split into a sparse collection of octants for efficient rendering and physics processing. Every octant has the same dimensions and can contain several cells.
+ [b]Note:[/b] GridMap doesn't extend [VisualInstance3D] and therefore can't be hidden or cull masked based on [member VisualInstance3D.layers]. If you make a light not affect the first layer, the whole GridMap won't be lit by the light in question.
</description>
<tutorials>
<link title="Using gridmaps">https://docs.godotengine.org/en/latest/tutorials/3d/using_gridmaps.html</link>
@@ -40,6 +41,7 @@
<return type="Array">
</return>
<description>
+ Returns an array of [ArrayMesh]es and [Transform] references of all bake meshes that exist within the current GridMap.
</description>
</method>
<method name="get_cell_item" qualifiers="const">
@@ -182,6 +184,9 @@
</method>
</methods>
<members>
+ <member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false">
+ If [code]true[/code], this GridMap bakes a navigation region.
+ </member>
<member name="cell_center_x" type="bool" setter="set_center_x" getter="get_center_x" default="true">
If [code]true[/code], grid items are centered on the X axis.
</member>
@@ -209,6 +214,9 @@
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
The physics layers this GridMap detects collisions in. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
</member>
+ <member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
+ The navigation layers the GridMap generates its navigable regions in.
+ </member>
<member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library">
The assigned [MeshLibrary].
</member>
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 633b209f0f..c1c230d104 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -179,6 +179,24 @@ bool GridMap::get_collision_layer_bit(int p_bit) const {
return get_collision_layer() & (1 << p_bit);
}
+void GridMap::set_bake_navigation(bool p_bake_navigation) {
+ bake_navigation = p_bake_navigation;
+ _recreate_octant_data();
+}
+
+bool GridMap::is_baking_navigation() {
+ return bake_navigation;
+}
+
+void GridMap::set_navigation_layers(uint32_t p_layers) {
+ navigation_layers = p_layers;
+ _recreate_octant_data();
+}
+
+uint32_t GridMap::get_navigation_layers() {
+ return navigation_layers;
+}
+
void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) {
if (!mesh_library.is_null()) {
mesh_library->unregister_owner(this);
@@ -189,7 +207,6 @@ void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) {
}
_recreate_octant_data();
- _change_notify("mesh_library");
}
Ref<MeshLibrary> GridMap::get_mesh_library() const {
@@ -286,7 +303,8 @@ void GridMap::set_cell_item(const Vector3i &p_position, int p_item, int p_rot) {
//create octant because it does not exist
Octant *g = memnew(Octant);
g->dirty = true;
- g->static_body = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
+ g->static_body = PhysicsServer3D::get_singleton()->body_create();
+ PhysicsServer3D::get_singleton()->body_set_mode(g->static_body, PhysicsServer3D::BODY_MODE_STATIC);
PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id());
PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer);
PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask);
@@ -474,13 +492,15 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
Octant::NavMesh nm;
nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item);
- if (navigation) {
+ if (bake_navigation) {
RID region = NavigationServer3D::get_singleton()->region_create();
+ NavigationServer3D::get_singleton()->region_set_layers(region, navigation_layers);
NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh);
- NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * nm.xform);
- NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
+ NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * mesh_library->get_item_navmesh_transform(c.item));
+ NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
nm.region = region;
}
+
g.navmesh_ids[E->get()] = nm;
}
}
@@ -491,7 +511,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
Octant::MultimeshInstance mmi;
RID mm = RS::get_singleton()->multimesh_create();
- RS::get_singleton()->multimesh_allocate(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D);
+ RS::get_singleton()->multimesh_allocate_data(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D);
RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid());
int idx = 0;
@@ -564,15 +584,17 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) {
RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform());
}
- if (navigation && mesh_library.is_valid()) {
+ if (bake_navigation && mesh_library.is_valid()) {
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
if (cell_map.has(F->key()) && F->get().region.is_valid() == false) {
Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item);
if (nm.is_valid()) {
RID region = NavigationServer3D::get_singleton()->region_create();
+ NavigationServer3D::get_singleton()->region_set_layers(region, navigation_layers);
NavigationServer3D::get_singleton()->region_set_navmesh(region, nm);
- NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * F->get().xform);
- NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
+ NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F->get().xform);
+ NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
+
F->get().region = region;
}
}
@@ -594,12 +616,10 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) {
RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID());
}
- if (navigation) {
- for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
- if (F->get().region.is_valid()) {
- NavigationServer3D::get_singleton()->free(F->get().region);
- F->get().region = RID();
- }
+ for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
+ if (F->get().region.is_valid()) {
+ NavigationServer3D::get_singleton()->free(F->get().region);
+ F->get().region = RID();
}
}
}
@@ -635,16 +655,6 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) {
void GridMap::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
- Node3D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation3D>(c);
- if (navigation) {
- break;
- }
-
- c = Object::cast_to<Node3D>(c->get_parent());
- }
-
last_transform = get_global_transform();
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
@@ -679,8 +689,6 @@ void GridMap::_notification(int p_what) {
_octant_exit_world(E->key());
}
- navigation = nullptr;
-
//_queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS);
//_update_octants_callback();
//_update_area_instances();
@@ -700,8 +708,6 @@ void GridMap::_update_visibility() {
return;
}
- _change_notify("visible");
-
for (Map<OctantKey, Octant *>::Element *e = octant_map.front(); e; e = e->next()) {
Octant *octant = e->value();
for (int i = 0; i < octant->multimesh_instances.size(); i++) {
@@ -787,6 +793,12 @@ void GridMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &GridMap::set_collision_layer_bit);
ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &GridMap::get_collision_layer_bit);
+ ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &GridMap::set_bake_navigation);
+ ClassDB::bind_method(D_METHOD("is_baking_navigation"), &GridMap::is_baking_navigation);
+
+ ClassDB::bind_method(D_METHOD("set_navigation_layers", "layers"), &GridMap::set_navigation_layers);
+ ClassDB::bind_method(D_METHOD("get_navigation_layers"), &GridMap::get_navigation_layers);
+
ClassDB::bind_method(D_METHOD("set_mesh_library", "mesh_library"), &GridMap::set_mesh_library);
ClassDB::bind_method(D_METHOD("get_mesh_library"), &GridMap::get_mesh_library);
@@ -840,6 +852,9 @@ void GridMap::_bind_methods() {
ADD_GROUP("Collision", "collision_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
+ ADD_GROUP("Navigation", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
BIND_CONSTANT(INVALID_CELL_ITEM);
@@ -1046,26 +1061,7 @@ RID GridMap::get_bake_mesh_instance(int p_idx) {
}
GridMap::GridMap() {
- collision_layer = 1;
- collision_mask = 1;
-
- cell_size = Vector3(2, 2, 2);
- octant_size = 8;
- awaiting_update = false;
- _in_tree = false;
- center_x = true;
- center_y = true;
- center_z = true;
-
- clip = false;
- clip_floor = 0;
- clip_axis = Vector3::AXIS_Z;
- clip_above = true;
- cell_scale = 1.0;
-
- navigation = nullptr;
set_notify_transform(true);
- recreating_octants = false;
}
GridMap::~GridMap() {
diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h
index ca7429ea26..4c04d492f7 100644
--- a/modules/gridmap/grid_map.h
+++ b/modules/gridmap/grid_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,6 @@
#ifndef GRID_MAP_H
#define GRID_MAP_H
-#include "scene/3d/navigation_3d.h"
#include "scene/3d/node_3d.h"
#include "scene/resources/mesh_library.h"
#include "scene/resources/multimesh.h"
@@ -53,7 +52,7 @@ class GridMap : public Node3D {
int16_t y;
int16_t z;
};
- uint64_t key;
+ uint64_t key = 0;
_FORCE_INLINE_ bool operator<(const IndexKey &p_key) const {
return key < p_key.key;
@@ -68,7 +67,7 @@ class GridMap : public Node3D {
y = (int16_t)p_vector.y;
z = (int16_t)p_vector.z;
}
- IndexKey() { key = 0; }
+ IndexKey() {}
};
/**
@@ -80,13 +79,7 @@ class GridMap : public Node3D {
unsigned int rot : 5;
unsigned int layer : 8;
};
- uint32_t cell;
-
- Cell() {
- item = 0;
- rot = 0;
- layer = 0;
- }
+ uint32_t cell = 0;
};
/**
@@ -103,7 +96,7 @@ class GridMap : public Node3D {
RID instance;
RID multimesh;
struct Item {
- int index;
+ int index = 0;
Transform transform;
IndexKey key;
};
@@ -116,7 +109,7 @@ class GridMap : public Node3D {
RID collision_debug;
RID collision_debug_instance;
- bool dirty;
+ bool dirty = false;
RID static_body;
Map<IndexKey, NavMesh> navmesh_ids;
};
@@ -129,35 +122,38 @@ class GridMap : public Node3D {
int16_t empty;
};
- uint64_t key;
+ uint64_t key = 0;
_FORCE_INLINE_ bool operator<(const OctantKey &p_key) const {
return key < p_key.key;
}
//OctantKey(const IndexKey& p_k, int p_item) { indexkey=p_k.key; item=p_item; }
- OctantKey() { key = 0; }
+ OctantKey() {}
};
- uint32_t collision_layer;
- uint32_t collision_mask;
+ uint32_t collision_layer = 1;
+ uint32_t collision_mask = 1;
+ bool bake_navigation = false;
+ uint32_t navigation_layers = 1;
Transform last_transform;
- bool _in_tree;
- Vector3 cell_size;
- int octant_size;
- bool center_x, center_y, center_z;
- float cell_scale;
- Navigation3D *navigation;
+ bool _in_tree = false;
+ Vector3 cell_size = Vector3(2, 2, 2);
+ int octant_size = 8;
+ bool center_x = true;
+ bool center_y = true;
+ bool center_z = true;
+ float cell_scale = 1.0;
- bool clip;
- bool clip_above;
- int clip_floor;
+ bool clip = false;
+ bool clip_above = true;
+ int clip_floor = 0;
- bool recreating_octants;
+ bool recreating_octants = false;
- Vector3::Axis clip_axis;
+ Vector3::Axis clip_axis = Vector3::AXIS_Z;
Ref<MeshLibrary> mesh_library;
@@ -167,10 +163,10 @@ class GridMap : public Node3D {
void _recreate_octant_data();
struct BakeLight {
- RS::LightType type;
+ RS::LightType type = RS::LightType::LIGHT_DIRECTIONAL;
Vector3 pos;
Vector3 dir;
- float param[RS::LIGHT_PARAM_MAX];
+ float param[RS::LIGHT_PARAM_MAX] = {};
};
_FORCE_INLINE_ Vector3 _octant_get_offset(const OctantKey &p_key) const {
@@ -183,7 +179,7 @@ class GridMap : public Node3D {
bool _octant_update(const OctantKey &p_key);
void _octant_clean_up(const OctantKey &p_key);
void _octant_transform(const OctantKey &p_key);
- bool awaiting_update;
+ bool awaiting_update = false;
void _queue_octants_dirty();
void _update_octants_callback();
@@ -227,6 +223,12 @@ public:
void set_collision_mask_bit(int p_bit, bool p_value);
bool get_collision_mask_bit(int p_bit) const;
+ void set_bake_navigation(bool p_bake_navigation);
+ bool is_baking_navigation();
+
+ void set_navigation_layers(uint32_t p_layers);
+ uint32_t get_navigation_layers();
+
void set_mesh_library(const Ref<MeshLibrary> &p_mesh_library);
Ref<MeshLibrary> get_mesh_library() const;
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index d4fbecd60f..da9cdb9bc5 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -724,7 +724,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
return true;
} else {
selected_palette = -1;
- mesh_library_palette->unselect_all();
+ mesh_library_palette->deselect_all();
update_palette();
_update_cursor_instance();
return true;
@@ -769,7 +769,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
struct _CGMEItemSort {
String name;
- int id;
+ int id = 0;
_FORCE_INLINE_ bool operator<(const _CGMEItemSort &r_it) const { return name < r_it.name; }
};
@@ -1151,7 +1151,6 @@ void GridMapEditor::_bind_methods() {
}
GridMapEditor::GridMapEditor(EditorNode *p_editor) {
- input_action = INPUT_NONE;
editor = p_editor;
undo_redo = p_editor->get_undo_redo();
@@ -1173,7 +1172,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
floor->set_min(-32767);
floor->set_max(32767);
floor->set_step(1);
- floor->get_line_edit()->add_theme_constant_override("minimum_spaces", 16);
+ floor->get_line_edit()->add_theme_constant_override("minimum_character_width", 16);
spatial_editor_hb->add_child(floor);
floor->connect("value_changed", callable_mp(this, &GridMapEditor::_floor_changed));
@@ -1234,7 +1233,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
settings_pick_distance->set_value(EDITOR_DEF("editors/grid_map/pick_distance", 5000.0));
settings_vbc->add_margin_child(TTR("Pick Distance:"), settings_pick_distance);
- clip_mode = CLIP_DISABLED;
options->get_popup()->connect("id_pressed", callable_mp(this, &GridMapEditor::_menu_option));
HBoxContainer *hb = memnew(HBoxContainer);
@@ -1275,8 +1273,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
EDITOR_DEF("editors/grid_map/preview_size", 64);
- display_mode = DISPLAY_THUMBNAIL;
-
mesh_library_palette = memnew(ItemList);
add_child(mesh_library_palette);
mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1296,11 +1292,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
edit_floor[1] = -1;
edit_floor[2] = -1;
- cursor_visible = false;
- selected_palette = -1;
- lock_view = false;
- cursor_rot = 0;
-
selection_mesh = RenderingServer::get_singleton()->mesh_create();
paste_mesh = RenderingServer::get_singleton()->mesh_create();
@@ -1418,8 +1409,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
}
_set_selection(false);
- updating = false;
- accumulated_floor_delta = 0.0;
indicator_mat.instance();
indicator_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index 69c8d999fd..6c7f0bedf6 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,11 +65,11 @@ class GridMapEditor : public VBoxContainer {
};
UndoRedo *undo_redo;
- InputAction input_action;
+ InputAction input_action = INPUT_NONE;
Panel *panel;
MenuButton *options;
SpinBox *floor;
- double accumulated_floor_delta;
+ double accumulated_floor_delta = 0.0;
Button *mode_thumbnail;
Button *mode_list;
LineEdit *search_box;
@@ -82,19 +82,19 @@ class GridMapEditor : public VBoxContainer {
struct SetItem {
Vector3i position;
- int new_value;
- int new_orientation;
- int old_value;
- int old_orientation;
+ int new_value = 0;
+ int new_orientation = 0;
+ int old_value = 0;
+ int old_orientation = 0;
};
List<SetItem> set_items;
GridMap *node = nullptr;
MeshLibrary *last_mesh_library;
- ClipMode clip_mode;
+ ClipMode clip_mode = CLIP_DISABLED;
- bool lock_view;
+ bool lock_view = false;
Transform grid_xform;
Transform edit_grid_xform;
Vector3::Axis edit_axis;
@@ -112,9 +112,9 @@ class GridMapEditor : public VBoxContainer {
RID paste_instance;
struct ClipboardItem {
- int cell_item;
+ int cell_item = 0;
Vector3 grid_offset;
- int orientation;
+ int orientation = 0;
RID instance;
};
@@ -125,14 +125,14 @@ class GridMapEditor : public VBoxContainer {
Ref<StandardMaterial3D> outer_mat;
Ref<StandardMaterial3D> selection_floor_mat;
- bool updating;
+ bool updating = false;
struct Selection {
Vector3 click;
Vector3 current;
Vector3 begin;
Vector3 end;
- bool active;
+ bool active = false;
} selection;
Selection last_selection;
@@ -141,18 +141,18 @@ class GridMapEditor : public VBoxContainer {
Vector3 current;
Vector3 begin;
Vector3 end;
- int orientation;
+ int orientation = 0;
};
PasteIndicator paste_indicator;
- bool cursor_visible;
+ bool cursor_visible = false;
Transform cursor_transform;
Vector3 cursor_origin;
- int display_mode;
- int selected_palette;
- int cursor_rot;
+ int display_mode = DISPLAY_THUMBNAIL;
+ int selected_palette = -1;
+ int cursor_rot = 0;
enum Menu {
MENU_OPTION_NEXT_LEVEL,
diff --git a/modules/gridmap/register_types.cpp b/modules/gridmap/register_types.cpp
index ab384fa942..5680664213 100644
--- a/modules/gridmap/register_types.cpp
+++ b/modules/gridmap/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gridmap/register_types.h b/modules/gridmap/register_types.h
index c0e3c39ca8..b977f4c5da 100644
--- a/modules/gridmap/register_types.h
+++ b/modules/gridmap/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index af3741bae9..9d6a399eff 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index ef8e116616..33fcdd1245 100644
--- a/modules/hdr/image_loader_hdr.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/hdr/register_types.cpp b/modules/hdr/register_types.cpp
index e749928f60..5a4a1993e0 100644
--- a/modules/hdr/register_types.cpp
+++ b/modules/hdr/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/hdr/register_types.h b/modules/hdr/register_types.h
index 02441516ec..c85bc84dce 100644
--- a/modules/hdr/register_types.h
+++ b/modules/hdr/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/icloud/SCsub b/modules/icloud/SCsub
deleted file mode 100644
index 805a484600..0000000000
--- a/modules/icloud/SCsub
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-Import("env_modules")
-
-env_icloud = env_modules.Clone()
-
-# (iOS) Enable module support
-env_icloud.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
-
-# (iOS) Build as separate static library
-modules_sources = []
-env_icloud.add_source_files(modules_sources, "*.cpp")
-env_icloud.add_source_files(modules_sources, "*.mm")
-mod_lib = env_modules.add_library("#bin/libgodot_icloud_module" + env["LIBSUFFIX"], modules_sources)
diff --git a/modules/icloud/config.py b/modules/icloud/config.py
deleted file mode 100644
index e68603fc93..0000000000
--- a/modules/icloud/config.py
+++ /dev/null
@@ -1,6 +0,0 @@
-def can_build(env, platform):
- return platform == "iphone"
-
-
-def configure(env):
- pass
diff --git a/modules/icloud/icloud.gdip b/modules/icloud/icloud.gdip
deleted file mode 100644
index 9f81be8a34..0000000000
--- a/modules/icloud/icloud.gdip
+++ /dev/null
@@ -1,17 +0,0 @@
-[config]
-name="iCloud"
-binary="icloud_lib.a"
-
-initialization="register_icloud_types"
-deinitialization="unregister_icloud_types"
-
-[dependencies]
-linked=[]
-embedded=[]
-system=[]
-
-capabilities=[]
-
-files=[]
-
-[plist]
diff --git a/modules/icloud/icloud.mm b/modules/icloud/icloud.mm
deleted file mode 100644
index 8a8ddbefe9..0000000000
--- a/modules/icloud/icloud.mm
+++ /dev/null
@@ -1,345 +0,0 @@
-/*************************************************************************/
-/* icloud.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "icloud.h"
-
-#import "platform/iphone/app_delegate.h"
-
-#import <Foundation/Foundation.h>
-
-ICloud *ICloud::instance = NULL;
-
-void ICloud::_bind_methods() {
- ClassDB::bind_method(D_METHOD("remove_key"), &ICloud::remove_key);
-
- ClassDB::bind_method(D_METHOD("set_key_values"), &ICloud::set_key_values);
- ClassDB::bind_method(D_METHOD("get_key_value"), &ICloud::get_key_value);
-
- ClassDB::bind_method(D_METHOD("synchronize_key_values"), &ICloud::synchronize_key_values);
- ClassDB::bind_method(D_METHOD("get_all_key_values"), &ICloud::get_all_key_values);
-
- ClassDB::bind_method(D_METHOD("get_pending_event_count"), &ICloud::get_pending_event_count);
- ClassDB::bind_method(D_METHOD("pop_pending_event"), &ICloud::pop_pending_event);
-};
-
-int ICloud::get_pending_event_count() {
- return pending_events.size();
-};
-
-Variant ICloud::pop_pending_event() {
- Variant front = pending_events.front()->get();
- pending_events.pop_front();
-
- return front;
-};
-
-ICloud *ICloud::get_singleton() {
- return instance;
-};
-
-//convert from apple's abstract type to godot's abstract type....
-Variant nsobject_to_variant(NSObject *object) {
- if ([object isKindOfClass:[NSString class]]) {
- const char *str = [(NSString *)object UTF8String];
- return String::utf8(str != NULL ? str : "");
- } else if ([object isKindOfClass:[NSData class]]) {
- PackedByteArray ret;
- NSData *data = (NSData *)object;
- if ([data length] > 0) {
- ret.resize([data length]);
- {
- // PackedByteArray::Write w = ret.write();
- copymem((void *)ret.ptr(), [data bytes], [data length]);
- }
- }
- return ret;
- } else if ([object isKindOfClass:[NSArray class]]) {
- Array result;
- NSArray *array = (NSArray *)object;
- for (NSUInteger i = 0; i < [array count]; ++i) {
- NSObject *value = [array objectAtIndex:i];
- result.push_back(nsobject_to_variant(value));
- }
- return result;
- } else if ([object isKindOfClass:[NSDictionary class]]) {
- Dictionary result;
- NSDictionary *dic = (NSDictionary *)object;
-
- NSArray *keys = [dic allKeys];
- int count = [keys count];
- for (int i = 0; i < count; ++i) {
- NSObject *k = [keys objectAtIndex:i];
- NSObject *v = [dic objectForKey:k];
-
- result[nsobject_to_variant(k)] = nsobject_to_variant(v);
- }
- return result;
- } else if ([object isKindOfClass:[NSNumber class]]) {
- //Every type except numbers can reliably identify its type. The following is comparing to the *internal* representation, which isn't guaranteed to match the type that was used to create it, and is not advised, particularly when dealing with potential platform differences (ie, 32/64 bit)
- //To avoid errors, we'll cast as broadly as possible, and only return int or float.
- //bool, char, int, uint, longlong -> int
- //float, double -> float
- NSNumber *num = (NSNumber *)object;
- if (strcmp([num objCType], @encode(BOOL)) == 0) {
- return Variant((int)[num boolValue]);
- } else if (strcmp([num objCType], @encode(char)) == 0) {
- return Variant((int)[num charValue]);
- } else if (strcmp([num objCType], @encode(int)) == 0) {
- return Variant([num intValue]);
- } else if (strcmp([num objCType], @encode(unsigned int)) == 0) {
- return Variant((int)[num unsignedIntValue]);
- } else if (strcmp([num objCType], @encode(long long)) == 0) {
- return Variant((int)[num longValue]);
- } else if (strcmp([num objCType], @encode(float)) == 0) {
- return Variant([num floatValue]);
- } else if (strcmp([num objCType], @encode(double)) == 0) {
- return Variant((float)[num doubleValue]);
- } else {
- return Variant();
- }
- } else if ([object isKindOfClass:[NSDate class]]) {
- //this is a type that icloud supports...but how did you submit it in the first place?
- //I guess this is a type that *might* show up, if you were, say, trying to make your game
- //compatible with existing cloud data written by another engine's version of your game
- WARN_PRINT("NSDate unsupported, returning null Variant");
- return Variant();
- } else if ([object isKindOfClass:[NSNull class]] or object == nil) {
- return Variant();
- } else {
- WARN_PRINT("Trying to convert unknown NSObject type to Variant");
- return Variant();
- }
-}
-
-NSObject *variant_to_nsobject(Variant v) {
- if (v.get_type() == Variant::STRING) {
- return [[NSString alloc] initWithUTF8String:((String)v).utf8().get_data()];
- } else if (v.get_type() == Variant::FLOAT) {
- return [NSNumber numberWithDouble:(double)v];
- } else if (v.get_type() == Variant::INT) {
- return [NSNumber numberWithLongLong:(long)(int)v];
- } else if (v.get_type() == Variant::BOOL) {
- return [NSNumber numberWithBool:BOOL((bool)v)];
- } else if (v.get_type() == Variant::DICTIONARY) {
- NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
- Dictionary dic = v;
- Array keys = dic.keys();
- for (int i = 0; i < keys.size(); ++i) {
- NSString *key = [[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()];
- NSObject *value = variant_to_nsobject(dic[keys[i]]);
-
- if (key == NULL || value == NULL) {
- return NULL;
- }
-
- [result setObject:value forKey:key];
- }
- return result;
- } else if (v.get_type() == Variant::ARRAY) {
- NSMutableArray *result = [[NSMutableArray alloc] init];
- Array arr = v;
- for (int i = 0; i < arr.size(); ++i) {
- NSObject *value = variant_to_nsobject(arr[i]);
- if (value == NULL) {
- //trying to add something unsupported to the array. cancel the whole array
- return NULL;
- }
- [result addObject:value];
- }
- return result;
- } else if (v.get_type() == Variant::PACKED_BYTE_ARRAY) {
- PackedByteArray arr = v;
- // PackedByteArray::Read r = arr.read();
- NSData *result = [NSData dataWithBytes:arr.ptr() length:arr.size()];
- return result;
- }
- WARN_PRINT(String("Could not add unsupported type to iCloud: '" + Variant::get_type_name(v.get_type()) + "'").utf8().get_data());
- return NULL;
-}
-
-Error ICloud::remove_key(String p_param) {
- NSString *key = [[NSString alloc] initWithUTF8String:p_param.utf8().get_data()];
-
- NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
-
- if (![[store dictionaryRepresentation] objectForKey:key]) {
- return ERR_INVALID_PARAMETER;
- }
-
- [store removeObjectForKey:key];
- return OK;
-}
-
-//return an array of the keys that could not be set
-Array ICloud::set_key_values(Dictionary p_params) {
- Array keys = p_params.keys();
-
- Array error_keys;
-
- for (int i = 0; i < keys.size(); ++i) {
- String variant_key = keys[i];
- Variant variant_value = p_params[variant_key];
-
- NSString *key = [[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()];
- if (key == NULL) {
- error_keys.push_back(variant_key);
- continue;
- }
-
- NSObject *value = variant_to_nsobject(variant_value);
-
- if (value == NULL) {
- error_keys.push_back(variant_key);
- continue;
- }
-
- NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
- [store setObject:value forKey:key];
- }
-
- return error_keys;
-}
-
-Variant ICloud::get_key_value(String p_param) {
- NSString *key = [[NSString alloc] initWithUTF8String:p_param.utf8().get_data()];
- NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
-
- if (![[store dictionaryRepresentation] objectForKey:key]) {
- return Variant();
- }
-
- Variant result = nsobject_to_variant([[store dictionaryRepresentation] objectForKey:key]);
-
- return result;
-}
-
-Variant ICloud::get_all_key_values() {
- Dictionary result;
-
- NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
- NSDictionary *store_dictionary = [store dictionaryRepresentation];
-
- NSArray *keys = [store_dictionary allKeys];
- int count = [keys count];
- for (int i = 0; i < count; ++i) {
- NSString *k = [keys objectAtIndex:i];
- NSObject *v = [store_dictionary objectForKey:k];
-
- const char *str = [k UTF8String];
- if (str != NULL) {
- result[String::utf8(str)] = nsobject_to_variant(v);
- }
- }
-
- return result;
-}
-
-Error ICloud::synchronize_key_values() {
- NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
- BOOL result = [store synchronize];
- if (result == YES) {
- return OK;
- } else {
- return FAILED;
- }
-}
-
-/*
-Error ICloud::initial_sync() {
- //you sometimes have to write something to the store to get it to download new data. go apple!
- NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
- if ([store boolForKey:@"isb"])
- {
- [store setBool:NO forKey:@"isb"];
- }
- else
- {
- [store setBool:YES forKey:@"isb"];
- }
- return synchronize();
-}
-
-*/
-ICloud::ICloud() {
- ERR_FAIL_COND(instance != NULL);
- instance = this;
- //connected = false;
-
- [[NSNotificationCenter defaultCenter]
- addObserverForName:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
- object:[NSUbiquitousKeyValueStore defaultStore]
- queue:nil
- usingBlock:^(NSNotification *notification) {
- NSDictionary *userInfo = [notification userInfo];
- NSInteger change = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] integerValue];
-
- Dictionary ret;
- ret["type"] = "key_value_changed";
-
- //PackedStringArray result_keys;
- //Array result_values;
- Dictionary keyValues;
- String reason = "";
-
- if (change == NSUbiquitousKeyValueStoreServerChange) {
- reason = "server";
- } else if (change == NSUbiquitousKeyValueStoreInitialSyncChange) {
- reason = "initial_sync";
- } else if (change == NSUbiquitousKeyValueStoreQuotaViolationChange) {
- reason = "quota_violation";
- } else if (change == NSUbiquitousKeyValueStoreAccountChange) {
- reason = "account";
- }
-
- ret["reason"] = reason;
-
- NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
-
- NSArray *keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
- for (NSString *key in keys) {
- const char *str = [key UTF8String];
- if (str == NULL) {
- continue;
- }
-
- NSObject *object = [store objectForKey:key];
-
- //figure out what kind of object it is
- Variant value = nsobject_to_variant(object);
-
- keyValues[String::utf8(str)] = value;
- }
-
- ret["changed_values"] = keyValues;
- pending_events.push_back(ret);
- }];
-}
-
-ICloud::~ICloud() {}
diff --git a/modules/icloud/icloud_module.h b/modules/icloud/icloud_module.h
deleted file mode 100644
index 7fd057525e..0000000000
--- a/modules/icloud/icloud_module.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*************************************************************************/
-/* icloud_module.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-void register_icloud_types();
-void unregister_icloud_types();
diff --git a/modules/inappstore/SCsub b/modules/inappstore/SCsub
deleted file mode 100644
index cee6a256d5..0000000000
--- a/modules/inappstore/SCsub
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-Import("env_modules")
-
-env_inappstore = env_modules.Clone()
-
-# (iOS) Enable module support
-env_inappstore.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
-
-# (iOS) Build as separate static library
-modules_sources = []
-env_inappstore.add_source_files(modules_sources, "*.cpp")
-env_inappstore.add_source_files(modules_sources, "*.mm")
-mod_lib = env_modules.add_library("#bin/libgodot_inappstore_module" + env["LIBSUFFIX"], modules_sources)
diff --git a/modules/inappstore/config.py b/modules/inappstore/config.py
deleted file mode 100644
index e68603fc93..0000000000
--- a/modules/inappstore/config.py
+++ /dev/null
@@ -1,6 +0,0 @@
-def can_build(env, platform):
- return platform == "iphone"
-
-
-def configure(env):
- pass
diff --git a/modules/inappstore/in_app_store.h b/modules/inappstore/in_app_store.h
deleted file mode 100644
index c8e5d17cec..0000000000
--- a/modules/inappstore/in_app_store.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*************************************************************************/
-/* in_app_store.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef IN_APP_STORE_H
-#define IN_APP_STORE_H
-
-#include "core/object/class_db.h"
-
-#ifdef __OBJC__
-@class GodotProductsDelegate;
-@class GodotTransactionsObserver;
-
-typedef GodotProductsDelegate InAppStoreProductDelegate;
-typedef GodotTransactionsObserver InAppStoreTransactionObserver;
-#else
-typedef void InAppStoreProductDelegate;
-typedef void InAppStoreTransactionObserver;
-#endif
-
-class InAppStore : public Object {
- GDCLASS(InAppStore, Object);
-
- static InAppStore *instance;
- static void _bind_methods();
-
- List<Variant> pending_events;
-
- InAppStoreProductDelegate *products_request_delegate;
- InAppStoreTransactionObserver *transactions_observer;
-
-public:
- Error request_product_info(Dictionary p_params);
- Error restore_purchases();
- Error purchase(Dictionary p_params);
-
- int get_pending_event_count();
- Variant pop_pending_event();
- void finish_transaction(String product_id);
- void set_auto_finish_transaction(bool b);
-
- void _post_event(Variant p_event);
- void _record_purchase(String product_id);
-
- static InAppStore *get_singleton();
-
- InAppStore();
- ~InAppStore();
-};
-
-#endif
diff --git a/modules/inappstore/in_app_store.mm b/modules/inappstore/in_app_store.mm
deleted file mode 100644
index 62977318c1..0000000000
--- a/modules/inappstore/in_app_store.mm
+++ /dev/null
@@ -1,411 +0,0 @@
-/*************************************************************************/
-/* in_app_store.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "in_app_store.h"
-
-#import <Foundation/Foundation.h>
-#import <StoreKit/StoreKit.h>
-
-InAppStore *InAppStore::instance = NULL;
-
-@interface SKProduct (LocalizedPrice)
-
-@property(nonatomic, readonly) NSString *localizedPrice;
-
-@end
-
-//----------------------------------//
-// SKProduct extension
-//----------------------------------//
-@implementation SKProduct (LocalizedPrice)
-
-- (NSString *)localizedPrice {
- NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
- [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
- [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
- [numberFormatter setLocale:self.priceLocale];
- NSString *formattedString = [numberFormatter stringFromNumber:self.price];
- return formattedString;
-}
-
-@end
-
-@interface GodotProductsDelegate : NSObject <SKProductsRequestDelegate>
-
-@property(nonatomic, strong) NSMutableArray *loadedProducts;
-@property(nonatomic, strong) NSMutableArray *pendingRequests;
-
-- (void)performRequestWithProductIDs:(NSSet *)productIDs;
-- (Error)purchaseProductWithProductID:(NSString *)productID;
-- (void)reset;
-
-@end
-
-@implementation GodotProductsDelegate
-
-- (instancetype)init {
- self = [super init];
-
- if (self) {
- [self godot_commonInit];
- }
-
- return self;
-}
-
-- (void)godot_commonInit {
- self.loadedProducts = [NSMutableArray new];
- self.pendingRequests = [NSMutableArray new];
-}
-
-- (void)performRequestWithProductIDs:(NSSet *)productIDs {
- SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:productIDs];
-
- request.delegate = self;
- [self.pendingRequests addObject:request];
- [request start];
-}
-
-- (Error)purchaseProductWithProductID:(NSString *)productID {
- SKProduct *product = nil;
-
- NSLog(@"searching for product!");
-
- if (self.loadedProducts) {
- for (SKProduct *storedProduct in self.loadedProducts) {
- if ([storedProduct.productIdentifier isEqualToString:productID]) {
- product = storedProduct;
- break;
- }
- }
- }
-
- if (!product) {
- return ERR_INVALID_PARAMETER;
- }
-
- NSLog(@"product found!");
-
- SKPayment *payment = [SKPayment paymentWithProduct:product];
- [[SKPaymentQueue defaultQueue] addPayment:payment];
-
- NSLog(@"purchase sent!");
-
- return OK;
-}
-
-- (void)reset {
- [self.loadedProducts removeAllObjects];
- [self.pendingRequests removeAllObjects];
-}
-
-- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
- [self.pendingRequests removeObject:request];
-
- Dictionary ret;
- ret["type"] = "product_info";
- ret["result"] = "error";
- ret["error"] = String::utf8([error.localizedDescription UTF8String]);
-
- InAppStore::get_singleton()->_post_event(ret);
-}
-
-- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
- [self.pendingRequests removeObject:request];
-
- NSArray *products = response.products;
- [self.loadedProducts addObjectsFromArray:products];
-
- Dictionary ret;
- ret["type"] = "product_info";
- ret["result"] = "ok";
- PackedStringArray titles;
- PackedStringArray descriptions;
- PackedFloat32Array prices;
- PackedStringArray ids;
- PackedStringArray localized_prices;
- PackedStringArray currency_codes;
-
- for (NSUInteger i = 0; i < [products count]; i++) {
- SKProduct *product = [products objectAtIndex:i];
-
- const char *str = [product.localizedTitle UTF8String];
- titles.push_back(String::utf8(str != NULL ? str : ""));
-
- str = [product.localizedDescription UTF8String];
- descriptions.push_back(String::utf8(str != NULL ? str : ""));
- prices.push_back([product.price doubleValue]);
- ids.push_back(String::utf8([product.productIdentifier UTF8String]));
- localized_prices.push_back(String::utf8([product.localizedPrice UTF8String]));
- currency_codes.push_back(String::utf8([[[product priceLocale] objectForKey:NSLocaleCurrencyCode] UTF8String]));
- }
-
- ret["titles"] = titles;
- ret["descriptions"] = descriptions;
- ret["prices"] = prices;
- ret["ids"] = ids;
- ret["localized_prices"] = localized_prices;
- ret["currency_codes"] = currency_codes;
-
- PackedStringArray invalid_ids;
-
- for (NSString *ipid in response.invalidProductIdentifiers) {
- invalid_ids.push_back(String::utf8([ipid UTF8String]));
- }
-
- ret["invalid_ids"] = invalid_ids;
-
- InAppStore::get_singleton()->_post_event(ret);
-}
-
-@end
-
-@interface GodotTransactionsObserver : NSObject <SKPaymentTransactionObserver>
-
-@property(nonatomic, assign) BOOL shouldAutoFinishTransactions;
-@property(nonatomic, strong) NSMutableDictionary *pendingTransactions;
-
-- (void)finishTransactionWithProductID:(NSString *)productID;
-- (void)reset;
-
-@end
-
-@implementation GodotTransactionsObserver
-
-- (instancetype)init {
- self = [super init];
-
- if (self) {
- [self godot_commonInit];
- }
-
- return self;
-}
-
-- (void)godot_commonInit {
- self.pendingTransactions = [NSMutableDictionary new];
-}
-
-- (void)finishTransactionWithProductID:(NSString *)productID {
- SKPaymentTransaction *transaction = self.pendingTransactions[productID];
-
- if (transaction) {
- [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- }
-
- self.pendingTransactions[productID] = nil;
-}
-
-- (void)reset {
- [self.pendingTransactions removeAllObjects];
-}
-
-- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
- printf("transactions updated!\n");
- for (SKPaymentTransaction *transaction in transactions) {
- switch (transaction.transactionState) {
- case SKPaymentTransactionStatePurchased: {
- printf("status purchased!\n");
- String pid = String::utf8([transaction.payment.productIdentifier UTF8String]);
- String transactionId = String::utf8([transaction.transactionIdentifier UTF8String]);
- InAppStore::get_singleton()->_record_purchase(pid);
- Dictionary ret;
- ret["type"] = "purchase";
- ret["result"] = "ok";
- ret["product_id"] = pid;
- ret["transaction_id"] = transactionId;
-
- NSData *receipt = nil;
- int sdk_version = [[[UIDevice currentDevice] systemVersion] intValue];
-
- NSBundle *bundle = [NSBundle mainBundle];
- // Get the transaction receipt file path location in the app bundle.
- NSURL *receiptFileURL = [bundle appStoreReceiptURL];
-
- // Read in the contents of the transaction file.
- receipt = [NSData dataWithContentsOfURL:receiptFileURL];
-
- NSString *receipt_to_send = nil;
-
- if (receipt != nil) {
- receipt_to_send = [receipt base64EncodedStringWithOptions:0];
- }
- Dictionary receipt_ret;
- receipt_ret["receipt"] = String::utf8(receipt_to_send != nil ? [receipt_to_send UTF8String] : "");
- receipt_ret["sdk"] = sdk_version;
- ret["receipt"] = receipt_ret;
-
- InAppStore::get_singleton()->_post_event(ret);
-
- if (self.shouldAutoFinishTransactions) {
- [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- } else {
- self.pendingTransactions[transaction.payment.productIdentifier] = transaction;
- }
-
- } break;
- case SKPaymentTransactionStateFailed: {
- printf("status transaction failed!\n");
- String pid = String::utf8([transaction.payment.productIdentifier UTF8String]);
- Dictionary ret;
- ret["type"] = "purchase";
- ret["result"] = "error";
- ret["product_id"] = pid;
- ret["error"] = String::utf8([transaction.error.localizedDescription UTF8String]);
- InAppStore::get_singleton()->_post_event(ret);
- [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- } break;
- case SKPaymentTransactionStateRestored: {
- printf("status transaction restored!\n");
- String pid = String::utf8([transaction.originalTransaction.payment.productIdentifier UTF8String]);
- InAppStore::get_singleton()->_record_purchase(pid);
- Dictionary ret;
- ret["type"] = "restore";
- ret["result"] = "ok";
- ret["product_id"] = pid;
- InAppStore::get_singleton()->_post_event(ret);
- [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- } break;
- default: {
- printf("status default %i!\n", (int)transaction.transactionState);
- } break;
- }
- }
-}
-
-@end
-
-void InAppStore::_bind_methods() {
- ClassDB::bind_method(D_METHOD("request_product_info"), &InAppStore::request_product_info);
- ClassDB::bind_method(D_METHOD("restore_purchases"), &InAppStore::restore_purchases);
- ClassDB::bind_method(D_METHOD("purchase"), &InAppStore::purchase);
-
- ClassDB::bind_method(D_METHOD("get_pending_event_count"), &InAppStore::get_pending_event_count);
- ClassDB::bind_method(D_METHOD("pop_pending_event"), &InAppStore::pop_pending_event);
- ClassDB::bind_method(D_METHOD("finish_transaction"), &InAppStore::finish_transaction);
- ClassDB::bind_method(D_METHOD("set_auto_finish_transaction"), &InAppStore::set_auto_finish_transaction);
-}
-
-Error InAppStore::request_product_info(Dictionary p_params) {
- ERR_FAIL_COND_V(!p_params.has("product_ids"), ERR_INVALID_PARAMETER);
-
- PackedStringArray pids = p_params["product_ids"];
- printf("************ request product info! %i\n", pids.size());
-
- NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:pids.size()];
- for (int i = 0; i < pids.size(); i++) {
- printf("******** adding %s to product list\n", pids[i].utf8().get_data());
- NSString *pid = [[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()];
- [array addObject:pid];
- };
-
- NSSet *products = [[NSSet alloc] initWithArray:array];
-
- [products_request_delegate performRequestWithProductIDs:products];
-
- return OK;
-}
-
-Error InAppStore::restore_purchases() {
- printf("restoring purchases!\n");
- [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
-
- return OK;
-}
-
-Error InAppStore::purchase(Dictionary p_params) {
- ERR_FAIL_COND_V(![SKPaymentQueue canMakePayments], ERR_UNAVAILABLE);
- if (![SKPaymentQueue canMakePayments]) {
- return ERR_UNAVAILABLE;
- }
-
- printf("purchasing!\n");
- Dictionary params = p_params;
- ERR_FAIL_COND_V(!params.has("product_id"), ERR_INVALID_PARAMETER);
-
- NSString *pid = [[NSString alloc] initWithUTF8String:String(params["product_id"]).utf8().get_data()];
-
- return [products_request_delegate purchaseProductWithProductID:pid];
-}
-
-int InAppStore::get_pending_event_count() {
- return pending_events.size();
-}
-
-Variant InAppStore::pop_pending_event() {
- Variant front = pending_events.front()->get();
- pending_events.pop_front();
-
- return front;
-}
-
-void InAppStore::_post_event(Variant p_event) {
- pending_events.push_back(p_event);
-}
-
-void InAppStore::_record_purchase(String product_id) {
- String skey = "purchased/" + product_id;
- NSString *key = [[NSString alloc] initWithUTF8String:skey.utf8().get_data()];
- [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
- [[NSUserDefaults standardUserDefaults] synchronize];
-}
-
-InAppStore *InAppStore::get_singleton() {
- return instance;
-}
-
-InAppStore::InAppStore() {
- ERR_FAIL_COND(instance != NULL);
- instance = this;
-
- products_request_delegate = [[GodotProductsDelegate alloc] init];
- transactions_observer = [[GodotTransactionsObserver alloc] init];
-
- [[SKPaymentQueue defaultQueue] addTransactionObserver:transactions_observer];
-}
-
-void InAppStore::finish_transaction(String product_id) {
- NSString *prod_id = [NSString stringWithCString:product_id.utf8().get_data() encoding:NSUTF8StringEncoding];
-
- [transactions_observer finishTransactionWithProductID:prod_id];
-}
-
-void InAppStore::set_auto_finish_transaction(bool b) {
- transactions_observer.shouldAutoFinishTransactions = b;
-}
-
-InAppStore::~InAppStore() {
- [products_request_delegate reset];
- [transactions_observer reset];
-
- products_request_delegate = nil;
- [[SKPaymentQueue defaultQueue] removeTransactionObserver:transactions_observer];
- transactions_observer = nil;
-}
diff --git a/modules/inappstore/in_app_store_module.cpp b/modules/inappstore/in_app_store_module.cpp
deleted file mode 100644
index 039bdd4f83..0000000000
--- a/modules/inappstore/in_app_store_module.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* in_app_store_module.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "in_app_store_module.h"
-
-#include "core/config/engine.h"
-
-#include "in_app_store.h"
-
-InAppStore *store_kit;
-
-void register_inappstore_types() {
- store_kit = memnew(InAppStore);
- Engine::get_singleton()->add_singleton(Engine::Singleton("InAppStore", store_kit));
-}
-
-void unregister_inappstore_types() {
- if (store_kit) {
- memdelete(store_kit);
- }
-}
diff --git a/modules/inappstore/in_app_store_module.h b/modules/inappstore/in_app_store_module.h
deleted file mode 100644
index 44673e58bc..0000000000
--- a/modules/inappstore/in_app_store_module.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*************************************************************************/
-/* in_app_store_module.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-void register_inappstore_types();
-void unregister_inappstore_types();
diff --git a/modules/inappstore/inappstore.gdip b/modules/inappstore/inappstore.gdip
deleted file mode 100644
index 7a5efb8ad3..0000000000
--- a/modules/inappstore/inappstore.gdip
+++ /dev/null
@@ -1,17 +0,0 @@
-[config]
-name="InAppStore"
-binary="inappstore_lib.a"
-
-initialization="register_inappstore_types"
-deinitialization="unregister_inappstore_types"
-
-[dependencies]
-linked=[]
-embedded=[]
-system=["StoreKit.framework"]
-
-capabilities=[]
-
-files=[]
-
-[plist]
diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp
index e5f041c618..7daf6a3a57 100644
--- a/modules/jpg/image_loader_jpegd.cpp
+++ b/modules/jpg/image_loader_jpegd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h
index 9aebaad9e3..be265b280c 100644
--- a/modules/jpg/image_loader_jpegd.h
+++ b/modules/jpg/image_loader_jpegd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/jpg/register_types.cpp b/modules/jpg/register_types.cpp
index b31746f769..a6ae96635f 100644
--- a/modules/jpg/register_types.cpp
+++ b/modules/jpg/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/jpg/register_types.h b/modules/jpg/register_types.h
index 52cd378b3a..577e9b06f7 100644
--- a/modules/jpg/register_types.h
+++ b/modules/jpg/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/jsonrpc/jsonrpc.cpp b/modules/jsonrpc/jsonrpc.cpp
index 320da182f8..306c0ff087 100644
--- a/modules/jsonrpc/jsonrpc.cpp
+++ b/modules/jsonrpc/jsonrpc.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -151,7 +151,7 @@ Variant JSONRPC::process_action(const Variant &p_action, bool p_process_arr_elem
}
String JSONRPC::process_string(const String &p_input) {
- if (p_input.empty()) {
+ if (p_input.is_empty()) {
return String();
}
diff --git a/modules/jsonrpc/jsonrpc.h b/modules/jsonrpc/jsonrpc.h
index c2acf84515..9fd016602d 100644
--- a/modules/jsonrpc/jsonrpc.h
+++ b/modules/jsonrpc/jsonrpc.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/jsonrpc/register_types.cpp b/modules/jsonrpc/register_types.cpp
index e6affaee41..d6b565ba84 100644
--- a/modules/jsonrpc/register_types.cpp
+++ b/modules/jsonrpc/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/jsonrpc/register_types.h b/modules/jsonrpc/register_types.h
index 854d73a21f..6a21a12444 100644
--- a/modules/jsonrpc/register_types.h
+++ b/modules/jsonrpc/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
index 66995382e7..61ebabdfb6 100644
--- a/modules/lightmapper_rd/lightmapper_rd.cpp
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,8 +40,8 @@
//#define DEBUG_TEXTURES
void LightmapperRD::add_mesh(const MeshData &p_mesh) {
- ERR_FAIL_COND(p_mesh.albedo_on_uv2.is_null() || p_mesh.albedo_on_uv2->empty());
- ERR_FAIL_COND(p_mesh.emission_on_uv2.is_null() || p_mesh.emission_on_uv2->empty());
+ ERR_FAIL_COND(p_mesh.albedo_on_uv2.is_null() || p_mesh.albedo_on_uv2->is_empty());
+ ERR_FAIL_COND(p_mesh.emission_on_uv2.is_null() || p_mesh.emission_on_uv2->is_empty());
ERR_FAIL_COND(p_mesh.albedo_on_uv2->get_width() != p_mesh.emission_on_uv2->get_width());
ERR_FAIL_COND(p_mesh.albedo_on_uv2->get_height() != p_mesh.emission_on_uv2->get_height());
ERR_FAIL_COND(p_mesh.points.size() == 0);
@@ -93,8 +93,8 @@ void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, con
l.direction[2] = p_direction.z;
l.range = p_range;
l.attenuation = p_attenuation;
- l.spot_angle = Math::deg2rad(p_spot_angle);
- l.spot_attenuation = p_spot_attenuation;
+ l.cos_spot_angle = Math::cos(Math::deg2rad(p_spot_angle));
+ l.inv_spot_attenuation = 1.0f / p_spot_attenuation;
l.color[0] = p_color.r;
l.color[1] = p_color.g;
l.color[2] = p_color.b;
@@ -1225,23 +1225,23 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
switch (p_quality) {
case BAKE_QUALITY_LOW: {
- push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/low_quality_ray_count");
+ push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/low_quality_ray_count");
} break;
case BAKE_QUALITY_MEDIUM: {
- push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/medium_quality_ray_count");
+ push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/medium_quality_ray_count");
} break;
case BAKE_QUALITY_HIGH: {
- push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/high_quality_ray_count");
+ push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/high_quality_ray_count");
} break;
case BAKE_QUALITY_ULTRA: {
- push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/ultra_quality_ray_count");
+ push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/ultra_quality_ray_count");
} break;
}
push_constant.ray_count = CLAMP(push_constant.ray_count, 16, 8192);
- int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/gpu_lightmapper/performance/region_size")));
- int max_rays = GLOBAL_GET("rendering/gpu_lightmapper/performance/max_rays_per_pass");
+ int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size")));
+ int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_pass");
int x_regions = (atlas_size.width - 1) / max_region_size + 1;
int y_regions = (atlas_size.height - 1) / max_region_size + 1;
@@ -1347,23 +1347,23 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
switch (p_quality) {
case BAKE_QUALITY_LOW: {
- push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/low_quality_probe_ray_count");
+ push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/low_quality_probe_ray_count");
} break;
case BAKE_QUALITY_MEDIUM: {
- push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count");
+ push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/medium_quality_probe_ray_count");
} break;
case BAKE_QUALITY_HIGH: {
- push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/high_quality_probe_ray_count");
+ push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/high_quality_probe_ray_count");
} break;
case BAKE_QUALITY_ULTRA: {
- push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count");
+ push_constant.ray_count = GLOBAL_GET("rendering/lightmapping/bake_quality/ultra_quality_probe_ray_count");
} break;
}
push_constant.atlas_size[0] = probe_positions.size();
push_constant.ray_count = CLAMP(push_constant.ray_count, 16, 8192);
- int max_rays = GLOBAL_GET("rendering/gpu_lightmapper/performance/max_rays_per_probe_pass");
+ int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_probe_pass");
int ray_iterations = (push_constant.ray_count - 1) / max_rays + 1;
for (int i = 0; i < ray_iterations; i++) {
@@ -1436,7 +1436,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
dst[j + 3] = src[j + 3];
}
}
- rd->texture_update(light_accum_tex, i, ds, true);
+ rd->texture_update(light_accum_tex, i, ds);
}
}
}
@@ -1537,7 +1537,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
{
//pre copy
for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
- rd->texture_copy(light_accum_tex, light_accum_tex2, Vector3(), Vector3(), Vector3(atlas_size.width, atlas_size.height, 1), 0, 0, i, i, true);
+ rd->texture_copy(light_accum_tex, light_accum_tex2, Vector3(), Vector3(), Vector3(atlas_size.width, atlas_size.height, 1), 0, 0, i, i);
}
Vector<RID> framebuffers;
diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h
index e17b5473a8..f2a826a447 100644
--- a/modules/lightmapper_rd/lightmapper_rd.h
+++ b/modules/lightmapper_rd/lightmapper_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,18 +46,18 @@ class LightmapperRD : public Lightmapper {
};
struct Light {
- float position[3];
+ float position[3] = {};
uint32_t type = LIGHT_TYPE_DIRECTIONAL;
- float direction[3];
- float energy;
- float color[3];
- float size;
- float range;
- float attenuation;
- float spot_angle;
- float spot_attenuation;
- uint32_t static_bake;
- uint32_t pad[3];
+ float direction[3] = {};
+ float energy = 0.0;
+ float color[3] = {};
+ float size = 0.0;
+ float range = 0.0;
+ float attenuation = 0.0;
+ float cos_spot_angle = 0.0;
+ float inv_spot_attenuation = 0.0;
+ uint32_t static_bake = 0;
+ uint32_t pad[3] = {};
bool operator<(const Light &p_light) const {
return type < p_light.type;
@@ -65,10 +65,10 @@ class LightmapperRD : public Lightmapper {
};
struct Vertex {
- float position[3];
- float normal_z;
- float uv[2];
- float normal_xy[2];
+ float position[3] = {};
+ float normal_z = 0.0;
+ float uv[2] = {};
+ float normal_xy[2] = {};
bool operator==(const Vertex &p_vtx) const {
return (position[0] == p_vtx.position[0]) &&
@@ -102,7 +102,7 @@ class LightmapperRD : public Lightmapper {
};
struct Probe {
- float position[4];
+ float position[4] = {};
};
Vector<Probe> probe_positions;
@@ -158,15 +158,15 @@ class LightmapperRD : public Lightmapper {
};
struct Box {
- float min_bounds[3];
- float pad0;
- float max_bounds[3];
- float pad1;
+ float min_bounds[3] = {};
+ float pad0 = 0.0;
+ float max_bounds[3] = {};
+ float pad1 = 0.0;
};
struct Triangle {
- uint32_t indices[3];
- uint32_t slice;
+ uint32_t indices[3] = {};
+ uint32_t slice = 0;
bool operator<(const Triangle &p_triangle) const {
return slice < p_triangle.slice;
}
@@ -177,8 +177,8 @@ class LightmapperRD : public Lightmapper {
Vector<Light> lights;
struct TriangleSort {
- uint32_t cell_index;
- uint32_t triangle_index;
+ uint32_t cell_index = 0;
+ uint32_t triangle_index = 0;
bool operator<(const TriangleSort &p_triangle_sort) const {
return cell_index < p_triangle_sort.cell_index; //sorting by triangle index in this case makes no sense
}
@@ -187,44 +187,44 @@ class LightmapperRD : public Lightmapper {
void _plot_triangle_into_triangle_index_list(int p_size, const Vector3i &p_ofs, const AABB &p_bounds, const Vector3 p_points[], uint32_t p_triangle_index, LocalVector<TriangleSort> &triangles, uint32_t p_grid_size);
struct RasterPushConstant {
- float atlas_size[2];
- float uv_offset[2];
- float to_cell_size[3];
- uint32_t base_triangle;
- float to_cell_offset[3];
- float bias;
- int32_t grid_size[3];
- uint32_t pad2;
+ float atlas_size[2] = {};
+ float uv_offset[2] = {};
+ float to_cell_size[3] = {};
+ uint32_t base_triangle = 0;
+ float to_cell_offset[3] = {};
+ float bias = 0.0;
+ int32_t grid_size[3] = {};
+ uint32_t pad2 = 0;
};
struct RasterSeamsPushConstant {
- uint32_t base_index;
- uint32_t slice;
- float uv_offset[2];
- uint32_t debug;
- float blend;
- uint32_t pad[2];
+ uint32_t base_index = 0;
+ uint32_t slice = 0;
+ float uv_offset[2] = {};
+ uint32_t debug = 0;
+ float blend = 0.0;
+ uint32_t pad[2] = {};
};
struct PushConstant {
- int32_t atlas_size[2];
- uint32_t ray_count;
- uint32_t ray_to;
+ int32_t atlas_size[2] = {};
+ uint32_t ray_count = 0;
+ uint32_t ray_to = 0;
- float world_size[3];
- float bias;
+ float world_size[3] = {};
+ float bias = 0.0;
- float to_cell_offset[3];
- uint32_t ray_from;
+ float to_cell_offset[3] = {};
+ uint32_t ray_from = 0;
- float to_cell_size[3];
- uint32_t light_count;
+ float to_cell_size[3] = {};
+ uint32_t light_count = 0;
- int32_t grid_size;
- int32_t atlas_slice;
- int32_t region_ofs[2];
+ int32_t grid_size = 0;
+ int32_t atlas_slice = 0;
+ int32_t region_ofs[2] = {};
- float environment_xform[12];
+ float environment_xform[12] = {};
};
Vector<Ref<Image>> bake_textures;
diff --git a/modules/lightmapper_rd/lm_common_inc.glsl b/modules/lightmapper_rd/lm_common_inc.glsl
index 0ff455936e..f8a0cd16de 100644
--- a/modules/lightmapper_rd/lm_common_inc.glsl
+++ b/modules/lightmapper_rd/lm_common_inc.glsl
@@ -56,8 +56,8 @@ struct Light {
float range;
float attenuation;
- float spot_angle;
- float spot_attenuation;
+ float cos_spot_angle;
+ float inv_spot_attenuation;
bool static_bake;
uint pad[3];
diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl
index 56976bd623..eb9d817f99 100644
--- a/modules/lightmapper_rd/lm_compute.glsl
+++ b/modules/lightmapper_rd/lm_compute.glsl
@@ -249,6 +249,15 @@ float quick_hash(vec2 pos) {
return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237);
}
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
void main() {
#ifdef MODE_LIGHT_PROBES
int probe_index = int(gl_GlobalInvocationID.x);
@@ -300,17 +309,20 @@ void main() {
d /= lights.data[i].range;
- attenuation = pow(max(1.0 - d, 0.0), lights.data[i].attenuation);
+ attenuation = get_omni_attenuation(d, 1.0 / lights.data[i].range, lights.data[i].attenuation);
if (lights.data[i].type == LIGHT_TYPE_SPOT) {
vec3 rel = normalize(position - light_pos);
- float angle = acos(dot(rel, lights.data[i].direction));
- if (angle > lights.data[i].spot_angle) {
+ float cos_spot_angle = lights.data[i].cos_spot_angle;
+ float cos_angle = dot(rel, lights.data[i].direction);
+
+ if (cos_angle < cos_spot_angle) {
continue; //invisible, dont try
}
- float d = clamp(angle / lights.data[i].spot_angle, 0, 1);
- attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation);
+ float scos = max(cos_angle, cos_spot_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
+ attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation);
}
}
diff --git a/modules/lightmapper_rd/register_types.cpp b/modules/lightmapper_rd/register_types.cpp
index b16adaf5d6..191bb3d765 100644
--- a/modules/lightmapper_rd/register_types.cpp
+++ b/modules/lightmapper_rd/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,18 +41,18 @@ static Lightmapper *create_lightmapper_rd() {
#endif
void register_lightmapper_rd_types() {
- GLOBAL_DEF("rendering/gpu_lightmapper/quality/low_quality_ray_count", 16);
- GLOBAL_DEF("rendering/gpu_lightmapper/quality/medium_quality_ray_count", 64);
- GLOBAL_DEF("rendering/gpu_lightmapper/quality/high_quality_ray_count", 256);
- GLOBAL_DEF("rendering/gpu_lightmapper/quality/ultra_quality_ray_count", 1024);
- GLOBAL_DEF("rendering/gpu_lightmapper/performance/max_rays_per_pass", 32);
- GLOBAL_DEF("rendering/gpu_lightmapper/performance/region_size", 512);
+ GLOBAL_DEF("rendering/lightmapping/bake_quality/low_quality_ray_count", 16);
+ GLOBAL_DEF("rendering/lightmapping/bake_quality/medium_quality_ray_count", 64);
+ GLOBAL_DEF("rendering/lightmapping/bake_quality/high_quality_ray_count", 256);
+ GLOBAL_DEF("rendering/lightmapping/bake_quality/ultra_quality_ray_count", 1024);
+ GLOBAL_DEF("rendering/lightmapping/bake_performance/max_rays_per_pass", 32);
+ GLOBAL_DEF("rendering/lightmapping/bake_performance/region_size", 512);
- GLOBAL_DEF("rendering/gpu_lightmapper/quality/low_quality_probe_ray_count", 64);
- GLOBAL_DEF("rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count", 256);
- GLOBAL_DEF("rendering/gpu_lightmapper/quality/high_quality_probe_ray_count", 512);
- GLOBAL_DEF("rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count", 2048);
- GLOBAL_DEF("rendering/gpu_lightmapper/performance/max_rays_per_probe_pass", 64);
+ GLOBAL_DEF("rendering/lightmapping/bake_quality/low_quality_probe_ray_count", 64);
+ GLOBAL_DEF("rendering/lightmapping/bake_quality/medium_quality_probe_ray_count", 256);
+ GLOBAL_DEF("rendering/lightmapping/bake_quality/high_quality_probe_ray_count", 512);
+ GLOBAL_DEF("rendering/lightmapping/bake_quality/ultra_quality_probe_ray_count", 2048);
+ GLOBAL_DEF("rendering/lightmapping/bake_performance/max_rays_per_probe_pass", 64);
#ifndef _3D_DISABLED
ClassDB::register_class<LightmapperRD>();
Lightmapper::create_gpu = create_lightmapper_rd;
diff --git a/modules/lightmapper_rd/register_types.h b/modules/lightmapper_rd/register_types.h
index b0e15a927f..622d6e37a7 100644
--- a/modules/lightmapper_rd/register_types.h
+++ b/modules/lightmapper_rd/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub
index 4fcbe8fb43..4fcbe8fb43 100755..100644
--- a/modules/mbedtls/SCsub
+++ b/modules/mbedtls/SCsub
diff --git a/modules/mbedtls/config.py b/modules/mbedtls/config.py
index d22f9454ed..d22f9454ed 100755..100644
--- a/modules/mbedtls/config.py
+++ b/modules/mbedtls/config.py
diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp
index 4ea38ebd60..73931b0365 100644
--- a/modules/mbedtls/crypto_mbedtls.cpp
+++ b/modules/mbedtls/crypto_mbedtls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -205,7 +205,7 @@ Error HMACContextMbedTLS::start(HashingContext::HashType p_hash_type, PackedByte
ERR_FAIL_COND_V_MSG(ctx != nullptr, ERR_FILE_ALREADY_IN_USE, "HMACContext already started.");
// HMAC keys can be any size.
- ERR_FAIL_COND_V_MSG(p_key.empty(), ERR_INVALID_PARAMETER, "Key must not be empty.");
+ ERR_FAIL_COND_V_MSG(p_key.is_empty(), ERR_INVALID_PARAMETER, "Key must not be empty.");
hash_type = p_hash_type;
mbedtls_md_type_t ht = CryptoMbedTLS::md_type_from_hashtype(p_hash_type, hash_len);
@@ -224,7 +224,7 @@ Error HMACContextMbedTLS::start(HashingContext::HashType p_hash_type, PackedByte
Error HMACContextMbedTLS::update(PackedByteArray p_data) {
ERR_FAIL_COND_V_MSG(ctx == nullptr, ERR_INVALID_DATA, "Start must be called before update.");
- ERR_FAIL_COND_V_MSG(p_data.empty(), ERR_INVALID_PARAMETER, "Src must not be empty.");
+ ERR_FAIL_COND_V_MSG(p_data.is_empty(), ERR_INVALID_PARAMETER, "Src must not be empty.");
int ret = mbedtls_md_hmac_update((mbedtls_md_context_t *)ctx, (const uint8_t *)p_data.ptr(), (size_t)p_data.size());
return ret ? FAILED : OK;
diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h
index 990f8ae578..5ced4d136c 100644
--- a/modules/mbedtls/crypto_mbedtls.h
+++ b/modules/mbedtls/crypto_mbedtls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mbedtls/dtls_server_mbedtls.cpp b/modules/mbedtls/dtls_server_mbedtls.cpp
index d9961b026f..5d895d8579 100644
--- a/modules/mbedtls/dtls_server_mbedtls.cpp
+++ b/modules/mbedtls/dtls_server_mbedtls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mbedtls/dtls_server_mbedtls.h b/modules/mbedtls/dtls_server_mbedtls.h
index d93553bf7f..9f0c9670e7 100644
--- a/modules/mbedtls/dtls_server_mbedtls.h
+++ b/modules/mbedtls/dtls_server_mbedtls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mbedtls/packet_peer_mbed_dtls.cpp b/modules/mbedtls/packet_peer_mbed_dtls.cpp
index 8206d739ae..8a6cdfb131 100644
--- a/modules/mbedtls/packet_peer_mbed_dtls.cpp
+++ b/modules/mbedtls/packet_peer_mbed_dtls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -246,7 +246,6 @@ int PacketPeerMbedDTLS::get_max_packet_size() const {
PacketPeerMbedDTLS::PacketPeerMbedDTLS() {
ssl_ctx.instance();
- status = STATUS_DISCONNECTED;
}
PacketPeerMbedDTLS::~PacketPeerMbedDTLS() {
diff --git a/modules/mbedtls/packet_peer_mbed_dtls.h b/modules/mbedtls/packet_peer_mbed_dtls.h
index b958fa3b95..6554c74a21 100755..100644
--- a/modules/mbedtls/packet_peer_mbed_dtls.h
+++ b/modules/mbedtls/packet_peer_mbed_dtls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,7 +44,7 @@ private:
uint8_t packet_buffer[PACKET_BUFFER_SIZE];
- Status status;
+ Status status = STATUS_DISCONNECTED;
String hostname;
Ref<PacketPeerUDP> base;
diff --git a/modules/mbedtls/register_types.cpp b/modules/mbedtls/register_types.cpp
index 59abbac8ec..e483030b94 100644
--- a/modules/mbedtls/register_types.cpp
+++ b/modules/mbedtls/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mbedtls/register_types.h b/modules/mbedtls/register_types.h
index 90c81b1682..46ffb8522b 100755..100644
--- a/modules/mbedtls/register_types.h
+++ b/modules/mbedtls/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mbedtls/ssl_context_mbedtls.cpp b/modules/mbedtls/ssl_context_mbedtls.cpp
index a2200e0644..cbb532587f 100644
--- a/modules/mbedtls/ssl_context_mbedtls.cpp
+++ b/modules/mbedtls/ssl_context_mbedtls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -76,7 +76,6 @@ void CookieContextMbedTLS::clear() {
}
CookieContextMbedTLS::CookieContextMbedTLS() {
- inited = false;
}
CookieContextMbedTLS::~CookieContextMbedTLS() {
@@ -205,7 +204,6 @@ mbedtls_ssl_context *SSLContextMbedTLS::get_context() {
}
SSLContextMbedTLS::SSLContextMbedTLS() {
- inited = false;
}
SSLContextMbedTLS::~SSLContextMbedTLS() {
diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h
index 96703a7eb7..30632018a8 100644
--- a/modules/mbedtls/ssl_context_mbedtls.h
+++ b/modules/mbedtls/ssl_context_mbedtls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,7 +50,7 @@ class CookieContextMbedTLS : public Reference {
friend class SSLContextMbedTLS;
protected:
- bool inited;
+ bool inited = false;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_cookie_ctx cookie_ctx;
@@ -65,7 +65,7 @@ public:
class SSLContextMbedTLS : public Reference {
protected:
- bool inited;
+ bool inited = false;
static PackedByteArray _read_file(String p_path);
diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp
index e9a610b7ee..d7597aa435 100644
--- a/modules/mbedtls/stream_peer_mbedtls.cpp
+++ b/modules/mbedtls/stream_peer_mbedtls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -274,7 +274,6 @@ int StreamPeerMbedTLS::get_available_bytes() const {
StreamPeerMbedTLS::StreamPeerMbedTLS() {
ssl_ctx.instance();
- status = STATUS_DISCONNECTED;
}
StreamPeerMbedTLS::~StreamPeerMbedTLS() {
diff --git a/modules/mbedtls/stream_peer_mbedtls.h b/modules/mbedtls/stream_peer_mbedtls.h
index 68b03ae995..b89d7fb238 100755..100644
--- a/modules/mbedtls/stream_peer_mbedtls.h
+++ b/modules/mbedtls/stream_peer_mbedtls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class StreamPeerMbedTLS : public StreamPeerSSL {
private:
- Status status;
+ Status status = STATUS_DISCONNECTED;
String hostname;
Ref<StreamPeer> base;
diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.cpp b/modules/mbedtls/tests/test_crypto_mbedtls.cpp
index c5a27aa794..4217497082 100644
--- a/modules/mbedtls/tests/test_crypto_mbedtls.cpp
+++ b/modules/mbedtls/tests/test_crypto_mbedtls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.h b/modules/mbedtls/tests/test_crypto_mbedtls.h
index 7b1e062239..b798717e52 100644
--- a/modules/mbedtls/tests/test_crypto_mbedtls.h
+++ b/modules/mbedtls/tests/test_crypto_mbedtls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/meshoptimizer/register_types.cpp b/modules/meshoptimizer/register_types.cpp
index 26c8c6ab72..a03310f518 100644
--- a/modules/meshoptimizer/register_types.cpp
+++ b/modules/meshoptimizer/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,9 +35,13 @@
void register_meshoptimizer_types() {
SurfaceTool::optimize_vertex_cache_func = meshopt_optimizeVertexCache;
SurfaceTool::simplify_func = meshopt_simplify;
+ SurfaceTool::simplify_scale_func = meshopt_simplifyScale;
+ SurfaceTool::simplify_sloppy_func = meshopt_simplifySloppy;
}
void unregister_meshoptimizer_types() {
SurfaceTool::optimize_vertex_cache_func = nullptr;
SurfaceTool::simplify_func = nullptr;
+ SurfaceTool::simplify_scale_func = nullptr;
+ SurfaceTool::simplify_sloppy_func = nullptr;
}
diff --git a/modules/meshoptimizer/register_types.h b/modules/meshoptimizer/register_types.h
index 42b3a76a85..5b15503acd 100644
--- a/modules/meshoptimizer/register_types.h
+++ b/modules/meshoptimizer/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp
index b20c043e0c..b128b81000 100644
--- a/modules/minimp3/audio_stream_mp3.cpp
+++ b/modules/minimp3/audio_stream_mp3.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -120,7 +120,10 @@ AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() {
Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() {
Ref<AudioStreamPlaybackMP3> mp3s;
- ERR_FAIL_COND_V(data == nullptr, mp3s);
+ ERR_FAIL_COND_V_MSG(data == nullptr, mp3s,
+ "This AudioStreamMP3 does not have an audio file assigned "
+ "to it. AudioStreamMP3 should not be created from the "
+ "inspector or with `.new()`. Instead, load an audio file.");
mp3s.instance();
mp3s->mp3_stream = Ref<AudioStreamMP3>(this);
@@ -156,7 +159,8 @@ void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) {
const uint8_t *src_datar = p_data.ptr();
mp3dec_ex_t mp3d;
- mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE);
+ int err = mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE);
+ ERR_FAIL_COND(err != 0);
channels = mp3d.info.channels;
sample_rate = mp3d.info.hz;
diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h
index 8d67190ac5..ce001fc418 100644
--- a/modules/minimp3/audio_stream_mp3.h
+++ b/modules/minimp3/audio_stream_mp3.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,11 +78,11 @@ class AudioStreamMP3 : public AudioStream {
void *data = nullptr;
uint32_t data_len = 0;
- float sample_rate = 1;
+ float sample_rate = 1.0;
int channels = 1;
- float length = 0;
+ float length = 0.0;
bool loop = false;
- float loop_offset = 0;
+ float loop_offset = 0.0;
void clear_data();
protected:
diff --git a/modules/minimp3/register_types.cpp b/modules/minimp3/register_types.cpp
index 2c648b8efe..4ab4c743d6 100644
--- a/modules/minimp3/register_types.cpp
+++ b/modules/minimp3/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/minimp3/register_types.h b/modules/minimp3/register_types.h
index 0d841e4987..96227c272e 100644
--- a/modules/minimp3/register_types.h
+++ b/modules/minimp3/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/minimp3/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp
index 82e536a755..afd26fb79e 100644
--- a/modules/minimp3/resource_importer_mp3.cpp
+++ b/modules/minimp3/resource_importer_mp3.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/minimp3/resource_importer_mp3.h b/modules/minimp3/resource_importer_mp3.h
index c1e8315e21..71b51887a2 100644
--- a/modules/minimp3/resource_importer_mp3.h
+++ b/modules/minimp3/resource_importer_mp3.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp
index a2fb443ef0..25b110dc62 100644
--- a/modules/mobile_vr/mobile_vr_interface.cpp
+++ b/modules/mobile_vr/mobile_vr_interface.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -448,19 +448,7 @@ void MobileVRInterface::process() {
};
};
-MobileVRInterface::MobileVRInterface() {
- initialized = false;
-
- // Just set some defaults for these. At some point we need to look at adding a lookup table for common device + headset combos and/or support reading cardboard QR codes
- eye_height = 1.85;
- intraocular_dist = 6.0;
- display_width = 14.5;
- display_to_lens = 4.0;
- oversample = 1.5;
- k1 = 0.215;
- k2 = 0.215;
- last_ticks = 0;
-};
+MobileVRInterface::MobileVRInterface() {}
MobileVRInterface::~MobileVRInterface() {
// and make sure we cleanup if we haven't already
diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h
index 9b03fff777..d28c2196af 100644
--- a/modules/mobile_vr/mobile_vr_interface.h
+++ b/modules/mobile_vr/mobile_vr_interface.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,19 +51,21 @@ class MobileVRInterface : public XRInterface {
GDCLASS(MobileVRInterface, XRInterface);
private:
- bool initialized;
+ bool initialized = false;
Basis orientation;
- float eye_height;
- uint64_t last_ticks;
- real_t intraocular_dist;
- real_t display_width;
- real_t display_to_lens;
- real_t oversample;
+ // Just set some defaults for these. At some point we need to look at adding a lookup table for common device + headset combos and/or support reading cardboard QR codes
+ float eye_height = 1.85;
+ uint64_t last_ticks = 0;
+
+ real_t intraocular_dist = 6.0;
+ real_t display_width = 14.5;
+ real_t display_to_lens = 4.0;
+ real_t oversample = 1.5;
//@TODO not yet used, these are needed in our distortion shader...
- real_t k1;
- real_t k2;
+ real_t k1 = 0.215;
+ real_t k2 = 0.215;
/*
logic for processing our sensor data, this was originally in our positional tracker logic but I think
@@ -73,9 +75,9 @@ private:
Vector3 scale_magneto(const Vector3 &p_magnetometer);
Basis combine_acc_mag(const Vector3 &p_grav, const Vector3 &p_magneto);
- int mag_count;
- bool has_gyro;
- bool sensor_first;
+ int mag_count = 0;
+ bool has_gyro = false;
+ bool sensor_first = false;
Vector3 last_accerometer_data;
Vector3 last_magnetometer_data;
Vector3 mag_current_min;
diff --git a/modules/mobile_vr/register_types.cpp b/modules/mobile_vr/register_types.cpp
index 0bb555e780..e7d33ba8a7 100644
--- a/modules/mobile_vr/register_types.cpp
+++ b/modules/mobile_vr/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mobile_vr/register_types.h b/modules/mobile_vr/register_types.h
index 33f608b6ed..9f20f252a4 100644
--- a/modules/mobile_vr/register_types.h
+++ b/modules/mobile_vr/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/Directory.Build.props b/modules/mono/Directory.Build.props
new file mode 100644
index 0000000000..fbf864b11b
--- /dev/null
+++ b/modules/mono/Directory.Build.props
@@ -0,0 +1,3 @@
+<Project>
+ <Import Project="$(MSBuildThisFileDirectory)\SdkPackageVersions.props" />
+</Project>
diff --git a/modules/mono/SdkPackageVersions.props b/modules/mono/SdkPackageVersions.props
new file mode 100644
index 0000000000..396443f30e
--- /dev/null
+++ b/modules/mono/SdkPackageVersions.props
@@ -0,0 +1,6 @@
+<Project>
+ <PropertyGroup>
+ <PackageVersion_Godot_NET_Sdk>4.0.0-dev4</PackageVersion_Godot_NET_Sdk>
+ <PackageVersion_Godot_SourceGenerators>4.0.0-dev1</PackageVersion_Godot_SourceGenerators>
+ </PropertyGroup>
+</Project>
diff --git a/modules/mono/build_scripts/godot_net_sdk_build.py b/modules/mono/build_scripts/godot_net_sdk_build.py
index 3bfba0f0f6..8c5a60d2db 100644
--- a/modules/mono/build_scripts/godot_net_sdk_build.py
+++ b/modules/mono/build_scripts/godot_net_sdk_build.py
@@ -21,6 +21,18 @@ def build_godot_net_sdk(source, target, env):
# No need to copy targets. The Godot.NET.Sdk csproj takes care of copying them.
+def get_nupkgs_versions(props_file):
+ import xml.etree.ElementTree as ET
+
+ tree = ET.parse(props_file)
+ root = tree.getroot()
+
+ return {
+ "Godot.NET.Sdk": root.find("./PropertyGroup/PackageVersion_Godot_NET_Sdk").text.strip(),
+ "Godot.SourceGenerators": root.find("./PropertyGroup/PackageVersion_Godot_SourceGenerators").text.strip(),
+ }
+
+
def build(env_mono):
assert env_mono["tools"]
@@ -30,14 +42,12 @@ def build(env_mono):
module_dir = os.getcwd()
- package_version_file = os.path.join(
- module_dir, "editor", "Godot.NET.Sdk", "Godot.NET.Sdk", "Godot.NET.Sdk_PackageVersion.txt"
- )
-
- with open(package_version_file, mode="r") as f:
- version = f.read().strip()
+ nupkgs_versions = get_nupkgs_versions(os.path.join(module_dir, "SdkPackageVersions.props"))
- target_filenames = ["Godot.NET.Sdk.%s.nupkg" % version]
+ target_filenames = [
+ "Godot.NET.Sdk.%s.nupkg" % nupkgs_versions["Godot.NET.Sdk"],
+ "Godot.SourceGenerators.%s.nupkg" % nupkgs_versions["Godot.SourceGenerators"],
+ ]
targets = [os.path.join(nupkgs_dir, filename) for filename in target_filenames]
diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp
index e3119a8da7..553c6eca53 100644
--- a/modules/mono/class_db_api_json.cpp
+++ b/modules/mono/class_db_api_json.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,7 +71,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
while ((k = t->method_map.next(k))) {
String name = k->operator String();
- ERR_CONTINUE(name.empty());
+ ERR_CONTINUE(name.is_empty());
if (name[0] == '_') {
continue; // Ignore non-virtual methods that start with an underscore
@@ -122,7 +122,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
method_dict["hint_flags"] = mb->get_hint_flags();
}
- if (!methods.empty()) {
+ if (!methods.is_empty()) {
class_dict["methods"] = methods;
}
}
@@ -149,7 +149,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
constant_dict["value"] = t->constant_map[F->get()];
}
- if (!constants.empty()) {
+ if (!constants.is_empty()) {
class_dict["constants"] = constants;
}
}
@@ -184,7 +184,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
}
}
- if (!signals.empty()) {
+ if (!signals.is_empty()) {
class_dict["signals"] = signals;
}
}
@@ -214,7 +214,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
property_dict["getter"] = psg->getter;
}
- if (!properties.empty()) {
+ if (!properties.is_empty()) {
class_dict["property_setget"] = properties;
}
}
@@ -233,7 +233,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
property_dict["usage"] = F->get().usage;
}
- if (!property_list.empty()) {
+ if (!property_list.is_empty()) {
class_dict["property_list"] = property_list;
}
}
diff --git a/modules/mono/class_db_api_json.h b/modules/mono/class_db_api_json.h
index 6b7f5a4d88..6698a6260f 100644
--- a/modules/mono/class_db_api_json.h
+++ b/modules/mono/class_db_api_json.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 63ac0956f4..4fca80fca0 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,6 +31,7 @@
#include "csharp_script.h"
#include <mono/metadata/threads.h>
+#include <mono/metadata/tokentype.h>
#include <stdint.h>
#include "core/config/project_settings.h"
@@ -346,14 +347,18 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin
"// }\n"
"}\n";
- String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
+ // Replaces all spaces in p_class_name with underscores to prevent
+ // erronous C# Script templates from being generated when the object name
+ // has spaces in it.
+ String class_name_no_spaces = p_class_name.replace(" ", "_");
+ String base_class_name = get_base_class_name(p_base_class_name, class_name_no_spaces);
script_template = script_template.replace("%BASE%", base_class_name)
- .replace("%CLASS%", p_class_name);
+ .replace("%CLASS%", class_name_no_spaces);
Ref<CSharpScript> script;
script.instance();
script->set_source_code(script_template);
- script->set_name(p_class_name);
+ script->set_name(class_name_no_spaces);
return script;
}
@@ -364,9 +369,10 @@ bool CSharpLanguage::is_using_templates() {
void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
String src = p_script->get_source_code();
- String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
+ String class_name_no_spaces = p_class_name.replace(" ", "_");
+ String base_class_name = get_base_class_name(p_base_class_name, class_name_no_spaces);
src = src.replace("%BASE%", base_class_name)
- .replace("%CLASS%", p_class_name)
+ .replace("%CLASS%", class_name_no_spaces)
.replace("%TS%", _get_indentation());
p_script->set_source_code(src);
}
@@ -395,7 +401,7 @@ bool CSharpLanguage::supports_builtin_mode() const {
#ifdef TOOLS_ENABLED
static String variant_type_to_managed_name(const String &p_var_type_name) {
- if (p_var_type_name.empty()) {
+ if (p_var_type_name.is_empty()) {
return "object";
}
@@ -757,7 +763,7 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
String appname = ProjectSettings::get_singleton()->get("application/config/name");
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
- if (appname_safe.empty()) {
+ if (appname_safe.is_empty()) {
appname_safe = "UnnamedProject";
}
@@ -854,7 +860,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
to_reload.push_back(script);
- if (script->get_path().empty()) {
+ if (script->get_path().is_empty()) {
script->tied_class_name_for_reload = script->script_class->get_name_for_lookup();
script->tied_class_namespace_for_reload = script->script_class->get_namespace();
}
@@ -971,7 +977,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
#endif
script->signals_invalidated = true;
- if (!script->get_path().empty()) {
+ if (!script->get_path().is_empty()) {
script->reload(p_soft_reload);
if (!script->valid) {
@@ -1177,46 +1183,56 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
}
#endif
-void CSharpLanguage::_load_scripts_metadata() {
- scripts_metadata.clear();
+void CSharpLanguage::lookup_script_for_class(GDMonoClass *p_class) {
+ if (!p_class->has_attribute(CACHED_CLASS(ScriptPathAttribute))) {
+ return;
+ }
- String scripts_metadata_filename = "scripts_metadata.";
+ MonoObject *attr = p_class->get_attribute(CACHED_CLASS(ScriptPathAttribute));
+ String path = CACHED_FIELD(ScriptPathAttribute, path)->get_string_value(attr);
-#ifdef TOOLS_ENABLED
- scripts_metadata_filename += Engine::get_singleton()->is_editor_hint() ? "editor" : "editor_player";
-#else
-#ifdef DEBUG_ENABLED
- scripts_metadata_filename += "debug";
-#else
- scripts_metadata_filename += "release";
-#endif
-#endif
+ dotnet_script_lookup_map[path] = DotNetScriptLookupInfo(
+ p_class->get_namespace(), p_class->get_name(), p_class);
+}
- String scripts_metadata_path = GodotSharpDirs::get_res_metadata_dir().plus_file(scripts_metadata_filename);
+void CSharpLanguage::lookup_scripts_in_assembly(GDMonoAssembly *p_assembly) {
+ if (p_assembly->has_attribute(CACHED_CLASS(AssemblyHasScriptsAttribute))) {
+ MonoObject *attr = p_assembly->get_attribute(CACHED_CLASS(AssemblyHasScriptsAttribute));
+ bool requires_lookup = CACHED_FIELD(AssemblyHasScriptsAttribute, requiresLookup)->get_bool_value(attr);
- if (FileAccess::exists(scripts_metadata_path)) {
- String old_json;
+ if (requires_lookup) {
+ // This is supported for scenarios where specifying all types would be cumbersome,
+ // such as when disabling C# source generators (for whatever reason) or when using a
+ // language other than C# that has nothing similar to source generators to automate it.
+ MonoImage *image = p_assembly->get_image();
- Error ferr = read_all_file_utf8(scripts_metadata_path, old_json);
+ int rows = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF);
- ERR_FAIL_COND(ferr != OK);
+ for (int i = 1; i < rows; i++) {
+ // We don't search inner classes, only top-level.
+ MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF);
- Variant old_dict_var;
- String err_str;
- int err_line;
- Error json_err = JSON::parse(old_json, old_dict_var, err_str, err_line);
- if (json_err != OK) {
- ERR_PRINT("Failed to parse metadata file: '" + err_str + "' (" + String::num_int64(err_line) + ").");
- return;
- }
+ if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) {
+ continue;
+ }
- scripts_metadata = old_dict_var.operator Dictionary();
- scripts_metadata_invalidated = false;
+ GDMonoClass *current = p_assembly->get_class(mono_class);
+ if (current) {
+ lookup_script_for_class(current);
+ }
+ }
+ } else {
+ // This is the most likely scenario as we use C# source generators
+ MonoArray *script_types = (MonoArray *)CACHED_FIELD(AssemblyHasScriptsAttribute, scriptTypes)->get_value(attr);
- print_verbose("Successfully loaded scripts metadata");
- } else {
- if (!Engine::get_singleton()->is_editor_hint()) {
- ERR_PRINT("Missing scripts metadata file.");
+ int length = mono_array_length(script_types);
+
+ for (int i = 0; i < length; i++) {
+ MonoReflectionType *reftype = mono_array_get(script_types, MonoReflectionType *, i);
+ ManagedType type = ManagedType::from_reftype(reftype);
+ ERR_CONTINUE(!type.type_class);
+ lookup_script_for_class(type.type_class);
+ }
}
}
}
@@ -1295,7 +1311,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() {
}
#endif
- scripts_metadata_invalidated = true;
+ dotnet_script_lookup_map.clear();
}
#ifdef TOOLS_ENABLED
@@ -1441,7 +1457,7 @@ Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_bindi
void CSharpLanguage::free_instance_binding_data(void *p_data) {
if (GDMono::get_singleton() == nullptr) {
#ifdef DEBUG_ENABLED
- CRASH_COND(!script_bindings.empty());
+ CRASH_COND(!script_bindings.is_empty());
#endif
// Mono runtime finalized, all the gchandle bindings were already released
return;
@@ -2599,7 +2615,7 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati
MonoCustomAttrInfo *event_attrs = mono_custom_attrs_from_event(top->get_mono_ptr(), raw_event);
if (event_attrs) {
if (mono_custom_attrs_has_attr(event_attrs, CACHED_CLASS(SignalAttribute)->get_mono_ptr())) {
- const char *event_name = mono_event_get_name(raw_event);
+ String event_name = String::utf8(mono_event_get_name(raw_event));
found_event_signals.push_back(StringName(event_name));
}
@@ -2803,7 +2819,7 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
name_only_hint_string += ",";
}
- String enum_field_name = mono_field_get_name(field);
+ String enum_field_name = String::utf8(mono_field_get_name(field));
r_hint_string += enum_field_name;
name_only_hint_string += enum_field_name;
@@ -3123,7 +3139,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
ERR_FAIL_COND_V_MSG(p_argcount == 0, nullptr,
"Cannot create script instance. The class '" + script_class->get_full_name() +
"' does not define a parameterless constructor." +
- (get_path().empty() ? String() : " Path: '" + get_path() + "'."));
+ (get_path().is_empty() ? String() : " Path: '" + get_path() + "'."));
ERR_FAIL_V_MSG(nullptr, "Constructor not found.");
}
@@ -3278,7 +3294,7 @@ bool CSharpScript::instance_has(const Object *p_this) const {
}
bool CSharpScript::has_source_code() const {
- return !source.empty();
+ return !source.is_empty();
}
String CSharpScript::get_source_code() const {
@@ -3351,45 +3367,34 @@ Error CSharpScript::reload(bool p_keep_state) {
GD_MONO_SCOPE_THREAD_ATTACH;
- GDMonoAssembly *project_assembly = GDMono::get_singleton()->get_project_assembly();
-
- if (project_assembly) {
- const Variant *script_metadata_var = CSharpLanguage::get_singleton()->get_scripts_metadata().getptr(get_path());
- if (script_metadata_var) {
- Dictionary script_metadata = script_metadata_var->operator Dictionary()["class"];
- const Variant *namespace_ = script_metadata.getptr("namespace");
- const Variant *class_name = script_metadata.getptr("class_name");
- ERR_FAIL_NULL_V(namespace_, ERR_BUG);
- ERR_FAIL_NULL_V(class_name, ERR_BUG);
- GDMonoClass *klass = project_assembly->get_class(namespace_->operator String(), class_name->operator String());
- if (klass && CACHED_CLASS(GodotObject)->is_assignable_from(klass)) {
- script_class = klass;
- }
- } else {
- // Missing script metadata. Fallback to legacy method
- script_class = project_assembly->get_object_derived_class(name);
+ const DotNetScriptLookupInfo *lookup_info =
+ CSharpLanguage::get_singleton()->lookup_dotnet_script(get_path());
+
+ if (lookup_info) {
+ GDMonoClass *klass = lookup_info->script_class;
+ if (klass) {
+ ERR_FAIL_COND_V(!CACHED_CLASS(GodotObject)->is_assignable_from(klass), FAILED);
+ script_class = klass;
}
+ }
- valid = script_class != nullptr;
+ valid = script_class != nullptr;
- if (script_class) {
+ if (script_class) {
#ifdef DEBUG_ENABLED
- print_verbose("Found class " + script_class->get_full_name() + " for script " + get_path());
+ print_verbose("Found class " + script_class->get_full_name() + " for script " + get_path());
#endif
- native = GDMonoUtils::get_class_native_base(script_class);
+ native = GDMonoUtils::get_class_native_base(script_class);
- CRASH_COND(native == nullptr);
+ CRASH_COND(native == nullptr);
- update_script_class_info(this);
+ update_script_class_info(this);
- _update_exports();
- }
-
- return OK;
+ _update_exports();
}
- return ERR_FILE_MISSING_DEPENDENCIES;
+ return OK;
}
ScriptLanguage *CSharpScript::get_language() const {
@@ -3579,9 +3584,9 @@ Error CSharpScript::load_source_code(const String &p_path) {
ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
ferr == ERR_INVALID_DATA ?
- "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded."
+ "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded."
" Please ensure that scripts are saved in valid UTF-8 unicode." :
- "Failed to read file: '" + p_path + "'.");
+ "Failed to read file: '" + p_path + "'.");
#ifdef TOOLS_ENABLED
source_changed_cache = true;
@@ -3593,7 +3598,7 @@ Error CSharpScript::load_source_code(const String &p_path) {
void CSharpScript::_update_name() {
String path = get_path();
- if (!path.empty()) {
+ if (!path.is_empty()) {
name = get_path().get_file().get_basename();
}
}
@@ -3639,7 +3644,7 @@ void CSharpScript::get_members(Set<StringName> *p_members) {
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index f482cc21f0..40f7ed4552 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -66,6 +66,18 @@ TScriptInstance *cast_script_instance(ScriptInstance *p_inst) {
#define CAST_CSHARP_INSTANCE(m_inst) (cast_script_instance<CSharpInstance, CSharpLanguage>(m_inst))
+struct DotNetScriptLookupInfo {
+ String class_namespace;
+ String class_name;
+ GDMonoClass *script_class = nullptr;
+
+ DotNetScriptLookupInfo() {} // Required by HashMap...
+
+ DotNetScriptLookupInfo(const String &p_class_namespace, const String &p_class_name, GDMonoClass *p_script_class) :
+ class_namespace(p_class_namespace), class_name(p_class_name), script_class(p_script_class) {
+ }
+};
+
class CSharpScript : public Script {
GDCLASS(CSharpScript, Script);
@@ -390,16 +402,15 @@ class CSharpLanguage : public ScriptLanguage {
int lang_idx = -1;
- Dictionary scripts_metadata;
- bool scripts_metadata_invalidated = true;
+ HashMap<String, DotNetScriptLookupInfo> dotnet_script_lookup_map;
+
+ void lookup_script_for_class(GDMonoClass *p_class);
// For debug_break and debug_break_parse
int _debug_parse_err_line = -1;
String _debug_parse_err_file;
String _debug_error;
- void _load_scripts_metadata();
-
friend class GDMono;
void _on_scripts_domain_unloaded();
@@ -436,18 +447,13 @@ public:
void reload_assemblies(bool p_soft_reload);
#endif
- _FORCE_INLINE_ Dictionary get_scripts_metadata_or_nothing() {
- return scripts_metadata_invalidated ? Dictionary() : scripts_metadata;
- }
+ _FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; }
- _FORCE_INLINE_ const Dictionary &get_scripts_metadata() {
- if (scripts_metadata_invalidated) {
- _load_scripts_metadata();
- }
- return scripts_metadata;
- }
+ void lookup_scripts_in_assembly(GDMonoAssembly *p_assembly);
- _FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; }
+ const DotNetScriptLookupInfo *lookup_dotnet_script(const String &p_script_path) const {
+ return dotnet_script_lookup_map.getptr(p_script_path);
+ }
String get_name() const override;
@@ -542,7 +548,7 @@ public:
class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader {
public:
- RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false) override;
+ RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override;
void get_recognized_extensions(List<String> *p_extensions) const override;
bool handles_type(const String &p_type) const override;
String get_resource_type(const String &p_path) const override;
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln
index 56c0cb7703..d1868f52ef 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln
@@ -2,6 +2,12 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot.NET.Sdk", "Godot.NET.Sdk\Godot.NET.Sdk.csproj", "{31B00BFA-DEA1-42FA-A472-9E54A92A8A5F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot.SourceGenerators", "Godot.SourceGenerators\Godot.SourceGenerators.csproj", "{32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot.SourceGenerators.Sample", "Godot.SourceGenerators.Sample\Godot.SourceGenerators.Sample.csproj", "{7297A614-8DF5-43DE-9EAD-99671B26BD1F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotSharp", "..\..\glue\GodotSharp\GodotSharp\GodotSharp.csproj", "{AEBF0036-DA76-4341-B651-A3F2856AB2FA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -12,5 +18,17 @@ Global
{31B00BFA-DEA1-42FA-A472-9E54A92A8A5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31B00BFA-DEA1-42FA-A472-9E54A92A8A5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31B00BFA-DEA1-42FA-A472-9E54A92A8A5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7297A614-8DF5-43DE-9EAD-99671B26BD1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7297A614-8DF5-43DE-9EAD-99671B26BD1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7297A614-8DF5-43DE-9EAD-99671B26BD1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7297A614-8DF5-43DE-9EAD-99671B26BD1F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj
index 8304d9e321..ef8add0ba8 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj
@@ -8,43 +8,33 @@
<PackageId>Godot.NET.Sdk</PackageId>
<Version>4.0.0</Version>
- <PackageProjectUrl>https://github.com/godotengine/godot/tree/master/modules/mono/editor/Godot.NET.Sdk</PackageProjectUrl>
+ <PackageVersion>$(PackageVersion_Godot_NET_Sdk)</PackageVersion>
+ <RepositoryUrl>https://github.com/godotengine/godot/tree/master/modules/mono/editor/Godot.NET.Sdk</RepositoryUrl>
+ <PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<PackageType>MSBuildSdk</PackageType>
<PackageTags>MSBuildSdk</PackageTags>
+ <PackageLicenseExpression>MIT</PackageLicenseExpression>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
- </PropertyGroup>
- <PropertyGroup>
- <NuspecFile>Godot.NET.Sdk.nuspec</NuspecFile>
- <GenerateNuspecDependsOn>$(GenerateNuspecDependsOn);SetNuSpecProperties</GenerateNuspecDependsOn>
+ <!-- Exclude target framework from the package dependencies as we don't include the build output -->
+ <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
+ <IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
- <Target Name="ReadGodotNETSdkVersion" BeforeTargets="BeforeBuild;BeforeRebuild;CoreCompile">
- <PropertyGroup>
- <PackageVersion>$([System.IO.File]::ReadAllText('$(ProjectDir)Godot.NET.Sdk_PackageVersion.txt').Trim())</PackageVersion>
- </PropertyGroup>
- </Target>
+ <ItemGroup>
+ <!-- Package Sdk\Sdk.props and Sdk\Sdk.targets file -->
+ <None Include="Sdk\Sdk.props" Pack="true" PackagePath="Sdk" Visible="false" />
+ <None Include="Sdk\Sdk.targets" Pack="true" PackagePath="Sdk" Visible="false" />
+ <!-- SdkPackageVersions.props -->
- <Target Name="SetNuSpecProperties" Condition=" Exists('$(NuspecFile)') " DependsOnTargets="ReadGodotNETSdkVersion">
- <PropertyGroup>
- <NuspecProperties>
- id=$(PackageId);
- description=$(Description);
- authors=$(Authors);
- version=$(PackageVersion);
- packagetype=$(PackageType);
- tags=$(PackageTags);
- projecturl=$(PackageProjectUrl)
- </NuspecProperties>
- </PropertyGroup>
- </Target>
+ <None Include="..\..\..\SdkPackageVersions.props" Pack="true" PackagePath="Sdk" Visible="false" />
+ </ItemGroup>
<Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack">
<PropertyGroup>
<GodotSourceRootPath>$(SolutionDir)\..\..\..\..\</GodotSourceRootPath>
<GodotOutputDataDir>$(GodotSourceRootPath)\bin\GodotSharp\</GodotOutputDataDir>
</PropertyGroup>
- <Copy SourceFiles="$(OutputPath)$(PackageId).$(PackageVersion).nupkg"
- DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
+ <Copy SourceFiles="$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
</Target>
</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.nuspec b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.nuspec
deleted file mode 100644
index ba68a4da43..0000000000
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.nuspec
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
- <metadata>
- <id>$id$</id>
- <version>$version$</version>
- <description>$description$</description>
- <authors>$authors$</authors>
- <owners>$authors$</owners>
- <projectUrl>$projecturl$</projectUrl>
- <requireLicenseAcceptance>false</requireLicenseAcceptance>
- <license type="expression">MIT</license>
- <licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
- <tags>$tags$</tags>
- <packageTypes>
- <packageType name="$packagetype$" />
- </packageTypes>
- <repository url="$projecturl$" />
- </metadata>
- <files>
- <file src="Sdk\**" target="Sdk" />
- </files>
-</package>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk_PackageVersion.txt b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk_PackageVersion.txt
deleted file mode 100644
index 34749489b9..0000000000
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk_PackageVersion.txt
+++ /dev/null
@@ -1 +0,0 @@
-4.0.0-dev3
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
index 5febcf3175..0128f5c706 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
@@ -1,4 +1,6 @@
<Project>
+ <Import Project="$(MSBuildThisFileDirectory)\SdkPackageVersions.props" />
+
<PropertyGroup>
<!-- Determines if we should import Microsoft.NET.Sdk, if it wasn't already imported. -->
<GodotSdkImportsMicrosoftNetSdk Condition=" '$(UsingMicrosoftNETSdk)' != 'true' ">true</GodotSdkImportsMicrosoftNetSdk>
@@ -94,6 +96,7 @@
<DefineConstants>$(GodotDefineConstants);$(DefineConstants)</DefineConstants>
</PropertyGroup>
+ <!-- Godot API references -->
<ItemGroup>
<!--
TODO:
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
index f5afd75505..92e299d2f3 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
@@ -14,4 +14,9 @@
-->
<DefineConstants Condition=" '$(GodotRealTIsDouble)' == 'true' ">GODOT_REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants>
</PropertyGroup>
+
+ <!-- C# source generators -->
+ <ItemGroup Condition=" '$(DisableImplicitGodotGeneratorReferences)' != 'true' ">
+ <PackageReference Include="Godot.SourceGenerators" Version="$(PackageVersion_Godot_SourceGenerators)" />
+ </ItemGroup>
</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs
new file mode 100644
index 0000000000..5eaebc4474
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs
@@ -0,0 +1,15 @@
+namespace Godot.SourceGenerators.Sample
+{
+ partial class Bar : Godot.Object
+ {
+ }
+
+ // Foo in another file
+ partial class Foo
+ {
+ }
+
+ partial class NotSameNameAsFile : Godot.Object
+ {
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs
new file mode 100644
index 0000000000..21a5bfe560
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs
@@ -0,0 +1,11 @@
+namespace Godot.SourceGenerators.Sample
+{
+ partial class Foo : Godot.Object
+ {
+ }
+
+ // Foo again in the same file
+ partial class Foo
+ {
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj
new file mode 100644
index 0000000000..24f7909861
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj
@@ -0,0 +1,31 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.1</TargetFramework>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <!-- $(GodotProjectDir) would normally be defined by the Godot.NET.Sdk -->
+ <GodotProjectDir>$(MSBuildProjectDirectory)</GodotProjectDir>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <!-- The emitted files are not part of the compilation nor design.
+ They're only for peeking at the generated sources. Sometimes the
+ emitted files get corrupted, but that won't break anything. -->
+ <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
+ <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GeneratedFiles</CompilerGeneratedFilesOutputPath>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\glue\GodotSharp\GodotSharp\GodotSharp.csproj">
+ <Private>False</Private>
+ </ProjectReference>
+ <ProjectReference Include="..\Godot.SourceGenerators\Godot.SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
+ </ItemGroup>
+
+ <!-- This file is imported automatically when using PackageReference to
+ reference Godot.SourceGenerators, but not when using ProjectReference -->
+ <Import Project="..\Godot.SourceGenerators\Godot.SourceGenerators.props" />
+
+</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
new file mode 100644
index 0000000000..4867c986e6
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
@@ -0,0 +1,33 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Godot.SourceGenerators
+{
+ public static class Common
+ {
+ public static void ReportNonPartialGodotScriptClass(
+ GeneratorExecutionContext context,
+ ClassDeclarationSyntax cds, INamedTypeSymbol symbol
+ )
+ {
+ string message =
+ "Missing partial modifier on declaration of type '" +
+ $"{symbol.FullQualifiedName()}' which is a subclass of '{GodotClasses.Object}'";
+
+ string description = $"{message}. Subclasses of '{GodotClasses.Object}' must be " +
+ "declared with the partial modifier or annotated with the " +
+ $"attribute '{GodotClasses.DisableGodotGeneratorsAttr}'.";
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor(id: "GODOT-G0001",
+ title: message,
+ messageFormat: message,
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description),
+ cds.GetLocation(),
+ cds.SyntaxTree.FilePath));
+ }
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
new file mode 100644
index 0000000000..c3e74822d5
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
@@ -0,0 +1,86 @@
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Godot.SourceGenerators
+{
+ static class ExtensionMethods
+ {
+ public static bool TryGetGlobalAnalyzerProperty(
+ this GeneratorExecutionContext context, string property, out string? value
+ ) => context.AnalyzerConfigOptions.GlobalOptions
+ .TryGetValue("build_property." + property, out value);
+
+ private static bool InheritsFrom(this INamedTypeSymbol? symbol, string baseName)
+ {
+ if (symbol == null)
+ return false;
+
+ while (true)
+ {
+ if (symbol.ToString() == baseName)
+ {
+ return true;
+ }
+
+ if (symbol.BaseType != null)
+ {
+ symbol = symbol.BaseType;
+ continue;
+ }
+
+ break;
+ }
+
+ return false;
+ }
+
+ private static bool IsGodotScriptClass(
+ this ClassDeclarationSyntax cds, Compilation compilation,
+ out INamedTypeSymbol? symbol
+ )
+ {
+ var sm = compilation.GetSemanticModel(cds.SyntaxTree);
+
+ var classTypeSymbol = sm.GetDeclaredSymbol(cds);
+
+ if (classTypeSymbol?.BaseType == null
+ || !classTypeSymbol.BaseType.InheritsFrom(GodotClasses.Object))
+ {
+ symbol = null;
+ return false;
+ }
+
+ symbol = classTypeSymbol;
+ return true;
+ }
+
+ public static IEnumerable<(ClassDeclarationSyntax cds, INamedTypeSymbol symbol)> SelectGodotScriptClasses(
+ this IEnumerable<ClassDeclarationSyntax> source,
+ Compilation compilation
+ )
+ {
+ foreach (var cds in source)
+ {
+ if (cds.IsGodotScriptClass(compilation, out var symbol))
+ yield return (cds, symbol!);
+ }
+ }
+
+ public static bool IsPartial(this ClassDeclarationSyntax cds)
+ => cds.Modifiers.Any(SyntaxKind.PartialKeyword);
+
+ public static bool HasDisableGeneratorsAttribute(this INamedTypeSymbol symbol)
+ => symbol.GetAttributes().Any(attr =>
+ attr.AttributeClass?.ToString() == GodotClasses.DisableGodotGeneratorsAttr);
+
+ private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } =
+ SymbolDisplayFormat.FullyQualifiedFormat
+ .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted);
+
+ public static string FullQualifiedName(this INamedTypeSymbol symbol)
+ => symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatOmitGlobal);
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj
new file mode 100644
index 0000000000..224d7e5b5a
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj
@@ -0,0 +1,40 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <LangVersion>8.0</LangVersion>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+ <PropertyGroup>
+ <Description>Core C# source generator for Godot projects.</Description>
+ <Authors>Godot Engine contributors</Authors>
+
+ <PackageId>Godot.SourceGenerators</PackageId>
+ <Version>4.0.0</Version>
+ <PackageVersion>$(PackageVersion_Godot_SourceGenerators)</PackageVersion>
+ <RepositoryUrl>https://github.com/godotengine/godot/tree/master/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators</RepositoryUrl>
+ <PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
+ <PackageLicenseExpression>MIT</PackageLicenseExpression>
+
+ <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <!-- Generates a package at build -->
+ <IncludeBuildOutput>false</IncludeBuildOutput> <!-- Do not include the generator as a lib dependency -->
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" PrivateAssets="all" />
+ <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.1" PrivateAssets="all" />
+ </ItemGroup>
+ <ItemGroup>
+ <!-- Package the generator in the analyzer directory of the nuget package -->
+ <None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
+
+ <!-- Package the props file -->
+ <None Include="Godot.SourceGenerators.props" Pack="true" PackagePath="build" Visible="false" />
+ </ItemGroup>
+
+ <Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack">
+ <PropertyGroup>
+ <GodotSourceRootPath>$(SolutionDir)\..\..\..\..\</GodotSourceRootPath>
+ <GodotOutputDataDir>$(GodotSourceRootPath)\bin\GodotSharp\</GodotOutputDataDir>
+ </PropertyGroup>
+ <Copy SourceFiles="$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
+ </Target>
+</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props
new file mode 100644
index 0000000000..f9b47ad5b1
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props
@@ -0,0 +1,7 @@
+<Project>
+ <ItemGroup>
+ <!-- $(GodotProjectDir) is defined by Godot.NET.Sdk -->
+ <CompilerVisibleProperty Include="GodotProjectDir" />
+ <CompilerVisibleProperty Include="GodotScriptPathAttributeGenerator" />
+ </ItemGroup>
+</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
new file mode 100644
index 0000000000..29e41d155a
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
@@ -0,0 +1,9 @@
+namespace Godot.SourceGenerators
+{
+ public static class GodotClasses
+ {
+ public const string Object = "Godot.Object";
+ public const string DisableGodotGeneratorsAttr = "Godot.DisableGodotGeneratorsAttribute";
+ public const string AssemblyHasScriptsAttr = "Godot.AssemblyHasScriptsAttribute";
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
new file mode 100644
index 0000000000..150e59e414
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+
+namespace Godot.SourceGenerators
+{
+ [Generator]
+ public class ScriptPathAttributeGenerator : ISourceGenerator
+ {
+ public void Execute(GeneratorExecutionContext context)
+ {
+ if (context.TryGetGlobalAnalyzerProperty("GodotScriptPathAttributeGenerator", out string? toggle)
+ && toggle == "disabled")
+ {
+ return;
+ }
+
+ // NOTE: IsNullOrEmpty doesn't work well with nullable checks
+ // ReSharper disable once ReplaceWithStringIsNullOrEmpty
+ if (!context.TryGetGlobalAnalyzerProperty("GodotProjectDir", out string? godotProjectDir)
+ || godotProjectDir!.Length == 0)
+ {
+ throw new InvalidOperationException("Property 'GodotProjectDir' is null or empty.");
+ }
+
+ var godotClasses = context.Compilation.SyntaxTrees
+ .SelectMany(tree =>
+ tree.GetRoot().DescendantNodes()
+ .OfType<ClassDeclarationSyntax>()
+ // Ignore inner classes
+ .Where(cds => !(cds.Parent is ClassDeclarationSyntax))
+ .SelectGodotScriptClasses(context.Compilation)
+ // Report and skip non-partial classes
+ .Where(x =>
+ {
+ if (x.cds.IsPartial() || x.symbol.HasDisableGeneratorsAttribute())
+ return true;
+ Common.ReportNonPartialGodotScriptClass(context, x.cds, x.symbol);
+ return false;
+ })
+ )
+ // Ignore classes whose name is not the same as the file name
+ .Where(x => Path.GetFileNameWithoutExtension(x.cds.SyntaxTree.FilePath) == x.symbol.Name)
+ .GroupBy(x => x.symbol)
+ .ToDictionary(g => g.Key, g => g.Select(x => x.cds));
+
+ foreach (var godotClass in godotClasses)
+ {
+ VisitGodotScriptClass(context, godotProjectDir,
+ symbol: godotClass.Key,
+ classDeclarations: godotClass.Value);
+ }
+
+ if (godotClasses.Count <= 0)
+ return;
+
+ AddScriptTypesAssemblyAttr(context, godotClasses);
+ }
+
+ private static void VisitGodotScriptClass(
+ GeneratorExecutionContext context,
+ string godotProjectDir,
+ INamedTypeSymbol symbol,
+ IEnumerable<ClassDeclarationSyntax> classDeclarations
+ )
+ {
+ var attributesBuilder = new StringBuilder();
+
+ // Remember syntax trees for which we already added an attribute, to prevent unnecessary duplicates.
+ var attributedTrees = new List<SyntaxTree>();
+
+ foreach (var cds in classDeclarations)
+ {
+ if (attributedTrees.Contains(cds.SyntaxTree))
+ continue;
+
+ attributedTrees.Add(cds.SyntaxTree);
+
+ if (attributesBuilder.Length != 0)
+ attributesBuilder.Append("\n ");
+
+ attributesBuilder.Append(@"[ScriptPathAttribute(""res://");
+ attributesBuilder.Append(RelativeToDir(cds.SyntaxTree.FilePath, godotProjectDir));
+ attributesBuilder.Append(@""")]");
+ }
+
+ string classNs = symbol.ContainingNamespace.Name;
+ string className = symbol.Name;
+
+ var source = $@"using Godot;
+namespace {classNs}
+{{
+ {attributesBuilder}
+ partial class {className}
+ {{
+ }}
+}}
+";
+ context.AddSource(classNs + "." + className + "_ScriptPath_Generated",
+ SourceText.From(source, Encoding.UTF8));
+ }
+
+ private static void AddScriptTypesAssemblyAttr(GeneratorExecutionContext context,
+ Dictionary<INamedTypeSymbol, IEnumerable<ClassDeclarationSyntax>> godotClasses)
+ {
+ var sourceBuilder = new StringBuilder();
+
+ sourceBuilder.Append("[assembly:");
+ sourceBuilder.Append(GodotClasses.AssemblyHasScriptsAttr);
+ sourceBuilder.Append("(new System.Type[] {");
+
+ bool first = true;
+
+ foreach (var godotClass in godotClasses)
+ {
+ var qualifiedName = godotClass.Key.ToDisplayString(
+ NullableFlowState.NotNull, SymbolDisplayFormat.FullyQualifiedFormat);
+ if (!first)
+ sourceBuilder.Append(", ");
+ first = false;
+ sourceBuilder.Append("typeof(");
+ sourceBuilder.Append(qualifiedName);
+ sourceBuilder.Append(")");
+ }
+
+ sourceBuilder.Append("})]\n");
+
+ context.AddSource("AssemblyScriptTypes_Generated",
+ SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
+ }
+
+ public void Initialize(GeneratorInitializationContext context)
+ {
+ }
+
+ private static string RelativeToDir(string path, string dir)
+ {
+ // Make sure the directory ends with a path separator
+ dir = Path.Combine(dir, " ").TrimEnd();
+
+ if (Path.DirectorySeparatorChar == '\\')
+ dir = dir.Replace("/", "\\") + "\\";
+
+ var fullPath = new Uri(Path.GetFullPath(path), UriKind.Absolute);
+ var relRoot = new Uri(Path.GetFullPath(dir), UriKind.Absolute);
+
+ // MakeRelativeUri converts spaces to %20, hence why we need UnescapeDataString
+ return Uri.UnescapeDataString(relRoot.MakeRelativeUri(fullPath).ToString());
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
index 4e2c0f17cc..cdac9acb25 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
@@ -1,11 +1,5 @@
using System;
-using GodotTools.Core;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
using Microsoft.Build.Construction;
-using Microsoft.Build.Globbing;
namespace GodotTools.ProjectEditor
{
@@ -31,47 +25,6 @@ namespace GodotTools.ProjectEditor
return root != null ? new MSBuildProject(root) : null;
}
- private static List<string> GetAllFilesRecursive(string rootDirectory, string mask)
- {
- string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories);
-
- // We want relative paths
- for (int i = 0; i < files.Length; i++)
- {
- files[i] = files[i].RelativeToPath(rootDirectory);
- }
-
- return new List<string>(files);
- }
-
- // NOTE: Assumes auto-including items. Only used by the scripts metadata generator, which will be replaced with source generators in the future.
- public static IEnumerable<string> GetIncludeFiles(string projectPath, string itemType)
- {
- var excluded = new List<string>();
- var includedFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");
-
- var root = ProjectRootElement.Open(projectPath);
- Debug.Assert(root != null);
-
- foreach (var item in root.Items)
- {
- if (string.IsNullOrEmpty(item.Condition))
- continue;
-
- if (item.ItemType != itemType)
- continue;
-
- string normalizedRemove = item.Remove.NormalizePath();
-
- var glob = MSBuildGlob.Parse(normalizedRemove);
- excluded.AddRange(includedFiles.Where(includedFile => glob.IsMatch(includedFile)));
- }
-
- includedFiles.RemoveAll(f => excluded.Contains(f));
-
- return includedFiles;
- }
-
public static void MigrateToProjectSdksStyle(MSBuildProject project, string projectName)
{
var origRoot = project.Root;
diff --git a/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets b/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
index 1d382dcb43..aab2d73bdd 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
+++ b/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
@@ -3,7 +3,6 @@
<Target Name="SetPropertiesForGenerateGodotNupkgsVersions">
<PropertyGroup>
- <GodotNETSdkPackageVersionFile>$(SolutionDir)..\Godot.NET.Sdk\Godot.NET.Sdk\Godot.NET.Sdk_PackageVersion.txt</GodotNETSdkPackageVersionFile>
<GeneratedGodotNupkgsVersionsFile>$(IntermediateOutputPath)GodotNupkgsVersions.g.cs</GeneratedGodotNupkgsVersionsFile>
</PropertyGroup>
</Target>
@@ -18,13 +17,14 @@
</Target>
<Target Name="_GenerateGodotNupkgsVersionsFile"
DependsOnTargets="SetPropertiesForGenerateGodotNupkgsVersions"
- Inputs="$(MSBuildProjectFile);@(GodotNETSdkPackageVersionFile)"
+ Inputs="$(MSBuildProjectFile);$(MSBuildThisFileDirectory);$(MSBuildProjectFile)\..\..\..\SdkPackageVersions.props"
Outputs="$(GeneratedGodotNupkgsVersionsFile)">
<PropertyGroup>
<GenerateGodotNupkgsVersionsCode><![CDATA[
namespace $(RootNamespace) {
public class GeneratedGodotNupkgsVersions {
- public const string GodotNETSdk = "$([System.IO.File]::ReadAllText('$(GodotNETSdkPackageVersionFile)').Trim())"%3b
+ public const string GodotNETSdk = "$(PackageVersion_Godot_NET_Sdk)"%3b
+ public const string GodotSourceGenerators = "$(PackageVersion_Godot_SourceGenerators)"%3b
}
}
]]></GenerateGodotNupkgsVersionsCode>
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
index b96b0c8175..2b6f972529 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
@@ -218,43 +218,12 @@ namespace GodotTools.Build
Godot.GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message);
}
- GenerateEditorScriptMetadata();
-
if (GodotSharpEditor.Instance.SkipBuildBeforePlaying)
return true; // Requested play from an external editor/IDE which already built the project
return BuildProjectBlocking("Debug");
}
- // NOTE: This will be replaced with C# source generators in 4.0
- public static void GenerateEditorScriptMetadata()
- {
- string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor");
- string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player");
-
- CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
-
- if (!File.Exists(editorScriptsMetadataPath))
- return;
-
- try
- {
- File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath);
- }
- catch (IOException e)
- {
- throw new IOException("Failed to copy scripts metadata file.", innerException: e);
- }
- }
-
- // NOTE: This will be replaced with C# source generators in 4.0
- public static string GenerateExportedGameScriptMetadata(bool isDebug)
- {
- string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}");
- CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath);
- return scriptsMetadataPath;
- }
-
public static void Initialize()
{
// Build tool settings
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
index 708ec73454..ed69c2b833 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
@@ -43,8 +43,6 @@ namespace GodotTools.Build
GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message);
}
- BuildManager.GenerateEditorScriptMetadata();
-
if (!BuildManager.BuildProjectBlocking("Debug"))
return; // Build failed
@@ -74,8 +72,6 @@ namespace GodotTools.Build
GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message);
}
- BuildManager.GenerateEditorScriptMetadata();
-
if (!BuildManager.BuildProjectBlocking("Debug", targets: new[] {"Rebuild"}))
return; // Build failed
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index e2feb66e35..774c49e705 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -86,7 +86,7 @@ namespace GodotTools.Build
{
case BuildTool.DotnetCli:
{
- string dotnetCliPath = OS.PathWhich("dotnet");
+ string dotnetCliPath = FindBuildEngineOnUnix("dotnet");
if (!string.IsNullOrEmpty(dotnetCliPath))
return (dotnetCliPath, BuildTool.DotnetCli);
GD.PushError($"Cannot find executable for '{BuildManager.PropNameDotnetCli}'. Fallback to MSBuild from Mono.");
@@ -122,7 +122,11 @@ namespace GodotTools.Build
if (OS.IsMacOS)
{
result.Add("/Library/Frameworks/Mono.framework/Versions/Current/bin/");
+ result.Add("/opt/local/bin/");
result.Add("/usr/local/var/homebrew/linked/mono/bin/");
+ result.Add("/usr/local/bin/");
+ result.Add("/usr/local/bin/dotnet/");
+ result.Add("/usr/local/share/dotnet/");
}
result.Add("/opt/novell/mono/bin/");
@@ -181,7 +185,7 @@ namespace GodotTools.Build
var outputArray = new Godot.Collections.Array<string>();
int exitCode = Godot.OS.Execute(vsWherePath, vsWhereArgs,
- blocking: true, output: (Godot.Collections.Array)outputArray);
+ output: (Godot.Collections.Array)outputArray);
if (exitCode != 0)
return string.Empty;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs b/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
index 793ef7fd71..16dd1c8c6b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
@@ -290,7 +290,8 @@ namespace GodotTools.Build
private static readonly (string packageId, string packageVersion)[] PackagesToAdd =
{
- ("Godot.NET.Sdk", GeneratedGodotNupkgsVersions.GodotNETSdk)
+ ("Godot.NET.Sdk", GeneratedGodotNupkgsVersions.GodotNETSdk),
+ ("Godot.SourceGenerators", GeneratedGodotNupkgsVersions.GodotSourceGenerators),
};
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
index 1d800b8151..e43f10804d 100644
--- a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
@@ -1,11 +1,6 @@
using Godot;
using System;
-using System.Linq;
-using Godot.Collections;
-using GodotTools.Internals;
using GodotTools.ProjectEditor;
-using File = GodotTools.Utils.File;
-using Directory = GodotTools.Utils.Directory;
namespace GodotTools
{
@@ -23,86 +18,5 @@ namespace GodotTools
return string.Empty;
}
}
-
- private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-
- private static ulong ConvertToTimestamp(this DateTime value)
- {
- TimeSpan elapsedTime = value - Epoch;
- return (ulong)elapsedTime.TotalSeconds;
- }
-
- private static bool TryParseFileMetadata(string includeFile, ulong modifiedTime, out Dictionary fileMetadata)
- {
- fileMetadata = null;
-
- var parseError = ScriptClassParser.ParseFile(includeFile, out var classes, out string errorStr);
-
- if (parseError != Error.Ok)
- {
- GD.PushError($"Failed to determine namespace and class for script: {includeFile}. Parse error: {errorStr ?? parseError.ToString()}");
- return false;
- }
-
- string searchName = System.IO.Path.GetFileNameWithoutExtension(includeFile);
-
- var firstMatch = classes.FirstOrDefault(classDecl =>
- classDecl.BaseCount != 0 && // If it doesn't inherit anything, it can't be a Godot.Object.
- classDecl.SearchName == searchName // Filter by the name we're looking for
- );
-
- if (firstMatch == null)
- return false; // Not found
-
- fileMetadata = new Dictionary
- {
- ["modified_time"] = $"{modifiedTime}",
- ["class"] = new Dictionary
- {
- ["namespace"] = firstMatch.Namespace,
- ["class_name"] = firstMatch.Name,
- ["nested"] = firstMatch.Nested
- }
- };
-
- return true;
- }
-
- public static void GenerateScriptsMetadata(string projectPath, string outputPath)
- {
- var metadataDict = Internal.GetScriptsMetadataOrNothing().Duplicate();
-
- bool IsUpToDate(string includeFile, ulong modifiedTime)
- {
- return metadataDict.TryGetValue(includeFile, out var oldFileVar) &&
- ulong.TryParse(((Dictionary)oldFileVar)["modified_time"] as string,
- out ulong storedModifiedTime) && storedModifiedTime == modifiedTime;
- }
-
- var outdatedFiles = ProjectUtils.GetIncludeFiles(projectPath, "Compile")
- .Select(path => ("res://" + path).SimplifyGodotPath())
- .ToDictionary(path => path, path => File.GetLastWriteTime(path).ConvertToTimestamp())
- .Where(pair => !IsUpToDate(includeFile: pair.Key, modifiedTime: pair.Value))
- .ToArray();
-
- foreach (var pair in outdatedFiles)
- {
- metadataDict.Remove(pair.Key);
-
- string includeFile = pair.Key;
-
- if (TryParseFileMetadata(includeFile, modifiedTime: pair.Value, out var fileMetadata))
- metadataDict[includeFile] = fileMetadata;
- }
-
- string json = metadataDict.Count <= 0 ? "{}" : JSON.Print(metadataDict);
-
- string baseDir = outputPath.GetBaseDir();
-
- if (!Directory.Exists(baseDir))
- Directory.CreateDirectory(baseDir);
-
- File.WriteAllText(outputPath, json);
- }
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index 5bb8d444c2..5bb8d444c2 100755..100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index e9bb701562..270be8b6bf 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -157,9 +157,6 @@ namespace GodotTools.Export
string buildConfig = isDebug ? "ExportDebug" : "ExportRelease";
- string scriptsMetadataPath = BuildManager.GenerateExportedGameScriptMetadata(isDebug);
- AddFile(scriptsMetadataPath, scriptsMetadataPath);
-
if (!BuildManager.BuildProjectBlocking(buildConfig, platform: platform))
throw new Exception("Failed to build project");
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs b/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs
index 219b7a698a..93ef837a83 100755..100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs
@@ -27,7 +27,7 @@ namespace GodotTools.Export
{
var outputWrapper = new Godot.Collections.Array();
- int exitCode = Godot.OS.Execute("xcode-select", new string[] { "--print-path" }, blocking: true, output: outputWrapper);
+ int exitCode = Godot.OS.Execute("xcode-select", new string[] { "--print-path" }, output: outputWrapper);
if (exitCode == 0)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
index 16f91a0925..ed25cdaa63 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
@@ -104,7 +104,7 @@ namespace GodotTools.Ides.Rider
if (line >= 0)
{
args.Add("--line");
- args.Add(line.ToString());
+ args.Add((line + 1).ToString()); // https://github.com/JetBrains/godot-support/issues/61
}
args.Add(scriptPath);
try
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
index 7e5049e4b7..77370090ec 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
@@ -1,7 +1,5 @@
-using System;
using System.Runtime.CompilerServices;
using Godot;
-using Godot.Collections;
using GodotTools.IdeMessaging.Requests;
namespace GodotTools.Internals
@@ -42,9 +40,6 @@ namespace GodotTools.Internals
public static void EditorNodeShowScriptScreen() => internal_EditorNodeShowScriptScreen();
- public static Dictionary<string, object> GetScriptsMetadataOrNothing() =>
- internal_GetScriptsMetadataOrNothing(typeof(Dictionary<string, object>));
-
public static string MonoWindowsInstallRoot => internal_MonoWindowsInstallRoot();
public static void EditorRunPlay() => internal_EditorRunPlay();
@@ -101,9 +96,6 @@ namespace GodotTools.Internals
private static extern void internal_EditorNodeShowScriptScreen();
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern Dictionary<string, object> internal_GetScriptsMetadataOrNothing(Type dictType);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_MonoWindowsInstallRoot();
[MethodImpl(MethodImplOptions.InternalCall)]
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs
deleted file mode 100644
index c72a84c513..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using Godot;
-using Godot.Collections;
-
-namespace GodotTools.Internals
-{
- public static class ScriptClassParser
- {
- public class ClassDecl
- {
- public string Name { get; }
- public string Namespace { get; }
- public bool Nested { get; }
- public long BaseCount { get; }
-
- public string SearchName => Nested ?
- Name.Substring(Name.LastIndexOf(".", StringComparison.Ordinal) + 1) :
- Name;
-
- public ClassDecl(string name, string @namespace, bool nested, long baseCount)
- {
- Name = name;
- Namespace = @namespace;
- Nested = nested;
- BaseCount = baseCount;
- }
- }
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern Error internal_ParseFile(string filePath, Array<Dictionary> classes, out string errorStr);
-
- public static Error ParseFile(string filePath, out IEnumerable<ClassDecl> classes, out string errorStr)
- {
- var classesArray = new Array<Dictionary>();
- var error = internal_ParseFile(filePath, classesArray, out errorStr);
- if (error != Error.Ok)
- {
- classes = null;
- return error;
- }
-
- var classesList = new List<ClassDecl>();
-
- foreach (var classDeclDict in classesArray)
- {
- classesList.Add(new ClassDecl(
- (string)classDeclDict["name"],
- (string)classDeclDict["namespace"],
- (bool)classDeclDict["nested"],
- (long)classDeclDict["base_count"]
- ));
- }
-
- classes = classesList;
-
- return Error.Ok;
- }
- }
-}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index ad7e5d4200..b1875aec3f 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,6 +39,7 @@
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/string/ucaps.h"
+#include "main/main.h"
#include "../glue/cs_glue_version.gen.h"
#include "../godotsharp_defs.h"
@@ -181,7 +182,7 @@ static String snake_to_camel_case(const String &p_identifier, bool p_input_is_up
String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype) {
// Based on the version in EditorHelp
- if (p_bbcode.empty()) {
+ if (p_bbcode.is_empty()) {
return String();
}
@@ -365,7 +366,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append("</c>");
} else if (link_tag == "enum") {
StringName search_cname = !target_itype ? target_cname :
- StringName(target_itype->name + "." + (String)target_cname);
+ StringName(target_itype->name + "." + (String)target_cname);
const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(search_cname);
@@ -644,7 +645,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
}
int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
- CRASH_COND(p_ienum.constants.empty());
+ CRASH_COND(p_ienum.constants.is_empty());
const ConstantInterface &front_iconstant = p_ienum.constants.front()->get();
Vector<String> front_parts = front_iconstant.name.split("_", /* p_allow_empty: */ true);
@@ -783,6 +784,72 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
}
}
+void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) {
+ p_output.append("using System;\n\n");
+ p_output.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
+ // The class where we put the extensions doesn't matter, so just use "GD".
+ p_output.append(INDENT1 "public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n" INDENT1 "{");
+
+#define ARRAY_IS_EMPTY(m_type) \
+ p_output.append("\n" INDENT2 "/// <summary>\n"); \
+ p_output.append(INDENT2 "/// Returns true if this " #m_type " array is empty or doesn't exist.\n"); \
+ p_output.append(INDENT2 "/// </summary>\n"); \
+ p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array check.</param>\n"); \
+ p_output.append(INDENT2 "/// <returns>Whether or not the array is empty.</returns>\n"); \
+ p_output.append(INDENT2 "public static bool IsEmpty(this " #m_type "[] instance)\n"); \
+ p_output.append(INDENT2 OPEN_BLOCK); \
+ p_output.append(INDENT3 "return instance == null || instance.Length == 0;\n"); \
+ p_output.append(INDENT2 CLOSE_BLOCK);
+
+#define ARRAY_JOIN(m_type) \
+ p_output.append("\n" INDENT2 "/// <summary>\n"); \
+ p_output.append(INDENT2 "/// Converts this " #m_type " array to a string delimited by the given string.\n"); \
+ p_output.append(INDENT2 "/// </summary>\n"); \
+ p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \
+ p_output.append(INDENT2 "/// <param name=\"delimiter\">The delimiter to use between items.</param>\n"); \
+ p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \
+ p_output.append(INDENT2 "public static string Join(this " #m_type "[] instance, string delimiter = \", \")\n"); \
+ p_output.append(INDENT2 OPEN_BLOCK); \
+ p_output.append(INDENT3 "return String.Join(delimiter, instance);\n"); \
+ p_output.append(INDENT2 CLOSE_BLOCK);
+
+#define ARRAY_STRINGIFY(m_type) \
+ p_output.append("\n" INDENT2 "/// <summary>\n"); \
+ p_output.append(INDENT2 "/// Converts this " #m_type " array to a string with brackets.\n"); \
+ p_output.append(INDENT2 "/// </summary>\n"); \
+ p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \
+ p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \
+ p_output.append(INDENT2 "public static string Stringify(this " #m_type "[] instance)\n"); \
+ p_output.append(INDENT2 OPEN_BLOCK); \
+ p_output.append(INDENT3 "return \"[\" + instance.Join() + \"]\";\n"); \
+ p_output.append(INDENT2 CLOSE_BLOCK);
+
+#define ARRAY_ALL(m_type) \
+ ARRAY_IS_EMPTY(m_type) \
+ ARRAY_JOIN(m_type) \
+ ARRAY_STRINGIFY(m_type)
+
+ ARRAY_ALL(byte);
+ ARRAY_ALL(int);
+ ARRAY_ALL(long);
+ ARRAY_ALL(float);
+ ARRAY_ALL(double);
+ ARRAY_ALL(string);
+ ARRAY_ALL(Color);
+ ARRAY_ALL(Vector2);
+ ARRAY_ALL(Vector2i);
+ ARRAY_ALL(Vector3);
+ ARRAY_ALL(Vector3i);
+
+#undef ARRAY_ALL
+#undef ARRAY_IS_EMPTY
+#undef ARRAY_JOIN
+#undef ARRAY_STRINGIFY
+
+ p_output.append(INDENT1 CLOSE_BLOCK); // End of GD class.
+ p_output.append(CLOSE_BLOCK); // End of namespace.
+}
+
void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
// Constants (in partial GD class)
@@ -819,7 +886,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
p_output.append(";");
}
- if (!global_constants.empty()) {
+ if (!global_constants.is_empty()) {
p_output.append("\n");
}
@@ -830,7 +897,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
for (List<EnumInterface>::Element *E = global_enums.front(); E; E = E->next()) {
const EnumInterface &ienum = E->get();
- CRASH_COND(ienum.constants.empty());
+ CRASH_COND(ienum.constants.is_empty());
String enum_proxy_name = ienum.cname.operator String();
@@ -926,6 +993,19 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
compile_items.push_back(output_file);
}
+ // Generate source file for array extensions
+ {
+ StringBuilder extensions_source;
+ _generate_array_extensions(extensions_source);
+ String output_file = path::join(base_gen_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_extensions.cs");
+ Error save_err = _save_file(output_file, extensions_source);
+ if (save_err != OK) {
+ return save_err;
+ }
+
+ compile_items.push_back(output_file);
+ }
+
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) {
const TypeInterface &itype = E.get();
@@ -1283,7 +1363,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
for (const List<EnumInterface>::Element *E = itype.enums.front(); E; E = E->next()) {
const EnumInterface &ienum = E->get();
- ERR_FAIL_COND_V(ienum.constants.empty(), ERR_BUG);
+ ERR_FAIL_COND_V(ienum.constants.is_empty(), ERR_BUG);
output.append(MEMBER_BEGIN "public enum ");
output.append(ienum.cname.operator String());
@@ -1479,6 +1559,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
ERR_FAIL_COND_V_MSG(prop_itype->is_singleton, ERR_BUG,
"Property type is a singleton: '" + p_itype.name + "." + String(p_iprop.cname) + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(prop_itype->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Property '" + p_itype.name + "." + String(p_iprop.cname) + "' has type '" + prop_itype->name +
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
if (p_iprop.prop_doc && p_iprop.prop_doc->description.size()) {
String xml_summary = bbcode_to_xml(fix_doc_description(p_iprop.prop_doc->description), &p_itype);
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
@@ -1575,6 +1661,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
ERR_FAIL_COND_V_MSG(return_type->is_singleton, ERR_BUG,
"Method return type is a singleton: '" + p_itype.name + "." + p_imethod.name + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(return_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Method '" + p_itype.name + "." + p_imethod.name + "' has return type '" + return_type->name +
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
String method_bind_field = "__method_bind_" + itos(p_method_bind_count);
String arguments_sig;
@@ -1593,6 +1685,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
"Argument type is a singleton: '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Argument '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "' has type '" +
+ arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
if (iarg.default_argument.size()) {
CRASH_COND_MSG(!_arg_default_value_is_assignable_to_type(iarg.def_param_value, *arg_type),
"Invalid default value for parameter '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
@@ -1661,14 +1759,14 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
cs_in_statements += def_arg;
cs_in_statements += ";\n" INDENT3;
- icall_params += arg_type->cs_in.empty() ? arg_in : sformat(arg_type->cs_in, arg_in);
+ icall_params += arg_type->cs_in.is_empty() ? arg_in : sformat(arg_type->cs_in, arg_in);
// Apparently the name attribute must not include the @
String param_tag_name = iarg.name.begins_with("@") ? iarg.name.substr(1, iarg.name.length()) : iarg.name;
default_args_doc.append(MEMBER_BEGIN "/// <param name=\"" + param_tag_name + "\">If the parameter is null, then the default value is " + def_arg + "</param>");
} else {
- icall_params += arg_type->cs_in.empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name);
+ icall_params += arg_type->cs_in.is_empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name);
}
}
@@ -1714,7 +1812,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
}
if (p_imethod.is_deprecated) {
- if (p_imethod.deprecation_message.empty()) {
+ if (p_imethod.deprecation_message.is_empty()) {
WARN_PRINT("An empty deprecation message is discouraged. Method: '" + p_imethod.proxy_name + "'.");
}
@@ -1782,7 +1880,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (return_type->cname == name_cache.type_void) {
p_output.append(im_call + "(" + icall_params + ");\n");
- } else if (return_type->cs_out.empty()) {
+ } else if (return_type->cs_out.is_empty()) {
p_output.append("return " + im_call + "(" + icall_params + ");\n");
} else {
p_output.append(sformat(return_type->cs_out, im_call, icall_params, return_type->cs_type, return_type->im_type_out));
@@ -1806,7 +1904,13 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
- "Argument type is a singleton: '" + iarg.name + "' of signal" + p_itype.name + "." + p_isignal.name + "'.");
+ "Argument type is a singleton: '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "'.");
+
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Argument '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "' has type '" +
+ arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
// Add the current arguments to the signature
@@ -1839,7 +1943,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
}
if (p_isignal.is_deprecated) {
- if (p_isignal.deprecation_message.empty()) {
+ if (p_isignal.deprecation_message.is_empty()) {
WARN_PRINT("An empty deprecation message is discouraged. Signal: '" + p_isignal.proxy_name + "'.");
}
@@ -2263,7 +2367,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
}
if (!ret_void) {
- if (return_type->c_out.empty()) {
+ if (return_type->c_out.is_empty()) {
p_output.append("\treturn " C_LOCAL_RET ";\n");
} else if (return_type->ret_as_byref_arg) {
p_output.append(sformat(return_type->c_out, return_type->c_type_out, C_LOCAL_RET, return_type->name, "arg_ret"));
@@ -2585,7 +2689,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
int argc = method_info.arguments.size();
- if (method_info.name.empty()) {
+ if (method_info.name.is_empty()) {
continue;
}
@@ -2932,9 +3036,9 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
}
break;
case Variant::FLOAT:
-#ifndef REAL_T_IS_DOUBLE
- r_iarg.default_argument += "f";
-#endif
+ if (r_iarg.type.cname == name_cache.type_float) {
+ r_iarg.default_argument += "f";
+ }
break;
case Variant::STRING:
case Variant::STRING_NAME:
@@ -2947,23 +3051,32 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "\"" + r_iarg.default_argument + "\"";
}
break;
- case Variant::TRANSFORM:
- if (p_val.operator Transform() == Transform()) {
- r_iarg.default_argument.clear();
- }
- r_iarg.default_argument = "new %s(" + r_iarg.default_argument + ")";
+ case Variant::PLANE: {
+ Plane plane = p_val.operator Plane();
+ r_iarg.default_argument = "new Plane(new Vector3(" + plane.normal.operator String() + "), " + rtos(plane.d) + ")";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
- break;
- case Variant::PLANE:
- case Variant::AABB:
+ } break;
+ case Variant::AABB: {
+ AABB aabb = p_val.operator ::AABB();
+ r_iarg.default_argument = "new AABB(new Vector3(" + aabb.position.operator String() + "), new Vector3(" + aabb.position.operator String() + "))";
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
+ case Variant::RECT2: {
+ Rect2 rect = p_val.operator Rect2();
+ r_iarg.default_argument = "new Rect2(new Vector2(" + rect.position.operator String() + "), new Vector2(" + rect.position.operator String() + "))";
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
+ case Variant::RECT2I: {
+ Rect2i rect = p_val.operator Rect2i();
+ r_iarg.default_argument = "new Rect2i(new Vector2i(" + rect.position.operator String() + "), new Vector2i(" + rect.position.operator String() + "))";
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
case Variant::COLOR:
- r_iarg.default_argument = "new Color(1, 1, 1, 1)";
+ r_iarg.default_argument = "new %s(" + r_iarg.default_argument + ")";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
break;
case Variant::VECTOR2:
case Variant::VECTOR2I:
- case Variant::RECT2:
- case Variant::RECT2I:
case Variant::VECTOR3:
case Variant::VECTOR3I:
r_iarg.default_argument = "new %s" + r_iarg.default_argument;
@@ -3001,12 +3114,43 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "new %s {}";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
break;
- case Variant::TRANSFORM2D:
- case Variant::BASIS:
- case Variant::QUAT:
- r_iarg.default_argument = Variant::get_type_name(p_val.get_type()) + ".Identity";
+ case Variant::TRANSFORM2D: {
+ Transform2D transform = p_val.operator Transform2D();
+ if (transform == Transform2D()) {
+ r_iarg.default_argument = "Transform2D.Identity";
+ } else {
+ r_iarg.default_argument = "new Transform2D(new Vector2" + transform.elements[0].operator String() + ", new Vector2" + transform.elements[1].operator String() + ", new Vector2" + transform.elements[2].operator String() + ")";
+ }
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
- break;
+ } break;
+ case Variant::TRANSFORM: {
+ Transform transform = p_val.operator Transform();
+ if (transform == Transform()) {
+ r_iarg.default_argument = "Transform.Identity";
+ } else {
+ Basis basis = transform.basis;
+ r_iarg.default_argument = "new Transform(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ", new Vector3" + transform.origin.operator String() + ")";
+ }
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
+ case Variant::BASIS: {
+ Basis basis = p_val.operator Basis();
+ if (basis == Basis()) {
+ r_iarg.default_argument = "Basis.Identity";
+ } else {
+ r_iarg.default_argument = "new Basis(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ")";
+ }
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
+ case Variant::QUAT: {
+ Quat quat = p_val.operator Quat();
+ if (quat == Quat()) {
+ r_iarg.default_argument = "Quat.Identity";
+ } else {
+ r_iarg.default_argument = "new Quat" + quat.operator String();
+ }
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
case Variant::CALLABLE:
case Variant::SIGNAL:
CRASH_NOW_MSG("Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value.");
@@ -3546,6 +3690,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
if (!bindings_generator.initialized) {
ERR_PRINT("Failed to initialize the bindings generator");
+ Main::cleanup(true);
::exit(0);
}
@@ -3572,6 +3717,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
}
// Exit once done
+ Main::cleanup(true);
::exit(0);
}
}
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 0cc1bb5f46..876046176b 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -661,6 +661,7 @@ class BindingsGenerator {
Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output);
Error _generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output);
+ void _generate_array_extensions(StringBuilder &p_output);
void _generate_global_constants(StringBuilder &p_output);
Error _generate_glue_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, StringBuilder &p_output);
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
index 2d37b1306c..bbfba83e6f 100644
--- a/modules/mono/editor/code_completion.cpp
+++ b/modules/mono/editor/code_completion.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -150,7 +150,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
List<String> directories;
directories.push_back(dir_access->get_current_dir());
- while (!directories.empty()) {
+ while (!directories.is_empty()) {
dir_access->change_dir(directories.back()->get());
directories.pop_back();
diff --git a/modules/mono/editor/code_completion.h b/modules/mono/editor/code_completion.h
index e38768612b..7f7521672b 100644
--- a/modules/mono/editor/code_completion.h
+++ b/modules/mono/editor/code_completion.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index f9be19bbe2..21efd58938 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,7 +49,6 @@
#include "../utils/osx_utils.h"
#include "code_completion.h"
#include "godotsharp_export.h"
-#include "script_class_parser.h"
MonoString *godot_icall_GodotSharpDirs_ResDataDir() {
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_data_dir());
@@ -172,36 +171,6 @@ MonoBoolean godot_icall_EditorProgress_Step(MonoString *p_task, MonoString *p_st
return EditorNode::progress_task_step(task, state, p_step, (bool)p_force_refresh);
}
-int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObject *p_classes, MonoString **r_error_str) {
- *r_error_str = nullptr;
-
- String filepath = GDMonoMarshal::mono_string_to_godot(p_filepath);
-
- ScriptClassParser scp;
- Error err = scp.parse_file(filepath);
- if (err == OK) {
- Array classes = GDMonoMarshal::mono_object_to_variant(p_classes);
- const Vector<ScriptClassParser::ClassDecl> &class_decls = scp.get_classes();
-
- for (int i = 0; i < class_decls.size(); i++) {
- const ScriptClassParser::ClassDecl &classDecl = class_decls[i];
-
- Dictionary classDeclDict;
- classDeclDict["name"] = classDecl.name;
- classDeclDict["namespace"] = classDecl.namespace_;
- classDeclDict["nested"] = classDecl.nested;
- classDeclDict["base_count"] = classDecl.base.size();
- classes.push_back(classDeclDict);
- }
- } else {
- String error_str = scp.get_error();
- if (!error_str.empty()) {
- *r_error_str = GDMonoMarshal::mono_string_from_godot(error_str);
- }
- }
- return err;
-}
-
uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_assemblies,
MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_assembly_dependencies) {
Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_assemblies);
@@ -289,18 +258,6 @@ void godot_icall_Internal_EditorNodeShowScriptScreen() {
EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT);
}
-MonoObject *godot_icall_Internal_GetScriptsMetadataOrNothing(MonoReflectionType *p_dict_reftype) {
- Dictionary maybe_metadata = CSharpLanguage::get_singleton()->get_scripts_metadata_or_nothing();
-
- MonoType *dict_type = mono_reflection_type_get_type(p_dict_reftype);
-
- int type_encoding = mono_type_get_type(dict_type);
- MonoClass *type_class_raw = mono_class_from_mono_type(dict_type);
- GDMonoClass *type_class = GDMono::get_singleton()->get_class(type_class_raw);
-
- return GDMonoMarshal::variant_to_mono_object(maybe_metadata, ManagedType(type_encoding, type_class));
-}
-
MonoString *godot_icall_Internal_MonoWindowsInstallRoot() {
#ifdef WINDOWS_ENABLED
String install_root_dir = GDMono::get_singleton()->get_mono_reg_info().install_root_dir;
@@ -395,9 +352,6 @@ void register_editor_internal_calls() {
GDMonoUtils::add_internal_call("GodotTools.Internals.EditorProgress::internal_Dispose", godot_icall_EditorProgress_Dispose);
GDMonoUtils::add_internal_call("GodotTools.Internals.EditorProgress::internal_Step", godot_icall_EditorProgress_Step);
- // ScriptClassParser
- GDMonoUtils::add_internal_call("GodotTools.Internals.ScriptClassParser::internal_ParseFile", godot_icall_ScriptClassParser_ParseFile);
-
// ExportPlugin
GDMonoUtils::add_internal_call("GodotTools.Export.ExportPlugin::internal_GetExportedAssemblyDependencies", godot_icall_ExportPlugin_GetExportedAssemblyDependencies);
@@ -416,7 +370,6 @@ void register_editor_internal_calls() {
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorDebuggerNodeReloadScripts", godot_icall_Internal_EditorDebuggerNodeReloadScripts);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", godot_icall_Internal_ScriptEditorEdit);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", godot_icall_Internal_EditorNodeShowScriptScreen);
- GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", godot_icall_Internal_GetScriptsMetadataOrNothing);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", godot_icall_Internal_MonoWindowsInstallRoot);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", godot_icall_Internal_EditorRunPlay);
GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", godot_icall_Internal_EditorRunStop);
diff --git a/modules/mono/editor/editor_internal_calls.h b/modules/mono/editor/editor_internal_calls.h
index ef4e639161..24080cd867 100644
--- a/modules/mono/editor/editor_internal_calls.h
+++ b/modules/mono/editor/editor_internal_calls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index b006eed69f..4b858c0e82 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h
index 586d4e5a0c..0e9d689618 100644
--- a/modules/mono/editor/godotsharp_export.h
+++ b/modules/mono/editor/godotsharp_export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp
deleted file mode 100644
index 70940c279e..0000000000
--- a/modules/mono/editor/script_class_parser.cpp
+++ /dev/null
@@ -1,753 +0,0 @@
-/*************************************************************************/
-/* script_class_parser.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "script_class_parser.h"
-
-#include "core/os/os.h"
-#include "core/templates/map.h"
-
-#include "../utils/string_utils.h"
-
-const char *ScriptClassParser::token_names[ScriptClassParser::TK_MAX] = {
- "[",
- "]",
- "{",
- "}",
- ".",
- ":",
- ",",
- "Symbol",
- "Identifier",
- "String",
- "Number",
- "<",
- ">",
- "EOF",
- "Error"
-};
-
-String ScriptClassParser::get_token_name(ScriptClassParser::Token p_token) {
- ERR_FAIL_INDEX_V(p_token, TK_MAX, "<error>");
- return token_names[p_token];
-}
-
-ScriptClassParser::Token ScriptClassParser::get_token() {
- while (true) {
- switch (code[idx]) {
- case '\n': {
- line++;
- idx++;
- break;
- };
- case 0: {
- return TK_EOF;
- } break;
- case '{': {
- idx++;
- return TK_CURLY_BRACKET_OPEN;
- };
- case '}': {
- idx++;
- return TK_CURLY_BRACKET_CLOSE;
- };
- case '[': {
- idx++;
- return TK_BRACKET_OPEN;
- };
- case ']': {
- idx++;
- return TK_BRACKET_CLOSE;
- };
- case '<': {
- idx++;
- return TK_OP_LESS;
- };
- case '>': {
- idx++;
- return TK_OP_GREATER;
- };
- case ':': {
- idx++;
- return TK_COLON;
- };
- case ',': {
- idx++;
- return TK_COMMA;
- };
- case '.': {
- idx++;
- return TK_PERIOD;
- };
- case '#': {
- //compiler directive
- while (code[idx] != '\n' && code[idx] != 0) {
- idx++;
- }
- continue;
- } break;
- case '/': {
- switch (code[idx + 1]) {
- case '*': { // block comment
- idx += 2;
- while (true) {
- if (code[idx] == 0) {
- error_str = "Unterminated comment";
- error = true;
- return TK_ERROR;
- } else if (code[idx] == '*' && code[idx + 1] == '/') {
- idx += 2;
- break;
- } else if (code[idx] == '\n') {
- line++;
- }
-
- idx++;
- }
-
- } break;
- case '/': { // line comment skip
- while (code[idx] != '\n' && code[idx] != 0) {
- idx++;
- }
-
- } break;
- default: {
- value = "/";
- idx++;
- return TK_SYMBOL;
- }
- }
-
- continue; // a comment
- } break;
- case '\'':
- case '"': {
- bool verbatim = idx != 0 && code[idx - 1] == '@';
-
- char32_t begin_str = code[idx];
- idx++;
- String tk_string = String();
- while (true) {
- if (code[idx] == 0) {
- error_str = "Unterminated String";
- error = true;
- return TK_ERROR;
- } else if (code[idx] == begin_str) {
- if (verbatim && code[idx + 1] == '"') { // '""' is verbatim string's '\"'
- idx += 2; // skip next '"' as well
- continue;
- }
-
- idx += 1;
- break;
- } else if (code[idx] == '\\' && !verbatim) {
- //escaped characters...
- idx++;
- char32_t next = code[idx];
- if (next == 0) {
- error_str = "Unterminated String";
- error = true;
- return TK_ERROR;
- }
- char32_t res = 0;
-
- switch (next) {
- case 'b':
- res = 8;
- break;
- case 't':
- res = 9;
- break;
- case 'n':
- res = 10;
- break;
- case 'f':
- res = 12;
- break;
- case 'r':
- res = 13;
- break;
- case '\"':
- res = '\"';
- break;
- case '\\':
- res = '\\';
- break;
- default: {
- res = next;
- } break;
- }
-
- tk_string += res;
-
- } else {
- if (code[idx] == '\n') {
- line++;
- }
- tk_string += code[idx];
- }
- idx++;
- }
-
- value = tk_string;
-
- return TK_STRING;
- } break;
- default: {
- if (code[idx] <= 32) {
- idx++;
- break;
- }
-
- if ((code[idx] >= 33 && code[idx] <= 47) || (code[idx] >= 58 && code[idx] <= 63) || (code[idx] >= 91 && code[idx] <= 94) || code[idx] == 96 || (code[idx] >= 123 && code[idx] <= 127)) {
- value = String::chr(code[idx]);
- idx++;
- return TK_SYMBOL;
- }
-
- if (code[idx] == '-' || (code[idx] >= '0' && code[idx] <= '9')) {
- //a number
- const char32_t *rptr;
- double number = String::to_float(&code[idx], &rptr);
- idx += (rptr - &code[idx]);
- value = number;
- return TK_NUMBER;
-
- } else if ((code[idx] == '@' && code[idx + 1] != '"') || code[idx] == '_' || (code[idx] >= 'A' && code[idx] <= 'Z') || (code[idx] >= 'a' && code[idx] <= 'z') || code[idx] > 127) {
- String id;
-
- id += code[idx];
- idx++;
-
- while (code[idx] == '_' || (code[idx] >= 'A' && code[idx] <= 'Z') || (code[idx] >= 'a' && code[idx] <= 'z') || (code[idx] >= '0' && code[idx] <= '9') || code[idx] > 127) {
- id += code[idx];
- idx++;
- }
-
- value = id;
- return TK_IDENTIFIER;
- } else if (code[idx] == '@' && code[idx + 1] == '"') {
- // begin of verbatim string
- idx++;
- } else {
- error_str = "Unexpected character.";
- error = true;
- return TK_ERROR;
- }
- }
- }
- }
-}
-
-Error ScriptClassParser::_skip_generic_type_params() {
- Token tk;
-
- while (true) {
- tk = get_token();
-
- if (tk == TK_IDENTIFIER) {
- tk = get_token();
- // Type specifications can end with "?" to denote nullable types, such as IList<int?>
- if (tk == TK_SYMBOL) {
- tk = get_token();
- if (value.operator String() != "?") {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found unexpected symbol '" + value + "'";
- error = true;
- return ERR_PARSE_ERROR;
- }
- if (tk != TK_OP_GREATER && tk != TK_COMMA) {
- error_str = "Nullable type symbol '?' is only allowed after an identifier, but found " + get_token_name(tk) + " next.";
- error = true;
- return ERR_PARSE_ERROR;
- }
- }
-
- if (tk == TK_PERIOD) {
- while (true) {
- tk = get_token();
-
- if (tk != TK_IDENTIFIER) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- tk = get_token();
-
- if (tk != TK_PERIOD) {
- break;
- }
- }
- }
-
- if (tk == TK_OP_LESS) {
- Error err = _skip_generic_type_params();
- if (err) {
- return err;
- }
- tk = get_token();
- }
-
- if (tk == TK_OP_GREATER) {
- return OK;
- } else if (tk != TK_COMMA) {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- } else if (tk == TK_OP_LESS) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found " + get_token_name(TK_OP_LESS);
- error = true;
- return ERR_PARSE_ERROR;
- } else if (tk == TK_OP_GREATER) {
- return OK;
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- }
-}
-
-Error ScriptClassParser::_parse_type_full_name(String &r_full_name) {
- Token tk = get_token();
-
- if (tk != TK_IDENTIFIER) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- r_full_name += String(value);
-
- if (code[idx] == '<') {
- idx++;
-
- // We don't mind if the base is generic, but we skip it any ways since this information is not needed
- Error err = _skip_generic_type_params();
- if (err) {
- return err;
- }
- }
-
- if (code[idx] != '.') { // We only want to take the next token if it's a period
- return OK;
- }
-
- tk = get_token();
-
- CRASH_COND(tk != TK_PERIOD); // Assertion
-
- r_full_name += ".";
-
- return _parse_type_full_name(r_full_name);
-}
-
-Error ScriptClassParser::_parse_class_base(Vector<String> &r_base) {
- String name;
-
- Error err = _parse_type_full_name(name);
- if (err) {
- return err;
- }
-
- Token tk = get_token();
-
- if (tk == TK_COMMA) {
- err = _parse_class_base(r_base);
- if (err) {
- return err;
- }
- } else if (tk == TK_IDENTIFIER && String(value) == "where") {
- err = _parse_type_constraints();
- if (err) {
- return err;
- }
-
- // An open curly bracket was parsed by _parse_type_constraints, so we can exit
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- // we are finished when we hit the open curly bracket
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- r_base.push_back(name);
-
- return OK;
-}
-
-Error ScriptClassParser::_parse_type_constraints() {
- Token tk = get_token();
- if (tk != TK_IDENTIFIER) {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- tk = get_token();
- if (tk != TK_COLON) {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- while (true) {
- tk = get_token();
- if (tk == TK_IDENTIFIER) {
- if (String(value) == "where") {
- return _parse_type_constraints();
- }
-
- tk = get_token();
- if (tk == TK_PERIOD) {
- while (true) {
- tk = get_token();
-
- if (tk != TK_IDENTIFIER) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- tk = get_token();
-
- if (tk != TK_PERIOD) {
- break;
- }
- }
- }
- }
-
- if (tk == TK_COMMA) {
- continue;
- } else if (tk == TK_IDENTIFIER && String(value) == "where") {
- return _parse_type_constraints();
- } else if (tk == TK_SYMBOL && String(value) == "(") {
- tk = get_token();
- if (tk != TK_SYMBOL || String(value) != ")") {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- } else if (tk == TK_OP_LESS) {
- Error err = _skip_generic_type_params();
- if (err) {
- return err;
- }
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- return OK;
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- }
-}
-
-Error ScriptClassParser::_parse_namespace_name(String &r_name, int &r_curly_stack) {
- Token tk = get_token();
-
- if (tk == TK_IDENTIFIER) {
- r_name += String(value);
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- tk = get_token();
-
- if (tk == TK_PERIOD) {
- r_name += ".";
- return _parse_namespace_name(r_name, r_curly_stack);
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- r_curly_stack++;
- return OK;
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-}
-
-Error ScriptClassParser::parse(const String &p_code) {
- code = p_code;
- idx = 0;
- line = 0;
- error_str = String();
- error = false;
- value = Variant();
- classes.clear();
-
- Token tk = get_token();
-
- Map<int, NameDecl> name_stack;
- int curly_stack = 0;
- int type_curly_stack = 0;
-
- while (!error && tk != TK_EOF) {
- String identifier = value;
- if (tk == TK_IDENTIFIER && (identifier == "class" || identifier == "struct")) {
- bool is_class = identifier == "class";
-
- tk = get_token();
-
- if (tk == TK_IDENTIFIER) {
- String name = value;
- int at_level = curly_stack;
-
- ClassDecl class_decl;
-
- for (Map<int, NameDecl>::Element *E = name_stack.front(); E; E = E->next()) {
- const NameDecl &name_decl = E->value();
-
- if (name_decl.type == NameDecl::NAMESPACE_DECL) {
- if (E != name_stack.front()) {
- class_decl.namespace_ += ".";
- }
- class_decl.namespace_ += name_decl.name;
- } else {
- class_decl.name += name_decl.name + ".";
- }
- }
-
- class_decl.name += name;
- class_decl.nested = type_curly_stack > 0;
-
- bool generic = false;
-
- while (true) {
- tk = get_token();
-
- if (tk == TK_COLON) {
- Error err = _parse_class_base(class_decl.base);
- if (err) {
- return err;
- }
-
- curly_stack++;
- type_curly_stack++;
-
- break;
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- curly_stack++;
- type_curly_stack++;
- break;
- } else if (tk == TK_OP_LESS && !generic) {
- generic = true;
-
- Error err = _skip_generic_type_params();
- if (err) {
- return err;
- }
- } else if (tk == TK_IDENTIFIER && String(value) == "where") {
- Error err = _parse_type_constraints();
- if (err) {
- return err;
- }
-
- // An open curly bracket was parsed by _parse_type_constraints, so we can exit
- curly_stack++;
- type_curly_stack++;
- break;
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- }
-
- NameDecl name_decl;
- name_decl.name = name;
- name_decl.type = is_class ? NameDecl::CLASS_DECL : NameDecl::STRUCT_DECL;
- name_stack[at_level] = name_decl;
-
- if (is_class) {
- if (!generic) { // no generics, thanks
- classes.push_back(class_decl);
- } else if (OS::get_singleton()->is_stdout_verbose()) {
- String full_name = class_decl.namespace_;
- if (full_name.length()) {
- full_name += ".";
- }
- full_name += class_decl.name;
- OS::get_singleton()->print("Ignoring generic class declaration: %s\n", full_name.utf8().get_data());
- }
- }
- }
- } else if (tk == TK_IDENTIFIER && identifier == "namespace") {
- if (type_curly_stack > 0) {
- error_str = "Found namespace nested inside type.";
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- String name;
- int at_level = curly_stack;
-
- Error err = _parse_namespace_name(name, curly_stack);
- if (err) {
- return err;
- }
-
- NameDecl name_decl;
- name_decl.name = name;
- name_decl.type = NameDecl::NAMESPACE_DECL;
- name_stack[at_level] = name_decl;
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- curly_stack++;
- } else if (tk == TK_CURLY_BRACKET_CLOSE) {
- curly_stack--;
- if (name_stack.has(curly_stack)) {
- if (name_stack[curly_stack].type != NameDecl::NAMESPACE_DECL) {
- type_curly_stack--;
- }
- name_stack.erase(curly_stack);
- }
- }
-
- tk = get_token();
- }
-
- if (!error && tk == TK_EOF && curly_stack > 0) {
- error_str = "Reached EOF with missing close curly brackets.";
- error = true;
- }
-
- if (error) {
- return ERR_PARSE_ERROR;
- }
-
- return OK;
-}
-
-static String get_preprocessor_directive(const String &p_line, int p_from) {
- CRASH_COND(p_line[p_from] != '#');
- p_from++;
- int i = p_from;
- while (i < p_line.length() && (p_line[i] == '_' || (p_line[i] >= 'A' && p_line[i] <= 'Z') ||
- (p_line[i] >= 'a' && p_line[i] <= 'z') || p_line[i] > 127)) {
- i++;
- }
- return p_line.substr(p_from, i - p_from);
-}
-
-static void run_dummy_preprocessor(String &r_source, const String &p_filepath) {
- Vector<String> lines = r_source.split("\n", /* p_allow_empty: */ true);
-
- bool *include_lines = memnew_arr(bool, lines.size());
-
- int if_level = -1;
- Vector<bool> is_branch_being_compiled;
-
- for (int i = 0; i < lines.size(); i++) {
- const String &line = lines[i];
-
- const int line_len = line.length();
-
- int j;
- for (j = 0; j < line_len; j++) {
- if (line[j] != ' ' && line[j] != '\t') {
- if (line[j] == '#') {
- // First non-whitespace char of the line is '#'
- include_lines[i] = false;
-
- String directive = get_preprocessor_directive(line, j);
-
- if (directive == "if") {
- if_level++;
- is_branch_being_compiled.push_back(if_level == 0 || is_branch_being_compiled[if_level - 1]);
- } else if (directive == "elif") {
- ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#elif' directive. File: '" + p_filepath + "'.");
- is_branch_being_compiled.write[if_level] = false;
- } else if (directive == "else") {
- ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#else' directive. File: '" + p_filepath + "'.");
- is_branch_being_compiled.write[if_level] = false;
- } else if (directive == "endif") {
- ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#endif' directive. File: '" + p_filepath + "'.");
- is_branch_being_compiled.remove(if_level);
- if_level--;
- }
-
- break;
- } else {
- // First non-whitespace char of the line is not '#'
- include_lines[i] = if_level == -1 || is_branch_being_compiled[if_level];
- break;
- }
- }
- }
-
- if (j == line_len) {
- // Loop ended without finding a non-whitespace character.
- // Either the line was empty or it only contained whitespaces.
- include_lines[i] = if_level == -1 || is_branch_being_compiled[if_level];
- }
- }
-
- r_source.clear();
-
- // Custom join ignoring lines removed by the preprocessor
- for (int i = 0; i < lines.size(); i++) {
- if (i > 0 && include_lines[i - 1]) {
- r_source += '\n';
- }
-
- if (include_lines[i]) {
- r_source += lines[i];
- }
- }
-}
-
-Error ScriptClassParser::parse_file(const String &p_filepath) {
- String source;
-
- Error ferr = read_all_file_utf8(p_filepath, source);
-
- ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
- ferr == ERR_INVALID_DATA ?
- "File '" + p_filepath + "' contains invalid unicode (UTF-8), so it was not loaded."
- " Please ensure that scripts are saved in valid UTF-8 unicode." :
- "Failed to read file: '" + p_filepath + "'.");
-
- run_dummy_preprocessor(source, p_filepath);
-
- return parse(source);
-}
-
-String ScriptClassParser::get_error() {
- return error_str;
-}
-
-Vector<ScriptClassParser::ClassDecl> ScriptClassParser::get_classes() {
- return classes;
-}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs
new file mode 100644
index 0000000000..ef135da51a
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Godot
+{
+ [AttributeUsage(AttributeTargets.Assembly)]
+ public class AssemblyHasScriptsAttribute : Attribute
+ {
+ private readonly bool requiresLookup;
+ private readonly System.Type[] scriptTypes;
+
+ public AssemblyHasScriptsAttribute()
+ {
+ requiresLookup = true;
+ }
+
+ public AssemblyHasScriptsAttribute(System.Type[] scriptTypes)
+ {
+ requiresLookup = false;
+ this.scriptTypes = scriptTypes;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs
new file mode 100644
index 0000000000..ac6cffceb2
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Godot
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class DisableGodotGeneratorsAttribute : Attribute
+ {
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs
new file mode 100644
index 0000000000..12eb1035c3
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Godot
+{
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ public class ScriptPathAttribute : Attribute
+ {
+ private string path;
+
+ public ScriptPathAttribute(string path)
+ {
+ this.path = path;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index 90141928ca..0c333d06ef 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -104,7 +104,7 @@ namespace Godot
/// <summary>
/// The HSV hue of this color, on the range 0 to 1.
/// </summary>
- /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHsv"/>.</value>
+ /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHSV"/>.</value>
public float h
{
get
@@ -145,14 +145,14 @@ namespace Godot
}
set
{
- this = FromHsv(value, s, v, a);
+ this = FromHSV(value, s, v, a);
}
}
/// <summary>
/// The HSV saturation of this color, on the range 0 to 1.
/// </summary>
- /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHsv"/>.</value>
+ /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHSV"/>.</value>
public float s
{
get
@@ -166,14 +166,14 @@ namespace Godot
}
set
{
- this = FromHsv(h, value, v, a);
+ this = FromHSV(h, value, v, a);
}
}
/// <summary>
/// The HSV value (brightness) of this color, on the range 0 to 1.
/// </summary>
- /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHsv"/>.</value>
+ /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHSV"/>.</value>
public float v
{
get
@@ -182,7 +182,7 @@ namespace Godot
}
set
{
- this = FromHsv(h, s, value, a);
+ this = FromHSV(h, s, value, a);
}
}
@@ -455,7 +455,7 @@ namespace Godot
/// </summary>
/// <param name="includeAlpha">Whether or not to include alpha. If false, the color is RGB instead of RGBA.</param>
/// <returns>A string for the HTML hexadecimal representation of this color.</returns>
- public string ToHtml(bool includeAlpha = true)
+ public string ToHTML(bool includeAlpha = true)
{
var txt = string.Empty;
@@ -532,18 +532,50 @@ namespace Godot
}
/// <summary>
+ /// Constructs a color either from an HTML color code or from a
+ /// standardized color name. Supported
+ /// color names are the same as the <see cref="Colors"/> constants.
+ /// </summary>
+ /// <param name="code">The HTML color code or color name to construct from.</param>
+ public Color(string code)
+ {
+ if (HtmlIsValid(code))
+ {
+ this = FromHTML(code);
+ }
+ else
+ {
+ this = Named(code);
+ }
+ }
+
+ /// <summary>
+ /// Constructs a color either from an HTML color code or from a
+ /// standardized color name, with `alpha` on the range of 0 to 1. Supported
+ /// color names are the same as the <see cref="Colors"/> constants.
+ /// </summary>
+ /// <param name="code">The HTML color code or color name to construct from.</param>
+ /// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param>
+ public Color(string code, float alpha)
+ {
+ this = new Color(code);
+ a = alpha;
+ }
+
+ /// <summary>
/// Constructs a color from the HTML hexadecimal color string in RGBA format.
/// </summary>
/// <param name="rgba">A string for the HTML hexadecimal representation of this color.</param>
- public Color(string rgba)
+ private static Color FromHTML(string rgba)
{
+ Color c;
if (rgba.Length == 0)
{
- r = 0f;
- g = 0f;
- b = 0f;
- a = 1.0f;
- return;
+ c.r = 0f;
+ c.g = 0f;
+ c.b = 0f;
+ c.a = 1.0f;
+ return c;
}
if (rgba[0] == '#')
@@ -577,47 +609,48 @@ namespace Godot
throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba);
}
- a = 1.0f;
+ c.a = 1.0f;
if (isShorthand)
{
- r = ParseCol4(rgba, 0) / 15f;
- g = ParseCol4(rgba, 1) / 15f;
- b = ParseCol4(rgba, 2) / 15f;
+ c.r = ParseCol4(rgba, 0) / 15f;
+ c.g = ParseCol4(rgba, 1) / 15f;
+ c.b = ParseCol4(rgba, 2) / 15f;
if (alpha)
{
- a = ParseCol4(rgba, 3) / 15f;
+ c.a = ParseCol4(rgba, 3) / 15f;
}
}
else
{
- r = ParseCol8(rgba, 0) / 255f;
- g = ParseCol8(rgba, 2) / 255f;
- b = ParseCol8(rgba, 4) / 255f;
+ c.r = ParseCol8(rgba, 0) / 255f;
+ c.g = ParseCol8(rgba, 2) / 255f;
+ c.b = ParseCol8(rgba, 4) / 255f;
if (alpha)
{
- a = ParseCol8(rgba, 6) / 255f;
+ c.a = ParseCol8(rgba, 6) / 255f;
}
}
- if (r < 0)
+ if (c.r < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba);
}
- if (g < 0)
+ if (c.g < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba);
}
- if (b < 0)
+ if (c.b < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba);
}
- if (a < 0)
+ if (c.a < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba);
}
+ return c;
}
/// <summary>
@@ -640,9 +673,8 @@ namespace Godot
/// the constants defined in <see cref="Colors"/>.
/// </summary>
/// <param name="name">The name of the color.</param>
- /// <param name="alpha">The alpha (transparency) component represented on the range of 0 to 1. Default: 1.</param>
/// <returns>The constructed color.</returns>
- public static Color ColorN(string name, float alpha = 1f)
+ private static Color Named(string name)
{
name = name.Replace(" ", String.Empty);
name = name.Replace("-", String.Empty);
@@ -656,9 +688,7 @@ namespace Godot
throw new ArgumentOutOfRangeException($"Invalid Color Name: {name}");
}
- Color color = Colors.namedColors[name];
- color.a = alpha;
- return color;
+ return Colors.namedColors[name];
}
/// <summary>
@@ -671,11 +701,11 @@ namespace Godot
/// <param name="value">The HSV value (brightness), typically on the range of 0 to 1.</param>
/// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param>
/// <returns>The constructed color.</returns>
- public static Color FromHsv(float hue, float saturation, float value, float alpha = 1.0f)
+ public static Color FromHSV(float hue, float saturation, float value, float alpha = 1.0f)
{
if (saturation == 0)
{
- // acp_hromatic (grey)
+ // Achromatic (grey)
return new Color(value, value, value, alpha);
}
@@ -715,7 +745,7 @@ namespace Godot
/// <param name="hue">Output parameter for the HSV hue.</param>
/// <param name="saturation">Output parameter for the HSV saturation.</param>
/// <param name="value">Output parameter for the HSV value.</param>
- public void ToHsv(out float hue, out float saturation, out float value)
+ public void ToHSV(out float hue, out float saturation, out float value)
{
float max = (float)Mathf.Max(r, Mathf.Max(g, b));
float min = (float)Mathf.Min(r, Mathf.Min(g, b));
@@ -803,7 +833,8 @@ namespace Godot
}
// Check if each hex digit is valid.
- for (int i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++)
+ {
if (ParseCol4(color, i) == -1)
{
return false;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
new file mode 100644
index 0000000000..763f470504
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
@@ -0,0 +1,27 @@
+namespace Godot
+{
+ public partial class PackedScene
+ {
+ /// <summary>
+ /// Instantiates the scene's node hierarchy, erroring on failure.
+ /// Triggers child scene instantiation(s). Triggers a
+ /// `Node.NotificationInstanced` notification on the root node.
+ /// </summary>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of Node.</typeparam>
+ public T Instance<T>(PackedScene.GenEditState editState = (PackedScene.GenEditState)0) where T : class
+ {
+ return (T)(object)Instance(editState);
+ }
+
+ /// <summary>
+ /// Instantiates the scene's node hierarchy, returning null on failure.
+ /// Triggers child scene instantiation(s). Triggers a
+ /// `Node.NotificationInstanced` notification on the root node.
+ /// </summary>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of Node.</typeparam>
+ public T InstanceOrNull<T>(PackedScene.GenEditState editState = (PackedScene.GenEditState)0) where T : class
+ {
+ return Instance(editState) as T;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
index 5f64c09a89..74fa05d1fd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
@@ -2,7 +2,7 @@ namespace Godot
{
public static partial class ResourceLoader
{
- public static T Load<T>(string path, string typeHint = null, bool noCache = false) where T : class
+ public static T Load<T>(string path, string typeHint = null, CacheMode noCache = CacheMode.Reuse) where T : class
{
return (T)(object)Load(path, typeHint, noCache);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs
new file mode 100644
index 0000000000..702a6c76ba
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Godot
+{
+ public static partial class GD
+ {
+ /// <summary>
+ /// Fires when an unhandled exception occurs, regardless of project settings.
+ /// </summary>
+ public static event EventHandler<UnhandledExceptionArgs> UnhandledException;
+
+ private static void OnUnhandledException(Exception e)
+ {
+ UnhandledException?.Invoke(null, new UnhandledExceptionArgs(e));
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index 6eecc262d6..c3f372d415 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -618,10 +618,10 @@ namespace Godot
/// This can also be used to round a floating point
/// number to an arbitrary number of decimals.
/// </summary>
- /// <param name="s">The value to stepify.</param>
+ /// <param name="s">The value to snap.</param>
/// <param name="step">The step size to snap to.</param>
/// <returns></returns>
- public static real_t Stepify(real_t s, real_t step)
+ public static real_t Snapped(real_t s, real_t step)
{
if (step != 0f)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
index f7703c77cc..868c3536fe 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
@@ -52,7 +52,7 @@ namespace Godot
}
/// <summary>
- /// The area of this rect.
+ /// The area of this Rect2.
/// </summary>
/// <value>Equivalent to <see cref="GetArea()"/>.</value>
public real_t Area
@@ -64,7 +64,7 @@ namespace Godot
/// Returns a Rect2 with equivalent position and size, modified so that
/// the top-left corner is the origin and width and height are positive.
/// </summary>
- /// <returns>The modified rect.</returns>
+ /// <returns>The modified Rect2.</returns>
public Rect2 Abs()
{
Vector2 end = End;
@@ -74,10 +74,11 @@ namespace Godot
/// <summary>
/// Returns the intersection of this Rect2 and `b`.
+ /// If the rectangles do not intersect, an empty Rect2 is returned.
/// </summary>
- /// <param name="b">The other rect.</param>
- /// <returns>The clipped rect.</returns>
- public Rect2 Clip(Rect2 b)
+ /// <param name="b">The other Rect2.</param>
+ /// <returns>The intersection of this Rect2 and `b`, or an empty Rect2 if they do not intersect.</returns>
+ public Rect2 Intersection(Rect2 b)
{
var newRect = b;
@@ -101,8 +102,8 @@ namespace Godot
/// <summary>
/// Returns true if this Rect2 completely encloses another one.
/// </summary>
- /// <param name="b">The other rect that may be enclosed.</param>
- /// <returns>A bool for whether or not this rect encloses `b`.</returns>
+ /// <param name="b">The other Rect2 that may be enclosed.</param>
+ /// <returns>A bool for whether or not this Rect2 encloses `b`.</returns>
public bool Encloses(Rect2 b)
{
return b._position.x >= _position.x && b._position.y >= _position.y &&
@@ -114,7 +115,7 @@ namespace Godot
/// Returns this Rect2 expanded to include a given point.
/// </summary>
/// <param name="to">The point to include.</param>
- /// <returns>The expanded rect.</returns>
+ /// <returns>The expanded Rect2.</returns>
public Rect2 Expand(Vector2 to)
{
var expanded = this;
@@ -156,10 +157,10 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown a given amount of units towards all the sides.
+ /// Returns a copy of the Rect2 grown by the specified amount on all sides.
/// </summary>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown rect.</returns>
+ /// <returns>The grown Rect2.</returns>
public Rect2 Grow(real_t by)
{
var g = this;
@@ -173,13 +174,13 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown a given amount of units towards each direction individually.
+ /// Returns a copy of the Rect2 grown by the specified amount on each side individually.
/// </summary>
- /// <param name="left">The amount to grow by on the left.</param>
- /// <param name="top">The amount to grow by on the top.</param>
- /// <param name="right">The amount to grow by on the right.</param>
- /// <param name="bottom">The amount to grow by on the bottom.</param>
- /// <returns>The grown rect.</returns>
+ /// <param name="left">The amount to grow by on the left side.</param>
+ /// <param name="top">The amount to grow by on the top side.</param>
+ /// <param name="right">The amount to grow by on the right side.</param>
+ /// <param name="bottom">The amount to grow by on the bottom side.</param>
+ /// <returns>The grown Rect2.</returns>
public Rect2 GrowIndividual(real_t left, real_t top, real_t right, real_t bottom)
{
var g = this;
@@ -193,19 +194,19 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown a given amount of units towards the <see cref="Margin"/> direction.
+ /// Returns a copy of the Rect2 grown by the specified amount on the specified Side.
/// </summary>
- /// <param name="margin">The direction to grow in.</param>
+ /// <param name="side">The side to grow.</param>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown rect.</returns>
- public Rect2 GrowMargin(Margin margin, real_t by)
+ /// <returns>The grown Rect2.</returns>
+ public Rect2 GrowSide(Side side, real_t by)
{
var g = this;
- g = g.GrowIndividual(Margin.Left == margin ? by : 0,
- Margin.Top == margin ? by : 0,
- Margin.Right == margin ? by : 0,
- Margin.Bottom == margin ? by : 0);
+ g = g.GrowIndividual(Side.Left == side ? by : 0,
+ Side.Top == side ? by : 0,
+ Side.Right == side ? by : 0,
+ Side.Bottom == side ? by : 0);
return g;
}
@@ -213,7 +214,7 @@ namespace Godot
/// <summary>
/// Returns true if the Rect2 is flat or empty, or false otherwise.
/// </summary>
- /// <returns>A bool for whether or not the rect has area.</returns>
+ /// <returns>A bool for whether or not the Rect2 has area.</returns>
public bool HasNoArea()
{
return _size.x <= 0 || _size.y <= 0;
@@ -223,7 +224,7 @@ namespace Godot
/// Returns true if the Rect2 contains a point, or false otherwise.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <returns>A bool for whether or not the rect contains `point`.</returns>
+ /// <returns>A bool for whether or not the Rect2 contains `point`.</returns>
public bool HasPoint(Vector2 point)
{
if (point.x < _position.x)
@@ -246,7 +247,7 @@ namespace Godot
/// If `includeBorders` is true, they will also be considered overlapping
/// if their borders touch, even without intersection.
/// </summary>
- /// <param name="b">The other rect to check for intersections with.</param>
+ /// <param name="b">The other Rect2 to check for intersections with.</param>
/// <param name="includeBorders">Whether or not to consider borders.</param>
/// <returns>A bool for whether or not they are intersecting.</returns>
public bool Intersects(Rect2 b, bool includeBorders = false)
@@ -296,8 +297,8 @@ namespace Godot
/// <summary>
/// Returns a larger Rect2 that contains this Rect2 and `b`.
/// </summary>
- /// <param name="b">The other rect.</param>
- /// <returns>The merged rect.</returns>
+ /// <param name="b">The other Rect2.</param>
+ /// <returns>The merged Rect2.</returns>
public Rect2 Merge(Rect2 b)
{
Rect2 newRect;
@@ -387,11 +388,11 @@ namespace Godot
}
/// <summary>
- /// Returns true if this rect and `other` are approximately equal, by running
+ /// Returns true if this Rect2 and `other` are approximately equal, by running
/// <see cref="Vector2.IsEqualApprox(Vector2)"/> on each component.
/// </summary>
- /// <param name="other">The other rect to compare.</param>
- /// <returns>Whether or not the rects are approximately equal.</returns>
+ /// <param name="other">The other Rect2 to compare.</param>
+ /// <returns>Whether or not the Rect2s are approximately equal.</returns>
public bool IsEqualApprox(Rect2 other)
{
return _position.IsEqualApprox(other._position) && _size.IsEqualApprox(other.Size);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
index 8f71c00d76..c27af74866 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
@@ -47,7 +47,7 @@ namespace Godot
}
/// <summary>
- /// The area of this rect.
+ /// The area of this Rect2i.
/// </summary>
/// <value>Equivalent to <see cref="GetArea()"/>.</value>
public int Area
@@ -59,7 +59,7 @@ namespace Godot
/// Returns a Rect2i with equivalent position and size, modified so that
/// the top-left corner is the origin and width and height are positive.
/// </summary>
- /// <returns>The modified rect.</returns>
+ /// <returns>The modified Rect2i.</returns>
public Rect2i Abs()
{
Vector2i end = End;
@@ -69,10 +69,11 @@ namespace Godot
/// <summary>
/// Returns the intersection of this Rect2i and `b`.
+ /// If the rectangles do not intersect, an empty Rect2i is returned.
/// </summary>
- /// <param name="b">The other rect.</param>
- /// <returns>The clipped rect.</returns>
- public Rect2i Clip(Rect2i b)
+ /// <param name="b">The other Rect2i.</param>
+ /// <returns>The intersection of this Rect2i and `b`, or an empty Rect2i if they do not intersect.</returns>
+ public Rect2i Intersection(Rect2i b)
{
var newRect = b;
@@ -96,8 +97,8 @@ namespace Godot
/// <summary>
/// Returns true if this Rect2i completely encloses another one.
/// </summary>
- /// <param name="b">The other rect that may be enclosed.</param>
- /// <returns>A bool for whether or not this rect encloses `b`.</returns>
+ /// <param name="b">The other Rect2i that may be enclosed.</param>
+ /// <returns>A bool for whether or not this Rect2i encloses `b`.</returns>
public bool Encloses(Rect2i b)
{
return b._position.x >= _position.x && b._position.y >= _position.y &&
@@ -109,7 +110,7 @@ namespace Godot
/// Returns this Rect2i expanded to include a given point.
/// </summary>
/// <param name="to">The point to include.</param>
- /// <returns>The expanded rect.</returns>
+ /// <returns>The expanded Rect2i.</returns>
public Rect2i Expand(Vector2i to)
{
var expanded = this;
@@ -151,10 +152,10 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown a given amount of units towards all the sides.
+ /// Returns a copy of the Rect2i grown by the specified amount on all sides.
/// </summary>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown rect.</returns>
+ /// <returns>The grown Rect2i.</returns>
public Rect2i Grow(int by)
{
var g = this;
@@ -168,13 +169,13 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown a given amount of units towards each direction individually.
+ /// Returns a copy of the Rect2i grown by the specified amount on each side individually.
/// </summary>
- /// <param name="left">The amount to grow by on the left.</param>
- /// <param name="top">The amount to grow by on the top.</param>
- /// <param name="right">The amount to grow by on the right.</param>
- /// <param name="bottom">The amount to grow by on the bottom.</param>
- /// <returns>The grown rect.</returns>
+ /// <param name="left">The amount to grow by on the left side.</param>
+ /// <param name="top">The amount to grow by on the top side.</param>
+ /// <param name="right">The amount to grow by on the right side.</param>
+ /// <param name="bottom">The amount to grow by on the bottom side.</param>
+ /// <returns>The grown Rect2i.</returns>
public Rect2i GrowIndividual(int left, int top, int right, int bottom)
{
var g = this;
@@ -188,37 +189,37 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown a given amount of units towards the <see cref="Margin"/> direction.
+ /// Returns a copy of the Rect2i grown by the specified amount on the specified Side.
/// </summary>
- /// <param name="margin">The direction to grow in.</param>
+ /// <param name="side">The side to grow.</param>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown rect.</returns>
- public Rect2i GrowMargin(Margin margin, int by)
+ /// <returns>The grown Rect2i.</returns>
+ public Rect2i GrowSide(Side side, int by)
{
var g = this;
- g = g.GrowIndividual(Margin.Left == margin ? by : 0,
- Margin.Top == margin ? by : 0,
- Margin.Right == margin ? by : 0,
- Margin.Bottom == margin ? by : 0);
+ g = g.GrowIndividual(Side.Left == side ? by : 0,
+ Side.Top == side ? by : 0,
+ Side.Right == side ? by : 0,
+ Side.Bottom == side ? by : 0);
return g;
}
/// <summary>
- /// Returns true if the Rect2 is flat or empty, or false otherwise.
+ /// Returns true if the Rect2i is flat or empty, or false otherwise.
/// </summary>
- /// <returns>A bool for whether or not the rect has area.</returns>
+ /// <returns>A bool for whether or not the Rect2i has area.</returns>
public bool HasNoArea()
{
return _size.x <= 0 || _size.y <= 0;
}
/// <summary>
- /// Returns true if the Rect2 contains a point, or false otherwise.
+ /// Returns true if the Rect2i contains a point, or false otherwise.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <returns>A bool for whether or not the rect contains `point`.</returns>
+ /// <returns>A bool for whether or not the Rect2i contains `point`.</returns>
public bool HasPoint(Vector2i point)
{
if (point.x < _position.x)
@@ -241,7 +242,7 @@ namespace Godot
/// If `includeBorders` is true, they will also be considered overlapping
/// if their borders touch, even without intersection.
/// </summary>
- /// <param name="b">The other rect to check for intersections with.</param>
+ /// <param name="b">The other Rect2i to check for intersections with.</param>
/// <param name="includeBorders">Whether or not to consider borders.</param>
/// <returns>A bool for whether or not they are intersecting.</returns>
public bool Intersects(Rect2i b, bool includeBorders = false)
@@ -273,10 +274,10 @@ namespace Godot
}
/// <summary>
- /// Returns a larger Rect2i that contains this Rect2 and `b`.
+ /// Returns a larger Rect2i that contains this Rect2i and `b`.
/// </summary>
- /// <param name="b">The other rect.</param>
- /// <returns>The merged rect.</returns>
+ /// <param name="b">The other Rect2i.</param>
+ /// <returns>The merged Rect2i.</returns>
public Rect2i Merge(Rect2i b)
{
Rect2i newRect;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index 0700f197ff..98efa89ef0 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -97,6 +97,36 @@ namespace Godot
return b;
}
+ /// <summary>
+ /// Converts a string containing a binary number into an integer.
+ /// Binary strings can either be prefixed with `0b` or not,
+ /// and they can also start with a `-` before the optional prefix.
+ /// </summary>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The converted string.</returns>
+ public static int BinToInt(this string instance)
+ {
+ if (instance.Length == 0)
+ {
+ return 0;
+ }
+
+ int sign = 1;
+
+ if (instance[0] == '-')
+ {
+ sign = -1;
+ instance = instance.Substring(1);
+ }
+
+ if (instance.StartsWith("0b"))
+ {
+ instance = instance.Substring(2);
+ }
+
+ return sign * Convert.ToInt32(instance, 2);;
+ }
+
// <summary>
// Return the amount of substrings in string.
// </summary>
@@ -432,24 +462,24 @@ namespace Godot
}
// <summary>
- // Hash the string and return a 32 bits integer.
+ // Hash the string and return a 32 bits unsigned integer.
// </summary>
- public static int Hash(this string instance)
+ public static uint Hash(this string instance)
{
- int index = 0;
- int hashv = 5381;
- int c;
+ uint hash = 5381;
- while ((c = instance[index++]) != 0)
- hashv = (hashv << 5) + hashv + c; // hash * 33 + c
+ foreach(uint c in instance)
+ {
+ hash = (hash << 5) + hash + c; // hash * 33 + c
+ }
- return hashv;
+ return hash;
}
/// <summary>
/// Returns a hexadecimal representation of this byte as a string.
/// </summary>
- /// <param name="bytes">The byte to encode.</param>
+ /// <param name="b">The byte to encode.</param>
/// <returns>The hexadecimal representation of this byte.</returns>
internal static string HexEncode(this byte b)
{
@@ -493,11 +523,20 @@ namespace Godot
return ret;
}
- // <summary>
- // Convert a string containing an hexadecimal number into an int.
- // </summary>
+ /// <summary>
+ /// Converts a string containing a hexadecimal number into an integer.
+ /// Hexadecimal strings can either be prefixed with `0x` or not,
+ /// and they can also start with a `-` before the optional prefix.
+ /// </summary>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The converted string.</returns>
public static int HexToInt(this string instance)
{
+ if (instance.Length == 0)
+ {
+ return 0;
+ }
+
int sign = 1;
if (instance[0] == '-')
@@ -506,10 +545,12 @@ namespace Godot
instance = instance.Substring(1);
}
- if (!instance.StartsWith("0x"))
- return 0;
+ if (instance.StartsWith("0x"))
+ {
+ instance = instance.Substring(2);
+ }
- return sign * int.Parse(instance.Substring(2), NumberStyles.HexNumber);
+ return sign * int.Parse(instance, NumberStyles.HexNumber);
}
// <summary>
@@ -892,22 +933,6 @@ namespace Godot
}
// <summary>
- // Decode a percent-encoded string. See [method percent_encode].
- // </summary>
- public static string PercentDecode(this string instance)
- {
- return Uri.UnescapeDataString(instance);
- }
-
- // <summary>
- // Percent-encode a string. This is meant to encode parameters in a URL when sending a HTTP GET request and bodies of form-urlencoded POST request.
- // </summary>
- public static string PercentEncode(this string instance)
- {
- return Uri.EscapeDataString(instance);
- }
-
- // <summary>
// If the string is a path, this concatenates [code]file[/code] at the end of the string as a subpath. E.g. [code]"this/is".plus_file("path") == "this/is/path"[/code].
// </summary>
public static string PlusFile(this string instance, string file)
@@ -1169,6 +1194,33 @@ namespace Godot
return Encoding.UTF8.GetBytes(instance);
}
+ /// <summary>
+ /// Decodes a string in URL encoded format. This is meant to
+ /// decode parameters in a URL when receiving an HTTP request.
+ /// This mostly wraps around `System.Uri.UnescapeDataString()`,
+ /// but also handles `+`.
+ /// See <see cref="URIEncode"/> for encoding.
+ /// </summary>
+ /// <param name="instance">The string to decode.</param>
+ /// <returns>The unescaped string.</returns>
+ public static string URIDecode(this string instance)
+ {
+ return Uri.UnescapeDataString(instance.Replace("+", "%20"));
+ }
+
+ /// <summary>
+ /// Encodes a string to URL friendly format. This is meant to
+ /// encode parameters in a URL when sending an HTTP request.
+ /// This wraps around `System.Uri.EscapeDataString()`.
+ /// See <see cref="URIDecode"/> for decoding.
+ /// </summary>
+ /// <param name="instance">The string to encode.</param>
+ /// <returns>The escaped string.</returns>
+ public static string URIEncode(this string instance)
+ {
+ return Uri.EscapeDataString(instance);
+ }
+
// <summary>
// Return a copy of the string with special characters escaped using the XML standard.
// </summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs
new file mode 100644
index 0000000000..be01674568
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Godot
+{
+ /// <summary>
+ /// Event arguments for when unhandled exceptions occur.
+ /// </summary>
+ public class UnhandledExceptionArgs
+ {
+ /// <summary>
+ /// Exception object
+ /// </summary>
+ public Exception Exception { get; private set; }
+
+ internal UnhandledExceptionArgs(Exception exception)
+ {
+ Exception = exception;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index b74dd6f4f4..6279ea1ace 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -511,7 +511,7 @@ namespace Godot
/// <returns>The snapped vector.</returns>
public Vector2 Snapped(Vector2 step)
{
- return new Vector2(Mathf.Stepify(x, step.x), Mathf.Stepify(y, step.y));
+ return new Vector2(Mathf.Snapped(x, step.x), Mathf.Snapped(y, step.y));
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index 07f5b3c38e..3b895bbbf6 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -111,10 +111,10 @@ namespace Godot
}
/// <summary>
- /// Returns the minimum angle to the given vector, in radians.
+ /// Returns the unsigned minimum angle to the given vector, in radians.
/// </summary>
/// <param name="to">The other vector to compare this vector to.</param>
- /// <returns>The angle between the two vectors, in radians.</returns>
+ /// <returns>The unsigned angle between the two vectors, in radians.</returns>
public real_t AngleTo(Vector3 to)
{
return Mathf.Atan2(Cross(to).Length(), Dot(to));
@@ -469,6 +469,23 @@ namespace Godot
}
/// <summary>
+ /// Returns the signed angle to the given vector, in radians.
+ /// The sign of the angle is positive in a counter-clockwise
+ /// direction and negative in a clockwise direction when viewed
+ /// from the side specified by the `axis`.
+ /// </summary>
+ /// <param name="to">The other vector to compare this vector to.</param>
+ /// <param name="axis">The reference axis to use for the angle sign.</param>
+ /// <returns>The signed angle between the two vectors, in radians.</returns>
+ public real_t SignedAngleTo(Vector3 to, Vector3 axis)
+ {
+ Vector3 crossTo = Cross(to);
+ real_t unsignedAngle = Mathf.Atan2(crossTo.Length(), Dot(to));
+ real_t sign = crossTo.Dot(axis);
+ return (sign < 0) ? -unsignedAngle : unsignedAngle;
+ }
+
+ /// <summary>
/// Returns the result of the spherical linear interpolation between
/// this vector and `to` by amount `weight`.
///
@@ -513,9 +530,9 @@ namespace Godot
{
return new Vector3
(
- Mathf.Stepify(x, step.x),
- Mathf.Stepify(y, step.y),
- Mathf.Stepify(z, step.z)
+ Mathf.Snapped(x, step.x),
+ Mathf.Snapped(y, step.y),
+ Mathf.Snapped(z, step.z)
);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index 86a16c17f1..54aaaf1f92 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -14,9 +14,12 @@
<ItemGroup>
<Compile Include="Core\AABB.cs" />
<Compile Include="Core\Array.cs" />
+ <Compile Include="Core\Attributes\AssemblyHasScriptsAttribute.cs" />
+ <Compile Include="Core\Attributes\DisableGodotGeneratorsAttribute.cs" />
<Compile Include="Core\Attributes\ExportAttribute.cs" />
<Compile Include="Core\Attributes\GodotMethodAttribute.cs" />
<Compile Include="Core\Attributes\RPCAttributes.cs" />
+ <Compile Include="Core\Attributes\ScriptPathAttribute.cs" />
<Compile Include="Core\Attributes\SignalAttribute.cs" />
<Compile Include="Core\Attributes\ToolAttribute.cs" />
<Compile Include="Core\Basis.cs" />
@@ -30,12 +33,14 @@
<Compile Include="Core\DynamicObject.cs" />
<Compile Include="Core\Extensions\NodeExtensions.cs" />
<Compile Include="Core\Extensions\ObjectExtensions.cs" />
+ <Compile Include="Core\Extensions\PackedSceneExtensions.cs" />
<Compile Include="Core\Extensions\ResourceLoaderExtensions.cs" />
<Compile Include="Core\Extensions\SceneTreeExtensions.cs" />
<Compile Include="Core\GD.cs" />
<Compile Include="Core\GodotSynchronizationContext.cs" />
<Compile Include="Core\GodotTaskScheduler.cs" />
<Compile Include="Core\GodotTraceListener.cs" />
+ <Compile Include="Core\GodotUnhandledExceptionEvent.cs" />
<Compile Include="Core\Interfaces\IAwaitable.cs" />
<Compile Include="Core\Interfaces\IAwaiter.cs" />
<Compile Include="Core\Interfaces\ISerializationListener.cs" />
@@ -55,6 +60,7 @@
<Compile Include="Core\StringName.cs" />
<Compile Include="Core\Transform.cs" />
<Compile Include="Core\Transform2D.cs" />
+ <Compile Include="Core\UnhandledExceptionArgs.cs" />
<Compile Include="Core\Vector2.cs" />
<Compile Include="Core\Vector2i.cs" />
<Compile Include="Core\Vector3.cs" />
diff --git a/modules/mono/glue/arguments_vector.h b/modules/mono/glue/arguments_vector.h
index ab48904571..9ba6a05ac6 100644
--- a/modules/mono/glue/arguments_vector.h
+++ b/modules/mono/glue/arguments_vector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp
index afcc75395b..34a96eba17 100644
--- a/modules/mono/glue/base_object_glue.cpp
+++ b/modules/mono/glue/base_object_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
index dedb5b9f75..191f863350 100644
--- a/modules/mono/glue/collections_glue.cpp
+++ b/modules/mono/glue/collections_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index a4566b82fb..a2ff868f65 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h
index f4263e286e..3db52d7c30 100644
--- a/modules/mono/glue/glue_header.h
+++ b/modules/mono/glue/glue_header.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/glue/nodepath_glue.cpp b/modules/mono/glue/nodepath_glue.cpp
index 9405360c6c..4ddb94e1a8 100644
--- a/modules/mono/glue/nodepath_glue.cpp
+++ b/modules/mono/glue/nodepath_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp
index 410a98aa84..f464e63a81 100644
--- a/modules/mono/glue/rid_glue.cpp
+++ b/modules/mono/glue/rid_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/glue/scene_tree_glue.cpp b/modules/mono/glue/scene_tree_glue.cpp
index 88695201a3..5a6fd69db8 100644
--- a/modules/mono/glue/scene_tree_glue.cpp
+++ b/modules/mono/glue/scene_tree_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,7 +48,7 @@ Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringNa
ptr->get_nodes_in_group(*group, &nodes);
// No need to bother if the group is empty
- if (!nodes.empty()) {
+ if (!nodes.is_empty()) {
MonoType *elem_type = mono_reflection_type_get_type(refltype);
MonoClass *mono_class = mono_class_from_mono_type(elem_type);
GDMonoClass *klass = GDMono::get_singleton()->get_class(mono_class);
diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp
index d71d175418..18a9221f89 100644
--- a/modules/mono/glue/string_glue.cpp
+++ b/modules/mono/glue/string_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/glue/string_name_glue.cpp b/modules/mono/glue/string_name_glue.cpp
index fc2bf32b95..f537896559 100644
--- a/modules/mono/glue/string_name_glue.cpp
+++ b/modules/mono/glue/string_name_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/godotsharp_defs.h b/modules/mono/godotsharp_defs.h
index 7d57d0fac3..273dba52f9 100644
--- a/modules/mono/godotsharp_defs.h
+++ b/modules/mono/godotsharp_defs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 093a935288..020a40575c 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -146,7 +146,7 @@ private:
String appname = ProjectSettings::get_singleton()->get("application/config/name");
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
- if (appname_safe.empty()) {
+ if (appname_safe.is_empty()) {
appname_safe = "UnnamedProject";
}
@@ -179,16 +179,16 @@ private:
#ifdef OSX_ENABLED
if (!DirAccess::exists(data_editor_tools_dir)) {
- data_editor_tools_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Tools");
+ data_editor_tools_dir = exe_dir.plus_file("../Resources/GodotSharp/Tools");
}
if (!DirAccess::exists(data_editor_prebuilt_api_dir)) {
- data_editor_prebuilt_api_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Api");
+ data_editor_prebuilt_api_dir = exe_dir.plus_file("../Resources/GodotSharp/Api");
}
if (!DirAccess::exists(data_mono_root_dir)) {
data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
- data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib");
+ data_mono_lib_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/lib");
}
#endif
@@ -218,11 +218,11 @@ private:
#ifdef OSX_ENABLED
if (!DirAccess::exists(data_mono_root_dir)) {
data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
- data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib");
+ data_mono_lib_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/lib");
}
if (!DirAccess::exists(data_game_assemblies_dir)) {
- data_game_assemblies_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Assemblies");
+ data_game_assemblies_dir = exe_dir.plus_file("../Resources/GodotSharp/Assemblies");
}
#endif
diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h
index 85be506c28..3a3c6f980e 100644
--- a/modules/mono/godotsharp_dirs.h
+++ b/modules/mono/godotsharp_dirs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp
index dbe9c7fc5d..6d868b527c 100644
--- a/modules/mono/managed_callable.cpp
+++ b/modules/mono/managed_callable.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/managed_callable.h b/modules/mono/managed_callable.h
index bde1b41781..c620eee60d 100644
--- a/modules/mono/managed_callable.h
+++ b/modules/mono/managed_callable.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp
index 16a6875406..8583065016 100644
--- a/modules/mono/mono_gc_handle.cpp
+++ b/modules/mono/mono_gc_handle.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h
index b85dc70af3..f435aab3dd 100644
--- a/modules/mono/mono_gc_handle.h
+++ b/modules/mono/mono_gc_handle.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/android_mono_config.h b/modules/mono/mono_gd/android_mono_config.h
index 9e304939b2..9d7cfe1b7c 100644
--- a/modules/mono/mono_gd/android_mono_config.h
+++ b/modules/mono/mono_gd/android_mono_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 772961291c..560788fb3a 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -142,7 +142,7 @@ void gd_mono_debug_init() {
int da_timeout = GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000);
if (Engine::get_singleton()->is_editor_hint() ||
- ProjectSettings::get_singleton()->get_resource_path().empty() ||
+ ProjectSettings::get_singleton()->get_resource_path().is_empty() ||
Main::is_project_manager()) {
if (da_args.size() == 0) {
return;
@@ -297,7 +297,7 @@ void GDMono::determine_mono_dirs(String &r_assembly_rootdir, String &r_config_di
}
#ifdef WINDOWS_ENABLED
- if (r_assembly_rootdir.empty() || r_config_dir.empty()) {
+ if (r_assembly_rootdir.is_empty() || r_config_dir.is_empty()) {
ERR_PRINT("Cannot find Mono in the registry.");
// Assertion: if they are not set, then they weren't found in the registry
CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0);
@@ -360,7 +360,7 @@ void GDMono::initialize() {
#ifndef TOOLS_ENABLED
// Exported games that don't use C# must still work. They likely don't ship with mscorlib.
// We only initialize the Mono runtime if we can find mscorlib. Otherwise it would crash.
- if (GDMonoAssembly::find_assembly("mscorlib.dll").empty()) {
+ if (GDMonoAssembly::find_assembly("mscorlib.dll").is_empty()) {
print_verbose("Mono: Skipping runtime initialization because 'mscorlib.dll' could not be found");
return;
}
@@ -593,8 +593,8 @@ ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMo
ApiAssemblyInfo::Version api_assembly_version;
const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE ?
- BINDINGS_CLASS_NATIVECALLS :
- BINDINGS_CLASS_NATIVECALLS_EDITOR;
+ BINDINGS_CLASS_NATIVECALLS :
+ BINDINGS_CLASS_NATIVECALLS_EDITOR;
GDMonoClass *nativecalls_klass = p_api_assembly->get_class(BINDINGS_NAMESPACE, nativecalls_name);
@@ -757,11 +757,11 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const
#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \
( \
(m_out_of_sync ? \
- String("The assembly is invalidated ") : \
- String("The assembly was not found ")) + \
+ String("The assembly is invalidated ") : \
+ String("The assembly was not found ")) + \
(m_prebuilt_exists ? \
- String("and the prebuilt assemblies are missing.") : \
- String("and we failed to copy the prebuilt assemblies.")))
+ String("and the prebuilt assemblies are missing.") : \
+ String("and we failed to copy the prebuilt assemblies.")))
String dst_assemblies_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config);
@@ -820,8 +820,8 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c
// If running the project manager, load it from the prebuilt API directory
String assembly_dir = !Main::is_project_manager() ?
- GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) :
- GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
+ GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) :
+ GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
String assembly_path = assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
@@ -853,8 +853,8 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly,
// If running the project manager, load it from the prebuilt API directory
String assembly_dir = !Main::is_project_manager() ?
- GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) :
- GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
+ GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) :
+ GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
@@ -944,7 +944,7 @@ void GDMono::_load_api_assemblies() {
// 2. Update the API assemblies
String update_error = update_api_assemblies_from_prebuilt("Debug", &core_api_assembly.out_of_sync, &editor_api_assembly.out_of_sync);
- CRASH_COND_MSG(!update_error.empty(), update_error);
+ CRASH_COND_MSG(!update_error.is_empty(), update_error);
// 3. Load the scripts domain again
Error domain_load_err = _load_scripts_domain();
@@ -998,7 +998,7 @@ bool GDMono::_load_project_assembly() {
String appname = ProjectSettings::get_singleton()->get("application/config/name");
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
- if (appname_safe.empty()) {
+ if (appname_safe.is_empty()) {
appname_safe = "UnnamedProject";
}
@@ -1006,6 +1006,7 @@ bool GDMono::_load_project_assembly() {
if (success) {
mono_assembly_set_main(project_assembly->get_assembly());
+ CSharpLanguage::get_singleton()->lookup_scripts_in_assembly(project_assembly);
}
return success;
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index 969296c44d..5accc21f8e 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 33628b3ce3..a1556bace5 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,20 +48,20 @@ Vector<String> GDMonoAssembly::search_dirs;
void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config, const String &p_custom_bcl_dir) {
String framework_dir;
- if (!p_custom_bcl_dir.empty()) {
+ if (!p_custom_bcl_dir.is_empty()) {
framework_dir = p_custom_bcl_dir;
} else if (mono_assembly_getrootdir()) {
framework_dir = String::utf8(mono_assembly_getrootdir()).plus_file("mono").plus_file("4.5");
}
- if (!framework_dir.empty()) {
+ if (!framework_dir.is_empty()) {
r_search_dirs.push_back(framework_dir);
r_search_dirs.push_back(framework_dir.plus_file("Facades"));
}
#if !defined(TOOLS_ENABLED)
String data_game_assemblies_dir = GodotSharpDirs::get_data_game_assemblies_dir();
- if (!data_game_assemblies_dir.empty()) {
+ if (!data_game_assemblies_dir.is_empty()) {
r_search_dirs.push_back(data_game_assemblies_dir);
}
#endif
@@ -72,7 +72,7 @@ void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const Strin
r_search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir());
}
- if (p_custom_config.empty()) {
+ if (p_custom_config.is_empty()) {
r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir());
} else {
String api_config = p_custom_config == "ExportRelease" ? "Release" : "Debug";
@@ -230,7 +230,7 @@ void GDMonoAssembly::initialize() {
MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, bool p_refonly, MonoAssemblyName *p_aname) {
Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
- ERR_FAIL_COND_V_MSG(data.empty(), nullptr, "Could read the assembly in the specified location");
+ ERR_FAIL_COND_V_MSG(data.is_empty(), nullptr, "Could read the assembly in the specified location");
String image_filename;
@@ -345,6 +345,45 @@ String GDMonoAssembly::get_path() const {
return String::utf8(mono_image_get_filename(image));
}
+bool GDMonoAssembly::has_attribute(GDMonoClass *p_attr_class) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_NULL_V(p_attr_class, false);
+#endif
+
+ if (!attrs_fetched) {
+ fetch_attributes();
+ }
+
+ if (!attributes) {
+ return false;
+ }
+
+ return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
+}
+
+MonoObject *GDMonoAssembly::get_attribute(GDMonoClass *p_attr_class) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_NULL_V(p_attr_class, nullptr);
+#endif
+
+ if (!attrs_fetched) {
+ fetch_attributes();
+ }
+
+ if (!attributes) {
+ return nullptr;
+ }
+
+ return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
+}
+
+void GDMonoAssembly::fetch_attributes() {
+ ERR_FAIL_COND(attributes != nullptr);
+
+ attributes = mono_custom_attrs_from_assembly(assembly);
+ attrs_fetched = true;
+}
+
GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const StringName &p_name) {
ERR_FAIL_NULL_V(image, nullptr);
@@ -379,8 +418,8 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
return match->value();
}
- StringName namespace_name = mono_class_get_namespace(p_mono_class);
- StringName class_name = mono_class_get_name(p_mono_class);
+ StringName namespace_name = String::utf8(mono_class_get_namespace(p_mono_class));
+ StringName class_name = String::utf8(mono_class_get_name(p_mono_class));
GDMonoClass *wrapped_class = memnew(GDMonoClass(namespace_name, class_name, p_mono_class, this));
@@ -390,70 +429,6 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
return wrapped_class;
}
-GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) {
- GDMonoClass *match = nullptr;
-
- if (gdobject_class_cache_updated) {
- Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class);
-
- if (result) {
- match = result->get();
- }
- } else {
- List<GDMonoClass *> nested_classes;
-
- int rows = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF);
-
- for (int i = 1; i < rows; i++) {
- MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF);
-
- if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) {
- continue;
- }
-
- GDMonoClass *current = get_class(mono_class);
-
- if (!current) {
- continue;
- }
-
- nested_classes.push_back(current);
-
- if (!match && current->get_name() == p_class) {
- match = current;
- }
-
- while (!nested_classes.empty()) {
- GDMonoClass *current_nested = nested_classes.front()->get();
- nested_classes.pop_front();
-
- void *iter = nullptr;
-
- while (true) {
- MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter);
-
- if (!raw_nested) {
- break;
- }
-
- GDMonoClass *nested_class = get_class(raw_nested);
-
- if (nested_class) {
- gdobject_class_cache.insert(nested_class->get_name(), nested_class);
- nested_classes.push_back(nested_class);
- }
- }
- }
-
- gdobject_class_cache.insert(current->get_name(), current);
- }
-
- gdobject_class_cache_updated = true;
- }
-
- return match;
-}
-
GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) {
if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) {
return GDMono::get_singleton()->get_corlib_assembly();
diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h
index fc10480e07..6191c491f4 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.h
+++ b/modules/mono/mono_gd/gd_mono_assembly.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,13 +71,13 @@ class GDMonoAssembly {
MonoImage *image;
MonoAssembly *assembly;
+ bool attrs_fetched = false;
+ MonoCustomAttrInfo *attributes = nullptr;
+
#ifdef GD_MONO_HOT_RELOAD
uint64_t modified_time = 0;
#endif
- bool gdobject_class_cache_updated = false;
- Map<StringName, GDMonoClass *> gdobject_class_cache;
-
HashMap<ClassKey, GDMonoClass *, ClassKey::Hasher> cached_classes;
Map<MonoClass *, GDMonoClass *> cached_raw;
@@ -111,11 +111,14 @@ public:
String get_path() const;
+ bool has_attribute(GDMonoClass *p_attr_class);
+ MonoObject *get_attribute(GDMonoClass *p_attr_class);
+
+ void fetch_attributes();
+
GDMonoClass *get_class(const StringName &p_namespace, const StringName &p_name);
GDMonoClass *get_class(MonoClass *p_mono_class);
- GDMonoClass *get_object_derived_class(const StringName &p_class);
-
static String find_assembly(const String &p_name);
static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String(), const String &p_custom_bcl_dir = String());
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp
index 3f51c6523b..d66cc29b9a 100644
--- a/modules/mono/mono_gd/gd_mono_cache.cpp
+++ b/modules/mono/mono_gd/gd_mono_cache.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -148,6 +148,11 @@ void CachedData::clear_godot_api_cache() {
class_PuppetSyncAttribute = nullptr;
class_GodotMethodAttribute = nullptr;
field_GodotMethodAttribute_methodName = nullptr;
+ class_ScriptPathAttribute = nullptr;
+ field_ScriptPathAttribute_path = nullptr;
+ class_AssemblyHasScriptsAttribute = nullptr;
+ field_AssemblyHasScriptsAttribute_requiresLookup = nullptr;
+ field_AssemblyHasScriptsAttribute_scriptTypes = nullptr;
field_GodotObject_ptr = nullptr;
field_StringName_ptr = nullptr;
@@ -272,6 +277,11 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(PuppetSyncAttribute, GODOT_API_CLASS(PuppetSyncAttribute));
CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute));
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
+ CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute));
+ CACHE_FIELD_AND_CHECK(ScriptPathAttribute, path, CACHED_CLASS(ScriptPathAttribute)->get_field("path"));
+ CACHE_CLASS_AND_CHECK(AssemblyHasScriptsAttribute, GODOT_API_CLASS(AssemblyHasScriptsAttribute));
+ CACHE_FIELD_AND_CHECK(AssemblyHasScriptsAttribute, requiresLookup, CACHED_CLASS(AssemblyHasScriptsAttribute)->get_field("requiresLookup"));
+ CACHE_FIELD_AND_CHECK(AssemblyHasScriptsAttribute, scriptTypes, CACHED_CLASS(AssemblyHasScriptsAttribute)->get_field("scriptTypes"));
CACHE_FIELD_AND_CHECK(GodotObject, ptr, CACHED_CLASS(GodotObject)->get_field(BINDINGS_PTR_FIELD));
CACHE_FIELD_AND_CHECK(StringName, ptr, CACHED_CLASS(StringName)->get_field(BINDINGS_PTR_FIELD));
diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h
index 9dfa5769be..51370da452 100644
--- a/modules/mono/mono_gd/gd_mono_cache.h
+++ b/modules/mono/mono_gd/gd_mono_cache.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -119,6 +119,11 @@ struct CachedData {
GDMonoClass *class_PuppetSyncAttribute;
GDMonoClass *class_GodotMethodAttribute;
GDMonoField *field_GodotMethodAttribute_methodName;
+ GDMonoClass *class_ScriptPathAttribute;
+ GDMonoField *field_ScriptPathAttribute_path;
+ GDMonoClass *class_AssemblyHasScriptsAttribute;
+ GDMonoField *field_AssemblyHasScriptsAttribute_requiresLookup;
+ GDMonoField *field_AssemblyHasScriptsAttribute_scriptTypes;
GDMonoField *field_GodotObject_ptr;
GDMonoField *field_StringName_ptr;
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index b734f52e4e..f9fddd931b 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -177,7 +177,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
void *iter = nullptr;
MonoMethod *raw_method = nullptr;
while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != nullptr) {
- StringName name = mono_method_get_name(raw_method);
+ StringName name = String::utf8(mono_method_get_name(raw_method));
// get_method implicitly fetches methods and adds them to this->methods
GDMonoMethod *method = get_method(raw_method, name);
@@ -319,7 +319,7 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method) {
MonoMethodSignature *sig = mono_method_signature(p_raw_method);
int params_count = mono_signature_get_param_count(sig);
- StringName method_name = mono_method_get_name(p_raw_method);
+ StringName method_name = String::utf8(mono_method_get_name(p_raw_method));
return get_method(p_raw_method, method_name, params_count);
}
@@ -392,7 +392,7 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
void *iter = nullptr;
MonoClassField *raw_field = nullptr;
while ((raw_field = mono_class_get_fields(mono_class, &iter)) != nullptr) {
- StringName name = mono_field_get_name(raw_field);
+ StringName name = String::utf8(mono_field_get_name(raw_field));
Map<StringName, GDMonoField *>::Element *match = fields.find(name);
@@ -441,7 +441,7 @@ const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
void *iter = nullptr;
MonoProperty *raw_property = nullptr;
while ((raw_property = mono_class_get_properties(mono_class, &iter)) != nullptr) {
- StringName name = mono_property_get_name(raw_property);
+ StringName name = String::utf8(mono_property_get_name(raw_property));
Map<StringName, GDMonoProperty *>::Element *match = properties.find(name);
@@ -468,14 +468,14 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
MonoClass *raw_class = nullptr;
while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != nullptr) {
if (mono_class_is_delegate(raw_class)) {
- StringName name = mono_class_get_name(raw_class);
+ StringName name = String::utf8(mono_class_get_name(raw_class));
Map<StringName, GDMonoClass *>::Element *match = delegates.find(name);
if (match) {
delegates_list.push_back(match->get());
} else {
- GDMonoClass *delegate = memnew(GDMonoClass(mono_class_get_namespace(raw_class), mono_class_get_name(raw_class), raw_class, assembly));
+ GDMonoClass *delegate = memnew(GDMonoClass(String::utf8(mono_class_get_namespace(raw_class)), String::utf8(mono_class_get_name(raw_class)), raw_class, assembly));
delegates.insert(name, delegate);
delegates_list.push_back(delegate);
}
@@ -492,7 +492,7 @@ const Vector<GDMonoMethod *> &GDMonoClass::get_all_methods() {
void *iter = nullptr;
MonoMethod *raw_method = nullptr;
while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != nullptr) {
- method_list.push_back(memnew(GDMonoMethod(mono_method_get_name(raw_method), raw_method)));
+ method_list.push_back(memnew(GDMonoMethod(String::utf8(mono_method_get_name(raw_method)), raw_method)));
}
method_list_fetched = true;
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index b93dfec30a..daea75bae8 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index 61d7f64a2a..1d4d52dfce 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -509,7 +509,7 @@ IMonoClassMember::Visibility GDMonoField::get_visibility() {
GDMonoField::GDMonoField(MonoClassField *p_mono_field, GDMonoClass *p_owner) {
owner = p_owner;
mono_field = p_mono_field;
- name = mono_field_get_name(mono_field);
+ name = String::utf8(mono_field_get_name(mono_field));
MonoType *field_type = mono_field_get_type(mono_field);
type.type_encoding = mono_type_get_type(field_type);
MonoClass *field_type_class = mono_class_from_mono_type(field_type);
diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h
index 5b40b439f9..ed5078c673 100644
--- a/modules/mono/mono_gd/gd_mono_field.h
+++ b/modules/mono/mono_gd/gd_mono_field.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h
index ffb56e7cec..483030610f 100644
--- a/modules/mono/mono_gd/gd_mono_header.h
+++ b/modules/mono/mono_gd/gd_mono_header.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index 82f916e8c5..fa93c6533a 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,6 @@
#include <mono/metadata/exception.h>
namespace GDMonoInternals {
-
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
// This method should not fail
@@ -113,9 +112,11 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
void unhandled_exception(MonoException *p_exc) {
mono_print_unhandled_exception((MonoObject *)p_exc);
+ gd_unhandled_exception_event(p_exc);
if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) {
// Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
+ mono_unhandled_exception((MonoObject *)p_exc);
GDMono::unhandled_exception_hook((MonoObject *)p_exc, nullptr);
GD_UNREACHABLE();
} else {
@@ -127,4 +128,14 @@ void unhandled_exception(MonoException *p_exc) {
#endif
}
}
+
+void gd_unhandled_exception_event(MonoException *p_exc) {
+ MonoImage *mono_image = GDMono::get_singleton()->get_core_api_assembly()->get_image();
+
+ MonoClass *gd_klass = mono_class_from_name(mono_image, "Godot", "GD");
+ MonoMethod *unhandled_exception_method = mono_class_get_method_from_name(gd_klass, "OnUnhandledException", -1);
+ void *args[1];
+ args[0] = p_exc;
+ mono_runtime_invoke(unhandled_exception_method, nullptr, (void **)args, nullptr);
+}
} // namespace GDMonoInternals
diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h
index 0fd6250785..26eb270eee 100644
--- a/modules/mono/mono_gd/gd_mono_internals.h
+++ b/modules/mono/mono_gd/gd_mono_internals.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,6 @@
#include "core/object/class_db.h"
namespace GDMonoInternals {
-
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged);
/**
@@ -46,6 +45,8 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged);
* Use GDMonoUtils::debug_unhandled_exception(MonoException *) instead.
*/
void unhandled_exception(MonoException *p_exc);
+
+void gd_unhandled_exception_event(MonoException *p_exc);
} // namespace GDMonoInternals
#endif // GD_MONO_INTERNALS_H
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index 7584e7ff0d..dafd36c36b 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -189,8 +189,6 @@ void GDMonoLog::initialize() {
GDMonoLog::GDMonoLog() {
singleton = this;
-
- log_level_id = -1;
}
GDMonoLog::~GDMonoLog() {
diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h
index 3a52316060..f7a53156ab 100644
--- a/modules/mono/mono_gd/gd_mono_log.h
+++ b/modules/mono/mono_gd/gd_mono_log.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,9 +46,9 @@
class GDMonoLog {
#ifdef GD_MONO_LOG_ENABLED
- int log_level_id;
+ int log_level_id = -1;
- FileAccess *log_file;
+ FileAccess *log_file = nullptr;
String log_file_path;
bool _try_create_logs_dir(const String &p_logs_dir);
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 64b350f270..359f6bba4d 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1204,7 +1204,7 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
MonoReflectionType *elem_reftype = nullptr;
GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
- return system_generic_list_to_Array(p_obj, p_type.type_class, elem_reftype);
+ return system_generic_list_to_Array_variant(p_obj, p_type.type_class, elem_reftype);
}
} break;
}
@@ -1333,15 +1333,22 @@ MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_cl
return mono_object;
}
-Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) {
+Variant system_generic_list_to_Array_variant(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) {
GDMonoMethod *to_array = p_class->get_method("ToArray", 0);
CRASH_COND(to_array == nullptr);
MonoException *exc = nullptr;
- MonoArray *mono_array = (MonoArray *)to_array->invoke_raw(p_obj, nullptr, &exc);
+ MonoObject *array = to_array->invoke_raw(p_obj, nullptr, &exc);
UNHANDLED_EXCEPTION(exc);
- return mono_array_to_Array(mono_array);
+ ERR_FAIL_NULL_V(array, Variant());
+
+ ManagedType type = ManagedType::from_class(mono_object_get_class(array));
+
+ bool result_is_array = type.type_encoding != MONO_TYPE_SZARRAY && type.type_encoding != MONO_TYPE_ARRAY;
+ ERR_FAIL_COND_V(result_is_array, Variant());
+
+ return mono_object_to_variant(array, type);
}
MonoArray *Array_to_mono_array(const Array &p_array) {
@@ -1677,8 +1684,8 @@ Callable managed_to_callable(const M_Callable &p_managed_callable) {
return Callable(managed_callable);
} else {
Object *target = p_managed_callable.target ?
- unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) :
- nullptr;
+ unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) :
+ nullptr;
StringName *method_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name));
StringName method = method_ptr ? *method_ptr : StringName();
return Callable(target, method);
@@ -1723,8 +1730,8 @@ M_Callable callable_to_managed(const Callable &p_callable) {
Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal) {
Object *owner = p_managed_signal.owner ?
- unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) :
- nullptr;
+ unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) :
+ nullptr;
StringName *name_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name));
StringName name = name_ptr ? *name_ptr : StringName();
return Signal(owner, name);
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 6d8227f8b4..668809ae5d 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -140,7 +140,7 @@ MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoCl
Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
-Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
+Variant system_generic_list_to_Array_variant(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
// Array
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index 1d87726234..67aabcde10 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h
index 115bd998fa..c08ffe904b 100644
--- a/modules/mono/mono_gd/gd_mono_method.h
+++ b/modules/mono/mono_gd/gd_mono_method.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_method_thunk.h b/modules/mono/mono_gd/gd_mono_method_thunk.h
index 01f3ae342a..091d26df1d 100644
--- a/modules/mono/mono_gd/gd_mono_method_thunk.h
+++ b/modules/mono/mono_gd/gd_mono_method_thunk.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp
index 1027c08a4a..5391b7775e 100644
--- a/modules/mono/mono_gd/gd_mono_property.cpp
+++ b/modules/mono/mono_gd/gd_mono_property.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@
GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_owner) {
owner = p_owner;
mono_property = p_mono_property;
- name = mono_property_get_name(mono_property);
+ name = String::utf8(mono_property_get_name(mono_property));
MonoMethod *prop_method = mono_property_get_get_method(mono_property);
diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h
index 611ac293e4..af7a2c02e5 100644
--- a/modules/mono/mono_gd/gd_mono_property.h
+++ b/modules/mono/mono_gd/gd_mono_property.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 05fd57255c..6e0a263c7f 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index 5370b1c6fc..9e024418e1 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp b/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp
index f4c964c6eb..a477c55456 100644
--- a/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp
+++ b/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/gd_mono_wasm_m2n.h b/modules/mono/mono_gd/gd_mono_wasm_m2n.h
index 68a14f15f4..159a2ed7b6 100644
--- a/modules/mono/mono_gd/gd_mono_wasm_m2n.h
+++ b/modules/mono/mono_gd/gd_mono_wasm_m2n.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/i_mono_class_member.h b/modules/mono/mono_gd/i_mono_class_member.h
index 2e8e01c80e..36e14ba27c 100644
--- a/modules/mono/mono_gd/i_mono_class_member.h
+++ b/modules/mono/mono_gd/i_mono_class_member.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/managed_type.cpp b/modules/mono/mono_gd/managed_type.cpp
index 3e971efece..0acfafe841 100644
--- a/modules/mono/mono_gd/managed_type.cpp
+++ b/modules/mono/mono_gd/managed_type.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/managed_type.h b/modules/mono/mono_gd/managed_type.h
index 491a2f3d20..0456a9a864 100644
--- a/modules/mono/mono_gd/managed_type.h
+++ b/modules/mono/mono_gd/managed_type.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/support/android_support.cpp b/modules/mono/mono_gd/support/android_support.cpp
index bc2ae03299..cba29d63cd 100644
--- a/modules/mono/mono_gd/support/android_support.cpp
+++ b/modules/mono/mono_gd/support/android_support.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -109,7 +109,7 @@ bool jni_exception_check(JNIEnv *p_env) {
String app_native_lib_dir_cache;
String determine_app_native_lib_dir() {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> activityThreadClass(env, env->FindClass("android/app/ActivityThread"));
jmethodID currentActivityThread = env->GetStaticMethodID(activityThreadClass, "currentActivityThread", "()Landroid/app/ActivityThread;");
@@ -134,7 +134,7 @@ String determine_app_native_lib_dir() {
}
String get_app_native_lib_dir() {
- if (app_native_lib_dir_cache.empty())
+ if (app_native_lib_dir_cache.is_empty())
app_native_lib_dir_cache = determine_app_native_lib_dir();
return app_native_lib_dir_cache;
}
@@ -253,7 +253,7 @@ int32_t get_build_version_sdk_int() {
// android.os.Build.VERSION.SDK_INT
if (build_version_sdk_int == 0) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass versionClass = env->FindClass("android/os/Build$VERSION");
ERR_FAIL_NULL_V(versionClass, 0);
@@ -281,7 +281,7 @@ MonoBoolean _gd_mono_init_cert_store() {
// return false;
// }
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> keyStoreClass(env, env->FindClass("java/security/KeyStore"));
@@ -322,7 +322,7 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
return nullptr;
}
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
ScopedLocalRef<jstring> js_alias(env, env->NewStringUTF(alias_utf8));
mono_free(alias_utf8);
@@ -380,7 +380,7 @@ void cleanup() {
if (godot_dl_handle)
gd_mono_android_dlclose(godot_dl_handle, nullptr);
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
if (certStore) {
env->DeleteGlobalRef(certStore);
@@ -437,7 +437,7 @@ GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_up_state(const char
*r_is_up = 0;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
ERR_FAIL_NULL_V(networkInterfaceClass, 0);
@@ -469,7 +469,7 @@ GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_supports_multicast(
*r_supports_multicast = 0;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
ERR_FAIL_NULL_V(networkInterfaceClass, 0);
@@ -507,7 +507,7 @@ static void interop_get_active_network_dns_servers(char **r_dns_servers, int *dn
CRASH_COND(get_build_version_sdk_int() < 23);
#endif
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
GodotJavaWrapper *godot_java = ((OS_Android *)OS::get_singleton())->get_godot_java();
jobject activity = godot_java->get_activity();
@@ -648,7 +648,7 @@ GD_PINVOKE_EXPORT const char *_monodroid_timezone_get_default_id() {
//
// TimeZone.getDefault().getID()
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> timeZoneClass(env, env->FindClass("java/util/TimeZone"));
ERR_FAIL_NULL_V(timeZoneClass, nullptr);
diff --git a/modules/mono/mono_gd/support/android_support.h b/modules/mono/mono_gd/support/android_support.h
index df51100bef..0c5dd2764c 100755..100644
--- a/modules/mono/mono_gd/support/android_support.h
+++ b/modules/mono/mono_gd/support/android_support.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/support/ios_support.h b/modules/mono/mono_gd/support/ios_support.h
index 48cef890d6..28a8806d0e 100755..100644
--- a/modules/mono/mono_gd/support/ios_support.h
+++ b/modules/mono/mono_gd/support/ios_support.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/mono_gd/support/ios_support.mm b/modules/mono/mono_gd/support/ios_support.mm
index e6e09c4146..cdee04edcf 100644
--- a/modules/mono/mono_gd/support/ios_support.mm
+++ b/modules/mono/mono_gd/support/ios_support.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp
index f5c1bda18b..80eb47bfd4 100644
--- a/modules/mono/register_types.cpp
+++ b/modules/mono/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/register_types.h b/modules/mono/register_types.h
index e30d9a8abd..1a2ff004b5 100644
--- a/modules/mono/register_types.h
+++ b/modules/mono/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index f220abfb4c..3aaf726fc8 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h
index 18d1e43e14..4c77f8cfed 100644
--- a/modules/mono/signal_awaiter_utils.h
+++ b/modules/mono/signal_awaiter_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h
index 60c9b9718a..4a220d89c8 100644
--- a/modules/mono/utils/macros.h
+++ b/modules/mono/utils/macros.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp
index 9902744743..bb1265e959 100644
--- a/modules/mono/utils/mono_reg_utils.cpp
+++ b/modules/mono/utils/mono_reg_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -173,7 +173,7 @@ String find_msbuild_tools_path() {
String output;
int exit_code;
- OS::get_singleton()->execute(vswhere_path, vswhere_args, true, nullptr, &output, &exit_code);
+ OS::get_singleton()->execute(vswhere_path, vswhere_args, &output, &exit_code);
if (exit_code == 0) {
Vector<String> lines = output.split("\n");
@@ -188,7 +188,7 @@ String find_msbuild_tools_path() {
if (key == "installationPath") {
String val = line.substr(sep_idx + 1, line.length()).strip_edges();
- ERR_BREAK(val.empty());
+ ERR_BREAK(val.is_empty());
if (!val.ends_with("\\")) {
val += "\\";
diff --git a/modules/mono/utils/mono_reg_utils.h b/modules/mono/utils/mono_reg_utils.h
index cc3f1cb035..0e617761ea 100644
--- a/modules/mono/utils/mono_reg_utils.h
+++ b/modules/mono/utils/mono_reg_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/osx_utils.cpp
index 41be198bcf..f4216c8129 100644
--- a/modules/mono/utils/osx_utils.cpp
+++ b/modules/mono/utils/osx_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/utils/osx_utils.h b/modules/mono/utils/osx_utils.h
index 92faead0fb..6704f19077 100644
--- a/modules/mono/utils/osx_utils.h
+++ b/modules/mono/utils/osx_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp
index a24097924e..93d44628ac 100644
--- a/modules/mono/utils/path_utils.cpp
+++ b/modules/mono/utils/path_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -136,7 +136,7 @@ String realpath(const String &p_path) {
}
String join(const String &p_a, const String &p_b) {
- if (p_a.empty()) {
+ if (p_a.is_empty()) {
return p_b;
}
@@ -165,7 +165,7 @@ String relative_to_impl(const String &p_path, const String &p_relative_to) {
} else {
String base_dir = p_relative_to.get_base_dir();
- if (base_dir.length() <= 2 && (base_dir.empty() || base_dir.ends_with(":"))) {
+ if (base_dir.length() <= 2 && (base_dir.is_empty() || base_dir.ends_with(":"))) {
return p_path;
}
diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h
index c19cb3bc8b..82b8f95f49 100644
--- a/modules/mono/utils/path_utils.h
+++ b/modules/mono/utils/path_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index d70004657c..43de77005e 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/mono/utils/string_utils.h b/modules/mono/utils/string_utils.h
index 99f3548f31..3290cb38b9 100644
--- a/modules/mono/utils/string_utils.h
+++ b/modules/mono/utils/string_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/ogg/register_types.cpp b/modules/ogg/register_types.cpp
index 73c691397c..b23ea65378 100644
--- a/modules/ogg/register_types.cpp
+++ b/modules/ogg/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/ogg/register_types.h b/modules/ogg/register_types.h
index 849d27bb06..49d5ed9c80 100644
--- a/modules/ogg/register_types.h
+++ b/modules/ogg/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml
index c06f3096de..86e7f9cc08 100644
--- a/modules/opensimplex/doc_classes/NoiseTexture.xml
+++ b/modules/opensimplex/doc_classes/NoiseTexture.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Uses an [OpenSimplexNoise] to fill the texture data. You can specify the texture size but keep in mind that larger textures will take longer to generate and seamless noise only works with square sized textures.
- NoiseTexture can also generate normalmap textures.
+ NoiseTexture can also generate normal map textures.
The class uses [Thread]s to generate the texture data internally, so [method Texture2D.get_data] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the data:
[codeblock]
var texture = preload("res://noise.tres")
@@ -18,7 +18,7 @@
<methods>
</methods>
<members>
- <member name="as_normalmap" type="bool" setter="set_as_normalmap" getter="is_normalmap" default="false">
+ <member name="as_normal_map" type="bool" setter="set_as_normal_map" getter="is_normal_map" default="false">
If [code]true[/code], the resulting texture contains a normal map created from the original noise interpreted as a bump map.
</member>
<member name="bump_strength" type="float" setter="set_bump_strength" getter="get_bump_strength" default="8.0">
@@ -32,6 +32,7 @@
</member>
<member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false">
Whether the texture can be tiled without visible seams or not. Seamless textures take longer to generate.
+ [b]Note:[/b] Seamless noise has a lower contrast compared to non-seamless noise. This is due to the way noise uses higher dimensions for generating seamless noise.
</member>
<member name="width" type="int" setter="set_width" getter="get_width" default="512">
Width of the generated texture.
diff --git a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml
index 9fe4c9c249..ad82f87213 100644
--- a/modules/opensimplex/doc_classes/OpenSimplexNoise.xml
+++ b/modules/opensimplex/doc_classes/OpenSimplexNoise.xml
@@ -32,7 +32,7 @@
<argument index="1" name="height" type="int">
</argument>
<description>
- Generate a noise image with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters.
+ Generate a noise image in [constant Image.FORMAT_L8] format with the requested [code]width[/code] and [code]height[/code], based on the current noise parameters.
</description>
</method>
<method name="get_noise_1d" qualifiers="const">
@@ -108,7 +108,8 @@
<argument index="0" name="size" type="int">
</argument>
<description>
- Generate a tileable noise image, based on the current noise parameters. Generated seamless images are always square ([code]size[/code] × [code]size[/code]).
+ Generate a tileable noise image in [constant Image.FORMAT_L8] format, based on the current noise parameters. Generated seamless images are always square ([code]size[/code] × [code]size[/code]).
+ [b]Note:[/b] Seamless noise has a lower contrast compared to non-seamless noise. This is due to the way noise uses higher dimensions for generating seamless noise.
</description>
</method>
</methods>
diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp
index 1181e69cd3..f5d401b058 100644
--- a/modules/opensimplex/noise_texture.cpp
+++ b/modules/opensimplex/noise_texture.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,16 +33,6 @@
#include "core/core_string_names.h"
NoiseTexture::NoiseTexture() {
- update_queued = false;
- noise_thread = nullptr;
- regen_queued = false;
- first_time = true;
-
- size = Vector2i(512, 512);
- seamless = false;
- as_normalmap = false;
- bump_strength = 8.0;
-
noise = Ref<OpenSimplexNoise>();
_queue_update();
@@ -52,10 +42,7 @@ NoiseTexture::~NoiseTexture() {
if (texture.is_valid()) {
RS::get_singleton()->free(texture);
}
- if (noise_thread) {
- Thread::wait_to_finish(noise_thread);
- memdelete(noise_thread);
- }
+ noise_thread.wait_to_finish();
}
void NoiseTexture::_bind_methods() {
@@ -68,8 +55,8 @@ void NoiseTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture::set_seamless);
ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless);
- ClassDB::bind_method(D_METHOD("set_as_normalmap", "as_normalmap"), &NoiseTexture::set_as_normalmap);
- ClassDB::bind_method(D_METHOD("is_normalmap"), &NoiseTexture::is_normalmap);
+ ClassDB::bind_method(D_METHOD("set_as_normal_map", "as_normal_map"), &NoiseTexture::set_as_normal_map);
+ ClassDB::bind_method(D_METHOD("is_normal_map"), &NoiseTexture::is_normal_map);
ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture::set_bump_strength);
ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture::get_bump_strength);
@@ -81,14 +68,14 @@ void NoiseTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normalmap"), "set_as_normalmap", "is_normalmap");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normal_map"), "set_as_normal_map", "is_normal_map");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
}
void NoiseTexture::_validate_property(PropertyInfo &property) const {
if (property.name == "bump_strength") {
- if (!as_normalmap) {
+ if (!as_normal_map) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
}
}
@@ -109,11 +96,9 @@ void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) {
void NoiseTexture::_thread_done(const Ref<Image> &p_image) {
_set_texture_data(p_image);
- Thread::wait_to_finish(noise_thread);
- memdelete(noise_thread);
- noise_thread = nullptr;
+ noise_thread.wait_to_finish();
if (regen_queued) {
- noise_thread = Thread::create(_thread_function, this);
+ noise_thread.start(_thread_function, this);
regen_queued = false;
}
}
@@ -148,8 +133,8 @@ Ref<Image> NoiseTexture::_generate_texture() {
image = ref_noise->get_image(size.x, size.y);
}
- if (as_normalmap) {
- image->bumpmap_to_normalmap(bump_strength);
+ if (as_normal_map) {
+ image->bump_map_to_normal_map(bump_strength);
}
return image;
@@ -165,8 +150,8 @@ void NoiseTexture::_update_texture() {
use_thread = false;
#endif
if (use_thread) {
- if (!noise_thread) {
- noise_thread = Thread::create(_thread_function, this);
+ if (!noise_thread.is_started()) {
+ noise_thread.start(_thread_function, this);
regen_queued = false;
} else {
regen_queued = true;
@@ -225,17 +210,17 @@ bool NoiseTexture::get_seamless() {
return seamless;
}
-void NoiseTexture::set_as_normalmap(bool p_as_normalmap) {
- if (p_as_normalmap == as_normalmap) {
+void NoiseTexture::set_as_normal_map(bool p_as_normal_map) {
+ if (p_as_normal_map == as_normal_map) {
return;
}
- as_normalmap = p_as_normalmap;
+ as_normal_map = p_as_normal_map;
_queue_update();
- _change_notify();
+ notify_property_list_changed();
}
-bool NoiseTexture::is_normalmap() {
- return as_normalmap;
+bool NoiseTexture::is_normal_map() {
+ return as_normal_map;
}
void NoiseTexture::set_bump_strength(float p_bump_strength) {
@@ -243,7 +228,7 @@ void NoiseTexture::set_bump_strength(float p_bump_strength) {
return;
}
bump_strength = p_bump_strength;
- if (as_normalmap) {
+ if (as_normal_map) {
_queue_update();
}
}
diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h
index 73960ba85f..e89479d962 100644
--- a/modules/opensimplex/noise_texture.h
+++ b/modules/opensimplex/noise_texture.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,20 +45,20 @@ class NoiseTexture : public Texture2D {
private:
Ref<Image> data;
- Thread *noise_thread;
+ Thread noise_thread;
- bool first_time;
- bool update_queued;
- bool regen_queued;
+ bool first_time = true;
+ bool update_queued = false;
+ bool regen_queued = false;
mutable RID texture;
- uint32_t flags;
+ uint32_t flags = 0;
Ref<OpenSimplexNoise> noise;
- Vector2i size;
- bool seamless;
- bool as_normalmap;
- float bump_strength;
+ Vector2i size = Vector2i(512, 512);
+ bool seamless = false;
+ bool as_normal_map = false;
+ float bump_strength = 8.0;
void _thread_done(const Ref<Image> &p_image);
static void _thread_function(void *p_ud);
@@ -82,8 +82,8 @@ public:
void set_seamless(bool p_seamless);
bool get_seamless();
- void set_as_normalmap(bool p_as_normalmap);
- bool is_normalmap();
+ void set_as_normal_map(bool p_as_normal_map);
+ bool is_normal_map();
void set_bump_strength(float p_bump_strength);
float get_bump_strength();
diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp
index aded4d2a07..3773946112 100644
--- a/modules/opensimplex/open_simplex_noise.cpp
+++ b/modules/opensimplex/open_simplex_noise.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,12 +33,6 @@
#include "core/core_string_names.h"
OpenSimplexNoise::OpenSimplexNoise() {
- seed = 0;
- persistence = 0.5;
- octaves = 3;
- period = 64;
- lacunarity = 2.0;
-
_init_seeds();
}
@@ -104,7 +98,7 @@ void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const {
Vector<uint8_t> data;
- data.resize(p_width * p_height * 4);
+ data.resize(p_width * p_height);
uint8_t *wd8 = data.ptrw();
@@ -112,21 +106,17 @@ Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const {
for (int j = 0; j < p_width; j++) {
float v = get_noise_2d(j, i);
v = v * 0.5 + 0.5; // Normalize [0..1]
- uint8_t value = uint8_t(CLAMP(v * 255.0, 0, 255));
- wd8[(i * p_width + j) * 4 + 0] = value;
- wd8[(i * p_width + j) * 4 + 1] = value;
- wd8[(i * p_width + j) * 4 + 2] = value;
- wd8[(i * p_width + j) * 4 + 3] = 255;
+ wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
}
}
- Ref<Image> image = memnew(Image(p_width, p_height, false, Image::FORMAT_RGBA8, data));
+ Ref<Image> image = memnew(Image(p_width, p_height, false, Image::FORMAT_L8, data));
return image;
}
Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const {
Vector<uint8_t> data;
- data.resize(p_size * p_size * 4);
+ data.resize(p_size * p_size);
uint8_t *wd8 = data.ptrw();
@@ -135,10 +125,10 @@ Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const {
float ii = (float)i / (float)p_size;
float jj = (float)j / (float)p_size;
- ii *= 2.0 * Math_PI;
- jj *= 2.0 * Math_PI;
+ ii *= Math_TAU;
+ jj *= Math_TAU;
- float radius = p_size / (2.0 * Math_PI);
+ float radius = p_size / Math_TAU;
float x = radius * Math::sin(jj);
float y = radius * Math::cos(jj);
@@ -147,15 +137,11 @@ Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const {
float v = get_noise_4d(x, y, z, w);
v = v * 0.5 + 0.5; // Normalize [0..1]
- uint8_t value = uint8_t(CLAMP(v * 255.0, 0, 255));
- wd8[(i * p_size + j) * 4 + 0] = value;
- wd8[(i * p_size + j) * 4 + 1] = value;
- wd8[(i * p_size + j) * 4 + 2] = value;
- wd8[(i * p_size + j) * 4 + 3] = 255;
+ wd8[(i * p_size + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
}
}
- Ref<Image> image = memnew(Image(p_size, p_size, false, Image::FORMAT_RGBA8, data));
+ Ref<Image> image = memnew(Image(p_size, p_size, false, Image::FORMAT_L8, data));
return image;
}
diff --git a/modules/opensimplex/open_simplex_noise.h b/modules/opensimplex/open_simplex_noise.h
index d9bf05115d..847c157409 100644
--- a/modules/opensimplex/open_simplex_noise.h
+++ b/modules/opensimplex/open_simplex_noise.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,22 +37,22 @@
#include "thirdparty/misc/open-simplex-noise.h"
-// The maximum number of octaves allowed. Note that these are statically allocated.
-// Higher values become exponentially slower, so this shouldn't be set too high
-// to avoid freezing the editor for long periods of time.
-#define MAX_OCTAVES 9
-
class OpenSimplexNoise : public Resource {
GDCLASS(OpenSimplexNoise, Resource);
OBJ_SAVE_TYPE(OpenSimplexNoise);
+ // The maximum number of octaves allowed. Note that these are statically allocated.
+ // Higher values become exponentially slower, so this shouldn't be set too high
+ // to avoid freezing the editor for long periods of time.
+ static const int MAX_OCTAVES = 9;
+
osn_context contexts[MAX_OCTAVES];
- int seed;
- float persistence; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness.
- int octaves; // Number of noise layers
- float period; // Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain.
- float lacunarity; // Controls period change across octaves. 2 is usually a good value to address all detail levels.
+ int seed = 0;
+ float persistence = 0.5; // Controls details, value in [0,1]. Higher increases grain, lower increases smoothness.
+ int octaves = 3; // Number of noise layers
+ float period = 64.0; // Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain.
+ float lacunarity = 2.0; // Controls period change across octaves. 2 is usually a good value to address all detail levels.
public:
OpenSimplexNoise();
diff --git a/modules/opensimplex/register_types.cpp b/modules/opensimplex/register_types.cpp
index fef90cdce3..e9735a2cc8 100644
--- a/modules/opensimplex/register_types.cpp
+++ b/modules/opensimplex/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/opensimplex/register_types.h b/modules/opensimplex/register_types.h
index 51c6815eae..d72e37e3a3 100644
--- a/modules/opensimplex/register_types.h
+++ b/modules/opensimplex/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/opus/register_types.cpp b/modules/opus/register_types.cpp
index a4329e142c..02874a9a4b 100644
--- a/modules/opus/register_types.cpp
+++ b/modules/opus/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/opus/register_types.h b/modules/opus/register_types.h
index ad6e083c82..af889cf809 100644
--- a/modules/opus/register_types.h
+++ b/modules/opus/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/pvr/image_compress_pvrtc.cpp b/modules/pvr/image_compress_pvrtc.cpp
index 6695a539d0..d2d8976694 100644
--- a/modules/pvr/image_compress_pvrtc.cpp
+++ b/modules/pvr/image_compress_pvrtc.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/pvr/image_compress_pvrtc.h b/modules/pvr/image_compress_pvrtc.h
index fde65f4bbe..985076ce4d 100644
--- a/modules/pvr/image_compress_pvrtc.h
+++ b/modules/pvr/image_compress_pvrtc.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/pvr/register_types.cpp b/modules/pvr/register_types.cpp
index 9bfc334d76..aeac564c93 100644
--- a/modules/pvr/register_types.cpp
+++ b/modules/pvr/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/pvr/register_types.h b/modules/pvr/register_types.h
index 8318996a46..74fcfe2ce4 100644
--- a/modules/pvr/register_types.h
+++ b/modules/pvr/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index c9cbb1935a..83f032ca2b 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,7 @@ enum PVRFLags {
PVR_VFLIP = 0x00010000
};
-RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
@@ -153,7 +153,7 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
}
Ref<Image> image = memnew(Image(width, height, mipmaps, format, data));
- ERR_FAIL_COND_V(image->empty(), RES());
+ ERR_FAIL_COND_V(image->is_empty(), RES());
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(image);
@@ -207,7 +207,7 @@ ResourceFormatPVR::ResourceFormatPVR() {
struct PVRTCBlock {
//blocks are 64 bits
- uint32_t data[2];
+ uint32_t data[2] = {};
};
_FORCE_INLINE_ bool is_po2(uint32_t p_input) {
diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h
index 07ef129689..26071ce30f 100644
--- a/modules/pvr/texture_loader_pvr.h
+++ b/modules/pvr/texture_loader_pvr.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class ResourceFormatPVR : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml
index 312275842a..b21f5d1e7a 100644
--- a/modules/regex/doc_classes/RegEx.xml
+++ b/modules/regex/doc_classes/RegEx.xml
@@ -39,8 +39,8 @@
var regex = RegEx.new()
regex.compile("\\S+") # Negated whitespace character class.
var results = []
- for match in regex.search_all("One Two \n\tThree"):
- results.push_back(match.get_string())
+ for result in regex.search_all("One Two \n\tThree"):
+ results.push_back(result.get_string())
# The `results` array now contains "One", "Two", "Three".
[/codeblock]
[b]Note:[/b] Godot's regex implementation is based on the [url=https://www.pcre.org/]PCRE2[/url] library. You can view the full pattern reference [url=https://www.pcre.org/current/doc/html/pcre2pattern.html]here[/url].
diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp
index c10a276eae..6bae12e7e6 100644
--- a/modules/regex/regex.cpp
+++ b/modules/regex/regex.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -365,12 +365,10 @@ Array RegEx::get_names() const {
RegEx::RegEx() {
general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
- code = nullptr;
}
RegEx::RegEx(const String &p_pattern) {
general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
- code = nullptr;
compile(p_pattern);
}
diff --git a/modules/regex/regex.h b/modules/regex/regex.h
index 5b4798b65a..f5773042fb 100644
--- a/modules/regex/regex.h
+++ b/modules/regex/regex.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,8 +42,8 @@ class RegExMatch : public Reference {
GDCLASS(RegExMatch, Reference);
struct Range {
- int start;
- int end;
+ int start = 0;
+ int end = 0;
};
String subject;
@@ -72,7 +72,7 @@ class RegEx : public Reference {
GDCLASS(RegEx, Reference);
void *general_ctx;
- void *code;
+ void *code = nullptr;
String pattern;
void _pattern_info(uint32_t what, void *where) const;
diff --git a/modules/regex/register_types.cpp b/modules/regex/register_types.cpp
index d470fcdaeb..82f3eaf707 100644
--- a/modules/regex/register_types.cpp
+++ b/modules/regex/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/regex/register_types.h b/modules/regex/register_types.h
index cf377cdf5f..fe94cde954 100644
--- a/modules/regex/register_types.h
+++ b/modules/regex/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/regex/tests/test_regex.h b/modules/regex/tests/test_regex.h
index 4b9e7e18eb..c2d303b435 100644
--- a/modules/regex/tests/test_regex.h
+++ b/modules/regex/tests/test_regex.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/register_module_types.h b/modules/register_module_types.h
index acd9fc7c97..2cff8c54c4 100644
--- a/modules/register_module_types.h
+++ b/modules/register_module_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index c510779317..cce08034df 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h
index 11b9e1c833..301d30fcf1 100644
--- a/modules/squish/image_compress_squish.h
+++ b/modules/squish/image_compress_squish.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/squish/register_types.cpp b/modules/squish/register_types.cpp
index ad28aff058..451e9d8e93 100644
--- a/modules/squish/register_types.cpp
+++ b/modules/squish/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/squish/register_types.h b/modules/squish/register_types.h
index ab56c54d4a..0f87d64333 100644
--- a/modules/squish/register_types.h
+++ b/modules/squish/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index 346833ab9c..6732078efc 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,7 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fra
int mixed = stb_vorbis_get_samples_float_interleaved(ogg_stream, 2, buffer, todo * 2);
if (vorbis_stream->channels == 1 && mixed > 0) {
//mix mono to stereo
- for (int i = start_buffer; i < mixed; i++) {
+ for (int i = start_buffer; i < start_buffer + mixed; i++) {
p_buffer[i].r = p_buffer[i].l;
}
}
@@ -124,7 +124,10 @@ AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() {
Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() {
Ref<AudioStreamPlaybackOGGVorbis> ovs;
- ERR_FAIL_COND_V(data == nullptr, ovs);
+ ERR_FAIL_COND_V_MSG(data == nullptr, ovs,
+ "This AudioStreamOGGVorbis does not have an audio file assigned "
+ "to it. AudioStreamOGGVorbis should not be created from the "
+ "inspector or with `.new()`. Instead, load an audio file.");
ovs.instance();
ovs->vorbis_stream = Ref<AudioStreamOGGVorbis>(this);
@@ -260,16 +263,7 @@ void AudioStreamOGGVorbis::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset");
}
-AudioStreamOGGVorbis::AudioStreamOGGVorbis() {
- data = nullptr;
- data_len = 0;
- length = 0;
- sample_rate = 1;
- channels = 1;
- loop_offset = 0;
- decode_mem_size = 0;
- loop = false;
-}
+AudioStreamOGGVorbis::AudioStreamOGGVorbis() {}
AudioStreamOGGVorbis::~AudioStreamOGGVorbis() {
clear_data();
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
index 5070f2a078..2bd70a2722 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,11 +41,11 @@ class AudioStreamOGGVorbis;
class AudioStreamPlaybackOGGVorbis : public AudioStreamPlaybackResampled {
GDCLASS(AudioStreamPlaybackOGGVorbis, AudioStreamPlaybackResampled);
- stb_vorbis *ogg_stream;
+ stb_vorbis *ogg_stream = nullptr;
stb_vorbis_alloc ogg_alloc;
- uint32_t frames_mixed;
- bool active;
- int loops;
+ uint32_t frames_mixed = 0;
+ bool active = false;
+ int loops = 0;
friend class AudioStreamOGGVorbis;
@@ -76,15 +76,15 @@ class AudioStreamOGGVorbis : public AudioStream {
friend class AudioStreamPlaybackOGGVorbis;
- void *data;
- uint32_t data_len;
+ void *data = nullptr;
+ uint32_t data_len = 0;
- int decode_mem_size;
- float sample_rate;
- int channels;
- float length;
- bool loop;
- float loop_offset;
+ int decode_mem_size = 0;
+ float sample_rate = 1.0;
+ int channels = 1;
+ float length = 0.0;
+ bool loop = false;
+ float loop_offset = 0.0;
void clear_data();
protected:
diff --git a/modules/stb_vorbis/register_types.cpp b/modules/stb_vorbis/register_types.cpp
index 13c26fc8cc..6f7eb53bc8 100644
--- a/modules/stb_vorbis/register_types.cpp
+++ b/modules/stb_vorbis/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/stb_vorbis/register_types.h b/modules/stb_vorbis/register_types.h
index f5a1dd31bc..d36d87606c 100644
--- a/modules/stb_vorbis/register_types.h
+++ b/modules/stb_vorbis/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
index d68d050d34..ec1c30783a 100644
--- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.h b/modules/stb_vorbis/resource_importer_ogg_vorbis.h
index 47f0039328..60fe3381fb 100644
--- a/modules/stb_vorbis/resource_importer_ogg_vorbis.h
+++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index 8ca4452ac9..6ce3e4b4b3 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h
index 8e478a40ce..e64175b172 100644
--- a/modules/svg/image_loader_svg.h
+++ b/modules/svg/image_loader_svg.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/svg/register_types.cpp b/modules/svg/register_types.cpp
index 9fbefd2cfe..1a611184d2 100644
--- a/modules/svg/register_types.cpp
+++ b/modules/svg/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/svg/register_types.h b/modules/svg/register_types.h
index a3d914e0cb..106ac9056f 100644
--- a/modules/svg/register_types.h
+++ b/modules/svg/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub
index 3589c8546d..b4067d41c2 100644
--- a/modules/text_server_adv/SCsub
+++ b/modules/text_server_adv/SCsub
@@ -38,6 +38,7 @@ def make_icu_data(target, source, env):
# Thirdparty source files
thirdparty_obj = []
+freetype_enabled = env.module_check_dependencies("text_server_adv", ["freetype"])
if env["builtin_harfbuzz"]:
env_harfbuzz = env_modules.Clone()
@@ -57,11 +58,9 @@ if env["builtin_harfbuzz"]:
"src/hb-face.cc",
"src/hb-fallback-shape.cc",
"src/hb-font.cc",
- "src/hb-ft.cc",
#'src/hb-gdi.cc',
#'src/hb-glib.cc',
#'src/hb-gobject-structs.cc',
- "src/hb-graphite2.cc",
"src/hb-icu.cc",
"src/hb-map.cc",
"src/hb-number.cc",
@@ -109,17 +108,29 @@ if env["builtin_harfbuzz"]:
"src/hb-unicode.cc",
#'src/hb-uniscribe.cc'
]
+
+ if freetype_enabled:
+ thirdparty_sources += [
+ "src/hb-ft.cc",
+ "src/hb-graphite2.cc",
+ ]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_harfbuzz.Append(
CPPPATH=[
"#thirdparty/harfbuzz/src",
- "#thirdparty/freetype/include",
- "#thirdparty/graphite/include",
"#thirdparty/icu4c/common/",
]
)
+ if freetype_enabled:
+ env_harfbuzz.Append(
+ CPPPATH=[
+ "#thirdparty/freetype/include",
+ "#thirdparty/graphite/include",
+ ]
+ )
+
if env["platform"] == "android" or env["platform"] == "linuxbsd" or env["platform"] == "server":
env_harfbuzz.Append(CCFLAGS=["-DHAVE_PTHREAD"])
@@ -133,12 +144,18 @@ if env["builtin_harfbuzz"]:
CCFLAGS=[
"-DHAVE_ICU_BUILTIN",
"-DHAVE_ICU",
- "-DHAVE_FREETYPE",
- "-DHAVE_GRAPHITE2",
- "-DGRAPHITE2_STATIC",
]
)
+ if freetype_enabled:
+ env_harfbuzz.Append(
+ CCFLAGS=[
+ "-DHAVE_FREETYPE",
+ "-DHAVE_GRAPHITE2",
+ "-DGRAPHITE2_STATIC",
+ ]
+ )
+
lib = env_harfbuzz.add_library("harfbuzz_builtin", thirdparty_sources)
thirdparty_obj += lib
@@ -156,7 +173,7 @@ if env["builtin_harfbuzz"]:
env.Append(LIBS=[lib])
-if env["builtin_graphite"]:
+if env["builtin_graphite"] and freetype_enabled:
env_graphite = env_modules.Clone()
env_graphite.disable_warnings()
@@ -488,12 +505,18 @@ if env_text_server_adv["tools"]:
env_text_server_adv.Append(
CPPPATH=[
"#thirdparty/harfbuzz/src",
- "#thirdparty/freetype/include",
- "#thirdparty/graphite/include",
"#thirdparty/icu4c/common/",
]
)
+if freetype_enabled:
+ env_text_server_adv.Append(
+ CPPPATH=[
+ "#thirdparty/freetype/include",
+ "#thirdparty/graphite/include",
+ ]
+ )
+
env_text_server_adv.add_source_files(module_obj, "*.cpp")
env.modules_sources += module_obj
diff --git a/modules/text_server_adv/bitmap_font_adv.cpp b/modules/text_server_adv/bitmap_font_adv.cpp
index b905b7dabb..df7b42eac6 100644
--- a/modules/text_server_adv/bitmap_font_adv.cpp
+++ b/modules/text_server_adv/bitmap_font_adv.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
struct hb_bmp_font_t {
BitmapFontDataAdvanced *face = nullptr;
- float font_size = 0;
+ float font_size = 0.0;
bool unref = false; /* Whether to destroy bm_face when done. */
};
@@ -340,7 +340,7 @@ Error BitmapFontDataAdvanced::load_from_file(const String &p_filename, int p_bas
char_map[idx] = c;
} else if (type == "kerning") {
KerningPairKey kpk;
- float k = 0;
+ float k = 0.0;
if (keys.has("first")) {
kpk.A = keys["first"].to_int();
}
@@ -361,67 +361,71 @@ Error BitmapFontDataAdvanced::load_from_file(const String &p_filename, int p_bas
base_size = height;
}
+ if (hb_handle) {
+ hb_font_destroy(hb_handle);
+ }
+ hb_handle = hb_bmp_font_create(this, base_size, nullptr);
valid = true;
memdelete(f);
return OK;
}
-Error BitmapFontDataAdvanced::load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) {
- _THREAD_SAFE_METHOD_
- ERR_FAIL_COND_V(p_data == nullptr, ERR_CANT_CREATE);
- ERR_FAIL_COND_V(p_size != sizeof(TextServer::BitmapFontData), ERR_CANT_CREATE);
-
- const TextServer::BitmapFontData *data = (const TextServer::BitmapFontData *)p_data;
-
- if (RenderingServer::get_singleton() != nullptr) {
- Ref<Image> image = memnew(Image(data->img));
- Ref<ImageTexture> tex = memnew(ImageTexture);
- tex->create_from_image(image);
+Error BitmapFontDataAdvanced::bitmap_new(float p_height, float p_ascent, int p_base_size) {
+ height = p_height;
+ ascent = p_ascent;
- textures.push_back(tex);
+ base_size = p_base_size;
+ if (base_size == 0) {
+ base_size = height;
}
- for (int i = 0; i < data->charcount; i++) {
- const int *c = &data->char_rects[i * 8];
-
- Character chr;
- chr.rect.position.x = c[1];
- chr.rect.position.y = c[2];
- chr.rect.size.x = c[3];
- chr.rect.size.y = c[4];
- if (c[7] < 0) {
- chr.advance.x = c[3];
- } else {
- chr.advance.x = c[7];
- }
- chr.align = Vector2(c[6], c[5]);
- char_map[c[0]] = chr;
+ char_map.clear();
+ textures.clear();
+ kerning_map.clear();
+ if (hb_handle) {
+ hb_font_destroy(hb_handle);
}
+ hb_handle = hb_bmp_font_create(this, base_size, nullptr);
+ valid = true;
- for (int i = 0; i < data->kerning_count; i++) {
- KerningPairKey kpk;
- kpk.A = data->kernings[i * 3 + 0];
- kpk.B = data->kernings[i * 3 + 1];
+ return OK;
+}
- if (data->kernings[i * 3 + 2] == 0 && kerning_map.has(kpk)) {
- kerning_map.erase(kpk);
- } else {
- kerning_map[kpk] = data->kernings[i * 3 + 2];
- }
- }
+void BitmapFontDataAdvanced::bitmap_add_texture(const Ref<Texture> &p_texture) {
+ ERR_FAIL_COND(!valid);
+ ERR_FAIL_COND_MSG(p_texture.is_null(), "It's not a reference to a valid Texture object.");
- height = data->height;
- ascent = data->ascent;
+ textures.push_back(p_texture);
+}
- base_size = p_base_size;
- if (base_size == 0) {
- base_size = height;
+void BitmapFontDataAdvanced::bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
+ ERR_FAIL_COND(!valid);
+
+ Character chr;
+ chr.rect = p_rect;
+ chr.texture_idx = p_texture_idx;
+ if (p_advance < 0) {
+ chr.advance.x = chr.rect.size.x;
+ } else {
+ chr.advance.x = p_advance;
}
+ chr.align = p_align;
+ char_map[p_char] = chr;
+}
- valid = true;
+void BitmapFontDataAdvanced::bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) {
+ ERR_FAIL_COND(!valid);
- return OK;
+ KerningPairKey kpk;
+ kpk.A = p_A;
+ kpk.B = p_B;
+
+ if (p_kerning == 0 && kerning_map.has(kpk)) {
+ kerning_map.erase(kpk);
+ } else {
+ kerning_map[kpk] = p_kerning;
+ }
}
float BitmapFontDataAdvanced::get_height(int p_size) const {
@@ -464,10 +468,7 @@ float BitmapFontDataAdvanced::get_base_size() const {
hb_font_t *BitmapFontDataAdvanced::get_hb_handle(int p_size) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!valid, nullptr);
- if (!cache.has(p_size)) {
- cache[p_size] = hb_bmp_font_create(this, p_size, nullptr);
- }
- return cache[p_size];
+ return hb_handle;
}
bool BitmapFontDataAdvanced::has_char(char32_t p_char) const {
@@ -514,6 +515,10 @@ Vector2 BitmapFontDataAdvanced::get_size(uint32_t p_char, int p_size) const {
return c->rect.size * (float(p_size) / float(base_size));
}
+float BitmapFontDataAdvanced::get_font_scale(int p_size) const {
+ return float(p_size) / float(base_size);
+}
+
Vector2 BitmapFontDataAdvanced::get_kerning(uint32_t p_char, uint32_t p_next, int p_size) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!valid, Vector2());
@@ -540,14 +545,14 @@ Vector2 BitmapFontDataAdvanced::draw_glyph(RID p_canvas, int p_size, const Vecto
ERR_FAIL_COND_V(c == nullptr, Vector2());
ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), Vector2());
if (c->texture_idx != -1) {
- Point2 cpos = p_pos;
- cpos += c->align * (float(p_size) / float(base_size));
- cpos.y -= ascent * (float(p_size) / float(base_size));
+ Point2i cpos = p_pos;
+ cpos += (c->align + Vector2(0, -ascent)) * (float(p_size) / float(base_size));
+ Size2i csize = c->rect.size * (float(p_size) / float(base_size));
if (RenderingServer::get_singleton() != nullptr) {
//if (distance_field_hint) { // Not implemented.
// RenderingServer::get_singleton()->canvas_item_set_distance_field_mode(p_canvas, true);
//}
- RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, c->rect.size * (float(p_size) / float(base_size))), textures[c->texture_idx]->get_rid(), c->rect, p_color, false, false);
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), textures[c->texture_idx]->get_rid(), c->rect, p_color, false, false);
//if (distance_field_hint) {
// RenderingServer::get_singleton()->canvas_item_set_distance_field_mode(p_canvas, false);
//}
@@ -574,7 +579,7 @@ Vector2 BitmapFontDataAdvanced::draw_glyph_outline(RID p_canvas, int p_size, int
}
BitmapFontDataAdvanced::~BitmapFontDataAdvanced() {
- for (Map<float, hb_font_t *>::Element *E = cache.front(); E; E = E->next()) {
- hb_font_destroy(E->get());
+ if (hb_handle) {
+ hb_font_destroy(hb_handle);
}
}
diff --git a/modules/text_server_adv/bitmap_font_adv.h b/modules/text_server_adv/bitmap_font_adv.h
index cb1a726f76..7b620021e1 100644
--- a/modules/text_server_adv/bitmap_font_adv.h
+++ b/modules/text_server_adv/bitmap_font_adv.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,18 +63,22 @@ private:
HashMap<uint32_t, Character> char_map;
Map<KerningPairKey, int> kerning_map;
- Map<float, hb_font_t *> cache;
+ hb_font_t *hb_handle = nullptr;
float height = 0.f;
float ascent = 0.f;
- float base_size = 0.f;
+ int base_size = 0;
bool distance_field_hint = false;
public:
virtual void clear_cache() override{};
virtual Error load_from_file(const String &p_filename, int p_base_size) override;
- virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) override;
+ virtual Error bitmap_new(float p_height, float p_ascent, int p_base_size) override;
+
+ virtual void bitmap_add_texture(const Ref<Texture> &p_texture) override;
+ virtual void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override;
+ virtual void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) override;
virtual float get_height(int p_size) const override;
virtual float get_ascent(int p_size) const override;
@@ -97,6 +101,7 @@ public:
virtual bool has_outline() const override { return false; };
virtual float get_base_size() const override;
+ virtual float get_font_scale(int p_size) const override;
virtual hb_font_t *get_hb_handle(int p_size) override;
diff --git a/modules/text_server_adv/config.py b/modules/text_server_adv/config.py
index 22482fce24..d22f9454ed 100644
--- a/modules/text_server_adv/config.py
+++ b/modules/text_server_adv/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return env.module_check_dependencies("text_server_adv", ["freetype"])
+ return True
def configure(env):
diff --git a/modules/text_server_adv/dynamic_font_adv.cpp b/modules/text_server_adv/dynamic_font_adv.cpp
index 99d78a5299..b60b9ddaec 100644
--- a/modules/text_server_adv/dynamic_font_adv.cpp
+++ b/modules/text_server_adv/dynamic_font_adv.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,6 +30,8 @@
#include "dynamic_font_adv.h"
+#ifdef MODULE_FREETYPE_ENABLED
+
#include FT_STROKER_H
#include FT_ADVANCES_H
#include FT_MULTIPLE_MASTERS_H
@@ -55,7 +57,7 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size(
fds = E->get();
} else {
if (font_mem == nullptr && font_path != String()) {
- if (!font_mem_cache.empty()) {
+ if (!font_mem_cache.is_empty()) {
font_mem = font_mem_cache.ptr();
font_mem_size = font_mem_cache.size();
} else {
@@ -124,8 +126,8 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size(
fds->size = p_size;
fds->ascent = (fds->face->size->metrics.ascender / 64.0) / oversampling * fds->scale_color_font;
fds->descent = (-fds->face->size->metrics.descender / 64.0) / oversampling * fds->scale_color_font;
- fds->underline_position = -fds->face->underline_position / 64.0 / oversampling * fds->scale_color_font;
- fds->underline_thickness = fds->face->underline_thickness / 64.0 / oversampling * fds->scale_color_font;
+ fds->underline_position = (-FT_MulFix(fds->face->underline_position, fds->face->size->metrics.y_scale) / 64.0) / oversampling * fds->scale_color_font;
+ fds->underline_thickness = (FT_MulFix(fds->face->underline_thickness, fds->face->size->metrics.y_scale) / 64.0) / oversampling * fds->scale_color_font;
//Load os2 TTF pable
fds->os2 = (TT_OS2 *)FT_Get_Sfnt_Table(fds->face, FT_SFNT_OS2);
@@ -171,7 +173,7 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size(
}
FT_Set_Var_Design_Coordinates(fds->face, coords.size(), coords.ptrw());
- hb_font_set_variations(fds->hb_handle, hb_vars.empty() ? nullptr : &hb_vars[0], hb_vars.size());
+ hb_font_set_variations(fds->hb_handle, hb_vars.is_empty() ? nullptr : &hb_vars[0], hb_vars.size());
FT_Done_MM_Var(library, amaster);
}
@@ -946,7 +948,7 @@ Vector2 DynamicFontDataAdvanced::draw_glyph(RID p_canvas, int p_size, const Vect
ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2());
if (ch.texture_idx != -1) {
- Point2 cpos = p_pos;
+ Point2i cpos = p_pos;
cpos += ch.align;
Color modulate = p_color;
if (FT_HAS_COLOR(fds->face)) {
@@ -977,7 +979,7 @@ Vector2 DynamicFontDataAdvanced::draw_glyph_outline(RID p_canvas, int p_size, in
ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2());
if (ch.texture_idx != -1) {
- Point2 cpos = p_pos;
+ Point2i cpos = p_pos;
cpos += ch.align;
Color modulate = p_color;
if (FT_HAS_COLOR(fds->face)) {
@@ -1001,3 +1003,5 @@ DynamicFontDataAdvanced::~DynamicFontDataAdvanced() {
FT_Done_FreeType(library);
}
}
+
+#endif // MODULE_FREETYPE_ENABLED
diff --git a/modules/text_server_adv/dynamic_font_adv.h b/modules/text_server_adv/dynamic_font_adv.h
index f9d6735c32..d69a30b321 100644
--- a/modules/text_server_adv/dynamic_font_adv.h
+++ b/modules/text_server_adv/dynamic_font_adv.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,10 @@
#include "font_adv.h"
+#include "modules/modules_enabled.gen.h"
+
+#ifdef MODULE_FREETYPE_ENABLED
+
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_TABLES_H
@@ -74,14 +78,11 @@ private:
uint32_t size : 16;
uint32_t outline_size : 16;
};
- uint32_t key;
+ uint32_t key = 0;
};
bool operator<(CacheID right) const {
return key < right.key;
}
- CacheID() {
- key = 0;
- }
};
struct DataAtSize {
@@ -91,10 +92,10 @@ private:
int size = 0;
float scale_color_font = 1.f;
- float ascent = 0;
- float descent = 0;
- float underline_position = 0;
- float underline_thickness = 0;
+ float ascent = 0.0;
+ float descent = 0.0;
+ float underline_position = 0.0;
+ float underline_thickness = 0.0;
Vector<CharTexture> textures;
HashMap<uint32_t, Character> glyph_map;
@@ -188,4 +189,6 @@ public:
virtual ~DynamicFontDataAdvanced() override;
};
+#endif // MODULE_FREETYPE_ENABLED
+
#endif // DYNAMIC_FONT_ADV_H
diff --git a/modules/text_server_adv/font_adv.h b/modules/text_server_adv/font_adv.h
index 88b327f57b..2b6d977451 100644
--- a/modules/text_server_adv/font_adv.h
+++ b/modules/text_server_adv/font_adv.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,11 +39,18 @@ struct FontDataAdvanced {
Map<String, bool> lang_support_overrides;
Map<String, bool> script_support_overrides;
bool valid = false;
+ int spacing_space = 0;
+ int spacing_glyph = 0;
virtual void clear_cache() = 0;
- virtual Error load_from_file(const String &p_filename, int p_base_size) = 0;
- virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) = 0;
+ virtual Error load_from_file(const String &p_filename, int p_base_size) { return ERR_CANT_CREATE; };
+ virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) { return ERR_CANT_CREATE; };
+ virtual Error bitmap_new(float p_height, float p_ascent, int p_base_size) { return ERR_CANT_CREATE; };
+
+ virtual void bitmap_add_texture(const Ref<Texture> &p_texture) { ERR_FAIL_MSG("Not supported."); };
+ virtual void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { ERR_FAIL_MSG("Not supported."); };
+ virtual void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) { ERR_FAIL_MSG("Not supported."); };
virtual float get_height(int p_size) const = 0;
virtual float get_ascent(int p_size) const = 0;
@@ -58,6 +65,18 @@ struct FontDataAdvanced {
virtual float get_underline_position(int p_size) const = 0;
virtual float get_underline_thickness(int p_size) const = 0;
+ virtual int get_spacing_space() const { return spacing_space; };
+ virtual void set_spacing_space(int p_value) {
+ spacing_space = p_value;
+ clear_cache();
+ };
+
+ virtual int get_spacing_glyph() const { return spacing_glyph; };
+ virtual void set_spacing_glyph(int p_value) {
+ spacing_glyph = p_value;
+ clear_cache();
+ };
+
virtual void set_antialiased(bool p_antialiased) = 0;
virtual bool get_antialiased() const = 0;
diff --git a/modules/text_server_adv/icu_data/icudata_stub.cpp b/modules/text_server_adv/icu_data/icudata_stub.cpp
index 13f0ac0c50..187001f33a 100644
--- a/modules/text_server_adv/icu_data/icudata_stub.cpp
+++ b/modules/text_server_adv/icu_data/icudata_stub.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/text_server_adv/register_types.cpp b/modules/text_server_adv/register_types.cpp
index 68117e0380..abefa83b9b 100644
--- a/modules/text_server_adv/register_types.cpp
+++ b/modules/text_server_adv/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/text_server_adv/register_types.h b/modules/text_server_adv/register_types.h
index 8319ddfd5d..ddd1190f40 100644
--- a/modules/text_server_adv/register_types.h
+++ b/modules/text_server_adv/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/text_server_adv/script_iterator.cpp b/modules/text_server_adv/script_iterator.cpp
index 60a617c3a7..8f23bb9e02 100644
--- a/modules/text_server_adv/script_iterator.cpp
+++ b/modules/text_server_adv/script_iterator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/text_server_adv/script_iterator.h b/modules/text_server_adv/script_iterator.h
index 4523aa2767..896a0e5c15 100644
--- a/modules/text_server_adv/script_iterator.h
+++ b/modules/text_server_adv/script_iterator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,9 +45,9 @@
class ScriptIterator {
public:
struct ScriptRange {
- int start;
- int end;
- hb_script_t script;
+ int start = 0;
+ int end = 0;
+ hb_script_t script = HB_SCRIPT_COMMON;
};
Vector<ScriptRange> script_ranges;
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 3a706286e5..2e3c2d1cab 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -171,7 +171,7 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) {
}
#else
if (icu_data == nullptr) {
- String filename = (p_filename.empty()) ? String("res://") + _MKSTR(ICU_DATA_NAME) : p_filename;
+ String filename = (p_filename.is_empty()) ? String("res://") + _MKSTR(ICU_DATA_NAME) : p_filename;
FileAccess *f = FileAccess::open(filename, FileAccess::READ);
if (!f) {
@@ -529,10 +529,12 @@ RID TextServerAdvanced::create_font_system(const String &p_name, int p_base_size
RID TextServerAdvanced::create_font_resource(const String &p_filename, int p_base_size) {
_THREAD_SAFE_METHOD_
FontDataAdvanced *fd = nullptr;
- if (p_filename.get_extension() == "ttf" || p_filename.get_extension() == "otf" || p_filename.get_extension() == "woff") {
- fd = memnew(DynamicFontDataAdvanced);
- } else if (p_filename.get_extension() == "fnt" || p_filename.get_extension() == "font") {
+ if (p_filename.get_extension() == "fnt" || p_filename.get_extension() == "font") {
fd = memnew(BitmapFontDataAdvanced);
+#ifdef MODULE_FREETYPE_ENABLED
+ } else if (p_filename.get_extension() == "ttf" || p_filename.get_extension() == "otf" || p_filename.get_extension() == "woff") {
+ fd = memnew(DynamicFontDataAdvanced);
+#endif
} else {
return RID();
}
@@ -549,10 +551,12 @@ RID TextServerAdvanced::create_font_resource(const String &p_filename, int p_bas
RID TextServerAdvanced::create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size) {
_THREAD_SAFE_METHOD_
FontDataAdvanced *fd = nullptr;
- if (p_type == "ttf" || p_type == "otf" || p_type == "woff") {
- fd = memnew(DynamicFontDataAdvanced);
- } else if (p_type == "fnt" || p_type == "font") {
+ if (p_type == "fnt" || p_type == "font") {
fd = memnew(BitmapFontDataAdvanced);
+#ifdef MODULE_FREETYPE_ENABLED
+ } else if (p_type == "ttf" || p_type == "otf" || p_type == "woff") {
+ fd = memnew(DynamicFontDataAdvanced);
+#endif
} else {
return RID();
}
@@ -566,6 +570,39 @@ RID TextServerAdvanced::create_font_memory(const uint8_t *p_data, size_t p_size,
return font_owner.make_rid(fd);
}
+RID TextServerAdvanced::create_font_bitmap(float p_height, float p_ascent, int p_base_size) {
+ _THREAD_SAFE_METHOD_
+ FontDataAdvanced *fd = memnew(BitmapFontDataAdvanced);
+ Error err = fd->bitmap_new(p_height, p_ascent, p_base_size);
+ if (err != OK) {
+ memdelete(fd);
+ return RID();
+ }
+
+ return font_owner.make_rid(fd);
+}
+
+void TextServerAdvanced::font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) {
+ _THREAD_SAFE_METHOD_
+ FontDataAdvanced *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->bitmap_add_texture(p_texture);
+}
+
+void TextServerAdvanced::font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
+ _THREAD_SAFE_METHOD_
+ FontDataAdvanced *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->bitmap_add_char(p_char, p_texture_idx, p_rect, p_align, p_advance);
+}
+
+void TextServerAdvanced::font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) {
+ _THREAD_SAFE_METHOD_
+ FontDataAdvanced *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->bitmap_add_kerning_pair(p_A, p_B, p_kerning);
+}
+
float TextServerAdvanced::font_get_height(RID p_font, int p_size) const {
_THREAD_SAFE_METHOD_
const FontDataAdvanced *fd = font_owner.getornull(p_font);
@@ -601,6 +638,34 @@ float TextServerAdvanced::font_get_underline_thickness(RID p_font, int p_size) c
return fd->get_underline_thickness(p_size);
}
+int TextServerAdvanced::font_get_spacing_space(RID p_font) const {
+ _THREAD_SAFE_METHOD_
+ const FontDataAdvanced *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND_V(!fd, 0);
+ return fd->get_spacing_space();
+}
+
+void TextServerAdvanced::font_set_spacing_space(RID p_font, int p_value) {
+ _THREAD_SAFE_METHOD_
+ FontDataAdvanced *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->set_spacing_space(p_value);
+}
+
+int TextServerAdvanced::font_get_spacing_glyph(RID p_font) const {
+ _THREAD_SAFE_METHOD_
+ const FontDataAdvanced *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND_V(!fd, 0);
+ return fd->get_spacing_glyph();
+}
+
+void TextServerAdvanced::font_set_spacing_glyph(RID p_font, int p_value) {
+ _THREAD_SAFE_METHOD_
+ FontDataAdvanced *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->set_spacing_glyph(p_value);
+}
+
void TextServerAdvanced::font_set_antialiased(RID p_font, bool p_antialiased) {
_THREAD_SAFE_METHOD_
FontDataAdvanced *fd = font_owner.getornull(p_font);
@@ -1061,7 +1126,7 @@ bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_te
ERR_FAIL_COND_V(!sd, false);
ERR_FAIL_COND_V(p_size <= 0, false);
- if (p_text.empty()) {
+ if (p_text.is_empty()) {
return true;
}
@@ -1602,11 +1667,18 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
HashMap<int, bool> breaks;
UErrorCode err = U_ZERO_ERROR;
- for (int i = 0; i < sd->spans.size(); i++) {
- UBreakIterator *bi = ubrk_open(UBRK_LINE, sd->spans[i].language.ascii().get_data(), data + _convert_pos_inv(sd, sd->spans[i].start), _convert_pos_inv(sd, sd->spans[i].end - sd->spans[i].start), &err);
+ int i = 0;
+ while (i < sd->spans.size()) {
+ String language = sd->spans[i].language;
+ int r_start = sd->spans[i].start;
+ while (i + 1 < sd->spans.size() && language == sd->spans[i + 1].language) {
+ i++;
+ }
+ int r_end = sd->spans[i].end;
+ UBreakIterator *bi = ubrk_open(UBRK_LINE, language.ascii().get_data(), data + _convert_pos_inv(sd, r_start), _convert_pos_inv(sd, r_end - r_start), &err);
if (U_FAILURE(err)) {
//No data loaded - use fallback.
- for (int j = sd->spans[i].start; j < sd->spans[i].end; j++) {
+ for (int j = r_start; j < r_end; j++) {
char32_t c = sd->text[j - sd->start];
if (is_whitespace(c)) {
breaks[j] = false;
@@ -1617,8 +1689,8 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
}
} else {
while (ubrk_next(bi) != UBRK_DONE) {
- int pos = _convert_pos(sd, ubrk_current(bi)) + sd->spans[i].start - 1;
- if (pos != sd->spans[i].end) {
+ int pos = _convert_pos(sd, ubrk_current(bi)) + r_start - 1;
+ if (pos != r_end) {
if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_HARD) && (ubrk_getRuleStatus(bi) < UBRK_LINE_HARD_LIMIT)) {
breaks[pos] = true;
} else if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_SOFT) && (ubrk_getRuleStatus(bi) < UBRK_LINE_SOFT_LIMIT)) {
@@ -1628,6 +1700,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
}
}
ubrk_close(bi);
+ i++;
}
sd->sort_valid = false;
@@ -1636,7 +1709,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
const char32_t *ch = sd->text.ptr();
Glyph *sd_glyphs = sd->glyphs.ptrw();
- for (int i = 0; i < sd_size; i++) {
+ for (i = 0; i < sd_size; i++) {
if (sd_glyphs[i].count > 0) {
char32_t c = ch[sd_glyphs[i].start - sd->start];
if (c == 0xfffc) {
@@ -1984,7 +2057,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
ftrs.push_back(feature);
}
}
- hb_shape(hb_font, p_sd->hb_buffer, ftrs.empty() ? nullptr : &ftrs[0], ftrs.size());
+ hb_shape(hb_font, p_sd->hb_buffer, ftrs.is_empty() ? nullptr : &ftrs[0], ftrs.size());
unsigned int glyph_count = 0;
hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(p_sd->hb_buffer, &glyph_count);
@@ -2041,6 +2114,11 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
gl.x_off = Math::round(glyph_pos[i].x_offset / (64.0 / fd->get_font_scale(fs)));
gl.y_off = -Math::round(glyph_pos[i].y_offset / (64.0 / fd->get_font_scale(fs)));
}
+ if (fd->get_spacing_space() && is_whitespace(p_sd->text[glyph_info[i].cluster])) {
+ gl.advance += fd->get_spacing_space();
+ } else {
+ gl.advance += fd->get_spacing_glyph();
+ }
if (p_sd->preserve_control) {
last_cluster_valid = last_cluster_valid && ((glyph_info[i].codepoint != 0) || is_whitespace(p_sd->text[glyph_info[i].cluster]) || is_linebreak(p_sd->text[glyph_info[i].cluster]));
@@ -2131,7 +2209,7 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) {
sd->script_iter = memnew(ScriptIterator(sd->text, 0, sd->text.length()));
}
- if (sd->bidi_override.empty()) {
+ if (sd->bidi_override.is_empty()) {
sd->bidi_override.push_back(Vector2i(0, sd->end));
}
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index 8c26554158..b53b5716e5 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -126,6 +126,11 @@ public:
virtual RID create_font_system(const String &p_name, int p_base_size = 16) override;
virtual RID create_font_resource(const String &p_filename, int p_base_size = 16) override;
virtual RID create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16) override;
+ virtual RID create_font_bitmap(float p_height, float p_ascent, int p_base_size = 16) override;
+
+ virtual void font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) override;
+ virtual void font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override;
+ virtual void font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) override;
virtual float font_get_height(RID p_font, int p_size) const override;
virtual float font_get_ascent(RID p_font, int p_size) const override;
@@ -134,6 +139,12 @@ public:
virtual float font_get_underline_position(RID p_font, int p_size) const override;
virtual float font_get_underline_thickness(RID p_font, int p_size) const override;
+ virtual int font_get_spacing_space(RID p_font) const override;
+ virtual void font_set_spacing_space(RID p_font, int p_value) override;
+
+ virtual int font_get_spacing_glyph(RID p_font) const override;
+ virtual void font_set_spacing_glyph(RID p_font, int p_value) override;
+
virtual void font_set_antialiased(RID p_font, bool p_antialiased) override;
virtual bool font_get_antialiased(RID p_font) const override;
diff --git a/modules/text_server_fb/bitmap_font_fb.cpp b/modules/text_server_fb/bitmap_font_fb.cpp
index 99cbccb69a..313f170f04 100644
--- a/modules/text_server_fb/bitmap_font_fb.cpp
+++ b/modules/text_server_fb/bitmap_font_fb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -148,7 +148,7 @@ Error BitmapFontDataFallback::load_from_file(const String &p_filename, int p_bas
char_map[idx] = c;
} else if (type == "kerning") {
KerningPairKey kpk;
- float k = 0;
+ float k = 0.0;
if (keys.has("first")) {
kpk.A = keys["first"].to_int();
}
@@ -175,61 +175,58 @@ Error BitmapFontDataFallback::load_from_file(const String &p_filename, int p_bas
return OK;
}
-Error BitmapFontDataFallback::load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) {
- _THREAD_SAFE_METHOD_
- ERR_FAIL_COND_V(p_data == nullptr, ERR_CANT_CREATE);
- ERR_FAIL_COND_V(p_size != sizeof(TextServer::BitmapFontData), ERR_CANT_CREATE);
+Error BitmapFontDataFallback::bitmap_new(float p_height, float p_ascent, int p_base_size) {
+ height = p_height;
+ ascent = p_ascent;
- const TextServer::BitmapFontData *data = (const TextServer::BitmapFontData *)p_data;
+ base_size = p_base_size;
+ if (base_size == 0) {
+ base_size = height;
+ }
- if (RenderingServer::get_singleton() != nullptr) {
- Ref<Image> image = memnew(Image(data->img));
- Ref<ImageTexture> tex = memnew(ImageTexture);
- tex->create_from_image(image);
+ char_map.clear();
+ textures.clear();
+ kerning_map.clear();
- textures.push_back(tex);
- }
+ valid = true;
- for (int i = 0; i < data->charcount; i++) {
- const int *c = &data->char_rects[i * 8];
-
- Character chr;
- chr.rect.position.x = c[1];
- chr.rect.position.y = c[2];
- chr.rect.size.x = c[3];
- chr.rect.size.y = c[4];
- if (c[7] < 0) {
- chr.advance.x = c[3];
- } else {
- chr.advance.x = c[7];
- }
- chr.align = Vector2(c[6], c[5]);
- char_map[c[0]] = chr;
- }
+ return OK;
+}
- for (int i = 0; i < data->kerning_count; i++) {
- KerningPairKey kpk;
- kpk.A = data->kernings[i * 3 + 0];
- kpk.B = data->kernings[i * 3 + 1];
+void BitmapFontDataFallback::bitmap_add_texture(const Ref<Texture> &p_texture) {
+ ERR_FAIL_COND(!valid);
+ ERR_FAIL_COND_MSG(p_texture.is_null(), "It's not a reference to a valid Texture object.");
- if (data->kernings[i * 3 + 2] == 0 && kerning_map.has(kpk)) {
- kerning_map.erase(kpk);
- } else {
- kerning_map[kpk] = data->kernings[i * 3 + 2];
- }
- }
+ textures.push_back(p_texture);
+}
- height = data->height;
- ascent = data->ascent;
+void BitmapFontDataFallback::bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
+ ERR_FAIL_COND(!valid);
- base_size = p_base_size;
- if (base_size == 0) {
- base_size = height;
+ Character chr;
+ chr.rect = p_rect;
+ chr.texture_idx = p_texture_idx;
+ if (p_advance < 0) {
+ chr.advance.x = chr.rect.size.x;
+ } else {
+ chr.advance.x = p_advance;
}
+ chr.align = p_align;
+ char_map[p_char] = chr;
+}
- valid = true;
+void BitmapFontDataFallback::bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) {
+ ERR_FAIL_COND(!valid);
- return OK;
+ KerningPairKey kpk;
+ kpk.A = p_A;
+ kpk.B = p_B;
+
+ if (p_kerning == 0 && kerning_map.has(kpk)) {
+ kerning_map.erase(kpk);
+ } else {
+ kerning_map[kpk] = p_kerning;
+ }
}
float BitmapFontDataFallback::get_height(int p_size) const {
@@ -321,15 +318,14 @@ Vector2 BitmapFontDataFallback::draw_glyph(RID p_canvas, int p_size, const Vecto
ERR_FAIL_COND_V(c == nullptr, Vector2());
ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), Vector2());
if (c->texture_idx != -1) {
- Point2 cpos = p_pos;
- cpos += c->align * (float(p_size) / float(base_size));
- cpos.y -= ascent * (float(p_size) / float(base_size));
-
+ Point2i cpos = p_pos;
+ cpos += (c->align + Vector2(0, -ascent)) * (float(p_size) / float(base_size));
+ Size2i csize = c->rect.size * (float(p_size) / float(base_size));
if (RenderingServer::get_singleton() != nullptr) {
//if (distance_field_hint) { // Not implemented.
// RenderingServer::get_singleton()->canvas_item_set_distance_field_mode(p_canvas, true);
//}
- RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, c->rect.size * (float(p_size) / float(base_size))), textures[c->texture_idx]->get_rid(), c->rect, p_color, false, false);
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), textures[c->texture_idx]->get_rid(), c->rect, p_color, false, false);
//if (distance_field_hint) {
// RenderingServer::get_singleton()->canvas_item_set_distance_field_mode(p_canvas, false);
//}
diff --git a/modules/text_server_fb/bitmap_font_fb.h b/modules/text_server_fb/bitmap_font_fb.h
index 73e6d8f791..7cd7507ebc 100644
--- a/modules/text_server_fb/bitmap_font_fb.h
+++ b/modules/text_server_fb/bitmap_font_fb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -70,7 +70,11 @@ public:
virtual void clear_cache() override{};
virtual Error load_from_file(const String &p_filename, int p_base_size) override;
- virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) override;
+ virtual Error bitmap_new(float p_height, float p_ascent, int p_base_size) override;
+
+ virtual void bitmap_add_texture(const Ref<Texture> &p_texture) override;
+ virtual void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override;
+ virtual void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) override;
virtual float get_height(int p_size) const override;
virtual float get_ascent(int p_size) const override;
diff --git a/modules/text_server_fb/config.py b/modules/text_server_fb/config.py
index 491377a369..7a73080ae9 100644
--- a/modules/text_server_fb/config.py
+++ b/modules/text_server_fb/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return env.module_check_dependencies("text_server_fb", ["freetype"])
+ return True
def configure(env):
diff --git a/modules/text_server_fb/dynamic_font_fb.cpp b/modules/text_server_fb/dynamic_font_fb.cpp
index ca9e5b580b..66d36bc885 100644
--- a/modules/text_server_fb/dynamic_font_fb.cpp
+++ b/modules/text_server_fb/dynamic_font_fb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,6 +30,8 @@
#include "dynamic_font_fb.h"
+#ifdef MODULE_FREETYPE_ENABLED
+
#include FT_STROKER_H
#include FT_ADVANCES_H
@@ -54,7 +56,7 @@ DynamicFontDataFallback::DataAtSize *DynamicFontDataFallback::get_data_for_size(
fds = E->get();
} else {
if (font_mem == nullptr && font_path != String()) {
- if (!font_mem_cache.empty()) {
+ if (!font_mem_cache.is_empty()) {
font_mem = font_mem_cache.ptr();
font_mem_size = font_mem_cache.size();
} else {
@@ -124,8 +126,9 @@ DynamicFontDataFallback::DataAtSize *DynamicFontDataFallback::get_data_for_size(
fds->size = p_size;
fds->ascent = (fds->face->size->metrics.ascender / 64.0) / oversampling * fds->scale_color_font;
fds->descent = (-fds->face->size->metrics.descender / 64.0) / oversampling * fds->scale_color_font;
- fds->underline_position = -fds->face->underline_position / 64.0 / oversampling * fds->scale_color_font;
- fds->underline_thickness = fds->face->underline_thickness / 64.0 / oversampling * fds->scale_color_font;
+ fds->underline_position = (-FT_MulFix(fds->face->underline_position, fds->face->size->metrics.y_scale) / 64.0) / oversampling * fds->scale_color_font;
+ fds->underline_thickness = (FT_MulFix(fds->face->underline_thickness, fds->face->size->metrics.y_scale) / 64.0) / oversampling * fds->scale_color_font;
+
if (p_outline_size != 0) {
size_cache_outline[id] = fds;
} else {
@@ -626,7 +629,7 @@ Vector2 DynamicFontDataFallback::draw_glyph(RID p_canvas, int p_size, const Vect
ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2());
if (ch.texture_idx != -1) {
- Point2 cpos = p_pos;
+ Point2i cpos = p_pos;
cpos += ch.align;
Color modulate = p_color;
@@ -658,7 +661,7 @@ Vector2 DynamicFontDataFallback::draw_glyph_outline(RID p_canvas, int p_size, in
ERR_FAIL_COND_V(ch.texture_idx < -1 || ch.texture_idx >= fds->textures.size(), Vector2());
if (ch.texture_idx != -1) {
- Point2 cpos = p_pos;
+ Point2i cpos = p_pos;
cpos += ch.align;
Color modulate = p_color;
@@ -683,3 +686,5 @@ DynamicFontDataFallback::~DynamicFontDataFallback() {
FT_Done_FreeType(library);
}
}
+
+#endif // MODULE_FREETYPE_ENABLED
diff --git a/modules/text_server_fb/dynamic_font_fb.h b/modules/text_server_fb/dynamic_font_fb.h
index 6ac8cb52a8..eb70f46666 100644
--- a/modules/text_server_fb/dynamic_font_fb.h
+++ b/modules/text_server_fb/dynamic_font_fb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,10 @@
#include "font_fb.h"
+#include "modules/modules_enabled.gen.h"
+
+#ifdef MODULE_FREETYPE_ENABLED
+
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -70,14 +74,11 @@ private:
uint32_t size : 16;
uint32_t outline_size : 16;
};
- uint32_t key;
+ uint32_t key = 0;
};
bool operator<(CacheID right) const {
return key < right.key;
}
- CacheID() {
- key = 0;
- }
};
struct DataAtSize {
@@ -86,10 +87,10 @@ private:
int size = 0;
float scale_color_font = 1.f;
- float ascent = 0;
- float descent = 0;
- float underline_position = 0;
- float underline_thickness = 0;
+ float ascent = 0.0;
+ float descent = 0.0;
+ float underline_position = 0.0;
+ float underline_thickness = 0.0;
Vector<CharTexture> textures;
HashMap<char32_t, Character> char_map;
@@ -166,4 +167,6 @@ public:
virtual ~DynamicFontDataFallback() override;
};
+#endif // MODULE_FREETYPE_ENABLED
+
#endif // DYNAMIC_FONT_FALLBACK_H
diff --git a/modules/text_server_fb/font_fb.h b/modules/text_server_fb/font_fb.h
index d2ce2661a1..218f3df03a 100644
--- a/modules/text_server_fb/font_fb.h
+++ b/modules/text_server_fb/font_fb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,11 +37,18 @@ struct FontDataFallback {
Map<String, bool> lang_support_overrides;
Map<String, bool> script_support_overrides;
bool valid = false;
+ int spacing_space = 0;
+ int spacing_glyph = 0;
virtual void clear_cache() = 0;
- virtual Error load_from_file(const String &p_filename, int p_base_size) = 0;
- virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) = 0;
+ virtual Error load_from_file(const String &p_filename, int p_base_size) { return ERR_CANT_CREATE; };
+ virtual Error load_from_memory(const uint8_t *p_data, size_t p_size, int p_base_size) { return ERR_CANT_CREATE; };
+ virtual Error bitmap_new(float p_height, float p_ascent, int p_base_size) { return ERR_CANT_CREATE; };
+
+ virtual void bitmap_add_texture(const Ref<Texture> &p_texture) { ERR_FAIL_MSG("Not supported."); };
+ virtual void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { ERR_FAIL_MSG("Not supported."); };
+ virtual void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) { ERR_FAIL_MSG("Not supported."); };
virtual float get_height(int p_size) const = 0;
virtual float get_ascent(int p_size) const = 0;
@@ -50,6 +57,18 @@ struct FontDataFallback {
virtual float get_underline_position(int p_size) const = 0;
virtual float get_underline_thickness(int p_size) const = 0;
+ virtual int get_spacing_space() const { return spacing_space; };
+ virtual void set_spacing_space(int p_value) {
+ spacing_space = p_value;
+ clear_cache();
+ };
+
+ virtual int get_spacing_glyph() const { return spacing_glyph; };
+ virtual void set_spacing_glyph(int p_value) {
+ spacing_glyph = p_value;
+ clear_cache();
+ };
+
virtual void set_antialiased(bool p_antialiased) = 0;
virtual bool get_antialiased() const = 0;
diff --git a/modules/text_server_fb/register_types.cpp b/modules/text_server_fb/register_types.cpp
index ad4d2d47ab..87cbd2ac2c 100644
--- a/modules/text_server_fb/register_types.cpp
+++ b/modules/text_server_fb/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/text_server_fb/register_types.h b/modules/text_server_fb/register_types.h
index 58f8436c67..c854db92e5 100644
--- a/modules/text_server_fb/register_types.h
+++ b/modules/text_server_fb/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index 675d0e5d4d..60ab14738a 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -107,10 +107,12 @@ RID TextServerFallback::create_font_system(const String &p_name, int p_base_size
RID TextServerFallback::create_font_resource(const String &p_filename, int p_base_size) {
_THREAD_SAFE_METHOD_
FontDataFallback *fd = nullptr;
- if (p_filename.get_extension() == "ttf" || p_filename.get_extension() == "otf" || p_filename.get_extension() == "woff") {
- fd = memnew(DynamicFontDataFallback);
- } else if (p_filename.get_extension() == "fnt" || p_filename.get_extension() == "font") {
+ if (p_filename.get_extension() == "fnt" || p_filename.get_extension() == "font") {
fd = memnew(BitmapFontDataFallback);
+#ifdef MODULE_FREETYPE_ENABLED
+ } else if (p_filename.get_extension() == "ttf" || p_filename.get_extension() == "otf" || p_filename.get_extension() == "woff") {
+ fd = memnew(DynamicFontDataFallback);
+#endif
} else {
return RID();
}
@@ -127,10 +129,12 @@ RID TextServerFallback::create_font_resource(const String &p_filename, int p_bas
RID TextServerFallback::create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size) {
_THREAD_SAFE_METHOD_
FontDataFallback *fd = nullptr;
- if (p_type == "ttf" || p_type == "otf" || p_type == "woff") {
- fd = memnew(DynamicFontDataFallback);
- } else if (p_type == "fnt" || p_type == "font") {
+ if (p_type == "fnt" || p_type == "font") {
fd = memnew(BitmapFontDataFallback);
+#ifdef MODULE_FREETYPE_ENABLED
+ } else if (p_type == "ttf" || p_type == "otf" || p_type == "woff") {
+ fd = memnew(DynamicFontDataFallback);
+#endif
} else {
return RID();
}
@@ -144,6 +148,39 @@ RID TextServerFallback::create_font_memory(const uint8_t *p_data, size_t p_size,
return font_owner.make_rid(fd);
}
+RID TextServerFallback::create_font_bitmap(float p_height, float p_ascent, int p_base_size) {
+ _THREAD_SAFE_METHOD_
+ FontDataFallback *fd = memnew(BitmapFontDataFallback);
+ Error err = fd->bitmap_new(p_height, p_ascent, p_base_size);
+ if (err != OK) {
+ memdelete(fd);
+ return RID();
+ }
+
+ return font_owner.make_rid(fd);
+}
+
+void TextServerFallback::font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) {
+ _THREAD_SAFE_METHOD_
+ FontDataFallback *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->bitmap_add_texture(p_texture);
+}
+
+void TextServerFallback::font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
+ _THREAD_SAFE_METHOD_
+ FontDataFallback *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->bitmap_add_char(p_char, p_texture_idx, p_rect, p_align, p_advance);
+}
+
+void TextServerFallback::font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) {
+ _THREAD_SAFE_METHOD_
+ FontDataFallback *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->bitmap_add_kerning_pair(p_A, p_B, p_kerning);
+}
+
float TextServerFallback::font_get_height(RID p_font, int p_size) const {
_THREAD_SAFE_METHOD_
const FontDataFallback *fd = font_owner.getornull(p_font);
@@ -179,6 +216,34 @@ float TextServerFallback::font_get_underline_thickness(RID p_font, int p_size) c
return fd->get_underline_thickness(p_size);
}
+int TextServerFallback::font_get_spacing_space(RID p_font) const {
+ _THREAD_SAFE_METHOD_
+ const FontDataFallback *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND_V(!fd, 0);
+ return fd->get_spacing_space();
+}
+
+void TextServerFallback::font_set_spacing_space(RID p_font, int p_value) {
+ _THREAD_SAFE_METHOD_
+ FontDataFallback *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->set_spacing_space(p_value);
+}
+
+int TextServerFallback::font_get_spacing_glyph(RID p_font) const {
+ _THREAD_SAFE_METHOD_
+ const FontDataFallback *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND_V(!fd, 0);
+ return fd->get_spacing_glyph();
+}
+
+void TextServerFallback::font_set_spacing_glyph(RID p_font, int p_value) {
+ _THREAD_SAFE_METHOD_
+ FontDataFallback *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND(!fd);
+ fd->set_spacing_glyph(p_value);
+}
+
void TextServerFallback::font_set_antialiased(RID p_font, bool p_antialiased) {
_THREAD_SAFE_METHOD_
FontDataFallback *fd = font_owner.getornull(p_font);
@@ -550,7 +615,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te
ERR_FAIL_COND_V(!sd, false);
ERR_FAIL_COND_V(p_size <= 0, false);
- if (p_text.empty()) {
+ if (p_text.is_empty()) {
return true;
}
@@ -573,7 +638,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te
span.fonts.push_back(p_fonts[i]);
}
}
- ERR_FAIL_COND_V(span.fonts.empty(), false);
+ ERR_FAIL_COND_V(span.fonts.is_empty(), false);
span.font_size = p_size;
span.language = p_language;
@@ -1184,6 +1249,11 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
sd->descent = MAX(sd->descent, Math::round(fd->get_advance(gl.index, gl.font_size).x * 0.5));
}
}
+ if (fd->get_spacing_space() && is_whitespace(sd->text[j])) {
+ gl.advance += fd->get_spacing_space();
+ } else {
+ gl.advance += fd->get_spacing_glyph();
+ }
sd->upos = MAX(sd->upos, fd->get_underline_position(gl.font_size));
sd->uthk = MAX(sd->uthk, fd->get_underline_thickness(gl.font_size));
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index 56bb1f7bf9..b10369d172 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -81,6 +81,11 @@ public:
virtual RID create_font_system(const String &p_name, int p_base_size = 16) override;
virtual RID create_font_resource(const String &p_filename, int p_base_size = 16) override;
virtual RID create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16) override;
+ virtual RID create_font_bitmap(float p_height, float p_ascent, int p_base_size = 16) override;
+
+ virtual void font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) override;
+ virtual void font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) override;
+ virtual void font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) override;
virtual float font_get_height(RID p_font, int p_size) const override;
virtual float font_get_ascent(RID p_font, int p_size) const override;
@@ -89,6 +94,12 @@ public:
virtual float font_get_underline_position(RID p_font, int p_size) const override;
virtual float font_get_underline_thickness(RID p_font, int p_size) const override;
+ virtual int font_get_spacing_space(RID p_font) const override;
+ virtual void font_set_spacing_space(RID p_font, int p_value) override;
+
+ virtual int font_get_spacing_glyph(RID p_font) const override;
+ virtual void font_set_spacing_glyph(RID p_font, int p_value) override;
+
virtual void font_set_antialiased(RID p_font, bool p_antialiased) override;
virtual bool font_get_antialiased(RID p_font) const override;
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
index aa8b3122f4..ef53661557 100644
--- a/modules/tga/image_loader_tga.cpp
+++ b/modules/tga/image_loader_tga.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,6 +56,10 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t
compressed_pos += 1;
count = (c & 0x7f) + 1;
+ if (output_pos + count * p_pixel_size > output_pos) {
+ return ERR_PARSE_ERROR;
+ }
+
if (c & 0x80) {
for (size_t i = 0; i < p_pixel_size; i++) {
pixels_w[i] = p_compressed_buffer[compressed_pos];
@@ -79,7 +83,7 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t
return OK;
}
-Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome) {
+Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome, size_t p_output_size) {
#define TGA_PUT_PIXEL(r, g, b, a) \
int image_data_ofs = ((y * width) + x); \
image_data_w[image_data_ofs * 4 + 0] = r; \
@@ -130,6 +134,9 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
if (p_is_monochrome) {
while (y != y_end) {
while (x != x_end) {
+ if (i > p_output_size) {
+ return ERR_PARSE_ERROR;
+ }
uint8_t shade = p_buffer[i];
TGA_PUT_PIXEL(shade, shade, shade, 0xff)
@@ -143,6 +150,9 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
} else {
while (y != y_end) {
while (x != x_end) {
+ if (i > p_output_size) {
+ return ERR_PARSE_ERROR;
+ }
uint8_t index = p_buffer[i];
uint8_t r = 0x00;
uint8_t g = 0x00;
@@ -171,6 +181,10 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
} else if (p_header.pixel_depth == 24) {
while (y != y_end) {
while (x != x_end) {
+ if (i + 2 > p_output_size) {
+ return ERR_PARSE_ERROR;
+ }
+
uint8_t r = p_buffer[i + 2];
uint8_t g = p_buffer[i + 1];
uint8_t b = p_buffer[i + 0];
@@ -186,6 +200,10 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
} else if (p_header.pixel_depth == 32) {
while (y != y_end) {
while (x != x_end) {
+ if (i + 3 > p_output_size) {
+ return ERR_PARSE_ERROR;
+ }
+
uint8_t a = p_buffer[i + 3];
uint8_t r = p_buffer[i + 2];
uint8_t g = p_buffer[i + 1];
@@ -279,7 +297,7 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
const uint8_t *src_image_r = src_image.ptr();
const size_t pixel_size = tga_header.pixel_depth >> 3;
- const size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size;
+ size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size;
Vector<uint8_t> uncompressed_buffer;
uncompressed_buffer.resize(buffer_size);
@@ -297,11 +315,12 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
}
} else {
buffer = src_image_r;
+ buffer_size = src_image_len;
};
if (err == OK) {
const uint8_t *palette_r = palette.ptr();
- err = convert_to_image(p_image, buffer, tga_header, palette_r, is_monochrome);
+ err = convert_to_image(p_image, buffer, tga_header, palette_r, is_monochrome, buffer_size);
}
}
diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h
index 6b3d33e7ef..cb2ce07edd 100644
--- a/modules/tga/image_loader_tga.h
+++ b/modules/tga/image_loader_tga.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,23 +57,23 @@ class ImageLoaderTGA : public ImageFormatLoader {
};
struct tga_header_s {
- uint8_t id_length;
- uint8_t color_map_type;
+ uint8_t id_length = 0;
+ uint8_t color_map_type = 0;
tga_type_e image_type;
- uint16_t first_color_entry;
- uint16_t color_map_length;
- uint8_t color_map_depth;
+ uint16_t first_color_entry = 0;
+ uint16_t color_map_length = 0;
+ uint8_t color_map_depth = 0;
- uint16_t x_origin;
- uint16_t y_origin;
- uint16_t image_width;
- uint16_t image_height;
- uint8_t pixel_depth;
- uint8_t image_descriptor;
+ uint16_t x_origin = 0;
+ uint16_t y_origin = 0;
+ uint16_t image_width = 0;
+ uint16_t image_height = 0;
+ uint8_t pixel_depth = 0;
+ uint8_t image_descriptor = 0;
};
static Error decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size);
- static Error convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome);
+ static Error convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome, size_t p_output_size);
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
diff --git a/modules/tga/register_types.cpp b/modules/tga/register_types.cpp
index 320f748083..9e5fe124ef 100644
--- a/modules/tga/register_types.cpp
+++ b/modules/tga/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/tga/register_types.h b/modules/tga/register_types.h
index 94a77d295e..0dcd750250 100644
--- a/modules/tga/register_types.h
+++ b/modules/tga/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/theora/register_types.cpp b/modules/theora/register_types.cpp
index 0676cab5c5..0218b8c7a4 100644
--- a/modules/theora/register_types.cpp
+++ b/modules/theora/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/theora/register_types.h b/modules/theora/register_types.h
index 4f0670b2c7..654d70e417 100644
--- a/modules/theora/register_types.h
+++ b/modules/theora/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 4f33f58ed1..c5f6dc0d99 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -140,9 +140,7 @@ void VideoStreamPlaybackTheora::clear() {
#ifdef THEORA_USE_THREAD_STREAMING
thread_exit = true;
thread_sem->post(); //just in case
- Thread::wait_to_finish(thread);
- memdelete(thread);
- thread = nullptr;
+ thread.wait_to_finish();
ring_buffer.clear();
#endif
@@ -181,7 +179,7 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
int read = file->get_buffer(read_buffer.ptr(), to_read);
ring_buffer.write(read_buffer.ptr(), read);
- thread = Thread::create(_streaming_thread, this);
+ thread.start(_streaming_thread, this);
#endif
@@ -556,7 +554,7 @@ void VideoStreamPlaybackTheora::play() {
}
playing = true;
- delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms");
+ delay_compensation = ProjectSettings::get_singleton()->get("audio/video/video_delay_compensation_ms");
delay_compensation /= 1000.0;
};
@@ -647,31 +645,13 @@ void VideoStreamPlaybackTheora::_streaming_thread(void *ud) {
#endif
VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
- file = nullptr;
- theora_p = 0;
- vorbis_p = 0;
- videobuf_ready = 0;
- playing = false;
- frames_pending = 0;
- videobuf_time = 0;
- paused = false;
-
- buffering = false;
texture = Ref<ImageTexture>(memnew(ImageTexture));
- mix_callback = nullptr;
- mix_udata = nullptr;
- audio_track = 0;
- delay_compensation = 0;
- audio_frames_wrote = 0;
#ifdef THEORA_USE_THREAD_STREAMING
int rb_power = nearest_shift(RB_SIZE_KB * 1024);
ring_buffer.resize(rb_power);
read_buffer.resize(RB_SIZE_KB * 1024);
thread_sem = Semaphore::create();
- thread = nullptr;
- thread_exit = false;
- thread_eof = false;
#endif
};
@@ -697,7 +677,7 @@ void VideoStreamTheora::_bind_methods() {
////////////
-RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h
index 867f464038..2685a8a013 100644
--- a/modules/theora/video_stream_theora.h
+++ b/modules/theora/video_stream_theora.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,6 +36,7 @@
#include "core/os/semaphore.h"
#include "core/os/thread.h"
#include "core/templates/ring_buffer.h"
+#include "core/templates/safe_refcount.h"
#include "scene/resources/video_stream.h"
#include "servers/audio_server.h"
@@ -52,12 +53,12 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
};
//Image frames[MAX_FRAMES];
- Image::Format format;
+ Image::Format format = Image::Format::FORMAT_L8;
Vector<uint8_t> frame_data;
- int frames_pending;
- FileAccess *file;
+ int frames_pending = 0;
+ FileAccess *file = nullptr;
String file_name;
- int audio_frames_wrote;
+ int audio_frames_wrote = 0;
Point2i size;
int buffer_data();
@@ -65,8 +66,8 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
void video_write();
float get_time() const;
- bool theora_eos;
- bool vorbis_eos;
+ bool theora_eos = false;
+ bool vorbis_eos = false;
ogg_sync_state oy;
ogg_page og;
@@ -74,33 +75,33 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
ogg_stream_state to;
th_info ti;
th_comment tc;
- th_dec_ctx *td;
+ th_dec_ctx *td = nullptr;
vorbis_info vi;
vorbis_dsp_state vd;
vorbis_block vb;
vorbis_comment vc;
th_pixel_fmt px_fmt;
- double videobuf_time;
- int pp_inc;
+ double videobuf_time = 0;
+ int pp_inc = 0;
- int theora_p;
- int vorbis_p;
- int pp_level_max;
- int pp_level;
- int videobuf_ready;
+ int theora_p = 0;
+ int vorbis_p = 0;
+ int pp_level_max = 0;
+ int pp_level = 0;
+ int videobuf_ready = 0;
- bool playing;
- bool buffering;
+ bool playing = false;
+ bool buffering = false;
- double last_update_time;
- double time;
- double delay_compensation;
+ double last_update_time = 0;
+ double time = 0;
+ double delay_compensation = 0;
Ref<ImageTexture> texture;
AudioMixCallback mix_callback;
- void *mix_udata;
- bool paused;
+ void *mix_udata = nullptr;
+ bool paused = false;
#ifdef THEORA_USE_THREAD_STREAMING
@@ -110,16 +111,16 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
RingBuffer<uint8_t> ring_buffer;
Vector<uint8_t> read_buffer;
- bool thread_eof;
+ bool thread_eof = false;
Semaphore *thread_sem;
- Thread *thread;
- volatile bool thread_exit;
+ Thread thread;
+ SafeFlag thread_exit;
static void _streaming_thread(void *ud);
#endif
- int audio_track;
+ int audio_track = 0;
protected:
void clear();
@@ -185,7 +186,7 @@ public:
class ResourceFormatLoaderTheora : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 75dc16c39a..47214e6974 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h
index ff040b0915..34390fccb0 100644
--- a/modules/tinyexr/image_loader_tinyexr.h
+++ b/modules/tinyexr/image_loader_tinyexr.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/tinyexr/image_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp
index 420619bd5f..f747763248 100644
--- a/modules/tinyexr/image_saver_tinyexr.cpp
+++ b/modules/tinyexr/image_saver_tinyexr.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/tinyexr/image_saver_tinyexr.h b/modules/tinyexr/image_saver_tinyexr.h
index c7154bcfc7..e5060ef11c 100644
--- a/modules/tinyexr/image_saver_tinyexr.h
+++ b/modules/tinyexr/image_saver_tinyexr.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/tinyexr/register_types.cpp b/modules/tinyexr/register_types.cpp
index 9d0fb8729e..ecbabc4951 100644
--- a/modules/tinyexr/register_types.cpp
+++ b/modules/tinyexr/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/tinyexr/register_types.h b/modules/tinyexr/register_types.h
index 9739488312..e401f37066 100644
--- a/modules/tinyexr/register_types.h
+++ b/modules/tinyexr/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/upnp/register_types.cpp b/modules/upnp/register_types.cpp
index e66bc9d11a..a5ee39517f 100644
--- a/modules/upnp/register_types.cpp
+++ b/modules/upnp/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/upnp/register_types.h b/modules/upnp/register_types.h
index 0c71db9ffa..768031c4d9 100644
--- a/modules/upnp/register_types.h
+++ b/modules/upnp/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp
index 988bf3017d..cff13251ce 100644
--- a/modules/upnp/upnp.cpp
+++ b/modules/upnp/upnp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
#include <stdlib.h>
bool UPNP::is_common_device(const String &dev) const {
- return dev.empty() ||
+ return dev.is_empty() ||
dev.find("InternetGatewayDevice") >= 0 ||
dev.find("WANIPConnection") >= 0 ||
dev.find("WANPPPConnection") >= 0 ||
@@ -76,7 +76,7 @@ int UPNP::discover(int timeout, int ttl, const String &device_filter) {
struct UPNPDev *dev = devlist;
while (dev) {
- if (device_filter.empty() || strstr(dev->st, device_filter.utf8().get_data())) {
+ if (device_filter.is_empty() || strstr(dev->st, device_filter.utf8().get_data())) {
add_device_to_list(dev, devlist);
}
@@ -393,9 +393,6 @@ void UPNP::_bind_methods() {
}
UPNP::UPNP() {
- discover_multicast_if = "";
- discover_local_port = 0;
- discover_ipv6 = false;
}
UPNP::~UPNP() {
diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h
index 81d770ec4c..a0cca96bc8 100644
--- a/modules/upnp/upnp.h
+++ b/modules/upnp/upnp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,9 +41,9 @@ class UPNP : public Reference {
GDCLASS(UPNP, Reference);
private:
- String discover_multicast_if;
- int discover_local_port;
- bool discover_ipv6;
+ String discover_multicast_if = "";
+ int discover_local_port = 0;
+ bool discover_ipv6 = false;
Vector<Ref<UPNPDevice>> devices;
diff --git a/modules/upnp/upnp_device.cpp b/modules/upnp/upnp_device.cpp
index 40eb6106a0..ddc66d593c 100644
--- a/modules/upnp/upnp_device.cpp
+++ b/modules/upnp/upnp_device.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,7 +65,7 @@ int UPNPDevice::add_port_mapping(int port, int port_internal, String desc, Strin
itos(port).utf8().get_data(),
itos(port_internal).utf8().get_data(),
igd_our_addr.utf8().get_data(),
- desc.empty() ? nullptr : desc.utf8().get_data(),
+ desc.is_empty() ? nullptr : desc.utf8().get_data(),
proto.utf8().get_data(),
nullptr, // Remote host, always nullptr as IGDs don't support it
duration > 0 ? itos(duration).utf8().get_data() : nullptr);
diff --git a/modules/upnp/upnp_device.h b/modules/upnp/upnp_device.h
index 53d621c90a..126e761a56 100644
--- a/modules/upnp/upnp_device.h
+++ b/modules/upnp/upnp_device.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/vhacd/register_types.cpp b/modules/vhacd/register_types.cpp
index 40c5e47440..daad39bdfb 100644
--- a/modules/vhacd/register_types.cpp
+++ b/modules/vhacd/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/vhacd/register_types.h b/modules/vhacd/register_types.h
index d02a990901..24ad9378f4 100644
--- a/modules/vhacd/register_types.h
+++ b/modules/vhacd/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml
index 088d84d2ec..5112ea43a7 100644
--- a/modules/visual_script/doc_classes/VisualScript.xml
+++ b/modules/visual_script/doc_classes/VisualScript.xml
@@ -26,23 +26,23 @@
</return>
<argument index="0" name="name" type="StringName">
</argument>
+ <argument index="1" name="func_node_id" type="int">
+ </argument>
<description>
- Add a function with the specified name to the VisualScript.
+ Add a function with the specified name to the VisualScript, and assign the root [VisualScriptFunction] node's id as [code]func_node_id[/code].
</description>
</method>
<method name="add_node">
<return type="void">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="id" type="int">
+ <argument index="0" name="id" type="int">
</argument>
- <argument index="2" name="node" type="VisualScriptNode">
+ <argument index="1" name="node" type="VisualScriptNode">
</argument>
- <argument index="3" name="position" type="Vector2" default="Vector2( 0, 0 )">
+ <argument index="2" name="position" type="Vector2" default="Vector2( 0, 0 )">
</argument>
<description>
- Add a node to a function of the VisualScript.
+ Add a node to the VisualScript.
</description>
</method>
<method name="add_variable">
@@ -157,15 +157,13 @@
<method name="data_connect">
<return type="void">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="from_node" type="int">
+ <argument index="0" name="from_node" type="int">
</argument>
- <argument index="2" name="from_port" type="int">
+ <argument index="1" name="from_port" type="int">
</argument>
- <argument index="3" name="to_node" type="int">
+ <argument index="2" name="to_node" type="int">
</argument>
- <argument index="4" name="to_port" type="int">
+ <argument index="3" name="to_port" type="int">
</argument>
<description>
Connect two data ports. The value of [code]from_node[/code]'s [code]from_port[/code] would be fed into [code]to_node[/code]'s [code]to_port[/code].
@@ -174,15 +172,13 @@
<method name="data_disconnect">
<return type="void">
</return>
- <argument index="0" name="func" type="StringName">
+ <argument index="0" name="from_node" type="int">
</argument>
- <argument index="1" name="from_node" type="int">
+ <argument index="1" name="from_port" type="int">
</argument>
- <argument index="2" name="from_port" type="int">
+ <argument index="2" name="to_node" type="int">
</argument>
- <argument index="3" name="to_node" type="int">
- </argument>
- <argument index="4" name="to_port" type="int">
+ <argument index="3" name="to_port" type="int">
</argument>
<description>
Disconnect two data ports previously connected with [method data_connect].
@@ -197,37 +193,31 @@
Returns the id of a function's entry point node.
</description>
</method>
- <method name="get_function_scroll" qualifiers="const">
- <return type="Vector2">
- </return>
- <argument index="0" name="name" type="StringName">
- </argument>
- <description>
- Returns the position of the center of the screen for a given function.
- </description>
- </method>
<method name="get_node" qualifiers="const">
<return type="VisualScriptNode">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="id" type="int">
+ <argument index="0" name="id" type="int">
</argument>
<description>
- Returns a node given its id and its function.
+ Returns a node given its id.
</description>
</method>
<method name="get_node_position" qualifiers="const">
<return type="Vector2">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="id" type="int">
+ <argument index="0" name="id" type="int">
</argument>
<description>
Returns a node's position in pixels.
</description>
</method>
+ <method name="get_scroll" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ Returns the current position of the center of the screen.
+ </description>
+ </method>
<method name="get_variable_default_value" qualifiers="const">
<return type="Variant">
</return>
@@ -267,15 +257,13 @@
<method name="has_data_connection" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="from_node" type="int">
+ <argument index="0" name="from_node" type="int">
</argument>
- <argument index="2" name="from_port" type="int">
+ <argument index="1" name="from_port" type="int">
</argument>
- <argument index="3" name="to_node" type="int">
+ <argument index="2" name="to_node" type="int">
</argument>
- <argument index="4" name="to_port" type="int">
+ <argument index="3" name="to_port" type="int">
</argument>
<description>
Returns whether the specified data ports are connected.
@@ -293,9 +281,7 @@
<method name="has_node" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="id" type="int">
+ <argument index="0" name="id" type="int">
</argument>
<description>
Returns whether a node exists with the given id.
@@ -304,13 +290,11 @@
<method name="has_sequence_connection" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="from_node" type="int">
+ <argument index="0" name="from_node" type="int">
</argument>
- <argument index="2" name="from_output" type="int">
+ <argument index="1" name="from_output" type="int">
</argument>
- <argument index="3" name="to_node" type="int">
+ <argument index="2" name="to_node" type="int">
</argument>
<description>
Returns whether the specified sequence ports are connected.
@@ -346,12 +330,10 @@
<method name="remove_node">
<return type="void">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="id" type="int">
+ <argument index="0" name="id" type="int">
</argument>
<description>
- Remove a specific node.
+ Remove the node with the specified id.
</description>
</method>
<method name="remove_variable">
@@ -399,13 +381,11 @@
<method name="sequence_connect">
<return type="void">
</return>
- <argument index="0" name="func" type="StringName">
+ <argument index="0" name="from_node" type="int">
</argument>
- <argument index="1" name="from_node" type="int">
+ <argument index="1" name="from_output" type="int">
</argument>
- <argument index="2" name="from_output" type="int">
- </argument>
- <argument index="3" name="to_node" type="int">
+ <argument index="2" name="to_node" type="int">
</argument>
<description>
Connect two sequence ports. The execution will flow from of [code]from_node[/code]'s [code]from_output[/code] into [code]to_node[/code].
@@ -415,29 +395,16 @@
<method name="sequence_disconnect">
<return type="void">
</return>
- <argument index="0" name="func" type="StringName">
- </argument>
- <argument index="1" name="from_node" type="int">
+ <argument index="0" name="from_node" type="int">
</argument>
- <argument index="2" name="from_output" type="int">
+ <argument index="1" name="from_output" type="int">
</argument>
- <argument index="3" name="to_node" type="int">
+ <argument index="2" name="to_node" type="int">
</argument>
<description>
Disconnect two sequence ports previously connected with [method sequence_connect].
</description>
</method>
- <method name="set_function_scroll">
- <return type="void">
- </return>
- <argument index="0" name="name" type="StringName">
- </argument>
- <argument index="1" name="ofs" type="Vector2">
- </argument>
- <description>
- Position the center of the screen for a function.
- </description>
- </method>
<method name="set_instance_base_type">
<return type="void">
</return>
@@ -450,14 +417,21 @@
<method name="set_node_position">
<return type="void">
</return>
- <argument index="0" name="func" type="StringName">
+ <argument index="0" name="id" type="int">
</argument>
- <argument index="1" name="id" type="int">
+ <argument index="1" name="position" type="Vector2">
</argument>
- <argument index="2" name="position" type="Vector2">
+ <description>
+ Set the node position in the VisualScript graph.
+ </description>
+ </method>
+ <method name="set_scroll">
+ <return type="void">
+ </return>
+ <argument index="0" name="ofs" type="Vector2">
</argument>
<description>
- Position a node on the screen.
+ Set the screen center to the given position.
</description>
</method>
<method name="set_variable_default_value">
@@ -496,9 +470,7 @@
</methods>
<signals>
<signal name="node_ports_changed">
- <argument index="0" name="function" type="String">
- </argument>
- <argument index="1" name="id" type="int">
+ <argument index="0" name="id" type="int">
</argument>
<description>
Emitted when the ports of a node are changed.
diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
index 000fbd0140..219ffd01d3 100644
--- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
+++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
@@ -92,7 +92,7 @@
<constant name="MATH_STEP_DECIMALS" value="24" enum="BuiltinFunc">
Return the number of digit places after the decimal that the first non-zero digit occurs.
</constant>
- <constant name="MATH_STEPIFY" value="25" enum="BuiltinFunc">
+ <constant name="MATH_SNAPPED" value="25" enum="BuiltinFunc">
Return the input snapped to a given step.
</constant>
<constant name="MATH_LERP" value="26" enum="BuiltinFunc">
@@ -202,24 +202,20 @@
<constant name="BYTES_TO_VAR" value="62" enum="BuiltinFunc">
Deserialize a [Variant] from a [PackedByteArray] serialized using [constant VAR_TO_BYTES].
</constant>
- <constant name="COLORN" value="63" enum="BuiltinFunc">
- Return the [Color] with the given name and alpha ranging from 0 to 1.
- [b]Note:[/b] Names are defined in [code]color_names.inc[/code].
- </constant>
- <constant name="MATH_SMOOTHSTEP" value="64" enum="BuiltinFunc">
+ <constant name="MATH_SMOOTHSTEP" value="63" enum="BuiltinFunc">
Return a number smoothly interpolated between the first two inputs, based on the third input. Similar to [constant MATH_LERP], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula:
[codeblock]
var t = clamp((weight - from) / (to - from), 0.0, 1.0)
return t * t * (3.0 - 2.0 * t)
[/codeblock]
</constant>
- <constant name="MATH_POSMOD" value="65" enum="BuiltinFunc">
+ <constant name="MATH_POSMOD" value="64" enum="BuiltinFunc">
</constant>
- <constant name="MATH_LERP_ANGLE" value="66" enum="BuiltinFunc">
+ <constant name="MATH_LERP_ANGLE" value="65" enum="BuiltinFunc">
</constant>
- <constant name="TEXT_ORD" value="67" enum="BuiltinFunc">
+ <constant name="TEXT_ORD" value="66" enum="BuiltinFunc">
</constant>
- <constant name="FUNC_MAX" value="68" enum="BuiltinFunc">
+ <constant name="FUNC_MAX" value="67" enum="BuiltinFunc">
Represents the size of the [enum BuiltinFunc] enum.
</constant>
</constants>
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index 0172f29923..4c7b66e368 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/visual_script/register_types.h b/modules/visual_script/register_types.h
index c18c2930b1..b02a93ebc1 100644
--- a/modules/visual_script/register_types.h
+++ b/modules/visual_script/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index f9ef184579..2517b17168 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
#include "scene/main/node.h"
#include "visual_script_nodes.h"
-//used by editor, this is not really saved
+// Used by editor, this is not really saved.
void VisualScriptNode::set_breakpoint(bool p_breakpoint) {
breakpoint = p_breakpoint;
}
@@ -55,8 +55,8 @@ void VisualScriptNode::set_default_input_value(int p_port, const Variant &p_valu
default_input_values[p_port] = p_value;
#ifdef TOOLS_ENABLED
- for (Set<VisualScript *>::Element *E = scripts_used.front(); E; E = E->next()) {
- E->get()->set_edited(true);
+ if (script_used.is_valid()) {
+ script_used->set_edited(true);
}
#endif
}
@@ -73,14 +73,14 @@ void VisualScriptNode::_set_default_input_values(Array p_values) {
void VisualScriptNode::validate_input_default_values() {
default_input_values.resize(MAX(default_input_values.size(), get_input_value_port_count())); //let it grow as big as possible, we don't want to lose values on resize
- //actually validate on save
+ // Actually validate on save.
for (int i = 0; i < get_input_value_port_count(); i++) {
Variant::Type expected = get_input_value_port_info(i).type;
if (expected == Variant::NIL || expected == default_input_values[i].get_type()) {
continue;
} else {
- //not the same, reconvert
+ // Not the same, reconvert.
Callable::CallError ce;
Variant existing = default_input_values[i];
const Variant *existingp = &existing;
@@ -94,7 +94,7 @@ void VisualScriptNode::validate_input_default_values() {
}
Array VisualScriptNode::_get_default_input_values() const {
- //validate on save, since on load there is little info about this
+ // Validate on save, since on load there is little info about this.
Array values = default_input_values;
values.resize(get_input_value_port_count());
@@ -118,6 +118,8 @@ void VisualScriptNode::_bind_methods() {
}
VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inputs, int p_output) const {
+ ERR_FAIL_COND_V(get_output_value_port_count() <= p_output, TypeGuess());
+
PropertyInfo pinfo = get_output_value_port_info(p_output);
TypeGuess tg;
@@ -131,15 +133,10 @@ VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inp
}
Ref<VisualScript> VisualScriptNode::get_visual_script() const {
- if (scripts_used.size()) {
- return Ref<VisualScript>(scripts_used.front()->get());
- }
-
- return Ref<VisualScript>();
+ return script_used;
}
VisualScriptNode::VisualScriptNode() {
- breakpoint = false;
}
////////////////
@@ -147,8 +144,6 @@ VisualScriptNode::VisualScriptNode() {
/////////////////////
VisualScriptNodeInstance::VisualScriptNodeInstance() {
- sequence_outputs = nullptr;
- input_ports = nullptr;
}
VisualScriptNodeInstance::~VisualScriptNodeInstance() {
@@ -165,13 +160,15 @@ VisualScriptNodeInstance::~VisualScriptNodeInstance() {
}
}
-void VisualScript::add_function(const StringName &p_name) {
+void VisualScript::add_function(const StringName &p_name, int p_func_node_id) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!String(p_name).is_valid_identifier());
ERR_FAIL_COND(functions.has(p_name));
+ ERR_FAIL_COND(variables.has(p_name));
+ ERR_FAIL_COND(custom_signals.has(p_name));
functions[p_name] = Function();
- functions[p_name].scroll = Vector2(-50, -100);
+ functions[p_name].func_id = p_func_node_id;
}
bool VisualScript::has_function(const StringName &p_name) const {
@@ -182,11 +179,7 @@ void VisualScript::remove_function(const StringName &p_name) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!functions.has(p_name));
- for (Map<int, Function::NodeData>::Element *E = functions[p_name].nodes.front(); E; E = E->next()) {
- E->get().node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed));
- E->get().node->scripts_used.erase(this);
- }
-
+ // Let the editor handle the node removal.
functions.erase(p_name);
}
@@ -207,53 +200,36 @@ void VisualScript::rename_function(const StringName &p_name, const StringName &p
functions.erase(p_name);
}
-void VisualScript::set_function_scroll(const StringName &p_name, const Vector2 &p_scroll) {
- ERR_FAIL_COND(!functions.has(p_name));
- functions[p_name].scroll = p_scroll;
+void VisualScript::set_scroll(const Vector2 &p_scroll) {
+ scroll = p_scroll;
}
-Vector2 VisualScript::get_function_scroll(const StringName &p_name) const {
- ERR_FAIL_COND_V(!functions.has(p_name), Vector2());
- return functions[p_name].scroll;
+Vector2 VisualScript::get_scroll() const {
+ return scroll;
}
void VisualScript::get_function_list(List<StringName> *r_functions) const {
- for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
- r_functions->push_back(E->key());
- }
-
- r_functions->sort_custom<StringName::AlphCompare>();
+ functions.get_key_list(r_functions);
+ // r_functions->sort_custom<StringName::AlphCompare>(); // Don't force sorting.
}
int VisualScript::get_function_node_id(const StringName &p_name) const {
ERR_FAIL_COND_V(!functions.has(p_name), -1);
- return functions[p_name].function_id;
+ return functions[p_name].func_id;
}
void VisualScript::_node_ports_changed(int p_id) {
- StringName function;
-
- for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
- if (E->get().nodes.has(p_id)) {
- function = E->key();
- break;
- }
- }
-
- ERR_FAIL_COND(function == StringName());
-
- Function &func = functions[function];
- Ref<VisualScriptNode> vsn = func.nodes[p_id].node;
+ Ref<VisualScriptNode> vsn = nodes[p_id].node;
vsn->validate_input_default_values();
- //must revalidate all the functions
+ // Must revalidate all the functions.
{
List<SequenceConnection> to_remove;
- for (Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) {
+ for (Set<SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) {
if (E->get().from_node == p_id && E->get().from_output >= vsn->get_output_sequence_port_count()) {
to_remove.push_back(E->get());
}
@@ -263,7 +239,7 @@ void VisualScript::_node_ports_changed(int p_id) {
}
while (to_remove.size()) {
- func.sequence_connections.erase(to_remove.front()->get());
+ sequence_connections.erase(to_remove.front()->get());
to_remove.pop_front();
}
}
@@ -271,7 +247,7 @@ void VisualScript::_node_ports_changed(int p_id) {
{
List<DataConnection> to_remove;
- for (Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) {
+ for (Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
if (E->get().from_node == p_id && E->get().from_port >= vsn->get_output_value_port_count()) {
to_remove.push_back(E->get());
}
@@ -281,63 +257,47 @@ void VisualScript::_node_ports_changed(int p_id) {
}
while (to_remove.size()) {
- func.data_connections.erase(to_remove.front()->get());
+ data_connections.erase(to_remove.front()->get());
to_remove.pop_front();
}
}
#ifdef TOOLS_ENABLED
- set_edited(true); //something changed, let's set as edited
- emit_signal("node_ports_changed", function, p_id);
+ set_edited(true); // Something changed, let's set as edited.
+ emit_signal("node_ports_changed", p_id);
#endif
}
-void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos) {
+void VisualScript::add_node(int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos) {
ERR_FAIL_COND(instances.size());
- ERR_FAIL_COND(!functions.has(p_func));
-
- for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
- ERR_FAIL_COND(E->get().nodes.has(p_id)); //id can exist only one in script, even for different functions
- }
+ ERR_FAIL_COND(nodes.has(p_id)); // ID can exist only one in script.
- Function &func = functions[p_func];
-
- if (Object::cast_to<VisualScriptFunction>(*p_node)) {
- //the function indeed
- ERR_FAIL_COND_MSG(func.function_id >= 0, "A function node has already been set here.");
-
- func.function_id = p_id;
- }
-
- Function::NodeData nd;
+ NodeData nd;
nd.node = p_node;
nd.pos = p_pos;
Ref<VisualScriptNode> vsn = p_node;
vsn->connect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed), varray(p_id));
- vsn->scripts_used.insert(this);
- vsn->validate_input_default_values(); // Validate when fully loaded
+ vsn->script_used = Ref<VisualScript>(this);
+ vsn->validate_input_default_values(); // Validate when fully loaded.
- func.nodes[p_id] = nd;
+ nodes[p_id] = nd;
}
-void VisualScript::remove_node(const StringName &p_func, int p_id) {
+void VisualScript::remove_node(int p_id) {
ERR_FAIL_COND(instances.size());
- ERR_FAIL_COND(!functions.has(p_func));
- Function &func = functions[p_func];
-
- ERR_FAIL_COND(!func.nodes.has(p_id));
+ ERR_FAIL_COND(!nodes.has(p_id));
{
List<SequenceConnection> to_remove;
- for (Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) {
+ for (Set<SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) {
if (E->get().from_node == p_id || E->get().to_node == p_id) {
to_remove.push_back(E->get());
}
}
while (to_remove.size()) {
- func.sequence_connections.erase(to_remove.front()->get());
+ sequence_connections.erase(to_remove.front()->get());
to_remove.pop_front();
}
}
@@ -345,122 +305,88 @@ void VisualScript::remove_node(const StringName &p_func, int p_id) {
{
List<DataConnection> to_remove;
- for (Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) {
+ for (Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
if (E->get().from_node == p_id || E->get().to_node == p_id) {
to_remove.push_back(E->get());
}
}
while (to_remove.size()) {
- func.data_connections.erase(to_remove.front()->get());
+ data_connections.erase(to_remove.front()->get());
to_remove.pop_front();
}
}
- if (Object::cast_to<VisualScriptFunction>(func.nodes[p_id].node.ptr())) {
- func.function_id = -1; //revert to invalid
- }
+ nodes[p_id].node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed));
+ nodes[p_id].node->script_used.unref();
- func.nodes[p_id].node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed));
- func.nodes[p_id].node->scripts_used.erase(this);
-
- func.nodes.erase(p_id);
+ nodes.erase(p_id);
}
-bool VisualScript::has_node(const StringName &p_func, int p_id) const {
- ERR_FAIL_COND_V(!functions.has(p_func), false);
- const Function &func = functions[p_func];
-
- return func.nodes.has(p_id);
+bool VisualScript::has_node(int p_id) const {
+ return nodes.has(p_id);
}
-Ref<VisualScriptNode> VisualScript::get_node(const StringName &p_func, int p_id) const {
- ERR_FAIL_COND_V(!functions.has(p_func), Ref<VisualScriptNode>());
- const Function &func = functions[p_func];
-
- ERR_FAIL_COND_V(!func.nodes.has(p_id), Ref<VisualScriptNode>());
+Ref<VisualScriptNode> VisualScript::get_node(int p_id) const {
+ ERR_FAIL_COND_V(!nodes.has(p_id), Ref<VisualScriptNode>());
- return func.nodes[p_id].node;
+ return nodes[p_id].node;
}
-void VisualScript::set_node_position(const StringName &p_func, int p_id, const Point2 &p_pos) {
+void VisualScript::set_node_position(int p_id, const Point2 &p_pos) {
ERR_FAIL_COND(instances.size());
- ERR_FAIL_COND(!functions.has(p_func));
- Function &func = functions[p_func];
-
- ERR_FAIL_COND(!func.nodes.has(p_id));
- func.nodes[p_id].pos = p_pos;
+ ERR_FAIL_COND(!nodes.has(p_id));
+ nodes[p_id].pos = p_pos;
}
-Point2 VisualScript::get_node_position(const StringName &p_func, int p_id) const {
- ERR_FAIL_COND_V(!functions.has(p_func), Point2());
- const Function &func = functions[p_func];
-
- ERR_FAIL_COND_V(!func.nodes.has(p_id), Point2());
- return func.nodes[p_id].pos;
+Point2 VisualScript::get_node_position(int p_id) const {
+ ERR_FAIL_COND_V(!nodes.has(p_id), Point2());
+ return nodes[p_id].pos;
}
-void VisualScript::get_node_list(const StringName &p_func, List<int> *r_nodes) const {
- ERR_FAIL_COND(!functions.has(p_func));
- const Function &func = functions[p_func];
-
- for (const Map<int, Function::NodeData>::Element *E = func.nodes.front(); E; E = E->next()) {
- r_nodes->push_back(E->key());
- }
+void VisualScript::get_node_list(List<int> *r_nodes) const {
+ nodes.get_key_list(r_nodes);
}
-void VisualScript::sequence_connect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) {
+void VisualScript::sequence_connect(int p_from_node, int p_from_output, int p_to_node) {
ERR_FAIL_COND(instances.size());
- ERR_FAIL_COND(!functions.has(p_func));
- Function &func = functions[p_func];
SequenceConnection sc;
sc.from_node = p_from_node;
sc.from_output = p_from_output;
sc.to_node = p_to_node;
- ERR_FAIL_COND(func.sequence_connections.has(sc));
+ ERR_FAIL_COND(sequence_connections.has(sc));
- func.sequence_connections.insert(sc);
+ sequence_connections.insert(sc);
}
-void VisualScript::sequence_disconnect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) {
- ERR_FAIL_COND(!functions.has(p_func));
- Function &func = functions[p_func];
-
+void VisualScript::sequence_disconnect(int p_from_node, int p_from_output, int p_to_node) {
SequenceConnection sc;
sc.from_node = p_from_node;
sc.from_output = p_from_output;
sc.to_node = p_to_node;
- ERR_FAIL_COND(!func.sequence_connections.has(sc));
+ ERR_FAIL_COND(!sequence_connections.has(sc));
- func.sequence_connections.erase(sc);
+ sequence_connections.erase(sc);
}
-bool VisualScript::has_sequence_connection(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) const {
- ERR_FAIL_COND_V(!functions.has(p_func), false);
- const Function &func = functions[p_func];
-
+bool VisualScript::has_sequence_connection(int p_from_node, int p_from_output, int p_to_node) const {
SequenceConnection sc;
sc.from_node = p_from_node;
sc.from_output = p_from_output;
sc.to_node = p_to_node;
- return func.sequence_connections.has(sc);
+ return sequence_connections.has(sc);
}
-void VisualScript::get_sequence_connection_list(const StringName &p_func, List<SequenceConnection> *r_connection) const {
- ERR_FAIL_COND(!functions.has(p_func));
- const Function &func = functions[p_func];
-
- for (const Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) {
+void VisualScript::get_sequence_connection_list(List<SequenceConnection> *r_connection) const {
+ for (const Set<SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) {
r_connection->push_back(E->get());
}
}
-void VisualScript::data_connect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
+void VisualScript::data_connect(int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
ERR_FAIL_COND(instances.size());
- ERR_FAIL_COND(!functions.has(p_func));
- Function &func = functions[p_func];
DataConnection dc;
dc.from_node = p_from_node;
@@ -468,72 +394,55 @@ void VisualScript::data_connect(const StringName &p_func, int p_from_node, int p
dc.to_node = p_to_node;
dc.to_port = p_to_port;
- ERR_FAIL_COND(func.data_connections.has(dc));
+ ERR_FAIL_COND(data_connections.has(dc));
- func.data_connections.insert(dc);
+ data_connections.insert(dc);
}
-void VisualScript::data_disconnect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
- ERR_FAIL_COND(!functions.has(p_func));
- Function &func = functions[p_func];
-
+void VisualScript::data_disconnect(int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
DataConnection dc;
dc.from_node = p_from_node;
dc.from_port = p_from_port;
dc.to_node = p_to_node;
dc.to_port = p_to_port;
- ERR_FAIL_COND(!func.data_connections.has(dc));
+ ERR_FAIL_COND(!data_connections.has(dc));
- func.data_connections.erase(dc);
+ data_connections.erase(dc);
}
-bool VisualScript::has_data_connection(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
- ERR_FAIL_COND_V(!functions.has(p_func), false);
- const Function &func = functions[p_func];
-
+bool VisualScript::has_data_connection(int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
DataConnection dc;
dc.from_node = p_from_node;
dc.from_port = p_from_port;
dc.to_node = p_to_node;
dc.to_port = p_to_port;
- return func.data_connections.has(dc);
+ return data_connections.has(dc);
}
-bool VisualScript::is_input_value_port_connected(const StringName &p_func, int p_node, int p_port) const {
- ERR_FAIL_COND_V(!functions.has(p_func), false);
- const Function &func = functions[p_func];
-
- for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) {
+bool VisualScript::is_input_value_port_connected(int p_node, int p_port) const {
+ for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
if (E->get().to_node == p_node && E->get().to_port == p_port) {
return true;
}
}
-
return false;
}
-bool VisualScript::get_input_value_port_connection_source(const StringName &p_func, int p_node, int p_port, int *r_node, int *r_port) const {
- ERR_FAIL_COND_V(!functions.has(p_func), false);
- const Function &func = functions[p_func];
-
- for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) {
+bool VisualScript::get_input_value_port_connection_source(int p_node, int p_port, int *r_node, int *r_port) const {
+ for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
if (E->get().to_node == p_node && E->get().to_port == p_port) {
*r_node = E->get().from_node;
*r_port = E->get().from_port;
return true;
}
}
-
return false;
}
-void VisualScript::get_data_connection_list(const StringName &p_func, List<DataConnection> *r_connection) const {
- ERR_FAIL_COND(!functions.has(p_func));
- const Function &func = functions[p_func];
-
- for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) {
+void VisualScript::get_data_connection_list(List<DataConnection> *r_connection) const {
+ for (const Set<DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
r_connection->push_back(E->get());
}
}
@@ -653,11 +562,8 @@ Dictionary VisualScript::_get_variable_info(const StringName &p_name) const {
}
void VisualScript::get_variable_list(List<StringName> *r_variables) const {
- for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) {
- r_variables->push_back(E->key());
- }
-
- r_variables->sort_custom<StringName::AlphCompare>();
+ variables.get_key_list(r_variables);
+ // r_variables->sort_custom<StringName::AlphCompare>(); // Don't force it.
}
void VisualScript::set_instance_base_type(const StringName &p_type) {
@@ -680,24 +586,19 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p
variables[p_new_name] = variables[p_name];
variables.erase(p_name);
-
- List<StringName> funcs;
- get_function_list(&funcs);
- for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions
- List<int> ids;
- get_node_list(F->get(), &ids);
- for (List<int>::Element *E = ids.front(); E; E = E->next()) {
- Ref<VisualScriptVariableGet> nodeget = get_node(F->get(), E->get());
- if (nodeget.is_valid()) {
- if (nodeget->get_variable() == p_name) {
- nodeget->set_variable(p_new_name);
- }
- } else {
- Ref<VisualScriptVariableSet> nodeset = get_node(F->get(), E->get());
- if (nodeset.is_valid()) {
- if (nodeset->get_variable() == p_name) {
- nodeset->set_variable(p_new_name);
- }
+ List<int> ids;
+ get_node_list(&ids);
+ for (List<int>::Element *E = ids.front(); E; E = E->next()) {
+ Ref<VisualScriptVariableGet> nodeget = get_node(E->get());
+ if (nodeget.is_valid()) {
+ if (nodeget->get_variable() == p_name) {
+ nodeget->set_variable(p_new_name);
+ }
+ } else {
+ Ref<VisualScriptVariableSet> nodeset = get_node(E->get());
+ if (nodeset.is_valid()) {
+ if (nodeset->get_variable() == p_name) {
+ nodeset->set_variable(p_new_name);
}
}
}
@@ -808,23 +709,24 @@ void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) co
}
int VisualScript::get_available_id() const {
- int max_id = 0;
- for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
- if (E->get().nodes.empty()) {
- continue;
+ // This is infinitely increasing,
+ // so one might want to implement a better solution,
+ // if the there is a case for huge number of nodes to be added to visual script.
+ List<int> nds;
+ nodes.get_key_list(&nds);
+ int max = -1;
+ for (const List<int>::Element *E = nds.front(); E; E = E->next()) {
+ if (E->get() > max) {
+ max = E->get();
}
-
- int last_id = E->get().nodes.back()->key();
- max_id = MAX(max_id, last_id + 1);
}
-
- return max_id;
+ return (max + 1);
}
/////////////////////////////////
bool VisualScript::can_instance() const {
- return true; //ScriptServer::is_scripting_enabled();
+ return true; // ScriptServer::is_scripting_enabled();
}
StringName VisualScript::get_instance_base_type() const {
@@ -832,7 +734,7 @@ StringName VisualScript::get_instance_base_type() const {
}
Ref<Script> VisualScript::get_base_script() const {
- return Ref<Script>(); // no inheritance in visual script
+ return Ref<Script>(); // No inheritance in visual script.
}
#ifdef TOOLS_ENABLED
@@ -842,20 +744,23 @@ void VisualScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder)
void VisualScript::_update_placeholders() {
if (placeholders.size() == 0) {
- return; //no bother if no placeholders
+ return; // No bother if no placeholders.
}
List<PropertyInfo> pinfo;
Map<StringName, Variant> values;
- for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) {
- if (!E->get()._export) {
+ List<StringName> keys;
+ variables.get_key_list(&keys);
+
+ for (List<StringName>::Element *E = keys.front(); E; E = E->next()) {
+ if (!variables[E->get()]._export) {
continue;
}
- PropertyInfo p = E->get().info;
- p.name = String(E->key());
+ PropertyInfo p = variables[E->get()].info;
+ p.name = String(E->get());
pinfo.push_back(p);
- values[p.name] = E->get().default_value;
+ values[p.name] = variables[E->get()].default_value;
}
for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
@@ -875,17 +780,18 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
List<PropertyInfo> pinfo;
Map<StringName, Variant> values;
- for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) {
- if (!E->get()._export) {
+ List<StringName> keys;
+ variables.get_key_list(&keys);
+
+ for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) {
+ if (!variables[E->get()]._export)
continue;
- }
- PropertyInfo p = E->get().info;
- p.name = String(E->key());
+ PropertyInfo p = variables[E->get()].info;
+ p.name = String(E->get());
pinfo.push_back(p);
- values[p.name] = E->get().default_value;
+ values[p.name] = variables[E->get()].default_value;
}
-
sins->update(pinfo, values);
return sins;
@@ -928,7 +834,7 @@ bool VisualScript::is_tool() const {
}
bool VisualScript::is_valid() const {
- return true; //always valid
+ return true; // Always valid.
}
ScriptLanguage *VisualScript::get_language() const {
@@ -964,11 +870,14 @@ bool VisualScript::get_property_default_value(const StringName &p_property, Vari
}
void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const {
- for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
+ List<StringName> funcs;
+ functions.get_key_list(&funcs);
+
+ for (List<StringName>::Element *E = funcs.front(); E; E = E->next()) {
MethodInfo mi;
- mi.name = E->key();
- if (E->get().function_id >= 0) {
- Ref<VisualScriptFunction> func = E->get().nodes[E->get().function_id].node;
+ mi.name = E->get();
+ if (functions[E->get()].func_id >= 0) {
+ Ref<VisualScriptFunction> func = nodes[functions[E->get()].func_id].node;
if (func.is_valid()) {
for (int i = 0; i < func->get_argument_count(); i++) {
PropertyInfo arg;
@@ -988,15 +897,15 @@ bool VisualScript::has_method(const StringName &p_method) const {
}
MethodInfo VisualScript::get_method_info(const StringName &p_method) const {
- const Map<StringName, Function>::Element *E = functions.find(p_method);
- if (!E) {
+ const Function funct = functions[p_method];
+ if (funct.func_id == -1) {
return MethodInfo();
}
MethodInfo mi;
- mi.name = E->key();
- if (E->get().function_id >= 0) {
- Ref<VisualScriptFunction> func = E->get().nodes[E->get().function_id].node;
+ mi.name = p_method;
+ if (funct.func_id >= 0) {
+ Ref<VisualScriptFunction> func = nodes[funct.func_id].node;
if (func.is_valid()) {
for (int i = 0; i < func->get_argument_count(); i++) {
PropertyInfo arg;
@@ -1028,28 +937,18 @@ void VisualScript::get_script_property_list(List<PropertyInfo> *p_list) const {
}
int VisualScript::get_member_line(const StringName &p_member) const {
-#ifdef TOOLS_ENABLED
- if (has_function(p_member)) {
- for (Map<int, Function::NodeData>::Element *E = functions[p_member].nodes.front(); E; E = E->next()) {
- if (Object::cast_to<VisualScriptFunction>(E->get().node.ptr())) {
- return E->key();
- }
- }
- }
-#endif
- return -1;
+ return functions[p_member].func_id; // will be -1 if not found
}
#ifdef TOOLS_ENABLED
bool VisualScript::are_subnodes_edited() const {
- for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
- for (const Map<int, Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) {
- if (F->get().node->is_edited()) {
- return true;
- }
+ List<int> keys;
+ nodes.get_key_list(&keys);
+ for (const List<int>::Element *F = keys.front(); F; F = F->next()) {
+ if (nodes[F->get()].node->is_edited()) {
+ return true;
}
}
-
return false;
}
#endif
@@ -1140,85 +1039,41 @@ void VisualScript::_set_data(const Dictionary &p_data) {
Array funcs = d["functions"];
functions.clear();
- Vector2 last_pos = Vector2(-100 * funcs.size(), -100 * funcs.size()); // this is the center of the last fn box
- Vector2 last_size = Vector2(0.0, 0.0);
-
for (int i = 0; i < funcs.size(); i++) {
Dictionary func = funcs[i];
-
- StringName name = func["name"];
- //int id=func["function_id"];
- add_function(name);
-
- set_function_scroll(name, func["scroll"]);
-
- Array nodes = func["nodes"];
-
- if (!d.has("vs_unify") && nodes.size() > 0) {
- Vector2 top_left = nodes[1];
- Vector2 bottom_right = nodes[1];
-
- for (int j = 0; j < nodes.size(); j += 3) {
- Point2 pos = nodes[j + 1];
- if (pos.y > top_left.y) {
- top_left.y = pos.y;
- }
- if (pos.y < bottom_right.y) {
- bottom_right.y = pos.y;
- }
- if (pos.x > bottom_right.x) {
- bottom_right.x = pos.x;
- }
- if (pos.x < top_left.x) {
- top_left.x = pos.x;
- }
- }
-
- Vector2 size = Vector2(bottom_right.x - top_left.x, top_left.y - bottom_right.y);
-
- Vector2 offset = last_pos + (last_size / 2.0) + (size / 2.0); // dunno I might just keep it in one axis but diagonal feels better....
-
- last_pos = offset;
- last_size = size;
-
- for (int j = 0; j < nodes.size(); j += 3) {
- add_node(name, nodes[j], nodes[j + 2], offset + nodes[j + 1]); // also add an additional buffer if you want to
- }
-
- } else {
- for (int j = 0; j < nodes.size(); j += 3) {
- add_node(name, nodes[j], nodes[j + 2], nodes[j + 1]);
- }
+ add_function(func["name"], func["function_id"]);
+ }
+ {
+ Array nodes = d["nodes"];
+ for (int i = 0; i < nodes.size(); i += 3) {
+ add_node(nodes[i], nodes[i + 2], nodes[i + 1]);
}
- Array sequence_connections = func["sequence_connections"];
+ Array sequence_connections = d["sequence_connections"];
for (int j = 0; j < sequence_connections.size(); j += 3) {
- sequence_connect(name, sequence_connections[j + 0], sequence_connections[j + 1], sequence_connections[j + 2]);
+ sequence_connect(sequence_connections[j + 0], sequence_connections[j + 1], sequence_connections[j + 2]);
}
- Array data_connections = func["data_connections"];
-
+ Array data_connections = d["data_connections"];
for (int j = 0; j < data_connections.size(); j += 4) {
- data_connect(name, data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]);
+ data_connect(data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]);
}
}
+ is_tool_script = d["is_tool_script"];
+ scroll = d["scroll"];
- if (d.has("is_tool_script")) {
- is_tool_script = d["is_tool_script"];
- } else {
- is_tool_script = false;
- }
-
- // Takes all the rpc methods
+ // Takes all the rpc methods.
rpc_functions.clear();
rpc_variables.clear();
- for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
- if (E->get().function_id >= 0 && E->get().nodes.find(E->get().function_id)) {
- Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
+ List<StringName> fns;
+ functions.get_key_list(&fns);
+ for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) {
+ if (functions[E->get()].func_id >= 0 && nodes.has(functions[E->get()].func_id)) {
+ Ref<VisualScriptFunction> vsf = nodes[functions[E->get()].func_id].node;
if (vsf.is_valid()) {
if (vsf->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
ScriptNetData nd;
- nd.name = E->key();
+ nd.name = E->get();
nd.mode = vsf->get_rpc_mode();
if (rpc_functions.find(nd) == -1) {
rpc_functions.push_back(nd);
@@ -1228,8 +1083,6 @@ void VisualScript::_set_data(const Dictionary &p_data) {
}
}
- // Visual script doesn't have rset :(
-
// Sort so we are 100% that they are always the same.
rpc_functions.sort_custom<SortNetData>();
}
@@ -1237,12 +1090,15 @@ void VisualScript::_set_data(const Dictionary &p_data) {
Dictionary VisualScript::_get_data() const {
Dictionary d;
d["base_type"] = base_type;
+
Array vars;
- for (const Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) {
- Dictionary var = _get_variable_info(E->key());
- var["name"] = E->key(); //make sure it's the right one
- var["default_value"] = E->get().default_value;
- var["export"] = E->get()._export;
+ List<StringName> var_names;
+ variables.get_key_list(&var_names);
+ for (const List<StringName>::Element *E = var_names.front(); E; E = E->next()) {
+ Dictionary var = _get_variable_info(E->get());
+ var["name"] = E->get(); // Make sure it's the right one.
+ var["default_value"] = variables[E->get()].default_value;
+ var["export"] = variables[E->get()]._export;
vars.push_back(var);
}
d["variables"] = vars;
@@ -1264,78 +1120,73 @@ Dictionary VisualScript::_get_data() const {
d["signals"] = sigs;
Array funcs;
-
- for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
+ List<StringName> func_names;
+ functions.get_key_list(&func_names);
+ for (const List<StringName>::Element *E = func_names.front(); E; E = E->next()) {
Dictionary func;
- func["name"] = E->key();
- func["function_id"] = E->get().function_id;
- func["scroll"] = E->get().scroll;
-
- Array nodes;
-
- for (const Map<int, Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) {
- nodes.push_back(F->key());
- nodes.push_back(F->get().pos);
- nodes.push_back(F->get().node);
- }
-
- func["nodes"] = nodes;
-
- Array sequence_connections;
-
- for (const Set<SequenceConnection>::Element *F = E->get().sequence_connections.front(); F; F = F->next()) {
- sequence_connections.push_back(F->get().from_node);
- sequence_connections.push_back(F->get().from_output);
- sequence_connections.push_back(F->get().to_node);
- }
-
- func["sequence_connections"] = sequence_connections;
-
- Array data_connections;
+ func["name"] = E->get();
+ func["function_id"] = functions[E->get()].func_id;
+ funcs.push_back(func);
+ }
+ d["functions"] = funcs;
- for (const Set<DataConnection>::Element *F = E->get().data_connections.front(); F; F = F->next()) {
- data_connections.push_back(F->get().from_node);
- data_connections.push_back(F->get().from_port);
- data_connections.push_back(F->get().to_node);
- data_connections.push_back(F->get().to_port);
- }
+ Array nds;
+ List<int> node_ids;
+ nodes.get_key_list(&node_ids);
+ for (const List<int>::Element *F = node_ids.front(); F; F = F->next()) {
+ nds.push_back(F->get());
+ nds.push_back(nodes[F->get()].pos);
+ nds.push_back(nodes[F->get()].node);
+ }
+ d["nodes"] = nds;
- func["data_connections"] = data_connections;
+ Array seqconns;
+ for (const Set<SequenceConnection>::Element *F = sequence_connections.front(); F; F = F->next()) {
+ seqconns.push_back(F->get().from_node);
+ seqconns.push_back(F->get().from_output);
+ seqconns.push_back(F->get().to_node);
+ }
+ d["sequence_connections"] = seqconns;
- funcs.push_back(func);
+ Array dataconns;
+ for (const Set<DataConnection>::Element *F = data_connections.front(); F; F = F->next()) {
+ dataconns.push_back(F->get().from_node);
+ dataconns.push_back(F->get().from_port);
+ dataconns.push_back(F->get().to_node);
+ dataconns.push_back(F->get().to_port);
}
+ d["data_connections"] = dataconns;
- d["functions"] = funcs;
d["is_tool_script"] = is_tool_script;
- d["vs_unify"] = true;
+ d["scroll"] = scroll;
return d;
}
void VisualScript::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_function", "name"), &VisualScript::add_function);
+ ClassDB::bind_method(D_METHOD("add_function", "name", "func_node_id"), &VisualScript::add_function);
ClassDB::bind_method(D_METHOD("has_function", "name"), &VisualScript::has_function);
ClassDB::bind_method(D_METHOD("remove_function", "name"), &VisualScript::remove_function);
ClassDB::bind_method(D_METHOD("rename_function", "name", "new_name"), &VisualScript::rename_function);
- ClassDB::bind_method(D_METHOD("set_function_scroll", "name", "ofs"), &VisualScript::set_function_scroll);
- ClassDB::bind_method(D_METHOD("get_function_scroll", "name"), &VisualScript::get_function_scroll);
+ ClassDB::bind_method(D_METHOD("set_scroll", "ofs"), &VisualScript::set_scroll);
+ ClassDB::bind_method(D_METHOD("get_scroll"), &VisualScript::get_scroll);
- ClassDB::bind_method(D_METHOD("add_node", "func", "id", "node", "position"), &VisualScript::add_node, DEFVAL(Point2()));
- ClassDB::bind_method(D_METHOD("remove_node", "func", "id"), &VisualScript::remove_node);
+ ClassDB::bind_method(D_METHOD("add_node", "id", "node", "position"), &VisualScript::add_node, DEFVAL(Point2()));
+ ClassDB::bind_method(D_METHOD("remove_node", "id"), &VisualScript::remove_node);
ClassDB::bind_method(D_METHOD("get_function_node_id", "name"), &VisualScript::get_function_node_id);
- ClassDB::bind_method(D_METHOD("get_node", "func", "id"), &VisualScript::get_node);
- ClassDB::bind_method(D_METHOD("has_node", "func", "id"), &VisualScript::has_node);
- ClassDB::bind_method(D_METHOD("set_node_position", "func", "id", "position"), &VisualScript::set_node_position);
- ClassDB::bind_method(D_METHOD("get_node_position", "func", "id"), &VisualScript::get_node_position);
+ ClassDB::bind_method(D_METHOD("get_node", "id"), &VisualScript::get_node);
+ ClassDB::bind_method(D_METHOD("has_node", "id"), &VisualScript::has_node);
+ ClassDB::bind_method(D_METHOD("set_node_position", "id", "position"), &VisualScript::set_node_position);
+ ClassDB::bind_method(D_METHOD("get_node_position", "id"), &VisualScript::get_node_position);
- ClassDB::bind_method(D_METHOD("sequence_connect", "func", "from_node", "from_output", "to_node"), &VisualScript::sequence_connect);
- ClassDB::bind_method(D_METHOD("sequence_disconnect", "func", "from_node", "from_output", "to_node"), &VisualScript::sequence_disconnect);
- ClassDB::bind_method(D_METHOD("has_sequence_connection", "func", "from_node", "from_output", "to_node"), &VisualScript::has_sequence_connection);
+ ClassDB::bind_method(D_METHOD("sequence_connect", "from_node", "from_output", "to_node"), &VisualScript::sequence_connect);
+ ClassDB::bind_method(D_METHOD("sequence_disconnect", "from_node", "from_output", "to_node"), &VisualScript::sequence_disconnect);
+ ClassDB::bind_method(D_METHOD("has_sequence_connection", "from_node", "from_output", "to_node"), &VisualScript::has_sequence_connection);
- ClassDB::bind_method(D_METHOD("data_connect", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_connect);
- ClassDB::bind_method(D_METHOD("data_disconnect", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_disconnect);
- ClassDB::bind_method(D_METHOD("has_data_connection", "func", "from_node", "from_port", "to_node", "to_port"), &VisualScript::has_data_connection);
+ ClassDB::bind_method(D_METHOD("data_connect", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_connect);
+ ClassDB::bind_method(D_METHOD("data_disconnect", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_disconnect);
+ ClassDB::bind_method(D_METHOD("has_data_connection", "from_node", "from_port", "to_node", "to_port"), &VisualScript::has_data_connection);
ClassDB::bind_method(D_METHOD("add_variable", "name", "default_value", "export"), &VisualScript::add_variable, DEFVAL(Variant()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("has_variable", "name"), &VisualScript::has_variable);
@@ -1371,7 +1222,7 @@ void VisualScript::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
- ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::INT, "id")));
+ ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::INT, "id")));
}
VisualScript::VisualScript() {
@@ -1380,16 +1231,12 @@ VisualScript::VisualScript() {
}
bool VisualScript::inherits_script(const Ref<Script> &p_script) const {
- return this == p_script.ptr(); //there is no inheritance in visual scripts, so this is enough
-}
-
-StringName VisualScript::get_default_func() const {
- return StringName("f_312843592");
+ return this == p_script.ptr(); // There is no inheritance in visual scripts, so this is enough.
}
-Set<int> VisualScript::get_output_sequence_ports_connected(const String &edited_func, int from_node) {
+Set<int> VisualScript::get_output_sequence_ports_connected(int from_node) {
List<VisualScript::SequenceConnection> *sc = memnew(List<VisualScript::SequenceConnection>);
- get_sequence_connection_list(edited_func, sc);
+ get_sequence_connection_list(sc);
Set<int> connected;
for (List<VisualScript::SequenceConnection>::Element *E = sc->front(); E; E = E->next()) {
if (E->get().from_node == from_node) {
@@ -1401,8 +1248,11 @@ Set<int> VisualScript::get_output_sequence_ports_connected(const String &edited_
}
VisualScript::~VisualScript() {
- while (!functions.empty()) {
- remove_function(functions.front()->key());
+ // Remove all nodes and stuff that hold data refs.
+ List<int> nds;
+ nodes.get_key_list(&nds);
+ for (const List<int>::Element *E = nds.front(); E; E = E->next()) {
+ remove_node(E->get());
}
}
@@ -1430,20 +1280,21 @@ bool VisualScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
}
void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
- for (const Map<StringName, VisualScript::Variable>::Element *E = script->variables.front(); E; E = E->next()) {
- if (!E->get()._export) {
+ List<StringName> vars;
+ script->variables.get_key_list(&vars);
+ for (const List<StringName>::Element *E = vars.front(); E; E = E->next()) {
+ if (!script->variables[E->get()]._export) {
continue;
}
- PropertyInfo p = E->get().info;
- p.name = String(E->key());
+ PropertyInfo p = script->variables[E->get()].info;
+ p.name = String(E->get());
p.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
p_properties->push_back(p);
}
}
Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
- const Map<StringName, VisualScript::Variable>::Element *E = script->variables.find(p_name);
- if (!E) {
+ if (!script->variables.has(p_name)) {
if (r_is_valid) {
*r_is_valid = false;
}
@@ -1454,19 +1305,17 @@ Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name,
*r_is_valid = true;
}
- return E->get().info.type;
+ return script->variables[p_name].info.type;
}
void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
- for (const Map<StringName, VisualScript::Function>::Element *E = script->functions.front(); E; E = E->next()) {
- if (E->key() == script->get_default_func()) {
- continue;
- }
-
+ List<StringName> fns;
+ script->functions.get_key_list(&fns);
+ for (const List<StringName>::Element *E = fns.front(); E; E = E->next()) {
MethodInfo mi;
- mi.name = E->key();
- if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) {
- Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
+ mi.name = E->get();
+ if (script->functions[E->get()].func_id >= 0 && script->nodes.has(script->functions[E->get()].func_id)) {
+ Ref<VisualScriptFunction> vsf = script->nodes[script->functions[E->get()].func_id].node;
if (vsf.is_valid()) {
for (int i = 0; i < vsf->get_argument_count(); i++) {
PropertyInfo arg;
@@ -1476,21 +1325,16 @@ void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
mi.arguments.push_back(arg);
}
- if (!vsf->is_sequenced()) { //assumed constant if not sequenced
+ if (!vsf->is_sequenced()) { // Assumed constant if not sequenced.
mi.flags |= METHOD_FLAG_CONST;
}
}
}
-
p_list->push_back(mi);
}
}
bool VisualScriptInstance::has_method(const StringName &p_method) const {
- if (p_method == script->get_default_func()) {
- return false;
- }
-
return script->functions.has(p_method);
}
@@ -1506,7 +1350,7 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int
pass_stack[node->pass_idx] = p_pass;
- if (!node->dependencies.empty()) {
+ if (!node->dependencies.is_empty()) {
int dc = node->dependencies.size();
VisualScriptNodeInstance **deps = node->dependencies.ptrw();
@@ -1522,10 +1366,10 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int
int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
- //is a default value (unassigned input port)
+ // Is a default value (unassigned input port).
input_args[i] = &default_values[index];
} else {
- //regular temporary in stack
+ // Rregular temporary in stack.
input_args[i] = &variant_stack[index];
}
}
@@ -1536,7 +1380,7 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int
Variant *working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr;
node->step(input_args, output_args, VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE, working_mem, r_error, error_str);
- //ignore return
+ // Ignore return.
if (r_error.error != Callable::CallError::CALL_OK) {
*r_error_node = node;
}
@@ -1547,7 +1391,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
ERR_FAIL_COND_V(!F, Variant());
Function *f = &F->get();
- //this call goes separate, so it can e yielded and suspended
+ // This call goes separate, so it can e yielded and suspended.
Variant *variant_stack = (Variant *)p_stack;
bool *sequence_bits = (bool *)(variant_stack + f->max_stack);
const Variant **input_args = (const Variant **)(sequence_bits + f->node_count);
@@ -1573,27 +1417,27 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
#endif
while (true) {
- p_pass++; //increment pass
+ p_pass++; // Increment pass.
current_node_id = node->get_id();
VSDEBUG("==========AT NODE: " + itos(current_node_id) + " base: " + node->get_base_node()->get_class_name());
VSDEBUG("AT STACK POS: " + itos(flow_stack_pos));
- //setup working mem
+ // Setup working mem.
working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr;
VSDEBUG("WORKING MEM: " + itos(node->working_mem_idx));
if (current_node_id == f->node) {
- //if function node, set up function arguments from beginning of stack
+ // If function node, set up function arguments from beginning of stack.
for (int i = 0; i < f->argument_count; i++) {
input_args[i] = &variant_stack[i];
}
} else {
- //run dependencies first
+ // Run dependencies first.
- if (!node->dependencies.empty()) {
+ if (!node->dependencies.is_empty()) {
int dc = node->dependencies.size();
VisualScriptNodeInstance **deps = node->dependencies.ptrw();
@@ -1608,18 +1452,18 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
if (!error) {
- //setup input pointers normally
+ // Setup input pointers normally.
VSDEBUG("INPUT PORTS: " + itos(node->input_port_count));
for (int i = 0; i < node->input_port_count; i++) {
int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
- //is a default value (unassigned input port)
+ // Is a default value (unassigned input port).
input_args[i] = &default_values[index];
VSDEBUG("\tPORT " + itos(i) + " DEFAULT VAL");
} else {
- //regular temporary in stack
+ // Regular temporary in stack.
input_args[i] = &variant_stack[index];
VSDEBUG("PORT " + itos(i) + " AT STACK " + itos(index));
}
@@ -1631,7 +1475,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
break;
}
- //setup output pointers
+ // Setup output pointers.
VSDEBUG("OUTPUT PORTS: " + itos(node->output_port_count));
for (int i = 0; i < node->output_port_count; i++) {
@@ -1639,15 +1483,15 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
VSDEBUG("PORT " + itos(i) + " AT STACK " + itos(node->output_ports[i]));
}
- //do step
+ // Do step.
VisualScriptNodeInstance::StartMode start_mode;
{
if (p_resuming_yield) {
start_mode = VisualScriptNodeInstance::START_MODE_RESUME_YIELD;
- p_resuming_yield = false; // should resume only the first time
+ p_resuming_yield = false; // Should resume only the first time.
} else if (flow_stack && (flow_stack[flow_stack_pos] & VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT)) {
- //if there is a push bit, it means we are continuing a sequence
+ // If there is a push bit, it means we are continuing a sequence.
start_mode = VisualScriptNodeInstance::START_MODE_CONTINUE_SEQUENCE;
} else {
start_mode = VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE;
@@ -1659,13 +1503,13 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
int ret = node->step(input_args, output_args, start_mode, working_mem, r_error, error_str);
if (r_error.error != Callable::CallError::CALL_OK) {
- //use error from step
+ // Use error from step.
error = true;
break;
}
if (ret & VisualScriptNodeInstance::STEP_YIELD_BIT) {
- //yielded!
+ // Yielded!
if (node->get_working_memory_size() == 0) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("A node yielded without working memory, please read the docs on how to yield properly!");
@@ -1681,7 +1525,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
break;
}
- //step 1, capture all state
+ // Step 1, capture all state.
state->instance_id = get_owner_ptr()->get_instance_id();
state->script_id = get_script()->get_instance_id();
state->instance = this;
@@ -1693,11 +1537,11 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
state->stack.resize(p_stack_size);
state->pass = p_pass;
copymem(state->stack.ptrw(), p_stack, p_stack_size);
- //step 2, run away, return directly
+ // Step 2, run away, return directly.
r_error.error = Callable::CallError::CALL_OK;
#ifdef DEBUG_ENABLED
- //will re-enter later, so exiting
+ // Will re-enter later, so exiting.
if (EngineDebugger::is_active()) {
VisualScriptLanguage::singleton->exit_function();
}
@@ -1742,18 +1586,18 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
error_str = RTR("Return value must be assigned to first element of node working memory! Fix your node please.");
error = true;
} else {
- //assign from working memory, first element
+ // Assign from working memory, first element.
return_value = *working_mem;
}
VSDEBUG("EXITING FUNCTION - VALUE " + String(return_value));
- break; //exit function requested, bye
+ break; // Exit function requested, bye
}
- VisualScriptNodeInstance *next = nullptr; //next node
+ VisualScriptNodeInstance *next = nullptr; // Next node.
if ((ret == output || ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) && node->sequence_output_count) {
- //if no exit bit was set, and has sequence outputs, guess next node
+ // If no exit bit was set, and has sequence outputs, guess next node.
if (output >= node->sequence_output_count) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Node returned an invalid sequence output: ") + itos(output);
@@ -1766,21 +1610,21 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
if (flow_stack) {
- //update flow stack pos (may have changed)
+ // Update flow stack pos (may have changed).
flow_stack[flow_stack_pos] = current_node_id;
- //add stack push bit if requested
+ // Add stack push bit if requested.
if (ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) {
flow_stack[flow_stack_pos] |= VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT;
- sequence_bits[node->sequence_index] = true; //remember sequence bit
+ sequence_bits[node->sequence_index] = true; // Remember sequence bit.
VSDEBUG("NEXT SEQ - FLAG BIT");
} else {
- sequence_bits[node->sequence_index] = false; //forget sequence bit
+ sequence_bits[node->sequence_index] = false; // Forget sequence bit.
VSDEBUG("NEXT SEQ - NORMAL");
}
if (ret & VisualScriptNodeInstance::STEP_FLAG_GO_BACK_BIT) {
- //go back request
+ // Go back request.
if (flow_stack_pos > 0) {
flow_stack_pos--;
@@ -1788,20 +1632,20 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
VSDEBUG("NEXT IS GO BACK");
} else {
VSDEBUG("NEXT IS GO BACK, BUT NO NEXT SO EXIT");
- break; //simply exit without value or error
+ break; // Simply exit without value or error.
}
} else if (next) {
if (sequence_bits[next->sequence_index]) {
- // what happened here is that we are entering a node that is in the middle of doing a sequence (pushed stack) from the front
+ // What happened here is that we are entering a node that is in the middle of doing a sequence (pushed stack) from the front
// because each node has a working memory, we can't really do a sub-sequence
// as a result, the sequence will be restarted and the stack will roll back to find where this node
- // started the sequence
+ // started the sequence.
bool found = false;
for (int i = flow_stack_pos; i >= 0; i--) {
if ((flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_MASK) == next->get_id()) {
- flow_stack_pos = i; //roll back and remove bit
+ flow_stack_pos = i; // Roll back and remove bit.
flow_stack[i] = next->get_id();
sequence_bits[next->sequence_index] = false;
found = true;
@@ -1819,7 +1663,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
VSDEBUG("RE-ENTERED A LOOP, RETURNED STACK POS TO - " + itos(flow_stack_pos));
} else {
- // check for stack overflow
+ // Check for stack overflow.
if (flow_stack_pos + 1 >= flow_max) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Stack overflow with stack depth: ") + itos(output);
@@ -1836,7 +1680,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
} else {
- //no next node, try to go back in stack to pushed bit
+ // No next node, try to go back in stack to pushed bit.
bool found = false;
@@ -1852,22 +1696,22 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
if (!found) {
VSDEBUG("NO NEXT NODE, NO GO BACK, EXITING");
- break; //done, couldn't find a push stack bit
+ break; // Done, couldn't find a push stack bit.
}
VSDEBUG("NO NEXT NODE, GO BACK TO: " + itos(flow_stack_pos));
}
} else {
- node = next; //stackless mode, simply assign next node
+ node = next; // Stackless mode, simply assign next node.
}
}
if (error) {
- //error
- // function, file, line, error, explanation
+ // Error
+ // Function, file, line, error, explanation.
String err_file = script->get_path();
String err_func = p_method;
- int err_line = current_node_id; //not a line but it works as one
+ int err_line = current_node_id; // Not a line but it works as one.
if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str == String())) {
if (error_str != String()) {
@@ -1906,7 +1750,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
#endif
- //clean up variant stack
+ // Clean up variant stack.
for (int i = 0; i < f->max_stack; i++) {
variant_stack[i].~Variant();
}
@@ -1954,7 +1798,7 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)nullptr;
for (int i = 0; i < f->node_count; i++) {
- sequence_bits[i] = false; //all starts as false
+ sequence_bits[i] = false; // All starts as false.
}
zeromem(pass_stack, f->pass_stack_size * sizeof(int));
@@ -1988,12 +1832,12 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
return Variant();
}
- //allocate variant stack
+ // Allocate variant stack.
for (int i = 0; i < f->max_stack; i++) {
memnew_placement(&variant_stack[i], Variant);
}
- //allocate function arguments (must be copied for yield to work properly)
+ // Allocate function arguments (must be copied for yield to work properly).
for (int i = 0; i < p_argcount; i++) {
variant_stack[i] = *p_args[i];
}
@@ -2002,12 +1846,12 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
}
void VisualScriptInstance::notification(int p_notification) {
- //do nothing as this is called using virtual
+ // Do nothing as this is called using virtual.
Variant what = p_notification;
const Variant *whatp = &what;
Callable::CallError ce;
- call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); //do as call
+ call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); // Do as call.
}
String VisualScriptInstance::to_string(bool *r_valid) {
@@ -2086,7 +1930,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
max_output_args = 0;
if (Object::cast_to<Node>(p_owner)) {
- //turn on these if they exist and base is a node
+ // Turn on these if they exist and base is a node.
Node *node = Object::cast_to<Node>(p_owner);
if (p_script->functions.has("_process")) {
node->set_process(true);
@@ -2105,190 +1949,236 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
}
}
- for (const Map<StringName, VisualScript::Variable>::Element *E = script->variables.front(); E; E = E->next()) {
- variables[E->key()] = E->get().default_value;
- }
-
- for (const Map<StringName, VisualScript::Function>::Element *E = script->functions.front(); E; E = E->next()) {
- if (E->key() == script->get_default_func()) {
- continue;
- }
-
- Function function;
- function.node = E->get().function_id;
- function.max_stack = 0;
- function.flow_stack_size = 0;
- function.pass_stack_size = 0;
- function.node_count = 0;
-
- Map<StringName, int> local_var_indices;
-
- if (function.node < 0) {
- VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E->key()));
-
- ERR_CONTINUE(function.node < 0);
+ // Setup variables.
+ {
+ List<StringName> keys;
+ script->variables.get_key_list(&keys);
+ for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) {
+ variables[E->get()] = script->variables[E->get()].default_value;
}
+ }
- {
- Ref<VisualScriptFunction> func_node = script->get_node(E->key(), E->get().function_id);
-
- if (func_node.is_null()) {
- VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E->key()));
+ // Setup functions from sequence trees.
+ {
+ List<StringName> keys;
+ script->functions.get_key_list(&keys);
+ for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) {
+ const VisualScript::Function vsfn = p_script->functions[E->get()];
+ Function function;
+ function.node = vsfn.func_id;
+ function.max_stack = 0;
+ function.flow_stack_size = 0;
+ function.pass_stack_size = 0;
+ function.node_count = 0;
+
+ Map<StringName, int> local_var_indices;
+
+ if (function.node < 0) {
+ VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E->get()));
+ ERR_CONTINUE(function.node < 0);
}
- ERR_CONTINUE(!func_node.is_valid());
-
- function.argument_count = func_node->get_argument_count();
- function.max_stack += function.argument_count;
- function.flow_stack_size = func_node->is_stack_less() ? 0 : func_node->get_stack_size();
- max_input_args = MAX(max_input_args, function.argument_count);
- }
-
- //multiple passes are required to set up this complex thing..
-
- //first create the nodes
- for (const Map<int, VisualScript::Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) {
- Ref<VisualScriptNode> node = F->get().node;
-
- VisualScriptNodeInstance *instance = node->instance(this); //create instance
- ERR_FAIL_COND(!instance);
+ {
+ Ref<VisualScriptFunction> func_node = script->get_node(vsfn.func_id);
- instance->base = node.ptr();
+ if (func_node.is_null()) {
+ VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E->get()));
+ }
- instance->id = F->key();
- instance->input_port_count = node->get_input_value_port_count();
- instance->input_ports = nullptr;
- instance->output_port_count = node->get_output_value_port_count();
- instance->output_ports = nullptr;
- instance->sequence_output_count = node->get_output_sequence_port_count();
- instance->sequence_index = function.node_count++;
- instance->sequence_outputs = nullptr;
- instance->pass_idx = -1;
+ ERR_CONTINUE(!func_node.is_valid());
- if (instance->input_port_count) {
- instance->input_ports = memnew_arr(int, instance->input_port_count);
- for (int i = 0; i < instance->input_port_count; i++) {
- instance->input_ports[i] = -1; //if not assigned, will become default value
- }
+ function.argument_count = func_node->get_argument_count();
+ function.max_stack += function.argument_count;
+ function.flow_stack_size = func_node->is_stack_less() ? 0 : func_node->get_stack_size();
+ max_input_args = MAX(max_input_args, function.argument_count);
}
-
- if (instance->output_port_count) {
- instance->output_ports = memnew_arr(int, instance->output_port_count);
- for (int i = 0; i < instance->output_port_count; i++) {
- instance->output_ports[i] = -1; //if not assigned, will output to trash
+ // Function nodes graphs.
+ Set<VisualScript::SequenceConnection> seqconns;
+ Set<VisualScript::DataConnection> dataconns;
+ Set<int> node_ids;
+ node_ids.insert(function.node);
+ {
+ List<int> nd_queue;
+ nd_queue.push_back(function.node);
+ while (!nd_queue.is_empty()) {
+ for (const Set<VisualScript::SequenceConnection>::Element *F = script->sequence_connections.front(); F; F = F->next()) {
+ if (nd_queue.front()->get() == F->get().from_node && !node_ids.has(F->get().to_node)) {
+ nd_queue.push_back(F->get().to_node);
+ node_ids.insert(F->get().to_node);
+ }
+ if (nd_queue.front()->get() == F->get().from_node && !seqconns.has(F->get())) {
+ seqconns.insert(F->get());
+ }
+ }
+ nd_queue.pop_front();
}
- }
-
- if (instance->sequence_output_count) {
- instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count);
- for (int i = 0; i < instance->sequence_output_count; i++) {
- instance->sequence_outputs[i] = nullptr; //if it remains null, flow ends here
+ HashMap<int, HashMap<int, Pair<int, int>>> dc_lut; // :: to -> to_port -> (from, from_port)
+ for (const Set<VisualScript::DataConnection>::Element *F = script->data_connections.front(); F; F = F->next()) {
+ dc_lut[F->get().to_node][F->get().to_port] = Pair<int, int>(F->get().from_node, F->get().from_port);
+ }
+ for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) {
+ nd_queue.push_back(F->get());
+ }
+ List<int> dc_keys;
+ while (!nd_queue.is_empty()) {
+ int ky = nd_queue.front()->get();
+ dc_lut[ky].get_key_list(&dc_keys);
+ for (const List<int>::Element *F = dc_keys.front(); F; F = F->next()) {
+ VisualScript::DataConnection dc;
+ dc.from_node = dc_lut[ky][F->get()].first;
+ dc.from_port = dc_lut[ky][F->get()].second;
+ dc.to_node = ky;
+ dc.to_port = F->get();
+ dataconns.insert(dc);
+ nd_queue.push_back(dc.from_node);
+ node_ids.insert(dc.from_node);
+ }
+ dc_keys.clear(); // Necessary as get_key_list does a push_back not a set.
+ nd_queue.pop_front();
}
}
- if (Object::cast_to<VisualScriptLocalVar>(node.ptr()) || Object::cast_to<VisualScriptLocalVarSet>(*node)) {
- //working memory is shared only for this node, for the same variables
- Ref<VisualScriptLocalVar> vslv = node;
-
- StringName var_name;
+ //Multiple passes are required to set up this complex thing..
+ //First create the nodes.
+ for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) {
+ Ref<VisualScriptNode> node = script->nodes[F->get()].node;
+
+ VisualScriptNodeInstance *instance = node->instance(this); // Create instance.
+ ERR_FAIL_COND(!instance);
+
+ instance->base = node.ptr();
+
+ instance->id = F->get();
+ instance->input_port_count = node->get_input_value_port_count();
+ instance->input_ports = NULL;
+ instance->output_port_count = node->get_output_value_port_count();
+ instance->output_ports = NULL;
+ instance->sequence_output_count = node->get_output_sequence_port_count();
+ instance->sequence_index = function.node_count++;
+ instance->sequence_outputs = NULL;
+ instance->pass_idx = -1;
+
+ if (instance->input_port_count) {
+ instance->input_ports = memnew_arr(int, instance->input_port_count);
+ for (int i = 0; i < instance->input_port_count; i++) {
+ instance->input_ports[i] = -1; // If not assigned, will become default value.
+ }
+ }
- if (Object::cast_to<VisualScriptLocalVar>(*node)) {
- var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges();
- } else {
- var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges();
+ if (instance->output_port_count) {
+ instance->output_ports = memnew_arr(int, instance->output_port_count);
+ for (int i = 0; i < instance->output_port_count; i++) {
+ instance->output_ports[i] = -1; // If not assigned, will output to trash.
+ }
}
- if (!local_var_indices.has(var_name)) {
- local_var_indices[var_name] = function.max_stack;
- function.max_stack++;
+ if (instance->sequence_output_count) {
+ instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count);
+ for (int i = 0; i < instance->sequence_output_count; i++) {
+ instance->sequence_outputs[i] = NULL; // If it remains null, flow ends here.
+ }
}
- instance->working_mem_idx = local_var_indices[var_name];
+ if (Object::cast_to<VisualScriptLocalVar>(node.ptr()) || Object::cast_to<VisualScriptLocalVarSet>(*node)) {
+ // Working memory is shared only for this node, for the same variables.
+ Ref<VisualScriptLocalVar> vslv = node;
- } else if (instance->get_working_memory_size()) {
- instance->working_mem_idx = function.max_stack;
- function.max_stack += instance->get_working_memory_size();
- } else {
- instance->working_mem_idx = -1; //no working mem
- }
+ StringName var_name;
- max_input_args = MAX(max_input_args, instance->input_port_count);
- max_output_args = MAX(max_output_args, instance->output_port_count);
+ if (Object::cast_to<VisualScriptLocalVar>(*node))
+ var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges();
+ else
+ var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges();
- instances[F->key()] = instance;
- }
+ if (!local_var_indices.has(var_name)) {
+ local_var_indices[var_name] = function.max_stack;
+ function.max_stack++;
+ }
- function.trash_pos = function.max_stack++; //create pos for trash
+ instance->working_mem_idx = local_var_indices[var_name];
- //second pass, do data connections
+ } else if (instance->get_working_memory_size()) {
+ instance->working_mem_idx = function.max_stack;
+ function.max_stack += instance->get_working_memory_size();
+ } else {
+ instance->working_mem_idx = -1; //no working mem
+ }
- for (const Set<VisualScript::DataConnection>::Element *F = E->get().data_connections.front(); F; F = F->next()) {
- VisualScript::DataConnection dc = F->get();
- ERR_CONTINUE(!instances.has(dc.from_node));
- VisualScriptNodeInstance *from = instances[dc.from_node];
- ERR_CONTINUE(!instances.has(dc.to_node));
- VisualScriptNodeInstance *to = instances[dc.to_node];
- ERR_CONTINUE(dc.from_port >= from->output_port_count);
- ERR_CONTINUE(dc.to_port >= to->input_port_count);
+ max_input_args = MAX(max_input_args, instance->input_port_count);
+ max_output_args = MAX(max_output_args, instance->output_port_count);
- if (from->output_ports[dc.from_port] == -1) {
- int stack_pos = function.max_stack++;
- from->output_ports[dc.from_port] = stack_pos;
+ instances[F->get()] = instance;
}
- if (from->get_sequence_output_count() == 0 && to->dependencies.find(from) == -1) {
- //if the node we are reading from has no output sequence, we must call step() before reading from it.
- if (from->pass_idx == -1) {
- from->pass_idx = function.pass_stack_size;
- function.pass_stack_size++;
+ function.trash_pos = function.max_stack++; // create pos for trash
+
+ // Second pass, do data connections.
+ for (const Set<VisualScript::DataConnection>::Element *F = dataconns.front(); F; F = F->next()) {
+ VisualScript::DataConnection dc = F->get();
+ ERR_CONTINUE(!instances.has(dc.from_node));
+ VisualScriptNodeInstance *from = instances[dc.from_node];
+ ERR_CONTINUE(!instances.has(dc.to_node));
+ VisualScriptNodeInstance *to = instances[dc.to_node];
+ ERR_CONTINUE(dc.from_port >= from->output_port_count);
+ ERR_CONTINUE(dc.to_port >= to->input_port_count);
+
+ if (from->output_ports[dc.from_port] == -1) {
+ int stack_pos = function.max_stack++;
+ from->output_ports[dc.from_port] = stack_pos;
}
- to->dependencies.push_back(from);
- }
- to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; //read from wherever the stack is
- }
-
- //third pass, do sequence connections
+ if (from->get_sequence_output_count() == 0 && to->dependencies.find(from) == -1) {
+ // If the node we are reading from has no output sequence, we must call step() before reading from it.
+ if (from->pass_idx == -1) {
+ from->pass_idx = function.pass_stack_size;
+ function.pass_stack_size++;
+ }
+ to->dependencies.push_back(from);
+ }
- for (const Set<VisualScript::SequenceConnection>::Element *F = E->get().sequence_connections.front(); F; F = F->next()) {
- VisualScript::SequenceConnection sc = F->get();
- ERR_CONTINUE(!instances.has(sc.from_node));
- VisualScriptNodeInstance *from = instances[sc.from_node];
- ERR_CONTINUE(!instances.has(sc.to_node));
- VisualScriptNodeInstance *to = instances[sc.to_node];
- ERR_CONTINUE(sc.from_output >= from->sequence_output_count);
+ to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; // Read from wherever the stack is.
+ }
- from->sequence_outputs[sc.from_output] = to;
- }
+ // Third pass, do sequence connections.
+ for (const Set<VisualScript::SequenceConnection>::Element *F = seqconns.front(); F; F = F->next()) {
+ VisualScript::SequenceConnection sc = F->get();
+ ERR_CONTINUE(!instances.has(sc.from_node));
+ VisualScriptNodeInstance *from = instances[sc.from_node];
+ ERR_CONTINUE(!instances.has(sc.to_node));
+ VisualScriptNodeInstance *to = instances[sc.to_node];
+ ERR_CONTINUE(sc.from_output >= from->sequence_output_count);
- //fourth pass:
- // 1) unassigned input ports to default values
- // 2) connect unassigned output ports to trash
+ from->sequence_outputs[sc.from_output] = to;
+ }
- for (const Map<int, VisualScript::Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) {
- ERR_CONTINUE(!instances.has(F->key()));
+ //fourth pass:
+ // 1) unassigned input ports to default values
+ // 2) connect unassigned output ports to trash
+ for (const Set<int>::Element *F = node_ids.front(); F; F = F->next()) {
+ ERR_CONTINUE(!instances.has(F->get()));
- Ref<VisualScriptNode> node = F->get().node;
- VisualScriptNodeInstance *instance = instances[F->key()];
+ Ref<VisualScriptNode> node = script->nodes[F->get()].node;
+ VisualScriptNodeInstance *instance = instances[F->get()];
- // connect to default values
- for (int i = 0; i < instance->input_port_count; i++) {
- if (instance->input_ports[i] == -1) {
- //unassigned, connect to default val
- instance->input_ports[i] = default_values.size() | VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT;
- default_values.push_back(node->get_default_input_value(i));
+ // Connect to default values.
+ for (int i = 0; i < instance->input_port_count; i++) {
+ if (instance->input_ports[i] == -1) {
+ // Unassigned, connect to default val.
+ instance->input_ports[i] = default_values.size() | VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT;
+ default_values.push_back(node->get_default_input_value(i));
+ }
}
- }
- // connect to trash
- for (int i = 0; i < instance->output_port_count; i++) {
- if (instance->output_ports[i] == -1) {
- instance->output_ports[i] = function.trash_pos; //trash is same for all
+ // Connect to trash.
+ for (int i = 0; i < instance->output_port_count; i++) {
+ if (instance->output_ports[i] == -1) {
+ instance->output_ports[i] = function.trash_pos; //trash is same for all
+ }
}
}
- }
- functions[E->key()] = function;
+ functions[E->get()] = function;
+ }
}
}
@@ -2354,7 +2244,7 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int
Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index;
- *working_mem = args; //arguments go to working mem.
+ *working_mem = args; // Arguments go to working mem.
Variant ret = instance->_call_internal(function, stack.ptrw(), stack.size(), node, flow_stack_pos, pass, true, r_error);
function = StringName(); //invalidate
@@ -2388,7 +2278,7 @@ Variant VisualScriptFunctionState::resume(Array p_args) {
Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index;
- *working_mem = p_args; //arguments go to working mem.
+ *working_mem = p_args; // Arguments go to working mem.
Variant ret = instance->_call_internal(function, stack.ptrw(), stack.size(), node, flow_stack_pos, pass, true, r_error);
function = StringName(); //invalidate
@@ -2498,7 +2388,7 @@ void VisualScriptLanguage::add_global_constant(const StringName &p_variable, con
/* DEBUGGER FUNCTIONS */
bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, const String &p_error) {
- //break because of parse error
+ // Break because of parse error.
if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_node = p_node;
@@ -2666,7 +2556,7 @@ void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<Strin
}
void VisualScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
- //no globals are really reachable in gdscript
+ // No globals are really reachable in gdscript.
}
String VisualScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
@@ -2730,19 +2620,13 @@ void VisualScriptLanguage::get_registered_node_names(List<String> *r_names) {
}
VisualScriptLanguage::VisualScriptLanguage() {
- notification = "_notification";
- _step = "_step";
- _subcall = "_subcall";
singleton = this;
- _debug_parse_err_node = -1;
- _debug_parse_err_file = "";
- _debug_call_stack_pos = 0;
int dmcs = GLOBAL_DEF("debug/settings/visual_script/max_call_stack", 1024);
ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/visual_script/max_call_stack", PropertyInfo(Variant::INT, "debug/settings/visual_script/max_call_stack", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater")); //minimum is 1024
if (EngineDebugger::is_active()) {
- //debugging enabled!
+ // Debugging enabled!
_debug_max_call_stack = dmcs;
_call_stack = memnew_arr(CallLevel, _debug_max_call_stack + 1);
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 59bdfb2fc3..72362e0ef4 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,10 +46,10 @@ class VisualScriptNode : public Resource {
friend class VisualScript;
- Set<VisualScript *> scripts_used;
+ Ref<VisualScript> script_used;
Array default_input_values;
- bool breakpoint;
+ bool breakpoint = false;
void _set_default_input_values(Array p_values);
Array _get_default_input_values() const;
@@ -83,20 +83,16 @@ public:
virtual String get_text() const;
virtual String get_category() const = 0;
- //used by editor, this is not really saved
+ // Used by editor, this is not really saved.
void set_breakpoint(bool p_breakpoint);
bool is_breakpoint() const;
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance) = 0;
struct TypeGuess {
- Variant::Type type;
+ Variant::Type type = Variant::NIL;
StringName gdclass;
Ref<Script> script;
-
- TypeGuess() {
- type = Variant::NIL;
- }
};
virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const;
@@ -106,27 +102,27 @@ public:
class VisualScriptNodeInstance {
friend class VisualScriptInstance;
- friend class VisualScriptLanguage; //for debugger
+ friend class VisualScriptLanguage; // For debugger.
- enum { //input argument addressing
+ enum { // Input argument addressing.
INPUT_SHIFT = 1 << 24,
INPUT_MASK = INPUT_SHIFT - 1,
INPUT_DEFAULT_VALUE_BIT = INPUT_SHIFT, // from unassigned input port, using default value (edited by user)
};
- int id;
- int sequence_index;
- VisualScriptNodeInstance **sequence_outputs;
- int sequence_output_count;
+ int id = 0;
+ int sequence_index = 0;
+ VisualScriptNodeInstance **sequence_outputs = nullptr;
+ int sequence_output_count = 0;
Vector<VisualScriptNodeInstance *> dependencies;
- int *input_ports;
- int input_port_count;
- int *output_ports;
- int output_port_count;
- int working_mem_idx;
- int pass_idx;
+ int *input_ports = nullptr;
+ int input_port_count = 0;
+ int *output_ports = nullptr;
+ int output_port_count = 0;
+ int working_mem_idx = 0;
+ int pass_idx = 0;
- VisualScriptNode *base;
+ VisualScriptNode *base = nullptr;
public:
enum StartMode {
@@ -138,13 +134,13 @@ public:
enum {
STEP_SHIFT = 1 << 24,
STEP_MASK = STEP_SHIFT - 1,
- STEP_FLAG_PUSH_STACK_BIT = STEP_SHIFT, //push bit to stack
- STEP_FLAG_GO_BACK_BIT = STEP_SHIFT << 1, //go back to previous node
- STEP_NO_ADVANCE_BIT = STEP_SHIFT << 2, //do not advance past this node
- STEP_EXIT_FUNCTION_BIT = STEP_SHIFT << 3, //return from function
- STEP_YIELD_BIT = STEP_SHIFT << 4, //yield (will find VisualScriptFunctionState state in first working memory)
+ STEP_FLAG_PUSH_STACK_BIT = STEP_SHIFT, // push bit to stack
+ STEP_FLAG_GO_BACK_BIT = STEP_SHIFT << 1, // go back to previous node
+ STEP_NO_ADVANCE_BIT = STEP_SHIFT << 2, // do not advance past this node
+ STEP_EXIT_FUNCTION_BIT = STEP_SHIFT << 3, // return from function
+ STEP_YIELD_BIT = STEP_SHIFT << 4, // yield (will find VisualScriptFunctionState state in first working memory)
- FLOW_STACK_PUSHED_BIT = 1 << 30, //in flow stack, means bit was pushed (must go back here if end of sequence)
+ FLOW_STACK_PUSHED_BIT = 1 << 30, // in flow stack, means bit was pushed (must go back here if end of sequence)
FLOW_STACK_MASK = FLOW_STACK_PUSHED_BIT - 1
};
@@ -157,7 +153,7 @@ public:
virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) = 0; //do a step, return which sequence port to go out
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) = 0; // Do a step, return which sequence port to go out.
Ref<VisualScriptNode> get_base_node() { return Ref<VisualScriptNode>(base); }
@@ -178,7 +174,7 @@ public:
uint64_t from_output : 16;
uint64_t to_node : 24;
};
- uint64_t id;
+ uint64_t id = 0;
};
bool operator<(const SequenceConnection &p_connection) const {
@@ -194,7 +190,7 @@ public:
uint64_t to_node : 24;
uint64_t to_port : 8;
};
- uint64_t id;
+ uint64_t id = 0;
};
bool operator<(const DataConnection &p_connection) const {
@@ -208,37 +204,35 @@ private:
StringName base_type;
struct Argument {
String name;
- Variant::Type type;
+ Variant::Type type = Variant::Type::NIL;
};
- struct Function {
- struct NodeData {
- Point2 pos;
- Ref<VisualScriptNode> node;
- };
-
- Map<int, NodeData> nodes;
-
- Set<SequenceConnection> sequence_connections;
+ struct NodeData {
+ Point2 pos;
+ Ref<VisualScriptNode> node;
+ };
- Set<DataConnection> data_connections;
+ HashMap<int, NodeData> nodes; // Can be a sparse map.
- int function_id;
+ Set<SequenceConnection> sequence_connections;
+ Set<DataConnection> data_connections;
- Vector2 scroll;
+ Vector2 scroll;
- Function() { function_id = -1; }
+ struct Function {
+ int func_id;
+ Function() { func_id = -1; }
};
struct Variable {
PropertyInfo info;
Variant default_value;
- bool _export;
- // add getter & setter options here
+ bool _export = false;
+ // Add getter & setter options here.
};
- Map<StringName, Function> functions;
- Map<StringName, Variable> variables;
+ HashMap<StringName, Function> functions;
+ HashMap<StringName, Variable> variables;
Map<StringName, Vector<Argument>> custom_signals;
Vector<ScriptNetData> rpc_functions;
Vector<ScriptNetData> rpc_variables;
@@ -249,7 +243,7 @@ private:
#ifdef TOOLS_ENABLED
Set<PlaceHolderScriptInstance *> placeholders;
- //void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
+ // void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override;
void _update_placeholders();
#endif
@@ -267,37 +261,38 @@ protected:
public:
bool inherits_script(const Ref<Script> &p_script) const override;
- // TODO: Remove it in future when breaking changes are acceptable
- StringName get_default_func() const;
- void add_function(const StringName &p_name);
+ void set_scroll(const Vector2 &p_scroll);
+ Vector2 get_scroll() const;
+
+ void add_function(const StringName &p_name, int p_func_node_id);
bool has_function(const StringName &p_name) const;
void remove_function(const StringName &p_name);
void rename_function(const StringName &p_name, const StringName &p_new_name);
- void set_function_scroll(const StringName &p_name, const Vector2 &p_scroll);
- Vector2 get_function_scroll(const StringName &p_name) const;
void get_function_list(List<StringName> *r_functions) const;
int get_function_node_id(const StringName &p_name) const;
void set_tool_enabled(bool p_enabled);
- void add_node(const StringName &p_func, int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos = Point2());
- void remove_node(const StringName &p_func, int p_id);
- bool has_node(const StringName &p_func, int p_id) const;
- Ref<VisualScriptNode> get_node(const StringName &p_func, int p_id) const;
- void set_node_position(const StringName &p_func, int p_id, const Point2 &p_pos);
- Point2 get_node_position(const StringName &p_func, int p_id) const;
- void get_node_list(const StringName &p_func, List<int> *r_nodes) const;
-
- void sequence_connect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node);
- void sequence_disconnect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node);
- bool has_sequence_connection(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) const;
- void get_sequence_connection_list(const StringName &p_func, List<SequenceConnection> *r_connection) const;
-
- void data_connect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
- void data_disconnect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
- bool has_data_connection(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
- void get_data_connection_list(const StringName &p_func, List<DataConnection> *r_connection) const;
- bool is_input_value_port_connected(const StringName &p_func, int p_node, int p_port) const;
- bool get_input_value_port_connection_source(const StringName &p_func, int p_node, int p_port, int *r_node, int *r_port) const;
+ void add_node(int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos = Point2());
+ void remove_node(int p_id);
+ bool has_node(int p_id) const;
+ Ref<VisualScriptNode> get_node(int p_id) const;
+ void set_node_position(int p_id, const Point2 &p_pos);
+ Point2 get_node_position(int p_id) const;
+ void get_node_list(List<int> *r_nodes) const;
+
+ void sequence_connect(int p_from_node, int p_from_output, int p_to_node);
+ void sequence_disconnect(int p_from_node, int p_from_output, int p_to_node);
+ bool has_sequence_connection(int p_from_node, int p_from_output, int p_to_node) const;
+ void get_sequence_connection_list(List<SequenceConnection> *r_connection) const;
+ Set<int> get_output_sequence_ports_connected(int from_node);
+
+ void data_connect(int p_from_node, int p_from_port, int p_to_node, int p_to_port);
+ void data_disconnect(int p_from_node, int p_from_port, int p_to_node, int p_to_port);
+ bool has_data_connection(int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
+ void get_data_connection_list(List<DataConnection> *r_connection) const;
+
+ bool is_input_value_port_connected(int p_node, int p_port) const;
+ bool get_input_value_port_connection_source(int p_node, int p_port, int *r_node, int *r_port) const;
void add_variable(const StringName &p_name, const Variant &p_default_value = Variant(), bool p_export = false);
bool has_variable(const StringName &p_name) const;
@@ -389,35 +384,35 @@ public:
};
class VisualScriptInstance : public ScriptInstance {
- Object *owner;
+ Object *owner = nullptr;
Ref<VisualScript> script;
- Map<StringName, Variant> variables; //using variable path, not script
+ Map<StringName, Variant> variables; // Using variable path, not script.
Map<int, VisualScriptNodeInstance *> instances;
struct Function {
- int node;
- int max_stack;
- int trash_pos;
- int flow_stack_size;
- int pass_stack_size;
- int node_count;
- int argument_count;
+ int node = 0;
+ int max_stack = 0;
+ int trash_pos = 0;
+ int flow_stack_size = 0;
+ int pass_stack_size = 0;
+ int node_count = 0;
+ int argument_count = 0;
};
Map<StringName, Function> functions;
Vector<Variant> default_values;
- int max_input_args, max_output_args;
+ int max_input_args = 0;
+ int max_output_args = 0;
StringName source;
void _dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Callable::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node);
Variant _call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Callable::CallError &r_error);
- //Map<StringName,Function> functions;
- friend class VisualScriptFunctionState; //for yield
- friend class VisualScriptLanguage; //for debugger
+ friend class VisualScriptFunctionState; // For yield.
+ friend class VisualScriptLanguage; // For debugger.
public:
virtual bool set(const StringName &p_name, const Variant &p_value);
virtual bool get(const StringName &p_name, Variant &r_ret) const;
@@ -481,14 +476,14 @@ class VisualScriptFunctionState : public Reference {
ObjectID instance_id;
ObjectID script_id;
- VisualScriptInstance *instance;
+ VisualScriptInstance *instance = nullptr;
StringName function;
Vector<uint8_t> stack;
- int working_mem_index;
- int variant_stack_size;
- VisualScriptNodeInstance *node;
- int flow_stack_pos;
- int pass;
+ int working_mem_index = 0;
+ int variant_stack_size = 0;
+ VisualScriptNodeInstance *node = nullptr;
+ int flow_stack_pos = 0;
+ int pass = 0;
Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
@@ -509,25 +504,25 @@ class VisualScriptLanguage : public ScriptLanguage {
Map<String, VisualScriptNodeRegisterFunc> register_funcs;
struct CallLevel {
- Variant *stack;
- Variant **work_mem;
- const StringName *function;
- VisualScriptInstance *instance;
- int *current_id;
+ Variant *stack = nullptr;
+ Variant **work_mem = nullptr;
+ const StringName *function = nullptr;
+ VisualScriptInstance *instance = nullptr;
+ int *current_id = nullptr;
};
- int _debug_parse_err_node;
- String _debug_parse_err_file;
+ int _debug_parse_err_node = -1;
+ String _debug_parse_err_file = "";
String _debug_error;
- int _debug_call_stack_pos;
+ int _debug_call_stack_pos = 0;
int _debug_max_call_stack;
CallLevel *_call_stack;
public:
- StringName notification;
+ StringName notification = "_notification";
StringName _get_output_port_unsequenced;
- StringName _step;
- StringName _subcall;
+ StringName _step = "_step";
+ StringName _subcall = "_subcall";
static VisualScriptLanguage *singleton;
@@ -538,7 +533,7 @@ public:
_FORCE_INLINE_ void enter_function(VisualScriptInstance *p_instance, const StringName *p_function, Variant *p_stack, Variant **p_work_mem, int *current_id) {
if (Thread::get_main_id() != Thread::get_caller_id()) {
- return; //no support for other threads than main for now
+ return; // No support for other threads than main for now.
}
if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) {
@@ -546,7 +541,7 @@ public:
}
if (_debug_call_stack_pos >= _debug_max_call_stack) {
- //stack overflow
+ // Stack overflow.
_debug_error = "Stack Overflow (Stack Size: " + itos(_debug_max_call_stack) + ")";
EngineDebugger::get_script_debugger()->debug(this);
return;
@@ -562,7 +557,7 @@ public:
_FORCE_INLINE_ void exit_function() {
if (Thread::get_main_id() != Thread::get_caller_id()) {
- return; //no support for other threads than main for now
+ return; // No support for other threads than main for now.
}
if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) {
@@ -640,7 +635,7 @@ public:
~VisualScriptLanguage();
};
-//aid for registering
+// Aid for registering.
template <class T>
static Ref<VisualScriptNode> create_node_generic(const String &p_name) {
Ref<T> node;
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index fe0c399f8d..7ca14fbca8 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,7 +63,7 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"is_inf",
"ease",
"step_decimals",
- "stepify",
+ "snapped",
"lerp",
"inverse_lerp",
"range_lerp",
@@ -101,7 +101,6 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"str2var",
"var2bytes",
"bytes2var",
- "color_named",
"smoothstep",
"posmod",
"lerp_angle",
@@ -192,7 +191,7 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case MATH_POSMOD:
case MATH_POW:
case MATH_EASE:
- case MATH_STEPIFY:
+ case MATH_SNAPPED:
case MATH_RANDF_RANGE:
case MATH_RANDI_RANGE:
case MATH_POLAR2CARTESIAN:
@@ -200,7 +199,6 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case LOGIC_MAX:
case LOGIC_MIN:
case TYPE_CONVERT:
- case COLORN:
return 2;
case MATH_LERP:
case MATH_LERP_ANGLE:
@@ -309,7 +307,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
case MATH_STEP_DECIMALS: {
return PropertyInfo(Variant::FLOAT, "step");
} break;
- case MATH_STEPIFY: {
+ case MATH_SNAPPED: {
if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "s");
} else {
@@ -476,13 +474,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::BOOL, "allow_objects");
}
} break;
- case COLORN: {
- if (p_idx == 0) {
- return PropertyInfo(Variant::STRING, "name");
- } else {
- return PropertyInfo(Variant::FLOAT, "alpha");
- }
- } break;
case FUNC_MAX: {
}
}
@@ -537,7 +528,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_STEP_DECIMALS: {
t = Variant::INT;
} break;
- case MATH_STEPIFY:
+ case MATH_SNAPPED:
case MATH_LERP:
case MATH_LERP_ANGLE:
case MATH_INVERSE_LERP:
@@ -635,9 +626,6 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
t = Variant::BOOL;
}
} break;
- case COLORN: {
- t = Variant::COLOR;
- } break;
case FUNC_MAX: {
}
}
@@ -659,7 +647,7 @@ String VisualScriptBuiltinFunc::get_caption() const {
void VisualScriptBuiltinFunc::set_func(BuiltinFunc p_which) {
ERR_FAIL_INDEX(p_which, FUNC_MAX);
func = p_which;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -805,10 +793,10 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(0);
*r_return = Math::step_decimals((double)*p_inputs[0]);
} break;
- case VisualScriptBuiltinFunc::MATH_STEPIFY: {
+ case VisualScriptBuiltinFunc::MATH_SNAPPED: {
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
- *r_return = Math::stepify((double)*p_inputs[0], (double)*p_inputs[1]);
+ *r_return = Math::snapped((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_LERP: {
VALIDATE_ARG_NUM(0);
@@ -1176,15 +1164,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
*r_return = ret;
} break;
- case VisualScriptBuiltinFunc::COLORN: {
- VALIDATE_ARG_NUM(1);
-
- Color color = Color::named(*p_inputs[0]);
- color.a = *p_inputs[1];
-
- *r_return = String(color);
-
- } break;
default: {
}
}
@@ -1254,7 +1233,7 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(MATH_ISINF);
BIND_ENUM_CONSTANT(MATH_EASE);
BIND_ENUM_CONSTANT(MATH_STEP_DECIMALS);
- BIND_ENUM_CONSTANT(MATH_STEPIFY);
+ BIND_ENUM_CONSTANT(MATH_SNAPPED);
BIND_ENUM_CONSTANT(MATH_LERP);
BIND_ENUM_CONSTANT(MATH_INVERSE_LERP);
BIND_ENUM_CONSTANT(MATH_RANGE_LERP);
@@ -1292,7 +1271,6 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(STR_TO_VAR);
BIND_ENUM_CONSTANT(VAR_TO_BYTES);
BIND_ENUM_CONSTANT(BYTES_TO_VAR);
- BIND_ENUM_CONSTANT(COLORN);
BIND_ENUM_CONSTANT(MATH_SMOOTHSTEP);
BIND_ENUM_CONSTANT(MATH_POSMOD);
BIND_ENUM_CONSTANT(MATH_LERP_ANGLE);
@@ -1344,7 +1322,7 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/ease", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_EASE>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/step_decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEP_DECIMALS>);
- VisualScriptLanguage::singleton->add_register_func("functions/built_in/stepify", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEPIFY>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/snapped", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SNAPPED>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp_angle", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP_ANGLE>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/inverse_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_INVERSE_LERP>);
@@ -1388,5 +1366,4 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/str2var", create_builtin_func_node<VisualScriptBuiltinFunc::STR_TO_VAR>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/var2bytes", create_builtin_func_node<VisualScriptBuiltinFunc::VAR_TO_BYTES>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/bytes2var", create_builtin_func_node<VisualScriptBuiltinFunc::BYTES_TO_VAR>);
- VisualScriptLanguage::singleton->add_register_func("functions/built_in/color_named", create_builtin_func_node<VisualScriptBuiltinFunc::COLORN>);
}
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index 361b445e30..1fafaf1d98 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,7 +63,7 @@ public:
MATH_ISINF,
MATH_EASE,
MATH_STEP_DECIMALS,
- MATH_STEPIFY,
+ MATH_SNAPPED,
MATH_LERP,
MATH_INVERSE_LERP,
MATH_RANGE_LERP,
@@ -101,7 +101,6 @@ public:
STR_TO_VAR,
VAR_TO_BYTES,
BYTES_TO_VAR,
- COLORN,
MATH_SMOOTHSTEP,
MATH_POSMOD,
MATH_LERP_ANGLE,
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 19de5d4adc..fcd55b3049 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -61,7 +61,7 @@ protected:
}
void _sig_changed() {
- _change_notify();
+ notify_property_list_changed();
emit_signal("changed");
}
@@ -172,7 +172,7 @@ protected:
public:
void edit(const StringName &p_sig) {
sig = p_sig;
- _change_notify();
+ notify_property_list_changed();
}
VisualScriptEditorSignalEdit() { undo_redo = nullptr; }
@@ -195,11 +195,10 @@ protected:
}
void _var_changed() {
- _change_notify();
+ notify_property_list_changed();
emit_signal("changed");
}
void _var_value_changed() {
- _change_notify("value"); //so the whole tree is not redrawn, makes editing smoother in general
emit_signal("changed");
}
@@ -227,6 +226,19 @@ protected:
undo_redo->create_action(TTR("Set Variable Type"));
undo_redo->add_do_method(script.ptr(), "set_variable_info", var, dc);
undo_redo->add_undo_method(script.ptr(), "set_variable_info", var, d);
+
+ // Setting the default value.
+ Variant::Type type = (Variant::Type)(int)p_value;
+ if (type != Variant::NIL) {
+ Variant default_value;
+ Callable::CallError ce;
+ Variant::construct(type, default_value, nullptr, 0, ce);
+ if (ce.error == Callable::CallError::CALL_OK) {
+ undo_redo->add_do_method(script.ptr(), "set_variable_default_value", var, default_value);
+ undo_redo->add_undo_method(script.ptr(), "set_variable_default_value", var, dc["value"]);
+ }
+ }
+
undo_redo->add_do_method(this, "_var_changed");
undo_redo->add_undo_method(this, "_var_changed");
undo_redo->commit_action();
@@ -309,7 +321,7 @@ protected:
}
p_list->push_back(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt));
p_list->push_back(PropertyInfo(script->get_variable_info(var).type, "value", script->get_variable_info(var).hint, script->get_variable_info(var).hint_string, PROPERTY_USAGE_DEFAULT));
- // Update this when PropertyHint changes
+ // Update this when PropertyHint changes.
p_list->push_back(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,ExpRange,Enum,ExpEasing,Length,SpriteFrame,KeyAccel,Flags,Layers2dRender,Layers2dPhysics,Layer3dRender,Layer3dPhysics,File,Dir,GlobalFile,GlobalDir,ResourceType,MultilineText,PlaceholderText,ColorNoAlpha,ImageCompressLossy,ImageCompressLossLess,ObjectId,String,NodePathToEditedNode,MethodOfVariantType,MethodOfBaseType,MethodOfInstance,MethodOfScript,PropertyOfVariantType,PropertyOfBaseType,PropertyOfInstance,PropertyOfScript,ObjectTooBig,NodePathValidTypes"));
p_list->push_back(PropertyInfo(Variant::STRING, "hint_string"));
p_list->push_back(PropertyInfo(Variant::BOOL, "export"));
@@ -318,7 +330,7 @@ protected:
public:
void edit(const StringName &p_var) {
var = p_var;
- _change_notify();
+ notify_property_list_changed();
}
VisualScriptEditorVariableEdit() { undo_redo = nullptr; }
@@ -546,39 +558,29 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
void VisualScriptEditor::_update_graph_connections() {
graph->clear_connections();
- List<StringName> funcs;
- script->get_function_list(&funcs);
+ List<VisualScript::SequenceConnection> sequence_conns;
+ script->get_sequence_connection_list(&sequence_conns);
- if (funcs.size() <= 0) {
- updating_graph = false;
- return;
+ for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
+ graph->connect_node(itos(E->get().from_node), E->get().from_output, itos(E->get().to_node), 0);
}
- for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) {
- List<VisualScript::SequenceConnection> sequence_conns;
- script->get_sequence_connection_list(F->get(), &sequence_conns);
-
- for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
- graph->connect_node(itos(E->get().from_node), E->get().from_output, itos(E->get().to_node), 0);
- }
-
- List<VisualScript::DataConnection> data_conns;
- script->get_data_connection_list(F->get(), &data_conns);
+ List<VisualScript::DataConnection> data_conns;
+ script->get_data_connection_list(&data_conns);
- for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) {
- VisualScript::DataConnection dc = E->get();
+ for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) {
+ VisualScript::DataConnection dc = E->get();
- Ref<VisualScriptNode> from_node = script->get_node(F->get(), E->get().from_node);
- Ref<VisualScriptNode> to_node = script->get_node(F->get(), E->get().to_node);
+ Ref<VisualScriptNode> from_node = script->get_node(E->get().from_node);
+ Ref<VisualScriptNode> to_node = script->get_node(E->get().to_node);
- if (to_node->has_input_sequence_port()) {
- dc.to_port++;
- }
+ if (to_node->has_input_sequence_port()) {
+ dc.to_port++;
+ }
- dc.from_port += from_node->get_output_sequence_port_count();
+ dc.from_port += from_node->get_output_sequence_port_count();
- graph->connect_node(itos(E->get().from_node), dc.from_port, itos(E->get().to_node), dc.to_port);
- }
+ graph->connect_node(itos(E->get().from_node), dc.from_port, itos(E->get().to_node), dc.to_port);
}
}
@@ -605,17 +607,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
}
}
-
- List<StringName> funcs;
- script->get_function_list(&funcs);
-
- if (funcs.size() <= 0) {
- graph->hide();
- select_func_text->show();
- updating_graph = false;
- return;
- }
-
graph->show();
select_func_text->hide();
@@ -655,348 +646,351 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
};
Ref<Texture2D> seq_port = Control::get_theme_icon("VisualShaderPort", "EditorIcons");
+ List<int> node_ids;
+ script->get_node_list(&node_ids);
- for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions
-
- List<int> ids;
- script->get_node_list(F->get(), &ids);
- StringName editor_icons = "EditorIcons";
+ List<int> ids;
+ script->get_node_list(&ids);
+ StringName editor_icons = "EditorIcons";
- for (List<int>::Element *E = ids.front(); E; E = E->next()) {
- if (p_only_id >= 0 && p_only_id != E->get()) {
- continue;
- }
+ for (List<int>::Element *E = ids.front(); E; E = E->next()) {
+ if (p_only_id >= 0 && p_only_id != E->get()) {
+ continue;
+ }
- Ref<VisualScriptNode> node = script->get_node(F->get(), E->get());
- Vector2 pos = script->get_node_position(F->get(), E->get());
+ Ref<VisualScriptNode> node = script->get_node(E->get());
+ Vector2 pos = script->get_node_position(E->get());
- GraphNode *gnode = memnew(GraphNode);
- gnode->set_title(node->get_caption());
- gnode->set_position_offset(pos * EDSCALE);
- if (error_line == E->get()) {
- gnode->set_overlay(GraphNode::OVERLAY_POSITION);
- } else if (node->is_breakpoint()) {
- gnode->set_overlay(GraphNode::OVERLAY_BREAKPOINT);
- }
+ GraphNode *gnode = memnew(GraphNode);
+ gnode->set_title(node->get_caption());
+ gnode->set_position_offset(pos * EDSCALE);
+ if (error_line == E->get()) {
+ gnode->set_overlay(GraphNode::OVERLAY_POSITION);
+ } else if (node->is_breakpoint()) {
+ gnode->set_overlay(GraphNode::OVERLAY_BREAKPOINT);
+ }
- gnode->set_meta("__vnode", node);
- gnode->set_name(itos(E->get()));
- gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved), varray(E->get()));
- gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node), varray(E->get()), CONNECT_DEFERRED);
+ gnode->set_meta("__vnode", node);
+ gnode->set_name(itos(E->get()));
+ gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved), varray(E->get()));
+ gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node), varray(E->get()), CONNECT_DEFERRED);
- if (E->get() != script->get_function_node_id(F->get())) {
- //function can't be erased
+ {
+ Ref<VisualScriptFunction> v = node;
+ if (!v.is_valid()) {
gnode->set_show_close_button(true);
}
+ }
- bool has_gnode_text = false;
+ bool has_gnode_text = false;
- Ref<VisualScriptLists> nd_list = node;
- bool is_vslist = nd_list.is_valid();
- if (is_vslist) {
- HBoxContainer *hbnc = memnew(HBoxContainer);
+ Ref<VisualScriptLists> nd_list = node;
+ bool is_vslist = nd_list.is_valid();
+ if (is_vslist) {
+ HBoxContainer *hbnc = memnew(HBoxContainer);
+ if (nd_list->is_input_port_editable()) {
+ has_gnode_text = true;
+ Button *btn = memnew(Button);
+ btn->set_text(TTR("Add Input Port"));
+ hbnc->add_child(btn);
+ btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E->get()), CONNECT_DEFERRED);
+ }
+ if (nd_list->is_output_port_editable()) {
if (nd_list->is_input_port_editable()) {
- has_gnode_text = true;
- Button *btn = memnew(Button);
- btn->set_text(TTR("Add Input Port"));
- hbnc->add_child(btn);
- btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E->get()), CONNECT_DEFERRED);
- }
- if (nd_list->is_output_port_editable()) {
- if (nd_list->is_input_port_editable()) {
- hbnc->add_spacer();
- }
- has_gnode_text = true;
- Button *btn = memnew(Button);
- btn->set_text(TTR("Add Output Port"));
- hbnc->add_child(btn);
- btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port), varray(E->get()), CONNECT_DEFERRED);
+ hbnc->add_spacer();
}
- gnode->add_child(hbnc);
- } else if (Object::cast_to<VisualScriptExpression>(node.ptr())) {
has_gnode_text = true;
- LineEdit *line_edit = memnew(LineEdit);
- line_edit->set_text(node->get_text());
- line_edit->set_expand_to_text_length(true);
- line_edit->add_theme_font_override("font", get_theme_font("source", "EditorFonts"));
- line_edit->add_theme_font_size_override("font_size", get_theme_font_size("source_size", "EditorFonts"));
- gnode->add_child(line_edit);
- line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E->get()));
- } else {
- String text = node->get_text();
- if (!text.empty()) {
- has_gnode_text = true;
- Label *label = memnew(Label);
- label->set_text(text);
- gnode->add_child(label);
- }
+ Button *btn = memnew(Button);
+ btn->set_text(TTR("Add Output Port"));
+ hbnc->add_child(btn);
+ btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port), varray(E->get()), CONNECT_DEFERRED);
}
-
- if (Object::cast_to<VisualScriptComment>(node.ptr())) {
- Ref<VisualScriptComment> vsc = node;
- gnode->set_comment(true);
- gnode->set_resizable(true);
- gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE);
- gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized), varray(E->get()));
+ gnode->add_child(hbnc);
+ } else if (Object::cast_to<VisualScriptExpression>(node.ptr())) {
+ has_gnode_text = true;
+ LineEdit *line_edit = memnew(LineEdit);
+ line_edit->set_text(node->get_text());
+ line_edit->set_expand_to_text_length(true);
+ line_edit->add_theme_font_override("font", get_theme_font("source", "EditorFonts"));
+ gnode->add_child(line_edit);
+ line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E->get()));
+ } else {
+ String text = node->get_text();
+ if (!text.is_empty()) {
+ has_gnode_text = true;
+ Label *label = memnew(Label);
+ label->set_text(text);
+ gnode->add_child(label);
}
+ }
- if (node_styles.has(node->get_category())) {
- Ref<StyleBoxFlat> sbf = node_styles[node->get_category()];
- if (gnode->is_comment()) {
- sbf = EditorNode::get_singleton()->get_theme_base()->get_theme()->get_stylebox("comment", "GraphNode");
- }
+ if (Object::cast_to<VisualScriptComment>(node.ptr())) {
+ Ref<VisualScriptComment> vsc = node;
+ gnode->set_comment(true);
+ gnode->set_resizable(true);
+ gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE);
+ gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized), varray(E->get()));
+ }
- Color c = sbf->get_border_color();
- Color ic = c;
- c.a = 1;
- if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) {
- Color mono_color;
- if (((c.r + c.g + c.b) / 3) < 0.7) {
- mono_color = Color(1.0, 1.0, 1.0);
- ic = Color(0.0, 0.0, 0.0, 0.7);
- } else {
- mono_color = Color(0.0, 0.0, 0.0);
- ic = Color(1.0, 1.0, 1.0, 0.7);
- }
- mono_color.a = 0.85;
- c = mono_color;
+ if (node_styles.has(node->get_category())) {
+ Ref<StyleBoxFlat> sbf = node_styles[node->get_category()];
+ if (gnode->is_comment()) {
+ sbf = EditorNode::get_singleton()->get_theme_base()->get_theme()->get_stylebox("comment", "GraphNode");
+ }
+
+ Color c = sbf->get_border_color();
+ Color ic = c;
+ c.a = 1;
+ if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) {
+ Color mono_color;
+ if (((c.r + c.g + c.b) / 3) < 0.7) {
+ mono_color = Color(1.0, 1.0, 1.0);
+ ic = Color(0.0, 0.0, 0.0, 0.7);
+ } else {
+ mono_color = Color(0.0, 0.0, 0.0);
+ ic = Color(1.0, 1.0, 1.0, 0.7);
}
- gnode->add_theme_color_override("title_color", c);
- c.a = 0.7;
- gnode->add_theme_color_override("close_color", c);
- gnode->add_theme_color_override("resizer_color", ic);
- gnode->add_theme_style_override("frame", sbf);
+ mono_color.a = 0.85;
+ c = mono_color;
}
+ gnode->add_theme_color_override("title_color", c);
+ c.a = 0.7;
+ gnode->add_theme_color_override("close_color", c);
+ gnode->add_theme_color_override("resizer_color", ic);
+ gnode->add_theme_style_override("frame", sbf);
+ }
- const Color mono_color = get_theme_color("mono_color", "Editor");
+ const Color mono_color = get_theme_color("mono_color", "Editor");
- int slot_idx = 0;
+ int slot_idx = 0;
- bool single_seq_output = node->get_output_sequence_port_count() == 1 && node->get_output_sequence_port_text(0) == String();
- if ((node->has_input_sequence_port() || single_seq_output) || has_gnode_text) {
- // IF has_gnode_text is true BUT we have no sequence ports to draw (in here),
- // we still draw the disabled default ones to shift up the slots by one,
- // so the slots DON'T start with the content text.
+ bool single_seq_output = node->get_output_sequence_port_count() == 1 && node->get_output_sequence_port_text(0) == String();
+ if ((node->has_input_sequence_port() || single_seq_output) || has_gnode_text) {
+ // IF has_gnode_text is true BUT we have no sequence ports to draw (in here),
+ // we still draw the disabled default ones to shift up the slots by one,
+ // so the slots DON'T start with the content text.
- // IF has_gnode_text is false, but we DO want to draw default sequence ports,
- // we draw a dummy text to take up the position of the sequence nodes, so all the other ports are still aligned correctly.
- if (!has_gnode_text) {
- Label *dummy = memnew(Label);
- dummy->set_text(" ");
- gnode->add_child(dummy);
- }
- gnode->set_slot(0, node->has_input_sequence_port(), TYPE_SEQUENCE, mono_color, single_seq_output, TYPE_SEQUENCE, mono_color, seq_port, seq_port);
- slot_idx++;
+ // IF has_gnode_text is false, but we DO want to draw default sequence ports,
+ // we draw a dummy text to take up the position of the sequence nodes, so all the other ports are still aligned correctly.
+ if (!has_gnode_text) {
+ Label *dummy = memnew(Label);
+ dummy->set_text(" ");
+ gnode->add_child(dummy);
}
+ gnode->set_slot(0, node->has_input_sequence_port(), TYPE_SEQUENCE, mono_color, single_seq_output, TYPE_SEQUENCE, mono_color, seq_port, seq_port);
+ slot_idx++;
+ }
- int mixed_seq_ports = 0;
+ int mixed_seq_ports = 0;
- if (!single_seq_output) {
- if (node->has_mixed_input_and_sequence_ports()) {
- mixed_seq_ports = node->get_output_sequence_port_count();
- } else {
- for (int i = 0; i < node->get_output_sequence_port_count(); i++) {
- Label *text2 = memnew(Label);
- text2->set_text(node->get_output_sequence_port_text(i));
- text2->set_align(Label::ALIGN_RIGHT);
- gnode->add_child(text2);
- gnode->set_slot(slot_idx, false, 0, Color(), true, TYPE_SEQUENCE, mono_color, seq_port, seq_port);
- slot_idx++;
- }
+ if (!single_seq_output) {
+ if (node->has_mixed_input_and_sequence_ports()) {
+ mixed_seq_ports = node->get_output_sequence_port_count();
+ } else {
+ for (int i = 0; i < node->get_output_sequence_port_count(); i++) {
+ Label *text2 = memnew(Label);
+ text2->set_text(node->get_output_sequence_port_text(i));
+ text2->set_align(Label::ALIGN_RIGHT);
+ gnode->add_child(text2);
+ gnode->set_slot(slot_idx, false, 0, Color(), true, TYPE_SEQUENCE, mono_color, seq_port, seq_port);
+ slot_idx++;
}
}
+ }
- for (int i = 0; i < MAX(node->get_output_value_port_count(), MAX(mixed_seq_ports, node->get_input_value_port_count())); i++) {
- bool left_ok = false;
- Variant::Type left_type = Variant::NIL;
- String left_name;
+ for (int i = 0; i < MAX(node->get_output_value_port_count(), MAX(mixed_seq_ports, node->get_input_value_port_count())); i++) {
+ bool left_ok = false;
+ Variant::Type left_type = Variant::NIL;
+ String left_name;
- if (i < node->get_input_value_port_count()) {
- PropertyInfo pi = node->get_input_value_port_info(i);
- left_ok = true;
- left_type = pi.type;
- left_name = pi.name;
- }
+ if (i < node->get_input_value_port_count()) {
+ PropertyInfo pi = node->get_input_value_port_info(i);
+ left_ok = true;
+ left_type = pi.type;
+ left_name = pi.name;
+ }
- bool right_ok = false;
- Variant::Type right_type = Variant::NIL;
- String right_name;
+ bool right_ok = false;
+ Variant::Type right_type = Variant::NIL;
+ String right_name;
- if (i >= mixed_seq_ports && i < node->get_output_value_port_count() + mixed_seq_ports) {
- PropertyInfo pi = node->get_output_value_port_info(i - mixed_seq_ports);
- right_ok = true;
- right_type = pi.type;
- right_name = pi.name;
+ if (i >= mixed_seq_ports && i < node->get_output_value_port_count() + mixed_seq_ports) {
+ PropertyInfo pi = node->get_output_value_port_info(i - mixed_seq_ports);
+ right_ok = true;
+ right_type = pi.type;
+ right_name = pi.name;
+ }
+ VBoxContainer *vbc = memnew(VBoxContainer);
+ HBoxContainer *hbc = memnew(HBoxContainer);
+ HBoxContainer *hbc2 = memnew(HBoxContainer);
+ vbc->add_child(hbc);
+ vbc->add_child(hbc2);
+ if (left_ok) {
+ Ref<Texture2D> t;
+ if (left_type >= 0 && left_type < Variant::VARIANT_MAX) {
+ t = type_icons[left_type];
+ }
+ if (t.is_valid()) {
+ TextureRect *tf = memnew(TextureRect);
+ tf->set_texture(t);
+ tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
+ hbc->add_child(tf);
}
- VBoxContainer *vbc = memnew(VBoxContainer);
- HBoxContainer *hbc = memnew(HBoxContainer);
- HBoxContainer *hbc2 = memnew(HBoxContainer);
- vbc->add_child(hbc);
- vbc->add_child(hbc2);
- if (left_ok) {
- Ref<Texture2D> t;
- if (left_type >= 0 && left_type < Variant::VARIANT_MAX) {
- t = type_icons[left_type];
- }
- if (t.is_valid()) {
- TextureRect *tf = memnew(TextureRect);
- tf->set_texture(t);
- tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
- hbc->add_child(tf);
- }
-
- if (is_vslist) {
- if (nd_list->is_input_port_name_editable()) {
- LineEdit *name_box = memnew(LineEdit);
- hbc->add_child(name_box);
- name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
- name_box->set_text(left_name);
- name_box->set_expand_to_text_length(true);
- name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get()));
- name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, true));
- } else {
- hbc->add_child(memnew(Label(left_name)));
- }
-
- if (nd_list->is_input_port_type_editable()) {
- OptionButton *opbtn = memnew(OptionButton);
- for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) {
- opbtn->add_item(Variant::get_type_name(Variant::Type(j)));
- }
- opbtn->select(left_type);
- opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- hbc->add_child(opbtn);
- opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, true), CONNECT_DEFERRED);
- }
- Button *rmbtn = memnew(Button);
- rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
- hbc->add_child(rmbtn);
- rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port), varray(E->get(), i), CONNECT_DEFERRED);
+ if (is_vslist) {
+ if (nd_list->is_input_port_name_editable()) {
+ LineEdit *name_box = memnew(LineEdit);
+ hbc->add_child(name_box);
+ name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
+ name_box->set_text(left_name);
+ name_box->set_expand_to_text_length(true);
+ name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get()));
+ name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, true));
} else {
hbc->add_child(memnew(Label(left_name)));
}
- if (left_type != Variant::NIL && !script->is_input_value_port_connected(F->get(), E->get(), i)) {
- PropertyInfo pi = node->get_input_value_port_info(i);
- Button *button = memnew(Button);
- Variant value = node->get_default_input_value(i);
- if (value.get_type() != left_type) {
- //different type? for now convert
- //not the same, reconvert
- Callable::CallError ce;
- const Variant *existingp = &value;
- Variant::construct(left_type, value, &existingp, 1, ce);
- }
-
- if (left_type == Variant::COLOR) {
- button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
- button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button), varray(button, value));
- } else if (left_type == Variant::OBJECT && Ref<Resource>(value).is_valid()) {
- Ref<Resource> res = value;
- Array arr;
- arr.push_back(button->get_instance_id());
- arr.push_back(String(value));
- EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_button_resource_previewed", arr);
-
- } else if (pi.type == Variant::INT && pi.hint == PROPERTY_HINT_ENUM) {
- button->set_text(pi.hint_string.get_slice(",", value));
- } else {
- button->set_text(value);
+ if (nd_list->is_input_port_type_editable()) {
+ OptionButton *opbtn = memnew(OptionButton);
+ for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) {
+ opbtn->add_item(Variant::get_type_name(Variant::Type(j)));
}
- button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E->get(), i));
- hbc2->add_child(button);
+ opbtn->select(left_type);
+ opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
+ hbc->add_child(opbtn);
+ opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, true), CONNECT_DEFERRED);
}
+
+ Button *rmbtn = memnew(Button);
+ rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
+ hbc->add_child(rmbtn);
+ rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port), varray(E->get(), i), CONNECT_DEFERRED);
} else {
- Control *c = memnew(Control);
- c->set_custom_minimum_size(Size2(10, 0) * EDSCALE);
- hbc->add_child(c);
+ hbc->add_child(memnew(Label(left_name)));
}
- hbc->add_spacer();
- hbc2->add_spacer();
+ if (left_type != Variant::NIL && !script->is_input_value_port_connected(E->get(), i)) {
+ PropertyInfo pi = node->get_input_value_port_info(i);
+ Button *button = memnew(Button);
+ Variant value = node->get_default_input_value(i);
+ if (value.get_type() != left_type) {
+ //different type? for now convert
+ //not the same, reconvert
+ Callable::CallError ce;
+ const Variant *existingp = &value;
+ Variant::construct(left_type, value, &existingp, 1, ce);
+ }
- if (i < mixed_seq_ports) {
- Label *text2 = memnew(Label);
- text2->set_text(node->get_output_sequence_port_text(i));
- text2->set_align(Label::ALIGN_RIGHT);
- hbc->add_child(text2);
+ if (left_type == Variant::COLOR) {
+ button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
+ button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button), varray(button, value));
+ } else if (left_type == Variant::OBJECT && Ref<Resource>(value).is_valid()) {
+ Ref<Resource> res = value;
+ Array arr;
+ arr.push_back(button->get_instance_id());
+ arr.push_back(String(value));
+ EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_button_resource_previewed", arr);
+
+ } else if (pi.type == Variant::INT && pi.hint == PROPERTY_HINT_ENUM) {
+ button->set_text(pi.hint_string.get_slice(",", value));
+ } else {
+ button->set_text(value);
+ }
+ button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E->get(), i));
+ hbc2->add_child(button);
}
+ } else {
+ Control *c = memnew(Control);
+ c->set_custom_minimum_size(Size2(10, 0) * EDSCALE);
+ hbc->add_child(c);
+ }
- if (right_ok) {
- if (is_vslist) {
- Button *rmbtn = memnew(Button);
- rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
- hbc->add_child(rmbtn);
- rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port), varray(E->get(), i), CONNECT_DEFERRED);
-
- if (nd_list->is_output_port_type_editable()) {
- OptionButton *opbtn = memnew(OptionButton);
- for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) {
- opbtn->add_item(Variant::get_type_name(Variant::Type(j)));
- }
- opbtn->select(right_type);
- opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
- hbc->add_child(opbtn);
- opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, false), CONNECT_DEFERRED);
- }
+ hbc->add_spacer();
+ hbc2->add_spacer();
- if (nd_list->is_output_port_name_editable()) {
- LineEdit *name_box = memnew(LineEdit);
- hbc->add_child(name_box);
- name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
- name_box->set_text(right_name);
- name_box->set_expand_to_text_length(true);
- name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get()));
- name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, false));
- } else {
- hbc->add_child(memnew(Label(right_name)));
+ if (i < mixed_seq_ports) {
+ Label *text2 = memnew(Label);
+ text2->set_text(node->get_output_sequence_port_text(i));
+ text2->set_align(Label::ALIGN_RIGHT);
+ hbc->add_child(text2);
+ }
+
+ if (right_ok) {
+ if (is_vslist) {
+ Button *rmbtn = memnew(Button);
+ rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
+ hbc->add_child(rmbtn);
+ rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port), varray(E->get(), i), CONNECT_DEFERRED);
+
+ if (nd_list->is_output_port_type_editable()) {
+ OptionButton *opbtn = memnew(OptionButton);
+ for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) {
+ opbtn->add_item(Variant::get_type_name(Variant::Type(j)));
}
- } else {
- hbc->add_child(memnew(Label(right_name)));
+ opbtn->select(right_type);
+ opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
+ hbc->add_child(opbtn);
+ opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, false), CONNECT_DEFERRED);
}
- Ref<Texture2D> t;
- if (right_type >= 0 && right_type < Variant::VARIANT_MAX) {
- t = type_icons[right_type];
- }
- if (t.is_valid()) {
- TextureRect *tf = memnew(TextureRect);
- tf->set_texture(t);
- tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
- hbc->add_child(tf);
+ if (nd_list->is_output_port_name_editable()) {
+ LineEdit *name_box = memnew(LineEdit);
+ hbc->add_child(name_box);
+ name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
+ name_box->set_text(right_name);
+ name_box->set_expand_to_text_length(true);
+ name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get()));
+ name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, false));
+ } else {
+ hbc->add_child(memnew(Label(right_name)));
}
- }
-
- gnode->add_child(vbc);
-
- bool dark_theme = get_theme_constant("dark_theme", "Editor");
- if (i < mixed_seq_ports) {
- gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture2D>(), seq_port);
} else {
- gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), right_ok, right_type, _color_from_type(right_type, dark_theme));
+ hbc->add_child(memnew(Label(right_name)));
}
- slot_idx++;
+ Ref<Texture2D> t;
+ if (right_type >= 0 && right_type < Variant::VARIANT_MAX) {
+ t = type_icons[right_type];
+ }
+ if (t.is_valid()) {
+ TextureRect *tf = memnew(TextureRect);
+ tf->set_texture(t);
+ tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
+ hbc->add_child(tf);
+ }
}
- graph->add_child(gnode);
+ gnode->add_child(vbc);
- if (gnode->is_comment()) {
- graph->move_child(gnode, 0);
+ bool dark_theme = get_theme_constant("dark_theme", "Editor");
+ if (i < mixed_seq_ports) {
+ gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture2D>(), seq_port);
+ } else {
+ gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), right_ok, right_type, _color_from_type(right_type, dark_theme));
}
+
+ slot_idx++;
+ }
+
+ graph->add_child(gnode);
+
+ if (gnode->is_comment()) {
+ graph->move_child(gnode, 0);
}
}
+
_update_graph_connections();
- // use default_func instead of default_func for now I think that should be good stop gap solution to ensure not breaking anything
- graph->call_deferred("set_scroll_ofs", script->get_function_scroll(default_func) * EDSCALE);
+
+ float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity");
+ graph->set_minimap_opacity(graph_minimap_opacity);
+
+ // Use default_func instead of default_func for now I think that should be good stop gap solution to ensure not breaking anything.
+ graph->call_deferred("set_scroll_ofs", script->get_scroll() * EDSCALE);
updating_graph = false;
}
void VisualScriptEditor::_change_port_type(int p_select, int p_id, int p_port, bool is_input) {
- StringName func = _get_function_of_node(p_id);
-
- Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
+ Ref<VisualScriptLists> vsn = script->get_node(p_id);
if (!vsn.is_valid()) {
return;
}
@@ -1015,14 +1009,12 @@ void VisualScriptEditor::_change_port_type(int p_select, int p_id, int p_port, b
void VisualScriptEditor::_update_node_size(int p_id) {
Node *node = graph->get_node(itos(p_id));
if (Object::cast_to<Control>(node)) {
- Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); //shrink if text is smaller
+ Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); // Shrink if text is smaller.
}
}
void VisualScriptEditor::_port_name_focus_out(const Node *p_name_box, int p_id, int p_port, bool is_input) {
- StringName func = _get_function_of_node(p_id);
-
- Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
+ Ref<VisualScriptLists> vsn = script->get_node(p_id);
if (!vsn.is_valid()) {
return;
}
@@ -1063,11 +1055,8 @@ void VisualScriptEditor::_update_members() {
List<StringName> func_names;
script->get_function_list(&func_names);
+ func_names.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E = func_names.front(); E; E = E->next()) {
- if (E->get() == default_func) {
- continue;
- }
-
TreeItem *ti = members->create_item(functions);
ti->set_text(0, E->get());
ti->set_selectable(0, true);
@@ -1200,7 +1189,7 @@ void VisualScriptEditor::_member_selected() {
#endif
if (held_ctrl) {
ERR_FAIL_COND(!script->has_function(selected));
- _center_on_node(selected, script->get_function_node_id(selected));
+ _center_on_node(script->get_function_node_id(selected));
}
}
}
@@ -1243,8 +1232,8 @@ void VisualScriptEditor::_member_edited() {
int node_id = script->get_function_node_id(name);
Ref<VisualScriptFunction> func;
- if (script->has_node(name, node_id)) {
- func = script->get_node(name, node_id);
+ if (script->has_node(node_id)) {
+ func = script->get_node(node_id);
}
undo_redo->create_action(TTR("Rename Function"));
undo_redo->add_do_method(script.ptr(), "rename_function", name, new_name);
@@ -1254,21 +1243,17 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(func.ptr(), "set_name", name);
}
- // also fix all function calls
- List<StringName> flst;
- script->get_function_list(&flst);
- for (List<StringName>::Element *E = flst.front(); E; E = E->next()) {
- List<int> lst;
- script->get_node_list(E->get(), &lst);
- for (List<int>::Element *F = lst.front(); F; F = F->next()) {
- Ref<VisualScriptFunctionCall> fncall = script->get_node(E->get(), F->get());
- if (!fncall.is_valid()) {
- continue;
- }
- if (fncall->get_function() == name) {
- undo_redo->add_do_method(fncall.ptr(), "set_function", new_name);
- undo_redo->add_undo_method(fncall.ptr(), "set_function", name);
- }
+ // Also fix all function calls.
+ List<int> lst;
+ script->get_node_list(&lst);
+ for (List<int>::Element *F = lst.front(); F; F = F->next()) {
+ Ref<VisualScriptFunctionCall> fncall = script->get_node(F->get());
+ if (!fncall.is_valid()) {
+ continue;
+ }
+ if (fncall->get_function() == name) {
+ undo_redo->add_do_method(fncall.ptr(), "set_function", new_name);
+ undo_redo->add_undo_method(fncall.ptr(), "set_function", name);
}
}
@@ -1280,7 +1265,7 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
- return; //or crash because it will become invalid
+ return; // Or crash because it will become invalid.
}
if (ti->get_parent() == root->get_children()->get_next()) {
@@ -1296,7 +1281,7 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
- return; //or crash because it will become invalid
+ return; // Or crash because it will become invalid.
}
if (ti->get_parent() == root->get_children()->get_next()->get_next()) {
@@ -1310,7 +1295,7 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
- return; //or crash because it will become invalid
+ return; // Or crash because it will become invalid.
}
}
@@ -1344,10 +1329,13 @@ void VisualScriptEditor::_create_function() {
func_node->add_argument(arg_type, arg_name);
}
+ int func_node_id = script->get_available_id();
+
undo_redo->create_action(TTR("Add Function"));
- undo_redo->add_do_method(script.ptr(), "add_function", name);
- undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node, ofs);
+ undo_redo->add_do_method(script.ptr(), "add_function", name, func_node_id);
undo_redo->add_undo_method(script.ptr(), "remove_function", name);
+ undo_redo->add_do_method(script.ptr(), "add_node", func_node_id, func_node, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", func_node_id);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
undo_redo->add_do_method(this, "_update_graph");
@@ -1431,11 +1419,12 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
if (ti->get_parent() == root) {
//main buttons
if (ti == root->get_children()) {
- //add function, this one uses menu
+ // Add function, this one uses menu.
if (p_button == 1) {
+ // Ensure script base exists otherwise use custom base type.
+ ERR_FAIL_COND(script.is_null());
new_virtual_method_select->select_method_from_base_type(script->get_instance_base_type(), String(), true);
-
return;
} else if (p_button == 0) {
String name = _validate_name("new_function");
@@ -1445,11 +1434,13 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
Ref<VisualScriptFunction> func_node;
func_node.instance();
func_node->set_name(name);
+ int fn_id = script->get_available_id();
undo_redo->create_action(TTR("Add Function"));
- undo_redo->add_do_method(script.ptr(), "add_function", name);
- undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node, ofs);
+ undo_redo->add_do_method(script.ptr(), "add_function", name, fn_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, ofs);
undo_redo->add_undo_method(script.ptr(), "remove_function", name);
+ undo_redo->add_do_method(script.ptr(), "remove_node", fn_id);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
undo_redo->add_do_method(this, "_update_graph");
@@ -1461,11 +1452,11 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
_update_graph();
}
- return; //or crash because it will become invalid
+ return; // Or crash because it will become invalid.
}
if (ti == root->get_children()->get_next()) {
- //add variable
+ // Add variable.
String name = _validate_name("new_variable");
selected = name;
@@ -1477,11 +1468,11 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
- return; //or crash because it will become invalid
+ return; // Or crash because it will become invalid.
}
if (ti == root->get_children()->get_next()->get_next()) {
- //add variable
+ // Add variable.
String name = _validate_name("new_signal");
selected = name;
@@ -1493,7 +1484,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
- return; //or crash because it will become invalid
+ return; // Or crash because it will become invalid.
}
} else if (ti->get_parent() == root->get_children()) {
selected = ti->get_text(0);
@@ -1505,9 +1496,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
}
void VisualScriptEditor::_add_input_port(int p_id) {
- StringName func = _get_function_of_node(p_id);
-
- Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
+ Ref<VisualScriptLists> vsn = script->get_node(p_id);
if (!vsn.is_valid()) {
return;
}
@@ -1527,9 +1516,7 @@ void VisualScriptEditor::_add_input_port(int p_id) {
}
void VisualScriptEditor::_add_output_port(int p_id) {
- StringName func = _get_function_of_node(p_id);
-
- Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
+ Ref<VisualScriptLists> vsn = script->get_node(p_id);
if (!vsn.is_valid()) {
return;
}
@@ -1549,9 +1536,7 @@ void VisualScriptEditor::_add_output_port(int p_id) {
}
void VisualScriptEditor::_remove_input_port(int p_id, int p_port) {
- StringName func = _get_function_of_node(p_id);
-
- Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
+ Ref<VisualScriptLists> vsn = script->get_node(p_id);
if (!vsn.is_valid()) {
return;
}
@@ -1561,17 +1546,17 @@ void VisualScriptEditor::_remove_input_port(int p_id, int p_port) {
undo_redo->create_action(TTR("Remove Input Port"), UndoRedo::MERGE_ENDS);
int conn_from = -1, conn_port = -1;
- script->get_input_value_port_connection_source(func, p_id, p_port, &conn_from, &conn_port);
+ script->get_input_value_port_connection_source(p_id, p_port, &conn_from, &conn_port);
if (conn_from != -1) {
- undo_redo->add_do_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, p_id, p_port);
+ undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_id, p_port);
}
undo_redo->add_do_method(vsn.ptr(), "remove_input_data_port", p_port);
undo_redo->add_do_method(this, "_update_graph", p_id);
if (conn_from != -1) {
- undo_redo->add_undo_method(script.ptr(), "data_connect", func, conn_from, conn_port, p_id, p_port);
+ undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_id, p_port);
}
undo_redo->add_undo_method(vsn.ptr(), "add_input_data_port", vsn->get_input_value_port_info(p_port).type, vsn->get_input_value_port_info(p_port).name, p_port);
@@ -1583,9 +1568,7 @@ void VisualScriptEditor::_remove_input_port(int p_id, int p_port) {
}
void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
- StringName func = _get_function_of_node(p_id);
-
- Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
+ Ref<VisualScriptLists> vsn = script->get_node(p_id);
if (!vsn.is_valid()) {
return;
}
@@ -1595,12 +1578,12 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
undo_redo->create_action(TTR("Remove Output Port"), UndoRedo::MERGE_ENDS);
List<VisualScript::DataConnection> data_connections;
- script->get_data_connection_list(func, &data_connections);
+ script->get_data_connection_list(&data_connections);
HashMap<int, Set<int>> conn_map;
for (const List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
if (E->get().from_node == p_id && E->get().from_port == p_port) {
- // push into the connections map
+ // Push into the connections map.
if (!conn_map.has(E->get().to_node)) {
conn_map.set(E->get().to_node, Set<int>());
}
@@ -1615,7 +1598,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
conn_map.get_key_list(&keys);
for (const List<int>::Element *E = keys.front(); E; E = E->next()) {
for (const Set<int>::Element *F = conn_map[E->get()].front(); F; F = F->next()) {
- undo_redo->add_undo_method(script.ptr(), "data_connect", func, p_id, p_port, E->get(), F->get());
+ undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E->get(), F->get());
}
}
@@ -1628,9 +1611,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
}
void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id) {
- StringName func = _get_function_of_node(p_id);
-
- Ref<VisualScriptExpression> vse = script->get_node(func, p_id);
+ Ref<VisualScriptExpression> vse = script->get_node(p_id);
if (!vse.is_valid()) {
return;
}
@@ -1646,7 +1627,7 @@ void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id
Node *node = graph->get_node(itos(p_id));
if (Object::cast_to<Control>(node)) {
- Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); //shrink if text is smaller
+ Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); // Shrink if text is smaller.
}
updating_graph = false;
@@ -1666,19 +1647,14 @@ Vector2 VisualScriptEditor::_get_available_pos(bool centered, Vector2 ofs) const
while (true) {
bool exists = false;
- List<StringName> all_fn;
- script->get_function_list(&all_fn);
- for (List<StringName>::Element *F = all_fn.front(); F; F = F->next()) {
- StringName curr_fn = F->get();
- List<int> existing;
- script->get_node_list(curr_fn, &existing);
- for (List<int>::Element *E = existing.front(); E; E = E->next()) {
- Point2 pos = script->get_node_position(curr_fn, E->get());
- if (pos.distance_to(ofs) < 50) {
- ofs += Vector2(graph->get_snap(), graph->get_snap());
- exists = true;
- break;
- }
+ List<int> existing;
+ script->get_node_list(&existing);
+ for (List<int>::Element *E = existing.front(); E; E = E->next()) {
+ Point2 pos = script->get_node_position(E->get());
+ if (pos.distance_to(ofs) < 50) {
+ ofs += Vector2(graph->get_snap(), graph->get_snap());
+ exists = true;
+ break;
}
}
if (exists) {
@@ -1710,7 +1686,7 @@ String VisualScriptEditor::_validate_name(const String &p_name) const {
}
void VisualScriptEditor::_on_nodes_delete() {
- // delete all the selected nodes
+ // Delete all the selected nodes.
List<int> to_erase;
@@ -1723,7 +1699,7 @@ void VisualScriptEditor::_on_nodes_delete() {
}
}
- if (to_erase.empty()) {
+ if (to_erase.is_empty()) {
return;
}
@@ -1732,26 +1708,24 @@ void VisualScriptEditor::_on_nodes_delete() {
for (List<int>::Element *F = to_erase.front(); F; F = F->next()) {
int cr_node = F->get();
- StringName func = _get_function_of_node(cr_node);
-
- undo_redo->add_do_method(script.ptr(), "remove_node", func, cr_node);
- undo_redo->add_undo_method(script.ptr(), "add_node", func, cr_node, script->get_node(func, cr_node), script->get_node_position(func, cr_node));
+ undo_redo->add_do_method(script.ptr(), "remove_node", cr_node);
+ undo_redo->add_undo_method(script.ptr(), "add_node", cr_node, script->get_node(cr_node), script->get_node_position(cr_node));
List<VisualScript::SequenceConnection> sequence_conns;
- script->get_sequence_connection_list(func, &sequence_conns);
+ script->get_sequence_connection_list(&sequence_conns);
for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
if (E->get().from_node == cr_node || E->get().to_node == cr_node) {
- undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, E->get().from_node, E->get().from_output, E->get().to_node);
+ undo_redo->add_undo_method(script.ptr(), "sequence_connect", E->get().from_node, E->get().from_output, E->get().to_node);
}
}
List<VisualScript::DataConnection> data_conns;
- script->get_data_connection_list(func, &data_conns);
+ script->get_data_connection_list(&data_conns);
for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) {
if (E->get().from_node == F->get() || E->get().to_node == F->get()) {
- undo_redo->add_undo_method(script.ptr(), "data_connect", func, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(script.ptr(), "data_connect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
}
}
}
@@ -1763,7 +1737,6 @@ void VisualScriptEditor::_on_nodes_delete() {
void VisualScriptEditor::_on_nodes_duplicate() {
Set<int> to_duplicate;
- List<StringName> funcs;
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
@@ -1771,12 +1744,11 @@ void VisualScriptEditor::_on_nodes_duplicate() {
if (gn->is_selected() && gn->is_close_button_visible()) {
int id = gn->get_name().operator String().to_int();
to_duplicate.insert(id);
- funcs.push_back(_get_function_of_node(id));
}
}
}
- if (to_duplicate.empty()) {
+ if (to_duplicate.is_empty()) {
return;
}
@@ -1787,9 +1759,8 @@ void VisualScriptEditor::_on_nodes_duplicate() {
HashMap<int, int> remap;
for (Set<int>::Element *F = to_duplicate.front(); F; F = F->next()) {
- // duplicate from the specific function but place it into the default func as it would lack the connections
- StringName func = _get_function_of_node(F->get());
- Ref<VisualScriptNode> node = script->get_node(func, F->get());
+ // Duplicate from the specific function but place it into the default func as it would lack the connections.
+ Ref<VisualScriptNode> node = script->get_node(F->get());
Ref<VisualScriptNode> dupe = node->duplicate(true);
@@ -1797,25 +1768,23 @@ void VisualScriptEditor::_on_nodes_duplicate() {
remap.set(F->get(), new_id);
to_select.insert(new_id);
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, dupe, script->get_node_position(func, F->get()) + Vector2(20, 20));
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, dupe, script->get_node_position(F->get()) + Vector2(20, 20));
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
}
- for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) {
- List<VisualScript::SequenceConnection> seqs;
- script->get_sequence_connection_list(F->get(), &seqs);
- for (List<VisualScript::SequenceConnection>::Element *E = seqs.front(); E; E = E->next()) {
- if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", default_func, remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]);
- }
+ List<VisualScript::SequenceConnection> seqs;
+ script->get_sequence_connection_list(&seqs);
+ for (List<VisualScript::SequenceConnection>::Element *E = seqs.front(); E; E = E->next()) {
+ if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]);
}
+ }
- List<VisualScript::DataConnection> data;
- script->get_data_connection_list(F->get(), &data);
- for (List<VisualScript::DataConnection>::Element *E = data.front(); E; E = E->next()) {
- if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) {
- undo_redo->add_do_method(script.ptr(), "data_connect", default_func, remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port);
- }
+ List<VisualScript::DataConnection> data;
+ script->get_data_connection_list(&data);
+ for (List<VisualScript::DataConnection>::Element *E = data.front(); E; E = E->next()) {
+ if (to_duplicate.has(E->get().from_node) && to_duplicate.has(E->get().to_node)) {
+ undo_redo->add_do_method(script.ptr(), "data_connect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port);
}
}
@@ -1833,7 +1802,7 @@ void VisualScriptEditor::_on_nodes_duplicate() {
}
if (to_select.size()) {
- EditorNode::get_singleton()->push_item(script->get_node(default_func, to_select.front()->get()).ptr());
+ EditorNode::get_singleton()->push_item(script->get_node(to_select.front()->get()).ptr());
}
}
@@ -1846,7 +1815,7 @@ void VisualScriptEditor::_generic_search(String p_base_type, Vector2 pos, bool n
new_connect_node_select->select_from_visual_script(p_base_type, false, false); // neither connecting nor reset text
- // ensure that the dialog fits inside the graph
+ // Ensure that the dialog fits inside the graph.
Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size();
pos.x = pos.x > bounds.x ? bounds.x : pos.x;
pos.y = pos.y > bounds.y ? bounds.y : pos.y;
@@ -1907,7 +1876,7 @@ void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) {
if (btn.is_valid() && btn->is_doubleclick()) {
TreeItem *ti = members->get_selected();
if (ti && ti->get_parent() == members->get_root()->get_children()) { // to check if it's a function
- _center_on_node(ti->get_metadata(0), script->get_function_node_id(ti->get_metadata(0)));
+ _center_on_node(script->get_function_node_id(ti->get_metadata(0)));
}
}
}
@@ -1925,8 +1894,8 @@ void VisualScriptEditor::_rename_function(const String &name, const String &new_
int node_id = script->get_function_node_id(name);
Ref<VisualScriptFunction> func;
- if (script->has_node(name, node_id)) {
- func = script->get_node(name, node_id);
+ if (script->has_node(node_id)) {
+ func = script->get_node(node_id);
}
undo_redo->create_action(TTR("Rename Function"));
undo_redo->add_do_method(script.ptr(), "rename_function", name, new_name);
@@ -1936,21 +1905,17 @@ void VisualScriptEditor::_rename_function(const String &name, const String &new_
undo_redo->add_undo_method(func.ptr(), "set_name", name);
}
- // also fix all function calls
- List<StringName> flst;
- script->get_function_list(&flst);
- for (List<StringName>::Element *E = flst.front(); E; E = E->next()) {
- List<int> lst;
- script->get_node_list(E->get(), &lst);
- for (List<int>::Element *F = lst.front(); F; F = F->next()) {
- Ref<VisualScriptFunctionCall> fncall = script->get_node(E->get(), F->get());
- if (!fncall.is_valid()) {
- continue;
- }
- if (fncall->get_function() == name) {
- undo_redo->add_do_method(fncall.ptr(), "set_function", new_name);
- undo_redo->add_undo_method(fncall.ptr(), "set_function", name);
- }
+ // Also fix all function calls.
+ List<int> lst;
+ script->get_node_list(&lst);
+ for (List<int>::Element *F = lst.front(); F; F = F->next()) {
+ Ref<VisualScriptFunctionCall> fncall = script->get_node(F->get());
+ if (!fncall.is_valid()) {
+ continue;
+ }
+ if (fncall->get_function() == name) {
+ undo_redo->add_do_method(fncall.ptr(), "set_function", new_name);
+ undo_redo->add_undo_method(fncall.ptr(), "set_function", name);
}
}
@@ -2103,7 +2068,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
ofs /= EDSCALE;
- int new_id = _create_new_node_from_name(d["node_type"], ofs, default_func);
+ int new_id = _create_new_node_from_name(d["node_type"], ofs);
Node *node = graph->get_node(itos(new_id));
if (node) {
@@ -2142,8 +2107,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
int new_id = script->get_available_id();
undo_redo->create_action(TTR("Add Node"));
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, vnode, ofs);
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
@@ -2171,11 +2136,11 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
int new_id = script->get_available_id();
undo_redo->create_action(TTR("Add Node"));
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, vnode, ofs);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, ofs);
undo_redo->add_do_method(vnode.ptr(), "set_base_type", script->get_instance_base_type());
undo_redo->add_do_method(vnode.ptr(), "set_function", d["function"]);
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
@@ -2203,8 +2168,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
int new_id = script->get_available_id();
undo_redo->create_action(TTR("Add Node"));
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, vnode, ofs);
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
@@ -2232,8 +2197,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
int new_id = script->get_available_id();
undo_redo->create_action(TTR("Add Preload Node"));
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, prnode, ofs);
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, prnode, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
@@ -2272,8 +2237,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
prnode.instance();
prnode->set_preload(res);
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, prnode, ofs);
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, prnode, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
new_ids.push_back(new_id);
new_id++;
ofs += Vector2(20, 20) * EDSCALE;
@@ -2339,7 +2304,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
scene_node->set_node_path(sn->get_path_to(node));
n = scene_node;
} else {
- // ! Doesn't work properly
+ // ! Doesn't work properly.
Ref<VisualScriptFunctionCall> call;
call.instance();
call->set_call_mode(VisualScriptFunctionCall::CALL_MODE_NODE_PATH);
@@ -2350,8 +2315,8 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
selecting_method_id = base_id;
}
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, base_id, n, ofs);
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, base_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", base_id, n, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", base_id);
base_id++;
ofs += Vector2(25, 25);
@@ -2420,13 +2385,13 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
vnode = pget;
}
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, base_id, vnode, ofs);
+ undo_redo->add_do_method(script.ptr(), "add_node", base_id, vnode, ofs);
undo_redo->add_do_method(vnode.ptr(), "set_property", d["property"]);
if (!use_get) {
undo_redo->add_do_method(vnode.ptr(), "set_default_input_value", 0, d["value"]);
}
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, base_id);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", base_id);
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
@@ -2465,12 +2430,12 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
vnode = pget;
}
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, base_id, vnode, ofs);
+ undo_redo->add_do_method(script.ptr(), "add_node", base_id, vnode, ofs);
undo_redo->add_do_method(vnode.ptr(), "set_property", d["property"]);
if (!use_get) {
undo_redo->add_do_method(vnode.ptr(), "set_default_input_value", 0, d["value"]);
}
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, base_id);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", base_id);
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
@@ -2480,7 +2445,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
void VisualScriptEditor::_selected_method(const String &p_method, const String &p_type, const bool p_connecting) {
- Ref<VisualScriptFunctionCall> vsfc = script->get_node(default_func, selecting_method_id);
+ Ref<VisualScriptFunctionCall> vsfc = script->get_node(selecting_method_id);
if (!vsfc.is_valid()) {
return;
}
@@ -2538,14 +2503,6 @@ void VisualScriptEditor::set_edited_resource(const RES &p_res) {
script->connect("node_ports_changed", callable_mp(this, &VisualScriptEditor::_node_ports_changed));
- default_func = script->get_default_func();
-
- if (!script->has_function(default_func)) // this is the supposed default function
- {
- script->add_function(default_func);
- script->set_edited(true); //so that if a function was added it's saved
- }
-
_update_graph();
call_deferred("_update_members");
}
@@ -2566,7 +2523,7 @@ String VisualScriptEditor::get_name() {
if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
name = script->get_path().get_file();
if (is_unsaved()) {
- if (script->get_path().empty()) {
+ if (script->get_path().is_empty()) {
name = TTR("[unsaved]");
}
name += "(*)";
@@ -2588,13 +2545,12 @@ bool VisualScriptEditor::is_unsaved() {
bool unsaved =
script->is_edited() ||
script->are_subnodes_edited() ||
- script->get_path().empty(); // In memory.
+ script->get_path().is_empty(); // In memory.
return unsaved;
}
Variant VisualScriptEditor::get_edit_state() {
Dictionary d;
- d["function"] = default_func;
d["scroll"] = graph->get_scroll_ofs();
d["zoom"] = graph->get_zoom();
d["using_snap"] = graph->is_using_snap();
@@ -2604,9 +2560,6 @@ Variant VisualScriptEditor::get_edit_state() {
void VisualScriptEditor::set_edit_state(const Variant &p_state) {
Dictionary d = p_state;
- if (d.has("function")) {
- selected = default_func;
- }
_update_graph();
_update_members();
@@ -2625,11 +2578,11 @@ void VisualScriptEditor::set_edit_state(const Variant &p_state) {
}
}
-void VisualScriptEditor::_center_on_node(const StringName &p_func, int p_id) {
+void VisualScriptEditor::_center_on_node(int p_id) {
Node *n = graph->get_node(itos(p_id));
GraphNode *gn = Object::cast_to<GraphNode>(n);
- // clear selection
+ // Clear selection.
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gnd = Object::cast_to<GraphNode>(graph->get_child(i));
if (gnd) {
@@ -2641,13 +2594,13 @@ void VisualScriptEditor::_center_on_node(const StringName &p_func, int p_id) {
gn->set_selected(true);
Vector2 new_scroll = gn->get_position_offset() - graph->get_size() * 0.5 + gn->get_size() * 0.5;
graph->set_scroll_ofs(new_scroll);
- script->set_function_scroll(p_func, new_scroll / EDSCALE);
+ script->set_scroll(new_scroll / EDSCALE);
script->set_edited(true);
}
}
void VisualScriptEditor::goto_line(int p_line, bool p_with_error) {
- p_line += 1; //add one because script lines begin from 0.
+ p_line += 1; // Add one because script lines begin from 0.
if (p_with_error) {
error_line = p_line;
@@ -2656,7 +2609,7 @@ void VisualScriptEditor::goto_line(int p_line, bool p_with_error) {
List<StringName> functions;
script->get_function_list(&functions);
for (List<StringName>::Element *E = functions.front(); E; E = E->next()) {
- if (script->has_node(E->get(), p_line)) {
+ if (script->has_node(p_line)) {
_update_graph();
_update_members();
@@ -2703,11 +2656,11 @@ Array VisualScriptEditor::get_breakpoints() {
script->get_function_list(&functions);
for (List<StringName>::Element *E = functions.front(); E; E = E->next()) {
List<int> nodes;
- script->get_node_list(E->get(), &nodes);
+ script->get_node_list(&nodes);
for (List<int>::Element *F = nodes.front(); F; F = F->next()) {
- Ref<VisualScriptNode> vsn = script->get_node(E->get(), F->get());
+ Ref<VisualScriptNode> vsn = script->get_node(F->get());
if (vsn->is_breakpoint()) {
- breakpoints.push_back(F->get() - 1); //subtract 1 because breakpoints in text start from zero
+ breakpoints.push_back(F->get() - 1); // Subtract 1 because breakpoints in text start from zero.
}
}
}
@@ -2718,7 +2671,7 @@ void VisualScriptEditor::add_callback(const String &p_function, PackedStringArra
if (script->has_function(p_function)) {
_update_members();
_update_graph();
- _center_on_node(p_function, script->get_function_node_id(p_function));
+ _center_on_node(script->get_function_node_id(p_function));
return;
}
@@ -2742,15 +2695,15 @@ void VisualScriptEditor::add_callback(const String &p_function, PackedStringArra
func->add_argument(type, name);
}
-
+ int fn_id = script->get_available_id();
func->set_name(p_function);
- script->add_function(p_function);
- script->add_node(p_function, script->get_available_id(), func);
+ script->add_function(p_function, fn_id);
+ script->add_node(fn_id, func);
_update_members();
_update_graph();
- _center_on_node(p_function, script->get_function_node_id(p_function));
+ _center_on_node(script->get_function_node_id(p_function));
}
bool VisualScriptEditor::show_members_overview() {
@@ -2844,8 +2797,8 @@ void VisualScriptEditor::_end_node_move() {
undo_redo->commit_action();
}
-void VisualScriptEditor::_move_node(const StringName &p_func, int p_id, const Vector2 &p_to) {
- if (!script->has_function(p_func)) {
+void VisualScriptEditor::_move_node(int p_id, const Vector2 &p_to) {
+ if (!script->has_node(p_id)) {
return;
}
@@ -2855,51 +2808,35 @@ void VisualScriptEditor::_move_node(const StringName &p_func, int p_id, const Ve
Object::cast_to<GraphNode>(node)->set_position_offset(p_to);
}
- script->set_node_position(p_func, p_id, p_to / EDSCALE);
-}
-
-StringName VisualScriptEditor::_get_function_of_node(int p_id) const {
- List<StringName> funcs;
- script->get_function_list(&funcs);
- for (List<StringName>::Element *E = funcs.front(); E; E = E->next()) {
- if (script->has_node(E->get(), p_id)) {
- return E->get();
- }
- }
-
- return ""; // this is passed to avoid crash and is tested against later
+ script->set_node_position(p_id, p_to / EDSCALE);
}
void VisualScriptEditor::_node_moved(Vector2 p_from, Vector2 p_to, int p_id) {
- StringName func = _get_function_of_node(p_id);
-
- undo_redo->add_do_method(this, "_move_node", func, p_id, p_to);
- undo_redo->add_undo_method(this, "_move_node", func, p_id, p_from);
+ undo_redo->add_do_method(this, "_move_node", p_id, p_to);
+ undo_redo->add_undo_method(this, "_move_node", p_id, p_from);
}
void VisualScriptEditor::_remove_node(int p_id) {
undo_redo->create_action(TTR("Remove VisualScript Node"));
- StringName func = _get_function_of_node(p_id);
-
- undo_redo->add_do_method(script.ptr(), "remove_node", func, p_id);
- undo_redo->add_undo_method(script.ptr(), "add_node", func, p_id, script->get_node(func, p_id), script->get_node_position(func, p_id));
+ undo_redo->add_do_method(script.ptr(), "remove_node", p_id);
+ undo_redo->add_undo_method(script.ptr(), "add_node", p_id, script->get_node(p_id), script->get_node_position(p_id));
List<VisualScript::SequenceConnection> sequence_conns;
- script->get_sequence_connection_list(func, &sequence_conns);
+ script->get_sequence_connection_list(&sequence_conns);
for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
if (E->get().from_node == p_id || E->get().to_node == p_id) {
- undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, E->get().from_node, E->get().from_output, E->get().to_node);
+ undo_redo->add_undo_method(script.ptr(), "sequence_connect", E->get().from_node, E->get().from_output, E->get().to_node);
}
}
List<VisualScript::DataConnection> data_conns;
- script->get_data_connection_list(func, &data_conns);
+ script->get_data_connection_list(&data_conns);
for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) {
if (E->get().from_node == p_id || E->get().to_node == p_id) {
- undo_redo->add_undo_method(script.ptr(), "data_connect", func, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(script.ptr(), "data_connect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
}
}
@@ -2909,13 +2846,13 @@ void VisualScriptEditor::_remove_node(int p_id) {
undo_redo->commit_action();
}
-void VisualScriptEditor::_node_ports_changed(const String &p_func, int p_id) {
+void VisualScriptEditor::_node_ports_changed(int p_id) {
_update_graph(p_id);
}
-bool VisualScriptEditor::node_has_sequence_connections(const StringName &p_func, int p_id) {
+bool VisualScriptEditor::node_has_sequence_connections(int p_id) {
List<VisualScript::SequenceConnection> sequence_conns;
- script->get_sequence_connection_list(p_func, &sequence_conns);
+ script->get_sequence_connection_list(&sequence_conns);
for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
int from = E->get().from_node;
@@ -2930,9 +2867,7 @@ bool VisualScriptEditor::node_has_sequence_connections(const StringName &p_func,
}
void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot) {
- StringName from_func = _get_function_of_node(p_from.to_int());
-
- Ref<VisualScriptNode> from_node = script->get_node(from_func, p_from.to_int());
+ Ref<VisualScriptNode> from_node = script->get_node(p_from.to_int());
ERR_FAIL_COND(!from_node.is_valid());
bool from_seq;
@@ -2942,9 +2877,7 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
return; //can't connect this, it's invalid
}
- StringName to_func = _get_function_of_node(p_to.to_int());
-
- Ref<VisualScriptNode> to_node = script->get_node(to_func, p_to.to_int());
+ Ref<VisualScriptNode> to_node = script->get_node(p_to.to_int());
ERR_FAIL_COND(!to_node.is_valid());
bool to_seq;
@@ -2956,56 +2889,23 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
ERR_FAIL_COND(from_seq != to_seq);
- // Do all the checks here
- StringName func; // this the func where we store the one the nodes at the end of the resolution on having multiple nodes
+ // Do all the checks here.
+ StringName func; // This the func where we store the one the nodes at the end of the resolution on having multiple nodes.
undo_redo->create_action(TTR("Connect Nodes"));
- if (from_func == to_func) {
- func = to_func;
- } else if (from_seq) {
- // this is a sequence connection
- _move_nodes_with_rescan(to_func, from_func, p_to.to_int()); // this function moves the nodes from func1 to func2
- func = from_func;
- } else {
- if (node_has_sequence_connections(to_func, p_to.to_int())) {
- if (node_has_sequence_connections(from_func, p_from.to_int())) {
- ERR_PRINT("Trying to connect between different sequence node trees");
- return;
- } else {
- _move_nodes_with_rescan(from_func, to_func, p_from.to_int());
- func = to_func;
- }
- } else if (node_has_sequence_connections(from_func, p_from.to_int())) {
- if (from_func == default_func) {
- _move_nodes_with_rescan(from_func, to_func, p_from.to_int());
- func = to_func;
- } else {
- _move_nodes_with_rescan(to_func, from_func, p_to.to_int());
- func = from_func;
- }
- } else {
- if (to_func == default_func) {
- _move_nodes_with_rescan(to_func, from_func, p_to.to_int());
- func = from_func;
- } else {
- _move_nodes_with_rescan(from_func, to_func, p_from.to_int());
- func = to_func;
- }
- }
- }
-
if (from_seq) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", func, p_from.to_int(), from_port, p_to.to_int());
- // this undo error on undo after move can't be removed without painful gymnastics
- undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, p_from.to_int(), from_port, p_to.to_int());
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", p_from.to_int(), from_port, p_to.to_int());
+ // This undo error on undo after move can't be removed without painful gymnastics
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", p_from.to_int(), from_port, p_to.to_int());
+ undo_redo->add_do_method(this, "_update_graph");
+ undo_redo->add_undo_method(this, "_update_graph");
} else {
bool converted = false;
- int conv_node = -1;
Ref<VisualScriptOperator> oper = to_node;
if (oper.is_valid() && oper->get_typed() == Variant::NIL) {
- // it's an operator Node and if the type is already nil
+ // It's an operator Node and if the type is already nil
if (from_node->get_output_value_port_info(from_port).type != Variant::NIL) {
oper->set_typed(from_node->get_output_value_port_info(from_port).type);
}
@@ -3013,106 +2913,36 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
Ref<VisualScriptOperator> operf = from_node;
if (operf.is_valid() && operf->get_typed() == Variant::NIL) {
- // it's an operator Node and if the type is already nil
+ // It's an operator Node and if the type is already nil
if (to_node->get_input_value_port_info(to_port).type != Variant::NIL) {
operf->set_typed(to_node->get_input_value_port_info(to_port).type);
}
}
- Variant::Type to_type = to_node->get_input_value_port_info(to_port).type;
- Variant::Type from_type = from_node->get_output_value_port_info(from_port).type;
-
- if (to_type != Variant::NIL && from_type != Variant::NIL && to_type != from_type) {
- // add a constructor node between the ports
- bool exceptions = false; // true if there are any exceptions
- exceptions = exceptions || (to_type == Variant::INT && from_type == Variant::FLOAT);
- exceptions = exceptions || (to_type == Variant::FLOAT && from_type == Variant::INT);
- if (Variant::can_convert(from_type, to_type) && !exceptions) {
- MethodInfo mi;
- mi.name = Variant::get_type_name(to_type);
- PropertyInfo pi;
- pi.name = "from";
- pi.type = from_type;
- mi.arguments.push_back(pi);
- mi.return_val.type = to_type;
- // we know that this is allowed so create a new constructor node
- Ref<VisualScriptConstructor> constructor;
- constructor.instance();
- constructor->set_constructor_type(to_type);
- constructor->set_constructor(mi);
- // add the new constructor node
-
- GraphNode *gn = Object::cast_to<GraphNode>(graph->get_node(p_from));
- GraphNode *gn2 = Object::cast_to<GraphNode>(graph->get_node(p_to));
- if (gn && gn2) {
- Vector2 from_node_size = gn->get_rect().get_size();
- Vector2 to_node_size = gn2->get_rect().get_size();
- Vector2 to_node_pos = script->get_node_position(func, p_to.to_int());
- Vector2 from_node_pos = script->get_node_position(func, p_from.to_int());
- Vector2 new_to_node_pos = from_node_pos;
- Vector2 constructor_pos;
- if ((to_node_pos.x - from_node_pos.x) < 0) {
- // to is behind from node
- if (to_node_pos.x > (from_node_pos.x - to_node_size.x - 240)) {
- new_to_node_pos.x = from_node_pos.x - to_node_size.x - 240; // approx size of constructor node + padding
- } else {
- new_to_node_pos.x = to_node_pos.x;
- }
- new_to_node_pos.y = to_node_pos.y;
- constructor_pos.x = from_node_pos.x - 210;
- constructor_pos.y = to_node_pos.y;
- } else {
- // to is ahead of from node
- if (to_node_pos.x < (from_node_size.x + from_node_pos.x + 240)) {
- new_to_node_pos.x = from_node_size.x + from_node_pos.x + 240; // approx size of constructor node + padding
- } else {
- new_to_node_pos.x = to_node_pos.x;
- }
- new_to_node_pos.y = to_node_pos.y;
- constructor_pos.x = from_node_size.x + from_node_pos.x + 10;
- constructor_pos.y = to_node_pos.y;
- }
- undo_redo->add_do_method(this, "_move_node", func, p_to.to_int(), new_to_node_pos);
- undo_redo->add_undo_method(this, "_move_node", func, p_to.to_int(), to_node_pos);
- conv_node = script->get_available_id();
- undo_redo->add_do_method(script.ptr(), "add_node", func, conv_node, constructor, _get_available_pos(false, constructor_pos));
- undo_redo->add_undo_method(script.ptr(), "remove_node", func, conv_node);
- converted = true;
- }
- }
- }
-
- // disconnect current, and connect the new one
- if (script->is_input_value_port_connected(func, p_to.to_int(), to_port)) {
+ // Disconnect current, and connect the new one
+ if (script->is_input_value_port_connected(p_to.to_int(), to_port)) {
if (can_swap && data_disconnect_node == p_to.to_int()) {
int conn_from;
int conn_port;
- script->get_input_value_port_connection_source(func, p_to.to_int(), to_port, &conn_from, &conn_port);
- undo_redo->add_do_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, p_to.to_int(), to_port);
- undo_redo->add_do_method(script.ptr(), "data_connect", func, conn_from, conn_port, data_disconnect_node, data_disconnect_port);
- undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, data_disconnect_node, data_disconnect_port);
- undo_redo->add_undo_method(script.ptr(), "data_connect", func, conn_from, conn_port, p_to.to_int(), to_port);
+ script->get_input_value_port_connection_source(p_to.to_int(), to_port, &conn_from, &conn_port);
+ undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_to.to_int(), to_port);
+ undo_redo->add_do_method(script.ptr(), "data_connect", conn_from, conn_port, data_disconnect_node, data_disconnect_port);
+ undo_redo->add_undo_method(script.ptr(), "data_disconnect", conn_from, conn_port, data_disconnect_node, data_disconnect_port);
+ undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_to.to_int(), to_port);
can_swap = false; // swapped
} else {
int conn_from;
int conn_port;
- script->get_input_value_port_connection_source(func, p_to.to_int(), to_port, &conn_from, &conn_port);
- undo_redo->add_do_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, p_to.to_int(), to_port);
- undo_redo->add_undo_method(script.ptr(), "data_connect", func, conn_from, conn_port, p_to.to_int(), to_port);
+ script->get_input_value_port_connection_source(p_to.to_int(), to_port, &conn_from, &conn_port);
+ undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_to.to_int(), to_port);
+ undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_to.to_int(), to_port);
}
}
if (!converted) {
- undo_redo->add_do_method(script.ptr(), "data_connect", func, p_from.to_int(), from_port, p_to.to_int(), to_port);
- undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, p_from.to_int(), from_port, p_to.to_int(), to_port);
- } else {
- // this is noice
- undo_redo->add_do_method(script.ptr(), "data_connect", func, p_from.to_int(), from_port, conv_node, 0);
- undo_redo->add_do_method(script.ptr(), "data_connect", func, conv_node, 0, p_to.to_int(), to_port);
- // I don't think this is needed but gonna leave it here for now... until I need to finalise it all
- undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, p_from.to_int(), from_port, conv_node, 0);
- undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, conv_node, 0, p_to.to_int(), to_port);
+ undo_redo->add_do_method(script.ptr(), "data_connect", p_from.to_int(), from_port, p_to.to_int(), to_port);
+ undo_redo->add_undo_method(script.ptr(), "data_disconnect", p_from.to_int(), from_port, p_to.to_int(), to_port);
}
- //update nodes in graph
+ // Update nodes in graph
if (!converted) {
undo_redo->add_do_method(this, "_update_graph", p_from.to_int());
undo_redo->add_do_method(this, "_update_graph", p_to.to_int());
@@ -3124,34 +2954,28 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
}
}
- undo_redo->add_do_method(this, "_update_graph_connections");
- undo_redo->add_undo_method(this, "_update_graph_connections");
-
undo_redo->commit_action();
}
void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot) {
- StringName func = _get_function_of_node(p_from.to_int());
- ERR_FAIL_COND(func != _get_function_of_node(p_to.to_int()));
-
- Ref<VisualScriptNode> from_node = script->get_node(func, p_from.to_int());
+ Ref<VisualScriptNode> from_node = script->get_node(p_from.to_int());
ERR_FAIL_COND(!from_node.is_valid());
bool from_seq;
int from_port;
if (!_get_out_slot(from_node, p_from_slot, from_port, from_seq)) {
- return; //can't connect this, it's invalid
+ return; // Can't connect this, it's invalid.
}
- Ref<VisualScriptNode> to_node = script->get_node(func, p_to.to_int());
+ Ref<VisualScriptNode> to_node = script->get_node(p_to.to_int());
ERR_FAIL_COND(!to_node.is_valid());
bool to_seq;
int to_port;
if (!_get_in_slot(to_node, p_to_slot, to_port, to_seq)) {
- return; //can't connect this, it's invalid
+ return; // Can't connect this, it's invalid.
}
ERR_FAIL_COND(from_seq != to_seq);
@@ -3159,248 +2983,27 @@ void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_sl
undo_redo->create_action(TTR("Disconnect Nodes"));
if (from_seq) {
- undo_redo->add_do_method(script.ptr(), "sequence_disconnect", func, p_from.to_int(), from_port, p_to.to_int());
- undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, p_from.to_int(), from_port, p_to.to_int());
+ undo_redo->add_do_method(script.ptr(), "sequence_disconnect", p_from.to_int(), from_port, p_to.to_int());
+ undo_redo->add_undo_method(script.ptr(), "sequence_connect", p_from.to_int(), from_port, p_to.to_int());
+ undo_redo->add_do_method(this, "_update_graph");
+ undo_redo->add_undo_method(this, "_update_graph");
} else {
can_swap = true;
data_disconnect_node = p_to.to_int();
data_disconnect_port = to_port;
- undo_redo->add_do_method(script.ptr(), "data_disconnect", func, p_from.to_int(), from_port, p_to.to_int(), to_port);
- undo_redo->add_undo_method(script.ptr(), "data_connect", func, p_from.to_int(), from_port, p_to.to_int(), to_port);
- //update relevant nodes in the graph
+ undo_redo->add_do_method(script.ptr(), "data_disconnect", p_from.to_int(), from_port, p_to.to_int(), to_port);
+ undo_redo->add_undo_method(script.ptr(), "data_connect", p_from.to_int(), from_port, p_to.to_int(), to_port);
+ // Update relevant nodes in the graph.
undo_redo->add_do_method(this, "_update_graph", p_from.to_int());
undo_redo->add_do_method(this, "_update_graph", p_to.to_int());
undo_redo->add_undo_method(this, "_update_graph", p_from.to_int());
undo_redo->add_undo_method(this, "_update_graph", p_to.to_int());
}
- undo_redo->add_do_method(this, "_update_graph_connections");
- undo_redo->add_undo_method(this, "_update_graph_connections");
undo_redo->commit_action();
}
-void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, const StringName &p_func_to, int p_id) {
- Set<int> nodes_to_move;
- HashMap<int, Map<int, int>> seqconns_to_move; // from => List(outp, to)
- HashMap<int, Map<int, Pair<int, int>>> dataconns_to_move; // to => List(inp_p => from, outp)
-
- nodes_to_move.insert(p_id);
- Set<int> sequence_connections;
- {
- List<VisualScript::SequenceConnection> sequence_conns;
- script->get_sequence_connection_list(p_func_from, &sequence_conns);
-
- HashMap<int, Map<int, int>> seqcons; // from => List(out_p => to)
-
- for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
- int from = E->get().from_node;
- int to = E->get().to_node;
- int out_p = E->get().from_output;
- if (!seqcons.has(from)) {
- seqcons.set(from, Map<int, int>());
- }
- seqcons[from].insert(out_p, to);
- sequence_connections.insert(to);
- sequence_connections.insert(from);
- }
-
- int conn = p_id;
- List<int> stack;
- HashMap<int, Set<int>> seen; // from, outp
- while (seqcons.has(conn)) {
- for (auto E = seqcons[conn].front(); E; E = E->next()) {
- if (seen.has(conn) && seen[conn].has(E->key())) {
- if (!E->next()) {
- if (stack.size() > 0) {
- conn = stack.back()->get();
- stack.pop_back();
- break;
- }
- conn = -101;
- break;
- }
- continue;
- }
- if (!seen.has(conn)) {
- seen.set(conn, Set<int>());
- }
- seen[conn].insert(E->key());
- stack.push_back(conn);
- if (!seqconns_to_move.has(conn)) {
- seqconns_to_move.set(conn, Map<int, int>());
- }
- seqconns_to_move[conn].insert(E->key(), E->get());
- conn = E->get();
- nodes_to_move.insert(conn);
- break;
- }
- if (!seqcons.has(conn) && stack.size() > 0) {
- conn = stack.back()->get();
- stack.pop_back();
- }
- }
- }
-
- {
- List<VisualScript::DataConnection> data_connections;
- script->get_data_connection_list(p_func_from, &data_connections);
- int func_from_node_id = script->get_function_node_id(p_func_from);
-
- HashMap<int, Map<int, Pair<int, int>>> connections;
-
- for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
- int from = E->get().from_node;
- int to = E->get().to_node;
- int out_p = E->get().from_port;
- int in_p = E->get().to_port;
-
- // skip if the from_node is a function node
- if (from == func_from_node_id) {
- continue;
- }
-
- if (!connections.has(to)) {
- connections.set(to, Map<int, Pair<int, int>>());
- }
- connections[to].insert(in_p, Pair<int, int>(from, out_p));
- }
-
- // go through the HashMap and do all sorts of crazy ass stuff now...
- Set<int> nodes_to_be_added;
- for (Set<int>::Element *F = nodes_to_move.front(); F; F = F->next()) {
- HashMap<int, Set<int>> seen;
- List<int> stack;
- int id = F->get();
- while (connections.has(id)) {
- for (auto E = connections[id].front(); E; E = E->next()) {
- if (seen.has(id) && seen[id].has(E->key())) {
- if (!E->next()) {
- if (stack.size() > 0) {
- id = stack.back()->get();
- stack.pop_back();
- break;
- }
- id = -11; // I assume ids can't be negative should confirm it...
- break;
- }
- continue;
- }
-
- if (sequence_connections.has(E->get().first)) {
- if (!nodes_to_move.has(E->get().first)) {
- if (stack.size() > 0) {
- id = stack.back()->get();
- stack.pop_back();
- break;
- }
- id = -11; // I assume ids can't be negative should confirm it...
- break;
- }
- }
-
- if (!seen.has(id)) {
- seen.set(id, Set<int>());
- }
- seen[id].insert(E->key());
- stack.push_back(id);
- if (!dataconns_to_move.has(id)) {
- dataconns_to_move.set(id, Map<int, Pair<int, int>>());
- }
- dataconns_to_move[id].insert(E->key(), Pair<int, int>(E->get().first, E->get().second));
- id = E->get().first;
- nodes_to_be_added.insert(id);
- break;
- }
- if (!connections.has(id) && stack.size() > 0) {
- id = stack.back()->get();
- stack.pop_back();
- }
- }
- }
- for (Set<int>::Element *E = nodes_to_be_added.front(); E; E = E->next()) {
- nodes_to_move.insert(E->get());
- }
- }
-
- // * this is primarily for the sake of the having proper undo
- List<VisualScript::SequenceConnection> seqext;
- List<VisualScript::DataConnection> dataext;
-
- List<VisualScript::SequenceConnection> seq_connections;
- script->get_sequence_connection_list(p_func_from, &seq_connections);
-
- for (List<VisualScript::SequenceConnection>::Element *E = seq_connections.front(); E; E = E->next()) {
- if (!nodes_to_move.has(E->get().from_node) && nodes_to_move.has(E->get().to_node)) {
- seqext.push_back(E->get());
- } else if (nodes_to_move.has(E->get().from_node) && !nodes_to_move.has(E->get().to_node)) {
- seqext.push_back(E->get());
- }
- }
-
- List<VisualScript::DataConnection> data_connections;
- script->get_data_connection_list(p_func_from, &data_connections);
-
- for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
- if (!nodes_to_move.has(E->get().from_node) && nodes_to_move.has(E->get().to_node)) {
- dataext.push_back(E->get());
- } else if (nodes_to_move.has(E->get().from_node) && !nodes_to_move.has(E->get().to_node)) {
- dataext.push_back(E->get());
- }
- }
-
- // undo_redo->create_action("Rescan Functions");
-
- for (Set<int>::Element *E = nodes_to_move.front(); E; E = E->next()) {
- int id = E->get();
-
- undo_redo->add_do_method(script.ptr(), "remove_node", p_func_from, id);
- undo_redo->add_do_method(script.ptr(), "add_node", p_func_to, id, script->get_node(p_func_from, id), script->get_node_position(p_func_from, id));
-
- undo_redo->add_undo_method(script.ptr(), "remove_node", p_func_to, id);
- undo_redo->add_undo_method(script.ptr(), "add_node", p_func_from, id, script->get_node(p_func_from, id), script->get_node_position(p_func_from, id));
- }
-
- List<int> skeys;
- seqconns_to_move.get_key_list(&skeys);
- for (List<int>::Element *E = skeys.front(); E; E = E->next()) {
- int from_node = E->get();
- for (Map<int, int>::Element *F = seqconns_to_move[from_node].front(); F; F = F->next()) {
- int from_port = F->key();
- int to_node = F->get();
- undo_redo->add_do_method(script.ptr(), "sequence_connect", p_func_to, from_node, from_port, to_node);
- undo_redo->add_undo_method(script.ptr(), "sequence_connect", p_func_from, from_node, from_port, to_node);
- }
- }
-
- List<int> keys;
- dataconns_to_move.get_key_list(&keys);
- for (List<int>::Element *E = keys.front(); E; E = E->next()) {
- int to_node = E->get(); // to_node
- for (Map<int, Pair<int, int>>::Element *F = dataconns_to_move[E->get()].front(); F; F = F->next()) {
- int inp_p = F->key();
- Pair<int, int> fro = F->get();
-
- undo_redo->add_do_method(script.ptr(), "data_connect", p_func_to, fro.first, fro.second, to_node, inp_p);
- undo_redo->add_undo_method(script.ptr(), "data_connect", p_func_from, fro.first, fro.second, to_node, inp_p);
- }
- }
-
- // this to have proper undo operations
- for (List<VisualScript::SequenceConnection>::Element *E = seqext.front(); E; E = E->next()) {
- undo_redo->add_undo_method(script.ptr(), "sequence_connect", p_func_from, E->get().from_node, E->get().from_output, E->get().to_node);
- }
- for (List<VisualScript::DataConnection>::Element *E = dataext.front(); E; E = E->next()) {
- undo_redo->add_undo_method(script.ptr(), "data_connect", p_func_from, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
- }
- // this doesn't need do methods as they are handled by the subsequent do calls implicitly
-
- undo_redo->add_do_method(this, "_update_graph");
- undo_redo->add_undo_method(this, "_update_graph");
-
- // undo_redo->commit_action();
-}
-
void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_pos) {
Node *node = graph->get_node(p_from);
GraphNode *gn = Object::cast_to<GraphNode>(node);
@@ -3408,23 +3011,22 @@ void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_fro
return;
}
- StringName func = _get_function_of_node(p_from.to_int());
-
- Ref<VisualScriptNode> vsn = script->get_node(func, p_from.to_int());
+ Ref<VisualScriptNode> vsn = script->get_node(p_from.to_int());
if (!vsn.is_valid()) {
return;
}
+ if (vsn->get_output_value_port_count())
- port_action_pos = p_release_pos;
+ port_action_pos = p_release_pos;
if (p_from_slot < vsn->get_output_sequence_port_count()) {
port_action_node = p_from.to_int();
port_action_output = p_from_slot;
- _port_action_menu(CREATE_ACTION, func);
+ _port_action_menu(CREATE_ACTION);
} else {
port_action_output = p_from_slot - vsn->get_output_sequence_port_count();
port_action_node = p_from.to_int();
- _port_action_menu(CREATE_CALL_SET_GET, func);
+ _port_action_menu(CREATE_CALL_SET_GET);
}
}
@@ -3438,9 +3040,7 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac
visited_nodes.insert(p_port_action_node);
- StringName func = _get_function_of_node(p_port_action_node);
-
- Ref<VisualScriptNode> node = script->get_node(func, p_port_action_node);
+ Ref<VisualScriptNode> node = script->get_node(p_port_action_node);
if (!node.is_valid()) {
return tg;
@@ -3454,11 +3054,11 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac
g.type = pi.type;
if (g.type == Variant::NIL || g.type == Variant::OBJECT) {
- //any or object input, must further guess what this is
+ // Any or object input, must further guess what this is.
int from_node;
int from_port;
- if (script->get_input_value_port_connection_source(func, p_port_action_node, i, &from_node, &from_port)) {
+ if (script->get_input_value_port_connection_source(p_port_action_node, i, &from_node, &from_port)) {
g = _guess_output_type(from_node, from_port, visited_nodes);
} else {
Variant defval = node->get_default_input_value(i);
@@ -3480,7 +3080,7 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac
return node->guess_output_type(in_guesses.ptrw(), p_port_action_output);
}
-void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func) {
+void VisualScriptEditor::_port_action_menu(int p_option) {
Vector2 ofs = graph->get_scroll_ofs() + port_action_pos;
if (graph->is_using_snap()) {
int snap = graph->get_snap();
@@ -3503,8 +3103,8 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func)
n->set_base_type("Object");
}
String type_string;
- if (script->get_node(func, port_action_node)->get_output_value_port_count() > 0) {
- type_string = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ if (script->get_node(port_action_node)->get_output_value_port_count() > 0) {
+ type_string = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string;
}
if (tg.type == Variant::OBJECT) {
if (tg.script.is_valid()) {
@@ -3519,7 +3119,7 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func)
} else {
new_connect_node_select->select_from_basic_type(tg.type);
}
- // ensure that the dialog fits inside the graph
+ // Ensure that the dialog fits inside the graph.
Vector2 pos = mouse_up_position;
Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size();
pos.x = pos.x > bounds.x ? bounds.x : pos.x;
@@ -3529,8 +3129,8 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func)
case CREATE_ACTION: {
VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn);
PropertyInfo property_info;
- if (script->get_node(func, port_action_node)->get_output_value_port_count() > 0) {
- property_info = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output);
+ if (script->get_node(port_action_node)->get_output_value_port_count() > 0) {
+ property_info = script->get_node(port_action_node)->get_output_value_port_info(port_action_output);
}
if (tg.type == Variant::OBJECT) {
if (property_info.type == Variant::OBJECT && property_info.hint_string != String()) {
@@ -3543,7 +3143,7 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func)
} else {
new_connect_node_select->select_from_action(Variant::get_type_name(tg.type));
}
- // ensure that the dialog fits inside the graph
+ // Ensure that the dialog fits inside the graph.
Vector2 pos = mouse_up_position;
Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size();
pos.x = pos.x > bounds.x ? bounds.x : pos.x;
@@ -3572,9 +3172,8 @@ void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<Visua
if (port >= value_count) {
port = 0;
}
- StringName func = _get_function_of_node(port_action_node);
- undo_redo->add_do_method(script.ptr(), "data_connect", func, port_action_node, port, new_id, 0);
- undo_redo->add_undo_method(script.ptr(), "data_disconnect", func, port_action_node, port, new_id, 0);
+ undo_redo->add_do_method(script.ptr(), "data_connect", port_action_node, port, new_id, 0);
+ undo_redo->add_undo_method(script.ptr(), "data_disconnect", port_action_node, port, new_id, 0);
undo_redo->commit_action();
}
@@ -3591,17 +3190,16 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
bool port_node_exists = true;
- StringName func = _get_function_of_node(port_action_node);
- if (func == StringName()) {
- func = default_func;
- port_node_exists = false;
- }
+ // if (func == StringName()) {
+ // func = default_func;
+ // port_node_exists = false;
+ // }
if (p_category == "visualscript") {
Ref<VisualScriptNode> vnode_new = VisualScriptLanguage::singleton->create_node_from_name(p_text);
Ref<VisualScriptNode> vnode_old;
- if (port_node_exists) {
- vnode_old = script->get_node(func, port_action_node);
+ if (port_node_exists && p_connecting) {
+ vnode_old = script->get_node(port_action_node);
}
int new_id = script->get_available_id();
@@ -3624,13 +3222,13 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
}
undo_redo->create_action(TTR("Add Node"));
- undo_redo->add_do_method(script.ptr(), "add_node", func, new_id, vnode_new, ofs);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode_new, ofs);
if (vnode_old.is_valid() && p_connecting) {
connect_seq(vnode_old, vnode_new, new_id);
connect_data(vnode_old, vnode_new, new_id);
}
- undo_redo->add_undo_method(script.ptr(), "remove_node", func, new_id);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
@@ -3687,8 +3285,8 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
int new_id = script->get_available_id();
undo_redo->create_action(TTR("Add Node"));
- undo_redo->add_do_method(script.ptr(), "add_node", func, new_id, vnode, ofs);
- undo_redo->add_undo_method(script.ptr(), "remove_node", func, new_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
undo_redo->add_do_method(this, "_update_graph", new_id);
undo_redo->add_undo_method(this, "_update_graph", new_id);
undo_redo->commit_action();
@@ -3699,7 +3297,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
port_action_new_node = new_id;
- Ref<VisualScriptNode> vsn = script->get_node(func, port_action_new_node);
+ Ref<VisualScriptNode> vsn = script->get_node(port_action_new_node);
if (Object::cast_to<VisualScriptFunctionCall>(vsn.ptr())) {
Ref<VisualScriptFunctionCall> vsfc = vsn;
@@ -3713,10 +3311,9 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
vsfc->set_base_type(String(""));
if (tg.gdclass != StringName()) {
vsfc->set_base_type(tg.gdclass);
-
- } else if (script->get_node(func, port_action_node).is_valid()) {
- PropertyHint hint = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint;
- String base_type = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ } else if (script->get_node(port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string;
if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
vsfc->set_base_type(base_type);
@@ -3749,9 +3346,9 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
if (tg.gdclass != StringName()) {
vsp->set_base_type(tg.gdclass);
- } else if (script->get_node(func, port_action_node).is_valid()) {
- PropertyHint hint = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint;
- String base_type = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ } else if (script->get_node(port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string;
if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
vsp->set_base_type(base_type);
@@ -3779,9 +3376,9 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
if (tg.gdclass != StringName()) {
vsp->set_base_type(tg.gdclass);
- } else if (script->get_node(func, port_action_node).is_valid()) {
- PropertyHint hint = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint;
- String base_type = script->get_node(func, port_action_node)->get_output_value_port_info(port_action_output).hint_string;
+ } else if (script->get_node(port_action_node).is_valid()) {
+ PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint;
+ String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string;
if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) {
vsp->set_base_type(base_type);
}
@@ -3799,16 +3396,13 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
}
}
if (port_node_exists) {
- Ref<VisualScriptNode> vnode_old = script->get_node(func, port_action_node);
+ Ref<VisualScriptNode> vnode_old = script->get_node(port_action_node);
if (vnode_old.is_valid() && p_connecting) {
connect_seq(vnode_old, vnode, port_action_new_node);
connect_data(vnode_old, vnode, port_action_new_node);
}
}
_update_graph(port_action_new_node);
- if (port_node_exists) {
- _update_graph_connections();
- }
}
void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id) {
@@ -3827,29 +3421,27 @@ void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<Visual
return;
}
- StringName func = _get_function_of_node(port_action_node);
-
undo_redo->create_action(TTR("Connect Node Sequence"));
int pass_port = -vnode_old->get_output_sequence_port_count() + 1;
int return_port = port_action_output - 1;
if (vnode_old->get_output_value_port_info(port_action_output).name == String("pass") &&
- !script->get_output_sequence_ports_connected(func, port_action_node).has(pass_port)) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", func, port_action_node, pass_port, new_id);
- undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, port_action_node, pass_port, new_id);
+ !script->get_output_sequence_ports_connected(port_action_node).has(pass_port)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, pass_port, new_id);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, pass_port, new_id);
} else if (vnode_old->get_output_value_port_info(port_action_output).name == String("return") &&
- !script->get_output_sequence_ports_connected(func, port_action_node).has(return_port)) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", func, port_action_node, return_port, new_id);
- undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, port_action_node, return_port, new_id);
+ !script->get_output_sequence_ports_connected(port_action_node).has(return_port)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, return_port, new_id);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, return_port, new_id);
} else {
for (int port = 0; port < vnode_old->get_output_sequence_port_count(); port++) {
int count = vnode_old->get_output_sequence_port_count();
- if (port_action_output < count && !script->get_output_sequence_ports_connected(func, port_action_node).has(port_action_output)) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", func, port_action_node, port_action_output, new_id);
- undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, port_action_node, port_action_output, new_id);
+ if (port_action_output < count && !script->get_output_sequence_ports_connected(port_action_node).has(port_action_output)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, port_action_output, new_id);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, port_action_output, new_id);
break;
- } else if (!script->get_output_sequence_ports_connected(func, port_action_node).has(port)) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", func, port_action_node, port, new_id);
- undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", func, port_action_node, port, new_id);
+ } else if (!script->get_output_sequence_ports_connected(port_action_node).has(port)) {
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, port, new_id);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, port, new_id);
break;
}
}
@@ -3884,9 +3476,9 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, cons
Ref<VisualScriptFunction> func_node;
func_node.instance();
func_node->set_name(name);
-
+ int fn_id = script->get_available_id();
undo_redo->create_action(TTR("Add Function"));
- undo_redo->add_do_method(script.ptr(), "add_function", name);
+ undo_redo->add_do_method(script.ptr(), "add_function", name, fn_id);
for (int i = 0; i < minfo.arguments.size(); i++) {
func_node->add_argument(minfo.arguments[i].type, minfo.arguments[i].name, -1, minfo.arguments[i].hint, minfo.arguments[i].hint_string);
@@ -3894,14 +3486,17 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, cons
Vector2 ofs = _get_available_pos();
- undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node, ofs);
+ undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", fn_id);
if (minfo.return_val.type != Variant::NIL || minfo.return_val.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
Ref<VisualScriptReturn> ret_node;
ret_node.instance();
ret_node->set_return_type(minfo.return_val.type);
ret_node->set_enable_return_value(true);
ret_node->set_name(name);
- undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id() + 1, ret_node, _get_available_pos(false, ofs + Vector2(500, 0)));
+ int nid = script->get_available_id() + 1;
+ undo_redo->add_do_method(script.ptr(), "add_node", nid, ret_node, _get_available_pos(false, ofs + Vector2(500, 0)));
+ undo_redo->add_undo_method(script.ptr(), "remove_node", nid);
}
undo_redo->add_undo_method(script.ptr(), "remove_function", name);
@@ -3916,21 +3511,16 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, cons
}
void VisualScriptEditor::_cancel_connect_node() {
- // ensure the cancel is done
+ // Ensure the cancel is done.
port_action_new_node = -1;
}
-int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const Vector2 &p_point, const StringName &p_func) {
- StringName func = default_func;
- if (p_func != StringName()) {
- func = p_func;
- }
-
+int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const Vector2 &p_point) {
Ref<VisualScriptNode> vnode = VisualScriptLanguage::singleton->create_node_from_name(p_text);
int new_id = script->get_available_id();
undo_redo->create_action(TTR("Add Node"));
- undo_redo->add_do_method(script.ptr(), "add_node", func, new_id, vnode, p_point);
- undo_redo->add_undo_method(script.ptr(), "remove_node", func, new_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, p_point);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
@@ -3938,7 +3528,7 @@ int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const V
}
void VisualScriptEditor::_default_value_changed() {
- Ref<VisualScriptNode> vsn = script->get_node(_get_function_of_node(editing_id), editing_id);
+ Ref<VisualScriptNode> vsn = script->get_node(editing_id);
if (vsn.is_null()) {
return;
}
@@ -3953,7 +3543,7 @@ void VisualScriptEditor::_default_value_changed() {
}
void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_input_port) {
- Ref<VisualScriptNode> vsn = script->get_node(_get_function_of_node(p_id), p_id);
+ Ref<VisualScriptNode> vsn = script->get_node(p_id);
if (vsn.is_null()) {
return;
}
@@ -3972,15 +3562,15 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
if (pinfo.type == Variant::NODE_PATH) {
Node *edited_scene = get_tree()->get_edited_scene_root();
- if (edited_scene) { // Fixing an old crash bug ( Visual Script Crashes on editing NodePath with an empty scene open)
+ if (edited_scene) { // Fixing an old crash bug ( Visual Script Crashes on editing NodePath with an empty scene open).
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
if (script_node) {
- //pick a node relative to the script, IF the script exists
+ // Pick a node relative to the script, IF the script exists.
pinfo.hint = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE;
pinfo.hint_string = script_node->get_path();
} else {
- //pick a path relative to edited scene
+ // Pick a path relative to edited scene.
pinfo.hint = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE;
pinfo.hint_string = get_tree()->get_edited_scene_root()->get_path();
}
@@ -4078,11 +3668,8 @@ void VisualScriptEditor::_graph_ofs_changed(const Vector2 &p_ofs) {
updating_graph = true;
- // Just use the default func for all the properties that need to be handled for drawing rather than adding to the Visual Script Class
- if (script->has_function(default_func)) {
- script->set_function_scroll(default_func, graph->get_scroll_ofs() / EDSCALE);
- script->set_edited(true);
- }
+ script->set_scroll(graph->get_scroll_ofs() / EDSCALE);
+ script->set_edited(true);
updating_graph = false;
}
@@ -4090,10 +3677,7 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_
if (updating_graph) {
return;
}
-
- StringName func = _get_function_of_node(p_node);
-
- Ref<VisualScriptComment> vsc = script->get_node(func, p_node);
+ Ref<VisualScriptComment> vsc = script->get_node(p_node);
if (vsc.is_null()) {
return;
}
@@ -4104,16 +3688,23 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_
return;
}
+ Vector2 new_size = p_new_size;
+ if (graph->is_using_snap()) {
+ Vector2 snap = Vector2(graph->get_snap(), graph->get_snap());
+ Vector2 min_size = (gn->get_minimum_size() + (snap * 0.5)).snapped(snap);
+ new_size = new_size.snapped(snap).max(min_size);
+ }
+
updating_graph = true;
graph->set_block_minimum_size_adjust(true); //faster resize
undo_redo->create_action(TTR("Resize Comment"), UndoRedo::MERGE_ENDS);
- undo_redo->add_do_method(vsc.ptr(), "set_size", p_new_size / EDSCALE);
+ undo_redo->add_do_method(vsc.ptr(), "set_size", new_size / EDSCALE);
undo_redo->add_undo_method(vsc.ptr(), "set_size", vsc->get_size());
undo_redo->commit_action();
- gn->set_custom_minimum_size(p_new_size);
+ gn->set_custom_minimum_size(new_size);
gn->set_size(Size2(1, 1));
graph->set_block_minimum_size_adjust(false);
updating_graph = false;
@@ -4131,8 +3722,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
if (gn) {
if (gn->is_selected()) {
int id = String(gn->get_name()).to_int();
- StringName func = _get_function_of_node(id);
- Ref<VisualScriptNode> vsn = script->get_node(func, id);
+ Ref<VisualScriptNode> vsn = script->get_node(id);
if (vsn.is_valid()) {
vsn->set_breakpoint(!vsn->is_breakpoint());
reselect.push_back(gn->get_name());
@@ -4154,58 +3744,47 @@ void VisualScriptEditor::_menu_option(int p_what) {
} break;
case EDIT_COPY_NODES:
case EDIT_CUT_NODES: {
- if (!script->has_function(default_func)) {
- break;
- }
-
clipboard->nodes.clear();
clipboard->data_connections.clear();
clipboard->sequence_connections.clear();
- Set<String> funcs;
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn) {
if (gn->is_selected()) {
- int id = String(gn->get_name()).to_int();
- StringName func = _get_function_of_node(id);
- Ref<VisualScriptNode> node = script->get_node(func, id);
+ int id = gn->get_name().operator String().to_int();
+ Ref<VisualScriptNode> node = script->get_node(id);
if (Object::cast_to<VisualScriptFunction>(*node)) {
EditorNode::get_singleton()->show_warning(TTR("Can't copy the function node."));
return;
}
if (node.is_valid()) {
clipboard->nodes[id] = node->duplicate(true);
- clipboard->nodes_positions[id] = script->get_node_position(func, id);
- funcs.insert(String(func));
+ clipboard->nodes_positions[id] = script->get_node_position(id);
}
}
}
}
- if (clipboard->nodes.empty()) {
+ if (clipboard->nodes.is_empty()) {
break;
}
- for (Set<String>::Element *F = funcs.front(); F; F = F->next()) {
- List<VisualScript::SequenceConnection> sequence_connections;
-
- script->get_sequence_connection_list(F->get(), &sequence_connections);
+ List<VisualScript::SequenceConnection> sequence_connections;
+ script->get_sequence_connection_list(&sequence_connections);
- for (List<VisualScript::SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) {
- if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) {
- clipboard->sequence_connections.insert(E->get());
- }
+ for (List<VisualScript::SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) {
+ if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) {
+ clipboard->sequence_connections.insert(E->get());
}
+ }
- List<VisualScript::DataConnection> data_connections;
-
- script->get_data_connection_list(F->get(), &data_connections);
+ List<VisualScript::DataConnection> data_connections;
+ script->get_data_connection_list(&data_connections);
- for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
- if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) {
- clipboard->data_connections.insert(E->get());
- }
+ for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
+ if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) {
+ clipboard->data_connections.insert(E->get());
}
}
if (p_what == EDIT_CUT_NODES) {
@@ -4214,11 +3793,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
} break;
case EDIT_PASTE_NODES: {
- if (!script->has_function(default_func)) {
- break;
- }
-
- if (clipboard->nodes.empty()) {
+ if (clipboard->nodes.is_empty()) {
EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty!"));
break;
}
@@ -4233,15 +3808,11 @@ void VisualScriptEditor::_menu_option(int p_what) {
Set<Vector2> existing_positions;
{
- List<StringName> functions;
- script->get_function_list(&functions);
- for (List<StringName>::Element *F = functions.front(); F; F = F->next()) {
- List<int> nodes;
- script->get_node_list(F->get(), &nodes);
- for (List<int>::Element *E = nodes.front(); E; E = E->next()) {
- Vector2 pos = script->get_node_position(F->get(), E->get()).snapped(Vector2(2, 2));
- existing_positions.insert(pos);
- }
+ List<int> nodes;
+ script->get_node_list(&nodes);
+ for (List<int>::Element *E = nodes.front(); E; E = E->next()) {
+ Vector2 pos = script->get_node_position(E->get()).snapped(Vector2(2, 2));
+ existing_positions.insert(pos);
}
}
@@ -4259,18 +3830,18 @@ void VisualScriptEditor::_menu_option(int p_what) {
paste_pos += Vector2(20, 20) * EDSCALE;
}
- undo_redo->add_do_method(script.ptr(), "add_node", default_func, new_id, node, paste_pos);
- undo_redo->add_undo_method(script.ptr(), "remove_node", default_func, new_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", new_id, node, paste_pos);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", new_id);
}
for (Set<VisualScript::SequenceConnection>::Element *E = clipboard->sequence_connections.front(); E; E = E->next()) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", default_func, remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]);
- undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", default_func, remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]);
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]);
+ undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]);
}
for (Set<VisualScript::DataConnection>::Element *E = clipboard->data_connections.front(); E; E = E->next()) {
- undo_redo->add_do_method(script.ptr(), "data_connect", default_func, remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port);
- undo_redo->add_undo_method(script.ptr(), "data_disconnect", default_func, remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port);
+ undo_redo->add_do_method(script.ptr(), "data_connect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port);
+ undo_redo->add_undo_method(script.ptr(), "data_disconnect", remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port);
}
undo_redo->add_do_method(this, "_update_graph");
@@ -4287,7 +3858,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
} break;
case EDIT_CREATE_FUNCTION: {
- StringName function = "";
+ // Create Function.
Map<int, Ref<VisualScriptNode>> nodes;
Set<int> selections;
for (int i = 0; i < graph->get_child_count(); i++) {
@@ -4295,20 +3866,14 @@ void VisualScriptEditor::_menu_option(int p_what) {
if (gn) {
if (gn->is_selected()) {
int id = String(gn->get_name()).to_int();
- StringName func = _get_function_of_node(id);
- Ref<VisualScriptNode> node = script->get_node(func, id);
+ Ref<VisualScriptNode> node = script->get_node(id);
if (Object::cast_to<VisualScriptFunction>(*node)) {
EditorNode::get_singleton()->show_warning(TTR("Can't create function with a function node."));
return;
}
if (node.is_valid()) {
- if (func != function && function != StringName("")) {
- EditorNode::get_singleton()->show_warning(TTR("Can't create function of nodes from nodes of multiple functions."));
- return;
- }
nodes.insert(id, node);
selections.insert(id);
- function = func;
}
}
}
@@ -4327,7 +3892,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
int start_node = -1;
Set<int> end_nodes;
if (nodes.size() == 1) {
- Ref<VisualScriptNode> nd = script->get_node(function, nodes.front()->key());
+ Ref<VisualScriptNode> nd = script->get_node(nodes.front()->key());
if (nd.is_valid() && nd->has_input_sequence_port()) {
start_node = nodes.front()->key();
} else {
@@ -4336,29 +3901,29 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
} else {
List<VisualScript::SequenceConnection> seqs;
- script->get_sequence_connection_list(function, &seqs);
+ script->get_sequence_connection_list(&seqs);
if (seqs.size() == 0) {
- // in case there are no sequence connections
- // select the top most node cause that's probably how
- // the user wants to connect the nodes
+ // In case there are no sequence connections,
+ // select the top most node cause that's probably how,
+ // the user wants to connect the nodes.
int top_nd = -1;
Vector2 top;
for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) {
- Ref<VisualScriptNode> nd = script->get_node(function, E->key());
+ Ref<VisualScriptNode> nd = script->get_node(E->key());
if (nd.is_valid() && nd->has_input_sequence_port()) {
if (top_nd < 0) {
top_nd = E->key();
- top = script->get_node_position(function, top_nd);
+ top = script->get_node_position(top_nd);
}
- Vector2 pos = script->get_node_position(function, E->key());
+ Vector2 pos = script->get_node_position(E->key());
if (top.y > pos.y) {
top_nd = E->key();
top = pos;
}
}
}
- Ref<VisualScriptNode> nd = script->get_node(function, top_nd);
+ Ref<VisualScriptNode> nd = script->get_node(top_nd);
if (nd.is_valid() && nd->has_input_sequence_port()) {
start_node = top_nd;
} else {
@@ -4366,7 +3931,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
return;
}
} else {
- // pick the node with input sequence
+ // Pick the node with input sequence.
Set<int> nodes_from;
Set<int> nodes_to;
for (List<VisualScript::SequenceConnection>::Element *E = seqs.front(); E; E = E->next()) {
@@ -4387,13 +3952,13 @@ void VisualScriptEditor::_menu_option(int p_what) {
nodes_to.insert(E->get().to_node);
}
- // to use to add return nodes
+ // To use to add return nodes.
_get_ends(start_node, seqs, selections, end_nodes);
if (start_node == -1) {
- // if we still don't have a start node then
- // run through the nodes and select the first tree node
- // ie node without any input sequence but output sequence
+ // If we still don't have a start node then,
+ // run through the nodes and select the first tree node,
+ // ie node without any input sequence but output sequence.
for (Set<int>::Element *E = nodes_from.front(); E; E = E->next()) {
if (!nodes_to.has(E->get())) {
start_node = E->get();
@@ -4404,20 +3969,20 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
if (start_node == -1) {
- return; // this should not happen, but just in case something goes wrong
+ return; // This should not happen, but just in case something goes wrong.
}
List<Variant::Type> inputs; // input types
List<Pair<int, int>> input_connections;
{
List<VisualScript::DataConnection> dats;
- script->get_data_connection_list(function, &dats);
+ script->get_data_connection_list(&dats);
for (List<VisualScript::DataConnection>::Element *E = dats.front(); E; E = E->next()) {
if (nodes.has(E->get().from_node) && nodes.has(E->get().to_node)) {
datamove.insert(E->get());
} else if (!nodes.has(E->get().from_node) && nodes.has(E->get().to_node)) {
- // add all these as inputs for the Function
- Ref<VisualScriptNode> node = script->get_node(function, E->get().to_node);
+ // Add all these as inputs for the Function.
+ Ref<VisualScriptNode> node = script->get_node(E->get().to_node);
if (node.is_valid()) {
dataext.insert(E->get());
PropertyInfo pi = node->get_input_value_port_info(E->get().to_port);
@@ -4429,59 +3994,55 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
}
}
-
- String new_fn = _validate_name("new_function");
-
- Vector2 ofs = _get_available_pos(false, script->get_node_position(function, start_node) - Vector2(80, 150));
-
- Ref<VisualScriptFunction> func_node;
- func_node.instance();
- func_node->set_name(new_fn);
-
- undo_redo->create_action(TTR("Create Function"));
-
- undo_redo->add_do_method(script.ptr(), "add_function", new_fn);
int fn_id = script->get_available_id();
- undo_redo->add_do_method(script.ptr(), "add_node", new_fn, fn_id, func_node, ofs);
- undo_redo->add_undo_method(script.ptr(), "remove_function", new_fn);
- undo_redo->add_do_method(this, "_update_members");
- undo_redo->add_undo_method(this, "_update_members");
- undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
- undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
-
- // Move the nodes
+ {
+ String new_fn = _validate_name("new_function");
- for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) {
- undo_redo->add_do_method(script.ptr(), "remove_node", function, E->key());
- undo_redo->add_do_method(script.ptr(), "add_node", new_fn, E->key(), E->get(), script->get_node_position(function, E->key()));
+ Vector2 ofs = _get_available_pos(false, script->get_node_position(start_node) - Vector2(80, 150));
- // undo_redo->add_undo_method(script.ptr(), "remove_node", new_fn, E->key()); not needed cause we already remove the function :P
- undo_redo->add_undo_method(script.ptr(), "add_node", function, E->key(), E->get(), script->get_node_position(function, E->key()));
- }
+ Ref<VisualScriptFunction> func_node;
+ func_node.instance();
+ func_node->set_name(new_fn);
- for (Set<VisualScript::SequenceConnection>::Element *E = seqmove.front(); E; E = E->next()) {
- undo_redo->add_do_method(script.ptr(), "sequence_connect", new_fn, E->get().from_node, E->get().from_output, E->get().to_node);
- undo_redo->add_undo_method(script.ptr(), "sequence_connect", function, E->get().from_node, E->get().from_output, E->get().to_node);
- }
+ undo_redo->create_action(TTR("Create Function"));
- for (Set<VisualScript::DataConnection>::Element *E = datamove.front(); E; E = E->next()) {
- undo_redo->add_do_method(script.ptr(), "data_connect", new_fn, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
- undo_redo->add_undo_method(script.ptr(), "data_connect", function, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_do_method(script.ptr(), "add_function", new_fn, fn_id);
+ undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, ofs);
+ undo_redo->add_undo_method(script.ptr(), "remove_function", new_fn);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", fn_id);
+ undo_redo->add_do_method(this, "_update_members");
+ undo_redo->add_undo_method(this, "_update_members");
+ undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
+ undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
+ // Might make the system more intelligent by checking port from info.
+ int i = 0;
+ List<Pair<int, int>>::Element *F = input_connections.front();
+ for (List<Variant::Type>::Element *E = inputs.front(); E && F; E = E->next(), F = F->next()) {
+ func_node->add_argument(E->get(), "arg_" + String::num_int64(i), i);
+ undo_redo->add_do_method(script.ptr(), "data_connect", fn_id, i, F->get().first, F->get().second);
+ i++; // increment i
+ }
+ // Ensure Preview Selection is of newly created function node.
+ if (selections.size()) {
+ EditorNode::get_singleton()->push_item(func_node.ptr());
+ }
}
+ // Move the nodes.
- // Add undo for external connections as well so that it's easier to revert back and forth
- // these didn't require do methods as it's already handled internally by other do calls
+ // Handles reconnection of sequence connections on undo, start here in case of issues.
for (Set<VisualScript::SequenceConnection>::Element *E = seqext.front(); E; E = E->next()) {
- undo_redo->add_undo_method(script.ptr(), "sequence_connect", function, E->get().from_node, E->get().from_output, E->get().to_node);
+ undo_redo->add_do_method(script.ptr(), "sequence_disconnect", E->get().from_node, E->get().from_output, E->get().to_node);
+ undo_redo->add_undo_method(script.ptr(), "sequence_connect", E->get().from_node, E->get().from_output, E->get().to_node);
}
for (Set<VisualScript::DataConnection>::Element *E = dataext.front(); E; E = E->next()) {
- undo_redo->add_undo_method(script.ptr(), "data_connect", function, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_do_method(script.ptr(), "data_disconnect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(script.ptr(), "data_connect", E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
}
- // I don't really think we need support for non sequenced functions at this moment
- undo_redo->add_do_method(script.ptr(), "sequence_connect", new_fn, fn_id, 0, start_node);
+ // I don't really think we need support for non sequenced functions at this moment.
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", fn_id, 0, start_node);
- // end nodes are mapped to the return nodes with data connections if possible
+ // Could fail with the new changes, start here when searching for bugs in create function shortcut.
int m = 1;
for (Set<int>::Element *G = end_nodes.front(); G; G = G->next()) {
Ref<VisualScriptReturn> ret_node;
@@ -4489,36 +4050,27 @@ void VisualScriptEditor::_menu_option(int p_what) {
int ret_id = fn_id + (m++);
selections.insert(ret_id);
- Vector2 ofsi = _get_available_pos(false, script->get_node_position(function, G->get()) + Vector2(80, -100));
- undo_redo->add_do_method(script.ptr(), "add_node", new_fn, ret_id, ret_node, ofsi);
- undo_redo->add_undo_method(script.ptr(), "remove_node", new_fn, ret_id);
+ Vector2 ofsi = _get_available_pos(false, script->get_node_position(G->get()) + Vector2(80, -100));
+ undo_redo->add_do_method(script.ptr(), "add_node", ret_id, ret_node, ofsi);
+ undo_redo->add_undo_method(script.ptr(), "remove_node", ret_id);
- undo_redo->add_do_method(script.ptr(), "sequence_connect", new_fn, G->get(), 0, ret_id);
- // add data outputs from each of the end_nodes
- Ref<VisualScriptNode> vsn = script->get_node(function, G->get());
+ undo_redo->add_do_method(script.ptr(), "sequence_connect", G->get(), 0, ret_id);
+ // Add data outputs from each of the end_nodes.
+ Ref<VisualScriptNode> vsn = script->get_node(G->get());
if (vsn.is_valid() && vsn->get_output_value_port_count() > 0) {
ret_node->set_enable_return_value(true);
- // use the zeroth data port cause that's the likely one that is planned to be used
+ // Use the zeroth data port cause that's the likely one that is planned to be used.
ret_node->set_return_type(vsn->get_output_value_port_info(0).type);
- undo_redo->add_do_method(script.ptr(), "data_connect", new_fn, G->get(), 0, ret_id, 0);
+ undo_redo->add_do_method(script.ptr(), "data_connect", G->get(), 0, ret_id, 0);
}
}
- // * might make the system more intelligent by checking port from info.
- int i = 0;
- List<Pair<int, int>>::Element *F = input_connections.front();
- for (List<Variant::Type>::Element *E = inputs.front(); E && F; E = E->next(), F = F->next()) {
- func_node->add_argument(E->get(), "arg_" + String::num_int64(i), i);
- undo_redo->add_do_method(script.ptr(), "data_connect", new_fn, fn_id, i, F->get().first, F->get().second);
- i++; // increment i
- }
-
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
- // make sure all Nodes get marked for selection so that they can be moved together
+ // Make sure all Nodes get marked for selection so that they can be moved together.
selections.insert(fn_id);
for (int k = 0; k < graph->get_child_count(); k++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(k));
@@ -4528,11 +4080,6 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
}
- // Ensure Preview Selection is of newly created function node
- if (selections.size()) {
- EditorNode::get_singleton()->push_item(func_node.ptr());
- }
-
} break;
case REFRESH_GRAPH: {
_update_graph();
@@ -4540,16 +4087,16 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
}
-// this is likely going to be very slow and I am not sure if I should keep it
-// but I hope that it will not be a problem considering that we won't be creating functions so frequently
-// and cyclic connections would be a problem but hopefully we won't let them get to this point
+// This is likely going to be very slow and I am not sure if I should keep it,
+// but I hope that it will not be a problem considering that we won't be creating functions so frequently,
+// and cyclic connections would be a problem but hopefully we won't let them get to this point.
void VisualScriptEditor::_get_ends(int p_node, const List<VisualScript::SequenceConnection> &p_seqs, const Set<int> &p_selected, Set<int> &r_end_nodes) {
for (const List<VisualScript::SequenceConnection>::Element *E = p_seqs.front(); E; E = E->next()) {
int from = E->get().from_node;
int to = E->get().to_node;
if (from == p_node && p_selected.has(to)) {
- // this is an interior connection move forward to the to node
+ // This is an interior connection move forward to the to node.
_get_ends(to, p_seqs, p_selected, r_end_nodes);
} else if (from == p_node && !p_selected.has(to)) {
r_end_nodes.insert(from);
@@ -4609,34 +4156,29 @@ void VisualScriptEditor::_member_option(int p_option) {
switch (member_type) {
case MEMBER_FUNCTION: {
if (p_option == MEMBER_REMOVE) {
- //delete the function
+ // Delete the function.
String name = member_name;
-
+ List<String> lst;
+ int fn_node = script->get_function_node_id(name);
undo_redo->create_action(TTR("Remove Function"));
undo_redo->add_do_method(script.ptr(), "remove_function", name);
- undo_redo->add_undo_method(script.ptr(), "add_function", name);
- List<int> nodes;
- script->get_node_list(name, &nodes);
- for (List<int>::Element *E = nodes.front(); E; E = E->next()) {
- undo_redo->add_undo_method(script.ptr(), "add_node", name, E->get(), script->get_node(name, E->get()), script->get_node_position(name, E->get()));
- }
-
- List<VisualScript::SequenceConnection> seq_connections;
-
- script->get_sequence_connection_list(name, &seq_connections);
-
- for (List<VisualScript::SequenceConnection>::Element *E = seq_connections.front(); E; E = E->next()) {
- undo_redo->add_undo_method(script.ptr(), "sequence_connect", name, E->get().from_node, E->get().from_output, E->get().to_node);
+ undo_redo->add_do_method(script.ptr(), "remove_node", fn_node);
+ undo_redo->add_undo_method(script.ptr(), "add_function", name, fn_node);
+ undo_redo->add_undo_method(script.ptr(), "add_node", fn_node, script->get_node(fn_node), script->get_node_position(fn_node));
+ List<VisualScript::SequenceConnection> seqcons;
+ script->get_sequence_connection_list(&seqcons);
+ for (const List<VisualScript::SequenceConnection>::Element *E = seqcons.front(); E; E = E->next()) {
+ if (E->get().from_node == fn_node) {
+ undo_redo->add_undo_method(script.ptr(), "sequence_connect", fn_node, E->get().from_output, E->get().to_node);
+ }
}
-
- List<VisualScript::DataConnection> data_connections;
-
- script->get_data_connection_list(name, &data_connections);
-
- for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
- undo_redo->add_undo_method(script.ptr(), "data_connect", name, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ List<VisualScript::DataConnection> datcons;
+ script->get_data_connection_list(&datcons);
+ for (const List<VisualScript::DataConnection>::Element *E = datcons.front(); E; E = E->next()) {
+ if (E->get().from_node == fn_node) {
+ undo_redo->add_undo_method(script.ptr(), "data_connect", fn_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ }
}
-
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
undo_redo->add_do_method(this, "_update_graph");
@@ -4732,13 +4274,13 @@ VisualScriptEditor::VisualScriptEditor() {
edit_menu->set_shortcut_context(this);
edit_menu->set_text(TTR("Edit"));
edit_menu->set_switch_on_hover(true);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/delete_selected"), EDIT_DELETE_NODES);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_graph_delete"), EDIT_DELETE_NODES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/toggle_breakpoint"), EDIT_TOGGLE_BREAKPOINT);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/find_node_type"), EDIT_FIND_NODE_TYPE);
edit_menu->get_popup()->add_separator();
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/copy_nodes"), EDIT_COPY_NODES);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/cut_nodes"), EDIT_CUT_NODES);
- edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/paste_nodes"), EDIT_PASTE_NODES);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY_NODES);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT_NODES);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE_NODES);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/create_function"), EDIT_CREATE_FUNCTION);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/refresh_nodes"), REFRESH_GRAPH);
@@ -4794,6 +4336,8 @@ VisualScriptEditor::VisualScriptEditor() {
graph->connect("duplicate_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_duplicate));
graph->connect("gui_input", callable_mp(this, &VisualScriptEditor::_graph_gui_input));
graph->set_drag_forwarding(this);
+ float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity");
+ graph->set_minimap_opacity(graph_minimap_opacity);
graph->hide();
graph->connect("scroll_offset_changed", callable_mp(this, &VisualScriptEditor::_graph_ofs_changed));
@@ -4976,12 +4520,8 @@ void VisualScriptEditor::free_clipboard() {
static void register_editor_callback() {
ScriptEditor::register_create_script_editor_function(create_editor);
- ED_SHORTCUT("visual_script_editor/delete_selected", TTR("Delete Selected"), KEY_DELETE);
ED_SHORTCUT("visual_script_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Type"), KEY_MASK_CMD + KEY_F);
- ED_SHORTCUT("visual_script_editor/copy_nodes", TTR("Copy Nodes"), KEY_MASK_CMD + KEY_C);
- ED_SHORTCUT("visual_script_editor/cut_nodes", TTR("Cut Nodes"), KEY_MASK_CMD + KEY_X);
- ED_SHORTCUT("visual_script_editor/paste_nodes", TTR("Paste Nodes"), KEY_MASK_CMD + KEY_V);
ED_SHORTCUT("visual_script_editor/create_function", TTR("Make Function"), KEY_MASK_CMD + KEY_G);
ED_SHORTCUT("visual_script_editor/refresh_nodes", TTR("Refresh Graph"), KEY_MASK_CMD + KEY_R);
ED_SHORTCUT("visual_script_editor/edit_member", TTR("Edit Member"), KEY_MASK_CMD + KEY_E);
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 5610e6b1b4..bb6f194286 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -136,8 +136,6 @@ class VisualScriptEditor : public ScriptEditorBase {
};
HashMap<StringName, Ref<StyleBox>> node_styles;
- StringName edited_func;
- StringName default_func;
void _update_graph_connections();
void _update_graph(int p_only_id = -1);
@@ -176,7 +174,7 @@ class VisualScriptEditor : public ScriptEditorBase {
Vector2 mouse_up_position;
- void _port_action_menu(int p_option, const StringName &p_func);
+ void _port_action_menu(int p_option);
void connect_data(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode, int new_id);
@@ -184,13 +182,13 @@ class VisualScriptEditor : public ScriptEditorBase {
void connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id);
void _cancel_connect_node();
- int _create_new_node_from_name(const String &p_text, const Vector2 &p_point, const StringName &p_func = StringName());
+ int _create_new_node_from_name(const String &p_text, const Vector2 &p_point);
void _selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting);
int error_line;
void _node_selected(Node *p_node);
- void _center_on_node(const StringName &p_func, int p_id);
+ void _center_on_node(int p_id);
void _node_filter_changed(const String &p_text);
void _change_base_type_callback();
@@ -201,7 +199,7 @@ class VisualScriptEditor : public ScriptEditorBase {
void _begin_node_move();
void _end_node_move();
- void _move_node(const StringName &p_func, int p_id, const Vector2 &p_to);
+ void _move_node(int p_id, const Vector2 &p_to);
void _get_ends(int p_node, const List<VisualScript::SequenceConnection> &p_seqs, const Set<int> &p_selected, Set<int> &r_end_nodes);
@@ -211,7 +209,7 @@ class VisualScriptEditor : public ScriptEditorBase {
void _graph_disconnected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot);
void _graph_connect_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_pos);
- void _node_ports_changed(const String &p_func, int p_id);
+ void _node_ports_changed(int p_id);
void _node_create();
void _update_available_nodes();
@@ -228,10 +226,8 @@ class VisualScriptEditor : public ScriptEditorBase {
void _port_name_focus_out(const Node *p_name_box, int p_id, int p_port, bool is_input);
Vector2 _get_available_pos(bool centered = true, Vector2 ofs = Vector2()) const;
- StringName _get_function_of_node(int p_id) const;
- void _move_nodes_with_rescan(const StringName &p_func_from, const StringName &p_func_to, int p_id);
- bool node_has_sequence_connections(const StringName &p_func, int p_id);
+ bool node_has_sequence_connections(int p_id);
void _generic_search(String p_base_type = "", Vector2 pos = Vector2(), bool node_centered = false);
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index 10a18dfd5e..f673cbb06d 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,7 +63,7 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val
}
expression_dirty = true;
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
return true;
}
@@ -1506,13 +1506,20 @@ VisualScriptNodeInstance *VisualScriptExpression::instance(VisualScriptInstance
return instance;
}
+void VisualScriptExpression::reset_state() {
+ if (nodes) {
+ memdelete(nodes);
+ nodes = nullptr;
+ root = nullptr;
+ }
+
+ error_str = String();
+ error_set = false;
+ str_ofs = 0;
+ inputs.clear();
+}
+
VisualScriptExpression::VisualScriptExpression() {
- output_type = Variant::NIL;
- expression_dirty = true;
- error_set = true;
- root = nullptr;
- nodes = nullptr;
- sequenced = false;
}
VisualScriptExpression::~VisualScriptExpression() {
diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h
index 2b3b25842d..c35075ea53 100644
--- a/modules/visual_script/visual_script_expression.h
+++ b/modules/visual_script/visual_script_expression.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,20 +39,18 @@ class VisualScriptExpression : public VisualScriptNode {
friend class VisualScriptNodeInstanceExpression;
struct Input {
- Variant::Type type;
+ Variant::Type type = Variant::NIL;
String name;
-
- Input() { type = Variant::NIL; }
};
Vector<Input> inputs;
- Variant::Type output_type;
+ Variant::Type output_type = Variant::NIL;
String expression;
- bool sequenced;
- int str_ofs;
- bool expression_dirty;
+ bool sequenced = false;
+ int str_ofs = 0;
+ bool expression_dirty = true;
bool _compile_expression();
@@ -114,7 +112,7 @@ class VisualScriptExpression : public VisualScriptNode {
Error _get_token(Token &r_token);
String error_str;
- bool error_set;
+ bool error_set = true;
struct ENode {
enum Type {
@@ -131,11 +129,10 @@ class VisualScriptExpression : public VisualScriptNode {
TYPE_CALL
};
- ENode *next;
+ ENode *next = nullptr;
- Type type;
+ Type type = Type::TYPE_SELF;
- ENode() { next = nullptr; }
virtual ~ENode() {
if (next) {
memdelete(next);
@@ -144,17 +141,17 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct Expression {
- bool is_op;
+ bool is_op = false;
union {
Variant::Operator op;
- ENode *node;
+ ENode *node = nullptr;
};
};
ENode *_parse_expression();
struct InputNode : public ENode {
- int index;
+ int index = 0;
InputNode() {
type = TYPE_INPUT;
}
@@ -168,9 +165,9 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct OperatorNode : public ENode {
- Variant::Operator op;
+ Variant::Operator op = Variant::Operator::OP_ADD;
- ENode *nodes[2];
+ ENode *nodes[2] = { nullptr, nullptr };
OperatorNode() {
type = TYPE_OPERATOR;
@@ -184,8 +181,8 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct IndexNode : public ENode {
- ENode *base;
- ENode *index;
+ ENode *base = nullptr;
+ ENode *index = nullptr;
IndexNode() {
type = TYPE_INDEX;
@@ -193,7 +190,7 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct NamedIndexNode : public ENode {
- ENode *base;
+ ENode *base = nullptr;
StringName name;
NamedIndexNode() {
@@ -202,7 +199,7 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct ConstructorNode : public ENode {
- Variant::Type data_type;
+ Variant::Type data_type = Variant::Type::NIL;
Vector<ENode *> arguments;
ConstructorNode() {
@@ -211,7 +208,7 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct CallNode : public ENode {
- ENode *base;
+ ENode *base = nullptr;
StringName method;
Vector<ENode *> arguments;
@@ -235,7 +232,7 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct BuiltinFuncNode : public ENode {
- VisualScriptBuiltinFunc::BuiltinFunc func;
+ VisualScriptBuiltinFunc::BuiltinFunc func = VisualScriptBuiltinFunc::BuiltinFunc::BYTES_TO_VAR;
Vector<ENode *> arguments;
BuiltinFuncNode() {
type = TYPE_BUILTIN_FUNC;
@@ -250,8 +247,8 @@ class VisualScriptExpression : public VisualScriptNode {
return node;
}
- ENode *root;
- ENode *nodes;
+ ENode *root = nullptr;
+ ENode *nodes = nullptr;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
@@ -259,6 +256,8 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
public:
+ virtual void reset_state() override;
+
virtual int get_output_sequence_port_count() const override;
virtual bool has_input_sequence_port() const override;
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index 36c756fc58..e2a8323509 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -628,7 +628,7 @@ VisualScriptNodeInstance *VisualScriptSwitch::instance(VisualScriptInstance *p_i
bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) {
if (String(p_name) == "case_count") {
case_values.resize(p_value);
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
return true;
}
@@ -638,7 +638,7 @@ bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value)
ERR_FAIL_INDEX_V(idx, case_values.size(), false);
case_values.write[idx].type = Variant::Type(int(p_value));
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
return true;
@@ -677,6 +677,10 @@ void VisualScriptSwitch::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
+void VisualScriptSwitch::reset_state() {
+ case_values.clear();
+}
+
void VisualScriptSwitch::_bind_methods() {
}
@@ -733,7 +737,7 @@ void VisualScriptTypeCast::set_base_type(const StringName &p_type) {
}
base_type = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -747,7 +751,7 @@ void VisualScriptTypeCast::set_base_script(const String &p_path) {
}
script = p_path;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
diff --git a/modules/visual_script/visual_script_flow_control.h b/modules/visual_script/visual_script_flow_control.h
index 1d0d6d103b..d9c4dedafd 100644
--- a/modules/visual_script/visual_script_flow_control.h
+++ b/modules/visual_script/visual_script_flow_control.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -202,6 +202,8 @@ protected:
static void _bind_methods();
public:
+ virtual void reset_state() override;
+
virtual int get_output_sequence_port_count() const override;
virtual bool has_input_sequence_port() const override;
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index b2aa42ef97..b5aacb0506 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -281,7 +281,7 @@ void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) {
}
basic_type = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -295,7 +295,7 @@ void VisualScriptFunctionCall::set_base_type(const StringName &p_type) {
}
base_type = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -309,7 +309,7 @@ void VisualScriptFunctionCall::set_base_script(const String &p_path) {
}
base_script = p_path;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -328,7 +328,7 @@ void VisualScriptFunctionCall::set_singleton(const StringName &p_type) {
base_type = obj->get_class();
}
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -425,7 +425,7 @@ void VisualScriptFunctionCall::set_function(const StringName &p_type) {
_update_method_cache();
}
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -439,7 +439,7 @@ void VisualScriptFunctionCall::set_base_path(const NodePath &p_type) {
}
base_path = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -453,7 +453,7 @@ void VisualScriptFunctionCall::set_call_mode(CallMode p_mode) {
}
call_mode = p_mode;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -476,7 +476,7 @@ void VisualScriptFunctionCall::set_rpc_call_mode(VisualScriptFunctionCall::RPCCa
}
rpc_call_mode = p_mode;
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
VisualScriptFunctionCall::RPCCallMode VisualScriptFunctionCall::get_rpc_call_mode() const {
@@ -1067,7 +1067,7 @@ void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) {
}
basic_type = p_type;
- _change_notify();
+ notify_property_list_changed();
_update_base_type();
ports_changed_notify();
}
@@ -1082,7 +1082,7 @@ void VisualScriptPropertySet::set_base_type(const StringName &p_type) {
}
base_type = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1096,7 +1096,7 @@ void VisualScriptPropertySet::set_base_script(const String &p_path) {
}
base_script = p_path;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1191,7 +1191,7 @@ void VisualScriptPropertySet::set_property(const StringName &p_type) {
property = p_type;
index = StringName();
_update_cache();
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1206,7 +1206,7 @@ void VisualScriptPropertySet::set_base_path(const NodePath &p_type) {
base_path = p_type;
_update_base_type();
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1221,7 +1221,7 @@ void VisualScriptPropertySet::set_call_mode(CallMode p_mode) {
call_mode = p_mode;
_update_base_type();
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1243,7 +1243,7 @@ void VisualScriptPropertySet::set_index(const StringName &p_type) {
}
index = p_type;
_update_cache();
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1259,7 +1259,7 @@ void VisualScriptPropertySet::set_assign_op(AssignOp p_op) {
assign_op = p_op;
_update_cache();
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1760,7 +1760,7 @@ void VisualScriptPropertyGet::set_base_type(const StringName &p_type) {
}
base_type = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1774,7 +1774,7 @@ void VisualScriptPropertyGet::set_base_script(const String &p_path) {
}
base_script = p_path;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1871,7 +1871,7 @@ void VisualScriptPropertyGet::set_property(const StringName &p_type) {
property = p_type;
_update_cache();
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1885,7 +1885,7 @@ void VisualScriptPropertyGet::set_base_path(const NodePath &p_type) {
}
base_path = p_type;
- _change_notify();
+ notify_property_list_changed();
_update_base_type();
ports_changed_notify();
}
@@ -1900,7 +1900,7 @@ void VisualScriptPropertyGet::set_call_mode(CallMode p_mode) {
}
call_mode = p_mode;
- _change_notify();
+ notify_property_list_changed();
_update_base_type();
ports_changed_notify();
}
@@ -1915,7 +1915,7 @@ void VisualScriptPropertyGet::set_basic_type(Variant::Type p_type) {
}
basic_type = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1937,7 +1937,7 @@ void VisualScriptPropertyGet::set_index(const StringName &p_type) {
}
index = p_type;
_update_cache();
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -2261,7 +2261,7 @@ void VisualScriptEmitSignal::set_signal(const StringName &p_type) {
name = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
diff --git a/modules/visual_script/visual_script_func_nodes.h b/modules/visual_script/visual_script_func_nodes.h
index 8372df561f..2ff9b7a981 100644
--- a/modules/visual_script/visual_script_func_nodes.h
+++ b/modules/visual_script/visual_script_func_nodes.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index edec270adc..fed6637acb 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,7 +57,7 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value
arguments.write[i].type = Variant::NIL;
}
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
return true;
}
if (String(p_name).begins_with("argument_")) {
@@ -303,6 +303,14 @@ VisualScriptNodeInstance *VisualScriptFunction::instance(VisualScriptInstance *p
return instance;
}
+void VisualScriptFunction::reset_state() {
+ arguments.clear();
+ stack_size = 256;
+ stack_less = false;
+ sequenced = true;
+ rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
VisualScriptFunction::VisualScriptFunction() {
stack_size = 256;
stack_less = false;
@@ -312,7 +320,7 @@ VisualScriptFunction::VisualScriptFunction() {
void VisualScriptFunction::set_stack_less(bool p_enable) {
stack_less = p_enable;
- _change_notify();
+ notify_property_list_changed();
}
bool VisualScriptFunction::is_stack_less() const {
@@ -421,7 +429,7 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
inputports.write[i].type = Variant::NIL;
}
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
return true;
}
if (String(p_name).begins_with("input_") && is_input_port_editable()) {
@@ -457,7 +465,7 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
outputports.write[i].type = Variant::NIL;
}
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
return true;
}
if (String(p_name).begins_with("output_") && is_output_port_editable()) {
@@ -578,7 +586,7 @@ void VisualScriptLists::add_input_data_port(Variant::Type p_type, const String &
}
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) {
@@ -590,7 +598,7 @@ void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type
inputports.write[p_idx].type = p_type;
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) {
@@ -602,7 +610,7 @@ void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name
inputports.write[p_idx].name = p_name;
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
void VisualScriptLists::remove_input_data_port(int p_argidx) {
@@ -615,7 +623,7 @@ void VisualScriptLists::remove_input_data_port(int p_argidx) {
inputports.remove(p_argidx);
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
// output data port interaction
@@ -634,7 +642,7 @@ void VisualScriptLists::add_output_data_port(Variant::Type p_type, const String
}
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) {
@@ -646,7 +654,7 @@ void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_typ
outputports.write[p_idx].type = p_type;
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) {
@@ -658,7 +666,7 @@ void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_nam
outputports.write[p_idx].name = p_name;
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
void VisualScriptLists::remove_output_data_port(int p_argidx) {
@@ -671,7 +679,7 @@ void VisualScriptLists::remove_output_data_port(int p_argidx) {
outputports.remove(p_argidx);
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
// sequences
@@ -687,6 +695,13 @@ bool VisualScriptLists::is_sequenced() const {
return sequenced;
}
+void VisualScriptLists::reset_state() {
+ inputports.clear();
+ outputports.clear();
+ sequenced = false;
+ flags = 0;
+}
+
VisualScriptLists::VisualScriptLists() {
// initialize
sequenced = false;
@@ -1433,7 +1448,7 @@ void VisualScriptConstant::set_constant_type(Variant::Type p_type) {
Callable::CallError ce;
Variant::construct(type, value, nullptr, 0, ce);
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
Variant::Type VisualScriptConstant::get_constant_type() const {
@@ -1764,7 +1779,7 @@ String VisualScriptGlobalConstant::get_caption() const {
void VisualScriptGlobalConstant::set_global_constant(int p_which) {
index = p_which;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1850,7 +1865,7 @@ String VisualScriptClassConstant::get_caption() const {
void VisualScriptClassConstant::set_class_constant(const StringName &p_which) {
name = p_which;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1876,7 +1891,7 @@ void VisualScriptClassConstant::set_base_type(const StringName &p_which) {
} else {
name = "";
}
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -1983,7 +1998,7 @@ String VisualScriptBasicTypeConstant::get_text() const {
void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) {
name = p_which;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -2010,7 +2025,7 @@ void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) {
} else {
name = "";
}
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -2140,7 +2155,7 @@ String VisualScriptMathConstant::get_caption() const {
void VisualScriptMathConstant::set_math_constant(MathConstant p_which) {
constant = p_which;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -2233,7 +2248,7 @@ String VisualScriptEngineSingleton::get_caption() const {
void VisualScriptEngineSingleton::set_singleton(const String &p_string) {
singleton = p_string;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -2342,7 +2357,7 @@ String VisualScriptSceneNode::get_caption() const {
void VisualScriptSceneNode::set_node_path(const NodePath &p_path) {
path = p_path;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -2620,7 +2635,7 @@ String VisualScriptResourcePath::get_caption() const {
void VisualScriptResourcePath::set_resource_path(const String &p_path) {
path = p_path;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -3748,7 +3763,7 @@ void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) {
type = p_type;
_update_elements();
ports_changed_notify();
- _change_notify(); //to make input appear/disappear
+ notify_property_list_changed(); //to make input appear/disappear
}
Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const {
diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h
index b6061f8838..7392443e4e 100644
--- a/modules/visual_script/visual_script_nodes.h
+++ b/modules/visual_script/visual_script_nodes.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -99,6 +99,8 @@ public:
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance) override;
+ virtual void reset_state() override;
+
VisualScriptFunction();
};
@@ -134,6 +136,8 @@ protected:
static void _bind_methods();
public:
+ virtual void reset_state() override;
+
virtual bool is_output_port_editable() const;
virtual bool is_output_port_name_editable() const;
virtual bool is_output_port_type_editable() const;
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index dbb76e19ac..862cac5c67 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -358,7 +358,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt
continue;
}
- bool in_modifier = p_modifiers.empty();
+ bool in_modifier = p_modifiers.is_empty();
for (Set<String>::Element *F = p_modifiers.front(); F && in_modifier; F = F->next()) {
if (E->get().findn(F->get()) != -1) {
in_modifier = true;
diff --git a/modules/visual_script/visual_script_property_selector.h b/modules/visual_script/visual_script_property_selector.h
index cc49b2863d..7a87f3d3ee 100644
--- a/modules/visual_script/visual_script_property_selector.h
+++ b/modules/visual_script/visual_script_property_selector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index dd07cc45a7..25fabd7b87 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -152,7 +152,7 @@ void VisualScriptYield::set_yield_mode(YieldMode p_mode) {
}
yield_mode = p_mode;
ports_changed_notify();
- _change_notify();
+ notify_property_list_changed();
}
VisualScriptYield::YieldMode VisualScriptYield::get_yield_mode() {
@@ -359,7 +359,7 @@ void VisualScriptYieldSignal::set_base_type(const StringName &p_type) {
base_type = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -374,7 +374,7 @@ void VisualScriptYieldSignal::set_signal(const StringName &p_type) {
signal = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -389,7 +389,7 @@ void VisualScriptYieldSignal::set_base_path(const NodePath &p_type) {
base_path = p_type;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
@@ -404,7 +404,7 @@ void VisualScriptYieldSignal::set_call_mode(CallMode p_mode) {
call_mode = p_mode;
- _change_notify();
+ notify_property_list_changed();
ports_changed_notify();
}
diff --git a/modules/visual_script/visual_script_yield_nodes.h b/modules/visual_script/visual_script_yield_nodes.h
index 7a72211027..cc7ce0a1c6 100644
--- a/modules/visual_script/visual_script_yield_nodes.h
+++ b/modules/visual_script/visual_script_yield_nodes.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/vorbis/register_types.cpp b/modules/vorbis/register_types.cpp
index 8874b3887b..d3e77ea629 100644
--- a/modules/vorbis/register_types.cpp
+++ b/modules/vorbis/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/vorbis/register_types.h b/modules/vorbis/register_types.h
index 7fa0dfdeef..1497e6f5e4 100644
--- a/modules/vorbis/register_types.h
+++ b/modules/vorbis/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webm/register_types.cpp b/modules/webm/register_types.cpp
index 6248787879..82157a71c9 100644
--- a/modules/webm/register_types.cpp
+++ b/modules/webm/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webm/register_types.h b/modules/webm/register_types.h
index 6a02e3a87a..d090fe745b 100644
--- a/modules/webm/register_types.h
+++ b/modules/webm/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index 2128b82e3f..101001cba0 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -156,7 +156,7 @@ void VideoStreamPlaybackWebm::stop() {
void VideoStreamPlaybackWebm::play() {
stop();
- delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms");
+ delay_compensation = ProjectSettings::get_singleton()->get("audio/video/video_delay_compensation_ms");
delay_compensation /= 1000.0;
playing = true;
@@ -429,7 +429,7 @@ void VideoStreamWebm::set_audio_track(int p_track) {
////////////
-RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h
index 25675cb248..60e02ab38b 100644
--- a/modules/webm/video_stream_webm.h
+++ b/modules/webm/video_stream_webm.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -126,7 +126,7 @@ public:
class ResourceFormatLoaderWebm : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index b169687f25..b304c4824f 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,7 +39,7 @@
#include <webp/encode.h>
static Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
- ERR_FAIL_COND_V(p_image.is_null() || p_image->empty(), Vector<uint8_t>());
+ ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>());
Ref<Image> img = p_image->duplicate();
if (img->detect_alpha()) {
diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h
index 49a7407600..9ea3056a19 100644
--- a/modules/webp/image_loader_webp.h
+++ b/modules/webp/image_loader_webp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webp/register_types.cpp b/modules/webp/register_types.cpp
index 0788b06309..ea9af72418 100644
--- a/modules/webp/register_types.cpp
+++ b/modules/webp/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webp/register_types.h b/modules/webp/register_types.h
index d574d7be1d..59d6894bf6 100644
--- a/modules/webp/register_types.h
+++ b/modules/webp/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/library_godot_webrtc.js b/modules/webrtc/library_godot_webrtc.js
index 9f029407d2..404a116716 100644
--- a/modules/webrtc/library_godot_webrtc.js
+++ b/modules/webrtc/library_godot_webrtc.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/register_types.cpp b/modules/webrtc/register_types.cpp
index 0e830f0540..ecfaed9089 100644
--- a/modules/webrtc/register_types.cpp
+++ b/modules/webrtc/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/register_types.h b/modules/webrtc/register_types.h
index 8f5b9e8452..710ee88a28 100644
--- a/modules/webrtc/register_types.h
+++ b/modules/webrtc/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_data_channel.cpp b/modules/webrtc/webrtc_data_channel.cpp
index cd9e77aff8..004112f992 100644
--- a/modules/webrtc/webrtc_data_channel.cpp
+++ b/modules/webrtc/webrtc_data_channel.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_data_channel.h b/modules/webrtc/webrtc_data_channel.h
index 1407f1e3bd..20affc513f 100644
--- a/modules/webrtc/webrtc_data_channel.h
+++ b/modules/webrtc/webrtc_data_channel.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_data_channel_gdnative.cpp b/modules/webrtc/webrtc_data_channel_gdnative.cpp
index 67ad2c07ce..d4cf464c7c 100644
--- a/modules/webrtc/webrtc_data_channel_gdnative.cpp
+++ b/modules/webrtc/webrtc_data_channel_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_data_channel_gdnative.h b/modules/webrtc/webrtc_data_channel_gdnative.h
index 03396d207d..7e02a32046 100644
--- a/modules/webrtc/webrtc_data_channel_gdnative.h
+++ b/modules/webrtc/webrtc_data_channel_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp
index 3a63001a56..dfbec80c86 100644
--- a/modules/webrtc/webrtc_data_channel_js.cpp
+++ b/modules/webrtc/webrtc_data_channel_js.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -182,16 +182,9 @@ bool WebRTCDataChannelJS::is_negotiated() const {
}
WebRTCDataChannelJS::WebRTCDataChannelJS() {
- queue_count = 0;
- _was_string = false;
- _write_mode = WRITE_MODE_BINARY;
- _js_id = 0;
}
WebRTCDataChannelJS::WebRTCDataChannelJS(int js_id) {
- queue_count = 0;
- _was_string = false;
- _write_mode = WRITE_MODE_BINARY;
_js_id = js_id;
godot_js_rtc_datachannel_connect(js_id, this, &_on_open, &_on_message, &_on_error, &_on_close);
diff --git a/modules/webrtc/webrtc_data_channel_js.h b/modules/webrtc/webrtc_data_channel_js.h
index e251760019..db58ebccff 100644
--- a/modules/webrtc/webrtc_data_channel_js.h
+++ b/modules/webrtc/webrtc_data_channel_js.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,16 +42,16 @@ private:
String _label;
String _protocol;
- bool _was_string;
- WriteMode _write_mode;
+ bool _was_string = false;
+ WriteMode _write_mode = WRITE_MODE_BINARY;
enum {
PACKET_BUFFER_SIZE = 65536 - 5 // 4 bytes for the size, 1 for for type
};
- int _js_id;
+ int _js_id = 0;
RingBuffer<uint8_t> in_buffer;
- int queue_count;
+ int queue_count = 0;
uint8_t packet_buffer[PACKET_BUFFER_SIZE];
static void _on_open(void *p_obj);
diff --git a/modules/webrtc/webrtc_multiplayer.cpp b/modules/webrtc/webrtc_multiplayer.cpp
index e0c0cad68c..741cad5640 100644
--- a/modules/webrtc/webrtc_multiplayer.cpp
+++ b/modules/webrtc/webrtc_multiplayer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_multiplayer.h b/modules/webrtc/webrtc_multiplayer.h
index fb37bd7722..6b4ae6fcc8 100644
--- a/modules/webrtc/webrtc_multiplayer.h
+++ b/modules/webrtc/webrtc_multiplayer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_peer_connection.cpp b/modules/webrtc/webrtc_peer_connection.cpp
index 670924bca2..3e2938bf7d 100644
--- a/modules/webrtc/webrtc_peer_connection.cpp
+++ b/modules/webrtc/webrtc_peer_connection.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_peer_connection.h b/modules/webrtc/webrtc_peer_connection.h
index 7366c3d0e8..ae75864489 100644
--- a/modules/webrtc/webrtc_peer_connection.h
+++ b/modules/webrtc/webrtc_peer_connection.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_peer_connection_gdnative.cpp b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
index aaa45d3a54..dcf78dfb73 100644
--- a/modules/webrtc/webrtc_peer_connection_gdnative.cpp
+++ b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_peer_connection_gdnative.h b/modules/webrtc/webrtc_peer_connection_gdnative.h
index 846b65c466..578af0202f 100644
--- a/modules/webrtc/webrtc_peer_connection_gdnative.h
+++ b/modules/webrtc/webrtc_peer_connection_gdnative.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_peer_connection_js.cpp b/modules/webrtc/webrtc_peer_connection_js.cpp
index ad9b46a8af..8879f7d6ec 100644
--- a/modules/webrtc/webrtc_peer_connection_js.cpp
+++ b/modules/webrtc/webrtc_peer_connection_js.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/webrtc/webrtc_peer_connection_js.h b/modules/webrtc/webrtc_peer_connection_js.h
index e33dd5f259..0272e67f6f 100644
--- a/modules/webrtc/webrtc_peer_connection_js.h
+++ b/modules/webrtc/webrtc_peer_connection_js.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/editor_debugger_server_websocket.cpp b/modules/websocket/editor_debugger_server_websocket.cpp
index 8eb975b323..b02d212c42 100644
--- a/modules/websocket/editor_debugger_server_websocket.cpp
+++ b/modules/websocket/editor_debugger_server_websocket.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/editor_debugger_server_websocket.h b/modules/websocket/editor_debugger_server_websocket.h
index 861f389aab..2f73b98c3d 100644
--- a/modules/websocket/editor_debugger_server_websocket.h
+++ b/modules/websocket/editor_debugger_server_websocket.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp
index d6e00a26af..25b6d6ef0e 100644
--- a/modules/websocket/emws_client.cpp
+++ b/modules/websocket/emws_client.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -140,11 +140,7 @@ Error EMWSClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffe
}
EMWSClient::EMWSClient() {
- _in_buf_size = DEF_BUF_SHIFT;
- _in_pkt_size = DEF_PKT_SHIFT;
- _is_connecting = false;
_peer = Ref<EMWSPeer>(memnew(EMWSPeer));
- _js_id = 0;
}
EMWSClient::~EMWSClient() {
diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h
index 0123c37457..2ab7dc83d0 100644
--- a/modules/websocket/emws_client.h
+++ b/modules/websocket/emws_client.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,10 +41,10 @@ class EMWSClient : public WebSocketClient {
GDCIIMPL(EMWSClient, WebSocketClient);
private:
- int _js_id;
- bool _is_connecting;
- int _in_buf_size;
- int _in_pkt_size;
+ int _js_id = 0;
+ bool _is_connecting = false;
+ int _in_buf_size = DEF_BUF_SHIFT;
+ int _in_pkt_size = DEF_PKT_SHIFT;
static void _esws_on_connect(void *obj, char *proto);
static void _esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string);
diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp
index 5dcfba5567..5e75e10d68 100644
--- a/modules/websocket/emws_peer.cpp
+++ b/modules/websocket/emws_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -106,8 +106,6 @@ void EMWSPeer::set_no_delay(bool p_enabled) {
}
EMWSPeer::EMWSPeer() {
- peer_sock = -1;
- write_mode = WRITE_MODE_BINARY;
close();
};
diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h
index 2291a32bbc..abe5bf2bdb 100644
--- a/modules/websocket/emws_peer.h
+++ b/modules/websocket/emws_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,12 +56,12 @@ class EMWSPeer : public WebSocketPeer {
GDCIIMPL(EMWSPeer, WebSocketPeer);
private:
- int peer_sock;
- WriteMode write_mode;
+ int peer_sock = -1;
+ WriteMode write_mode = WRITE_MODE_BINARY;
Vector<uint8_t> _packet_buffer;
PacketBuffer<uint8_t> _in_buffer;
- uint8_t _is_string;
+ uint8_t _is_string = 0;
public:
Error read_msg(const uint8_t *p_data, uint32_t p_size, bool p_is_string);
diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp
index 9d43283d3e..a35d84f372 100644
--- a/modules/websocket/emws_server.cpp
+++ b/modules/websocket/emws_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h
index 1ce17855fe..4179b20ffe 100644
--- a/modules/websocket/emws_server.h
+++ b/modules/websocket/emws_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/library_godot_websocket.js b/modules/websocket/library_godot_websocket.js
index cf2c00a6a6..b182d1ecde 100644
--- a/modules/websocket/library_godot_websocket.js
+++ b/modules/websocket/library_godot_websocket.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/packet_buffer.h b/modules/websocket/packet_buffer.h
index 18b47b8d50..ed756363cf 100644
--- a/modules/websocket/packet_buffer.h
+++ b/modules/websocket/packet_buffer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp
index 8979a09619..5a02509c4a 100644
--- a/modules/websocket/register_types.cpp
+++ b/modules/websocket/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/register_types.h b/modules/websocket/register_types.h
index bb7be57ab3..3884db67b7 100644
--- a/modules/websocket/register_types.h
+++ b/modules/websocket/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/remote_debugger_peer_websocket.cpp b/modules/websocket/remote_debugger_peer_websocket.cpp
index 9a72e460e2..c9591cc564 100644
--- a/modules/websocket/remote_debugger_peer_websocket.cpp
+++ b/modules/websocket/remote_debugger_peer_websocket.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/remote_debugger_peer_websocket.h b/modules/websocket/remote_debugger_peer_websocket.h
index bb03e5e892..03c60fb480 100644
--- a/modules/websocket/remote_debugger_peer_websocket.h
+++ b/modules/websocket/remote_debugger_peer_websocket.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp
index 8feaa9af5a..425013f811 100644
--- a/modules/websocket/websocket_client.cpp
+++ b/modules/websocket/websocket_client.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,7 +33,6 @@
GDCINULL(WebSocketClient);
WebSocketClient::WebSocketClient() {
- verify_ssl = true;
}
WebSocketClient::~WebSocketClient() {
diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h
index 2966dc480b..0225c9b3d3 100644
--- a/modules/websocket/websocket_client.h
+++ b/modules/websocket/websocket_client.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,7 +42,7 @@ class WebSocketClient : public WebSocketMultiplayerPeer {
protected:
Ref<WebSocketPeer> _peer;
- bool verify_ssl;
+ bool verify_ssl = true;
Ref<X509Certificate> ssl_cert;
static void _bind_methods();
diff --git a/modules/websocket/websocket_macros.h b/modules/websocket/websocket_macros.h
index cf4545b435..d04909c97d 100644
--- a/modules/websocket/websocket_macros.h
+++ b/modules/websocket/websocket_macros.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp
index fa2fe891a5..011cb86535 100644
--- a/modules/websocket/websocket_multiplayer_peer.cpp
+++ b/modules/websocket/websocket_multiplayer_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,15 +33,6 @@
#include "core/os/os.h"
WebSocketMultiplayerPeer::WebSocketMultiplayerPeer() {
- _is_multiplayer = false;
- _peer_id = 0;
- _target_peer = 0;
- _refusing = false;
-
- _current_packet.source = 0;
- _current_packet.destination = 0;
- _current_packet.size = 0;
- _current_packet.data = nullptr;
}
WebSocketMultiplayerPeer::~WebSocketMultiplayerPeer() {
diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h
index 54daae23a6..48a6607d89 100644
--- a/modules/websocket/websocket_multiplayer_peer.h
+++ b/modules/websocket/websocket_multiplayer_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,20 +55,20 @@ protected:
};
struct Packet {
- int source;
- int destination;
- uint8_t *data;
- uint32_t size;
+ int source = 0;
+ int destination = 0;
+ uint8_t *data = nullptr;
+ uint32_t size = 0;
};
List<Packet> _incoming_packets;
Map<int, Ref<WebSocketPeer>> _peer_map;
Packet _current_packet;
- bool _is_multiplayer;
- int _target_peer;
- int _peer_id;
- int _refusing;
+ bool _is_multiplayer = false;
+ int _target_peer = 0;
+ int _peer_id = 0;
+ int _refusing = false;
static void _bind_methods();
diff --git a/modules/websocket/websocket_peer.cpp b/modules/websocket/websocket_peer.cpp
index 30a5972330..e77fdcfed2 100644
--- a/modules/websocket/websocket_peer.cpp
+++ b/modules/websocket/websocket_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h
index 729fdfd340..2ba83637f9 100644
--- a/modules/websocket/websocket_peer.h
+++ b/modules/websocket/websocket_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp
index b20b925dec..f57e8d959c 100644
--- a/modules/websocket/websocket_server.cpp
+++ b/modules/websocket/websocket_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h
index 34ae52a1ee..3fbd5e3b95 100644
--- a/modules/websocket/websocket_server.h
+++ b/modules/websocket/websocket_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp
index a2b81438df..a075ae3982 100644
--- a/modules/websocket/wsl_client.cpp
+++ b/modules/websocket/wsl_client.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -337,11 +337,6 @@ Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer
}
WSLClient::WSLClient() {
- _in_buf_size = DEF_BUF_SHIFT;
- _in_pkt_size = DEF_PKT_SHIFT;
- _out_buf_size = DEF_BUF_SHIFT;
- _out_pkt_size = DEF_PKT_SHIFT;
-
_peer.instance();
_tcp.instance();
disconnect_from_host();
diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h
index 0141ea93ea..e7c91ed333 100644
--- a/modules/websocket/wsl_client.h
+++ b/modules/websocket/wsl_client.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,27 +44,27 @@ class WSLClient : public WebSocketClient {
GDCIIMPL(WSLClient, WebSocketClient);
private:
- int _in_buf_size;
- int _in_pkt_size;
- int _out_buf_size;
- int _out_pkt_size;
+ int _in_buf_size = DEF_BUF_SHIFT;
+ int _in_pkt_size = DEF_PKT_SHIFT;
+ int _out_buf_size = DEF_BUF_SHIFT;
+ int _out_pkt_size = DEF_PKT_SHIFT;
Ref<WSLPeer> _peer;
Ref<StreamPeerTCP> _tcp;
Ref<StreamPeer> _connection;
CharString _request;
- int _requested;
+ int _requested = 0;
uint8_t _resp_buf[WSL_MAX_HEADER_SIZE];
- int _resp_pos;
+ int _resp_pos = 0;
String _response;
String _key;
String _host;
Vector<String> _protocols;
- bool _use_ssl;
+ bool _use_ssl = false;
void _do_handshake();
bool _verify_headers(String &r_protocol);
diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp
index bf1ba43f8a..dbbf86d0da 100644
--- a/modules/websocket/wsl_peer.cpp
+++ b/modules/websocket/wsl_peer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -329,10 +329,6 @@ void WSLPeer::invalidate() {
}
WSLPeer::WSLPeer() {
- _data = nullptr;
- _is_string = 0;
- close_code = -1;
- write_mode = WRITE_MODE_BINARY;
}
WSLPeer::~WSLPeer() {
diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h
index 35ac18615a..5e6a7e8554 100644
--- a/modules/websocket/wsl_peer.h
+++ b/modules/websocket/wsl_peer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,29 +48,17 @@ class WSLPeer : public WebSocketPeer {
public:
struct PeerData {
- bool polling;
- bool destroy;
- bool valid;
- bool is_server;
- bool closing;
- void *obj;
- void *peer;
+ bool polling = false;
+ bool destroy = false;
+ bool valid = false;
+ bool is_server = false;
+ bool closing = false;
+ void *obj = nullptr;
+ void *peer = nullptr;
Ref<StreamPeer> conn;
Ref<StreamPeerTCP> tcp;
- int id;
- wslay_event_context_ptr ctx;
-
- PeerData() {
- polling = false;
- destroy = false;
- valid = false;
- is_server = false;
- id = 1;
- ctx = nullptr;
- obj = nullptr;
- closing = false;
- peer = nullptr;
- }
+ int id = 1;
+ wslay_event_context_ptr ctx = nullptr;
};
static String compute_key_response(String p_key);
@@ -80,17 +68,17 @@ private:
static bool _wsl_poll(struct PeerData *p_data);
static void _wsl_destroy(struct PeerData **p_data);
- struct PeerData *_data;
- uint8_t _is_string;
+ struct PeerData *_data = nullptr;
+ uint8_t _is_string = 0;
// Our packet info is just a boolean (is_string), using uint8_t for it.
PacketBuffer<uint8_t> _in_buffer;
Vector<uint8_t> _packet_buffer;
- WriteMode write_mode;
+ WriteMode write_mode = WRITE_MODE_BINARY;
public:
- int close_code;
+ int close_code = -1;
String close_reason;
void poll(); // Used by client and server.
diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp
index 9a05967e4e..437eb2061b 100644
--- a/modules/websocket/wsl_server.cpp
+++ b/modules/websocket/wsl_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,15 +34,6 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
-WSLServer::PendingPeer::PendingPeer() {
- use_ssl = false;
- time = 0;
- has_request = false;
- response_sent = 0;
- req_pos = 0;
- memset(req_buf, 0, sizeof(req_buf));
-}
-
bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) {
Vector<String> psa = String((char *)req_buf).split("\r\n");
int len = psa.size();
@@ -310,10 +301,6 @@ Error WSLServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer
}
WSLServer::WSLServer() {
- _in_buf_size = DEF_BUF_SHIFT;
- _in_pkt_size = DEF_PKT_SHIFT;
- _out_buf_size = DEF_BUF_SHIFT;
- _out_pkt_size = DEF_PKT_SHIFT;
_server.instance();
}
diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h
index f86de02797..75669e12ee 100644
--- a/modules/websocket/wsl_server.h
+++ b/modules/websocket/wsl_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,26 +53,24 @@ private:
public:
Ref<StreamPeerTCP> tcp;
Ref<StreamPeer> connection;
- bool use_ssl;
+ bool use_ssl = false;
- int time;
- uint8_t req_buf[WSL_MAX_HEADER_SIZE];
- int req_pos;
+ int time = 0;
+ uint8_t req_buf[WSL_MAX_HEADER_SIZE] = {};
+ int req_pos = 0;
String key;
String protocol;
- bool has_request;
+ bool has_request = false;
CharString response;
- int response_sent;
-
- PendingPeer();
+ int response_sent = 0;
Error do_handshake(const Vector<String> p_protocols);
};
- int _in_buf_size;
- int _in_pkt_size;
- int _out_buf_size;
- int _out_pkt_size;
+ int _in_buf_size = DEF_BUF_SHIFT;
+ int _in_pkt_size = DEF_PKT_SHIFT;
+ int _out_buf_size = DEF_BUF_SHIFT;
+ int _out_pkt_size = DEF_PKT_SHIFT;
List<Ref<PendingPeer>> _pending;
Ref<TCP_Server> _server;
diff --git a/modules/webxr/SCsub b/modules/webxr/SCsub
new file mode 100644
index 0000000000..0a96af0811
--- /dev/null
+++ b/modules/webxr/SCsub
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+
+Import("env")
+Import("env_modules")
+
+if env["platform"] == "javascript":
+ env.AddJSLibraries(["native/library_godot_webxr.js"])
+ env.AddJSExterns(["native/webxr.externs.js"])
+
+env_webxr = env_modules.Clone()
+env_webxr.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/webxr/config.py b/modules/webxr/config.py
new file mode 100644
index 0000000000..9efebed4e6
--- /dev/null
+++ b/modules/webxr/config.py
@@ -0,0 +1,14 @@
+def can_build(env, platform):
+ return True
+
+
+def configure(env):
+ pass
+
+
+def get_doc_classes():
+ return ["WebXRInterface"]
+
+
+def get_doc_path():
+ return "doc_classes"
diff --git a/modules/webxr/doc_classes/WebXRInterface.xml b/modules/webxr/doc_classes/WebXRInterface.xml
new file mode 100644
index 0000000000..2407d44496
--- /dev/null
+++ b/modules/webxr/doc_classes/WebXRInterface.xml
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="WebXRInterface" inherits="XRInterface" version="4.0">
+ <brief_description>
+ AR/VR interface using WebXR.
+ </brief_description>
+ <description>
+ WebXR is an open standard that allows creating VR and AR applications that run in the web browser.
+ As such, this interface is only available when running in an HTML5 export.
+ WebXR supports a wide range of devices, from the very capable (like Valve Index, HTC Vive, Oculus Rift and Quest) down to the much less capable (like Google Cardboard, Oculus Go, GearVR, or plain smartphones).
+ Since WebXR is based on Javascript, it makes extensive use of callbacks, which means that [WebXRInterface] is forced to use signals, where other AR/VR interfaces would instead use functions that return a result immediately. This makes [WebXRInterface] quite a bit more complicated to intialize than other AR/VR interfaces.
+ Here's the minimum code required to start an immersive VR session:
+ [codeblock]
+ extends Node3D
+
+ var webxr_interface
+ var vr_supported = false
+
+ func _ready():
+ # We assume this node has a button as a child.
+ # This button is for the user to consent to entering immersive VR mode.
+ $Button.connect("pressed", self, "_on_Button_pressed")
+
+ webxr_interface = XRServer.find_interface("WebXR")
+ if webxr_interface:
+ # WebXR uses a lot of asynchronous callbacks, so we connect to various
+ # signals in order to receive them.
+ webxr_interface.connect("session_supported", self, "_webxr_session_supported")
+ webxr_interface.connect("session_started", self, "_webxr_session_started")
+ webxr_interface.connect("session_ended", self, "_webxr_session_ended")
+ webxr_interface.connect("session_failed", self, "_webxr_session_failed")
+
+ # This returns immediately - our _webxr_session_supported() method
+ # (which we connected to the "session_supported" signal above) will
+ # be called sometime later to let us know if it's supported or not.
+ webxr_interface.is_session_supported("immersive-vr")
+
+ func _webxr_session_supported(session_mode, supported):
+ if session_mode == 'immersive-vr':
+ vr_supported = supported
+
+ func _on_Button_pressed():
+ if not vr_supported:
+ OS.alert("Your browser doesn't support VR")
+ return
+
+ # We want an immersive VR session, as opposed to AR ('immersive-ar') or a
+ # simple 3DoF viewer ('viewer').
+ webxr_interface.session_mode = 'immersive-vr'
+ # 'bounded-floor' is room scale, 'local-floor' is a standing or sitting
+ # experience (it puts you 1.6m above the ground if you have 3DoF headset),
+ # whereas as 'local' puts you down at the XROrigin.
+ # This list means it'll first try to request 'bounded-floor', then
+ # fallback on 'local-floor' and ultimately 'local', if nothing else is
+ # supported.
+ webxr_interface.requested_reference_space_types = 'bounded-floor, local-floor, local'
+ # In order to use 'local-floor' or 'bounded-floor' we must also
+ # mark the features as required or optional.
+ webxr_interface.required_features = 'local-floor'
+ webxr_interface.optional_features = 'bounded-floor'
+
+ # This will return false if we're unable to even request the session,
+ # however, it can still fail asynchronously later in the process, so we
+ # only know if it's really succeeded or failed when our
+ # _webxr_session_started() or _webxr_session_failed() methods are called.
+ if not webxr_interface.initialize():
+ OS.alert("Failed to initialize")
+ return
+
+ func _webxr_session_started():
+ $Button.visible = false
+ # This tells Godot to start rendering to the headset.
+ get_viewport().xr = true
+ # This will be the reference space type you ultimately got, out of the
+ # types that you requested above. This is useful if you want the game to
+ # work a little differently in 'bounded-floor' versus 'local-floor'.
+ print ("Reference space type: " + webxr_interface.reference_space_type)
+
+ func _webxr_session_ended():
+ $Button.visible = true
+ # If the user exits immersive mode, then we tell Godot to render to the web
+ # page again.
+ get_viewport().xr = false
+
+ func _webxr_session_failed(message):
+ OS.alert("Failed to initialize: " + message)
+ [/codeblock]
+ There are several ways to handle "controller" input:
+ - Using [XRController3D] nodes and their [signal XRController3D.button_pressed] and [signal XRController3D.button_released] signals. This is how controllers are typically handled in AR/VR apps in Godot, however, this will only work with advanced VR controllers like the Oculus Touch or Index controllers, for example. The buttons codes are defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url].
+ - Using [method Node._unhandled_input] and [InputEventJoypadButton] or [InputEventJoypadMotion]. This works the same as normal joypads, except the [member InputEvent.device] starts at 100, so the left controller is 100 and the right controller is 101, and the button codes are also defined by [url=https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping]Section 3.3 of the WebXR Gamepads Module[/url].
+ - Using the [signal select], [signal squeeze] and related signals. This method will work for both advanced VR controllers, and non-traditional "controllers" like a tap on the screen, a spoken voice command or a button press on the device itself. The [code]controller_id[/code] passed to these signals is the same id as used in [member XRController3D.controller_id].
+ You can use one or all of these methods to allow your game or app to support a wider or narrower set of devices and input methods, or to allow more advanced interations with more advanced devices.
+ </description>
+ <tutorials>
+ <link title="How to make a VR game for WebXR with Godot">https://www.snopekgames.com/blog/2020/how-make-vr-game-webxr-godot</link>
+ </tutorials>
+ <methods>
+ <method name="get_controller" qualifiers="const">
+ <return type="XRPositionalTracker">
+ </return>
+ <argument index="0" name="controller_id" type="int">
+ </argument>
+ <description>
+ Gets an [XRPositionalTracker] for the given [code]controller_id[/code].
+ In the context of WebXR, a "controller" can be an advanced VR controller like the Oculus Touch or Index controllers, or even a tap on the screen, a spoken voice command or a button press on the device itself. When a non-traditional controller is used, interpret the position and orientation of the [XRPositionalTracker] as a ray pointing at the object the user wishes to interact with.
+ Use this method to get information about the controller that triggered one of these signals:
+ - [signal selectstart]
+ - [signal select]
+ - [signal selectend]
+ - [signal squeezestart]
+ - [signal squeeze]
+ - [signal squeezestart]
+ </description>
+ </method>
+ <method name="is_session_supported">
+ <return type="void">
+ </return>
+ <argument index="0" name="session_mode" type="String">
+ </argument>
+ <description>
+ Checks if the given [code]session_mode[/code] is supported by the user's browser.
+ Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]"immersive-vr"[/code], [code]"immersive-ar"[/code], and [code]"inline"[/code].
+ This method returns nothing, instead it emits the [signal session_supported] signal with the result.
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="bounds_geometry" type="PackedVector3Array" setter="" getter="get_bounds_geometry">
+ The vertices of a polygon which defines the boundaries of the user's play area.
+ This will only be available if [member reference_space_type] is [code]"bounded-floor"[/code] and only on certain browsers and devices that support it.
+ The [signal reference_space_reset] signal may indicate when this changes.
+ </member>
+ <member name="optional_features" type="String" setter="set_optional_features" getter="get_optional_features">
+ A comma-seperated list of optional features used by [method XRInterface.initialize] when setting up the WebXR session.
+ If a user's browser or device doesn't support one of the given features, initialization will continue, but you won't be able to use the requested feature.
+ This doesn't have any effect on the interface when already initialized.
+ Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
+ </member>
+ <member name="reference_space_type" type="String" setter="" getter="get_reference_space_type">
+ The reference space type (from the list of requested types set in the [member requested_reference_space_types] property), that was ultimately used by [method XRInterface.initialize] when setting up the WebXR session.
+ Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
+ </member>
+ <member name="requested_reference_space_types" type="String" setter="set_requested_reference_space_types" getter="get_requested_reference_space_types">
+ A comma-seperated list of reference space types used by [method XRInterface.initialize] when setting up the WebXR session.
+ The reference space types are requested in order, and the first on supported by the users device or browser will be used. The [member reference_space_type] property contains the reference space type that was ultimately used.
+ This doesn't have any effect on the interface when already initialized.
+ Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
+ </member>
+ <member name="required_features" type="String" setter="set_required_features" getter="get_required_features">
+ A comma-seperated list of required features used by [method XRInterface.initialize] when setting up the WebXR session.
+ If a user's browser or device doesn't support one of the given features, initialization will fail and [signal session_failed] will be emitted.
+ This doesn't have any effect on the interface when already initialized.
+ Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
+ </member>
+ <member name="session_mode" type="String" setter="set_session_mode" getter="get_session_mode">
+ The session mode used by [method XRInterface.initialize] when setting up the WebXR session.
+ This doesn't have any effect on the interface when already initialized.
+ Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]"immersive-vr"[/code], [code]"immersive-ar"[/code], and [code]"inline"[/code].
+ </member>
+ <member name="visibility_state" type="String" setter="" getter="get_visibility_state">
+ Indicates if the WebXR session's imagery is visible to the user.
+ Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRVisibilityState]WebXR's XRVisibilityState[/url], including [code]"hidden"[/code], [code]"visible"[/code], and [code]"visible-blurred"[/code].
+ </member>
+ </members>
+ <signals>
+ <signal name="reference_space_reset">
+ <description>
+ Emitted to indicate that the reference space has been reset or reconfigured.
+ When (or whether) this is emitted depends on the user's browser or device, but may include when the user has changed the dimensions of their play space (which you may be able to access via [member bounds_geometry]) or pressed/held a button to recenter their position.
+ See [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpace/reset_event]WebXR's XRReferenceSpace reset event[/url] for more information.
+ </description>
+ </signal>
+ <signal name="select">
+ <argument index="0" name="controller_id" type="int">
+ </argument>
+ <description>
+ Emitted after one of the "controllers" has finished its "primary action".
+ Use [method get_controller] to get more information about the controller.
+ </description>
+ </signal>
+ <signal name="selectend">
+ <argument index="0" name="controller_id" type="int">
+ </argument>
+ <description>
+ Emitted when one of the "controllers" has finished its "primary action".
+ Use [method get_controller] to get more information about the controller.
+ </description>
+ </signal>
+ <signal name="selectstart">
+ <argument index="0" name="controller_id" type="int">
+ </argument>
+ <description>
+ Emitted when one of the "controllers" has started its "primary action".
+ Use [method get_controller] to get more information about the controller.
+ </description>
+ </signal>
+ <signal name="session_ended">
+ <description>
+ Emitted when the user ends the WebXR session (which can be done using UI from the browser or device).
+ At this point, you should do [code]get_viewport().xr = false[/code] to instruct Godot to resume rendering to the screen.
+ </description>
+ </signal>
+ <signal name="session_failed">
+ <argument index="0" name="message" type="String">
+ </argument>
+ <description>
+ Emitted by [method XRInterface.initialize] if the session fails to start.
+ [code]message[/code] may optionally contain an error message from WebXR, or an empty string if no message is available.
+ </description>
+ </signal>
+ <signal name="session_started">
+ <description>
+ Emitted by [method XRInterface.initialize] if the session is successfully started.
+ At this point, it's safe to do [code]get_viewport().xr = true[/code] to instruct Godot to start rendering to the AR/VR device.
+ </description>
+ </signal>
+ <signal name="session_supported">
+ <argument index="0" name="session_mode" type="String">
+ </argument>
+ <argument index="1" name="supported" type="bool">
+ </argument>
+ <description>
+ Emitted by [method is_session_supported] to indicate if the given [code]session_mode[/code] is supported or not.
+ </description>
+ </signal>
+ <signal name="squeeze">
+ <argument index="0" name="controller_id" type="int">
+ </argument>
+ <description>
+ Emitted after one of the "controllers" has finished its "primary squeeze action".
+ Use [method get_controller] to get more information about the controller.
+ </description>
+ </signal>
+ <signal name="squeezeend">
+ <argument index="0" name="controller_id" type="int">
+ </argument>
+ <description>
+ Emitted when one of the "controllers" has finished its "primary squeeze action".
+ Use [method get_controller] to get more information about the controller.
+ </description>
+ </signal>
+ <signal name="squeezestart">
+ <argument index="0" name="controller_id" type="int">
+ </argument>
+ <description>
+ Emitted when one of the "controllers" has started its "primary squeeze action".
+ Use [method get_controller] to get more information about the controller.
+ </description>
+ </signal>
+ <signal name="visibility_state_changed">
+ <description>
+ Emitted when [member visibility_state] has changed.
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
diff --git a/modules/webxr/godot_webxr.h b/modules/webxr/godot_webxr.h
new file mode 100644
index 0000000000..41a690f473
--- /dev/null
+++ b/modules/webxr/godot_webxr.h
@@ -0,0 +1,85 @@
+/*************************************************************************/
+/* godot_webxr.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GODOT_WEBXR_H
+#define GODOT_WEBXR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stddef.h"
+
+typedef void (*GodotWebXRSupportedCallback)(char *p_session_mode, int p_supported);
+typedef void (*GodotWebXRStartedCallback)(char *p_reference_space_type);
+typedef void (*GodotWebXREndedCallback)();
+typedef void (*GodotWebXRFailedCallback)(char *p_message);
+typedef void (*GodotWebXRControllerCallback)();
+typedef void (*GodotWebXRInputEventCallback)(char *p_signal_name, int p_controller_id);
+typedef void (*GodotWebXRSimpleEventCallback)(char *p_signal_name);
+
+extern int godot_webxr_is_supported();
+extern void godot_webxr_is_session_supported(const char *p_session_mode, GodotWebXRSupportedCallback p_callback);
+
+extern void godot_webxr_initialize(
+ const char *p_session_mode,
+ const char *p_required_features,
+ const char *p_optional_features,
+ const char *p_requested_reference_space_types,
+ GodotWebXRStartedCallback p_on_session_started,
+ GodotWebXREndedCallback p_on_session_ended,
+ GodotWebXRFailedCallback p_on_session_failed,
+ GodotWebXRControllerCallback p_on_controller_changed,
+ GodotWebXRInputEventCallback p_on_input_event,
+ GodotWebXRSimpleEventCallback p_on_simple_event);
+extern void godot_webxr_uninitialize();
+
+extern int godot_webxr_get_view_count();
+extern int *godot_webxr_get_render_targetsize();
+extern float *godot_webxr_get_transform_for_eye(int p_eye);
+extern float *godot_webxr_get_projection_for_eye(int p_eye);
+extern int godot_webxr_get_external_texture_for_eye(int p_eye);
+extern void godot_webxr_commit_for_eye(int p_eye);
+
+extern void godot_webxr_sample_controller_data();
+extern int godot_webxr_get_controller_count();
+extern int godot_webxr_is_controller_connected(int p_controller);
+extern float *godot_webxr_get_controller_transform(int p_controller);
+extern int *godot_webxr_get_controller_buttons(int p_controller);
+extern int *godot_webxr_get_controller_axes(int p_controller);
+
+extern char *godot_webxr_get_visibility_state();
+extern int *godot_webxr_get_bounds_geometry();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GODOT_WEBXR_H */
diff --git a/modules/webxr/native/library_godot_webxr.js b/modules/webxr/native/library_godot_webxr.js
new file mode 100644
index 0000000000..8e9ef8a73c
--- /dev/null
+++ b/modules/webxr/native/library_godot_webxr.js
@@ -0,0 +1,672 @@
+/*************************************************************************/
+/* library_godot_webxr.js */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+const GodotWebXR = {
+ $GodotWebXR__deps: ['$Browser', '$GL', '$GodotRuntime'],
+ $GodotWebXR: {
+ gl: null,
+
+ texture_ids: [null, null],
+ textures: [null, null],
+
+ session: null,
+ space: null,
+ frame: null,
+ pose: null,
+
+ // Monkey-patch the requestAnimationFrame() used by Emscripten for the main
+ // loop, so that we can swap it out for XRSession.requestAnimationFrame()
+ // when an XR session is started.
+ orig_requestAnimationFrame: null,
+ requestAnimationFrame: (callback) => {
+ if (GodotWebXR.session && GodotWebXR.space) {
+ const onFrame = function (time, frame) {
+ GodotWebXR.frame = frame;
+ GodotWebXR.pose = frame.getViewerPose(GodotWebXR.space);
+ callback(time);
+ GodotWebXR.frame = null;
+ GodotWebXR.pose = null;
+ };
+ GodotWebXR.session.requestAnimationFrame(onFrame);
+ } else {
+ GodotWebXR.orig_requestAnimationFrame(callback);
+ }
+ },
+ monkeyPatchRequestAnimationFrame: (enable) => {
+ if (GodotWebXR.orig_requestAnimationFrame === null) {
+ GodotWebXR.orig_requestAnimationFrame = Browser.requestAnimationFrame;
+ }
+ Browser.requestAnimationFrame = enable
+ ? GodotWebXR.requestAnimationFrame : GodotWebXR.orig_requestAnimationFrame;
+ },
+ pauseResumeMainLoop: () => {
+ // Once both GodotWebXR.session and GodotWebXR.space are set or
+ // unset, our monkey-patched requestAnimationFrame() should be
+ // enabled or disabled. When using the WebXR API Emulator, this
+ // gets picked up automatically, however, in the Oculus Browser
+ // on the Quest, we need to pause and resume the main loop.
+ Browser.pauseAsyncCallbacks();
+ Browser.mainLoop.pause();
+ window.setTimeout(function () {
+ Browser.resumeAsyncCallbacks();
+ Browser.mainLoop.resume();
+ }, 0);
+ },
+
+ // Some custom WebGL code for blitting our eye textures to the
+ // framebuffer we get from WebXR.
+ shaderProgram: null,
+ programInfo: null,
+ buffer: null,
+ // Vertex shader source.
+ vsSource: `
+ const vec2 scale = vec2(0.5, 0.5);
+ attribute vec4 aVertexPosition;
+
+ varying highp vec2 vTextureCoord;
+
+ void main () {
+ gl_Position = aVertexPosition;
+ vTextureCoord = aVertexPosition.xy * scale + scale;
+ }
+ `,
+ // Fragment shader source.
+ fsSource: `
+ varying highp vec2 vTextureCoord;
+
+ uniform sampler2D uSampler;
+
+ void main() {
+ gl_FragColor = texture2D(uSampler, vTextureCoord);
+ }
+ `,
+
+ initShaderProgram: (gl, vsSource, fsSource) => {
+ const vertexShader = GodotWebXR.loadShader(gl, gl.VERTEX_SHADER, vsSource);
+ const fragmentShader = GodotWebXR.loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
+
+ const shaderProgram = gl.createProgram();
+ gl.attachShader(shaderProgram, vertexShader);
+ gl.attachShader(shaderProgram, fragmentShader);
+ gl.linkProgram(shaderProgram);
+
+ if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
+ GodotRuntime.error(`Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgram)}`);
+ return null;
+ }
+
+ return shaderProgram;
+ },
+ loadShader: (gl, type, source) => {
+ const shader = gl.createShader(type);
+ gl.shaderSource(shader, source);
+ gl.compileShader(shader);
+
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
+ GodotRuntime.error(`An error occurred compiling the shader: ${gl.getShaderInfoLog(shader)}`);
+ gl.deleteShader(shader);
+ return null;
+ }
+
+ return shader;
+ },
+ initBuffer: (gl) => {
+ const positionBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ const positions = [
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0,
+ ];
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
+ return positionBuffer;
+ },
+ blitTexture: (gl, texture) => {
+ if (GodotWebXR.shaderProgram === null) {
+ GodotWebXR.shaderProgram = GodotWebXR.initShaderProgram(gl, GodotWebXR.vsSource, GodotWebXR.fsSource);
+ GodotWebXR.programInfo = {
+ program: GodotWebXR.shaderProgram,
+ attribLocations: {
+ vertexPosition: gl.getAttribLocation(GodotWebXR.shaderProgram, 'aVertexPosition'),
+ },
+ uniformLocations: {
+ uSampler: gl.getUniformLocation(GodotWebXR.shaderProgram, 'uSampler'),
+ },
+ };
+ GodotWebXR.buffer = GodotWebXR.initBuffer(gl);
+ }
+
+ const orig_program = gl.getParameter(gl.CURRENT_PROGRAM);
+ gl.useProgram(GodotWebXR.shaderProgram);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, GodotWebXR.buffer);
+ gl.vertexAttribPointer(GodotWebXR.programInfo.attribLocations.vertexPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(GodotWebXR.programInfo.attribLocations.vertexPosition);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.uniform1i(GodotWebXR.programInfo.uniformLocations.uSampler, 0);
+
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+
+ // Restore state.
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.disableVertexAttribArray(GodotWebXR.programInfo.attribLocations.vertexPosition);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.useProgram(orig_program);
+ },
+
+ // Holds the controllers list between function calls.
+ controllers: [],
+
+ // Updates controllers array, where the left hand (or sole tracker) is
+ // the first element, and the right hand is the second element, and any
+ // others placed at the 3rd position and up.
+ sampleControllers: () => {
+ if (!GodotWebXR.session || !GodotWebXR.frame) {
+ return;
+ }
+
+ let other_index = 2;
+ const controllers = [];
+ GodotWebXR.session.inputSources.forEach((input_source) => {
+ if (input_source.targetRayMode === 'tracked-pointer') {
+ if (input_source.handedness === 'right') {
+ controllers[1] = input_source;
+ } else if (input_source.handedness === 'left' || !controllers[0]) {
+ controllers[0] = input_source;
+ }
+ } else {
+ controllers[other_index++] = input_source;
+ }
+ });
+ GodotWebXR.controllers = controllers;
+ },
+
+ getControllerId: (input_source) => GodotWebXR.controllers.indexOf(input_source),
+ },
+
+ godot_webxr_is_supported__proxy: 'sync',
+ godot_webxr_is_supported__sig: 'i',
+ godot_webxr_is_supported: function () {
+ return !!navigator.xr;
+ },
+
+ godot_webxr_is_session_supported__proxy: 'sync',
+ godot_webxr_is_session_supported__sig: 'vii',
+ godot_webxr_is_session_supported: function (p_session_mode, p_callback) {
+ const session_mode = GodotRuntime.parseString(p_session_mode);
+ const cb = GodotRuntime.get_func(p_callback);
+ if (navigator.xr) {
+ navigator.xr.isSessionSupported(session_mode).then(function (supported) {
+ const c_str = GodotRuntime.allocString(session_mode);
+ cb(c_str, supported ? 1 : 0);
+ GodotRuntime.free(c_str);
+ });
+ } else {
+ const c_str = GodotRuntime.allocString(session_mode);
+ cb(c_str, 0);
+ GodotRuntime.free(c_str);
+ }
+ },
+
+ godot_webxr_initialize__deps: ['emscripten_webgl_get_current_context'],
+ godot_webxr_initialize__proxy: 'sync',
+ godot_webxr_initialize__sig: 'viiiiiiiiii',
+ godot_webxr_initialize: function (p_session_mode, p_required_features, p_optional_features, p_requested_reference_spaces, p_on_session_started, p_on_session_ended, p_on_session_failed, p_on_controller_changed, p_on_input_event, p_on_simple_event) {
+ GodotWebXR.monkeyPatchRequestAnimationFrame(true);
+
+ const session_mode = GodotRuntime.parseString(p_session_mode);
+ const required_features = GodotRuntime.parseString(p_required_features).split(',').map((s) => s.trim()).filter((s) => s !== '');
+ const optional_features = GodotRuntime.parseString(p_optional_features).split(',').map((s) => s.trim()).filter((s) => s !== '');
+ const requested_reference_space_types = GodotRuntime.parseString(p_requested_reference_spaces).split(',').map((s) => s.trim());
+ const onstarted = GodotRuntime.get_func(p_on_session_started);
+ const onended = GodotRuntime.get_func(p_on_session_ended);
+ const onfailed = GodotRuntime.get_func(p_on_session_failed);
+ const oncontroller = GodotRuntime.get_func(p_on_controller_changed);
+ const oninputevent = GodotRuntime.get_func(p_on_input_event);
+ const onsimpleevent = GodotRuntime.get_func(p_on_simple_event);
+
+ const session_init = {};
+ if (required_features.length > 0) {
+ session_init['requiredFeatures'] = required_features;
+ }
+ if (optional_features.length > 0) {
+ session_init['optionalFeatures'] = optional_features;
+ }
+
+ navigator.xr.requestSession(session_mode, session_init).then(function (session) {
+ GodotWebXR.session = session;
+
+ session.addEventListener('end', function (evt) {
+ onended();
+ });
+
+ session.addEventListener('inputsourceschange', function (evt) {
+ let controller_changed = false;
+ [evt.added, evt.removed].forEach((lst) => {
+ lst.forEach((input_source) => {
+ if (input_source.targetRayMode === 'tracked-pointer') {
+ controller_changed = true;
+ }
+ });
+ });
+ if (controller_changed) {
+ oncontroller();
+ }
+ });
+
+ ['selectstart', 'select', 'selectend', 'squeezestart', 'squeeze', 'squeezeend'].forEach((input_event) => {
+ session.addEventListener(input_event, function (evt) {
+ const c_str = GodotRuntime.allocString(input_event);
+ oninputevent(c_str, GodotWebXR.getControllerId(evt.inputSource));
+ GodotRuntime.free(c_str);
+ });
+ });
+
+ session.addEventListener('visibilitychange', function (evt) {
+ const c_str = GodotRuntime.allocString('visibility_state_changed');
+ onsimpleevent(c_str);
+ GodotRuntime.free(c_str);
+ });
+
+ const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef
+ const gl = GL.getContext(gl_context_handle).GLctx;
+ GodotWebXR.gl = gl;
+
+ gl.makeXRCompatible().then(function () {
+ session.updateRenderState({
+ baseLayer: new XRWebGLLayer(session, gl),
+ });
+
+ function onReferenceSpaceSuccess(reference_space, reference_space_type) {
+ GodotWebXR.space = reference_space;
+
+ // Using reference_space.addEventListener() crashes when
+ // using the polyfill with the WebXR Emulator extension,
+ // so we set the event property instead.
+ reference_space.onreset = function (evt) {
+ const c_str = GodotRuntime.allocString('reference_space_reset');
+ onsimpleevent(c_str);
+ GodotRuntime.free(c_str);
+ };
+
+ // Now that both GodotWebXR.session and GodotWebXR.space are
+ // set, we need to pause and resume the main loop for the XR
+ // main loop to kick in.
+ GodotWebXR.pauseResumeMainLoop();
+
+ // Call in setTimeout() so that errors in the onstarted()
+ // callback don't bubble up here and cause Godot to try the
+ // next reference space.
+ window.setTimeout(function () {
+ const c_str = GodotRuntime.allocString(reference_space_type);
+ onstarted(c_str);
+ GodotRuntime.free(c_str);
+ }, 0);
+ }
+
+ function requestReferenceSpace() {
+ const reference_space_type = requested_reference_space_types.shift();
+ session.requestReferenceSpace(reference_space_type)
+ .then((refSpace) => {
+ onReferenceSpaceSuccess(refSpace, reference_space_type);
+ })
+ .catch(() => {
+ if (requested_reference_space_types.length === 0) {
+ const c_str = GodotRuntime.allocString('Unable to get any of the requested reference space types');
+ onfailed(c_str);
+ GodotRuntime.free(c_str);
+ } else {
+ requestReferenceSpace();
+ }
+ });
+ }
+
+ requestReferenceSpace();
+ }).catch(function (error) {
+ const c_str = GodotRuntime.allocString(`Unable to make WebGL context compatible with WebXR: ${error}`);
+ onfailed(c_str);
+ GodotRuntime.free(c_str);
+ });
+ }).catch(function (error) {
+ const c_str = GodotRuntime.allocString(`Unable to start session: ${error}`);
+ onfailed(c_str);
+ GodotRuntime.free(c_str);
+ });
+ },
+
+ godot_webxr_uninitialize__proxy: 'sync',
+ godot_webxr_uninitialize__sig: 'v',
+ godot_webxr_uninitialize: function () {
+ if (GodotWebXR.session) {
+ GodotWebXR.session.end()
+ // Prevent exception when session has already ended.
+ .catch((e) => { });
+ }
+
+ // Clean-up the textures we allocated for each view.
+ const gl = GodotWebXR.gl;
+ for (let i = 0; i < GodotWebXR.textures.length; i++) {
+ const texture = GodotWebXR.textures[i];
+ if (texture !== null) {
+ gl.deleteTexture(texture);
+ }
+ GodotWebXR.textures[i] = null;
+
+ const texture_id = GodotWebXR.texture_ids[i];
+ if (texture_id !== null) {
+ GL.textures[texture_id] = null;
+ }
+ GodotWebXR.texture_ids[i] = null;
+ }
+
+ GodotWebXR.session = null;
+ GodotWebXR.space = null;
+ GodotWebXR.frame = null;
+ GodotWebXR.pose = null;
+
+ // Disable the monkey-patched window.requestAnimationFrame() and
+ // pause/restart the main loop to activate it on all platforms.
+ GodotWebXR.monkeyPatchRequestAnimationFrame(false);
+ GodotWebXR.pauseResumeMainLoop();
+ },
+
+ godot_webxr_get_view_count__proxy: 'sync',
+ godot_webxr_get_view_count__sig: 'i',
+ godot_webxr_get_view_count: function () {
+ if (!GodotWebXR.session || !GodotWebXR.pose) {
+ return 0;
+ }
+ return GodotWebXR.pose.views.length;
+ },
+
+ godot_webxr_get_render_targetsize__proxy: 'sync',
+ godot_webxr_get_render_targetsize__sig: 'i',
+ godot_webxr_get_render_targetsize: function () {
+ if (!GodotWebXR.session || !GodotWebXR.pose) {
+ return 0;
+ }
+
+ const glLayer = GodotWebXR.session.renderState.baseLayer;
+ const view = GodotWebXR.pose.views[0];
+ const viewport = glLayer.getViewport(view);
+
+ const buf = GodotRuntime.malloc(2 * 4);
+ GodotRuntime.setHeapValue(buf + 0, viewport.width, 'i32');
+ GodotRuntime.setHeapValue(buf + 4, viewport.height, 'i32');
+ return buf;
+ },
+
+ godot_webxr_get_transform_for_eye__proxy: 'sync',
+ godot_webxr_get_transform_for_eye__sig: 'ii',
+ godot_webxr_get_transform_for_eye: function (p_eye) {
+ if (!GodotWebXR.session || !GodotWebXR.pose) {
+ return 0;
+ }
+
+ const views = GodotWebXR.pose.views;
+ let matrix;
+ if (p_eye === 0) {
+ matrix = GodotWebXR.pose.transform.matrix;
+ } else {
+ matrix = views[p_eye - 1].transform.matrix;
+ }
+ const buf = GodotRuntime.malloc(16 * 4);
+ for (let i = 0; i < 16; i++) {
+ GodotRuntime.setHeapValue(buf + (i * 4), matrix[i], 'float');
+ }
+ return buf;
+ },
+
+ godot_webxr_get_projection_for_eye__proxy: 'sync',
+ godot_webxr_get_projection_for_eye__sig: 'ii',
+ godot_webxr_get_projection_for_eye: function (p_eye) {
+ if (!GodotWebXR.session || !GodotWebXR.pose) {
+ return 0;
+ }
+
+ const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0;
+ const matrix = GodotWebXR.pose.views[view_index].projectionMatrix;
+ const buf = GodotRuntime.malloc(16 * 4);
+ for (let i = 0; i < 16; i++) {
+ GodotRuntime.setHeapValue(buf + (i * 4), matrix[i], 'float');
+ }
+ return buf;
+ },
+
+ godot_webxr_get_external_texture_for_eye__proxy: 'sync',
+ godot_webxr_get_external_texture_for_eye__sig: 'ii',
+ godot_webxr_get_external_texture_for_eye: function (p_eye) {
+ if (!GodotWebXR.session) {
+ return 0;
+ }
+
+ const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0;
+ if (GodotWebXR.texture_ids[view_index]) {
+ return GodotWebXR.texture_ids[view_index];
+ }
+
+ // Check pose separately and after returning the cached texture id,
+ // because we won't get a pose in some cases if we lose tracking, and
+ // we don't want to return 0 just because tracking was lost.
+ if (!GodotWebXR.pose) {
+ return 0;
+ }
+
+ const glLayer = GodotWebXR.session.renderState.baseLayer;
+ const view = GodotWebXR.pose.views[view_index];
+ const viewport = glLayer.getViewport(view);
+ const gl = GodotWebXR.gl;
+
+ const texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, viewport.width, viewport.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ const texture_id = GL.getNewId(GL.textures);
+ GL.textures[texture_id] = texture;
+ GodotWebXR.textures[view_index] = texture;
+ GodotWebXR.texture_ids[view_index] = texture_id;
+ return texture_id;
+ },
+
+ godot_webxr_commit_for_eye__proxy: 'sync',
+ godot_webxr_commit_for_eye__sig: 'vi',
+ godot_webxr_commit_for_eye: function (p_eye) {
+ if (!GodotWebXR.session || !GodotWebXR.pose) {
+ return;
+ }
+
+ const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0;
+ const glLayer = GodotWebXR.session.renderState.baseLayer;
+ const view = GodotWebXR.pose.views[view_index];
+ const viewport = glLayer.getViewport(view);
+ const gl = GodotWebXR.gl;
+
+ const orig_framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
+ const orig_viewport = gl.getParameter(gl.VIEWPORT);
+
+ // Bind to WebXR's framebuffer.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer);
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ GodotWebXR.blitTexture(gl, GodotWebXR.textures[view_index]);
+
+ // Restore state.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, orig_framebuffer);
+ gl.viewport(orig_viewport[0], orig_viewport[1], orig_viewport[2], orig_viewport[3]);
+ },
+
+ godot_webxr_sample_controller_data__proxy: 'sync',
+ godot_webxr_sample_controller_data__sig: 'v',
+ godot_webxr_sample_controller_data: function () {
+ GodotWebXR.sampleControllers();
+ },
+
+ godot_webxr_get_controller_count__proxy: 'sync',
+ godot_webxr_get_controller_count__sig: 'i',
+ godot_webxr_get_controller_count: function () {
+ if (!GodotWebXR.session || !GodotWebXR.frame) {
+ return 0;
+ }
+ return GodotWebXR.controllers.length;
+ },
+
+ godot_webxr_is_controller_connected__proxy: 'sync',
+ godot_webxr_is_controller_connected__sig: 'ii',
+ godot_webxr_is_controller_connected: function (p_controller) {
+ if (!GodotWebXR.session || !GodotWebXR.frame) {
+ return false;
+ }
+ return !!GodotWebXR.controllers[p_controller];
+ },
+
+ godot_webxr_get_controller_transform__proxy: 'sync',
+ godot_webxr_get_controller_transform__sig: 'ii',
+ godot_webxr_get_controller_transform: function (p_controller) {
+ if (!GodotWebXR.session || !GodotWebXR.frame) {
+ return 0;
+ }
+
+ const controller = GodotWebXR.controllers[p_controller];
+ if (!controller) {
+ return 0;
+ }
+
+ const frame = GodotWebXR.frame;
+ const space = GodotWebXR.space;
+
+ const pose = frame.getPose(controller.targetRaySpace, space);
+ if (!pose) {
+ // This can mean that the controller lost tracking.
+ return 0;
+ }
+ const matrix = pose.transform.matrix;
+
+ const buf = GodotRuntime.malloc(16 * 4);
+ for (let i = 0; i < 16; i++) {
+ GodotRuntime.setHeapValue(buf + (i * 4), matrix[i], 'float');
+ }
+ return buf;
+ },
+
+ godot_webxr_get_controller_buttons__proxy: 'sync',
+ godot_webxr_get_controller_buttons__sig: 'ii',
+ godot_webxr_get_controller_buttons: function (p_controller) {
+ if (GodotWebXR.controllers.length === 0) {
+ return 0;
+ }
+
+ const controller = GodotWebXR.controllers[p_controller];
+ if (!controller || !controller.gamepad) {
+ return 0;
+ }
+
+ const button_count = controller.gamepad.buttons.length;
+
+ const buf = GodotRuntime.malloc((button_count + 1) * 4);
+ GodotRuntime.setHeapValue(buf, button_count, 'i32');
+ for (let i = 0; i < button_count; i++) {
+ GodotRuntime.setHeapValue(buf + 4 + (i * 4), controller.gamepad.buttons[i].value, 'float');
+ }
+ return buf;
+ },
+
+ godot_webxr_get_controller_axes__proxy: 'sync',
+ godot_webxr_get_controller_axes__sig: 'ii',
+ godot_webxr_get_controller_axes: function (p_controller) {
+ if (GodotWebXR.controllers.length === 0) {
+ return 0;
+ }
+
+ const controller = GodotWebXR.controllers[p_controller];
+ if (!controller || !controller.gamepad) {
+ return 0;
+ }
+
+ const axes_count = controller.gamepad.axes.length;
+
+ const buf = GodotRuntime.malloc((axes_count + 1) * 4);
+ GodotRuntime.setHeapValue(buf, axes_count, 'i32');
+ for (let i = 0; i < axes_count; i++) {
+ let value = controller.gamepad.axes[i];
+ if (i === 1 || i === 3) {
+ // Invert the Y-axis on thumbsticks and trackpads, in order to
+ // match OpenXR and other XR platform SDKs.
+ value *= -1.0;
+ }
+ GodotRuntime.setHeapValue(buf + 4 + (i * 4), value, 'float');
+ }
+ return buf;
+ },
+
+ godot_webxr_get_visibility_state__proxy: 'sync',
+ godot_webxr_get_visibility_state__sig: 'i',
+ godot_webxr_get_visibility_state: function () {
+ if (!GodotWebXR.session || !GodotWebXR.session.visibilityState) {
+ return 0;
+ }
+
+ return GodotRuntime.allocString(GodotWebXR.session.visibilityState);
+ },
+
+ godot_webxr_get_bounds_geometry__proxy: 'sync',
+ godot_webxr_get_bounds_geometry__sig: 'i',
+ godot_webxr_get_bounds_geometry: function () {
+ if (!GodotWebXR.space || !GodotWebXR.space.boundsGeometry) {
+ return 0;
+ }
+
+ const point_count = GodotWebXR.space.boundsGeometry.length;
+ if (point_count === 0) {
+ return 0;
+ }
+
+ const buf = GodotRuntime.malloc(((point_count * 3) + 1) * 4);
+ GodotRuntime.setHeapValue(buf, point_count, 'i32');
+ for (let i = 0; i < point_count; i++) {
+ const point = GodotWebXR.space.boundsGeometry[i];
+ GodotRuntime.setHeapValue(buf + ((i * 3) + 1) * 4, point.x, 'float');
+ GodotRuntime.setHeapValue(buf + ((i * 3) + 2) * 4, point.y, 'float');
+ GodotRuntime.setHeapValue(buf + ((i * 3) + 3) * 4, point.z, 'float');
+ }
+
+ return buf;
+ },
+};
+
+autoAddDeps(GodotWebXR, '$GodotWebXR');
+mergeInto(LibraryManager.library, GodotWebXR);
diff --git a/modules/webxr/native/webxr.externs.js b/modules/webxr/native/webxr.externs.js
new file mode 100644
index 0000000000..9ea105aa93
--- /dev/null
+++ b/modules/webxr/native/webxr.externs.js
@@ -0,0 +1,499 @@
+/**
+ * @type {XR}
+ */
+Navigator.prototype.xr;
+
+/**
+ * @constructor
+ */
+function XRSessionInit() {};
+
+/**
+ * @type {Array<string>}
+ */
+XRSessionInit.prototype.requiredFeatures;
+
+/**
+ * @type {Array<string>}
+ */
+XRSessionInit.prototype.optionalFeatures;
+
+/**
+ * @constructor
+ */
+function XR() {}
+
+/**
+ * @type {?function (Event)}
+ */
+XR.prototype.ondevicechanged;
+
+/**
+ * @param {string} mode
+ *
+ * @return {!Promise<boolean>}
+ */
+XR.prototype.isSessionSupported = function(mode) {};
+
+/**
+ * @param {string} mode
+ * @param {XRSessionInit} options
+ *
+ * @return {!Promise<XRSession>}
+ */
+XR.prototype.requestSession = function(mode, options) {};
+
+/**
+ * @constructor
+ */
+function XRSession() {}
+
+/**
+ * @type {XRRenderState}
+ */
+XRSession.prototype.renderState;
+
+/**
+ * @type {Array<XRInputSource>}
+ */
+XRSession.prototype.inputSources;
+
+/**
+ * @type {string}
+ */
+XRSession.prototype.visibilityState;
+
+/**
+ * @type {?function (Event)}
+ */
+XRSession.prototype.onend;
+
+/**
+ * @type {?function (XRInputSourcesChangeEvent)}
+ */
+XRSession.prototype.oninputsourceschange;
+
+/**
+ * @type {?function (XRInputSourceEvent)}
+ */
+XRSession.prototype.onselectstart;
+
+/**
+ * @type {?function (XRInputSourceEvent)}
+ */
+XRSession.prototype.onselect;
+
+/**
+ * @type {?function (XRInputSourceEvent)}
+ */
+XRSession.prototype.onselectend;
+
+/**
+ * @type {?function (XRInputSourceEvent)}
+ */
+XRSession.prototype.onsqueezestart;
+
+/**
+ * @type {?function (XRInputSourceEvent)}
+ */
+XRSession.prototype.onsqueeze;
+
+/**
+ * @type {?function (XRInputSourceEvent)}
+ */
+XRSession.prototype.onsqueezeend;
+
+/**
+ * @type {?function (Event)}
+ */
+XRSession.prototype.onvisibilitychange;
+
+/**
+ * @param {XRRenderStateInit} state
+ * @return {void}
+ */
+XRSession.prototype.updateRenderState = function (state) {};
+
+/**
+ * @param {XRFrameRequestCallback} callback
+ * @return {number}
+ */
+XRSession.prototype.requestAnimationFrame = function (callback) {};
+
+/**
+ * @param {number} handle
+ * @return {void}
+ */
+XRSession.prototype.cancelAnimationFrame = function (handle) {};
+
+/**
+ * @return {Promise<void>}
+ */
+XRSession.prototype.end = function () {};
+
+/**
+ * @param {string} referenceSpaceType
+ * @return {Promise<XRReferenceSpace>}
+ */
+XRSession.prototype.requestReferenceSpace = function (referenceSpaceType) {};
+
+/**
+ * @typedef {function(number, XRFrame): undefined}
+ */
+var XRFrameRequestCallback;
+
+/**
+ * @constructor
+ */
+function XRRenderStateInit() {}
+
+/**
+ * @type {number}
+ */
+XRRenderStateInit.prototype.depthNear;
+
+/**
+ * @type {number}
+ */
+XRRenderStateInit.prototype.depthFar;
+
+/**
+ * @type {number}
+ */
+XRRenderStateInit.prototype.inlineVerticalFieldOfView;
+
+/**
+ * @type {?XRWebGLLayer}
+ */
+XRRenderStateInit.prototype.baseLayer;
+
+/**
+ * @constructor
+ */
+function XRRenderState() {};
+
+/**
+ * @type {number}
+ */
+XRRenderState.prototype.depthNear;
+
+/**
+ * @type {number}
+ */
+XRRenderState.prototype.depthFar;
+
+/**
+ * @type {?number}
+ */
+XRRenderState.prototype.inlineVerticalFieldOfView;
+
+/**
+ * @type {?XRWebGLLayer}
+ */
+XRRenderState.prototype.baseLayer;
+
+/**
+ * @constructor
+ */
+function XRFrame() {}
+
+/**
+ * @type {XRSession}
+ */
+XRFrame.prototype.session;
+
+/**
+ * @param {XRReferenceSpace} referenceSpace
+ * @return {?XRViewerPose}
+ */
+XRFrame.prototype.getViewerPose = function (referenceSpace) {};
+
+/**
+ *
+ * @param {XRSpace} space
+ * @param {XRSpace} baseSpace
+ * @return {XRPose}
+ */
+XRFrame.prototype.getPose = function (space, baseSpace) {};
+
+/**
+ * @constructor
+ */
+function XRReferenceSpace() {};
+
+/**
+ * @type {Array<DOMPointReadOnly>}
+ */
+XRReferenceSpace.prototype.boundsGeometry;
+
+/**
+ * @param {XRRigidTransform} originOffset
+ * @return {XRReferenceSpace}
+ */
+XRReferenceSpace.prototype.getOffsetReferenceSpace = function(originOffset) {};
+
+/**
+ * @type {?function (Event)}
+ */
+XRReferenceSpace.prototype.onreset;
+
+/**
+ * @constructor
+ */
+function XRRigidTransform() {};
+
+/**
+ * @type {DOMPointReadOnly}
+ */
+XRRigidTransform.prototype.position;
+
+/**
+ * @type {DOMPointReadOnly}
+ */
+XRRigidTransform.prototype.orientation;
+
+/**
+ * @type {Float32Array}
+ */
+XRRigidTransform.prototype.matrix;
+
+/**
+ * @type {XRRigidTransform}
+ */
+XRRigidTransform.prototype.inverse;
+
+/**
+ * @constructor
+ */
+function XRView() {}
+
+/**
+ * @type {string}
+ */
+XRView.prototype.eye;
+
+/**
+ * @type {Float32Array}
+ */
+XRView.prototype.projectionMatrix;
+
+/**
+ * @type {XRRigidTransform}
+ */
+XRView.prototype.transform;
+
+/**
+ * @constructor
+ */
+function XRViewerPose() {}
+
+/**
+ * @type {Array<XRView>}
+ */
+XRViewerPose.prototype.views;
+
+/**
+ * @constructor
+ */
+function XRViewport() {}
+
+/**
+ * @type {number}
+ */
+XRViewport.prototype.x;
+
+/**
+ * @type {number}
+ */
+XRViewport.prototype.y;
+
+/**
+ * @type {number}
+ */
+XRViewport.prototype.width;
+
+/**
+ * @type {number}
+ */
+XRViewport.prototype.height;
+
+/**
+ * @constructor
+ */
+function XRWebGLLayerInit() {};
+
+/**
+ * @type {boolean}
+ */
+XRWebGLLayerInit.prototype.antialias;
+
+/**
+ * @type {boolean}
+ */
+XRWebGLLayerInit.prototype.depth;
+
+/**
+ * @type {boolean}
+ */
+XRWebGLLayerInit.prototype.stencil;
+
+/**
+ * @type {boolean}
+ */
+XRWebGLLayerInit.prototype.alpha;
+
+/**
+ * @type {boolean}
+ */
+XRWebGLLayerInit.prototype.ignoreDepthValues;
+
+/**
+ * @type {boolean}
+ */
+XRWebGLLayerInit.prototype.ignoreDepthValues;
+
+/**
+ * @type {number}
+ */
+XRWebGLLayerInit.prototype.framebufferScaleFactor;
+
+/**
+ * @constructor
+ *
+ * @param {XRSession} session
+ * @param {WebGLRenderContext|WebGL2RenderingContext} ctx
+ * @param {?XRWebGLLayerInit} options
+ */
+function XRWebGLLayer(session, ctx, options) {}
+
+/**
+ * @type {boolean}
+ */
+XRWebGLLayer.prototype.antialias;
+
+/**
+ * @type {boolean}
+ */
+XRWebGLLayer.prototype.ignoreDepthValues;
+
+/**
+ * @type {number}
+ */
+XRWebGLLayer.prototype.framebufferWidth;
+
+/**
+ * @type {number}
+ */
+XRWebGLLayer.prototype.framebufferHeight;
+
+/**
+ * @type {WebGLFramebuffer}
+ */
+XRWebGLLayer.prototype.framebuffer;
+
+/**
+ * @param {XRView} view
+ * @return {?XRViewport}
+ */
+XRWebGLLayer.prototype.getViewport = function(view) {};
+
+/**
+ * @param {XRSession} session
+ * @return {number}
+ */
+XRWebGLLayer.prototype.getNativeFramebufferScaleFactor = function (session) {};
+
+/**
+ * @constructor
+ */
+function WebGLRenderingContextBase() {};
+
+/**
+ * @return {Promise<void>}
+ */
+WebGLRenderingContextBase.prototype.makeXRCompatible = function () {};
+
+/**
+ * @constructor
+ */
+function XRInputSourcesChangeEvent() {};
+
+/**
+ * @type {Array<XRInputSource>}
+ */
+XRInputSourcesChangeEvent.prototype.added;
+
+/**
+ * @type {Array<XRInputSource>}
+ */
+XRInputSourcesChangeEvent.prototype.removed;
+
+/**
+ * @constructor
+ */
+function XRInputSourceEvent() {};
+
+/**
+ * @type {XRFrame}
+ */
+XRInputSourceEvent.prototype.frame;
+
+/**
+ * @type {XRInputSource}
+ */
+XRInputSourceEvent.prototype.inputSource;
+
+/**
+ * @constructor
+ */
+function XRInputSource() {};
+
+/**
+ * @type {Gamepad}
+ */
+XRInputSource.prototype.gamepad;
+
+/**
+ * @type {XRSpace}
+ */
+XRInputSource.prototype.gripSpace;
+
+/**
+ * @type {string}
+ */
+XRInputSource.prototype.handedness;
+
+/**
+ * @type {string}
+ */
+XRInputSource.prototype.profiles;
+
+/**
+ * @type {string}
+ */
+XRInputSource.prototype.targetRayMode;
+
+/**
+ * @type {XRSpace}
+ */
+XRInputSource.prototype.targetRaySpace;
+
+/**
+ * @constructor
+ */
+function XRSpace() {};
+
+/**
+ * @constructor
+ */
+function XRPose() {};
+
+/**
+ * @type {XRRigidTransform}
+ */
+XRPose.prototype.transform;
+
+/**
+ * @type {boolean}
+ */
+XRPose.prototype.emulatedPosition;
diff --git a/modules/arkit/arkit_module.cpp b/modules/webxr/register_types.cpp
index 87ee3b87a5..8baf7e05b8 100644
--- a/modules/arkit/arkit_module.cpp
+++ b/modules/webxr/register_types.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* arkit_module.cpp */
+/* register_types.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,18 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "arkit_module.h"
+#include "register_types.h"
-#include "arkit_interface.h"
+#include "webxr_interface.h"
+#include "webxr_interface_js.h"
-void register_arkit_types() {
- // does it make sense to register the class?
+void register_webxr_types() {
+ ClassDB::register_virtual_class<WebXRInterface>();
- Ref<ARKitInterface> arkit_interface;
- arkit_interface.instance();
- XRServer::get_singleton()->add_interface(arkit_interface);
+#ifdef JAVASCRIPT_ENABLED
+ Ref<WebXRInterfaceJS> webxr;
+ webxr.instance();
+ XRServer::get_singleton()->add_interface(webxr);
+#endif
}
-void unregister_arkit_types() {
- // should clean itself up nicely :)
+void unregister_webxr_types() {
}
diff --git a/modules/gamecenter/game_center_delegate.h b/modules/webxr/register_types.h
index 1b7025f915..f0c5a4bd79 100644
--- a/modules/gamecenter/game_center_delegate.h
+++ b/modules/webxr/register_types.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* game_center_delegate.h */
+/* register_types.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,8 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#import <GameKit/GameKit.h>
+#ifndef WEBXR_REGISTER_TYPES_H
+#define WEBXR_REGISTER_TYPES_H
-@interface GodotGameCenterDelegate : NSObject <GKGameCenterControllerDelegate>
+void register_webxr_types();
+void unregister_webxr_types();
-@end
+#endif // WEBXR_REGISTER_TYPES_H
diff --git a/modules/webxr/webxr_interface.cpp b/modules/webxr/webxr_interface.cpp
new file mode 100644
index 0000000000..3e8e75bf0e
--- /dev/null
+++ b/modules/webxr/webxr_interface.cpp
@@ -0,0 +1,71 @@
+/*************************************************************************/
+/* webxr_interface.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "webxr_interface.h"
+#include <stdlib.h>
+
+void WebXRInterface::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("is_session_supported", "session_mode"), &WebXRInterface::is_session_supported);
+ ClassDB::bind_method(D_METHOD("set_session_mode", "session_mode"), &WebXRInterface::set_session_mode);
+ ClassDB::bind_method(D_METHOD("get_session_mode"), &WebXRInterface::get_session_mode);
+ ClassDB::bind_method(D_METHOD("set_required_features", "required_features"), &WebXRInterface::set_required_features);
+ ClassDB::bind_method(D_METHOD("get_required_features"), &WebXRInterface::get_required_features);
+ ClassDB::bind_method(D_METHOD("set_optional_features", "optional_features"), &WebXRInterface::set_optional_features);
+ ClassDB::bind_method(D_METHOD("get_optional_features"), &WebXRInterface::get_optional_features);
+ ClassDB::bind_method(D_METHOD("get_reference_space_type"), &WebXRInterface::get_reference_space_type);
+ ClassDB::bind_method(D_METHOD("set_requested_reference_space_types", "requested_reference_space_types"), &WebXRInterface::set_requested_reference_space_types);
+ ClassDB::bind_method(D_METHOD("get_requested_reference_space_types"), &WebXRInterface::get_requested_reference_space_types);
+ ClassDB::bind_method(D_METHOD("get_controller", "controller_id"), &WebXRInterface::get_controller);
+ ClassDB::bind_method(D_METHOD("get_visibility_state"), &WebXRInterface::get_visibility_state);
+ ClassDB::bind_method(D_METHOD("get_bounds_geometry"), &WebXRInterface::get_bounds_geometry);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "session_mode", PROPERTY_HINT_NONE), "set_session_mode", "get_session_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "required_features", PROPERTY_HINT_NONE), "set_required_features", "get_required_features");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "optional_features", PROPERTY_HINT_NONE), "set_optional_features", "get_optional_features");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "requested_reference_space_types", PROPERTY_HINT_NONE), "set_requested_reference_space_types", "get_requested_reference_space_types");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "reference_space_type", PROPERTY_HINT_NONE), "", "get_reference_space_type");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "visibility_state", PROPERTY_HINT_NONE), "", "get_visibility_state");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "bounds_geometry", PROPERTY_HINT_NONE), "", "get_bounds_geometry");
+
+ ADD_SIGNAL(MethodInfo("session_supported", PropertyInfo(Variant::STRING, "session_mode"), PropertyInfo(Variant::BOOL, "supported")));
+ ADD_SIGNAL(MethodInfo("session_started"));
+ ADD_SIGNAL(MethodInfo("session_ended"));
+ ADD_SIGNAL(MethodInfo("session_failed", PropertyInfo(Variant::STRING, "message")));
+
+ ADD_SIGNAL(MethodInfo("selectstart", PropertyInfo(Variant::INT, "controller_id")));
+ ADD_SIGNAL(MethodInfo("select", PropertyInfo(Variant::INT, "controller_id")));
+ ADD_SIGNAL(MethodInfo("selectend", PropertyInfo(Variant::INT, "controller_id")));
+ ADD_SIGNAL(MethodInfo("squeezestart", PropertyInfo(Variant::INT, "controller_id")));
+ ADD_SIGNAL(MethodInfo("squeeze", PropertyInfo(Variant::INT, "controller_id")));
+ ADD_SIGNAL(MethodInfo("squeezeend", PropertyInfo(Variant::INT, "controller_id")));
+
+ ADD_SIGNAL(MethodInfo("visibility_state_changed"));
+ ADD_SIGNAL(MethodInfo("reference_space_reset"));
+}
diff --git a/modules/gamecenter/game_center.h b/modules/webxr/webxr_interface.h
index 76fd295460..c5b2dc8d73 100644
--- a/modules/gamecenter/game_center.h
+++ b/modules/webxr/webxr_interface.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* game_center.h */
+/* webxr_interface.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,44 +28,38 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GAME_CENTER_H
-#define GAME_CENTER_H
+#ifndef WEBXR_INTERFACE_H
+#define WEBXR_INTERFACE_H
-#include "core/object/class_db.h"
+#include "servers/xr/xr_interface.h"
+#include "servers/xr/xr_positional_tracker.h"
-class GameCenter : public Object {
- GDCLASS(GameCenter, Object);
+/**
+ @author David Snopek <david.snopek@snopekgames.com>
- static GameCenter *instance;
- static void _bind_methods();
-
- List<Variant> pending_events;
+ The WebXR interface is a VR/AR interface that can be used on the web.
+*/
- bool authenticated;
+class WebXRInterface : public XRInterface {
+ GDCLASS(WebXRInterface, XRInterface);
- void return_connect_error(const char *p_error_description);
+protected:
+ static void _bind_methods();
public:
- Error authenticate();
- bool is_authenticated();
-
- Error post_score(Dictionary p_score);
- Error award_achievement(Dictionary p_params);
- void reset_achievements();
- void request_achievements();
- void request_achievement_descriptions();
- Error show_game_center(Dictionary p_params);
- Error request_identity_verification_signature();
-
- void game_center_closed();
-
- int get_pending_event_count();
- Variant pop_pending_event();
-
- static GameCenter *get_singleton();
-
- GameCenter();
- ~GameCenter();
+ virtual void is_session_supported(const String &p_session_mode) = 0;
+ virtual void set_session_mode(String p_session_mode) = 0;
+ virtual String get_session_mode() const = 0;
+ virtual void set_required_features(String p_required_features) = 0;
+ virtual String get_required_features() const = 0;
+ virtual void set_optional_features(String p_optional_features) = 0;
+ virtual String get_optional_features() const = 0;
+ virtual void set_requested_reference_space_types(String p_requested_reference_space_types) = 0;
+ virtual String get_requested_reference_space_types() const = 0;
+ virtual String get_reference_space_type() const = 0;
+ virtual XRPositionalTracker *get_controller(int p_controller_id) const = 0;
+ virtual String get_visibility_state() const = 0;
+ virtual PackedVector3Array get_bounds_geometry() const = 0;
};
-#endif
+#endif // WEBXR_INTERFACE_H
diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp
new file mode 100644
index 0000000000..74789fc98e
--- /dev/null
+++ b/modules/webxr/webxr_interface_js.cpp
@@ -0,0 +1,460 @@
+/*************************************************************************/
+/* webxr_interface_js.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef JAVASCRIPT_ENABLED
+
+#include "webxr_interface_js.h"
+#include "core/input/input.h"
+#include "core/os/os.h"
+#include "emscripten.h"
+#include "godot_webxr.h"
+#include <stdlib.h>
+
+void _emwebxr_on_session_supported(char *p_session_mode, int p_supported) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ Ref<XRInterface> interface = xr_server->find_interface("WebXR");
+ ERR_FAIL_COND(interface.is_null());
+
+ String session_mode = String(p_session_mode);
+ interface->emit_signal("session_supported", session_mode, p_supported ? true : false);
+}
+
+void _emwebxr_on_session_started(char *p_reference_space_type) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ Ref<XRInterface> interface = xr_server->find_interface("WebXR");
+ ERR_FAIL_COND(interface.is_null());
+
+ String reference_space_type = String(p_reference_space_type);
+ ((WebXRInterfaceJS *)interface.ptr())->_set_reference_space_type(reference_space_type);
+ interface->emit_signal("session_started");
+}
+
+void _emwebxr_on_session_ended() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ Ref<XRInterface> interface = xr_server->find_interface("WebXR");
+ ERR_FAIL_COND(interface.is_null());
+
+ interface->uninitialize();
+ interface->emit_signal("session_ended");
+}
+
+void _emwebxr_on_session_failed(char *p_message) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ Ref<XRInterface> interface = xr_server->find_interface("WebXR");
+ ERR_FAIL_COND(interface.is_null());
+
+ interface->uninitialize();
+
+ String message = String(p_message);
+ interface->emit_signal("session_failed", message);
+}
+
+void _emwebxr_on_controller_changed() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ Ref<XRInterface> interface = xr_server->find_interface("WebXR");
+ ERR_FAIL_COND(interface.is_null());
+
+ ((WebXRInterfaceJS *)interface.ptr())->_on_controller_changed();
+}
+
+extern "C" EMSCRIPTEN_KEEPALIVE void _emwebxr_on_input_event(char *p_signal_name, int p_input_source) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ Ref<XRInterface> interface = xr_server->find_interface("WebXR");
+ ERR_FAIL_COND(interface.is_null());
+
+ StringName signal_name = StringName(p_signal_name);
+ interface->emit_signal(signal_name, p_input_source + 1);
+}
+
+extern "C" EMSCRIPTEN_KEEPALIVE void _emwebxr_on_simple_event(char *p_signal_name) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ Ref<XRInterface> interface = xr_server->find_interface("WebXR");
+ ERR_FAIL_COND(interface.is_null());
+
+ StringName signal_name = StringName(p_signal_name);
+ interface->emit_signal(signal_name);
+}
+
+void WebXRInterfaceJS::is_session_supported(const String &p_session_mode) {
+ godot_webxr_is_session_supported(p_session_mode.utf8().get_data(), &_emwebxr_on_session_supported);
+}
+
+void WebXRInterfaceJS::set_session_mode(String p_session_mode) {
+ session_mode = p_session_mode;
+}
+
+String WebXRInterfaceJS::get_session_mode() const {
+ return session_mode;
+}
+
+void WebXRInterfaceJS::set_required_features(String p_required_features) {
+ required_features = p_required_features;
+}
+
+String WebXRInterfaceJS::get_required_features() const {
+ return required_features;
+}
+
+void WebXRInterfaceJS::set_optional_features(String p_optional_features) {
+ optional_features = p_optional_features;
+}
+
+String WebXRInterfaceJS::get_optional_features() const {
+ return optional_features;
+}
+
+void WebXRInterfaceJS::set_requested_reference_space_types(String p_requested_reference_space_types) {
+ requested_reference_space_types = p_requested_reference_space_types;
+}
+
+String WebXRInterfaceJS::get_requested_reference_space_types() const {
+ return requested_reference_space_types;
+}
+
+void WebXRInterfaceJS::_set_reference_space_type(String p_reference_space_type) {
+ reference_space_type = p_reference_space_type;
+}
+
+String WebXRInterfaceJS::get_reference_space_type() const {
+ return reference_space_type;
+}
+
+XRPositionalTracker *WebXRInterfaceJS::get_controller(int p_controller_id) const {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, nullptr);
+
+ return xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+}
+
+String WebXRInterfaceJS::get_visibility_state() const {
+ char *c_str = godot_webxr_get_visibility_state();
+ if (c_str) {
+ String visibility_state = String(c_str);
+ free(c_str);
+
+ return visibility_state;
+ }
+ return String();
+}
+
+PackedVector3Array WebXRInterfaceJS::get_bounds_geometry() const {
+ PackedVector3Array ret;
+
+ int *js_bounds = godot_webxr_get_bounds_geometry();
+ if (js_bounds) {
+ ret.resize(js_bounds[0]);
+ for (int i = 0; i < js_bounds[0]; i++) {
+ float *js_vector3 = ((float *)js_bounds) + (i * 3) + 1;
+ ret.set(i, Vector3(js_vector3[0], js_vector3[1], js_vector3[2]));
+ }
+ free(js_bounds);
+ }
+
+ return ret;
+}
+
+StringName WebXRInterfaceJS::get_name() const {
+ return "WebXR";
+};
+
+int WebXRInterfaceJS::get_capabilities() const {
+ return XRInterface::XR_STEREO | XRInterface::XR_MONO;
+};
+
+bool WebXRInterfaceJS::is_stereo() {
+ return godot_webxr_get_view_count() == 2;
+};
+
+bool WebXRInterfaceJS::is_initialized() const {
+ return (initialized);
+};
+
+bool WebXRInterfaceJS::initialize() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, false);
+
+ if (!initialized) {
+ if (!godot_webxr_is_supported()) {
+ return false;
+ }
+
+ if (requested_reference_space_types.size() == 0) {
+ return false;
+ }
+
+ // make this our primary interface
+ xr_server->set_primary_interface(this);
+
+ // Clear render_targetsize to make sure it gets reset to the new size.
+ // Clearing in uninitialize() doesn't work because a frame can still be
+ // rendered after it's called, which will fill render_targetsize again.
+ render_targetsize.width = 0;
+ render_targetsize.height = 0;
+
+ initialized = true;
+
+ godot_webxr_initialize(
+ session_mode.utf8().get_data(),
+ required_features.utf8().get_data(),
+ optional_features.utf8().get_data(),
+ requested_reference_space_types.utf8().get_data(),
+ &_emwebxr_on_session_started,
+ &_emwebxr_on_session_ended,
+ &_emwebxr_on_session_failed,
+ &_emwebxr_on_controller_changed,
+ &_emwebxr_on_input_event,
+ &_emwebxr_on_simple_event);
+ };
+
+ return true;
+};
+
+void WebXRInterfaceJS::uninitialize() {
+ if (initialized) {
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != NULL) {
+ // no longer our primary interface
+ xr_server->clear_primary_interface_if(this);
+ }
+
+ godot_webxr_uninitialize();
+
+ reference_space_type = "";
+ initialized = false;
+ };
+};
+
+Transform WebXRInterfaceJS::_js_matrix_to_transform(float *p_js_matrix) {
+ Transform transform;
+
+ transform.basis.elements[0].x = p_js_matrix[0];
+ transform.basis.elements[1].x = p_js_matrix[1];
+ transform.basis.elements[2].x = p_js_matrix[2];
+ transform.basis.elements[0].y = p_js_matrix[4];
+ transform.basis.elements[1].y = p_js_matrix[5];
+ transform.basis.elements[2].y = p_js_matrix[6];
+ transform.basis.elements[0].z = p_js_matrix[8];
+ transform.basis.elements[1].z = p_js_matrix[9];
+ transform.basis.elements[2].z = p_js_matrix[10];
+ transform.origin.x = p_js_matrix[12];
+ transform.origin.y = p_js_matrix[13];
+ transform.origin.z = p_js_matrix[14];
+
+ return transform;
+}
+
+Size2 WebXRInterfaceJS::get_render_targetsize() {
+ if (render_targetsize.width != 0 && render_targetsize.height != 0) {
+ return render_targetsize;
+ }
+
+ int *js_size = godot_webxr_get_render_targetsize();
+ if (!initialized || js_size == nullptr) {
+ // As a temporary default (until WebXR is fully initialized), use half the window size.
+ Size2 temp = DisplayServer::get_singleton()->window_get_size();
+ temp.width /= 2.0;
+ return temp;
+ }
+
+ render_targetsize.width = js_size[0];
+ render_targetsize.height = js_size[1];
+
+ free(js_size);
+
+ return render_targetsize;
+};
+
+Transform WebXRInterfaceJS::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) {
+ Transform transform_for_eye;
+
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, transform_for_eye);
+
+ float *js_matrix = godot_webxr_get_transform_for_eye(p_eye);
+ if (!initialized || js_matrix == nullptr) {
+ transform_for_eye = p_cam_transform;
+ return transform_for_eye;
+ }
+
+ transform_for_eye = _js_matrix_to_transform(js_matrix);
+ free(js_matrix);
+
+ return p_cam_transform * xr_server->get_reference_frame() * transform_for_eye;
+};
+
+CameraMatrix WebXRInterfaceJS::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+ CameraMatrix eye;
+
+ float *js_matrix = godot_webxr_get_projection_for_eye(p_eye);
+ if (!initialized || js_matrix == nullptr) {
+ return eye;
+ }
+
+ int k = 0;
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ eye.matrix[i][j] = js_matrix[k++];
+ }
+ }
+
+ free(js_matrix);
+
+ // Copied from godot_oculus_mobile's ovr_mobile_session.cpp
+ eye.matrix[2][2] = -(p_z_far + p_z_near) / (p_z_far - p_z_near);
+ eye.matrix[3][2] = -(2.0f * p_z_far * p_z_near) / (p_z_far - p_z_near);
+
+ return eye;
+}
+
+unsigned int WebXRInterfaceJS::get_external_texture_for_eye(XRInterface::Eyes p_eye) {
+ if (!initialized) {
+ return 0;
+ }
+ return godot_webxr_get_external_texture_for_eye(p_eye);
+}
+
+void WebXRInterfaceJS::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+ if (!initialized) {
+ return;
+ }
+ godot_webxr_commit_for_eye(p_eye);
+};
+
+void WebXRInterfaceJS::process() {
+ if (initialized) {
+ godot_webxr_sample_controller_data();
+
+ int controller_count = godot_webxr_get_controller_count();
+ if (controller_count == 0) {
+ return;
+ }
+
+ for (int i = 0; i < controller_count; i++) {
+ _update_tracker(i);
+ }
+ };
+};
+
+void WebXRInterfaceJS::_update_tracker(int p_controller_id) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id + 1);
+ if (godot_webxr_is_controller_connected(p_controller_id)) {
+ if (tracker == nullptr) {
+ tracker = memnew(XRPositionalTracker);
+ tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
+ // Controller id's 0 and 1 are always the left and right hands.
+ if (p_controller_id < 2) {
+ tracker->set_tracker_name(p_controller_id == 0 ? "Left" : "Right");
+ tracker->set_tracker_hand(p_controller_id == 0 ? XRPositionalTracker::TRACKER_HAND_LEFT : XRPositionalTracker::TRACKER_HAND_RIGHT);
+ }
+ // Use the ids we're giving to our "virtual" gamepads.
+ tracker->set_joy_id(p_controller_id + 100);
+ xr_server->add_tracker(tracker);
+ }
+
+ Input *input = Input::get_singleton();
+
+ float *tracker_matrix = godot_webxr_get_controller_transform(p_controller_id);
+ if (tracker_matrix) {
+ Transform transform = _js_matrix_to_transform(tracker_matrix);
+ tracker->set_position(transform.origin);
+ tracker->set_orientation(transform.basis);
+ free(tracker_matrix);
+ }
+
+ int *buttons = godot_webxr_get_controller_buttons(p_controller_id);
+ if (buttons) {
+ for (int i = 0; i < buttons[0]; i++) {
+ input->joy_button(p_controller_id + 100, i, *((float *)buttons + (i + 1)));
+ }
+ free(buttons);
+ }
+
+ int *axes = godot_webxr_get_controller_axes(p_controller_id);
+ if (axes) {
+ for (int i = 0; i < axes[0]; i++) {
+ Input::JoyAxis joy_axis;
+ joy_axis.min = -1;
+ joy_axis.value = *((float *)axes + (i + 1));
+ input->joy_axis(p_controller_id + 100, i, joy_axis);
+ }
+ free(axes);
+ }
+ } else if (tracker) {
+ xr_server->remove_tracker(tracker);
+ }
+}
+
+void WebXRInterfaceJS::_on_controller_changed() {
+ // Register "virtual" gamepads with Godot for the ones we get from WebXR.
+ godot_webxr_sample_controller_data();
+ for (int i = 0; i < 2; i++) {
+ bool controller_connected = godot_webxr_is_controller_connected(i);
+ if (controllers_state[i] != controller_connected) {
+ Input::get_singleton()->joy_connection_changed(i + 100, controller_connected, i == 0 ? "Left" : "Right", "");
+ controllers_state[i] = controller_connected;
+ }
+ }
+}
+
+void WebXRInterfaceJS::notification(int p_what) {
+ // Nothing to do here.
+}
+
+WebXRInterfaceJS::WebXRInterfaceJS() {
+ initialized = false;
+ session_mode = "inline";
+ requested_reference_space_types = "local";
+};
+
+WebXRInterfaceJS::~WebXRInterfaceJS() {
+ // and make sure we cleanup if we haven't already
+ if (initialized) {
+ uninitialize();
+ };
+};
+
+#endif // JAVASCRIPT_ENABLED
diff --git a/modules/arkit/arkit_interface.h b/modules/webxr/webxr_interface_js.h
index 29e09411ff..49299b252f 100644
--- a/modules/arkit/arkit_interface.h
+++ b/modules/webxr/webxr_interface_js.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* arkit_interface.h */
+/* webxr_interface_js.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,85 +28,52 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARKIT_INTERFACE_H
-#define ARKIT_INTERFACE_H
+#ifndef WEBXR_INTERFACE_JS_H
+#define WEBXR_INTERFACE_JS_H
-#include "servers/camera/camera_feed.h"
-#include "servers/xr/xr_interface.h"
-#include "servers/xr/xr_positional_tracker.h"
+#ifdef JAVASCRIPT_ENABLED
+
+#include "webxr_interface.h"
/**
- @author Bastiaan Olij <mux213@gmail.com>
+ @author David Snopek <david.snopek@snopekgames.com>
- ARKit interface between iPhone and Godot
+ The WebXR interface is a VR/AR interface that can be used on the web.
*/
-// forward declaration for some needed objects
-class ARKitShader;
-
-#ifdef __OBJC__
-
-typedef ARAnchor GodotARAnchor;
-
-#else
-
-typedef void GodotARAnchor;
-#endif
-
-class ARKitInterface : public XRInterface {
- GDCLASS(ARKitInterface, XRInterface);
+class WebXRInterfaceJS : public WebXRInterface {
+ GDCLASS(WebXRInterfaceJS, WebXRInterface);
private:
bool initialized;
- bool session_was_started;
- bool plane_detection_is_enabled;
- bool light_estimation_is_enabled;
- real_t ambient_intensity;
- real_t ambient_color_temperature;
-
- Transform transform;
- CameraMatrix projection;
- float eye_height, z_near, z_far;
-
- Ref<CameraFeed> feed;
- size_t image_width[2];
- size_t image_height[2];
- Vector<uint8_t> img_data[2];
-
- struct anchor_map {
- XRPositionalTracker *tracker;
- unsigned char uuid[16];
- };
-
- ///@TODO should use memory map object from Godot?
- unsigned int num_anchors;
- unsigned int max_anchors;
- anchor_map *anchors;
- XRPositionalTracker *get_anchor_for_uuid(const unsigned char *p_uuid);
- void remove_anchor_for_uuid(const unsigned char *p_uuid);
- void remove_all_anchors();
-
-protected:
- static void _bind_methods();
-public:
- void start_session();
- void stop_session();
+ String session_mode;
+ String required_features;
+ String optional_features;
+ String requested_reference_space_types;
+ String reference_space_type;
- bool get_anchor_detection_is_enabled() const override;
- void set_anchor_detection_is_enabled(bool p_enable) override;
- virtual int get_camera_feed_id() override;
+ bool controllers_state[2];
+ Size2 render_targetsize;
- bool get_light_estimation_is_enabled() const;
- void set_light_estimation_is_enabled(bool p_enable);
+ Transform _js_matrix_to_transform(float *p_js_matrix);
+ void _update_tracker(int p_controller_id);
- real_t get_ambient_intensity() const;
- real_t get_ambient_color_temperature() const;
-
- /* while Godot has its own raycast logic this takes ARKits camera into account and hits on any ARAnchor */
- Array raycast(Vector2 p_screen_coord);
-
- virtual void notification(int p_what) override;
+public:
+ virtual void is_session_supported(const String &p_session_mode) override;
+ virtual void set_session_mode(String p_session_mode) override;
+ virtual String get_session_mode() const override;
+ virtual void set_required_features(String p_required_features) override;
+ virtual String get_required_features() const override;
+ virtual void set_optional_features(String p_optional_features) override;
+ virtual String get_optional_features() const override;
+ virtual void set_requested_reference_space_types(String p_requested_reference_space_types) override;
+ virtual String get_requested_reference_space_types() const override;
+ void _set_reference_space_type(String p_reference_space_type);
+ virtual String get_reference_space_type() const override;
+ virtual XRPositionalTracker *get_controller(int p_controller_id) const override;
+ virtual String get_visibility_state() const override;
+ virtual PackedVector3Array get_bounds_geometry() const override;
virtual StringName get_name() const override;
virtual int get_capabilities() const override;
@@ -119,16 +86,18 @@ public:
virtual bool is_stereo() override;
virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) override;
virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) override;
+ virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye) override;
virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) override;
virtual void process() override;
+ virtual void notification(int p_what) override;
- // called by delegate (void * because C++ and Obj-C don't always mix, should really change all platform/iphone/*.cpp files to .mm)
- void _add_or_update_anchor(GodotARAnchor *p_anchor);
- void _remove_anchor(GodotARAnchor *p_anchor);
+ void _on_controller_changed();
- ARKitInterface();
- ~ARKitInterface();
+ WebXRInterfaceJS();
+ ~WebXRInterfaceJS();
};
-#endif /* !ARKIT_INTERFACE_H */
+#endif // JAVASCRIPT_ENABLED
+
+#endif // WEBXR_INTERFACE_JS_H
diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp
index 224038d604..fb4df10904 100644
--- a/modules/xatlas_unwrap/register_types.cpp
+++ b/modules/xatlas_unwrap/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -154,6 +154,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
float h = *r_size_hint_y;
if (w == 0 || h == 0) {
+ xatlas::Destroy(atlas);
return false; //could not bake because there is no area
}
@@ -163,8 +164,8 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
*r_uvs = (float *)malloc(sizeof(float) * output.vertexCount * 2);
*r_indices = (int *)malloc(sizeof(int) * output.indexCount);
- float max_x = 0;
- float max_y = 0;
+ float max_x = 0.0;
+ float max_y = 0.0;
for (uint32_t i = 0; i < output.vertexCount; i++) {
(*r_vertices)[i] = output.vertexArray[i].xref;
(*r_uvs)[i * 2 + 0] = output.vertexArray[i].uv[0] / w;
diff --git a/modules/xatlas_unwrap/register_types.h b/modules/xatlas_unwrap/register_types.h
index fe924bab96..2ad729f172 100644
--- a/modules/xatlas_unwrap/register_types.h
+++ b/modules/xatlas_unwrap/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/android_keys_utils.cpp b/platform/android/android_keys_utils.cpp
index b5b4fb9a4b..5aa546c17b 100644
--- a/platform/android/android_keys_utils.cpp
+++ b/platform/android/android_keys_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h
index 4a34e77324..e0ee2888c0 100644
--- a/platform/android/android_keys_utils.h
+++ b/platform/android/android_keys_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp
index 8b82733d2d..d3c49c6eb7 100644
--- a/platform/android/api/api.cpp
+++ b/platform/android/api/api.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/api/api.h b/platform/android/api/api.h
index 5e951b9c88..fe3a6734ac 100644
--- a/platform/android/api/api.h
+++ b/platform/android/api/api.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/api/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h
index 63d71f5cf1..d6c7a1abe5 100644
--- a/platform/android/api/java_class_wrapper.h
+++ b/platform/android/api/java_class_wrapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h
index 7f20c354a0..965eaabf81 100644
--- a/platform/android/api/jni_singleton.h
+++ b/platform/android/api/jni_singleton.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -83,7 +83,7 @@ public:
v = (jvalue *)alloca(sizeof(jvalue) * p_argcount);
}
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
int res = env->PushLocalFrame(16);
diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp
index 1363c5ac1e..3a2ccac481 100644
--- a/platform/android/audio_driver_jandroid.cpp
+++ b/platform/android/audio_driver_jandroid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -72,10 +72,10 @@ Error AudioDriverAndroid::init() {
// __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
- JNIEnv *env = ThreadAndroid::get_env();
- int mix_rate = GLOBAL_GET("audio/mix_rate");
+ JNIEnv *env = get_jni_env();
+ int mix_rate = GLOBAL_GET("audio/driver/mix_rate");
- int latency = GLOBAL_GET("audio/output_latency");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
unsigned int buffer_size = next_power_of_2(latency * mix_rate / 1000);
print_verbose("Audio buffer size: " + itos(buffer_size));
@@ -98,7 +98,7 @@ void AudioDriverAndroid::start() {
}
void AudioDriverAndroid::setup(jobject p_io) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
io = p_io;
jclass c = env->GetObjectClass(io);
@@ -162,7 +162,7 @@ void AudioDriverAndroid::unlock() {
}
void AudioDriverAndroid::finish() {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(io, _quit);
if (audioBuffer) {
@@ -175,7 +175,7 @@ void AudioDriverAndroid::finish() {
}
void AudioDriverAndroid::set_pause(bool p_pause) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(io, _pause, p_pause);
}
diff --git a/platform/android/audio_driver_jandroid.h b/platform/android/audio_driver_jandroid.h
index 953ade9311..9007fd2f81 100644
--- a/platform/android/audio_driver_jandroid.h
+++ b/platform/android/audio_driver_jandroid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index e96e80e967..a1d8fb4810 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h
index 999cbe4657..e3efaddba2 100644
--- a/platform/android/audio_driver_opensl.h
+++ b/platform/android/audio_driver_opensl.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 650606ff8b..5f0fcc9b77 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -13,7 +13,7 @@ def get_name():
def can_build():
- return "ANDROID_NDK_ROOT" in os.environ
+ return ("ANDROID_SDK_ROOT" in os.environ) or ("ANDROID_HOME" in os.environ)
def get_platform(platform):
@@ -24,13 +24,33 @@ def get_opts():
from SCons.Variables import BoolVariable, EnumVariable
return [
- ("ANDROID_NDK_ROOT", "Path to the Android NDK", os.environ.get("ANDROID_NDK_ROOT", 0)),
+ ("ANDROID_NDK_ROOT", "Path to the Android NDK", get_android_ndk_root()),
+ ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_android_sdk_root()),
("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")),
BoolVariable("android_neon", "Enable NEON support (armv7 only)", True),
]
+# Return the ANDROID_SDK_ROOT environment variable.
+# While ANDROID_HOME has been deprecated, it's used as a fallback for backward
+# compatibility purposes.
+def get_android_sdk_root():
+ if "ANDROID_SDK_ROOT" in os.environ:
+ return os.environ.get("ANDROID_SDK_ROOT", 0)
+ else:
+ return os.environ.get("ANDROID_HOME", 0)
+
+
+# Return the ANDROID_NDK_ROOT environment variable.
+# We generate one for this build using the ANDROID_SDK_ROOT env
+# variable and the project ndk version.
+# If the env variable is already defined, we override it with
+# our own to match what the project expects.
+def get_android_ndk_root():
+ return get_android_sdk_root() + "/ndk/" + get_project_ndk_version()
+
+
def get_flags():
return [
("tools", False),
@@ -47,7 +67,31 @@ def create(env):
return env.Clone(tools=tools)
+# Check if ANDROID_NDK_ROOT is valid.
+# If not, install the ndk using ANDROID_SDK_ROOT and sdkmanager.
+def install_ndk_if_needed(env):
+ print("Checking for Android NDK...")
+ env_ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"])
+ if env_ndk_version is None:
+ # Reinstall the ndk and update ANDROID_NDK_ROOT.
+ print("Installing Android NDK...")
+ if env["ANDROID_SDK_ROOT"] is None:
+ raise Exception("Invalid ANDROID_SDK_ROOT environment variable.")
+
+ import subprocess
+
+ extension = ".bat" if os.name == "nt" else ""
+ sdkmanager_path = env["ANDROID_SDK_ROOT"] + "/cmdline-tools/latest/bin/sdkmanager" + extension
+ ndk_download_args = "ndk;" + get_project_ndk_version()
+ subprocess.check_call([sdkmanager_path, ndk_download_args])
+
+ env["ANDROID_NDK_ROOT"] = env["ANDROID_SDK_ROOT"] + "/ndk/" + get_project_ndk_version()
+ print("ANDROID_NDK_ROOT: " + env["ANDROID_NDK_ROOT"])
+
+
def configure(env):
+ install_ndk_if_needed(env)
+
# Workaround for MinGW. See:
# http://www.scons.org/wiki/LongCmdLinesOnWin32
if os.name == "nt":
@@ -270,7 +314,7 @@ def configure(env):
# Link flags
- ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
+ ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"])
if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
env.Append(LINKFLAGS=["-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a", "-nostdlib++"])
else:
@@ -323,8 +367,14 @@ def configure(env):
env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "vulkan", "android", "log", "z", "dl"])
+# Return the project NDK version.
+# This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
+def get_project_ndk_version():
+ return "21.4.7075529"
+
+
# Return NDK version string in source.properties (adapted from the Chromium project).
-def get_ndk_version(path):
+def get_env_ndk_version(path):
if path is None:
return None
prop_file_path = os.path.join(path, "source.properties")
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index ac619973d2..f8ac29c738 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,7 @@ DirAccess *DirAccessJAndroid::create_fs() {
Error DirAccessJAndroid::list_dir_begin() {
list_dir_end();
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring js = env->NewStringUTF(current_dir.utf8().get_data());
int res = env->CallIntMethod(io, _dir_open, js);
@@ -62,7 +62,7 @@ Error DirAccessJAndroid::list_dir_begin() {
String DirAccessJAndroid::get_next() {
ERR_FAIL_COND_V(id == 0, "");
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring str = (jstring)env->CallObjectMethod(io, _dir_next, id);
if (!str)
return "";
@@ -73,7 +73,7 @@ String DirAccessJAndroid::get_next() {
}
bool DirAccessJAndroid::current_is_dir() const {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallBooleanMethod(io, _dir_is_dir, id);
}
@@ -86,7 +86,7 @@ void DirAccessJAndroid::list_dir_end() {
if (id == 0)
return;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(io, _dir_close, id);
id = 0;
}
@@ -100,7 +100,7 @@ String DirAccessJAndroid::get_drive(int p_drive) {
}
Error DirAccessJAndroid::change_dir(String p_dir) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == ""))
return OK;
@@ -154,7 +154,7 @@ bool DirAccessJAndroid::file_exists(String p_file) {
}
bool DirAccessJAndroid::dir_exists(String p_dir) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
String sd;
@@ -207,7 +207,7 @@ size_t DirAccessJAndroid::get_space_left() {
}
void DirAccessJAndroid::setup(jobject p_io) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
io = p_io;
jclass c = env->GetObjectClass(io);
diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h
index 7d0def137a..fed468d051 100644
--- a/platform/android/dir_access_jandroid.h
+++ b/platform/android/dir_access_jandroid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 8711a4333c..5f7e5eaa83 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index f1f1a6a278..b9d1641656 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index eed3b226c8..326e513261 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,6 +37,7 @@
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
+#include "core/templates/safe_refcount.h"
#include "core/version.h"
#include "drivers/png/png_driver_common.h"
#include "editor/editor_export.h"
@@ -202,6 +203,19 @@ static const char *android_perms[] = {
static const char *SPLASH_IMAGE_EXPORT_PATH = "res/drawable/splash.png";
static const char *SPLASH_BG_COLOR_PATH = "res/drawable/splash_bg_color.png";
+static const char *SPLASH_CONFIG_PATH = "res://android/build/res/drawable/splash_drawable.xml";
+
+const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/splash_bg_color" />
+ <item>
+ <bitmap
+ android:gravity="%s"
+ android:filter="%s"
+ android:src="@drawable/splash" />
+ </item>
+</layer-list>
+)SPLASH";
struct LauncherIcon {
const char *export_path;
@@ -240,6 +254,9 @@ static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_coun
{ "res/mipmap/icon_background.png", 432 }
};
+static const int EXPORT_FORMAT_APK = 0;
+static const int EXPORT_FORMAT_AAB = 1;
+
class EditorExportPlatformAndroid : public EditorExportPlatform {
GDCLASS(EditorExportPlatformAndroid, EditorExportPlatform);
@@ -258,54 +275,54 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
EditorProgress *ep = nullptr;
};
- Vector<PluginConfig> plugins;
+ Vector<PluginConfigAndroid> plugins;
String last_plugin_names;
uint64_t last_custom_build_time = 0;
- volatile bool plugins_changed;
+ SafeFlag plugins_changed;
Mutex plugins_lock;
Vector<Device> devices;
- volatile bool devices_changed;
+ SafeFlag devices_changed;
Mutex device_lock;
- Thread *check_for_changes_thread;
- volatile bool quit_request;
+ Thread check_for_changes_thread;
+ SafeFlag quit_request;
static void _check_for_changes_poll_thread(void *ud) {
EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
- while (!ea->quit_request) {
+ while (!ea->quit_request.is_set()) {
// Check for plugins updates
{
// Nothing to do if we already know the plugins have changed.
- if (!ea->plugins_changed) {
- Vector<PluginConfig> loaded_plugins = get_plugins();
+ if (!ea->plugins_changed.is_set()) {
+ Vector<PluginConfigAndroid> loaded_plugins = get_plugins();
MutexLock lock(ea->plugins_lock);
if (ea->plugins.size() != loaded_plugins.size()) {
- ea->plugins_changed = true;
+ ea->plugins_changed.set();
} else {
for (int i = 0; i < ea->plugins.size(); i++) {
if (ea->plugins[i].name != loaded_plugins[i].name) {
- ea->plugins_changed = true;
+ ea->plugins_changed.set();
break;
}
}
}
- if (ea->plugins_changed) {
+ if (ea->plugins_changed.is_set()) {
ea->plugins = loaded_plugins;
}
}
}
// Check for devices updates
- String adb = EditorSettings::get_singleton()->get("export/android/adb");
+ String adb = get_adb_path();
if (FileAccess::exists(adb)) {
String devices;
List<String> args;
args.push_back("devices");
int ec;
- OS::get_singleton()->execute(adb, args, true, nullptr, &devices, &ec);
+ OS::get_singleton()->execute(adb, args, &devices, &ec);
Vector<String> ds = devices.split("\n");
Vector<String> ldevices;
@@ -358,7 +375,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
int ec2;
String dp;
- OS::get_singleton()->execute(adb, args, true, nullptr, &dp, &ec2);
+ OS::get_singleton()->execute(adb, args, &dp, &ec2);
Vector<String> props = dp.split("\n");
String vendor;
@@ -406,7 +423,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
ea->devices = ndevices;
- ea->devices_changed = true;
+ ea->devices_changed.set();
}
}
@@ -415,21 +432,21 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
uint64_t time = OS::get_singleton()->get_ticks_usec();
while (OS::get_singleton()->get_ticks_usec() - time < wait) {
OS::get_singleton()->delay_usec(1000 * sleep);
- if (ea->quit_request) {
+ if (ea->quit_request.is_set()) {
break;
}
}
}
if (EditorSettings::get_singleton()->get("export/android/shutdown_adb_on_exit")) {
- String adb = EditorSettings::get_singleton()->get("export/android/adb");
+ String adb = get_adb_path();
if (!FileAccess::exists(adb)) {
return; //adb not configured
}
List<String> args;
args.push_back("kill-server");
- OS::get_singleton()->execute(adb, args, true);
+ OS::get_singleton()->execute(adb, args);
};
}
@@ -626,7 +643,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
continue;
}
- if (file.ends_with(PLUGIN_CONFIG_EXT)) {
+ if (file.ends_with(PluginConfigAndroid::PLUGIN_CONFIG_EXT)) {
dir_files.push_back(file);
}
}
@@ -636,8 +653,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
return dir_files;
}
- static Vector<PluginConfig> get_plugins() {
- Vector<PluginConfig> loaded_plugins;
+ static Vector<PluginConfigAndroid> get_plugins() {
+ Vector<PluginConfigAndroid> loaded_plugins;
String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("android/plugins");
@@ -647,10 +664,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
if (DirAccess::exists(plugins_dir)) {
Vector<String> plugins_filenames = list_gdap_files(plugins_dir);
- if (!plugins_filenames.empty()) {
+ if (!plugins_filenames.is_empty()) {
Ref<ConfigFile> config_file = memnew(ConfigFile);
for (int i = 0; i < plugins_filenames.size(); i++) {
- PluginConfig config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
+ PluginConfigAndroid config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
if (config.valid_config) {
loaded_plugins.push_back(config);
} else {
@@ -663,11 +680,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
return loaded_plugins;
}
- static Vector<PluginConfig> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
- Vector<PluginConfig> enabled_plugins;
- Vector<PluginConfig> all_plugins = get_plugins();
+ static Vector<PluginConfigAndroid> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
+ Vector<PluginConfigAndroid> enabled_plugins;
+ Vector<PluginConfigAndroid> all_plugins = get_plugins();
for (int i = 0; i < all_plugins.size(); i++) {
- PluginConfig plugin = all_plugins[i];
+ PluginConfigAndroid plugin = all_plugins[i];
bool enabled = p_presets->get("plugins/" + plugin.name);
if (enabled) {
enabled_plugins.push_back(plugin);
@@ -750,7 +767,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
PackedStringArray user_perms = p_preset->get("permissions/custom_permissions");
for (int i = 0; i < user_perms.size(); i++) {
String user_perm = user_perms[i].strip_edges();
- if (!user_perm.empty()) {
+ if (!user_perm.is_empty()) {
r_permissions.push_back(user_perm);
}
}
@@ -772,6 +789,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
void _write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug) {
+ print_verbose("Building temporary manifest..");
String manifest_text =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
@@ -788,10 +806,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
manifest_text += _get_xr_features_tag(p_preset);
manifest_text += _get_instrumentation_tag(p_preset);
- String plugins_names = get_plugins_names(get_enabled_plugins(p_preset));
- manifest_text += _get_application_tag(p_preset, plugins_names);
+ manifest_text += _get_application_tag(p_preset);
manifest_text += "</manifest>\n";
String manifest_path = vformat("res://android/build/src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release"));
+
+ print_verbose("Storing manifest into " + manifest_path + ": " + "\n" + manifest_text);
store_string_at_path(manifest_path, manifest_text);
}
@@ -836,8 +855,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
int xr_mode_index = p_preset->get("xr_features/xr_mode");
bool focus_awareness = p_preset->get("xr_features/focus_awareness");
- String plugins_names = get_plugins_names(get_enabled_plugins(p_preset));
-
Vector<String> perms;
// Write permissions into the perms variable.
_get_permissions(p_preset, p_give_internet, perms);
@@ -975,11 +992,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
encode_uint32(xr_mode_index == /* XRMode.OVR */ 1 && focus_awareness ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
}
- if (tname == "meta-data" && attrname == "value" && value == "plugins_value" && !plugins_names.empty()) {
- // Update the meta-data 'android:value' attribute with the list of enabled plugins.
- string_table.write[attr_value] = plugins_names;
- }
-
is_focus_aware_metadata = tname == "meta-data" && attrname == "name" && value == "com.oculus.vr.focusaware";
iofs += 20;
}
@@ -1467,20 +1479,26 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
}
- void load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) {
- // TODO: Figure out how to handle remaining boot splash parameters (e.g: fullsize, filter)
+ String load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) {
+ bool scale_splash = ProjectSettings::get_singleton()->get("application/boot_splash/fullsize");
+ bool apply_filter = ProjectSettings::get_singleton()->get("application/boot_splash/use_filter");
String project_splash_path = ProjectSettings::get_singleton()->get("application/boot_splash/image");
- if (!project_splash_path.empty()) {
+ if (!project_splash_path.is_empty()) {
splash_image.instance();
+ print_verbose("Loading splash image: " + project_splash_path);
const Error err = ImageLoader::load_image(project_splash_path, splash_image);
if (err) {
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_error("- unable to load splash image from " + project_splash_path + " (" + itos(err) + ")");
+ }
splash_image.unref();
}
}
if (splash_image.is_null()) {
// Use the default
+ print_verbose("Using default splash image.");
splash_image = Ref<Image>(memnew(Image(boot_splash_png)));
}
@@ -1491,9 +1509,14 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
bg_color = boot_splash_bg_color;
}
+ print_verbose("Creating splash background color image.");
splash_bg_color_image.instance();
splash_bg_color_image->create(splash_image->get_width(), splash_image->get_height(), false, splash_image->get_format());
splash_bg_color_image->fill(bg_color);
+
+ String gravity = scale_splash ? "fill" : "center";
+ String processed_splash_config_xml = vformat(SPLASH_CONFIG_XML_CONTENT, gravity, bool_to_string(apply_filter));
+ return processed_splash_config_xml;
}
void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) {
@@ -1505,19 +1528,24 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
// Regular icon: user selection -> project icon -> default.
String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges();
- if (path.empty() || ImageLoader::load_image(path, icon) != OK) {
+ print_verbose("Loading regular icon from " + path);
+ if (path.is_empty() || ImageLoader::load_image(path, icon) != OK) {
+ print_verbose("- falling back to project icon: " + project_icon_path);
ImageLoader::load_image(project_icon_path, icon);
}
// Adaptive foreground: user selection -> regular icon (user selection -> project icon -> default).
path = static_cast<String>(p_preset->get(launcher_adaptive_icon_foreground_option)).strip_edges();
- if (path.empty() || ImageLoader::load_image(path, foreground) != OK) {
+ print_verbose("Loading adaptive foreground icon from " + path);
+ if (path.is_empty() || ImageLoader::load_image(path, foreground) != OK) {
+ print_verbose("- falling back to using the regular icon");
foreground = icon;
}
// Adaptive background: user selection -> default.
path = static_cast<String>(p_preset->get(launcher_adaptive_icon_background_option)).strip_edges();
- if (!path.empty()) {
+ if (!path.is_empty()) {
+ print_verbose("Loading adaptive background icon from " + path);
ImageLoader::load_image(path, background);
}
}
@@ -1532,20 +1560,29 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset,
+ const String &processed_splash_config_xml,
const Ref<Image> &splash_image,
const Ref<Image> &splash_bg_color_image,
const Ref<Image> &main_image,
const Ref<Image> &foreground,
const Ref<Image> &background) {
+ // Store the splash configuration
+ if (!processed_splash_config_xml.is_empty()) {
+ print_verbose("Storing processed splash configuration: " + String("\n") + processed_splash_config_xml);
+ store_string_at_path(SPLASH_CONFIG_PATH, processed_splash_config_xml);
+ }
+
// Store the splash image
- if (splash_image.is_valid() && !splash_image->empty()) {
+ if (splash_image.is_valid() && !splash_image->is_empty()) {
+ print_verbose("Storing splash image in " + String(SPLASH_IMAGE_EXPORT_PATH));
Vector<uint8_t> data;
_load_image_data(splash_image, data);
store_image(SPLASH_IMAGE_EXPORT_PATH, data);
}
// Store the splash bg color image
- if (splash_bg_color_image.is_valid() && !splash_bg_color_image->empty()) {
+ if (splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) {
+ print_verbose("Storing splash background image in " + String(SPLASH_BG_COLOR_PATH));
Vector<uint8_t> data;
_load_image_data(splash_bg_color_image, data);
store_image(SPLASH_BG_COLOR_PATH, data);
@@ -1555,20 +1592,23 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
// the default image from the export template will be used.
for (int i = 0; i < icon_densities_count; ++i) {
- if (main_image.is_valid() && !main_image->empty()) {
+ if (main_image.is_valid() && !main_image->is_empty()) {
+ print_verbose("Processing launcher icon for dimension " + itos(launcher_icons[i].dimensions) + " into " + launcher_icons[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_icons[i].export_path, main_image, launcher_icons[i].dimensions, data);
store_image(launcher_icons[i], data);
}
- if (foreground.is_valid() && !foreground->empty()) {
+ if (foreground.is_valid() && !foreground->is_empty()) {
+ print_verbose("Processing launcher adaptive icon foreground for dimension " + itos(launcher_adaptive_icon_foregrounds[i].dimensions) + " into " + launcher_adaptive_icon_foregrounds[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, foreground,
launcher_adaptive_icon_foregrounds[i].dimensions, data);
store_image(launcher_adaptive_icon_foregrounds[i], data);
}
- if (background.is_valid() && !background->empty()) {
+ if (background.is_valid() && !background->is_empty()) {
+ print_verbose("Processing launcher adaptive icon background for dimension " + itos(launcher_adaptive_icon_backgrounds[i].dimensions) + " into " + launcher_adaptive_icon_backgrounds[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, background,
launcher_adaptive_icon_backgrounds[i].dimensions, data);
@@ -1594,7 +1634,7 @@ public:
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override {
- String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
+ String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
if (driver == "GLES2") {
r_features->push_back("etc");
}
@@ -1613,14 +1653,14 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_template/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "custom_template/export_format", PROPERTY_HINT_ENUM, "Export APK,Export AAB"), EXPORT_FORMAT_APK));
- Vector<PluginConfig> plugins_configs = get_plugins();
+ Vector<PluginConfigAndroid> plugins_configs = get_plugins();
for (int i = 0; i < plugins_configs.size(); i++) {
print_verbose("Found Android plugin " + plugins_configs[i].name);
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + plugins_configs[i].name), false));
}
- plugins_changed = false;
+ plugins_changed.clear();
Vector<String> abis = get_abis();
for (int i = 0; i < abis.size(); ++i) {
@@ -1690,19 +1730,19 @@ public:
}
virtual bool should_update_export_options() override {
- bool export_options_changed = plugins_changed;
+ bool export_options_changed = plugins_changed.is_set();
if (export_options_changed) {
// don't clear unless we're reporting true, to avoid race
- plugins_changed = false;
+ plugins_changed.clear();
}
return export_options_changed;
}
virtual bool poll_export() override {
- bool dc = devices_changed;
+ bool dc = devices_changed.is_set();
if (dc) {
// don't clear unless we're reporting true, to avoid race
- devices_changed = false;
+ devices_changed.clear();
}
return dc;
}
@@ -1749,7 +1789,7 @@ public:
EditorProgress ep("run", "Running on " + devices[p_device].name, 3);
- String adb = EditorSettings::get_singleton()->get("export/android/adb");
+ String adb = get_adb_path();
// Export_temp APK.
if (ep.step("Exporting APK...", 0)) {
@@ -1772,7 +1812,7 @@ public:
}
// Export to temporary APK before sending to device.
- Error err = export_project(p_preset, true, tmp_export_path, p_debug_flags);
+ Error err = export_project_helper(p_preset, true, tmp_export_path, EXPORT_FORMAT_APK, true, p_debug_flags);
if (err != OK) {
CLEANUP_AND_RETURN(err);
@@ -1797,7 +1837,7 @@ public:
args.push_back("uninstall");
args.push_back(get_package_name(package_name));
- err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ err = OS::get_singleton()->execute(adb, args, nullptr, &rv);
}
print_line("Installing to device (please wait...): " + devices[p_device].name);
@@ -1812,7 +1852,7 @@ public:
args.push_back("-r");
args.push_back(tmp_export_path);
- err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ err = OS::get_singleton()->execute(adb, args, nullptr, &rv);
if (err || rv != 0) {
EditorNode::add_io_error("Could not install to device.");
CLEANUP_AND_RETURN(ERR_CANT_CREATE);
@@ -1829,7 +1869,7 @@ public:
args.push_back(devices[p_device].id);
args.push_back("reverse");
args.push_back("--remove-all");
- OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ OS::get_singleton()->execute(adb, args, nullptr, &rv);
if (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) {
int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port");
@@ -1840,7 +1880,7 @@ public:
args.push_back("tcp:" + itos(dbg_port));
args.push_back("tcp:" + itos(dbg_port));
- OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ OS::get_singleton()->execute(adb, args, nullptr, &rv);
print_line("Reverse result: " + itos(rv));
}
@@ -1854,7 +1894,7 @@ public:
args.push_back("tcp:" + itos(fs_port));
args.push_back("tcp:" + itos(fs_port));
- err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ err = OS::get_singleton()->execute(adb, args, nullptr, &rv);
print_line("Reverse result2: " + itos(rv));
}
} else {
@@ -1882,7 +1922,7 @@ public:
args.push_back("-n");
args.push_back(get_package_name(package_name) + "/com.godot.game.GodotApp");
- err = OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
+ err = OS::get_singleton()->execute(adb, args, nullptr, &rv);
if (err || rv != 0) {
EditorNode::add_io_error("Could not execute on device.");
CLEANUP_AND_RETURN(ERR_CANT_CREATE);
@@ -1896,6 +1936,55 @@ public:
return run_icon;
}
+ static String get_adb_path() {
+ String exe_ext = "";
+ if (OS::get_singleton()->get_name() == "Windows") {
+ exe_ext = ".exe";
+ }
+ String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path");
+ return sdk_path.plus_file("platform-tools/adb" + exe_ext);
+ }
+
+ static String get_apksigner_path() {
+ String exe_ext = "";
+ if (OS::get_singleton()->get_name() == "Windows") {
+ exe_ext = ".bat";
+ }
+ String apksigner_command_name = "apksigner" + exe_ext;
+ String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path");
+ String apksigner_path = "";
+
+ Error errn;
+ String build_tools_dir = sdk_path.plus_file("build-tools");
+ DirAccessRef da = DirAccess::open(build_tools_dir, &errn);
+ if (errn != OK) {
+ print_error("Unable to open Android 'build-tools' directory.");
+ return apksigner_path;
+ }
+
+ // There are additional versions directories we need to go through.
+ da->list_dir_begin();
+ String sub_dir = da->get_next();
+ while (!sub_dir.is_empty()) {
+ if (!sub_dir.begins_with(".") && da->current_is_dir()) {
+ // Check if the tool is here.
+ String tool_path = build_tools_dir.plus_file(sub_dir).plus_file(apksigner_command_name);
+ if (FileAccess::exists(tool_path)) {
+ apksigner_path = tool_path;
+ break;
+ }
+ }
+ sub_dir = da->get_next();
+ }
+ da->list_dir_end();
+
+ if (apksigner_path.is_empty()) {
+ EditorNode::get_singleton()->show_warning(TTR("Unable to find the 'apksigner' tool."));
+ }
+
+ return apksigner_path;
+ }
+
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override {
String err;
bool valid = false;
@@ -1906,6 +1995,7 @@ public:
String template_err;
bool dvalid = false;
bool rvalid = false;
+ bool has_export_templates = false;
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
@@ -1913,7 +2003,7 @@ public:
template_err += TTR("Custom debug template not found.") + "\n";
}
} else {
- dvalid = exists_export_template("android_debug.apk", &template_err);
+ has_export_templates |= exists_export_template("android_debug.apk", &template_err);
}
if (p_preset->get("custom_template/release") != "") {
@@ -1922,33 +2012,26 @@ public:
template_err += TTR("Custom release template not found.") + "\n";
}
} else {
- rvalid = exists_export_template("android_release.apk", &template_err);
+ has_export_templates |= exists_export_template("android_release.apk", &template_err);
}
- valid = dvalid || rvalid;
+ r_missing_templates = !has_export_templates;
+ valid = dvalid || rvalid || has_export_templates;
if (!valid) {
err += template_err;
}
} else {
- valid = exists_export_template("android_source.zip", &err);
- }
- r_missing_templates = !valid;
+ r_missing_templates = !exists_export_template("android_source.zip", &err);
- // Validate the rest of the configuration.
-
- String adb = EditorSettings::get_singleton()->get("export/android/adb");
+ bool installed_android_build_template = FileAccess::exists("res://android/build/build.gradle");
+ if (!installed_android_build_template) {
+ err += TTR("Android build template not installed in the project. Install it from the Project menu.") + "\n";
+ }
- if (!FileAccess::exists(adb)) {
- valid = false;
- err += TTR("ADB executable not configured in the Editor Settings.") + "\n";
+ valid = installed_android_build_template && !r_missing_templates;
}
- String js = EditorSettings::get_singleton()->get("export/android/jarsigner");
-
- if (!FileAccess::exists(js)) {
- valid = false;
- err += TTR("OpenJDK jarsigner not configured in the Editor Settings.") + "\n";
- }
+ // Validate the rest of the configuration.
String dk = p_preset->get("keystore/debug");
@@ -1962,30 +2045,50 @@ public:
String rk = p_preset->get("keystore/release");
- if (!rk.empty() && !FileAccess::exists(rk)) {
+ if (!rk.is_empty() && !FileAccess::exists(rk)) {
valid = false;
err += TTR("Release keystore incorrectly configured in the export preset.") + "\n";
}
- if (bool(p_preset->get("custom_template/use_custom_build"))) {
- String sdk_path = EditorSettings::get_singleton()->get("export/android/custom_build_sdk_path");
- if (sdk_path == "") {
- err += TTR("Custom build requires a valid Android SDK path in Editor Settings.") + "\n";
+ String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path");
+ if (sdk_path == "") {
+ err += TTR("A valid Android SDK path is required in Editor Settings.") + "\n";
+ valid = false;
+ } else {
+ Error errn;
+ // Check for the platform-tools directory.
+ DirAccessRef da = DirAccess::open(sdk_path.plus_file("platform-tools"), &errn);
+ if (errn != OK) {
+ err += TTR("Invalid Android SDK path in Editor Settings.");
+ err += TTR("Missing 'platform-tools' directory!");
+ err += "\n";
valid = false;
- } else {
- Error errn;
- // Check for the platform-tools directory.
- DirAccessRef da = DirAccess::open(sdk_path.plus_file("platform-tools"), &errn);
- if (errn != OK) {
- err += TTR("Invalid Android SDK path for custom build in Editor Settings.");
- err += TTR("Missing 'platform-tools' directory!");
- err += "\n";
- valid = false;
- }
}
- if (!FileAccess::exists("res://android/build/build.gradle")) {
- err += TTR("Android build template not installed in the project. Install it from the Project menu.") + "\n";
+ // Validate that adb is available
+ String adb_path = get_adb_path();
+ if (!FileAccess::exists(adb_path)) {
+ err += TTR("Unable to find Android SDK platform-tools' adb command.");
+ err += TTR("Please check in the Android SDK directory specified in Editor Settings.");
+ err += "\n";
+ valid = false;
+ }
+
+ // Check for the build-tools directory.
+ DirAccessRef build_tools_da = DirAccess::open(sdk_path.plus_file("build-tools"), &errn);
+ if (errn != OK) {
+ err += TTR("Invalid Android SDK path in Editor Settings.");
+ err += TTR("Missing 'build-tools' directory!");
+ err += "\n";
+ valid = false;
+ }
+
+ // Validate that apksigner is available
+ String apksigner_path = get_apksigner_path();
+ if (!FileAccess::exists(apksigner_path)) {
+ err += TTR("Unable to find Android SDK build-tools' apksigner command.");
+ err += TTR("Please check in the Android SDK directory specified in Editor Settings.");
+ err += "\n";
valid = false;
}
}
@@ -2019,7 +2122,7 @@ public:
// Ensure that `Use Custom Build` is enabled if a plugin is selected.
String enabled_plugins_names = get_plugins_names(get_enabled_plugins(p_preset));
bool custom_build_enabled = p_preset->get("custom_template/use_custom_build");
- if (!enabled_plugins_names.empty() && !custom_build_enabled) {
+ if (!enabled_plugins_names.is_empty() && !custom_build_enabled) {
valid = false;
err += TTR("\"Use Custom Build\" must be enabled to use the plugins.");
err += "\n";
@@ -2050,7 +2153,7 @@ public:
}
}
- if (int(p_preset->get("custom_template/export_format")) == 1 && /*AAB*/
+ if (int(p_preset->get("custom_template/export_format")) == EXPORT_FORMAT_AAB &&
!bool(p_preset->get("custom_template/use_custom_build"))) {
valid = false;
err += TTR("\"Export AAB\" is only valid when \"Use Custom Build\" is enabled.");
@@ -2068,7 +2171,7 @@ public:
return list;
}
- inline bool is_clean_build_required(Vector<PluginConfig> enabled_plugins) {
+ inline bool is_clean_build_required(Vector<PluginConfigAndroid> enabled_plugins) {
String plugin_names = get_plugins_names(enabled_plugins);
bool first_build = last_custom_build_time == 0;
bool have_plugins_changed = false;
@@ -2168,16 +2271,17 @@ public:
}
}
- Error sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, String export_path, EditorProgress ep) {
+ Error sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &export_path, EditorProgress &ep) {
int export_format = int(p_preset->get("custom_template/export_format"));
- String export_label = export_format == 1 ? "AAB" : "APK";
+ String export_label = export_format == EXPORT_FORMAT_AAB ? "AAB" : "APK";
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");
- String jarsigner = EditorSettings::get_singleton()->get("export/android/jarsigner");
- if (!FileAccess::exists(jarsigner)) {
- EditorNode::add_io_error("'jarsigner' could not be found.\nPlease supply a path in the Editor Settings.\nThe resulting " + export_label + " is unsigned.");
+ String apksigner = get_apksigner_path();
+ print_verbose("Starting signing of the " + export_label + " binary using " + apksigner);
+ if (!FileAccess::exists(apksigner)) {
+ EditorNode::add_io_error("'apksigner' could not be found.\nPlease check the command is available in the Android SDK build-tools directory.\nThe resulting " + export_label + " is unsigned.");
return OK;
}
@@ -2189,13 +2293,13 @@ public:
password = p_preset->get("keystore/debug_password");
user = p_preset->get("keystore/debug_user");
- if (keystore.empty()) {
+ if (keystore.is_empty()) {
keystore = EditorSettings::get_singleton()->get("export/android/debug_keystore");
password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass");
user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user");
}
- if (ep.step("Signing debug " + export_label + "...", 103)) {
+ if (ep.step("Signing debug " + export_label + "...", 104)) {
return ERR_SKIP;
}
@@ -2204,7 +2308,7 @@ public:
password = release_password;
user = release_username;
- if (ep.step("Signing release " + export_label + "...", 103)) {
+ if (ep.step("Signing release " + export_label + "...", 104)) {
return ERR_SKIP;
}
}
@@ -2215,58 +2319,76 @@ public:
}
List<String> args;
- args.push_back("-digestalg");
- args.push_back("SHA-256");
- args.push_back("-sigalg");
- args.push_back("SHA256withRSA");
- String tsa_url = EditorSettings::get_singleton()->get("export/android/timestamping_authority_url");
- if (tsa_url != "") {
- args.push_back("-tsa");
- args.push_back(tsa_url);
- }
- args.push_back("-verbose");
- args.push_back("-keystore");
+ args.push_back("sign");
+ args.push_back("--verbose");
+ args.push_back("--ks");
args.push_back(keystore);
- args.push_back("-storepass");
- args.push_back(password);
- args.push_back(export_path);
+ args.push_back("--ks-pass");
+ args.push_back("pass:" + password);
+ args.push_back("--ks-key-alias");
args.push_back(user);
+ args.push_back(export_path);
+ if (p_debug) {
+ // We only print verbose logs for debug builds to avoid leaking release keystore credentials.
+ print_verbose("Signing debug binary using: " + String("\n") + apksigner + " " + join_list(args, String(" ")));
+ }
int retval;
- OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval);
+ OS::get_singleton()->execute(apksigner, args, nullptr, &retval);
if (retval) {
- EditorNode::add_io_error("'jarsigner' returned with error #" + itos(retval));
+ EditorNode::add_io_error("'apksigner' returned with error #" + itos(retval));
return ERR_CANT_CREATE;
}
- if (ep.step("Verifying " + export_label + "...", 104)) {
+ if (ep.step("Verifying " + export_label + "...", 105)) {
return ERR_SKIP;
}
args.clear();
- args.push_back("-verify");
- args.push_back("-keystore");
- args.push_back(keystore);
+ args.push_back("verify");
+ args.push_back("--verbose");
args.push_back(export_path);
- args.push_back("-verbose");
+ if (p_debug) {
+ print_verbose("Verifying signed build using: " + String("\n") + apksigner + " " + join_list(args, String(" ")));
+ }
- OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval);
+ OS::get_singleton()->execute(apksigner, args, nullptr, &retval);
if (retval) {
- EditorNode::add_io_error("'jarsigner' verification of " + export_label + " failed. Make sure to use a jarsigner from OpenJDK 8.");
+ EditorNode::add_io_error("'apksigner' verification of " + export_label + " failed.");
return ERR_CANT_CREATE;
}
+
+ print_verbose("Successfully completed signing build.");
return OK;
}
void _clear_assets_directory() {
DirAccessRef da_res = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (da_res->dir_exists("res://android/build/assets")) {
+ print_verbose("Clearing assets directory..");
DirAccessRef da_assets = DirAccess::open("res://android/build/assets");
da_assets->erase_contents_recursive();
da_res->remove("res://android/build/assets");
}
}
+ String join_list(List<String> parts, const String &separator) const {
+ String ret;
+ for (int i = 0; i < parts.size(); ++i) {
+ if (i > 0) {
+ ret += separator;
+ }
+ ret += parts[i];
+ }
+ return ret;
+ }
+
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override {
+ int export_format = int(p_preset->get("custom_template/export_format"));
+ bool should_sign = p_preset->get("package/signed");
+ return export_project_helper(p_preset, p_debug, p_path, export_format, should_sign, p_flags);
+ }
+
+ Error export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int export_format, bool should_sign, int p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
String src_apk;
@@ -2275,15 +2397,25 @@ public:
EditorProgress ep("export", "Exporting for Android", 105, true);
bool use_custom_build = bool(p_preset->get("custom_template/use_custom_build"));
- int export_format = int(p_preset->get("custom_template/export_format"));
bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
- bool _signed = p_preset->get("package/signed");
bool apk_expansion = p_preset->get("apk_expansion/enable");
Vector<String> enabled_abis = get_enabled_abis(p_preset);
+ print_verbose("Exporting for Android...");
+ print_verbose("- debug build: " + bool_to_string(p_debug));
+ print_verbose("- export path: " + p_path);
+ print_verbose("- export format: " + itos(export_format));
+ print_verbose("- sign build: " + bool_to_string(should_sign));
+ print_verbose("- custom build enabled: " + bool_to_string(use_custom_build));
+ print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion));
+ print_verbose("- enabled abis: " + String(",").join(enabled_abis));
+ print_verbose("- export filter: " + itos(p_preset->get_export_filter()));
+ print_verbose("- include filter: " + p_preset->get_include_filter());
+ print_verbose("- exclude filter: " + p_preset->get_exclude_filter());
+
Ref<Image> splash_image;
Ref<Image> splash_bg_color_image;
- load_splash_refs(splash_image, splash_bg_color_image);
+ String processed_splash_config_xml = load_splash_refs(splash_image, splash_bg_color_image);
Ref<Image> main_image;
Ref<Image> foreground;
@@ -2295,7 +2427,7 @@ public:
// Write command line flags into the command_line_flags variable.
get_command_line_flags(p_preset, p_path, p_flags, command_line_flags);
- if (export_format == 1) {
+ if (export_format == EXPORT_FORMAT_AAB) {
if (!p_path.ends_with(".aab")) {
EditorNode::get_singleton()->show_warning(TTR("Invalid filename! Android App Bundle requires the *.aab extension."));
return ERR_UNCONFIGURED;
@@ -2305,33 +2437,37 @@ public:
return ERR_UNCONFIGURED;
}
}
- if (export_format == 0 && !p_path.ends_with(".apk")) {
+ if (export_format == EXPORT_FORMAT_APK && !p_path.ends_with(".apk")) {
EditorNode::get_singleton()->show_warning(
TTR("Invalid filename! Android APK requires the *.apk extension."));
return ERR_UNCONFIGURED;
}
- if (export_format > 1 || export_format < 0) {
+ if (export_format > EXPORT_FORMAT_AAB || export_format < EXPORT_FORMAT_APK) {
EditorNode::add_io_error("Unsupported export format!\n");
return ERR_UNCONFIGURED; //TODO: is this the right error?
}
if (use_custom_build) {
+ print_verbose("Starting custom build..");
//test that installed build version is alright
{
+ print_verbose("Checking build version..");
FileAccessRef f = FileAccess::open("res://android/.build_version", FileAccess::READ);
if (!f) {
EditorNode::get_singleton()->show_warning(TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu."));
return ERR_UNCONFIGURED;
}
String version = f->get_line().strip_edges();
+ print_verbose("- build version: " + version);
f->close();
if (version != VERSION_FULL_CONFIG) {
EditorNode::get_singleton()->show_warning(vformat(TTR("Android build version mismatch:\n Template installed: %s\n Godot Version: %s\nPlease reinstall Android build template from 'Project' menu."), version, VERSION_FULL_CONFIG));
return ERR_UNCONFIGURED;
}
}
- String sdk_path = EDITOR_GET("export/android/custom_build_sdk_path");
- ERR_FAIL_COND_V_MSG(sdk_path == "", ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/custom_build_sdk_path'.");
+ String sdk_path = EDITOR_GET("export/android/android_sdk_path");
+ ERR_FAIL_COND_V_MSG(sdk_path.is_empty(), ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/android_sdk_path'.");
+ print_verbose("Android sdk path: " + sdk_path);
// TODO: should we use "package/name" or "application/config/name"?
String project_name = get_project_name(p_preset->get("package/name"));
@@ -2340,27 +2476,31 @@ public:
EditorNode::add_io_error("Unable to overwrite res://android/build/res/*.xml files with project name");
}
// Copies the project icon files into the appropriate Gradle project directory.
- _copy_icons_to_gradle_project(p_preset, splash_image, splash_bg_color_image, main_image, foreground, background);
+ _copy_icons_to_gradle_project(p_preset, processed_splash_config_xml, splash_image, splash_bg_color_image, main_image, foreground, background);
// Write an AndroidManifest.xml file into the Gradle project directory.
_write_tmp_manifest(p_preset, p_give_internet, p_debug);
//stores all the project files inside the Gradle project directory. Also includes all ABIs
_clear_assets_directory();
if (!apk_expansion) {
+ print_verbose("Exporting project files..");
err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, NULL, ignore_so_file);
if (err != OK) {
EditorNode::add_io_error("Could not export project files to gradle project\n");
return err;
}
} else {
+ print_verbose("Saving apk expansion file..");
err = save_apk_expansion_file(p_preset, p_path);
if (err != OK) {
EditorNode::add_io_error("Could not write expansion package file!");
return err;
}
}
+ print_verbose("Storing command line flags..");
store_file_at_path("res://android/build/assets/_cl_", command_line_flags);
+ print_verbose("Updating ANDROID_HOME environment to " + sdk_path);
OS::get_singleton()->set_environment("ANDROID_HOME", sdk_path); //set and overwrite if required
String build_command;
@@ -2377,12 +2517,12 @@ public:
String version_code = itos(p_preset->get("version/code"));
String version_name = p_preset->get("version/name");
String enabled_abi_string = String("|").join(enabled_abis);
- String sign_flag = _signed ? "true" : "false";
+ String sign_flag = should_sign ? "true" : "false";
String zipalign_flag = "true";
- Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset);
- String local_plugins_binaries = get_plugins_binaries(BINARY_TYPE_LOCAL, enabled_plugins);
- String remote_plugins_binaries = get_plugins_binaries(BINARY_TYPE_REMOTE, enabled_plugins);
+ Vector<PluginConfigAndroid> enabled_plugins = get_enabled_plugins(p_preset);
+ String local_plugins_binaries = get_plugins_binaries(PluginConfigAndroid::BINARY_TYPE_LOCAL, enabled_plugins);
+ String remote_plugins_binaries = get_plugins_binaries(PluginConfigAndroid::BINARY_TYPE_REMOTE, enabled_plugins);
String custom_maven_repos = get_plugins_custom_maven_repos(enabled_plugins);
bool clean_build_required = is_clean_build_required(enabled_plugins);
@@ -2392,14 +2532,16 @@ public:
}
String build_type = p_debug ? "Debug" : "Release";
- if (export_format == 1) {
+ if (export_format == EXPORT_FORMAT_AAB) {
String bundle_build_command = vformat("bundle%s", build_type);
cmdline.push_back(bundle_build_command);
- } else if (export_format == 0) {
+ } else if (export_format == EXPORT_FORMAT_APK) {
String apk_build_command = vformat("assemble%s", build_type);
cmdline.push_back(apk_build_command);
}
+ cmdline.push_back("-p"); // argument to specify the start directory.
+ cmdline.push_back(build_path); // start directory.
cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name.
cmdline.push_back("-Pexport_version_code=" + version_code); // argument to specify the version code.
cmdline.push_back("-Pexport_version_name=" + version_name); // argument to specify the version name.
@@ -2409,7 +2551,15 @@ public:
cmdline.push_back("-Pplugins_maven_repos=" + custom_maven_repos); // argument to specify the list of custom maven repos for the plugins dependencies.
cmdline.push_back("-Pperform_zipalign=" + zipalign_flag); // argument to specify whether the build should be zipaligned.
cmdline.push_back("-Pperform_signing=" + sign_flag); // argument to specify whether the build should be signed.
- if (_signed && !p_debug) {
+ cmdline.push_back("-Pgodot_editor_version=" + String(VERSION_FULL_CONFIG));
+
+ // NOTE: The release keystore is not included in the verbose logging
+ // to avoid accidentally leaking sensitive information when sharing verbose logs for troubleshooting.
+ // Any non-sensitive additions to the command line arguments must be done above this section.
+ // Sensitive additions must be done below the logging statement.
+ print_verbose("Build Android project using gradle command: " + String("\n") + build_command + " " + join_list(cmdline, String(" ")));
+
+ if (should_sign && !p_debug) {
// Pass the release keystore info as well
String release_keystore = p_preset->get("keystore/release");
String release_username = p_preset->get("keystore/release_user");
@@ -2423,8 +2573,6 @@ public:
cmdline.push_back("-Prelease_keystore_alias=" + release_username); // argument to specify the release keystore alias.
cmdline.push_back("-Prelease_keystore_password=" + release_password); // argument to specity the release keystore password.
}
- cmdline.push_back("-p"); // argument to specify the start directory.
- cmdline.push_back(build_path); // start directory.
int result = EditorNode::get_singleton()->execute_and_show_output(TTR("Building Android Project (gradle)"), build_command, cmdline);
if (result != 0) {
@@ -2434,9 +2582,9 @@ public:
List<String> copy_args;
String copy_command;
- if (export_format == 1) {
+ if (export_format == EXPORT_FORMAT_AAB) {
copy_command = vformat("copyAndRename%sAab", build_type);
- } else if (export_format == 0) {
+ } else if (export_format == EXPORT_FORMAT_APK) {
copy_command = vformat("copyAndRename%sApk", build_type);
}
@@ -2455,15 +2603,18 @@ public:
copy_args.push_back("-Pexport_path=file:" + export_path);
copy_args.push_back("-Pexport_filename=" + export_filename);
+ print_verbose("Copying Android binary using gradle command: " + String("\n") + build_command + " " + join_list(copy_args, String(" ")));
int copy_result = EditorNode::get_singleton()->execute_and_show_output(TTR("Moving output"), build_command, copy_args);
if (copy_result != 0) {
EditorNode::get_singleton()->show_warning(TTR("Unable to copy and rename export file, check gradle project directory for outputs."));
return ERR_CANT_CREATE;
}
+ print_verbose("Successfully completed Android custom build.");
return OK;
}
// This is the start of the Legacy build system
+ print_verbose("Starting legacy build system..");
if (p_debug)
src_apk = p_preset->get("custom_template/debug");
else
@@ -2549,27 +2700,27 @@ public:
}
// Process the splash image
- if (file == SPLASH_IMAGE_EXPORT_PATH && splash_image.is_valid() && !splash_image->empty()) {
+ if (file == SPLASH_IMAGE_EXPORT_PATH && splash_image.is_valid() && !splash_image->is_empty()) {
_load_image_data(splash_image, data);
}
// Process the splash bg color image
- if (file == SPLASH_BG_COLOR_PATH && splash_bg_color_image.is_valid() && !splash_bg_color_image->empty()) {
+ if (file == SPLASH_BG_COLOR_PATH && splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) {
_load_image_data(splash_bg_color_image, data);
}
for (int i = 0; i < icon_densities_count; ++i) {
- if (main_image.is_valid() && !main_image->empty()) {
+ if (main_image.is_valid() && !main_image->is_empty()) {
if (file == launcher_icons[i].export_path) {
_process_launcher_icons(file, main_image, launcher_icons[i].dimensions, data);
}
}
- if (foreground.is_valid() && !foreground->empty()) {
+ if (foreground.is_valid() && !foreground->is_empty()) {
if (file == launcher_adaptive_icon_foregrounds[i].export_path) {
_process_launcher_icons(file, foreground, launcher_adaptive_icon_foregrounds[i].dimensions, data);
}
}
- if (background.is_valid() && !background->empty()) {
+ if (background.is_valid() && !background->is_empty()) {
if (file == launcher_adaptive_icon_backgrounds[i].export_path) {
_process_launcher_icons(file, background, launcher_adaptive_icon_backgrounds[i].dimensions, data);
}
@@ -2590,7 +2741,7 @@ public:
}
}
- if (file.begins_with("META-INF") && _signed) {
+ if (file.begins_with("META-INF") && should_sign) {
skip = true;
}
@@ -2620,7 +2771,7 @@ public:
ret = unzGoToNextFile(pkg);
}
- if (!invalid_abis.empty()) {
+ if (!invalid_abis.is_empty()) {
String unsupported_arch = String(", ").join(invalid_abis);
EditorNode::add_io_error("Missing libraries in the export template for the selected architectures: " + unsupported_arch + ".\n" +
"Please build a template with all required libraries, or uncheck the missing architectures in the export preset.");
@@ -2678,18 +2829,13 @@ public:
CLEANUP_AND_RETURN(err);
}
- if (_signed) {
- err = sign_apk(p_preset, p_debug, tmp_unaligned_path, ep);
- if (err != OK) {
- CLEANUP_AND_RETURN(err);
- }
- }
-
- // Let's zip-align (must be done after signing)
+ // Let's zip-align (must be done before signing)
static const int ZIP_ALIGNMENT = 4;
- if (ep.step("Aligning APK...", 105)) {
+ // If we're not signing the apk, then the next step should be the last.
+ const int next_step = should_sign ? 103 : 105;
+ if (ep.step("Aligning APK...", next_step)) {
CLEANUP_AND_RETURN(ERR_SKIP);
}
@@ -2763,6 +2909,15 @@ public:
zipClose(final_apk, nullptr);
unzClose(tmp_unaligned);
+ if (should_sign) {
+ // Signing must be done last as any additional modifications to the
+ // file will invalidate the signature.
+ err = sign_apk(p_preset, p_debug, p_path, ep);
+ if (err != OK) {
+ CLEANUP_AND_RETURN(err);
+ }
+ }
+
CLEANUP_AND_RETURN(OK);
}
@@ -2783,16 +2938,14 @@ public:
run_icon.instance();
run_icon->create_from_image(img);
- devices_changed = true;
- plugins_changed = true;
- quit_request = false;
- check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this);
+ devices_changed.set();
+ plugins_changed.set();
+ check_for_changes_thread.start(_check_for_changes_poll_thread, this);
}
~EditorExportPlatformAndroid() {
- quit_request = true;
- Thread::wait_to_finish(check_for_changes_thread);
- memdelete(check_for_changes_thread);
+ quit_request.set();
+ check_for_changes_thread.wait_to_finish();
}
};
@@ -2802,19 +2955,14 @@ void register_android_exporter() {
exe_ext = "*.exe";
}
- EDITOR_DEF("export/android/adb", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/adb", PROPERTY_HINT_GLOBAL_FILE, exe_ext));
- EDITOR_DEF("export/android/jarsigner", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/jarsigner", PROPERTY_HINT_GLOBAL_FILE, exe_ext));
+ EDITOR_DEF("export/android/android_sdk_path", "");
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/android_sdk_path", PROPERTY_HINT_GLOBAL_DIR));
EDITOR_DEF("export/android/debug_keystore", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"));
EDITOR_DEF("export/android/debug_keystore_user", "androiddebugkey");
EDITOR_DEF("export/android/debug_keystore_pass", "android");
EDITOR_DEF("export/android/force_system_user", false);
- EDITOR_DEF("export/android/custom_build_sdk_path", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/custom_build_sdk_path", PROPERTY_HINT_GLOBAL_DIR));
- EDITOR_DEF("export/android/timestamping_authority_url", "");
EDITOR_DEF("export/android/shutdown_adb_on_exit", true);
Ref<EditorExportPlatformAndroid> exporter = Ref<EditorExportPlatformAndroid>(memnew(EditorExportPlatformAndroid));
diff --git a/platform/android/export/export.h b/platform/android/export/export.h
index d11ab9f49e..28e09f41db 100644
--- a/platform/android/export/export.h
+++ b/platform/android/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index a9f38869e0..097a2391ee 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -146,6 +146,9 @@ Error store_string_at_path(const String &p_path, const String &p_data) {
String dir = p_path.get_base_dir();
Error err = create_directory(dir);
if (err != OK) {
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_error("Unable to write data into " + p_path);
+ }
return err;
}
FileAccess *fa = FileAccess::open(p_path, FileAccess::WRITE);
@@ -162,12 +165,14 @@ Error store_string_at_path(const String &p_path, const String &p_data) {
// This method will be called ONLY when custom build is enabled.
Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
String dst_path = p_path.replace_first("res://", "res://android/build/assets/");
+ print_verbose("Saving project files from " + p_path + " into " + dst_path);
Error err = store_file_at_path(dst_path, p_data);
return err;
}
// Creates strings.xml files inside the gradle project for different locales.
Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset, const String &project_name) {
+ print_verbose("Creating strings resources for supported locales for project " + project_name);
// Stores the string into the default values directory.
String processed_default_xml_string = vformat(godot_project_name_xml_string, project_name.xml_escape(true));
store_string_at_path("res://android/build/res/values/godot_project_name_string.xml", processed_default_xml_string);
@@ -175,6 +180,9 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
// Searches the Gradle project res/ directory to find all supported locales
DirAccessRef da = DirAccess::open("res://android/build/res");
if (!da) {
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_error("Unable to open Android resources directory.");
+ }
return ERR_CANT_OPEN;
}
da->list_dir_begin();
@@ -193,6 +201,7 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
if (ProjectSettings::get_singleton()->has_setting(property_name)) {
String locale_project_name = ProjectSettings::get_singleton()->get(property_name);
String processed_xml_string = vformat(godot_project_name_xml_string, locale_project_name.xml_escape(true));
+ print_verbose("Storing project name for locale " + locale + " under " + locale_directory);
store_string_at_path(locale_directory, processed_xml_string);
} else {
// TODO: Once the legacy build system is deprecated we don't need to have xml files for this else branch
@@ -208,8 +217,8 @@ String bool_to_string(bool v) {
}
String _get_gles_tag() {
- bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES3" &&
- !ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2");
+ bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/driver/driver_name") == "GLES3" &&
+ !ProjectSettings::get_singleton()->get("rendering/driver/fallback_to_gles2");
return min_gles3 ? " <uses-feature android:glEsVersion=\"0x00030000\" android:required=\"true\" />\n" : "";
}
@@ -260,14 +269,6 @@ String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset) {
return manifest_instrumentation_text;
}
-String _get_plugins_tag(const String &plugins_names) {
- if (!plugins_names.empty()) {
- return vformat(" <meta-data tools:node=\"replace\" android:name=\"plugins\" android:value=\"%s\" />\n", plugins_names);
- } else {
- return " <meta-data tools:node=\"remove\" android:name=\"plugins\" />\n";
- }
-}
-
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
String orientation = _get_android_orientation_label(_get_screen_orientation());
@@ -286,7 +287,7 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
return manifest_activity_text;
}
-String _get_application_tag(const Ref<EditorExportPreset> &p_preset, const String &plugins_names) {
+String _get_application_tag(const Ref<EditorExportPreset> &p_preset) {
bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
String manifest_application_text =
" <application android:label=\"@string/godot_project_name_string\"\n"
@@ -294,7 +295,6 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, const Strin
" android:icon=\"@mipmap/icon\">\n\n"
" <meta-data tools:node=\"remove\" android:name=\"xr_mode_metadata_name\" />\n";
- manifest_application_text += _get_plugins_tag(plugins_names);
if (uses_xr) {
manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n";
}
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index 0d933fb858..165d5da3ae 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index 7fc7d8c83d..56010c918a 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index e94681659c..948fa8c00b 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -22,6 +22,11 @@
tools:ignore="GoogleAppIndexingWarning"
android:icon="@mipmap/icon" >
+ <!-- Records the version of the Godot editor used for building -->
+ <meta-data
+ android:name="org.godotengine.editor.version"
+ android:value="${godotEditorVersion}" />
+
<!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. -->
<!-- Do these changes in the export preset. Adding new ones is fine. -->
@@ -30,11 +35,6 @@
android:name="xr_mode_metadata_name"
android:value="xr_mode_metadata_value" />
- <!-- Metadata populated at export time and used by Godot to figure out which plugins must be enabled. -->
- <meta-data
- android:name="plugins"
- android:value="plugins_value"/>
-
<activity
android:name=".GodotApp"
android:label="@string/godot_project_name_string"
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index 53d11fda5b..934c4bf441 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -85,6 +85,8 @@ android {
abiFilters export_abi_list
}
+ manifestPlaceholders = [godotEditorVersion: getGodotEditorVersion()]
+
// Feel free to modify the application id to your own.
applicationId getExportPackageName()
versionCode getExportVersionCode()
@@ -98,6 +100,8 @@ android {
disable 'MissingTranslation', 'UnusedResources'
}
+ ndkVersion versions.ndkVersion
+
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 80cf6f7ede..585e517631 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,5 +1,5 @@
ext.versions = [
- androidGradlePlugin: '4.1.0',
+ androidGradlePlugin: '4.0.1',
compileSdk : 29,
minSdk : 18,
targetSdk : 29,
@@ -7,7 +7,8 @@ ext.versions = [
supportCoreUtils : '1.0.0',
kotlinVersion : '1.4.10',
v4Support : '1.0.0',
- javaVersion : 1.8
+ javaVersion : 1.8,
+ ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated.
]
@@ -49,7 +50,56 @@ ext.getExportVersionName = { ->
return versionName
}
-final String PLUGIN_VALUE_SEPARATOR_REGEX = "\\|"
+ext.getGodotEditorVersion = { ->
+ String editorVersion = project.hasProperty("godot_editor_version") ? project.property("godot_editor_version") : ""
+ if (editorVersion == null || editorVersion.isEmpty()) {
+ // Try the library version first
+ editorVersion = getGodotLibraryVersion()
+
+ if (editorVersion.isEmpty()) {
+ // Fallback value.
+ editorVersion = "custom_build"
+ }
+ }
+ return editorVersion
+}
+
+ext.getGodotLibraryVersion = { ->
+ // Attempt to read the version from the `version.py` file.
+ String libraryVersion = ""
+
+ File versionFile = new File("../../../version.py")
+ if (versionFile.isFile()) {
+ List<String> requiredKeys = ["major", "minor", "patch", "status", "module_config"]
+ def map = [:]
+
+ List<String> lines = versionFile.readLines()
+ for (String line in lines) {
+ String[] keyValue = line.split("=")
+ String key = keyValue[0].trim()
+ String value = keyValue[1].trim().replaceAll("\"", "")
+
+ if (requiredKeys.contains(key)) {
+ if (!value.isEmpty()) {
+ map[key] = value
+ }
+ requiredKeys.remove(key)
+ }
+ }
+
+ if (requiredKeys.empty) {
+ libraryVersion = map.values().join(".")
+ }
+ }
+
+ if (libraryVersion.isEmpty()) {
+ // Fallback value in case we're unable to read the file.
+ libraryVersion = "custom_build"
+ }
+ return libraryVersion
+}
+
+final String VALUE_SEPARATOR_REGEX = "\\|"
// get the list of ABIs the project should be exported to
ext.getExportEnabledABIs = { ->
@@ -58,7 +108,7 @@ ext.getExportEnabledABIs = { ->
enabledABIs = "armeabi-v7a|arm64-v8a|x86|x86_64|"
}
Set<String> exportAbiFilter = [];
- for (String abi_name : enabledABIs.split(PLUGIN_VALUE_SEPARATOR_REGEX)) {
+ for (String abi_name : enabledABIs.split(VALUE_SEPARATOR_REGEX)) {
if (!abi_name.trim().isEmpty()){
exportAbiFilter.add(abi_name);
}
@@ -93,7 +143,7 @@ ext.getGodotPluginsMavenRepos = { ->
if (project.hasProperty("plugins_maven_repos")) {
String mavenReposProperty = project.property("plugins_maven_repos")
if (mavenReposProperty != null && !mavenReposProperty.trim().isEmpty()) {
- for (String mavenRepoUrl : mavenReposProperty.split(PLUGIN_VALUE_SEPARATOR_REGEX)) {
+ for (String mavenRepoUrl : mavenReposProperty.split(VALUE_SEPARATOR_REGEX)) {
mavenRepos += mavenRepoUrl.trim()
}
}
@@ -113,7 +163,7 @@ ext.getGodotPluginsRemoteBinaries = { ->
if (project.hasProperty("plugins_remote_binaries")) {
String remoteDepsList = project.property("plugins_remote_binaries")
if (remoteDepsList != null && !remoteDepsList.trim().isEmpty()) {
- for (String dep: remoteDepsList.split(PLUGIN_VALUE_SEPARATOR_REGEX)) {
+ for (String dep: remoteDepsList.split(VALUE_SEPARATOR_REGEX)) {
remoteDeps += dep.trim()
}
}
@@ -132,7 +182,7 @@ ext.getGodotPluginsLocalBinaries = { ->
if (project.hasProperty("plugins_local_binaries")) {
String pluginsList = project.property("plugins_local_binaries")
if (pluginsList != null && !pluginsList.trim().isEmpty()) {
- for (String plugin : pluginsList.split(PLUGIN_VALUE_SEPARATOR_REGEX)) {
+ for (String plugin : pluginsList.split(VALUE_SEPARATOR_REGEX)) {
binDeps += plugin.trim()
}
}
diff --git a/platform/android/java/app/res/drawable/splash_drawable.xml b/platform/android/java/app/res/drawable/splash_drawable.xml
index 2794a40817..30627b998c 100644
--- a/platform/android/java/app/res/drawable/splash_drawable.xml
+++ b/platform/android/java/app/res/drawable/splash_drawable.xml
@@ -6,7 +6,7 @@
<item>
<bitmap
android:gravity="center"
+ android:filter="false"
android:src="@drawable/splash" />
</item>
-
</layer-list>
diff --git a/platform/android/java/app/src/com/godot/game/GodotApp.java b/platform/android/java/app/src/com/godot/game/GodotApp.java
index 51df70969e..955446b0c2 100644
--- a/platform/android/java/app/src/com/godot/game/GodotApp.java
+++ b/platform/android/java/app/src/com/godot/game/GodotApp.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle
index 73c136ed0e..ec02b0fc7a 100644
--- a/platform/android/java/build.gradle
+++ b/platform/android/java/build.gradle
@@ -165,12 +165,6 @@ task cleanGodotTemplates(type: Delete) {
// Delete the library generated AAR files
delete("lib/build/outputs/aar")
- // Delete the godotpayment libs directory contents
- delete("plugins/godotpayment/libs")
-
- // Delete the generated godotpayment aar
- delete("plugins/godotpayment/build/outputs/aar")
-
// Delete the app libs directory contents
delete("app/libs")
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index fa39bc0f1d..3034794d69 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -6,6 +6,11 @@
<application>
+ <!-- Records the version of the Godot library -->
+ <meta-data
+ android:name="org.godotengine.library.version"
+ android:value="${godotLibraryVersion}" />
+
<service android:name=".GodotDownloaderService" />
</application>
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index 89ce3d15e6..6fc9a11a08 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -13,9 +13,13 @@ android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
+ ndkVersion versions.ndkVersion
+
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
+
+ manifestPlaceholders = [godotLibraryVersion: getGodotLibraryVersion()]
}
compileOptions {
@@ -68,7 +72,7 @@ android {
File sconsExecutableFile = null
def sconsName = "scons"
def sconsExts = (org.gradle.internal.os.OperatingSystem.current().isWindows()
- ? [".bat", ".exe"]
+ ? [".bat", ".cmd", ".ps1", ".exe"]
: [""])
logger.lifecycle("Looking for $sconsName executable path")
for (ext in sconsExts) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
index 8b7a9c6c74..0572cf3589 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
index 5aa48d87da..4e67402c63 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index ad1dc53bc0..0891904dff 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -464,7 +464,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) {
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
final Activity activity = getActivity();
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
@@ -572,24 +574,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
// This is where you do set up to display the download
- // progress (next step)
+ // progress (next step in onCreateView)
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
GodotDownloaderService.class);
- View downloadingExpansionView =
- inflater.inflate(R.layout.downloading_expansion, container, false);
- mPB = (ProgressBar)downloadingExpansionView.findViewById(R.id.progressBar);
- mStatusText = (TextView)downloadingExpansionView.findViewById(R.id.statusText);
- mProgressFraction = (TextView)downloadingExpansionView.findViewById(R.id.progressAsFraction);
- mProgressPercent = (TextView)downloadingExpansionView.findViewById(R.id.progressAsPercentage);
- mAverageSpeed = (TextView)downloadingExpansionView.findViewById(R.id.progressAverageSpeed);
- mTimeRemaining = (TextView)downloadingExpansionView.findViewById(R.id.progressTimeRemaining);
- mDashboard = downloadingExpansionView.findViewById(R.id.downloaderDashboard);
- mCellMessage = downloadingExpansionView.findViewById(R.id.approveCellular);
- mPauseButton = (Button)downloadingExpansionView.findViewById(R.id.pauseButton);
- mWiFiSettingsButton = (Button)downloadingExpansionView.findViewById(R.id.wifiSettingsButton);
-
- return downloadingExpansionView;
+ return;
}
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
@@ -600,6 +589,27 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
mCurrentIntent = activity.getIntent();
initializeGodot();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) {
+ if (mDownloaderClientStub != null) {
+ View downloadingExpansionView =
+ inflater.inflate(R.layout.downloading_expansion, container, false);
+ mPB = (ProgressBar)downloadingExpansionView.findViewById(R.id.progressBar);
+ mStatusText = (TextView)downloadingExpansionView.findViewById(R.id.statusText);
+ mProgressFraction = (TextView)downloadingExpansionView.findViewById(R.id.progressAsFraction);
+ mProgressPercent = (TextView)downloadingExpansionView.findViewById(R.id.progressAsPercentage);
+ mAverageSpeed = (TextView)downloadingExpansionView.findViewById(R.id.progressAverageSpeed);
+ mTimeRemaining = (TextView)downloadingExpansionView.findViewById(R.id.progressTimeRemaining);
+ mDashboard = downloadingExpansionView.findViewById(R.id.downloaderDashboard);
+ mCellMessage = downloadingExpansionView.findViewById(R.id.approveCellular);
+ mPauseButton = (Button)downloadingExpansionView.findViewById(R.id.pauseButton);
+ mWiFiSettingsButton = (Button)downloadingExpansionView.findViewById(R.id.wifiSettingsButton);
+
+ return downloadingExpansionView;
+ }
+
return containerLayout;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
index a3dae15980..9784d51182 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
index 434da95bc0..d33faab641 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index 2cd67933ee..63c91561ff 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -188,15 +188,15 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
if (GLUtils.use_32) {
setEGLConfigChooser(translucent ?
- new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
+ new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
new RegularConfigChooser(8, 8, 8, 8, 16, stencil)) :
- new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
+ new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
new RegularConfigChooser(5, 6, 5, 0, 16, stencil)));
} else {
setEGLConfigChooser(translucent ?
- new RegularConfigChooser(8, 8, 8, 8, 16, stencil) :
- new RegularConfigChooser(5, 6, 5, 0, 16, stencil));
+ new RegularConfigChooser(8, 8, 8, 8, 16, stencil) :
+ new RegularConfigChooser(5, 6, 5, 0, 16, stencil));
}
break;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index 894009e30f..c7c7c1b40c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
index 965e616ef3..7f5fd8627c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 6ccbe91e60..534a50e9ed 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
index 68b8a16641..2047c88070 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
index 64395f7d1e..59bdbf7f8d 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
index d5e0345a9c..2e59dbc0d0 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
index c95339c583..d1e8ae5ca9 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
index fb151fa504..2c39d06832 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index b052cd9d92..435b8b325f 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,6 +38,8 @@ import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
import android.os.Build;
import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.view.InputDevice;
import android.view.InputDevice.MotionRange;
import android.view.KeyEvent;
@@ -46,17 +48,24 @@ import android.view.MotionEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* Handles input related events for the {@link GodotRenderView} view.
*/
public class GodotInputHandler implements InputDeviceListener {
- private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>();
-
private final GodotRenderView mRenderView;
private final InputManagerCompat mInputManager;
+ private final String tag = this.getClass().getSimpleName();
+
+ private final SparseIntArray mJoystickIds = new SparseIntArray(4);
+ private final SparseArray<Joystick> mJoysticksDevices = new SparseArray<Joystick>(4);
+
public GodotInputHandler(GodotRenderView godotView) {
mRenderView = godotView;
mInputManager = InputManagerCompat.Factory.getInputManager(mRenderView.getView().getContext());
@@ -82,19 +91,20 @@ public class GodotInputHandler implements InputDeviceListener {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
return false;
- };
+ }
int source = event.getSource();
if (isKeyEvent_GameDevice(source)) {
- final int button = getGodotButton(keyCode);
- final int device_id = findJoystickDevice(event.getDeviceId());
-
// Check if the device exists
- if (device_id > -1) {
+ final int deviceId = event.getDeviceId();
+ if (mJoystickIds.indexOfKey(deviceId) >= 0) {
+ final int button = getGodotButton(keyCode);
+ final int godotJoyId = mJoystickIds.get(deviceId);
+
queueEvent(new Runnable() {
@Override
public void run() {
- GodotLib.joybutton(device_id, button, false);
+ GodotLib.joybutton(godotJoyId, button, false);
}
});
}
@@ -107,7 +117,7 @@ public class GodotInputHandler implements InputDeviceListener {
GodotLib.key(keyCode, scanCode, chr, false);
}
});
- };
+ }
return true;
}
@@ -122,24 +132,25 @@ public class GodotInputHandler implements InputDeviceListener {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
return false;
- };
+ }
int source = event.getSource();
//Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD)));
+ final int deviceId = event.getDeviceId();
+ // Check if source is a game device and that the device is a registered gamepad
if (isKeyEvent_GameDevice(source)) {
if (event.getRepeatCount() > 0) // ignore key echo
return true;
- final int button = getGodotButton(keyCode);
- final int device_id = findJoystickDevice(event.getDeviceId());
+ if (mJoystickIds.indexOfKey(deviceId) >= 0) {
+ final int button = getGodotButton(keyCode);
+ final int godotJoyId = mJoystickIds.get(deviceId);
- // Check if the device exists
- if (device_id > -1) {
queueEvent(new Runnable() {
@Override
public void run() {
- GodotLib.joybutton(device_id, button, true);
+ GodotLib.joybutton(godotJoyId, button, true);
}
});
}
@@ -152,7 +163,7 @@ public class GodotInputHandler implements InputDeviceListener {
GodotLib.key(keyCode, scanCode, chr, true);
}
});
- };
+ }
return true;
}
@@ -203,38 +214,52 @@ public class GodotInputHandler implements InputDeviceListener {
}
public boolean onGenericMotionEvent(MotionEvent event) {
- if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
- final int device_id = findJoystickDevice(event.getDeviceId());
-
+ if (event.isFromSource(InputDevice.SOURCE_JOYSTICK) && event.getAction() == MotionEvent.ACTION_MOVE) {
// Check if the device exists
- if (device_id > -1) {
- Joystick joy = mJoysticksDevices.get(device_id);
-
- for (int i = 0; i < joy.axes.size(); i++) {
- InputDevice.MotionRange range = joy.axes.get(i);
- final float value = (event.getAxisValue(range.getAxis()) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
- final int idx = i;
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyaxis(device_id, idx, value);
- }
- });
+ final int deviceId = event.getDeviceId();
+ if (mJoystickIds.indexOfKey(deviceId) >= 0) {
+ final int godotJoyId = mJoystickIds.get(deviceId);
+ Joystick joystick = mJoysticksDevices.get(deviceId);
+
+ for (int i = 0; i < joystick.axes.size(); i++) {
+ final int axis = joystick.axes.get(i);
+ final float value = event.getAxisValue(axis);
+ /**
+ * As all axes are polled for each event, only fire an axis event if the value has actually changed.
+ * Prevents flooding Godot with repeated events.
+ */
+ if (joystick.axesValues.indexOfKey(axis) < 0 || (float)joystick.axesValues.get(axis) != value) {
+ // save value to prevent repeats
+ joystick.axesValues.put(axis, value);
+ final int godotAxisIdx = i;
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyaxis(godotJoyId, godotAxisIdx, value);
+ //Log.i(tag, "GodotLib.joyaxis("+godotJoyId+", "+godotAxisIdx+", "+value+");");
+ }
+ });
+ }
}
- for (int i = 0; i < joy.hats.size(); i += 2) {
- final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
- final int hatY = Math.round(event.getAxisValue(joy.hats.get(i + 1).getAxis()));
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyhat(device_id, hatX, hatY);
- }
- });
+ if (joystick.hasAxisHat) {
+ final int hatX = Math.round(event.getAxisValue(MotionEvent.AXIS_HAT_X));
+ final int hatY = Math.round(event.getAxisValue(MotionEvent.AXIS_HAT_Y));
+ if (joystick.hatX != hatX || joystick.hatY != hatY) {
+ joystick.hatX = hatX;
+ joystick.hatY = hatY;
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyhat(godotJoyId, hatX, hatY);
+ //Log.i(tag, "GodotLib.joyhat("+godotJoyId+", "+hatX+", "+hatY+");");
+ }
+ });
+ }
}
return true;
}
- } else if ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) {
+ } else if (event.isFromSource(InputDevice.SOURCE_STYLUS)) {
final float x = event.getX();
final float y = event.getY();
final int type = event.getAction();
@@ -245,6 +270,7 @@ public class GodotInputHandler implements InputDeviceListener {
}
});
return true;
+
} else if (event.isFromSource(InputDevice.SOURCE_MOUSE) || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return handleMouseEvent(event);
@@ -266,67 +292,98 @@ public class GodotInputHandler implements InputDeviceListener {
}
}
+ private int assignJoystickIdNumber(int deviceId) {
+ int godotJoyId = 0;
+ while (mJoystickIds.indexOfValue(godotJoyId) >= 0) {
+ godotJoyId++;
+ }
+ mJoystickIds.put(deviceId, godotJoyId);
+ return godotJoyId;
+ }
+
@Override
public void onInputDeviceAdded(int deviceId) {
- int id = findJoystickDevice(deviceId);
-
// Check if the device has not been already added
- if (id < 0) {
- InputDevice device = mInputManager.getInputDevice(deviceId);
- //device can be null if deviceId is not found
- if (device != null) {
- int sources = device.getSources();
- if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ||
- ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) {
- id = mJoysticksDevices.size();
-
- Joystick joy = new Joystick();
- joy.device_id = deviceId;
- joy.name = device.getName();
- joy.axes = new ArrayList<InputDevice.MotionRange>();
- joy.hats = new ArrayList<InputDevice.MotionRange>();
-
- List<InputDevice.MotionRange> ranges = device.getMotionRanges();
- Collections.sort(ranges, new RangeComparator());
-
- for (InputDevice.MotionRange range : ranges) {
- if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
- joy.hats.add(range);
- } else {
- joy.axes.add(range);
- }
- }
- mJoysticksDevices.add(joy);
+ if (mJoystickIds.indexOfKey(deviceId) >= 0) {
+ return;
+ }
+
+ InputDevice device = mInputManager.getInputDevice(deviceId);
+ //device can be null if deviceId is not found
+ if (device == null) {
+ return;
+ }
+
+ int sources = device.getSources();
+
+ // Device may not be a joystick or gamepad
+ if ((sources & InputDevice.SOURCE_GAMEPAD) != InputDevice.SOURCE_GAMEPAD &&
+ (sources & InputDevice.SOURCE_JOYSTICK) != InputDevice.SOURCE_JOYSTICK) {
+ return;
+ }
+
+ // Assign first available number. Re-use numbers where possible.
+ final int id = assignJoystickIdNumber(deviceId);
+
+ final Joystick joystick = new Joystick();
+ joystick.device_id = deviceId;
+ joystick.name = device.getName();
+
+ //Helps with creating new joypad mappings.
+ Log.i(tag, "=== New Input Device: " + joystick.name);
- final int device_id = id;
- final String name = joy.name;
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyconnectionchanged(device_id, true, name);
- }
- });
+ Set<Integer> already = new HashSet<Integer>();
+ for (InputDevice.MotionRange range : device.getMotionRanges()) {
+ boolean isJoystick = range.isFromSource(InputDevice.SOURCE_JOYSTICK);
+ boolean isGamepad = range.isFromSource(InputDevice.SOURCE_GAMEPAD);
+ //Log.i(tag, "axis: "+range.getAxis()+ ", isJoystick: "+isJoystick+", isGamepad: "+isGamepad);
+ if (!isJoystick && !isGamepad) {
+ continue;
+ }
+ final int axis = range.getAxis();
+ if (axis == MotionEvent.AXIS_HAT_X || axis == MotionEvent.AXIS_HAT_Y) {
+ joystick.hasAxisHat = true;
+ } else {
+ if (!already.contains(axis)) {
+ already.add(axis);
+ joystick.axes.add(axis);
+ } else {
+ Log.w(tag, " - DUPLICATE AXIS VALUE IN LIST: " + axis);
}
}
}
+ Collections.sort(joystick.axes);
+ for (int idx = 0; idx < joystick.axes.size(); idx++) {
+ //Helps with creating new joypad mappings.
+ Log.i(tag, " - Mapping Android axis " + joystick.axes.get(idx) + " to Godot axis " + idx);
+ }
+ mJoysticksDevices.put(deviceId, joystick);
+
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyconnectionchanged(id, true, joystick.name);
+ }
+ });
}
@Override
public void onInputDeviceRemoved(int deviceId) {
- final int device_id = findJoystickDevice(deviceId);
-
- // Check if the evice has not been already removed
- if (device_id > -1) {
- mJoysticksDevices.remove(device_id);
-
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.joyconnectionchanged(device_id, false, "");
- }
- });
+ // Check if the device has not been already removed
+ if (mJoystickIds.indexOfKey(deviceId) < 0) {
+ return;
}
+ final int godotJoyId = mJoystickIds.get(deviceId);
+ mJoystickIds.delete(deviceId);
+ mJoysticksDevices.delete(deviceId);
+
+ queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.joyconnectionchanged(godotJoyId, false, "");
+ }
+ });
}
@Override
@@ -407,16 +464,6 @@ public class GodotInputHandler implements InputDeviceListener {
return button;
}
- private int findJoystickDevice(int device_id) {
- for (int i = 0; i < mJoysticksDevices.size(); i++) {
- if (mJoysticksDevices.get(i).device_id == device_id) {
- return i;
- }
- }
-
- return -1;
- }
-
private boolean handleMouseEvent(final MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_HOVER_ENTER:
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index 4dd1054738..3e0e6a65fd 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
index 1f3fe1e527..4b7318c718 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,9 +30,10 @@
package org.godotengine.godot.input;
-import android.view.InputDevice.MotionRange;
+import android.util.SparseArray;
import java.util.ArrayList;
+import java.util.List;
/**
* POJO class to represent a Joystick input device.
@@ -40,6 +41,12 @@ import java.util.ArrayList;
class Joystick {
int device_id;
String name;
- ArrayList<MotionRange> axes;
- ArrayList<MotionRange> hats;
+ List<Integer> axes = new ArrayList<Integer>();
+ protected boolean hasAxisHat = false;
+ /*
+ * Keep track of values so we can prevent flooding the engine with useless events.
+ */
+ protected final SparseArray axesValues = new SparseArray<Float>(4);
+ protected int hatX;
+ protected int hatY;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
index 93c204935c..993f0e9127 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,9 @@ import androidx.annotation.Nullable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -107,14 +109,47 @@ public abstract class GodotPlugin {
* This method is invoked on the render thread.
*/
public final void onRegisterPluginWithGodotNative() {
- nativeRegisterSingleton(getPluginName());
+ registeredSignals.putAll(registerPluginWithGodotNative(this, new GodotPluginInfoProvider() {
+ @NonNull
+ @Override
+ public String getPluginName() {
+ return GodotPlugin.this.getPluginName();
+ }
+
+ @NonNull
+ @Override
+ public List<String> getPluginMethods() {
+ return GodotPlugin.this.getPluginMethods();
+ }
+
+ @NonNull
+ @Override
+ public Set<SignalInfo> getPluginSignals() {
+ return GodotPlugin.this.getPluginSignals();
+ }
+
+ @NonNull
+ @Override
+ public Set<String> getPluginGDNativeLibrariesPaths() {
+ return GodotPlugin.this.getPluginGDNativeLibrariesPaths();
+ }
+ }));
+ }
- Class clazz = getClass();
+ /**
+ * Register the plugin with Godot native code.
+ *
+ * This method must be invoked on the render thread.
+ */
+ public static Map<String, SignalInfo> registerPluginWithGodotNative(Object pluginObject, GodotPluginInfoProvider pluginInfoProvider) {
+ nativeRegisterSingleton(pluginInfoProvider.getPluginName(), pluginObject);
+
+ Class clazz = pluginObject.getClass();
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
boolean found = false;
- for (String s : getPluginMethods()) {
+ for (String s : pluginInfoProvider.getPluginMethods()) {
if (s.equals(method.getName())) {
found = true;
break;
@@ -123,7 +158,7 @@ public abstract class GodotPlugin {
if (!found)
continue;
- List<String> ptr = new ArrayList<String>();
+ List<String> ptr = new ArrayList<>();
Class[] paramTypes = method.getParameterTypes();
for (Class c : paramTypes) {
@@ -133,26 +168,29 @@ public abstract class GodotPlugin {
String[] pt = new String[ptr.size()];
ptr.toArray(pt);
- nativeRegisterMethod(getPluginName(), method.getName(), method.getReturnType().getName(), pt);
+ nativeRegisterMethod(pluginInfoProvider.getPluginName(), method.getName(), method.getReturnType().getName(), pt);
}
// Register the signals for this plugin.
- for (SignalInfo signalInfo : getPluginSignals()) {
+ Map<String, SignalInfo> registeredSignals = new HashMap<>();
+ for (SignalInfo signalInfo : pluginInfoProvider.getPluginSignals()) {
String signalName = signalInfo.getName();
- nativeRegisterSignal(getPluginName(), signalName, signalInfo.getParamTypesNames());
+ nativeRegisterSignal(pluginInfoProvider.getPluginName(), signalName, signalInfo.getParamTypesNames());
registeredSignals.put(signalName, signalInfo);
}
// Get the list of gdnative libraries to register.
- Set<String> gdnativeLibrariesPaths = getPluginGDNativeLibrariesPaths();
+ Set<String> gdnativeLibrariesPaths = pluginInfoProvider.getPluginGDNativeLibrariesPaths();
if (!gdnativeLibrariesPaths.isEmpty()) {
nativeRegisterGDNativeLibraries(gdnativeLibrariesPaths.toArray(new String[0]));
}
+
+ return registeredSignals;
}
/**
* Invoked once during the Godot Android initialization process after creation of the
- * {@link org.godotengine.godot.GodotView} view.
+ * {@link org.godotengine.godot.GodotRenderView} view.
* <p>
* The plugin can return a non-null {@link View} layout in order to add it to the Godot view
* hierarchy.
@@ -290,8 +328,8 @@ public abstract class GodotPlugin {
/**
* Emit a registered Godot signal.
- * @param signalName
- * @param signalArgs
+ * @param signalName Name of the signal to emit. It will be validated against the set of registered signals.
+ * @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the {@link SignalInfo} matching the registered signalName parameter.
*/
protected void emitSignal(final String signalName, final Object... signalArgs) {
try {
@@ -301,6 +339,27 @@ public abstract class GodotPlugin {
throw new IllegalArgumentException(
"Signal " + signalName + " is not registered for this plugin.");
}
+ emitSignal(getGodot(), getPluginName(), signalInfo, signalArgs);
+ } catch (IllegalArgumentException exception) {
+ Log.w(TAG, exception.getMessage());
+ if (BuildConfig.DEBUG) {
+ throw exception;
+ }
+ }
+ }
+
+ /**
+ * Emit a Godot signal.
+ * @param godot
+ * @param pluginName Name of the Godot plugin the signal will be emitted from. The plugin must already be registered with the Godot engine.
+ * @param signalInfo Information about the signal to emit.
+ * @param signalArgs Arguments used to populate the emitted signal. The arguments will be validated against the given {@link SignalInfo} parameter.
+ */
+ public static void emitSignal(Godot godot, String pluginName, SignalInfo signalInfo, final Object... signalArgs) {
+ try {
+ if (signalInfo == null) {
+ throw new IllegalArgumentException("Signal must be non null.");
+ }
// Validate the arguments count.
Class<?>[] signalParamTypes = signalInfo.getParamTypes();
@@ -317,12 +376,8 @@ public abstract class GodotPlugin {
}
}
- runOnRenderThread(new Runnable() {
- @Override
- public void run() {
- nativeEmitSignal(getPluginName(), signalName, signalArgs);
- }
- });
+ godot.runOnRenderThread(() -> nativeEmitSignal(pluginName, signalInfo.getName(), signalArgs));
+
} catch (IllegalArgumentException exception) {
Log.w(TAG, exception.getMessage());
if (BuildConfig.DEBUG) {
@@ -335,7 +390,7 @@ public abstract class GodotPlugin {
* Used to setup a {@link GodotPlugin} instance.
* @param p_name Name of the instance.
*/
- private native void nativeRegisterSingleton(String p_name);
+ private static native void nativeRegisterSingleton(String p_name, Object object);
/**
* Used to complete registration of the {@link GodotPlugin} instance's methods.
@@ -344,13 +399,13 @@ public abstract class GodotPlugin {
* @param p_ret Return type of the registered method
* @param p_params Method parameters types
*/
- private native void nativeRegisterMethod(String p_sname, String p_name, String p_ret, String[] p_params);
+ private static native void nativeRegisterMethod(String p_sname, String p_name, String p_ret, String[] p_params);
/**
* Used to register gdnative libraries bundled by the plugin.
* @param gdnlibPaths Paths to the libraries relative to the 'assets' directory.
*/
- private native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths);
+ private static native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths);
/**
* Used to complete registration of the {@link GodotPlugin} instance's methods.
@@ -358,7 +413,7 @@ public abstract class GodotPlugin {
* @param signalName Name of the signal to register
* @param signalParamTypes Signal parameters types
*/
- private native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes);
+ private static native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes);
/**
* Used to emit signal by {@link GodotPlugin} instance.
@@ -366,5 +421,5 @@ public abstract class GodotPlugin {
* @param signalName Name of the signal to emit
* @param signalParams Signal parameters
*/
- private native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams);
+ private static native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams);
}
diff --git a/modules/arkit/arkit_session_delegate.h b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java
index df98bf506e..c3084b036e 100644
--- a/modules/arkit/arkit_session_delegate.h
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginInfoProvider.java
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* arkit_session_delegate.h */
+/* GodotPluginInfoProvider.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,23 +28,40 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARKIT_SESSION_DELEGATE_H
-#define ARKIT_SESSION_DELEGATE_H
+package org.godotengine.godot.plugin;
-#import <ARKit/ARKit.h>
-#import <UIKit/UIKit.h>
+import androidx.annotation.NonNull;
-class ARKitInterface;
+import java.util.List;
+import java.util.Set;
-@interface ARKitSessionDelegate : NSObject <ARSessionDelegate> {
- ARKitInterface *arkit_interface;
-}
+/**
+ * Provides the set of information expected from a Godot plugin.
+ */
+public interface GodotPluginInfoProvider {
+ /**
+ * Returns the name of the plugin.
+ */
+ @NonNull
+ String getPluginName();
-@property(nonatomic) ARKitInterface *arkit_interface;
+ /**
+ * Returns the list of methods to be exposed to Godot.
+ */
+ @NonNull
+ List<String> getPluginMethods();
-- (void)session:(ARSession *)session didAddAnchors:(NSArray<ARAnchor *> *)anchors API_AVAILABLE(ios(11.0));
-- (void)session:(ARSession *)session didRemoveAnchors:(NSArray<ARAnchor *> *)anchors API_AVAILABLE(ios(11.0));
-- (void)session:(ARSession *)session didUpdateAnchors:(NSArray<ARAnchor *> *)anchors API_AVAILABLE(ios(11.0));
-@end
+ /**
+ * Returns the list of signals to be exposed to Godot.
+ */
+ @NonNull
+ Set<SignalInfo> getPluginSignals();
-#endif /* !ARKIT_SESSION_DELEGATE_H */
+ /**
+ * Returns the paths for the plugin's gdnative libraries (if any).
+ *
+ * The paths must be relative to the 'assets' directory and point to a '*.gdnlib' file.
+ */
+ @NonNull
+ Set<String> getPluginGDNativeLibrariesPaths();
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
index 1c2d1a6563..5b41205253 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,8 +44,6 @@ import androidx.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -56,13 +54,6 @@ public final class GodotPluginRegistry {
private static final String GODOT_PLUGIN_V1_NAME_PREFIX = "org.godotengine.plugin.v1.";
- /**
- * Name for the metadata containing the list of Godot plugins to enable.
- */
- private static final String GODOT_ENABLED_PLUGINS_LABEL = "plugins";
-
- private static final String PLUGIN_VALUE_SEPARATOR_REGEX = "\\|";
-
private static GodotPluginRegistry instance;
private final ConcurrentHashMap<String, GodotPlugin> registry;
@@ -132,37 +123,11 @@ public final class GodotPluginRegistry {
return;
}
- // When using the Godot editor for building and exporting the apk, this is used to check
- // which plugins to enable.
- // When using a custom process to generate the apk, the metadata is not needed since
- // it's assumed that the developer is aware of the dependencies included in the apk.
- final Set<String> enabledPluginsSet;
- if (metaData.containsKey(GODOT_ENABLED_PLUGINS_LABEL)) {
- String enabledPlugins = metaData.getString(GODOT_ENABLED_PLUGINS_LABEL, "");
- String[] enabledPluginsList = enabledPlugins.split(PLUGIN_VALUE_SEPARATOR_REGEX);
- if (enabledPluginsList.length == 0) {
- // No plugins to enable. Aborting early.
- return;
- }
-
- enabledPluginsSet = new HashSet<>();
- for (String enabledPlugin : enabledPluginsList) {
- enabledPluginsSet.add(enabledPlugin.trim());
- }
- } else {
- enabledPluginsSet = null;
- }
-
int godotPluginV1NamePrefixLength = GODOT_PLUGIN_V1_NAME_PREFIX.length();
for (String metaDataName : metaData.keySet()) {
// Parse the meta-data looking for entry with the Godot plugin name prefix.
if (metaDataName.startsWith(GODOT_PLUGIN_V1_NAME_PREFIX)) {
String pluginName = metaDataName.substring(godotPluginV1NamePrefixLength).trim();
- if (enabledPluginsSet != null && !enabledPluginsSet.contains(pluginName)) {
- Log.w(TAG, "Plugin " + pluginName + " is listed in the dependencies but is not enabled.");
- continue;
- }
-
Log.i(TAG, "Initializing Godot plugin " + pluginName);
// Retrieve the plugin class full name.
@@ -177,8 +142,7 @@ public final class GodotPluginRegistry {
.getConstructor(Godot.class);
GodotPlugin pluginHandle = pluginConstructor.newInstance(godot);
- // Load the plugin initializer into the registry using the plugin name
- // as key.
+ // Load the plugin initializer into the registry using the plugin name as key.
if (!pluginName.equals(pluginHandle.getPluginName())) {
Log.w(TAG,
"Meta-data plugin name does not match the value returned by the plugin handle: " + pluginName + " =/= " + pluginHandle.getPluginName());
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
index f82c4d3fa0..6428422641 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
index acc9c4981b..d6e49bb635 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
index 82420eda79..19588f8465 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
index c89118ad55..721d7c65c6 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
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 7104baf86e..b0ca96271e 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
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
index f93cf0fa38..a35f6ec5a7 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
index e5c7a39bfb..f0e37d80b8 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
index fb02e3a69f..b967fd5f24 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java
index 982e43f9d1..0995477baf 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
index 819bcccdf1..245d573bfc 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
index 2d9b921466..d3aca267ef 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
index 43c7f0f966..83aa458064 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
index 54672db282..341427209b 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
index 126f3ad5f5..71610d2d00 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
index c83c47bed7..e690c5b695 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java/nativeSrcsConfigs/build.gradle b/platform/android/java/nativeSrcsConfigs/build.gradle
index 65b7bb9dc9..66077060ea 100644
--- a/platform/android/java/nativeSrcsConfigs/build.gradle
+++ b/platform/android/java/nativeSrcsConfigs/build.gradle
@@ -31,6 +31,8 @@ android {
}
}
+ ndkVersion versions.ndkVersion
+
externalNativeBuild {
cmake {
path "CMakeLists.txt"
diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp
index 9b44ac4b41..ab03599dc3 100644
--- a/platform/android/java_class_wrapper.cpp
+++ b/platform/android/java_class_wrapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,7 +37,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
if (!M)
return false;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
MethodInfo *method = nullptr;
for (List<MethodInfo>::Element *E = M->get().front(); E; E = E->next()) {
@@ -964,7 +964,7 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
if (class_cache.has(p_class))
return class_cache[p_class];
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass bclass = env->FindClass(p_class.utf8().get_data());
ERR_FAIL_COND_V(!bclass, Ref<JavaClass>());
@@ -1148,7 +1148,7 @@ JavaClassWrapper *JavaClassWrapper::singleton = nullptr;
JavaClassWrapper::JavaClassWrapper(jobject p_activity) {
singleton = this;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass activityClass = env->FindClass("android/app/Activity");
jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp
index 8d1db395ab..41201db32b 100644
--- a/platform/android/java_godot_io_wrapper.cpp
+++ b/platform/android/java_godot_io_wrapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,7 +34,7 @@
// JNIEnv is only valid within the thread it belongs to, in a multi threading environment
// we can't cache it.
// For GodotIO we call all access methods from our thread and we thus get a valid JNIEnv
-// from ThreadAndroid.
+// from get_jni_env().
GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instance) {
godot_io_instance = p_env->NewGlobalRef(p_godot_io_instance);
@@ -72,7 +72,7 @@ jobject GodotIOJavaWrapper::get_instance() {
Error GodotIOJavaWrapper::open_uri(const String &p_uri) {
if (_open_URI) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStr = env->NewStringUTF(p_uri.utf8().get_data());
return env->CallIntMethod(godot_io_instance, _open_URI, jStr) ? ERR_CANT_OPEN : OK;
} else {
@@ -82,7 +82,7 @@ Error GodotIOJavaWrapper::open_uri(const String &p_uri) {
String GodotIOJavaWrapper::get_user_data_dir() {
if (_get_data_dir) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_data_dir);
return jstring_to_string(s, env);
} else {
@@ -92,7 +92,7 @@ String GodotIOJavaWrapper::get_user_data_dir() {
String GodotIOJavaWrapper::get_locale() {
if (_get_locale) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_locale);
return jstring_to_string(s, env);
} else {
@@ -102,7 +102,7 @@ String GodotIOJavaWrapper::get_locale() {
String GodotIOJavaWrapper::get_model() {
if (_get_model) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_model);
return jstring_to_string(s, env);
} else {
@@ -112,7 +112,7 @@ String GodotIOJavaWrapper::get_model() {
int GodotIOJavaWrapper::get_screen_dpi() {
if (_get_screen_DPI) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallIntMethod(godot_io_instance, _get_screen_DPI);
} else {
return 160;
@@ -121,7 +121,7 @@ int GodotIOJavaWrapper::get_screen_dpi() {
void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) {
if (_screen_get_usable_rect) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _screen_get_usable_rect);
ERR_FAIL_COND(env->GetArrayLength(returnArray) != 4);
jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE);
@@ -134,7 +134,7 @@ void GodotIOJavaWrapper::screen_get_usable_rect(int (&p_rect_xywh)[4]) {
String GodotIOJavaWrapper::get_unique_id() {
if (_get_unique_id) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_unique_id);
return jstring_to_string(s, env);
} else {
@@ -148,7 +148,7 @@ bool GodotIOJavaWrapper::has_vk() {
void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
if (_show_keyboard) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);
}
@@ -156,21 +156,21 @@ void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int
void GodotIOJavaWrapper::hide_vk() {
if (_hide_keyboard) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_io_instance, _hide_keyboard);
}
}
void GodotIOJavaWrapper::set_screen_orientation(int p_orient) {
if (_set_screen_orientation) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_io_instance, _set_screen_orientation, p_orient);
}
}
int GodotIOJavaWrapper::get_screen_orientation() {
if (_get_screen_orientation) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallIntMethod(godot_io_instance, _get_screen_orientation);
} else {
return 0;
@@ -179,7 +179,7 @@ int GodotIOJavaWrapper::get_screen_orientation() {
String GodotIOJavaWrapper::get_system_dir(int p_dir) {
if (_get_system_dir) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir);
return jstring_to_string(s, env);
} else {
@@ -187,14 +187,14 @@ String GodotIOJavaWrapper::get_system_dir(int p_dir) {
}
}
-// volatile because it can be changed from non-main thread and we need to
+// SafeNumeric because it can be changed from non-main thread and we need to
// ensure the change is immediately visible to other threads.
-static volatile int virtual_keyboard_height;
+static SafeNumeric<int> virtual_keyboard_height;
int GodotIOJavaWrapper::get_vk_height() {
- return virtual_keyboard_height;
+ return virtual_keyboard_height.get();
}
void GodotIOJavaWrapper::set_vk_height(int p_height) {
- virtual_keyboard_height = p_height;
+ virtual_keyboard_height.set(p_height);
}
diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h
index 13270c794b..394e97effa 100644
--- a/platform/android/java_godot_io_wrapper.h
+++ b/platform/android/java_godot_io_wrapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 48b8171222..bb22162879 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -87,7 +87,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
godot_java = new GodotJavaWrapper(env, activity, godot_instance);
godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env));
- ThreadAndroid::make_default(jvm);
+ init_thread_jandroid(jvm, env);
jobject amgr = env->NewGlobalRef(p_asset_manager);
@@ -119,7 +119,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline) {
- ThreadAndroid::setup_thread();
+ setup_android_thread();
const char **cmdline = nullptr;
jstring *j_cmdline = nullptr;
@@ -206,7 +206,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
return;
if (step == 0) {
- // Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id,
+ // Since Godot is initialized on the UI thread, main_thread_id was set to that thread's id,
// but for Godot purposes, the main thread is the one running the game loop
Main::setup2(Thread::get_caller_id());
++step;
@@ -382,7 +382,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env,
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jclass clazz) {
- ThreadAndroid::setup_thread();
+ setup_android_thread();
AudioDriverAndroid::thread_func(env);
}
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index b499f6dfa1..a3e2933185 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java_godot_view_wrapper.cpp b/platform/android/java_godot_view_wrapper.cpp
index 6655dd9895..5b638300ef 100644
--- a/platform/android/java_godot_view_wrapper.cpp
+++ b/platform/android/java_godot_view_wrapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,7 +33,7 @@
#include "thread_jandroid.h"
GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
_godot_view = env->NewGlobalRef(godot_view);
@@ -47,20 +47,20 @@ GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) {
void GodotJavaViewWrapper::request_pointer_capture() {
if (_request_pointer_capture != 0) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(_godot_view, _request_pointer_capture);
}
}
void GodotJavaViewWrapper::release_pointer_capture() {
if (_request_pointer_capture != 0) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(_godot_view, _release_pointer_capture);
}
}
GodotJavaViewWrapper::~GodotJavaViewWrapper() {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->DeleteGlobalRef(_godot_view);
env->DeleteGlobalRef(_cls);
}
diff --git a/platform/android/java_godot_view_wrapper.h b/platform/android/java_godot_view_wrapper.h
index 4c8f6edad0..548c278292 100644
--- a/platform/android/java_godot_view_wrapper.h
+++ b/platform/android/java_godot_view_wrapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp
index 818e55476e..759980373a 100644
--- a/platform/android/java_godot_wrapper.cpp
+++ b/platform/android/java_godot_wrapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,7 +33,7 @@
// JNIEnv is only valid within the thread it belongs to, in a multi threading environment
// we can't cache it.
// For Godot we call most access methods from our thread and we thus get a valid JNIEnv
-// from ThreadAndroid. For one or two we expect to pass the environment
+// from get_jni_env(). For one or two we expect to pass the environment
// TODO we could probably create a base class for this...
@@ -91,7 +91,7 @@ jobject GodotJavaWrapper::get_activity() {
jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) {
if (godot_class) {
if (p_env == nullptr)
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
jfieldID fid = p_env->GetStaticFieldID(godot_class, p_name, p_class);
return p_env->GetStaticObjectField(godot_class, fid);
@@ -102,7 +102,7 @@ jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_cl
jobject GodotJavaWrapper::get_class_loader() {
if (_get_class_loader) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallObjectMethod(activity, _get_class_loader);
} else {
return nullptr;
@@ -113,7 +113,7 @@ GodotJavaViewWrapper *GodotJavaWrapper::get_godot_view() {
if (_godot_view != nullptr) {
return _godot_view;
}
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jmethodID godot_view_getter = env->GetMethodID(godot_class, "getRenderView", "()Lorg/godotengine/godot/GodotRenderView;");
_godot_view = new GodotJavaViewWrapper(env->CallObjectMethod(godot_instance, godot_view_getter));
return _godot_view;
@@ -122,7 +122,7 @@ GodotJavaViewWrapper *GodotJavaWrapper::get_godot_view() {
void GodotJavaWrapper::on_video_init(JNIEnv *p_env) {
if (_on_video_init)
if (p_env == nullptr)
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
p_env->CallVoidMethod(godot_instance, _on_video_init);
}
@@ -130,7 +130,7 @@ void GodotJavaWrapper::on_video_init(JNIEnv *p_env) {
void GodotJavaWrapper::on_godot_main_loop_started(JNIEnv *p_env) {
if (_on_godot_main_loop_started) {
if (p_env == nullptr) {
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
}
}
p_env->CallVoidMethod(godot_instance, _on_godot_main_loop_started);
@@ -139,7 +139,7 @@ void GodotJavaWrapper::on_godot_main_loop_started(JNIEnv *p_env) {
void GodotJavaWrapper::restart(JNIEnv *p_env) {
if (_restart)
if (p_env == nullptr)
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
p_env->CallVoidMethod(godot_instance, _restart);
}
@@ -147,21 +147,21 @@ void GodotJavaWrapper::restart(JNIEnv *p_env) {
void GodotJavaWrapper::force_quit(JNIEnv *p_env) {
if (_finish)
if (p_env == nullptr)
- p_env = ThreadAndroid::get_env();
+ p_env = get_jni_env();
p_env->CallVoidMethod(godot_instance, _finish);
}
void GodotJavaWrapper::set_keep_screen_on(bool p_enabled) {
if (_set_keep_screen_on) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_instance, _set_keep_screen_on, p_enabled);
}
}
void GodotJavaWrapper::alert(const String &p_message, const String &p_title) {
if (_alert) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStrMessage = env->NewStringUTF(p_message.utf8().get_data());
jstring jStrTitle = env->NewStringUTF(p_title.utf8().get_data());
env->CallVoidMethod(godot_instance, _alert, jStrMessage, jStrTitle);
@@ -169,7 +169,7 @@ void GodotJavaWrapper::alert(const String &p_message, const String &p_title) {
}
int GodotJavaWrapper::get_gles_version_code() {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
if (_get_GLES_version_code) {
return env->CallIntMethod(godot_instance, _get_GLES_version_code);
}
@@ -183,7 +183,7 @@ bool GodotJavaWrapper::has_get_clipboard() {
String GodotJavaWrapper::get_clipboard() {
if (_get_clipboard) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring s = (jstring)env->CallObjectMethod(godot_instance, _get_clipboard);
return jstring_to_string(s, env);
} else {
@@ -193,7 +193,7 @@ String GodotJavaWrapper::get_clipboard() {
String GodotJavaWrapper::get_input_fallback_mapping() {
if (_get_input_fallback_mapping) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring fallback_mapping = (jstring)env->CallObjectMethod(godot_instance, _get_input_fallback_mapping);
return jstring_to_string(fallback_mapping, env);
} else {
@@ -207,7 +207,7 @@ bool GodotJavaWrapper::has_set_clipboard() {
void GodotJavaWrapper::set_clipboard(const String &p_text) {
if (_set_clipboard) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStr = env->NewStringUTF(p_text.utf8().get_data());
env->CallVoidMethod(godot_instance, _set_clipboard, jStr);
}
@@ -215,7 +215,7 @@ void GodotJavaWrapper::set_clipboard(const String &p_text) {
bool GodotJavaWrapper::request_permission(const String &p_name) {
if (_request_permission) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jstring jStrName = env->NewStringUTF(p_name.utf8().get_data());
return env->CallBooleanMethod(godot_instance, _request_permission, jStrName);
} else {
@@ -225,7 +225,7 @@ bool GodotJavaWrapper::request_permission(const String &p_name) {
bool GodotJavaWrapper::request_permissions() {
if (_request_permissions) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallBooleanMethod(godot_instance, _request_permissions);
} else {
return false;
@@ -235,7 +235,7 @@ bool GodotJavaWrapper::request_permissions() {
Vector<String> GodotJavaWrapper::get_granted_permissions() const {
Vector<String> permissions_list;
if (_get_granted_permissions) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jobject permissions_object = env->CallObjectMethod(godot_instance, _get_granted_permissions);
jobjectArray *arr = reinterpret_cast<jobjectArray *>(&permissions_object);
@@ -253,14 +253,14 @@ Vector<String> GodotJavaWrapper::get_granted_permissions() const {
void GodotJavaWrapper::init_input_devices() {
if (_init_input_devices) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_instance, _init_input_devices);
}
}
jobject GodotJavaWrapper::get_surface() {
if (_get_surface) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallObjectMethod(godot_instance, _get_surface);
} else {
return nullptr;
@@ -269,7 +269,7 @@ jobject GodotJavaWrapper::get_surface() {
bool GodotJavaWrapper::is_activity_resumed() {
if (_is_activity_resumed) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
return env->CallBooleanMethod(godot_instance, _is_activity_resumed);
} else {
return false;
@@ -278,7 +278,7 @@ bool GodotJavaWrapper::is_activity_resumed() {
void GodotJavaWrapper::vibrate(int p_duration_ms) {
if (_vibrate) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(godot_instance, _vibrate, p_duration_ms);
}
}
diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h
index c212e107cb..99a60dffa1 100644
--- a/platform/android/java_godot_wrapper.h
+++ b/platform/android/java_godot_wrapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/jni_utils.cpp b/platform/android/jni_utils.cpp
index 8e1ae53b78..94652ab7ac 100644
--- a/platform/android/jni_utils.cpp
+++ b/platform/android/jni_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/jni_utils.h b/platform/android/jni_utils.h
index bda056604f..f2b89392b5 100644
--- a/platform/android/jni_utils.h
+++ b/platform/android/jni_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/net_socket_android.cpp b/platform/android/net_socket_android.cpp
index 0341ef3ec6..ddc2368793 100644
--- a/platform/android/net_socket_android.cpp
+++ b/platform/android/net_socket_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,7 @@ jmethodID NetSocketAndroid::_multicast_lock_acquire = 0;
jmethodID NetSocketAndroid::_multicast_lock_release = 0;
void NetSocketAndroid::setup(jobject p_net_utils) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
net_utils = env->NewGlobalRef(p_net_utils);
@@ -51,14 +51,14 @@ void NetSocketAndroid::setup(jobject p_net_utils) {
void NetSocketAndroid::multicast_lock_acquire() {
if (_multicast_lock_acquire) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(net_utils, _multicast_lock_acquire);
}
}
void NetSocketAndroid::multicast_lock_release() {
if (_multicast_lock_release) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
env->CallVoidMethod(net_utils, _multicast_lock_release);
}
}
diff --git a/platform/android/net_socket_android.h b/platform/android/net_socket_android.h
index 955d906535..cc2a68ac49 100644
--- a/platform/android/net_socket_android.h
+++ b/platform/android/net_socket_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index b90fb3ce6e..422814dd50 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -139,7 +139,7 @@ MainLoop *OS_Android::get_main_loop() const {
void OS_Android::main_loop_begin() {
if (main_loop)
- main_loop->init();
+ main_loop->initialize();
}
bool OS_Android::main_loop_iterate() {
@@ -151,7 +151,7 @@ bool OS_Android::main_loop_iterate() {
void OS_Android::main_loop_end() {
if (main_loop)
- main_loop->finish();
+ main_loop->finalize();
}
void OS_Android::main_loop_focusout() {
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index d9a07411ad..dd14b69cf9 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/platform_config.h b/platform/android/platform_config.h
index c5e896c4e1..601db9951f 100644
--- a/platform/android/platform_config.h
+++ b/platform/android/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/plugin/godot_plugin_config.h b/platform/android/plugin/godot_plugin_config.h
index ecb9c0c7f5..173ac115a2 100644
--- a/platform/android/plugin/godot_plugin_config.h
+++ b/platform/android/plugin/godot_plugin_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,23 +35,6 @@
#include "core/io/config_file.h"
#include "core/string/ustring.h"
-static const char *PLUGIN_CONFIG_EXT = ".gdap";
-
-static const char *CONFIG_SECTION = "config";
-static const char *CONFIG_NAME_KEY = "name";
-static const char *CONFIG_BINARY_TYPE_KEY = "binary_type";
-static const char *CONFIG_BINARY_KEY = "binary";
-
-static const char *DEPENDENCIES_SECTION = "dependencies";
-static const char *DEPENDENCIES_LOCAL_KEY = "local";
-static const char *DEPENDENCIES_REMOTE_KEY = "remote";
-static const char *DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY = "custom_maven_repos";
-
-static const char *BINARY_TYPE_LOCAL = "local";
-static const char *BINARY_TYPE_REMOTE = "remote";
-
-static const char *PLUGIN_VALUE_SEPARATOR = "|";
-
/*
The `config` section and fields are required and defined as follow:
- **name**: name of the plugin
@@ -67,7 +50,24 @@ The `dependencies` section and fields are optional and defined as follow:
See https://github.com/godotengine/godot/issues/38157#issuecomment-618773871
*/
-struct PluginConfig {
+struct PluginConfigAndroid {
+ inline static const char *PLUGIN_CONFIG_EXT = ".gdap";
+
+ inline static const char *CONFIG_SECTION = "config";
+ inline static const char *CONFIG_NAME_KEY = "name";
+ inline static const char *CONFIG_BINARY_TYPE_KEY = "binary_type";
+ inline static const char *CONFIG_BINARY_KEY = "binary";
+
+ inline static const char *DEPENDENCIES_SECTION = "dependencies";
+ inline static const char *DEPENDENCIES_LOCAL_KEY = "local";
+ inline static const char *DEPENDENCIES_REMOTE_KEY = "remote";
+ inline static const char *DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY = "custom_maven_repos";
+
+ inline static const char *BINARY_TYPE_LOCAL = "local";
+ inline static const char *BINARY_TYPE_REMOTE = "remote";
+
+ inline static const char *PLUGIN_VALUE_SEPARATOR = "|";
+
// Set to true when the config file is properly loaded.
bool valid_config = false;
// Unix timestamp of last change to this plugin.
@@ -88,7 +88,7 @@ struct PluginConfig {
* Set of prebuilt plugins.
* Currently unused, this is just for future reference:
*/
-// static const PluginConfig MY_PREBUILT_PLUGIN = {
+// static const PluginConfigAndroid MY_PREBUILT_PLUGIN = {
// /*.valid_config =*/true,
// /*.last_updated =*/0,
// /*.name =*/"GodotPayment",
@@ -101,7 +101,7 @@ struct PluginConfig {
static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
String absolute_path;
- if (!dependency_path.empty()) {
+ if (!dependency_path.is_empty()) {
if (dependency_path.is_abs_path()) {
absolute_path = ProjectSettings::get_singleton()->globalize_path(dependency_path);
} else {
@@ -112,10 +112,10 @@ static inline String resolve_local_dependency_path(String plugin_config_dir, Str
return absolute_path;
}
-static inline PluginConfig resolve_prebuilt_plugin(PluginConfig prebuilt_plugin, String plugin_config_dir) {
- PluginConfig resolved = prebuilt_plugin;
- resolved.binary = resolved.binary_type == BINARY_TYPE_LOCAL ? resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.binary) : prebuilt_plugin.binary;
- if (!prebuilt_plugin.local_dependencies.empty()) {
+static inline PluginConfigAndroid resolve_prebuilt_plugin(PluginConfigAndroid prebuilt_plugin, String plugin_config_dir) {
+ PluginConfigAndroid resolved = prebuilt_plugin;
+ resolved.binary = resolved.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ? resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.binary) : prebuilt_plugin.binary;
+ if (!prebuilt_plugin.local_dependencies.is_empty()) {
resolved.local_dependencies.clear();
for (int i = 0; i < prebuilt_plugin.local_dependencies.size(); i++) {
resolved.local_dependencies.push_back(resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.local_dependencies[i]));
@@ -124,26 +124,27 @@ static inline PluginConfig resolve_prebuilt_plugin(PluginConfig prebuilt_plugin,
return resolved;
}
-static inline Vector<PluginConfig> get_prebuilt_plugins(String plugins_base_dir) {
- Vector<PluginConfig> prebuilt_plugins;
+static inline Vector<PluginConfigAndroid> get_prebuilt_plugins(String plugins_base_dir) {
+ Vector<PluginConfigAndroid> prebuilt_plugins;
// prebuilt_plugins.push_back(resolve_prebuilt_plugin(MY_PREBUILT_PLUGIN, plugins_base_dir));
return prebuilt_plugins;
}
-static inline bool is_plugin_config_valid(PluginConfig plugin_config) {
- bool valid_name = !plugin_config.name.empty();
- bool valid_binary_type = plugin_config.binary_type == BINARY_TYPE_LOCAL ||
- plugin_config.binary_type == BINARY_TYPE_REMOTE;
+static inline bool is_plugin_config_valid(PluginConfigAndroid plugin_config) {
+ bool valid_name = !plugin_config.name.is_empty();
+ bool valid_binary_type = plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ||
+ plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE;
bool valid_binary = false;
if (valid_binary_type) {
- valid_binary = !plugin_config.binary.empty() &&
- (plugin_config.binary_type == BINARY_TYPE_REMOTE ||
+ valid_binary = !plugin_config.binary.is_empty() &&
+ (plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE ||
+
FileAccess::exists(plugin_config.binary));
}
bool valid_local_dependencies = true;
- if (!plugin_config.local_dependencies.empty()) {
+ if (!plugin_config.local_dependencies.is_empty()) {
for (int i = 0; i < plugin_config.local_dependencies.size(); i++) {
if (!FileAccess::exists(plugin_config.local_dependencies[i])) {
valid_local_dependencies = false;
@@ -154,7 +155,7 @@ static inline bool is_plugin_config_valid(PluginConfig plugin_config) {
return valid_name && valid_binary && valid_binary_type && valid_local_dependencies;
}
-static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_config, const String &config_path) {
+static inline uint64_t get_plugin_modification_time(const PluginConfigAndroid &plugin_config, const String &config_path) {
uint64_t last_updated = FileAccess::get_modified_time(config_path);
last_updated = MAX(last_updated, FileAccess::get_modified_time(plugin_config.binary));
@@ -166,30 +167,30 @@ static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_c
return last_updated;
}
-static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
- PluginConfig plugin_config = {};
+static inline PluginConfigAndroid load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
+ PluginConfigAndroid plugin_config = {};
if (config_file.is_valid()) {
Error err = config_file->load(path);
if (err == OK) {
String config_base_dir = path.get_base_dir();
- plugin_config.name = config_file->get_value(CONFIG_SECTION, CONFIG_NAME_KEY, String());
- plugin_config.binary_type = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_TYPE_KEY, String());
+ plugin_config.name = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_NAME_KEY, String());
+ plugin_config.binary_type = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_BINARY_TYPE_KEY, String());
- String binary_path = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_KEY, String());
- plugin_config.binary = plugin_config.binary_type == BINARY_TYPE_LOCAL ? resolve_local_dependency_path(config_base_dir, binary_path) : binary_path;
+ String binary_path = config_file->get_value(PluginConfigAndroid::CONFIG_SECTION, PluginConfigAndroid::CONFIG_BINARY_KEY, String());
+ plugin_config.binary = plugin_config.binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL ? resolve_local_dependency_path(config_base_dir, binary_path) : binary_path;
- if (config_file->has_section(DEPENDENCIES_SECTION)) {
- Vector<String> local_dependencies_paths = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_LOCAL_KEY, Vector<String>());
- if (!local_dependencies_paths.empty()) {
+ if (config_file->has_section(PluginConfigAndroid::DEPENDENCIES_SECTION)) {
+ Vector<String> local_dependencies_paths = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_LOCAL_KEY, Vector<String>());
+ if (!local_dependencies_paths.is_empty()) {
for (int i = 0; i < local_dependencies_paths.size(); i++) {
plugin_config.local_dependencies.push_back(resolve_local_dependency_path(config_base_dir, local_dependencies_paths[i]));
}
}
- plugin_config.remote_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_REMOTE_KEY, Vector<String>());
- plugin_config.custom_maven_repos = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY, Vector<String>());
+ plugin_config.remote_dependencies = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_REMOTE_KEY, Vector<String>());
+ plugin_config.custom_maven_repos = config_file->get_value(PluginConfigAndroid::DEPENDENCIES_SECTION, PluginConfigAndroid::DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY, Vector<String>());
}
plugin_config.valid_config = is_plugin_config_valid(plugin_config);
@@ -200,12 +201,12 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const
return plugin_config;
}
-static inline String get_plugins_binaries(String binary_type, Vector<PluginConfig> plugins_configs) {
+static inline String get_plugins_binaries(String binary_type, Vector<PluginConfigAndroid> plugins_configs) {
String plugins_binaries;
- if (!plugins_configs.empty()) {
+ if (!plugins_configs.is_empty()) {
Vector<String> binaries;
for (int i = 0; i < plugins_configs.size(); i++) {
- PluginConfig config = plugins_configs[i];
+ PluginConfigAndroid config = plugins_configs[i];
if (!config.valid_config) {
continue;
}
@@ -214,27 +215,27 @@ static inline String get_plugins_binaries(String binary_type, Vector<PluginConfi
binaries.push_back(config.binary);
}
- if (binary_type == BINARY_TYPE_LOCAL) {
+ if (binary_type == PluginConfigAndroid::BINARY_TYPE_LOCAL) {
binaries.append_array(config.local_dependencies);
}
- if (binary_type == BINARY_TYPE_REMOTE) {
+ if (binary_type == PluginConfigAndroid::BINARY_TYPE_REMOTE) {
binaries.append_array(config.remote_dependencies);
}
}
- plugins_binaries = String(PLUGIN_VALUE_SEPARATOR).join(binaries);
+ plugins_binaries = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(binaries);
}
return plugins_binaries;
}
-static inline String get_plugins_custom_maven_repos(Vector<PluginConfig> plugins_configs) {
+static inline String get_plugins_custom_maven_repos(Vector<PluginConfigAndroid> plugins_configs) {
String custom_maven_repos;
- if (!plugins_configs.empty()) {
+ if (!plugins_configs.is_empty()) {
Vector<String> repos_urls;
for (int i = 0; i < plugins_configs.size(); i++) {
- PluginConfig config = plugins_configs[i];
+ PluginConfigAndroid config = plugins_configs[i];
if (!config.valid_config) {
continue;
}
@@ -242,24 +243,24 @@ static inline String get_plugins_custom_maven_repos(Vector<PluginConfig> plugins
repos_urls.append_array(config.custom_maven_repos);
}
- custom_maven_repos = String(PLUGIN_VALUE_SEPARATOR).join(repos_urls);
+ custom_maven_repos = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(repos_urls);
}
return custom_maven_repos;
}
-static inline String get_plugins_names(Vector<PluginConfig> plugins_configs) {
+static inline String get_plugins_names(Vector<PluginConfigAndroid> plugins_configs) {
String plugins_names;
- if (!plugins_configs.empty()) {
+ if (!plugins_configs.is_empty()) {
Vector<String> names;
for (int i = 0; i < plugins_configs.size(); i++) {
- PluginConfig config = plugins_configs[i];
+ PluginConfigAndroid config = plugins_configs[i];
if (!config.valid_config) {
continue;
}
names.push_back(config.name);
}
- plugins_names = String(PLUGIN_VALUE_SEPARATOR).join(names);
+ plugins_names = String(PluginConfigAndroid::PLUGIN_VALUE_SEPARATOR).join(names);
}
return plugins_names;
diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp
index b8e5345b85..ba3e9fa20f 100644
--- a/platform/android/plugin/godot_plugin_jni.cpp
+++ b/platform/android/plugin/godot_plugin_jni.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,7 +41,7 @@ static HashMap<String, JNISingleton *> jni_singletons;
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj) {
String singname = jstring_to_string(name, env);
JNISingleton *s = (JNISingleton *)ClassDB::instance("JNISingleton");
s->set_instance(env->NewGlobalRef(obj));
@@ -51,7 +51,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
ProjectSettings::get_singleton()->set(singname, s);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args) {
String singname = jstring_to_string(sname, env);
ERR_FAIL_COND(!jni_singletons.has(singname));
@@ -83,7 +83,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
s->add_method(mname, mid, types, get_jni_type(retval));
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types) {
String singleton_name = jstring_to_string(j_plugin_name, env);
ERR_FAIL_COND(!jni_singletons.has(singleton_name));
@@ -104,7 +104,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
singleton->add_signal(signal_name, types);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params) {
String singleton_name = jstring_to_string(j_plugin_name, env);
ERR_FAIL_COND(!jni_singletons.has(singleton_name));
@@ -129,7 +129,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
singleton->emit_signal(signal_name, args, count);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths) {
int gdnlib_count = env->GetArrayLength(gdnlib_paths);
if (gdnlib_count == 0) {
return;
diff --git a/platform/android/plugin/godot_plugin_jni.h b/platform/android/plugin/godot_plugin_jni.h
index 80ce332e7c..b87f922e03 100644
--- a/platform/android/plugin/godot_plugin_jni.h
+++ b/platform/android/plugin/godot_plugin_jni.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,11 +35,11 @@
#include <jni.h>
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths);
}
#endif // GODOT_PLUGIN_JNI_H
diff --git a/platform/android/string_android.h b/platform/android/string_android.h
index 0a7dbf475d..3721315d3f 100644
--- a/platform/android/string_android.h
+++ b/platform/android/string_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,14 +37,14 @@
/**
* Converts JNI jstring to Godot String.
* @param source Source JNI string. If null an empty string is returned.
- * @param env JNI environment instance. If null obtained by ThreadAndroid::get_env().
+ * @param env JNI environment instance. If null obtained by get_jni_env().
* @return Godot string instance.
*/
static inline String jstring_to_string(jstring source, JNIEnv *env = nullptr) {
String result;
if (source) {
if (!env) {
- env = ThreadAndroid::get_env();
+ env = get_jni_env();
}
const char *const source_utf8 = env->GetStringUTFChars(source, nullptr);
if (source_utf8) {
diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp
index 442e4d781b..afcc7294f2 100644
--- a/platform/android/thread_jandroid.cpp
+++ b/platform/android/thread_jandroid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,116 +30,29 @@
#include "thread_jandroid.h"
-#include "core/object/script_language.h"
-#include "core/os/memory.h"
-#include "core/templates/safe_refcount.h"
+#include "core/os/thread.h"
-static void _thread_id_key_destr_callback(void *p_value) {
- memdelete(static_cast<Thread::ID *>(p_value));
-}
-
-static pthread_key_t _create_thread_id_key() {
- pthread_key_t key;
- pthread_key_create(&key, &_thread_id_key_destr_callback);
- return key;
-}
-
-pthread_key_t ThreadAndroid::thread_id_key = _create_thread_id_key();
-Thread::ID ThreadAndroid::next_thread_id = 0;
-
-Thread::ID ThreadAndroid::get_id() const {
- return id;
-}
-
-Thread *ThreadAndroid::create_thread_jandroid() {
- return memnew(ThreadAndroid);
-}
-
-void *ThreadAndroid::thread_callback(void *userdata) {
- ThreadAndroid *t = reinterpret_cast<ThreadAndroid *>(userdata);
- setup_thread();
- ScriptServer::thread_enter(); //scripts may need to attach a stack
- t->id = atomic_increment(&next_thread_id);
- pthread_setspecific(thread_id_key, (void *)memnew(ID(t->id)));
- t->callback(t->user);
- ScriptServer::thread_exit();
- return nullptr;
-}
-
-Thread *ThreadAndroid::create_func_jandroid(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
- ThreadAndroid *tr = memnew(ThreadAndroid);
- tr->callback = p_callback;
- tr->user = p_user;
- pthread_attr_init(&tr->pthread_attr);
- pthread_attr_setdetachstate(&tr->pthread_attr, PTHREAD_CREATE_JOINABLE);
-
- pthread_create(&tr->pthread, &tr->pthread_attr, thread_callback, tr);
-
- return tr;
-}
+static JavaVM *java_vm = nullptr;
+static thread_local JNIEnv *env = nullptr;
-Thread::ID ThreadAndroid::get_thread_id_func_jandroid() {
- void *value = pthread_getspecific(thread_id_key);
-
- if (value)
- return *static_cast<ID *>(value);
-
- ID new_id = atomic_increment(&next_thread_id);
- pthread_setspecific(thread_id_key, (void *)memnew(ID(new_id)));
- return new_id;
-}
-
-void ThreadAndroid::wait_to_finish_func_jandroid(Thread *p_thread) {
- ThreadAndroid *tp = static_cast<ThreadAndroid *>(p_thread);
- ERR_FAIL_COND(!tp);
- ERR_FAIL_COND(tp->pthread == 0);
-
- pthread_join(tp->pthread, nullptr);
- tp->pthread = 0;
-}
-
-void ThreadAndroid::_thread_destroyed(void *value) {
- /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
- JNIEnv *env = (JNIEnv *)value;
- if (env != nullptr) {
- java_vm->DetachCurrentThread();
- pthread_setspecific(jvm_key, nullptr);
- }
-}
-
-pthread_key_t ThreadAndroid::jvm_key;
-JavaVM *ThreadAndroid::java_vm = nullptr;
-
-void ThreadAndroid::setup_thread() {
- if (pthread_getspecific(jvm_key))
- return; //already setup
- JNIEnv *env;
+static void init_thread() {
java_vm->AttachCurrentThread(&env, nullptr);
- pthread_setspecific(jvm_key, (void *)env);
}
-void ThreadAndroid::make_default(JavaVM *p_java_vm) {
- java_vm = p_java_vm;
- create_func = create_func_jandroid;
- get_thread_id_func = get_thread_id_func_jandroid;
- wait_to_finish_func = wait_to_finish_func_jandroid;
- pthread_key_create(&jvm_key, _thread_destroyed);
- setup_thread();
+static void term_thread() {
+ java_vm->DetachCurrentThread();
}
-JNIEnv *ThreadAndroid::get_env() {
- if (!pthread_getspecific(jvm_key)) {
- setup_thread();
- }
-
- JNIEnv *env = nullptr;
- java_vm->AttachCurrentThread(&env, nullptr);
- return env;
+void init_thread_jandroid(JavaVM *p_jvm, JNIEnv *p_env) {
+ java_vm = p_jvm;
+ env = p_env;
+ Thread::_set_platform_funcs(nullptr, nullptr, &init_thread, &term_thread);
}
-ThreadAndroid::ThreadAndroid() {
- pthread = 0;
+void setup_android_thread() {
+ init_thread();
}
-ThreadAndroid::~ThreadAndroid() {
+JNIEnv *get_jni_env() {
+ return env;
}
diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h
index 9cfcc64813..ff13ae911f 100644
--- a/platform/android/thread_jandroid.h
+++ b/platform/android/thread_jandroid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,46 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef THREAD_POSIX_H
-#define THREAD_POSIX_H
+#ifndef THREAD_JANDROID_H
+#define THREAD_JANDROID_H
-#include "core/os/thread.h"
#include <jni.h>
-#include <pthread.h>
-#include <sys/types.h>
-class ThreadAndroid : public Thread {
- static pthread_key_t thread_id_key;
- static ID next_thread_id;
+void init_thread_jandroid(JavaVM *p_jvm, JNIEnv *p_env);
- pthread_t pthread;
- pthread_attr_t pthread_attr;
- ThreadCreateCallback callback;
- void *user;
- ID id;
-
- static Thread *create_thread_jandroid();
-
- static void *thread_callback(void *userdata);
-
- static Thread *create_func_jandroid(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID get_thread_id_func_jandroid();
- static void wait_to_finish_func_jandroid(Thread *p_thread);
-
- static void _thread_destroyed(void *value);
- ThreadAndroid();
-
- static pthread_key_t jvm_key;
- static JavaVM *java_vm;
-
-public:
- virtual ID get_id() const;
-
- static void make_default(JavaVM *p_java_vm);
- static void setup_thread();
- static JNIEnv *get_env();
-
- ~ThreadAndroid();
-};
+void setup_android_thread();
+JNIEnv *get_jni_env();
#endif
diff --git a/platform/android/vulkan/vulkan_context_android.cpp b/platform/android/vulkan/vulkan_context_android.cpp
index 56ef99dfc7..1bf85f07f1 100644
--- a/platform/android/vulkan/vulkan_context_android.cpp
+++ b/platform/android/vulkan/vulkan_context_android.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/android/vulkan/vulkan_context_android.h b/platform/android/vulkan/vulkan_context_android.h
index 6bd3cbee36..c608f2d665 100644
--- a/platform/android/vulkan/vulkan_context_android.h
+++ b/platform/android/vulkan/vulkan_context_android.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h
index 2f082f1e07..d6a2292dd2 100644
--- a/platform/iphone/app_delegate.h
+++ b/platform/iphone/app_delegate.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index c1942e77dd..d10ea5c68c 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index ad4af9ba6a..17796beb6f 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -34,6 +34,7 @@ def get_opts():
" validation layers)",
False,
),
+ BoolVariable("ios_simulator", "Build for iOS Simulator", False),
BoolVariable("ios_exceptions", "Enable exceptions", False),
("ios_triple", "Triple for ios toolchain", ""),
]
@@ -107,8 +108,17 @@ def configure(env):
## Compile flags
- if env["arch"] == "x86" or env["arch"] == "x86_64":
+ if env["ios_simulator"]:
detect_darwin_sdk_path("iphonesimulator", env)
+ env.Append(CCFLAGS=["-mios-simulator-version-min=13.0"])
+ env.Append(LINKFLAGS=["-mios-simulator-version-min=13.0"])
+ env.extra_suffix = ".simulator" + env.extra_suffix
+ else:
+ detect_darwin_sdk_path("iphone", env)
+ env.Append(CCFLAGS=["-miphoneos-version-min=11.0"])
+ env.Append(LINKFLAGS=["-miphoneos-version-min=11.0"])
+
+ if env["arch"] == "x86" or env["arch"] == "x86_64":
env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = "10.9"
arch_flag = "i386" if env["arch"] == "x86" else env["arch"]
env.Append(
@@ -116,11 +126,10 @@ def configure(env):
"-fobjc-arc -arch "
+ arch_flag
+ " -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks"
- " -fasm-blocks -isysroot $IPHONESDK -mios-simulator-version-min=13.0"
+ " -fasm-blocks -isysroot $IPHONESDK"
).split()
)
elif env["arch"] == "arm":
- detect_darwin_sdk_path("iphone", env)
env.Append(
CCFLAGS=(
"-fobjc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing"
@@ -128,16 +137,15 @@ def configure(env):
" -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb"
' "-DIBOutlet=__attribute__((iboutlet))"'
' "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))"'
- ' "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=11.0 -MMD -MT dependencies'.split()
+ ' "-DIBAction=void)__attribute__((ibaction)" -MMD -MT dependencies'.split()
)
)
elif env["arch"] == "arm64":
- detect_darwin_sdk_path("iphone", env)
env.Append(
CCFLAGS=(
"-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing"
" -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits"
- " -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=11.0"
+ " -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies"
" -isysroot $IPHONESDK".split()
)
)
@@ -162,7 +170,6 @@ def configure(env):
LINKFLAGS=[
"-arch",
arch_flag,
- "-mios-simulator-version-min=13.0",
"-isysroot",
"$IPHONESDK",
"-Xlinker",
@@ -173,46 +180,14 @@ def configure(env):
]
)
elif env["arch"] == "arm":
- env.Append(LINKFLAGS=["-arch", "armv7", "-Wl,-dead_strip", "-miphoneos-version-min=11.0"])
+ env.Append(LINKFLAGS=["-arch", "armv7", "-Wl,-dead_strip"])
if env["arch"] == "arm64":
- env.Append(LINKFLAGS=["-arch", "arm64", "-Wl,-dead_strip", "-miphoneos-version-min=11.0"])
+ env.Append(LINKFLAGS=["-arch", "arm64", "-Wl,-dead_strip"])
env.Append(
LINKFLAGS=[
"-isysroot",
"$IPHONESDK",
- "-framework",
- "AudioToolbox",
- "-framework",
- "AVFoundation",
- "-framework",
- "CoreAudio",
- "-framework",
- "CoreGraphics",
- "-framework",
- "CoreMedia",
- "-framework",
- "CoreVideo",
- "-framework",
- "CoreMotion",
- "-framework",
- "Foundation",
- "-framework",
- "GameController",
- "-framework",
- "MediaPlayer",
- "-framework",
- "Metal",
- "-framework",
- "QuartzCore",
- "-framework",
- "Security",
- "-framework",
- "SystemConfiguration",
- "-framework",
- "UIKit",
- "-framework",
- "ARKit",
]
)
diff --git a/platform/iphone/device_metrics.h b/platform/iphone/device_metrics.h
index 6d0ff49077..bc8f761dde 100644
--- a/platform/iphone/device_metrics.h
+++ b/platform/iphone/device_metrics.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/device_metrics.m b/platform/iphone/device_metrics.m
index 747872bc49..306ca95d03 100644
--- a/platform/iphone/device_metrics.m
+++ b/platform/iphone/device_metrics.m
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/display_layer.h b/platform/iphone/display_layer.h
index bfde8f96a3..1b8435d959 100644
--- a/platform/iphone/display_layer.h
+++ b/platform/iphone/display_layer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/display_layer.mm b/platform/iphone/display_layer.mm
index 7420a5ebe6..b8df81b89a 100644
--- a/platform/iphone/display_layer.mm
+++ b/platform/iphone/display_layer.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -89,7 +89,7 @@
// FIXME: Add Vulkan support via MoltenVK. Add fallback code back?
// Create GL ES 2 context
- if (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES2") {
+ if (GLOBAL_GET("rendering/driver/driver_name") == "GLES2") {
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
NSLog(@"Setting up an OpenGL ES 2.0 context.");
if (!context) {
diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h
index 2d77e9adff..31a44723a5 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/iphone/display_server_iphone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index e8abf1e3fa..05dc78bb4d 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 3406c75c35..c585c2afbe 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,6 +37,7 @@
#include "core/io/zip_io.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
+#include "core/templates/safe_refcount.h"
#include "core/version.h"
#include "editor/editor_export.h"
#include "editor/editor_node.h"
@@ -56,11 +57,11 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
Ref<ImageTexture> logo;
// Plugins
- volatile bool plugins_changed;
- Thread *check_for_changes_thread;
- volatile bool quit_request;
+ SafeFlag plugins_changed;
+ Thread check_for_changes_thread;
+ SafeFlag quit_request;
Mutex plugins_lock;
- Vector<PluginConfig> plugins;
+ Vector<PluginConfigIOS> plugins;
typedef Error (*FileHandler)(String p_file, void *p_userdata);
static Error _walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata);
@@ -141,19 +142,19 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
static void _check_for_changes_poll_thread(void *ud) {
EditorExportPlatformIOS *ea = (EditorExportPlatformIOS *)ud;
- while (!ea->quit_request) {
+ while (!ea->quit_request.is_set()) {
// Nothing to do if we already know the plugins have changed.
- if (!ea->plugins_changed) {
+ if (!ea->plugins_changed.is_set()) {
MutexLock lock(ea->plugins_lock);
- Vector<PluginConfig> loaded_plugins = get_plugins();
+ Vector<PluginConfigIOS> loaded_plugins = get_plugins();
if (ea->plugins.size() != loaded_plugins.size()) {
- ea->plugins_changed = true;
+ ea->plugins_changed.set();
} else {
for (int i = 0; i < ea->plugins.size(); i++) {
if (ea->plugins[i].name != loaded_plugins[i].name || ea->plugins[i].last_updated != loaded_plugins[i].last_updated) {
- ea->plugins_changed = true;
+ ea->plugins_changed.set();
break;
}
}
@@ -165,7 +166,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
while (OS::get_singleton()->get_ticks_usec() - time < wait) {
OS::get_singleton()->delay_usec(300000);
- if (ea->quit_request) {
+ if (ea->quit_request.is_set()) {
break;
}
}
@@ -182,10 +183,10 @@ public:
virtual Ref<Texture2D> get_logo() const override { return logo; }
virtual bool should_update_export_options() override {
- bool export_options_changed = plugins_changed;
+ bool export_options_changed = plugins_changed.is_set();
if (export_options_changed) {
// don't clear unless we're reporting true, to avoid race
- plugins_changed = false;
+ plugins_changed.clear();
}
return export_options_changed;
}
@@ -218,7 +219,7 @@ public:
da->list_dir_begin();
while (true) {
String file = da->get_next();
- if (file.empty()) {
+ if (file.is_empty()) {
break;
}
@@ -241,7 +242,7 @@ public:
continue;
}
- if (file.ends_with(PLUGIN_CONFIG_EXT)) {
+ if (file.ends_with(PluginConfigIOS::PLUGIN_CONFIG_EXT)) {
dir_files.push_back(file);
}
}
@@ -251,18 +252,18 @@ public:
return dir_files;
}
- static Vector<PluginConfig> get_plugins() {
- Vector<PluginConfig> loaded_plugins;
+ static Vector<PluginConfigIOS> get_plugins() {
+ Vector<PluginConfigIOS> loaded_plugins;
String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("ios/plugins");
if (DirAccess::exists(plugins_dir)) {
Vector<String> plugins_filenames = list_plugin_config_files(plugins_dir, true);
- if (!plugins_filenames.empty()) {
+ if (!plugins_filenames.is_empty()) {
Ref<ConfigFile> config_file = memnew(ConfigFile);
for (int i = 0; i < plugins_filenames.size(); i++) {
- PluginConfig config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
+ PluginConfigIOS config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
if (config.valid_config) {
loaded_plugins.push_back(config);
} else {
@@ -275,11 +276,11 @@ public:
return loaded_plugins;
}
- static Vector<PluginConfig> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
- Vector<PluginConfig> enabled_plugins;
- Vector<PluginConfig> all_plugins = get_plugins();
+ static Vector<PluginConfigIOS> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
+ Vector<PluginConfigIOS> enabled_plugins;
+ Vector<PluginConfigIOS> all_plugins = get_plugins();
for (int i = 0; i < all_plugins.size(); i++) {
- PluginConfig plugin = all_plugins[i];
+ PluginConfigIOS plugin = all_plugins[i];
bool enabled = p_presets->get("plugins/" + plugin.name);
if (enabled) {
enabled_plugins.push_back(plugin);
@@ -291,7 +292,7 @@ public:
};
void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
- String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
+ String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
r_features->push_back("pvrtc");
if (driver == "Vulkan") {
// FIXME: Review if this is correct.
@@ -360,11 +361,11 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
- Vector<PluginConfig> found_plugins = get_plugins();
+ Vector<PluginConfigIOS> found_plugins = get_plugins();
for (int i = 0; i < found_plugins.size(); i++) {
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + found_plugins[i].name), false));
}
- plugins_changed = false;
+ plugins_changed.clear();
plugins = found_plugins;
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/access_wifi"), false));
@@ -815,7 +816,7 @@ Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref<EditorExpor
const String splash_path = ProjectSettings::get_singleton()->get("application/boot_splash/image");
- if (!splash_path.empty()) {
+ if (!splash_path.is_empty()) {
splash.instance();
const Error err = splash->load(splash_path);
if (err) {
@@ -979,7 +980,7 @@ Error EditorExportPlatformIOS::_codesign(String p_file, void *p_userdata) {
codesign_args.push_back("-s");
codesign_args.push_back(data->preset->get(data->debug ? "application/code_sign_identity_debug" : "application/code_sign_identity_release"));
codesign_args.push_back(p_file);
- return OS::get_singleton()->execute("codesign", codesign_args, true);
+ return OS::get_singleton()->execute("codesign", codesign_args);
}
return OK;
}
@@ -1229,7 +1230,7 @@ Error EditorExportPlatformIOS::_copy_asset(const String &p_out_dir, const String
install_name_args.push_back(String("@rpath").plus_file(framework_name).plus_file(file_name));
install_name_args.push_back(destination);
- OS::get_singleton()->execute("install_name_tool", install_name_args, true);
+ OS::get_singleton()->execute("install_name_tool", install_name_args);
}
// Creating Info.plist
@@ -1345,28 +1346,25 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
Vector<String> plugin_embedded_dependencies;
Vector<String> plugin_files;
- Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset);
+ Vector<PluginConfigIOS> enabled_plugins = get_enabled_plugins(p_preset);
Vector<String> added_linked_dependenciy_names;
Vector<String> added_embedded_dependenciy_names;
HashMap<String, String> plist_values;
+ Set<String> plugin_linker_flags;
+
Error err;
for (int i = 0; i < enabled_plugins.size(); i++) {
- PluginConfig plugin = enabled_plugins[i];
+ PluginConfigIOS plugin = enabled_plugins[i];
// Export plugin binary.
- if (!plugin.supports_targets) {
- err = _copy_asset(dest_dir, plugin.binary, nullptr, true, true, r_exported_assets);
- } else {
- String plugin_binary_dir = plugin.binary.get_base_dir();
- String plugin_name_prefix = plugin.binary.get_basename().get_file();
- String plugin_file = plugin_name_prefix + "." + (p_debug ? "debug" : "release") + ".a";
- String result_file_name = plugin.binary.get_file();
-
- err = _copy_asset(dest_dir, plugin_binary_dir.plus_file(plugin_file), &result_file_name, true, true, r_exported_assets);
- }
+ String plugin_main_binary = get_plugin_main_binary(plugin, p_debug);
+ String plugin_binary_result_file = plugin.binary.get_file();
+ // We shouldn't embed .xcframework that contains static libraries.
+ // Static libraries are not embedded anyway.
+ err = _copy_asset(dest_dir, plugin_main_binary, &plugin_binary_result_file, true, false, r_exported_assets);
ERR_FAIL_COND_V(err, err);
@@ -1422,6 +1420,13 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
p_config_data.capabilities.push_back(capability);
}
+ // Linker flags
+ // Checking duplicates
+ for (int j = 0; j < plugin.linker_flags.size(); j++) {
+ String linker_flag = plugin.linker_flags[j];
+ plugin_linker_flags.insert(linker_flag);
+ }
+
// Plist
// Using hash map container to remove duplicates
const String *K = nullptr;
@@ -1430,7 +1435,7 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
String key = *K;
String value = plugin.plist[key];
- if (key.empty() || value.empty()) {
+ if (key.is_empty() || value.is_empty()) {
continue;
}
@@ -1457,7 +1462,7 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
String key = *K;
String value = plist_values[key];
- if (key.empty() || value.empty()) {
+ if (key.is_empty() || value.is_empty()) {
continue;
}
@@ -1502,6 +1507,27 @@ Error EditorExportPlatformIOS::_export_ios_plugins(const Ref<EditorExportPreset>
p_config_data.cpp_code += plugin_cpp_code.format(plugin_format, "$_");
}
+
+ // Update Linker Flag Values
+ {
+ String result_linker_flags = " ";
+ for (Set<String>::Element *E = plugin_linker_flags.front(); E; E = E->next()) {
+ const String &flag = E->get();
+
+ if (flag.length() == 0) {
+ continue;
+ }
+
+ if (result_linker_flags.length() > 0) {
+ result_linker_flags += ' ';
+ }
+
+ result_linker_flags += flag;
+ }
+ result_linker_flags = result_linker_flags.replace("\"", "\\\"");
+ p_config_data.linker_flags += result_linker_flags;
+ }
+
return OK;
}
@@ -1575,9 +1601,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
return ERR_SKIP;
}
- String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".fat.a";
+ String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".xcframework";
- print_line("Static library: " + library_to_use);
+ print_line("Static framework: " + library_to_use);
String pkg_name;
if (p_preset->get("application/name") != "") {
pkg_name = p_preset->get("application/name"); // app_name
@@ -1663,7 +1689,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
if (files_to_parse.has(file)) {
_fix_config_file(p_preset, data, config_data, p_debug);
} else if (file.begins_with("libgodot.iphone")) {
- if (file != library_to_use) {
+ if (!file.begins_with(library_to_use) || file.ends_with(String("/empty"))) {
ret = unzGoToNextFile(src_pkg_zip);
continue; //ignore!
}
@@ -1671,7 +1697,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
#if defined(OSX_ENABLED) || defined(X11_ENABLED)
is_execute = true;
#endif
- file = "godot_ios.a";
+ file = file.replace(library_to_use, binary_name + ".xcframework");
}
if (file == project_file) {
@@ -1848,7 +1874,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
archive_args.push_back("archive");
archive_args.push_back("-archivePath");
archive_args.push_back(archive_path);
- err = OS::get_singleton()->execute("xcodebuild", archive_args, true);
+ err = OS::get_singleton()->execute("xcodebuild", archive_args);
ERR_FAIL_COND_V(err, err);
if (ep.step("Making .ipa", 4)) {
@@ -1863,7 +1889,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
export_args.push_back("-allowProvisioningUpdates");
export_args.push_back("-exportPath");
export_args.push_back(dest_dir);
- err = OS::get_singleton()->execute("xcodebuild", export_args, true);
+ err = OS::get_singleton()->execute("xcodebuild", export_args);
ERR_FAIL_COND_V(err, err);
#else
print_line(".ipa can only be built on macOS. Leaving Xcode project without building the package.");
@@ -1930,7 +1956,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
err += etc_error;
}
- if (!err.empty()) {
+ if (!err.is_empty()) {
r_error = err;
}
@@ -1942,16 +1968,14 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() {
logo.instance();
logo->create_from_image(img);
- plugins_changed = true;
- quit_request = false;
+ plugins_changed.set();
- check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this);
+ check_for_changes_thread.start(_check_for_changes_poll_thread, this);
}
EditorExportPlatformIOS::~EditorExportPlatformIOS() {
- quit_request = true;
- Thread::wait_to_finish(check_for_changes_thread);
- memdelete(check_for_changes_thread);
+ quit_request.set();
+ check_for_changes_thread.wait_to_finish();
}
void register_iphone_exporter() {
diff --git a/platform/iphone/export/export.h b/platform/iphone/export/export.h
index 043d21f533..4a79ca279f 100644
--- a/platform/iphone/export/export.h
+++ b/platform/iphone/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_app_delegate.h b/platform/iphone/godot_app_delegate.h
index ebb21c499b..6335ada50e 100644
--- a/platform/iphone/godot_app_delegate.h
+++ b/platform/iphone/godot_app_delegate.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_app_delegate.m b/platform/iphone/godot_app_delegate.m
index a5aad26bd5..3ce9bffc79 100644
--- a/platform/iphone/godot_app_delegate.m
+++ b/platform/iphone/godot_app_delegate.m
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -302,37 +302,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
// MARK: Remote Notification
-- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
- }
-}
-
-- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didFailToRegisterForRemoteNotificationsWithError:error];
- }
-}
-
-- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
- for (ApplicationDelegateService *service in services) {
- if (![service respondsToSelector:_cmd]) {
- continue;
- }
-
- [service application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
- }
-
- completionHandler(UIBackgroundFetchResultNoData);
-}
+// Moved to the iOS Plugin
// MARK: User Activity and Handling Quick Actions
diff --git a/platform/iphone/godot_iphone.mm b/platform/iphone/godot_iphone.mm
index a4119bcafd..62bc2e6e52 100644
--- a/platform/iphone/godot_iphone.mm
+++ b/platform/iphone/godot_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_view.h b/platform/iphone/godot_view.h
index a8f4cb38d9..265f826173 100644
--- a/platform/iphone/godot_view.h
+++ b/platform/iphone/godot_view.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,12 +32,20 @@
class String;
+@class GodotView;
@protocol DisplayLayer;
@protocol GodotViewRendererProtocol;
+@protocol GodotViewDelegate
+
+- (BOOL)godotViewFinishedSetup:(GodotView *)view;
+
+@end
+
@interface GodotView : UIView
@property(assign, nonatomic) id<GodotViewRendererProtocol> renderer;
+@property(assign, nonatomic) id<GodotViewDelegate> delegate;
@property(assign, readonly, nonatomic) BOOL isActive;
diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm
index 0c50842cfa..887297848e 100644
--- a/platform/iphone/godot_view.mm
+++ b/platform/iphone/godot_view.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -120,6 +120,7 @@ static const int max_touches = 8;
[self stopRendering];
self.renderer = nil;
+ self.delegate = nil;
if (self.renderingLayer) {
[self.renderingLayer removeFromSuperlayer];
@@ -241,6 +242,14 @@ static const int max_touches = 8;
return;
}
+ if (self.delegate) {
+ BOOL delegateFinishedSetup = [self.delegate godotViewFinishedSetup:self];
+
+ if (!delegateFinishedSetup) {
+ return;
+ }
+ }
+
[self handleMotion];
[self.renderer renderOnView:self];
}
diff --git a/platform/iphone/godot_view_gesture_recognizer.h b/platform/iphone/godot_view_gesture_recognizer.h
index 1431a9fb89..48b2d5ffad 100644
--- a/platform/iphone/godot_view_gesture_recognizer.h
+++ b/platform/iphone/godot_view_gesture_recognizer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_view_gesture_recognizer.mm b/platform/iphone/godot_view_gesture_recognizer.mm
index 91cc07fcf6..cf6e5c5883 100644
--- a/platform/iphone/godot_view_gesture_recognizer.mm
+++ b/platform/iphone/godot_view_gesture_recognizer.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_view_renderer.h b/platform/iphone/godot_view_renderer.h
index ea8998c808..c6b0a05a4e 100644
--- a/platform/iphone/godot_view_renderer.h
+++ b/platform/iphone/godot_view_renderer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/godot_view_renderer.mm b/platform/iphone/godot_view_renderer.mm
index f2ff417e6f..07d664715a 100644
--- a/platform/iphone/godot_view_renderer.mm
+++ b/platform/iphone/godot_view_renderer.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h
index 5415c36cd9..4bf64d4bc1 100644
--- a/platform/iphone/ios.h
+++ b/platform/iphone/ios.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index d4e099063f..cef03534c4 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/joypad_iphone.h b/platform/iphone/joypad_iphone.h
index 85e26e1dc8..329cc8207f 100644
--- a/platform/iphone/joypad_iphone.h
+++ b/platform/iphone/joypad_iphone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/joypad_iphone.mm b/platform/iphone/joypad_iphone.mm
index 22d7dd4bd2..a0f0eee5d3 100644
--- a/platform/iphone/joypad_iphone.mm
+++ b/platform/iphone/joypad_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/keyboard_input_view.h b/platform/iphone/keyboard_input_view.h
index 5382a2e9a9..cfbfc7a120 100644
--- a/platform/iphone/keyboard_input_view.h
+++ b/platform/iphone/keyboard_input_view.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/keyboard_input_view.mm b/platform/iphone/keyboard_input_view.mm
index 1a37403de7..1408f78e90 100644
--- a/platform/iphone/keyboard_input_view.mm
+++ b/platform/iphone/keyboard_input_view.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/main.m b/platform/iphone/main.m
index 351b40a881..fddd5bd99f 100644
--- a/platform/iphone/main.m
+++ b/platform/iphone/main.m
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/native_video_view.h b/platform/iphone/native_video_view.h
index d8687b3538..2df5e27fa4 100644
--- a/platform/iphone/native_video_view.h
+++ b/platform/iphone/native_video_view.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/native_video_view.m b/platform/iphone/native_video_view.m
index 1193946f2b..f126749600 100644
--- a/platform/iphone/native_video_view.m
+++ b/platform/iphone/native_video_view.m
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index e98f870ba9..f4ff909adf 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/os_iphone.mm b/platform/iphone/os_iphone.mm
index dac61f2d9d..51c4da2960 100644
--- a/platform/iphone/os_iphone.mm
+++ b/platform/iphone/os_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -144,12 +144,10 @@ void OSIPhone::deinitialize_modules() {
}
void OSIPhone::set_main_loop(MainLoop *p_main_loop) {
- godot_ios_plugins_initialize();
-
main_loop = p_main_loop;
if (main_loop) {
- main_loop->init();
+ main_loop->initialize();
}
}
@@ -159,7 +157,7 @@ MainLoop *OSIPhone::get_main_loop() const {
void OSIPhone::delete_main_loop() {
if (main_loop) {
- main_loop->finish();
+ main_loop->finalize();
memdelete(main_loop);
};
@@ -179,6 +177,8 @@ bool OSIPhone::iterate() {
}
void OSIPhone::start() {
+ godot_ios_plugins_initialize();
+
Main::start();
if (joypad_iphone) {
diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h
index ec39ad0ba4..88ad4a3f67 100644
--- a/platform/iphone/platform_config.h
+++ b/platform/iphone/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/plugin/godot_plugin_config.h b/platform/iphone/plugin/godot_plugin_config.h
index 5323f94989..f4e30c8349 100644
--- a/platform/iphone/plugin/godot_plugin_config.h
+++ b/platform/iphone/plugin/godot_plugin_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,23 +35,6 @@
#include "core/io/config_file.h"
#include "core/string/ustring.h"
-static const char *PLUGIN_CONFIG_EXT = ".gdip";
-
-static const char *CONFIG_SECTION = "config";
-static const char *CONFIG_NAME_KEY = "name";
-static const char *CONFIG_BINARY_KEY = "binary";
-static const char *CONFIG_INITIALIZE_KEY = "initialization";
-static const char *CONFIG_DEINITIALIZE_KEY = "deinitialization";
-
-static const char *DEPENDENCIES_SECTION = "dependencies";
-static const char *DEPENDENCIES_LINKED_KEY = "linked";
-static const char *DEPENDENCIES_EMBEDDED_KEY = "embedded";
-static const char *DEPENDENCIES_SYSTEM_KEY = "system";
-static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities";
-static const char *DEPENDENCIES_FILES_KEY = "files";
-
-static const char *PLIST_SECTION = "plist";
-
/*
The `config` section and fields are required and defined as follow:
- **name**: name of the plugin
@@ -68,7 +51,25 @@ The `plist` section are optional.
- **key**: key and value that would be added in Info.plist file.
*/
-struct PluginConfig {
+struct PluginConfigIOS {
+ inline static const char *PLUGIN_CONFIG_EXT = ".gdip";
+
+ inline static const char *CONFIG_SECTION = "config";
+ inline static const char *CONFIG_NAME_KEY = "name";
+ inline static const char *CONFIG_BINARY_KEY = "binary";
+ inline static const char *CONFIG_INITIALIZE_KEY = "initialization";
+ inline static const char *CONFIG_DEINITIALIZE_KEY = "deinitialization";
+
+ inline static const char *DEPENDENCIES_SECTION = "dependencies";
+ inline static const char *DEPENDENCIES_LINKED_KEY = "linked";
+ inline static const char *DEPENDENCIES_EMBEDDED_KEY = "embedded";
+ inline static const char *DEPENDENCIES_SYSTEM_KEY = "system";
+ inline static const char *DEPENDENCIES_CAPABILITIES_KEY = "capabilities";
+ inline static const char *DEPENDENCIES_FILES_KEY = "files";
+ inline static const char *DEPENDENCIES_LINKER_FLAGS = "linker_flags";
+
+ inline static const char *PLIST_SECTION = "plist";
+
// Set to true when the config file is properly loaded.
bool valid_config = false;
bool supports_targets = false;
@@ -89,6 +90,8 @@ struct PluginConfig {
Vector<String> files_to_copy;
Vector<String> capabilities;
+ Vector<String> linker_flags;
+
// Optional plist section
// Supports only string types for now
HashMap<String, String> plist;
@@ -97,7 +100,7 @@ struct PluginConfig {
static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
String absolute_path;
- if (dependency_path.empty()) {
+ if (dependency_path.is_empty()) {
return absolute_path;
}
@@ -114,7 +117,7 @@ static inline String resolve_local_dependency_path(String plugin_config_dir, Str
static inline String resolve_system_dependency_path(String dependency_path) {
String absolute_path;
- if (dependency_path.empty()) {
+ if (dependency_path.is_empty()) {
return absolute_path;
}
@@ -133,7 +136,7 @@ static inline Vector<String> resolve_local_dependencies(String plugin_config_dir
for (int i = 0; i < p_paths.size(); i++) {
String path = resolve_local_dependency_path(plugin_config_dir, p_paths[i]);
- if (path.empty()) {
+ if (path.is_empty()) {
continue;
}
@@ -149,7 +152,7 @@ static inline Vector<String> resolve_system_dependencies(Vector<String> p_paths)
for (int i = 0; i < p_paths.size(); i++) {
String path = resolve_system_dependency_path(p_paths[i]);
- if (path.empty()) {
+ if (path.is_empty()) {
continue;
}
@@ -159,24 +162,33 @@ static inline Vector<String> resolve_system_dependencies(Vector<String> p_paths)
return paths;
}
-static inline bool validate_plugin(PluginConfig &plugin_config) {
- bool valid_name = !plugin_config.name.empty();
- bool valid_binary_name = !plugin_config.binary.empty();
- bool valid_initialize = !plugin_config.initialization_method.empty();
- bool valid_deinitialize = !plugin_config.deinitialization_method.empty();
+static inline bool validate_plugin(PluginConfigIOS &plugin_config) {
+ bool valid_name = !plugin_config.name.is_empty();
+ bool valid_binary_name = !plugin_config.binary.is_empty();
+ bool valid_initialize = !plugin_config.initialization_method.is_empty();
+ bool valid_deinitialize = !plugin_config.deinitialization_method.is_empty();
bool fields_value = valid_name && valid_binary_name && valid_initialize && valid_deinitialize;
- if (fields_value && FileAccess::exists(plugin_config.binary)) {
+ if (!fields_value) {
+ return false;
+ }
+
+ String plugin_extension = plugin_config.binary.get_extension().to_lower();
+
+ if ((plugin_extension == "a" && FileAccess::exists(plugin_config.binary)) ||
+ (plugin_extension == "xcframework" && DirAccess::exists(plugin_config.binary))) {
plugin_config.valid_config = true;
plugin_config.supports_targets = false;
- } else if (fields_value) {
+ } else {
String file_path = plugin_config.binary.get_base_dir();
String file_name = plugin_config.binary.get_basename().get_file();
- String release_file_name = file_path.plus_file(file_name + ".release.a");
- String debug_file_name = file_path.plus_file(file_name + ".debug.a");
+ String file_extension = plugin_config.binary.get_extension();
+ String release_file_name = file_path.plus_file(file_name + ".release." + file_extension);
+ String debug_file_name = file_path.plus_file(file_name + ".debug." + file_extension);
- if (FileAccess::exists(release_file_name) && FileAccess::exists(debug_file_name)) {
+ if ((plugin_extension == "a" && FileAccess::exists(release_file_name) && FileAccess::exists(debug_file_name)) ||
+ (plugin_extension == "xcframework" && DirAccess::exists(release_file_name) && DirAccess::exists(debug_file_name))) {
plugin_config.valid_config = true;
plugin_config.supports_targets = true;
}
@@ -185,7 +197,20 @@ static inline bool validate_plugin(PluginConfig &plugin_config) {
return plugin_config.valid_config;
}
-static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_config, const String &config_path) {
+static inline String get_plugin_main_binary(PluginConfigIOS &plugin_config, bool p_debug) {
+ if (!plugin_config.supports_targets) {
+ return plugin_config.binary;
+ }
+
+ String plugin_binary_dir = plugin_config.binary.get_base_dir();
+ String plugin_name_prefix = plugin_config.binary.get_basename().get_file();
+ String plugin_extension = plugin_config.binary.get_extension();
+ String plugin_file = plugin_name_prefix + "." + (p_debug ? "debug" : "release") + "." + plugin_extension;
+
+ return plugin_binary_dir.plus_file(plugin_file);
+}
+
+static inline uint64_t get_plugin_modification_time(const PluginConfigIOS &plugin_config, const String &config_path) {
uint64_t last_updated = FileAccess::get_modified_time(config_path);
if (!plugin_config.supports_targets) {
@@ -203,8 +228,8 @@ static inline uint64_t get_plugin_modification_time(const PluginConfig &plugin_c
return last_updated;
}
-static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
- PluginConfig plugin_config = {};
+static inline PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
+ PluginConfigIOS plugin_config = {};
if (!config_file.is_valid()) {
return plugin_config;
@@ -218,18 +243,18 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const
String config_base_dir = path.get_base_dir();
- plugin_config.name = config_file->get_value(CONFIG_SECTION, CONFIG_NAME_KEY, String());
- plugin_config.initialization_method = config_file->get_value(CONFIG_SECTION, CONFIG_INITIALIZE_KEY, String());
- plugin_config.deinitialization_method = config_file->get_value(CONFIG_SECTION, CONFIG_DEINITIALIZE_KEY, String());
+ plugin_config.name = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_NAME_KEY, String());
+ plugin_config.initialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_INITIALIZE_KEY, String());
+ plugin_config.deinitialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_DEINITIALIZE_KEY, String());
- String binary_path = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_KEY, String());
+ String binary_path = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_BINARY_KEY, String());
plugin_config.binary = resolve_local_dependency_path(config_base_dir, binary_path);
- if (config_file->has_section(DEPENDENCIES_SECTION)) {
- Vector<String> linked_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_LINKED_KEY, Vector<String>());
- Vector<String> embedded_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_EMBEDDED_KEY, Vector<String>());
- Vector<String> system_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_SYSTEM_KEY, Vector<String>());
- Vector<String> files = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_FILES_KEY, Vector<String>());
+ if (config_file->has_section(PluginConfigIOS::DEPENDENCIES_SECTION)) {
+ Vector<String> linked_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKED_KEY, Vector<String>());
+ Vector<String> embedded_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_EMBEDDED_KEY, Vector<String>());
+ Vector<String> system_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_SYSTEM_KEY, Vector<String>());
+ Vector<String> files = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_FILES_KEY, Vector<String>());
plugin_config.linked_dependencies = resolve_local_dependencies(config_base_dir, linked_dependencies);
plugin_config.embedded_dependencies = resolve_local_dependencies(config_base_dir, embedded_dependencies);
@@ -237,17 +262,19 @@ static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const
plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files);
- plugin_config.capabilities = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());
+ plugin_config.capabilities = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());
+
+ plugin_config.linker_flags = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKER_FLAGS, Vector<String>());
}
- if (config_file->has_section(PLIST_SECTION)) {
+ if (config_file->has_section(PluginConfigIOS::PLIST_SECTION)) {
List<String> keys;
- config_file->get_section_keys(PLIST_SECTION, &keys);
+ config_file->get_section_keys(PluginConfigIOS::PLIST_SECTION, &keys);
for (int i = 0; i < keys.size(); i++) {
- String value = config_file->get_value(PLIST_SECTION, keys[i], String());
+ String value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, keys[i], String());
- if (value.empty()) {
+ if (value.is_empty()) {
continue;
}
diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h
index ff76359842..52fb6fbbf2 100644
--- a/platform/iphone/view_controller.h
+++ b/platform/iphone/view_controller.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm
index 7e44d30851..6cef244567 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/iphone/view_controller.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,12 +40,14 @@
#import <AVFoundation/AVFoundation.h>
#import <GameController/GameController.h>
-@interface ViewController ()
+@interface ViewController () <GodotViewDelegate>
@property(strong, nonatomic) GodotViewRenderer *renderer;
@property(strong, nonatomic) GodotNativeVideoView *videoView;
@property(strong, nonatomic) GodotKeyboardInputView *keyboardView;
+@property(strong, nonatomic) UIView *godotLoadingOverlay;
+
@end
@implementation ViewController
@@ -62,6 +64,7 @@
self.view = view;
view.renderer = self.renderer;
+ view.delegate = self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
@@ -97,6 +100,7 @@
[super viewDidLoad];
[self observeKeyboard];
+ [self displayLoadingOverlay];
if (@available(iOS 11.0, *)) {
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
@@ -121,6 +125,31 @@
object:nil];
}
+- (void)displayLoadingOverlay {
+ NSBundle *bundle = [NSBundle mainBundle];
+ NSString *storyboardName = @"Launch Screen";
+
+ if ([bundle pathForResource:storyboardName ofType:@"storyboardc"] == nil) {
+ return;
+ }
+
+ UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:storyboardName bundle:bundle];
+
+ UIViewController *controller = [launchStoryboard instantiateInitialViewController];
+ self.godotLoadingOverlay = controller.view;
+ self.godotLoadingOverlay.frame = self.view.bounds;
+ self.godotLoadingOverlay.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
+
+ [self.view addSubview:self.godotLoadingOverlay];
+}
+
+- (BOOL)godotViewFinishedSetup:(GodotView *)view {
+ [self.godotLoadingOverlay removeFromSuperview];
+ self.godotLoadingOverlay = nil;
+
+ return YES;
+}
+
- (void)dealloc {
[self.videoView stopVideo];
@@ -130,6 +159,11 @@
self.renderer = nil;
+ if (self.godotLoadingOverlay) {
+ [self.godotLoadingOverlay removeFromSuperview];
+ self.godotLoadingOverlay = nil;
+ }
+
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
diff --git a/platform/iphone/vulkan_context_iphone.h b/platform/iphone/vulkan_context_iphone.h
index 5c3d5fe33e..88764e270e 100644
--- a/platform/iphone/vulkan_context_iphone.h
+++ b/platform/iphone/vulkan_context_iphone.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/iphone/vulkan_context_iphone.mm b/platform/iphone/vulkan_context_iphone.mm
index d62e826957..b980ae99f0 100644
--- a/platform/iphone/vulkan_context_iphone.mm
+++ b/platform/iphone/vulkan_context_iphone.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/.eslintrc.engine.js b/platform/javascript/.eslintrc.engine.js
index 00f0f147a9..78df6d41d9 100644
--- a/platform/javascript/.eslintrc.engine.js
+++ b/platform/javascript/.eslintrc.engine.js
@@ -3,8 +3,8 @@ module.exports = {
"./.eslintrc.js",
],
"globals": {
+ "InternalConfig": true,
"Godot": true,
"Preloader": true,
- "Utils": true,
},
};
diff --git a/platform/javascript/.eslintrc.libs.js b/platform/javascript/.eslintrc.libs.js
index e5f0c3d147..81b1b8c864 100644
--- a/platform/javascript/.eslintrc.libs.js
+++ b/platform/javascript/.eslintrc.libs.js
@@ -18,5 +18,8 @@ module.exports = {
"GodotRuntime": true,
"GodotFS": true,
"IDHandler": true,
+ "Browser": true,
+ "GL": true,
+ "XRWebGLLayer": true,
},
};
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 7a8005fe30..a760e36982 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -17,7 +17,7 @@ sys_env.AddJSLibraries(
[
"js/libs/library_godot_audio.js",
"js/libs/library_godot_display.js",
- "js/libs/library_godot_http_request.js",
+ "js/libs/library_godot_fetch.js",
"js/libs/library_godot_os.js",
"js/libs/library_godot_runtime.js",
]
@@ -27,8 +27,13 @@ if env["tools"]:
sys_env.AddJSLibraries(["js/libs/library_godot_editor_tools.js"])
if env["javascript_eval"]:
sys_env.AddJSLibraries(["js/libs/library_godot_eval.js"])
+
for lib in sys_env["JS_LIBS"]:
sys_env.Append(LINKFLAGS=["--js-library", lib])
+for js in env["JS_PRE"]:
+ sys_env.Append(LINKFLAGS=["--pre-js", env.File(js).path])
+for ext in env["JS_EXTERNS"]:
+ sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.path
build = []
if env["gdnative_enabled"]:
@@ -37,8 +42,6 @@ if env["gdnative_enabled"]:
sys_env["LIBS"] = []
# We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly.
sys_env.Append(LIBS=["idbfs.js"])
- # JS prepended to the module code loading the side library.
- sys_env.Append(LINKFLAGS=["--pre-js", sys_env.File("js/dynlink.pre.js")])
# Configure it as a main module (dynamic linking support).
sys_env.Append(CCFLAGS=["-s", "MAIN_MODULE=1"])
sys_env.Append(LINKFLAGS=["-s", "MAIN_MODULE=1"])
@@ -48,7 +51,6 @@ if env["gdnative_enabled"]:
sys_env["ENV"]["EMCC_FORCE_STDLIBS"] = "libc,libc++,libc++abi"
# The main emscripten runtime, with exported standard libraries.
sys = sys_env.Program(build_targets, ["javascript_runtime.cpp"])
- sys_env.Depends(sys, "js/dynlink.pre.js")
# The side library, containing all Godot code.
wasm_env = env.Clone()
@@ -66,10 +68,12 @@ else:
build = sys_env.Program(build_targets, javascript_files + ["javascript_runtime.cpp"])
sys_env.Depends(build[0], sys_env["JS_LIBS"])
+sys_env.Depends(build[0], sys_env["JS_PRE"])
+sys_env.Depends(build[0], sys_env["JS_EXTERNS"])
engine = [
"js/engine/preloader.js",
- "js/engine/utils.js",
+ "js/engine/config.js",
"js/engine/engine.js",
]
externs = [env.File("#platform/javascript/js/engine/engine.externs.js")]
@@ -82,34 +86,6 @@ wrap_list = [
]
js_wrapped = env.Textfile("#bin/godot", [env.File(f) for f in wrap_list], TEXTFILESUFFIX="${PROGSUFFIX}.wrapped.js")
-zip_dir = env.Dir("#bin/.javascript_zip")
-binary_name = "godot.tools" if env["tools"] else "godot"
-out_files = [
- zip_dir.File(binary_name + ".js"),
- zip_dir.File(binary_name + ".wasm"),
- zip_dir.File(binary_name + ".html"),
- zip_dir.File(binary_name + ".audio.worklet.js"),
-]
-html_file = "#misc/dist/html/editor.html" if env["tools"] else "#misc/dist/html/full-size.html"
-in_files = [js_wrapped, build[1], html_file, "#platform/javascript/js/libs/audio.worklet.js"]
-if env["gdnative_enabled"]:
- in_files.append(build[2]) # Runtime
- out_files.append(zip_dir.File(binary_name + ".side.wasm"))
-elif env["threads_enabled"]:
- in_files.append(build[2]) # Worker
- out_files.append(zip_dir.File(binary_name + ".worker.js"))
-
-if env["tools"]:
- in_files.append("#misc/dist/html/logo.svg")
- out_files.append(zip_dir.File("logo.svg"))
- in_files.append("#icon.png")
- out_files.append(zip_dir.File("favicon.png"))
-
-zip_files = env.InstallAs(out_files, in_files)
-env.Zip(
- "#bin/godot",
- zip_files,
- ZIPROOT=zip_dir,
- ZIPSUFFIX="${PROGSUFFIX}${ZIPSUFFIX}",
- ZIPCOMSTR="Archiving $SOURCES as $TARGET",
-)
+# Extra will be the thread worker, or the GDNative side, or None
+extra = build[2] if len(build) > 2 else None
+env.CreateTemplateZip(js_wrapped, build[1], extra)
diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp
index 6fd6c0ddf1..2f7bde065f 100644
--- a/platform/javascript/api/api.cpp
+++ b/platform/javascript/api/api.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/api/api.h b/platform/javascript/api/api.h
index 8afe0f33ce..2ac7333cdd 100644
--- a/platform/javascript/api/api.h
+++ b/platform/javascript/api/api.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/api/javascript_eval.h b/platform/javascript/api/javascript_eval.h
index 389983077e..24f7648ed9 100644
--- a/platform/javascript/api/javascript_eval.h
+++ b/platform/javascript/api/javascript_eval.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/api/javascript_tools_editor_plugin.cpp b/platform/javascript/api/javascript_tools_editor_plugin.cpp
index a063718a0c..8355faccc2 100644
--- a/platform/javascript/api/javascript_tools_editor_plugin.cpp
+++ b/platform/javascript/api/javascript_tools_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -108,7 +108,7 @@ void JavaScriptToolsEditorPlugin::_zip_recursive(String p_path, String p_base_pa
}
dir->list_dir_begin();
String cur = dir->get_next();
- while (!cur.empty()) {
+ while (!cur.is_empty()) {
String cs = p_path.plus_file(cur);
if (cur == "." || cur == ".." || cur == ".import") {
// Skip
diff --git a/platform/javascript/api/javascript_tools_editor_plugin.h b/platform/javascript/api/javascript_tools_editor_plugin.h
index df1197139c..557821d627 100644
--- a/platform/javascript/api/javascript_tools_editor_plugin.h
+++ b/platform/javascript/api/javascript_tools_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp
index 78fbed6d0f..478e848675 100644
--- a/platform/javascript/audio_driver_javascript.cpp
+++ b/platform/javascript/audio_driver_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -105,8 +105,8 @@ void AudioDriverJavaScript::_audio_driver_capture(int p_from, int p_samples) {
}
Error AudioDriverJavaScript::init() {
- mix_rate = GLOBAL_GET("audio/mix_rate");
- int latency = GLOBAL_GET("audio/output_latency");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
channel_count = godot_audio_init(mix_rate, latency, &_state_change_callback, &_latency_update_callback);
buffer_length = closest_power_of_2((latency * mix_rate / 1000));
@@ -267,7 +267,7 @@ int AudioDriverJavaScript::WorkletNode::create(int p_buffer_size, int p_channels
void AudioDriverJavaScript::WorkletNode::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) {
godot_audio_worklet_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, state);
- thread = Thread::create(_audio_thread_func, this);
+ thread.start(_audio_thread_func, this);
}
void AudioDriverJavaScript::WorkletNode::lock() {
@@ -280,8 +280,6 @@ void AudioDriverJavaScript::WorkletNode::unlock() {
void AudioDriverJavaScript::WorkletNode::finish() {
quit = true; // Ask thread to quit.
- Thread::wait_to_finish(thread);
- memdelete(thread);
- thread = nullptr;
+ thread.wait_to_finish();
}
#endif
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index f112a1ede4..393693640f 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,7 +59,7 @@ public:
STATE_MAX,
};
Mutex mutex;
- Thread *thread = nullptr;
+ Thread thread;
bool quit = false;
int32_t state[STATE_MAX] = { 0 };
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index d53c774e77..e80ef374ec 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -1,7 +1,14 @@
import os
import sys
-from emscripten_helpers import run_closure_compiler, create_engine_file, add_js_libraries
+from emscripten_helpers import (
+ run_closure_compiler,
+ create_engine_file,
+ add_js_libraries,
+ add_js_pre,
+ add_js_externs,
+ create_template_zip,
+)
from methods import get_compiler_version
from SCons.Util import WhereIs
@@ -50,12 +57,13 @@ def get_flags():
def configure(env):
- if not isinstance(env["initial_memory"], int):
+ try:
+ env["initial_memory"] = int(env["initial_memory"])
+ except Exception:
print("Initial memory must be a valid integer")
sys.exit(255)
## Build type
-
if env["target"] == "release":
# Use -Os to prioritize optimizing for reduced file size. This is
# particularly valuable for the web platform because it directly
@@ -84,9 +92,9 @@ def configure(env):
if not env["threads_enabled"]:
print("Threads must be enabled to build the editor. Please add the 'threads_enabled=yes' option")
sys.exit(255)
- if env["initial_memory"] < 32:
- print("Editor build requires at least 32MiB of initial memory. Forcing it.")
- env["initial_memory"] = 32
+ if env["initial_memory"] < 64:
+ print("Editor build requires at least 64MiB of initial memory. Forcing it.")
+ env["initial_memory"] = 64
elif env["builtin_icu"]:
env.Append(CCFLAGS=["-frtti"])
else:
@@ -131,12 +139,20 @@ def configure(env):
jscc = env.Builder(generator=run_closure_compiler, suffix=".cc.js", src_suffix=".js")
env.Append(BUILDERS={"BuildJS": jscc})
- # Add helper method for adding libraries.
+ # Add helper method for adding libraries, externs, pre-js.
+ env["JS_LIBS"] = []
+ env["JS_PRE"] = []
+ env["JS_EXTERNS"] = []
env.AddMethod(add_js_libraries, "AddJSLibraries")
+ env.AddMethod(add_js_pre, "AddJSPre")
+ env.AddMethod(add_js_externs, "AddJSExterns")
# Add method that joins/compiles our Engine files.
env.AddMethod(create_engine_file, "CreateEngineFile")
+ # Add method for creating the final zip file
+ env.AddMethod(create_template_zip, "CreateTemplateZip")
+
# Closure compiler extern and support for ecmascript specs (const, let, etc).
env["ENV"]["EMCC_CLOSURE_ARGS"] = "--language_in ECMASCRIPT6"
@@ -213,7 +229,15 @@ def configure(env):
env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"])
# callMain for manual start.
- env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"])
+ env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain','cwrap']"])
# Add code that allow exiting runtime.
env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"])
+
+ # TODO remove once we have GLES support back (temporary fix undefined symbols due to dead code elimination).
+ env.Append(
+ LINKFLAGS=[
+ "-s",
+ "EXPORTED_FUNCTIONS=['_main', '_emscripten_webgl_get_current_context', '_emscripten_webgl_commit_frame', '_emscripten_webgl_create_context']",
+ ]
+ )
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index 92e13553fc..12e06e24dc 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,41 +59,20 @@ bool DisplayServerJavaScript::is_canvas_focused() {
}
bool DisplayServerJavaScript::check_size_force_redraw() {
- int canvas_width;
- int canvas_height;
- emscripten_get_canvas_element_size(DisplayServerJavaScript::canvas_id, &canvas_width, &canvas_height);
- if (last_width != canvas_width || last_height != canvas_height) {
- last_width = canvas_width;
- last_height = canvas_height;
- // Update the framebuffer size for redraw.
- emscripten_set_canvas_element_size(DisplayServerJavaScript::canvas_id, canvas_width, canvas_height);
- return true;
- }
- return false;
+ return godot_js_display_size_update() != 0;
}
Point2 DisplayServerJavaScript::compute_position_in_canvas(int p_x, int p_y) {
- DisplayServerJavaScript *display = get_singleton();
- int canvas_x;
- int canvas_y;
- godot_js_display_canvas_bounding_rect_position_get(&canvas_x, &canvas_y);
- int canvas_width;
- int canvas_height;
- emscripten_get_canvas_element_size(display->canvas_id, &canvas_width, &canvas_height);
-
- double element_width;
- double element_height;
- emscripten_get_element_css_size(display->canvas_id, &element_width, &element_height);
-
- return Point2((int)(canvas_width / element_width * (p_x - canvas_x)),
- (int)(canvas_height / element_height * (p_y - canvas_y)));
+ int point[2];
+ godot_js_display_compute_position(p_x, p_y, point, point + 1);
+ return Point2(point[0], point[1]);
}
EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) {
DisplayServerJavaScript *display = get_singleton();
// Empty ID is canvas.
String target_id = String::utf8(p_event->id);
- if (target_id.empty() || target_id == String::utf8(display->canvas_id)) {
+ if (target_id.is_empty() || target_id == String::utf8(&(display->canvas_id[1]))) {
// This event property is the only reliable data on
// browser fullscreen state.
if (p_event->isFullscreen) {
@@ -455,7 +434,7 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const {
EmscriptenPointerlockChangeEvent ev;
emscripten_get_pointerlock_status(&ev);
- return (ev.isActive && String::utf8(ev.id) == String::utf8(canvas_id)) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
+ return (ev.isActive && String::utf8(ev.id) == String::utf8(&canvas_id[1])) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
}
// Wheel
@@ -558,57 +537,51 @@ bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const {
}
// Gamepad
-
-EM_BOOL DisplayServerJavaScript::gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data) {
+void DisplayServerJavaScript::gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid) {
Input *input = Input::get_singleton();
- if (p_event_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED) {
- String guid = "";
- if (String::utf8(p_event->mapping) == "standard")
- guid = "Default HTML5 Gamepad";
- input->joy_connection_changed(p_event->index, true, String::utf8(p_event->id), guid);
+ if (p_connected) {
+ input->joy_connection_changed(p_index, true, String::utf8(p_id), String::utf8(p_guid));
} else {
- input->joy_connection_changed(p_event->index, false, "");
+ input->joy_connection_changed(p_index, false, "");
}
- return true;
}
void DisplayServerJavaScript::process_joypads() {
- int joypad_count = emscripten_get_num_gamepads();
Input *input = Input::get_singleton();
- for (int joypad = 0; joypad < joypad_count; joypad++) {
- EmscriptenGamepadEvent state;
- EMSCRIPTEN_RESULT query_result = emscripten_get_gamepad_status(joypad, &state);
- // Chromium reserves gamepads slots, so NO_DATA is an expected result.
- ERR_CONTINUE(query_result != EMSCRIPTEN_RESULT_SUCCESS &&
- query_result != EMSCRIPTEN_RESULT_NO_DATA);
- if (query_result == EMSCRIPTEN_RESULT_SUCCESS && state.connected) {
- int button_count = MIN(state.numButtons, 18);
- int axis_count = MIN(state.numAxes, 8);
- for (int button = 0; button < button_count; button++) {
- float value = state.analogButton[button];
- input->joy_button(joypad, button, value);
- }
- for (int axis = 0; axis < axis_count; axis++) {
+ int32_t pads = godot_js_display_gamepad_sample_count();
+ int32_t s_btns_num = 0;
+ int32_t s_axes_num = 0;
+ int32_t s_standard = 0;
+ float s_btns[16];
+ float s_axes[10];
+ for (int idx = 0; idx < pads; idx++) {
+ int err = godot_js_display_gamepad_sample_get(idx, s_btns, &s_btns_num, s_axes, &s_axes_num, &s_standard);
+ if (err) {
+ continue;
+ }
+ for (int b = 0; b < s_btns_num; b++) {
+ float value = s_btns[b];
+ // Buttons 6 and 7 in the standard mapping need to be
+ // axis to be handled as JOY_AXIS_TRIGGER by Godot.
+ if (s_standard && (b == 6 || b == 7)) {
Input::JoyAxis joy_axis;
- joy_axis.min = -1;
- joy_axis.value = state.axis[axis];
- input->joy_axis(joypad, axis, joy_axis);
+ joy_axis.min = 0;
+ joy_axis.value = value;
+ int a = b == 6 ? JOY_AXIS_TRIGGER_LEFT : JOY_AXIS_TRIGGER_RIGHT;
+ input->joy_axis(idx, a, joy_axis);
+ } else {
+ input->joy_button(idx, b, value);
}
}
+ for (int a = 0; a < s_axes_num; a++) {
+ Input::JoyAxis joy_axis;
+ joy_axis.min = -1;
+ joy_axis.value = s_axes[a];
+ input->joy_axis(idx, a, joy_axis);
+ }
}
}
-#if 0
-bool DisplayServerJavaScript::is_joy_known(int p_device) {
- return Input::get_singleton()->is_joy_mapped(p_device);
-}
-
-
-String DisplayServerJavaScript::get_joy_guid(int p_device) const {
- return Input::get_singleton()->get_joy_guid_remapped(p_device);
-}
-#endif
-
Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() {
Vector<String> drivers;
drivers.push_back("dummy");
@@ -709,6 +682,9 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
// Ensure the canvas ID.
godot_js_config_canvas_id_get(canvas_id, 256);
+ // Handle contextmenu, webglcontextlost
+ godot_js_display_setup_canvas(p_resolution.x, p_resolution.y, p_mode == WINDOW_MODE_FULLSCREEN, OS::get_singleton()->is_hidpi_allowed() ? 1 : 0);
+
// Check if it's windows.
swap_cancel_ok = godot_js_display_is_swap_ok_cancel() == 1;
@@ -751,11 +727,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
video_driver_index = p_video_driver;
#endif
- window_set_mode(p_mode);
- if (godot_js_config_is_resize_on_start()) {
- window_set_size(p_resolution);
- }
-
EMSCRIPTEN_RESULT result;
#define EM_CHECK(ev) \
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
@@ -766,9 +737,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
#define SET_EM_WINDOW_CALLBACK(ev, cb) \
result = emscripten_set_##ev##_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, &cb); \
EM_CHECK(ev)
-#define SET_EM_CALLBACK_NOTARGET(ev, cb) \
- result = emscripten_set_##ev##_callback(nullptr, true, &cb); \
- EM_CHECK(ev)
// These callbacks from Emscripten's html5.h suffice to access most
// JavaScript APIs.
SET_EM_CALLBACK(canvas_id, mousedown, mouse_button_callback)
@@ -783,9 +751,6 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
SET_EM_CALLBACK(canvas_id, keypress, keypress_callback)
SET_EM_CALLBACK(canvas_id, keyup, keyup_callback)
SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, fullscreenchange, fullscreen_change_callback)
- SET_EM_CALLBACK_NOTARGET(gamepadconnected, gamepad_change_callback)
- SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback)
-#undef SET_EM_CALLBACK_NOTARGET
#undef SET_EM_CALLBACK
#undef EM_CHECK
@@ -798,6 +763,7 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive
WINDOW_EVENT_FOCUS_OUT);
godot_js_display_paste_cb(update_clipboard_callback);
godot_js_display_drop_files_cb(drop_files_js_callback);
+ godot_js_display_gamepad_cb(&DisplayServerJavaScript::gamepad_callback);
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_event);
}
@@ -850,20 +816,23 @@ Point2i DisplayServerJavaScript::screen_get_position(int p_screen) const {
}
Size2i DisplayServerJavaScript::screen_get_size(int p_screen) const {
- EmscriptenFullscreenChangeEvent ev;
- EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev);
- ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2i());
- return Size2i(ev.screenWidth, ev.screenHeight);
+ int size[2];
+ godot_js_display_screen_size_get(size, size + 1);
+ return Size2(size[0], size[1]);
}
Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const {
- int canvas[2];
- emscripten_get_canvas_element_size(canvas_id, canvas, canvas + 1);
- return Rect2i(0, 0, canvas[0], canvas[1]);
+ int size[2];
+ godot_js_display_window_size_get(size, size + 1);
+ return Rect2i(0, 0, size[0], size[1]);
}
int DisplayServerJavaScript::screen_get_dpi(int p_screen) const {
- return 96; // TODO maybe check pixel ratio via window.devicePixelRatio * 96? Inexact.
+ return godot_js_display_screen_dpi_get();
+}
+
+float DisplayServerJavaScript::screen_get_scale(int p_screen) const {
+ return godot_js_display_pixel_ratio_get();
}
Vector<DisplayServer::WindowID> DisplayServerJavaScript::get_window_list() const {
@@ -945,17 +914,13 @@ Size2i DisplayServerJavaScript::window_get_min_size(WindowID p_window) const {
}
void DisplayServerJavaScript::window_set_size(const Size2i p_size, WindowID p_window) {
- last_width = p_size.x;
- last_height = p_size.y;
- double scale = godot_js_display_pixel_ratio_get();
- emscripten_set_canvas_element_size(canvas_id, p_size.x, p_size.y);
- emscripten_set_element_css_size(canvas_id, p_size.x / scale, p_size.y / scale);
+ godot_js_display_desired_size_set(p_size.x, p_size.y);
}
Size2i DisplayServerJavaScript::window_get_size(WindowID p_window) const {
- int canvas[2];
- emscripten_get_canvas_element_size(canvas_id, canvas, canvas + 1);
- return Size2(canvas[0], canvas[1]);
+ int size[2];
+ godot_js_display_window_size_get(size, size + 1);
+ return Size2i(size[0], size[1]);
}
Size2i DisplayServerJavaScript::window_get_real_size(WindowID p_window) const {
@@ -969,20 +934,13 @@ void DisplayServerJavaScript::window_set_mode(WindowMode p_mode, WindowID p_wind
switch (p_mode) {
case WINDOW_MODE_WINDOWED: {
if (window_mode == WINDOW_MODE_FULLSCREEN) {
- emscripten_exit_fullscreen();
+ godot_js_display_fullscreen_exit();
}
window_mode = WINDOW_MODE_WINDOWED;
- window_set_size(Size2i(last_width, last_height));
} break;
case WINDOW_MODE_FULLSCREEN: {
- EmscriptenFullscreenStrategy strategy;
- strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
- strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
- strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
- strategy.canvasResizedCallback = nullptr;
- EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(canvas_id, false, &strategy);
- ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
- ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
+ int result = godot_js_display_fullscreen_request();
+ ERR_FAIL_COND_MSG(result, "The request was denied. Remember that enabling fullscreen is only possible from an input callback for the HTML5 platform.");
} break;
case WINDOW_MODE_MAXIMIZED:
case WINDOW_MODE_MINIMIZED:
@@ -1026,8 +984,9 @@ bool DisplayServerJavaScript::can_any_window_draw() const {
}
void DisplayServerJavaScript::process_events() {
- if (emscripten_sample_gamepad_data() == EMSCRIPTEN_RESULT_SUCCESS)
+ if (godot_js_display_gamepad_sample() == OK) {
process_joypads();
+ }
}
int DisplayServerJavaScript::get_current_video_driver() const {
diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h
index 1f00295d48..47e25ab2a0 100644
--- a/platform/javascript/display_server_javascript.h
+++ b/platform/javascript/display_server_javascript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,9 +57,6 @@ private:
double last_click_ms = 0;
int last_click_button_index = -1;
- int last_width = 0;
- int last_height = 0;
-
bool swap_cancel_ok = false;
// utilities
@@ -86,7 +83,7 @@ private:
static EM_BOOL touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
static EM_BOOL touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
- static EM_BOOL gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data);
+ static void gamepad_callback(int p_index, int p_connected, const char *p_id, const char *p_guid);
void process_joypads();
static Vector<String> get_rendering_drivers_func();
@@ -136,6 +133,7 @@ public:
Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
// windows
Vector<DisplayServer::WindowID> get_window_list() const override;
diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc
index e3f2ce42b4..7902efafe0 100644
--- a/platform/javascript/dom_keys.inc
+++ b/platform/javascript/dom_keys.inc
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py
index cc874c432e..04fbba8a41 100644
--- a/platform/javascript/emscripten_helpers.py
+++ b/platform/javascript/emscripten_helpers.py
@@ -15,13 +15,87 @@ def run_closure_compiler(target, source, env, for_signature):
return " ".join(cmd)
+def get_build_version():
+ import version
+
+ name = "custom_build"
+ if os.getenv("BUILD_NAME") != None:
+ name = os.getenv("BUILD_NAME")
+ return "%d.%d.%d.%s.%s" % (version.major, version.minor, version.patch, version.status, name)
+
+
def create_engine_file(env, target, source, externs):
if env["use_closure_compiler"]:
return env.BuildJS(target, source, JSEXTERNS=externs)
return env.Textfile(target, [env.File(s) for s in source])
+def create_template_zip(env, js, wasm, extra):
+ binary_name = "godot.tools" if env["tools"] else "godot"
+ zip_dir = env.Dir("#bin/.javascript_zip")
+ in_files = [
+ js,
+ wasm,
+ "#platform/javascript/js/libs/audio.worklet.js",
+ ]
+ out_files = [
+ zip_dir.File(binary_name + ".js"),
+ zip_dir.File(binary_name + ".wasm"),
+ zip_dir.File(binary_name + ".audio.worklet.js"),
+ ]
+ # GDNative/Threads specific
+ if env["gdnative_enabled"]:
+ in_files.append(extra) # Runtime
+ out_files.append(zip_dir.File(binary_name + ".side.wasm"))
+ elif env["threads_enabled"]:
+ in_files.append(extra) # Worker
+ out_files.append(zip_dir.File(binary_name + ".worker.js"))
+
+ service_worker = "#misc/dist/html/service-worker.js"
+ if env["tools"]:
+ # HTML
+ html = "#misc/dist/html/editor.html"
+ subst_dict = {"@GODOT_VERSION@": get_build_version(), "@GODOT_NAME@": "GodotEngine"}
+ html = env.Substfile(target="#bin/godot${PROGSUFFIX}.html", source=html, SUBST_DICT=subst_dict)
+ in_files.append(html)
+ out_files.append(zip_dir.File(binary_name + ".html"))
+ # And logo/favicon
+ in_files.append("#misc/dist/html/logo.svg")
+ out_files.append(zip_dir.File("logo.svg"))
+ in_files.append("#icon.png")
+ out_files.append(zip_dir.File("favicon.png"))
+ # PWA
+ service_worker = env.Substfile(
+ target="#bin/godot${PROGSUFFIX}.service.worker.js", source=service_worker, SUBST_DICT=subst_dict
+ )
+ in_files.append(service_worker)
+ out_files.append(zip_dir.File("service.worker.js"))
+ in_files.append("#misc/dist/html/manifest.json")
+ out_files.append(zip_dir.File("manifest.json"))
+ in_files.append("#misc/dist/html/offline.html")
+ out_files.append(zip_dir.File("offline.html"))
+ else:
+ # HTML
+ in_files.append("#misc/dist/html/full-size.html")
+ out_files.append(zip_dir.File(binary_name + ".html"))
+
+ zip_files = env.InstallAs(out_files, in_files)
+ env.Zip(
+ "#bin/godot",
+ zip_files,
+ ZIPROOT=zip_dir,
+ ZIPSUFFIX="${PROGSUFFIX}${ZIPSUFFIX}",
+ ZIPCOMSTR="Archiving $SOURCES as $TARGET",
+ )
+
+
def add_js_libraries(env, libraries):
- if "JS_LIBS" not in env:
- env["JS_LIBS"] = []
env.Append(JS_LIBS=env.File(libraries))
+
+
+def add_js_pre(env, js_pre):
+ env.Append(JS_PRE=env.File(js_pre))
+
+
+def add_js_externs(env, externs):
+ env.Append(JS_EXTERNS=env.File(externs))
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 37681b2484..46d0458ca1 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -119,7 +119,7 @@ public:
filepath = cache_path.plus_file(req[1].get_file()); // TODO dangerous?
ctype = "application/wasm";
}
- if (filepath.empty() || !FileAccess::exists(filepath)) {
+ if (filepath.is_empty() || !FileAccess::exists(filepath)) {
String s = "HTTP/1.1 404 Not Found\r\n";
s += "Connection: Close\r\n";
s += "\r\n";
@@ -135,6 +135,7 @@ public:
s += "Access-Control-Allow-Origin: *\r\n";
s += "Cross-Origin-Opener-Policy: same-origin\r\n";
s += "Cross-Origin-Embedder-Policy: require-corp\r\n";
+ s += "Cache-Control: no-store, max-age=0\r\n";
s += "\r\n";
CharString cs = s.utf8();
Error err = connection->put_data((const uint8_t *)cs.get_data(), cs.size() - 1);
@@ -213,7 +214,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
Ref<EditorHTTPServer> server;
bool server_quit = false;
Mutex server_lock;
- Thread *server_thread = nullptr;
+ Thread server_thread;
enum ExportMode {
EXPORT_MODE_NORMAL = 0,
@@ -241,7 +242,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
return name;
}
- void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects);
+ void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects, const Dictionary &p_file_sizes);
static void _server_thread_poll(void *data);
@@ -280,28 +281,34 @@ public:
~EditorExportPlatformJavaScript();
};
-void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects) {
+void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags, const Vector<SharedObject> p_shared_objects, const Dictionary &p_file_sizes) {
String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size());
String str_export;
Vector<String> lines = str_template.split("\n");
- Vector<String> flags;
- String flags_json;
- gen_export_flags(flags, p_flags);
- flags_json = JSON::print(flags);
- String libs;
+ Array libs;
for (int i = 0; i < p_shared_objects.size(); i++) {
- libs += "\"" + p_shared_objects[i].path.get_file() + "\",";
+ libs.push_back(p_shared_objects[i].path.get_file());
}
+ Vector<String> flags;
+ gen_export_flags(flags, p_flags & (~DEBUG_FLAG_DUMB_CLIENT));
+ Array args;
+ for (int i = 0; i < flags.size(); i++) {
+ args.push_back(flags[i]);
+ }
+ Dictionary config;
+ config["canvasResizePolicy"] = p_preset->get("html/canvas_resize_policy");
+ config["gdnativeLibs"] = libs;
+ config["executable"] = p_name;
+ config["args"] = args;
+ config["fileSizes"] = p_file_sizes;
+ const String str_config = JSON::print(config);
for (int i = 0; i < lines.size(); i++) {
String current_line = lines[i];
- current_line = current_line.replace("$GODOT_BASENAME", p_name);
+ current_line = current_line.replace("$GODOT_URL", p_name + ".js");
current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name"));
current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include"));
- current_line = current_line.replace("$GODOT_FULL_WINDOW", p_preset->get("html/full_window_size") ? "true" : "false");
- current_line = current_line.replace("$GODOT_GDNATIVE_LIBS", libs);
- current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false");
- current_line = current_line.replace("$GODOT_ARGS", flags_json);
+ current_line = current_line.replace("$GODOT_CONFIG", str_config);
str_export += current_line + "\n";
}
@@ -318,7 +325,7 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
}
if (p_preset->get("vram_texture_compression/for_mobile")) {
- String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
+ String driver = ProjectSettings::get_singleton()->get("rendering/driver/driver_name");
if (driver == "GLES2") {
r_features->push_back("etc");
} else if (driver == "Vulkan") {
@@ -344,7 +351,7 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/full_window_size"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "html/canvas_resize_policy", PROPERTY_HINT_ENUM, "None,Project,Adaptive"), 2));
}
String EditorExportPlatformJavaScript::get_name() const {
@@ -394,7 +401,7 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p
}
}
- if (!err.empty()) {
+ if (!err.is_empty()) {
r_error = err;
}
@@ -466,6 +473,8 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
return ERR_FILE_CORRUPT;
}
+ Vector<uint8_t> html;
+ Dictionary file_sizes;
do {
//get filename
unz_file_info info;
@@ -474,6 +483,16 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
String file = fname;
+ // HTML is handled later
+ if (file == "godot.html") {
+ if (custom_html.is_empty()) {
+ html.resize(info.uncompressed_size);
+ unzOpenCurrentFile(pkg);
+ unzReadCurrentFile(pkg, html.ptrw(), html.size());
+ unzCloseCurrentFile(pkg);
+ }
+ continue;
+ }
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -484,14 +503,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
//write
- if (file == "godot.html") {
- if (!custom_html.empty()) {
- continue;
- }
- _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug, p_flags, shared_objects);
- file = p_path.get_file();
-
- } else if (file == "godot.js") {
+ if (file == "godot.js") {
file = p_path.get_file().get_basename() + ".js";
} else if (file == "godot.worker.js") {
@@ -505,6 +517,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
} else if (file == "godot.wasm") {
file = p_path.get_file().get_basename() + ".wasm";
+ file_sizes[file.get_file()] = (uint64_t)info.uncompressed_size;
}
String dst = p_path.get_base_dir().plus_file(file);
@@ -520,30 +533,37 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
} while (unzGoToNextFile(pkg) == UNZ_OK);
unzClose(pkg);
- if (!custom_html.empty()) {
+ if (!custom_html.is_empty()) {
FileAccess *f = FileAccess::open(custom_html, FileAccess::READ);
if (!f) {
EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:") + "\n" + custom_html);
return ERR_FILE_CANT_READ;
}
- Vector<uint8_t> buf;
- buf.resize(f->get_len());
- f->get_buffer(buf.ptrw(), buf.size());
+ html.resize(f->get_len());
+ f->get_buffer(html.ptrw(), html.size());
memdelete(f);
- _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug, p_flags, shared_objects);
-
+ }
+ {
+ FileAccess *f = FileAccess::open(pck_path, FileAccess::READ);
+ if (f) {
+ file_sizes[pck_path.get_file()] = (uint64_t)f->get_len();
+ memdelete(f);
+ f = NULL;
+ }
+ _fix_html(html, p_preset, p_path.get_file().get_basename(), p_debug, p_flags, shared_objects, file_sizes);
f = FileAccess::open(p_path, FileAccess::WRITE);
if (!f) {
EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + p_path);
return ERR_FILE_CANT_WRITE;
}
- f->store_buffer(buf.ptr(), buf.size());
+ f->store_buffer(html.ptr(), html.size());
memdelete(f);
+ html.resize(0);
}
Ref<Image> splash;
const String splash_path = String(GLOBAL_GET("application/boot_splash/image")).strip_edges();
- if (!splash_path.empty()) {
+ if (!splash_path.is_empty()) {
splash.instance();
const Error err = splash->load(splash_path);
if (err) {
@@ -564,7 +584,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
// This way, the favicon can be displayed immediately when loading the page.
Ref<Image> favicon;
const String favicon_path = String(GLOBAL_GET("application/config/icon")).strip_edges();
- if (!favicon_path.empty()) {
+ if (!favicon_path.is_empty()) {
favicon.instance();
const Error err = favicon->load(favicon_path);
if (err) {
@@ -681,7 +701,7 @@ void EditorExportPlatformJavaScript::_server_thread_poll(void *data) {
EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
server.instance();
- server_thread = Thread::create(_server_thread_poll, this);
+ server_thread.start(_server_thread_poll, this);
Ref<Image> img = memnew(Image(_javascript_logo));
logo.instance();
@@ -702,8 +722,7 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() {
server->stop();
server_quit = true;
- Thread::wait_to_finish(server_thread);
- memdelete(server_thread);
+ server_thread.wait_to_finish();
}
void register_javascript_exporter() {
diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h
index 30c5c855d1..e641339f55 100644
--- a/platform/javascript/export/export.h
+++ b/platform/javascript/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/godot_audio.h b/platform/javascript/godot_audio.h
index aeb234269e..54fc8fa3b5 100644
--- a/platform/javascript/godot_audio.h
+++ b/platform/javascript/godot_audio.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h
index 23596a0897..f86aadd2c2 100644
--- a/platform/javascript/godot_js.h
+++ b/platform/javascript/godot_js.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,6 @@ extern "C" {
// Config
extern void godot_js_config_locale_get(char *p_ptr, int p_ptr_max);
extern void godot_js_config_canvas_id_get(char *p_ptr, int p_ptr_max);
-extern int godot_js_config_is_resize_on_start();
// OS
extern void godot_js_os_finish_async(void (*p_callback)());
@@ -49,8 +48,10 @@ extern int godot_js_os_fs_is_persistent();
extern void godot_js_os_fs_sync(void (*p_callback)());
extern int godot_js_os_execute(const char *p_json);
extern void godot_js_os_shell_open(const char *p_uri);
+extern int godot_js_os_hw_concurrency_get();
// Display
+extern int godot_js_display_screen_dpi_get();
extern double godot_js_display_pixel_ratio_get();
extern void godot_js_display_alert(const char *p_text);
extern int godot_js_display_touchscreen_is_available();
@@ -59,10 +60,15 @@ extern int godot_js_display_is_swap_ok_cancel();
// Display canvas
extern void godot_js_display_canvas_focus();
extern int godot_js_display_canvas_is_focused();
-extern void godot_js_display_canvas_bounding_rect_position_get(int32_t *p_x, int32_t *p_y);
// Display window
-extern void godot_js_display_window_request_fullscreen();
+extern void godot_js_display_desired_size_set(int p_width, int p_height);
+extern int godot_js_display_size_update();
+extern void godot_js_display_window_size_get(int32_t *p_x, int32_t *p_y);
+extern void godot_js_display_screen_size_get(int32_t *p_x, int32_t *p_y);
+extern int godot_js_display_fullscreen_request();
+extern int godot_js_display_fullscreen_exit();
+extern void godot_js_display_compute_position(int p_x, int p_y, int32_t *r_x, int32_t *r_y);
extern void godot_js_display_window_title_set(const char *p_text);
extern void godot_js_display_window_icon_set(const uint8_t *p_ptr, int p_len);
@@ -76,10 +82,17 @@ extern int godot_js_display_cursor_is_hidden();
extern void godot_js_display_cursor_set_custom_shape(const char *p_shape, const uint8_t *p_ptr, int p_len, int p_hotspot_x, int p_hotspot_y);
extern void godot_js_display_cursor_set_visible(int p_visible);
+// Display gamepad
+extern char *godot_js_display_gamepad_cb(void (*p_on_change)(int p_index, int p_connected, const char *p_id, const char *p_guid));
+extern int godot_js_display_gamepad_sample();
+extern int godot_js_display_gamepad_sample_count();
+extern int godot_js_display_gamepad_sample_get(int p_idx, float r_btns[16], int32_t *r_btns_num, float r_axes[10], int32_t *r_axes_num, int32_t *r_standard);
+
// Display listeners
extern void godot_js_display_notification_cb(void (*p_callback)(int p_notification), int p_enter, int p_exit, int p_in, int p_out);
extern void godot_js_display_paste_cb(void (*p_callback)(const char *p_text));
extern void godot_js_display_drop_files_cb(void (*p_callback)(char **p_filev, int p_filec));
+extern void godot_js_display_setup_canvas(int p_width, int p_height, int p_fullscreen, int p_hidpi);
#ifdef __cplusplus
}
#endif
diff --git a/platform/javascript/http_client.h.inc b/platform/javascript/http_client.h.inc
index 4d5ff88bdd..842a93fcba 100644
--- a/platform/javascript/http_client.h.inc
+++ b/platform/javascript/http_client.h.inc
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,24 +30,21 @@
// HTTPClient's additional private members in the javascript platform
-Error prepare_request(Method p_method, const String &p_url, const Vector<String> &p_headers);
+Error make_request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_len);
+static void _parse_headers(int p_len, const char **p_headers, void *p_ref);
-int xhr_id;
+int js_id = 0;
int read_limit = 4096;
-int response_read_offset = 0;
Status status = STATUS_DISCONNECTED;
String host;
int port = -1;
bool use_tls = false;
-String username;
-String password;
int polled_response_code = 0;
-String polled_response_header;
-PackedByteArray polled_response;
+Vector<String> response_headers;
+Vector<uint8_t> response_buffer;
#ifdef DEBUG_ENABLED
-bool has_polled = false;
uint64_t last_polling_frame = 0;
#endif
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index cb0e48b8a9..b79c965854 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,38 @@
#include "core/io/http_client.h"
-#include "http_request.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stddef.h"
+
+typedef enum {
+ GODOT_JS_FETCH_STATE_REQUESTING = 0,
+ GODOT_JS_FETCH_STATE_BODY = 1,
+ GODOT_JS_FETCH_STATE_DONE = 2,
+ GODOT_JS_FETCH_STATE_ERROR = -1,
+} godot_js_fetch_state_t;
+
+extern int godot_js_fetch_create(const char *p_method, const char *p_url, const char **p_headers, int p_headers_len, const uint8_t *p_body, int p_body_len);
+extern int godot_js_fetch_read_headers(int p_id, void (*parse_callback)(int p_size, const char **p_headers, void *p_ref), void *p_ref);
+extern int godot_js_fetch_read_chunk(int p_id, uint8_t *p_buf, int p_buf_size);
+extern void godot_js_fetch_free(int p_id);
+extern godot_js_fetch_state_t godot_js_fetch_state_get(int p_id);
+extern int godot_js_fetch_body_length_get(int p_id);
+extern int godot_js_fetch_http_status_get(int p_id);
+extern int godot_js_fetch_is_chunked(int p_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+void HTTPClient::_parse_headers(int p_len, const char **p_headers, void *p_ref) {
+ HTTPClient *client = static_cast<HTTPClient *>(p_ref);
+ for (int i = 0; i < p_len; i++) {
+ client->response_headers.push_back(String::utf8(p_headers[i]));
+ }
+}
Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) {
close();
@@ -74,46 +105,42 @@ Ref<StreamPeer> HTTPClient::get_connection() const {
ERR_FAIL_V_MSG(REF(), "Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform.");
}
-Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Vector<String> &p_headers) {
+Error HTTPClient::make_request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_len) {
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V_MSG(p_method == METHOD_TRACE || p_method == METHOD_CONNECT, ERR_UNAVAILABLE, "HTTP methods TRACE and CONNECT are not supported for the HTML5 platform.");
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(host.empty(), ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(host.is_empty(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + p_url;
- godot_xhr_reset(xhr_id);
- godot_xhr_open(xhr_id, _methods[p_method], url.utf8().get_data(),
- username.empty() ? nullptr : username.utf8().get_data(),
- password.empty() ? nullptr : password.utf8().get_data());
-
+ Vector<CharString> keeper;
+ Vector<const char *> c_strings;
for (int i = 0; i < p_headers.size(); i++) {
- int header_separator = p_headers[i].find(": ");
- ERR_FAIL_COND_V(header_separator < 0, ERR_INVALID_PARAMETER);
- godot_xhr_set_request_header(xhr_id,
- p_headers[i].left(header_separator).utf8().get_data(),
- p_headers[i].right(header_separator + 2).utf8().get_data());
+ keeper.push_back(p_headers[i].utf8());
+ c_strings.push_back(keeper[i].get_data());
+ }
+ if (js_id) {
+ godot_js_fetch_free(js_id);
}
- response_read_offset = 0;
+ js_id = godot_js_fetch_create(_methods[p_method], url.utf8().get_data(), c_strings.ptrw(), c_strings.size(), p_body, p_body_len);
status = STATUS_REQUESTING;
return OK;
}
Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) {
- Error err = prepare_request(p_method, p_url, p_headers);
- if (err != OK)
- return err;
- godot_xhr_send_data(xhr_id, p_body.ptr(), p_body.size());
- return OK;
+ if (p_body.is_empty()) {
+ return make_request(p_method, p_url, p_headers, nullptr, 0);
+ }
+ return make_request(p_method, p_url, p_headers, p_body.ptr(), p_body.size());
}
Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) {
- Error err = prepare_request(p_method, p_url, p_headers);
- if (err != OK)
- return err;
- godot_xhr_send_string(xhr_id, p_body.utf8().get_data());
- return OK;
+ if (p_body.is_empty()) {
+ return make_request(p_method, p_url, p_headers, nullptr, 0);
+ }
+ const CharString cs = p_body.utf8();
+ return make_request(p_method, p_url, p_headers, (const uint8_t *)cs.get_data(), cs.size() - 1);
}
void HTTPClient::close() {
@@ -121,10 +148,13 @@ void HTTPClient::close() {
port = -1;
use_tls = false;
status = STATUS_DISCONNECTED;
- polled_response.resize(0);
polled_response_code = 0;
- polled_response_header = String();
- godot_xhr_reset(xhr_id);
+ response_headers.resize(0);
+ response_buffer.resize(0);
+ if (js_id) {
+ godot_js_fetch_free(js_id);
+ js_id = 0;
+ }
}
HTTPClient::Status HTTPClient::get_status() const {
@@ -132,12 +162,11 @@ HTTPClient::Status HTTPClient::get_status() const {
}
bool HTTPClient::has_response() const {
- return !polled_response_header.empty();
+ return response_headers.size() > 0;
}
bool HTTPClient::is_response_chunked() const {
- // TODO evaluate using moz-chunked-arraybuffer, fetch & ReadableStream
- return false;
+ return godot_js_fetch_is_chunked(js_id);
}
int HTTPClient::get_response_code() const {
@@ -145,36 +174,42 @@ int HTTPClient::get_response_code() const {
}
Error HTTPClient::get_response_headers(List<String> *r_response) {
- if (polled_response_header.empty())
+ if (!response_headers.size()) {
return ERR_INVALID_PARAMETER;
-
- Vector<String> header_lines = polled_response_header.split("\r\n", false);
- for (int i = 0; i < header_lines.size(); ++i) {
- r_response->push_back(header_lines[i]);
}
- polled_response_header = String();
+ for (int i = 0; i < response_headers.size(); i++) {
+ r_response->push_back(response_headers[i]);
+ }
+ response_headers.clear();
return OK;
}
int HTTPClient::get_response_body_length() const {
- return polled_response.size();
+ return godot_js_fetch_body_length_get(js_id);
}
PackedByteArray HTTPClient::read_response_body_chunk() {
ERR_FAIL_COND_V(status != STATUS_BODY, PackedByteArray());
- int to_read = MIN(read_limit, polled_response.size() - response_read_offset);
- PackedByteArray chunk;
- chunk.resize(to_read);
- memcpy(chunk.ptrw(), polled_response.ptr() + response_read_offset, to_read);
- response_read_offset += to_read;
-
- if (response_read_offset == polled_response.size()) {
- status = STATUS_CONNECTED;
- polled_response.resize(0);
- godot_xhr_reset(xhr_id);
+ if (response_buffer.size() != read_limit) {
+ response_buffer.resize(read_limit);
+ }
+ int read = godot_js_fetch_read_chunk(js_id, response_buffer.ptrw(), read_limit);
+
+ // Check if the stream is over.
+ godot_js_fetch_state_t state = godot_js_fetch_state_get(js_id);
+ if (state == GODOT_JS_FETCH_STATE_DONE) {
+ status = STATUS_DISCONNECTED;
+ } else if (state != GODOT_JS_FETCH_STATE_BODY) {
+ status = STATUS_CONNECTION_ERROR;
}
+ PackedByteArray chunk;
+ if (!read) {
+ return chunk;
+ }
+ chunk.resize(read);
+ copymem(chunk.ptrw(), response_buffer.ptr(), read);
return chunk;
}
@@ -208,48 +243,48 @@ Error HTTPClient::poll() {
return OK;
case STATUS_CONNECTED:
- case STATUS_BODY:
return OK;
+ case STATUS_BODY: {
+ godot_js_fetch_state_t state = godot_js_fetch_state_get(js_id);
+ if (state == GODOT_JS_FETCH_STATE_DONE) {
+ status = STATUS_DISCONNECTED;
+ } else if (state != GODOT_JS_FETCH_STATE_BODY) {
+ status = STATUS_CONNECTION_ERROR;
+ return ERR_CONNECTION_ERROR;
+ }
+ return OK;
+ }
+
case STATUS_CONNECTION_ERROR:
return ERR_CONNECTION_ERROR;
case STATUS_REQUESTING: {
#ifdef DEBUG_ENABLED
- if (!has_polled) {
- has_polled = true;
- } else {
- // forcing synchronous requests is not possible on the web
- if (last_polling_frame == Engine::get_singleton()->get_idle_frames()) {
- WARN_PRINT("HTTPClient polled multiple times in one frame, "
- "but request cannot progress more than once per "
- "frame on the HTML5 platform.");
- }
+ // forcing synchronous requests is not possible on the web
+ if (last_polling_frame == Engine::get_singleton()->get_process_frames()) {
+ WARN_PRINT("HTTPClient polled multiple times in one frame, "
+ "but request cannot progress more than once per "
+ "frame on the HTML5 platform.");
}
- last_polling_frame = Engine::get_singleton()->get_idle_frames();
+ last_polling_frame = Engine::get_singleton()->get_process_frames();
#endif
- polled_response_code = godot_xhr_get_status(xhr_id);
- if (godot_xhr_get_ready_state(xhr_id) != XHR_READY_STATE_DONE) {
+ polled_response_code = godot_js_fetch_http_status_get(js_id);
+ godot_js_fetch_state_t js_state = godot_js_fetch_state_get(js_id);
+ if (js_state == GODOT_JS_FETCH_STATE_REQUESTING) {
return OK;
- } else if (!polled_response_code) {
+ } else if (js_state == GODOT_JS_FETCH_STATE_ERROR) {
+ // Fetch is in error state.
+ status = STATUS_CONNECTION_ERROR;
+ return ERR_CONNECTION_ERROR;
+ }
+ if (godot_js_fetch_read_headers(js_id, &_parse_headers, this)) {
+ // Failed to parse headers.
status = STATUS_CONNECTION_ERROR;
return ERR_CONNECTION_ERROR;
}
-
status = STATUS_BODY;
-
- PackedByteArray bytes;
- int len = godot_xhr_get_response_headers_length(xhr_id);
- bytes.resize(len + 1);
-
- godot_xhr_get_response_headers(xhr_id, reinterpret_cast<char *>(bytes.ptrw()), len);
- bytes.ptrw()[len] = 0;
-
- polled_response_header = String::utf8(reinterpret_cast<const char *>(bytes.ptr()));
-
- polled_response.resize(godot_xhr_get_response_length(xhr_id));
- godot_xhr_get_response(xhr_id, polled_response.ptrw(), polled_response.size());
break;
}
@@ -260,9 +295,8 @@ Error HTTPClient::poll() {
}
HTTPClient::HTTPClient() {
- xhr_id = godot_xhr_new();
}
HTTPClient::~HTTPClient() {
- godot_xhr_free(xhr_id);
+ close();
}
diff --git a/platform/javascript/http_request.h b/platform/javascript/http_request.h
deleted file mode 100644
index 41e4749216..0000000000
--- a/platform/javascript/http_request.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*************************************************************************/
-/* http_request.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef HTTP_REQUEST_H
-#define HTTP_REQUEST_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "stddef.h"
-
-typedef enum {
- XHR_READY_STATE_UNSENT = 0,
- XHR_READY_STATE_OPENED = 1,
- XHR_READY_STATE_HEADERS_RECEIVED = 2,
- XHR_READY_STATE_LOADING = 3,
- XHR_READY_STATE_DONE = 4,
-} godot_xhr_ready_state_t;
-
-extern int godot_xhr_new();
-extern void godot_xhr_reset(int p_xhr_id);
-extern void godot_xhr_free(int p_xhr_id);
-
-extern int godot_xhr_open(int p_xhr_id, const char *p_method, const char *p_url, const char *p_user = nullptr, const char *p_password = nullptr);
-
-extern void godot_xhr_set_request_header(int p_xhr_id, const char *p_header, const char *p_value);
-
-extern void godot_xhr_send_null(int p_xhr_id);
-extern void godot_xhr_send_string(int p_xhr_id, const char *p_data);
-extern void godot_xhr_send_data(int p_xhr_id, const void *p_data, int p_len);
-extern void godot_xhr_abort(int p_xhr_id);
-
-/* this is an HTTPClient::ResponseCode, not ::Status */
-extern int godot_xhr_get_status(int p_xhr_id);
-extern godot_xhr_ready_state_t godot_xhr_get_ready_state(int p_xhr_id);
-
-extern int godot_xhr_get_response_headers_length(int p_xhr_id);
-extern void godot_xhr_get_response_headers(int p_xhr_id, char *r_dst, int p_len);
-
-extern int godot_xhr_get_response_length(int p_xhr_id);
-extern void godot_xhr_get_response(int p_xhr_id, void *r_dst, int p_len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HTTP_REQUEST_H */
diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp
index b203253a39..cb19dd20d4 100644
--- a/platform/javascript/javascript_eval.cpp
+++ b/platform/javascript/javascript_eval.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index b4985a4f36..0fe95b0a8f 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -87,7 +87,14 @@ extern EMSCRIPTEN_KEEPALIVE int godot_js_main(int argc, char *argv[]) {
ResourceLoader::set_abort_on_missing_resources(false);
Main::start();
- os->get_main_loop()->init();
+ os->get_main_loop()->initialize();
+#ifdef TOOLS_ENABLED
+ if (Main::is_project_manager() && FileAccess::exists("/tmp/preload.zip")) {
+ PackedStringArray ps;
+ ps.push_back("/tmp/preload.zip");
+ os->get_main_loop()->emit_signal("files_dropped", ps, -1);
+ }
+#endif
emscripten_set_main_loop(main_loop_callback, -1, false);
// Immediately run the first iteration.
// We are inside an animation frame, we want to immediately draw on the newly setup canvas.
diff --git a/platform/javascript/javascript_runtime.cpp b/platform/javascript/javascript_runtime.cpp
index bfe9fbd1bc..2996e95a95 100644
--- a/platform/javascript/javascript_runtime.cpp
+++ b/platform/javascript/javascript_runtime.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/dynlink.pre.js b/platform/javascript/js/dynlink.pre.js
deleted file mode 100644
index 34bc371ea9..0000000000
--- a/platform/javascript/js/dynlink.pre.js
+++ /dev/null
@@ -1 +0,0 @@
-Module['dynamicLibraries'] = [Module['thisProgram'] + '.side.wasm'].concat(Module['dynamicLibraries'] ? Module['dynamicLibraries'] : []);
diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js
new file mode 100644
index 0000000000..82ff273ecf
--- /dev/null
+++ b/platform/javascript/js/engine/config.js
@@ -0,0 +1,320 @@
+/**
+ * An object used to configure the Engine instance based on godot export options, and to override those in custom HTML
+ * templates if needed.
+ *
+ * @header Engine configuration
+ * @summary The Engine configuration object. This is just a typedef, create it like a regular object, e.g.:
+ *
+ * ``const MyConfig = { executable: 'godot', unloadAfterInit: false }``
+ *
+ * @typedef {Object} EngineConfig
+ */
+const EngineConfig = {}; // eslint-disable-line no-unused-vars
+
+/**
+ * @struct
+ * @constructor
+ * @ignore
+ */
+const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-vars
+ const cfg = /** @lends {InternalConfig.prototype} */ {
+ /**
+ * Whether the unload the engine automatically after the instance is initialized.
+ *
+ * @memberof EngineConfig
+ * @default
+ * @type {boolean}
+ */
+ unloadAfterInit: true,
+ /**
+ * The HTML DOM Canvas object to use.
+ *
+ * By default, the first canvas element in the document will be used is none is specified.
+ *
+ * @memberof EngineConfig
+ * @default
+ * @type {?HTMLCanvasElement}
+ */
+ canvas: null,
+ /**
+ * The name of the WASM file without the extension. (Set by Godot Editor export process).
+ *
+ * @memberof EngineConfig
+ * @default
+ * @type {string}
+ */
+ executable: '',
+ /**
+ * An alternative name for the game pck to load. The executable name is used otherwise.
+ *
+ * @memberof EngineConfig
+ * @default
+ * @type {?string}
+ */
+ mainPack: null,
+ /**
+ * Specify a language code to select the proper localization for the game.
+ *
+ * The browser locale will be used if none is specified. See complete list of
+ * :ref:`supported locales <doc_locales>`.
+ *
+ * @memberof EngineConfig
+ * @type {?string}
+ * @default
+ */
+ locale: null,
+ /**
+ * The canvas resize policy determines how the canvas should be resized by Godot.
+ *
+ * ``0`` means Godot won't do any resizing. This is useful if you want to control the canvas size from
+ * javascript code in your template.
+ *
+ * ``1`` means Godot will resize the canvas on start, and when changing window size via engine functions.
+ *
+ * ``2`` means Godot will adapt the canvas size to match the whole browser window.
+ *
+ * @memberof EngineConfig
+ * @type {number}
+ * @default
+ */
+ canvasResizePolicy: 2,
+ /**
+ * The arguments to be passed as command line arguments on startup.
+ *
+ * See :ref:`command line tutorial <doc_command_line_tutorial>`.
+ *
+ * **Note**: :js:meth:`startGame <Engine.prototype.startGame>` will always add the ``--main-pack`` argument.
+ *
+ * @memberof EngineConfig
+ * @type {Array<string>}
+ * @default
+ */
+ args: [],
+ /**
+ * @ignore
+ * @type {Array.<string>}
+ */
+ persistentPaths: ['/userfs'],
+ /**
+ * @ignore
+ * @type {Array.<string>}
+ */
+ gdnativeLibs: [],
+ /**
+ * @ignore
+ * @type {Array.<string>}
+ */
+ fileSizes: [],
+ /**
+ * A callback function for handling Godot's ``OS.execute`` calls.
+ *
+ * This is for example used in the Web Editor template to switch between project manager and editor, and for running the game.
+ *
+ * @callback EngineConfig.onExecute
+ * @param {string} path The path that Godot's wants executed.
+ * @param {Array.<string>} args The arguments of the "command" to execute.
+ */
+ /**
+ * @ignore
+ * @type {?function(string, Array.<string>)}
+ */
+ onExecute: null,
+ /**
+ * A callback function for being notified when the Godot instance quits.
+ *
+ * **Note**: This function will not be called if the engine crashes or become unresponsive.
+ *
+ * @callback EngineConfig.onExit
+ * @param {number} status_code The status code returned by Godot on exit.
+ */
+ /**
+ * @ignore
+ * @type {?function(number)}
+ */
+ onExit: null,
+ /**
+ * A callback function for displaying download progress.
+ *
+ * The function is called once per frame while downloading files, so the usage of ``requestAnimationFrame()``
+ * is not necessary.
+ *
+ * If the callback function receives a total amount of bytes as 0, this means that it is impossible to calculate.
+ * Possible reasons include:
+ *
+ * - Files are delivered with server-side chunked compression
+ * - Files are delivered with server-side compression on Chromium
+ * - Not all file downloads have started yet (usually on servers without multi-threading)
+ *
+ * @callback EngineConfig.onProgress
+ * @param {number} current The current amount of downloaded bytes so far.
+ * @param {number} total The total amount of bytes to be downloaded.
+ */
+ /**
+ * @ignore
+ * @type {?function(number, number)}
+ */
+ onProgress: null,
+ /**
+ * A callback function for handling the standard output stream. This method should usually only be used in debug pages.
+ *
+ * By default, ``console.log()`` is used.
+ *
+ * @callback EngineConfig.onPrint
+ * @param {...*} [var_args] A variadic number of arguments to be printed.
+ */
+ /**
+ * @ignore
+ * @type {?function(...*)}
+ */
+ onPrint: function () {
+ console.log.apply(console, Array.from(arguments)); // eslint-disable-line no-console
+ },
+ /**
+ * A callback function for handling the standard error stream. This method should usually only be used in debug pages.
+ *
+ * By default, ``console.error()`` is used.
+ *
+ * @callback EngineConfig.onPrintError
+ * @param {...*} [var_args] A variadic number of arguments to be printed as errors.
+ */
+ /**
+ * @ignore
+ * @type {?function(...*)}
+ */
+ onPrintError: function (var_args) {
+ console.error.apply(console, Array.from(arguments)); // eslint-disable-line no-console
+ },
+ };
+
+ /**
+ * @ignore
+ * @struct
+ * @constructor
+ * @param {EngineConfig} opts
+ */
+ function Config(opts) {
+ this.update(opts);
+ }
+
+ Config.prototype = cfg;
+
+ /**
+ * @ignore
+ * @param {EngineConfig} opts
+ */
+ Config.prototype.update = function (opts) {
+ const config = opts || {};
+ function parse(key, def) {
+ if (typeof (config[key]) === 'undefined') {
+ return def;
+ }
+ return config[key];
+ }
+ // Module config
+ this.unloadAfterInit = parse('unloadAfterInit', this.unloadAfterInit);
+ this.onPrintError = parse('onPrintError', this.onPrintError);
+ this.onPrint = parse('onPrint', this.onPrint);
+ this.onProgress = parse('onProgress', this.onProgress);
+
+ // Godot config
+ this.canvas = parse('canvas', this.canvas);
+ this.executable = parse('executable', this.executable);
+ this.mainPack = parse('mainPack', this.mainPack);
+ this.locale = parse('locale', this.locale);
+ this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy);
+ this.persistentPaths = parse('persistentPaths', this.persistentPaths);
+ this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs);
+ this.fileSizes = parse('fileSizes', this.fileSizes);
+ this.args = parse('args', this.args);
+ this.onExecute = parse('onExecute', this.onExecute);
+ this.onExit = parse('onExit', this.onExit);
+ };
+
+ /**
+ * @ignore
+ * @param {string} loadPath
+ * @param {Response} response
+ */
+ Config.prototype.getModuleConfig = function (loadPath, response) {
+ let r = response;
+ return {
+ 'print': this.onPrint,
+ 'printErr': this.onPrintError,
+ 'thisProgram': this.executable,
+ 'noExitRuntime': true,
+ 'dynamicLibraries': [`${loadPath}.side.wasm`],
+ 'instantiateWasm': function (imports, onSuccess) {
+ function done(result) {
+ onSuccess(result['instance'], result['module']);
+ }
+ if (typeof (WebAssembly.instantiateStreaming) !== 'undefined') {
+ WebAssembly.instantiateStreaming(Promise.resolve(r), imports).then(done);
+ } else {
+ r.arrayBuffer().then(function (buffer) {
+ WebAssembly.instantiate(buffer, imports).then(done);
+ });
+ }
+ r = null;
+ return {};
+ },
+ 'locateFile': function (path) {
+ if (path.endsWith('.worker.js')) {
+ return `${loadPath}.worker.js`;
+ } else if (path.endsWith('.audio.worklet.js')) {
+ return `${loadPath}.audio.worklet.js`;
+ } else if (path.endsWith('.js')) {
+ return `${loadPath}.js`;
+ } else if (path.endsWith('.side.wasm')) {
+ return `${loadPath}.side.wasm`;
+ } else if (path.endsWith('.wasm')) {
+ return `${loadPath}.wasm`;
+ }
+ return path;
+ },
+ };
+ };
+
+ /**
+ * @ignore
+ * @param {function()} cleanup
+ */
+ Config.prototype.getGodotConfig = function (cleanup) {
+ // Try to find a canvas
+ if (!(this.canvas instanceof HTMLCanvasElement)) {
+ const nodes = document.getElementsByTagName('canvas');
+ if (nodes.length && nodes[0] instanceof HTMLCanvasElement) {
+ this.canvas = nodes[0];
+ }
+ if (!this.canvas) {
+ throw new Error('No canvas found in page');
+ }
+ }
+ // Canvas can grab focus on click, or key events won't work.
+ if (this.canvas.tabIndex < 0) {
+ this.canvas.tabIndex = 0;
+ }
+
+ // Browser locale, or custom one if defined.
+ let locale = this.locale;
+ if (!locale) {
+ locale = navigator.languages ? navigator.languages[0] : navigator.language;
+ locale = locale.split('.')[0];
+ }
+ const onExit = this.onExit;
+
+ // Godot configuration.
+ return {
+ 'canvas': this.canvas,
+ 'canvasResizePolicy': this.canvasResizePolicy,
+ 'locale': locale,
+ 'onExecute': this.onExecute,
+ 'onExit': function (p_code) {
+ cleanup(); // We always need to call the cleanup callback to free memory.
+ if (typeof (onExit) === 'function') {
+ onExit(p_code);
+ }
+ },
+ };
+ };
+ return new Config(initConfig);
+};
diff --git a/platform/javascript/js/engine/engine.externs.js b/platform/javascript/js/engine/engine.externs.js
index 1a94dd15ec..35a66a93ae 100644
--- a/platform/javascript/js/engine/engine.externs.js
+++ b/platform/javascript/js/engine/engine.externs.js
@@ -1,3 +1,4 @@
var Godot;
var WebAssembly = {};
WebAssembly.instantiate = function(buffer, imports) {};
+WebAssembly.instantiateStreaming = function(response, imports) {};
diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js
index 4b8a7dde69..19a0552c8c 100644
--- a/platform/javascript/js/engine/engine.js
+++ b/platform/javascript/js/engine/engine.js
@@ -1,291 +1,273 @@
+/**
+ * Projects exported for the Web expose the :js:class:`Engine` class to the JavaScript environment, that allows
+ * fine control over the engine's start-up process.
+ *
+ * This API is built in an asynchronous manner and requires basic understanding
+ * of `Promises <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises>`__.
+ *
+ * @module Engine
+ * @header HTML5 shell class reference
+ */
const Engine = (function () {
const preloader = new Preloader();
- let wasmExt = '.wasm';
- let unloadAfterInit = true;
- let loadPath = '';
let loadPromise = null;
+ let loadPath = '';
let initPromise = null;
- let stderr = null;
- let stdout = null;
- let progressFunc = null;
- function load(basePath) {
+ /**
+ * @classdesc The ``Engine`` class provides methods for loading and starting exported projects on the Web. For default export
+ * settings, this is already part of the exported HTML page. To understand practical use of the ``Engine`` class,
+ * see :ref:`Custom HTML page for Web export <doc_customizing_html5_shell>`.
+ *
+ * @description Create a new Engine instance with the given configuration.
+ *
+ * @global
+ * @constructor
+ * @param {EngineConfig} initConfig The initial config for this instance.
+ */
+ function Engine(initConfig) { // eslint-disable-line no-shadow
+ this.config = new InternalConfig(initConfig);
+ this.rtenv = null;
+ }
+
+ /**
+ * Load the engine from the specified base path.
+ *
+ * @param {string} basePath Base path of the engine to load.
+ * @param {number=} [size=0] The file size if known.
+ * @returns {Promise} A Promise that resolves once the engine is loaded.
+ *
+ * @function Engine.load
+ */
+ Engine.load = function (basePath, size) {
if (loadPromise == null) {
loadPath = basePath;
- loadPromise = preloader.loadPromise(basePath + wasmExt);
- preloader.setProgressFunc(progressFunc);
+ loadPromise = preloader.loadPromise(`${loadPath}.wasm`, size, true);
requestAnimationFrame(preloader.animateProgress);
}
return loadPromise;
- }
+ };
- function unload() {
+ /**
+ * Unload the engine to free memory.
+ *
+ * This method will be called automatically depending on the configuration. See :js:attr:`unloadAfterInit`.
+ *
+ * @function Engine.unload
+ */
+ Engine.unload = function () {
loadPromise = null;
- }
-
- /** @constructor */
- function Engine() { // eslint-disable-line no-shadow
- this.canvas = null;
- this.executableName = '';
- this.rtenv = null;
- this.customLocale = null;
- this.resizeCanvasOnStart = false;
- this.onExecute = null;
- this.onExit = null;
- this.persistentPaths = ['/userfs'];
- this.gdnativeLibs = [];
- }
-
- Engine.prototype.init = /** @param {string=} basePath */ function (basePath) {
- if (initPromise) {
- return initPromise;
- }
- if (loadPromise == null) {
- if (!basePath) {
- initPromise = Promise.reject(new Error('A base path must be provided when calling `init` and the engine is not loaded.'));
- return initPromise;
- }
- load(basePath);
- }
- let config = {};
- if (typeof stdout === 'function') {
- config.print = stdout;
- }
- if (typeof stderr === 'function') {
- config.printErr = stderr;
- }
- const me = this;
- initPromise = new Promise(function (resolve, reject) {
- config['locateFile'] = Utils.createLocateRewrite(loadPath);
- config['instantiateWasm'] = Utils.createInstantiatePromise(loadPromise);
- // Emscripten configuration.
- config['thisProgram'] = me.executableName;
- config['noExitRuntime'] = true;
- config['dynamicLibraries'] = me.gdnativeLibs;
- Godot(config).then(function (module) {
- module['initFS'](me.persistentPaths).then(function (fs_err) {
- me.rtenv = module;
- if (unloadAfterInit) {
- unload();
- }
- resolve();
- config = null;
- });
- });
- });
- return initPromise;
};
- /** @type {function(string, string):Object} */
- Engine.prototype.preloadFile = function (file, path) {
- return preloader.preload(file, path);
+ /**
+ * Check whether WebGL is available. Optionally, specify a particular version of WebGL to check for.
+ *
+ * @param {number=} [majorVersion=1] The major WebGL version to check for.
+ * @returns {boolean} If the given major version of WebGL is available.
+ * @function Engine.isWebGLAvailable
+ */
+ Engine.isWebGLAvailable = function (majorVersion = 1) {
+ try {
+ return !!document.createElement('canvas').getContext(['webgl', 'webgl2'][majorVersion - 1]);
+ } catch (e) { /* Not available */ }
+ return false;
};
- /** @type {function(...string):Object} */
- Engine.prototype.start = function () {
- // Start from arguments.
- const args = [];
- for (let i = 0; i < arguments.length; i++) {
- args.push(arguments[i]);
- }
- const me = this;
- return me.init().then(function () {
- if (!me.rtenv) {
- return Promise.reject(new Error('The engine must be initialized before it can be started'));
- }
-
- if (!(me.canvas instanceof HTMLCanvasElement)) {
- me.canvas = Utils.findCanvas();
- if (!me.canvas) {
- return Promise.reject(new Error('No canvas found in page'));
+ /**
+ * Safe Engine constructor, creates a new prototype for every new instance to avoid prototype pollution.
+ * @ignore
+ * @constructor
+ */
+ function SafeEngine(initConfig) {
+ const proto = /** @lends Engine.prototype */ {
+ /**
+ * Initialize the engine instance. Optionally, pass the base path to the engine to load it,
+ * if it hasn't been loaded yet. See :js:meth:`Engine.load`.
+ *
+ * @param {string=} basePath Base path of the engine to load.
+ * @return {Promise} A ``Promise`` that resolves once the engine is loaded and initialized.
+ */
+ init: function (basePath) {
+ if (initPromise) {
+ return initPromise;
}
- }
-
- // Canvas can grab focus on click, or key events won't work.
- if (me.canvas.tabIndex < 0) {
- me.canvas.tabIndex = 0;
- }
-
- // Disable right-click context menu.
- me.canvas.addEventListener('contextmenu', function (ev) {
- ev.preventDefault();
- }, false);
+ if (loadPromise == null) {
+ if (!basePath) {
+ initPromise = Promise.reject(new Error('A base path must be provided when calling `init` and the engine is not loaded.'));
+ return initPromise;
+ }
+ Engine.load(basePath, this.config.fileSizes[`${basePath}.wasm`]);
+ }
+ const me = this;
+ function doInit(promise) {
+ return promise.then(function (response) {
+ return Godot(me.config.getModuleConfig(loadPath, response.clone()));
+ }).then(function (module) {
+ const paths = me.config.persistentPaths;
+ return module['initFS'](paths).then(function (err) {
+ return Promise.resolve(module);
+ });
+ }).then(function (module) {
+ me.rtenv = module;
+ if (me.config.unloadAfterInit) {
+ Engine.unload();
+ }
+ return Promise.resolve();
+ });
+ }
+ preloader.setProgressFunc(this.config.onProgress);
+ initPromise = doInit(loadPromise);
+ return initPromise;
+ },
- // Until context restoration is implemented warn the user of context loss.
- me.canvas.addEventListener('webglcontextlost', function (ev) {
- alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert
- ev.preventDefault();
- }, false);
+ /**
+ * Load a file so it is available in the instance's file system once it runs. Must be called **before** starting the
+ * instance.
+ *
+ * If not provided, the ``path`` is derived from the URL of the loaded file.
+ *
+ * @param {string|ArrayBuffer} file The file to preload.
+ *
+ * If a ``string`` the file will be loaded from that path.
+ *
+ * If an ``ArrayBuffer`` or a view on one, the buffer will used as the content of the file.
+ *
+ * @param {string=} path Path by which the file will be accessible. Required, if ``file`` is not a string.
+ *
+ * @returns {Promise} A Promise that resolves once the file is loaded.
+ */
+ preloadFile: function (file, path) {
+ return preloader.preload(file, path, this.config.fileSizes[file]);
+ },
- // Browser locale, or custom one if defined.
- let locale = me.customLocale;
- if (!locale) {
- locale = navigator.languages ? navigator.languages[0] : navigator.language;
- locale = locale.split('.')[0];
- }
- // Godot configuration.
- me.rtenv['initConfig']({
- 'resizeCanvasOnStart': me.resizeCanvasOnStart,
- 'canvas': me.canvas,
- 'locale': locale,
- 'onExecute': function (p_args) {
- if (me.onExecute) {
- me.onExecute(p_args);
- return 0;
+ /**
+ * Start the engine instance using the given override configuration (if any).
+ * :js:meth:`startGame <Engine.prototype.startGame>` can be used in typical cases instead.
+ *
+ * This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init <Engine.prototype.init>`.
+ * The engine must be loaded beforehand.
+ *
+ * Fails if a canvas cannot be found on the page, or not specified in the configuration.
+ *
+ * @param {EngineConfig} override An optional configuration override.
+ * @return {Promise} Promise that resolves once the engine started.
+ */
+ start: function (override) {
+ this.config.update(override);
+ const me = this;
+ return me.init().then(function () {
+ if (!me.rtenv) {
+ return Promise.reject(new Error('The engine must be initialized before it can be started'));
}
- return 1;
- },
- 'onExit': function (p_code) {
- me.rtenv['deinitFS']();
- if (me.onExit) {
- me.onExit(p_code);
+
+ let config = {};
+ try {
+ config = me.config.getGodotConfig(function () {
+ me.rtenv = null;
+ });
+ } catch (e) {
+ return Promise.reject(e);
}
- me.rtenv = null;
- },
- });
+ // Godot configuration.
+ me.rtenv['initConfig'](config);
- return new Promise(function (resolve, reject) {
- preloader.preloadedFiles.forEach(function (file) {
- me.rtenv['copyToFS'](file.path, file.buffer);
+ // Preload GDNative libraries.
+ const libs = [];
+ me.config.gdnativeLibs.forEach(function (lib) {
+ libs.push(me.rtenv['loadDynamicLibrary'](lib, { 'loadAsync': true }));
+ });
+ return Promise.all(libs).then(function () {
+ return new Promise(function (resolve, reject) {
+ preloader.preloadedFiles.forEach(function (file) {
+ me.rtenv['copyToFS'](file.path, file.buffer);
+ });
+ preloader.preloadedFiles.length = 0; // Clear memory
+ me.rtenv['callMain'](me.config.args);
+ initPromise = null;
+ resolve();
+ });
+ });
});
- preloader.preloadedFiles.length = 0; // Clear memory
- me.rtenv['callMain'](args);
- initPromise = null;
- resolve();
- });
- });
- };
+ },
- Engine.prototype.startGame = function (execName, mainPack, extraArgs) {
- // Start and init with execName as loadPath if not inited.
- this.executableName = execName;
- const me = this;
- return Promise.all([
- this.init(execName),
- this.preloadFile(mainPack, mainPack),
- ]).then(function () {
- let args = ['--main-pack', mainPack];
- if (extraArgs) {
- args = args.concat(extraArgs);
- }
- return me.start.apply(me, args);
- });
- };
-
- Engine.prototype.setWebAssemblyFilenameExtension = function (override) {
- if (String(override).length === 0) {
- throw new Error('Invalid WebAssembly filename extension override');
- }
- wasmExt = String(override);
- };
-
- Engine.prototype.setUnloadAfterInit = function (enabled) {
- unloadAfterInit = enabled;
- };
-
- Engine.prototype.setCanvas = function (canvasElem) {
- this.canvas = canvasElem;
- };
-
- Engine.prototype.setCanvasResizedOnStart = function (enabled) {
- this.resizeCanvasOnStart = enabled;
- };
-
- Engine.prototype.setLocale = function (locale) {
- this.customLocale = locale;
- };
-
- Engine.prototype.setExecutableName = function (newName) {
- this.executableName = newName;
- };
-
- Engine.prototype.setProgressFunc = function (func) {
- progressFunc = func;
- };
+ /**
+ * Start the game instance using the given configuration override (if any).
+ *
+ * This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init <Engine.prototype.init>`.
+ *
+ * This will load the engine if it is not loaded, and preload the main pck.
+ *
+ * This method expects the initial config (or the override) to have both the :js:attr:`executable` and :js:attr:`mainPack`
+ * properties set (normally done by the editor during export).
+ *
+ * @param {EngineConfig} override An optional configuration override.
+ * @return {Promise} Promise that resolves once the game started.
+ */
+ startGame: function (override) {
+ this.config.update(override);
+ // Add main-pack argument.
+ const exe = this.config.executable;
+ const pack = this.config.mainPack || `${exe}.pck`;
+ this.config.args = ['--main-pack', pack].concat(this.config.args);
+ // Start and init with execName as loadPath if not inited.
+ const me = this;
+ return Promise.all([
+ this.init(exe),
+ this.preloadFile(pack, pack),
+ ]).then(function () {
+ return me.start.apply(me);
+ });
+ },
- Engine.prototype.setStdoutFunc = function (func) {
- const print = function (text) {
- let msg = text;
- if (arguments.length > 1) {
- msg = Array.prototype.slice.call(arguments).join(' ');
- }
- func(msg);
- };
- if (this.rtenv) {
- this.rtenv.print = print;
- }
- stdout = print;
- };
+ /**
+ * Create a file at the specified ``path`` with the passed as ``buffer`` in the instance's file system.
+ *
+ * @param {string} path The location where the file will be created.
+ * @param {ArrayBuffer} buffer The content of the file.
+ */
+ copyToFS: function (path, buffer) {
+ if (this.rtenv == null) {
+ throw new Error('Engine must be inited before copying files');
+ }
+ this.rtenv['copyToFS'](path, buffer);
+ },
- Engine.prototype.setStderrFunc = function (func) {
- const printErr = function (text) {
- let msg = text;
- if (arguments.length > 1) {
- msg = Array.prototype.slice.call(arguments).join(' ');
- }
- func(msg);
+ /**
+ * Request that the current instance quit.
+ *
+ * This is akin the user pressing the close button in the window manager, and will
+ * have no effect if the engine has crashed, or is stuck in a loop.
+ *
+ */
+ requestQuit: function () {
+ if (this.rtenv) {
+ this.rtenv['request_quit']();
+ }
+ },
};
- if (this.rtenv) {
- this.rtenv.printErr = printErr;
- }
- stderr = printErr;
- };
-
- Engine.prototype.setOnExecute = function (onExecute) {
- this.onExecute = onExecute;
- };
-
- Engine.prototype.setOnExit = function (onExit) {
- this.onExit = onExit;
- };
-
- Engine.prototype.copyToFS = function (path, buffer) {
- if (this.rtenv == null) {
- throw new Error('Engine must be inited before copying files');
- }
- this.rtenv['copyToFS'](path, buffer);
- };
-
- Engine.prototype.setPersistentPaths = function (persistentPaths) {
- this.persistentPaths = persistentPaths;
- };
- Engine.prototype.setGDNativeLibraries = function (gdnativeLibs) {
- this.gdnativeLibs = gdnativeLibs;
- };
+ Engine.prototype = proto;
+ // Closure compiler exported instance methods.
+ Engine.prototype['init'] = Engine.prototype.init;
+ Engine.prototype['preloadFile'] = Engine.prototype.preloadFile;
+ Engine.prototype['start'] = Engine.prototype.start;
+ Engine.prototype['startGame'] = Engine.prototype.startGame;
+ Engine.prototype['copyToFS'] = Engine.prototype.copyToFS;
+ Engine.prototype['requestQuit'] = Engine.prototype.requestQuit;
+ // Also expose static methods as instance methods
+ Engine.prototype['load'] = Engine.load;
+ Engine.prototype['unload'] = Engine.unload;
+ Engine.prototype['isWebGLAvailable'] = Engine.isWebGLAvailable;
+ return new Engine(initConfig);
+ }
- Engine.prototype.requestQuit = function () {
- if (this.rtenv) {
- this.rtenv['request_quit']();
- }
- };
+ // Closure compiler exported static methods.
+ SafeEngine['load'] = Engine.load;
+ SafeEngine['unload'] = Engine.unload;
+ SafeEngine['isWebGLAvailable'] = Engine.isWebGLAvailable;
- // Closure compiler exported engine methods.
- /** @export */
- Engine['isWebGLAvailable'] = Utils.isWebGLAvailable;
- Engine['load'] = load;
- Engine['unload'] = unload;
- Engine.prototype['init'] = Engine.prototype.init;
- Engine.prototype['preloadFile'] = Engine.prototype.preloadFile;
- Engine.prototype['start'] = Engine.prototype.start;
- Engine.prototype['startGame'] = Engine.prototype.startGame;
- Engine.prototype['setWebAssemblyFilenameExtension'] = Engine.prototype.setWebAssemblyFilenameExtension;
- Engine.prototype['setUnloadAfterInit'] = Engine.prototype.setUnloadAfterInit;
- Engine.prototype['setCanvas'] = Engine.prototype.setCanvas;
- Engine.prototype['setCanvasResizedOnStart'] = Engine.prototype.setCanvasResizedOnStart;
- Engine.prototype['setLocale'] = Engine.prototype.setLocale;
- Engine.prototype['setExecutableName'] = Engine.prototype.setExecutableName;
- Engine.prototype['setProgressFunc'] = Engine.prototype.setProgressFunc;
- Engine.prototype['setStdoutFunc'] = Engine.prototype.setStdoutFunc;
- Engine.prototype['setStderrFunc'] = Engine.prototype.setStderrFunc;
- Engine.prototype['setOnExecute'] = Engine.prototype.setOnExecute;
- Engine.prototype['setOnExit'] = Engine.prototype.setOnExit;
- Engine.prototype['copyToFS'] = Engine.prototype.copyToFS;
- Engine.prototype['setPersistentPaths'] = Engine.prototype.setPersistentPaths;
- Engine.prototype['setGDNativeLibraries'] = Engine.prototype.setGDNativeLibraries;
- Engine.prototype['requestQuit'] = Engine.prototype.requestQuit;
- return Engine;
+ return SafeEngine;
}());
if (typeof window !== 'undefined') {
window['Engine'] = Engine;
diff --git a/platform/javascript/js/engine/preloader.js b/platform/javascript/js/engine/preloader.js
index ec34fb93f2..3535fdb361 100644
--- a/platform/javascript/js/engine/preloader.js
+++ b/platform/javascript/js/engine/preloader.js
@@ -1,54 +1,79 @@
const Preloader = /** @constructor */ function () { // eslint-disable-line no-unused-vars
- const loadXHR = function (resolve, reject, file, tracker, attempts) {
- const xhr = new XMLHttpRequest();
+ function getTrackedResponse(response, load_status) {
+ let clen = 0;
+ let compressed = false;
+ response.headers.forEach(function (value, header) {
+ const h = header.toLowerCase().trim();
+ // We can't accurately compute compressed stream length.
+ if (h === 'content-encoding') {
+ compressed = true;
+ } else if (h === 'content-length') {
+ const length = parseInt(value, 10);
+ if (!Number.isNaN(length) && length > 0) {
+ clen = length;
+ }
+ }
+ });
+ if (!compressed && clen) {
+ load_status.total = clen;
+ }
+ function onloadprogress(reader, controller) {
+ return reader.read().then(function (result) {
+ if (load_status.done) {
+ return Promise.resolve();
+ }
+ if (result.value) {
+ controller.enqueue(result.value);
+ load_status.loaded += result.value.length;
+ }
+ if (!result.done) {
+ return onloadprogress(reader, controller);
+ }
+ load_status.done = true;
+ return Promise.resolve();
+ });
+ }
+ const reader = response.body.getReader();
+ return new Response(new ReadableStream({
+ start: function (controller) {
+ onloadprogress(reader, controller).then(function () {
+ controller.close();
+ });
+ },
+ }), { headers: response.headers });
+ }
+
+ function loadFetch(file, tracker, fileSize, raw) {
tracker[file] = {
- total: 0,
+ total: fileSize || 0,
loaded: 0,
- final: false,
+ done: false,
};
- xhr.onerror = function () {
+ return fetch(file).then(function (response) {
+ if (!response.ok) {
+ return Promise.reject(new Error(`Failed loading file '${file}'`));
+ }
+ const tr = getTrackedResponse(response, tracker[file]);
+ if (raw) {
+ return Promise.resolve(tr);
+ }
+ return tr.arrayBuffer();
+ });
+ }
+
+ function retry(func, attempts = 1) {
+ function onerror(err) {
if (attempts <= 1) {
- reject(new Error(`Failed loading file '${file}'`));
- } else {
+ return Promise.reject(err);
+ }
+ return new Promise(function (resolve, reject) {
setTimeout(function () {
- loadXHR(resolve, reject, file, tracker, attempts - 1);
+ retry(func, attempts - 1).then(resolve).catch(reject);
}, 1000);
- }
- };
- xhr.onabort = function () {
- tracker[file].final = true;
- reject(new Error(`Loading file '${file}' was aborted.`));
- };
- xhr.onloadstart = function (ev) {
- tracker[file].total = ev.total;
- tracker[file].loaded = ev.loaded;
- };
- xhr.onprogress = function (ev) {
- tracker[file].loaded = ev.loaded;
- tracker[file].total = ev.total;
- };
- xhr.onload = function () {
- if (xhr.status >= 400) {
- if (xhr.status < 500 || attempts <= 1) {
- reject(new Error(`Failed loading file '${file}': ${xhr.statusText}`));
- xhr.abort();
- } else {
- setTimeout(function () {
- loadXHR(resolve, reject, file, tracker, attempts - 1);
- }, 1000);
- }
- } else {
- tracker[file].final = true;
- resolve(xhr);
- }
- };
- // Make request.
- xhr.open('GET', file);
- if (!file.endsWith('.js')) {
- xhr.responseType = 'arraybuffer';
+ });
}
- xhr.send();
- };
+ return func().catch(onerror);
+ }
const DOWNLOAD_ATTEMPTS_MAX = 4;
const loadingFiles = {};
@@ -63,7 +88,7 @@ const Preloader = /** @constructor */ function () { // eslint-disable-line no-un
Object.keys(loadingFiles).forEach(function (file) {
const stat = loadingFiles[file];
- if (!stat.final) {
+ if (!stat.done) {
progressIsFinal = false;
}
if (!totalIsValid || stat.total === 0) {
@@ -92,21 +117,19 @@ const Preloader = /** @constructor */ function () { // eslint-disable-line no-un
progressFunc = callback;
};
- this.loadPromise = function (file) {
- return new Promise(function (resolve, reject) {
- loadXHR(resolve, reject, file, loadingFiles, DOWNLOAD_ATTEMPTS_MAX);
- });
+ this.loadPromise = function (file, fileSize, raw = false) {
+ return retry(loadFetch.bind(null, file, loadingFiles, fileSize, raw), DOWNLOAD_ATTEMPTS_MAX);
};
this.preloadedFiles = [];
- this.preload = function (pathOrBuffer, destPath) {
+ this.preload = function (pathOrBuffer, destPath, fileSize) {
let buffer = null;
if (typeof pathOrBuffer === 'string') {
const me = this;
- return this.loadPromise(pathOrBuffer).then(function (xhr) {
+ return this.loadPromise(pathOrBuffer, fileSize).then(function (buf) {
me.preloadedFiles.push({
path: destPath || pathOrBuffer,
- buffer: xhr.response,
+ buffer: buf,
});
return Promise.resolve();
});
diff --git a/platform/javascript/js/engine/utils.js b/platform/javascript/js/engine/utils.js
deleted file mode 100644
index 9273bbad42..0000000000
--- a/platform/javascript/js/engine/utils.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const Utils = { // eslint-disable-line no-unused-vars
-
- createLocateRewrite: function (execName) {
- function rw(path) {
- if (path.endsWith('.worker.js')) {
- return `${execName}.worker.js`;
- } else if (path.endsWith('.audio.worklet.js')) {
- return `${execName}.audio.worklet.js`;
- } else if (path.endsWith('.js')) {
- return `${execName}.js`;
- } else if (path.endsWith('.side.wasm')) {
- return `${execName}.side.wasm`;
- } else if (path.endsWith('.wasm')) {
- return `${execName}.wasm`;
- }
- return path;
- }
- return rw;
- },
-
- createInstantiatePromise: function (wasmLoader) {
- let loader = wasmLoader;
- function instantiateWasm(imports, onSuccess) {
- loader.then(function (xhr) {
- WebAssembly.instantiate(xhr.response, imports).then(function (result) {
- onSuccess(result['instance'], result['module']);
- });
- });
- loader = null;
- return {};
- }
-
- return instantiateWasm;
- },
-
- findCanvas: function () {
- const nodes = document.getElementsByTagName('canvas');
- if (nodes.length && nodes[0] instanceof HTMLCanvasElement) {
- return nodes[0];
- }
- return null;
- },
-
- isWebGLAvailable: function (majorVersion = 1) {
- let testContext = false;
- try {
- const testCanvas = document.createElement('canvas');
- if (majorVersion === 1) {
- testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl');
- } else if (majorVersion === 2) {
- testContext = testCanvas.getContext('webgl2') || testCanvas.getContext('experimental-webgl2');
- }
- } catch (e) {
- // Not available
- }
- return !!testContext;
- },
-};
diff --git a/platform/javascript/js/jsdoc2rst/publish.js b/platform/javascript/js/jsdoc2rst/publish.js
new file mode 100644
index 0000000000..ad9c0fbaaa
--- /dev/null
+++ b/platform/javascript/js/jsdoc2rst/publish.js
@@ -0,0 +1,354 @@
+/* eslint-disable strict */
+
+'use strict';
+
+const fs = require('fs');
+
+class JSDoclet {
+ constructor(doc) {
+ this.doc = doc;
+ this.description = doc['description'] || '';
+ this.name = doc['name'] || 'unknown';
+ this.longname = doc['longname'] || '';
+ this.types = [];
+ if (doc['type'] && doc['type']['names']) {
+ this.types = doc['type']['names'].slice();
+ }
+ this.type = this.types.length > 0 ? this.types.join('\\|') : '*';
+ this.variable = doc['variable'] || false;
+ this.kind = doc['kind'] || '';
+ this.memberof = doc['memberof'] || null;
+ this.scope = doc['scope'] || '';
+ this.members = [];
+ this.optional = doc['optional'] || false;
+ this.defaultvalue = doc['defaultvalue'];
+ this.summary = doc['summary'] || null;
+ this.classdesc = doc['classdesc'] || null;
+
+ // Parameters (functions)
+ this.params = [];
+ this.returns = doc['returns'] ? doc['returns'][0]['type']['names'][0] : 'void';
+ this.returns_desc = doc['returns'] ? doc['returns'][0]['description'] : null;
+
+ this.params = (doc['params'] || []).slice().map((p) => new JSDoclet(p));
+
+ // Custom tags
+ this.tags = doc['tags'] || [];
+ this.header = this.tags.filter((t) => t['title'] === 'header').map((t) => t['text']).pop() || null;
+ }
+
+ add_member(obj) {
+ this.members.push(obj);
+ }
+
+ is_static() {
+ return this.scope === 'static';
+ }
+
+ is_instance() {
+ return this.scope === 'instance';
+ }
+
+ is_object() {
+ return this.kind === 'Object' || (this.kind === 'typedef' && this.type === 'Object');
+ }
+
+ is_class() {
+ return this.kind === 'class';
+ }
+
+ is_function() {
+ return this.kind === 'function' || (this.kind === 'typedef' && this.type === 'function');
+ }
+
+ is_module() {
+ return this.kind === 'module';
+ }
+}
+
+function format_table(f, data, depth = 0) {
+ if (!data.length) {
+ return;
+ }
+
+ const column_sizes = new Array(data[0].length).fill(0);
+
+ data.forEach((row) => {
+ row.forEach((e, idx) => {
+ column_sizes[idx] = Math.max(e.length, column_sizes[idx]);
+ });
+ });
+
+ const indent = ' '.repeat(depth);
+ let sep = indent;
+ column_sizes.forEach((size) => {
+ sep += '+';
+ sep += '-'.repeat(size + 2);
+ });
+ sep += '+\n';
+ f.write(sep);
+
+ data.forEach((row) => {
+ let row_text = `${indent}|`;
+ row.forEach((entry, idx) => {
+ row_text += ` ${entry.padEnd(column_sizes[idx])} |`;
+ });
+ row_text += '\n';
+ f.write(row_text);
+ f.write(sep);
+ });
+
+ f.write('\n');
+}
+
+function make_header(header, sep) {
+ return `${header}\n${sep.repeat(header.length)}\n\n`;
+}
+
+function indent_multiline(text, depth) {
+ const indent = ' '.repeat(depth);
+ return text.split('\n').map((l) => (l === '' ? l : indent + l)).join('\n');
+}
+
+function make_rst_signature(obj, types = false, style = false) {
+ let out = '';
+ const fmt = style ? '*' : '';
+ obj.params.forEach((arg, idx) => {
+ if (idx > 0) {
+ if (arg.optional) {
+ out += ` ${fmt}[`;
+ }
+ out += ', ';
+ } else {
+ out += ' ';
+ if (arg.optional) {
+ out += `${fmt}[ `;
+ }
+ }
+ if (types) {
+ out += `${arg.type} `;
+ }
+ const variable = arg.variable ? '...' : '';
+ const defval = arg.defaultvalue !== undefined ? `=${arg.defaultvalue}` : '';
+ out += `${variable}${arg.name}${defval}`;
+ if (arg.optional) {
+ out += ` ]${fmt}`;
+ }
+ });
+ out += ' ';
+ return out;
+}
+
+function make_rst_param(f, obj, depth = 0) {
+ const indent = ' '.repeat(depth * 3);
+ f.write(indent);
+ f.write(`:param ${obj.type} ${obj.name}:\n`);
+ f.write(indent_multiline(obj.description, (depth + 1) * 3));
+ f.write('\n\n');
+}
+
+function make_rst_attribute(f, obj, depth = 0, brief = false) {
+ const indent = ' '.repeat(depth * 3);
+ f.write(indent);
+ f.write(`.. js:attribute:: ${obj.name}\n\n`);
+
+ if (brief) {
+ if (obj.summary) {
+ f.write(indent_multiline(obj.summary, (depth + 1) * 3));
+ }
+ f.write('\n\n');
+ return;
+ }
+
+ f.write(indent_multiline(obj.description, (depth + 1) * 3));
+ f.write('\n\n');
+
+ f.write(indent);
+ f.write(` :type: ${obj.type}\n\n`);
+
+ if (obj.defaultvalue !== undefined) {
+ let defval = obj.defaultvalue;
+ if (defval === '') {
+ defval = '""';
+ }
+ f.write(indent);
+ f.write(` :value: \`\`${defval}\`\`\n\n`);
+ }
+}
+
+function make_rst_function(f, obj, depth = 0) {
+ let prefix = '';
+ if (obj.is_instance()) {
+ prefix = 'prototype.';
+ }
+
+ const indent = ' '.repeat(depth * 3);
+ const sig = make_rst_signature(obj);
+ f.write(indent);
+ f.write(`.. js:function:: ${prefix}${obj.name}(${sig})\n`);
+ f.write('\n');
+
+ f.write(indent_multiline(obj.description, (depth + 1) * 3));
+ f.write('\n\n');
+
+ obj.params.forEach((param) => {
+ make_rst_param(f, param, depth + 1);
+ });
+
+ if (obj.returns !== 'void') {
+ f.write(indent);
+ f.write(' :return:\n');
+ f.write(indent_multiline(obj.returns_desc, (depth + 2) * 3));
+ f.write('\n\n');
+ f.write(indent);
+ f.write(` :rtype: ${obj.returns}\n\n`);
+ }
+}
+
+function make_rst_object(f, obj) {
+ let brief = false;
+ // Our custom header flag.
+ if (obj.header !== null) {
+ f.write(make_header(obj.header, '-'));
+ f.write(`${obj.description}\n\n`);
+ brief = true;
+ }
+
+ // Format members table and descriptions
+ const data = [['type', 'name']].concat(obj.members.map((m) => [m.type, `:js:attr:\`${m.name}\``]));
+
+ f.write(make_header('Properties', '^'));
+ format_table(f, data, 0);
+
+ make_rst_attribute(f, obj, 0, brief);
+
+ if (!obj.members.length) {
+ return;
+ }
+
+ f.write(' **Property Descriptions**\n\n');
+
+ // Properties first
+ obj.members.filter((m) => !m.is_function()).forEach((m) => {
+ make_rst_attribute(f, m, 1);
+ });
+
+ // Callbacks last
+ obj.members.filter((m) => m.is_function()).forEach((m) => {
+ make_rst_function(f, m, 1);
+ });
+}
+
+function make_rst_class(f, obj) {
+ const header = obj.header ? obj.header : obj.name;
+ f.write(make_header(header, '-'));
+
+ if (obj.classdesc) {
+ f.write(`${obj.classdesc}\n\n`);
+ }
+
+ const funcs = obj.members.filter((m) => m.is_function());
+ function make_data(m) {
+ const base = m.is_static() ? obj.name : `${obj.name}.prototype`;
+ const params = make_rst_signature(m, true, true);
+ const sig = `:js:attr:\`${m.name} <${base}.${m.name}>\` **(**${params}**)**`;
+ return [m.returns, sig];
+ }
+ const sfuncs = funcs.filter((m) => m.is_static());
+ const ifuncs = funcs.filter((m) => !m.is_static());
+
+ f.write(make_header('Static Methods', '^'));
+ format_table(f, sfuncs.map((m) => make_data(m)));
+
+ f.write(make_header('Instance Methods', '^'));
+ format_table(f, ifuncs.map((m) => make_data(m)));
+
+ const sig = make_rst_signature(obj);
+ f.write(`.. js:class:: ${obj.name}(${sig})\n\n`);
+ f.write(indent_multiline(obj.description, 3));
+ f.write('\n\n');
+
+ obj.params.forEach((p) => {
+ make_rst_param(f, p, 1);
+ });
+
+ f.write(' **Static Methods**\n\n');
+ sfuncs.forEach((m) => {
+ make_rst_function(f, m, 1);
+ });
+
+ f.write(' **Instance Methods**\n\n');
+ ifuncs.forEach((m) => {
+ make_rst_function(f, m, 1);
+ });
+}
+
+function make_rst_module(f, obj) {
+ const header = obj.header !== null ? obj.header : obj.name;
+ f.write(make_header(header, '='));
+ f.write(obj.description);
+ f.write('\n\n');
+}
+
+function write_base_object(f, obj) {
+ if (obj.is_object()) {
+ make_rst_object(f, obj);
+ } else if (obj.is_function()) {
+ make_rst_function(f, obj);
+ } else if (obj.is_class()) {
+ make_rst_class(f, obj);
+ } else if (obj.is_module()) {
+ make_rst_module(f, obj);
+ }
+}
+
+function generate(f, docs) {
+ const globs = [];
+ const SYMBOLS = {};
+ docs.filter((d) => !d.ignore && d.kind !== 'package').forEach((d) => {
+ SYMBOLS[d.name] = d;
+ if (d.memberof) {
+ const up = SYMBOLS[d.memberof];
+ if (up === undefined) {
+ console.log(d); // eslint-disable-line no-console
+ console.log(`Undefined symbol! ${d.memberof}`); // eslint-disable-line no-console
+ throw new Error('Undefined symbol!');
+ }
+ SYMBOLS[d.memberof].add_member(d);
+ } else {
+ globs.push(d);
+ }
+ });
+
+ f.write('.. _doc_html5_shell_classref:\n\n');
+ globs.forEach((obj) => write_base_object(f, obj));
+}
+
+/**
+ * Generate documentation output.
+ *
+ * @param {TAFFY} data - A TaffyDB collection representing
+ * all the symbols documented in your code.
+ * @param {object} opts - An object with options information.
+ */
+exports.publish = function (data, opts) {
+ const docs = data().get().filter((doc) => !doc.undocumented && !doc.ignore).map((doc) => new JSDoclet(doc));
+ const dest = opts.destination;
+ if (dest === 'dry-run') {
+ process.stdout.write('Dry run... ');
+ generate({
+ write: function () { /* noop */ },
+ }, docs);
+ process.stdout.write('Okay!\n');
+ return;
+ }
+ if (dest !== '' && !dest.endsWith('.rst')) {
+ throw new Error('Destination file must be either a ".rst" file, or an empty string (for printing to stdout)');
+ }
+ if (dest !== '') {
+ const f = fs.createWriteStream(dest);
+ generate(f, docs);
+ } else {
+ generate(process.stdout, docs);
+ }
+};
diff --git a/platform/javascript/js/libs/audio.worklet.js b/platform/javascript/js/libs/audio.worklet.js
index 414dc37097..6b3f80c6a9 100644
--- a/platform/javascript/js/libs/audio.worklet.js
+++ b/platform/javascript/js/libs/audio.worklet.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/libs/library_godot_audio.js b/platform/javascript/js/libs/library_godot_audio.js
index d01b8d887b..ac4055516c 100644
--- a/platform/javascript/js/libs/library_godot_audio.js
+++ b/platform/javascript/js/libs/library_godot_audio.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -238,6 +238,9 @@ const GodotAudioWorklet = {
close: function () {
return new Promise(function (resolve, reject) {
+ if (GodotAudioWorklet.promise === null) {
+ return;
+ }
GodotAudioWorklet.promise.then(function () {
GodotAudioWorklet.worklet.port.postMessage({
'cmd': 'stop',
@@ -247,7 +250,7 @@ const GodotAudioWorklet = {
GodotAudioWorklet.worklet = null;
GodotAudioWorklet.promise = null;
resolve();
- });
+ }).catch(function (err) { /* aborted? */ });
});
},
},
diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js
index 800d6f414f..519a50f2db 100644
--- a/platform/javascript/js/libs/library_godot_display.js
+++ b/platform/javascript/js/libs/library_godot_display.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -269,15 +269,272 @@ const GodotDisplayCursor = {
};
mergeInto(LibraryManager.library, GodotDisplayCursor);
+/*
+ * Display Gamepad API helper.
+ */
+const GodotDisplayGamepads = {
+ $GodotDisplayGamepads__deps: ['$GodotRuntime', '$GodotDisplayListeners'],
+ $GodotDisplayGamepads: {
+ samples: [],
+
+ get_pads: function () {
+ try {
+ // Will throw in iframe when permission is denied.
+ // Will throw/warn in the future for insecure contexts.
+ // See https://github.com/w3c/gamepad/pull/120
+ const pads = navigator.getGamepads();
+ if (pads) {
+ return pads;
+ }
+ return [];
+ } catch (e) {
+ return [];
+ }
+ },
+
+ get_samples: function () {
+ return GodotDisplayGamepads.samples;
+ },
+
+ get_sample: function (index) {
+ const samples = GodotDisplayGamepads.samples;
+ return index < samples.length ? samples[index] : null;
+ },
+
+ sample: function () {
+ const pads = GodotDisplayGamepads.get_pads();
+ const samples = [];
+ for (let i = 0; i < pads.length; i++) {
+ const pad = pads[i];
+ if (!pad) {
+ samples.push(null);
+ continue;
+ }
+ const s = {
+ standard: pad.mapping === 'standard',
+ buttons: [],
+ axes: [],
+ connected: pad.connected,
+ };
+ for (let b = 0; b < pad.buttons.length; b++) {
+ s.buttons.push(pad.buttons[b].value);
+ }
+ for (let a = 0; a < pad.axes.length; a++) {
+ s.axes.push(pad.axes[a]);
+ }
+ samples.push(s);
+ }
+ GodotDisplayGamepads.samples = samples;
+ },
+
+ init: function (onchange) {
+ GodotDisplayListeners.samples = [];
+ function add(pad) {
+ const guid = GodotDisplayGamepads.get_guid(pad);
+ const c_id = GodotRuntime.allocString(pad.id);
+ const c_guid = GodotRuntime.allocString(guid);
+ onchange(pad.index, 1, c_id, c_guid);
+ GodotRuntime.free(c_id);
+ GodotRuntime.free(c_guid);
+ }
+ const pads = GodotDisplayGamepads.get_pads();
+ for (let i = 0; i < pads.length; i++) {
+ // Might be reserved space.
+ if (pads[i]) {
+ add(pads[i]);
+ }
+ }
+ GodotDisplayListeners.add(window, 'gamepadconnected', function (evt) {
+ add(evt.gamepad);
+ }, false);
+ GodotDisplayListeners.add(window, 'gamepaddisconnected', function (evt) {
+ onchange(evt.gamepad.index, 0);
+ }, false);
+ },
+
+ get_guid: function (pad) {
+ if (pad.mapping) {
+ return pad.mapping;
+ }
+ const ua = navigator.userAgent;
+ let os = 'Unknown';
+ if (ua.indexOf('Android') >= 0) {
+ os = 'Android';
+ } else if (ua.indexOf('Linux') >= 0) {
+ os = 'Linux';
+ } else if (ua.indexOf('iPhone') >= 0) {
+ os = 'iOS';
+ } else if (ua.indexOf('Macintosh') >= 0) {
+ // Updated iPads will fall into this category.
+ os = 'MacOSX';
+ } else if (ua.indexOf('Windows') >= 0) {
+ os = 'Windows';
+ }
+
+ const id = pad.id;
+ // Chrom* style: NAME (Vendor: xxxx Product: xxxx)
+ const exp1 = /vendor: ([0-9a-f]{4}) product: ([0-9a-f]{4})/i;
+ // Firefox/Safari style (safari may remove leading zeores)
+ const exp2 = /^([0-9a-f]+)-([0-9a-f]+)-/i;
+ let vendor = '';
+ let product = '';
+ if (exp1.test(id)) {
+ const match = exp1.exec(id);
+ vendor = match[1].padStart(4, '0');
+ product = match[2].padStart(4, '0');
+ } else if (exp2.test(id)) {
+ const match = exp2.exec(id);
+ vendor = match[1].padStart(4, '0');
+ product = match[2].padStart(4, '0');
+ }
+ if (!vendor || !product) {
+ return `${os}Unknown`;
+ }
+ return os + vendor + product;
+ },
+ },
+};
+mergeInto(LibraryManager.library, GodotDisplayGamepads);
+
+const GodotDisplayScreen = {
+ $GodotDisplayScreen__deps: ['$GodotConfig', '$GodotOS', '$GL', 'emscripten_webgl_get_current_context'],
+ $GodotDisplayScreen: {
+ desired_size: [0, 0],
+ hidpi: true,
+ getPixelRatio: function () {
+ return GodotDisplayScreen.hidpi ? window.devicePixelRatio || 1 : 1;
+ },
+ isFullscreen: function () {
+ const elem = document.fullscreenElement || document.mozFullscreenElement
+ || document.webkitFullscreenElement || document.msFullscreenElement;
+ if (elem) {
+ return elem === GodotConfig.canvas;
+ }
+ // But maybe knowing the element is not supported.
+ return document.fullscreen || document.mozFullScreen
+ || document.webkitIsFullscreen;
+ },
+ hasFullscreen: function () {
+ return document.fullscreenEnabled || document.mozFullScreenEnabled
+ || document.webkitFullscreenEnabled;
+ },
+ requestFullscreen: function () {
+ if (!GodotDisplayScreen.hasFullscreen()) {
+ return 1;
+ }
+ const canvas = GodotConfig.canvas;
+ try {
+ const promise = (canvas.requestFullscreen || canvas.msRequestFullscreen
+ || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen
+ || canvas.webkitRequestFullscreen
+ ).call(canvas);
+ // Some browsers (Safari) return undefined.
+ // For the standard ones, we need to catch it.
+ if (promise) {
+ promise.catch(function () {
+ // nothing to do.
+ });
+ }
+ } catch (e) {
+ return 1;
+ }
+ return 0;
+ },
+ exitFullscreen: function () {
+ if (!GodotDisplayScreen.isFullscreen()) {
+ return 0;
+ }
+ try {
+ const promise = document.exitFullscreen();
+ if (promise) {
+ promise.catch(function () {
+ // nothing to do.
+ });
+ }
+ } catch (e) {
+ return 1;
+ }
+ return 0;
+ },
+ _updateGL: function () {
+ const gl_context_handle = _emscripten_webgl_get_current_context(); // eslint-disable-line no-undef
+ const gl = GL.getContext(gl_context_handle);
+ if (gl) {
+ GL.resizeOffscreenFramebuffer(gl);
+ }
+ },
+ updateSize: function () {
+ const isFullscreen = GodotDisplayScreen.isFullscreen();
+ const wantsFullWindow = GodotConfig.canvas_resize_policy === 2;
+ const noResize = GodotConfig.canvas_resize_policy === 0;
+ const wwidth = GodotDisplayScreen.desired_size[0];
+ const wheight = GodotDisplayScreen.desired_size[1];
+ const canvas = GodotConfig.canvas;
+ let width = wwidth;
+ let height = wheight;
+ if (noResize) {
+ // Don't resize canvas, just update GL if needed.
+ if (canvas.width !== width || canvas.height !== height) {
+ GodotDisplayScreen.desired_size = [canvas.width, canvas.height];
+ GodotDisplayScreen._updateGL();
+ return 1;
+ }
+ return 0;
+ }
+ const scale = GodotDisplayScreen.getPixelRatio();
+ if (isFullscreen || wantsFullWindow) {
+ // We need to match screen size.
+ width = window.innerWidth * scale;
+ height = window.innerHeight * scale;
+ }
+ const csw = `${width / scale}px`;
+ const csh = `${height / scale}px`;
+ if (canvas.style.width !== csw || canvas.style.height !== csh || canvas.width !== width || canvas.height !== height) {
+ // Size doesn't match.
+ // Resize canvas, set correct CSS pixel size, update GL.
+ canvas.width = width;
+ canvas.height = height;
+ canvas.style.width = csw;
+ canvas.style.height = csh;
+ GodotDisplayScreen._updateGL();
+ return 1;
+ }
+ return 0;
+ },
+ },
+};
+mergeInto(LibraryManager.library, GodotDisplayScreen);
+
/**
* Display server interface.
*
* Exposes all the functions needed by DisplayServer implementation.
*/
const GodotDisplay = {
- $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop'],
+ $GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop', '$GodotDisplayGamepads', '$GodotDisplayScreen'],
$GodotDisplay: {
window_icon: '',
+ findDPI: function () {
+ function testDPI(dpi) {
+ return window.matchMedia(`(max-resolution: ${dpi}dpi)`).matches;
+ }
+ function bisect(low, high, func) {
+ const mid = parseInt(((high - low) / 2) + low, 10);
+ if (high - low <= 1) {
+ return func(high) ? high : low;
+ }
+ if (func(mid)) {
+ return bisect(low, mid, func);
+ }
+ return bisect(mid, high, func);
+ }
+ try {
+ const dpi = bisect(0, 800, testDPI);
+ return dpi >= 96 ? dpi : 96;
+ } catch (e) {
+ return 96;
+ }
+ },
},
godot_js_display_is_swap_ok_cancel__sig: 'i',
@@ -295,9 +552,56 @@ const GodotDisplay = {
window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert
},
+ godot_js_display_screen_dpi_get__sig: 'i',
+ godot_js_display_screen_dpi_get: function () {
+ return GodotDisplay.findDPI();
+ },
+
godot_js_display_pixel_ratio_get__sig: 'f',
godot_js_display_pixel_ratio_get: function () {
- return window.devicePixelRatio || 1;
+ return GodotDisplayScreen.getPixelRatio();
+ },
+
+ godot_js_display_fullscreen_request__sig: 'i',
+ godot_js_display_fullscreen_request: function () {
+ return GodotDisplayScreen.requestFullscreen();
+ },
+
+ godot_js_display_fullscreen_exit__sig: 'i',
+ godot_js_display_fullscreen_exit: function () {
+ return GodotDisplayScreen.exitFullscreen();
+ },
+
+ godot_js_display_desired_size_set__sig: 'v',
+ godot_js_display_desired_size_set: function (width, height) {
+ GodotDisplayScreen.desired_size = [width, height];
+ GodotDisplayScreen.updateSize();
+ },
+
+ godot_js_display_size_update__sig: 'i',
+ godot_js_display_size_update: function () {
+ return GodotDisplayScreen.updateSize();
+ },
+
+ godot_js_display_screen_size_get__sig: 'vii',
+ godot_js_display_screen_size_get: function (width, height) {
+ const scale = GodotDisplayScreen.getPixelRatio();
+ GodotRuntime.setHeapValue(width, window.screen.width * scale, 'i32');
+ GodotRuntime.setHeapValue(height, window.screen.height * scale, 'i32');
+ },
+
+ godot_js_display_window_size_get: function (p_width, p_height) {
+ GodotRuntime.setHeapValue(p_width, GodotConfig.canvas.width, 'i32');
+ GodotRuntime.setHeapValue(p_height, GodotConfig.canvas.height, 'i32');
+ },
+
+ godot_js_display_compute_position: function (x, y, r_x, r_y) {
+ const canvas = GodotConfig.canvas;
+ const rect = canvas.getBoundingClientRect();
+ const rw = canvas.width / rect.width;
+ const rh = canvas.height / rect.height;
+ GodotRuntime.setHeapValue(r_x, (x - rect.x) * rw, 'i32');
+ GodotRuntime.setHeapValue(r_y, (y - rect.y) * rh, 'i32');
},
/*
@@ -313,13 +617,6 @@ const GodotDisplay = {
return document.activeElement === GodotConfig.canvas;
},
- godot_js_display_canvas_bounding_rect_position_get__sig: 'vii',
- godot_js_display_canvas_bounding_rect_position_get: function (r_x, r_y) {
- const brect = GodotConfig.canvas.getBoundingClientRect();
- GodotRuntime.setHeapValue(r_x, brect.x, 'i32');
- GodotRuntime.setHeapValue(r_y, brect.y, 'i32');
- },
-
/*
* Touchscreen
*/
@@ -363,15 +660,6 @@ const GodotDisplay = {
/*
* Window
*/
- godot_js_display_window_request_fullscreen__sig: 'v',
- godot_js_display_window_request_fullscreen: function () {
- const canvas = GodotConfig.canvas;
- (canvas.requestFullscreen || canvas.msRequestFullscreen
- || canvas.mozRequestFullScreen || canvas.mozRequestFullscreen
- || canvas.webkitRequestFullscreen
- ).call(canvas);
- },
-
godot_js_display_window_title_set__sig: 'vi',
godot_js_display_window_title_set: function (p_data) {
document.title = GodotRuntime.parseString(p_data);
@@ -387,7 +675,7 @@ const GodotDisplay = {
document.head.appendChild(link);
}
const old_icon = GodotDisplay.window_icon;
- const png = new Blob([GodotRuntime.heapCopy(HEAPU8, p_ptr, p_len)], { type: 'image/png' });
+ const png = new Blob([GodotRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { type: 'image/png' });
GodotDisplay.window_icon = URL.createObjectURL(png);
link.href = GodotDisplay.window_icon;
if (old_icon) {
@@ -427,7 +715,7 @@ const GodotDisplay = {
const shape = GodotRuntime.parseString(p_shape);
const old_shape = GodotDisplayCursor.cursors[shape];
if (p_len > 0) {
- const png = new Blob([GodotRuntime.heapCopy(HEAPU8, p_ptr, p_len)], { type: 'image/png' });
+ const png = new Blob([GodotRuntime.heapSlice(HEAPU8, p_ptr, p_len)], { type: 'image/png' });
const url = URL.createObjectURL(png);
GodotDisplayCursor.cursors[shape] = {
url: url,
@@ -491,6 +779,80 @@ const GodotDisplay = {
}, false);
GodotDisplayListeners.add(canvas, 'drop', GodotDisplayDragDrop.handler(dropFiles));
},
+
+ godot_js_display_setup_canvas__sig: 'viiii',
+ godot_js_display_setup_canvas: function (p_width, p_height, p_fullscreen, p_hidpi) {
+ const canvas = GodotConfig.canvas;
+ GodotDisplayListeners.add(canvas, 'contextmenu', function (ev) {
+ ev.preventDefault();
+ }, false);
+ GodotDisplayListeners.add(canvas, 'webglcontextlost', function (ev) {
+ alert('WebGL context lost, please reload the page'); // eslint-disable-line no-alert
+ ev.preventDefault();
+ }, false);
+ GodotDisplayScreen.hidpi = !!p_hidpi;
+ switch (GodotConfig.canvas_resize_policy) {
+ case 0: // None
+ GodotDisplayScreen.desired_size = [canvas.width, canvas.height];
+ break;
+ case 1: // Project
+ GodotDisplayScreen.desired_size = [p_width, p_height];
+ break;
+ default: // Full window
+ // Ensure we display in the right place, the size will be handled by updateSize
+ canvas.style.position = 'absolute';
+ canvas.style.top = 0;
+ canvas.style.left = 0;
+ break;
+ }
+ GodotDisplayScreen.updateSize();
+ if (p_fullscreen) {
+ GodotDisplayScreen.requestFullscreen();
+ }
+ },
+
+ /*
+ * Gamepads
+ */
+ godot_js_display_gamepad_cb__sig: 'vi',
+ godot_js_display_gamepad_cb: function (change_cb) {
+ const onchange = GodotRuntime.get_func(change_cb);
+ GodotDisplayGamepads.init(onchange);
+ },
+
+ godot_js_display_gamepad_sample_count__sig: 'i',
+ godot_js_display_gamepad_sample_count: function () {
+ return GodotDisplayGamepads.get_samples().length;
+ },
+
+ godot_js_display_gamepad_sample__sig: 'i',
+ godot_js_display_gamepad_sample: function () {
+ GodotDisplayGamepads.sample();
+ return 0;
+ },
+
+ godot_js_display_gamepad_sample_get__sig: 'iiiiiii',
+ godot_js_display_gamepad_sample_get: function (p_index, r_btns, r_btns_num, r_axes, r_axes_num, r_standard) {
+ const sample = GodotDisplayGamepads.get_sample(p_index);
+ if (!sample || !sample.connected) {
+ return 1;
+ }
+ const btns = sample.buttons;
+ const btns_len = btns.length < 16 ? btns.length : 16;
+ for (let i = 0; i < btns_len; i++) {
+ GodotRuntime.setHeapValue(r_btns + (i << 2), btns[i], 'float');
+ }
+ GodotRuntime.setHeapValue(r_btns_num, btns_len, 'i32');
+ const axes = sample.axes;
+ const axes_len = axes.length < 10 ? axes.length : 10;
+ for (let i = 0; i < axes_len; i++) {
+ GodotRuntime.setHeapValue(r_axes + (i << 2), axes[i], 'float');
+ }
+ GodotRuntime.setHeapValue(r_axes_num, axes_len, 'i32');
+ const is_standard = sample.standard ? 1 : 0;
+ GodotRuntime.setHeapValue(r_standard, is_standard, 'i32');
+ return 0;
+ },
};
autoAddDeps(GodotDisplay, '$GodotDisplay');
diff --git a/platform/javascript/js/libs/library_godot_editor_tools.js b/platform/javascript/js/libs/library_godot_editor_tools.js
index 12edc8e733..d7f1ad5ea1 100644
--- a/platform/javascript/js/libs/library_godot_editor_tools.js
+++ b/platform/javascript/js/libs/library_godot_editor_tools.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/libs/library_godot_eval.js b/platform/javascript/js/libs/library_godot_eval.js
index 1a2440dd24..9ab392b813 100644
--- a/platform/javascript/js/libs/library_godot_eval.js
+++ b/platform/javascript/js/libs/library_godot_eval.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/javascript/js/libs/library_godot_fetch.js b/platform/javascript/js/libs/library_godot_fetch.js
new file mode 100644
index 0000000000..4ae6a23593
--- /dev/null
+++ b/platform/javascript/js/libs/library_godot_fetch.js
@@ -0,0 +1,258 @@
+/*************************************************************************/
+/* library_godot_fetch.js */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+const GodotFetch = {
+ $GodotFetch__deps: ['$GodotRuntime'],
+ $GodotFetch: {
+
+ onread: function (id, result) {
+ const obj = IDHandler.get(id);
+ if (!obj) {
+ return;
+ }
+ if (result.value) {
+ obj.chunks.push(result.value);
+ }
+ obj.reading = false;
+ obj.done = result.done;
+ },
+
+ onresponse: function (id, response) {
+ const obj = IDHandler.get(id);
+ if (!obj) {
+ return;
+ }
+ let size = -1;
+ let compressed = false;
+ let chunked = false;
+ response.headers.forEach(function (value, header) {
+ const v = value.toLowerCase().trim();
+ const h = header.toLowerCase().trim();
+ if (h === 'content-encoding') {
+ compressed = true;
+ size = -1;
+ } else if (h === 'content-length') {
+ const len = Number.parseInt(value, 10);
+ if (!Number.isNaN(len) && !compressed) {
+ size = len;
+ }
+ } else if (h === 'transfer-encoding' && v === 'chunked') {
+ chunked = true;
+ }
+ });
+ obj.bodySize = size;
+ obj.status = response.status;
+ obj.response = response;
+ obj.reader = response.body.getReader();
+ obj.chunked = chunked;
+ },
+
+ onerror: function (id, err) {
+ GodotRuntime.error(err);
+ const obj = IDHandler.get(id);
+ if (!obj) {
+ return;
+ }
+ obj.error = err;
+ },
+
+ create: function (method, url, headers, body) {
+ const obj = {
+ request: null,
+ response: null,
+ reader: null,
+ error: null,
+ done: false,
+ reading: false,
+ status: 0,
+ chunks: [],
+ bodySize: -1,
+ };
+ const id = IDHandler.add(obj);
+ const init = {
+ method: method,
+ headers: headers,
+ body: body,
+ };
+ obj.request = fetch(url, init);
+ obj.request.then(GodotFetch.onresponse.bind(null, id)).catch(GodotFetch.onerror.bind(null, id));
+ return id;
+ },
+
+ free: function (id) {
+ const obj = IDHandler.get(id);
+ if (!obj) {
+ return;
+ }
+ IDHandler.remove(id);
+ if (!obj.request) {
+ return;
+ }
+ // Try to abort
+ obj.request.then(function (response) {
+ response.abort();
+ }).catch(function (e) { /* nothing to do */ });
+ },
+
+ read: function (id) {
+ const obj = IDHandler.get(id);
+ if (!obj) {
+ return;
+ }
+ if (obj.reader && !obj.reading) {
+ if (obj.done) {
+ obj.reader = null;
+ return;
+ }
+ obj.reading = true;
+ obj.reader.read().then(GodotFetch.onread.bind(null, id)).catch(GodotFetch.onerror.bind(null, id));
+ }
+ },
+ },
+
+ godot_js_fetch_create__sig: 'iii',
+ godot_js_fetch_create: function (p_method, p_url, p_headers, p_headers_size, p_body, p_body_size) {
+ const method = GodotRuntime.parseString(p_method);
+ const url = GodotRuntime.parseString(p_url);
+ const headers = GodotRuntime.parseStringArray(p_headers, p_headers_size);
+ const body = p_body_size ? GodotRuntime.heapSlice(HEAP8, p_body, p_body_size) : null;
+ return GodotFetch.create(method, url, headers.map(function (hv) {
+ const idx = hv.indexOf(':');
+ if (idx <= 0) {
+ return [];
+ }
+ return [
+ hv.slice(0, idx).trim(),
+ hv.slice(idx + 1).trim(),
+ ];
+ }).filter(function (v) {
+ return v.length === 2;
+ }), body);
+ },
+
+ godot_js_fetch_state_get__sig: 'ii',
+ godot_js_fetch_state_get: function (p_id) {
+ const obj = IDHandler.get(p_id);
+ if (!obj) {
+ return -1;
+ }
+ if (obj.error) {
+ return -1;
+ }
+ if (!obj.response) {
+ return 0;
+ }
+ if (obj.reader) {
+ return 1;
+ }
+ if (obj.done) {
+ return 2;
+ }
+ return -1;
+ },
+
+ godot_js_fetch_http_status_get__sig: 'ii',
+ godot_js_fetch_http_status_get: function (p_id) {
+ const obj = IDHandler.get(p_id);
+ if (!obj || !obj.response) {
+ return 0;
+ }
+ return obj.status;
+ },
+
+ godot_js_fetch_read_headers__sig: 'iii',
+ godot_js_fetch_read_headers: function (p_id, p_parse_cb, p_ref) {
+ const obj = IDHandler.get(p_id);
+ if (!obj || !obj.response) {
+ return 1;
+ }
+ const cb = GodotRuntime.get_func(p_parse_cb);
+ const arr = [];
+ obj.response.headers.forEach(function (v, h) {
+ arr.push(`${h}:${v}`);
+ });
+ const c_ptr = GodotRuntime.allocStringArray(arr);
+ cb(arr.length, c_ptr, p_ref);
+ GodotRuntime.freeStringArray(c_ptr, arr.length);
+ return 0;
+ },
+
+ godot_js_fetch_read_chunk__sig: 'ii',
+ godot_js_fetch_read_chunk: function (p_id, p_buf, p_buf_size) {
+ const obj = IDHandler.get(p_id);
+ if (!obj || !obj.response) {
+ return 0;
+ }
+ let to_read = p_buf_size;
+ const chunks = obj.chunks;
+ while (to_read && chunks.length) {
+ const chunk = obj.chunks[0];
+ if (chunk.length > to_read) {
+ GodotRuntime.heapCopy(HEAP8, chunk.slice(0, to_read), p_buf);
+ chunks[0] = chunk.slice(to_read);
+ to_read = 0;
+ } else {
+ GodotRuntime.heapCopy(HEAP8, chunk, p_buf);
+ to_read -= chunk.length;
+ chunks.pop();
+ }
+ }
+ if (!chunks.length) {
+ GodotFetch.read(p_id);
+ }
+ return p_buf_size - to_read;
+ },
+
+ godot_js_fetch_body_length_get__sig: 'ii',
+ godot_js_fetch_body_length_get: function (p_id) {
+ const obj = IDHandler.get(p_id);
+ if (!obj || !obj.response) {
+ return -1;
+ }
+ return obj.bodySize;
+ },
+
+ godot_js_fetch_is_chunked__sig: 'ii',
+ godot_js_fetch_is_chunked: function (p_id) {
+ const obj = IDHandler.get(p_id);
+ if (!obj || !obj.response) {
+ return -1;
+ }
+ return obj.chunked ? 1 : 0;
+ },
+
+ godot_js_fetch_free__sig: 'vi',
+ godot_js_fetch_free: function (id) {
+ GodotFetch.free(id);
+ },
+};
+
+autoAddDeps(GodotFetch, '$GodotFetch');
+mergeInto(LibraryManager.library, GodotFetch);
diff --git a/platform/javascript/js/libs/library_godot_http_request.js b/platform/javascript/js/libs/library_godot_http_request.js
deleted file mode 100644
index d4468bd5aa..0000000000
--- a/platform/javascript/js/libs/library_godot_http_request.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/*************************************************************************/
-/* http_request.js */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-const GodotHTTPRequest = {
- $GodotHTTPRequest__deps: ['$GodotRuntime'],
- $GodotHTTPRequest: {
- requests: [],
-
- getUnusedRequestId: function () {
- const idMax = GodotHTTPRequest.requests.length;
- for (let potentialId = 0; potentialId < idMax; ++potentialId) {
- if (GodotHTTPRequest.requests[potentialId] instanceof XMLHttpRequest) {
- continue;
- }
- return potentialId;
- }
- GodotHTTPRequest.requests.push(null);
- return idMax;
- },
-
- setupRequest: function (xhr) {
- xhr.responseType = 'arraybuffer';
- },
- },
-
- godot_xhr_new__sig: 'i',
- godot_xhr_new: function () {
- const newId = GodotHTTPRequest.getUnusedRequestId();
- GodotHTTPRequest.requests[newId] = new XMLHttpRequest();
- GodotHTTPRequest.setupRequest(GodotHTTPRequest.requests[newId]);
- return newId;
- },
-
- godot_xhr_reset__sig: 'vi',
- godot_xhr_reset: function (xhrId) {
- GodotHTTPRequest.requests[xhrId] = new XMLHttpRequest();
- GodotHTTPRequest.setupRequest(GodotHTTPRequest.requests[xhrId]);
- },
-
- godot_xhr_free__sig: 'vi',
- godot_xhr_free: function (xhrId) {
- GodotHTTPRequest.requests[xhrId].abort();
- GodotHTTPRequest.requests[xhrId] = null;
- },
-
- godot_xhr_open__sig: 'viiiii',
- godot_xhr_open: function (xhrId, method, url, p_user, p_password) {
- const user = p_user > 0 ? GodotRuntime.parseString(p_user) : null;
- const password = p_password > 0 ? GodotRuntime.parseString(p_password) : null;
- GodotHTTPRequest.requests[xhrId].open(GodotRuntime.parseString(method), GodotRuntime.parseString(url), true, user, password);
- },
-
- godot_xhr_set_request_header__sig: 'viii',
- godot_xhr_set_request_header: function (xhrId, header, value) {
- GodotHTTPRequest.requests[xhrId].setRequestHeader(GodotRuntime.parseString(header), GodotRuntime.parseString(value));
- },
-
- godot_xhr_send_null__sig: 'vi',
- godot_xhr_send_null: function (xhrId) {
- GodotHTTPRequest.requests[xhrId].send();
- },
-
- godot_xhr_send_string__sig: 'vii',
- godot_xhr_send_string: function (xhrId, strPtr) {
- if (!strPtr) {
- GodotRuntime.error('Failed to send string per XHR: null pointer');
- return;
- }
- GodotHTTPRequest.requests[xhrId].send(GodotRuntime.parseString(strPtr));
- },
-
- godot_xhr_send_data__sig: 'viii',
- godot_xhr_send_data: function (xhrId, ptr, len) {
- if (!ptr) {
- GodotRuntime.error('Failed to send data per XHR: null pointer');
- return;
- }
- if (len < 0) {
- GodotRuntime.error('Failed to send data per XHR: buffer length less than 0');
- return;
- }
- GodotHTTPRequest.requests[xhrId].send(HEAPU8.subarray(ptr, ptr + len));
- },
-
- godot_xhr_abort__sig: 'vi',
- godot_xhr_abort: function (xhrId) {
- GodotHTTPRequest.requests[xhrId].abort();
- },
-
- godot_xhr_get_status__sig: 'ii',
- godot_xhr_get_status: function (xhrId) {
- return GodotHTTPRequest.requests[xhrId].status;
- },
-
- godot_xhr_get_ready_state__sig: 'ii',
- godot_xhr_get_ready_state: function (xhrId) {
- return GodotHTTPRequest.requests[xhrId].readyState;
- },
-
- godot_xhr_get_response_headers_length__sig: 'ii',
- godot_xhr_get_response_headers_length: function (xhrId) {
- const headers = GodotHTTPRequest.requests[xhrId].getAllResponseHeaders();
- return headers === null ? 0 : GodotRuntime.strlen(headers);
- },
-
- godot_xhr_get_response_headers__sig: 'viii',
- godot_xhr_get_response_headers: function (xhrId, dst, len) {
- const str = GodotHTTPRequest.requests[xhrId].getAllResponseHeaders();
- if (str === null) {
- return;
- }
- GodotRuntime.stringToHeap(str, dst, len);
- },
-
- godot_xhr_get_response_length__sig: 'ii',
- godot_xhr_get_response_length: function (xhrId) {
- const body = GodotHTTPRequest.requests[xhrId].response;
- return body === null ? 0 : body.byteLength;
- },
-
- godot_xhr_get_response__sig: 'viii',
- godot_xhr_get_response: function (xhrId, dst, len) {
- let buf = GodotHTTPRequest.requests[xhrId].response;
- if (buf === null) {
- return;
- }
- buf = new Uint8Array(buf).subarray(0, len);
- HEAPU8.set(buf, dst);
- },
-};
-
-autoAddDeps(GodotHTTPRequest, '$GodotHTTPRequest');
-mergeInto(LibraryManager.library, GodotHTTPRequest);
diff --git a/platform/javascript/js/libs/library_godot_os.js b/platform/javascript/js/libs/library_godot_os.js
index 260cfbf97f..0f189b013c 100644
--- a/platform/javascript/js/libs/library_godot_os.js
+++ b/platform/javascript/js/libs/library_godot_os.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,21 +58,28 @@ const GodotConfig = {
$GodotConfig: {
canvas: null,
locale: 'en',
- resize_on_start: false,
+ canvas_resize_policy: 2, // Adaptive
on_execute: null,
+ on_exit: null,
init_config: function (p_opts) {
- GodotConfig.resize_on_start = !!p_opts['resizeCanvasOnStart'];
+ GodotConfig.canvas_resize_policy = p_opts['canvasResizePolicy'];
GodotConfig.canvas = p_opts['canvas'];
GodotConfig.locale = p_opts['locale'] || GodotConfig.locale;
GodotConfig.on_execute = p_opts['onExecute'];
- // This is called by emscripten, even if undocumented.
- Module['onExit'] = p_opts['onExit']; // eslint-disable-line no-undef
+ GodotConfig.on_exit = p_opts['onExit'];
},
locate_file: function (file) {
return Module['locateFile'](file); // eslint-disable-line no-undef
},
+ clear: function () {
+ GodotConfig.canvas = null;
+ GodotConfig.locale = 'en';
+ GodotConfig.canvas_resize_policy = 2;
+ GodotConfig.on_execute = null;
+ GodotConfig.on_exit = null;
+ },
},
godot_js_config_canvas_id_get__sig: 'vii',
@@ -84,11 +91,6 @@ const GodotConfig = {
godot_js_config_locale_get: function (p_ptr, p_ptr_max) {
GodotRuntime.stringToHeap(GodotConfig.locale, p_ptr, p_ptr_max);
},
-
- godot_js_config_is_resize_on_start__sig: 'i',
- godot_js_config_is_resize_on_start: function () {
- return GodotConfig.resize_on_start ? 1 : 0;
- },
};
autoAddDeps(GodotConfig, '$GodotConfig');
@@ -98,7 +100,6 @@ const GodotFS = {
$GodotFS__deps: ['$FS', '$IDBFS', '$GodotRuntime'],
$GodotFS__postset: [
'Module["initFS"] = GodotFS.init;',
- 'Module["deinitFS"] = GodotFS.deinit;',
'Module["copyToFS"] = GodotFS.copy_to_fs;',
].join(''),
$GodotFS: {
@@ -210,9 +211,10 @@ const GodotFS = {
mergeInto(LibraryManager.library, GodotFS);
const GodotOS = {
- $GodotOS__deps: ['$GodotFS', '$GodotRuntime'],
+ $GodotOS__deps: ['$GodotRuntime', '$GodotConfig', '$GodotFS'],
$GodotOS__postset: [
'Module["request_quit"] = function() { GodotOS.request_quit() };',
+ 'Module["onExit"] = GodotOS.cleanup;',
'GodotOS._fs_sync_promise = Promise.resolve();',
].join(''),
$GodotOS: {
@@ -224,6 +226,15 @@ const GodotOS = {
GodotOS._async_cbs.push(p_promise_cb);
},
+ cleanup: function (exit_code) {
+ const cb = GodotConfig.on_exit;
+ GodotFS.deinit();
+ GodotConfig.clear();
+ if (cb) {
+ cb(exit_code);
+ }
+ },
+
finish_async: function (callback) {
GodotOS._fs_sync_promise.then(function (err) {
const promises = [];
@@ -282,6 +293,11 @@ const GodotOS = {
godot_js_os_shell_open: function (p_uri) {
window.open(GodotRuntime.parseString(p_uri), '_blank');
},
+
+ godot_js_os_hw_concurrency_get__sig: 'i',
+ godot_js_os_hw_concurrency_get: function () {
+ return navigator.hardwareConcurrency || 1;
+ },
};
autoAddDeps(GodotOS, '$GodotOS');
diff --git a/platform/javascript/js/libs/library_godot_runtime.js b/platform/javascript/js/libs/library_godot_runtime.js
index 04f29ad681..3da1ed8f06 100644
--- a/platform/javascript/js/libs/library_godot_runtime.js
+++ b/platform/javascript/js/libs/library_godot_runtime.js
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -72,11 +72,16 @@ const GodotRuntime = {
return p_heap.subarray(p_ptr / bytes, p_ptr / bytes + p_len);
},
- heapCopy: function (p_heap, p_ptr, p_len) {
+ heapSlice: function (p_heap, p_ptr, p_len) {
const bytes = p_heap.BYTES_PER_ELEMENT;
return p_heap.slice(p_ptr / bytes, p_ptr / bytes + p_len);
},
+ heapCopy: function (p_dst, p_src, p_ptr) {
+ const bytes = p_src.BYTES_PER_ELEMENT;
+ return p_dst.set(p_src, p_ptr / bytes);
+ },
+
/*
* Strings
*/
@@ -84,6 +89,15 @@ const GodotRuntime = {
return UTF8ToString(p_ptr); // eslint-disable-line no-undef
},
+ parseStringArray: function (p_ptr, p_size) {
+ const strings = [];
+ const ptrs = GodotRuntime.heapSub(HEAP32, p_ptr, p_size); // TODO wasm64
+ ptrs.forEach(function (ptr) {
+ strings.push(GodotRuntime.parseString(ptr));
+ });
+ return strings;
+ },
+
strlen: function (p_str) {
return lengthBytesUTF8(p_str); // eslint-disable-line no-undef
},
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 8c976da58e..0b1650076c 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -106,14 +106,18 @@ void OS_JavaScript::finalize() {
// Miscellaneous
-Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+ return create_process(p_path, p_arguments);
+}
+
+Error OS_JavaScript::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) {
Array args;
for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
args.push_back(E->get());
}
String json_args = JSON::print(args);
int failed = godot_js_os_execute(json_args.utf8().get_data());
- ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() must be implemented in JavaScript via 'engine.setOnExecute' if required.");
+ ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() or create_process() must be implemented in JavaScript via 'engine.setOnExecute' if required.");
return OK;
}
@@ -125,6 +129,10 @@ int OS_JavaScript::get_process_id() const {
ERR_FAIL_V_MSG(0, "OS::get_process_id() is not available on the HTML5 platform.");
}
+int OS_JavaScript::get_processor_count() const {
+ return godot_js_os_hw_concurrency_get();
+}
+
bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
if (p_feature == "HTML5" || p_feature == "web") {
return true;
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 6682f8fd85..81bb9c5f3d 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -70,9 +70,11 @@ public:
MainLoop *get_main_loop() const override;
bool main_loop_iterate();
- Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
Error kill(const ProcessID &p_pid) override;
int get_process_id() const override;
+ int get_processor_count() const override;
String get_executable_path() const override;
Error shell_open(String p_uri) override;
diff --git a/platform/javascript/package-lock.json b/platform/javascript/package-lock.json
index 8e298a495e..b8c434b3dd 100644
--- a/platform/javascript/package-lock.json
+++ b/platform/javascript/package-lock.json
@@ -43,6 +43,12 @@
}
}
},
+ "@babel/parser": {
+ "version": "7.13.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.4.tgz",
+ "integrity": "sha512-uvoOulWHhI+0+1f9L4BoozY7U5cIkZ9PgJqvb041d6vypgUmtVPG4vmGm4pSggjl8BELzvHyUeJSUyEMY6b+qA==",
+ "dev": true
+ },
"@eslint/eslintrc": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz",
@@ -202,6 +208,12 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
+ "bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true
+ },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -218,6 +230,15 @@
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
+ "catharsis": {
+ "version": "0.8.11",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz",
+ "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
@@ -362,6 +383,12 @@
"ansi-colors": "^4.1.1"
}
},
+ "entities": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
+ "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
+ "dev": true
+ },
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -925,6 +952,51 @@
"esprima": "^4.0.0"
}
},
+ "js2xmlparser": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz",
+ "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==",
+ "dev": true,
+ "requires": {
+ "xmlcreate": "^2.0.3"
+ }
+ },
+ "jsdoc": {
+ "version": "3.6.6",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.6.tgz",
+ "integrity": "sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.9.4",
+ "bluebird": "^3.7.2",
+ "catharsis": "^0.8.11",
+ "escape-string-regexp": "^2.0.0",
+ "js2xmlparser": "^4.0.1",
+ "klaw": "^3.0.0",
+ "markdown-it": "^10.0.0",
+ "markdown-it-anchor": "^5.2.7",
+ "marked": "^0.8.2",
+ "mkdirp": "^1.0.4",
+ "requizzle": "^0.2.3",
+ "strip-json-comments": "^3.1.0",
+ "taffydb": "2.6.2",
+ "underscore": "~1.10.2"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ }
+ }
+ },
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -946,6 +1018,15 @@
"minimist": "^1.2.0"
}
},
+ "klaw": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+ "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -956,6 +1037,15 @@
"type-check": "~0.4.0"
}
},
+ "linkify-it": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
+ "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "dev": true,
+ "requires": {
+ "uc.micro": "^1.0.1"
+ }
+ },
"load-json-file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
@@ -984,6 +1074,37 @@
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
+ "markdown-it": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
+ "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "entities": "~2.0.0",
+ "linkify-it": "^2.0.0",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ }
+ },
+ "markdown-it-anchor": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz",
+ "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==",
+ "dev": true
+ },
+ "marked": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz",
+ "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==",
+ "dev": true
+ },
+ "mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+ "dev": true
+ },
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -1287,6 +1408,15 @@
"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
"dev": true
},
+ "requizzle": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
+ "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
"resolve": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
@@ -1513,6 +1643,12 @@
"string-width": "^3.0.0"
}
},
+ "taffydb": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+ "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
+ "dev": true
+ },
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -1546,6 +1682,18 @@
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
+ "uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true
+ },
+ "underscore": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
+ "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==",
+ "dev": true
+ },
"uri-js": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
@@ -1600,6 +1748,12 @@
"requires": {
"mkdirp": "^0.5.1"
}
+ },
+ "xmlcreate": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz",
+ "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==",
+ "dev": true
}
}
}
diff --git a/platform/javascript/package.json b/platform/javascript/package.json
index 630b584f5b..d9d272923e 100644
--- a/platform/javascript/package.json
+++ b/platform/javascript/package.json
@@ -5,20 +5,24 @@
"description": "Linting setup for Godot's HTML5 platform code",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "lint": "npm run lint:engine && npm run lint:libs && npm run lint:modules",
+ "docs": "jsdoc --template js/jsdoc2rst/ js/engine/engine.js js/engine/config.js --destination ''",
+ "lint": "npm run lint:engine && npm run lint:libs && npm run lint:modules && npm run lint:tools",
"lint:engine": "eslint \"js/engine/*.js\" --no-eslintrc -c .eslintrc.engine.js",
"lint:libs": "eslint \"js/libs/*.js\" --no-eslintrc -c .eslintrc.libs.js",
"lint:modules": "eslint \"../../modules/**/*.js\" --no-eslintrc -c .eslintrc.libs.js",
- "format": "npm run format:engine && npm run format:libs && npm run format:modules",
+ "lint:tools": "eslint \"js/jsdoc2rst/**/*.js\" --no-eslintrc -c .eslintrc.engine.js",
+ "format": "npm run format:engine && npm run format:libs && npm run format:modules && npm run format:tools",
"format:engine": "npm run lint:engine -- --fix",
"format:libs": "npm run lint:libs -- --fix",
- "format:modules": "npm run lint:modules -- --fix"
+ "format:modules": "npm run lint:modules -- --fix",
+ "format:tools": "npm run lint:tools -- --fix"
},
"author": "Godot Engine contributors",
"license": "MIT",
"devDependencies": {
"eslint": "^7.9.0",
"eslint-config-airbnb-base": "^14.2.0",
- "eslint-plugin-import": "^2.22.0"
+ "eslint-plugin-import": "^2.22.0",
+ "jsdoc": "^3.6.6"
}
}
diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h
index e2200376d3..65df34902e 100644
--- a/platform/javascript/platform_config.h
+++ b/platform/javascript/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub
index 6e43ffcedb..46714e9502 100644
--- a/platform/linuxbsd/SCsub
+++ b/platform/linuxbsd/SCsub
@@ -16,7 +16,10 @@ common_x11 = [
"key_mapping_x11.cpp",
]
+if "udev" in env and env["udev"]:
+ common_x11.append("libudev-so_wrap.c")
+
prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_x11)
-if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]:
+if env["debug_symbols"] and env["separate_debug_symbols"]:
env.AddPostAction(prog, run_in_subprocess(platform_linuxbsd_builders.make_debug_linuxbsd))
diff --git a/platform/linuxbsd/context_gl_x11.cpp b/platform/linuxbsd/context_gl_x11.cpp
index 71dc9602b3..1f92370ab7 100644
--- a/platform/linuxbsd/context_gl_x11.cpp
+++ b/platform/linuxbsd/context_gl_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/context_gl_x11.h b/platform/linuxbsd/context_gl_x11.h
index 7aed280c98..d089886f4d 100644
--- a/platform/linuxbsd/context_gl_x11.h
+++ b/platform/linuxbsd/context_gl_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp
index 36c304b7f9..ea0222cb19 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.cpp
+++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -104,7 +104,7 @@ static void handle_crash(int sig) {
// Try to get the file/line number using addr2line
int ret;
- Error err = OS::get_singleton()->execute(String("addr2line"), args, true, nullptr, &output, &ret);
+ Error err = OS::get_singleton()->execute(String("addr2line"), args, &output, &ret);
if (err == OK) {
output.erase(output.length() - 1, 1);
}
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.h b/platform/linuxbsd/crash_handler_linuxbsd.h
index 9bb03579bc..a3dae0cc22 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.h
+++ b/platform/linuxbsd/crash_handler_linuxbsd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index a819731328..09d185ae2b 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -64,15 +64,16 @@ def get_opts():
BoolVariable("use_llvm", "Use the LLVM compiler", False),
BoolVariable("use_lld", "Use the LLD linker", False),
BoolVariable("use_thinlto", "Use ThinLTO", False),
- BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False),
+ BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
BoolVariable("use_coverage", "Test Godot coverage", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False),
+ BoolVariable("use_msan", "Use LLVM/GCC compiler memory sanitizer (MSAN))", False),
BoolVariable("pulseaudio", "Detect and use PulseAudio", True),
- BoolVariable("udev", "Use udev for gamepad connection callbacks", False),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("udev", "Use udev for gamepad connection callbacks", True),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("touch", "Enable touch events", True),
BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False),
@@ -92,7 +93,7 @@ def configure(env):
else: # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "release_debug":
@@ -102,7 +103,7 @@ def configure(env):
env.Prepend(CCFLAGS=["-Os"])
env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
@@ -142,7 +143,7 @@ def configure(env):
env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
env.Append(LINKFLAGS=["-ftest-coverage", "-fprofile-arcs"])
- if env["use_ubsan"] or env["use_asan"] or env["use_lsan"] or env["use_tsan"]:
+ if env["use_ubsan"] or env["use_asan"] or env["use_lsan"] or env["use_tsan"] or env["use_msan"]:
env.extra_suffix += "s"
if env["use_ubsan"]:
@@ -161,6 +162,10 @@ def configure(env):
env.Append(CCFLAGS=["-fsanitize=thread"])
env.Append(LINKFLAGS=["-fsanitize=thread"])
+ if env["use_msan"]:
+ env.Append(CCFLAGS=["-fsanitize=memory"])
+ env.Append(LINKFLAGS=["-fsanitize=memory"])
+
if env["use_lto"]:
if not env["use_llvm"] and env.GetOption("num_jobs") > 1:
env.Append(CCFLAGS=["-flto"])
@@ -310,9 +315,8 @@ def configure(env):
if os.system("pkg-config --exists alsa") == 0: # 0 means found
print("Enabling ALSA")
+ env["alsa"] = True
env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"])
- # Don't parse --cflags, we don't need to add /usr/include/alsa to include path
- env.ParseConfig("pkg-config alsa --libs")
else:
print("ALSA libraries not found, disabling driver")
@@ -320,20 +324,20 @@ def configure(env):
if os.system("pkg-config --exists libpulse") == 0: # 0 means found
print("Enabling PulseAudio")
env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"])
- env.ParseConfig("pkg-config --cflags --libs libpulse")
+ env.ParseConfig("pkg-config --cflags libpulse")
else:
print("PulseAudio development libraries not found, disabling driver")
if platform.system() == "Linux":
env.Append(CPPDEFINES=["JOYDEV_ENABLED"])
-
if env["udev"]:
if os.system("pkg-config --exists libudev") == 0: # 0 means found
print("Enabling udev support")
env.Append(CPPDEFINES=["UDEV_ENABLED"])
- env.ParseConfig("pkg-config libudev --cflags --libs")
else:
print("libudev development libraries not found, disabling udev support")
+ else:
+ env["udev"] = False # Linux specific
# Linkflags below this line should typically stay the last ones
if not env["builtin_zlib"]:
@@ -390,4 +394,13 @@ def configure(env):
# Link those statically for portability
if env["use_static_cpp"]:
- env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"])
+ # Workaround for GH-31743, Ubuntu 18.04 i386 crashes when it's used.
+ # That doesn't make any sense but it's likely a Ubuntu bug?
+ if is64 or env["bits"] == "64":
+ env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"])
+ if env["use_llvm"]:
+ env["LINKCOM"] = env["LINKCOM"] + " -l:libatomic.a"
+
+ else:
+ if env["use_llvm"]:
+ env.Append(LIBS=["atomic"])
diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp
index 709523e836..da1c95a593 100644
--- a/platform/linuxbsd/detect_prime_x11.cpp
+++ b/platform/linuxbsd/detect_prime_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -61,6 +61,7 @@ struct vendor {
vendor vendormap[] = {
{ "Advanced Micro Devices, Inc.", 30 },
+ { "AMD", 30 },
{ "NVIDIA Corporation", 30 },
{ "X.Org", 30 },
{ "Intel Open Source Technology Center", 20 },
@@ -128,7 +129,7 @@ void create_context() {
int detect_prime() {
pid_t p;
- int priorities[2];
+ int priorities[2] = {};
String vendors[2];
String renderers[2];
diff --git a/platform/linuxbsd/detect_prime_x11.h b/platform/linuxbsd/detect_prime_x11.h
index 039bdee76b..0b548b849e 100644
--- a/platform/linuxbsd/detect_prime_x11.h
+++ b/platform/linuxbsd/detect_prime_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 7e58272208..3bc859e17d 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -191,7 +191,7 @@ void DisplayServerX11::alert(const String &p_alert, const String &p_title) {
}
if (program.length()) {
- OS::get_singleton()->execute(program, args, true);
+ OS::get_singleton()->execute(program, args);
} else {
print_line(p_alert);
}
@@ -622,7 +622,7 @@ String DisplayServerX11::_clipboard_get(Atom p_source, Window x11_window) const
if (utf8_atom != None) {
ret = _clipboard_get_impl(p_source, x11_window, utf8_atom);
}
- if (ret.empty()) {
+ if (ret.is_empty()) {
ret = _clipboard_get_impl(p_source, x11_window, XA_STRING);
}
return ret;
@@ -634,7 +634,7 @@ String DisplayServerX11::clipboard_get() const {
String ret;
ret = _clipboard_get(XInternAtom(x11_display, "CLIPBOARD", 0), windows[MAIN_WINDOW_ID].x11_window);
- if (ret.empty()) {
+ if (ret.is_empty()) {
ret = _clipboard_get(XA_PRIMARY, windows[MAIN_WINDOW_ID].x11_window);
}
@@ -727,9 +727,9 @@ Point2i DisplayServerX11::screen_get_position(int p_screen) const {
int count;
XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
- if (p_screen >= count) {
- return Point2i(0, 0);
- }
+
+ // Check if screen is valid
+ ERR_FAIL_INDEX_V(p_screen, count, Point2i(0, 0));
Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org);
@@ -758,9 +758,9 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
int count;
XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
- if (p_screen >= count) {
- return Rect2i(0, 0, 0, 0);
- }
+
+ // Check if screen is valid
+ ERR_FAIL_INDEX_V(p_screen, count, Rect2i(0, 0, 0, 0));
Rect2i rect = Rect2i(xsi[p_screen].x_org, xsi[p_screen].y_org, xsi[p_screen].width, xsi[p_screen].height);
XFree(xsi);
@@ -1041,11 +1041,13 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
- int count = get_screen_count();
- if (p_screen >= count) {
- return;
+ if (p_screen == SCREEN_OF_MAIN_WINDOW) {
+ p_screen = window_get_current_screen();
}
+ // Check if screen is valid
+ ERR_FAIL_INDEX(p_screen, get_screen_count());
+
if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN) {
Point2i position = screen_get_position(p_screen);
Size2i size = screen_get_size(p_screen);
@@ -2697,7 +2699,7 @@ bool DisplayServerX11::_wait_for_events() const {
}
void DisplayServerX11::_poll_events() {
- while (!events_thread_done) {
+ while (!events_thread_done.is_set()) {
_wait_for_events();
// Process events from the queue.
@@ -3360,7 +3362,7 @@ void DisplayServerX11::process_events() {
Vector<String> files = String((char *)p.data).split("\n", false);
for (int i = 0; i < files.size(); i++) {
- files.write[i] = files[i].replace("file://", "").http_unescape().strip_edges();
+ files.write[i] = files[i].replace("file://", "").uri_decode().strip_edges();
}
if (!windows[window_id].drop_files_callback.is_null()) {
@@ -4028,7 +4030,10 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
use_prime = 0;
}
- if (getenv("LD_LIBRARY_PATH")) {
+ // Some tools use fake libGL libraries and have them override the real one using
+ // LD_LIBRARY_PATH, so we skip them. *But* Steam also sets LD_LIBRARY_PATH for its
+ // runtime and includes system `/lib` and `/lib64`... so ignore Steam.
+ if (use_prime == -1 && getenv("LD_LIBRARY_PATH") && !getenv("STEAM_RUNTIME_LIBRARY_PATH")) {
String ld_library_path(getenv("LD_LIBRARY_PATH"));
Vector<String> libraries = ld_library_path.split(":");
@@ -4266,7 +4271,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
}
- events_thread = Thread::create(_poll_events_thread, this);
+ events_thread.start(_poll_events_thread, this);
_update_real_mouse_position(windows[MAIN_WINDOW_ID]);
@@ -4279,10 +4284,8 @@ DisplayServerX11::~DisplayServerX11() {
_clipboard_transfer_ownership(XA_PRIMARY, x11_main_window);
_clipboard_transfer_ownership(XInternAtom(x11_display, "CLIPBOARD", 0), x11_main_window);
- events_thread_done = true;
- Thread::wait_to_finish(events_thread);
- memdelete(events_thread);
- events_thread = nullptr;
+ events_thread_done.set();
+ events_thread.wait_to_finish();
//destroy all windows
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 6f437f3be9..10686d8424 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -252,8 +252,8 @@ class DisplayServerX11 : public DisplayServer {
void _dispatch_input_event(const Ref<InputEvent> &p_event);
mutable Mutex events_mutex;
- Thread *events_thread = nullptr;
- bool events_thread_done = false;
+ Thread events_thread;
+ SafeFlag events_thread_done;
LocalVector<XEvent> polled_events;
static void _poll_events_thread(void *ud);
bool _wait_for_events() const;
diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp
index 86ea95c563..cb95068314 100644
--- a/platform/linuxbsd/export/export.cpp
+++ b/platform/linuxbsd/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/export/export.h b/platform/linuxbsd/export/export.h
index 5ee81f485e..61e96aa2f6 100644
--- a/platform/linuxbsd/export/export.h
+++ b/platform/linuxbsd/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/godot_linuxbsd.cpp b/platform/linuxbsd/godot_linuxbsd.cpp
index e1796ccefe..6f5c46b59c 100644
--- a/platform/linuxbsd/godot_linuxbsd.cpp
+++ b/platform/linuxbsd/godot_linuxbsd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 0676587f7a..471259e50f 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,13 +32,14 @@
#include "joypad_linux.h"
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <unistd.h>
#ifdef UDEV_ENABLED
-#include <libudev.h>
+#include "libudev-so_wrap.h"
#endif
#define LONG_BITS (sizeof(long) * 8)
@@ -71,15 +72,28 @@ void JoypadLinux::Joypad::reset() {
}
JoypadLinux::JoypadLinux(Input *in) {
- exit_udev = false;
+#ifdef UDEV_ENABLED
+#ifdef DEBUG_ENABLED
+ int dylibloader_verbose = 1;
+#else
+ int dylibloader_verbose = 0;
+#endif
+ use_udev = initialize_libudev(dylibloader_verbose) == 0;
+ if (use_udev) {
+ print_verbose("JoypadLinux: udev enabled and loaded successfully.");
+ } else {
+ print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads.");
+ }
+#else
+ print_verbose("JoypadLinux: udev disabled, parsing /dev/input to detect joypads.");
+#endif
input = in;
- joy_thread = Thread::create(joy_thread_func, this);
+ joy_thread.start(joy_thread_func, this);
}
JoypadLinux::~JoypadLinux() {
- exit_udev = true;
- Thread::wait_to_finish(joy_thread);
- memdelete(joy_thread);
+ exit_monitor.set();
+ joy_thread.wait_to_finish();
close_joypad();
}
@@ -92,11 +106,20 @@ void JoypadLinux::joy_thread_func(void *p_user) {
void JoypadLinux::run_joypad_thread() {
#ifdef UDEV_ENABLED
- udev *_udev = udev_new();
- ERR_FAIL_COND(!_udev);
- enumerate_joypads(_udev);
- monitor_joypads(_udev);
- udev_unref(_udev);
+ if (use_udev) {
+ udev *_udev = udev_new();
+ if (!_udev) {
+ use_udev = false;
+ ERR_PRINT("Failed getting an udev context, falling back to parsing /dev/input.");
+ monitor_joypads();
+ } else {
+ enumerate_joypads(_udev);
+ monitor_joypads(_udev);
+ udev_unref(_udev);
+ }
+ } else {
+ monitor_joypads();
+ }
#else
monitor_joypads();
#endif
@@ -137,7 +160,7 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
udev_monitor_enable_receiving(mon);
int fd = udev_monitor_get_fd(mon);
- while (!exit_udev) {
+ while (!exit_monitor.is_set()) {
fd_set fds;
struct timeval tv;
int ret;
@@ -179,17 +202,27 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
#endif
void JoypadLinux::monitor_joypads() {
- while (!exit_udev) {
+ while (!exit_monitor.is_set()) {
{
MutexLock lock(joy_mutex);
- for (int i = 0; i < 32; i++) {
+ DIR *input_directory;
+ input_directory = opendir("/dev/input");
+ if (input_directory) {
+ struct dirent *current;
char fname[64];
- sprintf(fname, "/dev/input/event%d", i);
- if (attached_devices.find(fname) == -1) {
- open_joypad(fname);
+
+ while ((current = readdir(input_directory)) != NULL) {
+ if (strncmp(current->d_name, "event", 5) != 0) {
+ continue;
+ }
+ sprintf(fname, "/dev/input/%.*s", 16, current->d_name);
+ if (attached_devices.find(fname) == -1) {
+ open_joypad(fname);
+ }
}
}
+ closedir(input_directory);
}
usleep(1000000); // 1s
}
diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h
index 71eab78f99..b0d0db047b 100644
--- a/platform/linuxbsd/joypad_linux.h
+++ b/platform/linuxbsd/joypad_linux.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -70,10 +70,13 @@ private:
void reset();
};
- bool exit_udev;
+#ifdef UDEV_ENABLED
+ bool use_udev = false;
+#endif
+ SafeFlag exit_monitor;
Mutex joy_mutex;
- Thread *joy_thread;
- Input *input;
+ Thread joy_thread;
+ Input *input = nullptr;
Joypad joypads[JOYPADS_MAX];
Vector<String> attached_devices;
diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp
index 78049f2dfc..f9f612fa74 100644
--- a/platform/linuxbsd/key_mapping_x11.cpp
+++ b/platform/linuxbsd/key_mapping_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/key_mapping_x11.h b/platform/linuxbsd/key_mapping_x11.h
index 8f5e01a3c2..163a8e21db 100644
--- a/platform/linuxbsd/key_mapping_x11.h
+++ b/platform/linuxbsd/key_mapping_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/libudev-so_wrap.c b/platform/linuxbsd/libudev-so_wrap.c
new file mode 100644
index 0000000000..a9fa4a494a
--- /dev/null
+++ b/platform/linuxbsd/libudev-so_wrap.c
@@ -0,0 +1,1013 @@
+// This file is generated. Do not edit!
+// see https://github.com/hpvb/dynload-wrapper for details
+// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:59
+// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/libudev.h --sys-include <libudev.h> --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header libudev-so_wrap.h --output-implementation libudev-so_wrap.c
+//
+#include <stdint.h>
+
+#define udev_ref udev_ref_dylibloader_orig_libudev
+#define udev_unref udev_unref_dylibloader_orig_libudev
+#define udev_new udev_new_dylibloader_orig_libudev
+#define udev_set_log_fn udev_set_log_fn_dylibloader_orig_libudev
+#define udev_get_log_priority udev_get_log_priority_dylibloader_orig_libudev
+#define udev_set_log_priority udev_set_log_priority_dylibloader_orig_libudev
+#define udev_get_userdata udev_get_userdata_dylibloader_orig_libudev
+#define udev_set_userdata udev_set_userdata_dylibloader_orig_libudev
+#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_orig_libudev
+#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_orig_libudev
+#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_orig_libudev
+#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_orig_libudev
+#define udev_device_ref udev_device_ref_dylibloader_orig_libudev
+#define udev_device_unref udev_device_unref_dylibloader_orig_libudev
+#define udev_device_get_udev udev_device_get_udev_dylibloader_orig_libudev
+#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_orig_libudev
+#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_orig_libudev
+#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_orig_libudev
+#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_orig_libudev
+#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_orig_libudev
+#define udev_device_get_parent udev_device_get_parent_dylibloader_orig_libudev
+#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_orig_libudev
+#define udev_device_get_devpath udev_device_get_devpath_dylibloader_orig_libudev
+#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_orig_libudev
+#define udev_device_get_devtype udev_device_get_devtype_dylibloader_orig_libudev
+#define udev_device_get_syspath udev_device_get_syspath_dylibloader_orig_libudev
+#define udev_device_get_sysname udev_device_get_sysname_dylibloader_orig_libudev
+#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_orig_libudev
+#define udev_device_get_devnode udev_device_get_devnode_dylibloader_orig_libudev
+#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_orig_libudev
+#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_orig_libudev
+#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_orig_libudev
+#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_orig_libudev
+#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_orig_libudev
+#define udev_device_get_property_value udev_device_get_property_value_dylibloader_orig_libudev
+#define udev_device_get_driver udev_device_get_driver_dylibloader_orig_libudev
+#define udev_device_get_devnum udev_device_get_devnum_dylibloader_orig_libudev
+#define udev_device_get_action udev_device_get_action_dylibloader_orig_libudev
+#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_orig_libudev
+#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_orig_libudev
+#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_orig_libudev
+#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_orig_libudev
+#define udev_device_has_tag udev_device_has_tag_dylibloader_orig_libudev
+#define udev_monitor_ref udev_monitor_ref_dylibloader_orig_libudev
+#define udev_monitor_unref udev_monitor_unref_dylibloader_orig_libudev
+#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_orig_libudev
+#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_orig_libudev
+#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_orig_libudev
+#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_orig_libudev
+#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_orig_libudev
+#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_orig_libudev
+#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_orig_libudev
+#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_orig_libudev
+#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_orig_libudev
+#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_orig_libudev
+#define udev_enumerate_ref udev_enumerate_ref_dylibloader_orig_libudev
+#define udev_enumerate_unref udev_enumerate_unref_dylibloader_orig_libudev
+#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_orig_libudev
+#define udev_enumerate_new udev_enumerate_new_dylibloader_orig_libudev
+#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_orig_libudev
+#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_orig_libudev
+#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_orig_libudev
+#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_orig_libudev
+#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_orig_libudev
+#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_orig_libudev
+#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_orig_libudev
+#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_orig_libudev
+#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_orig_libudev
+#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_orig_libudev
+#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_orig_libudev
+#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_orig_libudev
+#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_orig_libudev
+#define udev_queue_ref udev_queue_ref_dylibloader_orig_libudev
+#define udev_queue_unref udev_queue_unref_dylibloader_orig_libudev
+#define udev_queue_get_udev udev_queue_get_udev_dylibloader_orig_libudev
+#define udev_queue_new udev_queue_new_dylibloader_orig_libudev
+#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_orig_libudev
+#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_orig_libudev
+#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_orig_libudev
+#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_orig_libudev
+#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_orig_libudev
+#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_orig_libudev
+#define udev_queue_get_fd udev_queue_get_fd_dylibloader_orig_libudev
+#define udev_queue_flush udev_queue_flush_dylibloader_orig_libudev
+#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_orig_libudev
+#define udev_hwdb_new udev_hwdb_new_dylibloader_orig_libudev
+#define udev_hwdb_ref udev_hwdb_ref_dylibloader_orig_libudev
+#define udev_hwdb_unref udev_hwdb_unref_dylibloader_orig_libudev
+#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_orig_libudev
+#define udev_util_encode_string udev_util_encode_string_dylibloader_orig_libudev
+#include <libudev.h>
+#undef udev_ref
+#undef udev_unref
+#undef udev_new
+#undef udev_set_log_fn
+#undef udev_get_log_priority
+#undef udev_set_log_priority
+#undef udev_get_userdata
+#undef udev_set_userdata
+#undef udev_list_entry_get_next
+#undef udev_list_entry_get_by_name
+#undef udev_list_entry_get_name
+#undef udev_list_entry_get_value
+#undef udev_device_ref
+#undef udev_device_unref
+#undef udev_device_get_udev
+#undef udev_device_new_from_syspath
+#undef udev_device_new_from_devnum
+#undef udev_device_new_from_subsystem_sysname
+#undef udev_device_new_from_device_id
+#undef udev_device_new_from_environment
+#undef udev_device_get_parent
+#undef udev_device_get_parent_with_subsystem_devtype
+#undef udev_device_get_devpath
+#undef udev_device_get_subsystem
+#undef udev_device_get_devtype
+#undef udev_device_get_syspath
+#undef udev_device_get_sysname
+#undef udev_device_get_sysnum
+#undef udev_device_get_devnode
+#undef udev_device_get_is_initialized
+#undef udev_device_get_devlinks_list_entry
+#undef udev_device_get_properties_list_entry
+#undef udev_device_get_tags_list_entry
+#undef udev_device_get_sysattr_list_entry
+#undef udev_device_get_property_value
+#undef udev_device_get_driver
+#undef udev_device_get_devnum
+#undef udev_device_get_action
+#undef udev_device_get_seqnum
+#undef udev_device_get_usec_since_initialized
+#undef udev_device_get_sysattr_value
+#undef udev_device_set_sysattr_value
+#undef udev_device_has_tag
+#undef udev_monitor_ref
+#undef udev_monitor_unref
+#undef udev_monitor_get_udev
+#undef udev_monitor_new_from_netlink
+#undef udev_monitor_enable_receiving
+#undef udev_monitor_set_receive_buffer_size
+#undef udev_monitor_get_fd
+#undef udev_monitor_receive_device
+#undef udev_monitor_filter_add_match_subsystem_devtype
+#undef udev_monitor_filter_add_match_tag
+#undef udev_monitor_filter_update
+#undef udev_monitor_filter_remove
+#undef udev_enumerate_ref
+#undef udev_enumerate_unref
+#undef udev_enumerate_get_udev
+#undef udev_enumerate_new
+#undef udev_enumerate_add_match_subsystem
+#undef udev_enumerate_add_nomatch_subsystem
+#undef udev_enumerate_add_match_sysattr
+#undef udev_enumerate_add_nomatch_sysattr
+#undef udev_enumerate_add_match_property
+#undef udev_enumerate_add_match_sysname
+#undef udev_enumerate_add_match_tag
+#undef udev_enumerate_add_match_parent
+#undef udev_enumerate_add_match_is_initialized
+#undef udev_enumerate_add_syspath
+#undef udev_enumerate_scan_devices
+#undef udev_enumerate_scan_subsystems
+#undef udev_enumerate_get_list_entry
+#undef udev_queue_ref
+#undef udev_queue_unref
+#undef udev_queue_get_udev
+#undef udev_queue_new
+#undef udev_queue_get_kernel_seqnum
+#undef udev_queue_get_udev_seqnum
+#undef udev_queue_get_udev_is_active
+#undef udev_queue_get_queue_is_empty
+#undef udev_queue_get_seqnum_is_finished
+#undef udev_queue_get_seqnum_sequence_is_finished
+#undef udev_queue_get_fd
+#undef udev_queue_flush
+#undef udev_queue_get_queued_list_entry
+#undef udev_hwdb_new
+#undef udev_hwdb_ref
+#undef udev_hwdb_unref
+#undef udev_hwdb_get_properties_list_entry
+#undef udev_util_encode_string
+#include <dlfcn.h>
+#include <stdio.h>
+struct udev* (*udev_ref_dylibloader_wrapper_libudev)(struct udev*);
+struct udev* (*udev_unref_dylibloader_wrapper_libudev)(struct udev*);
+struct udev* (*udev_new_dylibloader_wrapper_libudev)( void);
+void (*udev_set_log_fn_dylibloader_wrapper_libudev)(struct udev*, void*);
+int (*udev_get_log_priority_dylibloader_wrapper_libudev)(struct udev*);
+void (*udev_set_log_priority_dylibloader_wrapper_libudev)(struct udev*, int);
+void* (*udev_get_userdata_dylibloader_wrapper_libudev)(struct udev*);
+void (*udev_set_userdata_dylibloader_wrapper_libudev)(struct udev*, void*);
+struct udev_list_entry* (*udev_list_entry_get_next_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+struct udev_list_entry* (*udev_list_entry_get_by_name_dylibloader_wrapper_libudev)(struct udev_list_entry*,const char*);
+const char* (*udev_list_entry_get_name_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+const char* (*udev_list_entry_get_value_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+struct udev_device* (*udev_device_ref_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_device* (*udev_device_unref_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev* (*udev_device_get_udev_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_device* (*udev_device_new_from_syspath_dylibloader_wrapper_libudev)(struct udev*,const char*);
+struct udev_device* (*udev_device_new_from_devnum_dylibloader_wrapper_libudev)(struct udev*, char, dev_t);
+struct udev_device* (*udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev)(struct udev*,const char*,const char*);
+struct udev_device* (*udev_device_new_from_device_id_dylibloader_wrapper_libudev)(struct udev*,const char*);
+struct udev_device* (*udev_device_new_from_environment_dylibloader_wrapper_libudev)(struct udev*);
+struct udev_device* (*udev_device_get_parent_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_device* (*udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*);
+const char* (*udev_device_get_devpath_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_subsystem_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_devtype_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_syspath_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_sysname_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_sysnum_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_devnode_dylibloader_wrapper_libudev)(struct udev_device*);
+int (*udev_device_get_is_initialized_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_list_entry* (*udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_list_entry* (*udev_device_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_list_entry* (*udev_device_get_tags_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+struct udev_list_entry* (*udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_property_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+const char* (*udev_device_get_driver_dylibloader_wrapper_libudev)(struct udev_device*);
+dev_t (*udev_device_get_devnum_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_action_dylibloader_wrapper_libudev)(struct udev_device*);
+unsigned long long int (*udev_device_get_seqnum_dylibloader_wrapper_libudev)(struct udev_device*);
+unsigned long long int (*udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev)(struct udev_device*);
+const char* (*udev_device_get_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*);
+int (*udev_device_has_tag_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+struct udev_monitor* (*udev_monitor_ref_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev_monitor* (*udev_monitor_unref_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev* (*udev_monitor_get_udev_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev_monitor* (*udev_monitor_new_from_netlink_dylibloader_wrapper_libudev)(struct udev*,const char*);
+int (*udev_monitor_enable_receiving_dylibloader_wrapper_libudev)(struct udev_monitor*);
+int (*udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev)(struct udev_monitor*, int);
+int (*udev_monitor_get_fd_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev_device* (*udev_monitor_receive_device_dylibloader_wrapper_libudev)(struct udev_monitor*);
+int (*udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*,const char*);
+int (*udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*);
+int (*udev_monitor_filter_update_dylibloader_wrapper_libudev)(struct udev_monitor*);
+int (*udev_monitor_filter_remove_dylibloader_wrapper_libudev)(struct udev_monitor*);
+struct udev_enumerate* (*udev_enumerate_ref_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev_enumerate* (*udev_enumerate_unref_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev* (*udev_enumerate_get_udev_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev_enumerate* (*udev_enumerate_new_dylibloader_wrapper_libudev)(struct udev*);
+int (*udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+int (*udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+int (*udev_enumerate_add_match_property_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+int (*udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_add_match_tag_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_add_match_parent_dylibloader_wrapper_libudev)(struct udev_enumerate*,struct udev_device*);
+int (*udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+int (*udev_enumerate_add_syspath_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+int (*udev_enumerate_scan_devices_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+int (*udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev_list_entry* (*udev_enumerate_get_list_entry_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+struct udev_queue* (*udev_queue_ref_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev_queue* (*udev_queue_unref_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev* (*udev_queue_get_udev_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev_queue* (*udev_queue_new_dylibloader_wrapper_libudev)(struct udev*);
+unsigned long long int (*udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*);
+unsigned long long int (*udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*);
+int (*udev_queue_get_udev_is_active_dylibloader_wrapper_libudev)(struct udev_queue*);
+int (*udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev)(struct udev_queue*);
+int (*udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int);
+int (*udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int, unsigned long long int);
+int (*udev_queue_get_fd_dylibloader_wrapper_libudev)(struct udev_queue*);
+int (*udev_queue_flush_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev_list_entry* (*udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev)(struct udev_queue*);
+struct udev_hwdb* (*udev_hwdb_new_dylibloader_wrapper_libudev)(struct udev*);
+struct udev_hwdb* (*udev_hwdb_ref_dylibloader_wrapper_libudev)(struct udev_hwdb*);
+struct udev_hwdb* (*udev_hwdb_unref_dylibloader_wrapper_libudev)(struct udev_hwdb*);
+struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned);
+int (*udev_util_encode_string_dylibloader_wrapper_libudev)(const char*, char*, size_t);
+int initialize_libudev(int verbose) {
+ void *handle;
+ char *error;
+ handle = dlopen("libudev.so.1", RTLD_LAZY);
+ if (!handle) {
+ if (verbose) {
+ fprintf(stderr, "%s\n", dlerror());
+ }
+ return(1);
+ }
+ dlerror();
+// udev_ref
+ *(void **) (&udev_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_unref
+ *(void **) (&udev_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_new
+ *(void **) (&udev_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_set_log_fn
+ *(void **) (&udev_set_log_fn_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_log_fn");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_get_log_priority
+ *(void **) (&udev_get_log_priority_dylibloader_wrapper_libudev) = dlsym(handle, "udev_get_log_priority");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_set_log_priority
+ *(void **) (&udev_set_log_priority_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_log_priority");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_get_userdata
+ *(void **) (&udev_get_userdata_dylibloader_wrapper_libudev) = dlsym(handle, "udev_get_userdata");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_set_userdata
+ *(void **) (&udev_set_userdata_dylibloader_wrapper_libudev) = dlsym(handle, "udev_set_userdata");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_list_entry_get_next
+ *(void **) (&udev_list_entry_get_next_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_next");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_list_entry_get_by_name
+ *(void **) (&udev_list_entry_get_by_name_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_by_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_list_entry_get_name
+ *(void **) (&udev_list_entry_get_name_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_name");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_list_entry_get_value
+ *(void **) (&udev_list_entry_get_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_list_entry_get_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_ref
+ *(void **) (&udev_device_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_unref
+ *(void **) (&udev_device_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_udev
+ *(void **) (&udev_device_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_udev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_syspath
+ *(void **) (&udev_device_new_from_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_syspath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_devnum
+ *(void **) (&udev_device_new_from_devnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_devnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_subsystem_sysname
+ *(void **) (&udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_subsystem_sysname");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_device_id
+ *(void **) (&udev_device_new_from_device_id_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_device_id");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_new_from_environment
+ *(void **) (&udev_device_new_from_environment_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_new_from_environment");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_parent
+ *(void **) (&udev_device_get_parent_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_parent");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_parent_with_subsystem_devtype
+ *(void **) (&udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_parent_with_subsystem_devtype");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devpath
+ *(void **) (&udev_device_get_devpath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devpath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_subsystem
+ *(void **) (&udev_device_get_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_subsystem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devtype
+ *(void **) (&udev_device_get_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devtype");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_syspath
+ *(void **) (&udev_device_get_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_syspath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_sysname
+ *(void **) (&udev_device_get_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysname");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_sysnum
+ *(void **) (&udev_device_get_sysnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devnode
+ *(void **) (&udev_device_get_devnode_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devnode");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_is_initialized
+ *(void **) (&udev_device_get_is_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_is_initialized");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devlinks_list_entry
+ *(void **) (&udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devlinks_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_properties_list_entry
+ *(void **) (&udev_device_get_properties_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_properties_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_tags_list_entry
+ *(void **) (&udev_device_get_tags_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_tags_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_sysattr_list_entry
+ *(void **) (&udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysattr_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_property_value
+ *(void **) (&udev_device_get_property_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_property_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_driver
+ *(void **) (&udev_device_get_driver_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_driver");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_devnum
+ *(void **) (&udev_device_get_devnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_devnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_action
+ *(void **) (&udev_device_get_action_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_action");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_seqnum
+ *(void **) (&udev_device_get_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_seqnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_usec_since_initialized
+ *(void **) (&udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_usec_since_initialized");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_get_sysattr_value
+ *(void **) (&udev_device_get_sysattr_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_get_sysattr_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_set_sysattr_value
+ *(void **) (&udev_device_set_sysattr_value_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_set_sysattr_value");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_device_has_tag
+ *(void **) (&udev_device_has_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_device_has_tag");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_ref
+ *(void **) (&udev_monitor_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_unref
+ *(void **) (&udev_monitor_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_get_udev
+ *(void **) (&udev_monitor_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_get_udev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_new_from_netlink
+ *(void **) (&udev_monitor_new_from_netlink_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_new_from_netlink");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_enable_receiving
+ *(void **) (&udev_monitor_enable_receiving_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_enable_receiving");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_set_receive_buffer_size
+ *(void **) (&udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_set_receive_buffer_size");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_get_fd
+ *(void **) (&udev_monitor_get_fd_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_get_fd");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_receive_device
+ *(void **) (&udev_monitor_receive_device_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_receive_device");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_filter_add_match_subsystem_devtype
+ *(void **) (&udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_add_match_subsystem_devtype");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_filter_add_match_tag
+ *(void **) (&udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_add_match_tag");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_filter_update
+ *(void **) (&udev_monitor_filter_update_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_update");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_monitor_filter_remove
+ *(void **) (&udev_monitor_filter_remove_dylibloader_wrapper_libudev) = dlsym(handle, "udev_monitor_filter_remove");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_ref
+ *(void **) (&udev_enumerate_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_unref
+ *(void **) (&udev_enumerate_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_get_udev
+ *(void **) (&udev_enumerate_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_get_udev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_new
+ *(void **) (&udev_enumerate_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_subsystem
+ *(void **) (&udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_subsystem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_nomatch_subsystem
+ *(void **) (&udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_nomatch_subsystem");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_sysattr
+ *(void **) (&udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_sysattr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_nomatch_sysattr
+ *(void **) (&udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_nomatch_sysattr");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_property
+ *(void **) (&udev_enumerate_add_match_property_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_property");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_sysname
+ *(void **) (&udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_sysname");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_tag
+ *(void **) (&udev_enumerate_add_match_tag_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_tag");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_parent
+ *(void **) (&udev_enumerate_add_match_parent_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_parent");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_match_is_initialized
+ *(void **) (&udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_match_is_initialized");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_add_syspath
+ *(void **) (&udev_enumerate_add_syspath_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_add_syspath");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_scan_devices
+ *(void **) (&udev_enumerate_scan_devices_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_scan_devices");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_scan_subsystems
+ *(void **) (&udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_scan_subsystems");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_enumerate_get_list_entry
+ *(void **) (&udev_enumerate_get_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_enumerate_get_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_ref
+ *(void **) (&udev_queue_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_unref
+ *(void **) (&udev_queue_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_udev
+ *(void **) (&udev_queue_get_udev_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_new
+ *(void **) (&udev_queue_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_kernel_seqnum
+ *(void **) (&udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_kernel_seqnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_udev_seqnum
+ *(void **) (&udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev_seqnum");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_udev_is_active
+ *(void **) (&udev_queue_get_udev_is_active_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_udev_is_active");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_queue_is_empty
+ *(void **) (&udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_queue_is_empty");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_seqnum_is_finished
+ *(void **) (&udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_seqnum_is_finished");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_seqnum_sequence_is_finished
+ *(void **) (&udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_seqnum_sequence_is_finished");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_fd
+ *(void **) (&udev_queue_get_fd_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_fd");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_flush
+ *(void **) (&udev_queue_flush_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_flush");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_queue_get_queued_list_entry
+ *(void **) (&udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_queue_get_queued_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_hwdb_new
+ *(void **) (&udev_hwdb_new_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_new");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_hwdb_ref
+ *(void **) (&udev_hwdb_ref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_ref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_hwdb_unref
+ *(void **) (&udev_hwdb_unref_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_unref");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_hwdb_get_properties_list_entry
+ *(void **) (&udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev) = dlsym(handle, "udev_hwdb_get_properties_list_entry");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+// udev_util_encode_string
+ *(void **) (&udev_util_encode_string_dylibloader_wrapper_libudev) = dlsym(handle, "udev_util_encode_string");
+ if (verbose) {
+ error = dlerror();
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error);
+ }
+ }
+return 0;
+}
diff --git a/platform/linuxbsd/libudev-so_wrap.h b/platform/linuxbsd/libudev-so_wrap.h
new file mode 100644
index 0000000000..dd43fd1191
--- /dev/null
+++ b/platform/linuxbsd/libudev-so_wrap.h
@@ -0,0 +1,378 @@
+#ifndef DYLIBLOAD_WRAPPER_LIBUDEV
+#define DYLIBLOAD_WRAPPER_LIBUDEV
+// This file is generated. Do not edit!
+// see https://github.com/hpvb/dynload-wrapper for details
+// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:59
+// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/libudev.h --sys-include <libudev.h> --soname libudev.so.1 --init-name libudev --omit-prefix gnu_ --output-header libudev-so_wrap.h --output-implementation libudev-so_wrap.c
+//
+#include <stdint.h>
+
+#define udev_ref udev_ref_dylibloader_orig_libudev
+#define udev_unref udev_unref_dylibloader_orig_libudev
+#define udev_new udev_new_dylibloader_orig_libudev
+#define udev_set_log_fn udev_set_log_fn_dylibloader_orig_libudev
+#define udev_get_log_priority udev_get_log_priority_dylibloader_orig_libudev
+#define udev_set_log_priority udev_set_log_priority_dylibloader_orig_libudev
+#define udev_get_userdata udev_get_userdata_dylibloader_orig_libudev
+#define udev_set_userdata udev_set_userdata_dylibloader_orig_libudev
+#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_orig_libudev
+#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_orig_libudev
+#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_orig_libudev
+#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_orig_libudev
+#define udev_device_ref udev_device_ref_dylibloader_orig_libudev
+#define udev_device_unref udev_device_unref_dylibloader_orig_libudev
+#define udev_device_get_udev udev_device_get_udev_dylibloader_orig_libudev
+#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_orig_libudev
+#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_orig_libudev
+#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_orig_libudev
+#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_orig_libudev
+#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_orig_libudev
+#define udev_device_get_parent udev_device_get_parent_dylibloader_orig_libudev
+#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_orig_libudev
+#define udev_device_get_devpath udev_device_get_devpath_dylibloader_orig_libudev
+#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_orig_libudev
+#define udev_device_get_devtype udev_device_get_devtype_dylibloader_orig_libudev
+#define udev_device_get_syspath udev_device_get_syspath_dylibloader_orig_libudev
+#define udev_device_get_sysname udev_device_get_sysname_dylibloader_orig_libudev
+#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_orig_libudev
+#define udev_device_get_devnode udev_device_get_devnode_dylibloader_orig_libudev
+#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_orig_libudev
+#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_orig_libudev
+#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_orig_libudev
+#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_orig_libudev
+#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_orig_libudev
+#define udev_device_get_property_value udev_device_get_property_value_dylibloader_orig_libudev
+#define udev_device_get_driver udev_device_get_driver_dylibloader_orig_libudev
+#define udev_device_get_devnum udev_device_get_devnum_dylibloader_orig_libudev
+#define udev_device_get_action udev_device_get_action_dylibloader_orig_libudev
+#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_orig_libudev
+#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_orig_libudev
+#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_orig_libudev
+#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_orig_libudev
+#define udev_device_has_tag udev_device_has_tag_dylibloader_orig_libudev
+#define udev_monitor_ref udev_monitor_ref_dylibloader_orig_libudev
+#define udev_monitor_unref udev_monitor_unref_dylibloader_orig_libudev
+#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_orig_libudev
+#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_orig_libudev
+#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_orig_libudev
+#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_orig_libudev
+#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_orig_libudev
+#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_orig_libudev
+#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_orig_libudev
+#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_orig_libudev
+#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_orig_libudev
+#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_orig_libudev
+#define udev_enumerate_ref udev_enumerate_ref_dylibloader_orig_libudev
+#define udev_enumerate_unref udev_enumerate_unref_dylibloader_orig_libudev
+#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_orig_libudev
+#define udev_enumerate_new udev_enumerate_new_dylibloader_orig_libudev
+#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_orig_libudev
+#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_orig_libudev
+#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_orig_libudev
+#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_orig_libudev
+#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_orig_libudev
+#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_orig_libudev
+#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_orig_libudev
+#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_orig_libudev
+#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_orig_libudev
+#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_orig_libudev
+#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_orig_libudev
+#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_orig_libudev
+#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_orig_libudev
+#define udev_queue_ref udev_queue_ref_dylibloader_orig_libudev
+#define udev_queue_unref udev_queue_unref_dylibloader_orig_libudev
+#define udev_queue_get_udev udev_queue_get_udev_dylibloader_orig_libudev
+#define udev_queue_new udev_queue_new_dylibloader_orig_libudev
+#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_orig_libudev
+#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_orig_libudev
+#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_orig_libudev
+#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_orig_libudev
+#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_orig_libudev
+#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_orig_libudev
+#define udev_queue_get_fd udev_queue_get_fd_dylibloader_orig_libudev
+#define udev_queue_flush udev_queue_flush_dylibloader_orig_libudev
+#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_orig_libudev
+#define udev_hwdb_new udev_hwdb_new_dylibloader_orig_libudev
+#define udev_hwdb_ref udev_hwdb_ref_dylibloader_orig_libudev
+#define udev_hwdb_unref udev_hwdb_unref_dylibloader_orig_libudev
+#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_orig_libudev
+#define udev_util_encode_string udev_util_encode_string_dylibloader_orig_libudev
+#include <libudev.h>
+#undef udev_ref
+#undef udev_unref
+#undef udev_new
+#undef udev_set_log_fn
+#undef udev_get_log_priority
+#undef udev_set_log_priority
+#undef udev_get_userdata
+#undef udev_set_userdata
+#undef udev_list_entry_get_next
+#undef udev_list_entry_get_by_name
+#undef udev_list_entry_get_name
+#undef udev_list_entry_get_value
+#undef udev_device_ref
+#undef udev_device_unref
+#undef udev_device_get_udev
+#undef udev_device_new_from_syspath
+#undef udev_device_new_from_devnum
+#undef udev_device_new_from_subsystem_sysname
+#undef udev_device_new_from_device_id
+#undef udev_device_new_from_environment
+#undef udev_device_get_parent
+#undef udev_device_get_parent_with_subsystem_devtype
+#undef udev_device_get_devpath
+#undef udev_device_get_subsystem
+#undef udev_device_get_devtype
+#undef udev_device_get_syspath
+#undef udev_device_get_sysname
+#undef udev_device_get_sysnum
+#undef udev_device_get_devnode
+#undef udev_device_get_is_initialized
+#undef udev_device_get_devlinks_list_entry
+#undef udev_device_get_properties_list_entry
+#undef udev_device_get_tags_list_entry
+#undef udev_device_get_sysattr_list_entry
+#undef udev_device_get_property_value
+#undef udev_device_get_driver
+#undef udev_device_get_devnum
+#undef udev_device_get_action
+#undef udev_device_get_seqnum
+#undef udev_device_get_usec_since_initialized
+#undef udev_device_get_sysattr_value
+#undef udev_device_set_sysattr_value
+#undef udev_device_has_tag
+#undef udev_monitor_ref
+#undef udev_monitor_unref
+#undef udev_monitor_get_udev
+#undef udev_monitor_new_from_netlink
+#undef udev_monitor_enable_receiving
+#undef udev_monitor_set_receive_buffer_size
+#undef udev_monitor_get_fd
+#undef udev_monitor_receive_device
+#undef udev_monitor_filter_add_match_subsystem_devtype
+#undef udev_monitor_filter_add_match_tag
+#undef udev_monitor_filter_update
+#undef udev_monitor_filter_remove
+#undef udev_enumerate_ref
+#undef udev_enumerate_unref
+#undef udev_enumerate_get_udev
+#undef udev_enumerate_new
+#undef udev_enumerate_add_match_subsystem
+#undef udev_enumerate_add_nomatch_subsystem
+#undef udev_enumerate_add_match_sysattr
+#undef udev_enumerate_add_nomatch_sysattr
+#undef udev_enumerate_add_match_property
+#undef udev_enumerate_add_match_sysname
+#undef udev_enumerate_add_match_tag
+#undef udev_enumerate_add_match_parent
+#undef udev_enumerate_add_match_is_initialized
+#undef udev_enumerate_add_syspath
+#undef udev_enumerate_scan_devices
+#undef udev_enumerate_scan_subsystems
+#undef udev_enumerate_get_list_entry
+#undef udev_queue_ref
+#undef udev_queue_unref
+#undef udev_queue_get_udev
+#undef udev_queue_new
+#undef udev_queue_get_kernel_seqnum
+#undef udev_queue_get_udev_seqnum
+#undef udev_queue_get_udev_is_active
+#undef udev_queue_get_queue_is_empty
+#undef udev_queue_get_seqnum_is_finished
+#undef udev_queue_get_seqnum_sequence_is_finished
+#undef udev_queue_get_fd
+#undef udev_queue_flush
+#undef udev_queue_get_queued_list_entry
+#undef udev_hwdb_new
+#undef udev_hwdb_ref
+#undef udev_hwdb_unref
+#undef udev_hwdb_get_properties_list_entry
+#undef udev_util_encode_string
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define udev_ref udev_ref_dylibloader_wrapper_libudev
+#define udev_unref udev_unref_dylibloader_wrapper_libudev
+#define udev_new udev_new_dylibloader_wrapper_libudev
+#define udev_set_log_fn udev_set_log_fn_dylibloader_wrapper_libudev
+#define udev_get_log_priority udev_get_log_priority_dylibloader_wrapper_libudev
+#define udev_set_log_priority udev_set_log_priority_dylibloader_wrapper_libudev
+#define udev_get_userdata udev_get_userdata_dylibloader_wrapper_libudev
+#define udev_set_userdata udev_set_userdata_dylibloader_wrapper_libudev
+#define udev_list_entry_get_next udev_list_entry_get_next_dylibloader_wrapper_libudev
+#define udev_list_entry_get_by_name udev_list_entry_get_by_name_dylibloader_wrapper_libudev
+#define udev_list_entry_get_name udev_list_entry_get_name_dylibloader_wrapper_libudev
+#define udev_list_entry_get_value udev_list_entry_get_value_dylibloader_wrapper_libudev
+#define udev_device_ref udev_device_ref_dylibloader_wrapper_libudev
+#define udev_device_unref udev_device_unref_dylibloader_wrapper_libudev
+#define udev_device_get_udev udev_device_get_udev_dylibloader_wrapper_libudev
+#define udev_device_new_from_syspath udev_device_new_from_syspath_dylibloader_wrapper_libudev
+#define udev_device_new_from_devnum udev_device_new_from_devnum_dylibloader_wrapper_libudev
+#define udev_device_new_from_subsystem_sysname udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev
+#define udev_device_new_from_device_id udev_device_new_from_device_id_dylibloader_wrapper_libudev
+#define udev_device_new_from_environment udev_device_new_from_environment_dylibloader_wrapper_libudev
+#define udev_device_get_parent udev_device_get_parent_dylibloader_wrapper_libudev
+#define udev_device_get_parent_with_subsystem_devtype udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev
+#define udev_device_get_devpath udev_device_get_devpath_dylibloader_wrapper_libudev
+#define udev_device_get_subsystem udev_device_get_subsystem_dylibloader_wrapper_libudev
+#define udev_device_get_devtype udev_device_get_devtype_dylibloader_wrapper_libudev
+#define udev_device_get_syspath udev_device_get_syspath_dylibloader_wrapper_libudev
+#define udev_device_get_sysname udev_device_get_sysname_dylibloader_wrapper_libudev
+#define udev_device_get_sysnum udev_device_get_sysnum_dylibloader_wrapper_libudev
+#define udev_device_get_devnode udev_device_get_devnode_dylibloader_wrapper_libudev
+#define udev_device_get_is_initialized udev_device_get_is_initialized_dylibloader_wrapper_libudev
+#define udev_device_get_devlinks_list_entry udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev
+#define udev_device_get_properties_list_entry udev_device_get_properties_list_entry_dylibloader_wrapper_libudev
+#define udev_device_get_tags_list_entry udev_device_get_tags_list_entry_dylibloader_wrapper_libudev
+#define udev_device_get_sysattr_list_entry udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev
+#define udev_device_get_property_value udev_device_get_property_value_dylibloader_wrapper_libudev
+#define udev_device_get_driver udev_device_get_driver_dylibloader_wrapper_libudev
+#define udev_device_get_devnum udev_device_get_devnum_dylibloader_wrapper_libudev
+#define udev_device_get_action udev_device_get_action_dylibloader_wrapper_libudev
+#define udev_device_get_seqnum udev_device_get_seqnum_dylibloader_wrapper_libudev
+#define udev_device_get_usec_since_initialized udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev
+#define udev_device_get_sysattr_value udev_device_get_sysattr_value_dylibloader_wrapper_libudev
+#define udev_device_set_sysattr_value udev_device_set_sysattr_value_dylibloader_wrapper_libudev
+#define udev_device_has_tag udev_device_has_tag_dylibloader_wrapper_libudev
+#define udev_monitor_ref udev_monitor_ref_dylibloader_wrapper_libudev
+#define udev_monitor_unref udev_monitor_unref_dylibloader_wrapper_libudev
+#define udev_monitor_get_udev udev_monitor_get_udev_dylibloader_wrapper_libudev
+#define udev_monitor_new_from_netlink udev_monitor_new_from_netlink_dylibloader_wrapper_libudev
+#define udev_monitor_enable_receiving udev_monitor_enable_receiving_dylibloader_wrapper_libudev
+#define udev_monitor_set_receive_buffer_size udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev
+#define udev_monitor_get_fd udev_monitor_get_fd_dylibloader_wrapper_libudev
+#define udev_monitor_receive_device udev_monitor_receive_device_dylibloader_wrapper_libudev
+#define udev_monitor_filter_add_match_subsystem_devtype udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev
+#define udev_monitor_filter_add_match_tag udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev
+#define udev_monitor_filter_update udev_monitor_filter_update_dylibloader_wrapper_libudev
+#define udev_monitor_filter_remove udev_monitor_filter_remove_dylibloader_wrapper_libudev
+#define udev_enumerate_ref udev_enumerate_ref_dylibloader_wrapper_libudev
+#define udev_enumerate_unref udev_enumerate_unref_dylibloader_wrapper_libudev
+#define udev_enumerate_get_udev udev_enumerate_get_udev_dylibloader_wrapper_libudev
+#define udev_enumerate_new udev_enumerate_new_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_subsystem udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev
+#define udev_enumerate_add_nomatch_subsystem udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_sysattr udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev
+#define udev_enumerate_add_nomatch_sysattr udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_property udev_enumerate_add_match_property_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_sysname udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_tag udev_enumerate_add_match_tag_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_parent udev_enumerate_add_match_parent_dylibloader_wrapper_libudev
+#define udev_enumerate_add_match_is_initialized udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev
+#define udev_enumerate_add_syspath udev_enumerate_add_syspath_dylibloader_wrapper_libudev
+#define udev_enumerate_scan_devices udev_enumerate_scan_devices_dylibloader_wrapper_libudev
+#define udev_enumerate_scan_subsystems udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev
+#define udev_enumerate_get_list_entry udev_enumerate_get_list_entry_dylibloader_wrapper_libudev
+#define udev_queue_ref udev_queue_ref_dylibloader_wrapper_libudev
+#define udev_queue_unref udev_queue_unref_dylibloader_wrapper_libudev
+#define udev_queue_get_udev udev_queue_get_udev_dylibloader_wrapper_libudev
+#define udev_queue_new udev_queue_new_dylibloader_wrapper_libudev
+#define udev_queue_get_kernel_seqnum udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev
+#define udev_queue_get_udev_seqnum udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev
+#define udev_queue_get_udev_is_active udev_queue_get_udev_is_active_dylibloader_wrapper_libudev
+#define udev_queue_get_queue_is_empty udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev
+#define udev_queue_get_seqnum_is_finished udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev
+#define udev_queue_get_seqnum_sequence_is_finished udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev
+#define udev_queue_get_fd udev_queue_get_fd_dylibloader_wrapper_libudev
+#define udev_queue_flush udev_queue_flush_dylibloader_wrapper_libudev
+#define udev_queue_get_queued_list_entry udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev
+#define udev_hwdb_new udev_hwdb_new_dylibloader_wrapper_libudev
+#define udev_hwdb_ref udev_hwdb_ref_dylibloader_wrapper_libudev
+#define udev_hwdb_unref udev_hwdb_unref_dylibloader_wrapper_libudev
+#define udev_hwdb_get_properties_list_entry udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev
+#define udev_util_encode_string udev_util_encode_string_dylibloader_wrapper_libudev
+extern struct udev* (*udev_ref_dylibloader_wrapper_libudev)(struct udev*);
+extern struct udev* (*udev_unref_dylibloader_wrapper_libudev)(struct udev*);
+extern struct udev* (*udev_new_dylibloader_wrapper_libudev)( void);
+extern void (*udev_set_log_fn_dylibloader_wrapper_libudev)(struct udev*, void*);
+extern int (*udev_get_log_priority_dylibloader_wrapper_libudev)(struct udev*);
+extern void (*udev_set_log_priority_dylibloader_wrapper_libudev)(struct udev*, int);
+extern void* (*udev_get_userdata_dylibloader_wrapper_libudev)(struct udev*);
+extern void (*udev_set_userdata_dylibloader_wrapper_libudev)(struct udev*, void*);
+extern struct udev_list_entry* (*udev_list_entry_get_next_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+extern struct udev_list_entry* (*udev_list_entry_get_by_name_dylibloader_wrapper_libudev)(struct udev_list_entry*,const char*);
+extern const char* (*udev_list_entry_get_name_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+extern const char* (*udev_list_entry_get_value_dylibloader_wrapper_libudev)(struct udev_list_entry*);
+extern struct udev_device* (*udev_device_ref_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_device* (*udev_device_unref_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev* (*udev_device_get_udev_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_device* (*udev_device_new_from_syspath_dylibloader_wrapper_libudev)(struct udev*,const char*);
+extern struct udev_device* (*udev_device_new_from_devnum_dylibloader_wrapper_libudev)(struct udev*, char, dev_t);
+extern struct udev_device* (*udev_device_new_from_subsystem_sysname_dylibloader_wrapper_libudev)(struct udev*,const char*,const char*);
+extern struct udev_device* (*udev_device_new_from_device_id_dylibloader_wrapper_libudev)(struct udev*,const char*);
+extern struct udev_device* (*udev_device_new_from_environment_dylibloader_wrapper_libudev)(struct udev*);
+extern struct udev_device* (*udev_device_get_parent_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_device* (*udev_device_get_parent_with_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*);
+extern const char* (*udev_device_get_devpath_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_subsystem_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_devtype_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_syspath_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_sysname_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_sysnum_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_devnode_dylibloader_wrapper_libudev)(struct udev_device*);
+extern int (*udev_device_get_is_initialized_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_list_entry* (*udev_device_get_devlinks_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_list_entry* (*udev_device_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_list_entry* (*udev_device_get_tags_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+extern struct udev_list_entry* (*udev_device_get_sysattr_list_entry_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_property_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+extern const char* (*udev_device_get_driver_dylibloader_wrapper_libudev)(struct udev_device*);
+extern dev_t (*udev_device_get_devnum_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_action_dylibloader_wrapper_libudev)(struct udev_device*);
+extern unsigned long long int (*udev_device_get_seqnum_dylibloader_wrapper_libudev)(struct udev_device*);
+extern unsigned long long int (*udev_device_get_usec_since_initialized_dylibloader_wrapper_libudev)(struct udev_device*);
+extern const char* (*udev_device_get_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+extern int (*udev_device_set_sysattr_value_dylibloader_wrapper_libudev)(struct udev_device*,const char*,const char*);
+extern int (*udev_device_has_tag_dylibloader_wrapper_libudev)(struct udev_device*,const char*);
+extern struct udev_monitor* (*udev_monitor_ref_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev_monitor* (*udev_monitor_unref_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev* (*udev_monitor_get_udev_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev_monitor* (*udev_monitor_new_from_netlink_dylibloader_wrapper_libudev)(struct udev*,const char*);
+extern int (*udev_monitor_enable_receiving_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern int (*udev_monitor_set_receive_buffer_size_dylibloader_wrapper_libudev)(struct udev_monitor*, int);
+extern int (*udev_monitor_get_fd_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev_device* (*udev_monitor_receive_device_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern int (*udev_monitor_filter_add_match_subsystem_devtype_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*,const char*);
+extern int (*udev_monitor_filter_add_match_tag_dylibloader_wrapper_libudev)(struct udev_monitor*,const char*);
+extern int (*udev_monitor_filter_update_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern int (*udev_monitor_filter_remove_dylibloader_wrapper_libudev)(struct udev_monitor*);
+extern struct udev_enumerate* (*udev_enumerate_ref_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev_enumerate* (*udev_enumerate_unref_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev* (*udev_enumerate_get_udev_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev_enumerate* (*udev_enumerate_new_dylibloader_wrapper_libudev)(struct udev*);
+extern int (*udev_enumerate_add_match_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_add_nomatch_subsystem_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_add_match_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+extern int (*udev_enumerate_add_nomatch_sysattr_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+extern int (*udev_enumerate_add_match_property_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*,const char*);
+extern int (*udev_enumerate_add_match_sysname_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_add_match_tag_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_add_match_parent_dylibloader_wrapper_libudev)(struct udev_enumerate*,struct udev_device*);
+extern int (*udev_enumerate_add_match_is_initialized_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern int (*udev_enumerate_add_syspath_dylibloader_wrapper_libudev)(struct udev_enumerate*,const char*);
+extern int (*udev_enumerate_scan_devices_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern int (*udev_enumerate_scan_subsystems_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev_list_entry* (*udev_enumerate_get_list_entry_dylibloader_wrapper_libudev)(struct udev_enumerate*);
+extern struct udev_queue* (*udev_queue_ref_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev_queue* (*udev_queue_unref_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev* (*udev_queue_get_udev_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev_queue* (*udev_queue_new_dylibloader_wrapper_libudev)(struct udev*);
+extern unsigned long long int (*udev_queue_get_kernel_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern unsigned long long int (*udev_queue_get_udev_seqnum_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern int (*udev_queue_get_udev_is_active_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern int (*udev_queue_get_queue_is_empty_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern int (*udev_queue_get_seqnum_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int);
+extern int (*udev_queue_get_seqnum_sequence_is_finished_dylibloader_wrapper_libudev)(struct udev_queue*, unsigned long long int, unsigned long long int);
+extern int (*udev_queue_get_fd_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern int (*udev_queue_flush_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev_list_entry* (*udev_queue_get_queued_list_entry_dylibloader_wrapper_libudev)(struct udev_queue*);
+extern struct udev_hwdb* (*udev_hwdb_new_dylibloader_wrapper_libudev)(struct udev*);
+extern struct udev_hwdb* (*udev_hwdb_ref_dylibloader_wrapper_libudev)(struct udev_hwdb*);
+extern struct udev_hwdb* (*udev_hwdb_unref_dylibloader_wrapper_libudev)(struct udev_hwdb*);
+extern struct udev_list_entry* (*udev_hwdb_get_properties_list_entry_dylibloader_wrapper_libudev)(struct udev_hwdb*,const char*, unsigned);
+extern int (*udev_util_encode_string_dylibloader_wrapper_libudev)(const char*, char*, size_t);
+int initialize_libudev(int verbose);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index ac88d457a7..09e1f9461c 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,9 +65,9 @@ void OS_LinuxBSD::initialize_joypads() {
String OS_LinuxBSD::get_unique_id() const {
static String machine_id;
- if (machine_id.empty()) {
+ if (machine_id.is_empty()) {
if (FileAccess *f = FileAccess::open("/etc/machine-id", FileAccess::READ)) {
- while (machine_id.empty() && !f->eof_reached()) {
+ while (machine_id.is_empty() && !f->eof_reached()) {
machine_id = f->get_line().strip_edges();
}
f->close();
@@ -128,7 +128,7 @@ Error OS_LinuxBSD::shell_open(String p_uri) {
args.push_back(p_uri);
// Agnostic
- ok = execute("xdg-open", args, true, nullptr, nullptr, &err_code);
+ ok = execute("xdg-open", args, nullptr, &err_code);
if (ok == OK && !err_code) {
return OK;
} else if (err_code == 2) {
@@ -136,25 +136,25 @@ Error OS_LinuxBSD::shell_open(String p_uri) {
}
// GNOME
args.push_front("open"); // The command is `gio open`, so we need to add it to args
- ok = execute("gio", args, true, nullptr, nullptr, &err_code);
+ ok = execute("gio", args, nullptr, &err_code);
if (ok == OK && !err_code) {
return OK;
} else if (err_code == 2) {
return ERR_FILE_NOT_FOUND;
}
args.pop_front();
- ok = execute("gvfs-open", args, true, nullptr, nullptr, &err_code);
+ ok = execute("gvfs-open", args, nullptr, &err_code);
if (ok == OK && !err_code) {
return OK;
} else if (err_code == 2) {
return ERR_FILE_NOT_FOUND;
}
// KDE
- ok = execute("kde-open5", args, true, nullptr, nullptr, &err_code);
+ ok = execute("kde-open5", args, nullptr, &err_code);
if (ok == OK && !err_code) {
return OK;
}
- ok = execute("kde-open", args, true, nullptr, nullptr, &err_code);
+ ok = execute("kde-open", args, nullptr, &err_code);
return !err_code ? ok : FAILED;
}
@@ -232,7 +232,7 @@ String OS_LinuxBSD::get_system_dir(SystemDir p_dir) const {
String pipe;
List<String> arg;
arg.push_back(xdgparam);
- Error err = const_cast<OS_LinuxBSD *>(this)->execute("xdg-user-dir", arg, true, nullptr, &pipe);
+ Error err = const_cast<OS_LinuxBSD *>(this)->execute("xdg-user-dir", arg, &pipe);
if (err != OK) {
return ".";
}
@@ -246,7 +246,7 @@ void OS_LinuxBSD::run() {
return;
}
- main_loop->init();
+ main_loop->initialize();
//uint64_t last_ticks=get_ticks_usec();
@@ -263,7 +263,7 @@ void OS_LinuxBSD::run() {
}
};
- main_loop->finish();
+ main_loop->finalize();
}
void OS_LinuxBSD::disable_crash_handler() {
@@ -307,7 +307,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
List<String> args;
args.push_back(p_path);
args.push_front("trash"); // The command is `gio trash <file_name>` so we need to add it to args.
- Error result = execute("gio", args, true, nullptr, nullptr, &err_code); // For GNOME based machines.
+ Error result = execute("gio", args, nullptr, &err_code); // For GNOME based machines.
if (result == OK && !err_code) {
return OK;
} else if (err_code == 2) {
@@ -317,7 +317,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
args.pop_front();
args.push_front("move");
args.push_back("trash:/"); // The command is `kioclient5 move <file_name> trash:/`.
- result = execute("kioclient5", args, true, nullptr, nullptr, &err_code); // For KDE based machines.
+ result = execute("kioclient5", args, nullptr, &err_code); // For KDE based machines.
if (result == OK && !err_code) {
return OK;
} else if (err_code == 2) {
@@ -326,7 +326,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
args.pop_front();
args.pop_back();
- result = execute("gvfs-trash", args, true, nullptr, nullptr, &err_code); // For older Linux machines.
+ result = execute("gvfs-trash", args, nullptr, &err_code); // For older Linux machines.
if (result == OK && !err_code) {
return OK;
} else if (err_code == 2) {
@@ -410,7 +410,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
OS::Time time = OS::get_singleton()->get_time(false);
String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", date.year, date.month, date.day, time.hour, time.min);
timestamp = vformat("%s%02d", timestamp, time.sec); // vformat only supports up to 6 arguments.
- String trash_info = "[Trash Info]\nPath=" + p_path.http_escape() + "\nDeletionDate=" + timestamp + "\n";
+ String trash_info = "[Trash Info]\nPath=" + p_path.uri_encode() + "\nDeletionDate=" + timestamp + "\n";
{
Error err;
FileAccess *file = FileAccess::open(trash_path + "/info/" + file_name + ".trashinfo", FileAccess::WRITE, &err);
@@ -432,7 +432,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
mv_args.push_back(trash_path + "/files");
{
int retval;
- Error err = execute("mv", mv_args, true, nullptr, nullptr, &retval);
+ Error err = execute("mv", mv_args, nullptr, &retval);
// Issue an error if "mv" failed to move the given resource to the trash can.
if (err != OK || retval != 0) {
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
index 89d0bcd0f2..b6cf93c551 100644
--- a/platform/linuxbsd/os_linuxbsd.h
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/platform_config.h b/platform/linuxbsd/platform_config.h
index 571ad03db0..3195d08935 100644
--- a/platform/linuxbsd/platform_config.h
+++ b/platform/linuxbsd/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/vulkan_context_x11.cpp b/platform/linuxbsd/vulkan_context_x11.cpp
index 2eaa9f9446..021db630e0 100644
--- a/platform/linuxbsd/vulkan_context_x11.cpp
+++ b/platform/linuxbsd/vulkan_context_x11.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h
index af3d923cfe..26472444ad 100644
--- a/platform/linuxbsd/vulkan_context_x11.h
+++ b/platform/linuxbsd/vulkan_context_x11.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index aa95a89444..46c13d8550 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -18,5 +18,5 @@ files = [
prog = env.add_program("#bin/godot", files)
-if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]:
+if env["debug_symbols"] and env["separate_debug_symbols"]:
env.AddPostAction(prog, run_in_subprocess(platform_osx_builders.make_debug_osx))
diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h
index 1d467513e2..ac45559217 100644
--- a/platform/osx/context_gl_osx.h
+++ b/platform/osx/context_gl_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/context_gl_osx.mm b/platform/osx/context_gl_osx.mm
index 2319e9eb1f..88db1a296e 100644
--- a/platform/osx/context_gl_osx.mm
+++ b/platform/osx/context_gl_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/crash_handler_osx.h b/platform/osx/crash_handler_osx.h
index 9970f6045a..1601bbaab6 100644
--- a/platform/osx/crash_handler_osx.h
+++ b/platform/osx/crash_handler_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm
index 1429024598..147ce26779 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/osx/crash_handler_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -135,7 +135,7 @@ static void handle_crash(int sig) {
int ret;
String out = "";
- Error err = OS::get_singleton()->execute(String("atos"), args, true, NULL, &out, &ret);
+ Error err = OS::get_singleton()->execute(String("atos"), args, &out, &ret);
if (err == OK && out.substr(0, 2) != "0x") {
out.erase(out.length() - 1, 1);
output = out;
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 466f68d269..c39a4426be 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -31,10 +31,11 @@ def get_opts():
False,
),
EnumVariable("macports_clang", "Build using Clang from MacPorts", "no", ("no", "5.0", "devel")),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
+ BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False),
]
@@ -54,7 +55,7 @@ def configure(env):
if env["arch"] != "arm64":
env.Prepend(CCFLAGS=["-msse2"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "release_debug":
@@ -63,7 +64,7 @@ def configure(env):
else: # optimize for size
env.Prepend(CCFLAGS=["-Os"])
env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
@@ -131,7 +132,7 @@ def configure(env):
env["AS"] = basecmd + "as"
env.Append(CPPDEFINES=["__MACPORTS__"]) # hack to fix libvpx MM256_BROADCASTSI128_SI256 define
- if env["use_ubsan"] or env["use_asan"] or env["use_tsan"]:
+ if env["use_ubsan"] or env["use_asan"] or env["use_lsan"] or env["use_tsan"]:
env.extra_suffix += "s"
if env["use_ubsan"]:
@@ -142,6 +143,10 @@ def configure(env):
env.Append(CCFLAGS=["-fsanitize=address"])
env.Append(LINKFLAGS=["-fsanitize=address"])
+ if env["use_lsan"]:
+ env.Append(CCFLAGS=["-fsanitize=leak"])
+ env.Append(LINKFLAGS=["-fsanitize=leak"])
+
if env["use_tsan"]:
env.Append(CCFLAGS=["-fsanitize=thread"])
env.Append(LINKFLAGS=["-fsanitize=thread"])
diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h
index 91b8f9b2c5..f61581979f 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/osx/dir_access_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm
index 439c6a075f..552c33d018 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/osx/dir_access_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index ea55a3ff28..9fac99810b 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -93,6 +93,7 @@ public:
List<WarpEvent> warp_events;
NSTimeInterval last_warp = 0;
+ bool ignore_warp = false;
Vector<KeyEvent> key_event_buffer;
int key_event_pos;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 8d82119ae2..ed7d89009f 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -256,9 +256,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
List<String> args;
args.push_back(((OS_OSX *)(OS_OSX::get_singleton()))->open_with_filename);
String exec = OS::get_singleton()->get_executable_path();
-
- OS::ProcessID pid = 0;
- OS::get_singleton()->execute(exec, args, false, &pid);
+ OS::get_singleton()->create_process(exec, args);
}
#endif
return YES;
@@ -873,6 +871,15 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
NSPoint delta = NSMakePoint([event deltaX], [event deltaY]);
NSPoint mpos = [event locationInWindow];
+ if (DS_OSX->ignore_warp) {
+ // Discard late events, before warp
+ if (([event timestamp]) < DS_OSX->last_warp) {
+ return;
+ }
+ DS_OSX->ignore_warp = false;
+ return;
+ }
+
if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED) {
// Discard late events
if (([event timestamp]) < DS_OSX->last_warp) {
@@ -2100,6 +2107,8 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
CGAssociateMouseAndMouseCursorPosition(true);
}
+ last_warp = [[NSProcessInfo processInfo] systemUptime];
+ ignore_warp = true;
warp_events.clear();
mouse_mode = p_mode;
}
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index eecd2ed641..f31d8b9b81 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,7 +56,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
void _make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data);
Error _notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path);
- Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
+ Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path);
Error _create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name);
void _zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name);
@@ -114,7 +114,7 @@ public:
virtual void get_platform_features(List<String> *r_features) override {
r_features->push_back("pc");
r_features->push_back("s3tc");
- r_features->push_back("OSX");
+ r_features->push_back("macOS");
}
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) override {
@@ -159,7 +159,30 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_PLACEHOLDER_TEXT, "Type: Name (ID)"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/hardened_runtime"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements", PROPERTY_HINT_GLOBAL_FILE, "*.plist"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements/custom_file", PROPERTY_HINT_GLOBAL_FILE, "*.plist"), ""));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_jit_code_execution"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_unsigned_executable_memory"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/allow_dyld_environment_variables"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/disable_library_validation"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/audio_input"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/camera"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/location"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/address_book"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/calendars"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/photos_library"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/apple_events"), false));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/enabled"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/network_server"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/network_client"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/device_usb"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/device_bluetooth"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/entitlements/app_sandbox/files_downloads", PROPERTY_HINT_ENUM, "No,Read-only,Read-write"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/entitlements/app_sandbox/files_pictures", PROPERTY_HINT_ENUM, "No,Read-only,Read-write"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/entitlements/app_sandbox/files_music", PROPERTY_HINT_ENUM, "No,Read-only,Read-write"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/entitlements/app_sandbox/files_movies", PROPERTY_HINT_ENUM, "No,Read-only,Read-write"), 0));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray()));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "notarization/enable"), false));
@@ -419,7 +442,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset
args.push_back(p_path);
String str;
- Error err = OS::get_singleton()->execute("xcrun", args, true, nullptr, &str, nullptr, true);
+ Error err = OS::get_singleton()->execute("xcrun", args, &str, nullptr, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("altool (" + p_path + "):\n" + str);
@@ -437,7 +460,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset
return OK;
}
-Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path) {
#ifdef OSX_ENABLED
List<String> args;
@@ -449,15 +472,15 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
args.push_back("runtime");
}
- if ((p_preset->get("codesign/entitlements") != "") && (p_path.get_extension() != "dmg")) {
+ if (p_path.get_extension() != "dmg") {
args.push_back("--entitlements");
- args.push_back(p_preset->get("codesign/entitlements"));
+ args.push_back(p_ent_path);
}
PackedStringArray user_args = p_preset->get("codesign/custom_options");
for (int i = 0; i < user_args.size(); i++) {
String user_arg = user_args[i].strip_edges();
- if (!user_arg.empty()) {
+ if (!user_arg.is_empty()) {
args.push_back(user_arg);
}
}
@@ -470,7 +493,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
args.push_back(p_path);
String str;
- Error err = OS::get_singleton()->execute("codesign", args, true, nullptr, &str, nullptr, true);
+ Error err = OS::get_singleton()->execute("codesign", args, &str, nullptr, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("codesign (" + p_path + "):\n" + str);
@@ -504,7 +527,7 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin
args.push_back(p_app_path_name);
String str;
- Error err = OS::get_singleton()->execute("hdiutil", args, true, nullptr, &str, nullptr, true);
+ Error err = OS::get_singleton()->execute("hdiutil", args, &str, nullptr, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("hdiutil returned: " + str);
@@ -607,6 +630,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
// Now process our template.
bool found_binary = false;
int total_size = 0;
+ Vector<String> dylibs_found;
while (ret == UNZ_OK && err == OK) {
bool is_execute = false;
@@ -665,7 +689,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
Ref<Image> icon;
icon.instance();
icon->load(iconpath);
- if (!icon->empty()) {
+ if (!icon->is_empty()) {
_make_icon(icon, data);
}
}
@@ -678,14 +702,18 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name + "/");
+ file = file.replace("/data.mono.osx.64.release_debug/", "/GodotSharp/");
}
if (file.find("/data.mono.osx.64.release/") != -1) {
if (p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
continue; // skip
}
- file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name + "/");
+ file = file.replace("/data.mono.osx.64.release/", "/GodotSharp/");
+ }
+
+ if (file.ends_with(".dylib")) {
+ dylibs_found.push_back(file);
}
print_line("ADDING: " + file + " size: " + itos(data.size()));
@@ -735,22 +763,149 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
// See if we can code sign our new package.
bool sign_enabled = p_preset->get("codesign/enable");
+ String ent_path = p_preset->get("codesign/entitlements/custom_file");
+ if (sign_enabled && (ent_path == "")) {
+ ent_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".entitlements");
+
+ FileAccess *ent_f = FileAccess::open(ent_path, FileAccess::WRITE);
+ if (ent_f) {
+ ent_f->store_line("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ ent_f->store_line("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
+ ent_f->store_line("<plist version=\"1.0\">");
+ ent_f->store_line("<dict>");
+ if ((bool)p_preset->get("codesign/entitlements/allow_jit_code_execution")) {
+ ent_f->store_line("<key>com.apple.security.cs.allow-jit</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/allow_unsigned_executable_memory")) {
+ ent_f->store_line("<key>com.apple.security.cs.allow-unsigned-executable-memory</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/allow_dyld_environment_variables")) {
+ ent_f->store_line("<key>com.apple.security.cs.allow-dyld-environment-variables</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/disable_library_validation")) {
+ ent_f->store_line("<key>com.apple.security.cs.disable-library-validation</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/audio_input")) {
+ ent_f->store_line("<key>com.apple.security.device.audio-input</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/camera")) {
+ ent_f->store_line("<key>com.apple.security.device.camera</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/location")) {
+ ent_f->store_line("<key>com.apple.security.personal-information.location</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/address_book")) {
+ ent_f->store_line("<key>com.apple.security.personal-information.addressbook</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/calendars")) {
+ ent_f->store_line("<key>com.apple.security.personal-information.calendars</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/photos_library")) {
+ ent_f->store_line("<key>com.apple.security.personal-information.photos-library</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/apple_events")) {
+ ent_f->store_line("<key>com.apple.security.automation.apple-events</key>");
+ ent_f->store_line("<true/>");
+ }
+
+ if ((bool)p_preset->get("codesign/entitlements/app_sandbox/enabled")) {
+ ent_f->store_line("<key>com.apple.security.app-sandbox</key>");
+ ent_f->store_line("<true/>");
+
+ if ((bool)p_preset->get("codesign/entitlements/app_sandbox/network_server")) {
+ ent_f->store_line("<key>com.apple.security.network.server</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/app_sandbox/network_client")) {
+ ent_f->store_line("<key>com.apple.security.network.client</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/app_sandbox/device_usb")) {
+ ent_f->store_line("<key>com.apple.security.device.usb</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((bool)p_preset->get("codesign/entitlements/app_sandbox/device_bluetooth")) {
+ ent_f->store_line("<key>com.apple.security.device.bluetooth</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((int)p_preset->get("codesign/entitlements/app_sandbox/files_downloads") == 1) {
+ ent_f->store_line("<key>com.apple.security.files.downloads.read-only</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((int)p_preset->get("codesign/entitlements/app_sandbox/files_downloads") == 2) {
+ ent_f->store_line("<key>com.apple.security.files.downloads.read-write</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((int)p_preset->get("codesign/entitlements/app_sandbox/files_pictures") == 1) {
+ ent_f->store_line("<key>com.apple.security.files.pictures.read-only</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((int)p_preset->get("codesign/entitlements/app_sandbox/files_pictures") == 2) {
+ ent_f->store_line("<key>com.apple.security.files.pictures.read-write</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((int)p_preset->get("codesign/entitlements/app_sandbox/files_music") == 1) {
+ ent_f->store_line("<key>com.apple.security.files.music.read-only</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((int)p_preset->get("codesign/entitlements/app_sandbox/files_music") == 2) {
+ ent_f->store_line("<key>com.apple.security.files.music.read-write</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((int)p_preset->get("codesign/entitlements/app_sandbox/files_movies") == 1) {
+ ent_f->store_line("<key>com.apple.security.files.movies.read-only</key>");
+ ent_f->store_line("<true/>");
+ }
+ if ((int)p_preset->get("codesign/entitlements/app_sandbox/files_movies") == 2) {
+ ent_f->store_line("<key>com.apple.security.files.movies.read-write</key>");
+ ent_f->store_line("<true/>");
+ }
+ }
+
+ ent_f->store_line("</dict>");
+ ent_f->store_line("</plist>");
+
+ ent_f->close();
+ memdelete(ent_f);
+ } else {
+ err = ERR_CANT_CREATE;
+ }
+ }
+
if (err == OK) {
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < shared_objects.size(); i++) {
err = da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file());
if (err == OK && sign_enabled) {
- err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file());
+ err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file(), ent_path);
}
}
memdelete(da);
}
+ if (sign_enabled) {
+ for (int i = 0; i < dylibs_found.size(); i++) {
+ if (err == OK) {
+ err = _code_sign(p_preset, tmp_app_path_name + "/" + dylibs_found[i], ent_path);
+ }
+ }
+ }
+
if (err == OK && sign_enabled) {
if (ep.step("Code signing bundle", 2)) {
return ERR_SKIP;
}
- err = _code_sign(p_preset, tmp_app_path_name + "/Contents/MacOS/" + pkg_name);
+ err = _code_sign(p_preset, tmp_app_path_name + "/Contents/MacOS/" + pkg_name, ent_path);
}
if (export_format == "dmg") {
@@ -766,7 +921,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (ep.step("Code signing DMG", 3)) {
return ERR_SKIP;
}
- err = _code_sign(p_preset, p_path);
+ err = _code_sign(p_preset, p_path, ent_path);
}
} else {
// Create ZIP.
@@ -927,7 +1082,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
}
}
- if (!err.empty()) {
+ if (!err.is_empty()) {
r_error = err;
}
return valid;
diff --git a/platform/osx/export/export.h b/platform/osx/export/export.h
index 4ddcec09fb..f8cf41c0e7 100644
--- a/platform/osx/export/export.h
+++ b/platform/osx/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm
index 4e73d5441c..7e7dbf6afb 100644
--- a/platform/osx/godot_main_osx.mm
+++ b/platform/osx/godot_main_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp
index b2871b261e..0b6a0e20a6 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/osx/joypad_osx.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h
index 6c2a1ea70b..bf7e8949df 100644
--- a/platform/osx/joypad_osx.h
+++ b/platform/osx/joypad_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index f6eee31a6a..d57940775d 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index ed03e953a5..7b5daf5bfb 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -99,7 +99,7 @@ public:
String OS_OSX::get_unique_id() const {
static String serial_number;
- if (serial_number.empty()) {
+ if (serial_number.is_empty()) {
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
CFStringRef serialNumberAsCFString = NULL;
if (platformExpert) {
@@ -312,7 +312,7 @@ void OS_OSX::run() {
if (!main_loop)
return;
- main_loop->init();
+ main_loop->initialize();
bool quit = false;
while (!force_quit && !quit) {
@@ -329,7 +329,7 @@ void OS_OSX::run() {
ERR_PRINT("NSException: " + String([exception reason].UTF8String));
}
};
- main_loop->finish();
+ main_loop->finalize();
}
Error OS_OSX::move_to_trash(const String &p_path) {
diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h
index e657aca955..2d0fd872dc 100644
--- a/platform/osx/platform_config.h
+++ b/platform/osx/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/vulkan_context_osx.h b/platform/osx/vulkan_context_osx.h
index e996f176a9..8b6a75adfb 100644
--- a/platform/osx/vulkan_context_osx.h
+++ b/platform/osx/vulkan_context_osx.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/osx/vulkan_context_osx.mm b/platform/osx/vulkan_context_osx.mm
index ec8745ff01..75a4fc990f 100644
--- a/platform/osx/vulkan_context_osx.mm
+++ b/platform/osx/vulkan_context_osx.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/register_platform_apis.h b/platform/register_platform_apis.h
index 6b962f5d91..4cf84b321f 100644
--- a/platform/register_platform_apis.h
+++ b/platform/register_platform_apis.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/server/detect.py b/platform/server/detect.py
index db503584d3..c799ce03e1 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -32,13 +32,14 @@ def get_opts():
return [
BoolVariable("use_llvm", "Use the LLVM compiler", False),
- BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", False),
+ BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
BoolVariable("use_coverage", "Test Godot coverage", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN))", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN))", False),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
+ BoolVariable("use_msan", "Use LLVM/GCC compiler memory sanitizer (MSAN))", False),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False),
]
@@ -58,7 +59,7 @@ def configure(env):
else: # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "release_debug":
@@ -68,7 +69,7 @@ def configure(env):
env.Prepend(CCFLAGS=["-Os"])
env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
@@ -93,12 +94,13 @@ def configure(env):
env["CC"] = "clang"
env["CXX"] = "clang++"
env.extra_suffix = ".llvm" + env.extra_suffix
+ env.Append(LIBS=["atomic"])
if env["use_coverage"]:
env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
env.Append(LINKFLAGS=["-ftest-coverage", "-fprofile-arcs"])
- if env["use_ubsan"] or env["use_asan"] or env["use_lsan"] or env["use_tsan"]:
+ if env["use_ubsan"] or env["use_asan"] or env["use_lsan"] or env["use_tsan"] or env["use_msan"]:
env.extra_suffix += "s"
if env["use_ubsan"]:
@@ -117,6 +119,10 @@ def configure(env):
env.Append(CCFLAGS=["-fsanitize=thread"])
env.Append(LINKFLAGS=["-fsanitize=thread"])
+ if env["use_msan"]:
+ env.Append(CCFLAGS=["-fsanitize=memory"])
+ env.Append(LINKFLAGS=["-fsanitize=memory"])
+
if env["use_lto"]:
env.Append(CCFLAGS=["-flto"])
if not env["use_llvm"] and env.GetOption("num_jobs") > 1:
diff --git a/platform/server/godot_server.cpp b/platform/server/godot_server.cpp
index 9f22240a80..1ced95fcbc 100644
--- a/platform/server/godot_server.cpp
+++ b/platform/server/godot_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index 77cf15c489..852ec7c4ef 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index b707549b17..61025fa14b 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h
index 73136ec81b..32a19d811b 100644
--- a/platform/server/platform_config.h
+++ b/platform/server/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp
index 6090d13854..dc4238bdd4 100644
--- a/platform/uwp/app.cpp
+++ b/platform/uwp/app.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/app.h b/platform/uwp/app.h
index 5cffe378b1..0b02527dae 100644
--- a/platform/uwp/app.h
+++ b/platform/uwp/app.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/context_egl_uwp.cpp b/platform/uwp/context_egl_uwp.cpp
index a6607ed42c..bb2a14e9fc 100644
--- a/platform/uwp/context_egl_uwp.cpp
+++ b/platform/uwp/context_egl_uwp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/context_egl_uwp.h b/platform/uwp/context_egl_uwp.h
index 5e7dc1802d..974faa3ac7 100644
--- a/platform/uwp/context_egl_uwp.h
+++ b/platform/uwp/context_egl_uwp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index 00b57c48f3..1aad2bfa1a 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -641,7 +641,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
};
bool _valid_resource_name(const String &p_name) const {
- if (p_name.empty()) {
+ if (p_name.is_empty()) {
return false;
}
if (p_name.ends_with(".")) {
@@ -687,7 +687,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
bool _valid_bgcolor(const String &p_color) const {
- if (p_color.empty()) {
+ if (p_color.is_empty()) {
return true;
}
if (p_color.begins_with("#") && p_color.is_valid_html_color()) {
@@ -760,10 +760,10 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
result = result.replace("$version_string$", version);
Platform arch = (Platform)(int)p_preset->get("architecture/target");
- String architecture = arch == ARM ? "arm" : arch == X86 ? "x86" : "x64";
+ String architecture = arch == ARM ? "arm" : (arch == X86 ? "x86" : "x64");
result = result.replace("$architecture$", architecture);
- result = result.replace("$display_name$", String(p_preset->get("package/display_name")).empty() ? (String)ProjectSettings::get_singleton()->get("application/config/name") : String(p_preset->get("package/display_name")));
+ result = result.replace("$display_name$", String(p_preset->get("package/display_name")).is_empty() ? (String)ProjectSettings::get_singleton()->get("application/config/name") : String(p_preset->get("package/display_name")));
result = result.replace("$publisher_display_name$", p_preset->get("package/publisher_display_name"));
result = result.replace("$app_description$", p_preset->get("package/description"));
@@ -782,7 +782,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
String show_name_on_tiles = "";
- if (!name_on_tiles.empty()) {
+ if (!name_on_tiles.is_empty()) {
show_name_on_tiles = "<uap:ShowNameOnTiles>\n" + name_on_tiles + " </uap:ShowNameOnTiles>";
}
@@ -803,7 +803,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
String rotation_preference = "";
- if (!rotations.empty()) {
+ if (!rotations.is_empty()) {
rotation_preference = "<uap:InitialRotationPreference>\n" + rotations + " </uap:InitialRotationPreference>";
}
@@ -837,7 +837,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
String capabilities_string = "<Capabilities />";
- if (!capabilities_elements.empty()) {
+ if (!capabilities_elements.is_empty()) {
capabilities_string = "<Capabilities>\n" + capabilities_elements + " </Capabilities>";
}
@@ -1411,7 +1411,7 @@ public:
args.push_back(cert_pass);
args.push_back(p_path);
- OS::get_singleton()->execute(signtool_path, args, true);
+ OS::get_singleton()->execute(signtool_path, args);
#endif // WINDOWS_ENABLED
return OK;
diff --git a/platform/uwp/export/export.h b/platform/uwp/export/export.h
index 1a1555d8ee..bc23cad38c 100644
--- a/platform/uwp/export/export.h
+++ b/platform/uwp/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp
index 4fdfde9673..5da90db49d 100644
--- a/platform/uwp/joypad_uwp.cpp
+++ b/platform/uwp/joypad_uwp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h
index 2df87d6fd5..5df4a211ac 100644
--- a/platform/uwp/joypad_uwp.h
+++ b/platform/uwp/joypad_uwp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 693d8a69f1..fa97948395 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,14 +39,11 @@
#include "drivers/windows/dir_access_windows.h"
#include "drivers/windows/file_access_windows.h"
#include "drivers/windows/mutex_windows.h"
-#include "drivers/windows/rw_lock_windows.h"
#include "drivers/windows/semaphore_windows.h"
#include "main/main.h"
#include "platform/windows/windows_terminal_logger.h"
#include "servers/audio_server.h"
#include "servers/rendering/rendering_server_default.h"
-#include "servers/rendering/rendering_server_wrap_mt.h"
-#include "thread_uwp.h"
#include <ppltasks.h>
#include <wrl.h>
@@ -131,9 +128,6 @@ void OS_UWP::initialize_core() {
//RedirectIOToConsole();
- ThreadUWP::make_default();
- RWLockWindows::make_default();
-
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
@@ -638,7 +632,11 @@ void OS_UWP::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
// TODO
}
-Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+ return FAILED;
+};
+
+Error OS_UWP::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) {
return FAILED;
};
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index bf3c31f867..a4d3d6d52a 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -199,7 +199,8 @@ public:
virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
+ virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr);
virtual Error kill(const ProcessID &p_pid);
virtual bool has_environment(const String &p_var) const;
diff --git a/platform/uwp/platform_config.h b/platform/uwp/platform_config.h
index 09a16614e0..481f583f6f 100644
--- a/platform/uwp/platform_config.h
+++ b/platform/uwp/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/thread_uwp.cpp b/platform/uwp/thread_uwp.cpp
deleted file mode 100644
index 8e7bb144be..0000000000
--- a/platform/uwp/thread_uwp.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*************************************************************************/
-/* thread_uwp.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "thread_uwp.h"
-
-#include "core/os/memory.h"
-
-Thread *ThreadUWP::create_func_uwp(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
- ThreadUWP *thread = memnew(ThreadUWP);
-
- std::thread new_thread(p_callback, p_user);
- std::swap(thread->thread, new_thread);
-
- return thread;
-};
-
-Thread::ID ThreadUWP::get_thread_id_func_uwp() {
- return std::hash<std::thread::id>()(std::this_thread::get_id());
-};
-
-void ThreadUWP::wait_to_finish_func_uwp(Thread *p_thread) {
- ThreadUWP *tp = static_cast<ThreadUWP *>(p_thread);
- tp->thread.join();
-};
-
-Thread::ID ThreadUWP::get_id() const {
- return std::hash<std::thread::id>()(thread.get_id());
-};
-
-void ThreadUWP::make_default() {
- create_func = create_func_uwp;
- get_thread_id_func = get_thread_id_func_uwp;
- wait_to_finish_func = wait_to_finish_func_uwp;
-};
diff --git a/platform/uwp/thread_uwp.h b/platform/uwp/thread_uwp.h
deleted file mode 100644
index 9b2a2590a8..0000000000
--- a/platform/uwp/thread_uwp.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*************************************************************************/
-/* thread_uwp.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef THREAD_UWP_H
-#define THREAD_UWP_H
-
-#ifdef UWP_ENABLED
-
-#include "core/os/thread.h"
-
-#include <thread>
-
-class ThreadUWP : public Thread {
- std::thread thread;
-
- static Thread *create_func_uwp(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID get_thread_id_func_uwp();
- static void wait_to_finish_func_uwp(Thread *p_thread);
-
- ThreadUWP() {}
-
-public:
- virtual ID get_id() const;
-
- static void make_default();
-
- ~ThreadUWP() {}
-};
-
-#endif // UWP_ENABLED
-
-#endif // THREAD_UWP_H
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index 0c9aa77803..47d8e14680 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -32,5 +32,5 @@ if env["vsproj"]:
env.vs_srcs += ["platform/windows/" + str(x)]
if not os.getenv("VCINSTALLDIR"):
- if env["debug_symbols"] == "yes" and env["separate_debug_symbols"]:
+ if env["debug_symbols"] and env["separate_debug_symbols"]:
env.AddPostAction(prog, run_in_subprocess(platform_windows_builders.make_debug_mingw))
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
index 54251fc66c..207b0a1168 100644
--- a/platform/windows/context_gl_windows.cpp
+++ b/platform/windows/context_gl_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index 0013177609..e44e2945ca 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index 0f2f49c5ce..e24e466f88 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/crash_handler_windows.h b/platform/windows/crash_handler_windows.h
index 66a4cac296..e1ec8e6787 100644
--- a/platform/windows/crash_handler_windows.h
+++ b/platform/windows/crash_handler_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 5216fca2ca..f26dea8d35 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -64,7 +64,7 @@ def get_opts():
# XP support dropped after EOL due to missing API for IPv6 and other issues
# Vista support dropped after EOL due to GH-10243
("target_win_version", "Targeted Windows version, >= 0x0601 (Windows 7)", "0x0601"),
- EnumVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", "yes", ("yes", "no")),
+ BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
EnumVariable("windows_subsystem", "Windows subsystem", "default", ("default", "console", "gui")),
BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
("msvc_version", "MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.", None),
@@ -204,12 +204,12 @@ def configure_msvc(env, manual_msvc_config):
env.Append(LINKFLAGS=["/OPT:REF"])
elif env["target"] == "debug":
- env.AppendUnique(CCFLAGS=["/Z7", "/Od", "/EHsc"])
+ env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"])
env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["/DEBUG"])
- if env["debug_symbols"] == "yes":
- env.AppendUnique(CCFLAGS=["/Z7"])
+ if env["debug_symbols"]:
+ env.AppendUnique(CCFLAGS=["/Zi", "/FS"])
env.AppendUnique(LINKFLAGS=["/DEBUG"])
if env["windows_subsystem"] == "gui":
@@ -224,6 +224,7 @@ def configure_msvc(env, manual_msvc_config):
env.AppendUnique(CCFLAGS=["/MT"])
else:
env.AppendUnique(CCFLAGS=["/MD"])
+
env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"])
# Force to use Unicode encoding
env.AppendUnique(CCFLAGS=["/utf-8"])
@@ -339,13 +340,13 @@ def configure_mingw(env):
else: # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "release_debug":
env.Append(CCFLAGS=["-O2"])
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
- if env["debug_symbols"] == "yes":
+ if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
if env["optimize"] == "speed": # optimize for speed (default)
env.Append(CCFLAGS=["-O2"])
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 520b43f963..b9b78f7bd4 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -535,7 +535,7 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
}
#endif
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[p_window].wtctx) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window].wtctx) {
wintab_WTClose(windows[p_window].wtctx);
windows[p_window].wtctx = 0;
}
@@ -903,6 +903,9 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre
r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
}
}
+ if (!p_borderless) {
+ r_style |= WS_VISIBLE;
+ }
if (p_no_activate_focus) {
r_style_ex |= WS_EX_TOPMOST | WS_EX_NOACTIVATE;
@@ -910,7 +913,7 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre
r_style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
}
-void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repaint, bool p_maximized) {
+void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repaint) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -943,6 +946,7 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
RECT rect;
wd.fullscreen = false;
+ wd.maximized = wd.was_maximized;
if (wd.pre_fs_valid) {
rect = wd.pre_fs_rect;
@@ -951,13 +955,16 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
rect.right = wd.width;
rect.top = 0;
rect.bottom = wd.height;
+ wd.pre_fs_valid = true;
}
- _update_window_style(p_window, false, wd.was_maximized);
+ _update_window_style(p_window, false);
MoveWindow(wd.hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
-
- wd.pre_fs_valid = true;
+ } else if (p_mode == WINDOW_MODE_WINDOWED) {
+ ShowWindow(wd.hWnd, SW_RESTORE);
+ wd.maximized = false;
+ wd.minimized = false;
}
if (p_mode == WINDOW_MODE_MAXIMIZED) {
@@ -966,12 +973,6 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
wd.minimized = false;
}
- if (p_mode == WINDOW_MODE_WINDOWED) {
- ShowWindow(wd.hWnd, SW_RESTORE);
- wd.maximized = false;
- wd.minimized = false;
- }
-
if (p_mode == WINDOW_MODE_MINIMIZED) {
ShowWindow(wd.hWnd, SW_MINIMIZE);
wd.maximized = false;
@@ -1783,7 +1784,10 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
Ref<InputEventFromWindow> event_from_window = p_event;
if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) {
//send to a window
- ERR_FAIL_COND(!windows.has(event_from_window->get_window_id()));
+ if (!windows.has(event_from_window->get_window_id())) {
+ in_dispatch_input_event = false;
+ ERR_FAIL_MSG("DisplayServerWindows: Invalid window id in input event.");
+ }
Callable callable = windows[event_from_window->get_window_id()].input_event_callback;
if (callable.is_null()) {
in_dispatch_input_event = false;
@@ -1875,27 +1879,16 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
- case WM_ACTIVATE: // Watch For Window Activate Message
- {
- windows[window_id].minimized = HIWORD(wParam) != 0;
-
- if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) {
- _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN);
- windows[window_id].window_focused = true;
- alt_mem = false;
- control_mem = false;
- shift_mem = false;
- } else { // WM_INACTIVE
- Input::get_singleton()->release_pressed_events();
- _send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT);
- windows[window_id].window_focused = false;
- alt_mem = false;
- };
+ case WM_ACTIVATE: { // Watch For Window Activate Message
+ if (!windows[window_id].window_focused) {
+ _process_activate_event(window_id, wParam, lParam);
+ } else {
+ windows[window_id].saved_wparam = wParam;
+ windows[window_id].saved_lparam = lParam;
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
- wintab_WTEnable(windows[window_id].wtctx, GET_WM_ACTIVATE_STATE(wParam, lParam));
+ // Run a timer to prevent event catching warning if the focused window is closing.
+ windows[window_id].focus_timer_id = SetTimer(windows[window_id].hWnd, 2, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
}
-
return 0; // Return To The Message Loop
}
case WM_GETMINMAXINFO: {
@@ -1936,6 +1929,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_CLOSE: // Did We Receive A Close Message?
{
+ if (windows[window_id].focus_timer_id != 0U) {
+ KillTimer(windows[window_id].hWnd, windows[window_id].focus_timer_id);
+ }
_send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST);
return 0; // Jump Back
@@ -2025,7 +2021,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WT_CSRCHANGE:
case WT_PROXIMITY: {
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
AXIS pressure;
if (wintab_WTInfo(WTI_DEVICES + windows[window_id].wtlc.lcDevice, DVC_NPRESSURE, &pressure)) {
windows[window_id].min_pressure = int(pressure.axMin);
@@ -2039,7 +2035,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
} break;
case WT_PACKET: {
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
PACKET packet;
if (wintab_WTPacket(windows[window_id].wtctx, wParam, &packet)) {
float pressure = float(packet.pkNormalPressure - windows[window_id].min_pressure) / float(windows[window_id].max_pressure - windows[window_id].min_pressure);
@@ -2118,7 +2114,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
- if ((OS::get_singleton()->get_current_tablet_driver() != "winink") || !winink_available) {
+ if ((tablet_get_current_driver() != "winink") || !winink_available) {
break;
}
@@ -2144,7 +2140,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
- if ((OS::get_singleton()->get_current_tablet_driver() != "winink") || !winink_available) {
+ if ((tablet_get_current_driver() != "winink") || !winink_available) {
break;
}
@@ -2308,7 +2304,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_shift((wParam & MK_SHIFT) != 0);
mm->set_alt(alt_mem);
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
// Note: WinTab sends both WT_PACKET and WM_xBUTTONDOWN/UP/MOUSEMOVE events, use mouse 1/0 pressure only when last_pressure was not update recently.
if (windows[window_id].last_pressure_update < 10) {
windows[window_id].last_pressure_update++;
@@ -2618,17 +2614,21 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_ENTERSIZEMOVE: {
Input::get_singleton()->release_pressed_events();
- move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
+ windows[window_id].move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
} break;
case WM_EXITSIZEMOVE: {
- KillTimer(windows[window_id].hWnd, move_timer_id);
+ KillTimer(windows[window_id].hWnd, windows[window_id].move_timer_id);
} break;
case WM_TIMER: {
- if (wParam == move_timer_id) {
+ if (wParam == windows[window_id].move_timer_id) {
_process_key_events();
if (!Main::is_iterating()) {
Main::iteration();
}
+ } else if (wParam == windows[window_id].focus_timer_id) {
+ _process_activate_event(window_id, windows[window_id].saved_wparam, windows[window_id].saved_lparam);
+ KillTimer(windows[window_id].hWnd, wParam);
+ windows[window_id].focus_timer_id = 0U;
}
} break;
@@ -2785,6 +2785,25 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
+void DisplayServerWindows::_process_activate_event(WindowID p_window_id, WPARAM wParam, LPARAM lParam) {
+ if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) {
+ _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_IN);
+ windows[p_window_id].window_focused = true;
+ alt_mem = false;
+ control_mem = false;
+ shift_mem = false;
+ } else { // WM_INACTIVE
+ Input::get_singleton()->release_pressed_events();
+ _send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_OUT);
+ windows[p_window_id].window_focused = false;
+ alt_mem = false;
+ }
+
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window_id].wtctx) {
+ wintab_WTEnable(windows[p_window_id].wtctx, GET_WM_ACTIVATE_STATE(wParam, lParam));
+ }
+}
+
void DisplayServerWindows::_process_key_events() {
for (int i = 0; i < key_event_pos; i++) {
KeyEvent &ke = key_event_buffer[i];
@@ -2992,6 +3011,9 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
windows.erase(id);
return INVALID_WINDOW_ID;
}
+ if (p_mode != WINDOW_MODE_FULLSCREEN) {
+ wd.pre_fs_valid = true;
+ }
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
@@ -3015,7 +3037,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
DragAcceptFiles(wd.hWnd, true);
- if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available) {
+ if ((tablet_get_current_driver() == "wintab") && wintab_available) {
wintab_WTInfo(WTI_DEFSYSCTX, 0, &wd.wtlc);
wd.wtlc.lcOptions |= CXO_MESSAGES;
wd.wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
@@ -3082,6 +3104,40 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS {
SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2
} SHC_PROCESS_DPI_AWARENESS;
+int DisplayServerWindows::tablet_get_driver_count() const {
+ return tablet_drivers.size();
+}
+
+String DisplayServerWindows::tablet_get_driver_name(int p_driver) const {
+ if (p_driver < 0 || p_driver >= tablet_drivers.size()) {
+ return "";
+ } else {
+ return tablet_drivers[p_driver];
+ }
+}
+
+String DisplayServerWindows::tablet_get_current_driver() const {
+ return tablet_driver;
+}
+
+void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) {
+ if (tablet_get_driver_count() == 0) {
+ return;
+ }
+ bool found = false;
+ for (int i = 0; i < tablet_get_driver_count(); i++) {
+ if (p_driver == tablet_get_driver_name(i)) {
+ found = true;
+ }
+ }
+ if (found) {
+ _update_tablet_ctx(tablet_driver, p_driver);
+ tablet_driver = p_driver;
+ } else {
+ ERR_PRINT("Unknown tablet driver " + p_driver + ".");
+ }
+}
+
DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
drop_events = false;
key_event_pos = 0;
@@ -3100,6 +3156,35 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
outside = true;
+ //Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
+ HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
+ if (wintab_lib) {
+ wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW");
+ wintab_WTClose = (WTClosePtr)GetProcAddress(wintab_lib, "WTClose");
+ wintab_WTInfo = (WTInfoPtr)GetProcAddress(wintab_lib, "WTInfoW");
+ wintab_WTPacket = (WTPacketPtr)GetProcAddress(wintab_lib, "WTPacket");
+ wintab_WTEnable = (WTEnablePtr)GetProcAddress(wintab_lib, "WTEnable");
+
+ wintab_available = wintab_WTOpen && wintab_WTClose && wintab_WTInfo && wintab_WTPacket && wintab_WTEnable;
+ }
+
+ if (wintab_available) {
+ tablet_drivers.push_back("wintab");
+ }
+
+ //Note: Windows Ink API for pen input, available on Windows 8+ only.
+ HMODULE user32_lib = LoadLibraryW(L"user32.dll");
+ if (user32_lib) {
+ win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
+ win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
+
+ winink_available = win8p_GetPointerType && win8p_GetPointerPenInfo;
+ }
+
+ if (winink_available) {
+ tablet_drivers.push_back("winink");
+ }
+
if (OS::get_singleton()->is_hidpi_allowed()) {
HMODULE Shcore = LoadLibraryW(L"Shcore.dll");
@@ -3209,8 +3294,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
#endif
- move_timer_id = 1;
-
//set_ime_active(false);
if (!OS::get_singleton()->is_in_low_processor_usage_mode()) {
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 684746919a..a734077e59 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -264,7 +264,6 @@ class DisplayServerWindows : public DisplayServer {
_THREAD_SAFE_CLASS_
-public:
// WinTab API
static bool wintab_available;
static WTOpenPtr wintab_WTOpen;
@@ -279,8 +278,9 @@ public:
static GetPointerPenInfoPtr win8p_GetPointerPenInfo;
void _update_tablet_ctx(const String &p_old_driver, const String &p_new_driver);
+ String tablet_driver;
+ Vector<String> tablet_drivers;
-private:
void GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap);
enum {
@@ -339,6 +339,14 @@ private:
bool no_focus = false;
bool window_has_focus = false;
+ // Used to transfer data between events using timer.
+ WPARAM saved_wparam;
+ LPARAM saved_lparam;
+
+ // Timers.
+ uint32_t move_timer_id = 0U;
+ uint32_t focus_timer_id = 0U;
+
HANDLE wtctx;
LOGCONTEXTW wtlc;
int min_pressure;
@@ -387,8 +395,6 @@ private:
WindowID last_focused_window = INVALID_WINDOW_ID;
- uint32_t move_timer_id;
-
HCURSOR hCursor;
WNDPROC user_proc = nullptr;
@@ -411,19 +417,20 @@ private:
WNDCLASSEXW wc;
HCURSOR cursors[CURSOR_MAX] = { nullptr };
- CursorShape cursor_shape;
+ CursorShape cursor_shape = CursorShape::CURSOR_ARROW;
Map<CursorShape, Vector<Variant>> cursors_cache;
void _drag_event(WindowID p_window, float p_x, float p_y, int idx);
void _touch_event(WindowID p_window, bool p_pressed, float p_x, float p_y, int idx);
- void _update_window_style(WindowID p_window, bool p_repaint = true, bool p_maximized = false);
+ void _update_window_style(WindowID p_window, bool p_repaint = true);
void _update_window_mouse_passthrough(WindowID p_window);
void _update_real_mouse_position(WindowID p_window);
void _set_mouse_mode_impl(MouseMode p_mode);
+ void _process_activate_event(WindowID p_window_id, WPARAM wParam, LPARAM lParam);
void _process_key_events();
static void _dispatch_input_events(const Ref<InputEvent> &p_event);
@@ -535,6 +542,11 @@ public:
virtual String keyboard_get_layout_language(int p_index) const;
virtual String keyboard_get_layout_name(int p_index) const;
+ virtual int tablet_get_driver_count() const;
+ virtual String tablet_get_driver_name(int p_driver) const;
+ virtual String tablet_get_current_driver() const;
+ virtual void tablet_set_current_driver(const String &p_driver);
+
virtual void process_events();
virtual void force_process_and_drop_events();
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index c2436e8b64..222597b3ff 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -173,11 +173,11 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset>
}
#ifdef WINDOWS_ENABLED
- OS::get_singleton()->execute(rcedit_path, args, true);
+ OS::get_singleton()->execute(rcedit_path, args);
#else
// On non-Windows we need WINE to run rcedit
args.push_front(rcedit_path);
- OS::get_singleton()->execute(wine_path, args, true);
+ OS::get_singleton()->execute(wine_path, args);
#endif
}
@@ -299,7 +299,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
PackedStringArray user_args = p_preset->get("codesign/custom_options");
for (int i = 0; i < user_args.size(); i++) {
String user_arg = user_args[i].strip_edges();
- if (!user_arg.empty()) {
+ if (!user_arg.is_empty()) {
args.push_back(user_arg);
}
}
@@ -314,7 +314,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
#endif
String str;
- Error err = OS::get_singleton()->execute(signtool_path, args, true, nullptr, &str, nullptr, true);
+ Error err = OS::get_singleton()->execute(signtool_path, args, &str, nullptr, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("codesign (" + p_path + "): " + str);
diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h
index d669192831..6a7131c73f 100644
--- a/platform/windows/export/export.h
+++ b/platform/windows/export/export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis
index 1f625cfb77..857c6a88f1 100644
--- a/platform/windows/godot.natvis
+++ b/platform/windows/godot.natvis
@@ -10,12 +10,12 @@
</Expand>
</Type>
- <Type Name="PoolVector&lt;*&gt;">
+ <Type Name="LocalVector&lt;*&gt;">
<Expand>
- <Item Name="[size]">alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Item>
+ <Item Name="[size]">count</Item>
<ArrayItems>
- <Size>alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Size>
- <ValuePointer>alloc ? (($T1 *)alloc-&gt;mem) : 0</ValuePointer>
+ <Size>count</Size>
+ <ValuePointer>data</ValuePointer>
</ArrayItems>
</Expand>
</Type>
@@ -36,7 +36,7 @@
<DisplayString Condition="type == Variant::NIL">nil</DisplayString>
<DisplayString Condition="type == Variant::BOOL">{_data._bool}</DisplayString>
<DisplayString Condition="type == Variant::INT">{_data._int}</DisplayString>
- <DisplayString Condition="type == Variant::REAL">{_data._real}</DisplayString>
+ <DisplayString Condition="type == Variant::FLOAT">{_data._float}</DisplayString>
<DisplayString Condition="type == Variant::TRANSFORM2D">{_data._transform2d}</DisplayString>
<DisplayString Condition="type == Variant::AABB">{_data._aabb}</DisplayString>
<DisplayString Condition="type == Variant::BASIS">{_data._basis}</DisplayString>
@@ -49,24 +49,26 @@
<DisplayString Condition="type == Variant::QUAT">{*(Quat *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::NODE_PATH">{*(NodePath *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::RID">{*(RID *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::RID">{*(::RID *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::OBJECT">{*(Object *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::DICTIONARY">{*(Dictionary *)_data._mem}</DisplayString>
<DisplayString Condition="type == Variant::ARRAY">{*(Array *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_BYTE_ARRAY">{*(PoolByteArray *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_INT_ARRAY">{*(PoolIntArray *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_REAL_ARRAY">{*(PoolRealArray *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_STRING_ARRAY">{*(PoolStringArray *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_VECTOR2_ARRAY">{*(PoolVector2Array *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_VECTOR3_ARRAY">{*(PoolVector3Array *)_data._mem}</DisplayString>
- <DisplayString Condition="type == Variant::POOL_COLOR_ARRAY">{*(PoolColorArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_BYTE_ARRAY">{*(PackedByteArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_INT32_ARRAY">{*(PackedInt32Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_INT64_ARRAY">{*(PackedInt64Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_FLOAT32_ARRAY">{*(PackedFloat32Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_FLOAT64_ARRAY">{*(PackedFloat64Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_STRING_ARRAY">{*(PackedStringArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_VECTOR2_ARRAY">{*(PackedVector2Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_VECTOR3_ARRAY">{*(PackedVector3Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PACKED_COLOR_ARRAY">{*(PackedColorArray *)_data._mem}</DisplayString>
- <StringView Condition="type == Variant::STRING &amp;&amp; ((String *)(_data._mem))->_cowdata._ptr">((String *)(_data._mem))->_cowdata._ptr,su</StringView>
+ <StringView Condition="type == Variant::STRING &amp;&amp; ((String *)(_data._mem))->_cowdata._ptr">((String *)(_data._mem))->_cowdata._ptr,s32</StringView>
<Expand>
<Item Name="[value]" Condition="type == Variant::BOOL">_data._bool</Item>
<Item Name="[value]" Condition="type == Variant::INT">_data._int</Item>
- <Item Name="[value]" Condition="type == Variant::REAL">_data._real</Item>
+ <Item Name="[value]" Condition="type == Variant::FLOAT">_data._float</Item>
<Item Name="[value]" Condition="type == Variant::TRANSFORM2D">_data._transform2d</Item>
<Item Name="[value]" Condition="type == Variant::AABB">_data._aabb</Item>
<Item Name="[value]" Condition="type == Variant::BASIS">_data._basis</Item>
@@ -79,32 +81,34 @@
<Item Name="[value]" Condition="type == Variant::QUAT">*(Quat *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::COLOR">*(Color *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::NODE_PATH">*(NodePath *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::RID">*(RID *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::RID">*(::RID *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::OBJECT">*(Object *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::DICTIONARY">*(Dictionary *)_data._mem</Item>
<Item Name="[value]" Condition="type == Variant::ARRAY">*(Array *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_BYTE_ARRAY">*(PoolByteArray *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_INT_ARRAY">*(PoolIntArray *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_REAL_ARRAY">*(PoolRealArray *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_STRING_ARRAY">*(PoolStringArray *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_VECTOR2_ARRAY">*(PoolVector2Array *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_VECTOR3_ARRAY">*(PoolVector3Array *)_data._mem</Item>
- <Item Name="[value]" Condition="type == Variant::POOL_COLOR_ARRAY">*(PoolColorArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_BYTE_ARRAY">*(PackedByteArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_INT32_ARRAY">*(PackedInt32Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_INT64_ARRAY">*(PackedInt64Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_FLOAT32_ARRAY">*(PackedFloat32Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_FLOAT64_ARRAY">*(PackedFloat64Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_STRING_ARRAY">*(PackedStringArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_VECTOR2_ARRAY">*(PackedVector2Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_VECTOR3_ARRAY">*(PackedVector3Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PACKED_COLOR_ARRAY">*(PackedColorArray *)_data._mem</Item>
</Expand>
</Type>
<Type Name="String">
<DisplayString Condition="_cowdata._ptr == 0">[empty]</DisplayString>
- <DisplayString Condition="_cowdata._ptr != 0">{_cowdata._ptr,su}</DisplayString>
- <StringView Condition="_cowdata._ptr != 0">_cowdata._ptr,su</StringView>
+ <DisplayString Condition="_cowdata._ptr != 0">{_cowdata._ptr,s32}</DisplayString>
+ <StringView Condition="_cowdata._ptr != 0">_cowdata._ptr,s32</StringView>
</Type>
<Type Name="StringName">
<DisplayString Condition="_data &amp;&amp; _data->cname">{_data->cname}</DisplayString>
- <DisplayString Condition="_data &amp;&amp; !_data->cname">{_data->name,su}</DisplayString>
+ <DisplayString Condition="_data &amp;&amp; !_data->cname">{_data->name,s32}</DisplayString>
<DisplayString Condition="!_data">[empty]</DisplayString>
<StringView Condition="_data &amp;&amp; _data->cname">_data->cname</StringView>
- <StringView Condition="_data &amp;&amp; !_data->cname">_data->name,su</StringView>
+ <StringView Condition="_data &amp;&amp; !_data->cname">_data->name,s32</StringView>
</Type>
<Type Name="Vector2">
diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp
index add559a717..22e2e5f7e5 100644
--- a/platform/windows/godot_windows.cpp
+++ b/platform/windows/godot_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp
index ae5e846dac..f46a0dbe2e 100644
--- a/platform/windows/joypad_windows.cpp
+++ b/platform/windows/joypad_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h
index 08adc6b663..4727b4a14c 100644
--- a/platform/windows/joypad_windows.h
+++ b/platform/windows/joypad_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp
index 25eff7df57..3312c91932 100644
--- a/platform/windows/key_mapping_windows.cpp
+++ b/platform/windows/key_mapping_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h
index f64f1feb9f..fb07227014 100644
--- a/platform/windows/key_mapping_windows.h
+++ b/platform/windows/key_mapping_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/lang_table.h b/platform/windows/lang_table.h
index f81bab13a4..51583cc11e 100644
--- a/platform/windows/lang_table.h
+++ b/platform/windows/lang_table.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 451f3bf18c..3280a36e9b 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,15 +39,12 @@
#include "core/version_generated.gen.h"
#include "drivers/windows/dir_access_windows.h"
#include "drivers/windows/file_access_windows.h"
-#include "drivers/windows/rw_lock_windows.h"
-#include "drivers/windows/thread_windows.h"
#include "joypad_windows.h"
#include "lang_table.h"
#include "main/main.h"
#include "platform/windows/display_server_windows.h"
#include "servers/audio_server.h"
#include "servers/rendering/rendering_server_default.h"
-#include "servers/rendering/rendering_server_wrap_mt.h"
#include "windows_terminal_logger.h"
#include <avrt.h>
@@ -177,9 +174,6 @@ void OS_Windows::initialize() {
//RedirectIOToConsole();
- ThreadWindows::make_default();
- RWLockWindows::make_default();
-
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
@@ -410,24 +404,23 @@ String OS_Windows::_quote_command_line_argument(const String &p_text) const {
return p_text;
}
-Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
String path = p_path.replace("/", "\\");
+ String command = _quote_command_line_argument(path);
+ for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
+ command += " " + _quote_command_line_argument(E->get());
+ }
- if (p_blocking && r_pipe) {
- String argss = _quote_command_line_argument(path);
- for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
- argss += " " + _quote_command_line_argument(E->get());
- }
-
+ if (r_pipe) {
if (read_stderr) {
- argss += " 2>&1"; // Read stderr too
+ command += " 2>&1"; // Include stderr
}
- // Note: _wpopen is calling command as "cmd.exe /c argss", instead of executing it directly, add extra quotes around full command, to prevent it from stripping quotes in the command.
- argss = _quote_command_line_argument(argss);
-
- FILE *f = _wpopen((LPCWSTR)(argss.utf16().get_data()), L"r");
- ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ // Add extra quotes around the full command, to prevent it from stripping quotes in the command,
+ // because _wpopen calls command as "cmd.exe /c command", instead of executing it directly
+ command = _quote_command_line_argument(command);
+ FILE *f = _wpopen((LPCWSTR)(command.utf16().get_data()), L"r");
+ ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot create pipe from command: " + command);
char buf[65535];
while (fgets(buf, 65535, f)) {
if (p_pipe_mutex) {
@@ -438,20 +431,40 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
p_pipe_mutex->unlock();
}
}
-
int rv = _pclose(f);
+
if (r_exitcode) {
*r_exitcode = rv;
}
-
return OK;
}
- String cmdline = _quote_command_line_argument(path);
- const List<String>::Element *I = p_arguments.front();
- while (I) {
- cmdline += " " + _quote_command_line_argument(I->get());
- I = I->next();
+ ProcessInfo pi;
+ ZeroMemory(&pi.si, sizeof(pi.si));
+ pi.si.cb = sizeof(pi.si);
+ ZeroMemory(&pi.pi, sizeof(pi.pi));
+ LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
+
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
+
+ WaitForSingleObject(pi.pi.hProcess, INFINITE);
+ if (r_exitcode) {
+ DWORD ret2;
+ GetExitCodeProcess(pi.pi.hProcess, &ret2);
+ *r_exitcode = ret2;
+ }
+ CloseHandle(pi.pi.hProcess);
+ CloseHandle(pi.pi.hThread);
+
+ return OK;
+};
+
+Error OS_Windows::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) {
+ String path = p_path.replace("/", "\\");
+ String command = _quote_command_line_argument(path);
+ for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
+ command += " " + _quote_command_line_argument(E->get());
}
ProcessInfo pi;
@@ -460,27 +473,15 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- Char16String modstr = cmdline.utf16(); // Windows wants to change this no idea why.
- int ret = CreateProcessW(nullptr, (LPWSTR)(modstr.ptrw()), nullptr, nullptr, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
- ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK);
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
+ ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
- if (p_blocking) {
- WaitForSingleObject(pi.pi.hProcess, INFINITE);
- if (r_exitcode) {
- DWORD ret2;
- GetExitCodeProcess(pi.pi.hProcess, &ret2);
- *r_exitcode = ret2;
- }
-
- CloseHandle(pi.pi.hProcess);
- CloseHandle(pi.pi.hThread);
- } else {
- ProcessID pid = pi.pi.dwProcessId;
- if (r_child_id) {
- *r_child_id = pid;
- }
- process_map->insert(pid, pi);
+ ProcessID pid = pi.pi.dwProcessId;
+ if (r_child_id) {
+ *r_child_id = pid;
}
+ process_map->insert(pid, pi);
+
return OK;
};
@@ -614,7 +615,7 @@ void OS_Windows::run() {
if (!main_loop)
return;
- main_loop->init();
+ main_loop->initialize();
while (!force_quit) {
DisplayServer::get_singleton()->process_events(); // get rid of pending events
@@ -622,7 +623,7 @@ void OS_Windows::run() {
break;
};
- main_loop->finish();
+ main_loop->finalize();
}
MainLoop *OS_Windows::get_main_loop() const {
@@ -764,77 +765,12 @@ Error OS_Windows::move_to_trash(const String &p_path) {
return OK;
}
-int OS_Windows::get_tablet_driver_count() const {
- return tablet_drivers.size();
-}
-
-String OS_Windows::get_tablet_driver_name(int p_driver) const {
- if (p_driver < 0 || p_driver >= tablet_drivers.size()) {
- return "";
- } else {
- return tablet_drivers[p_driver];
- }
-}
-
-String OS_Windows::get_current_tablet_driver() const {
- return tablet_driver;
-}
-
-void OS_Windows::set_current_tablet_driver(const String &p_driver) {
- if (get_tablet_driver_count() == 0) {
- return;
- }
- bool found = false;
- for (int i = 0; i < get_tablet_driver_count(); i++) {
- if (p_driver == get_tablet_driver_name(i)) {
- found = true;
- }
- }
- if (found) {
- if (DisplayServerWindows::get_singleton()) {
- ((DisplayServerWindows *)DisplayServerWindows::get_singleton())->_update_tablet_ctx(tablet_driver, p_driver);
- }
- tablet_driver = p_driver;
- } else {
- ERR_PRINT("Unknown tablet driver " + p_driver + ".");
- }
-}
-
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
ticks_per_second = 0;
ticks_start = 0;
main_loop = nullptr;
process_map = nullptr;
- //Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
- HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
- if (wintab_lib) {
- DisplayServerWindows::wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW");
- DisplayServerWindows::wintab_WTClose = (WTClosePtr)GetProcAddress(wintab_lib, "WTClose");
- DisplayServerWindows::wintab_WTInfo = (WTInfoPtr)GetProcAddress(wintab_lib, "WTInfoW");
- DisplayServerWindows::wintab_WTPacket = (WTPacketPtr)GetProcAddress(wintab_lib, "WTPacket");
- DisplayServerWindows::wintab_WTEnable = (WTEnablePtr)GetProcAddress(wintab_lib, "WTEnable");
-
- DisplayServerWindows::wintab_available = DisplayServerWindows::wintab_WTOpen && DisplayServerWindows::wintab_WTClose && DisplayServerWindows::wintab_WTInfo && DisplayServerWindows::wintab_WTPacket && DisplayServerWindows::wintab_WTEnable;
- }
-
- if (DisplayServerWindows::wintab_available) {
- tablet_drivers.push_back("wintab");
- }
-
- //Note: Windows Ink API for pen input, available on Windows 8+ only.
- HMODULE user32_lib = LoadLibraryW(L"user32.dll");
- if (user32_lib) {
- DisplayServerWindows::win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
- DisplayServerWindows::win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
-
- DisplayServerWindows::winink_available = DisplayServerWindows::win8p_GetPointerType && DisplayServerWindows::win8p_GetPointerPenInfo;
- }
-
- if (DisplayServerWindows::winink_available) {
- tablet_drivers.push_back("winink");
- }
-
force_quit = false;
hInstance = _hInstance;
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 14d09d2b35..8f9ef254f1 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -73,9 +73,6 @@ class OS_Windows : public OS {
HINSTANCE hInstance;
MainLoop *main_loop;
- String tablet_driver;
- Vector<String> tablet_drivers;
-
#ifdef WASAPI_ENABLED
AudioDriverWASAPI driver_wasapi;
#endif
@@ -119,11 +116,6 @@ public:
virtual String get_name() const override;
- virtual int get_tablet_driver_count() const override;
- virtual String get_tablet_driver_name(int p_driver) const override;
- virtual String get_current_tablet_driver() const override;
- virtual void set_current_tablet_driver(const String &p_driver) override;
-
virtual void initialize_joypads() override {}
virtual Date get_date(bool utc) const override;
@@ -136,7 +128,8 @@ public:
virtual void delay_usec(uint32_t p_usec) const override;
virtual uint64_t get_ticks_usec() const override;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr) override;
+ virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
virtual Error kill(const ProcessID &p_pid) override;
virtual int get_process_id() const override;
diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h
index 09a16614e0..481f583f6f 100644
--- a/platform/windows/platform_config.h
+++ b/platform/windows/platform_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/vulkan_context_win.cpp b/platform/windows/vulkan_context_win.cpp
index 2c63281c49..e5e176ab93 100644
--- a/platform/windows/vulkan_context_win.cpp
+++ b/platform/windows/vulkan_context_win.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h
index 6e80db0286..4fe987218d 100644
--- a/platform/windows/vulkan_context_win.h
+++ b/platform/windows/vulkan_context_win.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
index 0938b65b04..56b620a6d9 100644
--- a/platform/windows/windows_terminal_logger.cpp
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h
index d4443a707d..aacfe5869e 100644
--- a/platform/windows/windows_terminal_logger.h
+++ b/platform/windows/windows_terminal_logger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index 0f98fad824..f39850441b 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -409,7 +409,7 @@ void AnimatedSprite2D::_notification(int p_what) {
}
update();
- _change_notify("frame");
+
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -477,7 +477,7 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
set_frame(frame);
}
- _change_notify();
+ notify_property_list_changed();
_reset_timeout();
update();
update_configuration_warning();
@@ -510,7 +510,7 @@ void AnimatedSprite2D::set_frame(int p_frame) {
frame = p_frame;
_reset_timeout();
update();
- _change_notify("frame");
+
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -546,7 +546,6 @@ void AnimatedSprite2D::set_offset(const Point2 &p_offset) {
offset = p_offset;
update();
item_rect_changed();
- _change_notify("offset");
}
Point2 AnimatedSprite2D::get_offset() const {
@@ -573,8 +572,7 @@ bool AnimatedSprite2D::is_flipped_v() const {
void AnimatedSprite2D::_res_changed() {
set_frame(frame);
- _change_notify("frame");
- _change_notify("animation");
+
update();
}
@@ -642,7 +640,7 @@ void AnimatedSprite2D::set_animation(const StringName &p_animation) {
animation = p_animation;
_reset_timeout();
set_frame(0);
- _change_notify();
+ notify_property_list_changed();
update();
}
@@ -654,7 +652,7 @@ String AnimatedSprite2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (frames.is_null()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames.");
@@ -712,15 +710,4 @@ void AnimatedSprite2D::_bind_methods() {
}
AnimatedSprite2D::AnimatedSprite2D() {
- centered = true;
- hflip = false;
- vflip = false;
-
- frame = 0;
- speed_scale = 1.0f;
- playing = false;
- backwards = false;
- animation = "default";
- timeout = 0;
- is_over = false;
}
diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h
index fddbf39be2..5e53a401e2 100644
--- a/scene/2d/animated_sprite_2d.h
+++ b/scene/2d/animated_sprite_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,14 +38,9 @@ class SpriteFrames : public Resource {
GDCLASS(SpriteFrames, Resource);
struct Anim {
- float speed;
- bool loop;
+ float speed = 5.0;
+ bool loop = true;
Vector<Ref<Texture2D>> frames;
-
- Anim() {
- loop = true;
- speed = 5;
- }
};
Map<StringName, Anim> animations;
@@ -109,20 +104,20 @@ class AnimatedSprite2D : public Node2D {
GDCLASS(AnimatedSprite2D, Node2D);
Ref<SpriteFrames> frames;
- bool playing;
- bool backwards;
- StringName animation;
- int frame;
- float speed_scale;
+ bool playing = false;
+ bool backwards = false;
+ StringName animation = "default";
+ int frame = 0;
+ float speed_scale = 1.0f;
- bool centered;
+ bool centered = true;
Point2 offset;
- bool is_over;
- float timeout;
+ bool is_over = false;
+ float timeout = 0.0;
- bool hflip;
- bool vflip;
+ bool hflip = false;
+ bool vflip = false;
void _res_changed();
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index d51ee3f9a8..49d1654e3f 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -590,13 +590,13 @@ void Area2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout);
ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout);
- ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
- ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
- ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
- ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
+ ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
+ ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
- ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
- ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
+ ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D")));
ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D")));
@@ -627,20 +627,8 @@ void Area2D::_bind_methods() {
Area2D::Area2D() :
CollisionObject2D(PhysicsServer2D::get_singleton()->area_create(), true) {
- space_override = SPACE_OVERRIDE_DISABLED;
set_gravity(98);
set_gravity_vector(Vector2(0, 1));
- gravity_is_point = false;
- gravity_distance_scale = 0;
- linear_damp = 0.1;
- angular_damp = 1;
- locked = false;
- priority = 0;
- monitoring = false;
- monitorable = false;
- collision_mask = 1;
- collision_layer = 1;
- audio_bus_override = false;
set_monitoring(true);
set_monitorable(true);
}
diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h
index 01426db999..39b022fd2c 100644
--- a/scene/2d/area_2d.h
+++ b/scene/2d/area_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,19 +47,19 @@ public:
};
private:
- SpaceOverride space_override;
+ SpaceOverride space_override = SPACE_OVERRIDE_DISABLED;
Vector2 gravity_vec;
real_t gravity;
- bool gravity_is_point;
- real_t gravity_distance_scale;
- real_t linear_damp;
- real_t angular_damp;
- uint32_t collision_mask;
- uint32_t collision_layer;
- int priority;
- bool monitoring;
- bool monitorable;
- bool locked;
+ bool gravity_is_point = false;
+ real_t gravity_distance_scale = 0.0;
+ real_t linear_damp = 0.1;
+ real_t angular_damp = 1.0;
+ uint32_t collision_mask = 1;
+ uint32_t collision_layer = 1;
+ int priority = 0;
+ bool monitoring = false;
+ bool monitorable = false;
+ bool locked = false;
void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape);
@@ -67,8 +67,8 @@ private:
void _body_exit_tree(ObjectID p_id);
struct ShapePair {
- int body_shape;
- int area_shape;
+ int body_shape = 0;
+ int area_shape = 0;
bool operator<(const ShapePair &p_sp) const {
if (body_shape == p_sp.body_shape) {
return area_shape < p_sp.area_shape;
@@ -85,8 +85,8 @@ private:
};
struct BodyState {
- int rc;
- bool in_tree;
+ int rc = 0;
+ bool in_tree = false;
VSet<ShapePair> shapes;
};
@@ -98,8 +98,8 @@ private:
void _area_exit_tree(ObjectID p_id);
struct AreaShapePair {
- int area_shape;
- int self_shape;
+ int area_shape = 0;
+ int self_shape = 0;
bool operator<(const AreaShapePair &p_sp) const {
if (area_shape == p_sp.area_shape) {
return self_shape < p_sp.self_shape;
@@ -116,15 +116,15 @@ private:
};
struct AreaState {
- int rc;
- bool in_tree;
+ int rc = 0;
+ bool in_tree = false;
VSet<AreaShapePair> shapes;
};
Map<ObjectID, AreaState> area_map;
void _clear_monitoring();
- bool audio_bus_override;
+ bool audio_bus_override = false;
StringName audio_bus;
protected:
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index 9bd716aeaa..6d8d6058eb 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,14 +35,14 @@
#include "scene/main/window.h"
void AudioStreamPlayer2D::_mix_audio() {
- if (!stream_playback.is_valid() || !active ||
+ if (!stream_playback.is_valid() || !active.is_set() ||
(stream_paused && !stream_paused_fade_out)) {
return;
}
- if (setseek >= 0.0) {
- stream_playback->start(setseek);
- setseek = -1.0; //reset seek
+ if (setseek.get() >= 0.0) {
+ stream_playback->start(setseek.get());
+ setseek.set(-1.0); //reset seek
}
//get data
@@ -57,7 +57,8 @@ void AudioStreamPlayer2D::_mix_audio() {
stream_playback->mix(buffer, pitch_scale, buffer_size);
//write all outputs
- for (int i = 0; i < output_count; i++) {
+ int oc = output_count.get();
+ for (int i = 0; i < oc; i++) {
Output current = outputs[i];
//see if current output exists, to keep volume ramp
@@ -130,14 +131,14 @@ void AudioStreamPlayer2D::_mix_audio() {
prev_outputs[i] = current;
}
- prev_output_count = output_count;
+ prev_output_count = oc;
//stream is no longer active, disable this.
if (!stream_playback->is_playing()) {
- active = false;
+ active.clear();
}
- output_ready = false;
+ output_ready.clear();
stream_paused_fade_in = false;
stream_paused_fade_out = false;
}
@@ -168,7 +169,7 @@ void AudioStreamPlayer2D::_notification(int p_what) {
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
//update anything related to position first, if possible of course
- if (!output_ready) {
+ if (!output_ready.is_set()) {
List<Viewport *> viewports;
Ref<World2D> world_2d = get_world_2d();
ERR_FAIL_COND(world_2d.is_null());
@@ -240,24 +241,20 @@ void AudioStreamPlayer2D::_notification(int p_what) {
}
}
- output_count = new_output_count;
- output_ready = true;
+ output_count.set(new_output_count);
+ output_ready.set();
}
//start playing if requested
- if (setplay >= 0.0) {
- setseek = setplay;
- active = true;
- setplay = -1;
- //do not update, this makes it easier to animate (will shut off otherwise)
- //_change_notify("playing"); //update property in editor
+ if (setplay.get() >= 0.0) {
+ setseek.set(setplay.get());
+ active.set();
+ setplay.set(-1);
}
//stop playing if no longer active
- if (!active) {
+ if (!active.is_set()) {
set_physics_process_internal(false);
- //do not update, this makes it easier to animate (will shut off otherwise)
- //_change_notify("playing"); //update property in editor
emit_signal("finished");
}
}
@@ -271,8 +268,8 @@ void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) {
if (stream_playback.is_valid()) {
stream_playback.unref();
stream.unref();
- active = false;
- setseek = -1;
+ active.clear();
+ setseek.set(-1);
}
if (p_stream.is_valid()) {
@@ -315,30 +312,29 @@ void AudioStreamPlayer2D::play(float p_from_pos) {
}
if (stream_playback.is_valid()) {
- active = true;
- setplay = p_from_pos;
- output_ready = false;
+ setplay.set(p_from_pos);
+ output_ready.clear();
set_physics_process_internal(true);
}
}
void AudioStreamPlayer2D::seek(float p_seconds) {
if (stream_playback.is_valid()) {
- setseek = p_seconds;
+ setseek.set(p_seconds);
}
}
void AudioStreamPlayer2D::stop() {
if (stream_playback.is_valid()) {
- active = false;
+ active.clear();
set_physics_process_internal(false);
- setplay = -1;
+ setplay.set(-1);
}
}
bool AudioStreamPlayer2D::is_playing() const {
if (stream_playback.is_valid()) {
- return active; // && stream_playback->is_playing();
+ return active.is_set() || setplay.get() >= 0;
}
return false;
@@ -346,6 +342,10 @@ bool AudioStreamPlayer2D::is_playing() const {
float AudioStreamPlayer2D::get_playback_position() {
if (stream_playback.is_valid()) {
+ float ss = setseek.get();
+ if (ss >= 0.0) {
+ return ss;
+ }
return stream_playback->get_playback_position();
}
@@ -385,7 +385,7 @@ void AudioStreamPlayer2D::_set_playing(bool p_enable) {
}
bool AudioStreamPlayer2D::_is_active() const {
- return active;
+ return active.is_set();
}
void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const {
@@ -404,7 +404,7 @@ void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const {
}
void AudioStreamPlayer2D::_bus_layout_changed() {
- _change_notify();
+ notify_property_list_changed();
}
void AudioStreamPlayer2D::set_max_distance(float p_pixels) {
@@ -503,21 +503,6 @@ void AudioStreamPlayer2D::_bind_methods() {
}
AudioStreamPlayer2D::AudioStreamPlayer2D() {
- volume_db = 0;
- pitch_scale = 1.0;
- autoplay = false;
- setseek = -1;
- active = false;
- output_count = 0;
- prev_output_count = 0;
- max_distance = 2000;
- attenuation = 1;
- setplay = -1;
- output_ready = false;
- area_mask = 1;
- stream_paused = false;
- stream_paused_fade_in = false;
- stream_paused_fade_out = false;
AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer2D::_bus_layout_changed));
}
diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h
index 4e236a367e..21f524c703 100644
--- a/scene/2d/audio_stream_player_2d.h
+++ b/scene/2d/audio_stream_player_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,6 +31,7 @@
#ifndef AUDIO_STREAM_PLAYER_2D_H
#define AUDIO_STREAM_PLAYER_2D_H
+#include "core/templates/safe_refcount.h"
#include "scene/2d/node_2d.h"
#include "servers/audio/audio_stream.h"
#include "servers/audio_server.h"
@@ -47,32 +48,32 @@ private:
struct Output {
AudioFrame vol;
- int bus_index;
- Viewport *viewport; //pointer only used for reference to previous mix
+ int bus_index = 0;
+ Viewport *viewport = nullptr; //pointer only used for reference to previous mix
};
Output outputs[MAX_OUTPUTS];
- volatile int output_count;
- volatile bool output_ready;
+ SafeNumeric<int> output_count;
+ SafeFlag output_ready;
//these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks)
Output prev_outputs[MAX_OUTPUTS];
- int prev_output_count;
+ int prev_output_count = 0;
Ref<AudioStreamPlayback> stream_playback;
Ref<AudioStream> stream;
Vector<AudioFrame> mix_buffer;
- volatile float setseek;
- volatile bool active;
- volatile float setplay;
+ SafeNumeric<float> setseek{ -1.0 };
+ SafeFlag active;
+ SafeNumeric<float> setplay{ -1.0 };
- float volume_db;
- float pitch_scale;
- bool autoplay;
- bool stream_paused;
- bool stream_paused_fade_in;
- bool stream_paused_fade_out;
+ float volume_db = 0.0;
+ float pitch_scale = 1.0;
+ bool autoplay = false;
+ bool stream_paused = false;
+ bool stream_paused_fade_in = false;
+ bool stream_paused_fade_out = false;
StringName bus;
void _mix_audio();
@@ -83,10 +84,10 @@ private:
void _bus_layout_changed();
- uint32_t area_mask;
+ uint32_t area_mask = 1;
- float max_distance;
- float attenuation;
+ float max_distance = 2000.0;
+ float attenuation = 1.0;
protected:
void _validate_property(PropertyInfo &property) const override;
diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp
index a36e0a86e1..539a66b881 100644
--- a/scene/2d/back_buffer_copy.cpp
+++ b/scene/2d/back_buffer_copy.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -93,8 +93,6 @@ void BackBufferCopy::_bind_methods() {
}
BackBufferCopy::BackBufferCopy() {
- rect = Rect2(-100, -100, 200, 200);
- copy_mode = COPY_MODE_RECT;
_update_copy_mode();
}
diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h
index b58034de19..6bdb3aaab2 100644
--- a/scene/2d/back_buffer_copy.h
+++ b/scene/2d/back_buffer_copy.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,8 +44,8 @@ public:
};
private:
- Rect2 rect;
- CopyMode copy_mode;
+ Rect2 rect = Rect2(-100, -100, 200, 200);
+ CopyMode copy_mode = COPY_MODE_RECT;
void _update_copy_mode();
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 2ba9de9e87..9030cc4263 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,11 +63,11 @@ void Camera2D::_update_scroll() {
};
}
-void Camera2D::_update_process_mode() {
+void Camera2D::_update_process_callback() {
if (Engine::get_singleton()->is_editor_hint()) {
set_process_internal(false);
set_physics_process_internal(false);
- } else if (process_mode == CAMERA2D_PROCESS_IDLE) {
+ } else if (process_callback == CAMERA2D_PROCESS_IDLE) {
set_process_internal(true);
set_physics_process_internal(false);
} else {
@@ -104,31 +104,31 @@ Transform2D Camera2D::get_camera_transform() {
if (!first) {
if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) {
- if (h_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !h_offset_changed) {
+ if (drag_horizontal_enabled && !Engine::get_singleton()->is_editor_hint() && !drag_horizontal_offset_changed) {
camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom.x * drag_margin[SIDE_LEFT]));
camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom.x * drag_margin[SIDE_RIGHT]));
} else {
- if (h_ofs < 0) {
- camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_RIGHT] * h_ofs;
+ if (drag_horizontal_offset < 0) {
+ camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_RIGHT] * drag_horizontal_offset;
} else {
- camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_LEFT] * h_ofs;
+ camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_LEFT] * drag_horizontal_offset;
}
- h_offset_changed = false;
+ drag_horizontal_offset_changed = false;
}
- if (v_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !v_offset_changed) {
+ if (drag_vertical_enabled && !Engine::get_singleton()->is_editor_hint() && !drag_vertical_offset_changed) {
camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom.y * drag_margin[SIDE_TOP]));
camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom.y * drag_margin[SIDE_BOTTOM]));
} else {
- if (v_ofs < 0) {
- camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[SIDE_BOTTOM] * v_ofs;
+ if (drag_vertical_offset < 0) {
+ camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[SIDE_BOTTOM] * drag_vertical_offset;
} else {
- camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[SIDE_TOP] * v_ofs;
+ camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[SIDE_TOP] * drag_vertical_offset;
}
- v_offset_changed = false;
+ drag_vertical_offset_changed = false;
}
} else if (anchor_mode == ANCHOR_MODE_FIXED_TOP_LEFT) {
@@ -157,7 +157,7 @@ Transform2D Camera2D::get_camera_transform() {
}
if (smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) {
- float c = smoothing * (process_mode == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
+ float c = smoothing * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos;
ret_camera_pos = smoothed_camera_pos;
//camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing;
@@ -247,7 +247,7 @@ void Camera2D::_notification(int p_what) {
add_to_group(group_name);
add_to_group(canvas_group_name);
- _update_process_mode();
+ _update_process_callback();
_update_scroll();
first = true;
@@ -263,6 +263,7 @@ void Camera2D::_notification(int p_what) {
viewport = nullptr;
} break;
+#ifdef TOOLS_ENABLED
case NOTIFICATION_DRAW: {
if (!is_inside_tree() || !Engine::get_singleton()->is_editor_hint()) {
break;
@@ -339,8 +340,8 @@ void Camera2D::_notification(int p_what) {
draw_line(inv_transform.xform(margin_endpoints[i]), inv_transform.xform(margin_endpoints[(i + 1) % 4]), margin_drawing_color, margin_drawing_width);
}
}
-
} break;
+#endif
}
}
@@ -375,17 +376,17 @@ bool Camera2D::is_rotating() const {
return rotating;
}
-void Camera2D::set_process_mode(Camera2DProcessMode p_mode) {
- if (process_mode == p_mode) {
+void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) {
+ if (process_callback == p_mode) {
return;
}
- process_mode = p_mode;
- _update_process_mode();
+ process_callback = p_mode;
+ _update_process_callback();
}
-Camera2D::Camera2DProcessMode Camera2D::get_process_mode() const {
- return process_mode;
+Camera2D::Camera2DProcessCallback Camera2D::get_process_callback() const {
+ return process_callback;
}
void Camera2D::_make_current(Object *p_which) {
@@ -476,15 +477,15 @@ void Camera2D::align() {
Point2 current_camera_pos = get_global_transform().get_origin();
if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) {
- if (h_ofs < 0) {
- camera_pos.x = current_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_RIGHT] * h_ofs;
+ if (drag_horizontal_offset < 0) {
+ camera_pos.x = current_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_RIGHT] * drag_horizontal_offset;
} else {
- camera_pos.x = current_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_LEFT] * h_ofs;
+ camera_pos.x = current_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_LEFT] * drag_horizontal_offset;
}
- if (v_ofs < 0) {
- camera_pos.y = current_camera_pos.y + screen_size.y * 0.5 * drag_margin[SIDE_TOP] * v_ofs;
+ if (drag_vertical_offset < 0) {
+ camera_pos.y = current_camera_pos.y + screen_size.y * 0.5 * drag_margin[SIDE_TOP] * drag_vertical_offset;
} else {
- camera_pos.y = current_camera_pos.y + screen_size.y * 0.5 * drag_margin[SIDE_BOTTOM] * v_ofs;
+ camera_pos.y = current_camera_pos.y + screen_size.y * 0.5 * drag_margin[SIDE_BOTTOM] * drag_vertical_offset;
}
} else if (anchor_mode == ANCHOR_MODE_FIXED_TOP_LEFT) {
camera_pos = current_camera_pos;
@@ -518,44 +519,44 @@ Size2 Camera2D::_get_camera_screen_size() const {
return get_viewport_rect().size;
}
-void Camera2D::set_h_drag_enabled(bool p_enabled) {
- h_drag_enabled = p_enabled;
+void Camera2D::set_drag_horizontal_enabled(bool p_enabled) {
+ drag_horizontal_enabled = p_enabled;
}
-bool Camera2D::is_h_drag_enabled() const {
- return h_drag_enabled;
+bool Camera2D::is_drag_horizontal_enabled() const {
+ return drag_horizontal_enabled;
}
-void Camera2D::set_v_drag_enabled(bool p_enabled) {
- v_drag_enabled = p_enabled;
+void Camera2D::set_drag_vertical_enabled(bool p_enabled) {
+ drag_vertical_enabled = p_enabled;
}
-bool Camera2D::is_v_drag_enabled() const {
- return v_drag_enabled;
+bool Camera2D::is_drag_vertical_enabled() const {
+ return drag_vertical_enabled;
}
-void Camera2D::set_v_offset(float p_offset) {
- v_ofs = p_offset;
- v_offset_changed = true;
+void Camera2D::set_drag_vertical_offset(float p_offset) {
+ drag_vertical_offset = p_offset;
+ drag_vertical_offset_changed = true;
Point2 old_smoothed_camera_pos = smoothed_camera_pos;
_update_scroll();
smoothed_camera_pos = old_smoothed_camera_pos;
}
-float Camera2D::get_v_offset() const {
- return v_ofs;
+float Camera2D::get_drag_vertical_offset() const {
+ return drag_vertical_offset;
}
-void Camera2D::set_h_offset(float p_offset) {
- h_ofs = p_offset;
- h_offset_changed = true;
+void Camera2D::set_drag_horizontal_offset(float p_offset) {
+ drag_horizontal_offset = p_offset;
+ drag_horizontal_offset_changed = true;
Point2 old_smoothed_camera_pos = smoothed_camera_pos;
_update_scroll();
smoothed_camera_pos = old_smoothed_camera_pos;
}
-float Camera2D::get_h_offset() const {
- return h_ofs;
+float Camera2D::get_drag_horizontal_offset() const {
+ return drag_horizontal_offset;
}
void Camera2D::_set_old_smoothing(float p_enable) {
@@ -568,6 +569,7 @@ void Camera2D::_set_old_smoothing(float p_enable) {
void Camera2D::set_enable_follow_smoothing(bool p_enabled) {
smoothing_enabled = p_enabled;
+ notify_property_list_changed();
}
bool Camera2D::is_follow_smoothing_enabled() const {
@@ -610,7 +612,9 @@ Node *Camera2D::get_custom_viewport() const {
void Camera2D::set_screen_drawing_enabled(bool enable) {
screen_drawing_enabled = enable;
+#ifdef TOOLS_ENABLED
update();
+#endif
}
bool Camera2D::is_screen_drawing_enabled() const {
@@ -619,7 +623,9 @@ bool Camera2D::is_screen_drawing_enabled() const {
void Camera2D::set_limit_drawing_enabled(bool enable) {
limit_drawing_enabled = enable;
+#ifdef TOOLS_ENABLED
update();
+#endif
}
bool Camera2D::is_limit_drawing_enabled() const {
@@ -628,13 +634,21 @@ bool Camera2D::is_limit_drawing_enabled() const {
void Camera2D::set_margin_drawing_enabled(bool enable) {
margin_drawing_enabled = enable;
+#ifdef TOOLS_ENABLED
update();
+#endif
}
bool Camera2D::is_margin_drawing_enabled() const {
return margin_drawing_enabled;
}
+void Camera2D::_validate_property(PropertyInfo &property) const {
+ if (!smoothing_enabled && property.name == "smoothing_speed") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Camera2D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &Camera2D::get_offset);
@@ -651,8 +665,8 @@ void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_scroll"), &Camera2D::_update_scroll);
- ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Camera2D::set_process_mode);
- ClassDB::bind_method(D_METHOD("get_process_mode"), &Camera2D::get_process_mode);
+ ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &Camera2D::set_process_callback);
+ ClassDB::bind_method(D_METHOD("get_process_callback"), &Camera2D::get_process_callback);
ClassDB::bind_method(D_METHOD("_set_current", "current"), &Camera2D::_set_current);
ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current);
@@ -663,17 +677,17 @@ void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_limit_smoothing_enabled", "limit_smoothing_enabled"), &Camera2D::set_limit_smoothing_enabled);
ClassDB::bind_method(D_METHOD("is_limit_smoothing_enabled"), &Camera2D::is_limit_smoothing_enabled);
- ClassDB::bind_method(D_METHOD("set_v_drag_enabled", "enabled"), &Camera2D::set_v_drag_enabled);
- ClassDB::bind_method(D_METHOD("is_v_drag_enabled"), &Camera2D::is_v_drag_enabled);
+ ClassDB::bind_method(D_METHOD("set_drag_vertical_enabled", "enabled"), &Camera2D::set_drag_vertical_enabled);
+ ClassDB::bind_method(D_METHOD("is_drag_vertical_enabled"), &Camera2D::is_drag_vertical_enabled);
- ClassDB::bind_method(D_METHOD("set_h_drag_enabled", "enabled"), &Camera2D::set_h_drag_enabled);
- ClassDB::bind_method(D_METHOD("is_h_drag_enabled"), &Camera2D::is_h_drag_enabled);
+ ClassDB::bind_method(D_METHOD("set_drag_horizontal_enabled", "enabled"), &Camera2D::set_drag_horizontal_enabled);
+ ClassDB::bind_method(D_METHOD("is_drag_horizontal_enabled"), &Camera2D::is_drag_horizontal_enabled);
- ClassDB::bind_method(D_METHOD("set_v_offset", "ofs"), &Camera2D::set_v_offset);
- ClassDB::bind_method(D_METHOD("get_v_offset"), &Camera2D::get_v_offset);
+ ClassDB::bind_method(D_METHOD("set_drag_vertical_offset", "offset"), &Camera2D::set_drag_vertical_offset);
+ ClassDB::bind_method(D_METHOD("get_drag_vertical_offset"), &Camera2D::get_drag_vertical_offset);
- ClassDB::bind_method(D_METHOD("set_h_offset", "ofs"), &Camera2D::set_h_offset);
- ClassDB::bind_method(D_METHOD("get_h_offset"), &Camera2D::get_h_offset);
+ ClassDB::bind_method(D_METHOD("set_drag_horizontal_offset", "offset"), &Camera2D::set_drag_horizontal_offset);
+ ClassDB::bind_method(D_METHOD("get_drag_horizontal_offset"), &Camera2D::get_drag_horizontal_offset);
ClassDB::bind_method(D_METHOD("set_drag_margin", "margin", "drag_margin"), &Camera2D::set_drag_margin);
ClassDB::bind_method(D_METHOD("get_drag_margin", "margin"), &Camera2D::get_drag_margin);
@@ -714,7 +728,7 @@ void Camera2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "_set_current", "is_current");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom"), "set_zoom", "get_zoom");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
ADD_GROUP("Limit", "limit_");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_left"), "set_limit", "get_limit", SIDE_LEFT);
@@ -723,23 +737,19 @@ void Camera2D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_bottom"), "set_limit", "get_limit", SIDE_BOTTOM);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "limit_smoothed"), "set_limit_smoothing_enabled", "is_limit_smoothing_enabled");
- ADD_GROUP("Draw Margin", "draw_margin_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_margin_h_enabled"), "set_h_drag_enabled", "is_h_drag_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_margin_v_enabled"), "set_v_drag_enabled", "is_v_drag_enabled");
-
ADD_GROUP("Smoothing", "smoothing_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smoothing_enabled"), "set_enable_follow_smoothing", "is_follow_smoothing_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "smoothing_speed"), "set_follow_smoothing", "get_follow_smoothing");
- ADD_GROUP("Offset", "offset_");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset_h", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_h_offset", "get_h_offset");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset");
-
- ADD_GROUP("Drag Margin", "drag_margin_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", SIDE_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_top", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", SIDE_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_right", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", SIDE_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_bottom", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", SIDE_BOTTOM);
+ ADD_GROUP("Drag", "drag_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_horizontal_enabled"), "set_drag_horizontal_enabled", "is_drag_horizontal_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_vertical_enabled"), "set_drag_vertical_enabled", "is_drag_vertical_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_horizontal_offset", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_drag_horizontal_offset", "get_drag_horizontal_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_vertical_offset", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_drag_vertical_offset", "get_drag_vertical_offset");
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_left_margin", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", SIDE_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_top_margin", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", SIDE_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_right_margin", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", SIDE_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_bottom_margin", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", SIDE_BOTTOM);
ADD_GROUP("Editor", "editor_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_draw_screen"), "set_screen_drawing_enabled", "is_screen_drawing_enabled");
@@ -753,9 +763,6 @@ void Camera2D::_bind_methods() {
}
Camera2D::Camera2D() {
- anchor_mode = ANCHOR_MODE_DRAG_CENTER;
- rotating = false;
- current = false;
limit[SIDE_LEFT] = -10000000;
limit[SIDE_TOP] = -10000000;
limit[SIDE_RIGHT] = 10000000;
@@ -765,27 +772,6 @@ Camera2D::Camera2D() {
drag_margin[SIDE_TOP] = 0.2;
drag_margin[SIDE_RIGHT] = 0.2;
drag_margin[SIDE_BOTTOM] = 0.2;
- camera_pos = Vector2();
- first = true;
- smoothing_enabled = false;
- limit_smoothing_enabled = false;
- custom_viewport = nullptr;
-
- process_mode = CAMERA2D_PROCESS_IDLE;
-
- smoothing = 5.0;
- zoom = Vector2(1, 1);
-
- screen_drawing_enabled = true;
- limit_drawing_enabled = false;
- margin_drawing_enabled = false;
-
- h_drag_enabled = false;
- v_drag_enabled = false;
- h_ofs = 0;
- v_ofs = 0;
- h_offset_changed = false;
- v_offset_changed = false;
set_notify_transform(true);
}
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index ebfcf97861..220e208eb0 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,7 @@ public:
ANCHOR_MODE_DRAG_CENTER
};
- enum Camera2DProcessMode {
+ enum Camera2DProcessCallback {
CAMERA2D_PROCESS_PHYSICS,
CAMERA2D_PROCESS_IDLE
};
@@ -51,36 +51,35 @@ public:
protected:
Point2 camera_pos;
Point2 smoothed_camera_pos;
- bool first;
+ bool first = true;
ObjectID custom_viewport_id; // to check validity
- Viewport *custom_viewport;
- Viewport *viewport;
+ Viewport *custom_viewport = nullptr;
+ Viewport *viewport = nullptr;
StringName group_name;
StringName canvas_group_name;
RID canvas;
Vector2 offset;
- Vector2 zoom;
- AnchorMode anchor_mode;
- bool rotating;
- bool current;
- float smoothing;
- bool smoothing_enabled;
+ Vector2 zoom = Vector2(1, 1);
+ AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER;
+ bool rotating = false;
+ bool current = false;
+ float smoothing = 5.0;
+ bool smoothing_enabled = false;
int limit[4];
- bool limit_smoothing_enabled;
- float drag_margin[4];
-
- bool h_drag_enabled;
- bool v_drag_enabled;
- float h_ofs;
- float v_ofs;
+ bool limit_smoothing_enabled = false;
- bool h_offset_changed;
- bool v_offset_changed;
+ float drag_margin[4];
+ bool drag_horizontal_enabled = false;
+ bool drag_vertical_enabled = false;
+ float drag_horizontal_offset = 0.0;
+ float drag_vertical_offset = 0.0;
+ bool drag_horizontal_offset_changed = false;
+ bool drag_vertical_offset_changed = false;
Point2 camera_screen_center;
- void _update_process_mode();
+ void _update_process_callback();
void _update_scroll();
void _make_current(Object *p_which);
@@ -88,18 +87,20 @@ protected:
void _set_old_smoothing(float p_enable);
- bool screen_drawing_enabled;
- bool limit_drawing_enabled;
- bool margin_drawing_enabled;
+ bool screen_drawing_enabled = true;
+ bool limit_drawing_enabled = false;
+ bool margin_drawing_enabled = false;
- Camera2DProcessMode process_mode;
+ Camera2DProcessCallback process_callback = CAMERA2D_PROCESS_IDLE;
Size2 _get_camera_screen_size() const;
protected:
virtual Transform2D get_camera_transform();
+
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_offset(const Vector2 &p_offset);
@@ -117,20 +118,20 @@ public:
void set_limit_smoothing_enabled(bool enable);
bool is_limit_smoothing_enabled() const;
- void set_h_drag_enabled(bool p_enabled);
- bool is_h_drag_enabled() const;
+ void set_drag_horizontal_enabled(bool p_enabled);
+ bool is_drag_horizontal_enabled() const;
- void set_v_drag_enabled(bool p_enabled);
- bool is_v_drag_enabled() const;
+ void set_drag_vertical_enabled(bool p_enabled);
+ bool is_drag_vertical_enabled() const;
void set_drag_margin(Side p_side, float p_drag_margin);
float get_drag_margin(Side p_side) const;
- void set_v_offset(float p_offset);
- float get_v_offset() const;
+ void set_drag_horizontal_offset(float p_offset);
+ float get_drag_horizontal_offset() const;
- void set_h_offset(float p_offset);
- float get_h_offset() const;
+ void set_drag_vertical_offset(float p_offset);
+ float get_drag_vertical_offset() const;
void set_enable_follow_smoothing(bool p_enabled);
bool is_follow_smoothing_enabled() const;
@@ -138,8 +139,8 @@ public:
void set_follow_smoothing(float p_speed);
float get_follow_smoothing() const;
- void set_process_mode(Camera2DProcessMode p_mode);
- Camera2DProcessMode get_process_mode() const;
+ void set_process_callback(Camera2DProcessCallback p_mode);
+ Camera2DProcessCallback get_process_callback() const;
void make_current();
void clear_current();
@@ -171,6 +172,6 @@ public:
};
VARIANT_ENUM_CAST(Camera2D::AnchorMode);
-VARIANT_ENUM_CAST(Camera2D::Camera2DProcessMode);
+VARIANT_ENUM_CAST(Camera2D::Camera2DProcessCallback);
#endif // CAMERA_2D_H
diff --git a/scene/2d/canvas_group.cpp b/scene/2d/canvas_group.cpp
index 39cae8e0c6..0f0e583ea7 100644
--- a/scene/2d/canvas_group.cpp
+++ b/scene/2d/canvas_group.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -84,4 +84,5 @@ CanvasGroup::CanvasGroup() {
set_fit_margin(10.0); //sets things
}
CanvasGroup::~CanvasGroup() {
+ RS::get_singleton()->canvas_item_set_canvas_group_mode(get_canvas_item(), RS::CANVAS_GROUP_MODE_DISABLED);
}
diff --git a/scene/2d/canvas_group.h b/scene/2d/canvas_group.h
index 19630befc7..cecf7c24f4 100644
--- a/scene/2d/canvas_group.h
+++ b/scene/2d/canvas_group.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp
index 8fb16534e8..5d5aaae505 100644
--- a/scene/2d/canvas_modulate.cpp
+++ b/scene/2d/canvas_modulate.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -84,7 +84,7 @@ String CanvasModulate::get_configuration_warning() const {
get_tree()->get_nodes_in_group("_canvas_modulate_" + itos(get_canvas().get_id()), &nodes);
if (nodes.size() > 1) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Only one visible CanvasModulate is allowed per scene (or set of instanced scenes). The first created one will work, while the rest will be ignored.");
@@ -94,7 +94,6 @@ String CanvasModulate::get_configuration_warning() const {
}
CanvasModulate::CanvasModulate() {
- color = Color(1, 1, 1, 1);
}
CanvasModulate::~CanvasModulate() {
diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h
index eac3cf9e54..4d55a5d9cb 100644
--- a/scene/2d/canvas_modulate.h
+++ b/scene/2d/canvas_modulate.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class CanvasModulate : public Node2D {
GDCLASS(CanvasModulate, Node2D);
- Color color;
+ Color color = Color(1, 1, 1, 1);
protected:
void _notification(int p_what);
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index fe16d4089a..c83ed36917 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -165,7 +165,7 @@ bool CollisionObject2D::is_shape_owner_one_way_collision_enabled(uint32_t p_owne
return shapes[p_owner].one_way_collision;
}
-void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin) {
+void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin) {
if (area) {
return; //not for areas
}
@@ -179,7 +179,7 @@ void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owne
}
}
-float CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const {
+real_t CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), 0);
return shapes[p_owner].one_way_collision_margin;
@@ -366,8 +366,8 @@ void CollisionObject2D::_update_pickable() {
String CollisionObject2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
- if (shapes.empty()) {
- if (!warning.empty()) {
+ if (shapes.is_empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape2D or CollisionPolygon2D as a child to define its shape.");
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index 8eff1b3aec..e82b61d441 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,35 +37,29 @@
class CollisionObject2D : public Node2D {
GDCLASS(CollisionObject2D, Node2D);
- bool area;
+ bool area = false;
RID rid;
- bool pickable;
+ bool pickable = false;
struct ShapeData {
- Object *owner;
+ Object *owner = nullptr;
Transform2D xform;
struct Shape {
Ref<Shape2D> shape;
- int index;
+ int index = 0;
};
Vector<Shape> shapes;
- bool disabled;
- bool one_way_collision;
- float one_way_collision_margin;
-
- ShapeData() {
- disabled = false;
- one_way_collision = false;
- one_way_collision_margin = 0;
- owner = nullptr;
- }
+
+ bool disabled = false;
+ bool one_way_collision = false;
+ real_t one_way_collision_margin = 0.0;
};
- int total_subshapes;
+ int total_subshapes = 0;
Map<uint32_t, ShapeData> shapes;
- bool only_update_transform_changes; //this is used for sync physics in KinematicBody
+ bool only_update_transform_changes = false; //this is used for sync physics in KinematicBody
protected:
CollisionObject2D(RID p_rid, bool p_area);
@@ -97,8 +91,8 @@ public:
void shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable);
bool is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const;
- void shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin);
- float get_shape_owner_one_way_collision_margin(uint32_t p_owner) const;
+ void shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin);
+ real_t get_shape_owner_one_way_collision_margin(uint32_t p_owner) const;
void shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape);
int shape_owner_get_shape_count(uint32_t p_owner) const;
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 64d82d715c..38198c496e 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,18 +36,18 @@
#include "scene/resources/concave_polygon_shape_2d.h"
#include "scene/resources/convex_polygon_shape_2d.h"
-#include "thirdparty/misc/triangulator.h"
+#include "thirdparty/misc/polypartition.h"
void CollisionPolygon2D::_build_polygon() {
parent->shape_owner_clear_shapes(owner_id);
- if (polygon.size() == 0) {
- return;
- }
-
bool solids = build_mode == BUILD_SOLIDS;
if (solids) {
+ if (polygon.size() < 3) {
+ return;
+ }
+
//here comes the sun, lalalala
//decompose concave into multiple convex polygons and add them
Vector<Vector<Vector2>> decomp = _decompose_in_convex();
@@ -58,6 +58,10 @@ void CollisionPolygon2D::_build_polygon() {
}
} else {
+ if (polygon.size() < 2) {
+ return;
+ }
+
Ref<ConcavePolygonShape2D> concave = memnew(ConcavePolygonShape2D);
Vector<Vector2> segments;
@@ -132,25 +136,28 @@ void CollisionPolygon2D::_notification(int p_what) {
break;
}
- for (int i = 0; i < polygon.size(); i++) {
+ int polygon_count = polygon.size();
+ for (int i = 0; i < polygon_count; i++) {
Vector2 p = polygon[i];
- Vector2 n = polygon[(i + 1) % polygon.size()];
+ Vector2 n = polygon[(i + 1) % polygon_count];
// draw line with width <= 1, so it does not scale with zoom and break pixel exact editing
draw_line(p, n, Color(0.9, 0.2, 0.0, 0.8), 1);
}
+
+ if (polygon_count > 2) {
#define DEBUG_DECOMPOSE
#if defined(TOOLS_ENABLED) && defined(DEBUG_DECOMPOSE)
+ Vector<Vector<Vector2>> decomp = _decompose_in_convex();
- Vector<Vector<Vector2>> decomp = _decompose_in_convex();
-
- Color c(0.4, 0.9, 0.1);
- for (int i = 0; i < decomp.size(); i++) {
- c.set_hsv(Math::fmod(c.get_h() + 0.738, 1), c.get_s(), c.get_v(), 0.5);
- draw_colored_polygon(decomp[i], c);
- }
+ Color c(0.4, 0.9, 0.1);
+ for (int i = 0; i < decomp.size(); i++) {
+ c.set_hsv(Math::fmod(c.get_h() + 0.738, 1), c.get_s(), c.get_v(), 0.5);
+ draw_colored_polygon(decomp[i], c);
+ }
#else
- draw_colored_polygon(polygon, get_tree()->get_debug_collisions_color());
+ draw_colored_polygon(polygon, get_tree()->get_debug_collisions_color());
#endif
+ }
if (one_way_collision) {
Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
@@ -158,7 +165,7 @@ void CollisionPolygon2D::_notification(int p_what) {
Vector2 line_to(0, 20);
draw_line(Vector2(), line_to, dcol, 3);
Vector<Vector2> pts;
- float tsize = 8;
+ real_t tsize = 8;
pts.push_back(line_to + (Vector2(0, tsize)));
pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0)));
pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0)));
@@ -194,6 +201,7 @@ void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) {
if (parent) {
_build_polygon();
+ _update_in_shape_owner();
}
update();
update_configuration_warning();
@@ -208,7 +216,10 @@ void CollisionPolygon2D::set_build_mode(BuildMode p_mode) {
build_mode = p_mode;
if (parent) {
_build_polygon();
+ _update_in_shape_owner();
}
+ update();
+ update_configuration_warning();
}
CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const {
@@ -233,17 +244,33 @@ String CollisionPolygon2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<CollisionObject2D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
}
- if (polygon.empty()) {
- if (!warning.empty()) {
+ int polygon_count = polygon.size();
+ if (polygon_count == 0) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("An empty CollisionPolygon2D has no effect on collision.");
+ } else {
+ bool solids = build_mode == BUILD_SOLIDS;
+ if (solids) {
+ if (polygon_count < 3) {
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("Invalid polygon. At least 3 points are needed in 'Solids' build mode.");
+ }
+ } else if (polygon_count < 2) {
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("Invalid polygon. At least 2 points are needed in 'Segments' build mode.");
+ }
}
return warning;
@@ -273,14 +300,14 @@ bool CollisionPolygon2D::is_one_way_collision_enabled() const {
return one_way_collision;
}
-void CollisionPolygon2D::set_one_way_collision_margin(float p_margin) {
+void CollisionPolygon2D::set_one_way_collision_margin(real_t p_margin) {
one_way_collision_margin = p_margin;
if (parent) {
parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin);
}
}
-float CollisionPolygon2D::get_one_way_collision_margin() const {
+real_t CollisionPolygon2D::get_one_way_collision_margin() const {
return one_way_collision_margin;
}
@@ -308,12 +335,5 @@ void CollisionPolygon2D::_bind_methods() {
}
CollisionPolygon2D::CollisionPolygon2D() {
- aabb = Rect2(-10, -10, 20, 20);
- build_mode = BUILD_SOLIDS;
set_notify_local_transform(true);
- parent = nullptr;
- owner_id = 0;
- disabled = false;
- one_way_collision = false;
- one_way_collision_margin = 1.0;
}
diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h
index 0f6b654149..9df9802629 100644
--- a/scene/2d/collision_polygon_2d.h
+++ b/scene/2d/collision_polygon_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,14 +46,14 @@ public:
};
protected:
- Rect2 aabb;
- BuildMode build_mode;
+ Rect2 aabb = Rect2(-10, -10, 20, 20);
+ BuildMode build_mode = BUILD_SOLIDS;
Vector<Point2> polygon;
- uint32_t owner_id;
- CollisionObject2D *parent;
- bool disabled;
- bool one_way_collision;
- float one_way_collision_margin;
+ uint32_t owner_id = 0;
+ CollisionObject2D *parent = nullptr;
+ bool disabled = false;
+ bool one_way_collision = false;
+ real_t one_way_collision_margin = 1.0;
Vector<Vector<Vector2>> _decompose_in_convex();
@@ -86,8 +86,8 @@ public:
void set_one_way_collision(bool p_enable);
bool is_one_way_collision_enabled() const;
- void set_one_way_collision_margin(float p_margin);
- float get_one_way_collision_margin() const;
+ void set_one_way_collision_margin(real_t p_margin);
+ real_t get_one_way_collision_margin() const;
CollisionPolygon2D();
};
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index a5cd624235..93949f741b 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -110,6 +110,7 @@ void CollisionShape2D::_notification(int p_what) {
draw_col.r = g;
draw_col.g = g;
draw_col.b = g;
+ draw_col.a *= 0.5;
}
shape->draw(get_canvas_item(), draw_col);
@@ -125,7 +126,7 @@ void CollisionShape2D::_notification(int p_what) {
Vector2 line_to(0, 20);
draw_line(Vector2(), line_to, draw_col, 2);
Vector<Vector2> pts;
- float tsize = 8;
+ real_t tsize = 8;
pts.push_back(line_to + (Vector2(0, tsize)));
pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0)));
pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0)));
@@ -141,6 +142,9 @@ void CollisionShape2D::_notification(int p_what) {
}
void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) {
+ if (p_shape == shape) {
+ return;
+ }
if (shape.is_valid()) {
shape->disconnect("changed", callable_mp(this, &CollisionShape2D::_shape_changed));
}
@@ -151,6 +155,7 @@ void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) {
if (shape.is_valid()) {
parent->shape_owner_add_shape(owner_id, shape);
}
+ _update_in_shape_owner();
}
if (shape.is_valid()) {
@@ -211,14 +216,14 @@ bool CollisionShape2D::is_one_way_collision_enabled() const {
return one_way_collision;
}
-void CollisionShape2D::set_one_way_collision_margin(float p_margin) {
+void CollisionShape2D::set_one_way_collision_margin(real_t p_margin) {
one_way_collision_margin = p_margin;
if (parent) {
parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin);
}
}
-float CollisionShape2D::get_one_way_collision_margin() const {
+real_t CollisionShape2D::get_one_way_collision_margin() const {
return one_way_collision_margin;
}
@@ -239,11 +244,5 @@ void CollisionShape2D::_bind_methods() {
}
CollisionShape2D::CollisionShape2D() {
- rect = Rect2(-Point2(10, 10), Point2(20, 20));
set_notify_local_transform(true);
- owner_id = 0;
- parent = nullptr;
- disabled = false;
- one_way_collision = false;
- one_way_collision_margin = 1.0;
}
diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h
index ced90d46f0..695d0c6657 100644
--- a/scene/2d/collision_shape_2d.h
+++ b/scene/2d/collision_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,13 +39,13 @@ class CollisionObject2D;
class CollisionShape2D : public Node2D {
GDCLASS(CollisionShape2D, Node2D);
Ref<Shape2D> shape;
- Rect2 rect;
- uint32_t owner_id;
- CollisionObject2D *parent;
+ Rect2 rect = Rect2(-Point2(10, 10), Point2(20, 20));
+ uint32_t owner_id = 0;
+ CollisionObject2D *parent = nullptr;
void _shape_changed();
- bool disabled;
- bool one_way_collision;
- float one_way_collision_margin;
+ bool disabled = false;
+ bool one_way_collision = false;
+ real_t one_way_collision_margin = 1.0;
void _update_in_shape_owner(bool p_xform_only = false);
@@ -69,8 +69,8 @@ public:
void set_one_way_collision(bool p_enable);
bool is_one_way_collision_enabled() const;
- void set_one_way_collision_margin(float p_margin);
- float get_one_way_collision_margin() const;
+ void set_one_way_collision_margin(real_t p_margin);
+ real_t get_one_way_collision_margin() const;
virtual String get_configuration_warning() const override;
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 3649746c40..48acee1bc4 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -60,7 +60,7 @@ void CPUParticles2D::set_amount(int p_amount) {
}
particle_data.resize((8 + 4 + 4) * p_amount);
- RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true);
+ RS::get_singleton()->multimesh_allocate_data(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_2D, true, true);
particle_order.resize(p_amount);
}
@@ -410,7 +410,7 @@ bool CPUParticles2D::get_particle_flag(ParticleFlags p_particle_flag) const {
void CPUParticles2D::set_emission_shape(EmissionShape p_shape) {
ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX);
emission_shape = p_shape;
- _change_notify();
+ notify_property_list_changed();
}
void CPUParticles2D::set_emission_sphere_radius(float p_radius) {
@@ -599,7 +599,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
cycle++;
if (one_shot && cycle > 0) {
set_emitting(false);
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -671,6 +671,8 @@ void CPUParticles2D::_particles_process(float p_delta) {
restart = true;
}
+ float tv = 0.0;
+
if (restart) {
if (!emitting) {
p.active = false;
@@ -685,12 +687,12 @@ void CPUParticles2D::_particles_process(float p_delta) {
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
p.seed = Math::rand();
@@ -700,7 +702,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
p.hue_rot_rand = Math::randf();
p.anim_offset_rand = Math::randf();
- float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0;
+ float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad));
p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
@@ -721,7 +723,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
//do none
} break;
case EMISSION_SHAPE_SPHERE: {
- float s = Math::randf(), t = 2.0 * Math_PI * Math::randf();
+ float s = Math::randf(), t = Math_TAU * Math::randf();
float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius;
} break;
@@ -743,7 +745,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
Vector2 normal = emission_normals.get(random_idx);
Transform2D m2;
m2.set_axis(0, normal);
- m2.set_axis(1, normal.tangent());
+ m2.set_axis(1, normal.orthogonal());
p.velocity = m2.basis_xform(p.velocity);
}
@@ -765,59 +767,61 @@ void CPUParticles2D::_particles_process(float p_delta) {
continue;
} else if (p.time > p.lifetime) {
p.active = false;
+ tv = 1.0;
} else {
uint32_t alt_seed = p.seed;
p.time += local_delta;
p.custom[1] = p.time / lifetime;
+ tv = p.time / p.lifetime;
float tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
float tex_orbit_velocity = 0.0;
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
- tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]);
+ tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
float tex_angular_velocity = 0.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
- tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
float tex_linear_accel = 0.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
- tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]);
+ tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
float tex_tangential_accel = 0.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
- tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
float tex_radial_accel = 0.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
- tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
float tex_damping = 0.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
- tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]);
+ tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_speed = 0.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
- tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]);
+ tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]);
+ tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
Vector2 force = gravity;
@@ -837,7 +841,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
//orbit velocity
float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]);
if (orbit_amount != 0.0) {
- float ang = orbit_amount * local_delta * Math_PI * 2.0;
+ float ang = orbit_amount * local_delta * Math_TAU;
// Not sure why the ParticlesMaterial code uses a clockwise rotation matrix,
// but we use -ang here to reproduce its behavior.
Transform2D rot = Transform2D(-ang, Vector2());
@@ -869,15 +873,15 @@ void CPUParticles2D::_particles_process(float p_delta) {
float tex_scale = 1.0;
if (curve_parameters[PARAM_SCALE].is_valid()) {
- tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]);
+ tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
}
float tex_hue_variation = 0.0;
if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
- tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]);
+ tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}
- float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
+ float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
float hue_rot_c = Math::cos(hue_rot_angle);
float hue_rot_s = Math::sin(hue_rot_angle);
@@ -893,7 +897,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
if (color_ramp.is_valid()) {
- p.color = color_ramp->get_color_at_offset(p.custom[1]) * color;
+ p.color = color_ramp->get_color_at_offset(tv) * color;
} else {
p.color = color;
}
@@ -908,7 +912,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) {
if (p.velocity.length() > 0.0) {
p.transform.elements[1] = p.velocity.normalized();
- p.transform.elements[0] = p.transform.elements[1].tangent();
+ p.transform.elements[0] = p.transform.elements[1].orthogonal();
}
} else {
@@ -1028,66 +1032,64 @@ void CPUParticles2D::_update_render_thread() {
}
void CPUParticles2D::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- set_process_internal(emitting);
- }
-
- if (p_what == NOTIFICATION_EXIT_TREE) {
- _set_redraw(false);
- }
-
- if (p_what == NOTIFICATION_DRAW) {
- // first update before rendering to avoid one frame delay after emitting starts
- if (emitting && (time == 0)) {
- _update_internal();
- }
-
- if (!redraw) {
- return; // don't add to render list
- }
-
- RID texrid;
- if (texture.is_valid()) {
- texrid = texture->get_rid();
- }
-
- RS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid);
- }
-
- if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
- _update_internal();
- }
-
- if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
- inv_emission_transform = get_global_transform().affine_inverse();
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ set_process_internal(emitting);
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ _set_redraw(false);
+ } break;
+ case NOTIFICATION_DRAW: {
+ // first update before rendering to avoid one frame delay after emitting starts
+ if (emitting && (time == 0)) {
+ _update_internal();
+ }
- if (!local_coords) {
- int pc = particles.size();
+ if (!redraw) {
+ return; // don't add to render list
+ }
- float *w = particle_data.ptrw();
- const Particle *r = particles.ptr();
- float *ptr = w;
+ RID texrid;
+ if (texture.is_valid()) {
+ texrid = texture->get_rid();
+ }
- for (int i = 0; i < pc; i++) {
- Transform2D t = inv_emission_transform * r[i].transform;
+ RS::get_singleton()->canvas_item_add_multimesh(get_canvas_item(), multimesh, texrid);
+ } break;
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ _update_internal();
+ } break;
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+ inv_emission_transform = get_global_transform().affine_inverse();
- if (r[i].active) {
- ptr[0] = t.elements[0][0];
- ptr[1] = t.elements[1][0];
- ptr[2] = 0;
- ptr[3] = t.elements[2][0];
- ptr[4] = t.elements[0][1];
- ptr[5] = t.elements[1][1];
- ptr[6] = 0;
- ptr[7] = t.elements[2][1];
+ if (!local_coords) {
+ int pc = particles.size();
+
+ float *w = particle_data.ptrw();
+ const Particle *r = particles.ptr();
+ float *ptr = w;
+
+ for (int i = 0; i < pc; i++) {
+ Transform2D t = inv_emission_transform * r[i].transform;
+
+ if (r[i].active) {
+ ptr[0] = t.elements[0][0];
+ ptr[1] = t.elements[1][0];
+ ptr[2] = 0;
+ ptr[3] = t.elements[2][0];
+ ptr[4] = t.elements[0][1];
+ ptr[5] = t.elements[1][1];
+ ptr[6] = 0;
+ ptr[7] = t.elements[2][1];
+
+ } else {
+ zeromem(ptr, sizeof(float) * 8);
+ }
- } else {
- zeromem(ptr, sizeof(float) * 8);
+ ptr += 16;
}
-
- ptr += 16;
}
- }
+ } break;
}
}
@@ -1365,34 +1367,14 @@ void CPUParticles2D::_bind_methods() {
}
CPUParticles2D::CPUParticles2D() {
- time = 0;
- inactive_time = 0;
- frame_remainder = 0;
- cycle = 0;
- redraw = false;
- emitting = false;
-
mesh = RenderingServer::get_singleton()->mesh_create();
multimesh = RenderingServer::get_singleton()->multimesh_create();
RenderingServer::get_singleton()->multimesh_set_mesh(multimesh, mesh);
set_emitting(true);
- set_one_shot(false);
set_amount(8);
- set_lifetime(1);
- set_fixed_fps(0);
- set_fractional_delta(true);
- set_pre_process_time(0);
- set_explosiveness_ratio(0);
- set_randomness_ratio(0);
- set_lifetime_randomness(0);
set_use_local_coordinates(true);
- set_draw_order(DRAW_ORDER_INDEX);
- set_speed_scale(1);
-
- set_direction(Vector2(1, 0));
- set_spread(45);
set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0);
set_param(PARAM_ANGULAR_VELOCITY, 0);
set_param(PARAM_ORBIT_VELOCITY, 0);
@@ -1405,11 +1387,6 @@ CPUParticles2D::CPUParticles2D() {
set_param(PARAM_HUE_VARIATION, 0);
set_param(PARAM_ANIM_SPEED, 0);
set_param(PARAM_ANIM_OFFSET, 0);
- set_emission_shape(EMISSION_SHAPE_POINT);
- set_emission_sphere_radius(1);
- set_emission_rect_extents(Vector2(1, 1));
-
- set_gravity(Vector2(0, 98));
for (int i = 0; i < PARAM_MAX; i++) {
set_param_randomness(Parameter(i), 0);
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 857f19b20f..7ee165b3e1 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,31 +78,31 @@ public:
};
private:
- bool emitting;
+ bool emitting = false;
struct Particle {
Transform2D transform;
Color color;
- float custom[4];
- float rotation;
+ float custom[4] = {};
+ float rotation = 0.0;
Vector2 velocity;
- bool active;
- float angle_rand;
- float scale_rand;
- float hue_rot_rand;
- float anim_offset_rand;
- float time;
- float lifetime;
+ bool active = false;
+ float angle_rand = 0.0;
+ float scale_rand = 0.0;
+ float hue_rot_rand = 0.0;
+ float anim_offset_rand = 0.0;
+ float time = 0.0;
+ float lifetime = 0.0;
Color base_color;
- uint32_t seed;
+ uint32_t seed = 0;
};
- float time;
- float inactive_time;
- float frame_remainder;
- int cycle;
- bool redraw;
+ float time = 0.0;
+ float inactive_time = 0.0;
+ float frame_remainder = 0.0;
+ int cycle = 0;
+ bool redraw = false;
RID mesh;
RID multimesh;
@@ -112,7 +112,7 @@ private:
Vector<int> particle_order;
struct SortLifetime {
- const Particle *particles;
+ const Particle *particles = nullptr;
bool operator()(int p_a, int p_b) const {
return particles[p_a].time > particles[p_b].time;
@@ -120,7 +120,7 @@ private:
};
struct SortAxis {
- const Particle *particles;
+ const Particle *particles = nullptr;
Vector2 axis;
bool operator()(int p_a, int p_b) const {
return axis.dot(particles[p_a].transform[2]) < axis.dot(particles[p_b].transform[2]);
@@ -129,28 +129,28 @@ private:
//
- bool one_shot;
+ bool one_shot = false;
- float lifetime;
- float pre_process_time;
- float explosiveness_ratio;
- float randomness_ratio;
- float lifetime_randomness;
- float speed_scale;
+ float lifetime = 1.0;
+ float pre_process_time = 0.0;
+ float explosiveness_ratio = 0.0;
+ float randomness_ratio = 0.0;
+ float lifetime_randomness = 0.0;
+ float speed_scale = 1.0;
bool local_coords;
- int fixed_fps;
- bool fractional_delta;
+ int fixed_fps = 0;
+ bool fractional_delta = true;
Transform2D inv_emission_transform;
- DrawOrder draw_order;
+ DrawOrder draw_order = DRAW_ORDER_INDEX;
Ref<Texture2D> texture;
////////
- Vector2 direction;
- float spread;
+ Vector2 direction = Vector2(1, 0);
+ float spread = 45.0;
float parameters[PARAM_MAX];
float randomness[PARAM_MAX];
@@ -161,15 +161,15 @@ private:
bool particle_flags[PARTICLE_FLAG_MAX];
- EmissionShape emission_shape;
- float emission_sphere_radius;
- Vector2 emission_rect_extents;
+ EmissionShape emission_shape = EMISSION_SHAPE_POINT;
+ float emission_sphere_radius = 1.0;
+ Vector2 emission_rect_extents = Vector2(1, 1);
Vector<Vector2> emission_points;
Vector<Vector2> emission_normals;
Vector<Color> emission_colors;
- int emission_point_count;
+ int emission_point_count = 0;
- Vector2 gravity;
+ Vector2 gravity = Vector2(0, 98);
void _update_internal();
void _particles_process(float p_delta);
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index 46096d7460..af70c47f7c 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -101,7 +101,6 @@ void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) {
RS::get_singleton()->particles_set_custom_aabb(particles, aabb);
- _change_notify("visibility_rect");
update();
}
@@ -305,7 +304,7 @@ void GPUParticles2D::_notification(int p_what) {
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
if (one_shot && !is_emitting()) {
- _change_notify();
+ notify_property_list_changed();
set_process_internal(false);
}
}
diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h
index 0d1b82d93e..774cef9cc9 100644
--- a/scene/2d/gpu_particles_2d.h
+++ b/scene/2d/gpu_particles_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp
index f5d13fd641..7d9cdd52ac 100644
--- a/scene/2d/joints_2d.cpp
+++ b/scene/2d/joints_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,56 +32,79 @@
#include "core/config/engine.h"
#include "physics_body_2d.h"
+#include "scene/scene_string_names.h"
#include "servers/physics_server_2d.h"
-void Joint2D::_update_joint(bool p_only_free) {
- if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid() && exclude_from_collision) {
- PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false);
- }
+void Joint2D::_disconnect_signals() {
+ Node *node_a = get_node_or_null(a);
+ PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
+ if (body_a) {
+ body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+ }
- PhysicsServer2D::get_singleton()->free(joint);
- joint = RID();
- ba = RID();
- bb = RID();
+ Node *node_b = get_node_or_null(b);
+ PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
+ if (body_b) {
+ body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
}
+}
+
+void Joint2D::_body_exit_tree() {
+ _disconnect_signals();
+ _update_joint(true);
+}
+
+void Joint2D::_update_joint(bool p_only_free) {
+ if (ba.is_valid() && bb.is_valid() && exclude_from_collision) {
+ PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false);
+ }
+
+ ba = RID();
+ bb = RID();
+ configured = false;
if (p_only_free || !is_inside_tree()) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = String();
return;
}
- Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)nullptr;
- Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)nullptr;
+ Node *node_a = get_node_or_null(a);
+ Node *node_b = get_node_or_null(b);
PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
if (node_a && !body_a && node_b && !body_b) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Node A and Node B must be PhysicsBody2Ds");
update_configuration_warning();
return;
}
if (node_a && !body_a) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Node A must be a PhysicsBody2D");
update_configuration_warning();
return;
}
if (node_b && !body_b) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Node B must be a PhysicsBody2D");
update_configuration_warning();
return;
}
if (!body_a || !body_b) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Joint is not connected to two PhysicsBody2Ds");
update_configuration_warning();
return;
}
if (body_a == body_b) {
+ PhysicsServer2D::get_singleton()->joint_clear(joint);
warning = TTR("Node A and Node B must be different PhysicsBody2Ds");
update_configuration_warning();
return;
@@ -90,7 +113,17 @@ void Joint2D::_update_joint(bool p_only_free) {
warning = String();
update_configuration_warning();
- joint = _configure_joint(body_a, body_b);
+ if (body_a) {
+ body_a->force_update_transform();
+ }
+
+ if (body_b) {
+ body_b->force_update_transform();
+ }
+
+ configured = true;
+
+ _configure_joint(joint, body_a, body_b);
ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint.");
@@ -99,6 +132,9 @@ void Joint2D::_update_joint(bool p_only_free) {
ba = body_a->get_rid();
bb = body_b->get_rid();
+ body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+ body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree));
+
PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
}
@@ -107,6 +143,10 @@ void Joint2D::set_node_a(const NodePath &p_node_a) {
return;
}
+ if (joint.is_valid()) {
+ _disconnect_signals();
+ }
+
a = p_node_a;
_update_joint();
}
@@ -119,6 +159,11 @@ void Joint2D::set_node_b(const NodePath &p_node_b) {
if (b == p_node_b) {
return;
}
+
+ if (joint.is_valid()) {
+ _disconnect_signals();
+ }
+
b = p_node_b;
_update_joint();
}
@@ -134,6 +179,7 @@ void Joint2D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
if (joint.is_valid()) {
+ _disconnect_signals();
_update_joint(true);
}
} break;
@@ -168,8 +214,8 @@ bool Joint2D::get_exclude_nodes_from_collision() const {
String Joint2D::get_configuration_warning() const {
String node_warning = Node2D::get_configuration_warning();
- if (!warning.empty()) {
- if (!node_warning.empty()) {
+ if (!warning.is_empty()) {
+ if (!node_warning.is_empty()) {
node_warning += "\n\n";
}
node_warning += warning;
@@ -198,8 +244,11 @@ void Joint2D::_bind_methods() {
}
Joint2D::Joint2D() {
- bias = 0;
- exclude_from_collision = true;
+ joint = PhysicsServer2D::get_singleton()->joint_create();
+}
+
+Joint2D::~Joint2D() {
+ PhysicsServer2D::get_singleton()->free(joint);
}
///////////////////////////////////////////////////////////////////////////////
@@ -223,16 +272,15 @@ void PinJoint2D::_notification(int p_what) {
}
}
-RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
- RID pj = PhysicsServer2D::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID());
- PhysicsServer2D::get_singleton()->pin_joint_set_param(pj, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness);
- return pj;
+void PinJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
+ PhysicsServer2D::get_singleton()->joint_make_pin(p_joint, get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID());
+ PhysicsServer2D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness);
}
void PinJoint2D::set_softness(real_t p_softness) {
softness = p_softness;
update();
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer2D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer2D::PIN_JOINT_SOFTNESS, p_softness);
}
}
@@ -249,7 +297,6 @@ void PinJoint2D::_bind_methods() {
}
PinJoint2D::PinJoint2D() {
- softness = 0;
}
///////////////////////////////////////////////////////////////////////////////
@@ -275,13 +322,13 @@ void GrooveJoint2D::_notification(int p_what) {
}
}
-RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
+void GrooveJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Transform2D gt = get_global_transform();
Vector2 groove_A1 = gt.get_origin();
Vector2 groove_A2 = gt.xform(Vector2(0, length));
Vector2 anchor_B = gt.xform(Vector2(0, initial_offset));
- return PhysicsServer2D::get_singleton()->groove_joint_create(groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid());
+ PhysicsServer2D::get_singleton()->joint_make_groove(p_joint, groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid());
}
void GrooveJoint2D::set_length(real_t p_length) {
@@ -313,8 +360,6 @@ void GrooveJoint2D::_bind_methods() {
}
GrooveJoint2D::GrooveJoint2D() {
- length = 50;
- initial_offset = 25;
}
///////////////////////////////////////////////////////////////////////////////
@@ -339,19 +384,17 @@ void DampedSpringJoint2D::_notification(int p_what) {
}
}
-RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
+void DampedSpringJoint2D::_configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Transform2D gt = get_global_transform();
Vector2 anchor_A = gt.get_origin();
Vector2 anchor_B = gt.xform(Vector2(0, length));
- RID dsj = PhysicsServer2D::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid());
+ PhysicsServer2D::get_singleton()->joint_make_damped_spring(p_joint, anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid());
if (rest_length) {
- PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length);
+ PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, rest_length);
}
- PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness);
- PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(dsj, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping);
-
- return dsj;
+ PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_STIFFNESS, stiffness);
+ PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(p_joint, PhysicsServer2D::DAMPED_SPRING_DAMPING, damping);
}
void DampedSpringJoint2D::set_length(real_t p_length) {
@@ -366,7 +409,7 @@ real_t DampedSpringJoint2D::get_length() const {
void DampedSpringJoint2D::set_rest_length(real_t p_rest_length) {
rest_length = p_rest_length;
update();
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_REST_LENGTH, p_rest_length ? p_rest_length : length);
}
}
@@ -378,7 +421,7 @@ real_t DampedSpringJoint2D::get_rest_length() const {
void DampedSpringJoint2D::set_stiffness(real_t p_stiffness) {
stiffness = p_stiffness;
update();
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_STIFFNESS, p_stiffness);
}
}
@@ -390,7 +433,7 @@ real_t DampedSpringJoint2D::get_stiffness() const {
void DampedSpringJoint2D::set_damping(real_t p_damping) {
damping = p_damping;
update();
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer2D::get_singleton()->damped_spring_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_SPRING_DAMPING, p_damping);
}
}
@@ -416,8 +459,4 @@ void DampedSpringJoint2D::_bind_methods() {
}
DampedSpringJoint2D::DampedSpringJoint2D() {
- length = 50;
- rest_length = 0;
- stiffness = 20;
- damping = 1;
}
diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h
index 759e7de8a0..08e02ee29d 100644
--- a/scene/2d/joints_2d.h
+++ b/scene/2d/joints_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,19 +43,24 @@ class Joint2D : public Node2D {
NodePath a;
NodePath b;
- real_t bias;
+ real_t bias = 0.0;
- bool exclude_from_collision;
+ bool exclude_from_collision = true;
+ bool configured = false;
String warning;
protected:
+ void _disconnect_signals();
+ void _body_exit_tree();
void _update_joint(bool p_only_free = false);
void _notification(int p_what);
- virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0;
+ virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0;
static void _bind_methods();
+ _FORCE_INLINE_ bool is_configured() const { return configured; }
+
public:
virtual String get_configuration_warning() const override;
@@ -73,16 +78,17 @@ public:
RID get_joint() const { return joint; }
Joint2D();
+ ~Joint2D();
};
class PinJoint2D : public Joint2D {
GDCLASS(PinJoint2D, Joint2D);
- real_t softness;
+ real_t softness = 0.0;
protected:
void _notification(int p_what);
- virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override;
+ virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override;
static void _bind_methods();
public:
@@ -95,12 +101,12 @@ public:
class GrooveJoint2D : public Joint2D {
GDCLASS(GrooveJoint2D, Joint2D);
- real_t length;
- real_t initial_offset;
+ real_t length = 50.0;
+ real_t initial_offset = 25.0;
protected:
void _notification(int p_what);
- virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override;
+ virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override;
static void _bind_methods();
public:
@@ -116,14 +122,14 @@ public:
class DampedSpringJoint2D : public Joint2D {
GDCLASS(DampedSpringJoint2D, Joint2D);
- real_t stiffness;
- real_t damping;
- real_t rest_length;
- real_t length;
+ real_t stiffness = 20.0;
+ real_t damping = 1.0;
+ real_t rest_length = 0.0;
+ real_t length = 50.0;
protected:
void _notification(int p_what);
- virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) override;
+ virtual void _configure_joint(RID p_joint, PhysicsBody2D *body_a, PhysicsBody2D *body_b) override;
static void _bind_methods();
public:
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 2b373a669b..58e15e3cca 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -159,6 +159,7 @@ int Light2D::get_item_shadow_cull_mask() const {
void Light2D::set_shadow_enabled(bool p_enabled) {
shadow = p_enabled;
RS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow);
+ notify_property_list_changed();
}
bool Light2D::is_shadow_enabled() const {
@@ -221,6 +222,12 @@ float Light2D::get_shadow_smooth() const {
return shadow_smooth;
}
+void Light2D::_validate_property(PropertyInfo &property) const {
+ if (!shadow && (property.name == "shadow_color" || property.name == "shadow_filter" || property.name == "shadow_filter_smooth" || property.name == "shadow_item_cull_mask")) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Light2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Light2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &Light2D::is_enabled);
@@ -300,22 +307,6 @@ void Light2D::_bind_methods() {
Light2D::Light2D() {
canvas_light = RenderingServer::get_singleton()->canvas_light_create();
- enabled = true;
- editor_only = false;
- shadow = false;
- color = Color(1, 1, 1);
- height = 0;
- z_min = -1024;
- z_max = 1024;
- layer_min = 0;
- layer_max = 0;
- item_mask = 1;
- item_shadow_mask = 1;
- energy = 1.0;
- shadow_color = Color(0, 0, 0, 0);
- shadow_filter = SHADOW_FILTER_NONE;
- shadow_smooth = 0;
- blend_mode = BLEND_MODE_ADD;
set_notify_transform(true);
}
@@ -393,7 +384,6 @@ void PointLight2D::set_texture_offset(const Vector2 &p_offset) {
texture_offset = p_offset;
RS::get_singleton()->canvas_light_set_texture_offset(_get_light(), texture_offset);
item_rect_changed();
- _change_notify("offset");
}
Vector2 PointLight2D::get_texture_offset() const {
@@ -404,7 +394,7 @@ String PointLight2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!texture.is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("A texture with the shape of the light must be supplied to the \"Texture\" property.");
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index 7dfeddc8e5..de8a2bb6d0 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -52,24 +52,24 @@ public:
private:
RID canvas_light;
- bool enabled;
- bool editor_only;
- bool shadow;
- Color color;
- Color shadow_color;
- float height;
- float energy;
- int z_min;
- int z_max;
- int layer_min;
- int layer_max;
- int item_mask;
- int item_shadow_mask;
- float shadow_smooth;
+ bool enabled = true;
+ bool editor_only = false;
+ bool shadow = false;
+ Color color = Color(1, 1, 1);
+ Color shadow_color = Color(0, 0, 0, 0);
+ float height = 0.0;
+ float energy = 1.0;
+ int z_min = -1024;
+ int z_max = 1024;
+ int layer_min = 0;
+ int layer_max = 0;
+ int item_mask = 1;
+ int item_shadow_mask = 1;
+ float shadow_smooth = 0.0;
Ref<Texture2D> texture;
Vector2 texture_offset;
- ShadowFilter shadow_filter;
- BlendMode blend_mode;
+ ShadowFilter shadow_filter = SHADOW_FILTER_NONE;
+ BlendMode blend_mode = BLEND_MODE_ADD;
void _update_light_visibility();
@@ -77,6 +77,7 @@ protected:
_FORCE_INLINE_ RID _get_light() const { return canvas_light; }
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_enabled(bool p_enabled);
diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp
index b5b39ccc8f..9589702e2e 100644
--- a/scene/2d/light_occluder_2d.cpp
+++ b/scene/2d/light_occluder_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -145,9 +145,6 @@ void OccluderPolygon2D::_bind_methods() {
OccluderPolygon2D::OccluderPolygon2D() {
occ_polygon = RS::get_singleton()->canvas_occluder_polygon_create();
- closed = true;
- cull = CULL_DISABLED;
- rect_cache_dirty = true;
}
OccluderPolygon2D::~OccluderPolygon2D() {
@@ -249,14 +246,14 @@ String LightOccluder2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!occluder_polygon.is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("An occluder polygon must be set (or drawn) for this occluder to take effect.");
}
if (occluder_polygon.is_valid() && occluder_polygon->get_polygon().size() == 0) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The occluder polygon for this occluder is empty. Please draw a polygon.");
diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h
index 97574af542..f567c6d965 100644
--- a/scene/2d/light_occluder_2d.h
+++ b/scene/2d/light_occluder_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,11 +46,11 @@ public:
private:
RID occ_polygon;
Vector<Vector2> polygon;
- bool closed;
- CullMode cull;
+ bool closed = true;
+ CullMode cull = CULL_DISABLED;
mutable Rect2 item_rect;
- mutable bool rect_cache_dirty;
+ mutable bool rect_cache_dirty = true;
protected:
static void _bind_methods();
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index e990e9f53e..37eb45c21d 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,15 +40,6 @@ VARIANT_ENUM_CAST(Line2D::LineCapMode)
VARIANT_ENUM_CAST(Line2D::LineTextureMode)
Line2D::Line2D() {
- _joint_mode = LINE_JOINT_SHARP;
- _begin_cap_mode = LINE_CAP_NONE;
- _end_cap_mode = LINE_CAP_NONE;
- _width = 10;
- _default_color = Color(1, 1, 1);
- _texture_mode = LINE_TEXTURE_NONE;
- _sharp_limit = 2.f;
- _round_precision = 8;
- _antialiased = false;
}
#ifdef TOOLS_ENABLED
@@ -125,6 +116,7 @@ Vector<Vector2> Line2D::get_points() const {
}
void Line2D::set_point_position(int i, Vector2 p_pos) {
+ ERR_FAIL_INDEX(i, _points.size());
_points.set(i, p_pos);
update();
}
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index 43739ee638..5e7eb4bac9 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -124,18 +124,18 @@ private:
private:
Vector<Vector2> _points;
- LineJointMode _joint_mode;
- LineCapMode _begin_cap_mode;
- LineCapMode _end_cap_mode;
- float _width;
+ LineJointMode _joint_mode = LINE_JOINT_SHARP;
+ LineCapMode _begin_cap_mode = LINE_CAP_NONE;
+ LineCapMode _end_cap_mode = LINE_CAP_NONE;
+ float _width = 10.0;
Ref<Curve> _curve;
- Color _default_color;
+ Color _default_color = Color(1, 1, 1);
Ref<Gradient> _gradient;
Ref<Texture2D> _texture;
- LineTextureMode _texture_mode;
- float _sharp_limit;
- int _round_precision;
- bool _antialiased;
+ LineTextureMode _texture_mode = LINE_TEXTURE_NONE;
+ float _sharp_limit = 2.f;
+ int _round_precision = 8;
+ bool _antialiased = false;
};
#endif // LINE2D_H
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index e0116d9bad..892ccadfda 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -94,20 +94,6 @@ static inline Vector2 interpolate(const Rect2 &r, const Vector2 &v) {
//----------------------------------------------------------------------------
LineBuilder::LineBuilder() {
- joint_mode = Line2D::LINE_JOINT_SHARP;
- width = 10;
- curve = nullptr;
- default_color = Color(0.4, 0.5, 1);
- gradient = nullptr;
- sharp_limit = 2.f;
- round_precision = 8;
- begin_cap_mode = Line2D::LINE_CAP_NONE;
- end_cap_mode = Line2D::LINE_CAP_NONE;
- tile_aspect = 1.f;
-
- _interpolate_color = false;
- _last_index[0] = 0;
- _last_index[1] = 0;
}
void LineBuilder::clear_output() {
@@ -554,7 +540,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col
float t = Vector2(1, 0).angle_to(vbegin);
float end_angle = t + angle_delta;
Vector2 rpos(0, 0);
- float tt_begin = -Math_PI / 2.f;
+ float tt_begin = -Math_PI / 2.0f;
float tt = tt_begin;
// Center vertice
diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h
index 0e033d9be1..654e61422b 100644
--- a/scene/2d/line_builder.h
+++ b/scene/2d/line_builder.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,17 +41,17 @@ public:
// TODO Move in a struct and reference it
// Input
Vector<Vector2> points;
- Line2D::LineJointMode joint_mode;
- Line2D::LineCapMode begin_cap_mode;
- Line2D::LineCapMode end_cap_mode;
- float width;
- Curve *curve;
- Color default_color;
- Gradient *gradient;
- Line2D::LineTextureMode texture_mode;
- float sharp_limit;
- int round_precision;
- float tile_aspect; // w/h
+ Line2D::LineJointMode joint_mode = Line2D::LINE_JOINT_SHARP;
+ Line2D::LineCapMode begin_cap_mode = Line2D::LINE_CAP_NONE;
+ Line2D::LineCapMode end_cap_mode = Line2D::LINE_CAP_NONE;
+ float width = 10.0;
+ Curve *curve = nullptr;
+ Color default_color = Color(0.4, 0.5, 1);
+ Gradient *gradient = nullptr;
+ Line2D::LineTextureMode texture_mode = Line2D::LineTextureMode::LINE_TEXTURE_NONE;
+ float sharp_limit = 2.f;
+ int round_precision = 8;
+ float tile_aspect = 1.f; // w/h
// TODO offset_joints option (offers alternative implementation of round joints)
// TODO Move in a struct and reference it
@@ -82,8 +82,8 @@ private:
void new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Color color, Rect2 uv_rect);
private:
- bool _interpolate_color;
- int _last_index[2]; // Index of last up and down vertices of the strip
+ bool _interpolate_color = false;
+ int _last_index[2] = {}; // Index of last up and down vertices of the strip
};
#endif // LINE_BUILDER_H
diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp
index 037e423ce9..b7a0028199 100644
--- a/scene/2d/mesh_instance_2d.cpp
+++ b/scene/2d/mesh_instance_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,7 +71,6 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
texture = p_texture;
update();
emit_signal("texture_changed");
- _change_notify("texture");
}
void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) {
diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h
index f10ab17a7c..adfda4cf7f 100644
--- a/scene/2d/mesh_instance_2d.h
+++ b/scene/2d/mesh_instance_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp
index c258e30eab..72a899370e 100644
--- a/scene/2d/multimesh_instance_2d.cpp
+++ b/scene/2d/multimesh_instance_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,7 +71,6 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
texture = p_texture;
update();
emit_signal("texture_changed");
- _change_notify("texture");
}
Ref<Texture2D> MultiMeshInstance2D::get_texture() const {
diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h
index aadedac42a..213cbd19b0 100644
--- a/scene/2d/multimesh_instance_2d.h
+++ b/scene/2d/multimesh_instance_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
deleted file mode 100644
index 039c6f2e53..0000000000
--- a/scene/2d/navigation_2d.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*************************************************************************/
-/* navigation_2d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "navigation_2d.h"
-#include "servers/navigation_server_2d.h"
-
-void Navigation2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_rid"), &Navigation2D::get_rid);
-
- ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point);
- ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner);
-
- ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation2D::set_cell_size);
- ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation2D::get_cell_size);
-
- ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation2D::set_edge_connection_margin);
- ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation2D::get_edge_connection_margin);
-
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
-}
-
-void Navigation2D::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_READY: {
- NavigationServer2D::get_singleton()->map_set_active(map, true);
- } break;
- case NOTIFICATION_EXIT_TREE: {
- NavigationServer2D::get_singleton()->map_set_active(map, false);
- } break;
- }
-}
-
-void Navigation2D::set_cell_size(float p_cell_size) {
- cell_size = p_cell_size;
- NavigationServer2D::get_singleton()->map_set_cell_size(map, cell_size);
-}
-
-void Navigation2D::set_edge_connection_margin(float p_edge_connection_margin) {
- edge_connection_margin = p_edge_connection_margin;
- NavigationServer2D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
-}
-
-Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) const {
- return NavigationServer2D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
-}
-
-Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) const {
- return NavigationServer2D::get_singleton()->map_get_closest_point(map, p_point);
-}
-
-RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const {
- return NavigationServer2D::get_singleton()->map_get_closest_point_owner(map, p_point);
-}
-
-Navigation2D::Navigation2D() {
- map = NavigationServer2D::get_singleton()->map_create();
- set_cell_size(10); // Ten pixels
- set_edge_connection_margin(100);
-}
-
-Navigation2D::~Navigation2D() {
- NavigationServer2D::get_singleton()->free(map);
-}
diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h
deleted file mode 100644
index 6046bddb32..0000000000
--- a/scene/2d/navigation_2d.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*************************************************************************/
-/* navigation_2d.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef NAVIGATION_2D_H
-#define NAVIGATION_2D_H
-
-#include "scene/2d/navigation_region_2d.h"
-#include "scene/2d/node_2d.h"
-
-class Navigation2D : public Node2D {
- GDCLASS(Navigation2D, Node2D);
-
- RID map;
- real_t cell_size;
- real_t edge_connection_margin;
-
-protected:
- static void _bind_methods();
- void _notification(int p_what);
-
-public:
- RID get_rid() const {
- return map;
- }
-
- void set_cell_size(float p_cell_size);
- float get_cell_size() const {
- return cell_size;
- }
-
- void set_edge_connection_margin(float p_edge_connection_margin);
- float get_edge_connection_margin() const {
- return edge_connection_margin;
- }
-
- Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true) const;
- Vector2 get_closest_point(const Vector2 &p_point) const;
- RID get_closest_point_owner(const Vector2 &p_point) const;
-
- Navigation2D();
- ~Navigation2D();
-};
-
-#endif // NAVIGATION_2D_H
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 1c7063d0d3..064fcc91a4 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,7 +32,6 @@
#include "core/config/engine.h"
#include "core/math/geometry_2d.h"
-#include "scene/2d/navigation_2d.h"
#include "servers/navigation_server_2d.h"
void NavigationAgent2D::_bind_methods() {
@@ -42,9 +41,6 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent2D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent2D::get_radius);
- ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent2D::set_navigation_node);
- ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent2D::get_navigation_node);
-
ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent2D::set_neighbor_dist);
ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent2D::get_neighbor_dist);
@@ -95,27 +91,10 @@ void NavigationAgent2D::_notification(int p_what) {
NavigationServer2D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
- // Search the navigation node and set it
- {
- Navigation2D *nav = nullptr;
- Node *p = get_parent();
- while (p != nullptr) {
- nav = Object::cast_to<Navigation2D>(p);
- if (nav != nullptr) {
- p = nullptr;
- } else {
- p = p->get_parent();
- }
- }
-
- set_navigation(nav);
- }
-
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
agent_parent = nullptr;
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -146,23 +125,13 @@ NavigationAgent2D::~NavigationAgent2D() {
agent = RID(); // Pointless
}
-void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
- if (navigation == p_nav) {
- return; // Pointless
- }
-
- navigation = p_nav;
- NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
-}
-
-void NavigationAgent2D::set_navigation_node(Node *p_nav) {
- Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
- ERR_FAIL_COND(nav == nullptr);
- set_navigation(nav);
+void NavigationAgent2D::set_navigable_layers(uint32_t p_layers) {
+ navigable_layers = p_layers;
+ update_navigation();
}
-Node *NavigationAgent2D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
+uint32_t NavigationAgent2D::get_navigable_layers() const {
+ return navigable_layers;
}
void NavigationAgent2D::set_target_desired_distance(real_t p_dd) {
@@ -274,7 +243,7 @@ String NavigationAgent2D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!Object::cast_to<Node2D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The NavigationAgent2D can be used only under a Node2D node");
@@ -287,7 +256,7 @@ void NavigationAgent2D::update_navigation() {
if (agent_parent == nullptr) {
return;
}
- if (navigation == nullptr) {
+ if (!agent_parent->is_inside_tree()) {
return;
}
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
@@ -319,7 +288,7 @@ void NavigationAgent2D::update_navigation() {
}
if (reload_path) {
- navigation_path = NavigationServer2D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true);
+ navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true, navigable_layers);
navigation_finished = false;
nav_path_index = 0;
emit_signal("path_changed");
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 1f2377837b..153ede8cec 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,16 +35,16 @@
#include "scene/main/node.h"
class Node2D;
-class Navigation2D;
class NavigationAgent2D : public Node {
GDCLASS(NavigationAgent2D, Node);
Node2D *agent_parent = nullptr;
- Navigation2D *navigation = nullptr;
RID agent;
+ uint32_t navigable_layers = 1;
+
real_t target_desired_distance = 1.0;
real_t radius;
real_t neighbor_dist;
@@ -74,18 +74,13 @@ public:
NavigationAgent2D();
virtual ~NavigationAgent2D();
- void set_navigation(Navigation2D *p_nav);
- const Navigation2D *get_navigation() const {
- return navigation;
- }
-
- void set_navigation_node(Node *p_nav);
- Node *get_navigation_node() const;
-
RID get_rid() const {
return agent;
}
+ void set_navigable_layers(uint32_t p_layers);
+ uint32_t get_navigable_layers() const;
+
void set_target_desired_distance(real_t p_dd);
real_t get_target_desired_distance() const {
return target_desired_distance;
diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp
index 252d7cbb96..965e2b6dc1 100644
--- a/scene/2d/navigation_obstacle_2d.cpp
+++ b/scene/2d/navigation_obstacle_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,48 +31,31 @@
#include "navigation_obstacle_2d.h"
#include "scene/2d/collision_shape_2d.h"
-#include "scene/2d/navigation_2d.h"
#include "scene/2d/physics_body_2d.h"
#include "servers/navigation_server_2d.h"
void NavigationObstacle2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node);
- ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node);
}
void NavigationObstacle2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
- update_agent_shape();
-
- // Search the navigation node and set it
- {
- Navigation2D *nav = nullptr;
- Node *p = get_parent();
- while (p != nullptr) {
- nav = Object::cast_to<Navigation2D>(p);
- if (nav != nullptr) {
- p = nullptr;
- } else {
- p = p->get_parent();
- }
- }
-
- set_navigation(nav);
- }
-
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
+ case NOTIFICATION_PARENTED: {
+ parent_node2d = Object::cast_to<Node2D>(get_parent());
+ update_agent_shape();
+ } break;
+ case NOTIFICATION_UNPARENTED: {
+ parent_node2d = nullptr;
+ } break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- Node2D *node = Object::cast_to<Node2D>(get_parent());
- if (node) {
- NavigationServer2D::get_singleton()->agent_set_position(agent, node->get_global_transform().get_origin());
+ if (parent_node2d) {
+ NavigationServer2D::get_singleton()->agent_set_position(agent, parent_node2d->get_global_transform().get_origin());
}
-
} break;
}
}
@@ -86,30 +69,11 @@ NavigationObstacle2D::~NavigationObstacle2D() {
agent = RID(); // Pointless
}
-void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) {
- if (navigation == p_nav) {
- return; // Pointless
- }
-
- navigation = p_nav;
- NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
-}
-
-void NavigationObstacle2D::set_navigation_node(Node *p_nav) {
- Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
- ERR_FAIL_COND(nav == nullptr);
- set_navigation(nav);
-}
-
-Node *NavigationObstacle2D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
-}
-
String NavigationObstacle2D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!Object::cast_to<Node2D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object.");
@@ -119,40 +83,37 @@ String NavigationObstacle2D::get_configuration_warning() const {
}
void NavigationObstacle2D::update_agent_shape() {
- Node *node = get_parent();
-
- // Estimate the radius of this physics body
- real_t radius = 0.0;
- for (int i(0); i < node->get_child_count(); i++) {
- // For each collision shape
- CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(node->get_child(i));
- if (cs) {
- // Take the distance between the Body center to the shape center
- real_t r = cs->get_transform().get_origin().length();
- if (cs->get_shape().is_valid()) {
- // and add the enclosing shape radius
- r += cs->get_shape()->get_enclosing_radius();
+ if (parent_node2d) {
+ // Estimate the radius of this physics body
+ real_t radius = 0.0;
+ for (int i(0); i < parent_node2d->get_child_count(); i++) {
+ // For each collision shape
+ CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(parent_node2d->get_child(i));
+ if (cs) {
+ // Take the distance between the Body center to the shape center
+ real_t r = cs->get_transform().get_origin().length();
+ if (cs->get_shape().is_valid()) {
+ // and add the enclosing shape radius
+ r += cs->get_shape()->get_enclosing_radius();
+ }
+ Size2 s = cs->get_global_transform().get_scale();
+ r *= MAX(s.x, s.y);
+ // Takes the biggest radius
+ radius = MAX(radius, r);
}
- Size2 s = cs->get_global_transform().get_scale();
- r *= MAX(s.x, s.y);
- // Takes the biggest radius
- radius = MAX(radius, r);
}
- }
- Node2D *node_2d = Object::cast_to<Node2D>(node);
- if (node_2d) {
- Vector2 s = node_2d->get_global_transform().get_scale();
+ Vector2 s = parent_node2d->get_global_transform().get_scale();
radius *= MAX(s.x, s.y);
- }
- if (radius == 0.0) {
- radius = 1.0; // Never a 0 radius
- }
+ if (radius == 0.0) {
+ radius = 1.0; // Never a 0 radius
+ }
- // Initialize the Agent as an object
- NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
- NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0);
- NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0);
- NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
- NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ // Initialize the Agent as an object
+ NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
+ NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0);
+ NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0);
+ NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
+ NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ }
}
diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h
index d65f44bc0e..135ca4651e 100644
--- a/scene/2d/navigation_obstacle_2d.h
+++ b/scene/2d/navigation_obstacle_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,15 +31,13 @@
#ifndef NAVIGATION_OBSTACLE_2D_H
#define NAVIGATION_OBSTACLE_2D_H
+#include "scene/2d/node_2d.h"
#include "scene/main/node.h"
-class Navigation2D;
-
class NavigationObstacle2D : public Node {
GDCLASS(NavigationObstacle2D, Node);
- Navigation2D *navigation = nullptr;
-
+ Node2D *parent_node2d = nullptr;
RID agent;
protected:
@@ -50,14 +48,6 @@ public:
NavigationObstacle2D();
virtual ~NavigationObstacle2D();
- void set_navigation(Navigation2D *p_nav);
- const Navigation2D *get_navigation() const {
- return navigation;
- }
-
- void set_navigation_node(Node *p_nav);
- Node *get_navigation_node() const;
-
RID get_rid() const {
return agent;
}
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index 98817ec03e..794993f892 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,10 +34,9 @@
#include "core/core_string_names.h"
#include "core/math/geometry_2d.h"
#include "core/os/mutex.h"
-#include "navigation_2d.h"
#include "servers/navigation_server_2d.h"
-#include "thirdparty/misc/triangulator.h"
+#include "thirdparty/misc/polypartition.h"
#ifdef TOOLS_ENABLED
Rect2 NavigationPolygon::_edit_get_rect() const {
@@ -228,7 +227,7 @@ void NavigationPolygon::make_polygons_from_outlines() {
MutexLock lock(navmesh_generation);
navmesh.unref();
}
- List<TriangulatorPoly> in_poly, out_poly;
+ List<TPPLPoly> in_poly, out_poly;
Vector2 outside_point(-1e10, -1e10);
@@ -278,23 +277,23 @@ void NavigationPolygon::make_polygons_from_outlines() {
bool outer = (interscount % 2) == 0;
- TriangulatorPoly tp;
+ TPPLPoly tp;
tp.Init(olsize);
for (int j = 0; j < olsize; j++) {
tp[j] = r[j];
}
if (outer) {
- tp.SetOrientation(TRIANGULATOR_CCW);
+ tp.SetOrientation(TPPL_ORIENTATION_CCW);
} else {
- tp.SetOrientation(TRIANGULATOR_CW);
+ tp.SetOrientation(TPPL_ORIENTATION_CW);
tp.SetHole(true);
}
in_poly.push_back(tp);
}
- TriangulatorPartition tpart;
+ TPPLPartition tpart;
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
ERR_PRINT("NavigationPolygon: Convex partition failed!");
return;
@@ -304,8 +303,8 @@ void NavigationPolygon::make_polygons_from_outlines() {
vertices.resize(0);
Map<Vector2, int> points;
- for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
- TriangulatorPoly &tp = I->get();
+ for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
+ TPPLPoly &tp = I->get();
struct Polygon p;
@@ -366,9 +365,7 @@ void NavigationRegion2D::set_enabled(bool p_enabled) {
if (!enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
} else {
- if (navigation) {
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
+ NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
}
if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) {
@@ -380,6 +377,14 @@ bool NavigationRegion2D::is_enabled() const {
return enabled;
}
+void NavigationRegion2D::set_layers(uint32_t p_layers) {
+ NavigationServer2D::get_singleton()->region_set_layers(region, p_layers);
+}
+
+uint32_t NavigationRegion2D::get_layers() const {
+ return NavigationServer2D::get_singleton()->region_get_layers(region);
+}
+
/////////////////////////////
#ifdef TOOLS_ENABLED
Rect2 NavigationRegion2D::_edit_get_rect() const {
@@ -394,29 +399,15 @@ bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
void NavigationRegion2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node2D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation2D>(c);
- if (navigation) {
- if (enabled) {
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
- break;
- }
-
- c = Object::cast_to<Node2D>(c->get_parent());
+ if (enabled) {
+ NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
}
-
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform());
-
} break;
case NOTIFICATION_EXIT_TREE: {
- if (navigation) {
- NavigationServer2D::get_singleton()->region_set_map(region, RID());
- }
- navigation = nullptr;
+ NavigationServer2D::get_singleton()->region_set_map(region, RID());
} break;
case NOTIFICATION_DRAW: {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) {
@@ -481,7 +472,6 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_
}
_navpoly_changed();
- _change_notify("navpoly");
update_configuration_warning();
}
@@ -503,23 +493,13 @@ String NavigationRegion2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!navpoly.is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon.");
}
- const Node2D *c = this;
- while (c) {
- if (Object::cast_to<Navigation2D>(c)) {
- return warning;
- }
- c = Object::cast_to<Node2D>(c->get_parent());
- }
- if (!warning.empty()) {
- warning += "\n\n";
- }
- return warning + TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data.");
+ return warning;
}
void NavigationRegion2D::_bind_methods() {
@@ -529,10 +509,14 @@ void NavigationRegion2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion2D::is_enabled);
+ ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion2D::set_layers);
+ ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion2D::get_layers);
+
ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_layers", "get_layers");
}
NavigationRegion2D::NavigationRegion2D() {
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index ba92d27a95..7b471bd555 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -91,14 +91,11 @@ public:
~NavigationPolygon() {}
};
-class Navigation2D;
-
class NavigationRegion2D : public Node2D {
GDCLASS(NavigationRegion2D, Node2D);
bool enabled = true;
RID region;
- Navigation2D *navigation = nullptr;
Ref<NavigationPolygon> navpoly;
void _navpoly_changed();
@@ -116,6 +113,9 @@ public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
+ void set_layers(uint32_t p_layers);
+ uint32_t get_layers() const;
+
void set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly);
Ref<NavigationPolygon> get_navigation_polygon() const;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index a2f687cd96..bf311632c8 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,12 +53,6 @@ void Node2D::_edit_set_state(const Dictionary &p_state) {
skew = p_state["skew"];
_update_transform();
- _change_notify("rotation");
- _change_notify("rotation_degrees");
- _change_notify("scale");
- _change_notify("skew");
- _change_notify("skew_degrees");
- _change_notify("position");
}
void Node2D::_edit_set_position(const Point2 &p_position) {
@@ -80,8 +74,6 @@ Size2 Node2D::_edit_get_scale() const {
void Node2D::_edit_set_rotation(float p_rotation) {
angle = p_rotation;
_update_transform();
- _change_notify("rotation");
- _change_notify("rotation_degrees");
}
float Node2D::_edit_get_rotation() const {
@@ -124,8 +116,6 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) {
_scale *= new_scale;
_update_transform();
- _change_notify("scale");
- _change_notify("position");
}
#endif
@@ -156,7 +146,6 @@ void Node2D::set_position(const Point2 &p_pos) {
}
pos = p_pos;
_update_transform();
- _change_notify("position");
}
void Node2D::set_rotation(float p_radians) {
@@ -165,8 +154,6 @@ void Node2D::set_rotation(float p_radians) {
}
angle = p_radians;
_update_transform();
- _change_notify("rotation");
- _change_notify("rotation_degrees");
}
void Node2D::set_skew(float p_radians) {
@@ -175,8 +162,6 @@ void Node2D::set_skew(float p_radians) {
}
skew = p_radians;
_update_transform();
- _change_notify("skew");
- _change_notify("skew_degrees");
}
void Node2D::set_rotation_degrees(float p_degrees) {
@@ -200,7 +185,6 @@ void Node2D::set_scale(const Size2 &p_scale) {
_scale.y = CMP_EPSILON;
}
_update_transform();
- _change_notify("scale");
}
Point2 Node2D::get_position() const {
@@ -358,7 +342,6 @@ void Node2D::set_z_index(int p_z) {
ERR_FAIL_COND(p_z > RS::CANVAS_ITEM_Z_MAX);
z_index = p_z;
RS::get_singleton()->canvas_item_set_z_index(get_canvas_item(), z_index);
- _change_notify("z_index");
}
void Node2D::set_z_as_relative(bool p_enabled) {
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index a66e7f625d..c27d740b8a 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,9 +37,9 @@ class Node2D : public CanvasItem {
GDCLASS(Node2D, CanvasItem);
Point2 pos;
- float angle = 0;
+ float angle = 0.0;
Size2 _scale = Vector2(1, 1);
- float skew = 0;
+ float skew = 0.0;
int z_index = 0;
bool z_relative = true;
diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp
index 8c9432f2fa..c93915d1bc 100644
--- a/scene/2d/parallax_background.cpp
+++ b/scene/2d/parallax_background.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -185,9 +185,5 @@ void ParallaxBackground::_bind_methods() {
}
ParallaxBackground::ParallaxBackground() {
- scale = 1.0;
set_layer(-100); //behind all by default
-
- base_scale = Vector2(1, 1);
- ignore_camera_zoom = false;
}
diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h
index 1667880ddb..c9991efc9d 100644
--- a/scene/2d/parallax_background.h
+++ b/scene/2d/parallax_background.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,15 +39,15 @@ class ParallaxBackground : public CanvasLayer {
GDCLASS(ParallaxBackground, CanvasLayer);
Point2 offset;
- float scale;
+ float scale = 1.0;
Point2 base_offset;
- Point2 base_scale;
+ Point2 base_scale = Vector2(1, 1);
Point2 screen_offset;
String group_name;
Point2 limit_begin;
Point2 limit_end;
Point2 final_offset;
- bool ignore_camera_zoom;
+ bool ignore_camera_zoom = false;
void _update_scroll();
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index 01aa5838b4..a38338e1e3 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -139,7 +139,7 @@ String ParallaxLayer::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<ParallaxBackground>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node.");
@@ -163,5 +163,4 @@ void ParallaxLayer::_bind_methods() {
}
ParallaxLayer::ParallaxLayer() {
- motion_scale = Size2(1, 1);
}
diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h
index 788df19a75..86694c7724 100644
--- a/scene/2d/parallax_layer.h
+++ b/scene/2d/parallax_layer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,7 @@ class ParallaxLayer : public Node2D {
Point2 orig_offset;
Point2 orig_scale;
- Size2 motion_scale;
+ Size2 motion_scale = Size2(1, 1);
Vector2 motion_offset;
Vector2 mirroring;
void _update_mirroring();
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index 6571474c9b..724998641f 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -200,7 +200,7 @@ void PathFollow2D::_update_transform() {
tangent_to_curve = (ahead_pos - pos).normalized();
}
- Vector2 normal_of_curve = -tangent_to_curve.tangent();
+ Vector2 normal_of_curve = -tangent_to_curve.orthogonal();
pos += tangent_to_curve * h_offset;
pos += normal_of_curve * v_offset;
@@ -240,7 +240,7 @@ bool PathFollow2D::get_cubic_interpolation() const {
void PathFollow2D::_validate_property(PropertyInfo &property) const {
if (property.name == "offset") {
- float max = 10000;
+ float max = 10000.0;
if (path && path->get_curve().is_valid()) {
max = path->get_curve()->get_baked_length();
}
@@ -257,7 +257,7 @@ String PathFollow2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!Object::cast_to<Path2D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("PathFollow2D only works when set as a child of a Path2D node.");
@@ -319,8 +319,6 @@ void PathFollow2D::set_offset(float p_offset) {
_update_transform();
}
- _change_notify("offset");
- _change_notify("unit_offset");
}
void PathFollow2D::set_h_offset(float p_h_offset) {
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 40042a04ef..a748817555 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,10 +64,10 @@ class PathFollow2D : public Node2D {
public:
private:
Path2D *path = nullptr;
- real_t offset = 0;
- real_t h_offset = 0;
- real_t v_offset = 0;
- real_t lookahead = 4;
+ real_t offset = 0.0;
+ real_t h_offset = 0.0;
+ real_t v_offset = 0.0;
+ real_t lookahead = 4.0;
bool cubic = true;
bool loop = true;
bool rotates = true;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index e314669fb0..96d8fb609b 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -111,8 +111,6 @@ bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const {
PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) :
CollisionObject2D(PhysicsServer2D::get_singleton()->body_create(), false) {
PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), p_mode);
- collision_layer = 1;
- collision_mask = 1;
set_pickable(false);
}
@@ -197,7 +195,6 @@ void StaticBody2D::_bind_methods() {
StaticBody2D::StaticBody2D() :
PhysicsBody2D(PhysicsServer2D::BODY_MODE_STATIC) {
- constant_angular_velocity = 0;
}
StaticBody2D::~StaticBody2D() {
@@ -301,7 +298,7 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
bool in_scene = E->get().in_scene;
- if (E->get().shapes.empty()) {
+ if (E->get().shapes.is_empty()) {
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree));
@@ -320,11 +317,11 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
struct _RigidBody2DInOut {
ObjectID id;
- int shape;
- int local_shape;
+ int shape = 0;
+ int local_shape = 0;
};
-bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) {
+bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) {
PhysicsServer2D::MotionResult *r = nullptr;
if (p_result.is_valid()) {
r = p_result->get_result_ptr();
@@ -611,7 +608,7 @@ void RigidBody2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_posit
PhysicsServer2D::get_singleton()->body_apply_impulse(get_rid(), p_impulse, p_position);
}
-void RigidBody2D::apply_torque_impulse(float p_torque) {
+void RigidBody2D::apply_torque_impulse(real_t p_torque) {
PhysicsServer2D::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque);
}
@@ -623,11 +620,11 @@ Vector2 RigidBody2D::get_applied_force() const {
return PhysicsServer2D::get_singleton()->body_get_applied_force(get_rid());
};
-void RigidBody2D::set_applied_torque(const float p_torque) {
+void RigidBody2D::set_applied_torque(const real_t p_torque) {
PhysicsServer2D::get_singleton()->body_set_applied_torque(get_rid(), p_torque);
};
-float RigidBody2D::get_applied_torque() const {
+real_t RigidBody2D::get_applied_torque() const {
return PhysicsServer2D::get_singleton()->body_get_applied_torque(get_rid());
};
@@ -639,7 +636,7 @@ void RigidBody2D::add_force(const Vector2 &p_force, const Vector2 &p_position) {
PhysicsServer2D::get_singleton()->body_add_force(get_rid(), p_force, p_position);
}
-void RigidBody2D::add_torque(const float p_torque) {
+void RigidBody2D::add_torque(const real_t p_torque) {
PhysicsServer2D::get_singleton()->body_add_torque(get_rid(), p_torque);
}
@@ -724,7 +721,7 @@ String RigidBody2D::get_configuration_warning() const {
String warning = CollisionObject2D::get_configuration_warning();
if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.elements[0].length() - 1.0) > 0.05 || ABS(t.elements[1].length() - 1.0) > 0.05)) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Size changes to RigidBody2D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");
@@ -841,25 +838,6 @@ void RigidBody2D::_bind_methods() {
RigidBody2D::RigidBody2D() :
PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) {
- mode = MODE_RIGID;
-
- mass = 1;
-
- gravity_scale = 1;
- linear_damp = -1;
- angular_damp = -1;
-
- max_contacts_reported = 0;
- state = nullptr;
-
- angular_velocity = 0;
- sleeping = false;
- ccd_mode = CCD_MODE_DISABLED;
-
- custom_integrator = false;
- contact_monitor = nullptr;
- can_sleep = true;
-
PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
}
@@ -906,7 +884,7 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision
Vector2 recover;
int hits = PhysicsServer2D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin);
int deepest = -1;
- float deepest_depth;
+ real_t deepest_depth;
for (int i = 0; i < hits; i++) {
if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) {
deepest = i;
@@ -966,7 +944,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
-Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) {
Vector2 body_velocity = p_linear_velocity;
Vector2 body_velocity_normal = body_velocity.normalized();
Vector2 up_direction = p_up_direction.normalized();
@@ -1057,7 +1035,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
return body_velocity;
}
-Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) {
Vector2 up_direction = p_up_direction.normalized();
bool was_on_floor = on_floor;
@@ -1123,11 +1101,11 @@ bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_moti
return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin);
}
-void KinematicBody2D::set_safe_margin(float p_margin) {
+void KinematicBody2D::set_safe_margin(real_t p_margin) {
margin = p_margin;
}
-float KinematicBody2D::get_safe_margin() const {
+real_t KinematicBody2D::get_safe_margin() const {
return margin;
}
@@ -1219,8 +1197,8 @@ void KinematicBody2D::_notification(int p_what) {
void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move, DEFVAL(true));
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 294b57eb13..2dc853b23b 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,8 +41,8 @@ class KinematicCollision2D;
class PhysicsBody2D : public CollisionObject2D {
GDCLASS(PhysicsBody2D, CollisionObject2D);
- uint32_t collision_layer;
- uint32_t collision_mask;
+ uint32_t collision_layer = 1;
+ uint32_t collision_mask = 1;
protected:
void _notification(int p_what);
@@ -74,7 +74,7 @@ class StaticBody2D : public PhysicsBody2D {
GDCLASS(StaticBody2D, PhysicsBody2D);
Vector2 constant_linear_velocity;
- real_t constant_angular_velocity;
+ real_t constant_angular_velocity = 0.0;
Ref<PhysicsMaterial> physics_material_override;
@@ -116,30 +116,30 @@ public:
};
private:
- bool can_sleep;
- PhysicsDirectBodyState2D *state;
- Mode mode;
+ bool can_sleep = true;
+ PhysicsDirectBodyState2D *state = nullptr;
+ Mode mode = MODE_RIGID;
- real_t mass;
+ real_t mass = 1.0;
Ref<PhysicsMaterial> physics_material_override;
- real_t gravity_scale;
- real_t linear_damp;
- real_t angular_damp;
+ real_t gravity_scale = 1.0;
+ real_t linear_damp = -1.0;
+ real_t angular_damp = -1.0;
Vector2 linear_velocity;
- real_t angular_velocity;
- bool sleeping;
+ real_t angular_velocity = 0.0;
+ bool sleeping = false;
- int max_contacts_reported;
+ int max_contacts_reported = 0;
- bool custom_integrator;
+ bool custom_integrator = false;
- CCDMode ccd_mode;
+ CCDMode ccd_mode = CCD_MODE_DISABLED;
struct ShapePair {
- int body_shape;
- int local_shape;
- bool tagged;
+ int body_shape = 0;
+ int local_shape = 0;
+ bool tagged = false;
bool operator<(const ShapePair &p_sp) const {
if (body_shape == p_sp.body_shape) {
return local_shape < p_sp.local_shape;
@@ -160,23 +160,23 @@ private:
};
struct BodyState {
//int rc;
- bool in_scene;
+ bool in_scene = false;
VSet<ShapePair> shapes;
};
struct ContactMonitor {
- bool locked;
+ bool locked = false;
Map<ObjectID, BodyState> body_map;
};
- ContactMonitor *contact_monitor;
+ ContactMonitor *contact_monitor = nullptr;
void _body_enter_tree(ObjectID p_id);
void _body_exit_tree(ObjectID p_id);
void _body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape);
void _direct_state_changed(Object *p_state);
- bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, float p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>());
+ bool _test_motion(const Vector2 &p_motion, bool p_infinite_inertia = true, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>());
protected:
void _notification(int p_what);
@@ -232,17 +232,17 @@ public:
void apply_central_impulse(const Vector2 &p_impulse);
void apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2());
- void apply_torque_impulse(float p_torque);
+ void apply_torque_impulse(real_t p_torque);
void set_applied_force(const Vector2 &p_force);
Vector2 get_applied_force() const;
- void set_applied_torque(const float p_torque);
- float get_applied_torque() const;
+ void set_applied_torque(const real_t p_torque);
+ real_t get_applied_torque() const;
void add_central_force(const Vector2 &p_force);
void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2());
- void add_torque(float p_torque);
+ void add_torque(real_t p_torque);
TypedArray<Node2D> get_colliding_bodies() const; //function for script
@@ -268,15 +268,15 @@ public:
Vector2 collider_vel;
ObjectID collider;
RID collider_rid;
- int collider_shape;
+ int collider_shape = 0;
Variant collider_metadata;
Vector2 remainder;
Vector2 travel;
- int local_shape;
+ int local_shape = 0;
};
private:
- float margin;
+ real_t margin;
Vector2 floor_normal;
Vector2 floor_velocity;
@@ -309,11 +309,11 @@ public:
bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision);
- void set_safe_margin(float p_margin);
- float get_safe_margin() const;
+ void set_safe_margin(real_t p_margin);
+ real_t get_safe_margin() const;
- Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
- Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true);
+ Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true);
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index 26340bb861..2bb75e5967 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -90,6 +90,12 @@ bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toler
}
#endif
+void Polygon2D::_validate_property(PropertyInfo &property) const {
+ if (!invert && property.name == "invert_border") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Polygon2D::_skeleton_bone_setup_changed() {
update();
}
@@ -155,7 +161,7 @@ void Polygon2D::_notification(int p_what) {
Rect2 bounds;
int highest_idx = -1;
float highest_y = -1e20;
- float sum = 0;
+ float sum = 0.0;
for (int i = 0; i < len; i++) {
if (i == 0) {
@@ -273,7 +279,7 @@ void Polygon2D::_notification(int p_what) {
//normalize the weights
for (int i = 0; i < vc; i++) {
- float tw = 0;
+ float tw = 0.0;
for (int j = 0; j < 4; j++) {
tw += weightsw[i * 4 + j];
}
@@ -455,6 +461,7 @@ Size2 Polygon2D::get_texture_scale() const {
void Polygon2D::set_invert(bool p_invert) {
invert = p_invert;
update();
+ notify_property_list_changed();
}
bool Polygon2D::get_invert() const {
@@ -483,7 +490,6 @@ void Polygon2D::set_offset(const Vector2 &p_offset) {
offset = p_offset;
rect_cache_dirty = true;
update();
- _change_notify("offset");
}
Vector2 Polygon2D::get_offset() const {
@@ -649,13 +655,4 @@ void Polygon2D::_bind_methods() {
}
Polygon2D::Polygon2D() {
- invert = false;
- invert_border = 100;
- antialiased = false;
- tex_rot = 0;
- tex_tile = true;
- tex_scale = Vector2(1, 1);
- color = Color(1, 1, 1);
- rect_cache_dirty = true;
- internal_vertices = 0;
}
diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h
index e2a8db414a..b329251277 100644
--- a/scene/2d/polygon_2d.h
+++ b/scene/2d/polygon_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@ class Polygon2D : public Node2D {
Vector<Vector2> uv;
Vector<Color> vertex_colors;
Array polygons;
- int internal_vertices;
+ int internal_vertices = 0;
struct Bone {
NodePath path;
@@ -49,19 +49,19 @@ class Polygon2D : public Node2D {
Vector<Bone> bone_weights;
- Color color;
+ Color color = Color(1, 1, 1);
Ref<Texture2D> texture;
- Size2 tex_scale;
+ Size2 tex_scale = Vector2(1, 1);
Vector2 tex_ofs;
- bool tex_tile;
- float tex_rot;
- bool invert;
- float invert_border;
- bool antialiased;
+ bool tex_tile = true;
+ float tex_rot = 0.0;
+ bool invert = false;
+ float invert_border = 100.0;
+ bool antialiased = false;
Vector2 offset;
- mutable bool rect_cache_dirty;
+ mutable bool rect_cache_dirty = true;
mutable Rect2 item_rect;
NodePath skeleton;
@@ -75,6 +75,7 @@ class Polygon2D : public Node2D {
protected:
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
#ifdef TOOLS_ENABLED
diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp
index 8e4165cf50..ff7a0dbac3 100644
--- a/scene/2d/position_2d.cpp
+++ b/scene/2d/position_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h
index 01b380bca8..fcaef0e6a3 100644
--- a/scene/2d/position_2d.h
+++ b/scene/2d/position_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index e53f89c46d..50625a0f39 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -159,30 +159,7 @@ void RayCast2D::_notification(int p_what) {
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
break;
}
- Transform2D xf;
- xf.rotate(target_position.angle());
- xf.translate(Vector2(target_position.length(), 0));
-
- // Draw an arrow indicating where the RayCast is pointing to
- Color draw_col = get_tree()->get_debug_collisions_color();
- if (!enabled) {
- float g = draw_col.get_v();
- draw_col.r = g;
- draw_col.g = g;
- draw_col.b = g;
- }
- 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);
- }
-
- draw_primitive(pts, cols, Vector<Vector2>());
+ _draw_debug_shape();
} break;
@@ -212,7 +189,7 @@ void RayCast2D::_update_raycast_state() {
}
PhysicsDirectSpaceState2D::RayResult rr;
-
+ bool prev_collision_state = collided;
if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) {
collided = true;
against = rr.collider_id;
@@ -224,6 +201,48 @@ void RayCast2D::_update_raycast_state() {
against = ObjectID();
against_shape = 0;
}
+
+ if (prev_collision_state != collided) {
+ update();
+ }
+}
+
+void RayCast2D::_draw_debug_shape() {
+ Color draw_col = collided ? Color(1.0, 0.01, 0) : get_tree()->get_debug_collisions_color();
+ if (!enabled) {
+ float g = draw_col.get_v();
+ draw_col.r = g;
+ draw_col.g = g;
+ draw_col.b = g;
+ }
+
+ // Draw an arrow indicating where the RayCast is pointing to
+ const float max_arrow_size = 6;
+ const float line_width = 1.4;
+ bool no_line = target_position.length() < line_width;
+ float arrow_size = CLAMP(target_position.length() * 2 / 3, line_width, max_arrow_size);
+
+ if (no_line) {
+ arrow_size = target_position.length();
+ } else {
+ draw_line(Vector2(), target_position - target_position.normalized() * arrow_size, draw_col, line_width);
+ }
+
+ Transform2D xf;
+ 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);
+ }
+
+ draw_primitive(pts, cols, Vector<Vector2>());
}
void RayCast2D::force_raycast_update() {
@@ -325,12 +344,4 @@ void RayCast2D::_bind_methods() {
}
RayCast2D::RayCast2D() {
- enabled = true;
- collided = false;
- against_shape = 0;
- collision_mask = 1;
- target_position = Vector2(0, 50);
- exclude_parent_body = true;
- collide_with_bodies = true;
- collide_with_areas = false;
}
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index 14932f782b..984c6bda49 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,20 +36,22 @@
class RayCast2D : public Node2D {
GDCLASS(RayCast2D, Node2D);
- bool enabled;
- bool collided;
+ bool enabled = true;
+ bool collided = false;
ObjectID against;
- int against_shape;
+ int against_shape = 0;
Vector2 collision_point;
Vector2 collision_normal;
Set<RID> exclude;
- uint32_t collision_mask;
- bool exclude_parent_body;
+ uint32_t collision_mask = 1;
+ bool exclude_parent_body = true;
- Vector2 target_position;
+ Vector2 target_position = Vector2(0, 50);
- bool collide_with_areas;
- bool collide_with_bodies;
+ bool collide_with_areas = false;
+ bool collide_with_bodies = true;
+
+ void _draw_debug_shape();
protected:
void _notification(int p_what);
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index 7655416ce2..f10714e28a 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -189,7 +189,7 @@ String RemoteTransform2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!has_node(remote_node) || !Object::cast_to<Node2D>(get_node(remote_node))) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Path property must point to a valid Node2D node to work.");
@@ -223,10 +223,5 @@ void RemoteTransform2D::_bind_methods() {
}
RemoteTransform2D::RemoteTransform2D() {
- use_global_coordinates = true;
- update_remote_position = true;
- update_remote_rotation = true;
- update_remote_scale = true;
-
set_notify_transform(true);
}
diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h
index 8b6f8d9678..4a26d7b339 100644
--- a/scene/2d/remote_transform_2d.h
+++ b/scene/2d/remote_transform_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,10 +40,10 @@ class RemoteTransform2D : public Node2D {
ObjectID cache;
- bool use_global_coordinates;
- bool update_remote_position;
- bool update_remote_rotation;
- bool update_remote_scale;
+ bool use_global_coordinates = true;
+ bool update_remote_position = true;
+ bool update_remote_rotation = true;
+ bool update_remote_scale = true;
void _update_remote();
void _update_cache();
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index ea1d9f5930..5728230a8c 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -136,7 +136,7 @@ int Bone2D::get_index_in_skeleton() const {
String Bone2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!skeleton) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
if (parent_bone) {
@@ -147,7 +147,7 @@ String Bone2D::get_configuration_warning() const {
}
if (rest == Transform2D(0, 0, 0, 0, 0, 0)) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("This bone lacks a proper REST pose. Go to the Skeleton2D node and set one.");
@@ -157,10 +157,6 @@ String Bone2D::get_configuration_warning() const {
}
Bone2D::Bone2D() {
- skeleton = nullptr;
- parent_bone = nullptr;
- skeleton_index = -1;
- default_length = 16;
set_notify_local_transform(true);
//this is a clever hack so the bone knows no rest has been set yet, allowing to show an error.
for (int i = 0; i < 3; i++) {
@@ -186,7 +182,7 @@ void Skeleton2D::_update_bone_setup() {
}
bone_setup_dirty = false;
- RS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true);
+ RS::get_singleton()->skeleton_allocate_data(skeleton, bones.size(), true);
bones.sort(); //sorty so they are always in the same order/index
@@ -293,9 +289,6 @@ void Skeleton2D::_bind_methods() {
}
Skeleton2D::Skeleton2D() {
- bone_setup_dirty = true;
- transform_dirty = true;
-
skeleton = RS::get_singleton()->skeleton_create();
set_notify_transform(true);
}
diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h
index 7e9ffd98e6..80ca8c80ac 100644
--- a/scene/2d/skeleton_2d.h
+++ b/scene/2d/skeleton_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,12 +43,12 @@ class Bone2D : public Node2D {
friend class AnimatedValuesBackup;
#endif
- Bone2D *parent_bone;
- Skeleton2D *skeleton;
+ Bone2D *parent_bone = nullptr;
+ Skeleton2D *skeleton = nullptr;
Transform2D rest;
- float default_length;
+ float default_length = 16.0;
- int skeleton_index;
+ int skeleton_index = -1;
protected:
void _notification(int p_what);
@@ -82,19 +82,19 @@ class Skeleton2D : public Node2D {
bool operator<(const Bone &p_bone) const {
return p_bone.bone->is_greater_than(bone);
}
- Bone2D *bone;
- int parent_index;
+ Bone2D *bone = nullptr;
+ int parent_index = 0;
Transform2D accum_transform;
Transform2D rest_inverse;
};
Vector<Bone> bones;
- bool bone_setup_dirty;
+ bool bone_setup_dirty = true;
void _make_bone_setup_dirty();
void _update_bone_setup();
- bool transform_dirty;
+ bool transform_dirty = true;
void _make_transform_dirty();
void _update_transform();
diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp
index a065565a0f..31040020dd 100644
--- a/scene/2d/sprite_2d.cpp
+++ b/scene/2d/sprite_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -155,7 +155,6 @@ void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) {
update();
emit_signal("texture_changed");
item_rect_changed();
- _change_notify("texture");
}
Ref<Texture2D> Sprite2D::get_texture() const {
@@ -176,7 +175,6 @@ void Sprite2D::set_offset(const Point2 &p_offset) {
offset = p_offset;
update();
item_rect_changed();
- _change_notify("offset");
}
Point2 Sprite2D::get_offset() const {
@@ -208,6 +206,7 @@ void Sprite2D::set_region(bool p_region) {
region = p_region;
update();
+ notify_property_list_changed();
}
bool Sprite2D::is_region() const {
@@ -224,8 +223,6 @@ void Sprite2D::set_region_rect(const Rect2 &p_region_rect) {
if (region) {
item_rect_changed();
}
-
- _change_notify("region_rect");
}
Rect2 Sprite2D::get_region_rect() const {
@@ -250,8 +247,6 @@ void Sprite2D::set_frame(int p_frame) {
frame = p_frame;
- _change_notify("frame");
- _change_notify("frame_coords");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -275,7 +270,7 @@ void Sprite2D::set_vframes(int p_amount) {
vframes = p_amount;
update();
item_rect_changed();
- _change_notify();
+ notify_property_list_changed();
}
int Sprite2D::get_vframes() const {
@@ -287,7 +282,7 @@ void Sprite2D::set_hframes(int p_amount) {
hframes = p_amount;
update();
item_rect_changed();
- _change_notify();
+ notify_property_list_changed();
}
int Sprite2D::get_hframes() const {
@@ -389,6 +384,10 @@ void Sprite2D::_validate_property(PropertyInfo &property) const {
if (property.name == "frame_coords") {
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
+
+ if (!region && (property.name == "region_rect" || property.name == "region_filter_clip")) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
}
void Sprite2D::_texture_changed() {
@@ -462,16 +461,6 @@ void Sprite2D::_bind_methods() {
}
Sprite2D::Sprite2D() {
- centered = true;
- hflip = false;
- vflip = false;
- region = false;
- region_filter_clip = false;
-
- frame = 0;
-
- vframes = 1;
- hframes = 1;
}
Sprite2D::~Sprite2D() {
diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h
index 2875d333bb..fa765f457d 100644
--- a/scene/2d/sprite_2d.h
+++ b/scene/2d/sprite_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,21 +39,21 @@ class Sprite2D : public Node2D {
Ref<Texture2D> texture;
Color specular_color;
- float shininess;
+ float shininess = 0.0;
- bool centered;
+ bool centered = true;
Point2 offset;
- bool hflip;
- bool vflip;
- bool region;
+ bool hflip = false;
+ bool vflip = false;
+ bool region = false;
Rect2 region_rect;
- bool region_filter_clip;
+ bool region_filter_clip = false;
- int frame;
+ int frame = 0;
- int vframes;
- int hframes;
+ int vframes = 1;
+ int hframes = 1;
void _get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index bff191a2bf..81a5b0b28c 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,16 +48,6 @@ int TileMap::_get_quadrant_size() const {
void TileMap::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node2D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation2D>(c);
- if (navigation) {
- break;
- }
-
- c = Object::cast_to<Node2D>(c->get_parent());
- }
-
if (use_parent) {
_clear_quadrants();
collision_parent = Object::cast_to<CollisionObject2D>(get_parent());
@@ -77,12 +67,10 @@ void TileMap::_notification(int p_what) {
_update_quadrant_space(RID());
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
Quadrant &q = E->get();
- if (navigation) {
- for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
- NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID());
- }
- q.navpoly_ids.clear();
+ for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
+ NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID());
}
+ q.navpoly_ids.clear();
if (collision_parent) {
collision_parent->remove_shape_owner(q.shape_owner_id);
@@ -96,8 +84,6 @@ void TileMap::_notification(int p_what) {
}
collision_parent = nullptr;
- navigation = nullptr;
-
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -135,11 +121,6 @@ void TileMap::_update_quadrant_transform() {
local_transform = get_transform();
}
- Transform2D nav_rel;
- if (navigation) {
- nav_rel = get_relative_transform_to_parent(navigation);
- }
-
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
Quadrant &q = E->get();
Transform2D xform;
@@ -150,9 +131,9 @@ void TileMap::_update_quadrant_transform() {
PhysicsServer2D::get_singleton()->body_set_state(q.body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
}
- if (navigation) {
+ if (bake_navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
- NavigationServer2D::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform);
+ NavigationServer2D::get_singleton()->region_set_transform(F->get().region, F->get().xform);
}
}
@@ -165,7 +146,6 @@ void TileMap::_update_quadrant_transform() {
void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
if (tile_set.is_valid()) {
tile_set->disconnect("changed", callable_mp(this, &TileMap::_recreate_quadrants));
- tile_set->remove_change_receptor(this);
}
_clear_quadrants();
@@ -173,7 +153,6 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
if (tile_set.is_valid()) {
tile_set->connect("changed", callable_mp(this, &TileMap::_recreate_quadrants));
- tile_set->add_change_receptor(this);
} else {
clear();
}
@@ -317,11 +296,6 @@ void TileMap::update_dirty_quadrants() {
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
Vector2 tofs = get_cell_draw_offset();
- Transform2D nav_rel;
- if (navigation) {
- nav_rel = get_relative_transform_to_parent(navigation);
- }
-
Vector2 qofs;
SceneTree *st = SceneTree::get_singleton();
@@ -354,12 +328,10 @@ void TileMap::update_dirty_quadrants() {
}
int shape_idx = 0;
- if (navigation) {
- for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
- NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
- }
- q.navpoly_ids.clear();
+ for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
+ NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
}
+ q.navpoly_ids.clear();
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
RS::get_singleton()->free(E->get().id);
@@ -581,7 +553,7 @@ void TileMap::update_dirty_quadrants() {
vs->canvas_item_add_set_transform(debug_canvas_item, Transform2D());
}
- if (navigation) {
+ if (bake_navigation) {
Ref<NavigationPolygon> navpoly;
Vector2 npoly_ofs;
if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
@@ -598,8 +570,8 @@ void TileMap::update_dirty_quadrants() {
_fix_cell_transform(xform, c, npoly_ofs, s);
RID region = NavigationServer2D::get_singleton()->region_create();
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- NavigationServer2D::get_singleton()->region_set_transform(region, nav_rel * xform);
+ NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
+ NavigationServer2D::get_singleton()->region_set_transform(region, xform);
NavigationServer2D::get_singleton()->region_set_navpoly(region, navpoly);
Quadrant::NavPoly np;
@@ -789,12 +761,10 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
dirty_quadrant_list.remove(&q.dirty_list);
}
- if (navigation) {
- for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
- NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
- }
- q.navpoly_ids.clear();
+ for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
+ NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
}
+ q.navpoly_ids.clear();
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
RS::get_singleton()->free(E->get().id);
@@ -1024,7 +994,9 @@ void TileMap::update_dirty_bitmask() {
void TileMap::fix_invalid_tiles() {
ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot fix invalid tiles if Tileset is not open.");
- for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
+
+ Map<PosKey, Cell> temp_tile_map = tile_map;
+ for (Map<PosKey, Cell>::Element *E = temp_tile_map.front(); E; E = E->next()) {
if (!tile_set->has_tile(get_cell(E->key().x, E->key().y))) {
set_cell(E->key().x, E->key().y, INVALID_CELL);
}
@@ -1328,7 +1300,7 @@ void TileMap::set_collision_use_parent(bool p_use_parent) {
}
_recreate_quadrants();
- _change_notify();
+ notify_property_list_changed();
update_configuration_warning();
}
@@ -1360,6 +1332,17 @@ float TileMap::get_collision_bounce() const {
return bounce;
}
+void TileMap::set_bake_navigation(bool p_bake_navigation) {
+ bake_navigation = p_bake_navigation;
+ for (Map<PosKey, Quadrant>::Element *F = quadrant_map.front(); F; F = F->next()) {
+ _make_quadrant_dirty(F);
+ }
+}
+
+bool TileMap::is_baking_navigation() {
+ return bake_navigation;
+}
+
uint32_t TileMap::get_collision_layer() const {
return collision_layer;
}
@@ -1714,7 +1697,7 @@ String TileMap::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (use_parent && !collision_parent) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
return TTR("TileMap with Use Parent on needs a parent CollisionObject2D to give shapes to. Please use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
@@ -1784,6 +1767,9 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_bounce", "value"), &TileMap::set_collision_bounce);
ClassDB::bind_method(D_METHOD("get_collision_bounce"), &TileMap::get_collision_bounce);
+ ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &TileMap::set_bake_navigation);
+ ClassDB::bind_method(D_METHOD("is_baking_navigation"), &TileMap::is_baking_navigation);
+
ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &TileMap::set_occluder_light_mask);
ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &TileMap::get_occluder_light_mask);
@@ -1842,6 +1828,9 @@ void TileMap::_bind_methods() {
ADD_GROUP("Occluder", "occluder_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask");
+ ADD_GROUP("Navigation", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation");
+
ADD_PROPERTY_DEFAULT("format", FORMAT_1);
ADD_SIGNAL(MethodInfo("settings_changed"));
@@ -1863,47 +1852,11 @@ void TileMap::_bind_methods() {
BIND_ENUM_CONSTANT(TILE_ORIGIN_BOTTOM_LEFT);
}
-void TileMap::_changed_callback(Object *p_changed, const char *p_prop) {
- if (tile_set.is_valid() && tile_set.ptr() == p_changed) {
- emit_signal("settings_changed");
- }
-}
-
TileMap::TileMap() {
- rect_cache_dirty = true;
- used_size_cache_dirty = true;
- pending_update = false;
- quadrant_order_dirty = false;
- quadrant_size = 16;
- cell_size = Size2(64, 64);
- custom_transform = Transform2D(64, 0, 0, 64, 0, 0);
- collision_layer = 1;
- collision_mask = 1;
- friction = 1;
- bounce = 0;
- mode = MODE_SQUARE;
- half_offset = HALF_OFFSET_DISABLED;
- use_parent = false;
- collision_parent = nullptr;
- use_kinematic = false;
- navigation = nullptr;
- use_y_sort = false;
- compatibility_mode = false;
- centered_textures = false;
- occluder_light_mask = 1;
- clip_uv = false;
- format = FORMAT_1; // Assume lowest possible format if none is present
-
- fp_adjust = 0.00001;
- tile_origin = TILE_ORIGIN_TOP_LEFT;
set_notify_transform(true);
set_notify_local_transform(false);
}
TileMap::~TileMap() {
- if (tile_set.is_valid()) {
- tile_set->remove_change_receptor(this);
- }
-
clear();
}
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 22b615a379..26c84a0bb9 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,7 +33,6 @@
#include "core/templates/self_list.h"
#include "core/templates/vset.h"
-#include "scene/2d/navigation_2d.h"
#include "scene/2d/node_2d.h"
#include "scene/resources/tile_set.h"
@@ -70,22 +69,22 @@ private:
};
Ref<TileSet> tile_set;
- Size2i cell_size;
- int quadrant_size;
- Mode mode;
- Transform2D custom_transform;
- HalfOffset half_offset;
- bool use_parent;
- CollisionObject2D *collision_parent;
- bool use_kinematic;
- Navigation2D *navigation;
+ Size2i cell_size = Size2(64, 64);
+ int quadrant_size = 16;
+ Mode mode = MODE_SQUARE;
+ Transform2D custom_transform = Transform2D(64, 0, 0, 64, 0, 0);
+ HalfOffset half_offset = HALF_OFFSET_DISABLED;
+ bool use_parent = false;
+ CollisionObject2D *collision_parent = nullptr;
+ bool use_kinematic = false;
+ bool bake_navigation = false;
union PosKey {
struct {
int16_t x;
int16_t y;
};
- uint32_t key;
+ uint32_t key = 0;
//using a more precise comparison so the regions can be sorted later
bool operator<(const PosKey &p_k) const { return (y == p_k.y) ? x < p_k.x : y < p_k.y; }
@@ -119,8 +118,7 @@ private:
int16_t autotile_coord_y : 16;
};
- uint64_t _u64t;
- Cell() { _u64t = 0; }
+ uint64_t _u64t = 0;
};
Map<PosKey, Cell> tile_map;
@@ -130,7 +128,7 @@ private:
Vector2 pos;
List<RID> canvas_items;
RID body;
- uint32_t shape_owner_id;
+ uint32_t shape_owner_id = 0;
SelfList<Quadrant> dirty_list;
@@ -176,27 +174,27 @@ private:
SelfList<Quadrant>::List dirty_quadrant_list;
- bool pending_update;
+ bool pending_update = false;
Rect2 rect_cache;
- bool rect_cache_dirty;
+ bool rect_cache_dirty = true;
Rect2 used_size_cache;
- bool used_size_cache_dirty;
- bool quadrant_order_dirty;
- bool use_y_sort;
- bool compatibility_mode;
- bool centered_textures;
- bool clip_uv;
- float fp_adjust;
- float friction;
- float bounce;
- uint32_t collision_layer;
- uint32_t collision_mask;
- mutable DataFormat format;
-
- TileOrigin tile_origin;
-
- int occluder_light_mask;
+ bool used_size_cache_dirty = true;
+ bool quadrant_order_dirty = false;
+ bool use_y_sort = false;
+ bool compatibility_mode = false;
+ bool centered_textures = false;
+ bool clip_uv = false;
+ float fp_adjust = 0.00001;
+ float friction = 1.0;
+ float bounce = 0.0;
+ uint32_t collision_layer = 1;
+ uint32_t collision_mask = 1;
+ mutable DataFormat format = FORMAT_1; // Assume lowest possible format if none is present
+
+ TileOrigin tile_origin = TILE_ORIGIN_TOP_LEFT;
+
+ int occluder_light_mask = 1;
void _fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc);
@@ -233,7 +231,6 @@ protected:
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const override;
- virtual void _changed_callback(Object *p_changed, const char *p_prop) override;
public:
enum {
@@ -297,6 +294,9 @@ public:
void set_collision_bounce(float p_bounce);
float get_collision_bounce() const;
+ void set_bake_navigation(bool p_bake_navigation);
+ bool is_baking_navigation();
+
void set_mode(Mode p_mode);
Mode get_mode() const;
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 4597300db8..9d6868a1b2 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -129,8 +129,11 @@ void TouchScreenButton::_notification(int p_what) {
if (shape.is_valid()) {
Color draw_col = get_tree()->get_debug_collisions_color();
- Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size();
- Vector2 pos = shape_centered ? size * 0.5f : Vector2();
+ Vector2 pos;
+ if (shape_centered && texture.is_valid()) {
+ pos = texture->get_size() * 0.5;
+ }
+
draw_set_transform_matrix(get_canvas_transform().translated(pos));
shape->draw(get_canvas_item(), draw_col);
}
@@ -251,9 +254,12 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
if (shape.is_valid()) {
check_rect = false;
- Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size();
- Transform2D xform = shape_centered ? Transform2D().translated(size * 0.5f) : Transform2D();
- touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5)));
+ Vector2 pos;
+ if (shape_centered && texture.is_valid()) {
+ pos = texture->get_size() * 0.5;
+ }
+
+ touched = shape->collide(Transform2D().translated(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5)));
}
if (bitmask.is_valid()) {
@@ -399,11 +405,6 @@ void TouchScreenButton::_bind_methods() {
}
TouchScreenButton::TouchScreenButton() {
- finger_pressed = -1;
- passby_press = false;
- visibility = VISIBILITY_ALWAYS;
- shape_centered = true;
- shape_visible = true;
unit_rect = Ref<RectangleShape2D>(memnew(RectangleShape2D));
- unit_rect->set_extents(Vector2(0.5, 0.5));
+ unit_rect->set_size(Vector2(1, 1));
}
diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h
index 287f886c2c..10820ad059 100644
--- a/scene/2d/touch_screen_button.h
+++ b/scene/2d/touch_screen_button.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,16 +50,16 @@ private:
Ref<Texture2D> texture_pressed;
Ref<BitMap> bitmask;
Ref<Shape2D> shape;
- bool shape_centered;
- bool shape_visible;
+ bool shape_centered = true;
+ bool shape_visible = true;
Ref<RectangleShape2D> unit_rect;
StringName action;
- bool passby_press;
- int finger_pressed;
+ bool passby_press = false;
+ int finger_pressed = -1;
- VisibilityMode visibility;
+ VisibilityMode visibility = VISIBILITY_ALWAYS;
void _input(const Ref<InputEvent> &p_event);
diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp
index e217f2a394..916038a1f3 100644
--- a/scene/2d/visibility_notifier_2d.cpp
+++ b/scene/2d/visibility_notifier_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -89,8 +89,6 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) {
item_rect_changed();
}
}
-
- _change_notify("rect");
}
Rect2 VisibilityNotifier2D::get_rect() const {
@@ -317,7 +315,7 @@ String VisibilityEnabler2D::get_configuration_warning() const {
#ifdef TOOLS_ENABLED
if (is_inside_tree() && get_parent() && (get_parent()->get_filename() == String() && get_parent() != get_tree()->get_edited_scene_root())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("VisibilityEnabler2D works best when used with the edited scene root directly as parent.");
@@ -363,6 +361,4 @@ VisibilityEnabler2D::VisibilityEnabler2D() {
}
enabler[ENABLER_PARENT_PROCESS] = false;
enabler[ENABLER_PARENT_PHYSICS_PROCESS] = false;
-
- visible = false;
}
diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h
index 671378bd4e..3d1701a1e5 100644
--- a/scene/2d/visibility_notifier_2d.h
+++ b/scene/2d/visibility_notifier_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -85,7 +85,7 @@ protected:
virtual void _screen_enter() override;
virtual void _screen_exit() override;
- bool visible;
+ bool visible = false;
void _find_nodes(Node *p_node);
diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp
index 7c2b41db70..7e7bc27cc2 100644
--- a/scene/2d/y_sort.cpp
+++ b/scene/2d/y_sort.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,6 +48,5 @@ void YSort::_bind_methods() {
}
YSort::YSort() {
- sort_enabled = true;
RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true);
}
diff --git a/scene/2d/y_sort.h b/scene/2d/y_sort.h
index 62787d6744..7d36ee3391 100644
--- a/scene/2d/y_sort.h
+++ b/scene/2d/y_sort.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,7 +35,7 @@
class YSort : public Node2D {
GDCLASS(YSort, Node2D);
- bool sort_enabled;
+ bool sort_enabled = true;
static void _bind_methods();
public:
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index b1adb0e88e..23eda379be 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -640,13 +640,13 @@ void Area3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_reverb_uniformity", "amount"), &Area3D::set_reverb_uniformity);
ClassDB::bind_method(D_METHOD("get_reverb_uniformity"), &Area3D::get_reverb_uniformity);
- ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
- ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
- ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
- ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
+ ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D")));
+ ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D")));
- ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
- ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
+ ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D")));
ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D")));
@@ -681,29 +681,10 @@ void Area3D::_bind_methods() {
Area3D::Area3D() :
CollisionObject3D(PhysicsServer3D::get_singleton()->area_create(), true) {
- space_override = SPACE_OVERRIDE_DISABLED;
set_gravity(9.8);
- locked = false;
set_gravity_vector(Vector3(0, -1, 0));
- gravity_is_point = false;
- gravity_distance_scale = 0;
- linear_damp = 0.1;
- angular_damp = 0.1;
- priority = 0;
- monitoring = false;
- monitorable = false;
- collision_mask = 1;
- collision_layer = 1;
set_monitoring(true);
set_monitorable(true);
-
- audio_bus_override = false;
- audio_bus = "Master";
-
- use_reverb_bus = false;
- reverb_bus = "Master";
- reverb_amount = 0.0;
- reverb_uniformity = 0.0;
}
Area3D::~Area3D() {
diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h
index 51f6317517..6d976115f7 100644
--- a/scene/3d/area_3d.h
+++ b/scene/3d/area_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,19 +47,19 @@ public:
};
private:
- SpaceOverride space_override;
+ SpaceOverride space_override = SPACE_OVERRIDE_DISABLED;
Vector3 gravity_vec;
real_t gravity;
- bool gravity_is_point;
- real_t gravity_distance_scale;
- real_t angular_damp;
- real_t linear_damp;
- uint32_t collision_mask;
- uint32_t collision_layer;
- int priority;
- bool monitoring;
- bool monitorable;
- bool locked;
+ bool gravity_is_point = false;
+ real_t gravity_distance_scale = 0.0;
+ real_t angular_damp = 0.1;
+ real_t linear_damp = 0.1;
+ uint32_t collision_mask = 1;
+ uint32_t collision_layer = 1;
+ int priority = 0;
+ bool monitoring = false;
+ bool monitorable = false;
+ bool locked = false;
void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape);
@@ -67,8 +67,8 @@ private:
void _body_exit_tree(ObjectID p_id);
struct ShapePair {
- int body_shape;
- int area_shape;
+ int body_shape = 0;
+ int area_shape = 0;
bool operator<(const ShapePair &p_sp) const {
if (body_shape == p_sp.body_shape) {
return area_shape < p_sp.area_shape;
@@ -85,8 +85,8 @@ private:
};
struct BodyState {
- int rc;
- bool in_tree;
+ int rc = 0;
+ bool in_tree = false;
VSet<ShapePair> shapes;
};
@@ -98,8 +98,8 @@ private:
void _area_exit_tree(ObjectID p_id);
struct AreaShapePair {
- int area_shape;
- int self_shape;
+ int area_shape = 0;
+ int self_shape = 0;
bool operator<(const AreaShapePair &p_sp) const {
if (area_shape == p_sp.area_shape) {
return self_shape < p_sp.self_shape;
@@ -116,21 +116,21 @@ private:
};
struct AreaState {
- int rc;
- bool in_tree;
+ int rc = 0;
+ bool in_tree = false;
VSet<AreaShapePair> shapes;
};
Map<ObjectID, AreaState> area_map;
void _clear_monitoring();
- bool audio_bus_override;
- StringName audio_bus;
+ bool audio_bus_override = false;
+ StringName audio_bus = "Master";
- bool use_reverb_bus;
- StringName reverb_bus;
- float reverb_amount;
- float reverb_uniformity;
+ bool use_reverb_bus = false;
+ StringName reverb_bus = "Master";
+ float reverb_amount = 0.0;
+ float reverb_uniformity = 0.0;
void _validate_property(PropertyInfo &property) const override;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 2907eb3c7e..72392be5bd 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,8 +42,8 @@ class Spcap {
private:
struct Speaker {
Vector3 direction;
- real_t effective_number_of_speakers; // precalculated
- mutable real_t squared_gain; // temporary
+ real_t effective_number_of_speakers = 0; // precalculated
+ mutable real_t squared_gain = 0; // temporary
};
Vector<Speaker> speakers;
@@ -138,15 +138,15 @@ void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tig
}
void AudioStreamPlayer3D::_mix_audio() {
- if (!stream_playback.is_valid() || !active ||
+ if (!stream_playback.is_valid() || !active.is_set() ||
(stream_paused && !stream_paused_fade_out)) {
return;
}
bool started = false;
- if (setseek >= 0.0) {
- stream_playback->start(setseek);
- setseek = -1.0; //reset seek
+ if (setseek.get() >= 0.0) {
+ stream_playback->start(setseek.get());
+ setseek.set(-1.0); //reset seek
started = true;
}
@@ -160,14 +160,14 @@ void AudioStreamPlayer3D::_mix_audio() {
}
// Mix if we're not paused or we're fading out
- if ((output_count > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) {
+ if ((output_count.get() > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) {
float output_pitch_scale = 0.0;
- if (output_count) {
+ if (output_count.get()) {
//used for doppler, not realistic but good enough
- for (int i = 0; i < output_count; i++) {
+ for (int i = 0; i < output_count.get(); i++) {
output_pitch_scale += outputs[i].pitch_scale;
}
- output_pitch_scale /= float(output_count);
+ output_pitch_scale /= float(output_count.get());
} else {
output_pitch_scale = 1.0;
}
@@ -176,7 +176,7 @@ void AudioStreamPlayer3D::_mix_audio() {
}
//write all outputs
- for (int i = 0; i < output_count; i++) {
+ for (int i = 0; i < output_count.get(); i++) {
Output current = outputs[i];
//see if current output exists, to keep volume ramp
@@ -285,14 +285,14 @@ void AudioStreamPlayer3D::_mix_audio() {
prev_outputs[i] = current;
}
- prev_output_count = output_count;
+ prev_output_count = output_count.get();
//stream is no longer active, disable this.
if (!stream_playback->is_playing()) {
- active = false;
+ active.clear();
}
- output_ready = false;
+ output_ready.clear();
stream_paused_fade_in = false;
stream_paused_fade_out = false;
}
@@ -360,7 +360,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
//update anything related to position first, if possible of course
- if (!output_ready) {
+ if (!output_ready.is_set()) {
Vector3 linear_velocity;
//compute linear velocity for doppler
@@ -596,24 +596,20 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
}
- output_count = new_output_count;
- output_ready = true;
+ output_count.set(new_output_count);
+ output_ready.set();
}
//start playing if requested
- if (setplay >= 0.0) {
- setseek = setplay;
- active = true;
- setplay = -1;
- //do not update, this makes it easier to animate (will shut off otherwise)
- ///_change_notify("playing"); //update property in editor
+ if (setplay.get() >= 0.0) {
+ setseek.set(setplay.get());
+ active.set();
+ setplay.set(-1);
}
//stop playing if no longer active
- if (!active) {
+ if (!active.is_set()) {
set_physics_process_internal(false);
- //do not update, this makes it easier to animate (will shut off otherwise)
- //_change_notify("playing"); //update property in editor
emit_signal("finished");
}
}
@@ -627,8 +623,8 @@ void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) {
if (stream_playback.is_valid()) {
stream_playback.unref();
stream.unref();
- active = false;
- setseek = -1;
+ active.clear();
+ setseek.set(-1);
}
if (p_stream.is_valid()) {
@@ -687,30 +683,29 @@ void AudioStreamPlayer3D::play(float p_from_pos) {
}
if (stream_playback.is_valid()) {
- active = true;
- setplay = p_from_pos;
- output_ready = false;
+ setplay.set(p_from_pos);
+ output_ready.clear();
set_physics_process_internal(true);
}
}
void AudioStreamPlayer3D::seek(float p_seconds) {
if (stream_playback.is_valid()) {
- setseek = p_seconds;
+ setseek.set(p_seconds);
}
}
void AudioStreamPlayer3D::stop() {
if (stream_playback.is_valid()) {
- active = false;
+ active.clear();
set_physics_process_internal(false);
- setplay = -1;
+ setplay.set(-1);
}
}
bool AudioStreamPlayer3D::is_playing() const {
if (stream_playback.is_valid()) {
- return active; // && stream_playback->is_playing();
+ return active.is_set() || setplay.get() >= 0;
}
return false;
@@ -718,6 +713,10 @@ bool AudioStreamPlayer3D::is_playing() const {
float AudioStreamPlayer3D::get_playback_position() {
if (stream_playback.is_valid()) {
+ float ss = setseek.get();
+ if (ss >= 0.0) {
+ return ss;
+ }
return stream_playback->get_playback_position();
}
@@ -757,7 +756,7 @@ void AudioStreamPlayer3D::_set_playing(bool p_enable) {
}
bool AudioStreamPlayer3D::_is_active() const {
- return active;
+ return active.is_set();
}
void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
@@ -776,7 +775,7 @@ void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
}
void AudioStreamPlayer3D::_bus_layout_changed() {
- _change_notify();
+ notify_property_list_changed();
}
void AudioStreamPlayer3D::set_max_distance(float p_metres) {
@@ -809,7 +808,6 @@ void AudioStreamPlayer3D::set_emission_angle(float p_angle) {
ERR_FAIL_COND(p_angle < 0 || p_angle > 90);
emission_angle = p_angle;
update_gizmo();
- _change_notify("emission_angle");
}
float AudioStreamPlayer3D::get_emission_angle() const {
@@ -1002,31 +1000,6 @@ void AudioStreamPlayer3D::_bind_methods() {
}
AudioStreamPlayer3D::AudioStreamPlayer3D() {
- unit_db = 0;
- unit_size = 1;
- attenuation_model = ATTENUATION_INVERSE_DISTANCE;
- max_db = 3;
- pitch_scale = 1.0;
- autoplay = false;
- setseek = -1;
- active = false;
- output_count = 0;
- prev_output_count = 0;
- max_distance = 0;
- setplay = -1;
- output_ready = false;
- area_mask = 1;
- emission_angle = 45;
- emission_angle_enabled = false;
- emission_angle_filter_attenuation_db = -12;
- attenuation_filter_cutoff_hz = 5000;
- attenuation_filter_db = -24;
- out_of_range_mode = OUT_OF_RANGE_MIX;
- doppler_tracking = DOPPLER_TRACKING_DISABLED;
- stream_paused = false;
- stream_paused_fade_in = false;
- stream_paused_fade_out = false;
-
velocity_tracker.instance();
AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer3D::_bus_layout_changed));
set_disable_scale(true);
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 339475b469..70c535bd89 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,6 +31,7 @@
#ifndef AUDIO_STREAM_PLAYER_3D_H
#define AUDIO_STREAM_PLAYER_3D_H
+#include "core/templates/safe_refcount.h"
#include "scene/3d/node_3d.h"
#include "scene/3d/velocity_tracker_3d.h"
#include "servers/audio/audio_filter_sw.h"
@@ -71,46 +72,39 @@ private:
AudioFilterSW filter;
AudioFilterSW::Processor filter_process[8];
AudioFrame vol[4];
- float filter_gain;
- float pitch_scale;
- int bus_index;
- int reverb_bus_index;
+ float filter_gain = 0.0;
+ float pitch_scale = 0.0;
+ int bus_index = -1;
+ int reverb_bus_index = -1;
AudioFrame reverb_vol[4];
- Viewport *viewport; //pointer only used for reference to previous mix
-
- Output() {
- filter_gain = 0;
- viewport = nullptr;
- reverb_bus_index = -1;
- bus_index = -1;
- }
+ Viewport *viewport = nullptr; //pointer only used for reference to previous mix
};
Output outputs[MAX_OUTPUTS];
- volatile int output_count;
- volatile bool output_ready;
+ SafeNumeric<int> output_count;
+ SafeFlag output_ready;
//these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks)
Output prev_outputs[MAX_OUTPUTS];
- int prev_output_count;
+ int prev_output_count = 0;
Ref<AudioStreamPlayback> stream_playback;
Ref<AudioStream> stream;
Vector<AudioFrame> mix_buffer;
- volatile float setseek;
- volatile bool active;
- volatile float setplay;
-
- AttenuationModel attenuation_model;
- float unit_db;
- float unit_size;
- float max_db;
- float pitch_scale;
- bool autoplay;
- bool stream_paused;
- bool stream_paused_fade_in;
- bool stream_paused_fade_out;
+ SafeNumeric<float> setseek{ -1.0 };
+ SafeFlag active;
+ SafeNumeric<float> setplay{ -1.0 };
+
+ AttenuationModel attenuation_model = ATTENUATION_INVERSE_DISTANCE;
+ float unit_db = 0.0;
+ float unit_size = 1.0;
+ float max_db = 3.0;
+ float pitch_scale = 1.0;
+ bool autoplay = false;
+ bool stream_paused = false;
+ bool stream_paused_fade_in = false;
+ bool stream_paused_fade_out = false;
StringName bus;
static void _calc_output_vol(const Vector3 &source_dir, real_t tightness, Output &output);
@@ -122,21 +116,21 @@ private:
void _bus_layout_changed();
- uint32_t area_mask;
+ uint32_t area_mask = 1;
- bool emission_angle_enabled;
- float emission_angle;
- float emission_angle_filter_attenuation_db;
- float attenuation_filter_cutoff_hz;
- float attenuation_filter_db;
+ bool emission_angle_enabled = false;
+ float emission_angle = 45.0;
+ float emission_angle_filter_attenuation_db = -12.0;
+ float attenuation_filter_cutoff_hz = 5000.0;
+ float attenuation_filter_db = -24.0;
- float max_distance;
+ float max_distance = 0.0;
Ref<VelocityTracker3D> velocity_tracker;
- DopplerTracking doppler_tracking;
+ DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED;
- OutOfRangeMode out_of_range_mode;
+ OutOfRangeMode out_of_range_mode = OUT_OF_RANGE_MIX;
float _get_attenuation_db(float p_distance) const;
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp
index 38c9e96fbc..402e2b8f40 100644
--- a/scene/3d/baked_lightmap.cpp
+++ b/scene/3d/baked_lightmap.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,6 +78,7 @@ void BakedLightmapData::clear_users() {
}
void BakedLightmapData::_set_user_data(const Array &p_data) {
+ ERR_FAIL_COND(p_data.size() <= 0);
ERR_FAIL_COND((p_data.size() % 4) != 0);
for (int i = 0; i < p_data.size(); i += 4) {
@@ -195,7 +196,7 @@ void BakedLightmapData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uses_spherical_harmonics", "uses_spherical_harmonics"), &BakedLightmapData::set_uses_spherical_harmonics);
ClassDB::bind_method(D_METHOD("is_using_spherical_harmonics"), &BakedLightmapData::is_using_spherical_harmonics);
- ClassDB::bind_method(D_METHOD("add_user", "path", "lightmap", "offset"), &BakedLightmapData::add_user);
+ ClassDB::bind_method(D_METHOD("add_user", "path", "uv_scale", "slice_index", "sub_instance"), &BakedLightmapData::add_user);
ClassDB::bind_method(D_METHOD("get_user_count"), &BakedLightmapData::get_user_count);
ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &BakedLightmapData::get_user_path);
ClassDB::bind_method(D_METHOD("clear_users"), &BakedLightmapData::clear_users);
@@ -678,7 +679,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d
}
TypedArray<Image> images = RS::get_singleton()->bake_render_uv2(mf.mesh->get_rid(), overrides, lightmap_size);
- ERR_FAIL_COND_V(images.empty(), BAKE_ERROR_CANT_CREATE_IMAGE);
+ ERR_FAIL_COND_V(images.is_empty(), BAKE_ERROR_CANT_CREATE_IMAGE);
Ref<Image> albedo = images[RS::BAKE_CHANNEL_ALBEDO_ALPHA];
Ref<Image> orm = images[RS::BAKE_CHANNEL_ORM];
@@ -1302,7 +1303,7 @@ bool BakedLightmap::is_interior() const {
void BakedLightmap::set_environment_mode(EnvironmentMode p_mode) {
environment_mode = p_mode;
- _change_notify();
+ notify_property_list_changed();
}
BakedLightmap::EnvironmentMode BakedLightmap::get_environment_mode() const {
@@ -1466,17 +1467,4 @@ void BakedLightmap::_bind_methods() {
}
BakedLightmap::BakedLightmap() {
- environment_mode = ENVIRONMENT_MODE_DISABLED;
- environment_custom_color = Color(0.2, 0.7, 1.0);
- environment_custom_energy = 1.0;
-
- bake_quality = BAKE_QUALITY_MEDIUM;
- interior = false;
- directional = false;
-
- gen_probes = GENERATE_PROBES_DISABLED;
- use_denoiser = true;
- bounces = 1;
- bias = 0.0005;
- max_texture_size = 16384;
}
diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h
index 8808569215..e2d89ab2d0 100644
--- a/scene/3d/baked_lightmap.h
+++ b/scene/3d/baked_lightmap.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,9 +53,9 @@ class BakedLightmapData : public Resource {
struct User {
NodePath path;
- int32_t sub_instance;
+ int32_t sub_instance = 0;
Rect2 uv_scale;
- int slice_index;
+ int slice_index = 0;
};
Vector<User> users;
@@ -136,32 +136,32 @@ public:
};
private:
- BakeQuality bake_quality;
- bool use_denoiser;
- int bounces;
- float bias;
- int max_texture_size;
- bool interior;
- EnvironmentMode environment_mode;
+ BakeQuality bake_quality = BAKE_QUALITY_MEDIUM;
+ bool use_denoiser = true;
+ int bounces = 1;
+ float bias = 0.0005;
+ int max_texture_size = 16384;
+ bool interior = false;
+ EnvironmentMode environment_mode = ENVIRONMENT_MODE_DISABLED;
Ref<Sky> environment_custom_sky;
- Color environment_custom_color;
- float environment_custom_energy;
- bool directional;
- GenerateProbes gen_probes;
+ Color environment_custom_color = Color(0.2, 0.7, 1.0);
+ float environment_custom_energy = 1.0;
+ bool directional = false;
+ GenerateProbes gen_probes = GENERATE_PROBES_DISABLED;
Ref<BakedLightmapData> light_data;
struct LightsFound {
Transform xform;
- Light3D *light;
+ Light3D *light = nullptr;
};
struct MeshesFound {
Transform xform;
NodePath node_path;
- int32_t subindex;
+ int32_t subindex = 0;
Ref<Mesh> mesh;
- int32_t lightmap_scale;
+ int32_t lightmap_scale = 0;
Vector<Ref<Material>> overrides;
};
@@ -172,19 +172,20 @@ private:
struct BakeTimeData {
String text;
- int pass;
- uint64_t last_step;
+ int pass = 0;
+ uint64_t last_step = 0;
};
struct BSPSimplex {
- int vertices[4];
- int planes[4];
+ int vertices[4] = {};
+ int planes[4] = {};
};
struct BSPNode {
static const int32_t EMPTY_LEAF = INT32_MIN;
Plane plane;
- int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
+ int32_t over = EMPTY_LEAF;
+ int32_t under = EMPTY_LEAF;
};
int _bsp_get_simplex_side(const Vector<Vector3> &p_points, const LocalVector<BSPSimplex> &p_simplices, const Plane &p_plane, uint32_t p_simplex) const;
@@ -192,16 +193,16 @@ private:
struct BakeStepUD {
Lightmapper::BakeStepFunc func;
- void *ud;
- float from_percent;
- float to_percent;
+ void *ud = nullptr;
+ float from_percent = 0.0;
+ float to_percent = 0.0;
};
static bool _lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh);
struct GenProbesOctree {
Vector3i offset;
- uint32_t size;
+ uint32_t size = 0;
GenProbesOctree *children[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
~GenProbesOctree() {
for (int i = 0; i < 8; i++) {
diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp
index 68303bbfe5..5315e685a0 100644
--- a/scene/3d/bone_attachment_3d.cpp
+++ b/scene/3d/bone_attachment_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -105,7 +105,6 @@ void BoneAttachment3D::_notification(int p_what) {
}
BoneAttachment3D::BoneAttachment3D() {
- bound = false;
}
void BoneAttachment3D::_bind_methods() {
diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h
index 70b871430f..0c6d5f12b1 100644
--- a/scene/3d/bone_attachment_3d.h
+++ b/scene/3d/bone_attachment_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class BoneAttachment3D : public Node3D {
GDCLASS(BoneAttachment3D, Node3D);
- bool bound;
+ bool bound = false;
String bone_name;
void _check_bind();
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 178c5c8ff8..f0623c625e 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -209,7 +209,7 @@ void Camera3D::set_projection(Camera3D::Projection p_mode) {
if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL || p_mode == PROJECTION_FRUSTUM) {
mode = p_mode;
_update_camera_mode();
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -432,7 +432,7 @@ void Camera3D::set_keep_aspect_mode(KeepAspect p_aspect) {
keep_aspect = p_aspect;
RenderingServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH);
_update_camera_mode();
- _change_notify();
+ notify_property_list_changed();
}
Camera3D::KeepAspect Camera3D::get_keep_aspect_mode() const {
@@ -476,13 +476,13 @@ void Camera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_fov"), &Camera3D::get_fov);
ClassDB::bind_method(D_METHOD("get_frustum_offset"), &Camera3D::get_frustum_offset);
ClassDB::bind_method(D_METHOD("get_size"), &Camera3D::get_size);
- ClassDB::bind_method(D_METHOD("get_zfar"), &Camera3D::get_zfar);
- ClassDB::bind_method(D_METHOD("get_znear"), &Camera3D::get_znear);
+ ClassDB::bind_method(D_METHOD("get_far"), &Camera3D::get_far);
+ ClassDB::bind_method(D_METHOD("get_near"), &Camera3D::get_near);
ClassDB::bind_method(D_METHOD("set_fov"), &Camera3D::set_fov);
ClassDB::bind_method(D_METHOD("set_frustum_offset"), &Camera3D::set_frustum_offset);
ClassDB::bind_method(D_METHOD("set_size"), &Camera3D::set_size);
- ClassDB::bind_method(D_METHOD("set_zfar"), &Camera3D::set_zfar);
- ClassDB::bind_method(D_METHOD("set_znear"), &Camera3D::set_znear);
+ ClassDB::bind_method(D_METHOD("set_far"), &Camera3D::set_far);
+ ClassDB::bind_method(D_METHOD("set_near"), &Camera3D::set_near);
ClassDB::bind_method(D_METHOD("get_projection"), &Camera3D::get_projection);
ClassDB::bind_method(D_METHOD("set_projection"), &Camera3D::set_projection);
ClassDB::bind_method(D_METHOD("set_h_offset", "ofs"), &Camera3D::set_h_offset);
@@ -519,8 +519,8 @@ void Camera3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset"), "set_frustum_offset", "get_frustum_offset");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_EXP_RANGE, "0.001,10,0.001,or_greater"), "set_znear", "get_znear");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_EXP_RANGE, "0.01,4000,0.01,or_greater"), "set_zfar", "get_zfar");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_EXP_RANGE, "0.001,10,0.001,or_greater"), "set_near", "get_near");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_EXP_RANGE, "0.01,4000,0.01,or_greater"), "set_far", "get_far");
BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE);
BIND_ENUM_CONSTANT(PROJECTION_ORTHOGONAL);
@@ -542,7 +542,7 @@ float Camera3D::get_size() const {
return size;
}
-float Camera3D::get_znear() const {
+float Camera3D::get_near() const {
return near;
}
@@ -550,7 +550,7 @@ Vector2 Camera3D::get_frustum_offset() const {
return frustum_offset;
}
-float Camera3D::get_zfar() const {
+float Camera3D::get_far() const {
return far;
}
@@ -562,18 +562,16 @@ void Camera3D::set_fov(float p_fov) {
ERR_FAIL_COND(p_fov < 1 || p_fov > 179);
fov = p_fov;
_update_camera_mode();
- _change_notify("fov");
}
void Camera3D::set_size(float p_size) {
ERR_FAIL_COND(p_size < 0.1 || p_size > 16384);
size = p_size;
_update_camera_mode();
- _change_notify("size");
}
-void Camera3D::set_znear(float p_znear) {
- near = p_znear;
+void Camera3D::set_near(float p_near) {
+ near = p_near;
_update_camera_mode();
}
@@ -582,8 +580,8 @@ void Camera3D::set_frustum_offset(Vector2 p_offset) {
_update_camera_mode();
}
-void Camera3D::set_zfar(float p_zfar) {
- far = p_zfar;
+void Camera3D::set_far(float p_far) {
+ far = p_far;
_update_camera_mode();
}
@@ -653,24 +651,10 @@ Vector3 Camera3D::get_doppler_tracked_velocity() const {
Camera3D::Camera3D() {
camera = RenderingServer::get_singleton()->camera_create();
- size = 1;
- fov = 0;
- frustum_offset = Vector2();
- near = 0;
- far = 0;
- current = false;
- viewport = nullptr;
- force_change = false;
- mode = PROJECTION_PERSPECTIVE;
set_perspective(75.0, 0.05, 4000.0);
- keep_aspect = KEEP_HEIGHT;
- layers = 0xfffff;
- v_offset = 0;
- h_offset = 0;
RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers);
//active=false;
velocity_tracker.instance();
- doppler_tracking = DOPPLER_TRACKING_DISABLED;
set_notify_transform(true);
set_disable_scale(true);
}
@@ -689,17 +673,17 @@ float ClippedCamera3D::get_margin() const {
return margin;
}
-void ClippedCamera3D::set_process_mode(ProcessMode p_mode) {
- if (process_mode == p_mode) {
+void ClippedCamera3D::set_process_callback(ClipProcessCallback p_mode) {
+ if (process_callback == p_mode) {
return;
}
- process_mode = p_mode;
- set_process_internal(process_mode == CLIP_PROCESS_IDLE);
- set_physics_process_internal(process_mode == CLIP_PROCESS_PHYSICS);
+ process_callback = p_mode;
+ set_process_internal(process_callback == CLIP_PROCESS_IDLE);
+ set_physics_process_internal(process_callback == CLIP_PROCESS_PHYSICS);
}
-ClippedCamera3D::ProcessMode ClippedCamera3D::get_process_mode() const {
- return process_mode;
+ClippedCamera3D::ClipProcessCallback ClippedCamera3D::get_process_callback() const {
+ return process_callback;
}
Transform ClippedCamera3D::get_camera_transform() const {
@@ -844,8 +828,8 @@ void ClippedCamera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ClippedCamera3D::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &ClippedCamera3D::get_margin);
- ClassDB::bind_method(D_METHOD("set_process_mode", "process_mode"), &ClippedCamera3D::set_process_mode);
- ClassDB::bind_method(D_METHOD("get_process_mode"), &ClippedCamera3D::get_process_mode);
+ ClassDB::bind_method(D_METHOD("set_process_callback", "process_callback"), &ClippedCamera3D::set_process_callback);
+ ClassDB::bind_method(D_METHOD("get_process_callback"), &ClippedCamera3D::get_process_callback);
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &ClippedCamera3D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &ClippedCamera3D::get_collision_mask);
@@ -870,7 +854,7 @@ void ClippedCamera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_exceptions"), &ClippedCamera3D::clear_exceptions);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_GROUP("Clip To", "clip_to");
@@ -882,16 +866,10 @@ void ClippedCamera3D::_bind_methods() {
}
ClippedCamera3D::ClippedCamera3D() {
- margin = 0;
- clip_offset = 0;
- process_mode = CLIP_PROCESS_PHYSICS;
set_physics_process_internal(true);
- collision_mask = 1;
set_notify_local_transform(Engine::get_singleton()->is_editor_hint());
points.resize(5);
pyramid_shape = PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONVEX_POLYGON);
- clip_to_areas = false;
- clip_to_bodies = true;
}
ClippedCamera3D::~ClippedCamera3D() {
diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h
index 04cec92b14..cea61e4db8 100644
--- a/scene/3d/camera_3d.h
+++ b/scene/3d/camera_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,26 +57,27 @@ public:
};
private:
- bool force_change;
- bool current;
- Viewport *viewport;
+ bool force_change = false;
+ bool current = false;
+ Viewport *viewport = nullptr;
- Projection mode;
+ Projection mode = PROJECTION_PERSPECTIVE;
- float fov;
- float size;
+ float fov = 0.0;
+ float size = 1.0;
Vector2 frustum_offset;
- float near, far;
- float v_offset;
- float h_offset;
- KeepAspect keep_aspect;
+ float near = 0.0;
+ float far = 0.0;
+ float v_offset = 0.0;
+ float h_offset = 0.0;
+ KeepAspect keep_aspect = KEEP_HEIGHT;
RID camera;
RID scenario_id;
// String camera_group;
- uint32_t layers;
+ uint32_t layers = 0xfffff;
Ref<Environment> environment;
Ref<CameraEffects> effects;
@@ -87,7 +88,7 @@ private:
friend class Viewport;
void _update_audio_listener_state();
- DopplerTracking doppler_tracking;
+ DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED;
Ref<VelocityTracker3D> velocity_tracker;
protected:
@@ -121,16 +122,16 @@ public:
float get_fov() const;
float get_size() const;
- float get_zfar() const;
- float get_znear() const;
+ float get_far() const;
+ float get_near() const;
Vector2 get_frustum_offset() const;
Projection get_projection() const;
void set_fov(float p_fov);
void set_size(float p_size);
- void set_zfar(float p_zfar);
- void set_znear(float p_znear);
+ void set_far(float p_far);
+ void set_near(float p_near);
void set_frustum_offset(Vector2 p_offset);
virtual Transform get_camera_transform() const;
@@ -185,19 +186,19 @@ class ClippedCamera3D : public Camera3D {
GDCLASS(ClippedCamera3D, Camera3D);
public:
- enum ProcessMode {
+ enum ClipProcessCallback {
CLIP_PROCESS_PHYSICS,
CLIP_PROCESS_IDLE,
};
private:
- ProcessMode process_mode;
+ ClipProcessCallback process_callback = CLIP_PROCESS_PHYSICS;
RID pyramid_shape;
- float margin;
- float clip_offset;
- uint32_t collision_mask;
- bool clip_to_areas;
- bool clip_to_bodies;
+ float margin = 0.0;
+ float clip_offset = 0.0;
+ uint32_t collision_mask = 1;
+ bool clip_to_areas = false;
+ bool clip_to_bodies = true;
Set<RID> exclude;
@@ -218,8 +219,8 @@ public:
void set_margin(float p_margin);
float get_margin() const;
- void set_process_mode(ProcessMode p_mode);
- ProcessMode get_process_mode() const;
+ void set_process_callback(ClipProcessCallback p_mode);
+ ClipProcessCallback get_process_callback() const;
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
@@ -239,5 +240,5 @@ public:
~ClippedCamera3D();
};
-VARIANT_ENUM_CAST(ClippedCamera3D::ProcessMode);
+VARIANT_ENUM_CAST(ClippedCamera3D::ClipProcessCallback);
#endif
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index 356992e922..849ef7a2bf 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,6 +30,7 @@
#include "collision_object_3d.h"
+#include "mesh_instance_3d.h"
#include "scene/scene_string_names.h"
#include "servers/physics_server_3d.h"
@@ -110,6 +111,42 @@ void CollisionObject3D::_update_pickable() {
}
}
+void CollisionObject3D::_update_debug_shapes() {
+ for (Set<uint32_t>::Element *shapedata_idx = debug_shapes_to_update.front(); shapedata_idx; shapedata_idx = shapedata_idx->next()) {
+ if (shapes.has(shapedata_idx->get())) {
+ ShapeData &shapedata = shapes[shapedata_idx->get()];
+ for (int i = 0; i < shapedata.shapes.size(); i++) {
+ ShapeData::ShapeBase &s = shapedata.shapes.write[i];
+ if (s.debug_shape) {
+ s.debug_shape->queue_delete();
+ s.debug_shape = nullptr;
+ }
+ if (s.shape.is_null() || shapedata.disabled) {
+ continue;
+ }
+
+ Ref<Mesh> mesh = s.shape->get_debug_mesh();
+ MeshInstance3D *mi = memnew(MeshInstance3D);
+ mi->set_transform(shapedata.xform);
+ mi->set_mesh(mesh);
+ add_child(mi);
+ mi->force_update_transform();
+ s.debug_shape = mi;
+ }
+ }
+ }
+ debug_shapes_to_update.clear();
+}
+
+void CollisionObject3D::_update_shape_data(uint32_t p_owner) {
+ if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
+ if (debug_shapes_to_update.is_empty()) {
+ call_deferred("_update_debug_shapes");
+ }
+ debug_shapes_to_update.insert(p_owner);
+ }
+}
+
void CollisionObject3D::set_ray_pickable(bool p_ray_pickable) {
ray_pickable = p_ray_pickable;
_update_pickable();
@@ -141,6 +178,8 @@ void CollisionObject3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject3D::shape_owner_clear_shapes);
ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject3D::shape_find_owner);
+ ClassDB::bind_method(D_METHOD("_update_debug_shapes"), &CollisionObject3D::_update_debug_shapes);
+
BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
@@ -188,6 +227,7 @@ void CollisionObject3D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabl
PhysicsServer3D::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);
}
}
+ _update_shape_data(p_owner);
}
bool CollisionObject3D::is_shape_owner_disabled(uint32_t p_owner) const {
@@ -223,6 +263,8 @@ void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transf
PhysicsServer3D::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform);
}
}
+
+ _update_shape_data(p_owner);
}
Transform CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const {
@@ -245,6 +287,7 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3
ShapeData::ShapeBase s;
s.index = total_subshapes;
s.shape = p_shape;
+
if (area) {
PhysicsServer3D::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled);
} else {
@@ -253,6 +296,8 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3
sd.shapes.push_back(s);
total_subshapes++;
+
+ _update_shape_data(p_owner);
}
int CollisionObject3D::shape_owner_get_shape_count(uint32_t p_owner) const {
@@ -279,13 +324,19 @@ void CollisionObject3D::shape_owner_remove_shape(uint32_t p_owner, int p_shape)
ERR_FAIL_COND(!shapes.has(p_owner));
ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());
- int index_to_remove = shapes[p_owner].shapes[p_shape].index;
+ const ShapeData::ShapeBase &s = shapes[p_owner].shapes[p_shape];
+ int index_to_remove = s.index;
+
if (area) {
PhysicsServer3D::get_singleton()->area_remove_shape(rid, index_to_remove);
} else {
PhysicsServer3D::get_singleton()->body_remove_shape(rid, index_to_remove);
}
+ if (s.debug_shape) {
+ s.debug_shape->queue_delete();
+ }
+
shapes[p_owner].shapes.remove(p_shape);
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
@@ -325,10 +376,7 @@ uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const {
CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) {
rid = p_rid;
area = p_area;
- capture_input_on_drag = false;
- ray_pickable = true;
set_notify_transform(true);
- total_subshapes = 0;
if (p_area) {
PhysicsServer3D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id());
@@ -349,8 +397,8 @@ bool CollisionObject3D::get_capture_input_on_drag() const {
String CollisionObject3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
- if (shapes.empty()) {
- if (!warning.empty()) {
+ if (shapes.is_empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape3D or CollisionPolygon3D as a child to define its shape.");
@@ -360,8 +408,6 @@ String CollisionObject3D::get_configuration_warning() const {
}
CollisionObject3D::CollisionObject3D() {
- capture_input_on_drag = false;
- ray_pickable = true;
set_notify_transform(true);
//owner=
diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h
index 39e7df40a8..fe20176984 100644
--- a/scene/3d/collision_object_3d.h
+++ b/scene/3d/collision_object_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,36 +37,36 @@
class CollisionObject3D : public Node3D {
GDCLASS(CollisionObject3D, Node3D);
- bool area;
+ bool area = false;
RID rid;
struct ShapeData {
- Object *owner;
+ Object *owner = nullptr;
Transform xform;
struct ShapeBase {
+ Node *debug_shape = nullptr;
Ref<Shape3D> shape;
- int index;
+ int index = 0;
};
Vector<ShapeBase> shapes;
- bool disabled;
-
- ShapeData() {
- disabled = false;
- owner = nullptr;
- }
+ bool disabled = false;
};
- int total_subshapes;
+ int total_subshapes = 0;
Map<uint32_t, ShapeData> shapes;
- bool capture_input_on_drag;
- bool ray_pickable;
+ bool capture_input_on_drag = false;
+ bool ray_pickable = true;
+
+ Set<uint32_t> debug_shapes_to_update;
void _update_pickable();
+ void _update_shape_data(uint32_t p_owner);
+
protected:
CollisionObject3D(RID p_rid, bool p_area);
@@ -77,6 +77,8 @@ protected:
virtual void _mouse_enter();
virtual void _mouse_exit();
+ void _update_debug_shapes();
+
public:
uint32_t create_shape_owner(Object *p_owner);
void remove_shape_owner(uint32_t owner);
diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp
index b8a4ab74ee..e3e2eb4669 100644
--- a/scene/3d/collision_polygon_3d.cpp
+++ b/scene/3d/collision_polygon_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -70,6 +70,7 @@ void CollisionPolygon3D::_build_polygon() {
}
convex->set_points(cp);
+ convex->set_margin(margin);
parent->shape_owner_add_shape(owner_id, convex);
parent->shape_owner_set_disabled(owner_id, disabled);
}
@@ -132,13 +133,13 @@ AABB CollisionPolygon3D::get_item_rect() const {
return aabb;
}
-void CollisionPolygon3D::set_depth(float p_depth) {
+void CollisionPolygon3D::set_depth(real_t p_depth) {
depth = p_depth;
_build_polygon();
update_gizmo();
}
-float CollisionPolygon3D::get_depth() const {
+real_t CollisionPolygon3D::get_depth() const {
return depth;
}
@@ -155,18 +156,29 @@ bool CollisionPolygon3D::is_disabled() const {
return disabled;
}
+real_t CollisionPolygon3D::get_margin() const {
+ return margin;
+}
+
+void CollisionPolygon3D::set_margin(real_t p_margin) {
+ margin = p_margin;
+ if (parent) {
+ _build_polygon();
+ }
+}
+
String CollisionPolygon3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
}
- if (polygon.empty()) {
- if (!warning.empty()) {
+ if (polygon.is_empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("An empty CollisionPolygon3D has no effect on collision.");
@@ -189,18 +201,17 @@ void CollisionPolygon3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &CollisionPolygon3D::set_disabled);
ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionPolygon3D::is_disabled);
+ ClassDB::bind_method(D_METHOD("set_margin", "margin"), &CollisionPolygon3D::set_margin);
+ ClassDB::bind_method(D_METHOD("get_margin"), &CollisionPolygon3D::get_margin);
+
ClassDB::bind_method(D_METHOD("_is_editable_3d_polygon"), &CollisionPolygon3D::_is_editable_3d_polygon);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth"), "set_depth", "get_depth");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin");
}
CollisionPolygon3D::CollisionPolygon3D() {
- aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
- depth = 1.0;
set_notify_local_transform(true);
- parent = nullptr;
- owner_id = 0;
- disabled = false;
}
diff --git a/scene/3d/collision_polygon_3d.h b/scene/3d/collision_polygon_3d.h
index bab85b6011..750751b509 100644
--- a/scene/3d/collision_polygon_3d.h
+++ b/scene/3d/collision_polygon_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,16 +37,17 @@
class CollisionObject3D;
class CollisionPolygon3D : public Node3D {
GDCLASS(CollisionPolygon3D, Node3D);
+ real_t margin = 0.04;
protected:
- float depth;
- AABB aabb;
+ real_t depth = 1.0;
+ AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
Vector<Point2> polygon;
- uint32_t owner_id;
- CollisionObject3D *parent;
+ uint32_t owner_id = 0;
+ CollisionObject3D *parent = nullptr;
- bool disabled;
+ bool disabled = false;
void _build_polygon();
@@ -59,8 +60,8 @@ protected:
static void _bind_methods();
public:
- void set_depth(float p_depth);
- float get_depth() const;
+ void set_depth(real_t p_depth);
+ real_t get_depth() const;
void set_polygon(const Vector<Point2> &p_polygon);
Vector<Point2> get_polygon() const;
@@ -70,6 +71,9 @@ public:
virtual AABB get_item_rect() const;
+ real_t get_margin() const;
+ void set_margin(real_t p_margin);
+
String get_configuration_warning() const override;
CollisionPolygon3D();
diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp
index e1c691b89a..242d82ab4c 100644
--- a/scene/3d/collision_shape_3d.cpp
+++ b/scene/3d/collision_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -60,7 +60,7 @@ void CollisionShape3D::make_convex_from_siblings() {
if (m.is_valid()) {
for (int j = 0; j < m->get_surface_count(); j++) {
Array a = m->surface_get_arrays(j);
- if (!a.empty()) {
+ if (!a.is_empty()) {
Vector<Vector3> v = a[RenderingServer::ARRAY_VERTEX];
for (int k = 0; k < v.size(); k++) {
vertices.append(mi->get_transform().xform(v[k]));
@@ -100,9 +100,6 @@ void CollisionShape3D::_notification(int p_what) {
if (parent) {
_update_in_shape_owner();
}
- if (get_tree()->is_debugging_collisions_hint()) {
- _update_debug_shape();
- }
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
if (parent) {
@@ -127,14 +124,14 @@ String CollisionShape3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
}
if (!shape.is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it.");
@@ -144,7 +141,7 @@ String CollisionShape3D::get_configuration_warning() const {
Object::cast_to<RigidBody3D>(get_parent()) &&
Object::cast_to<ConcavePolygonShape3D>(*shape) &&
Object::cast_to<RigidBody3D>(get_parent())->get_mode() != RigidBody3D::MODE_STATIC) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("ConcavePolygonShape3D doesn't support RigidBody3D in another mode than static.");
@@ -163,13 +160,14 @@ void CollisionShape3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("make_convex_from_siblings"), &CollisionShape3D::make_convex_from_siblings);
ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_siblings", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
- ClassDB::bind_method(D_METHOD("_update_debug_shape"), &CollisionShape3D::_update_debug_shape);
-
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
}
void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) {
+ if (p_shape == shape) {
+ return;
+ }
if (!shape.is_null()) {
shape->unregister_owner(this);
shape->disconnect("changed", callable_mp(this, &CollisionShape3D::_shape_changed));
@@ -211,10 +209,6 @@ bool CollisionShape3D::is_disabled() const {
CollisionShape3D::CollisionShape3D() {
//indicator = RenderingServer::get_singleton()->mesh_create();
- disabled = false;
- debug_shape = nullptr;
- parent = nullptr;
- owner_id = 0;
set_notify_local_transform(true);
}
@@ -225,34 +219,9 @@ CollisionShape3D::~CollisionShape3D() {
//RenderingServer::get_singleton()->free(indicator);
}
-void CollisionShape3D::_update_debug_shape() {
- debug_shape_dirty = false;
-
- if (debug_shape) {
- debug_shape->queue_delete();
- debug_shape = nullptr;
- }
-
- Ref<Shape3D> s = get_shape();
- if (s.is_null()) {
- return;
- }
-
- Ref<Mesh> mesh = s->get_debug_mesh();
- MeshInstance3D *mi = memnew(MeshInstance3D);
- mi->set_mesh(mesh);
- add_child(mi);
- debug_shape = mi;
-}
-
void CollisionShape3D::_shape_changed() {
// If this is a heightfield shape our center may have changed
if (parent) {
_update_in_shape_owner(true);
}
-
- if (is_inside_tree() && get_tree()->is_debugging_collisions_hint() && !debug_shape_dirty) {
- debug_shape_dirty = true;
- call_deferred("_update_debug_shape");
- }
}
diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h
index 35f40d27b1..5512417f75 100644
--- a/scene/3d/collision_shape_3d.h
+++ b/scene/3d/collision_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,17 +40,13 @@ class CollisionShape3D : public Node3D {
Ref<Shape3D> shape;
- uint32_t owner_id;
- CollisionObject3D *parent;
-
- Node *debug_shape;
- bool debug_shape_dirty;
+ uint32_t owner_id = 0;
+ CollisionObject3D *parent = nullptr;
void resource_changed(RES res);
- bool disabled;
+ bool disabled = false;
protected:
- void _update_debug_shape();
void _shape_changed();
void _update_in_shape_owner(bool p_xform_only = false);
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 215d9e062c..d22d7ff3ab 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -73,7 +73,7 @@ void CPUParticles3D::set_amount(int p_amount) {
}
particle_data.resize((12 + 4 + 4) * p_amount);
- RS::get_singleton()->multimesh_allocate(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, true, true);
+ RS::get_singleton()->multimesh_allocate_data(multimesh, p_amount, RS::MULTIMESH_TRANSFORM_3D, true, true);
particle_order.resize(p_amount);
}
@@ -152,6 +152,7 @@ float CPUParticles3D::get_speed_scale() const {
}
void CPUParticles3D::set_draw_order(DrawOrder p_order) {
+ ERR_FAIL_INDEX(p_order, DRAW_ORDER_MAX);
draw_order = p_order;
}
@@ -372,7 +373,7 @@ void CPUParticles3D::set_particle_flag(ParticleFlags p_particle_flag, bool p_ena
ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX);
particle_flags[p_particle_flag] = p_enable;
if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) {
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -575,7 +576,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
cycle++;
if (one_shot && cycle > 0) {
set_emitting(false);
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -646,6 +647,8 @@ void CPUParticles3D::_particles_process(float p_delta) {
restart = true;
}
+ float tv = 0.0;
+
if (restart) {
if (!emitting) {
p.active = false;
@@ -660,12 +663,12 @@ void CPUParticles3D::_particles_process(float p_delta) {
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(0);
+ tex_anim_offset = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
p.seed = Math::rand();
@@ -676,13 +679,13 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.anim_offset_rand = Math::randf();
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
- float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0;
+ float angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0);
p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp(1.0f, float(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
} else {
//initiate velocity spread in 3D
- float angle1_rad = Math::atan2(direction.x, direction.z) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0;
- float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0;
+ float angle1_rad = Math::atan2(direction.x, direction.z) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
+ float angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * spread);
Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad));
Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad));
@@ -706,8 +709,9 @@ void CPUParticles3D::_particles_process(float p_delta) {
//do none
} break;
case EMISSION_SHAPE_SPHERE: {
- float s = 2.0 * Math::randf() - 1.0, t = 2.0 * Math_PI * Math::randf();
- float radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
+ real_t s = 2.0 * Math::randf() - 1.0;
+ real_t t = Math_TAU * Math::randf();
+ real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s);
p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s);
} break;
case EMISSION_SHAPE_BOX: {
@@ -730,7 +734,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
Vector2 normal_2d(normal.x, normal.y);
Transform2D m2;
m2.set_axis(0, normal_2d);
- m2.set_axis(1, normal_2d.tangent());
+ m2.set_axis(1, normal_2d.orthogonal());
Vector2 velocity_2d(p.velocity.x, p.velocity.y);
velocity_2d = m2.basis_xform(velocity_2d);
p.velocity.x = velocity_2d.x;
@@ -771,61 +775,63 @@ void CPUParticles3D::_particles_process(float p_delta) {
continue;
} else if (p.time > p.lifetime) {
p.active = false;
+ tv = 1.0;
} else {
uint32_t alt_seed = p.seed;
p.time += local_delta;
p.custom[1] = p.time / lifetime;
+ tv = p.time / p.lifetime;
float tex_linear_velocity = 0.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
float tex_orbit_velocity = 0.0;
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
- tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(p.custom[1]);
+ tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
}
float tex_angular_velocity = 0.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
- tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(p.custom[1]);
+ tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
float tex_linear_accel = 0.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
- tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(p.custom[1]);
+ tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
float tex_tangential_accel = 0.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
- tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
float tex_radial_accel = 0.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
- tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(p.custom[1]);
+ tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
float tex_damping = 0.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
- tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(p.custom[1]);
+ tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
float tex_angle = 0.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
- tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(p.custom[1]);
+ tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
float tex_anim_speed = 0.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
- tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(p.custom[1]);
+ tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
float tex_anim_offset = 0.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
- tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(p.custom[1]);
+ tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
Vector3 force = gravity;
@@ -855,7 +861,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
float orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]);
if (orbit_amount != 0.0) {
- float ang = orbit_amount * local_delta * Math_PI * 2.0;
+ float ang = orbit_amount * local_delta * Math_TAU;
// Not sure why the ParticlesMaterial code uses a clockwise rotation matrix,
// but we use -ang here to reproduce its behavior.
Transform2D rot = Transform2D(-ang, Vector2());
@@ -887,15 +893,15 @@ void CPUParticles3D::_particles_process(float p_delta) {
float tex_scale = 1.0;
if (curve_parameters[PARAM_SCALE].is_valid()) {
- tex_scale = curve_parameters[PARAM_SCALE]->interpolate(p.custom[1]);
+ tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
}
float tex_hue_variation = 0.0;
if (curve_parameters[PARAM_HUE_VARIATION].is_valid()) {
- tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(p.custom[1]);
+ tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}
- float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_PI * 2.0 * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
+ float hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1.0f, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
float hue_rot_c = Math::cos(hue_rot_angle);
float hue_rot_s = Math::sin(hue_rot_angle);
@@ -911,7 +917,7 @@ void CPUParticles3D::_particles_process(float p_delta) {
}
if (color_ramp.is_valid()) {
- p.color = color_ramp->get_color_at_offset(p.custom[1]) * color;
+ p.color = color_ramp->get_color_at_offset(tv) * color;
} else {
p.color = color;
}
@@ -1006,6 +1012,7 @@ void CPUParticles3D::_update_particle_data_buffer() {
sorter.compare.particles = r;
sorter.sort(order, pc);
} else if (draw_order == DRAW_ORDER_VIEW_DEPTH) {
+ ERR_FAIL_NULL(get_viewport());
Camera3D *c = get_viewport()->get_camera();
if (c) {
Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close
@@ -1067,7 +1074,7 @@ void CPUParticles3D::_update_particle_data_buffer() {
ptr += 20;
}
- can_update = true;
+ can_update.set();
}
void CPUParticles3D::_set_redraw(bool p_redraw) {
@@ -1096,9 +1103,9 @@ void CPUParticles3D::_set_redraw(bool p_redraw) {
void CPUParticles3D::_update_render_thread() {
MutexLock lock(update_mutex);
- if (can_update) {
+ if (can_update.is_set()) {
RS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
- can_update = false; //wait for next time
+ can_update.clear(); //wait for next time
}
}
@@ -1160,7 +1167,7 @@ void CPUParticles3D::_notification(int p_what) {
ptr += 20;
}
- can_update = true;
+ can_update.set();
}
}
}
@@ -1440,13 +1447,6 @@ void CPUParticles3D::_bind_methods() {
}
CPUParticles3D::CPUParticles3D() {
- time = 0;
- inactive_time = 0;
- frame_remainder = 0;
- cycle = 0;
- redraw = false;
- emitting = false;
-
set_notify_transform(true);
multimesh = RenderingServer::get_singleton()->multimesh_create();
@@ -1454,23 +1454,8 @@ CPUParticles3D::CPUParticles3D() {
set_base(multimesh);
set_emitting(true);
- set_one_shot(false);
set_amount(8);
- set_lifetime(1);
- set_fixed_fps(0);
- set_fractional_delta(true);
- set_pre_process_time(0);
- set_explosiveness_ratio(0);
- set_randomness_ratio(0);
- set_lifetime_randomness(0);
- set_use_local_coordinates(true);
-
- set_draw_order(DRAW_ORDER_INDEX);
- set_speed_scale(1);
-
- set_direction(Vector3(1, 0, 0));
- set_spread(45);
- set_flatness(0);
+
set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0);
set_param(PARAM_ANGULAR_VELOCITY, 0);
set_param(PARAM_ORBIT_VELOCITY, 0);
@@ -1497,8 +1482,6 @@ CPUParticles3D::CPUParticles3D() {
particle_flags[i] = false;
}
- can_update = false;
-
set_color(Color(1, 1, 1, 1));
}
diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h
index 8c1b8a684c..10ac32622d 100644
--- a/scene/3d/cpu_particles_3d.h
+++ b/scene/3d/cpu_particles_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#define CPU_PARTICLES_H
#include "core/templates/rid.h"
+#include "core/templates/safe_refcount.h"
#include "scene/3d/visual_instance_3d.h"
class CPUParticles3D : public GeometryInstance3D {
@@ -43,6 +44,7 @@ public:
DRAW_ORDER_INDEX,
DRAW_ORDER_LIFETIME,
DRAW_ORDER_VIEW_DEPTH,
+ DRAW_ORDER_MAX
};
enum Parameter {
@@ -78,30 +80,30 @@ public:
};
private:
- bool emitting;
+ bool emitting = false;
struct Particle {
Transform transform;
Color color;
- float custom[4];
+ float custom[4] = {};
Vector3 velocity;
- bool active;
- float angle_rand;
- float scale_rand;
- float hue_rot_rand;
- float anim_offset_rand;
- float time;
- float lifetime;
+ bool active = false;
+ float angle_rand = 0.0;
+ float scale_rand = 0.0;
+ float hue_rot_rand = 0.0;
+ float anim_offset_rand = 0.0;
+ float time = 0.0;
+ float lifetime = 0.0;
Color base_color;
- uint32_t seed;
+ uint32_t seed = 0;
};
- float time;
- float inactive_time;
- float frame_remainder;
- int cycle;
- bool redraw;
+ float time = 0.0;
+ float inactive_time = 0.0;
+ float frame_remainder = 0.0;
+ int cycle = 0;
+ bool redraw = false;
RID multimesh;
@@ -110,7 +112,7 @@ private:
Vector<int> particle_order;
struct SortLifetime {
- const Particle *particles;
+ const Particle *particles = nullptr;
bool operator()(int p_a, int p_b) const {
return particles[p_a].time > particles[p_b].time;
@@ -118,7 +120,7 @@ private:
};
struct SortAxis {
- const Particle *particles;
+ const Particle *particles = nullptr;
Vector3 axis;
bool operator()(int p_a, int p_b) const {
return axis.dot(particles[p_a].transform.origin) < axis.dot(particles[p_b].transform.origin);
@@ -127,50 +129,50 @@ private:
//
- bool one_shot;
+ bool one_shot = false;
- float lifetime;
- float pre_process_time;
- float explosiveness_ratio;
- float randomness_ratio;
- float lifetime_randomness;
- float speed_scale;
- bool local_coords;
- int fixed_fps;
- bool fractional_delta;
+ float lifetime = 1.0;
+ float pre_process_time = 0.0;
+ float explosiveness_ratio = 0.0;
+ float randomness_ratio = 0.0;
+ float lifetime_randomness = 0.0;
+ float speed_scale = 1.0;
+ bool local_coords = true;
+ int fixed_fps = 0;
+ bool fractional_delta = true;
Transform inv_emission_transform;
- volatile bool can_update;
+ SafeFlag can_update;
- DrawOrder draw_order;
+ DrawOrder draw_order = DRAW_ORDER_INDEX;
Ref<Mesh> mesh;
////////
- Vector3 direction;
- float spread;
- float flatness;
+ Vector3 direction = Vector3(1, 0, 0);
+ float spread = 45.0;
+ float flatness = 0.0;
float parameters[PARAM_MAX];
- float randomness[PARAM_MAX];
+ float randomness[PARAM_MAX] = {};
Ref<Curve> curve_parameters[PARAM_MAX];
- Color color;
+ Color color = Color(1, 1, 1, 1);
Ref<Gradient> color_ramp;
- bool particle_flags[PARTICLE_FLAG_MAX];
+ bool particle_flags[PARTICLE_FLAG_MAX] = {};
- EmissionShape emission_shape;
- float emission_sphere_radius;
- Vector3 emission_box_extents;
+ EmissionShape emission_shape = EMISSION_SHAPE_POINT;
+ float emission_sphere_radius = 1.0;
+ Vector3 emission_box_extents = Vector3(1, 1, 1);
Vector<Vector3> emission_points;
Vector<Vector3> emission_normals;
Vector<Color> emission_colors;
- int emission_point_count;
+ int emission_point_count = 0;
- Vector3 gravity;
+ Vector3 gravity = Vector3(0, -9.8, 0);
void _update_internal();
void _particles_process(float p_delta);
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index fb72e10171..7d6abe458a 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,7 +34,6 @@ void Decal::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->decal_set_extents(decal, p_extents);
update_gizmo();
- _change_notify("extents");
}
Vector3 Decal::get_extents() const {
@@ -110,6 +109,7 @@ Color Decal::get_modulate() const {
void Decal::set_enable_distance_fade(bool p_enable) {
distance_fade_enabled = p_enable;
RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length);
+ notify_property_list_changed();
}
bool Decal::is_distance_fade_enabled() const {
@@ -154,6 +154,12 @@ Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
+void Decal::_validate_property(PropertyInfo &property) const {
+ if (!distance_fade_enabled && (property.name == "distance_fade_begin" || property.name == "distance_fade_length")) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Decal::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents);
ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents);
@@ -220,18 +226,6 @@ void Decal::_bind_methods() {
}
Decal::Decal() {
- extents = Vector3(1, 1, 1);
- emission_energy = 1.0;
- modulate = Color(1, 1, 1, 1);
- albedo_mix = 1.0;
- cull_mask = (1 << 20) - 1;
- upper_fade = 0.3;
- lower_fade = 0.3;
- normal_fade = 0;
- distance_fade_enabled = false;
- distance_fade_begin = 10;
- distance_fade_length = 1;
-
decal = RenderingServer::get_singleton()->decal_create();
RS::get_singleton()->instance_set_base(get_instance(), decal);
}
diff --git a/scene/3d/decal.h b/scene/3d/decal.h
index e821461772..ce19e76de1 100644
--- a/scene/3d/decal.h
+++ b/scene/3d/decal.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,21 +49,22 @@ public:
private:
RID decal;
- Vector3 extents;
+ Vector3 extents = Vector3(1, 1, 1);
Ref<Texture2D> textures[TEXTURE_MAX];
- float emission_energy;
- float albedo_mix;
- Color modulate;
- uint32_t cull_mask;
- float normal_fade;
- float upper_fade;
- float lower_fade;
- bool distance_fade_enabled;
- float distance_fade_begin;
- float distance_fade_length;
+ float emission_energy = 1.0;
+ float albedo_mix = 1.0;
+ Color modulate = Color(1, 1, 1, 1);
+ uint32_t cull_mask = (1 << 20) - 1;
+ float normal_fade = 0.0;
+ float upper_fade = 0.3;
+ float lower_fade = 0.3;
+ bool distance_fade_enabled = false;
+ float distance_fade_begin = 10.0;
+ float distance_fade_length = 1.0;
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_extents(const Vector3 &p_extents);
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index fd592012f8..43f820e5d4 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -91,7 +91,7 @@ Dictionary GIProbeData::_get_data() const {
}
void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
- RS::get_singleton()->gi_probe_allocate(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts);
+ RS::get_singleton()->gi_probe_allocate_data(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts);
bounds = p_aabb;
to_cell_xform = p_to_cell_xform;
octree_size = p_octree_size;
@@ -221,7 +221,7 @@ RID GIProbeData::get_rid() const {
void GIProbeData::_validate_property(PropertyInfo &property) const {
if (property.name == "anisotropy_strength") {
- bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/quality/gi_probes/anisotropic");
+ bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/global_illumination/gi_probes/anisotropic");
if (!anisotropy_enabled) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
@@ -286,17 +286,6 @@ void GIProbeData::_bind_methods() {
}
GIProbeData::GIProbeData() {
- ao = 0.0;
- ao_size = 0.5;
- dynamic_range = 4;
- energy = 1.0;
- bias = 1.5;
- normal_bias = 0.0;
- propagation = 0.7;
- anisotropy_strength = 0.5;
- interior = false;
- use_two_bounces = false;
-
probe = RS::get_singleton()->gi_probe_create();
}
@@ -334,7 +323,6 @@ GIProbe::Subdiv GIProbe::get_subdiv() const {
void GIProbe::set_extents(const Vector3 &p_extents) {
extents = p_extents;
update_gizmo();
- _change_notify("extents");
}
Vector3 GIProbe::get_extents() const {
@@ -427,13 +415,16 @@ Vector3i GIProbe::get_estimated_cell_size() const {
void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 };
+ p_from_node = p_from_node ? p_from_node : get_parent();
+ ERR_FAIL_NULL(p_from_node);
+
Voxelizer baker;
baker.begin_bake(subdiv_value[subdiv], AABB(-extents, extents * 2.0));
List<PlotMesh> mesh_list;
- _find_meshes(p_from_node ? p_from_node : get_parent(), mesh_list);
+ _find_meshes(p_from_node, mesh_list);
if (bake_begin_function) {
bake_begin_function(mesh_list.size() + 1);
@@ -497,7 +488,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
bake_end_function();
}
- _change_notify(); //bake property may have changed
+ notify_property_list_changed(); //bake property may have changed
}
void GIProbe::_debug_bake() {
@@ -516,11 +507,14 @@ String GIProbe::get_configuration_warning() const {
String warning = VisualInstance3D::get_configuration_warning();
if (RenderingServer::get_singleton()->is_low_end()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.");
+ } else if (probe_data.is_null()) {
+ warning += TTR("No GIProbe data set, so this node is disabled. Bake static objects to enable GI.");
}
+
return warning;
}
@@ -550,9 +544,6 @@ void GIProbe::_bind_methods() {
}
GIProbe::GIProbe() {
- subdiv = SUBDIV_128;
- extents = Vector3(10, 10, 10);
-
gi_probe = RS::get_singleton()->gi_probe_create();
set_disable_scale(true);
}
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index 2dadf48a06..534b425557 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,16 +46,16 @@ class GIProbeData : public Resource {
AABB bounds;
Vector3 octree_size;
- float dynamic_range;
- float energy;
- float bias;
- float normal_bias;
- float propagation;
- float anisotropy_strength;
- float ao;
- float ao_size;
- bool interior;
- bool use_two_bounces;
+ float dynamic_range = 4.0;
+ float energy = 1.0;
+ float bias = 1.5;
+ float normal_bias = 0.0;
+ float propagation = 0.7;
+ float anisotropy_strength = 0.5;
+ float ao = 0.0;
+ float ao_size = 0.5;
+ bool interior = false;
+ bool use_two_bounces = false;
protected:
static void _bind_methods();
@@ -129,8 +129,8 @@ private:
RID gi_probe;
- Subdiv subdiv;
- Vector3 extents;
+ Subdiv subdiv = SUBDIV_128;
+ Vector3 extents = Vector3(10, 10, 10);
struct PlotMesh {
Ref<Material> override_material;
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index ec33d7bcab..17a61b3e4d 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -100,7 +100,6 @@ void GPUParticles3D::set_visibility_aabb(const AABB &p_aabb) {
visibility_aabb = p_aabb;
RS::get_singleton()->particles_set_custom_aabb(particles, visibility_aabb);
update_gizmo();
- _change_notify("visibility_aabb");
}
void GPUParticles3D::set_use_local_coordinates(bool p_enable) {
@@ -190,7 +189,7 @@ void GPUParticles3D::set_draw_passes(int p_count) {
ERR_FAIL_COND(p_count < 1);
draw_passes.resize(p_count);
RS::get_singleton()->particles_set_draw_passes(particles, p_count);
- _change_notify();
+ notify_property_list_changed();
}
int GPUParticles3D::get_draw_passes() const {
@@ -353,7 +352,7 @@ void GPUParticles3D::_notification(int p_what) {
// the shot ends the editor can properly update
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
if (one_shot && !is_emitting()) {
- _change_notify();
+ notify_property_list_changed();
set_process_internal(false);
}
}
diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h
index f0e5f05e5b..0c1a1a510c 100644
--- a/scene/3d/gpu_particles_3d.h
+++ b/scene/3d/gpu_particles_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp
index 1f0d5d587d..97241be60f 100644
--- a/scene/3d/gpu_particles_collision_3d.cpp
+++ b/scene/3d/gpu_particles_collision_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -293,11 +293,11 @@ void GPUParticlesCollisionSDF::_find_closest_distance(const Vector3 &p_pos, cons
SGN(cb.cross(nor).dot(pb)) +
SGN(ac.cross(nor).dot(pc)) <
2.0) ?
- MIN(MIN(
+ MIN(MIN(
Vector3_dot2(ba * CLAMP(ba.dot(pa) / Vector3_dot2(ba), 0.0, 1.0) - pa),
Vector3_dot2(cb * CLAMP(cb.dot(pb) / Vector3_dot2(cb), 0.0, 1.0) - pb)),
Vector3_dot2(ac * CLAMP(ac.dot(pc) / Vector3_dot2(ac), 0.0, 1.0) - pc)) :
- nor.dot(pa) * nor.dot(pa) / Vector3_dot2(nor));
+ nor.dot(pa) * nor.dot(pa) / Vector3_dot2(nor));
closest_distance = MIN(closest_distance, inside_d);
}
diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h
index 9b644ade6b..81c33663f3 100644
--- a/scene/3d/gpu_particles_collision_3d.h
+++ b/scene/3d/gpu_particles_collision_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -130,16 +130,16 @@ private:
LEAF_MASK = LEAF_BIT - 1
};
AABB bounds;
- uint32_t children[2];
+ uint32_t children[2] = {};
};
struct FacePos {
Vector3 center;
- uint32_t index;
+ uint32_t index = 0;
};
struct FaceSort {
- uint32_t axis;
+ uint32_t axis = 0;
bool operator()(const FacePos &p_left, const FacePos &p_right) const {
return p_left.center[axis] < p_right.center[axis];
}
@@ -148,13 +148,13 @@ private:
uint32_t _create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness);
struct ComputeSDFParams {
- float *cells;
+ float *cells = nullptr;
Vector3i size;
- float cell_size;
+ float cell_size = 0.0;
Vector3 cell_offset;
- const BVH *bvh;
- const Face3 *triangles;
- float thickness;
+ const BVH *bvh = nullptr;
+ const Face3 *triangles = nullptr;
+ float thickness = 0.0;
};
void _find_closest_distance(const Vector3 &p_pos, const BVH *bvh, uint32_t p_bvh_cell, const Face3 *triangles, float thickness, float &closest_distance);
diff --git a/scene/3d/immediate_geometry_3d.cpp b/scene/3d/immediate_geometry_3d.cpp
index 7ccfd527a1..d64babaa9d 100644
--- a/scene/3d/immediate_geometry_3d.cpp
+++ b/scene/3d/immediate_geometry_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -87,21 +87,24 @@ Vector<Face3> ImmediateGeometry3D::get_faces(uint32_t p_usage_flags) const {
}
void ImmediateGeometry3D::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) {
+ const double lat_step = Math_TAU / p_lats;
+ const double lon_step = Math_TAU / p_lons;
+
for (int i = 1; i <= p_lats; i++) {
- double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats);
+ double lat0 = lat_step * (i - 1) - Math_TAU / 4;
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
- double lat1 = Math_PI * (-0.5 + (double)i / p_lats);
+ double lat1 = lat_step * i - Math_TAU / 4;
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
for (int j = p_lons; j >= 1; j--) {
- double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons;
+ double lng0 = lon_step * (j - 1);
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
- double lng1 = 2 * Math_PI * (double)(j) / p_lons;
+ double lng1 = lon_step * j;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
@@ -147,7 +150,6 @@ void ImmediateGeometry3D::_bind_methods() {
ImmediateGeometry3D::ImmediateGeometry3D() {
im = RenderingServer::get_singleton()->immediate_create();
set_base(im);
- empty = true;
}
ImmediateGeometry3D::~ImmediateGeometry3D() {
diff --git a/scene/3d/immediate_geometry_3d.h b/scene/3d/immediate_geometry_3d.h
index 1403936e22..ee4938d9f7 100644
--- a/scene/3d/immediate_geometry_3d.h
+++ b/scene/3d/immediate_geometry_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,7 +41,7 @@ class ImmediateGeometry3D : public GeometryInstance3D {
//a list of textures drawn need to be kept, to avoid references
// in RenderingServer from becoming invalid if the texture is no longer used
List<Ref<Texture2D>> cached_textures;
- bool empty;
+ bool empty = true;
AABB aabb;
protected:
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 3f816535f5..f109640aef 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,11 +48,7 @@ void Light3D::set_param(Param p_param, float p_value) {
update_gizmo();
if (p_param == PARAM_SPOT_ANGLE) {
- _change_notify("spot_angle");
update_configuration_warning();
- } else if (p_param == PARAM_RANGE) {
- _change_notify("omni_range");
- _change_notify("spot_range");
}
}
}
@@ -69,6 +65,8 @@ void Light3D::set_shadow(bool p_enable) {
if (type == RenderingServer::LIGHT_SPOT || type == RenderingServer::LIGHT_OMNI) {
update_configuration_warning();
}
+
+ notify_property_list_changed();
}
bool Light3D::has_shadow() const {
@@ -184,8 +182,6 @@ void Light3D::_update_visibility() {
#endif
RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree() && editor_ok);
-
- _change_notify("geometry/visible");
}
void Light3D::_notification(int p_what) {
@@ -208,10 +204,18 @@ bool Light3D::is_editor_only() const {
}
void Light3D::_validate_property(PropertyInfo &property) const {
+ if (!shadow && (property.name == "shadow_color" || property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_blur")) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+
if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_size") {
property.usage = 0;
}
+ if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_specular") {
+ property.usage = 0;
+ }
+
if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") {
property.usage = 0;
}
@@ -257,7 +261,7 @@ void Light3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,64,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01"), "set_param", "get_param", PARAM_SIZE);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR);
@@ -320,10 +324,6 @@ Light3D::Light3D(RenderingServer::LightType p_type) {
RS::get_singleton()->instance_set_base(get_instance(), light);
- reverse_cull = false;
- bake_mode = BAKE_DYNAMIC;
-
- editor_only = false;
set_color(Color(1, 1, 1, 1));
set_shadow(false);
set_negative(false);
@@ -347,13 +347,12 @@ Light3D::Light3D(RenderingServer::LightType p_type) {
set_param(PARAM_SHADOW_BIAS, 0.02);
set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0);
set_param(PARAM_TRANSMITTANCE_BIAS, 0.05);
- set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 1.0);
+ set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 0.1);
set_param(PARAM_SHADOW_FADE_START, 1);
set_disable_scale(true);
}
Light3D::Light3D() {
- type = RenderingServer::LIGHT_DIRECTIONAL;
ERR_PRINT("Light3D should not be instanced directly; use the DirectionalLight3D, OmniLight3D or SpotLight3D subtypes instead.");
}
@@ -462,7 +461,7 @@ String OmniLight3D::get_configuration_warning() const {
String warning = Light3D::get_configuration_warning();
if (!has_shadow() && get_projector().is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Projector texture only works with shadows active.");
@@ -496,14 +495,14 @@ String SpotLight3D::get_configuration_warning() const {
String warning = Light3D::get_configuration_warning();
if (has_shadow() && get_param(PARAM_SPOT_ANGLE) >= 90.0) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows.");
}
if (!has_shadow() && get_projector().is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Projector texture only works with shadows active.");
diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h
index 08287a3313..311db54bce 100644
--- a/scene/3d/light_3d.h
+++ b/scene/3d/light_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,16 +71,16 @@ public:
private:
Color color;
- float param[PARAM_MAX];
+ float param[PARAM_MAX] = {};
Color shadow_color;
- bool shadow;
- bool negative;
- bool reverse_cull;
- uint32_t cull_mask;
- RS::LightType type;
- bool editor_only;
+ bool shadow = false;
+ bool negative = false;
+ bool reverse_cull = false;
+ uint32_t cull_mask = 0;
+ RS::LightType type = RenderingServer::LIGHT_DIRECTIONAL;
+ bool editor_only = false;
void _update_visibility();
- BakeMode bake_mode;
+ BakeMode bake_mode = BAKE_DYNAMIC;
Ref<Texture2D> projector;
// bind helpers
diff --git a/scene/3d/lightmap_probe.cpp b/scene/3d/lightmap_probe.cpp
index ee21934b80..830b97ffab 100644
--- a/scene/3d/lightmap_probe.cpp
+++ b/scene/3d/lightmap_probe.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/lightmap_probe.h b/scene/3d/lightmap_probe.h
index c4bd33556f..df87ed49dd 100644
--- a/scene/3d/lightmap_probe.h
+++ b/scene/3d/lightmap_probe.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/lightmapper.cpp b/scene/3d/lightmapper.cpp
index 26faf5154c..c17ac52aa2 100644
--- a/scene/3d/lightmapper.cpp
+++ b/scene/3d/lightmapper.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h
index ccf9bde279..a07a964c01 100644
--- a/scene/3d/lightmapper.h
+++ b/scene/3d/lightmapper.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp
index 0a5b9ad09f..9842f152d7 100644
--- a/scene/3d/listener_3d.cpp
+++ b/scene/3d/listener_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -159,8 +159,6 @@ void Listener3D::_bind_methods() {
}
Listener3D::Listener3D() {
- current = false;
- force_change = false;
set_notify_transform(true);
//active=false;
}
diff --git a/scene/3d/listener_3d.h b/scene/3d/listener_3d.h
index 4b6923d6e8..85657a8e53 100644
--- a/scene/3d/listener_3d.h
+++ b/scene/3d/listener_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,8 +38,8 @@ class Listener3D : public Node3D {
GDCLASS(Listener3D, Node3D);
private:
- bool force_change;
- bool current;
+ bool force_change = false;
+ bool current = false;
RID scenario_id;
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index 13f40aed4f..b997c64b29 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -95,7 +95,7 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
ls.sort();
for (List<String>::Element *E = ls.front(); E; E = E->next()) {
- p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "0,1,0.00001"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "-1,1,0.00001"));
}
if (mesh.is_valid()) {
@@ -112,7 +112,6 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
if (mesh.is_valid()) {
mesh->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &MeshInstance3D::_mesh_changed));
- materials.clear();
}
mesh = p_mesh;
@@ -136,7 +135,7 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
update_gizmo();
- _change_notify();
+ notify_property_list_changed();
}
Ref<Mesh> MeshInstance3D::get_mesh() const {
@@ -153,7 +152,7 @@ void MeshInstance3D::_resolve_skeleton_path() {
if (skin_internal.is_null()) {
//a skin was created for us
skin_internal = new_skin_reference->get_skin();
- _change_notify();
+ notify_property_list_changed();
}
}
}
@@ -320,6 +319,7 @@ Ref<Material> MeshInstance3D::get_active_material(int p_surface) const {
}
void MeshInstance3D::_mesh_changed() {
+ ERR_FAIL_COND(mesh.is_null());
materials.resize(mesh->get_surface_count());
}
@@ -429,7 +429,6 @@ void MeshInstance3D::_bind_methods() {
}
MeshInstance3D::MeshInstance3D() {
- skeleton_path = NodePath("..");
}
MeshInstance3D::~MeshInstance3D() {
diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h
index 4434e305e8..eb300784b1 100644
--- a/scene/3d/mesh_instance_3d.h
+++ b/scene/3d/mesh_instance_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,15 +44,11 @@ protected:
Ref<Skin> skin;
Ref<Skin> skin_internal;
Ref<SkinReference> skin_ref;
- NodePath skeleton_path;
+ NodePath skeleton_path = NodePath("..");
struct BlendShapeTrack {
- int idx;
- float value;
- BlendShapeTrack() {
- idx = 0;
- value = 0;
- }
+ int idx = 0;
+ float value = 0.0;
};
Map<StringName, BlendShapeTrack> blend_shape_tracks;
diff --git a/scene/3d/multimesh_instance_3d.cpp b/scene/3d/multimesh_instance_3d.cpp
index 88dff111f7..2adef115cf 100644
--- a/scene/3d/multimesh_instance_3d.cpp
+++ b/scene/3d/multimesh_instance_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/multimesh_instance_3d.h b/scene/3d/multimesh_instance_3d.h
index 6e075b7f7f..63735fd3a6 100644
--- a/scene/3d/multimesh_instance_3d.h
+++ b/scene/3d/multimesh_instance_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp
deleted file mode 100644
index 851966db2b..0000000000
--- a/scene/3d/navigation_3d.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*************************************************************************/
-/* navigation_3d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "navigation_3d.h"
-
-#include "servers/navigation_server_3d.h"
-
-Vector<Vector3> Navigation3D::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) const {
- return NavigationServer3D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
-}
-
-Vector3 Navigation3D::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const {
- return NavigationServer3D::get_singleton()->map_get_closest_point_to_segment(map, p_from, p_to, p_use_collision);
-}
-
-Vector3 Navigation3D::get_closest_point(const Vector3 &p_point) const {
- return NavigationServer3D::get_singleton()->map_get_closest_point(map, p_point);
-}
-
-Vector3 Navigation3D::get_closest_point_normal(const Vector3 &p_point) const {
- return NavigationServer3D::get_singleton()->map_get_closest_point_normal(map, p_point);
-}
-
-RID Navigation3D::get_closest_point_owner(const Vector3 &p_point) const {
- return NavigationServer3D::get_singleton()->map_get_closest_point_owner(map, p_point);
-}
-
-void Navigation3D::set_up_vector(const Vector3 &p_up) {
- up = p_up;
- NavigationServer3D::get_singleton()->map_set_up(map, up);
-}
-
-Vector3 Navigation3D::get_up_vector() const {
- return up;
-}
-
-void Navigation3D::set_cell_size(float p_cell_size) {
- cell_size = p_cell_size;
- NavigationServer3D::get_singleton()->map_set_cell_size(map, cell_size);
-}
-
-void Navigation3D::set_edge_connection_margin(float p_edge_connection_margin) {
- edge_connection_margin = p_edge_connection_margin;
- NavigationServer3D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
-}
-
-void Navigation3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_rid"), &Navigation3D::get_rid);
-
- ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation3D::get_simple_path, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "start", "end", "use_collision"), &Navigation3D::get_closest_point_to_segment, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation3D::get_closest_point);
- ClassDB::bind_method(D_METHOD("get_closest_point_normal", "to_point"), &Navigation3D::get_closest_point_normal);
- ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation3D::get_closest_point_owner);
-
- ClassDB::bind_method(D_METHOD("set_up_vector", "up"), &Navigation3D::set_up_vector);
- ClassDB::bind_method(D_METHOD("get_up_vector"), &Navigation3D::get_up_vector);
-
- ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation3D::set_cell_size);
- ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation3D::get_cell_size);
-
- ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation3D::set_edge_connection_margin);
- ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation3D::get_edge_connection_margin);
-
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), "set_up_vector", "get_up_vector");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
-}
-
-void Navigation3D::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_READY: {
- NavigationServer3D::get_singleton()->map_set_active(map, true);
- } break;
- case NOTIFICATION_EXIT_TREE: {
- NavigationServer3D::get_singleton()->map_set_active(map, false);
- } break;
- }
-}
-
-Navigation3D::Navigation3D() {
- map = NavigationServer3D::get_singleton()->map_create();
-
- set_cell_size(0.3);
- set_edge_connection_margin(5.0); // Five meters, depends a lot on the agent's radius
-
- up = Vector3(0, 1, 0);
-}
-
-Navigation3D::~Navigation3D() {
- NavigationServer3D::get_singleton()->free(map);
-}
diff --git a/scene/3d/navigation_3d.h b/scene/3d/navigation_3d.h
deleted file mode 100644
index 890caed171..0000000000
--- a/scene/3d/navigation_3d.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*************************************************************************/
-/* navigation_3d.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef NAVIGATION_3D_H
-#define NAVIGATION_3D_H
-
-#include "scene/3d/navigation_region_3d.h"
-#include "scene/3d/node_3d.h"
-
-class Navigation3D : public Node3D {
- GDCLASS(Navigation3D, Node3D);
-
- RID map;
-
- Vector3 up;
- real_t cell_size;
- real_t edge_connection_margin;
-
-protected:
- static void _bind_methods();
- void _notification(int p_what);
-
-public:
- RID get_rid() const {
- return map;
- }
-
- void set_up_vector(const Vector3 &p_up);
- Vector3 get_up_vector() const;
-
- void set_cell_size(float p_cell_size);
- float get_cell_size() const {
- return cell_size;
- }
-
- void set_edge_connection_margin(float p_edge_connection_margin);
- float get_edge_connection_margin() const {
- return edge_connection_margin;
- }
-
- Vector<Vector3> get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true) const;
- Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision = false) const;
- Vector3 get_closest_point(const Vector3 &p_point) const;
- Vector3 get_closest_point_normal(const Vector3 &p_point) const;
- RID get_closest_point_owner(const Vector3 &p_point) const;
-
- Navigation3D();
- ~Navigation3D();
-};
-
-#endif // NAVIGATION_H
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index f9f8f276a3..21ca3d70dd 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,6 @@
#include "navigation_agent_3d.h"
#include "core/config/engine.h"
-#include "scene/3d/navigation_3d.h"
#include "servers/navigation_server_3d.h"
void NavigationAgent3D::_bind_methods() {
@@ -47,9 +46,6 @@ void NavigationAgent3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ignore_y", "ignore"), &NavigationAgent3D::set_ignore_y);
ClassDB::bind_method(D_METHOD("get_ignore_y"), &NavigationAgent3D::get_ignore_y);
- ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent3D::set_navigation_node);
- ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent3D::get_navigation_node);
-
ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent3D::set_neighbor_dist);
ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent3D::get_neighbor_dist);
@@ -101,28 +97,10 @@ void NavigationAgent3D::_notification(int p_what) {
agent_parent = Object::cast_to<Node3D>(get_parent());
NavigationServer3D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
-
- // Search the navigation node and set it
- {
- Navigation3D *nav = nullptr;
- Node *p = get_parent();
- while (p != nullptr) {
- nav = Object::cast_to<Navigation3D>(p);
- if (nav != nullptr) {
- p = nullptr;
- } else {
- p = p->get_parent();
- }
- }
-
- set_navigation(nav);
- }
-
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
agent_parent = nullptr;
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -154,25 +132,6 @@ NavigationAgent3D::~NavigationAgent3D() {
agent = RID(); // Pointless
}
-void NavigationAgent3D::set_navigation(Navigation3D *p_nav) {
- if (navigation == p_nav) {
- return; // Pointless
- }
-
- navigation = p_nav;
- NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
-}
-
-void NavigationAgent3D::set_navigation_node(Node *p_nav) {
- Navigation3D *nav = Object::cast_to<Navigation3D>(p_nav);
- ERR_FAIL_COND(nav == nullptr);
- set_navigation(nav);
-}
-
-Node *NavigationAgent3D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
-}
-
void NavigationAgent3D::set_target_desired_distance(real_t p_dd) {
target_desired_distance = p_dd;
}
@@ -290,7 +249,7 @@ String NavigationAgent3D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!Object::cast_to<Node3D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The NavigationAgent3D can be used only under a spatial node.");
@@ -303,7 +262,7 @@ void NavigationAgent3D::update_navigation() {
if (agent_parent == nullptr) {
return;
}
- if (navigation == nullptr) {
+ if (!agent_parent->is_inside_tree()) {
return;
}
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
@@ -337,7 +296,7 @@ void NavigationAgent3D::update_navigation() {
}
if (reload_path) {
- navigation_path = NavigationServer3D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true);
+ navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true);
navigation_finished = false;
nav_path_index = 0;
emit_signal("path_changed");
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index dcfd302561..22db889618 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,13 +35,11 @@
#include "scene/main/node.h"
class Node3D;
-class Navigation3D;
class NavigationAgent3D : public Node {
GDCLASS(NavigationAgent3D, Node);
Node3D *agent_parent = nullptr;
- Navigation3D *navigation = nullptr;
RID agent;
@@ -76,14 +74,6 @@ public:
NavigationAgent3D();
virtual ~NavigationAgent3D();
- void set_navigation(Navigation3D *p_nav);
- const Navigation3D *get_navigation() const {
- return navigation;
- }
-
- void set_navigation_node(Node *p_nav);
- Node *get_navigation_node() const;
-
RID get_rid() const {
return agent;
}
diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp
index adbff06ed6..df03bca4fd 100644
--- a/scene/3d/navigation_obstacle_3d.cpp
+++ b/scene/3d/navigation_obstacle_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,55 +31,38 @@
#include "navigation_obstacle_3d.h"
#include "scene/3d/collision_shape_3d.h"
-#include "scene/3d/navigation_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "servers/navigation_server_3d.h"
void NavigationObstacle3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle3D::set_navigation_node);
- ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle3D::get_navigation_node);
}
void NavigationObstacle3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
- update_agent_shape();
-
- // Search the navigation node and set it
- {
- Navigation3D *nav = nullptr;
- Node *p = get_parent();
- while (p != nullptr) {
- nav = Object::cast_to<Navigation3D>(p);
- if (nav != nullptr) {
- p = nullptr;
- } else {
- p = p->get_parent();
- }
- }
-
- set_navigation(nav);
- }
-
set_physics_process_internal(true);
} break;
case NOTIFICATION_EXIT_TREE: {
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
+ case NOTIFICATION_PARENTED: {
+ parent_node3d = Object::cast_to<Node3D>(get_parent());
+ update_agent_shape();
+ } break;
+ case NOTIFICATION_UNPARENTED: {
+ parent_node3d = nullptr;
+ } break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- Node3D *spatial = Object::cast_to<Node3D>(get_parent());
- if (spatial) {
- NavigationServer3D::get_singleton()->agent_set_position(agent, spatial->get_global_transform().origin);
- }
-
- PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
- if (rigid) {
- Vector3 v = rigid->get_linear_velocity();
- NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
- NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
+ if (parent_node3d) {
+ NavigationServer3D::get_singleton()->agent_set_position(agent, parent_node3d->get_global_transform().origin);
+
+ PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
+ if (rigid) {
+ Vector3 v = rigid->get_linear_velocity();
+ NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
+ NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
+ }
}
-
} break;
}
}
@@ -93,30 +76,11 @@ NavigationObstacle3D::~NavigationObstacle3D() {
agent = RID(); // Pointless
}
-void NavigationObstacle3D::set_navigation(Navigation3D *p_nav) {
- if (navigation == p_nav) {
- return; // Pointless
- }
-
- navigation = p_nav;
- NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
-}
-
-void NavigationObstacle3D::set_navigation_node(Node *p_nav) {
- Navigation3D *nav = Object::cast_to<Navigation3D>(p_nav);
- ERR_FAIL_COND(nav == nullptr);
- set_navigation(nav);
-}
-
-Node *NavigationObstacle3D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
-}
-
String NavigationObstacle3D::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
- if (!Object::cast_to<Node3D>(get_parent())) {
- if (!warning.empty()) {
+ if (!parent_node3d) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The NavigationObstacle3D only serves to provide collision avoidance to a spatial object.");
@@ -126,40 +90,38 @@ String NavigationObstacle3D::get_configuration_warning() const {
}
void NavigationObstacle3D::update_agent_shape() {
- Node *node = get_parent();
-
- // Estimate the radius of this physics body
- real_t radius = 0.0;
- for (int i(0); i < node->get_child_count(); i++) {
- // For each collision shape
- CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(node->get_child(i));
- if (cs) {
- // Take the distance between the Body center to the shape center
- real_t r = cs->get_transform().origin.length();
- if (cs->get_shape().is_valid()) {
- // and add the enclosing shape radius
- r += cs->get_shape()->get_enclosing_radius();
+ if (parent_node3d) {
+ // Estimate the radius of this physics body
+ real_t radius = 0.0;
+ for (int i(0); i < parent_node3d->get_child_count(); i++) {
+ // For each collision shape
+ CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(parent_node3d->get_child(i));
+ if (cs) {
+ // Take the distance between the Body center to the shape center
+ real_t r = cs->get_transform().origin.length();
+ if (cs->get_shape().is_valid()) {
+ // and add the enclosing shape radius
+ r += cs->get_shape()->get_enclosing_radius();
+ }
+ Vector3 s = cs->get_global_transform().basis.get_scale();
+ r *= MAX(s.x, MAX(s.y, s.z));
+ // Takes the biggest radius
+ radius = MAX(radius, r);
}
- Vector3 s = cs->get_global_transform().basis.get_scale();
- r *= MAX(s.x, MAX(s.y, s.z));
- // Takes the biggest radius
- radius = MAX(radius, r);
}
- }
- Node3D *spa = Object::cast_to<Node3D>(node);
- if (spa) {
- Vector3 s = spa->get_global_transform().basis.get_scale();
+
+ Vector3 s = parent_node3d->get_global_transform().basis.get_scale();
radius *= MAX(s.x, MAX(s.y, s.z));
- }
- if (radius == 0.0) {
- radius = 1.0; // Never a 0 radius
- }
+ if (radius == 0.0) {
+ radius = 1.0; // Never a 0 radius
+ }
- // Initialize the Agent as an object
- NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
- NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0);
- NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0);
- NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
- NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ // Initialize the Agent as an object
+ NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
+ NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0);
+ NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0);
+ NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
+ NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ }
}
diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h
index f2dc9182ca..b1bb53724a 100644
--- a/scene/3d/navigation_obstacle_3d.h
+++ b/scene/3d/navigation_obstacle_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,15 +31,13 @@
#ifndef NAVIGATION_OBSTACLE_H
#define NAVIGATION_OBSTACLE_H
+#include "scene/3d/node_3d.h"
#include "scene/main/node.h"
-class Navigation3D;
-
class NavigationObstacle3D : public Node {
GDCLASS(NavigationObstacle3D, Node);
- Navigation3D *navigation = nullptr;
-
+ Node3D *parent_node3d = nullptr;
RID agent;
protected:
@@ -50,14 +48,6 @@ public:
NavigationObstacle3D();
virtual ~NavigationObstacle3D();
- void set_navigation(Navigation3D *p_nav);
- const Navigation3D *get_navigation() const {
- return navigation;
- }
-
- void set_navigation_node(Node *p_nav);
- Node *get_navigation_node() const;
-
RID get_rid() const {
return agent;
}
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index 2ae01c7ab8..3ca704e4b8 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,7 +32,6 @@
#include "core/os/thread.h"
#include "mesh_instance_3d.h"
-#include "navigation_3d.h"
#include "servers/navigation_server_3d.h"
void NavigationRegion3D::set_enabled(bool p_enabled) {
@@ -48,9 +47,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) {
if (!enabled) {
NavigationServer3D::get_singleton()->region_set_map(region, RID());
} else {
- if (navigation) {
- NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
+ NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
}
if (debug_view) {
@@ -69,22 +66,21 @@ bool NavigationRegion3D::is_enabled() const {
return enabled;
}
+void NavigationRegion3D::set_layers(uint32_t p_layers) {
+ NavigationServer3D::get_singleton()->region_set_layers(region, p_layers);
+}
+
+uint32_t NavigationRegion3D::get_layers() const {
+ return NavigationServer3D::get_singleton()->region_get_layers(region);
+}
+
/////////////////////////////
void NavigationRegion3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node3D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation3D>(c);
- if (navigation) {
- if (enabled) {
- NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
- break;
- }
-
- c = c->get_parent_spatial();
+ if (enabled) {
+ NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
}
if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
@@ -105,15 +101,12 @@ void NavigationRegion3D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
- if (navigation) {
- NavigationServer3D::get_singleton()->region_set_map(region, RID());
- }
+ NavigationServer3D::get_singleton()->region_set_map(region, RID());
if (debug_view) {
debug_view->queue_delete();
debug_view = nullptr;
}
- navigation = nullptr;
} break;
}
}
@@ -124,13 +117,13 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmes
}
if (navmesh.is_valid()) {
- navmesh->remove_change_receptor(this);
+ navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed));
}
navmesh = p_navmesh;
if (navmesh.is_valid()) {
- navmesh->add_change_receptor(this);
+ navmesh->connect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed));
}
NavigationServer3D::get_singleton()->region_set_navmesh(region, p_navmesh);
@@ -150,7 +143,7 @@ Ref<NavigationMesh> NavigationRegion3D::get_navigation_mesh() const {
}
struct BakeThreadsArgs {
- NavigationRegion3D *nav_region;
+ NavigationRegion3D *nav_region = nullptr;
};
void _bake_navigation_mesh(void *p_user_data) {
@@ -170,18 +163,17 @@ void _bake_navigation_mesh(void *p_user_data) {
}
void NavigationRegion3D::bake_navigation_mesh() {
- ERR_FAIL_COND(bake_thread != nullptr);
+ ERR_FAIL_COND(bake_thread.is_started());
BakeThreadsArgs *args = memnew(BakeThreadsArgs);
args->nav_region = this;
- bake_thread = Thread::create(_bake_navigation_mesh, args);
- ERR_FAIL_COND(bake_thread == nullptr);
+ bake_thread.start(_bake_navigation_mesh, args);
}
void NavigationRegion3D::_bake_finished(Ref<NavigationMesh> p_nav_mesh) {
set_navigation_mesh(p_nav_mesh);
- bake_thread = nullptr;
+ bake_thread.wait_to_finish();
emit_signal("bake_finished");
}
@@ -193,25 +185,13 @@ String NavigationRegion3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!navmesh.is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("A NavigationMesh resource must be set or created for this node to work.");
}
- const Node3D *c = this;
- while (c) {
- if (Object::cast_to<Navigation3D>(c)) {
- return warning;
- }
-
- c = Object::cast_to<Node3D>(c->get_parent());
- }
-
- if (!warning.empty()) {
- warning += "\n\n";
- }
- return warning + TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data.");
+ return warning;
}
void NavigationRegion3D::_bind_methods() {
@@ -221,17 +201,21 @@ void NavigationRegion3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion3D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion3D::is_enabled);
+ ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion3D::set_layers);
+ ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion3D::get_layers);
+
ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationRegion3D::bake_navigation_mesh);
ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion3D::_bake_finished);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_layers", "get_layers");
ADD_SIGNAL(MethodInfo("navigation_mesh_changed"));
ADD_SIGNAL(MethodInfo("bake_finished"));
}
-void NavigationRegion3D::_changed_callback(Object *p_changed, const char *p_prop) {
+void NavigationRegion3D::_navigation_changed() {
update_gizmo();
update_configuration_warning();
}
@@ -243,7 +227,7 @@ NavigationRegion3D::NavigationRegion3D() {
NavigationRegion3D::~NavigationRegion3D() {
if (navmesh.is_valid()) {
- navmesh->remove_change_receptor(this);
+ navmesh->disconnect("changed", callable_mp(this, &NavigationRegion3D::_navigation_changed));
}
NavigationServer3D::get_singleton()->free(region);
}
diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h
index 4b1d59206b..52fa2d6159 100644
--- a/scene/3d/navigation_region_3d.h
+++ b/scene/3d/navigation_region_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,8 +35,6 @@
#include "scene/resources/mesh.h"
#include "scene/resources/navigation_mesh.h"
-class Navigation3D;
-
class NavigationRegion3D : public Node3D {
GDCLASS(NavigationRegion3D, Node3D);
@@ -44,19 +42,22 @@ class NavigationRegion3D : public Node3D {
RID region;
Ref<NavigationMesh> navmesh;
- Navigation3D *navigation = nullptr;
Node *debug_view = nullptr;
- Thread *bake_thread = nullptr;
+ Thread bake_thread;
+
+ void _navigation_changed();
protected:
void _notification(int p_what);
static void _bind_methods();
- void _changed_callback(Object *p_changed, const char *p_prop) override;
public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
+ void set_layers(uint32_t p_layers);
+ uint32_t get_layers() const;
+
void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh);
Ref<NavigationMesh> get_navigation_mesh() const;
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index deb04f0978..4575716f7a 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -226,10 +226,6 @@ void Node3D::_notification(int p_what) {
void Node3D::set_transform(const Transform &p_transform) {
data.local_transform = p_transform;
data.dirty |= DIRTY_VECTORS;
- _change_notify("translation");
- _change_notify("rotation");
- _change_notify("rotation_degrees");
- _change_notify("scale");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -239,8 +235,8 @@ void Node3D::set_transform(const Transform &p_transform) {
void Node3D::set_global_transform(const Transform &p_transform) {
Transform xform =
(data.parent && !data.top_level_active) ?
- data.parent->get_global_transform().affine_inverse() * p_transform :
- p_transform;
+ data.parent->get_global_transform().affine_inverse() * p_transform :
+ p_transform;
set_transform(xform);
}
@@ -307,7 +303,6 @@ Transform Node3D::get_relative_transform(const Node *p_parent) const {
void Node3D::set_translation(const Vector3 &p_translation) {
data.local_transform.origin = p_translation;
- _change_notify("transform");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -322,7 +317,6 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) {
data.rotation = p_euler_rad;
data.dirty |= DIRTY_LOCAL;
- _change_notify("transform");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -330,7 +324,7 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) {
}
void Node3D::set_rotation_degrees(const Vector3 &p_euler_deg) {
- set_rotation(p_euler_deg * Math_PI / 180.0);
+ set_rotation(p_euler_deg * (Math_PI / 180.0));
}
void Node3D::set_scale(const Vector3 &p_scale) {
@@ -341,7 +335,6 @@ void Node3D::set_scale(const Vector3 &p_scale) {
data.scale = p_scale;
data.dirty |= DIRTY_LOCAL;
- _change_notify("transform");
_propagate_transform_changed(this);
if (data.notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
@@ -364,7 +357,7 @@ Vector3 Node3D::get_rotation() const {
}
Vector3 Node3D::get_rotation_degrees() const {
- return get_rotation() * 180.0 / Math_PI;
+ return get_rotation() * (180.0 / Math_PI);
}
Vector3 Node3D::get_scale() const {
@@ -495,7 +488,6 @@ Ref<World3D> Node3D::get_world_3d() const {
void Node3D::_propagate_visibility_changed() {
notification(NOTIFICATION_VISIBILITY_CHANGED);
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
- _change_notify("visible");
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
_update_gizmo();
@@ -755,8 +747,8 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("orthonormalize"), &Node3D::orthonormalize);
ClassDB::bind_method(D_METHOD("set_identity"), &Node3D::set_identity);
- ClassDB::bind_method(D_METHOD("look_at", "target", "up"), &Node3D::look_at);
- ClassDB::bind_method(D_METHOD("look_at_from_position", "position", "target", "up"), &Node3D::look_at_from_position);
+ ClassDB::bind_method(D_METHOD("look_at", "target", "up"), &Node3D::look_at, DEFVAL(Vector3(0, 1, 0)));
+ ClassDB::bind_method(D_METHOD("look_at_from_position", "position", "target", "up"), &Node3D::look_at_from_position, DEFVAL(Vector3(0, 1, 0)));
ClassDB::bind_method(D_METHOD("to_local", "global_point"), &Node3D::to_local);
ClassDB::bind_method(D_METHOD("to_global", "local_point"), &Node3D::to_global);
diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h
index 180c441a2a..a62c7b31a8 100644
--- a/scene/3d/node_3d.h
+++ b/scene/3d/node_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -173,8 +173,8 @@ public:
void global_scale(const Vector3 &p_scale);
void global_translate(const Vector3 &p_offset);
- void look_at(const Vector3 &p_target, const Vector3 &p_up);
- void look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up);
+ void look_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
+ void look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
Vector3 to_local(Vector3 p_global) const;
Vector3 to_global(Vector3 p_local) const;
diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp
index 54e6330722..7e2601902b 100644
--- a/scene/3d/path_3d.cpp
+++ b/scene/3d/path_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -249,14 +249,14 @@ String PathFollow3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!Object::cast_to<Path3D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("PathFollow3D only works when set as a child of a Path3D node.");
} else {
Path3D *path = Object::cast_to<Path3D>(get_parent());
if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("PathFollow3D's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path3D's Curve resource.");
@@ -323,8 +323,6 @@ void PathFollow3D::set_offset(float p_offset) {
_update_transform();
}
- _change_notify("offset");
- _change_notify("unit_offset");
}
void PathFollow3D::set_h_offset(float p_h_offset) {
diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h
index 39f04f1556..17ee47593e 100644
--- a/scene/3d/path_3d.h
+++ b/scene/3d/path_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -66,10 +66,10 @@ public:
private:
Path3D *path = nullptr;
- real_t delta_offset = 0; // Change in offset since last _update_transform.
- real_t offset = 0;
- real_t h_offset = 0;
- real_t v_offset = 0;
+ real_t delta_offset = 0.0; // Change in offset since last _update_transform.
+ real_t offset = 0.0;
+ real_t h_offset = 0.0;
+ real_t v_offset = 0.0;
bool cubic = true;
bool loop = true;
RotationMode rotation_mode = ROTATION_XYZ;
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index d9e19db4bd..6d135c8283 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,7 +51,7 @@ Vector3 PhysicsBody3D::get_angular_velocity() const {
return Vector3();
}
-float PhysicsBody3D::get_inverse_mass() const {
+real_t PhysicsBody3D::get_inverse_mass() const {
return 0;
}
@@ -148,7 +148,8 @@ void PhysicsBody3D::_bind_methods() {
}
PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) :
- CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(p_mode), false) {
+ CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) {
+ PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode);
collision_layer = 1;
collision_mask = 1;
}
@@ -311,7 +312,7 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
bool in_tree = E->get().in_tree;
- if (E->get().shapes.empty()) {
+ if (E->get().shapes.is_empty()) {
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree));
@@ -330,8 +331,8 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
struct _RigidBodyInOut {
ObjectID id;
- int shape;
- int local_shape;
+ int shape = 0;
+ int local_shape = 0;
};
void RigidBody3D::_direct_state_changed(Object *p_state) {
@@ -714,7 +715,7 @@ String RigidBody3D::get_configuration_warning() const {
String warning = CollisionObject3D::get_configuration_warning();
if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Size changes to RigidBody3D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");
@@ -825,24 +826,6 @@ void RigidBody3D::_bind_methods() {
RigidBody3D::RigidBody3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) {
- mode = MODE_RIGID;
-
- mass = 1;
- max_contacts_reported = 0;
- state = nullptr;
-
- gravity_scale = 1;
- linear_damp = -1;
- angular_damp = -1;
-
- //angular_velocity=0;
- sleeping = false;
- ccd = false;
-
- custom_integrator = false;
- contact_monitor = nullptr;
- can_sleep = true;
-
PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
}
@@ -924,7 +907,7 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
-Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) {
Vector3 body_velocity = p_linear_velocity;
Vector3 body_velocity_normal = body_velocity.normalized();
Vector3 up_direction = p_up_direction.normalized();
@@ -1018,7 +1001,7 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
return body_velocity;
}
-Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) {
Vector3 up_direction = p_up_direction.normalized();
bool was_on_floor = on_floor;
@@ -1090,7 +1073,7 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision
Vector3 recover;
int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin);
int deepest = -1;
- float deepest_depth;
+ real_t deepest_depth;
for (int i = 0; i < hits; i++) {
if (deepest == -1 || sep_res[i].collision_depth > deepest_depth) {
deepest = i;
@@ -1131,12 +1114,12 @@ bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const {
return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis);
}
-void KinematicBody3D::set_safe_margin(float p_margin) {
+void KinematicBody3D::set_safe_margin(real_t p_margin) {
margin = p_margin;
PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin);
}
-float KinematicBody3D::get_safe_margin() const {
+real_t KinematicBody3D::get_safe_margin() const {
return margin;
}
@@ -1180,8 +1163,8 @@ void KinematicBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody3D::_direct_state_changed);
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody3D::test_move, DEFVAL(true));
@@ -1221,11 +1204,6 @@ void KinematicBody3D::_direct_state_changed(Object *p_state) {
KinematicBody3D::KinematicBody3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) {
- locked_axis = 0;
- on_floor = false;
- on_ceiling = false;
- on_wall = false;
-
set_safe_margin(0.001);
PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
}
@@ -1716,6 +1694,10 @@ bool PhysicalBone3D::SixDOFJointData::_set(const StringName &p_name, const Varia
String path = p_name;
+ if (!path.begins_with("joint_constraints/")) {
+ return false;
+ }
+
Vector3::Axis axis;
{
const String axis_s = path.get_slicec('/', 1);
@@ -1872,6 +1854,10 @@ bool PhysicalBone3D::SixDOFJointData::_get(const StringName &p_name, Variant &r_
String path = p_name;
+ if (!path.begins_with("joint_constraints/")) {
+ return false;
+ }
+
int axis;
{
const String axis_s = path.get_slicec('/', 1);
@@ -2026,7 +2012,7 @@ void PhysicalBone3D::_notification(int p_what) {
update_bone_id();
reset_to_rest_position();
reset_physics_simulation_state();
- if (!joint.is_valid() && joint_data) {
+ if (joint_data) {
_reload_joint();
}
break;
@@ -2037,10 +2023,7 @@ void PhysicalBone3D::_notification(int p_what) {
}
}
parent_skeleton = nullptr;
- if (joint.is_valid()) {
- PhysicsServer3D::get_singleton()->free(joint);
- joint = RID();
- }
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
break;
case NOTIFICATION_TRANSFORM_CHANGED:
if (Engine::get_singleton()->is_editor_hint()) {
@@ -2190,17 +2173,14 @@ void PhysicalBone3D::_fix_joint_offset() {
}
void PhysicalBone3D::_reload_joint() {
- if (joint.is_valid()) {
- PhysicsServer3D::get_singleton()->free(joint);
- joint = RID();
- }
-
if (!parent_skeleton) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
return;
}
PhysicalBone3D *body_a = parent_skeleton->get_physical_bone_parent(bone_id);
if (!body_a) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
return;
}
@@ -2210,7 +2190,7 @@ void PhysicalBone3D::_reload_joint() {
switch (get_joint_type()) {
case JOINT_TYPE_PIN: {
- joint = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin);
+ PhysicsServer3D::get_singleton()->joint_make_pin(joint, body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin);
const PinJointData *pjd(static_cast<const PinJointData *>(joint_data));
PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_BIAS, pjd->bias);
PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_DAMPING, pjd->damping);
@@ -2218,7 +2198,7 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_CONE: {
- joint = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset);
+ PhysicsServer3D::get_singleton()->joint_make_cone_twist(joint, body_a->get_rid(), local_a, get_rid(), joint_offset);
const ConeJointData *cjd(static_cast<const ConeJointData *>(joint_data));
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, cjd->swing_span);
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN, cjd->twist_span);
@@ -2228,7 +2208,7 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_HINGE: {
- joint = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset);
+ PhysicsServer3D::get_singleton()->joint_make_hinge(joint, body_a->get_rid(), local_a, get_rid(), joint_offset);
const HingeJointData *hjd(static_cast<const HingeJointData *>(joint_data));
PhysicsServer3D::get_singleton()->hinge_joint_set_flag(joint, PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT, hjd->angular_limit_enabled);
PhysicsServer3D::get_singleton()->hinge_joint_set_param(joint, PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER, hjd->angular_limit_upper);
@@ -2239,7 +2219,7 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_SLIDER: {
- joint = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset);
+ PhysicsServer3D::get_singleton()->joint_make_slider(joint, body_a->get_rid(), local_a, get_rid(), joint_offset);
const SliderJointData *sjd(static_cast<const SliderJointData *>(joint_data));
PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER, sjd->linear_limit_upper);
PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER, sjd->linear_limit_lower);
@@ -2254,7 +2234,7 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_6DOF: {
- joint = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset);
+ PhysicsServer3D::get_singleton()->joint_make_generic_6dof(joint, body_a->get_rid(), local_a, get_rid(), joint_offset);
const SixDOFJointData *g6dofjd(static_cast<const SixDOFJointData *>(joint_data));
for (int axis = 0; axis < 3; ++axis) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, g6dofjd->axis_data[axis].linear_limit_enabled);
@@ -2347,7 +2327,7 @@ void PhysicalBone3D::set_joint_type(JointType p_joint_type) {
_reload_joint();
#ifdef TOOLS_ENABLED
- _change_notify();
+ notify_property_list_changed();
if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
}
@@ -2362,7 +2342,6 @@ void PhysicalBone3D::set_joint_offset(const Transform &p_offset) {
joint_offset = p_offset;
_update_joint_offset();
- _change_notify("joint_rotation_degrees");
}
const Transform &PhysicalBone3D::get_joint_offset() const {
@@ -2373,7 +2352,6 @@ void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) {
joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale());
_update_joint_offset();
- _change_notify("joint_offset");
}
Vector3 PhysicalBone3D::get_joint_rotation() const {
@@ -2381,11 +2359,11 @@ Vector3 PhysicalBone3D::get_joint_rotation() const {
}
void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) {
- set_joint_rotation(p_euler_deg * Math_PI / 180.0);
+ set_joint_rotation(p_euler_deg * (Math_PI / 180.0));
}
Vector3 PhysicalBone3D::get_joint_rotation_degrees() const {
- return get_joint_rotation() * 180.0 / Math_PI;
+ return get_joint_rotation() * (180.0 / Math_PI);
}
const Transform &PhysicalBone3D::get_body_offset() const {
@@ -2508,6 +2486,7 @@ bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const {
PhysicalBone3D::PhysicalBone3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) {
+ joint = PhysicsServer3D::get_singleton()->joint_create();
reset_physics_simulation_state();
}
@@ -2515,6 +2494,7 @@ PhysicalBone3D::~PhysicalBone3D() {
if (joint_data) {
memdelete(joint_data);
}
+ PhysicsServer3D::get_singleton()->free(joint);
}
void PhysicalBone3D::update_bone_id() {
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index cbf16863fb..1450fce6a6 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,7 +50,7 @@ protected:
public:
virtual Vector3 get_linear_velocity() const;
virtual Vector3 get_angular_velocity() const;
- virtual float get_inverse_mass() const;
+ virtual real_t get_inverse_mass() const;
void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
@@ -111,31 +111,31 @@ public:
};
protected:
- bool can_sleep;
- PhysicsDirectBodyState3D *state;
- Mode mode;
+ bool can_sleep = true;
+ PhysicsDirectBodyState3D *state = nullptr;
+ Mode mode = MODE_RIGID;
- real_t mass;
+ real_t mass = 1.0;
Ref<PhysicsMaterial> physics_material_override;
Vector3 linear_velocity;
Vector3 angular_velocity;
Basis inverse_inertia_tensor;
- real_t gravity_scale;
- real_t linear_damp;
- real_t angular_damp;
+ real_t gravity_scale = 1.0;
+ real_t linear_damp = -1.0;
+ real_t angular_damp = -1.0;
- bool sleeping;
- bool ccd;
+ bool sleeping = false;
+ bool ccd = false;
- int max_contacts_reported;
+ int max_contacts_reported = 0;
- bool custom_integrator;
+ bool custom_integrator = false;
struct ShapePair {
- int body_shape;
- int local_shape;
- bool tagged;
+ int body_shape = 0;
+ int local_shape = 0;
+ bool tagged = false;
bool operator<(const ShapePair &p_sp) const {
if (body_shape == p_sp.body_shape) {
return local_shape < p_sp.local_shape;
@@ -157,16 +157,16 @@ protected:
};
struct BodyState {
//int rc;
- bool in_tree;
+ bool in_tree = false;
VSet<ShapePair> shapes;
};
struct ContactMonitor {
- bool locked;
+ bool locked = false;
Map<ObjectID, BodyState> body_map;
};
- ContactMonitor *contact_monitor;
+ ContactMonitor *contact_monitor = nullptr;
void _body_enter_tree(ObjectID p_id);
void _body_exit_tree(ObjectID p_id);
@@ -183,7 +183,7 @@ public:
void set_mass(real_t p_mass);
real_t get_mass() const;
- virtual float get_inverse_mass() const override { return 1.0 / mass; }
+ virtual real_t get_inverse_mass() const override { return 1.0 / mass; }
void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override);
Ref<PhysicsMaterial> get_physics_material_override() const;
@@ -261,27 +261,27 @@ public:
Vector3 collider_vel;
ObjectID collider;
RID collider_rid;
- int collider_shape;
+ int collider_shape = 0;
Variant collider_metadata;
Vector3 remainder;
Vector3 travel;
- int local_shape;
+ int local_shape = 0;
};
private:
Vector3 linear_velocity;
Vector3 angular_velocity;
- uint16_t locked_axis;
+ uint16_t locked_axis = 0;
- float margin;
+ real_t margin;
Vector3 floor_normal;
Vector3 floor_velocity;
RID on_floor_body;
- bool on_floor;
- bool on_ceiling;
- bool on_wall;
+ bool on_floor = false;
+ bool on_ceiling = false;
+ bool on_wall = false;
Vector<Collision> colliders;
Vector<Ref<KinematicCollision3D>> slide_colliders;
Ref<KinematicCollision3D> motion_cache;
@@ -309,11 +309,11 @@ public:
void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
- void set_safe_margin(float p_margin);
- float get_safe_margin() const;
+ void set_safe_margin(real_t p_margin);
+ real_t get_safe_margin() const;
- Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
- Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true);
+ Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true);
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
@@ -385,10 +385,8 @@ public:
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
real_t bias = 0.3;
- real_t damping = 1.;
- real_t impulse_clamp = 0;
-
- PinJointData() {}
+ real_t damping = 1.0;
+ real_t impulse_clamp = 0.0;
};
struct ConeJointData : public JointData {
@@ -398,14 +396,11 @@ public:
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
- real_t swing_span;
+ real_t swing_span = Math_PI * 0.25;
real_t twist_span = Math_PI;
real_t bias = 0.3;
real_t softness = 0.8;
real_t relaxation = 1.;
-
- ConeJointData() :
- swing_span(Math_PI * 0.25) {}
};
struct HingeJointData : public JointData {
@@ -416,16 +411,11 @@ public:
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
bool angular_limit_enabled = false;
- real_t angular_limit_upper;
- real_t angular_limit_lower;
+ real_t angular_limit_upper = Math_PI * 0.5;
+ real_t angular_limit_lower = -Math_PI * 0.5;
real_t angular_limit_bias = 0.3;
real_t angular_limit_softness = 0.9;
real_t angular_limit_relaxation = 1.;
-
- HingeJointData() :
-
- angular_limit_upper(Math_PI * 0.5),
- angular_limit_lower(-Math_PI * 0.5) {}
};
struct SliderJointData : public JointData {
@@ -435,45 +425,41 @@ public:
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
- real_t linear_limit_upper = 1.;
- real_t linear_limit_lower = -1.;
- real_t linear_limit_softness = 1.;
+ real_t linear_limit_upper = 1.0;
+ real_t linear_limit_lower = -1.0;
+ real_t linear_limit_softness = 1.0;
real_t linear_limit_restitution = 0.7;
- real_t linear_limit_damping = 1.;
- real_t angular_limit_upper = 0;
- real_t angular_limit_lower = 0;
- real_t angular_limit_softness = 1.;
+ real_t linear_limit_damping = 1.0;
+ real_t angular_limit_upper = 0.0;
+ real_t angular_limit_lower = 0.0;
+ real_t angular_limit_softness = 1.0;
real_t angular_limit_restitution = 0.7;
- real_t angular_limit_damping = 1.;
-
- SliderJointData() {}
+ real_t angular_limit_damping = 1.0;
};
struct SixDOFJointData : public JointData {
struct SixDOFAxisData {
bool linear_limit_enabled = true;
- real_t linear_limit_upper = 0;
- real_t linear_limit_lower = 0;
+ real_t linear_limit_upper = 0.0;
+ real_t linear_limit_lower = 0.0;
real_t linear_limit_softness = 0.7;
real_t linear_restitution = 0.5;
- real_t linear_damping = 1.;
+ real_t linear_damping = 1.0;
bool linear_spring_enabled = false;
- real_t linear_spring_stiffness = 0;
- real_t linear_spring_damping = 0;
- real_t linear_equilibrium_point = 0;
+ real_t linear_spring_stiffness = 0.0;
+ real_t linear_spring_damping = 0.0;
+ real_t linear_equilibrium_point = 0.0;
bool angular_limit_enabled = true;
- real_t angular_limit_upper = 0;
- real_t angular_limit_lower = 0;
+ real_t angular_limit_upper = 0.0;
+ real_t angular_limit_lower = 0.0;
real_t angular_limit_softness = 0.5;
- real_t angular_restitution = 0;
- real_t angular_damping = 1.;
+ real_t angular_restitution = 0.0;
+ real_t angular_damping = 1.0;
real_t erp = 0.5;
bool angular_spring_enabled = false;
- real_t angular_spring_stiffness = 0;
- real_t angular_spring_damping = 0.;
- real_t angular_equilibrium_point = 0;
-
- SixDOFAxisData() {}
+ real_t angular_spring_stiffness = 0.0;
+ real_t angular_spring_damping = 0.0;
+ real_t angular_equilibrium_point = 0.0;
};
virtual JointType get_joint_type() { return JOINT_TYPE_6DOF; }
@@ -505,12 +491,12 @@ private:
int bone_id = -1;
String bone_name;
- real_t bounce = 0;
- real_t mass = 1;
- real_t friction = 1;
- real_t gravity_scale = 1;
- real_t linear_damp = -1;
- real_t angular_damp = -1;
+ real_t bounce = 0.0;
+ real_t mass = 1.0;
+ real_t friction = 1.0;
+ real_t gravity_scale = 1.0;
+ real_t linear_damp = -1.0;
+ real_t angular_damp = -1.0;
bool can_sleep = true;
protected:
diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp
index 06de5ad0ae..de9c75621b 100644
--- a/scene/3d/physics_joint_3d.cpp
+++ b/scene/3d/physics_joint_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,75 +30,106 @@
#include "physics_joint_3d.h"
-void Joint3D::_update_joint(bool p_only_free) {
- if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid()) {
- PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb);
- }
+#include "scene/scene_string_names.h"
- PhysicsServer3D::get_singleton()->free(joint);
- joint = RID();
- ba = RID();
- bb = RID();
+void Joint3D::_disconnect_signals() {
+ Node *node_a = get_node_or_null(a);
+ PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a);
+ if (body_a) {
+ body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
}
+ Node *node_b = get_node_or_null(b);
+ PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b);
+ if (body_b) {
+ body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
+ }
+}
+
+void Joint3D::_body_exit_tree() {
+ _disconnect_signals();
+ _update_joint(true);
+}
+
+void Joint3D::_update_joint(bool p_only_free) {
+ if (ba.is_valid() && bb.is_valid()) {
+ PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb);
+ PhysicsServer3D::get_singleton()->body_remove_collision_exception(bb, ba);
+ }
+
+ ba = RID();
+ bb = RID();
+
+ configured = false;
+
if (p_only_free || !is_inside_tree()) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
warning = String();
return;
}
- Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)nullptr;
- Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)nullptr;
+ Node *node_a = get_node_or_null(a);
+ Node *node_b = get_node_or_null(b);
PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a);
PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b);
if (node_a && !body_a && node_b && !body_b) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
warning = TTR("Node A and Node B must be PhysicsBody3Ds");
update_configuration_warning();
return;
}
if (node_a && !body_a) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
warning = TTR("Node A must be a PhysicsBody3D");
update_configuration_warning();
return;
}
if (node_b && !body_b) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
warning = TTR("Node B must be a PhysicsBody3D");
update_configuration_warning();
return;
}
if (!body_a && !body_b) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
warning = TTR("Joint is not connected to any PhysicsBody3Ds");
update_configuration_warning();
return;
}
if (body_a == body_b) {
+ PhysicsServer3D::get_singleton()->joint_clear(joint);
warning = TTR("Node A and Node B must be different PhysicsBody3Ds");
update_configuration_warning();
return;
}
- if (!body_a) {
- SWAP(body_a, body_b);
- }
-
warning = String();
update_configuration_warning();
- joint = _configure_joint(body_a, body_b);
+ configured = true;
- ERR_FAIL_COND_MSG(!joint.is_valid(), "Failed to configure the joint.");
+ if (body_a) {
+ _configure_joint(joint, body_a, body_b);
+ } else if (body_b) {
+ _configure_joint(joint, body_b, nullptr);
+ }
PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority);
- ba = body_a->get_rid();
+ if (body_a) {
+ ba = body_a->get_rid();
+ body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
+ }
+
if (body_b) {
bb = body_b->get_rid();
+ body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree));
}
PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
@@ -109,6 +140,10 @@ void Joint3D::set_node_a(const NodePath &p_node_a) {
return;
}
+ if (joint.is_valid()) {
+ _disconnect_signals();
+ }
+
a = p_node_a;
_update_joint();
}
@@ -121,6 +156,11 @@ void Joint3D::set_node_b(const NodePath &p_node_b) {
if (b == p_node_b) {
return;
}
+
+ if (joint.is_valid()) {
+ _disconnect_signals();
+ }
+
b = p_node_b;
_update_joint();
}
@@ -147,6 +187,7 @@ void Joint3D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
if (joint.is_valid()) {
+ _disconnect_signals();
_update_joint(true);
}
} break;
@@ -168,8 +209,8 @@ bool Joint3D::get_exclude_nodes_from_collision() const {
String Joint3D::get_configuration_warning() const {
String node_warning = Node3D::get_configuration_warning();
- if (!warning.empty()) {
- if (!node_warning.empty()) {
+ if (!warning.is_empty()) {
+ if (!node_warning.is_empty()) {
node_warning += "\n\n";
}
node_warning += warning;
@@ -199,9 +240,12 @@ void Joint3D::_bind_methods() {
}
Joint3D::Joint3D() {
- exclude_from_collision = true;
- solver_priority = 1;
set_notify_transform(true);
+ joint = PhysicsServer3D::get_singleton()->joint_create();
+}
+
+Joint3D::~Joint3D() {
+ PhysicsServer3D::get_singleton()->free(joint);
}
///////////////////////////////////
@@ -219,20 +263,20 @@ void PinJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_IMPULSE_CLAMP);
}
-void PinJoint3D::set_param(Param p_param, float p_value) {
+void PinJoint3D::set_param(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, 3);
params[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer3D::PinJointParam(p_param), p_value);
}
}
-float PinJoint3D::get_param(Param p_param) const {
+real_t PinJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, 3, 0);
return params[p_param];
}
-RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void PinJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Vector3 pinpos = get_global_transform().origin;
Vector3 local_a = body_a->get_global_transform().affine_inverse().xform(pinpos);
Vector3 local_b;
@@ -243,11 +287,10 @@ RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
local_b = pinpos;
}
- RID j = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_pin(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < 3; i++) {
- PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PinJointParam(i), params[i]);
+ PhysicsServer3D::get_singleton()->pin_joint_set_param(p_joint, PhysicsServer3D::PinJointParam(i), params[i]);
}
- return j;
}
PinJoint3D::PinJoint3D() {
@@ -260,19 +303,19 @@ PinJoint3D::PinJoint3D() {
///////////////////////////////////
-void HingeJoint3D::_set_upper_limit(float p_limit) {
+void HingeJoint3D::_set_upper_limit(real_t p_limit) {
set_param(PARAM_LIMIT_UPPER, Math::deg2rad(p_limit));
}
-float HingeJoint3D::_get_upper_limit() const {
+real_t HingeJoint3D::_get_upper_limit() const {
return Math::rad2deg(get_param(PARAM_LIMIT_UPPER));
}
-void HingeJoint3D::_set_lower_limit(float p_limit) {
+void HingeJoint3D::_set_lower_limit(real_t p_limit) {
set_param(PARAM_LIMIT_LOWER, Math::deg2rad(p_limit));
}
-float HingeJoint3D::_get_lower_limit() const {
+real_t HingeJoint3D::_get_lower_limit() const {
return Math::rad2deg(get_param(PARAM_LIMIT_LOWER));
}
@@ -317,17 +360,17 @@ void HingeJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_MAX);
}
-void HingeJoint3D::set_param(Param p_param, float p_value) {
+void HingeJoint3D::set_param(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(get_joint(), PhysicsServer3D::HingeJointParam(p_param), p_value);
}
update_gizmo();
}
-float HingeJoint3D::get_param(Param p_param) const {
+real_t HingeJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
@@ -335,7 +378,7 @@ float HingeJoint3D::get_param(Param p_param) const {
void HingeJoint3D::set_flag(Flag p_flag, bool p_value) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags[p_flag] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_flag(get_joint(), PhysicsServer3D::HingeJointFlag(p_flag), p_value);
}
@@ -347,7 +390,7 @@ bool HingeJoint3D::get_flag(Flag p_flag) const {
return flags[p_flag];
}
-RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void HingeJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Transform gt = get_global_transform();
Transform ainv = body_a->get_global_transform().affine_inverse();
@@ -362,15 +405,14 @@ RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b)
local_b.orthonormalize();
- RID j = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_hinge(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < PARAM_MAX; i++) {
- PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HingeJointParam(i), params[i]);
+ PhysicsServer3D::get_singleton()->hinge_joint_set_param(p_joint, PhysicsServer3D::HingeJointParam(i), params[i]);
}
for (int i = 0; i < FLAG_MAX; i++) {
set_flag(Flag(i), flags[i]);
- PhysicsServer3D::get_singleton()->hinge_joint_set_flag(j, PhysicsServer3D::HingeJointFlag(i), flags[i]);
+ PhysicsServer3D::get_singleton()->hinge_joint_set_flag(p_joint, PhysicsServer3D::HingeJointFlag(i), flags[i]);
}
- return j;
}
HingeJoint3D::HingeJoint3D() {
@@ -391,19 +433,19 @@ HingeJoint3D::HingeJoint3D() {
//////////////////////////////////
-void SliderJoint3D::_set_upper_limit_angular(float p_limit_angular) {
+void SliderJoint3D::_set_upper_limit_angular(real_t p_limit_angular) {
set_param(PARAM_ANGULAR_LIMIT_UPPER, Math::deg2rad(p_limit_angular));
}
-float SliderJoint3D::_get_upper_limit_angular() const {
+real_t SliderJoint3D::_get_upper_limit_angular() const {
return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_UPPER));
}
-void SliderJoint3D::_set_lower_limit_angular(float p_limit_angular) {
+void SliderJoint3D::_set_lower_limit_angular(real_t p_limit_angular) {
set_param(PARAM_ANGULAR_LIMIT_LOWER, Math::deg2rad(p_limit_angular));
}
-float SliderJoint3D::_get_lower_limit_angular() const {
+real_t SliderJoint3D::_get_lower_limit_angular() const {
return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_LOWER));
}
@@ -468,21 +510,21 @@ void SliderJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_MAX);
}
-void SliderJoint3D::set_param(Param p_param, float p_value) {
+void SliderJoint3D::set_param(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(get_joint(), PhysicsServer3D::SliderJointParam(p_param), p_value);
}
update_gizmo();
}
-float SliderJoint3D::get_param(Param p_param) const {
+real_t SliderJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
-RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void SliderJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Transform gt = get_global_transform();
Transform ainv = body_a->get_global_transform().affine_inverse();
@@ -497,12 +539,10 @@ RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b
local_b.orthonormalize();
- RID j = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_slider(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < PARAM_MAX; i++) {
- PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SliderJointParam(i), params[i]);
+ PhysicsServer3D::get_singleton()->slider_joint_set_param(p_joint, PhysicsServer3D::SliderJointParam(i), params[i]);
}
-
- return j;
}
SliderJoint3D::SliderJoint3D() {
@@ -533,19 +573,19 @@ SliderJoint3D::SliderJoint3D() {
//////////////////////////////////
-void ConeTwistJoint3D::_set_swing_span(float p_limit_angular) {
+void ConeTwistJoint3D::_set_swing_span(real_t p_limit_angular) {
set_param(PARAM_SWING_SPAN, Math::deg2rad(p_limit_angular));
}
-float ConeTwistJoint3D::_get_swing_span() const {
+real_t ConeTwistJoint3D::_get_swing_span() const {
return Math::rad2deg(get_param(PARAM_SWING_SPAN));
}
-void ConeTwistJoint3D::_set_twist_span(float p_limit_angular) {
+void ConeTwistJoint3D::_set_twist_span(real_t p_limit_angular) {
set_param(PARAM_TWIST_SPAN, Math::deg2rad(p_limit_angular));
}
-float ConeTwistJoint3D::_get_twist_span() const {
+real_t ConeTwistJoint3D::_get_twist_span() const {
return Math::rad2deg(get_param(PARAM_TWIST_SPAN));
}
@@ -574,22 +614,22 @@ void ConeTwistJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_MAX);
}
-void ConeTwistJoint3D::set_param(Param p_param, float p_value) {
+void ConeTwistJoint3D::set_param(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(get_joint(), PhysicsServer3D::ConeTwistJointParam(p_param), p_value);
}
update_gizmo();
}
-float ConeTwistJoint3D::get_param(Param p_param) const {
+real_t ConeTwistJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
-RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void ConeTwistJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Transform gt = get_global_transform();
//Vector3 cone_twistpos = gt.origin;
//Vector3 cone_twistdir = gt.basis.get_axis(2);
@@ -607,12 +647,10 @@ RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *bod
local_b.orthonormalize();
- RID j = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_cone_twist(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < PARAM_MAX; i++) {
- PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::ConeTwistJointParam(i), params[i]);
+ PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(p_joint, PhysicsServer3D::ConeTwistJointParam(i), params[i]);
}
-
- return j;
}
ConeTwistJoint3D::ConeTwistJoint3D() {
@@ -625,51 +663,51 @@ ConeTwistJoint3D::ConeTwistJoint3D() {
/////////////////////////////////////////////////////////////////////
-void Generic6DOFJoint3D::_set_angular_hi_limit_x(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_hi_limit_x(real_t p_limit_angular) {
set_param_x(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_hi_limit_x() const {
+real_t Generic6DOFJoint3D::_get_angular_hi_limit_x() const {
return Math::rad2deg(get_param_x(PARAM_ANGULAR_UPPER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_lo_limit_x(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_lo_limit_x(real_t p_limit_angular) {
set_param_x(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_lo_limit_x() const {
+real_t Generic6DOFJoint3D::_get_angular_lo_limit_x() const {
return Math::rad2deg(get_param_x(PARAM_ANGULAR_LOWER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_hi_limit_y(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_hi_limit_y(real_t p_limit_angular) {
set_param_y(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_hi_limit_y() const {
+real_t Generic6DOFJoint3D::_get_angular_hi_limit_y() const {
return Math::rad2deg(get_param_y(PARAM_ANGULAR_UPPER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_lo_limit_y(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_lo_limit_y(real_t p_limit_angular) {
set_param_y(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_lo_limit_y() const {
+real_t Generic6DOFJoint3D::_get_angular_lo_limit_y() const {
return Math::rad2deg(get_param_y(PARAM_ANGULAR_LOWER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_hi_limit_z(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_hi_limit_z(real_t p_limit_angular) {
set_param_z(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_hi_limit_z() const {
+real_t Generic6DOFJoint3D::_get_angular_hi_limit_z() const {
return Math::rad2deg(get_param_z(PARAM_ANGULAR_UPPER_LIMIT));
}
-void Generic6DOFJoint3D::_set_angular_lo_limit_z(float p_limit_angular) {
+void Generic6DOFJoint3D::_set_angular_lo_limit_z(real_t p_limit_angular) {
set_param_z(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
-float Generic6DOFJoint3D::_get_angular_lo_limit_z() const {
+real_t Generic6DOFJoint3D::_get_angular_lo_limit_z() const {
return Math::rad2deg(get_param_z(PARAM_ANGULAR_LOWER_LIMIT));
}
@@ -831,45 +869,45 @@ void Generic6DOFJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_MAX);
}
-void Generic6DOFJoint3D::set_param_x(Param p_param, float p_value) {
+void Generic6DOFJoint3D::set_param_x(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_x[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_x(Param p_param) const {
+real_t Generic6DOFJoint3D::get_param_x(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_x[p_param];
}
-void Generic6DOFJoint3D::set_param_y(Param p_param, float p_value) {
+void Generic6DOFJoint3D::set_param_y(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_y[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_y(Param p_param) const {
+real_t Generic6DOFJoint3D::get_param_y(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_y[p_param];
}
-void Generic6DOFJoint3D::set_param_z(Param p_param, float p_value) {
+void Generic6DOFJoint3D::set_param_z(Param p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_z[p_param] = p_value;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_z(Param p_param) const {
+real_t Generic6DOFJoint3D::get_param_z(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_z[p_param];
}
@@ -877,7 +915,7 @@ float Generic6DOFJoint3D::get_param_z(Param p_param) const {
void Generic6DOFJoint3D::set_flag_x(Flag p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_x[p_flag] = p_enabled;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
@@ -891,7 +929,7 @@ bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const {
void Generic6DOFJoint3D::set_flag_y(Flag p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_y[p_flag] = p_enabled;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
@@ -905,7 +943,7 @@ bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const {
void Generic6DOFJoint3D::set_flag_z(Flag p_flag, bool p_enabled) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_z[p_flag] = p_enabled;
- if (get_joint().is_valid()) {
+ if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
@@ -916,7 +954,7 @@ bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const {
return flags_z[p_flag];
}
-RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
+void Generic6DOFJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
Transform gt = get_global_transform();
//Vector3 cone_twistpos = gt.origin;
//Vector3 cone_twistdir = gt.basis.get_axis(2);
@@ -934,19 +972,17 @@ RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *b
local_b.orthonormalize();
- RID j = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+ PhysicsServer3D::get_singleton()->joint_make_generic_6dof(p_joint, body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < PARAM_MAX; i++) {
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]);
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]);
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(i), params_x[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(i), params_y[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(i), params_z[i]);
}
for (int i = 0; i < FLAG_MAX; i++) {
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]);
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]);
- PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_x[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_y[i]);
+ PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(p_joint, Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(i), flags_z[i]);
}
-
- return j;
}
Generic6DOFJoint3D::Generic6DOFJoint3D() {
diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/physics_joint_3d.h
index 250ae8bf52..f624ba602b 100644
--- a/scene/3d/physics_joint_3d.h
+++ b/scene/3d/physics_joint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,19 +44,24 @@ class Joint3D : public Node3D {
NodePath a;
NodePath b;
- int solver_priority;
- bool exclude_from_collision;
+ int solver_priority = 1;
+ bool exclude_from_collision = true;
String warning;
+ bool configured = false;
protected:
+ void _disconnect_signals();
+ void _body_exit_tree();
void _update_joint(bool p_only_free = false);
void _notification(int p_what);
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0;
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) = 0;
static void _bind_methods();
+ _FORCE_INLINE_ bool is_configured() const { return configured; }
+
public:
virtual String get_configuration_warning() const override;
@@ -74,6 +79,7 @@ public:
RID get_joint() const { return joint; }
Joint3D();
+ ~Joint3D();
};
///////////////////////////////////////////
@@ -89,13 +95,13 @@ public:
};
protected:
- float params[3];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
+ real_t params[3];
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
public:
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
+ void set_param(Param p_param, real_t p_value);
+ real_t get_param(Param p_param) const;
PinJoint3D();
};
@@ -125,20 +131,20 @@ public:
};
protected:
- float params[PARAM_MAX];
+ real_t params[PARAM_MAX];
bool flags[FLAG_MAX];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
- void _set_upper_limit(float p_limit);
- float _get_upper_limit() const;
+ void _set_upper_limit(real_t p_limit);
+ real_t _get_upper_limit() const;
- void _set_lower_limit(float p_limit);
- float _get_lower_limit() const;
+ void _set_lower_limit(real_t p_limit);
+ real_t _get_lower_limit() const;
public:
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
+ void set_param(Param p_param, real_t p_value);
+ real_t get_param(Param p_param) const;
void set_flag(Flag p_flag, bool p_value);
bool get_flag(Flag p_flag) const;
@@ -182,19 +188,19 @@ public:
};
protected:
- void _set_upper_limit_angular(float p_limit_angular);
- float _get_upper_limit_angular() const;
+ void _set_upper_limit_angular(real_t p_limit_angular);
+ real_t _get_upper_limit_angular() const;
- void _set_lower_limit_angular(float p_limit_angular);
- float _get_lower_limit_angular() const;
+ void _set_lower_limit_angular(real_t p_limit_angular);
+ real_t _get_lower_limit_angular() const;
- float params[PARAM_MAX];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
+ real_t params[PARAM_MAX];
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
public:
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
+ void set_param(Param p_param, real_t p_value);
+ real_t get_param(Param p_param) const;
SliderJoint3D();
};
@@ -215,19 +221,19 @@ public:
};
protected:
- void _set_swing_span(float p_limit_angular);
- float _get_swing_span() const;
+ void _set_swing_span(real_t p_limit_angular);
+ real_t _get_swing_span() const;
- void _set_twist_span(float p_limit_angular);
- float _get_twist_span() const;
+ void _set_twist_span(real_t p_limit_angular);
+ real_t _get_twist_span() const;
- float params[PARAM_MAX];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
+ real_t params[PARAM_MAX];
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
public:
- void set_param(Param p_param, float p_value);
- float get_param(Param p_param) const;
+ void set_param(Param p_param, real_t p_value);
+ real_t get_param(Param p_param) const;
ConeTwistJoint3D();
};
@@ -275,43 +281,43 @@ public:
};
protected:
- void _set_angular_hi_limit_x(float p_limit_angular);
- float _get_angular_hi_limit_x() const;
+ void _set_angular_hi_limit_x(real_t p_limit_angular);
+ real_t _get_angular_hi_limit_x() const;
- void _set_angular_hi_limit_y(float p_limit_angular);
- float _get_angular_hi_limit_y() const;
+ void _set_angular_hi_limit_y(real_t p_limit_angular);
+ real_t _get_angular_hi_limit_y() const;
- void _set_angular_hi_limit_z(float p_limit_angular);
- float _get_angular_hi_limit_z() const;
+ void _set_angular_hi_limit_z(real_t p_limit_angular);
+ real_t _get_angular_hi_limit_z() const;
- void _set_angular_lo_limit_x(float p_limit_angular);
- float _get_angular_lo_limit_x() const;
+ void _set_angular_lo_limit_x(real_t p_limit_angular);
+ real_t _get_angular_lo_limit_x() const;
- void _set_angular_lo_limit_y(float p_limit_angular);
- float _get_angular_lo_limit_y() const;
+ void _set_angular_lo_limit_y(real_t p_limit_angular);
+ real_t _get_angular_lo_limit_y() const;
- void _set_angular_lo_limit_z(float p_limit_angular);
- float _get_angular_lo_limit_z() const;
+ void _set_angular_lo_limit_z(real_t p_limit_angular);
+ real_t _get_angular_lo_limit_z() const;
- float params_x[PARAM_MAX];
+ real_t params_x[PARAM_MAX];
bool flags_x[FLAG_MAX];
- float params_y[PARAM_MAX];
+ real_t params_y[PARAM_MAX];
bool flags_y[FLAG_MAX];
- float params_z[PARAM_MAX];
+ real_t params_z[PARAM_MAX];
bool flags_z[FLAG_MAX];
- virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
+ virtual void _configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) override;
static void _bind_methods();
public:
- void set_param_x(Param p_param, float p_value);
- float get_param_x(Param p_param) const;
+ void set_param_x(Param p_param, real_t p_value);
+ real_t get_param_x(Param p_param) const;
- void set_param_y(Param p_param, float p_value);
- float get_param_y(Param p_param) const;
+ void set_param_y(Param p_param, real_t p_value);
+ real_t get_param_y(Param p_param) const;
- void set_param_z(Param p_param, float p_value);
- float get_param_z(Param p_param) const;
+ void set_param_z(Param p_param, real_t p_value);
+ real_t get_param_z(Param p_param) const;
void set_flag_x(Flag p_flag, bool p_enabled);
bool get_flag_x(Flag p_flag) const;
diff --git a/scene/3d/position_3d.cpp b/scene/3d/position_3d.cpp
index e63c588e28..b231ba0df7 100644
--- a/scene/3d/position_3d.cpp
+++ b/scene/3d/position_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/position_3d.h b/scene/3d/position_3d.h
index 1c5f05ef95..065b14c3bd 100644
--- a/scene/3d/position_3d.h
+++ b/scene/3d/position_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/proximity_group_3d.cpp b/scene/3d/proximity_group_3d.cpp
index 7e25255885..9d9fea68b0 100644
--- a/scene/3d/proximity_group_3d.cpp
+++ b/scene/3d/proximity_group_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/proximity_group_3d.h b/scene/3d/proximity_group_3d.h
index d52843e9a2..05aa00b228 100644
--- a/scene/3d/proximity_group_3d.h
+++ b/scene/3d/proximity_group_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp
index 811e8a331b..465de2cb47 100644
--- a/scene/3d/ray_cast_3d.cpp
+++ b/scene/3d/ray_cast_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,10 +37,13 @@
void RayCast3D::set_target_position(const Vector3 &p_point) {
target_position = p_point;
- if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
- update_gizmo();
- }
- if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
+ update_gizmo();
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+ if (is_inside_tree()) {
+ _update_debug_shape_vertices();
+ }
+ } else if (debug_shape) {
_update_debug_shape();
}
}
@@ -146,16 +149,19 @@ bool RayCast3D::get_exclude_parent_body() const {
void RayCast3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ _update_debug_shape_vertices();
+ }
if (enabled && !Engine::get_singleton()->is_editor_hint()) {
set_physics_process_internal(true);
-
- if (get_tree()->is_debugging_collisions_hint()) {
- _update_debug_shape();
- }
} else {
set_physics_process_internal(false);
}
+ if (get_tree()->is_debugging_collisions_hint()) {
+ _update_debug_shape();
+ }
+
if (Object::cast_to<CollisionObject3D>(get_parent())) {
if (exclude_parent_body) {
exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
@@ -183,10 +189,7 @@ void RayCast3D::_notification(int p_what) {
bool prev_collision_state = collided;
_update_raycast_state();
if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) {
- if (debug_material.is_valid()) {
- Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D>>(debug_material);
- line_material->set_albedo(collided ? Color(1.0, 0, 0) : Color(1.0, 0.8, 0.6));
- }
+ _update_debug_shape_material(true);
}
} break;
@@ -310,6 +313,12 @@ void RayCast3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast3D::set_collide_with_bodies);
ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast3D::is_collide_with_bodies_enabled);
+ ClassDB::bind_method(D_METHOD("set_debug_shape_custom_color", "debug_shape_custom_color"), &RayCast3D::set_debug_shape_custom_color);
+ ClassDB::bind_method(D_METHOD("get_debug_shape_custom_color"), &RayCast3D::get_debug_shape_custom_color);
+
+ ClassDB::bind_method(D_METHOD("set_debug_shape_thickness", "debug_shape_thickness"), &RayCast3D::set_debug_shape_thickness);
+ ClassDB::bind_method(D_METHOD("get_debug_shape_thickness"), &RayCast3D::get_debug_shape_thickness);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position");
@@ -318,16 +327,80 @@ void RayCast3D::_bind_methods() {
ADD_GROUP("Collide With", "collide_with");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
+
+ ADD_GROUP("Debug Shape", "debug_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_shape_custom_color"), "set_debug_shape_custom_color", "get_debug_shape_custom_color");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_shape_thickness", PROPERTY_HINT_RANGE, "1,5"), "set_debug_shape_thickness", "get_debug_shape_thickness");
}
-void RayCast3D::_create_debug_shape() {
- if (!debug_material.is_valid()) {
- debug_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+float RayCast3D::get_debug_shape_thickness() const {
+ return debug_shape_thickness;
+}
+
+void RayCast3D::_update_debug_shape_vertices() {
+ debug_shape_vertices.clear();
+ debug_line_vertices.clear();
+
+ if (target_position == Vector3()) {
+ return;
+ }
+
+ debug_line_vertices.push_back(Vector3());
+ debug_line_vertices.push_back(target_position);
+
+ if (debug_shape_thickness > 1) {
+ float scale_factor = 100.0;
+ Vector3 dir = Vector3(target_position).normalized();
+ // Draw truncated pyramid
+ Vector3 normal = (fabs(dir.x) + fabs(dir.y) > CMP_EPSILON) ? Vector3(-dir.y, dir.x, 0).normalized() : Vector3(0, -dir.z, dir.y).normalized();
+ normal *= debug_shape_thickness / scale_factor;
+ int vertices_strip_order[14] = { 4, 5, 0, 1, 2, 5, 6, 4, 7, 0, 3, 2, 7, 6 };
+ for (int v = 0; v < 14; v++) {
+ Vector3 vertex = vertices_strip_order[v] < 4 ? normal : normal / 3.0 + target_position;
+ debug_shape_vertices.push_back(vertex.rotated(dir, Math_PI * (0.5 * (vertices_strip_order[v] % 4) + 0.25)));
+ }
+ }
+}
+
+void RayCast3D::set_debug_shape_thickness(const float p_debug_shape_thickness) {
+ debug_shape_thickness = p_debug_shape_thickness;
+ update_gizmo();
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+ if (is_inside_tree()) {
+ _update_debug_shape_vertices();
+ }
+ } else if (debug_shape) {
+ _update_debug_shape();
+ }
+}
+
+const Vector<Vector3> &RayCast3D::get_debug_shape_vertices() const {
+ return debug_shape_vertices;
+}
+
+const Vector<Vector3> &RayCast3D::get_debug_line_vertices() const {
+ return debug_line_vertices;
+}
- Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D>>(debug_material);
- line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
- line_material->set_albedo(Color(1.0, 0.8, 0.6));
+void RayCast3D::set_debug_shape_custom_color(const Color &p_color) {
+ debug_shape_custom_color = p_color;
+ if (debug_material.is_valid()) {
+ _update_debug_shape_material();
}
+}
+
+Ref<StandardMaterial3D> RayCast3D::get_debug_material() {
+ _update_debug_shape_material();
+ return debug_material;
+}
+
+const Color &RayCast3D::get_debug_shape_custom_color() const {
+ return debug_shape_custom_color;
+}
+
+void RayCast3D::_create_debug_shape() {
+ _update_debug_shape_material();
Ref<ArrayMesh> mesh = memnew(ArrayMesh);
@@ -338,6 +411,35 @@ void RayCast3D::_create_debug_shape() {
debug_shape = mi;
}
+void RayCast3D::_update_debug_shape_material(bool p_check_collision) {
+ if (!debug_material.is_valid()) {
+ Ref<StandardMaterial3D> material = memnew(StandardMaterial3D);
+ debug_material = material;
+
+ material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA);
+ }
+
+ Color color = debug_shape_custom_color;
+ if (color == Color(0.0, 0.0, 0.0)) {
+ // Use the default debug shape color defined in the Project Settings.
+ color = get_tree()->get_debug_collisions_color();
+ }
+
+ if (p_check_collision) {
+ if ((color.get_h() < 0.055 || color.get_h() > 0.945) && color.get_s() > 0.5 && color.get_v() > 0.5) {
+ // If base color is already quite reddish, hightlight collision with green color
+ color = Color(0.0, 1.0, 0.0, color.a);
+ } else {
+ // Else, hightlight collision with red color
+ color = Color(1.0, 0, 0, color.a);
+ }
+ }
+
+ Ref<StandardMaterial3D> material = static_cast<Ref<StandardMaterial3D>>(debug_material);
+ material->set_albedo(color);
+}
+
void RayCast3D::_update_debug_shape() {
if (!enabled) {
return;
@@ -348,23 +450,34 @@ void RayCast3D::_update_debug_shape() {
}
MeshInstance3D *mi = static_cast<MeshInstance3D *>(debug_shape);
- if (!mi->get_mesh().is_valid()) {
+ Ref<ArrayMesh> mesh = mi->get_mesh();
+ if (!mesh.is_valid()) {
return;
}
- Ref<ArrayMesh> mesh = mi->get_mesh();
+ _update_debug_shape_vertices();
+
mesh->clear_surfaces();
Array a;
a.resize(Mesh::ARRAY_MAX);
- Vector<Vector3> verts;
- verts.push_back(Vector3());
- verts.push_back(target_position);
- a[Mesh::ARRAY_VERTEX] = verts;
+ uint32_t flags = 0;
+ int surface_count = 0;
- mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
- mesh->surface_set_material(0, debug_material);
+ if (!debug_line_vertices.is_empty()) {
+ a[Mesh::ARRAY_VERTEX] = debug_line_vertices;
+ mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags);
+ mesh->surface_set_material(surface_count, debug_material);
+ ++surface_count;
+ }
+
+ if (!debug_shape_vertices.is_empty()) {
+ a[Mesh::ARRAY_VERTEX] = debug_shape_vertices;
+ mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLE_STRIP, a, Array(), Dictionary(), flags);
+ mesh->surface_set_material(surface_count, debug_material);
+ ++surface_count;
+ }
}
void RayCast3D::_clear_debug_shape() {
@@ -383,13 +496,4 @@ void RayCast3D::_clear_debug_shape() {
}
RayCast3D::RayCast3D() {
- enabled = true;
- collided = false;
- against_shape = 0;
- collision_mask = 1;
- target_position = Vector3(0, -1, 0);
- debug_shape = nullptr;
- exclude_parent_body = true;
- collide_with_areas = false;
- collide_with_bodies = true;
}
diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h
index f4fe7ba621..968cede9f2 100644
--- a/scene/3d/ray_cast_3d.h
+++ b/scene/3d/ray_cast_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,28 +36,34 @@
class RayCast3D : public Node3D {
GDCLASS(RayCast3D, Node3D);
- bool enabled;
- bool collided;
+ bool enabled = true;
+ bool collided = false;
ObjectID against;
- int against_shape;
+ int against_shape = 0;
Vector3 collision_point;
Vector3 collision_normal;
- Vector3 target_position;
+ Vector3 target_position = Vector3(0, -1, 0);
Set<RID> exclude;
- uint32_t collision_mask;
- bool exclude_parent_body;
+ uint32_t collision_mask = 1;
+ bool exclude_parent_body = true;
- Node *debug_shape;
+ Node *debug_shape = nullptr;
Ref<Material> debug_material;
+ Color debug_shape_custom_color = Color(0.0, 0.0, 0.0);
+ int debug_shape_thickness = 2;
+ Vector<Vector3> debug_shape_vertices;
+ Vector<Vector3> debug_line_vertices;
void _create_debug_shape();
void _update_debug_shape();
+ void _update_debug_shape_material(bool p_check_collision = false);
+ void _update_debug_shape_vertices();
void _clear_debug_shape();
- bool collide_with_areas;
- bool collide_with_bodies;
+ bool collide_with_areas = false;
+ bool collide_with_bodies = true;
protected:
void _notification(int p_what);
@@ -86,6 +92,17 @@ public:
void set_exclude_parent_body(bool p_exclude_parent_body);
bool get_exclude_parent_body() const;
+ const Color &get_debug_shape_custom_color() const;
+ void set_debug_shape_custom_color(const Color &p_color);
+
+ const Vector<Vector3> &get_debug_shape_vertices() const;
+ const Vector<Vector3> &get_debug_line_vertices() const;
+
+ Ref<StandardMaterial3D> get_debug_material();
+
+ float get_debug_shape_thickness() const;
+ void set_debug_shape_thickness(const float p_debug_thickness);
+
void force_raycast_update();
bool is_colliding() const;
Object *get_collider() const;
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index c82ed423a7..ad24f39bce 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,7 +42,7 @@ float ReflectionProbe::get_intensity() const {
void ReflectionProbe::set_ambient_mode(AmbientMode p_mode) {
ambient_mode = p_mode;
RS::get_singleton()->reflection_probe_set_ambient_mode(probe, RS::ReflectionProbeAmbientMode(p_mode));
- _change_notify();
+ notify_property_list_changed();
}
ReflectionProbe::AmbientMode ReflectionProbe::get_ambient_mode() const {
@@ -95,13 +95,12 @@ void ReflectionProbe::set_extents(const Vector3 &p_extents) {
if (extents[i] - 0.01 < ABS(origin_offset[i])) {
origin_offset[i] = SGN(origin_offset[i]) * (extents[i] - 0.01);
- _change_notify("origin_offset");
}
}
RS::get_singleton()->reflection_probe_set_extents(probe, extents);
RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset);
- _change_notify("extents");
+
update_gizmo();
}
@@ -120,7 +119,6 @@ void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) {
RS::get_singleton()->reflection_probe_set_extents(probe, extents);
RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset);
- _change_notify("origin_offset");
update_gizmo();
}
@@ -257,20 +255,6 @@ void ReflectionProbe::_bind_methods() {
}
ReflectionProbe::ReflectionProbe() {
- intensity = 1.0;
- ambient_mode = AMBIENT_ENVIRONMENT;
- ambient_color = Color(0, 0, 0);
- ambient_color_energy = 1.0;
- max_distance = 0;
- extents = Vector3(1, 1, 1);
- origin_offset = Vector3(0, 0, 0);
- box_projection = false;
- interior = false;
- enable_shadows = false;
- cull_mask = (1 << 20) - 1;
- update_mode = UPDATE_ONCE;
- lod_threshold = 1.0;
-
probe = RenderingServer::get_singleton()->reflection_probe_create();
RS::get_singleton()->instance_set_base(get_instance(), probe);
set_disable_scale(true);
diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h
index 4bff2f8bf9..15c2da3ae0 100644
--- a/scene/3d/reflection_probe.h
+++ b/scene/3d/reflection_probe.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -53,20 +53,20 @@ public:
private:
RID probe;
- float intensity;
- float max_distance;
- Vector3 extents;
- Vector3 origin_offset;
- bool box_projection;
- bool enable_shadows;
- bool interior;
- AmbientMode ambient_mode;
- Color ambient_color;
- float ambient_color_energy;
- float lod_threshold;
-
- uint32_t cull_mask;
- UpdateMode update_mode;
+ float intensity = 1.0;
+ float max_distance = 0.0;
+ Vector3 extents = Vector3(1, 1, 1);
+ Vector3 origin_offset = Vector3(0, 0, 0);
+ bool box_projection = false;
+ bool enable_shadows = false;
+ bool interior = false;
+ AmbientMode ambient_mode = AMBIENT_ENVIRONMENT;
+ Color ambient_color = Color(0, 0, 0);
+ float ambient_color_energy = 1.0;
+ float lod_threshold = 1.0;
+
+ uint32_t cull_mask = (1 << 20) - 1;
+ UpdateMode update_mode = UPDATE_ONCE;
protected:
static void _bind_methods();
diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp
index 358f9346f8..83ac813c53 100644
--- a/scene/3d/remote_transform_3d.cpp
+++ b/scene/3d/remote_transform_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -183,7 +183,7 @@ String RemoteTransform3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!has_node(remote_node) || !Object::cast_to<Node3D>(get_node(remote_node))) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work.");
@@ -217,10 +217,5 @@ void RemoteTransform3D::_bind_methods() {
}
RemoteTransform3D::RemoteTransform3D() {
- use_global_coordinates = true;
- update_remote_position = true;
- update_remote_rotation = true;
- update_remote_scale = true;
-
set_notify_transform(true);
}
diff --git a/scene/3d/remote_transform_3d.h b/scene/3d/remote_transform_3d.h
index 0ce30f7fce..21005d92d1 100644
--- a/scene/3d/remote_transform_3d.h
+++ b/scene/3d/remote_transform_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,10 +40,10 @@ class RemoteTransform3D : public Node3D {
ObjectID cache;
- bool use_global_coordinates;
- bool update_remote_position;
- bool update_remote_rotation;
- bool update_remote_scale;
+ bool use_global_coordinates = true;
+ bool update_remote_position = true;
+ bool update_remote_rotation = true;
+ bool update_remote_scale = true;
void _update_remote();
void _update_cache();
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 4425af26f9..be62fe801f 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -304,7 +304,7 @@ void Skeleton3D::_notification(int p_what) {
uint32_t bind_count = skin->get_bind_count();
if (E->get()->bind_count != bind_count) {
- RS::get_singleton()->skeleton_allocate(skeleton, bind_count);
+ RS::get_singleton()->skeleton_allocate_data(skeleton, bind_count);
E->get()->bind_count = bind_count;
E->get()->skin_bone_indices.resize(bind_count);
E->get()->skin_bone_indices_ptrs = E->get()->skin_bone_indices.ptrw();
@@ -927,10 +927,6 @@ void Skeleton3D::_bind_methods() {
}
Skeleton3D::Skeleton3D() {
- animate_physical_bones = true;
- dirty = false;
- version = 1;
- process_order_dirty = true;
}
Skeleton3D::~Skeleton3D() {
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index c54f89d3ce..9772bfcc95 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -74,57 +74,44 @@ private:
struct Bone {
String name;
- bool enabled;
- int parent;
- int sort_index; //used for re-sorting process order
+ bool enabled = true;
+ int parent = -1;
+ int sort_index = 0; //used for re-sorting process order
- bool disable_rest;
+ bool disable_rest = false;
Transform rest;
Transform pose;
Transform pose_global;
- bool custom_pose_enable;
+ bool custom_pose_enable = false;
Transform custom_pose;
- float global_pose_override_amount;
- bool global_pose_override_reset;
+ float global_pose_override_amount = 0.0;
+ bool global_pose_override_reset = false;
Transform global_pose_override;
#ifndef _3D_DISABLED
- PhysicalBone3D *physical_bone;
- PhysicalBone3D *cache_parent_physical_bone;
+ PhysicalBone3D *physical_bone = nullptr;
+ PhysicalBone3D *cache_parent_physical_bone = nullptr;
#endif // _3D_DISABLED
List<ObjectID> nodes_bound;
-
- Bone() {
- parent = -1;
- enabled = true;
- disable_rest = false;
- custom_pose_enable = false;
- global_pose_override_amount = 0;
- global_pose_override_reset = false;
-#ifndef _3D_DISABLED
- physical_bone = nullptr;
- cache_parent_physical_bone = nullptr;
-#endif // _3D_DISABLED
- }
};
Set<SkinReference *> skin_bindings;
void _skin_changed();
- bool animate_physical_bones;
+ bool animate_physical_bones = true;
Vector<Bone> bones;
Vector<int> process_order;
- bool process_order_dirty;
+ bool process_order_dirty = true;
void _make_dirty();
- bool dirty;
+ bool dirty = false;
- uint64_t version;
+ uint64_t version = 1;
// bind helpers
Array _get_bound_child_nodes_to_bone(int p_bone) const {
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp
index 32d7afd5df..cb486a12ae 100644
--- a/scene/3d/skeleton_ik_3d.cpp
+++ b/scene/3d/skeleton_ik_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -204,7 +204,7 @@ void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_
while (sub_chain_root) { // Reach the tip
sub_chain_root->current_pos = origin;
- if (!sub_chain_root->children.empty()) {
+ if (!sub_chain_root->children.is_empty()) {
ChainItem &child(sub_chain_root->children.write[0]);
// Is not tip
@@ -301,7 +301,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
Transform new_bone_pose(ci->initial_transform);
new_bone_pose.origin = ci->current_pos;
- if (!ci->children.empty()) {
+ if (!ci->children.is_empty()) {
/// Rotate basis
const Vector3 initial_ori((ci->children[0].initial_transform.origin - ci->initial_transform.origin).normalized());
const Vector3 rot_axis(initial_ori.cross(ci->current_ori).normalized());
@@ -321,7 +321,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true);
- if (!ci->children.empty()) {
+ if (!ci->children.is_empty()) {
ci = &ci->children.write[0];
} else {
ci = nullptr;
diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h
index 6c1db6dd33..eefecf68bb 100644
--- a/scene/3d/skeleton_ik_3d.h
+++ b/scene/3d/skeleton_ik_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,15 +54,13 @@ class FabrikInverseKinematic {
BoneId bone = -1;
PhysicalBone3D *pb = nullptr;
- real_t length = 0;
+ real_t length = 0.0;
/// Positions relative to root bone
Transform initial_transform;
Vector3 current_pos;
// Direction from this bone to child
Vector3 current_ori;
- ChainItem() {}
-
ChainItem *find_child(const BoneId p_bone_id);
ChainItem *add_child(const BoneId p_bone_id);
};
@@ -80,7 +78,7 @@ class FabrikInverseKinematic {
struct Chain {
ChainItem chain_root;
- ChainItem *middle_chain_item;
+ ChainItem *middle_chain_item = nullptr;
Vector<ChainTip> tips;
Vector3 magnet_position;
};
@@ -130,7 +128,7 @@ class SkeletonIK3D : public Node {
StringName root_bone;
StringName tip_bone;
- real_t interpolation = 1;
+ real_t interpolation = 1.0;
Transform target;
NodePath target_node_path_override;
bool override_tip_basis = true;
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index d811b2e852..2d8f22ab37 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -245,13 +245,11 @@ bool SoftBody3D::_get_property_pinned_points(int p_item, const String &p_what, V
return true;
}
-void SoftBody3D::_changed_callback(Object *p_changed, const char *p_prop) {
+void SoftBody3D::_softbody_changed() {
prepare_physics_server();
_reset_points_offsets();
#ifdef TOOLS_ENABLED
- if (p_changed == this) {
- update_configuration_warning();
- }
+ update_configuration_warning();
#endif
}
@@ -259,7 +257,9 @@ void SoftBody3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
if (Engine::get_singleton()->is_editor_hint()) {
- add_change_receptor(this);
+ // I have no idea what this is supposed to do, it's really weird
+ // leaving for upcoming PK work on physics
+ //add_change_receptor(this);
}
RID space = get_world_3d()->get_space();
@@ -337,8 +337,8 @@ void SoftBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness);
ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness);
- ClassDB::bind_method(D_METHOD("set_areaAngular_stiffness", "areaAngular_stiffness"), &SoftBody3D::set_areaAngular_stiffness);
- ClassDB::bind_method(D_METHOD("get_areaAngular_stiffness"), &SoftBody3D::get_areaAngular_stiffness);
+ ClassDB::bind_method(D_METHOD("set_angular_stiffness", "angular_stiffness"), &SoftBody3D::set_angular_stiffness);
+ ClassDB::bind_method(D_METHOD("get_angular_stiffness"), &SoftBody3D::get_angular_stiffness);
ClassDB::bind_method(D_METHOD("set_volume_stiffness", "volume_stiffness"), &SoftBody3D::set_volume_stiffness);
ClassDB::bind_method(D_METHOD("get_volume_stiffness"), &SoftBody3D::get_volume_stiffness);
@@ -366,7 +366,7 @@ void SoftBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "areaAngular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_areaAngular_stiffness", "get_areaAngular_stiffness");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_angular_stiffness", "get_angular_stiffness");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient");
@@ -380,7 +380,7 @@ String SoftBody3D::get_configuration_warning() const {
String warning = MeshInstance3D::get_configuration_warning();
if (get_mesh().is_null()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
@@ -389,7 +389,7 @@ String SoftBody3D::get_configuration_warning() const {
Transform t = get_transform();
if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
@@ -612,12 +612,12 @@ real_t SoftBody3D::get_linear_stiffness() {
return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid);
}
-void SoftBody3D::set_areaAngular_stiffness(real_t p_areaAngular_stiffness) {
- PhysicsServer3D::get_singleton()->soft_body_set_areaAngular_stiffness(physics_rid, p_areaAngular_stiffness);
+void SoftBody3D::set_angular_stiffness(real_t p_angular_stiffness) {
+ PhysicsServer3D::get_singleton()->soft_body_set_angular_stiffness(physics_rid, p_angular_stiffness);
}
-real_t SoftBody3D::get_areaAngular_stiffness() {
- return PhysicsServer3D::get_singleton()->soft_body_get_areaAngular_stiffness(physics_rid);
+real_t SoftBody3D::get_angular_stiffness() {
+ return PhysicsServer3D::get_singleton()->soft_body_get_angular_stiffness(physics_rid);
}
void SoftBody3D::set_volume_stiffness(real_t p_volume_stiffness) {
diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h
index c59a0b3aa3..6e24a530bd 100644
--- a/scene/3d/soft_body_3d.h
+++ b/scene/3d/soft_body_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,13 +39,13 @@ class SoftBodyRenderingServerHandler {
friend class SoftBody3D;
RID mesh;
- int surface;
+ int surface = 0;
Vector<uint8_t> buffer;
- uint32_t stride;
- uint32_t offset_vertices;
- uint32_t offset_normal;
+ uint32_t stride = 0;
+ uint32_t offset_vertices = 0;
+ uint32_t offset_normal = 0;
- uint8_t *write_buffer;
+ uint8_t *write_buffer = nullptr;
private:
SoftBodyRenderingServerHandler();
@@ -91,13 +91,15 @@ private:
bool pinned_points_cache_dirty = true;
Ref<ArrayMesh> debug_mesh_cache;
- class MeshInstance3D *debug_mesh;
+ class MeshInstance3D *debug_mesh = nullptr;
- bool capture_input_on_drag;
+ bool capture_input_on_drag = false;
bool ray_pickable = true;
void _update_pickable();
+ void _softbody_changed();
+
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
@@ -107,8 +109,6 @@ protected:
bool _set_property_pinned_points_attachment(int p_item, const String &p_what, const Variant &p_value);
bool _get_property_pinned_points(int p_item, const String &p_what, Variant &r_ret) const;
- virtual void _changed_callback(Object *p_changed, const char *p_prop) override;
-
void _notification(int p_what);
static void _bind_methods();
@@ -149,8 +149,8 @@ public:
void set_linear_stiffness(real_t p_linear_stiffness);
real_t get_linear_stiffness();
- void set_areaAngular_stiffness(real_t p_areaAngular_stiffness);
- real_t get_areaAngular_stiffness();
+ void set_angular_stiffness(real_t p_angular_stiffness);
+ real_t get_angular_stiffness();
void set_volume_stiffness(real_t p_volume_stiffness);
real_t get_volume_stiffness();
diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp
index 287d760db0..9518b47696 100644
--- a/scene/3d/spring_arm_3d.cpp
+++ b/scene/3d/spring_arm_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,11 +78,11 @@ void SpringArm3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin");
}
-float SpringArm3D::get_length() const {
+real_t SpringArm3D::get_length() const {
return spring_length;
}
-void SpringArm3D::set_length(float p_length) {
+void SpringArm3D::set_length(real_t p_length) {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update_gizmo();
}
@@ -106,11 +106,11 @@ uint32_t SpringArm3D::get_mask() {
return mask;
}
-float SpringArm3D::get_margin() {
+real_t SpringArm3D::get_margin() {
return margin;
}
-void SpringArm3D::set_margin(float p_margin) {
+void SpringArm3D::set_margin(real_t p_margin) {
margin = p_margin;
}
@@ -126,7 +126,7 @@ void SpringArm3D::clear_excluded_objects() {
excluded_objects.clear();
}
-float SpringArm3D::get_hit_length() {
+real_t SpringArm3D::get_hit_length() {
return current_spring_length;
}
@@ -143,7 +143,7 @@ void SpringArm3D::process_spring() {
PhysicsDirectSpaceState3D::RayResult r;
bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask);
if (intersected) {
- float dist = get_global_transform().origin.distance_to(r.position);
+ real_t dist = get_global_transform().origin.distance_to(r.position);
dist -= margin;
motion_delta = dist / (spring_length);
}
diff --git a/scene/3d/spring_arm_3d.h b/scene/3d/spring_arm_3d.h
index 7f6fe2f1a2..63505ab9d3 100644
--- a/scene/3d/spring_arm_3d.h
+++ b/scene/3d/spring_arm_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,19 +38,19 @@ class SpringArm3D : public Node3D {
Ref<Shape3D> shape;
Set<RID> excluded_objects;
- float spring_length = 1;
- float current_spring_length = 0;
+ real_t spring_length = 1.0;
+ real_t current_spring_length = 0.0;
bool keep_child_basis = false;
uint32_t mask = 1;
- float margin = 0.01;
+ real_t margin = 0.01;
protected:
void _notification(int p_what);
static void _bind_methods();
public:
- void set_length(float p_length);
- float get_length() const;
+ void set_length(real_t p_length);
+ real_t get_length() const;
void set_shape(Ref<Shape3D> p_shape);
Ref<Shape3D> get_shape() const;
void set_mask(uint32_t p_mask);
@@ -58,9 +58,9 @@ public:
void add_excluded_object(RID p_rid);
bool remove_excluded_object(RID p_rid);
void clear_excluded_objects();
- float get_hit_length();
- void set_margin(float p_margin);
- float get_margin();
+ real_t get_hit_length();
+ void set_margin(real_t p_margin);
+ real_t get_margin();
SpringArm3D() {}
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 1d20a9cd3b..b7a3135bd5 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -339,24 +339,10 @@ void SpriteBase3D::_bind_methods() {
}
SpriteBase3D::SpriteBase3D() {
- color_dirty = true;
- centered = true;
- hflip = false;
- vflip = false;
- parent_sprite = nullptr;
- pI = nullptr;
-
for (int i = 0; i < FLAG_MAX; i++) {
flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED;
}
- alpha_cut = ALPHA_CUT_DISABLED;
- billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
- axis = Vector3::AXIS_Z;
- pixel_size = 0.01;
- modulate = Color(1, 1, 1, 1);
- pending_update = false;
- opacity = 1.0;
immediate = RenderingServer::get_singleton()->immediate_create();
set_base(immediate);
}
@@ -532,6 +518,7 @@ void Sprite3D::set_region(bool p_region) {
region = p_region;
_queue_update();
+ notify_property_list_changed();
}
bool Sprite3D::is_region() const {
@@ -557,8 +544,6 @@ void Sprite3D::set_frame(int p_frame) {
_queue_update();
- _change_notify("frame");
- _change_notify("frame_coords");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -581,7 +566,7 @@ void Sprite3D::set_vframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
vframes = p_amount;
_queue_update();
- _change_notify();
+ notify_property_list_changed();
}
int Sprite3D::get_vframes() const {
@@ -592,7 +577,7 @@ void Sprite3D::set_hframes(int p_amount) {
ERR_FAIL_COND(p_amount < 1);
hframes = p_amount;
_queue_update();
- _change_notify();
+ notify_property_list_changed();
}
int Sprite3D::get_hframes() const {
@@ -639,6 +624,10 @@ void Sprite3D::_validate_property(PropertyInfo &property) const {
if (property.name == "frame_coords") {
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
+
+ if (!region && property.name == "region_rect") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
}
void Sprite3D::_bind_methods() {
@@ -904,12 +893,13 @@ void AnimatedSprite3D::_notification(int p_what) {
} else {
frame = fc - 1;
}
+ emit_signal(SceneStringNames::get_singleton()->animation_finished);
} else {
frame++;
}
_queue_update();
- _change_notify("frame");
+ emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
float to_process = MIN(timeout, remaining);
@@ -935,7 +925,7 @@ void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
set_frame(frame);
}
- _change_notify();
+ notify_property_list_changed();
_reset_timeout();
_queue_update();
update_configuration_warning();
@@ -968,7 +958,7 @@ void AnimatedSprite3D::set_frame(int p_frame) {
frame = p_frame;
_reset_timeout();
_queue_update();
- _change_notify("frame");
+
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
@@ -1004,8 +994,6 @@ Rect2 AnimatedSprite3D::get_item_rect() const {
void AnimatedSprite3D::_res_changed() {
set_frame(frame);
- _change_notify("frame");
- _change_notify("animation");
_queue_update();
}
@@ -1062,7 +1050,7 @@ void AnimatedSprite3D::set_animation(const StringName &p_animation) {
animation = p_animation;
_reset_timeout();
set_frame(0);
- _change_notify();
+ notify_property_list_changed();
_queue_update();
}
@@ -1074,7 +1062,7 @@ String AnimatedSprite3D::get_configuration_warning() const {
String warning = SpriteBase3D::get_configuration_warning();
if (frames.is_null()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames.");
@@ -1101,6 +1089,7 @@ void AnimatedSprite3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame);
ADD_SIGNAL(MethodInfo("frame_changed"));
+ ADD_SIGNAL(MethodInfo("animation_finished"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation");
@@ -1109,8 +1098,4 @@ void AnimatedSprite3D::_bind_methods() {
}
AnimatedSprite3D::AnimatedSprite3D() {
- frame = 0;
- playing = false;
- animation = "default";
- timeout = 0;
}
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index cb8467aac6..a9ce2d8eee 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,32 +55,32 @@ public:
};
private:
- bool color_dirty;
+ bool color_dirty = true;
Color color_accum;
- SpriteBase3D *parent_sprite;
+ SpriteBase3D *parent_sprite = nullptr;
List<SpriteBase3D *> children;
- List<SpriteBase3D *>::Element *pI;
+ List<SpriteBase3D *>::Element *pI = nullptr;
- bool centered;
+ bool centered = true;
Point2 offset;
- bool hflip;
- bool vflip;
+ bool hflip = false;
+ bool vflip = false;
- Color modulate;
- float opacity;
+ Color modulate = Color(1, 1, 1, 1);
+ float opacity = 1.0;
- Vector3::Axis axis;
- float pixel_size;
+ Vector3::Axis axis = Vector3::AXIS_Z;
+ float pixel_size = 0.01;
AABB aabb;
RID immediate;
bool flags[FLAG_MAX];
- AlphaCutMode alpha_cut;
- StandardMaterial3D::BillboardMode billboard_mode;
- bool pending_update;
+ AlphaCutMode alpha_cut = ALPHA_CUT_DISABLED;
+ StandardMaterial3D::BillboardMode billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
+ bool pending_update = false;
void _im_update();
void _propagate_color_changed();
@@ -195,16 +195,16 @@ class AnimatedSprite3D : public SpriteBase3D {
GDCLASS(AnimatedSprite3D, SpriteBase3D);
Ref<SpriteFrames> frames;
- bool playing;
- StringName animation;
- int frame;
+ bool playing = false;
+ StringName animation = "default";
+ int frame = 0;
- bool centered;
+ bool centered = true;
- float timeout;
+ float timeout = 0.0;
- bool hflip;
- bool vflip;
+ bool hflip = 1;
+ bool vflip = 1;
Color modulate;
diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp
index e27307e75f..8b774444b9 100644
--- a/scene/3d/vehicle_body_3d.cpp
+++ b/scene/3d/vehicle_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -106,7 +106,7 @@ String VehicleWheel3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (!Object::cast_to<VehicleBody3D>(get_parent())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("VehicleWheel3D serves to provide a wheel system to a VehicleBody3D. Please use it as a child of a VehicleBody3D.");
@@ -147,77 +147,77 @@ void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) {
}
}
-void VehicleWheel3D::set_radius(float p_radius) {
+void VehicleWheel3D::set_radius(real_t p_radius) {
m_wheelRadius = p_radius;
update_gizmo();
}
-float VehicleWheel3D::get_radius() const {
+real_t VehicleWheel3D::get_radius() const {
return m_wheelRadius;
}
-void VehicleWheel3D::set_suspension_rest_length(float p_length) {
+void VehicleWheel3D::set_suspension_rest_length(real_t p_length) {
m_suspensionRestLength = p_length;
update_gizmo();
}
-float VehicleWheel3D::get_suspension_rest_length() const {
+real_t VehicleWheel3D::get_suspension_rest_length() const {
return m_suspensionRestLength;
}
-void VehicleWheel3D::set_suspension_travel(float p_length) {
+void VehicleWheel3D::set_suspension_travel(real_t p_length) {
m_maxSuspensionTravelCm = p_length / 0.01;
}
-float VehicleWheel3D::get_suspension_travel() const {
+real_t VehicleWheel3D::get_suspension_travel() const {
return m_maxSuspensionTravelCm * 0.01;
}
-void VehicleWheel3D::set_suspension_stiffness(float p_value) {
+void VehicleWheel3D::set_suspension_stiffness(real_t p_value) {
m_suspensionStiffness = p_value;
}
-float VehicleWheel3D::get_suspension_stiffness() const {
+real_t VehicleWheel3D::get_suspension_stiffness() const {
return m_suspensionStiffness;
}
-void VehicleWheel3D::set_suspension_max_force(float p_value) {
+void VehicleWheel3D::set_suspension_max_force(real_t p_value) {
m_maxSuspensionForce = p_value;
}
-float VehicleWheel3D::get_suspension_max_force() const {
+real_t VehicleWheel3D::get_suspension_max_force() const {
return m_maxSuspensionForce;
}
-void VehicleWheel3D::set_damping_compression(float p_value) {
+void VehicleWheel3D::set_damping_compression(real_t p_value) {
m_wheelsDampingCompression = p_value;
}
-float VehicleWheel3D::get_damping_compression() const {
+real_t VehicleWheel3D::get_damping_compression() const {
return m_wheelsDampingCompression;
}
-void VehicleWheel3D::set_damping_relaxation(float p_value) {
+void VehicleWheel3D::set_damping_relaxation(real_t p_value) {
m_wheelsDampingRelaxation = p_value;
}
-float VehicleWheel3D::get_damping_relaxation() const {
+real_t VehicleWheel3D::get_damping_relaxation() const {
return m_wheelsDampingRelaxation;
}
-void VehicleWheel3D::set_friction_slip(float p_value) {
+void VehicleWheel3D::set_friction_slip(real_t p_value) {
m_frictionSlip = p_value;
}
-float VehicleWheel3D::get_friction_slip() const {
+real_t VehicleWheel3D::get_friction_slip() const {
return m_frictionSlip;
}
-void VehicleWheel3D::set_roll_influence(float p_value) {
+void VehicleWheel3D::set_roll_influence(real_t p_value) {
m_rollInfluence = p_value;
}
-float VehicleWheel3D::get_roll_influence() const {
+real_t VehicleWheel3D::get_roll_influence() const {
return m_rollInfluence;
}
@@ -295,27 +295,27 @@ void VehicleWheel3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_relaxation"), "set_damping_relaxation", "get_damping_relaxation");
}
-void VehicleWheel3D::set_engine_force(float p_engine_force) {
+void VehicleWheel3D::set_engine_force(real_t p_engine_force) {
m_engineForce = p_engine_force;
}
-float VehicleWheel3D::get_engine_force() const {
+real_t VehicleWheel3D::get_engine_force() const {
return m_engineForce;
}
-void VehicleWheel3D::set_brake(float p_brake) {
+void VehicleWheel3D::set_brake(real_t p_brake) {
m_brake = p_brake;
}
-float VehicleWheel3D::get_brake() const {
+real_t VehicleWheel3D::get_brake() const {
return m_brake;
}
-void VehicleWheel3D::set_steering(float p_steering) {
+void VehicleWheel3D::set_steering(real_t p_steering) {
m_steering = p_steering;
}
-float VehicleWheel3D::get_steering() const {
+real_t VehicleWheel3D::get_steering() const {
return m_steering;
}
@@ -335,39 +335,15 @@ bool VehicleWheel3D::is_used_as_steering() const {
return steers;
}
-float VehicleWheel3D::get_skidinfo() const {
+real_t VehicleWheel3D::get_skidinfo() const {
return m_skidInfo;
}
-float VehicleWheel3D::get_rpm() const {
+real_t VehicleWheel3D::get_rpm() const {
return m_rpm;
}
VehicleWheel3D::VehicleWheel3D() {
- steers = false;
- engine_traction = false;
- m_steering = real_t(0.);
- m_engineForce = real_t(0.);
- m_rotation = real_t(0.);
- m_deltaRotation = real_t(0.);
- m_brake = real_t(0.);
- m_rollInfluence = real_t(0.1);
-
- m_suspensionRestLength = 0.15;
- m_wheelRadius = 0.5; //0.28;
- m_suspensionStiffness = 5.88;
- m_wheelsDampingCompression = 0.83;
- m_wheelsDampingRelaxation = 0.88;
- m_frictionSlip = 10.5;
- m_bIsFrontWheel = false;
- m_maxSuspensionTravelCm = 500;
- m_maxSuspensionForce = 6000;
-
- m_suspensionRelativeVelocity = 0;
- m_clippedInvContactDotSuspension = 1.0;
- m_raycastInfo.m_isInContact = false;
-
- body = nullptr;
}
void VehicleBody3D::_update_wheel_transform(VehicleWheel3D &wheel, PhysicsDirectBodyState3D *s) {
@@ -431,7 +407,7 @@ real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) {
PhysicsDirectSpaceState3D *ss = s->get_space_state();
- bool col = ss->intersect_ray(source, target, rr, exclude);
+ bool col = ss->intersect_ray(source, target, rr, exclude, get_collision_mask());
wheel.m_raycastInfo.m_groundObject = nullptr;
@@ -564,7 +540,7 @@ void VehicleBody3D::_resolve_single_bilateral(PhysicsDirectBodyState3D *s, const
Vector3 vel = vel1 - vel2;
Basis b2trans;
- float b2invmass = 0;
+ real_t b2invmass = 0;
Vector3 b2lv;
Vector3 b2av;
Vector3 b2invinertia; //todo
@@ -622,8 +598,8 @@ VehicleBody3D::btVehicleWheelContactPoint::btVehicleWheelContactPoint(PhysicsDir
m_frictionPositionWorld(frictionPosWorld),
m_frictionDirectionWorld(frictionDirectionWorld),
m_maxImpulse(maxImpulse) {
- float denom0 = 0;
- float denom1 = 0;
+ real_t denom0 = 0;
+ real_t denom1 = 0;
{
Vector3 r0 = frictionPosWorld - s->get_transform().origin;
@@ -831,7 +807,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) {
state = Object::cast_to<PhysicsDirectBodyState3D>(p_state);
- float step = state->get_step();
+ real_t step = state->get_step();
for (int i = 0; i < wheels.size(); i++) {
_update_wheel(i, state);
@@ -891,7 +867,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) {
state = nullptr;
}
-void VehicleBody3D::set_engine_force(float p_engine_force) {
+void VehicleBody3D::set_engine_force(real_t p_engine_force) {
engine_force = p_engine_force;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
@@ -901,11 +877,11 @@ void VehicleBody3D::set_engine_force(float p_engine_force) {
}
}
-float VehicleBody3D::get_engine_force() const {
+real_t VehicleBody3D::get_engine_force() const {
return engine_force;
}
-void VehicleBody3D::set_brake(float p_brake) {
+void VehicleBody3D::set_brake(real_t p_brake) {
brake = p_brake;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
@@ -913,11 +889,11 @@ void VehicleBody3D::set_brake(float p_brake) {
}
}
-float VehicleBody3D::get_brake() const {
+real_t VehicleBody3D::get_brake() const {
return brake;
}
-void VehicleBody3D::set_steering(float p_steering) {
+void VehicleBody3D::set_steering(real_t p_steering) {
m_steeringValue = p_steering;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
@@ -927,7 +903,7 @@ void VehicleBody3D::set_steering(float p_steering) {
}
}
-float VehicleBody3D::get_steering() const {
+real_t VehicleBody3D::get_steering() const {
return m_steeringValue;
}
@@ -948,16 +924,6 @@ void VehicleBody3D::_bind_methods() {
}
VehicleBody3D::VehicleBody3D() {
- m_pitchControl = 0;
- m_currentVehicleSpeedKmHour = real_t(0.);
- m_steeringValue = real_t(0.);
-
- engine_force = 0;
- brake = 0;
-
- state = nullptr;
- ccd = false;
-
exclude.insert(get_rid());
//PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h
index 0b4b3a4440..860fa7e3b7 100644
--- a/scene/3d/vehicle_body_3d.h
+++ b/scene/3d/vehicle_body_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,52 +42,52 @@ class VehicleWheel3D : public Node3D {
Transform m_worldTransform;
Transform local_xform;
- bool engine_traction;
- bool steers;
+ bool engine_traction = false;
+ bool steers = false;
Vector3 m_chassisConnectionPointCS; //const
Vector3 m_wheelDirectionCS; //const
Vector3 m_wheelAxleCS; // const or modified by steering
- real_t m_suspensionRestLength;
- real_t m_maxSuspensionTravelCm;
- real_t m_wheelRadius;
+ real_t m_suspensionRestLength = 0.15;
+ real_t m_maxSuspensionTravelCm = 500.0;
+ real_t m_wheelRadius = 0.5;
- real_t m_suspensionStiffness;
- real_t m_wheelsDampingCompression;
- real_t m_wheelsDampingRelaxation;
- real_t m_frictionSlip;
- real_t m_maxSuspensionForce;
- bool m_bIsFrontWheel;
+ real_t m_suspensionStiffness = 5.88;
+ real_t m_wheelsDampingCompression = 0.83;
+ real_t m_wheelsDampingRelaxation = 0.88;
+ real_t m_frictionSlip = 10.5;
+ real_t m_maxSuspensionForce = 6000.0;
+ bool m_bIsFrontWheel = false;
- VehicleBody3D *body;
+ VehicleBody3D *body = nullptr;
//btVector3 m_wheelAxleCS; // const or modified by steering ?
- real_t m_steering;
- real_t m_rotation;
- real_t m_deltaRotation;
- real_t m_rpm;
- real_t m_rollInfluence;
- real_t m_engineForce;
- real_t m_brake;
+ real_t m_steering = 0.0;
+ real_t m_rotation = 0.0;
+ real_t m_deltaRotation = 0.0;
+ real_t m_rpm = 0.0;
+ real_t m_rollInfluence = 0.1;
+ real_t m_engineForce = 0.0;
+ real_t m_brake = 0.0;
- real_t m_clippedInvContactDotSuspension;
- real_t m_suspensionRelativeVelocity;
+ real_t m_clippedInvContactDotSuspension = 1.0;
+ real_t m_suspensionRelativeVelocity = 0.0;
//calculated by suspension
- real_t m_wheelsSuspensionForce;
- real_t m_skidInfo;
+ real_t m_wheelsSuspensionForce = 0.0;
+ real_t m_skidInfo = 0.0;
struct RaycastInfo {
//set by raycaster
Vector3 m_contactNormalWS; //contactnormal
Vector3 m_contactPointWS; //raycast hitpoint
- real_t m_suspensionLength;
+ real_t m_suspensionLength = 0.0;
Vector3 m_hardPointWS; //raycast starting point
Vector3 m_wheelDirectionWS; //direction in worldspace
Vector3 m_wheelAxleWS; // axle in worldspace
- bool m_isInContact;
- PhysicsBody3D *m_groundObject; //could be general void* ptr
+ bool m_isInContact = false;
+ PhysicsBody3D *m_groundObject = nullptr; //could be general void* ptr
} m_raycastInfo;
void _update(PhysicsDirectBodyState3D *s);
@@ -97,29 +97,29 @@ protected:
static void _bind_methods();
public:
- void set_radius(float p_radius);
- float get_radius() const;
+ void set_radius(real_t p_radius);
+ real_t get_radius() const;
- void set_suspension_rest_length(float p_length);
- float get_suspension_rest_length() const;
+ void set_suspension_rest_length(real_t p_length);
+ real_t get_suspension_rest_length() const;
- void set_suspension_travel(float p_length);
- float get_suspension_travel() const;
+ void set_suspension_travel(real_t p_length);
+ real_t get_suspension_travel() const;
- void set_suspension_stiffness(float p_value);
- float get_suspension_stiffness() const;
+ void set_suspension_stiffness(real_t p_value);
+ real_t get_suspension_stiffness() const;
- void set_suspension_max_force(float p_value);
- float get_suspension_max_force() const;
+ void set_suspension_max_force(real_t p_value);
+ real_t get_suspension_max_force() const;
- void set_damping_compression(float p_value);
- float get_damping_compression() const;
+ void set_damping_compression(real_t p_value);
+ real_t get_damping_compression() const;
- void set_damping_relaxation(float p_value);
- float get_damping_relaxation() const;
+ void set_damping_relaxation(real_t p_value);
+ real_t get_damping_relaxation() const;
- void set_friction_slip(float p_value);
- float get_friction_slip() const;
+ void set_friction_slip(real_t p_value);
+ real_t get_friction_slip() const;
void set_use_as_traction(bool p_enable);
bool is_used_as_traction() const;
@@ -129,21 +129,21 @@ public:
bool is_in_contact() const;
- void set_roll_influence(float p_value);
- float get_roll_influence() const;
+ void set_roll_influence(real_t p_value);
+ real_t get_roll_influence() const;
- float get_skidinfo() const;
+ real_t get_skidinfo() const;
- float get_rpm() const;
+ real_t get_rpm() const;
- void set_engine_force(float p_engine_force);
- float get_engine_force() const;
+ void set_engine_force(real_t p_engine_force);
+ real_t get_engine_force() const;
- void set_brake(float p_brake);
- float get_brake() const;
+ void set_brake(real_t p_brake);
+ real_t get_brake() const;
- void set_steering(float p_steering);
- float get_steering() const;
+ void set_steering(real_t p_steering);
+ real_t get_steering() const;
String get_configuration_warning() const override;
@@ -153,12 +153,12 @@ public:
class VehicleBody3D : public RigidBody3D {
GDCLASS(VehicleBody3D, RigidBody3D);
- float engine_force;
- float brake;
+ real_t engine_force = 0.0;
+ real_t brake = 0.0;
- real_t m_pitchControl;
- real_t m_steeringValue;
- real_t m_currentVehicleSpeedKmHour;
+ real_t m_pitchControl = 0.0;
+ real_t m_steeringValue = 0.0;
+ real_t m_currentVehicleSpeedKmHour = 0.0;
Set<RID> exclude;
@@ -168,12 +168,12 @@ class VehicleBody3D : public RigidBody3D {
Vector<real_t> m_sideImpulse;
struct btVehicleWheelContactPoint {
- PhysicsDirectBodyState3D *m_s;
- PhysicsBody3D *m_body1;
+ PhysicsDirectBodyState3D *m_s = nullptr;
+ PhysicsBody3D *m_body1 = nullptr;
Vector3 m_frictionPositionWorld;
Vector3 m_frictionDirectionWorld;
- real_t m_jacDiagABInv;
- real_t m_maxImpulse;
+ real_t m_jacDiagABInv = 0.0;
+ real_t m_maxImpulse = 0.0;
btVehicleWheelContactPoint(PhysicsDirectBodyState3D *s, PhysicsBody3D *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse);
};
@@ -195,14 +195,14 @@ class VehicleBody3D : public RigidBody3D {
void _direct_state_changed(Object *p_state) override;
public:
- void set_engine_force(float p_engine_force);
- float get_engine_force() const;
+ void set_engine_force(real_t p_engine_force);
+ real_t get_engine_force() const;
- void set_brake(float p_brake);
- float get_brake() const;
+ void set_brake(real_t p_brake);
+ real_t get_brake() const;
- void set_steering(float p_steering);
- float get_steering() const;
+ void set_steering(real_t p_steering);
+ real_t get_steering() const;
VehicleBody3D();
};
diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp
index eba7d44c16..5b5cc06456 100644
--- a/scene/3d/velocity_tracker_3d.cpp
+++ b/scene/3d/velocity_tracker_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,7 @@ void VelocityTracker3D::update_position(const Vector3 &p_position) {
if (physics_step) {
ph.frame = Engine::get_singleton()->get_physics_frames();
} else {
- ph.frame = Engine::get_singleton()->get_idle_frame_ticks();
+ ph.frame = Engine::get_singleton()->get_frame_ticks();
}
if (position_history_len == 0 || position_history[0].frame != ph.frame) { //in same frame, use latest
@@ -72,7 +72,7 @@ Vector3 VelocityTracker3D::get_tracked_linear_velocity() const {
uint64_t base = Engine::get_singleton()->get_physics_frames();
base_time = float(base - position_history[0].frame) / Engine::get_singleton()->get_iterations_per_second();
} else {
- uint64_t base = Engine::get_singleton()->get_idle_frame_ticks();
+ uint64_t base = Engine::get_singleton()->get_frame_ticks();
base_time = double(base - position_history[0].frame) / 1000000.0;
}
}
@@ -109,7 +109,7 @@ void VelocityTracker3D::reset(const Vector3 &p_new_pos) {
if (physics_step) {
ph.frame = Engine::get_singleton()->get_physics_frames();
} else {
- ph.frame = Engine::get_singleton()->get_idle_frame_ticks();
+ ph.frame = Engine::get_singleton()->get_frame_ticks();
}
position_history.write[0] = ph;
@@ -128,6 +128,4 @@ void VelocityTracker3D::_bind_methods() {
VelocityTracker3D::VelocityTracker3D() {
position_history.resize(4); // should be configurable
- position_history_len = 0;
- physics_step = false;
}
diff --git a/scene/3d/velocity_tracker_3d.h b/scene/3d/velocity_tracker_3d.h
index a7ab3dce4d..e971f4755a 100644
--- a/scene/3d/velocity_tracker_3d.h
+++ b/scene/3d/velocity_tracker_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,13 +37,13 @@ class VelocityTracker3D : public Reference {
GDCLASS(VelocityTracker3D, Reference);
struct PositionHistory {
- uint64_t frame;
+ uint64_t frame = 0;
Vector3 position;
};
- bool physics_step;
+ bool physics_step = false;
Vector<PositionHistory> position_history;
- int position_history_len;
+ int position_history_len = 0;
protected:
static void _bind_methods();
diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp
index 9f5c40caf4..471838b9d1 100644
--- a/scene/3d/visibility_notifier_3d.cpp
+++ b/scene/3d/visibility_notifier_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -69,7 +69,6 @@ void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) {
get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb));
}
- _change_notify("aabb");
update_gizmo();
}
@@ -80,13 +79,16 @@ AABB VisibilityNotifier3D::get_aabb() const {
void VisibilityNotifier3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
- get_world_3d()->_register_notifier(this, get_global_transform().xform(aabb));
+ world = get_world_3d();
+ ERR_FAIL_COND(!world.is_valid());
+ world->_register_notifier(this, get_global_transform().xform(aabb));
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
- get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb));
+ world->_update_notifier(this, get_global_transform().xform(aabb));
} break;
case NOTIFICATION_EXIT_WORLD: {
- get_world_3d()->_remove_notifier(this);
+ ERR_FAIL_COND(!world.is_valid());
+ world->_remove_notifier(this);
} break;
}
}
@@ -109,7 +111,6 @@ void VisibilityNotifier3D::_bind_methods() {
}
VisibilityNotifier3D::VisibilityNotifier3D() {
- aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
set_notify_transform(true);
}
@@ -249,6 +250,4 @@ VisibilityEnabler3D::VisibilityEnabler3D() {
for (int i = 0; i < ENABLER_MAX; i++) {
enabler[i] = true;
}
-
- visible = false;
}
diff --git a/scene/3d/visibility_notifier_3d.h b/scene/3d/visibility_notifier_3d.h
index 35f6c02e83..9f7705067f 100644
--- a/scene/3d/visibility_notifier_3d.h
+++ b/scene/3d/visibility_notifier_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,13 +33,15 @@
#include "scene/3d/node_3d.h"
+class World3D;
class Camera3D;
class VisibilityNotifier3D : public Node3D {
GDCLASS(VisibilityNotifier3D, Node3D);
+ Ref<World3D> world;
Set<Camera3D *> cameras;
- AABB aabb;
+ AABB aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
protected:
virtual void _screen_enter() {}
@@ -74,7 +76,7 @@ protected:
virtual void _screen_enter() override;
virtual void _screen_exit() override;
- bool visible;
+ bool visible = false;
void _find_nodes(Node *p_node);
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index 0b70b0f920..394c67e873 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,6 @@ void VisualInstance3D::_update_visibility() {
return;
}
- _change_notify("visible");
RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree());
}
@@ -135,7 +134,6 @@ RID VisualInstance3D::get_base() const {
VisualInstance3D::VisualInstance3D() {
instance = RenderingServer::get_singleton()->instance_create();
RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id());
- layers = 1;
set_notify_transform(true);
}
@@ -371,7 +369,7 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_gi_mode", "mode"), &GeometryInstance3D::set_gi_mode);
ClassDB::bind_method(D_METHOD("get_gi_mode"), &GeometryInstance3D::get_gi_mode);
- ClassDB::bind_method(D_METHOD("set_lod_bias", "p_bias"), &GeometryInstance3D::set_lod_bias);
+ ClassDB::bind_method(D_METHOD("set_lod_bias", "bias"), &GeometryInstance3D::set_lod_bias);
ClassDB::bind_method(D_METHOD("get_lod_bias"), &GeometryInstance3D::get_lod_bias);
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &GeometryInstance3D::set_custom_aabb);
@@ -412,17 +410,5 @@ void GeometryInstance3D::_bind_methods() {
}
GeometryInstance3D::GeometryInstance3D() {
- lod_min_distance = 0;
- lod_max_distance = 0;
- lod_min_hysteresis = 0;
- lod_max_hysteresis = 0;
-
- lod_bias = 1.0;
-
- gi_mode = GI_MODE_DISABLED;
- lightmap_scale = LIGHTMAP_SCALE_1X;
-
- shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
- extra_cull_margin = 0;
//RS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0);
}
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index 0810b7b4ce..7fed8095ef 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,7 +42,7 @@ class VisualInstance3D : public Node3D {
RID base;
RID instance;
- uint32_t layers;
+ uint32_t layers = 1;
RID _get_visual_instance_rid() const;
@@ -105,21 +105,21 @@ public:
};
private:
- ShadowCastingSetting shadow_casting_setting;
+ ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
Ref<Material> material_override;
- float lod_min_distance;
- float lod_max_distance;
- float lod_min_hysteresis;
- float lod_max_hysteresis;
+ float lod_min_distance = 0.0;
+ float lod_max_distance = 0.0;
+ float lod_min_hysteresis = 0.0;
+ float lod_max_hysteresis = 0.0;
- float lod_bias;
+ float lod_bias = 1.0;
mutable HashMap<StringName, Variant> instance_uniforms;
mutable HashMap<StringName, StringName> instance_uniform_property_remap;
- float extra_cull_margin;
- LightmapScale lightmap_scale;
- GIMode gi_mode;
+ float extra_cull_margin = 0.0;
+ LightmapScale lightmap_scale = LIGHTMAP_SCALE_1X;
+ GIMode gi_mode = GI_MODE_DISABLED;
const StringName *_instance_uniform_get_remap(const StringName p_name) const;
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
index c570fc7b7c..17c8596e8f 100644
--- a/scene/3d/voxelizer.cpp
+++ b/scene/3d/voxelizer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -294,7 +294,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector<Color> Voxelizer::_get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add) {
Vector<Color> ret;
- if (p_image.is_null() || p_image->empty()) {
+ if (p_image.is_null() || p_image->is_empty()) {
ret.resize(bake_texture_size * bake_texture_size);
for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
ret.write[i] = p_color_add;
@@ -1007,7 +1007,4 @@ Transform Voxelizer::get_to_cell_space_xform() const {
}
Voxelizer::Voxelizer() {
- sorted = false;
- color_scan_cell_width = 4;
- bake_texture_size = 128;
}
diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h
index 3546fd7729..87f949e7db 100644
--- a/scene/3d/voxelizer.h
+++ b/scene/3d/voxelizer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,35 +44,25 @@ private:
struct Cell {
uint32_t children[8];
- float albedo[3]; //albedo in RGB24
- float emission[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
- float normal[3];
- uint32_t used_sides;
- float alpha; //used for upsampling
- uint16_t x;
- uint16_t y;
- uint16_t z;
- uint16_t level;
+ float albedo[3] = {}; //albedo in RGB24
+ float emission[3] = {}; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
+ float normal[3] = {};
+ uint32_t used_sides = 0;
+ float alpha = 0.0; //used for upsampling
+ uint16_t x = 0;
+ uint16_t y = 0;
+ uint16_t z = 0;
+ uint16_t level = 0;
Cell() {
for (int i = 0; i < 8; i++) {
children[i] = CHILD_EMPTY;
}
-
- for (int i = 0; i < 3; i++) {
- emission[i] = 0;
- albedo[i] = 0;
- normal[i] = 0;
- }
- alpha = 0;
- used_sides = 0;
- x = y = z = 0;
- level = 0;
}
};
Vector<Cell> bake_cells;
- int cell_subdiv;
+ int cell_subdiv = 0;
struct CellSort {
union {
@@ -82,10 +72,10 @@ private:
uint64_t x : 16;
uint64_t level : 16;
};
- uint64_t key;
+ uint64_t key = 0;
};
- int32_t index;
+ int32_t index = 0;
_FORCE_INLINE_ bool operator<(const CellSort &p_cell_sort) const {
return key < p_cell_sort.key;
@@ -101,16 +91,16 @@ private:
Map<Ref<Material>, MaterialCache> material_cache;
AABB original_bounds;
AABB po2_bounds;
- int axis_cell_size[3];
+ int axis_cell_size[3] = {};
Transform to_cell_space;
- int color_scan_cell_width;
- int bake_texture_size;
- float cell_size;
+ int color_scan_cell_width = 4;
+ int bake_texture_size = 128;
+ float cell_size = 0.0;
- int max_original_cells;
- int leaf_voxel_count;
+ int max_original_cells = 0;
+ int leaf_voxel_count = 0;
Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add);
MaterialCache _get_material_cache(Ref<Material> p_material);
@@ -119,7 +109,7 @@ private:
void _fixup_plot(int p_idx, int p_level);
void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx);
- bool sorted;
+ bool sorted = false;
void _sort();
public:
diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp
index 3c12d4991e..214ffd6bd5 100644
--- a/scene/3d/world_environment.cpp
+++ b/scene/3d/world_environment.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,51 +35,69 @@
void WorldEnvironment::_notification(int p_what) {
if (p_what == Node3D::NOTIFICATION_ENTER_WORLD || p_what == Node3D::NOTIFICATION_ENTER_TREE) {
if (environment.is_valid()) {
- if (get_viewport()->find_world_3d()->get_environment().is_valid()) {
- WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
- }
- get_viewport()->find_world_3d()->set_environment(environment);
add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
+ _update_current_environment();
}
if (camera_effects.is_valid()) {
- if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) {
- WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding.");
- }
- get_viewport()->find_world_3d()->set_camera_effects(camera_effects);
add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
+ _update_current_camera_effects();
}
} else if (p_what == Node3D::NOTIFICATION_EXIT_WORLD || p_what == Node3D::NOTIFICATION_EXIT_TREE) {
- if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) {
- get_viewport()->find_world_3d()->set_environment(Ref<Environment>());
+ if (environment.is_valid()) {
remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
+ _update_current_environment();
}
- if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) {
- get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>());
+ if (camera_effects.is_valid()) {
remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
+ _update_current_camera_effects();
}
}
}
-void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) {
- if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) {
+void WorldEnvironment::_update_current_environment() {
+ WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())));
+
+ if (first) {
+ get_viewport()->find_world_3d()->set_environment(first->environment);
+ } else {
get_viewport()->find_world_3d()->set_environment(Ref<Environment>());
+ }
+ get_tree()->call_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warning");
+}
+
+void WorldEnvironment::_update_current_camera_effects() {
+ WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())));
+ if (first) {
+ get_viewport()->find_world_3d()->set_camera_effects(first->camera_effects);
+ } else {
+ get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>());
+ }
+
+ get_tree()->call_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warning");
+}
+
+void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) {
+ if (environment == p_environment) {
+ return;
+ }
+ if (is_inside_tree() && environment.is_valid()) {
remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
- //clean up
}
environment = p_environment;
+
if (is_inside_tree() && environment.is_valid()) {
- if (get_viewport()->find_world_3d()->get_environment().is_valid()) {
- WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
- }
- get_viewport()->find_world_3d()->set_environment(environment);
add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
- update_configuration_warning();
+ if (is_inside_tree()) {
+ _update_current_environment();
+ } else {
+ update_configuration_warning();
+ }
}
Ref<Environment> WorldEnvironment::get_environment() const {
@@ -87,22 +105,24 @@ Ref<Environment> WorldEnvironment::get_environment() const {
}
void WorldEnvironment::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) {
+ if (camera_effects == p_camera_effects) {
+ return;
+ }
+
if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) {
- get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>());
remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
- //clean up
}
camera_effects = p_camera_effects;
if (is_inside_tree() && camera_effects.is_valid()) {
- if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) {
- WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding.");
- }
- get_viewport()->find_world_3d()->set_camera_effects(camera_effects);
add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
- update_configuration_warning();
+ if (is_inside_tree()) {
+ _update_current_camera_effects();
+ } else {
+ update_configuration_warning();
+ }
}
Ref<CameraEffects> WorldEnvironment::get_camera_effects() const {
@@ -113,7 +133,7 @@ String WorldEnvironment::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!environment.is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect.");
@@ -123,14 +143,18 @@ String WorldEnvironment::get_configuration_warning() const {
return warning;
}
- List<Node *> nodes;
- get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), &nodes);
+ if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() != environment) {
+ if (!warning.is_empty()) {
+ warning += "\n\n";
+ }
+ warning += TTR("Only the first Environment has an effect in a scene (or set of instantiated scenes).");
+ }
- if (nodes.size() > 1) {
- if (!warning.empty()) {
+ if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() != camera_effects) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
- warning += TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes).");
+ warning += TTR("Only the first CameraEffects has an effect in a scene (or set of instantiated scenes).");
}
return warning;
diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h
index 3fd3dc0b50..e3f28d6d6b 100644
--- a/scene/3d/world_environment.h
+++ b/scene/3d/world_environment.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,6 +41,9 @@ class WorldEnvironment : public Node {
Ref<Environment> environment;
Ref<CameraEffects> camera_effects;
+ void _update_current_environment();
+ void _update_current_camera_effects();
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp
index 5d48795dc1..7fed34c7c6 100644
--- a/scene/3d/xr_nodes.cpp
+++ b/scene/3d/xr_nodes.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,7 +65,7 @@ String XRCamera3D::get_configuration_warning() const {
// must be child node of XROrigin3D!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("XRCamera3D must have an XROrigin3D node as its parent.");
@@ -91,9 +91,9 @@ Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const {
Vector2 cpos = get_viewport()->get_camera_coords(p_pos);
Vector3 ray;
- CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_near(), get_far());
Vector2 screen_he = cm.get_viewport_half_extents();
- ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_znear()).normalized();
+ ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_near()).normalized();
return ray;
};
@@ -113,7 +113,7 @@ Point2 XRCamera3D::unproject_position(const Vector3 &p_pos) const {
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_near(), get_far());
Plane p(get_camera_transform().xform_inv(p_pos), 1.0);
@@ -142,7 +142,7 @@ Vector3 XRCamera3D::project_position(const Point2 &p_point, float p_z_depth) con
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_near(), get_far());
Vector2 vp_he = cm.get_viewport_half_extents();
@@ -170,7 +170,7 @@ Vector<Plane> XRCamera3D::get_frustum() const {
ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>());
Size2 viewport_size = get_viewport()->get_visible_rect().size;
- CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
+ CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_near(), get_far());
return cm.get_projection_planes(get_camera_transform());
};
@@ -372,14 +372,14 @@ String XRController3D::get_configuration_warning() const {
// must be child node of XROrigin!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("XRController3D must have an XROrigin3D node as its parent.");
};
if (controller_id == 0) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The controller ID must not be 0 or this controller won't be bound to an actual controller.");
@@ -497,14 +497,14 @@ String XRAnchor3D::get_configuration_warning() const {
// must be child node of XROrigin3D!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
if (origin == nullptr) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("XRAnchor3D must have an XROrigin3D node as its parent.");
};
if (anchor_id == 0) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The anchor ID must not be 0 or this anchor won't be bound to an actual anchor.");
@@ -536,7 +536,7 @@ String XROrigin3D::get_configuration_warning() const {
String warning = Node3D::get_configuration_warning();
if (tracked_camera == nullptr) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("XROrigin3D requires an XRCamera3D child node.");
diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h
index 6aa7709485..7cd6e2ac57 100644
--- a/scene/3d/xr_nodes.h
+++ b/scene/3d/xr_nodes.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index e426e98def..15f562242f 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -311,14 +311,6 @@ AnimationNodeBlendSpace1D::AnimationNodeBlendSpace1D() {
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
blend_points[i].name = itos(i);
}
- blend_points_used = 0;
- max_space = 1;
- min_space = -1;
-
- snap = 0.1;
- value_label = "value";
-
- blend_position = "blend_position";
}
AnimationNodeBlendSpace1D::~AnimationNodeBlendSpace1D() {
diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h
index 816d3c9d4e..8886e6c679 100644
--- a/scene/animation/animation_blend_space_1d.h
+++ b/scene/animation/animation_blend_space_1d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,24 +43,24 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode {
struct BlendPoint {
StringName name;
Ref<AnimationRootNode> node;
- float position;
+ float position = 0.0;
};
BlendPoint blend_points[MAX_BLEND_POINTS];
- int blend_points_used;
+ int blend_points_used = 0;
- float max_space;
- float min_space;
+ float max_space = 1.0;
+ float min_space = -1.0;
- float snap;
+ float snap = 0.1;
- String value_label;
+ String value_label = "value";
void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node);
void _tree_changed();
- StringName blend_position;
+ StringName blend_position = "blend_position";
protected:
virtual void _validate_property(PropertyInfo &property) const override;
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index 5a42e2af7a..9c4bc107dd 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -437,7 +437,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
Vector2 blend_pos = get_parameter(blend_position);
int closest = get_parameter(this->closest);
float length_internal = get_parameter(this->length_internal);
- float mind = 0; //time of min distance point
+ float mind = 0.0; //time of min distance point
if (blend_mode == BLEND_MODE_INTERPOLATED) {
if (triangles.size() == 0) {
@@ -529,7 +529,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
}
if (new_closest != closest && new_closest != -1) {
- float from = 0;
+ float from = 0.0;
if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) {
//see how much animation remains
from = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, true, 0.0, FILTER_IGNORE, false) - length_internal;
@@ -665,18 +665,6 @@ AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() {
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
blend_points[i].name = itos(i);
}
- auto_triangles = true;
- blend_points_used = 0;
- max_space = Vector2(1, 1);
- min_space = Vector2(-1, -1);
- snap = Vector2(0.1, 0.1);
- x_label = "x";
- y_label = "y";
- trianges_dirty = false;
- blend_position = "blend_position";
- closest = "closest";
- length_internal = "length_internal";
- blend_mode = BLEND_MODE_INTERPOLATED;
}
AnimationNodeBlendSpace2D::~AnimationNodeBlendSpace2D() {
diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h
index 2aff678aad..65d09a550d 100644
--- a/scene/animation/animation_blend_space_2d.h
+++ b/scene/animation/animation_blend_space_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,23 +55,23 @@ protected:
};
BlendPoint blend_points[MAX_BLEND_POINTS];
- int blend_points_used;
+ int blend_points_used = 0;
struct BlendTriangle {
- int points[3];
+ int points[3] = {};
};
Vector<BlendTriangle> triangles;
- StringName blend_position;
- StringName closest;
- StringName length_internal;
- Vector2 max_space;
- Vector2 min_space;
- Vector2 snap;
- String x_label;
- String y_label;
- BlendMode blend_mode;
+ StringName blend_position = "blend_position";
+ StringName closest = "closest";
+ StringName length_internal = "length_internal";
+ Vector2 max_space = Vector2(1, 1);
+ Vector2 min_space = Vector2(-1, -1);
+ Vector2 snap = Vector2(0.1, 0.1);
+ String x_label = "x";
+ String y_label = "y";
+ BlendMode blend_mode = BLEND_MODE_INTERPOLATED;
void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node);
void _set_triangles(const Vector<int> &p_triangles);
@@ -79,8 +79,8 @@ protected:
void _blend_triangle(const Vector2 &p_pos, const Vector2 *p_points, float *r_weights);
- bool auto_triangles;
- bool trianges_dirty;
+ bool auto_triangles = true;
+ bool trianges_dirty = false;
void _update_triangles();
void _queue_auto_triangles();
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 56995c0c13..79a1dc1ac0 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,7 +34,6 @@
void AnimationNodeAnimation::set_animation(const StringName &p_name) {
animation = p_name;
- _change_notify("animation");
}
StringName AnimationNodeAnimation::get_animation() const {
@@ -125,9 +124,6 @@ void AnimationNodeAnimation::_bind_methods() {
}
AnimationNodeAnimation::AnimationNodeAnimation() {
- last_version = 0;
- skip = false;
- time = "time";
}
////////////////////////////////////////////////////////
@@ -346,21 +342,6 @@ void AnimationNodeOneShot::_bind_methods() {
AnimationNodeOneShot::AnimationNodeOneShot() {
add_input("in");
add_input("shot");
-
- fade_in = 0.1;
- fade_out = 0.1;
- autorestart = false;
- autorestart_delay = 1;
- autorestart_random_delay = 0;
-
- mix = MIX_MODE_BLEND;
- sync = false;
-
- active = "active";
- prev_active = "prev_active";
- time = "time";
- remaining = "remaining";
- time_to_restart = "time_to_restart";
}
////////////////////////////////////////////////
@@ -405,10 +386,8 @@ void AnimationNodeAdd2::_bind_methods() {
}
AnimationNodeAdd2::AnimationNodeAdd2() {
- add_amount = "add_amount";
add_input("in");
add_input("add");
- sync = false;
}
////////////////////////////////////////////////
@@ -454,11 +433,9 @@ void AnimationNodeAdd3::_bind_methods() {
}
AnimationNodeAdd3::AnimationNodeAdd3() {
- add_amount = "add_amount";
add_input("-add");
add_input("in");
add_input("+add");
- sync = false;
}
/////////////////////////////////////////////
@@ -504,10 +481,8 @@ void AnimationNodeBlend2::_bind_methods() {
}
AnimationNodeBlend2::AnimationNodeBlend2() {
- blend_amount = "blend_amount";
add_input("in");
add_input("blend");
- sync = false;
}
//////////////////////////////////////
@@ -583,7 +558,6 @@ void AnimationNodeTimeScale::_bind_methods() {
}
AnimationNodeTimeScale::AnimationNodeTimeScale() {
- scale = "scale";
add_input("in");
}
@@ -608,7 +582,6 @@ float AnimationNodeTimeSeek::process(float p_time, bool p_seek) {
} else if (seek_pos >= 0) {
float ret = blend_input(0, seek_pos, true, 1.0, FILTER_IGNORE, false);
set_parameter(this->seek_pos, -1.0); //reset
- _change_notify("seek_pos");
return ret;
} else {
return blend_input(0, p_time, false, 1.0, FILTER_IGNORE, false);
@@ -620,7 +593,6 @@ void AnimationNodeTimeSeek::_bind_methods() {
AnimationNodeTimeSeek::AnimationNodeTimeSeek() {
add_input("in");
- seek_pos = "seek_position";
}
/////////////////////////////////////////////////
@@ -728,7 +700,7 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
return 0;
}
- float rem = 0;
+ float rem = 0.0;
if (prev < 0) { // process current animation, check for transition
@@ -811,16 +783,7 @@ void AnimationNodeTransition::_bind_methods() {
}
AnimationNodeTransition::AnimationNodeTransition() {
- prev_xfading = "prev_xfading";
- prev = "prev";
- time = "time";
- current = "current";
- prev_current = "prev_current";
- xfade = 0.0;
-
- enabled_inputs = 0;
for (int i = 0; i < MAX_INPUTS; i++) {
- inputs[i].auto_advance = false;
inputs[i].name = "state " + itos(i);
}
}
@@ -1158,6 +1121,13 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons
p_list->push_back(PropertyInfo(Variant::ARRAY, "node_connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
+void AnimationNodeBlendTree::reset_state() {
+ graph_offset = Vector2();
+ nodes.clear();
+ emit_changed();
+ emit_signal("tree_changed");
+}
+
void AnimationNodeBlendTree::_tree_changed() {
emit_signal("tree_changed");
}
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 7241a6bc13..d82658c8c2 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,10 +37,10 @@ class AnimationNodeAnimation : public AnimationRootNode {
GDCLASS(AnimationNodeAnimation, AnimationRootNode);
StringName animation;
- StringName time;
+ StringName time = "time";
- uint64_t last_version;
- bool skip;
+ uint64_t last_version = 0;
+ bool skip = false;
protected:
void _validate_property(PropertyInfo &property) const override;
@@ -71,26 +71,26 @@ public:
};
private:
- float fade_in;
- float fade_out;
+ float fade_in = 0.1;
+ float fade_out = 0.1;
- bool autorestart;
- float autorestart_delay;
- float autorestart_random_delay;
- MixMode mix;
+ bool autorestart = false;
+ float autorestart_delay = 1.0;
+ float autorestart_random_delay = 0.0;
+ MixMode mix = MIX_MODE_BLEND;
- bool sync;
+ bool sync = false;
/* bool active;
bool do_start;
float time;
float remaining;*/
- StringName active;
- StringName prev_active;
- StringName time;
- StringName remaining;
- StringName time_to_restart;
+ StringName active = "active";
+ StringName prev_active = "prev_active";
+ StringName time = "time";
+ StringName remaining = "remaining";
+ StringName time_to_restart = "time_to_restart";
protected:
static void _bind_methods();
@@ -132,8 +132,8 @@ VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode)
class AnimationNodeAdd2 : public AnimationNode {
GDCLASS(AnimationNodeAdd2, AnimationNode);
- StringName add_amount;
- bool sync;
+ StringName add_amount = "add_amount";
+ bool sync = false;
protected:
static void _bind_methods();
@@ -156,8 +156,8 @@ public:
class AnimationNodeAdd3 : public AnimationNode {
GDCLASS(AnimationNodeAdd3, AnimationNode);
- StringName add_amount;
- bool sync;
+ StringName add_amount = "add_amount";
+ bool sync = false;
protected:
static void _bind_methods();
@@ -180,8 +180,8 @@ public:
class AnimationNodeBlend2 : public AnimationNode {
GDCLASS(AnimationNodeBlend2, AnimationNode);
- StringName blend_amount;
- bool sync;
+ StringName blend_amount = "blend_amount";
+ bool sync = false;
protected:
static void _bind_methods();
@@ -225,7 +225,7 @@ public:
class AnimationNodeTimeScale : public AnimationNode {
GDCLASS(AnimationNodeTimeScale, AnimationNode);
- StringName scale;
+ StringName scale = "scale";
protected:
static void _bind_methods();
@@ -244,7 +244,7 @@ public:
class AnimationNodeTimeSeek : public AnimationNode {
GDCLASS(AnimationNodeTimeSeek, AnimationNode);
- StringName seek_pos;
+ StringName seek_pos = "seek_position";
protected:
static void _bind_methods();
@@ -268,12 +268,11 @@ class AnimationNodeTransition : public AnimationNode {
};
struct InputData {
String name;
- bool auto_advance;
- InputData() { auto_advance = false; }
+ bool auto_advance = false;
};
InputData inputs[MAX_INPUTS];
- int enabled_inputs;
+ int enabled_inputs = 0;
/*
float prev_xfading;
@@ -282,13 +281,13 @@ class AnimationNodeTransition : public AnimationNode {
int current;
int prev_current; */
- StringName prev_xfading;
- StringName prev;
- StringName time;
- StringName current;
- StringName prev_current;
+ StringName prev_xfading = "prev_xfading";
+ StringName prev = "prev";
+ StringName time = "time";
+ StringName current = "current";
+ StringName prev_current = "prev_current";
- float xfade;
+ float xfade = 0.0;
void _update_inputs();
@@ -352,6 +351,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
+
public:
enum ConnectionError {
CONNECTION_OK,
@@ -381,7 +382,7 @@ public:
struct NodeConnection {
StringName input_node;
- int input_index;
+ int input_index = 0;
StringName output_node;
};
diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp
index abb2cf1b65..689acdd57b 100644
--- a/scene/animation/animation_cache.cpp
+++ b/scene/animation/animation_cache.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -308,7 +308,4 @@ void AnimationCache::set_root(Node *p_root) {
}
AnimationCache::AnimationCache() {
- root = nullptr;
- cache_dirty = true;
- cache_valid = false;
}
diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h
index feff1d364a..07c9d09ae0 100644
--- a/scene/animation/animation_cache.h
+++ b/scene/animation/animation_cache.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,31 +39,23 @@ class AnimationCache : public Object {
struct Path {
RES resource;
- Object *object;
- Skeleton3D *skeleton; // haxor
- Node *node;
- Node3D *spatial;
+ Object *object = nullptr;
+ Skeleton3D *skeleton = nullptr; // haxor
+ Node *node = nullptr;
+ Node3D *spatial = nullptr;
- int bone_idx;
+ int bone_idx = -1;
Vector<StringName> subpath;
- bool valid;
- Path() {
- object = nullptr;
- skeleton = nullptr;
- node = nullptr;
- bone_idx = -1;
- valid = false;
- spatial = nullptr;
- }
+ bool valid = false;
};
Set<Node *> connected_nodes;
Vector<Path> path_cache;
- Node *root;
+ Node *root = nullptr;
Ref<Animation> animation;
- bool cache_dirty;
- bool cache_valid;
+ bool cache_dirty = true;
+ bool cache_valid = false;
void _node_exit_tree(Node *p_node);
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 36552c966d..d46f24752e 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -130,11 +130,6 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
}
AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {
- switch_mode = SWITCH_MODE_IMMEDIATE;
- auto_advance = false;
- xfade = 0;
- disabled = false;
- priority = 1;
}
////////////////////////////////////////////////////////
@@ -322,7 +317,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
// stopped, invalid state
String node_name = start_request;
start_request = StringName(); //clear start request
- ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing.");
+ ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing. Maybe you need to enable Autoplay on Load for one of the nodes in your state machine or call .start() first?");
}
} else {
if (!_travel(p_state_machine, start_request)) {
@@ -398,7 +393,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
//find next
StringName next;
- float next_xfade = 0;
+ float next_xfade = 0.0;
AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE;
if (path.size()) {
@@ -495,21 +490,13 @@ void AnimationNodeStateMachinePlayback::_bind_methods() {
ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachinePlayback::stop);
ClassDB::bind_method(D_METHOD("is_playing"), &AnimationNodeStateMachinePlayback::is_playing);
ClassDB::bind_method(D_METHOD("get_current_node"), &AnimationNodeStateMachinePlayback::get_current_node);
+ ClassDB::bind_method(D_METHOD("get_current_play_position"), &AnimationNodeStateMachinePlayback::get_current_play_pos);
+ ClassDB::bind_method(D_METHOD("get_current_length"), &AnimationNodeStateMachinePlayback::get_current_length);
ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachinePlayback::get_travel_path);
}
AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() {
set_local_to_scene(true); //only one per instanced scene
-
- playing = false;
- len_current = 0;
- fading_time = 0;
- stop_request = false;
- len_total = 0.0;
- pos_current = 0.0;
- loops_current = 0;
- fading_pos = 0.0;
- start_request_travel = false;
}
///////////////////////////////////////////////////////
@@ -927,6 +914,18 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c
p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
+void AnimationNodeStateMachine::reset_state() {
+ states.clear();
+ transitions.clear();
+ playback = "playback";
+ start_node = StringName();
+ end_node = StringName();
+ graph_offset = Vector2();
+
+ emit_changed();
+ emit_signal("tree_changed");
+}
+
void AnimationNodeStateMachine::set_node_position(const StringName &p_name, const Vector2 &p_position) {
ERR_FAIL_COND(!states.has(p_name));
states[p_name].position = p_position;
@@ -973,5 +972,4 @@ void AnimationNodeStateMachine::_bind_methods() {
}
AnimationNodeStateMachine::AnimationNodeStateMachine() {
- playback = "playback";
}
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index ae8975e940..9c1bca63c3 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,13 +44,13 @@ public:
};
private:
- SwitchMode switch_mode;
- bool auto_advance;
+ SwitchMode switch_mode = SWITCH_MODE_IMMEDIATE;
+ bool auto_advance = false;
StringName advance_condition;
StringName advance_condition_name;
- float xfade;
- bool disabled;
- int priority;
+ float xfade = 0.0;
+ bool disabled = false;
+ int priority = 1;
protected:
static void _bind_methods();
@@ -89,28 +89,28 @@ class AnimationNodeStateMachinePlayback : public Resource {
friend class AnimationNodeStateMachine;
struct AStarCost {
- float distance;
+ float distance = 0.0;
StringName prev;
};
- float len_total;
+ float len_total = 0.0;
- float len_current;
- float pos_current;
- int loops_current;
+ float len_current = 0.0;
+ float pos_current = 0.0;
+ int loops_current = 0;
StringName current;
StringName fading_from;
- float fading_time;
- float fading_pos;
+ float fading_time = 0.0;
+ float fading_pos = 0.0;
Vector<StringName> path;
- bool playing;
+ bool playing = false;
StringName start_request;
- bool start_request_travel;
- bool stop_request;
+ bool start_request_travel = false;
+ bool stop_request = false;
bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel);
@@ -154,7 +154,7 @@ private:
Vector<Transition> transitions;
- StringName playback;
+ StringName playback = "playback";
StringName start_node;
StringName end_node;
@@ -171,6 +171,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
+
public:
virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 159ccae130..2c19307c52 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -206,7 +206,7 @@ void AnimationPlayer::_notification(int p_what) {
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
- if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) {
+ if (process_callback == ANIMATION_PROCESS_PHYSICS) {
break;
}
@@ -215,7 +215,7 @@ void AnimationPlayer::_notification(int p_what) {
}
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- if (animation_process_mode == ANIMATION_PROCESS_IDLE) {
+ if (process_callback == ANIMATION_PROCESS_IDLE) {
break;
}
@@ -229,13 +229,13 @@ void AnimationPlayer::_notification(int p_what) {
}
}
-void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
+void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_override) {
// Already cached?
if (p_anim->node_cache.size() == p_anim->animation->get_track_count()) {
return;
}
- Node *parent = get_node(root);
+ Node *parent = p_root_override ? p_root_override : get_node(root);
ERR_FAIL_COND(!parent);
@@ -782,13 +782,13 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
delta = next_pos - cd.pos; // Fix delta (after determination of backwards because negative zero is lost here)
if (&cd == &playback.current) {
- if (!backwards && cd.pos <= len && next_pos == len /*&& playback.blend.empty()*/) {
+ if (!backwards && cd.pos <= len && next_pos == len) {
//playback finished
end_reached = true;
end_notify = cd.pos < len; // Notify only if not already at the end
}
- if (backwards && cd.pos >= 0 && next_pos == 0 /*&& playback.blend.empty()*/) {
+ if (backwards && cd.pos >= 0 && next_pos == 0) {
//playback finished
end_reached = true;
end_notify = cd.pos > 0; // Notify only if not already at the beginning
@@ -969,7 +969,7 @@ Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animati
}
_ref_anim(p_animation);
- _change_notify();
+ notify_property_list_changed();
return OK;
}
@@ -981,7 +981,7 @@ void AnimationPlayer::remove_animation(const StringName &p_name) {
animation_set.erase(p_name);
clear_caches();
- _change_notify();
+ notify_property_list_changed();
}
void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) {
@@ -1039,7 +1039,7 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
}
clear_caches();
- _change_notify();
+ notify_property_list_changed();
}
bool AnimationPlayer::has_animation(const StringName &p_name) const {
@@ -1132,7 +1132,7 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
Playback &c = playback;
if (c.current.from) {
- float blend_time = 0;
+ float blend_time = 0.0;
// find if it can blend
BlendKey bk;
bk.from = c.current.from->name;
@@ -1403,8 +1403,8 @@ bool AnimationPlayer::is_reset_on_save_enabled() const {
return reset_on_save;
}
-void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
- if (animation_process_mode == p_mode) {
+void AnimationPlayer::set_process_callback(AnimationProcessCallback p_mode) {
+ if (process_callback == p_mode) {
return;
}
@@ -1412,14 +1412,14 @@ void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
if (pr) {
_set_process(false);
}
- animation_process_mode = p_mode;
+ process_callback = p_mode;
if (pr) {
_set_process(true);
}
}
-AnimationPlayer::AnimationProcessMode AnimationPlayer::get_animation_process_mode() const {
- return animation_process_mode;
+AnimationPlayer::AnimationProcessCallback AnimationPlayer::get_process_callback() const {
+ return process_callback;
}
void AnimationPlayer::set_method_call_mode(AnimationMethodCallMode p_mode) {
@@ -1435,7 +1435,7 @@ void AnimationPlayer::_set_process(bool p_process, bool p_force) {
return;
}
- switch (animation_process_mode) {
+ switch (process_callback) {
case ANIMATION_PROCESS_PHYSICS:
set_physics_process_internal(p_process && active);
break;
@@ -1497,13 +1497,13 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i
}
#ifdef TOOLS_ENABLED
-Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values() {
+Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_override) {
Ref<AnimatedValuesBackup> backup;
if (!playback.current.from) {
return backup;
}
- _ensure_node_caches(playback.current.from);
+ _ensure_node_caches(playback.current.from, p_root_override);
backup.instance();
for (int i = 0; i < playback.current.from->node_cache.size(); i++) {
@@ -1560,10 +1560,11 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) {
AnimationPlayer *aux_player = memnew(AnimationPlayer);
EditorNode::get_singleton()->add_child(aux_player);
- aux_player->set_root(aux_player->get_path_to(root_node));
aux_player->add_animation("RESET", reset_anim);
aux_player->set_assigned_animation("RESET");
- Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values();
+ // Forcing the use of the original root because the scene where original player belongs may be not the active one
+ Node *root = get_node(get_root());
+ Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(root);
aux_player->seek(0.0f, true);
aux_player->queue_delete();
@@ -1636,8 +1637,8 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_caches"), &AnimationPlayer::clear_caches);
- ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationPlayer::set_animation_process_mode);
- ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationPlayer::get_animation_process_mode);
+ ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationPlayer::set_process_callback);
+ ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationPlayer::get_process_callback);
ClassDB::bind_method(D_METHOD("set_method_call_mode", "mode"), &AnimationPlayer::set_method_call_mode);
ClassDB::bind_method(D_METHOD("get_method_call_mode"), &AnimationPlayer::get_method_call_mode);
@@ -1657,7 +1658,7 @@ void AnimationPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position");
ADD_GROUP("Playback Options", "playback_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_animation_process_mode", "get_animation_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playback_active", PROPERTY_HINT_NONE, "", 0), "set_active", "is_active");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale");
@@ -1677,23 +1678,7 @@ void AnimationPlayer::_bind_methods() {
}
AnimationPlayer::AnimationPlayer() {
- accum_pass = 1;
- cache_update_size = 0;
- cache_update_prop_size = 0;
- cache_update_bezier_size = 0;
- speed_scale = 1;
- end_reached = false;
- end_notify = false;
- reset_on_save = true;
- animation_process_mode = ANIMATION_PROCESS_IDLE;
- method_call_mode = ANIMATION_METHOD_CALL_DEFERRED;
- processing = false;
- default_blend_time = 0;
root = SceneStringNames::get_singleton()->path_pp;
- playing = false;
- active = true;
- playback.seeked = false;
- playback.started = false;
}
AnimationPlayer::~AnimationPlayer() {
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 7f0d5630e1..2a1821c215 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,9 +41,9 @@ class AnimatedValuesBackup : public Reference {
GDCLASS(AnimatedValuesBackup, Reference);
struct Entry {
- Object *object;
+ Object *object = nullptr;
Vector<StringName> subpath; // Unused if bone
- int bone_idx; // -1 if not a bone
+ int bone_idx = -1; // -1 if not a bone
Variant value;
};
Vector<Entry> entries;
@@ -64,7 +64,7 @@ class AnimationPlayer : public Node {
OBJ_CATEGORY("Animation Nodes");
public:
- enum AnimationProcessMode {
+ enum AnimationProcessCallback {
ANIMATION_PROCESS_PHYSICS,
ANIMATION_PROCESS_IDLE,
ANIMATION_PROCESS_MANUAL,
@@ -118,8 +118,6 @@ private:
Variant value_accum;
uint64_t accum_pass = 0;
Variant capture;
-
- PropertyAnim() {}
};
Map<StringName, PropertyAnim> property_anim;
@@ -130,8 +128,6 @@ private:
float bezier_accum = 0.0;
Object *object = nullptr;
uint64_t accum_pass = 0;
-
- BezierAnim() {}
};
Map<StringName, BezierAnim> bezier_anim;
@@ -141,7 +137,7 @@ private:
struct TrackNodeCacheKey {
ObjectID id;
- int bone_idx;
+ int bone_idx = -1;
inline bool operator<(const TrackNodeCacheKey &p_right) const {
if (id == p_right.id) {
@@ -155,16 +151,16 @@ private:
Map<TrackNodeCacheKey, TrackNodeCache> node_cache_map;
TrackNodeCache *cache_update[NODE_CACHE_UPDATE_MAX];
- int cache_update_size;
+ int cache_update_size = 0;
TrackNodeCache::PropertyAnim *cache_update_prop[NODE_CACHE_UPDATE_MAX];
- int cache_update_prop_size;
+ int cache_update_prop_size = 0;
TrackNodeCache::BezierAnim *cache_update_bezier[NODE_CACHE_UPDATE_MAX];
- int cache_update_bezier_size;
+ int cache_update_bezier_size = 0;
Set<TrackNodeCache *> playing_caches;
- uint64_t accum_pass;
- float speed_scale;
- float default_blend_time;
+ uint64_t accum_pass = 1;
+ float speed_scale = 1.0;
+ float default_blend_time = 0.0;
struct AnimationData {
String name;
@@ -183,54 +179,43 @@ private:
Map<BlendKey, float> blend_times;
struct PlaybackData {
- AnimationData *from;
- float pos;
- float speed_scale;
-
- PlaybackData() {
- pos = 0;
- speed_scale = 1.0;
- from = nullptr;
- }
+ AnimationData *from = nullptr;
+ float pos = 0.0;
+ float speed_scale = 1.0;
};
struct Blend {
PlaybackData data;
- float blend_time;
- float blend_left;
-
- Blend() {
- blend_left = 0;
- blend_time = 0;
- }
+ float blend_time = 0.0;
+ float blend_left = 0.0;
};
struct Playback {
List<Blend> blend;
PlaybackData current;
StringName assigned;
- bool seeked;
- bool started;
+ bool seeked = false;
+ bool started = false;
} playback;
List<StringName> queued;
- bool end_reached;
- bool end_notify;
+ bool end_reached = false;
+ bool end_notify = false;
String autoplay;
- bool reset_on_save;
- AnimationProcessMode animation_process_mode;
- AnimationMethodCallMode method_call_mode;
- bool processing;
- bool active;
+ bool reset_on_save = true;
+ AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE;
+ AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED;
+ bool processing = false;
+ bool active = true;
NodePath root;
void _animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_is_current = true, bool p_seeked = false, bool p_started = false);
- void _ensure_node_caches(AnimationData *p_anim);
+ void _ensure_node_caches(AnimationData *p_anim, Node *p_root_override = nullptr);
void _animation_process_data(PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, bool p_started);
void _animation_process2(float p_delta, bool p_started);
void _animation_update_transforms();
@@ -257,7 +242,7 @@ private:
void _set_process(bool p_process, bool p_force = false);
- bool playing;
+ bool playing = false;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
@@ -313,8 +298,8 @@ public:
void set_reset_on_save_enabled(bool p_enabled);
bool is_reset_on_save_enabled() const;
- void set_animation_process_mode(AnimationProcessMode p_mode);
- AnimationProcessMode get_animation_process_mode() const;
+ void set_process_callback(AnimationProcessCallback p_mode);
+ AnimationProcessCallback get_process_callback() const;
void set_method_call_mode(AnimationMethodCallMode p_mode);
AnimationMethodCallMode get_method_call_mode() const;
@@ -334,7 +319,7 @@ public:
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
#ifdef TOOLS_ENABLED
- Ref<AnimatedValuesBackup> backup_animated_values();
+ Ref<AnimatedValuesBackup> backup_animated_values(Node *p_root_override = nullptr);
Ref<AnimatedValuesBackup> apply_reset(bool p_user_initiated = false);
bool can_apply_reset() const;
#endif
@@ -343,7 +328,7 @@ public:
~AnimationPlayer();
};
-VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessMode);
+VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessCallback);
VARIANT_ENUM_CAST(AnimationPlayer::AnimationMethodCallMode);
#endif
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 2ef3ba87b2..26a13f33c9 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,7 +40,7 @@ void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
Array parameters = get_script_instance()->call("get_parameter_list");
for (int i = 0; i < parameters.size(); i++) {
Dictionary d = parameters[i];
- ERR_CONTINUE(d.empty());
+ ERR_CONTINUE(d.is_empty());
r_list->push_back(PropertyInfo::from_dict(d));
}
}
@@ -158,7 +158,7 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p
Ref<AnimationNode> node = blend_tree->get_node(node_name);
//inputs.write[p_input].last_pass = state->last_pass;
- float activity = 0;
+ float activity = 0.0;
float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
@@ -441,9 +441,6 @@ void AnimationNode::_bind_methods() {
}
AnimationNode::AnimationNode() {
- state = nullptr;
- parent = nullptr;
- filter_enabled = false;
}
////////////////////
@@ -476,7 +473,7 @@ void AnimationTree::set_active(bool p_active) {
active = p_active;
started = active;
- if (process_mode == ANIMATION_PROCESS_IDLE) {
+ if (process_callback == ANIMATION_PROCESS_IDLE) {
set_process_internal(active);
} else {
set_physics_process_internal(active);
@@ -497,8 +494,8 @@ bool AnimationTree::is_active() const {
return active;
}
-void AnimationTree::set_process_mode(AnimationProcessMode p_mode) {
- if (process_mode == p_mode) {
+void AnimationTree::set_process_callback(AnimationProcessCallback p_mode) {
+ if (process_callback == p_mode) {
return;
}
@@ -507,15 +504,15 @@ void AnimationTree::set_process_mode(AnimationProcessMode p_mode) {
set_active(false);
}
- process_mode = p_mode;
+ process_callback = p_mode;
if (was_active) {
set_active(true);
}
}
-AnimationTree::AnimationProcessMode AnimationTree::get_process_mode() const {
- return process_mode;
+AnimationTree::AnimationProcessCallback AnimationTree::get_process_callback() const {
+ return process_callback;
}
void AnimationTree::_node_removed(Node *p_node) {
@@ -820,6 +817,7 @@ void AnimationTree::_process_graph(float p_delta) {
Ref<Animation> a = as.animation;
float time = as.time;
float delta = as.delta;
+ float weight = as.blend;
bool seeked = as.seeked;
for (int i = 0; i < a->get_track_count(); i++) {
@@ -839,7 +837,7 @@ void AnimationTree::_process_graph(float p_delta) {
ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count);
- float blend = (*as.track_blends)[blend_idx];
+ float blend = (*as.track_blends)[blend_idx] * weight;
if (blend < CMP_EPSILON) {
continue; //nothing to blend
@@ -1236,11 +1234,11 @@ void AnimationTree::advance(float p_time) {
}
void AnimationTree::_notification(int p_what) {
- if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) {
+ if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_callback == ANIMATION_PROCESS_PHYSICS) {
_process_graph(get_physics_process_delta_time());
}
- if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_mode == ANIMATION_PROCESS_IDLE) {
+ if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_callback == ANIMATION_PROCESS_IDLE) {
_process_graph(get_process_delta_time());
}
@@ -1287,14 +1285,14 @@ String AnimationTree::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!root.is_valid()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("No root AnimationNode for the graph is set.");
}
if (!has_node(animation_player)) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Path to an AnimationPlayer node containing animations is not set.");
@@ -1302,12 +1300,12 @@ String AnimationTree::get_configuration_warning() const {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
if (!player) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Path set for AnimationPlayer does not lead to an AnimationPlayer node.");
} else if (!player->has_node(player->get_root())) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The AnimationPlayer root node is not a valid node.");
@@ -1396,7 +1394,7 @@ void AnimationTree::_update_properties() {
properties_dirty = false;
- _change_notify();
+ notify_property_list_changed();
}
bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) {
@@ -1406,9 +1404,6 @@ bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) {
if (property_map.has(p_name)) {
property_map[p_name] = p_value;
-#ifdef TOOLS_ENABLED
- _change_notify(p_name.operator String().utf8().get_data());
-#endif
return true;
}
@@ -1476,8 +1471,8 @@ void AnimationTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tree_root", "root"), &AnimationTree::set_tree_root);
ClassDB::bind_method(D_METHOD("get_tree_root"), &AnimationTree::get_tree_root);
- ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &AnimationTree::set_process_mode);
- ClassDB::bind_method(D_METHOD("get_process_mode"), &AnimationTree::get_process_mode);
+ ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationTree::set_process_callback);
+ ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationTree::get_process_callback);
ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationTree::set_animation_player);
ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationTree::get_animation_player);
@@ -1496,7 +1491,7 @@ void AnimationTree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_mode", "get_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback");
ADD_GROUP("Root Motion", "root_motion_");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_motion_track"), "set_root_motion_track", "get_root_motion_track");
@@ -1506,13 +1501,6 @@ void AnimationTree::_bind_methods() {
}
AnimationTree::AnimationTree() {
- process_mode = ANIMATION_PROCESS_IDLE;
- active = false;
- cache_valid = false;
- setup_pass = 1;
- process_pass = 1;
- started = true;
- properties_dirty = true;
}
AnimationTree::~AnimationTree() {
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 166ca04f40..1c5aec26ab 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,26 +63,26 @@ public:
struct AnimationState {
Ref<Animation> animation;
- float time;
- float delta;
- const Vector<float> *track_blends;
- float blend;
- bool seeked;
+ float time = 0.0;
+ float delta = 0.0;
+ const Vector<float> *track_blends = nullptr;
+ float blend = 0.0;
+ bool seeked = false;
};
struct State {
- int track_count;
+ int track_count = 0;
HashMap<NodePath, int> track_map;
List<AnimationState> animation_states;
- bool valid;
- AnimationPlayer *player;
- AnimationTree *tree;
+ bool valid = false;
+ AnimationPlayer *player = nullptr;
+ AnimationTree *tree = nullptr;
String invalid_reasons;
- uint64_t last_pass;
+ uint64_t last_pass = 0;
};
Vector<float> blends;
- State *state;
+ State *state = nullptr;
float _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections);
void _pre_update_animations(HashMap<NodePath, int> *track_map);
@@ -90,10 +90,10 @@ public:
//all this is temporary
StringName base_path;
Vector<StringName> connections;
- AnimationNode *parent;
+ AnimationNode *parent = nullptr;
HashMap<NodePath, bool> filter;
- bool filter_enabled;
+ bool filter_enabled = false;
Array _get_filters() const;
void _set_filters(const Array &p_filters);
@@ -163,7 +163,7 @@ class AnimationTree : public Node {
GDCLASS(AnimationTree, Node);
public:
- enum AnimationProcessMode {
+ enum AnimationProcessCallback {
ANIMATION_PROCESS_PHYSICS,
ANIMATION_PROCESS_IDLE,
ANIMATION_PROCESS_MANUAL,
@@ -171,36 +171,29 @@ public:
private:
struct TrackCache {
- bool root_motion;
- uint64_t setup_pass;
- uint64_t process_pass;
- Animation::TrackType type;
- Object *object;
+ bool root_motion = false;
+ uint64_t setup_pass = 0;
+ uint64_t process_pass = 0;
+ Animation::TrackType type = Animation::TrackType::TYPE_ANIMATION;
+ Object *object = nullptr;
ObjectID object_id;
TrackCache() {
- root_motion = false;
- setup_pass = 0;
- process_pass = 0;
- object = nullptr;
}
virtual ~TrackCache() {}
};
struct TrackCacheTransform : public TrackCache {
- Node3D *spatial;
- Skeleton3D *skeleton;
- int bone_idx;
+ Node3D *spatial = nullptr;
+ Skeleton3D *skeleton = nullptr;
+ int bone_idx = -1;
Vector3 loc;
Quat rot;
- float rot_blend_accum;
+ float rot_blend_accum = 0.0;
Vector3 scale;
TrackCacheTransform() {
type = Animation::TYPE_TRANSFORM;
- spatial = nullptr;
- bone_idx = -1;
- skeleton = nullptr;
}
};
@@ -215,33 +208,28 @@ private:
};
struct TrackCacheBezier : public TrackCache {
- float value;
+ float value = 0.0;
Vector<StringName> subpath;
TrackCacheBezier() {
type = Animation::TYPE_BEZIER;
- value = 0;
}
};
struct TrackCacheAudio : public TrackCache {
- bool playing;
- float start;
- float len;
+ bool playing = false;
+ float start = 0.0;
+ float len = 0.0;
TrackCacheAudio() {
type = Animation::TYPE_AUDIO;
- playing = false;
- start = 0;
- len = 0;
}
};
struct TrackCacheAnimation : public TrackCache {
- bool playing;
+ bool playing = false;
TrackCacheAnimation() {
type = Animation::TYPE_ANIMATION;
- playing = false;
}
};
@@ -250,12 +238,12 @@ private:
Ref<AnimationNode> root;
- AnimationProcessMode process_mode;
- bool active;
+ AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE;
+ bool active = false;
NodePath animation_player;
AnimationNode::State state;
- bool cache_valid;
+ bool cache_valid = false;
void _node_removed(Node *p_node);
void _caches_cleared();
@@ -263,16 +251,16 @@ private:
bool _update_caches(AnimationPlayer *player);
void _process_graph(float p_delta);
- uint64_t setup_pass;
- uint64_t process_pass;
+ uint64_t setup_pass = 1;
+ uint64_t process_pass = 1;
- bool started;
+ bool started = true;
NodePath root_motion_track;
Transform root_motion_transform;
friend class AnimationNode;
- bool properties_dirty;
+ bool properties_dirty = true;
void _tree_changed();
void _update_properties();
List<PropertyInfo> properties;
@@ -280,8 +268,8 @@ private:
HashMap<StringName, Variant> property_map;
struct Activity {
- uint64_t last_pass;
- float activity;
+ uint64_t last_pass = 0;
+ float activity = 0.0;
};
HashMap<StringName, Vector<Activity>> input_activity_map;
@@ -306,8 +294,8 @@ public:
void set_active(bool p_active);
bool is_active() const;
- void set_process_mode(AnimationProcessMode p_mode);
- AnimationProcessMode get_process_mode() const;
+ void set_process_callback(AnimationProcessCallback p_mode);
+ AnimationProcessCallback get_process_callback() const;
void set_animation_player(const NodePath &p_player);
NodePath get_animation_player() const;
@@ -332,6 +320,6 @@ public:
~AnimationTree();
};
-VARIANT_ENUM_CAST(AnimationTree::AnimationProcessMode)
+VARIANT_ENUM_CAST(AnimationTree::AnimationProcessCallback)
#endif // ANIMATION_GRAPH_PLAYER_H
diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp
index cbf2e4a6ff..9ee1f32581 100644
--- a/scene/animation/root_motion_view.cpp
+++ b/scene/animation/root_motion_view.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -89,12 +89,12 @@ void RootMotionView::_notification(int p_what) {
AnimationTree *tree = Object::cast_to<AnimationTree>(node);
if (tree && tree->is_active() && tree->get_root_motion_track() != NodePath()) {
- if (is_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_PHYSICS) {
+ if (is_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_PHYSICS) {
set_process_internal(false);
set_physics_process_internal(true);
}
- if (is_physics_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_IDLE) {
+ if (is_physics_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_IDLE) {
set_process_internal(true);
set_physics_process_internal(false);
}
@@ -188,13 +188,9 @@ void RootMotionView::_bind_methods() {
}
RootMotionView::RootMotionView() {
- zero_y = true;
- radius = 10;
- cell_size = 1;
set_process_internal(true);
immediate = RenderingServer::get_singleton()->immediate_create();
set_base(immediate);
- color = Color(0.5, 0.5, 1.0);
}
RootMotionView::~RootMotionView() {
diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h
index 77c51fe47a..afcff6137f 100644
--- a/scene/animation/root_motion_view.h
+++ b/scene/animation/root_motion_view.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,12 +39,12 @@ class RootMotionView : public VisualInstance3D {
public:
RID immediate;
NodePath path;
- float cell_size;
- float radius;
- bool use_in_game;
- Color color;
- bool first;
- bool zero_y;
+ float cell_size = 1.0;
+ float radius = 10.0;
+ bool use_in_game = false;
+ Color color = Color(0.5, 0.5, 1.0);
+ bool first = true;
+ bool zero_y = true;
Transform accumulated;
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 1a2a97ada8..eb35979a47 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -869,8 +869,21 @@ void Tween::start() {
return;
}
+ pending_update++;
+ for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
+ InterpolateData &data = E->get();
+ data.active = true;
+ }
+ pending_update--;
+
// We want to be activated
set_active(true);
+
+ // Don't resume from current position if stop_all() function has been used
+ if (was_stopped) {
+ seek(0);
+ }
+ was_stopped = false;
}
void Tween::reset(Object *p_object, StringName p_key) {
@@ -939,7 +952,7 @@ void Tween::stop(Object *p_object, StringName p_key) {
void Tween::stop_all() {
// We no longer need to be active since all tweens have been stopped
set_active(false);
-
+ was_stopped = true;
// For each interpolation...
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -1098,7 +1111,7 @@ void Tween::seek(real_t p_time) {
real_t Tween::tell() const {
// We want to grab the position of the furthest along tween
pending_update++;
- real_t pos = 0;
+ real_t pos = 0.0;
// For each interpolation...
for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -1122,7 +1135,7 @@ real_t Tween::get_runtime() const {
pending_update++;
// For each interpolation...
- real_t runtime = 0;
+ real_t runtime = 0.0;
for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
// Get the tween data and see if it's runtime is greater than the previous tweens
const InterpolateData &data = E->get();
@@ -1350,6 +1363,9 @@ void Tween::interpolate_property(Object *p_object, NodePath p_property, Variant
return;
}
+ // Check that the target object is valid
+ ERR_FAIL_COND_MSG(p_object == nullptr, vformat("The Tween \"%s\"'s target node is `null`. Is the node reference correct?", get_name()));
+
// Get the property from the node path
p_property = p_property.get_as_property_path();
@@ -1378,6 +1394,9 @@ void Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_
return;
}
+ // Check that the target object is valid
+ ERR_FAIL_COND_MSG(p_object == nullptr, vformat("The Tween \"%s\"'s target node is `null`. Is the node reference correct?", get_name()));
+
// Convert any integers into REALs as they are better for interpolation
if (p_initial_val.get_type() == Variant::INT) {
p_initial_val = p_initial_val.operator real_t();
@@ -1789,12 +1808,6 @@ void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
}
Tween::Tween() {
- // Initialize tween attributes
- tween_process_mode = TWEEN_PROCESS_IDLE;
- repeat = false;
- speed_scale = 1;
- pending_update = 0;
- uid = 0;
}
Tween::~Tween() {
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index 822fcf0b6f..142c0c65e0 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -79,11 +79,11 @@ private:
};
struct InterpolateData {
- bool active;
- InterpolateType type;
- bool finish;
- bool call_deferred;
- real_t elapsed;
+ bool active = false;
+ InterpolateType type = INTER_CALLBACK;
+ bool finish = false;
+ bool call_deferred = false;
+ real_t elapsed = 0.0;
ObjectID id;
Vector<StringName> key;
StringName concatenated_key;
@@ -92,33 +92,28 @@ private:
Variant final_val;
ObjectID target_id;
Vector<StringName> target_key;
- real_t duration;
- TransitionType trans_type;
- EaseType ease_type;
- real_t delay;
- int args;
+ real_t duration = 0.0;
+ TransitionType trans_type = TransitionType::TRANS_BACK;
+ EaseType ease_type = EaseType::EASE_COUNT;
+ real_t delay = 0.0;
+ int args = 0;
Variant arg[5];
- int uid;
- InterpolateData() {
- active = false;
- finish = false;
- call_deferred = false;
- uid = 0;
- }
+ int uid = 0;
};
String autoplay;
- TweenProcessMode tween_process_mode;
- bool repeat;
- float speed_scale;
- mutable int pending_update;
- int uid;
+ TweenProcessMode tween_process_mode = TWEEN_PROCESS_IDLE;
+ bool repeat = false;
+ float speed_scale = 1.0;
+ mutable int pending_update = 0;
+ int uid = 0;
+ bool was_stopped = false;
List<InterpolateData> interpolates;
struct PendingCommand {
StringName key;
- int args;
+ int args = 0;
Variant arg[10];
};
List<PendingCommand> pending_commands;
diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp
index 14aae9c7bf..2853a8b9d9 100644
--- a/scene/audio/audio_stream_player.cpp
+++ b/scene/audio/audio_stream_player.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -99,37 +99,37 @@ void AudioStreamPlayer::_mix_audio() {
use_fadeout = false;
}
- if (!stream_playback.is_valid() || !active ||
+ if (!stream_playback.is_valid() || !active.is_set() ||
(stream_paused && !stream_paused_fade)) {
return;
}
if (stream_paused) {
- if (stream_paused_fade) {
+ if (stream_paused_fade && stream_playback->is_playing()) {
_mix_internal(true);
stream_paused_fade = false;
}
return;
}
- if (setstop) {
+ if (setstop.is_set()) {
_mix_internal(true);
stream_playback->stop();
- setstop = false;
+ setstop.clear();
}
- if (setseek >= 0.0 && !stop_has_priority) {
+ if (setseek.get() >= 0.0 && !stop_has_priority.is_set()) {
if (stream_playback->is_playing()) {
//fade out to avoid pops
_mix_internal(true);
}
- stream_playback->start(setseek);
- setseek = -1.0; //reset seek
+ stream_playback->start(setseek.get());
+ setseek.set(-1.0); //reset seek
mix_volume_db = volume_db; //reset ramp
}
- stop_has_priority = false;
+ stop_has_priority.clear();
_mix_internal(false);
}
@@ -143,8 +143,8 @@ void AudioStreamPlayer::_notification(int p_what) {
}
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
- if (!active || (setseek < 0 && !stream_playback->is_playing())) {
- active = false;
+ if (!active.is_set() || (setseek.get() < 0 && !stream_playback->is_playing())) {
+ active.clear();
set_process_internal(false);
emit_signal("finished");
}
@@ -169,7 +169,7 @@ void AudioStreamPlayer::_notification(int p_what) {
void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
AudioServer::get_singleton()->lock();
- if (active && stream_playback.is_valid() && !stream_paused) {
+ if (active.is_set() && stream_playback.is_valid() && !stream_paused) {
//changing streams out of the blue is not a great idea, but at least
//lets try to somehow avoid a click
@@ -196,9 +196,9 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
if (stream_playback.is_valid()) {
stream_playback.unref();
stream.unref();
- active = false;
- setseek = -1;
- setstop = false;
+ active.clear();
+ setseek.set(-1);
+ setstop.clear();
}
if (p_stream.is_valid()) {
@@ -237,29 +237,29 @@ float AudioStreamPlayer::get_pitch_scale() const {
void AudioStreamPlayer::play(float p_from_pos) {
if (stream_playback.is_valid()) {
//mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks
- setseek = p_from_pos;
- stop_has_priority = false;
- active = true;
+ setseek.set(p_from_pos);
+ stop_has_priority.clear();
+ active.set();
set_process_internal(true);
}
}
void AudioStreamPlayer::seek(float p_seconds) {
if (stream_playback.is_valid()) {
- setseek = p_seconds;
+ setseek.set(p_seconds);
}
}
void AudioStreamPlayer::stop() {
- if (stream_playback.is_valid() && active) {
- setstop = true;
- stop_has_priority = true;
+ if (stream_playback.is_valid() && active.is_set()) {
+ setstop.set();
+ stop_has_priority.set();
}
}
bool AudioStreamPlayer::is_playing() const {
if (stream_playback.is_valid()) {
- return active && !setstop; //&& stream_playback->is_playing();
+ return active.is_set() && !setstop.is_set(); //&& stream_playback->is_playing();
}
return false;
@@ -267,6 +267,10 @@ bool AudioStreamPlayer::is_playing() const {
float AudioStreamPlayer::get_playback_position() {
if (stream_playback.is_valid()) {
+ float ss = setseek.get();
+ if (ss >= 0.0) {
+ return ss;
+ }
return stream_playback->get_playback_position();
}
@@ -314,7 +318,7 @@ void AudioStreamPlayer::_set_playing(bool p_enable) {
}
bool AudioStreamPlayer::_is_active() const {
- return active;
+ return active.is_set();
}
void AudioStreamPlayer::set_stream_paused(bool p_pause) {
@@ -344,7 +348,7 @@ void AudioStreamPlayer::_validate_property(PropertyInfo &property) const {
}
void AudioStreamPlayer::_bus_layout_changed() {
- _change_notify();
+ notify_property_list_changed();
}
Ref<AudioStreamPlayback> AudioStreamPlayer::get_stream_playback() {
@@ -402,18 +406,7 @@ void AudioStreamPlayer::_bind_methods() {
}
AudioStreamPlayer::AudioStreamPlayer() {
- mix_volume_db = 0;
- pitch_scale = 1.0;
- volume_db = 0;
- autoplay = false;
- setseek = -1;
- active = false;
- stream_paused = false;
- stream_paused_fade = false;
- mix_target = MIX_TARGET_STEREO;
fadeout_buffer.resize(512);
- setstop = false;
- use_fadeout = false;
AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer::_bus_layout_changed));
}
diff --git a/scene/audio/audio_stream_player.h b/scene/audio/audio_stream_player.h
index 2d9c4cb481..aa8d088be5 100644
--- a/scene/audio/audio_stream_player.h
+++ b/scene/audio/audio_stream_player.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,6 +31,7 @@
#ifndef AUDIO_STREAM_PLAYER_H
#define AUDIO_STREAM_PLAYER_H
+#include "core/templates/safe_refcount.h"
#include "scene/main/node.h"
#include "servers/audio/audio_stream.h"
@@ -49,22 +50,22 @@ private:
Ref<AudioStream> stream;
Vector<AudioFrame> mix_buffer;
Vector<AudioFrame> fadeout_buffer;
- bool use_fadeout;
-
- volatile float setseek;
- volatile bool active;
- volatile bool setstop;
- volatile bool stop_has_priority;
-
- float mix_volume_db;
- float pitch_scale;
- float volume_db;
- bool autoplay;
- bool stream_paused;
- bool stream_paused_fade;
+ bool use_fadeout = false;
+
+ SafeNumeric<float> setseek{ -1.0 };
+ SafeFlag active;
+ SafeFlag setstop;
+ SafeFlag stop_has_priority;
+
+ float mix_volume_db = 0.0;
+ float pitch_scale = 1.0;
+ float volume_db = 0.0;
+ bool autoplay = false;
+ bool stream_paused = false;
+ bool stream_paused_fade = false;
StringName bus;
- MixTarget mix_target;
+ MixTarget mix_target = MIX_TARGET_STEREO;
void _mix_internal(bool p_fadeout);
void _mix_audio();
diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp
index f848fc3e68..4dbe3cc1c4 100644
--- a/scene/debugger/scene_debugger.cpp
+++ b/scene/debugger/scene_debugger.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h
index af2d8904b5..9d54556187 100644
--- a/scene/debugger/scene_debugger.h
+++ b/scene/debugger/scene_debugger.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -77,7 +77,7 @@ public:
class SceneDebuggerTree {
public:
struct RemoteNode {
- int child_count;
+ int child_count = 0;
String name;
String type_name;
ObjectID id;
diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp
index 672102bf7a..c7f6c0e2da 100644
--- a/scene/gui/aspect_ratio_container.cpp
+++ b/scene/gui/aspect_ratio_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/aspect_ratio_container.h b/scene/gui/aspect_ratio_container.h
index 8ffc4363c3..c95c6a7274 100644
--- a/scene/gui/aspect_ratio_container.h
+++ b/scene/gui/aspect_ratio_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index dadb1bea31..db13b9b11f 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -199,7 +199,6 @@ void BaseButton::set_disabled(bool p_disabled) {
status.pressing_inside = false;
}
update();
- _change_notify("disabled");
}
bool BaseButton::is_disabled() const {
@@ -213,7 +212,6 @@ void BaseButton::set_pressed(bool p_pressed) {
if (status.pressed == p_pressed) {
return;
}
- _change_notify("pressed");
status.pressed = p_pressed;
if (p_pressed) {
@@ -448,18 +446,7 @@ void BaseButton::_bind_methods() {
}
BaseButton::BaseButton() {
- toggle_mode = false;
- shortcut_in_tooltip = true;
- keep_pressed_outside = false;
- status.pressed = false;
- status.press_attempt = false;
- status.hovering = false;
- status.pressing_inside = false;
- status.disabled = false;
set_focus_mode(FOCUS_ALL);
- action_mode = ACTION_MODE_BUTTON_RELEASE;
- button_mask = BUTTON_MASK_LEFT;
- shortcut_context = ObjectID();
}
BaseButton::~BaseButton() {
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 661801216d..d54d63cc39 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,21 +45,21 @@ public:
};
private:
- int button_mask;
- bool toggle_mode;
- bool shortcut_in_tooltip;
- bool keep_pressed_outside;
+ int button_mask = BUTTON_MASK_LEFT;
+ bool toggle_mode = false;
+ bool shortcut_in_tooltip = true;
+ bool keep_pressed_outside = false;
Ref<Shortcut> shortcut;
ObjectID shortcut_context;
- ActionMode action_mode;
+ ActionMode action_mode = ACTION_MODE_BUTTON_RELEASE;
struct Status {
- bool pressed;
- bool hovering;
- bool press_attempt;
- bool pressing_inside;
+ bool pressed = false;
+ bool hovering = false;
+ bool press_attempt = false;
+ bool pressing_inside = false;
- bool disabled;
+ bool disabled = false;
} status;
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index fdd88d155f..c570438b6a 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,9 +33,9 @@
#include "margin_container.h"
struct _MinSizeCache {
- int min_size;
- bool will_stretch;
- int final_size;
+ int min_size = 0;
+ bool will_stretch = false;
+ int final_size = 0;
};
void BoxContainer::_resort() {
@@ -50,7 +50,7 @@ void BoxContainer::_resort() {
int children_count = 0;
int stretch_min = 0;
int stretch_avail = 0;
- float stretch_ratio_total = 0;
+ float stretch_ratio_total = 0.0;
Map<Control *, _MinSizeCache> min_size_cache;
for (int i = 0; i < get_child_count(); i++) {
@@ -105,7 +105,7 @@ void BoxContainer::_resort() {
has_stretched = true;
bool refit_successful = true; //assume refit-test will go well
- float error = 0; // Keep track of accumulated error in pixels
+ float error = 0.0; // Keep track of accumulated error in pixels
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
@@ -331,7 +331,6 @@ void BoxContainer::add_spacer(bool p_begin) {
BoxContainer::BoxContainer(bool p_vertical) {
vertical = p_vertical;
- align = ALIGN_BEGIN;
}
void BoxContainer::_bind_methods() {
diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h
index c4d75c3cf1..31050d1feb 100644
--- a/scene/gui/box_container.h
+++ b/scene/gui/box_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,8 +44,8 @@ public:
};
private:
- bool vertical;
- AlignMode align;
+ bool vertical = false;
+ AlignMode align = ALIGN_BEGIN;
void _resort();
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 0cdfa9457e..b0bcde8865 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,6 +56,11 @@ Size2 Button::get_minimum_size() const {
}
}
+ Ref<Font> font = get_theme_font("font");
+ float font_height = font->get_height(get_theme_font_size("font_size"));
+
+ minsize.height = MAX(font_height, minsize.height);
+
return get_theme_stylebox("normal")->get_minimum_size() + minsize;
}
@@ -102,8 +107,8 @@ void Button::_notification(int p_what) {
style->draw(ci, Rect2(Point2(0, 0), size));
}
color = get_theme_color("font_color");
- if (has_theme_color("icon_color_normal")) {
- color_icon = get_theme_color("icon_color_normal");
+ if (has_theme_color("icon_normal_color")) {
+ color_icon = get_theme_color("icon_normal_color");
}
} break;
case DRAW_HOVER_PRESSED: {
@@ -117,13 +122,13 @@ void Button::_notification(int p_what) {
if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
}
- if (has_theme_color("font_color_hover_pressed")) {
- color = get_theme_color("font_color_hover_pressed");
+ if (has_theme_color("font_hover_pressed_color")) {
+ color = get_theme_color("font_hover_pressed_color");
} else {
color = get_theme_color("font_color");
}
- if (has_theme_color("icon_color_hover_pressed")) {
- color_icon = get_theme_color("icon_color_hover_pressed");
+ if (has_theme_color("icon_hover_pressed_color")) {
+ color_icon = get_theme_color("icon_hover_pressed_color");
}
break;
@@ -140,13 +145,13 @@ void Button::_notification(int p_what) {
if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
}
- if (has_theme_color("font_color_pressed")) {
- color = get_theme_color("font_color_pressed");
+ if (has_theme_color("font_pressed_color")) {
+ color = get_theme_color("font_pressed_color");
} else {
color = get_theme_color("font_color");
}
- if (has_theme_color("icon_color_pressed")) {
- color_icon = get_theme_color("icon_color_pressed");
+ if (has_theme_color("icon_pressed_color")) {
+ color_icon = get_theme_color("icon_pressed_color");
}
} break;
@@ -160,9 +165,9 @@ void Button::_notification(int p_what) {
if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
}
- color = get_theme_color("font_color_hover");
- if (has_theme_color("icon_color_hover")) {
- color_icon = get_theme_color("icon_color_hover");
+ color = get_theme_color("font_hover_color");
+ if (has_theme_color("icon_hover_color")) {
+ color_icon = get_theme_color("icon_hover_color");
}
} break;
@@ -176,9 +181,9 @@ void Button::_notification(int p_what) {
if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
}
- color = get_theme_color("font_color_disabled");
- if (has_theme_color("icon_color_disabled")) {
- color_icon = get_theme_color("icon_color_disabled");
+ color = get_theme_color("font_disabled_color");
+ if (has_theme_color("icon_disabled_color")) {
+ color_icon = get_theme_color("icon_disabled_color");
}
} break;
@@ -203,7 +208,7 @@ void Button::_notification(int p_what) {
color_icon.a = 0.4;
}
- float icon_ofs_region = 0;
+ float icon_ofs_region = 0.0;
if (rtl) {
if (_internal_margin[SIDE_RIGHT] > 0) {
icon_ofs_region = _internal_margin[SIDE_RIGHT] + get_theme_constant("hseparation");
@@ -303,13 +308,13 @@ void Button::_notification(int p_what) {
text_ofs.x -= icon_ofs.x;
}
- Color font_outline_modulate = get_theme_color("font_outline_modulate");
+ Color font_outline_color = get_theme_color("font_outline_color");
int outline_size = get_theme_constant("outline_size");
- if (outline_size > 0 && font_outline_modulate.a > 0) {
- text_buf->draw_outline(ci, text_ofs.floor(), outline_size, font_outline_modulate);
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ text_buf->draw_outline(ci, text_ofs, outline_size, font_outline_color);
}
- text_buf->draw(ci, text_ofs.floor(), color);
+ text_buf->draw(ci, text_ofs, color);
if (!_icon.is_null() && icon_region.size.width > 0) {
draw_texture_rect_region(_icon, icon_region, Rect2(Point2(), _icon->get_size()), color_icon);
@@ -338,7 +343,6 @@ void Button::set_text(const String &p_text) {
_shape();
update();
- _change_notify("text");
minimum_size_changed();
}
}
@@ -399,7 +403,6 @@ void Button::set_icon(const Ref<Texture2D> &p_icon) {
if (icon != p_icon) {
icon = p_icon;
update();
- _change_notify("icon");
minimum_size_changed();
}
}
@@ -424,7 +427,6 @@ void Button::set_flat(bool p_flat) {
if (flat != p_flat) {
flat = p_flat;
update();
- _change_notify("flat");
}
}
@@ -474,7 +476,7 @@ bool Button::_set(const StringName &p_name, const Variant &p_value) {
update();
}
}
- _change_notify();
+ notify_property_list_changed();
return true;
}
@@ -544,16 +546,8 @@ Button::Button(const String &p_text) {
text_buf.instance();
text_buf->set_flags(TextServer::BREAK_MANDATORY);
- flat = false;
- clip_text = false;
- expand_icon = false;
set_mouse_filter(MOUSE_FILTER_STOP);
set_text(p_text);
- align = ALIGN_CENTER;
-
- for (int i = 0; i < 4; i++) {
- _internal_margin[i] = 0;
- }
}
Button::~Button() {
diff --git a/scene/gui/button.h b/scene/gui/button.h
index f367448b86..d968f63f51 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,7 @@ public:
};
private:
- bool flat;
+ bool flat = false;
String text;
String xl_text;
Ref<TextParagraph> text_buf;
@@ -55,10 +55,10 @@ private:
TextDirection text_direction = TEXT_DIRECTION_AUTO;
Ref<Texture2D> icon;
- bool expand_icon;
- bool clip_text;
- TextAlign align;
- float _internal_margin[4];
+ bool expand_icon = false;
+ bool clip_text = false;
+ TextAlign align = ALIGN_CENTER;
+ float _internal_margin[4] = {};
void _shape();
diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp
index 1a72f3ca4d..909516e7ef 100644
--- a/scene/gui/center_container.cpp
+++ b/scene/gui/center_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -95,6 +95,4 @@ void CenterContainer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_top_left"), "set_use_top_left", "is_using_top_left");
}
-CenterContainer::CenterContainer() {
- use_top_left = false;
-}
+CenterContainer::CenterContainer() {}
diff --git a/scene/gui/center_container.h b/scene/gui/center_container.h
index 638843c389..0944f200fc 100644
--- a/scene/gui/center_container.h
+++ b/scene/gui/center_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class CenterContainer : public Container {
GDCLASS(CenterContainer, Container);
- bool use_top_left;
+ bool use_top_left = false;
protected:
void _notification(int p_what);
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index bb274195f4..9df328dd11 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h
index cc00524698..9fb0aea218 100644
--- a/scene/gui/check_box.h
+++ b/scene/gui/check_box.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index 2dd6cd1cb2..a8bf449355 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h
index 99a12a3270..29c557ce89 100644
--- a/scene/gui/check_button.h
+++ b/scene/gui/check_button.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 59cfbccf99..28a0ea0100 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index c989e5ed79..d0c39ec0f1 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 8b02567d88..bddbe30f53 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -52,6 +52,7 @@ void ColorPicker::_notification(int p_what) {
btn_pick->set_icon(get_theme_icon("screen_picker", "ColorPicker"));
bt_add_preset->set_icon(get_theme_icon("add_preset"));
+ _update_controls();
_update_color();
#ifdef TOOLS_ENABLED
@@ -112,6 +113,24 @@ void ColorPicker::_update_controls() {
btn_hsv->set_disabled(false);
}
+ if (raw_mode_enabled) {
+ for (int i = 0; i < 3; i++) {
+ scroll[i]->add_theme_icon_override("grabber", Ref<Texture2D>());
+ scroll[i]->add_theme_icon_override("grabber_highlight", Ref<Texture2D>());
+ scroll[i]->add_theme_style_override("slider", Ref<StyleBox>());
+ scroll[i]->add_theme_style_override("grabber_area", Ref<StyleBox>());
+ scroll[i]->add_theme_style_override("grabber_area_highlight", Ref<StyleBox>());
+ }
+ } else {
+ for (int i = 0; i < 3; i++) {
+ scroll[i]->add_theme_icon_override("grabber", get_theme_icon("bar_arrow"));
+ scroll[i]->add_theme_icon_override("grabber_highlight", get_theme_icon("bar_arrow"));
+ scroll[i]->add_theme_style_override("slider", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[i]->add_theme_style_override("grabber_area", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[i]->add_theme_style_override("grabber_area_highlight", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ }
+ }
+
if (edit_alpha) {
values[3]->show();
scroll[3]->show();
@@ -165,10 +184,13 @@ void ColorPicker::_value_changed(double) {
}
if (hsv_mode_enabled) {
- color.set_hsv(scroll[0]->get_value() / 360.0,
- scroll[1]->get_value() / 100.0,
- scroll[2]->get_value() / 100.0,
- scroll[3]->get_value() / 255.0);
+ h = scroll[0]->get_value() / 360.0;
+ s = scroll[1]->get_value() / 100.0;
+ v = scroll[2]->get_value() / 100.0;
+ color.set_hsv(h, s, v, scroll[3]->get_value() / 255.0);
+
+ last_hsv = color;
+
} else {
for (int i = 0; i < 4; i++) {
color.components[i] = scroll[i]->get_value() / (raw_mode_enabled ? 1.0 : 255.0);
@@ -239,6 +261,9 @@ void ColorPicker::_update_color(bool p_update_sliders) {
sample->update();
uv_edit->update();
w_edit->update();
+ for (int i = 0; i < 4; i++) {
+ scroll[i]->update();
+ }
updating = false;
}
@@ -452,6 +477,69 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
}
+void ColorPicker::_slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ Size2 size = scroll[p_which]->get_size();
+ Color left_color;
+ Color right_color;
+#ifdef TOOLS_ENABLED
+ const real_t margin = 4 * EDSCALE;
+#else
+ const real_t margin = 4;
+#endif
+
+ if (p_which == 3) {
+ scroll[p_which]->draw_texture_rect(get_theme_icon("preset_bg", "ColorPicker"), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else {
+ if (raw_mode_enabled) {
+ return;
+ }
+ if (hsv_mode_enabled) {
+ if (p_which == 0) {
+ Ref<Texture2D> hue = get_theme_icon("color_hue", "ColorPicker");
+ scroll[p_which]->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
+ scroll[p_which]->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(scroll[p_which]->get_size().x, margin)), false, Color(1, 1, 1), true);
+ return;
+ }
+ Color s_col;
+ Color v_col;
+ s_col.set_hsv(h, 0, v);
+ left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
+ s_col.set_hsv(h, 1, v);
+ v_col.set_hsv(h, s, 1);
+ right_color = (p_which == 1) ? s_col : v_col;
+ } else {
+ left_color = Color(
+ p_which == 0 ? 0 : color.r,
+ p_which == 1 ? 0 : color.g,
+ p_which == 2 ? 0 : color.b);
+ right_color = Color(
+ p_which == 0 ? 1 : color.r,
+ p_which == 1 ? 1 : color.g,
+ p_which == 2 ? 1 : color.b);
+ }
+ }
+
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ scroll[p_which]->draw_polygon(pos, col);
+}
+
void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> bev = p_event;
@@ -577,6 +665,10 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
}
void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
+ if (!is_inside_tree()) {
+ return;
+ }
+
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid() && bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) {
emit_signal("color_changed", color);
@@ -591,7 +683,7 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
}
Ref<Image> img = r->get_texture()->get_data();
- if (img.is_valid() && !img->empty()) {
+ if (img.is_valid() && !img->is_empty()) {
Vector2 ofs = mev->get_global_position() - r->get_visible_rect().get_position();
Color c = img->get_pixel(ofs.x, r->get_visible_rect().size.height - ofs.y);
@@ -606,6 +698,10 @@ void ColorPicker::_add_preset_pressed() {
}
void ColorPicker::_screen_pick_pressed() {
+ if (!is_inside_tree()) {
+ return;
+ }
+
Viewport *r = get_tree()->get_root();
if (!screen) {
screen = memnew(Control);
@@ -718,17 +814,6 @@ void ColorPicker::_bind_methods() {
ColorPicker::ColorPicker() :
BoxContainer(true) {
- updating = true;
- edit_alpha = true;
- text_is_constructor = false;
- hsv_mode_enabled = false;
- raw_mode_enabled = false;
- deferred_mode_enabled = false;
- changing_color = false;
- presets_enabled = true;
- presets_visible = true;
- screen = nullptr;
-
HBoxContainer *hb_edit = memnew(HBoxContainer);
add_child(hb_edit);
hb_edit->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -798,10 +883,16 @@ ColorPicker::ColorPicker() :
scroll[i]->set_h_size_flags(SIZE_EXPAND_FILL);
scroll[i]->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed));
+ scroll[i]->connect("draw", callable_mp(this, &ColorPicker::_slider_draw), make_binds(i));
vbr->add_child(hbc);
}
labels[3]->set_text("A");
+ scroll[3]->add_theme_icon_override("grabber", get_theme_icon("bar_arrow"));
+ scroll[3]->add_theme_icon_override("grabber_highlight", get_theme_icon("bar_arrow"));
+ scroll[3]->add_theme_style_override("slider", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[3]->add_theme_style_override("grabber_area", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[3]->add_theme_style_override("grabber_area_highlight", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
HBoxContainer *hhb = memnew(HBoxContainer);
vbr->add_child(hhb);
@@ -1001,12 +1092,5 @@ void ColorPickerButton::_bind_methods() {
}
ColorPickerButton::ColorPickerButton() {
- // Initialization is now done deferred,
- // this improves performance in the inspector as the color picker
- // can be expensive to initialize.
- picker = nullptr;
- popup = nullptr;
- edit_alpha = true;
-
set_toggle_mode(true);
}
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 128664b49d..24e1746c41 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,7 @@ class ColorPicker : public BoxContainer {
GDCLASS(ColorPicker, BoxContainer);
private:
- Control *screen;
+ Control *screen = nullptr;
Control *uv_edit;
Control *w_edit;
TextureRect *sample;
@@ -64,20 +64,22 @@ private:
Label *labels[4];
Button *text_type;
LineEdit *c_text;
- bool edit_alpha;
+ bool edit_alpha = true;
Size2i ms;
- bool text_is_constructor;
- int presets_per_row;
+ bool text_is_constructor = false;
+ int presets_per_row = 0;
Color color;
- bool raw_mode_enabled;
- bool hsv_mode_enabled;
- bool deferred_mode_enabled;
- bool updating;
- bool changing_color;
- bool presets_enabled;
- bool presets_visible;
- float h, s, v;
+ bool raw_mode_enabled = false;
+ bool hsv_mode_enabled = false;
+ bool deferred_mode_enabled = false;
+ bool updating = true;
+ bool changing_color = false;
+ bool presets_enabled = true;
+ bool presets_visible = true;
+ float h = 0.0;
+ float s = 0.0;
+ float v = 0.0;
Color last_hsv;
void _html_entered(const String &p_html);
@@ -89,6 +91,7 @@ private:
void _text_type_toggled();
void _sample_draw();
void _hsv_draw(int p_which, Control *c);
+ void _slider_draw(int p_which);
void _uv_input(const Ref<InputEvent> &p_event);
void _w_input(const Ref<InputEvent> &p_event);
@@ -139,10 +142,14 @@ public:
class ColorPickerButton : public Button {
GDCLASS(ColorPickerButton, Button);
- PopupPanel *popup;
- ColorPicker *picker;
+ // Initialization is now done deferred,
+ // this improves performance in the inspector as the color picker
+ // can be expensive to initialize.
+
+ PopupPanel *popup = nullptr;
+ ColorPicker *picker = nullptr;
Color color;
- bool edit_alpha;
+ bool edit_alpha = true;
void _color_changed(const Color &p_color);
void _modal_closed();
diff --git a/scene/gui/color_rect.cpp b/scene/gui/color_rect.cpp
index 0c38b93c60..e35d37d520 100644
--- a/scene/gui/color_rect.cpp
+++ b/scene/gui/color_rect.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/color_rect.h b/scene/gui/color_rect.h
index 61d57f7cca..5c650f9f01 100644
--- a/scene/gui/color_rect.h
+++ b/scene/gui/color_rect.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index f01da703c1..2e6b798eea 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -163,7 +163,7 @@ String Container::get_configuration_warning() const {
String warning = Control::get_configuration_warning();
if (get_class() == "Container" && get_script().is_null()) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, use a plain Control node instead.");
@@ -180,7 +180,6 @@ void Container::_bind_methods() {
}
Container::Container() {
- pending_sort = false;
// All containers should let mouse events pass by default.
set_mouse_filter(MOUSE_FILTER_PASS);
}
diff --git a/scene/gui/container.h b/scene/gui/container.h
index b789bcf3b0..a4f392a3ae 100644
--- a/scene/gui/container.h
+++ b/scene/gui/container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class Container : public Control {
GDCLASS(Container, Control);
- bool pending_sort;
+ bool pending_sort = false;
void _sort_children();
void _child_minsize_changed();
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 62cbec4ae5..bff3024e38 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -93,7 +93,7 @@ void Control::_edit_set_state(const Dictionary &p_state) {
void Control::_edit_set_position(const Point2 &p_position) {
#ifdef TOOLS_ENABLED
- set_position(p_position, CanvasItemEditor::get_singleton()->is_anchors_mode_enabled());
+ set_position(p_position, CanvasItemEditor::get_singleton()->is_anchors_mode_enabled() && Object::cast_to<Control>(data.parent));
#else
// Unlikely to happen. TODO: enclose all _edit_ functions into TOOLS_ENABLED
set_position(p_position);
@@ -439,14 +439,14 @@ bool Control::is_layout_rtl() const {
} else if (parent_window) {
return parent_window->is_layout_rtl();
} else {
- if (GLOBAL_GET("display/window/force_right_to_left_layout_direction")) {
+ if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
return true;
}
String locale = TranslationServer::get_singleton()->get_tool_locale();
return TS->is_locale_right_to_left(locale);
}
} else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) {
- if (GLOBAL_GET("display/window/force_right_to_left_layout_direction")) {
+ if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
return true;
}
String locale = TranslationServer::get_singleton()->get_tool_locale();
@@ -456,6 +456,10 @@ bool Control::is_layout_rtl() const {
}
}
+void Control::_clear_size_warning() {
+ data.size_warning = false;
+}
+
//moved theme configuration here, so controls can set up even if still not inside active scene
void Control::add_child_notify(Node *p_child) {
@@ -503,7 +507,9 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_EXIT_TREE: {
get_viewport()->_gui_remove_control(this);
-
+ } break;
+ case NOTIFICATION_READY: {
+ connect("ready", callable_mp(this, &Control::_clear_size_warning), varray(), CONNECT_DEFERRED | CONNECT_ONESHOT);
} break;
case NOTIFICATION_ENTER_CANVAS: {
@@ -709,7 +715,7 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const
}
}
- return Variant();
+ return false;
}
void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
@@ -1275,7 +1281,6 @@ void Control::_size_changed() {
}
if (pos_changed || size_changed) {
item_rect_changed(size_changed);
- _change_notify_offsets();
_notify_transform();
}
@@ -1315,10 +1320,6 @@ void Control::set_anchor(Side p_side, float p_anchor, bool p_keep_offset, bool p
}
update();
- _change_notify("anchor_left");
- _change_notify("anchor_right");
- _change_notify("anchor_top");
- _change_notify("anchor_bottom");
}
void Control::_set_anchor(Side p_side, float p_anchor) {
@@ -1592,16 +1593,6 @@ float Control::get_anchor(Side p_side) const {
return data.anchor[p_side];
}
-void Control::_change_notify_offsets() {
- // this avoids sending the whole object data again on a change
- _change_notify("offset_left");
- _change_notify("offset_top");
- _change_notify("offset_right");
- _change_notify("offset_bottom");
- _change_notify("rect_position");
- _change_notify("rect_size");
-}
-
void Control::set_offset(Side p_side, float p_value) {
ERR_FAIL_INDEX((int)p_side, 4);
@@ -1699,10 +1690,6 @@ void Control::_set_position(const Size2 &p_point) {
void Control::set_position(const Size2 &p_point, bool p_keep_offsets) {
if (p_keep_offsets) {
_compute_anchors(Rect2(p_point, data.size_cache), data.offset, data.anchor);
- _change_notify("anchor_left");
- _change_notify("anchor_right");
- _change_notify("anchor_top");
- _change_notify("anchor_bottom");
} else {
_compute_offsets(Rect2(p_point, data.size_cache), data.anchor, data.offset);
}
@@ -1721,6 +1708,11 @@ void Control::set_rect(const Rect2 &p_rect) {
}
void Control::_set_size(const Size2 &p_size) {
+#ifdef DEBUG_ENABLED
+ if (data.size_warning) {
+ WARN_PRINT("Adjusting the size of Control nodes before they are fully initialized is unreliable. Consider deferring it with set_deferred().");
+ }
+#endif
set_size(p_size);
}
@@ -1736,10 +1728,6 @@ void Control::set_size(const Size2 &p_size, bool p_keep_offsets) {
if (p_keep_offsets) {
_compute_anchors(Rect2(data.pos_cache, new_size), data.offset, data.anchor);
- _change_notify("anchor_left");
- _change_notify("anchor_right");
- _change_notify("anchor_top");
- _change_notify("anchor_bottom");
} else {
_compute_offsets(Rect2(data.pos_cache, new_size), data.anchor, data.offset);
}
@@ -2577,7 +2565,6 @@ void Control::set_rotation(float p_radians) {
data.rotation = p_radians;
update();
_notify_transform();
- _change_notify("rect_rotation");
}
float Control::get_rotation() const {
@@ -2602,7 +2589,6 @@ void Control::set_pivot_offset(const Vector2 &p_pivot) {
data.pivot_offset = p_pivot;
update();
_notify_transform();
- _change_notify("rect_pivot_offset");
}
Vector2 Control::get_pivot_offset() const {
@@ -2698,7 +2684,7 @@ String Control::get_configuration_warning() const {
String warning = CanvasItem::get_configuration_warning();
if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\".");
@@ -2785,6 +2771,8 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_focus"), &Control::has_focus);
ClassDB::bind_method(D_METHOD("grab_focus"), &Control::grab_focus);
ClassDB::bind_method(D_METHOD("release_focus"), &Control::release_focus);
+ ClassDB::bind_method(D_METHOD("find_prev_valid_focus"), &Control::find_prev_valid_focus);
+ ClassDB::bind_method(D_METHOD("find_next_valid_focus"), &Control::find_next_valid_focus);
ClassDB::bind_method(D_METHOD("get_focus_owner"), &Control::get_focus_owner);
ClassDB::bind_method(D_METHOD("set_h_size_flags", "flags"), &Control::set_h_size_flags);
@@ -2913,7 +2901,8 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", 0), "_set_global_position", "get_global_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_min_size"), "set_custom_minimum_size", "get_custom_minimum_size");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rect_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_rotation_degrees", "get_rotation_degrees");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rect_rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rect_rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_rotation_degrees", "get_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_scale"), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_pivot_offset"), "set_pivot_offset", "get_pivot_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rect_clip_content"), "set_clip_contents", "is_clipping_contents");
diff --git a/scene/gui/control.h b/scene/gui/control.h
index ea336e3c59..8981e05872 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -179,13 +179,14 @@ private:
LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED;
- float rotation = 0;
+ float rotation = 0.0;
Vector2 scale = Vector2(1, 1);
Vector2 pivot_offset;
+ bool size_warning = true;
int h_size_flags = SIZE_FILL;
int v_size_flags = SIZE_FILL;
- float expand = 1;
+ float expand = 1.0;
Point2 custom_minimum_size;
MouseFilter mouse_filter = MOUSE_FILTER_STOP;
@@ -233,9 +234,9 @@ private:
void _theme_changed();
- void _change_notify_offsets();
void _update_minimum_size();
+ void _clear_size_warning();
void _update_scroll();
void _compute_offsets(Rect2 p_rect, const float p_anchors[4], float (&r_offsets)[4]);
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 9f5f6c21c8..fdfbf9eafc 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -165,7 +165,7 @@ void AcceptDialog::register_text_enter(Node *p_line_edit) {
void AcceptDialog::_update_child_rects() {
Size2 label_size = label->get_minimum_size();
- if (label->get_text().empty()) {
+ if (label->get_text().is_empty()) {
label_size.height = 0;
}
int margin = hbc->get_theme_constant("margin", "Dialogs");
@@ -292,8 +292,6 @@ void AcceptDialog::set_swap_cancel_ok(bool p_swap) {
}
AcceptDialog::AcceptDialog() {
- parent_visible = nullptr;
-
set_wrap_controls(true);
set_visible(false);
set_transient(true);
@@ -325,7 +323,6 @@ AcceptDialog::AcceptDialog() {
ok->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed));
- hide_on_ok = true;
set_title(RTR("Alert!"));
connect("window_input", callable_mp(this, &AcceptDialog::_input_from_window));
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 8f6e0e86f9..b072055d49 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,12 +44,12 @@ class LineEdit;
class AcceptDialog : public Window {
GDCLASS(AcceptDialog, Window);
- Window *parent_visible;
+ Window *parent_visible = nullptr;
Panel *bg;
HBoxContainer *hbc;
Label *label;
Button *ok;
- bool hide_on_ok;
+ bool hide_on_ok = true;
void _custom_action(const String &p_action);
void _update_child_rects();
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 041b8ef174..7453324505 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,20 +50,20 @@ VBoxContainer *FileDialog::get_vbox() {
void FileDialog::_theme_changed() {
Color font_color = vbox->get_theme_color("font_color", "Button");
- Color font_color_hover = vbox->get_theme_color("font_color_hover", "Button");
- Color font_color_pressed = vbox->get_theme_color("font_color_pressed", "Button");
+ Color font_hover_color = vbox->get_theme_color("font_hover_color", "Button");
+ Color font_pressed_color = vbox->get_theme_color("font_pressed_color", "Button");
- dir_up->add_theme_color_override("icon_color_normal", font_color);
- dir_up->add_theme_color_override("icon_color_hover", font_color_hover);
- dir_up->add_theme_color_override("icon_color_pressed", font_color_pressed);
+ dir_up->add_theme_color_override("icon_normal_color", font_color);
+ dir_up->add_theme_color_override("icon_hover_color", font_hover_color);
+ dir_up->add_theme_color_override("icon_pressed_color", font_pressed_color);
- refresh->add_theme_color_override("icon_color_normal", font_color);
- refresh->add_theme_color_override("icon_color_hover", font_color_hover);
- refresh->add_theme_color_override("icon_color_pressed", font_color_pressed);
+ refresh->add_theme_color_override("icon_normal_color", font_color);
+ refresh->add_theme_color_override("icon_hover_color", font_hover_color);
+ refresh->add_theme_color_override("icon_pressed_color", font_pressed_color);
- show_hidden->add_theme_color_override("icon_color_normal", font_color);
- show_hidden->add_theme_color_override("icon_color_hover", font_color_hover);
- show_hidden->add_theme_color_override("icon_color_pressed", font_color_pressed);
+ show_hidden->add_theme_color_override("icon_normal_color", font_color);
+ show_hidden->add_theme_color_override("icon_hover_color", font_hover_color);
+ show_hidden->add_theme_color_override("icon_pressed_color", font_pressed_color);
}
void FileDialog::_notification(int p_what) {
@@ -136,7 +136,7 @@ void FileDialog::update_dir() {
}
// Deselect any item, to make "Select Current Folder" button text by default.
- deselect_items();
+ deselect_all();
}
void FileDialog::_dir_entered(String p_dir) {
@@ -172,7 +172,7 @@ void FileDialog::_post_popup() {
// For open dir mode, deselect all items on file dialog open.
if (mode == FILE_MODE_OPEN_DIR) {
- deselect_items();
+ deselect_all();
file_box->set_visible(false);
} else {
file_box->set_visible(true);
@@ -318,7 +318,7 @@ void FileDialog::_go_up() {
update_dir();
}
-void FileDialog::deselect_items() {
+void FileDialog::deselect_all() {
// Clear currently selected items in file manager.
tree->deselect_all();
@@ -434,7 +434,7 @@ void FileDialog::update_file_list() {
dirs.sort_custom<NaturalNoCaseComparator>();
files.sort_custom<NaturalNoCaseComparator>();
- while (!dirs.empty()) {
+ while (!dirs.is_empty()) {
String &dir_name = dirs.front()->get();
TreeItem *ti = tree->create_item(root);
ti->set_text(0, dir_name);
@@ -478,8 +478,8 @@ void FileDialog::update_file_list() {
String base_dir = dir_access->get_current_dir();
- while (!files.empty()) {
- bool match = patterns.empty();
+ while (!files.is_empty()) {
+ bool match = patterns.is_empty();
String match_str;
for (List<String>::Element *E = patterns.front(); E; E = E->next()) {
@@ -808,7 +808,7 @@ void FileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_file_name"), &FileDialog::update_file_name);
ClassDB::bind_method(D_METHOD("_update_dir"), &FileDialog::update_dir);
ClassDB::bind_method(D_METHOD("_update_file_list"), &FileDialog::update_file_list);
- ClassDB::bind_method(D_METHOD("deselect_items"), &FileDialog::deselect_items);
+ ClassDB::bind_method(D_METHOD("deselect_all"), &FileDialog::deselect_all);
ClassDB::bind_method(D_METHOD("invalidate"), &FileDialog::invalidate);
@@ -852,8 +852,6 @@ void FileDialog::set_default_show_hidden_files(bool p_show) {
FileDialog::FileDialog() {
show_hidden_files = default_show_hidden_files;
- mode_overrides_title = true;
-
vbox = memnew(VBoxContainer);
add_child(vbox);
vbox->connect("theme_changed", callable_mp(this, &FileDialog::_theme_changed));
@@ -925,14 +923,13 @@ FileDialog::FileDialog() {
vbox->add_child(file_box);
dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- access = ACCESS_RESOURCES;
_update_drives();
connect("confirmed", callable_mp(this, &FileDialog::_action_pressed));
tree->connect("multi_selected", callable_mp(this, &FileDialog::_tree_multi_selected), varray(), CONNECT_DEFERRED);
tree->connect("cell_selected", callable_mp(this, &FileDialog::_tree_selected), varray(), CONNECT_DEFERRED);
tree->connect("item_activated", callable_mp(this, &FileDialog::_tree_item_activated), varray());
- tree->connect("nothing_selected", callable_mp(this, &FileDialog::deselect_items));
+ tree->connect("nothing_selected", callable_mp(this, &FileDialog::deselect_all));
dir->connect("text_entered", callable_mp(this, &FileDialog::_dir_entered));
file->connect("text_entered", callable_mp(this, &FileDialog::_file_entered));
filter->connect("item_selected", callable_mp(this, &FileDialog::_filter_selected));
@@ -967,7 +964,6 @@ FileDialog::FileDialog() {
set_hide_on_ok(false);
- invalidated = true;
if (register_func) {
register_func(this);
}
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 8003650668..25b742c234 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -69,7 +69,7 @@ private:
LineEdit *makedirname;
Button *makedir;
- Access access;
+ Access access = ACCESS_RESOURCES;
//Button *action;
VBoxContainer *vbox;
FileMode mode;
@@ -93,12 +93,12 @@ private:
Vector<String> filters;
- bool mode_overrides_title;
+ bool mode_overrides_title = true;
static bool default_show_hidden_files;
- bool show_hidden_files;
+ bool show_hidden_files = false;
- bool invalidated;
+ bool invalidated = true;
void update_dir();
void update_file_name();
@@ -170,7 +170,7 @@ public:
void invalidate();
- void deselect_items();
+ void deselect_all();
FileDialog();
~FileDialog();
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 53d7ead548..36b383f16c 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,8 +42,6 @@
#endif
GradientEdit::GradientEdit() {
- grabbed = -1;
- grabbing = false;
set_focus_mode(FOCUS_ALL);
popup = memnew(PopupPanel);
@@ -237,7 +235,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
// Snap to "round" coordinates if holding Ctrl.
// Be more precise if holding Shift as well
if (mm->get_control()) {
- newofs = Math::stepify(newofs, mm->get_shift() ? 0.025 : 0.1);
+ newofs = Math::snapped(newofs, mm->get_shift() ? 0.025 : 0.1);
} else if (mm->get_shift()) {
// Snap to nearest point if holding just Shift
const float snap_threshold = 0.03;
diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h
index 6e950703bb..eb7367d598 100644
--- a/scene/gui/gradient_edit.h
+++ b/scene/gui/gradient_edit.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,8 +44,8 @@ class GradientEdit : public Control {
Ref<ImageTexture> checker;
- bool grabbing;
- int grabbed;
+ bool grabbing = false;
+ int grabbed = -1;
Vector<Gradient::Point> points;
void _draw_checker(int x, int y, int w, int h);
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 6c2d414ea9..331f0380c5 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -154,6 +154,10 @@ Vector2 GraphEditMinimap::_convert_to_graph_position(const Vector2 &p_position)
}
void GraphEditMinimap::_gui_input(const Ref<InputEvent> &p_ev) {
+ if (!ge->is_minimap_enabled()) {
+ return;
+ }
+
Ref<InputEventMouseButton> mb = p_ev;
Ref<InputEventMouseMotion> mm = p_ev;
@@ -381,6 +385,15 @@ void GraphEdit::_graph_node_moved(Node *p_gn) {
connections_layer->update();
}
+void GraphEdit::_graph_node_slot_updated(int p_index, Node *p_gn) {
+ GraphNode *gn = Object::cast_to<GraphNode>(p_gn);
+ ERR_FAIL_COND(!gn);
+ top_layer->update();
+ minimap->update();
+ update();
+ connections_layer->update();
+}
+
void GraphEdit::add_child_notify(Node *p_child) {
Control::add_child_notify(p_child);
@@ -389,7 +402,8 @@ void GraphEdit::add_child_notify(Node *p_child) {
GraphNode *gn = Object::cast_to<GraphNode>(p_child);
if (gn) {
gn->set_scale(Vector2(zoom, zoom));
- gn->connect("offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved), varray(gn));
+ gn->connect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved), varray(gn));
+ gn->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated), varray(gn));
gn->connect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised), varray(gn));
gn->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update));
gn->connect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::update));
@@ -401,16 +415,30 @@ void GraphEdit::add_child_notify(Node *p_child) {
void GraphEdit::remove_child_notify(Node *p_child) {
Control::remove_child_notify(p_child);
- if (is_inside_tree()) {
+ if (p_child == top_layer) {
+ top_layer = nullptr;
+ minimap = nullptr;
+ } else if (p_child == connections_layer) {
+ connections_layer = nullptr;
+ }
+
+ if (top_layer != nullptr && is_inside_tree()) {
top_layer->call_deferred("raise"); // Top layer always on top!
}
GraphNode *gn = Object::cast_to<GraphNode>(p_child);
if (gn) {
- gn->disconnect("offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved));
+ gn->disconnect("position_offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved));
+ gn->disconnect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated));
gn->disconnect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised));
- gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update));
- gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::update));
+
+ // In case of the whole GraphEdit being destroyed these references can already be freed.
+ if (connections_layer != nullptr && connections_layer->is_inside_tree()) {
+ gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update));
+ }
+ if (minimap != nullptr && minimap->is_inside_tree()) {
+ gn->disconnect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::update));
+ }
}
}
@@ -502,14 +530,14 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
for (int j = 0; j < gn->get_connection_output_count(); j++) {
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
- if (is_in_hot_zone(pos, p_point)) {
+ if (is_in_hot_zone(pos / zoom, p_point / zoom)) {
return true;
}
}
for (int j = 0; j < gn->get_connection_input_count(); j++) {
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
- if (is_in_hot_zone(pos, p_point)) {
+ if (is_in_hot_zone(pos / zoom, p_point / zoom)) {
return true;
}
}
@@ -523,7 +551,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
connecting_valid = false;
Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
- click_pos = mb->get_position();
+ click_pos = mb->get_position() / zoom;
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
if (!gn) {
@@ -532,7 +560,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
for (int j = 0; j < gn->get_connection_output_count(); j++) {
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
- if (is_in_hot_zone(pos, click_pos)) {
+ if (is_in_hot_zone(pos / zoom, click_pos)) {
if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) {
//check disconnect
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
@@ -574,7 +602,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
for (int j = 0; j < gn->get_connection_input_count(); j++) {
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
- if (is_in_hot_zone(pos, click_pos)) {
+ if (is_in_hot_zone(pos / zoom, click_pos)) {
if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) {
//check disconnect
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
@@ -623,11 +651,11 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
connecting_target = false;
top_layer->update();
minimap->update();
- connecting_valid = just_disconnected || click_pos.distance_to(connecting_to) > 20.0 * zoom;
+ connecting_valid = just_disconnected || click_pos.distance_to(connecting_to / zoom) > 20.0 * zoom;
if (connecting_valid) {
Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
- Vector2 mpos = mm->get_position();
+ Vector2 mpos = mm->get_position() / zoom;
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
if (!gn) {
@@ -638,7 +666,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
for (int j = 0; j < gn->get_connection_output_count(); j++) {
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
int type = gn->get_connection_output_type(j);
- if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
+ if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos)) {
connecting_target = true;
connecting_to = pos;
connecting_target_to = gn->get_name();
@@ -650,7 +678,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
for (int j = 0; j < gn->get_connection_input_count(); j++) {
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
int type = gn->get_connection_input_type(j);
- if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
+ if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos / zoom, mpos)) {
connecting_target = true;
connecting_to = pos;
connecting_target_to = gn->get_name();
@@ -732,6 +760,11 @@ bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos) {
continue;
}
Rect2 rect = child->get_rect();
+
+ // To prevent intersections with other nodes.
+ rect.position *= zoom;
+ rect.size *= zoom;
+
if (rect.has_point(p_mouse_pos)) {
//check sub-controls
Vector2 subpos = p_mouse_pos - rect.position;
@@ -1081,13 +1114,13 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
if (!gn->is_selected() && box_selection_mode_additive) {
emit_signal("node_selected", gn);
} else if (gn->is_selected() && !box_selection_mode_additive) {
- emit_signal("node_unselected", gn);
+ emit_signal("node_deselected", gn);
}
gn->set_selected(box_selection_mode_additive);
} else {
bool select = (previus_selected.find(gn) != nullptr);
if (gn->is_selected() && !select) {
- emit_signal("node_unselected", gn);
+ emit_signal("node_deselected", gn);
} else if (!gn->is_selected() && select) {
emit_signal("node_selected", gn);
}
@@ -1112,7 +1145,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
bool select = (previus_selected.find(gn) != nullptr);
if (gn->is_selected() && !select) {
- emit_signal("node_unselected", gn);
+ emit_signal("node_deselected", gn);
} else if (!gn->is_selected() && select) {
emit_signal("node_selected", gn);
}
@@ -1141,7 +1174,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
Rect2 r = gn->get_rect();
r.size *= zoom;
if (r.has_point(b->get_position())) {
- emit_signal("node_unselected", gn);
+ emit_signal("node_deselected", gn);
gn->set_selected(false);
}
}
@@ -1181,7 +1214,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
continue;
}
- if (gn_selected->has_point(b->get_position() - gn_selected->get_position())) {
+ if (gn_selected->has_point((b->get_position() - gn_selected->get_position()) / zoom)) {
gn = gn_selected;
break;
}
@@ -1204,7 +1237,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
o_gn->set_selected(true);
} else {
if (o_gn->is_selected()) {
- emit_signal("node_unselected", o_gn);
+ emit_signal("node_deselected", o_gn);
}
o_gn->set_selected(false);
}
@@ -1264,7 +1297,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
continue;
}
if (gn2->is_selected()) {
- emit_signal("node_unselected", gn2);
+ emit_signal("node_deselected", gn2);
}
gn2->set_selected(false);
}
@@ -1302,25 +1335,17 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
}
- Ref<InputEventKey> k = p_ev;
-
- if (k.is_valid()) {
- if (k->get_keycode() == KEY_D && k->is_pressed() && k->get_command()) {
+ if (p_ev->is_pressed()) {
+ if (p_ev->is_action("ui_graph_duplicate")) {
emit_signal("duplicate_nodes_request");
accept_event();
- }
-
- if (k->get_keycode() == KEY_C && k->is_pressed() && k->get_command()) {
+ } else if (p_ev->is_action("ui_copy")) {
emit_signal("copy_nodes_request");
accept_event();
- }
-
- if (k->get_keycode() == KEY_V && k->is_pressed() && k->get_command()) {
+ } else if (p_ev->is_action("ui_paste")) {
emit_signal("paste_nodes_request");
accept_event();
- }
-
- if (k->get_keycode() == KEY_DELETE && k->is_pressed()) {
+ } else if (p_ev->is_action("ui_graph_delete")) {
emit_signal("delete_nodes_request");
accept_event();
}
@@ -1533,7 +1558,12 @@ bool GraphEdit::is_minimap_enabled() const {
}
void GraphEdit::_minimap_toggled() {
- minimap->update();
+ if (is_minimap_enabled()) {
+ minimap->set_visible(true);
+ minimap->update();
+ } else {
+ minimap->set_visible(false);
+ }
}
void GraphEdit::set_connection_lines_thickness(float p_thickness) {
@@ -1576,7 +1606,7 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_valid_connection_type", "from_type", "to_type"), &GraphEdit::remove_valid_connection_type);
ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type);
- ClassDB::bind_method(D_METHOD("set_zoom", "p_zoom"), &GraphEdit::set_zoom);
+ ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom);
ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom);
ClassDB::bind_method(D_METHOD("set_snap", "pixels"), &GraphEdit::set_snap);
@@ -1591,9 +1621,9 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_connection_lines_antialiased", "pixels"), &GraphEdit::set_connection_lines_antialiased);
ClassDB::bind_method(D_METHOD("is_connection_lines_antialiased"), &GraphEdit::is_connection_lines_antialiased);
- ClassDB::bind_method(D_METHOD("set_minimap_size", "p_size"), &GraphEdit::set_minimap_size);
+ ClassDB::bind_method(D_METHOD("set_minimap_size", "size"), &GraphEdit::set_minimap_size);
ClassDB::bind_method(D_METHOD("get_minimap_size"), &GraphEdit::get_minimap_size);
- ClassDB::bind_method(D_METHOD("set_minimap_opacity", "p_opacity"), &GraphEdit::set_minimap_opacity);
+ ClassDB::bind_method(D_METHOD("set_minimap_opacity", "opacity"), &GraphEdit::set_minimap_opacity);
ClassDB::bind_method(D_METHOD("get_minimap_opacity"), &GraphEdit::get_minimap_opacity);
ClassDB::bind_method(D_METHOD("set_minimap_enabled", "enable"), &GraphEdit::set_minimap_enabled);
@@ -1628,7 +1658,7 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("copy_nodes_request"));
ADD_SIGNAL(MethodInfo("paste_nodes_request"));
ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
- ADD_SIGNAL(MethodInfo("node_unselected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
+ ADD_SIGNAL(MethodInfo("node_deselected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
ADD_SIGNAL(MethodInfo("delete_nodes_request"));
@@ -1640,8 +1670,6 @@ void GraphEdit::_bind_methods() {
GraphEdit::GraphEdit() {
set_focus_mode(FOCUS_ALL);
- awaiting_scroll_offset_update = false;
- top_layer = nullptr;
top_layer = memnew(GraphEditFilter(this));
add_child(top_layer);
top_layer->set_mouse_filter(MOUSE_FILTER_PASS);
@@ -1664,13 +1692,6 @@ GraphEdit::GraphEdit() {
v_scroll->set_name("_v_scroll");
top_layer->add_child(v_scroll);
- updating = false;
- connecting = false;
- right_disconnects = false;
-
- box_selecting = false;
- dragging = false;
-
//set large minmax so it can scroll even if not resized yet
h_scroll->set_min(-10000);
h_scroll->set_max(10000);
@@ -1681,8 +1702,6 @@ GraphEdit::GraphEdit() {
h_scroll->connect("value_changed", callable_mp(this, &GraphEdit::_scroll_moved));
v_scroll->connect("value_changed", callable_mp(this, &GraphEdit::_scroll_moved));
- zoom = 1;
-
zoom_hb = memnew(HBoxContainer);
top_layer->add_child(zoom_hb);
zoom_hb->set_position(Vector2(10, 10));
@@ -1741,7 +1760,7 @@ GraphEdit::GraphEdit() {
top_layer->add_child(minimap);
minimap->set_name("_minimap");
minimap->set_modulate(Color(1, 1, 1, minimap_opacity));
- minimap->set_mouse_filter(MOUSE_FILTER_STOP);
+ minimap->set_mouse_filter(MOUSE_FILTER_PASS);
minimap->set_custom_minimum_size(Vector2(50, 50));
minimap->set_size(minimap_size);
minimap->set_anchors_preset(Control::PRESET_BOTTOM_RIGHT);
@@ -1751,7 +1770,5 @@ GraphEdit::GraphEdit() {
minimap->set_offset(Side::SIDE_BOTTOM, -MINIMAP_OFFSET);
minimap->connect("draw", callable_mp(this, &GraphEdit::_minimap_draw));
- setting_scroll_ofs = false;
- just_disconnected = false;
set_clip_contents(true);
}
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index d081789784..8fdf975319 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -99,9 +99,9 @@ public:
struct Connection {
StringName from;
StringName to;
- int from_port;
- int to_port;
- float activity;
+ int from_port = 0;
+ int to_port = 0;
+ float activity = 0.0;
};
private:
@@ -121,41 +121,41 @@ private:
HScrollBar *h_scroll;
VScrollBar *v_scroll;
- float port_grab_distance_horizontal;
+ float port_grab_distance_horizontal = 0.0;
float port_grab_distance_vertical;
- bool connecting;
+ bool connecting = false;
String connecting_from;
- bool connecting_out;
- int connecting_index;
- int connecting_type;
+ bool connecting_out = false;
+ int connecting_index = 0;
+ int connecting_type = 0;
Color connecting_color;
- bool connecting_target;
+ bool connecting_target = false;
Vector2 connecting_to;
String connecting_target_to;
int connecting_target_index;
- bool just_disconnected;
- bool connecting_valid;
+ bool just_disconnected = false;
+ bool connecting_valid = false;
Vector2 click_pos;
- bool dragging;
- bool just_selected;
- bool moving_selection;
+ bool dragging = false;
+ bool just_selected = false;
+ bool moving_selection = false;
Vector2 drag_accum;
- float zoom;
+ float zoom = 1.0;
- bool box_selecting;
- bool box_selection_mode_additive;
+ bool box_selecting = false;
+ bool box_selection_mode_additive = false;
Point2 box_selecting_from;
Point2 box_selecting_to;
Rect2 box_selecting_rect;
List<GraphNode *> previus_selected;
- bool setting_scroll_ofs;
- bool right_disconnects;
- bool updating;
- bool awaiting_scroll_offset_update;
+ bool setting_scroll_ofs = false;
+ bool right_disconnects = false;
+ bool updating = false;
+ bool awaiting_scroll_offset_update = false;
List<Connection> connections;
float lines_thickness = 2.0f;
@@ -167,6 +167,7 @@ private:
void _graph_node_raised(Node *p_gn);
void _graph_node_moved(Node *p_gn);
+ void _graph_node_slot_updated(int p_index, Node *p_gn);
void _update_scroll();
void _scroll_moved(double);
@@ -194,7 +195,7 @@ private:
uint32_t type_a;
uint32_t type_b;
};
- uint64_t key;
+ uint64_t key = 0;
};
bool operator<(const ConnType &p_type) const {
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index eaee086b81..b615cdb266 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,7 +51,7 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
update();
}
}
- _change_notify();
+ notify_property_list_changed();
return true;
}
@@ -71,6 +71,8 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
si.enable_left = p_value;
} else if (what == "left_type") {
si.type_left = p_value;
+ } else if (what == "left_icon") {
+ si.custom_slot_left = p_value;
} else if (what == "left_color") {
si.color_left = p_value;
} else if (what == "right_enabled") {
@@ -79,11 +81,13 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
si.type_right = p_value;
} else if (what == "right_color") {
si.color_right = p_value;
+ } else if (what == "right_icon") {
+ si.custom_slot_right = p_value;
} else {
return false;
}
- set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right);
+ set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right, si.custom_slot_left, si.custom_slot_right);
update();
return true;
}
@@ -120,12 +124,16 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = si.type_left;
} else if (what == "left_color") {
r_ret = si.color_left;
+ } else if (what == "left_icon") {
+ r_ret = si.custom_slot_left;
} else if (what == "right_enabled") {
r_ret = si.enable_right;
} else if (what == "right_type") {
r_ret = si.type_right;
} else if (what == "right_color") {
r_ret = si.color_right;
+ } else if (what == "right_icon") {
+ r_ret = si.custom_slot_right;
} else {
return false;
}
@@ -152,9 +160,11 @@ void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::BOOL, base + "left_enabled"));
p_list->push_back(PropertyInfo(Variant::INT, base + "left_type"));
p_list->push_back(PropertyInfo(Variant::COLOR, base + "left_color"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, base + "left_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
p_list->push_back(PropertyInfo(Variant::BOOL, base + "right_enabled"));
p_list->push_back(PropertyInfo(Variant::INT, base + "right_type"));
p_list->push_back(PropertyInfo(Variant::COLOR, base + "right_color"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, base + "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
idx++;
}
@@ -355,7 +365,9 @@ void GraphNode::_shape() {
void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right) {
ERR_FAIL_COND(p_idx < 0);
- if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) && !p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1)) {
+ if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) &&
+ !p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1) &&
+ !p_custom_left.is_valid() && !p_custom_right.is_valid()) {
slot_info.erase(p_idx);
return;
}
@@ -372,6 +384,8 @@ void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const C
slot_info[p_idx] = s;
update();
connpos_dirty = true;
+
+ emit_signal("slot_updated", p_idx);
}
void GraphNode::clear_slot(int p_idx) {
@@ -472,7 +486,6 @@ void GraphNode::set_title(const String &p_title) {
_shape();
update();
- _change_notify("title");
minimum_size_changed();
}
@@ -826,6 +839,7 @@ void GraphNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "overlay", PROPERTY_HINT_ENUM, "Disabled,Breakpoint,Position"), "set_overlay", "get_overlay");
ADD_SIGNAL(MethodInfo("position_offset_changed"));
+ ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx")));
ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to")));
ADD_SIGNAL(MethodInfo("raise_request"));
ADD_SIGNAL(MethodInfo("close_request"));
@@ -838,12 +852,5 @@ void GraphNode::_bind_methods() {
GraphNode::GraphNode() {
title_buf.instance();
- overlay = OVERLAY_DISABLED;
- show_close = false;
- connpos_dirty = true;
set_mouse_filter(MOUSE_FILTER_STOP);
- comment = false;
- resizable = false;
- resizing = false;
- selected = false;
}
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index 08ae0d465d..1bc54dddb7 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,23 +46,14 @@ public:
private:
struct Slot {
- bool enable_left;
- int type_left;
- Color color_left;
- bool enable_right;
- int type_right;
- Color color_right;
+ bool enable_left = false;
+ int type_left = 0;
+ Color color_left = Color(1, 1, 1, 1);
+ bool enable_right = false;
+ int type_right = 0;
+ Color color_right = Color(1, 1, 1, 1);
Ref<Texture2D> custom_slot_left;
Ref<Texture2D> custom_slot_right;
-
- Slot() {
- enable_left = false;
- type_left = 0;
- color_left = Color(1, 1, 1, 1);
- enable_right = false;
- type_right = 0;
- color_right = Color(1, 1, 1, 1);
- }
};
String title;
@@ -72,12 +63,12 @@ private:
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
- bool show_close;
+ bool show_close = false;
Vector2 position_offset;
- bool comment;
- bool resizable;
+ bool comment = false;
+ bool resizable = false;
- bool resizing;
+ bool resizing = false;
Vector2 resizing_from;
Vector2 resizing_from_size;
@@ -87,7 +78,7 @@ private:
struct ConnCache {
Vector2 pos;
- int type;
+ int type = 0;
Color color;
};
@@ -96,16 +87,16 @@ private:
Map<int, Slot> slot_info;
- bool connpos_dirty;
+ bool connpos_dirty = true;
void _connpos_update();
void _resort();
void _shape();
Vector2 drag_from;
- bool selected;
+ bool selected = false;
- Overlay overlay;
+ Overlay overlay = OVERLAY_DISABLED;
protected:
void _gui_input(const Ref<InputEvent> &p_ev);
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index a08a348a18..541925a802 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -261,6 +261,4 @@ Size2 GridContainer::get_minimum_size() const {
return ms;
}
-GridContainer::GridContainer() {
- columns = 1;
-}
+GridContainer::GridContainer() {}
diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h
index 79d4aee284..9b43a5bc7e 100644
--- a/scene/gui/grid_container.h
+++ b/scene/gui/grid_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class GridContainer : public Container {
GDCLASS(GridContainer, Container);
- int columns;
+ int columns = 1;
protected:
void _notification(int p_what);
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index e0aef32e15..7afc04c51c 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,7 +50,7 @@ void ItemList::_shape(int p_idx) {
}
}
-void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) {
+int ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) {
Item item;
item.icon = p_texture;
item.icon_transposed = false;
@@ -64,14 +64,16 @@ void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, b
item.tooltip_enabled = true;
item.custom_bg = Color(0, 0, 0, 0);
items.push_back(item);
+ int item_id = items.size() - 1;
_shape(items.size() - 1);
update();
shape_changed = true;
+ return item_id;
}
-void ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) {
+int ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) {
Item item;
item.icon = p_item;
item.icon_transposed = false;
@@ -85,9 +87,11 @@ void ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) {
item.tooltip_enabled = true;
item.custom_bg = Color(0, 0, 0, 0);
items.push_back(item);
+ int item_id = items.size() - 1;
update();
shape_changed = true;
+ return item_id;
}
void ItemList::set_item_text(int p_idx, const String &p_text) {
@@ -333,7 +337,7 @@ void ItemList::select(int p_idx, bool p_single) {
update();
}
-void ItemList::unselect(int p_idx) {
+void ItemList::deselect(int p_idx) {
ERR_FAIL_INDEX(p_idx, items.size());
if (select_mode != SELECT_MULTI) {
@@ -345,7 +349,7 @@ void ItemList::unselect(int p_idx) {
update();
}
-void ItemList::unselect_all() {
+void ItemList::deselect_all() {
if (items.size() < 1) {
return;
}
@@ -573,7 +577,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
int i = closest;
if (select_mode == SELECT_MULTI && items[i].selected && mb->get_command()) {
- unselect(i);
+ deselect(i);
emit_signal("multi_selected", i, false);
} else if (select_mode == SELECT_MULTI && mb->get_shift() && current >= 0 && current < items.size() && current != i) {
@@ -759,7 +763,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
select(current, false);
emit_signal("multi_selected", current, true);
} else if (items[current].selected) {
- unselect(current);
+ deselect(current);
emit_signal("multi_selected", current, false);
}
}
@@ -879,6 +883,8 @@ void ItemList::_notification(int p_what) {
int vseparation = get_theme_constant("vseparation");
int icon_margin = get_theme_constant("icon_margin");
int line_separation = get_theme_constant("line_separation");
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
Ref<StyleBox> sbsel = has_focus() ? get_theme_stylebox("selected_focus") : get_theme_stylebox("selected");
Ref<StyleBox> cursor = has_focus() ? get_theme_stylebox("cursor") : get_theme_stylebox("cursor_unfocused");
@@ -886,7 +892,7 @@ void ItemList::_notification(int p_what) {
Color guide_color = get_theme_color("guide_color");
Color font_color = get_theme_color("font_color");
- Color font_color_selected = get_theme_color("font_color_selected");
+ Color font_selected_color = get_theme_color("font_selected_color");
if (has_focus()) {
RenderingServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(), true);
@@ -895,7 +901,7 @@ void ItemList::_notification(int p_what) {
}
if (shape_changed) {
- float max_column_width = 0;
+ float max_column_width = 0.0;
//1- compute item minimum sizes
for (int i = 0; i < items.size(); i++) {
@@ -1184,13 +1190,12 @@ void ItemList::_notification(int p_what) {
max_len = size2.x;
}
- Color modulate = items[i].selected ? font_color_selected : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color);
+ Color modulate = items[i].selected ? font_selected_color : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color);
if (items[i].disabled) {
modulate.a *= 0.5;
}
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
- text_ofs = text_ofs.floor();
text_ofs += base_ofs;
text_ofs += items[i].rect_cache.position;
@@ -1201,6 +1206,10 @@ void ItemList::_notification(int p_what) {
items.write[i].text_buf->set_width(max_len);
items.write[i].text_buf->set_align(HALIGN_CENTER);
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, outline_size, font_outline_color);
+ }
+
items[i].text_buf->draw(get_canvas_item(), text_ofs, modulate);
} else {
if (fixed_column_width > 0) {
@@ -1213,7 +1222,6 @@ void ItemList::_notification(int p_what) {
text_ofs.y += (items[i].rect_cache.size.height - size2.y) / 2;
}
- text_ofs = text_ofs.floor();
text_ofs += base_ofs;
text_ofs += items[i].rect_cache.position;
@@ -1228,6 +1236,11 @@ void ItemList::_notification(int p_what) {
} else {
items.write[i].text_buf->set_align(HALIGN_LEFT);
}
+
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ items[i].text_buf->draw_outline(get_canvas_item(), text_ofs, outline_size, font_outline_color);
+ }
+
items[i].text_buf->draw(get_canvas_item(), text_ofs, modulate);
}
}
@@ -1314,7 +1327,7 @@ int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const {
}
bool ItemList::is_pos_at_end_of_items(const Point2 &p_pos) const {
- if (items.empty()) {
+ if (items.is_empty()) {
return true;
}
@@ -1519,8 +1532,8 @@ void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_tooltip", "idx"), &ItemList::get_item_tooltip);
ClassDB::bind_method(D_METHOD("select", "idx", "single"), &ItemList::select, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("unselect", "idx"), &ItemList::unselect);
- ClassDB::bind_method(D_METHOD("unselect_all"), &ItemList::unselect_all);
+ ClassDB::bind_method(D_METHOD("deselect", "idx"), &ItemList::deselect);
+ ClassDB::bind_method(D_METHOD("deselect_all"), &ItemList::deselect_all);
ClassDB::bind_method(D_METHOD("is_selected", "idx"), &ItemList::is_selected);
ClassDB::bind_method(D_METHOD("get_selected_items"), &ItemList::get_selected_items);
@@ -1613,34 +1626,12 @@ void ItemList::_bind_methods() {
}
ItemList::ItemList() {
- current = -1;
-
- select_mode = SELECT_SINGLE;
- icon_mode = ICON_MODE_LEFT;
-
- fixed_column_width = 0;
- same_column_width = false;
- max_text_lines = 1;
- max_columns = 1;
- auto_height = false;
- auto_height_value = 0.0f;
-
scroll_bar = memnew(VScrollBar);
add_child(scroll_bar);
- shape_changed = true;
scroll_bar->connect("value_changed", callable_mp(this, &ItemList::_scroll_changed));
set_focus_mode(FOCUS_ALL);
- current_columns = 1;
- search_time_msec = 0;
- ensure_selected_visible = false;
- defer_select_single = -1;
- allow_rmb_select = false;
- allow_reselect = false;
- do_autoscroll_to_bottom = false;
-
- icon_scale = 1.0f;
set_clip_contents(true);
}
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index 9684ce0a32..86a0174a20 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -52,7 +52,7 @@ public:
private:
struct Item {
Ref<Texture2D> icon;
- bool icon_transposed;
+ bool icon_transposed = false;
Rect2i icon_region;
Color icon_modulate;
Ref<Texture2D> tag_icon;
@@ -62,10 +62,10 @@ private:
String language;
TextDirection text_direction = TEXT_DIRECTION_AUTO;
- bool selectable;
- bool selected;
- bool disabled;
- bool tooltip_enabled;
+ bool selectable = false;
+ bool selected = false;
+ bool disabled = false;
+ bool tooltip_enabled = false;
Variant metadata;
String tooltip;
Color custom_fg;
@@ -79,44 +79,44 @@ private:
bool operator<(const Item &p_another) const { return text < p_another.text; }
};
- int current;
+ int current = -1;
- bool shape_changed;
+ bool shape_changed = true;
- bool ensure_selected_visible;
- bool same_column_width;
+ bool ensure_selected_visible = false;
+ bool same_column_width = false;
- bool auto_height;
- float auto_height_value;
+ bool auto_height = false;
+ float auto_height_value = 0.0;
Vector<Item> items;
Vector<int> separators;
- SelectMode select_mode;
- IconMode icon_mode;
+ SelectMode select_mode = SELECT_SINGLE;
+ IconMode icon_mode = ICON_MODE_LEFT;
VScrollBar *scroll_bar;
- uint64_t search_time_msec;
+ uint64_t search_time_msec = 0;
String search_string;
- int current_columns;
- int fixed_column_width;
- int max_text_lines;
- int max_columns;
+ int current_columns = 1;
+ int fixed_column_width = 0;
+ int max_text_lines = 1;
+ int max_columns = 1;
Size2 fixed_icon_size;
Size2 max_item_size_cache;
- int defer_select_single;
+ int defer_select_single = -1;
- bool allow_rmb_select;
+ bool allow_rmb_select = false;
- bool allow_reselect;
+ bool allow_reselect = false;
- real_t icon_scale;
+ real_t icon_scale = 1.0;
- bool do_autoscroll_to_bottom;
+ bool do_autoscroll_to_bottom = false;
Array _get_items() const;
void _set_items(const Array &p_items);
@@ -130,8 +130,8 @@ protected:
static void _bind_methods();
public:
- void add_item(const String &p_item, const Ref<Texture2D> &p_texture = Ref<Texture2D>(), bool p_selectable = true);
- void add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable = true);
+ int add_item(const String &p_item, const Ref<Texture2D> &p_texture = Ref<Texture2D>(), bool p_selectable = true);
+ int add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable = true);
void set_item_text(int p_idx, const String &p_text);
String get_item_text(int p_idx) const;
@@ -183,8 +183,8 @@ public:
Color get_item_custom_fg_color(int p_idx) const;
void select(int p_idx, bool p_single = true);
- void unselect(int p_idx);
- void unselect_all();
+ void deselect(int p_idx);
+ void deselect_all();
bool is_selected(int p_idx) const;
Vector<int> get_selected_items();
bool is_anything_selected();
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index d70f07c0a8..be73fd8f51 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -184,17 +184,17 @@ void Label::_notification(int p_what) {
Ref<StyleBox> style = get_theme_stylebox("normal");
Ref<Font> font = get_theme_font("font");
Color font_color = get_theme_color("font_color");
- Color font_color_shadow = get_theme_color("font_color_shadow");
+ Color font_shadow_color = get_theme_color("font_shadow_color");
Point2 shadow_ofs(get_theme_constant("shadow_offset_x"), get_theme_constant("shadow_offset_y"));
int line_spacing = get_theme_constant("line_spacing");
- Color font_outline_modulate = get_theme_color("font_outline_modulate");
+ Color font_outline_color = get_theme_color("font_outline_color");
int outline_size = get_theme_constant("outline_size");
int shadow_outline_size = get_theme_constant("shadow_outline_size");
bool rtl = is_layout_rtl();
style->draw(ci, Rect2(Point2(0, 0), get_size()));
- float total_h = 0;
+ float total_h = 0.0;
int lines_visible = 0;
// Get number of lines to fit to the height.
@@ -260,7 +260,8 @@ void Label::_notification(int p_what) {
}
}
}
- visible_glyphs = total_glyphs * percent_visible;
+
+ visible_glyphs = MIN(total_glyphs, visible_chars);
}
Vector2 ofs;
@@ -298,17 +299,17 @@ void Label::_notification(int p_what) {
for (int j = 0; j < gl_size; j++) {
for (int k = 0; k < glyphs[j].repeat; k++) {
if (glyphs[j].font_rid != RID()) {
- if (font_color_shadow.a > 0) {
- TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + shadow_ofs, glyphs[j].index, font_color_shadow);
+ if (font_shadow_color.a > 0) {
+ TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + shadow_ofs, glyphs[j].index, font_shadow_color);
if (shadow_outline_size > 0) {
//draw shadow
- TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(-shadow_ofs.x, shadow_ofs.y), glyphs[j].index, font_color_shadow);
- TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(shadow_ofs.x, -shadow_ofs.y), glyphs[j].index, font_color_shadow);
- TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(-shadow_ofs.x, -shadow_ofs.y), glyphs[j].index, font_color_shadow);
+ TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(-shadow_ofs.x, shadow_ofs.y), glyphs[j].index, font_shadow_color);
+ TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(shadow_ofs.x, -shadow_ofs.y), glyphs[j].index, font_shadow_color);
+ TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, shadow_outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off) + Vector2(-shadow_ofs.x, -shadow_ofs.y), glyphs[j].index, font_shadow_color);
}
}
- if (font_outline_modulate.a != 0.0 && outline_size > 0) {
- TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off), glyphs[j].index, font_outline_modulate);
+ if (font_outline_color.a != 0.0 && outline_size > 0) {
+ TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, outline_size, ofs + Vector2(glyphs[j].x_off, glyphs[j].y_off), glyphs[j].index, font_outline_color);
}
}
ofs.x += glyphs[j].advance;
@@ -357,21 +358,25 @@ void Label::_notification(int p_what) {
}
Size2 Label::get_minimum_size() const {
- Size2 min_style = get_theme_stylebox("normal")->get_minimum_size();
-
// don't want to mutable everything
if (dirty || lines_dirty) {
const_cast<Label *>(this)->_shape();
}
+ Size2 min_size = minsize;
+
+ Ref<Font> font = get_theme_font("font");
+ min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size("font_size")) + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM));
+
+ Size2 min_style = get_theme_stylebox("normal")->get_minimum_size();
if (autowrap) {
- return Size2(1, clip ? 1 : minsize.height) + min_style;
+ return Size2(1, clip ? 1 : min_size.height) + min_style;
} else {
- Size2 ms = minsize;
if (clip) {
- ms.width = 1;
+ min_size.width = 1;
}
- return ms + min_style;
+
+ return min_size + min_style;
}
}
@@ -391,7 +396,7 @@ int Label::get_visible_line_count() const {
Ref<StyleBox> style = get_theme_stylebox("normal");
int line_spacing = get_theme_constant("line_spacing");
int lines_visible = 0;
- float total_h = 0;
+ float total_h = 0.0;
for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM) + line_spacing;
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
@@ -537,8 +542,9 @@ void Label::set_visible_characters(int p_amount) {
visible_chars = p_amount;
if (get_total_character_count() > 0) {
percent_visible = (float)p_amount / (float)get_total_character_count();
+ } else {
+ percent_visible = 1.0;
}
- _change_notify("percent_visible");
update();
}
@@ -555,7 +561,6 @@ void Label::set_percent_visible(float p_percent) {
visible_chars = get_total_character_count() * p_percent;
percent_visible = p_percent;
}
- _change_notify("visible_chars");
update();
}
@@ -564,6 +569,7 @@ float Label::get_percent_visible() const {
}
void Label::set_lines_skipped(int p_lines) {
+ ERR_FAIL_COND(p_lines < 0);
lines_skipped = p_lines;
_update_visible();
update();
@@ -610,7 +616,7 @@ bool Label::_set(const StringName &p_name, const Variant &p_value) {
update();
}
}
- _change_notify();
+ notify_property_list_changed();
return true;
}
diff --git a/scene/gui/label.h b/scene/gui/label.h
index 386297f582..032b4112e1 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -72,7 +72,7 @@ private:
Control::StructuredTextParser st_parser = STRUCTURED_TEXT_DEFAULT;
Array st_args;
- float percent_visible = 1;
+ float percent_visible = 1.0;
int visible_chars = -1;
int lines_skipped = 0;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index e623ba987f..830ffc092f 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,6 +30,7 @@
#include "line_edit.h"
+#include "core/input/input_map.h"
#include "core/object/message_queue.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -44,6 +45,175 @@
#endif
#include "scene/main/window.h"
+void LineEdit::_swap_current_input_direction() {
+ if (input_direction == TEXT_DIRECTION_LTR) {
+ input_direction = TEXT_DIRECTION_RTL;
+ } else {
+ input_direction = TEXT_DIRECTION_LTR;
+ }
+ set_cursor_position(get_cursor_position());
+ update();
+}
+
+void LineEdit::_move_cursor_left(bool p_select, bool p_move_by_word) {
+ if (selection.enabled && !p_select) {
+ set_cursor_position(selection.begin);
+ deselect();
+ return;
+ }
+
+ shift_selection_check_pre(p_select);
+
+ if (p_move_by_word) {
+ int cc = cursor_pos;
+
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
+ for (int i = words.size() - 1; i >= 0; i--) {
+ if (words[i].x < cc) {
+ cc = words[i].x;
+ break;
+ }
+ }
+
+ set_cursor_position(cc);
+ } else {
+ if (mid_grapheme_caret_enabled) {
+ set_cursor_position(get_cursor_position() - 1);
+ } else {
+ set_cursor_position(TS->shaped_text_prev_grapheme_pos(text_rid, get_cursor_position()));
+ }
+ }
+
+ shift_selection_check_post(p_select);
+}
+
+void LineEdit::_move_cursor_right(bool p_select, bool p_move_by_word) {
+ if (selection.enabled && !p_select) {
+ set_cursor_position(selection.end);
+ deselect();
+ return;
+ }
+
+ shift_selection_check_pre(p_select);
+
+ if (p_move_by_word) {
+ int cc = cursor_pos;
+
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
+ for (int i = 0; i < words.size(); i++) {
+ if (words[i].y > cc) {
+ cc = words[i].y;
+ break;
+ }
+ }
+
+ set_cursor_position(cc);
+ } else {
+ if (mid_grapheme_caret_enabled) {
+ set_cursor_position(get_cursor_position() + 1);
+ } else {
+ set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, get_cursor_position()));
+ }
+ }
+
+ shift_selection_check_post(p_select);
+}
+
+void LineEdit::_move_cursor_start(bool p_select) {
+ shift_selection_check_pre(p_select);
+ set_cursor_position(0);
+ shift_selection_check_post(p_select);
+}
+
+void LineEdit::_move_cursor_end(bool p_select) {
+ shift_selection_check_pre(p_select);
+ set_cursor_position(text.length());
+ shift_selection_check_post(p_select);
+}
+
+void LineEdit::_backspace(bool p_word, bool p_all_to_left) {
+ if (!editable) {
+ return;
+ }
+
+ if (p_all_to_left) {
+ deselect();
+ text = text.substr(0, cursor_pos);
+ _text_changed();
+ return;
+ }
+
+ if (selection.enabled) {
+ selection_delete();
+ return;
+ }
+
+ if (p_word) {
+ int cc = cursor_pos;
+
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
+ for (int i = words.size() - 1; i >= 0; i--) {
+ if (words[i].x < cc) {
+ cc = words[i].x;
+ }
+ }
+
+ delete_text(cc, cursor_pos);
+
+ set_cursor_position(cc);
+ } else {
+ delete_char();
+ }
+}
+
+void LineEdit::_delete(bool p_word, bool p_all_to_right) {
+ if (!editable) {
+ return;
+ }
+
+ if (p_all_to_right) {
+ deselect();
+ text = text.substr(cursor_pos, text.length() - cursor_pos);
+ _shape();
+ set_cursor_position(0);
+ _text_changed();
+ return;
+ }
+
+ if (selection.enabled) {
+ selection_delete();
+ return;
+ }
+
+ int text_len = text.length();
+
+ if (cursor_pos == text_len) {
+ return; // Nothing to do.
+ }
+
+ if (p_word) {
+ int cc = cursor_pos;
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
+ for (int i = 0; i < words.size(); i++) {
+ if (words[i].y > cc) {
+ cc = words[i].y;
+ break;
+ }
+ }
+
+ delete_text(cursor_pos, cc);
+ } else {
+ if (mid_grapheme_caret_enabled) {
+ set_cursor_position(cursor_pos + 1);
+ delete_char();
+ } else {
+ int cc = cursor_pos;
+ set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, cursor_pos));
+ delete_text(cc, cursor_pos);
+ }
+ }
+}
+
void LineEdit::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> b = p_event;
@@ -55,7 +225,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && context_menu_enabled) {
menu->set_position(get_screen_transform().xform(get_local_mouse_position()));
menu->set_size(Vector2(1, 1));
- //menu->set_scale(get_global_transform().get_scale());
+ _generate_context_menu();
menu->popup();
grab_focus();
accept_event();
@@ -69,7 +239,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
_reset_caret_blink_timer();
if (b->is_pressed()) {
accept_event(); //don't pass event further when clicked on text field
- if (!text.empty() && is_editable() && _is_over_clear_button(b->get_position())) {
+ if (!text.is_empty() && is_editable() && _is_over_clear_button(b->get_position())) {
clear_button_status.press_attempt = true;
clear_button_status.pressing_inside = true;
update();
@@ -85,11 +255,30 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
selection.creating = true;
} else {
- if (b->is_doubleclick() && selecting_enabled) {
- selection.enabled = true;
- selection.begin = 0;
- selection.end = text.length();
- selection.doubleclick = true;
+ if (selecting_enabled) {
+ if (!b->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - selection.last_dblclk) < 600) {
+ // Triple-click select all.
+ selection.enabled = true;
+ selection.begin = 0;
+ selection.end = text.length();
+ selection.doubleclick = true;
+ selection.last_dblclk = 0;
+ cursor_pos = selection.begin;
+ } else if (b->is_doubleclick()) {
+ // Double-click select word.
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
+ for (int i = 0; i < words.size(); i++) {
+ if (words[i].x < cursor_pos && words[i].y > cursor_pos) {
+ selection.enabled = true;
+ selection.begin = words[i].x;
+ selection.end = words[i].y;
+ selection.doubleclick = true;
+ selection.last_dblclk = OS::get_singleton()->get_ticks_msec();
+ cursor_pos = selection.end;
+ break;
+ }
+ }
+ }
}
selection.drag_attempt = false;
@@ -106,7 +295,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
update();
} else {
- if (!text.empty() && is_editable() && clear_button_enabled) {
+ if (!text.is_empty() && is_editable() && clear_button_enabled) {
bool press_attempt = clear_button_status.press_attempt;
clear_button_status.press_attempt = false;
if (press_attempt && clear_button_status.pressing_inside && _is_over_clear_button(b->get_position())) {
@@ -121,13 +310,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
selection.creating = false;
selection.doubleclick = false;
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
- if (selection.enabled) {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end);
- } else {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos);
- }
- }
+ show_virtual_keyboard();
}
update();
@@ -136,7 +319,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
- if (!text.empty() && is_editable() && clear_button_enabled) {
+ if (!text.is_empty() && is_editable() && clear_button_enabled) {
bool last_press_inside = clear_button_status.pressing_inside;
clear_button_status.pressing_inside = clear_button_status.press_attempt && _is_over_clear_button(m->get_position());
if (last_press_inside != clear_button_status.pressing_inside) {
@@ -159,453 +342,163 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
return;
}
-#ifdef APPLE_STYLE_KEYS
- if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) {
- uint32_t remap_key = KEY_UNKNOWN;
- switch (k->get_keycode()) {
- case KEY_F: {
- remap_key = KEY_RIGHT;
- } break;
- case KEY_B: {
- remap_key = KEY_LEFT;
- } break;
- case KEY_P: {
- remap_key = KEY_UP;
- } break;
- case KEY_N: {
- remap_key = KEY_DOWN;
- } break;
- case KEY_D: {
- remap_key = KEY_DELETE;
- } break;
- case KEY_H: {
- remap_key = KEY_BACKSPACE;
- } break;
- case KEY_A: {
- remap_key = KEY_HOME;
- } break;
- case KEY_E: {
- remap_key = KEY_END;
- } break;
+ if (context_menu_enabled) {
+ if (k->is_action("ui_menu", true)) {
+ Point2 pos = Point2(get_cursor_pixel_pos().x, (get_size().y + get_theme_font("font")->get_height(get_theme_font_size("font_size"))) / 2);
+ menu->set_position(get_global_transform().xform(pos));
+ menu->set_size(Vector2(1, 1));
+ _generate_context_menu();
+ menu->popup();
+ menu->grab_focus();
}
+ }
- if (remap_key != KEY_UNKNOWN) {
- k->set_keycode(remap_key);
- k->set_control(false);
+ // Default is ENTER, KP_ENTER. Cannot use ui_accept as default includes SPACE
+ if (k->is_action("ui_text_newline", true)) {
+ emit_signal("text_entered", text);
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
+ DisplayServer::get_singleton()->virtual_keyboard_hide();
}
}
-#endif
-
- unsigned int code = k->get_keycode();
-
- if (k->get_command() && is_shortcut_keys_enabled()) {
- bool handled = true;
-
- switch (code) {
- case (KEY_QUOTELEFT): { // Swap current input direction (primary cursor)
-
- if (input_direction == TEXT_DIRECTION_LTR) {
- input_direction = TEXT_DIRECTION_RTL;
- } else {
- input_direction = TEXT_DIRECTION_LTR;
- }
- set_cursor_position(get_cursor_position());
- update();
-
- } break;
-
- case (KEY_X): { // CUT.
-
- if (editable) {
- cut_text();
- }
-
- } break;
-
- case (KEY_C): { // COPY.
- copy_text();
-
- } break;
-
- case (KEY_Y): // PASTE (Yank for unix users).
- case (KEY_V): { // PASTE.
-
- if (editable) {
- paste_text();
- }
-
- } break;
-
- case (KEY_Z): { // Undo/redo.
- if (editable) {
- if (k->get_shift()) {
- redo();
- } else {
- undo();
- }
- }
- } break;
-
- case (KEY_U): { // Delete from start to cursor.
-
- if (editable) {
- deselect();
- text = text.substr(cursor_pos, text.length() - cursor_pos);
- _shape();
- set_cursor_position(0);
- _text_changed();
- }
-
- } break;
-
- case (KEY_K): { // Delete from cursor_pos to end.
-
- if (editable) {
- deselect();
- text = text.substr(0, cursor_pos);
- _text_changed();
- }
+ if (is_shortcut_keys_enabled()) {
+ if (k->is_action("ui_copy", true)) {
+ copy_text();
+ accept_event();
+ return;
+ }
- } break;
- case (KEY_A): { // Select all.
- select();
+ if (k->is_action("ui_text_select_all", true)) {
+ select();
+ accept_event();
+ return;
+ }
- } break;
-#ifdef APPLE_STYLE_KEYS
- case (KEY_LEFT): { // Go to start of text - like HOME key.
- shift_selection_check_pre(k->get_shift());
- set_cursor_position(0);
- shift_selection_check_post(k->get_shift());
- } break;
- case (KEY_RIGHT): { // Go to end of text - like END key.
- shift_selection_check_pre(k->get_shift());
- set_cursor_position(text.length());
- shift_selection_check_post(k->get_shift());
- } break;
- case (KEY_BACKSPACE): {
- if (!editable)
- break;
+ // Cut / Paste
+ if (k->is_action("ui_cut", true)) {
+ cut_text();
+ accept_event();
+ return;
+ }
- // If selected, delete the selection
- if (selection.enabled) {
- selection_delete();
- break;
- }
+ if (k->is_action("ui_paste", true)) {
+ paste_text();
+ accept_event();
+ return;
+ }
- // Otherwise delete from cursor to beginning of text edit
- int current_pos = get_cursor_position();
- if (current_pos != 0) {
- delete_text(0, current_pos);
- }
- } break;
-#endif
- default: {
- handled = false;
- }
+ // Undo / Redo
+ if (k->is_action("ui_undo", true)) {
+ undo();
+ accept_event();
+ return;
}
- if (handled) {
+ if (k->is_action("ui_redo", true)) {
+ redo();
accept_event();
return;
}
}
- _reset_caret_blink_timer();
- if (!k->get_metakey()) {
- bool handled = true;
- switch (code) {
- case KEY_KP_ENTER:
- case KEY_ENTER: {
- emit_signal("text_entered", text);
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
- DisplayServer::get_singleton()->virtual_keyboard_hide();
- }
-
- } break;
-
- case KEY_BACKSPACE: {
- if (!editable) {
- break;
- }
-
- if (selection.enabled) {
- selection_delete();
- break;
- }
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_alt()) {
-#else
- if (k->get_alt()) {
- handled = false;
- break;
- } else if (k->get_command()) {
-#endif
- int cc = cursor_pos;
-
- Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
- for (int i = words.size() - 1; i >= 0; i--) {
- if (words[i].x < cc) {
- cc = words[i].x;
- break;
- }
- }
-
- delete_text(cc, cursor_pos);
-
- set_cursor_position(cc);
-
- } else {
- delete_char();
- }
-
- } break;
- case KEY_KP_4: {
- if (k->get_unicode() != 0) {
- handled = false;
- break;
- }
- [[fallthrough]];
- }
- case KEY_LEFT: {
-#ifndef APPLE_STYLE_KEYS
- if (!k->get_alt()) {
-#endif
- if (selection.enabled && !k->get_shift()) {
- set_cursor_position(selection.begin);
- deselect();
- handled = true;
- break;
- }
-
- shift_selection_check_pre(k->get_shift());
-#ifndef APPLE_STYLE_KEYS
- }
-#endif
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_command()) {
- set_cursor_position(0);
- } else if (k->get_alt()) {
-#else
- if (k->get_alt()) {
- handled = false;
- break;
- } else if (k->get_command()) {
-#endif
- int cc = cursor_pos;
-
- Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
- for (int i = words.size() - 1; i >= 0; i--) {
- if (words[i].x < cc) {
- cc = words[i].x;
- break;
- }
- }
-
- set_cursor_position(cc);
-
- } else {
- if (mid_grapheme_caret_enabled) {
- set_cursor_position(get_cursor_position() - 1);
- } else {
- set_cursor_position(TS->shaped_text_prev_grapheme_pos(text_rid, get_cursor_position()));
- }
- }
-
- shift_selection_check_post(k->get_shift());
-
- } break;
- case KEY_KP_6: {
- if (k->get_unicode() != 0) {
- handled = false;
- break;
- }
- [[fallthrough]];
- }
- case KEY_RIGHT: {
-#ifndef APPLE_STYLE_KEYS
- if (!k->get_alt()) {
-#endif
- if (selection.enabled && !k->get_shift()) {
- set_cursor_position(selection.end);
- deselect();
- handled = true;
- break;
- }
-
- shift_selection_check_pre(k->get_shift());
-#ifndef APPLE_STYLE_KEYS
- }
-#endif
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_command()) {
- set_cursor_position(text.length());
- } else if (k->get_alt()) {
-#else
- if (k->get_alt()) {
- handled = false;
- break;
- } else if (k->get_command()) {
-#endif
- int cc = cursor_pos;
-
- Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
- for (int i = 0; i < words.size(); i++) {
- if (words[i].y > cc) {
- cc = words[i].y;
- break;
- }
- }
-
- set_cursor_position(cc);
-
- } else {
- if (mid_grapheme_caret_enabled) {
- set_cursor_position(get_cursor_position() + 1);
- } else {
- set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, get_cursor_position()));
- }
- }
-
- shift_selection_check_post(k->get_shift());
-
- } break;
- case KEY_UP: {
- shift_selection_check_pre(k->get_shift());
- if (get_cursor_position() == 0) {
- handled = false;
- }
- set_cursor_position(0);
- shift_selection_check_post(k->get_shift());
- } break;
- case KEY_DOWN: {
- shift_selection_check_pre(k->get_shift());
- if (get_cursor_position() == text.length()) {
- handled = false;
- }
- set_cursor_position(text.length());
- shift_selection_check_post(k->get_shift());
- } break;
- case KEY_DELETE: {
- if (!editable) {
- break;
- }
-
- if (k->get_shift() && !k->get_command() && !k->get_alt()) {
- cut_text();
- break;
- }
-
- if (selection.enabled) {
- selection_delete();
- break;
- }
-
- int text_len = text.length();
+ // BACKSPACE
+ if (k->is_action("ui_text_backspace_all_to_left", true)) {
+ _backspace(false, true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_backspace_word", true)) {
+ _backspace(true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_backspace", true)) {
+ _backspace();
+ accept_event();
+ return;
+ }
- if (cursor_pos == text_len) {
- break; // Nothing to do.
- }
+ // DELETE
+ if (k->is_action("ui_text_delete_all_to_right", true)) {
+ _delete(false, true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_delete_word", true)) {
+ _delete(true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_delete", true)) {
+ _delete();
+ accept_event();
+ return;
+ }
-#ifdef APPLE_STYLE_KEYS
- if (k->get_alt()) {
-#else
- if (k->get_alt()) {
- handled = false;
- break;
- } else if (k->get_command()) {
-#endif
- int cc = cursor_pos;
+ // Cursor Movement
- Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
- for (int i = 0; i < words.size(); i++) {
- if (words[i].y > cc) {
- cc = words[i].y;
- break;
- }
- }
+ k = k->duplicate();
+ bool shift_pressed = k->get_shift();
+ // Remove shift or else actions will not match. Use above variable for selection.
+ k->set_shift(false);
- delete_text(cursor_pos, cc);
+ if (k->is_action("ui_text_caret_word_left", true)) {
+ _move_cursor_left(shift_pressed, true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_left", true)) {
+ _move_cursor_left(shift_pressed);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_word_right", true)) {
+ _move_cursor_right(shift_pressed, true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_right", true)) {
+ _move_cursor_right(shift_pressed, false);
+ accept_event();
+ return;
+ }
- } else {
- if (mid_grapheme_caret_enabled) {
- set_cursor_position(cursor_pos + 1);
- delete_char();
- } else {
- int cc = cursor_pos;
- set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, cursor_pos));
- delete_text(cc, cursor_pos);
- }
- }
+ // Up = Home, Down = End
+ if (k->is_action("ui_text_caret_up", true) || k->is_action("ui_text_caret_line_start", true) || k->is_action("ui_text_caret_page_up", true)) {
+ _move_cursor_start(shift_pressed);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_down", true) || k->is_action("ui_text_caret_line_end", true) || k->is_action("ui_text_caret_page_down", true)) {
+ _move_cursor_end(shift_pressed);
+ accept_event();
+ return;
+ }
- } break;
- case KEY_KP_7: {
- if (k->get_unicode() != 0) {
- handled = false;
- break;
- }
- [[fallthrough]];
- }
- case KEY_HOME: {
- shift_selection_check_pre(k->get_shift());
- set_cursor_position(0);
- shift_selection_check_post(k->get_shift());
- } break;
- case KEY_KP_1: {
- if (k->get_unicode() != 0) {
- handled = false;
- break;
- }
- [[fallthrough]];
- }
- case KEY_END: {
- shift_selection_check_pre(k->get_shift());
- set_cursor_position(text.length());
- shift_selection_check_post(k->get_shift());
- } break;
- case KEY_MENU: {
- if (context_menu_enabled) {
- Point2 pos = Point2(get_cursor_pixel_pos().x, (get_size().y + get_theme_font("font")->get_height(get_theme_font_size("font_size"))) / 2);
- menu->set_position(get_global_transform().xform(pos));
- menu->set_size(Vector2(1, 1));
- //menu->set_scale(get_global_transform().get_scale());
- menu->popup();
- menu->grab_focus();
- }
- } break;
+ // Misc
+ if (k->is_action("ui_swap_input_direction", true)) {
+ _swap_current_input_direction();
+ accept_event();
+ return;
+ }
- default: {
- handled = false;
- } break;
- }
+ _reset_caret_blink_timer();
- if (handled) {
- accept_event();
- } else if (!k->get_command() || (k->get_command() && k->get_alt())) {
- if (k->get_unicode() >= 32 && k->get_keycode() != KEY_DELETE) {
- if (editable) {
- selection_delete();
- char32_t ucodestr[2] = { (char32_t)k->get_unicode(), 0 };
- int prev_len = text.length();
- append_at_cursor(ucodestr);
- if (text.length() != prev_len) {
- _text_changed();
- }
- accept_event();
- }
+ // Allow unicode handling if:
+ // * No Modifiers are pressed (except shift)
+ bool allow_unicode_handling = !(k->get_command() || k->get_control() || k->get_alt() || k->get_metakey());
- } else {
- return;
- }
+ if (allow_unicode_handling && editable && k->get_unicode() >= 32) {
+ // Handle Unicode (if no modifiers active)
+ selection_delete();
+ char32_t ucodestr[2] = { (char32_t)k->get_unicode(), 0 };
+ int prev_len = text.length();
+ append_at_cursor(ucodestr);
+ if (text.length() != prev_len) {
+ _text_changed();
}
-
- update();
+ accept_event();
}
-
- return;
}
}
@@ -635,10 +528,17 @@ Variant LineEdit::get_drag_data(const Point2 &p_point) {
}
bool LineEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
+ bool drop_override = Control::can_drop_data(p_point, p_data); // In case user wants to drop custom data.
+ if (drop_override) {
+ return drop_override;
+ }
+
return p_data.get_type() == Variant::STRING;
}
void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
+ Control::drop_data(p_point, p_data);
+
if (p_data.get_type() == Variant::STRING) {
set_cursor_at_pixel_pos(p_point.x);
int selected = selection.end - selection.begin;
@@ -653,7 +553,7 @@ void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
}
Control::CursorShape LineEdit::get_cursor_shape(const Point2 &p_pos) const {
- if (!text.empty() && is_editable() && _is_over_clear_button(p_pos)) {
+ if (!text.is_empty() && is_editable() && _is_over_clear_button(p_pos)) {
return CURSOR_ARROW;
}
return Control::get_cursor_shape(p_pos);
@@ -735,7 +635,7 @@ void LineEdit::_notification(int p_what) {
}
int x_ofs = 0;
- bool using_placeholder = text.empty() && ime_text.empty();
+ bool using_placeholder = text.is_empty() && ime_text.is_empty();
float text_width = TS->shaped_text_get_size(text_rid).x;
float text_height = TS->shaped_text_get_size(text_rid).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM);
@@ -770,8 +670,8 @@ void LineEdit::_notification(int p_what) {
int y_ofs = style->get_offset().y + (y_area - text_height) / 2;
Color selection_color = get_theme_color("selection_color");
- Color font_color = is_editable() ? get_theme_color("font_color") : get_theme_color("font_color_uneditable");
- Color font_color_selected = get_theme_color("font_color_selected");
+ Color font_color = is_editable() ? get_theme_color("font_color") : get_theme_color("font_uneditable_color");
+ Color font_selected_color = get_theme_color("font_selected_color");
Color cursor_color = get_theme_color("cursor_color");
// Draw placeholder color.
@@ -834,14 +734,32 @@ void LineEdit::_notification(int p_what) {
// Draw text.
ofs.y += TS->shaped_text_get_ascent(text_rid);
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ Vector2 oofs = ofs;
+ for (int i = 0; i < gl_size; i++) {
+ for (int j = 0; j < glyphs[i].repeat; j++) {
+ if (ceil(oofs.x) >= x_ofs && (oofs.x + glyphs[i].advance) <= ofs_max) {
+ if (glyphs[i].font_rid != RID()) {
+ TS->font_draw_glyph_outline(glyphs[i].font_rid, ci, glyphs[i].font_size, outline_size, oofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, font_outline_color);
+ }
+ }
+ oofs.x += glyphs[i].advance;
+ }
+ if (oofs.x >= ofs_max) {
+ break;
+ }
+ }
+ }
for (int i = 0; i < gl_size; i++) {
bool selected = selection.enabled && glyphs[i].start >= selection.begin && glyphs[i].end <= selection.end;
for (int j = 0; j < glyphs[i].repeat; j++) {
if (ceil(ofs.x) >= x_ofs && (ofs.x + glyphs[i].advance) <= ofs_max) {
if (glyphs[i].font_rid != RID()) {
- TS->font_draw_glyph(glyphs[i].font_rid, ci, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, selected ? font_color_selected : font_color);
+ TS->font_draw_glyph(glyphs[i].font_rid, ci, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, selected ? font_selected_color : font_color);
} else if ((glyphs[i].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
- TS->draw_hex_code_box(ci, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, selected ? font_color_selected : font_color);
+ TS->draw_hex_code_box(ci, glyphs[i].font_size, ofs + Vector2(glyphs[i].x_off, glyphs[i].y_off), glyphs[i].index, selected ? font_selected_color : font_color);
}
}
ofs.x += glyphs[i].advance;
@@ -953,14 +871,7 @@ void LineEdit::_notification(int p_what) {
DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id());
}
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
- if (selection.enabled) {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end);
- } else {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos);
- }
- }
-
+ show_virtual_keyboard();
} break;
case NOTIFICATION_FOCUS_EXIT: {
if (caret_blink_enabled && !caret_force_displayed) {
@@ -1001,13 +912,17 @@ void LineEdit::copy_text() {
}
void LineEdit::cut_text() {
- if (selection.enabled && !pass) {
+ if (editable && selection.enabled && !pass) {
DisplayServer::get_singleton()->clipboard_set(text.substr(selection.begin, selection.end - selection.begin));
selection_delete();
}
}
void LineEdit::paste_text() {
+ if (!editable) {
+ return;
+ }
+
// Strip escape characters like \n and \t as they can't be displayed on LineEdit.
String paste_buffer = DisplayServer::get_singleton()->clipboard_get().strip_escapes();
@@ -1028,6 +943,10 @@ void LineEdit::paste_text() {
}
void LineEdit::undo() {
+ if (!editable) {
+ return;
+ }
+
if (undo_stack_pos == nullptr) {
if (undo_stack.size() <= 1) {
return;
@@ -1047,6 +966,10 @@ void LineEdit::undo() {
}
void LineEdit::redo() {
+ if (!editable) {
+ return;
+ }
+
if (undo_stack_pos == nullptr) {
return;
}
@@ -1109,7 +1032,7 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
} break;
}
- bool using_placeholder = text.empty() && ime_text.empty();
+ bool using_placeholder = text.is_empty() && ime_text.is_empty();
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon("clear") : right_icon;
@@ -1157,7 +1080,7 @@ Vector2i LineEdit::get_cursor_pixel_pos() {
} break;
}
- bool using_placeholder = text.empty() && ime_text.empty();
+ bool using_placeholder = text.is_empty() && ime_text.is_empty();
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon("clear") : right_icon;
@@ -1231,6 +1154,8 @@ void LineEdit::cursor_set_blink_enabled(const bool p_enabled) {
}
draw_caret = true;
+
+ notify_property_list_changed();
}
bool LineEdit::cursor_get_force_displayed() const {
@@ -1407,6 +1332,21 @@ Array LineEdit::get_structured_text_bidi_override_options() const {
void LineEdit::clear() {
clear_internal();
_text_changed();
+
+ // This should reset virtual keyboard state if needed.
+ if (has_focus()) {
+ show_virtual_keyboard();
+ }
+}
+
+void LineEdit::show_virtual_keyboard() {
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
+ if (selection.enabled) {
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end);
+ } else {
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos);
+ }
+ }
}
String LineEdit::get_text() const {
@@ -1482,7 +1422,7 @@ void LineEdit::set_cursor_position(int p_pos) {
}
int ofs_max = get_size().width - style->get_margin(SIDE_RIGHT);
- bool using_placeholder = text.empty() && ime_text.empty();
+ bool using_placeholder = text.is_empty() && ime_text.is_empty();
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon("clear") : right_icon;
@@ -1559,18 +1499,18 @@ Size2 LineEdit::get_minimum_size() const {
Size2 min_size;
// Minimum size of text.
- int space_size = font->get_char_size('m', 0, font_size).x;
- min_size.width = get_theme_constant("minimum_spaces") * space_size;
+ int em_space_size = font->get_char_size('M', 0, font_size).x;
+ min_size.width = get_theme_constant("minimum_character_width") * em_space_size;
if (expand_to_text_length) {
// Add a space because some fonts are too exact, and because cursor needs a bit more when at the end.
- min_size.width = MAX(min_size.width, full_width + space_size);
+ min_size.width = MAX(min_size.width, full_width + em_space_size);
}
min_size.height = MAX(TS->shaped_text_get_size(text_rid).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM), font->get_height(font_size));
// Take icons into account.
- bool using_placeholder = text.empty() && ime_text.empty();
+ bool using_placeholder = text.is_empty() && ime_text.is_empty();
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon("clear") : right_icon;
@@ -1949,7 +1889,6 @@ void LineEdit::_text_changed() {
void LineEdit::_emit_text_change() {
emit_signal("text_changed", text);
- _change_notify("text");
text_changed_dirty = false;
}
@@ -1995,7 +1934,7 @@ void LineEdit::_fit_to_width() {
if (align == ALIGN_FILL) {
Ref<StyleBox> style = get_theme_stylebox("normal");
int t_width = get_size().width - style->get_margin(SIDE_RIGHT) - style->get_margin(SIDE_LEFT);
- bool using_placeholder = text.empty() && ime_text.empty();
+ bool using_placeholder = text.is_empty() && ime_text.is_empty();
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon("clear") : right_icon;
@@ -2034,25 +1973,50 @@ void LineEdit::_create_undo_state() {
undo_stack.push_back(op);
}
+int LineEdit::_get_menu_action_accelerator(const String &p_action) {
+ const List<Ref<InputEvent>> *events = InputMap::get_singleton()->action_get_events(p_action);
+ if (!events) {
+ return 0;
+ }
+
+ // Use first event in the list for the accelerator.
+ const List<Ref<InputEvent>>::Element *first_event = events->front();
+ if (!first_event) {
+ return 0;
+ }
+
+ const Ref<InputEventKey> event = first_event->get();
+ if (event.is_null()) {
+ return 0;
+ }
+
+ // Use physical keycode if non-zero
+ if (event->get_physical_keycode() != 0) {
+ return event->get_physical_keycode_with_modifiers();
+ } else {
+ return event->get_keycode_with_modifiers();
+ }
+}
+
void LineEdit::_generate_context_menu() {
// Reorganize context menu.
menu->clear();
if (editable) {
- menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0);
+ menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_cut") : 0);
}
- menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0);
+ menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_copy") : 0);
if (editable) {
- menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0);
+ menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_paste") : 0);
}
menu->add_separator();
if (is_selecting_enabled()) {
- menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0);
+ menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_text_select_all") : 0);
}
if (editable) {
menu->add_item(RTR("Clear"), MENU_CLEAR);
menu->add_separator();
- menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_Z : 0);
- menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z : 0);
+ menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_undo") : 0);
+ menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_redo") : 0);
}
menu->add_separator();
menu->add_submenu_item(RTR("Text writing direction"), "DirMenu");
@@ -2082,7 +2046,7 @@ bool LineEdit::_set(const StringName &p_name, const Variant &p_value) {
update();
}
}
- _change_notify();
+ notify_property_list_changed();
return true;
}
@@ -2113,6 +2077,12 @@ void LineEdit::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
}
+void LineEdit::_validate_property(PropertyInfo &property) const {
+ if (!caret_blink_enabled && property.name == "caret_blink_speed") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed);
@@ -2255,9 +2225,6 @@ LineEdit::LineEdit() {
text_rid = TS->create_shaped_text();
_create_undo_state();
- clear_button_status.press_attempt = false;
- clear_button_status.pressing_inside = false;
-
deselect();
set_focus_mode(FOCUS_ALL);
set_default_cursor_shape(CURSOR_IBEAM);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index e7b2a34eed..ef36377f2e 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -94,7 +94,7 @@ private:
Point2 ime_selection;
RID text_rid;
- float full_width = 0;
+ float full_width = 0.0;
bool selecting_enabled = true;
@@ -129,19 +129,20 @@ private:
Ref<Texture2D> right_icon;
struct Selection {
- int begin;
- int end;
- int cursor_start;
- bool enabled;
- bool creating;
- bool doubleclick;
- bool drag_attempt;
+ int begin = 0;
+ int end = 0;
+ int cursor_start = 0;
+ bool enabled = false;
+ bool creating = false;
+ bool doubleclick = false;
+ bool drag_attempt = false;
+ uint64_t last_dblclk = 0;
} selection;
struct TextOperation {
- int cursor_pos;
- int scroll_offset;
- int cached_width;
+ int cursor_pos = 0;
+ int scroll_offset = 0;
+ int cached_width = 0;
String text;
};
List<TextOperation> undo_stack;
@@ -163,6 +164,7 @@ private:
void _clear_redo();
void _create_undo_state();
+ int _get_menu_action_accelerator(const String &p_action);
void _generate_context_menu();
void _shape();
@@ -188,15 +190,23 @@ private:
void _editor_settings_changed();
- void _gui_input(Ref<InputEvent> p_event);
- void _notification(int p_what);
+ void _swap_current_input_direction();
+ void _move_cursor_left(bool p_select, bool p_move_by_word = false);
+ void _move_cursor_right(bool p_select, bool p_move_by_word = false);
+ void _move_cursor_start(bool p_select);
+ void _move_cursor_end(bool p_select);
+ void _backspace(bool p_word = false, bool p_all_to_left = false);
+ void _delete(bool p_word = false, bool p_all_to_right = false);
protected:
+ void _notification(int p_what);
static void _bind_methods();
+ void _gui_input(Ref<InputEvent> p_event);
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_align(Align p_align);
@@ -306,6 +316,9 @@ public:
Ref<Texture2D> get_right_icon();
virtual bool is_text_field() const override;
+
+ void show_virtual_keyboard();
+
LineEdit();
~LineEdit();
};
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
index b66ee514dc..1f7b61e3d1 100644
--- a/scene/gui/link_button.cpp
+++ b/scene/gui/link_button.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -163,8 +163,8 @@ void LinkButton::_notification(int p_what) {
} break;
case DRAW_HOVER_PRESSED:
case DRAW_PRESSED: {
- if (has_theme_color("font_color_pressed")) {
- color = get_theme_color("font_color_pressed");
+ if (has_theme_color("font_pressed_color")) {
+ color = get_theme_color("font_pressed_color");
} else {
color = get_theme_color("font_color");
}
@@ -173,12 +173,12 @@ void LinkButton::_notification(int p_what) {
} break;
case DRAW_HOVER: {
- color = get_theme_color("font_color_hover");
+ color = get_theme_color("font_hover_color");
do_underline = underline_mode != UNDERLINE_MODE_NEVER;
} break;
case DRAW_DISABLED: {
- color = get_theme_color("font_color_disabled");
+ color = get_theme_color("font_disabled_color");
do_underline = underline_mode == UNDERLINE_MODE_ALWAYS;
} break;
@@ -191,9 +191,17 @@ void LinkButton::_notification(int p_what) {
int width = text_buf->get_line_width();
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
if (is_layout_rtl()) {
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ text_buf->draw_outline(get_canvas_item(), Vector2(size.width - width, 0), outline_size, font_outline_color);
+ }
text_buf->draw(get_canvas_item(), Vector2(size.width - width, 0), color);
} else {
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ text_buf->draw_outline(get_canvas_item(), Vector2(0, 0), outline_size, font_outline_color);
+ }
text_buf->draw(get_canvas_item(), Vector2(0, 0), color);
}
@@ -231,7 +239,7 @@ bool LinkButton::_set(const StringName &p_name, const Variant &p_value) {
update();
}
}
- _change_notify();
+ notify_property_list_changed();
return true;
}
@@ -294,7 +302,6 @@ void LinkButton::_bind_methods() {
LinkButton::LinkButton() {
text_buf.instance();
- underline_mode = UNDERLINE_MODE_ALWAYS;
set_focus_mode(FOCUS_NONE);
set_default_cursor_shape(CURSOR_POINTING_HAND);
}
diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h
index 8c1daef166..7eaa9f88b6 100644
--- a/scene/gui/link_button.h
+++ b/scene/gui/link_button.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,7 +48,7 @@ public:
private:
String text;
Ref<TextLine> text_buf;
- UnderlineMode underline_mode;
+ UnderlineMode underline_mode = UNDERLINE_MODE_ALWAYS;
Dictionary opentype_features;
String language;
diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp
index b674b492d8..0e9610d0a3 100644
--- a/scene/gui/margin_container.cpp
+++ b/scene/gui/margin_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/margin_container.h b/scene/gui/margin_container.h
index 12e230d9d7..b782976ada 100644
--- a/scene/gui/margin_container.h
+++ b/scene/gui/margin_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index b98b3f7094..5acc7e808a 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -118,7 +118,6 @@ void MenuButton::set_disable_shortcuts(bool p_disabled) {
}
MenuButton::MenuButton() {
- switch_on_hover = false;
set_flat(true);
set_toggle_mode(true);
set_disable_shortcuts(false);
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 65b46d5b69..fd9ae6021e 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,9 +37,9 @@
class MenuButton : public Button {
GDCLASS(MenuButton, Button);
- bool clicked;
- bool switch_on_hover;
- bool disable_shortcuts;
+ bool clicked = false;
+ bool switch_on_hover = false;
+ bool disable_shortcuts = false;
PopupMenu *popup;
Array _get_items() const;
diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp
index 72754f375a..29a38ad5e3 100644
--- a/scene/gui/nine_patch_rect.cpp
+++ b/scene/gui/nine_patch_rect.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -98,7 +98,6 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) {
*/
minimum_size_changed();
emit_signal("texture_changed");
- _change_notify("texture");
}
Ref<Texture2D> NinePatchRect::get_texture() const {
@@ -110,20 +109,6 @@ void NinePatchRect::set_patch_margin(Side p_side, int p_size) {
margin[p_side] = p_size;
update();
minimum_size_changed();
- switch (p_side) {
- case SIDE_LEFT:
- _change_notify("patch_margin_left");
- break;
- case SIDE_TOP:
- _change_notify("patch_margin_top");
- break;
- case SIDE_RIGHT:
- _change_notify("patch_margin_right");
- break;
- case SIDE_BOTTOM:
- _change_notify("patch_margin_bottom");
- break;
- }
}
int NinePatchRect::get_patch_margin(Side p_side) const {
@@ -139,7 +124,6 @@ void NinePatchRect::set_region_rect(const Rect2 &p_region_rect) {
region_rect = p_region_rect;
item_rect_changed();
- _change_notify("region_rect");
}
Rect2 NinePatchRect::get_region_rect() const {
@@ -174,16 +158,7 @@ NinePatchRect::AxisStretchMode NinePatchRect::get_v_axis_stretch_mode() const {
}
NinePatchRect::NinePatchRect() {
- margin[SIDE_LEFT] = 0;
- margin[SIDE_RIGHT] = 0;
- margin[SIDE_BOTTOM] = 0;
- margin[SIDE_TOP] = 0;
-
set_mouse_filter(MOUSE_FILTER_IGNORE);
- draw_center = true;
-
- axis_h = AXIS_STRETCH_MODE_STRETCH;
- axis_v = AXIS_STRETCH_MODE_STRETCH;
}
NinePatchRect::~NinePatchRect() {
diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h
index 91d24ada8f..f9a3f31fe5 100644
--- a/scene/gui/nine_patch_rect.h
+++ b/scene/gui/nine_patch_rect.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,12 +43,13 @@ public:
AXIS_STRETCH_MODE_TILE_FIT,
};
- bool draw_center;
- int margin[4];
+ bool draw_center = true;
+ int margin[4] = {};
Rect2 region_rect;
Ref<Texture2D> texture;
- AxisStretchMode axis_h, axis_v;
+ AxisStretchMode axis_h = AXIS_STRETCH_MODE_STRETCH;
+ AxisStretchMode axis_v = AXIS_STRETCH_MODE_STRETCH;
protected:
void _notification(int p_what);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 8fdd3db4e7..e52b6917be 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -62,13 +62,13 @@ void OptionButton::_notification(int p_what) {
if (get_theme_constant("modulate_arrow")) {
switch (get_draw_mode()) {
case DRAW_PRESSED:
- clr = get_theme_color("font_color_pressed");
+ clr = get_theme_color("font_pressed_color");
break;
case DRAW_HOVER:
- clr = get_theme_color("font_color_hover");
+ clr = get_theme_color("font_hover_color");
break;
case DRAW_DISABLED:
- clr = get_theme_color("font_color_disabled");
+ clr = get_theme_color("font_disabled_color");
break;
default:
clr = get_theme_color("font_color");
@@ -336,7 +336,6 @@ void OptionButton::_bind_methods() {
}
OptionButton::OptionButton() {
- current = -1;
set_toggle_mode(true);
set_text_align(ALIGN_LEFT);
if (is_layout_rtl()) {
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index fec7695969..d846e395ad 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,7 @@ class OptionButton : public Button {
GDCLASS(OptionButton, Button);
PopupMenu *popup;
- int current;
+ int current = -1;
void _focused(int p_which);
void _selected(int p_which);
diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp
index 28cc056d6e..995e985c3a 100644
--- a/scene/gui/panel.cpp
+++ b/scene/gui/panel.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/panel.h b/scene/gui/panel.h
index e2c1ddc91d..84fd6aaead 100644
--- a/scene/gui/panel.h
+++ b/scene/gui/panel.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp
index 051b4de825..11d822c5e1 100644
--- a/scene/gui/panel_container.cpp
+++ b/scene/gui/panel_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/panel_container.h b/scene/gui/panel_container.h
index 92743f2c47..f27ca7fad7 100644
--- a/scene/gui/panel_container.h
+++ b/scene/gui/panel_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 791c78e2b4..36bcca61a7 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 48e7ea9452..0355405d7c 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index e1a324efb3..f237f79be1 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -52,8 +52,8 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
Size2 minsize = get_theme_stylebox("panel")->get_minimum_size(); // Accounts for margin in the margin container
minsize.x += scroll_container->get_v_scrollbar()->get_size().width * 2; // Adds a buffer so that the scrollbar does not render over the top of content
- float max_w = 0;
- float icon_w = 0;
+ float max_w = 0.0;
+ float icon_w = 0.0;
int check_w = MAX(get_theme_icon("checked")->get_width(), get_theme_icon("radio_checked")->get_width()) + hseparation;
int accel_max_w = 0;
bool has_check = false;
@@ -62,7 +62,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
Size2 size;
Size2 icon_size = items[i].get_icon_size();
- size.height = MAX(icon_size.height, items[i].text_buf->get_size().y);
+ size.height = _get_item_height(i);
icon_w = MAX(icon_size.width, icon_w);
size.width += items[i].h_ofs;
@@ -72,9 +72,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
}
size.width += items[i].text_buf->get_size().x;
- if (i > 0) {
- size.height += vseparation;
- }
+ size.height += vseparation;
if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) {
int accel_w = hseparation * 2;
@@ -91,7 +89,9 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
minsize.height += size.height;
}
- minsize.width += max_w + icon_w + accel_max_w;
+ int item_side_padding = get_theme_constant("item_start_padding") + get_theme_constant("item_end_padding");
+ minsize.width += max_w + icon_w + accel_max_w + item_side_padding;
+
if (has_check) {
minsize.width += check_w;
}
@@ -106,13 +106,35 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
return minsize;
}
+int PopupMenu::_get_item_height(int p_item) const {
+ ERR_FAIL_INDEX_V(p_item, items.size(), 0);
+ ERR_FAIL_COND_V(p_item < 0, 0);
+
+ int icon_height = items[p_item].get_icon_size().height;
+ if (items[p_item].checkable_type) {
+ icon_height = MAX(icon_height, MAX(get_theme_icon("checked")->get_height(), get_theme_icon("radio_checked")->get_height()));
+ }
+
+ int text_height = items[p_item].text_buf->get_size().height;
+ if (text_height == 0 && !items[p_item].separator) {
+ text_height = get_theme_font("font")->get_height(get_theme_font_size("font_size"));
+ }
+
+ int separator_height = 0;
+ if (items[p_item].separator) {
+ separator_height = MAX(get_theme_stylebox("separator")->get_minimum_size().height, MAX(get_theme_stylebox("labeled_separator_left")->get_minimum_size().height, get_theme_stylebox("labeled_separator_right")->get_minimum_size().height));
+ }
+
+ return MAX(separator_height, MAX(text_height, icon_height));
+}
+
int PopupMenu::_get_items_total_height() const {
int vsep = get_theme_constant("vseparation");
// Get total height of all items by taking max of icon height and font height
int items_total_height = 0;
for (int i = 0; i < items.size(); i++) {
- items_total_height += MAX(items[i].get_icon_size().height, items[i].text_buf->get_size().y) + vsep;
+ items_total_height += _get_item_height(i) + vsep;
}
// Subtract a separator which is not needed for the last item.
@@ -152,11 +174,9 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
}
for (int i = 0; i < items.size(); i++) {
- if (i > 0) {
- ofs.y += vseparation;
- }
+ ofs.y += i > 0 ? vseparation : (float)vseparation / 2;
- ofs.y += MAX(items[i].get_icon_size().height, items[i].text_buf->get_size().y);
+ ofs.y += _get_item_height(i);
if (p_over.y - control->get_position().y < ofs.y) {
return i;
@@ -455,6 +475,10 @@ void PopupMenu::_draw_items() {
margin_size.width = margin_container->get_theme_constant("margin_right") + margin_container->get_theme_constant("margin_left");
margin_size.height = margin_container->get_theme_constant("margin_top") + margin_container->get_theme_constant("margin_bottom");
+ // Space between the item content and the sides of popup menu.
+ int item_start_padding = get_theme_constant("item_start_padding");
+ int item_end_padding = get_theme_constant("item_end_padding");
+
bool rtl = control->is_layout_rtl();
Ref<StyleBox> style = get_theme_stylebox("panel");
Ref<StyleBox> hover = get_theme_stylebox("hover");
@@ -475,10 +499,10 @@ void PopupMenu::_draw_items() {
int vseparation = get_theme_constant("vseparation");
int hseparation = get_theme_constant("hseparation");
Color font_color = get_theme_color("font_color");
- Color font_color_disabled = get_theme_color("font_color_disabled");
- Color font_color_accel = get_theme_color("font_color_accel");
- Color font_color_hover = get_theme_color("font_color_hover");
- Color font_color_separator = get_theme_color("font_color_separator");
+ Color font_disabled_color = get_theme_color("font_disabled_color");
+ Color font_accelerator_color = get_theme_color("font_accelerator_color");
+ Color font_hover_color = get_theme_color("font_hover_color");
+ Color font_separator_color = get_theme_color("font_separator_color");
float scroll_width = scroll_container->get_v_scrollbar()->is_visible_in_tree() ? scroll_container->get_v_scrollbar()->get_size().width : 0;
float display_width = control->get_size().width - scroll_width;
@@ -506,22 +530,20 @@ void PopupMenu::_draw_items() {
// Loop through all items and draw each.
for (int i = 0; i < items.size(); i++) {
- // If not the first item, add the separation space between items.
- if (i > 0) {
- ofs.y += vseparation;
- }
+ // For the first item only add half a separation. For all other items, add a whole separation to the offset.
+ ofs.y += i > 0 ? vseparation : (float)vseparation / 2;
_shape_item(i);
Point2 item_ofs = ofs;
Size2 icon_size = items[i].get_icon_size();
- float h = MAX(icon_size.height, items[i].text_buf->get_size().y);
+ float h = _get_item_height(i);
if (i == mouse_over) {
if (rtl) {
- hover->draw(ci, Rect2(item_ofs + Point2(-hseparation + scroll_width, -vseparation / 2), Size2(display_width + hseparation * 2, h + vseparation)));
+ hover->draw(ci, Rect2(item_ofs + Point2(scroll_width, -vseparation / 2), Size2(display_width, h + vseparation)));
} else {
- hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(display_width + hseparation * 2, h + vseparation)));
+ hover->draw(ci, Rect2(item_ofs + Point2(0, -vseparation / 2), Size2(display_width, h + vseparation)));
}
}
@@ -531,24 +553,28 @@ void PopupMenu::_draw_items() {
item_ofs.x += items[i].h_ofs;
if (items[i].separator) {
int sep_h = separator->get_center_size().height + separator->get_minimum_size().height;
+ int sep_ofs = Math::floor((h - sep_h) / 2.0);
if (text != String()) {
int text_size = items[i].text_buf->get_size().width;
int text_center = display_width / 2;
int text_left = text_center - text_size / 2;
int text_right = text_center + text_size / 2;
if (text_left > item_ofs.x) {
- labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, text_left - item_ofs.x), sep_h)));
+ labeled_separator_left->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(MAX(0, text_left - item_ofs.x), sep_h)));
}
if (text_right < display_width) {
- labeled_separator_right->draw(ci, Rect2(Point2(text_right, item_ofs.y + Math::floor((h - sep_h) / 2.0)), Size2(MAX(0, display_width - text_right), sep_h)));
+ labeled_separator_right->draw(ci, Rect2(Point2(text_right, item_ofs.y + sep_ofs), Size2(MAX(0, display_width - text_right), sep_h)));
}
} else {
- separator->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(display_width, sep_h)));
+ separator->draw(ci, Rect2(item_ofs + Point2(0, sep_ofs), Size2(display_width, sep_h)));
}
}
Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1);
+ // For non-separator items, add some padding for the content.
+ item_ofs.x += item_start_padding;
+
// Checkboxes
if (items[i].checkable_type) {
Texture2D *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr();
@@ -571,35 +597,53 @@ void PopupMenu::_draw_items() {
// Submenu arrow on right hand side
if (items[i].submenu != "") {
if (rtl) {
- submenu->draw(ci, Point2(scroll_width + style->get_margin(SIDE_LEFT), item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
+ submenu->draw(ci, Point2(scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
} else {
- submenu->draw(ci, Point2(display_width - style->get_margin(SIDE_RIGHT) - submenu->get_width(), item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
+ submenu->draw(ci, Point2(display_width - style->get_margin(SIDE_RIGHT) - submenu->get_width() - item_end_padding, item_ofs.y + Math::floor(h - submenu->get_height()) / 2), icon_color);
}
}
// Text
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
if (items[i].separator) {
if (text != String()) {
int center = (display_width - items[i].text_buf->get_size().width) / 2;
- items[i].text_buf->draw(ci, Point2(center, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), font_color_separator);
+ Vector2 text_pos = Point2(center, item_ofs.y + Math::floor((h - items[i].text_buf->get_size().y) / 2.0));
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
+ items[i].text_buf->draw(ci, text_pos, font_separator_color);
}
} else {
item_ofs.x += icon_ofs + check_ofs;
if (rtl) {
- items[i].text_buf->draw(ci, Size2(control->get_size().width - items[i].text_buf->get_size().width - item_ofs.x, item_ofs.y) + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color));
+ Vector2 text_pos = Size2(control->get_size().width - items[i].text_buf->get_size().width - item_ofs.x, item_ofs.y) + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0));
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
+ items[i].text_buf->draw(ci, text_pos, items[i].disabled ? font_disabled_color : (i == mouse_over ? font_hover_color : font_color));
} else {
- items[i].text_buf->draw(ci, item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color));
+ Vector2 text_pos = item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0));
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ items[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
+ items[i].text_buf->draw(ci, text_pos, items[i].disabled ? font_disabled_color : (i == mouse_over ? font_hover_color : font_color));
}
}
// Accelerator / Shortcut
if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) {
if (rtl) {
- item_ofs.x = scroll_width + style->get_margin(SIDE_LEFT);
+ item_ofs.x = scroll_width + style->get_margin(SIDE_LEFT) + item_end_padding;
} else {
- item_ofs.x = display_width - style->get_margin(SIDE_RIGHT) - items[i].accel_text_buf->get_size().x;
+ item_ofs.x = display_width - style->get_margin(SIDE_RIGHT) - items[i].accel_text_buf->get_size().x - item_end_padding;
}
- items[i].accel_text_buf->draw(ci, item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)), i == mouse_over ? font_color_hover : font_color_accel);
+ Vector2 text_pos = item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0));
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ items[i].accel_text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
+ items[i].accel_text_buf->draw(ci, text_pos, i == mouse_over ? font_hover_color : font_accelerator_color);
}
// Cache the item vertical offset from the first item and the height
@@ -1349,10 +1393,10 @@ void PopupMenu::remove_item(int p_idx) {
child_controls_changed();
}
-void PopupMenu::add_separator(const String &p_text) {
+void PopupMenu::add_separator(const String &p_text, int p_id) {
Item sep;
sep.separator = true;
- sep.id = -1;
+ sep.id = p_id;
if (p_text != String()) {
sep.text = p_text;
sep.xl_text = tr(p_text);
@@ -1600,7 +1644,7 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_item", "idx"), &PopupMenu::remove_item);
- ClassDB::bind_method(D_METHOD("add_separator", "label"), &PopupMenu::add_separator, DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("add_separator", "label", "id"), &PopupMenu::add_separator, DEFVAL(String()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("clear"), &PopupMenu::clear);
ClassDB::bind_method(D_METHOD("_set_items"), &PopupMenu::_set_items);
@@ -1636,7 +1680,6 @@ void PopupMenu::_bind_methods() {
void PopupMenu::popup(const Rect2 &p_bounds) {
moved = Vector2();
popup_time_msec = OS::get_singleton()->get_ticks_msec();
- set_as_minsize();
Popup::popup(p_bounds);
}
@@ -1663,19 +1706,6 @@ PopupMenu::PopupMenu() {
connect("window_input", callable_mp(this, &PopupMenu::_gui_input));
- mouse_over = -1;
- submenu_over = -1;
- initial_button_mask = 0;
- during_grabbed_click = false;
-
- allow_search = true;
- search_time_msec = 0;
- search_string = "";
-
- set_hide_on_item_selection(true);
- set_hide_on_checkable_item_selection(true);
- set_hide_on_multistate_item_selection(false);
-
submenu_timer = memnew(Timer);
submenu_timer->set_wait_time(0.3);
submenu_timer->set_one_shot(true);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index a082fcf0e7..e4cbe984c9 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,28 +51,28 @@ class PopupMenu : public Popup {
String language;
Control::TextDirection text_direction = Control::TEXT_DIRECTION_AUTO;
- bool checked;
+ bool checked = false;
enum {
CHECKABLE_TYPE_NONE,
CHECKABLE_TYPE_CHECK_BOX,
CHECKABLE_TYPE_RADIO_BUTTON,
} checkable_type;
- int max_states;
- int state;
- bool separator;
- bool disabled;
- bool dirty;
- int id;
+ int max_states = 0;
+ int state = 0;
+ bool separator = false;
+ bool disabled = false;
+ bool dirty = true;
+ int id = 0;
Variant metadata;
String submenu;
String tooltip;
- uint32_t accel;
- int _ofs_cache;
- int _height_cache;
- int h_ofs;
+ uint32_t accel = 0;
+ int _ofs_cache = 0;
+ int _height_cache = 0;
+ int h_ofs = 0;
Ref<Shortcut> shortcut;
- bool shortcut_is_global;
- bool shortcut_is_disabled;
+ bool shortcut_is_global = false;
+ bool shortcut_is_disabled = false;
// Returns (0,0) if icon is null.
Size2 get_icon_size() const {
@@ -82,19 +82,7 @@ class PopupMenu : public Popup {
Item() {
text_buf.instance();
accel_text_buf.instance();
- dirty = true;
- checked = false;
checkable_type = CHECKABLE_TYPE_NONE;
- separator = false;
- max_states = 0;
- state = 0;
- accel = 0;
- disabled = false;
- _ofs_cache = 0;
- _height_cache = 0;
- h_ofs = 0;
- shortcut_is_global = false;
- shortcut_is_disabled = false;
}
};
@@ -104,15 +92,16 @@ class PopupMenu : public Popup {
Timer *submenu_timer;
List<Rect2> autohide_areas;
Vector<Item> items;
- int initial_button_mask;
- bool during_grabbed_click;
- int mouse_over;
- int submenu_over;
+ int initial_button_mask = 0;
+ bool during_grabbed_click = false;
+ int mouse_over = -1;
+ int submenu_over = -1;
Rect2 parent_rect;
String _get_accel_text(const Item &p_item) const;
int _get_mouse_over(const Point2 &p_over) const;
virtual Size2 _get_contents_minimum_size() const override;
+ int _get_item_height(int p_item) const;
int _get_items_total_height() const;
void _scroll_to_item(int p_item);
@@ -123,9 +112,9 @@ class PopupMenu : public Popup {
void _submenu_timeout();
uint64_t popup_time_msec = 0;
- bool hide_on_item_selection;
- bool hide_on_checkable_item_selection;
- bool hide_on_multistate_item_selection;
+ bool hide_on_item_selection = true;
+ bool hide_on_checkable_item_selection = true;
+ bool hide_on_multistate_item_selection = false;
Vector2 moved;
Array _get_items() const;
@@ -136,9 +125,9 @@ class PopupMenu : public Popup {
void _ref_shortcut(Ref<Shortcut> p_sc);
void _unref_shortcut(Ref<Shortcut> p_sc);
- bool allow_search;
- uint64_t search_time_msec;
- String search_string;
+ bool allow_search = true;
+ uint64_t search_time_msec = 0;
+ String search_string = "";
MarginContainer *margin_container;
ScrollContainer *scroll_container;
@@ -228,7 +217,7 @@ public:
void remove_item(int p_idx);
- void add_separator(const String &p_text = String());
+ void add_separator(const String &p_text = String(), int p_id = -1);
void clear();
diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp
index c111ddff58..6e8dfd5994 100644
--- a/scene/gui/progress_bar.cpp
+++ b/scene/gui/progress_bar.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -74,7 +74,13 @@ void ProgressBar::_notification(int p_what) {
if (percent_visible) {
String txt = TS->format_number(itos(int(get_as_ratio() * 100))) + TS->percent_sign();
TextLine tl = TextLine(txt, font, font_size);
- tl.draw(get_canvas_item(), (Point2(get_size().width - tl.get_size().x, get_size().height - tl.get_size().y) / 2).round(), font_color);
+ Vector2 text_pos = (Point2(get_size().width - tl.get_size().x, get_size().height - tl.get_size().y) / 2).round();
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ tl.draw_outline(get_canvas_item(), text_pos, outline_size, font_outline_color);
+ }
+ tl.draw(get_canvas_item(), text_pos, font_color);
}
}
}
@@ -98,5 +104,4 @@ void ProgressBar::_bind_methods() {
ProgressBar::ProgressBar() {
set_v_size_flags(0);
set_step(0.01);
- percent_visible = true;
}
diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h
index f00f993adf..fb6060d932 100644
--- a/scene/gui/progress_bar.h
+++ b/scene/gui/progress_bar.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class ProgressBar : public Range {
GDCLASS(ProgressBar, Range);
- bool percent_visible;
+ bool percent_visible = true;
protected:
void _notification(int p_what);
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index bdb9f408f0..86b775e795 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,7 +34,7 @@ String Range::get_configuration_warning() const {
String warning = Control::get_configuration_warning();
if (shared->exp_ratio && shared->min <= 0) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0.");
@@ -47,7 +47,6 @@ void Range::_value_changed_notify() {
_value_changed(shared->val);
emit_signal("value_changed", shared->val);
update();
- _change_notify("value");
}
void Range::Shared::emit_value_changed() {
@@ -63,7 +62,6 @@ void Range::Shared::emit_value_changed() {
void Range::_changed_notify(const char *p_what) {
emit_signal("changed");
update();
- _change_notify(p_what);
}
void Range::Shared::emit_changed(const char *p_what) {
@@ -171,7 +169,10 @@ void Range::set_as_ratio(double p_value) {
}
double Range::get_as_ratio() const {
- ERR_FAIL_COND_V_MSG(Math::is_equal_approx(get_max(), get_min()), 0.0, "Cannot get ratio when minimum and maximum value are equal.");
+ if (Math::is_equal_approx(get_max(), get_min())) {
+ // Avoid division by zero.
+ return 1.0;
+ }
if (shared->exp_ratio && get_min() >= 0) {
double exp_min = get_min() == 0 ? 0.0 : Math::log(get_min()) / Math::log((double)2);
@@ -311,17 +312,7 @@ bool Range::is_lesser_allowed() const {
Range::Range() {
shared = memnew(Shared);
- shared->min = 0;
- shared->max = 100;
- shared->val = 0;
- shared->step = 1;
- shared->page = 0;
shared->owners.insert(this);
- shared->exp_ratio = false;
- shared->allow_greater = false;
- shared->allow_lesser = false;
-
- _rounded_values = false;
}
Range::~Range() {
diff --git a/scene/gui/range.h b/scene/gui/range.h
index 9ba367aaa4..1072a109c6 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,11 +37,14 @@ class Range : public Control {
GDCLASS(Range, Control);
struct Shared {
- double val, min, max;
- double step, page;
- bool exp_ratio;
- bool allow_greater;
- bool allow_lesser;
+ double val = 0.0;
+ double min = 0.0;
+ double max = 100.0;
+ double step = 1.0;
+ double page = 0.0;
+ bool exp_ratio = false;
+ bool allow_greater = false;
+ bool allow_lesser = false;
Set<Range *> owners;
void emit_value_changed();
void emit_changed(const char *p_what = "");
@@ -62,7 +65,7 @@ protected:
static void _bind_methods();
- bool _rounded_values;
+ bool _rounded_values = false;
public:
void set_value(double p_val);
diff --git a/scene/gui/reference_rect.cpp b/scene/gui/reference_rect.cpp
index 773acb2713..6d7f2cfd57 100644
--- a/scene/gui/reference_rect.cpp
+++ b/scene/gui/reference_rect.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/reference_rect.h b/scene/gui/reference_rect.h
index becbbf47c5..7097e83a15 100644
--- a/scene/gui/reference_rect.h
+++ b/scene/gui/reference_rect.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp
index 5b201f45d3..39718a269a 100644
--- a/scene/gui/rich_text_effect.cpp
+++ b/scene/gui/rich_text_effect.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h
index 1aa62c1c83..f2e2823eff 100644
--- a/scene/gui/rich_text_effect.h
+++ b/scene/gui/rich_text_effect.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 69b2c6ac7e..ed319f9fd0 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,7 @@
#include "editor/editor_scale.h"
#endif
-RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
+RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) const {
if (p_free) {
if (p_item->subitems.size()) {
return p_item->subitems.front()->get();
@@ -90,7 +90,7 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
return nullptr;
}
-RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) {
+RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) const {
if (p_free) {
if (p_item->subitems.size()) {
return p_item->subitems.back()->get();
@@ -147,7 +147,7 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item
case ITEM_TEXT: {
ItemText *t = (ItemText *)it;
offset += t->text.length();
- if (offset > p_position) {
+ if (offset >= p_position) {
return it;
}
} break;
@@ -220,7 +220,7 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font>
if (tab_size > 0) { // Align inline tabs.
Vector<float> tabs;
- tabs.push_back(tab_size * p_base_font->get_char_size('m', 0, p_base_font_size).width);
+ tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width);
l.text_buf->tab_align(tabs);
}
@@ -314,7 +314,7 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font>
table->rows.clear();
Vector2 offset;
- float row_height = 0;
+ float row_height = 0.0;
for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) {
ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames.
@@ -392,7 +392,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
if (tab_size > 0) { // Align inline tabs.
Vector<float> tabs;
- tabs.push_back(tab_size * p_base_font->get_char_size('m', 0, p_base_font_size).width);
+ tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width);
l.text_buf->tab_align(tabs);
}
@@ -404,6 +404,18 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
break;
}
switch (it->type) {
+ case ITEM_DROPCAP: {
+ // Add dropcap.
+ const ItemDropcap *dc = (ItemDropcap *)it;
+ if (dc != nullptr) {
+ l.text_buf->set_dropcap(dc->text, dc->font, dc->font_size, dc->dropcap_margins);
+ l.dc_color = dc->color;
+ l.dc_ol_size = dc->ol_size;
+ l.dc_ol_color = dc->ol_color;
+ } else {
+ l.text_buf->clear_dropcap();
+ }
+ } break;
case ITEM_NEWLINE: {
Ref<Font> font = _find_font(it);
if (font.is_null()) {
@@ -442,6 +454,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
ItemImage *img = (ItemImage *)it;
l.text_buf->add_object((uint64_t)it, img->image->get_size(), img->inline_align, 1);
text += String::chr(0xfffc);
+ l.char_count += 1;
} break;
case ITEM_TABLE: {
ItemTable *table = static_cast<ItemTable *>(it);
@@ -541,7 +554,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
table->rows.clear();
Vector2 offset;
- float row_height = 0;
+ float row_height = 0.0;
for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) {
ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames.
@@ -606,11 +619,11 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
}
}
-void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_color_shadow, bool p_shadow_as_outline, const Point2 &p_shadow_ofs) {
+int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, bool p_shadow_as_outline, const Point2 &p_shadow_ofs) {
Vector2 off;
- ERR_FAIL_COND(p_frame == nullptr);
- ERR_FAIL_COND(p_line < 0 || p_line >= p_frame->lines.size());
+ ERR_FAIL_COND_V(p_frame == nullptr, 0);
+ ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), 0);
Line &l = p_frame->lines.write[p_line];
@@ -619,7 +632,7 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
Variant meta;
if (it_from == nullptr) {
- return;
+ return 0;
}
RID ci = get_canvas_item();
@@ -679,14 +692,32 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
}
}
+ // Draw dropcap.
+ int dc_lines = l.text_buf->get_dropcap_lines();
+ float h_off = l.text_buf->get_dropcap_size().x;
+ if (l.dc_ol_size > 0) {
+ l.text_buf->draw_dropcap_outline(ci, p_ofs + ((rtl) ? Vector2() : Vector2(l.offset.x, 0)), l.dc_ol_size, l.dc_ol_color);
+ }
+ l.text_buf->draw_dropcap(ci, p_ofs + ((rtl) ? Vector2() : Vector2(l.offset.x, 0)), l.dc_color);
+
+ int line_count = 0;
+ Size2 ctrl_size = get_size();
// Draw text.
for (int line = 0; line < l.text_buf->get_line_count(); line++) {
RID rid = l.text_buf->get_line_rid(line);
+ if (p_ofs.y + off.y >= ctrl_size.height) {
+ break;
+ }
+ if (p_ofs.y + off.y + TS->shaped_text_get_size(rid).y <= 0) {
+ off.y += TS->shaped_text_get_size(rid).y;
+ continue;
+ }
float width = l.text_buf->get_width();
float length = TS->shaped_text_get_width(rid);
// Draw line.
+ line_count++;
if (rtl) {
off.x = p_width - l.offset.x - width;
@@ -718,6 +749,14 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
} break;
}
+ if (line <= dc_lines) {
+ if (rtl) {
+ off.x -= h_off;
+ } else {
+ off.x += h_off;
+ }
+ }
+
//draw_rect(Rect2(p_ofs + off, TS->shaped_text_get_size(rid)), Color(1,0,0), false, 2); //DEBUG_RECTS
off.y += TS->shaped_text_get_ascent(rid);
@@ -738,6 +777,7 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
Color odd_row_bg = get_theme_color("table_odd_row_bg");
Color even_row_bg = get_theme_color("table_even_row_bg");
Color border = get_theme_color("table_border");
+ int hseparation = get_theme_constant("table_hseparation");
int col_count = table->columns.size();
int row_count = table->rows.size();
@@ -754,15 +794,15 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
coff.x = rect.size.width - table->columns[col].width - coff.x;
}
if (row % 2 == 0) {
- draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width, table->rows[row])), (frame->odd_row_bg != Color(0, 0, 0, 0) ? frame->odd_row_bg : odd_row_bg), true);
+ draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width + hseparation + frame->padding.position.x + frame->padding.size.x, table->rows[row])), (frame->odd_row_bg != Color(0, 0, 0, 0) ? frame->odd_row_bg : odd_row_bg), true);
} else {
- draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width, table->rows[row])), (frame->even_row_bg != Color(0, 0, 0, 0) ? frame->even_row_bg : even_row_bg), true);
+ draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width + hseparation + frame->padding.position.x + frame->padding.size.x, table->rows[row])), (frame->even_row_bg != Color(0, 0, 0, 0) ? frame->even_row_bg : even_row_bg), true);
}
- draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width, table->rows[row])), (frame->border != Color(0, 0, 0, 0) ? frame->border : border), false);
+ draw_rect(Rect2(p_ofs + rect.position + off + coff - frame->padding.position, Size2(table->columns[col].width + hseparation + frame->padding.position.x + frame->padding.size.x, table->rows[row])), (frame->border != Color(0, 0, 0, 0) ? frame->border : border), false);
}
for (int j = 0; j < frame->lines.size(); j++) {
- _draw_line(frame, j, p_ofs + rect.position + off + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_base_color, p_outline_size, p_outline_color, p_font_color_shadow, p_shadow_as_outline, p_shadow_ofs);
+ _draw_line(frame, j, p_ofs + rect.position + off + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_base_color, p_outline_size, p_outline_color, p_font_shadow_color, p_shadow_as_outline, p_shadow_ofs);
}
idx++;
}
@@ -781,8 +821,8 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
// Draw oulines and shadow.
for (int i = 0; i < gl_size; i++) {
Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start);
- int size = _find_outline_size(it);
- Color font_color = _find_outline_color(it, Color(0, 0, 0, 0));
+ int size = _find_outline_size(it, p_outline_size);
+ Color font_color = _find_outline_color(it, p_outline_color);
if (size <= 0) {
gloff.x += glyphs[i].advance;
continue;
@@ -882,9 +922,9 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
if (visible) {
if (frid != RID()) {
if (p_shadow_as_outline) {
- TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(-shadow_ofs.x, shadow_ofs.y), gl, p_font_color_shadow);
- TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(shadow_ofs.x, -shadow_ofs.y), gl, p_font_color_shadow);
- TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(-shadow_ofs.x, -shadow_ofs.y), gl, p_font_color_shadow);
+ TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(-shadow_ofs.x, shadow_ofs.y), gl, p_font_shadow_color);
+ TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(shadow_ofs.x, -shadow_ofs.y), gl, p_font_shadow_color);
+ TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff + Vector2(-shadow_ofs.x, -shadow_ofs.y), gl, p_font_shadow_color);
}
TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff, gl, font_color);
}
@@ -894,7 +934,7 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
}
// Draw main text.
- Color selection_fg = get_theme_color("font_color_selected");
+ Color selection_fg = get_theme_color("font_selected_color");
Color selection_bg = get_theme_color("selection_color");
int sel_start = -1;
@@ -1040,6 +1080,8 @@ void RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_
}
off.y += TS->shaped_text_get_descent(rid);
}
+
+ return line_count;
}
void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool *r_outside) {
@@ -1358,19 +1400,20 @@ void RichTextLabel::_notification(int p_what) {
}
Ref<Font> base_font = get_theme_font("normal_font");
Color base_color = get_theme_color("default_color");
- Color outline_color = get_theme_color("outline_color");
+ Color outline_color = get_theme_color("font_outline_color");
int outline_size = get_theme_constant("outline_size");
- Color font_color_shadow = get_theme_color("font_color_shadow");
+ Color font_shadow_color = get_theme_color("font_shadow_color");
bool use_outline = get_theme_constant("shadow_as_outline");
Point2 shadow_ofs(get_theme_constant("shadow_offset_x"), get_theme_constant("shadow_offset_y"));
+ visible_paragraph_count = 0;
visible_line_count = 0;
// New cache draw.
Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs);
while (ofs.y < size.height && from_line < main->lines.size()) {
- visible_line_count++;
- _draw_line(main, from_line, ofs, text_rect.size.x, base_color, outline_size, outline_color, font_color_shadow, use_outline, shadow_ofs);
+ visible_paragraph_count++;
+ visible_line_count += _draw_line(main, from_line, ofs, text_rect.size.x, base_color, outline_size, outline_color, font_shadow_color, use_outline, shadow_ofs);
ofs.y += main->lines[from_line].text_buf->get_size().y;
from_line++;
}
@@ -1532,53 +1575,36 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
- if (k->is_pressed() && !k->get_alt() && !k->get_shift()) {
+ if (k->is_pressed()) {
bool handled = false;
- switch (k->get_keycode()) {
- case KEY_PAGEUP: {
- if (vscroll->is_visible_in_tree()) {
- vscroll->set_value(vscroll->get_value() - vscroll->get_page());
- handled = true;
- }
- } break;
- case KEY_PAGEDOWN: {
- if (vscroll->is_visible_in_tree()) {
- vscroll->set_value(vscroll->get_value() + vscroll->get_page());
- handled = true;
- }
- } break;
- case KEY_UP: {
- if (vscroll->is_visible_in_tree()) {
- vscroll->set_value(vscroll->get_value() - get_theme_font("normal_font")->get_height(get_theme_font_size("normal_font_size")));
- handled = true;
- }
- } break;
- case KEY_DOWN: {
- if (vscroll->is_visible_in_tree()) {
- vscroll->set_value(vscroll->get_value() + get_theme_font("normal_font")->get_height(get_theme_font_size("normal_font_size")));
- handled = true;
- }
- } break;
- case KEY_HOME: {
- if (vscroll->is_visible_in_tree()) {
- vscroll->set_value(0);
- handled = true;
- }
- } break;
- case KEY_END: {
- if (vscroll->is_visible_in_tree()) {
- vscroll->set_value(vscroll->get_max());
- handled = true;
- }
- } break;
- case KEY_INSERT:
- case KEY_C: {
- if (k->get_command()) {
- selection_copy();
- handled = true;
- }
- } break;
+ if (k->is_action("ui_page_up") && vscroll->is_visible_in_tree()) {
+ vscroll->set_value(vscroll->get_value() - vscroll->get_page());
+ handled = true;
+ }
+ if (k->is_action("ui_page_down") && vscroll->is_visible_in_tree()) {
+ vscroll->set_value(vscroll->get_value() + vscroll->get_page());
+ handled = true;
+ }
+ if (k->is_action("ui_up") && vscroll->is_visible_in_tree()) {
+ vscroll->set_value(vscroll->get_value() - get_theme_font("normal_font")->get_height(get_theme_font_size("normal_font_size")));
+ handled = true;
+ }
+ if (k->is_action("ui_down") && vscroll->is_visible_in_tree()) {
+ vscroll->set_value(vscroll->get_value() + get_theme_font("normal_font")->get_height(get_theme_font_size("normal_font_size")));
+ handled = true;
+ }
+ if (k->is_action("ui_home") && vscroll->is_visible_in_tree()) {
+ vscroll->set_value(0);
+ handled = true;
+ }
+ if (k->is_action("ui_end") && vscroll->is_visible_in_tree()) {
+ vscroll->set_value(vscroll->get_max());
+ handled = true;
+ }
+ if (k->is_action("ui_copy")) {
+ selection_copy();
+ handled = true;
}
if (handled) {
@@ -1712,7 +1738,7 @@ int RichTextLabel::_find_font_size(Item *p_item) {
return -1;
}
-int RichTextLabel::_find_outline_size(Item *p_item) {
+int RichTextLabel::_find_outline_size(Item *p_item, int p_default) {
Item *sizeitem = p_item;
while (sizeitem) {
@@ -1724,7 +1750,7 @@ int RichTextLabel::_find_outline_size(Item *p_item) {
sizeitem = sizeitem->parent;
}
- return 0;
+ return p_default;
}
Dictionary RichTextLabel::_find_font_features(Item *p_item) {
@@ -1742,6 +1768,19 @@ Dictionary RichTextLabel::_find_font_features(Item *p_item) {
return Dictionary();
}
+RichTextLabel::ItemDropcap *RichTextLabel::_find_dc_item(Item *p_item) {
+ Item *item = p_item;
+
+ while (item) {
+ if (item->type == ITEM_DROPCAP) {
+ return static_cast<ItemDropcap *>(item);
+ }
+ item = item->parent;
+ }
+
+ return nullptr;
+}
+
RichTextLabel::ItemList *RichTextLabel::_find_list_item(Item *p_item) {
Item *item = p_item;
@@ -1793,7 +1832,7 @@ int RichTextLabel::_find_list(Item *p_item, Vector<int> &r_index, Vector<ItemLis
int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int p_base_font_size) {
Item *item = p_item;
- float margin = 0;
+ float margin = 0.0;
while (item) {
if (item->type == ITEM_INDENT) {
@@ -1805,7 +1844,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int
if (font_size == -1) {
font_size = p_base_font_size;
}
- margin += tab_size * font->get_char_size('m', 0, font_size).width;
+ margin += tab_size * font->get_char_size(' ', 0, font_size).width;
} else if (item->type == ITEM_LIST) {
Ref<Font> font = _find_font(item);
@@ -1816,7 +1855,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int
if (font_size == -1) {
font_size = p_base_font_size;
}
- margin += tab_size * font->get_char_size('m', 0, font_size).width;
+ margin += tab_size * font->get_char_size(' ', 0, font_size).width;
}
item = item->parent;
@@ -1960,46 +1999,6 @@ void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack
}
}
-Color RichTextLabel::_get_color_from_string(const String &p_color_str, const Color &p_default_color) {
- if (p_color_str.begins_with("#")) {
- return Color::html(p_color_str);
- } else if (p_color_str == "aqua") {
- return Color(0, 1, 1);
- } else if (p_color_str == "black") {
- return Color(0, 0, 0);
- } else if (p_color_str == "blue") {
- return Color(0, 0, 1);
- } else if (p_color_str == "fuchsia") {
- return Color(1, 0, 1);
- } else if (p_color_str == "gray" || p_color_str == "grey") {
- return Color(0.5, 0.5, 0.5);
- } else if (p_color_str == "green") {
- return Color(0, 0.5, 0);
- } else if (p_color_str == "lime") {
- return Color(0, 1, 0);
- } else if (p_color_str == "maroon") {
- return Color(0.5, 0, 0);
- } else if (p_color_str == "navy") {
- return Color(0, 0, 0.5);
- } else if (p_color_str == "olive") {
- return Color(0.5, 0.5, 0);
- } else if (p_color_str == "purple") {
- return Color(0.5, 0, 0.5);
- } else if (p_color_str == "red") {
- return Color(1, 0, 0);
- } else if (p_color_str == "silver") {
- return Color(0.75, 0.75, 0.75);
- } else if (p_color_str == "teal") {
- return Color(0, 0.5, 0.5);
- } else if (p_color_str == "white") {
- return Color(1, 1, 1);
- } else if (p_color_str == "yellow") {
- return Color(1, 1, 0);
- } else {
- return p_default_color;
- }
-}
-
bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) {
Item *item = p_item;
@@ -2238,6 +2237,8 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width,
}
ERR_FAIL_COND(p_image.is_null());
+ ERR_FAIL_COND(p_image->get_width() == 0);
+ ERR_FAIL_COND(p_image->get_height() == 0);
ItemImage *item = memnew(ItemImage);
item->image = p_image;
@@ -2316,6 +2317,24 @@ bool RichTextLabel::remove_line(const int p_line) {
return true;
}
+void RichTextLabel::push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins, const Color &p_color, int p_ol_size, const Color &p_ol_color) {
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
+ ERR_FAIL_COND(p_string.is_empty());
+ ERR_FAIL_COND(p_font.is_null());
+ ERR_FAIL_COND(p_size <= 0);
+
+ ItemDropcap *item = memnew(ItemDropcap);
+
+ item->text = p_string;
+ item->font = p_font;
+ item->font_size = p_size;
+ item->color = p_color;
+ item->ol_size = p_ol_size;
+ item->ol_color = p_ol_color;
+ item->dropcap_margins = p_dropcap_margins;
+ _add_item(item, false);
+}
+
void RichTextLabel::push_font(const Ref<Font> &p_font) {
ERR_FAIL_COND(current->type == ITEM_TABLE);
ERR_FAIL_COND(p_font.is_null());
@@ -2723,7 +2742,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
String bbcode_name;
typedef Map<String, String> OptionMap;
OptionMap bbcode_options;
- if (!split_tag_block.empty()) {
+ if (!split_tag_block.is_empty()) {
bbcode_name = split_tag_block[0];
for (int i = 1; i < split_tag_block.size(); i++) {
const String &expr = split_tag_block[i];
@@ -2765,7 +2784,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
tag_stack.pop_front();
pos = brk_end + 1;
- if (tag != "/img") {
+ if (tag != "/img" && tag != "/dropcap") {
pop();
}
@@ -2846,17 +2865,18 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
}
}
push_cell();
+ const Color fallback_color = Color(0, 0, 0, 0);
for (int i = 0; i < subtag.size(); i++) {
Vector<String> subtag_a = subtag[i].split("=");
if (subtag_a.size() == 2) {
if (subtag_a[0] == "border") {
- Color color = _get_color_from_string(subtag_a[1], Color(0, 0, 0, 0));
+ Color color = Color::from_string(subtag_a[1], fallback_color);
set_cell_border_color(color);
} else if (subtag_a[0] == "bg") {
Vector<String> subtag_b = subtag_a[1].split(",");
if (subtag_b.size() == 2) {
- Color color1 = _get_color_from_string(subtag_b[0], Color(0, 0, 0, 0));
- Color color2 = _get_color_from_string(subtag_b[1], Color(0, 0, 0, 0));
+ Color color1 = Color::from_string(subtag_b[0], fallback_color);
+ Color color2 = Color::from_string(subtag_b[1], fallback_color);
set_cell_row_background_color(color1, color2);
}
}
@@ -3041,6 +3061,54 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
push_meta(url);
pos = brk_end + 1;
tag_stack.push_front("url");
+ } else if (tag.begins_with("dropcap")) {
+ Vector<String> subtag = tag.substr(5, tag.length()).split(" ");
+ Ref<Font> f = get_theme_font("normal_font");
+ int fs = get_theme_font_size("normal_font_size") * 3;
+ Color color = get_theme_color("default_color");
+ Color outline_color = get_theme_color("outline_color");
+ int outline_size = get_theme_constant("outline_size");
+ Rect2 dropcap_margins = Rect2();
+
+ for (int i = 0; i < subtag.size(); i++) {
+ Vector<String> subtag_a = subtag[i].split("=");
+ if (subtag_a.size() == 2) {
+ if (subtag_a[0] == "font" || subtag_a[0] == "f") {
+ String fnt = subtag_a[1];
+ Ref<Font> font = ResourceLoader::load(fnt, "Font");
+ if (font.is_valid()) {
+ f = font;
+ }
+ } else if (subtag_a[0] == "font_size") {
+ fs = subtag_a[1].to_int();
+ } else if (subtag_a[0] == "margins") {
+ Vector<String> subtag_b = subtag_a[1].split(",");
+ if (subtag_b.size() == 4) {
+ dropcap_margins.position.x = subtag_b[0].to_float();
+ dropcap_margins.position.y = subtag_b[1].to_float();
+ dropcap_margins.size.x = subtag_b[2].to_float();
+ dropcap_margins.size.y = subtag_b[3].to_float();
+ }
+ } else if (subtag_a[0] == "outline_size") {
+ outline_size = subtag_a[1].to_int();
+ } else if (subtag_a[0] == "color") {
+ color = Color::from_string(subtag_a[1], color);
+ } else if (subtag_a[0] == "outline_color") {
+ outline_color = Color::from_string(subtag_a[1], outline_color);
+ }
+ }
+ }
+ int end = p_bbcode.find("[", brk_end);
+ if (end == -1) {
+ end = p_bbcode.length();
+ }
+
+ String txt = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
+
+ push_dropcap(txt, f, fs, dropcap_margins, color, outline_size, outline_color);
+
+ pos = end;
+ tag_stack.push_front(bbcode_name);
} else if (tag.begins_with("img")) {
VAlign align = VALIGN_TOP;
if (tag.begins_with("img=")) {
@@ -3066,12 +3134,12 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
Color color = Color(1.0, 1.0, 1.0);
OptionMap::Element *color_option = bbcode_options.find("color");
if (color_option) {
- color = _get_color_from_string(color_option->value(), color);
+ color = Color::from_string(color_option->value(), color);
}
int width = 0;
int height = 0;
- if (!bbcode_value.empty()) {
+ if (!bbcode_value.is_empty()) {
int sep = bbcode_value.find("x");
if (sep == -1) {
width = bbcode_value.to_int();
@@ -3098,14 +3166,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
tag_stack.push_front(bbcode_name);
} else if (tag.begins_with("color=")) {
String color_str = tag.substr(6, tag.length());
- Color color = _get_color_from_string(color_str, base_color);
+ Color color = Color::from_string(color_str, base_color);
push_color(color);
pos = brk_end + 1;
tag_stack.push_front("color");
} else if (tag.begins_with("outline_color=")) {
String color_str = tag.substr(14, tag.length());
- Color color = _get_color_from_string(color_str, base_color);
+ Color color = Color::from_string(color_str, base_color);
push_outline_color(color);
pos = brk_end + 1;
tag_stack.push_front("outline_color");
@@ -3299,14 +3367,46 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
return OK;
}
+void RichTextLabel::scroll_to_paragraph(int p_paragraph) {
+ ERR_FAIL_INDEX(p_paragraph, main->lines.size());
+ _validate_line_caches(main);
+ vscroll->set_value(main->lines[p_paragraph].offset.y);
+}
+
+int RichTextLabel::get_paragraph_count() const {
+ return current_frame->lines.size();
+}
+
+int RichTextLabel::get_visible_paragraph_count() const {
+ if (!is_visible()) {
+ return 0;
+ }
+ return visible_paragraph_count;
+}
+
void RichTextLabel::scroll_to_line(int p_line) {
- ERR_FAIL_INDEX(p_line, main->lines.size());
_validate_line_caches(main);
- vscroll->set_value(main->lines[p_line].offset.y);
+
+ int line_count = 0;
+ for (int i = 0; i < main->lines.size(); i++) {
+ if ((line_count <= p_line) && (line_count + main->lines[i].text_buf->get_line_count() >= p_line)) {
+ float line_offset = 0.f;
+ for (int j = 0; j < p_line - line_count; j++) {
+ line_offset += main->lines[i].text_buf->get_line_size(j).y;
+ }
+ vscroll->set_value(main->lines[i].offset.y + line_offset);
+ return;
+ }
+ line_count += main->lines[i].text_buf->get_line_count();
+ }
}
int RichTextLabel::get_line_count() const {
- return current_frame->lines.size();
+ int line_count = 0;
+ for (int i = 0; i < main->lines.size(); i++) {
+ line_count += main->lines[i].text_buf->get_line_count();
+ }
+ return line_count;
}
int RichTextLabel::get_visible_line_count() const {
@@ -3407,7 +3507,7 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
return false;
}
-String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p_selection) {
+String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p_selection) const {
String text;
ERR_FAIL_COND_V(p_frame == nullptr, text);
ERR_FAIL_COND_V(p_line < 0 || p_line >= p_frame->lines.size(), text);
@@ -3474,7 +3574,7 @@ String RichTextLabel::_get_line_text(ItemFrame *p_frame, int p_line, Selection p
return text;
}
-String RichTextLabel::get_selected_text() {
+String RichTextLabel::get_selected_text() const {
if (!selection.active || !selection.enabled) {
return "";
}
@@ -3498,6 +3598,22 @@ bool RichTextLabel::is_selection_enabled() const {
return selection.enabled;
}
+int RichTextLabel::get_selection_from() const {
+ if (!selection.active || !selection.enabled) {
+ return -1;
+ }
+
+ return selection.from_frame->lines[selection.from_line].char_offset + selection.from_char;
+}
+
+int RichTextLabel::get_selection_to() const {
+ if (!selection.active || !selection.enabled) {
+ return -1;
+ }
+
+ return selection.to_frame->lines[selection.to_line].char_offset + selection.to_char - 1;
+}
+
void RichTextLabel::set_bbcode(const String &p_bbcode) {
bbcode = p_bbcode;
if (is_inside_tree() && use_bbcode) {
@@ -3518,6 +3634,7 @@ void RichTextLabel::set_use_bbcode(bool p_enable) {
}
use_bbcode = p_enable;
set_bbcode(bbcode);
+ notify_property_list_changed();
}
bool RichTextLabel::is_using_bbcode() const {
@@ -3533,6 +3650,8 @@ String RichTextLabel::get_text() {
text += t->text;
} else if (it->type == ITEM_NEWLINE) {
text += "\n";
+ } else if (it->type == ITEM_IMAGE) {
+ text += " ";
} else if (it->type == ITEM_INDENT || it->type == ITEM_LIST) {
text += "\t";
}
@@ -3653,6 +3772,12 @@ int RichTextLabel::get_content_height() const {
return total_height;
}
+void RichTextLabel::_validate_property(PropertyInfo &property) const {
+ if (!use_bbcode && property.name == "bbcode_text") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &RichTextLabel::_gui_input);
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
@@ -3679,6 +3804,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline);
ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough);
ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(VALIGN_TOP));
+ ClassDB::bind_method(D_METHOD("push_dropcap", "string", "font", "size", "dropcap_margins", "color", "outline_size", "outline_color"), &RichTextLabel::push_dropcap, DEFVAL(Rect2()), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(0, 0, 0, 0)));
ClassDB::bind_method(D_METHOD("set_table_column_expand", "column", "expand", "ratio"), &RichTextLabel::set_table_column_expand);
ClassDB::bind_method(D_METHOD("set_cell_row_background_color", "odd_row_bg", "even_row_bg"), &RichTextLabel::set_cell_row_background_color);
ClassDB::bind_method(D_METHOD("set_cell_border_color", "color"), &RichTextLabel::set_cell_border_color);
@@ -3713,6 +3839,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_v_scroll"), &RichTextLabel::get_v_scroll);
ClassDB::bind_method(D_METHOD("scroll_to_line", "line"), &RichTextLabel::scroll_to_line);
+ ClassDB::bind_method(D_METHOD("scroll_to_paragraph", "paragraph"), &RichTextLabel::scroll_to_paragraph);
ClassDB::bind_method(D_METHOD("set_tab_size", "spaces"), &RichTextLabel::set_tab_size);
ClassDB::bind_method(D_METHOD("get_tab_size"), &RichTextLabel::get_tab_size);
@@ -3723,6 +3850,11 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_selection_enabled", "enabled"), &RichTextLabel::set_selection_enabled);
ClassDB::bind_method(D_METHOD("is_selection_enabled"), &RichTextLabel::is_selection_enabled);
+ ClassDB::bind_method(D_METHOD("get_selection_from"), &RichTextLabel::get_selection_from);
+ ClassDB::bind_method(D_METHOD("get_selection_to"), &RichTextLabel::get_selection_to);
+
+ ClassDB::bind_method(D_METHOD("get_selected_text"), &RichTextLabel::get_selected_text);
+
ClassDB::bind_method(D_METHOD("parse_bbcode", "bbcode"), &RichTextLabel::parse_bbcode);
ClassDB::bind_method(D_METHOD("append_bbcode", "bbcode"), &RichTextLabel::append_bbcode);
@@ -3743,6 +3875,9 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_count"), &RichTextLabel::get_line_count);
ClassDB::bind_method(D_METHOD("get_visible_line_count"), &RichTextLabel::get_visible_line_count);
+ ClassDB::bind_method(D_METHOD("get_paragraph_count"), &RichTextLabel::get_paragraph_count);
+ ClassDB::bind_method(D_METHOD("get_visible_paragraph_count"), &RichTextLabel::get_visible_paragraph_count);
+
ClassDB::bind_method(D_METHOD("get_content_height"), &RichTextLabel::get_content_height);
ClassDB::bind_method(D_METHOD("parse_expressions_for_values", "expressions"), &RichTextLabel::parse_expressions_for_values);
@@ -3814,12 +3949,21 @@ void RichTextLabel::_bind_methods() {
BIND_ENUM_CONSTANT(ITEM_WAVE);
BIND_ENUM_CONSTANT(ITEM_TORNADO);
BIND_ENUM_CONSTANT(ITEM_RAINBOW);
- BIND_ENUM_CONSTANT(ITEM_CUSTOMFX);
BIND_ENUM_CONSTANT(ITEM_META);
+ BIND_ENUM_CONSTANT(ITEM_DROPCAP);
+ BIND_ENUM_CONSTANT(ITEM_CUSTOMFX);
}
void RichTextLabel::set_visible_characters(int p_visible) {
visible_characters = p_visible;
+ if (p_visible == -1) {
+ percent_visible = 1;
+ } else {
+ int total_char_count = get_total_character_count();
+ if (total_char_count > 0) {
+ percent_visible = (float)p_visible / (float)total_char_count;
+ }
+ }
update();
}
@@ -3937,19 +4081,6 @@ RichTextLabel::RichTextLabel() {
main->first_invalid_line = 0;
main->first_resized_line = 0;
current_frame = main;
- tab_size = 4;
- default_align = ALIGN_LEFT;
- underline_meta = true;
- meta_hovering = nullptr;
- override_selected_font_color = false;
-
- scroll_visible = false;
- scroll_follow = false;
- scroll_following = false;
- updating_scroll = false;
- scroll_active = true;
- scroll_w = 0;
- scroll_updated = false;
vscroll = memnew(VScrollBar);
add_child(vscroll);
@@ -3961,19 +4092,6 @@ RichTextLabel::RichTextLabel() {
vscroll->connect("value_changed", callable_mp(this, &RichTextLabel::_scroll_changed));
vscroll->set_step(1);
vscroll->hide();
- use_bbcode = false;
-
- selection.click_frame = nullptr;
- selection.click_item = nullptr;
- selection.active = false;
- selection.enabled = false;
-
- visible_characters = -1;
- percent_visible = 1;
- visible_line_count = 0;
-
- fixed_width = -1;
- fit_content_height = false;
set_clip_contents(true);
}
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index f1dac69dce..e3e457d1f2 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -76,11 +76,14 @@ public:
ITEM_TORNADO,
ITEM_RAINBOW,
ITEM_META,
+ ITEM_DROPCAP,
ITEM_CUSTOMFX
};
protected:
+ void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
private:
struct Item;
@@ -89,6 +92,9 @@ private:
Item *from = nullptr;
Ref<TextParagraph> text_buf;
+ Color dc_color;
+ int dc_ol_size = 0;
+ Color dc_ol_color;
Vector2 offset;
int char_offset = 0;
@@ -140,6 +146,17 @@ private:
ItemText() { type = ITEM_TEXT; }
};
+ struct ItemDropcap : public Item {
+ String text;
+ Ref<Font> font;
+ int font_size = 0;
+ Color color;
+ int ol_size = 0;
+ Color ol_color;
+ Rect2 dropcap_margins;
+ ItemDropcap() { type = ITEM_DROPCAP; }
+ };
+
struct ItemImage : public Item {
Ref<Texture2D> image;
VAlign inline_align = VALIGN_TOP;
@@ -217,11 +234,11 @@ private:
struct ItemTable : public Item {
struct Column {
- bool expand;
- int expand_ratio;
- int min_width;
- int max_width;
- int width;
+ bool expand = false;
+ int expand_ratio = 0;
+ int min_width = 0;
+ int max_width = 0;
+ int width = 0;
};
Vector<Column> columns;
@@ -307,30 +324,31 @@ private:
}
};
- ItemFrame *main;
- Item *current;
- ItemFrame *current_frame;
+ ItemFrame *main = nullptr;
+ Item *current = nullptr;
+ ItemFrame *current_frame = nullptr;
- VScrollBar *vscroll;
+ VScrollBar *vscroll = nullptr;
- bool scroll_visible;
- bool scroll_follow;
- bool scroll_following;
- bool scroll_active;
- int scroll_w;
- bool scroll_updated;
- bool updating_scroll;
+ bool scroll_visible = false;
+ bool scroll_follow = false;
+ bool scroll_following = false;
+ bool scroll_active = true;
+ int scroll_w = 0;
+ bool scroll_updated = false;
+ bool updating_scroll = false;
int current_idx = 1;
int current_char_ofs = 0;
- int visible_line_count;
+ int visible_paragraph_count = 0;
+ int visible_line_count = 0;
- int tab_size;
- bool underline_meta;
- bool override_selected_font_color;
+ int tab_size = 4;
+ bool underline_meta = true;
+ bool override_selected_font_color = false;
- Align default_align;
+ Align default_align = ALIGN_LEFT;
- ItemMeta *meta_hovering;
+ ItemMeta *meta_hovering = nullptr;
Variant current_meta;
Vector<Ref<RichTextEffect>> custom_effects;
@@ -347,38 +365,38 @@ private:
Array st_args;
struct Selection {
- ItemFrame *click_frame;
- int click_line;
- Item *click_item;
- int click_char;
-
- ItemFrame *from_frame;
- int from_line;
- Item *from_item;
- int from_char;
-
- ItemFrame *to_frame;
- int to_line;
- Item *to_item;
- int to_char;
-
- bool active; // anything selected? i.e. from, to, etc. valid?
- bool enabled; // allow selections?
+ ItemFrame *click_frame = nullptr;
+ int click_line = 0;
+ Item *click_item = nullptr;
+ int click_char = 0;
+
+ ItemFrame *from_frame = nullptr;
+ int from_line = 0;
+ Item *from_item = nullptr;
+ int from_char = 0;
+
+ ItemFrame *to_frame = nullptr;
+ int to_line = 0;
+ Item *to_item = nullptr;
+ int to_char = 0;
+
+ bool active = false; // anything selected? i.e. from, to, etc. valid?
+ bool enabled = false; // allow selections?
};
Selection selection;
- int visible_characters;
- float percent_visible;
+ int visible_characters = -1;
+ float percent_visible = 1.0;
void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr);
- String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel);
+ String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel) const;
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, Item *p_from, Item *p_to);
void _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, int *r_char_offset);
void _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width);
- void _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_color_shadow, bool p_shadow_as_outline, const Point2 &shadow_ofs);
+ int _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, bool p_shadow_as_outline, const Point2 &shadow_ofs);
float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr);
String _roman(int p_num, bool p_capitalize) const;
@@ -389,8 +407,9 @@ private:
Ref<Font> _find_font(Item *p_item);
int _find_font_size(Item *p_item);
Dictionary _find_font_features(Item *p_item);
- int _find_outline_size(Item *p_item);
+ int _find_outline_size(Item *p_item, int p_default);
ItemList *_find_list_item(Item *p_item);
+ ItemDropcap *_find_dc_item(Item *p_item);
int _find_list(Item *p_item, Vector<int> &r_index, Vector<ItemList *> &r_list);
int _find_margin(Item *p_item, const Ref<Font> &p_base_font, int p_base_font_size);
Align _find_align(Item *p_item);
@@ -405,29 +424,24 @@ private:
bool _find_layout_subitem(Item *from, Item *to);
void _fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack);
- static Color _get_color_from_string(const String &p_color_str, const Color &p_default_color);
-
void _update_scroll();
void _update_fx(ItemFrame *p_frame, float p_delta_time);
void _scroll_changed(double);
void _gui_input(Ref<InputEvent> p_event);
- Item *_get_next_item(Item *p_item, bool p_free = false);
- Item *_get_prev_item(Item *p_item, bool p_free = false);
+ Item *_get_next_item(Item *p_item, bool p_free = false) const;
+ Item *_get_prev_item(Item *p_item, bool p_free = false) const;
Rect2 _get_text_rect();
Ref<RichTextEffect> _get_custom_effect_by_code(String p_bbcode_identifier);
virtual Dictionary parse_expressions_for_values(Vector<String> p_expressions);
- bool use_bbcode;
+ bool use_bbcode = false;
String bbcode;
- int fixed_width;
+ int fixed_width = -1;
- bool fit_content_height;
-
-protected:
- void _notification(int p_what);
+ bool fit_content_height = false;
public:
String get_text();
@@ -435,6 +449,7 @@ public:
void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0), VAlign p_align = VALIGN_TOP);
void add_newline();
bool remove_line(const int p_line);
+ void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0));
void push_font(const Ref<Font> &p_font);
void push_font_size(int p_font_size);
void push_font_features(const Dictionary &p_features);
@@ -492,6 +507,10 @@ public:
bool search(const String &p_string, bool p_from_selection = false, bool p_search_previous = false);
+ void scroll_to_paragraph(int p_paragraph);
+ int get_paragraph_count() const;
+ int get_visible_paragraph_count() const;
+
void scroll_to_line(int p_line);
int get_line_count() const;
int get_visible_line_count() const;
@@ -504,7 +523,9 @@ public:
void set_selection_enabled(bool p_enabled);
bool is_selection_enabled() const;
- String get_selected_text();
+ int get_selection_from() const;
+ int get_selection_to() const;
+ String get_selected_text() const;
void selection_copy();
Error parse_bbcode(const String &p_bbcode);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 1a4d19eab3..f2516e76a5 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -434,7 +434,7 @@ double ScrollBar::get_area_size() const {
}
double ScrollBar::get_area_offset() const {
- double ofs = 0;
+ double ofs = 0.0;
if (orientation == VERTICAL) {
ofs += get_theme_stylebox("hscroll")->get_margin(SIDE_TOP);
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index 358ed74965..24b3b33e82 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,14 +47,14 @@ class ScrollBar : public Range {
Orientation orientation;
Size2 size;
- float custom_step = -1;
+ float custom_step = -1.0;
HighlightStatus highlight = HIGHLIGHT_NONE;
struct Drag {
bool active = false;
- float pos_at_click = 0;
- float value_at_click = 0;
+ float pos_at_click = 0.0;
+ float value_at_click = 0.0;
} drag;
double get_grabber_size() const;
@@ -73,14 +73,14 @@ class ScrollBar : public Range {
Vector2 drag_node_accum;
Vector2 drag_node_from;
Vector2 last_drag_node_accum;
- float last_drag_node_time;
- float time_since_motion;
+ float last_drag_node_time = 0.0;
+ float time_since_motion = 0.0;
bool drag_node_touching = false;
bool drag_node_touching_deaccel = false;
- bool click_handled;
+ bool click_handled = false;
bool scrolling = false;
- double target_scroll = 0;
+ double target_scroll = 0.0;
bool smooth_scroll_enabled = false;
void _drag_node_exit();
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 942593df27..411891ece8 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -244,11 +244,11 @@ void ScrollContainer::_ensure_focused_visible(Control *p_control) {
if (is_a_parent_of(p_control)) {
Rect2 global_rect = get_global_rect();
Rect2 other_rect = p_control->get_global_rect();
- float right_margin = 0;
+ float right_margin = 0.0;
if (v_scroll->is_visible()) {
right_margin += v_scroll->get_size().x;
}
- float bottom_margin = 0;
+ float bottom_margin = 0.0;
if (h_scroll->is_visible()) {
bottom_margin += h_scroll->get_size().y;
}
@@ -264,6 +264,67 @@ void ScrollContainer::_ensure_focused_visible(Control *p_control) {
}
}
+void ScrollContainer::_update_dimensions() {
+ child_max_size = Size2(0, 0);
+ Size2 size = get_size();
+ Point2 ofs;
+
+ Ref<StyleBox> sb = get_theme_stylebox("bg");
+ size -= sb->get_minimum_size();
+ ofs += sb->get_offset();
+ bool rtl = is_layout_rtl();
+
+ if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
+ size.y -= h_scroll->get_minimum_size().y;
+ }
+
+ if (v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
+ size.x -= v_scroll->get_minimum_size().x;
+ }
+
+ for (int i = 0; i < get_child_count(); i++) {
+ Control *c = Object::cast_to<Control>(get_child(i));
+ if (!c) {
+ continue;
+ }
+ if (c->is_set_as_top_level()) {
+ continue;
+ }
+ if (c == h_scroll || c == v_scroll) {
+ continue;
+ }
+ Size2 minsize = c->get_combined_minimum_size();
+ child_max_size.x = MAX(child_max_size.x, minsize.x);
+ child_max_size.y = MAX(child_max_size.y, minsize.y);
+
+ Rect2 r = Rect2(-scroll, minsize);
+ if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
+ r.position.x = 0;
+ if (c->get_h_size_flags() & SIZE_EXPAND) {
+ r.size.width = MAX(size.width, minsize.width);
+ } else {
+ r.size.width = minsize.width;
+ }
+ }
+ if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
+ r.position.y = 0;
+ if (c->get_v_size_flags() & SIZE_EXPAND) {
+ r.size.height = MAX(size.height, minsize.height);
+ } else {
+ r.size.height = minsize.height;
+ }
+ }
+ r.position += ofs;
+ if (rtl && v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) {
+ r.position.x += v_scroll->get_minimum_size().x;
+ }
+ r.position = r.position.floor();
+ fit_child_in_rect(c, r);
+ }
+
+ update();
+}
+
void ScrollContainer::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) {
_updating_scrollbars = true;
@@ -272,67 +333,11 @@ void ScrollContainer::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_ensure_focused_visible));
+ _update_dimensions();
}
if (p_what == NOTIFICATION_SORT_CHILDREN) {
- child_max_size = Size2(0, 0);
- Size2 size = get_size();
- Point2 ofs;
-
- Ref<StyleBox> sb = get_theme_stylebox("bg");
- size -= sb->get_minimum_size();
- ofs += sb->get_offset();
- bool rtl = is_layout_rtl();
-
- if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
- size.y -= h_scroll->get_minimum_size().y;
- }
-
- if (v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
- size.x -= v_scroll->get_minimum_size().x;
- }
-
- for (int i = 0; i < get_child_count(); i++) {
- Control *c = Object::cast_to<Control>(get_child(i));
- if (!c) {
- continue;
- }
- if (c->is_set_as_top_level()) {
- continue;
- }
- if (c == h_scroll || c == v_scroll) {
- continue;
- }
- Size2 minsize = c->get_combined_minimum_size();
- child_max_size.x = MAX(child_max_size.x, minsize.x);
- child_max_size.y = MAX(child_max_size.y, minsize.y);
-
- Rect2 r = Rect2(-scroll, minsize);
- if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
- r.position.x = 0;
- if (c->get_h_size_flags() & SIZE_EXPAND) {
- r.size.width = MAX(size.width, minsize.width);
- } else {
- r.size.width = minsize.width;
- }
- }
- if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
- r.position.y = 0;
- if (c->get_v_size_flags() & SIZE_EXPAND) {
- r.size.height = MAX(size.height, minsize.height);
- } else {
- r.size.height = minsize.height;
- }
- }
- r.position += ofs;
- if (rtl && v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) {
- r.position.x += v_scroll->get_minimum_size().x;
- }
- r.position = r.position.floor();
- fit_child_in_rect(c, r);
- }
-
- update();
+ _update_dimensions();
};
if (p_what == NOTIFICATION_DRAW) {
@@ -558,7 +563,7 @@ String ScrollContainer::get_configuration_warning() const {
}
if (found != 1) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually.");
@@ -619,15 +624,7 @@ ScrollContainer::ScrollContainer() {
add_child(v_scroll);
v_scroll->connect("value_changed", callable_mp(this, &ScrollContainer::_scroll_moved));
- drag_speed = Vector2();
- drag_touching = false;
- drag_touching_deaccel = false;
- beyond_deadzone = false;
- scroll_h = true;
- scroll_v = true;
-
deadzone = GLOBAL_GET("gui/common/default_scroll_deadzone");
- follow_focus = false;
set_clip_contents(true);
};
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index 4bf200009e..9d3ce39345 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,18 +50,18 @@ class ScrollContainer : public Container {
Vector2 drag_accum;
Vector2 drag_from;
Vector2 last_drag_accum;
- float last_drag_time;
- float time_since_motion;
- bool drag_touching;
- bool drag_touching_deaccel;
- bool click_handled;
- bool beyond_deadzone;
+ float last_drag_time = 0.0;
+ float time_since_motion = 0.0;
+ bool drag_touching = false;
+ bool drag_touching_deaccel = false;
+ bool click_handled = false;
+ bool beyond_deadzone = false;
- bool scroll_h;
- bool scroll_v;
+ bool scroll_h = true;
+ bool scroll_v = true;
- int deadzone;
- bool follow_focus;
+ int deadzone = 0;
+ bool follow_focus = false;
void _cancel_drag();
@@ -69,6 +69,7 @@ protected:
Size2 get_minimum_size() const override;
void _gui_input(const Ref<InputEvent> &p_gui_input);
+ void _update_dimensions();
void _notification(int p_what);
void _scroll_moved(float);
diff --git a/scene/gui/separator.cpp b/scene/gui/separator.cpp
index 4f7e5720b8..3cb8ccf135 100644
--- a/scene/gui/separator.cpp
+++ b/scene/gui/separator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/separator.h b/scene/gui/separator.h
index eec989cfea..77162c68fa 100644
--- a/scene/gui/separator.h
+++ b/scene/gui/separator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@ class Separator : public Control {
GDCLASS(Separator, Control);
protected:
- Orientation orientation;
+ Orientation orientation = Orientation::HORIZONTAL;
void _notification(int p_what);
public:
diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp
index f8c7bc44a7..cbbcf9e069 100644
--- a/scene/gui/shortcut.cpp
+++ b/scene/gui/shortcut.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/shortcut.h b/scene/gui/shortcut.h
index 176958b397..ea91f29b5d 100644
--- a/scene/gui/shortcut.h
+++ b/scene/gui/shortcut.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 3dd5e022f0..2239226c78 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -73,8 +73,10 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
}
} else if (scrollable) {
if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) {
+ grab_focus();
set_value(get_value() + get_step());
} else if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+ grab_focus();
set_value(get_value() - get_step());
}
}
@@ -269,12 +271,5 @@ void Slider::_bind_methods() {
Slider::Slider(Orientation p_orientation) {
orientation = p_orientation;
- mouse_inside = false;
- grab.active = false;
- ticks = 0;
- ticks_on_borders = false;
- custom_step = -1;
- editable = true;
- scrollable = true;
set_focus_mode(FOCUS_ALL);
}
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index b4b56f2856..65a4036cd1 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,23 +37,23 @@ class Slider : public Range {
GDCLASS(Slider, Range);
struct Grab {
- int pos;
- float uvalue;
- bool active;
+ int pos = 0;
+ float uvalue = 0.0;
+ bool active = false;
} grab;
- int ticks;
- bool mouse_inside;
+ int ticks = 0;
+ bool mouse_inside = false;
Orientation orientation;
- float custom_step;
- bool editable;
- bool scrollable;
+ float custom_step = -1.0;
+ bool editable = true;
+ bool scrollable = true;
protected:
void _gui_input(Ref<InputEvent> p_event);
void _notification(int p_what);
static void _bind_methods();
- bool ticks_on_borders;
+ bool ticks_on_borders = false;
public:
virtual Size2 get_minimum_size() const override;
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index a4de4a0408..d82cc98e01 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -91,6 +91,14 @@ void SpinBox::_range_click_timeout() {
}
}
+void SpinBox::_release_mouse() {
+ if (drag.enabled) {
+ drag.enabled = false;
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ warp_mouse(drag.capture_pos);
+ }
+}
+
void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
if (!is_editable()) {
return;
@@ -136,12 +144,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
//set_default_cursor_shape(CURSOR_ARROW);
range_click_timer->stop();
-
- if (drag.enabled) {
- drag.enabled = false;
- Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
- warp_mouse(drag.capture_pos);
- }
+ _release_mouse();
drag.allowed = false;
}
@@ -199,6 +202,8 @@ void SpinBox::_notification(int p_what) {
} else if (p_what == NOTIFICATION_ENTER_TREE) {
_adjust_width_for_icon(get_theme_icon("updown"));
_value_changed(0);
+ } else if (p_what == NOTIFICATION_EXIT_TREE) {
+ _release_mouse();
} else if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
_value_changed(0);
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
@@ -268,7 +273,6 @@ void SpinBox::_bind_methods() {
}
SpinBox::SpinBox() {
- last_w = 0;
line_edit = memnew(LineEdit);
add_child(line_edit);
@@ -280,7 +284,6 @@ SpinBox::SpinBox() {
line_edit->connect("text_entered", callable_mp(this, &SpinBox::_text_entered), Vector<Variant>(), CONNECT_DEFERRED);
line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), Vector<Variant>(), CONNECT_DEFERRED);
line_edit->connect("gui_input", callable_mp(this, &SpinBox::_line_edit_input));
- drag.enabled = false;
range_click_timer = memnew(Timer);
range_click_timer->connect("timeout", callable_mp(this, &SpinBox::_range_click_timeout));
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index 1b3dc9d79e..e116adb64c 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,10 +39,11 @@ class SpinBox : public Range {
GDCLASS(SpinBox, Range);
LineEdit *line_edit;
- int last_w;
+ int last_w = 0;
Timer *range_click_timer;
void _range_click_timeout();
+ void _release_mouse();
void _text_entered(const String &p_string);
virtual void _value_changed(double) override;
@@ -52,11 +53,11 @@ class SpinBox : public Range {
void _line_edit_input(const Ref<InputEvent> &p_event);
struct Drag {
- float base_val;
- bool allowed;
- bool enabled;
+ float base_val = 0.0;
+ bool allowed = false;
+ bool enabled = false;
Vector2 capture_pos;
- float diff_y;
+ float diff_y = 0.0;
} drag;
void _line_edit_focus_exit();
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index 1e85bba0e3..d43e195df1 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -102,7 +102,7 @@ void SplitContainer::_resort() {
middle_sep += clamped_split_offset;
if (should_clamp_split_offset) {
split_offset = clamped_split_offset;
- _change_notify("split_offset");
+
should_clamp_split_offset = false;
}
}
@@ -359,12 +359,5 @@ void SplitContainer::_bind_methods() {
}
SplitContainer::SplitContainer(bool p_vertical) {
- mouse_inside = false;
- split_offset = 0;
- should_clamp_split_offset = false;
- middle_sep = 0;
vertical = p_vertical;
- dragging = false;
- collapsed = false;
- dragger_visibility = DRAGGER_VISIBLE;
}
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index e345016f3d..6cb94d6ecf 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,16 +44,16 @@ public:
};
private:
- bool should_clamp_split_offset;
- int split_offset;
- int middle_sep;
- bool vertical;
- bool dragging;
- int drag_from;
- int drag_ofs;
- bool collapsed;
- DraggerVisibility dragger_visibility;
- bool mouse_inside;
+ bool should_clamp_split_offset = false;
+ int split_offset = 0;
+ int middle_sep = 0;
+ bool vertical = false;
+ bool dragging = false;
+ int drag_from = 0;
+ int drag_ofs = 0;
+ bool collapsed = false;
+ DraggerVisibility dragger_visibility = DRAGGER_VISIBLE;
+ bool mouse_inside = false;
Control *_getch(int p_idx) const;
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index c5f56fe8e2..8ffdd269a4 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -203,8 +203,6 @@ void SubViewportContainer::_bind_methods() {
}
SubViewportContainer::SubViewportContainer() {
- stretch = false;
- shrink = 1;
set_process_input(true);
set_process_unhandled_input(true);
}
diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h
index e82ad772ce..77cf4c16b3 100644
--- a/scene/gui/subviewport_container.h
+++ b/scene/gui/subviewport_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,8 +36,8 @@
class SubViewportContainer : public Container {
GDCLASS(SubViewportContainer, Container);
- bool stretch;
- int shrink;
+ bool stretch = false;
+ int shrink = 1;
protected:
void _notification(int p_what);
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index ddb2b1fe47..e3e3f549de 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,11 +43,11 @@ int TabContainer::_get_top_margin() const {
}
// Respect the minimum tab height.
- Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
- Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
+ Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected");
+ Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
- int tab_height = MAX(MAX(tab_bg->get_minimum_size().height, tab_fg->get_minimum_size().height), tab_disabled->get_minimum_size().height);
+ int tab_height = MAX(MAX(tab_unselected->get_minimum_size().height, tab_selected->get_minimum_size().height), tab_disabled->get_minimum_size().height);
// Font height or higher icon wins.
int content_height = 0;
@@ -337,8 +337,8 @@ void TabContainer::_notification(int p_what) {
}
Vector<Control *> tabs = _get_tabs();
- Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
- Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
+ Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected");
+ Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
Ref<Texture2D> increment = get_theme_icon("increment");
Ref<Texture2D> increment_hl = get_theme_icon("increment_highlight");
@@ -346,9 +346,9 @@ void TabContainer::_notification(int p_what) {
Ref<Texture2D> decrement_hl = get_theme_icon("decrement_highlight");
Ref<Texture2D> menu = get_theme_icon("menu");
Ref<Texture2D> menu_hl = get_theme_icon("menu_highlight");
- Color font_color_fg = get_theme_color("font_color_fg");
- Color font_color_bg = get_theme_color("font_color_bg");
- Color font_color_disabled = get_theme_color("font_color_disabled");
+ Color font_selected_color = get_theme_color("font_selected_color");
+ Color font_unselected_color = get_theme_color("font_unselected_color");
+ Color font_disabled_color = get_theme_color("font_disabled_color");
int side_margin = get_theme_constant("side_margin");
// Find out start and width of the header area.
@@ -433,17 +433,17 @@ void TabContainer::_notification(int p_what) {
int tab_width = tab_widths[i];
if (get_tab_disabled(index)) {
if (rtl) {
- _draw_tab(tab_disabled, font_color_disabled, index, size.width - (tabs_ofs_cache + x) - tab_width);
+ _draw_tab(tab_disabled, font_disabled_color, index, size.width - (tabs_ofs_cache + x) - tab_width);
} else {
- _draw_tab(tab_disabled, font_color_disabled, index, tabs_ofs_cache + x);
+ _draw_tab(tab_disabled, font_disabled_color, index, tabs_ofs_cache + x);
}
} else if (index == current) {
x_current = x;
} else {
if (rtl) {
- _draw_tab(tab_bg, font_color_bg, index, size.width - (tabs_ofs_cache + x) - tab_width);
+ _draw_tab(tab_unselected, font_unselected_color, index, size.width - (tabs_ofs_cache + x) - tab_width);
} else {
- _draw_tab(tab_bg, font_color_bg, index, tabs_ofs_cache + x);
+ _draw_tab(tab_unselected, font_unselected_color, index, tabs_ofs_cache + x);
}
}
@@ -459,9 +459,9 @@ void TabContainer::_notification(int p_what) {
// Draw selected tab in front. only draw selected tab when it's in visible range.
if (tabs.size() > 0 && current - first_tab_cache < tab_widths.size() && current >= first_tab_cache) {
if (rtl) {
- _draw_tab(tab_fg, font_color_fg, current, size.width - (tabs_ofs_cache + x_current) - tab_widths[current]);
+ _draw_tab(tab_selected, font_selected_color, current, size.width - (tabs_ofs_cache + x_current) - tab_widths[current]);
} else {
- _draw_tab(tab_fg, font_color_fg, current, tabs_ofs_cache + x_current);
+ _draw_tab(tab_selected, font_selected_color, current, tabs_ofs_cache + x_current);
}
}
@@ -535,6 +535,8 @@ void TabContainer::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, in
Vector<Control *> tabs = _get_tabs();
RID canvas = get_canvas_item();
Ref<Font> font = get_theme_font("font");
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
int icon_text_distance = get_theme_constant("icon_separation");
int tab_width = _get_tab_width(p_index);
int header_height = _get_top_margin();
@@ -565,6 +567,9 @@ void TabContainer::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, in
// Draw the tab text.
Point2i text_pos(x_content, y_center - text_buf[p_index]->get_size().y / 2);
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ text_buf[p_index]->draw_outline(canvas, text_pos, outline_size, font_outline_color);
+ }
text_buf[p_index]->draw(canvas, text_pos, p_font_color);
}
@@ -655,15 +660,15 @@ int TabContainer::_get_tab_width(int p_index) const {
}
// Respect a minimum size.
- Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
- Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
+ Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected");
+ Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
if (get_tab_disabled(p_index)) {
width += tab_disabled->get_minimum_size().width;
} else if (p_index == current) {
- width += tab_fg->get_minimum_size().width;
+ width += tab_selected->get_minimum_size().width;
} else {
- width += tab_bg->get_minimum_size().width;
+ width += tab_unselected->get_minimum_size().width;
}
return width;
@@ -747,8 +752,6 @@ void TabContainer::set_current_tab(int p_current) {
_repaint();
- _change_notify("current_tab");
-
if (pending_previous == current) {
emit_signal("tab_selected", current);
} else {
@@ -789,6 +792,10 @@ Control *TabContainer::get_current_tab_control() const {
void TabContainer::remove_child_notify(Node *p_child) {
Container::remove_child_notify(p_child);
+ if (!Object::cast_to<Control>(p_child)) {
+ return;
+ }
+
call_deferred("_update_current_tab");
p_child->disconnect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback));
@@ -963,8 +970,6 @@ void TabContainer::set_tab_align(TabAlign p_align) {
ERR_FAIL_INDEX(p_align, 3);
align = p_align;
update();
-
- _change_notify("tab_align");
}
TabContainer::TabAlign TabContainer::get_tab_align() const {
@@ -1127,13 +1132,13 @@ Size2 TabContainer::get_minimum_size() const {
ms.y = MAX(ms.y, cms.y);
}
- Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
- Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
+ Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected");
+ Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
Ref<Font> font = get_theme_font("font");
if (tabs_visible) {
- ms.y += MAX(MAX(tab_bg->get_minimum_size().y, tab_fg->get_minimum_size().y), tab_disabled->get_minimum_size().y);
+ ms.y += MAX(MAX(tab_unselected->get_minimum_size().y, tab_selected->get_minimum_size().y), tab_disabled->get_minimum_size().y);
ms.y += _get_top_margin();
}
@@ -1239,20 +1244,5 @@ void TabContainer::_bind_methods() {
}
TabContainer::TabContainer() {
- first_tab_cache = 0;
- last_tab_cache = 0;
- buttons_visible_cache = false;
- menu_hovered = false;
- highlight_arrow = -1;
- tabs_ofs_cache = 0;
- current = 0;
- previous = 0;
- align = ALIGN_CENTER;
- tabs_visible = true;
- all_tabs_in_front = false;
- drag_to_rearrange_enabled = false;
- tabs_rearrange_group = -1;
- use_hidden_tabs_for_min_size = false;
-
connect("mouse_exited", callable_mp(this, &TabContainer::_on_mouse_exited));
}
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index 9ff56afe6e..4ed5255729 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,23 +46,23 @@ public:
};
private:
- int first_tab_cache;
- int tabs_ofs_cache;
- int last_tab_cache;
- int current;
- int previous;
- bool tabs_visible;
- bool all_tabs_in_front;
- bool buttons_visible_cache;
- bool menu_hovered;
- int highlight_arrow;
- TabAlign align;
+ int first_tab_cache = 0;
+ int tabs_ofs_cache = 0;
+ int last_tab_cache = 0;
+ int current = 0;
+ int previous = 0;
+ bool tabs_visible = true;
+ bool all_tabs_in_front = false;
+ bool buttons_visible_cache = false;
+ bool menu_hovered = false;
+ int highlight_arrow = -1;
+ TabAlign align = ALIGN_CENTER;
Control *_get_tab(int p_idx) const;
int _get_top_margin() const;
mutable ObjectID popup_obj_id;
- bool drag_to_rearrange_enabled;
- bool use_hidden_tabs_for_min_size;
- int tabs_rearrange_group;
+ bool drag_to_rearrange_enabled = false;
+ bool use_hidden_tabs_for_min_size = false;
+ int tabs_rearrange_group = -1;
Vector<Ref<TextLine>> text_buf;
Vector<Control *> _get_tabs() const;
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index d332a5cbc6..da1a9698d0 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,11 +38,11 @@
#include "scene/gui/texture_rect.h"
Size2 Tabs::get_minimum_size() const {
- Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
- Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
+ Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected");
+ Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
- int y_margin = MAX(MAX(tab_bg->get_minimum_size().height, tab_fg->get_minimum_size().height), tab_disabled->get_minimum_size().height);
+ int y_margin = MAX(MAX(tab_unselected->get_minimum_size().height, tab_selected->get_minimum_size().height), tab_disabled->get_minimum_size().height);
Size2 ms(0, 0);
@@ -61,9 +61,9 @@ Size2 Tabs::get_minimum_size() const {
if (tabs[i].disabled) {
ms.width += tab_disabled->get_minimum_size().width;
} else if (current == i) {
- ms.width += tab_fg->get_minimum_size().width;
+ ms.width += tab_selected->get_minimum_size().width;
} else {
- ms.width += tab_bg->get_minimum_size().width;
+ ms.width += tab_unselected->get_minimum_size().width;
}
if (tabs[i].right_button.is_valid()) {
@@ -71,7 +71,7 @@ Size2 Tabs::get_minimum_size() const {
Size2 bms = rb->get_size();
bms.width += get_theme_constant("hseparation");
ms.width += bms.width;
- ms.height = MAX(bms.height + tab_bg->get_minimum_size().height, ms.height);
+ ms.height = MAX(bms.height + tab_unselected->get_minimum_size().height, ms.height);
}
if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
@@ -79,7 +79,7 @@ Size2 Tabs::get_minimum_size() const {
Size2 bms = cb->get_size();
bms.width += get_theme_constant("hseparation");
ms.width += bms.width;
- ms.height = MAX(bms.height + tab_bg->get_minimum_size().height, ms.height);
+ ms.height = MAX(bms.height + tab_unselected->get_minimum_size().height, ms.height);
}
}
@@ -268,13 +268,16 @@ void Tabs::_notification(int p_what) {
_update_cache();
RID ci = get_canvas_item();
- Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
- Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
+ Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected");
+ Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
- Color color_fg = get_theme_color("font_color_fg");
- Color color_bg = get_theme_color("font_color_bg");
- Color color_disabled = get_theme_color("font_color_disabled");
+ Color font_selected_color = get_theme_color("font_selected_color");
+ Color font_unselected_color = get_theme_color("font_unselected_color");
+ Color font_disabled_color = get_theme_color("font_disabled_color");
Ref<Texture2D> close = get_theme_icon("close");
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
+
Vector2 size = get_size();
bool rtl = is_layout_rtl();
@@ -316,13 +319,13 @@ void Tabs::_notification(int p_what) {
if (tabs[i].disabled) {
sb = tab_disabled;
- col = color_disabled;
+ col = font_disabled_color;
} else if (i == current) {
- sb = tab_fg;
- col = color_fg;
+ sb = tab_selected;
+ col = font_selected_color;
} else {
- sb = tab_bg;
- col = color_bg;
+ sb = tab_unselected;
+ col = font_unselected_color;
}
if (w + lsize > limit) {
@@ -357,9 +360,17 @@ void Tabs::_notification(int p_what) {
}
if (rtl) {
- tabs[i].text_buf->draw(ci, Point2i(size.width - w - tabs[i].text_buf->get_size().x, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2), col);
+ Vector2 text_pos = Point2i(size.width - w - tabs[i].text_buf->get_size().x, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2);
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ tabs[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
+ tabs[i].text_buf->draw(ci, text_pos, col);
} else {
- tabs[i].text_buf->draw(ci, Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2), col);
+ Vector2 text_pos = Point2i(w, sb->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[i].text_buf->get_size().y) / 2);
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ tabs[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
+ tabs[i].text_buf->draw(ci, text_pos, col);
}
w += tabs[i].size_text;
@@ -481,7 +492,6 @@ void Tabs::set_current_tab(int p_current) {
previous = current;
current = p_current;
- _change_notify("current_tab");
_update_cache();
update();
@@ -652,8 +662,8 @@ void Tabs::_update_hover() {
void Tabs::_update_cache() {
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
- Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
- Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
+ Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected");
+ Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
int limit = get_size().width - incr->get_width() - decr->get_width();
@@ -683,9 +693,9 @@ void Tabs::_update_cache() {
if (tabs[i].disabled) {
sb = tab_disabled;
} else if (i == current) {
- sb = tab_fg;
+ sb = tab_selected;
} else {
- sb = tab_bg;
+ sb = tab_unselected;
}
int lsize = tabs[i].size_cache;
int slen = tabs[i].size_text;
@@ -918,8 +928,8 @@ void Tabs::move_tab(int from, int to) {
int Tabs::get_tab_width(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, tabs.size(), 0);
- Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
- Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
+ Ref<StyleBox> tab_unselected = get_theme_stylebox("tab_unselected");
+ Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
int x = 0;
@@ -937,9 +947,9 @@ int Tabs::get_tab_width(int p_idx) const {
if (tabs[p_idx].disabled) {
x += tab_disabled->get_minimum_size().width;
} else if (current == p_idx) {
- x += tab_fg->get_minimum_size().width;
+ x += tab_selected->get_minimum_size().width;
} else {
- x += tab_bg->get_minimum_size().width;
+ x += tab_unselected->get_minimum_size().width;
}
if (tabs[p_idx].right_button.is_valid()) {
@@ -1137,27 +1147,5 @@ void Tabs::_bind_methods() {
}
Tabs::Tabs() {
- current = 0;
- previous = 0;
- tab_align = ALIGN_CENTER;
- rb_hover = -1;
- rb_pressing = false;
- highlight_arrow = -1;
-
- cb_hover = -1;
- cb_pressing = false;
- cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER;
- offset = 0;
- max_drawn_tab = 0;
-
- select_with_rmb = false;
-
- min_width = 0;
- scrolling_enabled = true;
- buttons_visible = false;
- hover = -1;
- drag_to_rearrange_enabled = false;
- tabs_rearrange_group = -1;
-
connect("mouse_exited", callable_mp(this, &Tabs::_on_mouse_exited));
}
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index bf62ba7210..86877f4d80 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,42 +63,42 @@ private:
Ref<TextLine> text_buf;
Ref<Texture2D> icon;
- int ofs_cache;
- bool disabled;
- int size_cache;
- int size_text;
- int x_cache;
- int x_size_cache;
+ int ofs_cache = 0;
+ bool disabled = false;
+ int size_cache = 0;
+ int size_text = 0;
+ int x_cache = 0;
+ int x_size_cache = 0;
Ref<Texture2D> right_button;
Rect2 rb_rect;
Rect2 cb_rect;
};
- int offset;
- int max_drawn_tab;
- int highlight_arrow;
- bool buttons_visible;
- bool missing_right;
+ int offset = 0;
+ int max_drawn_tab = 0;
+ int highlight_arrow = -1;
+ bool buttons_visible = false;
+ bool missing_right = false;
Vector<Tab> tabs;
- int current;
- int previous;
+ int current = 0;
+ int previous = 0;
int _get_top_margin() const;
- TabAlign tab_align;
- int rb_hover;
- bool rb_pressing;
+ TabAlign tab_align = ALIGN_CENTER;
+ int rb_hover = -1;
+ bool rb_pressing = false;
- bool select_with_rmb;
+ bool select_with_rmb = false;
- int cb_hover;
- bool cb_pressing;
- CloseButtonDisplayPolicy cb_displaypolicy;
+ int cb_hover = -1;
+ bool cb_pressing = false;
+ CloseButtonDisplayPolicy cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER;
- int hover; // Hovered tab.
- int min_width;
- bool scrolling_enabled;
- bool drag_to_rearrange_enabled;
- int tabs_rearrange_group;
+ int hover = -1; // Hovered tab.
+ int min_width = 0;
+ bool scrolling_enabled = true;
+ bool drag_to_rearrange_enabled = false;
+ int tabs_rearrange_group = -1;
int get_tab_width(int p_idx) const;
void _ensure_no_over_offset();
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 27d82c7ac7..e488e7a914 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/input/input.h"
+#include "core/input/input_map.h"
#include "core/object/message_queue.h"
#include "core/object/script_language.h"
#include "core/os/keyboard.h"
@@ -189,12 +190,12 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_
text.write[p_line].data_buf->set_preserve_control(draw_control_chars);
if (p_ime_text.length() > 0) {
text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, opentype_features, language);
- if (!p_bidi_override.empty()) {
+ if (!p_bidi_override.is_empty()) {
TS->shaped_text_set_bidi_override(text.write[p_line].data_buf->get_rid(), p_bidi_override);
}
} else {
text.write[p_line].data_buf->add_string(text[p_line].data, font, font_size, opentype_features, language);
- if (!text[p_line].bidi_override.empty()) {
+ if (!text[p_line].bidi_override.is_empty()) {
TS->shaped_text_set_bidi_override(text.write[p_line].data_buf->get_rid(), text[p_line].bidi_override);
}
}
@@ -202,7 +203,7 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_
// Apply tab align.
if (indent_size > 0) {
Vector<float> tabs;
- tabs.push_back(font->get_char_size('m', 0, font_size).width * indent_size);
+ tabs.push_back(font->get_char_size(' ', 0, font_size).width * indent_size);
text.write[p_line].data_buf->tab_align(tabs);
}
}
@@ -212,7 +213,7 @@ void TextEdit::Text::invalidate_all_lines() {
text.write[i].data_buf->set_width(width);
if (indent_size > 0) {
Vector<float> tabs;
- tabs.push_back(font->get_char_size('m', 0, font_size).width * indent_size);
+ tabs.push_back(font->get_char_size(' ', 0, font_size).width * indent_size);
text.write[i].data_buf->tab_align(tabs);
}
}
@@ -411,25 +412,16 @@ void TextEdit::_update_selection_mode_word() {
_get_mouse_pos(Point2i(mp.x, mp.y), row, col);
String line = text[row];
- int beg = CLAMP(col, 0, line.length());
- // If its the first selection and on whitespace make sure we grab the word instead.
- if (!selection.active) {
- while (beg > 0 && line[beg] <= 32) {
- beg--;
- }
- }
+ int cursor_pos = CLAMP(col, 0, line.length());
+ int beg = cursor_pos;
int end = beg;
- bool symbol = beg < line.length() && _is_symbol(line[beg]);
-
- // Get the word end and begin points.
- while (beg > 0 && line[beg - 1] > 32 && (symbol == _is_symbol(line[beg - 1]))) {
- beg--;
- }
- while (end < line.length() && line[end + 1] > 32 && (symbol == _is_symbol(line[end + 1]))) {
- end++;
- }
- if (end < line.length()) {
- end += 1;
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(row)->get_rid());
+ for (int i = 0; i < words.size(); i++) {
+ if (words[i].x < cursor_pos && words[i].y > cursor_pos) {
+ beg = words[i].x;
+ end = words[i].y;
+ break;
+ }
}
// Initial selection.
@@ -500,7 +492,7 @@ void TextEdit::_update_minimap_click() {
int row;
_get_minimap_mouse_row(Point2i(mp.x, mp.y), row);
- if (row >= get_first_visible_line() && (row < get_last_visible_line() || row >= (text.size() - 1))) {
+ if (row >= get_first_visible_line() && (row < get_last_full_visible_line() || row >= (text.size() - 1))) {
minimap_scroll_ratio = v_scroll->get_as_ratio();
minimap_scroll_click_pos = mp.y;
can_drag_minimap = true;
@@ -637,7 +629,7 @@ void TextEdit::_notification(int p_what) {
int visible_rows = get_visible_rows() + 1;
- Color color = readonly ? cache.font_color_readonly : cache.font_color;
+ Color color = readonly ? cache.font_readonly_color : cache.font_color;
if (cache.background_color.a > 0.01) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(), get_size()), cache.background_color);
@@ -810,8 +802,8 @@ void TextEdit::_notification(int p_what) {
}
}
+ bool is_cursor_line_visible = false;
Point2 cursor_pos;
- int cursor_insert_offset_y = 0;
// Get the highlighted words.
String highlighted_text = get_selection_text();
@@ -877,7 +869,7 @@ void TextEdit::_notification(int p_what) {
Color current_color = cache.font_color;
if (readonly) {
- current_color = cache.font_color_readonly;
+ current_color = cache.font_readonly_color;
}
Vector<String> wrap_rows = get_wrap_rows_text(minimap_line);
@@ -918,7 +910,7 @@ void TextEdit::_notification(int p_what) {
if (color_map.has(last_wrap_column + j)) {
current_color = color_map[last_wrap_column + j].get("color");
if (readonly) {
- current_color.a = cache.font_color_readonly.a;
+ current_color.a = cache.font_readonly_color.a;
}
}
color = current_color;
@@ -977,6 +969,16 @@ void TextEdit::_notification(int p_what) {
}
}
+ int top_limit_y = 0;
+ int bottom_limit_y = get_size().height;
+ if (readonly) {
+ top_limit_y += cache.style_readonly->get_margin(SIDE_TOP);
+ bottom_limit_y -= cache.style_readonly->get_margin(SIDE_BOTTOM);
+ } else {
+ top_limit_y += cache.style_normal->get_margin(SIDE_TOP);
+ bottom_limit_y -= cache.style_normal->get_margin(SIDE_BOTTOM);
+ }
+
// draw main text
int row_height = get_row_height();
int line = first_visible_line;
@@ -1001,7 +1003,7 @@ void TextEdit::_notification(int p_what) {
Dictionary color_map = _get_line_syntax_highlighting(line);
// Ensure we at least use the font color.
- Color current_color = readonly ? cache.font_color_readonly : cache.font_color;
+ Color current_color = readonly ? cache.font_readonly_color : cache.font_color;
const Ref<TextParagraph> ldata = text.get_line_data(line);
@@ -1019,17 +1021,33 @@ void TextEdit::_notification(int p_what) {
const String &str = wrap_rows[line_wrap_index];
int char_margin = xmargin_beg - cursor.x_ofs;
- int ofs_readonly = 0;
int ofs_x = 0;
+ int ofs_y = 0;
if (readonly) {
- ofs_readonly = cache.style_readonly->get_offset().y / 2;
ofs_x = cache.style_readonly->get_offset().x / 2;
+ ofs_x -= cache.style_normal->get_offset().x / 2;
+ ofs_y = cache.style_readonly->get_offset().y / 2;
+ } else {
+ ofs_y = cache.style_normal->get_offset().y / 2;
}
- int ofs_y = (i * row_height + cache.line_spacing / 2) + ofs_readonly;
+ ofs_y += i * row_height + cache.line_spacing / 2;
ofs_y -= cursor.wrap_ofs * row_height;
ofs_y -= get_v_scroll_offset() * row_height;
+ bool clipped = false;
+ if (ofs_y + row_height < top_limit_y) {
+ // Line is outside the top margin, clip current line.
+ // Still need to go through the process to prepare color changes for next lines.
+ clipped = true;
+ }
+
+ if (ofs_y > bottom_limit_y) {
+ // Line is outside the bottom margin, clip any remaining text.
+ i = draw_amount;
+ break;
+ }
+
if (text.is_marked(line)) {
if (rtl) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end - xmargin_beg, row_height), cache.mark_color);
@@ -1050,7 +1068,7 @@ void TextEdit::_notification(int p_what) {
// Give visual indication of empty selected line.
if (selection.active && line >= selection.from_line && line <= selection.to_line && char_margin >= xmargin_beg) {
- int char_w = cache.font->get_char_size('m', 0, cache.font_size).width;
+ int char_w = cache.font->get_char_size(' ', 0, cache.font_size).width;
if (rtl) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - xmargin_beg - ofs_x - char_w, ofs_y, char_w, row_height), cache.selection_color);
} else {
@@ -1091,6 +1109,9 @@ void TextEdit::_notification(int p_what) {
tl->add_string(text, cache.font, cache.font_size);
int yofs = ofs_y + (row_height - tl->get_size().y) / 2;
+ if (cache.outline_size > 0 && cache.outline_color.a > 0) {
+ tl->draw_outline(ci, Point2(gutter_offset + ofs_x, yofs), cache.outline_size, cache.outline_color);
+ }
tl->draw(ci, Point2(gutter_offset + ofs_x, yofs), get_line_gutter_item_color(line, g));
} break;
case GUTTER_TPYE_ICON: {
@@ -1147,7 +1168,7 @@ void TextEdit::_notification(int p_what) {
char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x;
}
- if (selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection
+ if (!clipped && selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection
int sel_from = (line > selection.from_line) ? TS->shaped_text_get_range(rid).x : selection.from_column;
int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column;
Vector<Vector2> sel = TS->shaped_text_get_selection(rid, sel_from, sel_to);
@@ -1167,7 +1188,7 @@ void TextEdit::_notification(int p_what) {
}
int start = TS->shaped_text_get_range(rid).x;
- if (!search_text.empty()) { // Search highhlight
+ if (!clipped && !search_text.is_empty()) { // Search highhlight
int search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0);
while (search_text_col != -1) {
Vector<Vector2> sel = TS->shaped_text_get_selection(rid, search_text_col + start, search_text_col + search_text.length() + start);
@@ -1190,7 +1211,7 @@ void TextEdit::_notification(int p_what) {
}
}
- if (highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.empty()) { // Highlight
+ if (!clipped && highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight
int highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
while (highlighted_text_col != -1) {
Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text.length() + start);
@@ -1212,7 +1233,7 @@ void TextEdit::_notification(int p_what) {
}
}
- if (select_identifiers_enabled && highlighted_word.length() != 0) { // Highlight word
+ if (!clipped && select_identifiers_enabled && highlighted_word.length() != 0) { // Highlight word
if (_is_char(highlighted_word[0]) || highlighted_word[0] == '.') {
int highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
while (highlighted_word_col != -1) {
@@ -1230,7 +1251,7 @@ void TextEdit::_notification(int p_what) {
}
rect.position.y = TS->shaped_text_get_ascent(rid) + cache.font->get_underline_position(cache.font_size);
rect.size.y = cache.font->get_underline_thickness(cache.font_size);
- draw_rect(rect, cache.font_color_selected);
+ draw_rect(rect, cache.font_selected_color);
}
highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_word_col + 1);
@@ -1238,6 +1259,7 @@ void TextEdit::_notification(int p_what) {
}
}
+ const int line_top_offset_y = ofs_y;
ofs_y += (row_height - text_height) / 2;
const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid);
@@ -1246,11 +1268,27 @@ void TextEdit::_notification(int p_what) {
ofs_y += ldata->get_line_ascent(line_wrap_index);
int char_ofs = 0;
+ if (cache.outline_size > 0 && cache.outline_color.a > 0) {
+ for (int j = 0; j < gl_size; j++) {
+ for (int k = 0; k < glyphs[j].repeat; k++) {
+ if ((char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) {
+ if (glyphs[j].font_rid != RID()) {
+ TS->font_draw_glyph_outline(glyphs[j].font_rid, ci, glyphs[j].font_size, cache.outline_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, cache.outline_color);
+ }
+ }
+ char_ofs += glyphs[j].advance;
+ }
+ if ((char_ofs + char_margin) >= xmargin_end) {
+ break;
+ }
+ }
+ char_ofs = 0;
+ }
for (int j = 0; j < gl_size; j++) {
if (color_map.has(glyphs[j].start)) {
current_color = color_map[glyphs[j].start].get("color");
- if (readonly && current_color.a > cache.font_color_readonly.a) {
- current_color.a = cache.font_color_readonly.a;
+ if (readonly && current_color.a > cache.font_readonly_color.a) {
+ current_color.a = cache.font_readonly_color.a;
}
}
@@ -1259,40 +1297,44 @@ void TextEdit::_notification(int p_what) {
int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column;
if (glyphs[j].start >= sel_from && glyphs[j].end <= sel_to && override_selected_font_color) {
- current_color = cache.font_color_selected;
+ current_color = cache.font_selected_color;
}
}
- if (brace_matching_enabled) {
- if ((brace_open_match_line == line && brace_open_match_column == glyphs[j].start) ||
- (cursor.column == glyphs[j].start && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_open_matching || brace_open_mismatch))) {
- if (brace_open_mismatch) {
- current_color = cache.brace_mismatch_color;
+ int char_pos = char_ofs + char_margin + ofs_x;
+ if (char_pos >= xmargin_beg) {
+ if (brace_matching_enabled) {
+ if ((brace_open_match_line == line && brace_open_match_column == glyphs[j].start) ||
+ (cursor.column == glyphs[j].start && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_open_matching || brace_open_mismatch))) {
+ if (brace_open_mismatch) {
+ current_color = cache.brace_mismatch_color;
+ }
+ Rect2 rect = Rect2(char_pos, ofs_y + cache.font->get_underline_position(cache.font_size), glyphs[j].advance * glyphs[j].repeat, cache.font->get_underline_thickness(cache.font_size));
+ draw_rect(rect, current_color);
}
- Rect2 rect = Rect2(char_ofs + char_margin + ofs_x, ofs_y + cache.font->get_underline_position(cache.font_size), glyphs[j].advance * glyphs[j].repeat, cache.font->get_underline_thickness(cache.font_size));
- draw_rect(rect, current_color);
- }
- if ((brace_close_match_line == line && brace_close_match_column == glyphs[j].start) ||
- (cursor.column == glyphs[j].start + 1 && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_close_matching || brace_close_mismatch))) {
- if (brace_close_mismatch) {
- current_color = cache.brace_mismatch_color;
+ if ((brace_close_match_line == line && brace_close_match_column == glyphs[j].start) ||
+ (cursor.column == glyphs[j].start + 1 && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_close_matching || brace_close_mismatch))) {
+ if (brace_close_mismatch) {
+ current_color = cache.brace_mismatch_color;
+ }
+ Rect2 rect = Rect2(char_pos, ofs_y + cache.font->get_underline_position(cache.font_size), glyphs[j].advance * glyphs[j].repeat, cache.font->get_underline_thickness(cache.font_size));
+ draw_rect(rect, current_color);
}
- Rect2 rect = Rect2(char_ofs + char_margin + ofs_x, ofs_y + cache.font->get_underline_position(cache.font_size), glyphs[j].advance * glyphs[j].repeat, cache.font->get_underline_thickness(cache.font_size));
- draw_rect(rect, current_color);
+ }
+
+ if (draw_tabs && ((glyphs[j].flags & TextServer::GRAPHEME_IS_TAB) == TextServer::GRAPHEME_IS_TAB)) {
+ int yofs = (text_height - cache.tab_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
+ cache.tab_icon->draw(ci, Point2(char_pos, ofs_y + yofs), current_color);
+ } else if (draw_spaces && ((glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE)) {
+ int yofs = (text_height - cache.space_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
+ int xofs = (glyphs[j].advance * glyphs[j].repeat - cache.space_icon->get_width()) / 2;
+ cache.space_icon->draw(ci, Point2(char_pos + xofs, ofs_y + yofs), current_color);
}
}
- if (draw_tabs && ((glyphs[j].flags & TextServer::GRAPHEME_IS_TAB) == TextServer::GRAPHEME_IS_TAB)) {
- int yofs = (text_height - cache.tab_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
- cache.tab_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), current_color);
- }
- if (draw_spaces && ((glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE)) {
- int yofs = (text_height - cache.space_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
- int xofs = (glyphs[j].advance * glyphs[j].repeat - cache.space_icon->get_width()) / 2;
- cache.space_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x + xofs, ofs_y + yofs), current_color);
- }
+
for (int k = 0; k < glyphs[j].repeat; k++) {
- if ((char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) {
+ if (!clipped && (char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) {
if (glyphs[j].font_rid != RID()) {
TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color);
} else if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
@@ -1307,11 +1349,13 @@ void TextEdit::_notification(int p_what) {
}
if (line_wrap_index == line_wrap_amount && is_folded(line)) {
- int yofs = (text_height - cache.folded_eol_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
- int xofs = cache.folded_eol_icon->get_width() / 2;
- Color eol_color = cache.code_folding_color;
- eol_color.a = 1;
- cache.folded_eol_icon->draw(ci, Point2(char_ofs + char_margin + xofs + ofs_x, ofs_y + yofs), eol_color);
+ int xofs = char_ofs + char_margin + ofs_x + (cache.folded_eol_icon->get_width() / 2);
+ if (xofs >= xmargin_beg && xofs < xmargin_end) {
+ int yofs = (text_height - cache.folded_eol_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index);
+ Color eol_color = cache.code_folding_color;
+ eol_color.a = 1;
+ cache.folded_eol_icon->draw(ci, Point2(xofs, ofs_y + yofs), eol_color);
+ }
}
// Carets
@@ -1320,8 +1364,10 @@ void TextEdit::_notification(int p_what) {
#else
int caret_width = 1;
#endif
- if (cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) {
- cursor_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index);
+ if (!clipped && cursor.line == line && ((line_wrap_index == line_wrap_amount) || (cursor.column != TS->shaped_text_get_range(rid).y))) {
+ is_cursor_line_visible = true;
+ cursor_pos.y = line_top_offset_y;
+
if (ime_text.length() == 0) {
Rect2 l_caret, t_caret;
TextServer::Direction l_dir, t_dir;
@@ -1346,7 +1392,7 @@ void TextEdit::_notification(int p_what) {
cursor_pos.x = char_margin + ofs_x + t_caret.position.x;
}
- if (draw_caret) {
+ if (draw_caret && cursor_pos.x >= xmargin_beg && cursor_pos.x < xmargin_end) {
if (block_caret || insert_mode) {
//Block or underline caret, draw trailing carets at full height.
int h = cache.font->get_height(cache.font_size);
@@ -1371,7 +1417,7 @@ void TextEdit::_notification(int p_what) {
l_caret.size.y = h;
}
l_caret.position += Vector2(char_margin + ofs_x, ofs_y);
- l_caret.size.x = cache.font->get_char_size('m', 0, cache.font_size).x;
+ l_caret.size.x = cache.font->get_char_size('M', 0, cache.font_size).x;
draw_rect(l_caret, cache.caret_color, false);
}
@@ -1435,83 +1481,101 @@ void TextEdit::_notification(int p_what) {
}
}
}
- ofs_y += ldata->get_line_descent(line_wrap_index);
}
}
bool completion_below = false;
- if (completion_active && completion_options.size() > 0) {
- // Code completion box.
- Ref<StyleBox> csb = get_theme_stylebox("completion");
- int maxlines = get_theme_constant("completion_lines");
- int cmax_width = get_theme_constant("completion_max_width") * cache.font->get_char_size('x', 0, cache.font_size).x;
- int scrollw = get_theme_constant("completion_scroll_width");
- Color scrollc = get_theme_color("completion_scroll_color");
+ if (completion_active && is_cursor_line_visible && completion_options.size() > 0) {
+ // Completion panel
+
+ const Ref<StyleBox> csb = get_theme_stylebox("completion");
+ const int maxlines = get_theme_constant("completion_lines");
+ const int cmax_width = get_theme_constant("completion_max_width") * cache.font->get_char_size('x', 0, cache.font_size).x;
+ const Color scrollc = get_theme_color("completion_scroll_color");
const int completion_options_size = completion_options.size();
- int lines = MIN(completion_options_size, maxlines);
- int w = 0;
- int h = lines * row_height;
- int nofs = cache.font->get_string_size(completion_base, cache.font_size).width;
+ const int row_count = MIN(completion_options_size, maxlines);
+ const int completion_rows_height = row_count * row_height;
+ const int completion_base_width = cache.font->get_string_size(completion_base, cache.font_size).width;
+ int scroll_rectangle_width = get_theme_constant("completion_scroll_width");
+ int width = 0;
+
+ // Compute max width of the panel based on the longest completion option
if (completion_options_size < 50) {
for (int i = 0; i < completion_options_size; i++) {
- int w2 = MIN(cache.font->get_string_size(completion_options[i].display, cache.font_size).x, cmax_width);
- if (w2 > w) {
- w = w2;
+ int line_width = MIN(cache.font->get_string_size(completion_options[i].display, cache.font_size).x, cmax_width);
+ if (line_width > width) {
+ width = line_width;
}
}
} else {
- w = cmax_width;
+ width = cmax_width;
}
// Add space for completion icons.
const int icon_hsep = get_theme_constant("hseparation", "ItemList");
- Size2 icon_area_size(row_height, row_height);
- w += icon_area_size.width + icon_hsep;
+ const Size2 icon_area_size(row_height, row_height);
+ const int icon_area_width = icon_area_size.width + icon_hsep;
+ width += icon_area_width;
- int line_from = CLAMP(completion_index - lines / 2, 0, completion_options_size - lines);
+ const int line_from = CLAMP(completion_index - row_count / 2, 0, completion_options_size - row_count);
- for (int i = 0; i < lines; i++) {
+ for (int i = 0; i < row_count; i++) {
int l = line_from + i;
ERR_CONTINUE(l < 0 || l >= completion_options_size);
if (completion_options[l].default_value.get_type() == Variant::COLOR) {
- w += icon_area_size.width;
+ width += icon_area_size.width;
break;
}
}
- int th = h + csb->get_minimum_size().y;
+ // Position completion panel
+ completion_rect.size.width = width + 2;
+ completion_rect.size.height = completion_rows_height;
- if (cursor_pos.y + row_height + th > get_size().height) {
- completion_rect.position.y = cursor_pos.y - th - (cache.line_spacing / 2.0f) - cursor_insert_offset_y;
- } else {
- completion_rect.position.y = cursor_pos.y + cache.font->get_height(cache.font_size) + (cache.line_spacing / 2.0f) + csb->get_offset().y - cursor_insert_offset_y;
- completion_below = true;
+ if (completion_options_size <= maxlines) {
+ scroll_rectangle_width = 0;
}
- if (cursor_pos.x - nofs + w + scrollw > get_size().width) {
- completion_rect.position.x = get_size().width - w - scrollw;
+ const Point2 csb_offset = csb->get_offset();
+
+ const int total_width = completion_rect.size.width + csb->get_minimum_size().x + scroll_rectangle_width;
+ const int total_height = completion_rect.size.height + csb->get_minimum_size().y;
+
+ const int rect_left_border_x = cursor_pos.x - completion_base_width - icon_area_width - csb_offset.x;
+ const int rect_right_border_x = rect_left_border_x + total_width;
+
+ if (rect_left_border_x < 0) {
+ // Anchor the completion panel to the left
+ completion_rect.position.x = 0;
+ } else if (rect_right_border_x > get_size().width) {
+ // Anchor the completion panel to the right
+ completion_rect.position.x = get_size().width - total_width;
} else {
- completion_rect.position.x = cursor_pos.x - nofs;
+ // Let the completion panel float with the cursor
+ completion_rect.position.x = rect_left_border_x;
}
- completion_rect.size.width = w + 2;
- completion_rect.size.height = h;
- if (completion_options_size <= maxlines) {
- scrollw = 0;
+ if (cursor_pos.y + row_height + total_height > get_size().height) {
+ // Completion panel above the cursor line
+ completion_rect.position.y = cursor_pos.y - total_height;
+ } else {
+ // Completion panel below the cursor line
+ completion_rect.position.y = cursor_pos.y + row_height;
+ completion_below = true;
}
- draw_style_box(csb, Rect2(completion_rect.position - csb->get_offset(), completion_rect.size + csb->get_minimum_size() + Size2(scrollw, 0)));
+ draw_style_box(csb, Rect2(completion_rect.position - csb_offset, completion_rect.size + csb->get_minimum_size() + Size2(scroll_rectangle_width, 0)));
if (cache.completion_background_color.a > 0.01) {
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(completion_rect.position, completion_rect.size + Size2(scrollw, 0)), cache.completion_background_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(completion_rect.position, completion_rect.size + Size2(scroll_rectangle_width, 0)), cache.completion_background_color);
}
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(completion_rect.position.x, completion_rect.position.y + (completion_index - line_from) * get_row_height()), Size2(completion_rect.size.width, get_row_height())), cache.completion_selected_color);
- draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(nofs, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color);
+ draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(completion_base_width, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color);
- for (int i = 0; i < lines; i++) {
+ for (int i = 0; i < row_count; i++) {
int l = line_from + i;
ERR_CONTINUE(l < 0 || l >= completion_options_size);
@@ -1548,14 +1612,17 @@ void TextEdit::_notification(int p_what) {
}
tl->set_align(HALIGN_LEFT);
}
+ if (cache.outline_size > 0 && cache.outline_color.a > 0) {
+ tl->draw_outline(ci, title_pos, cache.outline_size, cache.outline_color);
+ }
tl->draw(ci, title_pos, completion_options[l].font_color);
}
- if (scrollw) {
+ if (scroll_rectangle_width) {
// Draw a small scroll rectangle to show a position in the options.
float r = (float)maxlines / completion_options_size;
float o = (float)line_from / completion_options_size;
- draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scrollw, completion_rect.size.y * r), scrollc);
+ draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scroll_rectangle_width, completion_rect.size.y * r), scrollc);
}
completion_line_ofs = line_from;
@@ -1563,7 +1630,7 @@ void TextEdit::_notification(int p_what) {
// Check to see if the hint should be drawn.
bool show_hint = false;
- if (completion_hint != "") {
+ if (is_cursor_line_visible && completion_hint != "") {
if (completion_active) {
if (completion_below && !callhint_below) {
show_hint = true;
@@ -1910,7 +1977,7 @@ void TextEdit::backspace_at_cursor() {
cursor_set_column(prev_column);
}
-void TextEdit::indent_right() {
+void TextEdit::indent_selected_lines_right() {
int start_line;
int end_line;
@@ -1962,7 +2029,7 @@ void TextEdit::indent_right() {
update();
}
-void TextEdit::indent_left() {
+void TextEdit::indent_selected_lines_left() {
int start_line;
int end_line;
@@ -2033,6 +2100,623 @@ int TextEdit::_calculate_spaces_till_next_right_indent(int column) {
return indent_size - column % indent_size;
}
+void TextEdit::_swap_current_input_direction() {
+ if (input_direction == TEXT_DIRECTION_LTR) {
+ input_direction = TEXT_DIRECTION_RTL;
+ } else {
+ input_direction = TEXT_DIRECTION_LTR;
+ }
+ cursor_set_column(cursor.column);
+ update();
+}
+
+void TextEdit::_new_line(bool p_split_current_line, bool p_above) {
+ if (readonly) {
+ return;
+ }
+
+ String ins = "\n";
+
+ // Keep indentation.
+ int space_count = 0;
+ for (int i = 0; i < cursor.column; i++) {
+ if (text[cursor.line][i] == '\t') {
+ if (indent_using_spaces) {
+ ins += space_indent;
+ } else {
+ ins += "\t";
+ }
+ space_count = 0;
+ } else if (text[cursor.line][i] == ' ') {
+ space_count++;
+
+ if (space_count == indent_size) {
+ if (indent_using_spaces) {
+ ins += space_indent;
+ } else {
+ ins += "\t";
+ }
+ space_count = 0;
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (is_folded(cursor.line)) {
+ unfold_line(cursor.line);
+ }
+
+ bool brace_indent = false;
+
+ // No need to indent if we are going upwards.
+ if (auto_indent && !p_above) {
+ // Indent once again if previous line will end with ':','{','[','(' and the line is not a comment
+ // (i.e. colon/brace precedes current cursor position).
+ if (cursor.column > 0) {
+ bool indent_char_found = false;
+ bool should_indent = false;
+ char indent_char = ':';
+ char c = text[cursor.line][cursor.column];
+
+ for (int i = 0; i < cursor.column; i++) {
+ c = text[cursor.line][i];
+ switch (c) {
+ case ':':
+ case '{':
+ case '[':
+ case '(':
+ indent_char_found = true;
+ should_indent = true;
+ indent_char = c;
+ continue;
+ }
+
+ if (indent_char_found && is_line_comment(cursor.line)) {
+ should_indent = true;
+ break;
+ } else if (indent_char_found && !_is_whitespace(c)) {
+ should_indent = false;
+ indent_char_found = false;
+ }
+ }
+
+ if (!is_line_comment(cursor.line) && should_indent) {
+ if (indent_using_spaces) {
+ ins += space_indent;
+ } else {
+ ins += "\t";
+ }
+
+ // No need to move the brace below if we are not taking the text with us.
+ char32_t closing_char = _get_right_pair_symbol(indent_char);
+ if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column])) {
+ if (p_split_current_line) {
+ brace_indent = true;
+ ins += "\n" + ins.substr(1, ins.length() - 2);
+ } else {
+ brace_indent = false;
+ ins = "\n" + ins.substr(1, ins.length() - 2);
+ }
+ }
+ }
+ }
+ }
+ begin_complex_operation();
+ bool first_line = false;
+ if (!p_split_current_line) {
+ if (p_above) {
+ if (cursor.line > 0) {
+ cursor_set_line(cursor.line - 1);
+ cursor_set_column(text[cursor.line].length());
+ } else {
+ cursor_set_column(0);
+ first_line = true;
+ }
+ } else {
+ cursor_set_column(text[cursor.line].length());
+ }
+ }
+
+ insert_text_at_cursor(ins);
+
+ if (first_line) {
+ cursor_set_line(0);
+ } else if (brace_indent) {
+ cursor_set_line(cursor.line - 1);
+ cursor_set_column(text[cursor.line].length());
+ }
+ end_complex_operation();
+}
+
+void TextEdit::_indent_right() {
+ if (readonly) {
+ return;
+ }
+
+ if (is_selection_active()) {
+ indent_selected_lines_right();
+ } else {
+ // Simple indent.
+ if (indent_using_spaces) {
+ // Insert only as much spaces as needed till next indentation level.
+ int spaces_to_add = _calculate_spaces_till_next_right_indent(cursor.column);
+ String indent_to_insert = String();
+ for (int i = 0; i < spaces_to_add; i++) {
+ indent_to_insert = ' ' + indent_to_insert;
+ }
+ _insert_text_at_cursor(indent_to_insert);
+ } else {
+ _insert_text_at_cursor("\t");
+ }
+ }
+}
+
+void TextEdit::_indent_left() {
+ if (readonly) {
+ return;
+ }
+
+ if (is_selection_active()) {
+ indent_selected_lines_left();
+ } else {
+ // Simple unindent.
+ int cc = cursor.column;
+ const String &line = text[cursor.line];
+
+ int left = _find_first_non_whitespace_column_of_line(line);
+ cc = MIN(cc, left);
+
+ while (cc < indent_size && cc < left && line[cc] == ' ') {
+ cc++;
+ }
+
+ if (cc > 0 && cc <= text[cursor.line].length()) {
+ if (text[cursor.line][cc - 1] == '\t') {
+ // Tabs unindentation.
+ _remove_text(cursor.line, cc - 1, cursor.line, cc);
+ if (cursor.column >= left) {
+ cursor_set_column(MAX(0, cursor.column - 1));
+ }
+ update();
+ } else {
+ // Spaces unindentation.
+ int spaces_to_remove = _calculate_spaces_till_next_left_indent(cc);
+ if (spaces_to_remove > 0) {
+ _remove_text(cursor.line, cc - spaces_to_remove, cursor.line, cc);
+ if (cursor.column > left - spaces_to_remove) { // Inside text?
+ cursor_set_column(MAX(0, cursor.column - spaces_to_remove));
+ }
+ update();
+ }
+ }
+ } else if (cc == 0 && line.length() > 0 && line[0] == '\t') {
+ _remove_text(cursor.line, 0, cursor.line, 1);
+ update();
+ }
+ }
+}
+
+void TextEdit::_move_cursor_left(bool p_select, bool p_move_by_word) {
+ // Handle selection
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ if (p_move_by_word) {
+ int cc = cursor.column;
+
+ if (cc == 0 && cursor.line > 0) {
+ cursor_set_line(cursor.line - 1);
+ cursor_set_column(text[cursor.line].length());
+ } else {
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid());
+ for (int i = words.size() - 1; i >= 0; i--) {
+ if (words[i].x < cc) {
+ cc = words[i].x;
+ break;
+ }
+ }
+ cursor_set_column(cc);
+ }
+ } else {
+ // If the cursor is at the start of the line, and not on the first line, move it up to the end of the previous line.
+ if (cursor.column == 0) {
+ if (cursor.line > 0) {
+ cursor_set_line(cursor.line - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1));
+ cursor_set_column(text[cursor.line].length());
+ }
+ } else {
+ if (mid_grapheme_caret_enabled) {
+ cursor_set_column(cursor_get_column() - 1);
+ } else {
+ cursor_set_column(TS->shaped_text_prev_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), cursor_get_column()));
+ }
+ }
+ }
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+}
+
+void TextEdit::_move_cursor_right(bool p_select, bool p_move_by_word) {
+ // Handle selection
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ if (p_move_by_word) {
+ int cc = cursor.column;
+
+ if (cc == text[cursor.line].length() && cursor.line < text.size() - 1) {
+ cursor_set_line(cursor.line + 1);
+ cursor_set_column(0);
+ } else {
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid());
+ for (int i = 0; i < words.size(); i++) {
+ if (words[i].y > cc) {
+ cc = words[i].y;
+ break;
+ }
+ }
+ cursor_set_column(cc);
+ }
+ } else {
+ // If we are at the end of the line, move the caret to the next line down.
+ if (cursor.column == text[cursor.line].length()) {
+ if (cursor.line < text.size() - 1) {
+ cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false);
+ cursor_set_column(0);
+ }
+ } else {
+ if (mid_grapheme_caret_enabled) {
+ cursor_set_column(cursor_get_column() + 1);
+ } else {
+ cursor_set_column(TS->shaped_text_next_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), cursor_get_column()));
+ }
+ }
+ }
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+}
+
+void TextEdit::_move_cursor_up(bool p_select) {
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ int cur_wrap_index = get_cursor_wrap_index();
+ if (cur_wrap_index > 0) {
+ cursor_set_line(cursor.line, true, false, cur_wrap_index - 1);
+ } else if (cursor.line == 0) {
+ cursor_set_column(0);
+ } else {
+ int new_line = cursor.line - num_lines_from(cursor.line - 1, -1);
+ if (line_wraps(new_line)) {
+ cursor_set_line(new_line, true, false, times_line_wraps(new_line));
+ } else {
+ cursor_set_line(new_line, true, false);
+ }
+ }
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+
+ _cancel_code_hint();
+}
+
+void TextEdit::_move_cursor_down(bool p_select) {
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ int cur_wrap_index = get_cursor_wrap_index();
+ if (cur_wrap_index < times_line_wraps(cursor.line)) {
+ cursor_set_line(cursor.line, true, false, cur_wrap_index + 1);
+ } else if (cursor.line == get_last_unhidden_line()) {
+ cursor_set_column(text[cursor.line].length());
+ } else {
+ int new_line = cursor.line + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1);
+ cursor_set_line(new_line, true, false, 0);
+ }
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+
+ _cancel_code_hint();
+}
+
+void TextEdit::_move_cursor_to_line_start(bool p_select) {
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ // Move cursor column to start of wrapped row and then to start of text.
+ Vector<String> rows = get_wrap_rows_text(cursor.line);
+ int wi = get_cursor_wrap_index();
+ int row_start_col = 0;
+ for (int i = 0; i < wi; i++) {
+ row_start_col += rows[i].length();
+ }
+ if (cursor.column == row_start_col || wi == 0) {
+ // Compute whitespace symbols seq length.
+ int current_line_whitespace_len = 0;
+ while (current_line_whitespace_len < text[cursor.line].length()) {
+ char32_t c = text[cursor.line][current_line_whitespace_len];
+ if (c != '\t' && c != ' ') {
+ break;
+ }
+ current_line_whitespace_len++;
+ }
+
+ if (cursor_get_column() == current_line_whitespace_len) {
+ cursor_set_column(0);
+ } else {
+ cursor_set_column(current_line_whitespace_len);
+ }
+ } else {
+ cursor_set_column(row_start_col);
+ }
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+
+ _cancel_completion();
+ completion_hint = "";
+}
+
+void TextEdit::_move_cursor_to_line_end(bool p_select) {
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ // Move cursor column to end of wrapped row and then to end of text.
+ Vector<String> rows = get_wrap_rows_text(cursor.line);
+ int wi = get_cursor_wrap_index();
+ int row_end_col = -1;
+ for (int i = 0; i < wi + 1; i++) {
+ row_end_col += rows[i].length();
+ }
+ if (wi == rows.size() - 1 || cursor.column == row_end_col) {
+ cursor_set_column(text[cursor.line].length());
+ } else {
+ cursor_set_column(row_end_col);
+ }
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+ _cancel_completion();
+ completion_hint = "";
+}
+
+void TextEdit::_move_cursor_page_up(bool p_select) {
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ int wi;
+ int n_line = cursor.line - num_lines_from_rows(cursor.line, get_cursor_wrap_index(), -get_visible_rows(), wi) + 1;
+ cursor_set_line(n_line, true, false, wi);
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+
+ _cancel_completion();
+ completion_hint = "";
+}
+
+void TextEdit::_move_cursor_page_down(bool p_select) {
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ int wi;
+ int n_line = cursor.line + num_lines_from_rows(cursor.line, get_cursor_wrap_index(), get_visible_rows(), wi) - 1;
+ cursor_set_line(n_line, true, false, wi);
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+
+ _cancel_completion();
+ completion_hint = "";
+}
+
+void TextEdit::_backspace(bool p_word, bool p_all_to_left) {
+ if (readonly) {
+ return;
+ }
+
+ if (is_selection_active()) {
+ _delete_selection();
+ return;
+ }
+ if (p_all_to_left) {
+ int cursor_current_column = cursor.column;
+ cursor.column = 0;
+ _remove_text(cursor.line, 0, cursor.line, cursor_current_column);
+ } else if (p_word) {
+ int line = cursor.line;
+ int column = cursor.column;
+
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
+ for (int i = words.size() - 1; i >= 0; i--) {
+ if (words[i].x < column) {
+ column = words[i].x;
+ break;
+ }
+ }
+
+ _remove_text(line, column, cursor.line, cursor.column);
+
+ cursor_set_line(line);
+ cursor_set_column(column);
+ } else {
+ // One character.
+ if (cursor.line > 0 && is_line_hidden(cursor.line - 1)) {
+ unfold_line(cursor.line - 1);
+ }
+ backspace_at_cursor();
+ }
+}
+
+void TextEdit::_delete(bool p_word, bool p_all_to_right) {
+ if (readonly) {
+ return;
+ }
+
+ if (is_selection_active()) {
+ _delete_selection();
+ return;
+ }
+ int curline_len = text[cursor.line].length();
+
+ if (cursor.line == text.size() - 1 && cursor.column == curline_len) {
+ return; // Last line, last column: Nothing to do.
+ }
+
+ int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1;
+ int next_column;
+
+ if (p_all_to_right) {
+ // Delete everything to right of cursor
+ next_column = curline_len;
+ next_line = cursor.line;
+ } else if (p_word && cursor.column < curline_len - 1) {
+ // Delete next word to right of cursor
+ int line = cursor.line;
+ int column = cursor.column;
+
+ Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
+ for (int i = 0; i < words.size(); i++) {
+ if (words[i].y > column) {
+ column = words[i].y;
+ break;
+ }
+ }
+
+ next_line = line;
+ next_column = column;
+ } else {
+ // Delete one character
+ next_column = cursor.column < curline_len ? (cursor.column + 1) : 0;
+ if (mid_grapheme_caret_enabled) {
+ next_column = cursor.column < curline_len ? (cursor.column + 1) : 0;
+ } else {
+ next_column = cursor.column < curline_len ? TS->shaped_text_next_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), (cursor.column)) : 0;
+ }
+ }
+
+ _remove_text(cursor.line, cursor.column, next_line, next_column);
+ update();
+}
+
+void TextEdit::_delete_selection() {
+ if (is_selection_active()) {
+ selection.active = false;
+ update();
+ _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
+ cursor_set_line(selection.from_line, true, false);
+ cursor_set_column(selection.from_column);
+ update();
+ }
+}
+
+void TextEdit::_move_cursor_document_start(bool p_select) {
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ cursor_set_line(0);
+ cursor_set_column(0);
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+}
+
+void TextEdit::_move_cursor_document_end(bool p_select) {
+ if (p_select) {
+ _pre_shift_selection();
+ } else {
+ deselect();
+ }
+
+ cursor_set_line(get_last_unhidden_line(), true, false, 9999);
+ cursor_set_column(text[cursor.line].length());
+
+ if (p_select) {
+ _post_shift_selection();
+ }
+}
+
+void TextEdit::_handle_unicode_character(uint32_t unicode, bool p_had_selection, bool p_update_auto_complete) {
+ if (p_update_auto_complete) {
+ _reset_caret_blink_timer();
+ }
+
+ if (p_had_selection) {
+ _delete_selection();
+ }
+
+ // Remove the old character if in insert mode and no selection.
+ if (insert_mode && !p_had_selection) {
+ begin_complex_operation();
+
+ // Make sure we don't try and remove empty space.
+ if (cursor.column < get_line(cursor.line).length()) {
+ _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
+ }
+ }
+
+ const char32_t chr[2] = { (char32_t)unicode, 0 };
+
+ // Clear completion hint when function closed
+ if (completion_hint != "" && unicode == ')') {
+ completion_hint = "";
+ }
+
+ if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
+ _consume_pair_symbol(chr[0]);
+ } else {
+ _insert_text_at_cursor(chr);
+ }
+
+ if ((insert_mode && !p_had_selection) || (selection.active != p_had_selection)) {
+ end_complex_operation();
+ }
+
+ if (p_update_auto_complete) {
+ _update_completion_candidates();
+ }
+}
+
void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) const {
float rows = p_mouse.y;
rows -= cache.style_normal->get_margin(SIDE_TOP);
@@ -2063,6 +2747,18 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
} else {
int colx = p_mouse.x - (cache.style_normal->get_margin(SIDE_LEFT) + gutters_width + gutter_padding);
colx += cursor.x_ofs;
+ col = get_char_pos_for_line(colx, row, wrap_index);
+ if (is_wrap_enabled() && wrap_index < times_line_wraps(row)) {
+ // Move back one if we are at the end of the row.
+ Vector<String> rows2 = get_wrap_rows_text(row);
+ int row_end_col = 0;
+ for (int i = 0; i < wrap_index + 1; i++) {
+ row_end_col += rows2[i].length();
+ }
+ if (col >= row_end_col) {
+ col -= 1;
+ }
+ }
RID text_rid = text.get_line_data(row)->get_line_rid(wrap_index);
if (is_layout_rtl()) {
@@ -2268,7 +2964,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int prev_col = cursor.column;
int prev_line = cursor.line;
- cursor_set_line(row, true, false);
+ cursor_set_line(row, false, false);
cursor_set_column(col);
if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) {
@@ -2293,8 +2989,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} else {
if (cursor.line < selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column < selection.selecting_column)) {
if (selection.shiftclick_left) {
- SWAP(selection.from_column, selection.to_column);
- SWAP(selection.from_line, selection.to_line);
selection.shiftclick_left = !selection.shiftclick_left;
}
selection.from_column = cursor.column;
@@ -2315,7 +3009,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
update();
}
-
} else {
selection.active = false;
selection.selecting_mode = SelectionMode::SELECTION_MODE_POINTER;
@@ -2364,7 +3057,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
menu->set_position(get_screen_transform().xform(mpos));
menu->set_size(Vector2(1, 1));
- // menu->set_scale(get_global_transform().get_scale());
+ _generate_context_menu();
menu->popup();
grab_focus();
}
@@ -2458,13 +3151,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventKey> k = p_gui_input;
if (k.is_valid()) {
- k = k->duplicate(); // It will be modified later on.
-
+ // Ctrl + Hover symbols
#ifdef OSX_ENABLED
if (k->get_keycode() == KEY_META) {
#else
if (k->get_keycode() == KEY_CONTROL) {
-
#endif
if (select_identifiers_enabled) {
if (k->is_pressed() && !dragging_minimap && !dragging_selection) {
@@ -2474,1191 +3165,347 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
set_highlighted_word(String());
}
}
+ return;
}
if (!k->is_pressed()) {
return;
}
- if (completion_active) {
- if (readonly) {
- return;
- }
-
- bool valid = true;
- if (k->get_command() || k->get_metakey()) {
- valid = false;
- }
-
- if (valid) {
- if (!k->get_alt()) {
- if (k->get_keycode() == KEY_UP) {
- if (completion_index > 0) {
- completion_index--;
- } else {
- completion_index = completion_options.size() - 1;
- }
- completion_current = completion_options[completion_index];
- update();
-
- accept_event();
- return;
- }
-
- if (k->get_keycode() == KEY_DOWN) {
- if (completion_index < completion_options.size() - 1) {
- completion_index++;
- } else {
- completion_index = 0;
- }
- completion_current = completion_options[completion_index];
- update();
-
- accept_event();
- return;
- }
-
- if (k->get_keycode() == KEY_PAGEUP) {
- completion_index -= get_theme_constant("completion_lines");
- if (completion_index < 0) {
- completion_index = 0;
- }
- completion_current = completion_options[completion_index];
- update();
- accept_event();
- return;
- }
-
- if (k->get_keycode() == KEY_PAGEDOWN) {
- completion_index += get_theme_constant("completion_lines");
- if (completion_index >= completion_options.size()) {
- completion_index = completion_options.size() - 1;
- }
- completion_current = completion_options[completion_index];
- update();
- accept_event();
- return;
- }
-
- if (k->get_keycode() == KEY_HOME && completion_index > 0) {
- completion_index = 0;
- completion_current = completion_options[completion_index];
- update();
- accept_event();
- return;
- }
-
- if (k->get_keycode() == KEY_END && completion_index < completion_options.size() - 1) {
- completion_index = completion_options.size() - 1;
- completion_current = completion_options[completion_index];
- update();
- accept_event();
- return;
- }
-
- if (k->get_keycode() == KEY_KP_ENTER || k->get_keycode() == KEY_ENTER || k->get_keycode() == KEY_TAB) {
- _confirm_completion();
- accept_event();
- return;
- }
-
- if (k->get_keycode() == KEY_BACKSPACE) {
- _reset_caret_blink_timer();
-
- backspace_at_cursor();
- _update_completion_candidates();
- accept_event();
- return;
- }
-
- if (k->get_keycode() == KEY_SHIFT) {
- accept_event();
- return;
- }
- }
-
- if (k->get_unicode() > 32) {
- _reset_caret_blink_timer();
-
- const char32_t chr[2] = { (char32_t)k->get_unicode(), 0 };
- if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
- _consume_pair_symbol(chr[0]);
- } else {
- // Remove the old character if in insert mode.
- if (insert_mode) {
- begin_complex_operation();
-
- // Make sure we don't try and remove empty space.
- if (cursor.column < get_line(cursor.line).length()) {
- _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
- }
- }
-
- _insert_text_at_cursor(chr);
-
- if (insert_mode) {
- end_complex_operation();
- }
- }
- _update_completion_candidates();
- accept_event();
-
- return;
- }
- }
-
- _cancel_completion();
- }
-
- /* TEST CONTROL FIRST! */
-
- // Some remaps for duplicate functions.
- if (k->get_command() && !k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_keycode() == KEY_INSERT) {
- k->set_keycode(KEY_C);
- }
- if (!k->get_command() && k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_keycode() == KEY_INSERT) {
- k->set_keycode(KEY_V);
- k->set_command(true);
- k->set_shift(false);
- }
-#ifdef APPLE_STYLE_KEYS
- if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) {
- uint32_t remap_key = KEY_UNKNOWN;
- switch (k->get_keycode()) {
- case KEY_F: {
- remap_key = KEY_RIGHT;
- } break;
- case KEY_B: {
- remap_key = KEY_LEFT;
- } break;
- case KEY_P: {
- remap_key = KEY_UP;
- } break;
- case KEY_N: {
- remap_key = KEY_DOWN;
- } break;
- case KEY_D: {
- remap_key = KEY_DELETE;
- } break;
- case KEY_H: {
- remap_key = KEY_BACKSPACE;
- } break;
- }
-
- if (remap_key != KEY_UNKNOWN) {
- k->set_keycode(remap_key);
- k->set_control(false);
- }
+ // If a modifier has been pressed, and nothing else, return.
+ if (k->get_keycode() == KEY_CONTROL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT || k->get_keycode() == KEY_META) {
+ return;
}
-#endif
_reset_caret_blink_timer();
+ // Allow unicode handling if:
+ // * No Modifiers are pressed (except shift)
+ bool allow_unicode_handling = !(k->get_command() || k->get_control() || k->get_alt() || k->get_metakey());
+
// Save here for insert mode, just in case it is cleared in the following section.
bool had_selection = selection.active;
- // Stuff to do when selection is active.
- if (!readonly && selection.active) {
- bool clear = false;
- bool unselect = false;
- bool dobreak = false;
-
- switch (k->get_keycode()) {
- case KEY_TAB: {
- if (k->get_shift()) {
- indent_left();
- } else {
- indent_right();
- }
- dobreak = true;
- accept_event();
- } break;
- case KEY_X:
- case KEY_C:
- // Special keys often used with control, wait.
- clear = (!k->get_command() || k->get_shift() || k->get_alt());
- break;
- case KEY_DELETE:
- if (!k->get_shift()) {
- accept_event();
- clear = true;
- dobreak = true;
- } else if (k->get_command() || k->get_alt()) {
- dobreak = true;
- }
- break;
- case KEY_BACKSPACE:
- accept_event();
- clear = true;
- dobreak = true;
- break;
- case KEY_LEFT:
- case KEY_RIGHT:
- case KEY_UP:
- case KEY_DOWN:
- case KEY_PAGEUP:
- case KEY_PAGEDOWN:
- case KEY_HOME:
- case KEY_END:
- // Ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys).
- if (k->get_command() || k->get_shift() || k->get_alt()) {
- break;
- }
- unselect = true;
- break;
-
- default:
- if (k->get_unicode() >= 32 && !k->get_command() && !k->get_alt() && !k->get_metakey()) {
- clear = true;
- }
- if (auto_brace_completion_enabled && _is_pair_left_symbol(k->get_unicode())) {
- clear = false;
- }
- }
-
- if (unselect) {
- selection.active = false;
- selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE;
- update();
- }
- if (clear) {
- if (!dobreak) {
- begin_complex_operation();
- }
- selection.active = false;
- update();
- _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
- cursor_set_line(selection.from_line, true, false);
- cursor_set_column(selection.from_column);
- update();
- }
- if (dobreak) {
- return;
- }
- }
-
selection.selecting_text = false;
- bool keycode_handled = true;
-
- // Special keycode test.
-
- switch (k->get_keycode()) {
- case KEY_KP_ENTER:
- case KEY_ENTER: {
- if (readonly) {
- break;
- }
-
- String ins = "\n";
-
- // Keep indentation.
- int space_count = 0;
- for (int i = 0; i < cursor.column; i++) {
- if (text[cursor.line][i] == '\t') {
- if (indent_using_spaces) {
- ins += space_indent;
- } else {
- ins += "\t";
- }
- space_count = 0;
- } else if (text[cursor.line][i] == ' ') {
- space_count++;
-
- if (space_count == indent_size) {
- if (indent_using_spaces) {
- ins += space_indent;
- } else {
- ins += "\t";
- }
- space_count = 0;
- }
- } else {
- break;
- }
- }
-
- if (is_folded(cursor.line)) {
- unfold_line(cursor.line);
- }
-
- bool brace_indent = false;
-
- // No need to indent if we are going upwards.
- if (auto_indent && !(k->get_command() && k->get_shift())) {
- // Indent once again if previous line will end with ':','{','[','(' and the line is not a comment
- // (i.e. colon/brace precedes current cursor position).
- if (cursor.column > 0) {
- bool indent_char_found = false;
- bool should_indent = false;
- char indent_char = ':';
- char c = text[cursor.line][cursor.column];
-
- for (int i = 0; i < cursor.column; i++) {
- c = text[cursor.line][i];
- switch (c) {
- case ':':
- case '{':
- case '[':
- case '(':
- indent_char_found = true;
- should_indent = true;
- indent_char = c;
- continue;
- }
-
- if (indent_char_found && is_line_comment(cursor.line)) {
- should_indent = true;
- break;
- } else if (indent_char_found && !_is_whitespace(c)) {
- should_indent = false;
- indent_char_found = false;
- }
- }
-
- if (!is_line_comment(cursor.line) && should_indent) {
- if (indent_using_spaces) {
- ins += space_indent;
- } else {
- ins += "\t";
- }
-
- // No need to move the brace below if we are not taking the text with us.
- char32_t closing_char = _get_right_pair_symbol(indent_char);
- if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !k->get_command()) {
- brace_indent = true;
- ins += "\n" + ins.substr(1, ins.length() - 2);
- }
- }
- }
- }
- begin_complex_operation();
- bool first_line = false;
- if (k->get_command()) {
- if (k->get_shift()) {
- if (cursor.line > 0) {
- cursor_set_line(cursor.line - 1);
- cursor_set_column(text[cursor.line].length());
- } else {
- cursor_set_column(0);
- first_line = true;
- }
- } else {
- cursor_set_column(text[cursor.line].length());
- }
- }
-
- insert_text_at_cursor(ins);
-
- if (first_line) {
- cursor_set_line(0);
- } else if (brace_indent) {
- cursor_set_line(cursor.line - 1);
- cursor_set_column(text[cursor.line].length());
- }
- end_complex_operation();
- } break;
- case KEY_ESCAPE: {
- if (completion_hint != "") {
- completion_hint = "";
- update();
- } else {
- keycode_handled = false;
- }
- } break;
- case KEY_TAB: {
- if (k->get_command()) {
- break; // Avoid tab when command.
- }
+ // Check and handle all built in shortcuts.
- if (readonly) {
- break;
- }
+ // AUTO-COMPLETE
- if (is_selection_active()) {
- if (k->get_shift()) {
- indent_left();
- } else {
- indent_right();
- }
- } else {
- if (k->get_shift()) {
- // Simple unindent.
- int cc = cursor.column;
- const String &line = text[cursor.line];
-
- int left = _find_first_non_whitespace_column_of_line(line);
- cc = MIN(cc, left);
-
- while (cc < indent_size && cc < left && line[cc] == ' ') {
- cc++;
- }
-
- if (cc > 0 && cc <= text[cursor.line].length()) {
- if (text[cursor.line][cc - 1] == '\t') {
- // Tabs unindentation.
- _remove_text(cursor.line, cc - 1, cursor.line, cc);
- if (cursor.column >= left) {
- cursor_set_column(MAX(0, cursor.column - 1));
- }
- update();
- } else {
- // Spaces unindentation.
- int spaces_to_remove = _calculate_spaces_till_next_left_indent(cc);
- if (spaces_to_remove > 0) {
- _remove_text(cursor.line, cc - spaces_to_remove, cursor.line, cc);
- if (cursor.column > left - spaces_to_remove) { // Inside text?
- cursor_set_column(MAX(0, cursor.column - spaces_to_remove));
- }
- update();
- }
- }
- } else if (cc == 0 && line.length() > 0 && line[0] == '\t') {
- _remove_text(cursor.line, 0, cursor.line, 1);
- update();
- }
- } else {
- // Simple indent.
- if (indent_using_spaces) {
- // Insert only as much spaces as needed till next indentation level.
- int spaces_to_add = _calculate_spaces_till_next_right_indent(cursor.column);
- String indent_to_insert = String();
- for (int i = 0; i < spaces_to_add; i++) {
- indent_to_insert = ' ' + indent_to_insert;
- }
- _insert_text_at_cursor(indent_to_insert);
- } else {
- _insert_text_at_cursor("\t");
- }
- }
- }
-
- } break;
- case KEY_BACKSPACE: {
- if (readonly) {
- break;
- }
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_alt() && cursor.column > 1) {
-#else
- if (k->get_alt()) {
- keycode_handled = false;
- break;
- } else if (k->get_command() && cursor.column > 1) {
-#endif
- int line = cursor.line;
- int column = cursor.column;
-
- Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
- for (int i = words.size() - 1; i >= 0; i--) {
- if (words[i].x < column) {
- column = words[i].x;
- break;
- }
- }
-
- _remove_text(line, column, cursor.line, cursor.column);
-
- cursor_set_line(line);
- cursor_set_column(column);
-
-#ifdef APPLE_STYLE_KEYS
- } else if (k->get_command()) {
- int cursor_current_column = cursor.column;
- cursor.column = 0;
- _remove_text(cursor.line, 0, cursor.line, cursor_current_column);
-#endif
- } else {
- if (cursor.line > 0 && is_line_hidden(cursor.line - 1)) {
- unfold_line(cursor.line - 1);
- }
- backspace_at_cursor();
- }
-
- } break;
- case KEY_KP_4: {
- if (k->get_unicode() != 0) {
- keycode_handled = false;
- break;
- }
- [[fallthrough]];
- }
- case KEY_LEFT: {
- if (k->get_shift()) {
- _pre_shift_selection();
-#ifdef APPLE_STYLE_KEYS
- } else {
-#else
- } else if (!k->get_alt()) {
-#endif
- deselect();
- }
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_command()) {
- // Start at first column (it's slightly faster that way) and look for the first non-whitespace character.
- int new_cursor_pos = 0;
- for (int i = 0; i < text[cursor.line].length(); ++i) {
- if (!_is_whitespace(text[cursor.line][i])) {
- new_cursor_pos = i;
- break;
- }
- }
- if (new_cursor_pos == cursor.column) {
- // We're already at the first text character, so move to the very beginning of the line.
- cursor_set_column(0);
- } else {
- // We're somewhere to the right of the first text character; move to the first one.
- cursor_set_column(new_cursor_pos);
- }
- } else if (k->get_alt()) {
-#else
- if (k->get_alt()) {
- keycode_handled = false;
- break;
- } else if (k->get_command()) {
-#endif
- int cc = cursor.column;
-
- if (cc == 0 && cursor.line > 0) {
- cursor_set_line(cursor.line - 1);
- cursor_set_column(text[cursor.line].length());
- } else {
- Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid());
- for (int i = words.size() - 1; i >= 0; i--) {
- if (words[i].x < cc) {
- cc = words[i].x;
- break;
- }
- }
- cursor_set_column(cc);
- }
+ if (k->is_action("ui_text_completion_query", true)) {
+ query_code_comple();
+ accept_event();
+ return;
+ }
- } else if (cursor.column == 0) {
- if (cursor.line > 0) {
- cursor_set_line(cursor.line - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1));
- cursor_set_column(text[cursor.line].length());
- }
+ if (completion_active) {
+ if (k->is_action("ui_up", true)) {
+ if (completion_index > 0) {
+ completion_index--;
} else {
- if (mid_grapheme_caret_enabled) {
- cursor_set_column(cursor_get_column() - 1);
- } else {
- cursor_set_column(TS->shaped_text_prev_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), cursor_get_column()));
- }
- }
-
- if (k->get_shift()) {
- _post_shift_selection();
- }
-
- } break;
- case KEY_KP_6: {
- if (k->get_unicode() != 0) {
- keycode_handled = false;
- break;
+ completion_index = completion_options.size() - 1;
}
- [[fallthrough]];
+ completion_current = completion_options[completion_index];
+ update();
+ accept_event();
+ return;
}
- case KEY_RIGHT: {
- if (k->get_shift()) {
- _pre_shift_selection();
-#ifdef APPLE_STYLE_KEYS
- } else {
-#else
- } else if (!k->get_alt()) {
-#endif
- deselect();
- }
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_command()) {
- cursor_set_column(text[cursor.line].length());
- } else if (k->get_alt()) {
-#else
- if (k->get_alt()) {
- keycode_handled = false;
- break;
- } else if (k->get_command()) {
-#endif
- int cc = cursor.column;
-
- if (cc == text[cursor.line].length() && cursor.line < text.size() - 1) {
- cursor_set_line(cursor.line + 1);
- cursor_set_column(0);
- } else {
- Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid());
- for (int i = 0; i < words.size(); i++) {
- if (words[i].y > cc) {
- cc = words[i].y;
- break;
- }
- }
- cursor_set_column(cc);
- }
-
- } else if (cursor.column == text[cursor.line].length()) {
- if (cursor.line < text.size() - 1) {
- cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false);
- cursor_set_column(0);
- }
+ if (k->is_action("ui_down", true)) {
+ if (completion_index < completion_options.size() - 1) {
+ completion_index++;
} else {
- if (mid_grapheme_caret_enabled) {
- cursor_set_column(cursor_get_column() + 1);
- } else {
- cursor_set_column(TS->shaped_text_next_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), cursor_get_column()));
- }
- }
-
- if (k->get_shift()) {
- _post_shift_selection();
- }
-
- } break;
- case KEY_KP_8: {
- if (k->get_unicode() != 0) {
- keycode_handled = false;
- break;
+ completion_index = 0;
}
- [[fallthrough]];
+ completion_current = completion_options[completion_index];
+ update();
+ accept_event();
+ return;
}
- case KEY_UP: {
- if (k->get_alt()) {
- keycode_handled = false;
- break;
- }
-#ifndef APPLE_STYLE_KEYS
- if (k->get_command()) {
-#else
- if (k->get_command() && k->get_alt()) {
-#endif
- _scroll_lines_up();
- break;
- }
-
- if (k->get_shift()) {
- _pre_shift_selection();
- }
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_command()) {
- cursor_set_line(0);
- } else
-#endif
- {
- int cur_wrap_index = get_cursor_wrap_index();
- if (cur_wrap_index > 0) {
- cursor_set_line(cursor.line, true, false, cur_wrap_index - 1);
- } else if (cursor.line == 0) {
- cursor_set_column(0);
- } else {
- int new_line = cursor.line - num_lines_from(cursor.line - 1, -1);
- if (line_wraps(new_line)) {
- cursor_set_line(new_line, true, false, times_line_wraps(new_line));
- } else {
- cursor_set_line(new_line, true, false);
- }
- }
- }
-
- if (k->get_shift()) {
- _post_shift_selection();
- }
- _cancel_code_hint();
-
- } break;
- case KEY_KP_2: {
- if (k->get_unicode() != 0) {
- keycode_handled = false;
- break;
+ if (k->is_action("ui_page_up", true)) {
+ completion_index -= get_theme_constant("completion_lines");
+ if (completion_index < 0) {
+ completion_index = 0;
}
- [[fallthrough]];
+ completion_current = completion_options[completion_index];
+ update();
+ accept_event();
+ return;
}
- case KEY_DOWN: {
- if (k->get_alt()) {
- keycode_handled = false;
- break;
- }
-#ifndef APPLE_STYLE_KEYS
- if (k->get_command()) {
-#else
- if (k->get_command() && k->get_alt()) {
-#endif
- _scroll_lines_down();
- break;
- }
-
- if (k->get_shift()) {
- _pre_shift_selection();
- }
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_command()) {
- cursor_set_line(get_last_unhidden_line(), true, false, 9999);
- } else
-#endif
- {
- int cur_wrap_index = get_cursor_wrap_index();
- if (cur_wrap_index < times_line_wraps(cursor.line)) {
- cursor_set_line(cursor.line, true, false, cur_wrap_index + 1);
- } else if (cursor.line == get_last_unhidden_line()) {
- cursor_set_column(text[cursor.line].length());
- } else {
- int new_line = cursor.line + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1);
- cursor_set_line(new_line, true, false, 0);
- }
- }
-
- if (k->get_shift()) {
- _post_shift_selection();
- }
- _cancel_code_hint();
-
- } break;
- case KEY_DELETE: {
- if (readonly) {
- break;
- }
-
- if (k->get_shift() && !k->get_command() && !k->get_alt() && is_shortcut_keys_enabled()) {
- cut();
- break;
- }
-
- int curline_len = text[cursor.line].length();
-
- if (cursor.line == text.size() - 1 && cursor.column == curline_len) {
- break; // Nothing to do.
- }
-
- int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1;
- int next_column;
-
-#ifdef APPLE_STYLE_KEYS
- if (k->get_alt() && cursor.column < curline_len - 1) {
-#else
- if (k->get_alt()) {
- keycode_handled = false;
- break;
- } else if (k->get_command() && cursor.column < curline_len - 1) {
-#endif
-
- int line = cursor.line;
- int column = cursor.column;
-
- Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid());
- for (int i = 0; i < words.size(); i++) {
- if (words[i].y > column) {
- column = words[i].y;
- break;
- }
- }
-
- next_line = line;
- next_column = column;
-#ifdef APPLE_STYLE_KEYS
- } else if (k->get_command()) {
- next_column = curline_len;
- next_line = cursor.line;
-#endif
- } else {
- if (mid_grapheme_caret_enabled) {
- next_column = cursor.column < curline_len ? (cursor.column + 1) : 0;
- } else {
- next_column = cursor.column < curline_len ? TS->shaped_text_next_grapheme_pos(text.get_line_data(cursor.line)->get_rid(), (cursor.column)) : 0;
- }
+ if (k->is_action("ui_page_down", true)) {
+ completion_index += get_theme_constant("completion_lines");
+ if (completion_index >= completion_options.size()) {
+ completion_index = completion_options.size() - 1;
}
-
- _remove_text(cursor.line, cursor.column, next_line, next_column);
+ completion_current = completion_options[completion_index];
update();
-
- } break;
- case KEY_KP_7: {
- if (k->get_unicode() != 0) {
- keycode_handled = false;
- break;
- }
- [[fallthrough]];
+ accept_event();
+ return;
}
- case KEY_HOME: {
-#ifdef APPLE_STYLE_KEYS
- if (k->get_shift())
- _pre_shift_selection();
-
- cursor_set_line(0);
-
- if (k->get_shift())
- _post_shift_selection();
- else if (k->get_command() || k->get_control())
- deselect();
-#else
- if (k->get_shift()) {
- _pre_shift_selection();
- }
-
- if (k->get_command()) {
- cursor_set_line(0);
- cursor_set_column(0);
- } else {
- // Move cursor column to start of wrapped row and then to start of text.
- Vector<String> rows = get_wrap_rows_text(cursor.line);
- int wi = get_cursor_wrap_index();
- int row_start_col = 0;
- for (int i = 0; i < wi; i++) {
- row_start_col += rows[i].length();
- }
- if (cursor.column == row_start_col || wi == 0) {
- // Compute whitespace symbols seq length.
- int current_line_whitespace_len = 0;
- while (current_line_whitespace_len < text[cursor.line].length()) {
- char32_t c = text[cursor.line][current_line_whitespace_len];
- if (c != '\t' && c != ' ') {
- break;
- }
- current_line_whitespace_len++;
- }
-
- if (cursor_get_column() == current_line_whitespace_len) {
- cursor_set_column(0);
- } else {
- cursor_set_column(current_line_whitespace_len);
- }
- } else {
- cursor_set_column(row_start_col);
- }
- }
-
- if (k->get_shift()) {
- _post_shift_selection();
- } else if (k->get_command() || k->get_control()) {
- deselect();
- }
- _cancel_completion();
- completion_hint = "";
-#endif
- } break;
- case KEY_KP_1: {
- if (k->get_unicode() != 0) {
- keycode_handled = false;
- break;
+ if (k->is_action("ui_home", true)) {
+ if (completion_index > 0) {
+ completion_index = 0;
+ completion_current = completion_options[completion_index];
+ update();
}
- [[fallthrough]];
+ accept_event();
+ return;
}
- case KEY_END: {
-#ifdef APPLE_STYLE_KEYS
- if (k->get_shift())
- _pre_shift_selection();
-
- cursor_set_line(get_last_unhidden_line(), true, false, 9999);
-
- if (k->get_shift())
- _post_shift_selection();
- else if (k->get_command() || k->get_control())
- deselect();
-#else
- if (k->get_shift()) {
- _pre_shift_selection();
- }
-
- if (k->get_command()) {
- cursor_set_line(get_last_unhidden_line(), true, false, 9999);
- }
-
- // Move cursor column to end of wrapped row and then to end of text.
- Vector<String> rows = get_wrap_rows_text(cursor.line);
- int wi = get_cursor_wrap_index();
- int row_end_col = -1;
- for (int i = 0; i < wi + 1; i++) {
- row_end_col += rows[i].length();
- }
- if (wi == rows.size() - 1 || cursor.column == row_end_col) {
- cursor_set_column(text[cursor.line].length());
- } else {
- cursor_set_column(row_end_col);
- }
-
- if (k->get_shift()) {
- _post_shift_selection();
- } else if (k->get_command() || k->get_control()) {
- deselect();
- }
-
- _cancel_completion();
- completion_hint = "";
-#endif
- } break;
- case KEY_KP_9: {
- if (k->get_unicode() != 0) {
- keycode_handled = false;
- break;
+ if (k->is_action("ui_end", true)) {
+ if (completion_index < completion_options.size() - 1) {
+ completion_index = completion_options.size() - 1;
+ completion_current = completion_options[completion_index];
+ update();
}
- [[fallthrough]];
+ accept_event();
+ return;
}
- case KEY_PAGEUP: {
- if (k->get_shift()) {
- _pre_shift_selection();
- }
-
- int wi;
- int n_line = cursor.line - num_lines_from_rows(cursor.line, get_cursor_wrap_index(), -get_visible_rows(), wi) + 1;
- cursor_set_line(n_line, true, false, wi);
-
- if (k->get_shift()) {
- _post_shift_selection();
- }
-
+ if (k->is_action("ui_accept", true) || k->is_action("ui_text_completion_accept", true)) {
+ _confirm_completion();
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_cancel", true)) {
_cancel_completion();
- completion_hint = "";
+ accept_event();
+ return;
+ }
- } break;
- case KEY_KP_3: {
- if (k->get_unicode() != 0) {
- keycode_handled = false;
- break;
+ // Handle Unicode here (if no modifiers active) and update autocomplete.
+ if (k->get_unicode() >= 32) {
+ if (allow_unicode_handling && !readonly) {
+ _handle_unicode_character(k->get_unicode(), had_selection, true);
+ accept_event();
+ return;
}
- [[fallthrough]];
}
- case KEY_PAGEDOWN: {
- if (k->get_shift()) {
- _pre_shift_selection();
- }
-
- int wi;
- int n_line = cursor.line + num_lines_from_rows(cursor.line, get_cursor_wrap_index(), get_visible_rows(), wi) - 1;
- cursor_set_line(n_line, true, false, wi);
+ }
- if (k->get_shift()) {
- _post_shift_selection();
- }
+ // NEWLINES.
+ if (k->is_action("ui_text_newline_above", true)) {
+ _new_line(false, true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_newline_blank", true)) {
+ _new_line(false);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_newline", true)) {
+ _new_line();
+ accept_event();
+ return;
+ }
- _cancel_completion();
- completion_hint = "";
+ // INDENTATION.
+ if (k->is_action("ui_text_dedent", true)) {
+ _indent_left();
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_indent", true)) {
+ _indent_right();
+ accept_event();
+ return;
+ }
- } break;
- case KEY_A: {
-#ifndef APPLE_STYLE_KEYS
- if (!k->get_control() || k->get_shift() || k->get_alt()) {
- keycode_handled = false;
- break;
- }
- if (is_shortcut_keys_enabled()) {
- select_all();
- }
-#else
- if ((!k->get_command() && !k->get_control())) {
- keycode_handled = false;
- break;
- }
- if (!k->get_shift() && k->get_command() && is_shortcut_keys_enabled())
- select_all();
- else if (k->get_control()) {
- if (k->get_shift())
- _pre_shift_selection();
-
- int current_line_whitespace_len = 0;
- while (current_line_whitespace_len < text[cursor.line].length()) {
- char32_t c = text[cursor.line][current_line_whitespace_len];
- if (c != '\t' && c != ' ')
- break;
- current_line_whitespace_len++;
- }
+ // BACKSPACE AND DELETE.
+ if (k->is_action("ui_text_backspace_all_to_left", true)) {
+ _backspace(false, true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_backspace_word", true)) {
+ _backspace(true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_backspace", true)) {
+ _backspace();
+ if (completion_active) {
+ _update_completion_candidates();
+ }
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_delete_all_to_right", true)) {
+ _delete(false, true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_delete_word", true)) {
+ _delete(true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_delete", true)) {
+ _delete();
+ accept_event();
+ return;
+ }
- if (cursor_get_column() == current_line_whitespace_len)
- cursor_set_column(0);
- else
- cursor_set_column(current_line_whitespace_len);
+ // SCROLLING.
+ if (k->is_action("ui_text_scroll_up", true)) {
+ _scroll_lines_up();
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_scroll_down", true)) {
+ _scroll_lines_down();
+ accept_event();
+ return;
+ }
- if (k->get_shift())
- _post_shift_selection();
- else if (k->get_command() || k->get_control())
- deselect();
- }
- } break;
- case KEY_E: {
- if (!k->get_control() || k->get_command() || k->get_alt()) {
- keycode_handled = false;
- break;
- }
+ // SELECT ALL, CUT, COPY, PASTE.
- if (k->get_shift())
- _pre_shift_selection();
+ if (k->is_action("ui_text_select_all", true)) {
+ select_all();
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_cut", true)) {
+ cut();
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_copy", true)) {
+ copy();
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_paste", true)) {
+ paste();
+ accept_event();
+ return;
+ }
- if (k->get_command())
- cursor_set_line(text.size() - 1, true, false);
- cursor_set_column(text[cursor.line].length());
+ // UNDO/REDO.
+ if (k->is_action("ui_undo", true)) {
+ undo();
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_redo", true)) {
+ redo();
+ accept_event();
+ return;
+ }
- if (k->get_shift())
- _post_shift_selection();
- else if (k->get_command() || k->get_control())
- deselect();
+ // MISC.
- _cancel_completion();
+ if (k->is_action("ui_menu", true)) {
+ if (context_menu_enabled) {
+ menu->set_position(get_screen_transform().xform(_get_cursor_pixel_pos()));
+ menu->set_size(Vector2(1, 1));
+ _generate_context_menu();
+ menu->popup();
+ menu->grab_focus();
+ }
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_toggle_insert_mode", true)) {
+ set_insert_mode(!insert_mode);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_cancel", true)) {
+ if (completion_hint != "") {
completion_hint = "";
-#endif
- } break;
- case (KEY_QUOTELEFT): { // Swap current input direction (primary cursor)
- if (!k->get_command()) {
- keycode_handled = false;
- break;
- }
-
- if (input_direction == TEXT_DIRECTION_LTR) {
- input_direction = TEXT_DIRECTION_RTL;
- } else {
- input_direction = TEXT_DIRECTION_LTR;
- }
- cursor_set_column(cursor.column);
update();
- } break;
- case KEY_X: {
- if (readonly) {
- break;
- }
- if (!k->get_command() || k->get_shift() || k->get_alt()) {
- keycode_handled = false;
- break;
- }
- if (is_shortcut_keys_enabled()) {
- cut();
- }
-
- } break;
- case KEY_C: {
- if (!k->get_command() || k->get_shift() || k->get_alt()) {
- keycode_handled = false;
- break;
- }
-
- if (is_shortcut_keys_enabled()) {
- copy();
- }
-
- } break;
- case KEY_Z: {
- if (readonly) {
- break;
- }
-
- if (!k->get_command()) {
- keycode_handled = false;
- break;
- }
-
- if (is_shortcut_keys_enabled()) {
- if (k->get_shift()) {
- redo();
- } else {
- undo();
- }
- }
- } break;
- case KEY_Y: {
- if (readonly) {
- break;
- }
-
- if (!k->get_command()) {
- keycode_handled = false;
- break;
- }
-
- if (is_shortcut_keys_enabled()) {
- redo();
- }
- } break;
- case KEY_V: {
- if (readonly) {
- break;
- }
- if (!k->get_command() || k->get_shift() || k->get_alt()) {
- keycode_handled = false;
- break;
- }
-
- if (is_shortcut_keys_enabled()) {
- paste();
- }
-
- } break;
- case KEY_SPACE: {
-#ifdef OSX_ENABLED
- if (completion_enabled && k->get_metakey()) { // cmd-space is spotlight shortcut in OSX
-#else
- if (completion_enabled && k->get_command()) {
-#endif
-
- query_code_comple();
- keycode_handled = true;
- } else {
- keycode_handled = false;
- }
+ }
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_swap_input_direction", true)) {
+ _swap_current_input_direction();
+ accept_event();
+ return;
+ }
- } break;
+ // CURSOR MOVEMENT
- case KEY_MENU: {
- if (context_menu_enabled) {
- menu->set_position(get_screen_transform().xform(_get_cursor_pixel_pos()));
- menu->set_size(Vector2(1, 1));
- menu->popup();
- menu->grab_focus();
- }
- } break;
+ k = k->duplicate();
+ bool shift_pressed = k->get_shift();
+ // Remove shift or else actions will not match. Use above variable for selection.
+ k->set_shift(false);
- default: {
- keycode_handled = false;
- } break;
+ // CURSOR MOVEMENT - LEFT, RIGHT.
+ if (k->is_action("ui_text_caret_word_left", true)) {
+ _move_cursor_left(shift_pressed, true);
+ accept_event();
+ return;
}
-
- if (keycode_handled) {
+ if (k->is_action("ui_text_caret_left", true)) {
+ _move_cursor_left(shift_pressed, false);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_word_right", true)) {
+ _move_cursor_right(shift_pressed, true);
accept_event();
+ return;
}
-
- if (k->get_keycode() == KEY_INSERT) {
- set_insert_mode(!insert_mode);
+ if (k->is_action("ui_text_caret_right", true)) {
+ _move_cursor_right(shift_pressed, false);
accept_event();
return;
}
- if (!keycode_handled && (!k->get_command() || (k->get_command() && k->get_alt()))) { // For German keyboards.
-
- if (k->get_unicode() >= 32) {
- if (readonly) {
- return;
- }
-
- // Remove the old character if in insert mode and no selection.
- if (insert_mode && !had_selection) {
- begin_complex_operation();
-
- // Make sure we don't try and remove empty space.
- if (cursor.column < get_line(cursor.line).length()) {
- _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
- }
- }
-
- const char32_t chr[2] = { (char32_t)k->get_unicode(), 0 };
+ // CURSOR MOVEMENT - UP, DOWN.
+ if (k->is_action("ui_text_caret_up", true)) {
+ _move_cursor_up(shift_pressed);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_down", true)) {
+ _move_cursor_down(shift_pressed);
+ accept_event();
+ return;
+ }
- if (completion_hint != "" && k->get_unicode() == ')') {
- completion_hint = "";
- }
- if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
- _consume_pair_symbol(chr[0]);
- } else {
- _insert_text_at_cursor(chr);
- }
+ // CURSOR MOVEMENT - DOCUMENT START/END.
+ if (k->is_action("ui_text_caret_document_start", true)) { // && shift_pressed) {
+ _move_cursor_document_start(shift_pressed);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_document_end", true)) { // && shift_pressed) {
+ _move_cursor_document_end(shift_pressed);
+ accept_event();
+ return;
+ }
- if (insert_mode && !had_selection) {
- end_complex_operation();
- }
+ // CURSOR MOVEMENT - LINE START/END.
+ if (k->is_action("ui_text_caret_line_start", true)) {
+ _move_cursor_to_line_start(shift_pressed);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_line_end", true)) {
+ _move_cursor_to_line_end(shift_pressed);
+ accept_event();
+ return;
+ }
- if (selection.active != had_selection) {
- end_complex_operation();
- }
- accept_event();
- }
+ // CURSOR MOVEMENT - PAGE UP/DOWN.
+ if (k->is_action("ui_text_caret_page_up", true)) {
+ _move_cursor_page_up(shift_pressed);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_page_down", true)) {
+ _move_cursor_page_down(shift_pressed);
+ accept_event();
+ return;
}
- return;
+ if (allow_unicode_handling && !readonly && k->get_unicode() >= 32) {
+ // Handle Unicode (if no modifiers active).
+ _handle_unicode_character(k->get_unicode(), had_selection, false);
+ accept_event();
+ return;
+ }
}
}
@@ -3747,8 +3594,8 @@ void TextEdit::_scroll_lines_up() {
if (!selection.active) {
int cur_line = cursor.line;
int cur_wrap = get_cursor_wrap_index();
- int last_vis_line = get_last_visible_line();
- int last_vis_wrap = get_last_visible_line_wrap_index();
+ int last_vis_line = get_last_full_visible_line();
+ int last_vis_wrap = get_last_full_visible_line_wrap_index();
if (cur_line > last_vis_line || (cur_line == last_vis_line && cur_wrap > last_vis_wrap)) {
cursor_set_line(last_vis_line, false, false, last_vis_wrap);
@@ -4034,25 +3881,50 @@ int TextEdit::_get_control_height() const {
return control_height;
}
+int TextEdit::_get_menu_action_accelerator(const String &p_action) {
+ const List<Ref<InputEvent>> *events = InputMap::get_singleton()->action_get_events(p_action);
+ if (!events) {
+ return 0;
+ }
+
+ // Use first event in the list for the accelerator.
+ const List<Ref<InputEvent>>::Element *first_event = events->front();
+ if (!first_event) {
+ return 0;
+ }
+
+ const Ref<InputEventKey> event = first_event->get();
+ if (event.is_null()) {
+ return 0;
+ }
+
+ // Use physical keycode if non-zero
+ if (event->get_physical_keycode() != 0) {
+ return event->get_physical_keycode_with_modifiers();
+ } else {
+ return event->get_keycode_with_modifiers();
+ }
+}
+
void TextEdit::_generate_context_menu() {
// Reorganize context menu.
menu->clear();
if (!readonly) {
- menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0);
+ menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_cut") : 0);
}
- menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0);
+ menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_copy") : 0);
if (!readonly) {
- menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0);
+ menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_paste") : 0);
}
menu->add_separator();
if (is_selecting_enabled()) {
- menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0);
+ menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_text_select_all") : 0);
}
if (!readonly) {
menu->add_item(RTR("Clear"), MENU_CLEAR);
menu->add_separator();
- menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_Z : 0);
- menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z : 0);
+ menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_undo") : 0);
+ menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_redo") : 0);
}
menu->add_separator();
menu->add_submenu_item(RTR("Text writing direction"), "DirMenu");
@@ -4121,8 +3993,8 @@ void TextEdit::adjust_viewport_to_cursor() {
int first_vis_line = get_first_visible_line();
int first_vis_wrap = cursor.wrap_ofs;
- int last_vis_line = get_last_visible_line();
- int last_vis_wrap = get_last_visible_line_wrap_index();
+ int last_vis_line = get_last_full_visible_line();
+ int last_vis_wrap = get_last_full_visible_line_wrap_index();
if (cur_line < first_vis_line || (cur_line == first_vis_line && cur_wrap < first_vis_wrap)) {
// Cursor is above screen.
@@ -4891,11 +4763,13 @@ void TextEdit::_update_caches() {
cache.completion_font_color = get_theme_color("completion_font_color");
cache.font = get_theme_font("font");
cache.font_size = get_theme_font_size("font_size");
+ cache.outline_color = get_theme_color("font_outline_color");
+ cache.outline_size = get_theme_constant("outline_size");
cache.caret_color = get_theme_color("caret_color");
cache.caret_background_color = get_theme_color("caret_background_color");
cache.font_color = get_theme_color("font_color");
- cache.font_color_selected = get_theme_color("font_color_selected");
- cache.font_color_readonly = get_theme_color("font_color_readonly");
+ cache.font_selected_color = get_theme_color("font_selected_color");
+ cache.font_readonly_color = get_theme_color("font_readonly_color");
cache.selection_color = get_theme_color("selection_color");
cache.mark_color = get_theme_color("mark_color");
cache.current_line_color = get_theme_color("current_line_color");
@@ -5140,6 +5014,10 @@ void TextEdit::set_auto_indent(bool p_auto_indent) {
}
void TextEdit::cut() {
+ if (readonly) {
+ return;
+ }
+
if (!selection.active) {
String clipboard = text[cursor.line];
DisplayServer::get_singleton()->clipboard_set(clipboard);
@@ -5187,6 +5065,10 @@ void TextEdit::copy() {
}
void TextEdit::paste() {
+ if (readonly) {
+ return;
+ }
+
String clipboard = DisplayServer::get_singleton()->clipboard_get();
begin_complex_operation();
@@ -5197,7 +5079,7 @@ void TextEdit::paste() {
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
- } else if (!cut_copy_line.empty() && cut_copy_line == clipboard) {
+ } else if (!cut_copy_line.is_empty() && cut_copy_line == clipboard) {
cursor_set_column(0);
String ins = "\n";
clipboard += ins;
@@ -5890,6 +5772,10 @@ void TextEdit::_clear_redo() {
}
void TextEdit::undo() {
+ if (readonly) {
+ return;
+ }
+
_push_current_op();
if (undo_stack_pos == nullptr) {
@@ -5940,6 +5826,9 @@ void TextEdit::undo() {
}
void TextEdit::redo() {
+ if (readonly) {
+ return;
+ }
_push_current_op();
if (undo_stack_pos == nullptr) {
@@ -6100,7 +5989,7 @@ double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const {
}
// Count the number of visible lines up to this line.
- double new_line_scroll_pos = 0;
+ double new_line_scroll_pos = 0.0;
int to = CLAMP(p_line, 0, text.size() - 1);
for (int i = 0; i < to; i++) {
if (!text.is_hidden(i)) {
@@ -6135,19 +6024,19 @@ int TextEdit::get_first_visible_line() const {
return CLAMP(cursor.line_ofs, 0, text.size() - 1);
}
-int TextEdit::get_last_visible_line() const {
+int TextEdit::get_last_full_visible_line() const {
int first_vis_line = get_first_visible_line();
int last_vis_line = 0;
int wi;
- last_vis_line = first_vis_line + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi) - 1;
+ last_vis_line = first_vis_line + num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows(), wi) - 1;
last_vis_line = CLAMP(last_vis_line, 0, text.size() - 1);
return last_vis_line;
}
-int TextEdit::get_last_visible_line_wrap_index() const {
+int TextEdit::get_last_full_visible_line_wrap_index() const {
int first_vis_line = get_first_visible_line();
int wi;
- num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi);
+ num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows(), wi);
return wi;
}
@@ -6469,7 +6358,7 @@ void TextEdit::query_code_comple() {
c--;
}
- bool ignored = completion_active && !completion_options.empty();
+ bool ignored = completion_active && !completion_options.is_empty();
if (ignored) {
ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_PLAIN_TEXT;
const ScriptCodeCompletionOption *previous_option = nullptr;
@@ -6878,7 +6767,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
update();
}
}
- _change_notify();
+ notify_property_list_changed();
return true;
}
@@ -7177,23 +7066,11 @@ void TextEdit::_bind_methods() {
}
TextEdit::TextEdit() {
- setting_row = false;
- draw_tabs = false;
- draw_spaces = false;
- override_selected_font_color = false;
- draw_caret = true;
- max_chars = 0;
clear();
- wrap_enabled = false;
- wrap_at = 0;
- wrap_right_offset = 10;
set_focus_mode(FOCUS_ALL);
_update_caches();
- cache.line_spacing = 1;
- cache.font_size = 16;
set_default_cursor_shape(CURSOR_IBEAM);
- indent_size = 4;
text.set_indent_size(indent_size);
text.clear();
@@ -7203,31 +7080,16 @@ TextEdit::TextEdit() {
add_child(h_scroll);
add_child(v_scroll);
- updating_scrolls = false;
- selection.active = false;
-
h_scroll->connect("value_changed", callable_mp(this, &TextEdit::_scroll_moved));
v_scroll->connect("value_changed", callable_mp(this, &TextEdit::_scroll_moved));
v_scroll->connect("scrolling", callable_mp(this, &TextEdit::_v_scroll_input));
- cursor_changed_dirty = false;
- text_changed_dirty = false;
-
- selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE;
- selection.selecting_line = 0;
- selection.selecting_column = 0;
- selection.selecting_text = false;
- selection.active = false;
-
- block_caret = false;
- caret_blink_enabled = false;
caret_blink_timer = memnew(Timer);
add_child(caret_blink_timer);
caret_blink_timer->set_wait_time(0.65);
caret_blink_timer->connect("timeout", callable_mp(this, &TextEdit::_toggle_draw_caret));
cursor_set_blink_enabled(false);
- right_click_moves_caret = true;
idle_detect = memnew(Timer);
add_child(idle_detect);
@@ -7240,54 +7102,8 @@ TextEdit::TextEdit() {
click_select_held->set_wait_time(0.05);
click_select_held->connect("timeout", callable_mp(this, &TextEdit::_click_selection_held));
- current_op.type = TextOperation::TYPE_NONE;
- undo_enabled = true;
undo_stack_max_size = GLOBAL_GET("gui/common/text_edit_undo_stack_max_size");
- undo_stack_pos = nullptr;
- setting_text = false;
- last_dblclk = 0;
- current_op.version = 0;
- version = 0;
- saved_version = 0;
- completion_enabled = false;
- completion_active = false;
- completion_line_ofs = 0;
- tooltip_obj = nullptr;
- line_length_guidelines = false;
- line_length_guideline_soft_col = 80;
- line_length_guideline_hard_col = 100;
- hiding_enabled = false;
- next_operation_is_complex = false;
- scroll_past_end_of_file_enabled = false;
- auto_brace_completion_enabled = false;
- brace_matching_enabled = false;
- highlight_all_occurrences = false;
- highlight_current_line = false;
- indent_using_spaces = false;
- space_indent = " ";
- auto_indent = false;
- insert_mode = false;
- window_has_focus = true;
- select_identifiers_enabled = false;
- smooth_scroll_enabled = false;
- scrolling = false;
- minimap_clicked = false;
- dragging_minimap = false;
- can_drag_minimap = false;
- minimap_scroll_ratio = 0;
- minimap_scroll_click_pos = 0;
- dragging_selection = false;
- target_v_scroll = 0;
- v_scroll_speed = 80;
- draw_minimap = false;
- minimap_width = 80;
- minimap_char_size = Point2(1, 2);
- minimap_line_spacing = 1;
-
- selecting_enabled = true;
- context_menu_enabled = true;
- shortcut_keys_enabled = true;
menu = memnew(PopupMenu);
add_child(menu);
@@ -7322,12 +7138,10 @@ TextEdit::TextEdit() {
menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY);
menu->add_child(menu_ctl);
- readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly.
set_readonly(false);
menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
menu_dir->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
menu_ctl->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
- first_draw = true;
}
TextEdit::~TextEdit() {
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 3f16ed1366..b0c7314c65 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -92,14 +92,11 @@ private:
Vector<Vector2i> bidi_override;
Ref<TextParagraph> data_buf;
- bool marked;
- bool hidden;
+ bool marked = false;
+ bool hidden = false;
Line() {
data_buf.instance();
-
- marked = false;
- hidden = false;
}
};
@@ -173,46 +170,31 @@ private:
};
struct Cursor {
- int last_fit_x;
- int line, column; ///< cursor
- int x_ofs, line_ofs, wrap_ofs;
- Cursor() {
- last_fit_x = 0;
- line = 0;
- column = 0; ///< cursor
- x_ofs = 0;
- line_ofs = 0;
- wrap_ofs = 0;
- }
+ int last_fit_x = 0;
+ int line = 0;
+ int column = 0; ///< cursor
+ int x_ofs = 0;
+ int line_ofs = 0;
+ int wrap_ofs = 0;
} cursor;
struct Selection {
- SelectionMode selecting_mode;
- int selecting_line, selecting_column;
- int selected_word_beg, selected_word_end, selected_word_origin;
- bool selecting_text;
-
- bool active;
-
- int from_line, from_column;
- int to_line, to_column;
-
- bool shiftclick_left;
- Selection() {
- selecting_mode = SelectionMode::SELECTION_MODE_NONE;
- selecting_line = 0;
- selecting_column = 0;
- selected_word_beg = 0;
- selected_word_end = 0;
- selected_word_origin = 0;
- selecting_text = false;
- active = false;
- from_line = 0;
- from_column = 0;
- to_line = 0;
- to_column = 0;
- shiftclick_left = false;
- }
+ SelectionMode selecting_mode = SelectionMode::SELECTION_MODE_NONE;
+ int selecting_line = 0;
+ int selecting_column = 0;
+ int selected_word_beg = 0;
+ int selected_word_end = 0;
+ int selected_word_origin = 0;
+ bool selecting_text = false;
+
+ bool active = false;
+
+ int from_line = 0;
+ int from_column = 0;
+ int to_line = 0;
+ int to_column = 0;
+
+ bool shiftclick_left = false;
} selection;
Map<int, Dictionary> syntax_highlighting_cache;
@@ -224,25 +206,16 @@ private:
TYPE_REMOVE
};
- Type type;
- int from_line, from_column;
- int to_line, to_column;
+ Type type = TYPE_NONE;
+ int from_line = 0;
+ int from_column = 0;
+ int to_line = 0;
+ int to_column = 0;
String text;
- uint32_t prev_version;
- uint32_t version;
- bool chain_forward;
- bool chain_backward;
- TextOperation() {
- type = TYPE_NONE;
- from_line = 0;
- from_column = 0;
- to_line = 0;
- to_column = 0;
- prev_version = 0;
- version = 0;
- chain_forward = false;
- chain_backward = false;
- }
+ uint32_t prev_version = 0;
+ uint32_t version = 0;
+ bool chain_forward = false;
+ bool chain_backward = false;
};
String ime_text;
@@ -251,7 +224,7 @@ private:
TextOperation current_op;
List<TextOperation> undo_stack;
- List<TextOperation>::Element *undo_stack_pos;
+ List<TextOperation>::Element *undo_stack_pos = nullptr;
int undo_stack_max_size;
void _clear_redo();
@@ -264,20 +237,20 @@ private:
Dictionary _get_line_syntax_highlighting(int p_line);
Set<String> completion_prefixes;
- bool completion_enabled;
+ bool completion_enabled = false;
List<ScriptCodeCompletionOption> completion_sources;
Vector<ScriptCodeCompletionOption> completion_options;
- bool completion_active;
- bool completion_forced;
+ bool completion_active = false;
+ bool completion_forced = false;
ScriptCodeCompletionOption completion_current;
String completion_base;
- int completion_index;
+ int completion_index = 0;
Rect2i completion_rect;
- int completion_line_ofs;
+ int completion_line_ofs = 0;
String completion_hint;
- int completion_hint_offset;
+ int completion_hint_offset = 0;
- bool setting_text;
+ bool setting_text = false;
// data
Text text;
@@ -290,93 +263,93 @@ private:
Array st_args;
bool draw_control_chars = false;
- uint32_t version;
- uint32_t saved_version;
+ uint32_t version = 0;
+ uint32_t saved_version = 0;
- int max_chars;
- bool readonly;
- bool indent_using_spaces;
- int indent_size;
- String space_indent;
+ int max_chars = 0;
+ bool readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly.
+ bool indent_using_spaces = false;
+ int indent_size = 4;
+ String space_indent = " ";
Timer *caret_blink_timer;
- bool caret_blink_enabled;
- bool draw_caret;
- bool window_has_focus;
- bool block_caret;
- bool right_click_moves_caret;
+ bool caret_blink_enabled = false;
+ bool draw_caret = true;
+ bool window_has_focus = true;
+ bool block_caret = false;
+ bool right_click_moves_caret = true;
bool mid_grapheme_caret_enabled = false;
- bool wrap_enabled;
- int wrap_at;
- int wrap_right_offset;
-
- bool first_draw;
- bool setting_row;
- bool draw_tabs;
- bool draw_spaces;
- bool override_selected_font_color;
- bool cursor_changed_dirty;
- bool text_changed_dirty;
- bool undo_enabled;
- bool line_length_guidelines;
- int line_length_guideline_soft_col;
- int line_length_guideline_hard_col;
- bool hiding_enabled;
- bool draw_minimap;
- int minimap_width;
- Point2 minimap_char_size;
- int minimap_line_spacing;
-
- bool highlight_all_occurrences;
- bool scroll_past_end_of_file_enabled;
- bool auto_brace_completion_enabled;
- bool brace_matching_enabled;
- bool highlight_current_line;
- bool auto_indent;
+ bool wrap_enabled = false;
+ int wrap_at = 0;
+ int wrap_right_offset = 10;
+
+ bool first_draw = true;
+ bool setting_row = false;
+ bool draw_tabs = false;
+ bool draw_spaces = false;
+ bool override_selected_font_color = false;
+ bool cursor_changed_dirty = false;
+ bool text_changed_dirty = false;
+ bool undo_enabled = true;
+ bool line_length_guidelines = false;
+ int line_length_guideline_soft_col = 80;
+ int line_length_guideline_hard_col = 100;
+ bool hiding_enabled = false;
+ bool draw_minimap = false;
+ int minimap_width = 80;
+ Point2 minimap_char_size = Point2(1, 2);
+ int minimap_line_spacing = 1;
+
+ bool highlight_all_occurrences = false;
+ bool scroll_past_end_of_file_enabled = false;
+ bool auto_brace_completion_enabled = false;
+ bool brace_matching_enabled = false;
+ bool highlight_current_line = false;
+ bool auto_indent = false;
String cut_copy_line;
- bool insert_mode;
- bool select_identifiers_enabled;
-
- bool smooth_scroll_enabled;
- bool scrolling;
- bool dragging_selection;
- bool dragging_minimap;
- bool can_drag_minimap;
- bool minimap_clicked;
- double minimap_scroll_ratio;
- double minimap_scroll_click_pos;
- float target_v_scroll;
- float v_scroll_speed;
+ bool insert_mode = false;
+ bool select_identifiers_enabled = false;
+
+ bool smooth_scroll_enabled = false;
+ bool scrolling = false;
+ bool dragging_selection = false;
+ bool dragging_minimap = false;
+ bool can_drag_minimap = false;
+ bool minimap_clicked = false;
+ double minimap_scroll_ratio = 0.0;
+ double minimap_scroll_click_pos = 0.0;
+ float target_v_scroll = 0.0;
+ float v_scroll_speed = 80.0;
String highlighted_word;
- uint64_t last_dblclk;
+ uint64_t last_dblclk = 0;
Timer *idle_detect;
Timer *click_select_held;
HScrollBar *h_scroll;
VScrollBar *v_scroll;
- bool updating_scrolls;
+ bool updating_scrolls = false;
- Object *tooltip_obj;
+ Object *tooltip_obj = nullptr;
StringName tooltip_func;
Variant tooltip_ud;
- bool next_operation_is_complex;
+ bool next_operation_is_complex = false;
- bool callhint_below;
+ bool callhint_below = false;
Vector2 callhint_offset;
String search_text;
- uint32_t search_flags;
- int search_result_line;
- int search_result_col;
+ uint32_t search_flags = 0;
+ int search_result_line = 0;
+ int search_result_col = 0;
- bool selecting_enabled;
+ bool selecting_enabled = true;
- bool context_menu_enabled;
- bool shortcut_keys_enabled;
+ bool context_menu_enabled = true;
+ bool shortcut_keys_enabled = true;
bool virtual_keyboard_enabled = true;
void _generate_context_menu();
@@ -400,8 +373,8 @@ private:
void set_line_as_center_visible(int p_line, int p_wrap_index = 0);
void set_line_as_last_visible(int p_line, int p_wrap_index = 0);
int get_first_visible_line() const;
- int get_last_visible_line() const;
- int get_last_visible_line_wrap_index() const;
+ int get_last_full_visible_line() const;
+ int get_last_full_visible_line_wrap_index() const;
double get_visible_rows_offset() const;
double get_v_scroll_offset() const;
@@ -435,6 +408,7 @@ private:
int _get_control_height() const;
Point2 _get_local_mouse_pos() const;
+ int _get_menu_action_accelerator(const String &p_action);
void _reset_caret_blink_timer();
void _toggle_draw_caret();
@@ -468,6 +442,26 @@ private:
int _calculate_spaces_till_next_left_indent(int column);
int _calculate_spaces_till_next_right_indent(int column);
+ // Methods used in shortcuts
+ void _swap_current_input_direction();
+ void _new_line(bool p_split_current = true, bool p_above = false);
+ void _indent_right();
+ void _indent_left();
+ void _move_cursor_left(bool p_select, bool p_move_by_word = false);
+ void _move_cursor_right(bool p_select, bool p_move_by_word = false);
+ void _move_cursor_up(bool p_select);
+ void _move_cursor_down(bool p_select);
+ void _move_cursor_to_line_start(bool p_select);
+ void _move_cursor_to_line_end(bool p_select);
+ void _move_cursor_page_up(bool p_select);
+ void _move_cursor_page_down(bool p_select);
+ void _backspace(bool p_word = false, bool p_all_to_left = false);
+ void _delete(bool p_word = false, bool p_all_to_right = false);
+ void _delete_selection();
+ void _move_cursor_document_start(bool p_select);
+ void _move_cursor_document_end(bool p_select);
+ void _handle_unicode_character(uint32_t unicode, bool p_had_selection, bool p_update_auto_complete);
+
protected:
struct Cache {
Ref<Texture2D> tab_icon;
@@ -477,7 +471,9 @@ protected:
Ref<StyleBox> style_focus;
Ref<StyleBox> style_readonly;
Ref<Font> font;
- int font_size;
+ int font_size = 16;
+ int outline_size = 0;
+ Color outline_color;
Color completion_background_color;
Color completion_selected_color;
Color completion_existing_color;
@@ -485,8 +481,8 @@ protected:
Color caret_color;
Color caret_background_color;
Color font_color;
- Color font_color_selected;
- Color font_color_readonly;
+ Color font_selected_color;
+ Color font_readonly_color;
Color selection_color;
Color mark_color;
Color code_folding_color;
@@ -498,12 +494,8 @@ protected:
Color search_result_border_color;
Color background_color;
- int line_spacing;
- int minimap_width;
- Cache() {
- line_spacing = 0;
- minimap_width = 0;
- }
+ int line_spacing = 1;
+ int minimap_width = 0;
} cache;
virtual String get_tooltip(const Point2 &p_pos) const override;
@@ -668,8 +660,8 @@ public:
int get_row_height() const;
void backspace_at_cursor();
- void indent_left();
- void indent_right();
+ void indent_selected_lines_left();
+ void indent_selected_lines_right();
int get_indent_level(int p_line) const;
bool is_line_comment(int p_line) const;
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index 4187d77083..f43e3d1a9d 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "texture_button.h"
+
#include "core/typedefs.h"
+
#include <stdlib.h>
Size2 TextureButton::get_minimum_size() const {
@@ -247,8 +249,8 @@ void TextureButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_disabled_texture", "texture"), &TextureButton::set_disabled_texture);
ClassDB::bind_method(D_METHOD("set_focused_texture", "texture"), &TextureButton::set_focused_texture);
ClassDB::bind_method(D_METHOD("set_click_mask", "mask"), &TextureButton::set_click_mask);
- ClassDB::bind_method(D_METHOD("set_expand", "p_expand"), &TextureButton::set_expand);
- ClassDB::bind_method(D_METHOD("set_stretch_mode", "p_mode"), &TextureButton::set_stretch_mode);
+ ClassDB::bind_method(D_METHOD("set_expand", "expand"), &TextureButton::set_expand);
+ ClassDB::bind_method(D_METHOD("set_stretch_mode", "mode"), &TextureButton::set_stretch_mode);
ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &TextureButton::set_flip_h);
ClassDB::bind_method(D_METHOD("is_flipped_h"), &TextureButton::is_flipped_h);
ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &TextureButton::set_flip_v);
@@ -375,13 +377,4 @@ bool TextureButton::is_flipped_v() const {
return vflip;
}
-TextureButton::TextureButton() {
- expand = false;
- stretch_mode = STRETCH_SCALE;
- hflip = false;
- vflip = false;
-
- _texture_region = Rect2();
- _position_rect = Rect2();
- _tile = false;
-}
+TextureButton::TextureButton() {}
diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h
index 6f7ee65ae4..8361f3c341 100644
--- a/scene/gui/texture_button.h
+++ b/scene/gui/texture_button.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,15 +54,15 @@ private:
Ref<Texture2D> disabled;
Ref<Texture2D> focused;
Ref<BitMap> click_mask;
- bool expand;
- StretchMode stretch_mode;
+ bool expand = false;
+ StretchMode stretch_mode = STRETCH_SCALE;
Rect2 _texture_region;
Rect2 _position_rect;
- bool _tile;
+ bool _tile = false;
- bool hflip;
- bool vflip;
+ bool hflip = false;
+ bool vflip = false;
protected:
virtual Size2 get_minimum_size() const override;
diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp
index 8278bd3689..46ce9d5ca9 100644
--- a/scene/gui/texture_progress_bar.cpp
+++ b/scene/gui/texture_progress_bar.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -145,9 +145,9 @@ Point2 TextureProgressBar::unit_val_to_uv(float val) {
float angle = (val * Math_TAU) - Math_PI * 0.5;
Point2 dir = Vector2(Math::cos(angle), Math::sin(angle));
float t1 = 1.0;
- float cp = 0;
- float cq = 0;
- float cr = 0;
+ float cp = 0.0;
+ float cq = 0.0;
+ float cr = 0.0;
float edgeLeft = 0.0;
float edgeRight = 1.0;
float edgeBottom = 0.0;
@@ -540,17 +540,5 @@ void TextureProgressBar::_bind_methods() {
}
TextureProgressBar::TextureProgressBar() {
- mode = FILL_LEFT_TO_RIGHT;
- rad_init_angle = 0;
- rad_center_off = Point2();
- rad_max_degrees = 360;
set_mouse_filter(MOUSE_FILTER_PASS);
-
- nine_patch_stretch = false;
- stretch_margin[SIDE_LEFT] = 0;
- stretch_margin[SIDE_RIGHT] = 0;
- stretch_margin[SIDE_BOTTOM] = 0;
- stretch_margin[SIDE_TOP] = 0;
-
- tint_under = tint_progress = tint_over = Color(1, 1, 1);
}
diff --git a/scene/gui/texture_progress_bar.h b/scene/gui/texture_progress_bar.h
index 4fab8076fd..a3883a7017 100644
--- a/scene/gui/texture_progress_bar.h
+++ b/scene/gui/texture_progress_bar.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -98,13 +98,15 @@ public:
TextureProgressBar();
private:
- FillMode mode;
- float rad_init_angle;
- float rad_max_degrees;
+ FillMode mode = FILL_LEFT_TO_RIGHT;
+ float rad_init_angle = 0.0;
+ float rad_max_degrees = 360.0;
Point2 rad_center_off;
- bool nine_patch_stretch;
- int stretch_margin[4];
- Color tint_under, tint_progress, tint_over;
+ bool nine_patch_stretch = false;
+ int stretch_margin[4] = {};
+ Color tint_under = Color(1, 1, 1);
+ Color tint_progress = Color(1, 1, 1);
+ Color tint_over = Color(1, 1, 1);
Point2 unit_val_to_uv(float val);
Point2 get_relative_center();
diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp
index 58e7249284..1cba88e06f 100644
--- a/scene/gui/texture_rect.cpp
+++ b/scene/gui/texture_rect.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -217,11 +217,7 @@ bool TextureRect::is_flipped_v() const {
}
TextureRect::TextureRect() {
- expand = false;
- hflip = false;
- vflip = false;
set_mouse_filter(MOUSE_FILTER_PASS);
- stretch_mode = STRETCH_SCALE_ON_EXPAND;
}
TextureRect::~TextureRect() {
diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h
index e39545f679..0f93d5732f 100644
--- a/scene/gui/texture_rect.h
+++ b/scene/gui/texture_rect.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,11 +49,11 @@ public:
};
private:
- bool expand;
- bool hflip;
- bool vflip;
+ bool expand = false;
+ bool hflip = false;
+ bool vflip = false;
Ref<Texture2D> texture;
- StretchMode stretch_mode;
+ StretchMode stretch_mode = STRETCH_SCALE_ON_EXPAND;
void _texture_changed();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index ad4545cf6c..6ac4d7fd2f 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -163,7 +163,7 @@ void TreeItem::set_text(int p_column, String p_text) {
cells.write[p_column].max = INT_MIN;
for (int i = 0; i < strings.size(); i++) {
int value = i;
- if (!strings[i].get_slicec(':', 1).empty()) {
+ if (!strings[i].get_slicec(':', 1).is_empty()) {
value = strings[i].get_slicec(':', 1).to_int();
}
cells.write[p_column].min = MIN(cells[p_column].min, value);
@@ -320,7 +320,7 @@ int TreeItem::get_icon_max_width(int p_column) const {
void TreeItem::set_range(int p_column, double p_value) {
ERR_FAIL_INDEX(p_column, cells.size());
if (cells[p_column].step > 0) {
- p_value = Math::stepify(p_value, cells[p_column].step);
+ p_value = Math::snapped(p_value, cells[p_column].step);
}
if (p_value < cells[p_column].min) {
p_value = cells[p_column].min;
@@ -1018,7 +1018,7 @@ void Tree::update_cache() {
cache.custom_button_font_highlight = get_theme_color("custom_button_font_highlight");
cache.font_color = get_theme_color("font_color");
- cache.font_color_selected = get_theme_color("font_color_selected");
+ cache.font_selected_color = get_theme_color("font_selected_color");
cache.guide_color = get_theme_color("guide_color");
cache.drop_position_color = get_theme_color("drop_position_color");
cache.hseparation = get_theme_constant("hseparation");
@@ -1118,7 +1118,7 @@ int Tree::get_item_height(TreeItem *p_item) const {
return height;
}
-void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color) {
+void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color, int p_ol_size, const Color &p_ol_color) {
ERR_FAIL_COND(cache.font.is_null());
Rect2i rect = p_rect;
@@ -1160,6 +1160,9 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co
Point2 draw_pos = rect.position;
draw_pos.y += Math::floor((rect.size.y - p_cell.text_buf->get_size().y) / 2.0);
p_cell.text_buf->set_width(MAX(0, rect.size.width));
+ if (p_ol_size > 0 && p_ol_color.a > 0) {
+ p_cell.text_buf->draw_outline(ci, draw_pos, p_ol_size, p_ol_color);
+ }
p_cell.text_buf->draw(ci, draw_pos, p_color);
rect.position.x += ts.width + cache.hseparation;
rect.size.x -= ts.width + cache.hseparation;
@@ -1182,6 +1185,9 @@ void Tree::draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Co
Point2 draw_pos = rect.position;
draw_pos.y += Math::floor((rect.size.y - p_cell.text_buf->get_size().y) / 2.0);
p_cell.text_buf->set_width(MAX(0, rect.size.width));
+ if (p_ol_size > 0 && p_ol_color.a > 0) {
+ p_cell.text_buf->draw_outline(ci, draw_pos, p_ol_size, p_ol_color);
+ }
p_cell.text_buf->draw(ci, draw_pos, p_color);
}
}
@@ -1212,7 +1218,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) {
Vector<String> strings = p_item->cells[p_col].text.split(",");
for (int j = 0; j < strings.size(); j++) {
int value = j;
- if (!strings[j].get_slicec(':', 1).empty()) {
+ if (!strings[j].get_slicec(':', 1).is_empty()) {
value = strings[j].get_slicec(':', 1).to_int();
}
if (option == value) {
@@ -1433,7 +1439,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
}
- Color col = p_item->cells[i].custom_color ? p_item->cells[i].color : get_theme_color(p_item->cells[i].selected ? "font_color_selected" : "font_color");
+ Color col = p_item->cells[i].custom_color ? p_item->cells[i].color : get_theme_color(p_item->cells[i].selected ? "font_selected_color" : "font_color");
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
Color icon_col = p_item->cells[i].icon_color;
if (p_item->cells[i].dirty) {
@@ -1450,7 +1458,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
switch (p_item->cells[i].mode) {
case TreeItem::CELL_MODE_STRING: {
- draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col);
+ draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color);
} break;
case TreeItem::CELL_MODE_CHECK: {
Ref<Texture2D> checked = cache.checked;
@@ -1471,7 +1479,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
item_rect.size.x -= check_w;
item_rect.position.x += check_w;
- draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col);
+ draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color);
} break;
case TreeItem::CELL_MODE_RANGE: {
@@ -1485,8 +1493,14 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
p_item->cells.write[i].text_buf->set_width(cell_width);
if (rtl) {
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ p_item->cells[i].text_buf->draw_outline(ci, text_pos + Vector2(cell_width - text_width, 0), outline_size, font_outline_color);
+ }
p_item->cells[i].text_buf->draw(ci, text_pos + Vector2(cell_width - text_width, 0), col);
} else {
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ p_item->cells[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
p_item->cells[i].text_buf->draw(ci, text_pos, col);
}
@@ -1501,8 +1515,14 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
int cell_width = item_rect.size.x - updown->get_width();
if (rtl) {
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ p_item->cells[i].text_buf->draw_outline(ci, text_pos + Vector2(cell_width - text_width, 0), outline_size, font_outline_color);
+ }
p_item->cells[i].text_buf->draw(ci, text_pos + Vector2(cell_width - text_width, 0), col);
} else {
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ p_item->cells[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
p_item->cells[i].text_buf->draw(ci, text_pos, col);
}
@@ -1543,7 +1563,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
if (!p_item->cells[i].editable) {
- draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col);
+ draw_item_rect(p_item->cells.write[i], item_rect, col, icon_col, outline_size, font_outline_color);
break;
}
@@ -1571,7 +1591,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
ir.position += cache.custom_button->get_offset();
}
- draw_item_rect(p_item->cells.write[i], ir, col, icon_col);
+ draw_item_rect(p_item->cells.write[i], ir, col, icon_col, outline_size, font_outline_color);
downarrow->draw(ci, arrow_pos);
@@ -2031,7 +2051,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
popup_menu->clear();
for (int i = 0; i < c.text.get_slice_count(","); i++) {
String s = c.text.get_slicec(',', i);
- popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).empty() ? i : s.get_slicec(':', 1).to_int());
+ popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).is_empty() ? i : s.get_slicec(':', 1).to_int());
}
popup_menu->set_size(Size2(col_width, 0));
@@ -2191,7 +2211,7 @@ void Tree::_text_editor_enter(String p_text) {
case TreeItem::CELL_MODE_RANGE: {
c.val = p_text.to_float();
if (c.step > 0) {
- c.val = Math::stepify(c.val, c.step);
+ c.val = Math::snapped(c.val, c.step);
}
if (c.val < c.min) {
c.val = c.min;
@@ -2930,7 +2950,7 @@ bool Tree::edit_selected() {
popup_menu->clear();
for (int i = 0; i < c.text.get_slice_count(","); i++) {
String s2 = c.text.get_slicec(',', i);
- popup_menu->add_item(s2.get_slicec(':', 0), s2.get_slicec(':', 1).empty() ? i : s2.get_slicec(':', 1).to_int());
+ popup_menu->add_item(s2.get_slicec(':', 0), s2.get_slicec(':', 1).is_empty() ? i : s2.get_slicec(':', 1).to_int());
}
popup_menu->set_size(Size2(rect.size.width, 0));
@@ -3143,6 +3163,8 @@ void Tree::_notification(int p_what) {
Ref<StyleBox> bg = cache.bg;
Ref<StyleBox> bg_focus = get_theme_stylebox("bg_focus");
+ Color font_outline_color = get_theme_color("font_outline_color");
+ int outline_size = get_theme_constant("outline_size");
Point2 draw_ofs;
draw_ofs += bg->get_offset();
@@ -3179,7 +3201,12 @@ void Tree::_notification(int p_what) {
//text
int clip_w = tbrect.size.width - sb->get_minimum_size().width;
columns.write[i].text_buf->set_width(clip_w);
- columns[i].text_buf->draw(ci, tbrect.position + Point2i(sb->get_offset().x + (tbrect.size.width - columns[i].text_buf->get_size().x) / 2, (tbrect.size.height - columns[i].text_buf->get_size().y) / 2), cache.title_button_color);
+
+ Vector2 text_pos = tbrect.position + Point2i(sb->get_offset().x + (tbrect.size.width - columns[i].text_buf->get_size().x) / 2, (tbrect.size.height - columns[i].text_buf->get_size().y) / 2);
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ columns[i].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
+ columns[i].text_buf->draw(ci, text_pos, cache.title_button_color);
}
}
}
@@ -3315,6 +3342,9 @@ void Tree::item_selected(int p_column, TreeItem *p_item) {
//emit_signal("multi_selected",p_item,p_column,true); - NO this is for TreeItem::select
selected_col = p_column;
+ if (!selected_item) {
+ selected_item = p_item;
+ }
} else {
select_single_item(p_item, root, p_column);
}
@@ -3322,6 +3352,14 @@ void Tree::item_selected(int p_column, TreeItem *p_item) {
}
void Tree::item_deselected(int p_column, TreeItem *p_item) {
+ if (selected_item == p_item) {
+ selected_item = nullptr;
+
+ if (selected_col == p_column) {
+ selected_col = -1;
+ }
+ }
+
if (select_mode == SELECT_MULTI || select_mode == SELECT_SINGLE) {
p_item->cells.write[p_column].selected = false;
}
@@ -4149,6 +4187,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_edited"), &Tree::get_edited);
ClassDB::bind_method(D_METHOD("get_edited_column"), &Tree::get_edited_column);
+ ClassDB::bind_method(D_METHOD("edit_selected"), &Tree::edit_selected);
ClassDB::bind_method(D_METHOD("get_custom_popup_rect"), &Tree::get_custom_popup_rect);
ClassDB::bind_method(D_METHOD("get_item_area_rect", "item", "column"), &Tree::_get_item_rect, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("get_item_at_position", "position"), &Tree::get_item_at_position);
@@ -4174,6 +4213,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language);
ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll);
+ ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::_scroll_to_item);
ClassDB::bind_method(D_METHOD("set_hide_folding", "hide"), &Tree::set_hide_folding);
ClassDB::bind_method(D_METHOD("is_folding_hidden"), &Tree::is_folding_hidden);
@@ -4223,19 +4263,8 @@ void Tree::_bind_methods() {
}
Tree::Tree() {
- selected_col = 0;
columns.resize(1);
- selected_item = nullptr;
- edited_item = nullptr;
- selected_col = -1;
- edited_col = -1;
- hide_root = false;
- select_mode = SELECT_SINGLE;
- root = nullptr;
- popup_menu = nullptr;
- popup_edited_item = nullptr;
- text_editor = nullptr;
set_focus_mode(FOCUS_ALL);
popup_menu = memnew(PopupMenu);
@@ -4279,50 +4308,9 @@ Tree::Tree() {
set_notify_transform(true);
- updating_value_editor = false;
- pressed_button = -1;
- show_column_titles = false;
-
- cache.click_type = Cache::CLICK_NONE;
- cache.hover_type = Cache::CLICK_NONE;
- cache.hover_index = -1;
- cache.click_index = -1;
- cache.click_id = -1;
- cache.click_item = nullptr;
- cache.click_column = 0;
- cache.hover_cell = -1;
- last_keypress = 0;
- focus_in_id = 0;
-
- blocked = 0;
-
- cursor_can_exit_tree = true;
set_mouse_filter(MOUSE_FILTER_STOP);
- drag_speed = 0;
- drag_touching = false;
- drag_touching_deaccel = false;
- pressing_for_editor = false;
- range_drag_enabled = false;
-
- hide_folding = false;
-
- drop_mode_flags = 0;
- drop_mode_over = nullptr;
- drop_mode_section = 0;
- single_select_defer = nullptr;
-
- scrolling = false;
- allow_rmb_select = false;
- force_edit_checkbox_only_on_checkbox = false;
-
set_clip_contents(true);
-
- cache.hover_item = nullptr;
- cache.hover_cell = -1;
-
- allow_reselect = false;
- propagate_mouse_activated = false;
}
Tree::~Tree() {
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 82422b8be3..1be21cb4a4 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -62,7 +62,7 @@ private:
friend class Tree;
struct Cell {
- TreeCellMode mode;
+ TreeCellMode mode = TreeItem::CELL_MODE_STRING;
Ref<Texture2D> icon;
Rect2i icon_region;
@@ -74,24 +74,27 @@ private:
Control::StructuredTextParser st_parser = Control::STRUCTURED_TEXT_DEFAULT;
Array st_args;
Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED;
- bool dirty;
- double min, max, step, val;
- int icon_max_w;
- bool expr;
- bool checked;
- bool editable;
- bool selected;
- bool selectable;
- bool custom_color;
+ bool dirty = true;
+ double min = 0.0;
+ double max = 100.0;
+ double step = 1.0;
+ double val = 0.0;
+ int icon_max_w = 0;
+ bool expr = false;
+ bool checked = false;
+ bool editable = false;
+ bool selected = false;
+ bool selectable = true;
+ bool custom_color = false;
Color color;
- bool custom_bg_color;
- bool custom_bg_outline;
+ bool custom_bg_color = false;
+ bool custom_bg_outline = false;
Color bg_color;
- bool custom_button;
- bool expand_right;
- Color icon_color;
+ bool custom_button = false;
+ bool expand_right = false;
+ Color icon_color = Color(1, 1, 1);
- TextAlign text_align;
+ TextAlign text_align = ALIGN_LEFT;
Variant meta;
String tooltip;
@@ -100,42 +103,17 @@ private:
StringName custom_draw_callback;
struct Button {
- int id;
- bool disabled;
+ int id = 0;
+ bool disabled = false;
Ref<Texture2D> texture;
- Color color;
+ Color color = Color(1, 1, 1, 1);
String tooltip;
- Button() {
- id = 0;
- disabled = false;
- color = Color(1, 1, 1, 1);
- tooltip = "";
- }
};
Vector<Button> buttons;
Cell() {
text_buf.instance();
- dirty = true;
- custom_draw_obj = ObjectID();
- custom_button = false;
- mode = TreeItem::CELL_MODE_STRING;
- min = 0;
- max = 100;
- step = 1;
- val = 0;
- checked = false;
- editable = false;
- selected = false;
- selectable = true;
- custom_color = false;
- custom_bg_color = false;
- expr = false;
- icon_max_w = 0;
- text_align = ALIGN_LEFT;
- expand_right = false;
- icon_color = Color(1, 1, 1);
}
Size2 get_icon_size() const;
@@ -332,46 +310,46 @@ public:
private:
friend class TreeItem;
- TreeItem *root;
- TreeItem *popup_edited_item;
- TreeItem *selected_item;
- TreeItem *edited_item;
+ TreeItem *root = nullptr;
+ TreeItem *popup_edited_item = nullptr;
+ TreeItem *selected_item = nullptr;
+ TreeItem *edited_item = nullptr;
- TreeItem *drop_mode_over;
- int drop_mode_section;
+ TreeItem *drop_mode_over = nullptr;
+ int drop_mode_section = 0;
- TreeItem *single_select_defer;
- int single_select_defer_column;
+ TreeItem *single_select_defer = nullptr;
+ int single_select_defer_column = 0;
- int pressed_button;
- bool pressing_for_editor;
+ int pressed_button = -1;
+ bool pressing_for_editor = false;
String pressing_for_editor_text;
Vector2 pressing_pos;
Rect2 pressing_item_rect;
- float range_drag_base;
- bool range_drag_enabled;
+ float range_drag_base = 0.0;
+ bool range_drag_enabled = false;
Vector2 range_drag_capture_pos;
- bool propagate_mouse_activated;
+ bool propagate_mouse_activated = false;
//TreeItem *cursor_item;
//int cursor_column;
Rect2 custom_popup_rect;
- int edited_col;
- int selected_col;
- int popup_edited_item_col;
- bool hide_root;
- SelectMode select_mode;
+ int edited_col = -1;
+ int selected_col = -1;
+ int popup_edited_item_col = -1;
+ bool hide_root = false;
+ SelectMode select_mode = SELECT_SINGLE;
- int blocked;
+ int blocked = 0;
- int drop_mode_flags;
+ int drop_mode_flags = 0;
struct ColumnInfo {
- int min_width;
- bool expand;
+ int min_width = 1;
+ bool expand = true;
String title;
Ref<TextLine> text_buf;
Dictionary opentype_features;
@@ -379,27 +357,25 @@ private:
Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED;
ColumnInfo() {
text_buf.instance();
- min_width = 1;
- expand = true;
}
};
- bool show_column_titles;
+ bool show_column_titles = false;
VBoxContainer *popup_editor_vb;
Popup *popup_editor;
- LineEdit *text_editor;
+ LineEdit *text_editor = nullptr;
HSlider *value_editor;
- bool updating_value_editor;
- uint64_t focus_in_id;
- PopupMenu *popup_menu;
+ bool updating_value_editor = false;
+ uint64_t focus_in_id = 0;
+ PopupMenu *popup_menu = nullptr;
Vector<ColumnInfo> columns;
Timer *range_click_timer;
- TreeItem *range_item_last;
- bool range_up_last;
+ TreeItem *range_item_last = nullptr;
+ bool range_up_last = false;
void _range_click_timeout();
int compute_item_height(TreeItem *p_item) const;
@@ -409,7 +385,7 @@ private:
void update_item_cell(TreeItem *p_item, int p_col);
void update_item_cache(TreeItem *p_item);
//void draw_item_text(String p_text,const Ref<Texture2D>& p_icon,int p_icon_max_w,bool p_tool,Rect2i p_rect,const Color& p_color);
- void draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color);
+ void draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color, int p_ol_size, const Color &p_ol_color);
int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item);
void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = nullptr, bool *r_in_range = nullptr, bool p_force_deselect = false);
int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod);
@@ -434,8 +410,8 @@ private:
struct Cache {
Ref<Font> font;
Ref<Font> tb_font;
- int font_size;
- int tb_font_size;
+ int font_size = 0;
+ int tb_font_size = 0;
Ref<StyleBox> bg;
Ref<StyleBox> selected;
Ref<StyleBox> selected_focus;
@@ -459,21 +435,21 @@ private:
Ref<Texture2D> updown;
Color font_color;
- Color font_color_selected;
+ Color font_selected_color;
Color guide_color;
Color drop_position_color;
Color relationship_line_color;
Color custom_button_font_highlight;
- int hseparation;
- int vseparation;
- int item_margin;
- int button_margin;
+ int hseparation = 0;
+ int vseparation = 0;
+ int item_margin = 0;
+ int button_margin = 0;
Point2 offset;
- int draw_relationship_lines;
- int draw_guides;
- int scroll_border;
- int scroll_speed;
+ int draw_relationship_lines = 0;
+ int draw_guides = 0;
+ int scroll_border = 0;
+ int scroll_speed = 0;
enum ClickType {
CLICK_NONE,
@@ -482,17 +458,17 @@ private:
};
- ClickType click_type;
- ClickType hover_type;
- int click_index;
- int click_id;
- TreeItem *click_item;
- int click_column;
- int hover_index;
+ ClickType click_type = Cache::CLICK_NONE;
+ ClickType hover_type = Cache::CLICK_NONE;
+ int click_index = -1;
+ int click_id = -1;
+ TreeItem *click_item = nullptr;
+ int click_column = 0;
+ int hover_index = -1;
Point2 click_pos;
- TreeItem *hover_item;
- int hover_cell;
+ TreeItem *hover_item = nullptr;
+ int hover_cell = -1;
Point2i text_editor_position;
@@ -510,9 +486,9 @@ private:
Rect2 search_item_rect(TreeItem *p_from, TreeItem *p_item);
//Rect2 get_item_rect(TreeItem *p_item);
- uint64_t last_keypress;
+ uint64_t last_keypress = 0;
String incr_search;
- bool cursor_can_exit_tree;
+ bool cursor_can_exit_tree = true;
void _do_incr_search(const String &p_add);
TreeItem *_search_item_text(TreeItem *p_at, const String &p_find, int *r_col, bool p_selectable, bool p_backwards = false);
@@ -526,21 +502,21 @@ private:
float last_drag_time;
float time_since_motion;*/
- float drag_speed;
- float drag_from;
- float drag_accum;
+ float drag_speed = 0.0;
+ float drag_from = 0.0;
+ float drag_accum = 0.0;
Vector2 last_speed;
- bool drag_touching;
- bool drag_touching_deaccel;
- bool click_handled;
- bool allow_rmb_select;
- bool scrolling;
+ bool drag_touching = false;
+ bool drag_touching_deaccel = false;
+ bool click_handled = false;
+ bool allow_rmb_select = false;
+ bool scrolling = false;
- bool allow_reselect;
+ bool allow_reselect = false;
- bool force_edit_checkbox_only_on_checkbox;
+ bool force_edit_checkbox_only_on_checkbox = false;
- bool hide_folding;
+ bool hide_folding = false;
int _count_selected_items(TreeItem *p_from) const;
void _go_left();
@@ -564,6 +540,10 @@ protected:
return get_item_rect(Object::cast_to<TreeItem>(p_item), p_column);
}
+ void _scroll_to_item(Object *p_item) {
+ scroll_to_item(Object::cast_to<TreeItem>(p_item));
+ }
+
public:
virtual String get_tooltip(const Point2 &p_pos) const override;
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index e118cb0d8d..0590ae2415 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -462,25 +462,7 @@ void VideoPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
}
-VideoPlayer::VideoPlayer() {
- volume = 1;
- loops = false;
- paused = false;
- autoplay = false;
- expand = true;
-
- audio_track = 0;
- bus_index = 0;
-
- buffering_ms = 500;
-
- // internal_stream.player=this;
- // stream_rid=AudioServer::get_singleton()->audio_stream_create(&internal_stream);
- last_audio_time = 0;
-
- wait_resampler = 0;
- wait_resampler_limit = 2;
-};
+VideoPlayer::VideoPlayer() {}
VideoPlayer::~VideoPlayer() {
// if (stream_rid.is_valid())
diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h
index 573aec5a2c..0edad296a1 100644
--- a/scene/gui/video_player.h
+++ b/scene/gui/video_player.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,8 +41,8 @@ class VideoPlayer : public Control {
struct Output {
AudioFrame vol;
- int bus_index;
- Viewport *viewport; //pointer only used for reference to previous mix
+ int bus_index = 0;
+ Viewport *viewport = nullptr; //pointer only used for reference to previous mix
};
Ref<VideoStreamPlayback> playback;
Ref<VideoStream> stream;
@@ -56,17 +56,18 @@ class VideoPlayer : public Control {
AudioRBResampler resampler;
Vector<AudioFrame> mix_buffer;
- int wait_resampler, wait_resampler_limit;
-
- bool paused;
- bool autoplay;
- float volume;
- double last_audio_time;
- bool expand;
- bool loops;
- int buffering_ms;
- int audio_track;
- int bus_index;
+ int wait_resampler = 0;
+ int wait_resampler_limit = 2;
+
+ bool paused = false;
+ bool autoplay = false;
+ float volume = 1.0;
+ double last_audio_time = 0.0;
+ bool expand = true;
+ bool loops = false;
+ int buffering_ms = 500;
+ int audio_track = 0;
+ int bus_index = 0;
StringName bus;
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 8babb1460f..90bc99a941 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -203,7 +203,7 @@ CanvasItemMaterial::LightMode CanvasItemMaterial::get_light_mode() const {
void CanvasItemMaterial::set_particles_animation(bool p_particles_anim) {
particles_animation = p_particles_anim;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
bool CanvasItemMaterial::get_particles_animation() const {
@@ -387,7 +387,6 @@ void CanvasItem::show() {
}
_propagate_visibility_changed(true);
- _change_notify("visible");
}
void CanvasItem::hide() {
@@ -403,7 +402,6 @@ void CanvasItem::hide() {
}
_propagate_visibility_changed(false);
- _change_notify("visible");
}
CanvasItem *CanvasItem::current_item_drawn = nullptr;
@@ -1035,7 +1033,7 @@ void CanvasItem::set_material(const Ref<Material> &p_material) {
rid = material->get_rid();
}
RS::get_singleton()->canvas_item_set_material(canvas_item, rid);
- _change_notify(); //properties for material exposed
+ notify_property_list_changed(); //properties for material exposed
}
void CanvasItem::set_use_parent_material(bool p_use_parent_material) {
@@ -1341,7 +1339,7 @@ void CanvasItem::set_texture_filter(TextureFilter p_texture_filter) {
}
texture_filter = p_texture_filter;
_update_texture_filter_changed(true);
- _change_notify();
+ notify_property_list_changed();
}
CanvasItem::TextureFilter CanvasItem::get_texture_filter() const {
@@ -1381,7 +1379,7 @@ void CanvasItem::set_texture_repeat(TextureRepeat p_texture_repeat) {
}
texture_repeat = p_texture_repeat;
_update_texture_repeat_changed(true);
- _change_notify();
+ notify_property_list_changed();
}
void CanvasItem::set_clip_children(bool p_enabled) {
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 34268c1a78..e22f93a7ea 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -90,7 +90,7 @@ private:
struct ShaderData {
RID shader;
- int users;
+ int users = 0;
};
static Map<MaterialKey, ShaderData> shader_map;
@@ -149,7 +149,7 @@ public:
static void finish_shaders();
static void flush_changes();
- RID get_shader_rid() const;
+ virtual RID get_shader_rid() const override;
virtual Shader::Mode get_shader_mode() const override;
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index 46cfb968f8..85d7edd64b 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -231,6 +231,7 @@ void CanvasLayer::set_follow_viewport(bool p_enable) {
follow_viewport = p_enable;
_update_follow_viewport();
+ notify_property_list_changed();
}
bool CanvasLayer::is_following_viewport() const {
@@ -257,6 +258,12 @@ void CanvasLayer::_update_follow_viewport(bool p_force_exit) {
}
}
+void CanvasLayer::_validate_property(PropertyInfo &property) const {
+ if (!follow_viewport && property.name == "follow_viewport_scale") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void CanvasLayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
ClassDB::bind_method(D_METHOD("get_layer"), &CanvasLayer::get_layer);
@@ -303,17 +310,7 @@ void CanvasLayer::_bind_methods() {
}
CanvasLayer::CanvasLayer() {
- vp = nullptr;
- scale = Vector2(1, 1);
- rot = 0;
- locrotscale_dirty = false;
- layer = 1;
canvas = RS::get_singleton()->canvas_create();
- custom_viewport = nullptr;
-
- sort_index = 0;
- follow_viewport = false;
- follow_viewport_scale = 1.0;
}
CanvasLayer::~CanvasLayer() {
diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h
index 0c68b1ab69..899039340a 100644
--- a/scene/main/canvas_layer.h
+++ b/scene/main/canvas_layer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,24 +38,24 @@ class Viewport;
class CanvasLayer : public Node {
GDCLASS(CanvasLayer, Node);
- bool locrotscale_dirty;
+ bool locrotscale_dirty = false;
Vector2 ofs;
- Size2 scale;
- real_t rot;
- int layer;
+ Size2 scale = Vector2(1, 1);
+ real_t rot = 0.0;
+ int layer = 1;
Transform2D transform;
RID canvas;
ObjectID custom_viewport_id; // to check validity
- Viewport *custom_viewport;
+ Viewport *custom_viewport = nullptr;
RID viewport;
- Viewport *vp;
+ Viewport *vp = nullptr;
- int sort_index;
+ int sort_index = 0;
- bool follow_viewport;
- float follow_viewport_scale;
+ bool follow_viewport = false;
+ float follow_viewport_scale = 1.0;
void _update_xform();
void _update_locrotscale();
@@ -64,6 +64,7 @@ class CanvasLayer : public Node {
protected:
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_layer(int p_xform);
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index f484d25dc1..71c372aec2 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,7 +49,7 @@ Error HTTPRequest::_parse_url(const String &p_url) {
got_response = false;
body_len = -1;
body.resize(0);
- downloaded = 0;
+ downloaded.set(0);
redirections = 0;
String url_lower = url.to_lower();
@@ -159,11 +159,11 @@ Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_cust
requesting = true;
- if (use_threads) {
- thread_done = false;
- thread_request_quit = false;
+ if (use_threads.is_set()) {
+ thread_done.clear();
+ thread_request_quit.clear();
client->set_blocking_mode(true);
- thread = Thread::create(_thread_func, this);
+ thread.start(_thread_func, this);
} else {
client->set_blocking_mode(false);
err = _request();
@@ -186,7 +186,7 @@ void HTTPRequest::_thread_func(void *p_userdata) {
if (err != OK) {
hr->call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
} else {
- while (!hr->thread_request_quit) {
+ while (!hr->thread_request_quit.is_set()) {
bool exit = hr->_update_connection();
if (exit) {
break;
@@ -195,7 +195,7 @@ void HTTPRequest::_thread_func(void *p_userdata) {
}
}
- hr->thread_done = true;
+ hr->thread_done.set();
}
void HTTPRequest::cancel_request() {
@@ -205,13 +205,11 @@ void HTTPRequest::cancel_request() {
return;
}
- if (!use_threads) {
+ if (!use_threads.is_set()) {
set_process_internal(false);
} else {
- thread_request_quit = true;
- Thread::wait_to_finish(thread);
- memdelete(thread);
- thread = nullptr;
+ thread_request_quit.set();
+ thread.wait_to_finish();
}
if (file) {
@@ -238,7 +236,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
List<String> rheaders;
client->get_response_headers(&rheaders);
response_headers.resize(0);
- downloaded = 0;
+ downloaded.set(0);
for (List<String>::Element *E = rheaders.front(); E; E = E->next()) {
response_headers.push_back(E->get());
}
@@ -278,7 +276,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
got_response = false;
body_len = -1;
body.resize(0);
- downloaded = 0;
+ downloaded.set(0);
redirections = new_redirs;
*ret_value = false;
return true;
@@ -389,9 +387,12 @@ bool HTTPRequest::_update_connection() {
}
client->poll();
+ if (client->get_status() != HTTPClient::STATUS_BODY) {
+ return false;
+ }
PackedByteArray chunk = client->read_response_body_chunk();
- downloaded += chunk.size();
+ downloaded.add(chunk.size());
if (file) {
const uint8_t *r = chunk.ptr();
@@ -404,19 +405,20 @@ bool HTTPRequest::_update_connection() {
body.append_array(chunk);
}
- if (body_size_limit >= 0 && downloaded > body_size_limit) {
+ if (body_size_limit >= 0 && downloaded.get() > body_size_limit) {
call_deferred("_request_done", RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray());
return true;
}
if (body_len >= 0) {
- if (downloaded == body_len) {
+ if (downloaded.get() == body_len) {
call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body);
return true;
}
} else if (client->get_status() == HTTPClient::STATUS_DISCONNECTED) {
// We read till EOF, with no errors. Request is done.
call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body);
+ return true;
}
return false;
@@ -480,7 +482,7 @@ void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArra
void HTTPRequest::_notification(int p_what) {
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
- if (use_threads) {
+ if (use_threads.is_set()) {
return;
}
bool done = _update_connection();
@@ -499,11 +501,11 @@ void HTTPRequest::_notification(int p_what) {
void HTTPRequest::set_use_threads(bool p_use) {
ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED);
- use_threads = p_use;
+ use_threads.set_to(p_use);
}
bool HTTPRequest::is_using_threads() const {
- return use_threads;
+ return use_threads.is_set();
}
void HTTPRequest::set_accept_gzip(bool p_gzip) {
@@ -557,7 +559,7 @@ int HTTPRequest::get_max_redirects() const {
}
int HTTPRequest::get_downloaded_bytes() const {
- return downloaded;
+ return downloaded.get();
}
int HTTPRequest::get_body_size() const {
@@ -640,31 +642,11 @@ void HTTPRequest::_bind_methods() {
}
HTTPRequest::HTTPRequest() {
- thread = nullptr;
-
- port = 80;
- redirections = 0;
- max_redirects = 8;
- body_len = -1;
- got_response = false;
- validate_ssl = false;
- use_ssl = false;
- accept_gzip = true;
- response_code = 0;
- request_sent = false;
- requesting = false;
client.instance();
- use_threads = false;
- thread_done = false;
- downloaded = 0;
- body_size_limit = -1;
- file = nullptr;
-
timer = memnew(Timer);
timer->set_one_shot(true);
timer->connect("timeout", callable_mp(this, &HTTPRequest::_timeout));
add_child(timer);
- timeout = 0;
}
HTTPRequest::~HTTPRequest() {
diff --git a/scene/main/http_request.h b/scene/main/http_request.h
index 2e8931120b..92b0ff28e9 100644
--- a/scene/main/http_request.h
+++ b/scene/main/http_request.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,6 +34,7 @@
#include "core/io/http_client.h"
#include "core/os/file_access.h"
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
#include "node.h"
#include "scene/main/timer.h"
@@ -60,42 +61,42 @@ public:
};
private:
- bool requesting;
+ bool requesting = false;
String request_string;
String url;
- int port;
+ int port = 80;
Vector<String> headers;
- bool validate_ssl;
- bool use_ssl;
+ bool validate_ssl = false;
+ bool use_ssl = false;
HTTPClient::Method method;
Vector<uint8_t> request_data;
- bool request_sent;
+ bool request_sent = false;
Ref<HTTPClient> client;
PackedByteArray body;
- volatile bool use_threads;
- bool accept_gzip;
+ SafeFlag use_threads;
+ bool accept_gzip = true;
- bool got_response;
- int response_code;
+ bool got_response = false;
+ int response_code = 0;
Vector<String> response_headers;
String download_to_file;
- FileAccess *file;
+ FileAccess *file = nullptr;
- int body_len;
- volatile int downloaded;
- int body_size_limit;
+ int body_len = -1;
+ SafeNumeric<int> downloaded;
+ int body_size_limit = -1;
- int redirections;
+ int redirections = 0;
bool _update_connection();
- int max_redirects;
+ int max_redirects = 8;
- int timeout;
+ int timeout = 0;
void _redirect_request(const String &p_new_url);
@@ -107,10 +108,10 @@ private:
bool has_header(const PackedStringArray &p_headers, const String &p_header_name);
String get_header_value(const PackedStringArray &p_headers, const String &header_name);
- volatile bool thread_done;
- volatile bool thread_request_quit;
+ SafeFlag thread_done;
+ SafeFlag thread_request_quit;
- Thread *thread;
+ Thread thread;
void _request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data);
static void _thread_func(void *p_userdata);
diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp
index ca8d5a2ca0..1661984e30 100644
--- a/scene/main/instance_placeholder.cpp
+++ b/scene/main/instance_placeholder.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h
index ec1f8a9b09..fe20fc4760 100644
--- a/scene/main/instance_placeholder.h
+++ b/scene/main/instance_placeholder.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index e2df2860ea..4c6bcb10b2 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,7 @@
#include <stdint.h>
-VARIANT_ENUM_CAST(Node::PauseMode);
+VARIANT_ENUM_CAST(Node::ProcessMode);
int Node::orphan_node_count = 0;
@@ -69,14 +69,14 @@ void Node::_notification(int p_notification) {
ERR_FAIL_COND(!get_viewport());
ERR_FAIL_COND(!get_tree());
- if (data.pause_mode == PAUSE_MODE_INHERIT) {
+ if (data.process_mode == PROCESS_MODE_INHERIT) {
if (data.parent) {
- data.pause_owner = data.parent->data.pause_owner;
+ data.process_owner = data.parent->data.process_owner;
} else {
- data.pause_owner = nullptr;
+ data.process_owner = nullptr;
}
} else {
- data.pause_owner = this;
+ data.process_owner = this;
}
if (data.input) {
@@ -110,7 +110,7 @@ void Node::_notification(int p_notification) {
remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
}
- data.pause_owner = nullptr;
+ data.process_owner = nullptr;
if (data.path_cache) {
memdelete(data.path_cache);
data.path_cache = nullptr;
@@ -367,8 +367,6 @@ void Node::set_physics_process(bool p_process) {
} else {
remove_from_group("physics_process");
}
-
- _change_notify("physics_process");
}
bool Node::is_physics_processing() const {
@@ -387,52 +385,87 @@ void Node::set_physics_process_internal(bool p_process_internal) {
} else {
remove_from_group("physics_process_internal");
}
-
- _change_notify("physics_process_internal");
}
bool Node::is_physics_processing_internal() const {
return data.physics_process_internal;
}
-void Node::set_pause_mode(PauseMode p_mode) {
- if (data.pause_mode == p_mode) {
+void Node::set_process_mode(ProcessMode p_mode) {
+ if (data.process_mode == p_mode) {
return;
}
- bool prev_inherits = data.pause_mode == PAUSE_MODE_INHERIT;
- data.pause_mode = p_mode;
if (!is_inside_tree()) {
- return; //pointless
- }
- if ((data.pause_mode == PAUSE_MODE_INHERIT) == prev_inherits) {
- return; ///nothing changed
+ data.process_mode = p_mode;
+ return;
}
- Node *owner = nullptr;
+ bool prev_can_process = can_process();
+
+ data.process_mode = p_mode;
- if (data.pause_mode == PAUSE_MODE_INHERIT) {
+ if (data.process_mode == PROCESS_MODE_INHERIT) {
if (data.parent) {
- owner = data.parent->data.pause_owner;
+ data.process_owner = data.parent->data.owner;
+ } else {
+ data.process_owner = nullptr;
}
} else {
- owner = this;
+ data.process_owner = this;
+ }
+
+ bool next_can_process = can_process();
+
+ int pause_notification = 0;
+
+ if (prev_can_process && !next_can_process) {
+ pause_notification = NOTIFICATION_PAUSED;
+ } else if (!prev_can_process && next_can_process) {
+ pause_notification = NOTIFICATION_UNPAUSED;
}
- _propagate_pause_owner(owner);
+ _propagate_process_owner(data.process_owner, pause_notification);
+#ifdef TOOLS_ENABLED
+ // This is required for the editor to update the visibility of disabled nodes
+ // Its very expensive during runtime to change, so editor-only
+ if (Engine::get_singleton()->is_editor_hint()) {
+ get_tree()->emit_signal("tree_process_mode_changed");
+ }
+#endif
}
-Node::PauseMode Node::get_pause_mode() const {
- return data.pause_mode;
+void Node::_propagate_pause_notification(bool p_enable) {
+ bool prev_can_process = _can_process(!p_enable);
+ bool next_can_process = _can_process(p_enable);
+
+ if (prev_can_process && !next_can_process) {
+ notification(NOTIFICATION_PAUSED);
+ } else if (!prev_can_process && next_can_process) {
+ notification(NOTIFICATION_UNPAUSED);
+ }
+
+ for (int i = 0; i < data.children.size(); i++) {
+ data.children[i]->_propagate_pause_notification(p_enable);
+ }
}
-void Node::_propagate_pause_owner(Node *p_owner) {
- if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT) {
- return;
+Node::ProcessMode Node::get_process_mode() const {
+ return data.process_mode;
+}
+
+void Node::_propagate_process_owner(Node *p_owner, int p_notification) {
+ data.process_owner = p_owner;
+
+ if (p_notification != 0) {
+ notification(p_notification);
}
- data.pause_owner = p_owner;
+
for (int i = 0; i < data.children.size(); i++) {
- data.children[i]->_propagate_pause_owner(p_owner);
+ Node *c = data.children[i];
+ if (c->data.process_mode == PROCESS_MODE_INHERIT) {
+ c->_propagate_process_owner(p_owner, p_notification);
+ }
}
}
@@ -466,7 +499,7 @@ uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_
nd.name = p_method;
nd.mode = p_mode;
data.rpc_methods.push_back(nd);
- return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15);
+ return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15);
} else {
int c_mid = (~(1 << 15)) & mid;
data.rpc_methods.write[c_mid].mode = p_mode;
@@ -555,7 +588,7 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallEr
return Variant();
}
- if (p_args[0]->get_type() != Variant::STRING) {
+ if (p_args[0]->get_type() != Variant::STRING_NAME) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -584,7 +617,7 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal
return Variant();
}
- if (p_args[1]->get_type() != Variant::STRING) {
+ if (p_args[1]->get_type() != Variant::STRING_NAME) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
@@ -607,7 +640,7 @@ Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Calla
return Variant();
}
- if (p_args[0]->get_type() != Variant::STRING) {
+ if (p_args[0]->get_type() != Variant::STRING_NAME) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -636,7 +669,7 @@ Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Ca
return Variant();
}
- if (p_args[1]->get_type() != Variant::STRING) {
+ if (p_args[1]->get_type() != Variant::STRING_NAME) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
@@ -797,9 +830,9 @@ bool Node::can_process_notification(int p_what) const {
case NOTIFICATION_PHYSICS_PROCESS:
return data.physics_process;
case NOTIFICATION_PROCESS:
- return data.idle_process;
+ return data.process;
case NOTIFICATION_INTERNAL_PROCESS:
- return data.idle_process_internal;
+ return data.process_internal;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS:
return data.physics_process_internal;
}
@@ -809,30 +842,33 @@ bool Node::can_process_notification(int p_what) const {
bool Node::can_process() const {
ERR_FAIL_COND_V(!is_inside_tree(), false);
+ return _can_process(get_tree()->is_paused());
+}
- if (get_tree()->is_paused()) {
- if (data.pause_mode == PAUSE_MODE_STOP) {
- return false;
- }
- if (data.pause_mode == PAUSE_MODE_PROCESS) {
- return true;
- }
- if (data.pause_mode == PAUSE_MODE_INHERIT) {
- if (!data.pause_owner) {
- return false; //clearly no pause owner by default
- }
-
- if (data.pause_owner->data.pause_mode == PAUSE_MODE_PROCESS) {
- return true;
- }
+bool Node::_can_process(bool p_paused) const {
+ ProcessMode process_mode;
- if (data.pause_owner->data.pause_mode == PAUSE_MODE_STOP) {
- return false;
- }
+ if (data.process_mode == PROCESS_MODE_INHERIT) {
+ if (!data.process_owner) {
+ process_mode = PROCESS_MODE_PAUSABLE;
+ } else {
+ process_mode = data.process_owner->data.process_mode;
}
+ } else {
+ process_mode = data.process_mode;
}
- return true;
+ if (process_mode == PROCESS_MODE_DISABLED) {
+ return false;
+ } else if (process_mode == PROCESS_MODE_ALWAYS) {
+ return true;
+ }
+
+ if (p_paused) {
+ return process_mode == PROCESS_MODE_WHEN_PAUSED;
+ } else {
+ return process_mode == PROCESS_MODE_PAUSABLE;
+ }
}
float Node::get_physics_process_delta_time() const {
@@ -845,50 +881,46 @@ float Node::get_physics_process_delta_time() const {
float Node::get_process_delta_time() const {
if (data.tree) {
- return data.tree->get_idle_process_time();
+ return data.tree->get_process_time();
} else {
return 0;
}
}
-void Node::set_process(bool p_idle_process) {
- if (data.idle_process == p_idle_process) {
+void Node::set_process(bool p_process) {
+ if (data.process == p_process) {
return;
}
- data.idle_process = p_idle_process;
+ data.process = p_process;
- if (data.idle_process) {
- add_to_group("idle_process", false);
+ if (data.process) {
+ add_to_group("process", false);
} else {
- remove_from_group("idle_process");
+ remove_from_group("process");
}
-
- _change_notify("idle_process");
}
bool Node::is_processing() const {
- return data.idle_process;
+ return data.process;
}
-void Node::set_process_internal(bool p_idle_process_internal) {
- if (data.idle_process_internal == p_idle_process_internal) {
+void Node::set_process_internal(bool p_process_internal) {
+ if (data.process_internal == p_process_internal) {
return;
}
- data.idle_process_internal = p_idle_process_internal;
+ data.process_internal = p_process_internal;
- if (data.idle_process_internal) {
- add_to_group("idle_process_internal", false);
+ if (data.process_internal) {
+ add_to_group("process_internal", false);
} else {
- remove_from_group("idle_process_internal");
+ remove_from_group("process_internal");
}
-
- _change_notify("idle_process_internal");
}
bool Node::is_processing_internal() const {
- return data.idle_process_internal;
+ return data.process_internal;
}
void Node::set_process_priority(int p_priority) {
@@ -900,11 +932,11 @@ void Node::set_process_priority(int p_priority) {
}
if (is_processing()) {
- data.tree->make_group_changed("idle_process");
+ data.tree->make_group_changed("process");
}
if (is_processing_internal()) {
- data.tree->make_group_changed("idle_process_internal");
+ data.tree->make_group_changed("process_internal");
}
if (is_physics_processing()) {
@@ -989,22 +1021,8 @@ void Node::_set_name_nocheck(const StringName &p_name) {
data.name = p_name;
}
-String Node::invalid_character = ". : @ / \"";
-
-bool Node::_validate_node_name(String &p_name) {
- String name = p_name;
- Vector<String> chars = Node::invalid_character.split(" ");
- for (int i = 0; i < chars.size(); i++) {
- name = name.replace(chars[i], "");
- }
- bool is_valid = name == p_name;
- p_name = name;
- return is_valid;
-}
-
void Node::set_name(const String &p_name) {
- String name = p_name;
- _validate_node_name(name);
+ String name = p_name.validate_node_name();
ERR_FAIL_COND(name == "");
data.name = name;
@@ -1116,7 +1134,7 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co
name = p_child->get_class();
// Adjust casing according to project setting. The current type name is expected to be in PascalCase.
- switch (ProjectSettings::get_singleton()->get("node/name_casing").operator int()) {
+ switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_casing").operator int()) {
case NAME_CASING_PASCAL_CASE:
break;
case NAME_CASING_CAMEL_CASE: {
@@ -1410,7 +1428,15 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
Node *Node::get_node(const NodePath &p_path) const {
Node *node = get_node_or_null(p_path);
- ERR_FAIL_COND_V_MSG(!node, nullptr, "Node not found: " + p_path + ".");
+
+ if (p_path.is_absolute()) {
+ ERR_FAIL_COND_V_MSG(!node, nullptr,
+ vformat(R"(Node not found: "%s" (absolute path attempted from "%s").)", p_path, get_path()));
+ } else {
+ ERR_FAIL_COND_V_MSG(!node, nullptr,
+ vformat(R"(Node not found: "%s" (relative to "%s").)", p_path, get_path()));
+ }
+
return node;
}
@@ -1887,7 +1913,7 @@ void Node::remove_and_skip() {
}
}
- while (!children.empty()) {
+ while (!children.is_empty()) {
Node *c_node = children.front()->get();
data.parent->add_child(c_node);
c_node->_propagate_replace_owner(nullptr, new_owner);
@@ -1906,46 +1932,49 @@ String Node::get_filename() const {
}
void Node::set_editor_description(const String &p_editor_description) {
- set_meta("_editor_description_", p_editor_description);
+ data.editor_description = p_editor_description;
}
String Node::get_editor_description() const {
- if (has_meta("_editor_description_")) {
- return get_meta("_editor_description_");
- } else {
- return "";
- }
+ return data.editor_description;
}
void Node::set_editable_instance(Node *p_node, bool p_editable) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_COND(!is_a_parent_of(p_node));
- NodePath p = get_path_to(p_node);
if (!p_editable) {
- data.editable_instances.erase(p);
+ p_node->data.editable_instance = false;
// Avoid this flag being needlessly saved;
// also give more visual feedback if editable children is re-enabled
set_display_folded(false);
} else {
- data.editable_instances[p] = true;
+ p_node->data.editable_instance = true;
}
}
bool Node::is_editable_instance(const Node *p_node) const {
if (!p_node) {
- return false; //easier, null is never editable :)
+ return false; // Easier, null is never editable. :)
}
ERR_FAIL_COND_V(!is_a_parent_of(p_node), false);
- NodePath p = get_path_to(p_node);
- return data.editable_instances.has(p);
+ return p_node->data.editable_instance;
}
-void Node::set_editable_instances(const HashMap<NodePath, int> &p_editable_instances) {
- data.editable_instances = p_editable_instances;
-}
+Node *Node::get_deepest_editable_node(Node *p_start_node) const {
+ ERR_FAIL_NULL_V(p_start_node, nullptr);
+ ERR_FAIL_COND_V(!is_a_parent_of(p_start_node), p_start_node);
+
+ Node const *iterated_item = p_start_node;
+ Node *node = p_start_node;
+
+ while (iterated_item->get_owner() && iterated_item->get_owner() != this) {
+ if (!is_editable_instance(iterated_item->get_owner()))
+ node = iterated_item->get_owner();
+
+ iterated_item = iterated_item->get_owner();
+ }
-HashMap<NodePath, int> Node::get_editable_instances() const {
- return data.editable_instances;
+ return node;
}
void Node::set_scene_instance_state(const Ref<SceneState> &p_state) {
@@ -2009,6 +2038,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
if (get_filename() != "") { //an instance
node->set_filename(get_filename());
+ node->data.editable_instance = data.editable_instance;
}
StringName script_property_name = CoreStringNames::get_singleton()->_script;
@@ -2021,19 +2051,26 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
// Since nodes in the instanced hierarchy won't be duplicated explicitly, we need to make an inventory
// of all the nodes in the tree of the instanced scene in order to transfer the values of the properties
+ Vector<const Node *> instance_roots;
+ instance_roots.push_back(this);
+
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
for (int i = 0; i < N->get()->get_child_count(); ++i) {
Node *descendant = N->get()->get_child(i);
// Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later
// but remember non-instanced nodes that are hidden below instanced ones
- if (descendant->data.owner != this) {
- if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent()) {
+ if (!instance_roots.has(descendant->get_owner())) {
+ if (descendant->get_parent() && descendant->get_parent() != this && descendant->data.owner != descendant->get_parent()) {
hidden_roots.push_back(descendant);
}
continue;
}
node_tree.push_back(descendant);
+
+ if (descendant->get_filename() != "" && instance_roots.has(descendant->get_owner())) {
+ instance_roots.push_back(descendant);
+ }
}
}
}
@@ -2156,8 +2193,17 @@ Node *Node::duplicate(int p_flags) const {
#ifdef TOOLS_ENABLED
Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const {
+ return duplicate_from_editor(r_duplimap, Map<RES, RES>());
+}
+
+Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const {
Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap);
+ // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated.
+ if (!p_resource_remap.is_empty()) {
+ remap_node_resources(dupe, p_resource_remap);
+ }
+
// Duplication of signals must happen after all the node descendants have been copied,
// because re-targeting of connections from some descendant to another is not possible
// if the emitter node comes later in tree order than the receiver
@@ -2165,75 +2211,55 @@ Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const {
return dupe;
}
-#endif
-void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const {
- if (get_owner() != get_parent()->get_owner()) {
- return;
- }
+void Node::remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const {
+ List<PropertyInfo> props;
+ p_node->get_property_list(&props);
- Node *node = nullptr;
-
- if (get_filename() != "") {
- Ref<PackedScene> res = ResourceLoader::load(get_filename());
- ERR_FAIL_COND_MSG(res.is_null(), "Cannot load scene: " + get_filename());
- node = res->instance();
- ERR_FAIL_COND(!node);
- } else {
- Object *obj = ClassDB::instance(get_class());
- ERR_FAIL_COND_MSG(!obj, "Node: Could not duplicate: " + String(get_class()) + ".");
- node = Object::cast_to<Node>(obj);
- if (!node) {
- memdelete(obj);
- ERR_FAIL_MSG("Node: Could not duplicate: " + String(get_class()) + ".");
- }
- }
-
- List<PropertyInfo> plist;
-
- get_property_list(&plist);
-
- for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
}
- String name = E->get().name;
- Variant value = get(name).duplicate(true);
-
- node->set(name, value);
+ Variant v = p_node->get(E->get().name);
+ if (v.is_ref()) {
+ RES res = v;
+ if (res.is_valid()) {
+ if (p_resource_remap.has(res)) {
+ p_node->set(E->get().name, p_resource_remap[res]);
+ remap_nested_resources(res, p_resource_remap);
+ }
+ }
+ }
}
- List<GroupInfo> groups;
- get_groups(&groups);
-
- for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
- node->add_to_group(E->get().name, E->get().persistent);
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ remap_node_resources(p_node->get_child(i), p_resource_remap);
}
+}
- node->set_name(get_name());
- p_new_parent->add_child(node);
-
- Node *owner = get_owner();
+void Node::remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const {
+ List<PropertyInfo> props;
+ p_resource->get_property_list(&props);
- if (p_reown_map.has(owner)) {
- owner = p_reown_map[owner];
- }
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
+ continue;
+ }
- if (owner) {
- NodePath p = get_path_to(owner);
- if (owner != this) {
- Node *new_owner = node->get_node(p);
- if (new_owner) {
- node->set_owner(new_owner);
+ Variant v = p_resource->get(E->get().name);
+ if (v.is_ref()) {
+ RES res = v;
+ if (res.is_valid()) {
+ if (p_resource_remap.has(res)) {
+ p_resource->set(E->get().name, p_resource_remap[res]);
+ remap_nested_resources(res, p_resource_remap);
+ }
}
}
}
-
- for (int i = 0; i < get_child_count(); i++) {
- get_child(i)->_duplicate_and_reown(node, p_reown_map);
- }
}
+#endif
// Duplication of signals must happen after all the node descendants have been copied,
// because re-targeting of connections from some descendant to another is not possible
@@ -2245,7 +2271,7 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const {
List<const Node *> process_list;
process_list.push_back(this);
- while (!process_list.empty()) {
+ while (!process_list.is_empty()) {
const Node *n = process_list.front()->get();
process_list.pop_front();
@@ -2289,49 +2315,6 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const {
}
}
-Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const {
- ERR_FAIL_COND_V(get_filename() != "", nullptr);
-
- Object *obj = ClassDB::instance(get_class());
- ERR_FAIL_COND_V_MSG(!obj, nullptr, "Node: Could not duplicate: " + String(get_class()) + ".");
-
- Node *node = Object::cast_to<Node>(obj);
- if (!node) {
- memdelete(obj);
- ERR_FAIL_V_MSG(nullptr, "Node: Could not duplicate: " + String(get_class()) + ".");
- }
- node->set_name(get_name());
-
- List<PropertyInfo> plist;
-
- get_property_list(&plist);
-
- for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
- continue;
- }
- String name = E->get().name;
- node->set(name, get(name));
- }
-
- List<GroupInfo> groups;
- get_groups(&groups);
-
- for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
- node->add_to_group(E->get().name, E->get().persistent);
- }
-
- for (int i = 0; i < get_child_count(); i++) {
- get_child(i)->_duplicate_and_reown(node, p_reown_map);
- }
-
- // Duplication of signals must happen after all the node descendants have been copied,
- // because re-targeting of connections from some descendant to another is not possible
- // if the emitter node comes later in tree order than the receiver
- _duplicate_signals(this, node);
- return node;
-}
-
static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) {
if (p_node->get_owner() == p_by) {
p_owned->push_back(p_node);
@@ -2342,12 +2325,7 @@ static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) {
}
}
-struct _NodeReplaceByPair {
- String name;
- Variant value;
-};
-
-void Node::replace_by(Node *p_node, bool p_keep_data) {
+void Node::replace_by(Node *p_node, bool p_keep_groups) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_COND(p_node->data.parent);
@@ -2355,21 +2333,7 @@ void Node::replace_by(Node *p_node, bool p_keep_data) {
List<Node *> owned_by_owner;
Node *owner = (data.owner == this) ? p_node : data.owner;
- List<_NodeReplaceByPair> replace_data;
-
- if (p_keep_data) {
- List<PropertyInfo> plist;
- get_property_list(&plist);
-
- for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
- _NodeReplaceByPair rd;
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
- continue;
- }
- rd.name = E->get().name;
- rd.value = get(rd.name);
- }
-
+ if (p_keep_groups) {
List<GroupInfo> groups;
get_groups(&groups);
@@ -2414,10 +2378,6 @@ void Node::replace_by(Node *p_node, bool p_keep_data) {
}
p_node->set_filename(get_filename());
-
- for (List<_NodeReplaceByPair>::Element *E = replace_data.front(); E; E = E->next()) {
- p_node->set(E->get().name, E->get().value);
- }
}
void Node::_replace_connections_target(Node *p_new_target) {
@@ -2709,10 +2669,10 @@ void Node::request_ready() {
}
void Node::_bind_methods() {
- GLOBAL_DEF("node/name_num_separator", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("node/name_num_separator", PropertyInfo(Variant::INT, "node/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"));
- GLOBAL_DEF("node/name_casing", NAME_CASING_PASCAL_CASE);
- ProjectSettings::get_singleton()->set_custom_property_info("node/name_casing", PropertyInfo(Variant::INT, "node/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case"));
+ GLOBAL_DEF("editor/node_naming/name_num_separator", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_num_separator", PropertyInfo(Variant::INT, "editor/node_naming/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"));
+ GLOBAL_DEF("editor/node_naming/name_casing", NAME_CASING_PASCAL_CASE);
+ ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_casing", PropertyInfo(Variant::INT, "editor/node_naming/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case"));
ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "legible_unique_name"), &Node::add_sibling, DEFVAL(false));
@@ -2767,8 +2727,8 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_processing_unhandled_input"), &Node::is_processing_unhandled_input);
ClassDB::bind_method(D_METHOD("set_process_unhandled_key_input", "enable"), &Node::set_process_unhandled_key_input);
ClassDB::bind_method(D_METHOD("is_processing_unhandled_key_input"), &Node::is_processing_unhandled_key_input);
- ClassDB::bind_method(D_METHOD("set_pause_mode", "mode"), &Node::set_pause_mode);
- ClassDB::bind_method(D_METHOD("get_pause_mode"), &Node::get_pause_mode);
+ ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Node::set_process_mode);
+ ClassDB::bind_method(D_METHOD("get_process_mode"), &Node::get_process_mode);
ClassDB::bind_method(D_METHOD("can_process"), &Node::can_process);
ClassDB::bind_method(D_METHOD("print_stray_nodes"), &Node::_print_stray_nodes);
@@ -2784,7 +2744,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree);
ClassDB::bind_method(D_METHOD("duplicate", "flags"), &Node::duplicate, DEFVAL(DUPLICATE_USE_INSTANCING | DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS));
- ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_data"), &Node::replace_by, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("replace_by", "node", "keep_groups"), &Node::replace_by, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder);
ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder);
@@ -2806,12 +2766,12 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("rpc_config", "method", "mode"), &Node::rpc_config);
ClassDB::bind_method(D_METHOD("rset_config", "property", "mode"), &Node::rset_config);
- ClassDB::bind_method(D_METHOD("_set_editor_description", "editor_description"), &Node::set_editor_description);
- ClassDB::bind_method(D_METHOD("_get_editor_description"), &Node::get_editor_description);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_editor_description", "_get_editor_description");
+ ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description);
+ ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description);
ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path);
ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path);
+
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path");
{
@@ -2875,9 +2835,11 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT);
BIND_CONSTANT(NOTIFICATION_TEXT_SERVER_CHANGED);
- BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT);
- BIND_ENUM_CONSTANT(PAUSE_MODE_STOP);
- BIND_ENUM_CONSTANT(PAUSE_MODE_PROCESS);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_INHERIT);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_PAUSABLE);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_WHEN_PAUSED);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_ALWAYS);
+ BIND_ENUM_CONSTANT(PROCESS_MODE_DISABLED);
BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS);
BIND_ENUM_CONSTANT(DUPLICATE_GROUPS);
@@ -2890,15 +2852,19 @@ void Node::_bind_methods() {
ADD_SIGNAL(MethodInfo("tree_exiting"));
ADD_SIGNAL(MethodInfo("tree_exited"));
- ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode");
-
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer");
+
+ ADD_GROUP("Process", "process_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,WhenPaused,Always,Disabled"), "set_process_mode", "get_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority");
+ ADD_GROUP("Editor Description", "editor_");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "set_editor_description", "get_editor_description");
+
BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::FLOAT, "delta")));
BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::FLOAT, "delta")));
BIND_VMETHOD(MethodInfo("_enter_tree"));
@@ -2911,7 +2877,7 @@ void Node::_bind_methods() {
}
String Node::_get_name_num_separator() {
- switch (ProjectSettings::get_singleton()->get("node/name_num_separator").operator int()) {
+ switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_num_separator").operator int()) {
case 0:
return "";
case 1:
diff --git a/scene/main/node.h b/scene/main/node.h
index 5c178d401c..b1e51d2aee 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,10 +46,12 @@ class Node : public Object {
OBJ_CATEGORY("Nodes");
public:
- enum PauseMode {
- PAUSE_MODE_INHERIT,
- PAUSE_MODE_STOP,
- PAUSE_MODE_PROCESS
+ enum ProcessMode {
+ PROCESS_MODE_INHERIT, // same as parent node
+ PROCESS_MODE_PAUSABLE, // process only if not paused
+ PROCESS_MODE_WHEN_PAUSED, // process only if paused
+ PROCESS_MODE_ALWAYS, // process always
+ PROCESS_MODE_DISABLED, // never process
};
enum DuplicateFlags {
@@ -80,7 +82,7 @@ private:
struct NetData {
StringName name;
- MultiplayerAPI::RPCMode mode;
+ MultiplayerAPI::RPCMode mode = MultiplayerAPI::RPCMode::RPC_MODE_DISABLED;
};
struct Data {
@@ -88,8 +90,6 @@ private:
Ref<SceneState> instance_state;
Ref<SceneState> inherited_state;
- HashMap<NodePath, int> editable_instances;
-
Node *parent = nullptr;
Node *owner = nullptr;
Vector<Node *> children;
@@ -104,6 +104,7 @@ private:
#ifdef TOOLS_ENABLED
NodePath import_path; // Path used when imported, used by scene editors to keep tracking.
#endif
+ String editor_description;
Viewport *viewport = nullptr;
@@ -111,8 +112,8 @@ private:
List<Node *>::Element *OW = nullptr; // Owned element.
List<Node *> owned;
- PauseMode pause_mode = PAUSE_MODE_INHERIT;
- Node *pause_owner = nullptr;
+ ProcessMode process_mode = PROCESS_MODE_INHERIT;
+ Node *process_owner = nullptr;
int network_master = 1; // Server by default.
Vector<NetData> rpc_methods;
@@ -121,11 +122,11 @@ private:
// Variables used to properly sort the node when processing, ignored otherwise.
// TODO: Should move all the stuff below to bits.
bool physics_process = false;
- bool idle_process = false;
+ bool process = false;
int process_priority = 0;
bool physics_process_internal = false;
- bool idle_process_internal = false;
+ bool process_internal = false;
bool input = false;
bool unhandled_input = false;
@@ -136,6 +137,7 @@ private:
bool use_placeholder = false;
bool display_folded = false;
+ bool editable_instance = false;
mutable NodePath *path_cache = nullptr;
@@ -167,11 +169,10 @@ private:
void _propagate_after_exit_tree();
void _propagate_validate_owner();
void _print_stray_nodes();
- void _propagate_pause_owner(Node *p_owner);
+ void _propagate_process_owner(Node *p_owner, int p_notification);
Array _get_node_and_resource(const NodePath &p_path);
void _duplicate_signals(const Node *p_original, Node *p_copy) const;
- void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const;
Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = nullptr) const;
TypedArray<Node> _get_children() const;
@@ -185,12 +186,9 @@ private:
friend class SceneTree;
void _set_tree(SceneTree *p_tree);
+ void _propagate_pause_notification(bool p_enable);
-#ifdef TOOLS_ENABLED
- friend class SceneTreeEditor;
-#endif
- static String invalid_character;
- static bool _validate_node_name(String &p_name);
+ _FORCE_INLINE_ bool _can_process(bool p_paused) const;
protected:
void _block() { data.blocked++; }
@@ -298,7 +296,7 @@ public:
struct GroupInfo {
StringName name;
- bool persistent;
+ bool persistent = false;
};
void get_groups(List<GroupInfo> *p_groups) const;
@@ -325,8 +323,7 @@ public:
void set_editable_instance(Node *p_node, bool p_editable);
bool is_editable_instance(const Node *p_node) const;
- void set_editable_instances(const HashMap<NodePath, int> &p_editable_instances);
- HashMap<NodePath, int> get_editable_instances() const;
+ Node *get_deepest_editable_node(Node *p_start_node) const;
/* NOTIFICATIONS */
@@ -339,14 +336,14 @@ public:
float get_physics_process_delta_time() const;
bool is_physics_processing() const;
- void set_process(bool p_idle_process);
+ void set_process(bool p_process);
float get_process_delta_time() const;
bool is_processing() const;
void set_physics_process_internal(bool p_process_internal);
bool is_physics_processing_internal() const;
- void set_process_internal(bool p_idle_process_internal);
+ void set_process_internal(bool p_process_internal);
bool is_processing_internal() const;
void set_process_priority(int p_priority);
@@ -362,9 +359,11 @@ public:
bool is_processing_unhandled_key_input() const;
Node *duplicate(int p_flags = DUPLICATE_GROUPS | DUPLICATE_SIGNALS | DUPLICATE_SCRIPTS) const;
- Node *duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const;
#ifdef TOOLS_ENABLED
Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const;
+ Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap, const Map<RES, RES> &p_resource_remap) const;
+ void remap_node_resources(Node *p_node, const Map<RES, RES> &p_resource_remap) const;
+ void remap_nested_resources(RES p_resource, const Map<RES, RES> &p_resource_remap) const;
#endif
// used by editors, to save what has changed only
@@ -381,8 +380,8 @@ public:
void replace_by(Node *p_node, bool p_keep_data = false);
- void set_pause_mode(PauseMode p_mode);
- PauseMode get_pause_mode() const;
+ void set_process_mode(ProcessMode p_mode);
+ ProcessMode get_process_mode() const;
bool can_process() const;
bool can_process_notification(int p_what) const;
diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp
index c1d4435687..cd9560db61 100644
--- a/scene/main/resource_preloader.cpp
+++ b/scene/main/resource_preloader.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/main/resource_preloader.h b/scene/main/resource_preloader.h
index 580dc35a57..1b7ea3fb9f 100644
--- a/scene/main/resource_preloader.h
+++ b/scene/main/resource_preloader.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 5cf3cbd382..9aaddfd373 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,6 +54,7 @@
#include "window.h"
#include <stdio.h>
+#include <stdlib.h>
void SceneTreeTimer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_time_left", "time"), &SceneTreeTimer::set_time_left);
@@ -72,12 +73,12 @@ float SceneTreeTimer::get_time_left() const {
return time_left;
}
-void SceneTreeTimer::set_pause_mode_process(bool p_pause_mode_process) {
- process_pause = p_pause_mode_process;
+void SceneTreeTimer::set_process_always(bool p_process_always) {
+ process_always = p_process_always;
}
-bool SceneTreeTimer::is_pause_mode_process() {
- return process_pause;
+bool SceneTreeTimer::is_process_always() {
+ return process_always;
}
void SceneTreeTimer::release_connections() {
@@ -90,10 +91,7 @@ void SceneTreeTimer::release_connections() {
}
}
-SceneTreeTimer::SceneTreeTimer() {
- time_left = 0;
- process_pause = true;
-}
+SceneTreeTimer::SceneTreeTimer() {}
void SceneTree::tree_changed() {
tree_version++;
@@ -136,7 +134,7 @@ void SceneTree::remove_from_group(const StringName &p_group, Node *p_node) {
ERR_FAIL_COND(!E);
E->get().nodes.erase(p_node);
- if (E->get().nodes.empty()) {
+ if (E->get().nodes.is_empty()) {
group_map.erase(E);
}
}
@@ -183,7 +181,7 @@ void SceneTree::_update_group_order(Group &g, bool p_use_priority) {
if (!g.changed) {
return;
}
- if (g.nodes.empty()) {
+ if (g.nodes.is_empty()) {
return;
}
@@ -206,7 +204,7 @@ void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_grou
return;
}
Group &g = E->get();
- if (g.nodes.empty()) {
+ if (g.nodes.is_empty()) {
return;
}
@@ -282,7 +280,7 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr
return;
}
Group &g = E->get();
- if (g.nodes.empty()) {
+ if (g.nodes.is_empty()) {
return;
}
@@ -333,7 +331,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group
return;
}
Group &g = E->get();
- if (g.nodes.empty()) {
+ if (g.nodes.is_empty()) {
return;
}
@@ -390,25 +388,26 @@ void SceneTree::set_group(const StringName &p_group, const String &p_name, const
set_group_flags(0, p_group, p_name, p_value);
}
-void SceneTree::init() {
+void SceneTree::initialize() {
initialized = true;
root->_set_tree(this);
- MainLoop::init();
+ MainLoop::initialize();
}
-bool SceneTree::iteration(float p_time) {
+bool SceneTree::physics_process(float p_time) {
root_lock++;
current_frame++;
flush_transform_notifications();
- MainLoop::iteration(p_time);
+ MainLoop::physics_process(p_time);
physics_process_time = p_time;
emit_signal("physics_frame");
_notify_group_pause("physics_process_internal", Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
+ call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_process_picking");
_notify_group_pause("physics_process", Node::NOTIFICATION_PHYSICS_PROCESS);
_flush_ugc();
MessageQueue::get_singleton()->flush(); //small little hack
@@ -422,29 +421,25 @@ bool SceneTree::iteration(float p_time) {
return _quit;
}
-bool SceneTree::idle(float p_time) {
- //print_line("ram: "+itos(OS::get_singleton()->get_static_memory_usage())+" sram: "+itos(OS::get_singleton()->get_dynamic_memory_usage()));
- //print_line("node count: "+itos(get_node_count()));
- //print_line("TEXTURE RAM: "+itos(RS::get_singleton()->get_render_info(RS::INFO_TEXTURE_MEM_USED)));
-
+bool SceneTree::process(float p_time) {
root_lock++;
- MainLoop::idle(p_time);
+ MainLoop::process(p_time);
- idle_process_time = p_time;
+ process_time = p_time;
if (multiplayer_poll) {
multiplayer->poll();
}
- emit_signal("idle_frame");
+ emit_signal("process_frame");
MessageQueue::get_singleton()->flush(); //small little hack
flush_transform_notifications();
- _notify_group_pause("idle_process_internal", Node::NOTIFICATION_INTERNAL_PROCESS);
- _notify_group_pause("idle_process", Node::NOTIFICATION_PROCESS);
+ _notify_group_pause("process_internal", Node::NOTIFICATION_INTERNAL_PROCESS);
+ _notify_group_pause("process", Node::NOTIFICATION_PROCESS);
_flush_ugc();
MessageQueue::get_singleton()->flush(); //small little hack
@@ -461,7 +456,7 @@ bool SceneTree::idle(float p_time) {
for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) {
List<Ref<SceneTreeTimer>>::Element *N = E->next();
- if (pause && !E->get()->is_pause_mode_process()) {
+ if (paused && !E->get()->is_process_always()) {
if (E == L) {
break; //break on last, so if new timers were added during list traversal, ignore them.
}
@@ -490,7 +485,7 @@ bool SceneTree::idle(float p_time) {
if (Engine::get_singleton()->is_editor_hint()) {
//simple hack to reload fallback environment if it changed from editor
- String env_path = ProjectSettings::get_singleton()->get("rendering/environment/default_environment");
+ String env_path = ProjectSettings::get_singleton()->get("rendering/environment/defaults/default_environment");
env_path = env_path.strip_edges(); //user may have added a space or two
String cpath;
Ref<Environment> fallback = get_root()->get_world_3d()->get_fallback_environment();
@@ -502,7 +497,7 @@ bool SceneTree::idle(float p_time) {
fallback = ResourceLoader::load(env_path);
if (fallback.is_null()) {
//could not load fallback, set as empty
- ProjectSettings::get_singleton()->set("rendering/environment/default_environment", "");
+ ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", "");
}
} else {
fallback.unref();
@@ -516,14 +511,14 @@ bool SceneTree::idle(float p_time) {
return _quit;
}
-void SceneTree::finish() {
+void SceneTree::finalize() {
_flush_delete_queue();
_flush_ugc();
initialized = false;
- MainLoop::finish();
+ MainLoop::finalize();
if (root) {
root->_set_tree(nullptr);
@@ -540,12 +535,7 @@ void SceneTree::finish() {
}
void SceneTree::quit(int p_exit_code) {
- if (p_exit_code >= 0) {
- // Override the exit code if a positive argument is given (the default is `-1`).
- // This is a shorthand for calling `set_exit_code()` on the OS singleton then quitting.
- OS::get_singleton()->set_exit_code(p_exit_code);
- }
-
+ OS::get_singleton()->set_exit_code(p_exit_code);
_quit = true;
}
@@ -765,20 +755,20 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() {
}
void SceneTree::set_pause(bool p_enabled) {
- if (p_enabled == pause) {
+ if (p_enabled == paused) {
return;
}
- pause = p_enabled;
+ paused = p_enabled;
NavigationServer3D::get_singleton()->set_active(!p_enabled);
PhysicsServer3D::get_singleton()->set_active(!p_enabled);
PhysicsServer2D::get_singleton()->set_active(!p_enabled);
if (get_root()) {
- get_root()->propagate_notification(p_enabled ? Node::NOTIFICATION_PAUSED : Node::NOTIFICATION_UNPAUSED);
+ get_root()->_propagate_pause_notification(p_enabled);
}
}
bool SceneTree::is_paused() const {
- return pause;
+ return paused;
}
void SceneTree::_notify_group_pause(const StringName &p_group, int p_notification) {
@@ -787,7 +777,7 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
return;
}
Group &g = E->get();
- if (g.nodes.empty()) {
+ if (g.nodes.is_empty()) {
return;
}
@@ -840,7 +830,7 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
return;
}
Group &g = E->get();
- if (g.nodes.empty()) {
+ if (g.nodes.is_empty()) {
return;
}
@@ -962,6 +952,21 @@ bool SceneTree::has_group(const StringName &p_identifier) const {
return group_map.has(p_identifier);
}
+Node *SceneTree::get_first_node_in_group(const StringName &p_group) {
+ Map<StringName, Group>::Element *E = group_map.find(p_group);
+ if (!E) {
+ return nullptr; //no group
+ }
+
+ _update_group_order(E->get()); //update order just in case
+
+ if (E->get().nodes.size() == 0) {
+ return nullptr;
+ }
+
+ return E->get().nodes[0];
+}
+
void SceneTree::get_nodes_in_group(const StringName &p_group, List<Node *> *p_list) {
Map<StringName, Group>::Element *E = group_map.find(p_group);
if (!E) {
@@ -1076,10 +1081,10 @@ void SceneTree::add_current_scene(Node *p_current) {
root->add_child(p_current);
}
-Ref<SceneTreeTimer> SceneTree::create_timer(float p_delay_sec, bool p_process_pause) {
+Ref<SceneTreeTimer> SceneTree::create_timer(float p_delay_sec, bool p_process_always) {
Ref<SceneTreeTimer> stt;
stt.instance();
- stt->set_pause_mode_process(p_process_pause);
+ stt->set_process_always(p_process_always);
stt->set_time_left(p_delay_sec);
timers.push_back(stt);
return stt;
@@ -1192,11 +1197,11 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pause", "enable"), &SceneTree::set_pause);
ClassDB::bind_method(D_METHOD("is_paused"), &SceneTree::is_paused);
- ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "pause_mode_process"), &SceneTree::create_timer, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("create_timer", "time_sec", "process_always"), &SceneTree::create_timer, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_node_count"), &SceneTree::get_node_count);
ClassDB::bind_method(D_METHOD("get_frame"), &SceneTree::get_frame);
- ClassDB::bind_method(D_METHOD("quit", "exit_code"), &SceneTree::quit, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("quit", "exit_code"), &SceneTree::quit, DEFVAL(EXIT_SUCCESS));
ClassDB::bind_method(D_METHOD("queue_delete", "obj"), &SceneTree::queue_delete);
@@ -1222,6 +1227,7 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_group", "group", "property", "value"), &SceneTree::set_group);
ClassDB::bind_method(D_METHOD("get_nodes_in_group", "group"), &SceneTree::_get_nodes_in_group);
+ ClassDB::bind_method(D_METHOD("get_first_node_in_group", "group"), &SceneTree::get_first_node_in_group);
ClassDB::bind_method(D_METHOD("set_current_scene", "child_node"), &SceneTree::set_current_scene);
ClassDB::bind_method(D_METHOD("get_current_scene"), &SceneTree::get_current_scene);
@@ -1260,12 +1266,13 @@ void SceneTree::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multiplayer_poll"), "set_multiplayer_poll_enabled", "is_multiplayer_poll_enabled");
ADD_SIGNAL(MethodInfo("tree_changed"));
+ ADD_SIGNAL(MethodInfo("tree_process_mode_changed")); //editor only signal, but due to API hash it cant be removed in run-time
ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("node_renamed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("node_configuration_warning_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
- ADD_SIGNAL(MethodInfo("idle_frame"));
+ ADD_SIGNAL(MethodInfo("process_frame"));
ADD_SIGNAL(MethodInfo("physics_frame"));
ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "screen")));
@@ -1303,7 +1310,7 @@ void SceneTree::get_argument_options(const StringName &p_function, int p_idx, Li
List<String> directories;
directories.push_back(dir_access->get_current_dir());
- while (!directories.empty()) {
+ while (!directories.is_empty()) {
dir_access->change_dir(directories.back()->get());
directories.pop_back();
@@ -1332,13 +1339,15 @@ SceneTree::SceneTree() {
if (singleton == nullptr) {
singleton = this;
}
- debug_collisions_color = GLOBAL_DEF("debug/shapes/collision/shape_color", Color(0.0, 0.6, 0.7, 0.5));
+ debug_collisions_color = GLOBAL_DEF("debug/shapes/collision/shape_color", Color(0.0, 0.6, 0.7, 0.42));
debug_collision_contact_color = GLOBAL_DEF("debug/shapes/collision/contact_color", Color(1.0, 0.2, 0.1, 0.8));
debug_navigation_color = GLOBAL_DEF("debug/shapes/navigation/geometry_color", Color(0.1, 1.0, 0.7, 0.4));
debug_navigation_disabled_color = GLOBAL_DEF("debug/shapes/navigation/disabled_geometry_color", Color(1.0, 0.7, 0.1, 0.4));
collision_debug_contacts = GLOBAL_DEF("debug/shapes/collision/max_contacts_displayed", 10000);
ProjectSettings::get_singleton()->set_custom_property_info("debug/shapes/collision/max_contacts_displayed", PropertyInfo(Variant::INT, "debug/shapes/collision/max_contacts_displayed", PROPERTY_HINT_RANGE, "0,20000,1")); // No negative
+ GLOBAL_DEF("debug/shapes/collision/draw_2d_outlines", true);
+
// Create with mainloop.
root = memnew(Window);
@@ -1355,34 +1364,54 @@ SceneTree::SceneTree() {
root->set_as_audio_listener_2d(true);
current_scene = nullptr;
- const int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)"));
+ const int msaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/msaa", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/msaa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)"));
root->set_msaa(Viewport::MSAA(msaa_mode));
- const int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"));
+ const int ssaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/screen_space_aa", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/screen_space_aa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"));
root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));
- const bool use_debanding = GLOBAL_DEF("rendering/quality/screen_filters/use_debanding", false);
+ const bool use_debanding = GLOBAL_DEF("rendering/anti_aliasing/quality/use_debanding", false);
root->set_use_debanding(use_debanding);
- float lod_threshold = GLOBAL_DEF("rendering/quality/mesh_lod/threshold_pixels", 1.0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/mesh_lod/threshold_pixels", PropertyInfo(Variant::FLOAT, "rendering/quality/mesh_lod/threshold_pixels", PROPERTY_HINT_RANGE, "0,1024,0.1"));
+ float lod_threshold = GLOBAL_DEF("rendering/mesh_lod/lod_change/threshold_pixels", 1.0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/mesh_lod/lod_change/threshold_pixels", PropertyInfo(Variant::FLOAT, "rendering/mesh_lod/lod_change/threshold_pixels", PROPERTY_HINT_RANGE, "0,1024,0.1"));
root->set_lod_threshold(lod_threshold);
- bool snap_2d_transforms = GLOBAL_DEF("rendering/quality/2d/snap_2d_transforms_to_pixel", false);
+ bool snap_2d_transforms = GLOBAL_DEF("rendering/2d/snap/snap_2d_transforms_to_pixel", false);
root->set_snap_2d_transforms_to_pixel(snap_2d_transforms);
- bool snap_2d_vertices = GLOBAL_DEF("rendering/quality/2d/snap_2d_vertices_to_pixel", false);
+ bool snap_2d_vertices = GLOBAL_DEF("rendering/2d/snap/snap_2d_vertices_to_pixel", false);
root->set_snap_2d_vertices_to_pixel(snap_2d_vertices);
- Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/quality/2d_sdf/oversize", 1)));
+ int shadowmap_size = GLOBAL_DEF("rendering/shadows/shadow_atlas/size", 4096);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
+ GLOBAL_DEF("rendering/shadows/shadow_atlas/size.mobile", 2048);
+ bool shadowmap_16_bits = GLOBAL_DEF("rendering/shadows/shadow_atlas/16_bits", true);
+ int atlas_q0 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_0_subdiv", 2);
+ int atlas_q1 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_1_subdiv", 2);
+ int atlas_q2 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_2_subdiv", 3);
+ int atlas_q3 = GLOBAL_DEF("rendering/shadows/shadow_atlas/quadrant_3_subdiv", 4);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/shadows/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+
+ root->set_shadow_atlas_size(shadowmap_size);
+ root->set_shadow_atlas_16_bits(shadowmap_16_bits);
+ root->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
+ root->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
+ root->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
+ root->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
+
+ Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/2d/sdf/oversize", 1)));
root->set_sdf_oversize(sdf_oversize);
- Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_DEF("rendering/quality/2d_sdf/scale", 1)));
+ Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_DEF("rendering/2d/sdf/scale", 1)));
root->set_sdf_scale(sdf_scale);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/2d_sdf/oversize", PropertyInfo(Variant::INT, "rendering/quality/2d_sdf/oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%"));
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/2d_sdf/scale", PropertyInfo(Variant::INT, "rendering/quality/2d_sdf/scale", PROPERTY_HINT_ENUM, "100%,50%,25%"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/sdf/oversize", PropertyInfo(Variant::INT, "rendering/2d/sdf/oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/sdf/scale", PropertyInfo(Variant::INT, "rendering/2d/sdf/scale", PROPERTY_HINT_ENUM, "100%,50%,25%"));
{ // Load default fallback environment.
// Get possible extensions.
@@ -1396,9 +1425,9 @@ SceneTree::SceneTree() {
ext_hint += "*." + E->get();
}
// Get path.
- String env_path = GLOBAL_DEF("rendering/environment/default_environment", "");
+ String env_path = GLOBAL_DEF("rendering/environment/defaults/default_environment", "");
// Setup property.
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/defaults/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint));
env_path = env_path.strip_edges();
if (env_path != String()) {
Ref<Environment> env = ResourceLoader::load(env_path);
@@ -1407,7 +1436,7 @@ SceneTree::SceneTree() {
} else {
if (Engine::get_singleton()->is_editor_hint()) {
// File was erased, clear the field.
- ProjectSettings::get_singleton()->set("rendering/environment/default_environment", "");
+ ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", "");
} else {
// File was erased, notify user.
ERR_PRINT(RTR("Default Environment as specified in Project Settings (Rendering -> Environment -> Default Environment) could not be loaded."));
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 9cf129d959..a2f2adb8f8 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,8 +51,8 @@ class SceneDebugger;
class SceneTreeTimer : public Reference {
GDCLASS(SceneTreeTimer, Reference);
- float time_left;
- bool process_pause;
+ float time_left = 0.0;
+ bool process_always = true;
protected:
static void _bind_methods();
@@ -61,8 +61,8 @@ public:
void set_time_left(float p_time);
float get_time_left() const;
- void set_pause_mode_process(bool p_pause_mode_process);
- bool is_pause_mode_process();
+ void set_process_always(bool p_process_always);
+ bool is_process_always();
void release_connections();
@@ -80,15 +80,14 @@ public:
private:
struct Group {
Vector<Node *> nodes;
- bool changed;
- Group() { changed = false; };
+ bool changed = false;
};
Window *root = nullptr;
uint64_t tree_version = 1;
float physics_process_time = 1.0;
- float idle_process_time = 1.0;
+ float process_time = 1.0;
bool accept_quit = true;
bool quit_on_go_back = true;
@@ -96,7 +95,7 @@ private:
bool debug_collisions_hint = false;
bool debug_navigation_hint = false;
#endif
- bool pause = false;
+ bool paused = false;
int root_lock = 0;
Map<StringName, Group> group_map;
@@ -236,20 +235,20 @@ public:
void flush_transform_notifications();
- virtual void init() override;
+ virtual void initialize() override;
- virtual bool iteration(float p_time) override;
- virtual bool idle(float p_time) override;
+ virtual bool physics_process(float p_time) override;
+ virtual bool process(float p_time) override;
- virtual void finish() override;
+ virtual void finalize() override;
void set_auto_accept_quit(bool p_enable);
void set_quit_on_go_back(bool p_enable);
- void quit(int p_exit_code = -1);
+ void quit(int p_exit_code = EXIT_SUCCESS);
_FORCE_INLINE_ float get_physics_process_time() const { return physics_process_time; }
- _FORCE_INLINE_ float get_idle_process_time() const { return idle_process_time; }
+ _FORCE_INLINE_ float get_process_time() const { return process_time; }
#ifdef TOOLS_ENABLED
bool is_node_being_edited(const Node *p_node) const;
@@ -303,6 +302,7 @@ public:
void queue_delete(Object *p_object);
void get_nodes_in_group(const StringName &p_group, List<Node *> *p_list);
+ Node *get_first_node_in_group(const StringName &p_group);
bool has_group(const StringName &p_identifier) const;
//void change_scene(const String& p_path);
@@ -317,7 +317,7 @@ public:
Error change_scene_to(const Ref<PackedScene> &p_scene);
Error reload_current_scene();
- Ref<SceneTreeTimer> create_timer(float p_delay_sec, bool p_process_pause = true);
+ Ref<SceneTreeTimer> create_timer(float p_delay_sec, bool p_process_always = true);
//used by Main::start, don't use otherwise
void add_current_scene(Node *p_current);
diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp
index 432fb5b4fb..b6b2982155 100644
--- a/scene/main/shader_globals_override.cpp
+++ b/scene/main/shader_globals_override.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -264,7 +264,7 @@ String ShaderGlobalsOverride::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (!active) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene.");
@@ -277,6 +277,4 @@ void ShaderGlobalsOverride::_bind_methods() {
ClassDB::bind_method(D_METHOD("_activate"), &ShaderGlobalsOverride::_activate);
}
-ShaderGlobalsOverride::ShaderGlobalsOverride() {
- active = false;
-}
+ShaderGlobalsOverride::ShaderGlobalsOverride() {}
diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h
index fea1677ad7..8d8794d465 100644
--- a/scene/main/shader_globals_override.h
+++ b/scene/main/shader_globals_override.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,7 @@ class ShaderGlobalsOverride : public Node {
StringName *_remap(const StringName &p_name) const;
- bool active;
+ bool active = false;
mutable HashMap<StringName, Override> overrides;
mutable HashMap<StringName, StringName> param_remaps;
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index 1c6037d26e..4bc159f6aa 100644
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,7 @@ void Timer::_notification(int p_what) {
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
- if (!processing || timer_process_mode == TIMER_PROCESS_PHYSICS || !is_processing_internal()) {
+ if (!processing || timer_process_callback == TIMER_PROCESS_PHYSICS || !is_processing_internal()) {
return;
}
time_left -= get_process_delta_time();
@@ -63,7 +63,7 @@ void Timer::_notification(int p_what) {
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- if (!processing || timer_process_mode == TIMER_PROCESS_IDLE || !is_physics_processing_internal()) {
+ if (!processing || timer_process_callback == TIMER_PROCESS_IDLE || !is_physics_processing_internal()) {
return;
}
time_left -= get_physics_process_delta_time();
@@ -143,12 +143,12 @@ float Timer::get_time_left() const {
return time_left > 0 ? time_left : 0;
}
-void Timer::set_timer_process_mode(TimerProcessMode p_mode) {
- if (timer_process_mode == p_mode) {
+void Timer::set_timer_process_callback(TimerProcessCallback p_callback) {
+ if (timer_process_callback == p_callback) {
return;
}
- switch (timer_process_mode) {
+ switch (timer_process_callback) {
case TIMER_PROCESS_PHYSICS:
if (is_physics_processing_internal()) {
set_physics_process_internal(false);
@@ -162,15 +162,15 @@ void Timer::set_timer_process_mode(TimerProcessMode p_mode) {
}
break;
}
- timer_process_mode = p_mode;
+ timer_process_callback = p_callback;
}
-Timer::TimerProcessMode Timer::get_timer_process_mode() const {
- return timer_process_mode;
+Timer::TimerProcessCallback Timer::get_timer_process_callback() const {
+ return timer_process_callback;
}
void Timer::_set_process(bool p_process, bool p_force) {
- switch (timer_process_mode) {
+ switch (timer_process_callback) {
case TIMER_PROCESS_PHYSICS:
set_physics_process_internal(p_process && !paused);
break;
@@ -201,12 +201,12 @@ void Timer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_time_left"), &Timer::get_time_left);
- ClassDB::bind_method(D_METHOD("set_timer_process_mode", "mode"), &Timer::set_timer_process_mode);
- ClassDB::bind_method(D_METHOD("get_timer_process_mode"), &Timer::get_timer_process_mode);
+ ClassDB::bind_method(D_METHOD("set_timer_process_callback", "callback"), &Timer::set_timer_process_callback);
+ ClassDB::bind_method(D_METHOD("get_timer_process_callback"), &Timer::get_timer_process_callback);
ADD_SIGNAL(MethodInfo("timeout"));
- ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_timer_process_mode", "get_timer_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_timer_process_callback", "get_timer_process_callback");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wait_time", PROPERTY_HINT_EXP_RANGE, "0.001,4096,0.001,or_greater"), "set_wait_time", "get_wait_time");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "is_one_shot");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autostart"), "set_autostart", "has_autostart");
@@ -217,12 +217,4 @@ void Timer::_bind_methods() {
BIND_ENUM_CONSTANT(TIMER_PROCESS_IDLE);
}
-Timer::Timer() {
- timer_process_mode = TIMER_PROCESS_IDLE;
- autostart = false;
- wait_time = 1;
- one_shot = false;
- time_left = -1;
- processing = false;
- paused = false;
-}
+Timer::Timer() {}
diff --git a/scene/main/timer.h b/scene/main/timer.h
index 61abf04f59..3d9e21d7fc 100644
--- a/scene/main/timer.h
+++ b/scene/main/timer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,20 +36,20 @@
class Timer : public Node {
GDCLASS(Timer, Node);
- float wait_time;
- bool one_shot;
- bool autostart;
- bool processing;
- bool paused;
+ float wait_time = 1.0;
+ bool one_shot = false;
+ bool autostart = false;
+ bool processing = false;
+ bool paused = false;
- double time_left;
+ double time_left = -1.0;
protected:
void _notification(int p_what);
static void _bind_methods();
public:
- enum TimerProcessMode {
+ enum TimerProcessCallback {
TIMER_PROCESS_PHYSICS,
TIMER_PROCESS_IDLE,
};
@@ -73,15 +73,15 @@ public:
float get_time_left() const;
- void set_timer_process_mode(TimerProcessMode p_mode);
- TimerProcessMode get_timer_process_mode() const;
+ void set_timer_process_callback(TimerProcessCallback p_callback);
+ TimerProcessCallback get_timer_process_callback() const;
Timer();
private:
- TimerProcessMode timer_process_mode;
+ TimerProcessCallback timer_process_callback = TIMER_PROCESS_IDLE;
void _set_process(bool p_process, bool p_force = false);
};
-VARIANT_ENUM_CAST(Timer::TimerProcessMode);
+VARIANT_ENUM_CAST(Timer::TimerProcessCallback);
#endif // TIMER_H
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 54cd3a0054..40b85e6d7b 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -144,7 +144,6 @@ void ViewportTexture::_bind_methods() {
}
ViewportTexture::ViewportTexture() {
- vp = nullptr;
set_local_to_scene(true);
}
@@ -184,26 +183,6 @@ public:
/////////////////////////////////////
-Viewport::GUI::GUI() {
- embed_subwindows_hint = false;
- embedding_subwindows = false;
-
- dragging = false;
- mouse_focus = nullptr;
- forced_mouse_focus = false;
- mouse_click_grabber = nullptr;
- mouse_focus_mask = 0;
- key_focus = nullptr;
- mouse_over = nullptr;
- drag_mouse_over = nullptr;
-
- tooltip_control = nullptr;
- tooltip_popup = nullptr;
- tooltip_label = nullptr;
-}
-
-/////////////////////////////////////
-
void Viewport::update_worlds() {
if (!is_inside_tree()) {
return;
@@ -299,6 +278,11 @@ void Viewport::_sub_window_update(Window *p_window) {
int x = (r.size.width - title_text.get_size().x) / 2;
int y = (-title_height - title_text.get_size().y) / 2;
+ Color font_outline_color = p_window->get_theme_color("title_outline_modulate");
+ int outline_size = p_window->get_theme_constant("title_outline_size");
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ title_text.draw_outline(sw.canvas_item, r.position + Point2(x, y), outline_size, font_outline_color);
+ }
title_text.draw(sw.canvas_item, r.position + Point2(x, y), title_color);
bool hl = gui.subwindow_focused == sw.window && gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE && gui.subwindow_drag_close_inside;
@@ -468,7 +452,7 @@ void Viewport::_notification(int p_what) {
//3D
PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count());
contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create();
- RenderingServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true);
+ RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true);
RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0);
RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid());
contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create();
@@ -567,280 +551,297 @@ void Viewport::_notification(int p_what) {
int point_count = PhysicsServer3D::get_singleton()->space_get_contact_count(find_world_3d()->get_space());
RS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count);
+
+ for (int i = 0; i < point_count; i++) {
+ Transform point_transform;
+ point_transform.origin = points[i];
+ RS::get_singleton()->multimesh_instance_set_transform(contact_3d_debug_multimesh, i, point_transform);
+ }
+ }
+ } break;
+ case NOTIFICATION_WM_MOUSE_EXIT: {
+ _drop_physics_mouseover();
+
+ // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not
+ // drop the gui mouseover here, as a scrollbar may be dragged while the
+ // mouse is outside the window (without the window having lost focus).
+ // See bug #39634
+ } break;
+ case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
+ _drop_physics_mouseover();
+
+ if (gui.mouse_focus && !gui.forced_mouse_focus) {
+ _drop_mouse_focus();
}
+ } break;
+ }
+}
+
+void Viewport::_process_picking() {
+ if (!is_inside_tree()) {
+ return;
+ }
+ if (!physics_object_picking) {
+ return;
+ }
+ if (to_screen_rect != Rect2i() && Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) {
+ return;
+ }
+
+ _drop_physics_mouseover(true);
- if (physics_object_picking && (to_screen_rect == Rect2i() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) {
#ifndef _3D_DISABLED
- Vector2 last_pos(1e20, 1e20);
- CollisionObject3D *last_object = nullptr;
- ObjectID last_id;
+ Vector2 last_pos(1e20, 1e20);
+ CollisionObject3D *last_object = nullptr;
+ ObjectID last_id;
#endif
- PhysicsDirectSpaceState3D::RayResult result;
- PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
-
- if (physics_has_last_mousepos) {
- // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved.
- // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame
- bool has_mouse_event = false;
- for (List<Ref<InputEvent>>::Element *E = physics_picking_events.front(); E; E = E->next()) {
- Ref<InputEventMouse> m = E->get();
- if (m.is_valid()) {
- has_mouse_event = true;
- break;
- }
- }
+ PhysicsDirectSpaceState3D::RayResult result;
+ PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
+
+ if (physics_has_last_mousepos) {
+ // if no mouse event exists, create a motion one. This is necessary because objects or camera may have moved.
+ // while this extra event is sent, it is checked if both camera and last object and last ID did not move. If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame
+ bool has_mouse_event = false;
+ for (List<Ref<InputEvent>>::Element *E = physics_picking_events.front(); E; E = E->next()) {
+ Ref<InputEventMouse> m = E->get();
+ if (m.is_valid()) {
+ has_mouse_event = true;
+ break;
+ }
+ }
- if (!has_mouse_event) {
- Ref<InputEventMouseMotion> mm;
- mm.instance();
-
- mm->set_device(InputEvent::DEVICE_ID_INTERNAL);
- mm->set_global_position(physics_last_mousepos);
- mm->set_position(physics_last_mousepos);
- mm->set_alt(physics_last_mouse_state.alt);
- mm->set_shift(physics_last_mouse_state.shift);
- mm->set_control(physics_last_mouse_state.control);
- mm->set_metakey(physics_last_mouse_state.meta);
- mm->set_button_mask(physics_last_mouse_state.mouse_mask);
- physics_picking_events.push_back(mm);
- }
- }
+ if (!has_mouse_event) {
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
- while (physics_picking_events.size()) {
- Ref<InputEvent> ev = physics_picking_events.front()->get();
- physics_picking_events.pop_front();
+ mm->set_device(InputEvent::DEVICE_ID_INTERNAL);
+ mm->set_global_position(physics_last_mousepos);
+ mm->set_position(physics_last_mousepos);
+ mm->set_alt(physics_last_mouse_state.alt);
+ mm->set_shift(physics_last_mouse_state.shift);
+ mm->set_control(physics_last_mouse_state.control);
+ mm->set_metakey(physics_last_mouse_state.meta);
+ mm->set_button_mask(physics_last_mouse_state.mouse_mask);
+ physics_picking_events.push_back(mm);
+ }
+ }
- Vector2 pos;
- bool is_mouse = false;
+ while (physics_picking_events.size()) {
+ Ref<InputEvent> ev = physics_picking_events.front()->get();
+ physics_picking_events.pop_front();
- Ref<InputEventMouseMotion> mm = ev;
+ Vector2 pos;
+ bool is_mouse = false;
- if (mm.is_valid()) {
- pos = mm->get_position();
- is_mouse = true;
+ Ref<InputEventMouseMotion> mm = ev;
- physics_has_last_mousepos = true;
- physics_last_mousepos = pos;
- physics_last_mouse_state.alt = mm->get_alt();
- physics_last_mouse_state.shift = mm->get_shift();
- physics_last_mouse_state.control = mm->get_control();
- physics_last_mouse_state.meta = mm->get_metakey();
- physics_last_mouse_state.mouse_mask = mm->get_button_mask();
- }
+ if (mm.is_valid()) {
+ pos = mm->get_position();
+ is_mouse = true;
- Ref<InputEventMouseButton> mb = ev;
+ physics_has_last_mousepos = true;
+ physics_last_mousepos = pos;
+ physics_last_mouse_state.alt = mm->get_alt();
+ physics_last_mouse_state.shift = mm->get_shift();
+ physics_last_mouse_state.control = mm->get_control();
+ physics_last_mouse_state.meta = mm->get_metakey();
+ physics_last_mouse_state.mouse_mask = mm->get_button_mask();
+ }
- if (mb.is_valid()) {
- pos = mb->get_position();
- is_mouse = true;
+ Ref<InputEventMouseButton> mb = ev;
- physics_has_last_mousepos = true;
- physics_last_mousepos = pos;
- physics_last_mouse_state.alt = mb->get_alt();
- physics_last_mouse_state.shift = mb->get_shift();
- physics_last_mouse_state.control = mb->get_control();
- physics_last_mouse_state.meta = mb->get_metakey();
+ if (mb.is_valid()) {
+ pos = mb->get_position();
+ is_mouse = true;
- if (mb->is_pressed()) {
- physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1));
- } else {
- physics_last_mouse_state.mouse_mask &= ~(1 << (mb->get_button_index() - 1));
+ physics_has_last_mousepos = true;
+ physics_last_mousepos = pos;
+ physics_last_mouse_state.alt = mb->get_alt();
+ physics_last_mouse_state.shift = mb->get_shift();
+ physics_last_mouse_state.control = mb->get_control();
+ physics_last_mouse_state.meta = mb->get_metakey();
- // If touch mouse raised, assume we don't know last mouse pos until new events come
- if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) {
- physics_has_last_mousepos = false;
- }
- }
- }
+ if (mb->is_pressed()) {
+ physics_last_mouse_state.mouse_mask |= (1 << (mb->get_button_index() - 1));
+ } else {
+ physics_last_mouse_state.mouse_mask &= ~(1 << (mb->get_button_index() - 1));
- Ref<InputEventKey> k = ev;
- if (k.is_valid()) {
- //only for mask
- physics_last_mouse_state.alt = k->get_alt();
- physics_last_mouse_state.shift = k->get_shift();
- physics_last_mouse_state.control = k->get_control();
- physics_last_mouse_state.meta = k->get_metakey();
- continue;
- }
+ // If touch mouse raised, assume we don't know last mouse pos until new events come
+ if (mb->get_device() == InputEvent::DEVICE_ID_TOUCH_MOUSE) {
+ physics_has_last_mousepos = false;
+ }
+ }
+ }
- Ref<InputEventScreenDrag> sd = ev;
+ Ref<InputEventKey> k = ev;
+ if (k.is_valid()) {
+ //only for mask
+ physics_last_mouse_state.alt = k->get_alt();
+ physics_last_mouse_state.shift = k->get_shift();
+ physics_last_mouse_state.control = k->get_control();
+ physics_last_mouse_state.meta = k->get_metakey();
+ continue;
+ }
- if (sd.is_valid()) {
- pos = sd->get_position();
- }
+ Ref<InputEventScreenDrag> sd = ev;
- Ref<InputEventScreenTouch> st = ev;
+ if (sd.is_valid()) {
+ pos = sd->get_position();
+ }
- if (st.is_valid()) {
- pos = st->get_position();
- }
+ Ref<InputEventScreenTouch> st = ev;
- if (ss2d) {
- //send to 2D
+ if (st.is_valid()) {
+ pos = st->get_position();
+ }
- uint64_t frame = get_tree()->get_frame();
+ if (ss2d) {
+ //send to 2D
- PhysicsDirectSpaceState2D::ShapeResult res[64];
- for (Set<CanvasLayer *>::Element *E = canvas_layers.front(); E; E = E->next()) {
- Transform2D canvas_transform;
- ObjectID canvas_layer_id;
- if (E->get()) {
- // A descendant CanvasLayer
- canvas_transform = E->get()->get_transform();
- canvas_layer_id = E->get()->get_instance_id();
- } else {
- // This Viewport's builtin canvas
- canvas_transform = get_canvas_transform();
- canvas_layer_id = ObjectID();
- }
+ uint64_t frame = get_tree()->get_frame();
+
+ PhysicsDirectSpaceState2D::ShapeResult res[64];
+ for (Set<CanvasLayer *>::Element *E = canvas_layers.front(); E; E = E->next()) {
+ Transform2D canvas_transform;
+ ObjectID canvas_layer_id;
+ if (E->get()) {
+ // A descendant CanvasLayer
+ canvas_transform = E->get()->get_transform();
+ canvas_layer_id = E->get()->get_instance_id();
+ } else {
+ // This Viewport's builtin canvas
+ canvas_transform = get_canvas_transform();
+ canvas_layer_id = ObjectID();
+ }
- Vector2 point = canvas_transform.affine_inverse().xform(pos);
-
- int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true);
- for (int i = 0; i < rc; i++) {
- if (res[i].collider_id.is_valid() && res[i].collider) {
- CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
- if (co) {
- bool send_event = true;
- if (is_mouse) {
- Map<ObjectID, uint64_t>::Element *F = physics_2d_mouseover.find(res[i].collider_id);
-
- if (!F) {
- physics_2d_mouseover.insert(res[i].collider_id, frame);
- co->_mouse_enter();
- } else {
- F->get() = frame;
- // It was already hovered, so don't send the event if it's faked
- if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) {
- send_event = false;
- }
- }
- }
-
- if (send_event) {
- co->_input_event(this, ev, res[i].shape);
- }
+ Vector2 point = canvas_transform.affine_inverse().xform(pos);
+
+ int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true);
+ for (int i = 0; i < rc; i++) {
+ if (res[i].collider_id.is_valid() && res[i].collider) {
+ CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
+ if (co && co->can_process()) {
+ bool send_event = true;
+ if (is_mouse) {
+ Map<ObjectID, uint64_t>::Element *F = physics_2d_mouseover.find(res[i].collider_id);
+
+ if (!F) {
+ physics_2d_mouseover.insert(res[i].collider_id, frame);
+ co->_mouse_enter();
+ } else {
+ F->get() = frame;
+ // It was already hovered, so don't send the event if it's faked
+ if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) {
+ send_event = false;
}
}
}
- }
- if (is_mouse) {
- List<Map<ObjectID, uint64_t>::Element *> to_erase;
-
- for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) {
- if (E->get() != frame) {
- Object *o = ObjectDB::get_instance(E->key());
- if (o) {
- CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
- if (co) {
- co->_mouse_exit();
- }
- }
- to_erase.push_back(E);
- }
+ if (send_event) {
+ co->_input_event(this, ev, res[i].shape);
}
+ }
+ }
+ }
+ }
+
+ if (is_mouse) {
+ List<Map<ObjectID, uint64_t>::Element *> to_erase;
- while (to_erase.size()) {
- physics_2d_mouseover.erase(to_erase.front()->get());
- to_erase.pop_front();
+ for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) {
+ if (E->get() != frame) {
+ Object *o = ObjectDB::get_instance(E->key());
+ if (o) {
+ CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
+ if (co) {
+ co->_mouse_exit();
}
}
+ to_erase.push_back(E);
}
+ }
+
+ while (to_erase.size()) {
+ physics_2d_mouseover.erase(to_erase.front()->get());
+ to_erase.pop_front();
+ }
+ }
+ }
#ifndef _3D_DISABLED
- bool captured = false;
-
- if (physics_object_capture.is_valid()) {
- CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture));
- if (co && camera) {
- _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0);
- captured = true;
- if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
- physics_object_capture = ObjectID();
- }
+ bool captured = false;
+
+ if (physics_object_capture.is_valid()) {
+ CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture));
+ if (co && camera) {
+ _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0);
+ captured = true;
+ if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
+ physics_object_capture = ObjectID();
+ }
- } else {
- physics_object_capture = ObjectID();
+ } else {
+ physics_object_capture = ObjectID();
+ }
+ }
+
+ if (captured) {
+ //none
+ } else if (pos == last_pos) {
+ if (last_id.is_valid()) {
+ if (ObjectDB::get_instance(last_id) && last_object) {
+ //good, exists
+ _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape);
+ if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
+ physics_object_capture = last_id;
+ }
+ }
+ }
+ } else {
+ if (camera) {
+ Vector3 from = camera->project_ray_origin(pos);
+ Vector3 dir = camera->project_ray_normal(pos);
+
+ PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space());
+ if (space) {
+ bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true);
+ ObjectID new_collider;
+ if (col) {
+ CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider);
+ if (co && co->can_process()) {
+ _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape);
+ last_object = co;
+ last_id = result.collider_id;
+ new_collider = last_id;
+ if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
+ physics_object_capture = last_id;
+ }
}
}
- if (captured) {
- //none
- } else if (pos == last_pos) {
- if (last_id.is_valid()) {
- if (ObjectDB::get_instance(last_id) && last_object) {
- //good, exists
- _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape);
- if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
- physics_object_capture = last_id;
- }
+ if (is_mouse && new_collider != physics_object_over) {
+ if (physics_object_over.is_valid()) {
+ CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
+ if (co) {
+ co->_mouse_exit();
}
}
- } else {
- if (camera) {
- Vector3 from = camera->project_ray_origin(pos);
- Vector3 dir = camera->project_ray_normal(pos);
-
- PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space());
- if (space) {
- bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true);
- ObjectID new_collider;
- if (col) {
- CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider);
- if (co) {
- _collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape);
- last_object = co;
- last_id = result.collider_id;
- new_collider = last_id;
- if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
- physics_object_capture = last_id;
- }
- }
- }
- if (is_mouse && new_collider != physics_object_over) {
- if (physics_object_over.is_valid()) {
- CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
- if (co) {
- co->_mouse_exit();
- }
- }
-
- if (new_collider.is_valid()) {
- CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider));
- if (co) {
- co->_mouse_enter();
- }
- }
-
- physics_object_over = new_collider;
- }
+ if (new_collider.is_valid()) {
+ CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider));
+ if (co) {
+ co->_mouse_enter();
}
-
- last_pos = pos;
}
+
+ physics_object_over = new_collider;
}
-#endif
}
- }
-
- } break;
- case NOTIFICATION_WM_MOUSE_EXIT: {
- _drop_physics_mouseover();
-
- // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not
- // drop the gui mouseover here, as a scrollbar may be dragged while the
- // mouse is outside the window (without the window having lost focus).
- // See bug #39634
- } break;
- case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
- _drop_physics_mouseover();
- if (gui.mouse_focus && !gui.forced_mouse_focus) {
- _drop_mouse_focus();
+ last_pos = pos;
}
- } break;
+ }
+#endif
}
}
@@ -1416,18 +1417,26 @@ Ref<ViewportTexture> Viewport::get_texture() const {
}
void Viewport::set_shadow_atlas_size(int p_size) {
- if (shadow_atlas_size == p_size) {
- return;
- }
-
shadow_atlas_size = p_size;
- RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size);
+ RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size, shadow_atlas_16_bits);
}
int Viewport::get_shadow_atlas_size() const {
return shadow_atlas_size;
}
+void Viewport::set_shadow_atlas_16_bits(bool p_16_bits) {
+ if (shadow_atlas_16_bits == p_16_bits) {
+ return;
+ }
+
+ shadow_atlas_16_bits = p_16_bits;
+ RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, shadow_atlas_size, shadow_atlas_16_bits);
+}
+
+bool Viewport::get_shadow_atlas_16_bits() const {
+ return shadow_atlas_16_bits;
+}
void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv) {
ERR_FAIL_INDEX(p_quadrant, 4);
ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
@@ -1505,7 +1514,7 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont
}
// If we found a tooltip, we stop here.
- if (!tooltip.empty()) {
+ if (!tooltip.is_empty()) {
break;
}
@@ -1538,8 +1547,8 @@ void Viewport::_gui_show_tooltip() {
gui.tooltip_control,
gui.tooltip_control->get_global_transform().xform_inv(gui.last_mouse_pos),
&tooltip_owner);
- tooltip_text.strip_edges();
- if (tooltip_text.empty()) {
+ tooltip_text = tooltip_text.strip_edges();
+ if (tooltip_text.is_empty()) {
return; // Nothing to show.
}
@@ -1580,7 +1589,8 @@ void Viewport::_gui_show_tooltip() {
Point2 tooltip_offset = ProjectSettings::get_singleton()->get("display/mouse_cursor/tooltip_position_offset");
Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size());
- Rect2i vr = gui.tooltip_popup->get_parent_visible_window()->get_usable_parent_rect();
+ Window *window = gui.tooltip_popup->get_parent_visible_window();
+ Rect2i vr = window->get_usable_parent_rect();
if (r.size.x + r.position.x > vr.size.x + vr.position.x) {
r.position.x = vr.position.x + vr.size.x - r.size.x;
@@ -1594,6 +1604,7 @@ void Viewport::_gui_show_tooltip() {
r.position.y = vr.position.y;
}
+ gui.tooltip_popup->set_current_screen(window->get_current_screen());
gui.tooltip_popup->set_position(r.position);
gui.tooltip_popup->set_size(r.size);
@@ -1759,19 +1770,22 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_
}
}
- if (!c) {
+ if (!c || c->data.mouse_filter == Control::MOUSE_FILTER_IGNORE) {
return nullptr;
}
matrix.affine_invert();
+ if (!c->has_point(matrix.xform(p_global))) {
+ return nullptr;
+ }
- //conditions for considering this as a valid control for return
- if (c->data.mouse_filter != Control::MOUSE_FILTER_IGNORE && c->has_point(matrix.xform(p_global)) && (!gui.drag_preview || (c != gui.drag_preview && !gui.drag_preview->is_a_parent_of(c)))) {
+ Control *drag_preview = _gui_get_drag_preview();
+ if (!drag_preview || (c != drag_preview && !drag_preview->is_a_parent_of(c))) {
r_inv_xform = matrix;
return c;
- } else {
- return nullptr;
}
+
+ return nullptr;
}
bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check) {
@@ -1909,9 +1923,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.drag_data = Variant();
gui.dragging = false;
- if (gui.drag_preview) {
- memdelete(gui.drag_preview);
- gui.drag_preview = nullptr;
+ Control *drag_preview = _gui_get_drag_preview();
+ if (drag_preview) {
+ memdelete(drag_preview);
+ gui.drag_preview_id = ObjectID();
}
_propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
//change mouse accordingly
@@ -1924,9 +1939,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
_gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false);
}
- if (gui.drag_preview && mb->get_button_index() == BUTTON_LEFT) {
- memdelete(gui.drag_preview);
- gui.drag_preview = nullptr;
+ Control *drag_preview = _gui_get_drag_preview();
+ if (drag_preview) {
+ memdelete(drag_preview);
+ gui.drag_preview_id = ObjectID();
}
gui.drag_data = Variant();
@@ -2023,10 +2039,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.mouse_focus_mask = 0;
break;
} else {
- if (gui.drag_preview != nullptr) {
+ Control *drag_preview = _gui_get_drag_preview();
+ if (drag_preview) {
ERR_PRINT("Don't set a drag preview and return null data. Preview was deleted and drag request ignored.");
- memdelete(gui.drag_preview);
- gui.drag_preview = nullptr;
+ memdelete(drag_preview);
+ gui.drag_preview_id = ObjectID();
}
gui.dragging = false;
}
@@ -2166,8 +2183,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (gui.drag_data.get_type() != Variant::NIL) {
//handle dragandrop
- if (gui.drag_preview) {
- gui.drag_preview->set_position(mpos);
+ Control *drag_preview = _gui_get_drag_preview();
+ if (drag_preview) {
+ drag_preview->set_position(mpos);
}
gui.drag_mouse_over = over;
@@ -2442,15 +2460,29 @@ void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
ERR_FAIL_COND(p_control->is_inside_tree());
ERR_FAIL_COND(p_control->get_parent() != nullptr);
- if (gui.drag_preview) {
- memdelete(gui.drag_preview);
+ Control *drag_preview = _gui_get_drag_preview();
+ if (drag_preview) {
+ memdelete(drag_preview);
}
p_control->set_as_top_level(true);
p_control->set_position(gui.last_mouse_pos);
p_base->get_root_parent_control()->add_child(p_control); //add as child of viewport
p_control->raise();
- gui.drag_preview = p_control;
+ gui.drag_preview_id = p_control->get_instance_id();
+}
+
+Control *Viewport::_gui_get_drag_preview() {
+ if (gui.drag_preview_id.is_null()) {
+ return nullptr;
+ } else {
+ Control *drag_preview = Object::cast_to<Control>(ObjectDB::get_instance(gui.drag_preview_id));
+ if (!drag_preview) {
+ ERR_PRINT("Don't free the control set as drag preview.");
+ gui.drag_preview_id = ObjectID();
+ }
+ return drag_preview;
+ }
}
void Viewport::_gui_remove_root_control(List<Control *>::Element *RI) {
@@ -2572,28 +2604,41 @@ void Viewport::_drop_mouse_focus() {
}
}
-void Viewport::_drop_physics_mouseover() {
+void Viewport::_drop_physics_mouseover(bool p_paused_only) {
physics_has_last_mousepos = false;
- while (physics_2d_mouseover.size()) {
- Object *o = ObjectDB::get_instance(physics_2d_mouseover.front()->key());
+ List<Map<ObjectID, uint64_t>::Element *> to_erase;
+
+ for (Map<ObjectID, uint64_t>::Element *E = physics_2d_mouseover.front(); E; E = E->next()) {
+ Object *o = ObjectDB::get_instance(E->key());
if (o) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
- co->_mouse_exit();
+ if (co) {
+ if (p_paused_only && co->can_process()) {
+ continue;
+ }
+ co->_mouse_exit();
+ to_erase.push_back(E);
+ }
}
- physics_2d_mouseover.erase(physics_2d_mouseover.front());
+ }
+
+ while (to_erase.size()) {
+ physics_2d_mouseover.erase(to_erase.front()->get());
+ to_erase.pop_front();
}
#ifndef _3D_DISABLED
if (physics_object_over.is_valid()) {
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
if (co) {
- co->_mouse_exit();
+ if (!(p_paused_only && co->can_process())) {
+ co->_mouse_exit();
+ physics_object_over = ObjectID();
+ physics_object_capture = ObjectID();
+ }
}
}
-
- physics_object_over = ObjectID();
- physics_object_capture = ObjectID();
#endif
}
@@ -3139,7 +3184,7 @@ String Viewport::get_configuration_warning() const {
String warning = Node::get_configuration_warning();
if (size.x == 0 || size.y == 0) {
- if (!warning.empty()) {
+ if (!warning.is_empty()) {
warning += "\n\n";
}
warning += TTR("Viewport size must be greater than 0 to render anything.");
@@ -3479,6 +3524,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size);
ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size);
+ ClassDB::bind_method(D_METHOD("set_shadow_atlas_16_bits", "enable"), &Viewport::set_shadow_atlas_16_bits);
+ ClassDB::bind_method(D_METHOD("get_shadow_atlas_16_bits"), &Viewport::get_shadow_atlas_16_bits);
+
ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels);
ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled);
@@ -3516,6 +3564,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_lod_threshold", "pixels"), &Viewport::set_lod_threshold);
ClassDB::bind_method(D_METHOD("get_lod_threshold"), &Viewport::get_lod_threshold);
+ ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d");
@@ -3546,6 +3596,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale");
ADD_GROUP("Shadow Atlas", "shadow_atlas_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_atlas_16_bits"), "set_shadow_atlas_16_bits", "get_shadow_atlas_16_bits");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 1);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 2);
@@ -3603,6 +3654,10 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(DEBUG_DRAW_SDFGI_PROBES);
BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_BUFFER);
BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLE_LOD);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_OMNI_LIGHTS);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_SPOT_LIGHTS);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_DECALS);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_REFLECTION_PROBES);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR);
@@ -3638,25 +3693,12 @@ Viewport::Viewport() {
viewport_textures.insert(default_texture.ptr());
default_texture->proxy = RS::get_singleton()->texture_proxy_create(texture_rid);
- audio_listener = false;
//internal_listener_2d = SpatialSound2DServer::get_singleton()->listener_create();
- audio_listener_2d = false;
- transparent_bg = false;
- parent = nullptr;
- listener = nullptr;
- camera = nullptr;
- override_canvas_transform = false;
canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport)
- gen_mipmaps = false;
-
//clear=true;
+ set_shadow_atlas_size(shadow_atlas_size);
- physics_object_picking = false;
- physics_has_last_mousepos = false;
- physics_last_mousepos = Vector2(Math_INF, Math_INF);
-
- shadow_atlas_size = 0;
for (int i = 0; i < 4; i++) {
shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX;
}
@@ -3673,50 +3715,11 @@ Viewport::Viewport() {
unhandled_input_group = "_vp_unhandled_input" + id;
unhandled_key_input_group = "_vp_unhandled_key_input" + id;
- disable_input = false;
-
// Window tooltip.
- gui.tooltip_timer = -1;
-
gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.5);
ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers
- gui.tooltip_control = nullptr;
- gui.tooltip_label = nullptr;
- gui.drag_preview = nullptr;
- gui.drag_attempted = false;
- gui.canvas_sort_index = 0;
- gui.roots_order_dirty = false;
- gui.mouse_focus = nullptr;
- gui.forced_mouse_focus = false;
- gui.last_mouse_focus = nullptr;
- gui.subwindow_focused = nullptr;
- gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
-
- msaa = MSAA_DISABLED;
- screen_space_aa = SCREEN_SPACE_AA_DISABLED;
- debug_draw = DEBUG_DRAW_DISABLED;
-
- snap_controls_to_pixels = true;
- snap_2d_transforms_to_pixel = false;
- snap_2d_vertices_to_pixel = false;
-
- physics_last_mouse_state.alt = false;
- physics_last_mouse_state.control = false;
- physics_last_mouse_state.shift = false;
- physics_last_mouse_state.meta = false;
- physics_last_mouse_state.mouse_mask = 0;
- local_input_handled = false;
- handle_input_locally = true;
-
- size_allocated = false;
-
- default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
- default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
-
- sdf_oversize = SDF_OVERSIZE_120_PERCENT;
- sdf_scale = SDF_SCALE_50_PERCENT;
- set_sdf_oversize(SDF_OVERSIZE_120_PERCENT); //set to server
+ set_sdf_oversize(sdf_oversize); //set to server
}
Viewport::~Viewport() {
@@ -3848,12 +3851,6 @@ void SubViewport::_bind_methods() {
BIND_ENUM_CONSTANT(UPDATE_ALWAYS);
}
-SubViewport::SubViewport() {
- xr = false;
- size_2d_override_stretch = false;
- update_mode = UPDATE_WHEN_VISIBLE;
- clear_mode = CLEAR_MODE_ALWAYS;
-}
+SubViewport::SubViewport() {}
-SubViewport::~SubViewport() {
-}
+SubViewport::~SubViewport() {}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index ffbc3c782a..0f11e6fb19 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,7 +56,7 @@ class ViewportTexture : public Texture2D {
NodePath path;
friend class Viewport;
- Viewport *vp;
+ Viewport *vp = nullptr;
mutable RID proxy_ph;
mutable RID proxy;
@@ -143,6 +143,10 @@ public:
DEBUG_DRAW_SDFGI_PROBES,
DEBUG_DRAW_GI_BUFFER,
DEBUG_DRAW_DISABLE_LOD,
+ DEBUG_DRAW_CLUSTER_OMNI_LIGHTS,
+ DEBUG_DRAW_CLUSTER_SPOT_LIGHTS,
+ DEBUG_DRAW_CLUSTER_DECALS,
+ DEBUG_DRAW_CLUSTER_REFLECTION_PROBES,
};
enum DefaultCanvasItemTextureFilter {
@@ -182,9 +186,9 @@ public:
private:
friend class ViewportTexture;
- Viewport *parent;
+ Viewport *parent = nullptr;
- Listener3D *listener;
+ Listener3D *listener = nullptr;
Set<Listener3D *> listeners;
struct CameraOverrideData {
@@ -193,11 +197,11 @@ private:
PROJECTION_PERSPECTIVE,
PROJECTION_ORTHOGONAL
};
- Projection projection;
- float fov;
- float size;
- float z_near;
- float z_far;
+ Projection projection = Projection::PROJECTION_PERSPECTIVE;
+ float fov = 0.0;
+ float size = 0.0;
+ float z_near = 0.0;
+ float z_far = 0.0;
RID rid;
operator bool() const {
@@ -205,7 +209,7 @@ private:
}
} camera_override;
- Camera3D *camera;
+ Camera3D *camera = nullptr;
Set<Camera3D *> cameras;
Set<CanvasLayer *> canvas_layers;
@@ -213,13 +217,13 @@ private:
RID current_canvas;
RID subwindow_canvas;
- bool audio_listener;
+ bool audio_listener = false;
RID internal_listener;
- bool audio_listener_2d;
+ bool audio_listener_2d = false;
RID internal_listener_2d;
- bool override_canvas_transform;
+ bool override_canvas_transform = false;
Transform2D canvas_transform_override;
Transform2D canvas_transform;
@@ -228,7 +232,7 @@ private:
Size2i size;
Size2i size_2d_override;
- bool size_allocated;
+ bool size_allocated = false;
RID contact_2d_debug;
RID contact_3d_debug_multimesh;
@@ -236,36 +240,36 @@ private:
Rect2 last_vp_rect;
- bool transparent_bg;
+ bool transparent_bg = false;
bool filter;
- bool gen_mipmaps;
+ bool gen_mipmaps = false;
- bool snap_controls_to_pixels;
- bool snap_2d_transforms_to_pixel;
- bool snap_2d_vertices_to_pixel;
+ bool snap_controls_to_pixels = true;
+ bool snap_2d_transforms_to_pixel = false;
+ bool snap_2d_vertices_to_pixel = false;
- bool physics_object_picking;
+ bool physics_object_picking = false;
List<Ref<InputEvent>> physics_picking_events;
ObjectID physics_object_capture;
ObjectID physics_object_over;
Transform physics_last_object_transform;
Transform physics_last_camera_transform;
ObjectID physics_last_id;
- bool physics_has_last_mousepos;
- Vector2 physics_last_mousepos;
+ bool physics_has_last_mousepos = false;
+ Vector2 physics_last_mousepos = Vector2(Math_INF, Math_INF);
struct {
- bool alt;
- bool control;
- bool shift;
- bool meta;
- int mouse_mask;
+ bool alt = false;
+ bool control = false;
+ bool shift = false;
+ bool meta = false;
+ int mouse_mask = 0;
} physics_last_mouse_state;
void _collision_object_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape);
- bool handle_input_locally;
- bool local_input_handled;
+ bool handle_input_locally = true;
+ bool local_input_handled = false;
Map<ObjectID, uint64_t> physics_2d_mouseover;
@@ -290,21 +294,22 @@ private:
RID texture_rid;
- DebugDraw debug_draw;
+ DebugDraw debug_draw = DEBUG_DRAW_DISABLED;
- int shadow_atlas_size;
+ int shadow_atlas_size = 2048;
+ bool shadow_atlas_16_bits = true;
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
- MSAA msaa;
- ScreenSpaceAA screen_space_aa;
+ MSAA msaa = MSAA_DISABLED;
+ ScreenSpaceAA screen_space_aa = SCREEN_SPACE_AA_DISABLED;
bool use_debanding = false;
float lod_threshold = 1.0;
Ref<ViewportTexture> default_texture;
Set<ViewportTexture *> viewport_textures;
- SDFOversize sdf_oversize;
- SDFScale sdf_scale;
+ SDFOversize sdf_oversize = SDF_OVERSIZE_120_PERCENT;
+ SDFScale sdf_scale = SDF_SCALE_50_PERCENT;
enum SubWindowDrag {
SUB_WINDOW_DRAG_DISABLED,
@@ -327,60 +332,58 @@ private:
};
struct SubWindow {
- Window *window;
+ Window *window = nullptr;
RID canvas_item;
};
struct GUI {
// info used when this is a window
- bool forced_mouse_focus; //used for menu buttons
- bool key_event_accepted;
- Control *mouse_focus;
- Control *last_mouse_focus;
- Control *mouse_click_grabber;
- int mouse_focus_mask;
- Control *key_focus;
- Control *mouse_over;
- Control *drag_mouse_over;
+ bool forced_mouse_focus = false; //used for menu buttons
+ bool key_event_accepted = false;
+ Control *mouse_focus = nullptr;
+ Control *last_mouse_focus = nullptr;
+ Control *mouse_click_grabber = nullptr;
+ int mouse_focus_mask = 0;
+ Control *key_focus = nullptr;
+ Control *mouse_over = nullptr;
+ Control *drag_mouse_over = nullptr;
Vector2 drag_mouse_over_pos;
- Control *tooltip_control;
- Window *tooltip_popup;
- Label *tooltip_label;
+ Control *tooltip_control = nullptr;
+ Window *tooltip_popup = nullptr;
+ Label *tooltip_label = nullptr;
Point2 tooltip_pos;
Point2 last_mouse_pos;
Point2 drag_accum;
- bool drag_attempted;
+ bool drag_attempted = false;
Variant drag_data;
- Control *drag_preview;
- float tooltip_timer;
- float tooltip_delay;
+ ObjectID drag_preview_id;
+ float tooltip_timer = -1.0;
+ float tooltip_delay = 0.0;
Transform2D focus_inv_xform;
- bool roots_order_dirty;
+ bool roots_order_dirty = false;
List<Control *> roots;
- int canvas_sort_index; //for sorting items with canvas as root
- bool dragging;
- bool embed_subwindows_hint;
- bool embedding_subwindows;
+ int canvas_sort_index = 0; //for sorting items with canvas as root
+ bool dragging = false;
+ bool embed_subwindows_hint = false;
+ bool embedding_subwindows = false;
- Window *subwindow_focused;
- SubWindowDrag subwindow_drag;
+ Window *subwindow_focused = nullptr;
+ SubWindowDrag subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
Vector2 subwindow_drag_from;
Vector2 subwindow_drag_pos;
Rect2i subwindow_drag_close_rect;
- bool subwindow_drag_close_inside;
+ bool subwindow_drag_close_inside = false;
SubWindowResize subwindow_resize_mode;
Rect2i subwindow_resize_from_rect;
Vector<SubWindow> sub_windows;
-
- GUI();
} gui;
- DefaultCanvasItemTextureFilter default_canvas_item_texture_filter;
- DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat;
+ DefaultCanvasItemTextureFilter default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
+ DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
- bool disable_input;
+ bool disable_input = false;
void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input);
void _gui_call_notification(Control *p_control, int p_what);
@@ -412,6 +415,7 @@ private:
void _gui_force_drag(Control *p_base, const Variant &p_data, Control *p_control);
void _gui_set_drag_preview(Control *p_base, Control *p_control);
+ Control *_gui_get_drag_preview();
void _gui_remove_focus_for_window(Node *p_window);
void _gui_remove_focus();
@@ -445,7 +449,7 @@ private:
void _canvas_layer_remove(CanvasLayer *p_canvas_layer);
void _drop_mouse_focus();
- void _drop_physics_mouseover();
+ void _drop_physics_mouseover(bool p_paused_only = false);
void _update_canvas_items(Node *p_node);
@@ -474,6 +478,7 @@ protected:
bool _is_size_allocated() const;
void _notification(int p_what);
+ void _process_picking();
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const override;
@@ -533,6 +538,9 @@ public:
void set_shadow_atlas_size(int p_size);
int get_shadow_atlas_size() const;
+ void set_shadow_atlas_16_bits(bool p_16_bits);
+ bool get_shadow_atlas_16_bits() const;
+
void set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv);
ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const;
@@ -642,10 +650,10 @@ public:
};
private:
- UpdateMode update_mode;
- ClearMode clear_mode;
- bool xr;
- bool size_2d_override_stretch;
+ UpdateMode update_mode = UPDATE_WHEN_VISIBLE;
+ ClearMode clear_mode = CLEAR_MODE_ALWAYS;
+ bool xr = false;
+ bool size_2d_override_stretch = false;
protected:
static void _bind_methods();
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index ad87139332..d697a1a5dd 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -826,6 +826,9 @@ bool Window::is_using_font_oversampling() const {
}
DisplayServer::WindowID Window::get_window_id() const {
+ if (embedder) {
+ return parent->get_window_id();
+ }
return window_id;
}
@@ -881,10 +884,6 @@ bool Window::_can_consume_input_events() const {
}
void Window::_window_input(const Ref<InputEvent> &p_ev) {
- if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev))) {
- return; //avoid joy input on editor
- }
-
if (EngineDebugger::is_active()) {
//quit from game window using F8
Ref<InputEventKey> k = p_ev;
@@ -1039,6 +1038,9 @@ void Window::popup_centered_ratio(float p_ratio) {
void Window::popup(const Rect2i &p_screen_rect) {
emit_signal("about_to_popup");
+ // Update window size to calculate the actual window size based on contents minimum size and minimum size.
+ _update_window_size();
+
if (p_screen_rect != Rect2i()) {
set_position(p_screen_rect.position);
set_size(p_screen_rect.size);
@@ -1283,14 +1285,14 @@ bool Window::is_layout_rtl() const {
if (parent) {
return parent->is_layout_rtl();
} else {
- if (GLOBAL_GET("display/window/force_right_to_left_layout_direction")) {
+ if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
return true;
}
String locale = TranslationServer::get_singleton()->get_tool_locale();
return TS->is_locale_right_to_left(locale);
}
} else if (layout_dir == LAYOUT_DIRECTION_LOCALE) {
- if (GLOBAL_GET("display/window/force_right_to_left_layout_direction")) {
+ if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) {
return true;
}
String locale = TranslationServer::get_singleton()->get_tool_locale();
@@ -1349,8 +1351,8 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_focus"), &Window::has_focus);
ClassDB::bind_method(D_METHOD("grab_focus"), &Window::grab_focus);
- ClassDB::bind_method(D_METHOD("set_ime_active"), &Window::set_ime_active);
- ClassDB::bind_method(D_METHOD("set_ime_position"), &Window::set_ime_position);
+ ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &Window::set_ime_active);
+ ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &Window::set_ime_position);
ClassDB::bind_method(D_METHOD("is_embedded"), &Window::is_embedded);
@@ -1466,11 +1468,6 @@ void Window::_bind_methods() {
}
Window::Window() {
- for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = false;
- }
- content_scale_mode = CONTENT_SCALE_MODE_DISABLED;
- content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE;
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
}
diff --git a/scene/main/window.h b/scene/main/window.h
index 20f8309952..38846ed00e 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -90,7 +90,7 @@ private:
mutable Size2i min_size;
mutable Size2i max_size;
mutable Mode mode = MODE_WINDOWED;
- mutable bool flags[FLAG_MAX];
+ mutable bool flags[FLAG_MAX] = {};
bool visible = true;
bool focused = false;
@@ -106,8 +106,8 @@ private:
void _update_child_controls();
Size2i content_scale_size;
- ContentScaleMode content_scale_mode;
- ContentScaleAspect content_scale_aspect;
+ ContentScaleMode content_scale_mode = CONTENT_SCALE_MODE_DISABLED;
+ ContentScaleAspect content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE;
void _make_window();
void _clear_window();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 30077aa642..fe8591e3d9 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,7 +50,6 @@
#include "scene/2d/line_2d.h"
#include "scene/2d/mesh_instance_2d.h"
#include "scene/2d/multimesh_instance_2d.h"
-#include "scene/2d/navigation_2d.h"
#include "scene/2d/navigation_agent_2d.h"
#include "scene/2d/navigation_obstacle_2d.h"
#include "scene/2d/parallax_background.h"
@@ -175,6 +174,7 @@
#include "scene/resources/video_stream.h"
#include "scene/resources/visual_shader.h"
#include "scene/resources/visual_shader_nodes.h"
+#include "scene/resources/visual_shader_sdf_nodes.h"
#include "scene/resources/world_2d.h"
#include "scene/resources/world_3d.h"
#include "scene/resources/world_margin_shape_3d.h"
@@ -205,7 +205,6 @@
#include "scene/3d/listener_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/multimesh_instance_3d.h"
-#include "scene/3d/navigation_3d.h"
#include "scene/3d/navigation_agent_3d.h"
#include "scene/3d/navigation_obstacle_3d.h"
#include "scene/3d/navigation_region_3d.h"
@@ -515,7 +514,6 @@ void register_scene_types() {
ClassDB::register_class<ConeTwistJoint3D>();
ClassDB::register_class<Generic6DOFJoint3D>();
- ClassDB::register_class<Navigation3D>();
ClassDB::register_class<NavigationRegion3D>();
ClassDB::register_class<NavigationAgent3D>();
ClassDB::register_class<NavigationObstacle3D>();
@@ -533,6 +531,7 @@ void register_scene_types() {
ClassDB::register_virtual_class<VisualShaderNodeOutput>();
ClassDB::register_virtual_class<VisualShaderNodeResizableBase>();
ClassDB::register_virtual_class<VisualShaderNodeGroupBase>();
+ ClassDB::register_virtual_class<VisualShaderNodeConstant>();
ClassDB::register_class<VisualShaderNodeFloatConstant>();
ClassDB::register_class<VisualShaderNodeIntConstant>();
ClassDB::register_class<VisualShaderNodeBooleanConstant>();
@@ -555,19 +554,14 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeDeterminant>();
ClassDB::register_class<VisualShaderNodeScalarDerivativeFunc>();
ClassDB::register_class<VisualShaderNodeVectorDerivativeFunc>();
- ClassDB::register_class<VisualShaderNodeScalarClamp>();
- ClassDB::register_class<VisualShaderNodeVectorClamp>();
+ ClassDB::register_class<VisualShaderNodeClamp>();
ClassDB::register_class<VisualShaderNodeFaceForward>();
ClassDB::register_class<VisualShaderNodeOuterProduct>();
- ClassDB::register_class<VisualShaderNodeVectorScalarStep>();
- ClassDB::register_class<VisualShaderNodeScalarSmoothStep>();
- ClassDB::register_class<VisualShaderNodeVectorSmoothStep>();
- ClassDB::register_class<VisualShaderNodeVectorScalarSmoothStep>();
+ ClassDB::register_class<VisualShaderNodeSmoothStep>();
+ ClassDB::register_class<VisualShaderNodeStep>();
ClassDB::register_class<VisualShaderNodeVectorDistance>();
ClassDB::register_class<VisualShaderNodeVectorRefract>();
- ClassDB::register_class<VisualShaderNodeScalarInterp>();
- ClassDB::register_class<VisualShaderNodeVectorInterp>();
- ClassDB::register_class<VisualShaderNodeVectorScalarMix>();
+ ClassDB::register_class<VisualShaderNodeMix>();
ClassDB::register_class<VisualShaderNodeVectorCompose>();
ClassDB::register_class<VisualShaderNodeTransformCompose>();
ClassDB::register_class<VisualShaderNodeVectorDecompose>();
@@ -593,7 +587,6 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeCubemapUniform>();
ClassDB::register_class<VisualShaderNodeIf>();
ClassDB::register_class<VisualShaderNodeSwitch>();
- ClassDB::register_class<VisualShaderNodeScalarSwitch>();
ClassDB::register_class<VisualShaderNodeFresnel>();
ClassDB::register_class<VisualShaderNodeExpression>();
ClassDB::register_class<VisualShaderNodeGlobalExpression>();
@@ -601,6 +594,12 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeCompare>();
ClassDB::register_class<VisualShaderNodeMultiplyAdd>();
+ ClassDB::register_class<VisualShaderNodeSDFToScreenUV>();
+ ClassDB::register_class<VisualShaderNodeScreenUVToSDF>();
+ ClassDB::register_class<VisualShaderNodeTextureSDF>();
+ ClassDB::register_class<VisualShaderNodeTextureSDFNormal>();
+ ClassDB::register_class<VisualShaderNodeSDFRaymarch>();
+
ClassDB::register_class<ShaderMaterial>();
ClassDB::register_virtual_class<CanvasItem>();
ClassDB::register_class<CanvasTexture>();
@@ -791,7 +790,6 @@ void register_scene_types() {
ClassDB::register_class<PathFollow2D>();
ClassDB::register_class<NavigationMesh>();
- ClassDB::register_class<Navigation2D>();
ClassDB::register_class<NavigationPolygon>();
ClassDB::register_class<NavigationRegion2D>();
ClassDB::register_class<NavigationAgent2D>();
@@ -812,6 +810,8 @@ void register_scene_types() {
ClassDB::add_compatibility_class("DynamicFont", "Font");
ClassDB::add_compatibility_class("DynamicFontData", "FontData");
ClassDB::add_compatibility_class("ToolButton", "Button");
+ ClassDB::add_compatibility_class("Navigation3D", "Node3D");
+ ClassDB::add_compatibility_class("Navigation2D", "Node2D");
// Renamed in 4.0.
// Keep alphabetical ordering to easily locate classes and avoid duplicates.
@@ -863,7 +863,6 @@ void register_scene_types() {
ClassDB::add_compatibility_class("Listener", "Listener3D");
ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D");
ClassDB::add_compatibility_class("MultiMeshInstance", "MultiMeshInstance3D");
- ClassDB::add_compatibility_class("Navigation", "Navigation3D");
ClassDB::add_compatibility_class("NavigationAgent", "NavigationAgent3D");
ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion3D");
ClassDB::add_compatibility_class("NavigationObstacle", "NavigationObstacle3D");
@@ -927,6 +926,16 @@ void register_scene_types() {
ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc");
ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp");
ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform");
+ ClassDB::add_compatibility_class("VisualShaderNodeScalarClamp", "VisualShaderNodeClamp");
+ ClassDB::add_compatibility_class("VisualShaderNodeVectorClamp", "VisualShaderNodeClamp");
+ ClassDB::add_compatibility_class("VisualShaderNodeScalarInterp", "VisualShaderNodeMix");
+ ClassDB::add_compatibility_class("VisualShaderNodeVectorInterp", "VisualShaderNodeMix");
+ ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarMix", "VisualShaderNodeMix");
+ ClassDB::add_compatibility_class("VisualShaderNodeScalarSmoothStep", "VisualShaderNodeSmoothStep");
+ ClassDB::add_compatibility_class("VisualShaderNodeVectorSmoothStep", "VisualShaderNodeSmoothStep");
+ ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarSmoothStep", "VisualShaderNodeSmoothStep");
+ ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarStep", "VisualShaderNodeStep");
+ ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch");
ClassDB::add_compatibility_class("World", "World3D");
ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D");
ClassDB::add_compatibility_class("Light2D", "PointLight2D");
@@ -936,10 +945,12 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
for (int i = 0; i < 20; i++) {
- GLOBAL_DEF("layer_names/2d_render/layer_" + itos(i + 1), "");
- GLOBAL_DEF("layer_names/2d_physics/layer_" + itos(i + 1), "");
- GLOBAL_DEF("layer_names/3d_render/layer_" + itos(i + 1), "");
- GLOBAL_DEF("layer_names/3d_physics/layer_" + itos(i + 1), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/2d_render/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/2d_physics/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/2d_navigation/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/3d_render/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/3d_physics/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/3d_navigation/layer_%d", i), "");
}
bool default_theme_hidpi = GLOBAL_DEF("gui/theme/use_hidpi", false);
diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h
index 603321991e..1ff542eef8 100644
--- a/scene/register_scene_types.h
+++ b/scene/register_scene_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index f4670ca850..cc1dafd0db 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -580,6 +580,10 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
+void Animation::reset_state() {
+ clear();
+}
+
int Animation::add_track(TrackType p_type, int p_at_pos) {
if (p_at_pos < 0 || p_at_pos >= tracks.size()) {
p_at_pos = tracks.size();
@@ -1604,7 +1608,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola
bool result = true;
int next = 0;
- float c = 0;
+ float c = 0.0;
// prepare for all cases of interpolation
if (loop && p_loop_wrap) {
@@ -2278,8 +2282,8 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
int iterations = 10;
float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes
- float low = 0; // 0% of the current animation segment
- float high = 1; // 100% of the current animation segment
+ float low = 0.0; // 0% of the current animation segment
+ float high = 1.0; // 100% of the current animation segment
float middle;
Vector2 start(0, bt->values[idx].value.value);
@@ -2836,7 +2840,7 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
erase = true;
} else {
erase = true;
- real_t lt = -1;
+ real_t lt = -1.0;
for (int j = 0; j < 3; j++) {
//search for t on first, one must be it
if (t[j] != -1) {
@@ -2919,11 +2923,7 @@ void Animation::optimize(float p_allowed_linear_err, float p_allowed_angular_err
}
}
-Animation::Animation() {
- step = 0.1;
- loop = false;
- length = 1;
-}
+Animation::Animation() {}
Animation::~Animation() {
for (int i = 0; i < tracks.size(); i++) {
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 650a54ebfc..66bc71c834 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,28 +65,19 @@ public:
private:
struct Track {
- TrackType type;
- InterpolationType interpolation;
- bool loop_wrap;
+ TrackType type = TrackType::TYPE_ANIMATION;
+ InterpolationType interpolation = INTERPOLATION_LINEAR;
+ bool loop_wrap = true;
NodePath path; // path to something
- bool imported;
- bool enabled;
- Track() {
- interpolation = INTERPOLATION_LINEAR;
- imported = false;
- loop_wrap = true;
- enabled = true;
- }
+ bool imported = false;
+ bool enabled = true;
+ Track() {}
virtual ~Track() {}
};
struct Key {
- float transition;
- float time; // time in secs
- Key() {
- transition = 1;
- time = 0;
- }
+ float transition = 1.0;
+ float time = 0.0; // time in secs
};
// transform key holds either Vector3 or Quaternion
@@ -112,13 +103,12 @@ private:
/* PROPERTY VALUE TRACK */
struct ValueTrack : public Track {
- UpdateMode update_mode;
- bool update_on_seek;
+ UpdateMode update_mode = UPDATE_CONTINUOUS;
+ bool update_on_seek = false;
Vector<TKey<Variant>> values;
ValueTrack() {
type = TYPE_VALUE;
- update_mode = UPDATE_CONTINUOUS;
}
};
@@ -139,7 +129,7 @@ private:
struct BezierKey {
Vector2 in_handle; //relative (x always <0)
Vector2 out_handle; //relative (x always >0)
- float value;
+ float value = 0.0;
};
struct BezierTrack : public Track {
@@ -154,11 +144,9 @@ private:
struct AudioKey {
RES stream;
- float start_offset; //offset from start
- float end_offset; //offset from end, if 0 then full length or infinite
+ float start_offset = 0.0; //offset from start
+ float end_offset = 0.0; //offset from end, if 0 then full length or infinite
AudioKey() {
- start_offset = 0;
- end_offset = 0;
}
};
@@ -217,9 +205,9 @@ private:
_FORCE_INLINE_ void _value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const;
_FORCE_INLINE_ void _method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const;
- float length;
- float step;
- bool loop;
+ float length = 1.0;
+ float step = 0.1;
+ bool loop = false;
// bind helpers
private:
@@ -264,6 +252,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
+
static void _bind_methods();
public:
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index 600a859894..06a91fb2f8 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -403,11 +403,7 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
}
}
-AudioStreamPlaybackSample::AudioStreamPlaybackSample() {
- active = false;
- offset = 0;
- sign = 1;
-}
+AudioStreamPlaybackSample::AudioStreamPlaybackSample() {}
/////////////////////
@@ -651,16 +647,7 @@ void AudioStreamSample::_bind_methods() {
BIND_ENUM_CONSTANT(LOOP_BACKWARD);
}
-AudioStreamSample::AudioStreamSample() {
- format = FORMAT_8_BITS;
- loop_mode = LOOP_DISABLED;
- stereo = false;
- loop_begin = 0;
- loop_end = 0;
- mix_rate = 44100;
- data = nullptr;
- data_bytes = 0;
-}
+AudioStreamSample::AudioStreamSample() {}
AudioStreamSample::~AudioStreamSample() {
if (data) {
diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h
index d91cdef57d..70b8ba79ad 100644
--- a/scene/resources/audio_stream_sample.h
+++ b/scene/resources/audio_stream_sample.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,19 +44,19 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback {
};
struct IMA_ADPCM_State {
- int16_t step_index;
- int32_t predictor;
+ int16_t step_index = 0;
+ int32_t predictor = 0;
/* values at loop point */
- int16_t loop_step_index;
- int32_t loop_predictor;
- int32_t last_nibble;
- int32_t loop_pos;
- int32_t window_ofs;
+ int16_t loop_step_index = 0;
+ int32_t loop_predictor = 0;
+ int32_t last_nibble = 0;
+ int32_t loop_pos = 0;
+ int32_t window_ofs = 0;
} ima_adpcm[2];
- int64_t offset;
- int sign;
- bool active;
+ int64_t offset = 0;
+ int sign = 1;
+ bool active = false;
friend class AudioStreamSample;
Ref<AudioStreamSample> base;
@@ -103,14 +103,14 @@ private:
DATA_PAD = 16 //padding for interpolation
};
- Format format;
- LoopMode loop_mode;
- bool stereo;
- int loop_begin;
- int loop_end;
- int mix_rate;
- void *data;
- uint32_t data_bytes;
+ Format format = FORMAT_8_BITS;
+ LoopMode loop_mode = LOOP_DISABLED;
+ bool stereo = false;
+ int loop_begin = 0;
+ int loop_end = 0;
+ int mix_rate = 44100;
+ void *data = nullptr;
+ uint32_t data_bytes = 0;
protected:
static void _bind_methods();
diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp
index d07447179d..8ffc7b4b4c 100644
--- a/scene/resources/bit_map.cpp
+++ b/scene/resources/bit_map.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,7 @@ void BitMap::create(const Size2 &p_size) {
}
void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshold) {
- ERR_FAIL_COND(p_image.is_null() || p_image->empty());
+ ERR_FAIL_COND(p_image.is_null() || p_image->is_empty());
Ref<Image> img = p_image->duplicate();
img->convert(Image::FORMAT_LA8);
ERR_FAIL_COND(img->get_format() != Image::FORMAT_LA8);
@@ -346,7 +346,7 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) {
}
int index = -1;
- float dist = 0;
+ float dist = 0.0;
//not looping first and last point
for (size_t i = 1, size = v.size(); i < size - 1; ++i) {
float cdist = perpendicular_distance(v[i], v[0], v[v.size() - 1]);
@@ -406,8 +406,8 @@ static Vector<Vector2> reduce(const Vector<Vector2> &points, const Rect2i &rect,
struct FillBitsStackEntry {
Point2i pos;
- int i;
- int j;
+ int i = 0;
+ int j = 0;
};
static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) {
@@ -677,9 +677,6 @@ void BitMap::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
}
-BitMap::BitMap() {
- width = 0;
- height = 0;
-}
+BitMap::BitMap() {}
//////////////////////////////////////
diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h
index 56ff72c094..68fd0b999a 100644
--- a/scene/resources/bit_map.h
+++ b/scene/resources/bit_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -40,8 +40,8 @@ class BitMap : public Resource {
OBJ_SAVE_TYPE(BitMap);
Vector<uint8_t> bitmask;
- int width;
- int height;
+ int width = 0;
+ int height = 0;
Vector<Vector2> _march_square(const Rect2i &rect, const Point2i &start) const;
diff --git a/scene/resources/box_shape_3d.cpp b/scene/resources/box_shape_3d.cpp
index e1c8a377c0..6e7adc0bd7 100644
--- a/scene/resources/box_shape_3d.cpp
+++ b/scene/resources/box_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,8 +34,8 @@
Vector<Vector3> BoxShape3D::get_debug_mesh_lines() const {
Vector<Vector3> lines;
AABB aabb;
- aabb.position = -get_extents();
- aabb.size = aabb.position * -2;
+ aabb.position = -size / 2;
+ aabb.size = size;
for (int i = 0; i < 12; i++) {
Vector3 a, b;
@@ -48,33 +48,32 @@ Vector<Vector3> BoxShape3D::get_debug_mesh_lines() const {
}
real_t BoxShape3D::get_enclosing_radius() const {
- return extents.length();
+ return size.length() / 2;
}
void BoxShape3D::_update_shape() {
- PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), extents);
+ PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), size / 2);
Shape3D::_update_shape();
}
-void BoxShape3D::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
+void BoxShape3D::set_size(const Vector3 &p_size) {
+ size = p_size;
_update_shape();
notify_change_to_owners();
- _change_notify("extents");
}
-Vector3 BoxShape3D::get_extents() const {
- return extents;
+Vector3 BoxShape3D::get_size() const {
+ return size;
}
void BoxShape3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &BoxShape3D::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &BoxShape3D::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &BoxShape3D::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &BoxShape3D::get_size);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size");
}
BoxShape3D::BoxShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_BOX)) {
- set_extents(Vector3(1, 1, 1));
+ set_size(Vector3(2, 2, 2));
}
diff --git a/scene/resources/box_shape_3d.h b/scene/resources/box_shape_3d.h
index fe634ce568..fce05d61ed 100644
--- a/scene/resources/box_shape_3d.h
+++ b/scene/resources/box_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,7 +35,7 @@
class BoxShape3D : public Shape3D {
GDCLASS(BoxShape3D, Shape3D);
- Vector3 extents;
+ Vector3 size;
protected:
static void _bind_methods();
@@ -43,8 +43,8 @@ protected:
virtual void _update_shape() override;
public:
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
virtual Vector<Vector3> get_debug_mesh_lines() const override;
virtual real_t get_enclosing_radius() const override;
diff --git a/scene/resources/camera_effects.cpp b/scene/resources/camera_effects.cpp
index 6b6ed51ed0..34c6bc05bc 100644
--- a/scene/resources/camera_effects.cpp
+++ b/scene/resources/camera_effects.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,7 +41,7 @@ RID CameraEffects::get_rid() const {
void CameraEffects::set_dof_blur_far_enabled(bool p_enabled) {
dof_blur_far_enabled = p_enabled;
_update_dof_blur();
- _change_notify();
+ notify_property_list_changed();
}
bool CameraEffects::is_dof_blur_far_enabled() const {
@@ -69,7 +69,7 @@ float CameraEffects::get_dof_blur_far_transition() const {
void CameraEffects::set_dof_blur_near_enabled(bool p_enabled) {
dof_blur_near_enabled = p_enabled;
_update_dof_blur();
- _change_notify();
+ notify_property_list_changed();
}
bool CameraEffects::is_dof_blur_near_enabled() const {
@@ -120,6 +120,7 @@ void CameraEffects::_update_dof_blur() {
void CameraEffects::set_override_exposure_enabled(bool p_enabled) {
override_exposure_enabled = p_enabled;
_update_override_exposure();
+ notify_property_list_changed();
}
bool CameraEffects::is_override_exposure_enabled() const {
@@ -144,6 +145,14 @@ void CameraEffects::_update_override_exposure() {
// Private methods, constructor and destructor
+void CameraEffects::_validate_property(PropertyInfo &property) const {
+ if ((!dof_blur_far_enabled && (property.name == "dof_blur_far_distance" || property.name == "dof_blur_far_transition")) ||
+ (!dof_blur_near_enabled && (property.name == "dof_blur_near_distance" || property.name == "dof_blur_near_transition")) ||
+ (!override_exposure_enabled && property.name == "override_exposure")) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void CameraEffects::_bind_methods() {
// DOF blur
diff --git a/scene/resources/camera_effects.h b/scene/resources/camera_effects.h
index 9a26f3d0b2..b9338f4806 100644
--- a/scene/resources/camera_effects.h
+++ b/scene/resources/camera_effects.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,12 +42,12 @@ private:
// DOF blur
bool dof_blur_far_enabled = false;
- float dof_blur_far_distance = 10;
- float dof_blur_far_transition = 5;
+ float dof_blur_far_distance = 10.0;
+ float dof_blur_far_transition = 5.0;
bool dof_blur_near_enabled = false;
- float dof_blur_near_distance = 2;
- float dof_blur_near_transition = 1;
+ float dof_blur_near_distance = 2.0;
+ float dof_blur_near_transition = 1.0;
float dof_blur_amount = 0.1;
void _update_dof_blur();
@@ -59,6 +59,7 @@ private:
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
virtual RID get_rid() const override;
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index e519970f38..e5edba8a67 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,12 +36,13 @@
Vector<Vector2> CapsuleShape2D::_get_points() const {
Vector<Vector2> points;
+ const real_t turn_step = Math_TAU / 24.0;
for (int i = 0; i < 24; i++) {
Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5);
- points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs);
+ points.push_back(Vector2(Math::sin(i * turn_step), Math::cos(i * turn_step)) * get_radius() + ofs);
if (i == 6 || i == 18) {
- points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs);
+ points.push_back(Vector2(Math::sin(i * turn_step), Math::cos(i * turn_step)) * get_radius() - ofs);
}
}
@@ -84,6 +85,11 @@ void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Vector<Color> col;
col.push_back(p_color);
RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
+ if (is_collision_outline_enabled()) {
+ RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col);
+ // Draw the last segment as it's not drawn by `canvas_item_add_polyline()`.
+ RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color);
+ }
}
Rect2 CapsuleShape2D::get_rect() const {
@@ -111,7 +117,5 @@ void CapsuleShape2D::_bind_methods() {
CapsuleShape2D::CapsuleShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->capsule_shape_create()) {
- radius = 10;
- height = 20;
_update_shape();
}
diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h
index 1caa6c68b8..439b67e8c3 100644
--- a/scene/resources/capsule_shape_2d.h
+++ b/scene/resources/capsule_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,8 +36,8 @@
class CapsuleShape2D : public Shape2D {
GDCLASS(CapsuleShape2D, Shape2D);
- real_t height;
- real_t radius;
+ real_t height = 20.0;
+ real_t radius = 10.0;
void _update_shape();
Vector<Vector2> _get_points() const;
diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp
index 5da7f682e5..226fe1ecd2 100644
--- a/scene/resources/capsule_shape_3d.cpp
+++ b/scene/resources/capsule_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -82,7 +82,6 @@ void CapsuleShape3D::set_radius(float p_radius) {
radius = p_radius;
_update_shape();
notify_change_to_owners();
- _change_notify("radius");
}
float CapsuleShape3D::get_radius() const {
@@ -93,7 +92,6 @@ void CapsuleShape3D::set_height(float p_height) {
height = p_height;
_update_shape();
notify_change_to_owners();
- _change_notify("height");
}
float CapsuleShape3D::get_height() const {
@@ -112,7 +110,5 @@ void CapsuleShape3D::_bind_methods() {
CapsuleShape3D::CapsuleShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CAPSULE)) {
- radius = 1.0;
- height = 1.0;
_update_shape();
}
diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h
index 432ca5654e..25645ecf9d 100644
--- a/scene/resources/capsule_shape_3d.h
+++ b/scene/resources/capsule_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,8 +35,8 @@
class CapsuleShape3D : public Shape3D {
GDCLASS(CapsuleShape3D, Shape3D);
- float radius;
- float height;
+ float radius = 1.0;
+ float height = 1.0;
protected:
static void _bind_methods();
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index dc1bf3b185..f06bc4248d 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,17 +71,22 @@ real_t CircleShape2D::get_enclosing_radius() const {
void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Vector<Vector2> points;
+ const real_t turn_step = Math_TAU / 24.0;
for (int i = 0; i < 24; i++) {
- points.push_back(Vector2(Math::cos(i * Math_PI * 2 / 24.0), Math::sin(i * Math_PI * 2 / 24.0)) * get_radius());
+ points.push_back(Vector2(Math::cos(i * turn_step), Math::sin(i * turn_step)) * get_radius());
}
Vector<Color> col;
col.push_back(p_color);
RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
+ if (is_collision_outline_enabled()) {
+ RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col);
+ // Draw the last segment as it's not drawn by `canvas_item_add_polyline()`.
+ RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color);
+ }
}
CircleShape2D::CircleShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->circle_shape_create()) {
- radius = 10;
_update_shape();
}
diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h
index ac8757e781..333f299236 100644
--- a/scene/resources/circle_shape_2d.h
+++ b/scene/resources/circle_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class CircleShape2D : public Shape2D {
GDCLASS(CircleShape2D, Shape2D);
- real_t radius;
+ real_t radius = 10.0;
void _update_shape();
protected:
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index eecf8afa8f..0c767c8a52 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -98,7 +98,7 @@ Rect2 ConcavePolygonShape2D::get_rect() const {
real_t ConcavePolygonShape2D::get_enclosing_radius() const {
Vector<Vector2> data = get_segments();
const Vector2 *read = data.ptr();
- real_t r = 0;
+ real_t r = 0.0;
for (int i(0); i < data.size(); i++) {
r = MAX(read[i].length_squared(), r);
}
diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h
index df8cc9920f..98ae341e97 100644
--- a/scene/resources/concave_polygon_shape_2d.h
+++ b/scene/resources/concave_polygon_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/concave_polygon_shape_3d.cpp b/scene/resources/concave_polygon_shape_3d.cpp
index 7cbafcbc4d..f067695d7d 100644
--- a/scene/resources/concave_polygon_shape_3d.cpp
+++ b/scene/resources/concave_polygon_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,7 +63,7 @@ Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() const {
real_t ConcavePolygonShape3D::get_enclosing_radius() const {
Vector<Vector3> data = get_faces();
const Vector3 *read = data.ptr();
- real_t r = 0;
+ real_t r = 0.0;
for (int i(0); i < data.size(); i++) {
r = MAX(read[i].length_squared(), r);
}
diff --git a/scene/resources/concave_polygon_shape_3d.h b/scene/resources/concave_polygon_shape_3d.h
index c17765b9ef..391459a3d7 100644
--- a/scene/resources/concave_polygon_shape_3d.h
+++ b/scene/resources/concave_polygon_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index 2b7531c630..6e56f6e7fc 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -72,9 +72,18 @@ void ConvexPolygonShape2D::_bind_methods() {
}
void ConvexPolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) {
+ if (points.size() < 3) {
+ return;
+ }
+
Vector<Color> col;
col.push_back(p_color);
RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
+ if (is_collision_outline_enabled()) {
+ RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col);
+ // Draw the last segment as it's not drawn by `canvas_item_add_polyline()`.
+ RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color);
+ }
}
Rect2 ConvexPolygonShape2D::get_rect() const {
@@ -91,7 +100,7 @@ Rect2 ConvexPolygonShape2D::get_rect() const {
}
real_t ConvexPolygonShape2D::get_enclosing_radius() const {
- real_t r = 0;
+ real_t r = 0.0;
for (int i(0); i < get_points().size(); i++) {
r = MAX(get_points()[i].length_squared(), r);
}
diff --git a/scene/resources/convex_polygon_shape_2d.h b/scene/resources/convex_polygon_shape_2d.h
index 294157bec5..1813b608bd 100644
--- a/scene/resources/convex_polygon_shape_2d.h
+++ b/scene/resources/convex_polygon_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/convex_polygon_shape_3d.cpp b/scene/resources/convex_polygon_shape_3d.cpp
index 29549e1114..9e030bc077 100644
--- a/scene/resources/convex_polygon_shape_3d.cpp
+++ b/scene/resources/convex_polygon_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,7 +56,7 @@ Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() const {
real_t ConvexPolygonShape3D::get_enclosing_radius() const {
Vector<Vector3> data = get_points();
const Vector3 *read = data.ptr();
- real_t r = 0;
+ real_t r = 0.0;
for (int i(0); i < data.size(); i++) {
r = MAX(read[i].length_squared(), r);
}
diff --git a/scene/resources/convex_polygon_shape_3d.h b/scene/resources/convex_polygon_shape_3d.h
index f436d2f5d4..edd127c8f4 100644
--- a/scene/resources/convex_polygon_shape_3d.h
+++ b/scene/resources/convex_polygon_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index de076670cf..bc479e557a 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,11 +47,6 @@ static _FORCE_INLINE_ T _bezier_interp(real_t t, T start, T control_1, T control
const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed";
Curve::Curve() {
- _bake_resolution = 100;
- _baked_cache_dirty = false;
- _min_value = 0;
- _max_value = 1;
- _minmax_set_once = 0b00;
}
int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, TangentMode left_mode, TangentMode right_mode) {
@@ -602,7 +597,7 @@ void Curve2D::remove_point(int p_index) {
}
void Curve2D::clear_points() {
- if (!points.empty()) {
+ if (!points.is_empty()) {
points.clear();
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
@@ -683,7 +678,7 @@ void Curve2D::_bake() const {
for (int i = 0; i < points.size() - 1; i++) {
float step = 0.1; // at least 10 substeps ought to be enough?
- float p = 0;
+ float p = 0.0;
while (p < 1.0) {
float np = p + step;
@@ -993,12 +988,9 @@ void Curve2D::_bind_methods() {
}
Curve2D::Curve2D() {
- baked_cache_dirty = false;
- baked_max_ofs = 0;
/* add_point(Vector2(-1,0,0));
add_point(Vector2(0,2,0));
add_point(Vector2(0,3,5));*/
- bake_interval = 5;
}
/***********************************************************************************/
@@ -1087,7 +1079,7 @@ void Curve3D::remove_point(int p_index) {
}
void Curve3D::clear_points() {
- if (!points.empty()) {
+ if (!points.is_empty()) {
points.clear();
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
@@ -1178,7 +1170,7 @@ void Curve3D::_bake() const {
for (int i = 0; i < points.size() - 1; i++) {
float step = 0.1; // at least 10 substeps ought to be enough?
- float p = 0;
+ float p = 0.0;
while (p < 1.0) {
float np = p + step;
@@ -1669,11 +1661,7 @@ void Curve3D::_bind_methods() {
}
Curve3D::Curve3D() {
- baked_cache_dirty = false;
- baked_max_ofs = 0;
/* add_point(Vector3(-1,0,0));
add_point(Vector3(0,2,0));
add_point(Vector3(0,3,5));*/
- bake_interval = 0.2;
- up_vector_enabled = true;
}
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index 6c5f4b7057..402c893cd8 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,21 +51,17 @@ public:
struct Point {
Vector2 pos;
- real_t left_tangent;
- real_t right_tangent;
- TangentMode left_mode;
- TangentMode right_mode;
+ real_t left_tangent = 0.0;
+ real_t right_tangent = 0.0;
+ TangentMode left_mode = TANGENT_FREE;
+ TangentMode right_mode = TANGENT_FREE;
Point() {
- left_tangent = 0;
- right_tangent = 0;
- left_mode = TANGENT_FREE;
- right_mode = TANGENT_FREE;
}
Point(Vector2 p_pos,
- real_t p_left = 0,
- real_t p_right = 0,
+ real_t p_left = 0.0,
+ real_t p_right = 0.0,
TangentMode p_left_mode = TANGENT_FREE,
TangentMode p_right_mode = TANGENT_FREE) {
pos = p_pos;
@@ -137,12 +133,12 @@ private:
void mark_dirty();
Vector<Point> _points;
- bool _baked_cache_dirty;
+ bool _baked_cache_dirty = false;
Vector<real_t> _baked_cache;
- int _bake_resolution;
- float _min_value;
- float _max_value;
- int _minmax_set_once; // Encodes whether min and max have been set a first time, first bit for min and second for max.
+ int _bake_resolution = 100;
+ float _min_value = 0.0;
+ float _max_value = 1.0;
+ int _minmax_set_once = 0b00; // Encodes whether min and max have been set a first time, first bit for min and second for max.
};
VARIANT_ENUM_CAST(Curve::TangentMode)
@@ -159,17 +155,17 @@ class Curve2D : public Resource {
Vector<Point> points;
struct BakedPoint {
- float ofs;
+ float ofs = 0.0;
Vector2 point;
};
- mutable bool baked_cache_dirty;
+ mutable bool baked_cache_dirty = false;
mutable PackedVector2Array baked_point_cache;
- mutable float baked_max_ofs;
+ mutable float baked_max_ofs = 0.0;
void _bake() const;
- float bake_interval;
+ float bake_interval = 5.0;
void _bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const;
Dictionary _get_data() const;
@@ -214,28 +210,26 @@ class Curve3D : public Resource {
Vector3 in;
Vector3 out;
Vector3 pos;
- float tilt;
-
- Point() { tilt = 0; }
+ float tilt = 0.0;
};
Vector<Point> points;
struct BakedPoint {
- float ofs;
+ float ofs = 0.0;
Vector3 point;
};
- mutable bool baked_cache_dirty;
+ mutable bool baked_cache_dirty = false;
mutable PackedVector3Array baked_point_cache;
mutable PackedFloat32Array baked_tilt_cache;
mutable PackedVector3Array baked_up_vector_cache;
- mutable float baked_max_ofs;
+ mutable float baked_max_ofs = 0.0;
void _bake() const;
- float bake_interval;
- bool up_vector_enabled;
+ float bake_interval = 0.2;
+ bool up_vector_enabled = true;
void _bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const;
Dictionary _get_data() const;
diff --git a/scene/resources/cylinder_shape_3d.cpp b/scene/resources/cylinder_shape_3d.cpp
index bb8c27a60d..63bdc8d26d 100644
--- a/scene/resources/cylinder_shape_3d.cpp
+++ b/scene/resources/cylinder_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -75,7 +75,6 @@ void CylinderShape3D::set_radius(float p_radius) {
radius = p_radius;
_update_shape();
notify_change_to_owners();
- _change_notify("radius");
}
float CylinderShape3D::get_radius() const {
@@ -86,7 +85,6 @@ void CylinderShape3D::set_height(float p_height) {
height = p_height;
_update_shape();
notify_change_to_owners();
- _change_notify("height");
}
float CylinderShape3D::get_height() const {
@@ -105,7 +103,5 @@ void CylinderShape3D::_bind_methods() {
CylinderShape3D::CylinderShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CYLINDER)) {
- radius = 1.0;
- height = 2.0;
_update_shape();
}
diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h
index e579e1f7cf..d1b8364672 100644
--- a/scene/resources/cylinder_shape_3d.h
+++ b/scene/resources/cylinder_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,8 +35,8 @@
class CylinderShape3D : public Shape3D {
GDCLASS(CylinderShape3D, Shape3D);
- float radius;
- float height;
+ float radius = 1.0;
+ float height = 2.0;
protected:
static void _bind_methods();
diff --git a/scene/resources/default_theme/bar_arrow.png b/scene/resources/default_theme/bar_arrow.png
new file mode 100644
index 0000000000..7cf146b8da
--- /dev/null
+++ b/scene/resources/default_theme/bar_arrow.png
Binary files differ
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 7dbf53a43c..0c661cc17d 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,10 +43,10 @@
typedef Map<const void *, Ref<ImageTexture>> TexCacheMap;
static TexCacheMap *tex_cache;
-static float scale = 1;
+static float scale = 1.0;
template <class T>
-static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, float p_right, float p_botton, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1, bool p_draw_center = true) {
+static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) {
Ref<ImageTexture> texture;
if (tex_cache->has(p_src)) {
@@ -66,11 +66,11 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, fl
style->set_texture(texture);
style->set_margin_size(SIDE_LEFT, p_left * scale);
style->set_margin_size(SIDE_RIGHT, p_right * scale);
- style->set_margin_size(SIDE_BOTTOM, p_botton * scale);
+ style->set_margin_size(SIDE_BOTTOM, p_bottom * scale);
style->set_margin_size(SIDE_TOP, p_top * scale);
style->set_default_margin(SIDE_LEFT, p_margin_left * scale);
style->set_default_margin(SIDE_RIGHT, p_margin_right * scale);
- style->set_default_margin(SIDE_BOTTOM, p_margin_botton * scale);
+ style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * scale);
style->set_default_margin(SIDE_TOP, p_margin_top * scale);
style->set_draw_center(p_draw_center);
@@ -88,11 +88,11 @@ static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left =
return style;
}
-static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left, float p_top, float p_right, float p_botton) {
+static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left, float p_top, float p_right, float p_bottom) {
p_sbox->set_expand_margin_size(SIDE_LEFT, p_left * scale);
p_sbox->set_expand_margin_size(SIDE_TOP, p_top * scale);
p_sbox->set_expand_margin_size(SIDE_RIGHT, p_right * scale);
- p_sbox->set_expand_margin_size(SIDE_BOTTOM, p_botton * scale);
+ p_sbox->set_expand_margin_size(SIDE_BOTTOM, p_bottom * scale);
return p_sbox;
}
@@ -115,6 +115,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
Ref<ImageTexture> texture(memnew(ImageTexture));
Ref<Image> img = p_texture->get_data();
+ img = img->duplicate();
if (p_flip_y) {
img->flip_y();
@@ -127,12 +128,44 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
return texture;
}
-static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1) {
+static Ref<FontData> make_font(int p_height, int p_ascent, int p_charcount, const int *p_char_rects, int p_kerning_count, const int *p_kernings, int p_w, int p_h, const unsigned char *p_img) {
+ Ref<FontData> font(memnew(FontData));
+ font->new_bitmap(p_height, p_ascent, p_height);
+
+ Ref<Image> image = memnew(Image(p_img));
+ Ref<ImageTexture> tex = memnew(ImageTexture);
+ tex->create_from_image(image);
+
+ font->bitmap_add_texture(tex);
+
+ for (int i = 0; i < p_charcount; i++) {
+ const int *c = &p_char_rects[i * 8];
+
+ int chr = c[0];
+ Rect2 frect;
+ frect.position.x = c[1];
+ frect.position.y = c[2];
+ frect.size.x = c[3];
+ frect.size.y = c[4];
+ Point2 align(c[6], c[5]);
+ int advance = c[7];
+
+ font->bitmap_add_char(chr, 0, frect, align, advance);
+ }
+
+ for (int i = 0; i < p_kerning_count; i++) {
+ font->bitmap_add_kerning_pair(p_kernings[i * 3 + 0], p_kernings[i * 3 + 1], p_kernings[i * 3 + 2]);
+ }
+
+ return font;
+}
+
+static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
Ref<StyleBox> style(memnew(StyleBoxEmpty));
style->set_default_margin(SIDE_LEFT, p_margin_left * scale);
style->set_default_margin(SIDE_RIGHT, p_margin_right * scale);
- style->set_default_margin(SIDE_BOTTOM, p_margin_botton * scale);
+ style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * scale);
style->set_default_margin(SIDE_TOP, p_margin_top * scale);
return style;
@@ -146,12 +179,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// Font Colors
Color control_font_color = Color(0.88, 0.88, 0.88);
- Color control_font_color_lower = Color(0.63, 0.63, 0.63);
- Color control_font_color_low = Color(0.69, 0.69, 0.69);
- Color control_font_color_hover = Color(0.94, 0.94, 0.94);
- Color control_font_color_disabled = Color(0.9, 0.9, 0.9, 0.2);
- Color control_font_color_pressed = Color(1, 1, 1);
- Color font_color_selection = Color(0.49, 0.49, 0.49);
+ Color control_font_lower_color = Color(0.63, 0.63, 0.63);
+ Color control_font_low_color = Color(0.69, 0.69, 0.69);
+ Color control_font_hover_color = Color(0.94, 0.94, 0.94);
+ Color control_font_disabled_color = Color(0.9, 0.9, 0.9, 0.2);
+ Color control_font_pressed_color = Color(1, 1, 1);
+
+ Color control_selection_color = Color(0.49, 0.49, 0.49);
// Panel
@@ -184,10 +218,17 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("outline_size", "Button", 0 * scale);
theme->set_color("font_color", "Button", control_font_color);
- theme->set_color("font_color_pressed", "Button", control_font_color_pressed);
- theme->set_color("font_color_hover", "Button", control_font_color_hover);
- theme->set_color("font_color_disabled", "Button", control_font_color_disabled);
- theme->set_color("font_outline_modulate", "Button", Color(1, 1, 1));
+ theme->set_color("font_pressed_color", "Button", control_font_pressed_color);
+ theme->set_color("font_hover_color", "Button", control_font_hover_color);
+ theme->set_color("font_hover_pressed_color", "Button", control_font_pressed_color);
+ theme->set_color("font_disabled_color", "Button", control_font_disabled_color);
+ theme->set_color("font_outline_color", "Button", Color(1, 1, 1));
+
+ theme->set_color("icon_normal_color", "Button", Color(1, 1, 1, 1));
+ theme->set_color("icon_pressed_color", "Button", Color(1, 1, 1, 1));
+ theme->set_color("icon_hover_color", "Button", Color(1, 1, 1, 1));
+ theme->set_color("icon_hover_pressed_color", "Button", Color(1, 1, 1, 1));
+ theme->set_color("icon_disabled_color", "Button", Color(1, 1, 1, 1));
theme->set_constant("hseparation", "Button", 2 * scale);
@@ -199,9 +240,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "LinkButton", -1);
theme->set_color("font_color", "LinkButton", control_font_color);
- theme->set_color("font_color_pressed", "LinkButton", control_font_color_pressed);
- theme->set_color("font_color_hover", "LinkButton", control_font_color_hover);
+ theme->set_color("font_pressed_color", "LinkButton", control_font_pressed_color);
+ theme->set_color("font_hover_color", "LinkButton", control_font_hover_color);
+ theme->set_color("font_outline_color", "LinkButton", Color(1, 1, 1));
+ theme->set_constant("outline_size", "LinkButton", 0);
theme->set_constant("underline_spacing", "LinkButton", 2 * scale);
// ColorPickerButton
@@ -216,11 +259,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "ColorPickerButton", -1);
theme->set_color("font_color", "ColorPickerButton", Color(1, 1, 1, 1));
- theme->set_color("font_color_pressed", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1));
- theme->set_color("font_color_hover", "ColorPickerButton", Color(1, 1, 1, 1));
- theme->set_color("font_color_disabled", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3));
+ theme->set_color("font_pressed_color", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1));
+ theme->set_color("font_hover_color", "ColorPickerButton", Color(1, 1, 1, 1));
+ theme->set_color("font_disabled_color", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3));
+ theme->set_color("font_outline_color", "ColorPickerButton", Color(1, 1, 1));
theme->set_constant("hseparation", "ColorPickerButton", 2 * scale);
+ theme->set_constant("outline_size", "ColorPickerButton", 0);
// OptionButton
@@ -253,12 +298,14 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "OptionButton", -1);
theme->set_color("font_color", "OptionButton", control_font_color);
- theme->set_color("font_color_pressed", "OptionButton", control_font_color_pressed);
- theme->set_color("font_color_hover", "OptionButton", control_font_color_hover);
- theme->set_color("font_color_disabled", "OptionButton", control_font_color_disabled);
+ theme->set_color("font_pressed_color", "OptionButton", control_font_pressed_color);
+ theme->set_color("font_hover_color", "OptionButton", control_font_hover_color);
+ theme->set_color("font_disabled_color", "OptionButton", control_font_disabled_color);
+ theme->set_color("font_outline_color", "OptionButton", Color(1, 1, 1));
theme->set_constant("hseparation", "OptionButton", 2 * scale);
theme->set_constant("arrow_margin", "OptionButton", 2 * scale);
+ theme->set_constant("outline_size", "OptionButton", 0);
// MenuButton
@@ -272,11 +319,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "MenuButton", -1);
theme->set_color("font_color", "MenuButton", control_font_color);
- theme->set_color("font_color_pressed", "MenuButton", control_font_color_pressed);
- theme->set_color("font_color_hover", "MenuButton", control_font_color_hover);
- theme->set_color("font_color_disabled", "MenuButton", Color(1, 1, 1, 0.3));
+ theme->set_color("font_pressed_color", "MenuButton", control_font_pressed_color);
+ theme->set_color("font_hover_color", "MenuButton", control_font_hover_color);
+ theme->set_color("font_disabled_color", "MenuButton", Color(1, 1, 1, 0.3));
+ theme->set_color("font_outline_color", "MenuButton", Color(1, 1, 1));
theme->set_constant("hseparation", "MenuButton", 3 * scale);
+ theme->set_constant("outline_size", "MenuButton", 0);
// CheckBox
@@ -307,13 +356,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "CheckBox", -1);
theme->set_color("font_color", "CheckBox", control_font_color);
- theme->set_color("font_color_pressed", "CheckBox", control_font_color_pressed);
- theme->set_color("font_color_hover", "CheckBox", control_font_color_hover);
- theme->set_color("font_color_hover_pressed", "CheckBox", control_font_color_pressed);
- theme->set_color("font_color_disabled", "CheckBox", control_font_color_disabled);
+ theme->set_color("font_pressed_color", "CheckBox", control_font_pressed_color);
+ theme->set_color("font_hover_color", "CheckBox", control_font_hover_color);
+ theme->set_color("font_hover_pressed_color", "CheckBox", control_font_pressed_color);
+ theme->set_color("font_disabled_color", "CheckBox", control_font_disabled_color);
+ theme->set_color("font_outline_color", "CheckBox", Color(1, 1, 1));
theme->set_constant("hseparation", "CheckBox", 4 * scale);
theme->set_constant("check_vadjust", "CheckBox", 0 * scale);
+ theme->set_constant("outline_size", "CheckBox", 0);
// CheckButton
@@ -344,13 +395,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "CheckButton", -1);
theme->set_color("font_color", "CheckButton", control_font_color);
- theme->set_color("font_color_pressed", "CheckButton", control_font_color_pressed);
- theme->set_color("font_color_hover", "CheckButton", control_font_color_hover);
- theme->set_color("font_color_hover_pressed", "CheckButton", control_font_color_pressed);
- theme->set_color("font_color_disabled", "CheckButton", control_font_color_disabled);
+ theme->set_color("font_pressed_color", "CheckButton", control_font_pressed_color);
+ theme->set_color("font_hover_color", "CheckButton", control_font_hover_color);
+ theme->set_color("font_hover_pressed_color", "CheckButton", control_font_pressed_color);
+ theme->set_color("font_disabled_color", "CheckButton", control_font_disabled_color);
+ theme->set_color("font_outline_color", "CheckButton", Color(1, 1, 1));
theme->set_constant("hseparation", "CheckButton", 4 * scale);
theme->set_constant("check_vadjust", "CheckButton", 0 * scale);
+ theme->set_constant("outline_size", "CheckButton", 0);
// Label
@@ -359,12 +412,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "Label", -1);
theme->set_color("font_color", "Label", Color(1, 1, 1));
- theme->set_color("font_color_shadow", "Label", Color(0, 0, 0, 0));
- theme->set_color("font_outline_modulate", "Label", Color(1, 1, 1));
+ theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0));
+ theme->set_color("font_outline_color", "Label", Color(1, 1, 1));
theme->set_constant("shadow_offset_x", "Label", 1 * scale);
theme->set_constant("shadow_offset_y", "Label", 1 * scale);
- theme->set_constant("outline_size", "Label", 0 * scale);
+ theme->set_constant("outline_size", "Label", 0);
theme->set_constant("shadow_outline_size", "Label", 1 * scale);
theme->set_constant("line_spacing", "Label", 3 * scale);
@@ -378,14 +431,16 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "LineEdit", -1);
theme->set_color("font_color", "LineEdit", control_font_color);
- theme->set_color("font_color_selected", "LineEdit", Color(0, 0, 0));
- theme->set_color("font_color_uneditable", "LineEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
- theme->set_color("cursor_color", "LineEdit", control_font_color_hover);
- theme->set_color("selection_color", "LineEdit", font_color_selection);
+ theme->set_color("font_selected_color", "LineEdit", Color(0, 0, 0));
+ theme->set_color("font_uneditable_color", "LineEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
+ theme->set_color("font_outline_color", "LineEdit", Color(1, 1, 1));
+ theme->set_color("cursor_color", "LineEdit", control_font_hover_color);
+ theme->set_color("selection_color", "LineEdit", control_selection_color);
theme->set_color("clear_button_color", "LineEdit", control_font_color);
- theme->set_color("clear_button_color_pressed", "LineEdit", control_font_color_pressed);
+ theme->set_color("clear_button_color_pressed", "LineEdit", control_font_pressed_color);
- theme->set_constant("minimum_spaces", "LineEdit", 12 * scale);
+ theme->set_constant("minimum_character_width", "LineEdit", 4);
+ theme->set_constant("outline_size", "LineEdit", 0);
theme->set_icon("clear", "LineEdit", make_icon(line_edit_clear_png));
@@ -397,8 +452,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font("font", "ProgressBar", Ref<Font>());
theme->set_font_size("font_size", "ProgressBar", -1);
- theme->set_color("font_color", "ProgressBar", control_font_color_hover);
- theme->set_color("font_color_shadow", "ProgressBar", Color(0, 0, 0));
+ theme->set_color("font_color", "ProgressBar", control_font_hover_color);
+ theme->set_color("font_shadow_color", "ProgressBar", Color(0, 0, 0));
+ theme->set_color("font_outline_color", "ProgressBar", Color(1, 1, 1));
+
+ theme->set_constant("outline_size", "ProgressBar", 0);
// TextEdit
@@ -417,12 +475,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("completion_background_color", "TextEdit", Color(0.17, 0.16, 0.2));
theme->set_color("completion_selected_color", "TextEdit", Color(0.26, 0.26, 0.27));
theme->set_color("completion_existing_color", "TextEdit", Color(0.87, 0.87, 0.87, 0.13));
- theme->set_color("completion_scroll_color", "TextEdit", control_font_color_pressed);
+ theme->set_color("completion_scroll_color", "TextEdit", control_font_pressed_color);
theme->set_color("completion_font_color", "TextEdit", Color(0.67, 0.67, 0.67));
theme->set_color("font_color", "TextEdit", control_font_color);
- theme->set_color("font_color_selected", "TextEdit", Color(0, 0, 0));
- theme->set_color("font_color_readonly", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
- theme->set_color("selection_color", "TextEdit", font_color_selection);
+ theme->set_color("font_selected_color", "TextEdit", Color(0, 0, 0));
+ theme->set_color("font_readonly_color", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
+ theme->set_color("font_outline_color", "TextEdit", Color(1, 1, 1));
+ theme->set_color("selection_color", "TextEdit", control_selection_color);
theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4));
theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8));
@@ -435,8 +494,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("completion_max_width", "TextEdit", 50);
theme->set_constant("completion_scroll_width", "TextEdit", 3);
theme->set_constant("line_spacing", "TextEdit", 4 * scale);
+ theme->set_constant("outline_size", "TextEdit", 0);
// CodeEdit
+
theme->set_stylebox("normal", "CodeEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0));
theme->set_stylebox("focus", "CodeEdit", focus);
theme->set_stylebox("read_only", "CodeEdit", make_stylebox(tree_bg_disabled_png, 4, 4, 4, 4, 0, 0, 0, 0));
@@ -457,12 +518,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("completion_background_color", "CodeEdit", Color(0.17, 0.16, 0.2));
theme->set_color("completion_selected_color", "CodeEdit", Color(0.26, 0.26, 0.27));
theme->set_color("completion_existing_color", "CodeEdit", Color(0.87, 0.87, 0.87, 0.13));
- theme->set_color("completion_scroll_color", "CodeEdit", control_font_color_pressed);
+ theme->set_color("completion_scroll_color", "CodeEdit", control_font_pressed_color);
theme->set_color("completion_font_color", "CodeEdit", Color(0.67, 0.67, 0.67));
theme->set_color("font_color", "CodeEdit", control_font_color);
- theme->set_color("font_color_selected", "CodeEdit", Color(0, 0, 0));
- theme->set_color("font_color_readonly", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
- theme->set_color("selection_color", "CodeEdit", font_color_selection);
+ theme->set_color("font_selected_color", "CodeEdit", Color(0, 0, 0));
+ theme->set_color("font_readonly_color", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
+ theme->set_color("font_outline_color", "CodeEdit", Color(1, 1, 1));
+ theme->set_color("selection_color", "CodeEdit", control_selection_color);
theme->set_color("mark_color", "CodeEdit", Color(1.0, 0.4, 0.4, 0.4));
theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8));
theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3));
@@ -480,6 +542,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("completion_max_width", "CodeEdit", 50);
theme->set_constant("completion_scroll_width", "CodeEdit", 3);
theme->set_constant("line_spacing", "CodeEdit", 4 * scale);
+ theme->set_constant("outline_size", "CodeEdit", 0);
Ref<Texture2D> empty_icon = memnew(ImageTexture);
@@ -535,7 +598,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("updown", "SpinBox", make_icon(spinbox_updown_png));
- //scroll container
+ // ScrollContainer
+
Ref<StyleBoxEmpty> empty;
empty.instance();
theme->set_stylebox("bg", "ScrollContainer", empty);
@@ -547,7 +611,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("scaleborder_size", "Window", 4 * scale);
theme->set_font("title_font", "Window", large_font);
+ theme->set_font_size("title_font_size", "Window", -1);
+
theme->set_color("title_color", "Window", Color(0, 0, 0));
+ theme->set_color("title_outline_modulate", "Window", Color(1, 1, 1));
+
+ theme->set_constant("title_outline_size", "Window", 0);
theme->set_constant("title_height", "Window", 20 * scale);
theme->set_constant("resize_margin", "Window", 4 * scale);
@@ -598,13 +667,17 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "PopupMenu", -1);
theme->set_color("font_color", "PopupMenu", control_font_color);
- theme->set_color("font_color_accel", "PopupMenu", Color(0.7, 0.7, 0.7, 0.8));
- theme->set_color("font_color_disabled", "PopupMenu", Color(0.4, 0.4, 0.4, 0.8));
- theme->set_color("font_color_hover", "PopupMenu", control_font_color);
- theme->set_color("font_color_separator", "PopupMenu", control_font_color);
+ theme->set_color("font_accelerator_color", "PopupMenu", Color(0.7, 0.7, 0.7, 0.8));
+ theme->set_color("font_disabled_color", "PopupMenu", Color(0.4, 0.4, 0.4, 0.8));
+ theme->set_color("font_hover_color", "PopupMenu", control_font_color);
+ theme->set_color("font_separator_color", "PopupMenu", control_font_color);
+ theme->set_color("font_outline_color", "PopupMenu", Color(1, 1, 1));
theme->set_constant("hseparation", "PopupMenu", 4 * scale);
theme->set_constant("vseparation", "PopupMenu", 4 * scale);
+ theme->set_constant("outline_size", "PopupMenu", 0);
+ theme->set_constant("item_start_padding", "PopupMenu", 2 * scale);
+ theme->set_constant("item_end_padding", "PopupMenu", 2 * scale);
// GraphNode
@@ -671,12 +744,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "Tree", -1);
theme->set_color("title_button_color", "Tree", control_font_color);
- theme->set_color("font_color", "Tree", control_font_color_low);
- theme->set_color("font_color_selected", "Tree", control_font_color_pressed);
+ theme->set_color("font_color", "Tree", control_font_low_color);
+ theme->set_color("font_selected_color", "Tree", control_font_pressed_color);
+ theme->set_color("font_outline_color", "Tree", Color(1, 1, 1));
theme->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1));
theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2));
theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27));
- theme->set_color("custom_button_font_highlight", "Tree", control_font_color_hover);
+ theme->set_color("custom_button_font_highlight", "Tree", control_font_hover_color);
theme->set_constant("hseparation", "Tree", 4 * scale);
theme->set_constant("vseparation", "Tree", 4 * scale);
@@ -686,8 +760,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("draw_guides", "Tree", 1);
theme->set_constant("scroll_border", "Tree", 4);
theme->set_constant("scroll_speed", "Tree", 12);
+ theme->set_constant("outline_size", "Tree", 0);
// ItemList
+
Ref<StyleBoxTexture> item_selected = make_stylebox(selection_png, 4, 4, 4, 4, 8, 2, 8, 2);
Ref<StyleBoxTexture> item_selected_oof = make_stylebox(selection_oof_png, 4, 4, 4, 4, 8, 2, 8, 2);
@@ -701,14 +777,17 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font("font", "ItemList", Ref<Font>());
theme->set_font_size("font_size", "ItemList", -1);
- theme->set_color("font_color", "ItemList", control_font_color_lower);
- theme->set_color("font_color_selected", "ItemList", control_font_color_pressed);
+ theme->set_color("font_color", "ItemList", control_font_lower_color);
+ theme->set_color("font_selected_color", "ItemList", control_font_pressed_color);
+ theme->set_color("font_outline_color", "ItemList", Color(1, 1, 1));
theme->set_color("guide_color", "ItemList", Color(0, 0, 0, 0.1));
theme->set_stylebox("selected", "ItemList", item_selected_oof);
theme->set_stylebox("selected_focus", "ItemList", item_selected);
theme->set_stylebox("cursor", "ItemList", focus);
theme->set_stylebox("cursor_unfocused", "ItemList", focus);
+ theme->set_constant("outline_size", "ItemList", 0);
+
// TabContainer
Ref<StyleBoxTexture> tc_sb = sb_expand(make_stylebox(tab_container_bg_png, 4, 4, 4, 4, 4, 4, 4, 4), 3, 3, 3, 3);
@@ -716,8 +795,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
tc_sb->set_expand_margin_size(SIDE_TOP, 2 * scale);
tc_sb->set_default_margin(SIDE_TOP, 8 * scale);
- theme->set_stylebox("tab_fg", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2));
- theme->set_stylebox("tab_bg", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3));
+ theme->set_stylebox("tab_selected", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2));
+ theme->set_stylebox("tab_unselected", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3));
theme->set_stylebox("tab_disabled", "TabContainer", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3));
theme->set_stylebox("panel", "TabContainer", tc_sb);
@@ -731,17 +810,19 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font("font", "TabContainer", Ref<Font>());
theme->set_font_size("font_size", "TabContainer", -1);
- theme->set_color("font_color_fg", "TabContainer", control_font_color_hover);
- theme->set_color("font_color_bg", "TabContainer", control_font_color_low);
- theme->set_color("font_color_disabled", "TabContainer", control_font_color_disabled);
+ theme->set_color("font_selected_color", "TabContainer", control_font_hover_color);
+ theme->set_color("font_unselected_color", "TabContainer", control_font_low_color);
+ theme->set_color("font_disabled_color", "TabContainer", control_font_disabled_color);
+ theme->set_color("font_outline_color", "TabContainer", Color(1, 1, 1));
theme->set_constant("side_margin", "TabContainer", 8 * scale);
theme->set_constant("icon_separation", "TabContainer", 4 * scale);
+ theme->set_constant("outline_size", "TabContainer", 0);
// Tabs
- theme->set_stylebox("tab_fg", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2));
- theme->set_stylebox("tab_bg", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3));
+ theme->set_stylebox("tab_selected", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2));
+ theme->set_stylebox("tab_unselected", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3));
theme->set_stylebox("tab_disabled", "Tabs", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3));
theme->set_stylebox("panel", "Tabs", tc_sb);
theme->set_stylebox("button_pressed", "Tabs", make_stylebox(button_pressed_png, 4, 4, 4, 4));
@@ -756,11 +837,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font("font", "Tabs", Ref<Font>());
theme->set_font_size("font_size", "Tabs", -1);
- theme->set_color("font_color_fg", "Tabs", control_font_color_hover);
- theme->set_color("font_color_bg", "Tabs", control_font_color_low);
- theme->set_color("font_color_disabled", "Tabs", control_font_color_disabled);
+ theme->set_color("font_selected_color", "Tabs", control_font_hover_color);
+ theme->set_color("font_unselected_color", "Tabs", control_font_low_color);
+ theme->set_color("font_disabled_color", "Tabs", control_font_disabled_color);
+ theme->set_color("font_outline_color", "Tabs", Color(1, 1, 1));
theme->set_constant("hseparation", "Tabs", 4 * scale);
+ theme->set_constant("outline_size", "Tabs", 0);
// Separators
@@ -801,6 +884,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("color_sample", "ColorPicker", make_icon(color_picker_sample_png));
theme->set_icon("preset_bg", "ColorPicker", make_icon(mini_checkerboard_png));
theme->set_icon("overbright_indicator", "ColorPicker", make_icon(overbright_indicator_png));
+ theme->set_icon("bar_arrow", "ColorPicker", make_icon(bar_arrow_png));
theme->set_icon("bg", "ColorPickerButton", make_icon(mini_checkerboard_png));
@@ -817,10 +901,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("font_size", "TooltipLabel", -1);
theme->set_color("font_color", "TooltipLabel", Color(0, 0, 0));
- theme->set_color("font_color_shadow", "TooltipLabel", Color(0, 0, 0, 0.1));
+ theme->set_color("font_shadow_color", "TooltipLabel", Color(0, 0, 0, 0.1));
+ theme->set_color("font_outline_color", "TooltipLabel", Color(1, 1, 1));
theme->set_constant("shadow_offset_x", "TooltipLabel", 1);
theme->set_constant("shadow_offset_y", "TooltipLabel", 1);
+ theme->set_constant("outline_size", "TooltipLabel", 0);
// RichTextLabel
@@ -840,10 +926,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_font_size("mono_font_size", "RichTextLabel", -1);
theme->set_color("default_color", "RichTextLabel", Color(1, 1, 1));
- theme->set_color("font_color_selected", "RichTextLabel", font_color_selection);
+ theme->set_color("font_selected_color", "RichTextLabel", Color(0, 0, 0));
theme->set_color("selection_color", "RichTextLabel", Color(0.1, 0.1, 1, 0.8));
- theme->set_color("font_color_shadow", "RichTextLabel", Color(0, 0, 0, 0));
+ theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0));
+
+ theme->set_color("font_outline_color", "RichTextLabel", Color(1, 1, 1));
theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * scale);
theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * scale);
@@ -853,9 +941,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("table_hseparation", "RichTextLabel", 3 * scale);
theme->set_constant("table_vseparation", "RichTextLabel", 3 * scale);
+ theme->set_constant("outline_size", "RichTextLabel", 0);
+
theme->set_color("table_odd_row_bg", "RichTextLabel", Color(0, 0, 0, 0));
theme->set_color("table_even_row_bg", "RichTextLabel", Color(0, 0, 0, 0));
theme->set_color("table_border", "RichTextLabel", Color(0, 0, 0, 0));
+
// Containers
theme->set_stylebox("bg", "VSplitContainer", make_stylebox(vsplit_bg_png, 1, 1, 1, 1));
@@ -895,6 +986,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("bezier_len_neg", "GraphEdit", 160 * scale);
// Visual Node Ports
+
theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 48 * scale);
theme->set_constant("port_grab_distance_vertical", "GraphEdit", 6 * scale);
@@ -926,45 +1018,15 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
Ref<StyleBox> default_style;
Ref<Texture2D> default_icon;
Ref<Font> default_font;
- int default_font_size = 16;
+ int default_font_size = 14;
if (p_font.is_valid()) {
default_font = p_font;
} else if (p_hidpi) {
- TextServer::BitmapFontData data;
- data.height = _hidpi_font_height;
- data.ascent = _hidpi_font_ascent;
- data.charcount = _hidpi_font_charcount;
- data.char_rects = &_hidpi_font_charrects[0][0];
- data.kerning_count = _hidpi_font_kerning_pair_count;
- data.kernings = &_hidpi_font_kerning_pairs[0][0];
- data.w = _hidpi_font_img_width;
- data.h = _hidpi_font_img_height;
- data.img = _hidpi_font_img_data;
-
- Ref<FontData> font_data;
- font_data.instance();
- font_data->load_memory((const uint8_t *)&data, sizeof(data), "fnt");
- default_font_size = font_data->get_base_size();
-
+ Ref<FontData> font_data = make_font(_hidpi_font_height, _hidpi_font_ascent, _hidpi_font_charcount, &_hidpi_font_charrects[0][0], _hidpi_font_kerning_pair_count, &_hidpi_font_kerning_pairs[0][0], _hidpi_font_img_width, _hidpi_font_img_height, _hidpi_font_img_data);
default_font.instance();
default_font->add_data(font_data);
} else {
- TextServer::BitmapFontData data;
- data.height = _lodpi_font_height;
- data.ascent = _lodpi_font_ascent;
- data.charcount = _lodpi_font_charcount;
- data.char_rects = &_lodpi_font_charrects[0][0];
- data.kerning_count = _lodpi_font_kerning_pair_count;
- data.kernings = &_lodpi_font_kerning_pairs[0][0];
- data.w = _lodpi_font_img_width;
- data.h = _lodpi_font_img_height;
- data.img = _lodpi_font_img_data;
-
- Ref<FontData> font_data;
- font_data.instance();
- font_data->load_memory((const uint8_t *)&data, sizeof(data), "fnt");
- default_font_size = font_data->get_base_size();
-
+ Ref<FontData> font_data = make_font(_lodpi_font_height, _lodpi_font_ascent, _lodpi_font_charcount, &_lodpi_font_charrects[0][0], _lodpi_font_kerning_pair_count, &_lodpi_font_kerning_pairs[0][0], _lodpi_font_img_width, _lodpi_font_img_height, _lodpi_font_img_data);
default_font.instance();
default_font->add_data(font_data);
}
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index 46f89a9b50..a7b2bec5a4 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index b905c9db69..6b78ba7933 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -14,6 +14,10 @@ static const unsigned char arrow_right_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char bar_arrow_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x14, 0x8, 0x4, 0x0, 0x0, 0x0, 0x2e, 0x6b, 0x75, 0xfc, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x1, 0x73, 0x52, 0x47, 0x42, 0x0, 0xae, 0xce, 0x1c, 0xe9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc0, 0x0, 0x0, 0xe, 0xc0, 0x1, 0x6a, 0xd6, 0x89, 0x9, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0xfc, 0xcf, 0x80, 0x1f, 0x30, 0x8e, 0x20, 0x5, 0x8c, 0x38, 0x24, 0xff, 0x53, 0x5f, 0xc1, 0xb, 0xee, 0x9f, 0x53, 0x18, 0x18, 0xd8, 0x73, 0x24, 0xbe, 0x62, 0x55, 0x70, 0x5f, 0x83, 0x61, 0x15, 0xa3, 0x2e, 0x3, 0x3, 0xc3, 0xd, 0xe6, 0x30, 0xd9, 0xcb, 0x18, 0xa, 0x1e, 0xc6, 0xfd, 0x9f, 0xc6, 0xc0, 0xd, 0x35, 0xea, 0x3b, 0x63, 0x81, 0xfc, 0x2c, 0x14, 0x5, 0xf, 0x2a, 0x18, 0xda, 0xd1, 0x1c, 0x50, 0xa9, 0xd0, 0x1, 0x57, 0xf0, 0x10, 0x53, 0x9a, 0x81, 0x81, 0x81, 0xa1, 0x52, 0xbe, 0x83, 0x81, 0x81, 0xf1, 0x3f, 0x2e, 0x69, 0xa8, 0x12, 0x3a, 0x4, 0x14, 0x0, 0x7b, 0xda, 0x34, 0x1, 0xbb, 0xb5, 0x3e, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char bookmark_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0xa, 0xc0, 0x30, 0xc, 0x3, 0xa5, 0xd0, 0xff, 0x7f, 0x59, 0x1d, 0x8a, 0x42, 0x8, 0x9, 0x95, 0xc9, 0xd2, 0xa1, 0x9a, 0x8c, 0xf1, 0xdd, 0x62, 0x1b, 0x38, 0xc, 0x87, 0x5a, 0x5, 0xae, 0x79, 0xde, 0x2, 0x1, 0x80, 0x94, 0x39, 0x48, 0x76, 0x49, 0x17, 0xa4, 0xf0, 0x24, 0x61, 0x2b, 0x51, 0x8b, 0xfc, 0x82, 0xcf, 0xb, 0x48, 0x7a, 0xdf, 0x75, 0x81, 0xf, 0xe5, 0x29, 0xf7, 0x92, 0x6b, 0x3, 0x1a, 0x1e, 0xda, 0x7c, 0x3d, 0x77, 0x21, 0x7b, 0xa8, 0x74, 0x2e, 0xcb, 0xd, 0xc8, 0x75, 0x13, 0x28, 0x9, 0xed, 0xc2, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/default_theme/xpmfix.sh b/scene/resources/default_theme/xpmfix.sh
deleted file mode 100755
index a24dede3c9..0000000000
--- a/scene/resources/default_theme/xpmfix.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-sed -i 's/static char/static const char/g' *.xpm
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 32840dd373..c04b271d81 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,7 +44,7 @@ RID Environment::get_rid() const {
void Environment::set_background(BGMode p_bg) {
bg_mode = p_bg;
RS::get_singleton()->environment_set_background(environment, RS::EnvironmentBG(p_bg));
- _change_notify();
+ notify_property_list_changed();
if (bg_mode != BG_SKY) {
set_fog_aerial_perspective(0.0);
}
@@ -138,7 +138,7 @@ Color Environment::get_ambient_light_color() const {
void Environment::set_ambient_source(AmbientSource p_source) {
ambient_source = p_source;
_update_ambient_light();
- _change_notify();
+ notify_property_list_changed();
}
Environment::AmbientSource Environment::get_ambient_source() const {
@@ -166,7 +166,7 @@ float Environment::get_ambient_light_sky_contribution() const {
void Environment::set_reflection_source(ReflectionSource p_source) {
reflection_source = p_source;
_update_ambient_light();
- _change_notify();
+ notify_property_list_changed();
}
Environment::ReflectionSource Environment::get_reflection_source() const {
@@ -224,7 +224,7 @@ float Environment::get_tonemap_white() const {
void Environment::set_tonemap_auto_exposure_enabled(bool p_enabled) {
tonemap_auto_exposure_enabled = p_enabled;
_update_tonemap();
- _change_notify();
+ notify_property_list_changed();
}
bool Environment::is_tonemap_auto_exposure_enabled() const {
@@ -285,7 +285,7 @@ void Environment::_update_tonemap() {
void Environment::set_ssr_enabled(bool p_enabled) {
ssr_enabled = p_enabled;
_update_ssr();
- _change_notify();
+ notify_property_list_changed();
}
bool Environment::is_ssr_enabled() const {
@@ -343,7 +343,7 @@ void Environment::_update_ssr() {
void Environment::set_ssao_enabled(bool p_enabled) {
ssao_enabled = p_enabled;
_update_ssao();
- _change_notify();
+ notify_property_list_changed();
}
bool Environment::is_ssao_enabled() const {
@@ -441,6 +441,7 @@ void Environment::_update_ssao() {
void Environment::set_sdfgi_enabled(bool p_enabled) {
sdfgi_enabled = p_enabled;
_update_sdfgi();
+ notify_property_list_changed();
}
bool Environment::is_sdfgi_enabled() const {
@@ -458,8 +459,6 @@ Environment::SDFGICascades Environment::get_sdfgi_cascades() const {
void Environment::set_sdfgi_min_cell_size(float p_size) {
sdfgi_min_cell_size = p_size;
- _change_notify("sdfgi_max_distance");
- _change_notify("sdfgi_cascade0_distance");
_update_sdfgi();
}
@@ -475,8 +474,6 @@ void Environment::set_sdfgi_max_distance(float p_distance) {
p_distance *= 0.5; //halve for each cascade
}
sdfgi_min_cell_size = p_distance;
- _change_notify("sdfgi_min_cell_size");
- _change_notify("sdfgi_cascade0_distance");
_update_sdfgi();
}
@@ -493,8 +490,6 @@ float Environment::get_sdfgi_max_distance() const {
void Environment::set_sdfgi_cascade0_distance(float p_distance) {
sdfgi_min_cell_size = p_distance / 64.0;
- _change_notify("sdfgi_min_cell_size");
- _change_notify("sdfgi_max_distance");
_update_sdfgi();
}
@@ -520,13 +515,12 @@ bool Environment::is_sdfgi_using_occlusion() const {
return sdfgi_use_occlusion;
}
-void Environment::set_sdfgi_use_multi_bounce(bool p_enabled) {
- sdfgi_use_multibounce = p_enabled;
+void Environment::set_sdfgi_bounce_feedback(float p_amount) {
+ sdfgi_bounce_feedback = p_amount;
_update_sdfgi();
}
-
-bool Environment::is_sdfgi_using_multi_bounce() const {
- return sdfgi_use_multibounce;
+float Environment::get_sdfgi_bounce_feedback() const {
+ return sdfgi_bounce_feedback;
}
void Environment::set_sdfgi_read_sky_light(bool p_enabled) {
@@ -573,7 +567,7 @@ void Environment::_update_sdfgi() {
sdfgi_min_cell_size,
RS::EnvironmentSDFGIYScale(sdfgi_y_scale),
sdfgi_use_occlusion,
- sdfgi_use_multibounce,
+ sdfgi_bounce_feedback,
sdfgi_read_sky_light,
sdfgi_energy,
sdfgi_normal_bias,
@@ -585,7 +579,7 @@ void Environment::_update_sdfgi() {
void Environment::set_glow_enabled(bool p_enabled) {
glow_enabled = p_enabled;
_update_glow();
- _change_notify();
+ notify_property_list_changed();
}
bool Environment::is_glow_enabled() const {
@@ -655,7 +649,7 @@ float Environment::get_glow_bloom() const {
void Environment::set_glow_blend_mode(GlowBlendMode p_mode) {
glow_blend_mode = p_mode;
_update_glow();
- _change_notify();
+ notify_property_list_changed();
}
Environment::GlowBlendMode Environment::get_glow_blend_mode() const {
@@ -723,7 +717,7 @@ void Environment::_update_glow() {
void Environment::set_fog_enabled(bool p_enabled) {
fog_enabled = p_enabled;
_update_fog();
- _change_notify();
+ notify_property_list_changed();
}
bool Environment::is_fog_enabled() const {
@@ -797,13 +791,13 @@ void Environment::_update_fog() {
// Volumetric Fog
void Environment::_update_volumetric_fog() {
- RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, RS::EnvVolumetricFogShadowFilter(volumetric_fog_shadow_filter));
+ RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, volumetric_fog_temporal_reproject, volumetric_fog_temporal_reproject_amount);
}
void Environment::set_volumetric_fog_enabled(bool p_enable) {
volumetric_fog_enabled = p_enable;
_update_volumetric_fog();
- _change_notify();
+ notify_property_list_changed();
}
bool Environment::is_volumetric_fog_enabled() const {
@@ -854,13 +848,20 @@ float Environment::get_volumetric_fog_gi_inject() const {
return volumetric_fog_gi_inject;
}
-void Environment::set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter) {
- volumetric_fog_shadow_filter = p_filter;
+void Environment::set_volumetric_fog_temporal_reprojection_enabled(bool p_enable) {
+ volumetric_fog_temporal_reproject = p_enable;
+ _update_volumetric_fog();
+}
+bool Environment::is_volumetric_fog_temporal_reprojection_enabled() const {
+ return volumetric_fog_temporal_reproject;
+}
+void Environment::set_volumetric_fog_temporal_reprojection_amount(float p_amount) {
+ volumetric_fog_temporal_reproject_amount = p_amount;
_update_volumetric_fog();
}
-Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_filter() const {
- return volumetric_fog_shadow_filter;
+float Environment::get_volumetric_fog_temporal_reprojection_amount() const {
+ return volumetric_fog_temporal_reproject_amount;
}
// Adjustment
@@ -868,7 +869,7 @@ Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_fi
void Environment::set_adjustment_enabled(bool p_enabled) {
adjustment_enabled = p_enabled;
_update_adjustment();
- _change_notify();
+ notify_property_list_changed();
}
bool Environment::is_adjustment_enabled() const {
@@ -983,6 +984,7 @@ void Environment::_validate_property(PropertyInfo &property) const {
"auto_exposure_",
"ss_reflections_",
"ssao_",
+ "sdfgi_",
"glow_",
"adjustment_",
nullptr
@@ -1200,8 +1202,8 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_sdfgi_y_scale"), &Environment::get_sdfgi_y_scale);
ClassDB::bind_method(D_METHOD("set_sdfgi_use_occlusion", "enable"), &Environment::set_sdfgi_use_occlusion);
ClassDB::bind_method(D_METHOD("is_sdfgi_using_occlusion"), &Environment::is_sdfgi_using_occlusion);
- ClassDB::bind_method(D_METHOD("set_sdfgi_use_multi_bounce", "enable"), &Environment::set_sdfgi_use_multi_bounce);
- ClassDB::bind_method(D_METHOD("is_sdfgi_using_multi_bounce"), &Environment::is_sdfgi_using_multi_bounce);
+ ClassDB::bind_method(D_METHOD("set_sdfgi_bounce_feedback", "amount"), &Environment::set_sdfgi_bounce_feedback);
+ ClassDB::bind_method(D_METHOD("get_sdfgi_bounce_feedback"), &Environment::get_sdfgi_bounce_feedback);
ClassDB::bind_method(D_METHOD("set_sdfgi_read_sky_light", "enable"), &Environment::set_sdfgi_read_sky_light);
ClassDB::bind_method(D_METHOD("is_sdfgi_reading_sky_light"), &Environment::is_sdfgi_reading_sky_light);
ClassDB::bind_method(D_METHOD("set_sdfgi_energy", "amount"), &Environment::set_sdfgi_energy);
@@ -1213,9 +1215,9 @@ void Environment::_bind_methods() {
ADD_GROUP("SDFGI", "sdfgi_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_enabled"), "set_sdfgi_enabled", "is_sdfgi_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_multi_bounce"), "set_sdfgi_use_multi_bounce", "is_sdfgi_using_multi_bounce");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_use_occlusion"), "set_sdfgi_use_occlusion", "is_sdfgi_using_occlusion");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sdfgi_read_sky_light"), "set_sdfgi_read_sky_light", "is_sdfgi_reading_sky_light");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_bounce_feedback", PROPERTY_HINT_RANGE, "0,1.99,0.01"), "set_sdfgi_bounce_feedback", "get_sdfgi_bounce_feedback");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_cascades", PROPERTY_HINT_ENUM, "4 Cascades,6 Cascades,8 Cascades"), "set_sdfgi_cascades", "get_sdfgi_cascades");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_min_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_sdfgi_min_cell_size", "get_sdfgi_min_cell_size");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance");
@@ -1317,8 +1319,10 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_volumetric_fog_detail_spread"), &Environment::get_volumetric_fog_detail_spread);
ClassDB::bind_method(D_METHOD("set_volumetric_fog_gi_inject", "gi_inject"), &Environment::set_volumetric_fog_gi_inject);
ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject);
- ClassDB::bind_method(D_METHOD("set_volumetric_fog_shadow_filter", "shadow_filter"), &Environment::set_volumetric_fog_shadow_filter);
- ClassDB::bind_method(D_METHOD("get_volumetric_fog_shadow_filter"), &Environment::get_volumetric_fog_shadow_filter);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_enabled", "enabled"), &Environment::set_volumetric_fog_temporal_reprojection_enabled);
+ ClassDB::bind_method(D_METHOD("is_volumetric_fog_temporal_reprojection_enabled"), &Environment::is_volumetric_fog_temporal_reprojection_enabled);
+ ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_amount", "temporal_reprojection_amount"), &Environment::set_volumetric_fog_temporal_reprojection_amount);
+ ClassDB::bind_method(D_METHOD("get_volumetric_fog_temporal_reprojection_amount"), &Environment::get_volumetric_fog_temporal_reprojection_amount);
ADD_GROUP("Volumetric Fog", "volumetric_fog_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_enabled"), "set_volumetric_fog_enabled", "is_volumetric_fog_enabled");
@@ -1328,7 +1332,9 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "volumetric_fog_shadow_filter", PROPERTY_HINT_ENUM, "Disabled,Low,Medium,High"), "set_volumetric_fog_shadow_filter", "get_volumetric_fog_shadow_filter");
+ ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_temporal_reprojection_amount", PROPERTY_HINT_RANGE, "0.0,0.999,0.001"), "set_volumetric_fog_temporal_reprojection_amount", "get_volumetric_fog_temporal_reprojection_amount");
// Adjustment
@@ -1417,7 +1423,7 @@ Environment::Environment() {
_update_fog();
_update_adjustment();
_update_volumetric_fog();
- _change_notify();
+ notify_property_list_changed();
}
Environment::~Environment() {
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index a720f2cc47..0df2c3cc27 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -103,7 +103,7 @@ private:
// Background
BGMode bg_mode = BG_CLEAR_COLOR;
Ref<Sky> bg_sky;
- float bg_sky_custom_fov = 0;
+ float bg_sky_custom_fov = 0.0;
Vector3 bg_sky_rotation;
Color bg_color;
float bg_energy = 1.0;
@@ -125,7 +125,7 @@ private:
float tonemap_white = 1.0;
bool tonemap_auto_exposure_enabled = false;
float tonemap_auto_exposure_min = 0.05;
- float tonemap_auto_exposure_max = 8;
+ float tonemap_auto_exposure_max = 8.0;
float tonemap_auto_exposure_speed = 0.5;
float tonemap_auto_exposure_grey = 0.4;
void _update_tonemap();
@@ -156,7 +156,7 @@ private:
float sdfgi_min_cell_size = 0.2;
SDFGIYScale sdfgi_y_scale = SDFGI_Y_SCALE_DISABLED;
bool sdfgi_use_occlusion = false;
- bool sdfgi_use_multibounce = false;
+ float sdfgi_bounce_feedback = 0.0;
bool sdfgi_read_sky_light = false;
float sdfgi_energy = 1.0;
float sdfgi_normal_bias = 1.1;
@@ -196,8 +196,9 @@ private:
float volumetric_fog_light_energy = 1.0;
float volumetric_fog_length = 64.0;
float volumetric_fog_detail_spread = 2.0;
- VolumetricFogShadowFilter volumetric_fog_shadow_filter = VOLUMETRIC_FOG_SHADOW_FILTER_LOW;
float volumetric_fog_gi_inject = 0.0;
+ bool volumetric_fog_temporal_reproject = true;
+ float volumetric_fog_temporal_reproject_amount = 0.9;
void _update_volumetric_fog();
// Adjustment
@@ -317,8 +318,8 @@ public:
SDFGIYScale get_sdfgi_y_scale() const;
void set_sdfgi_use_occlusion(bool p_enabled);
bool is_sdfgi_using_occlusion() const;
- void set_sdfgi_use_multi_bounce(bool p_enabled);
- bool is_sdfgi_using_multi_bounce() const;
+ void set_sdfgi_bounce_feedback(float p_amount);
+ float get_sdfgi_bounce_feedback() const;
void set_sdfgi_read_sky_light(bool p_enabled);
bool is_sdfgi_reading_sky_light() const;
void set_sdfgi_energy(float p_energy);
@@ -385,10 +386,12 @@ public:
float get_volumetric_fog_length() const;
void set_volumetric_fog_detail_spread(float p_detail_spread);
float get_volumetric_fog_detail_spread() const;
- void set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter);
- VolumetricFogShadowFilter get_volumetric_fog_shadow_filter() const;
void set_volumetric_fog_gi_inject(float p_gi_inject);
float get_volumetric_fog_gi_inject() const;
+ void set_volumetric_fog_temporal_reprojection_enabled(bool p_enable);
+ bool is_volumetric_fog_temporal_reprojection_enabled() const;
+ void set_volumetric_fog_temporal_reprojection_amount(float p_amount);
+ float get_volumetric_fog_temporal_reprojection_amount() const;
// Adjustment
void set_adjustment_enabled(bool p_enabled);
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 791f260c0e..6f87c524d8 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,6 +39,11 @@
void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_resource", "filename", "base_size"), &FontData::load_resource, DEFVAL(16));
ClassDB::bind_method(D_METHOD("load_memory", "data", "type", "base_size"), &FontData::_load_memory, DEFVAL(16));
+ ClassDB::bind_method(D_METHOD("new_bitmap", "height", "ascent", "base_size"), &FontData::new_bitmap);
+
+ ClassDB::bind_method(D_METHOD("bitmap_add_texture", "texture"), &FontData::bitmap_add_texture);
+ ClassDB::bind_method(D_METHOD("bitmap_add_char", "char", "texture_idx", "rect", "align", "advance"), &FontData::bitmap_add_char);
+ ClassDB::bind_method(D_METHOD("bitmap_add_kerning_pair", "A", "B", "kerning"), &FontData::bitmap_add_kerning_pair);
ClassDB::bind_method(D_METHOD("set_data_path", "path"), &FontData::set_data_path);
ClassDB::bind_method(D_METHOD("get_data_path"), &FontData::get_data_path);
@@ -50,6 +55,9 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_underline_position", "size"), &FontData::get_underline_position);
ClassDB::bind_method(D_METHOD("get_underline_thickness", "size"), &FontData::get_underline_thickness);
+ ClassDB::bind_method(D_METHOD("get_spacing", "type"), &FontData::get_spacing);
+ ClassDB::bind_method(D_METHOD("set_spacing", "type", "value"), &FontData::set_spacing);
+
ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &FontData::set_antialiased);
ClassDB::bind_method(D_METHOD("get_antialiased"), &FontData::get_antialiased);
@@ -100,6 +108,13 @@ void FontData::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_field_hint"), "set_distance_field_hint", "get_distance_field_hint");
ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting");
+
+ ADD_GROUP("Extra Spacing", "extra_spacing");
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_glyph"), "set_spacing", "get_spacing", SPACING_GLYPH);
+ ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_space"), "set_spacing", "get_spacing", SPACING_SPACE);
+
+ BIND_ENUM_CONSTANT(SPACING_GLYPH);
+ BIND_ENUM_CONSTANT(SPACING_SPACE);
}
bool FontData::_set(const StringName &p_name, const Variant &p_value) {
@@ -177,6 +192,14 @@ void FontData::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
+void FontData::reset_state() {
+ if (rid != RID()) {
+ TS->free(rid);
+ }
+ base_size = 16;
+ path = String();
+}
+
RID FontData::get_rid() const {
return rid;
}
@@ -211,6 +234,34 @@ void FontData::load_memory(const uint8_t *p_data, size_t p_size, const String &p
emit_changed();
}
+void FontData::new_bitmap(float p_height, float p_ascent, int p_base_size) {
+ if (rid != RID()) {
+ TS->free(rid);
+ }
+ rid = TS->create_font_bitmap(p_height, p_ascent, p_base_size);
+ path = TTR("(Bitmap: " + String::num_int64(rid.get_id(), 16, true) + ")");
+ base_size = TS->font_get_base_size(rid);
+ emit_changed();
+}
+
+void FontData::bitmap_add_texture(const Ref<Texture> &p_texture) {
+ if (rid != RID()) {
+ TS->font_bitmap_add_texture(rid, p_texture);
+ }
+}
+
+void FontData::bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
+ if (rid != RID()) {
+ TS->font_bitmap_add_char(rid, p_char, p_texture_idx, p_rect, p_align, p_advance);
+ }
+}
+
+void FontData::bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) {
+ if (rid != RID()) {
+ TS->font_bitmap_add_kerning_pair(rid, p_A, p_B, p_kerning);
+ }
+}
+
void FontData::set_data_path(const String &p_path) {
load_resource(p_path, base_size);
}
@@ -281,6 +332,27 @@ double FontData::get_variation(const String &p_name) const {
return TS->font_get_variation(rid, p_name);
}
+int FontData::get_spacing(int p_type) const {
+ if (rid == RID()) {
+ return 0;
+ }
+ if (p_type == SPACING_GLYPH) {
+ return TS->font_get_spacing_glyph(rid);
+ } else {
+ return TS->font_get_spacing_space(rid);
+ }
+}
+
+void FontData::set_spacing(int p_type, int p_value) {
+ ERR_FAIL_COND(rid == RID());
+ if (p_type == SPACING_GLYPH) {
+ TS->font_set_spacing_glyph(rid, p_value);
+ } else {
+ TS->font_set_spacing_space(rid, p_value);
+ }
+ emit_changed();
+}
+
void FontData::set_antialiased(bool p_antialiased) {
ERR_FAIL_COND(rid == RID());
TS->font_set_antialiased(rid, p_antialiased);
@@ -509,7 +581,7 @@ void Font::_data_changed() {
cache_wrap.clear();
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
bool Font::_set(const StringName &p_name, const Variant &p_value) {
@@ -588,6 +660,14 @@ void Font::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, "data/" + itos(data.size()), PROPERTY_HINT_RESOURCE_TYPE, "FontData"));
}
+void Font::reset_state() {
+ spacing_top = 0;
+ spacing_bottom = 0;
+ cache.clear();
+ cache_wrap.clear();
+ data.clear();
+}
+
void Font::add_data(const Ref<FontData> &p_data) {
ERR_FAIL_COND(p_data.is_null());
data.push_back(p_data);
@@ -600,7 +680,7 @@ void Font::add_data(const Ref<FontData> &p_data) {
cache_wrap.clear();
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
void Font::set_data(int p_idx, const Ref<FontData> &p_data) {
@@ -621,7 +701,7 @@ void Font::set_data(int p_idx, const Ref<FontData> &p_data) {
cache_wrap.clear();
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
int Font::get_data_count() const {
@@ -646,7 +726,7 @@ void Font::remove_data(int p_idx) {
cache_wrap.clear();
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
Dictionary Font::get_feature_list() const {
@@ -718,13 +798,13 @@ void Font::set_spacing(int p_type, int p_value) {
}
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
// Drawing string and string sizes, cached.
Size2 Font::get_string_size(const String &p_text, int p_size) const {
- ERR_FAIL_COND_V(data.empty(), Size2());
+ ERR_FAIL_COND_V(data.is_empty(), Size2());
uint64_t hash = p_text.hash64();
hash = hash_djb2_one_64(p_size, hash);
@@ -746,7 +826,7 @@ Size2 Font::get_string_size(const String &p_text, int p_size) const {
}
Size2 Font::get_multiline_string_size(const String &p_text, float p_width, int p_size, uint8_t p_flags) const {
- ERR_FAIL_COND_V(data.empty(), Size2());
+ ERR_FAIL_COND_V(data.is_empty(), Size2());
uint64_t hash = p_text.hash64();
hash = hash_djb2_one_64(p_size, hash);
@@ -781,6 +861,8 @@ Size2 Font::get_multiline_string_size(const String &p_text, float p_width, int p
}
void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
+ ERR_FAIL_COND(data.is_empty());
+
uint64_t hash = p_text.hash64();
hash = hash_djb2_one_64(p_size, hash);
@@ -811,6 +893,8 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t
}
void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const {
+ ERR_FAIL_COND(data.is_empty());
+
uint64_t hash = p_text.hash64();
hash = hash_djb2_one_64(p_size, hash);
@@ -951,7 +1035,7 @@ Font::~Font() {
/*************************************************************************/
-RES ResourceFormatLoaderFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
@@ -1006,7 +1090,7 @@ String ResourceFormatLoaderFont::get_resource_type(const String &p_path) const {
#ifndef DISABLE_DEPRECATED
-RES ResourceFormatLoaderCompatFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderCompatFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
diff --git a/scene/resources/font.h b/scene/resources/font.h
index fe28e1aea5..200373aa8c 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,6 +42,13 @@
class FontData : public Resource {
GDCLASS(FontData, Resource);
+public:
+ enum SpacingType {
+ SPACING_GLYPH,
+ SPACING_SPACE,
+ };
+
+private:
RID rid;
int base_size = 16;
String path;
@@ -53,6 +60,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
+
public:
virtual RID get_rid() const override;
@@ -60,6 +69,12 @@ public:
void load_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16);
void _load_memory(const PackedByteArray &p_data, const String &p_type, int p_base_size = 16);
+ void new_bitmap(float p_height, float p_ascent, int p_base_size = 16);
+
+ void bitmap_add_texture(const Ref<Texture> &p_texture);
+ void bitmap_add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance);
+ void bitmap_add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning);
+
void set_data_path(const String &p_path);
String get_data_path() const;
@@ -76,6 +91,9 @@ public:
float get_underline_position(int p_size) const;
float get_underline_thickness(int p_size) const;
+ int get_spacing(int p_type) const;
+ void set_spacing(int p_type, int p_value);
+
void set_antialiased(bool p_antialiased);
bool get_antialiased() const;
@@ -132,7 +150,7 @@ class Font : public Resource {
public:
enum SpacingType {
SPACING_TOP,
- SPACING_BOTTOM
+ SPACING_BOTTOM,
};
private:
@@ -151,6 +169,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
+
void _data_changed();
public:
@@ -195,13 +215,14 @@ public:
~Font();
};
+VARIANT_ENUM_CAST(FontData::SpacingType);
VARIANT_ENUM_CAST(Font::SpacingType);
/*************************************************************************/
class ResourceFormatLoaderFont : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
@@ -212,7 +233,7 @@ public:
class ResourceFormatLoaderCompatFont : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp
index 6b41b97e45..7b9b942142 100644
--- a/scene/resources/gradient.cpp
+++ b/scene/resources/gradient.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,7 +39,6 @@ Gradient::Gradient() {
points.write[0].offset = 0;
points.write[1].color = Color(1, 1, 1, 1);
points.write[1].offset = 1;
- is_sorted = true;
}
Gradient::~Gradient() {
@@ -47,7 +46,7 @@ Gradient::~Gradient() {
void Gradient::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &Gradient::add_point);
- ClassDB::bind_method(D_METHOD("remove_point", "offset"), &Gradient::remove_point);
+ ClassDB::bind_method(D_METHOD("remove_point", "point"), &Gradient::remove_point);
ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &Gradient::set_offset);
ClassDB::bind_method(D_METHOD("get_offset", "point"), &Gradient::get_offset);
diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h
index e839909770..cf5b179c45 100644
--- a/scene/resources/gradient.h
+++ b/scene/resources/gradient.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,7 +39,7 @@ class Gradient : public Resource {
public:
struct Point {
- float offset;
+ float offset = 0.0;
Color color;
bool operator<(const Point &p_ponit) const {
return offset < p_ponit.offset;
@@ -48,7 +48,7 @@ public:
private:
Vector<Point> points;
- bool is_sorted;
+ bool is_sorted = true;
_FORCE_INLINE_ void _update_sorting() {
if (!is_sorted) {
points.sort();
@@ -82,7 +82,7 @@ public:
Vector<Color> get_colors() const;
_FORCE_INLINE_ Color get_color_at_offset(float p_offset) {
- if (points.empty()) {
+ if (points.is_empty()) {
return Color(0, 0, 0, 1);
}
diff --git a/scene/resources/height_map_shape_3d.cpp b/scene/resources/height_map_shape_3d.cpp
index 2ae47bcf3c..5593bb766f 100644
--- a/scene/resources/height_map_shape_3d.cpp
+++ b/scene/resources/height_map_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -107,8 +107,6 @@ void HeightMapShape3D::set_map_width(int p_new) {
_update_shape();
notify_change_to_owners();
- _change_notify("map_width");
- _change_notify("map_data");
}
}
@@ -133,8 +131,6 @@ void HeightMapShape3D::set_map_depth(int p_new) {
_update_shape();
notify_change_to_owners();
- _change_notify("map_depth");
- _change_notify("map_data");
}
}
@@ -171,7 +167,6 @@ void HeightMapShape3D::set_map_data(PackedFloat32Array p_new) {
_update_shape();
notify_change_to_owners();
- _change_notify("map_data");
}
PackedFloat32Array HeightMapShape3D::get_map_data() const {
@@ -193,16 +188,12 @@ void HeightMapShape3D::_bind_methods() {
HeightMapShape3D::HeightMapShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_HEIGHTMAP)) {
- map_width = 2;
- map_depth = 2;
map_data.resize(map_width * map_depth);
real_t *w = map_data.ptrw();
w[0] = 0.0;
w[1] = 0.0;
w[2] = 0.0;
w[3] = 0.0;
- min_height = 0.0;
- max_height = 0.0;
_update_shape();
}
diff --git a/scene/resources/height_map_shape_3d.h b/scene/resources/height_map_shape_3d.h
index 9ee8b49689..6fc88cff90 100644
--- a/scene/resources/height_map_shape_3d.h
+++ b/scene/resources/height_map_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,11 +36,11 @@
class HeightMapShape3D : public Shape3D {
GDCLASS(HeightMapShape3D, Shape3D);
- int map_width;
- int map_depth;
+ int map_width = 2;
+ int map_depth = 2;
PackedFloat32Array map_data;
- float min_height;
- float max_height;
+ float min_height = 0.0;
+ float max_height = 0.0;
protected:
static void _bind_methods();
diff --git a/scene/resources/line_shape_2d.cpp b/scene/resources/line_shape_2d.cpp
index 58653c5f4a..d206f12287 100644
--- a/scene/resources/line_shape_2d.cpp
+++ b/scene/resources/line_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
bool LineShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
Vector2 point = get_distance() * get_normal();
- Vector2 l[2][2] = { { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 }, { point, point + get_normal() * 30 } };
+ Vector2 l[2][2] = { { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 }, { point, point + get_normal() * 30 } };
for (int i = 0; i < 2; i++) {
Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, l[i]);
@@ -77,7 +77,7 @@ real_t LineShape2D::get_distance() const {
void LineShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Vector2 point = get_distance() * get_normal();
- Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 };
+ Vector2 l1[2] = { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 };
RS::get_singleton()->canvas_item_add_line(p_to_rid, l1[0], l1[1], p_color, 3);
Vector2 l2[2] = { point, point + get_normal() * 30 };
RS::get_singleton()->canvas_item_add_line(p_to_rid, l2[0], l2[1], p_color, 3);
@@ -86,7 +86,7 @@ void LineShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Rect2 LineShape2D::get_rect() const {
Vector2 point = get_distance() * get_normal();
- Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 };
+ Vector2 l1[2] = { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 };
Vector2 l2[2] = { point, point + get_normal() * 30 };
Rect2 rect;
rect.position = l1[0];
@@ -113,7 +113,5 @@ void LineShape2D::_bind_methods() {
LineShape2D::LineShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->line_shape_create()) {
- normal = Vector2(0, 1);
- distance = 0;
_update_shape();
}
diff --git a/scene/resources/line_shape_2d.h b/scene/resources/line_shape_2d.h
index 7e67a8f67c..9f0405ad29 100644
--- a/scene/resources/line_shape_2d.h
+++ b/scene/resources/line_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,8 +36,8 @@
class LineShape2D : public Shape2D {
GDCLASS(LineShape2D, Shape2D);
- Vector2 normal;
- real_t distance;
+ Vector2 normal = Vector2(0, 1);
+ real_t distance = 0.0;
void _update_shape();
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 6e08af23f5..9931757cc4 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,6 +36,7 @@
#include "editor/editor_settings.h"
#endif
+#include "scene/main/scene_tree.h"
#include "scene/scene_string_names.h"
void Material::set_next_pass(const Ref<Material> &p_pass) {
@@ -80,6 +81,14 @@ void Material::_validate_property(PropertyInfo &property) const {
}
}
+void Material::inspect_native_shader_code() {
+ SceneTree *st = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop());
+ RID shader = get_shader_rid();
+ if (st && shader.is_valid()) {
+ st->call_group("_native_shader_source_visualizer", "_inspect_shader", shader);
+ }
+}
+
void Material::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass);
ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass);
@@ -87,6 +96,9 @@ void Material::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &Material::set_render_priority);
ClassDB::bind_method(D_METHOD("get_render_priority"), &Material::get_render_priority);
+ ClassDB::bind_method(D_METHOD("inspect_native_shader_code"), &Material::inspect_native_shader_code);
+ ClassDB::set_method_flags(get_class_static(), _scs_create("inspect_native_shader_code"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass");
@@ -180,7 +192,7 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) {
void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
// Only connect/disconnect the signal when running in the editor.
- // This can be a slow operation, and `_change_notify()` (which is called by `_shader_changed()`)
+ // This can be a slow operation, and `notify_property_list_changed()` (which is called by `_shader_changed()`)
// does nothing in non-editor builds anyway. See GH-34741 for details.
if (shader.is_valid() && Engine::get_singleton()->is_editor_hint()) {
shader->disconnect("changed", callable_mp(this, &ShaderMaterial::_shader_changed));
@@ -198,7 +210,7 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
}
RS::get_singleton()->material_set_shader(_get_material(), rid);
- _change_notify(); //properties for shader exposed
+ notify_property_list_changed(); //properties for shader exposed
emit_changed();
}
@@ -215,7 +227,7 @@ Variant ShaderMaterial::get_shader_param(const StringName &p_param) const {
}
void ShaderMaterial::_shader_changed() {
- _change_notify(); //update all properties
+ notify_property_list_changed(); //update all properties
}
void ShaderMaterial::_bind_methods() {
@@ -260,6 +272,13 @@ Shader::Mode ShaderMaterial::get_shader_mode() const {
return Shader::MODE_SPATIAL;
}
}
+RID ShaderMaterial::get_shader_rid() const {
+ if (shader.is_valid()) {
+ return shader->get_rid();
+ } else {
+ return RID();
+ }
+}
ShaderMaterial::ShaderMaterial() {
}
@@ -716,7 +735,7 @@ void BaseMaterial3D::_update_shader() {
if (flags[FLAG_SRGB_VERTEX_COLOR]) {
code += "\tif (!OUTPUT_IS_SRGB) {\n";
- code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n";
+ code += "\t\tCOLOR.rgb = mix(pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb * (1.0 / 12.92), lessThan(COLOR.rgb, vec3(0.04045)));\n";
code += "\t}\n";
}
if (flags[FLAG_USE_POINT_SIZE]) {
@@ -969,11 +988,11 @@ void BaseMaterial3D::_update_shader() {
if (features[FEATURE_NORMAL_MAPPING]) {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tNORMALMAP = triplanar_texture(texture_normal,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
+ code += "\tNORMAL_MAP = triplanar_texture(texture_normal,uv1_power_normal,uv1_triplanar_pos).rgb;\n";
} else {
- code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n";
+ code += "\tNORMAL_MAP = texture(texture_normal,base_uv).rgb;\n";
}
- code += "\tNORMALMAP_DEPTH = normal_scale;\n";
+ code += "\tNORMAL_MAP_DEPTH = normal_scale;\n";
}
if (features[FEATURE_EMISSION]) {
@@ -1000,7 +1019,7 @@ void BaseMaterial3D::_update_shader() {
if (features[FEATURE_REFRACTION]) {
if (features[FEATURE_NORMAL_MAPPING]) {
- code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) );\n";
+ code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMAL_MAP.x + BINORMAL * NORMAL_MAP.y + NORMAL * NORMAL_MAP.z,NORMAL_MAP_DEPTH) );\n";
} else {
code += "\tvec3 ref_normal = NORMAL;\n";
}
@@ -1198,8 +1217,8 @@ void BaseMaterial3D::_update_shader() {
break; // Internal value, skip.
}
- code += "\tvec3 detail_norm = mix(NORMALMAP,detail_norm_tex.rgb,detail_tex.a);\n";
- code += "\tNORMALMAP = mix(NORMALMAP,detail_norm,detail_mask_tex.r);\n";
+ code += "\tvec3 detail_norm = mix(NORMAL_MAP,detail_norm_tex.rgb,detail_tex.a);\n";
+ code += "\tNORMAL_MAP = mix(NORMAL_MAP,detail_norm,detail_mask_tex.r);\n";
code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
}
@@ -1470,7 +1489,7 @@ void BaseMaterial3D::set_transparency(Transparency p_transparency) {
transparency = p_transparency;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const {
@@ -1484,7 +1503,7 @@ void BaseMaterial3D::set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa) {
alpha_antialiasing_mode = p_alpha_aa;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
BaseMaterial3D::AlphaAntiAliasing BaseMaterial3D::get_alpha_antialiasing() const {
@@ -1498,7 +1517,7 @@ void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) {
shading_mode = p_shading_mode;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const {
@@ -1565,8 +1584,8 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
}
flags[p_flag] = p_enabled;
- if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN) {
- _change_notify();
+ if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN || p_flag == FLAG_USE_POINT_SIZE) {
+ notify_property_list_changed();
}
_queue_shader_change();
}
@@ -1583,7 +1602,7 @@ void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {
}
features[p_feature] = p_enabled;
- _change_notify();
+ notify_property_list_changed();
_queue_shader_change();
}
@@ -1601,7 +1620,7 @@ void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_t
RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size,
Vector2i(p_texture->get_width(), p_texture->get_height()));
}
- _change_notify();
+ notify_property_list_changed();
_queue_shader_change();
}
@@ -1631,7 +1650,7 @@ BaseMaterial3D::TextureFilter BaseMaterial3D::get_texture_filter() const {
void BaseMaterial3D::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const {
if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) {
- property.usage = 0;
+ property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
@@ -1664,16 +1683,24 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- if (property.name == "params_grow_amount" && !grow_enabled) {
- property.usage = 0;
+ if (property.name == "billboard_keep_scale" && billboard_mode == BILLBOARD_DISABLED) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+
+ if (property.name == "grow_amount" && !grow_enabled) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+
+ if (property.name == "point_size" && !flags[FLAG_USE_POINT_SIZE]) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
}
if (property.name == "proximity_fade_distance" && !proximity_fade_enabled) {
- property.usage = 0;
+ property.usage = PROPERTY_USAGE_NOEDITOR;
}
if ((property.name == "distance_fade_max_distance" || property.name == "distance_fade_min_distance") && distance_fade == DISTANCE_FADE_DISABLED) {
- property.usage = 0;
+ property.usage = PROPERTY_USAGE_NOEDITOR;
}
// you can only enable anti-aliasing (in mataerials) on alpha scissor and alpha hash
@@ -1841,7 +1868,7 @@ float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const {
void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) {
billboard_mode = p_mode;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const {
@@ -1878,7 +1905,7 @@ bool BaseMaterial3D::get_particles_anim_loop() const {
void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) {
deep_parallax = p_enable;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const {
@@ -1924,7 +1951,7 @@ bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const {
void BaseMaterial3D::set_grow_enabled(bool p_enable) {
grow_enabled = p_enable;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
bool BaseMaterial3D::is_grow_enabled() const {
@@ -2074,7 +2101,7 @@ void BaseMaterial3D::set_on_top_of_alpha() {
void BaseMaterial3D::set_proximity_fade(bool p_enable) {
proximity_fade_enabled = p_enable;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
bool BaseMaterial3D::is_proximity_fade_enabled() const {
@@ -2093,7 +2120,7 @@ float BaseMaterial3D::get_proximity_fade_distance() const {
void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) {
distance_fade = p_mode;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const {
@@ -2636,9 +2663,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
element(this) {
orm = p_orm;
// Initialize to the same values as the shader
- shading_mode = SHADING_MODE_PER_PIXEL;
- transparency = TRANSPARENCY_DISABLED;
- alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF;
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
set_specular(0.5);
set_roughness(1.0);
@@ -2670,7 +2694,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
set_particles_anim_h_frames(1);
set_particles_anim_v_frames(1);
set_particles_anim_loop(false);
- emission_op = EMISSION_OP_ADD;
set_transparency(TRANSPARENCY_DISABLED);
set_alpha_antialiasing(ALPHA_ANTIALIASING_OFF);
@@ -2678,8 +2701,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
set_alpha_hash_scale(1.0);
set_alpha_antialiasing_edge(0.3);
- proximity_fade_enabled = false;
- distance_fade = DISTANCE_FADE_DISABLED;
set_proximity_fade_distance(1);
set_distance_fade_min_distance(0);
set_distance_fade_max_distance(10);
@@ -2691,35 +2712,14 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
set_ao_texture_channel(TEXTURE_CHANNEL_RED);
set_refraction_texture_channel(TEXTURE_CHANNEL_RED);
- grow_enabled = false;
set_grow(0.0);
- deep_parallax = false;
- heightmap_parallax_flip_tangent = false;
- heightmap_parallax_flip_binormal = false;
set_heightmap_deep_parallax_min_layers(8);
set_heightmap_deep_parallax_max_layers(32);
set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal
- detail_uv = DETAIL_UV_1;
- blend_mode = BLEND_MODE_MIX;
- detail_blend_mode = BLEND_MODE_MIX;
- depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY;
- cull_mode = CULL_BACK;
- for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = false;
- }
flags[FLAG_USE_TEXTURE_REPEAT] = true;
- diffuse_mode = DIFFUSE_BURLEY;
- specular_mode = SPECULAR_SCHLICK_GGX;
-
- for (int i = 0; i < FEATURE_MAX; i++) {
- features[i] = false;
- }
-
- texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
-
_queue_shader_change();
}
diff --git a/scene/resources/material.h b/scene/resources/material.h
index caf28eea18..70452a5f74 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,6 +47,8 @@ class Material : public Resource {
Ref<Material> next_pass;
int render_priority;
+ void inspect_native_shader_code();
+
protected:
_FORCE_INLINE_ RID _get_material() const { return material; }
static void _bind_methods();
@@ -66,6 +68,7 @@ public:
int get_render_priority() const;
virtual RID get_rid() const override;
+ virtual RID get_shader_rid() const = 0;
virtual Shader::Mode get_shader_mode() const = 0;
Material();
@@ -100,6 +103,8 @@ public:
virtual Shader::Mode get_shader_mode() const override;
+ virtual RID get_shader_rid() const override;
+
ShaderMaterial();
~ShaderMaterial();
};
@@ -325,7 +330,7 @@ private:
struct ShaderData {
RID shader;
- int users;
+ int users = 0;
};
static Map<MaterialKey, ShaderData> shader_map;
@@ -463,16 +468,16 @@ private:
float alpha_scissor_threshold;
float alpha_hash_scale;
float alpha_antialiasing_edge;
- bool grow_enabled;
+ bool grow_enabled = false;
float ao_light_affect;
float grow;
int particles_anim_h_frames;
int particles_anim_v_frames;
bool particles_anim_loop;
- Transparency transparency;
- ShadingMode shading_mode;
+ Transparency transparency = TRANSPARENCY_DISABLED;
+ ShadingMode shading_mode = SHADING_MODE_PER_PIXEL;
- TextureFilter texture_filter;
+ TextureFilter texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
Vector3 uv1_scale;
Vector3 uv1_offset;
@@ -482,39 +487,39 @@ private:
Vector3 uv2_offset;
float uv2_triplanar_sharpness;
- DetailUV detail_uv;
+ DetailUV detail_uv = DETAIL_UV_1;
- bool deep_parallax;
+ bool deep_parallax = false;
int deep_parallax_min_layers;
int deep_parallax_max_layers;
- bool heightmap_parallax_flip_tangent;
- bool heightmap_parallax_flip_binormal;
+ bool heightmap_parallax_flip_tangent = false;
+ bool heightmap_parallax_flip_binormal = false;
- bool proximity_fade_enabled;
+ bool proximity_fade_enabled = false;
float proximity_fade_distance;
- DistanceFadeMode distance_fade;
+ DistanceFadeMode distance_fade = DISTANCE_FADE_DISABLED;
float distance_fade_max_distance;
float distance_fade_min_distance;
- BlendMode blend_mode;
- BlendMode detail_blend_mode;
- DepthDrawMode depth_draw_mode;
- CullMode cull_mode;
- bool flags[FLAG_MAX];
- SpecularMode specular_mode;
- DiffuseMode diffuse_mode;
+ BlendMode blend_mode = BLEND_MODE_MIX;
+ BlendMode detail_blend_mode = BLEND_MODE_MIX;
+ DepthDrawMode depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY;
+ CullMode cull_mode = CULL_BACK;
+ bool flags[FLAG_MAX] = {};
+ SpecularMode specular_mode = SPECULAR_SCHLICK_GGX;
+ DiffuseMode diffuse_mode = DIFFUSE_BURLEY;
BillboardMode billboard_mode;
- EmissionOperator emission_op;
+ EmissionOperator emission_op = EMISSION_OP_ADD;
TextureChannel metallic_texture_channel;
TextureChannel roughness_texture_channel;
TextureChannel ao_texture_channel;
TextureChannel refraction_texture_channel;
- AlphaAntiAliasing alpha_antialiasing_mode;
+ AlphaAntiAliasing alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF;
- bool features[FEATURE_MAX];
+ bool features[FEATURE_MAX] = {};
Ref<Texture2D> textures[TEXTURE_MAX];
@@ -736,7 +741,7 @@ public:
static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false);
- RID get_shader_rid() const;
+ virtual RID get_shader_rid() const override;
virtual Shader::Mode get_shader_mode() const override;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index f1c05b8014..1a2b21299a 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -74,7 +74,7 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
}
Array a = surface_get_arrays(i);
- ERR_FAIL_COND_V(a.empty(), Ref<TriangleMesh>());
+ ERR_FAIL_COND_V(a.is_empty(), Ref<TriangleMesh>());
int vc = surface_get_array_len(i);
Vector<Vector3> vertices = a[ARRAY_VERTEX];
@@ -226,7 +226,7 @@ Ref<Shape3D> Mesh::create_convex_shape() const {
for (int i = 0; i < get_surface_count(); i++) {
Array a = surface_get_arrays(i);
- ERR_FAIL_COND_V(a.empty(), Ref<ConvexPolygonShape3D>());
+ ERR_FAIL_COND_V(a.is_empty(), Ref<ConvexPolygonShape3D>());
Vector<Vector3> v = a[ARRAY_VERTEX];
vertices.append_array(v);
}
@@ -266,7 +266,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
}
Array a = surface_get_arrays(i);
- ERR_FAIL_COND_V(a.empty(), Ref<ArrayMesh>());
+ ERR_FAIL_COND_V(a.is_empty(), Ref<ArrayMesh>());
if (i == 0) {
arrays = a;
@@ -1095,6 +1095,15 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
return true;
}
+void ArrayMesh::reset_state() {
+ clear_surfaces();
+ clear_blend_shapes();
+
+ aabb = AABB();
+ blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
+ custom_aabb = AABB();
+}
+
void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
if (_is_generated()) {
return;
@@ -1156,7 +1165,7 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const
RenderingServer::get_singleton()->mesh_add_surface(mesh, sd);
clear_cache();
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -1278,7 +1287,6 @@ void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material)
surfaces.write[p_idx].material = p_material;
RenderingServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid());
- _change_notify("material");
emit_changed();
}
@@ -1350,7 +1358,7 @@ AABB ArrayMesh::get_custom_aabb() const {
return custom_aabb;
}
-void ArrayMesh::regen_normalmaps() {
+void ArrayMesh::regen_normal_maps() {
if (surfaces.size() == 0) {
return;
}
@@ -1375,8 +1383,8 @@ bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_v
struct ArrayMeshLightmapSurface {
Ref<Material> material;
LocalVector<SurfaceTool::Vertex> vertices;
- Mesh::PrimitiveType primitive;
- uint32_t format;
+ Mesh::PrimitiveType primitive = Mesh::PrimitiveType::PRIMITIVE_MAX;
+ uint32_t format = 0;
};
Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) {
@@ -1565,6 +1573,19 @@ Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cach
return OK;
}
+void ArrayMesh::set_shadow_mesh(const Ref<ArrayMesh> &p_mesh) {
+ shadow_mesh = p_mesh;
+ if (shadow_mesh.is_valid()) {
+ RS::get_singleton()->mesh_set_shadow_mesh(mesh, shadow_mesh->get_rid());
+ } else {
+ RS::get_singleton()->mesh_set_shadow_mesh(mesh, RID());
+ }
+}
+
+Ref<ArrayMesh> ArrayMesh::get_shadow_mesh() const {
+ return shadow_mesh;
+}
+
void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count);
@@ -1586,8 +1607,8 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape);
ClassDB::bind_method(D_METHOD("create_convex_shape"), &ArrayMesh::create_convex_shape);
ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline);
- ClassDB::bind_method(D_METHOD("regen_normalmaps"), &ArrayMesh::regen_normalmaps);
- ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normalmaps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
+ ClassDB::bind_method(D_METHOD("regen_normal_maps"), &ArrayMesh::regen_normal_maps);
+ ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normal_maps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ClassDB::bind_method(D_METHOD("lightmap_unwrap", "transform", "texel_size"), &ArrayMesh::lightmap_unwrap);
ClassDB::set_method_flags(get_class_static(), _scs_create("lightmap_unwrap"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ClassDB::bind_method(D_METHOD("get_faces"), &ArrayMesh::get_faces);
@@ -1596,6 +1617,9 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb);
ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb);
+ ClassDB::bind_method(D_METHOD("set_shadow_mesh", "mesh"), &ArrayMesh::set_shadow_mesh);
+ ClassDB::bind_method(D_METHOD("get_shadow_mesh"), &ArrayMesh::get_shadow_mesh);
+
ClassDB::bind_method(D_METHOD("_set_blend_shape_names", "blend_shape_names"), &ArrayMesh::_set_blend_shape_names);
ClassDB::bind_method(D_METHOD("_get_blend_shape_names"), &ArrayMesh::_get_blend_shape_names);
@@ -1606,6 +1630,7 @@ void ArrayMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_surfaces", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_surfaces", "_get_surfaces");
ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shadow_mesh", PROPERTY_HINT_RESOURCE_TYPE, "ArrayMesh"), "set_shadow_mesh", "get_shadow_mesh");
}
void ArrayMesh::reload_from_file() {
@@ -1616,13 +1641,12 @@ void ArrayMesh::reload_from_file() {
Resource::reload_from_file();
- _change_notify();
+ notify_property_list_changed();
}
ArrayMesh::ArrayMesh() {
//mesh is now created on demand
//mesh = RenderingServer::get_singleton()->mesh_create();
- blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
}
ArrayMesh::~ArrayMesh() {
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index b7f60bf814..2ce519e644 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -176,23 +176,24 @@ class ArrayMesh : public Mesh {
Array _get_surfaces() const;
void _set_surfaces(const Array &p_data);
+ Ref<ArrayMesh> shadow_mesh;
private:
struct Surface {
- uint32_t format;
- int array_length;
- int index_array_length;
- PrimitiveType primitive;
+ uint32_t format = 0;
+ int array_length = 0;
+ int index_array_length = 0;
+ PrimitiveType primitive = PrimitiveType::PRIMITIVE_MAX;
String name;
AABB aabb;
Ref<Material> material;
- bool is_2d;
+ bool is_2d = false;
};
Vector<Surface> surfaces;
mutable RID mesh;
AABB aabb;
- BlendShapeMode blend_shape_mode;
+ BlendShapeMode blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
Vector<StringName> blend_shapes;
AABB custom_aabb;
@@ -206,6 +207,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
+
static void _bind_methods();
public:
@@ -252,13 +255,16 @@ public:
AABB get_aabb() const override;
virtual RID get_rid() const override;
- void regen_normalmaps();
+ void regen_normal_maps();
Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05);
Error lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform = Transform(), float p_texel_size = 0.05);
virtual void reload_from_file() override;
+ void set_shadow_mesh(const Ref<ArrayMesh> &p_mesh);
+ Ref<ArrayMesh> get_shadow_mesh() const;
+
ArrayMesh();
~ArrayMesh();
diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp
index a5c360f123..3fb4f8f211 100644
--- a/scene/resources/mesh_data_tool.cpp
+++ b/scene/resources/mesh_data_tool.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,13 +43,35 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
ERR_FAIL_COND_V(p_mesh->surface_get_primitive_type(p_surface) != Mesh::PRIMITIVE_TRIANGLES, ERR_INVALID_PARAMETER);
Array arrays = p_mesh->surface_get_arrays(p_surface);
- ERR_FAIL_COND_V(arrays.empty(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(arrays.is_empty(), ERR_INVALID_PARAMETER);
Vector<Vector3> varray = arrays[Mesh::ARRAY_VERTEX];
int vcount = varray.size();
ERR_FAIL_COND_V(vcount == 0, ERR_INVALID_PARAMETER);
+ Vector<int> indices;
+
+ if (arrays[Mesh::ARRAY_INDEX].get_type() != Variant::NIL) {
+ indices = arrays[Mesh::ARRAY_INDEX];
+ } else {
+ //make code simpler
+ indices.resize(vcount);
+ int *iw = indices.ptrw();
+ for (int i = 0; i < vcount; i++) {
+ iw[i] = i;
+ }
+ }
+
+ int icount = indices.size();
+ const int *r = indices.ptr();
+
+ ERR_FAIL_COND_V(icount == 0, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(icount % 3, ERR_INVALID_PARAMETER);
+ for (int i = 0; i < icount; i++) {
+ ERR_FAIL_INDEX_V(r[i], vcount, ERR_INVALID_PARAMETER);
+ }
+
clear();
format = p_mesh->surface_get_format(p_surface);
material = p_mesh->surface_get_material(p_surface);
@@ -128,22 +150,6 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
vertices.write[i] = v;
}
- Vector<int> indices;
-
- if (arrays[Mesh::ARRAY_INDEX].get_type() != Variant::NIL) {
- indices = arrays[Mesh::ARRAY_INDEX];
- } else {
- //make code simpler
- indices.resize(vcount);
- int *iw = indices.ptrw();
- for (int i = 0; i < vcount; i++) {
- iw[i] = i;
- }
- }
-
- int icount = indices.size();
- const int *r = indices.ptr();
-
Map<Point2i, int> edge_indices;
for (int i = 0; i < icount; i += 3) {
diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h
index bf9f0dd25f..f5c8f11437 100644
--- a/scene/resources/mesh_data_tool.h
+++ b/scene/resources/mesh_data_tool.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
class MeshDataTool : public Reference {
GDCLASS(MeshDataTool, Reference);
- int format;
+ int format = 0;
struct Vertex {
Vector3 vertex;
Color color;
@@ -54,7 +54,7 @@ class MeshDataTool : public Reference {
Vector<Vertex> vertices;
struct Edge {
- int vertex[2];
+ int vertex[2] = {};
Vector<int> faces;
Variant meta;
};
@@ -62,8 +62,8 @@ class MeshDataTool : public Reference {
Vector<Edge> edges;
struct Face {
- int v[3];
- int edges[3];
+ int v[3] = {};
+ int edges[3] = {};
Variant meta;
};
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index 09b0d4b038..ad90481fbd 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -109,14 +109,14 @@ void MeshLibrary::create_item(int p_item) {
ERR_FAIL_COND(p_item < 0);
ERR_FAIL_COND(item_map.has(p_item));
item_map[p_item] = Item();
- _change_notify();
+ notify_property_list_changed();
}
void MeshLibrary::set_item_name(int p_item, const String &p_name) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].name = p_name;
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) {
@@ -124,25 +124,25 @@ void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) {
item_map[p_item].mesh = p_mesh;
notify_change_to_owners();
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].shapes = p_shapes;
- _change_notify();
+ notify_property_list_changed();
notify_change_to_owners();
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].navmesh = p_navmesh;
- _change_notify();
+ notify_property_list_changed();
notify_change_to_owners();
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_transform) {
@@ -150,14 +150,14 @@ void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_tran
item_map[p_item].navmesh_transform = p_transform;
notify_change_to_owners();
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].preview = p_preview;
emit_changed();
- _change_notify();
+ notify_property_list_changed();
}
String MeshLibrary::get_item_name(int p_item) const {
@@ -198,14 +198,14 @@ void MeshLibrary::remove_item(int p_item) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map.erase(p_item);
notify_change_to_owners();
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
void MeshLibrary::clear() {
item_map.clear();
notify_change_to_owners();
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -264,6 +264,9 @@ Array MeshLibrary::_get_item_shapes(int p_item) const {
return ret;
}
+void MeshLibrary::reset_state() {
+ clear();
+}
void MeshLibrary::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_item", "id"), &MeshLibrary::create_item);
ClassDB::bind_method(D_METHOD("set_item_name", "id", "name"), &MeshLibrary::set_item_name);
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index 0d5fb3005b..1da624c275 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,6 +65,7 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
static void _bind_methods();
public:
diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp
index f71cf383e5..4991887eb3 100644
--- a/scene/resources/multimesh.cpp
+++ b/scene/resources/multimesh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -217,7 +217,7 @@ Ref<Mesh> MultiMesh::get_mesh() const {
void MultiMesh::set_instance_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
- RenderingServer::get_singleton()->multimesh_allocate(multimesh, p_count, RS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data);
+ RenderingServer::get_singleton()->multimesh_allocate_data(multimesh, p_count, RS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data);
instance_count = p_count;
}
@@ -361,11 +361,6 @@ void MultiMesh::_bind_methods() {
MultiMesh::MultiMesh() {
multimesh = RenderingServer::get_singleton()->multimesh_create();
- use_colors = false;
- use_custom_data = false;
- transform_format = TRANSFORM_2D;
- visible_instance_count = -1;
- instance_count = 0;
}
MultiMesh::~MultiMesh() {
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index 16f5998a04..ca5c42d47a 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,11 +47,11 @@ public:
private:
Ref<Mesh> mesh;
RID multimesh;
- TransformFormat transform_format;
- bool use_colors;
- bool use_custom_data;
- int instance_count;
- int visible_instance_count;
+ TransformFormat transform_format = TRANSFORM_2D;
+ bool use_colors = false;
+ bool use_custom_data = false;
+ int instance_count = 0;
+ int visible_instance_count = -1;
protected:
static void _bind_methods();
diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp
index e815da5d45..8c12f59a00 100644
--- a/scene/resources/navigation_mesh.cpp
+++ b/scene/resources/navigation_mesh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,6 +31,8 @@
#include "navigation_mesh.h"
void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
+ ERR_FAIL_COND(p_mesh.is_null());
+
vertices = Vector<Vector3>();
clear_polygons();
@@ -74,7 +76,7 @@ int NavigationMesh::get_sample_partition_type() const {
void NavigationMesh::set_parsed_geometry_type(int p_value) {
ERR_FAIL_COND(p_value >= PARSED_GEOMETRY_MAX);
parsed_geometry_type = static_cast<ParsedGeometryType>(p_value);
- _change_notify();
+ notify_property_list_changed();
}
int NavigationMesh::get_parsed_geometry_type() const {
@@ -106,7 +108,7 @@ bool NavigationMesh::get_collision_mask_bit(int p_bit) const {
void NavigationMesh::set_source_geometry_mode(int p_geometry_mode) {
ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX);
source_geometry_mode = static_cast<SourceGeometryMode>(p_geometry_mode);
- _change_notify();
+ notify_property_list_changed();
}
int NavigationMesh::get_source_geometry_mode() const {
@@ -251,7 +253,7 @@ bool NavigationMesh::get_filter_walkable_low_height_spans() const {
void NavigationMesh::set_vertices(const Vector<Vector3> &p_vertices) {
vertices = p_vertices;
- _change_notify();
+ notify_property_list_changed();
}
Vector<Vector3> NavigationMesh::get_vertices() const {
@@ -263,7 +265,7 @@ void NavigationMesh::_set_polygons(const Array &p_array) {
for (int i = 0; i < p_array.size(); i++) {
polygons.write[i].indices = p_array[i];
}
- _change_notify();
+ notify_property_list_changed();
}
Array NavigationMesh::_get_polygons() const {
@@ -280,7 +282,7 @@ void NavigationMesh::add_polygon(const Vector<int> &p_polygon) {
Polygon polygon;
polygon.indices = p_polygon;
polygons.push_back(polygon);
- _change_notify();
+ notify_property_list_changed();
}
int NavigationMesh::get_polygon_count() const {
@@ -510,27 +512,4 @@ void NavigationMesh::_validate_property(PropertyInfo &property) const {
}
}
-NavigationMesh::NavigationMesh() {
- cell_size = 0.3f;
- cell_height = 0.2f;
- agent_height = 2.0f;
- agent_radius = 0.6f;
- agent_max_climb = 0.9f;
- agent_max_slope = 45.0f;
- region_min_size = 8.0f;
- region_merge_size = 20.0f;
- edge_max_length = 12.0f;
- edge_max_error = 1.3f;
- verts_per_poly = 6.0f;
- detail_sample_distance = 6.0f;
- detail_sample_max_error = 1.0f;
-
- partition_type = SAMPLE_PARTITION_WATERSHED;
- parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES;
- collision_mask = 0xFFFFFFFF;
- source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN;
- source_group_name = "navmesh";
- filter_low_hanging_obstacles = false;
- filter_ledge_spans = false;
- filter_walkable_low_height_spans = false;
-}
+NavigationMesh::NavigationMesh() {}
diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h
index b94f4408e1..966221c7c6 100644
--- a/scene/resources/navigation_mesh.h
+++ b/scene/resources/navigation_mesh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -82,30 +82,30 @@ public:
};
protected:
- float cell_size;
- float cell_height;
- float agent_height;
- float agent_radius;
- float agent_max_climb;
- float agent_max_slope;
- float region_min_size;
- float region_merge_size;
- float edge_max_length;
- float edge_max_error;
- float verts_per_poly;
- float detail_sample_distance;
- float detail_sample_max_error;
-
- SamplePartitionType partition_type;
- ParsedGeometryType parsed_geometry_type;
- uint32_t collision_mask;
-
- SourceGeometryMode source_geometry_mode;
- StringName source_group_name;
-
- bool filter_low_hanging_obstacles;
- bool filter_ledge_spans;
- bool filter_walkable_low_height_spans;
+ float cell_size = 0.3f;
+ float cell_height = 0.2f;
+ float agent_height = 2.0f;
+ float agent_radius = 0.6f;
+ float agent_max_climb = 0.9f;
+ float agent_max_slope = 45.0f;
+ float region_min_size = 8.0f;
+ float region_merge_size = 20.0f;
+ float edge_max_length = 12.0f;
+ float edge_max_error = 1.3f;
+ float verts_per_poly = 6.0f;
+ float detail_sample_distance = 6.0f;
+ float detail_sample_max_error = 1.0f;
+
+ SamplePartitionType partition_type = SAMPLE_PARTITION_WATERSHED;
+ ParsedGeometryType parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES;
+ uint32_t collision_mask = 0xFFFFFFFF;
+
+ SourceGeometryMode source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN;
+ StringName source_group_name = "navmesh";
+
+ bool filter_low_hanging_obstacles = false;
+ bool filter_ledge_spans = false;
+ bool filter_walkable_low_height_spans = false;
public:
// Recast settings
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 09674f3465..ab8a4b7934 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,7 +80,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
Node **ret_nodes = (Node **)alloca(sizeof(Node *) * nc);
- bool gen_node_path_cache = p_edit_state != GEN_EDIT_STATE_DISABLED && node_path_cache.empty();
+ bool gen_node_path_cache = p_edit_state != GEN_EDIT_STATE_DISABLED && node_path_cache.is_empty();
Map<Ref<Resource>, Ref<Resource>> resources_local_to_scene;
@@ -147,15 +147,20 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
}
#endif
}
- } else if (ClassDB::is_class_enabled(snames[n.type])) {
- //node belongs to this scene and must be created
- Object *obj = ClassDB::instance(snames[n.type]);
+ } else {
+ Object *obj = nullptr;
+
+ if (ClassDB::is_class_enabled(snames[n.type])) {
+ //node belongs to this scene and must be created
+ obj = ClassDB::instance(snames[n.type]);
+ }
+
if (!Object::cast_to<Node>(obj)) {
if (obj) {
memdelete(obj);
obj = nullptr;
}
- WARN_PRINT(String("Warning node of type " + snames[n.type].operator String() + " does not exist.").ascii().get_data());
+ WARN_PRINT(vformat("Node %s of type %s cannot be created. A placeholder will be created instead.", snames[n.name], snames[n.type]).ascii().get_data());
if (n.parent >= 0 && n.parent < nc && ret_nodes[n.parent]) {
if (Object::cast_to<Node3D>(ret_nodes[n.parent])) {
obj = memnew(Node3D);
@@ -172,10 +177,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
}
node = Object::cast_to<Node>(obj);
-
- } else {
- //print_line("Class is disabled for: " + itos(n.type));
- //print_line("name: " + String(snames[n.type]));
}
if (node) {
@@ -469,6 +470,11 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
p_node->get_property_list(&plist);
StringName type = p_node->get_class();
+ Ref<Script> script = p_node->get_script();
+ if (script.is_valid()) {
+ script->update_exports();
+ }
+
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
@@ -484,7 +490,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
isdefault = bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value));
}
- Ref<Script> script = p_node->get_script();
if (!isdefault && script.is_valid() && script->get_property_default_value(name, default_value)) {
isdefault = bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value));
}
@@ -603,7 +608,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
// Save the right type. If this node was created by an instance
// then flag that the node should not be created but reused
- if (pack_state_stack.empty()) {
+ if (pack_state_stack.is_empty()) {
//this node is not part of an instancing process, so save the type
nd.type = _nm_get_string(p_node->get_class(), name_map);
} else {
@@ -1349,7 +1354,7 @@ NodePath SceneState::get_node_path(int p_idx, bool p_for_parent) const {
sub_path.insert(0, base_path.get_name(i));
}
- if (sub_path.empty()) {
+ if (sub_path.is_empty()) {
return NodePath(".");
}
@@ -1589,8 +1594,6 @@ void SceneState::_bind_methods() {
}
SceneState::SceneState() {
- base_scene_idx = -1;
- last_modified_time = 0;
}
////////////////
@@ -1663,6 +1666,9 @@ void PackedScene::set_path(const String &p_path, bool p_take_over) {
Resource::set_path(p_path, p_take_over);
}
+void PackedScene::reset_state() {
+ clear();
+}
void PackedScene::_bind_methods() {
ClassDB::bind_method(D_METHOD("pack", "path"), &PackedScene::pack);
ClassDB::bind_method(D_METHOD("instance", "edit_state"), &PackedScene::instance, DEFVAL(GEN_EDIT_STATE_DISABLED));
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index fce3891507..78a0aeaa9a 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,7 +44,7 @@ class SceneState : public Reference {
mutable HashMap<NodePath, int> node_path_cache;
mutable Map<int, int> base_scene_node_remap;
- int base_scene_idx;
+ int base_scene_idx = -1;
enum {
NO_PARENT_SAVED = 0x7FFFFFFF,
@@ -53,16 +53,16 @@ class SceneState : public Reference {
};
struct NodeData {
- int parent;
- int owner;
- int type;
- int name;
- int instance;
- int index;
+ int parent = 0;
+ int owner = 0;
+ int type = 0;
+ int name = 0;
+ int instance = 0;
+ int index = 0;
struct Property {
- int name;
- int value;
+ int name = 0;
+ int value = 0;
};
Vector<Property> properties;
@@ -71,18 +71,17 @@ class SceneState : public Reference {
struct PackState {
Ref<SceneState> state;
- int node;
- PackState() { node = -1; }
+ int node = -1;
};
Vector<NodeData> nodes;
struct ConnectionData {
- int from;
- int to;
- int signal;
- int method;
- int flags;
+ int from = 0;
+ int to = 0;
+ int signal = 0;
+ int method = 0;
+ int flags = 0;
Vector<int> binds;
};
@@ -93,7 +92,7 @@ class SceneState : public Reference {
String path;
- uint64_t last_modified_time;
+ uint64_t last_modified_time = 0;
_FORCE_INLINE_ Ref<SceneState> _get_base_scene_state() const;
@@ -201,6 +200,7 @@ class PackedScene : public Resource {
protected:
virtual bool editor_can_reload_from_file() override { return false; } // this is handled by editor better
static void _bind_methods();
+ virtual void reset_state() override;
public:
enum GenEditState {
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index e2f96c54cb..167540eb77 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -305,6 +305,7 @@ void ParticlesMaterial::_update_shader() {
code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n";
code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n";
}
+ code += " float tv = 0.0;\n";
code += " if (RESTART) {\n";
if (tex_parameters[PARAM_ANGLE].is_valid()) {
@@ -407,64 +408,65 @@ void ParticlesMaterial::_update_shader() {
code += " } else {\n";
code += " CUSTOM.y += DELTA / LIFETIME;\n";
+ code += " tv = CUSTOM.y / CUSTOM.w;\n";
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_linear_velocity = 0.0;\n";
}
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
- code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_orbit_velocity = 0.0;\n";
}
}
if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
- code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_angular_velocity = 0.0;\n";
}
if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
- code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_linear_accel = 0.0;\n";
}
if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
- code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_radial_accel = 0.0;\n";
}
if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
- code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_tangent_accel = 0.0;\n";
}
if (tex_parameters[PARAM_DAMPING].is_valid()) {
- code += " float tex_damping = textureLod(damping_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_damping = textureLod(damping_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_damping = 0.0;\n";
}
if (tex_parameters[PARAM_ANGLE].is_valid()) {
- code += " float tex_angle = textureLod(angle_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_angle = textureLod(angle_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_angle = 0.0;\n";
}
if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) {
- code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_anim_speed = 0.0;\n";
}
if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
- code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_anim_offset = 0.0;\n";
}
@@ -526,13 +528,13 @@ void ParticlesMaterial::_update_shader() {
// apply color
// apply hue rotation
if (tex_parameters[PARAM_SCALE].is_valid()) {
- code += " float tex_scale = textureLod(scale_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_scale = textureLod(scale_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_scale = 1.0;\n";
}
if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) {
- code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
+ code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
code += " float tex_hue_variation = 0.0;\n";
}
@@ -553,7 +555,7 @@ void ParticlesMaterial::_update_shader() {
code += " vec4(1.250, -1.050, -0.203, 0.0),\n";
code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n";
if (color_ramp.is_valid()) {
- code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(CUSTOM.y, 0.0), 0.0);\n";
+ code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0);\n";
} else {
code += " COLOR = hue_rot_mat * color_value;\n";
}
@@ -646,7 +648,7 @@ void ParticlesMaterial::_update_shader() {
code += " for(int i=0;i<emit_count;i++) {\n";
code += " uint flags = FLAG_EMIT_POSITION|FLAG_EMIT_ROT_SCALE;\n";
code += " if (sub_emitter_keep_velocity) flags|=FLAG_EMIT_VELOCITY;\n";
- code += " emit_particle(TRANSFORM,VELOCITY,vec4(0.0),vec4(0.0),flags);\n";
+ code += " emit_subparticle(TRANSFORM,VELOCITY,vec4(0.0),vec4(0.0),flags);\n";
code += " }";
}
@@ -909,7 +911,7 @@ void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) {
color_ramp = p_texture;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture);
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
Ref<Texture2D> ParticlesMaterial::get_color_ramp() const {
@@ -921,7 +923,7 @@ void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_
particle_flags[p_particle_flag] = p_enable;
_queue_shader_change();
if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) {
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -933,7 +935,7 @@ bool ParticlesMaterial::get_particle_flag(ParticleFlags p_particle_flag) const {
void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) {
ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX);
emission_shape = p_shape;
- _change_notify();
+ notify_property_list_changed();
_queue_shader_change();
}
@@ -1064,7 +1066,7 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) {
sub_emitter_mode = p_sub_emitter_mode;
_queue_shader_change();
- _change_notify();
+ notify_property_list_changed();
}
ParticlesMaterial::SubEmitterMode ParticlesMaterial::get_sub_emitter_mode() const {
@@ -1368,7 +1370,6 @@ ParticlesMaterial::ParticlesMaterial() :
set_emission_box_extents(Vector3(1, 1, 1));
set_gravity(Vector3(0, -9.8, 0));
set_lifetime_randomness(0);
- emission_point_count = 1;
set_sub_emitter_mode(SUB_EMITTER_DISABLED);
set_sub_emitter_frequency(4);
@@ -1391,7 +1392,6 @@ ParticlesMaterial::ParticlesMaterial() :
set_color(Color(1, 1, 1, 1));
- current_key.key = 0;
current_key.invalid_key = 1;
_queue_shader_change();
diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h
index 7e8f05b706..3f874bd68c 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -100,7 +100,7 @@ private:
uint32_t collision_scale : 1;
};
- uint32_t key;
+ uint32_t key = 0;
bool operator<(const MaterialKey &p_key) const {
return key < p_key.key;
@@ -109,7 +109,7 @@ private:
struct ShaderData {
RID shader;
- int users;
+ int users = 0;
};
static Map<MaterialKey, ShaderData> shader_map;
@@ -235,7 +235,7 @@ private:
Ref<Texture2D> emission_point_texture;
Ref<Texture2D> emission_normal_texture;
Ref<Texture2D> emission_color_texture;
- int emission_point_count;
+ int emission_point_count = 1;
bool anim_loop;
@@ -340,7 +340,7 @@ public:
void set_sub_emitter_keep_velocity(bool p_enable);
bool get_sub_emitter_keep_velocity() const;
- RID get_shader_rid() const;
+ virtual RID get_shader_rid() const override;
virtual Shader::Mode get_shader_mode() const override;
diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp
index 59bf8c0e13..d65b0c8927 100644
--- a/scene/resources/physics_material.cpp
+++ b/scene/resources/physics_material.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h
index e9222ffa1b..d302800823 100644
--- a/scene/resources/physics_material.h
+++ b/scene/resources/physics_material.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,9 +39,9 @@ class PhysicsMaterial : public Resource {
OBJ_SAVE_TYPE(PhysicsMaterial);
RES_BASE_EXTENSION("phymat");
- real_t friction = 1;
+ real_t friction = 1.0;
bool rough = false;
- real_t bounce = 0;
+ real_t bounce = 0.0;
bool absorbent = false;
protected:
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index df98d4cfd4..f292140d6b 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h
index 44a97b4294..2f3cb634fb 100644
--- a/scene/resources/polygon_path_finder.h
+++ b/scene/resources/polygon_path_finder.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,13 +39,13 @@ class PolygonPathFinder : public Resource {
struct Point {
Vector2 pos;
Set<int> connections;
- float distance;
- float penalty;
- int prev;
+ float distance = 0.0;
+ float penalty = 0.0;
+ int prev = 0;
};
struct Edge {
- int points[2];
+ int points[2] = {};
_FORCE_INLINE_ bool operator<(const Edge &p_edge) const {
if (points[0] == p_edge.points[0]) {
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 06e181cb99..ba6c4591c9 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -214,7 +214,7 @@ void PrimitiveMesh::set_material(const Ref<Material> &p_material) {
if (!pending_request) {
// just apply it, else it'll happen when _update is called.
RenderingServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
- _change_notify();
+ notify_property_list_changed();
emit_changed();
};
}
@@ -247,18 +247,7 @@ bool PrimitiveMesh::get_flip_faces() const {
}
PrimitiveMesh::PrimitiveMesh() {
- flip_faces = false;
- // defaults
mesh = RenderingServer::get_singleton()->mesh_create();
-
- // assume primitive triangles as the type, correct for all but one and it will change this :)
- primitive_type = Mesh::PRIMITIVE_TRIANGLES;
-
- // make sure we do an update after we've finished constructing our object
- pending_request = true;
-
- array_len = 0;
- index_array_len = 0;
}
PrimitiveMesh::~PrimitiveMesh() {
@@ -304,8 +293,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
u = i;
u /= radial_segments;
- x = -sin(u * (Math_PI * 2.0));
- z = cos(u * (Math_PI * 2.0));
+ x = -sin(u * Math_TAU);
+ z = cos(u * Math_TAU);
Vector3 p = Vector3(x * radius * w, y, -z * radius * w);
points.push_back(p + Vector3(0.0, 0.5 * mid_height, 0.0));
@@ -343,8 +332,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
u = i;
u /= radial_segments;
- x = -sin(u * (Math_PI * 2.0));
- z = cos(u * (Math_PI * 2.0));
+ x = -sin(u * Math_TAU);
+ z = cos(u * Math_TAU);
Vector3 p = Vector3(x * radius, y, -z * radius);
points.push_back(p);
@@ -383,8 +372,8 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
float u2 = i;
u2 /= radial_segments;
- x = -sin(u2 * (Math_PI * 2.0));
- z = cos(u2 * (Math_PI * 2.0));
+ x = -sin(u2 * Math_TAU);
+ z = cos(u2 * Math_TAU);
Vector3 p = Vector3(x * radius * w, y, -z * radius * w);
points.push_back(p + Vector3(0.0, -0.5 * mid_height, 0.0));
@@ -468,13 +457,7 @@ int CapsuleMesh::get_rings() const {
return rings;
}
-CapsuleMesh::CapsuleMesh() {
- // defaults
- radius = 1.0;
- mid_height = 1.0;
- radial_segments = 64;
- rings = 8;
-}
+CapsuleMesh::CapsuleMesh() {}
/**
BoxMesh
@@ -725,13 +708,7 @@ int BoxMesh::get_subdivide_depth() const {
return subdivide_d;
}
-BoxMesh::BoxMesh() {
- // defaults
- size = Vector3(2.0, 2.0, 2.0);
- subdivide_w = 0;
- subdivide_h = 0;
- subdivide_d = 0;
-}
+BoxMesh::BoxMesh() {}
/**
CylinderMesh
@@ -769,8 +746,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
u = i;
u /= radial_segments;
- x = sin(u * (Math_PI * 2.0));
- z = cos(u * (Math_PI * 2.0));
+ x = sin(u * Math_TAU);
+ z = cos(u * Math_TAU);
Vector3 p = Vector3(x * radius, y, z * radius);
points.push_back(p);
@@ -809,8 +786,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
float r = i;
r /= radial_segments;
- x = sin(r * (Math_PI * 2.0));
- z = cos(r * (Math_PI * 2.0));
+ x = sin(r * Math_TAU);
+ z = cos(r * Math_TAU);
u = ((x + 1.0) * 0.25);
v = 0.5 + ((z + 1.0) * 0.25);
@@ -845,8 +822,8 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const {
float r = i;
r /= radial_segments;
- x = sin(r * (Math_PI * 2.0));
- z = cos(r * (Math_PI * 2.0));
+ x = sin(r * Math_TAU);
+ z = cos(r * Math_TAU);
u = 0.5 + ((x + 1.0) * 0.25);
v = 1.0 - ((z + 1.0) * 0.25);
@@ -938,14 +915,7 @@ int CylinderMesh::get_rings() const {
return rings;
}
-CylinderMesh::CylinderMesh() {
- // defaults
- top_radius = 1.0;
- bottom_radius = 1.0;
- height = 2.0;
- radial_segments = 64;
- rings = 4;
-}
+CylinderMesh::CylinderMesh() {}
/**
PlaneMesh
@@ -1053,12 +1023,7 @@ int PlaneMesh::get_subdivide_depth() const {
return subdivide_d;
}
-PlaneMesh::PlaneMesh() {
- // defaults
- size = Size2(2.0, 2.0);
- subdivide_w = 0;
- subdivide_d = 0;
-}
+PlaneMesh::PlaneMesh() {}
/**
PrismMesh
@@ -1338,14 +1303,7 @@ int PrismMesh::get_subdivide_depth() const {
return subdivide_d;
}
-PrismMesh::PrismMesh() {
- // defaults
- left_to_right = 0.5;
- size = Vector3(2.0, 2.0, 2.0);
- subdivide_w = 0;
- subdivide_h = 0;
- subdivide_d = 0;
-}
+PrismMesh::PrismMesh() {}
/**
QuadMesh
@@ -1409,7 +1367,6 @@ void QuadMesh::_bind_methods() {
QuadMesh::QuadMesh() {
primitive_type = PRIMITIVE_TRIANGLES;
- size = Size2(1.0, 1.0);
}
void QuadMesh::set_size(const Size2 &p_size) {
@@ -1458,8 +1415,8 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const {
float u = i;
u /= radial_segments;
- x = sin(u * (Math_PI * 2.0));
- z = cos(u * (Math_PI * 2.0));
+ x = sin(u * Math_TAU);
+ z = cos(u * Math_TAU);
if (is_hemisphere && y < 0.0) {
points.push_back(Vector3(x * radius * w, 0.0, z * radius * w));
@@ -1561,14 +1518,7 @@ bool SphereMesh::get_is_hemisphere() const {
return is_hemisphere;
}
-SphereMesh::SphereMesh() {
- // defaults
- radius = 1.0;
- height = 2.0;
- radial_segments = 64;
- rings = 32;
- is_hemisphere = false;
-}
+SphereMesh::SphereMesh() {}
/**
PointMesh
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 02aea9c5c8..bb3df9d10e 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,17 +49,19 @@ private:
mutable AABB aabb;
AABB custom_aabb;
- mutable int array_len;
- mutable int index_array_len;
+ mutable int array_len = 0;
+ mutable int index_array_len = 0;
Ref<Material> material;
- bool flip_faces;
+ bool flip_faces = false;
- mutable bool pending_request;
+ // make sure we do an update after we've finished constructing our object
+ mutable bool pending_request = true;
void _update() const;
protected:
- Mesh::PrimitiveType primitive_type;
+ // assume primitive triangles as the type, correct for all but one and it will change this :)
+ Mesh::PrimitiveType primitive_type = Mesh::PRIMITIVE_TRIANGLES;
static void _bind_methods();
@@ -104,10 +106,10 @@ class CapsuleMesh : public PrimitiveMesh {
GDCLASS(CapsuleMesh, PrimitiveMesh);
private:
- float radius;
- float mid_height;
- int radial_segments;
- int rings;
+ float radius = 1.0;
+ float mid_height = 1.0;
+ int radial_segments = 64;
+ int rings = 8;
protected:
static void _bind_methods();
@@ -136,10 +138,10 @@ class BoxMesh : public PrimitiveMesh {
GDCLASS(BoxMesh, PrimitiveMesh);
private:
- Vector3 size;
- int subdivide_w;
- int subdivide_h;
- int subdivide_d;
+ Vector3 size = Vector3(2.0, 2.0, 2.0);
+ int subdivide_w = 0;
+ int subdivide_h = 0;
+ int subdivide_d = 0;
protected:
static void _bind_methods();
@@ -169,11 +171,11 @@ class CylinderMesh : public PrimitiveMesh {
GDCLASS(CylinderMesh, PrimitiveMesh);
private:
- float top_radius;
- float bottom_radius;
- float height;
- int radial_segments;
- int rings;
+ float top_radius = 1.0;
+ float bottom_radius = 1.0;
+ float height = 2.0;
+ int radial_segments = 64;
+ int rings = 4;
protected:
static void _bind_methods();
@@ -205,9 +207,9 @@ class PlaneMesh : public PrimitiveMesh {
GDCLASS(PlaneMesh, PrimitiveMesh);
private:
- Size2 size;
- int subdivide_w;
- int subdivide_d;
+ Size2 size = Size2(2.0, 2.0);
+ int subdivide_w = 0;
+ int subdivide_d = 0;
protected:
static void _bind_methods();
@@ -233,11 +235,11 @@ class PrismMesh : public PrimitiveMesh {
GDCLASS(PrismMesh, PrimitiveMesh);
private:
- float left_to_right;
- Vector3 size;
- int subdivide_w;
- int subdivide_h;
- int subdivide_d;
+ float left_to_right = 0.5;
+ Vector3 size = Vector3(2.0, 2.0, 2.0);
+ int subdivide_w = 0;
+ int subdivide_h = 0;
+ int subdivide_d = 0;
protected:
static void _bind_methods();
@@ -270,7 +272,7 @@ class QuadMesh : public PrimitiveMesh {
GDCLASS(QuadMesh, PrimitiveMesh);
private:
- Size2 size;
+ Size2 size = Size2(1.0, 1.0);
protected:
static void _bind_methods();
@@ -290,11 +292,11 @@ class SphereMesh : public PrimitiveMesh {
GDCLASS(SphereMesh, PrimitiveMesh);
private:
- float radius;
- float height;
- int radial_segments;
- int rings;
- bool is_hemisphere;
+ float radius = 1.0;
+ float height = 2.0;
+ int radial_segments = 64;
+ int rings = 32;
+ bool is_hemisphere = false;
protected:
static void _bind_methods();
diff --git a/scene/resources/ray_shape_2d.cpp b/scene/resources/ray_shape_2d.cpp
index 67c4f84749..d2125445fa 100644
--- a/scene/resources/ray_shape_2d.cpp
+++ b/scene/resources/ray_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,7 @@ void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Vector2 tip = Vector2(0, get_length());
RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3);
Vector<Vector2> pts;
- float tsize = 4;
+ float tsize = 4.0;
pts.push_back(tip + Vector2(0, tsize));
pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0));
pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0));
@@ -99,7 +99,5 @@ bool RayShape2D::get_slips_on_slope() const {
RayShape2D::RayShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) {
- length = 20;
- slips_on_slope = false;
_update_shape();
}
diff --git a/scene/resources/ray_shape_2d.h b/scene/resources/ray_shape_2d.h
index c8202ca16c..56ecfa2722 100644
--- a/scene/resources/ray_shape_2d.h
+++ b/scene/resources/ray_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,8 +36,8 @@
class RayShape2D : public Shape2D {
GDCLASS(RayShape2D, Shape2D);
- real_t length;
- bool slips_on_slope;
+ real_t length = 20.0;
+ bool slips_on_slope = false;
void _update_shape();
diff --git a/scene/resources/ray_shape_3d.cpp b/scene/resources/ray_shape_3d.cpp
index 1705fb0f55..5446b4daab 100644
--- a/scene/resources/ray_shape_3d.cpp
+++ b/scene/resources/ray_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,7 +56,6 @@ void RayShape3D::set_length(float p_length) {
length = p_length;
_update_shape();
notify_change_to_owners();
- _change_notify("length");
}
float RayShape3D::get_length() const {
@@ -67,7 +66,6 @@ void RayShape3D::set_slips_on_slope(bool p_active) {
slips_on_slope = p_active;
_update_shape();
notify_change_to_owners();
- _change_notify("slips_on_slope");
}
bool RayShape3D::get_slips_on_slope() const {
@@ -87,12 +85,7 @@ void RayShape3D::_bind_methods() {
RayShape3D::RayShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_RAY)) {
- length = 1.0;
- slips_on_slope = false;
-
/* Code copied from setters to prevent the use of uninitialized variables */
_update_shape();
notify_change_to_owners();
- _change_notify("length");
- _change_notify("slips_on_slope");
}
diff --git a/scene/resources/ray_shape_3d.h b/scene/resources/ray_shape_3d.h
index a1a6702564..2da6311321 100644
--- a/scene/resources/ray_shape_3d.h
+++ b/scene/resources/ray_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,8 +34,8 @@
class RayShape3D : public Shape3D {
GDCLASS(RayShape3D, Shape3D);
- float length;
- bool slips_on_slope;
+ float length = 1.0;
+ bool slips_on_slope = false;
protected:
static void _bind_methods();
diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp
index 949fddf2e7..dc4c6dc2d7 100644
--- a/scene/resources/rectangle_shape_2d.cpp
+++ b/scene/resources/rectangle_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,40 +33,58 @@
#include "servers/physics_server_2d.h"
#include "servers/rendering_server.h"
void RectangleShape2D::_update_shape() {
- PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), extents);
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), size * 0.5);
emit_changed();
}
-void RectangleShape2D::set_extents(const Vector2 &p_extents) {
- extents = p_extents;
+void RectangleShape2D::set_size(const Vector2 &p_size) {
+ size = p_size;
_update_shape();
}
-Vector2 RectangleShape2D::get_extents() const {
- return extents;
+Vector2 RectangleShape2D::get_size() const {
+ return size;
}
void RectangleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
- RenderingServer::get_singleton()->canvas_item_add_rect(p_to_rid, Rect2(-extents, extents * 2.0), p_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(p_to_rid, Rect2(-size * 0.5, size), p_color);
+ if (is_collision_outline_enabled()) {
+ // Draw an outlined rectangle to make individual shapes easier to distinguish.
+ Vector<Vector2> stroke_points;
+ stroke_points.resize(5);
+ stroke_points.write[0] = -size * 0.5;
+ stroke_points.write[1] = Vector2(size.x, -size.y) * 0.5;
+ stroke_points.write[2] = size * 0.5;
+ stroke_points.write[3] = Vector2(-size.x, size.y) * 0.5;
+ stroke_points.write[4] = -size * 0.5;
+
+ Vector<Color> stroke_colors;
+ stroke_colors.resize(5);
+ for (int i = 0; i < 5; i++) {
+ stroke_colors.write[i] = (p_color);
+ }
+
+ RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, stroke_points, stroke_colors);
+ }
}
Rect2 RectangleShape2D::get_rect() const {
- return Rect2(-extents, extents * 2.0);
+ return Rect2(-size * 0.5, size);
}
real_t RectangleShape2D::get_enclosing_radius() const {
- return extents.length();
+ return size.length() / 2;
}
void RectangleShape2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &RectangleShape2D::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &RectangleShape2D::get_extents);
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &RectangleShape2D::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &RectangleShape2D::get_size);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "extents"), "set_extents", "get_extents");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
}
RectangleShape2D::RectangleShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->rectangle_shape_create()) {
- extents = Vector2(10, 10);
+ size = Vector2(20, 20);
_update_shape();
}
diff --git a/scene/resources/rectangle_shape_2d.h b/scene/resources/rectangle_shape_2d.h
index 6efa7ab9c8..8d747c86af 100644
--- a/scene/resources/rectangle_shape_2d.h
+++ b/scene/resources/rectangle_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,15 +36,15 @@
class RectangleShape2D : public Shape2D {
GDCLASS(RectangleShape2D, Shape2D);
- Vector2 extents;
+ Vector2 size;
void _update_shape();
protected:
static void _bind_methods();
public:
- void set_extents(const Vector2 &p_extents);
- Vector2 get_extents() const;
+ void set_size(const Vector2 &p_size);
+ Vector2 get_size() const;
virtual void draw(const RID &p_to_rid, const Color &p_color) override;
virtual Rect2 get_rect() const override;
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 58645dbe65..7ca532e1d6 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -114,23 +114,8 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R
}
int index = token.value;
-
- if (use_nocache) {
- r_res = int_resources[index];
- } else {
- String path = local_path + "::" + itos(index);
-
- if (!ignore_resource_parsing) {
- if (!ResourceCache::has(path)) {
- r_err_str = "Can't load cached sub-resource: " + path;
- return ERR_PARSE_ERROR;
- }
-
- r_res = RES(ResourceCache::get(path));
- } else {
- r_res = RES();
- }
- }
+ ERR_FAIL_COND_V(!int_resources.has(index), ERR_INVALID_PARAMETER);
+ r_res = int_resources[index];
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) {
@@ -440,7 +425,7 @@ Error ResourceLoaderText::load() {
er.type = type;
if (use_sub_threads) {
- Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, local_path);
+ Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, ResourceFormatLoader::CACHE_MODE_REUSE, local_path);
if (err != OK) {
if (ResourceLoader::get_abort_on_missing_resources()) {
@@ -517,29 +502,44 @@ Error ResourceLoaderText::load() {
//bool exists=ResourceCache::has(path);
Ref<Resource> res;
+ bool do_assign = false;
- if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist
-
- Object *obj = ClassDB::instance(type);
- if (!obj) {
- error_text += "Can't create sub resource of type: " + type;
- _printerr();
- error = ERR_FILE_CORRUPT;
- return error;
+ if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) {
+ //reuse existing
+ Resource *r = ResourceCache::get(path);
+ if (r && r->get_class() == type) {
+ res = Ref<Resource>(r);
+ res->reset_state();
+ do_assign = true;
}
+ }
- Resource *r = Object::cast_to<Resource>(obj);
- if (!r) {
- error_text += "Can't create sub resource of type, because not a resource: " + type;
- _printerr();
- error = ERR_FILE_CORRUPT;
- return error;
- }
+ if (res.is_null()) { //not reuse
+ if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && ResourceCache::has(path)) { //only if it doesn't exist
+ //cached, do not assign
+ Resource *r = ResourceCache::get(path);
+ res = Ref<Resource>(r);
+ } else {
+ //create
- res = Ref<Resource>(r);
- int_resources[id] = res;
- if (!use_nocache) {
- res->set_path(path);
+ Object *obj = ClassDB::instance(type);
+ if (!obj) {
+ error_text += "Can't create sub resource of type: " + type;
+ _printerr();
+ error = ERR_FILE_CORRUPT;
+ return error;
+ }
+
+ Resource *r = Object::cast_to<Resource>(obj);
+ if (!r) {
+ error_text += "Can't create sub resource of type, because not a resource: " + type;
+ _printerr();
+ error = ERR_FILE_CORRUPT;
+ return error;
+ }
+
+ res = Ref<Resource>(r);
+ do_assign = true;
}
}
@@ -557,7 +557,7 @@ Error ResourceLoaderText::load() {
}
if (assign != String()) {
- if (res.is_valid()) {
+ if (do_assign) {
res->set(assign, value);
}
//it's assignment
@@ -572,6 +572,11 @@ Error ResourceLoaderText::load() {
}
}
+ int_resources[id] = res; //always assign int resources
+ if (do_assign && cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
+ res->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE);
+ }
+
if (progress && resources_total > 0) {
*progress = resource_current / float(resources_total);
}
@@ -589,23 +594,33 @@ Error ResourceLoaderText::load() {
return error;
}
- Object *obj = ClassDB::instance(res_type);
- if (!obj) {
- error_text += "Can't create sub resource of type: " + res_type;
- _printerr();
- error = ERR_FILE_CORRUPT;
- return error;
+ if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(local_path)) {
+ Resource *r = ResourceCache::get(local_path);
+ if (r->get_class() == res_type) {
+ r->reset_state();
+ resource = Ref<Resource>(r);
+ }
}
- Resource *r = Object::cast_to<Resource>(obj);
- if (!r) {
- error_text += "Can't create sub resource of type, because not a resource: " + res_type;
- _printerr();
- error = ERR_FILE_CORRUPT;
- return error;
- }
+ if (!resource.is_valid()) {
+ Object *obj = ClassDB::instance(res_type);
+ if (!obj) {
+ error_text += "Can't create sub resource of type: " + res_type;
+ _printerr();
+ error = ERR_FILE_CORRUPT;
+ return error;
+ }
+
+ Resource *r = Object::cast_to<Resource>(obj);
+ if (!r) {
+ error_text += "Can't create sub resource of type, because not a resource: " + res_type;
+ _printerr();
+ error = ERR_FILE_CORRUPT;
+ return error;
+ }
- resource = Ref<Resource>(r);
+ resource = Ref<Resource>(r);
+ }
resource_current++;
@@ -620,7 +635,7 @@ Error ResourceLoaderText::load() {
_printerr();
} else {
error = OK;
- if (!use_nocache) {
+ if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
if (!ResourceCache::has(res_path)) {
resource->set_path(res_path);
}
@@ -668,7 +683,7 @@ Error ResourceLoaderText::load() {
error = OK;
//get it here
resource = packed_scene;
- if (!use_nocache && !ResourceCache::has(res_path)) {
+ if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE && !ResourceCache::has(res_path)) {
packed_scene->set_path(res_path);
}
@@ -699,18 +714,7 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) {
translation_remapped = p_remapped;
}
-ResourceLoaderText::ResourceLoaderText() {
- use_nocache = false;
-
- resources_total = 0;
- resource_current = 0;
-
- progress = nullptr;
- lines = false;
- translation_remapped = false;
- use_sub_threads = false;
- error = OK;
-}
+ResourceLoaderText::ResourceLoaderText() {}
ResourceLoaderText::~ResourceLoaderText() {
memdelete(f);
@@ -1252,7 +1256,7 @@ String ResourceLoaderText::recognize(FileAccess *p_f) {
/////////////////////
-RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
@@ -1265,7 +1269,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina
ResourceLoaderText loader;
String path = p_original_path != "" ? p_original_path : p_path;
- loader.use_nocache = p_no_cache;
+ loader.cache_mode = p_cache_mode;
loader.use_sub_threads = p_use_sub_threads;
loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
loader.progress = r_progress;
diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h
index ca7b0b021f..2dc683415d 100644
--- a/scene/resources/resource_format_text.h
+++ b/scene/resources/resource_format_text.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,12 +38,12 @@
#include "scene/resources/packed_scene.h"
class ResourceLoaderText {
- bool translation_remapped;
+ bool translation_remapped = false;
String local_path;
String res_path;
String error_text;
- FileAccess *f;
+ FileAccess *f = nullptr;
VariantParser::StreamFile stream;
@@ -53,28 +53,28 @@ class ResourceLoaderText {
String type;
};
- bool is_scene;
+ bool is_scene = false;
String res_type;
- bool ignore_resource_parsing;
+ bool ignore_resource_parsing = false;
//Map<String,String> remaps;
Map<int, ExtResource> ext_resources;
Map<int, RES> int_resources;
- int resources_total;
- int resource_current;
+ int resources_total = 0;
+ int resource_current = 0;
String resource_type;
VariantParser::Tag next_tag;
- bool use_nocache;
+ ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
- bool use_sub_threads;
- float *progress;
+ bool use_sub_threads = false;
+ float *progress = nullptr;
- mutable int lines;
+ mutable int lines = 0;
Map<String, String> remaps;
//void _printerr();
@@ -107,7 +107,7 @@ class ResourceLoaderText {
friend class ResourceFormatLoaderText;
- Error error;
+ Error error = OK;
RES resource;
@@ -134,7 +134,7 @@ public:
class ResourceFormatLoaderText : public ResourceFormatLoader {
public:
static ResourceFormatLoaderText *singleton;
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
@@ -152,11 +152,11 @@ class ResourceFormatSaverTextInstance {
Ref<PackedScene> packed_scene;
- bool takeover_paths;
- bool relative_paths;
- bool bundle_resources;
- bool skip_editor;
- FileAccess *f;
+ bool takeover_paths = false;
+ bool relative_paths = false;
+ bool bundle_resources = false;
+ bool skip_editor = false;
+ FileAccess *f = nullptr;
struct NonPersistentKey { //for resource properties generated on the fly
RES base;
@@ -173,7 +173,7 @@ class ResourceFormatSaverTextInstance {
struct ResourceSort {
RES resource;
- int index;
+ int index = 0;
bool operator<(const ResourceSort &p_right) const {
return index < p_right.index;
}
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index b1001203a1..35439634f8 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h
index 31a61ea564..f218955061 100644
--- a/scene/resources/segment_shape_2d.h
+++ b/scene/resources/segment_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 76d37eaa71..77c6199794 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -152,9 +152,7 @@ void Shader::_bind_methods() {
}
Shader::Shader() {
- mode = MODE_SPATIAL;
shader = RenderingServer::get_singleton()->shader_create();
- params_cache_dirty = true;
}
Shader::~Shader() {
@@ -163,7 +161,7 @@ Shader::~Shader() {
////////////
-RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index 0feaa179b2..6563181ca2 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,12 +51,12 @@ public:
private:
RID shader;
- Mode mode;
+ Mode mode = MODE_SPATIAL;
// hack the name of performance
// shaders keep a list of ShaderMaterial -> RenderingServer name translations, to make
// conversion fast and save memory.
- mutable bool params_cache_dirty;
+ mutable bool params_cache_dirty = true;
mutable Map<StringName, StringName> params_cache; //map a shader param to a material param..
Map<StringName, Ref<Texture2D>> default_textures;
@@ -102,7 +102,7 @@ VARIANT_ENUM_CAST(Shader::Mode);
class ResourceFormatLoaderShader : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp
index 94cecc76eb..013b1ef1a9 100644
--- a/scene/resources/shape_2d.cpp
+++ b/scene/resources/shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,11 @@
/*************************************************************************/
#include "shape_2d.h"
+
+#include "core/config/engine.h"
+#include "core/config/project_settings.h"
#include "servers/physics_server_2d.h"
+
RID Shape2D::get_rid() const {
return shape;
}
@@ -105,9 +109,17 @@ void Shape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias");
}
+bool Shape2D::is_collision_outline_enabled() {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ return true;
+ }
+#endif
+ return GLOBAL_DEF("debug/shapes/collision/draw_2d_outlines", true);
+}
+
Shape2D::Shape2D(const RID &p_rid) {
shape = p_rid;
- custom_bias = 0;
}
Shape2D::~Shape2D() {
diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h
index 495ffdd38b..14bdd60e4b 100644
--- a/scene/resources/shape_2d.h
+++ b/scene/resources/shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,7 @@ class Shape2D : public Resource {
OBJ_SAVE_TYPE(Shape2D);
RID shape;
- real_t custom_bias;
+ real_t custom_bias = 0.0;
protected:
static void _bind_methods();
@@ -61,6 +61,9 @@ public:
/// Returns the radius of a circle that fully enclose this shape
virtual real_t get_enclosing_radius() const = 0;
virtual RID get_rid() const override;
+
+ static bool is_collision_outline_enabled();
+
Shape2D();
~Shape2D();
};
diff --git a/scene/resources/shape_3d.cpp b/scene/resources/shape_3d.cpp
index 59766f4f1f..5761a405ce 100644
--- a/scene/resources/shape_3d.cpp
+++ b/scene/resources/shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -66,7 +66,7 @@ Ref<ArrayMesh> Shape3D::get_debug_mesh() {
debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh));
- if (!lines.empty()) {
+ if (!lines.is_empty()) {
//make mesh
Vector<Vector3> array;
array.resize(lines.size());
diff --git a/scene/resources/shape_3d.h b/scene/resources/shape_3d.h
index 5a9c2e3b9c..0644940fd4 100644
--- a/scene/resources/shape_3d.h
+++ b/scene/resources/shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp
index e88841a531..fee8fdbde2 100644
--- a/scene/resources/skin.cpp
+++ b/scene/resources/skin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,7 +58,7 @@ void Skin::set_bind_name(int p_index, const StringName &p_name) {
binds_ptr[p_index].name = p_name;
emit_changed();
if (notify_change) {
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -81,6 +81,10 @@ void Skin::clear_binds() {
emit_changed();
}
+void Skin::reset_state() {
+ clear_binds();
+}
+
bool Skin::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
if (name == "bind_count") {
@@ -153,6 +157,4 @@ void Skin::_bind_methods() {
}
Skin::Skin() {
- bind_count = 0;
- binds_ptr = nullptr;
}
diff --git a/scene/resources/skin.h b/scene/resources/skin.h
index e6ed4f1768..f5d64f96aa 100644
--- a/scene/resources/skin.h
+++ b/scene/resources/skin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,14 +44,15 @@ class Skin : public Resource {
Vector<Bind> binds;
- Bind *binds_ptr;
- int bind_count;
+ Bind *binds_ptr = nullptr;
+ int bind_count = 0;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
static void _bind_methods();
public:
diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp
index 7e32516f94..71424ba8ac 100644
--- a/scene/resources/sky.cpp
+++ b/scene/resources/sky.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -102,8 +102,6 @@ void Sky::_bind_methods() {
}
Sky::Sky() {
- mode = PROCESS_MODE_AUTOMATIC;
- radiance_size = RADIANCE_SIZE_256;
sky = RS::get_singleton()->sky_create();
}
diff --git a/scene/resources/sky.h b/scene/resources/sky.h
index 526ca94317..f0226d321d 100644
--- a/scene/resources/sky.h
+++ b/scene/resources/sky.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,8 +59,8 @@ public:
private:
RID sky;
- ProcessMode mode;
- RadianceSize radiance_size;
+ ProcessMode mode = PROCESS_MODE_AUTOMATIC;
+ RadianceSize radiance_size = RADIANCE_SIZE_256;
Ref<Material> sky_material;
protected:
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 05bb13a1e0..b2efecb1cb 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -522,53 +522,59 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
code += "}\n\n";
code += "void fragment() {\n";
- code += "\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n";
- code += "\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n";
- code += "\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n";
-
- code += "\t// rayleigh coefficients\n";
- code += "\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n";
- code += "\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n";
- code += "\t// mie coefficients from Preetham\n";
- code += "\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n";
-
- code += "\t// optical length\n";
- code += "\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n";
- code += "\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n";
- code += "\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n";
- code += "\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n";
-
- code += "\t// light extinction based on thickness of atmosphere\n";
- code += "\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n";
-
- code += "\t// in scattering\n";
- code += "\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n";
-
- code += "\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n";
- code += "\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n";
-
- code += "\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n";
- code += "\tvec3 betaMTheta = mie_beta * mie_phase;\n\n";
-
- code += "\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n";
- code += "\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n";
- code += "\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n";
-
- code += "\t// Hack in the ground color\n";
- code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
-
- code += "\t// Solar disk and out-scattering\n";
- code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n";
- code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
- code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
- code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
- code += "\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n";
-
- code += "\tvec3 color = (Lin + L0) * 0.04;\n";
- code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
- code += "\tCOLOR *= exposure;\n";
- code += "\t// Make optional, eliminates banding\n";
- code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n";
+ code += "\tif (LIGHT0_ENABLED) {\n";
+ code += "\t\tfloat zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 );\n";
+ code += "\t\tfloat sun_energy = max(0.0, 1.0 - exp(-((PI * 0.5) - acos(zenith_angle)))) * SUN_ENERGY * LIGHT0_ENERGY;\n";
+ code += "\t\tfloat sun_fade = 1.0 - clamp(1.0 - exp(LIGHT0_DIRECTION.y), 0.0, 1.0);\n\n";
+
+ code += "\t\t// rayleigh coefficients\n";
+ code += "\t\tfloat rayleigh_coefficient = rayleigh - ( 1.0 * ( 1.0 - sun_fade ) );\n";
+ code += "\t\tvec3 rayleigh_beta = rayleigh_coefficient * rayleigh_color.rgb * 0.0001;\n";
+ code += "\t\t// mie coefficients from Preetham\n";
+ code += "\t\tvec3 mie_beta = turbidity * mie * mie_color.rgb * 0.000434;\n\n";
+
+ code += "\t\t// optical length\n";
+ code += "\t\tfloat zenith = acos(max(0.0, dot(UP, EYEDIR)));\n";
+ code += "\t\tfloat optical_mass = 1.0 / (cos(zenith) + 0.15 * pow(93.885 - degrees(zenith), -1.253));\n";
+ code += "\t\tfloat rayleigh_scatter = rayleigh_zenith_size * optical_mass;\n";
+ code += "\t\tfloat mie_scatter = mie_zenith_size * optical_mass;\n\n";
+
+ code += "\t\t// light extinction based on thickness of atmosphere\n";
+ code += "\t\tvec3 extinction = exp(-(rayleigh_beta * rayleigh_scatter + mie_beta * mie_scatter));\n\n";
+
+ code += "\t\t// in scattering\n";
+ code += "\t\tfloat cos_theta = dot(EYEDIR, normalize(LIGHT0_DIRECTION));\n\n";
+
+ code += "\t\tfloat rayleigh_phase = (3.0 / (16.0 * PI)) * (1.0 + pow(cos_theta * 0.5 + 0.5, 2.0));\n";
+ code += "\t\tvec3 betaRTheta = rayleigh_beta * rayleigh_phase;\n\n";
+
+ code += "\t\tfloat mie_phase = henyey_greenstein(cos_theta, mie_eccentricity);\n";
+ code += "\t\tvec3 betaMTheta = mie_beta * mie_phase;\n\n";
+
+ code += "\t\tvec3 Lin = pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * (1.0 - extinction), vec3(1.5));\n";
+ code += "\t\t// Hack from https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Sky.js\n";
+ code += "\t\tLin *= mix(vec3(1.0), pow(sun_energy * ((betaRTheta + betaMTheta) / (rayleigh_beta + mie_beta)) * extinction, vec3(0.5)), clamp(pow(1.0 - zenith_angle, 5.0), 0.0, 1.0));\n\n";
+
+ code += "\t\t// Hack in the ground color\n";
+ code += "\t\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
+
+ code += "\t\t// Solar disk and out-scattering\n";
+ code += "\t\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n";
+ code += "\t\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
+ code += "\t\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
+ code += "\t\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
+ code += "\t\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n";
+
+ code += "\t\tvec3 color = (Lin + L0) * 0.04;\n";
+ code += "\t\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
+ code += "\t\tCOLOR *= exposure;\n";
+ code += "\t\t// Make optional, eliminates banding\n";
+ code += "\t\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n";
+ code += "\t} else {\n";
+ code += "\t\t// There is no sun, so display night_sky and nothing else\n";
+ code += "\t\tCOLOR = texture(night_sky, SKY_COORDS).xyz * 0.04;\n";
+ code += "\t\tCOLOR *= exposure;\n";
+ code += "\t}\n";
code += "}\n";
shader = RS::get_singleton()->shader_create();
@@ -591,5 +597,4 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
PhysicalSkyMaterial::~PhysicalSkyMaterial() {
RS::get_singleton()->free(shader);
- RS::get_singleton()->material_set_shader(_get_material(), RID());
}
diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h
index 5411994b7d..8fe015519d 100644
--- a/scene/resources/sky_material.h
+++ b/scene/resources/sky_material.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -89,7 +89,7 @@ public:
float get_sun_curve() const;
virtual Shader::Mode get_shader_mode() const override;
- RID get_shader_rid() const;
+ virtual RID get_shader_rid() const override;
ProceduralSkyMaterial();
~ProceduralSkyMaterial();
@@ -114,7 +114,7 @@ public:
Ref<Texture2D> get_panorama() const;
virtual Shader::Mode get_shader_mode() const override;
- RID get_shader_rid() const;
+ virtual RID get_shader_rid() const override;
PanoramaSkyMaterial();
~PanoramaSkyMaterial();
@@ -180,7 +180,7 @@ public:
Ref<Texture2D> get_night_sky() const;
virtual Shader::Mode get_shader_mode() const override;
- RID get_shader_rid() const;
+ virtual RID get_shader_rid() const override;
PhysicalSkyMaterial();
~PhysicalSkyMaterial();
diff --git a/scene/resources/sphere_shape_3d.cpp b/scene/resources/sphere_shape_3d.cpp
index 64e0a701b7..e4b4398063 100644
--- a/scene/resources/sphere_shape_3d.cpp
+++ b/scene/resources/sphere_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -66,7 +66,6 @@ void SphereShape3D::set_radius(float p_radius) {
radius = p_radius;
_update_shape();
notify_change_to_owners();
- _change_notify("radius");
}
float SphereShape3D::get_radius() const {
diff --git a/scene/resources/sphere_shape_3d.h b/scene/resources/sphere_shape_3d.h
index 5cad67aea5..eddd2a2132 100644
--- a/scene/resources/sphere_shape_3d.h
+++ b/scene/resources/sphere_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 0271edaff0..2159f1bc97 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -123,7 +123,6 @@ void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) {
}
emit_signal("texture_changed");
emit_changed();
- _change_notify("texture");
}
Ref<Texture2D> StyleBoxTexture::get_texture() const {
@@ -135,13 +134,6 @@ void StyleBoxTexture::set_margin_size(Side p_side, float p_size) {
margin[p_side] = p_size;
emit_changed();
- static const char *margin_prop[4] = {
- "content_margin_left",
- "content_margin_top",
- "content_margin_right",
- "content_margin_bottom",
- };
- _change_notify(margin_prop[p_side]);
}
float StyleBoxTexture::get_margin_size(Side p_side) const {
@@ -228,7 +220,6 @@ void StyleBoxTexture::set_region_rect(const Rect2 &p_region_rect) {
region_rect = p_region_rect;
emit_changed();
- _change_notify("region");
}
Rect2 StyleBoxTexture::get_region_rect() const {
@@ -320,20 +311,9 @@ void StyleBoxTexture::_bind_methods() {
BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_TILE_FIT);
}
-StyleBoxTexture::StyleBoxTexture() {
- for (int i = 0; i < 4; i++) {
- margin[i] = 0;
- expand_margin[i] = 0;
- }
- draw_center = true;
- modulate = Color(1, 1, 1, 1);
-
- axis_h = AXIS_STRETCH_MODE_STRETCH;
- axis_v = AXIS_STRETCH_MODE_STRETCH;
-}
+StyleBoxTexture::StyleBoxTexture() {}
-StyleBoxTexture::~StyleBoxTexture() {
-}
+StyleBoxTexture::~StyleBoxTexture() {}
////////////////
@@ -395,10 +375,10 @@ void StyleBoxFlat::set_corner_radius_all(int radius) {
emit_changed();
}
-void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_botton_right, const int radius_bottom_left) {
+void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_bottom_right, const int radius_bottom_left) {
corner_radius[0] = radius_top_left;
corner_radius[1] = radius_top_right;
- corner_radius[2] = radius_botton_right;
+ corner_radius[2] = radius_bottom_right;
corner_radius[3] = radius_bottom_left;
emit_changed();
@@ -480,6 +460,7 @@ Point2 StyleBoxFlat::get_shadow_offset() const {
void StyleBoxFlat::set_anti_aliased(const bool &p_anti_aliased) {
anti_aliased = p_anti_aliased;
emit_changed();
+ notify_property_list_changed();
}
bool StyleBoxFlat::is_anti_aliased() const {
@@ -576,8 +557,8 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color
color = outer_color;
corner_point = outer_points[corner_index];
}
- float x = radius * (float)cos((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.x;
- float y = radius * (float)sin((double)corner_index * Math_PI / 2.0 + (double)detail / (double)adapted_corner_detail * Math_PI / 2.0 + Math_PI) + corner_point.y;
+ real_t x = radius * (real_t)cos((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.x;
+ real_t y = radius * (real_t)sin((corner_index + detail / (double)adapted_corner_detail) * (Math_TAU / 4.0) + Math_PI) + corner_point.y;
verts.push_back(Vector2(x, y));
colors.push_back(color);
}
@@ -687,7 +668,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
if (aa_on) {
for (int i = 0; i < 4; i++) {
if (border_width[i] > 0) {
- border_style_rect = border_style_rect.grow_margin((Side)i, -aa_size_grow);
+ border_style_rect = border_style_rect.grow_side((Side)i, -aa_size_grow);
}
}
}
@@ -801,6 +782,12 @@ float StyleBoxFlat::get_style_margin(Side p_side) const {
return border_width[p_side];
}
+void StyleBoxFlat::_validate_property(PropertyInfo &property) const {
+ if (!anti_aliased && property.name == "anti_aliasing_size") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &StyleBoxFlat::set_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_color"), &StyleBoxFlat::get_bg_color);
@@ -888,38 +875,9 @@ void StyleBoxFlat::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "anti_aliasing_size", PROPERTY_HINT_RANGE, "1,5,1"), "set_aa_size", "get_aa_size");
}
-StyleBoxFlat::StyleBoxFlat() {
- bg_color = Color(0.6, 0.6, 0.6);
- shadow_color = Color(0, 0, 0, 0.6);
- border_color = Color(0.8, 0.8, 0.8);
-
- blend_border = false;
- draw_center = true;
- anti_aliased = true;
+StyleBoxFlat::StyleBoxFlat() {}
- shadow_size = 0;
- shadow_offset = Point2(0, 0);
- corner_detail = 8;
- aa_size = 1;
-
- border_width[0] = 0;
- border_width[1] = 0;
- border_width[2] = 0;
- border_width[3] = 0;
-
- expand_margin[0] = 0;
- expand_margin[1] = 0;
- expand_margin[2] = 0;
- expand_margin[3] = 0;
-
- corner_radius[0] = 0;
- corner_radius[1] = 0;
- corner_radius[2] = 0;
- corner_radius[3] = 0;
-}
-
-StyleBoxFlat::~StyleBoxFlat() {
-}
+StyleBoxFlat::~StyleBoxFlat() {}
void StyleBoxLine::set_color(const Color &p_color) {
color = p_color;
@@ -986,8 +944,17 @@ void StyleBoxLine::_bind_methods() {
}
float StyleBoxLine::get_style_margin(Side p_side) const {
- ERR_FAIL_INDEX_V((int)p_side, 4, thickness);
- return thickness;
+ ERR_FAIL_INDEX_V((int)p_side, 4, 0);
+
+ if (vertical) {
+ if (p_side == SIDE_LEFT || p_side == SIDE_RIGHT) {
+ return thickness / 2.0;
+ }
+ } else if (p_side == SIDE_TOP || p_side == SIDE_BOTTOM) {
+ return thickness / 2.0;
+ }
+
+ return 0;
}
Size2 StyleBoxLine::get_center_size() const {
@@ -1011,12 +978,6 @@ void StyleBoxLine::draw(RID p_canvas_item, const Rect2 &p_rect) const {
vs->canvas_item_add_rect(p_canvas_item, r, color);
}
-StyleBoxLine::StyleBoxLine() {
- grow_begin = 1.0;
- grow_end = 1.0;
- thickness = 1;
- color = Color(0.0, 0.0, 0.0);
- vertical = false;
-}
+StyleBoxLine::StyleBoxLine() {}
StyleBoxLine::~StyleBoxLine() {}
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 52d3160d36..dd5c873a00 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -86,14 +86,14 @@ public:
};
private:
- float expand_margin[4];
- float margin[4];
+ float expand_margin[4] = {};
+ float margin[4] = {};
Rect2 region_rect;
Ref<Texture2D> texture;
- bool draw_center;
- Color modulate;
- AxisStretchMode axis_h;
- AxisStretchMode axis_v;
+ bool draw_center = true;
+ Color modulate = Color(1, 1, 1, 1);
+ AxisStretchMode axis_h = AXIS_STRETCH_MODE_STRETCH;
+ AxisStretchMode axis_v = AXIS_STRETCH_MODE_STRETCH;
protected:
virtual float get_style_margin(Side p_side) const override;
@@ -139,26 +139,27 @@ VARIANT_ENUM_CAST(StyleBoxTexture::AxisStretchMode)
class StyleBoxFlat : public StyleBox {
GDCLASS(StyleBoxFlat, StyleBox);
- Color bg_color;
- Color shadow_color;
- Color border_color;
+ Color bg_color = Color(0.6, 0.6, 0.6);
+ Color shadow_color = Color(0, 0, 0, 0.6);
+ Color border_color = Color(0.8, 0.8, 0.8);
- int border_width[4];
- int expand_margin[4];
- int corner_radius[4];
+ int border_width[4] = {};
+ int expand_margin[4] = {};
+ int corner_radius[4] = {};
- bool draw_center;
- bool blend_border;
- bool anti_aliased;
+ bool draw_center = true;
+ bool blend_border = false;
+ bool anti_aliased = true;
- int corner_detail;
- int shadow_size;
+ int corner_detail = 8;
+ int shadow_size = 0;
Point2 shadow_offset;
- int aa_size;
+ int aa_size = 1;
protected:
virtual float get_style_margin(Side p_side) const override;
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
//Color
@@ -183,7 +184,7 @@ public:
//CORNER
void set_corner_radius_all(int radius);
- void set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_botton_right, const int radius_bottom_left);
+ void set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_bottom_right, const int radius_bottom_left);
void set_corner_radius(Corner p_corner, const int radius);
int get_corner_radius(Corner p_corner) const;
@@ -231,10 +232,10 @@ public:
class StyleBoxLine : public StyleBox {
GDCLASS(StyleBoxLine, StyleBox);
Color color;
- int thickness;
- bool vertical;
- float grow_begin;
- float grow_end;
+ int thickness = 1;
+ bool vertical = false;
+ float grow_begin = 1.0;
+ float grow_end = 1.0;
protected:
virtual float get_style_margin(Side p_side) const override;
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 50308d641a..47933bd69a 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,6 +35,8 @@
SurfaceTool::OptimizeVertexCacheFunc SurfaceTool::optimize_vertex_cache_func = nullptr;
SurfaceTool::SimplifyFunc SurfaceTool::simplify_func = nullptr;
+SurfaceTool::SimplifyScaleFunc SurfaceTool::simplify_scale_func = nullptr;
+SurfaceTool::SimplifySloppyFunc SurfaceTool::simplify_sloppy_func = nullptr;
bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const {
if (vertex != p_vertex.vertex) {
@@ -158,7 +160,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
//cap
weights.resize(expected_vertices);
//renormalize
- float total = 0;
+ float total = 0.0;
for (int i = 0; i < expected_vertices; i++) {
total += weights[i].weight;
}
@@ -297,6 +299,7 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vect
void SurfaceTool::add_index(int p_index) {
ERR_FAIL_COND(!begun);
+ ERR_FAIL_COND(p_index < 0);
format |= Mesh::ARRAY_FORMAT_INDEX;
index_array.push_back(p_index);
@@ -1194,12 +1197,7 @@ void SurfaceTool::_bind_methods() {
}
SurfaceTool::SurfaceTool() {
- first = false;
- begun = false;
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
last_custom_format[i] = CUSTOM_MAX;
}
- primitive = Mesh::PRIMITIVE_LINES;
- skin_weights = SKIN_4_WEIGHTS;
- format = 0;
}
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 0e60bfe389..17efdcba71 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -78,6 +78,10 @@ public:
static OptimizeVertexCacheFunc optimize_vertex_cache_func;
typedef size_t (*SimplifyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_error);
static SimplifyFunc simplify_func;
+ typedef float (*SimplifyScaleFunc)(const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
+ static SimplifyScaleFunc simplify_scale_func;
+ typedef size_t (*SimplifySloppyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *out_result_error);
+ static SimplifySloppyFunc simplify_sloppy_func;
private:
struct VertexHasher {
@@ -85,17 +89,17 @@ private:
};
struct WeightSort {
- int index;
- float weight;
+ int index = 0;
+ float weight = 0.0;
bool operator<(const WeightSort &p_right) const {
return weight < p_right.weight;
}
};
- bool begun;
- bool first;
- Mesh::PrimitiveType primitive;
- uint32_t format;
+ bool begun = false;
+ bool first = false;
+ Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_LINES;
+ uint32_t format = 0;
Ref<Material> material;
//arrays
LocalVector<Vertex> vertex_array;
@@ -111,7 +115,7 @@ private:
Plane last_tangent;
uint32_t last_smooth_group = 0;
- SkinWeightCount skin_weights;
+ SkinWeightCount skin_weights = SKIN_4_WEIGHTS;
Color last_custom[RS::ARRAY_CUSTOM_COUNT];
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index e3e4373fa9..9dd00849f4 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -110,16 +110,13 @@ TextEdit *SyntaxHighlighter::get_text_edit() {
}
void SyntaxHighlighter::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_line_syntax_highlighting", "p_line"), &SyntaxHighlighter::get_line_syntax_highlighting);
+ ClassDB::bind_method(D_METHOD("get_line_syntax_highlighting", "line"), &SyntaxHighlighter::get_line_syntax_highlighting);
ClassDB::bind_method(D_METHOD("update_cache"), &SyntaxHighlighter::update_cache);
ClassDB::bind_method(D_METHOD("clear_highlighting_cache"), &SyntaxHighlighter::clear_highlighting_cache);
ClassDB::bind_method(D_METHOD("get_text_edit"), &SyntaxHighlighter::get_text_edit);
- ClassDB::bind_method(D_METHOD("_get_line_syntax_highlighting", "p_line"), &SyntaxHighlighter::_get_line_syntax_highlighting);
- ClassDB::bind_method(D_METHOD("_update_cache"), &SyntaxHighlighter::_update_cache);
- ClassDB::bind_method(D_METHOD("_clear_highlighting_cache"), &SyntaxHighlighter::_clear_highlighting_cache);
-
- BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_line_syntax_highlighting", PropertyInfo(Variant::INT, "p_line")));
+ BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_line_syntax_highlighting", PropertyInfo(Variant::INT, "line")));
+ BIND_VMETHOD(MethodInfo("_clear_highlighting_cache"));
BIND_VMETHOD(MethodInfo("_update_cache"));
}
@@ -552,7 +549,7 @@ Dictionary CodeHighlighter::get_color_regions() const {
Dictionary r_color_regions;
for (int i = 0; i < color_regions.size(); i++) {
ColorRegion region = color_regions[i];
- r_color_regions[region.start_key + (region.end_key.empty() ? "" : " " + region.end_key)] = region.color;
+ r_color_regions[region.start_key + (region.end_key.is_empty() ? "" : " " + region.end_key)] = region.color;
}
return r_color_regions;
}
@@ -576,11 +573,11 @@ void CodeHighlighter::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_member_keyword_colors"), &CodeHighlighter::clear_member_keyword_colors);
ClassDB::bind_method(D_METHOD("get_member_keyword_colors"), &CodeHighlighter::get_member_keyword_colors);
- ClassDB::bind_method(D_METHOD("add_color_region", "p_start_key", "p_end_key", "p_color", "p_line_only"), &CodeHighlighter::add_color_region, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("remove_color_region", "p_start_key"), &CodeHighlighter::remove_color_region);
- ClassDB::bind_method(D_METHOD("has_color_region", "p_start_key"), &CodeHighlighter::has_color_region);
+ ClassDB::bind_method(D_METHOD("add_color_region", "start_key", "end_key", "color", "line_only"), &CodeHighlighter::add_color_region, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("remove_color_region", "start_key"), &CodeHighlighter::remove_color_region);
+ ClassDB::bind_method(D_METHOD("has_color_region", "start_key"), &CodeHighlighter::has_color_region);
- ClassDB::bind_method(D_METHOD("set_color_regions", "p_color_regions"), &CodeHighlighter::set_color_regions);
+ ClassDB::bind_method(D_METHOD("set_color_regions", "color_regions"), &CodeHighlighter::set_color_regions);
ClassDB::bind_method(D_METHOD("clear_color_regions"), &CodeHighlighter::clear_color_regions);
ClassDB::bind_method(D_METHOD("get_color_regions"), &CodeHighlighter::get_color_regions);
diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h
index 62865920d3..f3964b0c8f 100644
--- a/scene/resources/syntax_highlighter.h
+++ b/scene/resources/syntax_highlighter.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -75,7 +75,7 @@ private:
Color color;
String start_key;
String end_key;
- bool line_only;
+ bool line_only = false;
};
Vector<ColorRegion> color_regions;
Map<int, int> color_region_cache;
diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp
index e3bd5ce0ae..cf07003720 100644
--- a/scene/resources/text_file.cpp
+++ b/scene/resources/text_file.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h
index fa812b1e67..005075a218 100644
--- a/scene/resources/text_file.h
+++ b/scene/resources/text_file.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp
index cc9b6758b6..925867a1f2 100644
--- a/scene/resources/text_line.cpp
+++ b/scene/resources/text_line.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -97,7 +97,7 @@ void TextLine::_bind_methods() {
void TextLine::_shape() {
if (dirty) {
- if (!tab_stops.empty()) {
+ if (!tab_stops.is_empty()) {
TS->shaped_text_tab_align(rid, tab_stops);
}
if (align == HALIGN_FILL) {
@@ -167,6 +167,7 @@ void TextLine::set_bidi_override(const Vector<Vector2i> &p_override) {
}
bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
+ ERR_FAIL_COND_V(p_fonts.is_null(), false);
bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
spacing_top = p_fonts->get_spacing(Font::SPACING_TOP);
spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM);
diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h
index 6ed3558bd9..74d4f2c32c 100644
--- a/scene/resources/text_line.h
+++ b/scene/resources/text_line.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,7 @@ class TextLine : public Reference {
bool dirty = true;
- float width = -1;
+ float width = -1.0;
uint8_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
HAlign align = HALIGN_LEFT;
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index fd6dd071eb..444a4bb22a 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,6 +55,9 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextParagraph::_set_bidi_override);
+ ClassDB::bind_method(D_METHOD("set_dropcap", "text", "fonts", "size", "dropcap_margins", "opentype_features", "language"), &TextParagraph::set_dropcap, DEFVAL(Rect2()), DEFVAL(Dictionary()), DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap);
+
ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextParagraph::add_string, DEFVAL(Dictionary()), DEFVAL(""));
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(VALIGN_CENTER), DEFVAL(1));
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(VALIGN_CENTER));
@@ -81,6 +84,7 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rid"), &TextParagraph::get_rid);
ClassDB::bind_method(D_METHOD("get_line_rid", "line"), &TextParagraph::get_line_rid);
+ ClassDB::bind_method(D_METHOD("get_dropcap_rid"), &TextParagraph::get_dropcap_rid);
ClassDB::bind_method(D_METHOD("get_line_count"), &TextParagraph::get_line_count);
@@ -94,12 +98,18 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_underline_position", "line"), &TextParagraph::get_line_underline_position);
ClassDB::bind_method(D_METHOD("get_line_underline_thickness", "line"), &TextParagraph::get_line_underline_thickness);
- ClassDB::bind_method(D_METHOD("draw", "canvas", "pos", "color"), &TextParagraph::draw, DEFVAL(Color(1, 1, 1)));
- ClassDB::bind_method(D_METHOD("draw_outline", "canvas", "outline_size", "color"), &TextParagraph::draw_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
+ ClassDB::bind_method(D_METHOD("get_dropcap_size"), &TextParagraph::get_dropcap_size);
+ ClassDB::bind_method(D_METHOD("get_dropcap_lines"), &TextParagraph::get_dropcap_lines);
+
+ ClassDB::bind_method(D_METHOD("draw", "canvas", "pos", "color", "dc_color"), &TextParagraph::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1)));
+ ClassDB::bind_method(D_METHOD("draw_outline", "canvas", "pos", "outline_size", "color", "dc_color"), &TextParagraph::draw_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_line", "canvas", "pos", "line", "color"), &TextParagraph::draw_line, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_line_outline", "canvas", "pos", "line", "outline_size", "color"), &TextParagraph::draw_line_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
+ ClassDB::bind_method(D_METHOD("draw_dropcap", "canvas", "pos", "color"), &TextParagraph::draw_dropcap, DEFVAL(Color(1, 1, 1)));
+ ClassDB::bind_method(D_METHOD("draw_dropcap_outline", "canvas", "pos", "outline_size", "color"), &TextParagraph::draw_dropcap_outline, DEFVAL(1), DEFVAL(Color(1, 1, 1)));
+
ClassDB::bind_method(D_METHOD("hit_test", "coords"), &TextParagraph::hit_test);
}
@@ -110,14 +120,50 @@ void TextParagraph::_shape_lines() {
}
lines.clear();
- if (!tab_stops.empty()) {
+ if (!tab_stops.is_empty()) {
TS->shaped_text_tab_align(rid, tab_stops);
}
- Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(rid, width, 0, flags);
+ float h_offset = 0.f;
+ float v_offset = 0.f;
+ int start = 0;
+ dropcap_lines = 0;
+
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).x + dropcap_margins.size.x + dropcap_margins.position.x;
+ v_offset = TS->shaped_text_get_size(dropcap_rid).y + dropcap_margins.size.y + dropcap_margins.position.y;
+ } else {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).y + dropcap_margins.size.y + dropcap_margins.position.y;
+ v_offset = TS->shaped_text_get_size(dropcap_rid).x + dropcap_margins.size.x + dropcap_margins.position.x;
+ }
+
+ if (h_offset > 0) {
+ // Dropcap, flow around.
+ Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(rid, width - h_offset, 0, flags);
+ for (int i = 0; i < line_breaks.size(); i++) {
+ RID line = TS->shaped_text_substr(rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x);
+ float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x;
+ if (v_offset < h) {
+ TS->free(line);
+ break;
+ }
+ if (!tab_stops.is_empty()) {
+ TS->shaped_text_tab_align(line, tab_stops);
+ }
+ if (align == HALIGN_FILL && (line_breaks.size() == 1 || i < line_breaks.size() - 1)) {
+ TS->shaped_text_fit_to_width(line, width - h_offset, flags);
+ }
+ dropcap_lines++;
+ v_offset -= h;
+ start = line_breaks[i].y;
+ lines.push_back(line);
+ }
+ }
+ // Use fixed for the rest of lines.
+ Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(rid, width, start, flags);
for (int i = 0; i < line_breaks.size(); i++) {
RID line = TS->shaped_text_substr(rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x);
- if (!tab_stops.empty()) {
+ if (!tab_stops.is_empty()) {
TS->shaped_text_tab_align(line, tab_stops);
}
if (align == HALIGN_FILL && (line_breaks.size() == 1 || i < line_breaks.size() - 1)) {
@@ -139,6 +185,10 @@ RID TextParagraph::get_line_rid(int p_line) const {
return lines[p_line];
}
+RID TextParagraph::get_dropcap_rid() const {
+ return dropcap_rid;
+}
+
void TextParagraph::clear() {
spacing_top = 0;
spacing_bottom = 0;
@@ -147,10 +197,12 @@ void TextParagraph::clear() {
}
lines.clear();
TS->shaped_text_clear(rid);
+ TS->shaped_text_clear(dropcap_rid);
}
void TextParagraph::set_preserve_invalid(bool p_enabled) {
TS->shaped_text_set_preserve_invalid(rid, p_enabled);
+ TS->shaped_text_set_preserve_invalid(dropcap_rid, p_enabled);
dirty_lines = true;
}
@@ -160,6 +212,7 @@ bool TextParagraph::get_preserve_invalid() const {
void TextParagraph::set_preserve_control(bool p_enabled) {
TS->shaped_text_set_preserve_control(rid, p_enabled);
+ TS->shaped_text_set_preserve_control(dropcap_rid, p_enabled);
dirty_lines = true;
}
@@ -169,6 +222,7 @@ bool TextParagraph::get_preserve_control() const {
void TextParagraph::set_direction(TextServer::Direction p_direction) {
TS->shaped_text_set_direction(rid, p_direction);
+ TS->shaped_text_set_direction(dropcap_rid, p_direction);
dirty_lines = true;
}
@@ -179,6 +233,7 @@ TextServer::Direction TextParagraph::get_direction() const {
void TextParagraph::set_orientation(TextServer::Orientation p_orientation) {
TS->shaped_text_set_orientation(rid, p_orientation);
+ TS->shaped_text_set_orientation(dropcap_rid, p_orientation);
dirty_lines = true;
}
@@ -187,7 +242,23 @@ TextServer::Orientation TextParagraph::get_orientation() const {
return TS->shaped_text_get_orientation(rid);
}
+bool TextParagraph::set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins, const Dictionary &p_opentype_features, const String &p_language) {
+ ERR_FAIL_COND_V(p_fonts.is_null(), false);
+ TS->shaped_text_clear(dropcap_rid);
+ dropcap_margins = p_dropcap_margins;
+ bool res = TS->shaped_text_add_string(dropcap_rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
+ dirty_lines = true;
+ return res;
+}
+
+void TextParagraph::clear_dropcap() {
+ dropcap_margins = Rect2();
+ TS->shaped_text_clear(dropcap_rid);
+ dirty_lines = true;
+}
+
bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
+ ERR_FAIL_COND_V(p_fonts.is_null(), false);
bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
spacing_top = p_fonts->get_spacing(Font::SPACING_TOP);
spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM);
@@ -359,16 +430,57 @@ float TextParagraph::get_line_underline_thickness(int p_line) const {
return TS->shaped_text_get_underline_thickness(lines[p_line]);
}
-void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const {
+Size2 TextParagraph::get_dropcap_size() const {
+ return TS->shaped_text_get_size(dropcap_rid) + dropcap_margins.size + dropcap_margins.position;
+}
+
+int TextParagraph::get_dropcap_lines() const {
+ return dropcap_lines;
+}
+
+void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color, const Color &p_dc_color) const {
const_cast<TextParagraph *>(this)->_shape_lines();
Vector2 ofs = p_pos;
+ float h_offset = 0.f;
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).x + dropcap_margins.size.x + dropcap_margins.position.x;
+ } else {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).y + dropcap_margins.size.y + dropcap_margins.position.y;
+ }
+
+ if (h_offset > 0) {
+ // Draw dropcap.
+ Vector2 dc_off = ofs;
+ if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ dc_off.x += width - h_offset;
+ } else {
+ dc_off.y += width - h_offset;
+ }
+ }
+ TS->shaped_text_draw(dropcap_rid, p_canvas, dc_off + Vector2(0, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.size.y + dropcap_margins.position.y / 2), -1, -1, p_dc_color);
+ }
+
for (int i = 0; i < lines.size(); i++) {
+ float l_width = width;
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
ofs.y += TS->shaped_text_get_ascent(lines[i]) + spacing_top;
+ if (i <= dropcap_lines) {
+ if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+ ofs.x -= h_offset;
+ }
+ l_width -= h_offset;
+ }
} else {
ofs.y = p_pos.y;
ofs.x += TS->shaped_text_get_ascent(lines[i]) + spacing_top;
+ if (i <= dropcap_lines) {
+ if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+ ofs.x -= h_offset;
+ }
+ l_width -= h_offset;
+ }
}
float length = TS->shaped_text_get_width(lines[i]);
if (width > 0) {
@@ -378,16 +490,16 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
break;
case HALIGN_CENTER: {
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.x += Math::floor((width - length) / 2.0);
+ ofs.x += Math::floor((l_width - length) / 2.0);
} else {
- ofs.y += Math::floor((width - length) / 2.0);
+ ofs.y += Math::floor((l_width - length) / 2.0);
}
} break;
case HALIGN_RIGHT: {
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.x += width - length;
+ ofs.x += l_width - length;
} else {
- ofs.y += width - length;
+ ofs.y += l_width - length;
}
} break;
}
@@ -398,7 +510,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
} else {
clip_l = MAX(0, p_pos.y - ofs.y);
}
- TS->shaped_text_draw(lines[i], p_canvas, ofs, clip_l, clip_l + width, p_color);
+ TS->shaped_text_draw(lines[i], p_canvas, ofs, clip_l, clip_l + l_width, p_color);
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
ofs.y += TS->shaped_text_get_descent(lines[i]) + spacing_bottom;
@@ -409,16 +521,50 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
}
}
-void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color) const {
+void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color, const Color &p_dc_color) const {
const_cast<TextParagraph *>(this)->_shape_lines();
Vector2 ofs = p_pos;
+
+ float h_offset = 0.f;
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).x + dropcap_margins.size.x + dropcap_margins.position.x;
+ } else {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).y + dropcap_margins.size.y + dropcap_margins.position.y;
+ }
+
+ if (h_offset > 0) {
+ // Draw dropcap.
+ Vector2 dc_off = ofs;
+ if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ dc_off.x += width - h_offset;
+ } else {
+ dc_off.y += width - h_offset;
+ }
+ }
+ TS->shaped_text_draw_outline(dropcap_rid, p_canvas, dc_off + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_outline_size, p_dc_color);
+ }
+
for (int i = 0; i < lines.size(); i++) {
+ float l_width = width;
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
ofs.y += TS->shaped_text_get_ascent(lines[i]) + spacing_top;
+ if (i <= dropcap_lines) {
+ if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+ ofs.x -= h_offset;
+ }
+ l_width -= h_offset;
+ }
} else {
ofs.y = p_pos.y;
ofs.x += TS->shaped_text_get_ascent(lines[i]) + spacing_top;
+ if (i <= dropcap_lines) {
+ if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
+ ofs.x -= h_offset;
+ }
+ l_width -= h_offset;
+ }
}
float length = TS->shaped_text_get_width(lines[i]);
if (width > 0) {
@@ -428,16 +574,16 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
break;
case HALIGN_CENTER: {
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.x += Math::floor((width - length) / 2.0);
+ ofs.x += Math::floor((l_width - length) / 2.0);
} else {
- ofs.y += Math::floor((width - length) / 2.0);
+ ofs.y += Math::floor((l_width - length) / 2.0);
}
} break;
case HALIGN_RIGHT: {
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.x += width - length;
+ ofs.x += l_width - length;
} else {
- ofs.y += width - length;
+ ofs.y += l_width - length;
}
} break;
}
@@ -448,7 +594,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
} else {
clip_l = MAX(0, p_pos.y - ofs.y);
}
- TS->shaped_text_draw_outline(lines[i], p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color);
+ TS->shaped_text_draw_outline(lines[i], p_canvas, ofs, clip_l, clip_l + l_width, p_outline_size, p_color);
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.x = p_pos.x;
ofs.y += TS->shaped_text_get_descent(lines[i]) + spacing_bottom;
@@ -485,11 +631,56 @@ int TextParagraph::hit_test(const Point2 &p_coords) const {
return TS->shaped_text_get_range(rid).y;
}
+void TextParagraph::draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color) const {
+ Vector2 ofs = p_pos;
+ float h_offset = 0.f;
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).x + dropcap_margins.size.x + dropcap_margins.position.x;
+ } else {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).y + dropcap_margins.size.y + dropcap_margins.position.y;
+ }
+
+ if (h_offset > 0) {
+ // Draw dropcap.
+ if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ ofs.x += width - h_offset;
+ } else {
+ ofs.y += width - h_offset;
+ }
+ }
+ TS->shaped_text_draw(dropcap_rid, p_canvas, ofs + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_color);
+ }
+}
+
+void TextParagraph::draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size, const Color &p_color) const {
+ Vector2 ofs = p_pos;
+ float h_offset = 0.f;
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).x + dropcap_margins.size.x + dropcap_margins.position.x;
+ } else {
+ h_offset = TS->shaped_text_get_size(dropcap_rid).y + dropcap_margins.size.y + dropcap_margins.position.y;
+ }
+
+ if (h_offset > 0) {
+ // Draw dropcap.
+ if (TS->shaped_text_get_direction(dropcap_rid) == TextServer::DIRECTION_RTL) {
+ if (TS->shaped_text_get_orientation(dropcap_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ ofs.x += width - h_offset;
+ } else {
+ ofs.y += width - h_offset;
+ }
+ }
+ TS->shaped_text_draw_outline(dropcap_rid, p_canvas, ofs + Vector2(dropcap_margins.position.x, TS->shaped_text_get_ascent(dropcap_rid) + dropcap_margins.position.y), -1, -1, p_outline_size, p_color);
+ }
+}
+
void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color) const {
const_cast<TextParagraph *>(this)->_shape_lines();
ERR_FAIL_COND(p_line < 0 || p_line >= lines.size());
Vector2 ofs = p_pos;
+
if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
ofs.y += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top;
} else {
@@ -521,6 +712,7 @@ TextParagraph::TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int
TextParagraph::TextParagraph() {
rid = TS->create_shaped_text();
+ dropcap_rid = TS->create_shaped_text();
}
TextParagraph::~TextParagraph() {
@@ -529,4 +721,5 @@ TextParagraph::~TextParagraph() {
}
lines.clear();
TS->free(rid);
+ TS->free(dropcap_rid);
}
diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h
index f7f49e9058..a16fa8c3c4 100644
--- a/scene/resources/text_paragraph.h
+++ b/scene/resources/text_paragraph.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,6 +39,10 @@
class TextParagraph : public Reference {
GDCLASS(TextParagraph, Reference);
+ RID dropcap_rid;
+ int dropcap_lines = 0;
+ Rect2 dropcap_margins;
+
RID rid;
Vector<RID> lines;
int spacing_top = 0;
@@ -46,7 +50,7 @@ class TextParagraph : public Reference {
bool dirty_lines = true;
- float width = -1;
+ float width = -1.0;
uint8_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA;
HAlign align = HALIGN_LEFT;
@@ -60,6 +64,7 @@ protected:
public:
RID get_rid() const;
RID get_line_rid(int p_line) const;
+ RID get_dropcap_rid() const;
void clear();
@@ -77,6 +82,9 @@ public:
void set_bidi_override(const Vector<Vector2i> &p_override);
+ bool set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
+ void clear_dropcap();
+
bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
bool add_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER, int p_length = 1);
bool resize_object(Variant p_key, const Size2 &p_size, VAlign p_inline_align = VALIGN_CENTER);
@@ -108,12 +116,18 @@ public:
float get_line_underline_position(int p_line) const;
float get_line_underline_thickness(int p_line) const;
- void draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1)) const;
- void draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
+ Size2 get_dropcap_size() const;
+ int get_dropcap_lines() const;
+
+ void draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1), const Color &p_dc_color = Color(1, 1, 1)) const;
+ void draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1), const Color &p_dc_color = Color(1, 1, 1)) const;
void draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, const Color &p_color = Color(1, 1, 1)) const;
void draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_line, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
+ void draw_dropcap(RID p_canvas, const Vector2 &p_pos, const Color &p_color = Color(1, 1, 1)) const;
+ void draw_dropcap_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
+
int hit_test(const Point2 &p_coords) const;
void _set_bidi_override(const Array &p_override);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 706b18d2b5..d2bb1338d8 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -94,7 +94,7 @@ void ImageTexture::reload_from_file() {
create_from_image(img);
} else {
Resource::reload_from_file();
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
}
@@ -146,12 +146,12 @@ void ImageTexture::_reload_hook(const RID &p_hook) {
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(img);
RenderingServer::get_singleton()->texture_replace(texture, new_texture);
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
void ImageTexture::create_from_image(const Ref<Image> &p_image) {
- ERR_FAIL_COND_MSG(p_image.is_null(), "Invalid image");
+ ERR_FAIL_COND_MSG(p_image.is_null() || p_image->is_empty(), "Invalid image");
w = p_image->get_width();
h = p_image->get_height();
format = p_image->get_format();
@@ -163,7 +163,7 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image) {
RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_image);
RenderingServer::get_singleton()->texture_replace(texture, new_texture);
}
- _change_notify();
+ notify_property_list_changed();
emit_changed();
image_stored = true;
@@ -189,7 +189,7 @@ void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) {
RenderingServer::get_singleton()->texture_2d_update(texture, p_image);
}
- _change_notify();
+ notify_property_list_changed();
emit_changed();
alpha_cache.unref();
@@ -310,12 +310,7 @@ void ImageTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook);
}
-ImageTexture::ImageTexture() {
- w = h = 0;
- image_stored = false;
- mipmaps = false;
- format = Image::FORMAT_L8;
-}
+ImageTexture::ImageTexture() {}
ImageTexture::~ImageTexture() {
if (texture.is_valid()) {
@@ -371,8 +366,8 @@ Ref<Image> StreamTexture2D::load_image_from_file(FileAccess *f, int p_size_limit
img = Image::lossy_unpacker(pv);
}
- if (img.is_null() || img->empty()) {
- ERR_FAIL_COND_V(img.is_null() || img->empty(), Ref<Image>());
+ if (img.is_null() || img->is_empty()) {
+ ERR_FAIL_COND_V(img.is_null() || img->is_empty(), Ref<Image>());
}
if (first) {
@@ -548,7 +543,7 @@ Error StreamTexture2D::_load_data(const String &p_path, int &tw, int &th, int &t
memdelete(f);
- if (image.is_null() || image->empty()) {
+ if (image.is_null() || image->is_empty()) {
return ERR_CANT_OPEN;
}
@@ -617,7 +612,7 @@ Error StreamTexture2D::load(const String &p_path) {
}
#endif
- _change_notify();
+ notify_property_list_changed();
emit_changed();
return OK;
}
@@ -733,11 +728,7 @@ void StreamTexture2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
}
-StreamTexture2D::StreamTexture2D() {
- format = Image::FORMAT_MAX;
- w = 0;
- h = 0;
-}
+StreamTexture2D::StreamTexture2D() {}
StreamTexture2D::~StreamTexture2D() {
if (texture.is_valid()) {
@@ -745,7 +736,7 @@ StreamTexture2D::~StreamTexture2D() {
}
}
-RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
Ref<StreamTexture2D> st;
st.instance();
Error err = st->load(p_path);
@@ -924,7 +915,7 @@ Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_da
for (int i = 0; i < (r_depth + mipmaps); i++) {
Ref<Image> image = StreamTexture2D::load_image_from_file(f, 0);
- ERR_FAIL_COND_V(image.is_null() || image->empty(), ERR_CANT_OPEN);
+ ERR_FAIL_COND_V(image.is_null() || image->is_empty(), ERR_CANT_OPEN);
if (i == 0) {
r_format = image->get_format();
r_width = image->get_width();
@@ -968,7 +959,7 @@ Error StreamTexture3D::load(const String &p_path) {
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
- _change_notify();
+ notify_property_list_changed();
emit_changed();
return OK;
}
@@ -1033,13 +1024,7 @@ void StreamTexture3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
}
-StreamTexture3D::StreamTexture3D() {
- format = Image::FORMAT_MAX;
- w = 0;
- h = 0;
- d = 0;
- mipmaps = false;
-}
+StreamTexture3D::StreamTexture3D() {}
StreamTexture3D::~StreamTexture3D() {
if (texture.is_valid()) {
@@ -1049,7 +1034,7 @@ StreamTexture3D::~StreamTexture3D() {
/////////////////////////////
-RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
Ref<StreamTexture3D> st;
st.instance();
Error err = st->load(p_path);
@@ -1125,7 +1110,6 @@ void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) {
}
atlas = p_atlas;
emit_changed();
- _change_notify("atlas");
}
Ref<Texture2D> AtlasTexture::get_atlas() const {
@@ -1138,7 +1122,6 @@ void AtlasTexture::set_region(const Rect2 &p_region) {
}
region = p_region;
emit_changed();
- _change_notify("region");
}
Rect2 AtlasTexture::get_region() const {
@@ -1151,7 +1134,6 @@ void AtlasTexture::set_margin(const Rect2 &p_margin) {
}
margin = p_margin;
emit_changed();
- _change_notify("margin");
}
Rect2 AtlasTexture::get_margin() const {
@@ -1161,7 +1143,6 @@ Rect2 AtlasTexture::get_margin() const {
void AtlasTexture::set_filter_clip(const bool p_enable) {
filter_clip = p_enable;
emit_changed();
- _change_notify("filter_clip");
}
bool AtlasTexture::has_filter_clip() const {
@@ -1295,9 +1276,7 @@ bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
return atlas->is_pixel_opaque(x, y);
}
-AtlasTexture::AtlasTexture() {
- filter_clip = false;
-}
+AtlasTexture::AtlasTexture() {}
/////////////////////////////////////////
@@ -1698,9 +1677,7 @@ RID CurveTexture::get_rid() const {
return _texture;
}
-CurveTexture::CurveTexture() {
- _width = 2048;
-}
+CurveTexture::CurveTexture() {}
CurveTexture::~CurveTexture() {
if (_texture.is_valid()) {
@@ -1711,9 +1688,6 @@ CurveTexture::~CurveTexture() {
//////////////////
GradientTexture::GradientTexture() {
- update_pending = false;
- width = 2048;
-
_queue_update();
}
@@ -1926,7 +1900,7 @@ void AnimatedTexture::_update_proxy() {
}
}
time -= frame_limit;
- _change_notify("current_frame");
+
} else {
break;
}
@@ -2128,28 +2102,12 @@ AnimatedTexture::AnimatedTexture() {
proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
RenderingServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
- time = 0;
- frame_count = 1;
- fps = 4;
- prev_ticks = 0;
- current_frame = 0;
- pause = false;
- oneshot = false;
RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy));
-
-#ifndef NO_THREADS
- rw_lock = RWLock::create();
-#else
- rw_lock = nullptr;
-#endif
}
AnimatedTexture::~AnimatedTexture() {
RS::get_singleton()->free(proxy);
RS::get_singleton()->free(proxy_ph);
- if (rw_lock) {
- memdelete(rw_lock);
- }
}
///////////////////////////////
@@ -2223,7 +2181,7 @@ Error ImageTextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
"Cubemap array layers must be a multiple of 6");
}
- ERR_FAIL_COND_V(p_images[0].is_null() || p_images[0]->empty(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(p_images[0].is_null() || p_images[0]->is_empty(), ERR_INVALID_PARAMETER);
Image::Format new_format = p_images[0]->get_format();
int new_width = p_images[0]->get_width();
@@ -2297,11 +2255,6 @@ void ImageTextureLayered::_bind_methods() {
ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) {
layered_type = p_layered_type;
- format = Image::FORMAT_MAX;
-
- width = 0;
- height = 0;
- layers = 0;
}
ImageTextureLayered::~ImageTextureLayered() {
@@ -2361,7 +2314,7 @@ Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>>
for (uint32_t i = 0; i < layer_count; i++) {
Ref<Image> image = StreamTexture2D::load_image_from_file(f, p_size_limit);
- ERR_FAIL_COND_V(image.is_null() || image->empty(), ERR_CANT_OPEN);
+ ERR_FAIL_COND_V(image.is_null() || image->is_empty(), ERR_CANT_OPEN);
images.write[i] = image;
}
@@ -2398,7 +2351,7 @@ Error StreamTextureLayered::load(const String &p_path) {
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
- _change_notify();
+ notify_property_list_changed();
emit_changed();
return OK;
}
@@ -2469,11 +2422,6 @@ void StreamTextureLayered::_bind_methods() {
StreamTextureLayered::StreamTextureLayered(LayeredType p_type) {
layered_type = p_type;
- format = Image::FORMAT_MAX;
- w = 0;
- h = 0;
- layers = 0;
- mipmaps = false;
}
StreamTextureLayered::~StreamTextureLayered() {
@@ -2484,7 +2432,7 @@ StreamTextureLayered::~StreamTextureLayered() {
/////////////////////////////////////////////////
-RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
Ref<StreamTextureLayered> st;
if (p_path.get_extension().to_lower() == "stexarray") {
Ref<StreamTexture2DArray> s;
@@ -2602,7 +2550,7 @@ Ref<Image> CameraTexture::get_data() const {
void CameraTexture::set_camera_feed_id(int p_new_id) {
camera_feed_id = p_new_id;
- _change_notify();
+ notify_property_list_changed();
}
int CameraTexture::get_camera_feed_id() const {
@@ -2611,7 +2559,7 @@ int CameraTexture::get_camera_feed_id() const {
void CameraTexture::set_which_feed(CameraServer::FeedImage p_which) {
which_feed = p_which;
- _change_notify();
+ notify_property_list_changed();
}
CameraServer::FeedImage CameraTexture::get_which_feed() const {
@@ -2622,7 +2570,7 @@ void CameraTexture::set_camera_active(bool p_active) {
Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
if (feed.is_valid()) {
feed->set_active(p_active);
- _change_notify();
+ notify_property_list_changed();
}
}
@@ -2635,10 +2583,7 @@ bool CameraTexture::get_camera_active() const {
}
}
-CameraTexture::CameraTexture() {
- camera_feed_id = 0;
- which_feed = CameraServer::FEED_RGBA_IMAGE;
-}
+CameraTexture::CameraTexture() {}
CameraTexture::~CameraTexture() {
// nothing to do here yet
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index a8d8b785fa..a0d917fd86 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -83,12 +83,13 @@ class ImageTexture : public Texture2D {
RES_BASE_EXTENSION("tex");
mutable RID texture;
- Image::Format format;
- bool mipmaps;
- int w, h;
+ Image::Format format = Image::FORMAT_L8;
+ bool mipmaps = false;
+ int w = 0;
+ int h = 0;
Size2 size_override;
mutable Ref<BitMap> alpha_cache;
- bool image_stored;
+ bool image_stored = false;
protected:
virtual void reload_from_file() override;
@@ -160,8 +161,9 @@ private:
Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit = 0);
String path_to_file;
mutable RID texture;
- Image::Format format;
- int w, h;
+ Image::Format format = Image::FORMAT_MAX;
+ int w = 0;
+ int h = 0;
mutable Ref<BitMap> alpha_cache;
virtual void reload_from_file() override;
@@ -209,7 +211,7 @@ public:
class ResourceFormatLoaderStreamTexture2D : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
@@ -223,7 +225,7 @@ protected:
Ref<Texture2D> atlas;
Rect2 region;
Rect2 margin;
- bool filter_clip;
+ bool filter_clip = false;
static void _bind_methods();
@@ -370,12 +372,12 @@ class ImageTextureLayered : public TextureLayered {
LayeredType layered_type;
mutable RID texture;
- Image::Format format;
+ Image::Format format = Image::FORMAT_MAX;
- int width;
- int height;
- int layers;
- bool mipmaps;
+ int width = 0;
+ int height = 0;
+ int layers = 0;
+ bool mipmaps = false;
Error _create_from_images(const Array &p_images);
@@ -453,10 +455,12 @@ private:
Error _load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit = 0);
String path_to_file;
mutable RID texture;
- Image::Format format;
- int w, h, layers;
- bool mipmaps;
- LayeredType layered_type;
+ Image::Format format = Image::FORMAT_MAX;
+ int w = 0;
+ int h = 0;
+ int layers = 0;
+ bool mipmaps = false;
+ LayeredType layered_type = LayeredType::LAYERED_TYPE_2D_ARRAY;
virtual void reload_from_file() override;
@@ -509,7 +513,7 @@ public:
class ResourceFormatLoaderStreamTextureLayered : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
@@ -594,9 +598,11 @@ private:
Error _load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps);
String path_to_file;
mutable RID texture;
- Image::Format format;
- int w, h, d;
- bool mipmaps;
+ Image::Format format = Image::FORMAT_MAX;
+ int w = 0;
+ int h = 0;
+ int d = 0;
+ bool mipmaps = false;
virtual void reload_from_file() override;
@@ -625,7 +631,7 @@ public:
class ResourceFormatLoaderStreamTexture3D : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
@@ -638,7 +644,7 @@ class CurveTexture : public Texture2D {
private:
mutable RID _texture;
Ref<Curve> _curve;
- int _width;
+ int _width = 2048;
void _update();
@@ -680,7 +686,7 @@ class GradientTexture : public Texture2D {
public:
struct Point {
- float offset;
+ float offset = 0.0;
Color color;
bool operator<(const Point &p_ponit) const {
return offset < p_ponit.offset;
@@ -689,9 +695,9 @@ public:
private:
Ref<Gradient> gradient;
- bool update_pending;
+ bool update_pending = false;
RID texture;
- int width;
+ int width = 2048;
void _queue_update();
void _update();
@@ -745,7 +751,7 @@ class AnimatedTexture : public Texture2D {
GDCLASS(AnimatedTexture, Texture2D);
//use readers writers lock for this, since its far more times read than written to
- RWLock *rw_lock;
+ RWLock rw_lock;
public:
enum {
@@ -758,23 +764,19 @@ private:
struct Frame {
Ref<Texture2D> texture;
- float delay_sec;
-
- Frame() {
- delay_sec = 0;
- }
+ float delay_sec = 0.0;
};
Frame frames[MAX_FRAMES];
- int frame_count;
- int current_frame;
- bool pause;
- bool oneshot;
- float fps;
+ int frame_count = 1.0;
+ int current_frame = 0;
+ bool pause = false;
+ bool oneshot = false;
+ float fps = 4.0;
- float time;
+ float time = 0.0;
- uint64_t prev_ticks;
+ uint64_t prev_ticks = 0;
void _update_proxy();
@@ -822,8 +824,8 @@ class CameraTexture : public Texture2D {
GDCLASS(CameraTexture, Texture2D);
private:
- int camera_feed_id;
- CameraServer::FeedImage which_feed;
+ int camera_feed_id = 0;
+ CameraServer::FeedImage which_feed = CameraServer::FEED_RGBA_IMAGE;
protected:
static void _bind_methods();
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index c8bfcdfab4..0405ea98bb 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -358,7 +358,7 @@ void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -373,7 +373,7 @@ void Theme::set_default_theme_font_size(int p_font_size) {
default_theme_font_size = p_font_size;
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -436,7 +436,7 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_node_type, co
}
if (new_value) {
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
}
@@ -463,7 +463,7 @@ void Theme::clear_icon(const StringName &p_name, const StringName &p_node_type)
icon_map[p_node_type].erase(p_name);
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -506,7 +506,7 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_node_type
}
if (new_value) {
- _change_notify();
+ notify_property_list_changed();
}
emit_changed();
}
@@ -533,7 +533,7 @@ void Theme::clear_stylebox(const StringName &p_name, const StringName &p_node_ty
style_map[p_node_type].erase(p_name);
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -576,7 +576,7 @@ void Theme::set_font(const StringName &p_name, const StringName &p_node_type, co
}
if (new_value) {
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
}
@@ -604,7 +604,7 @@ void Theme::clear_font(const StringName &p_name, const StringName &p_node_type)
}
font_map[p_node_type].erase(p_name);
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -637,7 +637,7 @@ void Theme::set_font_size(const StringName &p_name, const StringName &p_node_typ
font_size_map[p_node_type][p_name] = p_font_size;
if (new_value) {
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
}
@@ -661,7 +661,7 @@ void Theme::clear_font_size(const StringName &p_name, const StringName &p_node_t
ERR_FAIL_COND(!font_size_map[p_node_type].has(p_name));
font_size_map[p_node_type].erase(p_name);
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -685,7 +685,7 @@ void Theme::set_color(const StringName &p_name, const StringName &p_node_type, c
color_map[p_node_type][p_name] = p_color;
if (new_value) {
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
}
@@ -707,7 +707,7 @@ void Theme::clear_color(const StringName &p_name, const StringName &p_node_type)
ERR_FAIL_COND(!color_map[p_node_type].has(p_name));
color_map[p_node_type].erase(p_name);
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -739,7 +739,7 @@ void Theme::set_constant(const StringName &p_name, const StringName &p_node_type
constant_map[p_node_type][p_name] = p_constant;
if (new_value) {
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
}
@@ -761,7 +761,7 @@ void Theme::clear_constant(const StringName &p_name, const StringName &p_node_ty
ERR_FAIL_COND(!constant_map[p_node_type].has(p_name));
constant_map[p_node_type].erase(p_name);
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -835,7 +835,7 @@ void Theme::clear() {
color_map.clear();
constant_map.clear();
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -887,7 +887,7 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
color_map = p_other->color_map;
constant_map = p_other->constant_map;
- _change_notify();
+ notify_property_list_changed();
emit_changed();
}
@@ -930,6 +930,9 @@ void Theme::get_type_list(List<StringName> *p_list) const {
}
}
+void Theme::reset_state() {
+ clear();
+}
void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_icon", "name", "node_type", "texture"), &Theme::set_icon);
ClassDB::bind_method(D_METHOD("get_icon", "name", "node_type"), &Theme::get_icon);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index ad05e0e2f5..35481126ea 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,6 +80,8 @@ protected:
static void _bind_methods();
+ virtual void reset_state() override;
+
public:
static Ref<Theme> get_default();
static void set_default(const Ref<Theme> &p_default);
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 4581763e9c..84be69d0d6 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -369,14 +369,14 @@ void TileSet::create_tile(int p_id) {
ERR_FAIL_COND(tile_map.has(p_id));
tile_map[p_id] = TileData();
tile_map[p_id].autotile_data = AutotileData();
- _change_notify("");
+ notify_property_list_changed();
emit_changed();
}
void TileSet::autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].autotile_data.bitmask_mode = p_mode;
- _change_notify("");
+ notify_property_list_changed();
emit_changed();
}
@@ -389,7 +389,6 @@ void TileSet::tile_set_texture(int p_id, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].texture = p_texture;
emit_changed();
- _change_notify("texture");
}
Ref<Texture2D> TileSet::tile_get_texture(int p_id) const {
@@ -412,7 +411,6 @@ void TileSet::tile_set_modulate(int p_id, const Color &p_modulate) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].modulate = p_modulate;
emit_changed();
- _change_notify("modulate");
}
Color TileSet::tile_get_modulate(int p_id) const {
@@ -435,7 +433,6 @@ void TileSet::tile_set_region(int p_id, const Rect2 &p_region) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].region = p_region;
emit_changed();
- _change_notify("region");
}
Rect2 TileSet::tile_get_region(int p_id) const {
@@ -447,7 +444,6 @@ void TileSet::tile_set_tile_mode(int p_id, TileMode p_tile_mode) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].tile_mode = p_tile_mode;
emit_changed();
- _change_notify("tile_mode");
}
TileSet::TileMode TileSet::tile_get_tile_mode(int p_id) const {
@@ -669,7 +665,6 @@ void TileSet::tile_set_name(int p_id, const String &p_name) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].name = p_name;
emit_changed();
- _change_notify("name");
}
String TileSet::tile_get_name(int p_id) const {
@@ -1060,7 +1055,7 @@ bool TileSet::is_tile_bound(int p_drawn_id, int p_neighbor_id) {
void TileSet::remove_tile(int p_id) {
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map.erase(p_id);
- _change_notify("");
+ notify_property_list_changed();
emit_changed();
}
@@ -1081,9 +1076,13 @@ int TileSet::find_tile_by_name(const String &p_name) const {
return -1;
}
+void TileSet::reset_state() {
+ clear();
+}
+
void TileSet::clear() {
tile_map.clear();
- _change_notify("");
+ notify_property_list_changed();
emit_changed();
}
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 79f1b4aa95..0a8721f35b 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -136,6 +136,8 @@ protected:
static void _bind_methods();
+ virtual void reset_state() override;
+
public:
void create_tile(int p_id);
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index 379ba53a34..f960f85521 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 34129e35da..859546694f 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,7 @@
#include "core/templates/vmap.h"
#include "servers/rendering/shader_types.h"
#include "visual_shader_nodes.h"
+#include "visual_shader_sdf_nodes.h"
bool VisualShaderNode::is_simple_decl() const {
return simple_decl;
@@ -486,6 +487,22 @@ void VisualShader::remove_node(Type p_type, int p_id) {
_queue_update();
}
+void VisualShader::replace_node(Type p_type, int p_id, const StringName &p_new_class) {
+ ERR_FAIL_INDEX(p_type, TYPE_MAX);
+ ERR_FAIL_COND(p_id < 2);
+ Graph *g = &graph[p_type];
+ ERR_FAIL_COND(!g->nodes.has(p_id));
+
+ if (g->nodes[p_id].node->get_class_name() == p_new_class) {
+ return;
+ }
+ VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(p_new_class));
+ vsn->connect("changed", callable_mp(this, &VisualShader::_queue_update));
+ g->nodes[p_id].node = Ref<VisualShaderNode>(vsn);
+
+ _queue_update();
+}
+
bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
const Graph *g = &graph[p_type];
@@ -568,6 +585,12 @@ bool VisualShader::is_port_types_compatible(int p_a, int p_b) const {
void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
ERR_FAIL_INDEX(p_type, TYPE_MAX);
Graph *g = &graph[p_type];
+
+ ERR_FAIL_COND(!g->nodes.has(p_from_node));
+ ERR_FAIL_INDEX(p_from_port, g->nodes[p_from_node].node->get_output_port_count());
+ ERR_FAIL_COND(!g->nodes.has(p_to_node));
+ ERR_FAIL_INDEX(p_to_port, g->nodes[p_to_node].node->get_input_port_count());
+
Connection c;
c.from_node = p_from_node;
c.from_port = p_from_port;
@@ -658,6 +681,8 @@ void VisualShader::get_node_connections(Type p_type, List<Connection> *r_connect
}
void VisualShader::set_mode(Mode p_mode) {
+ ERR_FAIL_INDEX_MSG(p_mode, Mode::MODE_MAX, vformat("Invalid shader mode: %d.", p_mode));
+
if (shader_mode == p_mode) {
return;
}
@@ -713,7 +738,7 @@ void VisualShader::set_mode(Mode p_mode) {
}
_queue_update();
- _change_notify();
+ notify_property_list_changed();
}
void VisualShader::set_graph_offset(const Vector2 &p_offset) {
@@ -1078,6 +1103,12 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
+void VisualShader::reset_state() {
+#ifndef _MSC_VER
+#warning everything needs to be cleared here
+#endif
+ emit_changed();
+}
void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
//mode
p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Node3D,CanvasItem,Particles,Sky"));
@@ -1375,11 +1406,11 @@ bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const Strin
}
void VisualShader::_update_shader() const {
- if (!dirty) {
+ if (!dirty.is_set()) {
return;
}
- dirty = false;
+ dirty.clear();
StringBuilder global_code;
StringBuilder global_code_per_node;
@@ -1565,15 +1596,16 @@ void VisualShader::_update_shader() const {
}
void VisualShader::_queue_update() {
- if (dirty) {
+ if (dirty.is_set()) {
return;
}
- dirty = true;
+ dirty.set();
call_deferred("_update_shader");
}
void VisualShader::_input_type_changed(Type p_type, int p_id) {
+ ERR_FAIL_INDEX(p_type, TYPE_MAX);
//erase connections using this input, as type changed
Graph *g = &graph[p_type];
@@ -1588,7 +1620,7 @@ void VisualShader::_input_type_changed(Type p_type, int p_id) {
}
void VisualShader::rebuild() {
- dirty = true;
+ dirty.set();
_update_shader();
}
@@ -1605,6 +1637,7 @@ void VisualShader::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_valid_node_id", "type"), &VisualShader::get_valid_node_id);
ClassDB::bind_method(D_METHOD("remove_node", "type", "id"), &VisualShader::remove_node);
+ ClassDB::bind_method(D_METHOD("replace_node", "type", "id", "new_class"), &VisualShader::replace_node);
ClassDB::bind_method(D_METHOD("is_node_connection", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection);
ClassDB::bind_method(D_METHOD("can_connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::can_connect_nodes);
@@ -1641,6 +1674,7 @@ void VisualShader::_bind_methods() {
}
VisualShader::VisualShader() {
+ dirty.set();
for (int i = 0; i < TYPE_MAX; i++) {
Ref<VisualShaderNodeOutput> output;
output.instance();
@@ -2359,8 +2393,8 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao", "AO" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normalmap", "NORMALMAP" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normalmap_depth", "NORMALMAP_DEPTH" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal_map", "NORMAL_MAP" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normal_map_depth", "NORMAL_MAP_DEPTH" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "rim", "RIM" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "rim_tint", "RIM_TINT" },
@@ -2386,8 +2420,8 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normalmap", "NORMALMAP" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normalmap_depth", "NORMALMAP_DEPTH" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal_map", "NORMAL_MAP" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normal_map_depth", "NORMAL_MAP_DEPTH" },
// Canvas Item, Light
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.a" },
@@ -3124,7 +3158,7 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
_expression = _expression.replace("\n", "\n\t\t");
static Vector<String> pre_symbols;
- if (pre_symbols.empty()) {
+ if (pre_symbols.is_empty()) {
pre_symbols.push_back("\t");
pre_symbols.push_back(",");
pre_symbols.push_back(";");
@@ -3144,7 +3178,7 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
}
static Vector<String> post_symbols;
- if (post_symbols.empty()) {
+ if (post_symbols.is_empty()) {
post_symbols.push_back("\t");
post_symbols.push_back("\n");
post_symbols.push_back(",");
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index a38c2886e2..ef724c7650 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#define VISUAL_SHADER_H
#include "core/string/string_builder.h"
+#include "core/templates/safe_refcount.h"
#include "scene/gui/control.h"
#include "scene/resources/shader.h"
@@ -57,10 +58,10 @@ public:
};
struct Connection {
- int from_node;
- int from_port;
- int to_node;
- int to_port;
+ int from_node = 0;
+ int from_port = 0;
+ int to_node = 0;
+ int to_port = 0;
};
struct DefaultTextureParam {
@@ -90,7 +91,7 @@ private:
Vector2 graph_offset;
struct RenderModeEnums {
- Shader::Mode mode;
+ Shader::Mode mode = Shader::Mode::MODE_MAX;
const char *string;
};
@@ -99,7 +100,7 @@ private:
static RenderModeEnums render_mode_enums[];
- volatile mutable bool dirty = true;
+ mutable SafeFlag dirty;
void _queue_update();
union ConnectionKey {
@@ -107,7 +108,7 @@ private:
uint64_t node : 32;
uint64_t port : 32;
};
- uint64_t key;
+ uint64_t key = 0;
bool operator<(const ConnectionKey &p_key) const {
return key < p_key.key;
}
@@ -126,6 +127,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void reset_state() override;
+
public: // internal methods
void set_shader_type(Type p_type);
Type get_shader_type() const;
@@ -152,6 +155,7 @@ public:
int find_node_id(Type p_type, const Ref<VisualShaderNode> &p_node) const;
void remove_node(Type p_type, int p_id);
+ void replace_node(Type p_type, int p_id, const StringName &p_new_class);
bool is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
@@ -264,7 +268,7 @@ class VisualShaderNodeCustom : public VisualShaderNode {
struct Port {
String name;
- int type;
+ int type = 0;
};
List<Port> input_ports;
@@ -304,9 +308,9 @@ class VisualShaderNodeInput : public VisualShaderNode {
Shader::Mode shader_mode = Shader::MODE_MAX;
struct Port {
- Shader::Mode mode;
- VisualShader::Type shader_type;
- PortType type;
+ Shader::Mode mode = Shader::Mode::MODE_MAX;
+ VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX;
+ PortType type = PortType::PORT_TYPE_MAX;
const char *name;
const char *string;
};
@@ -355,13 +359,13 @@ class VisualShaderNodeOutput : public VisualShaderNode {
public:
friend class VisualShader;
- VisualShader::Type shader_type;
- Shader::Mode shader_mode;
+ VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX;
+ Shader::Mode shader_mode = Shader::Mode::MODE_MAX;
struct Port {
- Shader::Mode mode;
- VisualShader::Type shader_type;
- PortType type;
+ Shader::Mode mode = Shader::Mode::MODE_MAX;
+ VisualShader::Type shader_type = VisualShader::Type::TYPE_MAX;
+ PortType type = PortType::PORT_TYPE_MAX;
const char *name;
const char *string;
};
@@ -518,7 +522,7 @@ protected:
bool editable = false;
struct Port {
- PortType type;
+ PortType type = PortType::PORT_TYPE_MAX;
String name;
};
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index a3358ea8c7..a99c09e89c 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,6 +30,11 @@
#include "visual_shader_nodes.h"
+////////////// Constants Base
+
+VisualShaderNodeConstant::VisualShaderNodeConstant() {
+}
+
////////////// Scalar(Float)
String VisualShaderNodeFloatConstant::get_caption() const {
@@ -480,7 +485,7 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade
case TYPE_COLOR:
u += " : hint_albedo";
break;
- case TYPE_NORMALMAP:
+ case TYPE_NORMAL_MAP:
u += " : hint_normal";
break;
}
@@ -780,7 +785,7 @@ void VisualShaderNodeTexture::_bind_methods() {
BIND_ENUM_CONSTANT(SOURCE_PORT);
BIND_ENUM_CONSTANT(TYPE_DATA);
BIND_ENUM_CONSTANT(TYPE_COLOR);
- BIND_ENUM_CONSTANT(TYPE_NORMALMAP);
+ BIND_ENUM_CONSTANT(TYPE_NORMAL_MAP);
}
VisualShaderNodeTexture::VisualShaderNodeTexture() {
@@ -1181,7 +1186,7 @@ String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShade
case TYPE_COLOR:
u += " : hint_albedo";
break;
- case TYPE_NORMALMAP:
+ case TYPE_NORMAL_MAP:
u += " : hint_normal";
break;
}
@@ -1310,7 +1315,7 @@ void VisualShaderNodeCubemap::_bind_methods() {
BIND_ENUM_CONSTANT(TYPE_DATA);
BIND_ENUM_CONSTANT(TYPE_COLOR);
- BIND_ENUM_CONSTANT(TYPE_NORMALMAP);
+ BIND_ENUM_CONSTANT(TYPE_NORMAL_MAP);
}
VisualShaderNodeCubemap::VisualShaderNodeCubemap() {
@@ -2081,9 +2086,6 @@ String VisualShaderNodeIntFunc::get_caption() const {
}
int VisualShaderNodeIntFunc::get_input_port_count() const {
- if (func == FUNC_CLAMP) {
- return 3;
- }
return 1;
}
@@ -2092,15 +2094,6 @@ VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_input_port_type(i
}
String VisualShaderNodeIntFunc::get_input_port_name(int p_port) const {
- if (func == FUNC_CLAMP) {
- if (p_port == 0) {
- return "";
- } else if (p_port == 1) {
- return "min";
- } else if (p_port == 2) {
- return "max";
- }
- }
return "";
}
@@ -2117,13 +2110,8 @@ String VisualShaderNodeIntFunc::get_output_port_name(int p_port) const {
}
String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- if (func == FUNC_CLAMP) {
- return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
- }
-
static const char *int_func_id[FUNC_SIGN + 1] = {
"abs($)",
- "",
"-($)",
"sign($)"
};
@@ -2132,12 +2120,6 @@ String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader:
}
void VisualShaderNodeIntFunc::set_function(Function p_func) {
- if (func != p_func) {
- if (p_func == FUNC_CLAMP) {
- set_input_port_default_value(1, 0);
- set_input_port_default_value(2, 0);
- }
- }
func = p_func;
emit_changed();
}
@@ -2156,10 +2138,9 @@ void VisualShaderNodeIntFunc::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Clamp,Negate,Sign"), "set_function", "get_function");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign"), "set_function", "get_function");
BIND_ENUM_CONSTANT(FUNC_ABS);
- BIND_ENUM_CONSTANT(FUNC_CLAMP);
BIND_ENUM_CONSTANT(FUNC_NEGATE);
BIND_ENUM_CONSTANT(FUNC_SIGN);
}
@@ -2749,21 +2730,29 @@ VisualShaderNodeVectorDerivativeFunc::VisualShaderNodeVectorDerivativeFunc() {
set_input_port_default_value(0, Vector3());
}
-////////////// Scalar Clamp
+////////////// Clamp
-String VisualShaderNodeScalarClamp::get_caption() const {
- return "ScalarClamp";
+String VisualShaderNodeClamp::get_caption() const {
+ return "Clamp";
}
-int VisualShaderNodeScalarClamp::get_input_port_count() const {
+int VisualShaderNodeClamp::get_input_port_count() const {
return 3;
}
-VisualShaderNodeScalarClamp::PortType VisualShaderNodeScalarClamp::get_input_port_type(int p_port) const {
+VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_input_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_INT:
+ return PORT_TYPE_SCALAR_INT;
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarClamp::get_input_port_name(int p_port) const {
+String VisualShaderNodeClamp::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "";
} else if (p_port == 1) {
@@ -2774,73 +2763,84 @@ String VisualShaderNodeScalarClamp::get_input_port_name(int p_port) const {
return "";
}
-int VisualShaderNodeScalarClamp::get_output_port_count() const {
+int VisualShaderNodeClamp::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarClamp::PortType VisualShaderNodeScalarClamp::get_output_port_type(int p_port) const {
+VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_output_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_INT:
+ return PORT_TYPE_SCALAR_INT;
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarClamp::get_output_port_name(int p_port) const {
+String VisualShaderNodeClamp::get_output_port_name(int p_port) const {
return "";
}
-String VisualShaderNodeScalarClamp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeClamp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
}
-VisualShaderNodeScalarClamp::VisualShaderNodeScalarClamp() {
- set_input_port_default_value(0, 0.0);
- set_input_port_default_value(1, 0.0);
- set_input_port_default_value(2, 1.0);
-}
-
-////////////// Vector Clamp
-
-String VisualShaderNodeVectorClamp::get_caption() const {
- return "VectorClamp";
-}
-
-int VisualShaderNodeVectorClamp::get_input_port_count() const {
- return 3;
-}
-
-VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorClamp::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
-String VisualShaderNodeVectorClamp::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "";
- } else if (p_port == 1) {
- return "min";
- } else if (p_port == 2) {
- return "max";
+void VisualShaderNodeClamp::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX);
+ if (op_type == p_op_type) {
+ return;
}
- return "";
+ switch (p_op_type) {
+ case OP_TYPE_FLOAT:
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(2, 0.0);
+ break;
+ case OP_TYPE_INT:
+ set_input_port_default_value(0, 0);
+ set_input_port_default_value(1, 0);
+ set_input_port_default_value(2, 0);
+ break;
+ case OP_TYPE_VECTOR:
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
+ break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
}
-int VisualShaderNodeVectorClamp::get_output_port_count() const {
- return 1;
+VisualShaderNodeClamp::OpType VisualShaderNodeClamp::get_op_type() const {
+ return op_type;
}
-VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorClamp::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
+Vector<StringName> VisualShaderNodeClamp::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("op_type");
+ return props;
}
-String VisualShaderNodeVectorClamp::get_output_port_name(int p_port) const {
- return "";
-}
+void VisualShaderNodeClamp::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeClamp::set_op_type);
+ ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeClamp::get_op_type);
-String VisualShaderNodeVectorClamp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector"), "set_op_type", "get_op_type");
+
+ BIND_ENUM_CONSTANT(OP_TYPE_FLOAT);
+ BIND_ENUM_CONSTANT(OP_TYPE_INT);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
-VisualShaderNodeVectorClamp::VisualShaderNodeVectorClamp() {
- set_input_port_default_value(0, Vector3(0, 0, 0));
- set_input_port_default_value(1, Vector3(0, 0, 0));
- set_input_port_default_value(2, Vector3(1, 1, 1));
+VisualShaderNodeClamp::VisualShaderNodeClamp() {
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(2, 1.0);
}
////////////// FaceForward
@@ -2938,24 +2938,32 @@ VisualShaderNodeOuterProduct::VisualShaderNodeOuterProduct() {
set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
}
-////////////// Vector-Scalar Step
+////////////// Step
-String VisualShaderNodeVectorScalarStep::get_caption() const {
- return "VectorScalarStep";
+String VisualShaderNodeStep::get_caption() const {
+ return "Step";
}
-int VisualShaderNodeVectorScalarStep::get_input_port_count() const {
+int VisualShaderNodeStep::get_input_port_count() const {
return 2;
}
-VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_input_port_type(int p_port) const {
- if (p_port == 0) {
- return PORT_TYPE_SCALAR;
+VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case OP_TYPE_VECTOR_SCALAR:
+ if (p_port == 1) {
+ return PORT_TYPE_VECTOR;
+ }
+ break;
+ default:
+ break;
}
- return PORT_TYPE_VECTOR;
+ return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeVectorScalarStep::get_input_port_name(int p_port) const {
+String VisualShaderNodeStep::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "edge";
} else if (p_port == 1) {
@@ -2964,89 +2972,120 @@ String VisualShaderNodeVectorScalarStep::get_input_port_name(int p_port) const {
return "";
}
-int VisualShaderNodeVectorScalarStep::get_output_port_count() const {
+int VisualShaderNodeStep::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
+VisualShaderNodeStep::PortType VisualShaderNodeStep::get_output_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case OP_TYPE_VECTOR_SCALAR:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
+ return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeVectorScalarStep::get_output_port_name(int p_port) const {
+String VisualShaderNodeStep::get_output_port_name(int p_port) const {
return "";
}
-String VisualShaderNodeVectorScalarStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
-}
-
-VisualShaderNodeVectorScalarStep::VisualShaderNodeVectorScalarStep() {
- set_input_port_default_value(0, 0.0);
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
-}
-
-////////////// Scalar SmoothStep
-
-String VisualShaderNodeScalarSmoothStep::get_caption() const {
- return "ScalarSmoothStep";
-}
-
-int VisualShaderNodeScalarSmoothStep::get_input_port_count() const {
- return 3;
+void VisualShaderNodeStep::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX);
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_SCALAR:
+ if (op_type == OP_TYPE_VECTOR) {
+ set_input_port_default_value(0, 0.0); // edge
+ }
+ if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) {
+ set_input_port_default_value(1, 0.0); // x
+ }
+ break;
+ case OP_TYPE_VECTOR:
+ if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) {
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge
+ }
+ if (op_type == OP_TYPE_SCALAR) {
+ set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x
+ }
+ break;
+ case OP_TYPE_VECTOR_SCALAR:
+ if (op_type == OP_TYPE_VECTOR) {
+ set_input_port_default_value(0, 0.0); // edge
+ }
+ if (op_type == OP_TYPE_SCALAR) {
+ set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x
+ }
+ break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
}
-VisualShaderNodeScalarSmoothStep::PortType VisualShaderNodeScalarSmoothStep::get_input_port_type(int p_port) const {
- return PORT_TYPE_SCALAR;
+VisualShaderNodeStep::OpType VisualShaderNodeStep::get_op_type() const {
+ return op_type;
}
-String VisualShaderNodeScalarSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "edge0";
- } else if (p_port == 1) {
- return "edge1";
- } else if (p_port == 2) {
- return "x";
- }
- return "";
+String VisualShaderNodeStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
}
-int VisualShaderNodeScalarSmoothStep::get_output_port_count() const {
- return 1;
+Vector<StringName> VisualShaderNodeStep::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("op_type");
+ return props;
}
-VisualShaderNodeScalarSmoothStep::PortType VisualShaderNodeScalarSmoothStep::get_output_port_type(int p_port) const {
- return PORT_TYPE_SCALAR;
-}
+void VisualShaderNodeStep::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeStep::set_op_type);
+ ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeStep::get_op_type);
-String VisualShaderNodeScalarSmoothStep::get_output_port_name(int p_port) const {
- return "";
-}
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type");
-String VisualShaderNodeScalarSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
+ BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
-VisualShaderNodeScalarSmoothStep::VisualShaderNodeScalarSmoothStep() {
+VisualShaderNodeStep::VisualShaderNodeStep() {
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
- set_input_port_default_value(2, 0.0);
}
-////////////// Vector SmoothStep
+////////////// SmoothStep
-String VisualShaderNodeVectorSmoothStep::get_caption() const {
- return "VectorSmoothStep";
+String VisualShaderNodeSmoothStep::get_caption() const {
+ return "SmoothStep";
}
-int VisualShaderNodeVectorSmoothStep::get_input_port_count() const {
+int VisualShaderNodeSmoothStep::get_input_port_count() const {
return 3;
}
-VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
+VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case OP_TYPE_VECTOR_SCALAR:
+ if (p_port == 2) {
+ return PORT_TYPE_VECTOR; // x
+ }
+ break;
+ default:
+ break;
+ }
+ return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeVectorSmoothStep::get_input_port_name(int p_port) const {
+String VisualShaderNodeSmoothStep::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "edge0";
} else if (p_port == 1) {
@@ -3057,78 +3096,96 @@ String VisualShaderNodeVectorSmoothStep::get_input_port_name(int p_port) const {
return "";
}
-int VisualShaderNodeVectorSmoothStep::get_output_port_count() const {
+int VisualShaderNodeSmoothStep::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
+VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_output_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case OP_TYPE_VECTOR_SCALAR:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
+ return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeVectorSmoothStep::get_output_port_name(int p_port) const {
+String VisualShaderNodeSmoothStep::get_output_port_name(int p_port) const {
return "";
}
-String VisualShaderNodeVectorSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
-}
-
-VisualShaderNodeVectorSmoothStep::VisualShaderNodeVectorSmoothStep() {
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
-}
-
-////////////// Vector-Scalar SmoothStep
-
-String VisualShaderNodeVectorScalarSmoothStep::get_caption() const {
- return "VectorScalarSmoothStep";
-}
-
-int VisualShaderNodeVectorScalarSmoothStep::get_input_port_count() const {
- return 3;
-}
-
-VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_input_port_type(int p_port) const {
- if (p_port == 0) {
- return PORT_TYPE_SCALAR;
- } else if (p_port == 1) {
- return PORT_TYPE_SCALAR;
+void VisualShaderNodeSmoothStep::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX);
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_SCALAR:
+ if (op_type == OP_TYPE_VECTOR) {
+ set_input_port_default_value(0, 0.0); // edge0
+ set_input_port_default_value(1, 0.0); // edge1
+ }
+ if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) {
+ set_input_port_default_value(2, 0.0); // x
+ }
+ break;
+ case OP_TYPE_VECTOR:
+ if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) {
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge0
+ set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // edge1
+ }
+ if (op_type == OP_TYPE_SCALAR) {
+ set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x
+ }
+ break;
+ case OP_TYPE_VECTOR_SCALAR:
+ if (op_type == OP_TYPE_VECTOR) {
+ set_input_port_default_value(0, 0.0); // edge0
+ set_input_port_default_value(1, 0.0); // edge1
+ }
+ if (op_type == OP_TYPE_SCALAR) {
+ set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x
+ }
+ break;
+ default:
+ break;
}
- return PORT_TYPE_VECTOR;
+ op_type = p_op_type;
+ emit_changed();
}
-String VisualShaderNodeVectorScalarSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "edge0";
- } else if (p_port == 1) {
- return "edge1";
- } else if (p_port == 2) {
- return "x";
- }
- return "";
+VisualShaderNodeSmoothStep::OpType VisualShaderNodeSmoothStep::get_op_type() const {
+ return op_type;
}
-int VisualShaderNodeVectorScalarSmoothStep::get_output_port_count() const {
- return 1;
+String VisualShaderNodeSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
}
-VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
+Vector<StringName> VisualShaderNodeSmoothStep::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("op_type");
+ return props;
}
-String VisualShaderNodeVectorScalarSmoothStep::get_output_port_name(int p_port) const {
- return "";
-}
+void VisualShaderNodeSmoothStep::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSmoothStep::set_op_type);
+ ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSmoothStep::get_op_type);
-String VisualShaderNodeVectorScalarSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type");
+
+ BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
-VisualShaderNodeVectorScalarSmoothStep::VisualShaderNodeVectorScalarSmoothStep() {
+VisualShaderNodeSmoothStep::VisualShaderNodeSmoothStep() {
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
- set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(2, 0.0);
}
////////////// Distance
@@ -3226,21 +3283,32 @@ VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() {
set_input_port_default_value(2, 0.0);
}
-////////////// Scalar Mix
+////////////// Mix
-String VisualShaderNodeScalarInterp::get_caption() const {
- return "ScalarMix";
+String VisualShaderNodeMix::get_caption() const {
+ return "Mix";
}
-int VisualShaderNodeScalarInterp::get_input_port_count() const {
+int VisualShaderNodeMix::get_input_port_count() const {
return 3;
}
-VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_input_port_type(int p_port) const {
+VisualShaderNodeMix::PortType VisualShaderNodeMix::get_input_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case OP_TYPE_VECTOR_SCALAR:
+ if (p_port == 2) {
+ break;
+ }
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const {
+String VisualShaderNodeMix::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "a";
} else if (p_port == 1) {
@@ -3250,121 +3318,90 @@ String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const {
}
}
-int VisualShaderNodeScalarInterp::get_output_port_count() const {
+int VisualShaderNodeMix::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_output_port_type(int p_port) const {
+VisualShaderNodeMix::PortType VisualShaderNodeMix::get_output_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case OP_TYPE_VECTOR_SCALAR:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarInterp::get_output_port_name(int p_port) const {
+String VisualShaderNodeMix::get_output_port_name(int p_port) const {
return "mix";
}
-String VisualShaderNodeScalarInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
-}
-
-VisualShaderNodeScalarInterp::VisualShaderNodeScalarInterp() {
- set_input_port_default_value(0, 0.0);
- set_input_port_default_value(1, 1.0);
- set_input_port_default_value(2, 0.5);
-}
-
-////////////// Vector Mix
-
-String VisualShaderNodeVectorInterp::get_caption() const {
- return "VectorMix";
-}
-
-int VisualShaderNodeVectorInterp::get_input_port_count() const {
- return 3;
-}
-
-VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
-String VisualShaderNodeVectorInterp::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "a";
- } else if (p_port == 1) {
- return "b";
- } else {
- return "weight";
+void VisualShaderNodeMix::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX);
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_SCALAR:
+ set_input_port_default_value(0, 0.0); // a
+ set_input_port_default_value(1, 1.0); // b
+ if (op_type == OP_TYPE_VECTOR) {
+ set_input_port_default_value(2, 0.5); // weight
+ }
+ break;
+ case OP_TYPE_VECTOR:
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a
+ set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b
+ if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) {
+ set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5)); // weight
+ }
+ break;
+ case OP_TYPE_VECTOR_SCALAR:
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a
+ set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b
+ if (op_type == OP_TYPE_VECTOR) {
+ set_input_port_default_value(2, 0.5); // weight
+ }
+ break;
+ default:
+ break;
}
+ op_type = p_op_type;
+ emit_changed();
}
-int VisualShaderNodeVectorInterp::get_output_port_count() const {
- return 1;
-}
-
-VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
-String VisualShaderNodeVectorInterp::get_output_port_name(int p_port) const {
- return "mix";
+VisualShaderNodeMix::OpType VisualShaderNodeMix::get_op_type() const {
+ return op_type;
}
-String VisualShaderNodeVectorInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeMix::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
}
-VisualShaderNodeVectorInterp::VisualShaderNodeVectorInterp() {
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
- set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5));
-}
-
-////////////// Vector Mix (by scalar)
-
-String VisualShaderNodeVectorScalarMix::get_caption() const {
- return "VectorScalarMix";
-}
-
-int VisualShaderNodeVectorScalarMix::get_input_port_count() const {
- return 3;
-}
-
-VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_input_port_type(int p_port) const {
- if (p_port == 2) {
- return PORT_TYPE_SCALAR;
- }
- return PORT_TYPE_VECTOR;
-}
-
-String VisualShaderNodeVectorScalarMix::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "a";
- } else if (p_port == 1) {
- return "b";
- } else {
- return "weight";
- }
-}
-
-int VisualShaderNodeVectorScalarMix::get_output_port_count() const {
- return 1;
+Vector<StringName> VisualShaderNodeMix::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("op_type");
+ return props;
}
-VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
+void VisualShaderNodeMix::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeMix::set_op_type);
+ ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMix::get_op_type);
-String VisualShaderNodeVectorScalarMix::get_output_port_name(int p_port) const {
- return "mix";
-}
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type");
-String VisualShaderNodeVectorScalarMix::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
+ BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
-VisualShaderNodeVectorScalarMix::VisualShaderNodeVectorScalarMix() {
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
- set_input_port_default_value(2, 0.5);
+VisualShaderNodeMix::VisualShaderNodeMix() {
+ set_input_port_default_value(0, 0.0); // a
+ set_input_port_default_value(1, 1.0); // b
+ set_input_port_default_value(2, 0.5); // weight
}
////////////// Vector Compose
@@ -4350,7 +4387,7 @@ String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, Visu
code += " : hint_albedo;\n";
}
break;
- case TYPE_NORMALMAP:
+ case TYPE_NORMAL_MAP:
code += " : hint_normal;\n";
break;
case TYPE_ANISO:
@@ -4431,7 +4468,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() {
BIND_ENUM_CONSTANT(TYPE_DATA);
BIND_ENUM_CONSTANT(TYPE_COLOR);
- BIND_ENUM_CONSTANT(TYPE_NORMALMAP);
+ BIND_ENUM_CONSTANT(TYPE_NORMAL_MAP);
BIND_ENUM_CONSTANT(TYPE_ANISO);
BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE);
@@ -4472,9 +4509,7 @@ int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const {
}
VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const {
- if (p_port == 0) {
- return PORT_TYPE_VECTOR;
- } else if (p_port == 1) {
+ if (p_port == 0 || p_port == 1) {
return PORT_TYPE_VECTOR;
}
return PORT_TYPE_SCALAR;
@@ -4608,7 +4643,7 @@ String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mod
else
code += " : hint_albedo;\n";
break;
- case TYPE_NORMALMAP:
+ case TYPE_NORMAL_MAP:
code += " : hint_normal;\n";
break;
case TYPE_ANISO:
@@ -4676,7 +4711,7 @@ String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, Vi
else
code += " : hint_albedo;\n";
break;
- case TYPE_NORMALMAP:
+ case TYPE_NORMAL_MAP:
code += " : hint_normal;\n";
break;
case TYPE_ANISO:
@@ -4746,7 +4781,7 @@ String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, Visu
code += " : hint_albedo;\n";
}
break;
- case TYPE_NORMALMAP:
+ case TYPE_NORMAL_MAP:
code += " : hint_normal;\n";
break;
case TYPE_ANISO:
@@ -4842,7 +4877,7 @@ VisualShaderNodeIf::VisualShaderNodeIf() {
////////////// Switch
String VisualShaderNodeSwitch::get_caption() const {
- return "VectorSwitch";
+ return "Switch";
}
int VisualShaderNodeSwitch::get_input_port_count() const {
@@ -4853,7 +4888,21 @@ VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int
if (p_port == 0) {
return PORT_TYPE_BOOLEAN;
}
- return PORT_TYPE_VECTOR;
+ if (p_port == 1 || p_port == 2) {
+ switch (op_type) {
+ case OP_TYPE_INT:
+ return PORT_TYPE_SCALAR_INT;
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case OP_TYPE_BOOLEAN:
+ return PORT_TYPE_BOOLEAN;
+ case OP_TYPE_TRANSFORM:
+ return PORT_TYPE_TRANSFORM;
+ default:
+ break;
+ }
+ }
+ return PORT_TYPE_SCALAR;
}
String VisualShaderNodeSwitch::get_input_port_name(int p_port) const {
@@ -4874,13 +4923,82 @@ int VisualShaderNodeSwitch::get_output_port_count() const {
}
VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
+ switch (op_type) {
+ case OP_TYPE_INT:
+ return PORT_TYPE_SCALAR_INT;
+ case OP_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case OP_TYPE_BOOLEAN:
+ return PORT_TYPE_BOOLEAN;
+ case OP_TYPE_TRANSFORM:
+ return PORT_TYPE_TRANSFORM;
+ default:
+ break;
+ }
+ return PORT_TYPE_SCALAR;
}
String VisualShaderNodeSwitch::get_output_port_name(int p_port) const {
return "result";
}
+void VisualShaderNodeSwitch::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX);
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_FLOAT:
+ set_input_port_default_value(1, 1.0);
+ set_input_port_default_value(2, 0.0);
+ break;
+ case OP_TYPE_INT:
+ set_input_port_default_value(1, 1);
+ set_input_port_default_value(2, 0);
+ break;
+ case OP_TYPE_VECTOR:
+ set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
+ set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
+ break;
+ case OP_TYPE_BOOLEAN:
+ set_input_port_default_value(1, true);
+ set_input_port_default_value(2, false);
+ break;
+ case OP_TYPE_TRANSFORM:
+ set_input_port_default_value(1, Transform());
+ set_input_port_default_value(2, Transform());
+ break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
+}
+
+VisualShaderNodeSwitch::OpType VisualShaderNodeSwitch::get_op_type() const {
+ return op_type;
+}
+
+Vector<StringName> VisualShaderNodeSwitch::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("op_type");
+ return props;
+}
+
+void VisualShaderNodeSwitch::_bind_methods() { // static
+ ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSwitch::set_op_type);
+ ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSwitch::get_op_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_op_type", "get_op_type");
+
+ BIND_ENUM_CONSTANT(OP_TYPE_FLOAT);
+ BIND_ENUM_CONSTANT(OP_TYPE_INT);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(OP_TYPE_BOOLEAN);
+ BIND_ENUM_CONSTANT(OP_TYPE_TRANSFORM);
+ BIND_ENUM_CONSTANT(OP_TYPE_MAX);
+}
+
String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
code += "\tif(" + p_input_vars[0] + ")\n";
@@ -4897,29 +5015,6 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::
VisualShaderNodeSwitch::VisualShaderNodeSwitch() {
simple_decl = false;
set_input_port_default_value(0, false);
- set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
- set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
-}
-
-////////////// Switch(scalar)
-
-String VisualShaderNodeScalarSwitch::get_caption() const {
- return "ScalarSwitch";
-}
-
-VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_input_port_type(int p_port) const {
- if (p_port == 0) {
- return PORT_TYPE_BOOLEAN;
- }
- return PORT_TYPE_SCALAR;
-}
-
-VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_output_port_type(int p_port) const {
- return PORT_TYPE_SCALAR;
-}
-
-VisualShaderNodeScalarSwitch::VisualShaderNodeScalarSwitch() {
- set_input_port_default_value(0, false);
set_input_port_default_value(1, 1.0);
set_input_port_default_value(2, 0.0);
}
@@ -5106,9 +5201,6 @@ int VisualShaderNodeCompare::get_input_port_count() const {
}
VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(int p_port) const {
- if (p_port == 2) {
- return PORT_TYPE_SCALAR;
- }
switch (ctype) {
case CTYPE_SCALAR:
return PORT_TYPE_SCALAR;
@@ -5120,8 +5212,9 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i
return PORT_TYPE_BOOLEAN;
case CTYPE_TRANSFORM:
return PORT_TYPE_TRANSFORM;
+ default:
+ return PORT_TYPE_SCALAR;
}
- return PORT_TYPE_VECTOR;
}
String VisualShaderNodeCompare::get_input_port_name(int p_port) const {
@@ -5340,10 +5433,10 @@ int VisualShaderNodeMultiplyAdd::get_input_port_count() const {
}
VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_input_port_type(int p_port) const {
- if (op_type == OP_TYPE_SCALAR) {
- return PORT_TYPE_SCALAR;
+ if (op_type == OP_TYPE_VECTOR) {
+ return PORT_TYPE_VECTOR;
}
- return PORT_TYPE_VECTOR;
+ return PORT_TYPE_SCALAR;
}
String VisualShaderNodeMultiplyAdd::get_input_port_name(int p_port) const {
@@ -5379,16 +5472,22 @@ String VisualShaderNodeMultiplyAdd::generate_code(Shader::Mode p_mode, VisualSha
void VisualShaderNodeMultiplyAdd::set_op_type(OpType p_op_type) {
ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX);
- if (p_op_type != op_type) {
- if (p_op_type == OP_TYPE_SCALAR) {
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_SCALAR:
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, 0.0);
- } else {
+ break;
+ case OP_TYPE_VECTOR:
set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
- }
+ break;
+ default:
+ break;
}
op_type = p_op_type;
emit_changed();
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 4b39c76388..a5d0fe4649 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,8 +37,27 @@
/// CONSTANTS
///////////////////////////////////////
-class VisualShaderNodeFloatConstant : public VisualShaderNode {
- GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNode);
+class VisualShaderNodeConstant : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeConstant, VisualShaderNode);
+
+public:
+ virtual String get_caption() const override = 0;
+
+ virtual int get_input_port_count() const override = 0;
+ virtual PortType get_input_port_type(int p_port) const override = 0;
+ virtual String get_input_port_name(int p_port) const override = 0;
+
+ virtual int get_output_port_count() const override = 0;
+ virtual PortType get_output_port_type(int p_port) const override = 0;
+ virtual String get_output_port_name(int p_port) const override = 0;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override = 0;
+
+ VisualShaderNodeConstant();
+};
+
+class VisualShaderNodeFloatConstant : public VisualShaderNodeConstant {
+ GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNodeConstant);
float constant = 0.0f;
protected:
@@ -67,8 +86,8 @@ public:
///////////////////////////////////////
-class VisualShaderNodeIntConstant : public VisualShaderNode {
- GDCLASS(VisualShaderNodeIntConstant, VisualShaderNode);
+class VisualShaderNodeIntConstant : public VisualShaderNodeConstant {
+ GDCLASS(VisualShaderNodeIntConstant, VisualShaderNodeConstant);
int constant = 0;
protected:
@@ -97,8 +116,8 @@ public:
///////////////////////////////////////
-class VisualShaderNodeBooleanConstant : public VisualShaderNode {
- GDCLASS(VisualShaderNodeBooleanConstant, VisualShaderNode);
+class VisualShaderNodeBooleanConstant : public VisualShaderNodeConstant {
+ GDCLASS(VisualShaderNodeBooleanConstant, VisualShaderNodeConstant);
bool constant = false;
protected:
@@ -127,8 +146,8 @@ public:
///////////////////////////////////////
-class VisualShaderNodeColorConstant : public VisualShaderNode {
- GDCLASS(VisualShaderNodeColorConstant, VisualShaderNode);
+class VisualShaderNodeColorConstant : public VisualShaderNodeConstant {
+ GDCLASS(VisualShaderNodeColorConstant, VisualShaderNodeConstant);
Color constant = Color(1, 1, 1, 1);
protected:
@@ -157,8 +176,8 @@ public:
///////////////////////////////////////
-class VisualShaderNodeVec3Constant : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVec3Constant, VisualShaderNode);
+class VisualShaderNodeVec3Constant : public VisualShaderNodeConstant {
+ GDCLASS(VisualShaderNodeVec3Constant, VisualShaderNodeConstant);
Vector3 constant;
protected:
@@ -187,8 +206,8 @@ public:
///////////////////////////////////////
-class VisualShaderNodeTransformConstant : public VisualShaderNode {
- GDCLASS(VisualShaderNodeTransformConstant, VisualShaderNode);
+class VisualShaderNodeTransformConstant : public VisualShaderNodeConstant {
+ GDCLASS(VisualShaderNodeTransformConstant, VisualShaderNodeConstant);
Transform constant;
protected:
@@ -236,7 +255,7 @@ public:
enum TextureType {
TYPE_DATA,
TYPE_COLOR,
- TYPE_NORMALMAP,
+ TYPE_NORMAL_MAP,
};
private:
@@ -412,7 +431,7 @@ public:
enum TextureType {
TYPE_DATA,
TYPE_COLOR,
- TYPE_NORMALMAP
+ TYPE_NORMAL_MAP
};
private:
@@ -807,7 +826,6 @@ class VisualShaderNodeIntFunc : public VisualShaderNode {
public:
enum Function {
FUNC_ABS,
- FUNC_CLAMP,
FUNC_NEGATE,
FUNC_SIGN,
};
@@ -1069,29 +1087,20 @@ public:
/// CLAMP
///////////////////////////////////////
-class VisualShaderNodeScalarClamp : public VisualShaderNode {
- GDCLASS(VisualShaderNodeScalarClamp, VisualShaderNode);
+class VisualShaderNodeClamp : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeClamp, VisualShaderNode);
public:
- virtual String get_caption() const override;
-
- virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
- virtual String get_input_port_name(int p_port) const override;
-
- virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
- virtual String get_output_port_name(int p_port) const override;
-
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
-
- VisualShaderNodeScalarClamp();
-};
-
-///////////////////////////////////////
+ enum OpType {
+ OP_TYPE_FLOAT,
+ OP_TYPE_INT,
+ OP_TYPE_VECTOR,
+ OP_TYPE_MAX,
+ };
-class VisualShaderNodeVectorClamp : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorClamp, VisualShaderNode);
+protected:
+ OpType op_type = OP_TYPE_FLOAT;
+ static void _bind_methods();
public:
virtual String get_caption() const override;
@@ -1104,11 +1113,18 @@ public:
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ void set_op_type(OpType p_type);
+ OpType get_op_type() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeVectorClamp();
+ VisualShaderNodeClamp();
};
+VARIANT_ENUM_CAST(VisualShaderNodeClamp::OpType)
+
///////////////////////////////////////
/// DERIVATIVE FUNCTIONS
///////////////////////////////////////
@@ -1241,8 +1257,20 @@ public:
/// STEP
///////////////////////////////////////
-class VisualShaderNodeVectorScalarStep : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorScalarStep, VisualShaderNode);
+class VisualShaderNodeStep : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeStep, VisualShaderNode);
+
+public:
+ enum OpType {
+ OP_TYPE_SCALAR,
+ OP_TYPE_VECTOR,
+ OP_TYPE_VECTOR_SCALAR,
+ OP_TYPE_MAX,
+ };
+
+protected:
+ OpType op_type = OP_TYPE_SCALAR;
+ static void _bind_methods();
public:
virtual String get_caption() const override;
@@ -1255,38 +1283,36 @@ public:
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ void set_op_type(OpType p_type);
+ OpType get_op_type() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeVectorScalarStep();
+ VisualShaderNodeStep();
};
+VARIANT_ENUM_CAST(VisualShaderNodeStep::OpType)
+
///////////////////////////////////////
/// SMOOTHSTEP
///////////////////////////////////////
-class VisualShaderNodeScalarSmoothStep : public VisualShaderNode {
- GDCLASS(VisualShaderNodeScalarSmoothStep, VisualShaderNode);
+class VisualShaderNodeSmoothStep : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeSmoothStep, VisualShaderNode);
public:
- virtual String get_caption() const override;
-
- virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
- virtual String get_input_port_name(int p_port) const override;
-
- virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
- virtual String get_output_port_name(int p_port) const override;
-
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
-
- VisualShaderNodeScalarSmoothStep();
-};
-
-///////////////////////////////////////
+ enum OpType {
+ OP_TYPE_SCALAR,
+ OP_TYPE_VECTOR,
+ OP_TYPE_VECTOR_SCALAR,
+ OP_TYPE_MAX,
+ };
-class VisualShaderNodeVectorSmoothStep : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorSmoothStep, VisualShaderNode);
+protected:
+ OpType op_type = OP_TYPE_SCALAR;
+ static void _bind_methods();
public:
virtual String get_caption() const override;
@@ -1299,32 +1325,18 @@ public:
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
-
- VisualShaderNodeVectorSmoothStep();
-};
-
-///////////////////////////////////////
-
-class VisualShaderNodeVectorScalarSmoothStep : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorScalarSmoothStep, VisualShaderNode);
-
-public:
- virtual String get_caption() const override;
-
- virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
- virtual String get_input_port_name(int p_port) const override;
+ void set_op_type(OpType p_type);
+ OpType get_op_type() const;
- virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
- virtual String get_output_port_name(int p_port) const override;
+ virtual Vector<StringName> get_editable_properties() const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeVectorScalarSmoothStep();
+ VisualShaderNodeSmoothStep();
};
+VARIANT_ENUM_CAST(VisualShaderNodeSmoothStep::OpType)
+
///////////////////////////////////////
/// DISTANCE
///////////////////////////////////////
@@ -1375,29 +1387,20 @@ public:
/// MIX
///////////////////////////////////////
-class VisualShaderNodeScalarInterp : public VisualShaderNode {
- GDCLASS(VisualShaderNodeScalarInterp, VisualShaderNode);
+class VisualShaderNodeMix : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeMix, VisualShaderNode);
public:
- virtual String get_caption() const override;
-
- virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
- virtual String get_input_port_name(int p_port) const override;
-
- virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
- virtual String get_output_port_name(int p_port) const override;
-
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
-
- VisualShaderNodeScalarInterp();
-};
-
-///////////////////////////////////////
+ enum OpType {
+ OP_TYPE_SCALAR,
+ OP_TYPE_VECTOR,
+ OP_TYPE_VECTOR_SCALAR,
+ OP_TYPE_MAX,
+ };
-class VisualShaderNodeVectorInterp : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorInterp, VisualShaderNode);
+protected:
+ OpType op_type = OP_TYPE_SCALAR;
+ static void _bind_methods();
public:
virtual String get_caption() const override;
@@ -1410,32 +1413,18 @@ public:
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
-
- VisualShaderNodeVectorInterp();
-};
-
-///////////////////////////////////////
-
-class VisualShaderNodeVectorScalarMix : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorScalarMix, VisualShaderNode);
-
-public:
- virtual String get_caption() const override;
-
- virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
- virtual String get_input_port_name(int p_port) const override;
+ void set_op_type(OpType p_type);
+ OpType get_op_type() const;
- virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
- virtual String get_output_port_name(int p_port) const override;
+ virtual Vector<StringName> get_editable_properties() const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeVectorScalarMix();
+ VisualShaderNodeMix();
};
+VARIANT_ENUM_CAST(VisualShaderNodeMix::OpType)
+
///////////////////////////////////////
/// COMPOSE
///////////////////////////////////////
@@ -1834,7 +1823,7 @@ public:
enum TextureType {
TYPE_DATA,
TYPE_COLOR,
- TYPE_NORMALMAP,
+ TYPE_NORMAL_MAP,
TYPE_ANISO,
};
@@ -2004,6 +1993,21 @@ class VisualShaderNodeSwitch : public VisualShaderNode {
GDCLASS(VisualShaderNodeSwitch, VisualShaderNode);
public:
+ enum OpType {
+ OP_TYPE_FLOAT,
+ OP_TYPE_INT,
+ OP_TYPE_VECTOR,
+ OP_TYPE_BOOLEAN,
+ OP_TYPE_TRANSFORM,
+ OP_TYPE_MAX,
+ };
+
+protected:
+ OpType op_type = OP_TYPE_FLOAT;
+
+ static void _bind_methods();
+
+public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
@@ -2014,22 +2018,17 @@ public:
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ void set_op_type(OpType p_type);
+ OpType get_op_type() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeSwitch();
};
-class VisualShaderNodeScalarSwitch : public VisualShaderNodeSwitch {
- GDCLASS(VisualShaderNodeScalarSwitch, VisualShaderNodeSwitch);
-
-public:
- virtual String get_caption() const override;
-
- virtual PortType get_input_port_type(int p_port) const override;
- virtual PortType get_output_port_type(int p_port) const override;
-
- VisualShaderNodeScalarSwitch();
-};
+VARIANT_ENUM_CAST(VisualShaderNodeSwitch::OpType)
///////////////////////////////////////
/// FRESNEL
diff --git a/scene/resources/visual_shader_sdf_nodes.cpp b/scene/resources/visual_shader_sdf_nodes.cpp
new file mode 100644
index 0000000000..d25e32b070
--- /dev/null
+++ b/scene/resources/visual_shader_sdf_nodes.cpp
@@ -0,0 +1,283 @@
+/*************************************************************************/
+/* visual_shader_sdf_nodes.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "visual_shader_sdf_nodes.h"
+
+// VisualShaderNodeSDFToScreenUV
+
+String VisualShaderNodeSDFToScreenUV::get_caption() const {
+ return "SDFToScreenUV";
+}
+
+int VisualShaderNodeSDFToScreenUV::get_input_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeSDFToScreenUV::get_input_port_name(int p_port) const {
+ return "sdf_pos";
+}
+
+int VisualShaderNodeSDFToScreenUV::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeSDFToScreenUV::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+}
+
+VisualShaderNodeSDFToScreenUV::VisualShaderNodeSDFToScreenUV() {
+}
+
+// VisualShaderNodeScreenUVToSDF
+
+String VisualShaderNodeScreenUVToSDF::get_caption() const {
+ return "ScreenUVToSDF";
+}
+
+int VisualShaderNodeScreenUVToSDF::get_input_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeScreenUVToSDF::get_input_port_name(int p_port) const {
+ return "uv";
+}
+
+int VisualShaderNodeScreenUVToSDF::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeScreenUVToSDF::get_output_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeScreenUVToSDF::get_input_port_default_hint(int p_port) const {
+ if (p_port == 0) {
+ return "default";
+ }
+ return "";
+}
+
+String VisualShaderNodeScreenUVToSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0] == String() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+}
+
+VisualShaderNodeScreenUVToSDF::VisualShaderNodeScreenUVToSDF() {
+}
+
+// VisualShaderNodeTextureSDF
+
+String VisualShaderNodeTextureSDF::get_caption() const {
+ return "TextureSDF";
+}
+
+int VisualShaderNodeTextureSDF::get_input_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeTextureSDF::PortType VisualShaderNodeTextureSDF::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeTextureSDF::get_input_port_name(int p_port) const {
+ return "sdf_pos";
+}
+
+int VisualShaderNodeTextureSDF::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeTextureSDF::PortType VisualShaderNodeTextureSDF::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeTextureSDF::get_output_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeTextureSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n";
+}
+
+VisualShaderNodeTextureSDF::VisualShaderNodeTextureSDF() {
+}
+
+// VisualShaderNodeTextureSDFNormal
+
+String VisualShaderNodeTextureSDFNormal::get_caption() const {
+ return "TextureSDFNormal";
+}
+
+int VisualShaderNodeTextureSDFNormal::get_input_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeTextureSDFNormal::get_input_port_name(int p_port) const {
+ return "sdf_pos";
+}
+
+int VisualShaderNodeTextureSDFNormal::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeTextureSDFNormal::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return "\t" + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+}
+
+VisualShaderNodeTextureSDFNormal::VisualShaderNodeTextureSDFNormal() {
+}
+
+// VisualShaderNodeSDFRaymarch
+
+String VisualShaderNodeSDFRaymarch::get_caption() const {
+ return "SDFRaymarch";
+}
+
+int VisualShaderNodeSDFRaymarch::get_input_port_count() const {
+ return 2;
+}
+
+VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_input_port_type(int p_port) const {
+ if (p_port == 0 || p_port == 1) {
+ return PORT_TYPE_VECTOR;
+ }
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeSDFRaymarch::get_input_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "from_pos";
+ } else if (p_port == 1) {
+ return "to_pos";
+ }
+ return String();
+}
+
+int VisualShaderNodeSDFRaymarch::get_output_port_count() const {
+ return 3;
+}
+
+VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_output_port_type(int p_port) const {
+ if (p_port == 0) {
+ return PORT_TYPE_SCALAR;
+ } else if (p_port == 1) {
+ return PORT_TYPE_BOOLEAN;
+ } else if (p_port == 2) {
+ return PORT_TYPE_VECTOR;
+ }
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeSDFRaymarch::get_output_port_name(int p_port) const {
+ if (p_port == 0) {
+ return "distance";
+ } else if (p_port == 1) {
+ return "hit";
+ } else if (p_port == 2) {
+ return "end_pos";
+ }
+ return String();
+}
+
+String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ String code;
+
+ code += "\t{\n";
+
+ if (p_input_vars[0] == String()) {
+ code += "\t\tvec2 __from_pos = vec2(0.0f);\n";
+ } else {
+ code += "\t\tvec2 __from_pos = " + p_input_vars[0] + ".xy;\n";
+ }
+
+ if (p_input_vars[1] == String()) {
+ code += "\t\tvec2 __to_pos = vec2(0.0f);\n";
+ } else {
+ code += "\t\tvec2 __to_pos = " + p_input_vars[1] + ".xy;\n";
+ }
+
+ code += "\n\t\tvec2 __at = __from_pos;\n";
+ code += "\t\tfloat __max_dist = distance(__from_pos, __to_pos);\n";
+ code += "\t\tvec2 __dir = normalize(__to_pos - __from_pos);\n\n";
+
+ code += "\t\tfloat __accum = 0.0f;\n";
+ code += "\t\twhile(__accum < __max_dist) {\n";
+ code += "\t\t\tfloat __d = texture_sdf(__at);\n";
+ code += "\t\t\t__accum += __d;\n";
+ code += "\t\t\tif (__d < 0.01f) {\n";
+ code += "\t\t\t\tbreak;\n";
+ code += "\t\t\t}\n";
+ code += "\t\t\t__at += __d * __dir;\n";
+ code += "\t\t}\n";
+
+ code += "\t\tfloat __dist = min(__max_dist, __accum);\n";
+ code += "\t\t" + p_output_vars[0] + " = __dist;\n";
+ code += "\t\t" + p_output_vars[1] + " = __accum < __max_dist;\n";
+ code += "\t\t" + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n";
+
+ code += "\t}\n";
+
+ return code;
+}
+
+VisualShaderNodeSDFRaymarch::VisualShaderNodeSDFRaymarch() {
+ simple_decl = false;
+}
diff --git a/scene/resources/visual_shader_sdf_nodes.h b/scene/resources/visual_shader_sdf_nodes.h
new file mode 100644
index 0000000000..0fcf5ec0b5
--- /dev/null
+++ b/scene/resources/visual_shader_sdf_nodes.h
@@ -0,0 +1,132 @@
+/*************************************************************************/
+/* visual_shader_sdf_nodes.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef VISUAL_SHADER_SDF_NODES_H
+#define VISUAL_SHADER_SDF_NODES_H
+
+#include "scene/resources/visual_shader.h"
+
+class VisualShaderNodeSDFToScreenUV : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeSDFToScreenUV, VisualShaderNode);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ VisualShaderNodeSDFToScreenUV();
+};
+
+class VisualShaderNodeScreenUVToSDF : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeScreenUVToSDF, VisualShaderNode);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String get_input_port_default_hint(int p_port) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ VisualShaderNodeScreenUVToSDF();
+};
+
+class VisualShaderNodeTextureSDF : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTextureSDF, VisualShaderNode);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ VisualShaderNodeTextureSDF();
+};
+
+class VisualShaderNodeTextureSDFNormal : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTextureSDFNormal, VisualShaderNode);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ VisualShaderNodeTextureSDFNormal();
+};
+
+class VisualShaderNodeSDFRaymarch : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeSDFRaymarch, VisualShaderNode);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ VisualShaderNodeSDFRaymarch();
+};
+
+#endif // VISUAL_SHADER_SDF_NODES_H
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index 41d3fe20be..a064ade362 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,12 +34,13 @@
#include "scene/2d/camera_2d.h"
#include "scene/2d/visibility_notifier_2d.h"
#include "scene/main/window.h"
+#include "servers/navigation_server_2d.h"
#include "servers/physics_server_2d.h"
#include "servers/rendering_server.h"
struct SpatialIndexer2D {
struct CellRef {
- int ref;
+ int ref = 0;
_FORCE_INLINE_ int inc() {
ref++;
@@ -49,10 +50,6 @@ struct SpatialIndexer2D {
ref--;
return ref;
}
-
- _FORCE_INLINE_ CellRef() {
- ref = 0;
- }
};
struct CellKey {
@@ -61,7 +58,7 @@ struct SpatialIndexer2D {
int32_t x;
int32_t y;
};
- uint64_t key;
+ uint64_t key = 0;
};
bool operator==(const CellKey &p_key) const { return key == p_key.key; }
@@ -86,9 +83,9 @@ struct SpatialIndexer2D {
Map<Viewport *, ViewportData> viewports;
- bool changed;
+ bool changed = false;
- uint64_t pass;
+ uint64_t pass = 0;
void _notifier_update_cells(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect, bool p_add) {
Point2i begin = p_rect.position;
@@ -111,7 +108,7 @@ struct SpatialIndexer2D {
ERR_CONTINUE(!E);
if (E->get().notifiers[p_notifier].dec() == 0) {
E->get().notifiers.erase(p_notifier);
- if (E->get().notifiers.empty()) {
+ if (E->get().notifiers.is_empty()) {
cells.erase(E);
}
}
@@ -156,7 +153,7 @@ struct SpatialIndexer2D {
}
}
- while (!removed.empty()) {
+ while (!removed.is_empty()) {
p_notifier->_exit_viewport(removed.front()->get());
removed.pop_front();
}
@@ -189,7 +186,7 @@ struct SpatialIndexer2D {
removed.push_back(E->key());
}
- while (!removed.empty()) {
+ while (!removed.is_empty()) {
removed.front()->get()->_exit_viewport(p_viewport);
removed.pop_front();
}
@@ -271,12 +268,12 @@ struct SpatialIndexer2D {
}
}
- while (!added.empty()) {
+ while (!added.is_empty()) {
added.front()->get()->_enter_viewport(E->key());
added.pop_front();
}
- while (!removed.empty()) {
+ while (!removed.is_empty()) {
E->get().notifiers.erase(removed.front()->get());
removed.front()->get()->_exit_viewport(E->key());
removed.pop_front();
@@ -287,8 +284,6 @@ struct SpatialIndexer2D {
}
SpatialIndexer2D() {
- pass = 0;
- changed = false;
cell_size = GLOBAL_DEF("world/2d/cell_size", 100);
}
};
@@ -321,14 +316,18 @@ void World2D::_update() {
indexer->_update();
}
-RID World2D::get_canvas() {
+RID World2D::get_canvas() const {
return canvas;
}
-RID World2D::get_space() {
+RID World2D::get_space() const {
return space;
}
+RID World2D::get_navigation_map() const {
+ return navigation_map;
+}
+
void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
r_viewports->push_back(E->key());
@@ -338,11 +337,13 @@ void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
void World2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas);
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
+ ClassDB::bind_method(D_METHOD("get_navigation_map"), &World2D::get_navigation_map);
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state);
ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas");
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
+ ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", 0), "", "get_direct_space_state");
}
@@ -352,9 +353,9 @@ PhysicsDirectSpaceState2D *World2D::get_direct_space_state() {
World2D::World2D() {
canvas = RenderingServer::get_singleton()->canvas_create();
- space = PhysicsServer2D::get_singleton()->space_create();
- //set space2D to be more friendly with pixels than meters, by adjusting some constants
+ // Create and configure space2D to be more friendly with pixels than meters
+ space = PhysicsServer2D::get_singleton()->space_create();
PhysicsServer2D::get_singleton()->space_set_active(space, true);
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98));
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1)));
@@ -362,11 +363,19 @@ World2D::World2D() {
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0));
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
+
+ // Create and configure the navigation_map to be more friendly with pixels than meters.
+ navigation_map = NavigationServer2D::get_singleton()->map_create();
+ NavigationServer2D::get_singleton()->map_set_active(navigation_map, true);
+ NavigationServer2D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 10));
+ NavigationServer2D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 100));
+
indexer = memnew(SpatialIndexer2D);
}
World2D::~World2D() {
RenderingServer::get_singleton()->free(canvas);
PhysicsServer2D::get_singleton()->free(space);
+ NavigationServer2D::get_singleton()->free(navigation_map);
memdelete(indexer);
}
diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h
index 11614f9aa4..38abf3d7ad 100644
--- a/scene/resources/world_2d.h
+++ b/scene/resources/world_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,6 +44,7 @@ class World2D : public Resource {
RID canvas;
RID space;
+ RID navigation_map;
SpatialIndexer2D *indexer;
@@ -63,8 +64,9 @@ protected:
void _update();
public:
- RID get_canvas();
- RID get_space();
+ RID get_canvas() const;
+ RID get_space() const;
+ RID get_navigation_map() const;
PhysicsDirectSpaceState2D *get_direct_space_state();
diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp
index b8fb3825ce..0e9f7a6cf2 100644
--- a/scene/resources/world_3d.cpp
+++ b/scene/resources/world_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,6 +35,7 @@
#include "scene/3d/camera_3d.h"
#include "scene/3d/visibility_notifier_3d.h"
#include "scene/scene_string_names.h"
+#include "servers/navigation_server_3d.h"
struct SpatialIndexer {
Octree<VisibilityNotifier3D> octree;
@@ -97,7 +98,7 @@ struct SpatialIndexer {
}
}
- while (!removed.empty()) {
+ while (!removed.is_empty()) {
p_notifier->_exit_camera(removed.front()->get());
removed.pop_front();
}
@@ -125,7 +126,7 @@ struct SpatialIndexer {
removed.push_back(E->key());
}
- while (!removed.empty()) {
+ while (!removed.is_empty()) {
removed.front()->get()->_exit_camera(p_camera);
removed.pop_front();
}
@@ -175,12 +176,12 @@ struct SpatialIndexer {
}
}
- while (!added.empty()) {
+ while (!added.is_empty()) {
added.front()->get()->_enter_camera(E->key());
added.pop_front();
}
- while (!removed.empty()) {
+ while (!removed.is_empty()) {
E->get().notifiers.erase(removed.front()->get());
removed.front()->get()->_exit_camera(E->key());
removed.pop_front();
@@ -243,6 +244,10 @@ RID World3D::get_space() const {
return space;
}
+RID World3D::get_navigation_map() const {
+ return navigation_map;
+}
+
RID World3D::get_scenario() const {
return scenario;
}
@@ -310,6 +315,7 @@ void World3D::get_camera_list(List<Camera3D *> *r_cameras) {
void World3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space);
+ ClassDB::bind_method(D_METHOD("get_navigation_map"), &World3D::get_navigation_map);
ClassDB::bind_method(D_METHOD("get_scenario"), &World3D::get_scenario);
ClassDB::bind_method(D_METHOD("set_environment", "env"), &World3D::set_environment);
ClassDB::bind_method(D_METHOD("get_environment"), &World3D::get_environment);
@@ -322,6 +328,7 @@ void World3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects");
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
+ ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map");
ADD_PROPERTY(PropertyInfo(Variant::RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState3D", 0), "", "get_direct_space_state");
}
@@ -338,6 +345,11 @@ World3D::World3D() {
PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1));
ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
+ navigation_map = NavigationServer3D::get_singleton()->map_create();
+ NavigationServer3D::get_singleton()->map_set_active(navigation_map, true);
+ NavigationServer3D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_size", 0.3));
+ NavigationServer3D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/3d/default_edge_connection_margin", 5.0)); // Five meters, depends a lot on the agent's radius
+
#ifdef _3D_DISABLED
indexer = nullptr;
#else
@@ -348,6 +360,7 @@ World3D::World3D() {
World3D::~World3D() {
PhysicsServer3D::get_singleton()->free(space);
RenderingServer::get_singleton()->free(scenario);
+ NavigationServer3D::get_singleton()->free(navigation_map);
#ifndef _3D_DISABLED
memdelete(indexer);
diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h
index 93e9c72e59..4e2717a2bb 100644
--- a/scene/resources/world_3d.h
+++ b/scene/resources/world_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,6 +46,7 @@ class World3D : public Resource {
private:
RID space;
+ RID navigation_map;
RID scenario;
SpatialIndexer *indexer;
Ref<Environment> environment;
@@ -70,6 +71,7 @@ protected:
public:
RID get_space() const;
+ RID get_navigation_map() const;
RID get_scenario() const;
void set_environment(const Ref<Environment> &p_environment);
diff --git a/scene/resources/world_margin_shape_3d.cpp b/scene/resources/world_margin_shape_3d.cpp
index 0936fcc657..28d50e1921 100644
--- a/scene/resources/world_margin_shape_3d.cpp
+++ b/scene/resources/world_margin_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -69,7 +69,6 @@ void WorldMarginShape3D::set_plane(Plane p_plane) {
plane = p_plane;
_update_shape();
notify_change_to_owners();
- _change_notify("plane");
}
Plane WorldMarginShape3D::get_plane() const {
diff --git a/scene/resources/world_margin_shape_3d.h b/scene/resources/world_margin_shape_3d.h
index 8099592d80..00417c4408 100644
--- a/scene/resources/world_margin_shape_3d.h
+++ b/scene/resources/world_margin_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index a72066e7a8..892802c103 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index b4d2429d7f..655e49c6f9 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index a2abbeb686..a28dcb1015 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,16 +39,16 @@ Error AudioDriverDummy::init() {
exit_thread = false;
samples_in = nullptr;
- mix_rate = GLOBAL_GET("audio/mix_rate");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_GET("audio/output_latency");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_frames * channels);
- thread = Thread::create(AudioDriverDummy::thread_func, this);
+ thread.start(AudioDriverDummy::thread_func, this);
return OK;
};
@@ -86,31 +86,18 @@ AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const {
};
void AudioDriverDummy::lock() {
- if (!thread) {
- return;
- }
mutex.lock();
};
void AudioDriverDummy::unlock() {
- if (!thread) {
- return;
- }
mutex.unlock();
};
void AudioDriverDummy::finish() {
- if (!thread) {
- return;
- }
-
exit_thread = true;
- Thread::wait_to_finish(thread);
+ thread.wait_to_finish();
if (samples_in) {
memdelete_arr(samples_in);
};
-
- memdelete(thread);
- thread = nullptr;
};
diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h
index 84a566e420..7d84e7ffc8 100644
--- a/servers/audio/audio_driver_dummy.h
+++ b/servers/audio/audio_driver_dummy.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,7 +37,7 @@
#include "core/os/thread.h"
class AudioDriverDummy : public AudioDriver {
- Thread *thread = nullptr;
+ Thread thread;
Mutex mutex;
int32_t *samples_in;
diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp
index d7279cdf48..3035828c95 100644
--- a/servers/audio/audio_effect.cpp
+++ b/servers/audio/audio_effect.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h
index b1be5dfea1..4556db9b93 100644
--- a/servers/audio/audio_effect.h
+++ b/servers/audio/audio_effect.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp
index f5eafb7e60..bcfa4c4c37 100644
--- a/servers/audio/audio_filter_sw.cpp
+++ b/servers/audio/audio_filter_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,7 +58,7 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
final_cutoff = 1; //don't allow less than this
}
- double omega = 2.0 * Math_PI * final_cutoff / sampling_rate;
+ double omega = Math_TAU * final_cutoff / sampling_rate;
double sin_v = Math::sin(omega);
double cos_v = Math::cos(omega);
@@ -132,7 +132,7 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
double hicutoff = resonance;
double centercutoff = (cutoff + resonance) / 2.0;
double bandwidth = (Math::log(centercutoff) - Math::log(hicutoff)) / Math::log((double)2);
- omega = 2.0 * Math_PI * centercutoff / sampling_rate;
+ omega = Math_TAU * centercutoff / sampling_rate;
alpha = Math::sin(omega) * Math::sinh(Math::log((double)2) / 2 * bandwidth * omega / Math::sin(omega));
a0 = 1 + alpha;
@@ -197,7 +197,7 @@ void AudioFilterSW::set_stages(int p_stages) { //adjust for multiple stages
/* Fouriertransform kernel to obtain response */
float AudioFilterSW::get_response(float p_freq, Coeffs *p_coeffs) {
- float freq = p_freq / sampling_rate * Math_PI * 2.0f;
+ float freq = p_freq / sampling_rate * Math_TAU;
float cx = p_coeffs->b0, cy = 0.0;
diff --git a/servers/audio/audio_filter_sw.h b/servers/audio/audio_filter_sw.h
index a7f570fbb4..540d6368e3 100644
--- a/servers/audio/audio_filter_sw.h
+++ b/servers/audio/audio_filter_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index 7613e70e64..3c8a1469cd 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -131,7 +131,7 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
src_read = read_space;
}
- rb_read_pos = (rb_read_pos + src_read) & rb_mask;
+ rb_read_pos.set((rb_read_pos.get() + src_read) & rb_mask);
// Create fadeout effect for the end of stream (note that it can be because of slow writer)
if (p_frames - target_todo > 0) {
@@ -183,8 +183,8 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m
src_mix_rate = p_src_mix_rate;
target_mix_rate = p_target_mix_rate;
offset = 0;
- rb_read_pos = 0;
- rb_write_pos = 0;
+ rb_read_pos.set(0);
+ rb_write_pos.set(0);
//avoid maybe strange noises upon load
for (unsigned int i = 0; i < (rb_len * channels); i++) {
@@ -205,8 +205,8 @@ void AudioRBResampler::clear() {
memdelete_arr(read_buf);
rb = nullptr;
offset = 0;
- rb_read_pos = 0;
- rb_write_pos = 0;
+ rb_read_pos.set(0);
+ rb_write_pos.set(0);
read_buf = nullptr;
}
@@ -214,8 +214,8 @@ AudioRBResampler::AudioRBResampler() {
rb = nullptr;
offset = 0;
read_buf = nullptr;
- rb_read_pos = 0;
- rb_write_pos = 0;
+ rb_read_pos.set(0);
+ rb_write_pos.set(0);
rb_bits = 0;
rb_len = 0;
diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h
index 12ec526adb..c0f981704b 100644
--- a/servers/audio/audio_rb_resampler.h
+++ b/servers/audio/audio_rb_resampler.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#define AUDIO_RB_RESAMPLER_H
#include "core/os/memory.h"
+#include "core/templates/safe_refcount.h"
#include "core/typedefs.h"
#include "servers/audio_server.h"
@@ -44,8 +45,8 @@ struct AudioRBResampler {
uint32_t src_mix_rate;
uint32_t target_mix_rate;
- volatile int rb_read_pos;
- volatile int rb_write_pos;
+ SafeNumeric<int> rb_read_pos;
+ SafeNumeric<int> rb_write_pos;
int32_t offset; //contains the fractional remainder of the resampler
enum {
@@ -62,8 +63,8 @@ struct AudioRBResampler {
public:
_FORCE_INLINE_ void flush() {
- rb_read_pos = 0;
- rb_write_pos = 0;
+ rb_read_pos.set(0);
+ rb_write_pos.set(0);
offset = 0;
}
@@ -78,8 +79,8 @@ public:
_FORCE_INLINE_ int get_writer_space() const {
int space, r, w;
- r = rb_read_pos;
- w = rb_write_pos;
+ r = rb_read_pos.get();
+ w = rb_write_pos.get();
if (r == w) {
space = rb_len - 1;
@@ -95,8 +96,8 @@ public:
_FORCE_INLINE_ int get_reader_space() const {
int space, r, w;
- r = rb_read_pos;
- w = rb_write_pos;
+ r = rb_read_pos.get();
+ w = rb_write_pos.get();
if (r == w) {
space = 0;
@@ -110,48 +111,52 @@ public:
}
_FORCE_INLINE_ bool has_data() const {
- return rb && rb_read_pos != rb_write_pos;
+ return rb && rb_read_pos.get() != rb_write_pos.get();
}
_FORCE_INLINE_ float *get_write_buffer() { return read_buf; }
_FORCE_INLINE_ void write(uint32_t p_frames) {
ERR_FAIL_COND(p_frames >= rb_len);
+ int wp = rb_write_pos.get();
+
switch (channels) {
case 1: {
for (uint32_t i = 0; i < p_frames; i++) {
- rb[rb_write_pos] = read_buf[i];
- rb_write_pos = (rb_write_pos + 1) & rb_mask;
+ rb[wp] = read_buf[i];
+ wp = (wp + 1) & rb_mask;
}
} break;
case 2: {
for (uint32_t i = 0; i < p_frames; i++) {
- rb[(rb_write_pos << 1) + 0] = read_buf[(i << 1) + 0];
- rb[(rb_write_pos << 1) + 1] = read_buf[(i << 1) + 1];
- rb_write_pos = (rb_write_pos + 1) & rb_mask;
+ rb[(wp << 1) + 0] = read_buf[(i << 1) + 0];
+ rb[(wp << 1) + 1] = read_buf[(i << 1) + 1];
+ wp = (wp + 1) & rb_mask;
}
} break;
case 4: {
for (uint32_t i = 0; i < p_frames; i++) {
- rb[(rb_write_pos << 2) + 0] = read_buf[(i << 2) + 0];
- rb[(rb_write_pos << 2) + 1] = read_buf[(i << 2) + 1];
- rb[(rb_write_pos << 2) + 2] = read_buf[(i << 2) + 2];
- rb[(rb_write_pos << 2) + 3] = read_buf[(i << 2) + 3];
- rb_write_pos = (rb_write_pos + 1) & rb_mask;
+ rb[(wp << 2) + 0] = read_buf[(i << 2) + 0];
+ rb[(wp << 2) + 1] = read_buf[(i << 2) + 1];
+ rb[(wp << 2) + 2] = read_buf[(i << 2) + 2];
+ rb[(wp << 2) + 3] = read_buf[(i << 2) + 3];
+ wp = (wp + 1) & rb_mask;
}
} break;
case 6: {
for (uint32_t i = 0; i < p_frames; i++) {
- rb[(rb_write_pos * 6) + 0] = read_buf[(i * 6) + 0];
- rb[(rb_write_pos * 6) + 1] = read_buf[(i * 6) + 1];
- rb[(rb_write_pos * 6) + 2] = read_buf[(i * 6) + 2];
- rb[(rb_write_pos * 6) + 3] = read_buf[(i * 6) + 3];
- rb[(rb_write_pos * 6) + 4] = read_buf[(i * 6) + 4];
- rb[(rb_write_pos * 6) + 5] = read_buf[(i * 6) + 5];
- rb_write_pos = (rb_write_pos + 1) & rb_mask;
+ rb[(wp * 6) + 0] = read_buf[(i * 6) + 0];
+ rb[(wp * 6) + 1] = read_buf[(i * 6) + 1];
+ rb[(wp * 6) + 2] = read_buf[(i * 6) + 2];
+ rb[(wp * 6) + 3] = read_buf[(i * 6) + 3];
+ rb[(wp * 6) + 4] = read_buf[(i * 6) + 4];
+ rb[(wp * 6) + 5] = read_buf[(i * 6) + 5];
+ wp = (wp + 1) & rb_mask;
}
} break;
}
+
+ rb_write_pos.set(wp);
}
int get_channel_count() const;
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index a7c9443dcf..ae07f999ed 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,21 +54,21 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
for (int i = 0; i < p_frames; i++) {
uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS);
- //standard cubic interpolation (great quality/performance ratio)
- //this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory.
+ // 4 point, 4th order optimal resampling algorithm from: http://yehar.com/blog/wp-content/uploads/2009/08/deip.pdf
float mu = (mix_offset & FP_MASK) / float(FP_LEN);
AudioFrame y0 = internal_buffer[idx - 3];
AudioFrame y1 = internal_buffer[idx - 2];
AudioFrame y2 = internal_buffer[idx - 1];
AudioFrame y3 = internal_buffer[idx - 0];
- float mu2 = mu * mu;
- AudioFrame a0 = y3 - y2 - y0 + y1;
- AudioFrame a1 = y0 - y1 - a0;
- AudioFrame a2 = y2 - y0;
- AudioFrame a3 = y1;
-
- p_buffer[i] = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3);
+ AudioFrame even1 = y2 + y1, odd1 = y2 - y1;
+ AudioFrame even2 = y3 + y0, odd2 = y3 - y0;
+ AudioFrame c0 = even1 * 0.46835497211269561 + even2 * 0.03164502784253309;
+ AudioFrame c1 = odd1 * 0.56001293337091440 + odd2 * 0.14666238593949288;
+ AudioFrame c2 = even1 * -0.250038759826233691 + even2 * 0.25003876124297131;
+ AudioFrame c3 = odd1 * -0.49949850957839148 + odd2 * 0.16649935475113800;
+ AudioFrame c4 = even1 * 0.00016095224137360 + even2 * -0.00016095810460478;
+ p_buffer[i] = (((c4 * mu + c3) * mu + c2) * mu + c1) * mu + c0;
mix_offset += mix_increment;
@@ -184,7 +184,7 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
return;
}
- if (!GLOBAL_GET("audio/enable_audio_input")) {
+ if (!GLOBAL_GET("audio/driver/enable_input")) {
WARN_PRINT("Need to enable Project settings > Audio > Enable Audio Input option to use capturing.");
return;
}
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 0bbb29b15c..93566783be 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_amplify.cpp b/servers/audio/effects/audio_effect_amplify.cpp
index 74fdcbc67a..c5c1174670 100644
--- a/servers/audio/effects/audio_effect_amplify.cpp
+++ b/servers/audio/effects/audio_effect_amplify.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_amplify.h b/servers/audio/effects/audio_effect_amplify.h
index 7245bbdcbe..2ece57854c 100644
--- a/servers/audio/effects/audio_effect_amplify.h
+++ b/servers/audio/effects/audio_effect_amplify.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp
new file mode 100644
index 0000000000..37e4122e50
--- /dev/null
+++ b/servers/audio/effects/audio_effect_capture.cpp
@@ -0,0 +1,140 @@
+/*************************************************************************/
+/* audio_effect_capture.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "audio_effect_capture.h"
+
+bool AudioEffectCapture::can_get_buffer(int p_frames) const {
+ return buffer.data_left() >= p_frames;
+}
+
+PackedVector2Array AudioEffectCapture::get_buffer(int p_frames) {
+ ERR_FAIL_COND_V(!buffer_initialized, PackedVector2Array());
+ ERR_FAIL_INDEX_V(p_frames, buffer.size(), PackedVector2Array());
+ int data_left = buffer.data_left();
+ if (data_left < p_frames || p_frames == 0) {
+ return PackedVector2Array();
+ }
+
+ PackedVector2Array ret;
+ ret.resize(p_frames);
+
+ Vector<AudioFrame> streaming_data;
+ streaming_data.resize(p_frames);
+ buffer.read(streaming_data.ptrw(), p_frames);
+ for (int32_t i = 0; i < p_frames; i++) {
+ ret.write[i] = Vector2(streaming_data[i].l, streaming_data[i].r);
+ }
+ return ret;
+}
+
+void AudioEffectCapture::clear_buffer() {
+ const int32_t data_left = buffer.data_left();
+ buffer.advance_read(data_left);
+}
+
+void AudioEffectCapture::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("can_get_buffer", "frames"), &AudioEffectCapture::can_get_buffer);
+ ClassDB::bind_method(D_METHOD("get_buffer", "frames"), &AudioEffectCapture::get_buffer);
+ ClassDB::bind_method(D_METHOD("clear_buffer"), &AudioEffectCapture::clear_buffer);
+ ClassDB::bind_method(D_METHOD("set_buffer_length", "buffer_length_seconds"), &AudioEffectCapture::set_buffer_length);
+ ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioEffectCapture::get_buffer_length);
+ ClassDB::bind_method(D_METHOD("get_frames_available"), &AudioEffectCapture::get_frames_available);
+ ClassDB::bind_method(D_METHOD("get_discarded_frames"), &AudioEffectCapture::get_discarded_frames);
+ ClassDB::bind_method(D_METHOD("get_buffer_length_frames"), &AudioEffectCapture::get_buffer_length_frames);
+ ClassDB::bind_method(D_METHOD("get_pushed_frames"), &AudioEffectCapture::get_pushed_frames);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_buffer_length", "get_buffer_length");
+}
+
+Ref<AudioEffectInstance> AudioEffectCapture::instance() {
+ if (!buffer_initialized) {
+ float target_buffer_size = AudioServer::get_singleton()->get_mix_rate() * buffer_length_seconds;
+ ERR_FAIL_COND_V(target_buffer_size <= 0 || target_buffer_size >= (1 << 27), Ref<AudioEffectInstance>());
+ buffer.resize(nearest_shift((int)target_buffer_size));
+ buffer_initialized = true;
+ }
+
+ clear_buffer();
+
+ Ref<AudioEffectCaptureInstance> ins;
+ ins.instance();
+ ins->base = Ref<AudioEffectCapture>(this);
+
+ return ins;
+}
+
+void AudioEffectCapture::set_buffer_length(float p_buffer_length_seconds) {
+ ERR_FAIL_COND(buffer_initialized);
+
+ buffer_length_seconds = p_buffer_length_seconds;
+}
+
+float AudioEffectCapture::get_buffer_length() {
+ return buffer_length_seconds;
+}
+
+int AudioEffectCapture::get_frames_available() const {
+ ERR_FAIL_COND_V(!buffer_initialized, 0);
+ return buffer.data_left();
+}
+
+int64_t AudioEffectCapture::get_discarded_frames() const {
+ return discarded_frames.get();
+}
+
+int AudioEffectCapture::get_buffer_length_frames() const {
+ ERR_FAIL_COND_V(!buffer_initialized, 0);
+ return buffer.size();
+}
+
+int64_t AudioEffectCapture::get_pushed_frames() const {
+ return pushed_frames.get();
+}
+
+void AudioEffectCaptureInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
+ RingBuffer<AudioFrame> &buffer = base->buffer;
+
+ for (int i = 0; i < p_frame_count; i++) {
+ p_dst_frames[i] = p_src_frames[i];
+ }
+
+ if (buffer.space_left() >= p_frame_count) {
+ // Add incoming audio frames to the IO ring buffer
+ int32_t ret = buffer.write(p_src_frames, p_frame_count);
+ ERR_FAIL_COND_MSG(ret != p_frame_count, "Failed to add data to effect capture ring buffer despite sufficient space.");
+ base->pushed_frames.add(p_frame_count);
+ } else {
+ base->discarded_frames.add(p_frame_count);
+ }
+}
+
+bool AudioEffectCaptureInstance::process_silence() const {
+ return true;
+}
diff --git a/modules/mono/editor/script_class_parser.h b/servers/audio/effects/audio_effect_capture.h
index deb6061191..81d4ed6b0f 100644
--- a/modules/mono/editor/script_class_parser.h
+++ b/servers/audio/effects/audio_effect_capture.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* script_class_parser.h */
+/* audio_effect_capture.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,81 +28,55 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SCRIPT_CLASS_PARSER_H
-#define SCRIPT_CLASS_PARSER_H
+#ifndef AUDIO_EFFECT_CAPTURE_H
+#define AUDIO_EFFECT_CAPTURE_H
-#include "core/string/ustring.h"
+#include "core/config/engine.h"
+#include "core/math/audio_frame.h"
+#include "core/object/reference.h"
#include "core/templates/vector.h"
-#include "core/variant/variant.h"
+#include "servers/audio/audio_effect.h"
+#include "servers/audio_server.h"
-class ScriptClassParser {
-public:
- struct NameDecl {
- enum Type {
- NAMESPACE_DECL,
- CLASS_DECL,
- STRUCT_DECL
- };
-
- String name;
- Type type = NAMESPACE_DECL;
- };
-
- struct ClassDecl {
- String name;
- String namespace_;
- Vector<String> base;
- bool nested = false;
- };
-
-private:
- String code;
- int idx = 0;
- int line = 0;
- String error_str;
- bool error = false;
- Variant value;
+class AudioEffectCapture;
- Vector<ClassDecl> classes;
+class AudioEffectCaptureInstance : public AudioEffectInstance {
+ GDCLASS(AudioEffectCaptureInstance, AudioEffectInstance);
+ friend class AudioEffectCapture;
+ Ref<AudioEffectCapture> base;
- enum Token {
- TK_BRACKET_OPEN,
- TK_BRACKET_CLOSE,
- TK_CURLY_BRACKET_OPEN,
- TK_CURLY_BRACKET_CLOSE,
- TK_PERIOD,
- TK_COLON,
- TK_COMMA,
- TK_SYMBOL,
- TK_IDENTIFIER,
- TK_STRING,
- TK_NUMBER,
- TK_OP_LESS,
- TK_OP_GREATER,
- TK_EOF,
- TK_ERROR,
- TK_MAX
- };
-
- static const char *token_names[TK_MAX];
- static String get_token_name(Token p_token);
+public:
+ virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) override;
+ virtual bool process_silence() const override;
+};
- Token get_token();
+class AudioEffectCapture : public AudioEffect {
+ GDCLASS(AudioEffectCapture, AudioEffect)
+ friend class AudioEffectCaptureInstance;
- Error _skip_generic_type_params();
+ RingBuffer<AudioFrame> buffer;
+ SafeNumeric<uint64_t> discarded_frames;
+ SafeNumeric<uint64_t> pushed_frames;
+ float buffer_length_seconds = 0.1f;
+ bool buffer_initialized = false;
- Error _parse_type_full_name(String &r_full_name);
- Error _parse_class_base(Vector<String> &r_base);
- Error _parse_type_constraints();
- Error _parse_namespace_name(String &r_name, int &r_curly_stack);
+protected:
+ static void _bind_methods();
public:
- Error parse(const String &p_code);
- Error parse_file(const String &p_filepath);
+ virtual Ref<AudioEffectInstance> instance() override;
+
+ void set_buffer_length(float p_buffer_length_seconds);
+ float get_buffer_length();
- String get_error();
+ bool can_get_buffer(int p_frames) const;
+ PackedVector2Array get_buffer(int p_len);
+ void clear_buffer();
- Vector<ClassDecl> get_classes();
+ int get_frames_available() const;
+ int64_t get_discarded_frames() const;
+ int get_buffer_length_frames() const;
+ int64_t get_pushed_frames() const;
};
-#endif // SCRIPT_CLASS_PARSER_H
+#endif // AUDIO_EFFECT_CAPTURE_H
diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp
index 2b530475f0..eb2268aa2e 100644
--- a/servers/audio/effects/audio_effect_chorus.cpp
+++ b/servers/audio/effects/audio_effect_chorus.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -84,7 +84,7 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A
if (v.cutoff == 0) {
continue;
}
- float auxlp = expf(-2.0 * Math_PI * v.cutoff / mix_rate);
+ float auxlp = expf(-Math_TAU * v.cutoff / mix_rate);
float c1 = 1.0 - auxlp;
float c2 = auxlp;
AudioFrame h = filter_h[vc];
@@ -104,7 +104,7 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A
float phase = (float)(local_cycles & AudioEffectChorus::CYCLES_MASK) / (float)(1 << AudioEffectChorus::CYCLES_FRAC);
- float wave_delay = sinf(phase * 2.0 * Math_PI) * max_depth_frames;
+ float wave_delay = sinf(phase * Math_TAU) * max_depth_frames;
int wave_delay_frames = lrint(floor(wave_delay));
float wave_delay_frac = wave_delay - (float)wave_delay_frames;
@@ -309,7 +309,7 @@ void AudioEffectChorus::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_dry", "amount"), &AudioEffectChorus::set_dry);
ClassDB::bind_method(D_METHOD("get_dry"), &AudioEffectChorus::get_dry);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "voice_count", PROPERTY_HINT_RANGE, "1,4,1"), "set_voice_count", "get_voice_count");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "voice_count", PROPERTY_HINT_RANGE, "1,4,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_voice_count", "get_voice_count");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dry", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dry", "get_dry");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wet", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_wet", "get_wet");
diff --git a/servers/audio/effects/audio_effect_chorus.h b/servers/audio/effects/audio_effect_chorus.h
index b32b300dfa..f5b023734a 100644
--- a/servers/audio/effects/audio_effect_chorus.h
+++ b/servers/audio/effects/audio_effect_chorus.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_compressor.cpp b/servers/audio/effects/audio_effect_compressor.cpp
index 4b0b4dabea..bb4a90f3d6 100644
--- a/servers/audio/effects/audio_effect_compressor.cpp
+++ b/servers/audio/effects/audio_effect_compressor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_compressor.h b/servers/audio/effects/audio_effect_compressor.h
index be187605c5..33c60680fc 100644
--- a/servers/audio/effects/audio_effect_compressor.h
+++ b/servers/audio/effects/audio_effect_compressor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp
index d6ab14be89..ba50eeb0a3 100644
--- a/servers/audio/effects/audio_effect_delay.cpp
+++ b/servers/audio/effects/audio_effect_delay.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -75,7 +75,7 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au
tap2_vol.r *= CLAMP(1.0 + base->tap_2_pan, 0, 1);
// feedback lowpass here
- float lpf_c = expf(-2.0 * Math_PI * base->feedback_lowpass / mix_rate); // 0 .. 10khz
+ float lpf_c = expf(-Math_TAU * base->feedback_lowpass / mix_rate); // 0 .. 10khz
float lpf_ic = 1.0 - lpf_c;
const AudioFrame *src = p_src_frames;
diff --git a/servers/audio/effects/audio_effect_delay.h b/servers/audio/effects/audio_effect_delay.h
index 3b7f2ea458..ff267d5023 100644
--- a/servers/audio/effects/audio_effect_delay.h
+++ b/servers/audio/effects/audio_effect_delay.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp
index dc5c2cc16f..06d51776a3 100644
--- a/servers/audio/effects/audio_effect_distortion.cpp
+++ b/servers/audio/effects/audio_effect_distortion.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,8 +36,8 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi
const float *src = (const float *)p_src_frames;
float *dst = (float *)p_dst_frames;
- //float lpf_c=expf(-2.0*Math_PI*keep_hf_hz.get()/(mix_rate*(float)OVERSAMPLE));
- float lpf_c = expf(-2.0 * Math_PI * base->keep_hf_hz / (AudioServer::get_singleton()->get_mix_rate()));
+ //float lpf_c=expf(-Math_TAU*keep_hf_hz.get()/(mix_rate*(float)OVERSAMPLE));
+ float lpf_c = expf(-Math_TAU * base->keep_hf_hz / (AudioServer::get_singleton()->get_mix_rate()));
float lpf_ic = 1.0 - lpf_c;
float drive_f = base->drive;
@@ -58,7 +58,8 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi
switch (base->mode) {
case AudioEffectDistortion::MODE_CLIP: {
- a = powf(a, 1.0001 - drive_f);
+ float a_sign = a < 0 ? -1.0f : 1.0f;
+ a = powf(abs(a), 1.0001 - drive_f) * a_sign;
if (a > 1.0) {
a = 1.0;
} else if (a < (-1.0)) {
diff --git a/servers/audio/effects/audio_effect_distortion.h b/servers/audio/effects/audio_effect_distortion.h
index 8149fc3f0a..9da800b79f 100644
--- a/servers/audio/effects/audio_effect_distortion.h
+++ b/servers/audio/effects/audio_effect_distortion.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_eq.cpp b/servers/audio/effects/audio_effect_eq.cpp
index ed4e7122b5..01ac605bd7 100644
--- a/servers/audio/effects/audio_effect_eq.cpp
+++ b/servers/audio/effects/audio_effect_eq.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_eq.h b/servers/audio/effects/audio_effect_eq.h
index 5a639f64d4..38c63a7d4f 100644
--- a/servers/audio/effects/audio_effect_eq.h
+++ b/servers/audio/effects/audio_effect_eq.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_filter.cpp b/servers/audio/effects/audio_effect_filter.cpp
index a5135ee1a6..c2d6074825 100644
--- a/servers/audio/effects/audio_effect_filter.cpp
+++ b/servers/audio/effects/audio_effect_filter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_filter.h b/servers/audio/effects/audio_effect_filter.h
index 16940173ba..9a48ccf70b 100644
--- a/servers/audio/effects/audio_effect_filter.h
+++ b/servers/audio/effects/audio_effect_filter.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_limiter.cpp b/servers/audio/effects/audio_effect_limiter.cpp
index 27f1aaf71f..1a4b01d947 100644
--- a/servers/audio/effects/audio_effect_limiter.cpp
+++ b/servers/audio/effects/audio_effect_limiter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_limiter.h b/servers/audio/effects/audio_effect_limiter.h
index 5204c42759..8f3092c0e2 100644
--- a/servers/audio/effects/audio_effect_limiter.h
+++ b/servers/audio/effects/audio_effect_limiter.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_panner.cpp b/servers/audio/effects/audio_effect_panner.cpp
index 32b7921d1f..238e979e13 100644
--- a/servers/audio/effects/audio_effect_panner.cpp
+++ b/servers/audio/effects/audio_effect_panner.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_panner.h b/servers/audio/effects/audio_effect_panner.h
index b4aa7a58b9..0938824c64 100644
--- a/servers/audio/effects/audio_effect_panner.h
+++ b/servers/audio/effects/audio_effect_panner.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp
index ffeaa7d25e..9b70f03a19 100644
--- a/servers/audio/effects/audio_effect_phaser.cpp
+++ b/servers/audio/effects/audio_effect_phaser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,13 +38,13 @@ void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFra
float dmin = base->range_min / (sampling_rate / 2.0);
float dmax = base->range_max / (sampling_rate / 2.0);
- float increment = 2.f * Math_PI * (base->rate / sampling_rate);
+ float increment = Math_TAU * (base->rate / sampling_rate);
for (int i = 0; i < p_frame_count; i++) {
phase += increment;
- while (phase >= Math_PI * 2.f) {
- phase -= Math_PI * 2.f;
+ while (phase >= Math_TAU) {
+ phase -= Math_TAU;
}
float d = dmin + (dmax - dmin) * ((sin(phase) + 1.f) / 2.f);
diff --git a/servers/audio/effects/audio_effect_phaser.h b/servers/audio/effects/audio_effect_phaser.h
index dbf014dbac..563927c678 100644
--- a/servers/audio/effects/audio_effect_phaser.h
+++ b/servers/audio/effects/audio_effect_phaser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index fdba1b59a3..2123fe8548 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h
index 0fa4de6b5b..18a9c33968 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.h
+++ b/servers/audio/effects/audio_effect_pitch_shift.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index 79388b2dc7..2015ede81f 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -118,7 +118,7 @@ void AudioEffectRecordInstance::init() {
#ifdef NO_THREADS
AudioServer::get_singleton()->add_update_callback(&AudioEffectRecordInstance::_update, this);
#else
- io_thread = Thread::create(_thread_callback, this);
+ io_thread.start(_thread_callback, this);
#endif
}
@@ -126,9 +126,7 @@ void AudioEffectRecordInstance::finish() {
#ifdef NO_THREADS
AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this);
#else
- if (thread_active) {
- Thread::wait_to_finish(io_thread);
- }
+ io_thread.wait_to_finish();
#endif
}
diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h
index 55080539d3..b97ec43946 100644
--- a/servers/audio/effects/audio_effect_record.h
+++ b/servers/audio/effects/audio_effect_record.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -48,7 +48,7 @@ class AudioEffectRecordInstance : public AudioEffectInstance {
Ref<AudioEffectRecord> base;
bool is_recording;
- Thread *io_thread;
+ Thread io_thread;
bool thread_active = false;
Vector<AudioFrame> ring_buffer;
diff --git a/servers/audio/effects/audio_effect_reverb.cpp b/servers/audio/effects/audio_effect_reverb.cpp
index f6465abfaf..b8d812680e 100644
--- a/servers/audio/effects/audio_effect_reverb.cpp
+++ b/servers/audio/effects/audio_effect_reverb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_reverb.h b/servers/audio/effects/audio_effect_reverb.h
index 3a1922bc1d..141ba48e29 100644
--- a/servers/audio/effects/audio_effect_reverb.h
+++ b/servers/audio/effects/audio_effect_reverb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
index 3f4f11ee8d..3f7ab74a74 100644
--- a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
+++ b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -110,10 +110,11 @@ void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames
while (p_frame_count) {
int to_fill = fft_size * 2 - temporal_fft_pos;
to_fill = MIN(to_fill, p_frame_count);
+ const double to_fill_step = Math_TAU / (double)fft_size;
float *fftw = temporal_fft.ptrw();
for (int i = 0; i < to_fill; i++) { //left and right buffers
- float window = -0.5 * Math::cos(2.0 * Math_PI * (double)temporal_fft_pos / (double)fft_size) + 0.5;
+ float window = -0.5 * Math::cos(to_fill_step * (double)temporal_fft_pos) + 0.5;
fftw[temporal_fft_pos * 2] = window * p_src_frames->l;
fftw[temporal_fft_pos * 2 + 1] = 0;
fftw[(temporal_fft_pos + fft_size * 2) * 2] = window * p_src_frames->r;
diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.h b/servers/audio/effects/audio_effect_spectrum_analyzer.h
index 0eacd43b57..fba276e2bb 100644
--- a/servers/audio/effects/audio_effect_spectrum_analyzer.h
+++ b/servers/audio/effects/audio_effect_spectrum_analyzer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_stereo_enhance.cpp b/servers/audio/effects/audio_effect_stereo_enhance.cpp
index 4f9bee83e4..dfdf154aa4 100644
--- a/servers/audio/effects/audio_effect_stereo_enhance.cpp
+++ b/servers/audio/effects/audio_effect_stereo_enhance.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_stereo_enhance.h b/servers/audio/effects/audio_effect_stereo_enhance.h
index 98ee18ba5a..f99256470b 100644
--- a/servers/audio/effects/audio_effect_stereo_enhance.h
+++ b/servers/audio/effects/audio_effect_stereo_enhance.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp
index aba04550db..d1a05ccf2a 100644
--- a/servers/audio/effects/audio_stream_generator.cpp
+++ b/servers/audio/effects/audio_stream_generator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_stream_generator.h b/servers/audio/effects/audio_stream_generator.h
index 49bda0fcf9..5d46771f4d 100644
--- a/servers/audio/effects/audio_stream_generator.h
+++ b/servers/audio/effects/audio_stream_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp
index 15abeea5f3..e0c3eb6d3a 100644
--- a/servers/audio/effects/eq.cpp
+++ b/servers/audio/effects/eq.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -89,8 +89,8 @@ void EQ::recalculate_band_coefficients() {
double frq_l = round(frq / pow(2.0, octave_size / 2.0));
double side_gain2 = POW2(Math_SQRT12);
- double th = 2.0 * Math_PI * frq / mix_rate;
- double th_l = 2.0 * Math_PI * frq_l / mix_rate;
+ double th = Math_TAU * frq / mix_rate;
+ double th_l = Math_TAU * frq_l / mix_rate;
double c2a = side_gain2 * POW2(cos(th)) - 2.0 * side_gain2 * cos(th_l) * cos(th) + side_gain2 - POW2(sin(th_l));
diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h
index c908c9c8fb..afd5bf5334 100644
--- a/servers/audio/effects/eq.h
+++ b/servers/audio/effects/eq.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp
index 1deb1499b5..7df2f99f67 100644
--- a/servers/audio/effects/reverb.cpp
+++ b/servers/audio/effects/reverb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -91,7 +91,7 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) {
}
if (params.hpf > 0) {
- float hpaux = expf(-2.0 * Math_PI * params.hpf * 6000 / params.mix_rate);
+ float hpaux = expf(-Math_TAU * params.hpf * 6000 / params.mix_rate);
float hp_a1 = (1.0 + hpaux) / 2.0;
float hp_a2 = -(1.0 + hpaux) / 2.0;
float hp_b1 = hpaux;
@@ -293,7 +293,7 @@ void Reverb::update_parameters() {
float auxdmp = params.damp / 2.0 + 0.5; //only half the range (0.5 .. 1.0 is enough)
auxdmp *= auxdmp;
- c.damp = expf(-2.0 * Math_PI * auxdmp * 10000 / params.mix_rate); // 0 .. 10khz
+ c.damp = expf(-Math_TAU * auxdmp * 10000 / params.mix_rate); // 0 .. 10khz
}
}
diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h
index 7dd88f9faf..e7ce55098d 100644
--- a/servers/audio/effects/reverb.h
+++ b/servers/audio/effects/reverb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index bea5e9e432..138cb6e1f8 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -71,13 +71,20 @@ void AudioDriver::update_mix_time(int p_frames) {
}
}
-double AudioDriver::get_time_since_last_mix() const {
- return (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0;
+double AudioDriver::get_time_since_last_mix() {
+ lock();
+ uint64_t last_mix_time = _last_mix_time;
+ unlock();
+ return (OS::get_singleton()->get_ticks_usec() - last_mix_time) / 1000000.0;
}
-double AudioDriver::get_time_to_next_mix() const {
- double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0;
- double mix_buffer = _last_mix_frames / (double)get_mix_rate();
+double AudioDriver::get_time_to_next_mix() {
+ lock();
+ uint64_t last_mix_time = _last_mix_time;
+ uint64_t last_mix_frames = _last_mix_frames;
+ unlock();
+ double total = (OS::get_singleton()->get_ticks_usec() - last_mix_time) / 1000000.0;
+ double mix_buffer = last_mix_frames / (double)get_mix_rate();
return mix_buffer - total;
}
@@ -181,10 +188,10 @@ int AudioDriverManager::get_driver_count() {
}
void AudioDriverManager::initialize(int p_driver) {
- GLOBAL_DEF_RST("audio/enable_audio_input", false);
- GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
- GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
- GLOBAL_DEF_RST("audio/output_latency.web", 50); // Safer default output_latency for web.
+ GLOBAL_DEF_RST("audio/driver/enable_input", false);
+ GLOBAL_DEF_RST("audio/driver/mix_rate", DEFAULT_MIX_RATE);
+ GLOBAL_DEF_RST("audio/driver/output_latency", DEFAULT_OUTPUT_LATENCY);
+ GLOBAL_DEF_RST("audio/driver/output_latency.web", 50); // Safer default output_latency for web.
int failed_driver = -1;
@@ -394,6 +401,7 @@ void AudioServer::_mix_step() {
for (int k = 0; k < bus->channels.size(); k++) {
if (!bus->channels[k].active) {
+ bus->channels.write[k].peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB);
continue;
}
@@ -427,7 +435,7 @@ void AudioServer::_mix_step() {
}
}
- bus->channels.write[k].peak_volume = AudioFrame(Math::linear2db(peak.l + 0.0000000001), Math::linear2db(peak.r + 0.0000000001));
+ bus->channels.write[k].peak_volume = AudioFrame(Math::linear2db(peak.l + AUDIO_PEAK_OFFSET), Math::linear2db(peak.r + AUDIO_PEAK_OFFSET));
if (!bus->channels[k].used) {
//see if any audio is contained, because channel was not used
@@ -931,9 +939,9 @@ void AudioServer::init_channels_and_buffers() {
}
void AudioServer::init() {
- channel_disable_threshold_db = GLOBAL_DEF_RST("audio/channel_disable_threshold_db", -60.0);
- channel_disable_frames = float(GLOBAL_DEF_RST("audio/channel_disable_time", 2.0)) * get_mix_rate();
- ProjectSettings::get_singleton()->set_custom_property_info("audio/channel_disable_time", PropertyInfo(Variant::FLOAT, "audio/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
+ channel_disable_threshold_db = GLOBAL_DEF_RST("audio/buses/channel_disable_threshold_db", -60.0);
+ channel_disable_frames = float(GLOBAL_DEF_RST("audio/buses/channel_disable_time", 2.0)) * get_mix_rate();
+ ProjectSettings::get_singleton()->set_custom_property_info("audio/buses/channel_disable_time", PropertyInfo(Variant::FLOAT, "audio/buses/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
buffer_size = 1024; //hardcoded for now
init_channels_and_buffers();
@@ -950,7 +958,7 @@ void AudioServer::init() {
set_edited(false); //avoid editors from thinking this was edited
#endif
- GLOBAL_DEF_RST("audio/video_delay_compensation_ms", 0);
+ GLOBAL_DEF_RST("audio/video/video_delay_compensation_ms", 0);
}
void AudioServer::update() {
@@ -1027,7 +1035,7 @@ void AudioServer::update() {
}
void AudioServer::load_default_bus_layout() {
- String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout");
+ String layout_path = ProjectSettings::get_singleton()->get("audio/buses/default_bus_layout");
if (ResourceLoader::exists(layout_path)) {
Ref<AudioBusLayout> default_layout = ResourceLoader::load(layout_path);
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 83377a5e9e..a1a373e1ca 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -70,8 +70,8 @@ protected:
#endif
public:
- double get_time_since_last_mix() const; //useful for video -> audio sync
- double get_time_to_next_mix() const;
+ double get_time_since_last_mix(); //useful for video -> audio sync
+ double get_time_to_next_mix();
enum SpeakerMode {
SPEAKER_MODE_STEREO,
@@ -199,7 +199,7 @@ private:
last_mix_with_audio = 0;
used = false;
active = false;
- peak_volume = AudioFrame(0, 0);
+ peak_volume = AudioFrame(AUDIO_MIN_PEAK_DB, AUDIO_MIN_PEAK_DB);
}
};
diff --git a/servers/camera/camera_feed.cpp b/servers/camera/camera_feed.cpp
index 41f44abae8..be812cf62d 100644
--- a/servers/camera/camera_feed.cpp
+++ b/servers/camera/camera_feed.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/camera/camera_feed.h b/servers/camera/camera_feed.h
index dca583c9de..fc02af4249 100644
--- a/servers/camera/camera_feed.h
+++ b/servers/camera/camera_feed.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/camera_server.cpp b/servers/camera_server.cpp
index 3caea6b7c3..b06f32417c 100644
--- a/servers/camera_server.cpp
+++ b/servers/camera_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/camera_server.h b/servers/camera_server.h
index e09b883eee..97aa8f74ba 100644
--- a/servers/camera_server.h
+++ b/servers/camera_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index e678c6919b..2fa333cc05 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -477,7 +477,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("enable_for_stealing_focus", "process_id"), &DisplayServer::enable_for_stealing_focus);
- ClassDB::bind_method(D_METHOD("native_video_play", "path", "volume", "audio_track", "subtitle_track"), &DisplayServer::native_video_play);
+ ClassDB::bind_method(D_METHOD("native_video_play", "path", "volume", "audio_track", "subtitle_track", "screen"), &DisplayServer::native_video_play);
ClassDB::bind_method(D_METHOD("native_video_is_playing"), &DisplayServer::native_video_is_playing);
ClassDB::bind_method(D_METHOD("native_video_stop"), &DisplayServer::native_video_stop);
ClassDB::bind_method(D_METHOD("native_video_pause"), &DisplayServer::native_video_pause);
@@ -504,6 +504,11 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_native_icon", "filename"), &DisplayServer::set_native_icon);
ClassDB::bind_method(D_METHOD("set_icon", "image"), &DisplayServer::set_icon);
+ ClassDB::bind_method(D_METHOD("tablet_get_driver_count"), &DisplayServer::tablet_get_driver_count);
+ ClassDB::bind_method(D_METHOD("tablet_get_driver_name", "idx"), &DisplayServer::tablet_get_driver_name);
+ ClassDB::bind_method(D_METHOD("tablet_get_current_driver"), &DisplayServer::tablet_get_current_driver);
+ ClassDB::bind_method(D_METHOD("tablet_set_current_driver", "name"), &DisplayServer::tablet_set_current_driver);
+
BIND_ENUM_CONSTANT(FEATURE_GLOBAL_MENU);
BIND_ENUM_CONSTANT(FEATURE_SUBWINDOWS);
BIND_ENUM_CONSTANT(FEATURE_TOUCHSCREEN);
diff --git a/servers/display_server.h b/servers/display_server.h
index 42b1562153..3aab572120 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -83,7 +83,7 @@ protected:
static DisplayServerCreate server_create_functions[MAX_SERVERS];
static int server_create_count;
- friend class RenderingServerDefault;
+ friend class RendererViewport;
virtual void _set_use_vsync(bool p_enable);
public:
@@ -340,6 +340,11 @@ public:
virtual String keyboard_get_layout_language(int p_index) const;
virtual String keyboard_get_layout_name(int p_index) const;
+ virtual int tablet_get_driver_count() const { return 1; };
+ virtual String tablet_get_driver_name(int p_driver) const { return "default"; };
+ virtual String tablet_get_current_driver() const { return "default"; };
+ virtual void tablet_set_current_driver(const String &p_driver){};
+
virtual void process_events() = 0;
virtual void force_process_and_drop_events();
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index b20f6865cd..fee74f3dbc 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,6 +80,18 @@ NavigationServer2D *NavigationServer2D::singleton = nullptr;
return NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3)); \
}
+#define FORWARD_5_R_C(CONV_R, FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, T_4, D_4, CONV_0, CONV_1, CONV_2, CONV_3, CONV_4) \
+ NavigationServer2D::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3, T_4 D_4) \
+ const { \
+ return CONV_R(NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3), CONV_4(D_4))); \
+ }
+
+#define FORWARD_5_C(FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, T_4, D_4, CONV_0, CONV_1, CONV_2, CONV_3, CONV_4) \
+ NavigationServer2D::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3, T_4 D_4) \
+ const { \
+ return NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3), CONV_4(D_4)); \
+ }
+
static RID rid_to_rid(const RID d) {
return d;
}
@@ -92,6 +104,10 @@ static int int_to_int(const int d) {
return d;
}
+static uint32_t uint32_to_uint32(const uint32_t d) {
+ return d;
+}
+
static real_t real_to_real(const real_t d) {
return d;
}
@@ -148,12 +164,14 @@ void NavigationServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("map_get_cell_size", "map"), &NavigationServer2D::map_get_cell_size);
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer2D::map_set_edge_connection_margin);
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer2D::map_get_edge_connection_margin);
- ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize"), &NavigationServer2D::map_get_path);
+ ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "layers"), &NavigationServer2D::map_get_path, DEFVAL(1));
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer2D::map_get_closest_point);
ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer2D::map_get_closest_point_owner);
ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer2D::region_create);
ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer2D::region_set_map);
+ ClassDB::bind_method(D_METHOD("region_set_layers", "region", "layers"), &NavigationServer2D::region_set_layers);
+ ClassDB::bind_method(D_METHOD("region_get_layers", "region"), &NavigationServer2D::region_get_layers);
ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer2D::region_set_transform);
ClassDB::bind_method(D_METHOD("region_set_navpoly", "region", "nav_poly"), &NavigationServer2D::region_set_navpoly);
@@ -193,14 +211,15 @@ real_t FORWARD_1_C(map_get_cell_size, RID, p_map, rid_to_rid);
void FORWARD_2_C(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin, rid_to_rid, real_to_real);
real_t FORWARD_1_C(map_get_edge_connection_margin, RID, p_map, rid_to_rid);
-Vector<Vector2> FORWARD_4_R_C(vector_v3_to_v2, map_get_path, RID, p_map, Vector2, p_origin, Vector2, p_destination, bool, p_optimize, rid_to_rid, v2_to_v3, v2_to_v3, bool_to_bool);
+Vector<Vector2> FORWARD_5_R_C(vector_v3_to_v2, map_get_path, RID, p_map, Vector2, p_origin, Vector2, p_destination, bool, p_optimize, uint32_t, p_layers, rid_to_rid, v2_to_v3, v2_to_v3, bool_to_bool, uint32_to_uint32);
Vector2 FORWARD_2_R_C(v3_to_v2, map_get_closest_point, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
RID FORWARD_2_C(map_get_closest_point_owner, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
RID FORWARD_0_C(region_create);
void FORWARD_2_C(region_set_map, RID, p_region, RID, p_map, rid_to_rid, rid_to_rid);
-
+void FORWARD_2_C(region_set_layers, RID, p_region, uint32_t, p_layers, rid_to_rid, uint32_to_uint32);
+uint32_t FORWARD_1_C(region_get_layers, RID, p_region, rid_to_rid);
void FORWARD_2_C(region_set_transform, RID, p_region, Transform2D, p_transform, rid_to_rid, trf2_to_trf3);
void NavigationServer2D::region_set_navpoly(RID p_region, Ref<NavigationPolygon> p_nav_mesh) const {
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index 895e41558a..46c8f6a71d 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -77,7 +77,7 @@ public:
virtual real_t map_get_edge_connection_margin(RID p_map) const;
/// Returns the navigation path to reach the destination from the origin.
- virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize) const;
+ virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_layers = 1) const;
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const;
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const;
@@ -88,6 +88,10 @@ public:
/// Set the map of this region.
virtual void region_set_map(RID p_region, RID p_map) const;
+ /// Set the region's layers
+ virtual void region_set_layers(RID p_region, uint32_t p_layers) const;
+ virtual uint32_t region_get_layers(RID p_region) const;
+
/// Set the global transformation of this region.
virtual void region_set_transform(RID p_region, Transform2D p_transform) const;
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index 8f9b5df589..d81ce70af6 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,7 @@ void NavigationServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("map_get_cell_size", "map"), &NavigationServer3D::map_get_cell_size);
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer3D::map_set_edge_connection_margin);
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer3D::map_get_edge_connection_margin);
- ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize"), &NavigationServer3D::map_get_path);
+ ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "layers"), &NavigationServer3D::map_get_path, DEFVAL(1));
ClassDB::bind_method(D_METHOD("map_get_closest_point_to_segment", "map", "start", "end", "use_collision"), &NavigationServer3D::map_get_closest_point_to_segment, DEFVAL(false));
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer3D::map_get_closest_point);
ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer3D::map_get_closest_point_normal);
@@ -54,6 +54,8 @@ void NavigationServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer3D::region_create);
ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer3D::region_set_map);
+ ClassDB::bind_method(D_METHOD("region_set_layers", "region", "layers"), &NavigationServer3D::region_set_layers);
+ ClassDB::bind_method(D_METHOD("region_get_layers", "region"), &NavigationServer3D::region_get_layers);
ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer3D::region_set_transform);
ClassDB::bind_method(D_METHOD("region_set_navmesh", "region", "nav_mesh"), &NavigationServer3D::region_set_navmesh);
ClassDB::bind_method(D_METHOD("region_bake_navmesh", "mesh", "node"), &NavigationServer3D::region_bake_navmesh);
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index e6421462b0..beed19d563 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -88,7 +88,7 @@ public:
virtual real_t map_get_edge_connection_margin(RID p_map) const = 0;
/// Returns the navigation path to reach the destination from the origin.
- virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) const = 0;
+ virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigable_layers = 1) const = 0;
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const = 0;
virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const = 0;
@@ -101,6 +101,10 @@ public:
/// Set the map of this region.
virtual void region_set_map(RID p_region, RID p_map) const = 0;
+ /// Set the region's layers
+ virtual void region_set_layers(RID p_region, uint32_t p_layers) const = 0;
+ virtual uint32_t region_get_layers(RID p_region) const = 0;
+
/// Set the global transformation of this region.
virtual void region_set_transform(RID p_region, Transform p_transform) const = 0;
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index 7485f31afc..6485c8d1e9 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -199,7 +199,7 @@ void Area2DSW::set_monitorable(bool p_monitorable) {
}
void Area2DSW::call_queries() {
- if (monitor_callback_id.is_valid() && !monitored_bodies.empty()) {
+ if (monitor_callback_id.is_valid() && !monitored_bodies.is_empty()) {
Variant res[5];
Variant *resptr[5];
for (int i = 0; i < 5; i++) {
@@ -234,7 +234,7 @@ void Area2DSW::call_queries() {
}
}
- if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) {
+ if (area_monitor_callback_id.is_valid() && !monitored_areas.is_empty()) {
Variant res[5];
Variant *resptr[5];
for (int i = 0; i < 5; i++) {
diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h
index d6b358a657..3bf603b30d 100644
--- a/servers/physics_2d/area_2d_sw.h
+++ b/servers/physics_2d/area_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index b1589b203f..21ad57e344 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/area_pair_2d_sw.h b/servers/physics_2d/area_pair_2d_sw.h
index 5e8670b464..4015aad5d1 100644
--- a/servers/physics_2d/area_pair_2d_sw.h
+++ b/servers/physics_2d/area_pair_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index a3eaff9c7f..d0636047b7 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 19e4b92a99..60d55ab8bd 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -164,7 +164,7 @@ public:
_FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
- _FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); }
+ _FORCE_INLINE_ bool can_report_contacts() const { return !contacts.is_empty(); }
_FORCE_INLINE_ void add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_normal, real_t p_depth, int p_local_shape, const Vector2 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector2 &p_collider_velocity_at_pos);
_FORCE_INLINE_ void add_exception(const RID &p_exception) { exceptions.insert(p_exception); }
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index bb6629becb..feced36a2b 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -288,21 +288,17 @@ bool BodyPair2DSW::setup(real_t p_step) {
if (A->is_shape_set_as_one_way_collision(shape_A)) {
Vector2 direction = xform_A.get_axis(1).normalized();
bool valid = false;
- if (B->get_linear_velocity().dot(direction) >= 0) {
- for (int i = 0; i < contact_count; i++) {
- Contact &c = contacts[i];
- if (!c.reused) {
- continue;
- }
- if (c.normal.dot(direction) > 0) { //greater (normal inverted)
- continue;
- }
-
- valid = true;
- break;
+ for (int i = 0; i < contact_count; i++) {
+ Contact &c = contacts[i];
+ if (!c.reused) {
+ continue;
}
+ if (c.normal.dot(direction) > -CMP_EPSILON) { //greater (normal inverted)
+ continue;
+ }
+ valid = true;
+ break;
}
-
if (!valid) {
collided = false;
oneway_disabled = true;
@@ -313,19 +309,16 @@ bool BodyPair2DSW::setup(real_t p_step) {
if (B->is_shape_set_as_one_way_collision(shape_B)) {
Vector2 direction = xform_B.get_axis(1).normalized();
bool valid = false;
- if (A->get_linear_velocity().dot(direction) >= 0) {
- for (int i = 0; i < contact_count; i++) {
- Contact &c = contacts[i];
- if (!c.reused) {
- continue;
- }
- if (c.normal.dot(direction) < 0) { //less (normal ok)
- continue;
- }
-
- valid = true;
- break;
+ for (int i = 0; i < contact_count; i++) {
+ Contact &c = contacts[i];
+ if (!c.reused) {
+ continue;
+ }
+ if (c.normal.dot(direction) < CMP_EPSILON) { //less (normal ok)
+ continue;
}
+ valid = true;
+ break;
}
if (!valid) {
collided = false;
@@ -409,7 +402,7 @@ bool BodyPair2DSW::setup(real_t p_step) {
kNormal += A->get_inv_inertia() * (c.rA.dot(c.rA) - rnA * rnA) + B->get_inv_inertia() * (c.rB.dot(c.rB) - rnB * rnB);
c.mass_normal = 1.0f / kNormal;
- Vector2 tangent = c.normal.tangent();
+ Vector2 tangent = c.normal.orthogonal();
real_t rtA = c.rA.dot(tangent);
real_t rtB = c.rB.dot(tangent);
real_t kTangent = A->get_inv_mass() + B->get_inv_mass();
@@ -469,7 +462,7 @@ void BodyPair2DSW::solve(real_t p_step) {
real_t vn = dv.dot(c.normal);
real_t vbn = dbv.dot(c.normal);
- Vector2 tangent = c.normal.tangent();
+ Vector2 tangent = c.normal.orthogonal();
real_t vt = dv.dot(tangent);
real_t jbn = (c.bias - vbn) * c.mass_normal;
diff --git a/servers/physics_2d/body_pair_2d_sw.h b/servers/physics_2d/body_pair_2d_sw.h
index ea4d55841a..31ab9b9017 100644
--- a/servers/physics_2d/body_pair_2d_sw.h
+++ b/servers/physics_2d/body_pair_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/broad_phase_2d_basic.cpp b/servers/physics_2d/broad_phase_2d_basic.cpp
index 3bdfc1a973..17424629a9 100644
--- a/servers/physics_2d/broad_phase_2d_basic.cpp
+++ b/servers/physics_2d/broad_phase_2d_basic.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/broad_phase_2d_basic.h b/servers/physics_2d/broad_phase_2d_basic.h
index 97e1c900b9..ca1db360fb 100644
--- a/servers/physics_2d/broad_phase_2d_basic.h
+++ b/servers/physics_2d/broad_phase_2d_basic.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index c8b3d193c9..6cfe6908d1 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -261,7 +261,7 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
}
}
- if (pb->object_set.empty() && pb->static_object_set.empty()) {
+ if (pb->object_set.is_empty() && pb->static_object_set.is_empty()) {
if (hash_table[idx] == pb) {
hash_table[idx] = pb->next;
} else {
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.h b/servers/physics_2d/broad_phase_2d_hash_grid.h
index 54994992c9..eb7c8879ac 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.h
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/broad_phase_2d_sw.cpp b/servers/physics_2d/broad_phase_2d_sw.cpp
index 5ba557e70a..7f0af48b1f 100644
--- a/servers/physics_2d/broad_phase_2d_sw.cpp
+++ b/servers/physics_2d/broad_phase_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h
index e4444cd180..d17ee6e2d6 100644
--- a/servers/physics_2d/broad_phase_2d_sw.h
+++ b/servers/physics_2d/broad_phase_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 6931d96fe4..7a2f312263 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index 36b7073a5c..2db3961f41 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -61,7 +61,7 @@ private:
Variant metadata;
bool disabled;
bool one_way_collision;
- float one_way_collision_margin;
+ real_t one_way_collision_margin;
Shape() {
disabled = false;
one_way_collision = false;
@@ -153,7 +153,7 @@ public:
return shapes[p_idx].disabled;
}
- _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision, float p_margin) {
+ _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision, real_t p_margin) {
CRASH_BAD_INDEX(p_idx, shapes.size());
shapes.write[p_idx].one_way_collision = p_one_way_collision;
shapes.write[p_idx].one_way_collision_margin = p_margin;
@@ -163,7 +163,7 @@ public:
return shapes[p_idx].one_way_collision;
}
- _FORCE_INLINE_ float get_shape_one_way_collision_margin(int p_idx) const {
+ _FORCE_INLINE_ real_t get_shape_one_way_collision_margin(int p_idx) const {
CRASH_BAD_INDEX(p_idx, shapes.size());
return shapes[p_idx].one_way_collision_margin;
}
diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp
index d993754fee..29242a554b 100644
--- a/servers/physics_2d/collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/collision_solver_2d_sat.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -88,7 +88,7 @@ _FORCE_INLINE_ static void _generate_contacts_edge_edge(const Vector2 *p_points_
#endif
Vector2 n = p_collector->normal;
- Vector2 t = n.tangent();
+ Vector2 t = n.orthogonal();
real_t dA = n.dot(p_points_A[0]);
real_t dB = n.dot(p_points_B[0]);
@@ -209,7 +209,7 @@ public:
if (!test_axis(na)) {
return false;
}
- if (!test_axis(na.tangent())) {
+ if (!test_axis(na.orthogonal())) {
return false;
}
}
@@ -219,7 +219,7 @@ public:
if (!test_axis(nb)) {
return false;
}
- if (!test_axis(nb.tangent())) {
+ if (!test_axis(nb.orthogonal())) {
return false;
}
}
@@ -450,7 +450,7 @@ static void _collision_segment_circle(const Shape2DSW *p_a, const Transform2D &p
//segment normal
if (!separator.test_axis(
- (p_transform_a.xform(segment_A->get_b()) - p_transform_a.xform(segment_A->get_a())).normalized().tangent())) {
+ (p_transform_a.xform(segment_A->get_b()) - p_transform_a.xform(segment_A->get_a())).normalized().orthogonal())) {
return;
}
diff --git a/servers/physics_2d/collision_solver_2d_sat.h b/servers/physics_2d/collision_solver_2d_sat.h
index 6bb485f561..49cc5176f9 100644
--- a/servers/physics_2d/collision_solver_2d_sat.h
+++ b/servers/physics_2d/collision_solver_2d_sat.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index 0e056691c7..5bd4d498c6 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/collision_solver_2d_sw.h b/servers/physics_2d/collision_solver_2d_sw.h
index f39cfee0a9..4f12ca9e88 100644
--- a/servers/physics_2d/collision_solver_2d_sw.h
+++ b/servers/physics_2d/collision_solver_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/constraint_2d_sw.h b/servers/physics_2d/constraint_2d_sw.h
index d8751f588e..49ae4dd848 100644
--- a/servers/physics_2d/constraint_2d_sw.h
+++ b/servers/physics_2d/constraint_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp
index 743f69d7d4..c7b556deba 100644
--- a/servers/physics_2d/joints_2d_sw.cpp
+++ b/servers/physics_2d/joints_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,6 +55,14 @@
* SOFTWARE.
*/
+void Joint2DSW::copy_settings_from(Joint2DSW *p_joint) {
+ set_self(p_joint->get_self());
+ set_max_force(p_joint->get_max_force());
+ set_bias(p_joint->get_bias());
+ set_max_bias(p_joint->get_max_bias());
+ disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies());
+}
+
static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const Vector2 &rB, const Vector2 &n) {
real_t value = 0;
@@ -75,9 +83,9 @@ static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const
static inline Vector2
relative_velocity(Body2DSW *a, Body2DSW *b, Vector2 rA, Vector2 rB) {
- Vector2 sum = a->get_linear_velocity() - rA.tangent() * a->get_angular_velocity();
+ Vector2 sum = a->get_linear_velocity() - rA.orthogonal() * a->get_angular_velocity();
if (b) {
- return (b->get_linear_velocity() - rB.tangent() * b->get_angular_velocity()) - sum;
+ return (b->get_linear_velocity() - rB.orthogonal() * b->get_angular_velocity()) - sum;
} else {
return -sum;
}
@@ -197,15 +205,6 @@ PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p
}
}
-PinJoint2DSW::~PinJoint2DSW() {
- if (A) {
- A->remove_constraint(this, 0);
- }
- if (B) {
- B->remove_constraint(this, 1);
- }
-}
-
//////////////////////////////////////////////
//////////////////////////////////////////////
//////////////////////////////////////////////
@@ -264,7 +263,7 @@ bool GrooveJoint2DSW::setup(real_t p_step) {
Space2DSW *space = A->get_space();
// calculate axis
- Vector2 n = -(tb - ta).tangent().normalized();
+ Vector2 n = -(tb - ta).orthogonal().normalized();
real_t d = ta.dot(n);
xf_normal = n;
@@ -282,7 +281,7 @@ bool GrooveJoint2DSW::setup(real_t p_step) {
} else {
clamp = 0.0f;
//joint->r1 = cpvsub(cpvadd(cpvmult(cpvperp(n), -td), cpvmult(n, d)), a->p);
- rA = ((-n.tangent() * -td) + n * d) - A->get_transform().get_origin();
+ rA = ((-n.orthogonal() * -td) + n * d) - A->get_transform().get_origin();
}
// Calculate mass tensor
@@ -332,17 +331,12 @@ GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_
A_groove_1 = A->get_inv_transform().xform(p_a_groove1);
A_groove_2 = A->get_inv_transform().xform(p_a_groove2);
B_anchor = B->get_inv_transform().xform(p_b_anchor);
- A_groove_normal = -(A_groove_2 - A_groove_1).normalized().tangent();
+ A_groove_normal = -(A_groove_2 - A_groove_1).normalized().orthogonal();
A->add_constraint(this, 0);
B->add_constraint(this, 1);
}
-GrooveJoint2DSW::~GrooveJoint2DSW() {
- A->remove_constraint(this, 0);
- B->remove_constraint(this, 1);
-}
-
//////////////////////////////////////////////
//////////////////////////////////////////////
//////////////////////////////////////////////
@@ -434,8 +428,3 @@ DampedSpringJoint2DSW::DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Ve
A->add_constraint(this, 0);
B->add_constraint(this, 1);
}
-
-DampedSpringJoint2DSW::~DampedSpringJoint2DSW() {
- A->remove_constraint(this, 0);
- B->remove_constraint(this, 1);
-}
diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/joints_2d_sw.h
index 3c8aab77c8..628de972ae 100644
--- a/servers/physics_2d/joints_2d_sw.h
+++ b/servers/physics_2d/joints_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,12 +49,26 @@ public:
_FORCE_INLINE_ void set_max_bias(real_t p_bias) { max_bias = p_bias; }
_FORCE_INLINE_ real_t get_max_bias() const { return max_bias; }
- virtual PhysicsServer2D::JointType get_type() const = 0;
+ virtual bool setup(real_t p_step) { return false; }
+ virtual void solve(real_t p_step) {}
+
+ void copy_settings_from(Joint2DSW *p_joint);
+
+ virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_MAX; }
Joint2DSW(Body2DSW **p_body_ptr = nullptr, int p_body_count = 0) :
Constraint2DSW(p_body_ptr, p_body_count) {
bias = 0;
max_force = max_bias = 3.40282e+38;
};
+
+ virtual ~Joint2DSW() {
+ for (int i = 0; i < get_body_count(); i++) {
+ Body2DSW *body = get_body_ptr()[i];
+ if (body) {
+ body->remove_constraint(this, i);
+ }
+ }
+ };
};
class PinJoint2DSW : public Joint2DSW {
@@ -76,7 +90,7 @@ class PinJoint2DSW : public Joint2DSW {
real_t softness;
public:
- virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_PIN; }
+ virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_PIN; }
virtual bool setup(real_t p_step);
virtual void solve(real_t p_step);
@@ -85,7 +99,6 @@ public:
real_t get_param(PhysicsServer2D::PinJointParam p_param) const;
PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p_body_b = nullptr);
- ~PinJoint2DSW();
};
class GrooveJoint2DSW : public Joint2DSW {
@@ -113,13 +126,12 @@ class GrooveJoint2DSW : public Joint2DSW {
bool correct;
public:
- virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_GROOVE; }
+ virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_GROOVE; }
virtual bool setup(real_t p_step);
virtual void solve(real_t p_step);
GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, Body2DSW *p_body_a, Body2DSW *p_body_b);
- ~GrooveJoint2DSW();
};
class DampedSpringJoint2DSW : public Joint2DSW {
@@ -146,7 +158,7 @@ class DampedSpringJoint2DSW : public Joint2DSW {
real_t v_coef;
public:
- virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_DAMPED_SPRING; }
+ virtual PhysicsServer2D::JointType get_type() const { return PhysicsServer2D::JOINT_TYPE_DAMPED_SPRING; }
virtual bool setup(real_t p_step);
virtual void solve(real_t p_step);
@@ -155,7 +167,6 @@ public:
real_t get_param(PhysicsServer2D::DampedSpringParam p_param) const;
DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, Body2DSW *p_body_a, Body2DSW *p_body_b);
- ~DampedSpringJoint2DSW();
};
#endif // JOINTS_2D_SW_H
diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp
index 223fd0114a..1040437ca7 100644
--- a/servers/physics_2d/physics_server_2d_sw.cpp
+++ b/servers/physics_2d/physics_server_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -149,24 +149,19 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &
return;
}
+ Vector2 rel_dir = (p_point_A - p_point_B);
+ real_t rel_length2 = rel_dir.length_squared();
if (cbk->valid_dir != Vector2()) {
- if (p_point_A.distance_squared_to(p_point_B) > cbk->valid_depth * cbk->valid_depth) {
- cbk->invalid_by_dir++;
- return;
- }
- Vector2 rel_dir = (p_point_A - p_point_B).normalized();
-
- if (cbk->valid_dir.dot(rel_dir) < Math_SQRT12) { //sqrt(2)/2.0 - 45 degrees
- cbk->invalid_by_dir++;
-
- /*
- print_line("A: "+p_point_A);
- print_line("B: "+p_point_B);
- print_line("discard too angled "+rtos(cbk->valid_dir.dot((p_point_A-p_point_B))));
- print_line("resnorm: "+(p_point_A-p_point_B).normalized());
- print_line("distance: "+rtos(p_point_A.distance_to(p_point_B)));
- */
- return;
+ if (cbk->valid_depth < 10e20) {
+ if (rel_length2 > cbk->valid_depth * cbk->valid_depth ||
+ (rel_length2 > CMP_EPSILON && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON)) {
+ cbk->invalid_by_dir++;
+ return;
+ }
+ } else {
+ if (rel_length2 > 0 && cbk->valid_dir.dot(rel_dir.normalized()) < CMP_EPSILON) {
+ return;
+ }
}
}
@@ -182,8 +177,7 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &
}
}
- real_t d = p_point_A.distance_squared_to(p_point_B);
- if (d < min_depth) {
+ if (rel_length2 < min_depth) {
return;
}
cbk->ptr[min_depth_idx * 2 + 0] = p_point_A;
@@ -673,7 +667,7 @@ void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo
body->set_shape_as_disabled(p_shape_idx, p_disabled);
}
-void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin) {
+void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
@@ -964,7 +958,7 @@ bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from,
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes);
}
-int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
+int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
@@ -991,6 +985,24 @@ PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) {
/* JOINT API */
+RID PhysicsServer2DSW::joint_create() {
+ Joint2DSW *joint = memnew(Joint2DSW);
+ RID joint_rid = joint_owner.make_rid(joint);
+ joint->set_self(joint_rid);
+ return joint_rid;
+}
+
+void PhysicsServer2DSW::joint_clear(RID p_joint) {
+ Joint2DSW *joint = joint_owner.getornull(p_joint);
+ if (joint->get_type() != JOINT_TYPE_MAX) {
+ Joint2DSW *empty_joint = memnew(Joint2DSW);
+ empty_joint->copy_settings_from(joint);
+
+ joint_owner.replace(p_joint, empty_joint);
+ memdelete(joint);
+ }
+}
+
void PhysicsServer2DSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) {
Joint2DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
@@ -1054,52 +1066,63 @@ bool PhysicsServer2DSW::joint_is_disabled_collisions_between_bodies(RID p_joint)
return joint->is_disabled_collisions_between_bodies();
}
-RID PhysicsServer2DSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b) {
+void PhysicsServer2DSW::joint_make_pin(RID p_joint, const Vector2 &p_pos, RID p_body_a, RID p_body_b) {
Body2DSW *A = body_owner.getornull(p_body_a);
- ERR_FAIL_COND_V(!A, RID());
+ ERR_FAIL_COND(!A);
Body2DSW *B = nullptr;
if (body_owner.owns(p_body_b)) {
B = body_owner.getornull(p_body_b);
- ERR_FAIL_COND_V(!B, RID());
+ ERR_FAIL_COND(!B);
}
+ Joint2DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
+
Joint2DSW *joint = memnew(PinJoint2DSW(p_pos, A, B));
- RID self = joint_owner.make_rid(joint);
- joint->set_self(self);
- return self;
+ joint_owner.replace(p_joint, joint);
+ joint->copy_settings_from(prev_joint);
+ memdelete(prev_joint);
}
-RID PhysicsServer2DSW::groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) {
+void PhysicsServer2DSW::joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) {
Body2DSW *A = body_owner.getornull(p_body_a);
- ERR_FAIL_COND_V(!A, RID());
+ ERR_FAIL_COND(!A);
Body2DSW *B = body_owner.getornull(p_body_b);
- ERR_FAIL_COND_V(!B, RID());
+ ERR_FAIL_COND(!B);
+
+ Joint2DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
Joint2DSW *joint = memnew(GrooveJoint2DSW(p_a_groove1, p_a_groove2, p_b_anchor, A, B));
- RID self = joint_owner.make_rid(joint);
- joint->set_self(self);
- return self;
+
+ joint_owner.replace(p_joint, joint);
+ joint->copy_settings_from(prev_joint);
+ memdelete(prev_joint);
}
-RID PhysicsServer2DSW::damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) {
+void PhysicsServer2DSW::joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) {
Body2DSW *A = body_owner.getornull(p_body_a);
- ERR_FAIL_COND_V(!A, RID());
+ ERR_FAIL_COND(!A);
Body2DSW *B = body_owner.getornull(p_body_b);
- ERR_FAIL_COND_V(!B, RID());
+ ERR_FAIL_COND(!B);
+
+ Joint2DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
Joint2DSW *joint = memnew(DampedSpringJoint2DSW(p_anchor_a, p_anchor_b, A, B));
- RID self = joint_owner.make_rid(joint);
- joint->set_self(self);
- return self;
+
+ joint_owner.replace(p_joint, joint);
+ joint->copy_settings_from(prev_joint);
+ memdelete(prev_joint);
}
void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {
Joint2DSW *j = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!j);
- ERR_FAIL_COND(j->get_type() != JOINT_PIN);
+ ERR_FAIL_COND(j->get_type() != JOINT_TYPE_PIN);
PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW *>(j);
pin_joint->set_param(p_param, p_value);
@@ -1108,7 +1131,7 @@ void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param,
real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
Joint2DSW *j = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!j, 0);
- ERR_FAIL_COND_V(j->get_type() != JOINT_PIN, 0);
+ ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_PIN, 0);
PinJoint2DSW *pin_joint = static_cast<PinJoint2DSW *>(j);
return pin_joint->get_param(p_param);
@@ -1117,7 +1140,7 @@ real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param
void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) {
Joint2DSW *j = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!j);
- ERR_FAIL_COND(j->get_type() != JOINT_DAMPED_SPRING);
+ ERR_FAIL_COND(j->get_type() != JOINT_TYPE_DAMPED_SPRING);
DampedSpringJoint2DSW *dsj = static_cast<DampedSpringJoint2DSW *>(j);
dsj->set_param(p_param, p_value);
@@ -1126,7 +1149,7 @@ void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringP
real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const {
Joint2DSW *j = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!j, 0);
- ERR_FAIL_COND_V(j->get_type() != JOINT_DAMPED_SPRING, 0);
+ ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_DAMPED_SPRING, 0);
DampedSpringJoint2DSW *dsj = static_cast<DampedSpringJoint2DSW *>(j);
return dsj->get_param(p_param);
@@ -1134,7 +1157,7 @@ real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSprin
PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const {
Joint2DSW *joint = joint_owner.getornull(p_joint);
- ERR_FAIL_COND_V(!joint, JOINT_PIN);
+ ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN);
return joint->get_type();
}
@@ -1331,7 +1354,7 @@ int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) {
PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = nullptr;
-PhysicsServer2DSW::PhysicsServer2DSW() {
+PhysicsServer2DSW::PhysicsServer2DSW(bool p_using_threads) {
singletonsw = this;
BroadPhase2DSW::create_func = BroadPhase2DHashGrid::_create;
//BroadPhase2DSW::create_func=BroadPhase2DBasic::_create;
@@ -1340,10 +1363,6 @@ PhysicsServer2DSW::PhysicsServer2DSW() {
island_count = 0;
active_objects = 0;
collision_pairs = 0;
-#ifdef NO_THREADS
- using_threads = false;
-#else
- using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2;
-#endif
+ using_threads = p_using_threads;
flushing_queries = false;
};
diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h
index 9bd9655e2c..65c5df0fce 100644
--- a/servers/physics_2d/physics_server_2d_sw.h
+++ b/servers/physics_2d/physics_server_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -61,11 +61,11 @@ class PhysicsServer2DSW : public PhysicsServer2D {
PhysicsDirectBodyState2DSW *direct_state;
- mutable RID_PtrOwner<Shape2DSW> shape_owner;
- mutable RID_PtrOwner<Space2DSW> space_owner;
- mutable RID_PtrOwner<Area2DSW> area_owner;
- mutable RID_PtrOwner<Body2DSW> body_owner;
- mutable RID_PtrOwner<Joint2DSW> joint_owner;
+ mutable RID_PtrOwner<Shape2DSW, true> shape_owner;
+ mutable RID_PtrOwner<Space2DSW, true> space_owner;
+ mutable RID_PtrOwner<Area2DSW, true> area_owner;
+ mutable RID_PtrOwner<Body2DSW, true> body_owner;
+ mutable RID_PtrOwner<Joint2DSW, true> joint_owner;
static PhysicsServer2DSW *singletonsw;
@@ -191,7 +191,7 @@ public:
virtual void body_clear_shapes(RID p_body) override;
virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) override;
- virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin) override;
+ virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) override;
virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id) override;
virtual ObjectID body_get_object_instance_id(RID p_body) const override;
@@ -248,22 +248,27 @@ public:
virtual void body_set_pickable(RID p_body, bool p_pickable) override;
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override;
- virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) override;
+ virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override;
// this function only works on physics process, errors and returns null otherwise
virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override;
/* JOINT API */
+ virtual RID joint_create() override;
+
+ virtual void joint_clear(RID p_joint) override;
+
virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value) override;
virtual real_t joint_get_param(RID p_joint, JointParam p_param) const override;
virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disabled) override;
virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const override;
- virtual RID pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b = RID()) override;
- virtual RID groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) override;
- virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) override;
+ virtual void joint_make_pin(RID p_joint, const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) override;
+ virtual void joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) override;
+ virtual void joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) override;
+
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override;
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override;
virtual void damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) override;
@@ -287,7 +292,7 @@ public:
int get_process_info(ProcessInfo p_info) override;
- PhysicsServer2DSW();
+ PhysicsServer2DSW(bool p_using_threads = false);
~PhysicsServer2DSW() {}
};
diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_2d/physics_server_2d_wrap_mt.cpp
index 49c38c6ce0..790c87cc44 100644
--- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp
+++ b/servers/physics_2d/physics_server_2d_wrap_mt.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,7 +33,7 @@
#include "core/os/os.h"
void PhysicsServer2DWrapMT::thread_exit() {
- exit = true;
+ exit.set();
}
void PhysicsServer2DWrapMT::thread_step(real_t p_delta) {
@@ -52,9 +52,9 @@ void PhysicsServer2DWrapMT::thread_loop() {
physics_2d_server->init();
- exit = false;
- step_thread_up = true;
- while (!exit) {
+ exit.clear();
+ step_thread_up.set();
+ while (!exit.is_set()) {
// flush commands one by one, until exit is requested
command_queue.wait_and_flush_one();
}
@@ -76,7 +76,7 @@ void PhysicsServer2DWrapMT::step(real_t p_step) {
}
void PhysicsServer2DWrapMT::sync() {
- if (thread) {
+ if (create_thread) {
if (first_frame) {
first_frame = false;
} else {
@@ -97,8 +97,8 @@ void PhysicsServer2DWrapMT::end_sync() {
void PhysicsServer2DWrapMT::init() {
if (create_thread) {
//OS::get_singleton()->release_rendering_thread();
- thread = Thread::create(_thread_callback, this);
- while (!step_thread_up) {
+ thread.start(_thread_callback, this);
+ while (!step_thread_up.is_set()) {
OS::get_singleton()->delay_usec(1000);
}
} else {
@@ -107,37 +107,19 @@ void PhysicsServer2DWrapMT::init() {
}
void PhysicsServer2DWrapMT::finish() {
- if (thread) {
+ if (thread.is_started()) {
command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit);
- Thread::wait_to_finish(thread);
- memdelete(thread);
-
- thread = nullptr;
+ thread.wait_to_finish();
} else {
physics_2d_server->finish();
}
-
- line_shape_free_cached_ids();
- ray_shape_free_cached_ids();
- segment_shape_free_cached_ids();
- circle_shape_free_cached_ids();
- rectangle_shape_free_cached_ids();
- capsule_shape_free_cached_ids();
- convex_polygon_shape_free_cached_ids();
- concave_polygon_shape_free_cached_ids();
-
- space_free_cached_ids();
- area_free_cached_ids();
- body_free_cached_ids();
}
PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) :
command_queue(p_create_thread) {
physics_2d_server = p_contained;
create_thread = p_create_thread;
- thread = nullptr;
step_pending = 0;
- step_thread_up = false;
pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h
index 1269cadd33..3577f706de 100644
--- a/servers/physics_2d/physics_server_2d_wrap_mt.h
+++ b/servers/physics_2d/physics_server_2d_wrap_mt.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,6 +34,7 @@
#include "core/config/project_settings.h"
#include "core/os/thread.h"
#include "core/templates/command_queue_mt.h"
+#include "core/templates/safe_refcount.h"
#include "servers/physics_server_2d.h"
#ifdef DEBUG_SYNC
@@ -52,9 +53,9 @@ class PhysicsServer2DWrapMT : public PhysicsServer2D {
Thread::ID server_thread;
Thread::ID main_thread;
- volatile bool exit;
- Thread *thread;
- volatile bool step_thread_up;
+ SafeFlag exit;
+ Thread thread;
+ SafeFlag step_thread_up;
bool create_thread;
Semaphore step_sem;
@@ -73,6 +74,8 @@ public:
#define ServerName PhysicsServer2D
#define ServerNameWrapMT PhysicsServer2DWrapMT
#define server_name physics_2d_server
+#define WRITE_ACTION
+
#include "servers/server_wrap_mt_common.h"
//FUNC1RID(shape,ShapeType); todo fix
@@ -93,7 +96,7 @@ public:
FUNC1RC(real_t, shape_get_custom_solver_bias, RID);
//these work well, but should be used from the main thread only
- bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) {
+ bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) override {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
return physics_2d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count);
}
@@ -108,18 +111,18 @@ public:
FUNC2RC(real_t, space_get_param, RID, SpaceParameter);
// this function only works on physics process, errors and returns null otherwise
- PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) {
+ PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) override {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
return physics_2d_server->space_get_direct_state(p_space);
}
FUNC2(space_set_debug_contacts, RID, int);
- virtual Vector<Vector2> space_get_contacts(RID p_space) const {
+ virtual Vector<Vector2> space_get_contacts(RID p_space) const override {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector2>());
return physics_2d_server->space_get_contacts(p_space);
}
- virtual int space_get_contact_count(RID p_space) const {
+ virtual int space_get_contact_count(RID p_space) const override {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0);
return physics_2d_server->space_get_contact_count(p_space);
}
@@ -189,7 +192,7 @@ public:
FUNC2RC(RID, body_get_shape, RID, int);
FUNC3(body_set_shape_disabled, RID, int, bool);
- FUNC4(body_set_shape_as_one_way_collision, RID, int, bool, float);
+ FUNC4(body_set_shape_as_one_way_collision, RID, int, bool, real_t);
FUNC2(body_remove_shape, RID, int);
FUNC1(body_clear_shapes, RID);
@@ -244,30 +247,34 @@ public:
FUNC4(body_set_force_integration_callback, RID, Object *, const StringName &, const Variant &);
- bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) {
+ bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) override {
return physics_2d_server->body_collide_shape(p_body, p_body_shape, p_shape, p_shape_xform, p_motion, r_results, p_result_max, r_result_count);
}
FUNC2(body_set_pickable, RID, bool);
- bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) {
+ bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes);
}
- int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) {
+ int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
}
// this function only works on physics process, errors and returns null otherwise
- PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) {
+ PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) override {
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
return physics_2d_server->body_get_direct_state(p_body);
}
/* JOINT API */
+ FUNCRID(joint)
+
+ FUNC1(joint_clear, RID)
+
FUNC3(joint_set_param, RID, JointParam, real_t);
FUNC2RC(real_t, joint_get_param, RID, JointParam);
@@ -280,9 +287,9 @@ public:
//TODO need to convert this to FUNCRID, but it's a hassle..
- FUNC3R(RID, pin_joint_create, const Vector2 &, RID, RID);
- FUNC5R(RID, groove_joint_create, const Vector2 &, const Vector2 &, const Vector2 &, RID, RID);
- FUNC4R(RID, damped_spring_joint_create, const Vector2 &, const Vector2 &, RID, RID);
+ FUNC4(joint_make_pin, RID, const Vector2 &, RID, RID);
+ FUNC6(joint_make_groove, RID, const Vector2 &, const Vector2 &, const Vector2 &, RID, RID);
+ FUNC5(joint_make_damped_spring, RID, const Vector2 &, const Vector2 &, RID, RID);
FUNC3(pin_joint_set_param, RID, PinJointParam, real_t);
FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam);
@@ -297,43 +304,28 @@ public:
FUNC1(free, RID);
FUNC1(set_active, bool);
- virtual void init();
- virtual void step(real_t p_step);
- virtual void sync();
- virtual void end_sync();
- virtual void flush_queries();
- virtual void finish();
+ virtual void init() override;
+ virtual void step(real_t p_step) override;
+ virtual void sync() override;
+ virtual void end_sync() override;
+ virtual void flush_queries() override;
+ virtual void finish() override;
- virtual bool is_flushing_queries() const {
+ virtual bool is_flushing_queries() const override {
return physics_2d_server->is_flushing_queries();
}
- int get_process_info(ProcessInfo p_info) {
+ int get_process_info(ProcessInfo p_info) override {
return physics_2d_server->get_process_info(p_info);
}
PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread);
~PhysicsServer2DWrapMT();
- template <class T>
- static PhysicsServer2D *init_server() {
-#ifdef NO_THREADS
- return memnew(T); // Always single unsafe when no threads are available.
-#else
- int tm = GLOBAL_DEF("physics/2d/thread_model", 1);
- if (tm == 0) { // single unsafe
- return memnew(T);
- } else if (tm == 1) { // single safe
- return memnew(PhysicsServer2DWrapMT(memnew(T), false));
- } else { // multi threaded
- return memnew(PhysicsServer2DWrapMT(memnew(T), true));
- }
-#endif
- }
-
#undef ServerNameWrapMT
#undef ServerName
#undef server_name
+#undef WRITE_ACTION
};
#ifdef DEBUG_SYNC
diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp
index afb1112fc0..6e7e802a8b 100644
--- a/servers/physics_2d/shape_2d_sw.cpp
+++ b/servers/physics_2d/shape_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -228,7 +228,7 @@ void SegmentShape2DSW::set_data(const Variant &p_data) {
Rect2 r = p_data;
a = r.position;
b = r.size;
- n = (b - a).tangent();
+ n = (b - a).orthogonal();
Rect2 aabb;
aabb.position = a;
@@ -339,10 +339,10 @@ void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_suppor
}
bool RectangleShape2DSW::contains_point(const Vector2 &p_point) const {
- float x = p_point.x;
- float y = p_point.y;
- float edge_x = half_extents.x;
- float edge_y = half_extents.y;
+ real_t x = p_point.x;
+ real_t y = p_point.y;
+ real_t edge_x = half_extents.x;
+ real_t edge_y = half_extents.y;
return (x >= -edge_x) && (x < edge_x) && (y >= -edge_y) && (y < edge_y);
}
@@ -590,7 +590,11 @@ real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2
}
void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
+#ifdef REAL_T_IS_DOUBLE
+ ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT64_ARRAY);
+#else
ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY);
+#endif
if (points) {
memdelete_arr(points);
@@ -612,7 +616,7 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
for (int i = 0; i < point_count; i++) {
Vector2 p = points[i].pos;
Vector2 pn = points[(i + 1) % point_count].pos;
- points[i].normal = (pn - p).tangent().normalized();
+ points[i].normal = (pn - p).orthogonal().normalized();
}
} else {
Vector<real_t> dvr = p_data;
@@ -740,7 +744,7 @@ bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Ve
if (nd < d) {
d = nd;
r_point = res;
- r_normal = (b - a).tangent().normalized();
+ r_normal = (b - a).orthogonal().normalized();
inters = true;
}
}
@@ -829,7 +833,11 @@ int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) {
}
void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
+#ifdef REAL_T_IS_DOUBLE
+ ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT64_ARRAY);
+#else
ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY);
+#endif
Rect2 aabb;
@@ -960,7 +968,7 @@ void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callbac
Vector2 a = pointptr[s.points[0]];
Vector2 b = pointptr[s.points[1]];
- SegmentShape2DSW ss(a, b, (b - a).tangent().normalized());
+ SegmentShape2DSW ss(a, b, (b - a).orthogonal().normalized());
p_callback(p_userdata, &ss);
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h
index eca284f7a4..ee2730ebb5 100644
--- a/servers/physics_2d/shape_2d_sw.h
+++ b/servers/physics_2d/shape_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -237,7 +237,7 @@ public:
virtual PhysicsServer2D::ShapeType get_type() const { return PhysicsServer2D::SHAPE_SEGMENT; }
_FORCE_INLINE_ Vector2 get_xformed_normal(const Transform2D &p_xform) const {
- return (p_xform.xform(b) - p_xform.xform(a)).normalized().tangent();
+ return (p_xform.xform(b) - p_xform.xform(a)).normalized().orthogonal();
}
virtual void project_rangev(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal, p_transform, r_min, r_max); }
virtual void get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const;
@@ -431,7 +431,7 @@ public:
Vector2 a = points[p_idx].pos;
p_idx++;
Vector2 b = points[p_idx == point_count ? 0 : p_idx].pos;
- return (p_xform.xform(b) - p_xform.xform(a)).normalized().tangent();
+ return (p_xform.xform(b) - p_xform.xform(a)).normalized().orthogonal();
}
virtual PhysicsServer2D::ShapeType get_type() const { return PhysicsServer2D::SHAPE_CONVEX_POLYGON; }
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index edadcabe0b..4f12248c3e 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -84,6 +84,10 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S
int shape_idx = space->intersection_query_subindex_results[i];
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
Shape2DSW *shape = col_obj->get_shape(shape_idx);
Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point);
@@ -229,6 +233,10 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) {
continue;
}
@@ -272,15 +280,19 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
//test initial overlap, does it collide if going all the way?
if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) {
continue;
}
- //test initial overlap
+ //test initial overlap, ignore objects it's inside of.
if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) {
- return false;
+ continue;
}
//just do kinematic solving
@@ -346,12 +358,17 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D &
}
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
- int shape_idx = space->intersection_query_subindex_results[i];
if (p_exclude.has(col_obj->get_self())) {
continue;
}
+ int shape_idx = space->intersection_query_subindex_results[i];
+
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
cbk.valid_dir = Vector2();
cbk.valid_depth = 0;
@@ -383,15 +400,6 @@ struct _RestCallbackData2D {
static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) {
_RestCallbackData2D *rd = (_RestCallbackData2D *)p_userdata;
- if (rd->valid_dir != Vector2()) {
- if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth) {
- return;
- }
- if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25) {
- return;
- }
- }
-
Vector2 contact_rel = p_point_B - p_point_A;
real_t len = contact_rel.length();
@@ -403,9 +411,21 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
return;
}
+ Vector2 normal = contact_rel / len;
+
+ if (rd->valid_dir != Vector2()) {
+ if (len > rd->valid_depth) {
+ return;
+ }
+
+ if (rd->valid_dir.dot(normal) > -CMP_EPSILON) {
+ return;
+ }
+ }
+
rd->best_len = len;
rd->best_contact = p_point_B;
- rd->best_normal = contact_rel / len;
+ rd->best_normal = normal;
rd->best_object = rd->object;
rd->best_shape = rd->shape;
rd->best_local_shape = rd->local_shape;
@@ -433,14 +453,18 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh
}
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
- int shape_idx = space->intersection_query_subindex_results[i];
if (p_exclude.has(col_obj->get_self())) {
continue;
}
+ int shape_idx = space->intersection_query_subindex_results[i];
+
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
rcd.valid_dir = Vector2();
- rcd.valid_depth = 0;
rcd.object = col_obj;
rcd.shape = shape_idx;
rcd.local_shape = 0;
@@ -643,9 +667,9 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
Vector2 a = sr[k * 2 + 0];
Vector2 b = sr[k * 2 + 1];
- recover_motion += (b - a) * 0.4;
+ recover_motion += (b - a) / cbk.amount;
- float depth = a.distance_to(b);
+ real_t depth = a.distance_to(b);
if (depth > result.collision_depth) {
result.collision_depth = depth;
result.collision_point = b;
@@ -740,10 +764,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs];
int excluded_shape_pair_count = 0;
- float separation_margin = MIN(p_margin, MAX(0.0, p_motion.length() - CMP_EPSILON)); //don't separate by more than the intended motion
+ real_t motion_length = p_motion.length();
+ Vector2 motion_normal = p_motion / motion_length;
Transform2D body_transform = p_from;
+ bool recovered = false;
+
{
//STEP 1, FREE BODY IF STUCK
@@ -794,7 +821,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
- float owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
+ real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
cbk.valid_depth = MAX(owc_margin, p_margin); //user specified, but never less than actual margin or it won't work
cbk.invalid_by_dir = 0;
@@ -805,7 +832,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
Vector2 lv = b->get_linear_velocity();
//compute displacement from linear velocity
Vector2 motion = lv * PhysicsDirectBodyState2DSW::singleton->step;
- float motion_len = motion.length();
+ real_t motion_len = motion.length();
motion.normalize();
cbk.valid_depth += motion_len * MAX(motion.dot(-cbk.valid_dir), 0.0);
}
@@ -820,7 +847,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
bool did_collide = false;
Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
- if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, separation_margin)) {
+ if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_margin)) {
did_collide = cbk.passed > current_passed; //more passed, so collision actually existed
}
@@ -846,11 +873,20 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
Vector2 recover_motion;
-
for (int i = 0; i < cbk.amount; i++) {
Vector2 a = sr[i * 2 + 0];
Vector2 b = sr[i * 2 + 1];
- recover_motion += (b - a) * 0.4;
+
+ // Compute plane on b towards a.
+ Vector2 n = (a - b).normalized();
+ real_t d = n.dot(b);
+
+ // Compute depth on recovered motion.
+ real_t depth = n.dot(a + recover_motion) - d;
+ if (depth > 0.0) {
+ // Only recover if there is penetration.
+ recover_motion -= n * depth * 0.4;
+ }
}
if (recover_motion == Vector2()) {
@@ -858,6 +894,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
break;
}
+ recovered = true;
+
body_transform.elements[2] += recover_motion;
body_aabb.position += recover_motion;
@@ -930,7 +968,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
//test initial overlap
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) {
if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) {
- continue;
+ Vector2 direction = col_obj_shape_xform.get_axis(1).normalized();
+ if (motion_normal.dot(direction) < 0) {
+ continue;
+ }
}
stuck = true;
@@ -940,13 +981,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
//just do kinematic solving
real_t low = 0;
real_t hi = 1;
- Vector2 mnormal = p_motion.normalized();
for (int k = 0; k < 8; k++) { //steps should be customizable..
real_t ofs = (low + hi) * 0.5;
- Vector2 sep = mnormal; //important optimization for this to work fast enough
+ Vector2 sep = motion_normal; //important optimization for this to work fast enough
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0);
if (collided) {
@@ -967,7 +1007,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
cbk.valid_depth = 10e20;
- Vector2 sep = mnormal; //important optimization for this to work fast enough
+ Vector2 sep = motion_normal; //important optimization for this to work fast enough
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_shape_xform, Vector2(), PhysicsServer2DSW::_shape_col_cbk, &cbk, &sep, 0);
if (!collided || cbk.amount == 0) {
continue;
@@ -998,11 +1038,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
bool collided = false;
- if (safe >= 1) {
- best_shape = -1; //no best shape with cast, reset to -1
- }
- {
+ if (recovered || (safe < 1)) {
+ if (safe >= 1) {
+ best_shape = -1; //no best shape with cast, reset to -1
+ }
+
//it collided, let's get the rest info in unsafe advance
Transform2D ugt = body_transform;
ugt.elements[2] += p_motion * unsafe;
@@ -1011,9 +1052,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
rcd.best_len = 0;
rcd.best_object = nullptr;
rcd.best_shape = 0;
- rcd.min_allowed_depth = test_motion_min_contact_depth;
- //optimization
+ // Allowed depth can't be lower than motion length, in order to handle contacts at low speed.
+ rcd.min_allowed_depth = MIN(motion_length, test_motion_min_contact_depth);
+
int from_shape = best_shape != -1 ? best_shape : 0;
int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count();
@@ -1061,7 +1103,22 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
rcd.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
- rcd.valid_depth = 10e20;
+
+ real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
+ rcd.valid_depth = MAX(owc_margin, p_margin); //user specified, but never less than actual margin or it won't work
+
+ if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
+ const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
+ if (b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_RIGID) {
+ //fix for moving platforms (kinematic and dynamic), margin is increased by how much it moved in the given direction
+ Vector2 lv = b->get_linear_velocity();
+ //compute displacement from linear velocity
+ Vector2 motion = lv * PhysicsDirectBodyState2DSW::singleton->step;
+ real_t motion_len = motion.length();
+ motion.normalize();
+ rcd.valid_depth += motion_len * MAX(motion.dot(-rcd.valid_dir), 0.0);
+ }
+ }
} else {
rcd.valid_dir = Vector2();
rcd.valid_depth = 0;
@@ -1331,7 +1388,7 @@ Space2DSW::Space2DSW() {
constraint_bias = 0.2;
body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_linear", 2.0);
- body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI));
+ body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", Math::deg2rad(8.0));
body_time_to_sleep = GLOBAL_DEF("physics/2d/time_before_sleep", 0.5);
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/2d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 93b62e0ba4..4d737d622f 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -187,7 +187,7 @@ public:
int test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, PhysicsServer2D::SeparationResult *r_results, int p_result_max, real_t p_margin);
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
- _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); }
+ _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.is_empty(); }
_FORCE_INLINE_ void add_debug_contact(const Vector2 &p_contact) {
if (contact_debug_count < contact_debug.size()) {
contact_debug.write[contact_debug_count++] = p_contact;
diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp
index 56b31a884d..6613d19729 100644
--- a/servers/physics_2d/step_2d_sw.cpp
+++ b/servers/physics_2d/step_2d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/step_2d_sw.h b/servers/physics_2d/step_2d_sw.h
index c1b2d01fb4..83b9130608 100644
--- a/servers/physics_2d/step_2d_sw.h
+++ b/servers/physics_2d/step_2d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/area_3d_sw.cpp b/servers/physics_3d/area_3d_sw.cpp
index 571f1435de..b6c5b3003c 100644
--- a/servers/physics_3d/area_3d_sw.cpp
+++ b/servers/physics_3d/area_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -199,7 +199,7 @@ void Area3DSW::set_monitorable(bool p_monitorable) {
}
void Area3DSW::call_queries() {
- if (monitor_callback_id.is_valid() && !monitored_bodies.empty()) {
+ if (monitor_callback_id.is_valid() && !monitored_bodies.is_empty()) {
Variant res[5];
Variant *resptr[5];
for (int i = 0; i < 5; i++) {
@@ -234,7 +234,7 @@ void Area3DSW::call_queries() {
}
}
- if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) {
+ if (area_monitor_callback_id.is_valid() && !monitored_areas.is_empty()) {
Variant res[5];
Variant *resptr[5];
for (int i = 0; i < 5; i++) {
diff --git a/servers/physics_3d/area_3d_sw.h b/servers/physics_3d/area_3d_sw.h
index a2efe6af51..8a0a1e963b 100644
--- a/servers/physics_3d/area_3d_sw.h
+++ b/servers/physics_3d/area_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/area_pair_3d_sw.cpp b/servers/physics_3d/area_pair_3d_sw.cpp
index a5fb20fe2b..4de5f1ba47 100644
--- a/servers/physics_3d/area_pair_3d_sw.cpp
+++ b/servers/physics_3d/area_pair_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/area_pair_3d_sw.h b/servers/physics_3d/area_pair_3d_sw.h
index 992d4747b9..fbdaa25cbb 100644
--- a/servers/physics_3d/area_pair_3d_sw.h
+++ b/servers/physics_3d/area_pair_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/body_3d_sw.cpp b/servers/physics_3d/body_3d_sw.cpp
index 841e593ba3..9eff14bbeb 100644
--- a/servers/physics_3d/body_3d_sw.cpp
+++ b/servers/physics_3d/body_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -51,18 +51,18 @@ void Body3DSW::_update_transform_dependant() {
}
void Body3DSW::update_inertias() {
- //update shapes and motions
+ // Update shapes and motions.
switch (mode) {
case PhysicsServer3D::BODY_MODE_RIGID: {
- //update tensor for all shapes, not the best way but should be somehow OK. (inspired from bullet)
+ // Update tensor for all shapes, not the best way but should be somehow OK. (inspired from bullet)
real_t total_area = 0;
for (int i = 0; i < get_shape_count(); i++) {
total_area += get_shape_area(i);
}
- // We have to recompute the center of mass
+ // We have to recompute the center of mass.
center_of_mass_local.zero();
for (int i = 0; i < get_shape_count(); i++) {
@@ -70,21 +70,24 @@ void Body3DSW::update_inertias() {
real_t mass = area * this->mass / total_area;
- // NOTE: we assume that the shape origin is also its center of mass
+ // NOTE: we assume that the shape origin is also its center of mass.
center_of_mass_local += mass * get_shape_transform(i).origin;
}
center_of_mass_local /= mass;
- // Recompute the inertia tensor
+ // Recompute the inertia tensor.
Basis inertia_tensor;
inertia_tensor.set_zero();
+ bool inertia_set = false;
for (int i = 0; i < get_shape_count(); i++) {
if (is_shape_disabled(i)) {
continue;
}
+ inertia_set = true;
+
const Shape3DSW *shape = get_shape(i);
real_t area = get_shape_area(i);
@@ -102,7 +105,12 @@ void Body3DSW::update_inertias() {
inertia_tensor += shape_inertia_tensor + (Basis() * shape_origin.dot(shape_origin) - shape_origin.outer(shape_origin)) * mass;
}
- // Compute the principal axes of inertia
+ // Set the inertia to a valid value when there are no valid shapes.
+ if (!inertia_set) {
+ inertia_tensor.set_diagonal(Vector3(1.0, 1.0, 1.0));
+ }
+
+ // Compute the principal axes of inertia.
principal_inertia_axes_local = inertia_tensor.diagonalize().transposed();
_inv_inertia = inertia_tensor.get_main_diagonal().inverse();
diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h
index 6dbda8670a..8e21003a5f 100644
--- a/servers/physics_3d/body_3d_sw.h
+++ b/servers/physics_3d/body_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -178,7 +178,7 @@ public:
}
_FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
- _FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); }
+ _FORCE_INLINE_ bool can_report_contacts() const { return !contacts.is_empty(); }
_FORCE_INLINE_ void add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_normal, real_t p_depth, int p_local_shape, const Vector3 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector3 &p_collider_velocity_at_pos);
_FORCE_INLINE_ void add_exception(const RID &p_exception) { exceptions.insert(p_exception); }
@@ -426,7 +426,7 @@ public:
ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector3());
return body->contacts[p_contact_idx].local_normal;
}
- virtual float get_contact_impulse(int p_contact_idx) const override {
+ virtual real_t get_contact_impulse(int p_contact_idx) const override {
return 0.0f; // Only implemented for bullet
}
virtual int get_contact_local_shape(int p_contact_idx) const override {
diff --git a/servers/physics_3d/body_pair_3d_sw.cpp b/servers/physics_3d/body_pair_3d_sw.cpp
index d8f187a7f8..6012ff1522 100644
--- a/servers/physics_3d/body_pair_3d_sw.cpp
+++ b/servers/physics_3d/body_pair_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/body_pair_3d_sw.h b/servers/physics_3d/body_pair_3d_sw.h
index 5f08d0cfa9..4d049eafdc 100644
--- a/servers/physics_3d/body_pair_3d_sw.h
+++ b/servers/physics_3d/body_pair_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/broad_phase_3d_basic.cpp b/servers/physics_3d/broad_phase_3d_basic.cpp
index 15a5968087..b41c2530da 100644
--- a/servers/physics_3d/broad_phase_3d_basic.cpp
+++ b/servers/physics_3d/broad_phase_3d_basic.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/broad_phase_3d_basic.h b/servers/physics_3d/broad_phase_3d_basic.h
index 361d322e14..54d34e005f 100644
--- a/servers/physics_3d/broad_phase_3d_basic.h
+++ b/servers/physics_3d/broad_phase_3d_basic.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/broad_phase_3d_sw.cpp b/servers/physics_3d/broad_phase_3d_sw.cpp
index 1a20fdd0cb..8aa64034ec 100644
--- a/servers/physics_3d/broad_phase_3d_sw.cpp
+++ b/servers/physics_3d/broad_phase_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/broad_phase_3d_sw.h b/servers/physics_3d/broad_phase_3d_sw.h
index 081e75810f..283c087b96 100644
--- a/servers/physics_3d/broad_phase_3d_sw.h
+++ b/servers/physics_3d/broad_phase_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/broad_phase_octree.cpp b/servers/physics_3d/broad_phase_octree.cpp
index 1ace1a4fcf..11324fa4e4 100644
--- a/servers/physics_3d/broad_phase_octree.cpp
+++ b/servers/physics_3d/broad_phase_octree.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/broad_phase_octree.h b/servers/physics_3d/broad_phase_octree.h
index 761a90a051..ee681dda96 100644
--- a/servers/physics_3d/broad_phase_octree.h
+++ b/servers/physics_3d/broad_phase_octree.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp
index e12f0659e2..293a7e6606 100644
--- a/servers/physics_3d/collision_object_3d_sw.cpp
+++ b/servers/physics_3d/collision_object_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,7 @@ void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform &p_trans
p_shape->add_owner(this);
if (!pending_shape_update_list.in_list()) {
- PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
//_update_shapes();
//_shapes_changed();
@@ -56,7 +56,7 @@ void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) {
p_shape->add_owner(this);
if (!pending_shape_update_list.in_list()) {
- PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
//_update_shapes();
//_shapes_changed();
@@ -68,7 +68,7 @@ void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_tr
shapes.write[p_index].xform = p_transform;
shapes.write[p_index].xform_inv = p_transform.affine_inverse();
if (!pending_shape_update_list.in_list()) {
- PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
//_update_shapes();
//_shapes_changed();
@@ -77,7 +77,7 @@ void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_tr
void CollisionObject3DSW::set_shape_as_disabled(int p_idx, bool p_enable) {
shapes.write[p_idx].disabled = p_enable;
if (!pending_shape_update_list.in_list()) {
- PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
}
@@ -106,7 +106,7 @@ void CollisionObject3DSW::remove_shape(int p_index) {
shapes.remove(p_index);
if (!pending_shape_update_list.in_list()) {
- PhysicsServer3DSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
//_update_shapes();
//_shapes_changed();
diff --git a/servers/physics_3d/collision_object_3d_sw.h b/servers/physics_3d/collision_object_3d_sw.h
index e1220f8855..3847b81381 100644
--- a/servers/physics_3d/collision_object_3d_sw.h
+++ b/servers/physics_3d/collision_object_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp
index 85f55ad66d..651961433c 100644
--- a/servers/physics_3d/collision_solver_3d_sat.cpp
+++ b/servers/physics_3d/collision_solver_3d_sat.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,38 @@
#include "collision_solver_3d_sat.h"
#include "core/math/geometry_3d.h"
-#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.02
+#include "gjk_epa.h"
+
+#define fallback_collision_solver gjk_epa_calculate_penetration
+
+// Cylinder SAT analytic methods and face-circle contact points for cylinder-trimesh and cylinder-box collision are based on ODE colliders.
+
+/*
+ * Cylinder-trimesh and Cylinder-box colliders by Alen Ladavac
+ * Ported to ODE by Nguyen Binh
+ */
+
+/*************************************************************************
+ * *
+ * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
+ * All rights reserved. Email: russ@q12.org Web: www.q12.org *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of EITHER: *
+ * (1) The GNU Lesser General Public License as published by the Free *
+ * Software Foundation; either version 2.1 of the License, or (at *
+ * your option) any later version. The text of the GNU Lesser *
+ * General Public License is included with this library in the *
+ * file LICENSE.TXT. *
+ * (2) The BSD-style license that is included with this library in *
+ * the file LICENSE-BSD.TXT. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
+ * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
+ * *
+ *************************************************************************/
struct _CollectorCallback {
CollisionSolver3DSW::CallbackResult callback;
@@ -82,6 +113,17 @@ static void _generate_contacts_point_face(const Vector3 *p_points_A, int p_point
p_callback->call(*p_points_A, closest_B);
}
+static void _generate_contacts_point_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(p_point_count_A != 1);
+ ERR_FAIL_COND(p_point_count_B != 3);
+#endif
+
+ Vector3 closest_B = Plane(p_points_B[0], p_points_B[1], p_points_B[2]).project(*p_points_A);
+
+ p_callback->call(*p_points_A, closest_B);
+}
+
static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A != 2);
@@ -128,6 +170,104 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_
p_callback->call(closest_A, closest_B);
}
+static void _generate_contacts_edge_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(p_point_count_A != 2);
+ ERR_FAIL_COND(p_point_count_B != 3);
+#endif
+
+ const Vector3 &circle_B_pos = p_points_B[0];
+ Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos;
+ Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos;
+
+ real_t circle_B_radius = circle_B_line_1.length();
+ Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized();
+
+ Plane circle_plane(circle_B_pos, circle_B_normal);
+
+ static const int max_clip = 2;
+ Vector3 contact_points[max_clip];
+ int num_points = 0;
+
+ // Project edge point in circle plane.
+ const Vector3 &edge_A_1 = p_points_A[0];
+ Vector3 proj_point_1 = circle_plane.project(edge_A_1);
+
+ Vector3 dist_vec = proj_point_1 - circle_B_pos;
+ real_t dist_sq = dist_vec.length_squared();
+
+ // Point 1 is inside disk, add as contact point.
+ if (dist_sq <= circle_B_radius * circle_B_radius) {
+ contact_points[num_points] = edge_A_1;
+ ++num_points;
+ }
+
+ const Vector3 &edge_A_2 = p_points_A[1];
+ Vector3 proj_point_2 = circle_plane.project(edge_A_2);
+
+ Vector3 dist_vec_2 = proj_point_2 - circle_B_pos;
+ real_t dist_sq_2 = dist_vec_2.length_squared();
+
+ // Point 2 is inside disk, add as contact point.
+ if (dist_sq_2 <= circle_B_radius * circle_B_radius) {
+ contact_points[num_points] = edge_A_2;
+ ++num_points;
+ }
+
+ if (num_points < 2) {
+ Vector3 line_vec = proj_point_2 - proj_point_1;
+ real_t line_length_sq = line_vec.length_squared();
+
+ // Create a quadratic formula of the form ax^2 + bx + c = 0
+ real_t a, b, c;
+
+ a = line_length_sq;
+ b = 2.0 * dist_vec.dot(line_vec);
+ c = dist_sq - circle_B_radius * circle_B_radius;
+
+ // Solve for t.
+ real_t sqrtterm = b * b - 4.0 * a * c;
+
+ // If the term we intend to square root is less than 0 then the answer won't be real,
+ // so the line doesn't intersect.
+ if (sqrtterm >= 0) {
+ sqrtterm = Math::sqrt(sqrtterm);
+
+ Vector3 edge_dir = edge_A_2 - edge_A_1;
+
+ real_t fraction_1 = (-b - sqrtterm) / (2.0 * a);
+ if ((fraction_1 > 0.0) && (fraction_1 < 1.0)) {
+ Vector3 face_point_1 = edge_A_1 + fraction_1 * edge_dir;
+ ERR_FAIL_COND(num_points >= max_clip);
+ contact_points[num_points] = face_point_1;
+ ++num_points;
+ }
+
+ real_t fraction_2 = (-b + sqrtterm) / (2.0 * a);
+ if ((fraction_2 > 0.0) && (fraction_2 < 1.0) && !Math::is_equal_approx(fraction_1, fraction_2)) {
+ Vector3 face_point_2 = edge_A_1 + fraction_2 * edge_dir;
+ ERR_FAIL_COND(num_points >= max_clip);
+ contact_points[num_points] = face_point_2;
+ ++num_points;
+ }
+ }
+ }
+
+ // Generate contact points.
+ for (int i = 0; i < num_points; i++) {
+ const Vector3 &contact_point_A = contact_points[i];
+
+ real_t d = circle_plane.distance_to(contact_point_A);
+ Vector3 closest_B = contact_point_A - circle_plane.normal * d;
+
+ if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) {
+ continue;
+ }
+
+ p_callback->call(contact_point_A, closest_B);
+ }
+}
+
static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A < 2);
@@ -217,36 +357,229 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
}
}
-static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
+static void _generate_contacts_face_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(p_point_count_A < 3);
+ ERR_FAIL_COND(p_point_count_B != 3);
+#endif
+
+ const Vector3 &circle_B_pos = p_points_B[0];
+ Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos;
+ Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos;
+
+ // Clip face with circle segments.
+ static const int circle_segments = 8;
+ Vector3 circle_points[circle_segments];
+
+ real_t angle_delta = 2.0 * Math_PI / circle_segments;
+
+ for (int i = 0; i < circle_segments; ++i) {
+ Vector3 point_pos = circle_B_pos;
+ point_pos += circle_B_line_1 * Math::cos(i * angle_delta);
+ point_pos += circle_B_line_2 * Math::sin(i * angle_delta);
+ circle_points[i] = point_pos;
+ }
+
+ _generate_contacts_face_face(p_points_A, p_point_count_A, circle_points, circle_segments, p_callback);
+
+ // Clip face with circle plane.
+ Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized();
+
+ Plane circle_plane(circle_B_pos, circle_B_normal);
+
+ static const int max_clip = 32;
+ Vector3 contact_points[max_clip];
+ int num_points = 0;
+
+ for (int i = 0; i < p_point_count_A; i++) {
+ int i_n = (i + 1) % p_point_count_A;
+
+ const Vector3 &edge0_A = p_points_A[i];
+ const Vector3 &edge1_A = p_points_A[i_n];
+
+ real_t dist0 = circle_plane.distance_to(edge0_A);
+ real_t dist1 = circle_plane.distance_to(edge1_A);
+
+ // First point in front of plane, generate contact point.
+ if (dist0 * circle_plane.d >= 0) {
+ ERR_FAIL_COND(num_points >= max_clip);
+ contact_points[num_points] = edge0_A;
+ ++num_points;
+ }
+
+ // Points on different sides, generate contact point.
+ if (dist0 * dist1 < 0) {
+ // calculate intersection
+ Vector3 rel = edge1_A - edge0_A;
+ real_t den = circle_plane.normal.dot(rel);
+ real_t dist = -(circle_plane.normal.dot(edge0_A) - circle_plane.d) / den;
+ Vector3 inters = edge0_A + rel * dist;
+
+ ERR_FAIL_COND(num_points >= max_clip);
+ contact_points[num_points] = inters;
+ ++num_points;
+ }
+ }
+
+ // Generate contact points.
+ for (int i = 0; i < num_points; i++) {
+ const Vector3 &contact_point_A = contact_points[i];
+
+ real_t d = circle_plane.distance_to(contact_point_A);
+ Vector3 closest_B = contact_point_A - circle_plane.normal * d;
+
+ if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) {
+ continue;
+ }
+
+ p_callback->call(contact_point_A, closest_B);
+ }
+}
+
+static void _generate_contacts_circle_circle(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(p_point_count_A != 3);
+ ERR_FAIL_COND(p_point_count_B != 3);
+#endif
+
+ const Vector3 &circle_A_pos = p_points_A[0];
+ Vector3 circle_A_line_1 = p_points_A[1] - circle_A_pos;
+ Vector3 circle_A_line_2 = p_points_A[2] - circle_A_pos;
+
+ real_t circle_A_radius = circle_A_line_1.length();
+ Vector3 circle_A_normal = circle_A_line_1.cross(circle_A_line_2).normalized();
+
+ const Vector3 &circle_B_pos = p_points_B[0];
+ Vector3 circle_B_line_1 = p_points_B[1] - circle_B_pos;
+ Vector3 circle_B_line_2 = p_points_B[2] - circle_B_pos;
+
+ real_t circle_B_radius = circle_B_line_1.length();
+ Vector3 circle_B_normal = circle_B_line_1.cross(circle_B_line_2).normalized();
+
+ static const int max_clip = 4;
+ Vector3 contact_points[max_clip];
+ int num_points = 0;
+
+ Vector3 centers_diff = circle_B_pos - circle_A_pos;
+ Vector3 norm_proj = circle_A_normal.dot(centers_diff) * circle_A_normal;
+ Vector3 comp_proj = centers_diff - norm_proj;
+ real_t proj_dist = comp_proj.length();
+ if (!Math::is_zero_approx(proj_dist)) {
+ comp_proj /= proj_dist;
+ if ((proj_dist > circle_A_radius - circle_B_radius) && (proj_dist > circle_B_radius - circle_A_radius)) {
+ // Circles are overlapping, use the 2 points of intersection as contacts.
+ real_t radius_a_sqr = circle_A_radius * circle_A_radius;
+ real_t radius_b_sqr = circle_B_radius * circle_B_radius;
+ real_t d_sqr = proj_dist * proj_dist;
+ real_t s = (1.0 + (radius_a_sqr - radius_b_sqr) / d_sqr) * 0.5;
+ real_t h = Math::sqrt(MAX(radius_a_sqr - d_sqr * s * s, 0.0));
+ Vector3 midpoint = circle_A_pos + s * comp_proj * proj_dist;
+ Vector3 h_vec = h * circle_A_normal.cross(comp_proj);
+
+ Vector3 point_A = midpoint + h_vec;
+ contact_points[num_points] = point_A;
+ ++num_points;
+
+ point_A = midpoint - h_vec;
+ contact_points[num_points] = point_A;
+ ++num_points;
+
+ // Add 2 points from circle A and B along the line between the centers.
+ point_A = circle_A_pos + comp_proj * circle_A_radius;
+ contact_points[num_points] = point_A;
+ ++num_points;
+
+ point_A = circle_B_pos - comp_proj * circle_B_radius - norm_proj;
+ contact_points[num_points] = point_A;
+ ++num_points;
+ } // Otherwise one circle is inside the other one, use 3 arbitrary equidistant points.
+ } // Otherwise circles are concentric, use 3 arbitrary equidistant points.
+
+ if (num_points == 0) {
+ // Generate equidistant points.
+ if (circle_A_radius < circle_B_radius) {
+ // Circle A inside circle B.
+ for (int i = 0; i < 3; ++i) {
+ Vector3 circle_A_point = circle_A_pos;
+ circle_A_point += circle_A_line_1 * Math::cos(2.0 * Math_PI * i / 3.0);
+ circle_A_point += circle_A_line_2 * Math::sin(2.0 * Math_PI * i / 3.0);
+
+ contact_points[num_points] = circle_A_point;
+ ++num_points;
+ }
+ } else {
+ // Circle B inside circle A.
+ for (int i = 0; i < 3; ++i) {
+ Vector3 circle_B_point = circle_B_pos;
+ circle_B_point += circle_B_line_1 * Math::cos(2.0 * Math_PI * i / 3.0);
+ circle_B_point += circle_B_line_2 * Math::sin(2.0 * Math_PI * i / 3.0);
+
+ Vector3 circle_A_point = circle_B_point - norm_proj;
+
+ contact_points[num_points] = circle_A_point;
+ ++num_points;
+ }
+ }
+ }
+
+ Plane circle_B_plane(circle_B_pos, circle_B_normal);
+
+ // Generate contact points.
+ for (int i = 0; i < num_points; i++) {
+ const Vector3 &contact_point_A = contact_points[i];
+
+ real_t d = circle_B_plane.distance_to(contact_point_A);
+ Vector3 closest_B = contact_point_A - circle_B_plane.normal * d;
+
+ if (p_callback->normal.dot(contact_point_A) >= p_callback->normal.dot(closest_B)) {
+ continue;
+ }
+
+ p_callback->call(contact_point_A, closest_B);
+ }
+}
+
+static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, Shape3DSW::FeatureType p_feature_type_A, const Vector3 *p_points_B, int p_point_count_B, Shape3DSW::FeatureType p_feature_type_B, _CollectorCallback *p_callback) {
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A < 1);
ERR_FAIL_COND(p_point_count_B < 1);
#endif
- static const GenerateContactsFunc generate_contacts_func_table[3][3] = {
+ static const GenerateContactsFunc generate_contacts_func_table[4][4] = {
{
_generate_contacts_point_point,
_generate_contacts_point_edge,
_generate_contacts_point_face,
+ _generate_contacts_point_circle,
},
{
nullptr,
_generate_contacts_edge_edge,
_generate_contacts_face_face,
+ _generate_contacts_edge_circle,
},
{
nullptr,
nullptr,
_generate_contacts_face_face,
- }
+ _generate_contacts_face_circle,
+ },
+ {
+ nullptr,
+ nullptr,
+ nullptr,
+ _generate_contacts_circle_circle,
+ },
};
int pointcount_B;
int pointcount_A;
const Vector3 *points_A;
const Vector3 *points_B;
+ int version_A;
+ int version_B;
- if (p_point_count_A > p_point_count_B) {
+ if (p_feature_type_A > p_feature_type_B) {
//swap
p_callback->swap = !p_callback->swap;
p_callback->normal = -p_callback->normal;
@@ -255,16 +588,17 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po
pointcount_A = p_point_count_B;
points_A = p_points_B;
points_B = p_points_A;
+ version_A = p_feature_type_B;
+ version_B = p_feature_type_A;
} else {
pointcount_B = p_point_count_B;
pointcount_A = p_point_count_A;
points_A = p_points_A;
points_B = p_points_B;
+ version_A = p_feature_type_A;
+ version_B = p_feature_type_B;
}
- int version_A = (pointcount_A > 3 ? 3 : pointcount_A) - 1;
- int version_B = (pointcount_B > 3 ? 3 : pointcount_B) - 1;
-
GenerateContactsFunc contacts_func = generate_contacts_func_table[version_A][version_B];
ERR_FAIL_COND(!contacts_func);
contacts_func(points_A, pointcount_A, points_B, pointcount_B, p_callback);
@@ -346,6 +680,17 @@ public:
return true;
}
+ static _FORCE_INLINE_ void test_contact_points(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) {
+ SeparatorAxisTest<ShapeA, ShapeB, withMargin> *separator = (SeparatorAxisTest<ShapeA, ShapeB, withMargin> *)p_userdata;
+ Vector3 axis = (p_point_B - p_point_A);
+ real_t depth = axis.length();
+
+ // Filter out bogus directions with a treshold and re-testing axis.
+ if (separator->best_depth - depth > 0.001) {
+ separator->test_axis(axis / depth);
+ }
+ }
+
_FORCE_INLINE_ void generate_contacts() {
// nothing to do, don't generate
if (best_axis == Vector3(0.0, 0.0, 0.0)) {
@@ -365,7 +710,8 @@ public:
Vector3 supports_A[max_supports];
int support_count_A;
- shape_A->get_supports(transform_A->basis.xform_inv(-best_axis).normalized(), max_supports, supports_A, support_count_A);
+ Shape3DSW::FeatureType support_type_A;
+ shape_A->get_supports(transform_A->basis.xform_inv(-best_axis).normalized(), max_supports, supports_A, support_count_A, support_type_A);
for (int i = 0; i < support_count_A; i++) {
supports_A[i] = transform_A->xform(supports_A[i]);
}
@@ -378,7 +724,8 @@ public:
Vector3 supports_B[max_supports];
int support_count_B;
- shape_B->get_supports(transform_B->basis.xform_inv(best_axis).normalized(), max_supports, supports_B, support_count_B);
+ Shape3DSW::FeatureType support_type_B;
+ shape_B->get_supports(transform_B->basis.xform_inv(best_axis).normalized(), max_supports, supports_B, support_count_B, support_type_B);
for (int i = 0; i < support_count_B; i++) {
supports_B[i] = transform_B->xform(supports_B[i]);
}
@@ -393,7 +740,7 @@ public:
if (callback->prev_axis) {
*callback->prev_axis = best_axis;
}
- _generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback);
+ _generate_contacts_from_supports(supports_A, support_count_A, support_type_A, supports_B, support_count_B, support_type_B, callback);
callback->collided = true;
}
@@ -498,7 +845,7 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t
//capsule sphere 1, sphere
- Vector3 capsule_axis = p_transform_b.basis.get_axis(2) * (capsule_B->get_height() * 0.5);
+ Vector3 capsule_axis = p_transform_b.basis.get_axis(1) * (capsule_B->get_height() * 0.5);
Vector3 capsule_ball_1 = p_transform_b.origin + capsule_axis;
@@ -529,6 +876,61 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t
template <bool withMargin>
static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+ const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a);
+ const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b);
+
+ SeparatorAxisTest<SphereShape3DSW, CylinderShape3DSW, withMargin> separator(sphere_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
+
+ if (!separator.test_previous_axis()) {
+ return;
+ }
+
+ // Cylinder B end caps.
+ Vector3 cylinder_B_axis = p_transform_b.basis.get_axis(1).normalized();
+ if (!separator.test_axis(cylinder_B_axis)) {
+ return;
+ }
+
+ Vector3 cylinder_diff = p_transform_b.origin - p_transform_a.origin;
+
+ // Cylinder B lateral surface.
+ if (!separator.test_axis(cylinder_B_axis.cross(cylinder_diff).cross(cylinder_B_axis).normalized())) {
+ return;
+ }
+
+ // Closest point to cylinder caps.
+ const Vector3 &sphere_center = p_transform_a.origin;
+ Vector3 cyl_axis = p_transform_b.basis.get_axis(1);
+ Vector3 cap_axis = p_transform_b.basis.get_axis(0);
+ real_t height_scale = cyl_axis.length();
+ real_t cap_dist = cylinder_B->get_height() * 0.5 * height_scale;
+ cyl_axis /= height_scale;
+ real_t radius_scale = cap_axis.length();
+ real_t cap_radius = cylinder_B->get_radius() * radius_scale;
+
+ for (int i = 0; i < 2; i++) {
+ Vector3 cap_dir = ((i == 0) ? cyl_axis : -cyl_axis);
+ Vector3 cap_pos = p_transform_b.origin + cap_dir * cap_dist;
+
+ Vector3 closest_point;
+
+ Vector3 diff = sphere_center - cap_pos;
+ Vector3 proj = diff - cap_dir.dot(diff) * cap_dir;
+
+ real_t proj_len = proj.length();
+ if (Math::is_zero_approx(proj_len)) {
+ // Point is equidistant to all circle points.
+ continue;
+ }
+
+ closest_point = cap_pos + (cap_radius / proj_len) * proj;
+
+ if (!separator.test_axis((closest_point - sphere_center).normalized())) {
+ return;
+ }
+ }
+
+ separator.generate_contacts();
}
template <bool withMargin>
@@ -739,14 +1141,14 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran
// faces of A
for (int i = 0; i < 3; i++) {
- Vector3 axis = p_transform_a.basis.get_axis(i);
+ Vector3 axis = p_transform_a.basis.get_axis(i).normalized();
if (!separator.test_axis(axis)) {
return;
}
}
- Vector3 cyl_axis = p_transform_b.basis.get_axis(2).normalized();
+ Vector3 cyl_axis = p_transform_b.basis.get_axis(1).normalized();
// edges of A, capsule cylinder
@@ -791,7 +1193,7 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran
// capsule balls, edges of A
for (int i = 0; i < 2; i++) {
- Vector3 capsule_axis = p_transform_b.basis.get_axis(2) * (capsule_B->get_height() * 0.5);
+ Vector3 capsule_axis = p_transform_b.basis.get_axis(1) * (capsule_B->get_height() * 0.5);
Vector3 sphere_pos = p_transform_b.origin + ((i == 0) ? capsule_axis : -capsule_axis);
@@ -826,6 +1228,115 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran
template <bool withMargin>
static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+ const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a);
+ const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b);
+
+ SeparatorAxisTest<BoxShape3DSW, CylinderShape3DSW, withMargin> separator(box_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
+
+ if (!separator.test_previous_axis()) {
+ return;
+ }
+
+ // Faces of A.
+ for (int i = 0; i < 3; i++) {
+ Vector3 axis = p_transform_a.basis.get_axis(i).normalized();
+
+ if (!separator.test_axis(axis)) {
+ return;
+ }
+ }
+
+ Vector3 cyl_axis = p_transform_b.basis.get_axis(1).normalized();
+
+ // Cylinder end caps.
+ {
+ if (!separator.test_axis(cyl_axis)) {
+ return;
+ }
+ }
+
+ // Edges of A, cylinder lateral surface.
+ for (int i = 0; i < 3; i++) {
+ Vector3 box_axis = p_transform_a.basis.get_axis(i);
+ Vector3 axis = box_axis.cross(cyl_axis);
+ if (Math::is_zero_approx(axis.length_squared())) {
+ continue;
+ }
+
+ if (!separator.test_axis(axis.normalized())) {
+ return;
+ }
+ }
+
+ // Gather points of A.
+ Vector3 vertices_A[8];
+ Vector3 box_extent = box_A->get_half_extents();
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 2; j++) {
+ for (int k = 0; k < 2; k++) {
+ Vector3 extent = box_extent;
+ extent.x *= (i * 2 - 1);
+ extent.y *= (j * 2 - 1);
+ extent.z *= (k * 2 - 1);
+ Vector3 &point = vertices_A[i * 2 * 2 + j * 2 + k];
+ point = p_transform_a.origin;
+ for (int l = 0; l < 3; l++) {
+ point += p_transform_a.basis.get_axis(l) * extent[l];
+ }
+ }
+ }
+ }
+
+ // Points of A, cylinder lateral surface.
+ for (int i = 0; i < 8; i++) {
+ const Vector3 &point = vertices_A[i];
+ Vector3 axis = Plane(cyl_axis, 0).project(point).normalized();
+
+ if (!separator.test_axis(axis)) {
+ return;
+ }
+ }
+
+ // Edges of A, cylinder end caps rim.
+ int edges_start_A[12] = { 0, 2, 4, 6, 0, 1, 4, 5, 0, 1, 2, 3 };
+ int edges_end_A[12] = { 1, 3, 5, 7, 2, 3, 6, 7, 4, 5, 6, 7 };
+
+ Vector3 cap_axis = cyl_axis * (cylinder_B->get_height() * 0.5);
+
+ for (int i = 0; i < 2; i++) {
+ Vector3 cap_pos = p_transform_b.origin + ((i == 0) ? cap_axis : -cap_axis);
+
+ for (int e = 0; e < 12; e++) {
+ const Vector3 &edge_start = vertices_A[edges_start_A[e]];
+ const Vector3 &edge_end = vertices_A[edges_end_A[e]];
+
+ Vector3 edge_dir = (edge_end - edge_start);
+ edge_dir.normalize();
+
+ real_t edge_dot = edge_dir.dot(cyl_axis);
+ if (Math::is_zero_approx(edge_dot)) {
+ // Edge is perpendicular to cylinder axis.
+ continue;
+ }
+
+ // Calculate intersection between edge and circle plane.
+ Vector3 edge_diff = cap_pos - edge_start;
+ real_t diff_dot = edge_diff.dot(cyl_axis);
+ Vector3 intersection = edge_start + edge_dir * diff_dot / edge_dot;
+
+ // Calculate tangent that touches intersection.
+ Vector3 tangent = (cap_pos - intersection).cross(cyl_axis);
+
+ // Axis is orthogonal both to tangent and edge direction.
+ Vector3 axis = tangent.cross(edge_dir);
+
+ if (!separator.test_axis(axis.normalized())) {
+ return;
+ }
+ }
+ }
+
+ separator.generate_contacts();
}
template <bool withMargin>
@@ -1058,8 +1569,8 @@ static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_
// some values
- Vector3 capsule_A_axis = p_transform_a.basis.get_axis(2) * (capsule_A->get_height() * 0.5);
- Vector3 capsule_B_axis = p_transform_b.basis.get_axis(2) * (capsule_B->get_height() * 0.5);
+ Vector3 capsule_A_axis = p_transform_a.basis.get_axis(1) * (capsule_A->get_height() * 0.5);
+ Vector3 capsule_B_axis = p_transform_b.basis.get_axis(1) * (capsule_B->get_height() * 0.5);
Vector3 capsule_A_ball_1 = p_transform_a.origin + capsule_A_axis;
Vector3 capsule_A_ball_2 = p_transform_a.origin - capsule_A_axis;
@@ -1111,6 +1622,19 @@ static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_
template <bool withMargin>
static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+ const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a);
+ const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b);
+
+ SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin> separator(capsule_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
+
+ CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CapsuleShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points;
+
+ // Fallback to generic algorithm to find the best separating axis.
+ if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) {
+ return;
+ }
+
+ separator.generate_contacts();
}
template <bool withMargin>
@@ -1146,7 +1670,7 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf
for (int i = 0; i < edge_count; i++) {
// cylinder
Vector3 edge_axis = p_transform_b.basis.xform(vertices[edges[i].a]) - p_transform_b.basis.xform(vertices[edges[i].b]);
- Vector3 axis = edge_axis.cross(p_transform_a.basis.get_axis(2)).normalized();
+ Vector3 axis = edge_axis.cross(p_transform_a.basis.get_axis(1)).normalized();
if (!separator.test_axis(axis)) {
return;
@@ -1158,7 +1682,7 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf
for (int i = 0; i < 2; i++) {
// edges of B, capsule cylinder
- Vector3 capsule_axis = p_transform_a.basis.get_axis(2) * (capsule_A->get_height() * 0.5);
+ Vector3 capsule_axis = p_transform_a.basis.get_axis(1) * (capsule_A->get_height() * 0.5);
Vector3 sphere_pos = p_transform_a.origin + ((i == 0) ? capsule_axis : -capsule_axis);
@@ -1196,7 +1720,7 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_tra
// edges of B, capsule cylinder
- Vector3 capsule_axis = p_transform_a.basis.get_axis(2) * (capsule_A->get_height() * 0.5);
+ Vector3 capsule_axis = p_transform_a.basis.get_axis(1) * (capsule_A->get_height() * 0.5);
for (int i = 0; i < 3; i++) {
// edge-cylinder
@@ -1236,14 +1760,165 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_tra
template <bool withMargin>
static void _collision_cylinder_cylinder(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+ const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a);
+ const CylinderShape3DSW *cylinder_B = static_cast<const CylinderShape3DSW *>(p_b);
+
+ SeparatorAxisTest<CylinderShape3DSW, CylinderShape3DSW, withMargin> separator(cylinder_A, p_transform_a, cylinder_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
+
+ Vector3 cylinder_A_axis = p_transform_a.basis.get_axis(1);
+ Vector3 cylinder_B_axis = p_transform_b.basis.get_axis(1);
+
+ if (!separator.test_previous_axis()) {
+ return;
+ }
+
+ // Cylinder A end caps.
+ if (!separator.test_axis(cylinder_A_axis.normalized())) {
+ return;
+ }
+
+ // Cylinder B end caps.
+ if (!separator.test_axis(cylinder_A_axis.normalized())) {
+ return;
+ }
+
+ Vector3 cylinder_diff = p_transform_b.origin - p_transform_a.origin;
+
+ // Cylinder A lateral surface.
+ if (!separator.test_axis(cylinder_A_axis.cross(cylinder_diff).cross(cylinder_A_axis).normalized())) {
+ return;
+ }
+
+ // Cylinder B lateral surface.
+ if (!separator.test_axis(cylinder_B_axis.cross(cylinder_diff).cross(cylinder_B_axis).normalized())) {
+ return;
+ }
+
+ real_t proj = cylinder_A_axis.cross(cylinder_B_axis).cross(cylinder_B_axis).dot(cylinder_A_axis);
+ if (Math::is_zero_approx(proj)) {
+ // Parallel cylinders, handle with specific axes only.
+ // Note: GJKEPA with no margin can lead to degenerate cases in this situation.
+ separator.generate_contacts();
+ return;
+ }
+
+ CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CylinderShape3DSW, CylinderShape3DSW, withMargin>::test_contact_points;
+
+ // Fallback to generic algorithm to find the best separating axis.
+ if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) {
+ return;
+ }
+
+ separator.generate_contacts();
}
template <bool withMargin>
static void _collision_cylinder_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+ const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a);
+ const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b);
+
+ SeparatorAxisTest<CylinderShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(cylinder_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
+
+ CollisionSolver3DSW::CallbackResult callback = SeparatorAxisTest<CylinderShape3DSW, ConvexPolygonShape3DSW, withMargin>::test_contact_points;
+
+ // Fallback to generic algorithm to find the best separating axis.
+ if (!fallback_collision_solver(p_a, p_transform_a, p_b, p_transform_b, callback, &separator)) {
+ return;
+ }
+
+ separator.generate_contacts();
}
template <bool withMargin>
static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+ const CylinderShape3DSW *cylinder_A = static_cast<const CylinderShape3DSW *>(p_a);
+ const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b);
+
+ SeparatorAxisTest<CylinderShape3DSW, FaceShape3DSW, withMargin> separator(cylinder_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
+
+ if (!separator.test_previous_axis()) {
+ return;
+ }
+
+ Vector3 vertex[3] = {
+ p_transform_b.xform(face_B->vertex[0]),
+ p_transform_b.xform(face_B->vertex[1]),
+ p_transform_b.xform(face_B->vertex[2]),
+ };
+
+ // Face B normal.
+ if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) {
+ return;
+ }
+
+ Vector3 cyl_axis = p_transform_a.basis.get_axis(1).normalized();
+
+ // Cylinder end caps.
+ {
+ if (!separator.test_axis(cyl_axis)) {
+ return;
+ }
+ }
+
+ // Edges of B, cylinder lateral surface.
+ for (int i = 0; i < 3; i++) {
+ Vector3 edge_axis = vertex[i] - vertex[(i + 1) % 3];
+ Vector3 axis = edge_axis.cross(cyl_axis);
+ if (Math::is_zero_approx(axis.length_squared())) {
+ continue;
+ }
+
+ if (!separator.test_axis(axis.normalized())) {
+ return;
+ }
+ }
+
+ // Points of B, cylinder lateral surface.
+ for (int i = 0; i < 3; i++) {
+ const Vector3 &point = vertex[i];
+ Vector3 axis = Plane(cyl_axis, 0).project(point).normalized();
+
+ if (!separator.test_axis(axis)) {
+ return;
+ }
+ }
+
+ // Edges of B, cylinder end caps rim.
+ Vector3 cap_axis = cyl_axis * (cylinder_A->get_height() * 0.5);
+
+ for (int i = 0; i < 2; i++) {
+ Vector3 cap_pos = p_transform_a.origin + ((i == 0) ? cap_axis : -cap_axis);
+
+ for (int j = 0; j < 3; j++) {
+ const Vector3 &edge_start = vertex[j];
+ const Vector3 &edge_end = vertex[(j + 1) % 3];
+ Vector3 edge_dir = edge_end - edge_start;
+ edge_dir.normalize();
+
+ real_t edge_dot = edge_dir.dot(cyl_axis);
+ if (Math::is_zero_approx(edge_dot)) {
+ // Edge is perpendicular to cylinder axis.
+ continue;
+ }
+
+ // Calculate intersection between edge and circle plane.
+ Vector3 edge_diff = cap_pos - edge_start;
+ real_t diff_dot = edge_diff.dot(cyl_axis);
+ Vector3 intersection = edge_start + edge_dir * diff_dot / edge_dot;
+
+ // Calculate tangent that touches intersection.
+ Vector3 tangent = (cap_pos - intersection).cross(cyl_axis);
+
+ // Axis is orthogonal both to tangent and edge direction.
+ Vector3 axis = tangent.cross(edge_dir);
+
+ if (!separator.test_axis(axis.normalized())) {
+ return;
+ }
+ }
+ }
+
+ separator.generate_contacts();
}
template <bool withMargin>
diff --git a/servers/physics_3d/collision_solver_3d_sat.h b/servers/physics_3d/collision_solver_3d_sat.h
index 5eccfda9ac..97454c0b4a 100644
--- a/servers/physics_3d/collision_solver_3d_sat.h
+++ b/servers/physics_3d/collision_solver_3d_sat.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/collision_solver_3d_sw.cpp
index e2bfaf990d..fd9ea00d92 100644
--- a/servers/physics_3d/collision_solver_3d_sw.cpp
+++ b/servers/physics_3d/collision_solver_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,8 +46,24 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T
static const int max_supports = 16;
Vector3 supports[max_supports];
int support_count;
-
- p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count);
+ Shape3DSW::FeatureType support_type;
+ p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count, support_type);
+
+ if (support_type == Shape3DSW::FEATURE_CIRCLE) {
+ ERR_FAIL_COND_V(support_count != 3, false);
+
+ Vector3 circle_pos = supports[0];
+ Vector3 circle_axis_1 = supports[1] - circle_pos;
+ Vector3 circle_axis_2 = supports[2] - circle_pos;
+
+ // Use 3 equidistant points on the circle.
+ for (int i = 0; i < 3; ++i) {
+ Vector3 vertex_pos = circle_pos;
+ vertex_pos += circle_axis_1 * Math::cos(2.0 * Math_PI * i / 3.0);
+ vertex_pos += circle_axis_2 * Math::sin(2.0 * Math_PI * i / 3.0);
+ supports[i] = vertex_pos;
+ }
+ }
bool found = false;
@@ -265,8 +281,25 @@ bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const
static const int max_supports = 16;
Vector3 supports[max_supports];
int support_count;
+ Shape3DSW::FeatureType support_type;
+
+ p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count, support_type);
- p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(), max_supports, supports, support_count);
+ if (support_type == Shape3DSW::FEATURE_CIRCLE) {
+ ERR_FAIL_COND_V(support_count != 3, false);
+
+ Vector3 circle_pos = supports[0];
+ Vector3 circle_axis_1 = supports[1] - circle_pos;
+ Vector3 circle_axis_2 = supports[2] - circle_pos;
+
+ // Use 3 equidistant points on the circle.
+ for (int i = 0; i < 3; ++i) {
+ Vector3 vertex_pos = circle_pos;
+ vertex_pos += circle_axis_1 * Math::cos(2.0 * Math_PI * i / 3.0);
+ vertex_pos += circle_axis_2 * Math::sin(2.0 * Math_PI * i / 3.0);
+ supports[i] = vertex_pos;
+ }
+ }
bool collided = false;
Vector3 closest;
diff --git a/servers/physics_3d/collision_solver_3d_sw.h b/servers/physics_3d/collision_solver_3d_sw.h
index 13f54ca8fb..81d87e9773 100644
--- a/servers/physics_3d/collision_solver_3d_sw.h
+++ b/servers/physics_3d/collision_solver_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/constraint_3d_sw.h b/servers/physics_3d/constraint_3d_sw.h
index 081ddb0382..2571335c43 100644
--- a/servers/physics_3d/constraint_3d_sw.h
+++ b/servers/physics_3d/constraint_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp
index e14949543e..aa7c11eec5 100644
--- a/servers/physics_3d/gjk_epa.cpp
+++ b/servers/physics_3d/gjk_epa.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,7 +64,7 @@ GJK-EPA collision solver by Nathanael Presson, 2008
/* GJK */
#define GJK_MAX_ITERATIONS 128
-#define GJK_ACCURARY ((real_t)0.0001)
+#define GJK_ACCURACY ((real_t)0.0001)
#define GJK_MIN_DISTANCE ((real_t)0.0001)
#define GJK_DUPLICATED_EPS ((real_t)0.0001)
#define GJK_SIMPLEX2_EPS ((real_t)0.0)
@@ -72,10 +72,13 @@ GJK-EPA collision solver by Nathanael Presson, 2008
#define GJK_SIMPLEX4_EPS ((real_t)0.0)
/* EPA */
-#define EPA_MAX_VERTICES 64
+#define EPA_MAX_VERTICES 128
#define EPA_MAX_FACES (EPA_MAX_VERTICES*2)
#define EPA_MAX_ITERATIONS 255
-#define EPA_ACCURACY ((real_t)0.0001)
+// -- GODOT start --
+//#define EPA_ACCURACY ((real_t)0.0001)
+#define EPA_ACCURACY ((real_t)0.00001)
+// -- GODOT end --
#define EPA_FALLBACK (10*EPA_ACCURACY)
#define EPA_PLANE_EPS ((real_t)0.00001)
#define EPA_INSIDE_EPS ((real_t)0.01)
@@ -237,7 +240,7 @@ struct GJK
/* Check for termination */
const real_t omega=vec3_dot(m_ray,w)/rl;
alpha=MAX(omega,alpha);
- if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
+ if(((rl-alpha)-(GJK_ACCURACY*rl))<=0)
{/* Return old simplex */
removevertice(m_simplices[m_current]);
break;
@@ -466,7 +469,7 @@ struct GJK
if(ng&&(Math::abs(vl)>GJK_SIMPLEX4_EPS))
{
real_t mindist=-1;
- real_t subw[3];
+ real_t subw[3] = {0.f, 0.f, 0.f};
U subm=0;
for(U i=0;i<3;++i)
{
@@ -512,7 +515,6 @@ struct GJK
{
Vector3 n;
real_t d;
- real_t p;
sSV* c[3];
sFace* f[3];
sFace* l[2];
@@ -661,8 +663,7 @@ struct GJK
remove(m_hull,best);
append(m_stock,best);
best=findbest();
- if(best->p>=outer.p) { outer=*best;
-}
+ outer=*best;
} else { m_status=eStatus::InvalidHull;break; }
} else { m_status=eStatus::AccuraryReached;break; }
} else { m_status=eStatus::OutOfVertices;break; }
@@ -688,24 +689,54 @@ struct GJK
}
}
/* Fallback */
- m_status = eStatus::FallBack;
- m_normal = -guess;
- const real_t nl=m_normal.length();
- if(nl>0) {
- m_normal = m_normal/nl;
+ m_status = eStatus::FallBack;
+ m_normal = -guess;
+ const real_t nl = m_normal.length();
+ if (nl > 0) {
+ m_normal = m_normal/nl;
} else {
- m_normal = Vector3(1,0,0);
-}
+ m_normal = Vector3(1,0,0);
+ }
m_depth = 0;
m_result.rank=1;
m_result.c[0]=simplex.c[0];
m_result.p[0]=1;
return(m_status);
}
+
+ bool getedgedist(sFace* face, sSV* a, sSV* b, real_t& dist)
+ {
+ const Vector3 ba = b->w - a->w;
+ const Vector3 n_ab = vec3_cross(ba, face->n); // Outward facing edge normal direction, on triangle plane
+ const real_t a_dot_nab = vec3_dot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required
+
+ if (a_dot_nab < 0) {
+ // Outside of edge a->b
+ const real_t ba_l2 = ba.length_squared();
+ const real_t a_dot_ba = vec3_dot(a->w, ba);
+ const real_t b_dot_ba = vec3_dot(b->w, ba);
+
+ if (a_dot_ba > 0) {
+ // Pick distance vertex a
+ dist = a->w.length();
+ } else if (b_dot_ba < 0) {
+ // Pick distance vertex b
+ dist = b->w.length();
+ } else {
+ // Pick distance to edge a->b
+ const real_t a_dot_b = vec3_dot(a->w, b->w);
+ dist = Math::sqrt(MAX((a->w.length_squared() * b->w.length_squared() - a_dot_b * a_dot_b) / ba_l2, 0.0));
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
sFace* newface(sSV* a,sSV* b,sSV* c,bool forced)
{
- if(m_stock.root)
- {
+ if (m_stock.root) {
sFace* face=m_stock.root;
remove(m_stock,face);
append(m_hull,face);
@@ -716,23 +747,23 @@ struct GJK
face->n = vec3_cross(b->w-a->w,c->w-a->w);
const real_t l=face->n.length();
const bool v=l>EPA_ACCURACY;
- face->p = MIN(MIN(
- vec3_dot(a->w,vec3_cross(face->n,a->w-b->w)),
- vec3_dot(b->w,vec3_cross(face->n,b->w-c->w))),
- vec3_dot(c->w,vec3_cross(face->n,c->w-a->w))) /
- (v?l:1);
- face->p = face->p>=-EPA_INSIDE_EPS?0:face->p;
- if(v)
- {
- face->d = vec3_dot(a->w,face->n)/l;
+ if (v) {
+ if (!(getedgedist(face, a, b, face->d) ||
+ getedgedist(face, b, c, face->d) ||
+ getedgedist(face, c, a, face->d))) {
+ // Origin projects to the interior of the triangle
+ // Use distance to triangle plane
+ face->d = vec3_dot(a->w, face->n) / l;
+ }
face->n /= l;
- if(forced||(face->d>=-EPA_PLANE_EPS))
- {
+ if (forced||(face->d>=-EPA_PLANE_EPS)) {
return(face);
- } else { m_status=eStatus::NonConvex;
-}
- } else { m_status=eStatus::Degenerated;
-}
+ } else {
+ m_status=eStatus::NonConvex;
+ }
+ } else {
+ m_status=eStatus::Degenerated;
+ }
remove(m_hull,face);
append(m_stock,face);
return(nullptr);
@@ -747,15 +778,13 @@ struct GJK
{
sFace* minf=m_hull.root;
real_t mind=minf->d*minf->d;
- real_t maxp=minf->p;
for(sFace* f=minf->l[1];f;f=f->l[1])
{
const real_t sqd=f->d*f->d;
- if((f->p>=maxp)&&(sqd<mind))
+ if(sqd<mind)
{
minf=f;
mind=sqd;
- maxp=f->p;
}
}
return(minf);
diff --git a/servers/physics_3d/gjk_epa.h b/servers/physics_3d/gjk_epa.h
index dec0f269e1..be3ba4e664 100644
--- a/servers/physics_3d/gjk_epa.h
+++ b/servers/physics_3d/gjk_epa.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp
index 789d6687a4..9c4493f4a2 100644
--- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -92,9 +92,9 @@ ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Trans
m_rbAFrame = rbAFrame;
m_rbBFrame = rbBFrame;
- m_swingSpan1 = Math_PI / 4.0;
- m_swingSpan2 = Math_PI / 4.0;
- m_twistSpan = Math_PI * 2;
+ m_swingSpan1 = Math_TAU / 8.0;
+ m_swingSpan2 = Math_TAU / 8.0;
+ m_twistSpan = Math_TAU;
m_biasFactor = 0.3f;
m_relaxationFactor = 1.0f;
diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h b/servers/physics_3d/joints/cone_twist_joint_3d_sw.h
index c713d8cf17..4e4d4e7f0c 100644
--- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.h
+++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -102,7 +102,7 @@ public:
bool m_solveSwingLimit;
public:
- virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_CONE_TWIST; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_CONE_TWIST; }
virtual bool setup(real_t p_timestep);
virtual void solve(real_t p_timestep);
diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
index 9ce5ebb7ed..13b389251f 100644
--- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -132,7 +132,7 @@ real_t G6DOFRotationalLimitMotor3DSW::solveAngularLimits(
real_t oldaccumImpulse = m_accumulatedImpulse;
real_t sum = oldaccumImpulse + clippedMotorImpulse;
- m_accumulatedImpulse = sum > hi ? real_t(0.) : sum < lo ? real_t(0.) : sum;
+ m_accumulatedImpulse = sum > hi ? real_t(0.) : (sum < lo ? real_t(0.) : sum);
clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse;
@@ -201,7 +201,7 @@ real_t G6DOFTranslationalLimitMotor3DSW::solveLinearAxis(
real_t oldNormalImpulse = m_accumulatedImpulse[limit_index];
real_t sum = oldNormalImpulse + normalImpulse;
- m_accumulatedImpulse[limit_index] = sum > hi ? real_t(0.) : sum < lo ? real_t(0.) : sum;
+ m_accumulatedImpulse[limit_index] = sum > hi ? real_t(0.) : (sum < lo ? real_t(0.) : sum);
normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse;
Vector3 impulse_vector = axis_normal_on_a * normalImpulse;
diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
index 7b98177066..d61a033231 100644
--- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
+++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -234,7 +234,7 @@ protected:
public:
Generic6DOFJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameInA, const Transform &frameInB, bool useLinearReferenceFrameA);
- virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_6DOF; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_6DOF; }
virtual bool setup(real_t p_timestep);
virtual void solve(real_t p_timestep);
diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
index c6fbc0f55f..2b9f0038b4 100644
--- a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.h b/servers/physics_3d/joints/hinge_joint_3d_sw.h
index c5af888eca..b6117aa0bc 100644
--- a/servers/physics_3d/joints/hinge_joint_3d_sw.h
+++ b/servers/physics_3d/joints/hinge_joint_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -96,7 +96,7 @@ class HingeJoint3DSW : public Joint3DSW {
real_t m_appliedImpulse;
public:
- virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_HINGE; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_HINGE; }
virtual bool setup(real_t p_step);
virtual void solve(real_t p_step);
diff --git a/servers/physics_3d/joints/jacobian_entry_3d_sw.h b/servers/physics_3d/joints/jacobian_entry_3d_sw.h
index 1737c21b3d..2829a5caf7 100644
--- a/servers/physics_3d/joints/jacobian_entry_3d_sw.h
+++ b/servers/physics_3d/joints/jacobian_entry_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.cpp b/servers/physics_3d/joints/pin_joint_3d_sw.cpp
index f028ad88f9..9f708ce151 100644
--- a/servers/physics_3d/joints/pin_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/pin_joint_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.h b/servers/physics_3d/joints/pin_joint_3d_sw.h
index 0181a4455b..1875983527 100644
--- a/servers/physics_3d/joints/pin_joint_3d_sw.h
+++ b/servers/physics_3d/joints/pin_joint_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -74,7 +74,7 @@ class PinJoint3DSW : public Joint3DSW {
Vector3 m_pivotInB;
public:
- virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_PIN; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_PIN; }
virtual bool setup(real_t p_step);
virtual void solve(real_t p_step);
diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.cpp b/servers/physics_3d/joints/slider_joint_3d_sw.cpp
index dd6cc04f7c..0adc471797 100644
--- a/servers/physics_3d/joints/slider_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/slider_joint_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.h b/servers/physics_3d/joints/slider_joint_3d_sw.h
index 37394a1580..f52f6ace27 100644
--- a/servers/physics_3d/joints/slider_joint_3d_sw.h
+++ b/servers/physics_3d/joints/slider_joint_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -243,7 +243,7 @@ public:
bool setup(real_t p_step);
void solve(real_t p_step);
- virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_SLIDER; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_SLIDER; }
};
#endif // SLIDER_JOINT_SW_H
diff --git a/servers/physics_3d/joints_3d_sw.h b/servers/physics_3d/joints_3d_sw.h
index 6a010ee771..225a71aca9 100644
--- a/servers/physics_3d/joints_3d_sw.h
+++ b/servers/physics_3d/joints_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,10 +36,28 @@
class Joint3DSW : public Constraint3DSW {
public:
- virtual PhysicsServer3D::JointType get_type() const = 0;
+ virtual bool setup(real_t p_step) { return false; }
+ virtual void solve(real_t p_step) {}
+
+ void copy_settings_from(Joint3DSW *p_joint) {
+ set_self(p_joint->get_self());
+ set_priority(p_joint->get_priority());
+ disable_collisions_between_bodies(p_joint->is_disabled_collisions_between_bodies());
+ }
+
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_TYPE_MAX; }
_FORCE_INLINE_ Joint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) :
Constraint3DSW(p_body_ptr, p_body_count) {
}
+
+ virtual ~Joint3DSW() {
+ for (int i = 0; i < get_body_count(); i++) {
+ Body3DSW *body = get_body_ptr()[i];
+ if (body) {
+ body->remove_constraint(this);
+ }
+ }
+ }
};
#endif // JOINTS_SW_H
diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp
index 07a7498fec..6bbef09907 100644
--- a/servers/physics_3d/physics_server_3d_sw.cpp
+++ b/servers/physics_3d/physics_server_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,47 +43,63 @@
#define FLUSH_QUERY_CHECK(m_object) \
ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead.");
-RID PhysicsServer3DSW::shape_create(ShapeType p_shape) {
- Shape3DSW *shape = nullptr;
- switch (p_shape) {
- case SHAPE_PLANE: {
- shape = memnew(PlaneShape3DSW);
- } break;
- case SHAPE_RAY: {
- shape = memnew(RayShape3DSW);
- } break;
- case SHAPE_SPHERE: {
- shape = memnew(SphereShape3DSW);
- } break;
- case SHAPE_BOX: {
- shape = memnew(BoxShape3DSW);
- } break;
- case SHAPE_CAPSULE: {
- shape = memnew(CapsuleShape3DSW);
- } break;
- case SHAPE_CYLINDER: {
- ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics3D. Please switch to Bullet in the Project Settings.");
- } break;
- case SHAPE_CONVEX_POLYGON: {
- shape = memnew(ConvexPolygonShape3DSW);
- } break;
- case SHAPE_CONCAVE_POLYGON: {
- shape = memnew(ConcavePolygonShape3DSW);
- } break;
- case SHAPE_HEIGHTMAP: {
- shape = memnew(HeightMapShape3DSW);
- } break;
- case SHAPE_CUSTOM: {
- ERR_FAIL_V(RID());
-
- } break;
- }
-
- RID id = shape_owner.make_rid(shape);
- shape->set_self(id);
-
- return id;
-};
+RID PhysicsServer3DSW::plane_shape_create() {
+ Shape3DSW *shape = memnew(PlaneShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::ray_shape_create() {
+ Shape3DSW *shape = memnew(RayShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::sphere_shape_create() {
+ Shape3DSW *shape = memnew(SphereShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::box_shape_create() {
+ Shape3DSW *shape = memnew(BoxShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::capsule_shape_create() {
+ Shape3DSW *shape = memnew(CapsuleShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::cylinder_shape_create() {
+ Shape3DSW *shape = memnew(CylinderShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::convex_polygon_shape_create() {
+ Shape3DSW *shape = memnew(ConvexPolygonShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::concave_polygon_shape_create() {
+ Shape3DSW *shape = memnew(ConcavePolygonShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::heightmap_shape_create() {
+ Shape3DSW *shape = memnew(HeightMapShape3DSW);
+ RID rid = shape_owner.make_rid(shape);
+ shape->set_self(rid);
+ return rid;
+}
+RID PhysicsServer3DSW::custom_shape_create() {
+ ERR_FAIL_V(RID());
+}
void PhysicsServer3DSW::shape_set_data(RID p_shape, const Variant &p_data) {
Shape3DSW *shape = shape_owner.getornull(p_shape);
@@ -174,7 +190,7 @@ real_t PhysicsServer3DSW::space_get_param(RID p_space, SpaceParameter p_param) c
PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space) {
Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, nullptr);
- ERR_FAIL_COND_V_MSG(space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification.");
+ ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification.");
return space->get_direct_state();
}
@@ -413,13 +429,6 @@ void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) {
area->set_ray_pickable(p_enable);
}
-bool PhysicsServer3DSW::area_is_ray_pickable(RID p_area) const {
- Area3DSW *area = area_owner.getornull(p_area);
- ERR_FAIL_COND_V(!area, false);
-
- return area->is_ray_pickable();
-}
-
void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -429,14 +438,8 @@ void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_rec
/* BODY API */
-RID PhysicsServer3DSW::body_create(BodyMode p_mode, bool p_init_sleeping) {
+RID PhysicsServer3DSW::body_create() {
Body3DSW *body = memnew(Body3DSW);
- if (p_mode != BODY_MODE_RIGID) {
- body->set_mode(p_mode);
- }
- if (p_init_sleeping) {
- body->set_state(BODY_STATE_SLEEPING, p_init_sleeping);
- }
RID rid = body_owner.make_rid(body);
body->set_self(rid);
return rid;
@@ -857,12 +860,6 @@ void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) {
body->set_ray_pickable(p_enable);
}
-bool PhysicsServer3DSW::body_is_ray_pickable(RID p_body) const {
- Body3DSW *body = body_owner.getornull(p_body);
- ERR_FAIL_COND_V(!body, false);
- return body->is_ray_pickable();
-}
-
bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) {
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
@@ -874,7 +871,7 @@ bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, co
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, body->get_kinematic_margin(), r_result, p_exclude_raycast_shapes);
}
-int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
+int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) {
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
@@ -886,6 +883,8 @@ int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_t
}
PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) {
+ ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");
+
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, nullptr);
ERR_FAIL_COND_V_MSG(body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");
@@ -896,30 +895,52 @@ PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) {
/* JOINT API */
-RID PhysicsServer3DSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
+RID PhysicsServer3DSW::joint_create() {
+ Joint3DSW *joint = memnew(Joint3DSW);
+ RID rid = joint_owner.make_rid(joint);
+ joint->set_self(rid);
+ return rid;
+}
+
+void PhysicsServer3DSW::joint_clear(RID p_joint) {
+ Joint3DSW *joint = joint_owner.getornull(p_joint);
+ if (joint->get_type() != JOINT_TYPE_MAX) {
+ Joint3DSW *empty_joint = memnew(Joint3DSW);
+ empty_joint->copy_settings_from(joint);
+
+ joint_owner.replace(p_joint, empty_joint);
+ memdelete(joint);
+ }
+}
+
+void PhysicsServer3DSW::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
Body3DSW *body_A = body_owner.getornull(p_body_A);
- ERR_FAIL_COND_V(!body_A, RID());
+ ERR_FAIL_COND(!body_A);
if (!p_body_B.is_valid()) {
- ERR_FAIL_COND_V(!body_A->get_space(), RID());
+ ERR_FAIL_COND(!body_A->get_space());
p_body_B = body_A->get_space()->get_static_global_body();
}
Body3DSW *body_B = body_owner.getornull(p_body_B);
- ERR_FAIL_COND_V(!body_B, RID());
+ ERR_FAIL_COND(!body_B);
+
+ ERR_FAIL_COND(body_A == body_B);
- ERR_FAIL_COND_V(body_A == body_B, RID());
+ Joint3DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
Joint3DSW *joint = memnew(PinJoint3DSW(body_A, p_local_A, body_B, p_local_B));
- RID rid = joint_owner.make_rid(joint);
- joint->set_self(rid);
- return rid;
+
+ joint->copy_settings_from(prev_joint);
+ joint_owner.replace(p_joint, joint);
+ memdelete(prev_joint);
}
void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
pin_joint->set_param(p_param, p_value);
}
@@ -927,7 +948,7 @@ void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param,
real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
- ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0);
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0);
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
return pin_joint->get_param(p_param);
}
@@ -935,7 +956,7 @@ real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param
void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
pin_joint->set_pos_a(p_A);
}
@@ -943,7 +964,7 @@ void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {
Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, Vector3());
- ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3());
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3());
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
return pin_joint->get_position_a();
}
@@ -951,7 +972,7 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const {
void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN);
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
pin_joint->set_pos_b(p_B);
}
@@ -959,55 +980,63 @@ void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {
Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, Vector3());
- ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3());
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3());
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
return pin_joint->get_position_b();
}
-RID PhysicsServer3DSW::joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) {
+void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) {
Body3DSW *body_A = body_owner.getornull(p_body_A);
- ERR_FAIL_COND_V(!body_A, RID());
+ ERR_FAIL_COND(!body_A);
if (!p_body_B.is_valid()) {
- ERR_FAIL_COND_V(!body_A->get_space(), RID());
+ ERR_FAIL_COND(!body_A->get_space());
p_body_B = body_A->get_space()->get_static_global_body();
}
Body3DSW *body_B = body_owner.getornull(p_body_B);
- ERR_FAIL_COND_V(!body_B, RID());
+ ERR_FAIL_COND(!body_B);
- ERR_FAIL_COND_V(body_A == body_B, RID());
+ ERR_FAIL_COND(body_A == body_B);
+
+ Joint3DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_frame_A, p_frame_B));
- RID rid = joint_owner.make_rid(joint);
- joint->set_self(rid);
- return rid;
+
+ joint->copy_settings_from(prev_joint);
+ joint_owner.replace(p_joint, joint);
+ memdelete(prev_joint);
}
-RID PhysicsServer3DSW::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) {
+void PhysicsServer3DSW::joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) {
Body3DSW *body_A = body_owner.getornull(p_body_A);
- ERR_FAIL_COND_V(!body_A, RID());
+ ERR_FAIL_COND(!body_A);
if (!p_body_B.is_valid()) {
- ERR_FAIL_COND_V(!body_A->get_space(), RID());
+ ERR_FAIL_COND(!body_A->get_space());
p_body_B = body_A->get_space()->get_static_global_body();
}
Body3DSW *body_B = body_owner.getornull(p_body_B);
- ERR_FAIL_COND_V(!body_B, RID());
+ ERR_FAIL_COND(!body_B);
+
+ ERR_FAIL_COND(body_A == body_B);
- ERR_FAIL_COND_V(body_A == body_B, RID());
+ Joint3DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B));
- RID rid = joint_owner.make_rid(joint);
- joint->set_self(rid);
- return rid;
+
+ joint->copy_settings_from(prev_joint);
+ joint_owner.replace(p_joint, joint);
+ memdelete(prev_joint);
}
void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_HINGE);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE);
HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint);
hinge_joint->set_param(p_param, p_value);
}
@@ -1015,7 +1044,7 @@ void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_par
real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
- ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0);
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0);
HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint);
return hinge_joint->get_param(p_param);
}
@@ -1023,7 +1052,7 @@ real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_p
void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_HINGE);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE);
HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint);
hinge_joint->set_flag(p_flag, p_value);
}
@@ -1031,7 +1060,7 @@ void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag,
bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, false);
- ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false);
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false);
HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint);
return hinge_joint->get_flag(p_flag);
}
@@ -1077,34 +1106,38 @@ bool PhysicsServer3DSW::joint_is_disabled_collisions_between_bodies(RID p_joint)
PhysicsServer3DSW::JointType PhysicsServer3DSW::joint_get_type(RID p_joint) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
- ERR_FAIL_COND_V(!joint, JOINT_PIN);
+ ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN);
return joint->get_type();
}
-RID PhysicsServer3DSW::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
Body3DSW *body_A = body_owner.getornull(p_body_A);
- ERR_FAIL_COND_V(!body_A, RID());
+ ERR_FAIL_COND(!body_A);
if (!p_body_B.is_valid()) {
- ERR_FAIL_COND_V(!body_A->get_space(), RID());
+ ERR_FAIL_COND(!body_A->get_space());
p_body_B = body_A->get_space()->get_static_global_body();
}
Body3DSW *body_B = body_owner.getornull(p_body_B);
- ERR_FAIL_COND_V(!body_B, RID());
+ ERR_FAIL_COND(!body_B);
+
+ ERR_FAIL_COND(body_A == body_B);
- ERR_FAIL_COND_V(body_A == body_B, RID());
+ Joint3DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
Joint3DSW *joint = memnew(SliderJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B));
- RID rid = joint_owner.make_rid(joint);
- joint->set_self(rid);
- return rid;
+
+ joint->copy_settings_from(prev_joint);
+ joint_owner.replace(p_joint, joint);
+ memdelete(prev_joint);
}
void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER);
SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint);
slider_joint->set_param(p_param, p_value);
}
@@ -1112,35 +1145,39 @@ void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_p
real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
- ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0);
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0);
SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint);
return slider_joint->get_param(p_param);
}
-RID PhysicsServer3DSW::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
Body3DSW *body_A = body_owner.getornull(p_body_A);
- ERR_FAIL_COND_V(!body_A, RID());
+ ERR_FAIL_COND(!body_A);
if (!p_body_B.is_valid()) {
- ERR_FAIL_COND_V(!body_A->get_space(), RID());
+ ERR_FAIL_COND(!body_A->get_space());
p_body_B = body_A->get_space()->get_static_global_body();
}
Body3DSW *body_B = body_owner.getornull(p_body_B);
- ERR_FAIL_COND_V(!body_B, RID());
+ ERR_FAIL_COND(!body_B);
+
+ ERR_FAIL_COND(body_A == body_B);
- ERR_FAIL_COND_V(body_A == body_B, RID());
+ Joint3DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
Joint3DSW *joint = memnew(ConeTwistJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B));
- RID rid = joint_owner.make_rid(joint);
- joint->set_self(rid);
- return rid;
+
+ joint->copy_settings_from(prev_joint);
+ joint_owner.replace(p_joint, joint);
+ memdelete(prev_joint);
}
void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST);
ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint);
cone_twist_joint->set_param(p_param, p_value);
}
@@ -1148,43 +1185,47 @@ void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointPa
real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
- ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0);
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0);
ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint);
return cone_twist_joint->get_param(p_param);
}
-RID PhysicsServer3DSW::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
Body3DSW *body_A = body_owner.getornull(p_body_A);
- ERR_FAIL_COND_V(!body_A, RID());
+ ERR_FAIL_COND(!body_A);
if (!p_body_B.is_valid()) {
- ERR_FAIL_COND_V(!body_A->get_space(), RID());
+ ERR_FAIL_COND(!body_A->get_space());
p_body_B = body_A->get_space()->get_static_global_body();
}
Body3DSW *body_B = body_owner.getornull(p_body_B);
- ERR_FAIL_COND_V(!body_B, RID());
+ ERR_FAIL_COND(!body_B);
- ERR_FAIL_COND_V(body_A == body_B, RID());
+ ERR_FAIL_COND(body_A == body_B);
+
+ Joint3DSW *prev_joint = joint_owner.getornull(p_joint);
+ ERR_FAIL_COND(prev_joint == nullptr);
Joint3DSW *joint = memnew(Generic6DOFJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B, true));
- RID rid = joint_owner.make_rid(joint);
- joint->set_self(rid);
- return rid;
+
+ joint->copy_settings_from(prev_joint);
+ joint_owner.replace(p_joint, joint);
+ memdelete(prev_joint);
}
void PhysicsServer3DSW::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_6DOF);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF);
Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint);
generic_6dof_joint->set_param(p_axis, p_param, p_value);
}
-real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) {
+real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
- ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0);
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0);
Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint);
return generic_6dof_joint->get_param(p_axis, p_param);
}
@@ -1192,15 +1233,15 @@ real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axi
void PhysicsServer3DSW::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
- ERR_FAIL_COND(joint->get_type() != JOINT_6DOF);
+ ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF);
Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint);
generic_6dof_joint->set_flag(p_axis, p_flag, p_enable);
}
-bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) {
+bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, false);
- ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false);
+ ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false);
Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint);
return generic_6dof_joint->get_flag(p_axis, p_flag);
}
@@ -1271,9 +1312,6 @@ void PhysicsServer3DSW::free(RID p_rid) {
} else if (joint_owner.owns(p_rid)) {
Joint3DSW *joint = joint_owner.getornull(p_rid);
- for (int i = 0; i < joint->get_body_count(); i++) {
- joint->get_body_ptr()[i]->remove_constraint(joint);
- }
joint_owner.free(p_rid);
memdelete(joint);
@@ -1317,6 +1355,10 @@ void PhysicsServer3DSW::step(real_t p_step) {
#endif
}
+void PhysicsServer3DSW::sync() {
+ doing_sync = true;
+};
+
void PhysicsServer3DSW::flush_queries() {
#ifndef _3D_DISABLED
@@ -1370,6 +1412,10 @@ void PhysicsServer3DSW::flush_queries() {
#endif
};
+void PhysicsServer3DSW::end_sync() {
+ doing_sync = false;
+};
+
void PhysicsServer3DSW::finish() {
memdelete(stepper);
memdelete(direct_state);
@@ -1431,14 +1477,15 @@ void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &
}
}
-PhysicsServer3DSW *PhysicsServer3DSW::singleton = nullptr;
-PhysicsServer3DSW::PhysicsServer3DSW() {
- singleton = this;
+PhysicsServer3DSW *PhysicsServer3DSW::singletonsw = nullptr;
+PhysicsServer3DSW::PhysicsServer3DSW(bool p_using_threads) {
+ singletonsw = this;
BroadPhase3DSW::create_func = BroadPhaseOctree::_create;
island_count = 0;
active_objects = 0;
collision_pairs = 0;
-
+ using_threads = p_using_threads;
active = true;
flushing_queries = false;
+ doing_sync = false;
};
diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h
index 1183bd0322..afda161fa8 100644
--- a/servers/physics_3d/physics_server_3d_sw.h
+++ b/servers/physics_3d/physics_server_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -50,6 +50,8 @@ class PhysicsServer3DSW : public PhysicsServer3D {
int active_objects;
int collision_pairs;
+ bool using_threads;
+ bool doing_sync;
bool flushing_queries;
Step3DSW *stepper;
@@ -57,20 +59,20 @@ class PhysicsServer3DSW : public PhysicsServer3D {
PhysicsDirectBodyState3DSW *direct_state;
- mutable RID_PtrOwner<Shape3DSW> shape_owner;
- mutable RID_PtrOwner<Space3DSW> space_owner;
- mutable RID_PtrOwner<Area3DSW> area_owner;
- mutable RID_PtrOwner<Body3DSW> body_owner;
- mutable RID_PtrOwner<Joint3DSW> joint_owner;
+ mutable RID_PtrOwner<Shape3DSW, true> shape_owner;
+ mutable RID_PtrOwner<Space3DSW, true> space_owner;
+ mutable RID_PtrOwner<Area3DSW, true> area_owner;
+ mutable RID_PtrOwner<Body3DSW, true> body_owner;
+ mutable RID_PtrOwner<Joint3DSW, true> joint_owner;
//void _clear_query(QuerySW *p_query);
friend class CollisionObject3DSW;
SelfList<CollisionObject3DSW>::List pending_shape_update_list;
void _update_shapes();
-public:
- static PhysicsServer3DSW *singleton;
+ static PhysicsServer3DSW *singletonsw;
+public:
struct CollCbkData {
int max;
int amount;
@@ -79,7 +81,17 @@ public:
static void _shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata);
- virtual RID shape_create(ShapeType p_shape) override;
+ virtual RID plane_shape_create() override;
+ virtual RID ray_shape_create() override;
+ virtual RID sphere_shape_create() override;
+ virtual RID box_shape_create() override;
+ virtual RID capsule_shape_create() override;
+ virtual RID cylinder_shape_create() override;
+ virtual RID convex_polygon_shape_create() override;
+ virtual RID concave_polygon_shape_create() override;
+ virtual RID heightmap_shape_create() override;
+ virtual RID custom_shape_create() override;
+
virtual void shape_set_data(RID p_shape, const Variant &p_data) override;
virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) override;
@@ -140,7 +152,6 @@ public:
virtual Transform area_get_transform(RID p_area) const override;
virtual void area_set_ray_pickable(RID p_area, bool p_enable) override;
- virtual bool area_is_ray_pickable(RID p_area) const override;
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override;
virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override;
@@ -153,7 +164,7 @@ public:
/* BODY API */
// create a body of a given type
- virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) override;
+ virtual RID body_create() override;
virtual void body_set_space(RID p_body, RID p_space) override;
virtual RID body_get_space(RID p_body) const override;
@@ -232,17 +243,16 @@ public:
virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant()) override;
virtual void body_set_ray_pickable(RID p_body, bool p_enable) override;
- virtual bool body_is_ray_pickable(RID p_body) const override;
virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override;
- virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) override;
+ virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override;
// this function only works on physics process, errors and returns null otherwise
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override;
/* SOFT BODY */
- virtual RID soft_body_create(bool p_init_sleeping = false) override { return RID(); }
+ virtual RID soft_body_create() override { return RID(); }
virtual void soft_body_update_rendering_server(RID p_body, class SoftBodyRenderingServerHandler *p_rendering_server_handler) override {}
@@ -266,49 +276,52 @@ public:
virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const override { return Vector3(); }
virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) override {}
- virtual bool soft_body_is_ray_pickable(RID p_body) const override { return false; }
virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) override {}
- virtual int soft_body_get_simulation_precision(RID p_body) override { return 0; }
+ virtual int soft_body_get_simulation_precision(RID p_body) const override { return 0; }
virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) override {}
- virtual real_t soft_body_get_total_mass(RID p_body) override { return 0.; }
+ virtual real_t soft_body_get_total_mass(RID p_body) const override { return 0.; }
virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override {}
- virtual real_t soft_body_get_linear_stiffness(RID p_body) override { return 0.; }
+ virtual real_t soft_body_get_linear_stiffness(RID p_body) const override { return 0.; }
- virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) override {}
- virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) override { return 0.; }
+ virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) override {}
+ virtual real_t soft_body_get_angular_stiffness(RID p_body) const override { return 0.; }
virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) override {}
- virtual real_t soft_body_get_volume_stiffness(RID p_body) override { return 0.; }
+ virtual real_t soft_body_get_volume_stiffness(RID p_body) const override { return 0.; }
virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override {}
- virtual real_t soft_body_get_pressure_coefficient(RID p_body) override { return 0.; }
+ virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override { return 0.; }
virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) override {}
- virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) override { return 0.; }
+ virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) const override { return 0.; }
virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) override {}
- virtual real_t soft_body_get_damping_coefficient(RID p_body) override { return 0.; }
+ virtual real_t soft_body_get_damping_coefficient(RID p_body) const override { return 0.; }
virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) override {}
- virtual real_t soft_body_get_drag_coefficient(RID p_body) override { return 0.; }
+ virtual real_t soft_body_get_drag_coefficient(RID p_body) const override { return 0.; }
virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) override {}
virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) override {}
- virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) override { return Vector3(); }
+ virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const override { return Vector3(); }
virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const override { return Vector3(); }
virtual void soft_body_remove_all_pinned_points(RID p_body) override {}
virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) override {}
- virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) override { return false; }
+ virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const override { return false; }
/* JOINT API */
- virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override;
+ virtual RID joint_create() override;
+
+ virtual void joint_clear(RID p_joint) override; //resets type
+
+ virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) override;
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) override;
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const override;
@@ -319,8 +332,8 @@ public:
virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) override;
virtual Vector3 pin_joint_get_local_b(RID p_joint) const override;
- virtual RID joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) override;
- virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override;
+ virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) override;
+ virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) override;
virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) override;
virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const override;
@@ -328,23 +341,23 @@ public:
virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) override;
virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const override;
- virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A
+ virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A
virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) override;
virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const override;
- virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A
+ virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A
virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) override;
virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const override;
- virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A
+ virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) override; //reference frame is A
virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) override;
- virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) override;
+ virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const override;
virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) override;
- virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) override;
+ virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) const override;
virtual JointType joint_get_type(RID p_joint) const override;
@@ -361,14 +374,16 @@ public:
virtual void set_active(bool p_active) override;
virtual void init() override;
virtual void step(real_t p_step) override;
+ virtual void sync() override;
virtual void flush_queries() override;
+ virtual void end_sync() override;
virtual void finish() override;
virtual bool is_flushing_queries() const override { return flushing_queries; }
int get_process_info(ProcessInfo p_info) override;
- PhysicsServer3DSW();
+ PhysicsServer3DSW(bool p_using_threads = false);
~PhysicsServer3DSW() {}
};
diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.cpp b/servers/physics_3d/physics_server_3d_wrap_mt.cpp
new file mode 100644
index 0000000000..f73f67a756
--- /dev/null
+++ b/servers/physics_3d/physics_server_3d_wrap_mt.cpp
@@ -0,0 +1,140 @@
+/*************************************************************************/
+/* physics_server_3d_wrap_mt.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "physics_server_3d_wrap_mt.h"
+
+#include "core/os/os.h"
+
+void PhysicsServer3DWrapMT::thread_exit() {
+ exit = true;
+}
+
+void PhysicsServer3DWrapMT::thread_step(real_t p_delta) {
+ physics_3d_server->step(p_delta);
+ step_sem.post();
+}
+
+void PhysicsServer3DWrapMT::_thread_callback(void *_instance) {
+ PhysicsServer3DWrapMT *vsmt = reinterpret_cast<PhysicsServer3DWrapMT *>(_instance);
+
+ vsmt->thread_loop();
+}
+
+void PhysicsServer3DWrapMT::thread_loop() {
+ server_thread = Thread::get_caller_id();
+
+ physics_3d_server->init();
+
+ exit = false;
+ step_thread_up = true;
+ while (!exit) {
+ // flush commands one by one, until exit is requested
+ command_queue.wait_and_flush_one();
+ }
+
+ command_queue.flush_all(); // flush all
+
+ physics_3d_server->finish();
+}
+
+/* EVENT QUEUING */
+
+void PhysicsServer3DWrapMT::step(real_t p_step) {
+ if (create_thread) {
+ command_queue.push(this, &PhysicsServer3DWrapMT::thread_step, p_step);
+ } else {
+ command_queue.flush_all(); //flush all pending from other threads
+ physics_3d_server->step(p_step);
+ }
+}
+
+void PhysicsServer3DWrapMT::sync() {
+ if (create_thread) {
+ if (first_frame) {
+ first_frame = false;
+ } else {
+ step_sem.wait(); //must not wait if a step was not issued
+ }
+ }
+ physics_3d_server->sync();
+}
+
+void PhysicsServer3DWrapMT::flush_queries() {
+ physics_3d_server->flush_queries();
+}
+
+void PhysicsServer3DWrapMT::end_sync() {
+ physics_3d_server->end_sync();
+}
+
+void PhysicsServer3DWrapMT::init() {
+ if (create_thread) {
+ //OS::get_singleton()->release_rendering_thread();
+ thread.start(_thread_callback, this);
+ while (!step_thread_up) {
+ OS::get_singleton()->delay_usec(1000);
+ }
+ } else {
+ physics_3d_server->init();
+ }
+}
+
+void PhysicsServer3DWrapMT::finish() {
+ if (thread.is_started()) {
+ command_queue.push(this, &PhysicsServer3DWrapMT::thread_exit);
+ thread.wait_to_finish();
+ } else {
+ physics_3d_server->finish();
+ }
+}
+
+PhysicsServer3DWrapMT::PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread) :
+ command_queue(p_create_thread) {
+ physics_3d_server = p_contained;
+ create_thread = p_create_thread;
+ step_pending = 0;
+ step_thread_up = false;
+
+ pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+
+ if (!p_create_thread) {
+ server_thread = Thread::get_caller_id();
+ } else {
+ server_thread = 0;
+ }
+
+ main_thread = Thread::get_caller_id();
+ first_frame = true;
+}
+
+PhysicsServer3DWrapMT::~PhysicsServer3DWrapMT() {
+ memdelete(physics_3d_server);
+ //finish();
+}
diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.h b/servers/physics_3d/physics_server_3d_wrap_mt.h
new file mode 100644
index 0000000000..f60e1332d5
--- /dev/null
+++ b/servers/physics_3d/physics_server_3d_wrap_mt.h
@@ -0,0 +1,422 @@
+/*************************************************************************/
+/* physics_server_3d_wrap_mt.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef PHYSICS3DSERVERWRAPMT_H
+#define PHYSICS3DSERVERWRAPMT_H
+
+#include "core/config/project_settings.h"
+#include "core/os/thread.h"
+#include "core/templates/command_queue_mt.h"
+#include "servers/physics_server_3d.h"
+
+#ifdef DEBUG_SYNC
+#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__));
+#else
+#define SYNC_DEBUG
+#endif
+
+class PhysicsServer3DWrapMT : public PhysicsServer3D {
+ mutable PhysicsServer3D *physics_3d_server;
+
+ mutable CommandQueueMT command_queue;
+
+ static void _thread_callback(void *_instance);
+ void thread_loop();
+
+ Thread::ID server_thread;
+ Thread::ID main_thread;
+ volatile bool exit = false;
+ Thread thread;
+ volatile bool step_thread_up = false;
+ bool create_thread = false;
+
+ Semaphore step_sem;
+ int step_pending;
+ void thread_step(real_t p_delta);
+ void thread_flush();
+
+ void thread_exit();
+
+ bool first_frame = true;
+
+ Mutex alloc_mutex;
+ int pool_max_size = 0;
+
+public:
+#define ServerName PhysicsServer3D
+#define ServerNameWrapMT PhysicsServer3DWrapMT
+#define server_name physics_3d_server
+#define WRITE_ACTION
+
+#include "servers/server_wrap_mt_common.h"
+
+ //FUNC1RID(shape,ShapeType); todo fix
+ FUNCRID(plane_shape)
+ FUNCRID(ray_shape)
+ FUNCRID(sphere_shape)
+ FUNCRID(box_shape)
+ FUNCRID(capsule_shape)
+ FUNCRID(cylinder_shape)
+ FUNCRID(convex_polygon_shape)
+ FUNCRID(concave_polygon_shape)
+ FUNCRID(heightmap_shape)
+ FUNCRID(custom_shape)
+
+ FUNC2(shape_set_data, RID, const Variant &);
+ FUNC2(shape_set_custom_solver_bias, RID, real_t);
+
+ FUNC2(shape_set_margin, RID, real_t)
+ FUNC1RC(real_t, shape_get_margin, RID)
+
+ FUNC1RC(ShapeType, shape_get_type, RID);
+ FUNC1RC(Variant, shape_get_data, RID);
+ FUNC1RC(real_t, shape_get_custom_solver_bias, RID);
+#if 0
+ //these work well, but should be used from the main thread only
+ bool shape_collide(RID p_shape_A, const Transform &p_xform_A, const Vector3 &p_motion_A, RID p_shape_B, const Transform &p_xform_B, const Vector3 &p_motion_B, Vector3 *r_results, int p_result_max, int &r_result_count) {
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
+ return physics_3d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count);
+ }
+#endif
+ /* SPACE API */
+
+ FUNCRID(space);
+ FUNC2(space_set_active, RID, bool);
+ FUNC1RC(bool, space_is_active, RID);
+
+ FUNC3(space_set_param, RID, SpaceParameter, real_t);
+ FUNC2RC(real_t, space_get_param, RID, SpaceParameter);
+
+ // this function only works on physics process, errors and returns null otherwise
+ PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space) override {
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
+ return physics_3d_server->space_get_direct_state(p_space);
+ }
+
+ FUNC2(space_set_debug_contacts, RID, int);
+ virtual Vector<Vector3> space_get_contacts(RID p_space) const override {
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector3>());
+ return physics_3d_server->space_get_contacts(p_space);
+ }
+
+ virtual int space_get_contact_count(RID p_space) const override {
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0);
+ return physics_3d_server->space_get_contact_count(p_space);
+ }
+
+ /* AREA API */
+
+ //FUNC0RID(area);
+ FUNCRID(area);
+
+ FUNC2(area_set_space, RID, RID);
+ FUNC1RC(RID, area_get_space, RID);
+
+ FUNC2(area_set_space_override_mode, RID, AreaSpaceOverrideMode);
+ FUNC1RC(AreaSpaceOverrideMode, area_get_space_override_mode, RID);
+
+ FUNC4(area_add_shape, RID, RID, const Transform &, bool);
+ FUNC3(area_set_shape, RID, int, RID);
+ FUNC3(area_set_shape_transform, RID, int, const Transform &);
+ FUNC3(area_set_shape_disabled, RID, int, bool);
+
+ FUNC1RC(int, area_get_shape_count, RID);
+ FUNC2RC(RID, area_get_shape, RID, int);
+ FUNC2RC(Transform, area_get_shape_transform, RID, int);
+ FUNC2(area_remove_shape, RID, int);
+ FUNC1(area_clear_shapes, RID);
+
+ FUNC2(area_attach_object_instance_id, RID, ObjectID);
+ FUNC1RC(ObjectID, area_get_object_instance_id, RID);
+
+ FUNC3(area_set_param, RID, AreaParameter, const Variant &);
+ FUNC2(area_set_transform, RID, const Transform &);
+
+ FUNC2RC(Variant, area_get_param, RID, AreaParameter);
+ FUNC1RC(Transform, area_get_transform, RID);
+
+ FUNC2(area_set_collision_mask, RID, uint32_t);
+ FUNC2(area_set_collision_layer, RID, uint32_t);
+
+ FUNC2(area_set_monitorable, RID, bool);
+ FUNC2(area_set_ray_pickable, RID, bool);
+
+ FUNC3(area_set_monitor_callback, RID, Object *, const StringName &);
+ FUNC3(area_set_area_monitor_callback, RID, Object *, const StringName &);
+
+ /* BODY API */
+
+ //FUNC2RID(body,BodyMode,bool);
+ FUNCRID(body)
+
+ FUNC2(body_set_space, RID, RID);
+ FUNC1RC(RID, body_get_space, RID);
+
+ FUNC2(body_set_mode, RID, BodyMode);
+ FUNC1RC(BodyMode, body_get_mode, RID);
+
+ FUNC4(body_add_shape, RID, RID, const Transform &, bool);
+ FUNC3(body_set_shape, RID, int, RID);
+ FUNC3(body_set_shape_transform, RID, int, const Transform &);
+
+ FUNC1RC(int, body_get_shape_count, RID);
+ FUNC2RC(Transform, body_get_shape_transform, RID, int);
+ FUNC2RC(RID, body_get_shape, RID, int);
+
+ FUNC3(body_set_shape_disabled, RID, int, bool);
+
+ FUNC2(body_remove_shape, RID, int);
+ FUNC1(body_clear_shapes, RID);
+
+ FUNC2(body_attach_object_instance_id, RID, ObjectID);
+ FUNC1RC(ObjectID, body_get_object_instance_id, RID);
+
+ FUNC2(body_set_enable_continuous_collision_detection, RID, bool);
+ FUNC1RC(bool, body_is_continuous_collision_detection_enabled, RID);
+
+ FUNC2(body_set_collision_layer, RID, uint32_t);
+ FUNC1RC(uint32_t, body_get_collision_layer, RID);
+
+ FUNC2(body_set_collision_mask, RID, uint32_t);
+ FUNC1RC(uint32_t, body_get_collision_mask, RID);
+
+ FUNC2(body_set_user_flags, RID, uint32_t);
+ FUNC1RC(uint32_t, body_get_user_flags, RID);
+
+ FUNC3(body_set_param, RID, BodyParameter, real_t);
+ FUNC2RC(real_t, body_get_param, RID, BodyParameter);
+
+ FUNC2(body_set_kinematic_safe_margin, RID, real_t);
+ FUNC1RC(real_t, body_get_kinematic_safe_margin, RID);
+
+ FUNC3(body_set_state, RID, BodyState, const Variant &);
+ FUNC2RC(Variant, body_get_state, RID, BodyState);
+
+ FUNC2(body_set_applied_force, RID, const Vector3 &);
+ FUNC1RC(Vector3, body_get_applied_force, RID);
+
+ FUNC2(body_set_applied_torque, RID, const Vector3 &);
+ FUNC1RC(Vector3, body_get_applied_torque, RID);
+
+ FUNC2(body_add_central_force, RID, const Vector3 &);
+ FUNC3(body_add_force, RID, const Vector3 &, const Vector3 &);
+ FUNC2(body_add_torque, RID, const Vector3 &);
+ FUNC2(body_apply_torque_impulse, RID, const Vector3 &);
+ FUNC2(body_apply_central_impulse, RID, const Vector3 &);
+ FUNC3(body_apply_impulse, RID, const Vector3 &, const Vector3 &);
+ FUNC2(body_set_axis_velocity, RID, const Vector3 &);
+
+ FUNC3(body_set_axis_lock, RID, BodyAxis, bool);
+ FUNC2RC(bool, body_is_axis_locked, RID, BodyAxis);
+
+ FUNC2(body_add_collision_exception, RID, RID);
+ FUNC2(body_remove_collision_exception, RID, RID);
+ FUNC2S(body_get_collision_exceptions, RID, List<RID> *);
+
+ FUNC2(body_set_max_contacts_reported, RID, int);
+ FUNC1RC(int, body_get_max_contacts_reported, RID);
+
+ FUNC2(body_set_contacts_reported_depth_threshold, RID, real_t);
+ FUNC1RC(real_t, body_get_contacts_reported_depth_threshold, RID);
+
+ FUNC2(body_set_omit_force_integration, RID, bool);
+ FUNC1RC(bool, body_is_omitting_force_integration, RID);
+
+ FUNC4(body_set_force_integration_callback, RID, Object *, const StringName &, const Variant &);
+
+ FUNC2(body_set_ray_pickable, RID, bool);
+
+ bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) override {
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
+ return physics_3d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes);
+ }
+
+ int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) override {
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
+ return physics_3d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
+ }
+
+ // this function only works on physics process, errors and returns null otherwise
+ PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) override {
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
+ return physics_3d_server->body_get_direct_state(p_body);
+ }
+
+ /* SOFT BODY API */
+
+ FUNCRID(soft_body)
+
+ FUNC2(soft_body_update_rendering_server, RID, class SoftBodyRenderingServerHandler *)
+
+ FUNC2(soft_body_set_space, RID, RID)
+ FUNC1RC(RID, soft_body_get_space, RID)
+
+ FUNC2(soft_body_set_ray_pickable, RID, bool);
+
+ FUNC2(soft_body_set_collision_layer, RID, uint32_t)
+ FUNC1RC(uint32_t, soft_body_get_collision_layer, RID)
+
+ FUNC2(soft_body_set_collision_mask, RID, uint32_t)
+ FUNC1RC(uint32_t, soft_body_get_collision_mask, RID)
+
+ FUNC2(soft_body_add_collision_exception, RID, RID)
+ FUNC2(soft_body_remove_collision_exception, RID, RID)
+ FUNC2S(soft_body_get_collision_exceptions, RID, List<RID> *)
+
+ FUNC3(soft_body_set_state, RID, BodyState, const Variant &);
+ FUNC2RC(Variant, soft_body_get_state, RID, BodyState);
+
+ FUNC2(soft_body_set_transform, RID, const Transform &);
+ FUNC2RC(Vector3, soft_body_get_vertex_position, RID, int);
+
+ FUNC2(soft_body_set_simulation_precision, RID, int);
+ FUNC1RC(int, soft_body_get_simulation_precision, RID);
+
+ FUNC2(soft_body_set_total_mass, RID, real_t);
+ FUNC1RC(real_t, soft_body_get_total_mass, RID);
+
+ FUNC2(soft_body_set_linear_stiffness, RID, real_t);
+ FUNC1RC(real_t, soft_body_get_linear_stiffness, RID);
+
+ FUNC2(soft_body_set_angular_stiffness, RID, real_t);
+ FUNC1RC(real_t, soft_body_get_angular_stiffness, RID);
+
+ FUNC2(soft_body_set_volume_stiffness, RID, real_t);
+ FUNC1RC(real_t, soft_body_get_volume_stiffness, RID);
+
+ FUNC2(soft_body_set_pressure_coefficient, RID, real_t);
+ FUNC1RC(real_t, soft_body_get_pressure_coefficient, RID);
+
+ FUNC2(soft_body_set_pose_matching_coefficient, RID, real_t);
+ FUNC1RC(real_t, soft_body_get_pose_matching_coefficient, RID);
+
+ FUNC2(soft_body_set_damping_coefficient, RID, real_t);
+ FUNC1RC(real_t, soft_body_get_damping_coefficient, RID);
+
+ FUNC2(soft_body_set_drag_coefficient, RID, real_t);
+ FUNC1RC(real_t, soft_body_get_drag_coefficient, RID);
+
+ FUNC2(soft_body_set_mesh, RID, const REF &);
+
+ FUNC3(soft_body_move_point, RID, int, const Vector3 &);
+ FUNC2RC(Vector3, soft_body_get_point_global_position, RID, int);
+ FUNC2RC(Vector3, soft_body_get_point_offset, RID, int);
+
+ FUNC1(soft_body_remove_all_pinned_points, RID);
+ FUNC3(soft_body_pin_point, RID, int, bool);
+ FUNC2RC(bool, soft_body_is_point_pinned, RID, int);
+
+ /* JOINT API */
+
+ FUNCRID(joint)
+
+ FUNC1(joint_clear, RID)
+
+ FUNC5(joint_make_pin, RID, RID, const Vector3 &, RID, const Vector3 &)
+
+ FUNC3(pin_joint_set_param, RID, PinJointParam, real_t)
+ FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam)
+
+ FUNC2(pin_joint_set_local_a, RID, const Vector3 &)
+ FUNC1RC(Vector3, pin_joint_get_local_a, RID)
+
+ FUNC2(pin_joint_set_local_b, RID, const Vector3 &)
+ FUNC1RC(Vector3, pin_joint_get_local_b, RID)
+
+ FUNC5(joint_make_hinge, RID, RID, const Transform &, RID, const Transform &)
+ FUNC7(joint_make_hinge_simple, RID, RID, const Vector3 &, const Vector3 &, RID, const Vector3 &, const Vector3 &)
+
+ FUNC3(hinge_joint_set_param, RID, HingeJointParam, real_t)
+ FUNC2RC(real_t, hinge_joint_get_param, RID, HingeJointParam)
+
+ FUNC3(hinge_joint_set_flag, RID, HingeJointFlag, bool)
+ FUNC2RC(bool, hinge_joint_get_flag, RID, HingeJointFlag)
+
+ FUNC5(joint_make_slider, RID, RID, const Transform &, RID, const Transform &)
+
+ FUNC3(slider_joint_set_param, RID, SliderJointParam, real_t)
+ FUNC2RC(real_t, slider_joint_get_param, RID, SliderJointParam)
+
+ FUNC5(joint_make_cone_twist, RID, RID, const Transform &, RID, const Transform &)
+
+ FUNC3(cone_twist_joint_set_param, RID, ConeTwistJointParam, real_t)
+ FUNC2RC(real_t, cone_twist_joint_get_param, RID, ConeTwistJointParam)
+
+ FUNC5(joint_make_generic_6dof, RID, RID, const Transform &, RID, const Transform &)
+
+ FUNC4(generic_6dof_joint_set_param, RID, Vector3::Axis, G6DOFJointAxisParam, real_t)
+ FUNC3RC(real_t, generic_6dof_joint_get_param, RID, Vector3::Axis, G6DOFJointAxisParam)
+
+ FUNC4(generic_6dof_joint_set_flag, RID, Vector3::Axis, G6DOFJointAxisFlag, bool)
+ FUNC3RC(bool, generic_6dof_joint_get_flag, RID, Vector3::Axis, G6DOFJointAxisFlag)
+
+ FUNC1RC(JointType, joint_get_type, RID);
+
+ FUNC2(joint_set_solver_priority, RID, int);
+ FUNC1RC(int, joint_get_solver_priority, RID);
+
+ FUNC2(joint_disable_collisions_between_bodies, RID, const bool);
+ FUNC1RC(bool, joint_is_disabled_collisions_between_bodies, RID);
+
+ /* MISC */
+
+ FUNC1(free, RID);
+ FUNC1(set_active, bool);
+
+ virtual void init() override;
+ virtual void step(real_t p_step) override;
+ virtual void sync() override;
+ virtual void end_sync() override;
+ virtual void flush_queries() override;
+ virtual void finish() override;
+
+ virtual bool is_flushing_queries() const override {
+ return physics_3d_server->is_flushing_queries();
+ }
+
+ int get_process_info(ProcessInfo p_info) override {
+ return physics_3d_server->get_process_info(p_info);
+ }
+
+ PhysicsServer3DWrapMT(PhysicsServer3D *p_contained, bool p_create_thread);
+ ~PhysicsServer3DWrapMT();
+
+#undef ServerNameWrapMT
+#undef ServerName
+#undef server_name
+#undef WRITE_ACTION
+};
+
+#ifdef DEBUG_SYNC
+#undef DEBUG_SYNC
+#endif
+#undef SYNC_DEBUG
+
+#endif // PHYSICS3DSERVERWRAPMT_H
diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp
index 107f850ebd..02d0c66215 100644
--- a/servers/physics_3d/shape_3d_sw.cpp
+++ b/servers/physics_3d/shape_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,10 +34,12 @@
#include "core/math/quick_hull.h"
#include "core/templates/sort_array.h"
-#define _POINT_SNAP 0.001953125
#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002
#define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.9998
+#define _CYLINDER_EDGE_IS_VALID_SUPPORT_THRESHOLD 0.002
+#define _CYLINDER_FACE_IS_VALID_SUPPORT_THRESHOLD 0.999
+
void Shape3DSW::configure(const AABB &p_aabb) {
aabb = p_aabb;
configured = true;
@@ -50,7 +52,8 @@ void Shape3DSW::configure(const AABB &p_aabb) {
Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const {
Vector3 res;
int amnt;
- get_supports(p_normal, 1, &res, amnt);
+ FeatureType type;
+ get_supports(p_normal, 1, &res, amnt, type);
return res;
}
@@ -167,16 +170,19 @@ Vector3 RayShape3DSW::get_support(const Vector3 &p_normal) const {
}
}
-void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
+void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const {
if (Math::abs(p_normal.z) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 2;
+ r_type = FEATURE_EDGE;
r_supports[0] = Vector3(0, 0, 0);
r_supports[1] = Vector3(0, 0, length);
} else if (p_normal.z > 0) {
r_amount = 1;
+ r_type = FEATURE_POINT;
*r_supports = Vector3(0, 0, length);
} else {
r_amount = 1;
+ r_type = FEATURE_POINT;
*r_supports = Vector3(0, 0, 0);
}
}
@@ -246,9 +252,10 @@ Vector3 SphereShape3DSW::get_support(const Vector3 &p_normal) const {
return p_normal * radius;
}
-void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
+void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const {
*r_supports = p_normal * radius;
r_amount = 1;
+ r_type = FEATURE_POINT;
}
bool SphereShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
@@ -261,7 +268,7 @@ bool SphereShape3DSW::intersect_point(const Vector3 &p_point) const {
Vector3 SphereShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
Vector3 p = p_point;
- float l = p.length();
+ real_t l = p.length();
if (l < radius) {
return p_point;
}
@@ -312,7 +319,7 @@ Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const {
return point;
}
-void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
+void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const {
static const int next[3] = { 1, 2, 0 };
static const int next2[3] = { 2, 0, 1 };
@@ -325,6 +332,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s
bool neg = dot < 0;
r_amount = 4;
+ r_type = FEATURE_FACE;
Vector3 point;
point[i] = half_extents[i];
@@ -362,6 +370,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s
if (Math::abs(p_normal.dot(axis)) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 2;
+ r_type = FEATURE_EDGE;
int i_n = next[i];
int i_n2 = next2[i];
@@ -389,6 +398,7 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s
(p_normal.z < 0) ? -half_extents.z : half_extents.z);
r_amount = 1;
+ r_type = FEATURE_POINT;
r_supports[0] = point;
}
@@ -429,7 +439,7 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
}
//check segments
- float min_distance = 1e20;
+ real_t min_distance = 1e20;
Vector3 closest_vertex = half_extents * p_point.sign();
Vector3 s[2] = {
closest_vertex,
@@ -442,7 +452,7 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
Vector3 closest_edge = Geometry3D::get_closest_point_to_segment(p_point, s);
- float d = p_point.distance_to(closest_edge);
+ real_t d = p_point.distance_to(closest_edge);
if (d < min_distance) {
min_point = closest_edge;
min_distance = d;
@@ -481,10 +491,10 @@ BoxShape3DSW::BoxShape3DSW() {
void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
Vector3 n = p_transform.basis.xform_inv(p_normal).normalized();
- real_t h = (n.z > 0) ? height : -height;
+ real_t h = (n.y > 0) ? height : -height;
n *= radius;
- n.z += h * 0.5;
+ n.y += h * 0.5;
r_max = p_normal.dot(p_transform.xform(n));
r_min = p_normal.dot(p_transform.xform(-n));
@@ -493,36 +503,38 @@ void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform &p
Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const {
Vector3 n = p_normal;
- real_t h = (n.z > 0) ? height : -height;
+ real_t h = (n.y > 0) ? height : -height;
n *= radius;
- n.z += h * 0.5;
+ n.y += h * 0.5;
return n;
}
-void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
+void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const {
Vector3 n = p_normal;
- real_t d = n.z;
+ real_t d = n.y;
if (Math::abs(d) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
// make it flat
- n.z = 0.0;
+ n.y = 0.0;
n.normalize();
n *= radius;
r_amount = 2;
+ r_type = FEATURE_EDGE;
r_supports[0] = n;
- r_supports[0].z += height * 0.5;
+ r_supports[0].y += height * 0.5;
r_supports[1] = n;
- r_supports[1].z -= height * 0.5;
+ r_supports[1].y -= height * 0.5;
} else {
real_t h = (d > 0) ? height : -height;
n *= radius;
- n.z += h * 0.5;
+ n.y += h * 0.5;
r_amount = 1;
+ r_type = FEATURE_POINT;
*r_supports = n;
}
}
@@ -539,7 +551,7 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &
// test against cylinder and spheres :-|
- collided = Geometry3D::segment_intersects_cylinder(p_begin, p_end, height, radius, &auxres, &auxn);
+ collided = Geometry3D::segment_intersects_cylinder(p_begin, p_end, height, radius, &auxres, &auxn, 1);
if (collided) {
real_t d = norm.dot(auxres);
@@ -551,7 +563,7 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &
}
}
- collided = Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(0, 0, height * 0.5), radius, &auxres, &auxn);
+ collided = Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(0, height * 0.5, 0), radius, &auxres, &auxn);
if (collided) {
real_t d = norm.dot(auxres);
@@ -563,7 +575,7 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &
}
}
- collided = Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(0, 0, height * -0.5), radius, &auxres, &auxn);
+ collided = Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(0, height * -0.5, 0), radius, &auxres, &auxn);
if (collided) {
real_t d = norm.dot(auxres);
@@ -584,19 +596,19 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &
}
bool CapsuleShape3DSW::intersect_point(const Vector3 &p_point) const {
- if (Math::abs(p_point.z) < height * 0.5) {
- return Vector3(p_point.x, p_point.y, 0).length() < radius;
+ if (Math::abs(p_point.y) < height * 0.5) {
+ return Vector3(p_point.x, 0, p_point.z).length() < radius;
} else {
Vector3 p = p_point;
- p.z = Math::abs(p.z) - height * 0.5;
+ p.y = Math::abs(p.y) - height * 0.5;
return p.length() < radius;
}
}
Vector3 CapsuleShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
Vector3 s[2] = {
- Vector3(0, 0, -height * 0.5),
- Vector3(0, 0, height * 0.5),
+ Vector3(0, -height * 0.5, 0),
+ Vector3(0, height * 0.5, 0),
};
Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, s);
@@ -621,7 +633,7 @@ Vector3 CapsuleShape3DSW::get_moment_of_inertia(real_t p_mass) const {
void CapsuleShape3DSW::_setup(real_t p_height, real_t p_radius) {
height = p_height;
radius = p_radius;
- configure(AABB(Vector3(-radius, -radius, -height * 0.5 - radius), Vector3(radius * 2, radius * 2, height + radius * 2.0)));
+ configure(AABB(Vector3(-radius, -height * 0.5 - radius, -radius), Vector3(radius * 2, height + radius * 2.0, radius * 2)));
}
void CapsuleShape3DSW::set_data(const Variant &p_data) {
@@ -642,6 +654,186 @@ CapsuleShape3DSW::CapsuleShape3DSW() {
height = radius = 0;
}
+/********** CYLINDER *************/
+
+void CylinderShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
+ Vector3 cylinder_axis = p_transform.basis.get_axis(1).normalized();
+ real_t axis_dot = cylinder_axis.dot(p_normal);
+
+ Vector3 local_normal = p_transform.basis.xform_inv(p_normal);
+ real_t scale = local_normal.length();
+ real_t scaled_radius = radius * scale;
+ real_t scaled_height = height * scale;
+
+ real_t length;
+ if (Math::abs(axis_dot) > 1.0) {
+ length = scaled_height * 0.5;
+ } else {
+ length = Math::abs(axis_dot * scaled_height * 0.5) + scaled_radius * Math::sqrt(1.0 - axis_dot * axis_dot);
+ }
+
+ real_t distance = p_normal.dot(p_transform.origin);
+
+ r_min = distance - length;
+ r_max = distance + length;
+}
+
+Vector3 CylinderShape3DSW::get_support(const Vector3 &p_normal) const {
+ Vector3 n = p_normal;
+ real_t h = (n.y > 0) ? height : -height;
+ real_t s = Math::sqrt(n.x * n.x + n.z * n.z);
+ if (Math::is_zero_approx(s)) {
+ n.x = radius;
+ n.y = h * 0.5;
+ n.z = 0.0;
+ } else {
+ real_t d = radius / s;
+ n.x = n.x * d;
+ n.y = h * 0.5;
+ n.z = n.z * d;
+ }
+
+ return n;
+}
+
+void CylinderShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const {
+ real_t d = p_normal.y;
+ if (Math::abs(d) > _CYLINDER_FACE_IS_VALID_SUPPORT_THRESHOLD) {
+ real_t h = (d > 0) ? height : -height;
+
+ Vector3 n = p_normal;
+ n.x = 0.0;
+ n.z = 0.0;
+ n.y = h * 0.5;
+
+ r_amount = 3;
+ r_type = FEATURE_CIRCLE;
+ r_supports[0] = n;
+ r_supports[1] = n;
+ r_supports[1].x += radius;
+ r_supports[2] = n;
+ r_supports[2].z += radius;
+ } else if (Math::abs(d) < _CYLINDER_EDGE_IS_VALID_SUPPORT_THRESHOLD) {
+ // make it flat
+ Vector3 n = p_normal;
+ n.y = 0.0;
+ n.normalize();
+ n *= radius;
+
+ r_amount = 2;
+ r_type = FEATURE_EDGE;
+ r_supports[0] = n;
+ r_supports[0].y += height * 0.5;
+ r_supports[1] = n;
+ r_supports[1].y -= height * 0.5;
+ } else {
+ r_amount = 1;
+ r_type = FEATURE_POINT;
+ r_supports[0] = get_support(p_normal);
+ return;
+
+ Vector3 n = p_normal;
+ real_t h = n.y * Math::sqrt(0.25 * height * height + radius * radius);
+ if (Math::abs(h) > 1.0) {
+ // Top or bottom surface.
+ n.y = (n.y > 0.0) ? height * 0.5 : -height * 0.5;
+ } else {
+ // Lateral surface.
+ n.y = height * 0.5 * h;
+ }
+
+ real_t s = Math::sqrt(n.x * n.x + n.z * n.z);
+ if (Math::is_zero_approx(s)) {
+ n.x = 0.0;
+ n.z = 0.0;
+ } else {
+ real_t scaled_radius = radius / s;
+ n.x = n.x * scaled_radius;
+ n.z = n.z * scaled_radius;
+ }
+
+ r_supports[0] = n;
+ }
+}
+
+bool CylinderShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
+ return Geometry3D::segment_intersects_cylinder(p_begin, p_end, height, radius, &r_result, &r_normal, 1);
+}
+
+bool CylinderShape3DSW::intersect_point(const Vector3 &p_point) const {
+ if (Math::abs(p_point.y) < height * 0.5) {
+ return Vector3(p_point.x, 0, p_point.z).length() < radius;
+ }
+ return false;
+}
+
+Vector3 CylinderShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
+ if (Math::absf(p_point.y) > height * 0.5) {
+ // Project point to top disk.
+ real_t dir = p_point.y > 0.0 ? 1.0 : -1.0;
+ Vector3 circle_pos(0.0, dir * height * 0.5, 0.0);
+ Plane circle_plane(circle_pos, Vector3(0.0, dir, 0.0));
+ Vector3 proj_point = circle_plane.project(p_point);
+
+ // Clip position.
+ Vector3 delta_point_1 = proj_point - circle_pos;
+ real_t dist_point_1 = delta_point_1.length_squared();
+ if (!Math::is_zero_approx(dist_point_1)) {
+ dist_point_1 = Math::sqrt(dist_point_1);
+ proj_point = circle_pos + delta_point_1 * MIN(dist_point_1, radius) / dist_point_1;
+ }
+
+ return proj_point;
+ } else {
+ Vector3 s[2] = {
+ Vector3(0, -height * 0.5, 0),
+ Vector3(0, height * 0.5, 0),
+ };
+
+ Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, s);
+
+ if (p.distance_to(p_point) < radius) {
+ return p_point;
+ }
+
+ return p + (p_point - p).normalized() * radius;
+ }
+}
+
+Vector3 CylinderShape3DSW::get_moment_of_inertia(real_t p_mass) const {
+ // use bad AABB approximation
+ Vector3 extents = get_aabb().size * 0.5;
+
+ return Vector3(
+ (p_mass / 3.0) * (extents.y * extents.y + extents.z * extents.z),
+ (p_mass / 3.0) * (extents.x * extents.x + extents.z * extents.z),
+ (p_mass / 3.0) * (extents.y * extents.y + extents.y * extents.y));
+}
+
+void CylinderShape3DSW::_setup(real_t p_height, real_t p_radius) {
+ height = p_height;
+ radius = p_radius;
+ configure(AABB(Vector3(-radius, -height * 0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0)));
+}
+
+void CylinderShape3DSW::set_data(const Variant &p_data) {
+ Dictionary d = p_data;
+ ERR_FAIL_COND(!d.has("radius"));
+ ERR_FAIL_COND(!d.has("height"));
+ _setup(d["height"], d["radius"]);
+}
+
+Variant CylinderShape3DSW::get_data() const {
+ Dictionary d;
+ d["radius"] = radius;
+ d["height"] = height;
+ return d;
+}
+
+CylinderShape3DSW::CylinderShape3DSW() {
+ height = radius = 0;
+}
+
/********** CONVEX POLYGON *************/
void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
@@ -689,7 +881,7 @@ Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const {
return vrts[vert_support_idx];
}
-void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
+void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const {
const Geometry3D::MeshData::Face *faces = mesh.faces.ptr();
int fc = mesh.faces.size();
@@ -734,6 +926,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
r_supports[j] = vertices[ind[j]];
}
r_amount = m;
+ r_type = FEATURE_FACE;
return;
}
}
@@ -743,6 +936,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
dot = ABS(dot);
if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD && (edges[i].a == vtx || edges[i].b == vtx)) {
r_amount = 2;
+ r_type = FEATURE_EDGE;
r_supports[0] = vertices[edges[i].a];
r_supports[1] = vertices[edges[i].b];
return;
@@ -751,6 +945,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
r_supports[0] = vertices[vtx];
r_amount = 1;
+ r_type = FEATURE_POINT;
}
bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
@@ -839,7 +1034,7 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con
return p_point;
}
- float min_distance = 1e20;
+ real_t min_distance = 1e20;
Vector3 min_point;
//check edges
@@ -852,7 +1047,7 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con
};
Vector3 closest = Geometry3D::get_closest_point_to_segment(p_point, s);
- float d = closest.distance_to(p_point);
+ real_t d = closest.distance_to(p_point);
if (d < min_distance) {
min_distance = d;
min_point = closest;
@@ -935,12 +1130,13 @@ Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const {
return vertex[vert_support_idx];
}
-void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
+void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const {
Vector3 n = p_normal;
/** TEST FACE AS SUPPORT **/
if (normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 3;
+ r_type = FEATURE_FACE;
for (int i = 0; i < 3; i++) {
r_supports[i] = vertex[i];
}
@@ -974,6 +1170,7 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_
dot = ABS(dot);
if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 2;
+ r_type = FEATURE_EDGE;
r_supports[0] = vertex[i];
r_supports[1] = vertex[nx];
return;
@@ -981,6 +1178,7 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_
}
r_amount = 1;
+ r_type = FEATURE_POINT;
r_supports[0] = vertex[vert_support_idx];
}
diff --git a/servers/physics_3d/shape_3d_sw.h b/servers/physics_3d/shape_3d_sw.h
index 2a2cd42255..cafe978abb 100644
--- a/servers/physics_3d/shape_3d_sw.h
+++ b/servers/physics_3d/shape_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -67,8 +67,11 @@ protected:
void configure(const AABB &p_aabb);
public:
- enum {
- MAX_SUPPORTS = 8
+ enum FeatureType {
+ FEATURE_POINT,
+ FEATURE_EDGE,
+ FEATURE_FACE,
+ FEATURE_CIRCLE,
};
virtual real_t get_area() const { return aabb.get_area(); }
@@ -85,7 +88,7 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const = 0;
virtual Vector3 get_support(const Vector3 &p_normal) const;
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const = 0;
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const = 0;
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const = 0;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const = 0;
virtual bool intersect_point(const Vector3 &p_point) const = 0;
@@ -110,7 +113,7 @@ class ConcaveShape3DSW : public Shape3DSW {
public:
virtual bool is_concave() const { return true; }
typedef void (*Callback)(void *p_userdata, Shape3DSW *p_convex);
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; }
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; }
virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const = 0;
@@ -129,7 +132,7 @@ public:
virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_PLANE; }
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
virtual Vector3 get_support(const Vector3 &p_normal) const;
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; }
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; }
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
virtual bool intersect_point(const Vector3 &p_point) const;
@@ -156,7 +159,7 @@ public:
virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_RAY; }
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
virtual Vector3 get_support(const Vector3 &p_normal) const;
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
virtual bool intersect_point(const Vector3 &p_point) const;
@@ -184,7 +187,7 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
virtual Vector3 get_support(const Vector3 &p_normal) const;
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
virtual bool intersect_point(const Vector3 &p_point) const;
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
@@ -209,7 +212,7 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
virtual Vector3 get_support(const Vector3 &p_normal) const;
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
virtual bool intersect_point(const Vector3 &p_point) const;
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
@@ -238,7 +241,7 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
virtual Vector3 get_support(const Vector3 &p_normal) const;
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
virtual bool intersect_point(const Vector3 &p_point) const;
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
@@ -251,6 +254,35 @@ public:
CapsuleShape3DSW();
};
+class CylinderShape3DSW : public Shape3DSW {
+ real_t height;
+ real_t radius;
+
+ void _setup(real_t p_height, real_t p_radius);
+
+public:
+ _FORCE_INLINE_ real_t get_height() const { return height; }
+ _FORCE_INLINE_ real_t get_radius() const { return radius; }
+
+ virtual real_t get_area() const { return 4.0 / 3.0 * Math_PI * radius * radius * radius + height * Math_PI * radius * radius; }
+
+ virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CYLINDER; }
+
+ virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
+ virtual Vector3 get_support(const Vector3 &p_normal) const;
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const;
+ virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
+
+ virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
+
+ virtual void set_data(const Variant &p_data);
+ virtual Variant get_data() const;
+
+ CylinderShape3DSW();
+};
+
struct ConvexPolygonShape3DSW : public Shape3DSW {
Geometry3D::MeshData mesh;
@@ -263,7 +295,7 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
virtual Vector3 get_support(const Vector3 &p_normal) const;
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
virtual bool intersect_point(const Vector3 &p_point) const;
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
@@ -399,7 +431,7 @@ struct FaceShape3DSW : public Shape3DSW {
void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
Vector3 get_support(const Vector3 &p_normal) const;
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const;
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
virtual bool intersect_point(const Vector3 &p_point) const;
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
@@ -437,7 +469,7 @@ struct MotionShape3DSW : public Shape3DSW {
}
return support;
}
- virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; }
+ virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount, FeatureType &r_type) const { r_amount = 0; }
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return false; }
virtual bool intersect_point(const Vector3 &p_point) const { return false; }
virtual Vector3 get_closest_point_to(const Vector3 &p_point) const { return p_point; }
diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp
index d9170cd986..c8741dc930 100644
--- a/servers/physics_3d/space_3d_sw.cpp
+++ b/servers/physics_3d/space_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -181,7 +181,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans
return 0;
}
- Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape);
+ Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
AABB aabb = p_xform.xform(shape->get_aabb());
@@ -210,6 +210,10 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) {
continue;
}
@@ -232,7 +236,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans
}
bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
- Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape);
+ Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, false);
AABB aabb = p_xform.xform(shape->get_aabb());
@@ -265,6 +269,10 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
Vector3 point_A, point_B;
Vector3 sep_axis = p_motion.normalized();
@@ -274,11 +282,11 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor
continue;
}
- //test initial overlap
+ //test initial overlap, ignore objects it's inside of.
sep_axis = p_motion.normalized();
if (!CollisionSolver3DSW::solve_distance(shape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) {
- return false;
+ continue;
}
//just do kinematic solving
@@ -340,7 +348,7 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_
return false;
}
- Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape);
+ Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
AABB aabb = p_shape_xform.xform(shape->get_aabb());
@@ -365,12 +373,17 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_
}
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
- int shape_idx = space->intersection_query_subindex_results[i];
if (p_exclude.has(col_obj->get_self())) {
continue;
}
+ int shape_idx = space->intersection_query_subindex_results[i];
+
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
if (CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) {
collided = true;
}
@@ -384,6 +397,8 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_
struct _RestCallbackData {
const CollisionObject3DSW *object;
const CollisionObject3DSW *best_object;
+ int local_shape;
+ int best_local_shape;
int shape;
int best_shape;
Vector3 best_contact;
@@ -409,10 +424,11 @@ static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B,
rd->best_normal = contact_rel / len;
rd->best_object = rd->object;
rd->best_shape = rd->shape;
+ rd->best_local_shape = rd->local_shape;
}
bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
- Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape);
+ Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
AABB aabb = p_shape_xform.xform(shape->get_aabb());
@@ -432,12 +448,17 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap
}
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
- int shape_idx = space->intersection_query_subindex_results[i];
if (p_exclude.has(col_obj->get_self())) {
continue;
}
+ int shape_idx = space->intersection_query_subindex_results[i];
+
+ if (col_obj->is_shape_set_as_disabled(shape_idx)) {
+ continue;
+ }
+
rcd.object = col_obj;
rcd.shape = shape_idx;
bool sc = CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin);
@@ -468,15 +489,15 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap
}
Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const {
- CollisionObject3DSW *obj = PhysicsServer3DSW::singleton->area_owner.getornull(p_object);
+ CollisionObject3DSW *obj = PhysicsServer3DSW::singletonsw->area_owner.getornull(p_object);
if (!obj) {
- obj = PhysicsServer3DSW::singleton->body_owner.getornull(p_object);
+ obj = PhysicsServer3DSW::singletonsw->body_owner.getornull(p_object);
}
ERR_FAIL_COND_V(!obj, Vector3());
ERR_FAIL_COND_V(obj->get_space() != space, Vector3());
- float min_distance = 1e20;
+ real_t min_distance = 1e20;
Vector3 min_point;
bool shapes_found = false;
@@ -492,7 +513,7 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob
Vector3 point = shape->get_closest_point_to(shape_xform.affine_inverse().xform(p_point));
point = shape_xform.xform(point);
- float dist = point.distance_to(p_point);
+ real_t dist = point.distance_to(p_point);
if (dist < min_distance) {
min_distance = dist;
min_point = point;
@@ -649,9 +670,9 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra
Vector3 a = sr[k * 2 + 0];
Vector3 b = sr[k * 2 + 1];
- recover_motion += (b - a) * 0.4;
+ recover_motion += (b - a) / cbk.amount;
- float depth = a.distance_to(b);
+ real_t depth = a.distance_to(b);
if (depth > result.collision_depth) {
result.collision_depth = depth;
result.collision_point = b;
@@ -739,8 +760,13 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb));
body_aabb = body_aabb.grow(p_margin);
+ real_t motion_length = p_motion.length();
+ Vector3 motion_normal = p_motion / motion_length;
+
Transform body_transform = p_from;
+ bool recovered = false;
+
{
//STEP 1, FREE BODY IF STUCK
@@ -791,7 +817,17 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
for (int i = 0; i < cbk.amount; i++) {
Vector3 a = sr[i * 2 + 0];
Vector3 b = sr[i * 2 + 1];
- recover_motion += (b - a) * 0.4;
+
+ // Compute plane on b towards a.
+ Vector3 n = (a - b).normalized();
+ real_t d = n.dot(b);
+
+ // Compute depth on recovered motion.
+ real_t depth = n.dot(a + recover_motion) - d;
+ if (depth > 0.0) {
+ // Only recover if there is penetration.
+ recover_motion -= n * depth * 0.4;
+ }
}
if (recover_motion == Vector3()) {
@@ -799,6 +835,8 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
break;
}
+ recovered = true;
+
body_transform.origin += recover_motion;
body_aabb.position += recover_motion;
@@ -848,14 +886,14 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
//test initial overlap, does it collide if going all the way?
Vector3 point_A, point_B;
- Vector3 sep_axis = p_motion.normalized();
+ Vector3 sep_axis = motion_normal;
Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
//test initial overlap, does it collide if going all the way?
if (CollisionSolver3DSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) {
continue;
}
- sep_axis = p_motion.normalized();
+ sep_axis = motion_normal;
if (!CollisionSolver3DSW::solve_distance(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) {
stuck = true;
@@ -865,13 +903,12 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
//just do kinematic solving
real_t low = 0;
real_t hi = 1;
- Vector3 mnormal = p_motion.normalized();
for (int k = 0; k < 8; k++) { //steps should be customizable..
real_t ofs = (low + hi) * 0.5;
- Vector3 sep = mnormal; //important optimization for this to work fast enough
+ Vector3 sep = motion_normal; //important optimization for this to work fast enough
mshape.motion = body_shape_xform_inv.basis.xform(p_motion * ofs);
@@ -912,16 +949,11 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
}
bool collided = false;
- if (safe >= 1) {
- //not collided
- collided = false;
- if (r_result) {
- r_result->motion = p_motion;
- r_result->remainder = Vector3();
- r_result->motion += (body_transform.get_origin() - p_from.get_origin());
+ if (recovered || (safe < 1)) {
+ if (safe >= 1) {
+ best_shape = -1; //no best shape with cast, reset to -1
}
- } else {
//it collided, let's get the rest info in unsafe advance
Transform ugt = body_transform;
ugt.origin += p_motion * unsafe;
@@ -930,25 +962,40 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
rcd.best_len = 0;
rcd.best_object = nullptr;
rcd.best_shape = 0;
- rcd.min_allowed_depth = test_motion_min_contact_depth;
- Transform body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
- Shape3DSW *body_shape = p_body->get_shape(best_shape);
+ // Allowed depth can't be lower than motion length, in order to handle contacts at low speed.
+ rcd.min_allowed_depth = MIN(motion_length, test_motion_min_contact_depth);
- body_aabb.position += p_motion * unsafe;
+ int from_shape = best_shape != -1 ? best_shape : 0;
+ int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count();
- int amount = _cull_aabb_for_body(p_body, body_aabb);
+ for (int j = from_shape; j < to_shape; j++) {
+ if (p_body->is_shape_set_as_disabled(j)) {
+ continue;
+ }
- for (int i = 0; i < amount; i++) {
- const CollisionObject3DSW *col_obj = intersection_query_results[i];
- int shape_idx = intersection_query_subindex_results[i];
+ Transform body_shape_xform = ugt * p_body->get_shape_transform(j);
+ Shape3DSW *body_shape = p_body->get_shape(j);
- rcd.object = col_obj;
- rcd.shape = shape_idx;
- bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin);
- if (!sc) {
+ if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer3D::SHAPE_RAY) {
continue;
}
+
+ body_aabb.position += p_motion * unsafe;
+
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
+
+ for (int i = 0; i < amount; i++) {
+ const CollisionObject3DSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ rcd.object = col_obj;
+ rcd.shape = shape_idx;
+ bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin);
+ if (!sc) {
+ continue;
+ }
+ }
}
if (rcd.best_len != 0) {
@@ -956,7 +1003,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
r_result->collider = rcd.best_object->get_self();
r_result->collider_id = rcd.best_object->get_instance_id();
r_result->collider_shape = rcd.best_shape;
- r_result->collision_local_shape = best_shape;
+ r_result->collision_local_shape = rcd.best_local_shape;
r_result->collision_normal = rcd.best_normal;
r_result->collision_point = rcd.best_contact;
//r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
@@ -972,17 +1019,15 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
}
collided = true;
- } else {
- if (r_result) {
- r_result->motion = p_motion;
- r_result->remainder = Vector3();
- r_result->motion += (body_transform.get_origin() - p_from.get_origin());
- }
-
- collided = false;
}
}
+ if (!collided && r_result) {
+ r_result->motion = p_motion;
+ r_result->remainder = Vector3();
+ r_result->motion += (body_transform.get_origin() - p_from.get_origin());
+ }
+
return collided;
}
@@ -1211,7 +1256,7 @@ Space3DSW::Space3DSW() {
constraint_bias = 0.01;
body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_linear", 0.1);
- body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI));
+ body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", Math::deg2rad(8.0));
body_time_to_sleep = GLOBAL_DEF("physics/3d/time_before_sleep", 0.5);
ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/3d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
body_angular_velocity_damp_ratio = 10;
diff --git a/servers/physics_3d/space_3d_sw.h b/servers/physics_3d/space_3d_sw.h
index 22535a6adb..eed3d86a72 100644
--- a/servers/physics_3d/space_3d_sw.h
+++ b/servers/physics_3d/space_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -182,7 +182,7 @@ public:
PhysicsDirectSpaceState3DSW *get_direct_state();
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
- _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); }
+ _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.is_empty(); }
_FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) {
if (contact_debug_count < contact_debug.size()) {
contact_debug.write[contact_debug_count++] = p_contact;
diff --git a/servers/physics_3d/step_3d_sw.cpp b/servers/physics_3d/step_3d_sw.cpp
index 9a2a0073a1..d9370de6a3 100644
--- a/servers/physics_3d/step_3d_sw.cpp
+++ b/servers/physics_3d/step_3d_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/step_3d_sw.h b/servers/physics_3d/step_3d_sw.h
index 9dbb61308f..55c48ec0eb 100644
--- a/servers/physics_3d/step_3d_sw.h
+++ b/servers/physics_3d/step_3d_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index 1ea8985543..83ebc0c55b 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,7 +42,7 @@ void PhysicsDirectBodyState2D::integrate_forces() {
real_t av = get_angular_velocity();
- float damp = 1.0 - step * get_total_linear_damp();
+ real_t damp = 1.0 - step * get_total_linear_damp();
if (damp < 0) { // reached zero in the given time
damp = 0;
@@ -168,11 +168,11 @@ Vector2 PhysicsShapeQueryParameters2D::get_motion() const {
return motion;
}
-void PhysicsShapeQueryParameters2D::set_margin(float p_margin) {
+void PhysicsShapeQueryParameters2D::set_margin(real_t p_margin) {
margin = p_margin;
}
-float PhysicsShapeQueryParameters2D::get_margin() const {
+real_t PhysicsShapeQueryParameters2D::get_margin() const {
return margin;
}
@@ -311,7 +311,7 @@ Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryPar
Array PhysicsDirectSpaceState2D::_cast_motion(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
- float closest_safe, closest_unsafe;
+ real_t closest_safe, closest_unsafe;
bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
if (!res) {
return Array();
@@ -517,7 +517,7 @@ PhysicsTestMotionResult2D::PhysicsTestMotionResult2D() {
///////////////////////////////////////
-bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) {
+bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) {
MotionResult *r = nullptr;
if (p_result.is_valid()) {
r = p_result->get_result_ptr();
@@ -655,12 +655,16 @@ void PhysicsServer2D::_bind_methods() {
/* JOINT API */
+ ClassDB::bind_method(D_METHOD("joint_create"), &PhysicsServer2D::joint_create);
+
+ ClassDB::bind_method(D_METHOD("joint_clear", "joint"), &PhysicsServer2D::joint_clear);
+
ClassDB::bind_method(D_METHOD("joint_set_param", "joint", "param", "value"), &PhysicsServer2D::joint_set_param);
ClassDB::bind_method(D_METHOD("joint_get_param", "joint", "param"), &PhysicsServer2D::joint_get_param);
- ClassDB::bind_method(D_METHOD("pin_joint_create", "anchor", "body_a", "body_b"), &PhysicsServer2D::pin_joint_create, DEFVAL(RID()));
- ClassDB::bind_method(D_METHOD("groove_joint_create", "groove1_a", "groove2_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::groove_joint_create, DEFVAL(RID()), DEFVAL(RID()));
- ClassDB::bind_method(D_METHOD("damped_spring_joint_create", "anchor_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::damped_spring_joint_create, DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("joint_make_pin", "joint", "anchor", "body_a", "body_b"), &PhysicsServer2D::joint_make_pin, DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("joint_make_groove", "joint", "groove1_a", "groove2_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::joint_make_groove, DEFVAL(RID()), DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("joint_make_damped_spring", "joint", "anchor_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::joint_make_damped_spring, DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("damped_spring_joint_set_param", "joint", "param", "value"), &PhysicsServer2D::damped_spring_joint_set_param);
ClassDB::bind_method(D_METHOD("damped_spring_joint_get_param", "joint", "param"), &PhysicsServer2D::damped_spring_joint_get_param);
@@ -727,9 +731,10 @@ void PhysicsServer2D::_bind_methods() {
BIND_ENUM_CONSTANT(BODY_STATE_SLEEPING);
BIND_ENUM_CONSTANT(BODY_STATE_CAN_SLEEP);
- BIND_ENUM_CONSTANT(JOINT_PIN);
- BIND_ENUM_CONSTANT(JOINT_GROOVE);
- BIND_ENUM_CONSTANT(JOINT_DAMPED_SPRING);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_PIN);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_GROOVE);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_DAMPED_SPRING);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_MAX);
BIND_ENUM_CONSTANT(JOINT_PARAM_BIAS);
BIND_ENUM_CONSTANT(JOINT_PARAM_MAX_BIAS);
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index f7607d5dd5..28f22ce06b 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,10 +45,10 @@ protected:
public:
virtual Vector2 get_total_gravity() const = 0; // get gravity vector working on this body space/area
- virtual float get_total_linear_damp() const = 0; // get density of this body space/area
- virtual float get_total_angular_damp() const = 0; // get density of this body space/area
+ virtual real_t get_total_linear_damp() const = 0; // get density of this body space/area
+ virtual real_t get_total_angular_damp() const = 0; // get density of this body space/area
- virtual float get_inverse_mass() const = 0; // get the mass
+ virtual real_t get_inverse_mass() const = 0; // get the mass
virtual real_t get_inverse_inertia() const = 0; // get density of this body space
virtual void set_linear_velocity(const Vector2 &p_velocity) = 0;
@@ -103,7 +103,7 @@ class PhysicsShapeQueryParameters2D : public Reference {
RID shape;
Transform2D transform;
Vector2 motion;
- float margin;
+ real_t margin;
Set<RID> exclude;
uint32_t collision_mask;
@@ -125,8 +125,8 @@ public:
void set_motion(const Vector2 &p_motion);
Vector2 get_motion() const;
- void set_margin(float p_margin);
- float get_margin() const;
+ void set_margin(real_t p_margin);
+ real_t get_margin() const;
void set_collision_mask(int p_collision_mask);
int get_collision_mask() const;
@@ -182,11 +182,11 @@ public:
virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0;
virtual int intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0;
- virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
+ virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
- virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
+ virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
- virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
+ virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct ShapeRestInfo {
Vector2 point;
@@ -198,7 +198,7 @@ public:
Variant metadata;
};
- virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
+ virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
PhysicsDirectSpaceState2D();
};
@@ -230,7 +230,7 @@ class PhysicsServer2D : public Object {
static PhysicsServer2D *singleton;
- virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>());
+ virtual bool _body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.08, const Ref<PhysicsTestMotionResult2D> &p_result = Ref<PhysicsTestMotionResult2D>());
protected:
static void _bind_methods();
@@ -393,7 +393,7 @@ public:
virtual Variant body_get_shape_metadata(RID p_body, int p_shape_idx) const = 0;
virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled) = 0;
- virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, float p_margin = 0) = 0;
+ virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, real_t p_margin = 0) = 0;
virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0;
virtual void body_clear_shapes(RID p_body) = 0;
@@ -431,8 +431,8 @@ public:
BODY_PARAM_MAX,
};
- virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) = 0;
- virtual float body_get_param(RID p_body, BodyParameter p_param) const = 0;
+ virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) = 0;
+ virtual real_t body_get_param(RID p_body, BodyParameter p_param) const = 0;
//state
enum BodyState {
@@ -450,15 +450,15 @@ public:
virtual void body_set_applied_force(RID p_body, const Vector2 &p_force) = 0;
virtual Vector2 body_get_applied_force(RID p_body) const = 0;
- virtual void body_set_applied_torque(RID p_body, float p_torque) = 0;
- virtual float body_get_applied_torque(RID p_body) const = 0;
+ virtual void body_set_applied_torque(RID p_body, real_t p_torque) = 0;
+ virtual real_t body_get_applied_torque(RID p_body) const = 0;
virtual void body_add_central_force(RID p_body, const Vector2 &p_force) = 0;
virtual void body_add_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0;
- virtual void body_add_torque(RID p_body, float p_torque) = 0;
+ virtual void body_add_torque(RID p_body, real_t p_torque) = 0;
virtual void body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) = 0;
- virtual void body_apply_torque_impulse(RID p_body, float p_torque) = 0;
+ virtual void body_apply_torque_impulse(RID p_body, real_t p_torque) = 0;
virtual void body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) = 0;
virtual void body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) = 0;
@@ -471,8 +471,8 @@ public:
virtual int body_get_max_contacts_reported(RID p_body) const = 0;
//missing remove
- virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) = 0;
- virtual float body_get_contacts_reported_depth_threshold(RID p_body) const = 0;
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) = 0;
+ virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const = 0;
virtual void body_set_omit_force_integration(RID p_body, bool p_omit) = 0;
virtual bool body_is_omitting_force_integration(RID p_body) const = 0;
@@ -506,10 +506,10 @@ public:
}
};
- virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0;
+ virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0;
struct SeparationResult {
- float collision_depth;
+ real_t collision_depth;
Vector2 collision_point;
Vector2 collision_normal;
Vector2 collider_velocity;
@@ -520,14 +520,19 @@ public:
Variant collider_metadata;
};
- virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) = 0;
+ virtual int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) = 0;
/* JOINT API */
+ virtual RID joint_create() = 0;
+
+ virtual void joint_clear(RID p_joint) = 0;
+
enum JointType {
- JOINT_PIN,
- JOINT_GROOVE,
- JOINT_DAMPED_SPRING
+ JOINT_TYPE_PIN,
+ JOINT_TYPE_GROOVE,
+ JOINT_TYPE_DAMPED_SPRING,
+ JOINT_TYPE_MAX
};
enum JointParam {
@@ -542,9 +547,9 @@ public:
virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0;
virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0;
- virtual RID pin_joint_create(const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) = 0;
- virtual RID groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) = 0;
- virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) = 0;
+ virtual void joint_make_pin(RID p_joint, const Vector2 &p_anchor, RID p_body_a, RID p_body_b = RID()) = 0;
+ virtual void joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) = 0;
+ virtual void joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()) = 0;
enum PinJointParam {
PIN_JOINT_SOFTNESS
@@ -576,7 +581,7 @@ public:
virtual void set_active(bool p_active) = 0;
virtual void init() = 0;
- virtual void step(float p_step) = 0;
+ virtual void step(real_t p_step) = 0;
virtual void sync() = 0;
virtual void flush_queries() = 0;
virtual void end_sync() = 0;
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index fabd661970..af25029f04 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,13 +42,13 @@ void PhysicsDirectBodyState3D::integrate_forces() {
Vector3 av = get_angular_velocity();
- float linear_damp = 1.0 - step * get_total_linear_damp();
+ real_t linear_damp = 1.0 - step * get_total_linear_damp();
if (linear_damp < 0) { // reached zero in the given time
linear_damp = 0;
}
- float angular_damp = 1.0 - step * get_total_angular_damp();
+ real_t angular_damp = 1.0 - step * get_total_angular_damp();
if (angular_damp < 0) { // reached zero in the given time
angular_damp = 0;
@@ -128,7 +128,7 @@ void PhysicsDirectBodyState3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleep_state", "is_sleeping");
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform");
+ ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform");
}
PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {}
@@ -164,11 +164,11 @@ Transform PhysicsShapeQueryParameters3D::get_transform() const {
return transform;
}
-void PhysicsShapeQueryParameters3D::set_margin(float p_margin) {
+void PhysicsShapeQueryParameters3D::set_margin(real_t p_margin) {
margin = p_margin;
}
-float PhysicsShapeQueryParameters3D::get_margin() const {
+real_t PhysicsShapeQueryParameters3D::get_margin() const {
return margin;
}
@@ -303,7 +303,7 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar
Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, const Vector3 &p_motion) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
- float closest_safe = 1.0f, closest_unsafe = 1.0f;
+ real_t closest_safe = 1.0f, closest_unsafe = 1.0f;
bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
if (!res) {
return Array();
@@ -398,10 +398,47 @@ void PhysicsShapeQueryResult3D::_bind_methods() {
///////////////////////////////////////
+RID PhysicsServer3D::shape_create(ShapeType p_shape) {
+ switch (p_shape) {
+ case SHAPE_PLANE:
+ return plane_shape_create();
+ case SHAPE_RAY:
+ return ray_shape_create();
+ case SHAPE_SPHERE:
+ return sphere_shape_create();
+ case SHAPE_BOX:
+ return box_shape_create();
+ case SHAPE_CAPSULE:
+ return capsule_shape_create();
+ case SHAPE_CYLINDER:
+ return cylinder_shape_create();
+ case SHAPE_CONVEX_POLYGON:
+ return convex_polygon_shape_create();
+ case SHAPE_CONCAVE_POLYGON:
+ return concave_polygon_shape_create();
+ case SHAPE_HEIGHTMAP:
+ return heightmap_shape_create();
+ case SHAPE_CUSTOM:
+ return custom_shape_create();
+ default:
+ return RID();
+ }
+}
+
void PhysicsServer3D::_bind_methods() {
#ifndef _3D_DISABLED
- ClassDB::bind_method(D_METHOD("shape_create", "type"), &PhysicsServer3D::shape_create);
+ ClassDB::bind_method(D_METHOD("plane_shape_create"), &PhysicsServer3D::plane_shape_create);
+ ClassDB::bind_method(D_METHOD("ray_shape_create"), &PhysicsServer3D::ray_shape_create);
+ ClassDB::bind_method(D_METHOD("sphere_shape_create"), &PhysicsServer3D::sphere_shape_create);
+ ClassDB::bind_method(D_METHOD("box_shape_create"), &PhysicsServer3D::box_shape_create);
+ ClassDB::bind_method(D_METHOD("capsule_shape_create"), &PhysicsServer3D::capsule_shape_create);
+ ClassDB::bind_method(D_METHOD("cylinder_shape_create"), &PhysicsServer3D::cylinder_shape_create);
+ ClassDB::bind_method(D_METHOD("convex_polygon_shape_create"), &PhysicsServer3D::convex_polygon_shape_create);
+ ClassDB::bind_method(D_METHOD("concave_polygon_shape_create"), &PhysicsServer3D::concave_polygon_shape_create);
+ ClassDB::bind_method(D_METHOD("heightmap_shape_create"), &PhysicsServer3D::heightmap_shape_create);
+ ClassDB::bind_method(D_METHOD("custom_shape_create"), &PhysicsServer3D::custom_shape_create);
+
ClassDB::bind_method(D_METHOD("shape_set_data", "shape", "data"), &PhysicsServer3D::shape_set_data);
ClassDB::bind_method(D_METHOD("shape_get_type", "shape"), &PhysicsServer3D::shape_get_type);
@@ -450,9 +487,8 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &PhysicsServer3D::area_set_monitorable);
ClassDB::bind_method(D_METHOD("area_set_ray_pickable", "area", "enable"), &PhysicsServer3D::area_set_ray_pickable);
- ClassDB::bind_method(D_METHOD("area_is_ray_pickable", "area"), &PhysicsServer3D::area_is_ray_pickable);
- ClassDB::bind_method(D_METHOD("body_create", "mode", "init_sleeping"), &PhysicsServer3D::body_create, DEFVAL(BODY_MODE_RIGID), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("body_create"), &PhysicsServer3D::body_create);
ClassDB::bind_method(D_METHOD("body_set_space", "body", "space"), &PhysicsServer3D::body_set_space);
ClassDB::bind_method(D_METHOD("body_get_space", "body"), &PhysicsServer3D::body_get_space);
@@ -517,19 +553,22 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_force_integration_callback", "body", "receiver", "method", "userdata"), &PhysicsServer3D::body_set_force_integration_callback, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("body_set_ray_pickable", "body", "enable"), &PhysicsServer3D::body_set_ray_pickable);
- ClassDB::bind_method(D_METHOD("body_is_ray_pickable", "body"), &PhysicsServer3D::body_is_ray_pickable);
ClassDB::bind_method(D_METHOD("body_get_direct_state", "body"), &PhysicsServer3D::body_get_direct_state);
/* JOINT API */
- BIND_ENUM_CONSTANT(JOINT_PIN);
- BIND_ENUM_CONSTANT(JOINT_HINGE);
- BIND_ENUM_CONSTANT(JOINT_SLIDER);
- BIND_ENUM_CONSTANT(JOINT_CONE_TWIST);
- BIND_ENUM_CONSTANT(JOINT_6DOF);
+ ClassDB::bind_method(D_METHOD("joint_create"), &PhysicsServer3D::joint_create);
+ ClassDB::bind_method(D_METHOD("joint_clear", "joint"), &PhysicsServer3D::joint_clear);
+
+ BIND_ENUM_CONSTANT(JOINT_TYPE_PIN);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_HINGE);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_SLIDER);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_CONE_TWIST);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_6DOF);
+ BIND_ENUM_CONSTANT(JOINT_TYPE_MAX);
- ClassDB::bind_method(D_METHOD("joint_create_pin", "body_A", "local_A", "body_B", "local_B"), &PhysicsServer3D::joint_create_pin);
+ ClassDB::bind_method(D_METHOD("joint_make_pin", "joint", "body_A", "local_A", "body_B", "local_B"), &PhysicsServer3D::joint_make_pin);
ClassDB::bind_method(D_METHOD("pin_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::pin_joint_set_param);
ClassDB::bind_method(D_METHOD("pin_joint_get_param", "joint", "param"), &PhysicsServer3D::pin_joint_get_param);
@@ -555,7 +594,7 @@ void PhysicsServer3D::_bind_methods() {
BIND_ENUM_CONSTANT(HINGE_JOINT_FLAG_USE_LIMIT);
BIND_ENUM_CONSTANT(HINGE_JOINT_FLAG_ENABLE_MOTOR);
- ClassDB::bind_method(D_METHOD("joint_create_hinge", "body_A", "hinge_A", "body_B", "hinge_B"), &PhysicsServer3D::joint_create_hinge);
+ ClassDB::bind_method(D_METHOD("joint_make_hinge", "joint", "body_A", "hinge_A", "body_B", "hinge_B"), &PhysicsServer3D::joint_make_hinge);
ClassDB::bind_method(D_METHOD("hinge_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::hinge_joint_set_param);
ClassDB::bind_method(D_METHOD("hinge_joint_get_param", "joint", "param"), &PhysicsServer3D::hinge_joint_get_param);
@@ -563,7 +602,7 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("hinge_joint_set_flag", "joint", "flag", "enabled"), &PhysicsServer3D::hinge_joint_set_flag);
ClassDB::bind_method(D_METHOD("hinge_joint_get_flag", "joint", "flag"), &PhysicsServer3D::hinge_joint_get_flag);
- ClassDB::bind_method(D_METHOD("joint_create_slider", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_slider);
+ ClassDB::bind_method(D_METHOD("joint_make_slider", "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_slider);
ClassDB::bind_method(D_METHOD("slider_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::slider_joint_set_param);
ClassDB::bind_method(D_METHOD("slider_joint_get_param", "joint", "param"), &PhysicsServer3D::slider_joint_get_param);
@@ -593,7 +632,7 @@ void PhysicsServer3D::_bind_methods() {
BIND_ENUM_CONSTANT(SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING);
BIND_ENUM_CONSTANT(SLIDER_JOINT_MAX);
- ClassDB::bind_method(D_METHOD("joint_create_cone_twist", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_cone_twist);
+ ClassDB::bind_method(D_METHOD("joint_make_cone_twist", "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_cone_twist);
ClassDB::bind_method(D_METHOD("cone_twist_joint_set_param", "joint", "param", "value"), &PhysicsServer3D::cone_twist_joint_set_param);
ClassDB::bind_method(D_METHOD("cone_twist_joint_get_param", "joint", "param"), &PhysicsServer3D::cone_twist_joint_get_param);
@@ -631,7 +670,7 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("joint_set_solver_priority", "joint", "priority"), &PhysicsServer3D::joint_set_solver_priority);
ClassDB::bind_method(D_METHOD("joint_get_solver_priority", "joint"), &PhysicsServer3D::joint_get_solver_priority);
- ClassDB::bind_method(D_METHOD("joint_create_generic_6dof", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_create_generic_6dof);
+ ClassDB::bind_method(D_METHOD("joint_make_generic_6dof", "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"), &PhysicsServer3D::joint_make_generic_6dof);
ClassDB::bind_method(D_METHOD("generic_6dof_joint_set_param", "joint", "axis", "param", "value"), &PhysicsServer3D::generic_6dof_joint_set_param);
ClassDB::bind_method(D_METHOD("generic_6dof_joint_get_param", "joint", "axis", "param"), &PhysicsServer3D::generic_6dof_joint_get_param);
@@ -718,7 +757,6 @@ void PhysicsServer3D::_bind_methods() {
}
PhysicsServer3D::PhysicsServer3D() {
- ERR_FAIL_COND(singleton != nullptr);
singleton = this;
}
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index ed3a7e87a4..e16857192c 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,12 +44,12 @@ protected:
public:
virtual Vector3 get_total_gravity() const = 0;
- virtual float get_total_angular_damp() const = 0;
- virtual float get_total_linear_damp() const = 0;
+ virtual real_t get_total_angular_damp() const = 0;
+ virtual real_t get_total_linear_damp() const = 0;
virtual Vector3 get_center_of_mass() const = 0;
virtual Basis get_principal_inertia_axes() const = 0;
- virtual float get_inverse_mass() const = 0; // get the mass
+ virtual real_t get_inverse_mass() const = 0; // get the mass
virtual Vector3 get_inverse_inertia() const = 0; // get density of this body space
virtual Basis get_inverse_inertia_tensor() const = 0; // get density of this body space
@@ -76,7 +76,7 @@ public:
virtual Vector3 get_contact_local_position(int p_contact_idx) const = 0;
virtual Vector3 get_contact_local_normal(int p_contact_idx) const = 0;
- virtual float get_contact_impulse(int p_contact_idx) const = 0;
+ virtual real_t get_contact_impulse(int p_contact_idx) const = 0;
virtual int get_contact_local_shape(int p_contact_idx) const = 0;
virtual RID get_contact_collider(int p_contact_idx) const = 0;
@@ -103,7 +103,7 @@ class PhysicsShapeQueryParameters3D : public Reference {
RES shape_ref;
RID shape;
Transform transform;
- float margin;
+ real_t margin;
Set<RID> exclude;
uint32_t collision_mask;
@@ -122,8 +122,8 @@ public:
void set_transform(const Transform &p_transform);
Transform get_transform() const;
- void set_margin(float p_margin);
- float get_margin() const;
+ void set_margin(real_t p_margin);
+ real_t get_margin() const;
void set_collision_mask(int p_collision_mask);
int get_collision_mask() const;
@@ -174,7 +174,7 @@ public:
virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false) = 0;
- virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
+ virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct ShapeRestInfo {
Vector3 point;
@@ -185,11 +185,11 @@ public:
Vector3 linear_velocity; //velocity at contact point
};
- virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) = 0;
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr) = 0;
- virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
+ virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
- virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
+ virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0;
@@ -240,7 +240,19 @@ public:
SHAPE_CUSTOM, ///< Server-Implementation based custom shape, calling shape_create() with this value will result in an error
};
- virtual RID shape_create(ShapeType p_shape) = 0;
+ RID shape_create(ShapeType p_shape);
+
+ virtual RID plane_shape_create() = 0;
+ virtual RID ray_shape_create() = 0;
+ virtual RID sphere_shape_create() = 0;
+ virtual RID box_shape_create() = 0;
+ virtual RID capsule_shape_create() = 0;
+ virtual RID cylinder_shape_create() = 0;
+ virtual RID convex_polygon_shape_create() = 0;
+ virtual RID concave_polygon_shape_create() = 0;
+ virtual RID heightmap_shape_create() = 0;
+ virtual RID custom_shape_create() = 0;
+
virtual void shape_set_data(RID p_shape, const Variant &p_data) = 0;
virtual void shape_set_custom_solver_bias(RID p_shape, real_t p_bias) = 0;
@@ -344,7 +356,6 @@ public:
virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0;
virtual void area_set_ray_pickable(RID p_area, bool p_enable) = 0;
- virtual bool area_is_ray_pickable(RID p_area) const = 0;
/* BODY API */
@@ -357,7 +368,7 @@ public:
BODY_MODE_CHARACTER
};
- virtual RID body_create(BodyMode p_mode = BODY_MODE_RIGID, bool p_init_sleeping = false) = 0;
+ virtual RID body_create() = 0;
virtual void body_set_space(RID p_body, RID p_space) = 0;
virtual RID body_get_space(RID p_body) const = 0;
@@ -404,8 +415,8 @@ public:
BODY_PARAM_MAX,
};
- virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) = 0;
- virtual float body_get_param(RID p_body, BodyParameter p_param) const = 0;
+ virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value) = 0;
+ virtual real_t body_get_param(RID p_body, BodyParameter p_param) const = 0;
virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) = 0;
virtual real_t body_get_kinematic_safe_margin(RID p_body) const = 0;
@@ -459,8 +470,8 @@ public:
virtual int body_get_max_contacts_reported(RID p_body) const = 0;
//missing remove
- virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) = 0;
- virtual float body_get_contacts_reported_depth_threshold(RID p_body) const = 0;
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) = 0;
+ virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const = 0;
virtual void body_set_omit_force_integration(RID p_body, bool p_omit) = 0;
virtual bool body_is_omitting_force_integration(RID p_body) const = 0;
@@ -468,7 +479,6 @@ public:
virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant()) = 0;
virtual void body_set_ray_pickable(RID p_body, bool p_enable) = 0;
- virtual bool body_is_ray_pickable(RID p_body) const = 0;
// this function only works on physics process, errors and returns null otherwise
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) = 0;
@@ -495,7 +505,7 @@ public:
virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0;
struct SeparationResult {
- float collision_depth;
+ real_t collision_depth;
Vector3 collision_point;
Vector3 collision_normal;
Vector3 collider_velocity;
@@ -506,11 +516,11 @@ public:
Variant collider_metadata;
};
- virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) = 0;
+ virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin = 0.001) = 0;
/* SOFT BODY */
- virtual RID soft_body_create(bool p_init_sleeping = false) = 0;
+ virtual RID soft_body_create() = 0;
virtual void soft_body_update_rendering_server(RID p_body, class SoftBodyRenderingServerHandler *p_rendering_server_handler) = 0;
@@ -536,55 +546,59 @@ public:
virtual Vector3 soft_body_get_vertex_position(RID p_body, int vertex_index) const = 0;
virtual void soft_body_set_ray_pickable(RID p_body, bool p_enable) = 0;
- virtual bool soft_body_is_ray_pickable(RID p_body) const = 0;
virtual void soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) = 0;
- virtual int soft_body_get_simulation_precision(RID p_body) = 0;
+ virtual int soft_body_get_simulation_precision(RID p_body) const = 0;
virtual void soft_body_set_total_mass(RID p_body, real_t p_total_mass) = 0;
- virtual real_t soft_body_get_total_mass(RID p_body) = 0;
+ virtual real_t soft_body_get_total_mass(RID p_body) const = 0;
virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) = 0;
- virtual real_t soft_body_get_linear_stiffness(RID p_body) = 0;
+ virtual real_t soft_body_get_linear_stiffness(RID p_body) const = 0;
- virtual void soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) = 0;
- virtual real_t soft_body_get_areaAngular_stiffness(RID p_body) = 0;
+ virtual void soft_body_set_angular_stiffness(RID p_body, real_t p_stiffness) = 0;
+ virtual real_t soft_body_get_angular_stiffness(RID p_body) const = 0;
virtual void soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) = 0;
- virtual real_t soft_body_get_volume_stiffness(RID p_body) = 0;
+ virtual real_t soft_body_get_volume_stiffness(RID p_body) const = 0;
virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) = 0;
- virtual real_t soft_body_get_pressure_coefficient(RID p_body) = 0;
+ virtual real_t soft_body_get_pressure_coefficient(RID p_body) const = 0;
virtual void soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) = 0;
- virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) = 0;
+ virtual real_t soft_body_get_pose_matching_coefficient(RID p_body) const = 0;
virtual void soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) = 0;
- virtual real_t soft_body_get_damping_coefficient(RID p_body) = 0;
+ virtual real_t soft_body_get_damping_coefficient(RID p_body) const = 0;
virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) = 0;
- virtual real_t soft_body_get_drag_coefficient(RID p_body) = 0;
+ virtual real_t soft_body_get_drag_coefficient(RID p_body) const = 0;
virtual void soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) = 0;
- virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) = 0;
+ virtual Vector3 soft_body_get_point_global_position(RID p_body, int p_point_index) const = 0;
virtual Vector3 soft_body_get_point_offset(RID p_body, int p_point_index) const = 0;
virtual void soft_body_remove_all_pinned_points(RID p_body) = 0;
virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) = 0;
- virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) = 0;
+ virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) const = 0;
/* JOINT API */
enum JointType {
- JOINT_PIN,
- JOINT_HINGE,
- JOINT_SLIDER,
- JOINT_CONE_TWIST,
- JOINT_6DOF
+ JOINT_TYPE_PIN,
+ JOINT_TYPE_HINGE,
+ JOINT_TYPE_SLIDER,
+ JOINT_TYPE_CONE_TWIST,
+ JOINT_TYPE_6DOF,
+ JOINT_TYPE_MAX,
};
+ virtual RID joint_create() = 0;
+
+ virtual void joint_clear(RID p_joint) = 0;
+
virtual JointType joint_get_type(RID p_joint) const = 0;
virtual void joint_set_solver_priority(RID p_joint, int p_priority) = 0;
@@ -593,7 +607,7 @@ public:
virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0;
virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0;
- virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) = 0;
+ virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) = 0;
enum PinJointParam {
PIN_JOINT_BIAS,
@@ -601,8 +615,8 @@ public:
PIN_JOINT_IMPULSE_CLAMP
};
- virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) = 0;
- virtual float pin_joint_get_param(RID p_joint, PinJointParam p_param) const = 0;
+ virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) = 0;
+ virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const = 0;
virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) = 0;
virtual Vector3 pin_joint_get_local_a(RID p_joint) const = 0;
@@ -628,11 +642,11 @@ public:
HINGE_JOINT_FLAG_MAX
};
- virtual RID joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) = 0;
- virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) = 0;
+ virtual void joint_make_hinge(RID p_joint, RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) = 0;
+ virtual void joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) = 0;
- virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) = 0;
- virtual float hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const = 0;
+ virtual void hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) = 0;
+ virtual real_t hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const = 0;
virtual void hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) = 0;
virtual bool hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const = 0;
@@ -665,10 +679,10 @@ public:
};
- virtual RID joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A
+ virtual void joint_make_slider(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A
- virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) = 0;
- virtual float slider_joint_get_param(RID p_joint, SliderJointParam p_param) const = 0;
+ virtual void slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) = 0;
+ virtual real_t slider_joint_get_param(RID p_joint, SliderJointParam p_param) const = 0;
enum ConeTwistJointParam {
CONE_TWIST_JOINT_SWING_SPAN,
@@ -679,10 +693,10 @@ public:
CONE_TWIST_MAX
};
- virtual RID joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A
+ virtual void joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A
- virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) = 0;
- virtual float cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const = 0;
+ virtual void cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) = 0;
+ virtual real_t cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const = 0;
enum G6DOFJointAxisParam {
G6DOF_JOINT_LINEAR_LOWER_LIMIT,
@@ -720,13 +734,13 @@ public:
G6DOF_JOINT_FLAG_MAX
};
- virtual RID joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A
+ virtual void joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) = 0; //reference frame is A
- virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, float p_value) = 0;
- virtual float generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) = 0;
+ virtual void generic_6dof_joint_set_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param, real_t p_value) = 0;
+ virtual real_t generic_6dof_joint_get_param(RID p_joint, Vector3::Axis, G6DOFJointAxisParam p_param) const = 0;
virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) = 0;
- virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) = 0;
+ virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) const = 0;
/* QUERY API */
@@ -741,8 +755,10 @@ public:
virtual void set_active(bool p_active) = 0;
virtual void init() = 0;
- virtual void step(float p_step) = 0;
+ virtual void step(real_t p_step) = 0;
+ virtual void sync() = 0;
virtual void flush_queries() = 0;
+ virtual void end_sync() = 0;
virtual void finish() = 0;
virtual bool is_flushing_queries() const = 0;
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 29e5ca3f77..deb230c4fb 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,6 +36,7 @@
#include "audio/audio_effect.h"
#include "audio/audio_stream.h"
#include "audio/effects/audio_effect_amplify.h"
+#include "audio/effects/audio_effect_capture.h"
#include "audio/effects/audio_effect_chorus.h"
#include "audio/effects/audio_effect_compressor.h"
#include "audio/effects/audio_effect_delay.h"
@@ -60,6 +61,7 @@
#include "physics_2d/physics_server_2d_sw.h"
#include "physics_2d/physics_server_2d_wrap_mt.h"
#include "physics_3d/physics_server_3d_sw.h"
+#include "physics_3d/physics_server_3d_wrap_mt.h"
#include "physics_server_2d.h"
#include "physics_server_3d.h"
#include "rendering/renderer_compositor.h"
@@ -75,11 +77,19 @@
ShaderTypes *shader_types = nullptr;
PhysicsServer3D *_createGodotPhysics3DCallback() {
- return memnew(PhysicsServer3DSW);
+ bool using_threads = GLOBAL_GET("physics/3d/run_on_thread");
+
+ PhysicsServer3D *physics_server = memnew(PhysicsServer3DSW(using_threads));
+
+ return memnew(PhysicsServer3DWrapMT(physics_server, using_threads));
}
PhysicsServer2D *_createGodotPhysics2DCallback() {
- return PhysicsServer2DWrapMT::init_server<PhysicsServer2DSW>();
+ bool using_threads = GLOBAL_GET("physics/2d/run_on_thread");
+
+ PhysicsServer2D *physics_server = memnew(PhysicsServer2DSW(using_threads));
+
+ return memnew(PhysicsServer2DWrapMT(physics_server, using_threads));
}
static bool has_server_feature_callback(const String &p_feature) {
@@ -94,6 +104,16 @@ static bool has_server_feature_callback(const String &p_feature) {
void preregister_server_types() {
shader_types = memnew(ShaderTypes);
+
+ GLOBAL_DEF("internationalization/rendering/text_driver", "");
+ String text_driver_options;
+ for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
+ if (i > 0) {
+ text_driver_options += ",";
+ }
+ text_driver_options += TextServerManager::get_interface_name(i);
+ }
+ ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options));
}
void register_server_types() {
@@ -166,6 +186,8 @@ void register_server_types() {
ClassDB::register_class<AudioEffectRecord>();
ClassDB::register_class<AudioEffectSpectrumAnalyzer>();
ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>();
+
+ ClassDB::register_class<AudioEffectCapture>();
}
ClassDB::register_virtual_class<RenderingDevice>();
diff --git a/servers/register_server_types.h b/servers/register_server_types.h
index 7d1dad37af..f6a65cb653 100644
--- a/servers/register_server_types.h
+++ b/servers/register_server_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index ea6ed2b532..7f3fc2f8f4 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -97,7 +97,7 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2
}
}
-void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item> &canvas_item_owner) {
+void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item, true> &canvas_item_owner) {
do {
ysort_owner->ysort_children_count = -1;
ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : nullptr;
@@ -148,6 +148,8 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
} else {
ci->final_clip_rect = global_rect;
}
+ ci->final_clip_rect.position = ci->final_clip_rect.position.round();
+ ci->final_clip_rect.size = ci->final_clip_rect.size.round();
ci->final_clip_owner = ci;
} else {
@@ -356,12 +358,12 @@ bool RendererCanvasCull::was_sdf_used() {
return sdf_used;
}
-RID RendererCanvasCull::canvas_create() {
+RID RendererCanvasCull::canvas_allocate() {
+ return canvas_owner.allocate_rid();
+}
+void RendererCanvasCull::canvas_initialize(RID p_rid) {
Canvas *canvas = memnew(Canvas);
- ERR_FAIL_COND_V(!canvas, RID());
- RID rid = canvas_owner.make_rid(canvas);
-
- return rid;
+ canvas_owner.initialize_rid(p_rid, canvas);
}
void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) {
@@ -393,11 +395,12 @@ void RendererCanvasCull::canvas_set_parent(RID p_canvas, RID p_parent, float p_s
canvas->parent_scale = p_scale;
}
-RID RendererCanvasCull::canvas_item_create() {
+RID RendererCanvasCull::canvas_item_allocate() {
+ return canvas_item_owner.allocate_rid();
+}
+void RendererCanvasCull::canvas_item_initialize(RID p_rid) {
Item *canvas_item = memnew(Item);
- ERR_FAIL_COND_V(!canvas_item, RID());
-
- return canvas_item_owner.make_rid(canvas_item);
+ canvas_item_owner.initialize_rid(p_rid, canvas_item);
}
void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) {
@@ -524,11 +527,11 @@ void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from,
Item::CommandPrimitive *line = canvas_item->alloc_command<Item::CommandPrimitive>();
ERR_FAIL_COND(!line);
if (p_width > 1.001) {
- Vector2 t = (p_from - p_to).tangent().normalized();
- line->points[0] = p_from + t * p_width;
- line->points[1] = p_from - t * p_width;
- line->points[2] = p_to - t * p_width;
- line->points[3] = p_to + t * p_width;
+ Vector2 t = (p_from - p_to).orthogonal().normalized() * p_width * 0.5;
+ line->points[0] = p_from + t;
+ line->points[1] = p_from - t;
+ line->points[2] = p_to - t;
+ line->points[3] = p_to + t;
line->point_count = 4;
} else {
line->point_count = 2;
@@ -600,7 +603,7 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
if (i == pc - 1) {
t = prev_t;
} else {
- t = (p_points[i + 1] - p_points[i]).normalized().tangent();
+ t = (p_points[i + 1] - p_points[i]).normalized().orthogonal();
if (i == 0) {
prev_t = t;
}
@@ -650,7 +653,7 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point
if (i == pc - 1) {
t = prev_t;
} else {
- t = (p_points[i + 1] - p_points[i]).normalized().tangent();
+ t = (p_points[i + 1] - p_points[i]).normalized().orthogonal();
if (i == 0) {
prev_t = t;
}
@@ -721,8 +724,10 @@ void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos,
static const int circle_points = 64;
points.resize(circle_points);
+ const real_t circle_point_step = Math_TAU / circle_points;
+
for (int i = 0; i < circle_points; i++) {
- float angle = (i / float(circle_points)) * 2 * Math_PI;
+ float angle = i * circle_point_step;
points.write[i].x = Math::cos(angle) * p_radius;
points.write[i].y = Math::sin(angle) * p_radius;
points.write[i] += p_pos;
@@ -874,7 +879,7 @@ void RendererCanvasCull::canvas_item_add_polygon(RID p_item, const Vector<Point2
ERR_FAIL_COND(uv_size != 0 && (uv_size != pointcount));
#endif
Vector<int> indices = Geometry2D::triangulate_polygon(p_points);
- ERR_FAIL_COND_MSG(indices.empty(), "Invalid polygon data, triangulation failed.");
+ ERR_FAIL_COND_MSG(indices.is_empty(), "Invalid polygon data, triangulation failed.");
Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!polygon);
@@ -889,10 +894,10 @@ void RendererCanvasCull::canvas_item_add_triangle_array(RID p_item, const Vector
int vertex_count = p_points.size();
ERR_FAIL_COND(vertex_count == 0);
- ERR_FAIL_COND(!p_colors.empty() && p_colors.size() != vertex_count && p_colors.size() != 1);
- ERR_FAIL_COND(!p_uvs.empty() && p_uvs.size() != vertex_count);
- ERR_FAIL_COND(!p_bones.empty() && p_bones.size() != vertex_count * 4);
- ERR_FAIL_COND(!p_weights.empty() && p_weights.size() != vertex_count * 4);
+ ERR_FAIL_COND(!p_colors.is_empty() && p_colors.size() != vertex_count && p_colors.size() != 1);
+ ERR_FAIL_COND(!p_uvs.is_empty() && p_uvs.size() != vertex_count);
+ ERR_FAIL_COND(!p_bones.is_empty() && p_bones.size() != vertex_count * 4);
+ ERR_FAIL_COND(!p_weights.is_empty() && p_weights.size() != vertex_count * 4);
Vector<int> indices = p_indices;
@@ -1073,10 +1078,13 @@ void RendererCanvasCull::canvas_item_set_canvas_group_mode(RID p_item, RS::Canva
}
}
-RID RendererCanvasCull::canvas_light_create() {
+RID RendererCanvasCull::canvas_light_allocate() {
+ return canvas_light_owner.allocate_rid();
+}
+void RendererCanvasCull::canvas_light_initialize(RID p_rid) {
RendererCanvasRender::Light *clight = memnew(RendererCanvasRender::Light);
clight->light_internal = RSG::canvas_render->light_create();
- return canvas_light_owner.make_rid(clight);
+ return canvas_light_owner.initialize_rid(p_rid, clight);
}
void RendererCanvasCull::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) {
@@ -1266,10 +1274,13 @@ void RendererCanvasCull::canvas_light_set_shadow_smooth(RID p_light, float p_smo
clight->shadow_smooth = p_smooth;
}
-RID RendererCanvasCull::canvas_light_occluder_create() {
+RID RendererCanvasCull::canvas_light_occluder_allocate() {
+ return canvas_light_occluder_owner.allocate_rid();
+}
+void RendererCanvasCull::canvas_light_occluder_initialize(RID p_rid) {
RendererCanvasRender::LightOccluderInstance *occluder = memnew(RendererCanvasRender::LightOccluderInstance);
- return canvas_light_occluder_owner.make_rid(occluder);
+ return canvas_light_occluder_owner.initialize_rid(p_rid, occluder);
}
void RendererCanvasCull::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) {
@@ -1347,10 +1358,13 @@ void RendererCanvasCull::canvas_light_occluder_set_light_mask(RID p_occluder, in
occluder->light_mask = p_mask;
}
-RID RendererCanvasCull::canvas_occluder_polygon_create() {
+RID RendererCanvasCull::canvas_occluder_polygon_allocate() {
+ return canvas_light_occluder_polygon_owner.allocate_rid();
+}
+void RendererCanvasCull::canvas_occluder_polygon_initialize(RID p_rid) {
LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon);
occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create();
- return canvas_light_occluder_polygon_owner.make_rid(occluder_poly);
+ return canvas_light_occluder_polygon_owner.initialize_rid(p_rid, occluder_poly);
}
void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) {
@@ -1391,8 +1405,11 @@ void RendererCanvasCull::canvas_set_shadow_texture_size(int p_size) {
RSG::canvas_render->set_shadow_texture_size(p_size);
}
-RID RendererCanvasCull::canvas_texture_create() {
- return RSG::storage->canvas_texture_create();
+RID RendererCanvasCull::canvas_texture_allocate() {
+ return RSG::storage->canvas_texture_allocate();
+}
+void RendererCanvasCull::canvas_texture_initialize(RID p_rid) {
+ RSG::storage->canvas_texture_initialize(p_rid);
}
void RendererCanvasCull::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index ec2389bcb5..b71f8e5a9a 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -101,9 +101,9 @@ public:
}
};
- RID_PtrOwner<LightOccluderPolygon> canvas_light_occluder_polygon_owner;
+ RID_PtrOwner<LightOccluderPolygon, true> canvas_light_occluder_polygon_owner;
- RID_PtrOwner<RendererCanvasRender::LightOccluderInstance> canvas_light_occluder_owner;
+ RID_PtrOwner<RendererCanvasRender::LightOccluderInstance, true> canvas_light_occluder_owner;
struct Canvas : public RendererViewport::CanvasBase {
Set<RID> viewports;
@@ -148,9 +148,9 @@ public:
}
};
- mutable RID_PtrOwner<Canvas> canvas_owner;
- RID_PtrOwner<Item> canvas_item_owner;
- RID_PtrOwner<RendererCanvasRender::Light> canvas_light_owner;
+ mutable RID_PtrOwner<Canvas, true> canvas_owner;
+ RID_PtrOwner<Item, true> canvas_item_owner;
+ RID_PtrOwner<RendererCanvasRender::Light, true> canvas_light_owner;
bool disable_scale;
bool sdf_used = false;
@@ -168,13 +168,17 @@ public:
bool was_sdf_used();
- RID canvas_create();
+ RID canvas_allocate();
+ void canvas_initialize(RID p_rid);
+
void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring);
void canvas_set_modulate(RID p_canvas, const Color &p_color);
void canvas_set_parent(RID p_canvas, RID p_parent, float p_scale);
void canvas_set_disable_scale(bool p_disable);
- RID canvas_item_create();
+ RID canvas_item_allocate();
+ void canvas_item_initialize(RID p_rid);
+
void canvas_item_set_parent(RID p_item, RID p_parent);
void canvas_item_set_visible(RID p_item, bool p_visible);
@@ -222,7 +226,9 @@ public:
void canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin = 5.0, bool p_fit_empty = false, float p_fit_margin = 0.0, bool p_blur_mipmaps = false);
- RID canvas_light_create();
+ RID canvas_light_allocate();
+ void canvas_light_initialize(RID p_rid);
+
void canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode);
void canvas_light_attach_to_canvas(RID p_light, RID p_canvas);
void canvas_light_set_enabled(RID p_light, bool p_enabled);
@@ -246,7 +252,9 @@ public:
void canvas_light_set_shadow_color(RID p_light, const Color &p_color);
void canvas_light_set_shadow_smooth(RID p_light, float p_smooth);
- RID canvas_light_occluder_create();
+ RID canvas_light_occluder_allocate();
+ void canvas_light_occluder_initialize(RID p_rid);
+
void canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas);
void canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled);
void canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon);
@@ -254,14 +262,18 @@ public:
void canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform);
void canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask);
- RID canvas_occluder_polygon_create();
+ RID canvas_occluder_polygon_allocate();
+ void canvas_occluder_polygon_initialize(RID p_rid);
+
void canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed);
void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode);
void canvas_set_shadow_texture_size(int p_size);
- RID canvas_texture_create();
+ RID canvas_texture_allocate();
+ void canvas_texture_initialize(RID p_rid);
+
void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture);
void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess);
diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp
index 9c7251763d..1945435586 100644
--- a/servers/rendering/renderer_canvas_render.cpp
+++ b/servers/rendering/renderer_canvas_render.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h
index ca95abcf65..f08986b021 100644
--- a/servers/rendering/renderer_canvas_render.h
+++ b/servers/rendering/renderer_canvas_render.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp
index e8c4a236fa..8861522d34 100644
--- a/servers/rendering/renderer_compositor.cpp
+++ b/servers/rendering/renderer_compositor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h
index f328330efa..919ae2c6da 100644
--- a/servers/rendering/renderer_compositor.h
+++ b/servers/rendering/renderer_compositor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
new file mode 100644
index 0000000000..0fdd864d47
--- /dev/null
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -0,0 +1,555 @@
+/*************************************************************************/
+/* cluster_builder_rd.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "cluster_builder_rd.h"
+#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/rendering_server_globals.h"
+
+ClusterBuilderSharedDataRD::ClusterBuilderSharedDataRD() {
+ RD::VertexFormatID vertex_format;
+
+ {
+ Vector<RD::VertexAttribute> attributes;
+ {
+ RD::VertexAttribute va;
+ va.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
+ va.stride = sizeof(float) * 3;
+ attributes.push_back(va);
+ }
+ vertex_format = RD::get_singleton()->vertex_format_create(attributes);
+ }
+
+ {
+ Vector<String> versions;
+ versions.push_back("");
+ cluster_render.cluster_render_shader.initialize(versions);
+ cluster_render.shader_version = cluster_render.cluster_render_shader.version_create();
+ cluster_render.shader = cluster_render.cluster_render_shader.version_get_shader(cluster_render.shader_version, 0);
+ cluster_render.shader_pipelines[ClusterRender::PIPELINE_NORMAL] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, RD::get_singleton()->framebuffer_format_create_empty(), vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState(), 0);
+ RD::PipelineMultisampleState ms;
+ ms.sample_count = RD::TEXTURE_SAMPLES_4;
+ cluster_render.shader_pipelines[ClusterRender::PIPELINE_MSAA] = RD::get_singleton()->render_pipeline_create(cluster_render.shader, RD::get_singleton()->framebuffer_format_create_empty(), vertex_format, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), ms, RD::PipelineDepthStencilState(), RD::PipelineColorBlendState(), 0);
+ }
+ {
+ Vector<String> versions;
+ versions.push_back("");
+ cluster_store.cluster_store_shader.initialize(versions);
+ cluster_store.shader_version = cluster_store.cluster_store_shader.version_create();
+ cluster_store.shader = cluster_store.cluster_store_shader.version_get_shader(cluster_store.shader_version, 0);
+ cluster_store.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_store.shader);
+ }
+ {
+ Vector<String> versions;
+ versions.push_back("");
+ cluster_debug.cluster_debug_shader.initialize(versions);
+ cluster_debug.shader_version = cluster_debug.cluster_debug_shader.version_create();
+ cluster_debug.shader = cluster_debug.cluster_debug_shader.version_get_shader(cluster_debug.shader_version, 0);
+ cluster_debug.shader_pipeline = RD::get_singleton()->compute_pipeline_create(cluster_debug.shader);
+ }
+
+ { // SPHERE
+ static const uint32_t icosphere_vertex_count = 42;
+ static const float icosphere_vertices[icosphere_vertex_count * 3] = {
+ 0, 0, -1, 0.7236073, -0.5257253, -0.4472195, -0.276388, -0.8506492, -0.4472199, -0.8944262, 0, -0.4472156, -0.276388, 0.8506492, -0.4472199, 0.7236073, 0.5257253, -0.4472195, 0.276388, -0.8506492, 0.4472199, -0.7236073, -0.5257253, 0.4472195, -0.7236073, 0.5257253, 0.4472195, 0.276388, 0.8506492, 0.4472199, 0.8944262, 0, 0.4472156, 0, 0, 1, -0.1624555, -0.4999952, -0.8506544, 0.4253227, -0.3090114, -0.8506542, 0.2628688, -0.8090116, -0.5257377, 0.8506479, 0, -0.5257359, 0.4253227, 0.3090114, -0.8506542, -0.5257298, 0, -0.8506517, -0.6881894, -0.4999969, -0.5257362, -0.1624555, 0.4999952, -0.8506544, -0.6881894, 0.4999969, -0.5257362, 0.2628688, 0.8090116, -0.5257377, 0.9510579, -0.3090126, 0, 0.9510579, 0.3090126, 0, 0, -1, 0, 0.5877856, -0.8090167, 0, -0.9510579, -0.3090126, 0, -0.5877856, -0.8090167, 0, -0.5877856, 0.8090167, 0, -0.9510579, 0.3090126, 0, 0.5877856, 0.8090167, 0, 0, 1, 0, 0.6881894, -0.4999969, 0.5257362, -0.2628688, -0.8090116, 0.5257377, -0.8506479, 0, 0.5257359, -0.2628688, 0.8090116, 0.5257377, 0.6881894, 0.4999969, 0.5257362, 0.1624555, -0.4999952, 0.8506544, 0.5257298, 0, 0.8506517, -0.4253227, -0.3090114, 0.8506542, -0.4253227, 0.3090114, 0.8506542, 0.1624555, 0.4999952, 0.8506544
+ };
+ static const uint32_t icosphere_triangle_count = 80;
+ static const uint32_t icosphere_triangle_indices[icosphere_triangle_count * 3] = {
+ 0, 13, 12, 1, 13, 15, 0, 12, 17, 0, 17, 19, 0, 19, 16, 1, 15, 22, 2, 14, 24, 3, 18, 26, 4, 20, 28, 5, 21, 30, 1, 22, 25, 2, 24, 27, 3, 26, 29, 4, 28, 31, 5, 30, 23, 6, 32, 37, 7, 33, 39, 8, 34, 40, 9, 35, 41, 10, 36, 38, 38, 41, 11, 38, 36, 41, 36, 9, 41, 41, 40, 11, 41, 35, 40, 35, 8, 40, 40, 39, 11, 40, 34, 39, 34, 7, 39, 39, 37, 11, 39, 33, 37, 33, 6, 37, 37, 38, 11, 37, 32, 38, 32, 10, 38, 23, 36, 10, 23, 30, 36, 30, 9, 36, 31, 35, 9, 31, 28, 35, 28, 8, 35, 29, 34, 8, 29, 26, 34, 26, 7, 34, 27, 33, 7, 27, 24, 33, 24, 6, 33, 25, 32, 6, 25, 22, 32, 22, 10, 32, 30, 31, 9, 30, 21, 31, 21, 4, 31, 28, 29, 8, 28, 20, 29, 20, 3, 29, 26, 27, 7, 26, 18, 27, 18, 2, 27, 24, 25, 6, 24, 14, 25, 14, 1, 25, 22, 23, 10, 22, 15, 23, 15, 5, 23, 16, 21, 5, 16, 19, 21, 19, 4, 21, 19, 20, 4, 19, 17, 20, 17, 3, 20, 17, 18, 3, 17, 12, 18, 12, 2, 18, 15, 16, 5, 15, 13, 16, 13, 0, 16, 12, 14, 2, 12, 13, 14, 13, 1, 14
+ };
+
+ Vector<uint8_t> vertex_data;
+ vertex_data.resize(sizeof(float) * icosphere_vertex_count * 3);
+ copymem(vertex_data.ptrw(), icosphere_vertices, vertex_data.size());
+
+ sphere_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
+
+ Vector<uint8_t> index_data;
+ index_data.resize(sizeof(uint32_t) * icosphere_triangle_count * 3);
+ copymem(index_data.ptrw(), icosphere_triangle_indices, index_data.size());
+
+ sphere_index_buffer = RD::get_singleton()->index_buffer_create(icosphere_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data);
+
+ Vector<RID> buffers;
+ buffers.push_back(sphere_vertex_buffer);
+
+ sphere_vertex_array = RD::get_singleton()->vertex_array_create(icosphere_vertex_count, vertex_format, buffers);
+
+ sphere_index_array = RD::get_singleton()->index_array_create(sphere_index_buffer, 0, icosphere_triangle_count * 3);
+
+ float min_d = 1e20;
+ for (uint32_t i = 0; i < icosphere_triangle_count; i++) {
+ Vector3 vertices[3];
+ for (uint32_t j = 0; j < 3; j++) {
+ uint32_t index = icosphere_triangle_indices[i * 3 + j];
+ for (uint32_t k = 0; k < 3; k++) {
+ vertices[j][k] = icosphere_vertices[index * 3 + k];
+ }
+ }
+ Plane p(vertices[0], vertices[1], vertices[2]);
+ min_d = MIN(Math::abs(p.d), min_d);
+ }
+ sphere_overfit = 1.0 / min_d;
+ }
+
+ { // CONE
+ static const uint32_t cone_vertex_count = 99;
+ static const float cone_vertices[cone_vertex_count * 3] = {
+ 0, 1, -1, 0.1950903, 0.9807853, -1, 0.3826835, 0.9238795, -1, 0.5555703, 0.8314696, -1, 0.7071068, 0.7071068, -1, 0.8314697, 0.5555702, -1, 0.9238795, 0.3826834, -1, 0.9807853, 0.1950903, -1, 1, 0, -1, 0.9807853, -0.1950902, -1, 0.9238796, -0.3826833, -1, 0.8314697, -0.5555702, -1, 0.7071068, -0.7071068, -1, 0.5555702, -0.8314697, -1, 0.3826833, -0.9238796, -1, 0.1950901, -0.9807853, -1, -3.25841e-7, -1, -1, -0.1950907, -0.9807852, -1, -0.3826839, -0.9238793, -1, -0.5555707, -0.8314693, -1, -0.7071073, -0.7071063, -1, -0.83147, -0.5555697, -1, -0.9238799, -0.3826827, -1, 0, 0, 0, -0.9807854, -0.1950894, -1, -1, 9.65599e-7, -1, -0.9807851, 0.1950913, -1, -0.9238791, 0.3826845, -1, -0.8314689, 0.5555713, -1, -0.7071059, 0.7071077, -1, -0.5555691, 0.8314704, -1, -0.3826821, 0.9238801, -1, -0.1950888, 0.9807856, -1
+ };
+ static const uint32_t cone_triangle_count = 62;
+ static const uint32_t cone_triangle_indices[cone_triangle_count * 3] = {
+ 0, 23, 1, 1, 23, 2, 2, 23, 3, 3, 23, 4, 4, 23, 5, 5, 23, 6, 6, 23, 7, 7, 23, 8, 8, 23, 9, 9, 23, 10, 10, 23, 11, 11, 23, 12, 12, 23, 13, 13, 23, 14, 14, 23, 15, 15, 23, 16, 16, 23, 17, 17, 23, 18, 18, 23, 19, 19, 23, 20, 20, 23, 21, 21, 23, 22, 22, 23, 24, 24, 23, 25, 25, 23, 26, 26, 23, 27, 27, 23, 28, 28, 23, 29, 29, 23, 30, 30, 23, 31, 31, 23, 32, 32, 23, 0, 7, 15, 24, 32, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 3, 6, 7, 3, 7, 8, 9, 9, 10, 7, 10, 11, 7, 11, 12, 15, 12, 13, 15, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20, 24, 20, 21, 24, 21, 22, 24, 24, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 1, 3, 15, 17, 24, 17, 19, 24, 24, 26, 32, 26, 28, 32, 28, 30, 32, 32, 3, 7, 7, 11, 15, 32, 7, 24
+ };
+
+ Vector<uint8_t> vertex_data;
+ vertex_data.resize(sizeof(float) * cone_vertex_count * 3);
+ copymem(vertex_data.ptrw(), cone_vertices, vertex_data.size());
+
+ cone_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
+
+ Vector<uint8_t> index_data;
+ index_data.resize(sizeof(uint32_t) * cone_triangle_count * 3);
+ copymem(index_data.ptrw(), cone_triangle_indices, index_data.size());
+
+ cone_index_buffer = RD::get_singleton()->index_buffer_create(cone_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data);
+
+ Vector<RID> buffers;
+ buffers.push_back(cone_vertex_buffer);
+
+ cone_vertex_array = RD::get_singleton()->vertex_array_create(cone_vertex_count, vertex_format, buffers);
+
+ cone_index_array = RD::get_singleton()->index_array_create(cone_index_buffer, 0, cone_triangle_count * 3);
+
+ float min_d = 1e20;
+ for (uint32_t i = 0; i < cone_triangle_count; i++) {
+ Vector3 vertices[3];
+ int32_t zero_index = -1;
+ for (uint32_t j = 0; j < 3; j++) {
+ uint32_t index = cone_triangle_indices[i * 3 + j];
+ for (uint32_t k = 0; k < 3; k++) {
+ vertices[j][k] = cone_vertices[index * 3 + k];
+ }
+ if (vertices[j] == Vector3()) {
+ zero_index = j;
+ }
+ }
+
+ if (zero_index != -1) {
+ Vector3 a = vertices[(zero_index + 1) % 3];
+ Vector3 b = vertices[(zero_index + 2) % 3];
+ Vector3 c = a + Vector3(0, 0, 1);
+ Plane p(a, b, c);
+ min_d = MIN(Math::abs(p.d), min_d);
+ }
+ }
+ cone_overfit = 1.0 / min_d;
+ }
+
+ { // BOX
+ static const uint32_t box_vertex_count = 8;
+ static const float box_vertices[box_vertex_count * 3] = {
+ -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1
+ };
+ static const uint32_t box_triangle_count = 12;
+ static const uint32_t box_triangle_indices[box_triangle_count * 3] = {
+ 1, 2, 0, 3, 6, 2, 7, 4, 6, 5, 0, 4, 6, 0, 2, 3, 5, 7, 1, 3, 2, 3, 7, 6, 7, 5, 4, 5, 1, 0, 6, 4, 0, 3, 1, 5
+ };
+
+ Vector<uint8_t> vertex_data;
+ vertex_data.resize(sizeof(float) * box_vertex_count * 3);
+ copymem(vertex_data.ptrw(), box_vertices, vertex_data.size());
+
+ box_vertex_buffer = RD::get_singleton()->vertex_buffer_create(vertex_data.size(), vertex_data);
+
+ Vector<uint8_t> index_data;
+ index_data.resize(sizeof(uint32_t) * box_triangle_count * 3);
+ copymem(index_data.ptrw(), box_triangle_indices, index_data.size());
+
+ box_index_buffer = RD::get_singleton()->index_buffer_create(box_triangle_count * 3, RD::INDEX_BUFFER_FORMAT_UINT32, index_data);
+
+ Vector<RID> buffers;
+ buffers.push_back(box_vertex_buffer);
+
+ box_vertex_array = RD::get_singleton()->vertex_array_create(box_vertex_count, vertex_format, buffers);
+
+ box_index_array = RD::get_singleton()->index_array_create(box_index_buffer, 0, box_triangle_count * 3);
+ }
+}
+ClusterBuilderSharedDataRD::~ClusterBuilderSharedDataRD() {
+ RD::get_singleton()->free(sphere_vertex_buffer);
+ RD::get_singleton()->free(sphere_index_buffer);
+ RD::get_singleton()->free(cone_vertex_buffer);
+ RD::get_singleton()->free(cone_index_buffer);
+ RD::get_singleton()->free(box_vertex_buffer);
+ RD::get_singleton()->free(box_index_buffer);
+
+ cluster_render.cluster_render_shader.version_free(cluster_render.shader_version);
+ cluster_store.cluster_store_shader.version_free(cluster_store.shader_version);
+ cluster_debug.cluster_debug_shader.version_free(cluster_debug.shader_version);
+}
+
+/////////////////////////////
+
+void ClusterBuilderRD::_clear() {
+ if (cluster_buffer.is_null()) {
+ return; //nothing to clear
+ }
+ RD::get_singleton()->free(cluster_buffer);
+ RD::get_singleton()->free(cluster_render_buffer);
+ RD::get_singleton()->free(element_buffer);
+ cluster_buffer = RID();
+ cluster_render_buffer = RID();
+ element_buffer = RID();
+
+ memfree(render_elements);
+
+ render_elements = nullptr;
+ render_element_max = 0;
+ render_element_count = 0;
+
+ RD::get_singleton()->free(framebuffer);
+ framebuffer = RID();
+
+ cluster_render_uniform_set = RID();
+ cluster_store_uniform_set = RID();
+}
+
+void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer) {
+ ERR_FAIL_COND(p_max_elements == 0);
+ ERR_FAIL_COND(p_screen_size.x < 1);
+ ERR_FAIL_COND(p_screen_size.y < 1);
+
+ _clear();
+
+ screen_size = p_screen_size;
+
+ cluster_screen_size.width = (p_screen_size.width - 1) / cluster_size + 1;
+ cluster_screen_size.height = (p_screen_size.height - 1) / cluster_size + 1;
+
+ max_elements_by_type = p_max_elements;
+ if (max_elements_by_type % 32) { //need to be 32 aligned
+ max_elements_by_type += 32 - (max_elements_by_type % 32);
+ }
+
+ cluster_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (max_elements_by_type / 32 + 32) * ELEMENT_TYPE_MAX * 4;
+
+ render_element_max = max_elements_by_type * ELEMENT_TYPE_MAX;
+
+ uint32_t element_tag_bits_size = render_element_max / 32;
+ uint32_t element_tag_depth_bits_size = render_element_max;
+ cluster_render_buffer_size = cluster_screen_size.x * cluster_screen_size.y * (element_tag_bits_size + element_tag_depth_bits_size) * 4; // tag bits (element was used) and tag depth (depth range in which it was used)
+
+ cluster_render_buffer = RD::get_singleton()->storage_buffer_create(cluster_render_buffer_size);
+ cluster_buffer = RD::get_singleton()->storage_buffer_create(cluster_buffer_size);
+
+ render_elements = (RenderElementData *)memalloc(sizeof(RenderElementData *) * render_element_max);
+ render_element_count = 0;
+
+ element_buffer = RD::get_singleton()->storage_buffer_create(sizeof(RenderElementData) * render_element_max);
+
+ uint32_t div_value = 1 << divisor;
+ if (use_msaa) {
+ framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value, RD::TEXTURE_SAMPLES_4);
+ } else {
+ framebuffer = RD::get_singleton()->framebuffer_create_empty(p_screen_size / div_value);
+ }
+
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(state_uniform);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(element_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 3;
+ u.ids.push_back(cluster_render_buffer);
+ uniforms.push_back(u);
+ }
+
+ cluster_render_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_render.shader, 0);
+ }
+
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(cluster_render_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(cluster_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 3;
+ u.ids.push_back(element_buffer);
+ uniforms.push_back(u);
+ }
+
+ cluster_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_store.shader, 0);
+ }
+
+ if (p_color_buffer.is_valid()) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(cluster_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(p_color_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 3;
+ u.ids.push_back(p_depth_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 4;
+ u.ids.push_back(p_depth_buffer_sampler);
+ uniforms.push_back(u);
+ }
+
+ debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shared->cluster_debug.shader, 0);
+ } else {
+ debug_uniform_set = RID();
+ }
+}
+
+void ClusterBuilderRD::begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y) {
+ view_xform = p_view_transform.affine_inverse();
+ projection = p_cam_projection;
+ z_near = projection.get_z_near();
+ z_far = projection.get_z_far();
+ orthogonal = p_cam_projection.is_orthogonal();
+ adjusted_projection = projection;
+ if (!orthogonal) {
+ adjusted_projection.adjust_perspective_znear(0.0001);
+ }
+
+ CameraMatrix correction;
+ correction.set_depth_correction(p_flip_y);
+ projection = correction * projection;
+ adjusted_projection = correction * adjusted_projection;
+
+ //reset counts
+ render_element_count = 0;
+ for (uint32_t i = 0; i < ELEMENT_TYPE_MAX; i++) {
+ cluster_count_by_type[i] = 0;
+ }
+}
+
+void ClusterBuilderRD::bake_cluster() {
+ RENDER_TIMESTAMP(">Bake Cluster");
+
+ RD::get_singleton()->draw_command_begin_label("Bake Light Cluster");
+
+ //clear cluster buffer
+ RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+
+ if (render_element_count > 0) {
+ //clear render buffer
+ RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size, RD::BARRIER_MASK_RASTER);
+
+ { //fill state uniform
+
+ StateUniform state;
+
+ RendererStorageRD::store_camera(adjusted_projection, state.projection);
+ state.inv_z_far = 1.0 / z_far;
+ state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size);
+ state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less
+
+ state.cluster_screen_width = cluster_screen_size.x;
+ state.cluster_depth_offset = (render_element_max / 32);
+ state.cluster_data_size = state.cluster_depth_offset + render_element_max;
+
+ RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ }
+
+ //update instances
+
+ RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+
+ RENDER_TIMESTAMP("Render Elements");
+
+ //render elements
+ {
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
+ ClusterBuilderSharedDataRD::ClusterRender::PushConstant push_constant = {};
+
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, shared->cluster_render.shader_pipelines[use_msaa ? ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_MSAA : ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_NORMAL]);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, cluster_render_uniform_set, 0);
+
+ for (uint32_t i = 0; i < render_element_count;) {
+ push_constant.base_index = i;
+ switch (render_elements[i].type) {
+ case ELEMENT_TYPE_OMNI_LIGHT: {
+ RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->sphere_vertex_array);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->sphere_index_array);
+ } break;
+ case ELEMENT_TYPE_SPOT_LIGHT: {
+ RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->cone_vertex_array);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->cone_index_array);
+ } break;
+ case ELEMENT_TYPE_DECAL:
+ case ELEMENT_TYPE_REFLECTION_PROBE: {
+ RD::get_singleton()->draw_list_bind_vertex_array(draw_list, shared->box_vertex_array);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, shared->box_index_array);
+ } break;
+ }
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterRender::PushConstant));
+
+ uint32_t instances = 1;
+#if 0
+ for (uint32_t j = i+1; j < element_count; j++) {
+ if (elements[i].type!=elements[j].type) {
+ break;
+ }
+ instances++;
+ }
+#endif
+ RD::get_singleton()->draw_list_draw(draw_list, true, instances);
+ i += instances;
+ }
+ RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_COMPUTE);
+ }
+ //store elements
+ RENDER_TIMESTAMP("Pack Elements");
+
+ {
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_store.shader_pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cluster_store_uniform_set, 0);
+
+ ClusterBuilderSharedDataRD::ClusterStore::PushConstant push_constant;
+ push_constant.cluster_render_data_size = render_element_max / 32 + render_element_max;
+ push_constant.max_render_element_count_div_32 = render_element_max / 32;
+ push_constant.cluster_screen_size[0] = cluster_screen_size.x;
+ push_constant.cluster_screen_size[1] = cluster_screen_size.y;
+ push_constant.render_element_count_div_32 = render_element_count > 0 ? (render_element_count - 1) / 32 + 1 : 0;
+ push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;
+ push_constant.pad1 = 0;
+ push_constant.pad2 = 0;
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterStore::PushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cluster_screen_size.x, cluster_screen_size.y, 1);
+
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ }
+ } else {
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_TRANSFER, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ }
+ RENDER_TIMESTAMP("<Bake Cluster");
+ RD::get_singleton()->draw_command_end_label();
+}
+
+void ClusterBuilderRD::debug(ElementType p_element) {
+ ERR_FAIL_COND(debug_uniform_set.is_null());
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shared->cluster_debug.shader_pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set, 0);
+
+ ClusterBuilderSharedDataRD::ClusterDebug::PushConstant push_constant;
+ push_constant.screen_size[0] = screen_size.x;
+ push_constant.screen_size[1] = screen_size.y;
+ push_constant.cluster_screen_size[0] = cluster_screen_size.x;
+ push_constant.cluster_screen_size[1] = cluster_screen_size.y;
+ push_constant.cluster_shift = get_shift_from_power_of_2(cluster_size);
+ push_constant.cluster_type = p_element;
+ push_constant.orthogonal = orthogonal;
+ push_constant.z_far = z_far;
+ push_constant.z_near = z_near;
+ push_constant.max_cluster_element_count_div_32 = max_elements_by_type / 32;
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ClusterBuilderSharedDataRD::ClusterDebug::PushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, screen_size.x, screen_size.y, 1);
+
+ RD::get_singleton()->compute_list_end();
+}
+
+RID ClusterBuilderRD::get_cluster_buffer() const {
+ return cluster_buffer;
+}
+
+uint32_t ClusterBuilderRD::get_cluster_size() const {
+ return cluster_size;
+}
+
+uint32_t ClusterBuilderRD::get_max_cluster_elements() const {
+ return max_elements_by_type;
+}
+
+void ClusterBuilderRD::set_shared(ClusterBuilderSharedDataRD *p_shared) {
+ shared = p_shared;
+}
+
+ClusterBuilderRD::ClusterBuilderRD() {
+ state_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(StateUniform));
+}
+
+ClusterBuilderRD::~ClusterBuilderRD() {
+ _clear();
+ RD::get_singleton()->free(state_uniform);
+}
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h
new file mode 100644
index 0000000000..dc1707b534
--- /dev/null
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.h
@@ -0,0 +1,378 @@
+/*************************************************************************/
+/* cluster_builder_rd.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef CLUSTER_BUILDER_RD_H
+#define CLUSTER_BUILDER_RD_H
+
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shaders/cluster_debug.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/cluster_render.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/cluster_store.glsl.gen.h"
+
+class ClusterBuilderSharedDataRD {
+ friend class ClusterBuilderRD;
+
+ RID sphere_vertex_buffer;
+ RID sphere_vertex_array;
+ RID sphere_index_buffer;
+ RID sphere_index_array;
+ float sphere_overfit = 0.0; //because an icosphere is not a perfect sphere, we need to enlarge it to cover the sphere area
+
+ RID cone_vertex_buffer;
+ RID cone_vertex_array;
+ RID cone_index_buffer;
+ RID cone_index_array;
+ float cone_overfit = 0.0; //because an cone mesh is not a perfect sphere, we need to enlarge it to cover the actual cone area
+
+ RID box_vertex_buffer;
+ RID box_vertex_array;
+ RID box_index_buffer;
+ RID box_index_array;
+
+ enum Divisor {
+ DIVISOR_1,
+ DIVISOR_2,
+ DIVISOR_4,
+ };
+
+ struct ClusterRender {
+ struct PushConstant {
+ uint32_t base_index;
+ uint32_t pad0;
+ uint32_t pad1;
+ uint32_t pad2;
+ };
+
+ ClusterRenderShaderRD cluster_render_shader;
+ RID shader_version;
+ RID shader;
+ enum PipelineVersion {
+ PIPELINE_NORMAL,
+ PIPELINE_MSAA,
+ PIPELINE_MAX
+ };
+
+ RID shader_pipelines[PIPELINE_MAX];
+ } cluster_render;
+
+ struct ClusterStore {
+ struct PushConstant {
+ uint32_t cluster_render_data_size; // how much data for a single cluster takes
+ uint32_t max_render_element_count_div_32; //divided by 32
+ uint32_t cluster_screen_size[2];
+ uint32_t render_element_count_div_32; //divided by 32
+ uint32_t max_cluster_element_count_div_32; //divided by 32
+ uint32_t pad1;
+ uint32_t pad2;
+ };
+
+ ClusterStoreShaderRD cluster_store_shader;
+ RID shader_version;
+ RID shader;
+ RID shader_pipeline;
+ } cluster_store;
+
+ struct ClusterDebug {
+ struct PushConstant {
+ uint32_t screen_size[2];
+ uint32_t cluster_screen_size[2];
+
+ uint32_t cluster_shift;
+ uint32_t cluster_type;
+ float z_near;
+ float z_far;
+
+ uint32_t orthogonal;
+ uint32_t max_cluster_element_count_div_32;
+ uint32_t pad1;
+ uint32_t pad2;
+ };
+
+ ClusterDebugShaderRD cluster_debug_shader;
+ RID shader_version;
+ RID shader;
+ RID shader_pipeline;
+ } cluster_debug;
+
+public:
+ ClusterBuilderSharedDataRD();
+ ~ClusterBuilderSharedDataRD();
+};
+
+class ClusterBuilderRD {
+public:
+ enum LightType {
+ LIGHT_TYPE_OMNI,
+ LIGHT_TYPE_SPOT
+ };
+
+ enum BoxType {
+ BOX_TYPE_REFLECTION_PROBE,
+ BOX_TYPE_DECAL,
+ };
+
+ enum ElementType {
+ ELEMENT_TYPE_OMNI_LIGHT,
+ ELEMENT_TYPE_SPOT_LIGHT,
+ ELEMENT_TYPE_DECAL,
+ ELEMENT_TYPE_REFLECTION_PROBE,
+ ELEMENT_TYPE_MAX,
+
+ };
+
+private:
+ ClusterBuilderSharedDataRD *shared = nullptr;
+
+ struct RenderElementData {
+ uint32_t type; //0-4
+ uint32_t touches_near;
+ uint32_t touches_far;
+ uint32_t original_index;
+ float transform_inv[12]; //transposed transform for less space
+ float scale[3];
+ uint32_t pad;
+ };
+
+ uint32_t cluster_count_by_type[ELEMENT_TYPE_MAX] = {};
+ uint32_t max_elements_by_type = 0;
+
+ RenderElementData *render_elements = nullptr;
+ uint32_t render_element_count = 0;
+ uint32_t render_element_max = 0;
+
+ Transform view_xform;
+ CameraMatrix adjusted_projection;
+ CameraMatrix projection;
+ float z_far = 0;
+ float z_near = 0;
+ bool orthogonal = false;
+
+ enum Divisor {
+ DIVISOR_1,
+ DIVISOR_2,
+ DIVISOR_4,
+ };
+
+ uint32_t cluster_size = 32;
+ bool use_msaa = true;
+ Divisor divisor = DIVISOR_4;
+
+ Size2i screen_size;
+ Size2i cluster_screen_size;
+
+ RID framebuffer;
+ RID cluster_render_buffer; //used for creating
+ RID cluster_buffer; //used for rendering
+ RID element_buffer; //used for storing, to hint element touches far plane or near plane
+ uint32_t cluster_render_buffer_size = 0;
+ uint32_t cluster_buffer_size = 0;
+
+ RID cluster_render_uniform_set;
+ RID cluster_store_uniform_set;
+
+ //persistent data
+
+ void _clear();
+
+ struct StateUniform {
+ float projection[16];
+ float inv_z_far;
+ uint32_t screen_to_clusters_shift; // shift to obtain coordinates in block indices
+ uint32_t cluster_screen_width; //
+ uint32_t cluster_data_size; // how much data for a single cluster takes
+ uint32_t cluster_depth_offset;
+ uint32_t pad0;
+ uint32_t pad1;
+ uint32_t pad2;
+ };
+
+ RID state_uniform;
+
+ RID debug_uniform_set;
+
+public:
+ void setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer);
+
+ void begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y);
+
+ _FORCE_INLINE_ void add_light(LightType p_type, const Transform &p_transform, float p_radius, float p_spot_aperture) {
+ if (p_type == LIGHT_TYPE_OMNI && cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT] == max_elements_by_type) {
+ return; //max number elements reached
+ }
+ if (p_type == LIGHT_TYPE_SPOT && cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT] == max_elements_by_type) {
+ return; //max number elements reached
+ }
+
+ RenderElementData &e = render_elements[render_element_count];
+
+ Transform xform = view_xform * p_transform;
+
+ float radius = xform.basis.get_uniform_scale();
+ if (radius > 0.98 || radius < 1.02) {
+ xform.basis.orthonormalize();
+ }
+
+ radius *= p_radius;
+
+ if (p_type == LIGHT_TYPE_OMNI) {
+ radius *= shared->sphere_overfit; // overfit icosphere
+
+ //omni
+ float depth = -xform.origin.z;
+ if (orthogonal) {
+ e.touches_near = (depth - radius) < z_near;
+ } else {
+ //contains camera inside light
+ float radius2 = radius * shared->sphere_overfit; // overfit again for outer size (camera may be outside actual sphere but behind an icosphere vertex)
+ e.touches_near = xform.origin.length_squared() < radius2 * radius2;
+ }
+
+ e.touches_far = (depth + radius) > z_far;
+ e.scale[0] = radius;
+ e.scale[1] = radius;
+ e.scale[2] = radius;
+ e.type = ELEMENT_TYPE_OMNI_LIGHT;
+ e.original_index = cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT];
+
+ RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+
+ cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT]++;
+
+ } else {
+ //spot
+ radius *= shared->cone_overfit; // overfit icosphere
+
+ real_t len = Math::tan(Math::deg2rad(p_spot_aperture)) * radius;
+ //approximate, probably better to use a cone support function
+ float max_d = -1e20;
+ float min_d = 1e20;
+#define CONE_MINMAX(m_x, m_y) \
+ { \
+ float d = -xform.xform(Vector3(len * m_x, len * m_y, -radius)).z; \
+ min_d = MIN(d, min_d); \
+ max_d = MAX(d, max_d); \
+ }
+
+ CONE_MINMAX(1, 1);
+ CONE_MINMAX(-1, 1);
+ CONE_MINMAX(-1, -1);
+ CONE_MINMAX(1, -1);
+
+ if (orthogonal) {
+ e.touches_near = min_d < z_near;
+ } else {
+ //contains camera inside light
+ Plane base_plane(xform.origin, -xform.basis.get_axis(Vector3::AXIS_Z));
+ float dist = base_plane.distance_to(Vector3());
+ if (dist >= 0 && dist < radius) {
+ //inside, check angle
+ float angle = Math::rad2deg(Math::acos((-xform.origin.normalized()).dot(-xform.basis.get_axis(Vector3::AXIS_Z))));
+ e.touches_near = angle < p_spot_aperture * 1.05; //overfit aperture a little due to cone overfit
+ } else {
+ e.touches_near = false;
+ }
+ }
+
+ e.touches_far = max_d > z_far;
+
+ e.scale[0] = len * shared->cone_overfit;
+ e.scale[1] = len * shared->cone_overfit;
+ e.scale[2] = radius;
+
+ e.type = ELEMENT_TYPE_SPOT_LIGHT;
+ e.original_index = cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]; //use omni since they share index
+
+ RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+
+ cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]++;
+ }
+
+ render_element_count++;
+ }
+
+ _FORCE_INLINE_ void add_box(BoxType p_box_type, const Transform &p_transform, const Vector3 &p_half_extents) {
+ if (p_box_type == BOX_TYPE_DECAL && cluster_count_by_type[ELEMENT_TYPE_DECAL] == max_elements_by_type) {
+ return; //max number elements reached
+ }
+ if (p_box_type == BOX_TYPE_REFLECTION_PROBE && cluster_count_by_type[ELEMENT_TYPE_REFLECTION_PROBE] == max_elements_by_type) {
+ return; //max number elements reached
+ }
+
+ RenderElementData &e = render_elements[render_element_count];
+ Transform xform = view_xform * p_transform;
+
+ //extract scale and scale the matrix by it, makes things simpler
+ Vector3 scale = p_half_extents;
+ for (uint32_t i = 0; i < 3; i++) {
+ float s = xform.basis.elements[i].length();
+ scale[i] *= s;
+ xform.basis.elements[i] /= s;
+ };
+
+ float box_depth = Math::abs(xform.basis.xform_inv(Vector3(0, 0, -1)).dot(scale));
+ float depth = -xform.origin.z;
+
+ if (orthogonal) {
+ e.touches_near = depth - box_depth < z_near;
+ } else {
+ //contains camera inside box
+ Vector3 inside = xform.xform_inv(Vector3(0, 0, 0)).abs();
+ e.touches_near = inside.x < scale.x && inside.y < scale.y && inside.z < scale.z;
+ }
+
+ e.touches_far = depth + box_depth > z_far;
+
+ e.scale[0] = scale.x;
+ e.scale[1] = scale.y;
+ e.scale[2] = scale.z;
+
+ e.type = (p_box_type == BOX_TYPE_DECAL) ? ELEMENT_TYPE_DECAL : ELEMENT_TYPE_REFLECTION_PROBE;
+ e.original_index = cluster_count_by_type[e.type];
+
+ RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+
+ cluster_count_by_type[e.type]++;
+ render_element_count++;
+ }
+
+ void bake_cluster();
+ void debug(ElementType p_element);
+
+ RID get_cluster_buffer() const;
+ uint32_t get_cluster_size() const;
+ uint32_t get_max_cluster_elements() const;
+
+ void set_shared(ClusterBuilderSharedDataRD *p_shared);
+
+ ClusterBuilderRD();
+ ~ClusterBuilderRD();
+};
+
+#endif // CLUSTER_BUILDER_H
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index b33255b54b..bc304aedd8 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -299,15 +299,12 @@ void EffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const
copy.push_constant.target[0] = p_rect.position.x;
copy.push_constant.target[1] = p_rect.position.y;
- int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
- int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
-
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);
RD::get_singleton()->compute_list_end();
}
@@ -322,15 +319,12 @@ void EffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama,
copy.push_constant.target[1] = 0;
copy.push_constant.camera_z_far = p_lod;
- int32_t x_groups = (p_panorama_size.width - 1) / 8 + 1;
- int32_t y_groups = (p_panorama_size.height - 1) / 8 + 1;
-
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_is_array ? COPY_MODE_CUBE_ARRAY_TO_PANORAMA : COPY_MODE_CUBE_TO_PANORAMA]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cube), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_panorama), 3);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_panorama_size.width, p_panorama_size.height, 1);
RD::get_singleton()->compute_list_end();
}
@@ -349,15 +343,12 @@ void EffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_
copy.push_constant.camera_z_far = p_z_far;
copy.push_constant.camera_z_near = p_z_near;
- int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
- int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
-
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_LINEARIZE_DEPTH]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);
RD::get_singleton()->compute_list_end();
}
@@ -374,15 +365,12 @@ void EffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture,
copy.push_constant.target[0] = p_rect.position.x;
copy.push_constant.target[1] = p_rect.position.y;
- int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
- int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
-
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_SIMPLY_COPY_DEPTH]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);
RD::get_singleton()->compute_list_end();
}
@@ -400,14 +388,11 @@ void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i
copy.push_constant.set_color[2] = p_color.b;
copy.push_constant.set_color[3] = p_color.a;
- int32_t x_groups = (p_region.size.width - 1) / 8 + 1;
- int32_t y_groups = (p_region.size.height - 1) / 8 + 1;
-
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_SET_COLOR_8BIT : COPY_MODE_SET_COLOR]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);
RD::get_singleton()->compute_list_end();
}
@@ -420,8 +405,6 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back
copy.push_constant.section[2] = p_region.size.width;
copy.push_constant.section[3] = p_region.size.height;
- int32_t x_groups = (p_region.size.width - 1) / 8 + 1;
- int32_t y_groups = (p_region.size.height - 1) / 8 + 1;
//HORIZONTAL
RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]);
@@ -431,7 +414,7 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back
copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL;
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
@@ -442,7 +425,7 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back
copy.push_constant.flags = base_flags;
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);
RD::get_singleton()->compute_list_end();
}
@@ -452,9 +435,6 @@ void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const
CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;
uint32_t base_flags = 0;
- int32_t x_groups = (p_size.width + 7) / 8;
- int32_t y_groups = (p_size.height + 7) / 8;
-
copy.push_constant.section[2] = p_size.x;
copy.push_constant.section[3] = p_size.y;
@@ -479,16 +459,13 @@ void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const
copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1);
RD::get_singleton()->compute_list_end();
}
void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- int32_t x_groups = (p_screen_size.width - 1) / 8 + 1;
- int32_t y_groups = (p_screen_size.height - 1) / 8 + 1;
-
{ //scale color and depth to half
ssr_scale.push_constant.camera_z_far = p_camera.get_z_far();
ssr_scale.push_constant.camera_z_near = p_camera.get_z_near();
@@ -506,7 +483,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_scale.push_constant, sizeof(ScreenSpaceReflectionScalePushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
}
@@ -547,7 +524,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R
}
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 2);
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
}
if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) {
@@ -585,7 +562,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
@@ -600,7 +577,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
}
RD::get_singleton()->compute_list_end();
@@ -609,9 +586,6 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R
void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- int32_t x_groups = (p_screen_size.width - 1) / 8 + 1;
- int32_t y_groups = (p_screen_size.height - 1) / 8 + 1;
-
Plane p = p_camera.xform4(Plane(1, 0, -1, 1));
p.normal /= p.d;
float unit_size = p.normal.x;
@@ -635,7 +609,7 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept
RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
@@ -646,7 +620,7 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept
sss.push_constant.vertical = true;
RD::get_singleton()->compute_list_set_push_constant(compute_list, &sss.push_constant, sizeof(SubSurfaceScatteringPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
RD::get_singleton()->compute_list_end();
}
@@ -690,39 +664,33 @@ void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const S
copy.push_constant.section[2] = p_size.width;
copy.push_constant.section[3] = p_size.height;
- int32_t x_groups = (p_size.width - 1) / 8 + 1;
- int32_t y_groups = (p_size.height - 1) / 8 + 1;
-
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_MIPMAP]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1);
RD::get_singleton()->compute_list_end();
}
-void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
+void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip) {
CopyToDPPushConstant push_constant;
- push_constant.screen_size[0] = p_rect.size.x;
- push_constant.screen_size[1] = p_rect.size.y;
- push_constant.dest_offset[0] = p_rect.position.x;
- push_constant.dest_offset[1] = p_rect.position.y;
- push_constant.bias = p_bias;
+ push_constant.screen_rect[0] = p_rect.position.x;
+ push_constant.screen_rect[1] = p_rect.position.y;
+ push_constant.screen_rect[2] = p_rect.size.width;
+ push_constant.screen_rect[3] = p_rect.size.height;
push_constant.z_far = p_z_far;
push_constant.z_near = p_z_near;
push_constant.z_flip = p_dp_flip;
- int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
- int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cube_to_dp.pipeline);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(CopyToDPPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
- RD::get_singleton()->compute_list_end();
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_TRANSFER);
}
void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
@@ -807,10 +775,7 @@ void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_
RD::get_singleton()->compute_list_set_push_constant(compute_list, &luminance_reduce.push_constant, sizeof(LuminanceReducePushConstant));
- int32_t x_groups = (luminance_reduce.push_constant.source_size[0] - 1) / 8 + 1;
- int32_t y_groups = (luminance_reduce.push_constant.source_size[1] - 1) / 8 + 1;
-
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, luminance_reduce.push_constant.source_size[0], luminance_reduce.push_constant.source_size[1], 1);
luminance_reduce.push_constant.source_size[0] = MAX(luminance_reduce.push_constant.source_size[0] / 8, 1);
luminance_reduce.push_constant.source_size[1] = MAX(luminance_reduce.push_constant.source_size[1] / 8, 1);
@@ -851,14 +816,12 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_texture), 1);
- int32_t x_groups = (p_base_texture_size.x - 1) / 8 + 1;
- int32_t y_groups = (p_base_texture_size.y - 1) / 8 + 1;
bokeh.push_constant.size[0] = p_base_texture_size.x;
bokeh.push_constant.size[1] = p_base_texture_size.y;
RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) {
@@ -875,8 +838,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture1), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1);
- x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1;
- y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1;
bokeh.push_constant.size[0] = p_base_texture_size.x >> 1;
bokeh.push_constant.size[1] = p_base_texture_size.y >> 1;
bokeh.push_constant.half_size = true;
@@ -890,7 +851,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
//third pass
@@ -906,7 +867,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) {
@@ -917,8 +878,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture2), 1);
- x_groups = (p_base_texture_size.x - 1) / 8 + 1;
- y_groups = (p_base_texture_size.y - 1) / 8 + 1;
bokeh.push_constant.size[0] = p_base_texture_size.x;
bokeh.push_constant.size[1] = p_base_texture_size.y;
bokeh.push_constant.half_size = false;
@@ -926,7 +885,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1);
}
} else {
//circle
@@ -944,15 +903,13 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture1), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_base_texture), 1);
- x_groups = ((p_base_texture_size.x >> 1) - 1) / 8 + 1;
- y_groups = ((p_base_texture_size.y >> 1) - 1) / 8 + 1;
bokeh.push_constant.size[0] = p_base_texture_size.x >> 1;
bokeh.push_constant.size[1] = p_base_texture_size.y >> 1;
bokeh.push_constant.half_size = true;
RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
//circle is just one pass, then upscale
@@ -964,8 +921,6 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_base_texture), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture1), 1);
- x_groups = (p_base_texture_size.x - 1) / 8 + 1;
- y_groups = (p_base_texture_size.y - 1) / 8 + 1;
bokeh.push_constant.size[0] = p_base_texture_size.x;
bokeh.push_constant.size[1] = p_base_texture_size.y;
bokeh.push_constant.half_size = false;
@@ -973,7 +928,7 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_base_texture_size.x, p_base_texture_size.y, 1);
}
RD::get_singleton()->compute_list_end();
@@ -992,47 +947,47 @@ void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID>
ssao.gather_push_constant.pass_coord_offset[0] = i % 2;
ssao.gather_push_constant.pass_coord_offset[1] = i / 2;
- ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.screen_size.x;
- ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.screen_size.y;
+ ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x;
+ ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y;
ssao.gather_push_constant.pass = i;
RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 2);
RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssao.gather_push_constant, sizeof(SSAOGatherPushConstant));
- int x_groups = ((p_settings.screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
- int y_groups = ((p_settings.screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
+ Size2i size = Size2i(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
- RD::get_singleton()->compute_list_dispatch(p_compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(p_compute_list, size.x, size.y, 1);
}
RD::get_singleton()->compute_list_add_barrier(p_compute_list);
}
-void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets) {
+void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &p_depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
+ RD::get_singleton()->draw_command_begin_label("SSAO");
/* FIRST PASS */
// Downsample and deinterleave the depth buffer.
{
+ RD::get_singleton()->draw_command_begin_label("Downsample Depth");
if (p_invalidate_uniform_sets) {
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 0;
- u.ids.push_back(depth_mipmaps[1]);
+ u.ids.push_back(p_depth_mipmaps[1]);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 1;
- u.ids.push_back(depth_mipmaps[2]);
+ u.ids.push_back(p_depth_mipmaps[2]);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 2;
- u.ids.push_back(depth_mipmaps[3]);
+ u.ids.push_back(p_depth_mipmaps[3]);
uniforms.push_back(u);
}
ssao.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.downsample_shader.version_get_shader(ssao.downsample_shader_version, 2), 2);
@@ -1051,8 +1006,8 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
ssao.downsample_push_constant.z_near = p_projection.get_z_near();
ssao.downsample_push_constant.z_far = p_projection.get_z_far();
}
- ssao.downsample_push_constant.pixel_size[0] = 1.0 / p_settings.screen_size.x;
- ssao.downsample_push_constant.pixel_size[1] = 1.0 / p_settings.screen_size.y;
+ ssao.downsample_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
+ ssao.downsample_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
ssao.downsample_push_constant.radius_sq = p_settings.radius * p_settings.radius;
int downsample_pipeline = SSAO_DOWNSAMPLE;
@@ -1068,24 +1023,25 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[downsample_pipeline]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(depth_mipmaps[0]), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_depth_mipmaps[0]), 1);
if (p_settings.quality > RS::ENV_SSAO_QUALITY_MEDIUM) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.downsample_uniform_set, 2);
}
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.downsample_push_constant, sizeof(SSAODownsamplePushConstant));
- int x_groups = (MAX(1, p_settings.screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
- int y_groups = (MAX(1, p_settings.screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
+ Size2i size(MAX(1, p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)), MAX(1, p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->draw_command_end_label(); // Downsample SSAO
}
/* SECOND PASS */
// Sample SSAO
{
- ssao.gather_push_constant.screen_size[0] = p_settings.screen_size.x;
- ssao.gather_push_constant.screen_size[1] = p_settings.screen_size.y;
+ RD::get_singleton()->draw_command_begin_label("Gather Samples");
+ ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
+ ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
@@ -1122,7 +1078,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
ssao.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit;
ssao.gather_push_constant.neg_inv_radius = -1.0 / ssao.gather_push_constant.radius;
- ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_size.x) * (p_settings.quarter_size.y) * 255);
+ ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_screen_size.x) * (p_settings.quarter_screen_size.y) * 255);
ssao.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target;
ssao.gather_push_constant.detail_intensity = p_settings.detail;
@@ -1184,6 +1140,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
}
if (p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) {
+ RD::get_singleton()->draw_command_begin_label("Generate Importance Map");
ssao.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
ssao.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
ssao.importance_map_push_constant.intensity = p_settings.intensity;
@@ -1192,21 +1149,19 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]);
gather_ssao(compute_list, p_ao_pong_slices, p_settings, true);
//generate importance map
- int x_groups = (p_settings.quarter_size.x - 1) / 8 + 1;
- int y_groups = (p_settings.quarter_size.y - 1) / 8 + 1;
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
//process importance map A
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPA]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map_pong), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
//process Importance Map B
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_PROCESS_IMPORTANCE_MAPB]);
@@ -1214,21 +1169,24 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_importance_map), 1);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.counter_uniform_set, 2);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.importance_map_push_constant, sizeof(SSAOImportanceMapPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_ADAPTIVE]);
+ RD::get_singleton()->draw_command_end_label(); // Importance Map
} else {
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]);
}
gather_ssao(compute_list, p_ao_slices, p_settings, false);
+ RD::get_singleton()->draw_command_end_label(); // Gather SSAO
}
// /* THIRD PASS */
// // Blur
//
{
+ RD::get_singleton()->draw_command_begin_label("Edge Aware Blur");
ssao.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness;
ssao.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
ssao.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
@@ -1268,25 +1226,25 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
}
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant));
- int x_groups = ((p_settings.screen_size.x >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
- int y_groups = ((p_settings.screen_size.y >> (p_settings.half_size ? 2 : 1)) - 1) / 8 + 1;
-
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ Size2i size(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
}
if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
RD::get_singleton()->compute_list_add_barrier(compute_list);
}
}
+ RD::get_singleton()->draw_command_end_label(); // Blur
}
/* FOURTH PASS */
// Interleave buffers
// back to full size
{
+ RD::get_singleton()->draw_command_begin_label("Interleave Buffers");
ssao.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness;
- ssao.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.screen_size.x;
- ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.screen_size.y;
+ ssao.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
+ ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
ssao.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2);
int interleave_pipeline = SSAO_INTERLEAVE_HALF;
@@ -1307,17 +1265,15 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant));
- int x_groups = (p_settings.screen_size.x - 1) / 8 + 1;
- int y_groups = (p_settings.screen_size.y - 1) / 8 + 1;
-
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.full_screen_size.x, p_settings.full_screen_size.y, 1);
RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->draw_command_end_label(); // Interleave
}
-
- RD::get_singleton()->compute_list_end();
+ RD::get_singleton()->draw_command_end_label(); //SSAO
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_TRANSFER); //wait for upcoming transfer
int zero[1] = { 0 };
- RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, false);
+ RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
}
void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) {
@@ -1330,12 +1286,9 @@ void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_normal), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_roughness), 1);
- int x_groups = (p_size.x - 1) / 8 + 1;
- int y_groups = (p_size.y - 1) / 8 + 1;
-
RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness_limiter.push_constant, sizeof(RoughnessLimiterPushConstant)); //not used but set anyway
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.x, p_size.y, 1);
RD::get_singleton()->compute_list_end();
}
@@ -1448,7 +1401,7 @@ void EffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_
RD::get_singleton()->draw_list_draw(draw_list, true);
}
-void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples) {
+void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
ResolvePushConstant push_constant;
push_constant.screen_size[0] = p_screen_size.x;
push_constant.screen_size[1] = p_screen_size.y;
@@ -1465,54 +1418,9 @@ void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RI
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1, 8, 8, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
- RD::get_singleton()->compute_list_end();
-}
-
-void EffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) {
- uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, (uint32_t)p_shrink_limit, 0, 0, 0 };
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_REDUCE]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_source_shadow, p_dest_shadow), 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8);
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1);
-}
-void EffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) {
- uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, 0, 0, 0, 0 };
-
- switch (p_filter) {
- case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED:
- case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW: {
- push_constant[5] = 0;
- } break;
- case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM: {
- push_constant[5] = 9;
- } break;
- case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH: {
- push_constant[5] = 18;
- } break;
- }
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_FILTER]);
- if (p_vertical) {
- push_constant[6] = 1;
- push_constant[7] = 0;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_shadow, p_backing_shadow), 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8);
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1);
- }
- if (p_vertical && p_horizontal) {
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- }
- if (p_horizontal) {
- push_constant[6] = 0;
- push_constant[7] = 1;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_backing_shadow, p_shadow), 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8);
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1, 8, 8, 1);
- }
+ RD::get_singleton()->compute_list_end(p_barrier);
}
void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
@@ -1678,8 +1586,12 @@ EffectsRD::EffectsRD() {
cube_to_dp.shader.initialize(copy_modes);
cube_to_dp.shader_version = cube_to_dp.shader.version_create();
-
- cube_to_dp.pipeline = RD::get_singleton()->compute_pipeline_create(cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0));
+ RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
+ RD::PipelineDepthStencilState dss;
+ dss.enable_depth_test = true;
+ dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS;
+ dss.enable_depth_write = true;
+ cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0);
}
{
@@ -1776,7 +1688,7 @@ EffectsRD::EffectsRD() {
}
}
- RD::get_singleton()->buffer_update(ssao.gather_constants_buffer, 0, sizeof(SSAOGatherConstants), &gather_constants, false);
+ RD::get_singleton()->buffer_update(ssao.gather_constants_buffer, 0, sizeof(SSAOGatherConstants), &gather_constants);
}
{
Vector<String> ssao_modes;
@@ -1795,7 +1707,8 @@ EffectsRD::EffectsRD() {
}
ssao.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t));
int zero[1] = { 0 };
- RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, false);
+ RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero);
+ RD::get_singleton()->set_resource_name(ssao.importance_map_load_counter, "Importance Map Load Counter");
Vector<RD::Uniform> uniforms;
{
@@ -1806,6 +1719,7 @@ EffectsRD::EffectsRD() {
uniforms.push_back(u);
}
ssao.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2), 2);
+ RD::get_singleton()->set_resource_name(ssao.counter_uniform_set, "Load Counter Uniform Set");
}
{
Vector<String> ssao_modes;
@@ -1834,7 +1748,7 @@ EffectsRD::EffectsRD() {
ssao.interleave_shader_version = ssao.interleave_shader.version_create();
for (int i = SSAO_INTERLEAVE; i <= SSAO_INTERLEAVE_HALF; i++) {
ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, i - SSAO_INTERLEAVE));
-
+ RD::get_singleton()->set_resource_name(ssao.pipelines[pipeline], "Interleave Pipeline " + itos(i));
pipeline++;
}
}
@@ -1867,7 +1781,7 @@ EffectsRD::EffectsRD() {
{
// Initialize cubemap filter
- filter.use_high_quality = GLOBAL_GET("rendering/quality/reflections/fast_filter_high_quality");
+ filter.use_high_quality = GLOBAL_GET("rendering/reflections/sky_reflections/fast_filter_high_quality");
Vector<String> cubemap_filter_modes;
cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n");
@@ -1883,10 +1797,10 @@ EffectsRD::EffectsRD() {
if (filter.use_high_quality) {
filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs));
- RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0], false);
+ RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0]);
} else {
filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs));
- RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0], false);
+ RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0]);
}
Vector<RD::Uniform> uniforms;
@@ -2005,20 +1919,6 @@ EffectsRD::EffectsRD() {
}
{
- Vector<String> shadow_reduce_modes;
- shadow_reduce_modes.push_back("\n#define MODE_REDUCE\n");
- shadow_reduce_modes.push_back("\n#define MODE_FILTER\n");
-
- shadow_reduce.shader.initialize(shadow_reduce_modes);
-
- shadow_reduce.shader_version = shadow_reduce.shader.version_create();
-
- for (int i = 0; i < SHADOW_REDUCE_MAX; i++) {
- shadow_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(shadow_reduce.shader.version_get_shader(shadow_reduce.shader_version, i));
- }
- }
-
- {
Vector<String> sort_modes;
sort_modes.push_back("\n#define MODE_SORT_BLOCK\n");
sort_modes.push_back("\n#define MODE_SORT_STEP\n");
@@ -2039,12 +1939,14 @@ EffectsRD::EffectsRD() {
sampler.max_lod = 0;
default_sampler = RD::get_singleton()->sampler_create(sampler);
+ RD::get_singleton()->set_resource_name(default_sampler, "Default Linear Sampler");
sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
sampler.mip_filter = RD::SAMPLER_FILTER_LINEAR;
sampler.max_lod = 1e20;
default_mipmap_sampler = RD::get_singleton()->sampler_create(sampler);
+ RD::get_singleton()->set_resource_name(default_mipmap_sampler, "Default MipMap Sampler");
{ //create index array for copy shaders
Vector<uint8_t> pv;
@@ -2104,5 +2006,4 @@ EffectsRD::~EffectsRD() {
ssr_scale.shader.version_free(ssr_scale.shader_version);
sss.shader.version_free(sss.shader_version);
tonemap.shader.version_free(tonemap.shader_version);
- shadow_reduce.shader.version_free(shadow_reduce.shader_version);
}
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index 8731466dea..1ba25e301b 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,6 @@
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/shadow_reduce.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h"
@@ -234,18 +233,17 @@ class EffectsRD {
} luminance_reduce;
struct CopyToDPPushConstant {
- int32_t screen_size[2];
- int32_t dest_offset[2];
- float bias;
float z_far;
float z_near;
uint32_t z_flip;
+ uint32_t pad;
+ float screen_rect[4];
};
struct CoptToDP {
CubeToDpShaderRD shader;
RID shader_version;
- RID pipeline;
+ PipelineCacheRD pipeline;
} cube_to_dp;
struct BokehPushConstant {
@@ -598,18 +596,6 @@ class EffectsRD {
RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels
} resolve;
- enum ShadowReduceMode {
- SHADOW_REDUCE_REDUCE,
- SHADOW_REDUCE_FILTER,
- SHADOW_REDUCE_MAX
- };
-
- struct ShadowReduce {
- ShadowReduceShaderRD shader;
- RID shader_version;
- RID pipelines[SHADOW_REDUCE_MAX];
- } shadow_reduce;
-
enum SortMode {
SORT_MODE_BLOCK,
SORT_MODE_STEP,
@@ -687,7 +673,7 @@ public:
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
- void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
+ void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip);
void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal);
@@ -745,9 +731,9 @@ public:
float fadeout_from = 50.0;
float fadeout_to = 300.0;
- Size2i screen_size = Size2i();
+ Size2i full_screen_size = Size2i();
Size2i half_screen_size = Size2i();
- Size2i quarter_size = Size2i();
+ Size2i quarter_screen_size = Size2i();
};
void tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings);
@@ -764,10 +750,7 @@ public:
void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection);
void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality);
- void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples);
-
- void reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RenderingDevice::ComputeListID compute_list);
- void filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RS::EnvVolumetricFogShadowFilter p_filter, RenderingDevice::ComputeListID compute_list, bool p_vertical = true, bool p_horizontal = true);
+ void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
void sort_buffer(RID p_uniform_set, int p_size);
diff --git a/servers/rendering/renderer_rd/light_cluster_builder.cpp b/servers/rendering/renderer_rd/light_cluster_builder.cpp
deleted file mode 100644
index b76b41ba26..0000000000
--- a/servers/rendering/renderer_rd/light_cluster_builder.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*************************************************************************/
-/* light_cluster_builder.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "light_cluster_builder.h"
-
-void LightClusterBuilder::begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection) {
- view_xform = p_view_transform;
- projection = p_cam_projection;
- z_near = -projection.get_z_near();
- z_far = -projection.get_z_far();
-
- //reset counts
- light_count = 0;
- refprobe_count = 0;
- decal_count = 0;
- item_count = 0;
- sort_id_count = 0;
-}
-
-void LightClusterBuilder::bake_cluster() {
- float slice_depth = (z_near - z_far) / depth;
-
- uint8_t *cluster_dataw = cluster_data.ptrw();
- Cell *cluster_data_ptr = (Cell *)cluster_dataw;
- //clear the cluster
- zeromem(cluster_data_ptr, (width * height * depth * sizeof(Cell)));
-
- /* Step 1, create cell positions and count them */
-
- for (uint32_t i = 0; i < item_count; i++) {
- const Item &item = items[i];
-
- int from_slice = Math::floor((z_near - (item.aabb.position.z + item.aabb.size.z)) / slice_depth);
- int to_slice = Math::floor((z_near - item.aabb.position.z) / slice_depth);
-
- if (from_slice >= (int)depth || to_slice < 0) {
- continue; //sorry no go
- }
-
- from_slice = MAX(0, from_slice);
- to_slice = MIN((int)depth - 1, to_slice);
-
- for (int j = from_slice; j <= to_slice; j++) {
- Vector3 min = item.aabb.position;
- Vector3 max = item.aabb.position + item.aabb.size;
-
- float limit_near = MIN((z_near - slice_depth * j), max.z);
- float limit_far = MAX((z_near - slice_depth * (j + 1)), min.z);
-
- max.z = limit_near;
- min.z = limit_near;
-
- Vector3 proj_min = projection.xform(min);
- Vector3 proj_max = projection.xform(max);
-
- int near_from_x = int(Math::floor((proj_min.x * 0.5 + 0.5) * width));
- int near_from_y = int(Math::floor((-proj_max.y * 0.5 + 0.5) * height));
- int near_to_x = int(Math::floor((proj_max.x * 0.5 + 0.5) * width));
- int near_to_y = int(Math::floor((-proj_min.y * 0.5 + 0.5) * height));
-
- max.z = limit_far;
- min.z = limit_far;
-
- proj_min = projection.xform(min);
- proj_max = projection.xform(max);
-
- int far_from_x = int(Math::floor((proj_min.x * 0.5 + 0.5) * width));
- int far_from_y = int(Math::floor((-proj_max.y * 0.5 + 0.5) * height));
- int far_to_x = int(Math::floor((proj_max.x * 0.5 + 0.5) * width));
- int far_to_y = int(Math::floor((-proj_min.y * 0.5 + 0.5) * height));
-
- //print_line(itos(j) + " near - " + Vector2i(near_from_x, near_from_y) + " -> " + Vector2i(near_to_x, near_to_y));
- //print_line(itos(j) + " far - " + Vector2i(far_from_x, far_from_y) + " -> " + Vector2i(far_to_x, far_to_y));
-
- int from_x = MIN(near_from_x, far_from_x);
- int from_y = MIN(near_from_y, far_from_y);
- int to_x = MAX(near_to_x, far_to_x);
- int to_y = MAX(near_to_y, far_to_y);
-
- if (from_x >= (int)width || to_x < 0 || from_y >= (int)height || to_y < 0) {
- continue;
- }
-
- int sx = MAX(0, from_x);
- int sy = MAX(0, from_y);
- int dx = MIN((int)width - 1, to_x);
- int dy = MIN((int)height - 1, to_y);
-
- //print_line(itos(j) + " - " + Vector2i(sx, sy) + " -> " + Vector2i(dx, dy));
-
- for (int x = sx; x <= dx; x++) {
- for (int y = sy; y <= dy; y++) {
- uint32_t offset = j * (width * height) + y * width + x;
-
- if (unlikely(sort_id_count == sort_id_max)) {
- sort_id_max = nearest_power_of_2_templated(sort_id_max + 1);
- sort_ids = (SortID *)memrealloc(sort_ids, sizeof(SortID) * sort_id_max);
- if (ids.size()) {
- ids.resize(sort_id_max);
- RD::get_singleton()->free(items_buffer);
- items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * sort_id_max);
- }
- }
-
- sort_ids[sort_id_count].cell_index = offset;
- sort_ids[sort_id_count].item_index = item.index;
- sort_ids[sort_id_count].item_type = item.type;
-
- sort_id_count++;
-
- //for now, only count
- cluster_data_ptr[offset].item_pointers[item.type]++;
- //print_line("at offset " + itos(offset) + " value: " + itos(cluster_data_ptr[offset].item_pointers[item.type]));
- }
- }
- }
- }
-
- /* Step 2, Assign pointers (and reset counters) */
-
- uint32_t offset = 0;
- for (uint32_t i = 0; i < (width * height * depth); i++) {
- for (int j = 0; j < ITEM_TYPE_MAX; j++) {
- uint32_t count = cluster_data_ptr[i].item_pointers[j]; //save count
- cluster_data_ptr[i].item_pointers[j] = offset; //replace count by pointer
- offset += count; //increase offset by count;
- }
- }
-
- //print_line("offset: " + itos(offset));
- /* Step 3, Place item lists */
-
- uint32_t *ids_ptr = ids.ptrw();
-
- for (uint32_t i = 0; i < sort_id_count; i++) {
- const SortID &id = sort_ids[i];
- Cell &cell = cluster_data_ptr[id.cell_index];
- uint32_t pointer = cell.item_pointers[id.item_type] & POINTER_MASK;
- uint32_t counter = cell.item_pointers[id.item_type] >> COUNTER_SHIFT;
- ids_ptr[pointer + counter] = id.item_index;
-
- cell.item_pointers[id.item_type] = pointer | ((counter + 1) << COUNTER_SHIFT);
- }
-
- RD::get_singleton()->texture_update(cluster_texture, 0, cluster_data, true);
- RD::get_singleton()->buffer_update(items_buffer, 0, offset * sizeof(uint32_t), ids_ptr, true);
-}
-
-void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth) {
- if (width == p_width && height == p_height && depth == p_depth) {
- return;
- }
- if (cluster_texture.is_valid()) {
- RD::get_singleton()->free(cluster_texture);
- }
-
- width = p_width;
- height = p_height;
- depth = p_depth;
-
- cluster_data.resize(width * height * depth * sizeof(Cell));
-
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
- tf.texture_type = RD::TEXTURE_TYPE_3D;
- tf.width = width;
- tf.height = height;
- tf.depth = depth;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
-
- cluster_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
- }
-}
-
-RID LightClusterBuilder::get_cluster_texture() const {
- return cluster_texture;
-}
-
-RID LightClusterBuilder::get_cluster_indices_buffer() const {
- return items_buffer;
-}
-
-LightClusterBuilder::LightClusterBuilder() {
- //initialize accumulators to something
- lights = (LightData *)memalloc(sizeof(LightData) * 1024);
- light_max = 1024;
-
- refprobes = (OrientedBoxData *)memalloc(sizeof(OrientedBoxData) * 1024);
- refprobe_max = 1024;
-
- decals = (OrientedBoxData *)memalloc(sizeof(OrientedBoxData) * 1024);
- decal_max = 1024;
-
- items = (Item *)memalloc(sizeof(Item) * 1024);
- item_max = 1024;
-
- sort_ids = (SortID *)memalloc(sizeof(SortID) * 1024);
- ids.resize(2014);
- items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 1024);
- item_max = 1024;
-}
-
-LightClusterBuilder::~LightClusterBuilder() {
- if (cluster_data.size()) {
- RD::get_singleton()->free(cluster_texture);
- }
-
- if (lights) {
- memfree(lights);
- }
- if (refprobes) {
- memfree(refprobes);
- }
- if (decals) {
- memfree(decals);
- }
- if (items) {
- memfree(items);
- }
- if (sort_ids) {
- memfree(sort_ids);
- RD::get_singleton()->free(items_buffer);
- }
-}
diff --git a/servers/rendering/renderer_rd/light_cluster_builder.h b/servers/rendering/renderer_rd/light_cluster_builder.h
deleted file mode 100644
index 0767a96817..0000000000
--- a/servers/rendering/renderer_rd/light_cluster_builder.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*************************************************************************/
-/* light_cluster_builder.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef LIGHT_CLUSTER_BUILDER_H
-#define LIGHT_CLUSTER_BUILDER_H
-
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
-
-class LightClusterBuilder {
-public:
- enum LightType {
- LIGHT_TYPE_OMNI,
- LIGHT_TYPE_SPOT
- };
-
- enum ItemType {
- ITEM_TYPE_OMNI_LIGHT,
- ITEM_TYPE_SPOT_LIGHT,
- ITEM_TYPE_REFLECTION_PROBE,
- ITEM_TYPE_DECAL,
- ITEM_TYPE_MAX //should always be 4
- };
-
- enum {
- COUNTER_SHIFT = 20, //one million total ids
- POINTER_MASK = (1 << COUNTER_SHIFT) - 1,
- COUNTER_MASK = 0xfff // 4096 items per cell
- };
-
-private:
- struct LightData {
- float position[3];
- uint32_t type;
- float radius;
- float spot_aperture;
- uint32_t pad[2];
- };
-
- uint32_t light_count = 0;
- uint32_t light_max = 0;
- LightData *lights = nullptr;
-
- struct OrientedBoxData {
- float position[3];
- uint32_t pad;
- float x_axis[3];
- uint32_t pad2;
- float y_axis[3];
- uint32_t pad3;
- float z_axis[3];
- uint32_t pad4;
- };
-
- uint32_t refprobe_count = 0;
- uint32_t refprobe_max = 0;
- OrientedBoxData *refprobes = nullptr;
-
- uint32_t decal_count = 0;
- uint32_t decal_max = 0;
- OrientedBoxData *decals = nullptr;
-
- struct Item {
- AABB aabb;
- ItemType type;
- uint32_t index;
- };
-
- Item *items = nullptr;
- uint32_t item_count = 0;
- uint32_t item_max = 0;
-
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t depth = 0;
-
- struct Cell {
- uint32_t item_pointers[ITEM_TYPE_MAX];
- };
-
- Vector<uint8_t> cluster_data;
- RID cluster_texture;
-
- struct SortID {
- uint32_t cell_index;
- uint32_t item_index;
- ItemType item_type;
- };
-
- SortID *sort_ids = nullptr;
- Vector<uint32_t> ids;
- uint32_t sort_id_count = 0;
- uint32_t sort_id_max = 0;
- RID items_buffer;
-
- Transform view_xform;
- CameraMatrix projection;
- float z_far = 0;
- float z_near = 0;
-
- _FORCE_INLINE_ void _add_item(const AABB &p_aabb, ItemType p_type, uint32_t p_index) {
- if (unlikely(item_count == item_max)) {
- item_max = nearest_power_of_2_templated(item_max + 1);
- items = (Item *)memrealloc(items, sizeof(Item) * item_max);
- }
-
- Item &item = items[item_count];
- item.aabb = p_aabb;
- item.index = p_index;
- item.type = p_type;
- item_count++;
- }
-
-public:
- void begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection);
-
- _FORCE_INLINE_ void add_light(LightType p_type, const Transform &p_transform, float p_radius, float p_spot_aperture) {
- if (unlikely(light_count == light_max)) {
- light_max = nearest_power_of_2_templated(light_max + 1);
- lights = (LightData *)memrealloc(lights, sizeof(LightData) * light_max);
- }
-
- LightData &ld = lights[light_count];
- ld.type = p_type;
- ld.position[0] = p_transform.origin.x;
- ld.position[1] = p_transform.origin.y;
- ld.position[2] = p_transform.origin.z;
- ld.radius = p_radius;
- ld.spot_aperture = p_spot_aperture;
-
- Transform xform = view_xform * p_transform;
-
- ld.radius *= xform.basis.get_uniform_scale();
-
- AABB aabb;
-
- switch (p_type) {
- case LIGHT_TYPE_OMNI: {
- aabb.position = xform.origin;
- aabb.size = Vector3(ld.radius, ld.radius, ld.radius);
- aabb.position -= aabb.size;
- aabb.size *= 2.0;
-
- _add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count);
- } break;
- case LIGHT_TYPE_SPOT: {
- float r = ld.radius;
- real_t len = Math::tan(Math::deg2rad(ld.spot_aperture)) * r;
-
- aabb.position = xform.origin;
- aabb.expand_to(xform.xform(Vector3(len, len, -r)));
- aabb.expand_to(xform.xform(Vector3(-len, len, -r)));
- aabb.expand_to(xform.xform(Vector3(-len, -len, -r)));
- aabb.expand_to(xform.xform(Vector3(len, -len, -r)));
- _add_item(aabb, ITEM_TYPE_SPOT_LIGHT, light_count);
- } break;
- }
-
- light_count++;
- }
-
- _FORCE_INLINE_ void add_reflection_probe(const Transform &p_transform, const Vector3 &p_half_extents) {
- if (unlikely(refprobe_count == refprobe_max)) {
- refprobe_max = nearest_power_of_2_templated(refprobe_max + 1);
- refprobes = (OrientedBoxData *)memrealloc(refprobes, sizeof(OrientedBoxData) * refprobe_max);
- }
-
- Transform xform = view_xform * p_transform;
-
- OrientedBoxData &rp = refprobes[refprobe_count];
- Vector3 origin = xform.origin;
- rp.position[0] = origin.x;
- rp.position[1] = origin.y;
- rp.position[2] = origin.z;
-
- Vector3 x_axis = xform.basis.get_axis(0) * p_half_extents.x;
- rp.x_axis[0] = x_axis.x;
- rp.x_axis[1] = x_axis.y;
- rp.x_axis[2] = x_axis.z;
-
- Vector3 y_axis = xform.basis.get_axis(1) * p_half_extents.y;
- rp.y_axis[0] = y_axis.x;
- rp.y_axis[1] = y_axis.y;
- rp.y_axis[2] = y_axis.z;
-
- Vector3 z_axis = xform.basis.get_axis(2) * p_half_extents.z;
- rp.z_axis[0] = z_axis.x;
- rp.z_axis[1] = z_axis.y;
- rp.z_axis[2] = z_axis.z;
-
- AABB aabb;
-
- aabb.position = origin + x_axis + y_axis + z_axis;
- aabb.expand_to(origin + x_axis + y_axis - z_axis);
- aabb.expand_to(origin + x_axis - y_axis + z_axis);
- aabb.expand_to(origin + x_axis - y_axis - z_axis);
- aabb.expand_to(origin - x_axis + y_axis + z_axis);
- aabb.expand_to(origin - x_axis + y_axis - z_axis);
- aabb.expand_to(origin - x_axis - y_axis + z_axis);
- aabb.expand_to(origin - x_axis - y_axis - z_axis);
-
- _add_item(aabb, ITEM_TYPE_REFLECTION_PROBE, refprobe_count);
-
- refprobe_count++;
- }
-
- _FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector3 &p_half_extents) {
- if (unlikely(decal_count == decal_max)) {
- decal_max = nearest_power_of_2_templated(decal_max + 1);
- decals = (OrientedBoxData *)memrealloc(decals, sizeof(OrientedBoxData) * decal_max);
- }
-
- Transform xform = view_xform * p_transform;
-
- OrientedBoxData &dc = decals[decal_count];
-
- Vector3 origin = xform.origin;
- dc.position[0] = origin.x;
- dc.position[1] = origin.y;
- dc.position[2] = origin.z;
-
- Vector3 x_axis = xform.basis.get_axis(0) * p_half_extents.x;
- dc.x_axis[0] = x_axis.x;
- dc.x_axis[1] = x_axis.y;
- dc.x_axis[2] = x_axis.z;
-
- Vector3 y_axis = xform.basis.get_axis(1) * p_half_extents.y;
- dc.y_axis[0] = y_axis.x;
- dc.y_axis[1] = y_axis.y;
- dc.y_axis[2] = y_axis.z;
-
- Vector3 z_axis = xform.basis.get_axis(2) * p_half_extents.z;
- dc.z_axis[0] = z_axis.x;
- dc.z_axis[1] = z_axis.y;
- dc.z_axis[2] = z_axis.z;
-
- AABB aabb;
-
- aabb.position = origin + x_axis + y_axis + z_axis;
- aabb.expand_to(origin + x_axis + y_axis - z_axis);
- aabb.expand_to(origin + x_axis - y_axis + z_axis);
- aabb.expand_to(origin + x_axis - y_axis - z_axis);
- aabb.expand_to(origin - x_axis + y_axis + z_axis);
- aabb.expand_to(origin - x_axis + y_axis - z_axis);
- aabb.expand_to(origin - x_axis - y_axis + z_axis);
- aabb.expand_to(origin - x_axis - y_axis - z_axis);
-
- _add_item(aabb, ITEM_TYPE_DECAL, decal_count);
-
- decal_count++;
- }
-
- void bake_cluster();
-
- void setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth);
-
- RID get_cluster_texture() const;
- RID get_cluster_indices_buffer() const;
-
- LightClusterBuilder();
- ~LightClusterBuilder();
-};
-
-#endif // LIGHT_CLUSTER_BUILDER_H
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
index 8319e3eed1..b2b919c40e 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h
index 2f91c3c3b5..b1c8f21ecc 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.h
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 591018346a..7d6e2fa8e4 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1367,7 +1367,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
}
if (light_count > 0) {
- RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * light_count, &state.light_uniforms[0], true);
+ RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * light_count, &state.light_uniforms[0]);
}
{
@@ -1421,7 +1421,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
//print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale));
state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5);
- RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer, true);
+ RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer);
}
{ //default filter/repeat
@@ -1622,7 +1622,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index,
projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp);
}
- Vector3 cam_target = Basis(Vector3(0, 0, Math_PI * 2 * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0));
+ Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0));
projection = projection * CameraMatrix(Transform().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
ShadowRenderPushConstant push_constant;
@@ -1689,7 +1689,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
to_light_xform[2] = from_pos;
to_light_xform[1] = light_dir;
- to_light_xform[0] = -light_dir.tangent();
+ to_light_xform[0] = -light_dir.orthogonal();
to_light_xform.invert();
@@ -2239,6 +2239,11 @@ Variant RendererCanvasRenderRD::ShaderData::get_default_parameter(const StringNa
return Variant();
}
+RS::ShaderNativeSourceCode RendererCanvasRenderRD::ShaderData::get_native_source_code() const {
+ RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
+ return canvas_singleton->shader.canvas_shader.version_get_native_source_code(version);
+}
+
RendererCanvasRenderRD::ShaderData::ShaderData() {
valid = false;
uses_screen_texture = false;
@@ -2488,8 +2493,8 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
actions.renames["COLOR"] = "color";
actions.renames["NORMAL"] = "normal";
- actions.renames["NORMALMAP"] = "normal_map";
- actions.renames["NORMALMAP_DEPTH"] = "normal_depth";
+ actions.renames["NORMAL_MAP"] = "normal_map";
+ actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
actions.renames["TEXTURE"] = "color_texture";
actions.renames["TEXTURE_PIXEL_SIZE"] = "draw_data.color_texture_pixel_size";
actions.renames["NORMAL_TEXTURE"] = "normal_texture";
@@ -2501,7 +2506,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
actions.renames["FRAGCOORD"] = "gl_FragCoord";
actions.renames["POINT_COORD"] = "gl_PointCoord";
- actions.renames["LIGHT_POSITION"] = "light_pos";
+ actions.renames["LIGHT_POSITION"] = "light_position";
actions.renames["LIGHT_COLOR"] = "light_color";
actions.renames["LIGHT_ENERGY"] = "light_energy";
actions.renames["LIGHT"] = "light";
@@ -2517,7 +2522,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
actions.usage_defines["SCREEN_PIXEL_SIZE"] = "@SCREEN_UV";
actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
- actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
+ actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
actions.usage_defines["LIGHT"] = "#define LIGHT_SHADER_CODE_USED\n";
actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
@@ -2690,9 +2695,10 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
state.default_transforms_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET);
}
- default_canvas_texture = storage->canvas_texture_create();
+ default_canvas_texture = storage->canvas_texture_allocate();
+ storage->canvas_texture_initialize(default_canvas_texture);
- state.shadow_texture_size = GLOBAL_GET("rendering/quality/2d_shadow_atlas/size");
+ state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size");
//create functions for shader and material
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_2D, _create_shader_funcs);
@@ -2701,9 +2707,14 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
state.time = 0;
{
- default_canvas_group_shader = storage->shader_create();
+ default_canvas_group_shader = storage->shader_allocate();
+ storage->shader_initialize(default_canvas_group_shader);
+
storage->shader_set_code(default_canvas_group_shader, "shader_type canvas_item; \nvoid fragment() {\n\tvec4 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0); if (c.a > 0.0001) c.rgb/=c.a; COLOR *= c; \n}\n");
- default_canvas_group_material = storage->material_create();
+
+ 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);
}
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 203d7a4890..cb947d7180 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -188,6 +188,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
virtual bool is_animated() const;
virtual bool casts_shadows() const;
virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ virtual RS::ShaderNativeSourceCode get_native_source_code() const;
+
ShaderData();
virtual ~ShaderData();
};
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 4ae7e68219..d5ac05d1d1 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -154,12 +154,9 @@ void RendererCompositorRD::initialize() {
}
}
-ThreadWorkPool RendererCompositorRD::thread_work_pool;
uint64_t RendererCompositorRD::frame = 1;
void RendererCompositorRD::finalize() {
- thread_work_pool.finish();
-
memdelete(scene);
memdelete(canvas);
memdelete(storage);
@@ -174,10 +171,9 @@ RendererCompositorRD *RendererCompositorRD::singleton = nullptr;
RendererCompositorRD::RendererCompositorRD() {
singleton = this;
- thread_work_pool.init();
time = 0;
storage = memnew(RendererStorageRD);
canvas = memnew(RendererCanvasRenderRD(storage));
- scene = memnew(RendererSceneRenderForward(storage));
+ scene = memnew(RendererSceneRenderForwardClustered(storage));
}
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index 877f47d702..67a843452b 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,14 +35,14 @@
#include "core/templates/thread_work_pool.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_scene_render_forward.h"
+#include "servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
class RendererCompositorRD : public RendererCompositor {
protected:
RendererCanvasRenderRD *canvas;
RendererStorageRD *storage;
- RendererSceneRenderForward *scene;
+ RendererSceneRenderRD *scene;
RID copy_viewports_rd_shader;
RID copy_viewports_rd_pipeline;
@@ -90,8 +90,6 @@ public:
virtual bool is_low_end() const { return false; }
- static ThreadWorkPool thread_work_pool;
-
static RendererCompositorRD *singleton;
RendererCompositorRD();
~RendererCompositorRD() {}
diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp
new file mode 100644
index 0000000000..d631cb4bac
--- /dev/null
+++ b/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp
@@ -0,0 +1,126 @@
+/*************************************************************************/
+/* renderer_scene_environment_rd.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
+
+uint64_t RendererSceneEnvironmentRD::auto_exposure_counter = 2;
+
+void RendererSceneEnvironmentRD::set_ambient_light(const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) {
+ ambient_light = p_color;
+ ambient_source = p_ambient;
+ ambient_light_energy = p_energy;
+ ambient_sky_contribution = p_sky_contribution;
+ reflection_source = p_reflection_source;
+ ao_color = p_ao_color;
+}
+
+void RendererSceneEnvironmentRD::set_tonemap(RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {
+ exposure = p_exposure;
+ tone_mapper = p_tone_mapper;
+ if (!auto_exposure && p_auto_exposure) {
+ auto_exposure_version = ++auto_exposure_counter;
+ }
+ auto_exposure = p_auto_exposure;
+ white = p_white;
+ min_luminance = p_min_luminance;
+ max_luminance = p_max_luminance;
+ auto_exp_speed = p_auto_exp_speed;
+ auto_exp_scale = p_auto_exp_scale;
+}
+
+void RendererSceneEnvironmentRD::set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
+ ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7");
+ glow_enabled = p_enable;
+ glow_levels = p_levels;
+ glow_intensity = p_intensity;
+ glow_strength = p_strength;
+ glow_mix = p_mix;
+ glow_bloom = p_bloom_threshold;
+ glow_blend_mode = p_blend_mode;
+ glow_hdr_bleed_threshold = p_hdr_bleed_threshold;
+ glow_hdr_bleed_scale = p_hdr_bleed_scale;
+ glow_hdr_luminance_cap = p_hdr_luminance_cap;
+}
+
+void RendererSceneEnvironmentRD::set_sdfgi(bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
+ sdfgi_enabled = p_enable;
+ sdfgi_cascades = p_cascades;
+ sdfgi_min_cell_size = p_min_cell_size;
+ sdfgi_use_occlusion = p_use_occlusion;
+ sdfgi_bounce_feedback = p_bounce_feedback;
+ sdfgi_read_sky_light = p_read_sky;
+ sdfgi_energy = p_energy;
+ sdfgi_normal_bias = p_normal_bias;
+ sdfgi_probe_bias = p_probe_bias;
+ sdfgi_y_scale = p_y_scale;
+}
+
+void RendererSceneEnvironmentRD::set_fog(bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) {
+ fog_enabled = p_enable;
+ fog_light_color = p_light_color;
+ fog_light_energy = p_light_energy;
+ fog_sun_scatter = p_sun_scatter;
+ fog_density = p_density;
+ fog_height = p_height;
+ fog_height_density = p_height_density;
+ fog_aerial_perspective = p_fog_aerial_perspective;
+}
+
+void RendererSceneEnvironmentRD::set_volumetric_fog(bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) {
+ volumetric_fog_enabled = p_enable;
+ volumetric_fog_density = p_density;
+ volumetric_fog_light = p_light;
+ volumetric_fog_light_energy = p_light_energy;
+ volumetric_fog_length = p_length;
+ volumetric_fog_detail_spread = p_detail_spread;
+ volumetric_fog_gi_inject = p_gi_inject;
+ volumetric_fog_temporal_reprojection = p_temporal_reprojection;
+ volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount;
+}
+
+void RendererSceneEnvironmentRD::set_ssr(bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) {
+ ssr_enabled = p_enable;
+ ssr_max_steps = p_max_steps;
+ ssr_fade_in = p_fade_int;
+ ssr_fade_out = p_fade_out;
+ ssr_depth_tolerance = p_depth_tolerance;
+}
+
+void RendererSceneEnvironmentRD::set_ssao(bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) {
+ ssao_enabled = p_enable;
+ ssao_radius = p_radius;
+ ssao_intensity = p_intensity;
+ ssao_power = p_power;
+ ssao_detail = p_detail;
+ ssao_horizon = p_horizon;
+ ssao_sharpness = p_sharpness;
+ ssao_direct_light_affect = p_light_affect;
+ ssao_ao_channel_affect = p_ao_channel_affect;
+}
diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h
new file mode 100644
index 0000000000..992c4bf471
--- /dev/null
+++ b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h
@@ -0,0 +1,155 @@
+/*************************************************************************/
+/* renderer_scene_environment_rd.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RENDERING_SERVER_SCENE_ENVIRONMENT_RD_H
+#define RENDERING_SERVER_SCENE_ENVIRONMENT_RD_H
+
+#include "servers/rendering/renderer_scene_render.h"
+#include "servers/rendering/rendering_device.h"
+
+class RendererSceneEnvironmentRD {
+private:
+ static uint64_t auto_exposure_counter;
+
+public:
+ // BG
+ RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR;
+ RID sky;
+ float sky_custom_fov = 0.0;
+ Basis sky_orientation;
+ Color bg_color;
+ float bg_energy = 1.0;
+ int canvas_max_layer = 0;
+ RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG;
+ Color ambient_light;
+ float ambient_light_energy = 1.0;
+ float ambient_sky_contribution = 1.0;
+ RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG;
+ Color ao_color;
+
+ /// Tonemap
+
+ RS::EnvironmentToneMapper tone_mapper;
+ float exposure = 1.0;
+ float white = 1.0;
+ bool auto_exposure = false;
+ float min_luminance = 0.2;
+ float max_luminance = 8.0;
+ float auto_exp_speed = 0.2;
+ float auto_exp_scale = 0.5;
+ uint64_t auto_exposure_version = 0;
+
+ // Fog
+ bool fog_enabled = false;
+ Color fog_light_color = Color(0.5, 0.6, 0.7);
+ float fog_light_energy = 1.0;
+ float fog_sun_scatter = 0.0;
+ float fog_density = 0.001;
+ float fog_height = 0.0;
+ float fog_height_density = 0.0; //can be negative to invert effect
+ float fog_aerial_perspective = 0.0;
+
+ /// Volumetric Fog
+ ///
+ bool volumetric_fog_enabled = false;
+ float volumetric_fog_density = 0.01;
+ Color volumetric_fog_light = Color(0, 0, 0);
+ float volumetric_fog_light_energy = 0.0;
+ float volumetric_fog_length = 64.0;
+ float volumetric_fog_detail_spread = 2.0;
+ float volumetric_fog_gi_inject = 0.0;
+ bool volumetric_fog_temporal_reprojection = true;
+ float volumetric_fog_temporal_reprojection_amount = 0.9;
+
+ /// Glow
+
+ bool glow_enabled = false;
+ Vector<float> glow_levels;
+ float glow_intensity = 0.8;
+ float glow_strength = 1.0;
+ float glow_bloom = 0.0;
+ float glow_mix = 0.01;
+ RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT;
+ float glow_hdr_bleed_threshold = 1.0;
+ float glow_hdr_luminance_cap = 12.0;
+ float glow_hdr_bleed_scale = 2.0;
+
+ /// SSAO
+
+ bool ssao_enabled = false;
+ float ssao_radius = 1.0;
+ float ssao_intensity = 2.0;
+ float ssao_power = 1.5;
+ float ssao_detail = 0.5;
+ float ssao_horizon = 0.06;
+ float ssao_sharpness = 0.98;
+ float ssao_direct_light_affect = 0.0;
+ float ssao_ao_channel_affect = 0.0;
+
+ /// SSR
+ ///
+ bool ssr_enabled = false;
+ int ssr_max_steps = 64;
+ float ssr_fade_in = 0.15;
+ float ssr_fade_out = 2.0;
+ float ssr_depth_tolerance = 0.2;
+
+ /// SDFGI
+ bool sdfgi_enabled = false;
+ RS::EnvironmentSDFGICascades sdfgi_cascades;
+ float sdfgi_min_cell_size = 0.2;
+ bool sdfgi_use_occlusion = false;
+ float sdfgi_bounce_feedback = 0.0;
+ bool sdfgi_read_sky_light = false;
+ float sdfgi_energy = 1.0;
+ float sdfgi_normal_bias = 1.1;
+ float sdfgi_probe_bias = 1.1;
+ RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_DISABLED;
+
+ /// Adjustments
+
+ bool adjustments_enabled = false;
+ float adjustments_brightness = 1.0f;
+ float adjustments_contrast = 1.0f;
+ float adjustments_saturation = 1.0f;
+ bool use_1d_color_correction = false;
+ RID color_correction = RID();
+
+ void set_ambient_light(const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color);
+ void set_tonemap(RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
+ void set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap);
+ void set_sdfgi(bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias);
+ void set_fog(bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective);
+ void set_volumetric_fog(bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount);
+ void set_ssr(bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance);
+ void set_ssao(bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect);
+};
+
+#endif /* !RENDERING_SERVER_SCENE_ENVIRONMENT_RD_H */
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
new file mode 100644
index 0000000000..4e4e553605
--- /dev/null
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
@@ -0,0 +1,3403 @@
+/*************************************************************************/
+/* renderer_scene_gi_rd.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "renderer_scene_gi_rd.h"
+
+#include "core/config/project_settings.h"
+#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
+#include "servers/rendering/rendering_server_default.h"
+
+const Vector3i RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
+
+////////////////////////////////////////////////////////////////////////////////
+// SDFGI
+
+void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, RendererSceneGIRD *p_gi) {
+ storage = p_gi->storage;
+ gi = p_gi;
+ cascade_mode = p_env->sdfgi_cascades;
+ min_cell_size = p_env->sdfgi_min_cell_size;
+ uses_occlusion = p_env->sdfgi_use_occlusion;
+ y_scale_mode = p_env->sdfgi_y_scale;
+ static const float y_scale[3] = { 1.0, 1.5, 2.0 };
+ y_mult = y_scale[y_scale_mode];
+ static const int cascasde_size[3] = { 4, 6, 8 };
+ cascades.resize(cascasde_size[cascade_mode]);
+ probe_axis_count = SDFGI::PROBE_DIVISOR + 1;
+ solid_cell_ratio = gi->sdfgi_solid_cell_ratio;
+ solid_cell_count = uint32_t(float(cascade_size * cascade_size * cascade_size) * solid_cell_ratio);
+
+ float base_cell_size = min_cell_size;
+
+ RD::TextureFormat tf_sdf;
+ tf_sdf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf_sdf.width = cascade_size; // Always 64x64
+ tf_sdf.height = cascade_size;
+ tf_sdf.depth = cascade_size;
+ tf_sdf.texture_type = RD::TEXTURE_TYPE_3D;
+ tf_sdf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+
+ {
+ RD::TextureFormat tf_render = tf_sdf;
+ tf_render.format = RD::DATA_FORMAT_R16_UINT;
+ render_albedo = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ tf_render.format = RD::DATA_FORMAT_R32_UINT;
+ render_emission = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ render_emission_aniso = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+
+ tf_render.format = RD::DATA_FORMAT_R8_UNORM; //at least its easy to visualize
+
+ for (int i = 0; i < 8; i++) {
+ render_occlusion[i] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ }
+
+ tf_render.format = RD::DATA_FORMAT_R32_UINT;
+ render_geom_facing = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+
+ tf_render.format = RD::DATA_FORMAT_R8G8B8A8_UINT;
+ render_sdf[0] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ render_sdf[1] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+
+ tf_render.width /= 2;
+ tf_render.height /= 2;
+ tf_render.depth /= 2;
+
+ render_sdf_half[0] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ render_sdf_half[1] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
+ }
+
+ RD::TextureFormat tf_occlusion = tf_sdf;
+ tf_occlusion.format = RD::DATA_FORMAT_R16_UINT;
+ tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R16_UINT);
+ tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16);
+ tf_occlusion.depth *= cascades.size(); //use depth for occlusion slices
+ tf_occlusion.width *= 2; //use width for the other half
+
+ RD::TextureFormat tf_light = tf_sdf;
+ tf_light.format = RD::DATA_FORMAT_R32_UINT;
+ tf_light.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT);
+ tf_light.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);
+
+ RD::TextureFormat tf_aniso0 = tf_sdf;
+ tf_aniso0.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ RD::TextureFormat tf_aniso1 = tf_sdf;
+ tf_aniso1.format = RD::DATA_FORMAT_R8G8_UNORM;
+
+ int passes = nearest_shift(cascade_size) - 1;
+
+ //store lightprobe SH
+ RD::TextureFormat tf_probes;
+ tf_probes.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf_probes.width = probe_axis_count * probe_axis_count;
+ tf_probes.height = probe_axis_count * SDFGI::SH_SIZE;
+ tf_probes.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ tf_probes.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+
+ history_size = p_requested_history_size;
+
+ RD::TextureFormat tf_probe_history = tf_probes;
+ tf_probe_history.format = RD::DATA_FORMAT_R16G16B16A16_SINT; //signed integer because SH are signed
+ tf_probe_history.array_layers = history_size;
+
+ RD::TextureFormat tf_probe_average = tf_probes;
+ tf_probe_average.format = RD::DATA_FORMAT_R32G32B32A32_SINT; //signed integer because SH are signed
+ tf_probe_average.texture_type = RD::TEXTURE_TYPE_2D;
+
+ lightprobe_history_scroll = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());
+ lightprobe_average_scroll = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());
+
+ {
+ //octahedral lightprobes
+ RD::TextureFormat tf_octprobes = tf_probes;
+ tf_octprobes.array_layers = cascades.size() * 2;
+ tf_octprobes.format = RD::DATA_FORMAT_R32_UINT; //pack well with RGBE
+ tf_octprobes.width = probe_axis_count * probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2);
+ tf_octprobes.height = probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2);
+ tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT);
+ tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);
+ //lightprobe texture is an octahedral texture
+
+ lightprobe_data = RD::get_singleton()->texture_create(tf_octprobes, RD::TextureView());
+ RD::TextureView tv;
+ tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
+ lightprobe_texture = RD::get_singleton()->texture_create_shared(tv, lightprobe_data);
+
+ //texture handling ambient data, to integrate with volumetric foc
+ RD::TextureFormat tf_ambient = tf_probes;
+ tf_ambient.array_layers = cascades.size();
+ tf_ambient.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; //pack well with RGBE
+ tf_ambient.width = probe_axis_count * probe_axis_count;
+ tf_ambient.height = probe_axis_count;
+ tf_ambient.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ //lightprobe texture is an octahedral texture
+ ambient_texture = RD::get_singleton()->texture_create(tf_ambient, RD::TextureView());
+ }
+
+ cascades_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES);
+
+ occlusion_data = RD::get_singleton()->texture_create(tf_occlusion, RD::TextureView());
+ {
+ RD::TextureView tv;
+ tv.format_override = RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16;
+ occlusion_texture = RD::get_singleton()->texture_create_shared(tv, occlusion_data);
+ }
+
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ SDFGI::Cascade &cascade = cascades[i];
+
+ /* 3D Textures */
+
+ cascade.sdf_tex = RD::get_singleton()->texture_create(tf_sdf, RD::TextureView());
+
+ cascade.light_data = RD::get_singleton()->texture_create(tf_light, RD::TextureView());
+
+ cascade.light_aniso_0_tex = RD::get_singleton()->texture_create(tf_aniso0, RD::TextureView());
+ cascade.light_aniso_1_tex = RD::get_singleton()->texture_create(tf_aniso1, RD::TextureView());
+
+ {
+ RD::TextureView tv;
+ tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
+ cascade.light_tex = RD::get_singleton()->texture_create_shared(tv, cascade.light_data);
+
+ RD::get_singleton()->texture_clear(cascade.light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ RD::get_singleton()->texture_clear(cascade.light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ RD::get_singleton()->texture_clear(cascade.light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ }
+
+ cascade.cell_size = base_cell_size;
+ Vector3 world_position = p_world_position;
+ world_position.y *= y_mult;
+ int32_t probe_cells = cascade_size / SDFGI::PROBE_DIVISOR;
+ Vector3 probe_size = Vector3(1, 1, 1) * cascade.cell_size * probe_cells;
+ Vector3i probe_pos = Vector3i((world_position / probe_size + Vector3(0.5, 0.5, 0.5)).floor());
+ cascade.position = probe_pos * probe_cells;
+
+ cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;
+
+ base_cell_size *= 2.0;
+
+ /* Probe History */
+
+ cascade.lightprobe_history_tex = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());
+ RD::get_singleton()->texture_clear(cascade.lightprobe_history_tex, Color(0, 0, 0, 0), 0, 1, 0, tf_probe_history.array_layers); //needs to be cleared for average to work
+
+ cascade.lightprobe_average_tex = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());
+ RD::get_singleton()->texture_clear(cascade.lightprobe_average_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); //needs to be cleared for average to work
+
+ /* Buffers */
+
+ cascade.solid_cell_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGI::Cascade::SolidCell) * solid_cell_count);
+ cascade.solid_cell_dispatch_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector<uint8_t>(), RD::STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT);
+ cascade.lights_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGIShader::Light) * MAX(SDFGI::MAX_STATIC_LIGHTS, SDFGI::MAX_DYNAMIC_LIGHTS));
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(render_albedo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 3;
+ for (int j = 0; j < 8; j++) {
+ u.ids.push_back(render_occlusion[j]);
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 4;
+ u.ids.push_back(render_emission);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 5;
+ u.ids.push_back(render_emission_aniso);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 6;
+ u.ids.push_back(render_geom_facing);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 7;
+ u.ids.push_back(cascade.sdf_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 8;
+ u.ids.push_back(occlusion_data);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 10;
+ u.ids.push_back(cascade.solid_cell_dispatch_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 11;
+ u.ids.push_back(cascade.solid_cell_buffer);
+ uniforms.push_back(u);
+ }
+
+ cascade.sdf_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_STORE), 0);
+ }
+
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(render_albedo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(render_geom_facing);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 3;
+ u.ids.push_back(render_emission);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 4;
+ u.ids.push_back(render_emission_aniso);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 5;
+ u.ids.push_back(cascade.solid_cell_dispatch_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 6;
+ u.ids.push_back(cascade.solid_cell_buffer);
+ uniforms.push_back(u);
+ }
+
+ cascade.scroll_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_SCROLL), 0);
+ }
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ for (int j = 0; j < 8; j++) {
+ u.ids.push_back(render_occlusion[j]);
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(occlusion_data);
+ uniforms.push_back(u);
+ }
+
+ cascade.scroll_occlusion_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_SCROLL_OCCLUSION), 0);
+ }
+ }
+
+ //direct light
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ SDFGI::Cascade &cascade = cascades[i];
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (j < cascades.size()) {
+ u.ids.push_back(cascades[j].sdf_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(cascade.solid_cell_dispatch_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(cascade.solid_cell_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 5;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.ids.push_back(cascade.light_data);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 6;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.ids.push_back(cascade.light_aniso_0_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 7;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.ids.push_back(cascade.light_aniso_1_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 8;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(cascades_ubo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 9;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(cascade.lights_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 10;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(lightprobe_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 11;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(occlusion_texture);
+ uniforms.push_back(u);
+ }
+
+ cascade.sdf_direct_light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.direct_light.version_get_shader(gi->sdfgi_shader.direct_light_shader, 0), 0);
+ }
+
+ //preprocess initialize uniform set
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(render_albedo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(render_sdf[0]);
+ uniforms.push_back(u);
+ }
+
+ sdf_initialize_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE), 0);
+ }
+
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(render_albedo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(render_sdf_half[0]);
+ uniforms.push_back(u);
+ }
+
+ sdf_initialize_half_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF), 0);
+ }
+
+ //jump flood uniform set
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(render_sdf[0]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(render_sdf[1]);
+ uniforms.push_back(u);
+ }
+
+ jump_flood_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0);
+ SWAP(uniforms.write[0].ids.write[0], uniforms.write[1].ids.write[0]);
+ jump_flood_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0);
+ }
+ //jump flood half uniform set
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(render_sdf_half[0]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(render_sdf_half[1]);
+ uniforms.push_back(u);
+ }
+
+ jump_flood_half_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0);
+ SWAP(uniforms.write[0].ids.write[0], uniforms.write[1].ids.write[0]);
+ jump_flood_half_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0);
+ }
+
+ //upscale half size sdf
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(render_albedo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ u.ids.push_back(render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 3;
+ u.ids.push_back(render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass
+ uniforms.push_back(u);
+ }
+
+ upscale_jfa_uniform_set_index = (passes & 1) ? 0 : 1;
+ sdf_upscale_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE), 0);
+ }
+
+ //occlusion uniform set
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(render_albedo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 2;
+ for (int i = 0; i < 8; i++) {
+ u.ids.push_back(render_occlusion[i]);
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 3;
+ u.ids.push_back(render_geom_facing);
+ uniforms.push_back(u);
+ }
+
+ occlusion_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_OCCLUSION), 0);
+ }
+
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ //integrate uniform
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (j < cascades.size()) {
+ u.ids.push_back(cascades[j].sdf_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (j < cascades.size()) {
+ u.ids.push_back(cascades[j].light_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (j < cascades.size()) {
+ u.ids.push_back(cascades[j].light_aniso_0_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (j < cascades.size()) {
+ u.ids.push_back(cascades[j].light_aniso_1_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 6;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 7;
+ u.ids.push_back(cascades_ubo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 8;
+ u.ids.push_back(lightprobe_data);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 9;
+ u.ids.push_back(cascades[i].lightprobe_history_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 10;
+ u.ids.push_back(cascades[i].lightprobe_average_tex);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 11;
+ u.ids.push_back(lightprobe_history_scroll);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 12;
+ u.ids.push_back(lightprobe_average_scroll);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 13;
+ RID parent_average;
+ if (i < cascades.size() - 1) {
+ parent_average = cascades[i + 1].lightprobe_average_tex;
+ } else {
+ parent_average = cascades[i - 1].lightprobe_average_tex; //to use something, but it won't be used
+ }
+ u.ids.push_back(parent_average);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 14;
+ u.ids.push_back(ambient_texture);
+ uniforms.push_back(u);
+ }
+
+ cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 0);
+ }
+
+ bounce_feedback = p_env->sdfgi_bounce_feedback;
+ energy = p_env->sdfgi_energy;
+ normal_bias = p_env->sdfgi_normal_bias;
+ probe_bias = p_env->sdfgi_probe_bias;
+ reads_sky = p_env->sdfgi_read_sky_light;
+}
+
+void RendererSceneGIRD::SDFGI::erase() {
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ const SDFGI::Cascade &c = cascades[i];
+ RD::get_singleton()->free(c.light_data);
+ RD::get_singleton()->free(c.light_aniso_0_tex);
+ RD::get_singleton()->free(c.light_aniso_1_tex);
+ RD::get_singleton()->free(c.sdf_tex);
+ RD::get_singleton()->free(c.solid_cell_dispatch_buffer);
+ RD::get_singleton()->free(c.solid_cell_buffer);
+ RD::get_singleton()->free(c.lightprobe_history_tex);
+ RD::get_singleton()->free(c.lightprobe_average_tex);
+ RD::get_singleton()->free(c.lights_buffer);
+ }
+
+ RD::get_singleton()->free(render_albedo);
+ RD::get_singleton()->free(render_emission);
+ RD::get_singleton()->free(render_emission_aniso);
+
+ RD::get_singleton()->free(render_sdf[0]);
+ RD::get_singleton()->free(render_sdf[1]);
+
+ RD::get_singleton()->free(render_sdf_half[0]);
+ RD::get_singleton()->free(render_sdf_half[1]);
+
+ for (int i = 0; i < 8; i++) {
+ RD::get_singleton()->free(render_occlusion[i]);
+ }
+
+ RD::get_singleton()->free(render_geom_facing);
+
+ RD::get_singleton()->free(lightprobe_data);
+ RD::get_singleton()->free(lightprobe_history_scroll);
+ RD::get_singleton()->free(occlusion_data);
+ RD::get_singleton()->free(ambient_texture);
+
+ RD::get_singleton()->free(cascades_ubo);
+}
+
+void RendererSceneGIRD::SDFGI::update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position) {
+ bounce_feedback = p_env->sdfgi_bounce_feedback;
+ energy = p_env->sdfgi_energy;
+ normal_bias = p_env->sdfgi_normal_bias;
+ probe_bias = p_env->sdfgi_probe_bias;
+ reads_sky = p_env->sdfgi_read_sky_light;
+
+ int32_t drag_margin = (cascade_size / SDFGI::PROBE_DIVISOR) / 2;
+
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ SDFGI::Cascade &cascade = cascades[i];
+ cascade.dirty_regions = Vector3i();
+
+ Vector3 probe_half_size = Vector3(1, 1, 1) * cascade.cell_size * float(cascade_size / SDFGI::PROBE_DIVISOR) * 0.5;
+ probe_half_size = Vector3(0, 0, 0);
+
+ Vector3 world_position = p_world_position;
+ world_position.y *= y_mult;
+ Vector3i pos_in_cascade = Vector3i((world_position + probe_half_size) / cascade.cell_size);
+
+ for (int j = 0; j < 3; j++) {
+ if (pos_in_cascade[j] < cascade.position[j]) {
+ while (pos_in_cascade[j] < (cascade.position[j] - drag_margin)) {
+ cascade.position[j] -= drag_margin * 2;
+ cascade.dirty_regions[j] += drag_margin * 2;
+ }
+ } else if (pos_in_cascade[j] > cascade.position[j]) {
+ while (pos_in_cascade[j] > (cascade.position[j] + drag_margin)) {
+ cascade.position[j] += drag_margin * 2;
+ cascade.dirty_regions[j] -= drag_margin * 2;
+ }
+ }
+
+ if (cascade.dirty_regions[j] == 0) {
+ continue; // not dirty
+ } else if (uint32_t(ABS(cascade.dirty_regions[j])) >= cascade_size) {
+ //moved too much, just redraw everything (make all dirty)
+ cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;
+ break;
+ }
+ }
+
+ if (cascade.dirty_regions != Vector3i() && cascade.dirty_regions != SDFGI::Cascade::DIRTY_ALL) {
+ //see how much the total dirty volume represents from the total volume
+ uint32_t total_volume = cascade_size * cascade_size * cascade_size;
+ uint32_t safe_volume = 1;
+ for (int j = 0; j < 3; j++) {
+ safe_volume *= cascade_size - ABS(cascade.dirty_regions[j]);
+ }
+ uint32_t dirty_volume = total_volume - safe_volume;
+ if (dirty_volume > (safe_volume / 2)) {
+ //more than half the volume is dirty, make all dirty so its only rendered once
+ cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;
+ }
+ }
+ }
+}
+
+void RendererSceneGIRD::SDFGI::update_light() {
+ RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light");
+
+ /* Update dynamic light */
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.direct_light_pipeline[SDFGIShader::DIRECT_LIGHT_MODE_DYNAMIC]);
+
+ SDFGIShader::DirectLightPushConstant push_constant;
+
+ push_constant.grid_size[0] = cascade_size;
+ push_constant.grid_size[1] = cascade_size;
+ push_constant.grid_size[2] = cascade_size;
+ push_constant.max_cascades = cascades.size();
+ push_constant.probe_axis_size = probe_axis_count;
+ push_constant.bounce_feedback = bounce_feedback;
+ push_constant.y_mult = y_mult;
+ push_constant.use_occlusion = uses_occlusion;
+
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ SDFGI::Cascade &cascade = cascades[i];
+ push_constant.light_count = cascade_dynamic_light_count[i];
+ push_constant.cascade = i;
+
+ if (cascades[i].all_dynamic_lights_dirty || gi->sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) {
+ push_constant.process_offset = 0;
+ push_constant.process_increment = 1;
+ } else {
+ static uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = {
+ 1, 2, 4, 8, 16
+ };
+
+ uint32_t frames_to_update = frames_to_update_table[gi->sdfgi_frames_to_update_light];
+
+ push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update;
+ push_constant.process_increment = frames_to_update;
+ }
+ cascades[i].all_dynamic_lights_dirty = false;
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DirectLightPushConstant));
+ RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0);
+ }
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->draw_command_end_label();
+}
+
+void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky) {
+ RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes");
+
+ SDFGIShader::IntegratePushConstant push_constant;
+ push_constant.grid_size[1] = cascade_size;
+ push_constant.grid_size[2] = cascade_size;
+ push_constant.grid_size[0] = cascade_size;
+ push_constant.max_cascades = cascades.size();
+ push_constant.probe_axis_size = probe_axis_count;
+ push_constant.history_index = render_pass % history_size;
+ push_constant.history_size = history_size;
+ static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 };
+ push_constant.ray_count = ray_count[gi->sdfgi_ray_count];
+ push_constant.ray_bias = probe_bias;
+ push_constant.image_size[0] = probe_axis_count * probe_axis_count;
+ push_constant.image_size[1] = probe_axis_count;
+ push_constant.store_ambient_texture = p_env->volumetric_fog_enabled;
+
+ RID sky_uniform_set = gi->sdfgi_shader.integrate_default_sky_uniform_set;
+ push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_DISABLED;
+ push_constant.y_mult = y_mult;
+
+ if (reads_sky && p_env) {
+ push_constant.sky_energy = p_env->bg_energy;
+
+ if (p_env->background == RS::ENV_BG_CLEAR_COLOR) {
+ push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR;
+ Color c = storage->get_default_clear_color().to_linear();
+ push_constant.sky_color[0] = c.r;
+ push_constant.sky_color[1] = c.g;
+ push_constant.sky_color[2] = c.b;
+ } else if (p_env->background == RS::ENV_BG_COLOR) {
+ push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR;
+ Color c = p_env->bg_color;
+ push_constant.sky_color[0] = c.r;
+ push_constant.sky_color[1] = c.g;
+ push_constant.sky_color[2] = c.b;
+
+ } else if (p_env->background == RS::ENV_BG_SKY) {
+ if (p_sky && p_sky->radiance.is_valid()) {
+ if (integrate_sky_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(integrate_sky_uniform_set)) {
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(p_sky->radiance);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 1;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ integrate_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 1);
+ }
+ sky_uniform_set = integrate_sky_uniform_set;
+ push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_SKY;
+ }
+ }
+ }
+
+ render_pass++;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_PROCESS]);
+
+ int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ push_constant.cascade = i;
+ push_constant.world_offset[0] = cascades[i].position.x / probe_divisor;
+ push_constant.world_offset[1] = cascades[i].position.y / probe_divisor;
+ push_constant.world_offset[2] = cascades[i].position.z / probe_divisor;
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[i].integrate_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sky_uniform_set, 1);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::IntegratePushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);
+ }
+
+ //end later after raster to avoid barriering on layout changes
+ //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER);
+
+ RD::get_singleton()->draw_command_end_label();
+}
+
+void RendererSceneGIRD::SDFGI::store_probes() {
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_COMPUTE, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes");
+
+ SDFGIShader::IntegratePushConstant push_constant;
+ push_constant.grid_size[1] = cascade_size;
+ push_constant.grid_size[2] = cascade_size;
+ push_constant.grid_size[0] = cascade_size;
+ push_constant.max_cascades = cascades.size();
+ push_constant.probe_axis_size = probe_axis_count;
+ push_constant.history_index = render_pass % history_size;
+ push_constant.history_size = history_size;
+ static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 };
+ push_constant.ray_count = ray_count[gi->sdfgi_ray_count];
+ push_constant.ray_bias = probe_bias;
+ push_constant.image_size[0] = probe_axis_count * probe_axis_count;
+ push_constant.image_size[1] = probe_axis_count;
+ push_constant.store_ambient_texture = false;
+
+ push_constant.sky_mode = 0;
+ push_constant.y_mult = y_mult;
+
+ // Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces
+ RENDER_TIMESTAMP("Average Probes");
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE]);
+
+ //convert to octahedral to store
+ push_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;
+ push_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;
+
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ push_constant.cascade = i;
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[i].integrate_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::IntegratePushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1);
+ }
+
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
+
+ RD::get_singleton()->draw_command_end_label();
+}
+
+int RendererSceneGIRD::SDFGI::get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const {
+ int dirty_count = 0;
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ const SDFGI::Cascade &c = cascades[i];
+
+ if (c.dirty_regions == SDFGI::Cascade::DIRTY_ALL) {
+ if (dirty_count == p_region) {
+ r_local_offset = Vector3i();
+ r_local_size = Vector3i(1, 1, 1) * cascade_size;
+
+ r_bounds.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + c.position)) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);
+ r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);
+ return i;
+ }
+ dirty_count++;
+ } else {
+ for (int j = 0; j < 3; j++) {
+ if (c.dirty_regions[j] != 0) {
+ if (dirty_count == p_region) {
+ Vector3i from = Vector3i(0, 0, 0);
+ Vector3i to = Vector3i(1, 1, 1) * cascade_size;
+
+ if (c.dirty_regions[j] > 0) {
+ //fill from the beginning
+ to[j] = c.dirty_regions[j];
+ } else {
+ //fill from the end
+ from[j] = to[j] + c.dirty_regions[j];
+ }
+
+ for (int k = 0; k < j; k++) {
+ // "chip" away previous regions to avoid re-voxelizing the same thing
+ if (c.dirty_regions[k] > 0) {
+ from[k] += c.dirty_regions[k];
+ } else if (c.dirty_regions[k] < 0) {
+ to[k] += c.dirty_regions[k];
+ }
+ }
+
+ r_local_offset = from;
+ r_local_size = to - from;
+
+ r_bounds.position = Vector3(from + Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + c.position) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);
+ r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);
+
+ return i;
+ }
+
+ dirty_count++;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+void RendererSceneGIRD::SDFGI::update_cascades() {
+ //update cascades
+ SDFGI::Cascade::UBO cascade_data[SDFGI::MAX_CASCADES];
+ int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;
+
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[i].position)) * cascades[i].cell_size;
+
+ cascade_data[i].offset[0] = pos.x;
+ cascade_data[i].offset[1] = pos.y;
+ cascade_data[i].offset[2] = pos.z;
+ cascade_data[i].to_cell = 1.0 / cascades[i].cell_size;
+ cascade_data[i].probe_offset[0] = cascades[i].position.x / probe_divisor;
+ cascade_data[i].probe_offset[1] = cascades[i].position.y / probe_divisor;
+ cascade_data[i].probe_offset[2] = cascades[i].position.z / probe_divisor;
+ cascade_data[i].pad = 0;
+ }
+
+ RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE);
+}
+
+void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) {
+ if (!debug_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set)) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
+ if (i < cascades.size()) {
+ u.ids.push_back(cascades[i].sdf_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
+ if (i < cascades.size()) {
+ u.ids.push_back(cascades[i].light_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
+ if (i < cascades.size()) {
+ u.ids.push_back(cascades[i].light_aniso_0_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
+ if (i < cascades.size()) {
+ u.ids.push_back(cascades[i].light_aniso_1_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 5;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(occlusion_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 8;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 9;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(cascades_ubo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 10;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.ids.push_back(p_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 11;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(lightprobe_texture);
+ uniforms.push_back(u);
+ }
+ debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0);
+ }
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.debug_pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set, 0);
+
+ SDFGIShader::DebugPushConstant push_constant;
+ push_constant.grid_size[0] = cascade_size;
+ push_constant.grid_size[1] = cascade_size;
+ push_constant.grid_size[2] = cascade_size;
+ push_constant.max_cascades = cascades.size();
+ push_constant.screen_size[0] = p_width;
+ push_constant.screen_size[1] = p_height;
+ push_constant.probe_axis_size = probe_axis_count;
+ push_constant.use_occlusion = uses_occlusion;
+ push_constant.y_mult = y_mult;
+
+ Vector2 vp_half = p_projection.get_viewport_half_extents();
+ push_constant.cam_extent[0] = vp_half.x;
+ push_constant.cam_extent[1] = vp_half.y;
+ push_constant.cam_extent[2] = -p_projection.get_z_near();
+
+ push_constant.cam_transform[0] = p_transform.basis.elements[0][0];
+ push_constant.cam_transform[1] = p_transform.basis.elements[1][0];
+ push_constant.cam_transform[2] = p_transform.basis.elements[2][0];
+ push_constant.cam_transform[3] = 0;
+ push_constant.cam_transform[4] = p_transform.basis.elements[0][1];
+ push_constant.cam_transform[5] = p_transform.basis.elements[1][1];
+ push_constant.cam_transform[6] = p_transform.basis.elements[2][1];
+ push_constant.cam_transform[7] = 0;
+ push_constant.cam_transform[8] = p_transform.basis.elements[0][2];
+ push_constant.cam_transform[9] = p_transform.basis.elements[1][2];
+ push_constant.cam_transform[10] = p_transform.basis.elements[2][2];
+ push_constant.cam_transform[11] = 0;
+ push_constant.cam_transform[12] = p_transform.origin.x;
+ push_constant.cam_transform[13] = p_transform.origin.y;
+ push_constant.cam_transform[14] = p_transform.origin.z;
+ push_constant.cam_transform[15] = 1;
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DebugPushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1);
+ RD::get_singleton()->compute_list_end();
+
+ Size2 rtsize = storage->render_target_get_size(p_render_target);
+ storage->get_effects()->copy_to_fb_rect(p_texture, storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true);
+}
+
+void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {
+ SDFGIShader::DebugProbesPushConstant push_constant;
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ push_constant.projection[i * 4 + j] = p_camera_with_transform.matrix[i][j];
+ }
+ }
+
+ //gen spheres from strips
+ uint32_t band_points = 16;
+ push_constant.band_power = 4;
+ push_constant.sections_in_band = ((band_points / 2) - 1);
+ push_constant.band_mask = band_points - 2;
+ push_constant.section_arc = Math_TAU / float(push_constant.sections_in_band);
+ push_constant.y_mult = y_mult;
+
+ uint32_t total_points = push_constant.sections_in_band * band_points;
+ uint32_t total_probes = probe_axis_count * probe_axis_count * probe_axis_count;
+
+ push_constant.grid_size[0] = cascade_size;
+ push_constant.grid_size[1] = cascade_size;
+ push_constant.grid_size[2] = cascade_size;
+ push_constant.cascade = 0;
+
+ push_constant.probe_axis_size = probe_axis_count;
+
+ if (!debug_probes_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(cascades_ubo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(lightprobe_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(occlusion_texture);
+ uniforms.push_back(u);
+ }
+
+ debug_probes_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_probes.version_get_shader(gi->sdfgi_shader.debug_probes_shader, 0), 0);
+ }
+
+ RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, gi->sdfgi_shader.debug_probes_pipeline[SDFGIShader::PROBE_DEBUG_PROBES].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, debug_probes_uniform_set, 0);
+ RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));
+ RD::get_singleton()->draw_list_draw(p_draw_list, false, total_probes, total_points);
+
+ if (gi->sdfgi_debug_probe_dir != Vector3()) {
+ print_line("CLICK DEBUG ME?");
+ uint32_t cascade = 0;
+ Vector3 offset = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[cascade].position)) * cascades[cascade].cell_size * Vector3(1.0, 1.0 / y_mult, 1.0);
+ Vector3 probe_size = cascades[cascade].cell_size * (cascade_size / SDFGI::PROBE_DIVISOR) * Vector3(1.0, 1.0 / y_mult, 1.0);
+ Vector3 ray_from = gi->sdfgi_debug_probe_pos;
+ Vector3 ray_to = gi->sdfgi_debug_probe_pos + gi->sdfgi_debug_probe_dir * cascades[cascade].cell_size * Math::sqrt(3.0) * cascade_size;
+ float sphere_radius = 0.2;
+ float closest_dist = 1e20;
+ gi->sdfgi_debug_probe_enabled = false;
+
+ Vector3i probe_from = cascades[cascade].position / (cascade_size / SDFGI::PROBE_DIVISOR);
+ for (int i = 0; i < (SDFGI::PROBE_DIVISOR + 1); i++) {
+ for (int j = 0; j < (SDFGI::PROBE_DIVISOR + 1); j++) {
+ for (int k = 0; k < (SDFGI::PROBE_DIVISOR + 1); k++) {
+ Vector3 pos = offset + probe_size * Vector3(i, j, k);
+ Vector3 res;
+ if (Geometry3D::segment_intersects_sphere(ray_from, ray_to, pos, sphere_radius, &res)) {
+ float d = ray_from.distance_to(res);
+ if (d < closest_dist) {
+ closest_dist = d;
+ gi->sdfgi_debug_probe_enabled = true;
+ gi->sdfgi_debug_probe_index = probe_from + Vector3i(i, j, k);
+ }
+ }
+ }
+ }
+ }
+
+ if (gi->sdfgi_debug_probe_enabled) {
+ print_line("found: " + gi->sdfgi_debug_probe_index);
+ } else {
+ print_line("no found");
+ }
+ gi->sdfgi_debug_probe_dir = Vector3();
+ }
+
+ if (gi->sdfgi_debug_probe_enabled) {
+ uint32_t cascade = 0;
+ uint32_t probe_cells = (cascade_size / SDFGI::PROBE_DIVISOR);
+ Vector3i probe_from = cascades[cascade].position / probe_cells;
+ Vector3i ofs = gi->sdfgi_debug_probe_index - probe_from;
+ if (ofs.x < 0 || ofs.y < 0 || ofs.z < 0) {
+ return;
+ }
+ if (ofs.x > SDFGI::PROBE_DIVISOR || ofs.y > SDFGI::PROBE_DIVISOR || ofs.z > SDFGI::PROBE_DIVISOR) {
+ return;
+ }
+
+ uint32_t mult = (SDFGI::PROBE_DIVISOR + 1);
+ uint32_t index = ofs.z * mult * mult + ofs.y * mult + ofs.x;
+
+ push_constant.probe_debug_index = index;
+
+ uint32_t cell_count = probe_cells * 2 * probe_cells * 2 * probe_cells * 2;
+
+ RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, gi->sdfgi_shader.debug_probes_pipeline[SDFGIShader::PROBE_DEBUG_VISIBILITY].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, debug_probes_uniform_set, 0);
+ RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));
+ RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, total_points);
+ }
+}
+
+void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform &p_transform, RendererSceneRenderRD *p_scene_render) {
+ /* Update general SDFGI Buffer */
+
+ SDFGIData sdfgi_data;
+
+ sdfgi_data.grid_size[0] = cascade_size;
+ sdfgi_data.grid_size[1] = cascade_size;
+ sdfgi_data.grid_size[2] = cascade_size;
+
+ sdfgi_data.max_cascades = cascades.size();
+ sdfgi_data.probe_axis_size = probe_axis_count;
+ sdfgi_data.cascade_probe_size[0] = sdfgi_data.probe_axis_size - 1; //float version for performance
+ sdfgi_data.cascade_probe_size[1] = sdfgi_data.probe_axis_size - 1;
+ sdfgi_data.cascade_probe_size[2] = sdfgi_data.probe_axis_size - 1;
+
+ float csize = cascade_size;
+ sdfgi_data.probe_to_uvw = 1.0 / float(sdfgi_data.cascade_probe_size[0]);
+ sdfgi_data.use_occlusion = uses_occlusion;
+ //sdfgi_data.energy = energy;
+
+ sdfgi_data.y_mult = y_mult;
+
+ float cascade_voxel_size = (csize / sdfgi_data.cascade_probe_size[0]);
+ float occlusion_clamp = (cascade_voxel_size - 0.5) / cascade_voxel_size;
+ sdfgi_data.occlusion_clamp[0] = occlusion_clamp;
+ sdfgi_data.occlusion_clamp[1] = occlusion_clamp;
+ sdfgi_data.occlusion_clamp[2] = occlusion_clamp;
+ sdfgi_data.normal_bias = (normal_bias / csize) * sdfgi_data.cascade_probe_size[0];
+
+ //vec2 tex_pixel_size = 1.0 / vec2(ivec2( (OCT_SIZE+2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE+2) * params.probe_axis_size ) );
+ //vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx;
+
+ uint32_t oct_size = SDFGI::LIGHTPROBE_OCT_SIZE;
+
+ sdfgi_data.lightprobe_tex_pixel_size[0] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size * sdfgi_data.probe_axis_size);
+ sdfgi_data.lightprobe_tex_pixel_size[1] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size);
+ sdfgi_data.lightprobe_tex_pixel_size[2] = 1.0;
+
+ sdfgi_data.energy = energy;
+
+ sdfgi_data.lightprobe_uv_offset[0] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[0];
+ sdfgi_data.lightprobe_uv_offset[1] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[1];
+ sdfgi_data.lightprobe_uv_offset[2] = float((oct_size + 2) * sdfgi_data.probe_axis_size) * sdfgi_data.lightprobe_tex_pixel_size[0];
+
+ sdfgi_data.occlusion_renormalize[0] = 0.5;
+ sdfgi_data.occlusion_renormalize[1] = 1.0;
+ sdfgi_data.occlusion_renormalize[2] = 1.0 / float(sdfgi_data.max_cascades);
+
+ int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;
+
+ for (uint32_t i = 0; i < sdfgi_data.max_cascades; i++) {
+ SDFGIData::ProbeCascadeData &c = sdfgi_data.cascades[i];
+ Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[i].position)) * cascades[i].cell_size;
+ Vector3 cam_origin = p_transform.origin;
+ cam_origin.y *= y_mult;
+ pos -= cam_origin; //make pos local to camera, to reduce numerical error
+ c.position[0] = pos.x;
+ c.position[1] = pos.y;
+ c.position[2] = pos.z;
+ c.to_probe = 1.0 / (float(cascade_size) * cascades[i].cell_size / float(probe_axis_count - 1));
+
+ Vector3i probe_ofs = cascades[i].position / probe_divisor;
+ c.probe_world_offset[0] = probe_ofs.x;
+ c.probe_world_offset[1] = probe_ofs.y;
+ c.probe_world_offset[2] = probe_ofs.z;
+
+ c.to_cell = 1.0 / cascades[i].cell_size;
+ }
+
+ RD::get_singleton()->buffer_update(gi->sdfgi_ubo, 0, sizeof(SDFGIData), &sdfgi_data, RD::BARRIER_MASK_COMPUTE);
+
+ /* Update dynamic lights in SDFGI cascades */
+
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ SDFGI::Cascade &cascade = cascades[i];
+
+ SDFGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS];
+ uint32_t idx = 0;
+ for (uint32_t j = 0; j < (uint32_t)p_scene_render->render_state.sdfgi_update_data->directional_lights->size(); j++) {
+ if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
+ break;
+ }
+
+ RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.getornull(p_scene_render->render_state.sdfgi_update_data->directional_lights->get(j));
+ ERR_CONTINUE(!li);
+
+ if (storage->light_directional_is_sky_only(li->light)) {
+ continue;
+ }
+
+ Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
+ dir.y *= y_mult;
+ dir.normalize();
+ lights[idx].direction[0] = dir.x;
+ lights[idx].direction[1] = dir.y;
+ lights[idx].direction[2] = dir.z;
+ Color color = storage->light_get_color(li->light);
+ color = color.to_linear();
+ lights[idx].color[0] = color.r;
+ lights[idx].color[1] = color.g;
+ lights[idx].color[2] = color.b;
+ lights[idx].type = RS::LIGHT_DIRECTIONAL;
+ lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY);
+ lights[idx].has_shadow = storage->light_has_shadow(li->light);
+
+ idx++;
+ }
+
+ AABB cascade_aabb;
+ cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascade.position)) * cascade.cell_size;
+ cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cascade.cell_size;
+
+ for (uint32_t j = 0; j < p_scene_render->render_state.sdfgi_update_data->positional_light_count; j++) {
+ if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
+ break;
+ }
+
+ RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.getornull(p_scene_render->render_state.sdfgi_update_data->positional_light_instances[j]);
+ ERR_CONTINUE(!li);
+
+ uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light);
+ if (i > max_sdfgi_cascade) {
+ continue;
+ }
+
+ if (!cascade_aabb.intersects(li->aabb)) {
+ continue;
+ }
+
+ Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
+ //faster to not do this here
+ //dir.y *= y_mult;
+ //dir.normalize();
+ lights[idx].direction[0] = dir.x;
+ lights[idx].direction[1] = dir.y;
+ lights[idx].direction[2] = dir.z;
+ Vector3 pos = li->transform.origin;
+ pos.y *= y_mult;
+ lights[idx].position[0] = pos.x;
+ lights[idx].position[1] = pos.y;
+ lights[idx].position[2] = pos.z;
+ Color color = storage->light_get_color(li->light);
+ color = color.to_linear();
+ lights[idx].color[0] = color.r;
+ lights[idx].color[1] = color.g;
+ lights[idx].color[2] = color.b;
+ lights[idx].type = storage->light_get_type(li->light);
+ lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY);
+ lights[idx].has_shadow = storage->light_has_shadow(li->light);
+ lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
+ lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
+ lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
+ lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+
+ idx++;
+ }
+
+ if (idx > 0) {
+ RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights, RD::BARRIER_MASK_COMPUTE);
+ }
+
+ cascade_dynamic_light_count[i] = idx;
+ }
+}
+
+void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) {
+ //print_line("rendering region " + itos(p_region));
+ RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but...
+ AABB bounds;
+ Vector3i from;
+ Vector3i size;
+
+ int cascade_prev = get_pending_region_data(p_region - 1, from, size, bounds);
+ int cascade_next = get_pending_region_data(p_region + 1, from, size, bounds);
+ int cascade = get_pending_region_data(p_region, from, size, bounds);
+ ERR_FAIL_COND(cascade < 0);
+
+ if (cascade_prev != cascade) {
+ //initialize render
+ RD::get_singleton()->texture_clear(render_albedo, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ RD::get_singleton()->texture_clear(render_emission, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ RD::get_singleton()->texture_clear(render_emission_aniso, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ RD::get_singleton()->texture_clear(render_geom_facing, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ }
+
+ //print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(cascades[cascade].cell_size));
+ p_scene_render->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing);
+
+ if (cascade_next != cascade) {
+ RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade");
+
+ RENDER_TIMESTAMP(">SDFGI Update SDF");
+ //done rendering! must update SDF
+ //clear dispatch indirect data
+
+ SDFGIShader::PreprocessPushConstant push_constant;
+ zeromem(&push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+
+ RENDER_TIMESTAMP("Scroll SDF");
+
+ //scroll
+ if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {
+ //for scroll
+ Vector3i dirty = cascades[cascade].dirty_regions;
+ push_constant.scroll[0] = dirty.x;
+ push_constant.scroll[1] = dirty.y;
+ push_constant.scroll[2] = dirty.z;
+ } else {
+ //for no scroll
+ push_constant.scroll[0] = 0;
+ push_constant.scroll[1] = 0;
+ push_constant.scroll[2] = 0;
+ }
+
+ cascades[cascade].all_dynamic_lights_dirty = true;
+
+ push_constant.grid_size = cascade_size;
+ push_constant.cascade = cascade;
+
+ if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ //must pre scroll existing data because not all is dirty
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_uniform_set, 0);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascades[cascade].solid_cell_dispatch_buffer, 0);
+ // no barrier do all together
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL_OCCLUSION]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_occlusion_uniform_set, 0);
+
+ Vector3i dirty = cascades[cascade].dirty_regions;
+ Vector3i groups;
+ groups.x = cascade_size - ABS(dirty.x);
+ groups.y = cascade_size - ABS(dirty.y);
+ groups.z = cascade_size - ABS(dirty.z);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z);
+
+ //no barrier, continue together
+
+ {
+ //scroll probes and their history also
+
+ SDFGIShader::IntegratePushConstant ipush_constant;
+ ipush_constant.grid_size[1] = cascade_size;
+ ipush_constant.grid_size[2] = cascade_size;
+ ipush_constant.grid_size[0] = cascade_size;
+ ipush_constant.max_cascades = cascades.size();
+ ipush_constant.probe_axis_size = probe_axis_count;
+ ipush_constant.history_index = 0;
+ ipush_constant.history_size = history_size;
+ ipush_constant.ray_count = 0;
+ ipush_constant.ray_bias = 0;
+ ipush_constant.sky_mode = 0;
+ ipush_constant.sky_energy = 0;
+ ipush_constant.sky_color[0] = 0;
+ ipush_constant.sky_color[1] = 0;
+ ipush_constant.sky_color[2] = 0;
+ ipush_constant.y_mult = y_mult;
+ ipush_constant.store_ambient_texture = false;
+
+ ipush_constant.image_size[0] = probe_axis_count * probe_axis_count;
+ ipush_constant.image_size[1] = probe_axis_count;
+
+ int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;
+ ipush_constant.cascade = cascade;
+ ipush_constant.world_offset[0] = cascades[cascade].position.x / probe_divisor;
+ ipush_constant.world_offset[1] = cascades[cascade].position.y / probe_divisor;
+ ipush_constant.world_offset[2] = cascades[cascade].position.z / probe_divisor;
+
+ ipush_constant.scroll[0] = dirty.x / probe_divisor;
+ ipush_constant.scroll[1] = dirty.y / probe_divisor;
+ ipush_constant.scroll[2] = dirty.z / probe_divisor;
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_SCROLL]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_SCROLL_STORE]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ if (bounce_feedback > 0.0) {
+ //multibounce requires this to be stored so direct light can read from it
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE]);
+
+ //convert to octahedral to store
+ ipush_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;
+ ipush_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1);
+ }
+ }
+
+ //ok finally barrier
+ RD::get_singleton()->compute_list_end();
+ }
+
+ //clear dispatch indirect data
+ uint32_t dispatch_indirct_data[4] = { 0, 0, 0, 0 };
+ RD::get_singleton()->buffer_update(cascades[cascade].solid_cell_dispatch_buffer, 0, sizeof(uint32_t) * 4, dispatch_indirct_data);
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ bool half_size = true; //much faster, very little difference
+ static const int optimized_jf_group_size = 8;
+
+ if (half_size) {
+ push_constant.grid_size >>= 1;
+
+ uint32_t cascade_half_size = cascade_size >> 1;
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_half_uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ //must start with regular jumpflood
+
+ push_constant.half_size = true;
+ {
+ RENDER_TIMESTAMP("SDFGI Jump Flood (Half Size)");
+
+ uint32_t s = cascade_half_size;
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD]);
+
+ int jf_us = 0;
+ //start with regular jump flood for very coarse reads, as this is impossible to optimize
+ while (s > 1) {
+ s /= 2;
+ push_constant.step_size = s;
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_half_uniform_set[jf_us], 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ jf_us = jf_us == 0 ? 1 : 0;
+
+ if (cascade_half_size / (s / 2) >= optimized_jf_group_size) {
+ break;
+ }
+ }
+
+ RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half Size)");
+
+ //continue with optimized jump flood for smaller reads
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);
+ while (s > 1) {
+ s /= 2;
+ push_constant.step_size = s;
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_half_uniform_set[jf_us], 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ jf_us = jf_us == 0 ? 1 : 0;
+ }
+ }
+
+ // restore grid size for last passes
+ push_constant.grid_size = cascade_size;
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_upscale_uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ //run one pass of fullsize jumpflood to fix up half size arctifacts
+
+ push_constant.half_size = false;
+ push_constant.step_size = 1;
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[upscale_jfa_uniform_set_index], 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ } else {
+ //full size jumpflood
+ RENDER_TIMESTAMP("SDFGI Jump Flood");
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ push_constant.half_size = false;
+ {
+ uint32_t s = cascade_size;
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD]);
+
+ int jf_us = 0;
+ //start with regular jump flood for very coarse reads, as this is impossible to optimize
+ while (s > 1) {
+ s /= 2;
+ push_constant.step_size = s;
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[jf_us], 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ jf_us = jf_us == 0 ? 1 : 0;
+
+ if (cascade_size / (s / 2) >= optimized_jf_group_size) {
+ break;
+ }
+ }
+
+ RENDER_TIMESTAMP("SDFGI Jump Flood Optimized");
+
+ //continue with optimized jump flood for smaller reads
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);
+ while (s > 1) {
+ s /= 2;
+ push_constant.step_size = s;
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[jf_us], 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ jf_us = jf_us == 0 ? 1 : 0;
+ }
+ }
+ }
+
+ RENDER_TIMESTAMP("SDFGI Occlusion");
+
+ // occlusion
+ {
+ uint32_t probe_size = cascade_size / SDFGI::PROBE_DIVISOR;
+ Vector3i probe_global_pos = cascades[cascade].position / probe_size;
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_OCCLUSION]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, occlusion_uniform_set, 0);
+ for (int i = 0; i < 8; i++) {
+ //dispatch all at once for performance
+ Vector3i offset(i & 1, (i >> 1) & 1, (i >> 2) & 1);
+
+ if ((probe_global_pos.x & 1) != 0) {
+ offset.x = (offset.x + 1) & 1;
+ }
+ if ((probe_global_pos.y & 1) != 0) {
+ offset.y = (offset.y + 1) & 1;
+ }
+ if ((probe_global_pos.z & 1) != 0) {
+ offset.z = (offset.z + 1) & 1;
+ }
+ push_constant.probe_offset[0] = offset.x;
+ push_constant.probe_offset[1] = offset.y;
+ push_constant.probe_offset[2] = offset.z;
+ push_constant.occlusion_index = i;
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+
+ Vector3i groups = Vector3i(probe_size + 1, probe_size + 1, probe_size + 1) - offset; //if offset, it's one less probe per axis to compute
+ RD::get_singleton()->compute_list_dispatch(compute_list, groups.x, groups.y, groups.z);
+ }
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ }
+
+ RENDER_TIMESTAMP("SDFGI Store");
+
+ // store
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_STORE]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].sdf_store_uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);
+
+ RD::get_singleton()->compute_list_end();
+
+ //clear these textures, as they will have previous garbage on next draw
+ RD::get_singleton()->texture_clear(cascades[cascade].light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ RD::get_singleton()->texture_clear(cascades[cascade].light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ RD::get_singleton()->texture_clear(cascades[cascade].light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
+
+#if 0
+ Vector<uint8_t> data = RD::get_singleton()->texture_get_data(cascades[cascade].sdf, 0);
+ Ref<Image> img;
+ img.instance();
+ for (uint32_t i = 0; i < cascade_size; i++) {
+ Vector<uint8_t> subarr = data.subarray(128 * 128 * i, 128 * 128 * (i + 1) - 1);
+ img->create(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr);
+ img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png");
+ }
+
+ //finalize render and update sdf
+#endif
+
+#if 0
+ Vector<uint8_t> data = RD::get_singleton()->texture_get_data(render_albedo, 0);
+ Ref<Image> img;
+ img.instance();
+ for (uint32_t i = 0; i < cascade_size; i++) {
+ Vector<uint8_t> subarr = data.subarray(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2 - 1);
+ img->createcascade_size, cascade_size, false, Image::FORMAT_RGB565, subarr);
+ img->convert(Image::FORMAT_RGBA8);
+ img->save_png("res://cascade_" + itos(cascade) + "_" + itos(i) + ".png");
+ }
+
+ //finalize render and update sdf
+#endif
+
+ RENDER_TIMESTAMP("<SDFGI Update SDF");
+ RD::get_singleton()->draw_command_end_label();
+ }
+}
+
+void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) {
+ RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but...
+
+ RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lighs");
+
+ update_cascades();
+ ; //need cascades updated for this
+
+ SDFGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS];
+ uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS];
+
+ for (uint32_t i = 0; i < p_cascade_count; i++) {
+ ERR_CONTINUE(p_cascade_indices[i] >= cascades.size());
+
+ SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];
+
+ { //fill light buffer
+
+ AABB cascade_aabb;
+ cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cc.position)) * cc.cell_size;
+ cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cc.cell_size;
+
+ int idx = 0;
+
+ for (uint32_t j = 0; j < (uint32_t)p_positional_light_cull_result[i].size(); j++) {
+ if (idx == SDFGI::MAX_STATIC_LIGHTS) {
+ break;
+ }
+
+ RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.getornull(p_positional_light_cull_result[i][j]);
+ ERR_CONTINUE(!li);
+
+ uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light);
+ if (p_cascade_indices[i] > max_sdfgi_cascade) {
+ continue;
+ }
+
+ if (!cascade_aabb.intersects(li->aabb)) {
+ continue;
+ }
+
+ lights[idx].type = storage->light_get_type(li->light);
+
+ Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
+ if (lights[idx].type == RS::LIGHT_DIRECTIONAL) {
+ dir.y *= y_mult; //only makes sense for directional
+ dir.normalize();
+ }
+ lights[idx].direction[0] = dir.x;
+ lights[idx].direction[1] = dir.y;
+ lights[idx].direction[2] = dir.z;
+ Vector3 pos = li->transform.origin;
+ pos.y *= y_mult;
+ lights[idx].position[0] = pos.x;
+ lights[idx].position[1] = pos.y;
+ lights[idx].position[2] = pos.z;
+ Color color = storage->light_get_color(li->light);
+ color = color.to_linear();
+ lights[idx].color[0] = color.r;
+ lights[idx].color[1] = color.g;
+ lights[idx].color[2] = color.b;
+ lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY);
+ lights[idx].has_shadow = storage->light_has_shadow(li->light);
+ lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
+ lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
+ lights[idx].cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
+ lights[idx].inv_spot_attenuation = 1.0f / storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+
+ idx++;
+ }
+
+ if (idx > 0) {
+ RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights);
+ }
+
+ light_count[i] = idx;
+ }
+ }
+
+ /* Static Lights */
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.direct_light_pipeline[SDFGIShader::DIRECT_LIGHT_MODE_STATIC]);
+
+ SDFGIShader::DirectLightPushConstant dl_push_constant;
+
+ dl_push_constant.grid_size[0] = cascade_size;
+ dl_push_constant.grid_size[1] = cascade_size;
+ dl_push_constant.grid_size[2] = cascade_size;
+ dl_push_constant.max_cascades = cascades.size();
+ dl_push_constant.probe_axis_size = probe_axis_count;
+ dl_push_constant.bounce_feedback = 0.0; // this is static light, do not multibounce yet
+ dl_push_constant.y_mult = y_mult;
+ dl_push_constant.use_occlusion = uses_occlusion;
+
+ //all must be processed
+ dl_push_constant.process_offset = 0;
+ dl_push_constant.process_increment = 1;
+
+ for (uint32_t i = 0; i < p_cascade_count; i++) {
+ ERR_CONTINUE(p_cascade_indices[i] >= cascades.size());
+
+ SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];
+
+ dl_push_constant.light_count = light_count[i];
+ dl_push_constant.cascade = p_cascade_indices[i];
+
+ if (dl_push_constant.light_count > 0) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cc.sdf_direct_light_uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &dl_push_constant, sizeof(SDFGIShader::DirectLightPushConstant));
+ RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cc.solid_cell_dispatch_buffer, 0);
+ }
+ }
+
+ RD::get_singleton()->compute_list_end();
+
+ RD::get_singleton()->draw_command_end_label();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// GIProbeInstance
+
+void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
+ uint32_t data_version = storage->gi_probe_get_data_version(probe);
+
+ // (RE)CREATE IF NEEDED
+
+ if (last_probe_data_version != data_version) {
+ //need to re-create everything
+ if (texture.is_valid()) {
+ RD::get_singleton()->free(texture);
+ RD::get_singleton()->free(write_buffer);
+ mipmaps.clear();
+ }
+
+ for (int i = 0; i < dynamic_maps.size(); i++) {
+ RD::get_singleton()->free(dynamic_maps[i].texture);
+ RD::get_singleton()->free(dynamic_maps[i].depth);
+ }
+
+ dynamic_maps.clear();
+
+ Vector3i octree_size = storage->gi_probe_get_octree_size(probe);
+
+ if (octree_size != Vector3i()) {
+ //can create a 3D texture
+ Vector<int> levels = storage->gi_probe_get_level_counts(probe);
+
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ tf.width = octree_size.x;
+ tf.height = octree_size.y;
+ tf.depth = octree_size.z;
+ tf.texture_type = RD::TEXTURE_TYPE_3D;
+ tf.mipmaps = levels.size();
+
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+
+ texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, levels.size(), 0, 1);
+
+ {
+ int total_elements = 0;
+ for (int i = 0; i < levels.size(); i++) {
+ total_elements += levels[i];
+ }
+
+ write_buffer = RD::get_singleton()->storage_buffer_create(total_elements * 16);
+ }
+
+ for (int i = 0; i < levels.size(); i++) {
+ GIProbeInstance::Mipmap mipmap;
+ mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), texture, 0, i, RD::TEXTURE_SLICE_3D);
+ mipmap.level = levels.size() - i - 1;
+ mipmap.cell_offset = 0;
+ for (uint32_t j = 0; j < mipmap.level; j++) {
+ mipmap.cell_offset += levels[j];
+ }
+ mipmap.cell_count = levels[mipmap.level];
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(storage->gi_probe_get_octree_buffer(probe));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(storage->gi_probe_get_data_buffer(probe));
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 4;
+ u.ids.push_back(write_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 9;
+ u.ids.push_back(storage->gi_probe_get_sdf_texture(probe));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 10;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ {
+ Vector<RD::Uniform> copy_uniforms = uniforms;
+ if (i == 0) {
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 3;
+ u.ids.push_back(gi->gi_probe_lights_uniform);
+ copy_uniforms.push_back(u);
+ }
+
+ mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT], 0);
+
+ copy_uniforms = uniforms; //restore
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 5;
+ u.ids.push_back(texture);
+ copy_uniforms.push_back(u);
+ }
+ mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0);
+ } else {
+ mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP], 0);
+ }
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 5;
+ u.ids.push_back(mipmap.texture);
+ uniforms.push_back(u);
+ }
+
+ mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE], 0);
+
+ mipmaps.push_back(mipmap);
+ }
+
+ {
+ uint32_t dynamic_map_size = MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
+ uint32_t oversample = nearest_power_of_2_templated(4);
+ int mipmap_index = 0;
+
+ while (mipmap_index < mipmaps.size()) {
+ GIProbeInstance::DynamicMap dmap;
+
+ if (oversample > 0) {
+ dmap.size = dynamic_map_size * (1 << oversample);
+ dmap.mipmap = -1;
+ oversample--;
+ } else {
+ dmap.size = dynamic_map_size >> mipmap_index;
+ dmap.mipmap = mipmap_index;
+ mipmap_index++;
+ }
+
+ RD::TextureFormat dtf;
+ dtf.width = dmap.size;
+ dtf.height = dmap.size;
+ dtf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
+
+ if (dynamic_maps.size() == 0) {
+ dtf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ }
+ dmap.texture = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+
+ if (dynamic_maps.size() == 0) {
+ //render depth for first one
+ dtf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
+ dtf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ dmap.fb_depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ }
+
+ //just use depth as-is
+ dtf.format = RD::DATA_FORMAT_R32_SFLOAT;
+ dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+
+ dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+
+ if (dynamic_maps.size() == 0) {
+ dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ dmap.normal = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+ dmap.orm = RD::get_singleton()->texture_create(dtf, RD::TextureView());
+
+ Vector<RID> fb;
+ fb.push_back(dmap.albedo);
+ fb.push_back(dmap.normal);
+ fb.push_back(dmap.orm);
+ fb.push_back(dmap.texture); //emission
+ fb.push_back(dmap.depth);
+ fb.push_back(dmap.fb_depth);
+
+ dmap.fb = RD::get_singleton()->framebuffer_create(fb);
+
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 3;
+ u.ids.push_back(gi->gi_probe_lights_uniform);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 5;
+ u.ids.push_back(dmap.albedo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 6;
+ u.ids.push_back(dmap.normal);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 7;
+ u.ids.push_back(dmap.orm);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 8;
+ u.ids.push_back(dmap.fb_depth);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 9;
+ u.ids.push_back(storage->gi_probe_get_sdf_texture(probe));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 10;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 11;
+ u.ids.push_back(dmap.texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 12;
+ u.ids.push_back(dmap.depth);
+ uniforms.push_back(u);
+ }
+
+ dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0);
+ }
+ } else {
+ bool plot = dmap.mipmap >= 0;
+ bool write = dmap.mipmap < (mipmaps.size() - 1);
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 5;
+ u.ids.push_back(dynamic_maps[dynamic_maps.size() - 1].texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 6;
+ u.ids.push_back(dynamic_maps[dynamic_maps.size() - 1].depth);
+ uniforms.push_back(u);
+ }
+
+ if (write) {
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 7;
+ u.ids.push_back(dmap.texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 8;
+ u.ids.push_back(dmap.depth);
+ uniforms.push_back(u);
+ }
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 9;
+ u.ids.push_back(storage->gi_probe_get_sdf_texture(probe));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 10;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ if (plot) {
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 11;
+ u.ids.push_back(mipmaps[dmap.mipmap].texture);
+ uniforms.push_back(u);
+ }
+ }
+
+ dmap.uniform_set = RD::get_singleton()->uniform_set_create(
+ uniforms,
+ gi->giprobe_lighting_shader_version_shaders[(write && plot) ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)],
+ 0);
+ }
+
+ dynamic_maps.push_back(dmap);
+ }
+ }
+ }
+
+ last_probe_data_version = data_version;
+ p_update_light_instances = true; //just in case
+
+ p_scene_render->_base_uniforms_changed();
+ }
+
+ // UDPDATE TIME
+
+ if (has_dynamic_object_data) {
+ //if it has dynamic object data, it needs to be cleared
+ RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, mipmaps.size(), 0, 1);
+ }
+
+ uint32_t light_count = 0;
+
+ if (p_update_light_instances || p_dynamic_objects.size() > 0) {
+ light_count = MIN(gi->gi_probe_max_lights, (uint32_t)p_light_instances.size());
+
+ {
+ Transform to_cell = storage->gi_probe_get_to_cell_xform(probe);
+ Transform to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse();
+ //update lights
+
+ for (uint32_t i = 0; i < light_count; i++) {
+ GIProbeLight &l = gi->gi_probe_lights[i];
+ RID light_instance = p_light_instances[i];
+ RID light = p_scene_render->light_instance_get_base_light(light_instance);
+
+ l.type = storage->light_get_type(light);
+ if (l.type == RS::LIGHT_DIRECTIONAL && storage->light_directional_is_sky_only(light)) {
+ light_count--;
+ continue;
+ }
+
+ l.attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
+ l.energy = storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
+ l.radius = to_cell.basis.xform(Vector3(storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();
+ Color color = storage->light_get_color(light).to_linear();
+ l.color[0] = color.r;
+ l.color[1] = color.g;
+ l.color[2] = color.b;
+
+ l.cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));
+ l.inv_spot_attenuation = 1.0f / storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+
+ Transform xform = p_scene_render->light_instance_get_base_transform(light_instance);
+
+ Vector3 pos = to_probe_xform.xform(xform.origin);
+ Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_axis(2)).normalized();
+
+ l.position[0] = pos.x;
+ l.position[1] = pos.y;
+ l.position[2] = pos.z;
+
+ l.direction[0] = dir.x;
+ l.direction[1] = dir.y;
+ l.direction[2] = dir.z;
+
+ l.has_shadow = storage->light_has_shadow(light);
+ }
+
+ RD::get_singleton()->buffer_update(gi->gi_probe_lights_uniform, 0, sizeof(GIProbeLight) * light_count, gi->gi_probe_lights);
+ }
+ }
+
+ if (has_dynamic_object_data || p_update_light_instances || p_dynamic_objects.size()) {
+ // PROCESS MIPMAPS
+ if (mipmaps.size()) {
+ //can update mipmaps
+
+ Vector3i probe_size = storage->gi_probe_get_octree_size(probe);
+
+ GIProbePushConstant push_constant;
+
+ push_constant.limits[0] = probe_size.x;
+ push_constant.limits[1] = probe_size.y;
+ push_constant.limits[2] = probe_size.z;
+ push_constant.stack_size = mipmaps.size();
+ push_constant.emission_scale = 1.0;
+ push_constant.propagation = storage->gi_probe_get_propagation(probe);
+ push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe);
+ push_constant.light_count = light_count;
+ push_constant.aniso_strength = 0;
+
+ /* print_line("probe update to version " + itos(last_probe_version));
+ print_line("propagation " + rtos(push_constant.propagation));
+ print_line("dynrange " + rtos(push_constant.dynamic_range));
+ */
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ int passes;
+ if (p_update_light_instances) {
+ passes = storage->gi_probe_is_using_two_bounces(probe) ? 2 : 1;
+ } else {
+ passes = 1; //only re-blitting is necessary
+ }
+ int wg_size = 64;
+ int wg_limit_x = RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X);
+
+ for (int pass = 0; pass < passes; pass++) {
+ if (p_update_light_instances) {
+ for (int i = 0; i < mipmaps.size(); i++) {
+ if (i == 0) {
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[pass == 0 ? GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT : GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]);
+ } else if (i == 1) {
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP]);
+ }
+
+ if (pass == 1 || i > 0) {
+ RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done
+ }
+ if (pass == 0 || i > 0) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].uniform_set, 0);
+ } else {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].second_bounce_uniform_set, 0);
+ }
+
+ push_constant.cell_offset = mipmaps[i].cell_offset;
+ push_constant.cell_count = mipmaps[i].cell_count;
+
+ int wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1;
+ while (wg_todo) {
+ int wg_count = MIN(wg_todo, wg_limit_x);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);
+ wg_todo -= wg_count;
+ push_constant.cell_offset += wg_count * wg_size;
+ }
+ }
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done
+ }
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE]);
+
+ for (int i = 0; i < mipmaps.size(); i++) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].write_uniform_set, 0);
+
+ push_constant.cell_offset = mipmaps[i].cell_offset;
+ push_constant.cell_count = mipmaps[i].cell_count;
+
+ int wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1;
+ while (wg_todo) {
+ int wg_count = MIN(wg_todo, wg_limit_x);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);
+ wg_todo -= wg_count;
+ push_constant.cell_offset += wg_count * wg_size;
+ }
+ }
+ }
+
+ RD::get_singleton()->compute_list_end();
+ }
+ }
+
+ has_dynamic_object_data = false; //clear until dynamic object data is used again
+
+ if (p_dynamic_objects.size() && dynamic_maps.size()) {
+ Vector3i octree_size = storage->gi_probe_get_octree_size(probe);
+ int multiplier = dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
+
+ Transform oversample_scale;
+ oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier));
+
+ Transform to_cell = oversample_scale * storage->gi_probe_get_to_cell_xform(probe);
+ Transform to_world_xform = transform * to_cell.affine_inverse();
+ Transform to_probe_xform = to_world_xform.affine_inverse();
+
+ AABB probe_aabb(Vector3(), octree_size);
+
+ //this could probably be better parallelized in compute..
+ for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {
+ RendererSceneRender::GeometryInstance *instance = p_dynamic_objects[i];
+
+ //transform aabb to giprobe
+ AABB aabb = (to_probe_xform * p_scene_render->geometry_instance_get_transform(instance)).xform(p_scene_render->geometry_instance_get_aabb(instance));
+
+ //this needs to wrap to grid resolution to avoid jitter
+ //also extend margin a bit just in case
+ Vector3i begin = aabb.position - Vector3i(1, 1, 1);
+ Vector3i end = aabb.position + aabb.size + Vector3i(1, 1, 1);
+
+ for (int j = 0; j < 3; j++) {
+ if ((end[j] - begin[j]) & 1) {
+ end[j]++; //for half extents split, it needs to be even
+ }
+ begin[j] = MAX(begin[j], 0);
+ end[j] = MIN(end[j], octree_size[j] * multiplier);
+ }
+
+ //aabb = aabb.intersection(probe_aabb); //intersect
+ aabb.position = begin;
+ aabb.size = end - begin;
+
+ //print_line("aabb: " + aabb);
+
+ for (int j = 0; j < 6; j++) {
+ //if (j != 0 && j != 3) {
+ // continue;
+ //}
+ static const Vector3 render_z[6] = {
+ Vector3(1, 0, 0),
+ Vector3(0, 1, 0),
+ Vector3(0, 0, 1),
+ Vector3(-1, 0, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, -1),
+ };
+ static const Vector3 render_up[6] = {
+ Vector3(0, 1, 0),
+ Vector3(0, 0, 1),
+ Vector3(0, 1, 0),
+ Vector3(0, 1, 0),
+ Vector3(0, 0, 1),
+ Vector3(0, 1, 0),
+ };
+
+ Vector3 render_dir = render_z[j];
+ Vector3 up_dir = render_up[j];
+
+ Vector3 center = aabb.position + aabb.size * 0.5;
+ Transform xform;
+ xform.set_look_at(center - aabb.size * 0.5 * render_dir, center, up_dir);
+
+ Vector3 x_dir = xform.basis.get_axis(0).abs();
+ int x_axis = int(Vector3(0, 1, 2).dot(x_dir));
+ Vector3 y_dir = xform.basis.get_axis(1).abs();
+ int y_axis = int(Vector3(0, 1, 2).dot(y_dir));
+ Vector3 z_dir = -xform.basis.get_axis(2);
+ int z_axis = int(Vector3(0, 1, 2).dot(z_dir.abs()));
+
+ Rect2i rect(aabb.position[x_axis], aabb.position[y_axis], aabb.size[x_axis], aabb.size[y_axis]);
+ bool x_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_axis(0)) < 0);
+ bool y_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_axis(1)) < 0);
+ bool z_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_axis(2)) > 0);
+
+ CameraMatrix cm;
+ cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]);
+
+ if (p_scene_render->cull_argument.size() == 0) {
+ p_scene_render->cull_argument.push_back(nullptr);
+ }
+ p_scene_render->cull_argument[0] = instance;
+
+ p_scene_render->_render_material(to_world_xform * xform, cm, true, p_scene_render->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size));
+
+ GIProbeDynamicPushConstant push_constant;
+ zeromem(&push_constant, sizeof(GIProbeDynamicPushConstant));
+ push_constant.limits[0] = octree_size.x;
+ push_constant.limits[1] = octree_size.y;
+ push_constant.limits[2] = octree_size.z;
+ push_constant.light_count = p_light_instances.size();
+ push_constant.x_dir[0] = x_dir[0];
+ push_constant.x_dir[1] = x_dir[1];
+ push_constant.x_dir[2] = x_dir[2];
+ push_constant.y_dir[0] = y_dir[0];
+ push_constant.y_dir[1] = y_dir[1];
+ push_constant.y_dir[2] = y_dir[2];
+ push_constant.z_dir[0] = z_dir[0];
+ push_constant.z_dir[1] = z_dir[1];
+ push_constant.z_dir[2] = z_dir[2];
+ push_constant.z_base = xform.origin[z_axis];
+ push_constant.z_sign = (z_flip ? -1.0 : 1.0);
+ push_constant.pos_multiplier = float(1.0) / multiplier;
+ push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe);
+ push_constant.flip_x = x_flip;
+ push_constant.flip_y = y_flip;
+ push_constant.rect_pos[0] = rect.position[0];
+ push_constant.rect_pos[1] = rect.position[1];
+ push_constant.rect_size[0] = rect.size[0];
+ push_constant.rect_size[1] = rect.size[1];
+ push_constant.prev_rect_ofs[0] = 0;
+ push_constant.prev_rect_ofs[1] = 0;
+ push_constant.prev_rect_size[0] = 0;
+ push_constant.prev_rect_size[1] = 0;
+ push_constant.on_mipmap = false;
+ push_constant.propagation = storage->gi_probe_get_propagation(probe);
+ push_constant.pad[0] = 0;
+ push_constant.pad[1] = 0;
+ push_constant.pad[2] = 0;
+
+ //process lighting
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[0].uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbeDynamicPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1);
+ //print_line("rect: " + itos(i) + ": " + rect);
+
+ for (int k = 1; k < dynamic_maps.size(); k++) {
+ // enlarge the rect if needed so all pixels fit when downscaled,
+ // this ensures downsampling is smooth and optimal because no pixels are left behind
+
+ //x
+ if (rect.position.x & 1) {
+ rect.size.x++;
+ push_constant.prev_rect_ofs[0] = 1; //this is used to ensure reading is also optimal
+ } else {
+ push_constant.prev_rect_ofs[0] = 0;
+ }
+ if (rect.size.x & 1) {
+ rect.size.x++;
+ }
+
+ rect.position.x >>= 1;
+ rect.size.x = MAX(1, rect.size.x >> 1);
+
+ //y
+ if (rect.position.y & 1) {
+ rect.size.y++;
+ push_constant.prev_rect_ofs[1] = 1;
+ } else {
+ push_constant.prev_rect_ofs[1] = 0;
+ }
+ if (rect.size.y & 1) {
+ rect.size.y++;
+ }
+
+ rect.position.y >>= 1;
+ rect.size.y = MAX(1, rect.size.y >> 1);
+
+ //shrink limits to ensure plot does not go outside map
+ if (dynamic_maps[k].mipmap > 0) {
+ for (int l = 0; l < 3; l++) {
+ push_constant.limits[l] = MAX(1, push_constant.limits[l] >> 1);
+ }
+ }
+
+ //print_line("rect: " + itos(i) + ": " + rect);
+ push_constant.rect_pos[0] = rect.position[0];
+ push_constant.rect_pos[1] = rect.position[1];
+ push_constant.prev_rect_size[0] = push_constant.rect_size[0];
+ push_constant.prev_rect_size[1] = push_constant.rect_size[1];
+ push_constant.rect_size[0] = rect.size[0];
+ push_constant.rect_size[1] = rect.size[1];
+ push_constant.on_mipmap = dynamic_maps[k].mipmap > 0;
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ if (dynamic_maps[k].mipmap < 0) {
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE]);
+ } else if (k < dynamic_maps.size() - 1) {
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT]);
+ } else {
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT]);
+ }
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[k].uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbeDynamicPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1);
+ }
+
+ RD::get_singleton()->compute_list_end();
+ }
+ }
+
+ has_dynamic_object_data = true; //clear until dynamic object data is used again
+ }
+
+ last_probe_version = storage->gi_probe_get_version(probe);
+}
+
+void RendererSceneGIRD::GIProbeInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
+ if (mipmaps.size() == 0) {
+ return;
+ }
+
+ CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(storage->gi_probe_get_to_cell_xform(probe).affine_inverse());
+
+ int level = 0;
+ Vector3i octree_size = storage->gi_probe_get_octree_size(probe);
+
+ GIProbeDebugPushConstant push_constant;
+ push_constant.alpha = p_alpha;
+ push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe);
+ push_constant.cell_offset = mipmaps[level].cell_offset;
+ push_constant.level = level;
+
+ push_constant.bounds[0] = octree_size.x >> level;
+ push_constant.bounds[1] = octree_size.y >> level;
+ push_constant.bounds[2] = octree_size.z >> level;
+ push_constant.pad = 0;
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ push_constant.projection[i * 4 + j] = cam_transform.matrix[i][j];
+ }
+ }
+
+ if (gi->giprobe_debug_uniform_set.is_valid()) {
+ RD::get_singleton()->free(gi->giprobe_debug_uniform_set);
+ }
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(storage->gi_probe_get_data_buffer(probe));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 3;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ int cell_count;
+ if (!p_emission && p_lighting && has_dynamic_object_data) {
+ cell_count = push_constant.bounds[0] * push_constant.bounds[1] * push_constant.bounds[2];
+ } else {
+ cell_count = mipmaps[level].cell_count;
+ }
+
+ gi->giprobe_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_debug_shader_version_shaders[0], 0);
+
+ int giprobe_debug_pipeline = GI_PROBE_DEBUG_COLOR;
+ if (p_emission) {
+ giprobe_debug_pipeline = GI_PROBE_DEBUG_EMISSION;
+ } else if (p_lighting) {
+ giprobe_debug_pipeline = has_dynamic_object_data ? GI_PROBE_DEBUG_LIGHT_FULL : GI_PROBE_DEBUG_LIGHT;
+ }
+ RD::get_singleton()->draw_list_bind_render_pipeline(
+ p_draw_list,
+ gi->giprobe_debug_shader_version_pipelines[giprobe_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, gi->giprobe_debug_uniform_set, 0);
+ RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(GIProbeDebugPushConstant));
+ RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// GIRD
+
+RendererSceneGIRD::RendererSceneGIRD() {
+ sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count")), 0, int32_t(RS::ENV_SDFGI_RAY_COUNT_MAX - 1)));
+ sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1)));
+ sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1)));
+}
+
+RendererSceneGIRD::~RendererSceneGIRD() {
+}
+
+void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky) {
+ storage = p_storage;
+
+ /* GI */
+
+ {
+ //kinda complicated to compute the amount of slots, we try to use as many as we can
+
+ gi_probe_max_lights = 32;
+
+ gi_probe_lights = memnew_arr(GIProbeLight, gi_probe_max_lights);
+ gi_probe_lights_uniform = RD::get_singleton()->uniform_buffer_create(gi_probe_max_lights * sizeof(GIProbeLight));
+ gi_probe_quality = RS::GIProbeQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/gi_probes/quality")), 0, 1));
+
+ String defines = "\n#define MAX_LIGHTS " + itos(gi_probe_max_lights) + "\n";
+
+ Vector<String> versions;
+ versions.push_back("\n#define MODE_COMPUTE_LIGHT\n");
+ versions.push_back("\n#define MODE_SECOND_BOUNCE\n");
+ versions.push_back("\n#define MODE_UPDATE_MIPMAPS\n");
+ versions.push_back("\n#define MODE_WRITE_TEXTURE\n");
+ versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_LIGHTING\n");
+ versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_WRITE\n");
+ versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n");
+ versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n#define MODE_DYNAMIC_SHRINK_WRITE\n");
+
+ giprobe_shader.initialize(versions, defines);
+ giprobe_lighting_shader_version = giprobe_shader.version_create();
+ for (int i = 0; i < GI_PROBE_SHADER_VERSION_MAX; i++) {
+ giprobe_lighting_shader_version_shaders[i] = giprobe_shader.version_get_shader(giprobe_lighting_shader_version, i);
+ giprobe_lighting_shader_version_pipelines[i] = RD::get_singleton()->compute_pipeline_create(giprobe_lighting_shader_version_shaders[i]);
+ }
+ }
+
+ {
+ String defines;
+ Vector<String> versions;
+ versions.push_back("\n#define MODE_DEBUG_COLOR\n");
+ versions.push_back("\n#define MODE_DEBUG_LIGHT\n");
+ versions.push_back("\n#define MODE_DEBUG_EMISSION\n");
+ versions.push_back("\n#define MODE_DEBUG_LIGHT\n#define MODE_DEBUG_LIGHT_FULL\n");
+
+ giprobe_debug_shader.initialize(versions, defines);
+ giprobe_debug_shader_version = giprobe_debug_shader.version_create();
+ for (int i = 0; i < GI_PROBE_DEBUG_MAX; i++) {
+ giprobe_debug_shader_version_shaders[i] = giprobe_debug_shader.version_get_shader(giprobe_debug_shader_version, i);
+
+ RD::PipelineRasterizationState rs;
+ rs.cull_mode = RD::POLYGON_CULL_FRONT;
+ RD::PipelineDepthStencilState ds;
+ ds.enable_depth_test = true;
+ ds.enable_depth_write = true;
+ ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
+
+ giprobe_debug_shader_version_pipelines[i].setup(giprobe_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
+ }
+ }
+
+ /* SDGFI */
+
+ {
+ Vector<String> preprocess_modes;
+ preprocess_modes.push_back("\n#define MODE_SCROLL\n");
+ preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n");
+ preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n");
+ preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n");
+ preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n");
+ preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n");
+ preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n");
+ preprocess_modes.push_back("\n#define MODE_OCCLUSION\n");
+ preprocess_modes.push_back("\n#define MODE_STORE\n");
+ String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n";
+ sdfgi_shader.preprocess.initialize(preprocess_modes, defines);
+ sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create();
+ for (int i = 0; i < SDFGIShader::PRE_PROCESS_MAX; i++) {
+ sdfgi_shader.preprocess_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i));
+ }
+ }
+
+ {
+ //calculate tables
+ String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+
+ Vector<String> direct_light_modes;
+ direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n");
+ direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n");
+ sdfgi_shader.direct_light.initialize(direct_light_modes, defines);
+ sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create();
+ for (int i = 0; i < SDFGIShader::DIRECT_LIGHT_MODE_MAX; i++) {
+ sdfgi_shader.direct_light_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i));
+ }
+ }
+
+ {
+ //calculate tables
+ String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+ defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n";
+ if (p_sky->sky_use_cubemap_array) {
+ defines += "\n#define USE_CUBEMAP_ARRAY\n";
+ }
+
+ Vector<String> integrate_modes;
+ integrate_modes.push_back("\n#define MODE_PROCESS\n");
+ integrate_modes.push_back("\n#define MODE_STORE\n");
+ integrate_modes.push_back("\n#define MODE_SCROLL\n");
+ integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n");
+ sdfgi_shader.integrate.initialize(integrate_modes, defines);
+ sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create();
+
+ for (int i = 0; i < SDFGIShader::INTEGRATE_MODE_MAX; i++) {
+ sdfgi_shader.integrate_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i));
+ }
+
+ {
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 1;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1);
+ }
+ }
+
+ //GK
+ {
+ //calculate tables
+ String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+ Vector<String> gi_modes;
+ gi_modes.push_back("\n#define USE_GIPROBES\n");
+ gi_modes.push_back("\n#define USE_SDFGI\n");
+ gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_GIPROBES\n");
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_GIPROBES\n");
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n");
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_GIPROBES\n");
+
+ shader.initialize(gi_modes, defines);
+ shader_version = shader.version_create();
+ for (int i = 0; i < MODE_MAX; i++) {
+ pipelines[i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i));
+ }
+
+ sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIData));
+ }
+ {
+ String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+ Vector<String> debug_modes;
+ debug_modes.push_back("");
+ sdfgi_shader.debug.initialize(debug_modes, defines);
+ sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create();
+ sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0);
+ sdfgi_shader.debug_pipeline = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.debug_shader_version);
+ }
+ {
+ String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
+
+ Vector<String> versions;
+ versions.push_back("\n#define MODE_PROBES\n");
+ versions.push_back("\n#define MODE_VISIBILITY\n");
+
+ sdfgi_shader.debug_probes.initialize(versions, defines);
+ sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();
+
+ {
+ RD::PipelineRasterizationState rs;
+ rs.cull_mode = RD::POLYGON_CULL_DISABLED;
+ RD::PipelineDepthStencilState ds;
+ ds.enable_depth_test = true;
+ ds.enable_depth_write = true;
+ ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
+ for (int i = 0; i < SDFGIShader::PROBE_DEBUG_MAX; i++) {
+ RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);
+ sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
+ }
+ }
+ }
+ default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GIProbeData) * MAX_GIPROBES);
+}
+
+void RendererSceneGIRD::free() {
+ RD::get_singleton()->free(default_giprobe_buffer);
+ RD::get_singleton()->free(gi_probe_lights_uniform);
+ RD::get_singleton()->free(sdfgi_ubo);
+
+ giprobe_debug_shader.version_free(giprobe_debug_shader_version);
+ giprobe_shader.version_free(giprobe_lighting_shader_version);
+ shader.version_free(shader_version);
+ sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);
+ sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);
+ sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader);
+ sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);
+ sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);
+
+ memdelete_arr(gi_probe_lights);
+}
+
+RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) {
+ SDFGI *sdfgi = memnew(SDFGI);
+
+ sdfgi->create(p_env, p_world_position, p_requested_history_size, this);
+
+ return sdfgi;
+}
+
+void RendererSceneGIRD::setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used, RendererSceneRenderRD *p_scene_render) {
+ r_gi_probes_used = 0;
+
+ // feels a little dirty to use our container this way but....
+ RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND(rb == nullptr);
+
+ RID gi_probe_buffer = p_scene_render->render_buffers_get_gi_probe_buffer(p_render_buffers);
+
+ RD::get_singleton()->draw_command_begin_label("GIProbes Setup");
+
+ GIProbeData gi_probe_data[MAX_GIPROBES];
+
+ bool giprobes_changed = false;
+
+ Transform to_camera;
+ to_camera.origin = p_transform.origin; //only translation, make local
+
+ for (int i = 0; i < MAX_GIPROBES; i++) {
+ RID texture;
+ if (i < (int)p_gi_probes.size()) {
+ GIProbeInstance *gipi = get_probe_instance(p_gi_probes[i]);
+
+ if (gipi) {
+ texture = gipi->texture;
+ GIProbeData &gipd = gi_probe_data[i];
+
+ RID base_probe = gipi->probe;
+
+ Transform to_cell = storage->gi_probe_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera;
+
+ gipd.xform[0] = to_cell.basis.elements[0][0];
+ gipd.xform[1] = to_cell.basis.elements[1][0];
+ gipd.xform[2] = to_cell.basis.elements[2][0];
+ gipd.xform[3] = 0;
+ gipd.xform[4] = to_cell.basis.elements[0][1];
+ gipd.xform[5] = to_cell.basis.elements[1][1];
+ gipd.xform[6] = to_cell.basis.elements[2][1];
+ gipd.xform[7] = 0;
+ gipd.xform[8] = to_cell.basis.elements[0][2];
+ gipd.xform[9] = to_cell.basis.elements[1][2];
+ gipd.xform[10] = to_cell.basis.elements[2][2];
+ gipd.xform[11] = 0;
+ gipd.xform[12] = to_cell.origin.x;
+ gipd.xform[13] = to_cell.origin.y;
+ gipd.xform[14] = to_cell.origin.z;
+ gipd.xform[15] = 1;
+
+ Vector3 bounds = storage->gi_probe_get_octree_size(base_probe);
+
+ gipd.bounds[0] = bounds.x;
+ gipd.bounds[1] = bounds.y;
+ gipd.bounds[2] = bounds.z;
+
+ gipd.dynamic_range = storage->gi_probe_get_dynamic_range(base_probe) * storage->gi_probe_get_energy(base_probe);
+ gipd.bias = storage->gi_probe_get_bias(base_probe);
+ gipd.normal_bias = storage->gi_probe_get_normal_bias(base_probe);
+ gipd.blend_ambient = !storage->gi_probe_is_interior(base_probe);
+ gipd.anisotropy_strength = 0;
+ gipd.ao = storage->gi_probe_get_ao(base_probe);
+ gipd.ao_size = Math::pow(storage->gi_probe_get_ao_size(base_probe), 4.0f);
+ gipd.mipmaps = gipi->mipmaps.size();
+ }
+
+ r_gi_probes_used++;
+ }
+
+ if (texture == RID()) {
+ texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ }
+
+ if (texture != rb->gi.giprobe_textures[i]) {
+ giprobes_changed = true;
+ rb->gi.giprobe_textures[i] = texture;
+ }
+ }
+
+ if (giprobes_changed) {
+ if (RD::get_singleton()->uniform_set_is_valid(rb->gi_uniform_set)) {
+ RD::get_singleton()->free(rb->gi_uniform_set);
+ }
+ rb->gi_uniform_set = RID();
+ if (rb->volumetric_fog) {
+ if (RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
+ RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
+ RD::get_singleton()->free(rb->volumetric_fog->uniform_set2);
+ }
+ rb->volumetric_fog->uniform_set = RID();
+ rb->volumetric_fog->uniform_set2 = RID();
+ }
+ }
+
+ if (p_gi_probes.size() > 0) {
+ RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GIProbeData) * MIN((uint64_t)MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, RD::BARRIER_MASK_COMPUTE);
+ }
+
+ RD::get_singleton()->draw_command_end_label();
+}
+
+void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, RendererSceneRenderRD *p_scene_render) {
+ RD::get_singleton()->draw_command_begin_label("GI Render");
+
+ RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND(rb == nullptr);
+ RendererSceneEnvironmentRD *env = p_scene_render->environment_owner.getornull(p_environment);
+
+ if (rb->ambient_buffer.is_null() || rb->using_half_size_gi != half_resolution) {
+ if (rb->ambient_buffer.is_valid()) {
+ RD::get_singleton()->free(rb->ambient_buffer);
+ RD::get_singleton()->free(rb->reflection_buffer);
+ }
+
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.width = rb->width;
+ tf.height = rb->height;
+ if (half_resolution) {
+ tf.width >>= 1;
+ tf.height >>= 1;
+ }
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->using_half_size_gi = half_resolution;
+
+ p_scene_render->_render_buffers_uniform_set_changed(p_render_buffers);
+ }
+
+ PushConstant push_constant;
+
+ push_constant.screen_size[0] = rb->width;
+ push_constant.screen_size[1] = rb->height;
+ push_constant.z_near = p_projection.get_z_near();
+ push_constant.z_far = p_projection.get_z_far();
+ push_constant.orthogonal = p_projection.is_orthogonal();
+ push_constant.proj_info[0] = -2.0f / (rb->width * p_projection.matrix[0][0]);
+ push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]);
+ push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
+ push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
+ push_constant.max_giprobes = MIN((uint64_t)MAX_GIPROBES, p_gi_probes.size());
+ push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH;
+
+ bool use_sdfgi = rb->sdfgi != nullptr;
+ bool use_giprobes = push_constant.max_giprobes > 0;
+
+ if (env) {
+ push_constant.ao_color[0] = env->ao_color.r;
+ push_constant.ao_color[1] = env->ao_color.g;
+ push_constant.ao_color[2] = env->ao_color.b;
+ } else {
+ push_constant.ao_color[0] = 0;
+ push_constant.ao_color[1] = 0;
+ push_constant.ao_color[2] = 0;
+ }
+
+ push_constant.cam_rotation[0] = p_transform.basis[0][0];
+ push_constant.cam_rotation[1] = p_transform.basis[1][0];
+ push_constant.cam_rotation[2] = p_transform.basis[2][0];
+ push_constant.cam_rotation[3] = 0;
+ push_constant.cam_rotation[4] = p_transform.basis[0][1];
+ push_constant.cam_rotation[5] = p_transform.basis[1][1];
+ push_constant.cam_rotation[6] = p_transform.basis[2][1];
+ push_constant.cam_rotation[7] = 0;
+ push_constant.cam_rotation[8] = p_transform.basis[0][2];
+ push_constant.cam_rotation[9] = p_transform.basis[1][2];
+ push_constant.cam_rotation[10] = p_transform.basis[2][2];
+ push_constant.cam_rotation[11] = 0;
+
+ if (rb->gi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->gi_uniform_set)) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
+ u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
+ u.ids.push_back(rb->sdfgi->cascades[j].light_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
+ u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_0_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
+ u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_1_tex);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 5;
+ if (rb->sdfgi) {
+ u.ids.push_back(rb->sdfgi->occlusion_texture);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 6;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 7;
+ u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 9;
+ u.ids.push_back(rb->ambient_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 10;
+ u.ids.push_back(rb->reflection_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 11;
+ if (rb->sdfgi) {
+ u.ids.push_back(rb->sdfgi->lightprobe_texture);
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 12;
+ u.ids.push_back(rb->depth_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 13;
+ u.ids.push_back(p_normal_roughness_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 14;
+ RID buffer = p_gi_probe_buffer.is_valid() ? p_gi_probe_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.ids.push_back(buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 15;
+ u.ids.push_back(sdfgi_ubo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 16;
+ u.ids.push_back(rb->gi.giprobe_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 17;
+ for (int i = 0; i < MAX_GIPROBES; i++) {
+ u.ids.push_back(rb->gi.giprobe_textures[i]);
+ }
+ uniforms.push_back(u);
+ }
+
+ rb->gi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0);
+ }
+
+ Mode mode;
+
+ if (rb->using_half_size_gi) {
+ mode = (use_sdfgi && use_giprobes) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_GIPROBE);
+ } else {
+ mode = (use_sdfgi && use_giprobes) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_GIPROBE);
+ }
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi_uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+
+ if (rb->using_half_size_gi) {
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width >> 1, rb->height >> 1, 1);
+ } else {
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1);
+ }
+ //do barrier later to allow oeverlap
+ //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //no barriers, let other compute, raster and transfer happen at the same time
+ RD::get_singleton()->draw_command_end_label();
+}
+
+RID RendererSceneGIRD::gi_probe_instance_create(RID p_base) {
+ GIProbeInstance gi_probe;
+ gi_probe.gi = this;
+ gi_probe.storage = storage;
+ gi_probe.probe = p_base;
+ RID rid = gi_probe_instance_owner.make_rid(gi_probe);
+ return rid;
+}
+
+void RendererSceneGIRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {
+ GIProbeInstance *gi_probe = get_probe_instance(p_probe);
+ ERR_FAIL_COND(!gi_probe);
+
+ gi_probe->transform = p_xform;
+}
+
+bool RendererSceneGIRD::gi_probe_needs_update(RID p_probe) const {
+ GIProbeInstance *gi_probe = get_probe_instance(p_probe);
+ ERR_FAIL_COND_V(!gi_probe, false);
+
+ return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
+}
+
+void RendererSceneGIRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
+ GIProbeInstance *gi_probe = get_probe_instance(p_probe);
+ ERR_FAIL_COND(!gi_probe);
+
+ gi_probe->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render);
+}
+
+void RendererSceneGIRD::debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
+ GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_gi_probe);
+ ERR_FAIL_COND(!gi_probe);
+
+ gi_probe->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha);
+}
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
new file mode 100644
index 0000000000..c0f3318538
--- /dev/null
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
@@ -0,0 +1,668 @@
+/*************************************************************************/
+/* renderer_scene_gi_rd.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RENDERING_SERVER_SCENE_GI_RD_H
+#define RENDERING_SERVER_SCENE_GI_RD_H
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/giprobe.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/giprobe_debug.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
+#include "servers/rendering/rendering_device.h"
+
+// Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
+class RendererSceneRenderRD;
+
+class RendererSceneGIRD {
+private:
+ RendererStorageRD *storage;
+
+ /* GIPROBE INSTANCE */
+
+ struct GIProbeLight {
+ uint32_t type;
+ float energy;
+ float radius;
+ float attenuation;
+
+ float color[3];
+ float cos_spot_angle;
+
+ float position[3];
+ float inv_spot_attenuation;
+
+ float direction[3];
+ uint32_t has_shadow;
+ };
+
+ struct GIProbePushConstant {
+ int32_t limits[3];
+ uint32_t stack_size;
+
+ float emission_scale;
+ float propagation;
+ float dynamic_range;
+ uint32_t light_count;
+
+ uint32_t cell_offset;
+ uint32_t cell_count;
+ float aniso_strength;
+ uint32_t pad;
+ };
+
+ struct GIProbeDynamicPushConstant {
+ int32_t limits[3];
+ uint32_t light_count;
+ int32_t x_dir[3];
+ float z_base;
+ int32_t y_dir[3];
+ float z_sign;
+ int32_t z_dir[3];
+ float pos_multiplier;
+ uint32_t rect_pos[2];
+ uint32_t rect_size[2];
+ uint32_t prev_rect_ofs[2];
+ uint32_t prev_rect_size[2];
+ uint32_t flip_x;
+ uint32_t flip_y;
+ float dynamic_range;
+ uint32_t on_mipmap;
+ float propagation;
+ float pad[3];
+ };
+
+ GIProbeLight *gi_probe_lights;
+ uint32_t gi_probe_max_lights;
+ RID gi_probe_lights_uniform;
+
+ enum {
+ GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT,
+ GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE,
+ GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP,
+ GI_PROBE_SHADER_VERSION_WRITE_TEXTURE,
+ GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING,
+ GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE,
+ GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT,
+ GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT,
+ GI_PROBE_SHADER_VERSION_MAX
+ };
+
+ GiprobeShaderRD giprobe_shader;
+ RID giprobe_lighting_shader_version;
+ RID giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_MAX];
+ RID giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_MAX];
+
+ enum {
+ GI_PROBE_DEBUG_COLOR,
+ GI_PROBE_DEBUG_LIGHT,
+ GI_PROBE_DEBUG_EMISSION,
+ GI_PROBE_DEBUG_LIGHT_FULL,
+ GI_PROBE_DEBUG_MAX
+ };
+
+ struct GIProbeDebugPushConstant {
+ float projection[16];
+ uint32_t cell_offset;
+ float dynamic_range;
+ float alpha;
+ uint32_t level;
+ int32_t bounds[3];
+ uint32_t pad;
+ };
+
+ GiprobeDebugShaderRD giprobe_debug_shader;
+ RID giprobe_debug_shader_version;
+ RID giprobe_debug_shader_version_shaders[GI_PROBE_DEBUG_MAX];
+ PipelineCacheRD giprobe_debug_shader_version_pipelines[GI_PROBE_DEBUG_MAX];
+ RID giprobe_debug_uniform_set;
+
+ /* SDFGI */
+
+ struct SDFGIShader {
+ enum SDFGIPreprocessShaderVersion {
+ PRE_PROCESS_SCROLL,
+ PRE_PROCESS_SCROLL_OCCLUSION,
+ PRE_PROCESS_JUMP_FLOOD_INITIALIZE,
+ PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF,
+ PRE_PROCESS_JUMP_FLOOD,
+ PRE_PROCESS_JUMP_FLOOD_OPTIMIZED,
+ PRE_PROCESS_JUMP_FLOOD_UPSCALE,
+ PRE_PROCESS_OCCLUSION,
+ PRE_PROCESS_STORE,
+ PRE_PROCESS_MAX
+ };
+
+ struct PreprocessPushConstant {
+ int32_t scroll[3];
+ int32_t grid_size;
+
+ int32_t probe_offset[3];
+ int32_t step_size;
+
+ int32_t half_size;
+ uint32_t occlusion_index;
+ int32_t cascade;
+ uint32_t pad;
+ };
+
+ SdfgiPreprocessShaderRD preprocess;
+ RID preprocess_shader;
+ RID preprocess_pipeline[PRE_PROCESS_MAX];
+
+ struct DebugPushConstant {
+ float grid_size[3];
+ uint32_t max_cascades;
+
+ int32_t screen_size[2];
+ uint32_t use_occlusion;
+ float y_mult;
+
+ float cam_extent[3];
+ uint32_t probe_axis_size;
+
+ float cam_transform[16];
+ };
+
+ SdfgiDebugShaderRD debug;
+ RID debug_shader;
+ RID debug_shader_version;
+ RID debug_pipeline;
+
+ enum ProbeDebugMode {
+ PROBE_DEBUG_PROBES,
+ PROBE_DEBUG_VISIBILITY,
+ PROBE_DEBUG_MAX
+ };
+
+ struct DebugProbesPushConstant {
+ float projection[16];
+
+ uint32_t band_power;
+ uint32_t sections_in_band;
+ uint32_t band_mask;
+ float section_arc;
+
+ float grid_size[3];
+ uint32_t cascade;
+
+ uint32_t pad;
+ float y_mult;
+ int32_t probe_debug_index;
+ int32_t probe_axis_size;
+ };
+
+ SdfgiDebugProbesShaderRD debug_probes;
+ RID debug_probes_shader;
+ RID debug_probes_shader_version;
+
+ PipelineCacheRD debug_probes_pipeline[PROBE_DEBUG_MAX];
+
+ struct Light {
+ float color[3];
+ float energy;
+
+ float direction[3];
+ uint32_t has_shadow;
+
+ float position[3];
+ float attenuation;
+
+ uint32_t type;
+ float cos_spot_angle;
+ float inv_spot_attenuation;
+ float radius;
+
+ float shadow_color[4];
+ };
+
+ struct DirectLightPushConstant {
+ float grid_size[3];
+ uint32_t max_cascades;
+
+ uint32_t cascade;
+ uint32_t light_count;
+ uint32_t process_offset;
+ uint32_t process_increment;
+
+ int32_t probe_axis_size;
+ float bounce_feedback;
+ float y_mult;
+ uint32_t use_occlusion;
+ };
+
+ enum {
+ DIRECT_LIGHT_MODE_STATIC,
+ DIRECT_LIGHT_MODE_DYNAMIC,
+ DIRECT_LIGHT_MODE_MAX
+ };
+ SdfgiDirectLightShaderRD direct_light;
+ RID direct_light_shader;
+ RID direct_light_pipeline[DIRECT_LIGHT_MODE_MAX];
+
+ enum {
+ INTEGRATE_MODE_PROCESS,
+ INTEGRATE_MODE_STORE,
+ INTEGRATE_MODE_SCROLL,
+ INTEGRATE_MODE_SCROLL_STORE,
+ INTEGRATE_MODE_MAX
+ };
+ struct IntegratePushConstant {
+ enum {
+ SKY_MODE_DISABLED,
+ SKY_MODE_COLOR,
+ SKY_MODE_SKY,
+ };
+
+ float grid_size[3];
+ uint32_t max_cascades;
+
+ uint32_t probe_axis_size;
+ uint32_t cascade;
+ uint32_t history_index;
+ uint32_t history_size;
+
+ uint32_t ray_count;
+ float ray_bias;
+ int32_t image_size[2];
+
+ int32_t world_offset[3];
+ uint32_t sky_mode;
+
+ int32_t scroll[3];
+ float sky_energy;
+
+ float sky_color[3];
+ float y_mult;
+
+ uint32_t store_ambient_texture;
+ uint32_t pad[3];
+ };
+
+ SdfgiIntegrateShaderRD integrate;
+ RID integrate_shader;
+ RID integrate_pipeline[INTEGRATE_MODE_MAX];
+
+ RID integrate_default_sky_uniform_set;
+
+ } sdfgi_shader;
+
+public:
+ /* GIPROBE INSTANCE */
+
+ //@TODO GIProbeInstance is still directly used in the render code, we'll address this when we refactor the render code itself.
+
+ struct GIProbeInstance {
+ // access to our containers
+ RendererStorageRD *storage;
+ RendererSceneGIRD *gi;
+
+ RID probe;
+ RID texture;
+ RID write_buffer;
+
+ struct Mipmap {
+ RID texture;
+ RID uniform_set;
+ RID second_bounce_uniform_set;
+ RID write_uniform_set;
+ uint32_t level;
+ uint32_t cell_offset;
+ uint32_t cell_count;
+ };
+ Vector<Mipmap> mipmaps;
+
+ struct DynamicMap {
+ RID texture; //color normally, or emission on first pass
+ RID fb_depth; //actual depth buffer for the first pass, float depth for later passes
+ RID depth; //actual depth buffer for the first pass, float depth for later passes
+ RID normal; //normal buffer for the first pass
+ RID albedo; //emission buffer for the first pass
+ RID orm; //orm buffer for the first pass
+ RID fb; //used for rendering, only valid on first map
+ RID uniform_set;
+ uint32_t size;
+ int mipmap; // mipmap to write to, -1 if no mipmap assigned
+ };
+
+ Vector<DynamicMap> dynamic_maps;
+
+ int slot = -1;
+ uint32_t last_probe_version = 0;
+ uint32_t last_probe_data_version = 0;
+
+ //uint64_t last_pass = 0;
+ uint32_t render_index = 0;
+
+ bool has_dynamic_object_data = false;
+
+ Transform transform;
+
+ void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render);
+ void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
+ };
+
+ mutable RID_Owner<GIProbeInstance> gi_probe_instance_owner;
+
+ _FORCE_INLINE_ GIProbeInstance *get_probe_instance(RID p_probe) const {
+ return gi_probe_instance_owner.getornull(p_probe);
+ };
+
+ _FORCE_INLINE_ RID gi_probe_instance_get_texture(RID p_probe) {
+ GIProbeInstance *gi_probe = get_probe_instance(p_probe);
+ ERR_FAIL_COND_V(!gi_probe, RID());
+ return gi_probe->texture;
+ };
+
+ RS::GIProbeQuality gi_probe_quality = RS::GI_PROBE_QUALITY_HIGH;
+
+ /* SDFGI */
+
+ struct SDFGI {
+ enum {
+ MAX_CASCADES = 8,
+ CASCADE_SIZE = 128,
+ PROBE_DIVISOR = 16,
+ ANISOTROPY_SIZE = 6,
+ MAX_DYNAMIC_LIGHTS = 128,
+ MAX_STATIC_LIGHTS = 1024,
+ LIGHTPROBE_OCT_SIZE = 6,
+ SH_SIZE = 16
+ };
+
+ struct Cascade {
+ struct UBO {
+ float offset[3];
+ float to_cell;
+ int32_t probe_offset[3];
+ uint32_t pad;
+ };
+
+ //cascade blocks are full-size for volume (128^3), half size for albedo/emission
+ RID sdf_tex;
+ RID light_tex;
+ RID light_aniso_0_tex;
+ RID light_aniso_1_tex;
+
+ RID light_data;
+ RID light_aniso_0_data;
+ RID light_aniso_1_data;
+
+ struct SolidCell { // this struct is unused, but remains as reference for size
+ uint32_t position;
+ uint32_t albedo;
+ uint32_t static_light;
+ uint32_t static_light_aniso;
+ };
+
+ RID solid_cell_dispatch_buffer; //buffer for indirect compute dispatch
+ RID solid_cell_buffer;
+
+ RID lightprobe_history_tex;
+ RID lightprobe_average_tex;
+
+ float cell_size;
+ Vector3i position;
+
+ static const Vector3i DIRTY_ALL;
+ Vector3i dirty_regions; //(0,0,0 is not dirty, negative is refresh from the end, DIRTY_ALL is refresh all.
+
+ RID sdf_store_uniform_set;
+ RID sdf_direct_light_uniform_set;
+ RID scroll_uniform_set;
+ RID scroll_occlusion_uniform_set;
+ RID integrate_uniform_set;
+ RID lights_buffer;
+
+ bool all_dynamic_lights_dirty = true;
+ };
+
+ // access to our containers
+ RendererStorageRD *storage;
+ RendererSceneGIRD *gi;
+
+ // used for rendering (voxelization)
+ RID render_albedo;
+ RID render_emission;
+ RID render_emission_aniso;
+ RID render_occlusion[8];
+ RID render_geom_facing;
+
+ RID render_sdf[2];
+ RID render_sdf_half[2];
+
+ // used for ping pong processing in cascades
+ RID sdf_initialize_uniform_set;
+ RID sdf_initialize_half_uniform_set;
+ RID jump_flood_uniform_set[2];
+ RID jump_flood_half_uniform_set[2];
+ RID sdf_upscale_uniform_set;
+ int upscale_jfa_uniform_set_index;
+ RID occlusion_uniform_set;
+
+ uint32_t cascade_size = 128;
+
+ LocalVector<Cascade> cascades;
+
+ RID lightprobe_texture;
+ RID lightprobe_data;
+ RID occlusion_texture;
+ RID occlusion_data;
+ RID ambient_texture; //integrates with volumetric fog
+
+ RID lightprobe_history_scroll; //used for scrolling lightprobes
+ RID lightprobe_average_scroll; //used for scrolling lightprobes
+
+ uint32_t history_size = 0;
+ float solid_cell_ratio = 0;
+ uint32_t solid_cell_count = 0;
+
+ RS::EnvironmentSDFGICascades cascade_mode;
+ float min_cell_size = 0;
+ uint32_t probe_axis_count = 0; //amount of probes per axis, this is an odd number because it encloses endpoints
+
+ RID debug_uniform_set;
+ RID debug_probes_uniform_set;
+ RID cascades_ubo;
+
+ bool uses_occlusion = false;
+ float bounce_feedback = 0.0;
+ bool reads_sky = false;
+ float energy = 1.0;
+ float normal_bias = 1.1;
+ float probe_bias = 1.1;
+ RS::EnvironmentSDFGIYScale y_scale_mode = RS::ENV_SDFGI_Y_SCALE_DISABLED;
+
+ float y_mult = 1.0;
+
+ uint32_t render_pass = 0;
+
+ int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically
+ RID integrate_sky_uniform_set;
+
+ void create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, RendererSceneGIRD *p_gi);
+ void erase();
+ void update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position);
+ void update_light();
+ void update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky);
+ void store_probes();
+ int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const;
+ void update_cascades();
+
+ void debug_draw(const CameraMatrix &p_projection, const Transform &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture);
+ void debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
+
+ void pre_process_gi(const Transform &p_transform, RendererSceneRenderRD *p_scene_render);
+ void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render);
+ void render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render);
+ };
+
+ RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16;
+ RS::EnvironmentSDFGIFramesToConverge sdfgi_frames_to_converge = RS::ENV_SDFGI_CONVERGE_IN_10_FRAMES;
+ RS::EnvironmentSDFGIFramesToUpdateLight sdfgi_frames_to_update_light = RS::ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES;
+
+ float sdfgi_solid_cell_ratio = 0.25;
+ Vector3 sdfgi_debug_probe_pos;
+ Vector3 sdfgi_debug_probe_dir;
+ bool sdfgi_debug_probe_enabled = false;
+ Vector3i sdfgi_debug_probe_index;
+
+ /* SDFGI UPDATE */
+
+ int sdfgi_get_lightprobe_octahedron_size() const { return SDFGI::LIGHTPROBE_OCT_SIZE; }
+
+ /* GI */
+ enum {
+ MAX_GIPROBES = 8
+ };
+
+ // Struct for use in render buffer
+ struct RenderBuffersGI {
+ RID giprobe_textures[MAX_GIPROBES];
+ RID giprobe_buffer;
+
+ RID full_buffer;
+ RID full_dispatch;
+ RID full_mask;
+ };
+
+ struct SDFGIData {
+ float grid_size[3];
+ uint32_t max_cascades;
+
+ uint32_t use_occlusion;
+ int32_t probe_axis_size;
+ float probe_to_uvw;
+ float normal_bias;
+
+ float lightprobe_tex_pixel_size[3];
+ float energy;
+
+ float lightprobe_uv_offset[3];
+ float y_mult;
+
+ float occlusion_clamp[3];
+ uint32_t pad3;
+
+ float occlusion_renormalize[3];
+ uint32_t pad4;
+
+ float cascade_probe_size[3];
+ uint32_t pad5;
+
+ struct ProbeCascadeData {
+ float position[3]; //offset of (0,0,0) in world coordinates
+ float to_probe; // 1/bounds * grid_size
+ int32_t probe_world_offset[3];
+ float to_cell; // 1/bounds * grid_size
+ };
+
+ ProbeCascadeData cascades[SDFGI::MAX_CASCADES];
+ };
+
+ struct GIProbeData {
+ float xform[16];
+ float bounds[3];
+ float dynamic_range;
+
+ float bias;
+ float normal_bias;
+ uint32_t blend_ambient;
+ uint32_t texture_slot;
+
+ float anisotropy_strength;
+ float ao;
+ float ao_size;
+ uint32_t mipmaps;
+ };
+
+ struct PushConstant {
+ int32_t screen_size[2];
+ float z_near;
+ float z_far;
+
+ float proj_info[4];
+ float ao_color[3];
+ uint32_t max_giprobes;
+
+ uint32_t high_quality_vct;
+ uint32_t orthogonal;
+ uint32_t pad[2];
+
+ float cam_rotation[12];
+ };
+
+ RID sdfgi_ubo;
+ enum Mode {
+ MODE_GIPROBE,
+ MODE_SDFGI,
+ MODE_COMBINED,
+ MODE_HALF_RES_GIPROBE,
+ MODE_HALF_RES_SDFGI,
+ MODE_HALF_RES_COMBINED,
+ MODE_MAX
+ };
+
+ RID default_giprobe_buffer;
+
+ bool half_resolution = false;
+ GiShaderRD shader;
+ RID shader_version;
+ RID pipelines[MODE_MAX];
+
+ RendererSceneGIRD();
+ ~RendererSceneGIRD();
+
+ void init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky);
+ void free();
+
+ SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size);
+
+ void setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used, RendererSceneRenderRD *p_scene_render);
+ void process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, RendererSceneRenderRD *p_scene_render);
+
+ RID gi_probe_instance_create(RID p_base);
+ void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
+ bool gi_probe_needs_update(RID p_probe) const;
+ void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render);
+ void debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
+};
+
+#endif /* !RENDERING_SERVER_SCENE_GI_RD_H */
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.h b/servers/rendering/renderer_rd/renderer_scene_render_forward.h
deleted file mode 100644
index 5d77c13b43..0000000000
--- a/servers/rendering/renderer_rd/renderer_scene_render_forward.h
+++ /dev/null
@@ -1,599 +0,0 @@
-/*************************************************************************/
-/* renderer_scene_render_forward.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_H
-#define RENDERING_SERVER_SCENE_RENDER_FORWARD_H
-
-#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
-#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
-#include "servers/rendering/renderer_rd/shaders/scene_forward.glsl.gen.h"
-
-class RendererSceneRenderForward : public RendererSceneRenderRD {
- enum {
- SCENE_UNIFORM_SET = 0,
- RENDER_PASS_UNIFORM_SET = 1,
- TRANSFORMS_UNIFORM_SET = 2,
- MATERIAL_UNIFORM_SET = 3
- };
-
- enum {
- SDFGI_MAX_CASCADES = 8,
- MAX_GI_PROBES = 8
- };
-
- /* Scene Shader */
-
- enum ShaderVersion {
- SHADER_VERSION_DEPTH_PASS,
- SHADER_VERSION_DEPTH_PASS_DP,
- SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
- SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE,
- SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
- SHADER_VERSION_DEPTH_PASS_WITH_SDF,
- SHADER_VERSION_COLOR_PASS,
- SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI,
- SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
- SHADER_VERSION_LIGHTMAP_COLOR_PASS,
- SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
- SHADER_VERSION_MAX
- };
-
- struct {
- SceneForwardShaderRD scene_shader;
- ShaderCompilerRD compiler;
- } shader;
-
- RendererStorageRD *storage;
-
- /* Material */
-
- struct ShaderData : public RendererStorageRD::ShaderData {
- enum BlendMode { //used internally
- BLEND_MODE_MIX,
- BLEND_MODE_ADD,
- BLEND_MODE_SUB,
- BLEND_MODE_MUL,
- BLEND_MODE_ALPHA_TO_COVERAGE
- };
-
- enum DepthDraw {
- DEPTH_DRAW_DISABLED,
- DEPTH_DRAW_OPAQUE,
- DEPTH_DRAW_ALWAYS
- };
-
- enum DepthTest {
- DEPTH_TEST_DISABLED,
- DEPTH_TEST_ENABLED
- };
-
- enum Cull {
- CULL_DISABLED,
- CULL_FRONT,
- CULL_BACK
- };
-
- enum CullVariant {
- CULL_VARIANT_NORMAL,
- CULL_VARIANT_REVERSED,
- CULL_VARIANT_DOUBLE_SIDED,
- CULL_VARIANT_MAX
-
- };
-
- enum AlphaAntiAliasing {
- ALPHA_ANTIALIASING_OFF,
- ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
- ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE
- };
-
- bool valid;
- RID version;
- uint32_t vertex_input_mask;
- PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
-
- String path;
-
- Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
-
- Vector<uint32_t> ubo_offsets;
- uint32_t ubo_size;
-
- String code;
- Map<StringName, RID> default_texture_params;
-
- DepthDraw depth_draw;
- DepthTest depth_test;
-
- bool uses_point_size;
- bool uses_alpha;
- bool uses_blend_alpha;
- bool uses_alpha_clip;
- bool uses_depth_pre_pass;
- bool uses_discard;
- bool uses_roughness;
- bool uses_normal;
-
- bool unshaded;
- bool uses_vertex;
- bool uses_sss;
- bool uses_transmittance;
- bool uses_screen_texture;
- bool uses_depth_texture;
- bool uses_normal_texture;
- bool uses_time;
- bool writes_modelview_or_projection;
- bool uses_world_coordinates;
-
- uint64_t last_pass = 0;
- uint32_t index = 0;
-
- virtual void set_code(const String &p_Code);
- virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
- void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
-
- virtual bool is_param_texture(const StringName &p_param) const;
- virtual bool is_animated() const;
- virtual bool casts_shadows() const;
- virtual Variant get_default_parameter(const StringName &p_parameter) const;
- ShaderData();
- virtual ~ShaderData();
- };
-
- RendererStorageRD::ShaderData *_create_shader_func();
- static RendererStorageRD::ShaderData *_create_shader_funcs() {
- return static_cast<RendererSceneRenderForward *>(singleton)->_create_shader_func();
- }
-
- struct MaterialData : public RendererStorageRD::MaterialData {
- uint64_t last_frame;
- ShaderData *shader_data;
- RID uniform_buffer;
- RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
- uint64_t last_pass = 0;
- uint32_t index = 0;
- RID next_pass;
- uint8_t priority;
- virtual void set_render_priority(int p_priority);
- virtual void set_next_pass(RID p_pass);
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
- virtual ~MaterialData();
- };
-
- RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
- static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
- return static_cast<RendererSceneRenderForward *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
- }
-
- /* Push Constant */
-
- struct PushConstant {
- uint32_t index;
- uint32_t pad;
- float bake_uv2_offset[2];
- };
-
- /* Framebuffer */
-
- struct RenderBufferDataForward : public RenderBufferData {
- //for rendering, may be MSAAd
-
- RID color;
- RID depth;
- RID specular;
- RID normal_roughness_buffer;
- RID giprobe_buffer;
-
- RID ambient_buffer;
- RID reflection_buffer;
-
- RS::ViewportMSAA msaa;
- RD::TextureSamples texture_samples;
-
- RID color_msaa;
- RID depth_msaa;
- RID specular_msaa;
- RID normal_roughness_buffer_msaa;
- RID roughness_buffer_msaa;
- RID giprobe_buffer_msaa;
-
- RID depth_fb;
- RID depth_normal_roughness_fb;
- RID depth_normal_roughness_giprobe_fb;
- RID color_fb;
- RID color_specular_fb;
- RID specular_only_fb;
- int width, height;
-
- RID render_sdfgi_uniform_set;
- void ensure_specular();
- void ensure_gi();
- void ensure_giprobe();
- void clear();
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
-
- ~RenderBufferDataForward();
- };
-
- virtual RenderBufferData *_create_render_buffer_data();
- void _allocate_normal_roughness_texture(RenderBufferDataForward *rb);
-
- RID shadow_sampler;
- RID render_base_uniform_set;
- RID render_pass_uniform_set;
- RID sdfgi_pass_uniform_set;
-
- uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
-
- virtual void _base_uniforms_changed();
- void _render_buffers_clear_uniform_set(RenderBufferDataForward *rb);
- virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
- virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
- virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers);
- virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers);
-
- void _update_render_base_uniform_set();
- RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
- RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes);
-
- struct LightmapData {
- float normal_xform[12];
- };
-
- struct LightmapCaptureData {
- float sh[9 * 4];
- };
-
- enum {
- INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
- INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7,
- INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
- INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
- INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
- INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11,
- INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
- INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
- INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
- INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
- INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT = 16,
- INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_MASK = 0x7,
- INSTANCE_DATA_FLAG_SKELETON = 1 << 19,
- };
-
- struct InstanceData {
- float transform[16];
- float normal_transform[16];
- uint32_t flags;
- uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer
- uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap)
- uint32_t mask;
- float lightmap_uv_scale[4];
- };
-
- struct SceneState {
- struct UBO {
- float projection_matrix[16];
- float inv_projection_matrix[16];
-
- float camera_matrix[16];
- float inv_camera_matrix[16];
-
- float viewport_size[2];
- float screen_pixel_size[2];
-
- float directional_penumbra_shadow_kernel[128]; //32 vec4s
- float directional_soft_shadow_kernel[128];
- float penumbra_shadow_kernel[128];
- float soft_shadow_kernel[128];
-
- uint32_t directional_penumbra_shadow_samples;
- uint32_t directional_soft_shadow_samples;
- uint32_t penumbra_shadow_samples;
- uint32_t soft_shadow_samples;
-
- float ambient_light_color_energy[4];
-
- float ambient_color_sky_mix;
- uint32_t use_ambient_light;
- uint32_t use_ambient_cubemap;
- uint32_t use_reflection_cubemap;
-
- float radiance_inverse_xform[12];
-
- float shadow_atlas_pixel_size[2];
- float directional_shadow_pixel_size[2];
-
- uint32_t directional_light_count;
- float dual_paraboloid_side;
- float z_far;
- float z_near;
-
- uint32_t ssao_enabled;
- float ssao_light_affect;
- float ssao_ao_affect;
- uint32_t roughness_limiter_enabled;
-
- float roughness_limiter_amount;
- float roughness_limiter_limit;
- uint32_t roughness_limiter_pad[2];
-
- float ao_color[4];
-
- float sdf_to_bounds[16];
-
- int32_t sdf_offset[3];
- uint32_t material_uv2_mode;
-
- int32_t sdf_size[3];
- uint32_t gi_upscale_for_msaa;
-
- uint32_t volumetric_fog_enabled;
- float volumetric_fog_inv_length;
- float volumetric_fog_detail_spread;
- uint32_t volumetric_fog_pad;
-
- // Fog
- uint32_t fog_enabled;
- float fog_density;
- float fog_height;
- float fog_height_density;
-
- float fog_light_color[3];
- float fog_sun_scatter;
-
- float fog_aerial_perspective;
-
- float time;
- float reflection_multiplier;
-
- uint32_t pancake_shadows;
- };
-
- UBO ubo;
-
- RID uniform_buffer;
-
- LightmapData *lightmaps;
- uint32_t max_lightmaps;
- RID lightmap_buffer;
-
- LightmapCaptureData *lightmap_captures;
- uint32_t max_lightmap_captures;
- RID lightmap_capture_buffer;
-
- RID instance_buffer;
- InstanceData *instances;
- uint32_t max_instances;
-
- bool used_screen_texture = false;
- bool used_normal_texture = false;
- bool used_depth_texture = false;
- bool used_sss = false;
- uint32_t current_shader_index = 0;
- uint32_t current_material_index = 0;
-
- } scene_state;
-
- /* Render List */
-
- struct RenderList {
- int max_elements;
-
- struct Element {
- RendererSceneRender::InstanceBase *instance;
- MaterialData *material;
- union {
- struct {
- //from least significant to most significant in sort, TODO: should be endian swapped on big endian
- uint64_t geometry_index : 20;
- uint64_t material_index : 15;
- uint64_t shader_index : 12;
- uint64_t uses_instancing : 1;
- uint64_t uses_forward_gi : 1;
- uint64_t uses_lightmap : 1;
- uint64_t depth_layer : 4;
- uint64_t priority : 8;
- };
-
- uint64_t sort_key;
- };
- uint32_t surface_index;
- };
-
- Element *base_elements;
- Element **elements;
-
- int element_count;
- int alpha_element_count;
-
- void clear() {
- element_count = 0;
- alpha_element_count = 0;
- }
-
- //should eventually be replaced by radix
-
- struct SortByKey {
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- return A->sort_key < B->sort_key;
- }
- };
-
- void sort_by_key(bool p_alpha) {
- SortArray<Element *, SortByKey> sorter;
- if (p_alpha) {
- sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
- } else {
- sorter.sort(elements, element_count);
- }
- }
-
- struct SortByDepth {
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- return A->instance->depth < B->instance->depth;
- }
- };
-
- void sort_by_depth(bool p_alpha) { //used for shadows
-
- SortArray<Element *, SortByDepth> sorter;
- if (p_alpha) {
- sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
- } else {
- sorter.sort(elements, element_count);
- }
- }
-
- struct SortByReverseDepthAndPriority {
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- uint32_t layer_A = uint32_t(A->priority);
- uint32_t layer_B = uint32_t(B->priority);
- if (layer_A == layer_B) {
- return A->instance->depth > B->instance->depth;
- } else {
- return layer_A < layer_B;
- }
- }
- };
-
- void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
-
- SortArray<Element *, SortByReverseDepthAndPriority> sorter;
- if (p_alpha) {
- sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
- } else {
- sorter.sort(elements, element_count);
- }
- }
-
- _FORCE_INLINE_ Element *add_element() {
- if (element_count + alpha_element_count >= max_elements) {
- return nullptr;
- }
- elements[element_count] = &base_elements[element_count];
- return elements[element_count++];
- }
-
- _FORCE_INLINE_ Element *add_alpha_element() {
- if (element_count + alpha_element_count >= max_elements) {
- return nullptr;
- }
- int idx = max_elements - alpha_element_count - 1;
- elements[idx] = &base_elements[idx];
- alpha_element_count++;
- return elements[idx];
- }
-
- void init() {
- element_count = 0;
- alpha_element_count = 0;
- elements = memnew_arr(Element *, max_elements);
- base_elements = memnew_arr(Element, max_elements);
- for (int i = 0; i < max_elements; i++) {
- elements[i] = &base_elements[i]; // assign elements
- }
- }
-
- RenderList() {
- max_elements = 0;
- }
-
- ~RenderList() {
- memdelete_arr(elements);
- memdelete_arr(base_elements);
- }
- };
-
- RenderList render_list;
-
- static RendererSceneRenderForward *singleton;
- uint64_t render_pass;
- double time;
- RID default_shader;
- RID default_material;
- RID overdraw_material_shader;
- RID overdraw_material;
- RID wireframe_material_shader;
- RID wireframe_material;
- RID default_shader_rd;
- RID default_shader_sdfgi_rd;
-
- RID default_vec4_xform_buffer;
- RID default_vec4_xform_uniform_set;
-
- enum PassMode {
- PASS_MODE_COLOR,
- PASS_MODE_COLOR_SPECULAR,
- PASS_MODE_COLOR_TRANSPARENT,
- PASS_MODE_SHADOW,
- PASS_MODE_SHADOW_DP,
- PASS_MODE_DEPTH,
- PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
- PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE,
- PASS_MODE_DEPTH_MATERIAL,
- PASS_MODE_SDF,
- };
-
- void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false);
- void _setup_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform);
-
- void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi = false, bool p_has_opaque_gi = false);
- void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
- _FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
- _FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
-
- void _fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, bool p_using_sdfgi = false);
-
- Map<Size2i, RID> sdfgi_framebuffer_size_cache;
-
- bool low_end = false;
-
-protected:
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
- virtual void _render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
- virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
- virtual void _render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
- virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
- virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances);
-
-public:
- virtual void set_time(double p_time, double p_step);
-
- virtual bool free(RID p_rid);
-
- RendererSceneRenderForward(RendererStorageRD *p_storage);
- ~RendererSceneRenderForward();
-};
-#endif // RASTERIZER_SCENE_HIGHEND_RD_H
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp b/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.cpp
index c6b2fa6dc0..7a19495f48 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* renderer_scene_render_forward.cpp */
+/* renderer_scene_render_forward_clustered.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "renderer_scene_render_forward.h"
+#include "renderer_scene_render_forward_clustered.h"
#include "core/config/project_settings.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_server_default.h"
/* SCENE SHADER */
-void RendererSceneRenderForward::ShaderData::set_code(const String &p_code) {
+void RendererSceneRenderForwardClustered::ShaderData::set_code(const String &p_code) {
//compile
code = p_code;
@@ -112,7 +112,7 @@ void RendererSceneRenderForward::ShaderData::set_code(const String &p_code) {
actions.usage_flag_pointers["TIME"] = &uses_time;
actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness;
actions.usage_flag_pointers["NORMAL"] = &uses_normal;
- actions.usage_flag_pointers["NORMALMAP"] = &uses_normal;
+ actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal;
actions.usage_flag_pointers["POINT_SIZE"] = &uses_point_size;
actions.usage_flag_pointers["POINT_COORD"] = &uses_point_size;
@@ -123,7 +123,7 @@ void RendererSceneRenderForward::ShaderData::set_code(const String &p_code) {
actions.uniforms = &uniforms;
- RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton;
+ RendererSceneRenderForwardClustered *scene_singleton = (RendererSceneRenderForwardClustered *)RendererSceneRenderForwardClustered::singleton;
Error err = scene_singleton->shader.compiler.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
@@ -257,7 +257,7 @@ void RendererSceneRenderForward::ShaderData::set_code(const String &p_code) {
RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j];
for (int k = 0; k < SHADER_VERSION_MAX; k++) {
- if (!static_cast<RendererSceneRenderForward *>(singleton)->shader.scene_shader.is_variant_enabled(k)) {
+ if (!static_cast<RendererSceneRenderForwardClustered *>(singleton)->shader.scene_shader.is_variant_enabled(k)) {
continue;
}
RD::PipelineRasterizationState raster_state;
@@ -324,7 +324,7 @@ void RendererSceneRenderForward::ShaderData::set_code(const String &p_code) {
valid = true;
}
-void RendererSceneRenderForward::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+void RendererSceneRenderForwardClustered::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
if (!p_texture.is_valid()) {
default_texture_params.erase(p_name);
} else {
@@ -332,7 +332,7 @@ void RendererSceneRenderForward::ShaderData::set_default_texture_param(const Str
}
}
-void RendererSceneRenderForward::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void RendererSceneRenderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
@@ -354,7 +354,7 @@ void RendererSceneRenderForward::ShaderData::get_param_list(List<PropertyInfo> *
}
}
-void RendererSceneRenderForward::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
+void RendererSceneRenderForwardClustered::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
@@ -369,7 +369,7 @@ void RendererSceneRenderForward::ShaderData::get_instance_param_list(List<Render
}
}
-bool RendererSceneRenderForward::ShaderData::is_param_texture(const StringName &p_param) const {
+bool RendererSceneRenderForwardClustered::ShaderData::is_param_texture(const StringName &p_param) const {
if (!uniforms.has(p_param)) {
return false;
}
@@ -377,15 +377,15 @@ bool RendererSceneRenderForward::ShaderData::is_param_texture(const StringName &
return uniforms[p_param].texture_order >= 0;
}
-bool RendererSceneRenderForward::ShaderData::is_animated() const {
+bool RendererSceneRenderForwardClustered::ShaderData::is_animated() const {
return false;
}
-bool RendererSceneRenderForward::ShaderData::casts_shadows() const {
+bool RendererSceneRenderForwardClustered::ShaderData::casts_shadows() const {
return false;
}
-Variant RendererSceneRenderForward::ShaderData::get_default_parameter(const StringName &p_parameter) const {
+Variant RendererSceneRenderForwardClustered::ShaderData::get_default_parameter(const StringName &p_parameter) const {
if (uniforms.has(p_parameter)) {
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
@@ -394,13 +394,19 @@ Variant RendererSceneRenderForward::ShaderData::get_default_parameter(const Stri
return Variant();
}
-RendererSceneRenderForward::ShaderData::ShaderData() {
+RS::ShaderNativeSourceCode RendererSceneRenderForwardClustered::ShaderData::get_native_source_code() const {
+ RendererSceneRenderForwardClustered *scene_singleton = (RendererSceneRenderForwardClustered *)RendererSceneRenderForwardClustered::singleton;
+
+ return scene_singleton->shader.scene_shader.version_get_native_source_code(version);
+}
+
+RendererSceneRenderForwardClustered::ShaderData::ShaderData() {
valid = false;
uses_screen_texture = false;
}
-RendererSceneRenderForward::ShaderData::~ShaderData() {
- RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton;
+RendererSceneRenderForwardClustered::ShaderData::~ShaderData() {
+ RendererSceneRenderForwardClustered *scene_singleton = (RendererSceneRenderForwardClustered *)RendererSceneRenderForwardClustered::singleton;
ERR_FAIL_COND(!scene_singleton);
//pipeline variants will clear themselves if shader is gone
if (version.is_valid()) {
@@ -408,21 +414,21 @@ RendererSceneRenderForward::ShaderData::~ShaderData() {
}
}
-RendererStorageRD::ShaderData *RendererSceneRenderForward::_create_shader_func() {
+RendererStorageRD::ShaderData *RendererSceneRenderForwardClustered::_create_shader_func() {
ShaderData *shader_data = memnew(ShaderData);
return shader_data;
}
-void RendererSceneRenderForward::MaterialData::set_render_priority(int p_priority) {
+void RendererSceneRenderForwardClustered::MaterialData::set_render_priority(int p_priority) {
priority = p_priority - RS::MATERIAL_RENDER_PRIORITY_MIN; //8 bits
}
-void RendererSceneRenderForward::MaterialData::set_next_pass(RID p_pass) {
+void RendererSceneRenderForwardClustered::MaterialData::set_next_pass(RID p_pass) {
next_pass = p_pass;
}
-void RendererSceneRenderForward::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
- RendererSceneRenderForward *scene_singleton = (RendererSceneRenderForward *)RendererSceneRenderForward::singleton;
+void RendererSceneRenderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ RendererSceneRenderForwardClustered *scene_singleton = (RendererSceneRenderForwardClustered *)RendererSceneRenderForwardClustered::singleton;
if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
p_uniform_dirty = true;
@@ -447,7 +453,7 @@ void RendererSceneRenderForward::MaterialData::update_parameters(const Map<Strin
//check whether buffer changed
if (p_uniform_dirty && ubo_data.size()) {
update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER);
}
uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
@@ -501,7 +507,7 @@ void RendererSceneRenderForward::MaterialData::update_parameters(const Map<Strin
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->shader.scene_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
}
-RendererSceneRenderForward::MaterialData::~MaterialData() {
+RendererSceneRenderForwardClustered::MaterialData::~MaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
}
@@ -511,7 +517,7 @@ RendererSceneRenderForward::MaterialData::~MaterialData() {
}
}
-RendererStorageRD::MaterialData *RendererSceneRenderForward::_create_material_func(ShaderData *p_shader) {
+RendererStorageRD::MaterialData *RendererSceneRenderForwardClustered::_create_material_func(ShaderData *p_shader) {
MaterialData *material_data = memnew(MaterialData);
material_data->shader_data = p_shader;
material_data->last_frame = false;
@@ -519,11 +525,11 @@ RendererStorageRD::MaterialData *RendererSceneRenderForward::_create_material_fu
return material_data;
}
-RendererSceneRenderForward::RenderBufferDataForward::~RenderBufferDataForward() {
+RendererSceneRenderForwardClustered::RenderBufferDataForward::~RenderBufferDataForward() {
clear();
}
-void RendererSceneRenderForward::RenderBufferDataForward::ensure_specular() {
+void RendererSceneRenderForwardClustered::RenderBufferDataForward::ensure_specular() {
if (!specular.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
@@ -577,20 +583,7 @@ void RendererSceneRenderForward::RenderBufferDataForward::ensure_specular() {
}
}
-void RendererSceneRenderForward::RenderBufferDataForward::ensure_gi() {
- if (!reflection_buffer.is_valid()) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.width = width;
- tf.height = height;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
- reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
- ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
- }
-}
-
-void RendererSceneRenderForward::RenderBufferDataForward::ensure_giprobe() {
+void RendererSceneRenderForwardClustered::RenderBufferDataForward::ensure_giprobe() {
if (!giprobe_buffer.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8_UINT;
@@ -626,17 +619,7 @@ void RendererSceneRenderForward::RenderBufferDataForward::ensure_giprobe() {
}
}
-void RendererSceneRenderForward::RenderBufferDataForward::clear() {
- if (ambient_buffer != RID() && ambient_buffer != color) {
- RD::get_singleton()->free(ambient_buffer);
- ambient_buffer = RID();
- }
-
- if (reflection_buffer != RID() && reflection_buffer != specular) {
- RD::get_singleton()->free(reflection_buffer);
- reflection_buffer = RID();
- }
-
+void RendererSceneRenderForwardClustered::RenderBufferDataForward::clear() {
if (giprobe_buffer != RID()) {
RD::get_singleton()->free(giprobe_buffer);
giprobe_buffer = RID();
@@ -690,7 +673,7 @@ void RendererSceneRenderForward::RenderBufferDataForward::clear() {
}
}
-void RendererSceneRenderForward::RenderBufferDataForward::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
+void RendererSceneRenderForwardClustered::RenderBufferDataForward::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
clear();
msaa = p_msaa;
@@ -757,7 +740,7 @@ void RendererSceneRenderForward::RenderBufferDataForward::configure(RID p_color_
}
}
-void RendererSceneRenderForward::_allocate_normal_roughness_texture(RenderBufferDataForward *rb) {
+void RendererSceneRenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferDataForward *rb) {
if (rb->normal_roughness_buffer.is_valid()) {
return;
}
@@ -795,263 +778,103 @@ void RendererSceneRenderForward::_allocate_normal_roughness_texture(RenderBuffer
_render_buffers_clear_uniform_set(rb);
}
-RendererSceneRenderRD::RenderBufferData *RendererSceneRenderForward::_create_render_buffer_data() {
+RendererSceneRenderRD::RenderBufferData *RendererSceneRenderForwardClustered::_create_render_buffer_data() {
return memnew(RenderBufferDataForward);
}
-bool RendererSceneRenderForward::free(RID p_rid) {
+bool RendererSceneRenderForwardClustered::free(RID p_rid) {
if (RendererSceneRenderRD::free(p_rid)) {
return true;
}
return false;
}
-void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi, bool p_has_opaque_gi) {
- uint32_t lightmap_captures_used = 0;
-
- for (int i = 0; i < p_element_count; i++) {
- const RenderList::Element *e = p_elements[i];
- InstanceData &id = scene_state.instances[i];
- bool store_transform = true;
- id.flags = 0;
- id.mask = e->instance->layer_mask;
- id.instance_uniforms_ofs = e->instance->instance_allocated_shader_parameters_offset >= 0 ? e->instance->instance_allocated_shader_parameters_offset : 0;
-
- if (e->instance->base_type == RS::INSTANCE_MULTIMESH) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH;
- uint32_t stride;
- if (storage->multimesh_get_transform_format(e->instance->base) == RS::MULTIMESH_TRANSFORM_2D) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
- stride = 2;
- } else {
- stride = 3;
- }
- if (storage->multimesh_uses_colors(e->instance->base)) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
- stride += 1;
- }
- if (storage->multimesh_uses_custom_data(e->instance->base)) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
- stride += 1;
- }
-
- id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
- } else if (e->instance->base_type == RS::INSTANCE_PARTICLES) {
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH;
- uint32_t stride;
- if (false) { // 2D particles
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
- stride = 2;
- } else {
- stride = 3;
- }
-
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
- stride += 1;
-
- id.flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
- stride += 1;
-
- id.flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
-
- if (!storage->particles_is_using_local_coords(e->instance->base)) {
- store_transform = false;
- }
-
- } else if (e->instance->base_type == RS::INSTANCE_MESH) {
- if (e->instance->skeleton.is_valid()) {
- id.flags |= INSTANCE_DATA_FLAG_SKELETON;
- }
- }
-
- if (store_transform) {
- RendererStorageRD::store_transform(e->instance->transform, id.transform);
- RendererStorageRD::store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform);
- } else {
- RendererStorageRD::store_transform(Transform(), id.transform);
- RendererStorageRD::store_transform(Transform(), id.normal_transform);
- }
-
- if (p_for_depth) {
- id.gi_offset = 0xFFFFFFFF;
- continue;
- }
-
- if (e->instance->lightmap) {
- int32_t lightmap_index = storage->lightmap_get_array_index(e->instance->lightmap->base);
- if (lightmap_index >= 0) {
- id.gi_offset = lightmap_index;
- id.gi_offset |= e->instance->lightmap_slice_index << 12;
- id.gi_offset |= e->instance->lightmap_cull_index << 20;
- id.lightmap_uv_scale[0] = e->instance->lightmap_uv_scale.position.x;
- id.lightmap_uv_scale[1] = e->instance->lightmap_uv_scale.position.y;
- id.lightmap_uv_scale[2] = e->instance->lightmap_uv_scale.size.width;
- id.lightmap_uv_scale[3] = e->instance->lightmap_uv_scale.size.height;
- id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP;
- if (storage->lightmap_uses_spherical_harmonics(e->instance->lightmap->base)) {
- id.flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP;
- }
- } else {
- id.gi_offset = 0xFFFFFFFF;
- }
- } else if (!e->instance->lightmap_sh.empty()) {
- if (lightmap_captures_used < scene_state.max_lightmap_captures) {
- const Color *src_capture = e->instance->lightmap_sh.ptr();
- LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used];
- for (int j = 0; j < 9; j++) {
- lcd.sh[j * 4 + 0] = src_capture[j].r;
- lcd.sh[j * 4 + 1] = src_capture[j].g;
- lcd.sh[j * 4 + 2] = src_capture[j].b;
- lcd.sh[j * 4 + 3] = src_capture[j].a;
- }
- id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE;
- id.gi_offset = lightmap_captures_used;
- lightmap_captures_used++;
- }
-
- } else {
- if (p_has_opaque_gi) {
- id.flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
- }
-
- if (!low_end && !e->instance->gi_probe_instances.empty()) {
- uint32_t written = 0;
- for (int j = 0; j < e->instance->gi_probe_instances.size(); j++) {
- RID probe = e->instance->gi_probe_instances[j];
-
- uint32_t index = gi_probe_instance_get_render_index(probe);
-
- if (written == 0) {
- id.gi_offset = index;
- id.flags |= INSTANCE_DATA_FLAG_USE_GIPROBE;
- written = 1;
- } else {
- id.gi_offset = index << 16;
- written = 2;
- break;
- }
- }
- if (written == 0) {
- id.gi_offset = 0xFFFFFFFF;
- } else if (written == 1) {
- id.gi_offset |= 0xFFFF0000;
- }
- } else {
- if (p_has_sdfgi && (e->instance->baked_light || e->instance->dynamic_gi)) {
- id.flags |= INSTANCE_DATA_FLAG_USE_SDFGI;
- }
- id.gi_offset = 0xFFFFFFFF;
- }
- }
- }
-
- RD::get_singleton()->buffer_update(scene_state.instance_buffer, 0, sizeof(InstanceData) * p_element_count, scene_state.instances, true);
- if (lightmap_captures_used) {
- RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, true);
- }
-}
-
/// RENDERING ///
-void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe, const Vector2 &p_uv_offset, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
+template <RendererSceneRenderForwardClustered::PassMode p_pass_mode>
+void RendererSceneRenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
RD::DrawListID draw_list = p_draw_list;
RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format;
//global scope bindings
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_base_uniform_set, SCENE_UNIFORM_SET);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_render_pass_uniform_set, RENDER_PASS_UNIFORM_SET);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_params->render_pass_uniform_set, RENDER_PASS_UNIFORM_SET);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_vec4_xform_uniform_set, TRANSFORMS_UNIFORM_SET);
- MaterialData *prev_material = nullptr;
+ RID prev_material_uniform_set;
RID prev_vertex_array_rd;
RID prev_index_array_rd;
RID prev_pipeline_rd;
RID prev_xforms_uniform_set;
- PushConstant push_constant;
- zeromem(&push_constant, sizeof(PushConstant));
- push_constant.bake_uv2_offset[0] = p_uv_offset.x;
- push_constant.bake_uv2_offset[1] = p_uv_offset.y;
+ bool shadow_pass = (p_params->pass_mode == PASS_MODE_SHADOW) || (p_params->pass_mode == PASS_MODE_SHADOW_DP);
+
+ SceneState::PushConstant push_constant;
+
+ if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL) {
+ push_constant.uv_offset = Math::make_half_float(p_params->uv_offset.y) << 16;
+ push_constant.uv_offset |= Math::make_half_float(p_params->uv_offset.x);
+ } else {
+ push_constant.uv_offset = 0;
+ }
+
+ for (uint32_t i = p_from_element; i < p_to_element; i++) {
+ const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i];
+ const RenderElementInfo &element_info = p_params->element_info[i];
+
+ push_constant.base_index = i + p_params->element_offset;
+
+ RID material_uniform_set;
+ ShaderData *shader;
+ void *mesh_surface;
+
+ if (shadow_pass || p_params->pass_mode == PASS_MODE_DEPTH) { //regular depth pass can use these too
+ material_uniform_set = surf->material_uniform_set_shadow;
+ shader = surf->shader_shadow;
+ mesh_surface = surf->surface_shadow;
- for (int i = 0; i < p_element_count; i++) {
- const RenderList::Element *e = p_elements[i];
+ } else {
+ material_uniform_set = surf->material_uniform_set;
+ shader = surf->shader;
+ mesh_surface = surf->surface;
+ }
- MaterialData *material = e->material;
- ShaderData *shader = material->shader_data;
- RID xforms_uniform_set;
+ if (!mesh_surface) {
+ continue;
+ }
//find cull variant
ShaderData::CullVariant cull_variant;
- if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || p_pass_mode == PASS_MODE_SDF || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)) {
+ if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL || p_params->pass_mode == PASS_MODE_SDF || ((p_params->pass_mode == PASS_MODE_SHADOW || p_params->pass_mode == PASS_MODE_SHADOW_DP) && surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS)) {
cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED;
} else {
- bool mirror = e->instance->mirror;
- if (p_reverse_cull) {
+ bool mirror = surf->owner->mirror;
+ if (p_params->reverse_cull) {
mirror = !mirror;
}
cull_variant = mirror ? ShaderData::CULL_VARIANT_REVERSED : ShaderData::CULL_VARIANT_NORMAL;
}
- //find primitive and vertex format
- RS::PrimitiveType primitive;
- void *mesh_surface = nullptr;
-
- switch (e->instance->base_type) {
- case RS::INSTANCE_MESH: {
- mesh_surface = storage->mesh_get_surface(e->instance->base, e->surface_index);
-
- primitive = storage->mesh_surface_get_primitive(mesh_surface);
- if (e->instance->skeleton.is_valid()) {
- xforms_uniform_set = storage->skeleton_get_3d_uniform_set(e->instance->skeleton, default_shader_rd, TRANSFORMS_UNIFORM_SET);
- }
- } break;
- case RS::INSTANCE_MULTIMESH: {
- RID mesh = storage->multimesh_get_mesh(e->instance->base);
- ERR_CONTINUE(!mesh.is_valid()); //should be a bug
-
- mesh_surface = storage->mesh_get_surface(e->instance->base, e->surface_index);
-
- primitive = storage->mesh_surface_get_primitive(mesh_surface);
-
- xforms_uniform_set = storage->multimesh_get_3d_uniform_set(e->instance->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
-
- } break;
- case RS::INSTANCE_IMMEDIATE: {
- ERR_CONTINUE(true); //should be a bug
- } break;
- case RS::INSTANCE_PARTICLES: {
- RID mesh = storage->particles_get_draw_pass_mesh(e->instance->base, e->surface_index >> 16);
- ERR_CONTINUE(!mesh.is_valid()); //should be a bug
-
- mesh_surface = storage->mesh_get_surface(e->instance->base, e->surface_index & 0xFFFF);
-
- primitive = storage->mesh_surface_get_primitive(mesh_surface);
-
- xforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(e->instance->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
-
- } break;
- default: {
- ERR_CONTINUE(true); //should be a bug
- }
- }
+ RS::PrimitiveType primitive = surf->primitive;
+ RID xforms_uniform_set = surf->owner->transforms_uniform_set;
ShaderVersion shader_version = SHADER_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized.
- switch (p_pass_mode) {
+ switch (p_params->pass_mode) {
case PASS_MODE_COLOR:
case PASS_MODE_COLOR_TRANSPARENT: {
- if (e->uses_lightmap) {
+ if (element_info.uses_lightmap) {
shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS;
- } else if (e->uses_forward_gi) {
+ } else if (element_info.uses_forward_gi) {
shader_version = SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI;
} else {
shader_version = SHADER_VERSION_COLOR_PASS;
}
} break;
case PASS_MODE_COLOR_SPECULAR: {
- if (e->uses_lightmap) {
+ if (element_info.uses_lightmap) {
shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR;
} else {
shader_version = SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR;
@@ -1086,42 +909,15 @@ void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw
RID vertex_array_rd;
RID index_array_rd;
- if (mesh_surface) {
- if (e->instance->mesh_instance.is_valid()) { //skeleton and blend shape
- storage->mesh_instance_surface_get_vertex_arrays_and_format(e->instance->mesh_instance, e->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format);
- } else {
- storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format);
- }
-
- if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(mesh_surface)) {
- Vector3 support_min = e->instance->transformed_aabb.get_support(-p_lod_plane.normal);
- Vector3 support_max = e->instance->transformed_aabb.get_support(p_lod_plane.normal);
-
- float distance_min = p_lod_plane.distance_to(support_min);
- float distance_max = p_lod_plane.distance_to(support_max);
-
- float distance = 0.0;
-
- if (distance_min * distance_max < 0.0) {
- //crossing plane
- distance = 0.0;
- } else if (distance_min >= 0.0) {
- distance = distance_min;
- } else if (distance_max <= 0.0) {
- distance = -distance_max;
- }
-
- Vector3 model_scale_vec = e->instance->transform.basis.get_scale_abs();
-
- float model_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z));
-
- index_array_rd = storage->mesh_surface_get_index_array_with_lod(mesh_surface, model_scale * e->instance->lod_bias, distance * p_lod_distance_multiplier, p_screen_lod_threshold);
-
- } else {
- index_array_rd = storage->mesh_surface_get_index_array(mesh_surface);
- }
+ //skeleton and blend shape
+ if (surf->owner->mesh_instance.is_valid()) {
+ storage->mesh_instance_surface_get_vertex_arrays_and_format(surf->owner->mesh_instance, surf->surface_index, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format);
+ } else {
+ storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, pipeline->get_vertex_input_mask(), vertex_array_rd, vertex_format);
}
+ index_array_rd = storage->mesh_surface_get_index_array(mesh_surface, element_info.lod_index);
+
if (prev_vertex_array_rd != vertex_array_rd) {
RD::get_singleton()->draw_list_bind_vertex_array(draw_list, vertex_array_rd);
prev_vertex_array_rd = vertex_array_rd;
@@ -1134,7 +930,7 @@ void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw
prev_index_array_rd = index_array_rd;
}
- RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_force_wireframe);
+ RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_params->force_wireframe);
if (pipeline_rd != prev_pipeline_rd) {
// checking with prev shader does not make so much sense, as
@@ -1148,40 +944,87 @@ void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw
prev_xforms_uniform_set = xforms_uniform_set;
}
- if (material != prev_material) {
+ if (material_uniform_set != prev_material_uniform_set) {
//update uniform set
- if (material->uniform_set.is_valid()) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material->uniform_set, MATERIAL_UNIFORM_SET);
+ if (material_uniform_set.is_valid()) {
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_uniform_set, MATERIAL_UNIFORM_SET);
}
- prev_material = material;
+ prev_material_uniform_set = material_uniform_set;
}
- push_constant.index = i;
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(PushConstant));
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SceneState::PushConstant));
- switch (e->instance->base_type) {
- case RS::INSTANCE_MESH: {
- RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid());
- } break;
- case RS::INSTANCE_MULTIMESH: {
- uint32_t instances = storage->multimesh_get_instances_to_draw(e->instance->base);
- RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances);
- } break;
- case RS::INSTANCE_IMMEDIATE: {
- } break;
- case RS::INSTANCE_PARTICLES: {
- uint32_t instances = storage->particles_get_amount(e->instance->base);
- RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances);
- } break;
- default: {
- ERR_CONTINUE(true); //should be a bug
- }
- }
+ uint32_t instance_count = surf->owner->instance_count > 1 ? surf->owner->instance_count : element_info.repeat;
+ RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count);
+ i += element_info.repeat - 1; //skip equal elements
+ }
+}
+
+void RendererSceneRenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
+ //use template for faster performance (pass mode comparisons are inlined)
+
+ switch (p_params->pass_mode) {
+ case PASS_MODE_COLOR: {
+ _render_list_template<PASS_MODE_COLOR>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_COLOR_SPECULAR: {
+ _render_list_template<PASS_MODE_COLOR_SPECULAR>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_COLOR_TRANSPARENT: {
+ _render_list_template<PASS_MODE_COLOR_TRANSPARENT>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_SHADOW: {
+ _render_list_template<PASS_MODE_SHADOW>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_SHADOW_DP: {
+ _render_list_template<PASS_MODE_SHADOW_DP>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_DEPTH: {
+ _render_list_template<PASS_MODE_DEPTH>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
+ _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: {
+ _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_DEPTH_MATERIAL: {
+ _render_list_template<PASS_MODE_DEPTH_MATERIAL>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ case PASS_MODE_SDF: {
+ _render_list_template<PASS_MODE_SDF>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ } break;
+ }
+}
+
+void RendererSceneRenderForwardClustered::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) {
+ uint32_t render_total = p_params->element_count;
+ uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();
+ uint32_t render_from = p_thread * render_total / total_threads;
+ uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads);
+ _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to);
+}
+
+void RendererSceneRenderForwardClustered::_render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
+ RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_framebuffer);
+ p_params->framebuffer_format = fb_format;
+
+ if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time
+ //multi threaded
+ thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count());
+ RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures);
+ RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RendererSceneRenderForwardClustered::_render_list_thread_function, p_params);
+ RD::get_singleton()->draw_list_end(p_params->barrier);
+ } else {
+ //single threaded
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures);
+ _render_list(draw_list, fb_format, p_params, 0, p_params->element_count);
+ RD::get_singleton()->draw_list_end(p_params->barrier);
}
}
-void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) {
+void RendererSceneRenderForwardClustered::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
//CameraMatrix projection = p_cam_projection;
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
CameraMatrix correction;
@@ -1209,8 +1052,18 @@ void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_ren
scene_state.ubo.penumbra_shadow_samples = penumbra_shadow_samples_get();
scene_state.ubo.soft_shadow_samples = soft_shadow_samples_get();
- scene_state.ubo.screen_pixel_size[0] = p_screen_pixel_size.x;
- scene_state.ubo.screen_pixel_size[1] = p_screen_pixel_size.y;
+ Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
+ scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
+ scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y;
+
+ scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_cluster_size);
+ scene_state.ubo.max_cluster_element_count_div_32 = p_max_cluster_elements / 32;
+ {
+ uint32_t cluster_screen_width = (p_screen_size.width - 1) / p_cluster_size + 1;
+ uint32_t cluster_screen_height = (p_screen_size.height - 1) / p_cluster_size + 1;
+ scene_state.ubo.cluster_type_size = cluster_screen_width * cluster_screen_height * (scene_state.ubo.max_cluster_element_count_div_32 + 32);
+ scene_state.ubo.cluster_width = cluster_screen_width;
+ }
if (p_shadow_atlas.is_valid()) {
Vector2 sas = shadow_atlas_get_size(p_shadow_atlas);
@@ -1277,7 +1130,7 @@ void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_ren
//vec2 tex_pixel_size = 1.0 / vec2(ivec2( (OCT_SIZE+2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE+2) * params.probe_axis_size ) );
//vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx;
- uint32_t oct_size = sdfgi_get_lightprobe_octahedron_size();
+ uint32_t oct_size = gi.sdfgi_get_lightprobe_octahedron_size();
scene_state.ubo.sdfgi_lightprobe_tex_pixel_size[0] = 1.0 / ((oct_size + 2) * scene_state.ubo.sdfgi_probe_axis_size * scene_state.ubo.sdfgi_probe_axis_size);
scene_state.ubo.sdfgi_lightprobe_tex_pixel_size[1] = 1.0 / ((oct_size + 2) * scene_state.ubo.sdfgi_probe_axis_size);
@@ -1410,269 +1263,333 @@ void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_ren
scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount();
scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit();
- RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true);
-}
-
-void RendererSceneRenderForward::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) {
- RID m_src;
-
- m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material;
-
- if (unlikely(get_debug_draw_mode() != RS::VIEWPORT_DEBUG_DRAW_DISABLED)) {
- if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
- m_src = overdraw_material;
- } else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING) {
- m_src = default_material;
+ if (p_index >= (int)scene_state.uniform_buffers.size()) {
+ uint32_t from = scene_state.uniform_buffers.size();
+ scene_state.uniform_buffers.resize(p_index + 1);
+ render_pass_uniform_sets.resize(p_index + 1);
+ for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) {
+ scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
}
}
+ RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER);
+}
- MaterialData *material = nullptr;
-
- if (m_src.is_valid()) {
- material = (MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
- if (!material || !material->shader_data->valid) {
- material = nullptr;
+void RendererSceneRenderForwardClustered::_update_instance_data_buffer(RenderListType p_render_list) {
+ if (scene_state.instance_data[p_render_list].size() > 0) {
+ if (scene_state.instance_buffer[p_render_list] == RID() || scene_state.instance_buffer_size[p_render_list] < scene_state.instance_data[p_render_list].size()) {
+ if (scene_state.instance_buffer[p_render_list] != RID()) {
+ RD::get_singleton()->free(scene_state.instance_buffer[p_render_list]);
+ }
+ uint32_t new_size = nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), scene_state.instance_data[p_render_list].size()));
+ scene_state.instance_buffer[p_render_list] = RD::get_singleton()->storage_buffer_create(new_size * sizeof(SceneState::InstanceData));
+ scene_state.instance_buffer_size[p_render_list] = new_size;
}
+ RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr(), RD::BARRIER_MASK_RASTER);
}
+}
+void RendererSceneRenderForwardClustered::_fill_instance_data(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) {
+ RenderList *rl = &render_list[p_render_list];
+ uint32_t element_total = p_max_elements >= 0 ? uint32_t(p_max_elements) : rl->elements.size();
- if (!material) {
- material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
- m_src = default_material;
- }
+ scene_state.instance_data[p_render_list].resize(p_offset + element_total);
+ rl->element_info.resize(p_offset + element_total);
- ERR_FAIL_COND(!material);
+ uint32_t repeats = 0;
+ GeometryInstanceSurfaceDataCache *prev_surface = nullptr;
+ for (uint32_t i = 0; i < element_total; i++) {
+ GeometryInstanceSurfaceDataCache *surface = rl->elements[i + p_offset];
+ GeometryInstanceForwardClustered *inst = surface->owner;
- _add_geometry_with_material(p_instance, p_surface, material, m_src, p_pass_mode, p_geometry_index, p_using_sdfgi);
+ SceneState::InstanceData &instance_data = scene_state.instance_data[p_render_list][i + p_offset];
- while (material->next_pass.is_valid()) {
- material = (MaterialData *)storage->material_get_data(material->next_pass, RendererStorageRD::SHADER_TYPE_3D);
- if (!material || !material->shader_data->valid) {
- break;
+ if (inst->store_transform_cache) {
+ RendererStorageRD::store_transform(inst->transform, instance_data.transform);
+ } else {
+ RendererStorageRD::store_transform(Transform(), instance_data.transform);
}
- _add_geometry_with_material(p_instance, p_surface, material, material->next_pass, p_pass_mode, p_geometry_index, p_using_sdfgi);
- }
-}
-void RendererSceneRenderForward::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) {
- bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;
- bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha);
- bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
- bool has_alpha = has_base_alpha || has_blend_alpha;
+ instance_data.flags = inst->flags_cache;
+ instance_data.gi_offset = inst->gi_offset_cache;
+ instance_data.layer_mask = inst->layer_mask;
+ instance_data.instance_uniforms_ofs = uint32_t(inst->shader_parameters_offset);
+ instance_data.lightmap_uv_scale[0] = inst->lightmap_uv_scale.position.x;
+ instance_data.lightmap_uv_scale[1] = inst->lightmap_uv_scale.position.y;
+ instance_data.lightmap_uv_scale[2] = inst->lightmap_uv_scale.size.x;
+ instance_data.lightmap_uv_scale[3] = inst->lightmap_uv_scale.size.y;
- if (p_material->shader_data->uses_sss) {
- scene_state.used_sss = true;
- }
+ bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid();
- if (p_material->shader_data->uses_screen_texture) {
- scene_state.used_screen_texture = true;
- }
+ if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2) {
+ //this element is the same as the previous one, count repeats to draw it using instancing
+ repeats++;
+ } else {
+ if (repeats > 0) {
+ for (uint32_t j = 1; j <= repeats; j++) {
+ rl->element_info[p_offset + i - j].repeat = j;
+ }
+ }
+ repeats = 1;
+ }
- if (p_material->shader_data->uses_depth_texture) {
- scene_state.used_depth_texture = true;
- }
+ RenderElementInfo &element_info = rl->element_info[p_offset + i];
- if (p_material->shader_data->uses_normal_texture) {
- scene_state.used_normal_texture = true;
- }
+ element_info.lod_index = surface->sort.lod_index;
+ element_info.uses_forward_gi = surface->sort.uses_forward_gi;
+ element_info.uses_lightmap = surface->sort.uses_lightmap;
- if (p_pass_mode != PASS_MODE_COLOR && p_pass_mode != PASS_MODE_COLOR_SPECULAR) {
- if (has_blend_alpha || has_read_screen_alpha || (has_base_alpha && !p_material->shader_data->uses_depth_pre_pass) || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED || p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
- //conditions in which no depth pass should be processed
- return;
+ if (cant_repeat) {
+ prev_surface = nullptr;
+ } else {
+ prev_surface = surface;
}
+ }
- if ((p_pass_mode != PASS_MODE_DEPTH_MATERIAL && p_pass_mode != PASS_MODE_SDF) && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass) {
- //shader does not use discard and does not write a vertex position, use generic material
- if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_DEPTH) {
- p_material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
- } else if ((p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) && !p_material->shader_data->uses_normal && !p_material->shader_data->uses_roughness) {
- p_material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
- }
+ if (repeats > 0) {
+ for (uint32_t j = 1; j <= repeats; j++) {
+ rl->element_info[p_offset + element_total - j].repeat = j;
}
-
- has_alpha = false;
}
- has_alpha = has_alpha || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED;
-
- RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element();
+ if (p_update_buffer) {
+ _update_instance_data_buffer(p_render_list);
+ }
+}
- if (!e) {
- return;
+void RendererSceneRenderForwardClustered::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) {
+ if (p_render_list == RENDER_LIST_OPAQUE) {
+ scene_state.used_sss = false;
+ scene_state.used_screen_texture = false;
+ scene_state.used_normal_texture = false;
+ scene_state.used_depth_texture = false;
}
+ uint32_t lightmap_captures_used = 0;
- e->instance = p_instance;
- e->material = p_material;
- e->surface_index = p_surface;
- e->sort_key = 0;
+ Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
+ near_plane.d += p_cam_projection.get_z_near();
+ float z_max = p_cam_projection.get_z_far() - p_cam_projection.get_z_near();
- if (e->material->last_pass != render_pass) {
- if (!RD::get_singleton()->uniform_set_is_valid(e->material->uniform_set)) {
- //uniform set no longer valid, probably a texture changed
- storage->material_force_update_textures(p_material_rid, RendererStorageRD::SHADER_TYPE_3D);
- }
- e->material->last_pass = render_pass;
- e->material->index = scene_state.current_material_index++;
- if (e->material->shader_data->last_pass != render_pass) {
- e->material->shader_data->last_pass = scene_state.current_material_index++;
- e->material->shader_data->index = scene_state.current_shader_index++;
+ RenderList *rl = &render_list[p_render_list];
+ _update_dirty_geometry_instances();
+
+ if (!p_append) {
+ rl->clear();
+ if (p_render_list == RENDER_LIST_OPAQUE) {
+ render_list[RENDER_LIST_ALPHA].clear(); //opaque fills alpha too
}
}
- e->geometry_index = p_geometry_index;
- e->material_index = e->material->index;
- e->uses_instancing = e->instance->base_type == RS::INSTANCE_MULTIMESH;
- e->uses_lightmap = e->instance->lightmap != nullptr || !e->instance->lightmap_sh.empty();
- e->uses_forward_gi = has_alpha && (e->instance->gi_probe_instances.size() || p_using_sdfgi);
- e->shader_index = e->shader_index;
- e->depth_layer = e->instance->depth_layer;
- e->priority = p_material->priority;
- if (p_material->shader_data->uses_time) {
- RenderingServerDefault::redraw_request();
- }
-}
+ //fill list
-void RendererSceneRenderForward::_fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, bool p_using_sdfgi) {
- scene_state.current_shader_index = 0;
- scene_state.current_material_index = 0;
- scene_state.used_sss = false;
- scene_state.used_screen_texture = false;
- scene_state.used_normal_texture = false;
- scene_state.used_depth_texture = false;
+ for (int i = 0; i < (int)p_instances.size(); i++) {
+ GeometryInstanceForwardClustered *inst = static_cast<GeometryInstanceForwardClustered *>(p_instances[i]);
- uint32_t geometry_index = 0;
+ Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
+ inst->depth = near_plane.distance_to(support_min);
+ uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
- //fill list
+ uint32_t flags = inst->base_flags; //fill flags if appropriate
- for (int i = 0; i < (int)p_instances.size(); i++) {
- InstanceBase *inst = p_instances[i];
+ bool uses_lightmap = false;
+ bool uses_gi = false;
- //add geometry for drawing
- switch (inst->base_type) {
- case RS::INSTANCE_MESH: {
- const RID *materials = nullptr;
- uint32_t surface_count;
+ if (p_render_list == RENDER_LIST_OPAQUE) {
+ //setup GI
- materials = storage->mesh_get_surface_count_and_materials(inst->base, surface_count);
- if (!materials) {
- continue; //nothing to do
+ if (inst->lightmap_instance.is_valid()) {
+ int32_t lightmap_cull_index = -1;
+ for (uint32_t j = 0; j < scene_state.lightmaps_used; j++) {
+ if (scene_state.lightmap_ids[j] == inst->lightmap_instance) {
+ lightmap_cull_index = j;
+ break;
+ }
+ }
+ if (lightmap_cull_index >= 0) {
+ inst->gi_offset_cache = inst->lightmap_slice_index << 16;
+ inst->gi_offset_cache |= lightmap_cull_index;
+ flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP;
+ if (scene_state.lightmap_has_sh[lightmap_cull_index]) {
+ flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP;
+ }
+ uses_lightmap = true;
+ } else {
+ inst->gi_offset_cache = 0xFFFFFFFF;
}
- const RID *inst_materials = inst->materials.ptr();
-
- for (uint32_t j = 0; j < surface_count; j++) {
- RID material = inst_materials[j].is_valid() ? inst_materials[j] : materials[j];
+ } else if (inst->lightmap_sh) {
+ if (lightmap_captures_used < scene_state.max_lightmap_captures) {
+ const Color *src_capture = inst->lightmap_sh->sh;
+ LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used];
+ for (int j = 0; j < 9; j++) {
+ lcd.sh[j * 4 + 0] = src_capture[j].r;
+ lcd.sh[j * 4 + 1] = src_capture[j].g;
+ lcd.sh[j * 4 + 2] = src_capture[j].b;
+ lcd.sh[j * 4 + 3] = src_capture[j].a;
+ }
+ flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE;
+ inst->gi_offset_cache = lightmap_captures_used;
+ lightmap_captures_used++;
+ uses_lightmap = true;
+ }
- uint32_t surface_index = storage->mesh_surface_get_render_pass_index(inst->base, j, render_pass, &geometry_index);
- _add_geometry(inst, j, material, p_pass_mode, surface_index, p_using_sdfgi);
+ } else if (!low_end) {
+ if (p_using_opaque_gi) {
+ flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
}
- //mesh->last_pass=frame;
+ if (inst->gi_probes[0].is_valid()) {
+ uint32_t probe0_index = 0xFFFF;
+ uint32_t probe1_index = 0xFFFF;
- } break;
+ for (uint32_t j = 0; j < scene_state.giprobes_used; j++) {
+ if (scene_state.giprobe_ids[j] == inst->gi_probes[0]) {
+ probe0_index = j;
+ } else if (scene_state.giprobe_ids[j] == inst->gi_probes[1]) {
+ probe1_index = j;
+ }
+ }
- case RS::INSTANCE_MULTIMESH: {
- if (storage->multimesh_get_instances_to_draw(inst->base) == 0) {
- //not visible, 0 instances
- continue;
- }
+ if (probe0_index == 0xFFFF && probe1_index != 0xFFFF) {
+ //0 must always exist if a probe exists
+ SWAP(probe0_index, probe1_index);
+ }
- RID mesh = storage->multimesh_get_mesh(inst->base);
- if (!mesh.is_valid()) {
- continue;
+ inst->gi_offset_cache = probe0_index | (probe1_index << 16);
+ flags |= INSTANCE_DATA_FLAG_USE_GIPROBE;
+ uses_gi = true;
+ } else {
+ if (p_using_sdfgi && inst->can_sdfgi) {
+ flags |= INSTANCE_DATA_FLAG_USE_SDFGI;
+ uses_gi = true;
+ }
+ inst->gi_offset_cache = 0xFFFFFFFF;
}
+ }
+ }
+ inst->flags_cache = flags;
- const RID *materials = nullptr;
- uint32_t surface_count;
+ GeometryInstanceSurfaceDataCache *surf = inst->surface_caches;
- materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
- if (!materials) {
- continue; //nothing to do
- }
+ while (surf) {
+ surf->sort.uses_forward_gi = 0;
+ surf->sort.uses_lightmap = 0;
- for (uint32_t j = 0; j < surface_count; j++) {
- uint32_t surface_index = storage->mesh_surface_get_multimesh_render_pass_index(mesh, j, render_pass, &geometry_index);
- _add_geometry(inst, j, materials[j], p_pass_mode, surface_index, p_using_sdfgi);
- }
+ // LOD
- } break;
-#if 0
- case RS::INSTANCE_IMMEDIATE: {
- RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base);
- ERR_CONTINUE(!immediate);
+ if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) {
+ //lod
+ Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_lod_plane.normal);
+ Vector3 lod_support_max = inst->transformed_aabb.get_support(p_lod_plane.normal);
- _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass);
+ float distance_min = p_lod_plane.distance_to(lod_support_min);
+ float distance_max = p_lod_plane.distance_to(lod_support_max);
- } break;
-#endif
- case RS::INSTANCE_PARTICLES: {
- int draw_passes = storage->particles_get_draw_passes(inst->base);
+ float distance = 0.0;
- for (int j = 0; j < draw_passes; j++) {
- RID mesh = storage->particles_get_draw_pass_mesh(inst->base, j);
- if (!mesh.is_valid())
- continue;
+ if (distance_min * distance_max < 0.0) {
+ //crossing plane
+ distance = 0.0;
+ } else if (distance_min >= 0.0) {
+ distance = distance_min;
+ } else if (distance_max <= 0.0) {
+ distance = -distance_max;
+ }
- const RID *materials = nullptr;
- uint32_t surface_count;
+ surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_lod_distance_multiplier, p_screen_lod_threshold);
+ } else {
+ surf->sort.lod_index = 0;
+ }
- materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
- if (!materials) {
- continue; //nothing to do
+ // ADD Element
+ if (p_pass_mode == PASS_MODE_COLOR) {
+ if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
+ rl->add_element(surf);
+ }
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA) {
+ render_list[RENDER_LIST_ALPHA].add_element(surf);
+ if (uses_gi) {
+ surf->sort.uses_forward_gi = 1;
}
+ }
- for (uint32_t k = 0; k < surface_count; k++) {
- uint32_t surface_index = storage->mesh_surface_get_particles_render_pass_index(mesh, j, render_pass, &geometry_index);
- _add_geometry(inst, (j << 16) | k, materials[j], p_pass_mode, surface_index, p_using_sdfgi);
- }
+ if (uses_lightmap) {
+ surf->sort.uses_lightmap = 1;
}
- } break;
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_SUBSURFACE_SCATTERING) {
+ scene_state.used_sss = true;
+ }
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_SCREEN_TEXTURE) {
+ scene_state.used_screen_texture = true;
+ }
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_NORMAL_TEXTURE) {
+ scene_state.used_normal_texture = true;
+ }
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DEPTH_TEXTURE) {
+ scene_state.used_depth_texture = true;
+ }
- default: {
+ } else if (p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) {
+ if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW) {
+ rl->add_element(surf);
+ }
+ } else {
+ if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
+ rl->add_element(surf);
+ }
}
+
+ surf->sort.depth_layer = depth_layer;
+
+ surf = surf->next;
}
}
+
+ if (p_render_list == RENDER_LIST_OPAQUE && lightmap_captures_used) {
+ RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, RD::BARRIER_MASK_RASTER);
+ }
+}
+
+void RendererSceneRenderForwardClustered::_setup_giprobes(const PagedArray<RID> &p_giprobes) {
+ scene_state.giprobes_used = MIN(p_giprobes.size(), uint32_t(MAX_GI_PROBES));
+ for (uint32_t i = 0; i < scene_state.giprobes_used; i++) {
+ scene_state.giprobe_ids[i] = p_giprobes[i];
+ }
}
-void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform) {
- uint32_t lightmaps_used = 0;
+void RendererSceneRenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) {
+ scene_state.lightmaps_used = 0;
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
if (i >= (int)scene_state.max_lightmaps) {
break;
}
- InstanceBase *lm = p_lightmaps[i];
- Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis;
+ RID lightmap = lightmap_instance_get_lightmap(p_lightmaps[i]);
+
+ Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
to_lm = to_lm.inverse().transposed(); //will transform normals
RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
- lm->lightmap_cull_index = i;
- lightmaps_used++;
+ scene_state.lightmap_ids[i] = p_lightmaps[i];
+ scene_state.lightmap_has_sh[i] = storage->lightmap_uses_spherical_harmonics(lightmap);
+
+ scene_state.lightmaps_used++;
}
- if (lightmaps_used > 0) {
- RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * lightmaps_used, scene_state.lightmaps, true);
+ if (scene_state.lightmaps_used > 0) {
+ RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps, RD::BARRIER_MASK_RASTER);
}
}
-void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
+void RendererSceneRenderForwardClustered::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
RenderBufferDataForward *render_buffer = nullptr;
if (p_render_buffer.is_valid()) {
render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer);
}
+ RendererSceneEnvironmentRD *env = get_environment(p_environment);
//first of all, make a new render pass
- render_pass++;
-
//fill up ubo
RENDER_TIMESTAMP("Setup 3D Scene");
- if (p_reflection_probe.is_valid()) {
- scene_state.ubo.reflection_multiplier = 0.0;
- } else {
- scene_state.ubo.reflection_multiplier = 1.0;
- }
-
float lod_distance_multiplier = p_cam_projection.get_lod_multiplier();
Plane lod_camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
@@ -1685,9 +1602,8 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
scene_state.ubo.viewport_size[0] = vp_he.x;
scene_state.ubo.viewport_size[1] = vp_he.y;
- scene_state.ubo.directional_light_count = p_directional_light_count;
+ scene_state.ubo.directional_light_count = 0;
- Size2 screen_pixel_size;
Size2i screen_size;
RID opaque_framebuffer;
RID opaque_specular_framebuffer;
@@ -1702,8 +1618,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
bool using_giprobe = false;
if (render_buffer) {
- screen_pixel_size.width = 1.0 / render_buffer->width;
- screen_pixel_size.height = 1.0 / render_buffer->height;
screen_size.x = render_buffer->width;
screen_size.y = render_buffer->height;
@@ -1711,7 +1625,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
if (!low_end && p_gi_probes.size() > 0) {
using_giprobe = true;
- render_buffer->ensure_gi();
}
if (!p_environment.is_valid() && using_giprobe) {
@@ -1721,7 +1634,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
if (environment_is_sdfgi_enabled(p_environment)) {
depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also giprobe
using_sdfgi = true;
- render_buffer->ensure_gi();
} else {
depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
}
@@ -1760,8 +1672,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
alpha_framebuffer = opaque_framebuffer;
} else if (p_reflection_probe.is_valid()) {
uint32_t resolution = reflection_probe_instance_get_resolution(p_reflection_probe);
- screen_pixel_size.width = 1.0 / resolution;
- screen_pixel_size.height = 1.0 / resolution;
screen_size.x = resolution;
screen_size.y = resolution;
@@ -1776,13 +1686,21 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
ERR_FAIL(); //bug?
}
+ RD::get_singleton()->draw_command_begin_label("Render Setup");
+
_setup_lightmaps(p_lightmaps, p_cam_transform);
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
+ _setup_giprobes(p_gi_probes);
+ _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
_update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
- render_list.clear();
- _fill_render_list(p_instances, PASS_MODE_COLOR, using_sdfgi);
+ _fill_render_list(RENDER_LIST_OPAQUE, p_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi, using_sdfgi || using_giprobe, lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+ render_list[RENDER_LIST_OPAQUE].sort_by_key();
+ render_list[RENDER_LIST_ALPHA].sort_by_depth();
+ _fill_instance_data(RENDER_LIST_OPAQUE);
+ _fill_instance_data(RENDER_LIST_ALPHA);
+
+ RD::get_singleton()->draw_command_end_label();
bool using_sss = !low_end && render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
@@ -1812,7 +1730,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
clear_color.b *= bg_energy;
if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) {
draw_sky_fog_only = true;
- storage->material_set_param(sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
+ storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
} break;
case RS::ENV_BG_COLOR: {
@@ -1822,7 +1740,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
clear_color.b *= bg_energy;
if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) {
draw_sky_fog_only = true;
- storage->material_set_param(sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
+ storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
} break;
case RS::ENV_BG_SKY: {
@@ -1842,6 +1760,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
// setup sky if used for ambient, reflections, or background
if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
+ RD::get_singleton()->draw_command_begin_label("Setup Sky");
CameraMatrix projection = p_cam_projection;
if (p_reflection_probe.is_valid()) {
CameraMatrix correction;
@@ -1849,67 +1768,88 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
projection = correction * p_cam_projection;
}
- _setup_sky(p_environment, p_render_buffer, projection, p_cam_transform, screen_size);
+ sky.setup(env, p_render_buffer, projection, p_cam_transform, screen_size, this);
- RID sky = environment_get_sky(p_environment);
- if (sky.is_valid()) {
- _update_sky(p_environment, projection, p_cam_transform);
- radiance_texture = sky_get_radiance_texture_rd(sky);
+ RID sky_rid = env->sky;
+ if (sky_rid.is_valid()) {
+ sky.update(env, projection, p_cam_transform, time);
+ radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
} else {
// do not try to draw sky if invalid
draw_sky = false;
}
+ RD::get_singleton()->draw_command_end_label();
}
} else {
clear_color = p_default_bg_color;
}
- RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_gi_probes);
-
- render_list.sort_by_key(false);
-
- _fill_instances(render_list.elements, render_list.element_count, false, false, using_sdfgi || using_giprobe);
-
bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION;
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
-
bool depth_pre_pass = !low_end && depth_framebuffer.is_valid();
bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment);
bool continue_depth = false;
if (depth_pre_pass) { //depth pre pass
- RENDER_TIMESTAMP("Render Depth Pre-Pass");
+
+ bool needs_pre_resolve = _needs_post_prepass_render(using_sdfgi || using_giprobe);
+ if (needs_pre_resolve) {
+ RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (parallel)");
+ } else {
+ RENDER_TIMESTAMP("Render Depth Pre-Pass");
+ }
+ if (needs_pre_resolve) {
+ //pre clear the depth framebuffer, as AMD (and maybe others?) use compute for it, and barrier other compute shaders.
+ RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
+ RD::get_singleton()->draw_list_end();
+ //start compute processes here, so they run at the same time as depth pre-pass
+ _post_prepass_render(using_sdfgi || using_giprobe);
+ }
+
+ RD::get_singleton()->draw_command_begin_label("Render Depth Pre-Pass");
+
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
bool finish_depth = using_ssao || using_sdfgi || using_giprobe;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), false, depth_pass_mode, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+ _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
+
+ RD::get_singleton()->draw_command_end_label();
+
+ if (needs_pre_resolve) {
+ _pre_resolve_render(using_sdfgi || using_giprobe);
+ }
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
RENDER_TIMESTAMP("Resolve Depth Pre-Pass");
+ RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass");
if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) {
+ if (needs_pre_resolve) {
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE);
+ }
static int texture_samples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 };
storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_giprobe ? render_buffer->giprobe_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_giprobe ? render_buffer->giprobe_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]);
} else if (finish_depth) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true);
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth);
}
+ RD::get_singleton()->draw_command_end_label();
}
continue_depth = !finish_depth;
}
- if (using_ssao) {
- _process_ssao(p_render_buffer, p_environment, render_buffer->normal_roughness_buffer, p_cam_projection);
- }
+ _pre_opaque_render(using_ssao, using_sdfgi || using_giprobe, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->giprobe_buffer : RID());
- if (using_sdfgi || using_giprobe) {
- _process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->ambient_buffer, render_buffer->reflection_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probes);
- }
+ RD::get_singleton()->draw_command_begin_label("Render Opaque Pass");
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
+ scene_state.ubo.directional_light_count = _get_render_state_directional_light_count();
+
+ _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
RENDER_TIMESTAMP("Render Opaque Pass");
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true);
+
bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
@@ -1929,17 +1869,17 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
}
RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
- RD::get_singleton()->draw_list_end();
-
+ RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+ _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
if (will_continue_color && using_separate_specular) {
// close the specular framebuffer, as it's no longer used
- draw_list = RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE);
+ RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE);
RD::get_singleton()->draw_list_end();
}
}
+ RD::get_singleton()->draw_command_end_label();
+
if (debug_giprobes) {
//debug giprobes
bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only);
@@ -1949,9 +1889,11 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
dc.set_depth_correction(true);
CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse());
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
+ RD::get_singleton()->draw_command_begin_label("Debug GIProbes");
for (int i = 0; i < (int)p_gi_probes.size(); i++) {
- _debug_giprobe(p_gi_probes[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0);
+ gi.debug_giprobe(p_gi_probes[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0);
}
+ RD::get_singleton()->draw_command_end_label();
RD::get_singleton()->draw_list_end();
}
@@ -1964,7 +1906,9 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
dc.set_depth_correction(true);
CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse());
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
+ RD::get_singleton()->draw_command_begin_label("Debug SDFGI");
_debug_sdfgi_probes(p_render_buffer, draw_list, opaque_framebuffer, cm);
+ RD::get_singleton()->draw_command_end_label();
RD::get_singleton()->draw_list_end();
}
@@ -1977,30 +1921,35 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
correction.set_depth_correction(true);
projection = correction * p_cam_projection;
}
-
- _draw_sky(can_continue_color, can_continue_depth, opaque_framebuffer, p_environment, projection, p_cam_transform);
+ RD::get_singleton()->draw_command_begin_label("Draw Sky");
+ sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, projection, p_cam_transform, time);
+ RD::get_singleton()->draw_command_end_label();
}
if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true);
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color);
if (using_separate_specular) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular, true);
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular);
}
}
if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true);
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth);
}
if (using_separate_specular) {
if (using_sss) {
RENDER_TIMESTAMP("Sub Surface Scattering");
+ RD::get_singleton()->draw_command_begin_label("Process Sub Surface Scattering");
_process_sss(p_render_buffer, p_cam_projection);
+ RD::get_singleton()->draw_command_end_label();
}
if (using_ssr) {
RENDER_TIMESTAMP("Screen Space Reflection");
+ RD::get_singleton()->draw_command_begin_label("Process Screen Space Reflections");
_process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED);
+ RD::get_singleton()->draw_command_end_label();
} else {
//just mix specular back
RENDER_TIMESTAMP("Merge Specular");
@@ -2010,119 +1959,161 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
RENDER_TIMESTAMP("Render Transparent Pass");
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
+ RD::get_singleton()->draw_command_begin_label("Render Transparent Pass");
- render_list.sort_by_reverse_depth_and_priority(true);
+ rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true);
- _fill_instances(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, using_sdfgi);
+ _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
{
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+ _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
}
+ RD::get_singleton()->draw_command_end_label();
+
+ RD::get_singleton()->draw_command_begin_label("Resolve");
+
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true);
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color);
}
-}
-void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
- RENDER_TIMESTAMP("Setup Rendering Shadow");
+ RD::get_singleton()->draw_command_end_label();
+}
+void RendererSceneRenderForwardClustered::_render_shadow_begin() {
+ scene_state.shadow_passes.clear();
+ RD::get_singleton()->draw_command_begin_label("Shadow Setup");
_update_render_base_uniform_set();
- render_pass++;
+ render_list[RENDER_LIST_SECONDARY].clear();
+ scene_state.instance_data[RENDER_LIST_SECONDARY].clear();
+}
+void RendererSceneRenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) {
+ uint32_t shadow_pass_index = scene_state.shadow_passes.size();
+
+ SceneState::ShadowPass shadow_pass;
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
- _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar, false, p_use_pancake);
+ _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake, shadow_pass_index);
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
p_screen_lod_threshold = 0.0;
}
- render_list.clear();
-
PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
- _fill_render_list(p_instances, pass_mode);
+ uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size();
+ _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_projection, p_transform, false, false, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, true);
+ uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from;
+ render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size);
+ _fill_instance_data(RENDER_LIST_SECONDARY, render_list_from, render_list_size, false);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
+ {
+ //regular forward for now
+ bool flip_cull = p_use_dp_flip;
+ if (p_flip_y) {
+ flip_cull = !flip_cull;
+ }
- RENDER_TIMESTAMP("Render Shadow");
+ shadow_pass.element_from = render_list_from;
+ shadow_pass.element_count = render_list_size;
+ shadow_pass.flip_cull = flip_cull;
+ shadow_pass.pass_mode = pass_mode;
- render_list.sort_by_key(false);
+ shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete
+ shadow_pass.camera_plane = p_camera_plane;
+ shadow_pass.screen_lod_threshold = p_screen_lod_threshold;
+ shadow_pass.lod_distance_multiplier = p_lod_distance_multiplier;
- _fill_instances(render_list.elements, render_list.element_count, true);
+ shadow_pass.framebuffer = p_framebuffer;
+ shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE);
+ shadow_pass.final_depth_action = p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE;
+ shadow_pass.rect = p_rect;
- {
- //regular forward for now
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
- RD::get_singleton()->draw_list_end();
+ scene_state.shadow_passes.push_back(shadow_pass);
}
}
-void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) {
- RENDER_TIMESTAMP("Setup Render Collider Heightfield");
+void RendererSceneRenderForwardClustered::_render_shadow_process() {
+ _update_instance_data_buffer(RENDER_LIST_SECONDARY);
+ //render shadows one after the other, so this can be done un-barriered and the driver can optimize (as well as allow us to run compute at the same time)
- _update_render_base_uniform_set();
+ for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
+ //render passes need to be configured after instance buffer is done, since they need the latest version
+ SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
+ shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>(), false, i);
+ }
- render_pass++;
+ RD::get_singleton()->draw_command_end_label();
+}
+void RendererSceneRenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
+ RD::get_singleton()->draw_command_begin_label("Shadow Render");
- scene_state.ubo.dual_paraboloid_side = 0;
+ for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
+ SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
+ RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
+ _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
+ }
+
+ if (p_barrier != RD::BARRIER_MASK_NO_BARRIER) {
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, p_barrier);
+ }
+ RD::get_singleton()->draw_command_end_label();
+}
- _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false);
+void RendererSceneRenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
+ RENDER_TIMESTAMP("Setup Render Collider Heightfield");
- render_list.clear();
+ RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield");
- PassMode pass_mode = PASS_MODE_SHADOW;
+ _update_render_base_uniform_set();
+ scene_state.ubo.dual_paraboloid_side = 0;
- _fill_render_list(p_instances, pass_mode);
+ _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
+ PassMode pass_mode = PASS_MODE_SHADOW;
- RENDER_TIMESTAMP("Render Collider Heightield");
+ _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform);
+ render_list[RENDER_LIST_SECONDARY].sort_by_key();
+ _fill_instance_data(RENDER_LIST_SECONDARY);
- render_list.sort_by_key(false);
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
- _fill_instances(render_list.elements, render_list.element_count, true);
+ RENDER_TIMESTAMP("Render Collider Heightfield");
{
//regular forward for now
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_fb), render_list.elements, render_list.element_count, false, pass_mode, true, rp_uniform_set);
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, true, rp_uniform_set);
+ _render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
}
+ RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RendererSceneRenderForwardClustered::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering Material");
- _update_render_base_uniform_set();
+ RD::get_singleton()->draw_command_begin_label("Render Material");
- render_pass++;
+ _update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
- scene_state.ubo.material_uv2_mode = true;
-
- _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
+ scene_state.ubo.material_uv2_mode = false;
- render_list.clear();
+ _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0);
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
- _fill_render_list(p_instances, pass_mode);
+ _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform);
+ render_list[RENDER_LIST_SECONDARY].sort_by_key();
+ _fill_instance_data(RENDER_LIST_SECONDARY);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Material");
- render_list.sort_by_key(false);
-
- _fill_instances(render_list.elements, render_list.element_count, true);
-
{
+ RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set);
//regular forward for now
Vector<Color> clear;
clear.push_back(Color(0, 0, 0, 0));
@@ -2131,37 +2122,36 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo
clear.push_back(Color(0, 0, 0, 0));
clear.push_back(Color(0, 0, 0, 0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set);
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count);
RD::get_singleton()->draw_list_end();
}
+
+ RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForward::_render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RendererSceneRenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering UV2");
- _update_render_base_uniform_set();
+ RD::get_singleton()->draw_command_begin_label("Render UV2");
- render_pass++;
+ _update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.material_uv2_mode = true;
- _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
-
- render_list.clear();
+ _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0);
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
- _fill_render_list(p_instances, pass_mode);
+ _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform());
+ render_list[RENDER_LIST_SECONDARY].sort_by_key();
+ _fill_instance_data(RENDER_LIST_SECONDARY);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Material");
- render_list.sort_by_key(false);
-
- _fill_instances(render_list.elements, render_list.element_count, true);
-
{
+ RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set, true);
//regular forward for now
Vector<Color> clear;
clear.push_back(Color(0, 0, 0, 0));
@@ -2189,31 +2179,32 @@ void RendererSceneRenderForward::_render_uv2(const PagedArray<InstanceBase *> &p
Vector2 ofs = uv_offsets[i];
ofs.x /= p_region.size.width;
ofs.y /= p_region.size.height;
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, true, ofs); //first wireframe, for pseudo conservative
+ render_list_params.uv_offset = ofs;
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); //first wireframe, for pseudo conservative
}
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false); //second regular triangles
+ render_list_params.uv_offset = Vector2();
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count); //second regular triangles
RD::get_singleton()->draw_list_end();
}
+
+ RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
+void RendererSceneRenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
RENDER_TIMESTAMP("Render SDFGI");
+ RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel");
+
_update_render_base_uniform_set();
RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
ERR_FAIL_COND(!render_buffer);
- render_pass++;
- render_list.clear();
-
PassMode pass_mode = PASS_MODE_SDF;
- _fill_render_list(p_instances, pass_mode);
- render_list.sort_by_key(false);
- _fill_instances(render_list.elements, render_list.element_count, true);
-
- RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture);
+ _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform());
+ render_list[RENDER_LIST_SECONDARY].sort_by_key();
+ _fill_instance_data(RENDER_LIST_SECONDARY);
Vector3 half_extents = p_bounds.size * 0.5;
Vector3 center = p_bounds.position + half_extents;
@@ -2264,7 +2255,9 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto
RendererStorageRD::store_transform(to_bounds.affine_inverse() * cam_xform, scene_state.ubo.sdf_to_bounds);
- _setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
+ _setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0);
+
+ RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture);
Map<Size2i, RID>::Element *E = sdfgi_framebuffer_size_cache.find(fb_size);
if (!E) {
@@ -2272,20 +2265,21 @@ void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vecto
E = sdfgi_framebuffer_size_cache.insert(fb_size, fb);
}
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(E->get()), render_list.elements, render_list.element_count, true, pass_mode, true, rp_uniform_set, false); //second regular triangles
- RD::get_singleton()->draw_list_end();
+ RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, rp_uniform_set, false);
+ _render_list_with_threads(&render_list_params, E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs);
}
+
+ RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForward::_base_uniforms_changed() {
+void RendererSceneRenderForwardClustered::_base_uniforms_changed() {
if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
RD::get_singleton()->free(render_base_uniform_set);
}
render_base_uniform_set = RID();
}
-void RendererSceneRenderForward::_update_render_base_uniform_set() {
+void RendererSceneRenderForwardClustered::_update_render_base_uniform_set() {
if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version())) {
if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
RD::get_singleton()->free(render_base_uniform_set);
@@ -2327,15 +2321,15 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(scene_state.uniform_buffer);
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(get_omni_light_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 4;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.ids.push_back(scene_state.instance_buffer);
+ u.ids.push_back(get_spot_light_buffer());
uniforms.push_back(u);
}
@@ -2343,48 +2337,33 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
RD::Uniform u;
u.binding = 5;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.ids.push_back(get_positional_light_buffer());
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.binding = 6;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(get_reflection_probe_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 7;
+ u.binding = 6;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(get_directional_light_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 10;
+ u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(scene_state.lightmap_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 11;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids = storage->lightmap_array_get_textures();
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 12;
+ u.binding = 8;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(scene_state.lightmap_capture_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 13;
+ u.binding = 9;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture();
u.ids.push_back(decal_atlas);
@@ -2392,7 +2371,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
}
{
RD::Uniform u;
- u.binding = 14;
+ u.binding = 10;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
u.ids.push_back(decal_atlas);
@@ -2400,7 +2379,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
}
{
RD::Uniform u;
- u.binding = 15;
+ u.binding = 11;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(get_decal_buffer());
uniforms.push_back(u);
@@ -2408,35 +2387,8 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
{
RD::Uniform u;
- u.binding = 16;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(get_cluster_builder_texture());
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 17;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.ids.push_back(get_cluster_builder_indices_buffer());
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.binding = 18;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- if (directional_shadow_get_texture().is_valid()) {
- u.ids.push_back(directional_shadow_get_texture());
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- }
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 19;
+ u.binding = 12;
u.ids.push_back(storage->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
@@ -2444,7 +2396,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
if (!low_end) {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 20;
+ u.binding = 13;
u.ids.push_back(sdfgi_get_ubo());
uniforms.push_back(u);
}
@@ -2453,10 +2405,9 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
}
}
-RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes) {
- if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
- RD::get_singleton()->free(render_pass_uniform_set);
- }
+RID RendererSceneRenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) {
+ //there should always be enough uniform buffers for render passes, otherwise bugs
+ ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID());
RenderBufferDataForward *rb = nullptr;
if (p_render_buffers.is_valid()) {
@@ -2468,6 +2419,24 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
Vector<RD::Uniform> uniforms;
{
+ RD::Uniform u;
+ u.binding = 0;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(scene_state.uniform_buffers[p_index]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ RID instance_buffer = scene_state.instance_buffer[p_render_list];
+ if (instance_buffer == RID()) {
+ instance_buffer = default_vec4_xform_buffer; // any buffer will do since its not used
+ }
+ u.ids.push_back(instance_buffer);
+ uniforms.push_back(u);
+ }
+ {
RID radiance_texture;
if (p_radiance_texture.is_valid()) {
radiance_texture = p_radiance_texture;
@@ -2475,7 +2444,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
}
RD::Uniform u;
- u.binding = 0;
+ u.binding = 2;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(radiance_texture);
uniforms.push_back(u);
@@ -2484,7 +2453,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID();
RD::Uniform u;
- u.binding = 1;
+ u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
if (ref_texture.is_valid()) {
u.ids.push_back(ref_texture);
@@ -2496,7 +2465,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RD::Uniform u;
- u.binding = 2;
+ u.binding = 4;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture;
if (p_shadow_atlas.is_valid()) {
@@ -2508,16 +2477,45 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
u.ids.push_back(texture);
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.binding = 5;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) {
+ u.ids.push_back(directional_shadow_get_texture());
+ } else {
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 6;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.resize(scene_state.max_lightmaps);
+ RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
+ for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
+ if (i < p_lightmaps.size()) {
+ RID base = lightmap_instance_get_lightmap(p_lightmaps[i]);
+ RID texture = storage->lightmap_get_texture(base);
+ RID rd_texture = storage->texture_get_rd_texture(texture);
+ u.ids.write[i] = rd_texture;
+ } else {
+ u.ids.write[i] = default_tex;
+ }
+ }
+ uniforms.push_back(u);
+ }
{
RD::Uniform u;
- u.binding = 3;
+ u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.resize(MAX_GI_PROBES);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
for (int i = 0; i < MAX_GI_PROBES; i++) {
if (i < (int)p_gi_probes.size()) {
- RID tex = gi_probe_instance_get_texture(p_gi_probes[i]);
+ RID tex = gi.gi_probe_instance_get_texture(p_gi_probes[i]);
if (!tex.is_valid()) {
tex = default_tex;
}
@@ -2532,7 +2530,16 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RD::Uniform u;
- u.binding = 4;
+ u.binding = 8;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer;
+ u.ids.push_back(cb);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.binding = 9;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
@@ -2540,17 +2547,18 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
}
{
RD::Uniform u;
- u.binding = 5;
+ u.binding = 10;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID();
RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
+
if (!low_end) {
{
RD::Uniform u;
- u.binding = 6;
+ u.binding = 11;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
u.ids.push_back(texture);
@@ -2559,7 +2567,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RD::Uniform u;
- u.binding = 7;
+ u.binding = 12;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID();
RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
@@ -2569,24 +2577,26 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RD::Uniform u;
- u.binding = 8;
+ u.binding = 13;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = rb && rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ RID ambient_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_ambient_texture(p_render_buffers) : RID();
+ RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 9;
+ u.binding = 14;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID texture = rb && rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ RID reflection_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_reflection_texture(p_render_buffers) : RID();
+ RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 10;
+ u.binding = 15;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID t;
if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
@@ -2599,7 +2609,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
}
{
RD::Uniform u;
- u.binding = 11;
+ u.binding = 16;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers));
@@ -2610,14 +2620,14 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
}
{
RD::Uniform u;
- u.binding = 12;
+ u.binding = 17;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 13;
+ u.binding = 18;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID vfog = RID();
if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) {
@@ -2633,11 +2643,19 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
}
}
- render_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET);
- return render_pass_uniform_set;
+ if (p_index >= (int)render_pass_uniform_sets.size()) {
+ render_pass_uniform_sets.resize(p_index + 1);
+ }
+
+ if (render_pass_uniform_sets[p_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[p_index])) {
+ RD::get_singleton()->free(render_pass_uniform_sets[p_index]);
+ }
+
+ render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET);
+ return render_pass_uniform_sets[p_index];
}
-RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) {
+RID RendererSceneRenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) {
if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) {
RD::get_singleton()->free(sdfgi_pass_uniform_set);
}
@@ -2645,10 +2663,24 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
Vector<RD::Uniform> uniforms;
{
+ RD::Uniform u;
+ u.binding = 0;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(scene_state.uniform_buffers[0]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(scene_state.instance_buffer[RENDER_LIST_SECONDARY]);
+ uniforms.push_back(u);
+ }
+ {
// No radiance texture.
RID radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
RD::Uniform u;
- u.binding = 0;
+ u.binding = 2;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(radiance_texture);
uniforms.push_back(u);
@@ -2658,7 +2690,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
// No reflection atlas.
RID ref_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK);
RD::Uniform u;
- u.binding = 1;
+ u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(ref_texture);
uniforms.push_back(u);
@@ -2667,7 +2699,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
{
// No shadow atlas.
RD::Uniform u;
- u.binding = 2;
+ u.binding = 4;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
@@ -2675,9 +2707,33 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
}
{
+ // No directional shadow atlas.
+ RD::Uniform u;
+ u.binding = 5;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ // No Lightmaps
+ RD::Uniform u;
+ u.binding = 6;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.resize(scene_state.max_lightmaps);
+ RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
+ for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
+ u.ids.write[i] = default_tex;
+ }
+
+ uniforms.push_back(u);
+ }
+
+ {
// No GIProbes
RD::Uniform u;
- u.binding = 3;
+ u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.resize(MAX_GI_PROBES);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
@@ -2687,33 +2743,43 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
uniforms.push_back(u);
}
+
+ {
+ RD::Uniform u;
+ u.binding = 8;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ RID cb = default_vec4_xform_buffer;
+ u.ids.push_back(cb);
+ uniforms.push_back(u);
+ }
+
// actual sdfgi stuff
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 4;
+ u.binding = 9;
u.ids.push_back(p_albedo_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 5;
+ u.binding = 10;
u.ids.push_back(p_emission_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 6;
+ u.binding = 11;
u.ids.push_back(p_emission_aniso_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 7;
+ u.binding = 12;
u.ids.push_back(p_geom_facing_texture);
uniforms.push_back(u);
}
@@ -2722,45 +2788,546 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
return sdfgi_pass_uniform_set;
}
-void RendererSceneRenderForward::_render_buffers_clear_uniform_set(RenderBufferDataForward *rb) {
+void RendererSceneRenderForwardClustered::_render_buffers_clear_uniform_set(RenderBufferDataForward *rb) {
}
-void RendererSceneRenderForward::_render_buffers_uniform_set_changed(RID p_render_buffers) {
+void RendererSceneRenderForwardClustered::_render_buffers_uniform_set_changed(RID p_render_buffers) {
RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
_render_buffers_clear_uniform_set(rb);
}
-RID RendererSceneRenderForward::_render_buffers_get_normal_texture(RID p_render_buffers) {
+RID RendererSceneRenderForwardClustered::_render_buffers_get_normal_texture(RID p_render_buffers) {
RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
return rb->normal_roughness_buffer;
}
-RID RendererSceneRenderForward::_render_buffers_get_ambient_texture(RID p_render_buffers) {
- RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+RendererSceneRenderForwardClustered *RendererSceneRenderForwardClustered::singleton = nullptr;
+
+void RendererSceneRenderForwardClustered::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ if (ginstance->dirty_list_element.in_list()) {
+ return;
+ }
+
+ //clear surface caches
+ GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches;
- return rb->ambient_buffer;
+ while (surf) {
+ GeometryInstanceSurfaceDataCache *next = surf->next;
+ geometry_instance_surface_alloc.free(surf);
+ surf = next;
+ }
+
+ ginstance->surface_caches = nullptr;
+
+ geometry_instance_dirty_list.add(&ginstance->dirty_list_element);
}
-RID RendererSceneRenderForward::_render_buffers_get_reflection_texture(RID p_render_buffers) {
- RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+void RendererSceneRenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) {
+ bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;
+ bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha);
+ bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
+ bool has_alpha = has_base_alpha || has_blend_alpha;
+
+ uint32_t flags = 0;
+
+ if (p_material->shader_data->uses_sss) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SUBSURFACE_SCATTERING;
+ }
+
+ if (p_material->shader_data->uses_screen_texture) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SCREEN_TEXTURE;
+ }
+
+ if (p_material->shader_data->uses_depth_texture) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DEPTH_TEXTURE;
+ }
+
+ if (p_material->shader_data->uses_normal_texture) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_NORMAL_TEXTURE;
+ }
+
+ if (ginstance->data->cast_double_sided_shadows) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS;
+ }
+
+ if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED) {
+ //material is only meant for alpha pass
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA;
+ if (p_material->shader_data->uses_depth_pre_pass && !(p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED)) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH;
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
+ }
+ } else {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE;
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH;
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
+ }
+
+ MaterialData *material_shadow = nullptr;
+ void *surface_shadow = nullptr;
+ if (!p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass) {
+ flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL;
+ material_shadow = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
- return rb->reflection_buffer;
+ RID shadow_mesh = storage->mesh_get_shadow_mesh(p_mesh);
+
+ if (shadow_mesh.is_valid()) {
+ surface_shadow = storage->mesh_get_surface(shadow_mesh, p_surface);
+ }
+
+ } else {
+ material_shadow = p_material;
+ }
+
+ GeometryInstanceSurfaceDataCache *sdcache = geometry_instance_surface_alloc.alloc();
+
+ sdcache->flags = flags;
+
+ sdcache->shader = p_material->shader_data;
+ sdcache->material_uniform_set = p_material->uniform_set;
+ sdcache->surface = storage->mesh_get_surface(p_mesh, p_surface);
+ sdcache->primitive = storage->mesh_surface_get_primitive(sdcache->surface);
+ sdcache->surface_index = p_surface;
+
+ if (ginstance->data->dirty_dependencies) {
+ storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
+ }
+
+ //shadow
+ sdcache->shader_shadow = material_shadow->shader_data;
+ sdcache->material_uniform_set_shadow = material_shadow->uniform_set;
+
+ sdcache->surface_shadow = surface_shadow ? surface_shadow : sdcache->surface;
+
+ sdcache->owner = ginstance;
+
+ sdcache->next = ginstance->surface_caches;
+ ginstance->surface_caches = sdcache;
+
+ //sortkey
+
+ sdcache->sort.sort_key1 = 0;
+ sdcache->sort.sort_key2 = 0;
+
+ sdcache->sort.surface_index = p_surface;
+ sdcache->sort.material_id_low = p_material_id & 0x3FFF;
+ sdcache->sort.material_id_hi = p_material_id >> 14;
+ sdcache->sort.shader_id = p_shader_id;
+ sdcache->sort.geometry_id = p_mesh.get_local_index(); //only meshes can repeat anyway
+ sdcache->sort.uses_forward_gi = ginstance->can_sdfgi;
+ sdcache->sort.priority = p_material->priority;
+}
+
+void RendererSceneRenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {
+ RID m_src;
+
+ m_src = ginstance->data->material_override.is_valid() ? ginstance->data->material_override : p_material;
+
+ MaterialData *material = nullptr;
+
+ if (m_src.is_valid()) {
+ material = (MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
+ if (!material || !material->shader_data->valid) {
+ material = nullptr;
+ }
+ }
+
+ if (material) {
+ if (ginstance->data->dirty_dependencies) {
+ storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
+ }
+ } else {
+ material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
+ m_src = default_material;
+ }
+
+ ERR_FAIL_COND(!material);
+
+ _geometry_instance_add_surface_with_material(ginstance, p_surface, material, m_src.get_local_index(), storage->material_get_shader_id(m_src), p_mesh);
+
+ while (material->next_pass.is_valid()) {
+ RID next_pass = material->next_pass;
+ material = (MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
+ if (!material || !material->shader_data->valid) {
+ break;
+ }
+ if (ginstance->data->dirty_dependencies) {
+ storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
+ }
+ _geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), storage->material_get_shader_id(next_pass), p_mesh);
+ }
+}
+
+void RendererSceneRenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geometry_instance) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+
+ if (ginstance->data->dirty_dependencies) {
+ ginstance->data->dependency_tracker.update_begin();
+ }
+
+ //add geometry for drawing
+ switch (ginstance->data->base_type) {
+ case RS::INSTANCE_MESH: {
+ const RID *materials = nullptr;
+ uint32_t surface_count;
+ RID mesh = ginstance->data->base;
+
+ materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
+ if (materials) {
+ //if no materials, no surfaces.
+ const RID *inst_materials = ginstance->data->surface_materials.ptr();
+ uint32_t surf_mat_count = ginstance->data->surface_materials.size();
+
+ for (uint32_t j = 0; j < surface_count; j++) {
+ RID material = (j < surf_mat_count && inst_materials[j].is_valid()) ? inst_materials[j] : materials[j];
+ _geometry_instance_add_surface(ginstance, j, material, mesh);
+ }
+ }
+
+ ginstance->instance_count = 1;
+
+ } break;
+
+ case RS::INSTANCE_MULTIMESH: {
+ RID mesh = storage->multimesh_get_mesh(ginstance->data->base);
+ if (mesh.is_valid()) {
+ const RID *materials = nullptr;
+ uint32_t surface_count;
+
+ materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
+ if (materials) {
+ for (uint32_t j = 0; j < surface_count; j++) {
+ _geometry_instance_add_surface(ginstance, j, materials[j], mesh);
+ }
+ }
+
+ ginstance->instance_count = storage->multimesh_get_instances_to_draw(ginstance->data->base);
+ }
+
+ } break;
+#if 0
+ case RS::INSTANCE_IMMEDIATE: {
+ RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base);
+ ERR_CONTINUE(!immediate);
+
+ _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass);
+
+ } break;
+#endif
+ case RS::INSTANCE_PARTICLES: {
+ int draw_passes = storage->particles_get_draw_passes(ginstance->data->base);
+
+ for (int j = 0; j < draw_passes; j++) {
+ RID mesh = storage->particles_get_draw_pass_mesh(ginstance->data->base, j);
+ if (!mesh.is_valid())
+ continue;
+
+ const RID *materials = nullptr;
+ uint32_t surface_count;
+
+ materials = storage->mesh_get_surface_count_and_materials(mesh, surface_count);
+ if (materials) {
+ for (uint32_t k = 0; k < surface_count; k++) {
+ _geometry_instance_add_surface(ginstance, k, materials[k], mesh);
+ }
+ }
+ }
+
+ ginstance->instance_count = storage->particles_get_amount(ginstance->data->base);
+
+ } break;
+
+ default: {
+ }
+ }
+
+ //Fill push constant
+
+ bool store_transform = true;
+
+ if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;
+ uint32_t stride;
+ if (storage->multimesh_get_transform_format(ginstance->data->base) == RS::MULTIMESH_TRANSFORM_2D) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
+ stride = 2;
+ } else {
+ stride = 3;
+ }
+ if (storage->multimesh_uses_colors(ginstance->data->base)) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
+ stride += 1;
+ }
+ if (storage->multimesh_uses_custom_data(ginstance->data->base)) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
+ stride += 1;
+ }
+
+ ginstance->base_flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
+ ginstance->transforms_uniform_set = storage->multimesh_get_3d_uniform_set(ginstance->data->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+
+ } else if (ginstance->data->base_type == RS::INSTANCE_PARTICLES) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;
+ uint32_t stride;
+ if (false) { // 2D particles
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;
+ stride = 2;
+ } else {
+ stride = 3;
+ }
+
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;
+ stride += 1;
+
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;
+ stride += 1;
+
+ ginstance->base_flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
+
+ if (!storage->particles_is_using_local_coords(ginstance->data->base)) {
+ store_transform = false;
+ }
+ ginstance->transforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+
+ } else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
+ if (storage->skeleton_is_valid(ginstance->data->skeleton)) {
+ ginstance->base_flags |= INSTANCE_DATA_FLAG_SKELETON;
+ ginstance->transforms_uniform_set = storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ if (ginstance->data->dirty_dependencies) {
+ storage->skeleton_update_dependency(ginstance->data->skeleton, &ginstance->data->dependency_tracker);
+ }
+ }
+ }
+
+ ginstance->store_transform_cache = store_transform;
+ ginstance->can_sdfgi = false;
+
+ if (!lightmap_instance_is_valid(ginstance->lightmap_instance) && !low_end) {
+ if (ginstance->gi_probes[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) {
+ ginstance->can_sdfgi = true;
+ }
+ }
+
+ if (ginstance->data->dirty_dependencies) {
+ ginstance->data->dependency_tracker.update_end();
+ ginstance->data->dirty_dependencies = false;
+ }
+
+ ginstance->dirty_list_element.remove_from_list();
+}
+
+void RendererSceneRenderForwardClustered::_update_dirty_geometry_instances() {
+ while (geometry_instance_dirty_list.first()) {
+ _geometry_instance_update(geometry_instance_dirty_list.first()->self());
+ }
+}
+
+void RendererSceneRenderForwardClustered::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
+ switch (p_notification) {
+ case RendererStorage::DEPENDENCY_CHANGED_MATERIAL:
+ case RendererStorage::DEPENDENCY_CHANGED_MESH:
+ case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
+ case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: {
+ static_cast<RendererSceneRenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
+ } break;
+ case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata);
+ if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
+ ginstance->instance_count = static_cast<RendererSceneRenderForwardClustered *>(singleton)->storage->multimesh_get_instances_to_draw(ginstance->data->base);
+ }
+ } break;
+ default: {
+ //rest of notifications of no interest
+ } break;
+ }
+}
+void RendererSceneRenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
+ static_cast<RendererSceneRenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
+}
+
+RendererSceneRender::GeometryInstance *RendererSceneRenderForwardClustered::geometry_instance_create(RID p_base) {
+ RS::InstanceType type = storage->get_base_type(p_base);
+ ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
+
+ GeometryInstanceForwardClustered *ginstance = geometry_instance_alloc.alloc();
+ ginstance->data = memnew(GeometryInstanceForwardClustered::Data);
+
+ ginstance->data->base = p_base;
+ ginstance->data->base_type = type;
+ ginstance->data->dependency_tracker.userdata = ginstance;
+ ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed;
+ ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted;
+
+ _geometry_instance_mark_dirty(ginstance);
+
+ return ginstance;
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->skeleton = p_skeleton;
+ _geometry_instance_mark_dirty(ginstance);
+ ginstance->data->dirty_dependencies = true;
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->material_override = p_override;
+ _geometry_instance_mark_dirty(ginstance);
+ ginstance->data->dirty_dependencies = true;
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->surface_materials = p_materials;
+ _geometry_instance_mark_dirty(ginstance);
+ ginstance->data->dirty_dependencies = true;
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->mesh_instance = p_mesh_instance;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->transform = p_transform;
+ ginstance->mirror = p_transform.basis.determinant() < 0;
+ ginstance->data->aabb = p_aabb;
+ ginstance->transformed_aabb = p_transformed_aabb;
+
+ Vector3 model_scale_vec = p_transform.basis.get_scale_abs();
+ // handle non uniform scale here
+
+ float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z));
+ float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z));
+ ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9;
+
+ ginstance->lod_model_scale = max_scale;
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->lod_bias = p_lod_bias;
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->use_baked_light = p_enable;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->data->use_dynamic_gi = p_enable;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->lightmap_instance = p_lightmap_instance;
+ ginstance->lightmap_uv_scale = p_lightmap_uv_scale;
+ ginstance->lightmap_slice_index = p_lightmap_slice_index;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ if (p_sh9) {
+ if (ginstance->lightmap_sh == nullptr) {
+ ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc();
+ }
+
+ copymem(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9);
+ } else {
+ if (ginstance->lightmap_sh != nullptr) {
+ geometry_instance_lightmap_sh.free(ginstance->lightmap_sh);
+ ginstance->lightmap_sh = nullptr;
+ }
+ }
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->shader_parameters_offset = p_offset;
+ _geometry_instance_mark_dirty(ginstance);
+}
+void RendererSceneRenderForwardClustered::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+
+ ginstance->data->cast_double_sided_shadows = p_enable;
+ _geometry_instance_mark_dirty(ginstance);
+}
+
+void RendererSceneRenderForwardClustered::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ ginstance->layer_mask = p_layer_mask;
+}
+
+void RendererSceneRenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry_instance) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ if (ginstance->lightmap_sh != nullptr) {
+ geometry_instance_lightmap_sh.free(ginstance->lightmap_sh);
+ }
+ GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches;
+ while (surf) {
+ GeometryInstanceSurfaceDataCache *next = surf->next;
+ geometry_instance_surface_alloc.free(surf);
+ surf = next;
+ }
+ memdelete(ginstance->data);
+ geometry_instance_alloc.free(ginstance);
}
-RendererSceneRenderForward *RendererSceneRenderForward::singleton = nullptr;
+uint32_t RendererSceneRenderForwardClustered::geometry_instance_get_pair_mask() {
+ return (1 << RS::INSTANCE_GI_PROBE);
+}
+void RendererSceneRenderForwardClustered::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) {
+}
+void RendererSceneRenderForwardClustered::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
+}
+void RendererSceneRenderForwardClustered::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) {
+}
-void RendererSceneRenderForward::set_time(double p_time, double p_step) {
- time = p_time;
- RendererSceneRenderRD::set_time(p_time, p_step);
+Transform RendererSceneRenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance);
+ ERR_FAIL_COND_V(!ginstance, Transform());
+ return ginstance->transform;
+}
+AABB RendererSceneRenderForwardClustered::geometry_instance_get_aabb(GeometryInstance *p_instance) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance);
+ ERR_FAIL_COND_V(!ginstance, AABB());
+ return ginstance->data->aabb;
}
-RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_storage) :
+void RendererSceneRenderForwardClustered::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) {
+ GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
+ ERR_FAIL_COND(!ginstance);
+ if (p_gi_probe_instance_count > 0) {
+ ginstance->gi_probes[0] = p_gi_probe_instances[0];
+ } else {
+ ginstance->gi_probes[0] = RID();
+ }
+
+ if (p_gi_probe_instance_count > 1) {
+ ginstance->gi_probes[1] = p_gi_probe_instances[1];
+ } else {
+ ginstance->gi_probes[1] = RID();
+ }
+}
+
+RendererSceneRenderForwardClustered::RendererSceneRenderForwardClustered(RendererStorageRD *p_storage) :
RendererSceneRenderRD(p_storage) {
singleton = this;
low_end = is_low_end();
- storage = p_storage;
/* SCENE SHADER */
@@ -2774,16 +3341,15 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
if (is_using_radiance_cubemap_array()) {
defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";
}
- defines += "\n#define SDFGI_OCT_SIZE " + itos(sdfgi_get_lightprobe_octahedron_size()) + "\n";
+ defines += "\n#define SDFGI_OCT_SIZE " + itos(gi.sdfgi_get_lightprobe_octahedron_size()) + "\n";
defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(get_max_directional_lights()) + "\n";
{
//lightmaps
- scene_state.max_lightmaps = storage->lightmap_array_get_size();
+ scene_state.max_lightmaps = low_end ? 2 : MAX_LIGHTMAPS;
defines += "\n#define MAX_LIGHTMAP_TEXTURES " + itos(scene_state.max_lightmaps) + "\n";
defines += "\n#define MAX_LIGHTMAPS " + itos(scene_state.max_lightmaps) + "\n";
- scene_state.lightmaps = memnew_arr(LightmapData, scene_state.max_lightmaps);
scene_state.lightmap_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapData) * scene_state.max_lightmaps);
}
{
@@ -2860,8 +3426,8 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
actions.renames["FRAGCOORD"] = "gl_FragCoord";
actions.renames["FRONT_FACING"] = "gl_FrontFacing";
- actions.renames["NORMALMAP"] = "normalmap";
- actions.renames["NORMALMAP_DEPTH"] = "normaldepth";
+ actions.renames["NORMAL_MAP"] = "normal_map";
+ actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
actions.renames["ALBEDO"] = "albedo";
actions.renames["ALPHA"] = "alpha";
actions.renames["METALLIC"] = "metallic";
@@ -2928,8 +3494,8 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n";
actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n";
actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n";
- actions.usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
- actions.usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
+ actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
+ actions.usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP";
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
@@ -2958,7 +3524,7 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
actions.render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
actions.render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
- bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley");
+ bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley");
if (!force_lambert) {
actions.render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
@@ -2970,7 +3536,7 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n";
- bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx");
+ bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx");
if (!force_blinn) {
actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
@@ -2996,29 +3562,18 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
actions.global_buffer_array_variable = "global_variables.data";
- actions.instance_uniform_index_variable = "instances.data[instance_index].instance_uniforms_ofs";
+ actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs";
shader.compiler.initialize(actions);
}
- //render list
- render_list.max_elements = GLOBAL_DEF_RST("rendering/limits/rendering/max_renderable_elements", (int)128000);
- render_list.init();
- render_pass = 0;
-
- {
- scene_state.max_instances = render_list.max_elements;
- scene_state.instances = memnew_arr(InstanceData, scene_state.max_instances);
- scene_state.instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(InstanceData) * scene_state.max_instances);
- }
-
- scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
-
{
//default material and shader
- default_shader = storage->shader_create();
+ default_shader = storage->shader_allocate();
+ storage->shader_initialize(default_shader);
storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n");
- default_material = storage->material_create();
+ default_material = storage->material_allocate();
+ storage->material_initialize(default_material);
storage->material_set_shader(default_material, default_shader);
MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
@@ -3029,14 +3584,18 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
}
{
- overdraw_material_shader = storage->shader_create();
+ overdraw_material_shader = storage->shader_allocate();
+ storage->shader_initialize(overdraw_material_shader);
storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
- overdraw_material = storage->material_create();
+ overdraw_material = storage->material_allocate();
+ storage->material_initialize(overdraw_material);
storage->material_set_shader(overdraw_material, overdraw_material_shader);
- wireframe_material_shader = storage->shader_create();
+ wireframe_material_shader = storage->shader_allocate();
+ storage->shader_initialize(wireframe_material_shader);
storage->shader_set_code(wireframe_material_shader, "shader_type spatial;\nrender_mode wireframe,unshaded;\n void fragment() { ALBEDO=vec3(0.0,0.0,0.0); }");
- wireframe_material = storage->material_create();
+ wireframe_material = storage->material_allocate();
+ storage->material_initialize(wireframe_material);
storage->material_set_shader(wireframe_material, wireframe_material_shader);
}
@@ -3059,14 +3618,18 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
sampler.compare_op = RD::COMPARE_OP_LESS;
shadow_sampler = RD::get_singleton()->sampler_create(sampler);
}
+
+ render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances");
}
-RendererSceneRenderForward::~RendererSceneRenderForward() {
+RendererSceneRenderForwardClustered::~RendererSceneRenderForwardClustered() {
directional_shadow_atlas_set_size(0);
//clear base uniform set if still valid
- if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
- RD::get_singleton()->free(render_pass_uniform_set);
+ for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) {
+ if (render_pass_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[i])) {
+ RD::get_singleton()->free(render_pass_uniform_sets[i]);
+ }
}
if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) {
@@ -3085,12 +3648,16 @@ RendererSceneRenderForward::~RendererSceneRenderForward() {
storage->free(default_material);
{
- RD::get_singleton()->free(scene_state.uniform_buffer);
- RD::get_singleton()->free(scene_state.instance_buffer);
+ for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) {
+ RD::get_singleton()->free(scene_state.uniform_buffers[i]);
+ }
RD::get_singleton()->free(scene_state.lightmap_buffer);
RD::get_singleton()->free(scene_state.lightmap_capture_buffer);
- memdelete_arr(scene_state.instances);
- memdelete_arr(scene_state.lightmaps);
+ for (uint32_t i = 0; i < RENDER_LIST_MAX; i++) {
+ if (scene_state.instance_buffer[i] != RID()) {
+ RD::get_singleton()->free(scene_state.instance_buffer[i]);
+ }
+ }
memdelete_arr(scene_state.lightmap_captures);
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h b/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h
new file mode 100644
index 0000000000..98e2a7efcc
--- /dev/null
+++ b/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h
@@ -0,0 +1,766 @@
+/*************************************************************************/
+/* renderer_scene_render_forward_clustered.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H
+#define RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H
+
+#include "core/templates/paged_allocator.h"
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
+
+class RendererSceneRenderForwardClustered : public RendererSceneRenderRD {
+ enum {
+ SCENE_UNIFORM_SET = 0,
+ RENDER_PASS_UNIFORM_SET = 1,
+ TRANSFORMS_UNIFORM_SET = 2,
+ MATERIAL_UNIFORM_SET = 3
+ };
+
+ enum {
+ SDFGI_MAX_CASCADES = 8,
+ MAX_GI_PROBES = 8,
+ MAX_LIGHTMAPS = 8,
+ MAX_GI_PROBES_PER_INSTANCE = 2,
+ INSTANCE_DATA_BUFFER_MIN_SIZE = 4096
+ };
+
+ enum RenderListType {
+ RENDER_LIST_OPAQUE, //used for opaque objects
+ RENDER_LIST_ALPHA, //used for transparent objects
+ RENDER_LIST_SECONDARY, //used for shadows and other objects
+ RENDER_LIST_MAX
+
+ };
+
+ /* Scene Shader */
+
+ enum ShaderVersion {
+ SHADER_VERSION_DEPTH_PASS,
+ SHADER_VERSION_DEPTH_PASS_DP,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE,
+ SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
+ SHADER_VERSION_DEPTH_PASS_WITH_SDF,
+ SHADER_VERSION_COLOR_PASS,
+ SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI,
+ SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_MAX
+ };
+
+ struct {
+ SceneForwardClusteredShaderRD scene_shader;
+ ShaderCompilerRD compiler;
+ } shader;
+
+ /* Material */
+
+ struct ShaderData : public RendererStorageRD::ShaderData {
+ enum BlendMode { //used internally
+ BLEND_MODE_MIX,
+ BLEND_MODE_ADD,
+ BLEND_MODE_SUB,
+ BLEND_MODE_MUL,
+ BLEND_MODE_ALPHA_TO_COVERAGE
+ };
+
+ enum DepthDraw {
+ DEPTH_DRAW_DISABLED,
+ DEPTH_DRAW_OPAQUE,
+ DEPTH_DRAW_ALWAYS
+ };
+
+ enum DepthTest {
+ DEPTH_TEST_DISABLED,
+ DEPTH_TEST_ENABLED
+ };
+
+ enum Cull {
+ CULL_DISABLED,
+ CULL_FRONT,
+ CULL_BACK
+ };
+
+ enum CullVariant {
+ CULL_VARIANT_NORMAL,
+ CULL_VARIANT_REVERSED,
+ CULL_VARIANT_DOUBLE_SIDED,
+ CULL_VARIANT_MAX
+
+ };
+
+ enum AlphaAntiAliasing {
+ ALPHA_ANTIALIASING_OFF,
+ ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
+ ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE
+ };
+
+ bool valid;
+ RID version;
+ uint32_t vertex_input_mask;
+ PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
+
+ String path;
+
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String code;
+ Map<StringName, RID> default_texture_params;
+
+ DepthDraw depth_draw;
+ DepthTest depth_test;
+
+ bool uses_point_size;
+ bool uses_alpha;
+ bool uses_blend_alpha;
+ bool uses_alpha_clip;
+ bool uses_depth_pre_pass;
+ bool uses_discard;
+ bool uses_roughness;
+ bool uses_normal;
+
+ bool unshaded;
+ bool uses_vertex;
+ bool uses_sss;
+ bool uses_transmittance;
+ bool uses_screen_texture;
+ bool uses_depth_texture;
+ bool uses_normal_texture;
+ bool uses_time;
+ bool writes_modelview_or_projection;
+ bool uses_world_coordinates;
+
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
+
+ virtual bool is_param_texture(const StringName &p_param) const;
+ virtual bool is_animated() const;
+ virtual bool casts_shadows() const;
+ virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ virtual RS::ShaderNativeSourceCode get_native_source_code() const;
+
+ ShaderData();
+ virtual ~ShaderData();
+ };
+
+ RendererStorageRD::ShaderData *_create_shader_func();
+ static RendererStorageRD::ShaderData *_create_shader_funcs() {
+ return static_cast<RendererSceneRenderForwardClustered *>(singleton)->_create_shader_func();
+ }
+
+ struct MaterialData : public RendererStorageRD::MaterialData {
+ uint64_t last_frame;
+ ShaderData *shader_data;
+ RID uniform_buffer;
+ RID uniform_set;
+ Vector<RID> texture_cache;
+ Vector<uint8_t> ubo_data;
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+ RID next_pass;
+ uint8_t priority;
+ virtual void set_render_priority(int p_priority);
+ virtual void set_next_pass(RID p_pass);
+ virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual ~MaterialData();
+ };
+
+ RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
+ static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
+ return static_cast<RendererSceneRenderForwardClustered *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
+ }
+
+ /* Framebuffer */
+
+ struct RenderBufferDataForward : public RenderBufferData {
+ //for rendering, may be MSAAd
+
+ RID color;
+ RID depth;
+ RID specular;
+ RID normal_roughness_buffer;
+ RID giprobe_buffer;
+
+ RS::ViewportMSAA msaa;
+ RD::TextureSamples texture_samples;
+
+ RID color_msaa;
+ RID depth_msaa;
+ RID specular_msaa;
+ RID normal_roughness_buffer_msaa;
+ RID roughness_buffer_msaa;
+ RID giprobe_buffer_msaa;
+
+ RID depth_fb;
+ RID depth_normal_roughness_fb;
+ RID depth_normal_roughness_giprobe_fb;
+ RID color_fb;
+ RID color_specular_fb;
+ RID specular_only_fb;
+ int width, height;
+
+ RID render_sdfgi_uniform_set;
+ void ensure_specular();
+ void ensure_giprobe();
+ void clear();
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
+
+ ~RenderBufferDataForward();
+ };
+
+ virtual RenderBufferData *_create_render_buffer_data();
+ void _allocate_normal_roughness_texture(RenderBufferDataForward *rb);
+
+ RID shadow_sampler;
+ RID render_base_uniform_set;
+ LocalVector<RID> render_pass_uniform_sets;
+ RID sdfgi_pass_uniform_set;
+
+ uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
+
+ virtual void _base_uniforms_changed();
+ void _render_buffers_clear_uniform_set(RenderBufferDataForward *rb);
+ virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
+ virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
+
+ void _update_render_base_uniform_set();
+ RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
+ RID _setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false, int p_index = 0);
+
+ enum PassMode {
+ PASS_MODE_COLOR,
+ PASS_MODE_COLOR_SPECULAR,
+ PASS_MODE_COLOR_TRANSPARENT,
+ PASS_MODE_SHADOW,
+ PASS_MODE_SHADOW_DP,
+ PASS_MODE_DEPTH,
+ PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
+ PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE,
+ PASS_MODE_DEPTH_MATERIAL,
+ PASS_MODE_SDF,
+ };
+
+ struct GeometryInstanceSurfaceDataCache;
+ struct RenderElementInfo;
+
+ struct RenderListParameters {
+ GeometryInstanceSurfaceDataCache **elements = nullptr;
+ RenderElementInfo *element_info = nullptr;
+ int element_count = 0;
+ bool reverse_cull = false;
+ PassMode pass_mode = PASS_MODE_COLOR;
+ bool no_gi = false;
+ RID render_pass_uniform_set;
+ bool force_wireframe = false;
+ Vector2 uv_offset;
+ Plane lod_plane;
+ float lod_distance_multiplier = 0.0;
+ float screen_lod_threshold = 0.0;
+ RD::FramebufferFormatID framebuffer_format = 0;
+ uint32_t element_offset = 0;
+ uint32_t barrier = RD::BARRIER_MASK_ALL;
+
+ RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
+ elements = p_elements;
+ element_info = p_element_info;
+ element_count = p_element_count;
+ reverse_cull = p_reverse_cull;
+ pass_mode = p_pass_mode;
+ no_gi = p_no_gi;
+ render_pass_uniform_set = p_render_pass_uniform_set;
+ force_wireframe = p_force_wireframe;
+ uv_offset = p_uv_offset;
+ lod_plane = p_lod_plane;
+ lod_distance_multiplier = p_lod_distance_multiplier;
+ screen_lod_threshold = p_screen_lod_threshold;
+ element_offset = p_element_offset;
+ barrier = p_barrier;
+ }
+ };
+
+ struct LightmapData {
+ float normal_xform[12];
+ };
+
+ struct LightmapCaptureData {
+ float sh[9 * 4];
+ };
+
+ enum {
+ INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
+ INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7,
+ INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
+ INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
+ INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
+ INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11,
+ INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
+ INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
+ INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
+ INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
+ INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT = 16,
+ INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_MASK = 0x7,
+ INSTANCE_DATA_FLAG_SKELETON = 1 << 19,
+ };
+
+ struct SceneState {
+ struct UBO {
+ float projection_matrix[16];
+ float inv_projection_matrix[16];
+
+ float camera_matrix[16];
+ float inv_camera_matrix[16];
+
+ float viewport_size[2];
+ float screen_pixel_size[2];
+
+ uint32_t cluster_shift;
+ uint32_t cluster_width;
+ uint32_t cluster_type_size;
+ uint32_t max_cluster_element_count_div_32;
+
+ float directional_penumbra_shadow_kernel[128]; //32 vec4s
+ float directional_soft_shadow_kernel[128];
+ float penumbra_shadow_kernel[128];
+ float soft_shadow_kernel[128];
+
+ uint32_t directional_penumbra_shadow_samples;
+ uint32_t directional_soft_shadow_samples;
+ uint32_t penumbra_shadow_samples;
+ uint32_t soft_shadow_samples;
+
+ float ambient_light_color_energy[4];
+
+ float ambient_color_sky_mix;
+ uint32_t use_ambient_light;
+ uint32_t use_ambient_cubemap;
+ uint32_t use_reflection_cubemap;
+
+ float radiance_inverse_xform[12];
+
+ float shadow_atlas_pixel_size[2];
+ float directional_shadow_pixel_size[2];
+
+ uint32_t directional_light_count;
+ float dual_paraboloid_side;
+ float z_far;
+ float z_near;
+
+ uint32_t ssao_enabled;
+ float ssao_light_affect;
+ float ssao_ao_affect;
+ uint32_t roughness_limiter_enabled;
+
+ float roughness_limiter_amount;
+ float roughness_limiter_limit;
+ uint32_t roughness_limiter_pad[2];
+
+ float ao_color[4];
+
+ float sdf_to_bounds[16];
+
+ int32_t sdf_offset[3];
+ uint32_t material_uv2_mode;
+
+ int32_t sdf_size[3];
+ uint32_t gi_upscale_for_msaa;
+
+ uint32_t volumetric_fog_enabled;
+ float volumetric_fog_inv_length;
+ float volumetric_fog_detail_spread;
+ uint32_t volumetric_fog_pad;
+
+ // Fog
+ uint32_t fog_enabled;
+ float fog_density;
+ float fog_height;
+ float fog_height_density;
+
+ float fog_light_color[3];
+ float fog_sun_scatter;
+
+ float fog_aerial_perspective;
+
+ float time;
+ float reflection_multiplier;
+
+ uint32_t pancake_shadows;
+ };
+
+ struct PushConstant {
+ uint32_t base_index; //
+ uint32_t uv_offset; //packed
+ uint32_t pad[2];
+ };
+
+ struct InstanceData {
+ float transform[16];
+ uint32_t flags;
+ uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables
+ uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index)
+ uint32_t layer_mask;
+ float lightmap_uv_scale[4];
+ };
+
+ UBO ubo;
+
+ LocalVector<RID> uniform_buffers;
+
+ LightmapData lightmaps[MAX_LIGHTMAPS];
+ RID lightmap_ids[MAX_LIGHTMAPS];
+ bool lightmap_has_sh[MAX_LIGHTMAPS];
+ uint32_t lightmaps_used = 0;
+ uint32_t max_lightmaps;
+ RID lightmap_buffer;
+
+ RID instance_buffer[RENDER_LIST_MAX];
+ uint32_t instance_buffer_size[RENDER_LIST_MAX] = { 0, 0, 0 };
+ LocalVector<InstanceData> instance_data[RENDER_LIST_MAX];
+
+ LightmapCaptureData *lightmap_captures;
+ uint32_t max_lightmap_captures;
+ RID lightmap_capture_buffer;
+
+ RID giprobe_ids[MAX_GI_PROBES];
+ uint32_t giprobes_used = 0;
+
+ bool used_screen_texture = false;
+ bool used_normal_texture = false;
+ bool used_depth_texture = false;
+ bool used_sss = false;
+
+ struct ShadowPass {
+ uint32_t element_from;
+ uint32_t element_count;
+ bool flip_cull;
+ PassMode pass_mode;
+
+ RID rp_uniform_set;
+ Plane camera_plane;
+ float lod_distance_multiplier;
+ float screen_lod_threshold;
+
+ RID framebuffer;
+ RD::InitialAction initial_depth_action;
+ RD::FinalAction final_depth_action;
+ Rect2i rect;
+ };
+
+ LocalVector<ShadowPass> shadow_passes;
+
+ } scene_state;
+
+ static RendererSceneRenderForwardClustered *singleton;
+
+ RID default_shader;
+ RID default_material;
+ RID overdraw_material_shader;
+ RID overdraw_material;
+ RID wireframe_material_shader;
+ RID wireframe_material;
+ RID default_shader_rd;
+ RID default_shader_sdfgi_rd;
+
+ RID default_vec4_xform_buffer;
+ RID default_vec4_xform_uniform_set;
+
+ void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
+ void _setup_giprobes(const PagedArray<RID> &p_giprobes);
+ void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform);
+
+ struct RenderElementInfo {
+ uint32_t repeat : 22;
+ uint32_t uses_lightmap : 1;
+ uint32_t uses_forward_gi : 1;
+ uint32_t lod_index : 8;
+ };
+
+ template <PassMode p_pass_mode>
+ _FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
+
+ void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
+
+ LocalVector<RD::DrawListID> thread_draw_lists;
+ void _render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params);
+ void _render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>());
+
+ uint32_t render_list_thread_threshold = 500;
+
+ void _update_instance_data_buffer(RenderListType p_render_list);
+ void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true);
+ void _fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, const Plane &p_lod_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, bool p_append = false);
+
+ Map<Size2i, RID> sdfgi_framebuffer_size_cache;
+
+ struct GeometryInstanceData;
+ struct GeometryInstanceForwardClustered;
+
+ struct GeometryInstanceLightmapSH {
+ Color sh[9];
+ };
+
+ // Cached data for drawing surfaces
+ struct GeometryInstanceSurfaceDataCache {
+ enum {
+ FLAG_PASS_DEPTH = 1,
+ FLAG_PASS_OPAQUE = 2,
+ FLAG_PASS_ALPHA = 4,
+ FLAG_PASS_SHADOW = 8,
+ FLAG_USES_SHARED_SHADOW_MATERIAL = 128,
+ FLAG_USES_SUBSURFACE_SCATTERING = 2048,
+ FLAG_USES_SCREEN_TEXTURE = 4096,
+ FLAG_USES_DEPTH_TEXTURE = 8192,
+ FLAG_USES_NORMAL_TEXTURE = 16384,
+ FLAG_USES_DOUBLE_SIDED_SHADOWS = 32768,
+ };
+
+ union {
+ struct {
+ uint64_t lod_index : 8;
+ uint64_t surface_index : 10;
+ uint64_t geometry_id : 32;
+ uint64_t material_id_low : 14;
+
+ uint64_t material_id_hi : 18;
+ uint64_t shader_id : 32;
+ uint64_t uses_forward_gi : 1;
+ uint64_t uses_lightmap : 1;
+ uint64_t depth_layer : 4;
+ uint64_t priority : 8;
+ };
+ struct {
+ uint64_t sort_key1;
+ uint64_t sort_key2;
+ };
+ } sort;
+
+ RS::PrimitiveType primitive = RS::PRIMITIVE_MAX;
+ uint32_t flags = 0;
+ uint32_t surface_index = 0;
+
+ void *surface = nullptr;
+ RID material_uniform_set;
+ ShaderData *shader = nullptr;
+
+ void *surface_shadow = nullptr;
+ RID material_uniform_set_shadow;
+ ShaderData *shader_shadow = nullptr;
+
+ GeometryInstanceSurfaceDataCache *next = nullptr;
+ GeometryInstanceForwardClustered *owner = nullptr;
+ };
+
+ struct GeometryInstanceForwardClustered : public GeometryInstance {
+ //used during rendering
+ bool mirror = false;
+ bool non_uniform_scale = false;
+ float lod_bias = 0.0;
+ float lod_model_scale = 1.0;
+ AABB transformed_aabb; //needed for LOD
+ float depth = 0;
+ uint32_t gi_offset_cache = 0;
+ uint32_t flags_cache = 0;
+ bool store_transform_cache = true;
+ int32_t shader_parameters_offset = -1;
+ uint32_t lightmap_slice_index;
+ Rect2 lightmap_uv_scale;
+ uint32_t layer_mask = 1;
+ RID transforms_uniform_set;
+ uint32_t instance_count = 0;
+ RID mesh_instance;
+ bool can_sdfgi = false;
+ //used during setup
+ uint32_t base_flags = 0;
+ Transform transform;
+ RID gi_probes[MAX_GI_PROBES_PER_INSTANCE];
+ RID lightmap_instance;
+ GeometryInstanceLightmapSH *lightmap_sh = nullptr;
+ GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
+ SelfList<GeometryInstanceForwardClustered> dirty_list_element;
+
+ struct Data {
+ //data used less often goes into regular heap
+ RID base;
+ RS::InstanceType base_type;
+
+ RID skeleton;
+ Vector<RID> surface_materials;
+ RID material_override;
+ AABB aabb;
+
+ bool use_dynamic_gi = false;
+ bool use_baked_light = false;
+ bool cast_double_sided_shadows = false;
+ bool mirror = false;
+ bool dirty_dependencies = false;
+
+ RendererStorage::DependencyTracker dependency_tracker;
+ };
+
+ Data *data = nullptr;
+
+ GeometryInstanceForwardClustered() :
+ dirty_list_element(this) {}
+ };
+
+ static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
+
+ SelfList<GeometryInstanceForwardClustered>::List geometry_instance_dirty_list;
+
+ PagedAllocator<GeometryInstanceForwardClustered> geometry_instance_alloc;
+ PagedAllocator<GeometryInstanceSurfaceDataCache> geometry_instance_surface_alloc;
+ PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
+
+ void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
+ void _geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
+ void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
+ void _geometry_instance_update(GeometryInstance *p_geometry_instance);
+ void _update_dirty_geometry_instances();
+
+ bool low_end = false;
+
+ /* Render List */
+
+ struct RenderList {
+ LocalVector<GeometryInstanceSurfaceDataCache *> elements;
+ LocalVector<RenderElementInfo> element_info;
+
+ void clear() {
+ elements.clear();
+ element_info.clear();
+ }
+
+ //should eventually be replaced by radix
+
+ struct SortByKey {
+ _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
+ return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2);
+ }
+ };
+
+ void sort_by_key() {
+ SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter;
+ sorter.sort(elements.ptr(), elements.size());
+ }
+
+ void sort_by_key_range(uint32_t p_from, uint32_t p_size) {
+ SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter;
+ sorter.sort(elements.ptr() + p_from, p_size);
+ }
+
+ struct SortByDepth {
+ _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
+ return (A->owner->depth < B->owner->depth);
+ }
+ };
+
+ void sort_by_depth() { //used for shadows
+
+ SortArray<GeometryInstanceSurfaceDataCache *, SortByDepth> sorter;
+ sorter.sort(elements.ptr(), elements.size());
+ }
+
+ struct SortByReverseDepthAndPriority {
+ _FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
+ return (A->sort.priority == B->sort.priority) ? (A->owner->depth > B->owner->depth) : (A->sort.priority < B->sort.priority);
+ }
+ };
+
+ void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
+
+ SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter;
+ sorter.sort(elements.ptr(), elements.size());
+ }
+
+ _FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) {
+ elements.push_back(p_element);
+ }
+ };
+
+ RenderList render_list[RENDER_LIST_MAX];
+
+protected:
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
+
+ virtual void _render_shadow_begin();
+ virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true);
+ virtual void _render_shadow_process();
+ virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+
+ virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
+ virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
+ virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
+ virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances);
+
+public:
+ virtual GeometryInstance *geometry_instance_create(RID p_base);
+ virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton);
+ virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override);
+ virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials);
+ virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance);
+ virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb);
+ virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask);
+ virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias);
+ virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable);
+ virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable);
+ virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index);
+ virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9);
+ virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset);
+ virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable);
+
+ virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance);
+ virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance);
+
+ virtual void geometry_instance_free(GeometryInstance *p_geometry_instance);
+
+ virtual uint32_t geometry_instance_get_pair_mask();
+ virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count);
+ virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count);
+ virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count);
+ virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count);
+
+ virtual bool free(RID p_rid);
+
+ RendererSceneRenderForwardClustered(RendererStorageRD *p_storage);
+ ~RendererSceneRenderForwardClustered();
+};
+#endif // !RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 02ec399f58..4cf296f0db 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,8 +35,6 @@
#include "renderer_compositor_rd.h"
#include "servers/rendering/rendering_server_default.h"
-uint64_t RendererSceneRenderRD::auto_exposure_counter = 2;
-
void get_vogel_disk(float *r_kernel, int p_sample_count) {
const float golden_angle = 2.4;
@@ -49,975 +47,42 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) {
}
}
-void RendererSceneRenderRD::_clear_reflection_data(ReflectionData &rd) {
- rd.layers.clear();
- rd.radiance_base_cubemap = RID();
- if (rd.downsampled_radiance_cubemap.is_valid()) {
- RD::get_singleton()->free(rd.downsampled_radiance_cubemap);
- }
- rd.downsampled_radiance_cubemap = RID();
- rd.downsampled_layer.mipmaps.clear();
- rd.coefficient_buffer = RID();
-}
-
-void RendererSceneRenderRD::_update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality) {
- //recreate radiance and all data
-
- int mipmaps = p_mipmaps;
- uint32_t w = p_size, h = p_size;
-
- if (p_use_array) {
- int layers = p_low_quality ? 8 : roughness_layers;
-
- for (int i = 0; i < layers; i++) {
- ReflectionData::Layer layer;
- uint32_t mmw = w;
- uint32_t mmh = h;
- layer.mipmaps.resize(mipmaps);
- layer.views.resize(mipmaps);
- for (int j = 0; j < mipmaps; j++) {
- ReflectionData::Layer::Mipmap &mm = layer.mipmaps.write[j];
- mm.size.width = mmw;
- mm.size.height = mmh;
- for (int k = 0; k < 6; k++) {
- mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6 + k, j);
- Vector<RID> fbtex;
- fbtex.push_back(mm.views[k]);
- mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
- }
-
- layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6, j, RD::TEXTURE_SLICE_CUBEMAP);
-
- mmw = MAX(1, mmw >> 1);
- mmh = MAX(1, mmh >> 1);
- }
-
- rd.layers.push_back(layer);
- }
-
- } else {
- mipmaps = p_low_quality ? 8 : mipmaps;
- //regular cubemap, lower quality (aliasing, less memory)
- ReflectionData::Layer layer;
- uint32_t mmw = w;
- uint32_t mmh = h;
- layer.mipmaps.resize(mipmaps);
- layer.views.resize(mipmaps);
- for (int j = 0; j < mipmaps; j++) {
- ReflectionData::Layer::Mipmap &mm = layer.mipmaps.write[j];
- mm.size.width = mmw;
- mm.size.height = mmh;
- for (int k = 0; k < 6; k++) {
- mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + k, j);
- Vector<RID> fbtex;
- fbtex.push_back(mm.views[k]);
- mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
- }
-
- layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, j, RD::TEXTURE_SLICE_CUBEMAP);
-
- mmw = MAX(1, mmw >> 1);
- mmh = MAX(1, mmh >> 1);
- }
-
- rd.layers.push_back(layer);
- }
-
- rd.radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, RD::TEXTURE_SLICE_CUBEMAP);
-
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.width = 64; // Always 64x64
- tf.height = 64;
- tf.texture_type = RD::TEXTURE_TYPE_CUBE;
- tf.array_layers = 6;
- tf.mipmaps = 7;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
-
- rd.downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView());
- {
- uint32_t mmw = 64;
- uint32_t mmh = 64;
- rd.downsampled_layer.mipmaps.resize(7);
- for (int j = 0; j < rd.downsampled_layer.mipmaps.size(); j++) {
- ReflectionData::DownsampleLayer::Mipmap &mm = rd.downsampled_layer.mipmaps.write[j];
- mm.size.width = mmw;
- mm.size.height = mmh;
- mm.view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rd.downsampled_radiance_cubemap, 0, j, RD::TEXTURE_SLICE_CUBEMAP);
-
- mmw = MAX(1, mmw >> 1);
- mmh = MAX(1, mmh >> 1);
- }
- }
-}
-
-void RendererSceneRenderRD::_create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays) {
- storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size);
-
- for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) {
- storage->get_effects()->cubemap_downsample(rd.downsampled_layer.mipmaps[i - 1].view, rd.downsampled_layer.mipmaps[i].view, rd.downsampled_layer.mipmaps[i].size);
- }
-
- Vector<RID> views;
- if (p_use_arrays) {
- for (int i = 1; i < rd.layers.size(); i++) {
- views.push_back(rd.layers[i].views[0]);
- }
- } else {
- for (int i = 1; i < rd.layers[0].views.size(); i++) {
- views.push_back(rd.layers[0].views[i]);
- }
- }
-
- storage->get_effects()->cubemap_filter(rd.downsampled_radiance_cubemap, views, p_use_arrays);
-}
-
-void RendererSceneRenderRD::_create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer) {
- if (p_use_arrays) {
- //render directly to the layers
- storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, rd.layers[p_base_layer].views[0], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers.size() - 1.0), rd.layers[p_base_layer].mipmaps[0].size.x);
- } else {
- storage->get_effects()->cubemap_roughness(rd.layers[0].views[p_base_layer - 1], rd.layers[0].views[p_base_layer], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers[0].mipmaps.size() - 1.0), rd.layers[0].mipmaps[p_base_layer].size.x);
- }
-}
-
-void RendererSceneRenderRD::_update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end) {
- for (int i = p_start; i < p_end; i++) {
- for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) {
- for (int k = 0; k < 6; k++) {
- RID view = rd.layers[i].mipmaps[j].views[k];
- RID texture = rd.layers[i].mipmaps[j + 1].views[k];
- Size2i size = rd.layers[i].mipmaps[j + 1].size;
- storage->get_effects()->make_mipmap(view, texture, size);
- }
- }
- }
-}
-
-void RendererSceneRenderRD::_sdfgi_erase(RenderBuffers *rb) {
- for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- const SDFGI::Cascade &c = rb->sdfgi->cascades[i];
- RD::get_singleton()->free(c.light_data);
- RD::get_singleton()->free(c.light_aniso_0_tex);
- RD::get_singleton()->free(c.light_aniso_1_tex);
- RD::get_singleton()->free(c.sdf_tex);
- RD::get_singleton()->free(c.solid_cell_dispatch_buffer);
- RD::get_singleton()->free(c.solid_cell_buffer);
- RD::get_singleton()->free(c.lightprobe_history_tex);
- RD::get_singleton()->free(c.lightprobe_average_tex);
- RD::get_singleton()->free(c.lights_buffer);
- }
-
- RD::get_singleton()->free(rb->sdfgi->render_albedo);
- RD::get_singleton()->free(rb->sdfgi->render_emission);
- RD::get_singleton()->free(rb->sdfgi->render_emission_aniso);
-
- RD::get_singleton()->free(rb->sdfgi->render_sdf[0]);
- RD::get_singleton()->free(rb->sdfgi->render_sdf[1]);
-
- RD::get_singleton()->free(rb->sdfgi->render_sdf_half[0]);
- RD::get_singleton()->free(rb->sdfgi->render_sdf_half[1]);
-
- for (int i = 0; i < 8; i++) {
- RD::get_singleton()->free(rb->sdfgi->render_occlusion[i]);
- }
-
- RD::get_singleton()->free(rb->sdfgi->render_geom_facing);
-
- RD::get_singleton()->free(rb->sdfgi->lightprobe_data);
- RD::get_singleton()->free(rb->sdfgi->lightprobe_history_scroll);
- RD::get_singleton()->free(rb->sdfgi->occlusion_data);
- RD::get_singleton()->free(rb->sdfgi->ambient_texture);
-
- RD::get_singleton()->free(rb->sdfgi->cascades_ubo);
-
- memdelete(rb->sdfgi);
-
- rb->sdfgi = nullptr;
-}
-
-const Vector3i RendererSceneRenderRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
-
void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) {
- Environment *env = environment_owner.getornull(p_environment);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment);
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
bool needs_sdfgi = env && env->sdfgi_enabled;
if (!needs_sdfgi) {
if (rb->sdfgi != nullptr) {
//erase it
- _sdfgi_erase(rb);
+ rb->sdfgi->erase();
+ memdelete(rb->sdfgi);
+ rb->sdfgi = nullptr;
+
_render_buffers_uniform_set_changed(p_render_buffers);
}
return;
}
static const uint32_t history_frames_to_converge[RS::ENV_SDFGI_CONVERGE_MAX] = { 5, 10, 15, 20, 25, 30 };
- uint32_t requested_history_size = history_frames_to_converge[sdfgi_frames_to_converge];
+ uint32_t requested_history_size = history_frames_to_converge[gi.sdfgi_frames_to_converge];
if (rb->sdfgi && (rb->sdfgi->cascade_mode != env->sdfgi_cascades || rb->sdfgi->min_cell_size != env->sdfgi_min_cell_size || requested_history_size != rb->sdfgi->history_size || rb->sdfgi->uses_occlusion != env->sdfgi_use_occlusion || rb->sdfgi->y_scale_mode != env->sdfgi_y_scale)) {
//configuration changed, erase
- _sdfgi_erase(rb);
+ rb->sdfgi->erase();
+ memdelete(rb->sdfgi);
+ rb->sdfgi = nullptr;
}
- SDFGI *sdfgi = rb->sdfgi;
+ RendererSceneGIRD::SDFGI *sdfgi = rb->sdfgi;
if (sdfgi == nullptr) {
- //re-create
- rb->sdfgi = memnew(SDFGI);
- sdfgi = rb->sdfgi;
- sdfgi->cascade_mode = env->sdfgi_cascades;
- sdfgi->min_cell_size = env->sdfgi_min_cell_size;
- sdfgi->uses_occlusion = env->sdfgi_use_occlusion;
- sdfgi->y_scale_mode = env->sdfgi_y_scale;
- static const float y_scale[3] = { 1.0, 1.5, 2.0 };
- sdfgi->y_mult = y_scale[sdfgi->y_scale_mode];
- static const int cascasde_size[3] = { 4, 6, 8 };
- sdfgi->cascades.resize(cascasde_size[sdfgi->cascade_mode]);
- sdfgi->probe_axis_count = SDFGI::PROBE_DIVISOR + 1;
- sdfgi->solid_cell_ratio = sdfgi_solid_cell_ratio;
- sdfgi->solid_cell_count = uint32_t(float(sdfgi->cascade_size * sdfgi->cascade_size * sdfgi->cascade_size) * sdfgi->solid_cell_ratio);
-
- float base_cell_size = sdfgi->min_cell_size;
-
- RD::TextureFormat tf_sdf;
- tf_sdf.format = RD::DATA_FORMAT_R8_UNORM;
- tf_sdf.width = sdfgi->cascade_size; // Always 64x64
- tf_sdf.height = sdfgi->cascade_size;
- tf_sdf.depth = sdfgi->cascade_size;
- tf_sdf.texture_type = RD::TEXTURE_TYPE_3D;
- tf_sdf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
-
- {
- RD::TextureFormat tf_render = tf_sdf;
- tf_render.format = RD::DATA_FORMAT_R16_UINT;
- sdfgi->render_albedo = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
- tf_render.format = RD::DATA_FORMAT_R32_UINT;
- sdfgi->render_emission = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
- sdfgi->render_emission_aniso = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
-
- tf_render.format = RD::DATA_FORMAT_R8_UNORM; //at least its easy to visualize
-
- for (int i = 0; i < 8; i++) {
- sdfgi->render_occlusion[i] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
- }
-
- tf_render.format = RD::DATA_FORMAT_R32_UINT;
- sdfgi->render_geom_facing = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
-
- tf_render.format = RD::DATA_FORMAT_R8G8B8A8_UINT;
- sdfgi->render_sdf[0] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
- sdfgi->render_sdf[1] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
-
- tf_render.width /= 2;
- tf_render.height /= 2;
- tf_render.depth /= 2;
-
- sdfgi->render_sdf_half[0] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
- sdfgi->render_sdf_half[1] = RD::get_singleton()->texture_create(tf_render, RD::TextureView());
- }
-
- RD::TextureFormat tf_occlusion = tf_sdf;
- tf_occlusion.format = RD::DATA_FORMAT_R16_UINT;
- tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R16_UINT);
- tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16);
- tf_occlusion.depth *= sdfgi->cascades.size(); //use depth for occlusion slices
- tf_occlusion.width *= 2; //use width for the other half
-
- RD::TextureFormat tf_light = tf_sdf;
- tf_light.format = RD::DATA_FORMAT_R32_UINT;
- tf_light.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT);
- tf_light.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);
-
- RD::TextureFormat tf_aniso0 = tf_sdf;
- tf_aniso0.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
- RD::TextureFormat tf_aniso1 = tf_sdf;
- tf_aniso1.format = RD::DATA_FORMAT_R8G8_UNORM;
-
- int passes = nearest_shift(sdfgi->cascade_size) - 1;
-
- //store lightprobe SH
- RD::TextureFormat tf_probes;
- tf_probes.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf_probes.width = sdfgi->probe_axis_count * sdfgi->probe_axis_count;
- tf_probes.height = sdfgi->probe_axis_count * SDFGI::SH_SIZE;
- tf_probes.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
- tf_probes.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
-
- sdfgi->history_size = requested_history_size;
-
- RD::TextureFormat tf_probe_history = tf_probes;
- tf_probe_history.format = RD::DATA_FORMAT_R16G16B16A16_SINT; //signed integer because SH are signed
- tf_probe_history.array_layers = sdfgi->history_size;
-
- RD::TextureFormat tf_probe_average = tf_probes;
- tf_probe_average.format = RD::DATA_FORMAT_R32G32B32A32_SINT; //signed integer because SH are signed
- tf_probe_average.texture_type = RD::TEXTURE_TYPE_2D;
-
- sdfgi->lightprobe_history_scroll = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());
- sdfgi->lightprobe_average_scroll = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());
-
- {
- //octahedral lightprobes
- RD::TextureFormat tf_octprobes = tf_probes;
- tf_octprobes.array_layers = sdfgi->cascades.size() * 2;
- tf_octprobes.format = RD::DATA_FORMAT_R32_UINT; //pack well with RGBE
- tf_octprobes.width = sdfgi->probe_axis_count * sdfgi->probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2);
- tf_octprobes.height = sdfgi->probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2);
- tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT);
- tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);
- //lightprobe texture is an octahedral texture
-
- sdfgi->lightprobe_data = RD::get_singleton()->texture_create(tf_octprobes, RD::TextureView());
- RD::TextureView tv;
- tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
- sdfgi->lightprobe_texture = RD::get_singleton()->texture_create_shared(tv, sdfgi->lightprobe_data);
-
- //texture handling ambient data, to integrate with volumetric foc
- RD::TextureFormat tf_ambient = tf_probes;
- tf_ambient.array_layers = sdfgi->cascades.size();
- tf_ambient.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; //pack well with RGBE
- tf_ambient.width = sdfgi->probe_axis_count * sdfgi->probe_axis_count;
- tf_ambient.height = sdfgi->probe_axis_count;
- tf_ambient.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
- //lightprobe texture is an octahedral texture
- sdfgi->ambient_texture = RD::get_singleton()->texture_create(tf_ambient, RD::TextureView());
- }
-
- sdfgi->cascades_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES);
-
- sdfgi->occlusion_data = RD::get_singleton()->texture_create(tf_occlusion, RD::TextureView());
- {
- RD::TextureView tv;
- tv.format_override = RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16;
- sdfgi->occlusion_texture = RD::get_singleton()->texture_create_shared(tv, sdfgi->occlusion_data);
- }
-
- for (uint32_t i = 0; i < sdfgi->cascades.size(); i++) {
- SDFGI::Cascade &cascade = sdfgi->cascades[i];
-
- /* 3D Textures */
-
- cascade.sdf_tex = RD::get_singleton()->texture_create(tf_sdf, RD::TextureView());
-
- cascade.light_data = RD::get_singleton()->texture_create(tf_light, RD::TextureView());
-
- cascade.light_aniso_0_tex = RD::get_singleton()->texture_create(tf_aniso0, RD::TextureView());
- cascade.light_aniso_1_tex = RD::get_singleton()->texture_create(tf_aniso1, RD::TextureView());
-
- {
- RD::TextureView tv;
- tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
- cascade.light_tex = RD::get_singleton()->texture_create_shared(tv, cascade.light_data);
-
- RD::get_singleton()->texture_clear(cascade.light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
- RD::get_singleton()->texture_clear(cascade.light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
- RD::get_singleton()->texture_clear(cascade.light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);
- }
-
- cascade.cell_size = base_cell_size;
- Vector3 world_position = p_world_position;
- world_position.y *= sdfgi->y_mult;
- int32_t probe_cells = sdfgi->cascade_size / SDFGI::PROBE_DIVISOR;
- Vector3 probe_size = Vector3(1, 1, 1) * cascade.cell_size * probe_cells;
- Vector3i probe_pos = Vector3i((world_position / probe_size + Vector3(0.5, 0.5, 0.5)).floor());
- cascade.position = probe_pos * probe_cells;
-
- cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;
-
- base_cell_size *= 2.0;
-
- /* Probe History */
-
- cascade.lightprobe_history_tex = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());
- RD::get_singleton()->texture_clear(cascade.lightprobe_history_tex, Color(0, 0, 0, 0), 0, 1, 0, tf_probe_history.array_layers); //needs to be cleared for average to work
-
- cascade.lightprobe_average_tex = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());
- RD::get_singleton()->texture_clear(cascade.lightprobe_average_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); //needs to be cleared for average to work
-
- /* Buffers */
-
- cascade.solid_cell_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGI::Cascade::SolidCell) * sdfgi->solid_cell_count);
- cascade.solid_cell_dispatch_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector<uint8_t>(), RD::STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT);
- cascade.lights_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDGIShader::Light) * MAX(SDFGI::MAX_STATIC_LIGHTS, SDFGI::MAX_DYNAMIC_LIGHTS));
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(sdfgi->render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(sdfgi->render_albedo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 3;
- for (int j = 0; j < 8; j++) {
- u.ids.push_back(sdfgi->render_occlusion[j]);
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 4;
- u.ids.push_back(sdfgi->render_emission);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 5;
- u.ids.push_back(sdfgi->render_emission_aniso);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 6;
- u.ids.push_back(sdfgi->render_geom_facing);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 7;
- u.ids.push_back(cascade.sdf_tex);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 8;
- u.ids.push_back(sdfgi->occlusion_data);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 10;
- u.ids.push_back(cascade.solid_cell_dispatch_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 11;
- u.ids.push_back(cascade.solid_cell_buffer);
- uniforms.push_back(u);
- }
-
- cascade.sdf_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_STORE), 0);
- }
-
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(sdfgi->render_albedo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(sdfgi->render_geom_facing);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 3;
- u.ids.push_back(sdfgi->render_emission);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 4;
- u.ids.push_back(sdfgi->render_emission_aniso);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 5;
- u.ids.push_back(cascade.solid_cell_dispatch_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 6;
- u.ids.push_back(cascade.solid_cell_buffer);
- uniforms.push_back(u);
- }
-
- cascade.scroll_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_SCROLL), 0);
- }
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- for (int j = 0; j < 8; j++) {
- u.ids.push_back(sdfgi->render_occlusion[j]);
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(sdfgi->occlusion_data);
- uniforms.push_back(u);
- }
-
- cascade.scroll_occlusion_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_SCROLL_OCCLUSION), 0);
- }
- }
-
- //direct light
- for (uint32_t i = 0; i < sdfgi->cascades.size(); i++) {
- SDFGI::Cascade &cascade = sdfgi->cascades[i];
-
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 1;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (j < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 2;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.ids.push_back(cascade.solid_cell_dispatch_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 4;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.ids.push_back(cascade.solid_cell_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 5;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.ids.push_back(cascade.light_data);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 6;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.ids.push_back(cascade.light_aniso_0_tex);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 7;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.ids.push_back(cascade.light_aniso_1_tex);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 8;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(rb->sdfgi->cascades_ubo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 9;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.ids.push_back(cascade.lights_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 10;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(rb->sdfgi->lightprobe_texture);
- uniforms.push_back(u);
- }
-
- cascade.sdf_direct_light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, 0), 0);
- }
-
- //preprocess initialize uniform set
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(sdfgi->render_albedo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(sdfgi->render_sdf[0]);
- uniforms.push_back(u);
- }
-
- sdfgi->sdf_initialize_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE), 0);
- }
-
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(sdfgi->render_albedo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(sdfgi->render_sdf_half[0]);
- uniforms.push_back(u);
- }
-
- sdfgi->sdf_initialize_half_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF), 0);
- }
-
- //jump flood uniform set
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(sdfgi->render_sdf[0]);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(sdfgi->render_sdf[1]);
- uniforms.push_back(u);
- }
-
- sdfgi->jump_flood_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_JUMP_FLOOD), 0);
- SWAP(uniforms.write[0].ids.write[0], uniforms.write[1].ids.write[0]);
- sdfgi->jump_flood_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_JUMP_FLOOD), 0);
- }
- //jump flood half uniform set
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(sdfgi->render_sdf_half[0]);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(sdfgi->render_sdf_half[1]);
- uniforms.push_back(u);
- }
-
- sdfgi->jump_flood_half_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_JUMP_FLOOD), 0);
- SWAP(uniforms.write[0].ids.write[0], uniforms.write[1].ids.write[0]);
- sdfgi->jump_flood_half_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_JUMP_FLOOD), 0);
- }
-
- //upscale half size sdf
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(sdfgi->render_albedo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- u.ids.push_back(sdfgi->render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 3;
- u.ids.push_back(sdfgi->render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass
- uniforms.push_back(u);
- }
-
- sdfgi->upscale_jfa_uniform_set_index = (passes & 1) ? 0 : 1;
- sdfgi->sdf_upscale_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE), 0);
- }
-
- //occlusion uniform set
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 1;
- u.ids.push_back(sdfgi->render_albedo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 2;
- for (int i = 0; i < 8; i++) {
- u.ids.push_back(sdfgi->render_occlusion[i]);
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 3;
- u.ids.push_back(sdfgi->render_geom_facing);
- uniforms.push_back(u);
- }
-
- sdfgi->occlusion_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, SDGIShader::PRE_PROCESS_OCCLUSION), 0);
- }
-
- for (uint32_t i = 0; i < sdfgi->cascades.size(); i++) {
- //integrate uniform
-
- Vector<RD::Uniform> uniforms;
-
- {
- RD::Uniform u;
- u.binding = 1;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (j < sdfgi->cascades.size()) {
- u.ids.push_back(sdfgi->cascades[j].sdf_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 2;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (j < sdfgi->cascades.size()) {
- u.ids.push_back(sdfgi->cascades[j].light_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (j < sdfgi->cascades.size()) {
- u.ids.push_back(sdfgi->cascades[j].light_aniso_0_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 4;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (j < sdfgi->cascades.size()) {
- u.ids.push_back(sdfgi->cascades[j].light_aniso_1_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 6;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 7;
- u.ids.push_back(sdfgi->cascades_ubo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 8;
- u.ids.push_back(sdfgi->lightprobe_data);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 9;
- u.ids.push_back(sdfgi->cascades[i].lightprobe_history_tex);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 10;
- u.ids.push_back(sdfgi->cascades[i].lightprobe_average_tex);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 11;
- u.ids.push_back(sdfgi->lightprobe_history_scroll);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 12;
- u.ids.push_back(sdfgi->lightprobe_average_scroll);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 13;
- RID parent_average;
- if (i < sdfgi->cascades.size() - 1) {
- parent_average = sdfgi->cascades[i + 1].lightprobe_average_tex;
- } else {
- parent_average = sdfgi->cascades[i - 1].lightprobe_average_tex; //to use something, but it won't be used
- }
- u.ids.push_back(parent_average);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 14;
- u.ids.push_back(sdfgi->ambient_texture);
- uniforms.push_back(u);
- }
-
- sdfgi->cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 0);
- }
-
- sdfgi->uses_multibounce = env->sdfgi_use_multibounce;
- sdfgi->energy = env->sdfgi_energy;
- sdfgi->normal_bias = env->sdfgi_normal_bias;
- sdfgi->probe_bias = env->sdfgi_probe_bias;
- sdfgi->reads_sky = env->sdfgi_read_sky_light;
+ // re-create
+ rb->sdfgi = gi.create_sdfgi(env, p_world_position, requested_history_size);
_render_buffers_uniform_set_changed(p_render_buffers);
-
- return; //done. all levels will need to be rendered which its going to take a bit
- }
-
- //check for updates
-
- sdfgi->uses_multibounce = env->sdfgi_use_multibounce;
- sdfgi->energy = env->sdfgi_energy;
- sdfgi->normal_bias = env->sdfgi_normal_bias;
- sdfgi->probe_bias = env->sdfgi_probe_bias;
- sdfgi->reads_sky = env->sdfgi_read_sky_light;
-
- int32_t drag_margin = (sdfgi->cascade_size / SDFGI::PROBE_DIVISOR) / 2;
-
- for (uint32_t i = 0; i < sdfgi->cascades.size(); i++) {
- SDFGI::Cascade &cascade = sdfgi->cascades[i];
- cascade.dirty_regions = Vector3i();
-
- Vector3 probe_half_size = Vector3(1, 1, 1) * cascade.cell_size * float(sdfgi->cascade_size / SDFGI::PROBE_DIVISOR) * 0.5;
- probe_half_size = Vector3(0, 0, 0);
-
- Vector3 world_position = p_world_position;
- world_position.y *= sdfgi->y_mult;
- Vector3i pos_in_cascade = Vector3i((world_position + probe_half_size) / cascade.cell_size);
-
- for (int j = 0; j < 3; j++) {
- if (pos_in_cascade[j] < cascade.position[j]) {
- while (pos_in_cascade[j] < (cascade.position[j] - drag_margin)) {
- cascade.position[j] -= drag_margin * 2;
- cascade.dirty_regions[j] += drag_margin * 2;
- }
- } else if (pos_in_cascade[j] > cascade.position[j]) {
- while (pos_in_cascade[j] > (cascade.position[j] + drag_margin)) {
- cascade.position[j] += drag_margin * 2;
- cascade.dirty_regions[j] -= drag_margin * 2;
- }
- }
-
- if (cascade.dirty_regions[j] == 0) {
- continue; // not dirty
- } else if (uint32_t(ABS(cascade.dirty_regions[j])) >= sdfgi->cascade_size) {
- //moved too much, just redraw everything (make all dirty)
- cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;
- break;
- }
- }
-
- if (cascade.dirty_regions != Vector3i() && cascade.dirty_regions != SDFGI::Cascade::DIRTY_ALL) {
- //see how much the total dirty volume represents from the total volume
- uint32_t total_volume = sdfgi->cascade_size * sdfgi->cascade_size * sdfgi->cascade_size;
- uint32_t safe_volume = 1;
- for (int j = 0; j < 3; j++) {
- safe_volume *= sdfgi->cascade_size - ABS(cascade.dirty_regions[j]);
- }
- uint32_t dirty_volume = total_volume - safe_volume;
- if (dirty_volume > (safe_volume / 2)) {
- //more than half the volume is dirty, make all dirty so its only rendered once
- cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;
- }
- }
+ } else {
+ //check for updates
+ rb->sdfgi->update(env, p_world_position);
}
}
@@ -1032,9 +97,9 @@ int RendererSceneRenderRD::sdfgi_get_pending_region_count(RID p_render_buffers)
int dirty_count = 0;
for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- const SDFGI::Cascade &c = rb->sdfgi->cascades[i];
+ const RendererSceneGIRD::SDFGI::Cascade &c = rb->sdfgi->cascades[i];
- if (c.dirty_regions == SDFGI::Cascade::DIRTY_ALL) {
+ if (c.dirty_regions == RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL) {
dirty_count++;
} else {
for (int j = 0; j < 3; j++) {
@@ -1048,72 +113,15 @@ int RendererSceneRenderRD::sdfgi_get_pending_region_count(RID p_render_buffers)
return dirty_count;
}
-int RendererSceneRenderRD::_sdfgi_get_pending_region_data(RID p_render_buffers, int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const {
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND_V(rb == nullptr, -1);
- ERR_FAIL_COND_V(rb->sdfgi == nullptr, -1);
-
- int dirty_count = 0;
- for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- const SDFGI::Cascade &c = rb->sdfgi->cascades[i];
-
- if (c.dirty_regions == SDFGI::Cascade::DIRTY_ALL) {
- if (dirty_count == p_region) {
- r_local_offset = Vector3i();
- r_local_size = Vector3i(1, 1, 1) * rb->sdfgi->cascade_size;
-
- r_bounds.position = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + c.position)) * c.cell_size * Vector3(1, 1.0 / rb->sdfgi->y_mult, 1);
- r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / rb->sdfgi->y_mult, 1);
- return i;
- }
- dirty_count++;
- } else {
- for (int j = 0; j < 3; j++) {
- if (c.dirty_regions[j] != 0) {
- if (dirty_count == p_region) {
- Vector3i from = Vector3i(0, 0, 0);
- Vector3i to = Vector3i(1, 1, 1) * rb->sdfgi->cascade_size;
-
- if (c.dirty_regions[j] > 0) {
- //fill from the beginning
- to[j] = c.dirty_regions[j];
- } else {
- //fill from the end
- from[j] = to[j] + c.dirty_regions[j];
- }
-
- for (int k = 0; k < j; k++) {
- // "chip" away previous regions to avoid re-voxelizing the same thing
- if (c.dirty_regions[k] > 0) {
- from[k] += c.dirty_regions[k];
- } else if (c.dirty_regions[k] < 0) {
- to[k] += c.dirty_regions[k];
- }
- }
-
- r_local_offset = from;
- r_local_size = to - from;
-
- r_bounds.position = Vector3(from + Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + c.position) * c.cell_size * Vector3(1, 1.0 / rb->sdfgi->y_mult, 1);
- r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / rb->sdfgi->y_mult, 1);
-
- return i;
- }
-
- dirty_count++;
- }
- }
- }
- }
- return -1;
-}
-
AABB RendererSceneRenderRD::sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const {
AABB bounds;
Vector3i from;
Vector3i size;
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND_V(rb == nullptr, AABB());
+ ERR_FAIL_COND_V(rb->sdfgi == nullptr, AABB());
- int c = _sdfgi_get_pending_region_data(p_render_buffers, p_region, from, size, bounds);
+ int c = rb->sdfgi->get_pending_region_data(p_region, from, size, bounds);
ERR_FAIL_COND_V(c == -1, AABB());
return bounds;
}
@@ -1122,1841 +130,179 @@ uint32_t RendererSceneRenderRD::sdfgi_get_pending_region_cascade(RID p_render_bu
AABB bounds;
Vector3i from;
Vector3i size;
-
- return _sdfgi_get_pending_region_data(p_render_buffers, p_region, from, size, bounds);
-}
-
-void RendererSceneRenderRD::_sdfgi_update_cascades(RID p_render_buffers) {
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND(rb == nullptr);
- if (rb->sdfgi == nullptr) {
- return;
- }
-
- //update cascades
- SDFGI::Cascade::UBO cascade_data[SDFGI::MAX_CASCADES];
- int32_t probe_divisor = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR;
-
- for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + rb->sdfgi->cascades[i].position)) * rb->sdfgi->cascades[i].cell_size;
-
- cascade_data[i].offset[0] = pos.x;
- cascade_data[i].offset[1] = pos.y;
- cascade_data[i].offset[2] = pos.z;
- cascade_data[i].to_cell = 1.0 / rb->sdfgi->cascades[i].cell_size;
- cascade_data[i].probe_offset[0] = rb->sdfgi->cascades[i].position.x / probe_divisor;
- cascade_data[i].probe_offset[1] = rb->sdfgi->cascades[i].position.y / probe_divisor;
- cascade_data[i].probe_offset[2] = rb->sdfgi->cascades[i].position.z / probe_divisor;
- cascade_data[i].pad = 0;
- }
-
- RD::get_singleton()->buffer_update(rb->sdfgi->cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, true);
-}
-
-void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_environment, const PagedArray<RID> &p_directional_light_instances, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND(rb == nullptr);
- if (rb->sdfgi == nullptr) {
- return;
- }
- Environment *env = environment_owner.getornull(p_environment);
-
- RENDER_TIMESTAMP(">SDFGI Update Probes");
-
- /* Update Cascades UBO */
- _sdfgi_update_cascades(p_render_buffers);
- /* Update Dynamic Lights Buffer */
-
- RENDER_TIMESTAMP("Update Lights");
-
- /* Update dynamic lights */
-
- {
- int32_t cascade_light_count[SDFGI::MAX_CASCADES];
-
- for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- SDFGI::Cascade &cascade = rb->sdfgi->cascades[i];
-
- SDGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS];
- uint32_t idx = 0;
- for (uint32_t j = 0; j < (uint32_t)p_directional_light_instances.size(); j++) {
- if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
- break;
- }
-
- LightInstance *li = light_instance_owner.getornull(p_directional_light_instances[j]);
- ERR_CONTINUE(!li);
-
- if (storage->light_directional_is_sky_only(li->light)) {
- continue;
- }
-
- Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
- dir.y *= rb->sdfgi->y_mult;
- dir.normalize();
- lights[idx].direction[0] = dir.x;
- lights[idx].direction[1] = dir.y;
- lights[idx].direction[2] = dir.z;
- Color color = storage->light_get_color(li->light);
- color = color.to_linear();
- lights[idx].color[0] = color.r;
- lights[idx].color[1] = color.g;
- lights[idx].color[2] = color.b;
- lights[idx].type = RS::LIGHT_DIRECTIONAL;
- lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY);
- lights[idx].has_shadow = storage->light_has_shadow(li->light);
-
- idx++;
- }
-
- AABB cascade_aabb;
- cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + cascade.position)) * cascade.cell_size;
- cascade_aabb.size = Vector3(1, 1, 1) * rb->sdfgi->cascade_size * cascade.cell_size;
-
- for (uint32_t j = 0; j < p_positional_light_count; j++) {
- if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
- break;
- }
-
- LightInstance *li = light_instance_owner.getornull(p_positional_light_instances[j]);
- ERR_CONTINUE(!li);
-
- uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light);
- if (i > max_sdfgi_cascade) {
- continue;
- }
-
- if (!cascade_aabb.intersects(li->aabb)) {
- continue;
- }
-
- Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
- //faster to not do this here
- //dir.y *= rb->sdfgi->y_mult;
- //dir.normalize();
- lights[idx].direction[0] = dir.x;
- lights[idx].direction[1] = dir.y;
- lights[idx].direction[2] = dir.z;
- Vector3 pos = li->transform.origin;
- pos.y *= rb->sdfgi->y_mult;
- lights[idx].position[0] = pos.x;
- lights[idx].position[1] = pos.y;
- lights[idx].position[2] = pos.z;
- Color color = storage->light_get_color(li->light);
- color = color.to_linear();
- lights[idx].color[0] = color.r;
- lights[idx].color[1] = color.g;
- lights[idx].color[2] = color.b;
- lights[idx].type = storage->light_get_type(li->light);
- lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY);
- lights[idx].has_shadow = storage->light_has_shadow(li->light);
- lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
- lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
- lights[idx].spot_angle = Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE));
- lights[idx].spot_attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
-
- idx++;
- }
-
- if (idx > 0) {
- RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights, true);
- }
-
- cascade_light_count[i] = idx;
- }
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_DYNAMIC]);
-
- SDGIShader::DirectLightPushConstant push_constant;
-
- push_constant.grid_size[0] = rb->sdfgi->cascade_size;
- push_constant.grid_size[1] = rb->sdfgi->cascade_size;
- push_constant.grid_size[2] = rb->sdfgi->cascade_size;
- push_constant.max_cascades = rb->sdfgi->cascades.size();
- push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
- push_constant.multibounce = rb->sdfgi->uses_multibounce;
- push_constant.y_mult = rb->sdfgi->y_mult;
-
- push_constant.process_offset = 0;
- push_constant.process_increment = 1;
-
- for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- SDFGI::Cascade &cascade = rb->sdfgi->cascades[i];
- push_constant.light_count = cascade_light_count[i];
- push_constant.cascade = i;
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DirectLightPushConstant));
- RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0);
- }
- RD::get_singleton()->compute_list_end();
- }
-
- RENDER_TIMESTAMP("Raytrace");
-
- SDGIShader::IntegratePushConstant push_constant;
- push_constant.grid_size[1] = rb->sdfgi->cascade_size;
- push_constant.grid_size[2] = rb->sdfgi->cascade_size;
- push_constant.grid_size[0] = rb->sdfgi->cascade_size;
- push_constant.max_cascades = rb->sdfgi->cascades.size();
- push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
- push_constant.history_index = rb->sdfgi->render_pass % rb->sdfgi->history_size;
- push_constant.history_size = rb->sdfgi->history_size;
- static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 8, 16, 32, 64, 96, 128 };
- push_constant.ray_count = ray_count[sdfgi_ray_count];
- push_constant.ray_bias = rb->sdfgi->probe_bias;
- push_constant.image_size[0] = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count;
- push_constant.image_size[1] = rb->sdfgi->probe_axis_count;
- push_constant.store_ambient_texture = env->volumetric_fog_enabled;
-
- RID sky_uniform_set = sdfgi_shader.integrate_default_sky_uniform_set;
- push_constant.sky_mode = SDGIShader::IntegratePushConstant::SKY_MODE_DISABLED;
- push_constant.y_mult = rb->sdfgi->y_mult;
-
- if (rb->sdfgi->reads_sky && env) {
- push_constant.sky_energy = env->bg_energy;
-
- if (env->background == RS::ENV_BG_CLEAR_COLOR) {
- push_constant.sky_mode = SDGIShader::IntegratePushConstant::SKY_MODE_COLOR;
- Color c = storage->get_default_clear_color().to_linear();
- push_constant.sky_color[0] = c.r;
- push_constant.sky_color[1] = c.g;
- push_constant.sky_color[2] = c.b;
- } else if (env->background == RS::ENV_BG_COLOR) {
- push_constant.sky_mode = SDGIShader::IntegratePushConstant::SKY_MODE_COLOR;
- Color c = env->bg_color;
- push_constant.sky_color[0] = c.r;
- push_constant.sky_color[1] = c.g;
- push_constant.sky_color[2] = c.b;
-
- } else if (env->background == RS::ENV_BG_SKY) {
- Sky *sky = sky_owner.getornull(env->sky);
- if (sky && sky->radiance.is_valid()) {
- if (sky->sdfgi_integrate_sky_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(sky->sdfgi_integrate_sky_uniform_set)) {
- Vector<RD::Uniform> uniforms;
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 0;
- u.ids.push_back(sky->radiance);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 1;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
-
- sky->sdfgi_integrate_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1);
- }
- sky_uniform_set = sky->sdfgi_integrate_sky_uniform_set;
- push_constant.sky_mode = SDGIShader::IntegratePushConstant::SKY_MODE_SKY;
- }
- }
- }
-
- rb->sdfgi->render_pass++;
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_PROCESS]);
-
- int32_t probe_divisor = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR;
- for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- push_constant.cascade = i;
- push_constant.world_offset[0] = rb->sdfgi->cascades[i].position.x / probe_divisor;
- push_constant.world_offset[1] = rb->sdfgi->cascades[i].position.y / probe_divisor;
- push_constant.world_offset[2] = rb->sdfgi->cascades[i].position.z / probe_divisor;
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[i].integrate_uniform_set, 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sky_uniform_set, 1);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::IntegratePushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1);
- }
-
- RD::get_singleton()->compute_list_add_barrier(compute_list); //wait until done
-
- // Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces
- RENDER_TIMESTAMP("Average Probes");
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_STORE]);
-
- //convert to octahedral to store
- push_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;
- push_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;
-
- for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- push_constant.cascade = i;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[i].integrate_uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::IntegratePushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1, 8, 8, 1);
- }
-
- RD::get_singleton()->compute_list_end();
-
- RENDER_TIMESTAMP("<SDFGI Update Probes");
-}
-
-void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used) {
- r_gi_probes_used = 0;
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND(rb == nullptr);
-
- RID gi_probe_buffer = render_buffers_get_gi_probe_buffer(p_render_buffers);
- GI::GIProbeData gi_probe_data[RenderBuffers::MAX_GIPROBES];
-
- bool giprobes_changed = false;
-
- Transform to_camera;
- to_camera.origin = p_transform.origin; //only translation, make local
-
- for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) {
- RID texture;
- if (i < (int)p_gi_probes.size()) {
- GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_gi_probes[i]);
-
- if (gipi) {
- texture = gipi->texture;
- GI::GIProbeData &gipd = gi_probe_data[i];
-
- RID base_probe = gipi->probe;
-
- Transform to_cell = storage->gi_probe_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera;
-
- gipd.xform[0] = to_cell.basis.elements[0][0];
- gipd.xform[1] = to_cell.basis.elements[1][0];
- gipd.xform[2] = to_cell.basis.elements[2][0];
- gipd.xform[3] = 0;
- gipd.xform[4] = to_cell.basis.elements[0][1];
- gipd.xform[5] = to_cell.basis.elements[1][1];
- gipd.xform[6] = to_cell.basis.elements[2][1];
- gipd.xform[7] = 0;
- gipd.xform[8] = to_cell.basis.elements[0][2];
- gipd.xform[9] = to_cell.basis.elements[1][2];
- gipd.xform[10] = to_cell.basis.elements[2][2];
- gipd.xform[11] = 0;
- gipd.xform[12] = to_cell.origin.x;
- gipd.xform[13] = to_cell.origin.y;
- gipd.xform[14] = to_cell.origin.z;
- gipd.xform[15] = 1;
-
- Vector3 bounds = storage->gi_probe_get_octree_size(base_probe);
-
- gipd.bounds[0] = bounds.x;
- gipd.bounds[1] = bounds.y;
- gipd.bounds[2] = bounds.z;
-
- gipd.dynamic_range = storage->gi_probe_get_dynamic_range(base_probe) * storage->gi_probe_get_energy(base_probe);
- gipd.bias = storage->gi_probe_get_bias(base_probe);
- gipd.normal_bias = storage->gi_probe_get_normal_bias(base_probe);
- gipd.blend_ambient = !storage->gi_probe_is_interior(base_probe);
- gipd.anisotropy_strength = 0;
- gipd.ao = storage->gi_probe_get_ao(base_probe);
- gipd.ao_size = Math::pow(storage->gi_probe_get_ao_size(base_probe), 4.0f);
- gipd.mipmaps = gipi->mipmaps.size();
- }
-
- r_gi_probes_used++;
- }
-
- if (texture == RID()) {
- texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
- }
-
- if (texture != rb->giprobe_textures[i]) {
- giprobes_changed = true;
- rb->giprobe_textures[i] = texture;
- }
- }
-
- if (giprobes_changed) {
- if (RD::get_singleton()->uniform_set_is_valid(rb->gi_uniform_set)) {
- RD::get_singleton()->free(rb->gi_uniform_set);
- }
- rb->gi_uniform_set = RID();
- if (rb->volumetric_fog) {
- if (RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
- RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
- RD::get_singleton()->free(rb->volumetric_fog->uniform_set2);
- }
- rb->volumetric_fog->uniform_set = RID();
- rb->volumetric_fog->uniform_set2 = RID();
- }
- }
-
- if (p_gi_probes.size() > 0) {
- RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GI::GIProbeData) * MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, true);
- }
-}
-
-void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) {
- RENDER_TIMESTAMP("Render GI");
-
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND(rb == nullptr);
- Environment *env = environment_owner.getornull(p_environment);
-
- GI::PushConstant push_constant;
-
- push_constant.screen_size[0] = rb->width;
- push_constant.screen_size[1] = rb->height;
- push_constant.z_near = p_projection.get_z_near();
- push_constant.z_far = p_projection.get_z_far();
- push_constant.orthogonal = p_projection.is_orthogonal();
- push_constant.proj_info[0] = -2.0f / (rb->width * p_projection.matrix[0][0]);
- push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]);
- push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
- push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
- push_constant.max_giprobes = MIN((uint64_t)RenderBuffers::MAX_GIPROBES, p_gi_probes.size());
- push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH;
- push_constant.use_sdfgi = rb->sdfgi != nullptr;
-
- if (env) {
- push_constant.ao_color[0] = env->ao_color.r;
- push_constant.ao_color[1] = env->ao_color.g;
- push_constant.ao_color[2] = env->ao_color.b;
- } else {
- push_constant.ao_color[0] = 0;
- push_constant.ao_color[1] = 0;
- push_constant.ao_color[2] = 0;
- }
-
- push_constant.cam_rotation[0] = p_transform.basis[0][0];
- push_constant.cam_rotation[1] = p_transform.basis[1][0];
- push_constant.cam_rotation[2] = p_transform.basis[2][0];
- push_constant.cam_rotation[3] = 0;
- push_constant.cam_rotation[4] = p_transform.basis[0][1];
- push_constant.cam_rotation[5] = p_transform.basis[1][1];
- push_constant.cam_rotation[6] = p_transform.basis[2][1];
- push_constant.cam_rotation[7] = 0;
- push_constant.cam_rotation[8] = p_transform.basis[0][2];
- push_constant.cam_rotation[9] = p_transform.basis[1][2];
- push_constant.cam_rotation[10] = p_transform.basis[2][2];
- push_constant.cam_rotation[11] = 0;
-
- if (rb->sdfgi) {
- GI::SDFGIData sdfgi_data;
-
- sdfgi_data.grid_size[0] = rb->sdfgi->cascade_size;
- sdfgi_data.grid_size[1] = rb->sdfgi->cascade_size;
- sdfgi_data.grid_size[2] = rb->sdfgi->cascade_size;
-
- sdfgi_data.max_cascades = rb->sdfgi->cascades.size();
- sdfgi_data.probe_axis_size = rb->sdfgi->probe_axis_count;
- sdfgi_data.cascade_probe_size[0] = sdfgi_data.probe_axis_size - 1; //float version for performance
- sdfgi_data.cascade_probe_size[1] = sdfgi_data.probe_axis_size - 1;
- sdfgi_data.cascade_probe_size[2] = sdfgi_data.probe_axis_size - 1;
-
- float csize = rb->sdfgi->cascade_size;
- sdfgi_data.probe_to_uvw = 1.0 / float(sdfgi_data.cascade_probe_size[0]);
- sdfgi_data.use_occlusion = rb->sdfgi->uses_occlusion;
- //sdfgi_data.energy = rb->sdfgi->energy;
-
- sdfgi_data.y_mult = rb->sdfgi->y_mult;
-
- float cascade_voxel_size = (csize / sdfgi_data.cascade_probe_size[0]);
- float occlusion_clamp = (cascade_voxel_size - 0.5) / cascade_voxel_size;
- sdfgi_data.occlusion_clamp[0] = occlusion_clamp;
- sdfgi_data.occlusion_clamp[1] = occlusion_clamp;
- sdfgi_data.occlusion_clamp[2] = occlusion_clamp;
- sdfgi_data.normal_bias = (rb->sdfgi->normal_bias / csize) * sdfgi_data.cascade_probe_size[0];
-
- //vec2 tex_pixel_size = 1.0 / vec2(ivec2( (OCT_SIZE+2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE+2) * params.probe_axis_size ) );
- //vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx;
-
- uint32_t oct_size = SDFGI::LIGHTPROBE_OCT_SIZE;
-
- sdfgi_data.lightprobe_tex_pixel_size[0] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size * sdfgi_data.probe_axis_size);
- sdfgi_data.lightprobe_tex_pixel_size[1] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size);
- sdfgi_data.lightprobe_tex_pixel_size[2] = 1.0;
-
- sdfgi_data.energy = rb->sdfgi->energy;
-
- sdfgi_data.lightprobe_uv_offset[0] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[0];
- sdfgi_data.lightprobe_uv_offset[1] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[1];
- sdfgi_data.lightprobe_uv_offset[2] = float((oct_size + 2) * sdfgi_data.probe_axis_size) * sdfgi_data.lightprobe_tex_pixel_size[0];
-
- sdfgi_data.occlusion_renormalize[0] = 0.5;
- sdfgi_data.occlusion_renormalize[1] = 1.0;
- sdfgi_data.occlusion_renormalize[2] = 1.0 / float(sdfgi_data.max_cascades);
-
- int32_t probe_divisor = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR;
-
- for (uint32_t i = 0; i < sdfgi_data.max_cascades; i++) {
- GI::SDFGIData::ProbeCascadeData &c = sdfgi_data.cascades[i];
- Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + rb->sdfgi->cascades[i].position)) * rb->sdfgi->cascades[i].cell_size;
- Vector3 cam_origin = p_transform.origin;
- cam_origin.y *= rb->sdfgi->y_mult;
- pos -= cam_origin; //make pos local to camera, to reduce numerical error
- c.position[0] = pos.x;
- c.position[1] = pos.y;
- c.position[2] = pos.z;
- c.to_probe = 1.0 / (float(rb->sdfgi->cascade_size) * rb->sdfgi->cascades[i].cell_size / float(rb->sdfgi->probe_axis_count - 1));
-
- Vector3i probe_ofs = rb->sdfgi->cascades[i].position / probe_divisor;
- c.probe_world_offset[0] = probe_ofs.x;
- c.probe_world_offset[1] = probe_ofs.y;
- c.probe_world_offset[2] = probe_ofs.z;
-
- c.to_cell = 1.0 / rb->sdfgi->cascades[i].cell_size;
- }
-
- RD::get_singleton()->buffer_update(gi.sdfgi_ubo, 0, sizeof(GI::SDFGIData), &sdfgi_data, true);
- }
-
- if (rb->gi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->gi_uniform_set)) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 1;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 2;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[j].light_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_0_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 4;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_1_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 5;
- if (rb->sdfgi) {
- u.ids.push_back(rb->sdfgi->occlusion_texture);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 6;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 7;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 9;
- u.ids.push_back(p_ambient_buffer);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 10;
- u.ids.push_back(p_reflection_buffer);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 11;
- if (rb->sdfgi) {
- u.ids.push_back(rb->sdfgi->lightprobe_texture);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 12;
- u.ids.push_back(rb->depth_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 13;
- u.ids.push_back(p_normal_roughness_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 14;
- RID buffer = p_gi_probe_buffer.is_valid() ? p_gi_probe_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
- u.ids.push_back(buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 15;
- u.ids.push_back(gi.sdfgi_ubo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 16;
- u.ids.push_back(rb->giprobe_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 17;
- for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) {
- u.ids.push_back(rb->giprobe_textures[i]);
- }
- uniforms.push_back(u);
- }
-
- rb->gi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi.shader.version_get_shader(gi.shader_version, 0), 0);
- }
+ ERR_FAIL_COND_V(rb == nullptr, -1);
+ ERR_FAIL_COND_V(rb->sdfgi == nullptr, -1);
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi.pipelines[0]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi_uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GI::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1);
- RD::get_singleton()->compute_list_end();
+ return rb->sdfgi->get_pending_region_data(p_region, from, size, bounds);
}
-RID RendererSceneRenderRD::sky_create() {
- return sky_owner.make_rid(Sky());
+RID RendererSceneRenderRD::sky_allocate() {
+ return sky.allocate_sky_rid();
}
-
-void RendererSceneRenderRD::_sky_invalidate(Sky *p_sky) {
- if (!p_sky->dirty) {
- p_sky->dirty = true;
- p_sky->dirty_list = dirty_sky_list;
- dirty_sky_list = p_sky;
- }
+void RendererSceneRenderRD::sky_initialize(RID p_rid) {
+ sky.initialize_sky_rid(p_rid);
}
void RendererSceneRenderRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
- Sky *sky = sky_owner.getornull(p_sky);
- ERR_FAIL_COND(!sky);
- ERR_FAIL_COND(p_radiance_size < 32 || p_radiance_size > 2048);
- if (sky->radiance_size == p_radiance_size) {
- return;
- }
- sky->radiance_size = p_radiance_size;
-
- if (sky->mode == RS::SKY_MODE_REALTIME && sky->radiance_size != 256) {
- WARN_PRINT("Realtime Skies can only use a radiance size of 256. Radiance size will be set to 256 internally.");
- sky->radiance_size = 256;
- }
-
- _sky_invalidate(sky);
- if (sky->radiance.is_valid()) {
- RD::get_singleton()->free(sky->radiance);
- sky->radiance = RID();
- }
- _clear_reflection_data(sky->reflection);
+ sky.sky_set_radiance_size(p_sky, p_radiance_size);
}
void RendererSceneRenderRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
- Sky *sky = sky_owner.getornull(p_sky);
- ERR_FAIL_COND(!sky);
-
- if (sky->mode == p_mode) {
- return;
- }
-
- sky->mode = p_mode;
-
- if (sky->mode == RS::SKY_MODE_REALTIME && sky->radiance_size != 256) {
- WARN_PRINT("Realtime Skies can only use a radiance size of 256. Radiance size will be set to 256 internally.");
- sky_set_radiance_size(p_sky, 256);
- }
-
- _sky_invalidate(sky);
- if (sky->radiance.is_valid()) {
- RD::get_singleton()->free(sky->radiance);
- sky->radiance = RID();
- }
- _clear_reflection_data(sky->reflection);
+ sky.sky_set_mode(p_sky, p_mode);
}
void RendererSceneRenderRD::sky_set_material(RID p_sky, RID p_material) {
- Sky *sky = sky_owner.getornull(p_sky);
- ERR_FAIL_COND(!sky);
- sky->material = p_material;
- _sky_invalidate(sky);
+ sky.sky_set_material(p_sky, p_material);
}
Ref<Image> RendererSceneRenderRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {
- Sky *sky = sky_owner.getornull(p_sky);
- ERR_FAIL_COND_V(!sky, Ref<Image>());
-
- _update_dirty_skys();
-
- if (sky->radiance.is_valid()) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
- tf.width = p_size.width;
- tf.height = p_size.height;
- tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
-
- RID rad_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
- storage->get_effects()->copy_cubemap_to_panorama(sky->radiance, rad_tex, p_size, p_bake_irradiance ? roughness_layers : 0, sky->reflection.layers.size() > 1);
- Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0);
- RD::get_singleton()->free(rad_tex);
-
- Ref<Image> img;
- img.instance();
- img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data);
- for (int i = 0; i < p_size.width; i++) {
- for (int j = 0; j < p_size.height; j++) {
- Color c = img->get_pixel(i, j);
- c.r *= p_energy;
- c.g *= p_energy;
- c.b *= p_energy;
- img->set_pixel(i, j, c);
- }
- }
- return img;
- }
-
- return Ref<Image>();
-}
-
-void RendererSceneRenderRD::_update_dirty_skys() {
- Sky *sky = dirty_sky_list;
-
- while (sky) {
- bool texture_set_dirty = false;
- //update sky configuration if texture is missing
-
- if (sky->radiance.is_null()) {
- int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1;
-
- uint32_t w = sky->radiance_size, h = sky->radiance_size;
- int layers = roughness_layers;
- if (sky->mode == RS::SKY_MODE_REALTIME) {
- layers = 8;
- if (roughness_layers != 8) {
- WARN_PRINT("When using REALTIME skies, roughness_layers should be set to 8 in the project settings for best quality reflections");
- }
- }
-
- if (sky_use_cubemap_array) {
- //array (higher quality, 6 times more memory)
- RD::TextureFormat tf;
- tf.array_layers = layers * 6;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
- tf.mipmaps = mipmaps;
- tf.width = w;
- tf.height = h;
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
- sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- _update_reflection_data(sky->reflection, sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME);
-
- } else {
- //regular cubemap, lower quality (aliasing, less memory)
- RD::TextureFormat tf;
- tf.array_layers = 6;
- tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tf.texture_type = RD::TEXTURE_TYPE_CUBE;
- tf.mipmaps = MIN(mipmaps, layers);
- tf.width = w;
- tf.height = h;
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
- sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- _update_reflection_data(sky->reflection, sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME);
- }
- texture_set_dirty = true;
- }
-
- // Create subpass buffers if they haven't been created already
- if (sky->half_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->half_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) {
- RD::TextureFormat tformat;
- tformat.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tformat.width = sky->screen_size.x / 2;
- tformat.height = sky->screen_size.y / 2;
- tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
- tformat.texture_type = RD::TEXTURE_TYPE_2D;
-
- sky->half_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
- Vector<RID> texs;
- texs.push_back(sky->half_res_pass);
- sky->half_res_framebuffer = RD::get_singleton()->framebuffer_create(texs);
- texture_set_dirty = true;
- }
-
- if (sky->quarter_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->quarter_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) {
- RD::TextureFormat tformat;
- tformat.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- tformat.width = sky->screen_size.x / 4;
- tformat.height = sky->screen_size.y / 4;
- tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
- tformat.texture_type = RD::TEXTURE_TYPE_2D;
-
- sky->quarter_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
- Vector<RID> texs;
- texs.push_back(sky->quarter_res_pass);
- sky->quarter_res_framebuffer = RD::get_singleton()->framebuffer_create(texs);
- texture_set_dirty = true;
- }
-
- if (texture_set_dirty) {
- for (int i = 0; i < SKY_TEXTURE_SET_MAX; i++) {
- if (sky->texture_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(sky->texture_uniform_sets[i])) {
- RD::get_singleton()->free(sky->texture_uniform_sets[i]);
- sky->texture_uniform_sets[i] = RID();
- }
- }
- }
-
- sky->reflection.dirty = true;
- sky->processing_layer = 0;
-
- Sky *next = sky->dirty_list;
- sky->dirty_list = nullptr;
- sky->dirty = false;
- sky = next;
- }
-
- dirty_sky_list = nullptr;
+ return sky.sky_bake_panorama(p_sky, p_energy, p_bake_irradiance, p_size);
}
-RID RendererSceneRenderRD::sky_get_radiance_texture_rd(RID p_sky) const {
- Sky *sky = sky_owner.getornull(p_sky);
- ERR_FAIL_COND_V(!sky, RID());
-
- return sky->radiance;
+RID RendererSceneRenderRD::environment_allocate() {
+ return environment_owner.allocate_rid();
}
-
-RID RendererSceneRenderRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const {
- Sky *sky = sky_owner.getornull(p_sky);
- ERR_FAIL_COND_V(!sky, RID());
-
- if (sky->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(sky->uniform_set)) {
- sky->uniform_set = RID();
- if (sky->radiance.is_valid()) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 0;
- u.ids.push_back(sky->radiance);
- uniforms.push_back(u);
- }
-
- sky->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set);
- }
- }
-
- return sky->uniform_set;
-}
-
-RID RendererSceneRenderRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version) {
- if (p_sky->texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(p_sky->texture_uniform_sets[p_version])) {
- return p_sky->texture_uniform_sets[p_version];
- }
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 0;
- if (p_sky->radiance.is_valid() && p_version <= SKY_TEXTURE_SET_QUARTER_RES) {
- u.ids.push_back(p_sky->radiance);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1; // half res
- if (p_sky->half_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) {
- if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
- u.ids.push_back(p_sky->reflection.layers[0].views[1]);
- } else {
- u.ids.push_back(p_sky->half_res_pass);
- }
- } else {
- if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 2; // quarter res
- if (p_sky->quarter_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) {
- if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
- u.ids.push_back(p_sky->reflection.layers[0].views[2]);
- } else {
- u.ids.push_back(p_sky->quarter_res_pass);
- }
- } else {
- if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
- }
- }
- uniforms.push_back(u);
- }
-
- p_sky->texture_uniform_sets[p_version] = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_TEXTURES);
- return p_sky->texture_uniform_sets[p_version];
-}
-
-RID RendererSceneRenderRD::sky_get_material(RID p_sky) const {
- Sky *sky = sky_owner.getornull(p_sky);
- ERR_FAIL_COND_V(!sky, RID());
-
- return sky->material;
-}
-
-void RendererSceneRenderRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
- ERR_FAIL_COND(!is_environment(p_environment));
-
- SkyMaterialData *material = nullptr;
-
- Sky *sky = sky_owner.getornull(environment_get_sky(p_environment));
-
- RID sky_material;
-
- RS::EnvironmentBG background = environment_get_background(p_environment);
-
- if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) {
- ERR_FAIL_COND(!sky);
- sky_material = sky_get_material(environment_get_sky(p_environment));
-
- if (sky_material.is_valid()) {
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
- if (!material || !material->shader_data->valid) {
- material = nullptr;
- }
- }
-
- if (!material) {
- sky_material = sky_shader.default_material;
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
- }
- }
-
- if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
- sky_material = sky_scene_state.fog_material;
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
- }
-
- ERR_FAIL_COND(!material);
-
- SkyShaderData *shader_data = material->shader_data;
-
- ERR_FAIL_COND(!shader_data);
-
- Basis sky_transform = environment_get_sky_orientation(p_environment);
- sky_transform.invert();
-
- float multiplier = environment_get_bg_energy(p_environment);
- float custom_fov = environment_get_sky_custom_fov(p_environment);
- // Camera
- CameraMatrix camera;
-
- if (custom_fov) {
- float near_plane = p_projection.get_z_near();
- float far_plane = p_projection.get_z_far();
- float aspect = p_projection.get_aspect();
-
- camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
-
- } else {
- camera = p_projection;
- }
-
- sky_transform = p_transform.basis * sky_transform;
-
- if (shader_data->uses_quarter_res) {
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_QUARTER_RES];
-
- RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_QUARTER_RES);
-
- Vector<Color> clear_colors;
- clear_colors.push_back(Color(0.0, 0.0, 0.0));
-
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
- storage->get_effects()->render_sky(draw_list, time, sky->quarter_res_framebuffer, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
- RD::get_singleton()->draw_list_end();
- }
-
- if (shader_data->uses_half_res) {
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_HALF_RES];
-
- RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_HALF_RES);
-
- Vector<Color> clear_colors;
- clear_colors.push_back(Color(0.0, 0.0, 0.0));
-
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
- storage->get_effects()->render_sky(draw_list, time, sky->half_res_framebuffer, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
- RD::get_singleton()->draw_list_end();
- }
-
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_BACKGROUND];
-
- RID texture_uniform_set;
- if (sky) {
- texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_BACKGROUND);
- } else {
- texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
- }
-
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
- storage->get_effects()->render_sky(draw_list, time, p_fb, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
- RD::get_singleton()->draw_list_end();
-}
-
-void RendererSceneRenderRD::_setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size) {
- ERR_FAIL_COND(!is_environment(p_environment));
-
- SkyMaterialData *material = nullptr;
-
- Sky *sky = sky_owner.getornull(environment_get_sky(p_environment));
-
- RID sky_material;
-
- SkyShaderData *shader_data = nullptr;
-
- RS::EnvironmentBG background = environment_get_background(p_environment);
-
- if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) {
- ERR_FAIL_COND(!sky);
- sky_material = sky_get_material(environment_get_sky(p_environment));
-
- if (sky_material.is_valid()) {
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
- if (!material || !material->shader_data->valid) {
- material = nullptr;
- }
- }
-
- if (!material) {
- sky_material = sky_shader.default_material;
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
- }
-
- ERR_FAIL_COND(!material);
-
- shader_data = material->shader_data;
-
- ERR_FAIL_COND(!shader_data);
- }
-
- if (sky) {
- // Invalidate supbass buffers if screen size changes
- if (sky->screen_size != p_screen_size) {
- sky->screen_size = p_screen_size;
- sky->screen_size.x = sky->screen_size.x < 4 ? 4 : sky->screen_size.x;
- sky->screen_size.y = sky->screen_size.y < 4 ? 4 : sky->screen_size.y;
- if (shader_data->uses_half_res) {
- if (sky->half_res_pass.is_valid()) {
- RD::get_singleton()->free(sky->half_res_pass);
- sky->half_res_pass = RID();
- }
- _sky_invalidate(sky);
- }
- if (shader_data->uses_quarter_res) {
- if (sky->quarter_res_pass.is_valid()) {
- RD::get_singleton()->free(sky->quarter_res_pass);
- sky->quarter_res_pass = RID();
- }
- _sky_invalidate(sky);
- }
- }
-
- // Create new subpass buffers if necessary
- if ((shader_data->uses_half_res && sky->half_res_pass.is_null()) ||
- (shader_data->uses_quarter_res && sky->quarter_res_pass.is_null()) ||
- sky->radiance.is_null()) {
- _sky_invalidate(sky);
- _update_dirty_skys();
- }
-
- if (shader_data->uses_time && time - sky->prev_time > 0.00001) {
- sky->prev_time = time;
- sky->reflection.dirty = true;
- RenderingServerDefault::redraw_request();
- }
-
- if (material != sky->prev_material) {
- sky->prev_material = material;
- sky->reflection.dirty = true;
- }
-
- if (material->uniform_set_updated) {
- material->uniform_set_updated = false;
- sky->reflection.dirty = true;
- }
-
- if (!p_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) {
- sky->prev_position = p_transform.origin;
- sky->reflection.dirty = true;
- }
-
- if (shader_data->uses_light) {
- // Check whether the directional_light_buffer changes
- bool light_data_dirty = false;
-
- if (sky_scene_state.ubo.directional_light_count != sky_scene_state.last_frame_directional_light_count) {
- light_data_dirty = true;
- for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) {
- sky_scene_state.directional_lights[i].enabled = false;
- }
- }
- if (!light_data_dirty) {
- for (uint32_t i = 0; i < sky_scene_state.ubo.directional_light_count; i++) {
- if (sky_scene_state.directional_lights[i].direction[0] != sky_scene_state.last_frame_directional_lights[i].direction[0] ||
- sky_scene_state.directional_lights[i].direction[1] != sky_scene_state.last_frame_directional_lights[i].direction[1] ||
- sky_scene_state.directional_lights[i].direction[2] != sky_scene_state.last_frame_directional_lights[i].direction[2] ||
- sky_scene_state.directional_lights[i].energy != sky_scene_state.last_frame_directional_lights[i].energy ||
- sky_scene_state.directional_lights[i].color[0] != sky_scene_state.last_frame_directional_lights[i].color[0] ||
- sky_scene_state.directional_lights[i].color[1] != sky_scene_state.last_frame_directional_lights[i].color[1] ||
- sky_scene_state.directional_lights[i].color[2] != sky_scene_state.last_frame_directional_lights[i].color[2] ||
- sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled ||
- sky_scene_state.directional_lights[i].size != sky_scene_state.last_frame_directional_lights[i].size) {
- light_data_dirty = true;
- break;
- }
- }
- }
-
- if (light_data_dirty) {
- RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights, true);
-
- RendererSceneRenderRD::SkyDirectionalLightData *temp = sky_scene_state.last_frame_directional_lights;
- sky_scene_state.last_frame_directional_lights = sky_scene_state.directional_lights;
- sky_scene_state.directional_lights = temp;
- sky_scene_state.last_frame_directional_light_count = sky_scene_state.ubo.directional_light_count;
- sky->reflection.dirty = true;
- }
- }
- }
-
- //setup fog variables
- sky_scene_state.ubo.volumetric_fog_enabled = false;
- if (p_render_buffers.is_valid()) {
- if (render_buffers_has_volumetric_fog(p_render_buffers)) {
- sky_scene_state.ubo.volumetric_fog_enabled = true;
-
- float fog_end = render_buffers_get_volumetric_fog_end(p_render_buffers);
- if (fog_end > 0.0) {
- sky_scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end;
- } else {
- sky_scene_state.ubo.volumetric_fog_inv_length = 1.0;
- }
-
- float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_buffers); //reverse lookup
- if (fog_detail_spread > 0.0) {
- sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread;
- } else {
- sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0;
- }
- }
-
- RID fog_uniform_set = render_buffers_get_volumetric_fog_sky_uniform_set(p_render_buffers);
-
- if (fog_uniform_set != RID()) {
- sky_scene_state.fog_uniform_set = fog_uniform_set;
- } else {
- sky_scene_state.fog_uniform_set = sky_scene_state.default_fog_uniform_set;
- }
- }
-
- sky_scene_state.ubo.z_far = p_projection.get_z_far();
- sky_scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_environment);
- sky_scene_state.ubo.fog_density = environment_get_fog_density(p_environment);
- sky_scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_environment);
- Color fog_color = environment_get_fog_light_color(p_environment).to_linear();
- float fog_energy = environment_get_fog_light_energy(p_environment);
- sky_scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
- sky_scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;
- sky_scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy;
- sky_scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_environment);
-
- RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo, true);
-}
-
-void RendererSceneRenderRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
- ERR_FAIL_COND(!is_environment(p_environment));
-
- Sky *sky = sky_owner.getornull(environment_get_sky(p_environment));
- ERR_FAIL_COND(!sky);
-
- RID sky_material = sky_get_material(environment_get_sky(p_environment));
-
- SkyMaterialData *material = nullptr;
-
- if (sky_material.is_valid()) {
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
- if (!material || !material->shader_data->valid) {
- material = nullptr;
- }
- }
-
- if (!material) {
- sky_material = sky_shader.default_material;
- material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
- }
-
- ERR_FAIL_COND(!material);
-
- SkyShaderData *shader_data = material->shader_data;
-
- ERR_FAIL_COND(!shader_data);
-
- float multiplier = environment_get_bg_energy(p_environment);
-
- bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY;
- RS::SkyMode sky_mode = sky->mode;
-
- if (sky_mode == RS::SKY_MODE_AUTOMATIC) {
- if (shader_data->uses_time || shader_data->uses_position) {
- update_single_frame = true;
- sky_mode = RS::SKY_MODE_REALTIME;
- } else if (shader_data->uses_light || shader_data->ubo_size > 0) {
- update_single_frame = false;
- sky_mode = RS::SKY_MODE_INCREMENTAL;
- } else {
- update_single_frame = true;
- sky_mode = RS::SKY_MODE_QUALITY;
- }
- }
-
- if (sky->processing_layer == 0 && sky_mode == RS::SKY_MODE_INCREMENTAL) {
- // On the first frame after creating sky, rebuild in single frame
- update_single_frame = true;
- sky_mode = RS::SKY_MODE_QUALITY;
- }
-
- int max_processing_layer = sky_use_cubemap_array ? sky->reflection.layers.size() : sky->reflection.layers[0].mipmaps.size();
-
- // Update radiance cubemap
- if (sky->reflection.dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) {
- static const Vector3 view_normals[6] = {
- Vector3(+1, 0, 0),
- Vector3(-1, 0, 0),
- Vector3(0, +1, 0),
- Vector3(0, -1, 0),
- Vector3(0, 0, +1),
- Vector3(0, 0, -1)
- };
- static const Vector3 view_up[6] = {
- Vector3(0, -1, 0),
- Vector3(0, -1, 0),
- Vector3(0, 0, +1),
- Vector3(0, 0, -1),
- Vector3(0, -1, 0),
- Vector3(0, -1, 0)
- };
-
- CameraMatrix cm;
- cm.set_perspective(90, 1, 0.01, 10.0);
- CameraMatrix correction;
- correction.set_depth_correction(true);
- cm = correction * cm;
-
- if (shader_data->uses_quarter_res) {
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES];
-
- Vector<Color> clear_colors;
- clear_colors.push_back(Color(0.0, 0.0, 0.0));
- RD::DrawListID cubemap_draw_list;
-
- for (int i = 0; i < 6; i++) {
- Transform local_view;
- local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
- RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES);
-
- cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- storage->get_effects()->render_sky(cubemap_draw_list, time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
- RD::get_singleton()->draw_list_end();
- }
- }
-
- if (shader_data->uses_half_res) {
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES];
-
- Vector<Color> clear_colors;
- clear_colors.push_back(Color(0.0, 0.0, 0.0));
- RD::DrawListID cubemap_draw_list;
-
- for (int i = 0; i < 6; i++) {
- Transform local_view;
- local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
- RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_CUBEMAP_HALF_RES);
-
- cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- storage->get_effects()->render_sky(cubemap_draw_list, time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
- RD::get_singleton()->draw_list_end();
- }
- }
-
- RD::DrawListID cubemap_draw_list;
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP];
-
- for (int i = 0; i < 6; i++) {
- Transform local_view;
- local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
- RID texture_uniform_set = _get_sky_textures(sky, SKY_TEXTURE_SET_CUBEMAP);
-
- cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- storage->get_effects()->render_sky(cubemap_draw_list, time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
- RD::get_singleton()->draw_list_end();
- }
-
- if (sky_mode == RS::SKY_MODE_REALTIME) {
- _create_reflection_fast_filter(sky->reflection, sky_use_cubemap_array);
- if (sky_use_cubemap_array) {
- _update_reflection_mipmaps(sky->reflection, 0, sky->reflection.layers.size());
- }
- } else {
- if (update_single_frame) {
- for (int i = 1; i < max_processing_layer; i++) {
- _create_reflection_importance_sample(sky->reflection, sky_use_cubemap_array, 10, i);
- }
- if (sky_use_cubemap_array) {
- _update_reflection_mipmaps(sky->reflection, 0, sky->reflection.layers.size());
- }
- } else {
- if (sky_use_cubemap_array) {
- // Multi-Frame so just update the first array level
- _update_reflection_mipmaps(sky->reflection, 0, 1);
- }
- }
- sky->processing_layer = 1;
- }
-
- sky->reflection.dirty = false;
-
- } else {
- if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {
- _create_reflection_importance_sample(sky->reflection, sky_use_cubemap_array, 10, sky->processing_layer);
-
- if (sky_use_cubemap_array) {
- _update_reflection_mipmaps(sky->reflection, sky->processing_layer, sky->processing_layer + 1);
- }
-
- sky->processing_layer++;
- }
- }
-}
-
-/* SKY SHADER */
-
-void RendererSceneRenderRD::SkyShaderData::set_code(const String &p_code) {
- //compile
-
- code = p_code;
- valid = false;
- ubo_size = 0;
- uniforms.clear();
-
- if (code == String()) {
- return; //just invalid, but no error
- }
-
- ShaderCompilerRD::GeneratedCode gen_code;
- ShaderCompilerRD::IdentifierActions actions;
-
- uses_time = false;
- uses_half_res = false;
- uses_quarter_res = false;
- uses_position = false;
- uses_light = false;
-
- actions.render_mode_flags["use_half_res_pass"] = &uses_half_res;
- actions.render_mode_flags["use_quarter_res_pass"] = &uses_quarter_res;
-
- actions.usage_flag_pointers["TIME"] = &uses_time;
- actions.usage_flag_pointers["POSITION"] = &uses_position;
- actions.usage_flag_pointers["LIGHT0_ENABLED"] = &uses_light;
- actions.usage_flag_pointers["LIGHT0_ENERGY"] = &uses_light;
- actions.usage_flag_pointers["LIGHT0_DIRECTION"] = &uses_light;
- actions.usage_flag_pointers["LIGHT0_COLOR"] = &uses_light;
- actions.usage_flag_pointers["LIGHT0_SIZE"] = &uses_light;
- actions.usage_flag_pointers["LIGHT1_ENABLED"] = &uses_light;
- actions.usage_flag_pointers["LIGHT1_ENERGY"] = &uses_light;
- actions.usage_flag_pointers["LIGHT1_DIRECTION"] = &uses_light;
- actions.usage_flag_pointers["LIGHT1_COLOR"] = &uses_light;
- actions.usage_flag_pointers["LIGHT1_SIZE"] = &uses_light;
- actions.usage_flag_pointers["LIGHT2_ENABLED"] = &uses_light;
- actions.usage_flag_pointers["LIGHT2_ENERGY"] = &uses_light;
- actions.usage_flag_pointers["LIGHT2_DIRECTION"] = &uses_light;
- actions.usage_flag_pointers["LIGHT2_COLOR"] = &uses_light;
- actions.usage_flag_pointers["LIGHT2_SIZE"] = &uses_light;
- actions.usage_flag_pointers["LIGHT3_ENABLED"] = &uses_light;
- actions.usage_flag_pointers["LIGHT3_ENERGY"] = &uses_light;
- actions.usage_flag_pointers["LIGHT3_DIRECTION"] = &uses_light;
- actions.usage_flag_pointers["LIGHT3_COLOR"] = &uses_light;
- actions.usage_flag_pointers["LIGHT3_SIZE"] = &uses_light;
-
- actions.uniforms = &uniforms;
-
- RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
-
- Error err = scene_singleton->sky_shader.compiler.compile(RS::SHADER_SKY, code, &actions, path, gen_code);
-
- ERR_FAIL_COND(err != OK);
-
- if (version.is_null()) {
- version = scene_singleton->sky_shader.shader.version_create();
- }
-
-#if 0
- print_line("**compiling shader:");
- print_line("**defines:\n");
- for (int i = 0; i < gen_code.defines.size(); i++) {
- print_line(gen_code.defines[i]);
- }
- print_line("\n**uniforms:\n" + gen_code.uniforms);
- // print_line("\n**vertex_globals:\n" + gen_code.vertex_global);
- // print_line("\n**vertex_code:\n" + gen_code.vertex);
- print_line("\n**fragment_globals:\n" + gen_code.fragment_global);
- print_line("\n**fragment_code:\n" + gen_code.fragment);
- print_line("\n**light_code:\n" + gen_code.light);
-#endif
-
- scene_singleton->sky_shader.shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines);
- ERR_FAIL_COND(!scene_singleton->sky_shader.shader.version_is_valid(version));
-
- ubo_size = gen_code.uniform_total_size;
- ubo_offsets = gen_code.uniform_offsets;
- texture_uniforms = gen_code.texture_uniforms;
-
- //update pipelines
-
- for (int i = 0; i < SKY_VERSION_MAX; i++) {
- RD::PipelineDepthStencilState depth_stencil_state;
- depth_stencil_state.enable_depth_test = true;
- depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
-
- RID shader_variant = scene_singleton->sky_shader.shader.version_get_shader(version, i);
- pipelines[i].setup(shader_variant, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0);
- }
-
- valid = true;
-}
-
-void RendererSceneRenderRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
- if (!p_texture.is_valid()) {
- default_texture_params.erase(p_name);
- } else {
- default_texture_params[p_name] = p_texture;
- }
-}
-
-void RendererSceneRenderRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
- Map<int, StringName> order;
-
- for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
- if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
- continue;
- }
-
- if (E->get().texture_order >= 0) {
- order[E->get().texture_order + 100000] = E->key();
- } else {
- order[E->get().order] = E->key();
- }
- }
-
- for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
- PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
- pi.name = E->get();
- p_param_list->push_back(pi);
- }
-}
-
-void RendererSceneRenderRD::SkyShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
- for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
- if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
- continue;
- }
-
- RendererStorage::InstanceShaderParam p;
- p.info = ShaderLanguage::uniform_to_property_info(E->get());
- p.info.name = E->key(); //supply name
- p.index = E->get().instance_index;
- p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint);
- p_param_list->push_back(p);
- }
-}
-
-bool RendererSceneRenderRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
- if (!uniforms.has(p_param)) {
- return false;
- }
-
- return uniforms[p_param].texture_order >= 0;
-}
-
-bool RendererSceneRenderRD::SkyShaderData::is_animated() const {
- return false;
-}
-
-bool RendererSceneRenderRD::SkyShaderData::casts_shadows() const {
- return false;
-}
-
-Variant RendererSceneRenderRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
- if (uniforms.has(p_parameter)) {
- ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
- Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
- return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
- }
- return Variant();
-}
-
-RendererSceneRenderRD::SkyShaderData::SkyShaderData() {
- valid = false;
-}
-
-RendererSceneRenderRD::SkyShaderData::~SkyShaderData() {
- RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
- ERR_FAIL_COND(!scene_singleton);
- //pipeline variants will clear themselves if shader is gone
- if (version.is_valid()) {
- scene_singleton->sky_shader.shader.version_free(version);
- }
-}
-
-RendererStorageRD::ShaderData *RendererSceneRenderRD::_create_sky_shader_func() {
- SkyShaderData *shader_data = memnew(SkyShaderData);
- return shader_data;
-}
-
-void RendererSceneRenderRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
- RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
-
- uniform_set_updated = true;
-
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
-}
-
-RendererSceneRenderRD::SkyMaterialData::~SkyMaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
-}
-
-RendererStorageRD::MaterialData *RendererSceneRenderRD::_create_sky_material_func(SkyShaderData *p_shader) {
- SkyMaterialData *material_data = memnew(SkyMaterialData);
- material_data->shader_data = p_shader;
- material_data->last_frame = false;
- //update will happen later anyway so do nothing.
- return material_data;
-}
-
-RID RendererSceneRenderRD::environment_create() {
- return environment_owner.make_rid(Environment());
+void RendererSceneRenderRD::environment_initialize(RID p_rid) {
+ environment_owner.initialize_rid(p_rid, RendererSceneEnvironmentRD());
}
void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->background = p_bg;
}
void RendererSceneRenderRD::environment_set_sky(RID p_env, RID p_sky) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky = p_sky;
}
void RendererSceneRenderRD::environment_set_sky_custom_fov(RID p_env, float p_scale) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky_custom_fov = p_scale;
}
void RendererSceneRenderRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky_orientation = p_orientation;
}
void RendererSceneRenderRD::environment_set_bg_color(RID p_env, const Color &p_color) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_color = p_color;
}
void RendererSceneRenderRD::environment_set_bg_energy(RID p_env, float p_energy) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_energy = p_energy;
}
void RendererSceneRenderRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->canvas_max_layer = p_max_layer;
}
void RendererSceneRenderRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- env->ambient_light = p_color;
- env->ambient_source = p_ambient;
- env->ambient_light_energy = p_energy;
- env->ambient_sky_contribution = p_sky_contribution;
- env->reflection_source = p_reflection_source;
- env->ao_color = p_ao_color;
+ env->set_ambient_light(p_color, p_ambient, p_energy, p_sky_contribution, p_reflection_source, p_ao_color);
}
RS::EnvironmentBG RendererSceneRenderRD::environment_get_background(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX);
return env->background;
}
RID RendererSceneRenderRD::environment_get_sky(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RID());
return env->sky;
}
float RendererSceneRenderRD::environment_get_sky_custom_fov(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->sky_custom_fov;
}
Basis RendererSceneRenderRD::environment_get_sky_orientation(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Basis());
return env->sky_orientation;
}
Color RendererSceneRenderRD::environment_get_bg_color(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->bg_color;
}
float RendererSceneRenderRD::environment_get_bg_energy(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->bg_energy;
}
int RendererSceneRenderRD::environment_get_canvas_max_layer(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->canvas_max_layer;
}
Color RendererSceneRenderRD::environment_get_ambient_light_color(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->ambient_light;
}
RS::EnvironmentAmbientSource RendererSceneRenderRD::environment_get_ambient_source(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG);
return env->ambient_source;
}
float RendererSceneRenderRD::environment_get_ambient_light_energy(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_light_energy;
}
float RendererSceneRenderRD::environment_get_ambient_sky_contribution(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_sky_contribution;
}
RS::EnvironmentReflectionSource RendererSceneRenderRD::environment_get_reflection_source(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED);
return env->reflection_source;
}
Color RendererSceneRenderRD::environment_get_ao_color(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->ao_color;
}
void RendererSceneRenderRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- env->exposure = p_exposure;
- env->tone_mapper = p_tone_mapper;
- if (!env->auto_exposure && p_auto_exposure) {
- env->auto_exposure_version = ++auto_exposure_counter;
- }
- env->auto_exposure = p_auto_exposure;
- env->white = p_white;
- env->min_luminance = p_min_luminance;
- env->max_luminance = p_max_luminance;
- env->auto_exp_speed = p_auto_exp_speed;
- env->auto_exp_scale = p_auto_exp_scale;
+ env->set_tonemap(p_tone_mapper, p_exposure, p_white, p_auto_exposure, p_min_luminance, p_max_luminance, p_auto_exp_speed, p_auto_exp_scale);
}
void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7");
- env->glow_enabled = p_enable;
- env->glow_levels = p_levels;
- env->glow_intensity = p_intensity;
- env->glow_strength = p_strength;
- env->glow_mix = p_mix;
- env->glow_bloom = p_bloom_threshold;
- env->glow_blend_mode = p_blend_mode;
- env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold;
- env->glow_hdr_bleed_scale = p_hdr_bleed_scale;
- env->glow_hdr_luminance_cap = p_hdr_luminance_cap;
+ env->set_glow(p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap);
}
void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enable) {
@@ -2967,100 +313,77 @@ void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable)
glow_high_quality = p_enable;
}
-void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
- Environment *env = environment_owner.getornull(p_env);
+void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
if (low_end) {
return;
}
- env->sdfgi_enabled = p_enable;
- env->sdfgi_cascades = p_cascades;
- env->sdfgi_min_cell_size = p_min_cell_size;
- env->sdfgi_use_occlusion = p_use_occlusion;
- env->sdfgi_use_multibounce = p_use_multibounce;
- env->sdfgi_read_sky_light = p_read_sky;
- env->sdfgi_energy = p_energy;
- env->sdfgi_normal_bias = p_normal_bias;
- env->sdfgi_probe_bias = p_probe_bias;
- env->sdfgi_y_scale = p_y_scale;
+ env->set_sdfgi(p_enable, p_cascades, p_min_cell_size, p_y_scale, p_use_occlusion, p_bounce_feedback, p_read_sky, p_energy, p_normal_bias, p_probe_bias);
}
void RendererSceneRenderRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- env->fog_enabled = p_enable;
- env->fog_light_color = p_light_color;
- env->fog_light_energy = p_light_energy;
- env->fog_sun_scatter = p_sun_scatter;
- env->fog_density = p_density;
- env->fog_height = p_height;
- env->fog_height_density = p_height_density;
- env->fog_aerial_perspective = p_fog_aerial_perspective;
+ env->set_fog(p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_fog_aerial_perspective);
}
bool RendererSceneRenderRD::environment_is_fog_enabled(RID p_env) const {
- const Environment *env = environment_owner.getornull(p_env);
+ const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->fog_enabled;
}
Color RendererSceneRenderRD::environment_get_fog_light_color(RID p_env) const {
- const Environment *env = environment_owner.getornull(p_env);
+ const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->fog_light_color;
}
float RendererSceneRenderRD::environment_get_fog_light_energy(RID p_env) const {
- const Environment *env = environment_owner.getornull(p_env);
+ const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_light_energy;
}
float RendererSceneRenderRD::environment_get_fog_sun_scatter(RID p_env) const {
- const Environment *env = environment_owner.getornull(p_env);
+ const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_sun_scatter;
}
float RendererSceneRenderRD::environment_get_fog_density(RID p_env) const {
- const Environment *env = environment_owner.getornull(p_env);
+ const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_density;
}
float RendererSceneRenderRD::environment_get_fog_height(RID p_env) const {
- const Environment *env = environment_owner.getornull(p_env);
+ const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_height;
}
float RendererSceneRenderRD::environment_get_fog_height_density(RID p_env) const {
- const Environment *env = environment_owner.getornull(p_env);
+ const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_height_density;
}
float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) const {
- const Environment *env = environment_owner.getornull(p_env);
+ const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->fog_aerial_perspective;
}
-void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) {
- Environment *env = environment_owner.getornull(p_env);
+void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) {
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
if (low_end) {
return;
}
- env->volumetric_fog_enabled = p_enable;
- env->volumetric_fog_density = p_density;
- env->volumetric_fog_light = p_light;
- env->volumetric_fog_light_energy = p_light_energy;
- env->volumetric_fog_length = p_length;
- env->volumetric_fog_detail_spread = p_detail_spread;
- env->volumetric_fog_shadow_filter = p_shadow_filter;
- env->volumetric_fog_gi_inject = p_gi_inject;
+ env->set_volumetric_fog(p_enable, p_density, p_light, p_light_energy, p_length, p_detail_spread, p_gi_inject, p_temporal_reprojection, p_temporal_reprojection_amount);
}
void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) {
@@ -3071,47 +394,27 @@ void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_siz
void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) {
volumetric_fog_filter_active = p_enable;
}
-void RendererSceneRenderRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) {
- p_shrink_size = nearest_power_of_2_templated(p_shrink_size);
- if (volumetric_fog_directional_shadow_shrink == (uint32_t)p_shrink_size) {
- return;
- }
-
- _clear_shadow_shrink_stages(directional_shadow.shrink_stages);
-}
-void RendererSceneRenderRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) {
- p_shrink_size = nearest_power_of_2_templated(p_shrink_size);
- if (volumetric_fog_positional_shadow_shrink == (uint32_t)p_shrink_size) {
- return;
- }
-
- for (uint32_t i = 0; i < shadow_atlas_owner.get_rid_count(); i++) {
- ShadowAtlas *sa = shadow_atlas_owner.get_ptr_by_index(i);
- _clear_shadow_shrink_stages(sa->shrink_stages);
- }
-}
void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {
- sdfgi_ray_count = p_ray_count;
+ gi.sdfgi_ray_count = p_ray_count;
}
void RendererSceneRenderRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {
- sdfgi_frames_to_converge = p_frames;
+ gi.sdfgi_frames_to_converge = p_frames;
+}
+void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) {
+ gi.sdfgi_frames_to_update_light = p_update;
}
void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
if (low_end) {
return;
}
- env->ssr_enabled = p_enable;
- env->ssr_max_steps = p_max_steps;
- env->ssr_fade_in = p_fade_int;
- env->ssr_fade_out = p_fade_out;
- env->ssr_depth_tolerance = p_depth_tolerance;
+ env->set_ssr(p_enable, p_max_steps, p_fade_int, p_fade_out, p_depth_tolerance);
}
void RendererSceneRenderRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {
@@ -3123,22 +426,14 @@ RS::EnvironmentSSRRoughnessQuality RendererSceneRenderRD::environment_get_ssr_ro
}
void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
if (low_end) {
return;
}
- env->ssao_enabled = p_enable;
- env->ssao_radius = p_radius;
- env->ssao_intensity = p_intensity;
- env->ssao_power = p_power;
- env->ssao_detail = p_detail;
- env->ssao_horizon = p_horizon;
- env->ssao_sharpness = p_sharpness;
- env->ssao_direct_light_affect = p_light_affect;
- env->ssao_ao_channel_affect = p_ao_channel_affect;
+ env->set_ssao(p_enable, p_radius, p_intensity, p_power, p_detail, p_horizon, p_sharpness, p_light_affect, p_ao_channel_affect);
}
void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) {
@@ -3151,30 +446,30 @@ void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQual
}
bool RendererSceneRenderRD::environment_is_ssao_enabled(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->ssao_enabled;
}
float RendererSceneRenderRD::environment_get_ssao_ao_affect(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0.0);
return env->ssao_ao_channel_affect;
}
float RendererSceneRenderRD::environment_get_ssao_light_affect(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0.0);
return env->ssao_direct_light_affect;
}
bool RendererSceneRenderRD::environment_is_ssr_enabled(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->ssr_enabled;
}
bool RendererSceneRenderRD::environment_is_sdfgi_enabled(RID p_env) const {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->sdfgi_enabled;
}
@@ -3184,7 +479,7 @@ bool RendererSceneRenderRD::is_environment(RID p_env) const {
}
Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Ref<Image>());
if (env->background == RS::ENV_BG_CAMERA_FEED || env->background == RS::ENV_BG_CANVAS || env->background == RS::ENV_BG_KEEP) {
@@ -3224,8 +519,12 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba
RID RendererSceneRenderRD::reflection_atlas_create() {
ReflectionAtlas ra;
- ra.count = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_count");
- ra.size = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_size");
+ ra.count = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_count");
+ ra.size = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_size");
+
+ ra.cluster_builder = memnew(ClusterBuilderRD);
+ ra.cluster_builder->set_shared(&cluster_builder_shared);
+ ra.cluster_builder->setup(Size2i(ra.size, ra.size), max_cluster_elements, RID(), RID(), RID());
return reflection_atlas_owner.make_rid(ra);
}
@@ -3238,6 +537,8 @@ void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_ref
return; //no changes
}
+ ra->cluster_builder->setup(Size2i(ra->size, ra->size), max_cluster_elements, RID(), RID(), RID());
+
ra->size = p_reflection_size;
ra->count = p_reflection_count;
@@ -3247,9 +548,8 @@ void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_ref
ra->reflection = RID();
RD::get_singleton()->free(ra->depth_buffer);
ra->depth_buffer = RID();
-
for (int i = 0; i < ra->reflections.size(); i++) {
- _clear_reflection_data(ra->reflections.write[i].data);
+ ra->reflections.write[i].data.clear_reflection_data();
if (ra->reflections[i].owner.is_null()) {
continue;
}
@@ -3353,7 +653,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
}
if (atlas->reflection.is_null()) {
- int mipmaps = MIN(roughness_layers, Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) + 1);
+ int mipmaps = MIN(sky.roughness_layers, Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) + 1);
mipmaps = storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS ? 8 : mipmaps; // always use 8 mipmaps with real time filtering
{
//reflection atlas was unused, create:
@@ -3378,7 +678,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
}
atlas->reflections.resize(atlas->count);
for (int i = 0; i < atlas->count; i++) {
- _update_reflection_data(atlas->reflections.write[i].data, atlas->size, mipmaps, false, atlas->reflection, i * 6, storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS);
+ atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers);
for (int j = 0; j < 6; j++) {
Vector<RID> fb;
fb.push_back(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j]);
@@ -3438,7 +738,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
if (storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
// Using real time reflections, all roughness is done in one step
- _create_reflection_fast_filter(atlas->reflections.write[rpi->atlas_index].data, false);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(storage, false);
rpi->rendering = false;
rpi->processing_side = 0;
rpi->processing_layer = 1;
@@ -3446,7 +746,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
}
if (rpi->processing_layer > 1) {
- _create_reflection_importance_sample(atlas->reflections.write[rpi->atlas_index].data, false, 10, rpi->processing_layer);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(storage, false, 10, rpi->processing_layer, sky.sky_ggx_samples_quality);
rpi->processing_layer++;
if (rpi->processing_layer == atlas->reflections[rpi->atlas_index].data.layers[0].mipmaps.size()) {
rpi->rendering = false;
@@ -3457,7 +757,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
return false;
} else {
- _create_reflection_importance_sample(atlas->reflections.write[rpi->atlas_index].data, false, rpi->processing_side, rpi->processing_layer);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(storage, false, rpi->processing_side, rpi->processing_layer, sky.sky_ggx_samples_quality);
}
rpi->processing_side++;
@@ -3504,13 +804,28 @@ RID RendererSceneRenderRD::shadow_atlas_create() {
return shadow_atlas_owner.make_rid(ShadowAtlas());
}
-void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
+void RendererSceneRenderRD::_update_shadow_atlas(ShadowAtlas *shadow_atlas) {
+ if (shadow_atlas->size > 0 && shadow_atlas->depth.is_null()) {
+ RD::TextureFormat tf;
+ tf.format = shadow_atlas->use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
+ tf.width = shadow_atlas->size;
+ tf.height = shadow_atlas->size;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+
+ shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ Vector<RID> fb_tex;
+ fb_tex.push_back(shadow_atlas->depth);
+ shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb_tex);
+ }
+}
+
+void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND(!shadow_atlas);
ERR_FAIL_COND(p_size < 0);
p_size = next_power_of_2(p_size);
- if (p_size == shadow_atlas->size) {
+ if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) {
return;
}
@@ -3518,7 +833,6 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
if (shadow_atlas->depth.is_valid()) {
RD::get_singleton()->free(shadow_atlas->depth);
shadow_atlas->depth = RID();
- _clear_shadow_shrink_stages(shadow_atlas->shrink_stages);
}
for (int i = 0; i < 4; i++) {
//clear subdivisions
@@ -3537,16 +851,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
shadow_atlas->shadow_owners.clear();
shadow_atlas->size = p_size;
-
- if (shadow_atlas->size) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
- tf.width = shadow_atlas->size;
- tf.height = shadow_atlas->size;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
- shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
- }
+ shadow_atlas->use_16_bits = p_size;
}
void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
@@ -3801,10 +1106,24 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i
return false;
}
-void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
+void RendererSceneRenderRD::_update_directional_shadow_atlas() {
+ if (directional_shadow.depth.is_null() && directional_shadow.size > 0) {
+ RD::TextureFormat tf;
+ tf.format = directional_shadow.use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
+ tf.width = directional_shadow.size;
+ tf.height = directional_shadow.size;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+
+ directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ Vector<RID> fb_tex;
+ fb_tex.push_back(directional_shadow.depth);
+ directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb_tex);
+ }
+}
+void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
p_size = nearest_power_of_2_templated(p_size);
- if (directional_shadow.size == p_size) {
+ if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) {
return;
}
@@ -3812,21 +1131,9 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
if (directional_shadow.depth.is_valid()) {
RD::get_singleton()->free(directional_shadow.depth);
- _clear_shadow_shrink_stages(directional_shadow.shrink_stages);
directional_shadow.depth = RID();
+ _base_uniforms_changed();
}
-
- if (p_size > 0) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
- tf.width = p_size;
- tf.height = p_size;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
- directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
- }
-
- _base_uniforms_changed();
}
void RendererSceneRenderRD::set_directional_shadow_count(int p_count) {
@@ -3880,8 +1187,11 @@ int RendererSceneRenderRD::get_directional_light_shadow_size(RID p_light_intance
//////////////////////////////////////////////////
-RID RendererSceneRenderRD::camera_effects_create() {
- return camera_effects_owner.make_rid(CameraEffects());
+RID RendererSceneRenderRD::camera_effects_allocate() {
+ return camera_effects_owner.allocate_rid();
+}
+void RendererSceneRenderRD::camera_effects_initialize(RID p_rid) {
+ camera_effects_owner.initialize_rid(p_rid, CameraEffects());
}
void RendererSceneRenderRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) {
@@ -3946,11 +1256,7 @@ void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_inst
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
- if (storage->light_get_type(light_instance->light) != RS::LIGHT_DIRECTIONAL) {
- p_pass = 0;
- }
-
- ERR_FAIL_INDEX(p_pass, 4);
+ ERR_FAIL_INDEX(p_pass, 6);
light_instance->shadow_transform[p_pass].camera = p_projection;
light_instance->shadow_transform[p_pass].transform = p_transform;
@@ -3996,29 +1302,6 @@ RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap
return &shadow_cubemaps[p_size];
}
-RendererSceneRenderRD::ShadowMap *RendererSceneRenderRD::_get_shadow_map(const Size2i &p_size) {
- if (!shadow_maps.has(p_size)) {
- ShadowMap sm;
- {
- RD::TextureFormat tf;
- tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
- tf.width = p_size.width;
- tf.height = p_size.height;
- tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
-
- sm.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
- }
-
- Vector<RID> fbtex;
- fbtex.push_back(sm.depth);
- sm.fb = RD::get_singleton()->framebuffer_create(fbtex);
-
- shadow_maps[p_size] = sm;
- }
-
- return &shadow_maps[p_size];
-}
-
//////////////////////////
RID RendererSceneRenderRD::decal_instance_create(RID p_decal) {
@@ -4035,809 +1318,41 @@ void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Tran
/////////////////////////////////
+RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) {
+ LightmapInstance li;
+ li.lightmap = p_lightmap;
+ return lightmap_instance_owner.make_rid(li);
+}
+void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) {
+ LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap);
+ ERR_FAIL_COND(!li);
+ li->transform = p_transform;
+}
+
+/////////////////////////////////
+
RID RendererSceneRenderRD::gi_probe_instance_create(RID p_base) {
- GIProbeInstance gi_probe;
- gi_probe.probe = p_base;
- RID rid = gi_probe_instance_owner.make_rid(gi_probe);
- return rid;
+ return gi.gi_probe_instance_create(p_base);
}
void RendererSceneRenderRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
- ERR_FAIL_COND(!gi_probe);
-
- gi_probe->transform = p_xform;
+ gi.gi_probe_instance_set_transform_to_data(p_probe, p_xform);
}
bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
- ERR_FAIL_COND_V(!gi_probe, false);
-
if (low_end) {
return false;
}
- //return true;
- return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
+ return gi.gi_probe_needs_update(p_probe);
}
-void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<InstanceBase *> &p_dynamic_objects) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
- ERR_FAIL_COND(!gi_probe);
-
+void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) {
if (low_end) {
return;
}
- uint32_t data_version = storage->gi_probe_get_data_version(gi_probe->probe);
-
- // (RE)CREATE IF NEEDED
-
- if (gi_probe->last_probe_data_version != data_version) {
- //need to re-create everything
- if (gi_probe->texture.is_valid()) {
- RD::get_singleton()->free(gi_probe->texture);
- RD::get_singleton()->free(gi_probe->write_buffer);
- gi_probe->mipmaps.clear();
- }
-
- for (int i = 0; i < gi_probe->dynamic_maps.size(); i++) {
- RD::get_singleton()->free(gi_probe->dynamic_maps[i].texture);
- RD::get_singleton()->free(gi_probe->dynamic_maps[i].depth);
- }
-
- gi_probe->dynamic_maps.clear();
-
- Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe);
-
- if (octree_size != Vector3i()) {
- //can create a 3D texture
- Vector<int> levels = storage->gi_probe_get_level_counts(gi_probe->probe);
-
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
- tf.width = octree_size.x;
- tf.height = octree_size.y;
- tf.depth = octree_size.z;
- tf.texture_type = RD::TEXTURE_TYPE_3D;
- tf.mipmaps = levels.size();
-
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
-
- gi_probe->texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- RD::get_singleton()->texture_clear(gi_probe->texture, Color(0, 0, 0, 0), 0, levels.size(), 0, 1, false);
-
- {
- int total_elements = 0;
- for (int i = 0; i < levels.size(); i++) {
- total_elements += levels[i];
- }
-
- gi_probe->write_buffer = RD::get_singleton()->storage_buffer_create(total_elements * 16);
- }
-
- for (int i = 0; i < levels.size(); i++) {
- GIProbeInstance::Mipmap mipmap;
- mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), gi_probe->texture, 0, i, RD::TEXTURE_SLICE_3D);
- mipmap.level = levels.size() - i - 1;
- mipmap.cell_offset = 0;
- for (uint32_t j = 0; j < mipmap.level; j++) {
- mipmap.cell_offset += levels[j];
- }
- mipmap.cell_count = levels[mipmap.level];
-
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 1;
- u.ids.push_back(storage->gi_probe_get_octree_buffer(gi_probe->probe));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 2;
- u.ids.push_back(storage->gi_probe_get_data_buffer(gi_probe->probe));
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 4;
- u.ids.push_back(gi_probe->write_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 9;
- u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 10;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
-
- {
- Vector<RD::Uniform> copy_uniforms = uniforms;
- if (i == 0) {
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 3;
- u.ids.push_back(gi_probe_lights_uniform);
- copy_uniforms.push_back(u);
- }
-
- mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT], 0);
-
- copy_uniforms = uniforms; //restore
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 5;
- u.ids.push_back(gi_probe->texture);
- copy_uniforms.push_back(u);
- }
- mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0);
- } else {
- mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP], 0);
- }
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 5;
- u.ids.push_back(mipmap.texture);
- uniforms.push_back(u);
- }
-
- mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE], 0);
-
- gi_probe->mipmaps.push_back(mipmap);
- }
-
- {
- uint32_t dynamic_map_size = MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
- uint32_t oversample = nearest_power_of_2_templated(4);
- int mipmap_index = 0;
-
- while (mipmap_index < gi_probe->mipmaps.size()) {
- GIProbeInstance::DynamicMap dmap;
-
- if (oversample > 0) {
- dmap.size = dynamic_map_size * (1 << oversample);
- dmap.mipmap = -1;
- oversample--;
- } else {
- dmap.size = dynamic_map_size >> mipmap_index;
- dmap.mipmap = mipmap_index;
- mipmap_index++;
- }
-
- RD::TextureFormat dtf;
- dtf.width = dmap.size;
- dtf.height = dmap.size;
- dtf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
-
- if (gi_probe->dynamic_maps.size() == 0) {
- dtf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
- }
- dmap.texture = RD::get_singleton()->texture_create(dtf, RD::TextureView());
-
- if (gi_probe->dynamic_maps.size() == 0) {
- //render depth for first one
- dtf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
- dtf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
- dmap.fb_depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());
- }
-
- //just use depth as-is
- dtf.format = RD::DATA_FORMAT_R32_SFLOAT;
- dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
-
- dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());
-
- if (gi_probe->dynamic_maps.size() == 0) {
- dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
- dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
- dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView());
- dmap.normal = RD::get_singleton()->texture_create(dtf, RD::TextureView());
- dmap.orm = RD::get_singleton()->texture_create(dtf, RD::TextureView());
-
- Vector<RID> fb;
- fb.push_back(dmap.albedo);
- fb.push_back(dmap.normal);
- fb.push_back(dmap.orm);
- fb.push_back(dmap.texture); //emission
- fb.push_back(dmap.depth);
- fb.push_back(dmap.fb_depth);
-
- dmap.fb = RD::get_singleton()->framebuffer_create(fb);
-
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 3;
- u.ids.push_back(gi_probe_lights_uniform);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 5;
- u.ids.push_back(dmap.albedo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 6;
- u.ids.push_back(dmap.normal);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 7;
- u.ids.push_back(dmap.orm);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 8;
- u.ids.push_back(dmap.fb_depth);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 9;
- u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 10;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 11;
- u.ids.push_back(dmap.texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 12;
- u.ids.push_back(dmap.depth);
- uniforms.push_back(u);
- }
-
- dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0);
- }
- } else {
- bool plot = dmap.mipmap >= 0;
- bool write = dmap.mipmap < (gi_probe->mipmaps.size() - 1);
-
- Vector<RD::Uniform> uniforms;
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 5;
- u.ids.push_back(gi_probe->dynamic_maps[gi_probe->dynamic_maps.size() - 1].texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 6;
- u.ids.push_back(gi_probe->dynamic_maps[gi_probe->dynamic_maps.size() - 1].depth);
- uniforms.push_back(u);
- }
-
- if (write) {
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 7;
- u.ids.push_back(dmap.texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 8;
- u.ids.push_back(dmap.depth);
- uniforms.push_back(u);
- }
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 9;
- u.ids.push_back(storage->gi_probe_get_sdf_texture(gi_probe->probe));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 10;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
-
- if (plot) {
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 11;
- u.ids.push_back(gi_probe->mipmaps[dmap.mipmap].texture);
- uniforms.push_back(u);
- }
- }
-
- dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_lighting_shader_version_shaders[(write && plot) ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : write ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT], 0);
- }
-
- gi_probe->dynamic_maps.push_back(dmap);
- }
- }
- }
-
- gi_probe->last_probe_data_version = data_version;
- p_update_light_instances = true; //just in case
-
- _base_uniforms_changed();
- }
-
- // UDPDATE TIME
-
- if (gi_probe->has_dynamic_object_data) {
- //if it has dynamic object data, it needs to be cleared
- RD::get_singleton()->texture_clear(gi_probe->texture, Color(0, 0, 0, 0), 0, gi_probe->mipmaps.size(), 0, 1, true);
- }
-
- uint32_t light_count = 0;
-
- if (p_update_light_instances || p_dynamic_objects.size() > 0) {
- light_count = MIN(gi_probe_max_lights, (uint32_t)p_light_instances.size());
-
- {
- Transform to_cell = storage->gi_probe_get_to_cell_xform(gi_probe->probe);
- Transform to_probe_xform = (gi_probe->transform * to_cell.affine_inverse()).affine_inverse();
- //update lights
-
- for (uint32_t i = 0; i < light_count; i++) {
- GIProbeLight &l = gi_probe_lights[i];
- RID light_instance = p_light_instances[i];
- RID light = light_instance_get_base_light(light_instance);
-
- l.type = storage->light_get_type(light);
- if (l.type == RS::LIGHT_DIRECTIONAL && storage->light_directional_is_sky_only(light)) {
- light_count--;
- continue;
- }
-
- l.attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
- l.energy = storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
- l.radius = to_cell.basis.xform(Vector3(storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();
- Color color = storage->light_get_color(light).to_linear();
- l.color[0] = color.r;
- l.color[1] = color.g;
- l.color[2] = color.b;
-
- l.spot_angle_radians = Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE));
- l.spot_attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
-
- Transform xform = light_instance_get_base_transform(light_instance);
-
- Vector3 pos = to_probe_xform.xform(xform.origin);
- Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_axis(2)).normalized();
-
- l.position[0] = pos.x;
- l.position[1] = pos.y;
- l.position[2] = pos.z;
-
- l.direction[0] = dir.x;
- l.direction[1] = dir.y;
- l.direction[2] = dir.z;
-
- l.has_shadow = storage->light_has_shadow(light);
- }
-
- RD::get_singleton()->buffer_update(gi_probe_lights_uniform, 0, sizeof(GIProbeLight) * light_count, gi_probe_lights, true);
- }
- }
-
- if (gi_probe->has_dynamic_object_data || p_update_light_instances || p_dynamic_objects.size()) {
- // PROCESS MIPMAPS
- if (gi_probe->mipmaps.size()) {
- //can update mipmaps
-
- Vector3i probe_size = storage->gi_probe_get_octree_size(gi_probe->probe);
-
- GIProbePushConstant push_constant;
-
- push_constant.limits[0] = probe_size.x;
- push_constant.limits[1] = probe_size.y;
- push_constant.limits[2] = probe_size.z;
- push_constant.stack_size = gi_probe->mipmaps.size();
- push_constant.emission_scale = 1.0;
- push_constant.propagation = storage->gi_probe_get_propagation(gi_probe->probe);
- push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(gi_probe->probe);
- push_constant.light_count = light_count;
- push_constant.aniso_strength = 0;
-
- /* print_line("probe update to version " + itos(gi_probe->last_probe_version));
- print_line("propagation " + rtos(push_constant.propagation));
- print_line("dynrange " + rtos(push_constant.dynamic_range));
- */
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
- int passes;
- if (p_update_light_instances) {
- passes = storage->gi_probe_is_using_two_bounces(gi_probe->probe) ? 2 : 1;
- } else {
- passes = 1; //only re-blitting is necessary
- }
- int wg_size = 64;
- int wg_limit_x = RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X);
-
- for (int pass = 0; pass < passes; pass++) {
- if (p_update_light_instances) {
- for (int i = 0; i < gi_probe->mipmaps.size(); i++) {
- if (i == 0) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[pass == 0 ? GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT : GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]);
- } else if (i == 1) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP]);
- }
-
- if (pass == 1 || i > 0) {
- RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done
- }
- if (pass == 0 || i > 0) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi_probe->mipmaps[i].uniform_set, 0);
- } else {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi_probe->mipmaps[i].second_bounce_uniform_set, 0);
- }
-
- push_constant.cell_offset = gi_probe->mipmaps[i].cell_offset;
- push_constant.cell_count = gi_probe->mipmaps[i].cell_count;
-
- int wg_todo = (gi_probe->mipmaps[i].cell_count - 1) / wg_size + 1;
- while (wg_todo) {
- int wg_count = MIN(wg_todo, wg_limit_x);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);
- wg_todo -= wg_count;
- push_constant.cell_offset += wg_count * wg_size;
- }
- }
-
- RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done
- }
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE]);
-
- for (int i = 0; i < gi_probe->mipmaps.size(); i++) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi_probe->mipmaps[i].write_uniform_set, 0);
-
- push_constant.cell_offset = gi_probe->mipmaps[i].cell_offset;
- push_constant.cell_count = gi_probe->mipmaps[i].cell_count;
-
- int wg_todo = (gi_probe->mipmaps[i].cell_count - 1) / wg_size + 1;
- while (wg_todo) {
- int wg_count = MIN(wg_todo, wg_limit_x);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);
- wg_todo -= wg_count;
- push_constant.cell_offset += wg_count * wg_size;
- }
- }
- }
-
- RD::get_singleton()->compute_list_end();
- }
- }
-
- gi_probe->has_dynamic_object_data = false; //clear until dynamic object data is used again
-
- if (p_dynamic_objects.size() && gi_probe->dynamic_maps.size()) {
- Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe);
- int multiplier = gi_probe->dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
-
- Transform oversample_scale;
- oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier));
-
- Transform to_cell = oversample_scale * storage->gi_probe_get_to_cell_xform(gi_probe->probe);
- Transform to_world_xform = gi_probe->transform * to_cell.affine_inverse();
- Transform to_probe_xform = to_world_xform.affine_inverse();
-
- AABB probe_aabb(Vector3(), octree_size);
-
- //this could probably be better parallelized in compute..
- for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {
- InstanceBase *instance = p_dynamic_objects[i];
- //not used, so clear
- instance->depth_layer = 0;
- instance->depth = 0;
-
- //transform aabb to giprobe
- AABB aabb = (to_probe_xform * instance->transform).xform(instance->aabb);
-
- //this needs to wrap to grid resolution to avoid jitter
- //also extend margin a bit just in case
- Vector3i begin = aabb.position - Vector3i(1, 1, 1);
- Vector3i end = aabb.position + aabb.size + Vector3i(1, 1, 1);
-
- for (int j = 0; j < 3; j++) {
- if ((end[j] - begin[j]) & 1) {
- end[j]++; //for half extents split, it needs to be even
- }
- begin[j] = MAX(begin[j], 0);
- end[j] = MIN(end[j], octree_size[j] * multiplier);
- }
-
- //aabb = aabb.intersection(probe_aabb); //intersect
- aabb.position = begin;
- aabb.size = end - begin;
-
- //print_line("aabb: " + aabb);
-
- for (int j = 0; j < 6; j++) {
- //if (j != 0 && j != 3) {
- // continue;
- //}
- static const Vector3 render_z[6] = {
- Vector3(1, 0, 0),
- Vector3(0, 1, 0),
- Vector3(0, 0, 1),
- Vector3(-1, 0, 0),
- Vector3(0, -1, 0),
- Vector3(0, 0, -1),
- };
- static const Vector3 render_up[6] = {
- Vector3(0, 1, 0),
- Vector3(0, 0, 1),
- Vector3(0, 1, 0),
- Vector3(0, 1, 0),
- Vector3(0, 0, 1),
- Vector3(0, 1, 0),
- };
-
- Vector3 render_dir = render_z[j];
- Vector3 up_dir = render_up[j];
-
- Vector3 center = aabb.position + aabb.size * 0.5;
- Transform xform;
- xform.set_look_at(center - aabb.size * 0.5 * render_dir, center, up_dir);
-
- Vector3 x_dir = xform.basis.get_axis(0).abs();
- int x_axis = int(Vector3(0, 1, 2).dot(x_dir));
- Vector3 y_dir = xform.basis.get_axis(1).abs();
- int y_axis = int(Vector3(0, 1, 2).dot(y_dir));
- Vector3 z_dir = -xform.basis.get_axis(2);
- int z_axis = int(Vector3(0, 1, 2).dot(z_dir.abs()));
-
- Rect2i rect(aabb.position[x_axis], aabb.position[y_axis], aabb.size[x_axis], aabb.size[y_axis]);
- bool x_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_axis(0)) < 0);
- bool y_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_axis(1)) < 0);
- bool z_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_axis(2)) > 0);
-
- CameraMatrix cm;
- cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]);
-
- if (cull_argument.size() == 0) {
- cull_argument.push_back(nullptr);
- }
- cull_argument[0] = instance;
-
- _render_material(to_world_xform * xform, cm, true, cull_argument, gi_probe->dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size));
-
- GIProbeDynamicPushConstant push_constant;
- zeromem(&push_constant, sizeof(GIProbeDynamicPushConstant));
- push_constant.limits[0] = octree_size.x;
- push_constant.limits[1] = octree_size.y;
- push_constant.limits[2] = octree_size.z;
- push_constant.light_count = p_light_instances.size();
- push_constant.x_dir[0] = x_dir[0];
- push_constant.x_dir[1] = x_dir[1];
- push_constant.x_dir[2] = x_dir[2];
- push_constant.y_dir[0] = y_dir[0];
- push_constant.y_dir[1] = y_dir[1];
- push_constant.y_dir[2] = y_dir[2];
- push_constant.z_dir[0] = z_dir[0];
- push_constant.z_dir[1] = z_dir[1];
- push_constant.z_dir[2] = z_dir[2];
- push_constant.z_base = xform.origin[z_axis];
- push_constant.z_sign = (z_flip ? -1.0 : 1.0);
- push_constant.pos_multiplier = float(1.0) / multiplier;
- push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(gi_probe->probe);
- push_constant.flip_x = x_flip;
- push_constant.flip_y = y_flip;
- push_constant.rect_pos[0] = rect.position[0];
- push_constant.rect_pos[1] = rect.position[1];
- push_constant.rect_size[0] = rect.size[0];
- push_constant.rect_size[1] = rect.size[1];
- push_constant.prev_rect_ofs[0] = 0;
- push_constant.prev_rect_ofs[1] = 0;
- push_constant.prev_rect_size[0] = 0;
- push_constant.prev_rect_size[1] = 0;
- push_constant.on_mipmap = false;
- push_constant.propagation = storage->gi_probe_get_propagation(gi_probe->probe);
- push_constant.pad[0] = 0;
- push_constant.pad[1] = 0;
- push_constant.pad[2] = 0;
-
- //process lighting
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi_probe->dynamic_maps[0].uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbeDynamicPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1);
- //print_line("rect: " + itos(i) + ": " + rect);
-
- for (int k = 1; k < gi_probe->dynamic_maps.size(); k++) {
- // enlarge the rect if needed so all pixels fit when downscaled,
- // this ensures downsampling is smooth and optimal because no pixels are left behind
-
- //x
- if (rect.position.x & 1) {
- rect.size.x++;
- push_constant.prev_rect_ofs[0] = 1; //this is used to ensure reading is also optimal
- } else {
- push_constant.prev_rect_ofs[0] = 0;
- }
- if (rect.size.x & 1) {
- rect.size.x++;
- }
-
- rect.position.x >>= 1;
- rect.size.x = MAX(1, rect.size.x >> 1);
-
- //y
- if (rect.position.y & 1) {
- rect.size.y++;
- push_constant.prev_rect_ofs[1] = 1;
- } else {
- push_constant.prev_rect_ofs[1] = 0;
- }
- if (rect.size.y & 1) {
- rect.size.y++;
- }
-
- rect.position.y >>= 1;
- rect.size.y = MAX(1, rect.size.y >> 1);
-
- //shrink limits to ensure plot does not go outside map
- if (gi_probe->dynamic_maps[k].mipmap > 0) {
- for (int l = 0; l < 3; l++) {
- push_constant.limits[l] = MAX(1, push_constant.limits[l] >> 1);
- }
- }
-
- //print_line("rect: " + itos(i) + ": " + rect);
- push_constant.rect_pos[0] = rect.position[0];
- push_constant.rect_pos[1] = rect.position[1];
- push_constant.prev_rect_size[0] = push_constant.rect_size[0];
- push_constant.prev_rect_size[1] = push_constant.rect_size[1];
- push_constant.rect_size[0] = rect.size[0];
- push_constant.rect_size[1] = rect.size[1];
- push_constant.on_mipmap = gi_probe->dynamic_maps[k].mipmap > 0;
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- if (gi_probe->dynamic_maps[k].mipmap < 0) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE]);
- } else if (k < gi_probe->dynamic_maps.size() - 1) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT]);
- } else {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT]);
- }
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi_probe->dynamic_maps[k].uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbeDynamicPushConstant));
- RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1);
- }
-
- RD::get_singleton()->compute_list_end();
- }
- }
-
- gi_probe->has_dynamic_object_data = true; //clear until dynamic object data is used again
- }
-
- gi_probe->last_probe_version = storage->gi_probe_get_version(gi_probe->probe);
-}
-
-void RendererSceneRenderRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
-
- if (gi_probe->mipmaps.size() == 0) {
- return;
- }
-
- CameraMatrix transform = (p_camera_with_transform * CameraMatrix(gi_probe->transform)) * CameraMatrix(storage->gi_probe_get_to_cell_xform(gi_probe->probe).affine_inverse());
-
- int level = 0;
- Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe);
-
- GIProbeDebugPushConstant push_constant;
- push_constant.alpha = p_alpha;
- push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(gi_probe->probe);
- push_constant.cell_offset = gi_probe->mipmaps[level].cell_offset;
- push_constant.level = level;
-
- push_constant.bounds[0] = octree_size.x >> level;
- push_constant.bounds[1] = octree_size.y >> level;
- push_constant.bounds[2] = octree_size.z >> level;
- push_constant.pad = 0;
-
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- push_constant.projection[i * 4 + j] = transform.matrix[i][j];
- }
- }
-
- if (giprobe_debug_uniform_set.is_valid()) {
- RD::get_singleton()->free(giprobe_debug_uniform_set);
- }
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 1;
- u.ids.push_back(storage->gi_probe_get_data_buffer(gi_probe->probe));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 2;
- u.ids.push_back(gi_probe->texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 3;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
-
- int cell_count;
- if (!p_emission && p_lighting && gi_probe->has_dynamic_object_data) {
- cell_count = push_constant.bounds[0] * push_constant.bounds[1] * push_constant.bounds[2];
- } else {
- cell_count = gi_probe->mipmaps[level].cell_count;
- }
-
- giprobe_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_debug_shader_version_shaders[0], 0);
- RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, giprobe_debug_shader_version_pipelines[p_emission ? GI_PROBE_DEBUG_EMISSION : p_lighting ? (gi_probe->has_dynamic_object_data ? GI_PROBE_DEBUG_LIGHT_FULL : GI_PROBE_DEBUG_LIGHT) : GI_PROBE_DEBUG_COLOR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, giprobe_debug_uniform_set, 0);
- RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(GIProbeDebugPushConstant));
- RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36);
+ gi.gi_probe_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this);
}
void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {
@@ -4848,132 +1363,7 @@ void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawLi
return; //nothing to debug
}
- SDGIShader::DebugProbesPushConstant push_constant;
-
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- push_constant.projection[i * 4 + j] = p_camera_with_transform.matrix[i][j];
- }
- }
-
- //gen spheres from strips
- uint32_t band_points = 16;
- push_constant.band_power = 4;
- push_constant.sections_in_band = ((band_points / 2) - 1);
- push_constant.band_mask = band_points - 2;
- push_constant.section_arc = (Math_PI * 2.0) / float(push_constant.sections_in_band);
- push_constant.y_mult = rb->sdfgi->y_mult;
-
- uint32_t total_points = push_constant.sections_in_band * band_points;
- uint32_t total_probes = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count;
-
- push_constant.grid_size[0] = rb->sdfgi->cascade_size;
- push_constant.grid_size[1] = rb->sdfgi->cascade_size;
- push_constant.grid_size[2] = rb->sdfgi->cascade_size;
- push_constant.cascade = 0;
-
- push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
-
- if (!rb->sdfgi->debug_probes_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(rb->sdfgi->debug_probes_uniform_set)) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 1;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(rb->sdfgi->cascades_ubo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 2;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(rb->sdfgi->lightprobe_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 4;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(rb->sdfgi->occlusion_texture);
- uniforms.push_back(u);
- }
-
- rb->sdfgi->debug_probes_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, 0), 0);
- }
-
- RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, sdfgi_shader.debug_probes_pipeline[SDGIShader::PROBE_DEBUG_PROBES].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, rb->sdfgi->debug_probes_uniform_set, 0);
- RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(SDGIShader::DebugProbesPushConstant));
- RD::get_singleton()->draw_list_draw(p_draw_list, false, total_probes, total_points);
-
- if (sdfgi_debug_probe_dir != Vector3()) {
- print_line("CLICK DEBUG ME?");
- uint32_t cascade = 0;
- Vector3 offset = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + rb->sdfgi->cascades[cascade].position)) * rb->sdfgi->cascades[cascade].cell_size * Vector3(1.0, 1.0 / rb->sdfgi->y_mult, 1.0);
- Vector3 probe_size = rb->sdfgi->cascades[cascade].cell_size * (rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR) * Vector3(1.0, 1.0 / rb->sdfgi->y_mult, 1.0);
- Vector3 ray_from = sdfgi_debug_probe_pos;
- Vector3 ray_to = sdfgi_debug_probe_pos + sdfgi_debug_probe_dir * rb->sdfgi->cascades[cascade].cell_size * Math::sqrt(3.0) * rb->sdfgi->cascade_size;
- float sphere_radius = 0.2;
- float closest_dist = 1e20;
- sdfgi_debug_probe_enabled = false;
-
- Vector3i probe_from = rb->sdfgi->cascades[cascade].position / (rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR);
- for (int i = 0; i < (SDFGI::PROBE_DIVISOR + 1); i++) {
- for (int j = 0; j < (SDFGI::PROBE_DIVISOR + 1); j++) {
- for (int k = 0; k < (SDFGI::PROBE_DIVISOR + 1); k++) {
- Vector3 pos = offset + probe_size * Vector3(i, j, k);
- Vector3 res;
- if (Geometry3D::segment_intersects_sphere(ray_from, ray_to, pos, sphere_radius, &res)) {
- float d = ray_from.distance_to(res);
- if (d < closest_dist) {
- closest_dist = d;
- sdfgi_debug_probe_enabled = true;
- sdfgi_debug_probe_index = probe_from + Vector3i(i, j, k);
- }
- }
- }
- }
- }
-
- if (sdfgi_debug_probe_enabled) {
- print_line("found: " + sdfgi_debug_probe_index);
- } else {
- print_line("no found");
- }
- sdfgi_debug_probe_dir = Vector3();
- }
-
- if (sdfgi_debug_probe_enabled) {
- uint32_t cascade = 0;
- uint32_t probe_cells = (rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR);
- Vector3i probe_from = rb->sdfgi->cascades[cascade].position / probe_cells;
- Vector3i ofs = sdfgi_debug_probe_index - probe_from;
- if (ofs.x < 0 || ofs.y < 0 || ofs.z < 0) {
- return;
- }
- if (ofs.x > SDFGI::PROBE_DIVISOR || ofs.y > SDFGI::PROBE_DIVISOR || ofs.z > SDFGI::PROBE_DIVISOR) {
- return;
- }
-
- uint32_t mult = (SDFGI::PROBE_DIVISOR + 1);
- uint32_t index = ofs.z * mult * mult + ofs.y * mult + ofs.x;
-
- push_constant.probe_debug_index = index;
-
- uint32_t cell_count = probe_cells * 2 * probe_cells * 2 * probe_cells * 2;
-
- RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, sdfgi_shader.debug_probes_pipeline[SDGIShader::PROBE_DEBUG_VISIBILITY].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, rb->sdfgi->debug_probes_uniform_set, 0);
- RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(SDGIShader::DebugProbesPushConstant));
- RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, total_points);
- }
+ rb->sdfgi->debug_probes(p_draw_list, p_framebuffer, p_camera_with_transform);
}
////////////////////////////////
@@ -5082,9 +1472,6 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
RD::get_singleton()->free(rb->luminance.reduce[i]);
}
- for (int i = 0; i < rb->luminance.reduce.size(); i++) {
- RD::get_singleton()->free(rb->luminance.reduce[i]);
- }
rb->luminance.reduce.clear();
if (rb->luminance.current.is_valid()) {
@@ -5125,6 +1512,13 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
RD::get_singleton()->free(rb->ssr.normal_scaled);
rb->ssr.normal_scaled = RID();
}
+
+ if (rb->ambient_buffer.is_valid()) {
+ RD::get_singleton()->free(rb->ambient_buffer);
+ RD::get_singleton()->free(rb->reflection_buffer);
+ rb->ambient_buffer = RID();
+ rb->reflection_buffer = RID();
+ }
}
void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) {
@@ -5158,7 +1552,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb
return;
}
- Environment *env = environment_owner.getornull(p_environment);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment);
ERR_FAIL_COND(!env);
ERR_FAIL_COND(!env->ssr_enabled);
@@ -5203,12 +1597,11 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
- Environment *env = environment_owner.getornull(p_environment);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment);
ERR_FAIL_COND(!env);
RENDER_TIMESTAMP("Process SSAO");
- //TODO clear when settings chenge to or from ultra
if (rb->ssao.ao_final.is_valid() && ssao_using_half_size != ssao_half_size) {
RD::get_singleton()->free(rb->ssao.depth);
RD::get_singleton()->free(rb->ssao.ao_deinterleaved);
@@ -5258,9 +1651,11 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
tf.array_layers = 4;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
rb->ssao.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ssao.depth, "SSAO Depth");
for (uint32_t i = 0; i < tf.mipmaps; i++) {
RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.depth, 0, i, RD::TEXTURE_SLICE_2D_ARRAY);
rb->ssao.depth_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(rb->ssao.depth_slices[i], "SSAO Depth Mip " + itos(i) + " ");
}
}
@@ -5273,9 +1668,11 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
tf.array_layers = 4;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
rb->ssao.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved, "SSAO De-interleaved Array");
for (uint32_t i = 0; i < 4; i++) {
RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.ao_deinterleaved, i, 0);
rb->ssao.ao_deinterleaved_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved_slices[i], "SSAO De-interleaved Array Layer " + itos(i) + " ");
}
}
@@ -5288,9 +1685,11 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
tf.array_layers = 4;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
rb->ssao.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ssao.ao_pong, "SSAO De-interleaved Array Pong");
for (uint32_t i = 0; i < 4; i++) {
RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.ao_pong, i, 0);
rb->ssao.ao_pong_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved_slices[i], "SSAO De-interleaved Array Layer " + itos(i) + " Pong");
}
}
@@ -5301,7 +1700,9 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
tf.height = half_height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
rb->ssao.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ssao.importance_map[0], "SSAO Importance Map");
rb->ssao.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ssao.importance_map[1], "SSAO Importance Map Pong");
}
{
RD::TextureFormat tf;
@@ -5310,6 +1711,7 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
tf.height = rb->height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
rb->ssao.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ssao.ao_final, "SSAO Final");
_render_buffers_uniform_set_changed(p_render_buffers);
}
ssao_using_half_size = ssao_half_size;
@@ -5330,9 +1732,9 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
settings.blur_passes = ssao_blur_passes;
settings.fadeout_from = ssao_fadeout_from;
settings.fadeout_to = ssao_fadeout_to;
- settings.screen_size = Size2i(rb->width, rb->height);
+ settings.full_screen_size = Size2i(rb->width, rb->height);
settings.half_screen_size = Size2i(buffer_width, buffer_height);
- settings.quarter_size = Size2i(half_width, half_height);
+ settings.quarter_screen_size = Size2i(half_width, half_height);
storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao_deinterleaved, rb->ssao.ao_deinterleaved_slices, rb->ssao.ao_pong, rb->ssao.ao_pong_slices, rb->ssao.ao_final, rb->ssao.importance_map[0], rb->ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid);
}
@@ -5341,7 +1743,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(RID p_rende
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
- Environment *env = environment_owner.getornull(p_environment);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment);
//glow (if enabled)
CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects);
@@ -5525,16 +1927,16 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
}
- if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && _render_buffers_get_ambient_texture(p_render_buffers).is_valid()) {
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- RID ambient_texture = _render_buffers_get_ambient_texture(p_render_buffers);
- RID reflection_texture = _render_buffers_get_reflection_texture(p_render_buffers);
+ RID ambient_texture = rb->ambient_buffer;
+ RID reflection_texture = rb->reflection_buffer;
effects->copy_to_fb_rect(ambient_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture);
}
}
void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) {
- Environment *env = environment_owner.getornull(p_env);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->adjustments_enabled = p_enable;
@@ -5545,152 +1947,6 @@ void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable,
env->color_correction = p_color_correction;
}
-void RendererSceneRenderRD::_sdfgi_debug_draw(RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform) {
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND(!rb);
-
- if (!rb->sdfgi) {
- return; //eh
- }
-
- if (!rb->sdfgi->debug_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(rb->sdfgi->debug_uniform_set)) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 1;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
- if (i < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[i].sdf_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 2;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
- if (i < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[i].light_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
- if (i < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[i].light_aniso_0_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 4;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
- if (i < rb->sdfgi->cascades.size()) {
- u.ids.push_back(rb->sdfgi->cascades[i].light_aniso_1_tex);
- } else {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
- }
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 5;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(rb->sdfgi->occlusion_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 8;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 9;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(rb->sdfgi->cascades_ubo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 10;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.ids.push_back(rb->texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 11;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.push_back(rb->sdfgi->lightprobe_texture);
- uniforms.push_back(u);
- }
- rb->sdfgi->debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.debug_shader_version, 0);
- }
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.debug_pipeline);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->debug_uniform_set, 0);
-
- SDGIShader::DebugPushConstant push_constant;
- push_constant.grid_size[0] = rb->sdfgi->cascade_size;
- push_constant.grid_size[1] = rb->sdfgi->cascade_size;
- push_constant.grid_size[2] = rb->sdfgi->cascade_size;
- push_constant.max_cascades = rb->sdfgi->cascades.size();
- push_constant.screen_size[0] = rb->width;
- push_constant.screen_size[1] = rb->height;
- push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
- push_constant.use_occlusion = rb->sdfgi->uses_occlusion;
- push_constant.y_mult = rb->sdfgi->y_mult;
-
- Vector2 vp_half = p_projection.get_viewport_half_extents();
- push_constant.cam_extent[0] = vp_half.x;
- push_constant.cam_extent[1] = vp_half.y;
- push_constant.cam_extent[2] = -p_projection.get_z_near();
-
- push_constant.cam_transform[0] = p_transform.basis.elements[0][0];
- push_constant.cam_transform[1] = p_transform.basis.elements[1][0];
- push_constant.cam_transform[2] = p_transform.basis.elements[2][0];
- push_constant.cam_transform[3] = 0;
- push_constant.cam_transform[4] = p_transform.basis.elements[0][1];
- push_constant.cam_transform[5] = p_transform.basis.elements[1][1];
- push_constant.cam_transform[6] = p_transform.basis.elements[2][1];
- push_constant.cam_transform[7] = 0;
- push_constant.cam_transform[8] = p_transform.basis.elements[0][2];
- push_constant.cam_transform[9] = p_transform.basis.elements[1][2];
- push_constant.cam_transform[10] = p_transform.basis.elements[2][2];
- push_constant.cam_transform[11] = 0;
- push_constant.cam_transform[12] = p_transform.origin.x;
- push_constant.cam_transform[13] = p_transform.origin.y;
- push_constant.cam_transform[14] = p_transform.origin.z;
- push_constant.cam_transform[15] = 1;
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DebugPushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1);
- RD::get_singleton()->compute_list_end();
-
- Size2 rtsize = storage->render_target_get_size(rb->render_target);
- storage->get_effects()->copy_to_fb_rect(rb->texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), true);
-}
-
RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
@@ -5710,14 +1966,25 @@ RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) {
RID RendererSceneRenderRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
- if (rb->giprobe_buffer.is_null()) {
- rb->giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::GIProbeData) * RenderBuffers::MAX_GIPROBES);
+ if (rb->gi.giprobe_buffer.is_null()) {
+ rb->gi.giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::GIProbeData) * RendererSceneGIRD::MAX_GIPROBES);
}
- return rb->giprobe_buffer;
+ return rb->gi.giprobe_buffer;
}
RID RendererSceneRenderRD::render_buffers_get_default_gi_probe_buffer() {
- return default_giprobe_buffer;
+ return gi.default_giprobe_buffer;
+}
+
+RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) {
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND_V(!rb, RID());
+ return rb->ambient_buffer;
+}
+RID RendererSceneRenderRD::render_buffers_get_gi_reflection_texture(RID p_render_buffers) {
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND_V(!rb, RID());
+ return rb->reflection_buffer;
}
uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const {
@@ -5755,7 +2022,7 @@ Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RI
ERR_FAIL_COND_V(!rb, Vector3i());
ERR_FAIL_COND_V(!rb->sdfgi, Vector3i());
ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), Vector3i());
- int32_t probe_divisor = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR;
+ int32_t probe_divisor = rb->sdfgi->cascade_size / RendererSceneGIRD::SDFGI::PROBE_DIVISOR;
return rb->sdfgi->cascades[p_cascade].position / probe_divisor;
}
@@ -5857,6 +2124,11 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
rb->msaa = p_msaa;
rb->screen_space_aa = p_screen_space_aa;
rb->use_debanding = p_use_debanding;
+ if (rb->cluster_builder == nullptr) {
+ rb->cluster_builder = memnew(ClusterBuilderRD);
+ }
+ rb->cluster_builder->set_shared(&cluster_builder_shared);
+
_free_render_buffer_data(rb);
{
@@ -5897,6 +2169,12 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
rb->data->configure(rb->texture, rb->depth_texture, p_width, p_height, p_msaa);
_render_buffers_uniform_set_changed(p_render_buffers);
+
+ rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
+}
+
+void RendererSceneRenderRD::gi_set_use_half_resolution(bool p_enable) {
+ gi.half_resolution = p_enable;
}
void RendererSceneRenderRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {
@@ -5993,11 +2271,11 @@ void RendererSceneRenderRD::directional_shadow_quality_set(RS::ShadowQuality p_q
}
int RendererSceneRenderRD::get_roughness_layers() const {
- return roughness_layers;
+ return sky.roughness_layers;
}
bool RendererSceneRenderRD::is_using_radiance_cubemap_array() const {
- return sky_use_cubemap_array;
+ return sky.sky_use_cubemap_array;
}
RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_get_data(RID p_render_buffers) {
@@ -6007,17 +2285,34 @@ RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_g
}
void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment) {
+ cluster.reflection_count = 0;
+
for (uint32_t i = 0; i < (uint32_t)p_reflections.size(); i++) {
- RID rpi = p_reflections[i];
+ if (cluster.reflection_count == cluster.max_reflections) {
+ break;
+ }
- if (i >= cluster.max_reflections) {
- reflection_probe_instance_set_render_index(rpi, 0); //invalid, but something needs to be set
+ ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_reflections[i]);
+ if (!rpi) {
continue;
}
- reflection_probe_instance_set_render_index(rpi, i);
+ cluster.reflection_sort[cluster.reflection_count].instance = rpi;
+ cluster.reflection_sort[cluster.reflection_count].depth = -p_camera_inverse_transform.xform(rpi->transform.origin).z;
+ cluster.reflection_count++;
+ }
+
+ if (cluster.reflection_count > 0) {
+ SortArray<Cluster::InstanceSort<ReflectionProbeInstance>> sort_array;
+ sort_array.sort(cluster.reflection_sort, cluster.reflection_count);
+ }
+
+ for (uint32_t i = 0; i < cluster.reflection_count; i++) {
+ ReflectionProbeInstance *rpi = cluster.reflection_sort[i].instance;
- RID base_probe = reflection_probe_instance_get_probe(rpi);
+ rpi->render_index = i;
+
+ RID base_probe = rpi->probe;
Cluster::ReflectionData &reflection_ubo = cluster.reflections[i];
@@ -6026,7 +2321,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
reflection_ubo.box_extents[0] = extents.x;
reflection_ubo.box_extents[1] = extents.y;
reflection_ubo.box_extents[2] = extents.z;
- reflection_ubo.index = reflection_probe_instance_get_atlas_index(rpi);
+ reflection_ubo.index = rpi->atlas_index;
Vector3 origin_offset = storage->reflection_probe_get_origin_offset(base_probe);
@@ -6035,46 +2330,50 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
reflection_ubo.box_offset[2] = origin_offset.z;
reflection_ubo.mask = storage->reflection_probe_get_cull_mask(base_probe);
- float intensity = storage->reflection_probe_get_intensity(base_probe);
- bool interior = storage->reflection_probe_is_interior(base_probe);
- bool box_projection = storage->reflection_probe_is_box_projection(base_probe);
+ reflection_ubo.intensity = storage->reflection_probe_get_intensity(base_probe);
+ reflection_ubo.ambient_mode = storage->reflection_probe_get_ambient_mode(base_probe);
- reflection_ubo.params[0] = intensity;
- reflection_ubo.params[1] = 0;
- reflection_ubo.params[2] = interior ? 1.0 : 0.0;
- reflection_ubo.params[3] = box_projection ? 1.0 : 0.0;
+ reflection_ubo.exterior = !storage->reflection_probe_is_interior(base_probe);
+ reflection_ubo.box_project = storage->reflection_probe_is_box_projection(base_probe);
Color ambient_linear = storage->reflection_probe_get_ambient_color(base_probe).to_linear();
float interior_ambient_energy = storage->reflection_probe_get_ambient_color_energy(base_probe);
- uint32_t ambient_mode = storage->reflection_probe_get_ambient_mode(base_probe);
reflection_ubo.ambient[0] = ambient_linear.r * interior_ambient_energy;
reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy;
reflection_ubo.ambient[2] = ambient_linear.b * interior_ambient_energy;
- reflection_ubo.ambient_mode = ambient_mode;
- Transform transform = reflection_probe_instance_get_transform(rpi);
+ Transform transform = rpi->transform;
Transform proj = (p_camera_inverse_transform * transform).inverse();
RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix);
- cluster.builder.add_reflection_probe(transform, extents);
+ current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_REFLECTION_PROBE, transform, extents);
- reflection_probe_instance_set_render_pass(rpi, RSG::rasterizer->get_frame_number());
+ rpi->last_pass = RSG::rasterizer->get_frame_number();
}
- if (p_reflections.size()) {
- RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, MIN(cluster.max_reflections, (unsigned int)p_reflections.size()) * sizeof(ReflectionData), cluster.reflections, true);
+ if (cluster.reflection_count) {
+ RD::get_singleton()->buffer_update(cluster.reflection_buffer, 0, cluster.reflection_count * sizeof(RendererSceneSkyRD::ReflectionData), cluster.reflections, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
}
}
-void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) {
- uint32_t light_count = 0;
+void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) {
+ Transform inverse_transform = p_camera_transform.affine_inverse();
+
r_directional_light_count = 0;
r_positional_light_count = 0;
- sky_scene_state.ubo.directional_light_count = 0;
+ sky.sky_scene_state.ubo.directional_light_count = 0;
+
+ Plane camera_plane(p_camera_transform.origin, -p_camera_transform.basis.get_axis(Vector3::AXIS_Z).normalized());
+
+ cluster.omni_light_count = 0;
+ cluster.spot_light_count = 0;
for (int i = 0; i < (int)p_lights.size(); i++) {
- RID li = p_lights[i];
- RID base = light_instance_get_base_light(li);
+ LightInstance *li = light_instance_owner.getornull(p_lights[i]);
+ if (!li) {
+ continue;
+ }
+ RID base = li->light;
ERR_CONTINUE(base.is_null());
@@ -6082,9 +2381,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
switch (type) {
case RS::LIGHT_DIRECTIONAL: {
// Copy to SkyDirectionalLightData
- if (r_directional_light_count < sky_scene_state.max_directional_lights) {
- SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[r_directional_light_count];
- Transform light_transform = light_instance_get_base_transform(li);
+ if (r_directional_light_count < sky.sky_scene_state.max_directional_lights) {
+ RendererSceneSkyRD::SkyDirectionalLightData &sky_light_data = sky.sky_scene_state.directional_lights[r_directional_light_count];
+ Transform light_transform = li->transform;
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
sky_light_data.direction[0] = world_direction.x;
@@ -6111,7 +2410,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
angular_diameter = 0.0;
}
sky_light_data.size = angular_diameter;
- sky_scene_state.ubo.directional_light_count++;
+ sky.sky_scene_state.ubo.directional_light_count++;
}
if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_is_sky_only(base)) {
@@ -6120,9 +2419,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
Cluster::DirectionalLightData &light_data = cluster.directional_lights[r_directional_light_count];
- Transform light_transform = light_instance_get_base_transform(li);
+ Transform light_transform = li->transform;
- Vector3 direction = p_camera_inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized();
+ Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized();
light_data.direction[0] = direction.x;
light_data.direction[1] = direction.y;
@@ -6201,28 +2500,28 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);
light_data.blend_splits = storage->light_directional_get_blend_splits(base);
for (int j = 0; j < 4; j++) {
- Rect2 atlas_rect = light_instance_get_directional_shadow_atlas_rect(li, j);
- CameraMatrix matrix = light_instance_get_shadow_camera(li, j);
- float split = light_instance_get_directional_shadow_split(li, MIN(limit, j));
+ Rect2 atlas_rect = li->shadow_transform[j].atlas_rect;
+ CameraMatrix matrix = li->shadow_transform[j].camera;
+ float split = li->shadow_transform[MIN(limit, j)].split;
CameraMatrix bias;
bias.set_light_bias();
CameraMatrix rectm;
rectm.set_light_atlas_rect(atlas_rect);
- Transform modelview = (p_camera_inverse_transform * light_instance_get_shadow_transform(li, j)).inverse();
+ Transform modelview = (inverse_transform * li->shadow_transform[j].transform).inverse();
CameraMatrix shadow_mtx = rectm * bias * matrix * modelview;
light_data.shadow_split_offsets[j] = split;
- float bias_scale = light_instance_get_shadow_bias_scale(li, j);
+ float bias_scale = li->shadow_transform[j].bias_scale;
light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_scale;
- light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * light_instance_get_directional_shadow_texel_size(li, j);
+ light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size;
light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale;
- light_data.shadow_z_range[j] = light_instance_get_shadow_range(li, j);
- light_data.shadow_range_begin[j] = light_instance_get_shadow_range_begin(li, j);
+ light_data.shadow_z_range[j] = li->shadow_transform[j].farplane;
+ light_data.shadow_range_begin[j] = li->shadow_transform[j].range_begin;
RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
- Vector2 uv_scale = light_instance_get_shadow_uv_scale(li, j);
+ Vector2 uv_scale = li->shadow_transform[j].uv_scale;
uv_scale *= atlas_rect.size; //adapt to atlas size
switch (j) {
case 0: {
@@ -6259,170 +2558,201 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
r_directional_light_count++;
} break;
- case RS::LIGHT_SPOT:
case RS::LIGHT_OMNI: {
- if (light_count >= cluster.max_lights) {
+ if (cluster.omni_light_count >= cluster.max_lights) {
continue;
}
- Transform light_transform = light_instance_get_base_transform(li);
+ cluster.omni_light_sort[cluster.omni_light_count].instance = li;
+ cluster.omni_light_sort[cluster.omni_light_count].depth = camera_plane.distance_to(li->transform.origin);
+ cluster.omni_light_count++;
+ } break;
+ case RS::LIGHT_SPOT: {
+ if (cluster.spot_light_count >= cluster.max_lights) {
+ continue;
+ }
- Cluster::LightData &light_data = cluster.lights[light_count];
- cluster.lights_instances[light_count] = li;
+ cluster.spot_light_sort[cluster.spot_light_count].instance = li;
+ cluster.spot_light_sort[cluster.spot_light_count].depth = camera_plane.distance_to(li->transform.origin);
+ cluster.spot_light_count++;
+ } break;
+ }
- float sign = storage->light_is_negative(base) ? -1 : 1;
- Color linear_col = storage->light_get_color(base).to_linear();
+ li->last_pass = RSG::rasterizer->get_frame_number();
+ }
- light_data.attenuation_energy[0] = Math::make_half_float(storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION));
- light_data.attenuation_energy[1] = Math::make_half_float(sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI);
+ if (cluster.omni_light_count) {
+ SortArray<Cluster::InstanceSort<LightInstance>> sorter;
+ sorter.sort(cluster.omni_light_sort, cluster.omni_light_count);
+ }
- light_data.color_specular[0] = MIN(uint32_t(linear_col.r * 255), 255);
- light_data.color_specular[1] = MIN(uint32_t(linear_col.g * 255), 255);
- light_data.color_specular[2] = MIN(uint32_t(linear_col.b * 255), 255);
- light_data.color_specular[3] = MIN(uint32_t(storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 255), 255);
+ if (cluster.spot_light_count) {
+ SortArray<Cluster::InstanceSort<LightInstance>> sorter;
+ sorter.sort(cluster.spot_light_sort, cluster.spot_light_count);
+ }
- float radius = MAX(0.001, storage->light_get_param(base, RS::LIGHT_PARAM_RANGE));
- light_data.inv_radius = 1.0 / radius;
+ ShadowAtlas *shadow_atlas = nullptr;
- Vector3 pos = p_camera_inverse_transform.xform(light_transform.origin);
+ if (p_shadow_atlas.is_valid() && p_using_shadows) {
+ shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
+ }
- light_data.position[0] = pos.x;
- light_data.position[1] = pos.y;
- light_data.position[2] = pos.z;
+ for (uint32_t i = 0; i < (cluster.omni_light_count + cluster.spot_light_count); i++) {
+ uint32_t index = (i < cluster.omni_light_count) ? i : i - (cluster.omni_light_count);
+ Cluster::LightData &light_data = (i < cluster.omni_light_count) ? cluster.omni_lights[index] : cluster.spot_lights[index];
+ RS::LightType type = (i < cluster.omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT;
+ LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance;
+ RID base = li->light;
- Vector3 direction = p_camera_inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, -1))).normalized();
+ Transform light_transform = li->transform;
- light_data.direction[0] = direction.x;
- light_data.direction[1] = direction.y;
- light_data.direction[2] = direction.z;
+ float sign = storage->light_is_negative(base) ? -1 : 1;
+ Color linear_col = storage->light_get_color(base).to_linear();
- float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+ light_data.attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION);
- light_data.size = size;
+ float energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI;
- light_data.cone_attenuation_angle[0] = Math::make_half_float(storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION));
- float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE);
- light_data.cone_attenuation_angle[1] = Math::make_half_float(Math::cos(Math::deg2rad(spot_angle)));
+ light_data.color[0] = linear_col.r * energy;
+ light_data.color[1] = linear_col.g * energy;
+ light_data.color[2] = linear_col.b * energy;
+ light_data.specular_amount = storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0;
- light_data.mask = storage->light_get_cull_mask(base);
+ float radius = MAX(0.001, storage->light_get_param(base, RS::LIGHT_PARAM_RANGE));
+ light_data.inv_radius = 1.0 / radius;
- light_data.atlas_rect[0] = 0;
- light_data.atlas_rect[1] = 0;
- light_data.atlas_rect[2] = 0;
- light_data.atlas_rect[3] = 0;
+ Vector3 pos = inverse_transform.xform(light_transform.origin);
- RID projector = storage->light_get_projector(base);
+ light_data.position[0] = pos.x;
+ light_data.position[1] = pos.y;
+ light_data.position[2] = pos.z;
- if (projector.is_valid()) {
- Rect2 rect = storage->decal_atlas_get_texture_rect(projector);
+ Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, -1))).normalized();
- if (type == RS::LIGHT_SPOT) {
- light_data.projector_rect[0] = rect.position.x;
- light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped
- light_data.projector_rect[2] = rect.size.width;
- light_data.projector_rect[3] = -rect.size.height;
- } else {
- light_data.projector_rect[0] = rect.position.x;
- light_data.projector_rect[1] = rect.position.y;
- light_data.projector_rect[2] = rect.size.width;
- light_data.projector_rect[3] = rect.size.height * 0.5; //used by dp, so needs to be half
- }
- } else {
- light_data.projector_rect[0] = 0;
- light_data.projector_rect[1] = 0;
- light_data.projector_rect[2] = 0;
- light_data.projector_rect[3] = 0;
- }
+ light_data.direction[0] = direction.x;
+ light_data.direction[1] = direction.y;
+ light_data.direction[2] = direction.z;
- if (p_using_shadows && p_shadow_atlas.is_valid() && shadow_atlas_owns_light_instance(p_shadow_atlas, li)) {
- // fill in the shadow information
+ float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
- Color shadow_color = storage->light_get_shadow_color(base);
+ light_data.size = size;
- light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255);
- light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255);
- light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255);
- light_data.shadow_color_enabled[3] = 255;
+ light_data.inv_spot_attenuation = 1.0f / storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
+ float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE);
+ light_data.cos_spot_angle = Math::cos(Math::deg2rad(spot_angle));
- if (type == RS::LIGHT_SPOT) {
- light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0);
- float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0;
- shadow_texel_size *= light_instance_get_shadow_texel_size(li, p_shadow_atlas);
+ light_data.mask = storage->light_get_cull_mask(base);
- light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size;
+ light_data.atlas_rect[0] = 0;
+ light_data.atlas_rect[1] = 0;
+ light_data.atlas_rect[2] = 0;
+ light_data.atlas_rect[3] = 0;
- } else { //omni
- light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0;
- float shadow_texel_size = light_instance_get_shadow_texel_size(li, p_shadow_atlas);
- light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space
- }
+ RID projector = storage->light_get_projector(base);
- light_data.transmittance_bias = storage->light_get_transmittance_bias(base);
+ if (projector.is_valid()) {
+ Rect2 rect = storage->decal_atlas_get_texture_rect(projector);
- Rect2 rect = light_instance_get_shadow_atlas_rect(li, p_shadow_atlas);
+ if (type == RS::LIGHT_SPOT) {
+ light_data.projector_rect[0] = rect.position.x;
+ light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped
+ light_data.projector_rect[2] = rect.size.width;
+ light_data.projector_rect[3] = -rect.size.height;
+ } else {
+ light_data.projector_rect[0] = rect.position.x;
+ light_data.projector_rect[1] = rect.position.y;
+ light_data.projector_rect[2] = rect.size.width;
+ light_data.projector_rect[3] = rect.size.height * 0.5; //used by dp, so needs to be half
+ }
+ } else {
+ light_data.projector_rect[0] = 0;
+ light_data.projector_rect[1] = 0;
+ light_data.projector_rect[2] = 0;
+ light_data.projector_rect[3] = 0;
+ }
- light_data.atlas_rect[0] = rect.position.x;
- light_data.atlas_rect[1] = rect.position.y;
- light_data.atlas_rect[2] = rect.size.width;
- light_data.atlas_rect[3] = rect.size.height;
+ if (shadow_atlas && shadow_atlas->shadow_owners.has(li->self)) {
+ // fill in the shadow information
- light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
- light_data.shadow_volumetric_fog_fade = 1.0 / storage->light_get_shadow_volumetric_fog_fade(base);
+ light_data.shadow_enabled = true;
- if (type == RS::LIGHT_OMNI) {
- light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another
- Transform proj = (p_camera_inverse_transform * light_transform).inverse();
+ if (type == RS::LIGHT_SPOT) {
+ light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0);
+ float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0;
+ shadow_texel_size *= light_instance_get_shadow_texel_size(li->self, p_shadow_atlas);
- RendererStorageRD::store_transform(proj, light_data.shadow_matrix);
+ light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size;
- if (size > 0.0) {
- light_data.soft_shadow_size = size;
- } else {
- light_data.soft_shadow_size = 0.0;
- light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF
- }
+ } else { //omni
+ light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0;
+ float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas);
+ light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space
+ }
- } else if (type == RS::LIGHT_SPOT) {
- Transform modelview = (p_camera_inverse_transform * light_transform).inverse();
- CameraMatrix bias;
- bias.set_light_bias();
+ light_data.transmittance_bias = storage->light_get_transmittance_bias(base);
- CameraMatrix shadow_mtx = bias * light_instance_get_shadow_camera(li, 0) * modelview;
- RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix);
+ Rect2 rect = light_instance_get_shadow_atlas_rect(li->self, p_shadow_atlas);
- if (size > 0.0) {
- CameraMatrix cm = light_instance_get_shadow_camera(li, 0);
- float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle));
- light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width;
- } else {
- light_data.soft_shadow_size = 0.0;
- light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF
- }
- }
+ light_data.atlas_rect[0] = rect.position.x;
+ light_data.atlas_rect[1] = rect.position.y;
+ light_data.atlas_rect[2] = rect.size.width;
+ light_data.atlas_rect[3] = rect.size.height;
+
+ light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
+ light_data.shadow_volumetric_fog_fade = 1.0 / storage->light_get_shadow_volumetric_fog_fade(base);
+
+ if (type == RS::LIGHT_OMNI) {
+ light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another
+ Transform proj = (inverse_transform * light_transform).inverse();
+
+ RendererStorageRD::store_transform(proj, light_data.shadow_matrix);
+
+ if (size > 0.0) {
+ light_data.soft_shadow_size = size;
} else {
- light_data.shadow_color_enabled[3] = 0;
+ light_data.soft_shadow_size = 0.0;
+ light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF
}
- light_instance_set_index(li, light_count);
+ } else if (type == RS::LIGHT_SPOT) {
+ Transform modelview = (inverse_transform * light_transform).inverse();
+ CameraMatrix bias;
+ bias.set_light_bias();
- cluster.builder.add_light(type == RS::LIGHT_SPOT ? LightClusterBuilder::LIGHT_TYPE_SPOT : LightClusterBuilder::LIGHT_TYPE_OMNI, light_transform, radius, spot_angle);
+ CameraMatrix shadow_mtx = bias * li->shadow_transform[0].camera * modelview;
+ RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix);
- light_count++;
- r_positional_light_count++;
- } break;
+ if (size > 0.0) {
+ CameraMatrix cm = li->shadow_transform[0].camera;
+ float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle));
+ light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width;
+ } else {
+ light_data.soft_shadow_size = 0.0;
+ light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF
+ }
+ }
+ } else {
+ light_data.shadow_enabled = false;
}
- light_instance_set_render_pass(li, RSG::rasterizer->get_frame_number());
+ li->light_index = index;
+
+ current_cluster_builder->add_light(type == RS::LIGHT_SPOT ? ClusterBuilderRD::LIGHT_TYPE_SPOT : ClusterBuilderRD::LIGHT_TYPE_OMNI, light_transform, radius, spot_angle);
+
+ r_positional_light_count++;
+ }
- //update UBO for forward rendering, blit to texture for clustered
+ //update without barriers
+ if (cluster.omni_light_count) {
+ RD::get_singleton()->buffer_update(cluster.omni_light_buffer, 0, sizeof(Cluster::LightData) * cluster.omni_light_count, cluster.omni_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
}
- if (light_count) {
- RD::get_singleton()->buffer_update(cluster.light_buffer, 0, sizeof(Cluster::LightData) * light_count, cluster.lights, true);
+ if (cluster.spot_light_count) {
+ RD::get_singleton()->buffer_update(cluster.spot_light_buffer, 0, sizeof(Cluster::LightData) * cluster.spot_light_count, cluster.spot_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
}
if (r_directional_light_count) {
- RD::get_singleton()->buffer_update(cluster.directional_light_buffer, 0, sizeof(Cluster::DirectionalLightData) * r_directional_light_count, cluster.directional_lights, true);
+ RD::get_singleton()->buffer_update(cluster.directional_light_buffer, 0, sizeof(Cluster::DirectionalLightData) * r_directional_light_count, cluster.directional_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
}
}
@@ -6431,18 +2761,26 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
- uint32_t decal_count = MIN((uint32_t)p_decals.size(), cluster.max_decals);
- int idx = 0;
+ uint32_t decal_count = p_decals.size();
+
+ cluster.decal_count = 0;
+
for (uint32_t i = 0; i < decal_count; i++) {
- RID di = p_decals[i];
- RID decal = decal_instance_get_base(di);
+ if (cluster.decal_count == cluster.max_decals) {
+ break;
+ }
- Transform xform = decal_instance_get_transform(di);
+ DecalInstance *di = decal_instance_owner.getornull(p_decals[i]);
+ if (!di) {
+ continue;
+ }
+ RID decal = di->decal;
- float fade = 1.0;
+ Transform xform = di->transform;
+
+ real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
if (storage->decal_is_distance_fade_enabled(decal)) {
- real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
float fade_begin = storage->decal_get_distance_fade_begin(decal);
float fade_length = storage->decal_get_distance_fade_length(decal);
@@ -6450,18 +2788,43 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
if (distance > fade_begin + fade_length) {
continue; // do not use this decal, its invisible
}
+ }
+ }
+
+ cluster.decal_sort[cluster.decal_count].instance = di;
+ cluster.decal_sort[cluster.decal_count].depth = distance;
+ cluster.decal_count++;
+ }
+
+ if (cluster.decal_count > 0) {
+ SortArray<Cluster::InstanceSort<DecalInstance>> sort_array;
+ sort_array.sort(cluster.decal_sort, cluster.decal_count);
+ }
+
+ for (uint32_t i = 0; i < cluster.decal_count; i++) {
+ DecalInstance *di = cluster.decal_sort[i].instance;
+ RID decal = di->decal;
+ Transform xform = di->transform;
+ float fade = 1.0;
+
+ if (storage->decal_is_distance_fade_enabled(decal)) {
+ real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
+ float fade_begin = storage->decal_get_distance_fade_begin(decal);
+ float fade_length = storage->decal_get_distance_fade_length(decal);
+
+ if (distance > fade_begin) {
fade = 1.0 - (distance - fade_begin) / fade_length;
}
}
- Cluster::DecalData &dd = cluster.decals[idx];
+ Cluster::DecalData &dd = cluster.decals[i];
Vector3 decal_extents = storage->decal_get_extents(decal);
Transform scale_xform;
scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z));
- Transform to_decal_xform = (p_camera_inverse_xform * decal_instance_get_transform(di) * scale_xform * uv_xform).affine_inverse();
+ Transform to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse();
RendererStorageRD::store_transform(to_decal_xform, dd.xform);
Vector3 normal = xform.basis.get_axis(Vector3::AXIS_Y).normalized();
@@ -6546,19 +2909,18 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
dd.upper_fade = storage->decal_get_upper_fade(decal);
dd.lower_fade = storage->decal_get_lower_fade(decal);
- cluster.builder.add_decal(xform, decal_extents);
-
- idx++;
+ current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_DECAL, xform, decal_extents);
}
- if (idx > 0) {
- RD::get_singleton()->buffer_update(cluster.decal_buffer, 0, sizeof(Cluster::DecalData) * idx, cluster.decals, true);
+ if (cluster.decal_count > 0) {
+ RD::get_singleton()->buffer_update(cluster.decal_buffer, 0, sizeof(Cluster::DecalData) * cluster.decal_count, cluster.decals, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
}
}
void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
ERR_FAIL_COND(!rb->volumetric_fog);
+ RD::get_singleton()->free(rb->volumetric_fog->prev_light_density_map);
RD::get_singleton()->free(rb->volumetric_fog->light_density_map);
RD::get_singleton()->free(rb->volumetric_fog->fog_map);
@@ -6580,53 +2942,10 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
rb->volumetric_fog = nullptr;
}
-void RendererSceneRenderRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) {
- //create fog mipmaps
- uint32_t fog_texture_size = p_target_size;
- uint32_t base_texture_size = p_base_size;
-
- ShadowShrinkStage first;
- first.size = base_texture_size;
- first.texture = p_base;
- shrink_stages.push_back(first); //put depth first in case we dont find smaller ones
-
- while (fog_texture_size < base_texture_size) {
- base_texture_size = MAX(base_texture_size / 8, fog_texture_size);
-
- ShadowShrinkStage s;
- s.size = base_texture_size;
-
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
- tf.width = base_texture_size;
- tf.height = base_texture_size;
- tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
-
- if (base_texture_size == fog_texture_size) {
- s.filter_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
- tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT;
- }
-
- s.texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- shrink_stages.push_back(s);
- }
-}
-
-void RendererSceneRenderRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) {
- for (int i = 1; i < shrink_stages.size(); i++) {
- RD::get_singleton()->free(shrink_stages[i].texture);
- if (shrink_stages[i].filter_texture.is_valid()) {
- RD::get_singleton()->free(shrink_stages[i].filter_texture);
- }
- }
- shrink_stages.clear();
-}
-
void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
- Environment *env = environment_owner.getornull(p_environment);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment);
float ratio = float(rb->width) / float((rb->width + rb->height) / 2);
uint32_t target_width = uint32_t(float(volumetric_fog_size) * ratio);
@@ -6645,6 +2964,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
return;
}
+ RENDER_TIMESTAMP(">Volumetric Fog");
+
if (env && env->volumetric_fog_enabled && !rb->volumetric_fog) {
//required volumetric fog but not existing, create
rb->volumetric_fog = memnew(VolumetricFog);
@@ -6658,11 +2979,16 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
tf.height = target_height;
tf.depth = volumetric_fog_depth;
tf.texture_type = RD::TEXTURE_TYPE_3D;
- tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
rb->volumetric_fog->light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
- tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+
+ rb->volumetric_fog->prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->texture_clear(rb->volumetric_fog->prev_light_density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
+
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
rb->volumetric_fog->fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
_render_buffers_uniform_set_changed(p_render_buffers);
@@ -6676,163 +3002,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
uniforms.push_back(u);
}
- rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG);
- }
-
- //update directional shadow
-
- if (p_use_directional_shadows) {
- if (directional_shadow.shrink_stages.empty()) {
- if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
- //invalidate uniform set, we will need a new one
- RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
- rb->volumetric_fog->uniform_set = RID();
- }
- _allocate_shadow_shrink_stages(directional_shadow.depth, directional_shadow.size, directional_shadow.shrink_stages, volumetric_fog_directional_shadow_shrink);
- }
-
- if (directional_shadow.shrink_stages.size() > 1) {
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- for (int i = 1; i < directional_shadow.shrink_stages.size(); i++) {
- int32_t src_size = directional_shadow.shrink_stages[i - 1].size;
- int32_t dst_size = directional_shadow.shrink_stages[i].size;
- Rect2i r(0, 0, src_size, src_size);
- int32_t shrink_limit = 8 / (src_size / dst_size);
-
- storage->get_effects()->reduce_shadow(directional_shadow.shrink_stages[i - 1].texture, directional_shadow.shrink_stages[i].texture, Size2i(src_size, src_size), r, shrink_limit, compute_list);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && directional_shadow.shrink_stages[i].filter_texture.is_valid()) {
- Rect2i rf(0, 0, dst_size, dst_size);
- storage->get_effects()->filter_shadow(directional_shadow.shrink_stages[i].texture, directional_shadow.shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), rf, env->volumetric_fog_shadow_filter, compute_list);
- }
- }
- RD::get_singleton()->compute_list_end();
- }
- }
-
- ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
-
- if (shadow_atlas) {
- //shrink shadows that need to be shrunk
-
- bool force_shrink_shadows = false;
-
- if (shadow_atlas->shrink_stages.empty()) {
- if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
- //invalidate uniform set, we will need a new one
- RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
- rb->volumetric_fog->uniform_set = RID();
- }
- _allocate_shadow_shrink_stages(shadow_atlas->depth, shadow_atlas->size, shadow_atlas->shrink_stages, volumetric_fog_positional_shadow_shrink);
- force_shrink_shadows = true;
- }
-
- if (rb->volumetric_fog->last_shadow_filter != env->volumetric_fog_shadow_filter) {
- //if shadow filter changed, invalidate caches
- rb->volumetric_fog->last_shadow_filter = env->volumetric_fog_shadow_filter;
- force_shrink_shadows = true;
- }
-
- cluster.lights_shadow_rect_cache_count = 0;
-
- for (int i = 0; i < p_positional_light_count; i++) {
- if (cluster.lights[i].shadow_color_enabled[3] > 127) {
- RID li = cluster.lights_instances[i];
-
- ERR_CONTINUE(!shadow_atlas->shadow_owners.has(li));
-
- uint32_t key = shadow_atlas->shadow_owners[li];
-
- uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
- uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK;
-
- ERR_CONTINUE((int)shadow >= shadow_atlas->quadrants[quadrant].shadows.size());
-
- ShadowAtlas::Quadrant::Shadow &s = shadow_atlas->quadrants[quadrant].shadows.write[shadow];
-
- if (!force_shrink_shadows && s.fog_version == s.version) {
- continue; //do not update, no need
- }
-
- s.fog_version = s.version;
-
- uint32_t quadrant_size = shadow_atlas->size >> 1;
-
- Rect2i atlas_rect;
-
- atlas_rect.position.x = (quadrant & 1) * quadrant_size;
- atlas_rect.position.y = (quadrant >> 1) * quadrant_size;
-
- uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision);
- atlas_rect.position.x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
- atlas_rect.position.y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
-
- atlas_rect.size.x = shadow_size;
- atlas_rect.size.y = shadow_size;
-
- cluster.lights_shadow_rect_cache[cluster.lights_shadow_rect_cache_count] = atlas_rect;
-
- cluster.lights_shadow_rect_cache_count++;
-
- if (cluster.lights_shadow_rect_cache_count == cluster.max_lights) {
- break; //light limit reached
- }
- }
- }
-
- if (cluster.lights_shadow_rect_cache_count > 0) {
- //there are shadows to be shrunk, try to do them in parallel
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
- for (int i = 1; i < shadow_atlas->shrink_stages.size(); i++) {
- int32_t base_size = shadow_atlas->shrink_stages[0].size;
- int32_t src_size = shadow_atlas->shrink_stages[i - 1].size;
- int32_t dst_size = shadow_atlas->shrink_stages[i].size;
-
- uint32_t rect_divisor = base_size / src_size;
-
- int32_t shrink_limit = 8 / (src_size / dst_size);
-
- //shrink in parallel for more performance
- for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) {
- Rect2i src_rect = cluster.lights_shadow_rect_cache[j];
-
- src_rect.position /= rect_divisor;
- src_rect.size /= rect_divisor;
-
- storage->get_effects()->reduce_shadow(shadow_atlas->shrink_stages[i - 1].texture, shadow_atlas->shrink_stages[i].texture, Size2i(src_size, src_size), src_rect, shrink_limit, compute_list);
- }
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && shadow_atlas->shrink_stages[i].filter_texture.is_valid()) {
- uint32_t filter_divisor = base_size / dst_size;
-
- //filter in parallel for more performance
- for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) {
- Rect2i dst_rect = cluster.lights_shadow_rect_cache[j];
-
- dst_rect.position /= filter_divisor;
- dst_rect.size /= filter_divisor;
-
- storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, true, false);
- }
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) {
- Rect2i dst_rect = cluster.lights_shadow_rect_cache[j];
-
- dst_rect.position /= filter_divisor;
- dst_rect.size /= filter_divisor;
-
- storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, false, true);
- }
- }
- }
-
- RD::get_singleton()->compute_list_end();
- }
+ rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky.sky_shader.default_shader_rd, RendererSceneSkyRD::SKY_SET_FOG);
}
//update volumetric fog
@@ -6846,10 +3016,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1;
- if (shadow_atlas == nullptr || shadow_atlas->shrink_stages.size() == 0) {
+ ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
+ if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) {
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
} else {
- u.ids.push_back(shadow_atlas->shrink_stages[shadow_atlas->shrink_stages.size() - 1].texture);
+ u.ids.push_back(shadow_atlas->depth);
}
uniforms.push_back(u);
@@ -6859,10 +3030,10 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 2;
- if (directional_shadow.shrink_stages.size() == 0) {
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
+ if (directional_shadow.depth.is_valid()) {
+ u.ids.push_back(directional_shadow.depth);
} else {
- u.ids.push_back(directional_shadow.shrink_stages[directional_shadow.shrink_stages.size() - 1].texture);
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
}
uniforms.push_back(u);
}
@@ -6871,23 +3042,22 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 3;
- u.ids.push_back(get_positional_light_buffer());
+ u.ids.push_back(get_omni_light_buffer());
uniforms.push_back(u);
}
-
{
RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 4;
- u.ids.push_back(get_directional_light_buffer());
+ u.ids.push_back(get_spot_light_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 5;
- u.ids.push_back(get_cluster_builder_texture());
+ u.ids.push_back(get_directional_light_buffer());
uniforms.push_back(u);
}
@@ -6895,7 +3065,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 6;
- u.ids.push_back(get_cluster_builder_indices_buffer());
+ u.ids.push_back(rb->cluster_builder->get_cluster_buffer());
uniforms.push_back(u);
}
@@ -6943,8 +3113,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 12;
- for (int i = 0; i < RenderBuffers::MAX_GIPROBES; i++) {
- u.ids.push_back(rb->giprobe_textures[i]);
+ for (int i = 0; i < RendererSceneGIRD::MAX_GIPROBES; i++) {
+ u.ids.push_back(rb->gi.giprobe_textures[i]);
}
uniforms.push_back(u);
}
@@ -6955,6 +3125,20 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 14;
+ u.ids.push_back(volumetric_fog.params_ubo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 15;
+ u.ids.push_back(rb->volumetric_fog->prev_light_density_map);
+ uniforms.push_back(u);
+ }
rb->volumetric_fog->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.shader.version_get_shader(volumetric_fog.shader_version, 0), 0);
@@ -7000,7 +3184,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
rb->volumetric_fog->length = env->volumetric_fog_length;
rb->volumetric_fog->spread = env->volumetric_fog_detail_spread;
- VolumetricFogShader::PushConstant push_constant;
+ VolumetricFogShader::ParamsUBO params;
Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents();
Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents();
@@ -7016,51 +3200,78 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
fog_near_size = Vector2();
}
- push_constant.fog_frustum_size_begin[0] = fog_near_size.x;
- push_constant.fog_frustum_size_begin[1] = fog_near_size.y;
+ params.fog_frustum_size_begin[0] = fog_near_size.x;
+ params.fog_frustum_size_begin[1] = fog_near_size.y;
- push_constant.fog_frustum_size_end[0] = fog_far_size.x;
- push_constant.fog_frustum_size_end[1] = fog_far_size.y;
+ params.fog_frustum_size_end[0] = fog_far_size.x;
+ params.fog_frustum_size_end[1] = fog_far_size.y;
- push_constant.z_near = z_near;
- push_constant.z_far = z_far;
+ params.z_near = z_near;
+ params.z_far = z_far;
- push_constant.fog_frustum_end = fog_end;
+ params.fog_frustum_end = fog_end;
- push_constant.fog_volume_size[0] = rb->volumetric_fog->width;
- push_constant.fog_volume_size[1] = rb->volumetric_fog->height;
- push_constant.fog_volume_size[2] = rb->volumetric_fog->depth;
+ params.fog_volume_size[0] = rb->volumetric_fog->width;
+ params.fog_volume_size[1] = rb->volumetric_fog->height;
+ params.fog_volume_size[2] = rb->volumetric_fog->depth;
- push_constant.directional_light_count = p_directional_light_count;
+ params.directional_light_count = p_directional_light_count;
Color light = env->volumetric_fog_light.to_linear();
- push_constant.light_energy[0] = light.r * env->volumetric_fog_light_energy;
- push_constant.light_energy[1] = light.g * env->volumetric_fog_light_energy;
- push_constant.light_energy[2] = light.b * env->volumetric_fog_light_energy;
- push_constant.base_density = env->volumetric_fog_density;
-
- push_constant.detail_spread = env->volumetric_fog_detail_spread;
- push_constant.gi_inject = env->volumetric_fog_gi_inject;
-
- push_constant.cam_rotation[0] = p_cam_transform.basis[0][0];
- push_constant.cam_rotation[1] = p_cam_transform.basis[1][0];
- push_constant.cam_rotation[2] = p_cam_transform.basis[2][0];
- push_constant.cam_rotation[3] = 0;
- push_constant.cam_rotation[4] = p_cam_transform.basis[0][1];
- push_constant.cam_rotation[5] = p_cam_transform.basis[1][1];
- push_constant.cam_rotation[6] = p_cam_transform.basis[2][1];
- push_constant.cam_rotation[7] = 0;
- push_constant.cam_rotation[8] = p_cam_transform.basis[0][2];
- push_constant.cam_rotation[9] = p_cam_transform.basis[1][2];
- push_constant.cam_rotation[10] = p_cam_transform.basis[2][2];
- push_constant.cam_rotation[11] = 0;
- push_constant.filter_axis = 0;
- push_constant.max_gi_probes = env->volumetric_fog_gi_inject > 0.001 ? p_gi_probe_count : 0;
+ params.light_energy[0] = light.r * env->volumetric_fog_light_energy;
+ params.light_energy[1] = light.g * env->volumetric_fog_light_energy;
+ params.light_energy[2] = light.b * env->volumetric_fog_light_energy;
+ params.base_density = env->volumetric_fog_density;
+
+ params.detail_spread = env->volumetric_fog_detail_spread;
+ params.gi_inject = env->volumetric_fog_gi_inject;
+
+ params.cam_rotation[0] = p_cam_transform.basis[0][0];
+ params.cam_rotation[1] = p_cam_transform.basis[1][0];
+ params.cam_rotation[2] = p_cam_transform.basis[2][0];
+ params.cam_rotation[3] = 0;
+ params.cam_rotation[4] = p_cam_transform.basis[0][1];
+ params.cam_rotation[5] = p_cam_transform.basis[1][1];
+ params.cam_rotation[6] = p_cam_transform.basis[2][1];
+ params.cam_rotation[7] = 0;
+ params.cam_rotation[8] = p_cam_transform.basis[0][2];
+ params.cam_rotation[9] = p_cam_transform.basis[1][2];
+ params.cam_rotation[10] = p_cam_transform.basis[2][2];
+ params.cam_rotation[11] = 0;
+ params.filter_axis = 0;
+ params.max_gi_probes = env->volumetric_fog_gi_inject > 0.001 ? p_gi_probe_count : 0;
+ params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;
+
+ Transform to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform;
+ storage->store_transform(to_prev_cam_view, params.to_prev_view);
+
+ params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection;
+ params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount;
+
+ {
+ uint32_t cluster_size = rb->cluster_builder->get_cluster_size();
+ params.cluster_shift = get_shift_from_power_of_2(cluster_size);
+
+ uint32_t cluster_screen_width = (rb->width - 1) / cluster_size + 1;
+ uint32_t cluster_screen_height = (rb->height - 1) / cluster_size + 1;
+ params.cluster_type_size = cluster_screen_width * cluster_screen_height * (32 + 32);
+ params.cluster_width = cluster_screen_width;
+ params.max_cluster_element_count_div_32 = max_cluster_elements / 32;
+
+ params.screen_size[0] = rb->width;
+ params.screen_size[1] = rb->height;
+ }
/* Vector2 dssize = directional_shadow_get_size();
push_constant.directional_shadow_pixel_size[0] = 1.0 / dssize.x;
push_constant.directional_shadow_pixel_size[1] = 1.0 / dssize.y;
*/
+
+ RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog");
+
+ RENDER_TIMESTAMP("Render Fog");
+ RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), &params, RD::BARRIER_MASK_COMPUTE);
+
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
bool use_filter = volumetric_fog_filter_active;
@@ -7068,93 +3279,225 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[using_sdfgi ? VOLUMETRIC_FOG_SHADER_DENSITY_WITH_SDFGI : VOLUMETRIC_FOG_SHADER_DENSITY]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set, 0);
+
if (using_sdfgi) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1);
}
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 4, 4, 4);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth);
+
+ RD::get_singleton()->draw_command_end_label();
+
+ RD::get_singleton()->compute_list_end();
- RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->texture_copy(rb->volumetric_fog->light_density_map, rb->volumetric_fog->prev_light_density_map, Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 0, 0, 0, 0);
+
+ compute_list = RD::get_singleton()->compute_list_begin();
if (use_filter) {
+ RD::get_singleton()->draw_command_begin_label("Filter Fog");
+
+ RENDER_TIMESTAMP("Filter Fog");
+
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[VOLUMETRIC_FOG_SHADER_FILTER]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 8, 8, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->compute_list_end();
+ //need restart for buffer update
- push_constant.filter_axis = 1;
+ params.filter_axis = 1;
+ RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), &params);
+ compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[VOLUMETRIC_FOG_SHADER_FILTER]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set2, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth, 8, 8, 1);
+ if (using_sdfgi) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1);
+ }
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth);
RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->draw_command_end_label();
}
+ RENDER_TIMESTAMP("Integrate Fog");
+ RD::get_singleton()->draw_command_begin_label("Integrate Fog");
+
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.pipelines[VOLUMETRIC_FOG_SHADER_FOG]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, 1, 8, 8, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, 1);
- RD::get_singleton()->compute_list_end();
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER);
+
+ RENDER_TIMESTAMP("<Volumetric Fog");
+ RD::get_singleton()->draw_command_end_label();
+
+ rb->volumetric_fog->prev_cam_transform = p_cam_transform;
}
-void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
- Color clear_color;
- if (p_render_buffers.is_valid()) {
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND(!rb);
- clear_color = storage->render_target_get_clear_request_color(rb->render_target);
- } else {
- clear_color = storage->get_default_clear_color();
+uint32_t RendererSceneRenderRD::_get_render_state_directional_light_count() const {
+ return render_state.directional_light_count;
+}
+
+bool RendererSceneRenderRD::_needs_post_prepass_render(bool p_use_gi) {
+ if (render_state.render_buffers.is_valid()) {
+ RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers);
+ if (rb->sdfgi != nullptr) {
+ return true;
+ }
}
+ return false;
+}
- //assign render indices to giprobes
- for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) {
- GIProbeInstance *giprobe_inst = gi_probe_instance_owner.getornull(p_gi_probes[i]);
- if (giprobe_inst) {
- giprobe_inst->render_index = i;
+void RendererSceneRenderRD::_post_prepass_render(bool p_use_gi) {
+ if (render_state.render_buffers.is_valid()) {
+ if (p_use_gi) {
+ RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers);
+ ERR_FAIL_COND(rb == nullptr);
+ if (rb->sdfgi == nullptr) {
+ return;
+ }
+
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(render_state.environment);
+ rb->sdfgi->update_probes(env, sky.sky_owner.getornull(env->sky));
+ }
+ }
+}
+
+void RendererSceneRenderRD::_pre_resolve_render(bool p_use_gi) {
+ if (render_state.render_buffers.is_valid()) {
+ if (p_use_gi) {
+ RD::get_singleton()->compute_list_end();
}
}
+}
- const PagedArray<RID> *lights = &p_lights;
- const PagedArray<RID> *reflections = &p_reflection_probes;
- const PagedArray<RID> *gi_probes = &p_gi_probes;
+void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer) {
+ // Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
- PagedArray<RID> empty;
+ if (render_state.render_buffers.is_valid() && p_use_gi) {
+ RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers);
+ ERR_FAIL_COND(rb == nullptr);
+ if (rb->sdfgi == nullptr) {
+ return;
+ }
- if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
- lights = &empty;
- reflections = &empty;
- gi_probes = &empty;
+ rb->sdfgi->store_probes();
}
- cluster.builder.begin(p_cam_transform.affine_inverse(), p_cam_projection); //prepare cluster
+ render_state.cube_shadows.clear();
+ render_state.shadows.clear();
+ render_state.directional_shadows.clear();
+
+ Plane camera_plane(render_state.cam_transform.origin, -render_state.cam_transform.basis.get_axis(Vector3::AXIS_Z));
+ float lod_distance_multiplier = render_state.cam_projection.get_lod_multiplier();
+
+ {
+ for (int i = 0; i < render_state.render_shadow_count; i++) {
+ LightInstance *li = light_instance_owner.getornull(render_state.render_shadows[i].light);
+
+ if (storage->light_get_type(li->light) == RS::LIGHT_DIRECTIONAL) {
+ render_state.directional_shadows.push_back(i);
+ } else if (storage->light_get_type(li->light) == RS::LIGHT_OMNI && storage->light_omni_get_shadow_mode(li->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
+ render_state.cube_shadows.push_back(i);
+ } else {
+ render_state.shadows.push_back(i);
+ }
+ }
+
+ //cube shadows are rendered in their own way
+ for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) {
+ _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, true, true, true);
+ }
+
+ if (render_state.directional_shadows.size()) {
+ //open the pass for directional shadows
+ _update_directional_shadow_atlas();
+ RD::get_singleton()->draw_list_begin(directional_shadow.fb, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE);
+ RD::get_singleton()->draw_list_end();
+ }
+ }
+
+ // Render GI
+
+ bool render_shadows = render_state.directional_shadows.size() || render_state.shadows.size();
+ bool render_gi = render_state.render_buffers.is_valid() && p_use_gi;
+
+ if (render_shadows && render_gi) {
+ RENDER_TIMESTAMP("Render GI + Render Shadows (parallel)");
+ } else if (render_shadows) {
+ RENDER_TIMESTAMP("Render Shadows");
+ } else if (render_gi) {
+ RENDER_TIMESTAMP("Render GI");
+ }
+
+ //prepare shadow rendering
+ if (render_shadows) {
+ _render_shadow_begin();
+
+ //render directional shadows
+ for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) {
+ _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false);
+ }
+ //render positional shadows
+ for (uint32_t i = 0; i < render_state.shadows.size(); i++) {
+ _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, render_state.shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, render_state.screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true);
+ }
+
+ _render_shadow_process();
+ }
+
+ //start GI
+ if (render_gi) {
+ gi.process_gi(render_state.render_buffers, p_normal_roughness_buffer, p_gi_probe_buffer, render_state.environment, render_state.cam_projection, render_state.cam_transform, *render_state.gi_probes, this);
+ }
+
+ //Do shadow rendering (in parallel with GI)
+ if (render_shadows) {
+ _render_shadow_end(RD::BARRIER_MASK_NO_BARRIER);
+ }
+
+ if (render_gi) {
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //use a later barrier
+ }
+
+ if (render_state.render_buffers.is_valid()) {
+ if (p_use_ssao) {
+ _process_ssao(render_state.render_buffers, render_state.environment, p_normal_roughness_buffer, render_state.cam_projection);
+ }
+ }
+
+ //full barrier here, we need raster, transfer and compute and it depends from the previous work
+ RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL);
+
+ if (current_cluster_builder) {
+ current_cluster_builder->begin(render_state.cam_transform, render_state.cam_projection, !render_state.reflection_probe.is_valid());
+ }
bool using_shadows = true;
- if (p_reflection_probe.is_valid()) {
- if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(p_reflection_probe))) {
+ if (render_state.reflection_probe.is_valid()) {
+ if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(render_state.reflection_probe))) {
using_shadows = false;
}
} else {
//do not render reflections when rendering a reflection probe
- _setup_reflections(*reflections, p_cam_transform.affine_inverse(), p_environment);
+ _setup_reflections(*render_state.reflection_probes, render_state.cam_transform.affine_inverse(), render_state.environment);
}
uint32_t directional_light_count = 0;
uint32_t positional_light_count = 0;
- _setup_lights(*lights, p_cam_transform.affine_inverse(), p_shadow_atlas, using_shadows, directional_light_count, positional_light_count);
- _setup_decals(p_decals, p_cam_transform.affine_inverse());
- cluster.builder.bake_cluster(); //bake to cluster
+ _setup_lights(*render_state.lights, render_state.cam_transform, render_state.shadow_atlas, using_shadows, directional_light_count, positional_light_count);
+ _setup_decals(*render_state.decals, render_state.cam_transform.affine_inverse());
- uint32_t gi_probe_count = 0;
- _setup_giprobes(p_render_buffers, p_cam_transform, *gi_probes, gi_probe_count);
+ render_state.directional_light_count = directional_light_count;
- if (p_render_buffers.is_valid()) {
+ if (current_cluster_builder) {
+ current_cluster_builder->bake_cluster();
+ }
+
+ if (render_state.render_buffers.is_valid()) {
bool directional_shadows = false;
for (uint32_t i = 0; i < directional_light_count; i++) {
if (cluster.directional_lights[i].shadow_enabled) {
@@ -7162,43 +3505,164 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
break;
}
}
- _update_volumetric_fog(p_render_buffers, p_environment, p_cam_projection, p_cam_transform, p_shadow_atlas, directional_light_count, directional_shadows, positional_light_count, gi_probe_count);
+ _update_volumetric_fog(render_state.render_buffers, render_state.environment, render_state.cam_projection, render_state.cam_transform, render_state.shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count);
+ }
+}
+
+void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data) {
+ // getting this here now so we can direct call a bunch of things more easily
+ RenderBuffers *rb = nullptr;
+ if (p_render_buffers.is_valid()) {
+ rb = render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND(!rb); // !BAS! Do we fail here or skip the parts that won't work. can't really see a case why we would be rendering without buffers....
+ }
+
+ //assign render data
+ {
+ render_state.render_buffers = p_render_buffers;
+ render_state.cam_transform = p_cam_transform;
+ render_state.cam_projection = p_cam_projection;
+ render_state.cam_ortogonal = p_cam_projection.is_orthogonal();
+ render_state.instances = &p_instances;
+ render_state.lights = &p_lights;
+ render_state.reflection_probes = &p_reflection_probes;
+ render_state.gi_probes = &p_gi_probes;
+ render_state.decals = &p_decals;
+ render_state.lightmaps = &p_lightmaps;
+ render_state.environment = p_environment;
+ render_state.camera_effects = p_camera_effects;
+ render_state.shadow_atlas = p_shadow_atlas;
+ render_state.reflection_atlas = p_reflection_atlas;
+ render_state.reflection_probe = p_reflection_probe;
+ render_state.reflection_probe_pass = p_reflection_probe_pass;
+ render_state.screen_lod_threshold = p_screen_lod_threshold;
+
+ render_state.render_shadows = p_render_shadows;
+ render_state.render_shadow_count = p_render_shadow_count;
+ render_state.render_sdfgi_regions = p_render_sdfgi_regions;
+ render_state.render_sdfgi_region_count = p_render_sdfgi_region_count;
+ render_state.sdfgi_update_data = p_sdfgi_update_data;
+ }
+
+ PagedArray<RID> empty;
+
+ if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
+ render_state.lights = &empty;
+ render_state.reflection_probes = &empty;
+ render_state.gi_probes = &empty;
+ }
+
+ //sdfgi first
+ if (rb != nullptr && rb->sdfgi != nullptr) {
+ for (int i = 0; i < render_state.render_sdfgi_region_count; i++) {
+ rb->sdfgi->render_region(p_render_buffers, render_state.render_sdfgi_regions[i].region, render_state.render_sdfgi_regions[i].instances, this);
+ }
+ if (render_state.sdfgi_update_data->update_static) {
+ rb->sdfgi->render_static_lights(p_render_buffers, render_state.sdfgi_update_data->static_cascade_count, p_sdfgi_update_data->static_cascade_indices, render_state.sdfgi_update_data->static_positional_lights, this);
+ }
+ }
+
+ Color clear_color;
+ if (p_render_buffers.is_valid()) {
+ clear_color = storage->render_target_get_clear_request_color(rb->render_target);
+ } else {
+ clear_color = storage->get_default_clear_color();
+ }
+
+ //assign render indices to giprobes
+ for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) {
+ RendererSceneGIRD::GIProbeInstance *giprobe_inst = gi.gi_probe_instance_owner.getornull(p_gi_probes[i]);
+ if (giprobe_inst) {
+ giprobe_inst->render_index = i;
+ }
}
- _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, directional_light_count, *gi_probes, p_lightmaps, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold);
+ if (render_buffers_owner.owns(render_state.render_buffers)) {
+ RenderBuffers *rs_rb = render_buffers_owner.getornull(render_state.render_buffers);
+ current_cluster_builder = rs_rb->cluster_builder;
+ } else if (reflection_probe_instance_owner.owns(render_state.reflection_probe)) {
+ ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_state.reflection_probe);
+ ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas);
+ if (!ra) {
+ ERR_PRINT("reflection probe has no reflection atlas! Bug?");
+ current_cluster_builder = nullptr;
+ } else {
+ current_cluster_builder = ra->cluster_builder;
+ }
+ } else {
+ ERR_PRINT("No cluster builder, bug"); //should never happen, will crash
+ current_cluster_builder = nullptr;
+ }
+
+ if (rb != nullptr && rb->sdfgi != nullptr) {
+ rb->sdfgi->update_cascades();
+
+ rb->sdfgi->pre_process_gi(p_cam_transform, this);
+ }
+
+ render_state.gi_probe_count = 0;
+ if (rb != nullptr && rb->sdfgi != nullptr) {
+ gi.setup_giprobes(render_state.render_buffers, render_state.cam_transform, *render_state.gi_probes, render_state.gi_probe_count, this);
+
+ rb->sdfgi->update_light();
+ }
+
+ render_state.depth_prepass_used = false;
+ //calls _pre_opaque_render between depth pre-pass and opaque pass
+ _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, *render_state.gi_probes, p_lightmaps, p_environment, current_cluster_builder->get_cluster_buffer(), current_cluster_builder->get_cluster_size(), current_cluster_builder->get_max_cluster_elements(), p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold);
if (p_render_buffers.is_valid()) {
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES) {
+ ClusterBuilderRD::ElementType elem_type = ClusterBuilderRD::ELEMENT_TYPE_MAX;
+ switch (debug_draw) {
+ case RS::VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS:
+ elem_type = ClusterBuilderRD::ELEMENT_TYPE_OMNI_LIGHT;
+ break;
+ case RS::VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS:
+ elem_type = ClusterBuilderRD::ELEMENT_TYPE_SPOT_LIGHT;
+ break;
+ case RS::VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS:
+ elem_type = ClusterBuilderRD::ELEMENT_TYPE_DECAL;
+ break;
+ case RS::VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES:
+ elem_type = ClusterBuilderRD::ELEMENT_TYPE_REFLECTION_PROBE;
+ break;
+ default: {
+ }
+ }
+ current_cluster_builder->debug(elem_type);
+ }
+
RENDER_TIMESTAMP("Tonemap");
_render_buffers_post_process_and_tonemap(p_render_buffers, p_environment, p_camera_effects, p_cam_projection);
_render_buffers_debug_draw(p_render_buffers, p_shadow_atlas);
- if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SDFGI) {
- _sdfgi_debug_draw(p_render_buffers, p_cam_projection, p_cam_transform);
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SDFGI && rb != nullptr && rb->sdfgi != nullptr) {
+ rb->sdfgi->debug_draw(p_cam_projection, p_cam_transform, rb->width, rb->height, rb->render_target, rb->texture);
}
}
}
-void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
+void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region) {
LightInstance *light_instance = light_instance_owner.getornull(p_light);
ERR_FAIL_COND(!light_instance);
Rect2i atlas_rect;
- RID atlas_texture;
+ uint32_t atlas_size;
+ RID atlas_fb;
bool using_dual_paraboloid = false;
bool using_dual_paraboloid_flip = false;
- float znear = 0;
- float zfar = 0;
RID render_fb;
RID render_texture;
- float bias = 0;
- float normal_bias = 0;
+ float zfar;
bool use_pancake = false;
- bool use_linear_depth = false;
bool render_cubemap = false;
bool finalize_cubemap = false;
+ bool flip_y = false;
+
CameraMatrix light_projection;
Transform light_transform;
@@ -7231,7 +3695,6 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
atlas_rect.position.x += atlas_rect.size.width;
atlas_rect.position.y += atlas_rect.size.height;
}
-
} else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
atlas_rect.size.height /= 2;
@@ -7246,15 +3709,11 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size;
light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size;
- float bias_mult = light_instance->shadow_transform[p_pass].bias_scale;
zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
- bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult;
- normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult;
- ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
- render_fb = shadow_map->fb;
- render_texture = shadow_map->depth;
- atlas_texture = directional_shadow.depth;
+ render_fb = directional_shadow.fb;
+ render_texture = RID();
+ flip_y = true;
} else {
//set from shadow atlas
@@ -7263,6 +3722,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
ERR_FAIL_COND(!shadow_atlas);
ERR_FAIL_COND(!shadow_atlas->shadow_owners.has(p_light));
+ _update_shadow_atlas(shadow_atlas);
+
uint32_t key = shadow_atlas->shadow_owners[p_light];
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
@@ -7281,11 +3742,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
atlas_rect.size.width = shadow_size;
atlas_rect.size.height = shadow_size;
- atlas_texture = shadow_atlas->depth;
zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
- bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS);
- normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS);
if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) {
if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
@@ -7294,10 +3752,17 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
render_fb = cubemap->side_fb[p_pass];
render_texture = cubemap->cubemap;
- light_projection = light_instance->shadow_transform[0].camera;
- light_transform = light_instance->shadow_transform[0].transform;
+ light_projection = light_instance->shadow_transform[p_pass].camera;
+ light_transform = light_instance->shadow_transform[p_pass].transform;
render_cubemap = true;
finalize_cubemap = p_pass == 5;
+ atlas_fb = shadow_atlas->fb;
+
+ atlas_size = shadow_atlas->size;
+
+ if (p_pass == 0) {
+ _render_shadow_begin();
+ }
} else {
light_projection = light_instance->shadow_transform[0].camera;
@@ -7308,394 +3773,52 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
using_dual_paraboloid = true;
using_dual_paraboloid_flip = p_pass == 1;
-
- ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
- render_fb = shadow_map->fb;
- render_texture = shadow_map->depth;
+ render_fb = shadow_atlas->fb;
+ flip_y = true;
}
} else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) {
light_projection = light_instance->shadow_transform[0].camera;
light_transform = light_instance->shadow_transform[0].transform;
- ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
- render_fb = shadow_map->fb;
- render_texture = shadow_map->depth;
+ render_fb = shadow_atlas->fb;
- znear = light_instance->shadow_transform[0].camera.get_z_near();
- use_linear_depth = true;
+ flip_y = true;
}
}
if (render_cubemap) {
//rendering to cubemap
- _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
+ _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, Rect2(), false, true, true, true);
if (finalize_cubemap) {
+ _render_shadow_process();
+ _render_shadow_end();
//reblit
- atlas_rect.size.height /= 2;
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false);
- atlas_rect.position.y += atlas_rect.size.height;
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true);
- }
- } else {
- //render shadow
-
- _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
+ Rect2 atlas_rect_norm = atlas_rect;
+ atlas_rect_norm.position.x /= float(atlas_size);
+ atlas_rect_norm.position.y /= float(atlas_size);
+ atlas_rect_norm.size.x /= float(atlas_size);
+ atlas_rect_norm.size.y /= float(atlas_size);
+ atlas_rect_norm.size.height /= 2;
+ storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false);
+ atlas_rect_norm.position.y += atlas_rect_norm.size.height;
+ storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true);
- //copy to atlas
- if (use_linear_depth) {
- storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar);
- } else {
- storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true);
+ //restore transform so it can be properly used
+ light_instance_set_shadow_transform(p_light, CameraMatrix(), light_instance->transform, zfar, 0, 0, 0);
}
- //does not work from depth to color
- //RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true);
+ } else {
+ //render shadow
+ _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass);
}
}
-void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
_render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region);
}
-void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances) {
- //print_line("rendering region " + itos(p_region));
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND(!rb);
- ERR_FAIL_COND(!rb->sdfgi);
- AABB bounds;
- Vector3i from;
- Vector3i size;
-
- int cascade_prev = _sdfgi_get_pending_region_data(p_render_buffers, p_region - 1, from, size, bounds);
- int cascade_next = _sdfgi_get_pending_region_data(p_render_buffers, p_region + 1, from, size, bounds);
- int cascade = _sdfgi_get_pending_region_data(p_render_buffers, p_region, from, size, bounds);
- ERR_FAIL_COND(cascade < 0);
-
- if (cascade_prev != cascade) {
- //initialize render
- RD::get_singleton()->texture_clear(rb->sdfgi->render_albedo, Color(0, 0, 0, 0), 0, 1, 0, 1, true);
- RD::get_singleton()->texture_clear(rb->sdfgi->render_emission, Color(0, 0, 0, 0), 0, 1, 0, 1, true);
- RD::get_singleton()->texture_clear(rb->sdfgi->render_emission_aniso, Color(0, 0, 0, 0), 0, 1, 0, 1, true);
- RD::get_singleton()->texture_clear(rb->sdfgi->render_geom_facing, Color(0, 0, 0, 0), 0, 1, 0, 1, true);
- }
-
- //print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(rb->sdfgi->cascades[cascade].cell_size));
- _render_sdfgi(p_render_buffers, from, size, bounds, p_instances, rb->sdfgi->render_albedo, rb->sdfgi->render_emission, rb->sdfgi->render_emission_aniso, rb->sdfgi->render_geom_facing);
-
- if (cascade_next != cascade) {
- RENDER_TIMESTAMP(">SDFGI Update SDF");
- //done rendering! must update SDF
- //clear dispatch indirect data
-
- SDGIShader::PreprocessPushConstant push_constant;
- zeromem(&push_constant, sizeof(SDGIShader::PreprocessPushConstant));
-
- RENDER_TIMESTAMP("Scroll SDF");
-
- //scroll
- if (rb->sdfgi->cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {
- //for scroll
- Vector3i dirty = rb->sdfgi->cascades[cascade].dirty_regions;
- push_constant.scroll[0] = dirty.x;
- push_constant.scroll[1] = dirty.y;
- push_constant.scroll[2] = dirty.z;
- } else {
- //for no scroll
- push_constant.scroll[0] = 0;
- push_constant.scroll[1] = 0;
- push_constant.scroll[2] = 0;
- }
- push_constant.grid_size = rb->sdfgi->cascade_size;
- push_constant.cascade = cascade;
-
- if (rb->sdfgi->cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
- //must pre scroll existing data because not all is dirty
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_SCROLL]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].scroll_uniform_set, 0);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_indirect(compute_list, rb->sdfgi->cascades[cascade].solid_cell_dispatch_buffer, 0);
- // no barrier do all together
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_SCROLL_OCCLUSION]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].scroll_occlusion_uniform_set, 0);
-
- Vector3i dirty = rb->sdfgi->cascades[cascade].dirty_regions;
- Vector3i groups;
- groups.x = rb->sdfgi->cascade_size - ABS(dirty.x);
- groups.y = rb->sdfgi->cascade_size - ABS(dirty.y);
- groups.z = rb->sdfgi->cascade_size - ABS(dirty.z);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z, 4, 4, 4);
-
- //no barrier, continue together
-
- {
- //scroll probes and their history also
-
- SDGIShader::IntegratePushConstant ipush_constant;
- ipush_constant.grid_size[1] = rb->sdfgi->cascade_size;
- ipush_constant.grid_size[2] = rb->sdfgi->cascade_size;
- ipush_constant.grid_size[0] = rb->sdfgi->cascade_size;
- ipush_constant.max_cascades = rb->sdfgi->cascades.size();
- ipush_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
- ipush_constant.history_index = 0;
- ipush_constant.history_size = rb->sdfgi->history_size;
- ipush_constant.ray_count = 0;
- ipush_constant.ray_bias = 0;
- ipush_constant.sky_mode = 0;
- ipush_constant.sky_energy = 0;
- ipush_constant.sky_color[0] = 0;
- ipush_constant.sky_color[1] = 0;
- ipush_constant.sky_color[2] = 0;
- ipush_constant.y_mult = rb->sdfgi->y_mult;
- ipush_constant.store_ambient_texture = false;
-
- ipush_constant.image_size[0] = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count;
- ipush_constant.image_size[1] = rb->sdfgi->probe_axis_count;
-
- int32_t probe_divisor = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR;
- ipush_constant.cascade = cascade;
- ipush_constant.world_offset[0] = rb->sdfgi->cascades[cascade].position.x / probe_divisor;
- ipush_constant.world_offset[1] = rb->sdfgi->cascades[cascade].position.y / probe_divisor;
- ipush_constant.world_offset[2] = rb->sdfgi->cascades[cascade].position.z / probe_divisor;
-
- ipush_constant.scroll[0] = dirty.x / probe_divisor;
- ipush_constant.scroll[1] = dirty.y / probe_divisor;
- ipush_constant.scroll[2] = dirty.z / probe_divisor;
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_SCROLL]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1);
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_SCROLL_STORE]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1);
- }
-
- //ok finally barrier
- RD::get_singleton()->compute_list_end();
- }
-
- //clear dispatch indirect data
- uint32_t dispatch_indirct_data[4] = { 0, 0, 0, 0 };
- RD::get_singleton()->buffer_update(rb->sdfgi->cascades[cascade].solid_cell_dispatch_buffer, 0, sizeof(uint32_t) * 4, dispatch_indirct_data, true);
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
- bool half_size = true; //much faster, very little difference
- static const int optimized_jf_group_size = 8;
-
- if (half_size) {
- push_constant.grid_size >>= 1;
-
- uint32_t cascade_half_size = rb->sdfgi->cascade_size >> 1;
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_initialize_half_uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, 4, 4, 4);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- //must start with regular jumpflood
-
- push_constant.half_size = true;
- {
- RENDER_TIMESTAMP("SDFGI Jump Flood (Half Size)");
-
- uint32_t s = cascade_half_size;
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD]);
-
- int jf_us = 0;
- //start with regular jump flood for very coarse reads, as this is impossible to optimize
- while (s > 1) {
- s /= 2;
- push_constant.step_size = s;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_half_uniform_set[jf_us], 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, 4, 4, 4);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- jf_us = jf_us == 0 ? 1 : 0;
-
- if (cascade_half_size / (s / 2) >= optimized_jf_group_size) {
- break;
- }
- }
-
- RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half Size)");
-
- //continue with optimized jump flood for smaller reads
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);
- while (s > 1) {
- s /= 2;
- push_constant.step_size = s;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_half_uniform_set[jf_us], 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- jf_us = jf_us == 0 ? 1 : 0;
- }
- }
-
- // restore grid size for last passes
- push_constant.grid_size = rb->sdfgi->cascade_size;
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_upscale_uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- //run one pass of fullsize jumpflood to fix up half size arctifacts
-
- push_constant.half_size = false;
- push_constant.step_size = 1;
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[rb->sdfgi->upscale_jfa_uniform_set_index], 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- } else {
- //full size jumpflood
- RENDER_TIMESTAMP("SDFGI Jump Flood");
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->sdf_initialize_uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4);
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- push_constant.half_size = false;
- {
- uint32_t s = rb->sdfgi->cascade_size;
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD]);
-
- int jf_us = 0;
- //start with regular jump flood for very coarse reads, as this is impossible to optimize
- while (s > 1) {
- s /= 2;
- push_constant.step_size = s;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[jf_us], 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- jf_us = jf_us == 0 ? 1 : 0;
-
- if (rb->sdfgi->cascade_size / (s / 2) >= optimized_jf_group_size) {
- break;
- }
- }
-
- RENDER_TIMESTAMP("SDFGI Jump Flood Optimized");
-
- //continue with optimized jump flood for smaller reads
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);
- while (s > 1) {
- s /= 2;
- push_constant.step_size = s;
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->jump_flood_uniform_set[jf_us], 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, optimized_jf_group_size, optimized_jf_group_size, optimized_jf_group_size);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- jf_us = jf_us == 0 ? 1 : 0;
- }
- }
- }
-
- RENDER_TIMESTAMP("SDFGI Occlusion");
-
- // occlusion
- {
- uint32_t probe_size = rb->sdfgi->cascade_size / SDFGI::PROBE_DIVISOR;
- Vector3i probe_global_pos = rb->sdfgi->cascades[cascade].position / probe_size;
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_OCCLUSION]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->occlusion_uniform_set, 0);
- for (int i = 0; i < 8; i++) {
- //dispatch all at once for performance
- Vector3i offset(i & 1, (i >> 1) & 1, (i >> 2) & 1);
-
- if ((probe_global_pos.x & 1) != 0) {
- offset.x = (offset.x + 1) & 1;
- }
- if ((probe_global_pos.y & 1) != 0) {
- offset.y = (offset.y + 1) & 1;
- }
- if ((probe_global_pos.z & 1) != 0) {
- offset.z = (offset.z + 1) & 1;
- }
- push_constant.probe_offset[0] = offset.x;
- push_constant.probe_offset[1] = offset.y;
- push_constant.probe_offset[2] = offset.z;
- push_constant.occlusion_index = i;
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
-
- Vector3i groups = Vector3i(probe_size + 1, probe_size + 1, probe_size + 1) - offset; //if offset, it's one less probe per axis to compute
- RD::get_singleton()->compute_list_dispatch(compute_list, groups.x, groups.y, groups.z);
- }
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- }
-
- RENDER_TIMESTAMP("SDFGI Store");
-
- // store
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.preprocess_pipeline[SDGIShader::PRE_PROCESS_STORE]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].sdf_store_uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, 4, 4, 4);
-
- RD::get_singleton()->compute_list_end();
-
- //clear these textures, as they will have previous garbage on next draw
- RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1, true);
- RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1, true);
- RD::get_singleton()->texture_clear(rb->sdfgi->cascades[cascade].light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1, true);
-
-#if 0
- Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rb->sdfgi->cascades[cascade].sdf, 0);
- Ref<Image> img;
- img.instance();
- for (uint32_t i = 0; i < rb->sdfgi->cascade_size; i++) {
- Vector<uint8_t> subarr = data.subarray(128 * 128 * i, 128 * 128 * (i + 1) - 1);
- img->create(rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, false, Image::FORMAT_L8, subarr);
- img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png");
- }
-
- //finalize render and update sdf
-#endif
-
-#if 0
- Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rb->sdfgi->render_albedo, 0);
- Ref<Image> img;
- img.instance();
- for (uint32_t i = 0; i < rb->sdfgi->cascade_size; i++) {
- Vector<uint8_t> subarr = data.subarray(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2 - 1);
- img->create(rb->sdfgi->cascade_size, rb->sdfgi->cascade_size, false, Image::FORMAT_RGB565, subarr);
- img->convert(Image::FORMAT_RGBA8);
- img->save_png("res://cascade_" + itos(cascade) + "_" + itos(i) + ".png");
- }
-
- //finalize render and update sdf
-#endif
-
- RENDER_TIMESTAMP("<SDFGI Update SDF");
- }
-}
-
-void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) {
+void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) {
ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider));
Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();
CameraMatrix cm;
@@ -7712,122 +3835,22 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider,
_render_particle_collider_heightfield(fb, cam_xform, cm, p_instances);
}
-void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) {
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
- ERR_FAIL_COND(!rb);
- ERR_FAIL_COND(!rb->sdfgi);
-
- _sdfgi_update_cascades(p_render_buffers); //need cascades updated for this
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_STATIC]);
-
- SDGIShader::DirectLightPushConstant dl_push_constant;
-
- dl_push_constant.grid_size[0] = rb->sdfgi->cascade_size;
- dl_push_constant.grid_size[1] = rb->sdfgi->cascade_size;
- dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size;
- dl_push_constant.max_cascades = rb->sdfgi->cascades.size();
- dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
- dl_push_constant.multibounce = false; // this is static light, do not multibounce yet
- dl_push_constant.y_mult = rb->sdfgi->y_mult;
-
- //all must be processed
- dl_push_constant.process_offset = 0;
- dl_push_constant.process_increment = 1;
-
- SDGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS];
-
- for (uint32_t i = 0; i < p_cascade_count; i++) {
- ERR_CONTINUE(p_cascade_indices[i] >= rb->sdfgi->cascades.size());
-
- SDFGI::Cascade &cc = rb->sdfgi->cascades[p_cascade_indices[i]];
-
- { //fill light buffer
-
- AABB cascade_aabb;
- cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(rb->sdfgi->cascade_size >> 1) + cc.position)) * cc.cell_size;
- cascade_aabb.size = Vector3(1, 1, 1) * rb->sdfgi->cascade_size * cc.cell_size;
-
- int idx = 0;
-
- for (uint32_t j = 0; j < (uint32_t)p_positional_light_cull_result[i].size(); j++) {
- if (idx == SDFGI::MAX_STATIC_LIGHTS) {
- break;
- }
-
- LightInstance *li = light_instance_owner.getornull(p_positional_light_cull_result[i][j]);
- ERR_CONTINUE(!li);
-
- uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light);
- if (p_cascade_indices[i] > max_sdfgi_cascade) {
- continue;
- }
-
- if (!cascade_aabb.intersects(li->aabb)) {
- continue;
- }
-
- lights[idx].type = storage->light_get_type(li->light);
-
- Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
- if (lights[idx].type == RS::LIGHT_DIRECTIONAL) {
- dir.y *= rb->sdfgi->y_mult; //only makes sense for directional
- dir.normalize();
- }
- lights[idx].direction[0] = dir.x;
- lights[idx].direction[1] = dir.y;
- lights[idx].direction[2] = dir.z;
- Vector3 pos = li->transform.origin;
- pos.y *= rb->sdfgi->y_mult;
- lights[idx].position[0] = pos.x;
- lights[idx].position[1] = pos.y;
- lights[idx].position[2] = pos.z;
- Color color = storage->light_get_color(li->light);
- color = color.to_linear();
- lights[idx].color[0] = color.r;
- lights[idx].color[1] = color.g;
- lights[idx].color[2] = color.b;
- lights[idx].energy = storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY);
- lights[idx].has_shadow = storage->light_has_shadow(li->light);
- lights[idx].attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
- lights[idx].radius = storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
- lights[idx].spot_angle = Math::deg2rad(storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE));
- lights[idx].spot_attenuation = storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
-
- idx++;
- }
-
- if (idx > 0) {
- RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights, true);
- }
- dl_push_constant.light_count = idx;
- }
-
- dl_push_constant.cascade = p_cascade_indices[i];
-
- if (dl_push_constant.light_count > 0) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cc.sdf_direct_light_uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &dl_push_constant, sizeof(SDGIShader::DirectLightPushConstant));
- RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cc.solid_cell_dispatch_buffer, 0);
- }
- }
-
- RD::get_singleton()->compute_list_end();
-}
-
bool RendererSceneRenderRD::free(RID p_rid) {
if (render_buffers_owner.owns(p_rid)) {
RenderBuffers *rb = render_buffers_owner.getornull(p_rid);
_free_render_buffer_data(rb);
memdelete(rb->data);
if (rb->sdfgi) {
- _sdfgi_erase(rb);
+ rb->sdfgi->erase();
+ memdelete(rb->sdfgi);
+ rb->sdfgi = nullptr;
}
if (rb->volumetric_fog) {
_volumetric_fog_erase(rb);
}
+ if (rb->cluster_builder) {
+ memdelete(rb->cluster_builder);
+ }
render_buffers_owner.free(p_rid);
} else if (environment_owner.owns(p_rid)) {
//not much to delete, just free it
@@ -7837,6 +3860,10 @@ bool RendererSceneRenderRD::free(RID p_rid) {
camera_effects_owner.free(p_rid);
} else if (reflection_atlas_owner.owns(p_rid)) {
reflection_atlas_set_size(p_rid, 0, 0);
+ ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_rid);
+ if (ra->cluster_builder) {
+ memdelete(ra->cluster_builder);
+ }
reflection_atlas_owner.free(p_rid);
} else if (reflection_probe_instance_owner.owns(p_rid)) {
//not much to delete, just free it
@@ -7845,8 +3872,10 @@ bool RendererSceneRenderRD::free(RID p_rid) {
reflection_probe_instance_owner.free(p_rid);
} else if (decal_instance_owner.owns(p_rid)) {
decal_instance_owner.free(p_rid);
- } else if (gi_probe_instance_owner.owns(p_rid)) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_rid);
+ } else if (lightmap_instance_owner.owns(p_rid)) {
+ lightmap_instance_owner.free(p_rid);
+ } else if (gi.gi_probe_instance_owner.owns(p_rid)) {
+ RendererSceneGIRD::GIProbeInstance *gi_probe = gi.gi_probe_instance_owner.getornull(p_rid);
if (gi_probe->texture.is_valid()) {
RD::get_singleton()->free(gi_probe->texture);
RD::get_singleton()->free(gi_probe->write_buffer);
@@ -7857,37 +3886,10 @@ bool RendererSceneRenderRD::free(RID p_rid) {
RD::get_singleton()->free(gi_probe->dynamic_maps[i].depth);
}
- gi_probe_instance_owner.free(p_rid);
- } else if (sky_owner.owns(p_rid)) {
- _update_dirty_skys();
- Sky *sky = sky_owner.getornull(p_rid);
-
- if (sky->radiance.is_valid()) {
- RD::get_singleton()->free(sky->radiance);
- sky->radiance = RID();
- }
- _clear_reflection_data(sky->reflection);
-
- if (sky->uniform_buffer.is_valid()) {
- RD::get_singleton()->free(sky->uniform_buffer);
- sky->uniform_buffer = RID();
- }
-
- if (sky->half_res_pass.is_valid()) {
- RD::get_singleton()->free(sky->half_res_pass);
- sky->half_res_pass = RID();
- }
-
- if (sky->quarter_res_pass.is_valid()) {
- RD::get_singleton()->free(sky->quarter_res_pass);
- sky->quarter_res_pass = RID();
- }
-
- if (sky->material.is_valid()) {
- storage->free(sky->material);
- }
-
- sky_owner.free(p_rid);
+ gi.gi_probe_instance_owner.free(p_rid);
+ } else if (sky.sky_owner.owns(p_rid)) {
+ sky.update_dirty_skys();
+ sky.free_sky(p_rid);
} else if (light_instance_owner.owns(p_rid)) {
LightInstance *light_instance = light_instance_owner.getornull(p_rid);
@@ -7921,7 +3923,7 @@ void RendererSceneRenderRD::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_dr
}
void RendererSceneRenderRD::update() {
- _update_dirty_skys();
+ sky.update_dirty_skys();
}
void RendererSceneRenderRD::set_time(double p_time, double p_step) {
@@ -7980,23 +3982,28 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
//RID sampled_light;
- InstanceBase ins;
+ GeometryInstance *gi = geometry_instance_create(p_base);
- ins.base_type = RSG::storage->get_base_type(p_base);
- ins.base = p_base;
- ins.materials.resize(RSG::storage->mesh_get_surface_count(p_base));
- for (int i = 0; i < ins.materials.size(); i++) {
- if (i < p_material_overrides.size()) {
- ins.materials.write[i] = p_material_overrides[i];
+ uint32_t sc = RSG::storage->mesh_get_surface_count(p_base);
+ Vector<RID> materials;
+ materials.resize(sc);
+
+ for (uint32_t i = 0; i < sc; i++) {
+ if (i < (uint32_t)p_material_overrides.size()) {
+ materials.write[i] = p_material_overrides[i];
}
}
+ geometry_instance_set_surface_materials(gi, materials);
+
if (cull_argument.size() == 0) {
cull_argument.push_back(nullptr);
}
- cull_argument[0] = &ins;
+ cull_argument[0] = gi;
_render_uv2(cull_argument, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height));
+ geometry_instance_free(gi);
+
TypedArray<Image> ret;
{
@@ -8042,26 +4049,23 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
}
void RendererSceneRenderRD::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {
- sdfgi_debug_probe_pos = p_position;
- sdfgi_debug_probe_dir = p_dir;
+ gi.sdfgi_debug_probe_pos = p_position;
+ gi.sdfgi_debug_probe_dir = p_dir;
}
RendererSceneRenderRD *RendererSceneRenderRD::singleton = nullptr;
-RID RendererSceneRenderRD::get_cluster_builder_texture() {
- return cluster.builder.get_cluster_texture();
-}
-
-RID RendererSceneRenderRD::get_cluster_builder_indices_buffer() {
- return cluster.builder.get_cluster_indices_buffer();
-}
-
RID RendererSceneRenderRD::get_reflection_probe_buffer() {
return cluster.reflection_buffer;
}
-RID RendererSceneRenderRD::get_positional_light_buffer() {
- return cluster.light_buffer;
+RID RendererSceneRenderRD::get_omni_light_buffer() {
+ return cluster.omni_light_buffer;
+}
+
+RID RendererSceneRenderRD::get_spot_light_buffer() {
+ return cluster.spot_light_buffer;
}
+
RID RendererSceneRenderRD::get_directional_light_buffer() {
return cluster.directional_light_buffer;
}
@@ -8077,429 +4081,66 @@ bool RendererSceneRenderRD::is_low_end() const {
}
RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
+ max_cluster_elements = GLOBAL_GET("rendering/limits/cluster_builder/max_clustered_elements");
+
storage = p_storage;
singleton = this;
- roughness_layers = GLOBAL_GET("rendering/quality/reflections/roughness_layers");
- sky_ggx_samples_quality = GLOBAL_GET("rendering/quality/reflections/ggx_samples");
- sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections");
- // sky_use_cubemap_array = false;
+ directional_shadow.size = GLOBAL_GET("rendering/shadows/directional_shadow/size");
+ directional_shadow.use_16_bits = GLOBAL_GET("rendering/shadows/directional_shadow/16_bits");
uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
- low_end = GLOBAL_GET("rendering/quality/rd_renderer/use_low_end_renderer");
+ low_end = GLOBAL_GET("rendering/driver/rd_renderer/use_low_end_renderer");
if (textures_per_stage < 48) {
low_end = true;
}
- if (!low_end) {
- //kinda complicated to compute the amount of slots, we try to use as many as we can
-
- gi_probe_max_lights = 32;
-
- gi_probe_lights = memnew_arr(GIProbeLight, gi_probe_max_lights);
- gi_probe_lights_uniform = RD::get_singleton()->uniform_buffer_create(gi_probe_max_lights * sizeof(GIProbeLight));
- gi_probe_quality = RS::GIProbeQuality(CLAMP(int(GLOBAL_GET("rendering/quality/gi_probes/quality")), 0, 1));
-
- String defines = "\n#define MAX_LIGHTS " + itos(gi_probe_max_lights) + "\n";
-
- Vector<String> versions;
- versions.push_back("\n#define MODE_COMPUTE_LIGHT\n");
- versions.push_back("\n#define MODE_SECOND_BOUNCE\n");
- versions.push_back("\n#define MODE_UPDATE_MIPMAPS\n");
- versions.push_back("\n#define MODE_WRITE_TEXTURE\n");
- versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_LIGHTING\n");
- versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_WRITE\n");
- versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n");
- versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n#define MODE_DYNAMIC_SHRINK_WRITE\n");
-
- giprobe_shader.initialize(versions, defines);
- giprobe_lighting_shader_version = giprobe_shader.version_create();
- for (int i = 0; i < GI_PROBE_SHADER_VERSION_MAX; i++) {
- giprobe_lighting_shader_version_shaders[i] = giprobe_shader.version_get_shader(giprobe_lighting_shader_version, i);
- giprobe_lighting_shader_version_pipelines[i] = RD::get_singleton()->compute_pipeline_create(giprobe_lighting_shader_version_shaders[i]);
- }
- }
-
- if (!low_end) {
- String defines;
- Vector<String> versions;
- versions.push_back("\n#define MODE_DEBUG_COLOR\n");
- versions.push_back("\n#define MODE_DEBUG_LIGHT\n");
- versions.push_back("\n#define MODE_DEBUG_EMISSION\n");
- versions.push_back("\n#define MODE_DEBUG_LIGHT\n#define MODE_DEBUG_LIGHT_FULL\n");
-
- giprobe_debug_shader.initialize(versions, defines);
- giprobe_debug_shader_version = giprobe_debug_shader.version_create();
- for (int i = 0; i < GI_PROBE_DEBUG_MAX; i++) {
- giprobe_debug_shader_version_shaders[i] = giprobe_debug_shader.version_get_shader(giprobe_debug_shader_version, i);
-
- RD::PipelineRasterizationState rs;
- rs.cull_mode = RD::POLYGON_CULL_FRONT;
- RD::PipelineDepthStencilState ds;
- ds.enable_depth_test = true;
- ds.enable_depth_write = true;
- ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
-
- giprobe_debug_shader_version_pipelines[i].setup(giprobe_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
- }
- }
-
/* SKY SHADER */
- {
- // Start with the directional lights for the sky
- sky_scene_state.max_directional_lights = 4;
- uint32_t directional_light_buffer_size = sky_scene_state.max_directional_lights * sizeof(SkyDirectionalLightData);
- sky_scene_state.directional_lights = memnew_arr(SkyDirectionalLightData, sky_scene_state.max_directional_lights);
- sky_scene_state.last_frame_directional_lights = memnew_arr(SkyDirectionalLightData, sky_scene_state.max_directional_lights);
- sky_scene_state.last_frame_directional_light_count = sky_scene_state.max_directional_lights + 1;
- sky_scene_state.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size);
-
- String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_scene_state.max_directional_lights) + "\n";
-
- // Initialize sky
- Vector<String> sky_modes;
- sky_modes.push_back(""); // Full size
- sky_modes.push_back("\n#define USE_HALF_RES_PASS\n"); // Half Res
- sky_modes.push_back("\n#define USE_QUARTER_RES_PASS\n"); // Quarter res
- sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n"); // Cubemap
- sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n#define USE_HALF_RES_PASS\n"); // Half Res Cubemap
- sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n#define USE_QUARTER_RES_PASS\n"); // Quarter res Cubemap
- sky_shader.shader.initialize(sky_modes, defines);
- }
-
- // register our shader funds
- storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_shader_funcs);
- storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
-
- {
- ShaderCompilerRD::DefaultIdentifierActions actions;
-
- actions.renames["COLOR"] = "color";
- actions.renames["ALPHA"] = "alpha";
- actions.renames["EYEDIR"] = "cube_normal";
- actions.renames["POSITION"] = "params.position_multiplier.xyz";
- actions.renames["SKY_COORDS"] = "panorama_coords";
- actions.renames["SCREEN_UV"] = "uv";
- actions.renames["TIME"] = "params.time";
- actions.renames["HALF_RES_COLOR"] = "half_res_color";
- actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color";
- actions.renames["RADIANCE"] = "radiance";
- actions.renames["FOG"] = "custom_fog";
- actions.renames["LIGHT0_ENABLED"] = "directional_lights.data[0].enabled";
- actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction_energy.xyz";
- actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].direction_energy.w";
- actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color_size.xyz";
- actions.renames["LIGHT0_SIZE"] = "directional_lights.data[0].color_size.w";
- actions.renames["LIGHT1_ENABLED"] = "directional_lights.data[1].enabled";
- actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction_energy.xyz";
- actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].direction_energy.w";
- actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color_size.xyz";
- actions.renames["LIGHT1_SIZE"] = "directional_lights.data[1].color_size.w";
- actions.renames["LIGHT2_ENABLED"] = "directional_lights.data[2].enabled";
- actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction_energy.xyz";
- actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].direction_energy.w";
- actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color_size.xyz";
- actions.renames["LIGHT2_SIZE"] = "directional_lights.data[2].color_size.w";
- actions.renames["LIGHT3_ENABLED"] = "directional_lights.data[3].enabled";
- actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction_energy.xyz";
- actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].direction_energy.w";
- actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color_size.xyz";
- actions.renames["LIGHT3_SIZE"] = "directional_lights.data[3].color_size.w";
- actions.renames["AT_CUBEMAP_PASS"] = "AT_CUBEMAP_PASS";
- actions.renames["AT_HALF_RES_PASS"] = "AT_HALF_RES_PASS";
- actions.renames["AT_QUARTER_RES_PASS"] = "AT_QUARTER_RES_PASS";
- actions.custom_samplers["RADIANCE"] = "material_samplers[3]";
- actions.usage_defines["HALF_RES_COLOR"] = "\n#define USES_HALF_RES_COLOR\n";
- actions.usage_defines["QUARTER_RES_COLOR"] = "\n#define USES_QUARTER_RES_COLOR\n";
- actions.render_mode_defines["disable_fog"] = "#define DISABLE_FOG\n";
-
- actions.sampler_array_name = "material_samplers";
- actions.base_texture_binding_index = 1;
- actions.texture_layout_set = 1;
- actions.base_uniform_string = "material.";
- actions.base_varying_index = 10;
-
- actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
- actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
- actions.global_buffer_array_variable = "global_variables.data";
-
- sky_shader.compiler.initialize(actions);
- }
-
- {
- // default material and shader for sky shader
- sky_shader.default_shader = storage->shader_create();
- storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0); } \n");
- sky_shader.default_material = storage->material_create();
- storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
-
- SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
- sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND);
-
- sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO));
-
- Vector<RD::Uniform> uniforms;
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 0;
- u.ids.resize(12);
- RID *ids_ptr = u.ids.ptrw();
- ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[3] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[4] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[5] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[6] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[7] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[8] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 1;
- u.ids.push_back(storage->global_variables_get_storage_buffer());
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.binding = 2;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(sky_scene_state.uniform_buffer);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(sky_scene_state.directional_light_buffer);
- uniforms.push_back(u);
- }
-
- sky_scene_state.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_UNIFORMS);
- }
-
- {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 0;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
- u.ids.push_back(vfog);
- uniforms.push_back(u);
- }
-
- sky_scene_state.default_fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG);
- }
-
- {
- // Need defaults for using fog with clear color
- sky_scene_state.fog_shader = storage->shader_create();
- storage->shader_set_code(sky_scene_state.fog_shader, "shader_type sky; uniform vec4 clear_color; void fragment() { COLOR = clear_color.rgb; } \n");
- sky_scene_state.fog_material = storage->material_create();
- storage->material_set_shader(sky_scene_state.fog_material, sky_scene_state.fog_shader);
-
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 0;
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1;
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 2;
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- uniforms.push_back(u);
- }
+ sky.init(storage);
- sky_scene_state.fog_only_texture_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_TEXTURES);
- }
+ /* GI */
if (!low_end) {
- //SDFGI
- {
- Vector<String> preprocess_modes;
- preprocess_modes.push_back("\n#define MODE_SCROLL\n");
- preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n");
- preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n");
- preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n");
- preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n");
- preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n");
- preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n");
- preprocess_modes.push_back("\n#define MODE_OCCLUSION\n");
- preprocess_modes.push_back("\n#define MODE_STORE\n");
- String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n";
- sdfgi_shader.preprocess.initialize(preprocess_modes, defines);
- sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create();
- for (int i = 0; i < SDGIShader::PRE_PROCESS_MAX; i++) {
- sdfgi_shader.preprocess_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i));
- }
- }
-
- {
- //calculate tables
- String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
-
- Vector<String> direct_light_modes;
- direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n");
- direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n");
- sdfgi_shader.direct_light.initialize(direct_light_modes, defines);
- sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create();
- for (int i = 0; i < SDGIShader::DIRECT_LIGHT_MODE_MAX; i++) {
- sdfgi_shader.direct_light_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i));
- }
- }
-
- {
- //calculate tables
- String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
- defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n";
-
- Vector<String> integrate_modes;
- integrate_modes.push_back("\n#define MODE_PROCESS\n");
- integrate_modes.push_back("\n#define MODE_STORE\n");
- integrate_modes.push_back("\n#define MODE_SCROLL\n");
- integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n");
- sdfgi_shader.integrate.initialize(integrate_modes, defines);
- sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create();
-
- for (int i = 0; i < SDGIShader::INTEGRATE_MODE_MAX; i++) {
- sdfgi_shader.integrate_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i));
- }
-
- {
- Vector<RD::Uniform> uniforms;
-
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 0;
- u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 1;
- u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
-
- sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1);
- }
- }
- {
- //calculate tables
- String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
- Vector<String> gi_modes;
- gi_modes.push_back("");
- gi.shader.initialize(gi_modes, defines);
- gi.shader_version = gi.shader.version_create();
- for (int i = 0; i < GI::MODE_MAX; i++) {
- gi.pipelines[i] = RD::get_singleton()->compute_pipeline_create(gi.shader.version_get_shader(gi.shader_version, i));
- }
-
- gi.sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(GI::SDFGIData));
- }
- {
- String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
- Vector<String> debug_modes;
- debug_modes.push_back("");
- sdfgi_shader.debug.initialize(debug_modes, defines);
- sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create();
- sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0);
- sdfgi_shader.debug_pipeline = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.debug_shader_version);
- }
- {
- String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
-
- Vector<String> versions;
- versions.push_back("\n#define MODE_PROBES\n");
- versions.push_back("\n#define MODE_VISIBILITY\n");
-
- sdfgi_shader.debug_probes.initialize(versions, defines);
- sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();
-
- {
- RD::PipelineRasterizationState rs;
- rs.cull_mode = RD::POLYGON_CULL_DISABLED;
- RD::PipelineDepthStencilState ds;
- ds.enable_depth_test = true;
- ds.enable_depth_write = true;
- ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
- for (int i = 0; i < SDGIShader::PROBE_DEBUG_MAX; i++) {
- RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);
- sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
- }
- }
- }
- default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::GIProbeData) * RenderBuffers::MAX_GIPROBES);
+ gi.init(storage, &sky);
}
- //cluster setup
- uint32_t uniform_max_size = RD::get_singleton()->limit_get(RD::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
+ { //decals
+ cluster.max_decals = max_cluster_elements;
+ uint32_t decal_buffer_size = cluster.max_decals * sizeof(Cluster::DecalData);
+ cluster.decals = memnew_arr(Cluster::DecalData, cluster.max_decals);
+ cluster.decal_sort = memnew_arr(Cluster::InstanceSort<DecalInstance>, cluster.max_decals);
+ cluster.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size);
+ }
{ //reflections
- uint32_t reflection_buffer_size;
- if (uniform_max_size < 65536) {
- //Yes, you guessed right, ARM again
- reflection_buffer_size = uniform_max_size;
- } else {
- reflection_buffer_size = 65536;
- }
- cluster.max_reflections = reflection_buffer_size / sizeof(Cluster::ReflectionData);
+ cluster.max_reflections = max_cluster_elements;
cluster.reflections = memnew_arr(Cluster::ReflectionData, cluster.max_reflections);
- cluster.reflection_buffer = RD::get_singleton()->storage_buffer_create(reflection_buffer_size);
+ cluster.reflection_sort = memnew_arr(Cluster::InstanceSort<ReflectionProbeInstance>, cluster.max_reflections);
+ cluster.reflection_buffer = RD::get_singleton()->storage_buffer_create(sizeof(Cluster::ReflectionData) * cluster.max_reflections);
}
{ //lights
- cluster.max_lights = MIN(1024 * 1024, uniform_max_size) / sizeof(Cluster::LightData); //1mb of lights
+ cluster.max_lights = max_cluster_elements;
+
uint32_t light_buffer_size = cluster.max_lights * sizeof(Cluster::LightData);
- cluster.lights = memnew_arr(Cluster::LightData, cluster.max_lights);
- cluster.light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size);
+ cluster.omni_lights = memnew_arr(Cluster::LightData, cluster.max_lights);
+ cluster.omni_light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size);
+ cluster.omni_light_sort = memnew_arr(Cluster::InstanceSort<LightInstance>, cluster.max_lights);
+ cluster.spot_lights = memnew_arr(Cluster::LightData, cluster.max_lights);
+ cluster.spot_light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size);
+ cluster.spot_light_sort = memnew_arr(Cluster::InstanceSort<LightInstance>, cluster.max_lights);
//defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(cluster.max_lights) + "\n";
- cluster.lights_instances = memnew_arr(RID, cluster.max_lights);
- cluster.lights_shadow_rect_cache = memnew_arr(Rect2i, cluster.max_lights);
- cluster.max_directional_lights = 8;
+ cluster.max_directional_lights = MAX_DIRECTIONAL_LIGHTS;
uint32_t directional_light_buffer_size = cluster.max_directional_lights * sizeof(Cluster::DirectionalLightData);
cluster.directional_lights = memnew_arr(Cluster::DirectionalLightData, cluster.max_directional_lights);
cluster.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size);
}
- { //decals
- cluster.max_decals = MIN(1024 * 1024, uniform_max_size) / sizeof(Cluster::DecalData); //1mb of decals
- uint32_t decal_buffer_size = cluster.max_decals * sizeof(Cluster::DecalData);
- cluster.decals = memnew_arr(Cluster::DecalData, cluster.max_decals);
- cluster.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size);
- }
-
- cluster.builder.setup(16, 8, 24);
-
if (!low_end) {
String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(cluster.max_directional_lights) + "\n";
Vector<String> volumetric_fog_modes;
@@ -8512,6 +4153,7 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
for (int i = 0; i < VOLUMETRIC_FOG_SHADER_MAX; i++) {
volumetric_fog.pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.shader.version_get_shader(volumetric_fog.shader_version, i));
}
+ volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO));
}
{
@@ -8523,74 +4165,59 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
shadow_sampler = RD::get_singleton()->sampler_create(sampler);
}
- camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape"))));
- camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter"));
- environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"), GLOBAL_GET("rendering/quality/ssao/adaptive_target"), GLOBAL_GET("rendering/quality/ssao/blur_passes"), GLOBAL_GET("rendering/quality/ssao/fadeout_from"), GLOBAL_GET("rendering/quality/ssao/fadeout_to"));
- screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled");
- screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount");
- screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit");
- glow_bicubic_upscale = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0;
- glow_high_quality = GLOBAL_GET("rendering/quality/glow/use_high_quality");
- ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality")));
- sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality")));
- sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale");
- sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale");
+ camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_shape"))));
+ camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_use_jitter"));
+ environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/environment/ssao/quality"))), GLOBAL_GET("rendering/environment/ssao/half_size"), GLOBAL_GET("rendering/environment/ssao/adaptive_target"), GLOBAL_GET("rendering/environment/ssao/blur_passes"), GLOBAL_GET("rendering/environment/ssao/fadeout_from"), GLOBAL_GET("rendering/environment/ssao/fadeout_to"));
+ screen_space_roughness_limiter = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/enabled");
+ screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/amount");
+ screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/anti_aliasing/screen_space_roughness_limiter/limit");
+ glow_bicubic_upscale = int(GLOBAL_GET("rendering/environment/glow/upscale_mode")) > 0;
+ glow_high_quality = GLOBAL_GET("rendering/environment/glow/use_high_quality");
+ ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/environment/screen_space_reflection/roughness_quality")));
+ sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_quality")));
+ sss_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_scale");
+ sss_depth_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale");
directional_penumbra_shadow_kernel = memnew_arr(float, 128);
directional_soft_shadow_kernel = memnew_arr(float, 128);
penumbra_shadow_kernel = memnew_arr(float, 128);
soft_shadow_kernel = memnew_arr(float, 128);
- shadows_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality"))));
- directional_shadow_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality"))));
+ shadows_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/shadows/soft_shadow_quality"))));
+ directional_shadow_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/shadows/directional_shadow/soft_shadow_quality"))));
- environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth"));
- environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter"));
- environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink"));
- environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
+ environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/environment/volumetric_fog/volume_size"), GLOBAL_GET("rendering/environment/volumetric_fog/volume_depth"));
+ environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter"));
cull_argument.set_page_pool(&cull_argument_pool);
+
+ gi.half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution");
}
RendererSceneRenderRD::~RendererSceneRenderRD() {
- for (Map<Vector2i, ShadowMap>::Element *E = shadow_maps.front(); E; E = E->next()) {
- RD::get_singleton()->free(E->get().depth);
- }
for (Map<int, ShadowCubemap>::Element *E = shadow_cubemaps.front(); E; E = E->next()) {
RD::get_singleton()->free(E->get().cubemap);
}
- if (sky_scene_state.uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_scene_state.uniform_set)) {
- RD::get_singleton()->free(sky_scene_state.uniform_set);
+ if (sky.sky_scene_state.uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky.sky_scene_state.uniform_set)) {
+ RD::get_singleton()->free(sky.sky_scene_state.uniform_set);
}
if (!low_end) {
- RD::get_singleton()->free(default_giprobe_buffer);
- RD::get_singleton()->free(gi_probe_lights_uniform);
- RD::get_singleton()->free(gi.sdfgi_ubo);
-
- giprobe_debug_shader.version_free(giprobe_debug_shader_version);
- giprobe_shader.version_free(giprobe_lighting_shader_version);
- gi.shader.version_free(gi.shader_version);
- sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);
- sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);
- sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader);
- sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);
- sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);
+ gi.free();
volumetric_fog.shader.version_free(volumetric_fog.shader_version);
-
- memdelete_arr(gi_probe_lights);
- }
-
- SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
- sky_shader.shader.version_free(md->shader_data->version);
- RD::get_singleton()->free(sky_scene_state.directional_light_buffer);
- RD::get_singleton()->free(sky_scene_state.uniform_buffer);
- memdelete_arr(sky_scene_state.directional_lights);
- memdelete_arr(sky_scene_state.last_frame_directional_lights);
- storage->free(sky_shader.default_shader);
- storage->free(sky_shader.default_material);
- storage->free(sky_scene_state.fog_shader);
- storage->free(sky_scene_state.fog_material);
+ RD::get_singleton()->free(volumetric_fog.params_ubo);
+ }
+
+ RendererSceneSkyRD::SkyMaterialData *md = (RendererSceneSkyRD::SkyMaterialData *)storage->material_get_data(sky.sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
+ sky.sky_shader.shader.version_free(md->shader_data->version);
+ RD::get_singleton()->free(sky.sky_scene_state.directional_light_buffer);
+ RD::get_singleton()->free(sky.sky_scene_state.uniform_buffer);
+ memdelete_arr(sky.sky_scene_state.directional_lights);
+ memdelete_arr(sky.sky_scene_state.last_frame_directional_lights);
+ storage->free(sky.sky_shader.default_shader);
+ storage->free(sky.sky_shader.default_material);
+ storage->free(sky.sky_scene_state.fog_shader);
+ storage->free(sky.sky_scene_state.fog_material);
memdelete_arr(directional_penumbra_shadow_kernel);
memdelete_arr(directional_soft_shadow_kernel);
memdelete_arr(penumbra_shadow_kernel);
@@ -8598,15 +4225,19 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
{
RD::get_singleton()->free(cluster.directional_light_buffer);
- RD::get_singleton()->free(cluster.light_buffer);
+ RD::get_singleton()->free(cluster.omni_light_buffer);
+ RD::get_singleton()->free(cluster.spot_light_buffer);
RD::get_singleton()->free(cluster.reflection_buffer);
RD::get_singleton()->free(cluster.decal_buffer);
memdelete_arr(cluster.directional_lights);
- memdelete_arr(cluster.lights);
- memdelete_arr(cluster.lights_shadow_rect_cache);
- memdelete_arr(cluster.lights_instances);
+ memdelete_arr(cluster.omni_lights);
+ memdelete_arr(cluster.spot_lights);
+ memdelete_arr(cluster.omni_light_sort);
+ memdelete_arr(cluster.spot_light_sort);
memdelete_arr(cluster.reflections);
+ memdelete_arr(cluster.reflection_sort);
memdelete_arr(cluster.decals);
+ memdelete_arr(cluster.decal_sort);
}
RD::get_singleton()->free(shadow_sampler);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index ded6d99e47..001cfeb74d 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,69 +34,23 @@
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering/renderer_rd/light_cluster_builder.h"
+#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_gi_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
-#include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/giprobe.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/giprobe_debug.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
class RendererSceneRenderRD : public RendererSceneRender {
+ friend RendererSceneSkyRD;
+ friend RendererSceneGIRD;
+
protected:
+ RendererStorageRD *storage;
double time;
-
- // Skys need less info from Directional Lights than the normal shaders
- struct SkyDirectionalLightData {
- float direction[3];
- float energy;
- float color[3];
- float size;
- uint32_t enabled;
- uint32_t pad[3];
- };
-
- struct SkySceneState {
- struct UBO {
- uint32_t volumetric_fog_enabled;
- float volumetric_fog_inv_length;
- float volumetric_fog_detail_spread;
-
- float fog_aerial_perspective;
-
- float fog_light_color[3];
- float fog_sun_scatter;
-
- uint32_t fog_enabled;
- float fog_density;
-
- float z_far;
- uint32_t directional_light_count;
- };
-
- UBO ubo;
-
- SkyDirectionalLightData *directional_lights;
- SkyDirectionalLightData *last_frame_directional_lights;
- uint32_t max_directional_lights;
- uint32_t last_frame_directional_light_count;
- RID directional_light_buffer;
- RID uniform_set;
- RID uniform_buffer;
- RID fog_uniform_set;
- RID default_fog_uniform_set;
-
- RID fog_shader;
- RID fog_material;
- RID fog_only_texture_uniform_set;
- } sky_scene_state;
+ double time_step = 0;
struct RenderBufferData {
virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) = 0;
@@ -104,19 +58,22 @@ protected:
};
virtual RenderBufferData *_create_render_buffer_data() = 0;
- void _setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count);
+ void _setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count);
void _setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform);
void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment);
- void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used);
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
- virtual void _render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
- virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
- virtual void _render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
- virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
- virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) = 0;
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
+
+ virtual void _render_shadow_begin() = 0;
+ virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0;
+ virtual void _render_shadow_process() = 0;
+ virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0;
+
+ virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
+ virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
+ virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
+ virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0;
- virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
RenderBufferData *render_buffers_get_data(RID p_render_buffers);
@@ -124,205 +81,37 @@ protected:
virtual void _base_uniforms_changed() = 0;
virtual void _render_buffers_uniform_set_changed(RID p_render_buffers) = 0;
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) = 0;
- virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers) = 0;
- virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers) = 0;
void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection);
void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive);
void _process_sss(RID p_render_buffers, const CameraMatrix &p_camera);
- void _setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size);
- void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
- void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
- void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes);
+ bool _needs_post_prepass_render(bool p_use_gi);
+ void _post_prepass_render(bool p_use_gi);
+ void _pre_resolve_render(bool p_use_gi);
+
+ void _pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer);
+ uint32_t _get_render_state_directional_light_count() const;
// needed for a single argument calls (material and uv2)
- PagedArrayPool<InstanceBase *> cull_argument_pool;
- PagedArray<InstanceBase *> cull_argument; //need this to exist
+ PagedArrayPool<GeometryInstance *> cull_argument_pool;
+ PagedArray<GeometryInstance *> cull_argument; //need this to exist
+
+ RendererSceneGIRD gi;
+ RendererSceneSkyRD sky;
+
+ RendererSceneEnvironmentRD *get_environment(RID p_environment) {
+ if (p_environment.is_valid()) {
+ return environment_owner.getornull(p_environment);
+ } else {
+ return nullptr;
+ }
+ }
+
private:
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
- double time_step = 0;
static RendererSceneRenderRD *singleton;
- int roughness_layers;
-
- RendererStorageRD *storage;
-
- struct ReflectionData {
- struct Layer {
- struct Mipmap {
- RID framebuffers[6];
- RID views[6];
- Size2i size;
- };
- Vector<Mipmap> mipmaps; //per-face view
- Vector<RID> views; // per-cubemap view
- };
-
- struct DownsampleLayer {
- struct Mipmap {
- RID view;
- Size2i size;
- };
- Vector<Mipmap> mipmaps;
- };
-
- RID radiance_base_cubemap; //cubemap for first layer, first cubemap
- RID downsampled_radiance_cubemap;
- DownsampleLayer downsampled_layer;
- RID coefficient_buffer;
-
- bool dirty = true;
-
- Vector<Layer> layers;
- };
-
- void _clear_reflection_data(ReflectionData &rd);
- void _update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality);
- void _create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays);
- void _create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer);
- void _update_reflection_mipmaps(ReflectionData &rd, int p_start, int p_end);
-
- /* Sky shader */
-
- enum SkyVersion {
- SKY_VERSION_BACKGROUND,
- SKY_VERSION_HALF_RES,
- SKY_VERSION_QUARTER_RES,
- SKY_VERSION_CUBEMAP,
- SKY_VERSION_CUBEMAP_HALF_RES,
- SKY_VERSION_CUBEMAP_QUARTER_RES,
- SKY_VERSION_MAX
- };
-
- struct SkyShader {
- SkyShaderRD shader;
- ShaderCompilerRD compiler;
-
- RID default_shader;
- RID default_material;
- RID default_shader_rd;
- } sky_shader;
-
- struct SkyShaderData : public RendererStorageRD::ShaderData {
- bool valid;
- RID version;
-
- PipelineCacheRD pipelines[SKY_VERSION_MAX];
- Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
-
- Vector<uint32_t> ubo_offsets;
- uint32_t ubo_size;
-
- String path;
- String code;
- Map<StringName, RID> default_texture_params;
-
- bool uses_time;
- bool uses_position;
- bool uses_half_res;
- bool uses_quarter_res;
- bool uses_light;
-
- virtual void set_code(const String &p_Code);
- virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
- virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
- virtual bool is_param_texture(const StringName &p_param) const;
- virtual bool is_animated() const;
- virtual bool casts_shadows() const;
- virtual Variant get_default_parameter(const StringName &p_parameter) const;
- SkyShaderData();
- virtual ~SkyShaderData();
- };
-
- RendererStorageRD::ShaderData *_create_sky_shader_func();
- static RendererStorageRD::ShaderData *_create_sky_shader_funcs() {
- return static_cast<RendererSceneRenderRD *>(singleton)->_create_sky_shader_func();
- };
-
- struct SkyMaterialData : public RendererStorageRD::MaterialData {
- uint64_t last_frame;
- SkyShaderData *shader_data;
- RID uniform_buffer;
- RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
- bool uniform_set_updated;
-
- virtual void set_render_priority(int p_priority) {}
- virtual void set_next_pass(RID p_pass) {}
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
- virtual ~SkyMaterialData();
- };
-
- RendererStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
- static RendererStorageRD::MaterialData *_create_sky_material_funcs(RendererStorageRD::ShaderData *p_shader) {
- return static_cast<RendererSceneRenderRD *>(singleton)->_create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
- };
-
- enum SkyTextureSetVersion {
- SKY_TEXTURE_SET_BACKGROUND,
- SKY_TEXTURE_SET_HALF_RES,
- SKY_TEXTURE_SET_QUARTER_RES,
- SKY_TEXTURE_SET_CUBEMAP,
- SKY_TEXTURE_SET_CUBEMAP_HALF_RES,
- SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES,
- SKY_TEXTURE_SET_MAX
- };
-
- enum SkySet {
- SKY_SET_UNIFORMS,
- SKY_SET_MATERIAL,
- SKY_SET_TEXTURES,
- SKY_SET_FOG,
- SKY_SET_MAX
- };
-
- /* SKY */
- struct Sky {
- RID radiance;
- RID half_res_pass;
- RID half_res_framebuffer;
- RID quarter_res_pass;
- RID quarter_res_framebuffer;
- Size2i screen_size;
-
- RID texture_uniform_sets[SKY_TEXTURE_SET_MAX];
- RID uniform_set;
-
- RID material;
- RID uniform_buffer;
-
- int radiance_size = 256;
-
- RS::SkyMode mode = RS::SKY_MODE_AUTOMATIC;
-
- ReflectionData reflection;
- bool dirty = false;
- int processing_layer = 0;
- Sky *dirty_list = nullptr;
-
- //State to track when radiance cubemap needs updating
- SkyMaterialData *prev_material;
- Vector3 prev_position;
- float prev_time;
-
- RID sdfgi_integrate_sky_uniform_set;
- };
-
- Sky *dirty_sky_list = nullptr;
-
- void _sky_invalidate(Sky *p_sky);
- void _update_dirty_skys();
- RID _get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version);
-
- uint32_t sky_ggx_samples_quality;
- bool sky_use_cubemap_array;
-
- mutable RID_Owner<Sky> sky_owner;
-
/* REFLECTION ATLAS */
struct ReflectionAtlas {
@@ -335,11 +124,13 @@ private:
struct Reflection {
RID owner;
- ReflectionData data;
+ RendererSceneSkyRD::ReflectionData data;
RID fbs[6];
};
Vector<Reflection> reflections;
+
+ ClusterBuilderRD *cluster_builder = nullptr;
};
mutable RID_Owner<ReflectionAtlas> reflection_atlas_owner;
@@ -374,150 +165,14 @@ private:
mutable RID_Owner<DecalInstance> decal_instance_owner;
- /* GIPROBE INSTANCE */
-
- struct GIProbeLight {
- uint32_t type;
- float energy;
- float radius;
- float attenuation;
-
- float color[3];
- float spot_angle_radians;
-
- float position[3];
- float spot_attenuation;
-
- float direction[3];
- uint32_t has_shadow;
- };
-
- struct GIProbePushConstant {
- int32_t limits[3];
- uint32_t stack_size;
-
- float emission_scale;
- float propagation;
- float dynamic_range;
- uint32_t light_count;
-
- uint32_t cell_offset;
- uint32_t cell_count;
- float aniso_strength;
- uint32_t pad;
- };
-
- struct GIProbeDynamicPushConstant {
- int32_t limits[3];
- uint32_t light_count;
- int32_t x_dir[3];
- float z_base;
- int32_t y_dir[3];
- float z_sign;
- int32_t z_dir[3];
- float pos_multiplier;
- uint32_t rect_pos[2];
- uint32_t rect_size[2];
- uint32_t prev_rect_ofs[2];
- uint32_t prev_rect_size[2];
- uint32_t flip_x;
- uint32_t flip_y;
- float dynamic_range;
- uint32_t on_mipmap;
- float propagation;
- float pad[3];
- };
-
- struct GIProbeInstance {
- RID probe;
- RID texture;
- RID write_buffer;
-
- struct Mipmap {
- RID texture;
- RID uniform_set;
- RID second_bounce_uniform_set;
- RID write_uniform_set;
- uint32_t level;
- uint32_t cell_offset;
- uint32_t cell_count;
- };
- Vector<Mipmap> mipmaps;
-
- struct DynamicMap {
- RID texture; //color normally, or emission on first pass
- RID fb_depth; //actual depth buffer for the first pass, float depth for later passes
- RID depth; //actual depth buffer for the first pass, float depth for later passes
- RID normal; //normal buffer for the first pass
- RID albedo; //emission buffer for the first pass
- RID orm; //orm buffer for the first pass
- RID fb; //used for rendering, only valid on first map
- RID uniform_set;
- uint32_t size;
- int mipmap; // mipmap to write to, -1 if no mipmap assigned
- };
-
- Vector<DynamicMap> dynamic_maps;
-
- int slot = -1;
- uint32_t last_probe_version = 0;
- uint32_t last_probe_data_version = 0;
-
- //uint64_t last_pass = 0;
- uint32_t render_index = 0;
-
- bool has_dynamic_object_data = false;
+ /* LIGHTMAP INSTANCE */
+ struct LightmapInstance {
+ RID lightmap;
Transform transform;
};
- GIProbeLight *gi_probe_lights;
- uint32_t gi_probe_max_lights;
- RID gi_probe_lights_uniform;
-
- enum {
- GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT,
- GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE,
- GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP,
- GI_PROBE_SHADER_VERSION_WRITE_TEXTURE,
- GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING,
- GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE,
- GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT,
- GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT,
- GI_PROBE_SHADER_VERSION_MAX
- };
- GiprobeShaderRD giprobe_shader;
- RID giprobe_lighting_shader_version;
- RID giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_MAX];
- RID giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_MAX];
-
- mutable RID_Owner<GIProbeInstance> gi_probe_instance_owner;
-
- RS::GIProbeQuality gi_probe_quality = RS::GI_PROBE_QUALITY_HIGH;
-
- enum {
- GI_PROBE_DEBUG_COLOR,
- GI_PROBE_DEBUG_LIGHT,
- GI_PROBE_DEBUG_EMISSION,
- GI_PROBE_DEBUG_LIGHT_FULL,
- GI_PROBE_DEBUG_MAX
- };
-
- struct GIProbeDebugPushConstant {
- float projection[16];
- uint32_t cell_offset;
- float dynamic_range;
- float alpha;
- uint32_t level;
- int32_t bounds[3];
- uint32_t pad;
- };
-
- GiprobeDebugShaderRD giprobe_debug_shader;
- RID giprobe_debug_shader_version;
- RID giprobe_debug_shader_version_shaders[GI_PROBE_DEBUG_MAX];
- PipelineCacheRD giprobe_debug_shader_version_pipelines[GI_PROBE_DEBUG_MAX];
- RID giprobe_debug_uniform_set;
+ mutable RID_Owner<LightmapInstance> lightmap_instance_owner;
/* SHADOW ATLAS */
@@ -562,17 +217,18 @@ private:
uint32_t smallest_subdiv = 0;
int size = 0;
+ bool use_16_bits = false;
RID depth;
RID fb; //for copying
Map<RID, uint32_t> shadow_owners;
-
- Vector<ShadowShrinkStage> shrink_stages;
};
RID_Owner<ShadowAtlas> shadow_atlas_owner;
+ void _update_shadow_atlas(ShadowAtlas *shadow_atlas);
+
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set
@@ -593,17 +249,16 @@ private:
struct DirectionalShadow {
RID depth;
+ RID fb; //when renderign direct
int light_count = 0;
int size = 0;
+ bool use_16_bits = false;
int current_light = 0;
- Vector<ShadowShrinkStage> shrink_stages;
-
} directional_shadow;
- void _allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size);
- void _clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages);
+ void _update_directional_shadow_atlas();
/* SHADOW CUBEMAPS */
@@ -615,14 +270,6 @@ private:
Map<int, ShadowCubemap> shadow_cubemaps;
ShadowCubemap *_get_shadow_cubemap(int p_size);
- struct ShadowMap {
- RID depth;
- RID fb;
- };
-
- Map<Vector2i, ShadowMap> shadow_maps;
- ShadowMap *_get_shadow_map(const Size2i &p_size);
-
void _create_shadow_cubemaps();
/* LIGHT INSTANCE */
@@ -642,7 +289,7 @@ private:
RS::LightType light_type = RS::LIGHT_DIRECTIONAL;
- ShadowTransform shadow_transform[4];
+ ShadowTransform shadow_transform[6];
AABB aabb;
RID self;
@@ -675,110 +322,6 @@ private:
/* ENVIRONMENT */
- struct Environment {
- // BG
- RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR;
- RID sky;
- float sky_custom_fov = 0.0;
- Basis sky_orientation;
- Color bg_color;
- float bg_energy = 1.0;
- int canvas_max_layer = 0;
- RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG;
- Color ambient_light;
- float ambient_light_energy = 1.0;
- float ambient_sky_contribution = 1.0;
- RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG;
- Color ao_color;
-
- /// Tonemap
-
- RS::EnvironmentToneMapper tone_mapper;
- float exposure = 1.0;
- float white = 1.0;
- bool auto_exposure = false;
- float min_luminance = 0.2;
- float max_luminance = 8.0;
- float auto_exp_speed = 0.2;
- float auto_exp_scale = 0.5;
- uint64_t auto_exposure_version = 0;
-
- // Fog
- bool fog_enabled = false;
- Color fog_light_color = Color(0.5, 0.6, 0.7);
- float fog_light_energy = 1.0;
- float fog_sun_scatter = 0.0;
- float fog_density = 0.001;
- float fog_height = 0.0;
- float fog_height_density = 0.0; //can be negative to invert effect
- float fog_aerial_perspective = 0.0;
-
- /// Volumetric Fog
- ///
- bool volumetric_fog_enabled = false;
- float volumetric_fog_density = 0.01;
- Color volumetric_fog_light = Color(0, 0, 0);
- float volumetric_fog_light_energy = 0.0;
- float volumetric_fog_length = 64.0;
- float volumetric_fog_detail_spread = 2.0;
- RS::EnvVolumetricFogShadowFilter volumetric_fog_shadow_filter = RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW;
- float volumetric_fog_gi_inject = 0.0;
-
- /// Glow
-
- bool glow_enabled = false;
- Vector<float> glow_levels;
- float glow_intensity = 0.8;
- float glow_strength = 1.0;
- float glow_bloom = 0.0;
- float glow_mix = 0.01;
- RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT;
- float glow_hdr_bleed_threshold = 1.0;
- float glow_hdr_luminance_cap = 12.0;
- float glow_hdr_bleed_scale = 2.0;
-
- /// SSAO
-
- bool ssao_enabled = false;
- float ssao_radius = 1.0;
- float ssao_intensity = 2.0;
- float ssao_power = 1.5;
- float ssao_detail = 0.5;
- float ssao_horizon = 0.06;
- float ssao_sharpness = 0.98;
- float ssao_direct_light_affect = 0.0;
- float ssao_ao_channel_affect = 0.0;
-
- /// SSR
- ///
- bool ssr_enabled = false;
- int ssr_max_steps = 64;
- float ssr_fade_in = 0.15;
- float ssr_fade_out = 2.0;
- float ssr_depth_tolerance = 0.2;
-
- /// SDFGI
- bool sdfgi_enabled = false;
- RS::EnvironmentSDFGICascades sdfgi_cascades;
- float sdfgi_min_cell_size = 0.2;
- bool sdfgi_use_occlusion = false;
- bool sdfgi_use_multibounce = false;
- bool sdfgi_read_sky_light = false;
- float sdfgi_energy = 1.0;
- float sdfgi_normal_bias = 1.1;
- float sdfgi_probe_bias = 1.1;
- RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_DISABLED;
-
- /// Adjustments
-
- bool adjustments_enabled = false;
- float adjustments_brightness = 1.0f;
- float adjustments_contrast = 1.0f;
- float adjustments_saturation = 1.0f;
- bool use_1d_color_correction = false;
- RID color_correction = RID();
- };
-
RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
bool ssao_half_size = false;
bool ssao_using_half_size = false;
@@ -791,9 +334,7 @@ private:
bool glow_high_quality = false;
RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGNESS_QUALITY_LOW;
- static uint64_t auto_exposure_counter;
-
- mutable RID_Owner<Environment> environment_owner;
+ mutable RID_Owner<RendererSceneEnvironmentRD, true> environment_owner;
/* CAMERA EFFECTS */
@@ -819,18 +360,16 @@ private:
float sss_scale = 0.05;
float sss_depth_scale = 0.01;
- mutable RID_Owner<CameraEffects> camera_effects_owner;
+ mutable RID_Owner<CameraEffects, true> camera_effects_owner;
/* RENDER BUFFERS */
- struct SDFGI;
+ ClusterBuilderSharedDataRD cluster_builder_shared;
+ ClusterBuilderRD *current_cluster_builder = nullptr;
+
struct VolumetricFog;
struct RenderBuffers {
- enum {
- MAX_GIPROBES = 8
- };
-
RenderBufferData *data = nullptr;
int width = 0, height = 0;
RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
@@ -845,9 +384,11 @@ private:
RID depth_texture; //main depth texture
RID gi_uniform_set;
- SDFGI *sdfgi = nullptr;
+ RendererSceneGIRD::SDFGI *sdfgi = nullptr;
VolumetricFog *volumetric_fog = nullptr;
+ ClusterBuilderRD *cluster_builder = nullptr;
+
//built-in textures used for ping pong image processing and blurring
struct Blur {
RID texture;
@@ -885,389 +426,14 @@ private:
RID blur_radius[2];
} ssr;
- RID giprobe_textures[MAX_GIPROBES];
- RID giprobe_buffer;
- };
-
- RID default_giprobe_buffer;
-
- /* SDFGI */
-
- struct SDFGI {
- enum {
- MAX_CASCADES = 8,
- CASCADE_SIZE = 128,
- PROBE_DIVISOR = 16,
- ANISOTROPY_SIZE = 6,
- MAX_DYNAMIC_LIGHTS = 128,
- MAX_STATIC_LIGHTS = 1024,
- LIGHTPROBE_OCT_SIZE = 6,
- SH_SIZE = 16
- };
-
- struct Cascade {
- struct UBO {
- float offset[3];
- float to_cell;
- int32_t probe_offset[3];
- uint32_t pad;
- };
-
- //cascade blocks are full-size for volume (128^3), half size for albedo/emission
- RID sdf_tex;
- RID light_tex;
- RID light_aniso_0_tex;
- RID light_aniso_1_tex;
-
- RID light_data;
- RID light_aniso_0_data;
- RID light_aniso_1_data;
-
- struct SolidCell { // this struct is unused, but remains as reference for size
- uint32_t position;
- uint32_t albedo;
- uint32_t static_light;
- uint32_t static_light_aniso;
- };
-
- RID solid_cell_dispatch_buffer; //buffer for indirect compute dispatch
- RID solid_cell_buffer;
-
- RID lightprobe_history_tex;
- RID lightprobe_average_tex;
-
- float cell_size;
- Vector3i position;
-
- static const Vector3i DIRTY_ALL;
- Vector3i dirty_regions; //(0,0,0 is not dirty, negative is refresh from the end, DIRTY_ALL is refresh all.
-
- RID sdf_store_uniform_set;
- RID sdf_direct_light_uniform_set;
- RID scroll_uniform_set;
- RID scroll_occlusion_uniform_set;
- RID integrate_uniform_set;
- RID lights_buffer;
- };
+ RID ambient_buffer;
+ RID reflection_buffer;
+ bool using_half_size_gi = false;
- //used for rendering (voxelization)
- RID render_albedo;
- RID render_emission;
- RID render_emission_aniso;
- RID render_occlusion[8];
- RID render_geom_facing;
-
- RID render_sdf[2];
- RID render_sdf_half[2];
-
- //used for ping pong processing in cascades
- RID sdf_initialize_uniform_set;
- RID sdf_initialize_half_uniform_set;
- RID jump_flood_uniform_set[2];
- RID jump_flood_half_uniform_set[2];
- RID sdf_upscale_uniform_set;
- int upscale_jfa_uniform_set_index;
- RID occlusion_uniform_set;
-
- uint32_t cascade_size = 128;
-
- LocalVector<Cascade> cascades;
-
- RID lightprobe_texture;
- RID lightprobe_data;
- RID occlusion_texture;
- RID occlusion_data;
- RID ambient_texture; //integrates with volumetric fog
-
- RID lightprobe_history_scroll; //used for scrolling lightprobes
- RID lightprobe_average_scroll; //used for scrolling lightprobes
-
- uint32_t history_size = 0;
- float solid_cell_ratio = 0;
- uint32_t solid_cell_count = 0;
-
- RS::EnvironmentSDFGICascades cascade_mode;
- float min_cell_size = 0;
- uint32_t probe_axis_count = 0; //amount of probes per axis, this is an odd number because it encloses endpoints
-
- RID debug_uniform_set;
- RID debug_probes_uniform_set;
- RID cascades_ubo;
-
- bool uses_occlusion = false;
- bool uses_multibounce = false;
- bool reads_sky = false;
- float energy = 1.0;
- float normal_bias = 1.1;
- float probe_bias = 1.1;
- RS::EnvironmentSDFGIYScale y_scale_mode = RS::ENV_SDFGI_Y_SCALE_DISABLED;
-
- float y_mult = 1.0;
-
- uint32_t render_pass = 0;
+ RendererSceneGIRD::RenderBuffersGI gi;
};
- RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16;
- RS::EnvironmentSDFGIFramesToConverge sdfgi_frames_to_converge = RS::ENV_SDFGI_CONVERGE_IN_10_FRAMES;
- float sdfgi_solid_cell_ratio = 0.25;
- Vector3 sdfgi_debug_probe_pos;
- Vector3 sdfgi_debug_probe_dir;
- bool sdfgi_debug_probe_enabled = false;
- Vector3i sdfgi_debug_probe_index;
-
- struct SDGIShader {
- enum SDFGIPreprocessShaderVersion {
- PRE_PROCESS_SCROLL,
- PRE_PROCESS_SCROLL_OCCLUSION,
- PRE_PROCESS_JUMP_FLOOD_INITIALIZE,
- PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF,
- PRE_PROCESS_JUMP_FLOOD,
- PRE_PROCESS_JUMP_FLOOD_OPTIMIZED,
- PRE_PROCESS_JUMP_FLOOD_UPSCALE,
- PRE_PROCESS_OCCLUSION,
- PRE_PROCESS_STORE,
- PRE_PROCESS_MAX
- };
-
- struct PreprocessPushConstant {
- int32_t scroll[3];
- int32_t grid_size;
-
- int32_t probe_offset[3];
- int32_t step_size;
-
- int32_t half_size;
- uint32_t occlusion_index;
- int32_t cascade;
- uint32_t pad;
- };
-
- SdfgiPreprocessShaderRD preprocess;
- RID preprocess_shader;
- RID preprocess_pipeline[PRE_PROCESS_MAX];
-
- struct DebugPushConstant {
- float grid_size[3];
- uint32_t max_cascades;
-
- int32_t screen_size[2];
- uint32_t use_occlusion;
- float y_mult;
-
- float cam_extent[3];
- uint32_t probe_axis_size;
-
- float cam_transform[16];
- };
-
- SdfgiDebugShaderRD debug;
- RID debug_shader;
- RID debug_shader_version;
- RID debug_pipeline;
-
- enum ProbeDebugMode {
- PROBE_DEBUG_PROBES,
- PROBE_DEBUG_VISIBILITY,
- PROBE_DEBUG_MAX
- };
-
- struct DebugProbesPushConstant {
- float projection[16];
-
- uint32_t band_power;
- uint32_t sections_in_band;
- uint32_t band_mask;
- float section_arc;
-
- float grid_size[3];
- uint32_t cascade;
-
- uint32_t pad;
- float y_mult;
- int32_t probe_debug_index;
- int32_t probe_axis_size;
- };
-
- SdfgiDebugProbesShaderRD debug_probes;
- RID debug_probes_shader;
- RID debug_probes_shader_version;
-
- PipelineCacheRD debug_probes_pipeline[PROBE_DEBUG_MAX];
-
- struct Light {
- float color[3];
- float energy;
-
- float direction[3];
- uint32_t has_shadow;
-
- float position[3];
- float attenuation;
-
- uint32_t type;
- float spot_angle;
- float spot_attenuation;
- float radius;
-
- float shadow_color[4];
- };
-
- struct DirectLightPushConstant {
- float grid_size[3];
- uint32_t max_cascades;
-
- uint32_t cascade;
- uint32_t light_count;
- uint32_t process_offset;
- uint32_t process_increment;
-
- int32_t probe_axis_size;
- uint32_t multibounce;
- float y_mult;
- uint32_t pad;
- };
-
- enum {
- DIRECT_LIGHT_MODE_STATIC,
- DIRECT_LIGHT_MODE_DYNAMIC,
- DIRECT_LIGHT_MODE_MAX
- };
- SdfgiDirectLightShaderRD direct_light;
- RID direct_light_shader;
- RID direct_light_pipeline[DIRECT_LIGHT_MODE_MAX];
-
- enum {
- INTEGRATE_MODE_PROCESS,
- INTEGRATE_MODE_STORE,
- INTEGRATE_MODE_SCROLL,
- INTEGRATE_MODE_SCROLL_STORE,
- INTEGRATE_MODE_MAX
- };
- struct IntegratePushConstant {
- enum {
- SKY_MODE_DISABLED,
- SKY_MODE_COLOR,
- SKY_MODE_SKY,
- };
-
- float grid_size[3];
- uint32_t max_cascades;
-
- uint32_t probe_axis_size;
- uint32_t cascade;
- uint32_t history_index;
- uint32_t history_size;
-
- uint32_t ray_count;
- float ray_bias;
- int32_t image_size[2];
-
- int32_t world_offset[3];
- uint32_t sky_mode;
-
- int32_t scroll[3];
- float sky_energy;
-
- float sky_color[3];
- float y_mult;
-
- uint32_t store_ambient_texture;
- uint32_t pad[3];
- };
-
- SdfgiIntegrateShaderRD integrate;
- RID integrate_shader;
- RID integrate_pipeline[INTEGRATE_MODE_MAX];
-
- RID integrate_default_sky_uniform_set;
-
- } sdfgi_shader;
-
- void _sdfgi_erase(RenderBuffers *rb);
- int _sdfgi_get_pending_region_data(RID p_render_buffers, int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const;
- void _sdfgi_update_cascades(RID p_render_buffers);
-
/* GI */
-
- struct GI {
- struct SDFGIData {
- float grid_size[3];
- uint32_t max_cascades;
-
- uint32_t use_occlusion;
- int32_t probe_axis_size;
- float probe_to_uvw;
- float normal_bias;
-
- float lightprobe_tex_pixel_size[3];
- float energy;
-
- float lightprobe_uv_offset[3];
- float y_mult;
-
- float occlusion_clamp[3];
- uint32_t pad3;
-
- float occlusion_renormalize[3];
- uint32_t pad4;
-
- float cascade_probe_size[3];
- uint32_t pad5;
-
- struct ProbeCascadeData {
- float position[3]; //offset of (0,0,0) in world coordinates
- float to_probe; // 1/bounds * grid_size
- int32_t probe_world_offset[3];
- float to_cell; // 1/bounds * grid_size
- };
-
- ProbeCascadeData cascades[SDFGI::MAX_CASCADES];
- };
-
- struct GIProbeData {
- float xform[16];
- float bounds[3];
- float dynamic_range;
-
- float bias;
- float normal_bias;
- uint32_t blend_ambient;
- uint32_t texture_slot;
-
- float anisotropy_strength;
- float ao;
- float ao_size;
- uint32_t mipmaps;
- };
-
- struct PushConstant {
- int32_t screen_size[2];
- float z_near;
- float z_far;
-
- float proj_info[4];
-
- uint32_t max_giprobes;
- uint32_t high_quality_vct;
- uint32_t use_sdfgi;
- uint32_t orthogonal;
-
- float ao_color[3];
- uint32_t pad;
-
- float cam_rotation[12];
- };
-
- RID sdfgi_ubo;
- enum {
- MODE_MAX = 1
- };
-
- GiShaderRD shader;
- RID shader_version;
- RID pipelines[MODE_MAX];
- } gi;
-
bool screen_space_roughness_limiter = false;
float screen_space_roughness_limiter_amount = 0.25;
float screen_space_roughness_limiter_limit = 0.18;
@@ -1280,21 +446,29 @@ private:
void _render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas);
void _render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection);
- void _sdfgi_debug_draw(RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform);
/* Cluster */
struct Cluster {
/* Scene State UBO */
- struct ReflectionData { //should always be 128 bytes
+ enum {
+ REFLECTION_AMBIENT_DISABLED = 0,
+ REFLECTION_AMBIENT_ENVIRONMENT = 1,
+ REFLECTION_AMBIENT_COLOR = 2,
+ };
+
+ struct ReflectionData {
float box_extents[3];
float index;
float box_offset[3];
uint32_t mask;
- float params[4]; // intensity, 0, interior , boxproject
float ambient[3]; // ambient color,
+ float intensity;
+ bool exterior;
+ bool box_project;
uint32_t ambient_mode;
+ uint32_t pad;
float local_matrix[16]; // up to here for spot and omni, rest is for directional
};
@@ -1303,10 +477,15 @@ private:
float inv_radius;
float direction[3];
float size;
- uint16_t attenuation_energy[2]; //16 bits attenuation, then energy
- uint8_t color_specular[4]; //rgb color, a specular (8 bit unorm)
- uint16_t cone_attenuation_angle[2]; // attenuation and angle, (16bit float)
- uint8_t shadow_color_enabled[4]; //shadow rgb color, a>0.5 enabled (8bit unorm)
+
+ float color[3];
+ float attenuation;
+
+ float inv_spot_attenuation;
+ float cos_spot_angle;
+ float specular_amount;
+ uint32_t shadow_enabled;
+
float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv
float shadow_matrix[16];
float shadow_bias;
@@ -1370,31 +549,85 @@ private:
float normal_fade;
};
+ template <class T>
+ struct InstanceSort {
+ float depth;
+ T *instance;
+ bool operator<(const InstanceSort &p_sort) const {
+ return depth < p_sort.depth;
+ }
+ };
+
ReflectionData *reflections;
+ InstanceSort<ReflectionProbeInstance> *reflection_sort;
uint32_t max_reflections;
RID reflection_buffer;
uint32_t max_reflection_probes_per_instance;
+ uint32_t reflection_count = 0;
DecalData *decals;
+ InstanceSort<DecalInstance> *decal_sort;
uint32_t max_decals;
RID decal_buffer;
+ uint32_t decal_count;
+
+ LightData *omni_lights;
+ LightData *spot_lights;
- LightData *lights;
+ InstanceSort<LightInstance> *omni_light_sort;
+ InstanceSort<LightInstance> *spot_light_sort;
uint32_t max_lights;
- RID light_buffer;
- RID *lights_instances;
- Rect2i *lights_shadow_rect_cache;
- uint32_t lights_shadow_rect_cache_count = 0;
+ RID omni_light_buffer;
+ RID spot_light_buffer;
+ uint32_t omni_light_count = 0;
+ uint32_t spot_light_count = 0;
DirectionalLightData *directional_lights;
uint32_t max_directional_lights;
RID directional_light_buffer;
- LightClusterBuilder builder;
-
} cluster;
+ struct RenderState {
+ RID render_buffers;
+ Transform cam_transform;
+ CameraMatrix cam_projection;
+ bool cam_ortogonal = false;
+ const PagedArray<GeometryInstance *> *instances = nullptr;
+ const PagedArray<RID> *lights = nullptr;
+ const PagedArray<RID> *reflection_probes = nullptr;
+ const PagedArray<RID> *gi_probes = nullptr;
+ const PagedArray<RID> *decals = nullptr;
+ const PagedArray<RID> *lightmaps = nullptr;
+ RID environment;
+ RID camera_effects;
+ RID shadow_atlas;
+ RID reflection_atlas;
+ RID reflection_probe;
+ int reflection_probe_pass = 0;
+ float screen_lod_threshold = 0.0;
+
+ const RenderShadowData *render_shadows = nullptr;
+ int render_shadow_count = 0;
+ const RenderSDFGIData *render_sdfgi_regions = nullptr;
+ int render_sdfgi_region_count = 0;
+ const RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
+
+ uint32_t directional_light_count = 0;
+ uint32_t gi_probe_count = 0;
+
+ LocalVector<int> cube_shadows;
+ LocalVector<int> shadows;
+ LocalVector<int> directional_shadows;
+
+ bool depth_prepass_used;
+ } render_state;
+
struct VolumetricFog {
+ enum {
+ MAX_TEMPORAL_FRAMES = 16
+ };
+
uint32_t width = 0;
uint32_t height = 0;
uint32_t depth = 0;
@@ -1403,6 +636,8 @@ private:
float spread;
RID light_density_map;
+ RID prev_light_density_map;
+
RID fog_map;
RID uniform_set;
RID uniform_set2;
@@ -1410,6 +645,8 @@ private:
RID sky_uniform_set;
int last_shadow_filter = -1;
+
+ Transform prev_cam_transform;
};
enum {
@@ -1421,7 +658,7 @@ private:
};
struct VolumetricFogShader {
- struct PushConstant {
+ struct ParamsUBO {
float fog_frustum_size_begin[2];
float fog_frustum_size_end[2];
@@ -1439,13 +676,24 @@ private:
float detail_spread;
float gi_inject;
uint32_t max_gi_probes;
- uint32_t pad;
+ uint32_t cluster_type_size;
+
+ float screen_size[2];
+ uint32_t cluster_shift;
+ uint32_t cluster_width;
+
+ uint32_t max_cluster_element_count_div_32;
+ uint32_t use_temporal_reprojection;
+ uint32_t temporal_frame;
+ float temporal_blend;
float cam_rotation[12];
+ float to_prev_view[16];
};
VolumetricFogShaderRD shader;
+ RID params_ubo;
RID shader_version;
RID pipelines[VOLUMETRIC_FOG_SHADER_MAX];
@@ -1453,9 +701,7 @@ private:
uint32_t volumetric_fog_depth = 128;
uint32_t volumetric_fog_size = 128;
- bool volumetric_fog_filter_active = false;
- uint32_t volumetric_fog_directional_shadow_shrink = 512;
- uint32_t volumetric_fog_positional_shadow_shrink = 512;
+ bool volumetric_fog_filter_active = true;
void _volumetric_fog_erase(RenderBuffers *rb);
void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count);
@@ -1465,18 +711,26 @@ private:
uint64_t scene_pass = 0;
uint64_t shadow_atlas_realloc_tolerance_msec = 500;
+ /* !BAS! is this used anywhere?
struct SDFGICosineNeighbour {
uint32_t neighbour;
float weight;
};
+ */
+ uint32_t max_cluster_elements = 512;
bool low_end = false;
+ void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true);
+
public:
+ virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance) = 0;
+ virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0;
+
/* SHADOW ATLAS API */
RID shadow_atlas_create();
- void shadow_atlas_set_size(RID p_atlas, int p_size);
+ void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false);
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
_FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) {
@@ -1497,7 +751,7 @@ public:
return Size2(atlas->size, atlas->size);
}
- void directional_shadow_atlas_set_size(int p_size);
+ void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false);
int get_directional_light_shadow_size(RID p_light_intance);
void set_directional_shadow_count(int p_count);
@@ -1511,28 +765,26 @@ public:
/* SDFGI UPDATE */
- int sdfgi_get_lightprobe_octahedron_size() const { return SDFGI::LIGHTPROBE_OCT_SIZE; }
virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position);
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const;
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const;
virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const;
- virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const PagedArray<RID> &p_directional_light_instances, const RID *p_positional_light_instances, uint32_t p_positional_light_count);
RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; }
+
/* SKY API */
- RID sky_create();
+ virtual RID sky_allocate();
+ virtual void sky_initialize(RID p_rid);
+
void sky_set_radiance_size(RID p_sky, int p_radiance_size);
void sky_set_mode(RID p_sky, RS::SkyMode p_mode);
void sky_set_material(RID p_sky, RID p_material);
Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size);
- RID sky_get_radiance_texture_rd(RID p_sky) const;
- RID sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const;
- RID sky_get_material(RID p_sky) const;
-
/* ENVIRONMENT API */
- RID environment_create();
+ virtual RID environment_allocate();
+ virtual void environment_initialize(RID p_rid);
void environment_set_background(RID p_env, RS::EnvironmentBG p_bg);
void environment_set_sky(RID p_env, RID p_sky);
@@ -1573,12 +825,10 @@ public:
float environment_get_fog_height_density(RID p_env) const;
float environment_get_fog_aerial_perspective(RID p_env) const;
- void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter);
+ void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount);
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth);
virtual void environment_set_volumetric_fog_filter_active(bool p_enable);
- virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size);
- virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size);
void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance);
void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect);
@@ -1589,9 +839,10 @@ public:
bool environment_is_ssr_enabled(RID p_env) const;
bool environment_is_sdfgi_enabled(RID p_env) const;
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias);
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias);
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count);
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames);
+ virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update);
void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality);
RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const;
@@ -1601,7 +852,8 @@ public:
virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size);
- virtual RID camera_effects_create();
+ virtual RID camera_effects_allocate();
+ virtual void camera_effects_initialize(RID p_rid);
virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter);
virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape);
@@ -1822,64 +1074,41 @@ public:
return decal->transform;
}
- RID gi_probe_instance_create(RID p_base);
- void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
- bool gi_probe_needs_update(RID p_probe) const;
- void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects);
-
- void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi_probe_quality = p_quality; }
-
- _FORCE_INLINE_ uint32_t gi_probe_instance_get_slot(RID p_probe) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
- return gi_probe->slot;
- }
- _FORCE_INLINE_ RID gi_probe_instance_get_base_probe(RID p_probe) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
- return gi_probe->probe;
- }
- _FORCE_INLINE_ Transform gi_probe_instance_get_transform_to_cell(RID p_probe) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
- return storage->gi_probe_get_to_cell_xform(gi_probe->probe) * gi_probe->transform.affine_inverse();
+ virtual RID lightmap_instance_create(RID p_lightmap);
+ virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform);
+ _FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) {
+ return lightmap_instance_owner.getornull(p_lightmap_instance) != nullptr;
}
- _FORCE_INLINE_ RID gi_probe_instance_get_texture(RID p_probe) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
- return gi_probe->texture;
+ _FORCE_INLINE_ RID lightmap_instance_get_lightmap(RID p_lightmap_instance) {
+ LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
+ return li->lightmap;
}
-
- _FORCE_INLINE_ void gi_probe_instance_set_render_index(RID p_instance, uint32_t p_render_index) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!gi_probe);
- gi_probe->render_index = p_render_index;
+ _FORCE_INLINE_ Transform lightmap_instance_get_transform(RID p_lightmap_instance) {
+ LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
+ return li->transform;
}
- _FORCE_INLINE_ uint32_t gi_probe_instance_get_render_index(RID p_instance) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_instance);
- ERR_FAIL_COND_V(!gi_probe, 0);
+ /* gi light probes */
- return gi_probe->render_index;
- }
- /*
- _FORCE_INLINE_ void gi_probe_instance_set_render_pass(RID p_instance, uint32_t p_render_pass) {
- GIProbeInstance *g_probe = gi_probe_instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!g_probe);
- g_probe->last_pass = p_render_pass;
- }
+ RID gi_probe_instance_create(RID p_base);
+ void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
+ bool gi_probe_needs_update(RID p_probe) const;
+ void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects);
+ void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi.gi_probe_quality = p_quality; }
- _FORCE_INLINE_ uint32_t gi_probe_instance_get_render_pass(RID p_instance) {
- GIProbeInstance *g_probe = gi_probe_instance_owner.getornull(p_instance);
- ERR_FAIL_COND_V(!g_probe, 0);
+ /* render buffers */
- return g_probe->last_pass;
- }
-*/
RID render_buffers_create();
void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding);
+ void gi_set_use_half_resolution(bool p_enable);
RID render_buffers_get_ao_texture(RID p_render_buffers);
RID render_buffers_get_back_buffer_texture(RID p_render_buffers);
RID render_buffers_get_gi_probe_buffer(RID p_render_buffers);
RID render_buffers_get_default_gi_probe_buffer();
+ RID render_buffers_get_gi_ambient_texture(RID p_render_buffers);
+ RID render_buffers_get_gi_reflection_texture(RID p_render_buffers);
uint32_t render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const;
bool render_buffers_is_sdfgi_enabled(RID p_render_buffers) const;
@@ -1900,16 +1129,11 @@ public:
float render_buffers_get_volumetric_fog_end(RID p_render_buffers);
float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers);
- void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
-
- void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0);
-
- void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
+ void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr);
- void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances);
- void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result);
+ void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
- void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances);
+ void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances);
virtual void set_scene_pass(uint64_t p_pass) {
scene_pass = p_pass;
@@ -1958,12 +1182,11 @@ public:
return debug_draw;
}
- virtual void set_time(double p_time, double p_step);
+ void set_time(double p_time, double p_step);
- RID get_cluster_builder_texture();
- RID get_cluster_builder_indices_buffer();
RID get_reflection_probe_buffer();
- RID get_positional_light_buffer();
+ RID get_omni_light_buffer();
+ RID get_spot_light_buffer();
RID get_directional_light_buffer();
RID get_decal_buffer();
int get_max_directional_lights() const;
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
new file mode 100644
index 0000000000..769335ac16
--- /dev/null
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -0,0 +1,1491 @@
+/*************************************************************************/
+/* renderer_scene_sky_rd.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "renderer_scene_sky_rd.h"
+#include "core/config/project_settings.h"
+#include "renderer_scene_render_rd.h"
+#include "servers/rendering/rendering_server_default.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// SKY SHADER
+
+void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
+ //compile
+
+ code = p_code;
+ valid = false;
+ ubo_size = 0;
+ uniforms.clear();
+
+ if (code == String()) {
+ return; //just invalid, but no error
+ }
+
+ ShaderCompilerRD::GeneratedCode gen_code;
+ ShaderCompilerRD::IdentifierActions actions;
+
+ uses_time = false;
+ uses_half_res = false;
+ uses_quarter_res = false;
+ uses_position = false;
+ uses_light = false;
+
+ actions.render_mode_flags["use_half_res_pass"] = &uses_half_res;
+ actions.render_mode_flags["use_quarter_res_pass"] = &uses_quarter_res;
+
+ actions.usage_flag_pointers["TIME"] = &uses_time;
+ actions.usage_flag_pointers["POSITION"] = &uses_position;
+ actions.usage_flag_pointers["LIGHT0_ENABLED"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_ENERGY"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_DIRECTION"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT0_SIZE"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_ENABLED"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_ENERGY"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_DIRECTION"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT1_SIZE"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_ENABLED"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_ENERGY"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_DIRECTION"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT2_SIZE"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_ENABLED"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_ENERGY"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_DIRECTION"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_COLOR"] = &uses_light;
+ actions.usage_flag_pointers["LIGHT3_SIZE"] = &uses_light;
+
+ actions.uniforms = &uniforms;
+
+ // !BAS! Contemplate making `SkyShader sky` accessible from this struct or even part of this struct.
+ RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
+
+ Error err = scene_singleton->sky.sky_shader.compiler.compile(RS::SHADER_SKY, code, &actions, path, gen_code);
+
+ ERR_FAIL_COND(err != OK);
+
+ if (version.is_null()) {
+ version = scene_singleton->sky.sky_shader.shader.version_create();
+ }
+
+#if 0
+ print_line("**compiling shader:");
+ print_line("**defines:\n");
+ for (int i = 0; i < gen_code.defines.size(); i++) {
+ print_line(gen_code.defines[i]);
+ }
+ print_line("\n**uniforms:\n" + gen_code.uniforms);
+ // print_line("\n**vertex_globals:\n" + gen_code.vertex_global);
+ // print_line("\n**vertex_code:\n" + gen_code.vertex);
+ print_line("\n**fragment_globals:\n" + gen_code.fragment_global);
+ print_line("\n**fragment_code:\n" + gen_code.fragment);
+ print_line("\n**light_code:\n" + gen_code.light);
+#endif
+
+ scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines);
+ ERR_FAIL_COND(!scene_singleton->sky.sky_shader.shader.version_is_valid(version));
+
+ ubo_size = gen_code.uniform_total_size;
+ ubo_offsets = gen_code.uniform_offsets;
+ texture_uniforms = gen_code.texture_uniforms;
+
+ //update pipelines
+
+ for (int i = 0; i < SKY_VERSION_MAX; i++) {
+ RD::PipelineDepthStencilState depth_stencil_state;
+ depth_stencil_state.enable_depth_test = true;
+ depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
+
+ RID shader_variant = scene_singleton->sky.sky_shader.shader.version_get_shader(version, i);
+ pipelines[i].setup(shader_variant, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0);
+ }
+
+ valid = true;
+}
+
+void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+ if (!p_texture.is_valid()) {
+ default_texture_params.erase(p_name);
+ } else {
+ default_texture_params[p_name] = p_texture;
+ }
+}
+
+void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+ Map<int, StringName> order;
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ if (E->get().texture_order >= 0) {
+ order[E->get().texture_order + 100000] = E->key();
+ } else {
+ order[E->get().order] = E->key();
+ }
+ }
+
+ for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
+ PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
+ pi.name = E->get();
+ p_param_list->push_back(pi);
+ }
+}
+
+void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ RendererStorage::InstanceShaderParam p;
+ p.info = ShaderLanguage::uniform_to_property_info(E->get());
+ p.info.name = E->key(); //supply name
+ p.index = E->get().instance_index;
+ p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint);
+ p_param_list->push_back(p);
+ }
+}
+
+bool RendererSceneSkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const {
+ if (!uniforms.has(p_param)) {
+ return false;
+ }
+
+ return uniforms[p_param].texture_order >= 0;
+}
+
+bool RendererSceneSkyRD::SkyShaderData::is_animated() const {
+ return false;
+}
+
+bool RendererSceneSkyRD::SkyShaderData::casts_shadows() const {
+ return false;
+}
+
+Variant RendererSceneSkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const {
+ if (uniforms.has(p_parameter)) {
+ ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
+ Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
+ return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
+ }
+ return Variant();
+}
+
+RS::ShaderNativeSourceCode RendererSceneSkyRD::SkyShaderData::get_native_source_code() const {
+ RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
+
+ return scene_singleton->sky.sky_shader.shader.version_get_native_source_code(version);
+}
+
+RendererSceneSkyRD::SkyShaderData::SkyShaderData() {
+ valid = false;
+}
+
+RendererSceneSkyRD::SkyShaderData::~SkyShaderData() {
+ RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
+ ERR_FAIL_COND(!scene_singleton);
+ //pipeline variants will clear themselves if shader is gone
+ if (version.is_valid()) {
+ scene_singleton->sky.sky_shader.shader.version_free(version);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Sky material
+
+void RendererSceneSkyRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
+
+ uniform_set_updated = true;
+
+ if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
+ p_uniform_dirty = true;
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ uniform_buffer = RID();
+ }
+
+ ubo_data.resize(shader_data->ubo_size);
+ if (ubo_data.size()) {
+ uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
+ memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
+ }
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ //check whether buffer changed
+ if (p_uniform_dirty && ubo_data.size()) {
+ update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
+ }
+
+ uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
+
+ if ((uint32_t)texture_cache.size() != tex_uniform_count) {
+ texture_cache.resize(tex_uniform_count);
+ p_textures_dirty = true;
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ if (p_textures_dirty && tex_uniform_count) {
+ update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
+ }
+
+ if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
+ // This material does not require an uniform set, so don't create it.
+ return;
+ }
+
+ if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ //no reason to update uniform set, only UBO (or nothing) was needed to update
+ return;
+ }
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ if (shader_data->ubo_size) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ const RID *textures = texture_cache.ptrw();
+ for (uint32_t i = 0; i < tex_uniform_count; i++) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1 + i;
+ u.ids.push_back(textures[i]);
+ uniforms.push_back(u);
+ }
+ }
+
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
+}
+
+RendererSceneSkyRD::SkyMaterialData::~SkyMaterialData() {
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ }
+
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ReflectionData
+
+void RendererSceneSkyRD::ReflectionData::clear_reflection_data() {
+ layers.clear();
+ radiance_base_cubemap = RID();
+ if (downsampled_radiance_cubemap.is_valid()) {
+ RD::get_singleton()->free(downsampled_radiance_cubemap);
+ }
+ downsampled_radiance_cubemap = RID();
+ downsampled_layer.mipmaps.clear();
+ coefficient_buffer = RID();
+}
+
+void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers) {
+ //recreate radiance and all data
+
+ int mipmaps = p_mipmaps;
+ uint32_t w = p_size, h = p_size;
+
+ if (p_use_array) {
+ int num_layers = p_low_quality ? 8 : p_roughness_layers;
+
+ for (int i = 0; i < num_layers; i++) {
+ ReflectionData::Layer layer;
+ uint32_t mmw = w;
+ uint32_t mmh = h;
+ layer.mipmaps.resize(mipmaps);
+ layer.views.resize(mipmaps);
+ for (int j = 0; j < mipmaps; j++) {
+ ReflectionData::Layer::Mipmap &mm = layer.mipmaps.write[j];
+ mm.size.width = mmw;
+ mm.size.height = mmh;
+ for (int k = 0; k < 6; k++) {
+ mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6 + k, j);
+ Vector<RID> fbtex;
+ fbtex.push_back(mm.views[k]);
+ mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
+ }
+
+ layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6, j, RD::TEXTURE_SLICE_CUBEMAP);
+
+ mmw = MAX(1, mmw >> 1);
+ mmh = MAX(1, mmh >> 1);
+ }
+
+ layers.push_back(layer);
+ }
+
+ } else {
+ mipmaps = p_low_quality ? 8 : mipmaps;
+ //regular cubemap, lower quality (aliasing, less memory)
+ ReflectionData::Layer layer;
+ uint32_t mmw = w;
+ uint32_t mmh = h;
+ layer.mipmaps.resize(mipmaps);
+ layer.views.resize(mipmaps);
+ for (int j = 0; j < mipmaps; j++) {
+ ReflectionData::Layer::Mipmap &mm = layer.mipmaps.write[j];
+ mm.size.width = mmw;
+ mm.size.height = mmh;
+ for (int k = 0; k < 6; k++) {
+ mm.views[k] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + k, j);
+ Vector<RID> fbtex;
+ fbtex.push_back(mm.views[k]);
+ mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
+ }
+
+ layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, j, RD::TEXTURE_SLICE_CUBEMAP);
+
+ mmw = MAX(1, mmw >> 1);
+ mmh = MAX(1, mmh >> 1);
+ }
+
+ layers.push_back(layer);
+ }
+
+ radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, RD::TEXTURE_SLICE_CUBEMAP);
+
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.width = 64; // Always 64x64
+ tf.height = 64;
+ tf.texture_type = RD::TEXTURE_TYPE_CUBE;
+ tf.array_layers = 6;
+ tf.mipmaps = 7;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+
+ downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ {
+ uint32_t mmw = 64;
+ uint32_t mmh = 64;
+ downsampled_layer.mipmaps.resize(7);
+ for (int j = 0; j < downsampled_layer.mipmaps.size(); j++) {
+ ReflectionData::DownsampleLayer::Mipmap &mm = downsampled_layer.mipmaps.write[j];
+ mm.size.width = mmw;
+ mm.size.height = mmh;
+ mm.view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), downsampled_radiance_cubemap, 0, j, RD::TEXTURE_SLICE_CUBEMAP);
+
+ mmw = MAX(1, mmw >> 1);
+ mmh = MAX(1, mmh >> 1);
+ }
+ }
+}
+
+void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays) {
+ p_storage->get_effects()->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size);
+
+ for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
+ p_storage->get_effects()->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size);
+ }
+
+ Vector<RID> views;
+ if (p_use_arrays) {
+ for (int i = 1; i < layers.size(); i++) {
+ views.push_back(layers[i].views[0]);
+ }
+ } else {
+ for (int i = 1; i < layers[0].views.size(); i++) {
+ views.push_back(layers[0].views[i]);
+ }
+ }
+
+ p_storage->get_effects()->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays);
+}
+
+void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) {
+ if (p_use_arrays) {
+ //render directly to the layers
+ p_storage->get_effects()->cubemap_roughness(radiance_base_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x);
+ } else {
+ p_storage->get_effects()->cubemap_roughness(
+ layers[0].views[p_base_layer - 1],
+ layers[0].views[p_base_layer],
+ p_cube_side,
+ p_sky_ggx_samples_quality,
+ float(p_base_layer) / (layers[0].mipmaps.size() - 1.0),
+ layers[0].mipmaps[p_base_layer].size.x);
+ }
+}
+
+void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end) {
+ for (int i = p_start; i < p_end; i++) {
+ for (int j = 0; j < layers[i].views.size() - 1; j++) {
+ RID view = layers[i].views[j];
+ RID texture = layers[i].views[j + 1];
+ Size2i size = layers[i].mipmaps[j + 1].size;
+ p_storage->get_effects()->cubemap_downsample(view, texture, size);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RendererSceneSkyRD::Sky
+
+void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) {
+ if (radiance.is_valid()) {
+ RD::get_singleton()->free(radiance);
+ radiance = RID();
+ }
+ reflection.clear_reflection_data();
+
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ uniform_buffer = RID();
+ }
+
+ if (half_res_pass.is_valid()) {
+ RD::get_singleton()->free(half_res_pass);
+ half_res_pass = RID();
+ }
+
+ if (quarter_res_pass.is_valid()) {
+ RD::get_singleton()->free(quarter_res_pass);
+ quarter_res_pass = RID();
+ }
+
+ if (material.is_valid()) {
+ p_storage->free(material);
+ }
+}
+
+RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd) {
+ if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) {
+ return texture_uniform_sets[p_version];
+ }
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+ if (radiance.is_valid() && p_version <= SKY_TEXTURE_SET_QUARTER_RES) {
+ u.ids.push_back(radiance);
+ } else {
+ u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1; // half res
+ if (half_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) {
+ if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
+ u.ids.push_back(reflection.layers[0].views[1]);
+ } else {
+ u.ids.push_back(half_res_pass);
+ }
+ } else {
+ if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
+ u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ } else {
+ u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2; // quarter res
+ if (quarter_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) {
+ if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
+ u.ids.push_back(reflection.layers[0].views[2]);
+ } else {
+ u.ids.push_back(quarter_res_pass);
+ }
+ } else {
+ if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
+ u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ } else {
+ u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
+ }
+ }
+ uniforms.push_back(u);
+ }
+
+ texture_uniform_sets[p_version] = RD::get_singleton()->uniform_set_create(uniforms, p_default_shader_rd, SKY_SET_TEXTURES);
+ return texture_uniform_sets[p_version];
+}
+
+bool RendererSceneSkyRD::Sky::set_radiance_size(int p_radiance_size) {
+ ERR_FAIL_COND_V(p_radiance_size < 32 || p_radiance_size > 2048, false);
+ if (radiance_size == p_radiance_size) {
+ return false;
+ }
+ radiance_size = p_radiance_size;
+
+ if (mode == RS::SKY_MODE_REALTIME && radiance_size != 256) {
+ WARN_PRINT("Realtime Skies can only use a radiance size of 256. Radiance size will be set to 256 internally.");
+ radiance_size = 256;
+ }
+
+ if (radiance.is_valid()) {
+ RD::get_singleton()->free(radiance);
+ radiance = RID();
+ }
+ reflection.clear_reflection_data();
+
+ return true;
+}
+
+bool RendererSceneSkyRD::Sky::set_mode(RS::SkyMode p_mode) {
+ if (mode == p_mode) {
+ return false;
+ }
+
+ mode = p_mode;
+
+ if (mode == RS::SKY_MODE_REALTIME && radiance_size != 256) {
+ WARN_PRINT("Realtime Skies can only use a radiance size of 256. Radiance size will be set to 256 internally.");
+ set_radiance_size(256);
+ }
+
+ if (radiance.is_valid()) {
+ RD::get_singleton()->free(radiance);
+ radiance = RID();
+ }
+ reflection.clear_reflection_data();
+
+ return true;
+}
+
+bool RendererSceneSkyRD::Sky::set_material(RID p_material) {
+ if (material == p_material) {
+ return false;
+ }
+
+ material = p_material;
+ return true;
+}
+
+Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(RendererStorageRD *p_storage, float p_energy, int p_roughness_layers, const Size2i &p_size) {
+ if (radiance.is_valid()) {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+ tf.width = p_size.width;
+ tf.height = p_size.height;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+
+ RID rad_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ p_storage->get_effects()->copy_cubemap_to_panorama(radiance, rad_tex, p_size, p_roughness_layers, reflection.layers.size() > 1);
+ Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0);
+ RD::get_singleton()->free(rad_tex);
+
+ Ref<Image> img;
+ img.instance();
+ img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data);
+ for (int i = 0; i < p_size.width; i++) {
+ for (int j = 0; j < p_size.height; j++) {
+ Color c = img->get_pixel(i, j);
+ c.r *= p_energy;
+ c.g *= p_energy;
+ c.b *= p_energy;
+ img->set_pixel(i, j, c);
+ }
+ }
+ return img;
+ }
+
+ return Ref<Image>();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RendererSceneSkyRD
+
+RendererStorageRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_func() {
+ SkyShaderData *shader_data = memnew(SkyShaderData);
+ return shader_data;
+}
+
+RendererStorageRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_funcs() {
+ // !BAS! Why isn't _create_sky_shader_func not just static too?
+ return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_shader_func();
+};
+
+RendererStorageRD::MaterialData *RendererSceneSkyRD::_create_sky_material_func(SkyShaderData *p_shader) {
+ SkyMaterialData *material_data = memnew(SkyMaterialData);
+ material_data->shader_data = p_shader;
+ material_data->last_frame = false;
+ //update will happen later anyway so do nothing.
+ return material_data;
+}
+
+RendererStorageRD::MaterialData *RendererSceneSkyRD::_create_sky_material_funcs(RendererStorageRD::ShaderData *p_shader) {
+ // !BAS! same here, we could just make _create_sky_material_func static?
+ return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_material_func(static_cast<SkyShaderData *>(p_shader));
+};
+
+RendererSceneSkyRD::RendererSceneSkyRD() {
+ roughness_layers = GLOBAL_GET("rendering/reflections/sky_reflections/roughness_layers");
+ sky_ggx_samples_quality = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples");
+ sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections");
+}
+
+void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
+ storage = p_storage;
+
+ {
+ // Start with the directional lights for the sky
+ sky_scene_state.max_directional_lights = 4;
+ uint32_t directional_light_buffer_size = sky_scene_state.max_directional_lights * sizeof(SkyDirectionalLightData);
+ sky_scene_state.directional_lights = memnew_arr(SkyDirectionalLightData, sky_scene_state.max_directional_lights);
+ sky_scene_state.last_frame_directional_lights = memnew_arr(SkyDirectionalLightData, sky_scene_state.max_directional_lights);
+ sky_scene_state.last_frame_directional_light_count = sky_scene_state.max_directional_lights + 1;
+ sky_scene_state.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size);
+
+ String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_scene_state.max_directional_lights) + "\n";
+
+ // Initialize sky
+ Vector<String> sky_modes;
+ sky_modes.push_back(""); // Full size
+ sky_modes.push_back("\n#define USE_HALF_RES_PASS\n"); // Half Res
+ sky_modes.push_back("\n#define USE_QUARTER_RES_PASS\n"); // Quarter res
+ sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n"); // Cubemap
+ sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n#define USE_HALF_RES_PASS\n"); // Half Res Cubemap
+ sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n#define USE_QUARTER_RES_PASS\n"); // Quarter res Cubemap
+ sky_shader.shader.initialize(sky_modes, defines);
+ }
+
+ // register our shader funds
+ storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_shader_funcs);
+ storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
+
+ {
+ ShaderCompilerRD::DefaultIdentifierActions actions;
+
+ actions.renames["COLOR"] = "color";
+ actions.renames["ALPHA"] = "alpha";
+ actions.renames["EYEDIR"] = "cube_normal";
+ actions.renames["POSITION"] = "params.position_multiplier.xyz";
+ actions.renames["SKY_COORDS"] = "panorama_coords";
+ actions.renames["SCREEN_UV"] = "uv";
+ actions.renames["TIME"] = "params.time";
+ actions.renames["HALF_RES_COLOR"] = "half_res_color";
+ actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color";
+ actions.renames["RADIANCE"] = "radiance";
+ actions.renames["FOG"] = "custom_fog";
+ actions.renames["LIGHT0_ENABLED"] = "directional_lights.data[0].enabled";
+ actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction_energy.xyz";
+ actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].direction_energy.w";
+ actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color_size.xyz";
+ actions.renames["LIGHT0_SIZE"] = "directional_lights.data[0].color_size.w";
+ actions.renames["LIGHT1_ENABLED"] = "directional_lights.data[1].enabled";
+ actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction_energy.xyz";
+ actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].direction_energy.w";
+ actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color_size.xyz";
+ actions.renames["LIGHT1_SIZE"] = "directional_lights.data[1].color_size.w";
+ actions.renames["LIGHT2_ENABLED"] = "directional_lights.data[2].enabled";
+ actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction_energy.xyz";
+ actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].direction_energy.w";
+ actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color_size.xyz";
+ actions.renames["LIGHT2_SIZE"] = "directional_lights.data[2].color_size.w";
+ actions.renames["LIGHT3_ENABLED"] = "directional_lights.data[3].enabled";
+ actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction_energy.xyz";
+ actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].direction_energy.w";
+ actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color_size.xyz";
+ actions.renames["LIGHT3_SIZE"] = "directional_lights.data[3].color_size.w";
+ actions.renames["AT_CUBEMAP_PASS"] = "AT_CUBEMAP_PASS";
+ actions.renames["AT_HALF_RES_PASS"] = "AT_HALF_RES_PASS";
+ actions.renames["AT_QUARTER_RES_PASS"] = "AT_QUARTER_RES_PASS";
+ actions.custom_samplers["RADIANCE"] = "material_samplers[3]";
+ actions.usage_defines["HALF_RES_COLOR"] = "\n#define USES_HALF_RES_COLOR\n";
+ actions.usage_defines["QUARTER_RES_COLOR"] = "\n#define USES_QUARTER_RES_COLOR\n";
+ actions.render_mode_defines["disable_fog"] = "#define DISABLE_FOG\n";
+
+ actions.sampler_array_name = "material_samplers";
+ actions.base_texture_binding_index = 1;
+ actions.texture_layout_set = 1;
+ actions.base_uniform_string = "material.";
+ actions.base_varying_index = 10;
+
+ actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
+ actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+ actions.global_buffer_array_variable = "global_variables.data";
+
+ sky_shader.compiler.initialize(actions);
+ }
+
+ {
+ // default material and shader for sky shader
+ sky_shader.default_shader = storage->shader_allocate();
+ storage->shader_initialize(sky_shader.default_shader);
+
+ storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0); } \n");
+
+ sky_shader.default_material = storage->material_allocate();
+ storage->material_initialize(sky_shader.default_material);
+
+ storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
+
+ SkyMaterialData *md = (SkyMaterialData *)storage->material_get_data(sky_shader.default_material, RendererStorageRD::SHADER_TYPE_SKY);
+ sky_shader.default_shader_rd = sky_shader.shader.version_get_shader(md->shader_data->version, SKY_VERSION_BACKGROUND);
+
+ sky_scene_state.uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkySceneState::UBO));
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 0;
+ u.ids.resize(12);
+ RID *ids_ptr = u.ids.ptrw();
+ ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[3] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[4] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[5] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[6] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[7] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[8] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(storage->global_variables_get_storage_buffer());
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(sky_scene_state.uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.ids.push_back(sky_scene_state.directional_light_buffer);
+ uniforms.push_back(u);
+ }
+
+ sky_scene_state.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_UNIFORMS);
+ }
+
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 0;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
+ u.ids.push_back(vfog);
+ uniforms.push_back(u);
+ }
+
+ sky_scene_state.default_fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG);
+ }
+
+ {
+ // Need defaults for using fog with clear color
+ sky_scene_state.fog_shader = storage->shader_allocate();
+ storage->shader_initialize(sky_scene_state.fog_shader);
+
+ storage->shader_set_code(sky_scene_state.fog_shader, "shader_type sky; uniform vec4 clear_color; void fragment() { COLOR = clear_color.rgb; } \n");
+ sky_scene_state.fog_material = storage->material_allocate();
+ storage->material_initialize(sky_scene_state.fog_material);
+
+ storage->material_set_shader(sky_scene_state.fog_material, sky_scene_state.fog_shader);
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1;
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+ u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+ uniforms.push_back(u);
+ }
+
+ sky_scene_state.fog_only_texture_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_TEXTURES);
+ }
+}
+
+void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
+ ERR_FAIL_COND(!p_env); // I guess without an environment we also can't have a sky...
+
+ SkyMaterialData *material = nullptr;
+ Sky *sky = get_sky(p_env->sky);
+
+ RID sky_material;
+
+ SkyShaderData *shader_data = nullptr;
+
+ RS::EnvironmentBG background = p_env->background;
+
+ if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) {
+ // !BAS! Possibly silently fail here, we now get error spam when you select sky as the background but haven't setup the sky yet.
+ ERR_FAIL_COND(!sky);
+ sky_material = sky_get_material(p_env->sky);
+
+ if (sky_material.is_valid()) {
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
+ if (!material || !material->shader_data->valid) {
+ material = nullptr;
+ }
+ }
+
+ if (!material) {
+ sky_material = sky_shader.default_material;
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
+ }
+
+ ERR_FAIL_COND(!material);
+
+ shader_data = material->shader_data;
+
+ ERR_FAIL_COND(!shader_data);
+ }
+
+ if (sky) {
+ // Invalidate supbass buffers if screen size changes
+ if (sky->screen_size != p_screen_size) {
+ sky->screen_size = p_screen_size;
+ sky->screen_size.x = sky->screen_size.x < 4 ? 4 : sky->screen_size.x;
+ sky->screen_size.y = sky->screen_size.y < 4 ? 4 : sky->screen_size.y;
+ if (shader_data->uses_half_res) {
+ if (sky->half_res_pass.is_valid()) {
+ RD::get_singleton()->free(sky->half_res_pass);
+ sky->half_res_pass = RID();
+ }
+ invalidate_sky(sky);
+ }
+ if (shader_data->uses_quarter_res) {
+ if (sky->quarter_res_pass.is_valid()) {
+ RD::get_singleton()->free(sky->quarter_res_pass);
+ sky->quarter_res_pass = RID();
+ }
+ invalidate_sky(sky);
+ }
+ }
+
+ // Create new subpass buffers if necessary
+ if ((shader_data->uses_half_res && sky->half_res_pass.is_null()) ||
+ (shader_data->uses_quarter_res && sky->quarter_res_pass.is_null()) ||
+ sky->radiance.is_null()) {
+ invalidate_sky(sky);
+ update_dirty_skys();
+ }
+
+ if (shader_data->uses_time && p_scene_render->time - sky->prev_time > 0.00001) {
+ sky->prev_time = p_scene_render->time;
+ sky->reflection.dirty = true;
+ RenderingServerDefault::redraw_request();
+ }
+
+ if (material != sky->prev_material) {
+ sky->prev_material = material;
+ sky->reflection.dirty = true;
+ }
+
+ if (material->uniform_set_updated) {
+ material->uniform_set_updated = false;
+ sky->reflection.dirty = true;
+ }
+
+ if (!p_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) {
+ sky->prev_position = p_transform.origin;
+ sky->reflection.dirty = true;
+ }
+
+ if (shader_data->uses_light) {
+ // Check whether the directional_light_buffer changes
+ bool light_data_dirty = false;
+
+ if (sky_scene_state.ubo.directional_light_count != sky_scene_state.last_frame_directional_light_count) {
+ light_data_dirty = true;
+ for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) {
+ sky_scene_state.directional_lights[i].enabled = false;
+ }
+ }
+ if (!light_data_dirty) {
+ for (uint32_t i = 0; i < sky_scene_state.ubo.directional_light_count; i++) {
+ if (sky_scene_state.directional_lights[i].direction[0] != sky_scene_state.last_frame_directional_lights[i].direction[0] ||
+ sky_scene_state.directional_lights[i].direction[1] != sky_scene_state.last_frame_directional_lights[i].direction[1] ||
+ sky_scene_state.directional_lights[i].direction[2] != sky_scene_state.last_frame_directional_lights[i].direction[2] ||
+ sky_scene_state.directional_lights[i].energy != sky_scene_state.last_frame_directional_lights[i].energy ||
+ sky_scene_state.directional_lights[i].color[0] != sky_scene_state.last_frame_directional_lights[i].color[0] ||
+ sky_scene_state.directional_lights[i].color[1] != sky_scene_state.last_frame_directional_lights[i].color[1] ||
+ sky_scene_state.directional_lights[i].color[2] != sky_scene_state.last_frame_directional_lights[i].color[2] ||
+ sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled ||
+ sky_scene_state.directional_lights[i].size != sky_scene_state.last_frame_directional_lights[i].size) {
+ light_data_dirty = true;
+ break;
+ }
+ }
+ }
+
+ if (light_data_dirty) {
+ RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights);
+
+ SkyDirectionalLightData *temp = sky_scene_state.last_frame_directional_lights;
+ sky_scene_state.last_frame_directional_lights = sky_scene_state.directional_lights;
+ sky_scene_state.directional_lights = temp;
+ sky_scene_state.last_frame_directional_light_count = sky_scene_state.ubo.directional_light_count;
+ sky->reflection.dirty = true;
+ }
+ }
+ }
+
+ //setup fog variables
+ sky_scene_state.ubo.volumetric_fog_enabled = false;
+ if (p_render_buffers.is_valid()) {
+ if (p_scene_render->render_buffers_has_volumetric_fog(p_render_buffers)) {
+ sky_scene_state.ubo.volumetric_fog_enabled = true;
+
+ float fog_end = p_scene_render->render_buffers_get_volumetric_fog_end(p_render_buffers);
+ if (fog_end > 0.0) {
+ sky_scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end;
+ } else {
+ sky_scene_state.ubo.volumetric_fog_inv_length = 1.0;
+ }
+
+ float fog_detail_spread = p_scene_render->render_buffers_get_volumetric_fog_detail_spread(p_render_buffers); //reverse lookup
+ if (fog_detail_spread > 0.0) {
+ sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread;
+ } else {
+ sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0;
+ }
+ }
+
+ RID fog_uniform_set = p_scene_render->render_buffers_get_volumetric_fog_sky_uniform_set(p_render_buffers);
+
+ if (fog_uniform_set != RID()) {
+ sky_scene_state.fog_uniform_set = fog_uniform_set;
+ } else {
+ sky_scene_state.fog_uniform_set = sky_scene_state.default_fog_uniform_set;
+ }
+ }
+
+ sky_scene_state.ubo.z_far = p_projection.get_z_far();
+ sky_scene_state.ubo.fog_enabled = p_env->fog_enabled;
+ sky_scene_state.ubo.fog_density = p_env->fog_density;
+ sky_scene_state.ubo.fog_aerial_perspective = p_env->fog_aerial_perspective;
+ Color fog_color = p_env->fog_light_color.to_linear();
+ float fog_energy = p_env->fog_light_energy;
+ sky_scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
+ sky_scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;
+ sky_scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy;
+ sky_scene_state.ubo.fog_sun_scatter = p_env->fog_sun_scatter;
+
+ RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo);
+}
+
+void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform &p_transform, double p_time) {
+ ERR_FAIL_COND(!p_env);
+
+ Sky *sky = get_sky(p_env->sky);
+ ERR_FAIL_COND(!sky);
+
+ RID sky_material = sky_get_material(p_env->sky);
+
+ SkyMaterialData *material = nullptr;
+
+ if (sky_material.is_valid()) {
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
+ if (!material || !material->shader_data->valid) {
+ material = nullptr;
+ }
+ }
+
+ if (!material) {
+ sky_material = sky_shader.default_material;
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
+ }
+
+ ERR_FAIL_COND(!material);
+
+ SkyShaderData *shader_data = material->shader_data;
+
+ ERR_FAIL_COND(!shader_data);
+
+ float multiplier = p_env->bg_energy;
+
+ bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY;
+ RS::SkyMode sky_mode = sky->mode;
+
+ if (sky_mode == RS::SKY_MODE_AUTOMATIC) {
+ if (shader_data->uses_time || shader_data->uses_position) {
+ update_single_frame = true;
+ sky_mode = RS::SKY_MODE_REALTIME;
+ } else if (shader_data->uses_light || shader_data->ubo_size > 0) {
+ update_single_frame = false;
+ sky_mode = RS::SKY_MODE_INCREMENTAL;
+ } else {
+ update_single_frame = true;
+ sky_mode = RS::SKY_MODE_QUALITY;
+ }
+ }
+
+ if (sky->processing_layer == 0 && sky_mode == RS::SKY_MODE_INCREMENTAL) {
+ // On the first frame after creating sky, rebuild in single frame
+ update_single_frame = true;
+ sky_mode = RS::SKY_MODE_QUALITY;
+ }
+
+ int max_processing_layer = sky_use_cubemap_array ? sky->reflection.layers.size() : sky->reflection.layers[0].mipmaps.size();
+
+ // Update radiance cubemap
+ if (sky->reflection.dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) {
+ static const Vector3 view_normals[6] = {
+ Vector3(+1, 0, 0),
+ Vector3(-1, 0, 0),
+ Vector3(0, +1, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, +1),
+ Vector3(0, 0, -1)
+ };
+ static const Vector3 view_up[6] = {
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, +1),
+ Vector3(0, 0, -1),
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0)
+ };
+
+ CameraMatrix cm;
+ cm.set_perspective(90, 1, 0.01, 10.0);
+ CameraMatrix correction;
+ correction.set_depth_correction(true);
+ cm = correction * cm;
+
+ if (shader_data->uses_quarter_res) {
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES];
+
+ Vector<Color> clear_colors;
+ clear_colors.push_back(Color(0.0, 0.0, 0.0));
+ RD::DrawListID cubemap_draw_list;
+
+ for (int i = 0; i < 6; i++) {
+ Transform local_view;
+ local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
+ RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
+
+ cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ storage->get_effects()->render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
+ RD::get_singleton()->draw_list_end();
+ }
+ }
+
+ if (shader_data->uses_half_res) {
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_HALF_RES];
+
+ Vector<Color> clear_colors;
+ clear_colors.push_back(Color(0.0, 0.0, 0.0));
+ RD::DrawListID cubemap_draw_list;
+
+ for (int i = 0; i < 6; i++) {
+ Transform local_view;
+ local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
+ RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
+
+ cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ storage->get_effects()->render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
+ RD::get_singleton()->draw_list_end();
+ }
+ }
+
+ RD::DrawListID cubemap_draw_list;
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP];
+
+ for (int i = 0; i < 6; i++) {
+ Transform local_view;
+ local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
+ RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
+
+ cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ storage->get_effects()->render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
+ RD::get_singleton()->draw_list_end();
+ }
+
+ if (sky_mode == RS::SKY_MODE_REALTIME) {
+ sky->reflection.create_reflection_fast_filter(storage, sky_use_cubemap_array);
+ if (sky_use_cubemap_array) {
+ sky->reflection.update_reflection_mipmaps(storage, 0, sky->reflection.layers.size());
+ }
+ } else {
+ if (update_single_frame) {
+ for (int i = 1; i < max_processing_layer; i++) {
+ sky->reflection.create_reflection_importance_sample(storage, sky_use_cubemap_array, 10, i, sky_ggx_samples_quality);
+ }
+ if (sky_use_cubemap_array) {
+ sky->reflection.update_reflection_mipmaps(storage, 0, sky->reflection.layers.size());
+ }
+ } else {
+ if (sky_use_cubemap_array) {
+ // Multi-Frame so just update the first array level
+ sky->reflection.update_reflection_mipmaps(storage, 0, 1);
+ }
+ }
+ sky->processing_layer = 1;
+ }
+
+ sky->reflection.dirty = false;
+
+ } else {
+ if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {
+ sky->reflection.create_reflection_importance_sample(storage, sky_use_cubemap_array, 10, sky->processing_layer, sky_ggx_samples_quality);
+
+ if (sky_use_cubemap_array) {
+ sky->reflection.update_reflection_mipmaps(storage, sky->processing_layer, sky->processing_layer + 1);
+ }
+
+ sky->processing_layer++;
+ }
+ }
+}
+
+void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, const CameraMatrix &p_projection, const Transform &p_transform, double p_time) {
+ ERR_FAIL_COND(!p_env);
+
+ Sky *sky = get_sky(p_env->sky);
+ ERR_FAIL_COND(!sky);
+
+ SkyMaterialData *material = nullptr;
+ RID sky_material;
+
+ RS::EnvironmentBG background = p_env->background;
+
+ if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) {
+ ERR_FAIL_COND(!sky);
+ sky_material = sky_get_material(p_env->sky);
+
+ if (sky_material.is_valid()) {
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
+ if (!material || !material->shader_data->valid) {
+ material = nullptr;
+ }
+ }
+
+ if (!material) {
+ sky_material = sky_shader.default_material;
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
+ }
+ }
+
+ if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
+ sky_material = sky_scene_state.fog_material;
+ material = (SkyMaterialData *)storage->material_get_data(sky_material, RendererStorageRD::SHADER_TYPE_SKY);
+ }
+
+ ERR_FAIL_COND(!material);
+
+ SkyShaderData *shader_data = material->shader_data;
+
+ ERR_FAIL_COND(!shader_data);
+
+ Basis sky_transform = p_env->sky_orientation;
+ sky_transform.invert();
+
+ float multiplier = p_env->bg_energy;
+ float custom_fov = p_env->sky_custom_fov;
+ // Camera
+ CameraMatrix camera;
+
+ if (custom_fov) {
+ float near_plane = p_projection.get_z_near();
+ float far_plane = p_projection.get_z_far();
+ float aspect = p_projection.get_aspect();
+
+ camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
+
+ } else {
+ camera = p_projection;
+ }
+
+ sky_transform = p_transform.basis * sky_transform;
+
+ if (shader_data->uses_quarter_res) {
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_QUARTER_RES];
+
+ RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
+
+ Vector<Color> clear_colors;
+ clear_colors.push_back(Color(0.0, 0.0, 0.0));
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
+ storage->get_effects()->render_sky(draw_list, p_time, sky->quarter_res_framebuffer, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
+ RD::get_singleton()->draw_list_end();
+ }
+
+ if (shader_data->uses_half_res) {
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_HALF_RES];
+
+ RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
+
+ Vector<Color> clear_colors;
+ clear_colors.push_back(Color(0.0, 0.0, 0.0));
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
+ storage->get_effects()->render_sky(draw_list, p_time, sky->half_res_framebuffer, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
+ RD::get_singleton()->draw_list_end();
+ }
+
+ PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_BACKGROUND];
+
+ RID texture_uniform_set;
+ if (sky) {
+ texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
+ } else {
+ texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
+ }
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
+ storage->get_effects()->render_sky(draw_list, p_time, p_fb, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
+ RD::get_singleton()->draw_list_end();
+}
+
+void RendererSceneSkyRD::invalidate_sky(Sky *p_sky) {
+ if (!p_sky->dirty) {
+ p_sky->dirty = true;
+ p_sky->dirty_list = dirty_sky_list;
+ dirty_sky_list = p_sky;
+ }
+}
+
+void RendererSceneSkyRD::update_dirty_skys() {
+ Sky *sky = dirty_sky_list;
+
+ while (sky) {
+ bool texture_set_dirty = false;
+ //update sky configuration if texture is missing
+
+ if (sky->radiance.is_null()) {
+ int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1;
+
+ uint32_t w = sky->radiance_size, h = sky->radiance_size;
+ int layers = roughness_layers;
+ if (sky->mode == RS::SKY_MODE_REALTIME) {
+ layers = 8;
+ if (roughness_layers != 8) {
+ WARN_PRINT("When using REALTIME skies, roughness_layers should be set to 8 in the project settings for best quality reflections");
+ }
+ }
+
+ if (sky_use_cubemap_array) {
+ //array (higher quality, 6 times more memory)
+ RD::TextureFormat tf;
+ tf.array_layers = layers * 6;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+ tf.mipmaps = mipmaps;
+ tf.width = w;
+ tf.height = h;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+
+ sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ sky->reflection.update_reflection_data(sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers);
+
+ } else {
+ //regular cubemap, lower quality (aliasing, less memory)
+ RD::TextureFormat tf;
+ tf.array_layers = 6;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.texture_type = RD::TEXTURE_TYPE_CUBE;
+ tf.mipmaps = MIN(mipmaps, layers);
+ tf.width = w;
+ tf.height = h;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+
+ sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ sky->reflection.update_reflection_data(sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers);
+ }
+ texture_set_dirty = true;
+ }
+
+ // Create subpass buffers if they haven't been created already
+ if (sky->half_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->half_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) {
+ RD::TextureFormat tformat;
+ tformat.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tformat.width = sky->screen_size.x / 2;
+ tformat.height = sky->screen_size.y / 2;
+ tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D;
+
+ sky->half_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+ Vector<RID> texs;
+ texs.push_back(sky->half_res_pass);
+ sky->half_res_framebuffer = RD::get_singleton()->framebuffer_create(texs);
+ texture_set_dirty = true;
+ }
+
+ if (sky->quarter_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->quarter_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) {
+ RD::TextureFormat tformat;
+ tformat.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tformat.width = sky->screen_size.x / 4;
+ tformat.height = sky->screen_size.y / 4;
+ tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ tformat.texture_type = RD::TEXTURE_TYPE_2D;
+
+ sky->quarter_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+ Vector<RID> texs;
+ texs.push_back(sky->quarter_res_pass);
+ sky->quarter_res_framebuffer = RD::get_singleton()->framebuffer_create(texs);
+ texture_set_dirty = true;
+ }
+
+ if (texture_set_dirty) {
+ for (int i = 0; i < SKY_TEXTURE_SET_MAX; i++) {
+ if (sky->texture_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(sky->texture_uniform_sets[i])) {
+ RD::get_singleton()->free(sky->texture_uniform_sets[i]);
+ sky->texture_uniform_sets[i] = RID();
+ }
+ }
+ }
+
+ sky->reflection.dirty = true;
+ sky->processing_layer = 0;
+
+ Sky *next = sky->dirty_list;
+ sky->dirty_list = nullptr;
+ sky->dirty = false;
+ sky = next;
+ }
+
+ dirty_sky_list = nullptr;
+}
+
+RID RendererSceneSkyRD::sky_get_material(RID p_sky) const {
+ Sky *sky = get_sky(p_sky);
+ ERR_FAIL_COND_V(!sky, RID());
+
+ return sky->material;
+}
+
+RID RendererSceneSkyRD::allocate_sky_rid() {
+ return sky_owner.allocate_rid();
+}
+
+void RendererSceneSkyRD::initialize_sky_rid(RID p_rid) {
+ sky_owner.initialize_rid(p_rid, Sky());
+}
+
+RendererSceneSkyRD::Sky *RendererSceneSkyRD::get_sky(RID p_sky) const {
+ return sky_owner.getornull(p_sky);
+}
+
+void RendererSceneSkyRD::free_sky(RID p_sky) {
+ Sky *sky = get_sky(p_sky);
+ ERR_FAIL_COND(!sky);
+
+ sky->free(storage);
+ sky_owner.free(p_sky);
+}
+
+void RendererSceneSkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) {
+ Sky *sky = get_sky(p_sky);
+ ERR_FAIL_COND(!sky);
+
+ if (sky->set_radiance_size(p_radiance_size)) {
+ invalidate_sky(sky);
+ }
+}
+
+void RendererSceneSkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {
+ Sky *sky = get_sky(p_sky);
+ ERR_FAIL_COND(!sky);
+
+ if (sky->set_mode(p_mode)) {
+ invalidate_sky(sky);
+ }
+}
+
+void RendererSceneSkyRD::sky_set_material(RID p_sky, RID p_material) {
+ Sky *sky = get_sky(p_sky);
+ ERR_FAIL_COND(!sky);
+
+ if (sky->set_material(p_material)) {
+ invalidate_sky(sky);
+ }
+}
+
+Ref<Image> RendererSceneSkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {
+ Sky *sky = get_sky(p_sky);
+ ERR_FAIL_COND_V(!sky, Ref<Image>());
+
+ update_dirty_skys();
+
+ return sky->bake_panorama(storage, p_energy, p_bake_irradiance ? roughness_layers : 0, p_size);
+}
+
+RID RendererSceneSkyRD::sky_get_radiance_texture_rd(RID p_sky) const {
+ Sky *sky = get_sky(p_sky);
+ ERR_FAIL_COND_V(!sky, RID());
+
+ return sky->radiance;
+}
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
new file mode 100644
index 0000000000..73390a586b
--- /dev/null
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
@@ -0,0 +1,292 @@
+/*************************************************************************/
+/* renderer_scene_sky_rd.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RENDERING_SERVER_SCENE_SKY_RD_H
+#define RENDERING_SERVER_SCENE_SKY_RD_H
+
+#include "core/templates/rid_owner.h"
+#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
+#include "servers/rendering/rendering_device.h"
+
+// Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
+class RendererSceneRenderRD;
+
+class RendererSceneSkyRD {
+private:
+ RendererStorageRD *storage;
+
+public:
+ enum SkySet {
+ SKY_SET_UNIFORMS,
+ SKY_SET_MATERIAL,
+ SKY_SET_TEXTURES,
+ SKY_SET_FOG,
+ SKY_SET_MAX
+ };
+
+ enum SkyTextureSetVersion {
+ SKY_TEXTURE_SET_BACKGROUND,
+ SKY_TEXTURE_SET_HALF_RES,
+ SKY_TEXTURE_SET_QUARTER_RES,
+ SKY_TEXTURE_SET_CUBEMAP,
+ SKY_TEXTURE_SET_CUBEMAP_HALF_RES,
+ SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES,
+ SKY_TEXTURE_SET_MAX
+ };
+
+ enum SkyVersion {
+ SKY_VERSION_BACKGROUND,
+ SKY_VERSION_HALF_RES,
+ SKY_VERSION_QUARTER_RES,
+ SKY_VERSION_CUBEMAP,
+ SKY_VERSION_CUBEMAP_HALF_RES,
+ SKY_VERSION_CUBEMAP_QUARTER_RES,
+ SKY_VERSION_MAX
+ };
+
+ // Skys need less info from Directional Lights than the normal shaders
+ struct SkyDirectionalLightData {
+ float direction[3];
+ float energy;
+ float color[3];
+ float size;
+ uint32_t enabled;
+ uint32_t pad[3];
+ };
+
+ struct SkySceneState {
+ struct UBO {
+ uint32_t volumetric_fog_enabled;
+ float volumetric_fog_inv_length;
+ float volumetric_fog_detail_spread;
+
+ float fog_aerial_perspective;
+
+ float fog_light_color[3];
+ float fog_sun_scatter;
+
+ uint32_t fog_enabled;
+ float fog_density;
+
+ float z_far;
+ uint32_t directional_light_count;
+ };
+
+ UBO ubo;
+
+ SkyDirectionalLightData *directional_lights;
+ SkyDirectionalLightData *last_frame_directional_lights;
+ uint32_t max_directional_lights;
+ uint32_t last_frame_directional_light_count;
+ RID directional_light_buffer;
+ RID uniform_set;
+ RID uniform_buffer;
+ RID fog_uniform_set;
+ RID default_fog_uniform_set;
+
+ RID fog_shader;
+ RID fog_material;
+ RID fog_only_texture_uniform_set;
+ } sky_scene_state;
+
+ struct ReflectionData {
+ struct Layer {
+ struct Mipmap {
+ RID framebuffers[6];
+ RID views[6];
+ Size2i size;
+ };
+ Vector<Mipmap> mipmaps; //per-face view
+ Vector<RID> views; // per-cubemap view
+ };
+
+ struct DownsampleLayer {
+ struct Mipmap {
+ RID view;
+ Size2i size;
+ };
+ Vector<Mipmap> mipmaps;
+ };
+
+ RID radiance_base_cubemap; //cubemap for first layer, first cubemap
+ RID downsampled_radiance_cubemap;
+ DownsampleLayer downsampled_layer;
+ RID coefficient_buffer;
+
+ bool dirty = true;
+
+ Vector<Layer> layers;
+
+ void clear_reflection_data();
+ void update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers);
+ void create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays);
+ void create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality);
+ void update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end);
+ };
+
+ struct SkyShaderData : public RendererStorageRD::ShaderData {
+ bool valid;
+ RID version;
+
+ PipelineCacheRD pipelines[SKY_VERSION_MAX];
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String path;
+ String code;
+ Map<StringName, RID> default_texture_params;
+
+ bool uses_time;
+ bool uses_position;
+ bool uses_half_res;
+ bool uses_quarter_res;
+ bool uses_light;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
+ virtual bool is_param_texture(const StringName &p_param) const;
+ virtual bool is_animated() const;
+ virtual bool casts_shadows() const;
+ virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ virtual RS::ShaderNativeSourceCode get_native_source_code() const;
+ SkyShaderData();
+ virtual ~SkyShaderData();
+ };
+
+ /* Sky shader */
+
+ struct SkyShader {
+ SkyShaderRD shader;
+ ShaderCompilerRD compiler;
+
+ RID default_shader;
+ RID default_material;
+ RID default_shader_rd;
+ } sky_shader;
+
+ struct SkyMaterialData : public RendererStorageRD::MaterialData {
+ uint64_t last_frame;
+ SkyShaderData *shader_data;
+ RID uniform_buffer;
+ RID uniform_set;
+ Vector<RID> texture_cache;
+ Vector<uint8_t> ubo_data;
+ bool uniform_set_updated;
+
+ virtual void set_render_priority(int p_priority) {}
+ virtual void set_next_pass(RID p_pass) {}
+ virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual ~SkyMaterialData();
+ };
+
+ struct Sky {
+ RID radiance;
+ RID half_res_pass;
+ RID half_res_framebuffer;
+ RID quarter_res_pass;
+ RID quarter_res_framebuffer;
+ Size2i screen_size;
+
+ RID texture_uniform_sets[SKY_TEXTURE_SET_MAX];
+ RID uniform_set;
+
+ RID material;
+ RID uniform_buffer;
+
+ int radiance_size = 256;
+
+ RS::SkyMode mode = RS::SKY_MODE_AUTOMATIC;
+
+ ReflectionData reflection;
+ bool dirty = false;
+ int processing_layer = 0;
+ Sky *dirty_list = nullptr;
+
+ //State to track when radiance cubemap needs updating
+ SkyMaterialData *prev_material;
+ Vector3 prev_position;
+ float prev_time;
+
+ void free(RendererStorageRD *p_storage);
+
+ RID get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd);
+ bool set_radiance_size(int p_radiance_size);
+ bool set_mode(RS::SkyMode p_mode);
+ bool set_material(RID p_material);
+ Ref<Image> bake_panorama(RendererStorageRD *p_storage, float p_energy, int p_roughness_layers, const Size2i &p_size);
+ };
+
+ uint32_t sky_ggx_samples_quality;
+ bool sky_use_cubemap_array;
+ Sky *dirty_sky_list = nullptr;
+ mutable RID_Owner<Sky, true> sky_owner;
+ int roughness_layers;
+
+ RendererStorageRD::ShaderData *_create_sky_shader_func();
+ static RendererStorageRD::ShaderData *_create_sky_shader_funcs();
+
+ RendererStorageRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
+ static RendererStorageRD::MaterialData *_create_sky_material_funcs(RendererStorageRD::ShaderData *p_shader);
+
+ RendererSceneSkyRD();
+
+ void init(RendererStorageRD *p_storage);
+
+ void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
+ void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform &p_transform, double p_time);
+ void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, const CameraMatrix &p_projection, const Transform &p_transform, double p_time);
+
+ void invalidate_sky(Sky *p_sky);
+ void update_dirty_skys();
+
+ RID sky_get_material(RID p_sky) const;
+
+ RID allocate_sky_rid();
+ void initialize_sky_rid(RID p_rid);
+ Sky *get_sky(RID p_sky) const;
+ void free_sky(RID p_sky);
+ void sky_set_radiance_size(RID p_sky, int p_radiance_size);
+ void sky_set_mode(RID p_sky, RS::SkyMode p_mode);
+ void sky_set_material(RID p_sky, RID p_material);
+ Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size);
+
+ RID sky_get_radiance_texture_rd(RID p_sky) const;
+};
+
+#endif /* RENDERING_SERVER_SCENE_SKY_RD_H */
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 61b390b956..2a34049675 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,6 +36,10 @@
#include "renderer_compositor_rd.h"
#include "servers/rendering/shader_language.h"
+bool RendererStorageRD::can_create_resources_async() const {
+ return true;
+}
+
Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) {
Ref<Image> image = p_image->duplicate();
@@ -535,9 +539,13 @@ Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image
return image;
}
-RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) {
- ERR_FAIL_COND_V(p_image.is_null(), RID());
- ERR_FAIL_COND_V(p_image->empty(), RID());
+RID RendererStorageRD::texture_allocate() {
+ return texture_owner.allocate_rid();
+}
+
+void RendererStorageRD::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) {
+ ERR_FAIL_COND(p_image.is_null());
+ ERR_FAIL_COND(p_image->is_empty());
TextureToRDFormat ret_format;
Ref<Image> image = _validate_texture_format(p_image, ret_format);
@@ -585,13 +593,13 @@ RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) {
Vector<Vector<uint8_t>> data_slices;
data_slices.push_back(data);
texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices);
- ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID());
+ ERR_FAIL_COND(texture.rd_texture.is_null());
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
rd_view.format_override = texture.rd_format_srgb;
texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture);
if (texture.rd_texture_srgb.is_null()) {
RD::get_singleton()->free(texture.rd_texture);
- ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID());
+ ERR_FAIL_COND(texture.rd_texture_srgb.is_null());
}
}
@@ -602,14 +610,14 @@ RID RendererStorageRD::texture_2d_create(const Ref<Image> &p_image) {
texture.rd_view = rd_view;
texture.is_proxy = false;
- return texture_owner.make_rid(texture);
+ texture_owner.initialize_rid(p_texture, texture);
}
-RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
- ERR_FAIL_COND_V(p_layers.size() == 0, RID());
+void RendererStorageRD::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
+ ERR_FAIL_COND(p_layers.size() == 0);
- ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6, RID());
- ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0), RID());
+ ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6);
+ ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0));
TextureToRDFormat ret_format;
Vector<Ref<Image>> images;
@@ -620,7 +628,7 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay
Image::Format valid_format = Image::FORMAT_MAX;
for (int i = 0; i < p_layers.size(); i++) {
- ERR_FAIL_COND_V(p_layers[i]->empty(), RID());
+ ERR_FAIL_COND(p_layers[i]->is_empty());
if (i == 0) {
valid_width = p_layers[i]->get_width();
@@ -628,10 +636,10 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay
valid_format = p_layers[i]->get_format();
valid_mipmaps = p_layers[i]->has_mipmaps();
} else {
- ERR_FAIL_COND_V(p_layers[i]->get_width() != valid_width, RID());
- ERR_FAIL_COND_V(p_layers[i]->get_height() != valid_height, RID());
- ERR_FAIL_COND_V(p_layers[i]->get_format() != valid_format, RID());
- ERR_FAIL_COND_V(p_layers[i]->has_mipmaps() != valid_mipmaps, RID());
+ ERR_FAIL_COND(p_layers[i]->get_width() != valid_width);
+ ERR_FAIL_COND(p_layers[i]->get_height() != valid_height);
+ ERR_FAIL_COND(p_layers[i]->get_format() != valid_format);
+ ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps);
}
images.push_back(_validate_texture_format(p_layers[i], ret_format));
@@ -695,13 +703,13 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay
data_slices.push_back(data);
}
texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices);
- ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID());
+ ERR_FAIL_COND(texture.rd_texture.is_null());
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
rd_view.format_override = texture.rd_format_srgb;
texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture);
if (texture.rd_texture_srgb.is_null()) {
RD::get_singleton()->free(texture.rd_texture);
- ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID());
+ ERR_FAIL_COND(texture.rd_texture_srgb.is_null());
}
}
@@ -712,14 +720,14 @@ RID RendererStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_lay
texture.rd_view = rd_view;
texture.is_proxy = false;
- return texture_owner.make_rid(texture);
+ texture_owner.initialize_rid(p_texture, texture);
}
-RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
- ERR_FAIL_COND_V(p_data.size() == 0, RID());
+void RendererStorageRD::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
+ ERR_FAIL_COND(p_data.size() == 0);
Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
if (verr != Image::VALIDATE_3D_OK) {
- ERR_FAIL_V_MSG(RID(), Image::get_3d_image_validation_error_text(verr));
+ ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr));
}
TextureToRDFormat ret_format;
@@ -811,13 +819,13 @@ RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, in
data_slices.push_back(all_data); //one slice
texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices);
- ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID());
+ ERR_FAIL_COND(texture.rd_texture.is_null());
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
rd_view.format_override = texture.rd_format_srgb;
texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture);
if (texture.rd_texture_srgb.is_null()) {
RD::get_singleton()->free(texture.rd_texture);
- ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID());
+ ERR_FAIL_COND(texture.rd_texture_srgb.is_null());
}
}
@@ -828,12 +836,12 @@ RID RendererStorageRD::texture_3d_create(Image::Format p_format, int p_width, in
texture.rd_view = rd_view;
texture.is_proxy = false;
- return texture_owner.make_rid(texture);
+ texture_owner.initialize_rid(p_texture, texture);
}
-RID RendererStorageRD::texture_proxy_create(RID p_base) {
+void RendererStorageRD::texture_proxy_initialize(RID p_texture, RID p_base) {
Texture *tex = texture_owner.getornull(p_base);
- ERR_FAIL_COND_V(!tex, RID());
+ ERR_FAIL_COND(!tex);
Texture proxy_tex = *tex;
proxy_tex.rd_view.format_override = tex->rd_format;
@@ -847,15 +855,13 @@ RID RendererStorageRD::texture_proxy_create(RID p_base) {
proxy_tex.is_proxy = true;
proxy_tex.proxies.clear();
- RID rid = texture_owner.make_rid(proxy_tex);
+ texture_owner.initialize_rid(p_texture, proxy_tex);
- tex->proxies.push_back(rid);
-
- return rid;
+ tex->proxies.push_back(p_texture);
}
void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) {
- ERR_FAIL_COND(p_image.is_null() || p_image->empty());
+ ERR_FAIL_COND(p_image.is_null() || p_image->is_empty());
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
@@ -873,7 +879,7 @@ void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_im
TextureToRDFormat f;
Ref<Image> validated = _validate_texture_format(p_image, f);
- RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data(), !p_immediate);
+ RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data());
}
void RendererStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) {
@@ -918,7 +924,7 @@ void RendererStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>
}
}
- RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data, true);
+ RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data);
}
void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) {
@@ -961,7 +967,7 @@ void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) {
}
//these two APIs can be used together or in combination with the others.
-RID RendererStorageRD::texture_2d_placeholder_create() {
+void RendererStorageRD::texture_2d_placeholder_initialize(RID p_texture) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
@@ -974,10 +980,10 @@ RID RendererStorageRD::texture_2d_placeholder_create() {
}
}
- return texture_2d_create(image);
+ texture_2d_initialize(p_texture, image);
}
-RID RendererStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) {
+void RendererStorageRD::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
@@ -1000,10 +1006,10 @@ RID RendererStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredT
}
}
- return texture_2d_layered_create(images, p_layered_type);
+ texture_2d_layered_initialize(p_texture, images, p_layered_type);
}
-RID RendererStorageRD::texture_3d_placeholder_create() {
+void RendererStorageRD::texture_3d_placeholder_initialize(RID p_texture) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
@@ -1022,7 +1028,7 @@ RID RendererStorageRD::texture_3d_placeholder_create() {
images.push_back(image);
}
- return texture_3d_create(Image::FORMAT_RGBA8, 4, 4, 4, false, images);
+ texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, images);
}
Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const {
@@ -1039,7 +1045,7 @@ Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const {
Ref<Image> image;
image.instance();
image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
- ERR_FAIL_COND_V(image->empty(), Ref<Image>());
+ ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (tex->format != tex->validated_format) {
image->convert(tex->format);
}
@@ -1062,7 +1068,7 @@ Ref<Image> RendererStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) c
Ref<Image> image;
image.instance();
image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
- ERR_FAIL_COND_V(image->empty(), Ref<Image>());
+ ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (tex->format != tex->validated_format) {
image->convert(tex->format);
}
@@ -1090,7 +1096,7 @@ Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const {
Ref<Image> img;
img.instance();
img->create(bs.size.width, bs.size.height, false, tex->validated_format, sub_region);
- ERR_FAIL_COND_V(img->empty(), Vector<Ref<Image>>());
+ ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>());
if (tex->format != tex->validated_format) {
img->convert(tex->format);
}
@@ -1223,8 +1229,11 @@ RendererStorageRD::CanvasTexture::~CanvasTexture() {
clear_sets();
}
-RID RendererStorageRD::canvas_texture_create() {
- return canvas_texture_owner.make_rid(memnew(CanvasTexture));
+RID RendererStorageRD::canvas_texture_allocate() {
+ return canvas_texture_owner.allocate_rid();
+}
+void RendererStorageRD::canvas_texture_initialize(RID p_rid) {
+ canvas_texture_owner.initialize_rid(p_rid, memnew(CanvasTexture));
}
void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
@@ -1234,7 +1243,7 @@ void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::Can
ct->diffuse = p_texture;
} break;
case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
- ct->normalmap = p_texture;
+ ct->normal_map = p_texture;
} break;
case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
ct->specular = p_texture;
@@ -1316,7 +1325,7 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1;
- t = texture_owner.getornull(ct->normalmap);
+ t = texture_owner.getornull(ct->normal_map);
if (!t) {
u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL));
ct->use_normal_cache = false;
@@ -1365,12 +1374,15 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas
/* SHADER API */
-RID RendererStorageRD::shader_create() {
+RID RendererStorageRD::shader_allocate() {
+ return shader_owner.allocate_rid();
+}
+void RendererStorageRD::shader_initialize(RID p_rid) {
Shader shader;
shader.data = nullptr;
shader.type = SHADER_TYPE_MAX;
- return shader_owner.make_rid(shader);
+ shader_owner.initialize_rid(p_rid, shader);
}
void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) {
@@ -1438,7 +1450,7 @@ void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) {
for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
Material *material = E->get();
- material->instance_dependency.instance_notify_changed(false, true);
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
}
@@ -1499,9 +1511,21 @@ void RendererStorageRD::shader_set_data_request_function(ShaderType p_shader_typ
shader_data_request_func[p_shader_type] = p_function;
}
+RS::ShaderNativeSourceCode RendererStorageRD::shader_get_native_source_code(RID p_shader) const {
+ Shader *shader = shader_owner.getornull(p_shader);
+ ERR_FAIL_COND_V(!shader, RS::ShaderNativeSourceCode());
+ if (shader->data) {
+ return shader->data->get_native_source_code();
+ }
+ return RS::ShaderNativeSourceCode();
+}
+
/* COMMON MATERIAL API */
-RID RendererStorageRD::material_create() {
+RID RendererStorageRD::material_allocate() {
+ return material_owner.allocate_rid();
+}
+void RendererStorageRD::material_initialize(RID p_rid) {
Material material;
material.data = nullptr;
material.shader = nullptr;
@@ -1511,12 +1535,8 @@ RID RendererStorageRD::material_create() {
material.uniform_dirty = false;
material.texture_dirty = false;
material.priority = 0;
- RID id = material_owner.make_rid(material);
- {
- Material *material_ptr = material_owner.getornull(id);
- material_ptr->self = id;
- }
- return id;
+ material.self = p_rid;
+ material_owner.initialize_rid(p_rid, material);
}
void RendererStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) {
@@ -1547,7 +1567,8 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) {
}
if (p_shader.is_null()) {
- material->instance_dependency.instance_notify_changed(false, true);
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
+ material->shader_id = 0;
return;
}
@@ -1555,6 +1576,7 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) {
ERR_FAIL_COND(!shader);
material->shader = shader;
material->shader_type = shader->type;
+ material->shader_id = p_shader.get_local_index();
shader->owners.insert(material);
if (shader->type == SHADER_TYPE_MAX) {
@@ -1568,7 +1590,7 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) {
material->data->set_next_pass(material->next_pass);
material->data->set_render_priority(material->priority);
//updating happens later
- material->instance_dependency.instance_notify_changed(false, true);
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
@@ -1613,7 +1635,7 @@ void RendererStorageRD::material_set_next_pass(RID p_material, RID p_next_materi
material->data->set_next_pass(p_next_material);
}
- material->instance_dependency.instance_notify_changed(false, true);
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
}
void RendererStorageRD::material_set_render_priority(RID p_material, int priority) {
@@ -1663,10 +1685,10 @@ void RendererStorageRD::material_get_instance_shader_parameters(RID p_material,
}
}
-void RendererStorageRD::material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) {
+void RendererStorageRD::material_update_dependency(RID p_material, DependencyTracker *p_instance) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
- p_instance->update_dependency(&material->instance_dependency);
+ p_instance->update_dependency(&material->dependency);
if (material->next_pass.is_valid()) {
material_update_dependency(material->next_pass, p_instance);
}
@@ -2216,7 +2238,7 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
RendererStorageRD *singleton = (RendererStorageRD *)RendererStorage::base_singleton;
#ifdef TOOLS_ENABLED
Texture *roughness_detect_texture = nullptr;
- RS::TextureDetectRoughnessChannel roughness_channel = RS::TEXTURE_DETECT_ROUGNHESS_R;
+ RS::TextureDetectRoughnessChannel roughness_channel = RS::TEXTURE_DETECT_ROUGHNESS_R;
Texture *normal_detect_texture = nullptr;
#endif
@@ -2388,8 +2410,11 @@ void RendererStorageRD::_update_queued_materials() {
/* MESH API */
-RID RendererStorageRD::mesh_create() {
- return mesh_owner.make_rid(Mesh());
+RID RendererStorageRD::mesh_allocate() {
+ return mesh_owner.allocate_rid();
+}
+void RendererStorageRD::mesh_initialize(RID p_rid) {
+ mesh_owner.initialize_rid(p_rid, Mesh());
}
void RendererStorageRD::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) {
@@ -2596,7 +2621,13 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su
_mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1);
}
- mesh->instance_dependency.instance_notify_changed(true, true);
+ mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
+
+ for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) {
+ Mesh *shadow_owner = E->get();
+ shadow_owner->shadow_mesh = RID();
+ shadow_owner->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
+ }
mesh->material_cache.clear();
}
@@ -2638,7 +2669,7 @@ void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
mesh->surfaces[p_surface]->material = p_material;
- mesh->instance_dependency.instance_notify_changed(false, true);
+ mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
mesh->material_cache.clear();
}
@@ -2813,6 +2844,25 @@ AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
return aabb;
}
+void RendererStorageRD::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {
+ Mesh *mesh = mesh_owner.getornull(p_mesh);
+ ERR_FAIL_COND(!mesh);
+
+ Mesh *shadow_mesh = mesh_owner.getornull(mesh->shadow_mesh);
+ if (shadow_mesh) {
+ shadow_mesh->shadow_owners.erase(mesh);
+ }
+ mesh->shadow_mesh = p_shadow_mesh;
+
+ shadow_mesh = mesh_owner.getornull(mesh->shadow_mesh);
+
+ if (shadow_mesh) {
+ shadow_mesh->shadow_owners.insert(mesh);
+ }
+
+ mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
+}
+
void RendererStorageRD::mesh_clear(RID p_mesh) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
@@ -2858,8 +2908,14 @@ void RendererStorageRD::mesh_clear(RID p_mesh) {
MeshInstance *mi = E->get();
_mesh_instance_clear(mi);
}
- mesh->instance_dependency.instance_notify_changed(true, true);
mesh->has_bone_weights = false;
+ mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
+
+ for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) {
+ Mesh *shadow_owner = E->get();
+ shadow_owner->shadow_mesh = RID();
+ shadow_owner->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
+ }
}
bool RendererStorageRD::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) {
@@ -3002,7 +3058,7 @@ void RendererStorageRD::update_mesh_instances() {
MeshInstance *mi = dirty_mesh_instance_weights.first()->self();
if (mi->blend_weights_buffer.is_valid()) {
- RD::get_singleton()->buffer_update(mi->blend_weights_buffer, 0, mi->blend_weights.size() * sizeof(float), mi->blend_weights.ptr(), true);
+ RD::get_singleton()->buffer_update(mi->blend_weights_buffer, 0, mi->blend_weights.size() * sizeof(float), mi->blend_weights.ptr());
}
dirty_mesh_instance_weights.remove(&mi->weight_update_list);
mi->weights_dirty = false;
@@ -3056,7 +3112,7 @@ void RendererStorageRD::update_mesh_instances() {
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SkeletonShader::PushConstant));
//dispatch without barrier, so all is done at the same time
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.vertex_count, 1, 1, 64, 1, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.vertex_count, 1, 1);
}
mi->dirty = false;
@@ -3256,11 +3312,14 @@ void RendererStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Surf
////////////////// MULTIMESH
-RID RendererStorageRD::multimesh_create() {
- return multimesh_owner.make_rid(MultiMesh());
+RID RendererStorageRD::multimesh_allocate() {
+ return multimesh_owner.allocate_rid();
+}
+void RendererStorageRD::multimesh_initialize(RID p_rid) {
+ multimesh_owner.initialize_rid(p_rid, MultiMesh());
}
-void RendererStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
+void RendererStorageRD::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
@@ -3298,6 +3357,8 @@ void RendererStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS:
if (multimesh->instances) {
multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4);
}
+
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MULTIMESH);
}
int RendererStorageRD::multimesh_get_instance_count(RID p_multimesh) const {
@@ -3331,7 +3392,7 @@ void RendererStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
}
}
- multimesh->instance_dependency.instance_notify_changed(true, true);
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
}
#define MULTIMESH_DIRTY_REGION_SIZE 512
@@ -3668,7 +3729,7 @@ void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float
{
const float *r = p_buffer.ptr();
- RD::get_singleton()->buffer_update(multimesh->buffer, 0, p_buffer.size() * sizeof(float), r, false);
+ RD::get_singleton()->buffer_update(multimesh->buffer, 0, p_buffer.size() * sizeof(float), r);
multimesh->buffer_set = true;
}
@@ -3690,7 +3751,7 @@ void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float
const float *data = p_buffer.ptr();
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
- multimesh->instance_dependency.instance_notify_changed(true, false);
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
}
@@ -3731,6 +3792,8 @@ void RendererStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_v
}
multimesh->visible_instances = p_visible;
+
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
}
int RendererStorageRD::multimesh_get_visible_instances(RID p_multimesh) const {
@@ -3765,14 +3828,14 @@ void RendererStorageRD::_update_dirty_multimeshes() {
if (multimesh->data_cache_used_dirty_regions > 32 || multimesh->data_cache_used_dirty_regions > visible_region_count / 2) {
//if there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much
- RD::get_singleton()->buffer_update(multimesh->buffer, 0, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data, false);
+ RD::get_singleton()->buffer_update(multimesh->buffer, 0, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data);
} else {
//not that many regions? update them all
for (uint32_t i = 0; i < visible_region_count; i++) {
if (multimesh->data_cache_dirty_regions[i]) {
uint64_t offset = i * region_size;
uint64_t size = multimesh->stride_cache * multimesh->instances * sizeof(float);
- RD::get_singleton()->buffer_update(multimesh->buffer, offset, MIN(region_size, size - offset), &data[i * region_size], false);
+ RD::get_singleton()->buffer_update(multimesh->buffer, offset, MIN(region_size, size - offset), &data[i * region_size]);
}
}
}
@@ -3788,7 +3851,7 @@ void RendererStorageRD::_update_dirty_multimeshes() {
//aabb is dirty..
_multimesh_re_create_aabb(multimesh, data, visible_instances);
multimesh->aabb_dirty = false;
- multimesh->instance_dependency.instance_notify_changed(true, false);
+ multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
}
@@ -3803,8 +3866,11 @@ void RendererStorageRD::_update_dirty_multimeshes() {
/* PARTICLES */
-RID RendererStorageRD::particles_create() {
- return particles_owner.make_rid(Particles());
+RID RendererStorageRD::particles_allocate() {
+ return particles_owner.allocate_rid();
+}
+void RendererStorageRD::particles_initialize(RID p_rid) {
+ particles_owner.initialize_rid(p_rid, Particles());
}
void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) {
@@ -3926,7 +3992,7 @@ void RendererStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->custom_aabb = p_aabb;
- particles->instance_dependency.instance_notify_changed(true, false);
+ particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
void RendererStorageRD::particles_set_speed_scale(RID p_particles, float p_scale) {
@@ -4155,24 +4221,18 @@ RID RendererStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass)
return particles->draw_passes[p_pass];
}
-void RendererStorageRD::particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) {
- RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance);
-
+void RendererStorageRD::particles_add_collision(RID p_particles, RID p_particles_collision_instance) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- ERR_FAIL_COND(instance->base_type != RS::INSTANCE_PARTICLES_COLLISION);
-
- particles->collisions.insert(instance);
+ particles->collisions.insert(p_particles_collision_instance);
}
-void RendererStorageRD::particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) {
- RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance);
-
+void RendererStorageRD::particles_remove_collision(RID p_particles, RID p_particles_collision_instance) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
- particles->collisions.erase(instance);
+ particles->collisions.erase(p_particles_collision_instance);
}
void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta) {
@@ -4272,9 +4332,15 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
to_particles = p_particles->emission_transform.affine_inverse();
}
uint32_t collision_3d_textures_used = 0;
- for (const Set<RendererSceneRender::InstanceBase *>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
- ParticlesCollision *pc = particles_collision_owner.getornull(E->get()->base);
- Transform to_collider = E->get()->transform;
+ for (const Set<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
+ ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(E->get());
+ if (!pci || !pci->active) {
+ continue;
+ }
+ ParticlesCollision *pc = particles_collision_owner.getornull(pci->collision);
+ ERR_CONTINUE(!pc);
+
+ Transform to_collider = pci->transform;
if (p_particles->use_local_coords) {
to_collider = to_particles * to_collider;
}
@@ -4463,7 +4529,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
if (sub_emitter && sub_emitter->emission_storage_buffer.is_valid()) {
// print_line("updating subemitter buffer");
int32_t zero[4] = { 0, sub_emitter->amount, 0, 0 };
- RD::get_singleton()->buffer_update(sub_emitter->emission_storage_buffer, 0, sizeof(uint32_t) * 4, zero, true);
+ RD::get_singleton()->buffer_update(sub_emitter->emission_storage_buffer, 0, sizeof(uint32_t) * 4, zero);
push_constant.can_emit = true;
if (sub_emitter->emitting) {
@@ -4481,13 +4547,13 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
}
if (p_particles->emission_buffer && p_particles->emission_buffer->particle_count) {
- RD::get_singleton()->buffer_update(p_particles->emission_storage_buffer, 0, sizeof(uint32_t) * 4 + sizeof(ParticleEmissionBuffer::Data) * p_particles->emission_buffer->particle_count, p_particles->emission_buffer, true);
+ RD::get_singleton()->buffer_update(p_particles->emission_storage_buffer, 0, sizeof(uint32_t) * 4 + sizeof(ParticleEmissionBuffer::Data) * p_particles->emission_buffer->particle_count, p_particles->emission_buffer);
p_particles->emission_buffer->particle_count = 0;
}
p_particles->clear = false;
- RD::get_singleton()->buffer_update(p_particles->frame_params_buffer, 0, sizeof(ParticlesFrameParams), &frame_params, true);
+ RD::get_singleton()->buffer_update(p_particles->frame_params_buffer, 0, sizeof(ParticlesFrameParams), &frame_params);
ParticlesMaterialData *m = (ParticlesMaterialData *)material_get_data(p_particles->process_material, SHADER_TYPE_PARTICLES);
if (!m) {
@@ -4509,7 +4575,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ParticlesShader::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_particles->amount, 1, 1, 64, 1, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_particles->amount, 1, 1);
RD::get_singleton()->compute_list_end();
}
@@ -4563,7 +4629,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 &
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy_push_constant, sizeof(ParticlesShader::CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1);
RD::get_singleton()->compute_list_end();
@@ -4575,7 +4641,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 &
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy_push_constant, sizeof(ParticlesShader::CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1);
RD::get_singleton()->compute_list_end();
}
@@ -4682,12 +4748,12 @@ void RendererStorageRD::update_particles() {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy_push_constant, sizeof(ParticlesShader::CopyPushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1, 64, 1, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1);
RD::get_singleton()->compute_list_end();
}
- particles->instance_dependency.instance_notify_changed(true, false); //make sure shadows are updated
+ particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
}
@@ -4817,6 +4883,10 @@ Variant RendererStorageRD::ParticlesShaderData::get_default_parameter(const Stri
return Variant();
}
+RS::ShaderNativeSourceCode RendererStorageRD::ParticlesShaderData::get_native_source_code() const {
+ return base_singleton->particles_shader.shader.version_get_native_source_code(version);
+}
+
RendererStorageRD::ParticlesShaderData::ParticlesShaderData() {
valid = false;
}
@@ -4934,8 +5004,11 @@ RendererStorageRD::MaterialData *RendererStorageRD::_create_particles_material_f
/* PARTICLES COLLISION API */
-RID RendererStorageRD::particles_collision_create() {
- return particles_collision_owner.make_rid(ParticlesCollision());
+RID RendererStorageRD::particles_collision_allocate() {
+ return particles_collision_owner.allocate_rid();
+}
+void RendererStorageRD::particles_collision_initialize(RID p_rid) {
+ particles_collision_owner.initialize_rid(p_rid, ParticlesCollision());
}
RID RendererStorageRD::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const {
@@ -4986,7 +5059,7 @@ void RendererStorageRD::particles_collision_set_collision_type(RID p_particles_c
particles_collision->heightfield_texture = RID();
}
particles_collision->type = p_type;
- particles_collision->instance_dependency.instance_notify_changed(true, false);
+ particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
void RendererStorageRD::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) {
@@ -5000,7 +5073,7 @@ void RendererStorageRD::particles_collision_set_sphere_radius(RID p_particles_co
ERR_FAIL_COND(!particles_collision);
particles_collision->radius = p_radius;
- particles_collision->instance_dependency.instance_notify_changed(true, false);
+ particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) {
@@ -5008,7 +5081,7 @@ void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_coll
ERR_FAIL_COND(!particles_collision);
particles_collision->extents = p_extents;
- particles_collision->instance_dependency.instance_notify_changed(true, false);
+ particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
void RendererStorageRD::particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) {
@@ -5042,7 +5115,7 @@ void RendererStorageRD::particles_collision_set_field_texture(RID p_particles_co
void RendererStorageRD::particles_collision_height_field_update(RID p_particles_collision) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
- particles_collision->instance_dependency.instance_notify_changed(true, false);
+ particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
void RendererStorageRD::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) {
@@ -5096,10 +5169,29 @@ bool RendererStorageRD::particles_collision_is_heightfield(RID p_particles_colli
return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE;
}
+RID RendererStorageRD::particles_collision_instance_create(RID p_collision) {
+ ParticlesCollisionInstance pci;
+ pci.collision = p_collision;
+ return particles_collision_instance_owner.make_rid(pci);
+}
+void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) {
+ ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
+ ERR_FAIL_COND(!pci);
+ pci->transform = p_transform;
+}
+void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) {
+ ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
+ ERR_FAIL_COND(!pci);
+ pci->active = p_active;
+}
+
/* SKELETON API */
-RID RendererStorageRD::skeleton_create() {
- return skeleton_owner.make_rid(Skeleton());
+RID RendererStorageRD::skeleton_allocate() {
+ return skeleton_owner.allocate_rid();
+}
+void RendererStorageRD::skeleton_initialize(RID p_rid) {
+ skeleton_owner.initialize_rid(p_rid, Skeleton());
}
void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) {
@@ -5110,7 +5202,7 @@ void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) {
}
}
-void RendererStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
+void RendererStorageRD::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
ERR_FAIL_COND(p_bones < 0);
@@ -5149,6 +5241,8 @@ void RendererStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d
skeleton->uniform_set_mi = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON);
}
}
+
+ skeleton->dependency.changed_notify(DEPENDENCY_CHANGED_SKELETON_DATA);
}
int RendererStorageRD::skeleton_get_bone_count(RID p_skeleton) const {
@@ -5264,12 +5358,13 @@ void RendererStorageRD::_update_dirty_skeletons() {
Skeleton *skeleton = skeleton_dirty_list;
if (skeleton->size) {
- RD::get_singleton()->buffer_update(skeleton->buffer, 0, skeleton->data.size() * sizeof(float), skeleton->data.ptr(), false);
+ RD::get_singleton()->buffer_update(skeleton->buffer, 0, skeleton->data.size() * sizeof(float), skeleton->data.ptr());
}
skeleton_dirty_list = skeleton->dirty_list;
- skeleton->instance_dependency.instance_notify_changed(true, false);
+ skeleton->dependency.changed_notify(DEPENDENCY_CHANGED_SKELETON_BONES);
+
skeleton->version++;
skeleton->dirty = false;
@@ -5281,7 +5376,7 @@ void RendererStorageRD::_update_dirty_skeletons() {
/* LIGHT */
-RID RendererStorageRD::light_create(RS::LightType p_type) {
+void RendererStorageRD::_light_initialize(RID p_light, RS::LightType p_type) {
Light light;
light.type = p_type;
@@ -5290,19 +5385,43 @@ RID RendererStorageRD::light_create(RS::LightType p_type) {
light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;
light.param[RS::LIGHT_PARAM_RANGE] = 1.0;
light.param[RS::LIGHT_PARAM_SIZE] = 0.0;
+ light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0;
light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;
+ light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0;
light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
- light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
+ light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
+ light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
+ light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1;
light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
- light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0;
- return light_owner.make_rid(light);
+ light_owner.initialize_rid(p_light, light);
+}
+
+RID RendererStorageRD::directional_light_allocate() {
+ return light_owner.allocate_rid();
+}
+void RendererStorageRD::directional_light_initialize(RID p_light) {
+ _light_initialize(p_light, RS::LIGHT_DIRECTIONAL);
+}
+
+RID RendererStorageRD::omni_light_allocate() {
+ return light_owner.allocate_rid();
+}
+void RendererStorageRD::omni_light_initialize(RID p_light) {
+ _light_initialize(p_light, RS::LIGHT_OMNI);
+}
+
+RID RendererStorageRD::spot_light_allocate() {
+ return light_owner.allocate_rid();
+}
+void RendererStorageRD::spot_light_initialize(RID p_light) {
+ _light_initialize(p_light, RS::LIGHT_SPOT);
}
void RendererStorageRD::light_set_color(RID p_light, const Color &p_color) {
@@ -5328,7 +5447,7 @@ void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, flo
case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
case RS::LIGHT_PARAM_SHADOW_BIAS: {
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
} break;
default: {
}
@@ -5343,7 +5462,7 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
light->shadow = p_enabled;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) {
@@ -5385,7 +5504,7 @@ void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
light->cull_mask = p_mask;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
@@ -5395,7 +5514,7 @@ void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_ena
light->reverse_cull = p_enabled;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
@@ -5405,7 +5524,7 @@ void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bak
light->bake_mode = p_bake_mode;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
@@ -5415,7 +5534,7 @@ void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_casc
light->max_sdfgi_cascade = p_cascade;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
@@ -5425,7 +5544,7 @@ void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniSha
light->omni_shadow_mode = p_mode;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
RS::LightOmniShadowMode RendererStorageRD::light_omni_get_shadow_mode(RID p_light) {
@@ -5441,7 +5560,7 @@ void RendererStorageRD::light_directional_set_shadow_mode(RID p_light, RS::Light
light->directional_shadow_mode = p_mode;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) {
@@ -5450,7 +5569,7 @@ void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_e
light->directional_blend_splits = p_enable;
light->version++;
- light->instance_dependency.instance_notify_changed(true, false);
+ light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
}
bool RendererStorageRD::light_directional_get_blend_splits(RID p_light) const {
@@ -5540,8 +5659,11 @@ AABB RendererStorageRD::light_get_aabb(RID p_light) const {
/* REFLECTION PROBE */
-RID RendererStorageRD::reflection_probe_create() {
- return reflection_probe_owner.make_rid(ReflectionProbe());
+RID RendererStorageRD::reflection_probe_allocate() {
+ return reflection_probe_owner.allocate_rid();
+}
+void RendererStorageRD::reflection_probe_initialize(RID p_reflection_probe) {
+ reflection_probe_owner.initialize_rid(p_reflection_probe, ReflectionProbe());
}
void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
@@ -5549,7 +5671,7 @@ void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::Reflec
ERR_FAIL_COND(!reflection_probe);
reflection_probe->update_mode = p_mode;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void RendererStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
@@ -5586,7 +5708,7 @@ void RendererStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_d
reflection_probe->max_distance = p_distance;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
@@ -5597,7 +5719,7 @@ void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3
return;
}
reflection_probe->extents = p_extents;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
@@ -5605,7 +5727,7 @@ void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Ve
ERR_FAIL_COND(!reflection_probe);
reflection_probe->origin_offset = p_offset;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
@@ -5613,7 +5735,7 @@ void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_ena
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void RendererStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
@@ -5628,7 +5750,7 @@ void RendererStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_
ERR_FAIL_COND(!reflection_probe);
reflection_probe->enable_shadows = p_enable;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
@@ -5636,7 +5758,7 @@ void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_l
ERR_FAIL_COND(!reflection_probe);
reflection_probe->cull_mask = p_layers;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void RendererStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
@@ -5653,7 +5775,7 @@ void RendererStorageRD::reflection_probe_set_lod_threshold(RID p_probe, float p_
reflection_probe->lod_threshold = p_ratio;
- reflection_probe->instance_dependency.instance_notify_changed(true, false);
+ reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
AABB RendererStorageRD::reflection_probe_get_aabb(RID p_probe) const {
@@ -5763,15 +5885,18 @@ float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe)
return reflection_probe->ambient_color_energy;
}
-RID RendererStorageRD::decal_create() {
- return decal_owner.make_rid(Decal());
+RID RendererStorageRD::decal_allocate() {
+ return decal_owner.allocate_rid();
+}
+void RendererStorageRD::decal_initialize(RID p_decal) {
+ decal_owner.initialize_rid(p_decal, Decal());
}
void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->extents = p_extents;
- decal->instance_dependency.instance_notify_changed(true, false);
+ decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
@@ -5795,7 +5920,7 @@ void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type,
texture_add_to_decal_atlas(decal->textures[p_type]);
}
- decal->instance_dependency.instance_notify_changed(false, true);
+ decal->dependency.changed_notify(DEPENDENCY_CHANGED_DECAL);
}
void RendererStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) {
@@ -5820,7 +5945,7 @@ void RendererStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->cull_mask = p_layers;
- decal->instance_dependency.instance_notify_changed(true, false);
+ decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
@@ -5851,11 +5976,14 @@ AABB RendererStorageRD::decal_get_aabb(RID p_decal) const {
return AABB(-decal->extents, decal->extents * 2.0);
}
-RID RendererStorageRD::gi_probe_create() {
- return gi_probe_owner.make_rid(GIProbe());
+RID RendererStorageRD::gi_probe_allocate() {
+ return gi_probe_owner.allocate_rid();
+}
+void RendererStorageRD::gi_probe_initialize(RID p_gi_probe) {
+ gi_probe_owner.initialize_rid(p_gi_probe, GIProbe());
}
-void RendererStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
+void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
@@ -5977,7 +6105,7 @@ void RendererStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_
gi_probe->version++;
gi_probe->data_version++;
- gi_probe->instance_dependency.instance_notify_changed(true, false);
+ gi_probe->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
AABB RendererStorageRD::gi_probe_get_bounds(RID p_gi_probe) const {
@@ -6204,8 +6332,12 @@ RID RendererStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) {
/* LIGHTMAP API */
-RID RendererStorageRD::lightmap_create() {
- return lightmap_owner.make_rid(Lightmap());
+RID RendererStorageRD::lightmap_allocate() {
+ return lightmap_owner.allocate_rid();
+}
+
+void RendererStorageRD::lightmap_initialize(RID p_lightmap) {
+ lightmap_owner.initialize_rid(p_lightmap, Lightmap());
}
void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
@@ -6408,7 +6540,8 @@ void RendererStorageRD::_clear_render_target(RenderTarget *rt) {
void RendererStorageRD::_update_render_target(RenderTarget *rt) {
if (rt->texture.is_null()) {
//create a placeholder until updated
- rt->texture = texture_2d_placeholder_create();
+ rt->texture = texture_allocate();
+ texture_2d_placeholder_initialize(rt->texture);
Texture *tex = texture_owner.getornull(rt->texture);
tex->is_render_target = true;
}
@@ -6908,7 +7041,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[1], 0); //fill [0]
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
/* Process */
@@ -6924,7 +7057,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
push_constant.stride = stride;
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
stride /= 2;
swap = !swap;
RD::get_singleton()->compute_list_add_barrier(compute_list);
@@ -6935,7 +7068,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) {
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_STORE_SHRINK : RenderTargetSDF::SHADER_STORE]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1, 8, 8, 1);
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
RD::get_singleton()->compute_list_end();
}
@@ -7055,45 +7188,45 @@ void RendererStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_ta
rt->backbuffer_uniform_set = p_uniform_set;
}
-void RendererStorageRD::base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) {
+void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
if (mesh_owner.owns(p_base)) {
Mesh *mesh = mesh_owner.getornull(p_base);
- p_instance->update_dependency(&mesh->instance_dependency);
+ p_instance->update_dependency(&mesh->dependency);
} else if (multimesh_owner.owns(p_base)) {
MultiMesh *multimesh = multimesh_owner.getornull(p_base);
- p_instance->update_dependency(&multimesh->instance_dependency);
+ p_instance->update_dependency(&multimesh->dependency);
if (multimesh->mesh.is_valid()) {
base_update_dependency(multimesh->mesh, p_instance);
}
} else if (reflection_probe_owner.owns(p_base)) {
ReflectionProbe *rp = reflection_probe_owner.getornull(p_base);
- p_instance->update_dependency(&rp->instance_dependency);
+ p_instance->update_dependency(&rp->dependency);
} else if (decal_owner.owns(p_base)) {
Decal *decal = decal_owner.getornull(p_base);
- p_instance->update_dependency(&decal->instance_dependency);
+ p_instance->update_dependency(&decal->dependency);
} else if (gi_probe_owner.owns(p_base)) {
GIProbe *gip = gi_probe_owner.getornull(p_base);
- p_instance->update_dependency(&gip->instance_dependency);
+ p_instance->update_dependency(&gip->dependency);
} else if (lightmap_owner.owns(p_base)) {
Lightmap *lm = lightmap_owner.getornull(p_base);
- p_instance->update_dependency(&lm->instance_dependency);
+ p_instance->update_dependency(&lm->dependency);
} else if (light_owner.owns(p_base)) {
Light *l = light_owner.getornull(p_base);
- p_instance->update_dependency(&l->instance_dependency);
+ p_instance->update_dependency(&l->dependency);
} else if (particles_owner.owns(p_base)) {
Particles *p = particles_owner.getornull(p_base);
- p_instance->update_dependency(&p->instance_dependency);
+ p_instance->update_dependency(&p->dependency);
} else if (particles_collision_owner.owns(p_base)) {
ParticlesCollision *pc = particles_collision_owner.getornull(p_base);
- p_instance->update_dependency(&pc->instance_dependency);
+ p_instance->update_dependency(&pc->dependency);
}
}
-void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, InstanceBaseDependency *p_instance) {
+void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
- p_instance->update_dependency(&skeleton->instance_dependency);
+ p_instance->update_dependency(&skeleton->dependency);
}
RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
@@ -7299,6 +7432,7 @@ void RendererStorageRD::_update_decal_atlas() {
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
+ RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
{
//create the framebuffer
@@ -7353,7 +7487,7 @@ void RendererStorageRD::_update_decal_atlas() {
prev_texture = mm.texture;
}
} else {
- RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1, false);
+ RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
}
}
}
@@ -8114,39 +8248,49 @@ bool RendererStorageRD::free(RID p_rid) {
_update_queued_materials();
}
material_set_shader(p_rid, RID()); //clean up shader
- material->instance_dependency.instance_notify_deleted(p_rid);
+ material->dependency.deleted_notify(p_rid);
+
material_owner.free(p_rid);
} else if (mesh_owner.owns(p_rid)) {
mesh_clear(p_rid);
+ mesh_set_shadow_mesh(p_rid, RID());
Mesh *mesh = mesh_owner.getornull(p_rid);
- mesh->instance_dependency.instance_notify_deleted(p_rid);
+ mesh->dependency.deleted_notify(p_rid);
if (mesh->instances.size()) {
ERR_PRINT("deleting mesh with active instances");
}
+ if (mesh->shadow_owners.size()) {
+ for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) {
+ Mesh *shadow_owner = E->get();
+ shadow_owner->shadow_mesh = RID();
+ shadow_owner->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
+ }
+ }
mesh_owner.free(p_rid);
} else if (mesh_instance_owner.owns(p_rid)) {
MeshInstance *mi = mesh_instance_owner.getornull(p_rid);
_mesh_instance_clear(mi);
mi->mesh->instances.erase(mi->I);
mi->I = nullptr;
+
mesh_instance_owner.free(p_rid);
memdelete(mi);
} else if (multimesh_owner.owns(p_rid)) {
_update_dirty_multimeshes();
- multimesh_allocate(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D);
+ multimesh_allocate_data(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D);
MultiMesh *multimesh = multimesh_owner.getornull(p_rid);
- multimesh->instance_dependency.instance_notify_deleted(p_rid);
+ multimesh->dependency.deleted_notify(p_rid);
multimesh_owner.free(p_rid);
} else if (skeleton_owner.owns(p_rid)) {
_update_dirty_skeletons();
- skeleton_allocate(p_rid, 0);
+ skeleton_allocate_data(p_rid, 0);
Skeleton *skeleton = skeleton_owner.getornull(p_rid);
- skeleton->instance_dependency.instance_notify_deleted(p_rid);
+ skeleton->dependency.deleted_notify(p_rid);
skeleton_owner.free(p_rid);
} else if (reflection_probe_owner.owns(p_rid)) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid);
- reflection_probe->instance_dependency.instance_notify_deleted(p_rid);
+ reflection_probe->dependency.deleted_notify(p_rid);
reflection_probe_owner.free(p_rid);
} else if (decal_owner.owns(p_rid)) {
Decal *decal = decal_owner.getornull(p_rid);
@@ -8155,30 +8299,30 @@ bool RendererStorageRD::free(RID p_rid) {
texture_remove_from_decal_atlas(decal->textures[i]);
}
}
- decal->instance_dependency.instance_notify_deleted(p_rid);
+ decal->dependency.deleted_notify(p_rid);
decal_owner.free(p_rid);
} else if (gi_probe_owner.owns(p_rid)) {
- gi_probe_allocate(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
+ gi_probe_allocate_data(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
GIProbe *gi_probe = gi_probe_owner.getornull(p_rid);
- gi_probe->instance_dependency.instance_notify_deleted(p_rid);
+ gi_probe->dependency.deleted_notify(p_rid);
gi_probe_owner.free(p_rid);
} else if (lightmap_owner.owns(p_rid)) {
lightmap_set_textures(p_rid, RID(), false);
Lightmap *lightmap = lightmap_owner.getornull(p_rid);
- lightmap->instance_dependency.instance_notify_deleted(p_rid);
+ lightmap->dependency.deleted_notify(p_rid);
lightmap_owner.free(p_rid);
} else if (light_owner.owns(p_rid)) {
light_set_projector(p_rid, RID()); //clear projector
// delete the texture
Light *light = light_owner.getornull(p_rid);
- light->instance_dependency.instance_notify_deleted(p_rid);
+ light->dependency.deleted_notify(p_rid);
light_owner.free(p_rid);
} else if (particles_owner.owns(p_rid)) {
Particles *particles = particles_owner.getornull(p_rid);
_particles_free_data(particles);
- particles->instance_dependency.instance_notify_deleted(p_rid);
+ particles->dependency.deleted_notify(p_rid);
particles_owner.free(p_rid);
} else if (particles_collision_owner.owns(p_rid)) {
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_rid);
@@ -8186,8 +8330,10 @@ bool RendererStorageRD::free(RID p_rid) {
if (particles_collision->heightfield_texture.is_valid()) {
RD::get_singleton()->free(particles_collision->heightfield_texture);
}
- particles_collision->instance_dependency.instance_notify_deleted(p_rid);
+ particles_collision->dependency.deleted_notify(p_rid);
particles_collision_owner.free(p_rid);
+ } else if (particles_collision_instance_owner.owns(p_rid)) {
+ particles_collision_instance_owner.free(p_rid);
} else if (render_target_owner.owns(p_rid)) {
RenderTarget *rt = render_target_owner.getornull(p_rid);
@@ -8212,11 +8358,11 @@ EffectsRD *RendererStorageRD::get_effects() {
}
void RendererStorageRD::capture_timestamps_begin() {
- RD::get_singleton()->capture_timestamp("Frame Begin", false);
+ RD::get_singleton()->capture_timestamp("Frame Begin");
}
void RendererStorageRD::capture_timestamp(const String &p_name) {
- RD::get_singleton()->capture_timestamp(p_name, true);
+ RD::get_singleton()->capture_timestamp(p_name);
}
uint32_t RendererStorageRD::get_captured_timestamps_count() const {
@@ -8250,7 +8396,7 @@ RendererStorageRD::RendererStorageRD() {
static_assert(sizeof(GlobalVariables::Value) == 16);
- global_variables.buffer_size = GLOBAL_GET("rendering/high_end/global_shader_variables_buffer_size");
+ global_variables.buffer_size = GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size");
global_variables.buffer_size = MAX(4096, global_variables.buffer_size);
global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size);
zeromem(global_variables.buffer_values, sizeof(GlobalVariables::Value) * global_variables.buffer_size);
@@ -8518,14 +8664,14 @@ RendererStorageRD::RendererStorageRD() {
sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.use_anisotropy = true;
- sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/quality/texture_filters/anisotropic_filtering_level"));
+ sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/textures/default_filters/anisotropic_filtering_level"));
} break;
case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: {
sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.use_anisotropy = true;
- sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/quality/texture_filters/anisotropic_filtering_level"));
+ sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/textures/default_filters/anisotropic_filtering_level"));
} break;
default: {
@@ -8695,7 +8841,7 @@ RendererStorageRD::RendererStorageRD() {
}
}
- lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed");
+ lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed");
/* Particles */
@@ -8736,7 +8882,7 @@ RendererStorageRD::RendererStorageRD() {
actions.renames["RESTART_VELOCITY"] = "restart_velocity";
actions.renames["RESTART_COLOR"] = "restart_color";
actions.renames["RESTART_CUSTOM"] = "restart_custom";
- actions.renames["emit_particle"] = "emit_particle";
+ actions.renames["emit_subparticle"] = "emit_subparticle";
actions.renames["COLLIDED"] = "collided";
actions.renames["COLLISION_NORMAL"] = "collision_normal";
actions.renames["COLLISION_DEPTH"] = "collision_depth";
@@ -8762,9 +8908,11 @@ RendererStorageRD::RendererStorageRD() {
{
// default material and shader for particles shader
- particles_shader.default_shader = shader_create();
+ particles_shader.default_shader = shader_allocate();
+ shader_initialize(particles_shader.default_shader);
shader_set_code(particles_shader.default_shader, "shader_type particles; void compute() { COLOR = vec4(1.0); } \n");
- particles_shader.default_material = material_create();
+ particles_shader.default_material = material_allocate();
+ material_initialize(particles_shader.default_material);
material_set_shader(particles_shader.default_material, particles_shader.default_shader);
ParticlesMaterialData *md = (ParticlesMaterialData *)material_get_data(particles_shader.default_material, RendererStorageRD::SHADER_TYPE_PARTICLES);
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index e4199ffd12..cd3d4604eb 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -95,6 +95,21 @@ public:
p_array[11] = 0;
}
+ static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.basis.elements[0][0];
+ p_array[1] = p_mtx.basis.elements[0][1];
+ p_array[2] = p_mtx.basis.elements[0][2];
+ p_array[3] = p_mtx.origin.x;
+ p_array[4] = p_mtx.basis.elements[1][0];
+ p_array[5] = p_mtx.basis.elements[1][1];
+ p_array[6] = p_mtx.basis.elements[1][2];
+ p_array[7] = p_mtx.origin.y;
+ p_array[8] = p_mtx.basis.elements[2][0];
+ p_array[9] = p_mtx.basis.elements[2][1];
+ p_array[10] = p_mtx.basis.elements[2][2];
+ p_array[11] = p_mtx.origin.z;
+ }
+
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
@@ -127,6 +142,8 @@ public:
virtual bool is_animated() const = 0;
virtual bool casts_shadows() const = 0;
virtual Variant get_default_parameter(const StringName &p_parameter) const = 0;
+ virtual RS::ShaderNativeSourceCode get_native_source_code() const { return RS::ShaderNativeSourceCode(); }
+
virtual ~ShaderData() {}
};
@@ -187,7 +204,7 @@ private:
struct CanvasTexture {
RID diffuse;
- RID normalmap;
+ RID normal_map;
RID specular;
Color specular_color = Color(1, 1, 1, 1);
float shininess = 1.0;
@@ -204,7 +221,7 @@ private:
~CanvasTexture();
};
- RID_PtrOwner<CanvasTexture> canvas_texture_owner;
+ RID_PtrOwner<CanvasTexture, true> canvas_texture_owner;
/* TEXTURE API */
struct Texture {
@@ -350,7 +367,7 @@ private:
};
ShaderDataRequestFunction shader_data_request_func[SHADER_TYPE_MAX];
- mutable RID_Owner<Shader> shader_owner;
+ mutable RID_Owner<Shader, true> shader_owner;
/* Material */
@@ -360,6 +377,7 @@ private:
Shader *shader;
//shortcut to shader data and type
ShaderType shader_type;
+ uint32_t shader_id = 0;
bool update_requested;
bool uniform_dirty;
bool texture_dirty;
@@ -367,11 +385,11 @@ private:
Map<StringName, Variant> params;
int32_t priority;
RID next_pass;
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
};
MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX];
- mutable RID_Owner<Material> material_owner;
+ mutable RID_Owner<Material, true> material_owner;
Material *material_update_list;
void _material_queue_update(Material *material, bool p_uniform, bool p_texture);
@@ -460,10 +478,13 @@ private:
List<MeshInstance *> instances;
- RendererStorage::InstanceDependency instance_dependency;
+ RID shadow_mesh;
+ Set<Mesh *> shadow_owners;
+
+ Dependency dependency;
};
- mutable RID_Owner<Mesh> mesh_owner;
+ mutable RID_Owner<Mesh, true> mesh_owner;
struct MeshInstance {
Mesh *mesh;
@@ -563,10 +584,10 @@ private:
bool dirty = false;
MultiMesh *dirty_list = nullptr;
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
};
- mutable RID_Owner<MultiMesh> multimesh_owner;
+ mutable RID_Owner<MultiMesh, true> multimesh_owner;
MultiMesh *multimesh_dirty_list = nullptr;
@@ -734,7 +755,7 @@ private:
ParticleEmissionBuffer *emission_buffer = nullptr;
RID emission_storage_buffer;
- Set<RendererSceneRender::InstanceBase *> collisions;
+ Set<RID> collisions;
Particles() :
inactive(true),
@@ -761,7 +782,7 @@ private:
clear(true) {
}
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
ParticlesFrameParams frame_params;
};
@@ -839,6 +860,8 @@ private:
virtual bool is_animated() const;
virtual bool casts_shadows() const;
virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ virtual RS::ShaderNativeSourceCode get_native_source_code() const;
+
ParticlesShaderData();
virtual ~ParticlesShaderData();
};
@@ -870,7 +893,7 @@ private:
void update_particles();
- mutable RID_Owner<Particles> particles_owner;
+ mutable RID_Owner<Particles, true> particles_owner;
/* Particles Collision */
@@ -889,10 +912,18 @@ private:
RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024;
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
+ };
+
+ mutable RID_Owner<ParticlesCollision, true> particles_collision_owner;
+
+ struct ParticlesCollisionInstance {
+ RID collision;
+ Transform transform;
+ bool active = false;
};
- mutable RID_Owner<ParticlesCollision> particles_collision_owner;
+ mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner;
/* Skeleton */
@@ -911,10 +942,10 @@ private:
uint64_t version = 1;
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
};
- mutable RID_Owner<Skeleton> skeleton_owner;
+ mutable RID_Owner<Skeleton, true> skeleton_owner;
_FORCE_INLINE_ void _skeleton_make_dirty(Skeleton *skeleton);
@@ -943,10 +974,10 @@ private:
bool directional_sky_only = false;
uint64_t version = 0;
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
};
- mutable RID_Owner<Light> light_owner;
+ mutable RID_Owner<Light, true> light_owner;
/* REFLECTION PROBE */
@@ -966,10 +997,10 @@ private:
uint32_t cull_mask = (1 << 20) - 1;
float lod_threshold = 0.01;
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
};
- mutable RID_Owner<ReflectionProbe> reflection_probe_owner;
+ mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner;
/* DECAL */
@@ -987,10 +1018,10 @@ private:
float distance_fade_length = 1;
float normal_fade = 0.0;
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
};
- mutable RID_Owner<Decal> decal_owner;
+ mutable RID_Owner<Decal, true> decal_owner;
/* GI PROBE */
@@ -1025,7 +1056,7 @@ private:
uint32_t version = 1;
uint32_t data_version = 1;
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
};
GiprobeSdfShaderRD giprobe_sdf_shader;
@@ -1033,7 +1064,7 @@ private:
RID giprobe_sdf_shader_version_shader;
RID giprobe_sdf_shader_pipeline;
- mutable RID_Owner<GIProbe> gi_probe_owner;
+ mutable RID_Owner<GIProbe, true> gi_probe_owner;
/* REFLECTION PROBE */
@@ -1054,7 +1085,7 @@ private:
int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
};
- RendererStorage::InstanceDependency instance_dependency;
+ Dependency dependency;
};
bool using_lightmap_array; //high end uses this
@@ -1064,7 +1095,7 @@ private:
uint64_t lightmap_array_version = 0;
- mutable RID_Owner<Lightmap> lightmap_owner;
+ mutable RID_Owner<Lightmap, true> lightmap_owner;
float lightmap_probe_capture_update_speed = 4;
@@ -1218,12 +1249,16 @@ private:
EffectsRD effects;
public:
+ virtual bool can_create_resources_async() const;
+
/* TEXTURE API */
- virtual RID texture_2d_create(const Ref<Image> &p_image);
- virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type);
- virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent
- virtual RID texture_proxy_create(RID p_base);
+ virtual RID texture_allocate();
+
+ virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image);
+ virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type);
+ virtual void texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent
+ virtual void texture_proxy_initialize(RID p_texture, RID p_base);
virtual void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate);
@@ -1233,9 +1268,9 @@ public:
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to);
//these two APIs can be used together or in combination with the others.
- virtual RID texture_2d_placeholder_create();
- virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type);
- virtual RID texture_3d_placeholder_create();
+ virtual void texture_2d_placeholder_initialize(RID p_texture);
+ virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type);
+ virtual void texture_3d_placeholder_initialize(RID p_texture);
virtual Ref<Image> texture_2d_get(RID p_texture) const;
virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const;
@@ -1307,7 +1342,8 @@ public:
/* CANVAS TEXTURE API */
- virtual RID canvas_texture_create();
+ RID canvas_texture_allocate();
+ void canvas_texture_initialize(RID p_canvas_texture);
virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture);
virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess);
@@ -1319,7 +1355,8 @@ public:
/* SHADER API */
- RID shader_create();
+ RID shader_allocate();
+ void shader_initialize(RID p_shader);
void shader_set_code(RID p_shader, const String &p_code);
String shader_get_code(RID p_shader) const;
@@ -1330,9 +1367,12 @@ public:
Variant shader_get_param_default(RID p_shader, const StringName &p_param) const;
void shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function);
+ virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const;
+
/* COMMON MATERIAL API */
- RID material_create();
+ RID material_allocate();
+ void material_initialize(RID p_material);
void material_set_shader(RID p_material, RID p_shader);
@@ -1347,11 +1387,16 @@ public:
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters);
- void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance);
+ void material_update_dependency(RID p_material, DependencyTracker *p_instance);
void material_force_update_textures(RID p_material, ShaderType p_shader_type);
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
+ _FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) {
+ Material *material = material_owner.getornull(p_material);
+ return material->shader_id;
+ }
+
_FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) {
Material *material = material_owner.getornull(p_material);
if (!material || material->shader_type != p_shader_type) {
@@ -1363,7 +1408,8 @@ public:
/* MESH API */
- virtual RID mesh_create();
+ RID mesh_allocate();
+ void mesh_initialize(RID p_mesh);
virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count);
@@ -1388,6 +1434,7 @@ public:
virtual AABB mesh_get_custom_aabb(RID p_mesh) const;
virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID());
+ virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh);
virtual void mesh_clear(RID p_mesh);
@@ -1408,7 +1455,7 @@ public:
if (r_surface_count == 0) {
return nullptr;
}
- if (mesh->material_cache.empty()) {
+ if (mesh->material_cache.is_empty()) {
mesh->material_cache.resize(mesh->surface_count);
for (uint32_t i = 0; i < r_surface_count; i++) {
mesh->material_cache.write[i] = mesh->surfaces[i]->material;
@@ -1426,6 +1473,13 @@ public:
return mesh->surfaces[p_surface_index];
}
+ _FORCE_INLINE_ RID mesh_get_shadow_mesh(RID p_mesh) {
+ Mesh *mesh = mesh_owner.getornull(p_mesh);
+ ERR_FAIL_COND_V(!mesh, RID());
+
+ return mesh->shadow_mesh;
+ }
+
_FORCE_INLINE_ RS::PrimitiveType mesh_surface_get_primitive(void *p_surface) {
Mesh::Surface *surface = reinterpret_cast<Mesh::Surface *>(p_surface);
return surface->primitive;
@@ -1436,13 +1490,7 @@ public:
return s->lod_count > 0;
}
- _FORCE_INLINE_ RID mesh_surface_get_index_array(void *p_surface) const {
- Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
-
- return s->index_array;
- }
-
- _FORCE_INLINE_ RID mesh_surface_get_index_array_with_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const {
+ _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const {
Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
int32_t current_lod = -1;
@@ -1454,9 +1502,19 @@ public:
current_lod = i;
}
if (current_lod == -1) {
+ return 0;
+ } else {
+ return current_lod + 1;
+ }
+ }
+
+ _FORCE_INLINE_ RID mesh_surface_get_index_array(void *p_surface, uint32_t p_lod) const {
+ Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
+
+ if (p_lod == 0) {
return s->index_array;
} else {
- return s->lods[current_lod].index_array;
+ return s->lods[p_lod - 1].index_array;
}
}
@@ -1572,9 +1630,10 @@ public:
/* MULTIMESH API */
- RID multimesh_create();
+ RID multimesh_allocate();
+ void multimesh_initialize(RID p_multimesh);
- void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false);
+ 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);
int multimesh_get_instance_count(RID p_multimesh) const;
void multimesh_set_mesh(RID p_multimesh, RID p_mesh);
@@ -1638,24 +1697,28 @@ public:
/* IMMEDIATE API */
- RID immediate_create() { return RID(); }
- void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {}
- void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {}
- void immediate_normal(RID p_immediate, const Vector3 &p_normal) {}
- void immediate_tangent(RID p_immediate, const Plane &p_tangent) {}
- void immediate_color(RID p_immediate, const Color &p_color) {}
- void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {}
- void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {}
- void immediate_end(RID p_immediate) {}
- void immediate_clear(RID p_immediate) {}
- void immediate_set_material(RID p_immediate, RID p_material) {}
- RID immediate_get_material(RID p_immediate) const { return RID(); }
- AABB immediate_get_aabb(RID p_immediate) const { return AABB(); }
+ RID immediate_allocate() { return RID(); }
+ void immediate_initialize(RID p_immediate) {}
+
+ virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {}
+ virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {}
+ virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) {}
+ virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) {}
+ virtual void immediate_color(RID p_immediate, const Color &p_color) {}
+ virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {}
+ virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {}
+ virtual void immediate_end(RID p_immediate) {}
+ virtual void immediate_clear(RID p_immediate) {}
+ virtual void immediate_set_material(RID p_immediate, RID p_material) {}
+ virtual RID immediate_get_material(RID p_immediate) const { return RID(); }
+ virtual AABB immediate_get_aabb(RID p_immediate) const { return AABB(); }
/* SKELETON API */
- RID skeleton_create();
- void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false);
+ RID skeleton_allocate();
+ void skeleton_initialize(RID p_skeleton);
+
+ void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false);
void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform);
int skeleton_get_bone_count(RID p_skeleton) const;
@@ -1664,6 +1727,10 @@ public:
void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
+ _FORCE_INLINE_ bool skeleton_is_valid(RID p_skeleton) {
+ return skeleton_owner.getornull(p_skeleton) != nullptr;
+ }
+
_FORCE_INLINE_ RID skeleton_get_3d_uniform_set(RID p_skeleton, RID p_shader, uint32_t p_set) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, RID());
@@ -1685,11 +1752,16 @@ public:
}
/* Light API */
- RID light_create(RS::LightType p_type);
+ void _light_initialize(RID p_rid, RS::LightType p_type);
+
+ RID directional_light_allocate();
+ void directional_light_initialize(RID p_light);
- RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); }
- RID omni_light_create() { return light_create(RS::LIGHT_OMNI); }
- RID spot_light_create() { return light_create(RS::LIGHT_SPOT); }
+ RID omni_light_allocate();
+ void omni_light_initialize(RID p_light);
+
+ RID spot_light_allocate();
+ void spot_light_initialize(RID p_light);
void light_set_color(RID p_light, const Color &p_color);
void light_set_param(RID p_light, RS::LightParam p_param, float p_value);
@@ -1792,7 +1864,8 @@ public:
/* PROBE API */
- RID reflection_probe_create();
+ RID reflection_probe_allocate();
+ void reflection_probe_initialize(RID p_reflection_probe);
void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode);
void reflection_probe_set_intensity(RID p_probe, float p_intensity);
@@ -1827,12 +1900,14 @@ public:
Color reflection_probe_get_ambient_color(RID p_probe) const;
float reflection_probe_get_ambient_color_energy(RID p_probe) const;
- void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance);
- void skeleton_update_dependency(RID p_skeleton, InstanceBaseDependency *p_instance);
+ void base_update_dependency(RID p_base, DependencyTracker *p_instance);
+ void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance);
/* DECAL API */
- virtual RID decal_create();
+ RID decal_allocate();
+ void decal_initialize(RID p_decal);
+
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents);
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture);
virtual void decal_set_emission_energy(RID p_decal, float p_energy);
@@ -1907,9 +1982,10 @@ public:
/* GI PROBE API */
- RID gi_probe_create();
+ RID gi_probe_allocate();
+ void gi_probe_initialize(RID p_gi_probe);
- void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts);
+ void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts);
AABB gi_probe_get_bounds(RID p_gi_probe) const;
Vector3i gi_probe_get_octree_size(RID p_gi_probe) const;
@@ -1960,7 +2036,8 @@ public:
/* LIGHTMAP CAPTURE */
- virtual RID lightmap_create();
+ RID lightmap_allocate();
+ void lightmap_initialize(RID p_lightmap);
virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics);
virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds);
@@ -1977,7 +2054,11 @@ public:
_FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const {
return lightmap_probe_capture_update_speed;
}
-
+ _FORCE_INLINE_ RID lightmap_get_texture(RID p_lightmap) const {
+ const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND_V(!lm, RID());
+ return lm->light_texture;
+ }
_FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const {
ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays
const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
@@ -2005,7 +2086,8 @@ public:
/* PARTICLES */
- RID particles_create();
+ RID particles_allocate();
+ void particles_initialize(RID p_particles_collision);
void particles_set_emitting(RID p_particles, bool p_emitting);
void particles_set_amount(RID p_particles, int p_amount);
@@ -2078,12 +2160,14 @@ public:
return particles->particles_transforms_buffer_uniform_set;
}
- virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance);
- virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance);
+ virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance);
+ virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance);
/* PARTICLES COLLISION */
- virtual RID particles_collision_create();
+ RID particles_collision_allocate();
+ void particles_collision_initialize(RID p_particles_collision);
+
virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type);
virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask);
virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius); //for spheres
@@ -2099,6 +2183,11 @@ public:
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const;
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
+ //used from 2D and 3D
+ virtual RID particles_collision_instance_create(RID p_collision);
+ virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform);
+ virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active);
+
/* GLOBAL VARIABLES API */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value);
@@ -2174,7 +2263,7 @@ public:
void render_info_end_capture() {}
int get_captured_render_info(RS::RenderInfo p_info) { return 0; }
- int get_render_info(RS::RenderInfo p_info) { return 0; }
+ uint64_t get_render_info(RS::RenderInfo p_info) { return 0; }
String get_video_adapter_name() const { return String(); }
String get_video_adapter_vendor() const { return String(); }
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
index 2c1d2a84fd..8135d388e1 100644
--- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -687,7 +687,15 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
uint32_t index = p_default_actions.base_varying_index;
+ List<Pair<StringName, SL::ShaderNode::Varying>> var_frag_to_light;
+
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) {
+ if (E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT || E->get().stage == SL::ShaderNode::Varying::STAGE_FRAGMENT) {
+ var_frag_to_light.push_back(Pair<StringName, SL::ShaderNode::Varying>(E->key(), E->get()));
+ fragment_varyings.insert(E->key());
+ continue;
+ }
+
String vcode;
String interp_mode = _interpstr(E->get().interpolation);
vcode += _prestr(E->get().precision);
@@ -705,6 +713,21 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
index++;
}
+ if (var_frag_to_light.size() > 0) {
+ String gcode = "\n\nstruct {\n";
+ for (List<Pair<StringName, SL::ShaderNode::Varying>>::Element *E = var_frag_to_light.front(); E; E = E->next()) {
+ gcode += "\t" + _prestr(E->get().second.precision) + _typestr(E->get().second.type) + " " + _mkid(E->get().first);
+ if (E->get().second.array_size > 0) {
+ gcode += "[";
+ gcode += itos(E->get().second.array_size);
+ gcode += "]";
+ }
+ gcode += ";\n";
+ }
+ gcode += "} frag_to_light;\n";
+ r_gen_code.fragment_global += gcode;
+ }
+
for (int i = 0; i < pnode->vconstants.size(); i++) {
const SL::ShaderNode::Constant &cnode = pnode->vconstants[i];
String gcode;
@@ -833,6 +856,19 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
} break;
case SL::Node::TYPE_VARIABLE: {
SL::VariableNode *vnode = (SL::VariableNode *)p_node;
+ bool use_fragment_varying = false;
+
+ if (current_func_name != vertex_name) {
+ if (p_assigning) {
+ if (shader->varyings.has(vnode->name)) {
+ use_fragment_varying = true;
+ }
+ } else {
+ if (fragment_varyings.has(vnode->name)) {
+ use_fragment_varying = true;
+ }
+ }
+ }
if (p_assigning && p_actions.write_flag_pointers.has(vnode->name)) {
*p_actions.write_flag_pointers[vnode->name] = true;
@@ -877,7 +913,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}
} else {
- code = _mkid(vnode->name); //its something else (local var most likely) use as is
+ if (use_fragment_varying) {
+ code = "frag_to_light.";
+ }
+ code += _mkid(vnode->name); //its something else (local var most likely) use as is
}
}
@@ -920,7 +959,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
if (adnode->datatype == SL::TYPE_STRUCT) {
declaration += _mkid(adnode->struct_name);
} else {
- declaration = _prestr(adnode->precision) + _typestr(adnode->datatype);
+ declaration += _prestr(adnode->precision) + _typestr(adnode->datatype);
}
for (int i = 0; i < adnode->declarations.size(); i++) {
if (i > 0) {
@@ -930,7 +969,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}
declaration += _mkid(adnode->declarations[i].name);
declaration += "[";
- declaration += itos(adnode->declarations[i].size);
+ if (adnode->size_expression != nullptr) {
+ declaration += _dump_node_code(adnode->size_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ } else {
+ declaration += itos(adnode->declarations[i].size);
+ }
declaration += "]";
int sz = adnode->declarations[i].initializer.size();
if (sz > 0) {
@@ -958,6 +1001,23 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
} break;
case SL::Node::TYPE_ARRAY: {
SL::ArrayNode *anode = (SL::ArrayNode *)p_node;
+ bool use_fragment_varying = false;
+
+ if (current_func_name != vertex_name) {
+ if (anode->assign_expression != nullptr) {
+ use_fragment_varying = true;
+ } else {
+ if (p_assigning) {
+ if (shader->varyings.has(anode->name)) {
+ use_fragment_varying = true;
+ }
+ } else {
+ if (fragment_varyings.has(anode->name)) {
+ use_fragment_varying = true;
+ }
+ }
+ }
+ }
if (p_assigning && p_actions.write_flag_pointers.has(anode->name)) {
*p_actions.write_flag_pointers[anode->name] = true;
@@ -980,18 +1040,22 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
if (p_default_actions.renames.has(anode->name)) {
code = p_default_actions.renames[anode->name];
} else {
- code = _mkid(anode->name);
+ if (use_fragment_varying) {
+ code = "frag_to_light.";
+ }
+ code += _mkid(anode->name);
}
if (anode->call_expression != nullptr) {
code += ".";
code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false);
- }
-
- if (anode->index_expression != nullptr) {
+ } else if (anode->index_expression != nullptr) {
code += "[";
code += _dump_node_code(anode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "]";
+ } else if (anode->assign_expression != nullptr) {
+ code += "=";
+ code += _dump_node_code(anode->assign_expression, p_level, r_gen_code, p_actions, p_default_actions, true, false);
}
if (anode->name == time_name) {
@@ -1229,8 +1293,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += "[";
code += _dump_node_code(mnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "]";
+ } else if (mnode->assign_expression != nullptr) {
+ code += "=";
+ code += _dump_node_code(mnode->assign_expression, p_level, r_gen_code, p_actions, p_default_actions, true, false);
}
-
} break;
}
@@ -1270,6 +1336,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide
used_name_defines.clear();
used_rmode_defines.clear();
used_flag_pointers.clear();
+ fragment_varyings.clear();
shader = parser.get_shader();
function = nullptr;
@@ -1333,8 +1400,8 @@ ShaderCompilerRD::ShaderCompilerRD() {
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["NORMAL_MAP"] = "normal_map";
+ actions[RS::SHADER_SPATIAL].renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
actions[RS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo";
actions[RS::SHADER_SPATIAL].renames["ALPHA"] = "alpha";
actions[RS::SHADER_SPATIAL].renames["METALLIC"] = "metallic";
@@ -1380,8 +1447,8 @@ ShaderCompilerRD::ShaderCompilerRD() {
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["NORMAL_MAP"] = "#define ENABLE_NORMAL_MAP\n";
+ actions[RS::SHADER_SPATIAL].usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP";
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";
@@ -1401,7 +1468,7 @@ ShaderCompilerRD::ShaderCompilerRD() {
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");
+ bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley");
if (!force_lambert) {
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
@@ -1411,7 +1478,7 @@ ShaderCompilerRD::ShaderCompilerRD() {
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");
+ bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx");
if (!force_blinn) {
actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.h b/servers/rendering/renderer_rd/shader_compiler_rd.h
index 694f8fff91..6575829e73 100644
--- a/servers/rendering/renderer_rd/shader_compiler_rd.h
+++ b/servers/rendering/renderer_rd/shader_compiler_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -114,6 +114,7 @@ private:
Set<StringName> used_flag_pointers;
Set<StringName> used_rmode_defines;
Set<StringName> internal_functions;
+ Set<StringName> fragment_varyings;
DefaultIdentifierActions actions;
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 41126218ae..e4a39ff813 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -301,6 +301,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
builder.append(compute_codev.get_data()); // version info (if exists)
builder.append("\n"); //make sure defines begin at newline
+ builder.append(base_compute_defines.get_data());
builder.append(general_defines.get_data());
builder.append(variant_defines[p_variant].get_data());
@@ -351,6 +352,127 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
}
}
+RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_version) {
+ Version *version = version_owner.getornull(p_version);
+ RS::ShaderNativeSourceCode source_code;
+ ERR_FAIL_COND_V(!version, source_code);
+
+ source_code.versions.resize(variant_defines.size());
+
+ for (int i = 0; i < source_code.versions.size(); i++) {
+ if (!is_compute) {
+ //vertex stage
+
+ StringBuilder builder;
+
+ builder.append(vertex_codev.get_data()); // version info (if exists)
+ builder.append("\n"); //make sure defines begin at newline
+ builder.append(general_defines.get_data());
+ builder.append(variant_defines[i].get_data());
+
+ for (int j = 0; j < version->custom_defines.size(); j++) {
+ builder.append(version->custom_defines[j].get_data());
+ }
+
+ builder.append(vertex_code0.get_data()); //first part of vertex
+
+ builder.append(version->uniforms.get_data()); //uniforms (same for vertex and fragment)
+
+ builder.append(vertex_code1.get_data()); //second part of vertex
+
+ builder.append(version->vertex_globals.get_data()); // vertex globals
+
+ builder.append(vertex_code2.get_data()); //third part of vertex
+
+ builder.append(version->vertex_code.get_data()); // code
+
+ builder.append(vertex_code3.get_data()); //fourth of vertex
+
+ RS::ShaderNativeSourceCode::Version::Stage stage;
+ stage.name = "vertex";
+ stage.code = builder.as_string();
+
+ source_code.versions.write[i].stages.push_back(stage);
+ }
+
+ if (!is_compute) {
+ //fragment stage
+
+ StringBuilder builder;
+
+ builder.append(fragment_codev.get_data()); // version info (if exists)
+ builder.append("\n"); //make sure defines begin at newline
+ builder.append(general_defines.get_data());
+ builder.append(variant_defines[i].get_data());
+ for (int j = 0; j < version->custom_defines.size(); j++) {
+ builder.append(version->custom_defines[j].get_data());
+ }
+
+ builder.append(fragment_code0.get_data()); //first part of fragment
+
+ builder.append(version->uniforms.get_data()); //uniforms (same for fragment and fragment)
+
+ builder.append(fragment_code1.get_data()); //first part of fragment
+
+ builder.append(version->fragment_globals.get_data()); // fragment globals
+
+ builder.append(fragment_code2.get_data()); //third part of fragment
+
+ builder.append(version->fragment_light.get_data()); // fragment light
+
+ builder.append(fragment_code3.get_data()); //fourth part of fragment
+
+ builder.append(version->fragment_code.get_data()); // fragment code
+
+ builder.append(fragment_code4.get_data()); //fourth part of fragment
+
+ RS::ShaderNativeSourceCode::Version::Stage stage;
+ stage.name = "fragment";
+ stage.code = builder.as_string();
+
+ source_code.versions.write[i].stages.push_back(stage);
+ }
+
+ if (is_compute) {
+ //compute stage
+
+ StringBuilder builder;
+
+ builder.append(compute_codev.get_data()); // version info (if exists)
+ builder.append("\n"); //make sure defines begin at newline
+ builder.append(base_compute_defines.get_data());
+ builder.append(general_defines.get_data());
+ builder.append(variant_defines[i].get_data());
+
+ for (int j = 0; j < version->custom_defines.size(); j++) {
+ builder.append(version->custom_defines[j].get_data());
+ }
+
+ builder.append(compute_code0.get_data()); //first part of compute
+
+ builder.append(version->uniforms.get_data()); //uniforms (same for compute and fragment)
+
+ builder.append(compute_code1.get_data()); //second part of compute
+
+ builder.append(version->compute_globals.get_data()); // compute globals
+
+ builder.append(compute_code2.get_data()); //third part of compute
+
+ builder.append(version->compute_code.get_data()); // code
+
+ builder.append(compute_code3.get_data()); //fourth of compute
+
+ RS::ShaderNativeSourceCode::Version::Stage stage;
+ stage.name = "compute";
+ stage.code = builder.as_string();
+
+ source_code.versions.write[i].stages.push_back(stage);
+ }
+ }
+
+ return source_code;
+}
+
void ShaderRD::_compile_version(Version *p_version) {
_clear_version(p_version);
@@ -360,7 +482,7 @@ void ShaderRD::_compile_version(Version *p_version) {
p_version->variants = memnew_arr(RID, variant_defines.size());
#if 1
- RendererCompositorRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version);
+ RendererThreadPool::singleton->thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version);
#else
for (int i = 0; i < variant_defines.size(); i++) {
_compile_variant(i, p_version);
@@ -475,6 +597,22 @@ bool ShaderRD::is_variant_enabled(int p_variant) const {
return variants_enabled[p_variant];
}
+ShaderRD::ShaderRD() {
+ // Do not feel forced to use this, in most cases it makes little to no difference.
+ bool use_32_threads = false;
+ if (RD::get_singleton()->get_device_vendor_name() == "NVIDIA") {
+ use_32_threads = true;
+ }
+ String base_compute_define_text;
+ if (use_32_threads) {
+ base_compute_define_text = "\n#define NATIVE_LOCAL_GROUP_SIZE 32\n#define NATIVE_LOCAL_SIZE_2D_X 8\n#define NATIVE_LOCAL_SIZE_2D_Y 4\n";
+ } else {
+ base_compute_define_text = "\n#define NATIVE_LOCAL_GROUP_SIZE 64\n#define NATIVE_LOCAL_SIZE_2D_X 8\n#define NATIVE_LOCAL_SIZE_2D_Y 8\n";
+ }
+
+ base_compute_defines = base_compute_define_text.ascii();
+}
+
void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) {
ERR_FAIL_COND(variant_defines.size());
ERR_FAIL_COND(p_variant_defines.size() == 0);
diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h
index 05e07d3cf3..e0f4dcf2d0 100644
--- a/servers/rendering/renderer_rd/shader_rd.h
+++ b/servers/rendering/renderer_rd/shader_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,6 +36,7 @@
#include "core/templates/map.h"
#include "core/templates/rid_owner.h"
#include "core/variant/variant.h"
+#include "servers/rendering_server.h"
#include <stdio.h>
/**
@@ -98,8 +99,10 @@ class ShaderRD {
const char *name;
+ CharString base_compute_defines;
+
protected:
- ShaderRD() {}
+ ShaderRD();
void setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name);
public:
@@ -133,6 +136,8 @@ public:
void set_variant_enabled(int p_variant, bool p_enabled);
bool is_variant_enabled(int p_variant) const;
+ RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version);
+
void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = "");
virtual ~ShaderRD();
};
diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub
index deaa9668df..0f85e3fa30 100644
--- a/servers/rendering/renderer_rd/shaders/SCsub
+++ b/servers/rendering/renderer_rd/shaders/SCsub
@@ -11,7 +11,7 @@ if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("cubemap_roughness.glsl")
env.RD_GLSL("cubemap_downsampler.glsl")
env.RD_GLSL("cubemap_filter.glsl")
- env.RD_GLSL("scene_forward.glsl")
+ env.RD_GLSL("scene_forward_clustered.glsl")
env.RD_GLSL("sky.glsl")
env.RD_GLSL("tonemap.glsl")
env.RD_GLSL("cube_to_dp.glsl")
@@ -39,8 +39,10 @@ if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("sdfgi_debug.glsl")
env.RD_GLSL("sdfgi_debug_probes.glsl")
env.RD_GLSL("volumetric_fog.glsl")
- env.RD_GLSL("shadow_reduce.glsl")
env.RD_GLSL("particles.glsl")
env.RD_GLSL("particles_copy.glsl")
env.RD_GLSL("sort.glsl")
env.RD_GLSL("skeleton.glsl")
+ env.RD_GLSL("cluster_render.glsl")
+ env.RD_GLSL("cluster_store.glsl")
+ env.RD_GLSL("cluster_debug.glsl")
diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index 7808e7ed52..3b39edc70e 100644
--- a/servers/rendering/renderer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -396,7 +396,7 @@ vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv
vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color);
#ifdef LIGHT_SHADER_CODE_USED
- shadow_color *= shadow_modulate;
+ shadow_color.rgb *= shadow_modulate;
#endif
shadow_color.a *= light_color.a; //respect light alpha
@@ -497,9 +497,9 @@ void main() {
vec2 shadow_vertex = vertex;
{
- float normal_depth = 1.0;
+ float normal_map_depth = 1.0;
-#if defined(NORMALMAP_USED)
+#if defined(NORMAL_MAP_USED)
vec3 normal_map = vec3(0.0, 0.0, 1.0);
normal_used = true;
#endif
@@ -510,8 +510,8 @@ FRAGMENT_SHADER_CODE
/* 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);
+#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
}
@@ -546,7 +546,7 @@ FRAGMENT_SHADER_CODE
#ifdef LIGHT_SHADER_CODE_USED
vec4 shadow_modulate = vec4(1.0);
- light_color = light_compute(light_vertex, direction, normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, true);
+ light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true);
#else
if (normal_used) {
@@ -563,7 +563,7 @@ FRAGMENT_SHADER_CODE
light_color = light_shadow_compute(light_base, light_color, shadow_uv
#ifdef LIGHT_SHADER_CODE_USED
,
- shadow_modulate
+ shadow_modulate.rgb
#endif
);
}
@@ -605,7 +605,7 @@ FRAGMENT_SHADER_CODE
vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height);
light_color.rgb *= light_base_color.rgb;
- light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, color, uv, false);
+ light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false);
#else
light_color.rgb *= light_base_color.rgb * light_base_color.a;
@@ -659,7 +659,7 @@ FRAGMENT_SHADER_CODE
light_color = light_shadow_compute(light_base, light_color, shadow_uv
#ifdef LIGHT_SHADER_CODE_USED
,
- shadow_modulate
+ shadow_modulate.rgb
#endif
);
}
diff --git a/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl b/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl
index e723468dd8..3a4bf4da07 100644
--- a/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/cluster_data_inc.glsl
@@ -6,12 +6,18 @@
struct LightData { //this structure needs to be as packed as possible
vec3 position;
float inv_radius;
+
vec3 direction;
float size;
- uint attenuation_energy; //attenuation
- uint color_specular; //rgb color, a specular (8 bit unorm)
- uint cone_attenuation_angle; // attenuation and angle, (16bit float)
- uint shadow_color_enabled; //shadow rgb color, a>0.5 enabled (8bit unorm)
+
+ vec3 color;
+ float attenuation;
+
+ float cone_attenuation;
+ float cone_angle;
+ float specular_amount;
+ bool shadow_enabled;
+
vec4 atlas_rect; // rect in the shadow atlas
mat4 shadow_matrix;
float shadow_bias;
@@ -34,9 +40,13 @@ struct ReflectionData {
float index;
vec3 box_offset;
uint mask;
- vec4 params; // intensity, 0, interior , boxproject
vec3 ambient; // ambient color
+ float intensity;
+ bool exterior;
+ bool box_project;
uint ambient_mode;
+ uint pad;
+ //0-8 is intensity,8-9 is ambient, mode
mat4 local_matrix; // up to here for spot and omni, rest is for directional
// notes: for ambientblend, use distance to edge to blend between already existing global environment
};
diff --git a/servers/rendering/renderer_rd/shaders/cluster_debug.glsl b/servers/rendering/renderer_rd/shaders/cluster_debug.glsl
new file mode 100644
index 0000000000..70a875192c
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/cluster_debug.glsl
@@ -0,0 +1,115 @@
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+const vec3 usage_gradient[33] = vec3[]( // 1 (none) + 32
+ vec3(0.14, 0.17, 0.23),
+ vec3(0.24, 0.44, 0.83),
+ vec3(0.23, 0.57, 0.84),
+ vec3(0.22, 0.71, 0.84),
+ vec3(0.22, 0.85, 0.83),
+ vec3(0.21, 0.85, 0.72),
+ vec3(0.21, 0.85, 0.57),
+ vec3(0.20, 0.85, 0.42),
+ vec3(0.20, 0.85, 0.27),
+ vec3(0.27, 0.86, 0.19),
+ vec3(0.51, 0.85, 0.19),
+ vec3(0.57, 0.86, 0.19),
+ vec3(0.62, 0.85, 0.19),
+ vec3(0.67, 0.86, 0.20),
+ vec3(0.73, 0.85, 0.20),
+ vec3(0.78, 0.85, 0.20),
+ vec3(0.83, 0.85, 0.20),
+ vec3(0.85, 0.82, 0.20),
+ vec3(0.85, 0.76, 0.20),
+ vec3(0.85, 0.81, 0.20),
+ vec3(0.85, 0.65, 0.20),
+ vec3(0.84, 0.60, 0.21),
+ vec3(0.84, 0.56, 0.21),
+ vec3(0.84, 0.51, 0.21),
+ vec3(0.84, 0.46, 0.21),
+ vec3(0.84, 0.41, 0.21),
+ vec3(0.84, 0.36, 0.21),
+ vec3(0.84, 0.31, 0.21),
+ vec3(0.84, 0.27, 0.21),
+ vec3(0.83, 0.22, 0.22),
+ vec3(0.83, 0.22, 0.27),
+ vec3(0.83, 0.22, 0.32),
+ vec3(1.00, 0.63, 0.70));
+layout(push_constant, binding = 0, std430) uniform Params {
+ uvec2 screen_size;
+ uvec2 cluster_screen_size;
+
+ uint cluster_shift;
+ uint cluster_type;
+ float z_near;
+ float z_far;
+
+ bool orthogonal;
+ uint max_cluster_element_count_div_32;
+ uint pad1;
+ uint pad2;
+}
+params;
+
+layout(set = 0, binding = 1, std430) buffer restrict readonly ClusterData {
+ uint data[];
+}
+cluster_data;
+
+layout(rgba16f, set = 0, binding = 2) uniform restrict writeonly image2D screen_buffer;
+layout(set = 0, binding = 3) uniform texture2D depth_buffer;
+layout(set = 0, binding = 4) uniform sampler depth_buffer_sampler;
+
+void main() {
+ uvec2 screen_pos = gl_GlobalInvocationID.xy;
+ if (any(greaterThanEqual(screen_pos, params.screen_size))) {
+ return;
+ }
+
+ uvec2 cluster_pos = screen_pos >> params.cluster_shift;
+
+ uint offset = cluster_pos.y * params.cluster_screen_size.x + cluster_pos.x;
+ offset += params.cluster_screen_size.x * params.cluster_screen_size.y * params.cluster_type;
+ offset *= (params.max_cluster_element_count_div_32 + 32);
+
+ //depth buffers generally can't be accessed via image API
+ float depth = texelFetch(sampler2D(depth_buffer, depth_buffer_sampler), ivec2(screen_pos), 0).r * 2.0 - 1.0;
+
+ if (params.orthogonal) {
+ depth = ((depth + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
+ } else {
+ depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
+ }
+ depth /= params.z_far;
+
+ uint slice = uint(clamp(floor(depth * 32.0), 0.0, 31.0));
+ uint slice_minmax = cluster_data.data[offset + params.max_cluster_element_count_div_32 + slice];
+ uint item_min = slice_minmax & 0xFFFF;
+ uint item_max = slice_minmax >> 16;
+
+ uint item_count = 0;
+ for (uint i = 0; i < params.max_cluster_element_count_div_32; i++) {
+ uint slice_bits = cluster_data.data[offset + i];
+ while (slice_bits != 0) {
+ uint bit = findLSB(slice_bits);
+ uint item = i * 32 + bit;
+ if ((item >= item_min && item < item_max)) {
+ item_count++;
+ }
+ slice_bits &= ~(1 << bit);
+ }
+ }
+
+ item_count = min(item_count, 32);
+
+ vec3 color = usage_gradient[item_count];
+
+ color = mix(color * 1.2, color * 0.3, float(slice) / 31.0);
+
+ imageStore(screen_buffer, ivec2(screen_pos), vec4(color, 1.0));
+}
diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl
new file mode 100644
index 0000000000..8723ea78e4
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl
@@ -0,0 +1,168 @@
+#[vertex]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(location = 0) in vec3 vertex_attrib;
+
+layout(location = 0) out float depth_interp;
+layout(location = 1) out flat uint element_index;
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ uint base_index;
+ uint pad0;
+ uint pad1;
+ uint pad2;
+}
+params;
+
+layout(set = 0, binding = 1, std140) uniform State {
+ mat4 projection;
+
+ float inv_z_far;
+ uint screen_to_clusters_shift; // shift to obtain coordinates in block indices
+ uint cluster_screen_width; //
+ uint cluster_data_size; // how much data for a single cluster takes
+
+ uint cluster_depth_offset;
+ uint pad0;
+ uint pad1;
+ uint pad2;
+}
+state;
+
+struct RenderElement {
+ uint type; //0-4
+ bool touches_near;
+ bool touches_far;
+ uint original_index;
+ mat3x4 transform_inv;
+ vec3 scale;
+ uint pad;
+};
+
+layout(set = 0, binding = 2, std430) buffer restrict readonly RenderElements {
+ RenderElement data[];
+}
+render_elements;
+
+void main() {
+ element_index = params.base_index + gl_InstanceIndex;
+
+ vec3 vertex = vertex_attrib;
+ vertex *= render_elements.data[element_index].scale;
+
+ vertex = vec4(vertex, 1.0) * render_elements.data[element_index].transform_inv;
+ depth_interp = -vertex.z;
+
+ gl_Position = state.projection * vec4(vertex, 1.0);
+}
+
+#[fragment]
+
+#version 450
+
+VERSION_DEFINES
+
+#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic) && defined(GL_KHR_shader_subgroup_vote)
+
+#extension GL_KHR_shader_subgroup_ballot : enable
+#extension GL_KHR_shader_subgroup_arithmetic : enable
+#extension GL_KHR_shader_subgroup_vote : enable
+
+#define USE_SUBGROUPS
+#endif
+
+layout(location = 0) in float depth_interp;
+layout(location = 1) in flat uint element_index;
+
+layout(set = 0, binding = 1, std140) uniform State {
+ mat4 projection;
+ float inv_z_far;
+ uint screen_to_clusters_shift; // shift to obtain coordinates in block indices
+ uint cluster_screen_width; //
+ uint cluster_data_size; // how much data for a single cluster takes
+ uint cluster_depth_offset;
+ uint pad0;
+ uint pad1;
+ uint pad2;
+}
+state;
+
+//cluster data is layout linearly, each cell contains the follow information:
+// - list of bits for every element to mark as used, so (max_elem_count/32)*4 uints
+// - a uint for each element to mark the depth bits used when rendering (0-31)
+
+layout(set = 0, binding = 3, std430) buffer restrict ClusterRender {
+ uint data[];
+}
+cluster_render;
+
+void main() {
+ //convert from screen to cluster
+ uvec2 cluster = uvec2(gl_FragCoord.xy) >> state.screen_to_clusters_shift;
+
+ //get linear cluster offset from screen poss
+ uint cluster_offset = cluster.x + state.cluster_screen_width * cluster.y;
+ //multiply by data size to position at the beginning of the element list for this cluster
+ cluster_offset *= state.cluster_data_size;
+
+ //find the current element in the list and plot the bit to mark it as used
+ uint usage_write_offset = cluster_offset + (element_index >> 5);
+ uint usage_write_bit = 1 << (element_index & 0x1F);
+
+#ifdef USE_SUBGROUPS
+
+ uint cluster_thread_group_index;
+
+ if (!gl_HelperInvocation) {
+ //http://advances.realtimerendering.com/s2017/2017_Sig_Improved_Culling_final.pdf
+
+ uvec4 mask;
+
+ while (true) {
+ // find the cluster offset of the first active thread
+ // threads that did break; go inactive and no longer count
+ uint first = subgroupBroadcastFirst(cluster_offset);
+ // update the mask for thread that match this cluster
+ mask = subgroupBallot(first == cluster_offset);
+ if (first == cluster_offset) {
+ // This thread belongs to the group of threads that match this offset,
+ // so exit the loop.
+ break;
+ }
+ }
+
+ cluster_thread_group_index = subgroupBallotExclusiveBitCount(mask);
+
+ if (cluster_thread_group_index == 0) {
+ atomicOr(cluster_render.data[usage_write_offset], usage_write_bit);
+ }
+ }
+#else
+ if (!gl_HelperInvocation) {
+ atomicOr(cluster_render.data[usage_write_offset], usage_write_bit);
+ }
+#endif
+ //find the current element in the depth usage list and mark the current depth as used
+ float unit_depth = depth_interp * state.inv_z_far;
+
+ uint z_bit = clamp(uint(floor(unit_depth * 32.0)), 0, 31);
+
+ uint z_write_offset = cluster_offset + state.cluster_depth_offset + element_index;
+ uint z_write_bit = 1 << z_bit;
+
+#ifdef USE_SUBGROUPS
+ if (!gl_HelperInvocation) {
+ z_write_bit = subgroupOr(z_write_bit); //merge all Zs
+ if (cluster_thread_group_index == 0) {
+ atomicOr(cluster_render.data[z_write_offset], z_write_bit);
+ }
+ }
+#else
+ if (!gl_HelperInvocation) {
+ atomicOr(cluster_render.data[z_write_offset], z_write_bit);
+ }
+#endif
+}
diff --git a/servers/rendering/renderer_rd/shaders/cluster_store.glsl b/servers/rendering/renderer_rd/shaders/cluster_store.glsl
new file mode 100644
index 0000000000..5be0893c4f
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/cluster_store.glsl
@@ -0,0 +1,119 @@
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ uint cluster_render_data_size; // how much data for a single cluster takes
+ uint max_render_element_count_div_32; //divided by 32
+ uvec2 cluster_screen_size;
+ uint render_element_count_div_32; //divided by 32
+
+ uint max_cluster_element_count_div_32; //divided by 32
+ uint pad1;
+ uint pad2;
+}
+params;
+
+layout(set = 0, binding = 1, std430) buffer restrict readonly ClusterRender {
+ uint data[];
+}
+cluster_render;
+
+layout(set = 0, binding = 2, std430) buffer restrict ClusterStore {
+ uint data[];
+}
+cluster_store;
+
+struct RenderElement {
+ uint type; //0-4
+ bool touches_near;
+ bool touches_far;
+ uint original_index;
+ mat3x4 transform_inv;
+ vec3 scale;
+ uint pad;
+};
+
+layout(set = 0, binding = 3, std430) buffer restrict readonly RenderElements {
+ RenderElement data[];
+}
+render_elements;
+
+void main() {
+ uvec2 pos = gl_GlobalInvocationID.xy;
+ if (any(greaterThanEqual(pos, params.cluster_screen_size))) {
+ return;
+ }
+
+ //counter for each type of render_element
+
+ //base offset for this cluster
+ uint base_offset = (pos.x + params.cluster_screen_size.x * pos.y);
+ uint src_offset = base_offset * params.cluster_render_data_size;
+
+ uint render_element_offset = 0;
+
+ //check all render_elements and see which one was written to
+ while (render_element_offset < params.render_element_count_div_32) {
+ uint bits = cluster_render.data[src_offset + render_element_offset];
+ while (bits != 0) {
+ //if bits exist, check the render_element
+ uint index_bit = findLSB(bits);
+ uint index = render_element_offset * 32 + index_bit;
+ uint type = render_elements.data[index].type;
+
+ uint z_range_offset = src_offset + params.max_render_element_count_div_32 + index;
+ uint z_range = cluster_render.data[z_range_offset];
+
+ //if object was written, z was written, but check just in case
+ if (z_range != 0) { //should always be > 0
+
+ uint from_z = findLSB(z_range);
+ uint to_z = findMSB(z_range) + 1;
+
+ if (render_elements.data[index].touches_near) {
+ from_z = 0;
+ }
+
+ if (render_elements.data[index].touches_far) {
+ to_z = 32;
+ }
+
+ // find cluster offset in the buffer used for indexing in the renderer
+ uint dst_offset = (base_offset + type * (params.cluster_screen_size.x * params.cluster_screen_size.y)) * (params.max_cluster_element_count_div_32 + 32);
+
+ uint orig_index = render_elements.data[index].original_index;
+ //store this index in the Z slices by setting the relevant bit
+ for (uint i = from_z; i < to_z; i++) {
+ uint slice_ofs = dst_offset + params.max_cluster_element_count_div_32 + i;
+
+ uint minmax = cluster_store.data[slice_ofs];
+
+ if (minmax == 0) {
+ minmax = 0xFFFF; //min 0, max 0xFFFF
+ }
+
+ uint elem_min = min(orig_index, minmax & 0xFFFF);
+ uint elem_max = max(orig_index + 1, minmax >> 16); //always store plus one, so zero means range is empty when not written to
+
+ minmax = elem_min | (elem_max << 16);
+ cluster_store.data[slice_ofs] = minmax;
+ }
+
+ uint store_word = orig_index >> 5;
+ uint store_bit = orig_index & 0x1F;
+
+ //store the actual render_element index at the end, so the rendering code can reference it
+ cluster_store.data[dst_offset + store_word] |= 1 << store_bit;
+ }
+
+ bits &= ~(1 << index_bit); //clear the bit to continue iterating
+ }
+
+ render_element_offset++;
+ }
+}
diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl
index 54d67db6c6..c3ac0bee57 100644
--- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl
+++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl
@@ -1,33 +1,48 @@
-#[compute]
+#[vertex]
#version 450
VERSION_DEFINES
-layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+layout(push_constant, binding = 1, std430) uniform Params {
+ float z_far;
+ float z_near;
+ bool z_flip;
+ uint pad;
+ vec4 screen_rect;
+}
+params;
+
+layout(location = 0) out vec2 uv_interp;
+
+void main() {
+ vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
+ uv_interp = base_arr[gl_VertexIndex];
+ vec2 screen_pos = uv_interp * params.screen_rect.zw + params.screen_rect.xy;
+ gl_Position = vec4(screen_pos * 2.0 - 1.0, 0.0, 1.0);
+}
+
+#[fragment]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(location = 0) in vec2 uv_interp;
layout(set = 0, binding = 0) uniform samplerCube source_cube;
layout(push_constant, binding = 1, std430) uniform Params {
- ivec2 screen_size;
- ivec2 offset;
- float bias;
float z_far;
float z_near;
bool z_flip;
+ uint pad;
+ vec4 screen_rect;
}
params;
-layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer;
-
void main() {
- ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing
- return;
- }
-
- vec2 pixel_size = 1.0 / vec2(params.screen_size);
- vec2 uv = (vec2(pos) + 0.5) * pixel_size;
+ vec2 uv = uv_interp;
vec3 normal = vec3(uv * 2.0 - 1.0, 0.0);
@@ -65,5 +80,5 @@ void main() {
float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
depth = (linear_depth * depth_fix) / params.z_far;
- imageStore(depth_buffer, pos + params.offset, vec4(depth));
+ gl_FragDepth = depth;
}
diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl
index 8011dadc72..92a5682572 100644
--- a/servers/rendering/renderer_rd/shaders/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/gi.glsl
@@ -97,13 +97,12 @@ layout(push_constant, binding = 0, std430) uniform Params {
vec4 proj_info;
+ vec3 ao_color;
uint max_giprobes;
+
bool high_quality_vct;
- bool use_sdfgi;
bool orthogonal;
-
- vec3 ao_color;
- uint pad;
+ uint pad[2];
mat3x4 cam_rotation;
}
@@ -331,7 +330,7 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o
}
ambient_light.rgb = diffuse;
-#if 1
+
if (roughness < 0.2) {
vec3 pos_to_uvw = 1.0 / sdfgi.grid_size;
vec4 light_accum = vec4(0.0);
@@ -363,59 +362,63 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o
//ray_pos += ray_dir * (bias / sdfgi.cascades[cascade].to_cell); //bias to avoid self occlusion
ray_pos += (ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) + cam_normal * 1.4) * bias / sdfgi.cascades[cascade].to_cell;
}
-
float softness = 0.2 + min(1.0, roughness * 5.0) * 4.0; //approximation to roughness so it does not seem like a hard fade
- while (length(ray_pos) < max_distance) {
- for (uint i = 0; i < sdfgi.max_cascades; i++) {
- if (i >= cascade && length(ray_pos) < radius_sizes[i]) {
- cascade = max(i, cascade); //never go down
-
- vec3 pos = ray_pos - sdfgi.cascades[i].position;
- pos *= sdfgi.cascades[i].to_cell * pos_to_uvw;
-
- float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), pos).r * 255.0 - 1.1;
-
- vec4 hit_light = vec4(0.0);
- if (distance < softness) {
- hit_light.rgb = texture(sampler3D(light_cascades[i], linear_sampler), pos).rgb;
- hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
- hit_light.a = clamp(1.0 - (distance / softness), 0.0, 1.0);
- hit_light.rgb *= hit_light.a;
- }
+ uint i = 0;
+ bool found = false;
+ while (true) {
+ if (length(ray_pos) >= max_distance || light_accum.a > 0.99) {
+ break;
+ }
+ if (!found && i >= cascade && length(ray_pos) < radius_sizes[i]) {
+ uint next_i = min(i + 1, sdfgi.max_cascades - 1);
+ cascade = max(i, cascade); //never go down
- distance /= sdfgi.cascades[i].to_cell;
+ vec3 pos = ray_pos - sdfgi.cascades[i].position;
+ pos *= sdfgi.cascades[i].to_cell * pos_to_uvw;
- if (i < (sdfgi.max_cascades - 1)) {
- pos = ray_pos - sdfgi.cascades[i + 1].position;
- pos *= sdfgi.cascades[i + 1].to_cell * pos_to_uvw;
+ float fdistance = textureLod(sampler3D(sdf_cascades[i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
- float distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.1;
+ vec4 hit_light = vec4(0.0);
+ if (fdistance < softness) {
+ hit_light.rgb = textureLod(sampler3D(light_cascades[i], linear_sampler), pos, 0.0).rgb;
+ hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
+ hit_light.a = clamp(1.0 - (fdistance / softness), 0.0, 1.0);
+ hit_light.rgb *= hit_light.a;
+ }
- vec4 hit_light2 = vec4(0.0);
- if (distance2 < softness) {
- hit_light2.rgb = texture(sampler3D(light_cascades[i + 1], linear_sampler), pos).rgb;
- hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
- hit_light2.a = clamp(1.0 - (distance2 / softness), 0.0, 1.0);
- hit_light2.rgb *= hit_light2.a;
- }
+ fdistance /= sdfgi.cascades[i].to_cell;
- float prev_radius = i == 0 ? 0.0 : radius_sizes[i - 1];
- float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0);
+ if (i < (sdfgi.max_cascades - 1)) {
+ pos = ray_pos - sdfgi.cascades[next_i].position;
+ pos *= sdfgi.cascades[next_i].to_cell * pos_to_uvw;
- distance2 /= sdfgi.cascades[i + 1].to_cell;
+ float fdistance2 = textureLod(sampler3D(sdf_cascades[next_i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
- hit_light = mix(hit_light, hit_light2, blend);
- distance = mix(distance, distance2, blend);
+ vec4 hit_light2 = vec4(0.0);
+ if (fdistance2 < softness) {
+ hit_light2.rgb = textureLod(sampler3D(light_cascades[next_i], linear_sampler), pos, 0.0).rgb;
+ hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
+ hit_light2.a = clamp(1.0 - (fdistance2 / softness), 0.0, 1.0);
+ hit_light2.rgb *= hit_light2.a;
}
- light_accum += hit_light;
- ray_pos += ray_dir * distance;
- break;
+ float prev_radius = i == 0 ? 0.0 : radius_sizes[max(0, i - 1)];
+ float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0);
+
+ fdistance2 /= sdfgi.cascades[next_i].to_cell;
+
+ hit_light = mix(hit_light, hit_light2, blend);
+ fdistance = mix(fdistance, fdistance2, blend);
}
- }
- if (light_accum.a > 0.99) {
- break;
+ light_accum += hit_light;
+ ray_pos += ray_dir * fdistance;
+ found = true;
+ }
+ i++;
+ if (i == sdfgi.max_cascades) {
+ i = 0;
+ found = false;
}
}
@@ -434,8 +437,6 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o
}
}
-#endif
-
reflection_light.rgb = specular;
ambient_light.rgb *= sdfgi.energy;
@@ -597,35 +598,24 @@ vec4 fetch_normal_and_roughness(ivec2 pos) {
return normal_roughness;
}
-void main() {
- // Pixel being shaded
- ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing
- return;
- }
-
- vec3 vertex = reconstruct_position(pos);
- vertex.y = -vertex.y;
-
+void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 reflection_light) {
vec4 normal_roughness = fetch_normal_and_roughness(pos);
- vec3 normal = normal_roughness.xyz;
- vec4 ambient_light = vec4(0.0), reflection_light = vec4(0.0);
+ vec3 normal = normal_roughness.xyz;
if (normal.length() > 0.5) {
//valid normal, can do GI
float roughness = normal_roughness.w;
-
vertex = mat3(params.cam_rotation) * vertex;
normal = normalize(mat3(params.cam_rotation) * normal);
-
vec3 reflection = normalize(reflect(normalize(vertex), normal));
- if (params.use_sdfgi) {
- sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light);
- }
+#ifdef USE_SDFGI
+ sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light);
+#endif
- if (params.max_giprobes > 0) {
+#ifdef USE_GIPROBES
+ {
uvec2 giprobe_tex = texelFetch(usampler2D(giprobe_buffer, linear_sampler), pos, 0).rg;
roughness *= roughness;
//find arbitrary tangent and bitangent, then build a matrix
@@ -648,16 +638,40 @@ void main() {
spec_accum /= blend_accum;
}
- if (params.use_sdfgi) {
- reflection_light = blend_color(spec_accum, reflection_light);
- ambient_light = blend_color(amb_accum, ambient_light);
- } else {
- reflection_light = spec_accum;
- ambient_light = amb_accum;
- }
+#ifdef USE_SDFGI
+ reflection_light = blend_color(spec_accum, reflection_light);
+ ambient_light = blend_color(amb_accum, ambient_light);
+#else
+ reflection_light = spec_accum;
+ ambient_light = amb_accum;
+#endif
}
+#endif
+ }
+}
+
+void main() {
+ ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+
+#ifdef MODE_HALF_RES
+ pos <<= 1;
+#endif
+ if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing
+ return;
}
+ vec4 ambient_light = vec4(0.0);
+ vec4 reflection_light = vec4(0.0);
+
+ vec3 vertex = reconstruct_position(pos);
+ vertex.y = -vertex.y;
+
+ process_gi(pos, vertex, ambient_light, reflection_light);
+
+#ifdef MODE_HALF_RES
+ pos >>= 1;
+#endif
+
imageStore(ambient_buffer, pos, ambient_light);
imageStore(reflection_buffer, pos, reflection_light);
}
diff --git a/servers/rendering/renderer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/giprobe.glsl
index ea4237a45e..b931461b31 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe.glsl
@@ -51,10 +51,10 @@ struct Light {
float attenuation;
vec3 color;
- float spot_angle_radians;
+ float cos_spot_angle;
vec3 position;
- float spot_attenuation;
+ float inv_spot_attenuation;
vec3 direction;
bool has_shadow;
@@ -208,6 +208,15 @@ float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
return occlusion; //max(0.0,distance);
}
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 light_pos) {
if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) {
light_pos = pos - lights.data[light].direction * length(vec3(params.limits));
@@ -220,17 +229,19 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3
return false;
}
- attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation);
+ attenuation = get_omni_attenuation(distance, 1.0 / lights.data[light].radius, lights.data[light].attenuation);
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
vec3 rel = normalize(pos - light_pos);
- float angle = acos(dot(rel, lights.data[light].direction));
- if (angle > lights.data[light].spot_angle_radians) {
+ float cos_spot_angle = lights.data[light].cos_spot_angle;
+ float cos_angle = dot(rel, lights.data[light].direction);
+ if (cos_angle < cos_spot_angle) {
return false;
}
- float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
- attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation);
+ float scos = max(cos_angle, cos_spot_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
+ attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation);
}
}
diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
index 9c794f1bcc..56b3b7ccb4 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
@@ -43,10 +43,10 @@ struct Light {
float attenuation;
vec3 color;
- float spot_angle_radians;
+ float cos_spot_angle;
vec3 position;
- float spot_attenuation;
+ float inv_spot_attenuation;
vec3 direction;
bool has_shadow;
@@ -146,13 +146,15 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
vec3 rel = normalize(pos - light_pos);
- float angle = acos(dot(rel, lights.data[light].direction));
- if (angle > lights.data[light].spot_angle_radians) {
+ float cos_spot_angle = lights.data[light].cos_spot_angle;
+ float cos_angle = dot(rel, lights.data[light].direction);
+ if (cos_angle < cos_spot_angle) {
return false;
}
- float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
- attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation);
+ float scos = max(cos_angle, cos_spot_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
+ attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation);
}
}
diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl
index 926c7ef9fc..cb6d8dc7f6 100644
--- a/servers/rendering/renderer_rd/shaders/particles.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles.glsl
@@ -173,7 +173,7 @@ uint hash(uint x) {
return x;
}
-bool emit_particle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom, uint p_flags) {
+bool emit_subparticle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom, uint p_flags) {
if (!params.can_emit) {
return false;
}
diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl
index 9429a66dc9..e83c4ca93b 100644
--- a/servers/rendering/renderer_rd/shaders/resolve.glsl
+++ b/servers/rendering/renderer_rd/shaders/resolve.glsl
@@ -58,6 +58,116 @@ void main() {
#else
+#if 1
+
+ vec4 group1;
+ vec4 group2;
+ vec4 group3;
+ vec4 group4;
+ int best_index = 0;
+
+ //2X
+ group1.x = texelFetch(source_depth, pos, 0).r;
+ group1.y = texelFetch(source_depth, pos, 1).r;
+
+ //4X
+ if (params.sample_count >= 4) {
+ group1.z = texelFetch(source_depth, pos, 2).r;
+ group1.w = texelFetch(source_depth, pos, 3).r;
+ }
+ //8X
+ if (params.sample_count >= 8) {
+ group2.x = texelFetch(source_depth, pos, 4).r;
+ group2.y = texelFetch(source_depth, pos, 5).r;
+ group2.z = texelFetch(source_depth, pos, 6).r;
+ group2.w = texelFetch(source_depth, pos, 7).r;
+ }
+ //16X
+ if (params.sample_count >= 16) {
+ group3.x = texelFetch(source_depth, pos, 8).r;
+ group3.y = texelFetch(source_depth, pos, 9).r;
+ group3.z = texelFetch(source_depth, pos, 10).r;
+ group3.w = texelFetch(source_depth, pos, 11).r;
+
+ group4.x = texelFetch(source_depth, pos, 12).r;
+ group4.y = texelFetch(source_depth, pos, 13).r;
+ group4.z = texelFetch(source_depth, pos, 14).r;
+ group4.w = texelFetch(source_depth, pos, 15).r;
+ }
+
+ if (params.sample_count == 2) {
+ best_index = (pos.x & 1) ^ ((pos.y >> 1) & 1); //not much can be done here
+ } else if (params.sample_count == 4) {
+ vec4 freq = vec4(equal(group1, vec4(group1.x)));
+ freq += vec4(equal(group1, vec4(group1.y)));
+ freq += vec4(equal(group1, vec4(group1.z)));
+ freq += vec4(equal(group1, vec4(group1.w)));
+
+ float min_f = freq.x;
+ best_index = 0;
+ if (freq.y < min_f) {
+ best_index = 1;
+ min_f = freq.y;
+ }
+ if (freq.z < min_f) {
+ best_index = 2;
+ min_f = freq.z;
+ }
+ if (freq.w < min_f) {
+ best_index = 3;
+ }
+ } else if (params.sample_count == 8) {
+ vec4 freq0 = vec4(equal(group1, vec4(group1.x)));
+ vec4 freq1 = vec4(equal(group2, vec4(group1.x)));
+ freq0 += vec4(equal(group1, vec4(group1.y)));
+ freq1 += vec4(equal(group2, vec4(group1.y)));
+ freq0 += vec4(equal(group1, vec4(group1.z)));
+ freq1 += vec4(equal(group2, vec4(group1.z)));
+ freq0 += vec4(equal(group1, vec4(group1.w)));
+ freq1 += vec4(equal(group2, vec4(group1.w)));
+ freq0 += vec4(equal(group1, vec4(group2.x)));
+ freq1 += vec4(equal(group2, vec4(group2.x)));
+ freq0 += vec4(equal(group1, vec4(group2.y)));
+ freq1 += vec4(equal(group2, vec4(group2.y)));
+ freq0 += vec4(equal(group1, vec4(group2.z)));
+ freq1 += vec4(equal(group2, vec4(group2.z)));
+ freq0 += vec4(equal(group1, vec4(group2.w)));
+ freq1 += vec4(equal(group2, vec4(group2.w)));
+
+ float min_f0 = freq0.x;
+ int best_index0 = 0;
+ if (freq0.y < min_f0) {
+ best_index0 = 1;
+ min_f0 = freq0.y;
+ }
+ if (freq0.z < min_f0) {
+ best_index0 = 2;
+ min_f0 = freq0.z;
+ }
+ if (freq0.w < min_f0) {
+ best_index0 = 3;
+ min_f0 = freq0.w;
+ }
+
+ float min_f1 = freq1.x;
+ int best_index1 = 4;
+ if (freq1.y < min_f1) {
+ best_index1 = 5;
+ min_f1 = freq1.y;
+ }
+ if (freq1.z < min_f1) {
+ best_index1 = 6;
+ min_f1 = freq1.z;
+ }
+ if (freq1.w < min_f1) {
+ best_index1 = 7;
+ min_f1 = freq1.w;
+ }
+
+ best_index = mix(best_index0, best_index1, min_f0 < min_f1);
+ }
+
+#else
float depths[16];
int depth_indices[16];
int depth_amount[16];
@@ -91,7 +201,7 @@ void main() {
depth_least = depth_amount[j];
}
}
-
+#endif
best_depth = texelFetch(source_depth, pos, best_index).r;
best_normal_roughness = texelFetch(source_normal_roughness, pos, best_index);
#ifdef GIPROBE_RESOLVE
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index a7fe86b029..7b86dac143 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -4,7 +4,7 @@
VERSION_DEFINES
-#include "scene_forward_inc.glsl"
+#include "scene_forward_clustered_inc.glsl"
/* INPUT ATTRIBS */
@@ -16,7 +16,7 @@ layout(location = 0) in vec3 vertex_attrib;
layout(location = 1) in vec3 normal_attrib;
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
layout(location = 2) in vec4 tangent_attrib;
#endif
@@ -76,7 +76,7 @@ layout(location = 3) out vec2 uv_interp;
layout(location = 4) out vec2 uv2_interp;
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
layout(location = 5) out vec3 tangent_interp;
layout(location = 6) out vec3 binormal_interp;
#endif
@@ -89,33 +89,45 @@ MATERIAL_UNIFORMS
} material;
#endif
-/* clang-format off */
-
-VERTEX_SHADER_GLOBALS
-
-/* clang-format on */
-
invariant gl_Position;
-layout(location = 7) flat out uint instance_index;
-
#ifdef MODE_DUAL_PARABOLOID
layout(location = 8) out float dp_clip;
#endif
+layout(location = 9) out flat uint instance_index;
+
+/* clang-format off */
+
+VERTEX_SHADER_GLOBALS
+
+/* clang-format on */
+
void main() {
- instance_index = draw_call.instance_index;
vec4 instance_custom = vec4(0.0);
#if defined(COLOR_USED)
color_interp = color_attrib;
#endif
+ instance_index = draw_call.instance_index;
+
+ bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH);
+ if (!is_multimesh) {
+ instance_index += gl_InstanceIndex;
+ }
+
mat4 world_matrix = instances.data[instance_index].transform;
- mat3 world_normal_matrix = mat3(instances.data[instance_index].normal_transform);
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH)) {
+ mat3 world_normal_matrix;
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) {
+ world_normal_matrix = inverse(mat3(world_matrix));
+ } else {
+ world_normal_matrix = mat3(world_matrix);
+ }
+
+ if (is_multimesh) {
//multimesh, instances are for it
uint offset = (instances.data[instance_index].flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK;
offset *= gl_InstanceIndex;
@@ -144,10 +156,6 @@ void main() {
matrix = transpose(matrix);
world_matrix = world_matrix * matrix;
world_normal_matrix = world_normal_matrix * mat3(matrix);
-
- } else {
- //not a multimesh, instances are for multiple draw calls
- instance_index += gl_InstanceIndex;
}
vec3 vertex = vertex_attrib;
@@ -155,7 +163,7 @@ void main() {
vec3 normal = normal_attrib * 2.0 - 1.0;
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
vec3 tangent = tangent_attrib.xyz * 2.0 - 1.0;
float binormalf = tangent_attrib.a * 2.0 - 1.0;
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
@@ -179,7 +187,7 @@ void main() {
vertex = (vec4(vertex, 1.0) * m).xyz;
normal = (vec4(normal, 0.0) * m).xyz;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
tangent = (vec4(tangent, 0.0) * m).xyz;
binormal = (vec4(binormal, 0.0) * m).xyz;
@@ -195,7 +203,7 @@ void main() {
uv2_interp = uv2_attrib;
#endif
-#ifdef USE_OVERRIDE_POSITION
+#ifdef OVERRIDE_POSITION
vec4 position;
#endif
@@ -208,7 +216,7 @@ void main() {
normal = world_normal_matrix * normal;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
tangent = world_normal_matrix * tangent;
binormal = world_normal_matrix * binormal;
@@ -239,7 +247,7 @@ VERTEX_SHADER_CODE
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
binormal = modelview_normal * binormal;
tangent = modelview_normal * tangent;
@@ -251,7 +259,7 @@ VERTEX_SHADER_CODE
vertex = (scene_data.inv_camera_matrix * vec4(vertex, 1.0)).xyz;
normal = mat3(scene_data.inverse_normal_matrix) * normal;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
binormal = mat3(scene_data.camera_inverse_binormal_matrix) * binormal;
tangent = mat3(scene_data.camera_inverse_tangent_matrix) * tangent;
@@ -263,7 +271,7 @@ VERTEX_SHADER_CODE
normal_interp = normal;
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
tangent_interp = tangent;
binormal_interp = binormal;
#endif
@@ -290,7 +298,7 @@ VERTEX_SHADER_CODE
#endif //MODE_RENDER_DEPTH
-#ifdef USE_OVERRIDE_POSITION
+#ifdef OVERRIDE_POSITION
gl_Position = position;
#else
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
@@ -305,7 +313,8 @@ VERTEX_SHADER_CODE
#endif
#ifdef MODE_RENDER_MATERIAL
if (scene_data.material_uv2_mode) {
- gl_Position.xy = (uv2_attrib.xy + draw_call.bake_uv2_offset) * 2.0 - 1.0;
+ vec2 uv_offset = unpackHalf2x16(draw_call.uv_offset);
+ gl_Position.xy = (uv2_attrib.xy + uv_offset) * 2.0 - 1.0;
gl_Position.z = 0.00001;
gl_Position.w = 1.0;
}
@@ -318,7 +327,7 @@ VERTEX_SHADER_CODE
VERSION_DEFINES
-#include "scene_forward_inc.glsl"
+#include "scene_forward_clustered_inc.glsl"
/* Varyings */
@@ -340,23 +349,22 @@ layout(location = 3) in vec2 uv_interp;
layout(location = 4) in vec2 uv2_interp;
#endif
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
layout(location = 5) in vec3 tangent_interp;
layout(location = 6) in vec3 binormal_interp;
#endif
-layout(location = 7) flat in uint instance_index;
-
#ifdef MODE_DUAL_PARABOLOID
layout(location = 8) in float dp_clip;
#endif
+layout(location = 9) in flat uint instance_index;
+
//defines to keep compatibility with vertex
#define world_matrix instances.data[instance_index].transform
-#define world_normal_matrix instances.data[instance_index].normal_transform
#define projection_matrix scene_data.projection_matrix
#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE)
@@ -545,7 +553,7 @@ vec3 F0(float metallic, float specular, vec3 albedo) {
return mix(vec3(dielectric), albedo, vec3(metallic));
}
-void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 shadow_attenuation, vec3 diffuse_color, float roughness, float metallic, float specular, float specular_blob_intensity,
+void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, vec3 f0, uint orms, float specular_amount,
#ifdef LIGHT_BACKLIGHT_USED
vec3 backlight,
#endif
@@ -557,7 +565,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
float transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
- float rim, float rim_tint,
+ float rim, float rim_tint, vec3 rim_color,
#endif
#ifdef LIGHT_CLEARCOAT_USED
float clearcoat, float clearcoat_gloss,
@@ -565,6 +573,9 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
#ifdef LIGHT_ANISOTROPY_USED
vec3 B, vec3 T, float anisotropy,
#endif
+#ifdef USE_SOFT_SHADOWS
+ float A,
+#endif
#ifdef USE_SHADOW_TO_OPACITY
inout float alpha,
#endif
@@ -574,7 +585,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
// light is written by the light shader
vec3 normal = N;
- vec3 albedo = diffuse_color;
vec3 light = L;
vec3 view = V;
@@ -585,7 +595,12 @@ LIGHT_SHADER_CODE
/* clang-format on */
#else
+
+#ifdef USE_SOFT_SHADOWS
float NdotL = min(A + dot(N, L), 1.0);
+#else
+ float NdotL = dot(N, L);
+#endif
float cNdotL = max(NdotL, 0.0); // clamped NdotL
float NdotV = dot(N, V);
float cNdotV = max(NdotV, 0.0);
@@ -595,14 +610,25 @@ LIGHT_SHADER_CODE
#endif
#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
+#ifdef USE_SOFT_SHADOWS
float cNdotH = clamp(A + dot(N, H), 0.0, 1.0);
+#else
+ float cNdotH = clamp(dot(N, H), 0.0, 1.0);
+#endif
#endif
#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED)
+#ifdef USE_SOFT_SHADOWS
float cLdotH = clamp(A + dot(L, H), 0.0, 1.0);
+#else
+ float cLdotH = clamp(dot(L, H), 0.0, 1.0);
+#endif
#endif
+ float metallic = unpackUnorm4x8(orms).z;
if (metallic < 1.0) {
+ float roughness = unpackUnorm4x8(orms).y;
+
#if defined(DIFFUSE_OREN_NAYAR)
vec3 diffuse_brdf_NL;
#else
@@ -612,23 +638,6 @@ LIGHT_SHADER_CODE
#if defined(DIFFUSE_LAMBERT_WRAP)
// energy conserving lambert wrap shader
diffuse_brdf_NL = max(0.0, (NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
-
-#elif defined(DIFFUSE_OREN_NAYAR)
-
- {
- // see http://mimosa-pudica.net/improved-oren-nayar.html
- float LdotV = dot(L, V);
-
- float s = LdotV - NdotL * NdotV;
- float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
-
- float sigma2 = roughness * roughness; // TODO: this needs checking
- vec3 A = 1.0 + sigma2 * (-0.5 / (sigma2 + 0.33) + 0.17 * diffuse_color / (sigma2 + 0.13));
- float B = 0.45 * sigma2 / (sigma2 + 0.09);
-
- diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI);
- }
-
#elif defined(DIFFUSE_TOON)
diffuse_brdf_NL = smoothstep(-roughness, max(roughness, 0.01), NdotL);
@@ -656,15 +665,15 @@ LIGHT_SHADER_CODE
diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
#endif
- diffuse_light += light_color * diffuse_color * shadow_attenuation * diffuse_brdf_NL * attenuation;
+ diffuse_light += light_color * diffuse_brdf_NL * attenuation;
#if defined(LIGHT_BACKLIGHT_USED)
- diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation;
+ diffuse_light += light_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation;
#endif
#if defined(LIGHT_RIM_USED)
float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
- diffuse_light += rim_light * rim * mix(vec3(1.0), diffuse_color, rim_tint) * light_color;
+ diffuse_light += rim_light * rim * mix(vec3(1.0), rim_color, rim_tint) * light_color;
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
@@ -682,7 +691,7 @@ LIGHT_SHADER_CODE
vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) +
vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
- diffuse_light += profile * transmittance_color.a * diffuse_color * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI) * attenuation;
+ diffuse_light += profile * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI);
}
#else
@@ -692,7 +701,7 @@ LIGHT_SHADER_CODE
fade = pow(max(0.0, 1.0 - fade), transmittance_curve);
fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0);
- diffuse_light += diffuse_color * transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade * attenuation;
+ diffuse_light += transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade;
}
#endif //SSS_MODE_SKIN
@@ -700,6 +709,7 @@ LIGHT_SHADER_CODE
#endif //LIGHT_TRANSMITTANCE_USED
}
+ float roughness = unpackUnorm4x8(orms).y;
if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely
// D
@@ -712,7 +722,7 @@ LIGHT_SHADER_CODE
blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
float intensity = blinn;
- specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation;
+ specular_light += light_color * intensity * attenuation * specular_amount;
#elif defined(SPECULAR_PHONG)
@@ -723,7 +733,7 @@ LIGHT_SHADER_CODE
phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
float intensity = (phong) / max(4.0 * cNdotV * cNdotL, 0.75);
- specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation;
+ specular_light += light_color * intensity * attenuation * specular_amount;
#elif defined(SPECULAR_TOON)
@@ -732,7 +742,7 @@ LIGHT_SHADER_CODE
float mid = 1.0 - roughness;
mid *= mid;
float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid;
- diffuse_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection
+ diffuse_light += light_color * intensity * attenuation * specular_amount; // write to diffuse_light, as in toon shading you generally want no reflection
#elif defined(SPECULAR_DISABLED)
// none..
@@ -757,13 +767,12 @@ LIGHT_SHADER_CODE
float G = G_GGX_2cos(cNdotL, alpha_ggx) * G_GGX_2cos(cNdotV, alpha_ggx);
#endif
// F
- vec3 f0 = F0(metallic, specular, diffuse_color);
float cLdotH5 = SchlickFresnel(cLdotH);
vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);
vec3 specular_brdf_NL = cNdotL * D * F * G;
- specular_light += specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation;
+ specular_light += specular_brdf_NL * light_color * attenuation * specular_amount;
#endif
#if defined(LIGHT_CLEARCOAT_USED)
@@ -777,12 +786,12 @@ LIGHT_SHADER_CODE
float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL;
- specular_light += clearcoat_specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation;
+ specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount;
#endif
}
#ifdef USE_SHADOW_TO_OPACITY
- alpha = min(alpha, clamp(1.0 - length(shadow_attenuation * attenuation), 0.0, 1.0));
+ alpha = min(alpha, clamp(1.0 - attenuation), 0.0, 1.0));
#endif
#endif //defined(USE_LIGHT_SHADER_CODE)
@@ -790,13 +799,11 @@ LIGHT_SHADER_CODE
#ifndef USE_NO_SHADOWS
-// Produces cheap white noise, optimized for window-space
-// Comes from: https://www.shadertoy.com/view/4djSRW
-// Copyright: Dave Hoskins, MIT License
+// Interleaved Gradient Noise
+// http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare
float quick_hash(vec2 pos) {
- vec3 p3 = fract(vec3(pos.xyx) * .1031);
- p3 += dot(p3, p3.yzx + 33.33);
- return fract((p3.x + p3.y) * p3.z);
+ const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);
+ return fract(magic.z * fract(dot(pos, magic.xy)));
}
float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {
@@ -895,69 +902,39 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex
#endif //USE_NO_SHADOWS
-void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity,
-#ifdef LIGHT_BACKLIGHT_USED
- vec3 backlight,
-#endif
-#ifdef LIGHT_TRANSMITTANCE_USED
- vec4 transmittance_color,
- float transmittance_depth,
- float transmittance_curve,
- float transmittance_boost,
-#endif
-#ifdef LIGHT_RIM_USED
- float rim, float rim_tint,
-#endif
-#ifdef LIGHT_CLEARCOAT_USED
- float clearcoat, float clearcoat_gloss,
-#endif
-#ifdef LIGHT_ANISOTROPY_USED
- vec3 binormal, vec3 tangent, float anisotropy,
-#endif
-#ifdef USE_SHADOW_TO_OPACITY
- inout float alpha,
-#endif
- inout vec3 diffuse_light, inout vec3 specular_light) {
- vec3 light_rel_vec = lights.data[idx].position - vertex;
- float light_length = length(light_rel_vec);
- float normalized_distance = light_length * lights.data[idx].inv_radius;
- vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
- float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), attenuation_energy.x);
- float light_attenuation = omni_attenuation;
- vec3 shadow_attenuation = vec3(1.0);
- vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
- color_specular.rgb *= attenuation_energy.y;
- float size_A = 0.0;
-
- if (lights.data[idx].size > 0.0) {
- float t = lights.data[idx].size / max(0.001, light_length);
- size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
- }
-
-#ifdef LIGHT_TRANSMITTANCE_USED
- float transmittance_z = transmittance_depth; //no transmittance by default
-#endif
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {
#ifndef USE_NO_SHADOWS
- vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled);
- if (shadow_color_enabled.w > 0.5) {
+ if (omni_lights.data[idx].shadow_enabled) {
// there is a shadowmap
+ vec3 light_rel_vec = omni_lights.data[idx].position - vertex;
+ float light_length = length(light_rel_vec);
+
vec4 v = vec4(vertex, 1.0);
- vec4 splane = (lights.data[idx].shadow_matrix * v);
+ vec4 splane = (omni_lights.data[idx].shadow_matrix * v);
float shadow_len = length(splane.xyz); //need to remember shadow len from here
{
- vec3 nofs = normal_interp * lights.data[idx].shadow_normal_bias / lights.data[idx].inv_radius;
+ vec3 nofs = normal_interp * omni_lights.data[idx].shadow_normal_bias / omni_lights.data[idx].inv_radius;
nofs *= (1.0 - max(0.0, dot(normalize(light_rel_vec), normalize(normal_interp))));
v.xyz += nofs;
- splane = (lights.data[idx].shadow_matrix * v);
+ splane = (omni_lights.data[idx].shadow_matrix * v);
}
float shadow;
- if (lights.data[idx].soft_shadow_size > 0.0) {
+#ifdef USE_SOFT_SHADOWS
+ if (omni_lights.data[idx].soft_shadow_size > 0.0) {
//soft shadow
//find blocker
@@ -977,10 +954,10 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
vec3 tangent = normalize(cross(v0, normal));
vec3 bitangent = normalize(cross(tangent, normal));
- float z_norm = shadow_len * lights.data[idx].inv_radius;
+ float z_norm = shadow_len * omni_lights.data[idx].inv_radius;
- tangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale;
- bitangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale;
+ tangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale;
+ bitangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale;
for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy;
@@ -988,7 +965,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y;
pos = normalize(pos);
- vec4 uv_rect = lights.data[idx].atlas_rect;
+ vec4 uv_rect = omni_lights.data[idx].atlas_rect;
if (pos.z >= 0.0) {
pos.z += 1.0;
@@ -1016,7 +993,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
tangent *= penumbra;
bitangent *= penumbra;
- z_norm -= lights.data[idx].inv_radius * lights.data[idx].shadow_bias;
+ z_norm -= omni_lights.data[idx].inv_radius * omni_lights.data[idx].shadow_bias;
shadow = 0.0;
for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
@@ -1024,7 +1001,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y;
pos = normalize(pos);
- vec4 uv_rect = lights.data[idx].atlas_rect;
+ vec4 uv_rect = omni_lights.data[idx].atlas_rect;
if (pos.z >= 0.0) {
pos.z += 1.0;
@@ -1047,8 +1024,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
shadow = 1.0;
}
} else {
+#endif
splane.xyz = normalize(splane.xyz);
- vec4 clamp_rect = lights.data[idx].atlas_rect;
+ vec4 clamp_rect = omni_lights.data[idx].atlas_rect;
if (splane.z >= 0.0) {
splane.z += 1.0;
@@ -1062,101 +1040,149 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
splane.xy /= splane.z;
splane.xy = splane.xy * 0.5 + 0.5;
- splane.z = (shadow_len - lights.data[idx].shadow_bias) * lights.data[idx].inv_radius;
+ splane.z = (shadow_len - omni_lights.data[idx].shadow_bias) * omni_lights.data[idx].inv_radius;
splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
splane.w = 1.0; //needed? i think it should be 1 already
- shadow = sample_pcf_shadow(shadow_atlas, lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane);
+ shadow = sample_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane);
+#ifdef USE_SOFT_SHADOWS
}
+#endif
+
+ return shadow;
+ }
+#endif
+ return 1.0;
+}
+
+void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 f0, uint orms, float shadow,
+#ifdef LIGHT_BACKLIGHT_USED
+ vec3 backlight,
+#endif
#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 clamp_rect = lights.data[idx].atlas_rect;
+ vec4 transmittance_color,
+ float transmittance_depth,
+ float transmittance_curve,
+ float transmittance_boost,
+#endif
+#ifdef LIGHT_RIM_USED
+ float rim, float rim_tint, vec3 rim_color,
+#endif
+#ifdef LIGHT_CLEARCOAT_USED
+ float clearcoat, float clearcoat_gloss,
+#endif
+#ifdef LIGHT_ANISOTROPY_USED
+ vec3 binormal, vec3 tangent, float anisotropy,
+#endif
+#ifdef USE_SHADOW_TO_OPACITY
+ inout float alpha,
+#endif
+ inout vec3 diffuse_light, inout vec3 specular_light) {
+ vec3 light_rel_vec = omni_lights.data[idx].position - vertex;
+ float light_length = length(light_rel_vec);
+ float omni_attenuation = get_omni_attenuation(light_length, omni_lights.data[idx].inv_radius, omni_lights.data[idx].attenuation);
+ float light_attenuation = omni_attenuation;
+ vec3 color = omni_lights.data[idx].color;
- //redo shadowmapping, but shrink the model a bit to avoid arctifacts
- splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0));
+#ifdef USE_SOFT_SHADOWS
+ float size_A = 0.0;
- shadow_len = length(splane.xyz);
- splane = normalize(splane.xyz);
+ if (omni_lights.data[idx].size > 0.0) {
+ float t = omni_lights.data[idx].size / max(0.001, light_length);
+ size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
+ }
+#endif
- if (splane.z >= 0.0) {
- splane.z += 1.0;
+#ifdef LIGHT_TRANSMITTANCE_USED
+ float transmittance_z = transmittance_depth; //no transmittance by default
+ transmittance_color.a *= light_attenuation;
+ {
+ vec4 clamp_rect = omni_lights.data[idx].atlas_rect;
- } else {
- splane.z = 1.0 - splane.z;
- }
+ //redo shadowmapping, but shrink the model a bit to avoid arctifacts
+ vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0));
- splane.xy /= splane.z;
- splane.xy = splane.xy * 0.5 + 0.5;
- splane.z = shadow_len * lights.data[idx].inv_radius;
- splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
- splane.w = 1.0; //needed? i think it should be 1 already
+ shadow_len = length(splane.xyz);
+ splane = normalize(splane.xyz);
+
+ if (splane.z >= 0.0) {
+ splane.z += 1.0;
- float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
- transmittance_z = (splane.z - shadow_z) / lights.data[idx].inv_radius;
+ } else {
+ splane.z = 1.0 - splane.z;
}
-#endif
- vec3 no_shadow = vec3(1.0);
+ splane.xy /= splane.z;
+ splane.xy = splane.xy * 0.5 + 0.5;
+ splane.z = shadow_len * omni_lights.data[idx].inv_radius;
+ splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
+ splane.w = 1.0; //needed? i think it should be 1 already
- if (lights.data[idx].projector_rect != vec4(0.0)) {
- vec3 local_v = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz;
- local_v = normalize(local_v);
+ float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
+ transmittance_z = (splane.z - shadow_z) / omni_lights.data[idx].inv_radius;
+ }
+#endif
- vec4 atlas_rect = lights.data[idx].projector_rect;
+#if 0
- if (local_v.z >= 0.0) {
- local_v.z += 1.0;
- atlas_rect.y += atlas_rect.w;
+ if (omni_lights.data[idx].projector_rect != vec4(0.0)) {
+ vec3 local_v = (omni_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz;
+ local_v = normalize(local_v);
- } else {
- local_v.z = 1.0 - local_v.z;
- }
+ vec4 atlas_rect = omni_lights.data[idx].projector_rect;
- local_v.xy /= local_v.z;
- local_v.xy = local_v.xy * 0.5 + 0.5;
- vec2 proj_uv = local_v.xy * atlas_rect.zw;
+ if (local_v.z >= 0.0) {
+ local_v.z += 1.0;
+ atlas_rect.y += atlas_rect.w;
- vec2 proj_uv_ddx;
- vec2 proj_uv_ddy;
- {
- vec3 local_v_ddx = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)).xyz;
- local_v_ddx = normalize(local_v_ddx);
+ } else {
+ local_v.z = 1.0 - local_v.z;
+ }
- if (local_v_ddx.z >= 0.0) {
- local_v_ddx.z += 1.0;
- } else {
- local_v_ddx.z = 1.0 - local_v_ddx.z;
- }
+ local_v.xy /= local_v.z;
+ local_v.xy = local_v.xy * 0.5 + 0.5;
+ vec2 proj_uv = local_v.xy * atlas_rect.zw;
- local_v_ddx.xy /= local_v_ddx.z;
- local_v_ddx.xy = local_v_ddx.xy * 0.5 + 0.5;
+ vec2 proj_uv_ddx;
+ vec2 proj_uv_ddy;
+ {
+ vec3 local_v_ddx = (omni_lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)).xyz;
+ local_v_ddx = normalize(local_v_ddx);
- proj_uv_ddx = local_v_ddx.xy * atlas_rect.zw - proj_uv;
+ if (local_v_ddx.z >= 0.0) {
+ local_v_ddx.z += 1.0;
+ } else {
+ local_v_ddx.z = 1.0 - local_v_ddx.z;
+ }
- vec3 local_v_ddy = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)).xyz;
- local_v_ddy = normalize(local_v_ddy);
+ local_v_ddx.xy /= local_v_ddx.z;
+ local_v_ddx.xy = local_v_ddx.xy * 0.5 + 0.5;
- if (local_v_ddy.z >= 0.0) {
- local_v_ddy.z += 1.0;
- } else {
- local_v_ddy.z = 1.0 - local_v_ddy.z;
- }
+ proj_uv_ddx = local_v_ddx.xy * atlas_rect.zw - proj_uv;
- local_v_ddy.xy /= local_v_ddy.z;
- local_v_ddy.xy = local_v_ddy.xy * 0.5 + 0.5;
+ vec3 local_v_ddy = (omni_lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)).xyz;
+ local_v_ddy = normalize(local_v_ddy);
- proj_uv_ddy = local_v_ddy.xy * atlas_rect.zw - proj_uv;
+ if (local_v_ddy.z >= 0.0) {
+ local_v_ddy.z += 1.0;
+ } else {
+ local_v_ddy.z = 1.0 - local_v_ddy.z;
}
- vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + atlas_rect.xy, proj_uv_ddx, proj_uv_ddy);
- no_shadow = mix(no_shadow, proj.rgb, proj.a);
+ local_v_ddy.xy /= local_v_ddy.z;
+ local_v_ddy.xy = local_v_ddy.xy * 0.5 + 0.5;
+
+ proj_uv_ddy = local_v_ddy.xy * atlas_rect.zw - proj_uv;
}
- shadow_attenuation = mix(shadow_color_enabled.rgb, no_shadow, shadow);
+ vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + atlas_rect.xy, proj_uv_ddx, proj_uv_ddy);
+ no_shadow = mix(no_shadow, proj.rgb, proj.a);
}
-#endif //USE_NO_SHADOWS
+#endif
+
+ light_attenuation *= shadow;
- light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity,
+ light_compute(normal, normalize(light_rel_vec), eye_vec, color, light_attenuation, f0, orms, omni_lights.data[idx].specular_amount,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
#endif
@@ -1168,7 +1194,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
- rim * omni_attenuation, rim_tint,
+ rim * omni_attenuation, rim_tint, rim_color,
#endif
#ifdef LIGHT_CLEARCOAT_USED
clearcoat, clearcoat_gloss,
@@ -1176,6 +1202,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_ANISOTROPY_USED
binormal, tangent, anisotropy,
#endif
+#ifdef USE_SOFT_SHADOWS
+ size_A,
+#endif
#ifdef USE_SHADOW_TO_OPACITY
alpha,
#endif
@@ -1183,89 +1212,39 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
specular_light);
}
-void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity,
-#ifdef LIGHT_BACKLIGHT_USED
- vec3 backlight,
-#endif
-#ifdef LIGHT_TRANSMITTANCE_USED
- vec4 transmittance_color,
- float transmittance_depth,
- float transmittance_curve,
- float transmittance_boost,
-#endif
-#ifdef LIGHT_RIM_USED
- float rim, float rim_tint,
-#endif
-#ifdef LIGHT_CLEARCOAT_USED
- float clearcoat, float clearcoat_gloss,
-#endif
-#ifdef LIGHT_ANISOTROPY_USED
- vec3 binormal, vec3 tangent, float anisotropy,
-#endif
-#ifdef USE_SHADOW_TO_OPACITY
- inout float alpha,
-#endif
- inout vec3 diffuse_light,
- inout vec3 specular_light) {
- vec3 light_rel_vec = lights.data[idx].position - vertex;
- float light_length = length(light_rel_vec);
- float normalized_distance = light_length * lights.data[idx].inv_radius;
- vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy);
- float spot_attenuation = pow(max(1.0 - normalized_distance, 0.001), attenuation_energy.x);
- vec3 spot_dir = lights.data[idx].direction;
- vec2 spot_att_angle = unpackHalf2x16(lights.data[idx].cone_attenuation_angle);
- float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y);
- float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_att_angle.y));
- spot_attenuation *= 1.0 - pow(spot_rim, spot_att_angle.x);
- float light_attenuation = spot_attenuation;
- vec3 shadow_attenuation = vec3(1.0);
- vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular);
- color_specular.rgb *= attenuation_energy.y;
-
- float size_A = 0.0;
-
- if (lights.data[idx].size > 0.0) {
- float t = lights.data[idx].size / max(0.001, light_length);
- size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
- }
-/*
- if (lights.data[idx].atlas_rect!=vec4(0.0)) {
- //use projector texture
- }
- */
-#ifdef LIGHT_TRANSMITTANCE_USED
- float transmittance_z = transmittance_depth;
-#endif
-
+float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
#ifndef USE_NO_SHADOWS
- vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled);
- if (shadow_color_enabled.w > 0.5) {
+ if (spot_lights.data[idx].shadow_enabled) {
+ vec3 light_rel_vec = spot_lights.data[idx].position - vertex;
+ float light_length = length(light_rel_vec);
+ vec3 spot_dir = spot_lights.data[idx].direction;
//there is a shadowmap
vec4 v = vec4(vertex, 1.0);
- v.xyz -= spot_dir * lights.data[idx].shadow_bias;
+ v.xyz -= spot_dir * spot_lights.data[idx].shadow_bias;
- float z_norm = dot(spot_dir, -light_rel_vec) * lights.data[idx].inv_radius;
+ float z_norm = dot(spot_dir, -light_rel_vec) * spot_lights.data[idx].inv_radius;
float depth_bias_scale = 1.0 / (max(0.0001, z_norm)); //the closer to the light origin, the more you have to offset to reach 1px in the map
- vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * lights.data[idx].shadow_normal_bias * depth_bias_scale;
+ vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * spot_lights.data[idx].shadow_normal_bias * depth_bias_scale;
normal_bias -= spot_dir * dot(spot_dir, normal_bias); //only XY, no Z
v.xyz += normal_bias;
//adjust with bias
- z_norm = dot(spot_dir, v.xyz - lights.data[idx].position) * lights.data[idx].inv_radius;
+ z_norm = dot(spot_dir, v.xyz - spot_lights.data[idx].position) * spot_lights.data[idx].inv_radius;
float shadow;
- vec4 splane = (lights.data[idx].shadow_matrix * v);
+ vec4 splane = (spot_lights.data[idx].shadow_matrix * v);
splane /= splane.w;
- if (lights.data[idx].soft_shadow_size > 0.0) {
+#ifdef USE_SOFT_SHADOWS
+ if (spot_lights.data[idx].soft_shadow_size > 0.0) {
//soft shadow
//find blocker
- vec2 shadow_uv = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy;
+ vec2 shadow_uv = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy;
float blocker_count = 0.0;
float blocker_average = 0.0;
@@ -1278,11 +1257,11 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr));
}
- float uv_size = lights.data[idx].soft_shadow_size * z_norm * lights.data[idx].soft_shadow_scale;
- vec2 clamp_max = lights.data[idx].atlas_rect.xy + lights.data[idx].atlas_rect.zw;
+ float uv_size = spot_lights.data[idx].soft_shadow_size * z_norm * spot_lights.data[idx].soft_shadow_scale;
+ vec2 clamp_max = spot_lights.data[idx].atlas_rect.xy + spot_lights.data[idx].atlas_rect.zw;
for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size;
- suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max);
+ suv = clamp(suv, spot_lights.data[idx].atlas_rect.xy, clamp_max);
float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r;
if (d < z_norm) {
blocker_average += d;
@@ -1299,7 +1278,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
shadow = 0.0;
for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size;
- suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max);
+ suv = clamp(suv, spot_lights.data[idx].atlas_rect.xy, clamp_max);
shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(suv, z_norm, 1.0));
}
@@ -1311,54 +1290,93 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
}
} else {
+#endif
//hard shadow
- vec4 shadow_uv = vec4(splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy, z_norm, 1.0);
+ vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z, 1.0);
- shadow = sample_pcf_shadow(shadow_atlas, lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv);
+ shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv);
+#ifdef USE_SOFT_SHADOWS
}
+#endif
- vec3 no_shadow = vec3(1.0);
+ return shadow;
+ }
- if (lights.data[idx].projector_rect != vec4(0.0)) {
- splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0));
- splane /= splane.w;
+#endif //USE_NO_SHADOWS
- vec2 proj_uv = splane.xy * lights.data[idx].projector_rect.zw;
+ return 1.0;
+}
- //ensure we have proper mipmaps
- vec4 splane_ddx = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0));
- splane_ddx /= splane_ddx.w;
- vec2 proj_uv_ddx = splane_ddx.xy * lights.data[idx].projector_rect.zw - proj_uv;
+void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 f0, uint orms, float shadow,
+#ifdef LIGHT_BACKLIGHT_USED
+ vec3 backlight,
+#endif
+#ifdef LIGHT_TRANSMITTANCE_USED
+ vec4 transmittance_color,
+ float transmittance_depth,
+ float transmittance_curve,
+ float transmittance_boost,
+#endif
+#ifdef LIGHT_RIM_USED
+ float rim, float rim_tint, vec3 rim_color,
+#endif
+#ifdef LIGHT_CLEARCOAT_USED
+ float clearcoat, float clearcoat_gloss,
+#endif
+#ifdef LIGHT_ANISOTROPY_USED
+ vec3 binormal, vec3 tangent, float anisotropy,
+#endif
+#ifdef USE_SHADOW_TO_OPACITY
+ inout float alpha,
+#endif
+ inout vec3 diffuse_light,
+ inout vec3 specular_light) {
+ vec3 light_rel_vec = spot_lights.data[idx].position - vertex;
+ float light_length = length(light_rel_vec);
+ float spot_attenuation = get_omni_attenuation(light_length, spot_lights.data[idx].inv_radius, spot_lights.data[idx].attenuation);
+ vec3 spot_dir = spot_lights.data[idx].direction;
+ float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights.data[idx].cone_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights.data[idx].cone_angle));
+ spot_attenuation *= 1.0 - pow(spot_rim, spot_lights.data[idx].cone_attenuation);
+ float light_attenuation = spot_attenuation;
+ vec3 color = spot_lights.data[idx].color;
+ float specular_amount = spot_lights.data[idx].specular_amount;
- vec4 splane_ddy = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0));
- splane_ddy /= splane_ddy.w;
- vec2 proj_uv_ddy = splane_ddy.xy * lights.data[idx].projector_rect.zw - proj_uv;
+#ifdef USE_SOFT_SHADOWS
+ float size_A = 0.0;
- vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + lights.data[idx].projector_rect.xy, proj_uv_ddx, proj_uv_ddy);
- no_shadow = mix(no_shadow, proj.rgb, proj.a);
- }
+ if (spot_lights.data[idx].size > 0.0) {
+ float t = spot_lights.data[idx].size / max(0.001, light_length);
+ size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
+ }
+#endif
- shadow_attenuation = mix(shadow_color_enabled.rgb, no_shadow, shadow);
+ /*
+ if (spot_lights.data[idx].atlas_rect!=vec4(0.0)) {
+ //use projector texture
+ }
+ */
#ifdef LIGHT_TRANSMITTANCE_USED
- {
- splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0));
- splane /= splane.w;
- splane.xy = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy;
-
- float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
- //reconstruct depth
- shadow_z /= lights.data[idx].inv_radius;
- //distance to light plane
- float z = dot(spot_dir, -light_rel_vec);
- transmittance_z = z - shadow_z;
- }
-#endif //LIGHT_TRANSMITTANCE_USED
+ float transmittance_z = transmittance_depth;
+ transmittance_color.a *= light_attenuation;
+ {
+ splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0));
+ splane /= splane.w;
+ splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy;
+
+ float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
+ //reconstruct depth
+ shadow_z /= spot_lights.data[idx].inv_radius;
+ //distance to light plane
+ float z = dot(spot_dir, -light_rel_vec);
+ transmittance_z = z - shadow_z;
}
+#endif //LIGHT_TRANSMITTANCE_USED
-#endif //USE_NO_SHADOWS
+ light_attenuation *= shadow;
- light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity,
+ light_compute(normal, normalize(light_rel_vec), eye_vec, color, light_attenuation, f0, orms, spot_lights.data[idx].specular_amount,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
#endif
@@ -1370,7 +1388,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
- rim * spot_attenuation, rim_tint,
+ rim * spot_attenuation, rim_tint, rim_color,
#endif
#ifdef LIGHT_CLEARCOAT_USED
clearcoat, clearcoat_gloss,
@@ -1378,6 +1396,9 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_ANISOTROPY_USED
binormal, tangent, anisotropy,
#endif
+#ifdef USE_SOFT_SHADOW
+ size_A,
+#endif
#ifdef USE_SHADOW_TO_OPACITY
alpha,
#endif
@@ -1401,11 +1422,11 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes
blend *= blend;
blend = max(0.0, 1.0 - blend);
- if (reflections.data[ref_index].params.x > 0.0) { // compute reflection
+ if (reflections.data[ref_index].intensity > 0.0) { // compute reflection
vec3 local_ref_vec = (reflections.data[ref_index].local_matrix * vec4(ref_vec, 0.0)).xyz;
- if (reflections.data[ref_index].params.w > 0.5) { //box project
+ if (reflections.data[ref_index].box_project) { //box project
vec3 nrdir = normalize(local_ref_vec);
vec3 rbmax = (box_extents - local_pos) / nrdir;
@@ -1422,11 +1443,11 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes
reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, reflections.data[ref_index].index), roughness * MAX_ROUGHNESS_LOD).rgb;
- if (reflections.data[ref_index].params.z < 0.5) {
+ if (reflections.data[ref_index].exterior) {
reflection.rgb = mix(specular_light, reflection.rgb, blend);
}
- reflection.rgb *= reflections.data[ref_index].params.x;
+ reflection.rgb *= reflections.data[ref_index].intensity; //intensity
reflection.a = blend;
reflection.rgb *= reflection.a;
@@ -1445,7 +1466,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes
ambient_out.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_amb_vec, reflections.data[ref_index].index), MAX_ROUGHNESS_LOD).rgb;
ambient_out.a = blend;
- if (reflections.data[ref_index].params.z < 0.5) { //interior
+ if (reflections.data[ref_index].exterior) {
ambient_out.rgb = mix(ambient_light, ambient_out.rgb, blend);
}
@@ -1456,7 +1477,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes
vec4 ambient_out;
ambient_out.a = blend;
ambient_out.rgb = reflections.data[ref_index].ambient;
- if (reflections.data[ref_index].params.z < 0.5) {
+ if (reflections.data[ref_index].exterior) {
ambient_out.rgb = mix(ambient_light, ambient_out.rgb, blend);
}
ambient_out.rgb *= ambient_out.a;
@@ -1759,7 +1780,7 @@ vec4 fog_process(vec3 vertex) {
}
}
- float fog_amount = 1.0 - exp(vertex.z * scene_data.fog_density);
+ float fog_amount = 1.0 - exp(min(0.0, vertex.z * scene_data.fog_density));
if (abs(scene_data.fog_height_density) > 0.001) {
float y = (scene_data.camera_matrix * vec4(vertex, 1.0)).y;
@@ -1774,7 +1795,43 @@ vec4 fog_process(vec3 vertex) {
return vec4(fog_color, fog_amount);
}
+void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) {
+ uint item_min_max = cluster_buffer.data[p_offset];
+ item_min = item_min_max & 0xFFFF;
+ item_max = item_min_max >> 16;
+ ;
+
+ item_from = item_min >> 5;
+ item_to = (item_max == 0) ? 0 : ((item_max - 1) >> 5) + 1; //side effect of how it is stored, as item_max 0 means no elements
+}
+
+uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) {
+ int local_min = clamp(int(z_min) - int(i) * 32, 0, 31);
+ int mask_width = min(int(z_max) - int(z_min), 32 - local_min);
+ return bitfieldInsert(uint(0), uint(0xFFFFFFFF), local_min, mask_width);
+}
+
+float blur_shadow(float shadow) {
+ return shadow;
+#if 0
+ //disabling for now, will investigate later
+ float interp_shadow = shadow;
+ if (gl_HelperInvocation) {
+ interp_shadow = -4.0; // technically anything below -4 will do but just to make sure
+ }
+
+ uvec2 fc2 = uvec2(gl_FragCoord.xy);
+ interp_shadow -= dFdx(interp_shadow) * (float(fc2.x & 1) - 0.5);
+ interp_shadow -= dFdy(interp_shadow) * (float(fc2.y & 1) - 0.5);
+
+ if (interp_shadow >= 0.0) {
+ shadow = interp_shadow;
+ }
+ return shadow;
#endif
+}
+
+#endif //!MODE_RENDER DEPTH
void main() {
#ifdef MODE_DUAL_PARABOLOID
@@ -1802,9 +1859,7 @@ void main() {
float clearcoat_gloss = 0.0;
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
-#if defined(CUSTOM_FOG_USED)
- vec4 custom_fog = vec4(0.0);
-#endif
+ vec4 fog = vec4(0.0);
#if defined(CUSTOM_RADIANCE_USED)
vec4 custom_radiance = vec4(0.0);
#endif
@@ -1812,14 +1867,12 @@ void main() {
vec4 custom_irradiance = vec4(0.0);
#endif
-#if defined(AO_USED)
float ao = 1.0;
float ao_light_affect = 0.0;
-#endif
float alpha = 1.0;
-#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
+#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
vec3 binormal = normalize(binormal_interp);
vec3 tangent = normalize(tangent_interp);
#else
@@ -1850,12 +1903,12 @@ void main() {
vec4 color = color_interp;
#endif
-#if defined(NORMALMAP_USED)
+#if defined(NORMAL_MAP_USED)
- vec3 normalmap = vec3(0.5);
+ vec3 normal_map = vec3(0.5);
#endif
- float normaldepth = 1.0;
+ float normal_map_depth = 1.0;
vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size + scene_data.screen_pixel_size * 0.5; //account for center
@@ -1926,12 +1979,12 @@ FRAGMENT_SHADER_CODE
#endif // !USE_SHADOW_TO_OPACITY
-#ifdef NORMALMAP_USED
+#ifdef NORMAL_MAP_USED
- normalmap.xy = normalmap.xy * 2.0 - 1.0;
- normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
+ normal_map.xy = normal_map.xy * 2.0 - 1.0;
+ normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
- normal = normalize(mix(normal, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth));
+ normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth));
#endif
@@ -1953,77 +2006,147 @@ FRAGMENT_SHADER_CODE
discard;
}
#endif
+
+ /////////////////////// FOG //////////////////////
+#ifndef MODE_RENDER_DEPTH
+
+#ifndef CUSTOM_FOG_USED
+ // fog must be processed as early as possible and then packed.
+ // to maximize VGPR usage
+ // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
+
+ if (scene_data.fog_enabled) {
+ fog = fog_process(vertex);
+ }
+
+#ifndef LOW_END_MODE
+ if (scene_data.volumetric_fog_enabled) {
+ vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z);
+ if (scene_data.fog_enabled) {
+ //must use the full blending equation here to blend fogs
+ vec4 res;
+ float sa = 1.0 - volumetric_fog.a;
+ res.a = fog.a * sa + volumetric_fog.a;
+ if (res.a == 0.0) {
+ res.rgb = vec3(0.0);
+ } else {
+ res.rgb = (fog.rgb * fog.a * sa + volumetric_fog.rgb * volumetric_fog.a) / res.a;
+ }
+ fog = res;
+ } else {
+ fog = volumetric_fog;
+ }
+ }
+#endif //!LOW_END_MODE
+#endif //!CUSTOM_FOG_USED
+
+ uint fog_rg = packHalf2x16(fog.rg);
+ uint fog_ba = packHalf2x16(fog.ba);
+
+#endif //!MODE_RENDER_DEPTH
+
/////////////////////// DECALS ////////////////////////////////
#ifndef MODE_RENDER_DEPTH
- uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]), vec3(screen_uv, (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)));
+ uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> scene_data.cluster_shift;
+ uint cluster_offset = (scene_data.cluster_width * cluster_pos.y + cluster_pos.x) * (scene_data.max_cluster_element_count_div_32 + 32);
+
+ uint cluster_z = uint(clamp((-vertex.z / scene_data.z_far) * 32.0, 0.0, 31.0));
+
//used for interpolating anything cluster related
vec3 vertex_ddx = dFdx(vertex);
vec3 vertex_ddy = dFdy(vertex);
{ // process decals
- uint decal_count = cluster_cell.w >> CLUSTER_COUNTER_SHIFT;
- uint decal_pointer = cluster_cell.w & CLUSTER_POINTER_MASK;
+ uint cluster_decal_offset = cluster_offset + scene_data.cluster_type_size * 2;
- //do outside for performance and avoiding arctifacts
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
- for (uint i = 0; i < decal_count; i++) {
- uint decal_index = cluster_data.indices[decal_pointer + i];
- if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) {
- continue; //not masked
- }
+ cluster_get_item_range(cluster_decal_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
- vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
- if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
- continue; //out of decal
- }
+#ifdef USE_SUBGROUPS
+ item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+ item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+#endif
- //we need ddx/ddy for mipmaps, so simulate them
- vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz;
- vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz;
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_decal_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+#ifdef USE_SUBGROUPS
+ uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+#else
+ uint merged_mask = mask;
+#endif
- float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade);
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1 << bit);
+#ifdef USE_SUBGROUPS
+ if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ continue;
+ }
+#endif
+ uint decal_index = 32 * i + bit;
- if (decals.data[decal_index].normal_fade > 0.0) {
- fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5);
- }
+ if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
- if (decals.data[decal_index].albedo_rect != vec4(0.0)) {
- //has albedo
- vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw);
- decal_albedo *= decals.data[decal_index].modulate;
- decal_albedo.a *= fade;
- albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);
-
- if (decals.data[decal_index].normal_rect != vec4(0.0)) {
- vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
- decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software
- decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));
- //convert to view space, use xzy because y is up
- decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz;
-
- normal = normalize(mix(normal, decal_normal, decal_albedo.a));
+ vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
+ if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
+ continue; //out of decal
}
- if (decals.data[decal_index].orm_rect != vec4(0.0)) {
- vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
-#if defined(AO_USED)
- ao = mix(ao, decal_orm.r, decal_albedo.a);
-#endif
- roughness = mix(roughness, decal_orm.g, decal_albedo.a);
- metallic = mix(metallic, decal_orm.b, decal_albedo.a);
+ //we need ddx/ddy for mipmaps, so simulate them
+ vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz;
+ vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz;
+
+ float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade);
+
+ if (decals.data[decal_index].normal_fade > 0.0) {
+ fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5);
}
- }
- if (decals.data[decal_index].emission_rect != vec4(0.0)) {
- //emission is additive, so its independent from albedo
- emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade;
+ if (decals.data[decal_index].albedo_rect != vec4(0.0)) {
+ //has albedo
+ vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw);
+ decal_albedo *= decals.data[decal_index].modulate;
+ decal_albedo.a *= fade;
+ albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);
+
+ if (decals.data[decal_index].normal_rect != vec4(0.0)) {
+ vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
+ decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software
+ decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));
+ //convert to view space, use xzy because y is up
+ decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz;
+
+ normal = normalize(mix(normal, decal_normal, decal_albedo.a));
+ }
+
+ if (decals.data[decal_index].orm_rect != vec4(0.0)) {
+ vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
+ ao = mix(ao, decal_orm.r, decal_albedo.a);
+ roughness = mix(roughness, decal_orm.g, decal_albedo.a);
+ metallic = mix(metallic, decal_orm.b, decal_albedo.a);
+ }
+ }
+
+ if (decals.data[decal_index].emission_rect != vec4(0.0)) {
+ //emission is additive, so its independent from albedo
+ emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade;
+ }
}
}
}
+ //pack albedo until needed again, saves 2 VGPRs in the meantime
+
#endif //not render depth
/////////////////////// LIGHTING //////////////////////////////
@@ -2091,12 +2214,7 @@ FRAGMENT_SHADER_CODE
//radiance
- float specular_blob_intensity = 1.0;
-
-#if defined(SPECULAR_TOON)
- specular_blob_intensity *= specular * 2.0;
-#endif
-
+/// GI ///
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
#ifdef USE_LIGHTMAP
@@ -2124,10 +2242,10 @@ FRAGMENT_SHADER_CODE
} else if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap
bool uses_sh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP);
- uint ofs = instances.data[instance_index].gi_offset & 0xFFF;
+ uint ofs = instances.data[instance_index].gi_offset & 0xFFFF;
vec3 uvw;
uvw.xy = uv2 * instances.data[instance_index].lightmap_uv_scale.zw + instances.data[instance_index].lightmap_uv_scale.xy;
- uvw.z = float((instances.data[instance_index].gi_offset >> 12) & 0xFF);
+ uvw.z = float((instances.data[instance_index].gi_offset >> 16) & 0xFFFF);
if (uses_sh) {
uvw.z *= 4.0; //SH textures use 4 times more data
@@ -2263,17 +2381,17 @@ FRAGMENT_SHADER_CODE
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers
- ivec2 coord;
+ vec2 coord;
if (scene_data.gi_upscale_for_msaa) {
- ivec2 base_coord = ivec2(gl_FragCoord.xy);
- ivec2 closest_coord = base_coord;
- float closest_ang = dot(normal, texelFetch(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0).xyz * 2.0 - 1.0);
+ vec2 base_coord = screen_uv;
+ vec2 closest_coord = base_coord;
+ float closest_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0.0).xyz * 2.0 - 1.0);
for (int i = 0; i < 4; i++) {
- const ivec2 neighbours[4] = ivec2[](ivec2(-1, 0), ivec2(1, 0), ivec2(0, -1), ivec2(0, 1));
- ivec2 neighbour_coord = base_coord + neighbours[i];
- float neighbour_ang = dot(normal, texelFetch(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord, 0).xyz * 2.0 - 1.0);
+ const vec2 neighbours[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1));
+ vec2 neighbour_coord = base_coord + neighbours[i] * scene_data.screen_pixel_size;
+ float neighbour_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord, 0.0).xyz * 2.0 - 1.0);
if (neighbour_ang > closest_ang) {
closest_ang = neighbour_ang;
closest_coord = neighbour_coord;
@@ -2283,28 +2401,69 @@ FRAGMENT_SHADER_CODE
coord = closest_coord;
} else {
- coord = ivec2(gl_FragCoord.xy);
+ coord = screen_uv;
}
- vec4 buffer_ambient = texelFetch(sampler2D(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0);
- vec4 buffer_reflection = texelFetch(sampler2D(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0);
+ vec4 buffer_ambient = textureLod(sampler2D(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0);
+ vec4 buffer_reflection = textureLod(sampler2D(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0);
ambient_light = mix(ambient_light, buffer_ambient.rgb, buffer_ambient.a);
specular_light = mix(specular_light, buffer_reflection.rgb, buffer_reflection.a);
}
#endif
+#ifndef LOW_END_MODE
+ if (scene_data.ssao_enabled) {
+ float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
+ ao = min(ao, ssao);
+ ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect);
+ }
+#endif //LOW_END_MODE
+
{ // process reflections
vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
- uint reflection_probe_count = cluster_cell.z >> CLUSTER_COUNTER_SHIFT;
- uint reflection_probe_pointer = cluster_cell.z & CLUSTER_POINTER_MASK;
+ uint cluster_reflection_offset = cluster_offset + scene_data.cluster_type_size * 3;
+
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
- for (uint i = 0; i < reflection_probe_count; i++) {
- uint ref_index = cluster_data.indices[reflection_probe_pointer + i];
- reflection_process(ref_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
+ cluster_get_item_range(cluster_reflection_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+
+#ifdef USE_SUBGROUPS
+ item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+ item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+#endif
+
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_reflection_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+#ifdef USE_SUBGROUPS
+ uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+#else
+ uint merged_mask = mask;
+#endif
+
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1 << bit);
+#ifdef USE_SUBGROUPS
+ if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ continue;
+ }
+#endif
+ uint reflection_index = 32 * i + bit;
+
+ if (!bool(reflections.data[reflection_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
+
+ reflection_process(reflection_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
+ }
}
if (reflection_accum.a > 0.0) {
@@ -2318,6 +2477,16 @@ FRAGMENT_SHADER_CODE
#endif
}
+ //finalize ambient light here
+ ambient_light *= albedo.rgb;
+ ambient_light *= ao;
+
+ // convert ao to direct light ao
+ ao = mix(1.0, ao, ao_light_affect);
+
+ //this saves some VGPRs
+ vec3 f0 = F0(metallic, specular, albedo);
+
{
#if defined(DIFFUSE_TOON)
//simplify for toon, as
@@ -2335,24 +2504,39 @@ FRAGMENT_SHADER_CODE
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- vec3 f0 = F0(metallic, specular, albedo);
specular_light *= env.x * f0 + env.y;
#endif
}
+#endif //GI !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
+
+#if !defined(MODE_RENDER_DEPTH)
+ //this saves some VGPRs
+ uint orms = packUnorm4x8(vec4(ao, roughness, metallic, specular));
+#endif
+
+// LIGHTING
+#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
+
{ //directional light
- for (uint i = 0; i < scene_data.directional_light_count; i++) {
+ // Do shadow and lighting in two passes to reduce register pressure
+ uint shadow0 = 0;
+ uint shadow1 = 0;
+
+ for (uint i = 0; i < 8; i++) {
+ if (i >= scene_data.directional_light_count) {
+ break;
+ }
+
if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) {
continue; //not masked
}
- vec3 shadow_attenuation = vec3(1.0);
-
-#ifdef LIGHT_TRANSMITTANCE_USED
- float transmittance_z = transmittance_depth;
-#endif
+ float shadow = 1.0;
+#ifdef USE_SOFT_SHADOWS
+ //version with soft shadows, more expensive
if (directional_lights.data[i].shadow_enabled) {
float depth_z = -vertex.z;
@@ -2366,8 +2550,6 @@ FRAGMENT_SHADER_CODE
normal_bias -= light_dir * dot(light_dir, normal_bias); \
m_var.xyz += normal_bias;
- float shadow = 0.0;
-
if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
vec4 v = vec4(vertex, 1.0);
@@ -2388,19 +2570,6 @@ FRAGMENT_SHADER_CODE
shadow_color = directional_lights.data[i].shadow_color1.rgb;
-#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
- vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
- trans_coord /= trans_coord.w;
-
- float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_z_range.x;
- float z = trans_coord.z * directional_lights.data[i].shadow_z_range.x;
-
- transmittance_z = z - shadow_z;
- }
-#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
vec4 v = vec4(vertex, 1.0);
@@ -2420,19 +2589,6 @@ FRAGMENT_SHADER_CODE
}
shadow_color = directional_lights.data[i].shadow_color2.rgb;
-#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
- vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
- trans_coord /= trans_coord.w;
-
- float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_z_range.y;
- float z = trans_coord.z * directional_lights.data[i].shadow_z_range.y;
-
- transmittance_z = z - shadow_z;
- }
-#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
vec4 v = vec4(vertex, 1.0);
@@ -2452,19 +2608,6 @@ FRAGMENT_SHADER_CODE
}
shadow_color = directional_lights.data[i].shadow_color3.rgb;
-#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
- vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
- trans_coord /= trans_coord.w;
-
- float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_z_range.z;
- float z = trans_coord.z * directional_lights.data[i].shadow_z_range.z;
-
- transmittance_z = z - shadow_z;
- }
-#endif
} else {
vec4 v = vec4(vertex, 1.0);
@@ -2485,20 +2628,6 @@ FRAGMENT_SHADER_CODE
}
shadow_color = directional_lights.data[i].shadow_color4.rgb;
-
-#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
- vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
- trans_coord /= trans_coord.w;
-
- float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_z_range.w;
- float z = trans_coord.z * directional_lights.data[i].shadow_z_range.w;
-
- transmittance_z = z - shadow_z;
- }
-#endif
}
if (directional_lights.data[i].blend_splits) {
@@ -2572,130 +2701,407 @@ FRAGMENT_SHADER_CODE
shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance
- shadow_attenuation = mix(shadow_color, vec3(1.0), shadow);
+#undef BIAS_FUNC
+ }
+#else
+ // Soft shadow disabled version
+
+ if (directional_lights.data[i].shadow_enabled) {
+ float depth_z = -vertex.z;
+
+ vec4 pssm_coord;
+ vec3 light_dir = directional_lights.data[i].direction;
+ vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp))));
+
+#define BIAS_FUNC(m_var, m_idx) \
+ m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \
+ vec3 normal_bias = base_normal_bias * directional_lights.data[i].shadow_normal_bias[m_idx]; \
+ normal_bias -= light_dir * dot(light_dir, normal_bias); \
+ m_var.xyz += normal_bias;
+
+ if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
+ vec4 v = vec4(vertex, 1.0);
+
+ BIAS_FUNC(v, 0)
+
+ pssm_coord = (directional_lights.data[i].shadow_matrix1 * v);
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
+ } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
+ vec4 v = vec4(vertex, 1.0);
+
+ BIAS_FUNC(v, 1)
+
+ pssm_coord = (directional_lights.data[i].shadow_matrix2 * v);
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
+ } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
+ vec4 v = vec4(vertex, 1.0);
+
+ BIAS_FUNC(v, 2)
+
+ pssm_coord = (directional_lights.data[i].shadow_matrix3 * v);
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
+
+ } else {
+ vec4 v = vec4(vertex, 1.0);
+
+ BIAS_FUNC(v, 3)
+
+ pssm_coord = (directional_lights.data[i].shadow_matrix4 * v);
+#ifdef LIGHT_TRANSMITTANCE_USED
+ {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
+ }
+
+ pssm_coord /= pssm_coord.w;
+
+ shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+
+ if (directional_lights.data[i].blend_splits) {
+ float pssm_blend;
+
+ if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
+ vec4 v = vec4(vertex, 1.0);
+ BIAS_FUNC(v, 1)
+ pssm_coord = (directional_lights.data[i].shadow_matrix2 * v);
+ pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z);
+ } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
+ vec4 v = vec4(vertex, 1.0);
+ BIAS_FUNC(v, 2)
+ pssm_coord = (directional_lights.data[i].shadow_matrix3 * v);
+ pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z);
+ } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
+ vec4 v = vec4(vertex, 1.0);
+ BIAS_FUNC(v, 3)
+ pssm_coord = (directional_lights.data[i].shadow_matrix4 * v);
+ pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z);
+ } else {
+ pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached)
+ }
+
+ pssm_coord /= pssm_coord.w;
+
+ float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord);
+ shadow = mix(shadow, shadow2, pssm_blend);
+ }
+
+ shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance
#undef BIAS_FUNC
}
+#endif
+
+ if (i < 4) {
+ shadow0 |= uint(clamp(shadow * 255.0, 0.0, 255.0)) << (i * 8);
+ } else {
+ shadow1 |= uint(clamp(shadow * 255.0, 0.0, 255.0)) << ((i - 4) * 8);
+ }
+ }
+
+ for (uint i = 0; i < 8; i++) {
+ if (i >= scene_data.directional_light_count) {
+ break;
+ }
+
+ if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
+
+#ifdef LIGHT_TRANSMITTANCE_USED
+ float transmittance_z = transmittance_depth;
+
+ if (directional_lights.data[i].shadow_enabled) {
+ float depth_z = -vertex.z;
+
+ if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x;
+
+ transmittance_z = z - shadow_z;
+ } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
+ trans_coord /= trans_coord.w;
- light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].size, directional_lights.data[i].color * directional_lights.data[i].energy, 1.0, shadow_attenuation, albedo, roughness, metallic, specular, directional_lights.data[i].specular * specular_blob_intensity,
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y;
+
+ transmittance_z = z - shadow_z;
+ } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z;
+
+ transmittance_z = z - shadow_z;
+
+ } else {
+ vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
+ vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
+ trans_coord /= trans_coord.w;
+
+ float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
+ shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w;
+ float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w;
+
+ transmittance_z = z - shadow_z;
+ }
+#endif
+
+ float shadow = 1.0;
+
+ if (i < 4) {
+ shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0;
+ } else {
+ shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
+ }
+
+ blur_shadow(shadow);
+
+ light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0,
#ifdef LIGHT_BACKLIGHT_USED
- backlight,
+ backlight,
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
- transmittance_color,
- transmittance_depth,
- transmittance_curve,
- transmittance_boost,
- transmittance_z,
+ transmittance_color,
+ transmittance_depth,
+ transmittance_curve,
+ transmittance_boost,
+ transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
- rim, rim_tint,
+ rim, rim_tint, albedo,
#endif
#ifdef LIGHT_CLEARCOAT_USED
- clearcoat, clearcoat_gloss,
+ clearcoat, clearcoat_gloss,
#endif
#ifdef LIGHT_ANISOTROPY_USED
- binormal, tangent, anisotropy,
+ binormal, tangent, anisotropy,
+#endif
+#ifdef USE_SOFT_SHADOW
+ directional_lights.data[i].size,
#endif
#ifdef USE_SHADOW_TO_OPACITY
- alpha,
+ alpha,
#endif
- diffuse_light,
- specular_light);
+ diffuse_light,
+ specular_light);
+ }
}
- }
- { //omni lights
+ { //omni lights
- uint omni_light_count = cluster_cell.x >> CLUSTER_COUNTER_SHIFT;
- uint omni_light_pointer = cluster_cell.x & CLUSTER_POINTER_MASK;
+ uint cluster_omni_offset = cluster_offset;
- for (uint i = 0; i < omni_light_count; i++) {
- uint light_index = cluster_data.indices[omni_light_pointer + i];
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
- if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
- continue; //not masked
- }
+ cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+
+#ifdef USE_SUBGROUPS
+ item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+ item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+#endif
+
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_omni_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+#ifdef USE_SUBGROUPS
+ uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+#else
+ uint merged_mask = mask;
+#endif
- light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity,
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1 << bit);
+#ifdef USE_SUBGROUPS
+ if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ continue;
+ }
+#endif
+ uint light_index = 32 * i + bit;
+
+ if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
+
+ float shadow = light_process_omni_shadow(light_index, vertex, view);
+
+ shadow = blur_shadow(shadow);
+
+ light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
#ifdef LIGHT_BACKLIGHT_USED
- backlight,
+ backlight,
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
- transmittance_color,
- transmittance_depth,
- transmittance_curve,
- transmittance_boost,
+ transmittance_color,
+ transmittance_depth,
+ transmittance_curve,
+ transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
- rim,
- rim_tint,
+ rim,
+ rim_tint,
+ albedo,
#endif
#ifdef LIGHT_CLEARCOAT_USED
- clearcoat, clearcoat_gloss,
+ clearcoat, clearcoat_gloss,
#endif
#ifdef LIGHT_ANISOTROPY_USED
- tangent, binormal, anisotropy,
+ tangent, binormal, anisotropy,
#endif
#ifdef USE_SHADOW_TO_OPACITY
- alpha,
+ alpha,
#endif
- diffuse_light, specular_light);
+ diffuse_light, specular_light);
+ }
+ }
}
- }
- { //spot lights
- uint spot_light_count = cluster_cell.y >> CLUSTER_COUNTER_SHIFT;
- uint spot_light_pointer = cluster_cell.y & CLUSTER_POINTER_MASK;
+ { //spot lights
- for (uint i = 0; i < spot_light_count; i++) {
- uint light_index = cluster_data.indices[spot_light_pointer + i];
+ uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size;
- if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
- continue; //not masked
- }
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
+
+ cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
- light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity,
+#ifdef USE_SUBGROUPS
+ item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+ item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+#endif
+
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_spot_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+#ifdef USE_SUBGROUPS
+ uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+#else
+ uint merged_mask = mask;
+#endif
+
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1 << bit);
+#ifdef USE_SUBGROUPS
+ if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ continue;
+ }
+#endif
+
+ uint light_index = 32 * i + bit;
+
+ if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
+
+ float shadow = light_process_spot_shadow(light_index, vertex, view);
+
+ shadow = blur_shadow(shadow);
+
+ light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
#ifdef LIGHT_BACKLIGHT_USED
- backlight,
+ backlight,
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
- transmittance_color,
- transmittance_depth,
- transmittance_curve,
- transmittance_boost,
+ transmittance_color,
+ transmittance_depth,
+ transmittance_curve,
+ transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
- rim,
- rim_tint,
+ rim,
+ rim_tint,
+ albedo,
#endif
#ifdef LIGHT_CLEARCOAT_USED
- clearcoat, clearcoat_gloss,
+ clearcoat, clearcoat_gloss,
#endif
#ifdef LIGHT_ANISOTROPY_USED
- tangent, binormal, anisotropy,
+ tangent, binormal, anisotropy,
#endif
#ifdef USE_SHADOW_TO_OPACITY
- alpha,
+ alpha,
#endif
- diffuse_light, specular_light);
+ diffuse_light, specular_light);
+ }
+ }
}
- }
#ifdef USE_SHADOW_TO_OPACITY
- alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
+ alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
#if defined(ALPHA_SCISSOR_USED)
- if (alpha < alpha_scissor) {
- discard;
- }
+ if (alpha < alpha_scissor) {
+ discard;
+ }
#endif // ALPHA_SCISSOR_USED
#ifdef USE_OPAQUE_PREPASS
- if (alpha < opaque_prepass_threshold) {
- discard;
- }
+ if (alpha < opaque_prepass_threshold) {
+ discard;
+ }
#endif // USE_OPAQUE_PREPASS
@@ -2707,173 +3113,149 @@ FRAGMENT_SHADER_CODE
#ifdef MODE_RENDER_SDF
- {
- vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
- ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size));
-
- uint albedo16 = 0x1; //solid flag
- albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;
- albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6;
- albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1;
-
- imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16));
-
- uint facing_bits = 0;
- const vec3 aniso_dir[6] = vec3[](
- vec3(1, 0, 0),
- vec3(0, 1, 0),
- vec3(0, 0, 1),
- vec3(-1, 0, 0),
- vec3(0, -1, 0),
- vec3(0, 0, -1));
-
- vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp);
-
- float closest_dist = -1e20;
-
- for (uint i = 0; i < 6; i++) {
- float d = dot(cam_normal, aniso_dir[i]);
- if (d > closest_dist) {
- closest_dist = d;
- facing_bits = (1 << i);
+ {
+ vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
+ ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size));
+
+ uint albedo16 = 0x1; //solid flag
+ albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;
+ albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6;
+ albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1;
+
+ imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16));
+
+ uint facing_bits = 0;
+ const vec3 aniso_dir[6] = vec3[](
+ vec3(1, 0, 0),
+ vec3(0, 1, 0),
+ vec3(0, 0, 1),
+ vec3(-1, 0, 0),
+ vec3(0, -1, 0),
+ vec3(0, 0, -1));
+
+ vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp);
+
+ float closest_dist = -1e20;
+
+ for (uint i = 0; i < 6; i++) {
+ float d = dot(cam_normal, aniso_dir[i]);
+ if (d > closest_dist) {
+ closest_dist = d;
+ facing_bits = (1 << i);
+ }
}
- }
- imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
+ imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
- if (length(emission) > 0.001) {
- float lumas[6];
- vec3 light_total = vec3(0);
+ if (length(emission) > 0.001) {
+ float lumas[6];
+ vec3 light_total = vec3(0);
- for (int i = 0; i < 6; i++) {
- float strength = max(0.0, dot(cam_normal, aniso_dir[i]));
- vec3 light = emission * strength;
- light_total += light;
- lumas[i] = max(light.r, max(light.g, light.b));
- }
+ for (int i = 0; i < 6; i++) {
+ float strength = max(0.0, dot(cam_normal, aniso_dir[i]));
+ vec3 light = emission * strength;
+ light_total += light;
+ lumas[i] = max(light.r, max(light.g, light.b));
+ }
- float luma_total = max(light_total.r, max(light_total.g, light_total.b));
+ float luma_total = max(light_total.r, max(light_total.g, light_total.b));
- uint light_aniso = 0;
+ uint light_aniso = 0;
- for (int i = 0; i < 6; i++) {
- light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5);
- }
+ for (int i = 0; i < 6; i++) {
+ light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5);
+ }
- //compress to RGBE9995 to save space
+ //compress to RGBE9995 to save space
- const float pow2to9 = 512.0f;
- const float B = 15.0f;
- const float N = 9.0f;
- const float LN2 = 0.6931471805599453094172321215;
+ const float pow2to9 = 512.0f;
+ const float B = 15.0f;
+ const float N = 9.0f;
+ const float LN2 = 0.6931471805599453094172321215;
- float cRed = clamp(light_total.r, 0.0, 65408.0);
- float cGreen = clamp(light_total.g, 0.0, 65408.0);
- float cBlue = clamp(light_total.b, 0.0, 65408.0);
+ float cRed = clamp(light_total.r, 0.0, 65408.0);
+ float cGreen = clamp(light_total.g, 0.0, 65408.0);
+ float cBlue = clamp(light_total.b, 0.0, 65408.0);
- float cMax = max(cRed, max(cGreen, cBlue));
+ float cMax = max(cRed, max(cGreen, cBlue));
- float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B;
+ float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B;
- float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f);
+ float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f);
- float exps = expp + 1.0f;
+ float exps = expp + 1.0f;
- if (0.0 <= sMax && sMax < pow2to9) {
- exps = expp;
- }
+ if (0.0 <= sMax && sMax < pow2to9) {
+ exps = expp;
+ }
- float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
- float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
- float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
- //store as 8985 to have 2 extra neighbour bits
- uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
+ float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
+ float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
+ float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
+ //store as 8985 to have 2 extra neighbour bits
+ uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
- imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
- imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
+ imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
+ imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
+ }
}
- }
#endif
#ifdef MODE_RENDER_MATERIAL
- albedo_output_buffer.rgb = albedo;
- albedo_output_buffer.a = alpha;
+ albedo_output_buffer.rgb = albedo;
+ albedo_output_buffer.a = alpha;
- normal_output_buffer.rgb = normal * 0.5 + 0.5;
- normal_output_buffer.a = 0.0;
- depth_output_buffer.r = -vertex.z;
+ normal_output_buffer.rgb = normal * 0.5 + 0.5;
+ normal_output_buffer.a = 0.0;
+ depth_output_buffer.r = -vertex.z;
-#if defined(AO_USED)
- orm_output_buffer.r = ao;
-#else
- orm_output_buffer.r = 0.0;
-#endif
- orm_output_buffer.g = roughness;
- orm_output_buffer.b = metallic;
- orm_output_buffer.a = sss_strength;
+ orm_output_buffer.r = ao;
+ orm_output_buffer.g = roughness;
+ orm_output_buffer.b = metallic;
+ orm_output_buffer.a = sss_strength;
- emission_output_buffer.rgb = emission;
- emission_output_buffer.a = 0.0;
+ emission_output_buffer.rgb = emission;
+ emission_output_buffer.a = 0.0;
#endif
#ifdef MODE_RENDER_NORMAL_ROUGHNESS
- normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
+ normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
#ifdef MODE_RENDER_GIPROBE
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
- uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
- uint index2 = instances.data[instance_index].gi_offset >> 16;
- giprobe_buffer.x = index1 & 0xFF;
- giprobe_buffer.y = index2 & 0xFF;
- } else {
- giprobe_buffer.x = 0xFF;
- giprobe_buffer.y = 0xFF;
- }
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
+ uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
+ uint index2 = instances.data[instance_index].gi_offset >> 16;
+ giprobe_buffer.x = index1 & 0xFF;
+ giprobe_buffer.y = index2 & 0xFF;
+ } else {
+ giprobe_buffer.x = 0xFF;
+ giprobe_buffer.y = 0xFF;
+ }
#endif
-#endif //MODE_RENDER_NORMAL
+#endif //MODE_RENDER_NORMAL_ROUGHNESS
//nothing happens, so a tree-ssa optimizer will result in no fragment shader :)
#else
- specular_light *= scene_data.reflection_multiplier;
- ambient_light *= albedo; //ambient must be multiplied by albedo at the end
-
-//ambient occlusion
-#if defined(AO_USED)
-
-#ifndef LOW_END_MODE
- if (scene_data.ssao_enabled && scene_data.ssao_ao_affect > 0.0) {
- float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
- ao = mix(ao, min(ao, ssao), scene_data.ssao_ao_affect);
- ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect);
- }
-#endif //LOW_END_MODE
-
- ambient_light = mix(scene_data.ao_color.rgb, ambient_light, ao);
- ao_light_affect = mix(1.0, ao, ao_light_affect);
- specular_light = mix(scene_data.ao_color.rgb, specular_light, ao_light_affect);
- diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect);
-#else
-
-#ifndef LOW_END_MODE
- if (scene_data.ssao_enabled) {
- float ao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
- ambient_light = mix(scene_data.ao_color.rgb, ambient_light, ao);
- float ao_light_affect = mix(1.0, ao, scene_data.ssao_light_affect);
- specular_light = mix(scene_data.ao_color.rgb, specular_light, ao_light_affect);
- diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect);
- }
-#endif //LOW_END_MODE
+ // multiply by albedo
+ diffuse_light *= albedo; // ambient must be multiplied by albedo at the end
-#endif // AO_USED
+ // apply direct light AO
+ ao = unpackUnorm4x8(orms).x;
+ specular_light *= ao;
+ diffuse_light *= ao;
- // base color remapping
- diffuse_light *= 1.0 - metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point
+ // apply metallic
+ metallic = unpackUnorm4x8(orms).z;
+ diffuse_light *= 1.0 - metallic;
ambient_light *= 1.0 - metallic;
+ //restore fog
+ fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba));
+
#ifdef MODE_MULTIPLE_RENDER_TARGETS
#ifdef MODE_UNSHADED
@@ -2889,25 +3271,8 @@ FRAGMENT_SHADER_CODE
specular_buffer = vec4(specular_light, metallic);
#endif
- // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
- if (scene_data.fog_enabled) {
- vec4 fog = fog_process(vertex);
- diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
- specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
- }
-
-#ifndef LOW_END_MODE
- if (scene_data.volumetric_fog_enabled) {
- vec4 fog = volumetric_fog_process(screen_uv, -vertex.z);
- diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
- specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
- }
-#endif // LOW_END_MODE
-
-#if defined(CUSTOM_FOG_USED)
- diffuse_buffer.rgb = mix(diffuse_buffer.rgb, custom_fog.rgb, custom_fog.a);
- specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), custom_fog.a);
-#endif //CUSTOM_FOG_USED
+ diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
+ specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
#else //MODE_MULTIPLE_RENDER_TARGETS
@@ -2919,22 +3284,10 @@ FRAGMENT_SHADER_CODE
#endif //USE_NO_SHADING
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
- if (scene_data.fog_enabled) {
- vec4 fog = fog_process(vertex);
- frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
- }
-#ifndef LOW_END_MODE
- if (scene_data.volumetric_fog_enabled) {
- vec4 fog = volumetric_fog_process(screen_uv, -vertex.z);
- frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
- }
-#endif
-
-#if defined(CUSTOM_FOG_USED)
- frag_color.rgb = mix(frag_color.rgb, custom_fog.rgb, custom_fog.a);
-#endif //CUSTOM_FOG_USED
+ frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
+ ;
#endif //MODE_MULTIPLE_RENDER_TARGETS
#endif //MODE_RENDER_DEPTH
-}
+ }
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
index fdc9941bba..d78890fa9e 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
@@ -3,9 +3,18 @@
#define MAX_GI_PROBES 8
+#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic)
+
+#extension GL_KHR_shader_subgroup_ballot : enable
+#extension GL_KHR_shader_subgroup_arithmetic : enable
+
+#define USE_SUBGROUPS
+
+#endif
+
#include "cluster_data_inc.glsl"
-#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_GIPROBE) || defined(TANGENT_USED) || defined(NORMALMAP_USED)
+#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_GIPROBE) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED)
#ifndef NORMAL_USED
#define NORMAL_USED
#endif
@@ -13,8 +22,9 @@
layout(push_constant, binding = 0, std430) uniform DrawCall {
uint instance_index;
- uint pad; //16 bits minimum size
- vec2 bake_uv2_offset; //used for bake to uv2, ignored otherwise
+ uint uv_offset;
+ uint pad0;
+ uint pad1;
}
draw_call;
@@ -33,91 +43,13 @@ draw_call;
#define SAMPLER_NEAREST_WITH_MIPMAPS_ANISOTROPIC_REPEAT 10
#define SAMPLER_LINEAR_WITH_MIPMAPS_ANISOTROPIC_REPEAT 11
-layout(set = 0, binding = 1) uniform sampler material_samplers[12];
-
-layout(set = 0, binding = 2) uniform sampler shadow_sampler;
-
#define SDFGI_MAX_CASCADES 8
-layout(set = 0, binding = 3, std140) uniform SceneData {
- mat4 projection_matrix;
- mat4 inv_projection_matrix;
-
- mat4 camera_matrix;
- mat4 inv_camera_matrix;
-
- vec2 viewport_size;
- vec2 screen_pixel_size;
-
- //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted
- vec4 directional_penumbra_shadow_kernel[32];
- vec4 directional_soft_shadow_kernel[32];
- vec4 penumbra_shadow_kernel[32];
- vec4 soft_shadow_kernel[32];
-
- uint directional_penumbra_shadow_samples;
- uint directional_soft_shadow_samples;
- uint penumbra_shadow_samples;
- uint soft_shadow_samples;
-
- vec4 ambient_light_color_energy;
-
- float ambient_color_sky_mix;
- bool use_ambient_light;
- bool use_ambient_cubemap;
- bool use_reflection_cubemap;
-
- mat3 radiance_inverse_xform;
-
- vec2 shadow_atlas_pixel_size;
- vec2 directional_shadow_pixel_size;
-
- uint directional_light_count;
- float dual_paraboloid_side;
- float z_far;
- float z_near;
-
- bool ssao_enabled;
- float ssao_light_affect;
- float ssao_ao_affect;
- bool roughness_limiter_enabled;
-
- float roughness_limiter_amount;
- float roughness_limiter_limit;
- uvec2 roughness_limiter_pad;
-
- vec4 ao_color;
-
- mat4 sdf_to_bounds;
-
- ivec3 sdf_offset;
- bool material_uv2_mode;
-
- ivec3 sdf_size;
- bool gi_upscale_for_msaa;
-
- bool volumetric_fog_enabled;
- float volumetric_fog_inv_length;
- float volumetric_fog_detail_spread;
- uint volumetric_fog_pad;
-
- bool fog_enabled;
- float fog_density;
- float fog_height;
- float fog_height_density;
-
- vec3 fog_light_color;
- float fog_sun_scatter;
-
- float fog_aerial_perspective;
-
- float time;
- float reflection_multiplier; // one normally, zero when rendering reflections
+/* Set 1: Base Pass (never changes) */
- bool pancake_shadows;
-}
+layout(set = 0, binding = 1) uniform sampler material_samplers[12];
-scene_data;
+layout(set = 0, binding = 2) uniform sampler shadow_sampler;
#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6)
#define INSTANCE_FLAGS_USE_SDFGI (1 << 7)
@@ -134,33 +66,24 @@ scene_data;
#define INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK 0x7
#define INSTANCE_FLAGS_SKELETON (1 << 19)
+#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20)
-struct InstanceData {
- mat4 transform;
- mat4 normal_transform;
- uint flags;
- uint instance_uniforms_ofs; //base offset in global buffer for instance variables
- uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
- uint layer_mask;
- vec4 lightmap_uv_scale;
-};
-
-layout(set = 0, binding = 4, std430) restrict readonly buffer Instances {
- InstanceData data[];
+layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights {
+ LightData data[];
}
-instances;
+omni_lights;
-layout(set = 0, binding = 5, std430) restrict readonly buffer Lights {
+layout(set = 0, binding = 4, std430) restrict readonly buffer SpotLights {
LightData data[];
}
-lights;
+spot_lights;
-layout(set = 0, binding = 6) buffer restrict readonly ReflectionProbeData {
+layout(set = 0, binding = 5) buffer restrict readonly ReflectionProbeData {
ReflectionData data[];
}
reflections;
-layout(set = 0, binding = 7, std140) uniform DirectionalLights {
+layout(set = 0, binding = 6, std140) uniform DirectionalLights {
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
}
directional_lights;
@@ -172,40 +95,29 @@ struct Lightmap {
mat3 normal_xform;
};
-layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps {
+layout(set = 0, binding = 7, std140) restrict readonly buffer Lightmaps {
Lightmap data[];
}
lightmaps;
-layout(set = 0, binding = 11) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
-
struct LightmapCapture {
vec4 sh[9];
};
-layout(set = 0, binding = 12, std140) restrict readonly buffer LightmapCaptures {
+layout(set = 0, binding = 8, std140) restrict readonly buffer LightmapCaptures {
LightmapCapture data[];
}
lightmap_captures;
-layout(set = 0, binding = 13) uniform texture2D decal_atlas;
-layout(set = 0, binding = 14) uniform texture2D decal_atlas_srgb;
+layout(set = 0, binding = 9) uniform texture2D decal_atlas;
+layout(set = 0, binding = 10) uniform texture2D decal_atlas_srgb;
-layout(set = 0, binding = 15, std430) restrict readonly buffer Decals {
+layout(set = 0, binding = 11, std430) restrict readonly buffer Decals {
DecalData data[];
}
decals;
-layout(set = 0, binding = 16) uniform utexture3D cluster_texture;
-
-layout(set = 0, binding = 17, std430) restrict readonly buffer ClusterData {
- uint indices[];
-}
-cluster_data;
-
-layout(set = 0, binding = 18) uniform texture2D directional_shadow_atlas;
-
-layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableData {
+layout(set = 0, binding = 12, std430) restrict readonly buffer GlobalVariableData {
vec4 data[];
}
global_variables;
@@ -219,7 +131,7 @@ struct SDFGIProbeCascadeData {
float to_cell; // 1/bounds * grid_size
};
-layout(set = 0, binding = 20, std140) uniform SDFGI {
+layout(set = 0, binding = 13, std140) uniform SDFGI {
vec3 grid_size;
uint max_cascades;
@@ -249,38 +161,140 @@ sdfgi;
#endif //LOW_END_MODE
-// decal atlas
+/* Set 2: Render Pass (changes per render pass) */
+
+layout(set = 1, binding = 0, std140) uniform SceneData {
+ mat4 projection_matrix;
+ mat4 inv_projection_matrix;
+
+ mat4 camera_matrix;
+ mat4 inv_camera_matrix;
+
+ vec2 viewport_size;
+ vec2 screen_pixel_size;
+
+ uint cluster_shift;
+ uint cluster_width;
+ uint cluster_type_size;
+ uint max_cluster_element_count_div_32;
+
+ //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted
+ vec4 directional_penumbra_shadow_kernel[32];
+ vec4 directional_soft_shadow_kernel[32];
+ vec4 penumbra_shadow_kernel[32];
+ vec4 soft_shadow_kernel[32];
+
+ uint directional_penumbra_shadow_samples;
+ uint directional_soft_shadow_samples;
+ uint penumbra_shadow_samples;
+ uint soft_shadow_samples;
+
+ vec4 ambient_light_color_energy;
+
+ float ambient_color_sky_mix;
+ bool use_ambient_light;
+ bool use_ambient_cubemap;
+ bool use_reflection_cubemap;
-/* Set 1, Radiance */
+ mat3 radiance_inverse_xform;
+
+ vec2 shadow_atlas_pixel_size;
+ vec2 directional_shadow_pixel_size;
+
+ uint directional_light_count;
+ float dual_paraboloid_side;
+ float z_far;
+ float z_near;
+
+ bool ssao_enabled;
+ float ssao_light_affect;
+ float ssao_ao_affect;
+ bool roughness_limiter_enabled;
+
+ float roughness_limiter_amount;
+ float roughness_limiter_limit;
+ uvec2 roughness_limiter_pad;
+
+ vec4 ao_color;
+
+ mat4 sdf_to_bounds;
+
+ ivec3 sdf_offset;
+ bool material_uv2_mode;
+
+ ivec3 sdf_size;
+ bool gi_upscale_for_msaa;
+
+ bool volumetric_fog_enabled;
+ float volumetric_fog_inv_length;
+ float volumetric_fog_detail_spread;
+ uint volumetric_fog_pad;
+
+ bool fog_enabled;
+ float fog_density;
+ float fog_height;
+ float fog_height_density;
+
+ vec3 fog_light_color;
+ float fog_sun_scatter;
+
+ float fog_aerial_perspective;
+
+ float time;
+ float reflection_multiplier; // one normally, zero when rendering reflections
+
+ bool pancake_shadows;
+}
+
+scene_data;
+
+struct InstanceData {
+ mat4 transform;
+ uint flags;
+ uint instance_uniforms_ofs; //base offset in global buffer for instance variables
+ uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
+ uint layer_mask;
+ vec4 lightmap_uv_scale;
+};
+
+layout(set = 1, binding = 1, std430) buffer restrict readonly InstanceDataBuffer {
+ InstanceData data[];
+}
+instances;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
-layout(set = 1, binding = 0) uniform textureCubeArray radiance_cubemap;
+layout(set = 1, binding = 2) uniform textureCubeArray radiance_cubemap;
#else
-layout(set = 1, binding = 0) uniform textureCube radiance_cubemap;
+layout(set = 1, binding = 2) uniform textureCube radiance_cubemap;
#endif
-/* Set 2, Reflection and Shadow Atlases (view dependent) */
+layout(set = 1, binding = 3) uniform textureCubeArray reflection_atlas;
-layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas;
+layout(set = 1, binding = 4) uniform texture2D shadow_atlas;
-layout(set = 1, binding = 2) uniform texture2D shadow_atlas;
+layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas;
-#ifndef LOW_END_MODE
-layout(set = 1, binding = 3) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
+layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
+
+#ifndef LOW_END_MOD
+layout(set = 1, binding = 7) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
#endif
-/* Set 3, Render Buffers */
+layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer {
+ uint data[];
+}
+cluster_buffer;
#ifdef MODE_RENDER_SDF
-layout(r16ui, set = 1, binding = 4) uniform restrict writeonly uimage3D albedo_volume_grid;
-layout(r32ui, set = 1, binding = 5) uniform restrict writeonly uimage3D emission_grid;
-layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_aniso_grid;
-layout(r32ui, set = 1, binding = 7) uniform restrict uimage3D geom_facing_grid;
+layout(r16ui, set = 1, binding = 9) uniform restrict writeonly uimage3D albedo_volume_grid;
+layout(r32ui, set = 1, binding = 10) uniform restrict writeonly uimage3D emission_grid;
+layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_aniso_grid;
+layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid;
//still need to be present for shaders that use it, so remap them to something
#define depth_buffer shadow_atlas
@@ -289,17 +303,17 @@ layout(r32ui, set = 1, binding = 7) uniform restrict uimage3D geom_facing_grid;
#else
-layout(set = 1, binding = 4) uniform texture2D depth_buffer;
-layout(set = 1, binding = 5) uniform texture2D color_buffer;
+layout(set = 1, binding = 9) uniform texture2D depth_buffer;
+layout(set = 1, binding = 10) uniform texture2D color_buffer;
#ifndef LOW_END_MODE
-layout(set = 1, binding = 6) uniform texture2D normal_roughness_buffer;
-layout(set = 1, binding = 7) uniform texture2D ao_buffer;
-layout(set = 1, binding = 8) uniform texture2D ambient_buffer;
-layout(set = 1, binding = 9) uniform texture2D reflection_buffer;
-layout(set = 1, binding = 10) uniform texture2DArray sdfgi_lightprobe_texture;
-layout(set = 1, binding = 11) uniform texture3D sdfgi_occlusion_cascades;
+layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer;
+layout(set = 1, binding = 12) uniform texture2D ao_buffer;
+layout(set = 1, binding = 13) uniform texture2D ambient_buffer;
+layout(set = 1, binding = 14) uniform texture2D reflection_buffer;
+layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture;
+layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades;
struct GIProbeData {
mat4 xform;
@@ -317,22 +331,22 @@ struct GIProbeData {
uint mipmaps;
};
-layout(set = 1, binding = 12, std140) uniform GIProbes {
+layout(set = 1, binding = 17, std140) uniform GIProbes {
GIProbeData data[MAX_GI_PROBES];
}
gi_probes;
-layout(set = 1, binding = 13) uniform texture3D volumetric_fog_texture;
+layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture;
#endif // LOW_END_MODE
#endif
-/* Set 4 Skeleton & Instancing (Multimesh) */
+/* Set 2 Skeleton & Instancing (can change per item) */
layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms {
vec4 data[];
}
transforms;
-/* Set 5 User Material */
+/* Set 3 User Material */
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl
index 813ea29fa1..e4c3f3a84b 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl
@@ -97,6 +97,8 @@ void main() {
float blend = 0.0;
#if 1
+ // No interpolation
+
vec3 inv_dir = 1.0 / ray_dir;
float rough = 0.5;
@@ -161,114 +163,11 @@ void main() {
hit_light *= (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0)));
- if (blend > 0.0) {
- light = mix(light, hit_light, blend);
- blend = 0.0;
- } else {
- light = hit_light;
-
- //process blend
- float blend_from = (float(params.probe_axis_size - 1) / 2.0) - 2.5;
- float blend_to = blend_from + 2.0;
-
- vec3 cam_pos = params.cam_transform[3].xyz - cascades.data[i].offset;
- cam_pos *= cascades.data[i].to_cell;
-
- pos += ray_dir * min(advance, max_advance);
- vec3 inner_pos = pos - cam_pos;
-
- inner_pos = inner_pos * float(params.probe_axis_size - 1) / params.grid_size.x;
-
- float len = length(inner_pos);
-
- inner_pos = abs(normalize(inner_pos));
- len *= max(inner_pos.x, max(inner_pos.y, inner_pos.z));
-
- if (len >= blend_from) {
- blend = smoothstep(blend_from, blend_to, len);
-
- pos /= cascades.data[i].to_cell;
- pos += cascades.data[i].offset;
- ray_pos = pos;
- hit = false; //continue trace for blend
-
- continue;
- }
- }
+ light = hit_light;
break;
}
- light = mix(light, vec3(0.0), blend);
-
-#else
-
- vec3 inv_dir = 1.0 / ray_dir;
-
- bool hit = false;
- vec4 light_accum = vec4(0.0);
-
- float blend_size = (params.grid_size.x / float(params.probe_axis_size - 1)) * 0.5;
-
- float radius_sizes[MAX_CASCADES];
- for (uint i = 0; i < params.max_cascades; i++) {
- radius_sizes[i] = (1.0 / cascades.data[i].to_cell) * (params.grid_size.x * 0.5 - blend_size);
- }
-
- float max_distance = radius_sizes[params.max_cascades - 1];
- float advance = 0;
- while (advance < max_distance) {
- for (uint i = 0; i < params.max_cascades; i++) {
- if (advance < radius_sizes[i]) {
- vec3 pos = (ray_pos + ray_dir * advance) - cascades.data[i].offset;
- pos *= cascades.data[i].to_cell * pos_to_uvw;
-
- float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), pos).r * 255.0 - 1.0;
-
- vec4 hit_light = vec4(0.0);
- if (distance < 1.0) {
- hit_light.a = max(0.0, 1.0 - distance);
- hit_light.rgb = texture(sampler3D(light_cascades[i], linear_sampler), pos).rgb;
- hit_light.rgb *= hit_light.a;
- }
-
- distance /= cascades.data[i].to_cell;
-
- if (i < (params.max_cascades - 1)) {
- pos = (ray_pos + ray_dir * advance) - cascades.data[i + 1].offset;
- pos *= cascades.data[i + 1].to_cell * pos_to_uvw;
-
- float distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.0;
-
- vec4 hit_light2 = vec4(0.0);
- if (distance2 < 1.0) {
- hit_light2.a = max(0.0, 1.0 - distance2);
- hit_light2.rgb = texture(sampler3D(light_cascades[i + 1], linear_sampler), pos).rgb;
- hit_light2.rgb *= hit_light2.a;
- }
-
- float prev_radius = i == 0 ? 0.0 : radius_sizes[i - 1];
- float blend = (advance - prev_radius) / (radius_sizes[i] - prev_radius);
-
- distance2 /= cascades.data[i + 1].to_cell;
-
- hit_light = mix(hit_light, hit_light2, blend);
- distance = mix(distance, distance2, blend);
- }
-
- light_accum += hit_light;
- advance += distance;
- break;
- }
- }
-
- if (light_accum.a > 0.98) {
- break;
- }
- }
-
- light = light_accum.rgb / light_accum.a;
-
#endif
imageStore(screen_buffer, screen_pos, vec4(linear_to_srgb(light), 1.0));
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
index 61e4bf5e18..dc7238abed 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
@@ -67,8 +67,8 @@ struct Light {
float attenuation;
uint type;
- float spot_angle;
- float spot_attenuation;
+ float cos_spot_angle;
+ float inv_spot_attenuation;
float radius;
vec4 shadow_color;
@@ -80,6 +80,7 @@ layout(set = 0, binding = 9, std140) buffer restrict readonly Lights {
lights;
layout(set = 0, binding = 10) uniform texture2DArray lightprobe_texture;
+layout(set = 0, binding = 11) uniform texture3D occlusion_texture;
layout(push_constant, binding = 0, std430) uniform Params {
vec3 grid_size;
@@ -91,9 +92,9 @@ layout(push_constant, binding = 0, std430) uniform Params {
uint process_increment;
int probe_axis_size;
- bool multibounce;
+ float bounce_feedback;
float y_mult;
- uint pad;
+ bool use_occlusion;
}
params;
@@ -112,11 +113,23 @@ vec2 octahedron_encode(vec3 n) {
return n.xy;
}
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
void main() {
uint voxel_index = uint(gl_GlobalInvocationID.x);
//used for skipping voxels every N frames
- voxel_index = params.process_offset + voxel_index * params.process_increment;
+ if (params.process_increment > 1) {
+ voxel_index *= params.process_increment;
+ voxel_index += params.process_offset;
+ }
if (voxel_index >= dispatch_data.total_count) {
return;
@@ -134,10 +147,96 @@ void main() {
uint voxel_albedo = process_voxels.data[voxel_index].albedo;
vec3 albedo = vec3(uvec3(voxel_albedo >> 10, voxel_albedo >> 5, voxel_albedo) & uvec3(0x1F)) / float(0x1F);
- vec3 light_accum[6];
-
+ vec3 light_accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
uint valid_aniso = (voxel_albedo >> 15) & 0x3F;
+ const vec3 aniso_dir[6] = vec3[](
+ vec3(1, 0, 0),
+ vec3(0, 1, 0),
+ vec3(0, 0, 1),
+ vec3(-1, 0, 0),
+ vec3(0, -1, 0),
+ vec3(0, 0, -1));
+
+ // Add indirect light first, in order to save computation resources
+#ifdef MODE_PROCESS_DYNAMIC
+ if (params.bounce_feedback > 0.001) {
+ vec3 feedback = (params.bounce_feedback < 1.0) ? (albedo * params.bounce_feedback) : mix(albedo, vec3(1.0), params.bounce_feedback - 1.0);
+ vec3 pos = (vec3(positioni) + vec3(0.5)) * float(params.probe_axis_size - 1) / params.grid_size;
+ ivec3 probe_base_pos = ivec3(pos);
+
+ float weight_accum[6] = float[](0, 0, 0, 0, 0, 0);
+
+ ivec3 tex_pos = ivec3(probe_base_pos.xy, int(params.cascade));
+ tex_pos.x += probe_base_pos.z * int(params.probe_axis_size);
+
+ tex_pos.xy = tex_pos.xy * (OCT_SIZE + 2) + ivec2(1);
+
+ vec3 base_tex_posf = vec3(tex_pos);
+ vec2 tex_pixel_size = 1.0 / vec2(ivec2((OCT_SIZE + 2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE + 2) * params.probe_axis_size));
+ vec3 probe_uv_offset = vec3(ivec3(OCT_SIZE + 2, OCT_SIZE + 2, (OCT_SIZE + 2) * params.probe_axis_size)) * tex_pixel_size.xyx;
+
+ for (uint j = 0; j < 8; j++) {
+ ivec3 offset = (ivec3(j) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1);
+ ivec3 probe_posi = probe_base_pos;
+ probe_posi += offset;
+
+ // Compute weight
+
+ vec3 probe_pos = vec3(probe_posi);
+ vec3 probe_to_pos = pos - probe_pos;
+ vec3 probe_dir = normalize(-probe_to_pos);
+
+ // Compute lightprobe texture position
+
+ vec3 trilinear = vec3(1.0) - abs(probe_to_pos);
+
+ for (uint k = 0; k < 6; k++) {
+ if (bool(valid_aniso & (1 << k))) {
+ vec3 n = aniso_dir[k];
+ float weight = trilinear.x * trilinear.y * trilinear.z * max(0, dot(n, probe_dir));
+
+ if (weight > 0.0 && params.use_occlusion) {
+ ivec3 occ_indexv = abs((cascades.data[params.cascade].probe_world_offset + probe_posi) & ivec3(1, 1, 1)) * ivec3(1, 2, 4);
+ vec4 occ_mask = mix(vec4(0.0), vec4(1.0), equal(ivec4(occ_indexv.x | occ_indexv.y), ivec4(0, 1, 2, 3)));
+
+ vec3 occ_pos = (vec3(positioni) + aniso_dir[k] + vec3(0.5)) / params.grid_size;
+ occ_pos.z += float(params.cascade);
+ if (occ_indexv.z != 0) { //z bit is on, means index is >=4, so make it switch to the other half of textures
+ occ_pos.x += 1.0;
+ }
+ occ_pos *= vec3(0.5, 1.0, 1.0 / float(params.max_cascades)); //renormalize
+ float occlusion = dot(textureLod(sampler3D(occlusion_texture, linear_sampler), occ_pos, 0.0), occ_mask);
+
+ weight *= occlusion;
+ }
+
+ if (weight > 0.0) {
+ vec3 tex_posf = base_tex_posf + vec3(octahedron_encode(n) * float(OCT_SIZE), 0.0);
+ tex_posf.xy *= tex_pixel_size;
+
+ vec3 pos_uvw = tex_posf;
+ pos_uvw.xy += vec2(offset.xy) * probe_uv_offset.xy;
+ pos_uvw.x += float(offset.z) * probe_uv_offset.z;
+ vec3 indirect_light = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0).rgb;
+
+ light_accum[k] += indirect_light * weight;
+ weight_accum[k] += weight;
+ }
+ }
+ }
+ }
+
+ for (uint k = 0; k < 6; k++) {
+ if (weight_accum[k] > 0.0) {
+ light_accum[k] /= weight_accum[k];
+ light_accum[k] *= feedback;
+ }
+ }
+ }
+
+#endif
+
{
uint rgbe = process_voxels.data[voxel_index].light;
@@ -153,18 +252,10 @@ void main() {
uint aniso = process_voxels.data[voxel_index].light_aniso;
for (uint i = 0; i < 6; i++) {
float strength = ((aniso >> (i * 5)) & 0x1F) / float(0x1F);
- light_accum[i] = l * strength;
+ light_accum[i] += l * strength;
}
}
- const vec3 aniso_dir[6] = vec3[](
- vec3(1, 0, 0),
- vec3(0, 1, 0),
- vec3(0, 0, 1),
- vec3(-1, 0, 0),
- vec3(0, -1, 0),
- vec3(0, 0, -1));
-
// Raytrace light
vec3 pos_to_uvw = 1.0 / params.grid_size;
@@ -184,22 +275,26 @@ void main() {
direction = normalize(rel_vec);
light_distance = length(rel_vec);
rel_vec.y /= params.y_mult;
- attenuation = pow(clamp(1.0 - length(rel_vec) / lights.data[i].radius, 0.0, 1.0), lights.data[i].attenuation);
+ attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation);
+
} break;
case LIGHT_TYPE_SPOT: {
vec3 rel_vec = lights.data[i].position - position;
direction = normalize(rel_vec);
light_distance = length(rel_vec);
rel_vec.y /= params.y_mult;
- attenuation = pow(clamp(1.0 - length(rel_vec) / lights.data[i].radius, 0.0, 1.0), lights.data[i].attenuation);
-
- float angle = acos(dot(normalize(rel_vec), -lights.data[i].direction));
- if (angle > lights.data[i].spot_angle) {
- attenuation = 0.0;
- } else {
- float d = clamp(angle / lights.data[i].spot_angle, 0, 1);
- attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation);
+ attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation);
+
+ float cos_spot_angle = lights.data[i].cos_spot_angle;
+ float cos_angle = dot(-direction, lights.data[i].direction);
+
+ if (cos_angle < cos_spot_angle) {
+ continue;
}
+
+ float scos = max(cos_angle, cos_spot_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
+ attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation);
} break;
}
@@ -282,65 +377,6 @@ void main() {
}
}
- // Add indirect light
-
- if (params.multibounce) {
- vec3 pos = (vec3(positioni) + vec3(0.5)) * float(params.probe_axis_size - 1) / params.grid_size;
- ivec3 probe_base_pos = ivec3(pos);
-
- vec4 probe_accum[6] = vec4[](vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0));
- float weight_accum[6] = float[](0, 0, 0, 0, 0, 0);
-
- ivec3 tex_pos = ivec3(probe_base_pos.xy, int(params.cascade));
- tex_pos.x += probe_base_pos.z * int(params.probe_axis_size);
-
- tex_pos.xy = tex_pos.xy * (OCT_SIZE + 2) + ivec2(1);
-
- vec3 base_tex_posf = vec3(tex_pos);
- vec2 tex_pixel_size = 1.0 / vec2(ivec2((OCT_SIZE + 2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE + 2) * params.probe_axis_size));
- vec3 probe_uv_offset = (ivec3(OCT_SIZE + 2, OCT_SIZE + 2, (OCT_SIZE + 2) * params.probe_axis_size)) * tex_pixel_size.xyx;
-
- for (uint j = 0; j < 8; j++) {
- ivec3 offset = (ivec3(j) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1);
- ivec3 probe_posi = probe_base_pos;
- probe_posi += offset;
-
- // Compute weight
-
- vec3 probe_pos = vec3(probe_posi);
- vec3 probe_to_pos = pos - probe_pos;
- vec3 probe_dir = normalize(-probe_to_pos);
-
- // Compute lightprobe texture position
-
- vec3 trilinear = vec3(1.0) - abs(probe_to_pos);
-
- for (uint k = 0; k < 6; k++) {
- if (bool(valid_aniso & (1 << k))) {
- vec3 n = aniso_dir[k];
- float weight = trilinear.x * trilinear.y * trilinear.z * max(0.005, dot(n, probe_dir));
-
- vec3 tex_posf = base_tex_posf + vec3(octahedron_encode(n) * float(OCT_SIZE), 0.0);
- tex_posf.xy *= tex_pixel_size;
-
- vec3 pos_uvw = tex_posf;
- pos_uvw.xy += vec2(offset.xy) * probe_uv_offset.xy;
- pos_uvw.x += float(offset.z) * probe_uv_offset.z;
- vec4 indirect_light = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0);
-
- probe_accum[k] += indirect_light * weight;
- weight_accum[k] += weight;
- }
- }
- }
-
- for (uint k = 0; k < 6; k++) {
- if (weight_accum[k] > 0.0) {
- light_accum[k] += probe_accum[k].rgb * albedo / weight_accum[k];
- }
- }
- }
-
// Store the light in the light texture
float lumas[6];
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
index d516ab22c3..007e4c113a 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
@@ -39,8 +39,11 @@ layout(rgba32i, set = 0, binding = 13) uniform restrict iimage2D lightprobe_aver
layout(rgba16f, set = 0, binding = 14) uniform restrict writeonly image2DArray lightprobe_ambient_texture;
+#ifdef USE_CUBEMAP_ARRAY
+layout(set = 1, binding = 0) uniform textureCubeArray sky_irradiance;
+#else
layout(set = 1, binding = 0) uniform textureCube sky_irradiance;
-
+#endif
layout(set = 1, binding = 1) uniform sampler linear_sampler_mipmaps;
#define HISTORY_BITS 10
@@ -136,12 +139,24 @@ uint rgbe_encode(vec3 color) {
return (uint(sRed) & 0x1FF) | ((uint(sGreen) & 0x1FF) << 9) | ((uint(sBlue) & 0x1FF) << 18) | ((uint(exps) & 0x1F) << 27);
}
+struct SH {
+#if (SH_SIZE == 16)
+ float c[48];
+#else
+ float c[28];
+#endif
+};
+
+shared SH sh_accum[64]; //8x8
+
void main() {
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
if (any(greaterThanEqual(pos, params.image_size))) { //too large, do nothing
return;
}
+ uint probe_index = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 8;
+
#ifdef MODE_PROCESS
float probe_cell_size = float(params.grid_size.x / float(params.probe_axis_size - 1)) / cascades.data[params.cascade].to_cell;
@@ -154,27 +169,9 @@ void main() {
vec3 probe_pos = cascades.data[params.cascade].offset + vec3(probe_cell) * probe_cell_size;
vec3 pos_to_uvw = 1.0 / params.grid_size;
- vec4 probe_sh_accum[SH_SIZE] = vec4[](
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0)
-#if (SH_SIZE == 16)
- ,
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0),
- vec4(0.0)
-#endif
- );
+ for (uint i = 0; i < SH_SIZE * 3; i++) {
+ sh_accum[probe_index].c[i] = 0.0;
+ }
// quickly ensure each probe has a different "offset" for the vogel function, based on integer world position
uvec3 h3 = hash3(uvec3(params.world_offset + probe_cell));
@@ -195,14 +192,12 @@ void main() {
vec3 inv_dir = 1.0 / ray_dir;
bool hit = false;
- vec3 hit_normal;
- vec3 hit_light;
- vec3 hit_aniso0;
- vec3 hit_aniso1;
+ uint hit_cascade;
float bias = params.ray_bias;
vec3 abs_ray_dir = abs(ray_dir);
ray_pos += ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) * bias / cascades.data[params.cascade].to_cell;
+ vec3 uvw;
for (uint j = params.cascade; j < params.max_cascades; j++) {
//convert to local bounds
@@ -221,14 +216,12 @@ void main() {
float advance = 0.0;
- vec3 uvw;
-
while (advance < max_advance) {
//read how much to advance from SDF
uvw = (pos + ray_dir * advance) * pos_to_uvw;
float distance = texture(sampler3D(sdf_cascades[j], linear_sampler), uvw).r * 255.0 - 1.0;
- if (distance < 0.001) {
+ if (distance < 0.05) {
//consider hit
hit = true;
break;
@@ -238,17 +231,7 @@ void main() {
}
if (hit) {
- const float EPSILON = 0.001;
- hit_normal = normalize(vec3(
- texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r,
- texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r,
- texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r));
-
- hit_light = texture(sampler3D(light_cascades[j], linear_sampler), uvw).rgb;
- vec4 aniso0 = texture(sampler3D(aniso0_cascades[j], linear_sampler), uvw);
- hit_aniso0 = aniso0.rgb;
- hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[j], linear_sampler), uvw).rg);
-
+ hit_cascade = j;
break;
}
@@ -261,11 +244,32 @@ void main() {
vec4 light;
if (hit) {
- //one liner magic
- light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0)));
- light.a = 1.0;
+ //avoid reading different texture from different threads
+ for (uint j = params.cascade; j < params.max_cascades; j++) {
+ if (j == hit_cascade) {
+ const float EPSILON = 0.001;
+ vec3 hit_normal = normalize(vec3(
+ texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r,
+ texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r,
+ texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r));
+
+ vec3 hit_light = texture(sampler3D(light_cascades[hit_cascade], linear_sampler), uvw).rgb;
+ vec4 aniso0 = texture(sampler3D(aniso0_cascades[hit_cascade], linear_sampler), uvw);
+ vec3 hit_aniso0 = aniso0.rgb;
+ vec3 hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[hit_cascade], linear_sampler), uvw).rg);
+
+ //one liner magic
+ light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0)));
+ light.a = 1.0;
+ }
+ }
+
} else if (params.sky_mode == SKY_MODE_SKY) {
+#ifdef USE_CUBEMAP_ARRAY
+ light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates
+#else
light.rgb = textureLod(samplerCube(sky_irradiance, linear_sampler_mipmaps), ray_dir, 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates
+#endif
light.rgb *= params.sky_energy;
light.a = 0.0;
@@ -278,33 +282,33 @@ void main() {
}
vec3 ray_dir2 = ray_dir * ray_dir;
- float c[SH_SIZE] = float[](
-
- 0.282095, //l0
- 0.488603 * ray_dir.y, //l1n1
- 0.488603 * ray_dir.z, //l1n0
- 0.488603 * ray_dir.x, //l1p1
- 1.092548 * ray_dir.x * ray_dir.y, //l2n2
- 1.092548 * ray_dir.y * ray_dir.z, //l2n1
- 0.315392 * (3.0 * ray_dir2.z - 1.0), //l20
- 1.092548 * ray_dir.x * ray_dir.z, //l2p1
- 0.546274 * (ray_dir2.x - ray_dir2.y) //l2p2
+
+#define SH_ACCUM(m_idx, m_value) \
+ { \
+ vec3 l = light.rgb * (m_value); \
+ sh_accum[probe_index].c[m_idx * 3 + 0] += l.r; \
+ sh_accum[probe_index].c[m_idx * 3 + 1] += l.g; \
+ sh_accum[probe_index].c[m_idx * 3 + 2] += l.b; \
+ }
+ SH_ACCUM(0, 0.282095); //l0
+ SH_ACCUM(1, 0.488603 * ray_dir.y); //l1n1
+ SH_ACCUM(2, 0.488603 * ray_dir.z); //l1n0
+ SH_ACCUM(3, 0.488603 * ray_dir.x); //l1p1
+ SH_ACCUM(4, 1.092548 * ray_dir.x * ray_dir.y); //l2n2
+ SH_ACCUM(5, 1.092548 * ray_dir.y * ray_dir.z); //l2n1
+ SH_ACCUM(6, 0.315392 * (3.0 * ray_dir2.z - 1.0)); //l20
+ SH_ACCUM(7, 1.092548 * ray_dir.x * ray_dir.z); //l2p1
+ SH_ACCUM(8, 0.546274 * (ray_dir2.x - ray_dir2.y)); //l2p2
#if (SH_SIZE == 16)
- ,
- 0.590043 * ray_dir.y * (3.0f * ray_dir2.x - ray_dir2.y),
- 2.890611 * ray_dir.y * ray_dir.x * ray_dir.z,
- 0.646360 * ray_dir.y * (-1.0f + 5.0f * ray_dir2.z),
- 0.373176 * (5.0f * ray_dir2.z * ray_dir.z - 3.0f * ray_dir.z),
- 0.457045 * ray_dir.x * (-1.0f + 5.0f * ray_dir2.z),
- 1.445305 * (ray_dir2.x - ray_dir2.y) * ray_dir.z,
- 0.590043 * ray_dir.x * (ray_dir2.x - 3.0f * ray_dir2.y)
+ SH_ACCUM(9, 0.590043 * ray_dir.y * (3.0f * ray_dir2.x - ray_dir2.y));
+ SH_ACCUM(10, 2.890611 * ray_dir.y * ray_dir.x * ray_dir.z);
+ SH_ACCUM(11, 0.646360 * ray_dir.y * (-1.0f + 5.0f * ray_dir2.z));
+ SH_ACCUM(12, 0.373176 * (5.0f * ray_dir2.z * ray_dir.z - 3.0f * ray_dir.z));
+ SH_ACCUM(13, 0.457045 * ray_dir.x * (-1.0f + 5.0f * ray_dir2.z));
+ SH_ACCUM(14, 1.445305 * (ray_dir2.x - ray_dir2.y) * ray_dir.z);
+ SH_ACCUM(15, 0.590043 * ray_dir.x * (ray_dir2.x - 3.0f * ray_dir2.y));
#endif
- );
-
- for (uint j = 0; j < SH_SIZE; j++) {
- probe_sh_accum[j] += light * c[j];
- }
}
for (uint i = 0; i < SH_SIZE; i++) {
@@ -312,7 +316,7 @@ void main() {
ivec3 prev_pos = ivec3(pos.x, pos.y * SH_SIZE + i, int(params.history_index));
ivec2 average_pos = prev_pos.xy;
- vec4 value = probe_sh_accum[i] * 4.0 / float(params.ray_count);
+ vec4 value = vec4(sh_accum[probe_index].c[i * 3 + 0], sh_accum[probe_index].c[i * 3 + 1], sh_accum[probe_index].c[i * 3 + 2], 1.0) * 4.0 / float(params.ray_count);
ivec4 ivalue = clamp(ivec4(value * float(1 << HISTORY_BITS)), -32768, 32767); //clamp to 16 bits, so higher values don't break average
@@ -344,37 +348,11 @@ void main() {
ivec2 oct_pos = (pos / OCT_SIZE) * (OCT_SIZE + 2) + ivec2(1);
ivec2 local_pos = pos % OCT_SIZE;
- //fill the spherical harmonic
- vec4 sh[SH_SIZE];
-
- for (uint i = 0; i < SH_SIZE; i++) {
- // store in history texture
- ivec2 average_pos = sh_pos + ivec2(0, i);
- ivec4 average = imageLoad(lightprobe_average_texture, average_pos);
-
- sh[i] = (vec4(average) / float(params.history_size)) / float(1 << HISTORY_BITS);
- }
-
//compute the octahedral normal for this texel
vec3 normal = octahedron_encode(vec2(local_pos) / float(OCT_SIZE));
- /*
+
// read the spherical harmonic
- const float c1 = 0.429043;
- const float c2 = 0.511664;
- const float c3 = 0.743125;
- const float c4 = 0.886227;
- const float c5 = 0.247708;
- vec4 light = (c1 * sh[8] * (normal.x * normal.x - normal.y * normal.y) +
- c3 * sh[6] * normal.z * normal.z +
- c4 * sh[0] -
- c5 * sh[6] +
- 2.0 * c1 * sh[4] * normal.x * normal.y +
- 2.0 * c1 * sh[7] * normal.x * normal.z +
- 2.0 * c1 * sh[5] * normal.y * normal.z +
- 2.0 * c2 * sh[3] * normal.x +
- 2.0 * c2 * sh[1] * normal.y +
- 2.0 * c2 * sh[2] * normal.z);
-*/
+
vec3 normal2 = normal * normal;
float c[SH_SIZE] = float[](
@@ -426,7 +404,14 @@ void main() {
vec3 radiance = vec3(0.0);
for (uint i = 0; i < SH_SIZE; i++) {
- vec3 m = sh[i].rgb * c[i] * 4.0;
+ // store in history texture
+ ivec2 average_pos = sh_pos + ivec2(0, i);
+ ivec4 average = imageLoad(lightprobe_average_texture, average_pos);
+
+ vec4 sh = (vec4(average) / float(params.history_size)) / float(1 << HISTORY_BITS);
+
+ vec3 m = sh.rgb * c[i] * 4.0;
+
irradiance += m * l_mult[i];
radiance += m;
}
@@ -515,13 +500,15 @@ void main() {
//can't scroll, must look for position in parent cascade
//to global coords
- float probe_cell_size = float(params.grid_size.x / float(params.probe_axis_size - 1)) / cascades.data[params.cascade].to_cell;
+ float cell_to_probe = float(params.grid_size.x / float(params.probe_axis_size - 1));
+
+ float probe_cell_size = cell_to_probe / cascades.data[params.cascade].to_cell;
vec3 probe_pos = cascades.data[params.cascade].offset + vec3(probe_cell) * probe_cell_size;
//to parent local coords
+ float probe_cell_size_next = cell_to_probe / cascades.data[params.cascade + 1].to_cell;
probe_pos -= cascades.data[params.cascade + 1].offset;
- probe_pos *= cascades.data[params.cascade + 1].to_cell;
- probe_pos = probe_pos * float(params.probe_axis_size - 1) / float(params.grid_size.x);
+ probe_pos /= probe_cell_size_next;
ivec3 probe_posi = ivec3(probe_pos);
//add up all light, no need to use occlusion here, since occlusion will do its work afterwards
@@ -574,20 +561,28 @@ void main() {
}
} else {
- // clear and let it re-raytrace, only for the last cascade, which happens very un-often
- //scroll
+ //scroll at the edge of the highest cascade, just copy what is there,
+ //since its the closest we have anyway
+
for (uint j = 0; j < params.history_size; j++) {
+ ivec2 tex_pos;
+ tex_pos = probe_cell.xy;
+ tex_pos.x += probe_cell.z * int(params.probe_axis_size);
+
for (int i = 0; i < SH_SIZE; i++) {
// copy from history texture
+ ivec3 src_pos = ivec3(tex_pos.x, tex_pos.y * SH_SIZE + i, int(j));
ivec3 dst_pos = ivec3(pos.x, pos.y * SH_SIZE + i, int(j));
- imageStore(lightprobe_history_scroll_texture, dst_pos, ivec4(0));
+ ivec4 value = imageLoad(lightprobe_history_texture, dst_pos);
+ imageStore(lightprobe_history_scroll_texture, dst_pos, value);
}
}
for (int i = 0; i < SH_SIZE; i++) {
// copy from average texture
- ivec2 dst_pos = ivec2(pos.x, pos.y * SH_SIZE + i);
- imageStore(lightprobe_average_scroll_texture, dst_pos, ivec4(0));
+ ivec2 spos = ivec2(pos.x, pos.y * SH_SIZE + i);
+ ivec4 average = imageLoad(lightprobe_average_texture, spos);
+ imageStore(lightprobe_average_scroll_texture, spos, average);
}
}
diff --git a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl
deleted file mode 100644
index 29443ae7db..0000000000
--- a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl
+++ /dev/null
@@ -1,105 +0,0 @@
-#[compute]
-
-#version 450
-
-VERSION_DEFINES
-
-#define BLOCK_SIZE 8
-
-layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
-
-#ifdef MODE_REDUCE
-
-shared float tmp_data[BLOCK_SIZE * BLOCK_SIZE];
-const uint swizzle_table[BLOCK_SIZE] = uint[](0, 4, 2, 6, 1, 5, 3, 7);
-const uint unswizzle_table[BLOCK_SIZE] = uint[](0, 0, 0, 1, 0, 2, 1, 3);
-
-#endif
-
-layout(r32f, set = 0, binding = 0) uniform restrict readonly image2D source_depth;
-layout(r32f, set = 0, binding = 1) uniform restrict writeonly image2D dst_depth;
-
-layout(push_constant, binding = 1, std430) uniform Params {
- ivec2 source_size;
- ivec2 source_offset;
- uint min_size;
- uint gaussian_kernel_version;
- ivec2 filter_dir;
-}
-params;
-
-void main() {
-#ifdef MODE_REDUCE
-
- uvec2 pos = gl_LocalInvocationID.xy;
-
- ivec2 image_offset = params.source_offset;
- ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy);
- uint dst_t = swizzle_table[pos.y] * BLOCK_SIZE + swizzle_table[pos.x];
- tmp_data[dst_t] = imageLoad(source_depth, min(image_pos, params.source_size - ivec2(1))).r;
- ivec2 image_size = params.source_size;
-
- uint t = pos.y * BLOCK_SIZE + pos.x;
-
- //neighbours
- uint size = BLOCK_SIZE;
-
- do {
- groupMemoryBarrier();
- barrier();
-
- size >>= 1;
- image_size >>= 1;
- image_offset >>= 1;
-
- if (all(lessThan(pos, uvec2(size)))) {
- uint nx = t + size;
- uint ny = t + (BLOCK_SIZE * size);
- uint nxy = ny + size;
-
- tmp_data[t] += tmp_data[nx];
- tmp_data[t] += tmp_data[ny];
- tmp_data[t] += tmp_data[nxy];
- tmp_data[t] /= 4.0;
- }
-
- } while (size > params.min_size);
-
- if (all(lessThan(pos, uvec2(size)))) {
- image_pos = ivec2(unswizzle_table[size + pos.x], unswizzle_table[size + pos.y]);
- image_pos += image_offset + ivec2(gl_WorkGroupID.xy) * int(size);
-
- image_size = max(ivec2(1), image_size); //in case image size became 0
-
- if (all(lessThan(image_pos, uvec2(image_size)))) {
- imageStore(dst_depth, image_pos, vec4(tmp_data[t]));
- }
- }
-#endif
-
-#ifdef MODE_FILTER
-
- ivec2 image_pos = params.source_offset + ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(image_pos, params.source_size))) {
- return;
- }
-
- ivec2 clamp_min = ivec2(params.source_offset);
- ivec2 clamp_max = ivec2(params.source_size) - 1;
-
- //gaussian kernel, size 9, sigma 4
- const int kernel_size = 9;
- const float gaussian_kernel[kernel_size * 3] = float[](
- 0.000229, 0.005977, 0.060598, 0.241732, 0.382928, 0.241732, 0.060598, 0.005977, 0.000229,
- 0.028532, 0.067234, 0.124009, 0.179044, 0.20236, 0.179044, 0.124009, 0.067234, 0.028532,
- 0.081812, 0.101701, 0.118804, 0.130417, 0.134535, 0.130417, 0.118804, 0.101701, 0.081812);
- float accum = 0.0;
- for (int i = 0; i < kernel_size; i++) {
- ivec2 ofs = clamp(image_pos + params.filter_dir * (i - kernel_size / 2), clamp_min, clamp_max);
- accum += imageLoad(source_depth, ofs).r * gaussian_kernel[params.gaussian_kernel_version + i];
- }
-
- imageStore(dst_depth, image_pos, vec4(accum));
-
-#endif
-}
diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl
index b19f5a9ad3..680d1045cd 100644
--- a/servers/rendering/renderer_rd/shaders/skeleton.glsl
+++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl
@@ -100,7 +100,7 @@ void main() {
for (uint i = 0; i < params.blend_shape_count; i++) {
float w = blend_shape_weights.data[i];
- if (w > 0.0001) {
+ if (abs(w) > 0.0001) {
uint base_offset = (params.vertex_count * i + index) * params.vertex_stride;
blend_vertex += uintBitsToFloat(uvec3(src_blend_shapes.data[base_offset + 0], src_blend_shapes.data[base_offset + 1], src_blend_shapes.data[base_offset + 2])) * w;
diff --git a/servers/rendering/renderer_rd/shaders/ssao.glsl b/servers/rendering/renderer_rd/shaders/ssao.glsl
index f67965ab49..231f8f91ec 100644
--- a/servers/rendering/renderer_rd/shaders/ssao.glsl
+++ b/servers/rendering/renderer_rd/shaders/ssao.glsl
@@ -88,7 +88,7 @@ counter;
layout(rg8, set = 2, binding = 0) uniform restrict writeonly image2D dest_image;
// This push_constant is full - 128 bytes - if you need to add more data, consider adding to the uniform buffer instead
-layout(push_constant, binding = 1, std430) uniform Params {
+layout(push_constant, binding = 3, std430) uniform Params {
ivec2 screen_size;
int pass;
int quality;
@@ -249,7 +249,6 @@ void SSAOTap(const int p_quality_level, inout float r_obscurance_sum, inout floa
SSAO_tap_inner(p_quality_level, r_obscurance_sum, r_weight_sum, sampling_mirrored_uv, mip_level, p_pix_center_pos, p_pixel_normal, p_fallof_sq, p_weight_mod);
}
-// this function is designed to only work with half/half depth at the moment - there's a couple of hardcoded paths that expect pixel/texel size, so it will not work for full res
void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, out float r_weight, const vec2 p_pos, int p_quality_level, bool p_adaptive_base) {
vec2 pos_rounded = trunc(p_pos);
uvec2 upos = uvec2(pos_rounded);
@@ -257,8 +256,8 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o
const int number_of_taps = (p_adaptive_base) ? (SSAO_ADAPTIVE_TAP_BASE_COUNT) : (num_taps[p_quality_level]);
float pix_z, pix_left_z, pix_top_z, pix_right_z, pix_bottom_z;
- vec4 valuesUL = textureGather(source_depth_mipmaps, vec3(pos_rounded * params.half_screen_pixel_size, params.pass)); // g_ViewspaceDepthSource.GatherRed(g_PointMirrorSampler, pos_rounded * params.half_screen_pixel_size);
- vec4 valuesBR = textureGather(source_depth_mipmaps, vec3((pos_rounded + vec2(1.0)) * params.half_screen_pixel_size, params.pass)); // g_ViewspaceDepthSource.GatherRed(g_PointMirrorSampler, pos_rounded * params.half_screen_pixel_size, ivec2(1, 1));
+ vec4 valuesUL = textureGather(source_depth_mipmaps, vec3(pos_rounded * params.half_screen_pixel_size, params.pass));
+ vec4 valuesBR = textureGather(source_depth_mipmaps, vec3((pos_rounded + vec2(1.0)) * params.half_screen_pixel_size, params.pass));
// get this pixel's viewspace depth
pix_z = valuesUL.y;
@@ -276,8 +275,7 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o
uvec2 full_res_coord = upos * 2 * params.size_multiplier + params.pass_coord_offset.xy;
vec3 pixel_normal = load_normal(ivec2(full_res_coord));
- //const vec2 pixel_size_at_center = pix_center_pos.z * params.NDC_to_view_mul * params.half_screen_pixel_size; // optimized approximation of:
- vec2 pixel_size_at_center = NDC_to_view_space(normalized_screen_pos.xy + params.half_screen_pixel_size * 0.5, pix_center_pos.z).xy - pix_center_pos.xy;
+ const vec2 pixel_size_at_center = NDC_to_view_space(normalized_screen_pos.xy + params.half_screen_pixel_size, pix_center_pos.z).xy - pix_center_pos.xy;
float pixel_lookup_radius;
float fallof_sq;
@@ -440,9 +438,6 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o
fade_out *= clamp(1.0 - edge_fadeout_factor, 0.0, 1.0);
}
- // same as a bove, but a lot more conservative version
- // fade_out *= clamp( dot( edgesLRTB, vec4( 0.9, 0.9, 0.9, 0.9 ) ) - 2.6 , 0.0, 1.0);
-
// strength
obscurance = params.intensity * obscurance;
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
index 13b162f0c9..e7ba8feb80 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
@@ -4,6 +4,15 @@
VERSION_DEFINES
+/* Do not use subgroups here, seems there is not much advantage and causes glitches
+#extension GL_KHR_shader_subgroup_ballot: enable
+#extension GL_KHR_shader_subgroup_arithmetic: enable
+
+#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic)
+#define USE_SUBGROUPS
+#endif
+*/
+
#if defined(MODE_FOG) || defined(MODE_FILTER)
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
@@ -23,22 +32,25 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
layout(set = 0, binding = 1) uniform texture2D shadow_atlas;
layout(set = 0, binding = 2) uniform texture2D directional_shadow_atlas;
-layout(set = 0, binding = 3, std430) restrict readonly buffer Lights {
+layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights {
LightData data[];
}
-lights;
+omni_lights;
-layout(set = 0, binding = 4, std140) uniform DirectionalLights {
+layout(set = 0, binding = 4, std430) restrict readonly buffer SpotLights {
+ LightData data[];
+}
+spot_lights;
+
+layout(set = 0, binding = 5, std140) uniform DirectionalLights {
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
}
directional_lights;
-layout(set = 0, binding = 5) uniform utexture3D cluster_texture;
-
-layout(set = 0, binding = 6, std430) restrict readonly buffer ClusterData {
- uint indices[];
+layout(set = 0, binding = 6, std430) buffer restrict readonly ClusterBuffer {
+ uint data[];
}
-cluster_data;
+cluster_buffer;
layout(set = 0, binding = 7) uniform sampler linear_sampler;
@@ -132,7 +144,7 @@ layout(set = 1, binding = 2) uniform texture3D sdfgi_occlusion_texture;
#endif //SDFGI
-layout(push_constant, binding = 0, std430) uniform Params {
+layout(set = 0, binding = 14, std140) uniform Params {
vec2 fog_frustum_size_begin;
vec2 fog_frustum_size_end;
@@ -150,12 +162,24 @@ layout(push_constant, binding = 0, std430) uniform Params {
float detail_spread;
float gi_inject;
uint max_gi_probes;
- uint pad;
+ uint cluster_type_size;
+
+ vec2 screen_size;
+ uint cluster_shift;
+ uint cluster_width;
+
+ uint max_cluster_element_count_div_32;
+ bool use_temporal_reprojection;
+ uint temporal_frame;
+ float temporal_blend;
mat3x4 cam_rotation;
+ mat4 to_prev_view;
}
params;
+layout(set = 0, binding = 15) uniform texture3D prev_density_texture;
+
float get_depth_at_pos(float cell_depth_size, int z) {
float d = float(z) * cell_depth_size + cell_depth_size * 0.5; //center of voxels
d = pow(d, params.detail_spread);
@@ -169,6 +193,51 @@ vec3 hash3f(uvec3 x) {
return vec3(x & 0xFFFFF) / vec3(float(0xFFFFF));
}
+float get_omni_attenuation(float distance, float inv_range, float decay) {
+ float nd = distance * inv_range;
+ nd *= nd;
+ nd *= nd; // nd^4
+ nd = max(1.0 - nd, 0.0);
+ nd *= nd; // nd^2
+ return nd * pow(max(distance, 0.0001), -decay);
+}
+
+void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) {
+ uint item_min_max = cluster_buffer.data[p_offset];
+ item_min = item_min_max & 0xFFFF;
+ item_max = item_min_max >> 16;
+ ;
+
+ item_from = item_min >> 5;
+ item_to = (item_max == 0) ? 0 : ((item_max - 1) >> 5) + 1; //side effect of how it is stored, as item_max 0 means no elements
+}
+
+uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) {
+ int local_min = clamp(int(z_min) - int(i) * 32, 0, 31);
+ int mask_width = min(int(z_max) - int(z_min), 32 - local_min);
+ return bitfieldInsert(uint(0), uint(0xFFFFFFFF), local_min, mask_width);
+}
+
+#define TEMPORAL_FRAMES 16
+
+const vec3 halton_map[TEMPORAL_FRAMES] = vec3[](
+ vec3(0.5, 0.33333333, 0.2),
+ vec3(0.25, 0.66666667, 0.4),
+ vec3(0.75, 0.11111111, 0.6),
+ vec3(0.125, 0.44444444, 0.8),
+ vec3(0.625, 0.77777778, 0.04),
+ vec3(0.375, 0.22222222, 0.24),
+ vec3(0.875, 0.55555556, 0.44),
+ vec3(0.0625, 0.88888889, 0.64),
+ vec3(0.5625, 0.03703704, 0.84),
+ vec3(0.3125, 0.37037037, 0.08),
+ vec3(0.8125, 0.7037037, 0.28),
+ vec3(0.1875, 0.14814815, 0.48),
+ vec3(0.6875, 0.48148148, 0.68),
+ vec3(0.4375, 0.81481481, 0.88),
+ vec3(0.9375, 0.25925926, 0.12),
+ vec3(0.03125, 0.59259259, 0.32));
+
void main() {
vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size);
@@ -184,6 +253,12 @@ void main() {
//posf += mix(vec3(0.0),vec3(1.0),0.3) * hash3f(uvec3(pos)) * 2.0 - 1.0;
vec3 fog_unit_pos = posf * fog_cell_size + fog_cell_size * 0.5; //center of voxels
+
+ uvec2 screen_pos = uvec2(fog_unit_pos.xy * params.screen_size);
+ uvec2 cluster_pos = screen_pos >> params.cluster_shift;
+ uint cluster_offset = (params.cluster_width * cluster_pos.y + cluster_pos.x) * (params.max_cluster_element_count_div_32 + 32);
+ //positions in screen are too spread apart, no hopes for optimizing with subgroups
+
fog_unit_pos.z = pow(fog_unit_pos.z, params.detail_spread);
vec3 view_pos;
@@ -191,6 +266,47 @@ void main() {
view_pos.z = -params.fog_frustum_end * fog_unit_pos.z;
view_pos.y = -view_pos.y;
+ vec4 reprojected_density = vec4(0.0);
+ float reproject_amount = 0.0;
+
+ if (params.use_temporal_reprojection) {
+ vec3 prev_view = (params.to_prev_view * vec4(view_pos, 1.0)).xyz;
+ //undo transform into prev view
+ prev_view.y = -prev_view.y;
+ //z back to unit size
+ prev_view.z /= -params.fog_frustum_end;
+ //xy back to unit size
+ prev_view.xy /= mix(params.fog_frustum_size_begin, params.fog_frustum_size_end, vec2(prev_view.z));
+ prev_view.xy = prev_view.xy * 0.5 + 0.5;
+ //z back to unspread value
+ prev_view.z = pow(prev_view.z, 1.0 / params.detail_spread);
+
+ if (all(greaterThan(prev_view, vec3(0.0))) && all(lessThan(prev_view, vec3(1.0)))) {
+ //reprojectinon fits
+
+ reprojected_density = textureLod(sampler3D(prev_density_texture, linear_sampler), prev_view, 0.0);
+ reproject_amount = params.temporal_blend;
+
+ // Since we can reproject, now we must jitter the current view pos.
+ // This is done here because cells that can't reproject should not jitter.
+
+ fog_unit_pos = posf * fog_cell_size + fog_cell_size * halton_map[params.temporal_frame]; //center of voxels, offset by halton table
+
+ screen_pos = uvec2(fog_unit_pos.xy * params.screen_size);
+ cluster_pos = screen_pos >> params.cluster_shift;
+ cluster_offset = (params.cluster_width * cluster_pos.y + cluster_pos.x) * (params.max_cluster_element_count_div_32 + 32);
+ //positions in screen are too spread apart, no hopes for optimizing with subgroups
+
+ fog_unit_pos.z = pow(fog_unit_pos.z, params.detail_spread);
+
+ view_pos.xy = (fog_unit_pos.xy * 2.0 - 1.0) * mix(params.fog_frustum_size_begin, params.fog_frustum_size_end, vec2(fog_unit_pos.z));
+ view_pos.z = -params.fog_frustum_end * fog_unit_pos.z;
+ view_pos.y = -view_pos.y;
+ }
+ }
+
+ uint cluster_z = uint(clamp((abs(view_pos.z) / params.z_far) * 32.0, 0.0, 31.0));
+
vec3 total_light = params.light_color;
float total_density = params.base_density;
@@ -257,108 +373,160 @@ void main() {
//compute lights from cluster
- vec3 cluster_pos;
- cluster_pos.xy = fog_unit_pos.xy;
- cluster_pos.z = clamp((abs(view_pos.z) - params.z_near) / (params.z_far - params.z_near), 0.0, 1.0);
+ { //omni lights
- uvec4 cluster_cell = texture(usampler3D(cluster_texture, linear_sampler), cluster_pos);
+ uint cluster_omni_offset = cluster_offset;
- uint omni_light_count = cluster_cell.x >> CLUSTER_COUNTER_SHIFT;
- uint omni_light_pointer = cluster_cell.x & CLUSTER_POINTER_MASK;
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
- for (uint i = 0; i < omni_light_count; i++) {
- uint light_index = cluster_data.indices[omni_light_pointer + i];
+ cluster_get_item_range(cluster_omni_offset + params.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
- vec3 light_pos = lights.data[i].position;
- float d = distance(lights.data[i].position, view_pos) * lights.data[i].inv_radius;
- vec3 shadow_attenuation = vec3(1.0);
+#ifdef USE_SUBGROUPS
+ item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+ item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+#endif
- if (d < 1.0) {
- vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy);
- vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular);
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_omni_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+#ifdef USE_SUBGROUPS
+ uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+#else
+ uint merged_mask = mask;
+#endif
- float attenuation = pow(max(1.0 - d, 0.0), attenuation_energy.x);
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1 << bit);
+#ifdef USE_SUBGROUPS
+ if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ continue;
+ }
+#endif
+ uint light_index = 32 * i + bit;
- vec3 light = attenuation_energy.y * color_specular.rgb / M_PI;
+ //if (!bool(omni_omni_lights.data[light_index].mask & draw_call.layer_mask)) {
+ // continue; //not masked
+ //}
- vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[i].shadow_color_enabled);
+ vec3 light_pos = omni_lights.data[light_index].position;
+ float d = distance(omni_lights.data[light_index].position, view_pos);
+ float shadow_attenuation = 1.0;
- if (shadow_color_enabled.a > 0.5) {
- //has shadow
- vec4 v = vec4(view_pos, 1.0);
+ if (d * omni_lights.data[light_index].inv_radius < 1.0) {
+ float attenuation = get_omni_attenuation(d, omni_lights.data[light_index].inv_radius, omni_lights.data[light_index].attenuation);
- vec4 splane = (lights.data[i].shadow_matrix * v);
- float shadow_len = length(splane.xyz); //need to remember shadow len from here
+ vec3 light = omni_lights.data[light_index].color / M_PI;
- splane.xyz = normalize(splane.xyz);
- vec4 clamp_rect = lights.data[i].atlas_rect;
+ if (omni_lights.data[light_index].shadow_enabled) {
+ //has shadow
+ vec4 v = vec4(view_pos, 1.0);
- if (splane.z >= 0.0) {
- splane.z += 1.0;
+ vec4 splane = (omni_lights.data[light_index].shadow_matrix * v);
+ float shadow_len = length(splane.xyz); //need to remember shadow len from here
- clamp_rect.y += clamp_rect.w;
+ splane.xyz = normalize(splane.xyz);
+ vec4 clamp_rect = omni_lights.data[light_index].atlas_rect;
- } else {
- splane.z = 1.0 - splane.z;
- }
+ if (splane.z >= 0.0) {
+ splane.z += 1.0;
+
+ clamp_rect.y += clamp_rect.w;
- splane.xy /= splane.z;
+ } else {
+ splane.z = 1.0 - splane.z;
+ }
- splane.xy = splane.xy * 0.5 + 0.5;
- splane.z = shadow_len * lights.data[i].inv_radius;
- splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
- splane.w = 1.0; //needed? i think it should be 1 already
+ splane.xy /= splane.z;
- float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r;
- float shadow = exp(min(0.0, (depth - splane.z)) / lights.data[i].inv_radius * lights.data[i].shadow_volumetric_fog_fade);
+ splane.xy = splane.xy * 0.5 + 0.5;
+ splane.z = shadow_len * omni_lights.data[light_index].inv_radius;
+ splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
+ splane.w = 1.0; //needed? i think it should be 1 already
- shadow_attenuation = mix(shadow_color_enabled.rgb, vec3(1.0), shadow);
+ float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r;
+
+ shadow_attenuation = exp(min(0.0, (depth - splane.z)) / omni_lights.data[light_index].inv_radius * omni_lights.data[light_index].shadow_volumetric_fog_fade);
+ }
+ total_light += light * attenuation * shadow_attenuation;
+ }
}
- total_light += light * attenuation * shadow_attenuation;
}
}
- uint spot_light_count = cluster_cell.y >> CLUSTER_COUNTER_SHIFT;
- uint spot_light_pointer = cluster_cell.y & CLUSTER_POINTER_MASK;
+ { //spot lights
- for (uint i = 0; i < spot_light_count; i++) {
- uint light_index = cluster_data.indices[spot_light_pointer + i];
+ uint cluster_spot_offset = cluster_offset + params.cluster_type_size;
- vec3 light_pos = lights.data[i].position;
- vec3 light_rel_vec = lights.data[i].position - view_pos;
- float d = length(light_rel_vec) * lights.data[i].inv_radius;
- vec3 shadow_attenuation = vec3(1.0);
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
- if (d < 1.0) {
- vec2 attenuation_energy = unpackHalf2x16(lights.data[i].attenuation_energy);
- vec4 color_specular = unpackUnorm4x8(lights.data[i].color_specular);
+ cluster_get_item_range(cluster_spot_offset + params.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
- float attenuation = pow(max(1.0 - d, 0.0), attenuation_energy.x);
+#ifdef USE_SUBGROUPS
+ item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+ item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+#endif
- vec3 spot_dir = lights.data[i].direction;
- vec2 spot_att_angle = unpackHalf2x16(lights.data[i].cone_attenuation_angle);
- float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y);
- float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_att_angle.y));
- attenuation *= 1.0 - pow(spot_rim, spot_att_angle.x);
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_spot_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+#ifdef USE_SUBGROUPS
+ uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+#else
+ uint merged_mask = mask;
+#endif
- vec3 light = attenuation_energy.y * color_specular.rgb / M_PI;
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1 << bit);
+#ifdef USE_SUBGROUPS
+ if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ continue;
+ }
+#endif
- vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[i].shadow_color_enabled);
+ //if (!bool(omni_lights.data[light_index].mask & draw_call.layer_mask)) {
+ // continue; //not masked
+ //}
- if (shadow_color_enabled.a > 0.5) {
- //has shadow
- vec4 v = vec4(view_pos, 1.0);
+ uint light_index = 32 * i + bit;
- vec4 splane = (lights.data[i].shadow_matrix * v);
- splane /= splane.w;
+ vec3 light_pos = spot_lights.data[light_index].position;
+ vec3 light_rel_vec = spot_lights.data[light_index].position - view_pos;
+ float d = length(light_rel_vec);
+ float shadow_attenuation = 1.0;
- float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r;
- float shadow = exp(min(0.0, (depth - splane.z)) / lights.data[i].inv_radius * lights.data[i].shadow_volumetric_fog_fade);
+ if (d * spot_lights.data[light_index].inv_radius < 1.0) {
+ float attenuation = get_omni_attenuation(d, spot_lights.data[light_index].inv_radius, spot_lights.data[light_index].attenuation);
- shadow_attenuation = mix(shadow_color_enabled.rgb, vec3(1.0), shadow);
- }
+ vec3 spot_dir = spot_lights.data[light_index].direction;
+ float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights.data[light_index].cone_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights.data[light_index].cone_angle));
+ attenuation *= 1.0 - pow(spot_rim, spot_lights.data[light_index].cone_attenuation);
+
+ vec3 light = spot_lights.data[light_index].color / M_PI;
+
+ if (spot_lights.data[light_index].shadow_enabled) {
+ //has shadow
+ vec4 v = vec4(view_pos, 1.0);
+
+ vec4 splane = (spot_lights.data[light_index].shadow_matrix * v);
+ splane /= splane.w;
- total_light += light * attenuation * shadow_attenuation;
+ float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r;
+
+ shadow_attenuation = exp(min(0.0, (depth - splane.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade);
+ }
+
+ total_light += light * attenuation * shadow_attenuation;
+ }
+ }
}
}
@@ -461,7 +629,11 @@ void main() {
#endif
- imageStore(density_map, pos, vec4(total_light, total_density));
+ vec4 final_density = vec4(total_light, total_density);
+
+ final_density = mix(final_density, reprojected_density, reproject_amount);
+
+ imageStore(density_map, pos, final_density);
#endif
#ifdef MODE_FOG
diff --git a/servers/rendering/renderer_scene.cpp b/servers/rendering/renderer_scene.cpp
index 1da8fc59de..dd544d4f3f 100644
--- a/servers/rendering/renderer_scene.cpp
+++ b/servers/rendering/renderer_scene.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h
index 22af720ae7..b546001843 100644
--- a/servers/rendering/renderer_scene.h
+++ b/servers/rendering/renderer_scene.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,8 @@
class RendererScene {
public:
- virtual RID camera_create() = 0;
+ virtual RID camera_allocate() = 0;
+ virtual void camera_initialize(RID p_rid) = 0;
virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0;
virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0;
@@ -48,7 +49,8 @@ public:
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0;
virtual bool is_camera(RID p_camera) const = 0;
- virtual RID scenario_create() = 0;
+ virtual RID scenario_allocate() = 0;
+ virtual void scenario_initialize(RID p_rid) = 0;
virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) = 0;
virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0;
@@ -58,7 +60,8 @@ public:
virtual bool is_scenario(RID p_scenario) const = 0;
virtual RID scenario_get_environment(RID p_scenario) = 0;
- virtual RID instance_create() = 0;
+ virtual RID instance_allocate() = 0;
+ virtual void instance_initialize(RID p_rid) = 0;
virtual void instance_set_base(RID p_instance, RID p_base) = 0;
virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0;
@@ -95,11 +98,13 @@ public:
virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0;
virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0;
- virtual void directional_shadow_atlas_set_size(int p_size) = 0;
+ virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
/* SKY API */
- virtual RID sky_create() = 0;
+ virtual RID sky_allocate() = 0;
+ virtual void sky_initialize(RID p_rid) = 0;
+
virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0;
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
@@ -107,7 +112,8 @@ public:
/* ENVIRONMENT API */
- virtual RID environment_create() = 0;
+ virtual RID environment_allocate() = 0;
+ virtual void environment_initialize(RID p_rid) = 0;
virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0;
virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
@@ -122,12 +128,10 @@ public:
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
- virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+ virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
- virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
- virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0;
virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
@@ -136,10 +140,11 @@ public:
virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0;
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
+ virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0;
virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
@@ -160,7 +165,8 @@ public:
/* Camera Effects */
- virtual RID camera_effects_create() = 0;
+ virtual RID camera_effects_allocate() = 0;
+ virtual void camera_effects_initialize(RID p_rid) = 0;
virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0;
virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0;
@@ -172,14 +178,17 @@ public:
virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
virtual RID shadow_atlas_create() = 0;
- virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
+ virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = false) = 0;
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
/* Render Buffers */
virtual RID render_buffers_create() = 0;
+
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0;
+ virtual void gi_set_use_half_resolution(bool p_enable) = 0;
+
virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;
virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0;
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index be2eb71581..e8155e4025 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,9 +39,11 @@
/* CAMERA API */
-RID RendererSceneCull::camera_create() {
- Camera *camera = memnew(Camera);
- return camera_owner.make_rid(camera);
+RID RendererSceneCull::camera_allocate() {
+ return camera_owner.allocate_rid();
+}
+void RendererSceneCull::camera_initialize(RID p_rid) {
+ camera_owner.initialize_rid(p_rid, memnew(Camera));
}
void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) {
@@ -129,25 +131,35 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
if (geom->can_cast_shadows) {
light->shadow_dirty = true;
}
- geom->lighting_dirty = true;
- } else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY;
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
geom->reflection_probes.insert(B);
reflection_probe->geometries.insert(A);
- geom->reflection_dirty = true;
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY;
+ }
- } else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
geom->decals.insert(B);
decal->geometries.insert(A);
- geom->decal_dirty = true;
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_DECAL_DIRTY;
+ }
} else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
@@ -156,10 +168,15 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
if (A->dynamic_gi) {
geom->lightmap_captures.insert(A);
lightmap_data->geometries.insert(B);
+
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_LIGHTMAP_CAPTURE;
+ }
((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture
}
- } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -171,13 +188,17 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
gi_probe->geometries.insert(A);
}
- geom->gi_probes_dirty = true;
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_GI_PROBE_DIRTY;
+ }
} else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
gi_probe->lights.insert(A);
} else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
- RSG::storage->particles_add_collision(A->base, B);
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
+ RSG::storage->particles_add_collision(A->base, collision->instance);
}
}
@@ -201,34 +222,52 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
if (geom->can_cast_shadows) {
light->shadow_dirty = true;
}
- geom->lighting_dirty = true;
- } else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY;
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
geom->reflection_probes.erase(B);
reflection_probe->geometries.erase(A);
- geom->reflection_dirty = true;
- } else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY;
+ }
+
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
geom->decals.erase(B);
decal->geometries.erase(A);
- geom->decal_dirty = true;
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_DECAL_DIRTY;
+ }
+
} else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
if (A->dynamic_gi) {
geom->lightmap_captures.erase(B);
+
+ if (geom->lightmap_captures.is_empty() && A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags &= ~uint32_t(InstanceData::FLAG_LIGHTMAP_CAPTURE);
+ }
+
lightmap_data->geometries.erase(A);
((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture
}
- } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ } else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -239,21 +278,26 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
gi_probe->geometries.erase(A);
}
- geom->gi_probes_dirty = true;
+ if (A->scenario && A->array_index >= 0) {
+ InstanceData &idata = A->scenario->instance_data[A->array_index];
+ idata.flags |= InstanceData::FLAG_GEOM_GI_PROBE_DIRTY;
+ }
} else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
gi_probe->lights.erase(A);
} else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
- RSG::storage->particles_remove_collision(A->base, B);
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
+ RSG::storage->particles_remove_collision(A->base, collision->instance);
}
}
-RID RendererSceneCull::scenario_create() {
+RID RendererSceneCull::scenario_allocate() {
+ return scenario_owner.allocate_rid();
+}
+void RendererSceneCull::scenario_initialize(RID p_rid) {
Scenario *scenario = memnew(Scenario);
- ERR_FAIL_COND_V(!scenario, RID());
- RID scenario_rid = scenario_owner.make_rid(scenario);
- scenario->self = scenario_rid;
+ scenario->self = p_rid;
scenario->reflection_probe_shadow_atlas = scene_render->shadow_atlas_create();
scene_render->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest
@@ -262,7 +306,11 @@ RID RendererSceneCull::scenario_create() {
scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4);
scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8);
scenario->reflection_atlas = scene_render->reflection_atlas_create();
- return scenario_rid;
+
+ scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool);
+ scenario->instance_data.set_page_pool(&instance_data_page_pool);
+
+ scenario_owner.initialize_rid(p_rid, scenario);
}
void RendererSceneCull::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) {
@@ -322,14 +370,14 @@ void RendererSceneCull::_instance_queue_update(Instance *p_instance, bool p_upda
_instance_update_list.add(&p_instance->update_item);
}
-RID RendererSceneCull::instance_create() {
+RID RendererSceneCull::instance_allocate() {
+ return instance_owner.allocate_rid();
+}
+void RendererSceneCull::instance_initialize(RID p_rid) {
Instance *instance = memnew(Instance);
- ERR_FAIL_COND_V(!instance, RID());
+ instance->self = p_rid;
- RID instance_rid = instance_owner.make_rid(instance);
- instance->self = instance_rid;
-
- return instance_rid;
+ instance_owner.initialize_rid(p_rid, instance);
}
void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
@@ -337,10 +385,23 @@ void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
if (needs_instance != p_instance->mesh_instance.is_valid()) {
if (needs_instance) {
p_instance->mesh_instance = RSG::storage->mesh_instance_create(p_instance->base);
+
} else {
RSG::storage->free(p_instance->mesh_instance);
p_instance->mesh_instance = RID();
}
+
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+ scene_render->geometry_instance_set_mesh_instance(geom->geometry_instance, p_instance->mesh_instance);
+
+ if (p_instance->scenario && p_instance->array_index >= 0) {
+ InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
+ if (p_instance->mesh_instance.is_valid()) {
+ idata.flags |= InstanceData::FLAG_USES_MESH_INSTANCE;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_USES_MESH_INSTANCE);
+ }
+ }
}
if (p_instance->mesh_instance.is_valid()) {
@@ -364,13 +425,21 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
if (instance->mesh_instance.is_valid()) {
RSG::storage->free(instance->mesh_instance);
instance->mesh_instance = RID();
+ // no need to set instance data flag here, as it was freed above
}
switch (instance->base_type) {
+ case RS::INSTANCE_MESH:
+ case RS::INSTANCE_MULTIMESH:
+ case RS::INSTANCE_IMMEDIATE:
+ case RS::INSTANCE_PARTICLES: {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_free(geom->geometry_instance);
+ } break;
case RS::INSTANCE_LIGHT: {
InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
- if (scenario && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+ if (scenario && instance->visible && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
scenario->dynamic_lights.erase(light->instance);
}
@@ -385,6 +454,10 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
}
scene_render->free(light->instance);
} break;
+ case RS::INSTANCE_PARTICLES_COLLISION: {
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
+ RSG::storage->free(collision->instance);
+ } break;
case RS::INSTANCE_REFLECTION_PROBE: {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
scene_render->free(reflection_probe->instance);
@@ -403,6 +476,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
while (lightmap_data->users.front()) {
instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0);
}
+ scene_render->free(lightmap_data->instance);
} break;
case RS::INSTANCE_GI_PROBE: {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
@@ -460,8 +534,29 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
case RS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = memnew(InstanceGeometryData);
instance->base_data = geom;
+ geom->geometry_instance = scene_render->geometry_instance_create(p_base);
+
+ scene_render->geometry_instance_set_skeleton(geom->geometry_instance, instance->skeleton);
+ scene_render->geometry_instance_set_material_override(geom->geometry_instance, instance->material_override);
+ scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, instance->materials);
+ scene_render->geometry_instance_set_transform(geom->geometry_instance, instance->transform, instance->aabb, instance->transformed_aabb);
+ scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, instance->layer_mask);
+ scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, instance->lod_bias);
+ scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, instance->baked_light);
+ scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, instance->dynamic_gi);
+ scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
+ scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index);
+ if (instance->lightmap_sh.size() == 9) {
+ scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, instance->lightmap_sh.ptr());
+ }
} break;
+ case RS::INSTANCE_PARTICLES_COLLISION: {
+ InstanceParticlesCollisionData *collision = memnew(InstanceParticlesCollisionData);
+ collision->instance = RSG::storage->particles_collision_instance_create(p_base);
+ RSG::storage->particles_collision_instance_set_active(collision->instance, instance->visible);
+ instance->base_data = collision;
+ } break;
case RS::INSTANCE_REFLECTION_PROBE: {
InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData);
reflection_probe->owner = instance;
@@ -479,7 +574,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
case RS::INSTANCE_LIGHTMAP: {
InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData);
instance->base_data = lightmap_data;
- //lightmap_data->instance = scene_render->lightmap_data_instance_create(p_base);
+ lightmap_data->instance = scene_render->lightmap_instance_create(p_base);
} break;
case RS::INSTANCE_GI_PROBE: {
InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData);
@@ -504,7 +599,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
}
//forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
- RSG::storage->base_update_dependency(p_base, instance);
+ RSG::storage->base_update_dependency(p_base, &instance->dependency_tracker);
}
_instance_queue_update(instance, true, true);
@@ -602,6 +697,14 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
ERR_FAIL_COND(!instance);
instance->layer_mask = p_mask;
+ if (instance->scenario && instance->array_index >= 0) {
+ instance->scenario->instance_data[instance->array_index].layer_mask = p_mask;
+ }
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, p_mask);
+ }
}
void RendererSceneCull::instance_set_transform(RID p_instance, const Transform &p_transform) {
@@ -682,6 +785,22 @@ void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) {
} else if (instance->indexer_id.is_valid()) {
_unpair_instance(instance);
}
+
+ if (instance->base_type == RS::INSTANCE_LIGHT) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
+ if (instance->scenario && RSG::storage->light_get_type(instance->base) != RS::LIGHT_DIRECTIONAL && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+ if (p_visible) {
+ instance->scenario->dynamic_lights.push_back(light->instance);
+ } else {
+ instance->scenario->dynamic_lights.erase(light->instance);
+ }
+ }
+ }
+
+ if (instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
+ RSG::storage->particles_collision_instance_set_active(collision->instance, p_visible);
+ }
}
inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
@@ -725,12 +844,17 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton)
if (p_skeleton.is_valid()) {
//update the dependency now, so if cleared, we remove it
- RSG::storage->skeleton_update_dependency(p_skeleton, instance);
+ RSG::storage->skeleton_update_dependency(p_skeleton, &instance->dependency_tracker);
}
- _instance_update_mesh_instance(instance);
-
_instance_queue_update(instance, true, true);
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ _instance_update_mesh_instance(instance);
+
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_skeleton(geom->geometry_instance, p_skeleton);
+ }
}
void RendererSceneCull::instance_set_exterior(RID p_instance, bool p_enabled) {
@@ -826,6 +950,20 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF
case RS::INSTANCE_FLAG_USE_BAKED_LIGHT: {
instance->baked_light = p_enabled;
+ if (instance->scenario && instance->array_index >= 0) {
+ InstanceData &idata = instance->scenario->instance_data[instance->array_index];
+ if (instance->baked_light) {
+ idata.flags |= InstanceData::FLAG_USES_BAKED_LIGHT;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_USES_BAKED_LIGHT);
+ }
+ }
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, p_enabled);
+ }
+
} break;
case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: {
if (p_enabled == instance->dynamic_gi) {
@@ -841,10 +979,24 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF
//once out of octree, can be changed
instance->dynamic_gi = p_enabled;
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, p_enabled);
+ }
+
} break;
case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: {
instance->redraw_if_visible = p_enabled;
+ if (instance->scenario && instance->array_index >= 0) {
+ InstanceData &idata = instance->scenario->instance_data[instance->array_index];
+ if (instance->redraw_if_visible) {
+ idata.flags |= InstanceData::FLAG_REDRAW_IF_VISIBLE;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_REDRAW_IF_VISIBLE);
+ }
+ }
+
} break;
default: {
}
@@ -856,6 +1008,28 @@ void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instanc
ERR_FAIL_COND(!instance);
instance->cast_shadows = p_shadow_casting_setting;
+
+ if (instance->scenario && instance->array_index >= 0) {
+ InstanceData &idata = instance->scenario->instance_data[instance->array_index];
+
+ if (instance->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
+ idata.flags |= InstanceData::FLAG_CAST_SHADOWS;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_CAST_SHADOWS);
+ }
+
+ if (instance->cast_shadows == RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
+ idata.flags |= InstanceData::FLAG_CAST_SHADOWS_ONLY;
+ } else {
+ idata.flags &= ~uint32_t(InstanceData::FLAG_CAST_SHADOWS_ONLY);
+ }
+ }
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
+ }
+
_instance_queue_update(instance, false, true);
}
@@ -865,6 +1039,11 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance,
instance->material_override = p_material;
_instance_queue_update(instance, false, true);
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_material_override(geom->geometry_instance, p_material);
+ }
}
void RendererSceneCull::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) {
@@ -889,9 +1068,17 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig
instance->lightmap_uv_scale = p_lightmap_uv_scale;
instance->lightmap_slice_index = p_slice_index;
+ RID lightmap_instance_rid;
+
if (lightmap_instance) {
InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data);
lightmap_data->users.insert(instance);
+ lightmap_instance_rid = lightmap_data->instance;
+ }
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index);
}
}
@@ -900,16 +1087,21 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l
ERR_FAIL_COND(!instance);
instance->lod_bias = p_lod_bias;
+
+ if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, p_lod_bias);
+ }
}
void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
- Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter);
+ Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter);
if (!E) {
- RendererSceneRender::InstanceBase::InstanceShaderParameter isp;
+ Instance::InstanceShaderParameter isp;
isp.index = -1;
isp.info = PropertyInfo();
isp.value = p_value;
@@ -950,7 +1142,7 @@ void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instan
const_cast<RendererSceneCull *>(this)->update_dirty_instances();
Vector<StringName> names;
- for (Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) {
+ for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) {
names.push_back(E->key());
}
names.sort_custom<StringName::AlphCompare>();
@@ -972,13 +1164,13 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
RS::LightBakeMode bake_mode = RSG::storage->light_get_bake_mode(p_instance->base);
if (RSG::storage->light_get_type(p_instance->base) != RS::LIGHT_DIRECTIONAL && bake_mode != light->bake_mode) {
- if (p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+ if (p_instance->visible && p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
p_instance->scenario->dynamic_lights.erase(light->instance);
}
light->bake_mode = bake_mode;
- if (p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
+ if (p_instance->visible && p_instance->scenario && light->bake_mode == RS::LIGHT_BAKE_DYNAMIC) {
p_instance->scenario->dynamic_lights.push_back(light->instance);
}
}
@@ -987,42 +1179,58 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
if (light->max_sdfgi_cascade != max_sdfgi_cascade) {
light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario
}
- }
-
- if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
+ } else if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform);
- reflection_probe->reflection_dirty = true;
- }
- if (p_instance->base_type == RS::INSTANCE_DECAL) {
+ if (p_instance->scenario && p_instance->array_index >= 0) {
+ InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
+ idata.flags |= InstanceData::FLAG_REFLECTION_PROBE_DIRTY;
+ }
+ } else if (p_instance->base_type == RS::INSTANCE_DECAL) {
InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
scene_render->decal_instance_set_transform(decal->instance, p_instance->transform);
- }
+ } else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
+ InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data);
- if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
+ scene_render->lightmap_instance_set_transform(lightmap->instance, p_instance->transform);
+ } else if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data);
scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform);
- }
-
- if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
+ } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform);
- }
+ } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
+ InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(p_instance->base_data);
- if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
//remove materials no longer used and un-own them
if (RSG::storage->particles_collision_is_heightfield(p_instance->base)) {
heightfield_particle_colliders_update_list.insert(p_instance);
}
+ RSG::storage->particles_collision_instance_set_transform(collision->instance, p_instance->transform);
}
if (p_instance->aabb.has_no_surface()) {
return;
}
+ if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
+ //if this moved, update the captured objects
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
+ //erase dependencies, since no longer a lightmap
+
+ for (Set<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) {
+ Instance *geom = E->get();
+ _instance_queue_update(geom, true, false);
+ }
+ }
+
+ AABB new_aabb;
+ new_aabb = p_instance->transform.xform(p_instance->aabb);
+ p_instance->transformed_aabb = new_aabb;
+
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
//make sure lights are updated if it casts shadow
@@ -1038,33 +1246,18 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
//affected by lightmap captures, must update capture info!
_update_instance_lightmap_captures(p_instance);
} else {
- if (!p_instance->lightmap_sh.empty()) {
+ if (!p_instance->lightmap_sh.is_empty()) {
p_instance->lightmap_sh.clear(); //don't need SH
p_instance->lightmap_target_sh.clear(); //don't need SH
+ scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, nullptr);
}
}
- }
-
- if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
- //if this moved, update the captured objects
- InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
- //erase dependencies, since no longer a lightmap
- for (Set<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) {
- Instance *geom = E->get();
- _instance_queue_update(geom, true, false);
- }
+ scene_render->geometry_instance_set_transform(geom->geometry_instance, p_instance->transform, p_instance->aabb, p_instance->transformed_aabb);
}
- p_instance->mirror = p_instance->transform.basis.determinant() < 0.0;
-
- AABB new_aabb;
-
- new_aabb = p_instance->transform.xform(p_instance->aabb);
-
- p_instance->transformed_aabb = new_aabb;
-
- if (p_instance->scenario == nullptr || !p_instance->visible || Math::is_zero_approx(p_instance->transform.basis.determinant())) {
+ // note: we had to remove is equal approx check here, it meant that det == 0.000004 won't work, which is the case for some of our scenes.
+ if (p_instance->scenario == nullptr || !p_instance->visible || p_instance->transform.basis.determinant() == 0) {
p_instance->prev_transformed_aabb = p_instance->transformed_aabb;
return;
}
@@ -1091,12 +1284,69 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
} else {
p_instance->indexer_id = p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].insert(bvh_aabb, p_instance);
}
+
+ p_instance->array_index = p_instance->scenario->instance_data.size();
+ InstanceData idata;
+ idata.instance = p_instance;
+ idata.layer_mask = p_instance->layer_mask;
+ idata.flags = p_instance->base_type; //changing it means de-indexing, so this never needs to be changed later
+ idata.base_rid = p_instance->base;
+ switch (p_instance->base_type) {
+ case RS::INSTANCE_MESH:
+ case RS::INSTANCE_MULTIMESH:
+ case RS::INSTANCE_IMMEDIATE:
+ case RS::INSTANCE_PARTICLES: {
+ idata.instance_geometry = static_cast<InstanceGeometryData *>(p_instance->base_data)->geometry_instance;
+ } break;
+ case RS::INSTANCE_LIGHT: {
+ idata.instance_data_rid = static_cast<InstanceLightData *>(p_instance->base_data)->instance.get_id();
+ } break;
+ case RS::INSTANCE_REFLECTION_PROBE: {
+ idata.instance_data_rid = static_cast<InstanceReflectionProbeData *>(p_instance->base_data)->instance.get_id();
+ } break;
+ case RS::INSTANCE_DECAL: {
+ idata.instance_data_rid = static_cast<InstanceDecalData *>(p_instance->base_data)->instance.get_id();
+ } break;
+ case RS::INSTANCE_LIGHTMAP: {
+ idata.instance_data_rid = static_cast<InstanceLightmapData *>(p_instance->base_data)->instance.get_id();
+ } break;
+ case RS::INSTANCE_GI_PROBE: {
+ idata.instance_data_rid = static_cast<InstanceGIProbeData *>(p_instance->base_data)->probe_instance.get_id();
+ } break;
+ default: {
+ }
+ }
+
+ if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
+ //always dirty when added
+ idata.flags |= InstanceData::FLAG_REFLECTION_PROBE_DIRTY;
+ }
+ if (p_instance->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
+ idata.flags |= InstanceData::FLAG_CAST_SHADOWS;
+ }
+ if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
+ idata.flags |= InstanceData::FLAG_CAST_SHADOWS_ONLY;
+ }
+ if (p_instance->redraw_if_visible) {
+ idata.flags |= InstanceData::FLAG_REDRAW_IF_VISIBLE;
+ }
+ // dirty flags should not be set here, since no pairing has happened
+ if (p_instance->baked_light) {
+ idata.flags |= InstanceData::FLAG_USES_BAKED_LIGHT;
+ }
+ if (p_instance->mesh_instance.is_valid()) {
+ idata.flags |= InstanceData::FLAG_USES_MESH_INSTANCE;
+ }
+
+ p_instance->scenario->instance_data.push_back(idata);
+ p_instance->scenario->instance_aabbs.push_back(InstanceBounds(p_instance->transformed_aabb));
} else {
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].update(p_instance->indexer_id, bvh_aabb);
} else {
p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES].update(p_instance->indexer_id, bvh_aabb);
}
+ p_instance->scenario->instance_aabbs[p_instance->array_index] = InstanceBounds(p_instance->transformed_aabb);
}
//move instance and repair
@@ -1114,10 +1364,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
pair.pair_mask |= 1 << RS::INSTANCE_GI_PROBE;
pair.pair_mask |= 1 << RS::INSTANCE_LIGHTMAP;
- if (pair_volumes_to_mesh) {
- pair.pair_mask |= 1 << RS::INSTANCE_DECAL;
- pair.pair_mask |= 1 << RS::INSTANCE_REFLECTION_PROBE;
- }
+ pair.pair_mask |= geometry_instance_pair_mask;
+
pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
} else if (p_instance->base_type == RS::INSTANCE_LIGHT) {
pair.pair_mask |= RS::INSTANCE_GEOMETRY_MASK;
@@ -1127,7 +1375,10 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
pair.pair_mask |= (1 << RS::INSTANCE_GI_PROBE);
pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
}
- } else if (pair_volumes_to_mesh && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL)) {
+ } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE)) {
+ pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
+ pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
+ } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) {
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
@@ -1164,6 +1415,30 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) {
}
p_instance->indexer_id = DynamicBVH::ID();
+
+ //replace this by last
+ int32_t swap_with_index = p_instance->scenario->instance_data.size() - 1;
+ if (swap_with_index != p_instance->array_index) {
+ p_instance->scenario->instance_data[swap_with_index].instance->array_index = p_instance->array_index; //swap
+ p_instance->scenario->instance_data[p_instance->array_index] = p_instance->scenario->instance_data[swap_with_index];
+ p_instance->scenario->instance_aabbs[p_instance->array_index] = p_instance->scenario->instance_aabbs[swap_with_index];
+ }
+
+ // pop last
+ p_instance->scenario->instance_data.pop_back();
+ p_instance->scenario->instance_aabbs.pop_back();
+
+ //uninitialize
+ p_instance->array_index = -1;
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ // Clear these now because the InstanceData containing the dirty flags is gone
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+
+ scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, nullptr, 0);
+ scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, nullptr, 0);
+ scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, nullptr, 0);
+ scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, nullptr, 0);
+ }
}
void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
@@ -1320,430 +1595,323 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance)
}
}
}
+
+ scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, p_instance->lightmap_sh.ptr());
}
-bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_lod_threshold) {
+void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) {
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
Transform light_transform = p_instance->transform;
light_transform.orthonormalize(); //scale does not count on lights
- bool animated_material_found = false;
-
- switch (RSG::storage->light_get_type(p_instance->base)) {
- case RS::LIGHT_DIRECTIONAL: {
- Plane camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
-
- real_t max_distance = p_cam_projection.get_z_far();
- real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
- if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
- max_distance = MIN(shadow_max, max_distance);
- }
- max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001);
- real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance);
-
- RS::LightDirectionalShadowDepthRangeMode depth_range_mode = RSG::storage->light_directional_get_shadow_depth_range_mode(p_instance->base);
-
- real_t pancake_size = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
-
- if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED) {
- //optimize min/max
-
- Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
- Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
-
- geometry_instances_to_shadow_render.clear();
-
- struct CullConvex {
- PagedArray<RendererSceneRender::InstanceBase *> *result;
- _FORCE_INLINE_ bool operator()(void *p_data) {
- Instance *p_instance = (Instance *)p_data;
- result->push_back(p_instance);
- return false;
- }
- };
-
- CullConvex cull_convex;
- cull_convex.result = &geometry_instances_to_shadow_render;
-
- p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
-
- Plane base(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2));
- //check distance max and min
+ real_t max_distance = p_cam_projection.get_z_far();
+ real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
+ if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
+ max_distance = MIN(shadow_max, max_distance);
+ }
+ max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001);
+ real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance);
- bool found_items = false;
- real_t z_max = -1e20;
- real_t z_min = 1e20;
+ RS::LightDirectionalShadowDepthRangeMode depth_range_mode = RSG::storage->light_directional_get_shadow_depth_range_mode(p_instance->base);
- for (int i = 0; i < (int)instance_shadow_cull_result.size(); i++) {
- Instance *instance = instance_shadow_cull_result[i];
- if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
- continue;
- }
+ real_t pancake_size = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
+ real_t range = max_distance - min_distance;
- real_t max, min;
- instance->transformed_aabb.project_range_in_plane(base, min, max);
+ int splits = 0;
+ switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) {
+ case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
+ splits = 1;
+ break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
+ splits = 2;
+ break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
+ splits = 4;
+ break;
+ }
- if (max > z_max) {
- z_max = max;
- }
+ real_t distances[5];
- if (min < z_min) {
- z_min = min;
- }
+ distances[0] = min_distance;
+ for (int i = 0; i < splits; i++) {
+ distances[i + 1] = min_distance + RSG::storage->light_get_param(p_instance->base, RS::LightParam(RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range;
+ };
- found_items = true;
- }
+ distances[splits] = max_distance;
- if (found_items) {
- min_distance = MAX(min_distance, z_min);
- max_distance = MIN(max_distance, z_max);
- }
- }
+ real_t texture_size = scene_render->get_directional_light_shadow_size(light->instance);
- real_t range = max_distance - min_distance;
+ bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base);
- int splits = 0;
- switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) {
- case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
- splits = 1;
- break;
- case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
- splits = 2;
- break;
- case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
- splits = 4;
- break;
- }
+ real_t first_radius = 0.0;
- real_t distances[5];
+ real_t min_distance_bias_scale = distances[1];
- distances[0] = min_distance;
- for (int i = 0; i < splits; i++) {
- distances[i + 1] = min_distance + RSG::storage->light_get_param(p_instance->base, RS::LightParam(RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range;
- };
+ cull.shadow_count = p_shadow_index + 1;
+ cull.shadows[p_shadow_index].cascade_count = splits;
+ cull.shadows[p_shadow_index].light_instance = light->instance;
- distances[splits] = max_distance;
+ for (int i = 0; i < splits; i++) {
+ RENDER_TIMESTAMP("Culling Directional Light split" + itos(i));
- real_t texture_size = scene_render->get_directional_light_shadow_size(light->instance);
+ // setup a camera matrix for that range!
+ CameraMatrix camera_matrix;
- bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base);
+ real_t aspect = p_cam_projection.get_aspect();
- real_t first_radius = 0.0;
+ if (p_cam_orthogonal) {
+ Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
- real_t min_distance_bias_scale = pancake_size > 0 ? distances[1] / 10.0 : 0;
+ camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
+ } else {
+ real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it
+ camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
+ }
- for (int i = 0; i < splits; i++) {
- RENDER_TIMESTAMP("Culling Directional Light split" + itos(i));
+ //obtain the frustum endpoints
- // setup a camera matrix for that range!
- CameraMatrix camera_matrix;
+ Vector3 endpoints[8]; // frustum plane endpoints
+ bool res = camera_matrix.get_endpoints(p_cam_transform, endpoints);
+ ERR_CONTINUE(!res);
- real_t aspect = p_cam_projection.get_aspect();
+ // obtain the light frustum ranges (given endpoints)
- if (p_cam_orthogonal) {
- Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
+ Transform transform = light_transform; //discard scale and stabilize light
- camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
- } else {
- real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it
- camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
- }
+ Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized();
+ Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized();
+ Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized();
+ //z_vec points against the camera, like in default opengl
- //obtain the frustum endpoints
+ real_t x_min = 0.f, x_max = 0.f;
+ real_t y_min = 0.f, y_max = 0.f;
+ real_t z_min = 0.f, z_max = 0.f;
- Vector3 endpoints[8]; // frustum plane endpoints
- bool res = camera_matrix.get_endpoints(p_cam_transform, endpoints);
- ERR_CONTINUE(!res);
+ // FIXME: z_max_cam is defined, computed, but not used below when setting up
+ // ortho_camera. Commented out for now to fix warnings but should be investigated.
+ real_t x_min_cam = 0.f, x_max_cam = 0.f;
+ real_t y_min_cam = 0.f, y_max_cam = 0.f;
+ real_t z_min_cam = 0.f;
+ //real_t z_max_cam = 0.f;
- // obtain the light frustm ranges (given endpoints)
+ real_t bias_scale = 1.0;
+ real_t aspect_bias_scale = 1.0;
- Transform transform = light_transform; //discard scale and stabilize light
+ //used for culling
- Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized();
- Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized();
- Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized();
- //z_vec points agsint the camera, like in default opengl
+ for (int j = 0; j < 8; j++) {
+ real_t d_x = x_vec.dot(endpoints[j]);
+ real_t d_y = y_vec.dot(endpoints[j]);
+ real_t d_z = z_vec.dot(endpoints[j]);
- real_t x_min = 0.f, x_max = 0.f;
- real_t y_min = 0.f, y_max = 0.f;
- real_t z_min = 0.f, z_max = 0.f;
+ if (j == 0 || d_x < x_min) {
+ x_min = d_x;
+ }
+ if (j == 0 || d_x > x_max) {
+ x_max = d_x;
+ }
- // FIXME: z_max_cam is defined, computed, but not used below when setting up
- // ortho_camera. Commented out for now to fix warnings but should be investigated.
- real_t x_min_cam = 0.f, x_max_cam = 0.f;
- real_t y_min_cam = 0.f, y_max_cam = 0.f;
- real_t z_min_cam = 0.f;
- //real_t z_max_cam = 0.f;
+ if (j == 0 || d_y < y_min) {
+ y_min = d_y;
+ }
+ if (j == 0 || d_y > y_max) {
+ y_max = d_y;
+ }
- real_t bias_scale = 1.0;
- real_t aspect_bias_scale = 1.0;
+ if (j == 0 || d_z < z_min) {
+ z_min = d_z;
+ }
+ if (j == 0 || d_z > z_max) {
+ z_max = d_z;
+ }
+ }
- //used for culling
+ real_t radius = 0;
+ real_t soft_shadow_expand = 0;
+ Vector3 center;
- for (int j = 0; j < 8; j++) {
- real_t d_x = x_vec.dot(endpoints[j]);
- real_t d_y = y_vec.dot(endpoints[j]);
- real_t d_z = z_vec.dot(endpoints[j]);
+ {
+ //camera viewport stuff
- if (j == 0 || d_x < x_min) {
- x_min = d_x;
- }
- if (j == 0 || d_x > x_max) {
- x_max = d_x;
- }
+ for (int j = 0; j < 8; j++) {
+ center += endpoints[j];
+ }
+ center /= 8.0;
- if (j == 0 || d_y < y_min) {
- y_min = d_y;
- }
- if (j == 0 || d_y > y_max) {
- y_max = d_y;
- }
+ //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5;
- if (j == 0 || d_z < z_min) {
- z_min = d_z;
- }
- if (j == 0 || d_z > z_max) {
- z_max = d_z;
- }
+ for (int j = 0; j < 8; j++) {
+ real_t d = center.distance_to(endpoints[j]);
+ if (d > radius) {
+ radius = d;
}
+ }
- real_t radius = 0;
- real_t soft_shadow_expand = 0;
- Vector3 center;
-
- {
- //camera viewport stuff
-
- for (int j = 0; j < 8; j++) {
- center += endpoints[j];
- }
- center /= 8.0;
-
- //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5;
-
- for (int j = 0; j < 8; j++) {
- real_t d = center.distance_to(endpoints[j]);
- if (d > radius) {
- radius = d;
- }
- }
-
- radius *= texture_size / (texture_size - 2.0); //add a texel by each side
-
- if (i == 0) {
- first_radius = radius;
- } else {
- bias_scale = radius / first_radius;
- }
-
- z_min_cam = z_vec.dot(center) - radius;
-
- {
- float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
-
- if (soft_shadow_angle > 0.0 && pancake_size > 0.0) {
- float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam;
- soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range;
+ radius *= texture_size / (texture_size - 2.0); //add a texel by each side
- x_max += soft_shadow_expand;
- y_max += soft_shadow_expand;
+ if (i == 0) {
+ first_radius = radius;
+ } else {
+ bias_scale = radius / first_radius;
+ }
- x_min -= soft_shadow_expand;
- y_min -= soft_shadow_expand;
- }
- }
+ z_min_cam = z_vec.dot(center) - radius;
- x_max_cam = x_vec.dot(center) + radius + soft_shadow_expand;
- x_min_cam = x_vec.dot(center) - radius - soft_shadow_expand;
- y_max_cam = y_vec.dot(center) + radius + soft_shadow_expand;
- y_min_cam = y_vec.dot(center) - radius - soft_shadow_expand;
+ {
+ float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
- if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) {
- //this trick here is what stabilizes the shadow (make potential jaggies to not move)
- //at the cost of some wasted resolution. Still the quality increase is very well worth it
+ if (soft_shadow_angle > 0.0) {
+ float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam;
+ soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range;
- real_t unit = radius * 2.0 / texture_size;
+ x_max += soft_shadow_expand;
+ y_max += soft_shadow_expand;
- x_max_cam = Math::stepify(x_max_cam, unit);
- x_min_cam = Math::stepify(x_min_cam, unit);
- y_max_cam = Math::stepify(y_max_cam, unit);
- y_min_cam = Math::stepify(y_min_cam, unit);
- }
+ x_min -= soft_shadow_expand;
+ y_min -= soft_shadow_expand;
}
+ }
- //now that we now all ranges, we can proceed to make the light frustum planes, for culling octree
-
- Vector<Plane> light_frustum_planes;
- light_frustum_planes.resize(6);
-
- //right/left
- light_frustum_planes.write[0] = Plane(x_vec, x_max);
- light_frustum_planes.write[1] = Plane(-x_vec, -x_min);
- //top/bottom
- light_frustum_planes.write[2] = Plane(y_vec, y_max);
- light_frustum_planes.write[3] = Plane(-y_vec, -y_min);
- //near/far
- light_frustum_planes.write[4] = Plane(z_vec, z_max + 1e6);
- light_frustum_planes.write[5] = Plane(-z_vec, -z_min); // z_min is ok, since casters further than far-light plane are not needed
-
- geometry_instances_to_shadow_render.clear();
- instance_shadow_cull_result.clear();
+ x_max_cam = x_vec.dot(center) + radius + soft_shadow_expand;
+ x_min_cam = x_vec.dot(center) - radius - soft_shadow_expand;
+ y_max_cam = y_vec.dot(center) + radius + soft_shadow_expand;
+ y_min_cam = y_vec.dot(center) - radius - soft_shadow_expand;
- Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&light_frustum_planes[0], light_frustum_planes.size());
+ if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) {
+ //this trick here is what stabilizes the shadow (make potential jaggies to not move)
+ //at the cost of some wasted resolution. Still the quality increase is very well worth it
- struct CullConvex {
- PagedArray<Instance *> *result;
- _FORCE_INLINE_ bool operator()(void *p_data) {
- Instance *p_instance = (Instance *)p_data;
- result->push_back(p_instance);
- return false;
- }
- };
+ real_t unit = radius * 2.0 / texture_size;
- CullConvex cull_convex;
- cull_convex.result = &instance_shadow_cull_result;
+ x_max_cam = Math::snapped(x_max_cam, unit);
+ x_min_cam = Math::snapped(x_min_cam, unit);
+ y_max_cam = Math::snapped(y_max_cam, unit);
+ y_min_cam = Math::snapped(y_min_cam, unit);
+ }
+ }
- p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(light_frustum_planes.ptr(), light_frustum_planes.size(), points.ptr(), points.size(), cull_convex);
+ //now that we know all ranges, we can proceed to make the light frustum planes, for culling octree
- // a pre pass will need to be needed to determine the actual z-near to be used
+ Vector<Plane> light_frustum_planes;
+ light_frustum_planes.resize(6);
- Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
+ //right/left
+ light_frustum_planes.write[0] = Plane(x_vec, x_max);
+ light_frustum_planes.write[1] = Plane(-x_vec, -x_min);
+ //top/bottom
+ light_frustum_planes.write[2] = Plane(y_vec, y_max);
+ light_frustum_planes.write[3] = Plane(-y_vec, -y_min);
+ //near/far
+ light_frustum_planes.write[4] = Plane(z_vec, z_max + 1e6);
+ light_frustum_planes.write[5] = Plane(-z_vec, -z_min); // z_min is ok, since casters further than far-light plane are not needed
- real_t cull_max = 0;
- for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
- real_t min, max;
- Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
- continue;
- }
+ // a pre pass will need to be needed to determine the actual z-near to be used
- instance->transformed_aabb.project_range_in_plane(Plane(z_vec, 0), min, max);
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
- if (j == 0 || max > cull_max) {
- cull_max = max;
- }
+ if (pancake_size > 0) {
+ z_max = z_vec.dot(center) + radius + pancake_size;
+ }
- if (instance->mesh_instance.is_valid()) {
- RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
- }
+ if (aspect != 1.0) {
+ // if the aspect is different, then the radius will become larger.
+ // if this happens, then bias needs to be adjusted too, as depth will increase
+ // to do this, compare the depth of one that would have resulted from a square frustum
- geometry_instances_to_shadow_render.push_back(instance);
- }
-
- if (cull_max > z_max) {
- z_max = cull_max;
+ CameraMatrix camera_matrix_square;
+ if (p_cam_orthogonal) {
+ Vector2 vp_he = camera_matrix.get_viewport_half_extents();
+ if (p_cam_vaspect) {
+ camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
+ } else {
+ camera_matrix_square.set_orthogonal(vp_he.y * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
}
-
- if (pancake_size > 0) {
- z_max = z_vec.dot(center) + radius + pancake_size;
+ } else {
+ Vector2 vp_he = camera_matrix.get_viewport_half_extents();
+ if (p_cam_vaspect) {
+ camera_matrix_square.set_frustum(vp_he.x * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
+ } else {
+ camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
}
+ }
- if (aspect != 1.0) {
- // if the aspect is different, then the radius will become larger.
- // if this happens, then bias needs to be adjusted too, as depth will increase
- // to do this, compare the depth of one that would have resulted from a square frustum
-
- CameraMatrix camera_matrix_square;
- if (p_cam_orthogonal) {
- Vector2 vp_he = camera_matrix.get_viewport_half_extents();
- if (p_cam_vaspect) {
- camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
- } else {
- camera_matrix_square.set_orthogonal(vp_he.y * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
- }
- } else {
- Vector2 vp_he = camera_matrix.get_viewport_half_extents();
- if (p_cam_vaspect) {
- camera_matrix_square.set_frustum(vp_he.x * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
- } else {
- camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
- }
- }
-
- Vector3 endpoints_square[8]; // frustum plane endpoints
- res = camera_matrix_square.get_endpoints(p_cam_transform, endpoints_square);
- ERR_CONTINUE(!res);
- Vector3 center_square;
- real_t z_max_square = 0;
-
- for (int j = 0; j < 8; j++) {
- center_square += endpoints_square[j];
-
- real_t d_z = z_vec.dot(endpoints_square[j]);
-
- if (j == 0 || d_z > z_max_square) {
- z_max_square = d_z;
- }
- }
+ Vector3 endpoints_square[8]; // frustum plane endpoints
+ res = camera_matrix_square.get_endpoints(p_cam_transform, endpoints_square);
+ ERR_CONTINUE(!res);
+ Vector3 center_square;
- if (cull_max > z_max_square) {
- z_max_square = cull_max;
- }
+ for (int j = 0; j < 8; j++) {
+ center_square += endpoints_square[j];
+ }
- center_square /= 8.0;
+ center_square /= 8.0;
- real_t radius_square = 0;
+ real_t radius_square = 0;
- for (int j = 0; j < 8; j++) {
- real_t d = center_square.distance_to(endpoints_square[j]);
- if (d > radius_square) {
- radius_square = d;
- }
- }
+ for (int j = 0; j < 8; j++) {
+ real_t d = center_square.distance_to(endpoints_square[j]);
+ if (d > radius_square) {
+ radius_square = d;
+ }
+ }
- radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side
+ radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side
- if (pancake_size > 0) {
- z_max_square = z_vec.dot(center_square) + radius_square + pancake_size;
- }
+ float z_max_square = z_vec.dot(center_square) + radius_square + pancake_size;
- real_t z_min_cam_square = z_vec.dot(center_square) - radius_square;
+ real_t z_min_cam_square = z_vec.dot(center_square) - radius_square;
- aspect_bias_scale = (z_max - z_min_cam) / (z_max_square - z_min_cam_square);
+ aspect_bias_scale = (z_max - z_min_cam) / (z_max_square - z_min_cam_square);
- // this is not entirely perfect, because the cull-adjusted z-max may be different
- // but at least it's warranted that it results in a greater bias, so no acne should be present either way.
- // pancaking also helps with this.
- }
+ // this is not entirely perfect, because the cull-adjusted z-max may be different
+ // but at least it's warranted that it results in a greater bias, so no acne should be present either way.
+ // pancaking also helps with this.
+ }
- {
- CameraMatrix ortho_camera;
- real_t half_x = (x_max_cam - x_min_cam) * 0.5;
- real_t half_y = (y_max_cam - y_min_cam) * 0.5;
+ {
+ CameraMatrix ortho_camera;
+ real_t half_x = (x_max_cam - x_min_cam) * 0.5;
+ real_t half_y = (y_max_cam - y_min_cam) * 0.5;
- ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam));
+ ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam));
- Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam));
+ Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam));
- Transform ortho_transform;
- ortho_transform.basis = transform.basis;
- ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max;
+ Transform ortho_transform;
+ ortho_transform.basis = transform.basis;
+ ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max;
- {
- Vector3 max_in_view = p_cam_transform.affine_inverse().xform(z_vec * cull_max);
- Vector3 dir_in_view = p_cam_transform.xform_inv(z_vec).normalized();
- cull_max = dir_in_view.dot(max_in_view);
- }
+ cull.shadows[p_shadow_index].cascades[i].frustum = Frustum(light_frustum_planes);
+ cull.shadows[p_shadow_index].cascades[i].projection = ortho_camera;
+ cull.shadows[p_shadow_index].cascades[i].transform = ortho_transform;
+ cull.shadows[p_shadow_index].cascades[i].zfar = z_max - z_min_cam;
+ cull.shadows[p_shadow_index].cascades[i].split = distances[i + 1];
+ cull.shadows[p_shadow_index].cascades[i].shadow_texel_size = radius * 2.0 / texture_size;
+ cull.shadows[p_shadow_index].cascades[i].bias_scale = bias_scale * aspect_bias_scale * min_distance_bias_scale;
+ cull.shadows[p_shadow_index].cascades[i].range_begin = z_max;
+ cull.shadows[p_shadow_index].cascades[i].uv_scale = uv_scale;
+ }
+ }
+}
- scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, z_max - z_min_cam, distances[i + 1], i, radius * 2.0 / texture_size, bias_scale * aspect_bias_scale * min_distance_bias_scale, z_max, uv_scale);
- }
+bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_lod_threshold) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
- RSG::storage->update_mesh_instances();
+ Transform light_transform = p_instance->transform;
+ light_transform.orthonormalize(); //scale does not count on lights
- scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render, camera_plane, p_cam_projection.get_lod_multiplier(), p_screen_lod_threshold);
- }
+ bool animated_material_found = false;
+ switch (RSG::storage->light_get_type(p_instance->base)) {
+ case RS::LIGHT_DIRECTIONAL: {
} break;
case RS::LIGHT_OMNI: {
RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base);
if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !scene_render->light_instances_can_render_shadow_cube()) {
+ if (max_shadows_used + 2 > MAX_UPDATE_SHADOWS) {
+ return true;
+ }
for (int i = 0; i < 2; i++) {
//using this one ensures that raster deferred will have it
RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i));
@@ -1760,7 +1928,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
planes.write[5] = light_transform.xform(Plane(Vector3(0, 0, -z), 0));
- geometry_instances_to_shadow_render.clear();
instance_shadow_cull_result.clear();
Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
@@ -1781,6 +1948,8 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
+ RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++];
+
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
Instance *instance = instance_shadow_cull_result[j];
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
@@ -1790,24 +1959,26 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
animated_material_found = true;
}
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
-
if (instance->mesh_instance.is_valid()) {
RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
}
}
- geometry_instances_to_shadow_render.push_back(instance);
+ shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
}
RSG::storage->update_mesh_instances();
scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0);
- scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render);
+ shadow_data.light = light->instance;
+ shadow_data.pass = i;
}
} else { //shadow cube
+ if (max_shadows_used + 6 > MAX_UPDATE_SHADOWS) {
+ return true;
+ }
+
real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
CameraMatrix cm;
cm.set_perspective(90, 1, 0.01, radius);
@@ -1837,7 +2008,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
Vector<Plane> planes = cm.get_projection_planes(xform);
- geometry_instances_to_shadow_render.clear();
instance_shadow_cull_result.clear();
Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
@@ -1856,7 +2026,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
- Plane near_plane(xform.origin, -xform.basis.get_axis(2));
+ RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++];
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
Instance *instance = instance_shadow_cull_result[j];
@@ -1866,29 +2036,33 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
animated_material_found = true;
}
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
if (instance->mesh_instance.is_valid()) {
RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
}
}
- geometry_instances_to_shadow_render.push_back(instance);
+ shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
}
RSG::storage->update_mesh_instances();
scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0);
- scene_render->render_shadow(light->instance, p_shadow_atlas, i, geometry_instances_to_shadow_render);
+
+ shadow_data.light = light->instance;
+ shadow_data.pass = i;
}
//restore the regular DP matrix
- scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0);
+ //scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0);
}
} break;
case RS::LIGHT_SPOT: {
RENDER_TIMESTAMP("Culling Spot Light");
+ if (max_shadows_used + 1 > MAX_UPDATE_SHADOWS) {
+ return true;
+ }
+
real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
@@ -1897,7 +2071,6 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
Vector<Plane> planes = cm.get_projection_planes(light_transform);
- geometry_instances_to_shadow_render.clear();
instance_shadow_cull_result.clear();
Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
@@ -1916,7 +2089,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
p_scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_convex);
- Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
+ RendererSceneRender::RenderShadowData &shadow_data = render_shadow_data[max_shadows_used++];
for (int j = 0; j < (int)instance_shadow_cull_result.size(); j++) {
Instance *instance = instance_shadow_cull_result[j];
@@ -1926,20 +2099,19 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
animated_material_found = true;
}
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
if (instance->mesh_instance.is_valid()) {
RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
}
}
- geometry_instances_to_shadow_render.push_back(instance);
+ shadow_data.instances.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
}
RSG::storage->update_mesh_instances();
scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0);
- scene_render->render_shadow(light->instance, p_shadow_atlas, 0, geometry_instances_to_shadow_render);
+ shadow_data.light = light->instance;
+ shadow_data.pass = 0;
} break;
}
@@ -1992,14 +2164,13 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_
RID environment = _render_get_environment(p_camera, p_scenario);
- _prepare_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), p_screen_lod_threshold);
- _render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold);
+ _render_scene(camera->transform, camera_matrix, ortho, camera->vaspect, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold);
#endif
}
void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas) {
// render for AR/VR interface
-
+#if 0
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
@@ -2079,255 +2250,394 @@ void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_
// And render our scene...
_render_scene(p_render_buffers, cam_transform, camera_matrix, false, environment, camera->effects, p_scenario, p_shadow_atlas, RID(), -1, p_screen_lod_threshold);
+#endif
};
-void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows) {
- // Note, in stereo rendering:
- // - p_cam_transform will be a transform in the middle of our two eyes
- // - p_cam_projection is a wider frustrum that encompasses both eyes
+void RendererSceneCull::_frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data) {
+ uint32_t cull_total = cull_data->scenario->instance_data.size();
+ uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();
+ uint32_t cull_from = p_thread * cull_total / total_threads;
+ uint32_t cull_to = (p_thread + 1 == total_threads) ? cull_total : ((p_thread + 1) * cull_total / total_threads);
- Scenario *scenario = scenario_owner.getornull(p_scenario);
+ _frustum_cull(*cull_data, frustum_cull_result_threads[p_thread], cull_from, cull_to);
+}
- render_pass++;
- uint32_t camera_layer_mask = p_visible_layers;
+void RendererSceneCull::_frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to) {
+ uint64_t frame_number = RSG::rasterizer->get_frame_number();
+ float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
- scene_render->set_scene_pass(render_pass);
+ uint32_t sdfgi_last_light_index = 0xFFFFFFFF;
+ uint32_t sdfgi_last_light_cascade = 0xFFFFFFFF;
- if (p_render_buffers.is_valid()) {
- scene_render->sdfgi_update(p_render_buffers, p_environment, p_cam_transform.origin); //update conditions for SDFGI (whether its used or not)
- }
+ RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
- RENDER_TIMESTAMP("Frustum Culling");
+ for (uint64_t i = p_from; i < p_to; i++) {
+ bool mesh_visible = false;
- //rasterizer->set_camera(camera->transform, camera_matrix,ortho);
+ if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->frustum)) {
+ InstanceData &idata = cull_data.scenario->instance_data[i];
+ uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
- Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
+ if ((cull_data.visible_layers & idata.layer_mask) == 0) {
+ //failure
+ } else if (base_type == RS::INSTANCE_LIGHT) {
+ cull_result.lights.push_back(idata.instance);
+ cull_result.light_instances.push_back(RID::from_uint64(idata.instance_data_rid));
+ if (cull_data.shadow_atlas.is_valid() && RSG::storage->light_has_shadow(idata.base_rid)) {
+ scene_render->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later
+ }
- Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2).normalized());
- float z_far = p_cam_projection.get_z_far();
+ } else if (base_type == RS::INSTANCE_REFLECTION_PROBE) {
+ if (cull_data.render_reflection_probe != idata.instance) {
+ //avoid entering The Matrix
- instance_cull_result.clear();
- /* STEP 2 - CULL */
- {
- CullResult cull_result;
- cull_result.result = &instance_cull_result;
+ if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data);
+ cull_data.cull->lock.lock();
+ if (!reflection_probe->update_list.in_list()) {
+ reflection_probe->render_step = 0;
+ reflection_probe_render_list.add_last(&reflection_probe->update_list);
+ }
+ cull_data.cull->lock.unlock();
- Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&planes[0], planes.size());
+ idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY);
+ }
- scenario->indexers[Scenario::INDEXER_GEOMETRY].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_result);
- scenario->indexers[Scenario::INDEXER_VOLUMES].convex_query(planes.ptr(), planes.size(), points.ptr(), points.size(), cull_result);
- }
+ if (scene_render->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) {
+ cull_result.reflections.push_back(RID::from_uint64(idata.instance_data_rid));
+ }
+ }
+ } else if (base_type == RS::INSTANCE_DECAL) {
+ cull_result.decals.push_back(RID::from_uint64(idata.instance_data_rid));
+
+ } else if (base_type == RS::INSTANCE_GI_PROBE) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(idata.instance->base_data);
+ cull_data.cull->lock.lock();
+ if (!gi_probe->update_element.in_list()) {
+ gi_probe_update_list.add(&gi_probe->update_element);
+ }
+ cull_data.cull->lock.unlock();
+ cull_result.gi_probes.push_back(RID::from_uint64(idata.instance_data_rid));
- //light_samplers_culled=0;
+ } else if (base_type == RS::INSTANCE_LIGHTMAP) {
+ cull_result.gi_probes.push_back(RID::from_uint64(idata.instance_data_rid));
+ } else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) {
+ bool keep = true;
- /*
- print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0));
- print_line("OTO: "+itos(p_scenario->octree.get_octant_count()));
- print_line("OTE: "+itos(p_scenario->octree.get_elem_count()));
- print_line("OTP: "+itos(p_scenario->octree.get_pair_count()));
- */
+ if (idata.flags & InstanceData::FLAG_REDRAW_IF_VISIBLE) {
+ RenderingServerDefault::redraw_request();
+ }
- /* STEP 3 - PROCESS PORTALS, VALIDATE ROOMS */
- //removed, will replace with culling
+ if (base_type == RS::INSTANCE_MESH) {
+ mesh_visible = true;
+ } else if (base_type == RS::INSTANCE_PARTICLES) {
+ //particles visible? process them
+ if (RSG::storage->particles_is_inactive(idata.base_rid)) {
+ //but if nothing is going on, don't do it.
+ keep = false;
+ } else {
+ cull_data.cull->lock.lock();
+ RSG::storage->particles_request_process(idata.base_rid);
+ cull_data.cull->lock.unlock();
+ RSG::storage->particles_set_view_axis(idata.base_rid, -cull_data.cam_transform.basis.get_axis(2).normalized());
+ //particles visible? request redraw
+ RenderingServerDefault::redraw_request();
+ }
+ }
- /* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */
- uint64_t frame_number = RSG::rasterizer->get_frame_number();
- float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
+ if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ uint32_t idx = 0;
- geometry_instances_to_render.clear();
- light_cull_result.clear();
- lightmap_cull_result.clear();
- reflection_probe_instance_cull_result.clear();
- light_instance_cull_result.clear();
- gi_probe_instance_cull_result.clear();
- lightmap_cull_result.clear();
- decal_instance_cull_result.clear();
-
- for (uint32_t i = 0; i < (uint32_t)instance_cull_result.size(); i++) {
- Instance *ins = instance_cull_result[i];
-
- if ((camera_layer_mask & ins->layer_mask) == 0) {
- //failure
- } else if (ins->base_type == RS::INSTANCE_LIGHT) {
- InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data);
+ for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+ instance_pair_buffer[idx++] = light->instance;
+ if (idx == MAX_INSTANCE_PAIRS) {
+ break;
+ }
+ }
- light_cull_result.push_back(ins);
- light_instance_cull_result.push_back(light->instance);
- if (p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(ins->base)) {
- scene_render->light_instance_mark_visible(light->instance); //mark it visible for shadow allocation later
- }
+ scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, instance_pair_buffer, idx);
+ idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY);
+ }
- } else if (ins->base_type == RS::INSTANCE_REFLECTION_PROBE) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(ins->base_data);
+ if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ uint32_t idx = 0;
- if (p_reflection_probe != reflection_probe->instance) {
- //avoid entering The Matrix
+ for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
- if (reflection_probe->reflection_dirty || scene_render->reflection_probe_instance_needs_redraw(reflection_probe->instance)) {
- if (!reflection_probe->update_list.in_list()) {
- reflection_probe->render_step = 0;
- reflection_probe_render_list.add_last(&reflection_probe->update_list);
+ instance_pair_buffer[idx++] = reflection_probe->instance;
+ if (idx == MAX_INSTANCE_PAIRS) {
+ break;
+ }
}
- reflection_probe->reflection_dirty = false;
- }
-
- if (scene_render->reflection_probe_instance_has_reflection(reflection_probe->instance)) {
- reflection_probe_instance_cull_result.push_back(reflection_probe->instance);
+ scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
+ idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY);
}
- }
- } else if (ins->base_type == RS::INSTANCE_DECAL) {
- InstanceDecalData *decal = static_cast<InstanceDecalData *>(ins->base_data);
- decal_instance_cull_result.push_back(decal->instance);
+ if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) {
+ //InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ //todo for GLES3
+ idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY);
+ /*for (Set<Instance *>::Element *E = geom->dec.front(); E; E = E->next()) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
- } else if (ins->base_type == RS::INSTANCE_GI_PROBE) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(ins->base_data);
- if (!gi_probe->update_element.in_list()) {
- gi_probe_update_list.add(&gi_probe->update_element);
- }
+ instance_pair_buffer[idx++] = reflection_probe->instance;
+ if (idx==MAX_INSTANCE_PAIRS) {
+ break;
+ }
+ }*/
+ //scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, light_instances, idx);
+ }
- gi_probe_instance_cull_result.push_back(gi_probe->probe_instance);
+ if (idata.flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ uint32_t idx = 0;
+ for (Set<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) {
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data);
- } else if (ins->base_type == RS::INSTANCE_LIGHTMAP) {
- lightmap_cull_result.push_back(ins);
- } else if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
- bool keep = true;
+ instance_pair_buffer[idx++] = gi_probe->probe_instance;
+ if (idx == MAX_INSTANCE_PAIRS) {
+ break;
+ }
+ }
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
+ scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
+ idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY);
+ }
- if (ins->redraw_if_visible) {
- RenderingServerDefault::redraw_request();
- }
+ if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
+ Color *sh = idata.instance->lightmap_sh.ptrw();
+ const Color *target_sh = idata.instance->lightmap_target_sh.ptr();
+ for (uint32_t j = 0; j < 9; j++) {
+ sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
+ }
+ scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, sh);
+ idata.instance->last_frame_pass = frame_number;
+ }
- if (ins->base_type == RS::INSTANCE_PARTICLES) {
- //particles visible? process them
- if (RSG::storage->particles_is_inactive(ins->base)) {
- //but if nothing is going on, don't do it.
- keep = false;
- } else {
- RSG::storage->particles_request_process(ins->base);
- RSG::storage->particles_set_view_axis(ins->base, -p_cam_transform.basis.get_axis(2).normalized());
- //particles visible? request redraw
- RenderingServerDefault::redraw_request();
+ if (keep) {
+ cull_result.geometry_instances.push_back(idata.instance_geometry);
}
}
+ }
- if (pair_volumes_to_mesh && geom->lighting_dirty) {
- int l = 0;
- //only called when lights AABB enter/exit this geometry
- ins->light_instances.resize(geom->lights.size());
-
- for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
- InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+ for (uint32_t j = 0; j < cull_data.cull->shadow_count; j++) {
+ for (uint32_t k = 0; k < cull_data.cull->shadows[j].cascade_count; k++) {
+ if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->shadows[j].cascades[k].frustum)) {
+ InstanceData &idata = cull_data.scenario->instance_data[i];
+ uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
- ins->light_instances.write[l++] = light->instance;
+ if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS) {
+ cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry);
+ mesh_visible = true;
+ }
}
-
- geom->lighting_dirty = false;
}
+ }
- if (pair_volumes_to_mesh && geom->reflection_dirty) {
- int l = 0;
- //only called when reflection probe AABB enter/exit this geometry
- ins->reflection_probe_instances.resize(geom->reflection_probes.size());
-
- for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
+ for (uint32_t j = 0; j < cull_data.cull->sdfgi.region_count; j++) {
+ if (cull_data.scenario->instance_aabbs[i].in_aabb(cull_data.cull->sdfgi.region_aabb[j])) {
+ InstanceData &idata = cull_data.scenario->instance_data[i];
+ uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
- ins->reflection_probe_instances.write[l++] = reflection_probe->instance;
+ if (base_type == RS::INSTANCE_LIGHT) {
+ InstanceLightData *instance_light = (InstanceLightData *)idata.instance->base_data;
+ if (instance_light->bake_mode == RS::LIGHT_BAKE_STATIC && cull_data.cull->sdfgi.region_cascade[j] <= instance_light->max_sdfgi_cascade) {
+ if (sdfgi_last_light_index != i || sdfgi_last_light_cascade != cull_data.cull->sdfgi.region_cascade[j]) {
+ sdfgi_last_light_index = i;
+ sdfgi_last_light_cascade = cull_data.cull->sdfgi.region_cascade[j];
+ cull_result.sdfgi_cascade_lights[sdfgi_last_light_cascade].push_back(instance_light->instance);
+ }
+ }
+ } else if ((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ if (idata.flags & InstanceData::FLAG_USES_BAKED_LIGHT) {
+ cull_result.sdfgi_region_geometry_instances[j].push_back(idata.instance_geometry);
+ mesh_visible = true;
+ }
}
-
- geom->reflection_dirty = false;
}
+ }
+
+ if (mesh_visible && cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_USES_MESH_INSTANCE) {
+ cull_result.mesh_instances.push_back(cull_data.scenario->instance_data[i].instance->mesh_instance);
+ }
+ }
+}
- if (geom->gi_probes_dirty) {
- int l = 0;
- //only called when reflection probe AABB enter/exit this geometry
- ins->gi_probe_instances.resize(geom->gi_probes.size());
+void RendererSceneCull::_render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows) {
+ // Note, in stereo rendering:
+ // - p_cam_transform will be a transform in the middle of our two eyes
+ // - p_cam_projection is a wider frustrum that encompasses both eyes
- for (Set<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) {
- InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data);
+ Instance *render_reflection_probe = instance_owner.getornull(p_reflection_probe); //if null, not rendering to it
- ins->gi_probe_instances.write[l++] = gi_probe->probe_instance;
- }
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
- geom->gi_probes_dirty = false;
- }
+ render_pass++;
- if (ins->last_frame_pass != frame_number && !ins->lightmap_target_sh.empty() && !ins->lightmap_sh.empty()) {
- Color *sh = ins->lightmap_sh.ptrw();
- const Color *target_sh = ins->lightmap_target_sh.ptr();
- for (uint32_t j = 0; j < 9; j++) {
- sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
- }
- }
+ scene_render->set_scene_pass(render_pass);
- if (ins->mesh_instance.is_valid()) {
- RSG::storage->mesh_instance_check_for_update(ins->mesh_instance);
- }
+ if (p_render_buffers.is_valid()) {
+ //no rendering code here, this is only to set up what needs to be done, request regions, etc.
+ scene_render->sdfgi_update(p_render_buffers, p_environment, p_cam_transform.origin); //update conditions for SDFGI (whether its used or not)
+ }
- ins->depth = near_plane.distance_to(ins->transform.origin);
- ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15);
+ RENDER_TIMESTAMP("Frustum Culling");
- if (keep) {
- geometry_instances_to_render.push_back(ins);
- ins->last_render_pass = render_pass;
- } else {
- ins->last_render_pass = 0; // make invalid
- }
- }
+ //rasterizer->set_camera(camera->transform, camera_matrix,ortho);
- ins->last_frame_pass = frame_number;
- }
+ Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
- RSG::storage->update_mesh_instances();
+ Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2).normalized());
- /* STEP 5 - PROCESS LIGHTS */
+ /* STEP 2 - CULL */
- directional_light_cull_result.clear();
+ cull.frustum = Frustum(planes);
+ Vector<RID> directional_lights;
// directional lights
{
- directional_shadow_cull_result.clear();
+ cull.shadow_count = 0;
+
+ Vector<Instance *> lights_with_shadow;
for (List<Instance *>::Element *E = scenario->directional_lights.front(); E; E = E->next()) {
if (!E->get()->visible) {
continue;
}
+ if (directional_lights.size() > RendererSceneRender::MAX_DIRECTIONAL_LIGHTS) {
+ break;
+ }
+
InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
//check shadow..
if (light) {
if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->get()->base) && !(RSG::storage->light_get_type(E->get()->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_is_sky_only(E->get()->base))) {
- directional_shadow_cull_result.push_back(E->get());
+ lights_with_shadow.push_back(E->get());
}
//add to list
- directional_light_cull_result.push_back(light->instance);
+ directional_lights.push_back(light->instance);
+ }
+ }
+
+ scene_render->set_directional_shadow_count(lights_with_shadow.size());
+
+ for (int i = 0; i < lights_with_shadow.size(); i++) {
+ _light_instance_setup_directional_shadow(i, lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect);
+ }
+ }
+
+ { //sdfgi
+ cull.sdfgi.region_count = 0;
+
+ if (p_render_buffers.is_valid()) {
+ cull.sdfgi.cascade_light_count = 0;
+
+ uint32_t prev_cascade = 0xFFFFFFFF;
+ uint32_t pending_region_count = scene_render->sdfgi_get_pending_region_count(p_render_buffers);
+
+ for (uint32_t i = 0; i < pending_region_count; i++) {
+ cull.sdfgi.region_aabb[i] = scene_render->sdfgi_get_pending_region_bounds(p_render_buffers, i);
+ uint32_t region_cascade = scene_render->sdfgi_get_pending_region_cascade(p_render_buffers, i);
+ cull.sdfgi.region_cascade[i] = region_cascade;
+
+ if (region_cascade != prev_cascade) {
+ cull.sdfgi.cascade_light_index[cull.sdfgi.cascade_light_count] = region_cascade;
+ cull.sdfgi.cascade_light_count++;
+ prev_cascade = region_cascade;
+ }
}
- light_instance_cull_result.push_back(light->instance);
+ cull.sdfgi.region_count = pending_region_count;
}
+ }
+
+ frustum_cull_result.clear();
+
+ {
+ uint64_t cull_from = 0;
+ uint64_t cull_to = scenario->instance_data.size();
+
+ FrustumCullData cull_data;
+
+ //prepare for eventual thread usage
+ cull_data.cull = &cull;
+ cull_data.scenario = scenario;
+ cull_data.shadow_atlas = p_shadow_atlas;
+ cull_data.cam_transform = p_cam_transform;
+ cull_data.visible_layers = p_visible_layers;
+ cull_data.render_reflection_probe = render_reflection_probe;
+//#define DEBUG_CULL_TIME
+#ifdef DEBUG_CULL_TIME
+ uint64_t time_from = OS::get_singleton()->get_ticks_usec();
+#endif
+ if (cull_to > thread_cull_threshold) {
+ //multiple threads
+ for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) {
+ frustum_cull_result_threads[i].clear();
+ }
+
+ RendererThreadPool::singleton->thread_work_pool.do_work(frustum_cull_result_threads.size(), this, &RendererSceneCull::_frustum_cull_threaded, &cull_data);
- scene_render->set_directional_shadow_count(directional_shadow_cull_result.size());
+ for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) {
+ frustum_cull_result.append_from(frustum_cull_result_threads[i]);
+ }
- for (uint32_t i = 0; i < (uint32_t)directional_shadow_cull_result.size(); i++) {
- RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i));
+ } else {
+ //single threaded
+ _frustum_cull(cull_data, frustum_cull_result, cull_from, cull_to);
+ }
- _light_instance_update_shadow(directional_shadow_cull_result[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario, p_screen_lod_threshold);
+#ifdef DEBUG_CULL_TIME
+ static float time_avg = 0;
+ static uint32_t time_count = 0;
+ time_avg += double(OS::get_singleton()->get_ticks_usec() - time_from) / 1000.0;
+ time_count++;
+ print_line("time taken: " + rtos(time_avg / time_count));
+#endif
- RENDER_TIMESTAMP("<Rendering Directional Light " + itos(i));
+ if (frustum_cull_result.mesh_instances.size()) {
+ for (uint64_t i = 0; i < frustum_cull_result.mesh_instances.size(); i++) {
+ RSG::storage->mesh_instance_check_for_update(frustum_cull_result.mesh_instances[i]);
+ }
+ RSG::storage->update_mesh_instances();
}
}
+ //render shadows
+
+ max_shadows_used = 0;
+
if (p_using_shadows) { //setup shadow maps
- //SortArray<Instance*,_InstanceLightsort> sorter;
- //sorter.sort(light_cull_result,light_cull_count);
- for (uint32_t i = 0; i < (uint32_t)light_cull_result.size(); i++) {
- Instance *ins = light_cull_result[i];
+ // Directional Shadows
+
+ for (uint32_t i = 0; i < cull.shadow_count; i++) {
+ for (uint32_t j = 0; j < cull.shadows[i].cascade_count; j++) {
+ const Cull::Shadow::Cascade &c = cull.shadows[i].cascades[j];
+ // print_line("shadow " + itos(i) + " cascade " + itos(j) + " elements: " + itos(c.cull_result.size()));
+ scene_render->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale);
+ if (max_shadows_used == MAX_UPDATE_SHADOWS) {
+ continue;
+ }
+ render_shadow_data[max_shadows_used].light = cull.shadows[i].light_instance;
+ render_shadow_data[max_shadows_used].pass = j;
+ render_shadow_data[max_shadows_used].instances.merge_unordered(frustum_cull_result.directional_shadows[i].cascade_geometry_instances[j]);
+ max_shadows_used++;
+ }
+ }
+
+ // Positional Shadowss
+ for (uint32_t i = 0; i < (uint32_t)frustum_cull_result.lights.size(); i++) {
+ Instance *ins = frustum_cull_result.lights[i];
if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) {
continue;
@@ -2412,88 +2722,78 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
bool redraw = scene_render->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version);
- if (redraw) {
+ if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) {
//must redraw!
RENDER_TIMESTAMP(">Rendering Light " + itos(i));
light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario, p_screen_lod_threshold);
RENDER_TIMESTAMP("<Rendering Light " + itos(i));
+ } else {
+ light->shadow_dirty = redraw;
}
}
}
- /* UPDATE SDFGI */
-
- if (p_render_buffers.is_valid()) {
- uint32_t cascade_index[8];
- for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
- sdfgi_cascade_lights[i].clear();
- }
- uint32_t cascade_count = 0;
- uint32_t sdfgi_light_cull_count = 0;
+ //render SDFGI
- uint32_t prev_cascade = 0xFFFFFFFF;
- for (int i = 0; i < scene_render->sdfgi_get_pending_region_count(p_render_buffers); i++) {
- AABB region = scene_render->sdfgi_get_pending_region_bounds(p_render_buffers, i);
- uint32_t region_cascade = scene_render->sdfgi_get_pending_region_cascade(p_render_buffers, i);
+ {
+ sdfgi_update_data.update_static = false;
- if (region_cascade != prev_cascade) {
- cascade_index[cascade_count] = region_cascade;
- cascade_count++;
- sdfgi_light_cull_pass++;
- prev_cascade = region_cascade;
+ if (cull.sdfgi.region_count > 0) {
+ //update regions
+ for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) {
+ render_sdfgi_data[i].instances.merge_unordered(frustum_cull_result.sdfgi_region_geometry_instances[i]);
+ render_sdfgi_data[i].region = i;
}
- instance_sdfgi_cull_result.clear();
- {
- CullResult cull_result;
- cull_result.result = &instance_sdfgi_cull_result;
-
- scenario->indexers[Scenario::INDEXER_GEOMETRY].aabb_query(region, cull_result);
- scenario->indexers[Scenario::INDEXER_VOLUMES].aabb_query(region, cull_result);
+ //check if static lights were culled
+ bool static_lights_culled = false;
+ for (uint32_t i = 0; i < cull.sdfgi.cascade_light_count; i++) {
+ if (frustum_cull_result.sdfgi_cascade_lights[i].size()) {
+ static_lights_culled = true;
+ break;
+ }
}
- geometry_instances_to_sdfgi_render.clear();
-
- for (uint32_t j = 0; j < (uint32_t)instance_sdfgi_cull_result.size(); j++) {
- Instance *ins = instance_sdfgi_cull_result[j];
-
- bool keep = false;
-
- if (ins->base_type == RS::INSTANCE_LIGHT) {
- InstanceLightData *instance_light = (InstanceLightData *)ins->base_data;
- if (instance_light->bake_mode != RS::LIGHT_BAKE_STATIC || region_cascade > instance_light->max_sdfgi_cascade) {
- continue;
- }
+ if (static_lights_culled) {
+ sdfgi_update_data.static_cascade_count = cull.sdfgi.cascade_light_count;
+ sdfgi_update_data.static_cascade_indices = cull.sdfgi.cascade_light_index;
+ sdfgi_update_data.static_positional_lights = frustum_cull_result.sdfgi_cascade_lights;
+ sdfgi_update_data.update_static = true;
+ }
+ }
- if (sdfgi_light_cull_pass != instance_light->sdfgi_cascade_light_pass) {
- instance_light->sdfgi_cascade_light_pass = sdfgi_light_cull_pass;
- sdfgi_cascade_lights[cascade_count - 1].push_back(instance_light->instance);
- }
- } else if ((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
- if (ins->baked_light) {
- keep = true;
- if (ins->mesh_instance.is_valid()) {
- RSG::storage->mesh_instance_check_for_update(ins->mesh_instance);
- }
- }
- }
+ if (p_render_buffers.is_valid()) {
+ sdfgi_update_data.directional_lights = &directional_lights;
+ sdfgi_update_data.positional_light_instances = scenario->dynamic_lights.ptr();
+ sdfgi_update_data.positional_light_count = scenario->dynamic_lights.size();
+ }
+ }
- if (keep) {
- geometry_instances_to_sdfgi_render.push_back(ins);
- }
- }
+ //append the directional lights to the lights culled
+ for (int i = 0; i < directional_lights.size(); i++) {
+ frustum_cull_result.light_instances.push_back(directional_lights[i]);
+ }
- RSG::storage->update_mesh_instances();
+ RID camera_effects;
+ if (p_force_camera_effects.is_valid()) {
+ camera_effects = p_force_camera_effects;
+ } else {
+ camera_effects = scenario->camera_effects;
+ }
+ /* PROCESS GEOMETRY AND DRAW SCENE */
- scene_render->render_sdfgi(p_render_buffers, i, geometry_instances_to_sdfgi_render);
- //have to save updated cascades, then update static lights.
- }
+ RENDER_TIMESTAMP("Render Scene ");
+ scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.gi_probes, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data);
- if (sdfgi_light_cull_count) {
- scene_render->render_sdfgi_static_lights(p_render_buffers, cascade_count, cascade_index, sdfgi_cascade_lights);
- }
+ for (uint32_t i = 0; i < max_shadows_used; i++) {
+ render_shadow_data[i].instances.clear();
+ }
+ max_shadows_used = 0;
- scene_render->sdfgi_update_probes(p_render_buffers, p_environment, directional_light_cull_result, scenario->dynamic_lights.ptr(), scenario->dynamic_lights.size());
+ for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) {
+ render_sdfgi_data[i].instances.clear();
}
+
+ // virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0;
}
RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) {
@@ -2517,21 +2817,6 @@ RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) {
return RID();
}
-void RendererSceneCull::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
- Scenario *scenario = scenario_owner.getornull(p_scenario);
-
- RID camera_effects;
- if (p_force_camera_effects.is_valid()) {
- camera_effects = p_force_camera_effects;
- } else {
- camera_effects = scenario->camera_effects;
- }
- /* PROCESS GEOMETRY AND DRAW SCENE */
-
- RENDER_TIMESTAMP("Render Scene ");
- scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, geometry_instances_to_render, light_instance_cull_result, reflection_probe_instance_cull_result, gi_probe_instance_cull_result, decal_instance_cull_result, lightmap_cull_result, p_environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold);
-}
-
void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
#ifndef _3D_DISABLED
@@ -2544,7 +2829,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario,
environment = scenario->fallback_environment;
}
RENDER_TIMESTAMP("Render Empty Scene ");
- scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::InstanceBase *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RendererSceneRender::InstanceBase *>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0);
+ scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
#endif
}
@@ -2607,8 +2892,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
}
RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step));
- _prepare_scene(xform, cm, false, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, lod_threshold, use_shadows);
- _render_scene(RID(), xform, cm, false, RID(), RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step, lod_threshold);
+ _render_scene(xform, cm, false, false, RID(), RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step, lod_threshold, use_shadows);
} else {
//do roughness postprocess step until it believes it's done
@@ -2819,7 +3103,9 @@ void RendererSceneCull::render_probes() {
update_lights = true;
}
- geometry_instances_to_render.clear();
+ frustum_cull_result.geometry_instances.clear();
+
+ RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
for (Set<Instance *>::Element *E = probe->dynamic_geometries.front(); E; E = E->next()) {
Instance *ins = E->get();
@@ -2828,25 +3114,26 @@ void RendererSceneCull::render_probes() {
}
InstanceGeometryData *geom = (InstanceGeometryData *)ins->base_data;
- if (geom->gi_probes_dirty) {
- //giprobes may be dirty, so update
- int l = 0;
- //only called when reflection probe AABB enter/exit this geometry
- ins->gi_probe_instances.resize(geom->gi_probes.size());
-
+ if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY)) {
+ uint32_t idx = 0;
for (Set<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) {
InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data);
- ins->gi_probe_instances.write[l++] = gi_probe2->probe_instance;
+ instance_pair_buffer[idx++] = gi_probe2->probe_instance;
+ if (idx == MAX_INSTANCE_PAIRS) {
+ break;
+ }
}
- geom->gi_probes_dirty = false;
+ scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
+
+ ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY);
}
- geometry_instances_to_render.push_back(E->get());
+ frustum_cull_result.geometry_instances.push_back(geom->geometry_instance);
}
- scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, geometry_instances_to_render);
+ scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, frustum_cull_result.geometry_instances);
gi_probe_update_list.remove(gi_probe);
@@ -2861,7 +3148,7 @@ void RendererSceneCull::render_particle_colliders() {
if (hfpc->scenario && hfpc->base_type == RS::INSTANCE_PARTICLES_COLLISION && RSG::storage->particles_collision_is_heightfield(hfpc->base)) {
//update heightfield
instance_cull_result.clear();
- geometry_instances_to_render.clear();
+ frustum_cull_result.geometry_instances.clear();
struct CullAABB {
PagedArray<Instance *> *result;
@@ -2882,16 +3169,17 @@ void RendererSceneCull::render_particle_colliders() {
if (!instance || !((1 << instance->base_type) & (RS::INSTANCE_GEOMETRY_MASK & (~(1 << RS::INSTANCE_PARTICLES))))) { //all but particles to avoid self collision
continue;
}
- geometry_instances_to_render.push_back(instance);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+ frustum_cull_result.geometry_instances.push_back(geom->geometry_instance);
}
- scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, geometry_instances_to_render);
+ scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, frustum_cull_result.geometry_instances);
}
heightfield_particle_colliders_update_list.erase(heightfield_particle_colliders_update_list.front());
}
}
-void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) {
+void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) {
List<RendererStorage::InstanceShaderParam> plist;
RSG::storage->material_get_instance_shader_parameters(p_material, &plist);
for (List<RendererStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) {
@@ -2906,7 +3194,7 @@ void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<Str
continue; //first one found always has priority
}
- RendererSceneRender::InstanceBase::InstanceShaderParameter isp;
+ Instance::InstanceShaderParameter isp;
isp.index = E->get().index;
isp.info = E->get().info;
isp.default_value = E->get().default_value;
@@ -2925,14 +3213,14 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
}
if (p_instance->update_dependencies) {
- p_instance->instance_increase_version();
+ p_instance->dependency_tracker.update_begin();
if (p_instance->base.is_valid()) {
- RSG::storage->base_update_dependency(p_instance->base, p_instance);
+ RSG::storage->base_update_dependency(p_instance->base, &p_instance->dependency_tracker);
}
if (p_instance->material_override.is_valid()) {
- RSG::storage->material_update_dependency(p_instance->material_override, p_instance);
+ RSG::storage->material_update_dependency(p_instance->material_override, &p_instance->dependency_tracker);
}
if (p_instance->base_type == RS::INSTANCE_MESH) {
@@ -2949,7 +3237,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
bool can_cast_shadows = true;
bool is_animated = false;
- Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> isparams;
+ Map<StringName, Instance::InstanceShaderParameter> isparams;
if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
can_cast_shadows = false;
@@ -2984,7 +3272,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
- RSG::storage->material_update_dependency(mat, p_instance);
+ RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
}
}
@@ -3015,7 +3303,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
- RSG::storage->material_update_dependency(mat, p_instance);
+ RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
}
}
@@ -3023,7 +3311,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
can_cast_shadows = false;
}
- RSG::storage->base_update_dependency(mesh, p_instance);
+ RSG::storage->base_update_dependency(mesh, &p_instance->dependency_tracker);
}
} else if (p_instance->base_type == RS::INSTANCE_IMMEDIATE) {
RID mat = RSG::storage->immediate_get_material(p_instance->base);
@@ -3041,7 +3329,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
}
if (mat.is_valid()) {
- RSG::storage->material_update_dependency(mat, p_instance);
+ RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
}
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
@@ -3072,7 +3360,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat);
- RSG::storage->material_update_dependency(mat, p_instance);
+ RSG::storage->material_update_dependency(mat, &p_instance->dependency_tracker);
}
}
}
@@ -3100,7 +3388,9 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0);
if (p_instance->instance_allocated_shader_parameters) {
p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self);
- for (Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) {
+ scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, p_instance->instance_allocated_shader_parameters_offset);
+
+ for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) {
if (E->get().value.get_type() != Variant::NIL) {
RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value);
}
@@ -3108,15 +3398,21 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
} else {
RSG::storage->global_variables_instance_free(p_instance->self);
p_instance->instance_allocated_shader_parameters_offset = -1;
+ scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, -1);
}
}
}
if (p_instance->skeleton.is_valid()) {
- RSG::storage->skeleton_update_dependency(p_instance->skeleton, p_instance);
+ RSG::storage->skeleton_update_dependency(p_instance->skeleton, &p_instance->dependency_tracker);
}
- p_instance->clean_up_dependencies();
+ p_instance->dependency_tracker.update_end();
+
+ if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+ scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, p_instance->materials);
+ }
}
_instance_update_list.remove(&p_instance->update_item);
@@ -3164,6 +3460,9 @@ bool RendererSceneCull::free(RID p_rid) {
while (scenario->instances.first()) {
instance_set_scenario(scenario->instances.first()->self()->self, RID());
}
+ scenario->instance_aabbs.reset();
+ scenario->instance_data.reset();
+
scene_render->free(scenario->reflection_probe_shadow_atlas);
scene_render->free(scenario->reflection_atlas);
scenario_owner.free(p_rid);
@@ -3209,54 +3508,50 @@ TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const Vector<RI
RendererSceneCull *RendererSceneCull::singleton = nullptr;
+void RendererSceneCull::set_scene_render(RendererSceneRender *p_scene_render) {
+ scene_render = p_scene_render;
+ geometry_instance_pair_mask = scene_render->geometry_instance_get_pair_mask();
+}
+
RendererSceneCull::RendererSceneCull() {
render_pass = 1;
singleton = this;
- pair_volumes_to_mesh = false;
instance_cull_result.set_page_pool(&instance_cull_page_pool);
instance_shadow_cull_result.set_page_pool(&instance_cull_page_pool);
- instance_sdfgi_cull_result.set_page_pool(&instance_cull_page_pool);
- light_cull_result.set_page_pool(&instance_cull_page_pool);
- directional_shadow_cull_result.set_page_pool(&instance_cull_page_pool);
- geometry_instances_to_render.set_page_pool(&base_instance_cull_page_pool);
- geometry_instances_to_shadow_render.set_page_pool(&base_instance_cull_page_pool);
- geometry_instances_to_sdfgi_render.set_page_pool(&base_instance_cull_page_pool);
- lightmap_cull_result.set_page_pool(&base_instance_cull_page_pool);
-
- reflection_probe_instance_cull_result.set_page_pool(&rid_cull_page_pool);
- light_instance_cull_result.set_page_pool(&rid_cull_page_pool);
- directional_light_cull_result.set_page_pool(&rid_cull_page_pool);
- gi_probe_instance_cull_result.set_page_pool(&rid_cull_page_pool);
- decal_instance_cull_result.set_page_pool(&rid_cull_page_pool);
+ for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) {
+ render_shadow_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool);
+ }
+ for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ render_sdfgi_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool);
+ }
- for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
- sdfgi_cascade_lights[i].set_page_pool(&rid_cull_page_pool);
+ frustum_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
+ frustum_cull_result_threads.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count());
+ for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) {
+ frustum_cull_result_threads[i].init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);
}
- indexer_update_iterations = GLOBAL_GET("rendering/spatial_indexer/update_iterations_per_frame");
+ indexer_update_iterations = GLOBAL_GET("rendering/limits/spatial_indexer/update_iterations_per_frame");
+ thread_cull_threshold = GLOBAL_GET("rendering/limits/spatial_indexer/threaded_cull_minimum_instances");
+ thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)RendererThreadPool::singleton->thread_work_pool.get_thread_count()); //make sure there is at least one thread per CPU
}
RendererSceneCull::~RendererSceneCull() {
instance_cull_result.reset();
instance_shadow_cull_result.reset();
- instance_sdfgi_cull_result.reset();
- light_cull_result.reset();
- directional_shadow_cull_result.reset();
-
- geometry_instances_to_render.reset();
- geometry_instances_to_shadow_render.reset();
- geometry_instances_to_sdfgi_render.reset();
- lightmap_cull_result.reset();
- reflection_probe_instance_cull_result.reset();
- light_instance_cull_result.reset();
- directional_light_cull_result.reset();
- gi_probe_instance_cull_result.reset();
- decal_instance_cull_result.reset();
+ for (uint32_t i = 0; i < MAX_UPDATE_SHADOWS; i++) {
+ render_shadow_data[i].instances.reset();
+ }
+ for (uint32_t i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ render_sdfgi_data[i].instances.reset();
+ }
- for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
- sdfgi_cascade_lights[i].reset();
+ frustum_cull_result.reset();
+ for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) {
+ frustum_cull_result_threads[i].reset();
}
+ frustum_cull_result_threads.clear();
}
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index 8bf262d7c0..32f4334288 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -52,7 +52,10 @@ public:
RendererSceneRender *scene_render;
enum {
- SDFGI_MAX_CASCADES = 8
+ SDFGI_MAX_CASCADES = 8,
+ SDFGI_MAX_REGIONS_PER_CASCADE = 3,
+ MAX_INSTANCE_PAIRS = 32,
+ MAX_UPDATE_SHADOWS = 512
};
uint64_t render_pass;
@@ -91,9 +94,11 @@ public:
}
};
- mutable RID_PtrOwner<Camera> camera_owner;
+ mutable RID_PtrOwner<Camera, true> camera_owner;
+
+ virtual RID camera_allocate();
+ virtual void camera_initialize(RID p_rid);
- virtual RID camera_create();
virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far);
virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far);
@@ -108,6 +113,156 @@ public:
struct Instance;
+ struct PlaneSign {
+ _ALWAYS_INLINE_ PlaneSign() {}
+ _ALWAYS_INLINE_ PlaneSign(const Plane &p_plane) {
+ if (p_plane.normal.x > 0) {
+ signs[0] = 0;
+ } else {
+ signs[0] = 3;
+ }
+ if (p_plane.normal.y > 0) {
+ signs[1] = 1;
+ } else {
+ signs[1] = 4;
+ }
+ if (p_plane.normal.z > 0) {
+ signs[2] = 2;
+ } else {
+ signs[2] = 5;
+ }
+ }
+
+ uint32_t signs[3];
+ };
+
+ struct Frustum {
+ Vector<Plane> planes;
+ Vector<PlaneSign> plane_signs;
+ const Plane *planes_ptr;
+ const PlaneSign *plane_signs_ptr;
+ uint32_t plane_count;
+
+ _ALWAYS_INLINE_ Frustum() {}
+ _ALWAYS_INLINE_ Frustum(const Frustum &p_frustum) {
+ planes = p_frustum.planes;
+ plane_signs = p_frustum.plane_signs;
+
+ planes_ptr = planes.ptr();
+ plane_signs_ptr = plane_signs.ptr();
+ plane_count = p_frustum.plane_count;
+ }
+ _ALWAYS_INLINE_ void operator=(const Frustum &p_frustum) {
+ planes = p_frustum.planes;
+ plane_signs = p_frustum.plane_signs;
+
+ planes_ptr = planes.ptr();
+ plane_signs_ptr = plane_signs.ptr();
+ plane_count = p_frustum.plane_count;
+ }
+ _ALWAYS_INLINE_ Frustum(const Vector<Plane> &p_planes) {
+ planes = p_planes;
+ planes_ptr = planes.ptrw();
+ plane_count = planes.size();
+ for (int i = 0; i < planes.size(); i++) {
+ PlaneSign ps(p_planes[i]);
+ plane_signs.push_back(ps);
+ }
+
+ plane_signs_ptr = plane_signs.ptr();
+ }
+ };
+
+ struct InstanceBounds {
+ // Efficiently store instance bounds.
+ // Because bounds checking is performed first,
+ // keep it separated from data.
+
+ real_t bounds[6];
+ _ALWAYS_INLINE_ InstanceBounds() {}
+
+ _ALWAYS_INLINE_ InstanceBounds(const AABB &p_aabb) {
+ bounds[0] = p_aabb.position.x;
+ bounds[1] = p_aabb.position.y;
+ bounds[2] = p_aabb.position.z;
+ bounds[3] = p_aabb.position.x + p_aabb.size.x;
+ bounds[4] = p_aabb.position.y + p_aabb.size.y;
+ bounds[5] = p_aabb.position.z + p_aabb.size.z;
+ }
+ _ALWAYS_INLINE_ bool in_frustum(const Frustum &p_frustum) const {
+ // This is not a full SAT check and the possibility of false positives exist,
+ // but the tradeoff vs performance is still very good.
+
+ for (uint32_t i = 0; i < p_frustum.plane_count; i++) {
+ Vector3 min(
+ bounds[p_frustum.plane_signs_ptr[i].signs[0]],
+ bounds[p_frustum.plane_signs_ptr[i].signs[1]],
+ bounds[p_frustum.plane_signs_ptr[i].signs[2]]);
+
+ if (p_frustum.planes_ptr[i].distance_to(min) >= 0.0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ _ALWAYS_INLINE_ bool in_aabb(const AABB &p_aabb) const {
+ Vector3 end = p_aabb.position + p_aabb.size;
+
+ if (bounds[0] >= end.x) {
+ return false;
+ }
+ if (bounds[3] <= p_aabb.position.x) {
+ return false;
+ }
+ if (bounds[1] >= end.y) {
+ return false;
+ }
+ if (bounds[4] <= p_aabb.position.y) {
+ return false;
+ }
+ if (bounds[2] >= end.z) {
+ return false;
+ }
+ if (bounds[5] <= p_aabb.position.z) {
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+ struct InstanceData {
+ // Store instance pointer as well as common instance processing information,
+ // to make processing more cache friendly.
+ enum Flags {
+ FLAG_BASE_TYPE_MASK = 0xFF,
+ FLAG_CAST_SHADOWS = (1 << 8),
+ FLAG_CAST_SHADOWS_ONLY = (1 << 9),
+ FLAG_REDRAW_IF_VISIBLE = (1 << 10),
+ FLAG_GEOM_LIGHTING_DIRTY = (1 << 11),
+ FLAG_GEOM_REFLECTION_DIRTY = (1 << 12),
+ FLAG_GEOM_DECAL_DIRTY = (1 << 13),
+ FLAG_GEOM_GI_PROBE_DIRTY = (1 << 14),
+ FLAG_LIGHTMAP_CAPTURE = (1 << 15),
+ FLAG_USES_BAKED_LIGHT = (1 << 16),
+ FLAG_USES_MESH_INSTANCE = (1 << 17),
+ FLAG_REFLECTION_PROBE_DIRTY = (1 << 18),
+ };
+
+ uint32_t flags = 0;
+ uint32_t layer_mask = 0; //for fast layer-mask discard
+ RID base_rid;
+ union {
+ uint64_t instance_data_rid;
+ RendererSceneRender::GeometryInstance *instance_geometry;
+ };
+ Instance *instance = nullptr;
+ };
+
+ PagedArrayPool<InstanceBounds> instance_aabb_page_pool;
+ PagedArrayPool<InstanceData> instance_data_page_pool;
+
struct Scenario {
enum IndexerType {
INDEXER_GEOMETRY, //for geometry
@@ -131,6 +286,9 @@ public:
LocalVector<RID> dynamic_lights;
+ PagedArray<InstanceBounds> instance_aabbs;
+ PagedArray<InstanceData> instance_data;
+
Scenario() {
indexers[INDEXER_GEOMETRY].set_index(INDEXER_GEOMETRY);
indexers[INDEXER_VOLUMES].set_index(INDEXER_VOLUMES);
@@ -140,14 +298,15 @@ public:
int indexer_update_iterations = 0;
- mutable RID_PtrOwner<Scenario> scenario_owner;
+ mutable RID_PtrOwner<Scenario, true> scenario_owner;
static void _instance_pair(Instance *p_A, Instance *p_B);
static void _instance_unpair(Instance *p_A, Instance *p_B);
- static void _instance_update_mesh_instance(Instance *p_instance);
+ void _instance_update_mesh_instance(Instance *p_instance);
- virtual RID scenario_create();
+ virtual RID scenario_allocate();
+ virtual void scenario_initialize(RID p_rid);
virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode);
virtual void scenario_set_environment(RID p_scenario, RID p_environment);
@@ -174,10 +333,59 @@ public:
virtual ~InstanceBaseData() {}
};
- struct Instance : RendererSceneRender::InstanceBase {
+ struct Instance {
+ RS::InstanceType base_type;
+ RID base;
+
+ RID skeleton;
+ RID material_override;
+
+ RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist
+
+ Transform transform;
+
+ float lod_bias;
+
+ Vector<RID> materials;
+
+ RS::ShadowCastingSetting cast_shadows;
+
+ uint32_t layer_mask;
+ //fit in 32 bits
+ bool mirror : 8;
+ bool receive_shadows : 8;
+ bool visible : 8;
+ bool baked_light : 2; //this flag is only to know if it actually did use baked light
+ bool dynamic_gi : 2; //same above for dynamic objects
+ bool redraw_if_visible : 4;
+
+ Instance *lightmap;
+ Rect2 lightmap_uv_scale;
+ int lightmap_slice_index;
+ uint32_t lightmap_cull_index;
+ Vector<Color> lightmap_sh; //spherical harmonic
+
+ AABB aabb;
+ AABB transformed_aabb;
+ AABB prev_transformed_aabb;
+
+ struct InstanceShaderParameter {
+ int32_t index = -1;
+ Variant value;
+ Variant default_value;
+ PropertyInfo info;
+ };
+
+ Map<StringName, InstanceShaderParameter> instance_shader_parameters;
+ bool instance_allocated_shader_parameters = false;
+ int32_t instance_allocated_shader_parameters_offset = -1;
+
+ //
+
RID self;
//scenario stuff
DynamicBVH::ID indexer_id;
+ int32_t array_index;
Scenario *scenario;
SelfList<Instance> scenario_item;
@@ -199,7 +407,6 @@ public:
Vector<Color> lightmap_target_sh; //target is used for incrementally changing the SH over time, this avoids pops in some corner cases and when going interior <-> exterior
- uint64_t last_render_pass;
uint64_t last_frame_pass;
uint64_t version; // changes to this, and changes to base increase version
@@ -209,23 +416,61 @@ public:
SelfList<InstancePair>::List pairs;
uint64_t pair_check;
- virtual void dependency_deleted(RID p_dependency) {
- if (p_dependency == base) {
- singleton->instance_set_base(self, RID());
- } else if (p_dependency == skeleton) {
- singleton->instance_attach_skeleton(self, RID());
- } else {
- singleton->_instance_queue_update(this, false, true);
+ RendererStorage::DependencyTracker dependency_tracker;
+
+ static void dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *tracker) {
+ Instance *instance = (Instance *)tracker->userdata;
+ switch (p_notification) {
+ case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA:
+ case RendererStorage::DEPENDENCY_CHANGED_AABB: {
+ singleton->_instance_queue_update(instance, true, false);
+
+ } break;
+ case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: {
+ singleton->_instance_queue_update(instance, false, true);
+ } break;
+ case RendererStorage::DEPENDENCY_CHANGED_MESH:
+ case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
+ case RendererStorage::DEPENDENCY_CHANGED_DECAL:
+ case RendererStorage::DEPENDENCY_CHANGED_LIGHT:
+ case RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
+ singleton->_instance_queue_update(instance, true, true);
+ } break;
+ case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
+ case RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES: {
+ //ignored
+ } break;
}
}
- virtual void dependency_changed(bool p_aabb, bool p_dependencies) {
- singleton->_instance_queue_update(this, p_aabb, p_dependencies);
+ static void dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *tracker) {
+ Instance *instance = (Instance *)tracker->userdata;
+
+ if (p_dependency == instance->base) {
+ singleton->instance_set_base(instance->self, RID());
+ } else if (p_dependency == instance->skeleton) {
+ singleton->instance_attach_skeleton(instance->self, RID());
+ } else {
+ singleton->_instance_queue_update(instance, false, true);
+ }
}
Instance() :
scenario_item(this),
update_item(this) {
+ base_type = RS::INSTANCE_NONE;
+ cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
+ receive_shadows = true;
+ visible = true;
+ layer_mask = 1;
+ baked_light = false;
+ dynamic_gi = false;
+ redraw_if_visible = false;
+ lightmap_slice_index = 0;
+ lightmap = nullptr;
+ lightmap_cull_index = 0;
+ lod_bias = 1.0;
+
scenario = nullptr;
update_aabb = false;
@@ -240,7 +485,6 @@ public:
lod_begin_hysteresis = 0;
lod_end_hysteresis = 0;
- last_render_pass = 0;
last_frame_pass = 0;
version = 1;
base_data = nullptr;
@@ -248,6 +492,11 @@ public:
custom_aabb = nullptr;
pair_check = 0;
+ array_index = -1;
+
+ dependency_tracker.userdata = this;
+ dependency_tracker.changed_callback = dependency_changed;
+ dependency_tracker.deleted_callback = dependency_deleted;
}
~Instance() {
@@ -264,29 +513,19 @@ public:
void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false);
struct InstanceGeometryData : public InstanceBaseData {
+ RendererSceneRender::GeometryInstance *geometry_instance = nullptr;
Set<Instance *> lights;
- bool lighting_dirty;
bool can_cast_shadows;
bool material_is_animated;
Set<Instance *> decals;
- bool decal_dirty;
-
Set<Instance *> reflection_probes;
- bool reflection_dirty;
-
Set<Instance *> gi_probes;
- bool gi_probes_dirty;
-
Set<Instance *> lightmap_captures;
InstanceGeometryData() {
- lighting_dirty = false;
- reflection_dirty = true;
can_cast_shadows = true;
material_is_animated = true;
- gi_probes_dirty = true;
- decal_dirty = true;
}
};
@@ -296,14 +535,12 @@ public:
Set<Instance *> geometries;
RID instance;
- bool reflection_dirty;
SelfList<InstanceReflectionProbeData> update_list;
int render_step;
InstanceReflectionProbeData() :
update_list(this) {
- reflection_dirty = true;
render_step = -1;
}
};
@@ -320,6 +557,10 @@ public:
SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
+ struct InstanceParticlesCollisionData : public InstanceBaseData {
+ RID instance;
+ };
+
struct InstanceLightData : public InstanceBaseData {
RID instance;
uint64_t last_version;
@@ -334,8 +575,6 @@ public:
RS::LightBakeMode bake_mode;
uint32_t max_sdfgi_cascade = 2;
- uint64_t sdfgi_cascade_light_pass = 0;
-
InstanceLightData() {
bake_mode = RS::LIGHT_BAKE_DISABLED;
shadow_dirty = true;
@@ -387,6 +626,7 @@ public:
SelfList<InstanceGIProbeData>::List gi_probe_update_list;
struct InstanceLightmapData : public InstanceBaseData {
+ RID instance;
Set<Instance *> geometries;
Set<Instance *> users;
@@ -452,46 +692,147 @@ public:
}
};
- struct CullResult {
- PagedArray<Instance *> *result;
- _FORCE_INLINE_ bool operator()(void *p_data) {
- Instance *p_instance = (Instance *)p_data;
- result->push_back(p_instance);
- return false;
- }
- };
-
Set<Instance *> heightfield_particle_colliders_update_list;
PagedArrayPool<Instance *> instance_cull_page_pool;
- PagedArrayPool<RendererSceneRender::InstanceBase *> base_instance_cull_page_pool;
+ PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool;
PagedArrayPool<RID> rid_cull_page_pool;
PagedArray<Instance *> instance_cull_result;
- PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_render;
PagedArray<Instance *> instance_shadow_cull_result;
- PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_shadow_render;
- PagedArray<Instance *> instance_sdfgi_cull_result;
- PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_sdfgi_render;
- PagedArray<Instance *> light_cull_result;
- PagedArray<RendererSceneRender::InstanceBase *> lightmap_cull_result;
- PagedArray<Instance *> directional_shadow_cull_result;
- PagedArray<RID> reflection_probe_instance_cull_result;
- PagedArray<RID> light_instance_cull_result;
- PagedArray<RID> directional_light_cull_result;
- PagedArray<RID> gi_probe_instance_cull_result;
- PagedArray<RID> decal_instance_cull_result;
- PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES];
+ struct FrustumCullResult {
+ PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances;
+ PagedArray<Instance *> lights;
+ PagedArray<RID> light_instances;
+ PagedArray<RID> lightmaps;
+ PagedArray<RID> reflections;
+ PagedArray<RID> decals;
+ PagedArray<RID> gi_probes;
+ PagedArray<RID> mesh_instances;
+
+ struct DirectionalShadow {
+ PagedArray<RendererSceneRender::GeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES];
+ } directional_shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS];
+
+ PagedArray<RendererSceneRender::GeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE];
+ PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES];
+
+ void clear() {
+ geometry_instances.clear();
+ lights.clear();
+ light_instances.clear();
+ lightmaps.clear();
+ reflections.clear();
+ decals.clear();
+ gi_probes.clear();
+ mesh_instances.clear();
+ for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
+ for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
+ directional_shadows[i].cascade_geometry_instances[j].clear();
+ }
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ sdfgi_region_geometry_instances[i].clear();
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
+ sdfgi_cascade_lights[i].clear();
+ }
+ }
+
+ void reset() {
+ geometry_instances.reset();
+ lights.reset();
+ light_instances.reset();
+ lightmaps.reset();
+ reflections.reset();
+ decals.reset();
+ gi_probes.reset();
+ mesh_instances.reset();
+ for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
+ for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
+ directional_shadows[i].cascade_geometry_instances[j].reset();
+ }
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ sdfgi_region_geometry_instances[i].reset();
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
+ sdfgi_cascade_lights[i].reset();
+ }
+ }
+
+ void append_from(FrustumCullResult &p_cull_result) {
+ geometry_instances.merge_unordered(p_cull_result.geometry_instances);
+ lights.merge_unordered(p_cull_result.lights);
+ light_instances.merge_unordered(p_cull_result.light_instances);
+ lightmaps.merge_unordered(p_cull_result.lightmaps);
+ reflections.merge_unordered(p_cull_result.reflections);
+ decals.merge_unordered(p_cull_result.decals);
+ gi_probes.merge_unordered(p_cull_result.gi_probes);
+ mesh_instances.merge_unordered(p_cull_result.mesh_instances);
+
+ for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
+ for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
+ directional_shadows[i].cascade_geometry_instances[j].merge_unordered(p_cull_result.directional_shadows[i].cascade_geometry_instances[j]);
+ }
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ sdfgi_region_geometry_instances[i].merge_unordered(p_cull_result.sdfgi_region_geometry_instances[i]);
+ }
+
+ for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
+ sdfgi_cascade_lights[i].merge_unordered(p_cull_result.sdfgi_cascade_lights[i]);
+ }
+ }
- uint64_t sdfgi_light_cull_pass = 0;
- int directional_light_count;
+ void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RendererSceneRender::GeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) {
+ geometry_instances.set_page_pool(p_geometry_instance_pool);
+ light_instances.set_page_pool(p_rid_pool);
+ lights.set_page_pool(p_instance_pool);
+ lightmaps.set_page_pool(p_rid_pool);
+ reflections.set_page_pool(p_rid_pool);
+ decals.set_page_pool(p_rid_pool);
+ gi_probes.set_page_pool(p_rid_pool);
+ mesh_instances.set_page_pool(p_rid_pool);
+ for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
+ for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
+ directional_shadows[i].cascade_geometry_instances[j].set_page_pool(p_geometry_instance_pool);
+ }
+ }
- RID_PtrOwner<Instance> instance_owner;
+ for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
+ sdfgi_region_geometry_instances[i].set_page_pool(p_geometry_instance_pool);
+ }
- bool pair_volumes_to_mesh; // used in traditional forward, unnecesary on clustered
+ for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
+ sdfgi_cascade_lights[i].set_page_pool(p_rid_pool);
+ }
+ }
+ };
- virtual RID instance_create();
+ FrustumCullResult frustum_cull_result;
+ LocalVector<FrustumCullResult> frustum_cull_result_threads;
+
+ RendererSceneRender::RenderShadowData render_shadow_data[MAX_UPDATE_SHADOWS];
+ uint32_t max_shadows_used = 0;
+
+ RendererSceneRender::RenderSDFGIData render_sdfgi_data[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE];
+ RendererSceneRender::RenderSDFGIUpdateData sdfgi_update_data;
+
+ uint32_t thread_cull_threshold = 200;
+
+ RID_PtrOwner<Instance, true> instance_owner;
+
+ uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecesary on clustered
+
+ virtual RID instance_allocate();
+ virtual void instance_initialize(RID p_rid);
virtual void instance_set_base(RID p_instance, RID p_base);
virtual void instance_set_scenario(RID p_instance, RID p_scenario);
@@ -523,7 +864,7 @@ public:
virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias);
- void _update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material);
+ void _update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material);
virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value);
virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const;
@@ -536,13 +877,64 @@ public:
_FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance);
void _unpair_instance(Instance *p_instance);
+ void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect);
+
_FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_lod_threshold);
RID _render_get_environment(RID p_camera, RID p_scenario);
+ struct Cull {
+ struct Shadow {
+ RID light_instance;
+ struct Cascade {
+ Frustum frustum;
+
+ CameraMatrix projection;
+ Transform transform;
+ real_t zfar;
+ real_t split;
+ real_t shadow_texel_size;
+ real_t bias_scale;
+ real_t range_begin;
+ Vector2 uv_scale;
+
+ } cascades[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; //max 4 cascades
+ uint32_t cascade_count;
+
+ } shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS];
+
+ uint32_t shadow_count;
+
+ struct SDFGI {
+ //have arrays here because SDFGI functions expects this, plus regions can have areas
+ AABB region_aabb[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade
+ uint32_t region_cascade[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade
+ uint32_t region_count = 0;
+
+ uint32_t cascade_light_index[SDFGI_MAX_CASCADES];
+ uint32_t cascade_light_count = 0;
+
+ } sdfgi;
+
+ SpinLock lock;
+
+ Frustum frustum;
+ } cull;
+
+ struct FrustumCullData {
+ Cull *cull;
+ Scenario *scenario;
+ RID shadow_atlas;
+ Transform cam_transform;
+ uint32_t visible_layers;
+ Instance *render_reflection_probe;
+ };
+
+ void _frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data);
+ void _frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to);
+
bool _render_reflection_probe_step(Instance *p_instance, int p_step);
- void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows = true);
- void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
+ void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true);
void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas);
void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas);
@@ -564,18 +956,21 @@ public:
#define PASSBASE scene_render
- PASS1(directional_shadow_atlas_set_size, int)
+ PASS2(directional_shadow_atlas_set_size, int, bool)
PASS1(gi_probe_set_quality, RS::GIProbeQuality)
/* SKY API */
- PASS0R(RID, sky_create)
+ PASS0R(RID, sky_allocate)
+ PASS1(sky_initialize, RID)
+
PASS2(sky_set_radiance_size, RID, int)
PASS2(sky_set_mode, RID, RS::SkyMode)
PASS2(sky_set_material, RID, RID)
PASS4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
- PASS0R(RID, environment_create)
+ PASS0R(RID, environment_allocate)
+ PASS1(environment_initialize, RID)
PASS1RC(bool, is_environment, RID)
@@ -603,16 +998,15 @@ public:
PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
- PASS9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter)
+ PASS10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float)
PASS2(environment_set_volumetric_fog_volume_size, int, int)
PASS1(environment_set_volumetric_fog_filter_active, bool)
- PASS1(environment_set_volumetric_fog_directional_shadow_shrink_size, int)
- PASS1(environment_set_volumetric_fog_positional_shadow_shrink_size, int)
- PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
+ PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, float, bool, float, float, float)
PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount)
PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge)
+ PASS1(environment_set_sdfgi_frames_to_update_light, RS::EnvironmentSDFGIFramesToUpdateLight)
PASS1RC(RS::EnvironmentBG, environment_get_background, RID)
PASS1RC(int, environment_get_canvas_max_layer, RID)
@@ -625,7 +1019,8 @@ public:
/* CAMERA EFFECTS */
- PASS0R(RID, camera_effects_create)
+ PASS0R(RID, camera_effects_allocate)
+ PASS1(camera_effects_initialize, RID)
PASS2(camera_effects_set_dof_blur_quality, RS::DOFBlurQuality, bool)
PASS1(camera_effects_set_dof_blur_bokeh_shape, RS::DOFBokehShape)
@@ -642,10 +1037,11 @@ public:
PASS0R(RID, render_buffers_create)
PASS7(render_buffers_configure, RID, RID, int, int, RS::ViewportMSAA, RS::ViewportScreenSpaceAA, bool)
+ PASS1(gi_set_use_half_resolution, bool)
/* Shadow Atlas */
PASS0R(RID, shadow_atlas_create)
- PASS2(shadow_atlas_set_size, RID, int)
+ PASS3(shadow_atlas_set_size, RID, int, bool)
PASS3(shadow_atlas_set_quadrant_subdivision, RID, int, int)
PASS1(set_debug_draw_mode, RS::ViewportDebugDraw)
@@ -654,6 +1050,8 @@ public:
bool free(RID p_rid);
+ void set_scene_render(RendererSceneRender *p_scene_render);
+
RendererSceneCull();
virtual ~RendererSceneCull();
};
diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp
index 2c36c5c59d..f27bdc6798 100644
--- a/servers/rendering/renderer_scene_render.cpp
+++ b/servers/rendering/renderer_scene_render.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index 19ab7a392b..1dea3580b6 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,30 +37,61 @@
class RendererSceneRender {
public:
+ enum {
+ MAX_DIRECTIONAL_LIGHTS = 8,
+ MAX_DIRECTIONAL_LIGHT_CASCADES = 4
+ };
+
+ struct GeometryInstance {
+ virtual ~GeometryInstance() {}
+ };
+
+ virtual GeometryInstance *geometry_instance_create(RID p_base) = 0;
+ virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) = 0;
+ virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0;
+ virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0;
+ virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0;
+ virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0;
+ virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0;
+ virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0;
+ virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
+ virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
+ virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0;
+ virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) = 0;
+ virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) = 0;
+ virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
+
+ virtual uint32_t geometry_instance_get_pair_mask() = 0;
+ virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) = 0;
+ virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0;
+ virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0;
+ virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) = 0;
+
+ virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0;
+
/* SHADOW ATLAS API */
virtual RID shadow_atlas_create() = 0;
- virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
+ virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) = 0;
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
- virtual void directional_shadow_atlas_set_size(int p_size) = 0;
+ virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
virtual void set_directional_shadow_count(int p_count) = 0;
/* SDFGI UPDATE */
- struct InstanceBase;
-
virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0;
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0;
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0;
virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const = 0;
- virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const PagedArray<RID> &p_directionals, const RID *p_positional_light_instances, uint32_t p_positional_light_count) = 0;
/* SKY API */
- virtual RID sky_create() = 0;
+ virtual RID sky_allocate() = 0;
+ virtual void sky_initialize(RID p_rid) = 0;
+
virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0;
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
@@ -68,7 +99,8 @@ public:
/* ENVIRONMENT API */
- virtual RID environment_create() = 0;
+ virtual RID environment_allocate() = 0;
+ virtual void environment_initialize(RID p_rid) = 0;
virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) = 0;
virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
@@ -87,12 +119,9 @@ public:
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
- virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
-
+ virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
- virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
- virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0;
virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
@@ -101,10 +130,11 @@ public:
virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0;
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
+ virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0;
virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
@@ -118,7 +148,8 @@ public:
virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0;
virtual int environment_get_canvas_max_layer(RID p_env) const = 0;
- virtual RID camera_effects_create() = 0;
+ virtual RID camera_effects_allocate() = 0;
+ virtual void camera_effects_initialize(RID p_rid) = 0;
virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) = 0;
virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) = 0;
@@ -129,83 +160,6 @@ public:
virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
- struct InstanceBase : public RendererStorage::InstanceBaseDependency {
- RS::InstanceType base_type;
- RID base;
-
- RID skeleton;
- RID material_override;
-
- RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist
-
- Transform transform;
-
- float lod_bias;
-
- int depth_layer;
- uint32_t layer_mask;
-
- //RID sampled_light;
-
- Vector<RID> materials;
- Vector<RID> light_instances;
- Vector<RID> reflection_probe_instances;
- Vector<RID> gi_probe_instances;
-
- RS::ShadowCastingSetting cast_shadows;
-
- //fit in 32 bits
- bool mirror : 8;
- bool receive_shadows : 8;
- bool visible : 8;
- bool baked_light : 2; //this flag is only to know if it actually did use baked light
- bool dynamic_gi : 2; //this flag is only to know if it actually did use baked light
- bool redraw_if_visible : 4;
-
- float depth; //used for sorting
-
- InstanceBase *lightmap;
- Rect2 lightmap_uv_scale;
- int lightmap_slice_index;
- uint32_t lightmap_cull_index;
- Vector<Color> lightmap_sh; //spherical harmonic
-
- AABB aabb;
- AABB transformed_aabb;
- AABB prev_transformed_aabb;
-
- struct InstanceShaderParameter {
- int32_t index = -1;
- Variant value;
- Variant default_value;
- PropertyInfo info;
- };
-
- Map<StringName, InstanceShaderParameter> instance_shader_parameters;
- bool instance_allocated_shader_parameters = false;
- int32_t instance_allocated_shader_parameters_offset = -1;
-
- InstanceBase() {
- base_type = RS::INSTANCE_NONE;
- cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
- receive_shadows = true;
- visible = true;
- depth_layer = 0;
- layer_mask = 1;
- instance_version = 0;
- baked_light = false;
- dynamic_gi = false;
- redraw_if_visible = false;
- lightmap_slice_index = 0;
- lightmap = nullptr;
- lightmap_cull_index = 0;
- lod_bias = 1.0;
- }
-
- virtual ~InstanceBase() {
- }
- };
-
virtual RID light_instance_create(RID p_light) = 0;
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0;
@@ -230,20 +184,42 @@ public:
virtual RID decal_instance_create(RID p_decal) = 0;
virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0;
+ virtual RID lightmap_instance_create(RID p_lightmap) = 0;
+ virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) = 0;
+
virtual RID gi_probe_instance_create(RID p_gi_probe) = 0;
virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
virtual bool gi_probe_needs_update(RID p_probe) const = 0;
- virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects) = 0;
+ virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0;
virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0;
- virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0;
+ struct RenderShadowData {
+ RID light;
+ int pass = 0;
+ PagedArray<GeometryInstance *> instances;
+ };
+
+ struct RenderSDFGIData {
+ int region = 0;
+ PagedArray<GeometryInstance *> instances;
+ };
+
+ struct RenderSDFGIUpdateData {
+ bool update_static = false;
+ uint32_t static_cascade_count;
+ uint32_t *static_cascade_indices;
+ PagedArray<RID> *static_positional_lights;
+
+ const Vector<RID> *directional_lights;
+ const RID *positional_light_instances;
+ uint32_t positional_light_count;
+ };
+
+ virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr) = 0;
- virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0;
- virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
- virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances) = 0;
- virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_lights) = 0;
- virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) = 0;
+ virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
+ virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0;
virtual void set_scene_pass(uint64_t p_pass) = 0;
virtual void set_time(double p_time, double p_step) = 0;
@@ -251,6 +227,7 @@ public:
virtual RID render_buffers_create() = 0;
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0;
+ virtual void gi_set_use_half_resolution(bool p_enable) = 0;
virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0;
virtual bool screen_space_roughness_limiter_is_active() const = 0;
diff --git a/servers/rendering/renderer_storage.cpp b/servers/rendering/renderer_storage.cpp
index 1b2773e404..a402ecc668 100644
--- a/servers/rendering/renderer_storage.cpp
+++ b/servers/rendering/renderer_storage.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,28 +32,31 @@
RendererStorage *RendererStorage::base_singleton = nullptr;
-void RendererStorage::InstanceDependency::instance_notify_changed(bool p_aabb, bool p_dependencies) {
- for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
- E->key()->dependency_changed(p_aabb, p_dependencies);
+void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p_notification) {
+ for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
+ if (E->key()->changed_callback) {
+ E->key()->changed_callback(p_notification, E->key());
+ }
}
}
-void RendererStorage::InstanceDependency::instance_notify_deleted(RID p_deleted) {
- for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
- E->key()->dependency_deleted(p_deleted);
+void RendererStorage::Dependency::deleted_notify(const RID &p_rid) {
+ for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
+ if (E->key()->deleted_callback) {
+ E->key()->deleted_callback(p_rid, E->key());
+ }
}
- for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
+ for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
E->key()->dependencies.erase(this);
}
-
instances.clear();
}
-RendererStorage::InstanceDependency::~InstanceDependency() {
+RendererStorage::Dependency::~Dependency() {
#ifdef DEBUG_ENABLED
if (instances.size()) {
WARN_PRINT("Leaked instance dependency: Bug - did not call instance_notify_deleted when freeing.");
- for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
+ for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
E->key()->dependencies.erase(this);
}
}
diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h
index 895a7a5be8..22cf6acb19 100644
--- a/servers/rendering/renderer_storage.h
+++ b/servers/rendering/renderer_storage.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,43 +37,59 @@ class RendererStorage {
Color default_clear_color;
public:
- struct InstanceBaseDependency;
+ enum DependencyChangedNotification {
+ DEPENDENCY_CHANGED_AABB,
+ DEPENDENCY_CHANGED_MATERIAL,
+ DEPENDENCY_CHANGED_MESH,
+ DEPENDENCY_CHANGED_MULTIMESH,
+ DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES,
+ DEPENDENCY_CHANGED_DECAL,
+ DEPENDENCY_CHANGED_SKELETON_DATA,
+ DEPENDENCY_CHANGED_SKELETON_BONES,
+ DEPENDENCY_CHANGED_LIGHT,
+ DEPENDENCY_CHANGED_REFLECTION_PROBE,
+ };
+
+ struct DependencyTracker;
- struct InstanceDependency {
- void instance_notify_changed(bool p_aabb, bool p_dependencies);
- void instance_notify_deleted(RID p_deleted);
+protected:
+ struct Dependency {
+ void changed_notify(DependencyChangedNotification p_notification);
+ void deleted_notify(const RID &p_rid);
- ~InstanceDependency();
+ ~Dependency();
private:
- friend struct InstanceBaseDependency;
- Map<InstanceBaseDependency *, uint32_t> instances;
+ friend struct DependencyTracker;
+ Map<DependencyTracker *, uint32_t> instances;
};
- struct InstanceBaseDependency {
- uint32_t instance_version;
- Set<InstanceDependency *> dependencies;
+public:
+ struct DependencyTracker {
+ void *userdata = nullptr;
+ typedef void (*ChangedCallback)(DependencyChangedNotification, DependencyTracker *);
+ typedef void (*DeletedCallback)(const RID &, DependencyTracker *);
- virtual void dependency_deleted(RID p_dependency) {}
- virtual void dependency_changed(bool p_aabb, bool p_dependencies) {}
+ ChangedCallback changed_callback = nullptr;
+ DeletedCallback deleted_callback = nullptr;
- void instance_increase_version() {
+ void update_begin() { // call before updating dependencies
instance_version++;
}
- void update_dependency(InstanceDependency *p_dependency) {
+ void update_dependency(Dependency *p_dependency) { //called internally, can't be used directly, use update functions in Storage
dependencies.insert(p_dependency);
p_dependency->instances[this] = instance_version;
}
- void clean_up_dependencies() {
- List<Pair<InstanceDependency *, Map<InstanceBaseDependency *, uint32_t>::Element *>> to_clean_up;
- for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) {
- InstanceDependency *dep = E->get();
- Map<InstanceBaseDependency *, uint32_t>::Element *F = dep->instances.find(this);
+ void update_end() { //call after updating dependencies
+ List<Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *>> to_clean_up;
+ for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) {
+ Dependency *dep = E->get();
+ Map<DependencyTracker *, uint32_t>::Element *F = dep->instances.find(this);
ERR_CONTINUE(!F);
if (F->get() != instance_version) {
- Pair<InstanceDependency *, Map<InstanceBaseDependency *, uint32_t>::Element *> p;
+ Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *> p;
p.first = dep;
p.second = F;
to_clean_up.push_back(p);
@@ -82,27 +98,36 @@ public:
while (to_clean_up.size()) {
to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second);
+ dependencies.erase(to_clean_up.front()->get().first);
to_clean_up.pop_front();
}
}
- void clear_dependencies() {
- for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) {
- InstanceDependency *dep = E->get();
+ void clear() { // clear all dependencies
+ for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) {
+ Dependency *dep = E->get();
dep->instances.erase(this);
}
dependencies.clear();
}
- virtual ~InstanceBaseDependency() { clear_dependencies(); }
+ ~DependencyTracker() { clear(); }
+
+ private:
+ friend struct Dependency;
+ uint32_t instance_version = 0;
+ Set<Dependency *> dependencies;
};
+ virtual bool can_create_resources_async() const = 0;
/* TEXTURE API */
- virtual RID texture_2d_create(const Ref<Image> &p_image) = 0;
- virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0;
- virtual RID texture_3d_create(Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0;
- virtual RID texture_proxy_create(RID p_base) = 0; //all slices, then all the mipmaps, must be coherent
+ virtual RID texture_allocate() = 0;
+
+ virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) = 0;
+ virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0;
+ virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0;
+ virtual void texture_proxy_initialize(RID p_texture, RID p_base) = 0; //all slices, then all the mipmaps, must be coherent
virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; //mostly used for video and streaming
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
@@ -110,9 +135,9 @@ public:
virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0;
//these two APIs can be used together or in combination with the others.
- virtual RID texture_2d_placeholder_create() = 0;
- virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0;
- virtual RID texture_3d_placeholder_create() = 0;
+ virtual void texture_2d_placeholder_initialize(RID p_texture) = 0;
+ virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) = 0;
+ virtual void texture_3d_placeholder_initialize(RID p_texture) = 0;
virtual Ref<Image> texture_2d_get(RID p_texture) const = 0;
virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0;
@@ -139,7 +164,9 @@ public:
/* CANVAS TEXTURE API */
- virtual RID canvas_texture_create() = 0;
+ virtual RID canvas_texture_allocate() = 0;
+ virtual void canvas_texture_initialize(RID p_rid) = 0;
+
virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0;
virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
@@ -148,7 +175,8 @@ public:
/* SHADER API */
- virtual RID shader_create() = 0;
+ virtual RID shader_allocate() = 0;
+ virtual void shader_initialize(RID p_rid) = 0;
virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
virtual String shader_get_code(RID p_shader) const = 0;
@@ -158,9 +186,12 @@ public:
virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0;
virtual Variant shader_get_param_default(RID p_material, const StringName &p_param) const = 0;
+ virtual RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0;
+
/* COMMON MATERIAL API */
- virtual RID material_create() = 0;
+ virtual RID material_allocate() = 0;
+ virtual void material_initialize(RID p_rid) = 0;
virtual void material_set_render_priority(RID p_material, int priority) = 0;
virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
@@ -181,11 +212,12 @@ public:
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
- virtual void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) = 0;
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0;
/* MESH API */
- virtual RID mesh_create() = 0;
+ virtual RID mesh_allocate() = 0;
+ virtual void mesh_initialize(RID p_rid) = 0;
virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) = 0;
@@ -211,6 +243,8 @@ public:
virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) = 0;
+ virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) = 0;
+
virtual void mesh_clear(RID p_mesh) = 0;
virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) = 0;
@@ -225,9 +259,10 @@ public:
/* MULTIMESH API */
- virtual RID multimesh_create() = 0;
+ virtual RID multimesh_allocate() = 0;
+ virtual void multimesh_initialize(RID p_rid) = 0;
- virtual void multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0;
+ virtual 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) = 0;
virtual int multimesh_get_instance_count(RID p_multimesh) const = 0;
@@ -254,7 +289,9 @@ public:
/* IMMEDIATE API */
- virtual RID immediate_create() = 0;
+ virtual RID immediate_allocate() = 0;
+ virtual void immediate_initialize(RID p_rid) = 0;
+
virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) = 0;
virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) = 0;
virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) = 0;
@@ -270,8 +307,10 @@ public:
/* SKELETON API */
- virtual RID skeleton_create() = 0;
- virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0;
+ virtual RID skeleton_allocate() = 0;
+ virtual void skeleton_initialize(RID p_rid) = 0;
+
+ virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0;
virtual int skeleton_get_bone_count(RID p_skeleton) const = 0;
virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0;
virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0;
@@ -281,11 +320,14 @@ public:
/* Light API */
- virtual RID light_create(RS::LightType p_type) = 0;
+ virtual RID directional_light_allocate() = 0;
+ virtual void directional_light_initialize(RID p_rid) = 0;
+
+ virtual RID omni_light_allocate() = 0;
+ virtual void omni_light_initialize(RID p_rid) = 0;
- RID directional_light_create() { return light_create(RS::LIGHT_DIRECTIONAL); }
- RID omni_light_create() { return light_create(RS::LIGHT_OMNI); }
- RID spot_light_create() { return light_create(RS::LIGHT_SPOT); }
+ virtual RID spot_light_allocate() = 0;
+ virtual void spot_light_initialize(RID p_rid) = 0;
virtual void light_set_color(RID p_light, const Color &p_color) = 0;
virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0;
@@ -323,7 +365,8 @@ public:
/* PROBE API */
- virtual RID reflection_probe_create() = 0;
+ virtual RID reflection_probe_allocate() = 0;
+ virtual void reflection_probe_initialize(RID p_rid) = 0;
virtual void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) = 0;
virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
@@ -349,12 +392,14 @@ public:
virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0;
virtual float reflection_probe_get_lod_threshold(RID p_probe) const = 0;
- virtual void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) = 0;
- virtual void skeleton_update_dependency(RID p_base, InstanceBaseDependency *p_instance) = 0;
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
+ virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
/* DECAL API */
- virtual RID decal_create() = 0;
+ virtual RID decal_allocate() = 0;
+ virtual void decal_initialize(RID p_rid) = 0;
+
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
@@ -369,9 +414,10 @@ public:
/* GI PROBE API */
- virtual RID gi_probe_create() = 0;
+ virtual RID gi_probe_allocate() = 0;
+ virtual void gi_probe_initialize(RID p_rid) = 0;
- virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0;
+ virtual void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0;
virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0;
virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0;
@@ -414,9 +460,10 @@ public:
virtual uint32_t gi_probe_get_version(RID p_probe) = 0;
- /* LIGHTMAP CAPTURE */
+ /* LIGHTMAP */
- virtual RID lightmap_create() = 0;
+ virtual RID lightmap_allocate() = 0;
+ virtual void lightmap_initialize(RID p_rid) = 0;
virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0;
virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0;
@@ -434,7 +481,8 @@ public:
/* PARTICLES */
- virtual RID particles_create() = 0;
+ virtual RID particles_allocate() = 0;
+ virtual void particles_initialize(RID p_rid) = 0;
virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0;
virtual bool particles_get_emitting(RID p_particles) = 0;
@@ -474,14 +522,16 @@ public:
virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0;
- virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0;
- virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0;
+ virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) = 0;
+ virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) = 0;
virtual void update_particles() = 0;
/* PARTICLES COLLISION */
- virtual RID particles_collision_create() = 0;
+ virtual RID particles_collision_allocate() = 0;
+ virtual void particles_collision_initialize(RID p_rid) = 0;
+
virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) = 0;
virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0;
virtual void particles_collision_set_sphere_radius(RID p_particles_collision, float p_radius) = 0; //for spheres
@@ -496,6 +546,11 @@ public:
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0;
virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0;
+ //used from 2D and 3D
+ virtual RID particles_collision_instance_create(RID p_collision) = 0;
+ virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) = 0;
+ virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0;
+
/* GLOBAL VARIABLES */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;
@@ -553,7 +608,7 @@ public:
virtual void render_info_end_capture() = 0;
virtual int get_captured_render_info(RS::RenderInfo p_info) = 0;
- virtual int get_render_info(RS::RenderInfo p_info) = 0;
+ virtual uint64_t get_render_info(RS::RenderInfo p_info) = 0;
virtual String get_video_adapter_name() const = 0;
virtual String get_video_adapter_vendor() const = 0;
diff --git a/modules/camera_iphone/camera_module.cpp b/servers/rendering/renderer_thread_pool.cpp
index f3d00be204..98050dd508 100644
--- a/modules/camera_iphone/camera_module.cpp
+++ b/servers/rendering/renderer_thread_pool.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* camera_module.cpp */
+/* renderer_thread_pool.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,13 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "camera_module.h"
+#include "renderer_thread_pool.h"
-#include "camera_ios.h"
+RendererThreadPool *RendererThreadPool::singleton = nullptr;
-void register_camera_types() {
- CameraServer::make_default<CameraIOS>();
+RendererThreadPool::RendererThreadPool() {
+ singleton = this;
+ thread_work_pool.init();
}
-void unregister_camera_types() {
+RendererThreadPool::~RendererThreadPool() {
+ thread_work_pool.finish();
}
diff --git a/modules/camera_iphone/camera_ios.h b/servers/rendering/renderer_thread_pool.h
index 7da43e4851..ae25415a0d 100644
--- a/modules/camera_iphone/camera_ios.h
+++ b/servers/rendering/renderer_thread_pool.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* camera_ios.h */
+/* renderer_thread_pool.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,18 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CAMERAIOS_H
-#define CAMERAIOS_H
+#ifndef RENDERERTHREADPOOL_H
+#define RENDERERTHREADPOOL_H
-#include "servers/camera_server.h"
+#include "core/templates/thread_work_pool.h"
-class CameraIOS : public CameraServer {
-private:
+class RendererThreadPool {
public:
- CameraIOS();
- ~CameraIOS();
+ ThreadWorkPool thread_work_pool;
- void update_feeds();
+ static RendererThreadPool *singleton;
+ RendererThreadPool();
+ ~RendererThreadPool();
};
-#endif /* CAMERAIOS_H */
+#endif // RENDERERTHREADPOOL_H
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index ea95eb1189..a5d5033c18 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -457,7 +457,7 @@ void RendererViewport::draw_viewports() {
}
if (Engine::get_singleton()->is_editor_hint()) {
- set_default_clear_color(GLOBAL_GET("rendering/environment/default_clear_color"));
+ set_default_clear_color(GLOBAL_GET("rendering/environment/defaults/default_clear_color"));
}
//sort viewports
@@ -608,19 +608,20 @@ void RendererViewport::draw_viewports() {
}
}
-RID RendererViewport::viewport_create() {
- Viewport *viewport = memnew(Viewport);
-
- RID rid = viewport_owner.make_rid(viewport);
+RID RendererViewport::viewport_allocate() {
+ return viewport_owner.allocate_rid();
+}
- viewport->self = rid;
+void RendererViewport::viewport_initialize(RID p_rid) {
+ Viewport *viewport = memnew(Viewport);
+ viewport->self = p_rid;
viewport->hide_scenario = false;
viewport->hide_canvas = false;
viewport->render_target = RSG::storage->render_target_create();
viewport->shadow_atlas = RSG::scene->shadow_atlas_create();
viewport->viewport_render_direct_to_screen = false;
- return rid;
+ viewport_owner.initialize_rid(p_rid, viewport);
}
void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
@@ -831,13 +832,14 @@ void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas
viewport->canvas_map[p_canvas].sublayer = p_sublayer;
}
-void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
+void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->shadow_atlas_size = p_size;
+ viewport->shadow_atlas_16_bits = p_16_bits;
- RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size);
+ RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size, viewport->shadow_atlas_16_bits);
}
void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
@@ -1018,5 +1020,10 @@ void RendererViewport::set_default_clear_color(const Color &p_color) {
RSG::storage->set_default_clear_color(p_color);
}
+//workaround for setting this on thread
+void RendererViewport::call_set_use_vsync(bool p_enable) {
+ DisplayServer::get_singleton()->_set_use_vsync(p_enable);
+}
+
RendererViewport::RendererViewport() {
}
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index e836d05dfc..f5ed543e8d 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -81,6 +81,7 @@ public:
RID shadow_atlas;
int shadow_atlas_size;
+ bool shadow_atlas_16_bits = false;
bool sdf_active;
@@ -164,7 +165,7 @@ public:
uint64_t draw_viewports_pass = 0;
- mutable RID_PtrOwner<Viewport> viewport_owner;
+ mutable RID_PtrOwner<Viewport, true> viewport_owner;
struct ViewportSort {
_FORCE_INLINE_ bool operator()(const Viewport *p_left, const Viewport *p_right) const {
@@ -185,7 +186,8 @@ private:
void _draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye = XRInterface::EYE_MONO);
public:
- RID viewport_create();
+ RID viewport_allocate();
+ void viewport_initialize(RID p_rid);
void viewport_set_use_xr(RID p_viewport, bool p_use_xr);
@@ -217,7 +219,7 @@ public:
void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
- void viewport_set_shadow_atlas_size(RID p_viewport, int p_size);
+ void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false);
void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa);
@@ -248,6 +250,9 @@ public:
bool free(RID p_rid);
+ //workaround for setting this on thread
+ void call_set_use_vsync(bool p_enable);
+
RendererViewport();
virtual ~RendererViewport() {}
};
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index ba30670082..27a9353e4e 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -68,7 +68,7 @@ RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const
Vector<Vector<uint8_t>> data;
for (int i = 0; i < p_data.size(); i++) {
Vector<uint8_t> byte_slice = p_data[i];
- ERR_FAIL_COND_V(byte_slice.empty(), RID());
+ ERR_FAIL_COND_V(byte_slice.is_empty(), RID());
data.push_back(byte_slice);
}
return texture_create(p_format->base, p_view->base, data);
@@ -154,7 +154,7 @@ RID RenderingDevice::shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_
String error = p_bytecode->get_stage_compile_error(stage);
ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
sd.spir_v = p_bytecode->get_stage_bytecode(stage);
- if (sd.spir_v.empty()) {
+ if (sd.spir_v.is_empty()) {
continue;
}
stage_data.push_back(sd);
@@ -174,8 +174,8 @@ RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader,
return uniform_set_create(uniforms, p_shader, p_shader_set);
}
-Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) {
- return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw);
+Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier) {
+ return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_post_barrier);
}
RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) {
@@ -240,16 +240,12 @@ void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, cons
compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size);
}
-void RenderingDevice::compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads, uint32_t p_x_local_group, uint32_t p_y_local_group, uint32_t p_z_local_group) {
- compute_list_dispatch(p_list, (p_x_threads - 1) / p_x_local_group + 1, (p_y_threads - 1) / p_y_local_group + 1, (p_z_threads - 1) / p_z_local_group + 1);
-}
-
void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared);
ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D));
- ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "sync_with_draw"), &RenderingDevice::texture_update, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "post_barrier"), &RenderingDevice::texture_update, DEFVAL(BARRIER_MASK_ALL));
ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data);
ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage);
@@ -257,15 +253,15 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared);
ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid);
- ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "sync_with_draw"), &RenderingDevice::texture_copy, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "sync_with_draw"), &RenderingDevice::texture_clear, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "sync_with_draw"), &RenderingDevice::texture_resolve_multisample, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "post_barrier"), &RenderingDevice::texture_copy, DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::texture_clear, DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::texture_resolve_multisample, DEFVAL(BARRIER_MASK_ALL));
ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create);
- ClassDB::bind_method(D_METHOD("framebuffer_format_create_empty", "size"), &RenderingDevice::framebuffer_format_create_empty);
+ ClassDB::bind_method(D_METHOD("framebuffer_format_create_empty", "samples"), &RenderingDevice::framebuffer_format_create_empty, DEFVAL(TEXTURE_SAMPLES_1));
ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples);
ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID));
- ClassDB::bind_method(D_METHOD("framebuffer_create_empty", "size", "validate_with_format"), &RenderingDevice::framebuffer_create_empty, DEFVAL(INVALID_FORMAT_ID));
+ ClassDB::bind_method(D_METHOD("framebuffer_create_empty", "size", "samples", "validate_with_format"), &RenderingDevice::framebuffer_create_empty, DEFVAL(TEXTURE_SAMPLES_1), DEFVAL(INVALID_FORMAT_ID));
ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format);
ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create);
@@ -273,7 +269,7 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data", "use_as_storage"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create);
- ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data", "use_restart_indices"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create);
ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true));
@@ -287,7 +283,8 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create);
ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid);
- ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "sync_with_draw"), &RenderingDevice::_buffer_update, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "post_barrier"), &RenderingDevice::_buffer_update, DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL));
ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data);
ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0));
@@ -316,19 +313,19 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i()));
ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor);
- ClassDB::bind_method(D_METHOD("draw_list_end"), &RenderingDevice::draw_list_end);
+ ClassDB::bind_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::draw_list_end, DEFVAL(BARRIER_MASK_ALL));
- ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin);
+ ClassDB::bind_method(D_METHOD("compute_list_begin", "allow_draw_overlap"), &RenderingDevice::compute_list_begin, DEFVAL(false));
ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline);
ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant);
ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set);
ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch);
ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier);
- ClassDB::bind_method(D_METHOD("compute_list_end"), &RenderingDevice::compute_list_end);
+ ClassDB::bind_method(D_METHOD("compute_list_end", "post_barrier"), &RenderingDevice::compute_list_end, DEFVAL(BARRIER_MASK_ALL));
ClassDB::bind_method(D_METHOD("free", "rid"), &RenderingDevice::free);
- ClassDB::bind_method(D_METHOD("capture_timestamp", "name", "sync_to_draw"), &RenderingDevice::capture_timestamp);
+ ClassDB::bind_method(D_METHOD("capture_timestamp", "name"), &RenderingDevice::capture_timestamp);
ClassDB::bind_method(D_METHOD("get_captured_timestamps_count"), &RenderingDevice::get_captured_timestamps_count);
ClassDB::bind_method(D_METHOD("get_captured_timestamps_frame"), &RenderingDevice::get_captured_timestamps_frame);
ClassDB::bind_method(D_METHOD("get_captured_timestamp_gpu_time", "index"), &RenderingDevice::get_captured_timestamp_gpu_time);
@@ -340,8 +337,27 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit);
ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync);
+ ClassDB::bind_method(D_METHOD("barrier", "from", "to"), &RenderingDevice::barrier, DEFVAL(BARRIER_MASK_ALL), DEFVAL(BARRIER_MASK_ALL));
+ ClassDB::bind_method(D_METHOD("full_barrier"), &RenderingDevice::full_barrier);
+
ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device);
+ ClassDB::bind_method(D_METHOD("set_resource_name", "id", "name"), &RenderingDevice::set_resource_name);
+
+ ClassDB::bind_method(D_METHOD("draw_command_begin_label", "name", "color"), &RenderingDevice::draw_command_begin_label);
+ ClassDB::bind_method(D_METHOD("draw_command_insert_label", "name", "color"), &RenderingDevice::draw_command_insert_label);
+ ClassDB::bind_method(D_METHOD("draw_command_end_label"), &RenderingDevice::draw_command_end_label);
+
+ ClassDB::bind_method(D_METHOD("get_device_vendor_name"), &RenderingDevice::get_device_vendor_name);
+ ClassDB::bind_method(D_METHOD("get_device_name"), &RenderingDevice::get_device_name);
+ ClassDB::bind_method(D_METHOD("get_device_pipeline_cache_uuid"), &RenderingDevice::get_device_pipeline_cache_uuid);
+
+ BIND_CONSTANT(BARRIER_MASK_RASTER);
+ BIND_CONSTANT(BARRIER_MASK_COMPUTE);
+ BIND_CONSTANT(BARRIER_MASK_TRANSFER);
+ BIND_CONSTANT(BARRIER_MASK_ALL);
+ BIND_CONSTANT(BARRIER_MASK_NO_BARRIER);
+
BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8);
BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16);
BIND_ENUM_CONSTANT(DATA_FORMAT_B4G4R4A4_UNORM_PACK16);
@@ -744,6 +760,8 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE);
BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params)
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION); //start rendering and clear the framebuffer (supply params)
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION_CONTINUE); //continue rendering and clear the framebuffer (supply params)
BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared)
BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it
BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously)
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index b3d4e66f6c..9fbf58d131 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -336,6 +336,18 @@ public:
};
/*****************/
+ /**** BARRIER ****/
+ /*****************/
+
+ enum BarrierMask {
+ BARRIER_MASK_RASTER = 1,
+ BARRIER_MASK_COMPUTE = 2,
+ BARRIER_MASK_TRANSFER = 4,
+ BARRIER_MASK_NO_BARRIER = 8,
+ BARRIER_MASK_ALL = BARRIER_MASK_RASTER | BARRIER_MASK_COMPUTE | BARRIER_MASK_TRANSFER
+ };
+
+ /*****************/
/**** TEXTURE ****/
/*****************/
@@ -438,16 +450,16 @@ public:
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0;
- virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the beginning of the frame, unless sync with draw is used, which is used to mix updates with draw calls
+ virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush
virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0;
virtual bool texture_is_shared(RID p_texture) = 0;
virtual bool texture_is_valid(RID p_texture) = 0;
- virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false) = 0;
- virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false) = 0;
- virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw = false) = 0;
+ virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
+ virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
+ virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
/*********************/
/**** FRAMEBUFFER ****/
@@ -468,11 +480,11 @@ public:
// This ID is warranted to be unique for the same formats, does not need to be freed
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format) = 0;
- virtual FramebufferFormatID framebuffer_format_create_empty(const Size2i &p_size) = 0;
+ virtual FramebufferFormatID framebuffer_format_create_empty(TextureSamples p_samples = TEXTURE_SAMPLES_1) = 0;
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format) = 0;
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID) = 0;
- virtual RID framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check = INVALID_ID) = 0;
+ virtual RID framebuffer_create_empty(const Size2i &p_size, TextureSamples p_samples = TEXTURE_SAMPLES_1, FramebufferFormatID p_format_check = INVALID_ID) = 0;
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer) = 0;
@@ -649,7 +661,8 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0;
virtual bool uniform_set_is_valid(RID p_uniform_set) = 0;
- virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the beginning of the frame, unless sync with draw is used, which is used to mix updates with draw calls
+ virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
+ virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
virtual Vector<uint8_t> buffer_get_data(RID p_buffer) = 0; //this causes stall, only use to retrieve large buffers for saving
/*************************/
@@ -930,7 +943,9 @@ public:
/********************/
enum InitialAction {
- INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params)
+ INITIAL_ACTION_CLEAR, //start rendering and clear the whole framebuffer (region or not) (supply params)
+ INITIAL_ACTION_CLEAR_REGION, //start rendering and clear the framebuffer in the specified region (supply params)
+ INITIAL_ACTION_CLEAR_REGION_CONTINUE, //countinue rendering and clear the framebuffer in the specified region (supply params)
INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared)
INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it
INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously)
@@ -962,7 +977,7 @@ public:
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect) = 0;
virtual void draw_list_disable_scissor(DrawListID p_list) = 0;
- virtual void draw_list_end() = 0;
+ virtual void draw_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
/***********************/
/**** COMPUTE LISTS ****/
@@ -970,17 +985,18 @@ public:
typedef int64_t ComputeListID;
- virtual ComputeListID compute_list_begin() = 0;
+ virtual ComputeListID compute_list_begin(bool p_allow_draw_overlap = false) = 0;
virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0;
virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0;
virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0;
virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0;
- virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads, uint32_t p_x_local_group, uint32_t p_y_local_group, uint32_t p_z_local_group);
+ virtual void compute_list_dispatch_threads(ComputeListID p_list, uint32_t p_x_threads, uint32_t p_y_threads, uint32_t p_z_threads) = 0;
virtual void compute_list_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) = 0;
virtual void compute_list_add_barrier(ComputeListID p_list) = 0;
- virtual void compute_list_end() = 0;
+ virtual void compute_list_end(uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
+ virtual void barrier(uint32_t p_from = BARRIER_MASK_ALL, uint32_t p_to = BARRIER_MASK_ALL) = 0;
virtual void full_barrier() = 0;
/***************/
@@ -993,7 +1009,7 @@ public:
/**** Timing ****/
/****************/
- virtual void capture_timestamp(const String &p_name, bool p_sync_to_draw) = 0;
+ virtual void capture_timestamp(const String &p_name) = 0;
virtual uint32_t get_captured_timestamps_count() const = 0;
virtual uint64_t get_captured_timestamps_frame() const = 0;
virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0;
@@ -1058,6 +1074,16 @@ public:
virtual RenderingDevice *create_local_device() = 0;
+ virtual void set_resource_name(RID p_id, const String p_name) = 0;
+
+ virtual void draw_command_begin_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1)) = 0;
+ virtual void draw_command_insert_label(String p_label_name, const Color p_color = Color(1, 1, 1, 1)) = 0;
+ virtual void draw_command_end_label() = 0;
+
+ virtual String get_device_vendor_name() const = 0;
+ virtual String get_device_name() const = 0;
+ virtual String get_device_pipeline_cache_uuid() const = 0;
+
static RenderingDevice *get_singleton();
RenderingDevice();
@@ -1077,7 +1103,7 @@ protected:
RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set);
- Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false);
+ Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0);
diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp
index af9ecef0dd..2f11360364 100644
--- a/servers/rendering/rendering_device_binds.cpp
+++ b/servers/rendering/rendering_device_binds.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -163,7 +163,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present.");
}
- if (version_texts.empty()) {
+ if (version_texts.is_empty()) {
version_texts[""] = ""; //make sure a default version exists
}
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index 5deeec3ffe..e43c3669b5 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index da6c3ef6f4..c6fe6a07e0 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,7 +64,7 @@ void RenderingServerDefault::_draw_margins() {
/* FREE */
-void RenderingServerDefault::free(RID p_rid) {
+void RenderingServerDefault::_free(RID p_rid) {
if (RSG::storage->free(p_rid)) {
return;
}
@@ -91,7 +91,7 @@ void RenderingServerDefault::request_frame_drawn_callback(Object *p_where, const
frame_drawn_callbacks.push_back(fdc);
}
-void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
+void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
//needs to be done before changes is reset to 0, to not force the editor to redraw
RS::get_singleton()->emit_signal("frame_pre_draw");
@@ -162,24 +162,66 @@ void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
}
frame_profile_frame = RSG::storage->get_captured_timestamps_frame();
+
+ if (print_gpu_profile) {
+ if (print_frame_profile_ticks_from == 0) {
+ print_frame_profile_ticks_from = OS::get_singleton()->get_ticks_usec();
+ }
+ float total_time = 0.0;
+
+ for (int i = 0; i < frame_profile.size() - 1; i++) {
+ String name = frame_profile[i].name;
+ if (name[0] == '<' || name[0] == '>') {
+ continue;
+ }
+
+ float time = frame_profile[i + 1].gpu_msec - frame_profile[i].gpu_msec;
+
+ if (name[0] != '<' && name[0] != '>') {
+ if (print_gpu_profile_task_time.has(name)) {
+ print_gpu_profile_task_time[name] += time;
+ } else {
+ print_gpu_profile_task_time[name] = time;
+ }
+ }
+ }
+
+ if (frame_profile.size()) {
+ total_time = frame_profile[frame_profile.size() - 1].gpu_msec;
+ }
+
+ uint64_t ticks_elapsed = OS::get_singleton()->get_ticks_usec() - print_frame_profile_ticks_from;
+ print_frame_profile_frame_count++;
+ if (ticks_elapsed > 1000000) {
+ print_line("GPU PROFILE (total " + rtos(total_time) + "ms): ");
+
+ float print_threshold = 0.01;
+ for (OrderedHashMap<String, float>::Element E = print_gpu_profile_task_time.front(); E; E = E.next()) {
+ float time = E.value() / float(print_frame_profile_frame_count);
+ if (time > print_threshold) {
+ print_line("\t-" + E.key() + ": " + rtos(time) + "ms");
+ }
+ }
+ print_gpu_profile_task_time.clear();
+ print_frame_profile_ticks_from = OS::get_singleton()->get_ticks_usec();
+ print_frame_profile_frame_count = 0;
+ }
+ }
}
float RenderingServerDefault::get_frame_setup_time_cpu() const {
return frame_setup_time;
}
-void RenderingServerDefault::sync() {
-}
-
bool RenderingServerDefault::has_changed() const {
return changes > 0;
}
-void RenderingServerDefault::init() {
+void RenderingServerDefault::_init() {
RSG::rasterizer->initialize();
}
-void RenderingServerDefault::finish() {
+void RenderingServerDefault::_finish() {
if (test_cube.is_valid()) {
free(test_cube);
}
@@ -187,9 +229,35 @@ void RenderingServerDefault::finish() {
RSG::rasterizer->finalize();
}
+void RenderingServerDefault::init() {
+ if (create_thread) {
+ print_verbose("RenderingServerWrapMT: Creating render thread");
+ DisplayServer::get_singleton()->release_rendering_thread();
+ if (create_thread) {
+ thread.start(_thread_callback, this);
+ print_verbose("RenderingServerWrapMT: Starting render thread");
+ }
+ while (!draw_thread_up.is_set()) {
+ OS::get_singleton()->delay_usec(1000);
+ }
+ print_verbose("RenderingServerWrapMT: Finished render thread");
+ } else {
+ _init();
+ }
+}
+
+void RenderingServerDefault::finish() {
+ if (create_thread) {
+ command_queue.push(this, &RenderingServerDefault::_thread_exit);
+ thread.wait_to_finish();
+ } else {
+ _finish();
+ }
+}
+
/* STATUS INFORMATION */
-int RenderingServerDefault::get_render_info(RenderInfo p_info) {
+uint64_t RenderingServerDefault::get_render_info(RenderInfo p_info) {
return RSG::storage->get_render_info(p_info);
}
@@ -232,6 +300,11 @@ void RenderingServerDefault::sdfgi_set_debug_probe_select(const Vector3 &p_posit
RSG::scene->sdfgi_set_debug_probe_select(p_position, p_dir);
}
+void RenderingServerDefault::set_print_gpu_profile(bool p_enable) {
+ RSG::storage->capturing_timestamps = p_enable;
+ print_gpu_profile = p_enable;
+}
+
RID RenderingServerDefault::get_test_cube() {
if (!test_cube.is_valid()) {
test_cube = _make_test_cube();
@@ -247,10 +320,6 @@ void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) {
RSG::storage->set_debug_generate_wireframes(p_generate);
}
-void RenderingServerDefault::call_set_use_vsync(bool p_enable) {
- DisplayServer::get_singleton()->_set_use_vsync(p_enable);
-}
-
bool RenderingServerDefault::is_low_end() const {
// FIXME: Commented out when rebasing vulkan branch on master,
// causes a crash, it seems rasterizer is not initialized yet the
@@ -259,7 +328,74 @@ bool RenderingServerDefault::is_low_end() const {
return false;
}
-RenderingServerDefault::RenderingServerDefault() {
+void RenderingServerDefault::_thread_exit() {
+ exit.set();
+}
+
+void RenderingServerDefault::_thread_draw(bool p_swap_buffers, double frame_step) {
+ if (!draw_pending.decrement()) {
+ _draw(p_swap_buffers, frame_step);
+ }
+}
+
+void RenderingServerDefault::_thread_flush() {
+ draw_pending.decrement();
+}
+
+void RenderingServerDefault::_thread_callback(void *_instance) {
+ RenderingServerDefault *vsmt = reinterpret_cast<RenderingServerDefault *>(_instance);
+
+ vsmt->_thread_loop();
+}
+
+void RenderingServerDefault::_thread_loop() {
+ server_thread = Thread::get_caller_id();
+
+ DisplayServer::get_singleton()->make_rendering_thread();
+
+ _init();
+
+ draw_thread_up.set();
+ while (!exit.is_set()) {
+ // flush commands one by one, until exit is requested
+ command_queue.wait_and_flush_one();
+ }
+
+ command_queue.flush_all(); // flush all
+
+ _finish();
+}
+
+/* EVENT QUEUING */
+
+void RenderingServerDefault::sync() {
+ if (create_thread) {
+ draw_pending.increment();
+ command_queue.push_and_sync(this, &RenderingServerDefault::_thread_flush);
+ } else {
+ command_queue.flush_all(); //flush all pending from other threads
+ }
+}
+
+void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
+ if (create_thread) {
+ draw_pending.increment();
+ command_queue.push(this, &RenderingServerDefault::_thread_draw, p_swap_buffers, frame_step);
+ } else {
+ _draw(p_swap_buffers, frame_step);
+ }
+}
+
+RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
+ command_queue(p_create_thread) {
+ create_thread = p_create_thread;
+
+ if (!p_create_thread) {
+ server_thread = Thread::get_caller_id();
+ } else {
+ server_thread = 0;
+ }
+
RSG::canvas = memnew(RendererCanvasCull);
RSG::viewport = memnew(RendererViewport);
RendererSceneCull *sr = memnew(RendererSceneCull);
@@ -267,7 +403,7 @@ RenderingServerDefault::RenderingServerDefault() {
RSG::rasterizer = RendererCompositor::create();
RSG::storage = RSG::rasterizer->get_storage();
RSG::canvas_render = RSG::rasterizer->get_canvas();
- sr->scene_render = RSG::rasterizer->get_scene();
+ sr->set_scene_render(RSG::rasterizer->get_scene());
frame_profile_frame = 0;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 922cf08f3b..c6be07a3de 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,12 +32,15 @@
#define RENDERING_SERVER_DEFAULT_H
#include "core/math/octree.h"
+#include "core/templates/command_queue_mt.h"
+#include "core/templates/ordered_hash_map.h"
#include "renderer_canvas_cull.h"
#include "renderer_scene_cull.h"
#include "renderer_viewport.h"
#include "rendering_server_globals.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
+#include "servers/server_wrap_mt_common.h"
class RenderingServerDefault : public RenderingServer {
enum {
@@ -74,6 +77,37 @@ class RenderingServerDefault : public RenderingServer {
float frame_setup_time = 0;
+ //for printing
+ bool print_gpu_profile = false;
+ OrderedHashMap<String, float> print_gpu_profile_task_time;
+ uint64_t print_frame_profile_ticks_from = 0;
+ uint32_t print_frame_profile_frame_count = 0;
+
+ mutable CommandQueueMT command_queue;
+
+ static void _thread_callback(void *_instance);
+ void _thread_loop();
+
+ Thread::ID server_thread;
+ SafeFlag exit;
+ Thread thread;
+ SafeFlag draw_thread_up;
+ bool create_thread;
+
+ SafeNumeric<uint64_t> draw_pending;
+ void _thread_draw(bool p_swap_buffers, double frame_step);
+ void _thread_flush();
+
+ void _thread_exit();
+
+ Mutex alloc_mutex;
+
+ void _draw(bool p_swap_buffers, double frame_step);
+ void _init();
+ void _finish();
+
+ void _free(RID p_rid);
+
public:
//if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed()
//#define DEBUG_CHANGES
@@ -90,800 +124,813 @@ public:
#else
_FORCE_INLINE_ static void redraw_request() { changes++; }
+#endif
-#define DISPLAY_CHANGED \
- changes++;
+#define WRITE_ACTION redraw_request();
+
+#ifdef DEBUG_SYNC
+#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__));
+#else
+#define SYNC_DEBUG
#endif
-#define BIND0R(m_r, m_name) \
- m_r m_name() { return BINDBASE->m_name(); }
-#define BIND0RC(m_r, m_name) \
- m_r m_name() const { return BINDBASE->m_name(); }
-#define BIND1R(m_r, m_name, m_type1) \
- m_r m_name(m_type1 arg1) { return BINDBASE->m_name(arg1); }
-#define BIND1RC(m_r, m_name, m_type1) \
- m_r m_name(m_type1 arg1) const { return BINDBASE->m_name(arg1); }
-#define BIND2R(m_r, m_name, m_type1, m_type2) \
- m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); }
-#define BIND2RC(m_r, m_name, m_type1, m_type2) \
- m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); }
-#define BIND3R(m_r, m_name, m_type1, m_type2, m_type3) \
- m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { return BINDBASE->m_name(arg1, arg2, arg3); }
-#define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \
- m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) const { return BINDBASE->m_name(arg1, arg2, arg3); }
-#define BIND4R(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \
- m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return BINDBASE->m_name(arg1, arg2, arg3, arg4); }
-#define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \
- m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); }
-#define BIND5R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \
- m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); }
-#define BIND5RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \
- m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); }
-#define BIND6R(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
- m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); }
-#define BIND6RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
- m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); }
-
-#define BIND0(m_name) \
- void m_name() { DISPLAY_CHANGED BINDBASE->m_name(); }
-#define BIND1(m_name, m_type1) \
- void m_name(m_type1 arg1) { DISPLAY_CHANGED BINDBASE->m_name(arg1); }
-#define BIND1C(m_name, m_type1) \
- void m_name(m_type1 arg1) const { DISPLAY_CHANGED BINDBASE->m_name(arg1); }
-#define BIND2(m_name, m_type1, m_type2) \
- void m_name(m_type1 arg1, m_type2 arg2) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2); }
-#define BIND2C(m_name, m_type1, m_type2) \
- void m_name(m_type1 arg1, m_type2 arg2) const { BINDBASE->m_name(arg1, arg2); }
-#define BIND3(m_name, m_type1, m_type2, m_type3) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3); }
-#define BIND4(m_name, m_type1, m_type2, m_type3, m_type4) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4); }
-#define BIND5(m_name, m_type1, m_type2, m_type3, m_type4, m_type5) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5); }
-#define BIND6(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6); }
-#define BIND7(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7); }
-#define BIND8(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); }
-#define BIND9(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); }
-#define BIND10(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); }
-#define BIND11(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); }
-#define BIND12(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); }
-#define BIND13(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); }
-#define BIND14(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13, m_type14) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13, m_type14 arg14) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); }
-#define BIND15(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11, m_type12, m_type13, m_type14, m_type15) \
- void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11, m_type12 arg12, m_type13 arg13, m_type14 arg14, m_type15 arg15) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); }
+#include "servers/server_wrap_mt_common.h"
//from now on, calls forwarded to this singleton
-#define BINDBASE RSG::storage
+#define ServerName RendererStorage
+#define server_name RSG::storage
/* TEXTURE API */
+#define FUNCRIDTEX0(m_type) \
+ virtual RID m_type##_create() override { \
+ RID ret = RSG::storage->texture_allocate(); \
+ if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \
+ RSG::storage->m_type##_initialize(ret); \
+ } else { \
+ command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret); \
+ } \
+ return ret; \
+ }
+
+#define FUNCRIDTEX1(m_type, m_type1) \
+ virtual RID m_type##_create(m_type1 p1) override { \
+ RID ret = RSG::storage->texture_allocate(); \
+ if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \
+ RSG::storage->m_type##_initialize(ret, p1); \
+ } else { \
+ command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1); \
+ } \
+ return ret; \
+ }
+
+#define FUNCRIDTEX2(m_type, m_type1, m_type2) \
+ virtual RID m_type##_create(m_type1 p1, m_type2 p2) override { \
+ RID ret = RSG::storage->texture_allocate(); \
+ if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \
+ RSG::storage->m_type##_initialize(ret, p1, p2); \
+ } else { \
+ command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1, p2); \
+ } \
+ return ret; \
+ }
+
+#define FUNCRIDTEX6(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \
+ virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6) override { \
+ RID ret = RSG::storage->texture_allocate(); \
+ if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \
+ RSG::storage->m_type##_initialize(ret, p1, p2, p3, p4, p5, p6); \
+ } else { \
+ command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1, p2, p3, p4, p5, p6); \
+ } \
+ return ret; \
+ }
+
//these go pass-through, as they can be called from any thread
- BIND1R(RID, texture_2d_create, const Ref<Image> &)
- BIND2R(RID, texture_2d_layered_create, const Vector<Ref<Image>> &, TextureLayeredType)
- BIND6R(RID, texture_3d_create, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &)
- BIND1R(RID, texture_proxy_create, RID)
+ FUNCRIDTEX1(texture_2d, const Ref<Image> &)
+ FUNCRIDTEX2(texture_2d_layered, const Vector<Ref<Image>> &, TextureLayeredType)
+ FUNCRIDTEX6(texture_3d, Image::Format, int, int, int, bool, const Vector<Ref<Image>> &)
+ FUNCRIDTEX1(texture_proxy, RID)
//goes pass-through
- BIND3(texture_2d_update_immediate, RID, const Ref<Image> &, int)
+ FUNC3(texture_2d_update_immediate, RID, const Ref<Image> &, int)
//these go through command queue if they are in another thread
- BIND3(texture_2d_update, RID, const Ref<Image> &, int)
- BIND2(texture_3d_update, RID, const Vector<Ref<Image>> &)
- BIND2(texture_proxy_update, RID, RID)
+ FUNC3(texture_2d_update, RID, const Ref<Image> &, int)
+ FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &)
+ FUNC2(texture_proxy_update, RID, RID)
//these also go pass-through
- BIND0R(RID, texture_2d_placeholder_create)
- BIND1R(RID, texture_2d_layered_placeholder_create, TextureLayeredType)
- BIND0R(RID, texture_3d_placeholder_create)
+ FUNCRIDTEX0(texture_2d_placeholder)
+ FUNCRIDTEX1(texture_2d_layered_placeholder, TextureLayeredType)
+ FUNCRIDTEX0(texture_3d_placeholder)
- BIND1RC(Ref<Image>, texture_2d_get, RID)
- BIND2RC(Ref<Image>, texture_2d_layer_get, RID, int)
- BIND1RC(Vector<Ref<Image>>, texture_3d_get, RID)
+ FUNC1RC(Ref<Image>, texture_2d_get, RID)
+ FUNC2RC(Ref<Image>, texture_2d_layer_get, RID, int)
+ FUNC1RC(Vector<Ref<Image>>, texture_3d_get, RID)
- BIND2(texture_replace, RID, RID)
+ FUNC2(texture_replace, RID, RID)
- BIND3(texture_set_size_override, RID, int, int)
+ FUNC3(texture_set_size_override, RID, int, int)
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
- BIND2(texture_bind, RID, uint32_t)
+ FUNC2(texture_bind, RID, uint32_t)
#endif
- BIND3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
- BIND3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *)
- BIND3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *)
+ FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
+ FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *)
+ FUNC3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *)
- BIND2(texture_set_path, RID, const String &)
- BIND1RC(String, texture_get_path, RID)
- BIND1(texture_debug_usage, List<TextureInfo> *)
+ FUNC2(texture_set_path, RID, const String &)
+ FUNC1RC(String, texture_get_path, RID)
+ FUNC1(texture_debug_usage, List<TextureInfo> *)
- BIND2(texture_set_force_redraw_if_visible, RID, bool)
+ FUNC2(texture_set_force_redraw_if_visible, RID, bool)
/* SHADER API */
- BIND0R(RID, shader_create)
+ FUNCRIDSPLIT(shader)
- BIND2(shader_set_code, RID, const String &)
- BIND1RC(String, shader_get_code, RID)
+ FUNC2(shader_set_code, RID, const String &)
+ FUNC1RC(String, shader_get_code, RID)
- BIND2C(shader_get_param_list, RID, List<PropertyInfo> *)
+ FUNC2C(shader_get_param_list, RID, List<PropertyInfo> *)
- BIND3(shader_set_default_texture_param, RID, const StringName &, RID)
- BIND2RC(RID, shader_get_default_texture_param, RID, const StringName &)
- BIND2RC(Variant, shader_get_param_default, RID, const StringName &)
+ FUNC3(shader_set_default_texture_param, RID, const StringName &, RID)
+ FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &)
+ FUNC2RC(Variant, shader_get_param_default, RID, const StringName &)
+
+ FUNC1RC(ShaderNativeSourceCode, shader_get_native_source_code, RID)
/* COMMON MATERIAL API */
- BIND0R(RID, material_create)
+ FUNCRIDSPLIT(material)
- BIND2(material_set_shader, RID, RID)
+ FUNC2(material_set_shader, RID, RID)
- BIND3(material_set_param, RID, const StringName &, const Variant &)
- BIND2RC(Variant, material_get_param, RID, const StringName &)
+ FUNC3(material_set_param, RID, const StringName &, const Variant &)
+ FUNC2RC(Variant, material_get_param, RID, const StringName &)
- BIND2(material_set_render_priority, RID, int)
- BIND2(material_set_next_pass, RID, RID)
+ FUNC2(material_set_render_priority, RID, int)
+ FUNC2(material_set_next_pass, RID, RID)
/* MESH API */
- virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) {
- RID mesh = mesh_create();
- mesh_set_blend_shape_count(mesh, p_blend_shape_count);
- for (int i = 0; i < p_surfaces.size(); i++) {
- mesh_add_surface(mesh, p_surfaces[i]);
+ virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) override {
+ RID mesh = RSG::storage->mesh_allocate();
+
+ if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) {
+ if (Thread::get_caller_id() == server_thread) {
+ command_queue.flush_if_pending();
+ }
+ RSG::storage->mesh_initialize(mesh);
+ RSG::storage->mesh_set_blend_shape_count(mesh, p_blend_shape_count);
+ for (int i = 0; i < p_surfaces.size(); i++) {
+ RSG::storage->mesh_add_surface(mesh, p_surfaces[i]);
+ }
+ } else {
+ command_queue.push(RSG::storage, &RendererStorage::mesh_initialize, mesh);
+ command_queue.push(RSG::storage, &RendererStorage::mesh_set_blend_shape_count, mesh, p_blend_shape_count);
+ for (int i = 0; i < p_surfaces.size(); i++) {
+ RSG::storage->mesh_add_surface(mesh, p_surfaces[i]);
+ command_queue.push(RSG::storage, &RendererStorage::mesh_add_surface, mesh, p_surfaces[i]);
+ }
}
+
return mesh;
}
- BIND2(mesh_set_blend_shape_count, RID, int)
+ FUNC2(mesh_set_blend_shape_count, RID, int)
- BIND0R(RID, mesh_create)
+ FUNCRIDSPLIT(mesh)
- BIND2(mesh_add_surface, RID, const SurfaceData &)
+ FUNC2(mesh_add_surface, RID, const SurfaceData &)
- BIND1RC(int, mesh_get_blend_shape_count, RID)
+ FUNC1RC(int, mesh_get_blend_shape_count, RID)
- BIND2(mesh_set_blend_shape_mode, RID, BlendShapeMode)
- BIND1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID)
+ FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode)
+ FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID)
- BIND4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &)
+ FUNC4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &)
- BIND3(mesh_surface_set_material, RID, int, RID)
- BIND2RC(RID, mesh_surface_get_material, RID, int)
+ FUNC3(mesh_surface_set_material, RID, int, RID)
+ FUNC2RC(RID, mesh_surface_get_material, RID, int)
- BIND2RC(SurfaceData, mesh_get_surface, RID, int)
+ FUNC2RC(SurfaceData, mesh_get_surface, RID, int)
- BIND1RC(int, mesh_get_surface_count, RID)
+ FUNC1RC(int, mesh_get_surface_count, RID)
- BIND2(mesh_set_custom_aabb, RID, const AABB &)
- BIND1RC(AABB, mesh_get_custom_aabb, RID)
+ FUNC2(mesh_set_custom_aabb, RID, const AABB &)
+ FUNC1RC(AABB, mesh_get_custom_aabb, RID)
- BIND1(mesh_clear, RID)
+ FUNC2(mesh_set_shadow_mesh, RID, RID)
+
+ FUNC1(mesh_clear, RID)
/* MULTIMESH API */
- BIND0R(RID, multimesh_create)
+ FUNCRIDSPLIT(multimesh)
- BIND5(multimesh_allocate, RID, int, MultimeshTransformFormat, bool, bool)
- BIND1RC(int, multimesh_get_instance_count, RID)
+ FUNC5(multimesh_allocate_data, RID, int, MultimeshTransformFormat, bool, bool)
+ FUNC1RC(int, multimesh_get_instance_count, RID)
- BIND2(multimesh_set_mesh, RID, RID)
- BIND3(multimesh_instance_set_transform, RID, int, const Transform &)
- BIND3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &)
- BIND3(multimesh_instance_set_color, RID, int, const Color &)
- BIND3(multimesh_instance_set_custom_data, RID, int, const Color &)
+ FUNC2(multimesh_set_mesh, RID, RID)
+ FUNC3(multimesh_instance_set_transform, RID, int, const Transform &)
+ FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &)
+ FUNC3(multimesh_instance_set_color, RID, int, const Color &)
+ FUNC3(multimesh_instance_set_custom_data, RID, int, const Color &)
- BIND1RC(RID, multimesh_get_mesh, RID)
- BIND1RC(AABB, multimesh_get_aabb, RID)
+ FUNC1RC(RID, multimesh_get_mesh, RID)
+ FUNC1RC(AABB, multimesh_get_aabb, RID)
- BIND2RC(Transform, multimesh_instance_get_transform, RID, int)
- BIND2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int)
- BIND2RC(Color, multimesh_instance_get_color, RID, int)
- BIND2RC(Color, multimesh_instance_get_custom_data, RID, int)
+ FUNC2RC(Transform, multimesh_instance_get_transform, RID, int)
+ FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int)
+ FUNC2RC(Color, multimesh_instance_get_color, RID, int)
+ FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int)
- BIND2(multimesh_set_buffer, RID, const Vector<float> &)
- BIND1RC(Vector<float>, multimesh_get_buffer, RID)
+ FUNC2(multimesh_set_buffer, RID, const Vector<float> &)
+ FUNC1RC(Vector<float>, multimesh_get_buffer, RID)
- BIND2(multimesh_set_visible_instances, RID, int)
- BIND1RC(int, multimesh_get_visible_instances, RID)
+ FUNC2(multimesh_set_visible_instances, RID, int)
+ FUNC1RC(int, multimesh_get_visible_instances, RID)
/* IMMEDIATE API */
- BIND0R(RID, immediate_create)
- BIND3(immediate_begin, RID, PrimitiveType, RID)
- BIND2(immediate_vertex, RID, const Vector3 &)
- BIND2(immediate_normal, RID, const Vector3 &)
- BIND2(immediate_tangent, RID, const Plane &)
- BIND2(immediate_color, RID, const Color &)
- BIND2(immediate_uv, RID, const Vector2 &)
- BIND2(immediate_uv2, RID, const Vector2 &)
- BIND1(immediate_end, RID)
- BIND1(immediate_clear, RID)
- BIND2(immediate_set_material, RID, RID)
- BIND1RC(RID, immediate_get_material, RID)
+ FUNCRIDSPLIT(immediate)
+ FUNC3(immediate_begin, RID, PrimitiveType, RID)
+ FUNC2(immediate_vertex, RID, const Vector3 &)
+ FUNC2(immediate_normal, RID, const Vector3 &)
+ FUNC2(immediate_tangent, RID, const Plane &)
+ FUNC2(immediate_color, RID, const Color &)
+ FUNC2(immediate_uv, RID, const Vector2 &)
+ FUNC2(immediate_uv2, RID, const Vector2 &)
+ FUNC1(immediate_end, RID)
+ FUNC1(immediate_clear, RID)
+ FUNC2(immediate_set_material, RID, RID)
+ FUNC1RC(RID, immediate_get_material, RID)
/* SKELETON API */
- BIND0R(RID, skeleton_create)
- BIND3(skeleton_allocate, RID, int, bool)
- BIND1RC(int, skeleton_get_bone_count, RID)
- BIND3(skeleton_bone_set_transform, RID, int, const Transform &)
- BIND2RC(Transform, skeleton_bone_get_transform, RID, int)
- BIND3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
- BIND2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
- BIND2(skeleton_set_base_transform_2d, RID, const Transform2D &)
+ FUNCRIDSPLIT(skeleton)
+ FUNC3(skeleton_allocate_data, RID, int, bool)
+ FUNC1RC(int, skeleton_get_bone_count, RID)
+ FUNC3(skeleton_bone_set_transform, RID, int, const Transform &)
+ FUNC2RC(Transform, skeleton_bone_get_transform, RID, int)
+ FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
+ FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
+ FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &)
/* Light API */
- BIND0R(RID, directional_light_create)
- BIND0R(RID, omni_light_create)
- BIND0R(RID, spot_light_create)
+ FUNCRIDSPLIT(directional_light)
+ FUNCRIDSPLIT(omni_light)
+ FUNCRIDSPLIT(spot_light)
- BIND2(light_set_color, RID, const Color &)
- BIND3(light_set_param, RID, LightParam, float)
- BIND2(light_set_shadow, RID, bool)
- BIND2(light_set_shadow_color, RID, const Color &)
- BIND2(light_set_projector, RID, RID)
- BIND2(light_set_negative, RID, bool)
- BIND2(light_set_cull_mask, RID, uint32_t)
- BIND2(light_set_reverse_cull_face_mode, RID, bool)
- BIND2(light_set_bake_mode, RID, LightBakeMode)
- BIND2(light_set_max_sdfgi_cascade, RID, uint32_t)
+ FUNC2(light_set_color, RID, const Color &)
+ FUNC3(light_set_param, RID, LightParam, float)
+ FUNC2(light_set_shadow, RID, bool)
+ FUNC2(light_set_shadow_color, RID, const Color &)
+ FUNC2(light_set_projector, RID, RID)
+ FUNC2(light_set_negative, RID, bool)
+ FUNC2(light_set_cull_mask, RID, uint32_t)
+ FUNC2(light_set_reverse_cull_face_mode, RID, bool)
+ FUNC2(light_set_bake_mode, RID, LightBakeMode)
+ FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t)
- BIND2(light_omni_set_shadow_mode, RID, LightOmniShadowMode)
+ FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode)
- BIND2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
- BIND2(light_directional_set_blend_splits, RID, bool)
- BIND2(light_directional_set_sky_only, RID, bool)
- BIND2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
+ FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
+ FUNC2(light_directional_set_blend_splits, RID, bool)
+ FUNC2(light_directional_set_sky_only, RID, bool)
+ FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
/* PROBE API */
- BIND0R(RID, reflection_probe_create)
-
- BIND2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode)
- BIND2(reflection_probe_set_intensity, RID, float)
- BIND2(reflection_probe_set_ambient_color, RID, const Color &)
- BIND2(reflection_probe_set_ambient_energy, RID, float)
- BIND2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode)
- BIND2(reflection_probe_set_max_distance, RID, float)
- BIND2(reflection_probe_set_extents, RID, const Vector3 &)
- BIND2(reflection_probe_set_origin_offset, RID, const Vector3 &)
- BIND2(reflection_probe_set_as_interior, RID, bool)
- BIND2(reflection_probe_set_enable_box_projection, RID, bool)
- BIND2(reflection_probe_set_enable_shadows, RID, bool)
- BIND2(reflection_probe_set_cull_mask, RID, uint32_t)
- BIND2(reflection_probe_set_resolution, RID, int)
- BIND2(reflection_probe_set_lod_threshold, RID, float)
+ FUNCRIDSPLIT(reflection_probe)
+
+ FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode)
+ FUNC2(reflection_probe_set_intensity, RID, float)
+ FUNC2(reflection_probe_set_ambient_color, RID, const Color &)
+ FUNC2(reflection_probe_set_ambient_energy, RID, float)
+ FUNC2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode)
+ FUNC2(reflection_probe_set_max_distance, RID, float)
+ FUNC2(reflection_probe_set_extents, RID, const Vector3 &)
+ FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &)
+ FUNC2(reflection_probe_set_as_interior, RID, bool)
+ FUNC2(reflection_probe_set_enable_box_projection, RID, bool)
+ FUNC2(reflection_probe_set_enable_shadows, RID, bool)
+ FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
+ FUNC2(reflection_probe_set_resolution, RID, int)
+ FUNC2(reflection_probe_set_lod_threshold, RID, float)
/* DECAL API */
- BIND0R(RID, decal_create)
+ FUNCRIDSPLIT(decal)
- BIND2(decal_set_extents, RID, const Vector3 &)
- BIND3(decal_set_texture, RID, DecalTexture, RID)
- BIND2(decal_set_emission_energy, RID, float)
- BIND2(decal_set_albedo_mix, RID, float)
- BIND2(decal_set_modulate, RID, const Color &)
- BIND2(decal_set_cull_mask, RID, uint32_t)
- BIND4(decal_set_distance_fade, RID, bool, float, float)
- BIND3(decal_set_fade, RID, float, float)
- BIND2(decal_set_normal_fade, RID, float)
+ FUNC2(decal_set_extents, RID, const Vector3 &)
+ FUNC3(decal_set_texture, RID, DecalTexture, RID)
+ FUNC2(decal_set_emission_energy, RID, float)
+ FUNC2(decal_set_albedo_mix, RID, float)
+ FUNC2(decal_set_modulate, RID, const Color &)
+ FUNC2(decal_set_cull_mask, RID, uint32_t)
+ FUNC4(decal_set_distance_fade, RID, bool, float, float)
+ FUNC3(decal_set_fade, RID, float, float)
+ FUNC2(decal_set_normal_fade, RID, float)
/* BAKED LIGHT API */
- BIND0R(RID, gi_probe_create)
+ FUNCRIDSPLIT(gi_probe)
- BIND8(gi_probe_allocate, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &)
+ FUNC8(gi_probe_allocate_data, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &)
- BIND1RC(AABB, gi_probe_get_bounds, RID)
- BIND1RC(Vector3i, gi_probe_get_octree_size, RID)
- BIND1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID)
- BIND1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID)
- BIND1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID)
- BIND1RC(Vector<int>, gi_probe_get_level_counts, RID)
- BIND1RC(Transform, gi_probe_get_to_cell_xform, RID)
+ FUNC1RC(AABB, gi_probe_get_bounds, RID)
+ FUNC1RC(Vector3i, gi_probe_get_octree_size, RID)
+ FUNC1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID)
+ FUNC1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID)
+ FUNC1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID)
+ FUNC1RC(Vector<int>, gi_probe_get_level_counts, RID)
+ FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID)
- BIND2(gi_probe_set_dynamic_range, RID, float)
- BIND1RC(float, gi_probe_get_dynamic_range, RID)
+ FUNC2(gi_probe_set_dynamic_range, RID, float)
+ FUNC1RC(float, gi_probe_get_dynamic_range, RID)
- BIND2(gi_probe_set_propagation, RID, float)
- BIND1RC(float, gi_probe_get_propagation, RID)
+ FUNC2(gi_probe_set_propagation, RID, float)
+ FUNC1RC(float, gi_probe_get_propagation, RID)
- BIND2(gi_probe_set_energy, RID, float)
- BIND1RC(float, gi_probe_get_energy, RID)
+ FUNC2(gi_probe_set_energy, RID, float)
+ FUNC1RC(float, gi_probe_get_energy, RID)
- BIND2(gi_probe_set_ao, RID, float)
- BIND1RC(float, gi_probe_get_ao, RID)
+ FUNC2(gi_probe_set_ao, RID, float)
+ FUNC1RC(float, gi_probe_get_ao, RID)
- BIND2(gi_probe_set_ao_size, RID, float)
- BIND1RC(float, gi_probe_get_ao_size, RID)
+ FUNC2(gi_probe_set_ao_size, RID, float)
+ FUNC1RC(float, gi_probe_get_ao_size, RID)
- BIND2(gi_probe_set_bias, RID, float)
- BIND1RC(float, gi_probe_get_bias, RID)
+ FUNC2(gi_probe_set_bias, RID, float)
+ FUNC1RC(float, gi_probe_get_bias, RID)
- BIND2(gi_probe_set_normal_bias, RID, float)
- BIND1RC(float, gi_probe_get_normal_bias, RID)
+ FUNC2(gi_probe_set_normal_bias, RID, float)
+ FUNC1RC(float, gi_probe_get_normal_bias, RID)
- BIND2(gi_probe_set_interior, RID, bool)
- BIND1RC(bool, gi_probe_is_interior, RID)
+ FUNC2(gi_probe_set_interior, RID, bool)
+ FUNC1RC(bool, gi_probe_is_interior, RID)
- BIND2(gi_probe_set_use_two_bounces, RID, bool)
- BIND1RC(bool, gi_probe_is_using_two_bounces, RID)
+ FUNC2(gi_probe_set_use_two_bounces, RID, bool)
+ FUNC1RC(bool, gi_probe_is_using_two_bounces, RID)
- BIND2(gi_probe_set_anisotropy_strength, RID, float)
- BIND1RC(float, gi_probe_get_anisotropy_strength, RID)
+ FUNC2(gi_probe_set_anisotropy_strength, RID, float)
+ FUNC1RC(float, gi_probe_get_anisotropy_strength, RID)
/* LIGHTMAP */
- BIND0R(RID, lightmap_create)
+ FUNCRIDSPLIT(lightmap)
- BIND3(lightmap_set_textures, RID, RID, bool)
- BIND2(lightmap_set_probe_bounds, RID, const AABB &)
- BIND2(lightmap_set_probe_interior, RID, bool)
- BIND5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &)
- BIND1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID)
- BIND1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID)
- BIND1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID)
- BIND1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID)
- BIND1(lightmap_set_probe_capture_update_speed, float)
+ FUNC3(lightmap_set_textures, RID, RID, bool)
+ FUNC2(lightmap_set_probe_bounds, RID, const AABB &)
+ FUNC2(lightmap_set_probe_interior, RID, bool)
+ FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &)
+ FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID)
+ FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID)
+ FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID)
+ FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID)
+ FUNC1(lightmap_set_probe_capture_update_speed, float)
/* PARTICLES */
- BIND0R(RID, particles_create)
-
- BIND2(particles_set_emitting, RID, bool)
- BIND1R(bool, particles_get_emitting, RID)
- BIND2(particles_set_amount, RID, int)
- BIND2(particles_set_lifetime, RID, float)
- BIND2(particles_set_one_shot, RID, bool)
- BIND2(particles_set_pre_process_time, RID, float)
- BIND2(particles_set_explosiveness_ratio, RID, float)
- BIND2(particles_set_randomness_ratio, RID, float)
- BIND2(particles_set_custom_aabb, RID, const AABB &)
- BIND2(particles_set_speed_scale, RID, float)
- BIND2(particles_set_use_local_coordinates, RID, bool)
- BIND2(particles_set_process_material, RID, RID)
- BIND2(particles_set_fixed_fps, RID, int)
- BIND2(particles_set_fractional_delta, RID, bool)
- BIND1R(bool, particles_is_inactive, RID)
- BIND1(particles_request_process, RID)
- BIND1(particles_restart, RID)
- BIND6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t)
- BIND2(particles_set_subemitter, RID, RID)
- BIND2(particles_set_collision_base_size, RID, float)
-
- BIND2(particles_set_draw_order, RID, RS::ParticlesDrawOrder)
-
- BIND2(particles_set_draw_passes, RID, int)
- BIND3(particles_set_draw_pass_mesh, RID, int, RID)
-
- BIND1R(AABB, particles_get_current_aabb, RID)
- BIND2(particles_set_emission_transform, RID, const Transform &)
+ FUNCRIDSPLIT(particles)
+
+ FUNC2(particles_set_emitting, RID, bool)
+ FUNC1R(bool, particles_get_emitting, RID)
+ FUNC2(particles_set_amount, RID, int)
+ FUNC2(particles_set_lifetime, RID, float)
+ FUNC2(particles_set_one_shot, RID, bool)
+ FUNC2(particles_set_pre_process_time, RID, float)
+ FUNC2(particles_set_explosiveness_ratio, RID, float)
+ FUNC2(particles_set_randomness_ratio, RID, float)
+ FUNC2(particles_set_custom_aabb, RID, const AABB &)
+ FUNC2(particles_set_speed_scale, RID, float)
+ FUNC2(particles_set_use_local_coordinates, RID, bool)
+ FUNC2(particles_set_process_material, RID, RID)
+ FUNC2(particles_set_fixed_fps, RID, int)
+ FUNC2(particles_set_fractional_delta, RID, bool)
+ FUNC1R(bool, particles_is_inactive, RID)
+ FUNC1(particles_request_process, RID)
+ FUNC1(particles_restart, RID)
+ FUNC6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t)
+ FUNC2(particles_set_subemitter, RID, RID)
+ FUNC2(particles_set_collision_base_size, RID, float)
+
+ FUNC2(particles_set_draw_order, RID, RS::ParticlesDrawOrder)
+
+ FUNC2(particles_set_draw_passes, RID, int)
+ FUNC3(particles_set_draw_pass_mesh, RID, int, RID)
+
+ FUNC1R(AABB, particles_get_current_aabb, RID)
+ FUNC2(particles_set_emission_transform, RID, const Transform &)
/* PARTICLES COLLISION */
- BIND0R(RID, particles_collision_create)
-
- BIND2(particles_collision_set_collision_type, RID, ParticlesCollisionType)
- BIND2(particles_collision_set_cull_mask, RID, uint32_t)
- BIND2(particles_collision_set_sphere_radius, RID, float)
- BIND2(particles_collision_set_box_extents, RID, const Vector3 &)
- BIND2(particles_collision_set_attractor_strength, RID, float)
- BIND2(particles_collision_set_attractor_directionality, RID, float)
- BIND2(particles_collision_set_attractor_attenuation, RID, float)
- BIND2(particles_collision_set_field_texture, RID, RID)
- BIND1(particles_collision_height_field_update, RID)
- BIND2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution)
-
-#undef BINDBASE
+ FUNCRIDSPLIT(particles_collision)
+
+ FUNC2(particles_collision_set_collision_type, RID, ParticlesCollisionType)
+ FUNC2(particles_collision_set_cull_mask, RID, uint32_t)
+ FUNC2(particles_collision_set_sphere_radius, RID, float)
+ FUNC2(particles_collision_set_box_extents, RID, const Vector3 &)
+ FUNC2(particles_collision_set_attractor_strength, RID, float)
+ FUNC2(particles_collision_set_attractor_directionality, RID, float)
+ FUNC2(particles_collision_set_attractor_attenuation, RID, float)
+ FUNC2(particles_collision_set_field_texture, RID, RID)
+ FUNC1(particles_collision_height_field_update, RID)
+ FUNC2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution)
+
+#undef server_name
+#undef ServerName
//from now on, calls forwarded to this singleton
-#define BINDBASE RSG::scene
+#define ServerName RendererScene
+#define server_name RSG::scene
/* CAMERA API */
- BIND0R(RID, camera_create)
- BIND4(camera_set_perspective, RID, float, float, float)
- BIND4(camera_set_orthogonal, RID, float, float, float)
- BIND5(camera_set_frustum, RID, float, Vector2, float, float)
- BIND2(camera_set_transform, RID, const Transform &)
- BIND2(camera_set_cull_mask, RID, uint32_t)
- BIND2(camera_set_environment, RID, RID)
- BIND2(camera_set_camera_effects, RID, RID)
- BIND2(camera_set_use_vertical_aspect, RID, bool)
-
-#undef BINDBASE
+ FUNCRIDSPLIT(camera)
+ FUNC4(camera_set_perspective, RID, float, float, float)
+ FUNC4(camera_set_orthogonal, RID, float, float, float)
+ FUNC5(camera_set_frustum, RID, float, Vector2, float, float)
+ FUNC2(camera_set_transform, RID, const Transform &)
+ FUNC2(camera_set_cull_mask, RID, uint32_t)
+ FUNC2(camera_set_environment, RID, RID)
+ FUNC2(camera_set_camera_effects, RID, RID)
+ FUNC2(camera_set_use_vertical_aspect, RID, bool)
+
+#undef server_name
+#undef ServerName
//from now on, calls forwarded to this singleton
-#define BINDBASE RSG::viewport
+#define ServerName RendererViewport
+#define server_name RSG::viewport
/* VIEWPORT TARGET API */
- BIND0R(RID, viewport_create)
+ FUNCRIDSPLIT(viewport)
+
+ FUNC2(viewport_set_use_xr, RID, bool)
+ FUNC3(viewport_set_size, RID, int, int)
- BIND2(viewport_set_use_xr, RID, bool)
- BIND3(viewport_set_size, RID, int, int)
+ FUNC2(viewport_set_active, RID, bool)
+ FUNC2(viewport_set_parent_viewport, RID, RID)
- BIND2(viewport_set_active, RID, bool)
- BIND2(viewport_set_parent_viewport, RID, RID)
+ FUNC2(viewport_set_clear_mode, RID, ViewportClearMode)
- BIND2(viewport_set_clear_mode, RID, ViewportClearMode)
+ FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int)
+ FUNC2(viewport_set_render_direct_to_screen, RID, bool)
- BIND3(viewport_attach_to_screen, RID, const Rect2 &, int)
- BIND2(viewport_set_render_direct_to_screen, RID, bool)
+ FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode)
- BIND2(viewport_set_update_mode, RID, ViewportUpdateMode)
- BIND2(viewport_set_vflip, RID, bool)
+ FUNC1RC(RID, viewport_get_texture, RID)
- BIND1RC(RID, viewport_get_texture, RID)
+ FUNC2(viewport_set_hide_scenario, RID, bool)
+ FUNC2(viewport_set_hide_canvas, RID, bool)
+ FUNC2(viewport_set_disable_environment, RID, bool)
- BIND2(viewport_set_hide_scenario, RID, bool)
- BIND2(viewport_set_hide_canvas, RID, bool)
- BIND2(viewport_set_disable_environment, RID, bool)
+ FUNC2(viewport_attach_camera, RID, RID)
+ FUNC2(viewport_set_scenario, RID, RID)
+ FUNC2(viewport_attach_canvas, RID, RID)
- BIND2(viewport_attach_camera, RID, RID)
- BIND2(viewport_set_scenario, RID, RID)
- BIND2(viewport_attach_canvas, RID, RID)
+ FUNC2(viewport_remove_canvas, RID, RID)
+ FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
+ FUNC2(viewport_set_transparent_background, RID, bool)
+ FUNC2(viewport_set_snap_2d_transforms_to_pixel, RID, bool)
+ FUNC2(viewport_set_snap_2d_vertices_to_pixel, RID, bool)
- BIND2(viewport_remove_canvas, RID, RID)
- BIND3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
- BIND2(viewport_set_transparent_background, RID, bool)
- BIND2(viewport_set_snap_2d_transforms_to_pixel, RID, bool)
- BIND2(viewport_set_snap_2d_vertices_to_pixel, RID, bool)
+ FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter)
+ FUNC2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat)
- BIND2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter)
- BIND2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat)
+ FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
+ FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
+ FUNC3(viewport_set_shadow_atlas_size, RID, int, bool)
+ FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale)
+ FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
+ FUNC2(viewport_set_msaa, RID, ViewportMSAA)
+ FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
+ FUNC2(viewport_set_use_debanding, RID, bool)
+ FUNC2(viewport_set_lod_threshold, RID, float)
- BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &)
- BIND4(viewport_set_canvas_stacking, RID, RID, int, int)
- BIND2(viewport_set_shadow_atlas_size, RID, int)
- BIND3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale)
- BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
- BIND2(viewport_set_msaa, RID, ViewportMSAA)
- BIND2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
- BIND2(viewport_set_use_debanding, RID, bool)
- BIND2(viewport_set_lod_threshold, RID, float)
+ FUNC2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
+ FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
- BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
- BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw)
+ FUNC2(viewport_set_measure_render_time, RID, bool)
+ FUNC1RC(float, viewport_get_measured_render_time_cpu, RID)
+ FUNC1RC(float, viewport_get_measured_render_time_gpu, RID)
- BIND2(viewport_set_measure_render_time, RID, bool)
- BIND1RC(float, viewport_get_measured_render_time_cpu, RID)
- BIND1RC(float, viewport_get_measured_render_time_gpu, RID)
+ FUNC1(call_set_use_vsync, bool)
/* ENVIRONMENT API */
-#undef BINDBASE
+#undef server_name
+#undef ServerName
//from now on, calls forwarded to this singleton
-#define BINDBASE RSG::scene
+#define ServerName RendererScene
+#define server_name RSG::scene
- BIND1(directional_shadow_atlas_set_size, int)
- BIND1(gi_probe_set_quality, GIProbeQuality)
+ FUNC2(directional_shadow_atlas_set_size, int, bool)
+ FUNC1(gi_probe_set_quality, GIProbeQuality)
/* SKY API */
- BIND0R(RID, sky_create)
- BIND2(sky_set_radiance_size, RID, int)
- BIND2(sky_set_mode, RID, SkyMode)
- BIND2(sky_set_material, RID, RID)
- BIND4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
+ FUNCRIDSPLIT(sky)
+ FUNC2(sky_set_radiance_size, RID, int)
+ FUNC2(sky_set_mode, RID, SkyMode)
+ FUNC2(sky_set_material, RID, RID)
+ FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
- BIND0R(RID, environment_create)
+ FUNCRIDSPLIT(environment)
- BIND2(environment_set_background, RID, EnvironmentBG)
- BIND2(environment_set_sky, RID, RID)
- BIND2(environment_set_sky_custom_fov, RID, float)
- BIND2(environment_set_sky_orientation, RID, const Basis &)
- BIND2(environment_set_bg_color, RID, const Color &)
- BIND2(environment_set_bg_energy, RID, float)
- BIND2(environment_set_canvas_max_layer, RID, int)
- BIND7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &)
+ FUNC2(environment_set_background, RID, EnvironmentBG)
+ FUNC2(environment_set_sky, RID, RID)
+ FUNC2(environment_set_sky_custom_fov, RID, float)
+ FUNC2(environment_set_sky_orientation, RID, const Basis &)
+ FUNC2(environment_set_bg_color, RID, const Color &)
+ FUNC2(environment_set_bg_energy, RID, float)
+ FUNC2(environment_set_canvas_max_layer, RID, int)
+ FUNC7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &)
// FIXME: Disabled during Vulkan refactoring, should be ported.
#if 0
- BIND2(environment_set_camera_feed_id, RID, int)
+ FUNC2(environment_set_camera_feed_id, RID, int)
#endif
- BIND6(environment_set_ssr, RID, bool, int, float, float, float)
- BIND1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality)
+ FUNC6(environment_set_ssr, RID, bool, int, float, float, float)
+ FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality)
- BIND10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float)
- BIND6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float)
+ FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float)
+ FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float)
- BIND11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
- BIND1(environment_glow_set_use_bicubic_upscale, bool)
- BIND1(environment_glow_set_use_high_quality, bool)
+ FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
+ FUNC1(environment_glow_set_use_bicubic_upscale, bool)
+ FUNC1(environment_glow_set_use_high_quality, bool)
- BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
+ FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
- BIND7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
+ FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
- BIND9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
- BIND9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter)
+ FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
+ FUNC10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float)
- BIND2(environment_set_volumetric_fog_volume_size, int, int)
- BIND1(environment_set_volumetric_fog_filter_active, bool)
- BIND1(environment_set_volumetric_fog_directional_shadow_shrink_size, int)
- BIND1(environment_set_volumetric_fog_positional_shadow_shrink_size, int)
+ FUNC2(environment_set_volumetric_fog_volume_size, int, int)
+ FUNC1(environment_set_volumetric_fog_filter_active, bool)
- BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
- BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
- BIND1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge)
+ FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, float, bool, float, float, float)
+ FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
+ FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge)
+ FUNC1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight)
- BIND3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
+ FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
- BIND3(screen_space_roughness_limiter_set_active, bool, float, float)
- BIND1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality)
- BIND2(sub_surface_scattering_set_scale, float, float)
+ FUNC3(screen_space_roughness_limiter_set_active, bool, float, float)
+ FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality)
+ FUNC2(sub_surface_scattering_set_scale, float, float)
/* CAMERA EFFECTS */
- BIND0R(RID, camera_effects_create)
+ FUNCRIDSPLIT(camera_effects)
- BIND2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool)
- BIND1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape)
+ FUNC2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool)
+ FUNC1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape)
- BIND8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float)
- BIND3(camera_effects_set_custom_exposure, RID, bool, float)
+ FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float)
+ FUNC3(camera_effects_set_custom_exposure, RID, bool, float)
- BIND1(shadows_quality_set, ShadowQuality);
- BIND1(directional_shadow_quality_set, ShadowQuality);
+ FUNC1(shadows_quality_set, ShadowQuality);
+ FUNC1(directional_shadow_quality_set, ShadowQuality);
/* SCENARIO API */
-#undef BINDBASE
-#define BINDBASE RSG::scene
+#undef server_name
+#undef ServerName
- BIND0R(RID, scenario_create)
+#define ServerName RendererScene
+#define server_name RSG::scene
- BIND2(scenario_set_debug, RID, ScenarioDebugMode)
- BIND2(scenario_set_environment, RID, RID)
- BIND2(scenario_set_camera_effects, RID, RID)
- BIND2(scenario_set_fallback_environment, RID, RID)
+ FUNCRIDSPLIT(scenario)
+
+ FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
+ FUNC2(scenario_set_environment, RID, RID)
+ FUNC2(scenario_set_camera_effects, RID, RID)
+ FUNC2(scenario_set_fallback_environment, RID, RID)
/* INSTANCING API */
- BIND0R(RID, instance_create)
+ FUNCRIDSPLIT(instance)
- BIND2(instance_set_base, RID, RID)
- BIND2(instance_set_scenario, RID, RID)
- BIND2(instance_set_layer_mask, RID, uint32_t)
- BIND2(instance_set_transform, RID, const Transform &)
- BIND2(instance_attach_object_instance_id, RID, ObjectID)
- BIND3(instance_set_blend_shape_weight, RID, int, float)
- BIND3(instance_set_surface_material, RID, int, RID)
- BIND2(instance_set_visible, RID, bool)
+ FUNC2(instance_set_base, RID, RID)
+ FUNC2(instance_set_scenario, RID, RID)
+ FUNC2(instance_set_layer_mask, RID, uint32_t)
+ FUNC2(instance_set_transform, RID, const Transform &)
+ FUNC2(instance_attach_object_instance_id, RID, ObjectID)
+ FUNC3(instance_set_blend_shape_weight, RID, int, float)
+ FUNC3(instance_set_surface_material, RID, int, RID)
+ FUNC2(instance_set_visible, RID, bool)
- BIND2(instance_set_custom_aabb, RID, AABB)
+ FUNC2(instance_set_custom_aabb, RID, AABB)
- BIND2(instance_attach_skeleton, RID, RID)
- BIND2(instance_set_exterior, RID, bool)
+ FUNC2(instance_attach_skeleton, RID, RID)
+ FUNC2(instance_set_exterior, RID, bool)
- BIND2(instance_set_extra_visibility_margin, RID, real_t)
+ FUNC2(instance_set_extra_visibility_margin, RID, real_t)
// don't use these in a game!
- BIND2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID)
- BIND3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID)
- BIND2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID)
+ FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID)
+ FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID)
+ FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID)
+
+ FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool)
+ FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
+ FUNC2(instance_geometry_set_material_override, RID, RID)
- BIND3(instance_geometry_set_flag, RID, InstanceFlags, bool)
- BIND2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
- BIND2(instance_geometry_set_material_override, RID, RID)
+ FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float)
+ FUNC2(instance_geometry_set_as_instance_lod, RID, RID)
+ FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
+ FUNC2(instance_geometry_set_lod_bias, RID, float)
- BIND5(instance_geometry_set_draw_range, RID, float, float, float, float)
- BIND2(instance_geometry_set_as_instance_lod, RID, RID)
- BIND4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
- BIND2(instance_geometry_set_lod_bias, RID, float)
+ FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
+ FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
+ FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &)
+ FUNC2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *)
- BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
- BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
- BIND2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &)
- BIND2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *)
+ FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &)
- BIND3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &)
+ FUNC1(gi_set_use_half_resolution, bool)
-#undef BINDBASE
+#undef server_name
+#undef ServerName
//from now on, calls forwarded to this singleton
-#define BINDBASE RSG::canvas
+#define ServerName RendererCanvasCull
+#define server_name RSG::canvas
/* CANVAS (2D) */
- BIND0R(RID, canvas_create)
- BIND3(canvas_set_item_mirroring, RID, RID, const Point2 &)
- BIND2(canvas_set_modulate, RID, const Color &)
- BIND3(canvas_set_parent, RID, RID, float)
- BIND1(canvas_set_disable_scale, bool)
-
- BIND0R(RID, canvas_texture_create)
- BIND3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID)
- BIND3(canvas_texture_set_shading_parameters, RID, const Color &, float)
-
- BIND2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter)
- BIND2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat)
-
- BIND0R(RID, canvas_item_create)
- BIND2(canvas_item_set_parent, RID, RID)
-
- BIND2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter)
- BIND2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat)
-
- BIND2(canvas_item_set_visible, RID, bool)
- BIND2(canvas_item_set_light_mask, RID, int)
-
- BIND2(canvas_item_set_update_when_visible, RID, bool)
-
- BIND2(canvas_item_set_transform, RID, const Transform2D &)
- BIND2(canvas_item_set_clip, RID, bool)
- BIND2(canvas_item_set_distance_field_mode, RID, bool)
- BIND3(canvas_item_set_custom_rect, RID, bool, const Rect2 &)
- BIND2(canvas_item_set_modulate, RID, const Color &)
- BIND2(canvas_item_set_self_modulate, RID, const Color &)
-
- BIND2(canvas_item_set_draw_behind_parent, RID, bool)
-
- BIND5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float)
- BIND5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
- BIND4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float)
- BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
- BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
- BIND6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
- BIND7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool)
- BIND10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
- BIND6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
- BIND5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
- BIND9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int)
- BIND5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID)
- BIND3(canvas_item_add_multimesh, RID, RID, RID)
- BIND3(canvas_item_add_particles, RID, RID, RID)
- BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
- BIND2(canvas_item_add_clip_ignore, RID, bool)
- BIND2(canvas_item_set_sort_children_by_y, RID, bool)
- BIND2(canvas_item_set_z_index, RID, int)
- BIND2(canvas_item_set_z_as_relative_to_parent, RID, bool)
- BIND3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
- BIND2(canvas_item_attach_skeleton, RID, RID)
-
- BIND1(canvas_item_clear, RID)
- BIND2(canvas_item_set_draw_index, RID, int)
-
- BIND2(canvas_item_set_material, RID, RID)
-
- BIND2(canvas_item_set_use_parent_material, RID, bool)
-
- BIND6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool)
-
- BIND0R(RID, canvas_light_create)
-
- BIND2(canvas_light_set_mode, RID, CanvasLightMode)
-
- BIND2(canvas_light_attach_to_canvas, RID, RID)
- BIND2(canvas_light_set_enabled, RID, bool)
- BIND2(canvas_light_set_texture_scale, RID, float)
- BIND2(canvas_light_set_transform, RID, const Transform2D &)
- BIND2(canvas_light_set_texture, RID, RID)
- BIND2(canvas_light_set_texture_offset, RID, const Vector2 &)
- BIND2(canvas_light_set_color, RID, const Color &)
- BIND2(canvas_light_set_height, RID, float)
- BIND2(canvas_light_set_energy, RID, float)
- BIND3(canvas_light_set_z_range, RID, int, int)
- BIND3(canvas_light_set_layer_range, RID, int, int)
- BIND2(canvas_light_set_item_cull_mask, RID, int)
- BIND2(canvas_light_set_item_shadow_cull_mask, RID, int)
- BIND2(canvas_light_set_directional_distance, RID, float)
-
- BIND2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode)
-
- BIND2(canvas_light_set_shadow_enabled, RID, bool)
- BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
- BIND2(canvas_light_set_shadow_color, RID, const Color &)
- BIND2(canvas_light_set_shadow_smooth, RID, float)
-
- BIND0R(RID, canvas_light_occluder_create)
- BIND2(canvas_light_occluder_attach_to_canvas, RID, RID)
- BIND2(canvas_light_occluder_set_enabled, RID, bool)
- BIND2(canvas_light_occluder_set_polygon, RID, RID)
- BIND2(canvas_light_occluder_set_as_sdf_collision, RID, bool)
- BIND2(canvas_light_occluder_set_transform, RID, const Transform2D &)
- BIND2(canvas_light_occluder_set_light_mask, RID, int)
-
- BIND0R(RID, canvas_occluder_polygon_create)
- BIND3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool)
-
- BIND2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
-
- BIND1(canvas_set_shadow_texture_size, int)
+ FUNCRIDSPLIT(canvas)
+ FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &)
+ FUNC2(canvas_set_modulate, RID, const Color &)
+ FUNC3(canvas_set_parent, RID, RID, float)
+ FUNC1(canvas_set_disable_scale, bool)
+
+ FUNCRIDSPLIT(canvas_texture)
+ FUNC3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID)
+ FUNC3(canvas_texture_set_shading_parameters, RID, const Color &, float)
+
+ FUNC2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter)
+ FUNC2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat)
+
+ FUNCRIDSPLIT(canvas_item)
+ FUNC2(canvas_item_set_parent, RID, RID)
+
+ FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter)
+ FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat)
+
+ FUNC2(canvas_item_set_visible, RID, bool)
+ FUNC2(canvas_item_set_light_mask, RID, int)
+
+ FUNC2(canvas_item_set_update_when_visible, RID, bool)
+
+ FUNC2(canvas_item_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_item_set_clip, RID, bool)
+ FUNC2(canvas_item_set_distance_field_mode, RID, bool)
+ FUNC3(canvas_item_set_custom_rect, RID, bool, const Rect2 &)
+ FUNC2(canvas_item_set_modulate, RID, const Color &)
+ FUNC2(canvas_item_set_self_modulate, RID, const Color &)
+
+ FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
+
+ FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float)
+ FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
+ FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float)
+ FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
+ FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
+ FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
+ FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool)
+ FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
+ FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
+ FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
+ FUNC9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int)
+ FUNC5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID)
+ FUNC3(canvas_item_add_multimesh, RID, RID, RID)
+ FUNC3(canvas_item_add_particles, RID, RID, RID)
+ FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_item_add_clip_ignore, RID, bool)
+ FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
+ FUNC2(canvas_item_set_z_index, RID, int)
+ FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool)
+ FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
+ FUNC2(canvas_item_attach_skeleton, RID, RID)
+
+ FUNC1(canvas_item_clear, RID)
+ FUNC2(canvas_item_set_draw_index, RID, int)
+
+ FUNC2(canvas_item_set_material, RID, RID)
+
+ FUNC2(canvas_item_set_use_parent_material, RID, bool)
+
+ FUNC6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool)
+
+ FUNCRIDSPLIT(canvas_light)
+
+ FUNC2(canvas_light_set_mode, RID, CanvasLightMode)
+
+ FUNC2(canvas_light_attach_to_canvas, RID, RID)
+ FUNC2(canvas_light_set_enabled, RID, bool)
+ FUNC2(canvas_light_set_texture_scale, RID, float)
+ FUNC2(canvas_light_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_light_set_texture, RID, RID)
+ FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &)
+ FUNC2(canvas_light_set_color, RID, const Color &)
+ FUNC2(canvas_light_set_height, RID, float)
+ FUNC2(canvas_light_set_energy, RID, float)
+ FUNC3(canvas_light_set_z_range, RID, int, int)
+ FUNC3(canvas_light_set_layer_range, RID, int, int)
+ FUNC2(canvas_light_set_item_cull_mask, RID, int)
+ FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int)
+ FUNC2(canvas_light_set_directional_distance, RID, float)
+
+ FUNC2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode)
+
+ FUNC2(canvas_light_set_shadow_enabled, RID, bool)
+ FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
+ FUNC2(canvas_light_set_shadow_color, RID, const Color &)
+ FUNC2(canvas_light_set_shadow_smooth, RID, float)
+
+ FUNCRIDSPLIT(canvas_light_occluder)
+ FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID)
+ FUNC2(canvas_light_occluder_set_enabled, RID, bool)
+ FUNC2(canvas_light_occluder_set_polygon, RID, RID)
+ FUNC2(canvas_light_occluder_set_as_sdf_collision, RID, bool)
+ FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_light_occluder_set_light_mask, RID, int)
+
+ FUNCRIDSPLIT(canvas_occluder_polygon)
+ FUNC3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool)
+
+ FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
+
+ FUNC1(canvas_set_shadow_texture_size, int)
/* GLOBAL VARIABLES */
-#undef BINDBASE
+#undef server_name
+#undef ServerName
//from now on, calls forwarded to this singleton
-#define BINDBASE RSG::storage
+#define ServerName RendererStorage
+#define server_name RSG::storage
- BIND3(global_variable_add, const StringName &, GlobalVariableType, const Variant &)
- BIND1(global_variable_remove, const StringName &)
- BIND0RC(Vector<StringName>, global_variable_get_list)
- BIND2(global_variable_set, const StringName &, const Variant &)
- BIND2(global_variable_set_override, const StringName &, const Variant &)
- BIND1RC(GlobalVariableType, global_variable_get_type, const StringName &)
- BIND1RC(Variant, global_variable_get, const StringName &)
+ FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &)
+ FUNC1(global_variable_remove, const StringName &)
+ FUNC0RC(Vector<StringName>, global_variable_get_list)
+ FUNC2(global_variable_set, const StringName &, const Variant &)
+ FUNC2(global_variable_set_override, const StringName &, const Variant &)
+ FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &)
+ FUNC1RC(Variant, global_variable_get, const StringName &)
- BIND1(global_variables_load_settings, bool)
- BIND0(global_variables_clear)
+ FUNC1(global_variables_load_settings, bool)
+ FUNC0(global_variables_clear)
+
+#undef server_name
+#undef ServerName
+#undef WRITE_ACTION
+#undef SYNC_DEBUG
/* BLACK BARS */
- virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom);
- virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom);
+ virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) override;
+ virtual void black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) override;
/* FREE */
- virtual void free(RID p_rid); ///< free RIDs associated with the visual server
+ virtual void free(RID p_rid) override {
+ if (Thread::get_caller_id() == server_thread) {
+ command_queue.flush_if_pending();
+ _free(p_rid);
+ } else {
+ command_queue.push(this, &RenderingServerDefault::_free, p_rid);
+ }
+ }
/* EVENT QUEUING */
- virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata);
+ virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) override;
- virtual void draw(bool p_swap_buffers, double frame_step);
- virtual void sync();
- virtual bool has_changed() const;
- virtual void init();
- virtual void finish();
+ virtual void draw(bool p_swap_buffers, double frame_step) override;
+ virtual void sync() override;
+ virtual bool has_changed() const override;
+ virtual void init() override;
+ virtual void finish() override;
/* STATUS INFORMATION */
- virtual int get_render_info(RenderInfo p_info);
- virtual String get_video_adapter_name() const;
- virtual String get_video_adapter_vendor() const;
+ virtual uint64_t get_render_info(RenderInfo p_info) override;
+ virtual String get_video_adapter_name() const override;
+ virtual String get_video_adapter_vendor() const override;
- virtual void set_frame_profiling_enabled(bool p_enable);
- virtual Vector<FrameProfileArea> get_frame_profile();
- virtual uint64_t get_frame_profile_frame();
+ virtual void set_frame_profiling_enabled(bool p_enable) override;
+ virtual Vector<FrameProfileArea> get_frame_profile() override;
+ virtual uint64_t get_frame_profile_frame() override;
- virtual RID get_test_cube();
+ virtual RID get_test_cube() override;
/* TESTING */
- virtual float get_frame_setup_time_cpu() const;
+ virtual float get_frame_setup_time_cpu() const override;
- virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true);
- virtual void set_default_clear_color(const Color &p_color);
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override;
+ virtual void set_default_clear_color(const Color &p_color) override;
- virtual bool has_feature(Features p_feature) const;
+ virtual bool has_feature(Features p_feature) const override;
- virtual bool has_os_feature(const String &p_feature) const;
- virtual void set_debug_generate_wireframes(bool p_generate);
+ virtual bool has_os_feature(const String &p_feature) const override;
+ virtual void set_debug_generate_wireframes(bool p_generate) override;
- virtual void call_set_use_vsync(bool p_enable);
+ virtual bool is_low_end() const override;
- virtual bool is_low_end() const;
+ virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override;
- virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir);
+ virtual void set_print_gpu_profile(bool p_enable) override;
- RenderingServerDefault();
+ RenderingServerDefault(bool p_create_thread = false);
~RenderingServerDefault();
-
-#undef DISPLAY_CHANGED
-
-#undef BIND0R
-#undef BIND1RC
-#undef BIND2RC
-#undef BIND3RC
-#undef BIND4RC
-
-#undef BIND1
-#undef BIND2
-#undef BIND3
-#undef BIND4
-#undef BIND5
-#undef BIND6
-#undef BIND7
-#undef BIND8
-#undef BIND9
-#undef BIND10
};
#endif
diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp
index b9df36e93a..c0d9988e85 100644
--- a/servers/rendering/rendering_server_globals.cpp
+++ b/servers/rendering/rendering_server_globals.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h
index 580526f7e0..a28a0f5180 100644
--- a/servers/rendering/rendering_server_globals.h
+++ b/servers/rendering/rendering_server_globals.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp
deleted file mode 100644
index 40ad228fd0..0000000000
--- a/servers/rendering/rendering_server_wrap_mt.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/*************************************************************************/
-/* rendering_server_wrap_mt.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "rendering_server_wrap_mt.h"
-#include "core/config/project_settings.h"
-#include "core/os/os.h"
-#include "servers/display_server.h"
-
-void RenderingServerWrapMT::thread_exit() {
- exit = true;
-}
-
-void RenderingServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) {
- if (!atomic_decrement(&draw_pending)) {
- rendering_server->draw(p_swap_buffers, frame_step);
- }
-}
-
-void RenderingServerWrapMT::thread_flush() {
- atomic_decrement(&draw_pending);
-}
-
-void RenderingServerWrapMT::_thread_callback(void *_instance) {
- RenderingServerWrapMT *vsmt = reinterpret_cast<RenderingServerWrapMT *>(_instance);
-
- vsmt->thread_loop();
-}
-
-void RenderingServerWrapMT::thread_loop() {
- server_thread = Thread::get_caller_id();
-
- DisplayServer::get_singleton()->make_rendering_thread();
-
- rendering_server->init();
-
- exit = false;
- draw_thread_up = true;
- while (!exit) {
- // flush commands one by one, until exit is requested
- command_queue.wait_and_flush_one();
- }
-
- command_queue.flush_all(); // flush all
-
- rendering_server->finish();
-}
-
-/* EVENT QUEUING */
-
-void RenderingServerWrapMT::sync() {
- if (create_thread) {
- atomic_increment(&draw_pending);
- command_queue.push_and_sync(this, &RenderingServerWrapMT::thread_flush);
- } else {
- command_queue.flush_all(); //flush all pending from other threads
- }
-}
-
-void RenderingServerWrapMT::draw(bool p_swap_buffers, double frame_step) {
- if (create_thread) {
- atomic_increment(&draw_pending);
- command_queue.push(this, &RenderingServerWrapMT::thread_draw, p_swap_buffers, frame_step);
- } else {
- rendering_server->draw(p_swap_buffers, frame_step);
- }
-}
-
-void RenderingServerWrapMT::init() {
- if (create_thread) {
- print_verbose("RenderingServerWrapMT: Creating render thread");
- DisplayServer::get_singleton()->release_rendering_thread();
- if (create_thread) {
- thread = Thread::create(_thread_callback, this);
- print_verbose("RenderingServerWrapMT: Starting render thread");
- }
- while (!draw_thread_up) {
- OS::get_singleton()->delay_usec(1000);
- }
- print_verbose("RenderingServerWrapMT: Finished render thread");
- } else {
- rendering_server->init();
- }
-}
-
-void RenderingServerWrapMT::finish() {
- sky_free_cached_ids();
- shader_free_cached_ids();
- material_free_cached_ids();
- mesh_free_cached_ids();
- multimesh_free_cached_ids();
- immediate_free_cached_ids();
- skeleton_free_cached_ids();
- directional_light_free_cached_ids();
- omni_light_free_cached_ids();
- spot_light_free_cached_ids();
- reflection_probe_free_cached_ids();
- gi_probe_free_cached_ids();
- lightmap_free_cached_ids();
- particles_free_cached_ids();
- particles_collision_free_cached_ids();
- camera_free_cached_ids();
- viewport_free_cached_ids();
- environment_free_cached_ids();
- camera_effects_free_cached_ids();
- scenario_free_cached_ids();
- instance_free_cached_ids();
- canvas_free_cached_ids();
- canvas_item_free_cached_ids();
- canvas_light_occluder_free_cached_ids();
- canvas_occluder_polygon_free_cached_ids();
-
- if (thread) {
- command_queue.push(this, &RenderingServerWrapMT::thread_exit);
- Thread::wait_to_finish(thread);
- memdelete(thread);
-
- thread = nullptr;
- } else {
- rendering_server->finish();
- }
-}
-
-void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) {
- singleton_mt->call_set_use_vsync(p_enable);
-}
-
-RenderingServerWrapMT *RenderingServerWrapMT::singleton_mt = nullptr;
-
-RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread) :
- command_queue(p_create_thread) {
- singleton_mt = this;
- DisplayServer::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly
-
- rendering_server = p_contained;
- create_thread = p_create_thread;
- thread = nullptr;
- draw_pending = 0;
- draw_thread_up = false;
- pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
-
- if (!p_create_thread) {
- server_thread = Thread::get_caller_id();
- } else {
- server_thread = 0;
- }
-}
-
-RenderingServerWrapMT::~RenderingServerWrapMT() {
- memdelete(rendering_server);
- //finish();
-}
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
deleted file mode 100644
index 1e6c3b8f71..0000000000
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ /dev/null
@@ -1,800 +0,0 @@
-/*************************************************************************/
-/* rendering_server_wrap_mt.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef RENDERING_SERVER_WRAP_MT_H
-#define RENDERING_SERVER_WRAP_MT_H
-
-#include "core/os/thread.h"
-#include "core/templates/command_queue_mt.h"
-#include "servers/rendering_server.h"
-
-class RenderingServerWrapMT : public RenderingServer {
- // the real visual server
- mutable RenderingServer *rendering_server;
-
- mutable CommandQueueMT command_queue;
-
- static void _thread_callback(void *_instance);
- void thread_loop();
-
- Thread::ID server_thread;
- volatile bool exit;
- Thread *thread;
- volatile bool draw_thread_up;
- bool create_thread;
-
- uint64_t draw_pending;
- void thread_draw(bool p_swap_buffers, double frame_step);
- void thread_flush();
-
- void thread_exit();
-
- Mutex alloc_mutex;
-
- int pool_max_size;
-
- //#define DEBUG_SYNC
-
- static RenderingServerWrapMT *singleton_mt;
-
-#ifdef DEBUG_SYNC
-#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__));
-#else
-#define SYNC_DEBUG
-#endif
-
-public:
-#define ServerName RenderingServer
-#define ServerNameWrapMT RenderingServerWrapMT
-#define server_name rendering_server
-#include "servers/server_wrap_mt_common.h"
-
- //these go pass-through, as they can be called from any thread
- virtual RID texture_2d_create(const Ref<Image> &p_image) { return rendering_server->texture_2d_create(p_image); }
- virtual RID texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, TextureLayeredType p_layered_type) { return rendering_server->texture_2d_layered_create(p_layers, p_layered_type); }
- virtual RID texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { return rendering_server->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); }
- virtual RID texture_proxy_create(RID p_base) { return rendering_server->texture_proxy_create(p_base); }
-
- //goes pass-through
- virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) { rendering_server->texture_2d_update_immediate(p_texture, p_image, p_layer); }
- //these go through command queue if they are in another thread
- FUNC3(texture_2d_update, RID, const Ref<Image> &, int)
- FUNC2(texture_3d_update, RID, const Vector<Ref<Image>> &)
- FUNC2(texture_proxy_update, RID, RID)
-
- //these also go pass-through
- virtual RID texture_2d_placeholder_create() { return rendering_server->texture_2d_placeholder_create(); }
- virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_type) { return rendering_server->texture_2d_layered_placeholder_create(p_type); }
- virtual RID texture_3d_placeholder_create() { return rendering_server->texture_3d_placeholder_create(); }
-
- FUNC1RC(Ref<Image>, texture_2d_get, RID)
- FUNC2RC(Ref<Image>, texture_2d_layer_get, RID, int)
- FUNC1RC(Vector<Ref<Image>>, texture_3d_get, RID)
-
- FUNC2(texture_replace, RID, RID)
-
- FUNC3(texture_set_size_override, RID, int, int)
-// FIXME: Disabled during Vulkan refactoring, should be ported.
-#if 0
- FUNC2(texture_bind, RID, uint32_t)
-#endif
-
- FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
- FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *)
- FUNC3(texture_set_detect_roughness_callback, RID, TextureDetectRoughnessCallback, void *)
-
- FUNC2(texture_set_path, RID, const String &)
- FUNC1RC(String, texture_get_path, RID)
- FUNC1S(texture_debug_usage, List<TextureInfo> *)
-
- FUNC2(texture_set_force_redraw_if_visible, RID, bool)
-
- /* SHADER API */
-
- FUNCRID(shader)
-
- FUNC2(shader_set_code, RID, const String &)
- FUNC1RC(String, shader_get_code, RID)
-
- FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *)
-
- FUNC3(shader_set_default_texture_param, RID, const StringName &, RID)
- FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &)
- FUNC2RC(Variant, shader_get_param_default, RID, const StringName &)
-
- /* COMMON MATERIAL API */
-
- FUNCRID(material)
-
- FUNC2(material_set_shader, RID, RID)
-
- FUNC3(material_set_param, RID, const StringName &, const Variant &)
- FUNC2RC(Variant, material_get_param, RID, const StringName &)
-
- FUNC2(material_set_render_priority, RID, int)
- FUNC2(material_set_next_pass, RID, RID)
-
- /* MESH API */
-
- virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) {
- return rendering_server->mesh_create_from_surfaces(p_surfaces, p_blend_shape_count);
- }
-
- FUNC2(mesh_set_blend_shape_count, RID, int)
-
- FUNCRID(mesh)
-
- FUNC2(mesh_add_surface, RID, const SurfaceData &)
-
- FUNC1RC(int, mesh_get_blend_shape_count, RID)
-
- FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode)
- FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID)
-
- FUNC4(mesh_surface_update_region, RID, int, int, const Vector<uint8_t> &)
-
- FUNC3(mesh_surface_set_material, RID, int, RID)
- FUNC2RC(RID, mesh_surface_get_material, RID, int)
-
- FUNC2RC(SurfaceData, mesh_get_surface, RID, int)
-
- FUNC1RC(int, mesh_get_surface_count, RID)
-
- FUNC2(mesh_set_custom_aabb, RID, const AABB &)
- FUNC1RC(AABB, mesh_get_custom_aabb, RID)
-
- FUNC1(mesh_clear, RID)
-
- /* MULTIMESH API */
-
- FUNCRID(multimesh)
-
- FUNC5(multimesh_allocate, RID, int, MultimeshTransformFormat, bool, bool)
- FUNC1RC(int, multimesh_get_instance_count, RID)
-
- FUNC2(multimesh_set_mesh, RID, RID)
- FUNC3(multimesh_instance_set_transform, RID, int, const Transform &)
- FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &)
- FUNC3(multimesh_instance_set_color, RID, int, const Color &)
- FUNC3(multimesh_instance_set_custom_data, RID, int, const Color &)
-
- FUNC1RC(RID, multimesh_get_mesh, RID)
- FUNC1RC(AABB, multimesh_get_aabb, RID)
-
- FUNC2RC(Transform, multimesh_instance_get_transform, RID, int)
- FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int)
- FUNC2RC(Color, multimesh_instance_get_color, RID, int)
- FUNC2RC(Color, multimesh_instance_get_custom_data, RID, int)
-
- FUNC2(multimesh_set_buffer, RID, const Vector<float> &)
- FUNC1RC(Vector<float>, multimesh_get_buffer, RID)
-
- FUNC2(multimesh_set_visible_instances, RID, int)
- FUNC1RC(int, multimesh_get_visible_instances, RID)
-
- /* IMMEDIATE API */
-
- FUNCRID(immediate)
- FUNC3(immediate_begin, RID, PrimitiveType, RID)
- FUNC2(immediate_vertex, RID, const Vector3 &)
- FUNC2(immediate_normal, RID, const Vector3 &)
- FUNC2(immediate_tangent, RID, const Plane &)
- FUNC2(immediate_color, RID, const Color &)
- FUNC2(immediate_uv, RID, const Vector2 &)
- FUNC2(immediate_uv2, RID, const Vector2 &)
- FUNC1(immediate_end, RID)
- FUNC1(immediate_clear, RID)
- FUNC2(immediate_set_material, RID, RID)
- FUNC1RC(RID, immediate_get_material, RID)
-
- /* SKELETON API */
-
- FUNCRID(skeleton)
- FUNC3(skeleton_allocate, RID, int, bool)
- FUNC1RC(int, skeleton_get_bone_count, RID)
- FUNC3(skeleton_bone_set_transform, RID, int, const Transform &)
- FUNC2RC(Transform, skeleton_bone_get_transform, RID, int)
- FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
- FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
- FUNC2(skeleton_set_base_transform_2d, RID, const Transform2D &)
-
- /* Light API */
-
- FUNCRID(directional_light)
- FUNCRID(omni_light)
- FUNCRID(spot_light)
-
- FUNC2(light_set_color, RID, const Color &)
- FUNC3(light_set_param, RID, LightParam, float)
- FUNC2(light_set_shadow, RID, bool)
- FUNC2(light_set_shadow_color, RID, const Color &)
- FUNC2(light_set_projector, RID, RID)
- FUNC2(light_set_negative, RID, bool)
- FUNC2(light_set_cull_mask, RID, uint32_t)
- FUNC2(light_set_reverse_cull_face_mode, RID, bool)
- FUNC2(light_set_bake_mode, RID, LightBakeMode)
- FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t)
-
- FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode)
-
- FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
- FUNC2(light_directional_set_blend_splits, RID, bool)
- FUNC2(light_directional_set_sky_only, RID, bool)
- FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
-
- /* PROBE API */
-
- FUNCRID(reflection_probe)
-
- FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode)
- FUNC2(reflection_probe_set_intensity, RID, float)
- FUNC2(reflection_probe_set_ambient_color, RID, const Color &)
- FUNC2(reflection_probe_set_ambient_energy, RID, float)
- FUNC2(reflection_probe_set_ambient_mode, RID, ReflectionProbeAmbientMode)
- FUNC2(reflection_probe_set_max_distance, RID, float)
- FUNC2(reflection_probe_set_extents, RID, const Vector3 &)
- FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &)
- FUNC2(reflection_probe_set_as_interior, RID, bool)
- FUNC2(reflection_probe_set_enable_box_projection, RID, bool)
- FUNC2(reflection_probe_set_enable_shadows, RID, bool)
- FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
- FUNC2(reflection_probe_set_resolution, RID, int)
- FUNC2(reflection_probe_set_lod_threshold, RID, float)
-
- /* DECAL API */
-
- FUNCRID(decal)
-
- FUNC2(decal_set_extents, RID, const Vector3 &)
- FUNC3(decal_set_texture, RID, DecalTexture, RID)
- FUNC2(decal_set_emission_energy, RID, float)
- FUNC2(decal_set_albedo_mix, RID, float)
- FUNC2(decal_set_modulate, RID, const Color &)
- FUNC2(decal_set_cull_mask, RID, uint32_t)
- FUNC4(decal_set_distance_fade, RID, bool, float, float)
- FUNC3(decal_set_fade, RID, float, float)
- FUNC2(decal_set_normal_fade, RID, float)
-
- /* BAKED LIGHT API */
-
- FUNCRID(gi_probe)
-
- FUNC8(gi_probe_allocate, RID, const Transform &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &)
-
- FUNC1RC(AABB, gi_probe_get_bounds, RID)
- FUNC1RC(Vector3i, gi_probe_get_octree_size, RID)
- FUNC1RC(Vector<uint8_t>, gi_probe_get_octree_cells, RID)
- FUNC1RC(Vector<uint8_t>, gi_probe_get_data_cells, RID)
- FUNC1RC(Vector<uint8_t>, gi_probe_get_distance_field, RID)
- FUNC1RC(Vector<int>, gi_probe_get_level_counts, RID)
- FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID)
-
- FUNC2(gi_probe_set_dynamic_range, RID, float)
- FUNC1RC(float, gi_probe_get_dynamic_range, RID)
-
- FUNC2(gi_probe_set_propagation, RID, float)
- FUNC1RC(float, gi_probe_get_propagation, RID)
-
- FUNC2(gi_probe_set_energy, RID, float)
- FUNC1RC(float, gi_probe_get_energy, RID)
-
- FUNC2(gi_probe_set_ao, RID, float)
- FUNC1RC(float, gi_probe_get_ao, RID)
-
- FUNC2(gi_probe_set_ao_size, RID, float)
- FUNC1RC(float, gi_probe_get_ao_size, RID)
-
- FUNC2(gi_probe_set_bias, RID, float)
- FUNC1RC(float, gi_probe_get_bias, RID)
-
- FUNC2(gi_probe_set_normal_bias, RID, float)
- FUNC1RC(float, gi_probe_get_normal_bias, RID)
-
- FUNC2(gi_probe_set_interior, RID, bool)
- FUNC1RC(bool, gi_probe_is_interior, RID)
-
- FUNC2(gi_probe_set_use_two_bounces, RID, bool)
- FUNC1RC(bool, gi_probe_is_using_two_bounces, RID)
-
- FUNC2(gi_probe_set_anisotropy_strength, RID, float)
- FUNC1RC(float, gi_probe_get_anisotropy_strength, RID)
-
- FUNC1(gi_probe_set_quality, GIProbeQuality)
-
- /* LIGHTMAP CAPTURE */
-
- FUNCRID(lightmap)
- FUNC3(lightmap_set_textures, RID, RID, bool)
- FUNC2(lightmap_set_probe_bounds, RID, const AABB &)
- FUNC2(lightmap_set_probe_interior, RID, bool)
- FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &)
- FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID)
- FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID)
- FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID)
- FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID)
-
- FUNC1(lightmap_set_probe_capture_update_speed, float)
-
- /* PARTICLES */
-
- FUNCRID(particles)
-
- FUNC2(particles_set_emitting, RID, bool)
- FUNC1R(bool, particles_get_emitting, RID)
- FUNC2(particles_set_amount, RID, int)
- FUNC2(particles_set_lifetime, RID, float)
- FUNC2(particles_set_one_shot, RID, bool)
- FUNC2(particles_set_pre_process_time, RID, float)
- FUNC2(particles_set_explosiveness_ratio, RID, float)
- FUNC2(particles_set_randomness_ratio, RID, float)
- FUNC2(particles_set_custom_aabb, RID, const AABB &)
- FUNC2(particles_set_speed_scale, RID, float)
- FUNC2(particles_set_use_local_coordinates, RID, bool)
- FUNC2(particles_set_process_material, RID, RID)
- FUNC2(particles_set_fixed_fps, RID, int)
- FUNC2(particles_set_fractional_delta, RID, bool)
- FUNC2(particles_set_collision_base_size, RID, float)
-
- FUNC1R(bool, particles_is_inactive, RID)
- FUNC1(particles_request_process, RID)
- FUNC1(particles_restart, RID)
-
- FUNC6(particles_emit, RID, const Transform &, const Vector3 &, const Color &, const Color &, uint32_t)
-
- FUNC2(particles_set_draw_order, RID, RS::ParticlesDrawOrder)
-
- FUNC2(particles_set_draw_passes, RID, int)
- FUNC3(particles_set_draw_pass_mesh, RID, int, RID)
- FUNC2(particles_set_emission_transform, RID, const Transform &)
- FUNC2(particles_set_subemitter, RID, RID)
-
- FUNC1R(AABB, particles_get_current_aabb, RID)
-
- /* PARTICLES COLLISION */
-
- FUNCRID(particles_collision)
-
- FUNC2(particles_collision_set_collision_type, RID, ParticlesCollisionType)
- FUNC2(particles_collision_set_cull_mask, RID, uint32_t)
- FUNC2(particles_collision_set_sphere_radius, RID, float)
- FUNC2(particles_collision_set_box_extents, RID, const Vector3 &)
- FUNC2(particles_collision_set_attractor_strength, RID, float)
- FUNC2(particles_collision_set_attractor_directionality, RID, float)
- FUNC2(particles_collision_set_attractor_attenuation, RID, float)
- FUNC2(particles_collision_set_field_texture, RID, RID)
- FUNC1(particles_collision_height_field_update, RID)
- FUNC2(particles_collision_set_height_field_resolution, RID, ParticlesCollisionHeightfieldResolution)
-
- /* CAMERA API */
-
- FUNCRID(camera)
- FUNC4(camera_set_perspective, RID, float, float, float)
- FUNC4(camera_set_orthogonal, RID, float, float, float)
- FUNC5(camera_set_frustum, RID, float, Vector2, float, float)
- FUNC2(camera_set_transform, RID, const Transform &)
- FUNC2(camera_set_cull_mask, RID, uint32_t)
- FUNC2(camera_set_environment, RID, RID)
- FUNC2(camera_set_camera_effects, RID, RID)
- FUNC2(camera_set_use_vertical_aspect, RID, bool)
-
- /* VIEWPORT TARGET API */
-
- FUNCRID(viewport)
-
- FUNC2(viewport_set_use_xr, RID, bool)
-
- FUNC3(viewport_set_size, RID, int, int)
-
- FUNC2(viewport_set_active, RID, bool)
- FUNC2(viewport_set_parent_viewport, RID, RID)
-
- FUNC2(viewport_set_clear_mode, RID, ViewportClearMode)
-
- FUNC3(viewport_attach_to_screen, RID, const Rect2 &, DisplayServer::WindowID)
- FUNC2(viewport_set_render_direct_to_screen, RID, bool)
-
- FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode)
-
- FUNC1RC(RID, viewport_get_texture, RID)
-
- FUNC2(viewport_set_hide_scenario, RID, bool)
- FUNC2(viewport_set_hide_canvas, RID, bool)
- FUNC2(viewport_set_disable_environment, RID, bool)
-
- FUNC2(viewport_attach_camera, RID, RID)
- FUNC2(viewport_set_scenario, RID, RID)
- FUNC2(viewport_attach_canvas, RID, RID)
-
- FUNC2(viewport_remove_canvas, RID, RID)
- FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
- FUNC2(viewport_set_transparent_background, RID, bool)
- FUNC2(viewport_set_snap_2d_transforms_to_pixel, RID, bool)
- FUNC2(viewport_set_snap_2d_vertices_to_pixel, RID, bool)
-
- FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter)
- FUNC2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat)
-
- FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
- FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
- FUNC2(viewport_set_shadow_atlas_size, RID, int)
- FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale)
-
- FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
- FUNC2(viewport_set_msaa, RID, ViewportMSAA)
- FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
- FUNC2(viewport_set_use_debanding, RID, bool)
-
- FUNC2(viewport_set_lod_threshold, RID, float)
-
- //this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport
- virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) {
- return rendering_server->viewport_get_render_info(p_viewport, p_info);
- }
-
- FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
-
- FUNC2(viewport_set_measure_render_time, RID, bool)
- virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const {
- return rendering_server->viewport_get_measured_render_time_cpu(p_viewport);
- }
- virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const {
- return rendering_server->viewport_get_measured_render_time_gpu(p_viewport);
- }
-
- FUNC1(directional_shadow_atlas_set_size, int)
-
- /* SKY API */
-
- FUNCRID(sky)
- FUNC2(sky_set_radiance_size, RID, int)
- FUNC2(sky_set_mode, RID, SkyMode)
- FUNC2(sky_set_material, RID, RID)
- FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
-
- /* ENVIRONMENT API */
-
- FUNCRID(environment)
-
- FUNC2(environment_set_background, RID, EnvironmentBG)
- FUNC2(environment_set_sky, RID, RID)
- FUNC2(environment_set_sky_custom_fov, RID, float)
- FUNC2(environment_set_sky_orientation, RID, const Basis &)
- FUNC2(environment_set_bg_color, RID, const Color &)
- FUNC2(environment_set_bg_energy, RID, float)
- FUNC2(environment_set_canvas_max_layer, RID, int)
- FUNC7(environment_set_ambient_light, RID, const Color &, EnvironmentAmbientSource, float, float, EnvironmentReflectionSource, const Color &)
-
-// FIXME: Disabled during Vulkan refactoring, should be ported.
-#if 0
- FUNC2(environment_set_camera_feed_id, RID, int)
-#endif
- FUNC6(environment_set_ssr, RID, bool, int, float, float, float)
- FUNC1(environment_set_ssr_roughness_quality, EnvironmentSSRRoughnessQuality)
-
- FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float)
-
- FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float)
-
- FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
- FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
- FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge)
-
- FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
- FUNC1(environment_glow_set_use_bicubic_upscale, bool)
- FUNC1(environment_glow_set_use_high_quality, bool)
-
- FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
-
- FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
-
- FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
-
- FUNC9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter)
-
- FUNC2(environment_set_volumetric_fog_volume_size, int, int)
- FUNC1(environment_set_volumetric_fog_filter_active, bool)
- FUNC1(environment_set_volumetric_fog_directional_shadow_shrink_size, int)
- FUNC1(environment_set_volumetric_fog_positional_shadow_shrink_size, int)
-
- FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
-
- FUNC3(screen_space_roughness_limiter_set_active, bool, float, float)
- FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality)
- FUNC2(sub_surface_scattering_set_scale, float, float)
-
- FUNCRID(camera_effects)
-
- FUNC2(camera_effects_set_dof_blur_quality, DOFBlurQuality, bool)
- FUNC1(camera_effects_set_dof_blur_bokeh_shape, DOFBokehShape)
-
- FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float)
- FUNC3(camera_effects_set_custom_exposure, RID, bool, float)
-
- FUNC1(shadows_quality_set, ShadowQuality);
- FUNC1(directional_shadow_quality_set, ShadowQuality);
-
- FUNCRID(scenario)
-
- FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
- FUNC2(scenario_set_environment, RID, RID)
- FUNC2(scenario_set_camera_effects, RID, RID)
- FUNC2(scenario_set_fallback_environment, RID, RID)
-
- /* INSTANCING API */
- FUNCRID(instance)
-
- FUNC2(instance_set_base, RID, RID)
- FUNC2(instance_set_scenario, RID, RID)
- FUNC2(instance_set_layer_mask, RID, uint32_t)
- FUNC2(instance_set_transform, RID, const Transform &)
- FUNC2(instance_attach_object_instance_id, RID, ObjectID)
- FUNC3(instance_set_blend_shape_weight, RID, int, float)
- FUNC3(instance_set_surface_material, RID, int, RID)
- FUNC2(instance_set_visible, RID, bool)
-
- FUNC2(instance_set_custom_aabb, RID, AABB)
-
- FUNC2(instance_attach_skeleton, RID, RID)
- FUNC2(instance_set_exterior, RID, bool)
-
- FUNC2(instance_set_extra_visibility_margin, RID, real_t)
-
- // don't use these in a game!
- FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID)
- FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID)
- FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID)
-
- FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool)
- FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
- FUNC2(instance_geometry_set_material_override, RID, RID)
-
- FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float)
- FUNC2(instance_geometry_set_as_instance_lod, RID, RID)
- FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
- FUNC2(instance_geometry_set_lod_bias, RID, float)
-
- FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
- FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
- FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &)
- FUNC2SC(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *)
-
- /* BAKE */
-
- FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &)
-
- /* CANVAS (2D) */
-
- FUNCRID(canvas)
- FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &)
- FUNC2(canvas_set_modulate, RID, const Color &)
- FUNC3(canvas_set_parent, RID, RID, float)
- FUNC1(canvas_set_disable_scale, bool)
-
- FUNCRID(canvas_texture)
- FUNC3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID)
- FUNC3(canvas_texture_set_shading_parameters, RID, const Color &, float)
-
- FUNC2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter)
- FUNC2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat)
-
- FUNCRID(canvas_item)
- FUNC2(canvas_item_set_parent, RID, RID)
-
- FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter)
- FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat)
-
- FUNC2(canvas_item_set_visible, RID, bool)
- FUNC2(canvas_item_set_light_mask, RID, int)
-
- FUNC2(canvas_item_set_update_when_visible, RID, bool)
-
- FUNC2(canvas_item_set_transform, RID, const Transform2D &)
- FUNC2(canvas_item_set_clip, RID, bool)
- FUNC2(canvas_item_set_distance_field_mode, RID, bool)
- FUNC3(canvas_item_set_custom_rect, RID, bool, const Rect2 &)
- FUNC2(canvas_item_set_modulate, RID, const Color &)
- FUNC2(canvas_item_set_self_modulate, RID, const Color &)
-
- FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
-
- FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float)
- FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
- FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float)
- FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
- FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
- FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
- FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool)
- FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
- FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
- FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
- FUNC9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int)
- FUNC5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID)
- FUNC3(canvas_item_add_multimesh, RID, RID, RID)
- FUNC3(canvas_item_add_particles, RID, RID, RID)
- FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
- FUNC2(canvas_item_add_clip_ignore, RID, bool)
- FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
- FUNC2(canvas_item_set_z_index, RID, int)
- FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool)
- FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
- FUNC2(canvas_item_attach_skeleton, RID, RID)
-
- FUNC1(canvas_item_clear, RID)
- FUNC2(canvas_item_set_draw_index, RID, int)
-
- FUNC2(canvas_item_set_material, RID, RID)
-
- FUNC2(canvas_item_set_use_parent_material, RID, bool)
-
- FUNC6(canvas_item_set_canvas_group_mode, RID, CanvasGroupMode, float, bool, float, bool)
-
- FUNC0R(RID, canvas_light_create)
-
- FUNC2(canvas_light_set_mode, RID, CanvasLightMode)
-
- FUNC2(canvas_light_attach_to_canvas, RID, RID)
- FUNC2(canvas_light_set_enabled, RID, bool)
- FUNC2(canvas_light_set_texture_scale, RID, float)
- FUNC2(canvas_light_set_transform, RID, const Transform2D &)
- FUNC2(canvas_light_set_texture, RID, RID)
- FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &)
- FUNC2(canvas_light_set_color, RID, const Color &)
- FUNC2(canvas_light_set_height, RID, float)
- FUNC2(canvas_light_set_energy, RID, float)
- FUNC3(canvas_light_set_z_range, RID, int, int)
- FUNC3(canvas_light_set_layer_range, RID, int, int)
- FUNC2(canvas_light_set_item_cull_mask, RID, int)
- FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int)
- FUNC2(canvas_light_set_directional_distance, RID, float)
-
- FUNC2(canvas_light_set_blend_mode, RID, CanvasLightBlendMode)
-
- FUNC2(canvas_light_set_shadow_enabled, RID, bool)
- FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
- FUNC2(canvas_light_set_shadow_color, RID, const Color &)
- FUNC2(canvas_light_set_shadow_smooth, RID, float)
-
- FUNCRID(canvas_light_occluder)
- FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID)
- FUNC2(canvas_light_occluder_set_enabled, RID, bool)
- FUNC2(canvas_light_occluder_set_polygon, RID, RID)
- FUNC2(canvas_light_occluder_set_as_sdf_collision, RID, bool)
- FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &)
- FUNC2(canvas_light_occluder_set_light_mask, RID, int)
-
- FUNCRID(canvas_occluder_polygon)
- FUNC3(canvas_occluder_polygon_set_shape, RID, const Vector<Vector2> &, bool)
-
- FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
-
- FUNC1(canvas_set_shadow_texture_size, int)
-
- /* GLOBAL VARIABLES */
-
- FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &)
- FUNC1(global_variable_remove, const StringName &)
- FUNC0RC(Vector<StringName>, global_variable_get_list)
- FUNC2(global_variable_set, const StringName &, const Variant &)
- FUNC2(global_variable_set_override, const StringName &, const Variant &)
- FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &)
- FUNC1RC(Variant, global_variable_get, const StringName &)
- FUNC1(global_variables_load_settings, bool)
- FUNC0(global_variables_clear)
-
- /* BLACK BARS */
-
- FUNC4(black_bars_set_margins, int, int, int, int)
- FUNC4(black_bars_set_images, RID, RID, RID, RID)
-
- /* FREE */
-
- FUNC1(free, RID)
-
- /* EVENT QUEUING */
-
- FUNC3(request_frame_drawn_callback, Object *, const StringName &, const Variant &)
-
- virtual void init();
- virtual void finish();
- virtual void draw(bool p_swap_buffers, double frame_step);
- virtual void sync();
- FUNC0RC(bool, has_changed)
-
- /* RENDER INFO */
-
- //this passes directly to avoid stalling
- virtual int get_render_info(RenderInfo p_info) {
- return rendering_server->get_render_info(p_info);
- }
-
- virtual String get_video_adapter_name() const {
- return rendering_server->get_video_adapter_name();
- }
-
- virtual String get_video_adapter_vendor() const {
- return rendering_server->get_video_adapter_vendor();
- }
-
- FUNC4(set_boot_image, const Ref<Image> &, const Color &, bool, bool)
- FUNC1(set_default_clear_color, const Color &)
-
- FUNC0R(RID, get_test_cube)
-
- FUNC1(set_debug_generate_wireframes, bool)
-
- virtual bool has_feature(Features p_feature) const {
- return rendering_server->has_feature(p_feature);
- }
- virtual bool has_os_feature(const String &p_feature) const {
- return rendering_server->has_os_feature(p_feature);
- }
-
- FUNC1(call_set_use_vsync, bool)
-
- static void set_use_vsync_callback(bool p_enable);
-
- virtual bool is_low_end() const {
- return rendering_server->is_low_end();
- }
-
- virtual uint64_t get_frame_profile_frame() {
- return rendering_server->get_frame_profile_frame();
- }
-
- virtual void set_frame_profiling_enabled(bool p_enabled) {
- rendering_server->set_frame_profiling_enabled(p_enabled);
- }
-
- virtual Vector<FrameProfileArea> get_frame_profile() {
- return rendering_server->get_frame_profile();
- }
-
- virtual float get_frame_setup_time_cpu() const {
- return rendering_server->get_frame_setup_time_cpu();
- }
-
- virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {
- rendering_server->sdfgi_set_debug_probe_select(p_position, p_dir);
- }
-
- RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread);
- ~RenderingServerWrapMT();
-
-#undef ServerName
-#undef ServerNameWrapMT
-#undef server_name
-};
-
-#ifdef DEBUG_SYNC
-#undef DEBUG_SYNC
-#endif
-#undef SYNC_DEBUG
-
-#endif
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 742ad8a7bf..df1a7d58d0 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -558,13 +558,13 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_ERROR, "Invalid numeric constant");
}
hexa_found = true;
- } else if (GETCHAR(i) == 'e') {
- if (hexa_found || exponent_found || float_suffix_found) {
+ } else if (GETCHAR(i) == 'e' && !hexa_found) {
+ if (exponent_found || float_suffix_found) {
return _make_token(TK_ERROR, "Invalid numeric constant");
}
exponent_found = true;
- } else if (GETCHAR(i) == 'f') {
- if (hexa_found || exponent_found) {
+ } else if (GETCHAR(i) == 'f' && !hexa_found) {
+ if (exponent_found) {
return _make_token(TK_ERROR, "Invalid numeric constant");
}
float_suffix_found = true;
@@ -643,7 +643,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
}
if (hexa_found) {
- tk.constant = (double)str.hex_to_int(true);
+ tk.constant = (double)str.hex_to_int();
} else {
tk.constant = str.to_float();
}
@@ -913,6 +913,7 @@ void ShaderLanguage::clear() {
char_idx = 0;
error_set = false;
error_str = "";
+ last_const = false;
while (nodes) {
Node *n = nodes;
nodes = nodes->next;
@@ -920,7 +921,7 @@ void ShaderLanguage::clear() {
}
}
-bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name) {
+bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name, ConstantNode::Value *r_constant_value) {
if (p_function_info.built_ins.has(p_identifier)) {
if (r_data_type) {
*r_data_type = p_function_info.built_ins[p_identifier].type;
@@ -968,6 +969,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
if (r_struct_name) {
*r_struct_name = p_block->variables[p_identifier].struct_name;
}
+ if (r_constant_value) {
+ *r_constant_value = p_block->variables[p_identifier].value;
+ }
return true;
}
@@ -1028,6 +1032,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
}
if (shader->constants.has(p_identifier)) {
+ if (r_is_const) {
+ *r_is_const = true;
+ }
if (r_data_type) {
*r_data_type = shader->constants[p_identifier].type;
}
@@ -1040,6 +1047,11 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
if (r_struct_name) {
*r_struct_name = shader->constants[p_identifier].type_str;
}
+ if (r_constant_value) {
+ if (shader->constants[p_identifier].initializer && shader->constants[p_identifier].initializer->values.size() == 1) {
+ *r_constant_value = shader->constants[p_identifier].initializer->values[0];
+ }
+ }
return true;
}
@@ -3090,6 +3102,72 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
return false;
}
+bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message) {
+ if (current_function == String("light")) {
+ *r_message = RTR("Varying may not be assigned in the 'light' function.");
+ return false;
+ }
+ switch (p_varying.stage) {
+ case ShaderNode::Varying::STAGE_UNKNOWN: // first assign
+ if (current_function == String("vertex")) {
+ p_varying.stage = ShaderNode::Varying::STAGE_VERTEX;
+ } else if (current_function == String("fragment")) {
+ p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT;
+ }
+ break;
+ case ShaderNode::Varying::STAGE_VERTEX:
+ if (current_function == String("fragment")) {
+ *r_message = RTR("Varyings which assigned in 'vertex' function may not be reassigned in 'fragment' or 'light'.");
+ return false;
+ }
+ break;
+ case ShaderNode::Varying::STAGE_FRAGMENT:
+ if (current_function == String("vertex")) {
+ *r_message = RTR("Varyings which assigned in 'fragment' function may not be reassigned in 'vertex' or 'light'.");
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+bool ShaderLanguage::_validate_varying_using(ShaderNode::Varying &p_varying, String *r_message) {
+ switch (p_varying.stage) {
+ case ShaderNode::Varying::STAGE_UNKNOWN:
+ *r_message = RTR("Varying must be assigned before using!");
+ return false;
+ case ShaderNode::Varying::STAGE_VERTEX:
+ if (current_function == String("fragment")) {
+ p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT;
+ } else if (current_function == String("light")) {
+ p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT;
+ }
+ break;
+ case ShaderNode::Varying::STAGE_FRAGMENT:
+ if (current_function == String("light")) {
+ p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT;
+ }
+ break;
+ case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT:
+ if (current_function == String("light")) {
+ *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'");
+ return false;
+ }
+ break;
+ case ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT:
+ if (current_function == String("fragment")) {
+ *r_message = RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'");
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message) {
if (p_node->type == Node::TYPE_OPERATOR) {
OperatorNode *op = static_cast<OperatorNode *>(p_node);
@@ -3130,13 +3208,6 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi
return false;
}
- if (shader->varyings.has(var->name) && current_function != String("vertex")) {
- if (r_message) {
- *r_message = RTR("Varyings can only be assigned in vertex function.");
- }
- return false;
- }
-
if (shader->constants.has(var->name) || var->is_const) {
if (r_message) {
*r_message = RTR("Constants cannot be modified.");
@@ -3157,13 +3228,6 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi
return false;
}
- if (shader->varyings.has(arr->name) && current_function != String("vertex")) {
- if (r_message) {
- *r_message = RTR("Varyings can only be assigned in vertex function.");
- }
- return false;
- }
-
return true;
}
@@ -3241,6 +3305,137 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
ERR_FAIL_V(false); //bug? function not found
}
+ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size) {
+ DataType type = TYPE_VOID;
+ String struct_name = "";
+ int array_size = 0;
+ bool auto_size = false;
+ Token tk = _get_token();
+
+ if (tk.type == TK_CURLY_BRACKET_OPEN) {
+ auto_size = true;
+ } else {
+ if (shader->structs.has(tk.text)) {
+ type = TYPE_STRUCT;
+ struct_name = tk.text;
+ } else {
+ if (!is_token_variable_datatype(tk.type)) {
+ _set_error("Invalid data type for array");
+ return nullptr;
+ }
+ type = get_token_datatype(tk.type);
+ }
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_OPEN) {
+ TkPos pos = _get_tkpos();
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_CLOSE) {
+ array_size = p_array_size;
+ tk = _get_token();
+ } else {
+ _set_tkpos(pos);
+
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
+ if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
+ _set_error("Expected single integer constant > 0");
+ return nullptr;
+ }
+
+ ConstantNode *cnode = (ConstantNode *)n;
+ if (cnode->values.size() == 1) {
+ array_size = cnode->values[0].sint;
+ if (array_size <= 0) {
+ _set_error("Expected single integer constant > 0");
+ return nullptr;
+ }
+ } else {
+ _set_error("Expected single integer constant > 0");
+ return nullptr;
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']'");
+ return nullptr;
+ } else {
+ tk = _get_token();
+ }
+ }
+ } else {
+ _set_error("Expected '['");
+ return nullptr;
+ }
+
+ if (type != p_type || struct_name != p_struct_name || array_size != p_array_size) {
+ String error_str = "Cannot convert from '";
+ if (type == TYPE_STRUCT) {
+ error_str += struct_name;
+ } else {
+ error_str += get_datatype_name(type);
+ }
+ error_str += "[";
+ error_str += itos(array_size);
+ error_str += "]'";
+ error_str += " to '";
+ if (type == TYPE_STRUCT) {
+ error_str += p_struct_name;
+ } else {
+ error_str += get_datatype_name(p_type);
+ }
+ error_str += "[";
+ error_str += itos(p_array_size);
+ error_str += "]'";
+ _set_error(error_str);
+ return nullptr;
+ }
+ }
+
+ ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
+ an->datatype = p_type;
+ an->struct_name = p_struct_name;
+
+ if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
+ while (true) {
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
+ if (!n) {
+ return nullptr;
+ }
+
+ if (p_type != n->get_datatype() || p_struct_name != n->get_datatype_name()) {
+ _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (type == TYPE_STRUCT ? struct_name : get_datatype_name(type)) + "'");
+ return nullptr;
+ }
+
+ tk = _get_token();
+ if (tk.type == TK_COMMA) {
+ an->initializer.push_back(n);
+ } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
+ an->initializer.push_back(n);
+ break;
+ } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
+ an->initializer.push_back(n);
+ break;
+ } else {
+ if (auto_size) {
+ _set_error("Expected '}' or ','");
+ } else {
+ _set_error("Expected ')' or ','");
+ }
+ return nullptr;
+ }
+ }
+ if (an->initializer.size() != p_array_size) {
+ _set_error("Array size mismatch");
+ return nullptr;
+ }
+ } else {
+ _set_error("Expected array initialization!");
+ return nullptr;
+ }
+
+ return an;
+}
+
ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info) {
Vector<Expression> expression;
@@ -3384,142 +3579,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
Node *nexpr;
if (pstruct->members[i]->array_size != 0) {
- DataType type = pstruct->members[i]->get_datatype();
- String struct_name = pstruct->members[i]->struct_name;
- int array_size = pstruct->members[i]->array_size;
-
- DataType type2;
- String struct_name2 = "";
- int array_size2 = 0;
-
- bool auto_size = false;
-
- tk = _get_token();
-
- if (tk.type == TK_CURLY_BRACKET_OPEN) {
- auto_size = true;
- } else {
- if (shader->structs.has(tk.text)) {
- type2 = TYPE_STRUCT;
- struct_name2 = tk.text;
- } else {
- if (!is_token_variable_datatype(tk.type)) {
- _set_error("Invalid data type for array");
- return nullptr;
- }
- type2 = get_token_datatype(tk.type);
- }
-
- tk = _get_token();
- if (tk.type == TK_BRACKET_OPEN) {
- TkPos pos2 = _get_tkpos();
- tk = _get_token();
- if (tk.type == TK_BRACKET_CLOSE) {
- array_size2 = array_size;
- tk = _get_token();
- } else {
- _set_tkpos(pos2);
-
- Node *n = _parse_and_reduce_expression(p_block, p_function_info);
- if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
-
- ConstantNode *cnode = (ConstantNode *)n;
- if (cnode->values.size() == 1) {
- array_size2 = cnode->values[0].sint;
- if (array_size2 <= 0) {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
- } else {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
-
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return nullptr;
- } else {
- tk = _get_token();
- }
- }
- } else {
- _set_error("Expected '['");
- return nullptr;
- }
-
- if (type != type2 || struct_name != struct_name2 || array_size != array_size2) {
- String error_str = "Cannot convert from '";
- if (type2 == TYPE_STRUCT) {
- error_str += struct_name2;
- } else {
- error_str += get_datatype_name(type2);
- }
- error_str += "[";
- error_str += itos(array_size2);
- error_str += "]'";
- error_str += " to '";
- if (type == TYPE_STRUCT) {
- error_str += struct_name;
- } else {
- error_str += get_datatype_name(type);
- }
- error_str += "[";
- error_str += itos(array_size);
- error_str += "]'";
- _set_error(error_str);
- return nullptr;
- }
- }
-
- ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
- an->datatype = type;
- an->struct_name = struct_name;
-
- if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
- while (true) {
- Node *n = _parse_and_reduce_expression(p_block, p_function_info);
- if (!n) {
- return nullptr;
- }
-
- if (type != n->get_datatype() || struct_name != n->get_datatype_name()) {
- _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (type == TYPE_STRUCT ? struct_name : get_datatype_name(type)) + "'");
- return nullptr;
- }
-
- tk = _get_token();
- if (tk.type == TK_COMMA) {
- an->initializer.push_back(n);
- continue;
- } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
- an->initializer.push_back(n);
- break;
- } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
- an->initializer.push_back(n);
- break;
- } else {
- if (auto_size) {
- _set_error("Expected '}' or ','");
- } else {
- _set_error("Expected ')' or ','");
- }
- return nullptr;
- }
- }
- if (an->initializer.size() != array_size) {
- _set_error("Array size mismatch");
- return nullptr;
- }
- } else {
- _set_error("Expected array initialization!");
+ nexpr = _parse_array_constructor(p_block, p_function_info, pstruct->members[i]->get_datatype(), pstruct->members[i]->struct_name, pstruct->members[i]->array_size);
+ if (!nexpr) {
return nullptr;
}
-
- nexpr = an;
} else {
nexpr = _parse_and_reduce_expression(p_block, p_function_info);
if (!nexpr) {
@@ -3722,6 +3785,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else {
//an identifier
+ last_const = false;
_set_tkpos(pos);
DataType data_type;
@@ -3749,6 +3813,24 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
_set_error("Unknown identifier in expression: " + String(identifier));
return nullptr;
}
+ if (ident_type == IDENTIFIER_VARYING) {
+ TkPos prev_pos = _get_tkpos();
+ Token next_token = _get_token();
+ _set_tkpos(prev_pos);
+ String error;
+ if (next_token.type == TK_OP_ASSIGN) {
+ if (!_validate_varying_assign(shader->varyings[identifier], &error)) {
+ _set_error(error);
+ return nullptr;
+ }
+ } else {
+ if (!_validate_varying_using(shader->varyings[identifier], &error)) {
+ _set_error(error);
+ return nullptr;
+ }
+ }
+ }
+ last_const = is_const;
if (ident_type == IDENTIFIER_FUNCTION) {
_set_error("Can't use function as identifier: " + String(identifier));
@@ -3758,16 +3840,26 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
Node *index_expression = nullptr;
Node *call_expression = nullptr;
+ Node *assign_expression = nullptr;
if (array_size > 0) {
tk = _get_token();
- if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD) {
- _set_error("Expected '[' or '.'");
+ if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD && tk.type != TK_OP_ASSIGN) {
+ _set_error("Expected '[','.' or '='");
return nullptr;
}
- if (tk.type == TK_PERIOD) {
+ if (tk.type == TK_OP_ASSIGN) {
+ if (is_const) {
+ _set_error("Constants cannot be modified.");
+ return nullptr;
+ }
+ assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size);
+ if (!assign_expression) {
+ return nullptr;
+ }
+ } else if (tk.type == TK_PERIOD) {
completion_class = TAG_ARRAY;
p_block->block_tag = SubClassTag::TAG_ARRAY;
call_expression = _parse_and_reduce_expression(p_block, p_function_info);
@@ -3791,7 +3883,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (index_expression->type == Node::TYPE_CONSTANT) {
ConstantNode *cnode = (ConstantNode *)index_expression;
if (cnode) {
- if (!cnode->values.empty()) {
+ if (!cnode->values.is_empty()) {
int value = cnode->values[0].sint;
if (value < 0 || value >= array_size) {
_set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1));
@@ -3814,6 +3906,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
arrname->struct_name = struct_name;
arrname->index_expression = index_expression;
arrname->call_expression = call_expression;
+ arrname->assign_expression = assign_expression;
arrname->is_const = is_const;
expr = arrname;
@@ -4154,7 +4247,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (array_size > 0) {
tk = _get_token();
- if (tk.type == TK_PERIOD) {
+ if (tk.type == TK_OP_ASSIGN) {
+ if (last_const) {
+ last_const = false;
+ _set_error("Constants cannot be modified.");
+ return nullptr;
+ }
+ Node *assign_expression = _parse_array_constructor(p_block, p_function_info, member_type, member_struct_name, array_size);
+ if (!assign_expression) {
+ return nullptr;
+ }
+ mn->assign_expression = assign_expression;
+ } else if (tk.type == TK_PERIOD) {
_set_error("Nested array length() is not yet implemented");
return nullptr;
} else if (tk.type == TK_BRACKET_OPEN) {
@@ -4171,7 +4275,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (index_expression->type == Node::TYPE_CONSTANT) {
ConstantNode *cnode = (ConstantNode *)index_expression;
if (cnode) {
- if (!cnode->values.empty()) {
+ if (!cnode->values.is_empty()) {
int value = cnode->values[0].sint;
if (value < 0 || value >= array_size) {
_set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1));
@@ -4189,7 +4293,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
mn->index_expression = index_expression;
} else {
- _set_error("Expected '[' or '.'");
+ _set_error("Expected '[','.' or '='");
return nullptr;
}
}
@@ -5010,17 +5114,53 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
decl.name = name;
decl.size = 0U;
+ pos = _get_tkpos();
tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) {
unknown_size = true;
} else {
if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) {
+ _set_tkpos(pos);
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
+ if (n) {
+ if (n->type == Node::TYPE_VARIABLE) {
+ VariableNode *vn = static_cast<VariableNode *>(n);
+ if (vn) {
+ ConstantNode::Value v;
+ DataType data_type;
+
+ _find_identifier(p_block, false, p_function_info, vn->name, &data_type, nullptr, &is_const, nullptr, nullptr, &v);
+
+ if (is_const) {
+ if (data_type == TYPE_INT) {
+ int32_t value = v.sint;
+ if (value > 0) {
+ node->size_expression = n;
+ decl.size = (uint32_t)value;
+ }
+ } else if (data_type == TYPE_UINT) {
+ uint32_t value = v.uint;
+ if (value > 0U) {
+ node->size_expression = n;
+ decl.size = value;
+ }
+ }
+ }
+ }
+ } else if (n->type == Node::TYPE_OPERATOR) {
+ _set_error("Array size expressions are not yet implemented.");
+ return ERR_PARSE_ERROR;
+ }
+ }
+ } else if (((int)tk.constant) > 0) {
+ decl.size = (uint32_t)tk.constant;
+ }
+
+ if (decl.size == 0U) {
_set_error("Expected integer constant > 0 or ']'");
return ERR_PARSE_ERROR;
}
-
- decl.size = ((uint32_t)tk.constant);
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
@@ -5218,7 +5358,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
_set_error("Expected array initialization");
return ERR_PARSE_ERROR;
}
- if (is_const) {
+ if (node->is_const) {
_set_error("Expected initialization of constant");
return ERR_PARSE_ERROR;
}
@@ -5252,6 +5392,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
decl.initializer = n;
+ if (n->type == Node::TYPE_CONSTANT) {
+ ConstantNode *const_node = static_cast<ConstantNode *>(n);
+ if (const_node && const_node->values.size() == 1) {
+ var.value = const_node->values[0];
+ }
+ }
+
if (var.type == TYPE_STRUCT ? (var.struct_name != n->get_datatype_name()) : (var.type != n->get_datatype())) {
_set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (var.type == TYPE_STRUCT ? String(var.struct_name) : get_datatype_name(var.type)) + "'");
return ERR_PARSE_ERROR;
@@ -5420,18 +5567,29 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ControlFlowNode *flow = (ControlFlowNode *)switch_block->statements[i];
if (flow) {
if (flow->flow_op == FLOW_OP_CASE) {
- ConstantNode *n2 = static_cast<ConstantNode *>(flow->expressions[0]);
- if (!n2) {
- return ERR_PARSE_ERROR;
- }
- if (n2->values.empty()) {
- return ERR_PARSE_ERROR;
- }
- if (constants.has(n2->values[0].sint)) {
- _set_error("Duplicated case label: '" + itos(n2->values[0].sint) + "'");
- return ERR_PARSE_ERROR;
+ if (flow->expressions[0]->type == Node::TYPE_CONSTANT) {
+ ConstantNode *cn = static_cast<ConstantNode *>(flow->expressions[0]);
+ if (!cn || cn->values.is_empty()) {
+ return ERR_PARSE_ERROR;
+ }
+ if (constants.has(cn->values[0].sint)) {
+ _set_error("Duplicated case label: '" + itos(cn->values[0].sint) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ constants.insert(cn->values[0].sint);
+ } else if (flow->expressions[0]->type == Node::TYPE_VARIABLE) {
+ VariableNode *vn = static_cast<VariableNode *>(flow->expressions[0]);
+ if (!vn) {
+ return ERR_PARSE_ERROR;
+ }
+ ConstantNode::Value v;
+ _find_identifier(p_block, false, p_function_info, vn->name, nullptr, nullptr, nullptr, nullptr, nullptr, &v);
+ if (constants.has(v.sint)) {
+ _set_error("Duplicated case label: '" + itos(v.sint) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ constants.insert(v.sint);
}
- constants.insert(n2->values[0].sint);
} else if (flow->flow_op == FLOW_OP_DEFAULT) {
continue;
} else {
@@ -5467,12 +5625,38 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
}
+ Node *n = nullptr;
+
if (tk.type != TK_INT_CONSTANT) {
- _set_error("Expected integer constant");
- return ERR_PARSE_ERROR;
- }
+ bool correct_constant_expression = false;
+ DataType data_type;
- int constant = (int)tk.constant * sign;
+ if (tk.type == TK_IDENTIFIER) {
+ bool is_const;
+ _find_identifier(p_block, false, p_function_info, tk.text, &data_type, nullptr, &is_const);
+ if (is_const) {
+ if (data_type == TYPE_INT) {
+ correct_constant_expression = true;
+ }
+ }
+ }
+ if (!correct_constant_expression) {
+ _set_error("Expected integer constant");
+ return ERR_PARSE_ERROR;
+ }
+
+ VariableNode *vn = alloc_node<VariableNode>();
+ vn->name = tk.text;
+ n = vn;
+ } else {
+ ConstantNode::Value v;
+ v.sint = (int)tk.constant * sign;
+
+ ConstantNode *cn = alloc_node<ConstantNode>();
+ cn->values.push_back(v);
+ cn->datatype = TYPE_INT;
+ n = cn;
+ }
tk = _get_token();
@@ -5484,12 +5668,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_CASE;
- ConstantNode *n = alloc_node<ConstantNode>();
- ConstantNode::Value v;
- v.sint = constant;
- n->values.push_back(v);
- n->datatype = TYPE_INT;
-
BlockNode *case_block = alloc_node<BlockNode>();
case_block->block_type = BlockNode::BLOCK_TYPE_CASE;
case_block->parent_block = p_block;
@@ -5683,6 +5861,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_BUG;
}
+ String return_struct_name = String(b->parent_function->return_struct_name);
+
ControlFlowNode *flow = alloc_node<ControlFlowNode>();
flow->flow_op = FLOW_OP_RETURN;
@@ -5691,7 +5871,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_SEMICOLON) {
//all is good
if (b->parent_function->return_type != TYPE_VOID) {
- _set_error("Expected return with expression of type '" + get_datatype_name(b->parent_function->return_type) + "'");
+ _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + "'");
return ERR_PARSE_ERROR;
}
} else {
@@ -5701,8 +5881,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_PARSE_ERROR;
}
- if (b->parent_function->return_type != expr->get_datatype()) {
- _set_error("Expected return expression of type '" + get_datatype_name(b->parent_function->return_type) + "'");
+ if (b->parent_function->return_type != expr->get_datatype() || return_struct_name != expr->get_datatype_name()) {
+ _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + "'");
return ERR_PARSE_ERROR;
}
@@ -5746,15 +5926,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
pos = _get_tkpos();
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- //all is good
_set_error("Expected ';' after discard");
+ return ERR_PARSE_ERROR;
}
p_block->statements.push_back(flow);
} else if (tk.type == TK_CF_BREAK) {
if (!p_can_break) {
- //all is good
- _set_error("Breaking is not allowed here");
+ _set_error("'break' is not allowed outside of a loop or 'switch' statement");
+ return ERR_PARSE_ERROR;
}
ControlFlowNode *flow = alloc_node<ControlFlowNode>();
@@ -5763,8 +5943,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
pos = _get_tkpos();
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
- //all is good
_set_error("Expected ';' after break");
+ return ERR_PARSE_ERROR;
}
p_block->statements.push_back(flow);
@@ -5779,8 +5959,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
} else if (tk.type == TK_CF_CONTINUE) {
if (!p_can_continue) {
- //all is good
- _set_error("Continuing is not allowed here");
+ _set_error("'continue' is not allowed outside of a loop");
+ return ERR_PARSE_ERROR;
}
ControlFlowNode *flow = alloc_node<ControlFlowNode>();
@@ -5791,6 +5971,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type != TK_SEMICOLON) {
//all is good
_set_error("Expected ';' after continue");
+ return ERR_PARSE_ERROR;
}
p_block->statements.push_back(flow);
@@ -5955,6 +6136,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_IDENTIFIER) {
st.name = tk.text;
+ if (shader->structs.has(st.name)) {
+ _set_error("Redefinition of '" + String(st.name) + "'");
+ return ERR_PARSE_ERROR;
+ }
tk = _get_token();
if (tk.type != TK_CURLY_BRACKET_OPEN) {
_set_error("Expected '{'");
@@ -6147,6 +6332,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
+ TkPos name_pos = _get_tkpos();
name = tk.text;
if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
@@ -6192,7 +6378,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
uniform2.texture_order = -1;
- uniform2.order = uniforms++;
+ if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
+ uniform2.order = uniforms++;
+ }
}
uniform2.type = type;
uniform2.scope = uniform_scope;
@@ -6426,11 +6614,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_set_error("Expected ';'");
return ERR_PARSE_ERROR;
}
- } else {
+ } else { // varying
ShaderNode::Varying varying;
varying.type = type;
varying.precision = precision;
varying.interpolation = interpolation;
+ varying.tkpos = name_pos;
tk = _get_token();
if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
@@ -7043,6 +7232,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
+ for (Map<StringName, ShaderNode::Varying>::Element *E = shader->varyings.front(); E; E = E->next()) {
+ if (E->get().stage == ShaderNode::Varying::STAGE_VERTEX || E->get().stage == ShaderNode::Varying::STAGE_FRAGMENT) {
+ _set_tkpos(E->get().tkpos);
+ _set_error(RTR("Varying must only be used in two different stages, which can be 'vertex' 'fragment' and 'light'"));
+ return ERR_PARSE_ERROR;
+ }
+ }
+
return OK;
}
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 9d2d591542..14594b039c 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -41,6 +41,11 @@
class ShaderLanguage {
public:
+ struct TkPos {
+ int char_idx;
+ int tk_line;
+ };
+
enum TokenType {
TK_EMPTY,
TK_IDENTIFIER,
@@ -414,6 +419,7 @@ public:
StringName name;
Node *index_expression = nullptr;
Node *call_expression = nullptr;
+ Node *assign_expression = nullptr;
bool is_const = false;
virtual DataType get_datatype() const { return datatype_cache; }
@@ -437,6 +443,7 @@ public:
DataType datatype = TYPE_VOID;
String struct_name;
bool is_const = false;
+ Node *size_expression = nullptr;
struct Declaration {
StringName name;
@@ -496,6 +503,7 @@ public:
int line; //for completion
int array_size;
bool is_const;
+ ConstantNode::Value value;
};
Map<StringName, Variable> variables;
@@ -526,6 +534,7 @@ public:
StringName name;
Node *owner = nullptr;
Node *index_expression = nullptr;
+ Node *assign_expression = nullptr;
bool has_swizzling_duplicates = false;
virtual DataType get_datatype() const { return datatype; }
@@ -594,10 +603,21 @@ public:
};
struct Varying {
+ enum Stage {
+ STAGE_UNKNOWN,
+ STAGE_VERTEX, // transition stage to STAGE_VERTEX_TO_FRAGMENT or STAGE_VERTEX_TO_LIGHT, emits error if they are not used
+ STAGE_FRAGMENT, // transition stage to STAGE_FRAGMENT_TO_LIGHT, emits error if it's not used
+ STAGE_VERTEX_TO_FRAGMENT,
+ STAGE_VERTEX_TO_LIGHT,
+ STAGE_FRAGMENT_TO_LIGHT,
+ };
+
+ Stage stage = STAGE_UNKNOWN;
DataType type = TYPE_VOID;
DataInterpolation interpolation = INTERPOLATION_FLAT;
DataPrecision precision = PRECISION_DEFAULT;
int array_size = 0;
+ TkPos tkpos;
Varying() {}
};
@@ -774,11 +794,7 @@ private:
int tk_line;
StringName current_function;
-
- struct TkPos {
- int char_idx;
- int tk_line;
- };
+ bool last_const = false;
TkPos _get_tkpos() {
TkPos tkp;
@@ -819,7 +835,7 @@ private:
IDENTIFIER_CONSTANT,
};
- bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr);
+ bool _find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type = nullptr, IdentifierType *r_type = nullptr, bool *r_is_const = nullptr, int *r_array_size = nullptr, StringName *r_struct_name = nullptr, ConstantNode::Value *r_constant_value = nullptr);
bool _is_operator_assign(Operator p_op) const;
bool _validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message = nullptr);
bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr);
@@ -859,8 +875,11 @@ private:
bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr);
bool _propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat);
bool _propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin);
+ bool _validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message);
+ bool _validate_varying_using(ShaderNode::Varying &p_varying, String *r_message);
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
+ Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size);
ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
Node *_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index 0c9b2ddf2f..e99b8504bb 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -94,8 +94,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BINORMAL"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW"] = constt(ShaderLanguage::TYPE_VEC3);
- shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL_MAP"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL_MAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["UV2"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["COLOR"] = constt(ShaderLanguage::TYPE_VEC4);
@@ -242,8 +242,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["LIGHT_VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL_MAP"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["NORMAL_MAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["TEXTURE"] = constt(ShaderLanguage::TYPE_SAMPLER2D);
@@ -347,7 +347,7 @@ ShaderTypes::ShaderTypes() {
emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("custom", ShaderLanguage::TYPE_VEC4));
emit_vertex_func.arguments.push_back(ShaderLanguage::StageFunctionInfo::Argument("flags", ShaderLanguage::TYPE_UINT));
emit_vertex_func.return_type = ShaderLanguage::TYPE_BOOL; //whether it could emit
- shader_modes[RS::SHADER_PARTICLES].functions["compute"].stage_functions["emit_particle"] = emit_vertex_func;
+ shader_modes[RS::SHADER_PARTICLES].functions["compute"].stage_functions["emit_subparticle"] = emit_vertex_func;
}
shader_modes[RS::SHADER_PARTICLES].modes.push_back("collision_use_scale");
diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h
index 50f910babb..e59cef6b79 100644
--- a/servers/rendering/shader_types.h
+++ b/servers/rendering/shader_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index e9bfb7ecf5..809343114c 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -242,22 +242,24 @@ RID RenderingServer::_make_test_cube() {
RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) {
Vector<Vector3> vertices;
Vector<Vector3> normals;
+ const double lat_step = Math_TAU / p_lats;
+ const double lon_step = Math_TAU / p_lons;
for (int i = 1; i <= p_lats; i++) {
- double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats);
+ double lat0 = lat_step * (i - 1) - Math_TAU / 4;
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
- double lat1 = Math_PI * (-0.5 + (double)i / p_lats);
+ double lat1 = lat_step * i - Math_TAU / 4;
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
for (int j = p_lons; j >= 1; j--) {
- double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons;
+ double lng0 = lon_step * (j - 1);
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
- double lng1 = 2 * Math_PI * (double)(j) / p_lons;
+ double lng1 = lon_step * j;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
@@ -865,8 +867,22 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
ERR_FAIL_V(ERR_INVALID_DATA);
} break;
}
-
ERR_FAIL_COND_V(array_len == 0, ERR_INVALID_DATA);
+ } else if (i == RS::ARRAY_BONES) {
+ switch (p_arrays[i].get_type()) {
+ case Variant::PACKED_INT32_ARRAY: {
+ Vector<Vector3> vertexes = p_arrays[RS::ARRAY_VERTEX];
+ Vector<int32_t> bones = p_arrays[i];
+ int32_t bone_8_group_count = bones.size() / (ARRAY_WEIGHTS_SIZE * 2);
+ int32_t vertex_count = vertexes.size();
+ if (vertex_count == bone_8_group_count) {
+ format |= RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS;
+ }
+ } break;
+ default: {
+ ERR_FAIL_V(ERR_INVALID_DATA);
+ } break;
+ }
} else if (i == RS::ARRAY_INDEX) {
index_array_len = PackedInt32Array(p_arrays[i]).size();
}
@@ -1473,7 +1489,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("mesh_clear", "mesh"), &RenderingServer::mesh_clear);
ClassDB::bind_method(D_METHOD("multimesh_create"), &RenderingServer::multimesh_create);
- ClassDB::bind_method(D_METHOD("multimesh_allocate", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &RenderingServer::multimesh_allocate, DEFVAL(false), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("multimesh_allocate_data", "multimesh", "instances", "transform_format", "color_format", "custom_data_format"), &RenderingServer::multimesh_allocate_data, DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("multimesh_get_instance_count", "multimesh"), &RenderingServer::multimesh_get_instance_count);
ClassDB::bind_method(D_METHOD("multimesh_set_mesh", "multimesh", "mesh"), &RenderingServer::multimesh_set_mesh);
ClassDB::bind_method(D_METHOD("multimesh_instance_set_transform", "multimesh", "index", "transform"), &RenderingServer::multimesh_instance_set_transform);
@@ -1507,7 +1523,7 @@ void RenderingServer::_bind_methods() {
#endif
ClassDB::bind_method(D_METHOD("skeleton_create"), &RenderingServer::skeleton_create);
- ClassDB::bind_method(D_METHOD("skeleton_allocate", "skeleton", "bones", "is_2d_skeleton"), &RenderingServer::skeleton_allocate, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("skeleton_allocate_data", "skeleton", "bones", "is_2d_skeleton"), &RenderingServer::skeleton_allocate_data, DEFVAL(false));
ClassDB::bind_method(D_METHOD("skeleton_get_bone_count", "skeleton"), &RenderingServer::skeleton_get_bone_count);
ClassDB::bind_method(D_METHOD("skeleton_bone_set_transform", "skeleton", "bone", "transform"), &RenderingServer::skeleton_bone_set_transform);
ClassDB::bind_method(D_METHOD("skeleton_bone_get_transform", "skeleton", "bone"), &RenderingServer::skeleton_bone_get_transform);
@@ -1647,7 +1663,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &RenderingServer::viewport_set_transparent_background);
ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &RenderingServer::viewport_set_global_canvas_transform);
ClassDB::bind_method(D_METHOD("viewport_set_canvas_stacking", "viewport", "canvas", "layer", "sublayer"), &RenderingServer::viewport_set_canvas_stacking);
- ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &RenderingServer::viewport_set_shadow_atlas_size);
+ ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size", "use_16_bits"), &RenderingServer::viewport_set_shadow_atlas_size, DEFVAL(false));
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision);
ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa);
ClassDB::bind_method(D_METHOD("viewport_set_use_debanding", "viewport", "enable"), &RenderingServer::viewport_set_use_debanding);
@@ -2239,138 +2255,137 @@ void RenderingServer::set_render_loop_enabled(bool p_enabled) {
RenderingServer::RenderingServer() {
//ERR_FAIL_COND(singleton);
+
+ thread_pool = memnew(RendererThreadPool);
singleton = this;
- GLOBAL_DEF_RST("rendering/vram_compression/import_bptc", false);
- GLOBAL_DEF_RST("rendering/vram_compression/import_s3tc", true);
- GLOBAL_DEF_RST("rendering/vram_compression/import_etc", false);
- GLOBAL_DEF_RST("rendering/vram_compression/import_etc2", true);
- GLOBAL_DEF_RST("rendering/vram_compression/import_pvrtc", false);
+ GLOBAL_DEF_RST("rendering/textures/vram_compression/import_bptc", false);
+ GLOBAL_DEF_RST("rendering/textures/vram_compression/import_s3tc", true);
+ GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc", false);
+ GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc2", true);
+ GLOBAL_DEF_RST("rendering/textures/vram_compression/import_pvrtc", false);
GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::FLOAT, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"));
- GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096);
- GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384"));
- GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality", 2);
- GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality.mobile", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
-
- GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality", 2);
- GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
-
- GLOBAL_DEF("rendering/quality/2d_shadow_atlas/size", 2048);
-
- GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer", false);
- GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer.mobile", true);
-
- GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
- GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
- GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 1);
- GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2);
- GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3);
- GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
-
- GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8);
- GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
- GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
- GLOBAL_DEF("rendering/quality/reflections/ggx_samples", 1024);
- GLOBAL_DEF("rendering/quality/reflections/ggx_samples.mobile", 128);
- GLOBAL_DEF("rendering/quality/reflections/fast_filter_high_quality", false);
- GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size", 256);
- GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size.mobile", 128);
- GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_count", 64);
-
- GLOBAL_DEF("rendering/quality/gi_probes/anisotropic", false);
- GLOBAL_DEF("rendering/quality/gi_probes/quality", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/quality/gi_probes/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)"));
-
- GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
- GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);
- GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley", false);
- GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley.mobile", true);
- GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx", false);
- GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx.mobile", true);
-
- GLOBAL_DEF("rendering/quality/depth_prepass/enable", true);
- GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple");
-
- GLOBAL_DEF("rendering/quality/texture_filters/use_nearest_mipmap_filter", false);
- GLOBAL_DEF("rendering/quality/texture_filters/anisotropic_filtering_level", 2);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/texture_filters/anisotropic_filtering_level", PropertyInfo(Variant::INT, "rendering/quality/texture_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Faster),4x (Fast),8x (Average),16x (Slow)"));
-
- GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)"));
- GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_quality", 2);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)"));
- GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_use_jitter", false);
-
- GLOBAL_DEF("rendering/quality/ssao/quality", 2);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/quality", PropertyInfo(Variant::INT, "rendering/quality/ssao/quality", PROPERTY_HINT_ENUM, "Very Low (Fast),Low (Fast),Medium (Average),High (Slow),Ultra (Custom)"));
- GLOBAL_DEF("rendering/quality/ssao/half_size", false);
- GLOBAL_DEF("rendering/quality/ssao/half_size.mobile", true);
- GLOBAL_DEF("rendering/quality/ssao/adaptive_target", 0.5);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/adaptive_target", PropertyInfo(Variant::FLOAT, "rendering/quality/ssao/adaptive_target", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"));
- GLOBAL_DEF("rendering/quality/ssao/blur_passes", 2);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/blur_passes", PropertyInfo(Variant::INT, "rendering/quality/ssao/blur_passes", PROPERTY_HINT_RANGE, "0,6"));
- GLOBAL_DEF("rendering/quality/ssao/fadeout_from", 50.0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/fadeout_from", PropertyInfo(Variant::FLOAT, "rendering/quality/ssao/fadeout_from", PROPERTY_HINT_RANGE, "0.0,512,0.1,or_greater"));
- GLOBAL_DEF("rendering/quality/ssao/fadeout_to", 300.0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/fadeout_to", PropertyInfo(Variant::FLOAT, "rendering/quality/ssao/fadeout_to", PROPERTY_HINT_RANGE, "64,65536,0.1,or_greater"));
-
- GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled", true);
- GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_amount", 0.25);
- GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_limit", 0.18);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter_amount", PropertyInfo(Variant::FLOAT, "rendering/quality/screen_filters/screen_space_roughness_limiter_amount", PROPERTY_HINT_RANGE, "0.01,4.0,0.01"));
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter_limit", PropertyInfo(Variant::FLOAT, "rendering/quality/screen_filters/screen_space_roughness_limiter_limit", PROPERTY_HINT_RANGE, "0.01,1.0,0.01"));
-
- GLOBAL_DEF("rendering/quality/glow/upscale_mode", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/quality/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)"));
- GLOBAL_DEF("rendering/quality/glow/upscale_mode.mobile", 0);
- GLOBAL_DEF("rendering/quality/glow/use_high_quality", false);
-
- GLOBAL_DEF("rendering/quality/screen_space_reflection/roughness_quality", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_space_reflection/roughness_quality", PropertyInfo(Variant::INT, "rendering/quality/screen_space_reflection/roughness_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)"));
-
- GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_quality", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_quality", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/subsurface_scattering_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)"));
- GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_scale", 0.05);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001"));
- GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", 0.01);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001"));
-
- GLOBAL_DEF("rendering/high_end/global_shader_variables_buffer_size", 65536);
-
- GLOBAL_DEF("rendering/lightmapper/probe_capture_update_speed", 15);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/lightmapper/probe_capture_update_speed", PropertyInfo(Variant::FLOAT, "rendering/lightmapper/probe_capture_update_speed", PROPERTY_HINT_RANGE, "0.001,256,0.001"));
-
- GLOBAL_DEF("rendering/sdfgi/probe_ray_count", 2);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/sdfgi/probe_ray_count", PropertyInfo(Variant::INT, "rendering/sdfgi/probe_ray_count", PROPERTY_HINT_ENUM, "8 (Fastest),16,32,64,96,128 (Slowest)"));
- GLOBAL_DEF("rendering/sdfgi/frames_to_converge", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/sdfgi/frames_to_converge", PropertyInfo(Variant::INT, "rendering/sdfgi/frames_to_converge", PROPERTY_HINT_ENUM, "5 (Less Latency but Lower Quality),10,15,20,25,30 (More Latency but Higher Quality)"));
-
- GLOBAL_DEF("rendering/volumetric_fog/volume_size", 64);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_size", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_size", PROPERTY_HINT_RANGE, "16,512,1"));
- GLOBAL_DEF("rendering/volumetric_fog/volume_depth", 128);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_depth", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_depth", PROPERTY_HINT_RANGE, "16,512,1"));
- GLOBAL_DEF("rendering/volumetric_fog/use_filter", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/use_filter", PropertyInfo(Variant::INT, "rendering/volumetric_fog/use_filter", PROPERTY_HINT_ENUM, "No (Faster),Yes (Higher Quality)"));
- GLOBAL_DEF("rendering/volumetric_fog/directional_shadow_shrink", 512);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/directional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/directional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1"));
- GLOBAL_DEF("rendering/volumetric_fog/positional_shadow_shrink", 512);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/positional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/positional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1"));
-
- GLOBAL_DEF("rendering/spatial_indexer/update_iterations_per_frame", 10);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1"));
+ GLOBAL_DEF("rendering/shadows/directional_shadow/size", 4096);
+ GLOBAL_DEF("rendering/shadows/directional_shadow/size.mobile", 2048);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384"));
+ GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality", 2);
+ GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality.mobile", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
+ GLOBAL_DEF("rendering/shadows/directional_shadow/16_bits", true);
+
+ GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality", 2);
+ GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality.mobile", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
+
+ GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048);
+
+ GLOBAL_DEF("rendering/driver/rd_renderer/use_low_end_renderer", false);
+ GLOBAL_DEF("rendering/driver/rd_renderer/use_low_end_renderer.mobile", true);
+
+ GLOBAL_DEF("rendering/reflections/sky_reflections/roughness_layers", 8);
+ GLOBAL_DEF("rendering/reflections/sky_reflections/texture_array_reflections", true);
+ GLOBAL_DEF("rendering/reflections/sky_reflections/texture_array_reflections.mobile", false);
+ GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples", 1024);
+ GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples.mobile", 128);
+ GLOBAL_DEF("rendering/reflections/sky_reflections/fast_filter_high_quality", false);
+ GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_size", 256);
+ GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_size.mobile", 128);
+ GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_count", 64);
+
+ GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false);
+
+ GLOBAL_DEF("rendering/global_illumination/gi_probes/anisotropic", false);
+ GLOBAL_DEF("rendering/global_illumination/gi_probes/quality", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/global_illumination/gi_probes/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)"));
+
+ GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading", false);
+ GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading.mobile", true);
+ GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley", false);
+ GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true);
+ GLOBAL_DEF("rendering/shading/overrides/force_blinn_over_ggx", false);
+ GLOBAL_DEF("rendering/shading/overrides/force_blinn_over_ggx.mobile", true);
+
+ GLOBAL_DEF("rendering/driver/depth_prepass/enable", true);
+ GLOBAL_DEF("rendering/driver/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple");
+
+ GLOBAL_DEF("rendering/textures/default_filters/use_nearest_mipmap_filter", false);
+ GLOBAL_DEF("rendering/textures/default_filters/anisotropic_filtering_level", 2);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/default_filters/anisotropic_filtering_level", PropertyInfo(Variant::INT, "rendering/textures/default_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Faster),4x (Fast),8x (Average),16x (Slow)"));
+
+ GLOBAL_DEF("rendering/camera/depth_of_field/depth_of_field_bokeh_shape", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/camera/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/camera/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)"));
+ GLOBAL_DEF("rendering/camera/depth_of_field/depth_of_field_bokeh_quality", 2);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/camera/depth_of_field/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/camera/depth_of_field/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)"));
+ GLOBAL_DEF("rendering/camera/depth_of_field/depth_of_field_use_jitter", false);
+
+ GLOBAL_DEF("rendering/environment/ssao/quality", 2);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/quality", PropertyInfo(Variant::INT, "rendering/environment/ssao/quality", PROPERTY_HINT_ENUM, "Very Low (Fast),Low (Fast),Medium (Average),High (Slow),Ultra (Custom)"));
+ GLOBAL_DEF("rendering/environment/ssao/half_size", false);
+ GLOBAL_DEF("rendering/environment/ssao/half_size.mobile", true);
+ GLOBAL_DEF("rendering/environment/ssao/adaptive_target", 0.5);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/adaptive_target", PropertyInfo(Variant::FLOAT, "rendering/environment/ssao/adaptive_target", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"));
+ GLOBAL_DEF("rendering/environment/ssao/blur_passes", 2);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/blur_passes", PropertyInfo(Variant::INT, "rendering/environment/ssao/blur_passes", PROPERTY_HINT_RANGE, "0,6"));
+ GLOBAL_DEF("rendering/environment/ssao/fadeout_from", 50.0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/fadeout_from", PropertyInfo(Variant::FLOAT, "rendering/environment/ssao/fadeout_from", PROPERTY_HINT_RANGE, "0.0,512,0.1,or_greater"));
+ GLOBAL_DEF("rendering/environment/ssao/fadeout_to", 300.0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/fadeout_to", PropertyInfo(Variant::FLOAT, "rendering/environment/ssao/fadeout_to", PROPERTY_HINT_RANGE, "64,65536,0.1,or_greater"));
+
+ GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/enabled", true);
+ GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/amount", 0.25);
+ GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/limit", 0.18);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/screen_space_roughness_limiter/amount", PropertyInfo(Variant::FLOAT, "rendering/anti_aliasing/screen_space_roughness_limiter/amount", PROPERTY_HINT_RANGE, "0.01,4.0,0.01"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/screen_space_roughness_limiter/limit", PropertyInfo(Variant::FLOAT, "rendering/anti_aliasing/screen_space_roughness_limiter/limit", PROPERTY_HINT_RANGE, "0.01,1.0,0.01"));
+
+ GLOBAL_DEF("rendering/environment/glow/upscale_mode", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/environment/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)"));
+ GLOBAL_DEF("rendering/environment/glow/upscale_mode.mobile", 0);
+ GLOBAL_DEF("rendering/environment/glow/use_high_quality", false);
+
+ GLOBAL_DEF("rendering/environment/screen_space_reflection/roughness_quality", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/screen_space_reflection/roughness_quality", PropertyInfo(Variant::INT, "rendering/environment/screen_space_reflection/roughness_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)"));
+
+ GLOBAL_DEF("rendering/environment/subsurface_scattering/subsurface_scattering_quality", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/subsurface_scattering/subsurface_scattering_quality", PropertyInfo(Variant::INT, "rendering/environment/subsurface_scattering/subsurface_scattering_quality", PROPERTY_HINT_ENUM, "Disabled (Fastest),Low (Fast),Medium (Average),High (Slow)"));
+ GLOBAL_DEF("rendering/environment/subsurface_scattering/subsurface_scattering_scale", 0.05);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/subsurface_scattering/subsurface_scattering_scale", PropertyInfo(Variant::FLOAT, "rendering/environment/subsurface_scattering/subsurface_scattering_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001"));
+ GLOBAL_DEF("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale", 0.01);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001"));
+
+ GLOBAL_DEF("rendering/limits/global_shader_variables/buffer_size", 65536);
+
+ GLOBAL_DEF("rendering/lightmapping/probe_capture/update_speed", 15);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/lightmapping/probe_capture/update_speed", PropertyInfo(Variant::FLOAT, "rendering/lightmapping/probe_capture/update_speed", PROPERTY_HINT_RANGE, "0.001,256,0.001"));
+
+ GLOBAL_DEF("rendering/global_illumination/sdfgi/probe_ray_count", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/probe_ray_count", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/probe_ray_count", PROPERTY_HINT_ENUM, "8 (Fastest),16,32,64,96,128 (Slowest)"));
+ GLOBAL_DEF("rendering/global_illumination/sdfgi/frames_to_converge", 4);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/frames_to_converge", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/frames_to_converge", PROPERTY_HINT_ENUM, "5 (Less Latency but Lower Quality),10,15,20,25,30 (More Latency but Higher Quality)"));
+ GLOBAL_DEF("rendering/global_illumination/sdfgi/frames_to_update_lights", 2);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/frames_to_update_lights", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/frames_to_update_lights", PROPERTY_HINT_ENUM, "1 (Slower),2,4,8,16 (Faster)"));
+
+ GLOBAL_DEF("rendering/environment/volumetric_fog/volume_size", 64);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/volumetric_fog/volume_size", PropertyInfo(Variant::INT, "rendering/environment/volumetric_fog/volume_size", PROPERTY_HINT_RANGE, "16,512,1"));
+ GLOBAL_DEF("rendering/environment/volumetric_fog/volume_depth", 128);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/volumetric_fog/volume_depth", PropertyInfo(Variant::INT, "rendering/environment/volumetric_fog/volume_depth", PROPERTY_HINT_RANGE, "16,512,1"));
+ GLOBAL_DEF("rendering/environment/volumetric_fog/use_filter", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/volumetric_fog/use_filter", PropertyInfo(Variant::INT, "rendering/environment/volumetric_fog/use_filter", PROPERTY_HINT_ENUM, "No (Faster),Yes (Higher Quality)"));
+
+ GLOBAL_DEF("rendering/limits/spatial_indexer/update_iterations_per_frame", 10);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/limits/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1"));
+ GLOBAL_DEF("rendering/limits/spatial_indexer/threaded_cull_minimum_instances", 1000);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/spatial_indexer/threaded_cull_minimum_instances", PropertyInfo(Variant::INT, "rendering/limits/spatial_indexer/threaded_cull_minimum_instances", PROPERTY_HINT_RANGE, "32,65536,1"));
+ GLOBAL_DEF("rendering/limits/forward_renderer/threaded_render_minimum_instances", 500);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/forward_renderer/threaded_render_minimum_instances", PropertyInfo(Variant::INT, "rendering/limits/forward_renderer/threaded_render_minimum_instances", PROPERTY_HINT_RANGE, "32,65536,1"));
+
+ GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1"));
}
RenderingServer::~RenderingServer() {
+ memdelete(thread_pool);
singleton = nullptr;
}
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index f403264a96..6a8bb83ec1 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -39,6 +39,7 @@
#include "core/variant/typed_array.h"
#include "core/variant/variant.h"
#include "servers/display_server.h"
+#include "servers/rendering/renderer_thread_pool.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/shader_language.h"
@@ -52,6 +53,8 @@ class RenderingServer : public Object {
Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const;
+ RendererThreadPool *thread_pool = nullptr;
+
protected:
RID _make_test_cube();
void _free_internal_rids();
@@ -130,11 +133,11 @@ public:
virtual void texture_set_detect_normal_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0;
enum TextureDetectRoughnessChannel {
- TEXTURE_DETECT_ROUGNHESS_R,
- TEXTURE_DETECT_ROUGNHESS_G,
- TEXTURE_DETECT_ROUGNHESS_B,
- TEXTURE_DETECT_ROUGNHESS_A,
- TEXTURE_DETECT_ROUGNHESS_GRAY,
+ TEXTURE_DETECT_ROUGHNESS_R,
+ TEXTURE_DETECT_ROUGHNESS_G,
+ TEXTURE_DETECT_ROUGHNESS_B,
+ TEXTURE_DETECT_ROUGHNESS_A,
+ TEXTURE_DETECT_ROUGHNESS_GRAY,
};
typedef void (*TextureDetectRoughnessCallback)(void *, const String &, TextureDetectRoughnessChannel);
@@ -176,6 +179,19 @@ public:
virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0;
virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0;
+ struct ShaderNativeSourceCode {
+ struct Version {
+ struct Stage {
+ String name;
+ String code;
+ };
+ Vector<Stage> stages;
+ };
+ Vector<Version> versions;
+ };
+
+ virtual ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const = 0;
+
/* COMMON MATERIAL API */
enum {
@@ -338,6 +354,8 @@ public:
virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0;
virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0;
+ virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) = 0;
+
virtual void mesh_clear(RID p_mesh) = 0;
/* MULTIMESH API */
@@ -349,7 +367,7 @@ public:
MULTIMESH_TRANSFORM_3D,
};
- virtual void multimesh_allocate(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0;
+ virtual void multimesh_allocate_data(RID p_multimesh, int p_instances, MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) = 0;
virtual int multimesh_get_instance_count(RID p_multimesh) const = 0;
virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh) = 0;
@@ -391,7 +409,7 @@ public:
/* SKELETON API */
virtual RID skeleton_create() = 0;
- virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0;
+ virtual void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false) = 0;
virtual int skeleton_get_bone_count(RID p_skeleton) const = 0;
virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) = 0;
virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const = 0;
@@ -534,7 +552,7 @@ public:
virtual RID gi_probe_create() = 0;
- virtual void gi_probe_allocate(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0;
+ virtual void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0;
virtual AABB gi_probe_get_bounds(RID p_gi_probe) const = 0;
virtual Vector3i gi_probe_get_octree_size(RID p_gi_probe) const = 0;
@@ -782,7 +800,7 @@ public:
virtual void viewport_set_sdf_oversize_and_scale(RID p_viewport, ViewportSDFOversize p_oversize, ViewportSDFScale p_scale) = 0;
- virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size) = 0;
+ virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false) = 0;
virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0;
enum ViewportMSAA {
@@ -840,7 +858,10 @@ public:
VIEWPORT_DEBUG_DRAW_SDFGI_PROBES,
VIEWPORT_DEBUG_DRAW_GI_BUFFER,
VIEWPORT_DEBUG_DRAW_DISABLE_LOD,
-
+ VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS,
+ VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS,
+ VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS,
+ VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES,
};
virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
@@ -849,7 +870,7 @@ public:
virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const = 0;
virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const = 0;
- virtual void directional_shadow_atlas_set_size(int p_size) = 0;
+ virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
/* SKY API */
@@ -964,9 +985,10 @@ public:
ENV_SDFGI_Y_SCALE_50_PERCENT
};
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
enum EnvironmentSDFGIRayCount {
+ ENV_SDFGI_RAY_COUNT_4,
ENV_SDFGI_RAY_COUNT_8,
ENV_SDFGI_RAY_COUNT_16,
ENV_SDFGI_RAY_COUNT_32,
@@ -990,20 +1012,22 @@ public:
virtual void environment_set_sdfgi_frames_to_converge(EnvironmentSDFGIFramesToConverge p_frames) = 0;
- virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0;
-
- enum EnvVolumetricFogShadowFilter {
- ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED,
- ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW,
- ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM,
- ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH,
+ enum EnvironmentSDFGIFramesToUpdateLight {
+ ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME,
+ ENV_SDFGI_UPDATE_LIGHT_IN_2_FRAMES,
+ ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES,
+ ENV_SDFGI_UPDATE_LIGHT_IN_8_FRAMES,
+ ENV_SDFGI_UPDATE_LIGHT_IN_16_FRAMES,
+ ENV_SDFGI_UPDATE_LIGHT_MAX,
};
- virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+ virtual void environment_set_sdfgi_frames_to_update_light(EnvironmentSDFGIFramesToUpdateLight p_update) = 0;
+
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0;
+
+ virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
- virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
- virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0;
@@ -1395,7 +1419,7 @@ public:
INFO_VERTEX_MEM_USED,
};
- virtual int get_render_info(RenderInfo p_info) = 0;
+ virtual uint64_t get_render_info(RenderInfo p_info) = 0;
virtual String get_video_adapter_name() const = 0;
virtual String get_video_adapter_vendor() const = 0;
@@ -1411,6 +1435,8 @@ public:
virtual float get_frame_setup_time_cpu() const = 0;
+ virtual void gi_set_use_half_resolution(bool p_enable) = 0;
+
/* TESTING */
virtual RID get_test_cube() = 0;
@@ -1443,6 +1469,8 @@ public:
virtual bool is_low_end() const = 0;
+ virtual void set_print_gpu_profile(bool p_enable) = 0;
+
RenderingDevice *create_local_rendering_device() const;
bool is_render_loop_enabled() const;
diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h
index 4481b296c6..95d2e2254e 100644
--- a/servers/server_wrap_mt_common.h
+++ b/servers/server_wrap_mt_common.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,245 +29,89 @@
/*************************************************************************/
#define FUNC0R(m_r, m_type) \
- virtual m_r m_type() { \
+ virtual m_r m_type() override { \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(); \
} \
}
-#define FUNCRID(m_type) \
- List<RID> m_type##_id_pool; \
- int m_type##allocn() { \
- for (int i = 0; i < pool_max_size; i++) { \
- m_type##_id_pool.push_back(server_name->m_type##_create()); \
- } \
- return 0; \
- } \
- void m_type##_free_cached_ids() { \
- while (m_type##_id_pool.size()) { \
- server_name->free(m_type##_id_pool.front()->get()); \
- m_type##_id_pool.pop_front(); \
- } \
- } \
- virtual RID m_type##_create() { \
- if (Thread::get_caller_id() != server_thread) { \
- RID rid; \
- MutexLock lock(alloc_mutex); \
- if (m_type##_id_pool.size() == 0) { \
- int ret; \
- command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, &ret); \
- SYNC_DEBUG \
- } \
- rid = m_type##_id_pool.front()->get(); \
- m_type##_id_pool.pop_front(); \
- return rid; \
- } else { \
- return server_name->m_type##_create(); \
- } \
- }
-
-#define FUNC1RID(m_type, m_arg1) \
- int m_type##allocn() { \
- for (int i = 0; i < m_type##_pool_max_size; i++) { \
- m_type##_id_pool.push_back(server_name->m_type##_create()); \
- } \
- return 0; \
- } \
- void m_type##_free_cached_ids() { \
- while (m_type##_id_pool.size()) { \
- free(m_type##_id_pool.front()->get()); \
- m_type##_id_pool.pop_front(); \
- } \
- } \
- virtual RID m_type##_create(m_arg1 p1) { \
- if (Thread::get_caller_id() != server_thread) { \
- RID rid; \
- MutexLock lock(alloc_mutex); \
- if (m_type##_id_pool.size() == 0) { \
- int ret; \
- command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, &ret); \
- SYNC_DEBUG \
- } \
- rid = m_type##_id_pool.front()->get(); \
- m_type##_id_pool.pop_front(); \
- return rid; \
- } else { \
- return server_name->m_type##_create(p1); \
- } \
- }
-
-#define FUNC2RID(m_type, m_arg1, m_arg2) \
- int m_type##allocn() { \
- for (int i = 0; i < m_type##_pool_max_size; i++) { \
- m_type##_id_pool.push_back(server_name->m_type##_create()); \
- } \
- return 0; \
- } \
- void m_type##_free_cached_ids() { \
- while (m_type##_id_pool.size()) { \
- free(m_type##_id_pool.front()->get()); \
- m_type##_id_pool.pop_front(); \
- } \
- } \
- virtual RID m_type##_create(m_arg1 p1, m_arg2 p2) { \
- if (Thread::get_caller_id() != server_thread) { \
- RID rid; \
- MutexLock lock(alloc_mutex); \
- if (m_type##_id_pool.size() == 0) { \
- int ret; \
- command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, &ret); \
- SYNC_DEBUG \
- } \
- rid = m_type##_id_pool.front()->get(); \
- m_type##_id_pool.pop_front(); \
- return rid; \
- } else { \
- return server_name->m_type##_create(p1, p2); \
- } \
- }
-
-#define FUNC3RID(m_type, m_arg1, m_arg2, m_arg3) \
- int m_type##allocn() { \
- for (int i = 0; i < m_type##_pool_max_size; i++) { \
- m_type##_id_pool.push_back(server_name->m_type##_create()); \
- } \
- return 0; \
- } \
- void m_type##_free_cached_ids() { \
- while (m_type##_id_pool.size()) { \
- free(m_type##_id_pool.front()->get()); \
- m_type##_id_pool.pop_front(); \
- } \
- } \
- virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
- if (Thread::get_caller_id() != server_thread) { \
- RID rid; \
- MutexLock lock(alloc_mutex); \
- if (m_type##_id_pool.size() == 0) { \
- int ret; \
- command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, &ret); \
- SYNC_DEBUG \
- } \
- rid = m_type##_id_pool.front()->get(); \
- m_type##_id_pool.pop_front(); \
- return rid; \
- } else { \
- return server_name->m_type##_create(p1, p2, p3); \
- } \
- }
-
-#define FUNC4RID(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
- int m_type##allocn() { \
- for (int i = 0; i < m_type##_pool_max_size; i++) { \
- m_type##_id_pool.push_back(server_name->m_type##_create()); \
- } \
- return 0; \
- } \
- void m_type##_free_cached_ids() { \
- while (m_type##_id_pool.size()) { \
- free(m_type##_id_pool.front()->get()); \
- m_type##_id_pool.pop_front(); \
- } \
- } \
- virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
- if (Thread::get_caller_id() != server_thread) { \
- RID rid; \
- MutexLock lock(alloc_mutex); \
- if (m_type##_id_pool.size() == 0) { \
- int ret; \
- command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, &ret); \
- SYNC_DEBUG \
- } \
- rid = m_type##_id_pool.front()->get(); \
- m_type##_id_pool.pop_front(); \
- return rid; \
- } else { \
- return server_name->m_type##_create(p1, p2, p3, p4); \
- } \
+#define FUNCRIDSPLIT(m_type) \
+ virtual RID m_type##_create() override { \
+ RID ret = server_name->m_type##_allocate(); \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type##_initialize, ret); \
+ } else { \
+ server_name->m_type##_initialize(ret); \
+ } \
+ return ret; \
}
-#define FUNC5RID(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
- List<RID> m_type##_id_pool; \
- int m_type##allocn(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
- for (int i = 0; i < pool_max_size; i++) { \
- m_type##_id_pool.push_back(server_name->m_type##_create(p1, p2, p3, p4, p5)); \
- } \
- return 0; \
- } \
- void m_type##_free_cached_ids() { \
- while (m_type##_id_pool.size()) { \
- free(m_type##_id_pool.front()->get()); \
- m_type##_id_pool.pop_front(); \
- } \
- } \
- virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
- if (Thread::get_caller_id() != server_thread) { \
- RID rid; \
- MutexLock lock(alloc_mutex); \
- if (m_type##_id_pool.size() == 0) { \
- int ret; \
- command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, p5, &ret); \
- SYNC_DEBUG \
- } \
- rid = m_type##_id_pool.front()->get(); \
- m_type##_id_pool.pop_front(); \
- return rid; \
- } else { \
- return server_name->m_type##_create(p1, p2, p3, p4, p5); \
- } \
+//RID now returns directly, ensure thread safety yourself
+#define FUNCRID(m_type) \
+ virtual RID m_type##_create() override { \
+ return server_name->m_type##_create(); \
}
#define FUNC0RC(m_r, m_type) \
- virtual m_r m_type() const { \
+ virtual m_r m_type() const override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(); \
} \
}
#define FUNC0(m_type) \
- virtual void m_type() { \
+ virtual void m_type() override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(); \
} \
}
#define FUNC0C(m_type) \
- virtual void m_type() const { \
+ virtual void m_type() const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(); \
} \
}
#define FUNC0S(m_type) \
- virtual void m_type() { \
+ virtual void m_type() override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(); \
} \
}
#define FUNC0SC(m_type) \
- virtual void m_type() const { \
+ virtual void m_type() const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(); \
} \
}
@@ -275,560 +119,646 @@
///////////////////////////////////////////////
#define FUNC1R(m_r, m_type, m_arg1) \
- virtual m_r m_type(m_arg1 p1) { \
+ virtual m_r m_type(m_arg1 p1) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1); \
} \
}
#define FUNC1RC(m_r, m_type, m_arg1) \
- virtual m_r m_type(m_arg1 p1) const { \
+ virtual m_r m_type(m_arg1 p1) const override { \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1); \
} \
}
#define FUNC1S(m_type, m_arg1) \
- virtual void m_type(m_arg1 p1) { \
+ virtual void m_type(m_arg1 p1) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1); \
} \
}
#define FUNC1SC(m_type, m_arg1) \
- virtual void m_type(m_arg1 p1) const { \
+ virtual void m_type(m_arg1 p1) const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1); \
} \
}
#define FUNC1(m_type, m_arg1) \
- virtual void m_type(m_arg1 p1) { \
+ virtual void m_type(m_arg1 p1) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1); \
} \
}
#define FUNC1C(m_type, m_arg1) \
- virtual void m_type(m_arg1 p1) const { \
+ virtual void m_type(m_arg1 p1) const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1); \
} \
}
#define FUNC2R(m_r, m_type, m_arg1, m_arg2) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2) { \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2); \
} \
}
#define FUNC2RC(m_r, m_type, m_arg1, m_arg2) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2) const { \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2) const override { \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2); \
} \
}
#define FUNC2S(m_type, m_arg1, m_arg2) \
- virtual void m_type(m_arg1 p1, m_arg2 p2) { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2); \
} \
}
#define FUNC2SC(m_type, m_arg1, m_arg2) \
- virtual void m_type(m_arg1 p1, m_arg2 p2) const { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2) const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2); \
} \
}
#define FUNC2(m_type, m_arg1, m_arg2) \
- virtual void m_type(m_arg1 p1, m_arg2 p2) { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2); \
} \
}
#define FUNC2C(m_type, m_arg1, m_arg2) \
- virtual void m_type(m_arg1 p1, m_arg2 p2) const { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2) const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2); \
} \
}
#define FUNC3R(m_r, m_type, m_arg1, m_arg2, m_arg3) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2, p3); \
} \
}
#define FUNC3RC(m_r, m_type, m_arg1, m_arg2, m_arg3) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2, p3); \
} \
}
#define FUNC3S(m_type, m_arg1, m_arg2, m_arg3) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3); \
} \
}
#define FUNC3SC(m_type, m_arg1, m_arg2, m_arg3) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3); \
} \
}
#define FUNC3(m_type, m_arg1, m_arg2, m_arg3) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3); \
} \
}
#define FUNC3C(m_type, m_arg1, m_arg2, m_arg3) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3); \
} \
}
#define FUNC4R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2, p3, p4); \
} \
}
#define FUNC4RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2, p3, p4); \
} \
}
#define FUNC4S(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4); \
} \
}
#define FUNC4SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4); \
} \
}
#define FUNC4(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4); \
} \
}
-#define FUNC4C(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \
- } else { \
- server_name->m_type(p1, p2, p3, p4); \
- } \
+#define FUNC4C(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4); \
+ } \
}
#define FUNC5R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2, p3, p4, p5); \
} \
}
#define FUNC5RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2, p3, p4, p5); \
} \
}
#define FUNC5S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) override { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
SYNC_DEBUG \
} else { \
+ command_queue.flush_if_pending(); \
server_name->m_type(p1, p2, p3, p4, p5); \
} \
}
-#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
- SYNC_DEBUG \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5); \
- } \
+#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
+ SYNC_DEBUG \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5); \
+ } \
}
-#define FUNC5(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5); \
- } \
+#define FUNC5(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5); \
+ } \
}
-#define FUNC5C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5); \
- } \
+#define FUNC5C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5); \
+ } \
}
#define FUNC6R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
+ WRITE_ACTION \
if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
SYNC_DEBUG \
return ret; \
} else { \
+ command_queue.flush_if_pending(); \
return server_name->m_type(p1, p2, p3, p4, p5, p6); \
} \
}
-#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
- if (Thread::get_caller_id() != server_thread) { \
- m_r ret; \
- command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
- SYNC_DEBUG \
- return ret; \
- } else { \
- return server_name->m_type(p1, p2, p3, p4, p5, p6); \
- } \
+#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ m_r ret; \
+ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
+ SYNC_DEBUG \
+ return ret; \
+ } else { \
+ command_queue.flush_if_pending(); \
+ return server_name->m_type(p1, p2, p3, p4, p5, p6); \
+ } \
+ }
+
+#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
+ SYNC_DEBUG \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6); \
+ } \
+ }
+
+#define FUNC6SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
+ SYNC_DEBUG \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6); \
+ } \
}
-#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
- SYNC_DEBUG \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6); \
- } \
+#define FUNC6(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6); \
+ } \
}
-#define FUNC6SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
- SYNC_DEBUG \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6); \
- } \
+#define FUNC6C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6); \
+ } \
}
-#define FUNC6(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6); \
- } \
+#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ m_r ret; \
+ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
+ SYNC_DEBUG \
+ return ret; \
+ } else { \
+ command_queue.flush_if_pending(); \
+ return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
+ } \
}
-#define FUNC6C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6); \
- } \
- }
-
-#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
- if (Thread::get_caller_id() != server_thread) { \
- m_r ret; \
- command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
- SYNC_DEBUG \
- return ret; \
- } else { \
- return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
- } \
- }
-
-#define FUNC7RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
- if (Thread::get_caller_id() != server_thread) { \
- m_r ret; \
- command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
- SYNC_DEBUG \
- return ret; \
- } else { \
- return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
- } \
- }
-
-#define FUNC7S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
- SYNC_DEBUG \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
- } \
- }
-
-#define FUNC7SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
- SYNC_DEBUG \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
- } \
- }
-
-#define FUNC7(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
- } \
- }
-
-#define FUNC7C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
- } \
- }
-
-#define FUNC8R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \
- if (Thread::get_caller_id() != server_thread) { \
- m_r ret; \
- command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
- SYNC_DEBUG \
- return ret; \
- } else { \
- return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
- } \
- }
-
-#define FUNC8RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
- virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \
- if (Thread::get_caller_id() != server_thread) { \
- m_r ret; \
- command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
- SYNC_DEBUG \
- return ret; \
- } else { \
- return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
- } \
- }
-
-#define FUNC8S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
- SYNC_DEBUG \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
- } \
- }
-
-#define FUNC8SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
- SYNC_DEBUG \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
- } \
- }
-
-#define FUNC8(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
- } \
- }
-
-#define FUNC8C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
- } \
- }
-
-#define FUNC9(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9); \
- } \
- }
-
-#define FUNC10(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
- } \
- }
-
-#define FUNC11(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
- } \
- }
-
-#define FUNC12(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
- } \
- }
-
-#define FUNC13(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
- } \
- }
-
-#define FUNC14(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
- } \
- }
-
-#define FUNC15(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14, m_arg15) \
- virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14, m_arg15 p15) { \
- if (Thread::get_caller_id() != server_thread) { \
- command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \
- } else { \
- server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \
- } \
+#define FUNC7RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ m_r ret; \
+ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
+ SYNC_DEBUG \
+ return ret; \
+ } else { \
+ command_queue.flush_if_pending(); \
+ return server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
+ } \
+ }
+
+#define FUNC7S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
+ SYNC_DEBUG \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
+ } \
+ }
+
+#define FUNC7SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
+ SYNC_DEBUG \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
+ } \
+ }
+
+#define FUNC7(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
+ } \
+ }
+
+#define FUNC7C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
+ } \
+ }
+
+#define FUNC8R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ m_r ret; \
+ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
+ SYNC_DEBUG \
+ return ret; \
+ } else { \
+ command_queue.flush_if_pending(); \
+ return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
+ } \
+ }
+
+#define FUNC8RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
+ virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ m_r ret; \
+ command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
+ SYNC_DEBUG \
+ return ret; \
+ } else { \
+ command_queue.flush_if_pending(); \
+ return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
+ } \
+ }
+
+#define FUNC8S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
+ SYNC_DEBUG \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
+ } \
+ }
+
+#define FUNC8SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
+ SYNC_DEBUG \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
+ } \
+ }
+
+#define FUNC8(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
+ } \
+ }
+
+#define FUNC8C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const override { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
+ } \
+ }
+
+#define FUNC9(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9); \
+ } \
+ }
+
+#define FUNC10(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
+ } \
+ }
+
+#define FUNC11(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
+ } \
+ }
+
+#define FUNC12(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
+ } \
+ }
+
+#define FUNC13(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
+ } \
+ }
+
+#define FUNC14(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
+ } \
+ }
+
+#define FUNC15(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14, m_arg15) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11, m_arg12 p12, m_arg13 p13, m_arg14 p14, m_arg15 p15) override { \
+ WRITE_ACTION \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \
+ } else { \
+ command_queue.flush_if_pending(); \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \
+ } \
}
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index fa39185ac0..d6d3c11cfb 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -219,6 +219,11 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_font_system", "name", "base_size"), &TextServer::create_font_system, DEFVAL(16));
ClassDB::bind_method(D_METHOD("create_font_resource", "filename", "base_size"), &TextServer::create_font_resource, DEFVAL(16));
ClassDB::bind_method(D_METHOD("create_font_memory", "data", "type", "base_size"), &TextServer::_create_font_memory, DEFVAL(16));
+ ClassDB::bind_method(D_METHOD("create_font_bitmap", "height", "ascent", "base_size"), &TextServer::create_font_bitmap);
+
+ ClassDB::bind_method(D_METHOD("font_bitmap_add_texture", "font", "texture"), &TextServer::font_bitmap_add_texture);
+ ClassDB::bind_method(D_METHOD("font_bitmap_add_char", "font", "char", "texture_idx", "rect", "align", "advance"), &TextServer::font_bitmap_add_char);
+ ClassDB::bind_method(D_METHOD("font_bitmap_add_kerning_pair", "font", "A", "B", "kerning"), &TextServer::font_bitmap_add_kerning_pair);
ClassDB::bind_method(D_METHOD("font_get_height", "font", "size"), &TextServer::font_get_height);
ClassDB::bind_method(D_METHOD("font_get_ascent", "font", "size"), &TextServer::font_get_ascent);
@@ -227,6 +232,12 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_get_underline_position", "font", "size"), &TextServer::font_get_underline_position);
ClassDB::bind_method(D_METHOD("font_get_underline_thickness", "font", "size"), &TextServer::font_get_underline_thickness);
+ ClassDB::bind_method(D_METHOD("font_get_spacing_space", "font"), &TextServer::font_get_spacing_space);
+ ClassDB::bind_method(D_METHOD("font_set_spacing_space", "font", "value"), &TextServer::font_set_spacing_space);
+
+ ClassDB::bind_method(D_METHOD("font_get_spacing_glyph", "font"), &TextServer::font_get_spacing_glyph);
+ ClassDB::bind_method(D_METHOD("font_set_spacing_glyph", "font", "value"), &TextServer::font_set_spacing_glyph);
+
ClassDB::bind_method(D_METHOD("font_set_antialiased", "font", "antialiased"), &TextServer::font_set_antialiased);
ClassDB::bind_method(D_METHOD("font_get_antialiased", "font"), &TextServer::font_get_antialiased);
@@ -284,7 +295,7 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_shaped_text", "direction", "orientation"), &TextServer::create_shaped_text, DEFVAL(DIRECTION_AUTO), DEFVAL(ORIENTATION_HORIZONTAL));
- ClassDB::bind_method(D_METHOD("shaped_text_clear"), &TextServer::shaped_text_clear);
+ ClassDB::bind_method(D_METHOD("shaped_text_clear", "rid"), &TextServer::shaped_text_clear);
ClassDB::bind_method(D_METHOD("shaped_text_set_direction", "shaped", "direction"), &TextServer::shaped_text_set_direction, DEFVAL(DIRECTION_AUTO));
ClassDB::bind_method(D_METHOD("shaped_text_get_direction", "shaped"), &TextServer::shaped_text_get_direction);
@@ -550,7 +561,7 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po
Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<float> &p_width, int p_start, bool p_once, uint8_t /*TextBreakFlag*/ p_break_flags) const {
Vector<Vector2i> lines;
- ERR_FAIL_COND_V(p_width.empty(), lines);
+ ERR_FAIL_COND_V(p_width.is_empty(), lines);
const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped);
const Vector<Glyph> &logical = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
diff --git a/servers/text_server.h b/servers/text_server.h
index a9b8649268..e1429da1d1 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -192,18 +192,6 @@ public:
Vector<TextServer::Glyph> glyphs_logical;
};
- struct BitmapFontData {
- int height = 0;
- int ascent = 0;
- int charcount = 0;
- const int *char_rects = nullptr;
- int kerning_count = 0;
- const int *kernings = nullptr;
- int w = 0;
- int h = 0;
- const unsigned char *img = nullptr;
- };
-
protected:
static void _bind_methods();
@@ -236,11 +224,22 @@ public:
virtual RID create_font_system(const String &p_name, int p_base_size = 16) = 0;
virtual RID create_font_resource(const String &p_filename, int p_base_size = 16) = 0;
virtual RID create_font_memory(const uint8_t *p_data, size_t p_size, const String &p_type, int p_base_size = 16) = 0;
+ virtual RID create_font_bitmap(float p_height, float p_ascent, int p_base_size = 16) = 0;
+
+ virtual void font_bitmap_add_texture(RID p_font, const Ref<Texture> &p_texture) = 0;
+ virtual void font_bitmap_add_char(RID p_font, char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) = 0;
+ virtual void font_bitmap_add_kerning_pair(RID p_font, char32_t p_A, char32_t p_B, int p_kerning) = 0;
virtual float font_get_height(RID p_font, int p_size) const = 0;
virtual float font_get_ascent(RID p_font, int p_size) const = 0;
virtual float font_get_descent(RID p_font, int p_size) const = 0;
+ virtual int font_get_spacing_space(RID p_font) const = 0;
+ virtual void font_set_spacing_space(RID p_font, int p_value) = 0;
+
+ virtual int font_get_spacing_glyph(RID p_font) const = 0;
+ virtual void font_set_spacing_glyph(RID p_font, int p_value) = 0;
+
virtual float font_get_underline_position(RID p_font, int p_size) const = 0;
virtual float font_get_underline_thickness(RID p_font, int p_size) const = 0;
diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp
index e9858416ec..9148631899 100644
--- a/servers/xr/xr_interface.cpp
+++ b/servers/xr/xr_interface.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h
index 8afcf115d2..8039018f35 100644
--- a/servers/xr/xr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp
index 91469b1aec..5341390045 100644
--- a/servers/xr/xr_positional_tracker.cpp
+++ b/servers/xr/xr_positional_tracker.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h
index c0976d3c13..420d818342 100644
--- a/servers/xr/xr_positional_tracker.h
+++ b/servers/xr/xr_positional_tracker.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp
index 9d35825ae9..2acc2e398c 100644
--- a/servers/xr_server.cpp
+++ b/servers/xr_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr_server.h b/servers/xr_server.h
index d66d4e778a..d3972be838 100644
--- a/servers/xr_server.h
+++ b/servers/xr_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/SCsub b/tests/SCsub
index 7aab28531d..0f3c14f0bd 100644
--- a/tests/SCsub
+++ b/tests/SCsub
@@ -17,6 +17,11 @@ if env["module_gdnative_enabled"]:
if env_tests["platform"] == "windows":
env_tests.Append(CPPDEFINES=[("DOCTEST_THREAD_LOCAL", "")])
+# Increase number of addressable sections in object files
+# due to doctest's heavy use of templates and macros.
+if env_tests.msvc:
+ env_tests.Append(CCFLAGS=["/bigobj"])
+
env_tests.add_source_files(env.tests_sources, "*.cpp")
lib = env_tests.add_library("tests", env.tests_sources)
diff --git a/tests/data/images/icon.bmp b/tests/data/images/icon.bmp
new file mode 100644
index 0000000000..e006f7ebdd
--- /dev/null
+++ b/tests/data/images/icon.bmp
Binary files differ
diff --git a/tests/data/images/icon.jpg b/tests/data/images/icon.jpg
new file mode 100644
index 0000000000..b45bfa8d9b
--- /dev/null
+++ b/tests/data/images/icon.jpg
Binary files differ
diff --git a/tests/data/images/icon.png b/tests/data/images/icon.png
new file mode 100644
index 0000000000..45aaaf584f
--- /dev/null
+++ b/tests/data/images/icon.png
Binary files differ
diff --git a/tests/data/images/icon.tga b/tests/data/images/icon.tga
new file mode 100644
index 0000000000..dcacdc5c67
--- /dev/null
+++ b/tests/data/images/icon.tga
Binary files differ
diff --git a/tests/data/images/icon.webp b/tests/data/images/icon.webp
new file mode 100644
index 0000000000..6c4707e858
--- /dev/null
+++ b/tests/data/images/icon.webp
Binary files differ
diff --git a/tests/test_aabb.h b/tests/test_aabb.h
index 404a73a95f..517c4dcefd 100644
--- a/tests/test_aabb.h
+++ b/tests/test_aabb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_array.h b/tests/test_array.h
new file mode 100644
index 0000000000..52da256860
--- /dev/null
+++ b/tests/test_array.h
@@ -0,0 +1,186 @@
+/*************************************************************************/
+/* test_array.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_ARRAY_H
+#define TEST_ARRAY_H
+
+#include "core/object/class_db.h"
+#include "core/object/script_language.h"
+#include "core/templates/hashfuncs.h"
+#include "core/templates/vector.h"
+#include "core/variant/array.h"
+#include "core/variant/container_type_validate.h"
+#include "core/variant/variant.h"
+#include "tests/test_macros.h"
+
+namespace TestArray {
+
+TEST_CASE("[Array] size(), clear(), and is_empty()") {
+ Array arr;
+ CHECK(arr.size() == 0);
+ CHECK(arr.is_empty());
+ arr.push_back(1);
+ CHECK(arr.size() == 1);
+ arr.clear();
+ CHECK(arr.is_empty());
+ CHECK(arr.size() == 0);
+}
+
+TEST_CASE("[Array] Assignment and comparison operators") {
+ Array arr1;
+ Array arr2;
+ arr1.push_back(1);
+ CHECK(arr1 != arr2);
+ CHECK(arr1 > arr2);
+ CHECK(arr1 >= arr2);
+ arr2.push_back(2);
+ CHECK(arr1 != arr2);
+ CHECK(arr1 < arr2);
+ CHECK(arr1 <= arr2);
+ CHECK(arr2 > arr1);
+ CHECK(arr2 >= arr1);
+ Array arr3 = arr2;
+ CHECK(arr3 == arr2);
+}
+
+TEST_CASE("[Array] append_array()") {
+ Array arr1;
+ Array arr2;
+ arr1.push_back(1);
+ arr1.append_array(arr2);
+ CHECK(arr1.size() == 1);
+ arr2.push_back(2);
+ arr1.append_array(arr2);
+ CHECK(arr1.size() == 2);
+ CHECK(int(arr1[0]) == 1);
+ CHECK(int(arr1[1]) == 2);
+}
+
+TEST_CASE("[Array] resize(), insert(), and erase()") {
+ Array arr;
+ arr.resize(2);
+ CHECK(arr.size() == 2);
+ arr.insert(0, 1);
+ CHECK(int(arr[0]) == 1);
+ arr.insert(0, 2);
+ CHECK(int(arr[0]) == 2);
+ arr.erase(2);
+ CHECK(int(arr[0]) == 1);
+}
+
+TEST_CASE("[Array] front() and back()") {
+ Array arr;
+ arr.push_back(1);
+ CHECK(int(arr.front()) == 1);
+ CHECK(int(arr.back()) == 1);
+ arr.push_back(3);
+ CHECK(int(arr.front()) == 1);
+ CHECK(int(arr.back()) == 3);
+}
+
+TEST_CASE("[Array] has() and count()") {
+ Array arr;
+ arr.push_back(1);
+ arr.push_back(1);
+ CHECK(arr.has(1));
+ CHECK(!arr.has(2));
+ CHECK(arr.count(1) == 2);
+ CHECK(arr.count(2) == 0);
+}
+
+TEST_CASE("[Array] remove()") {
+ Array arr;
+ arr.push_back(1);
+ arr.push_back(2);
+ arr.remove(0);
+ CHECK(arr.size() == 1);
+ CHECK(int(arr[0]) == 2);
+ arr.remove(0);
+ CHECK(arr.size() == 0);
+
+ // The array is now empty; try to use `remove()` again.
+ // Normally, this prints an error message so we silence it.
+ ERR_PRINT_OFF;
+ arr.remove(0);
+ ERR_PRINT_ON;
+
+ CHECK(arr.size() == 0);
+}
+
+TEST_CASE("[Array] get()") {
+ Array arr;
+ arr.push_back(1);
+ CHECK(int(arr.get(0)) == 1);
+}
+
+TEST_CASE("[Array] sort()") {
+ Array arr;
+
+ arr.push_back(3);
+ arr.push_back(4);
+ arr.push_back(2);
+ arr.push_back(1);
+ arr.sort();
+ int val = 1;
+ for (int i = 0; i < arr.size(); i++) {
+ CHECK(int(arr[i]) == val);
+ val++;
+ }
+}
+
+TEST_CASE("[Array] push_front(), pop_front(), pop_back()") {
+ Array arr;
+ arr.push_front(1);
+ arr.push_front(2);
+ CHECK(int(arr[0]) == 2);
+ arr.pop_front();
+ CHECK(int(arr[0]) == 1);
+ CHECK(arr.size() == 1);
+ arr.push_front(2);
+ arr.push_front(3);
+ arr.pop_back();
+ CHECK(int(arr[1]) == 2);
+ CHECK(arr.size() == 2);
+}
+
+TEST_CASE("[Array] max() and min()") {
+ Array arr;
+ arr.push_back(3);
+ arr.push_front(4);
+ arr.push_back(5);
+ arr.push_back(2);
+ int max = int(arr.max());
+ int min = int(arr.min());
+ CHECK(max == 5);
+ CHECK(min == 2);
+}
+} // namespace TestArray
+
+#endif // TEST_ARRAY_H
diff --git a/tests/test_astar.h b/tests/test_astar.h
index cd1bd84c15..12664a5ff1 100644
--- a/tests/test_astar.h
+++ b/tests/test_astar.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_basis.h b/tests/test_basis.h
index 00a00b4a5b..11c68f9eb7 100644
--- a/tests/test_basis.h
+++ b/tests/test_basis.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_class_db.h b/tests/test_class_db.h
index 9a30891c16..9ef4569c14 100644
--- a/tests/test_class_db.h
+++ b/tests/test_class_db.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GODOT_TEST_CLASS_DB_H
-#define GODOT_TEST_CLASS_DB_H
+#ifndef TEST_CLASS_DB_H
+#define TEST_CLASS_DB_H
#include "core/register_core_types.h"
@@ -42,11 +42,6 @@
#include "tests/test_macros.h"
-#define TEST_COND DOCTEST_CHECK_FALSE_MESSAGE
-#define TEST_FAIL DOCTEST_FAIL
-#define TEST_FAIL_COND DOCTEST_REQUIRE_FALSE_MESSAGE
-#define TEST_FAIL_COND_WARN DOCTEST_WARN_FALSE_MESSAGE
-
namespace TestClassDB {
struct TypeReference {
@@ -298,7 +293,7 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
const ExposedClass *top = &p_class;
while (!setter && top->base != StringName()) {
top = p_context.find_exposed_class(top->base);
- TEST_FAIL_COND(!top, "Class not found '" + top->base + "'. Inherited by '" + top->name + "'.");
+ TEST_FAIL_COND(!top, "Class not found '", top->base, "'. Inherited by '", top->name, "'.");
setter = top->find_method_by_name(p_prop.setter);
}
@@ -308,23 +303,23 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
top = &p_class;
while (!getter && top->base != StringName()) {
top = p_context.find_exposed_class(top->base);
- TEST_FAIL_COND(!top, "Class not found '" + top->base + "'. Inherited by '" + top->name + "'.");
+ TEST_FAIL_COND(!top, "Class not found '", top->base, "'. Inherited by '", top->name, "'.");
getter = top->find_method_by_name(p_prop.getter);
}
TEST_FAIL_COND((!setter && !getter),
- "Couldn't find neither the setter nor the getter for property: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ "Couldn't find neither the setter nor the getter for property: '", p_class.name, ".", String(p_prop.name), "'.");
if (setter) {
int setter_argc = p_prop.index != -1 ? 2 : 1;
TEST_FAIL_COND(setter->arguments.size() != setter_argc,
- "Invalid property setter argument count: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ "Invalid property setter argument count: '", p_class.name, ".", String(p_prop.name), "'.");
}
if (getter) {
int getter_argc = p_prop.index != -1 ? 1 : 0;
TEST_FAIL_COND(getter->arguments.size() != getter_argc,
- "Invalid property setter argument count: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ "Invalid property setter argument count: '", p_class.name, ".", String(p_prop.name), "'.");
}
if (getter && setter) {
@@ -335,7 +330,7 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
setter_first_arg.type.name == p_context.names_cache.string_type;
TEST_FAIL_COND(!whitelisted,
- "Return type from getter doesn't match first argument of setter, for property: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ "Return type from getter doesn't match first argument of setter, for property: '", p_class.name, ".", String(p_prop.name), "'.");
}
}
@@ -344,10 +339,17 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
const ExposedClass *prop_class = p_context.find_exposed_class(prop_type_ref);
if (prop_class) {
TEST_COND(prop_class->is_singleton,
- "Property type is a singleton: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ "Property type is a singleton: '", p_class.name, ".", String(p_prop.name), "'.");
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(prop_class->api_type == ClassDB::API_EDITOR,
+ "Property '", p_class.name, ".", p_prop.name, "' has type '", prop_class->name,
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
} else {
+ // Look for types that don't inherit Object
TEST_FAIL_COND(!p_context.has_type(prop_type_ref),
- "Property type '" + prop_type_ref.name + "' not found: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ "Property type '", prop_type_ref.name, "' not found: '", p_class.name, ".", String(p_prop.name), "'.");
}
if (getter) {
@@ -356,7 +358,7 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
if (idx_arg.type.name != p_context.names_cache.int_type) {
// If not an int, it can be an enum
TEST_COND(p_context.enum_types.find(idx_arg.type.name) < 0,
- "Invalid type '" + idx_arg.type.name + "' for index argument of property getter: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ "Invalid type '", idx_arg.type.name, "' for index argument of property getter: '", p_class.name, ".", String(p_prop.name), "'.");
}
}
}
@@ -368,17 +370,29 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
// Assume the index parameter is an enum
// If not an int, it can be an enum
TEST_COND(p_context.enum_types.find(idx_arg.type.name) < 0,
- "Invalid type '" + idx_arg.type.name + "' for index argument of property setter: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ "Invalid type '", idx_arg.type.name, "' for index argument of property setter: '", p_class.name, ".", String(p_prop.name), "'.");
}
}
}
}
void validate_method(const Context &p_context, const ExposedClass &p_class, const MethodData &p_method) {
- const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type);
- if (return_class) {
- TEST_COND(return_class->is_singleton,
- "Method return type is a singleton: '" + p_class.name + "." + p_method.name + "'.");
+ if (p_method.return_type.name != StringName()) {
+ const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type);
+ if (return_class) {
+ TEST_COND(return_class->is_singleton,
+ "Method return type is a singleton: '", p_class.name, ".", p_method.name, "'.");
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(return_class->api_type == ClassDB::API_EDITOR,
+ "Method '", p_class.name, ".", p_method.name, "' has return type '", return_class->name,
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+ } else {
+ // Look for types that don't inherit Object
+ TEST_FAIL_COND(!p_context.has_type(p_method.return_type),
+ "Method return type '", p_method.return_type.name, "' not found: '", p_class.name, ".", p_method.name, "'.");
+ }
}
for (const List<ArgumentData>::Element *F = p_method.arguments.front(); F; F = F->next()) {
@@ -387,17 +401,24 @@ void validate_method(const Context &p_context, const ExposedClass &p_class, cons
const ExposedClass *arg_class = p_context.find_exposed_class(arg.type);
if (arg_class) {
TEST_COND(arg_class->is_singleton,
- "Argument type is a singleton: '" + arg.name + "' of method '" + p_class.name + "." + p_method.name + "'.");
+ "Argument type is a singleton: '", arg.name, "' of method '", p_class.name, ".", p_method.name, "'.");
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(arg_class->api_type == ClassDB::API_EDITOR,
+ "Argument '", arg.name, "' of method '", p_class.name, ".", p_method.name, "' has type '",
+ arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
} else {
+ // Look for types that don't inherit Object
TEST_FAIL_COND(!p_context.has_type(arg.type),
- "Argument type '" + arg.type.name + "' not found: '" + arg.name + "' of method" + p_class.name + "." + p_method.name + "'.");
+ "Argument type '", arg.type.name, "' not found: '", arg.name, "' of method", p_class.name, ".", p_method.name, "'.");
}
if (arg.has_defval) {
String type_error_msg;
bool arg_defval_assignable_to_type = arg_default_value_is_assignable_to_type(p_context, arg.defval, arg.type, &type_error_msg);
String err_msg = vformat("Invalid default value for parameter '%s' of method '%s.%s'.", arg.name, p_class.name, p_method.name);
- if (!type_error_msg.empty()) {
+ if (!type_error_msg.is_empty()) {
err_msg += " " + type_error_msg;
}
TEST_COND(!arg_defval_assignable_to_type, err_msg.utf8().get_data());
@@ -412,10 +433,17 @@ void validate_signal(const Context &p_context, const ExposedClass &p_class, cons
const ExposedClass *arg_class = p_context.find_exposed_class(arg.type);
if (arg_class) {
TEST_COND(arg_class->is_singleton,
- "Argument class is a singleton: '" + arg.name + "' of signal" + p_class.name + "." + p_signal.name + "'.");
+ "Argument class is a singleton: '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "'.");
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(arg_class->api_type == ClassDB::API_EDITOR,
+ "Argument '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "' has type '",
+ arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
} else {
+ // Look for types that don't inherit Object
TEST_FAIL_COND(!p_context.has_type(arg.type),
- "Argument type '" + arg.type.name + "' not found: '" + arg.name + "' of signal" + p_class.name + "." + p_signal.name + "'.");
+ "Argument type '", arg.type.name, "' not found: '", arg.name, "' of signal", p_class.name, ".", p_signal.name, "'.");
}
}
}
@@ -426,7 +454,7 @@ void validate_class(const Context &p_context, const ExposedClass &p_exposed_clas
if (!is_derived_type) {
// Asserts about the base Object class
TEST_FAIL_COND(p_exposed_class.name != p_context.names_cache.object_class,
- "Class '" + p_exposed_class.name + "' has no base class.");
+ "Class '", p_exposed_class.name, "' has no base class.");
TEST_FAIL_COND(!p_exposed_class.is_instantiable,
"Object class is not instantiable.");
TEST_FAIL_COND(p_exposed_class.api_type != ClassDB::API_CORE,
@@ -436,10 +464,10 @@ void validate_class(const Context &p_context, const ExposedClass &p_exposed_clas
}
TEST_FAIL_COND((p_exposed_class.is_singleton && p_exposed_class.base != p_context.names_cache.object_class),
- "Singleton base class '" + String(p_exposed_class.base) + "' is not Object, for class '" + p_exposed_class.name + "'.");
+ "Singleton base class '", String(p_exposed_class.base), "' is not Object, for class '", p_exposed_class.name, "'.");
TEST_FAIL_COND((is_derived_type && !p_context.exposed_classes.has(p_exposed_class.base)),
- "Base type '" + p_exposed_class.base.operator String() + "' does not exist, for class '" + p_exposed_class.name + "'.");
+ "Base type '", p_exposed_class.base.operator String(), "' does not exist, for class '", p_exposed_class.name, "'.");
for (const List<PropertyData>::Element *F = p_exposed_class.properties.front(); F; F = F->next()) {
validate_property(p_context, p_exposed_class, F->get());
@@ -519,7 +547,7 @@ void add_exposed_classes(Context &r_context) {
bool valid = false;
prop.index = ClassDB::get_property_index(class_name, prop.name, &valid);
- TEST_FAIL_COND(!valid, "Invalid property: '" + exposed_class.name + "." + String(prop.name) + "'.");
+ TEST_FAIL_COND(!valid, "Invalid property: '", exposed_class.name, ".", String(prop.name), "'.");
exposed_class.properties.push_back(prop);
}
@@ -538,7 +566,7 @@ void add_exposed_classes(Context &r_context) {
int argc = method_info.arguments.size();
- if (method_info.name.empty()) {
+ if (method_info.name.is_empty()) {
continue;
}
@@ -557,7 +585,7 @@ void add_exposed_classes(Context &r_context) {
if (!m && !method.is_virtual) {
TEST_FAIL_COND(!virtual_method_list.find(method_info),
- "Missing MethodBind for non-virtual method: '" + exposed_class.name + "." + method.name + "'.");
+ "Missing MethodBind for non-virtual method: '", exposed_class.name, ".", method.name, "'.");
// A virtual method without the virtual flag. This is a special case.
@@ -584,9 +612,8 @@ void add_exposed_classes(Context &r_context) {
bool bad_reference_hint = !method.is_virtual && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE &&
ClassDB::is_parent_class(return_info.class_name, r_context.names_cache.reference_class);
- TEST_COND(bad_reference_hint, String() + "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." +
- " Are you returning a reference type by pointer? Method: '" +
- exposed_class.name + "." + method.name + "'.");
+ TEST_COND(bad_reference_hint, "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'.", " Are you returning a reference type by pointer? Method: '",
+ exposed_class.name, ".", method.name, "'.");
} else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
method.return_type.name = return_info.hint_string;
} else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
@@ -636,7 +663,7 @@ void add_exposed_classes(Context &r_context) {
}
TEST_COND(exposed_class.find_property_by_name(method.name),
- "Method name conflicts with property: '" + String(class_name) + "." + String(method.name) + "'.");
+ "Method name conflicts with property: '", String(class_name), ".", String(method.name), "'.");
// Classes starting with an underscore are ignored unless they're used as a property setter or getter
if (!method.is_virtual && String(method.name)[0] == '_') {
@@ -724,8 +751,8 @@ void add_exposed_classes(Context &r_context) {
for (const List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) {
const StringName &constant_name = E->get();
int *value = class_info->constant_map.getptr(constant_name);
- TEST_FAIL_COND(!value, "Missing enum constant value: '" +
- String(class_name) + "." + String(enum_.name) + "." + String(constant_name) + "'.");
+ TEST_FAIL_COND(!value, "Missing enum constant value: '",
+ String(class_name), ".", String(enum_.name), ".", String(constant_name), "'.");
constants.erase(constant_name);
ConstantData constant;
@@ -743,7 +770,7 @@ void add_exposed_classes(Context &r_context) {
for (const List<String>::Element *E = constants.front(); E; E = E->next()) {
const String &constant_name = E->get();
int *value = class_info->constant_map.getptr(StringName(E->get()));
- TEST_FAIL_COND(!value, "Missing enum constant value: '" + String(class_name) + "." + String(constant_name) + "'.");
+ TEST_FAIL_COND(!value, "Missing enum constant value: '", String(class_name), ".", String(constant_name), "'.");
ConstantData constant;
constant.name = constant_name;
@@ -822,7 +849,7 @@ TEST_SUITE("[ClassDB]") {
const ExposedClass *object_class = context.find_exposed_class(context.names_cache.object_class);
TEST_FAIL_COND(!object_class, "Object class not found.");
TEST_FAIL_COND(object_class->base != StringName(),
- "Object class derives from another class: '" + object_class->base + "'.");
+ "Object class derives from another class: '", object_class->base, "'.");
for (ExposedClasses::Element E = context.exposed_classes.front(); E; E = E.next()) {
validate_class(context, E.value());
@@ -832,4 +859,4 @@ TEST_SUITE("[ClassDB]") {
}
} // namespace TestClassDB
-#endif //GODOT_TEST_CLASS_DB_H
+#endif // TEST_CLASS_DB_H
diff --git a/tests/test_color.h b/tests/test_color.h
index c2bb63b7d0..eb8d7dcbd4 100644
--- a/tests/test_color.h
+++ b/tests/test_color.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_command_queue.h b/tests/test_command_queue.h
index ce42d94475..b4fa63ad2b 100644
--- a/tests/test_command_queue.h
+++ b/tests/test_command_queue.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -122,8 +122,8 @@ public:
int message_count_to_read = 0;
bool exit_threads = false;
- Thread *reader_thread = nullptr;
- Thread *writer_thread = nullptr;
+ Thread reader_thread;
+ Thread writer_thread;
int func1_count = 0;
@@ -221,20 +221,16 @@ public:
}
void init_threads() {
- reader_thread = Thread::create(&SharedThreadState::static_reader_thread_loop, this);
- writer_thread = Thread::create(&SharedThreadState::static_writer_thread_loop, this);
+ reader_thread.start(&SharedThreadState::static_reader_thread_loop, this);
+ writer_thread.start(&SharedThreadState::static_writer_thread_loop, this);
}
void destroy_threads() {
exit_threads = true;
reader_threadwork.main_start_work();
writer_threadwork.main_start_work();
- Thread::wait_to_finish(reader_thread);
- memdelete(reader_thread);
- reader_thread = nullptr;
- Thread::wait_to_finish(writer_thread);
- memdelete(writer_thread);
- writer_thread = nullptr;
+ reader_thread.wait_to_finish();
+ writer_thread.wait_to_finish();
}
};
diff --git a/tests/test_config_file.h b/tests/test_config_file.h
index f910ca4b1f..958341018b 100644
--- a/tests/test_config_file.h
+++ b/tests/test_config_file.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_crypto.h b/tests/test_crypto.h
index 9e219ceec9..8da8c75544 100644
--- a/tests/test_crypto.h
+++ b/tests/test_crypto.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_curve.h b/tests/test_curve.h
index b123ef6325..019941a7ce 100644
--- a/tests/test_curve.h
+++ b/tests/test_curve.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_expression.h b/tests/test_expression.h
index 0d970ba87a..0ef60d1a19 100644
--- a/tests/test_expression.h
+++ b/tests/test_expression.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -173,11 +173,11 @@ TEST_CASE("[Expression] Built-in functions") {
"`sqrt(pow(3, 2) + pow(4, 2))` should return the expected result.");
CHECK_MESSAGE(
- expression.parse("stepify(sin(0.5), 0.01)") == OK,
+ expression.parse("snapped(sin(0.5), 0.01)") == OK,
"The expression should parse successfully.");
CHECK_MESSAGE(
Math::is_equal_approx(float(expression.execute()), 0.48),
- "`stepify(sin(0.5), 0.01)` should return the expected result.");
+ "`snapped(sin(0.5), 0.01)` should return the expected result.");
CHECK_MESSAGE(
expression.parse("pow(2.0, -2500)") == OK,
diff --git a/tests/test_file_access.h b/tests/test_file_access.h
index 0d5c9d79ce..00a314644c 100644
--- a/tests/test_file_access.h
+++ b/tests/test_file_access.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,11 +32,12 @@
#define TEST_FILE_ACCESS_H
#include "core/os/file_access.h"
+#include "test_utils.h"
namespace TestFileAccess {
TEST_CASE("[FileAccess] CSV read") {
- FileAccess *f = FileAccess::open("tests/data/translations.csv", FileAccess::READ);
+ FileAccess *f = FileAccess::open(TestUtils::get_data_path("translations.csv"), FileAccess::READ);
Vector<String> header = f->get_csv_line(); // Default delimiter: ","
REQUIRE(header.size() == 3);
diff --git a/tests/test_geometry_2d.h b/tests/test_geometry_2d.h
new file mode 100644
index 0000000000..ea02d1114f
--- /dev/null
+++ b/tests/test_geometry_2d.h
@@ -0,0 +1,553 @@
+/*************************************************************************/
+/* test_geometry_2d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_GEOMETRY_2D_H
+#define TEST_GEOMETRY_2D_H
+
+#include "core/math/geometry_2d.h"
+#include "core/templates/vector.h"
+
+#include "thirdparty/doctest/doctest.h"
+
+namespace TestGeometry2D {
+
+TEST_CASE("[Geometry2D] Point in circle") {
+ CHECK(Geometry2D::is_point_in_circle(Vector2(0, 0), Vector2(0, 0), 1.0));
+
+ CHECK(Geometry2D::is_point_in_circle(Vector2(0, 0), Vector2(11.99, 0), 12));
+ CHECK(Geometry2D::is_point_in_circle(Vector2(-11.99, 0), Vector2(0, 0), 12));
+
+ CHECK_FALSE(Geometry2D::is_point_in_circle(Vector2(0, 0), Vector2(12.01, 0), 12));
+ CHECK_FALSE(Geometry2D::is_point_in_circle(Vector2(-12.01, 0), Vector2(0, 0), 12));
+
+ CHECK(Geometry2D::is_point_in_circle(Vector2(7, -42), Vector2(4, -40), 3.7));
+ CHECK_FALSE(Geometry2D::is_point_in_circle(Vector2(7, -42), Vector2(4, -40), 3.5));
+
+ // This tests points on the edge of the circle. They are treated as beeing inside the circle.
+ // In `is_point_in_triangle` and `is_point_in_polygon` they are treated as being outside, so in order the make
+ // the behaviour consistent this may change in the future (see issue #44717 and PR #44274).
+ CHECK(Geometry2D::is_point_in_circle(Vector2(1.0, 0.0), Vector2(0, 0), 1.0));
+ CHECK(Geometry2D::is_point_in_circle(Vector2(0.0, -1.0), Vector2(0, 0), 1.0));
+}
+
+TEST_CASE("[Geometry2D] Point in triangle") {
+ CHECK(Geometry2D::is_point_in_triangle(Vector2(0, 0), Vector2(-1, 1), Vector2(0, -1), Vector2(1, 1)));
+ CHECK_FALSE(Geometry2D::is_point_in_triangle(Vector2(-1.01, 1.0), Vector2(-1, 1), Vector2(0, -1), Vector2(1, 1)));
+
+ CHECK(Geometry2D::is_point_in_triangle(Vector2(3, 2.5), Vector2(1, 4), Vector2(3, 2), Vector2(5, 4)));
+ CHECK(Geometry2D::is_point_in_triangle(Vector2(-3, -2.5), Vector2(-1, -4), Vector2(-3, -2), Vector2(-5, -4)));
+ CHECK_FALSE(Geometry2D::is_point_in_triangle(Vector2(0, 0), Vector2(1, 4), Vector2(3, 2), Vector2(5, 4)));
+
+ // This tests points on the edge of the triangle. They are treated as beeing outside the triangle.
+ // In `is_point_in_circle` they are treated as being inside, so in order the make
+ // the behaviour consistent this may change in the future (see issue #44717 and PR #44274).
+ CHECK_FALSE(Geometry2D::is_point_in_triangle(Vector2(1, 1), Vector2(-1, 1), Vector2(0, -1), Vector2(1, 1)));
+ CHECK_FALSE(Geometry2D::is_point_in_triangle(Vector2(0, 1), Vector2(-1, 1), Vector2(0, -1), Vector2(1, 1)));
+}
+
+TEST_CASE("[Geometry2D] Point in polygon") {
+ Vector<Vector2> p;
+ CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(0, 0), p));
+
+ p.push_back(Vector2(-88, 120));
+ p.push_back(Vector2(-74, -38));
+ p.push_back(Vector2(135, -145));
+ p.push_back(Vector2(425, 70));
+ p.push_back(Vector2(68, 112));
+ p.push_back(Vector2(-120, 370));
+ p.push_back(Vector2(-323, -145));
+ CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(-350, 0), p));
+ CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(-110, 60), p));
+ CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(412, 96), p));
+ CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(83, 130), p));
+ CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(-320, -153), p));
+
+ CHECK(Geometry2D::is_point_in_polygon(Vector2(0, 0), p));
+ CHECK(Geometry2D::is_point_in_polygon(Vector2(-230, 0), p));
+ CHECK(Geometry2D::is_point_in_polygon(Vector2(130, -110), p));
+ CHECK(Geometry2D::is_point_in_polygon(Vector2(370, 55), p));
+ CHECK(Geometry2D::is_point_in_polygon(Vector2(-160, 190), p));
+
+ // This tests points on the edge of the polygon. They are treated as beeing outside the polygon.
+ // In `is_point_in_circle` they are treated as being inside, so in order the make
+ // the behaviour consistent this may change in the future (see issue #44717 and PR #44274).
+ CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(68, 112), p));
+ CHECK_FALSE(Geometry2D::is_point_in_polygon(Vector2(-88, 120), p));
+}
+
+TEST_CASE("[Geometry2D] Polygon clockwise") {
+ Vector<Vector2> p;
+ CHECK_FALSE(Geometry2D::is_polygon_clockwise(p));
+
+ p.push_back(Vector2(5, -5));
+ p.push_back(Vector2(-1, -5));
+ p.push_back(Vector2(-5, -1));
+ p.push_back(Vector2(-1, 3));
+ p.push_back(Vector2(1, 5));
+ CHECK(Geometry2D::is_polygon_clockwise(p));
+
+ p.invert();
+ CHECK_FALSE(Geometry2D::is_polygon_clockwise(p));
+}
+
+TEST_CASE("[Geometry2D] Line intersection") {
+ Vector2 r;
+ CHECK(Geometry2D::line_intersects_line(Vector2(2, 0), Vector2(0, 1), Vector2(0, 2), Vector2(1, 0), r));
+ CHECK(r.is_equal_approx(Vector2(2, 2)));
+
+ CHECK(Geometry2D::line_intersects_line(Vector2(-1, 1), Vector2(1, -1), Vector2(4, 1), Vector2(-1, -1), r));
+ CHECK(r.is_equal_approx(Vector2(1.5, -1.5)));
+
+ CHECK(Geometry2D::line_intersects_line(Vector2(-1, 0), Vector2(-1, -1), Vector2(1, 0), Vector2(1, -1), r));
+ CHECK(r.is_equal_approx(Vector2(0, 1)));
+
+ CHECK_FALSE_MESSAGE(
+ Geometry2D::line_intersects_line(Vector2(-1, 1), Vector2(1, -1), Vector2(0, 1), Vector2(1, -1), r),
+ "Parallel lines should not intersect.");
+}
+
+TEST_CASE("[Geometry2D] Segment intersection.") {
+ Vector2 r;
+
+ CHECK(Geometry2D::segment_intersects_segment(Vector2(-1, 1), Vector2(1, -1), Vector2(1, 1), Vector2(-1, -1), &r));
+ CHECK(r.is_equal_approx(Vector2(0, 0)));
+
+ CHECK_FALSE(Geometry2D::segment_intersects_segment(Vector2(-1, 1), Vector2(1, -1), Vector2(1, 1), Vector2(0.1, 0.1), &r));
+ CHECK_FALSE_MESSAGE(
+ Geometry2D::segment_intersects_segment(Vector2(-1, 1), Vector2(1, -1), Vector2(0, 1), Vector2(1, -1), &r),
+ "Parallel segments should not intersect.");
+}
+
+TEST_CASE("[Geometry2D] Closest point to segment") {
+ Vector2 s[] = { Vector2(-4, -4), Vector2(4, 4) };
+ CHECK(Geometry2D::get_closest_point_to_segment(Vector2(4.1, 4.1), s).is_equal_approx(Vector2(4, 4)));
+ CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-4.1, -4.1), s).is_equal_approx(Vector2(-4, -4)));
+ CHECK(Geometry2D::get_closest_point_to_segment(Vector2(-1, 1), s).is_equal_approx(Vector2(0, 0)));
+}
+
+TEST_CASE("[Geometry2D] Closest point to uncapped segment") {
+ Vector2 s[] = { Vector2(-4, -4), Vector2(4, 4) };
+ CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-1, 1), s).is_equal_approx(Vector2(0, 0)));
+ CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(-4, -6), s).is_equal_approx(Vector2(-5, -5)));
+ CHECK(Geometry2D::get_closest_point_to_segment_uncapped(Vector2(4, 6), s).is_equal_approx(Vector2(5, 5)));
+}
+
+TEST_CASE("[Geometry2D] Closest points between segments") {
+ Vector2 c1, c2;
+ Geometry2D::get_closest_points_between_segments(Vector2(2, 2), Vector2(3, 3), Vector2(4, 4), Vector2(4, 5), c1, c2);
+ CHECK(c1.is_equal_approx(Vector2(3, 3)));
+ CHECK(c2.is_equal_approx(Vector2(4, 4)));
+
+ Geometry2D::get_closest_points_between_segments(Vector2(0, 1), Vector2(-2, -1), Vector2(0, 0), Vector2(2, -2), c1, c2);
+ CHECK(c1.is_equal_approx(Vector2(-0.5, 0.5)));
+ CHECK(c2.is_equal_approx(Vector2(0, 0)));
+
+ Geometry2D::get_closest_points_between_segments(Vector2(-1, 1), Vector2(1, -1), Vector2(1, 1), Vector2(-1, -1), c1, c2);
+ CHECK(c1.is_equal_approx(Vector2(0, 0)));
+ CHECK(c2.is_equal_approx(Vector2(0, 0)));
+}
+
+TEST_CASE("[Geometry2D] Make atlas") {
+ Vector<Point2i> result;
+ Size2i size;
+
+ Vector<Size2i> r;
+ r.push_back(Size2i(2, 2));
+ Geometry2D::make_atlas(r, result, size);
+ CHECK(size == Size2i(2, 2));
+ CHECK(result.size() == r.size());
+
+ r.clear();
+ result.clear();
+ r.push_back(Size2i(1, 2));
+ r.push_back(Size2i(3, 4));
+ r.push_back(Size2i(5, 6));
+ r.push_back(Size2i(7, 8));
+ Geometry2D::make_atlas(r, result, size);
+ CHECK(result.size() == r.size());
+}
+
+TEST_CASE("[Geometry2D] Polygon intersection") {
+ Vector<Point2> a;
+ Vector<Point2> b;
+ Vector<Vector<Point2>> r;
+
+ a.push_back(Point2(30, 60));
+ a.push_back(Point2(70, 5));
+ a.push_back(Point2(200, 40));
+ a.push_back(Point2(80, 200));
+
+ SUBCASE("[Geometry2D] Both polygons are empty") {
+ r = Geometry2D::intersect_polygons(Vector<Point2>(), Vector<Point2>());
+ CHECK_MESSAGE(r.is_empty(), "Both polygons are empty. The intersection should also be empty.");
+ }
+
+ SUBCASE("[Geometry2D] One polygon is empty") {
+ r = Geometry2D::intersect_polygons(a, b);
+ REQUIRE_MESSAGE(r.is_empty(), "One polygon is empty. The intersection should also be empty.");
+ }
+
+ SUBCASE("[Geometry2D] Basic intersection") {
+ b.push_back(Point2(200, 300));
+ b.push_back(Point2(90, 200));
+ b.push_back(Point2(50, 100));
+ b.push_back(Point2(200, 90));
+ r = Geometry2D::intersect_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 1, "The polygons should intersect each other with 1 resulting intersection polygon.");
+ REQUIRE_MESSAGE(r[0].size() == 3, "The resulting intersection polygon should have 3 vertices.");
+ CHECK(r[0][0].is_equal_approx(Point2(86.52174, 191.30436)));
+ CHECK(r[0][1].is_equal_approx(Point2(50, 100)));
+ CHECK(r[0][2].is_equal_approx(Point2(160.52632, 92.63157)));
+ }
+
+ SUBCASE("[Geometry2D] Intersection with one polygon beeing completly inside the other polygon") {
+ b.push_back(Point2(80, 100));
+ b.push_back(Point2(50, 50));
+ b.push_back(Point2(150, 50));
+ r = Geometry2D::intersect_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 1, "The polygons should intersect each other with 1 resulting intersection polygon.");
+ REQUIRE_MESSAGE(r[0].size() == 3, "The resulting intersection polygon should have 3 vertices.");
+ CHECK(r[0][0].is_equal_approx(b[0]));
+ CHECK(r[0][1].is_equal_approx(b[1]));
+ CHECK(r[0][2].is_equal_approx(b[2]));
+ }
+
+ SUBCASE("[Geometry2D] No intersection with 2 non-empty polygons") {
+ b.push_back(Point2(150, 150));
+ b.push_back(Point2(250, 100));
+ b.push_back(Point2(300, 200));
+ r = Geometry2D::intersect_polygons(a, b);
+ REQUIRE_MESSAGE(r.is_empty(), "The polygons should not intersect each other.");
+ }
+
+ SUBCASE("[Geometry2D] Intersection with 2 resulting polygons") {
+ a.clear();
+ a.push_back(Point2(70, 5));
+ a.push_back(Point2(140, 7));
+ a.push_back(Point2(100, 52));
+ a.push_back(Point2(170, 50));
+ a.push_back(Point2(60, 125));
+ b.push_back(Point2(70, 105));
+ b.push_back(Point2(115, 55));
+ b.push_back(Point2(90, 15));
+ b.push_back(Point2(160, 50));
+ r = Geometry2D::intersect_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 2, "The polygons should intersect each other with 2 resulting intersection polygons.");
+ REQUIRE_MESSAGE(r[0].size() == 4, "The resulting intersection polygon should have 4 vertices.");
+ CHECK(r[0][0].is_equal_approx(Point2(70, 105)));
+ CHECK(r[0][1].is_equal_approx(Point2(115, 55)));
+ CHECK(r[0][2].is_equal_approx(Point2(112.894737, 51.63158)));
+ CHECK(r[0][3].is_equal_approx(Point2(159.509537, 50.299728)));
+
+ REQUIRE_MESSAGE(r[1].size() == 3, "The intersection polygon should have 3 vertices.");
+ CHECK(r[1][0].is_equal_approx(Point2(119.692307, 29.846149)));
+ CHECK(r[1][1].is_equal_approx(Point2(107.706421, 43.33028)));
+ CHECK(r[1][2].is_equal_approx(Point2(90, 15)));
+ }
+}
+
+TEST_CASE("[Geometry2D] Merge polygons") {
+ Vector<Point2> a;
+ Vector<Point2> b;
+ Vector<Vector<Point2>> r;
+
+ a.push_back(Point2(225, 180));
+ a.push_back(Point2(160, 230));
+ a.push_back(Point2(20, 212));
+ a.push_back(Point2(50, 115));
+
+ SUBCASE("[Geometry2D] Both polygons are empty") {
+ r = Geometry2D::merge_polygons(Vector<Point2>(), Vector<Point2>());
+ REQUIRE_MESSAGE(r.is_empty(), "Both polygons are empty. The union should also be empty.");
+ }
+
+ SUBCASE("[Geometry2D] One polygon is empty") {
+ r = Geometry2D::merge_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 1, "One polygon is non-empty. There should be 1 resulting merged polygon.");
+ REQUIRE_MESSAGE(r[0].size() == 4, "The resulting merged polygon should have 4 vertices.");
+ CHECK(r[0][0].is_equal_approx(a[0]));
+ CHECK(r[0][1].is_equal_approx(a[1]));
+ CHECK(r[0][2].is_equal_approx(a[2]));
+ CHECK(r[0][3].is_equal_approx(a[3]));
+ }
+
+ SUBCASE("[Geometry2D] Basic merge with 2 polygons") {
+ b.push_back(Point2(180, 190));
+ b.push_back(Point2(60, 140));
+ b.push_back(Point2(160, 80));
+ r = Geometry2D::merge_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 1, "The merged polygons should result in 1 polygon.");
+ REQUIRE_MESSAGE(r[0].size() == 7, "The resulting merged polygon should have 7 vertices.");
+ CHECK(r[0][0].is_equal_approx(Point2(174.791077, 161.350967)));
+ CHECK(r[0][1].is_equal_approx(Point2(225, 180)));
+ CHECK(r[0][2].is_equal_approx(Point2(160, 230)));
+ CHECK(r[0][3].is_equal_approx(Point2(20, 212)));
+ CHECK(r[0][4].is_equal_approx(Point2(50, 115)));
+ CHECK(r[0][5].is_equal_approx(Point2(81.911758, 126.852943)));
+ CHECK(r[0][6].is_equal_approx(Point2(160, 80)));
+ }
+
+ SUBCASE("[Geometry2D] Merge with 2 resulting merged polygons (outline and hole)") {
+ b.push_back(Point2(180, 190));
+ b.push_back(Point2(140, 125));
+ b.push_back(Point2(60, 140));
+ b.push_back(Point2(160, 80));
+ r = Geometry2D::merge_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 2, "The merged polygons should result in 2 polygons.");
+
+ REQUIRE_MESSAGE(!Geometry2D::is_polygon_clockwise(r[0]), "The merged polygon (outline) should be counter-clockwise.");
+ REQUIRE_MESSAGE(r[0].size() == 7, "The resulting merged polygon (outline) should have 7 vertices.");
+ CHECK(r[0][0].is_equal_approx(Point2(174.791077, 161.350967)));
+ CHECK(r[0][1].is_equal_approx(Point2(225, 180)));
+ CHECK(r[0][2].is_equal_approx(Point2(160, 230)));
+ CHECK(r[0][3].is_equal_approx(Point2(20, 212)));
+ CHECK(r[0][4].is_equal_approx(Point2(50, 115)));
+ CHECK(r[0][5].is_equal_approx(Point2(81.911758, 126.852943)));
+ CHECK(r[0][6].is_equal_approx(Point2(160, 80)));
+
+ REQUIRE_MESSAGE(Geometry2D::is_polygon_clockwise(r[1]), "The resulting merged polygon (hole) should be clockwise.");
+ REQUIRE_MESSAGE(r[1].size() == 3, "The resulting merged polygon (hole) should have 3 vertices.");
+ CHECK(r[1][0].is_equal_approx(Point2(98.083069, 132.859421)));
+ CHECK(r[1][1].is_equal_approx(Point2(158.689453, 155.370377)));
+ CHECK(r[1][2].is_equal_approx(Point2(140, 125)));
+ }
+}
+
+TEST_CASE("[Geometry2D] Clip polygons") {
+ Vector<Point2> a;
+ Vector<Point2> b;
+ Vector<Vector<Point2>> r;
+
+ a.push_back(Point2(225, 180));
+ a.push_back(Point2(160, 230));
+ a.push_back(Point2(20, 212));
+ a.push_back(Point2(50, 115));
+
+ SUBCASE("[Geometry2D] Both polygons are empty") {
+ r = Geometry2D::clip_polygons(Vector<Point2>(), Vector<Point2>());
+ CHECK_MESSAGE(r.is_empty(), "Both polygons are empty. The clip should also be empty.");
+ }
+
+ SUBCASE("[Geometry2D] Basic clip with one result polygon") {
+ b.push_back(Point2(250, 170));
+ b.push_back(Point2(175, 270));
+ b.push_back(Point2(120, 260));
+ b.push_back(Point2(25, 80));
+ r = Geometry2D::clip_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 1, "The clipped polygons should result in 1 polygon.");
+ REQUIRE_MESSAGE(r[0].size() == 3, "The resulting clipped polygon should have 3 vertices.");
+ CHECK(r[0][0].is_equal_approx(Point2(100.102173, 222.298843)));
+ CHECK(r[0][1].is_equal_approx(Point2(20, 212)));
+ CHECK(r[0][2].is_equal_approx(Point2(47.588089, 122.798492)));
+ }
+
+ SUBCASE("[Geometry2D] Polygon b completely overlaps polygon a") {
+ b.push_back(Point2(250, 170));
+ b.push_back(Point2(175, 270));
+ b.push_back(Point2(10, 210));
+ b.push_back(Point2(55, 80));
+ r = Geometry2D::clip_polygons(a, b);
+ CHECK_MESSAGE(r.is_empty(), "Polygon 'b' completely overlaps polygon 'a'. This should result in no clipped polygons.");
+ }
+
+ SUBCASE("[Geometry2D] Polygon a completely overlaps polygon b") {
+ b.push_back(Point2(150, 200));
+ b.push_back(Point2(65, 190));
+ b.push_back(Point2(80, 140));
+ r = Geometry2D::clip_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 2, "Polygon 'a' completely overlaps polygon 'b'. This should result in 2 clipped polygons.");
+ REQUIRE_MESSAGE(r[0].size() == 4, "The resulting clipped polygon should have 4 vertices.");
+ REQUIRE_MESSAGE(!Geometry2D::is_polygon_clockwise(r[0]), "The resulting clipped polygon (outline) should be counter-clockwise.");
+ CHECK(r[0][0].is_equal_approx(a[0]));
+ CHECK(r[0][1].is_equal_approx(a[1]));
+ CHECK(r[0][2].is_equal_approx(a[2]));
+ CHECK(r[0][3].is_equal_approx(a[3]));
+ REQUIRE_MESSAGE(r[1].size() == 3, "The resulting clipped polygon should have 3 vertices.");
+ REQUIRE_MESSAGE(Geometry2D::is_polygon_clockwise(r[1]), "The resulting clipped polygon (hole) should be clockwise.");
+ CHECK(r[1][0].is_equal_approx(b[1]));
+ CHECK(r[1][1].is_equal_approx(b[0]));
+ CHECK(r[1][2].is_equal_approx(b[2]));
+ }
+}
+
+TEST_CASE("[Geometry2D] Exclude polygons") {
+ Vector<Point2> a;
+ Vector<Point2> b;
+ Vector<Vector<Point2>> r;
+
+ a.push_back(Point2(225, 180));
+ a.push_back(Point2(160, 230));
+ a.push_back(Point2(20, 212));
+ a.push_back(Point2(50, 115));
+
+ SUBCASE("[Geometry2D] Both polygons are empty") {
+ r = Geometry2D::exclude_polygons(Vector<Point2>(), Vector<Point2>());
+ CHECK_MESSAGE(r.is_empty(), "Both polygons are empty. The excluded polygon should also be empty.");
+ }
+
+ SUBCASE("[Geometry2D] One polygon is empty") {
+ r = Geometry2D::exclude_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 1, "One polygon is non-empty. There should be 1 resulting excluded polygon.");
+ REQUIRE_MESSAGE(r[0].size() == 4, "The resulting excluded polygon should have 4 vertices.");
+ CHECK(r[0][0].is_equal_approx(a[0]));
+ CHECK(r[0][1].is_equal_approx(a[1]));
+ CHECK(r[0][2].is_equal_approx(a[2]));
+ CHECK(r[0][3].is_equal_approx(a[3]));
+ }
+
+ SUBCASE("[Geometry2D] Exclude with 2 resulting polygons (outline and hole)") {
+ b.push_back(Point2(140, 160));
+ b.push_back(Point2(150, 220));
+ b.push_back(Point2(40, 200));
+ b.push_back(Point2(60, 140));
+ r = Geometry2D::exclude_polygons(a, b);
+ REQUIRE_MESSAGE(r.size() == 2, "There should be 2 resulting excluded polygons (outline and hole).");
+ REQUIRE_MESSAGE(r[0].size() == 4, "The resulting excluded polygon should have 4 vertices.");
+ REQUIRE_MESSAGE(!Geometry2D::is_polygon_clockwise(r[0]), "The resulting excluded polygon (outline) should be counter-clockwise.");
+ CHECK(r[0][0].is_equal_approx(a[0]));
+ CHECK(r[0][1].is_equal_approx(a[1]));
+ CHECK(r[0][2].is_equal_approx(a[2]));
+ CHECK(r[0][3].is_equal_approx(a[3]));
+ REQUIRE_MESSAGE(r[1].size() == 4, "The resulting excluded polygon should have 4 vertices.");
+ REQUIRE_MESSAGE(Geometry2D::is_polygon_clockwise(r[1]), "The resulting excluded polygon (hole) should be clockwise.");
+ CHECK(r[1][0].is_equal_approx(Point2(40, 200)));
+ CHECK(r[1][1].is_equal_approx(Point2(150, 220)));
+ CHECK(r[1][2].is_equal_approx(Point2(140, 160)));
+ CHECK(r[1][3].is_equal_approx(Point2(60, 140)));
+ }
+}
+
+TEST_CASE("[Geometry2D] Intersect polyline with polygon") {
+ Vector<Vector2> l;
+ Vector<Vector2> p;
+ Vector<Vector<Point2>> r;
+
+ l.push_back(Vector2(100, 90));
+ l.push_back(Vector2(120, 250));
+
+ p.push_back(Vector2(225, 180));
+ p.push_back(Vector2(160, 230));
+ p.push_back(Vector2(20, 212));
+ p.push_back(Vector2(50, 115));
+
+ SUBCASE("[Geometry2D] Both line and polygon are empty") {
+ r = Geometry2D::intersect_polyline_with_polygon(Vector<Vector2>(), Vector<Vector2>());
+ CHECK_MESSAGE(r.is_empty(), "Both line and polygon are empty. The intersection line should also be empty.");
+ }
+
+ SUBCASE("[Geometry2D] Line is non-empty and polygon is empty") {
+ r = Geometry2D::intersect_polyline_with_polygon(l, Vector<Vector2>());
+ CHECK_MESSAGE(r.is_empty(), "The polygon is empty while the line is non-empty. The intersection line should be empty.");
+ }
+
+ SUBCASE("[Geometry2D] Basic intersection with 1 resulting intersection line") {
+ r = Geometry2D::intersect_polyline_with_polygon(l, p);
+ REQUIRE_MESSAGE(r.size() == 1, "There should be 1 resulting intersection line.");
+ REQUIRE_MESSAGE(r[0].size() == 2, "The resulting intersection line should have 2 vertices.");
+ CHECK(r[0][0].is_equal_approx(Vector2(105.711609, 135.692886)));
+ CHECK(r[0][1].is_equal_approx(Vector2(116.805809, 224.446457)));
+ }
+
+ SUBCASE("[Geometry2D] Complex intersection with 2 resulting intersection lines") {
+ l.clear();
+ l.push_back(Vector2(100, 90));
+ l.push_back(Vector2(190, 255));
+ l.push_back(Vector2(135, 260));
+ l.push_back(Vector2(57, 200));
+ l.push_back(Vector2(50, 170));
+ l.push_back(Vector2(15, 155));
+ r = Geometry2D::intersect_polyline_with_polygon(l, p);
+ REQUIRE_MESSAGE(r.size() == 2, "There should be 2 resulting intersection lines.");
+ REQUIRE_MESSAGE(r[0].size() == 2, "The resulting intersection line should have 2 vertices.");
+ CHECK(r[0][0].is_equal_approx(Vector2(129.804565, 144.641693)));
+ CHECK(r[0][1].is_equal_approx(Vector2(171.527084, 221.132996)));
+ REQUIRE_MESSAGE(r[1].size() == 4, "The resulting intersection line should have 4 vertices.");
+ CHECK(r[1][0].is_equal_approx(Vector2(83.15609, 220.120087)));
+ CHECK(r[1][1].is_equal_approx(Vector2(57, 200)));
+ CHECK(r[1][2].is_equal_approx(Vector2(50, 170)));
+ CHECK(r[1][3].is_equal_approx(Vector2(34.980492, 163.563065)));
+ }
+}
+
+TEST_CASE("[Geometry2D] Clip polyline with polygon") {
+ Vector<Vector2> l;
+ Vector<Vector2> p;
+ Vector<Vector<Point2>> r;
+
+ l.push_back(Vector2(70, 140));
+ l.push_back(Vector2(160, 320));
+
+ p.push_back(Vector2(225, 180));
+ p.push_back(Vector2(160, 230));
+ p.push_back(Vector2(20, 212));
+ p.push_back(Vector2(50, 115));
+
+ SUBCASE("[Geometry2D] Both line and polygon are empty") {
+ r = Geometry2D::clip_polyline_with_polygon(Vector<Vector2>(), Vector<Vector2>());
+ CHECK_MESSAGE(r.is_empty(), "Both line and polygon are empty. The clipped line should also be empty.");
+ }
+
+ SUBCASE("[Geometry2D] Polygon is empty and line is non-empty") {
+ r = Geometry2D::clip_polyline_with_polygon(l, Vector<Vector2>());
+ REQUIRE_MESSAGE(r.size() == 1, "There should be 1 resulting clipped line.");
+ REQUIRE_MESSAGE(r[0].size() == 2, "The resulting clipped line should have 2 vertices.");
+ CHECK(r[0][0].is_equal_approx(l[0]));
+ CHECK(r[0][1].is_equal_approx(l[1]));
+ }
+
+ SUBCASE("[Geometry2D] Basic clip with 1 resulting clipped line") {
+ r = Geometry2D::clip_polyline_with_polygon(l, p);
+ REQUIRE_MESSAGE(r.size() == 1, "There should be 1 resulting clipped line.");
+ REQUIRE_MESSAGE(r[0].size() == 2, "The resulting clipped line should have 2 vertices.");
+ CHECK(r[0][0].is_equal_approx(Vector2(111.908401, 223.816803)));
+ CHECK(r[0][1].is_equal_approx(Vector2(160, 320)));
+ }
+
+ SUBCASE("[Geometry2D] Complex clip with 2 resulting clipped lines") {
+ l.clear();
+ l.push_back(Vector2(55, 70));
+ l.push_back(Vector2(50, 190));
+ l.push_back(Vector2(120, 165));
+ l.push_back(Vector2(122, 250));
+ l.push_back(Vector2(160, 320));
+ r = Geometry2D::clip_polyline_with_polygon(l, p);
+ REQUIRE_MESSAGE(r.size() == 2, "There should be 2 resulting clipped lines.");
+ REQUIRE_MESSAGE(r[0].size() == 3, "The resulting clipped line should have 3 vertices.");
+ CHECK(r[0][0].is_equal_approx(Vector2(160, 320)));
+ CHECK(r[0][1].is_equal_approx(Vector2(122, 250)));
+ CHECK(r[0][2].is_equal_approx(Vector2(121.412682, 225.038757)));
+ REQUIRE_MESSAGE(r[1].size() == 2, "The resulting clipped line should have 2 vertices.");
+ CHECK(r[1][0].is_equal_approx(Vector2(53.07737, 116.143021)));
+ CHECK(r[1][1].is_equal_approx(Vector2(55, 70)));
+ }
+}
+} // namespace TestGeometry2D
+
+#endif // TEST_GEOMETRY_2D_H
diff --git a/tests/test_geometry_3d.h b/tests/test_geometry_3d.h
new file mode 100644
index 0000000000..2b2a424b2b
--- /dev/null
+++ b/tests/test_geometry_3d.h
@@ -0,0 +1,417 @@
+/*************************************************************************/
+/* test_geometry_3d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_3D_GEOMETRY_H
+#define TEST_3D_GEOMETRY_H
+
+#include "core/math/geometry_3d.h"
+#include "core/math/plane.h"
+#include "core/math/random_number_generator.h"
+#include "core/math/vector3.h"
+#include "tests/test_macros.h"
+#include "vector"
+
+namespace Test3DGeometry {
+TEST_CASE("[Geometry3D] Closest Points Between Segments") {
+ struct Case {
+ Vector3 p_1, p_2, p_3, p_4;
+ Vector3 got_1, got_2;
+ Vector3 want_1, want_2;
+ Case(){};
+ Case(Vector3 p_p_1, Vector3 p_p_2, Vector3 p_p_3, Vector3 p_p_4, Vector3 p_want_1, Vector3 p_want_2) :
+ p_1(p_p_1), p_2(p_p_2), p_3(p_p_3), p_4(p_p_4), want_1(p_want_1), want_2(p_want_2){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(1, -1, 1), Vector3(1, 1, -1), Vector3(-1, -2, -1), Vector3(-1, 1, 1), Vector3(1, -0.2, 0.2), Vector3(-1, -0.2, 0.2)));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ Geometry3D::get_closest_points_between_segments(current_case.p_1, current_case.p_2, current_case.p_3, current_case.p_4, current_case.got_1, current_case.got_2);
+ CHECK(current_case.got_1.is_equal_approx(current_case.want_1));
+ CHECK(current_case.got_2.is_equal_approx(current_case.want_2));
+ }
+}
+TEST_CASE("[Geometry3D] Closest Distance Between Segments") {
+ struct Case {
+ Vector3 p_1, p_2, p_3, p_4;
+ float want;
+ Case(){};
+ Case(Vector3 p_p_1, Vector3 p_p_2, Vector3 p_p_3, Vector3 p_p_4, float p_want) :
+ p_1(p_p_1), p_2(p_p_2), p_3(p_p_3), p_4(p_p_4), want(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(1, -2, 0), Vector3(1, 2, 0), Vector3(-1, 2, 0), Vector3(-1, -2, 0), 0.0f));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ float out = Geometry3D::get_closest_distance_between_segments(current_case.p_1, current_case.p_2, current_case.p_3, current_case.p_4);
+ CHECK(out == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Build Box Planes") {
+ const Vector3 extents = Vector3(5, 5, 20);
+ Vector<Plane> box = Geometry3D::build_box_planes(extents);
+ CHECK(box.size() == 6);
+ CHECK(extents.x == box[0].d);
+ CHECK(box[0].normal == Vector3(1, 0, 0));
+ CHECK(extents.x == box[1].d);
+ CHECK(box[1].normal == Vector3(-1, 0, 0));
+ CHECK(extents.y == box[2].d);
+ CHECK(box[2].normal == Vector3(0, 1, 0));
+ CHECK(extents.y == box[3].d);
+ CHECK(box[3].normal == Vector3(0, -1, 0));
+ CHECK(extents.z == box[4].d);
+ CHECK(box[4].normal == Vector3(0, 0, 1));
+ CHECK(extents.z == box[5].d);
+ CHECK(box[5].normal == Vector3(0, 0, -1));
+}
+TEST_CASE("[Geometry3D] Build Capsule Planes") {
+ struct Case {
+ real_t radius, height;
+ int sides, lats;
+ Vector3::Axis axis;
+ int want_size;
+ Case(){};
+ Case(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis, int p_want) :
+ radius(p_radius), height(p_height), sides(p_sides), lats(p_lats), axis(p_axis), want_size(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(10, 20, 6, 10, Vector3::Axis(), 126));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ Vector<Plane> capsule = Geometry3D::build_capsule_planes(current_case.radius, current_case.height, current_case.sides, current_case.lats, current_case.axis);
+ // Should equal (p_sides * p_lats) * 2 + p_sides
+ CHECK(capsule.size() == current_case.want_size);
+ }
+}
+TEST_CASE("[Geometry3D] Build Cylinder Planes") {
+ struct Case {
+ real_t radius, height;
+ int sides;
+ Vector3::Axis axis;
+ int want_size;
+ Case(){};
+ Case(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis, int p_want) :
+ radius(p_radius), height(p_height), sides(p_sides), axis(p_axis), want_size(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(3.0f, 10.0f, 10, Vector3::Axis(), 12));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ Vector<Plane> planes = Geometry3D::build_cylinder_planes(current_case.radius, current_case.height, current_case.sides, current_case.axis);
+ CHECK(planes.size() == current_case.want_size);
+ }
+}
+TEST_CASE("[Geometry3D] Build Sphere Planes") {
+ struct Case {
+ real_t radius;
+ int lats, lons;
+ Vector3::Axis axis;
+ int want_size;
+ Case(){};
+ Case(real_t p_radius, int p_lat, int p_lons, Vector3::Axis p_axis, int p_want) :
+ radius(p_radius), lats(p_lat), lons(p_lons), axis(p_axis), want_size(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(10.0f, 10, 3, Vector3::Axis(), 63));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ Vector<Plane> planes = Geometry3D::build_sphere_planes(current_case.radius, current_case.lats, current_case.lons, current_case.axis);
+ CHECK(planes.size() == 63);
+ }
+}
+TEST_CASE("[Geometry3D] Build Convex Mesh") {
+ struct Case {
+ Vector<Plane> object;
+ int want_faces, want_edges, want_vertices;
+ Case(){};
+ Case(Vector<Plane> p_object, int p_want_faces, int p_want_edges, int p_want_vertices) :
+ object(p_object), want_faces(p_want_faces), want_edges(p_want_edges), want_vertices(p_want_vertices){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Geometry3D::build_box_planes(Vector3(5, 10, 5)), 6, 12, 8));
+ tt.push_back(Case(Geometry3D::build_capsule_planes(5, 5, 20, 20, Vector3::Axis()), 820, 7603, 6243));
+ tt.push_back(Case(Geometry3D::build_cylinder_planes(5, 5, 20, Vector3::Axis()), 22, 100, 80));
+ tt.push_back(Case(Geometry3D::build_sphere_planes(5, 5, 20), 220, 1011, 522));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ Geometry3D::MeshData mesh = Geometry3D::build_convex_mesh(current_case.object);
+ CHECK(mesh.faces.size() == current_case.want_faces);
+ CHECK(mesh.edges.size() == current_case.want_edges);
+ CHECK(mesh.vertices.size() == current_case.want_vertices);
+ }
+}
+TEST_CASE("[Geometry3D] Clip Polygon") {
+ struct Case {
+ Plane clipping_plane;
+ Vector<Vector3> polygon;
+ bool want;
+ Case(){};
+ Case(Plane p_clipping_plane, Vector<Vector3> p_polygon, bool p_want) :
+ clipping_plane(p_clipping_plane), polygon(p_polygon), want(p_want){};
+ };
+ Vector<Case> tt;
+ Vector<Plane> box_planes = Geometry3D::build_box_planes(Vector3(5, 10, 5));
+ Vector<Vector3> box = Geometry3D::compute_convex_mesh_points(&box_planes[0], box_planes.size());
+ tt.push_back(Case(Plane(), box, true));
+ tt.push_back(Case(Plane(Vector3(0, 3, 0), Vector3(0, 1, 0)), box, false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ Vector<Vector3> output = Geometry3D::clip_polygon(current_case.polygon, current_case.clipping_plane);
+ if (current_case.want) {
+ CHECK(output == current_case.polygon);
+ } else {
+ CHECK(output != current_case.polygon);
+ }
+ }
+}
+TEST_CASE("[Geometry3D] Compute Convex Mesh Points") {
+ struct Case {
+ Vector<Plane> mesh;
+ Vector<Vector3> want;
+ Case(){};
+ Case(Vector<Plane> p_mesh, Vector<Vector3> p_want) :
+ mesh(p_mesh), want(p_want){};
+ };
+ Vector<Case> tt;
+ Vector<Vector3> cube;
+ cube.push_back(Vector3(-5, -5, -5));
+ cube.push_back(Vector3(5, -5, -5));
+ cube.push_back(Vector3(-5, 5, -5));
+ cube.push_back(Vector3(5, 5, -5));
+ cube.push_back(Vector3(-5, -5, 5));
+ cube.push_back(Vector3(5, -5, 5));
+ cube.push_back(Vector3(-5, 5, 5));
+ cube.push_back(Vector3(5, 5, 5));
+ tt.push_back(Case(Geometry3D::build_box_planes(Vector3(5, 5, 5)), cube));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ Vector<Vector3> vectors = Geometry3D::compute_convex_mesh_points(&current_case.mesh[0], current_case.mesh.size());
+ CHECK(vectors == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Get Closest Point To Segment") {
+ struct Case {
+ Vector3 point;
+ Vector<Vector3> segment;
+ Vector3 want;
+ Case(){};
+ Case(Vector3 p_point, Vector<Vector3> p_segment, Vector3 p_want) :
+ point(p_point), segment(p_segment), want(p_want){};
+ };
+ Vector<Case> tt;
+ Vector<Vector3> test_segment;
+ test_segment.push_back(Vector3(1, 1, 1));
+ test_segment.push_back(Vector3(5, 5, 5));
+ tt.push_back(Case(Vector3(2, 1, 4), test_segment, Vector3(2.33333, 2.33333, 2.33333)));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ Vector3 output = Geometry3D::get_closest_point_to_segment(current_case.point, &current_case.segment[0]);
+ CHECK(output.is_equal_approx(current_case.want));
+ }
+}
+TEST_CASE("[Geometry3D] Plane and Box Overlap") {
+ struct Case {
+ Vector3 normal, max_box;
+ float d;
+ bool want;
+ Case(){};
+ Case(Vector3 p_normal, float p_d, Vector3 p_max_box, bool p_want) :
+ normal(p_normal), max_box(p_max_box), d(p_d), want(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(3, 4, 2), 5, Vector3(5, 5, 5), true));
+ tt.push_back(Case(Vector3(0, 1, 0), -10, Vector3(5, 5, 5), false));
+ tt.push_back(Case(Vector3(1, 0, 0), -6, Vector3(5, 5, 5), false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool overlap = Geometry3D::planeBoxOverlap(current_case.normal, current_case.d, current_case.max_box);
+ CHECK(overlap == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Is Point in Projected Triangle") {
+ struct Case {
+ Vector3 point, v_1, v_2, v_3;
+ bool want;
+ Case(){};
+ Case(Vector3 p_point, Vector3 p_v_1, Vector3 p_v_2, Vector3 p_v_3, bool p_want) :
+ point(p_point), v_1(p_v_1), v_2(p_v_2), v_3(p_v_3), want(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(1, 1, 0), Vector3(3, 0, 0), Vector3(0, 3, 0), Vector3(-3, 0, 0), true));
+ tt.push_back(Case(Vector3(5, 1, 0), Vector3(3, 0, 0), Vector3(0, 3, 0), Vector3(-3, 0, 0), false));
+ tt.push_back(Case(Vector3(3, 0, 0), Vector3(3, 0, 0), Vector3(0, 3, 0), Vector3(-3, 0, 0), true));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool output = Geometry3D::point_in_projected_triangle(current_case.point, current_case.v_1, current_case.v_2, current_case.v_3);
+ CHECK(output == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Does Ray Intersect Triangle") {
+ struct Case {
+ Vector3 from, direction, v_1, v_2, v_3;
+ Vector3 *result;
+ bool want;
+ Case(){};
+ Case(Vector3 p_from, Vector3 p_direction, Vector3 p_v_1, Vector3 p_v_2, Vector3 p_v_3, bool p_want) :
+ from(p_from), direction(p_direction), v_1(p_v_1), v_2(p_v_2), v_3(p_v_3), result(nullptr), want(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(0, 1, 1), Vector3(0, 0, -10), Vector3(0, 3, 0), Vector3(-3, 0, 0), Vector3(3, 0, 0), true));
+ tt.push_back(Case(Vector3(5, 10, 1), Vector3(0, 0, -10), Vector3(0, 3, 0), Vector3(-3, 0, 0), Vector3(3, 0, 0), false));
+ tt.push_back(Case(Vector3(0, 1, 1), Vector3(0, 0, 10), Vector3(0, 3, 0), Vector3(-3, 0, 0), Vector3(3, 0, 0), false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool output = Geometry3D::ray_intersects_triangle(current_case.from, current_case.direction, current_case.v_1, current_case.v_2, current_case.v_3, current_case.result);
+ CHECK(output == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Does Segment Intersect Convex") {
+ struct Case {
+ Vector3 from, to;
+ Vector<Plane> planes;
+ Vector3 *result, *normal;
+ bool want;
+ Case(){};
+ Case(Vector3 p_from, Vector3 p_to, Vector<Plane> p_planes, bool p_want) :
+ from(p_from), to(p_to), planes(p_planes), result(nullptr), normal(nullptr), want(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(10, 10, 10), Vector3(0, 0, 0), Geometry3D::build_box_planes(Vector3(5, 5, 5)), true));
+ tt.push_back(Case(Vector3(10, 10, 10), Vector3(5, 5, 5), Geometry3D::build_box_planes(Vector3(5, 5, 5)), true));
+ tt.push_back(Case(Vector3(10, 10, 10), Vector3(6, 5, 5), Geometry3D::build_box_planes(Vector3(5, 5, 5)), false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool output = Geometry3D::segment_intersects_convex(current_case.from, current_case.to, &current_case.planes[0], current_case.planes.size(), current_case.result, current_case.normal);
+ CHECK(output == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Segment Intersects Cylinder") {
+ struct Case {
+ Vector3 from, to;
+ real_t height, radius;
+ Vector3 *result, *normal;
+ bool want;
+ Case(){};
+ Case(Vector3 p_from, Vector3 p_to, real_t p_height, real_t p_radius, bool p_want) :
+ from(p_from), to(p_to), height(p_height), radius(p_radius), result(nullptr), normal(nullptr), want(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(10, 10, 10), Vector3(0, 0, 0), 5, 5, true));
+ tt.push_back(Case(Vector3(10, 10, 10), Vector3(6, 6, 6), 5, 5, false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool output = Geometry3D::segment_intersects_cylinder(current_case.from, current_case.to, current_case.height, current_case.radius, current_case.result, current_case.normal);
+ CHECK(output == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Segment Intersects Cylinder") {
+ struct Case {
+ Vector3 from, to, sphere_pos;
+ real_t radius;
+ Vector3 *result, *normal;
+ bool want;
+ Case(){};
+ Case(Vector3 p_from, Vector3 p_to, Vector3 p_sphere_pos, real_t p_radius, bool p_want) :
+ from(p_from), to(p_to), sphere_pos(p_sphere_pos), radius(p_radius), result(nullptr), normal(nullptr), want(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(10, 10, 10), Vector3(0, 0, 0), Vector3(0, 0, 0), 5, true));
+ tt.push_back(Case(Vector3(10, 10, 10), Vector3(0, 0, 2.5), Vector3(0, 0, 0), 5, true));
+ tt.push_back(Case(Vector3(10, 10, 10), Vector3(5, 5, 5), Vector3(0, 0, 0), 5, false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool output = Geometry3D::segment_intersects_sphere(current_case.from, current_case.to, current_case.sphere_pos, current_case.radius, current_case.result, current_case.normal);
+ CHECK(output == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Segment Intersects Triangle") {
+ struct Case {
+ Vector3 from, to, v_1, v_2, v_3, *result;
+ bool want;
+ Case(){};
+ Case(Vector3 p_from, Vector3 p_to, Vector3 p_v_1, Vector3 p_v_2, Vector3 p_v_3, bool p_want) :
+ from(p_from), to(p_to), v_1(p_v_1), v_2(p_v_2), v_3(p_v_3), result(nullptr), want(p_want){};
+ };
+ Vector<Case> tt;
+ tt.push_back(Case(Vector3(1, 1, 1), Vector3(-1, -1, -1), Vector3(-3, 0, 0), Vector3(0, 3, 0), Vector3(3, 0, 0), true));
+ tt.push_back(Case(Vector3(1, 1, 1), Vector3(3, 0, 0), Vector3(-3, 0, 0), Vector3(0, 3, 0), Vector3(3, 0, 0), true));
+ tt.push_back(Case(Vector3(1, 1, 1), Vector3(10, -1, -1), Vector3(-3, 0, 0), Vector3(0, 3, 0), Vector3(3, 0, 0), false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool output = Geometry3D::segment_intersects_triangle(current_case.from, current_case.to, current_case.v_1, current_case.v_2, current_case.v_3, current_case.result);
+ CHECK(output == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Triangle and Box Overlap") {
+ struct Case {
+ Vector3 box_centre;
+ Vector3 box_half_size;
+ Vector3 *tri_verts;
+ bool want;
+ Case(){};
+ Case(Vector3 p_centre, Vector3 p_half_size, Vector3 *p_verts, bool p_want) :
+ box_centre(p_centre), box_half_size(p_half_size), tri_verts(p_verts), want(p_want){};
+ };
+ Vector<Case> tt;
+ Vector3 GoodTriangle[3] = { Vector3(3, 2, 3), Vector3(2, 2, 1), Vector3(2, 1, 1) };
+ tt.push_back(Case(Vector3(0, 0, 0), Vector3(5, 5, 5), GoodTriangle, true));
+ Vector3 BadTriangle[3] = { Vector3(100, 100, 100), Vector3(-100, -100, -100), Vector3(10, 10, 10) };
+ tt.push_back(Case(Vector3(1000, 1000, 1000), Vector3(1, 1, 1), BadTriangle, false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool output = Geometry3D::triangle_box_overlap(current_case.box_centre, current_case.box_half_size, current_case.tri_verts);
+ CHECK(output == current_case.want);
+ }
+}
+TEST_CASE("[Geometry3D] Triangle and Sphere Intersect") {
+ struct Case {
+ Vector<Vector3> triangle;
+ Vector3 normal, sphere_pos, triangle_contact, sphere_contact;
+ real_t sphere_radius;
+ bool want;
+ Case(){};
+ Case(Vector<Vector3> p_triangle, Vector3 p_normal, Vector3 p_sphere_pos, real_t p_sphere_radius, bool p_want) :
+ triangle(p_triangle), normal(p_normal), sphere_pos(p_sphere_pos), triangle_contact(Vector3()), sphere_contact(Vector3()), sphere_radius(p_sphere_radius), want(p_want){};
+ };
+ Vector<Case> tt;
+ Vector<Vector3> triangle;
+ triangle.push_back(Vector3(3, 0, 0));
+ triangle.push_back(Vector3(-3, 0, 0));
+ triangle.push_back(Vector3(0, 3, 0));
+ tt.push_back(Case(triangle, Vector3(0, -1, 0), Vector3(0, 0, 0), 5, true));
+ tt.push_back(Case(triangle, Vector3(0, 1, 0), Vector3(0, 0, 0), 5, true));
+ tt.push_back(Case(triangle, Vector3(0, 1, 0), Vector3(20, 0, 0), 5, false));
+ for (int i = 0; i < tt.size(); ++i) {
+ Case current_case = tt[i];
+ bool output = Geometry3D::triangle_sphere_intersection_test(&current_case.triangle[0], current_case.normal, current_case.sphere_pos, current_case.sphere_radius, current_case.triangle_contact, current_case.sphere_contact);
+ CHECK(output == current_case.want);
+ }
+}
+} // namespace Test3DGeometry
+#endif
diff --git a/tests/test_gradient.h b/tests/test_gradient.h
index 0c018c33e5..8eaa6b2b64 100644
--- a/tests/test_gradient.h
+++ b/tests/test_gradient.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_gui.cpp b/tests/test_gui.cpp
index a4559687c8..b83bd10af4 100644
--- a/tests/test_gui.cpp
+++ b/tests/test_gui.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -63,8 +63,8 @@ public:
virtual void request_quit() {
quit();
}
- virtual void init() {
- SceneTree::init();
+ virtual void initialize() {
+ SceneTree::initialize();
Panel *frame = memnew(Panel);
frame->set_anchor(SIDE_RIGHT, Control::ANCHOR_END);
diff --git a/tests/test_gui.h b/tests/test_gui.h
index 5a23179eee..e5c40de7e8 100644
--- a/tests/test_gui.h
+++ b/tests/test_gui.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_hashing_context.h b/tests/test_hashing_context.h
new file mode 100644
index 0000000000..728a5f2cfa
--- /dev/null
+++ b/tests/test_hashing_context.h
@@ -0,0 +1,165 @@
+/*************************************************************************/
+/* test_hashing_context.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_HASHING_CONTEXT_H
+#define TEST_HASHING_CONTEXT_H
+
+#include "core/crypto/hashing_context.h"
+
+#include "tests/test_macros.h"
+
+namespace TestHashingContext {
+
+TEST_CASE("[HashingContext] Default - MD5/SHA1/SHA256") {
+ HashingContext ctx;
+
+ static const uint8_t md5_expected[] = {
+ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
+ };
+ static const uint8_t sha1_expected[] = {
+ 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
+ 0xaf, 0xd8, 0x07, 0x09
+ };
+ static const uint8_t sha256_expected[] = {
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
+ };
+
+ CHECK(ctx.start(HashingContext::HASH_MD5) == OK);
+ PackedByteArray result = ctx.finish();
+ REQUIRE(result.size() == 16);
+ CHECK(memcmp(result.ptr(), md5_expected, 16) == 0);
+
+ CHECK(ctx.start(HashingContext::HASH_SHA1) == OK);
+ result = ctx.finish();
+ REQUIRE(result.size() == 20);
+ CHECK(memcmp(result.ptr(), sha1_expected, 20) == 0);
+
+ CHECK(ctx.start(HashingContext::HASH_SHA256) == OK);
+ result = ctx.finish();
+ REQUIRE(result.size() == 32);
+ CHECK(memcmp(result.ptr(), sha256_expected, 32) == 0);
+}
+
+TEST_CASE("[HashingContext] Multiple updates - MD5/SHA1/SHA256") {
+ HashingContext ctx;
+ const String s = "xyz";
+
+ const PackedByteArray s_byte_parts[] = {
+ String("x").to_ascii_buffer(),
+ String("y").to_ascii_buffer(),
+ String("z").to_ascii_buffer()
+ };
+
+ static const uint8_t md5_expected[] = {
+ 0xd1, 0x6f, 0xb3, 0x6f, 0x09, 0x11, 0xf8, 0x78, 0x99, 0x8c, 0x13, 0x61, 0x91, 0xaf, 0x70, 0x5e
+ };
+ static const uint8_t sha1_expected[] = {
+ 0x66, 0xb2, 0x74, 0x17, 0xd3, 0x7e, 0x02, 0x4c, 0x46, 0x52, 0x6c, 0x2f, 0x6d, 0x35, 0x8a, 0x75,
+ 0x4f, 0xc5, 0x52, 0xf3
+ };
+ static const uint8_t sha256_expected[] = {
+ 0x36, 0x08, 0xbc, 0xa1, 0xe4, 0x4e, 0xa6, 0xc4, 0xd2, 0x68, 0xeb, 0x6d, 0xb0, 0x22, 0x60, 0x26,
+ 0x98, 0x92, 0xc0, 0xb4, 0x2b, 0x86, 0xbb, 0xf1, 0xe7, 0x7a, 0x6f, 0xa1, 0x6c, 0x3c, 0x92, 0x82
+ };
+
+ CHECK(ctx.start(HashingContext::HASH_MD5) == OK);
+ CHECK(ctx.update(s_byte_parts[0]) == OK);
+ CHECK(ctx.update(s_byte_parts[1]) == OK);
+ CHECK(ctx.update(s_byte_parts[2]) == OK);
+ PackedByteArray result = ctx.finish();
+ REQUIRE(result.size() == 16);
+ CHECK(memcmp(result.ptr(), md5_expected, 16) == 0);
+
+ CHECK(ctx.start(HashingContext::HASH_SHA1) == OK);
+ CHECK(ctx.update(s_byte_parts[0]) == OK);
+ CHECK(ctx.update(s_byte_parts[1]) == OK);
+ CHECK(ctx.update(s_byte_parts[2]) == OK);
+ result = ctx.finish();
+ REQUIRE(result.size() == 20);
+ CHECK(memcmp(result.ptr(), sha1_expected, 20) == 0);
+
+ CHECK(ctx.start(HashingContext::HASH_SHA256) == OK);
+ CHECK(ctx.update(s_byte_parts[0]) == OK);
+ CHECK(ctx.update(s_byte_parts[1]) == OK);
+ CHECK(ctx.update(s_byte_parts[2]) == OK);
+ result = ctx.finish();
+ REQUIRE(result.size() == 32);
+ CHECK(memcmp(result.ptr(), sha256_expected, 32) == 0);
+}
+
+TEST_CASE("[HashingContext] Invalid use of start") {
+ HashingContext ctx;
+
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ ctx.start(static_cast<HashingContext::HashType>(-1)) == ERR_UNAVAILABLE,
+ "Using invalid hash types should fail.");
+ ERR_PRINT_ON;
+
+ REQUIRE(ctx.start(HashingContext::HASH_MD5) == OK);
+
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ ctx.start(HashingContext::HASH_MD5) == ERR_ALREADY_IN_USE,
+ "Calling 'start' twice before 'finish' should fail.");
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[HashingContext] Invalid use of update") {
+ HashingContext ctx;
+
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ ctx.update(PackedByteArray()) == ERR_UNCONFIGURED,
+ "Calling 'update' before 'start' should fail.");
+ ERR_PRINT_ON;
+
+ REQUIRE(ctx.start(HashingContext::HASH_MD5) == OK);
+
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ ctx.update(PackedByteArray()) == FAILED,
+ "Calling 'update' with an empty byte array should fail.");
+ ERR_PRINT_ON;
+}
+
+TEST_CASE("[HashingContext] Invalid use of finish") {
+ HashingContext ctx;
+
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ ctx.finish() == PackedByteArray(),
+ "Calling 'finish' before 'start' should return an empty byte array.");
+ ERR_PRINT_ON;
+}
+} // namespace TestHashingContext
+
+#endif // TEST_HASHING_CONTEXT_H
diff --git a/tests/test_image.h b/tests/test_image.h
new file mode 100644
index 0000000000..d73717f5b7
--- /dev/null
+++ b/tests/test_image.h
@@ -0,0 +1,259 @@
+/*************************************************************************/
+/* test_image.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_IMAGE_H
+#define TEST_IMAGE_H
+
+#include "core/io/file_access_pack.h"
+#include "core/io/image.h"
+#include "test_utils.h"
+
+#include "thirdparty/doctest/doctest.h"
+
+namespace TestImage {
+
+TEST_CASE("[Image] Instantiation") {
+ Ref<Image> image = memnew(Image(8, 4, false, Image::FORMAT_RGBA8));
+ CHECK_MESSAGE(
+ !image->is_empty(),
+ "An image created with specified size and format should not be empty at first.");
+ CHECK_MESSAGE(
+ image->is_invisible(),
+ "A newly created image should be invisible.");
+ CHECK_MESSAGE(
+ !image->is_compressed(),
+ "A newly created image should not be compressed.");
+ CHECK(!image->has_mipmaps());
+
+ Ref<Image> image_copy = memnew(Image());
+ CHECK_MESSAGE(
+ image_copy->is_empty(),
+ "An image created without any specified size and format be empty at first.");
+ image_copy->copy_internals_from(image);
+
+ CHECK_MESSAGE(
+ image->get_data() == image_copy->get_data(),
+ "Duplicated images should have the same data.");
+
+ PackedByteArray image_data = image->get_data();
+ Ref<Image> image_from_data = memnew(Image(8, 4, false, Image::FORMAT_RGBA8, image_data));
+ CHECK_MESSAGE(
+ image->get_data() == image_from_data->get_data(),
+ "An image created from data of another image should have the same data of the original image.");
+}
+
+TEST_CASE("[Image] Saving and loading") {
+ Ref<Image> image = memnew(Image(4, 4, false, Image::FORMAT_RGBA8));
+ const String save_path_png = OS::get_singleton()->get_cache_path().plus_file("image.png");
+ const String save_path_exr = OS::get_singleton()->get_cache_path().plus_file("image.exr");
+
+ // Save PNG
+ Error err;
+ err = image->save_png(save_path_png);
+ CHECK_MESSAGE(
+ err == OK,
+ "The image should be saved successfully as a .png file.");
+
+ // Save EXR
+ err = image->save_exr(save_path_exr, false);
+ CHECK_MESSAGE(
+ err == OK,
+ "The image should be saved successfully as an .exr file.");
+
+ // Load using load()
+ Ref<Image> image_load = memnew(Image());
+ err = image_load->load(save_path_png);
+ CHECK_MESSAGE(
+ err == OK,
+ "The image should load successfully using load().");
+ CHECK_MESSAGE(
+ image->get_data() == image_load->get_data(),
+ "The loaded image should have the same data as the one that got saved.");
+
+ // Load BMP
+ Ref<Image> image_bmp = memnew(Image());
+ FileAccessRef f_bmp = FileAccess::open(TestUtils::get_data_path("images/icon.bmp"), FileAccess::READ, &err);
+ PackedByteArray data_bmp;
+ data_bmp.resize(f_bmp->get_len() + 1);
+ f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_len());
+ CHECK_MESSAGE(
+ image_bmp->load_bmp_from_buffer(data_bmp) == OK,
+ "The BMP image should load successfully.");
+
+ // Load JPG
+ Ref<Image> image_jpg = memnew(Image());
+ FileAccessRef f_jpg = FileAccess::open(TestUtils::get_data_path("images/icon.jpg"), FileAccess::READ, &err);
+ PackedByteArray data_jpg;
+ data_jpg.resize(f_jpg->get_len() + 1);
+ f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_len());
+ CHECK_MESSAGE(
+ image_jpg->load_jpg_from_buffer(data_jpg) == OK,
+ "The JPG image should load successfully.");
+
+ // Load WEBP
+ Ref<Image> image_webp = memnew(Image());
+ FileAccessRef f_webp = FileAccess::open(TestUtils::get_data_path("images/icon.webp"), FileAccess::READ, &err);
+ PackedByteArray data_webp;
+ data_webp.resize(f_webp->get_len() + 1);
+ f_webp->get_buffer(data_webp.ptrw(), f_webp->get_len());
+ CHECK_MESSAGE(
+ image_webp->load_webp_from_buffer(data_webp) == OK,
+ "The WEBP image should load successfully.");
+
+ // Load PNG
+ Ref<Image> image_png = memnew(Image());
+ FileAccessRef f_png = FileAccess::open(TestUtils::get_data_path("images/icon.png"), FileAccess::READ, &err);
+ PackedByteArray data_png;
+ data_png.resize(f_png->get_len() + 1);
+ f_png->get_buffer(data_png.ptrw(), f_png->get_len());
+ CHECK_MESSAGE(
+ image_png->load_png_from_buffer(data_png) == OK,
+ "The PNG image should load successfully.");
+
+ // Load TGA
+ Ref<Image> image_tga = memnew(Image());
+ FileAccessRef f_tga = FileAccess::open(TestUtils::get_data_path("images/icon.tga"), FileAccess::READ, &err);
+ PackedByteArray data_tga;
+ data_tga.resize(f_tga->get_len() + 1);
+ f_tga->get_buffer(data_tga.ptrw(), f_tga->get_len());
+ CHECK_MESSAGE(
+ image_tga->load_tga_from_buffer(data_tga) == OK,
+ "The TGA image should load successfully.");
+}
+
+TEST_CASE("[Image] Basic getters") {
+ Ref<Image> image = memnew(Image(8, 4, false, Image::FORMAT_LA8));
+ CHECK(image->get_width() == 8);
+ CHECK(image->get_height() == 4);
+ CHECK(image->get_size() == Vector2(8, 4));
+ CHECK(image->get_format() == Image::FORMAT_LA8);
+ CHECK(image->get_used_rect() == Rect2(0, 0, 0, 0));
+ Ref<Image> image_get_rect = image->get_rect(Rect2(0, 0, 2, 1));
+ CHECK(image_get_rect->get_size() == Vector2(2, 1));
+}
+
+TEST_CASE("[Image] Resizing") {
+ Ref<Image> image = memnew(Image(8, 8, false, Image::FORMAT_RGBA8));
+ // Crop
+ image->crop(4, 4);
+ CHECK_MESSAGE(
+ image->get_size() == Vector2(4, 4),
+ "get_size() should return the correct size after cropping.");
+ image->set_pixel(0, 0, Color(1, 1, 1, 1));
+
+ // Resize
+ for (int i = 0; i < 5; i++) {
+ Ref<Image> image_resized = memnew(Image());
+ image_resized->copy_internals_from(image);
+ Image::Interpolation interpolation = static_cast<Image::Interpolation>(i);
+ image_resized->resize(8, 8, interpolation);
+ CHECK_MESSAGE(
+ image_resized->get_size() == Vector2(8, 8),
+ "get_size() should return the correct size after resizing.");
+ CHECK_MESSAGE(
+ image_resized->get_pixel(1, 1).a > 0,
+ "Resizing an image should also affect its content.");
+ }
+
+ // shrink_x2()
+ image->shrink_x2();
+ CHECK_MESSAGE(
+ image->get_size() == Vector2(2, 2),
+ "get_size() should return the correct size after shrink_x2().");
+
+ // resize_to_po2()
+ Ref<Image> image_po_2 = memnew(Image(14, 28, false, Image::FORMAT_RGBA8));
+ image_po_2->resize_to_po2();
+ CHECK_MESSAGE(
+ image_po_2->get_size() == Vector2(16, 32),
+ "get_size() should return the correct size after resize_to_po2().");
+}
+
+TEST_CASE("[Image] Modifying pixels of an image") {
+ Ref<Image> image = memnew(Image(3, 3, false, Image::FORMAT_RGBA8));
+ image->set_pixel(0, 0, Color(1, 1, 1, 1));
+ CHECK_MESSAGE(
+ !image->is_invisible(),
+ "Image should not be invisible after drawing on it.");
+ CHECK_MESSAGE(
+ image->get_pixelv(Vector2(0, 0)).is_equal_approx(Color(1, 1, 1, 1)),
+ "Image's get_pixel() should return the same color value as the one being set with set_pixel() in the same position.");
+ CHECK_MESSAGE(
+ image->get_used_rect() == Rect2(0, 0, 1, 1),
+ "Image's get_used_rect should return the expected value, larger than Rect2(0, 0, 0, 0) if it's visible.");
+
+ image->set_pixelv(Vector2(0, 0), Color(0.5, 0.5, 0.5, 0.5));
+ Ref<Image> image2 = memnew(Image(3, 3, false, Image::FORMAT_RGBA8));
+
+ // Fill image with color
+ image2->fill(Color(0.5, 0.5, 0.5, 0.5));
+ for (int x = 0; x < image2->get_width(); x++) {
+ for (int y = 0; y < image2->get_height(); y++) {
+ CHECK_MESSAGE(
+ image2->get_pixel(x, y).r > 0.49,
+ "fill() should colorize all pixels of the image.");
+ }
+ }
+
+ // Blend two images together
+ image->blend_rect(image2, Rect2(Vector2(0, 0), image2->get_size()), Vector2(0, 0));
+ CHECK_MESSAGE(
+ image->get_pixel(0, 0).a > 0.7,
+ "blend_rect() should blend the alpha values of the two images.");
+ CHECK_MESSAGE(
+ image->get_used_rect().size == image->get_size(),
+ "get_used_rect() should return the expected value, its Rect size should be the same as get_size() if there are no transparent pixels.");
+
+ Ref<Image> image3 = memnew(Image(2, 2, false, Image::FORMAT_RGBA8));
+ image3->set_pixel(0, 0, Color(0, 1, 0, 1));
+
+ //blit_rect() two images together
+ image->blit_rect(image3, Rect2(Vector2(0, 0), image3->get_size()), Vector2(0, 0));
+ CHECK_MESSAGE(
+ image->get_pixel(0, 0).is_equal_approx(Color(0, 1, 0, 1)),
+ "blit_rect() should replace old colors and not blend them.");
+ CHECK_MESSAGE(
+ !image->get_pixel(2, 2).is_equal_approx(Color(0, 1, 0, 1)),
+ "blit_rect() should not affect the area of the image that is outside src_rect.");
+
+ // Flip image
+ image3->flip_x();
+ CHECK(image3->get_pixel(1, 0).is_equal_approx(Color(0, 1, 0, 1)));
+ CHECK_MESSAGE(
+ image3->get_pixel(0, 0).is_equal_approx(Color(0, 0, 0, 0)),
+ "flip_x() should not leave old pixels behind.");
+ image3->flip_y();
+ CHECK(image3->get_pixel(1, 1).is_equal_approx(Color(0, 1, 0, 1)));
+ CHECK_MESSAGE(
+ image3->get_pixel(1, 0).is_equal_approx(Color(0, 0, 0, 0)),
+ "flip_y() should not leave old pixels behind.");
+}
+} // namespace TestImage
+#endif // TEST_IMAGE_H
diff --git a/tests/test_json.h b/tests/test_json.h
index fe29e89e06..e652a8fced 100644
--- a/tests/test_json.h
+++ b/tests/test_json.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_list.h b/tests/test_list.h
index 8d29bd907f..1c70b6e961 100644
--- a/tests/test_list.h
+++ b/tests/test_list.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,7 +57,7 @@ TEST_CASE("[List] Push/pop back") {
CHECK(n->get() == "C");
CHECK(list.size() == 3);
- CHECK(!list.empty());
+ CHECK(!list.is_empty());
String v;
v = list.back()->get();
@@ -71,7 +71,7 @@ TEST_CASE("[List] Push/pop back") {
CHECK(v == "A");
CHECK(list.size() == 0);
- CHECK(list.empty());
+ CHECK(list.is_empty());
CHECK(list.back() == nullptr);
CHECK(list.front() == nullptr);
@@ -89,7 +89,7 @@ TEST_CASE("[List] Push/pop front") {
CHECK(n->get() == "C");
CHECK(list.size() == 3);
- CHECK(!list.empty());
+ CHECK(!list.is_empty());
String v;
v = list.front()->get();
@@ -103,7 +103,7 @@ TEST_CASE("[List] Push/pop front") {
CHECK(v == "A");
CHECK(list.size() == 0);
- CHECK(list.empty());
+ CHECK(list.is_empty());
CHECK(list.back() == nullptr);
CHECK(list.front() == nullptr);
@@ -252,7 +252,7 @@ TEST_CASE("[List] Clear") {
list.clear();
CHECK(list.size() == 0);
- CHECK(list.empty());
+ CHECK(list.is_empty());
}
TEST_CASE("[List] Invert") {
diff --git a/tests/test_local_vector.h b/tests/test_local_vector.h
new file mode 100644
index 0000000000..eff2a16abc
--- /dev/null
+++ b/tests/test_local_vector.h
@@ -0,0 +1,229 @@
+/*************************************************************************/
+/* test_local_vector.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_LOCAL_VECTOR_H
+#define TEST_LOCAL_VECTOR_H
+
+#include "core/templates/local_vector.h"
+
+#include "tests/test_macros.h"
+
+namespace TestLocalVector {
+
+TEST_CASE("[LocalVector] Push Back.") {
+ LocalVector<int> vector;
+ vector.push_back(0);
+ vector.push_back(1);
+ vector.push_back(2);
+ vector.push_back(3);
+ vector.push_back(4);
+
+ CHECK(vector[0] == 0);
+ CHECK(vector[1] == 1);
+ CHECK(vector[2] == 2);
+ CHECK(vector[3] == 3);
+ CHECK(vector[4] == 4);
+}
+
+TEST_CASE("[LocalVector] Find.") {
+ LocalVector<int> vector;
+ vector.push_back(3);
+ vector.push_back(1);
+ vector.push_back(4);
+ vector.push_back(0);
+ vector.push_back(2);
+
+ CHECK(vector[0] == 3);
+ CHECK(vector[1] == 1);
+ CHECK(vector[2] == 4);
+ CHECK(vector[3] == 0);
+ CHECK(vector[4] == 2);
+
+ CHECK(vector.find(0) == 3);
+ CHECK(vector.find(1) == 1);
+ CHECK(vector.find(2) == 4);
+ CHECK(vector.find(3) == 0);
+ CHECK(vector.find(4) == 2);
+
+ CHECK(vector.find(-1) == -1);
+ CHECK(vector.find(5) == -1);
+}
+
+TEST_CASE("[LocalVector] Remove.") {
+ LocalVector<int> vector;
+ vector.push_back(0);
+ vector.push_back(1);
+ vector.push_back(2);
+ vector.push_back(3);
+ vector.push_back(4);
+
+ vector.remove(0);
+
+ CHECK(vector[0] == 1);
+ CHECK(vector[1] == 2);
+ CHECK(vector[2] == 3);
+ CHECK(vector[3] == 4);
+
+ vector.remove(2);
+
+ CHECK(vector[0] == 1);
+ CHECK(vector[1] == 2);
+ CHECK(vector[2] == 4);
+
+ vector.remove(1);
+
+ CHECK(vector[0] == 1);
+ CHECK(vector[1] == 4);
+
+ vector.remove(0);
+
+ CHECK(vector[0] == 4);
+}
+
+TEST_CASE("[LocalVector] Remove Unordered.") {
+ LocalVector<int> vector;
+ vector.push_back(0);
+ vector.push_back(1);
+ vector.push_back(2);
+ vector.push_back(3);
+ vector.push_back(4);
+
+ CHECK(vector.size() == 5);
+
+ vector.remove_unordered(0);
+
+ CHECK(vector.size() == 4);
+
+ CHECK(vector.find(0) == -1);
+ CHECK(vector.find(1) != -1);
+ CHECK(vector.find(2) != -1);
+ CHECK(vector.find(3) != -1);
+ CHECK(vector.find(4) != -1);
+
+ // Now the vector is no more ordered.
+ vector.remove_unordered(vector.find(3));
+
+ CHECK(vector.size() == 3);
+
+ CHECK(vector.find(3) == -1);
+ CHECK(vector.find(1) != -1);
+ CHECK(vector.find(2) != -1);
+ CHECK(vector.find(4) != -1);
+
+ vector.remove_unordered(vector.find(2));
+
+ CHECK(vector.size() == 2);
+
+ CHECK(vector.find(2) == -1);
+ CHECK(vector.find(1) != -1);
+ CHECK(vector.find(4) != -1);
+
+ vector.remove_unordered(vector.find(4));
+
+ CHECK(vector.size() == 1);
+
+ CHECK(vector.find(4) == -1);
+ CHECK(vector.find(1) != -1);
+
+ // Remove the last one.
+ vector.remove_unordered(0);
+
+ CHECK(vector.is_empty());
+ CHECK(vector.size() == 0);
+}
+
+TEST_CASE("[LocalVector] Erase.") {
+ LocalVector<int> vector;
+ vector.push_back(1);
+ vector.push_back(3);
+ vector.push_back(0);
+ vector.push_back(2);
+ vector.push_back(4);
+
+ CHECK(vector.find(2) == 3);
+
+ vector.erase(2);
+
+ CHECK(vector.find(2) == -1);
+ CHECK(vector.size() == 4);
+}
+
+TEST_CASE("[LocalVector] Size / Resize / Reserve.") {
+ LocalVector<int> vector;
+
+ CHECK(vector.is_empty());
+ CHECK(vector.size() == 0);
+ CHECK(vector.get_capacity() == 0);
+
+ vector.resize(10);
+
+ CHECK(vector.size() == 10);
+ CHECK(vector.get_capacity() >= 10);
+
+ vector.resize(5);
+
+ CHECK(vector.size() == 5);
+ // Capacity is supposed to change only when the size increase.
+ CHECK(vector.get_capacity() >= 10);
+
+ vector.remove(0);
+ vector.remove(0);
+ vector.remove(0);
+
+ CHECK(vector.size() == 2);
+ // Capacity is supposed to change only when the size increase.
+ CHECK(vector.get_capacity() >= 10);
+
+ vector.reset();
+
+ CHECK(vector.size() == 0);
+ CHECK(vector.get_capacity() == 0);
+
+ vector.reserve(3);
+
+ CHECK(vector.is_empty());
+ CHECK(vector.size() == 0);
+ CHECK(vector.get_capacity() >= 3);
+
+ vector.push_back(0);
+ vector.push_back(0);
+ vector.push_back(0);
+
+ CHECK(vector.size() == 3);
+ CHECK(vector.get_capacity() >= 3);
+
+ vector.push_back(0);
+
+ CHECK(vector.size() == 4);
+ CHECK(vector.get_capacity() >= 4);
+}
+} // namespace TestLocalVector
+
+#endif // TEST_LOCAL_VECTOR_H
diff --git a/tests/test_lru.h b/tests/test_lru.h
index 260841f4c4..2802754729 100644
--- a/tests/test_lru.h
+++ b/tests/test_lru.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_macros.cpp b/tests/test_macros.cpp
index 2317223b23..b0b28ab374 100644
--- a/tests/test_macros.cpp
+++ b/tests/test_macros.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_macros.h b/tests/test_macros.h
index ae6af93825..a13f3abbe7 100644
--- a/tests/test_macros.h
+++ b/tests/test_macros.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,6 +44,12 @@
// The test case is marked as failed, but does not fail the entire test run.
#define TEST_CASE_MAY_FAIL(name) TEST_CASE(name *doctest::may_fail())
+// Provide aliases to conform with Godot naming conventions (see error macros).
+#define TEST_COND(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)
+#define TEST_FAIL(cond, ...) DOCTEST_FAIL(cond, __VA_ARGS__)
+#define TEST_FAIL_COND(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)
+#define TEST_FAIL_COND_WARN(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)
+
// Temporarily disable error prints to test failure paths.
// This allows to avoid polluting the test summary with error messages.
// The `_print_error_enabled` boolean is defined in `core/print_string.cpp` and
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index 5d961854cb..f2a546de9b 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,7 @@
#include "core/templates/list.h"
#include "test_aabb.h"
+#include "test_array.h"
#include "test_astar.h"
#include "test_basis.h"
#include "test_class_db.h"
@@ -43,11 +44,17 @@
#include "test_curve.h"
#include "test_expression.h"
#include "test_file_access.h"
+#include "test_geometry_2d.h"
+#include "test_geometry_3d.h"
#include "test_gradient.h"
#include "test_gui.h"
+#include "test_hashing_context.h"
+#include "test_image.h"
#include "test_json.h"
#include "test_list.h"
+#include "test_local_vector.h"
#include "test_lru.h"
+#include "test_marshalls.h"
#include "test_math.h"
#include "test_method_bind.h"
#include "test_node_path.h"
@@ -61,11 +68,13 @@
#include "test_random_number_generator.h"
#include "test_rect2.h"
#include "test_render.h"
+#include "test_resource.h"
#include "test_shader_lang.h"
#include "test_string.h"
#include "test_text_server.h"
#include "test_validate_testing.h"
#include "test_variant.h"
+#include "test_xml_parser.h"
#include "modules/modules_tests.gen.h"
diff --git a/tests/test_main.h b/tests/test_main.h
index 983bfde402..8c506a776f 100644
--- a/tests/test_main.h
+++ b/tests/test_main.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_marshalls.h b/tests/test_marshalls.h
new file mode 100644
index 0000000000..6bd916164e
--- /dev/null
+++ b/tests/test_marshalls.h
@@ -0,0 +1,329 @@
+/*************************************************************************/
+/* test_marshalls.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_MARSHALLS_H
+#define TEST_MARSHALLS_H
+
+#include "core/io/marshalls.h"
+
+#include "tests/test_macros.h"
+
+namespace TestMarshalls {
+
+TEST_CASE("[Marshalls] Unsigned 16 bit integer encoding") {
+ uint8_t arr[2];
+
+ unsigned int actual_size = encode_uint16(0x1234, arr);
+ CHECK(actual_size == sizeof(uint16_t));
+ CHECK_MESSAGE(arr[0] == 0x34, "First encoded byte value should be equal to low order byte value.");
+ CHECK_MESSAGE(arr[1] == 0x12, "Last encoded byte value should be equal to high order byte value.");
+}
+
+TEST_CASE("[Marshalls] Unsigned 32 bit integer encoding") {
+ uint8_t arr[4];
+
+ unsigned int actual_size = encode_uint32(0x12345678, arr);
+ CHECK(actual_size == sizeof(uint32_t));
+ CHECK_MESSAGE(arr[0] == 0x78, "First encoded byte value should be equal to low order byte value.");
+ CHECK(arr[1] == 0x56);
+ CHECK(arr[2] == 0x34);
+ CHECK_MESSAGE(arr[3] == 0x12, "Last encoded byte value should be equal to high order byte value.");
+}
+
+TEST_CASE("[Marshalls] Unsigned 64 bit integer encoding") {
+ uint8_t arr[8];
+
+ unsigned int actual_size = encode_uint64(0x0f123456789abcdef, arr);
+ CHECK(actual_size == sizeof(uint64_t));
+ CHECK_MESSAGE(arr[0] == 0xef, "First encoded byte value should be equal to low order byte value.");
+ CHECK(arr[1] == 0xcd);
+ CHECK(arr[2] == 0xab);
+ CHECK(arr[3] == 0x89);
+ CHECK(arr[4] == 0x67);
+ CHECK(arr[5] == 0x45);
+ CHECK(arr[6] == 0x23);
+ CHECK_MESSAGE(arr[7] == 0xf1, "Last encoded byte value should be equal to high order byte value.");
+}
+
+TEST_CASE("[Marshalls] Unsigned 16 bit integer decoding") {
+ uint8_t arr[] = { 0x34, 0x12 };
+
+ CHECK(decode_uint16(arr) == 0x1234);
+}
+
+TEST_CASE("[Marshalls] Unsigned 32 bit integer decoding") {
+ uint8_t arr[] = { 0x78, 0x56, 0x34, 0x12 };
+
+ CHECK(decode_uint32(arr) == 0x12345678);
+}
+
+TEST_CASE("[Marshalls] Unsigned 64 bit integer decoding") {
+ uint8_t arr[] = { 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0xf1 };
+
+ CHECK(decode_uint64(arr) == 0x0f123456789abcdef);
+}
+
+TEST_CASE("[Marshalls] Floating point single precision encoding") {
+ uint8_t arr[4];
+
+ // Decimal: 0.15625
+ // IEEE 754 single-precision binary floating-point format:
+ // sign exponent (8 bits) fraction (23 bits)
+ // 0 01111100 01000000000000000000000
+ // Hexadecimal: 0x3E200000
+ unsigned int actual_size = encode_float(0.15625f, arr);
+ CHECK(actual_size == sizeof(uint32_t));
+ CHECK(arr[0] == 0x00);
+ CHECK(arr[1] == 0x00);
+ CHECK(arr[2] == 0x20);
+ CHECK(arr[3] == 0x3e);
+}
+
+TEST_CASE("[Marshalls] Floating point double precision encoding") {
+ uint8_t arr[8];
+
+ // Decimal: 0.333333333333333314829616256247390992939472198486328125
+ // IEEE 754 double-precision binary floating-point format:
+ // sign exponent (11 bits) fraction (52 bits)
+ // 0 01111111101 0101010101010101010101010101010101010101010101010101
+ // Hexadecimal: 0x3FD5555555555555
+ unsigned int actual_size = encode_double(0.33333333333333333, arr);
+ CHECK(actual_size == sizeof(uint64_t));
+ CHECK(arr[0] == 0x55);
+ CHECK(arr[1] == 0x55);
+ CHECK(arr[2] == 0x55);
+ CHECK(arr[3] == 0x55);
+ CHECK(arr[4] == 0x55);
+ CHECK(arr[5] == 0x55);
+ CHECK(arr[6] == 0xd5);
+ CHECK(arr[7] == 0x3f);
+}
+
+TEST_CASE("[Marshalls] Floating point single precision decoding") {
+ uint8_t arr[] = { 0x00, 0x00, 0x20, 0x3e };
+
+ // See floating point encoding test case for details behind expected values
+ CHECK(decode_float(arr) == 0.15625f);
+}
+
+TEST_CASE("[Marshalls] Floating point double precision decoding") {
+ uint8_t arr[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x3f };
+
+ // See floating point encoding test case for details behind expected values
+ CHECK(decode_double(arr) == 0.33333333333333333);
+}
+
+TEST_CASE("[Marshalls] C string encoding") {
+ char cstring[] = "Godot"; // 5 characters
+ uint8_t data[6];
+
+ int actual_size = encode_cstring(cstring, data);
+ CHECK(actual_size == 6);
+ CHECK(data[0] == 'G');
+ CHECK(data[1] == 'o');
+ CHECK(data[2] == 'd');
+ CHECK(data[3] == 'o');
+ CHECK(data[4] == 't');
+ CHECK(data[5] == '\0');
+}
+
+TEST_CASE("[Marshalls] NIL Variant encoding") {
+ int r_len;
+ Variant variant;
+ uint8_t buffer[4];
+
+ CHECK(encode_variant(variant, buffer, r_len) == OK);
+ CHECK_MESSAGE(r_len == 4, "Length == 4 bytes for Variant::Type");
+ CHECK_MESSAGE(buffer[0] == 0x00, "Variant::NIL");
+ CHECK(buffer[1] == 0x00);
+ CHECK(buffer[2] == 0x00);
+ CHECK(buffer[3] == 0x00);
+ // No value
+}
+
+TEST_CASE("[Marshalls] INT 32 bit Variant encoding") {
+ int r_len;
+ Variant variant(0x12345678);
+ uint8_t buffer[8];
+
+ CHECK(encode_variant(variant, buffer, r_len) == OK);
+ CHECK_MESSAGE(r_len == 8, "Length == 4 bytes for Variant::Type + 4 bytes for int32_t");
+ CHECK_MESSAGE(buffer[0] == 0x02, "Variant::INT");
+ CHECK(buffer[1] == 0x00);
+ CHECK(buffer[2] == 0x00);
+ CHECK(buffer[3] == 0x00);
+ // Check value
+ CHECK(buffer[4] == 0x78);
+ CHECK(buffer[5] == 0x56);
+ CHECK(buffer[6] == 0x34);
+ CHECK(buffer[7] == 0x12);
+}
+
+TEST_CASE("[Marshalls] INT 64 bit Variant encoding") {
+ int r_len;
+ Variant variant(uint64_t(0x0f123456789abcdef));
+ uint8_t buffer[12];
+
+ CHECK(encode_variant(variant, buffer, r_len) == OK);
+ CHECK_MESSAGE(r_len == 12, "Length == 4 bytes for Variant::Type + 8 bytes for int64_t");
+ CHECK_MESSAGE(buffer[0] == 0x02, "Variant::INT");
+ CHECK(buffer[1] == 0x00);
+ CHECK_MESSAGE(buffer[2] == 0x01, "ENCODE_FLAG_64");
+ CHECK(buffer[3] == 0x00);
+ // Check value
+ CHECK(buffer[4] == 0xef);
+ CHECK(buffer[5] == 0xcd);
+ CHECK(buffer[6] == 0xab);
+ CHECK(buffer[7] == 0x89);
+ CHECK(buffer[8] == 0x67);
+ CHECK(buffer[9] == 0x45);
+ CHECK(buffer[10] == 0x23);
+ CHECK(buffer[11] == 0xf1);
+}
+
+TEST_CASE("[Marshalls] FLOAT single precision Variant encoding") {
+ int r_len;
+ Variant variant(0.15625f);
+ uint8_t buffer[8];
+
+ CHECK(encode_variant(variant, buffer, r_len) == OK);
+ CHECK_MESSAGE(r_len == 8, "Length == 4 bytes for Variant::Type + 4 bytes for float");
+ CHECK_MESSAGE(buffer[0] == 0x03, "Variant::FLOAT");
+ CHECK(buffer[1] == 0x00);
+ CHECK(buffer[2] == 0x00);
+ CHECK(buffer[3] == 0x00);
+ // Check value
+ CHECK(buffer[4] == 0x00);
+ CHECK(buffer[5] == 0x00);
+ CHECK(buffer[6] == 0x20);
+ CHECK(buffer[7] == 0x3e);
+}
+
+TEST_CASE("[Marshalls] FLOAT double precision Variant encoding") {
+ int r_len;
+ Variant variant(0.33333333333333333);
+ uint8_t buffer[12];
+
+ CHECK(encode_variant(variant, buffer, r_len) == OK);
+ CHECK_MESSAGE(r_len == 12, "Length == 4 bytes for Variant::Type + 8 bytes for double");
+ CHECK_MESSAGE(buffer[0] == 0x03, "Variant::FLOAT");
+ CHECK(buffer[1] == 0x00);
+ CHECK_MESSAGE(buffer[2] == 0x01, "ENCODE_FLAG_64");
+ CHECK(buffer[3] == 0x00);
+ // Check value
+ CHECK(buffer[4] == 0x55);
+ CHECK(buffer[5] == 0x55);
+ CHECK(buffer[6] == 0x55);
+ CHECK(buffer[7] == 0x55);
+ CHECK(buffer[8] == 0x55);
+ CHECK(buffer[9] == 0x55);
+ CHECK(buffer[10] == 0xd5);
+ CHECK(buffer[11] == 0x3f);
+}
+
+TEST_CASE("[Marshalls] Invalid data Variant decoding") {
+ Variant variant;
+ int r_len = 0;
+ uint8_t some_buffer[1] = { 0x00 };
+ uint8_t out_of_range_type_buffer[4] = { 0xff }; // Greater than Variant::VARIANT_MAX
+
+ CHECK(decode_variant(variant, some_buffer, /* less than 4 */ 1, &r_len) == ERR_INVALID_DATA);
+ CHECK(r_len == 0);
+
+ CHECK(decode_variant(variant, out_of_range_type_buffer, 4, &r_len) == ERR_INVALID_DATA);
+ CHECK(r_len == 0);
+}
+
+TEST_CASE("[Marshalls] NIL Variant decoding") {
+ Variant variant;
+ int r_len;
+ uint8_t buffer[] = {
+ 0x00, 0x00, 0x00, 0x00 // Variant::NIL
+ };
+
+ CHECK(decode_variant(variant, buffer, 4, &r_len) == OK);
+ CHECK(r_len == 4);
+ CHECK(variant == Variant());
+}
+
+TEST_CASE("[Marshalls] INT 32 bit Variant decoding") {
+ Variant variant;
+ int r_len;
+ uint8_t buffer[] = {
+ 0x02, 0x00, 0x00, 0x00, // Variant::INT
+ 0x78, 0x56, 0x34, 0x12 // value
+ };
+
+ CHECK(decode_variant(variant, buffer, 8, &r_len) == OK);
+ CHECK(r_len == 8);
+ CHECK(variant == Variant(0x12345678));
+}
+
+TEST_CASE("[Marshalls] INT 64 bit Variant decoding") {
+ Variant variant;
+ int r_len;
+ uint8_t buffer[] = {
+ 0x02, 0x00, 0x01, 0x00, // Variant::INT & ENCODE_FLAG_64
+ 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0xf1 // value
+ };
+
+ CHECK(decode_variant(variant, buffer, 12, &r_len) == OK);
+ CHECK(r_len == 12);
+ CHECK(variant == Variant(uint64_t(0x0f123456789abcdef)));
+}
+
+TEST_CASE("[Marshalls] FLOAT single precision Variant decoding") {
+ Variant variant;
+ int r_len;
+ uint8_t buffer[] = {
+ 0x03, 0x00, 0x00, 0x00, // Variant::FLOAT
+ 0x00, 0x00, 0x20, 0x3e // value
+ };
+
+ CHECK(decode_variant(variant, buffer, 8, &r_len) == OK);
+ CHECK(r_len == 8);
+ CHECK(variant == Variant(0.15625f));
+}
+
+TEST_CASE("[Marshalls] FLOAT double precision Variant decoding") {
+ Variant variant;
+ int r_len;
+ uint8_t buffer[] = {
+ 0x03, 0x00, 0x01, 0x00, // Variant::FLOAT & ENCODE_FLAG_64
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x3f // value
+ };
+
+ CHECK(decode_variant(variant, buffer, 12, &r_len) == OK);
+ CHECK(r_len == 12);
+ CHECK(variant == Variant(0.33333333333333333));
+}
+} // namespace TestMarshalls
+
+#endif // TEST_MARSHALLS_H
diff --git a/tests/test_math.cpp b/tests/test_math.cpp
index a7f99e5401..26c2aa2088 100644
--- a/tests/test_math.cpp
+++ b/tests/test_math.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -513,7 +513,7 @@ MainLoop *test() {
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
- if (cmdlargs.empty()) {
+ if (cmdlargs.is_empty()) {
//try editor!
return nullptr;
}
@@ -617,7 +617,7 @@ MainLoop *test() {
List<String> args;
args.push_back("-l");
- Error err = OS::get_singleton()->execute("/bin/ls", args, true, nullptr, &ret);
+ Error err = OS::get_singleton()->execute("/bin/ls", args, &ret);
print_line("error: " + itos(err));
print_line(ret);
diff --git a/tests/test_math.h b/tests/test_math.h
index 77bce8dd66..4375925bd5 100644
--- a/tests/test_math.h
+++ b/tests/test_math.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_method_bind.h b/tests/test_method_bind.h
index 62d8bd132c..879e7949e2 100644
--- a/tests/test_method_bind.h
+++ b/tests/test_method_bind.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_node_path.h b/tests/test_node_path.h
index e9e06186f5..f30fe53c5a 100644
--- a/tests/test_node_path.h
+++ b/tests/test_node_path.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_oa_hash_map.cpp b/tests/test_oa_hash_map.cpp
index b0bb01bc71..904c01642d 100644
--- a/tests/test_oa_hash_map.cpp
+++ b/tests/test_oa_hash_map.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_oa_hash_map.h b/tests/test_oa_hash_map.h
index eb2b3d1e99..9745802cc0 100644
--- a/tests/test_oa_hash_map.h
+++ b/tests/test_oa_hash_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_object.h b/tests/test_object.h
index 6fef2576e7..142d76553d 100644
--- a/tests/test_object.h
+++ b/tests/test_object.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,12 +31,103 @@
#ifndef TEST_OBJECT_H
#define TEST_OBJECT_H
+#include "core/core_string_names.h"
#include "core/object/object.h"
#include "thirdparty/doctest/doctest.h"
+// Declared in global namespace because of GDCLASS macro warning (Windows):
+// "Unqualified friend declaration referring to type outside of the nearest enclosing namespace
+// is a Microsoft extension; add a nested name specifier".
+class _TestDerivedObject : public Object {
+ GDCLASS(_TestDerivedObject, Object);
+
+ int property_value;
+
+protected:
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_property", "property"), &_TestDerivedObject::set_property);
+ ClassDB::bind_method(D_METHOD("get_property"), &_TestDerivedObject::get_property);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "property"), "set_property", "get_property");
+ }
+
+public:
+ void set_property(int value) { property_value = value; }
+ int get_property() const { return property_value; }
+};
+
namespace TestObject {
+class _MockScriptInstance : public ScriptInstance {
+ StringName property_name = "NO_NAME";
+ Variant property_value;
+
+public:
+ bool set(const StringName &p_name, const Variant &p_value) override {
+ property_name = p_name;
+ property_value = p_value;
+ return true;
+ }
+ bool get(const StringName &p_name, Variant &r_ret) const override {
+ if (property_name == p_name) {
+ r_ret = property_value;
+ return true;
+ }
+ return false;
+ }
+ void get_property_list(List<PropertyInfo> *p_properties) const override {
+ }
+ Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const override {
+ return Variant::PACKED_FLOAT32_ARRAY;
+ }
+ void get_method_list(List<MethodInfo> *p_list) const override {
+ }
+ bool has_method(const StringName &p_method) const override {
+ return false;
+ }
+ Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
+ return Variant();
+ }
+ void notification(int p_notification) override {
+ }
+ Ref<Script> get_script() const override {
+ return Ref<Script>();
+ }
+ Vector<ScriptNetData> get_rpc_methods() const override {
+ return Vector<ScriptNetData>();
+ }
+ uint16_t get_rpc_method_id(const StringName &p_method) const override {
+ return 0;
+ }
+ StringName get_rpc_method(uint16_t p_id) const override {
+ return StringName();
+ }
+ MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const override {
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ }
+ MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override {
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ }
+ Vector<ScriptNetData> get_rset_properties() const override {
+ return Vector<ScriptNetData>();
+ }
+ uint16_t get_rset_property_id(const StringName &p_variable) const override {
+ return 0;
+ }
+ StringName get_rset_property(uint16_t p_id) const override {
+ return StringName();
+ }
+ MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const override {
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ }
+ MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override {
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ }
+ ScriptLanguage *get_language() override {
+ return nullptr;
+ }
+};
+
TEST_CASE("[Object] Core getters") {
Object object;
@@ -55,6 +146,15 @@ TEST_CASE("[Object] Core getters") {
CHECK_MESSAGE(
object.get_save_class() == "Object",
"The returned save class should match the expected value.");
+
+ List<String> inheritance_list;
+ object.get_inheritance_list_static(&inheritance_list);
+ CHECK_MESSAGE(
+ inheritance_list.size() == 1,
+ "The inheritance list should consist of Object only");
+ CHECK_MESSAGE(
+ inheritance_list[0] == "Object",
+ "The inheritance list should consist of Object only");
}
TEST_CASE("[Object] Metadata") {
@@ -87,6 +187,119 @@ TEST_CASE("[Object] Metadata") {
meta_list2.size() == 0,
"The metadata list should contain 0 items after removing all metadata items.");
}
+
+TEST_CASE("[Object] Construction") {
+ Object object;
+
+ CHECK_MESSAGE(
+ !object.is_reference(),
+ "Object is not a Reference.");
+
+ Object *p_db = ObjectDB::get_instance(object.get_instance_id());
+ CHECK_MESSAGE(
+ p_db == &object,
+ "The database pointer returned by the object id should reference same object.");
+}
+
+TEST_CASE("[Object] Script instance property setter") {
+ Object object;
+ _MockScriptInstance *script_instance = memnew(_MockScriptInstance);
+ object.set_script_instance(script_instance);
+
+ bool valid = false;
+ object.set("some_name", 100, &valid);
+ CHECK(valid);
+ Variant actual_value;
+ CHECK_MESSAGE(
+ script_instance->get("some_name", actual_value),
+ "The assigned script instance should successfully retrieve value by name.");
+ CHECK_MESSAGE(
+ actual_value == Variant(100),
+ "The returned value should equal the one which was set by the object.");
+}
+
+TEST_CASE("[Object] Script instance property getter") {
+ Object object;
+ _MockScriptInstance *script_instance = memnew(_MockScriptInstance);
+ script_instance->set("some_name", 100); // Make sure script instance has the property
+ object.set_script_instance(script_instance);
+
+ bool valid = false;
+ const Variant &actual_value = object.get("some_name", &valid);
+ CHECK(valid);
+ CHECK_MESSAGE(
+ actual_value == Variant(100),
+ "The returned value should equal the one which was set by the script instance.");
+}
+
+TEST_CASE("[Object] Built-in property setter") {
+ ClassDB::register_class<_TestDerivedObject>();
+ _TestDerivedObject derived_object;
+
+ bool valid = false;
+ derived_object.set("property", 100, &valid);
+ CHECK(valid);
+ CHECK_MESSAGE(
+ derived_object.get_property() == 100,
+ "The property value should equal the one which was set with built-in setter.");
+}
+
+TEST_CASE("[Object] Built-in property getter") {
+ ClassDB::register_class<_TestDerivedObject>();
+ _TestDerivedObject derived_object;
+ derived_object.set_property(100);
+
+ bool valid = false;
+ const Variant &actual_value = derived_object.get("property", &valid);
+ CHECK(valid);
+ CHECK_MESSAGE(
+ actual_value == Variant(100),
+ "The returned value should equal the one which was set with built-in setter.");
+}
+
+TEST_CASE("[Object] Script property setter") {
+ Object object;
+ Variant script;
+
+ bool valid = false;
+ object.set(CoreStringNames::get_singleton()->_script, script, &valid);
+ CHECK(valid);
+ CHECK_MESSAGE(
+ object.get_script() == script,
+ "The object script should be equal to the assigned one.");
+}
+
+TEST_CASE("[Object] Script property getter") {
+ Object object;
+ Variant script;
+ object.set_script(script);
+
+ bool valid = false;
+ const Variant &actual_value = object.get(CoreStringNames::get_singleton()->_script, &valid);
+ CHECK(valid);
+ CHECK_MESSAGE(
+ actual_value == script,
+ "The returned value should be equal to the assigned script.");
+}
+
+TEST_CASE("[Object] Absent name setter") {
+ Object object;
+
+ bool valid = true;
+ object.set("absent_name", 100, &valid);
+ CHECK(!valid);
+}
+
+TEST_CASE("[Object] Absent name getter") {
+ Object object;
+
+ bool valid = true;
+ const Variant &actual_value = object.get("absent_name", &valid);
+ CHECK(!valid);
+ CHECK_MESSAGE(
+ actual_value == Variant(),
+ "The returned value should equal nil variant.");
+}
} // namespace TestObject
#endif // TEST_OBJECT_H
diff --git a/tests/test_ordered_hash_map.h b/tests/test_ordered_hash_map.h
index ef26d2531b..fbaaa224cf 100644
--- a/tests/test_ordered_hash_map.h
+++ b/tests/test_ordered_hash_map.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_paged_array.h b/tests/test_paged_array.h
index 6b61160229..7efd3799f3 100644
--- a/tests/test_paged_array.h
+++ b/tests/test_paged_array.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_path_follow_2d.h b/tests/test_path_follow_2d.h
new file mode 100644
index 0000000000..388b690060
--- /dev/null
+++ b/tests/test_path_follow_2d.h
@@ -0,0 +1,241 @@
+/*************************************************************************/
+/* test_path_follow_2d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_PATH_FOLLOW_2D_H
+#define TEST_PATH_FOLLOW_2D_H
+
+#include "scene/2d/path_2d.h"
+#include "scene/resources/curve.h"
+
+#include "tests/test_macros.h"
+
+namespace TestPathFollow2D {
+
+TEST_CASE("[PathFollow2D] Sampling with unit offset") {
+ const Ref<Curve2D> &curve = memnew(Curve2D());
+ curve->add_point(Vector2(0, 0));
+ curve->add_point(Vector2(100, 0));
+ curve->add_point(Vector2(100, 100));
+ curve->add_point(Vector2(0, 100));
+ curve->add_point(Vector2(0, 0));
+ const Path2D *path = memnew(Path2D);
+ path->set_curve(curve);
+ const PathFollow2D *path_follow_2d = memnew(PathFollow2D);
+ path->add_child(path_follow_2d);
+
+ path_follow_2d->set_unit_offset(0);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 0)));
+
+ path_follow_2d->set_unit_offset(0.125);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 0)));
+
+ path_follow_2d->set_unit_offset(0.25);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 0)));
+
+ path_follow_2d->set_unit_offset(0.375);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 50)));
+
+ path_follow_2d->set_unit_offset(0.5);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 100)));
+
+ path_follow_2d->set_unit_offset(0.625);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 100)));
+
+ path_follow_2d->set_unit_offset(0.75);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 100)));
+
+ path_follow_2d->set_unit_offset(0.875);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 50)));
+
+ path_follow_2d->set_unit_offset(1);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 0)));
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow2D] Sampling with offset") {
+ const Ref<Curve2D> &curve = memnew(Curve2D());
+ curve->add_point(Vector2(0, 0));
+ curve->add_point(Vector2(100, 0));
+ curve->add_point(Vector2(100, 100));
+ curve->add_point(Vector2(0, 100));
+ curve->add_point(Vector2(0, 0));
+ const Path2D *path = memnew(Path2D);
+ path->set_curve(curve);
+ const PathFollow2D *path_follow_2d = memnew(PathFollow2D);
+ path->add_child(path_follow_2d);
+
+ path_follow_2d->set_offset(0);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 0)));
+
+ path_follow_2d->set_offset(50);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 0)));
+
+ path_follow_2d->set_offset(100);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 0)));
+
+ path_follow_2d->set_offset(150);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 50)));
+
+ path_follow_2d->set_offset(200);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 100)));
+
+ path_follow_2d->set_offset(250);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 100)));
+
+ path_follow_2d->set_offset(300);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 100)));
+
+ path_follow_2d->set_offset(350);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 50)));
+
+ path_follow_2d->set_offset(400);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(0, 0)));
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow2D] Removal of a point in curve") {
+ const Ref<Curve2D> &curve = memnew(Curve2D());
+ curve->add_point(Vector2(0, 0));
+ curve->add_point(Vector2(100, 0));
+ curve->add_point(Vector2(100, 100));
+ const Path2D *path = memnew(Path2D);
+ path->set_curve(curve);
+ const PathFollow2D *path_follow_2d = memnew(PathFollow2D);
+ path->add_child(path_follow_2d);
+
+ path_follow_2d->set_unit_offset(0.5);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(100, 0)));
+
+ curve->remove_point(1);
+
+ CHECK_MESSAGE(
+ path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 50)),
+ "Path follow's position should be updated after removing a point from the curve");
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow2D] Setting h_offset and v_offset") {
+ const Ref<Curve2D> &curve = memnew(Curve2D());
+ curve->add_point(Vector2(0, 0));
+ curve->add_point(Vector2(100, 0));
+ const Path2D *path = memnew(Path2D);
+ path->set_curve(curve);
+ const PathFollow2D *path_follow_2d = memnew(PathFollow2D);
+ path->add_child(path_follow_2d);
+
+ path_follow_2d->set_unit_offset(0.5);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(50, 0)));
+
+ path_follow_2d->set_h_offset(25);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(75, 0)));
+
+ path_follow_2d->set_v_offset(25);
+ CHECK(path_follow_2d->get_transform().get_origin().is_equal_approx(Vector2(75, 25)));
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow2D] Unit offset out of range") {
+ const Ref<Curve2D> &curve = memnew(Curve2D());
+ curve->add_point(Vector2(0, 0));
+ curve->add_point(Vector2(100, 0));
+ const Path2D *path = memnew(Path2D);
+ path->set_curve(curve);
+ const PathFollow2D *path_follow_2d = memnew(PathFollow2D);
+ path->add_child(path_follow_2d);
+
+ path_follow_2d->set_loop(true);
+
+ path_follow_2d->set_unit_offset(-0.3);
+ CHECK_MESSAGE(
+ path_follow_2d->get_unit_offset() == 0.7,
+ "Unit Offset should loop back from the end in the opposite direction");
+
+ path_follow_2d->set_unit_offset(1.3);
+ CHECK_MESSAGE(
+ path_follow_2d->get_unit_offset() == 0.3,
+ "Unit Offset should loop back from the end in the opposite direction");
+
+ path_follow_2d->set_loop(false);
+
+ path_follow_2d->set_unit_offset(-0.3);
+ CHECK_MESSAGE(
+ path_follow_2d->get_unit_offset() == 0,
+ "Unit Offset should be clamped at 0");
+
+ path_follow_2d->set_unit_offset(1.3);
+ CHECK_MESSAGE(
+ path_follow_2d->get_unit_offset() == 1,
+ "Unit Offset should be clamped at 1");
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow2D] Offset out of range") {
+ const Ref<Curve2D> &curve = memnew(Curve2D());
+ curve->add_point(Vector2(0, 0));
+ curve->add_point(Vector2(100, 0));
+ const Path2D *path = memnew(Path2D);
+ path->set_curve(curve);
+ const PathFollow2D *path_follow_2d = memnew(PathFollow2D);
+ path->add_child(path_follow_2d);
+
+ path_follow_2d->set_loop(true);
+
+ path_follow_2d->set_offset(-50);
+ CHECK_MESSAGE(
+ path_follow_2d->get_offset() == 50,
+ "Offset should loop back from the end in the opposite direction");
+
+ path_follow_2d->set_offset(150);
+ CHECK_MESSAGE(
+ path_follow_2d->get_offset() == 50,
+ "Offset should loop back from the end in the opposite direction");
+
+ path_follow_2d->set_loop(false);
+
+ path_follow_2d->set_offset(-50);
+ CHECK_MESSAGE(
+ path_follow_2d->get_offset() == 0,
+ "Offset should be clamped at 0");
+
+ path_follow_2d->set_offset(150);
+ CHECK_MESSAGE(
+ path_follow_2d->get_offset() == 100,
+ "Offset should be clamped at 1");
+
+ memdelete(path);
+}
+} // namespace TestPathFollow2D
+
+#endif // TEST_PATH_FOLLOW_2D_H
diff --git a/tests/test_path_follow_3d.h b/tests/test_path_follow_3d.h
new file mode 100644
index 0000000000..b6b4c88222
--- /dev/null
+++ b/tests/test_path_follow_3d.h
@@ -0,0 +1,220 @@
+/*************************************************************************/
+/* test_path_follow_3d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_PATH_FOLLOW_3D_H
+#define TEST_PATH_FOLLOW_3D_H
+
+#include "scene/3d/path_3d.h"
+#include "scene/resources/curve.h"
+
+#include "tests/test_macros.h"
+
+namespace TestPathFollow3D {
+
+TEST_CASE("[PathFollow3D] Sampling with unit offset") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ curve->add_point(Vector3(100, 100, 0));
+ curve->add_point(Vector3(100, 100, 100));
+ curve->add_point(Vector3(100, 0, 100));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_unit_offset(0);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(0, 0, 0));
+
+ path_follow_3d->set_unit_offset(0.125);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(50, 0, 0));
+
+ path_follow_3d->set_unit_offset(0.25);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 0);
+
+ path_follow_3d->set_unit_offset(0.375);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 0)));
+
+ path_follow_3d->set_unit_offset(0.5);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 0)));
+
+ path_follow_3d->set_unit_offset(0.625);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 50)));
+
+ path_follow_3d->set_unit_offset(0.75);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 100)));
+
+ path_follow_3d->set_unit_offset(0.875);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 100)));
+
+ path_follow_3d->set_unit_offset(1);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 100)));
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow3D] Sampling with offset") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ curve->add_point(Vector3(100, 100, 0));
+ curve->add_point(Vector3(100, 100, 100));
+ curve->add_point(Vector3(100, 0, 100));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_offset(0);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(0, 0, 0));
+
+ path_follow_3d->set_offset(50);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(50, 0, 0));
+
+ path_follow_3d->set_offset(100);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 0);
+
+ path_follow_3d->set_offset(150);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 0)));
+
+ path_follow_3d->set_offset(200);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 0)));
+
+ path_follow_3d->set_offset(250);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 50)));
+
+ path_follow_3d->set_offset(300);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 100, 100)));
+
+ path_follow_3d->set_offset(350);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 50, 100)));
+
+ path_follow_3d->set_offset(400);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector3(100, 0, 100)));
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow3D] Removal of a point in curve") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ curve->add_point(Vector3(100, 100, 0));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_unit_offset(0.5);
+ CHECK(path_follow_3d->get_transform().get_origin().is_equal_approx(Vector2(100, 0, 0)));
+
+ curve->remove_point(1);
+
+ CHECK_MESSAGE(
+ path_follow_3d->get_transform().get_origin().is_equal_approx(Vector2(50, 50, 0)),
+ "Path follow's position should be updated after removing a point from the curve");
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow3D] Unit offset out of range") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_loop(true);
+
+ path_follow_3d->set_unit_offset(-0.3);
+ CHECK_MESSAGE(
+ path_follow_3d->get_unit_offset() == 0.7,
+ "Unit Offset should loop back from the end in the opposite direction");
+
+ path_follow_3d->set_unit_offset(1.3);
+ CHECK_MESSAGE(
+ path_follow_3d->get_unit_offset() == 0.3,
+ "Unit Offset should loop back from the end in the opposite direction");
+
+ path_follow_3d->set_loop(false);
+
+ path_follow_3d->set_unit_offset(-0.3);
+ CHECK_MESSAGE(
+ path_follow_3d->get_unit_offset() == 0,
+ "Unit Offset should be clamped at 0");
+
+ path_follow_3d->set_unit_offset(1.3);
+ CHECK_MESSAGE(
+ path_follow_3d->get_unit_offset() == 1,
+ "Unit Offset should be clamped at 1");
+
+ memdelete(path);
+}
+
+TEST_CASE("[PathFollow3D] Offset out of range") {
+ const Ref<Curve3D> &curve = memnew(Curve3D());
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3(100, 0, 0));
+ const Path3D *path = memnew(Path3D);
+ path->set_curve(curve);
+ const PathFollow3D *path_follow_3d = memnew(PathFollow3D);
+ path->add_child(path_follow_3d);
+
+ path_follow_3d->set_loop(true);
+
+ path_follow_3d->set_offset(-50);
+ CHECK_MESSAGE(
+ path_follow_3d->get_offset() == 50,
+ "Offset should loop back from the end in the opposite direction");
+
+ path_follow_3d->set_offset(150);
+ CHECK_MESSAGE(
+ path_follow_3d->get_offset() == 50,
+ "Offset should loop back from the end in the opposite direction");
+
+ path_follow_3d->set_loop(false);
+
+ path_follow_3d->set_offset(-50);
+ CHECK_MESSAGE(
+ path_follow_3d->get_offset() == 0,
+ "Offset should be clamped at 0");
+
+ path_follow_3d->set_offset(150);
+ CHECK_MESSAGE(
+ path_follow_3d->get_offset() == 100,
+ "Offset should be clamped at max value of curve");
+
+ memdelete(path);
+}
+} // namespace TestPathFollow3D
+
+#endif // TEST_PATH_FOLLOW_3D_H
diff --git a/tests/test_pck_packer.h b/tests/test_pck_packer.h
index e086d65105..8e4721b821 100644
--- a/tests/test_pck_packer.h
+++ b/tests/test_pck_packer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_physics_2d.cpp b/tests/test_physics_2d.cpp
index d40df52f1b..570e1897d6 100644
--- a/tests/test_physics_2d.cpp
+++ b/tests/test_physics_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -315,7 +315,7 @@ protected:
}
public:
- virtual void init() override {
+ virtual void initialize() override {
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
@@ -389,10 +389,10 @@ public:
//_add_plane(Vector2(-1,0).normalized(),-600);
}
- virtual bool idle(float p_time) override {
+ virtual bool process(float p_time) override {
return false;
}
- virtual void finish() override {
+ virtual void finalize() override {
}
TestPhysics2DMainLoop() {}
diff --git a/tests/test_physics_2d.h b/tests/test_physics_2d.h
index 517d324f3b..966d49200a 100644
--- a/tests/test_physics_2d.h
+++ b/tests/test_physics_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_physics_3d.cpp b/tests/test_physics_3d.cpp
index 5f84b2eb50..74afbad9d1 100644
--- a/tests/test_physics_3d.cpp
+++ b/tests/test_physics_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,7 +59,7 @@ class TestPhysics3DMainLoop : public MainLoop {
RID character;
- float ofs_x, ofs_y;
+ real_t ofs_x, ofs_y;
Point2 joy_direction;
@@ -86,7 +86,9 @@ protected:
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape], scenario);
- RID body = ps->body_create(p_body, !p_active_default);
+ RID body = ps->body_create();
+ ps->body_set_mode(body, p_body);
+ ps->body_set_state(body, PhysicsServer3D::BODY_STATE_SLEEPING, !p_active_default);
ps->body_set_space(body, space);
ps->body_set_param(body, PhysicsServer3D::BODY_PARAM_BOUNCE, 0.0);
//todo set space
@@ -108,21 +110,23 @@ protected:
RID world_margin_shape = ps->shape_create(PhysicsServer3D::SHAPE_PLANE);
ps->shape_set_data(world_margin_shape, p_plane);
- RID b = ps->body_create(PhysicsServer3D::BODY_MODE_STATIC);
+ RID b = ps->body_create();
+ ps->body_set_mode(b, PhysicsServer3D::BODY_MODE_STATIC);
+
ps->body_set_space(b, space);
//todo set space
ps->body_add_shape(b, world_margin_shape);
return b;
}
- void configure_body(RID p_body, float p_mass, float p_friction, float p_bounce) {
+ void configure_body(RID p_body, real_t p_mass, real_t p_friction, real_t p_bounce) {
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
ps->body_set_param(p_body, PhysicsServer3D::BODY_PARAM_MASS, p_mass);
ps->body_set_param(p_body, PhysicsServer3D::BODY_PARAM_FRICTION, p_friction);
ps->body_set_param(p_body, PhysicsServer3D::BODY_PARAM_BOUNCE, p_bounce);
}
- void init_shapes() {
+ void initialize_shapes() {
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
@@ -202,7 +206,8 @@ protected:
RID triins = vs->instance_create2(trimesh_mesh, scenario);
- RID tribody = ps->body_create(PhysicsServer3D::BODY_MODE_STATIC);
+ RID tribody = ps->body_create();
+ ps->body_set_mode(tribody, PhysicsServer3D::BODY_MODE_STATIC);
ps->body_set_space(tribody, space);
//todo set space
ps->body_add_shape(tribody, trimesh_shape);
@@ -211,8 +216,8 @@ protected:
vs->instance_set_transform(triins, tritrans);
}
- void make_grid(int p_width, int p_height, float p_cellsize, float p_cellheight, const Transform &p_xform = Transform()) {
- Vector<Vector<float>> grid;
+ void make_grid(int p_width, int p_height, real_t p_cellsize, real_t p_cellheight, const Transform &p_xform = Transform()) {
+ Vector<Vector<real_t>> grid;
grid.resize(p_width);
@@ -253,8 +258,8 @@ public:
}
if (mm.is_valid() && mm->get_button_mask() & 1) {
- float y = -mm->get_relative().y / 20.0;
- float x = mm->get_relative().x / 20.0;
+ real_t y = -mm->get_relative().y / 20.0;
+ real_t x = mm->get_relative().x / 20.0;
if (mover.is_valid()) {
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
@@ -269,9 +274,9 @@ public:
virtual void request_quit() {
quit = true;
}
- virtual void init() override {
+ virtual void initialize() override {
ofs_x = ofs_y = 0;
- init_shapes();
+ initialize_shapes();
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
space = ps->space_create();
@@ -310,9 +315,9 @@ public:
test_fall();
quit = false;
}
- virtual bool iteration(float p_time) override {
+ virtual bool physics_process(float p_time) override {
if (mover.is_valid()) {
- static float joy_speed = 10;
+ static real_t joy_speed = 10;
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
Transform t = ps->body_get_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM);
t.origin += Vector3(joy_speed * joy_direction.x * p_time, -joy_speed * joy_direction.y * p_time, 0);
@@ -328,7 +333,7 @@ public:
return quit;
}
- virtual void finish() override {
+ virtual void finalize() override {
}
void test_joint() {
@@ -358,7 +363,8 @@ public:
ps->shape_set_data(capsule_shape, capsule_params);
RID mesh_instance = vs->instance_create2(capsule_mesh, scenario);
- character = ps->body_create(PhysicsServer3D::BODY_MODE_CHARACTER);
+ character = ps->body_create();
+ ps->body_set_mode(character, PhysicsServer3D::BODY_MODE_CHARACTER);
ps->body_set_space(character, space);
//todo add space
ps->body_add_shape(character, capsule_shape);
@@ -396,7 +402,7 @@ public:
create_static_plane(Plane(Vector3(0, 1, 0), -1));
}
- virtual bool idle(float p_time) override {
+ virtual bool process(float p_time) override {
return false;
}
diff --git a/tests/test_physics_3d.h b/tests/test_physics_3d.h
index d03f2c6573..b6b66f350e 100644
--- a/tests/test_physics_3d.h
+++ b/tests/test_physics_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_random_number_generator.h b/tests/test_random_number_generator.h
index 999e6d4862..39c4771c19 100644
--- a/tests/test_random_number_generator.h
+++ b/tests/test_random_number_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -73,8 +73,8 @@ TEST_CASE_MAY_FAIL("[RandomNumberGenerator] Integer 32 bit") {
break;
}
}
- INFO("Current seed: " << rng->get_seed());
- INFO("Current iteration: " << i);
+ INFO("Current seed: ", rng->get_seed());
+ INFO("Current iteration: ", i);
CHECK_MESSAGE(higher, "Given current seed, this should give an integer higher than 0x0fff'ffff at least once.");
}
@@ -185,13 +185,13 @@ TEST_CASE("[RandomNumberGenerator] Zero for first number immediately after seedi
rng->set_seed(0);
uint32_t n1 = rng->randi();
uint32_t n2 = rng->randi();
- INFO("Initial random values: " << n1 << " " << n2);
+ INFO("Initial random values: ", n1, " ", n2);
CHECK(n1 != 0);
rng->set_seed(1);
uint32_t n3 = rng->randi();
uint32_t n4 = rng->randi();
- INFO("Values after changing the seed: " << n3 << " " << n4);
+ INFO("Values after changing the seed: ", n3, " ", n4);
CHECK(n3 != 0);
}
@@ -199,7 +199,7 @@ TEST_CASE("[RandomNumberGenerator] Restore state") {
Ref<RandomNumberGenerator> rng = memnew(RandomNumberGenerator);
rng->randomize();
uint64_t last_seed = rng->get_seed();
- INFO("Current seed: " << last_seed);
+ INFO("Current seed: ", last_seed);
rng->randi();
rng->randi();
@@ -208,18 +208,18 @@ TEST_CASE("[RandomNumberGenerator] Restore state") {
"The seed should remain the same after generating some numbers");
uint64_t saved_state = rng->get_state();
- INFO("Current state: " << saved_state);
+ INFO("Current state: ", saved_state);
real_t f1_before = rng->randf();
real_t f2_before = rng->randf();
- INFO("This seed produces: " << f1_before << " " << f2_before);
+ INFO("This seed produces: ", f1_before, " ", f2_before);
// Restore now.
rng->set_state(saved_state);
real_t f1_after = rng->randf();
real_t f2_after = rng->randf();
- INFO("Resetting the state produces: " << f1_after << " " << f2_after);
+ INFO("Resetting the state produces: ", f1_after, " ", f2_after);
String msg = "Should restore the sequence of numbers after resetting the state";
CHECK_MESSAGE(f1_before == f1_after, msg);
@@ -229,22 +229,22 @@ TEST_CASE("[RandomNumberGenerator] Restore state") {
TEST_CASE("[RandomNumberGenerator] Restore from seed") {
Ref<RandomNumberGenerator> rng = memnew(RandomNumberGenerator);
rng->set_seed(0);
- INFO("Current seed: " << rng->get_seed());
+ INFO("Current seed: ", rng->get_seed());
uint32_t s0_1_before = rng->randi();
uint32_t s0_2_before = rng->randi();
- INFO("This seed produces: " << s0_1_before << " " << s0_2_before);
+ INFO("This seed produces: ", s0_1_before, " ", s0_2_before);
rng->set_seed(9000);
- INFO("Current seed: " << rng->get_seed());
+ INFO("Current seed: ", rng->get_seed());
uint32_t s9000_1 = rng->randi();
uint32_t s9000_2 = rng->randi();
- INFO("This seed produces: " << s9000_1 << " " << s9000_2);
+ INFO("This seed produces: ", s9000_1, " ", s9000_2);
rng->set_seed(0);
- INFO("Current seed: " << rng->get_seed());
+ INFO("Current seed: ", rng->get_seed());
uint32_t s0_1_after = rng->randi();
uint32_t s0_2_after = rng->randi();
- INFO("This seed produces: " << s0_1_after << " " << s0_2_after);
+ INFO("This seed produces: ", s0_1_after, " ", s0_2_after);
String msg = "Should restore the sequence of numbers after resetting the seed";
CHECK_MESSAGE(s0_1_before == s0_1_after, msg);
diff --git a/tests/test_rect2.h b/tests/test_rect2.h
index b6edc9ce81..b94a8b7d05 100644
--- a/tests/test_rect2.h
+++ b/tests/test_rect2.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -197,11 +197,11 @@ TEST_CASE("[Rect2] Growing") {
"grow_individual() with positive and negative values should return the expected Rect2.");
CHECK_MESSAGE(
- Rect2(0, 100, 1280, 720).grow_margin(SIDE_TOP, 500).is_equal_approx(Rect2(0, -400, 1280, 1220)),
- "grow_margin() with positive value should return the expected Rect2.");
+ Rect2(0, 100, 1280, 720).grow_side(SIDE_TOP, 500).is_equal_approx(Rect2(0, -400, 1280, 1220)),
+ "grow_side() with positive value should return the expected Rect2.");
CHECK_MESSAGE(
- Rect2(0, 100, 1280, 720).grow_margin(SIDE_TOP, -500).is_equal_approx(Rect2(0, 600, 1280, 220)),
- "grow_margin() with negative value should return the expected Rect2.");
+ Rect2(0, 100, 1280, 720).grow_side(SIDE_TOP, -500).is_equal_approx(Rect2(0, 600, 1280, 220)),
+ "grow_side() with negative value should return the expected Rect2.");
}
TEST_CASE("[Rect2] Has point") {
@@ -409,11 +409,11 @@ TEST_CASE("[Rect2i] Growing") {
"grow_individual() with positive and negative values should return the expected Rect2i.");
CHECK_MESSAGE(
- Rect2i(0, 100, 1280, 720).grow_margin(SIDE_TOP, 500) == Rect2i(0, -400, 1280, 1220),
- "grow_margin() with positive value should return the expected Rect2i.");
+ Rect2i(0, 100, 1280, 720).grow_side(SIDE_TOP, 500) == Rect2i(0, -400, 1280, 1220),
+ "grow_side() with positive value should return the expected Rect2i.");
CHECK_MESSAGE(
- Rect2i(0, 100, 1280, 720).grow_margin(SIDE_TOP, -500) == Rect2i(0, 600, 1280, 220),
- "grow_margin() with negative value should return the expected Rect2i.");
+ Rect2i(0, 100, 1280, 720).grow_side(SIDE_TOP, -500) == Rect2i(0, 600, 1280, 220),
+ "grow_side() with negative value should return the expected Rect2i.");
}
TEST_CASE("[Rect2i] Has point") {
diff --git a/tests/test_render.cpp b/tests/test_render.cpp
index d14251bc6a..72b2840098 100644
--- a/tests/test_render.cpp
+++ b/tests/test_render.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -183,8 +183,8 @@ public:
//vs->light_set_shadow( lightaux, true );
light = vs->instance_create2(lightaux, scenario);
Transform lla;
- //lla.set_look_at(Vector3(),Vector3(1,-1,1),Vector3(0,1,0));
- lla.set_look_at(Vector3(), Vector3(-0.000000, -0.836026, -0.548690), Vector3(0, 1, 0));
+ //lla.set_look_at(Vector3(),Vector3(1, -1, 1));
+ lla.set_look_at(Vector3(), Vector3(0.0, -0.836026, -0.548690));
vs->instance_set_transform(light, lla);
diff --git a/tests/test_render.h b/tests/test_render.h
index 4a6340c443..35bb383773 100644
--- a/tests/test_render.h
+++ b/tests/test_render.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_resource.h b/tests/test_resource.h
new file mode 100644
index 0000000000..cee3281995
--- /dev/null
+++ b/tests/test_resource.h
@@ -0,0 +1,114 @@
+/*************************************************************************/
+/* test_resource.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_RESOURCE
+#define TEST_RESOURCE
+
+#include "core/io/resource.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/os/os.h"
+
+#include "thirdparty/doctest/doctest.h"
+
+namespace TestResource {
+
+TEST_CASE("[Resource] Duplication") {
+ Ref<Resource> resource = memnew(Resource);
+ resource->set_name("Hello world");
+ Ref<Resource> child_resource = memnew(Resource);
+ child_resource->set_name("I'm a child resource");
+ resource->set_meta("other_resource", child_resource);
+
+ Ref<Resource> resource_dupe = resource->duplicate();
+ const Ref<Resource> &resource_dupe_reference = resource_dupe;
+ resource_dupe->set_name("Changed name");
+ child_resource->set_name("My name was changed too");
+
+ CHECK_MESSAGE(
+ resource_dupe->get_name() == "Changed name",
+ "Duplicated resource should have the new name.");
+ CHECK_MESSAGE(
+ resource_dupe_reference->get_name() == "Changed name",
+ "Reference to the duplicated resource should have the new name.");
+ CHECK_MESSAGE(
+ resource->get_name() == "Hello world",
+ "Original resource name should not be affected after editing the duplicate's name.");
+ CHECK_MESSAGE(
+ Ref<Resource>(resource_dupe->get_meta("other_resource"))->get_name() == "My name was changed too",
+ "Duplicated resource should share its child resource with the original.");
+}
+
+TEST_CASE("[Resource] Saving and loading") {
+ Ref<Resource> resource = memnew(Resource);
+ resource->set_name("Hello world");
+ resource->set_meta(" ExampleMetadata ", Vector2i(40, 80));
+ resource->set_meta("string", "The\nstring\nwith\nunnecessary\nline\n\t\\\nbreaks");
+ Ref<Resource> child_resource = memnew(Resource);
+ child_resource->set_name("I'm a child resource");
+ resource->set_meta("other_resource", child_resource);
+ const String save_path_binary = OS::get_singleton()->get_cache_path().plus_file("resource.res");
+ const String save_path_text = OS::get_singleton()->get_cache_path().plus_file("resource.tres");
+ ResourceSaver::save(save_path_binary, resource);
+ ResourceSaver::save(save_path_text, resource);
+
+ const Ref<Resource> &loaded_resource_binary = ResourceLoader::load(save_path_binary);
+ CHECK_MESSAGE(
+ loaded_resource_binary->get_name() == "Hello world",
+ "The loaded resource name should be equal to the expected value.");
+ CHECK_MESSAGE(
+ loaded_resource_binary->get_meta(" ExampleMetadata ") == Vector2i(40, 80),
+ "The loaded resource metadata should be equal to the expected value.");
+ CHECK_MESSAGE(
+ loaded_resource_binary->get_meta("string") == "The\nstring\nwith\nunnecessary\nline\n\t\\\nbreaks",
+ "The loaded resource metadata should be equal to the expected value.");
+ const Ref<Resource> &loaded_child_resource_binary = loaded_resource_binary->get_meta("other_resource");
+ CHECK_MESSAGE(
+ loaded_child_resource_binary->get_name() == "I'm a child resource",
+ "The loaded child resource name should be equal to the expected value.");
+
+ const Ref<Resource> &loaded_resource_text = ResourceLoader::load(save_path_text);
+ CHECK_MESSAGE(
+ loaded_resource_text->get_name() == "Hello world",
+ "The loaded resource name should be equal to the expected value.");
+ CHECK_MESSAGE(
+ loaded_resource_text->get_meta(" ExampleMetadata ") == Vector2i(40, 80),
+ "The loaded resource metadata should be equal to the expected value.");
+ CHECK_MESSAGE(
+ loaded_resource_text->get_meta("string") == "The\nstring\nwith\nunnecessary\nline\n\t\\\nbreaks",
+ "The loaded resource metadata should be equal to the expected value.");
+ const Ref<Resource> &loaded_child_resource_text = loaded_resource_text->get_meta("other_resource");
+ CHECK_MESSAGE(
+ loaded_child_resource_text->get_name() == "I'm a child resource",
+ "The loaded child resource name should be equal to the expected value.");
+}
+} // namespace TestResource
+
+#endif // TEST_RESOURCE
diff --git a/tests/test_shader_lang.cpp b/tests/test_shader_lang.cpp
index e79c83b001..a023f35506 100644
--- a/tests/test_shader_lang.cpp
+++ b/tests/test_shader_lang.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -308,7 +308,7 @@ static Error recreate_code(void *p_str, SL::ShaderNode *p_program) {
MainLoop *test() {
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
- if (cmdlargs.empty()) {
+ if (cmdlargs.is_empty()) {
//try editor!
print_line("usage: godot -test shader_lang <shader>");
return nullptr;
diff --git a/tests/test_shader_lang.h b/tests/test_shader_lang.h
index 2811c5f46e..46a2e6af35 100644
--- a/tests/test_shader_lang.h
+++ b/tests/test_shader_lang.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/tests/test_string.h b/tests/test_string.h
index 3c5d4a2f01..6febf22765 100644
--- a/tests/test_string.h
+++ b/tests/test_string.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -244,11 +244,11 @@ TEST_CASE("[String] Testing size and length of string") {
}
TEST_CASE("[String] Testing for empty string") {
- CHECK(!String("Mellon").empty());
+ CHECK(!String("Mellon").is_empty());
// do this more than once, to check for string corruption
- CHECK(String("").empty());
- CHECK(String("").empty());
- CHECK(String("").empty());
+ CHECK(String("").is_empty());
+ CHECK(String("").is_empty());
+ CHECK(String("").is_empty());
}
TEST_CASE("[String] Test chr") {
@@ -266,7 +266,7 @@ TEST_CASE("[String] Operator []") {
a[6] = 'C';
CHECK(a == "Sugar Cane");
CHECK(a[1] == 'u');
- CHECK(a.ord_at(1) == 'u');
+ CHECK(a.unicode_at(1) == 'u');
}
TEST_CASE("[String] Case function test") {
@@ -370,12 +370,9 @@ TEST_CASE("[String] String to integer") {
TEST_CASE("[String] Hex to integer") {
static const char *nums[4] = { "0xFFAE", "22", "0", "AADDAD" };
static const int64_t num[4] = { 0xFFAE, 0x22, 0, 0xAADDAD };
- static const bool wo_prefix[4] = { false, true, true, true };
- static const bool w_prefix[4] = { true, false, true, false };
for (int i = 0; i < 4; i++) {
- CHECK((String(nums[i]).hex_to_int(true) == num[i]) == w_prefix[i]);
- CHECK((String(nums[i]).hex_to_int(false) == num[i]) == wo_prefix[i]);
+ CHECK(String(nums[i]).hex_to_int() == num[i]);
}
}
@@ -1155,20 +1152,12 @@ TEST_CASE("[String] hash") {
CHECK(a.hash64() != c.hash64());
}
-TEST_CASE("[String] http_escape/unescape") {
+TEST_CASE("[String] uri_encode/unescape") {
String s = "Godot Engine:'docs'";
String t = "Godot%20Engine%3A%27docs%27";
- CHECK(s.http_escape() == t);
- CHECK(t.http_unescape() == s);
-}
-
-TEST_CASE("[String] percent_encode/decode") { // Note: is it redundant? Seems to be same as http_escape/unescape but in lower case.
- String s = "Godot Engine:'docs'";
- String t = "Godot%20Engine%3a%27docs%27";
-
- CHECK(s.percent_encode() == t);
- CHECK(t.percent_decode() == s);
+ CHECK(s.uri_encode() == t);
+ CHECK(t.uri_decode() == s);
}
TEST_CASE("[String] xml_escape/unescape") {
@@ -1177,6 +1166,52 @@ TEST_CASE("[String] xml_escape/unescape") {
CHECK(s.xml_escape(false).xml_unescape() == s);
}
+TEST_CASE("[String] xml_unescape") {
+ // Named entities
+ String input = "&quot;&amp;&apos;&lt;&gt;";
+ CHECK(input.xml_unescape() == "\"&\'<>");
+
+ // Numeric entities
+ input = "&#x41;&#66;";
+ CHECK(input.xml_unescape() == "AB");
+
+ input = "&#0;&x#0;More text";
+ String result = input.xml_unescape();
+ // Didn't put in a leading NUL and terminate the string
+ CHECK(input.length() > 0);
+ CHECK(input[0] != '\0');
+ // Entity should be left as-is if invalid
+ CHECK(input.xml_unescape() == input);
+
+ // Check near char32_t range
+ input = "&#xFFFFFFFF;";
+ result = input.xml_unescape();
+ CHECK(result.length() == 1);
+ CHECK(result[0] == 0xFFFFFFFF);
+ input = "&#4294967295;";
+ result = input.xml_unescape();
+ CHECK(result.length() == 1);
+ CHECK(result[0] == 0xFFFFFFFF);
+
+ // Check out of range of char32_t
+ input = "&#xFFFFFFFFF;";
+ CHECK(input.xml_unescape() == input);
+ input = "&#4294967296;";
+ CHECK(input.xml_unescape() == input);
+
+ // Shouldn't consume without ending in a ';'
+ input = "&#66";
+ CHECK(input.xml_unescape() == input);
+ input = "&#x41";
+ CHECK(input.xml_unescape() == input);
+
+ // Invalid characters should make the entity ignored
+ input = "&#x41SomeIrrelevantText;";
+ CHECK(input.xml_unescape() == input);
+ input = "&#66SomeIrrelevantText;";
+ CHECK(input.xml_unescape() == input);
+}
+
TEST_CASE("[String] Strip escapes") {
String s = "\t\tTest Test\r\n Test";
CHECK(s.strip_escapes() == "Test Test Test");
@@ -1283,6 +1318,20 @@ TEST_CASE("[String] humanize_size") {
CHECK(String::humanize_size(100523550) == "95.86 MiB");
CHECK(String::humanize_size(5345555000) == "4.97 GiB");
}
+
+TEST_CASE("[String] validate_node_name") {
+ String numeric_only = "12345";
+ CHECK(numeric_only.validate_node_name() == "12345");
+
+ String name_with_spaces = "Name with spaces";
+ CHECK(name_with_spaces.validate_node_name() == "Name with spaces");
+
+ String name_with_kana = "Name with kana ゴドツ";
+ CHECK(name_with_kana.validate_node_name() == "Name with kana ゴドツ");
+
+ String name_with_invalid_chars = "Name with invalid characters :.@removed!";
+ CHECK(name_with_invalid_chars.validate_node_name() == "Name with invalid characters removed!");
+}
} // namespace TestString
#endif // TEST_STRING_H
diff --git a/tests/test_text_server.h b/tests/test_text_server.h
index a1a97f3211..b0b40447fe 100644
--- a/tests/test_text_server.h
+++ b/tests/test_text_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,7 @@ TEST_SUITE("[[TextServer]") {
SUBCASE("[TextServer] Init") {
for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
TextServer *ts = TextServerManager::initialize(i, err);
- TEST_FAIL_COND((err != OK || ts == nullptr), "Text server " + TextServerManager::get_interface_name(i) + " init failed.");
+ TEST_FAIL_COND((err != OK || ts == nullptr), "Text server ", TextServerManager::get_interface_name(i), " init failed.");
}
}
diff --git a/modules/icloud/icloud_module.cpp b/tests/test_utils.cpp
index 43fdc7d45e..1666a257a9 100644
--- a/modules/icloud/icloud_module.cpp
+++ b/tests/test_utils.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* icloud_module.cpp */
+/* test_utils.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,21 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "icloud_module.h"
+#include "test_utils.h"
-#include "core/config/engine.h"
+#include "core/os/os.h"
-#include "icloud.h"
-
-ICloud *icloud;
-
-void register_icloud_types() {
- icloud = memnew(ICloud);
- Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud));
+String TestUtils::get_data_path(const String &p_file) {
+ String data_path = "../tests/data";
+ return get_executable_dir().plus_file(data_path.plus_file(p_file));
}
-void unregister_icloud_types() {
- if (icloud) {
- memdelete(icloud);
- }
+String TestUtils::get_executable_dir() {
+ return OS::get_singleton()->get_executable_path().get_base_dir();
}
diff --git a/core/os/rw_lock.cpp b/tests/test_utils.h
index 669f05c6b0..f05ab0bdb1 100644
--- a/core/os/rw_lock.cpp
+++ b/tests/test_utils.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rw_lock.cpp */
+/* test_utils.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,16 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "rw_lock.h"
+#ifndef TEST_UTILS_H
+#define TEST_UTILS_H
-#include "core/error/error_macros.h"
+#include "core/string/ustring.h"
-#include <stddef.h>
+namespace TestUtils {
-RWLock *(*RWLock::create_func)() = nullptr;
+String get_data_path(const String &p_file);
+String get_executable_dir();
+} // namespace TestUtils
-RWLock *RWLock::create() {
- ERR_FAIL_COND_V(!create_func, nullptr);
-
- return create_func();
-}
+#endif // TEST_UTILS_H
diff --git a/tests/test_validate_testing.h b/tests/test_validate_testing.h
index b4ea6eb576..6d3eea724c 100644
--- a/tests/test_validate_testing.h
+++ b/tests/test_validate_testing.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -179,10 +179,8 @@ TEST_SUITE("Validate tests") {
color_arr.push_back(Color(2, 2, 2));
INFO(color_arr);
- INFO("doctest insertion operator << "
- << var << " " << vec2 << " " << rect2 << " " << color);
-
- CHECK(true); // So all above prints.
+ // doctest string concatenation.
+ CHECK_MESSAGE(true, var, " ", vec2, " ", rect2, " ", color);
}
}
diff --git a/tests/test_variant.h b/tests/test_variant.h
index b575f6744d..dfc72b512c 100644
--- a/tests/test_variant.h
+++ b/tests/test_variant.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -105,6 +105,600 @@ TEST_CASE("[Variant] Writer and parser float") {
CHECK_MESSAGE(b64_float_parsed == 340282001837565597733306976381245063168.0, "Should not overflow.");
}
+
+TEST_CASE("[Variant] Assignment To Bool from Int,Float,String,Vec2,Vec2i,Vec3,Vec3i and Color") {
+ Variant int_v = 0;
+ Variant bool_v = true;
+ int_v = bool_v; // int_v is now a bool
+ CHECK(int_v == Variant(true));
+ bool_v = false;
+ int_v = bool_v;
+ CHECK(int_v.get_type() == Variant::BOOL);
+
+ Variant float_v = 0.0f;
+ bool_v = true;
+ float_v = bool_v;
+ CHECK(float_v == Variant(true));
+ bool_v = false;
+ float_v = bool_v;
+ CHECK(float_v.get_type() == Variant::BOOL);
+
+ Variant string_v = "";
+ bool_v = true;
+ string_v = bool_v;
+ CHECK(string_v == Variant(true));
+ bool_v = false;
+ string_v = bool_v;
+ CHECK(string_v.get_type() == Variant::BOOL);
+
+ Variant vec2_v = Vector2(0, 0);
+ bool_v = true;
+ vec2_v = bool_v;
+ CHECK(vec2_v == Variant(true));
+ bool_v = false;
+ vec2_v = bool_v;
+ CHECK(vec2_v.get_type() == Variant::BOOL);
+
+ Variant vec2i_v = Vector2i(0, 0);
+ bool_v = true;
+ vec2i_v = bool_v;
+ CHECK(vec2i_v == Variant(true));
+ bool_v = false;
+ vec2i_v = bool_v;
+ CHECK(vec2i_v.get_type() == Variant::BOOL);
+
+ Variant vec3_v = Vector3(0, 0, 0);
+ bool_v = true;
+ vec3_v = bool_v;
+ CHECK(vec3_v == Variant(true));
+ bool_v = false;
+ vec3_v = bool_v;
+ CHECK(vec3_v.get_type() == Variant::BOOL);
+
+ Variant vec3i_v = Vector3i(0, 0, 0);
+ bool_v = true;
+ vec3i_v = bool_v;
+ CHECK(vec3i_v == Variant(true));
+ bool_v = false;
+ vec3i_v = bool_v;
+ CHECK(vec3i_v.get_type() == Variant::BOOL);
+
+ Variant col_v = Color(0.5f, 0.2f, 0.75f);
+ bool_v = true;
+ col_v = bool_v;
+ CHECK(col_v == Variant(true));
+ bool_v = false;
+ col_v = bool_v;
+ CHECK(col_v.get_type() == Variant::BOOL);
+}
+
+TEST_CASE("[Variant] Assignment To Int from Bool,Float,String,Vec2,Vec2i,Vec3,Vec3i and Color") {
+ Variant bool_v = false;
+ Variant int_v = 2;
+ bool_v = int_v; // Now bool_v is int
+ CHECK(bool_v == Variant(2));
+ int_v = -3;
+ bool_v = int_v;
+ CHECK(bool_v.get_type() == Variant::INT);
+
+ Variant float_v = 0.0f;
+ int_v = 2;
+ float_v = int_v;
+ CHECK(float_v == Variant(2));
+ int_v = -3;
+ float_v = int_v;
+ CHECK(float_v.get_type() == Variant::INT);
+
+ Variant string_v = "";
+ int_v = 2;
+ string_v = int_v;
+ CHECK(string_v == Variant(2));
+ int_v = -3;
+ string_v = int_v;
+ CHECK(string_v.get_type() == Variant::INT);
+
+ Variant vec2_v = Vector2(0, 0);
+ int_v = 2;
+ vec2_v = int_v;
+ CHECK(vec2_v == Variant(2));
+ int_v = -3;
+ vec2_v = int_v;
+ CHECK(vec2_v.get_type() == Variant::INT);
+
+ Variant vec2i_v = Vector2i(0, 0);
+ int_v = 2;
+ vec2i_v = int_v;
+ CHECK(vec2i_v == Variant(2));
+ int_v = -3;
+ vec2i_v = int_v;
+ CHECK(vec2i_v.get_type() == Variant::INT);
+
+ Variant vec3_v = Vector3(0, 0, 0);
+ int_v = 2;
+ vec3_v = int_v;
+ CHECK(vec3_v == Variant(2));
+ int_v = -3;
+ vec3_v = int_v;
+ CHECK(vec3_v.get_type() == Variant::INT);
+
+ Variant vec3i_v = Vector3i(0, 0, 0);
+ int_v = 2;
+ vec3i_v = int_v;
+ CHECK(vec3i_v == Variant(2));
+ int_v = -3;
+ vec3i_v = int_v;
+ CHECK(vec3i_v.get_type() == Variant::INT);
+
+ Variant col_v = Color(0.5f, 0.2f, 0.75f);
+ int_v = 2;
+ col_v = int_v;
+ CHECK(col_v == Variant(2));
+ int_v = -3;
+ col_v = int_v;
+ CHECK(col_v.get_type() == Variant::INT);
+}
+
+TEST_CASE("[Variant] Assignment To Float from Bool,Int,String,Vec2,Vec2i,Vec3,Vec3i and Color") {
+ Variant bool_v = false;
+ Variant float_v = 1.5f;
+ bool_v = float_v; // Now bool_v is float
+ CHECK(bool_v == Variant(1.5f));
+ float_v = -4.6f;
+ bool_v = float_v;
+ CHECK(bool_v.get_type() == Variant::FLOAT);
+
+ Variant int_v = 1;
+ float_v = 1.5f;
+ int_v = float_v;
+ CHECK(int_v == Variant(1.5f));
+ float_v = -4.6f;
+ int_v = float_v;
+ CHECK(int_v.get_type() == Variant::FLOAT);
+
+ Variant string_v = "";
+ float_v = 1.5f;
+ string_v = float_v;
+ CHECK(string_v == Variant(1.5f));
+ float_v = -4.6f;
+ string_v = float_v;
+ CHECK(string_v.get_type() == Variant::FLOAT);
+
+ Variant vec2_v = Vector2(0, 0);
+ float_v = 1.5f;
+ vec2_v = float_v;
+ CHECK(vec2_v == Variant(1.5f));
+ float_v = -4.6f;
+ vec2_v = float_v;
+ CHECK(vec2_v.get_type() == Variant::FLOAT);
+
+ Variant vec2i_v = Vector2i(0, 0);
+ float_v = 1.5f;
+ vec2i_v = float_v;
+ CHECK(vec2i_v == Variant(1.5f));
+ float_v = -4.6f;
+ vec2i_v = float_v;
+ CHECK(vec2i_v.get_type() == Variant::FLOAT);
+
+ Variant vec3_v = Vector3(0, 0, 0);
+ float_v = 1.5f;
+ vec3_v = float_v;
+ CHECK(vec3_v == Variant(1.5f));
+ float_v = -4.6f;
+ vec3_v = float_v;
+ CHECK(vec3_v.get_type() == Variant::FLOAT);
+
+ Variant vec3i_v = Vector3i(0, 0, 0);
+ float_v = 1.5f;
+ vec3i_v = float_v;
+ CHECK(vec3i_v == Variant(1.5f));
+ float_v = -4.6f;
+ vec3i_v = float_v;
+ CHECK(vec3i_v.get_type() == Variant::FLOAT);
+
+ Variant col_v = Color(0.5f, 0.2f, 0.75f);
+ float_v = 1.5f;
+ col_v = float_v;
+ CHECK(col_v == Variant(1.5f));
+ float_v = -4.6f;
+ col_v = float_v;
+ CHECK(col_v.get_type() == Variant::FLOAT);
+}
+
+TEST_CASE("[Variant] Assignment To String from Bool,Int,Float,Vec2,Vec2i,Vec3,Vec3i and Color") {
+ Variant bool_v = false;
+ Variant string_v = "Hello";
+ bool_v = string_v; // Now bool_v is string
+ CHECK(bool_v == Variant("Hello"));
+ string_v = "Hello there";
+ bool_v = string_v;
+ CHECK(bool_v.get_type() == Variant::STRING);
+
+ Variant int_v = 0;
+ string_v = "Hello";
+ int_v = string_v;
+ CHECK(int_v == Variant("Hello"));
+ string_v = "Hello there";
+ int_v = string_v;
+ CHECK(int_v.get_type() == Variant::STRING);
+
+ Variant float_v = 0.0f;
+ string_v = "Hello";
+ float_v = string_v;
+ CHECK(float_v == Variant("Hello"));
+ string_v = "Hello there";
+ float_v = string_v;
+ CHECK(float_v.get_type() == Variant::STRING);
+
+ Variant vec2_v = Vector2(0, 0);
+ string_v = "Hello";
+ vec2_v = string_v;
+ CHECK(vec2_v == Variant("Hello"));
+ string_v = "Hello there";
+ vec2_v = string_v;
+ CHECK(vec2_v.get_type() == Variant::STRING);
+
+ Variant vec2i_v = Vector2i(0, 0);
+ string_v = "Hello";
+ vec2i_v = string_v;
+ CHECK(vec2i_v == Variant("Hello"));
+ string_v = "Hello there";
+ vec2i_v = string_v;
+ CHECK(vec2i_v.get_type() == Variant::STRING);
+
+ Variant vec3_v = Vector3(0, 0, 0);
+ string_v = "Hello";
+ vec3_v = string_v;
+ CHECK(vec3_v == Variant("Hello"));
+ string_v = "Hello there";
+ vec3_v = string_v;
+ CHECK(vec3_v.get_type() == Variant::STRING);
+
+ Variant vec3i_v = Vector3i(0, 0, 0);
+ string_v = "Hello";
+ vec3i_v = string_v;
+ CHECK(vec3i_v == Variant("Hello"));
+ string_v = "Hello there";
+ vec3i_v = string_v;
+ CHECK(vec3i_v.get_type() == Variant::STRING);
+
+ Variant col_v = Color(0.5f, 0.2f, 0.75f);
+ string_v = "Hello";
+ col_v = string_v;
+ CHECK(col_v == Variant("Hello"));
+ string_v = "Hello there";
+ col_v = string_v;
+ CHECK(col_v.get_type() == Variant::STRING);
+}
+
+TEST_CASE("[Variant] Assignment To Vec2 from Bool,Int,Float,String,Vec2i,Vec3,Vec3i and Color") {
+ Variant bool_v = false;
+ Variant vec2_v = Vector2(2.2f, 3.5f);
+ bool_v = vec2_v; // Now bool_v is Vector2
+ CHECK(bool_v == Variant(Vector2(2.2f, 3.5f)));
+ vec2_v = Vector2(-5.4f, -7.9f);
+ bool_v = vec2_v;
+ CHECK(bool_v.get_type() == Variant::VECTOR2);
+
+ Variant int_v = 0;
+ vec2_v = Vector2(2.2f, 3.5f);
+ int_v = vec2_v;
+ CHECK(int_v == Variant(Vector2(2.2f, 3.5f)));
+ vec2_v = Vector2(-5.4f, -7.9f);
+ int_v = vec2_v;
+ CHECK(int_v.get_type() == Variant::VECTOR2);
+
+ Variant float_v = 0.0f;
+ vec2_v = Vector2(2.2f, 3.5f);
+ float_v = vec2_v;
+ CHECK(float_v == Variant(Vector2(2.2f, 3.5f)));
+ vec2_v = Vector2(-5.4f, -7.9f);
+ float_v = vec2_v;
+ CHECK(float_v.get_type() == Variant::VECTOR2);
+
+ Variant string_v = "";
+ vec2_v = Vector2(2.2f, 3.5f);
+ string_v = vec2_v;
+ CHECK(string_v == Variant(Vector2(2.2f, 3.5f)));
+ vec2_v = Vector2(-5.4f, -7.9f);
+ string_v = vec2_v;
+ CHECK(string_v.get_type() == Variant::VECTOR2);
+
+ Variant vec2i_v = Vector2i(0, 0);
+ vec2_v = Vector2(2.2f, 3.5f);
+ vec2i_v = vec2_v;
+ CHECK(vec2i_v == Variant(Vector2(2.2f, 3.5f)));
+ vec2_v = Vector2(-5.4f, -7.9f);
+ vec2i_v = vec2_v;
+ CHECK(vec2i_v.get_type() == Variant::VECTOR2);
+
+ Variant vec3_v = Vector3(0, 0, 0);
+ vec2_v = Vector2(2.2f, 3.5f);
+ vec3_v = vec2_v;
+ CHECK(vec3_v == Variant(Vector2(2.2f, 3.5f)));
+ vec2_v = Vector2(-5.4f, -7.9f);
+ vec3_v = vec2_v;
+ CHECK(vec3_v.get_type() == Variant::VECTOR2);
+
+ Variant vec3i_v = Vector3i(0, 0, 0);
+ vec2_v = Vector2(2.2f, 3.5f);
+ vec3i_v = vec2_v;
+ CHECK(vec3i_v == Variant(Vector2(2.2f, 3.5f)));
+ vec2_v = Vector2(-5.4f, -7.9f);
+ vec3i_v = vec2_v;
+ CHECK(vec3i_v.get_type() == Variant::VECTOR2);
+
+ Variant col_v = Color(0.5f, 0.2f, 0.75f);
+ vec2_v = Vector2(2.2f, 3.5f);
+ col_v = vec2_v;
+ CHECK(col_v == Variant(Vector2(2.2f, 3.5f)));
+ vec2_v = Vector2(-5.4f, -7.9f);
+ col_v = vec2_v;
+ CHECK(col_v.get_type() == Variant::VECTOR2);
+}
+
+TEST_CASE("[Variant] Assignment To Vec2i from Bool,Int,Float,String,Vec2,Vec3,Vec3i and Color") {
+ Variant bool_v = false;
+ Variant vec2i_v = Vector2i(2, 3);
+ bool_v = vec2i_v; // Now bool_v is Vector2i
+ CHECK(bool_v == Variant(Vector2i(2, 3)));
+ vec2i_v = Vector2i(-5, -7);
+ bool_v = vec2i_v;
+ CHECK(bool_v.get_type() == Variant::VECTOR2I);
+
+ Variant int_v = 0;
+ vec2i_v = Vector2i(2, 3);
+ int_v = vec2i_v;
+ CHECK(int_v == Variant(Vector2i(2, 3)));
+ vec2i_v = Vector2i(-5, -7);
+ int_v = vec2i_v;
+ CHECK(int_v.get_type() == Variant::VECTOR2I);
+
+ Variant float_v = 0.0f;
+ vec2i_v = Vector2i(2, 3);
+ float_v = vec2i_v;
+ CHECK(float_v == Variant(Vector2i(2, 3)));
+ vec2i_v = Vector2i(-5, -7);
+ float_v = vec2i_v;
+ CHECK(float_v.get_type() == Variant::VECTOR2I);
+
+ Variant string_v = "";
+ vec2i_v = Vector2i(2, 3);
+ string_v = vec2i_v;
+ CHECK(string_v == Variant(Vector2i(2, 3)));
+ vec2i_v = Vector2i(-5, -7);
+ string_v = vec2i_v;
+ CHECK(string_v.get_type() == Variant::VECTOR2I);
+
+ Variant vec2_v = Vector2(0, 0);
+ vec2i_v = Vector2i(2, 3);
+ vec2_v = vec2i_v;
+ CHECK(vec2_v == Variant(Vector2i(2, 3)));
+ vec2i_v = Vector2i(-5, -7);
+ vec2_v = vec2i_v;
+ CHECK(vec2i_v.get_type() == Variant::VECTOR2I);
+
+ Variant vec3_v = Vector3(0, 0, 0);
+ vec2i_v = Vector2i(2, 3);
+ vec3_v = vec2i_v;
+ CHECK(vec3_v == Variant(Vector2i(2, 3)));
+ vec2i_v = Vector2i(-5, -7);
+ vec3_v = vec2i_v;
+ CHECK(vec3_v.get_type() == Variant::VECTOR2I);
+
+ Variant vec3i_v = Vector3i(0, 0, 0);
+ vec2i_v = Vector2i(2, 3);
+ vec3i_v = vec2i_v;
+ CHECK(vec3i_v == Variant(Vector2i(2, 3)));
+ vec2i_v = Vector2i(-5, -7);
+ vec3i_v = vec2i_v;
+ CHECK(vec3i_v.get_type() == Variant::VECTOR2I);
+
+ Variant col_v = Color(0.5f, 0.2f, 0.75f);
+ vec2i_v = Vector2i(2, 3);
+ col_v = vec2i_v;
+ CHECK(col_v == Variant(Vector2i(2, 3)));
+ vec2i_v = Vector2i(-5, -7);
+ col_v = vec2i_v;
+ CHECK(col_v.get_type() == Variant::VECTOR2I);
+}
+
+TEST_CASE("[Variant] Assignment To Vec3 from Bool,Int,Float,String,Vec2,Vec2i,Vec3i and Color") {
+ Variant bool_v = false;
+ Variant vec3_v = Vector3(2.2f, 3.5f, 5.3f);
+ bool_v = vec3_v; // Now bool_v is Vector3
+ CHECK(bool_v == Variant(Vector3(2.2f, 3.5f, 5.3f)));
+ vec3_v = Vector3(-5.4f, -7.9f, -2.1f);
+ bool_v = vec3_v;
+ CHECK(bool_v.get_type() == Variant::VECTOR3);
+
+ Variant int_v = 0;
+ vec3_v = Vector3(2.2f, 3.5f, 5.3f);
+ int_v = vec3_v;
+ CHECK(int_v == Variant(Vector3(2.2f, 3.5f, 5.3f)));
+ vec3_v = Vector3(-5.4f, -7.9f, -2.1f);
+ int_v = vec3_v;
+ CHECK(int_v.get_type() == Variant::VECTOR3);
+
+ Variant float_v = 0.0f;
+ vec3_v = Vector3(2.2f, 3.5f, 5.3f);
+ float_v = vec3_v;
+ CHECK(float_v == Variant(Vector3(2.2f, 3.5f, 5.3f)));
+ vec3_v = Vector3(-5.4f, -7.9f, -2.1f);
+ float_v = vec3_v;
+ CHECK(float_v.get_type() == Variant::VECTOR3);
+
+ Variant string_v = "";
+ vec3_v = Vector3(2.2f, 3.5f, 5.3f);
+ string_v = vec3_v;
+ CHECK(string_v == Variant(Vector3(2.2f, 3.5f, 5.3f)));
+ vec3_v = Vector3(-5.4f, -7.9f, -2.1f);
+ string_v = vec3_v;
+ CHECK(string_v.get_type() == Variant::VECTOR3);
+
+ Variant vec2_v = Vector2(0, 0);
+ vec3_v = Vector3(2.2f, 3.5f, 5.3f);
+ vec2_v = vec3_v;
+ CHECK(vec2_v == Variant(Vector3(2.2f, 3.5f, 5.3f)));
+ vec3_v = Vector3(-5.4f, -7.9f, -2.1f);
+ vec2_v = vec3_v;
+ CHECK(vec2_v.get_type() == Variant::VECTOR3);
+
+ Variant vec2i_v = Vector2i(0, 0);
+ vec3_v = Vector3(2.2f, 3.5f, 5.3f);
+ vec2i_v = vec3_v;
+ CHECK(vec2i_v == Variant(Vector3(2.2f, 3.5f, 5.3f)));
+ vec3_v = Vector3(-5.4f, -7.9f, -2.1f);
+ vec2i_v = vec3_v;
+ CHECK(vec2i_v.get_type() == Variant::VECTOR3);
+
+ Variant vec3i_v = Vector3i(0, 0, 0);
+ vec3_v = Vector3(2.2f, 3.5f, 5.3f);
+ vec3i_v = vec3_v;
+ CHECK(vec3i_v == Variant(Vector3(2.2f, 3.5f, 5.3f)));
+ vec3_v = Vector3(-5.4f, -7.9f, -2.1f);
+ vec3i_v = vec3_v;
+ CHECK(vec3i_v.get_type() == Variant::VECTOR3);
+
+ Variant col_v = Color(0.5f, 0.2f, 0.75f);
+ vec3_v = Vector3(2.2f, 3.5f, 5.3f);
+ col_v = vec3_v;
+ CHECK(col_v == Variant(Vector3(2.2f, 3.5f, 5.3f)));
+ vec3_v = Vector3(-5.4f, -7.9f, -2.1f);
+ col_v = vec3_v;
+ CHECK(col_v.get_type() == Variant::VECTOR3);
+}
+
+TEST_CASE("[Variant] Assignment To Vec3i from Bool,Int,Float,String,Vec2,Vec2i,Vec3 and Color") {
+ Variant bool_v = false;
+ Variant vec3i_v = Vector3i(2, 3, 5);
+ bool_v = vec3i_v; // Now bool_v is Vector3i
+ CHECK(bool_v == Variant(Vector3i(2, 3, 5)));
+ vec3i_v = Vector3i(-5, -7, -2);
+ bool_v = vec3i_v;
+ CHECK(bool_v.get_type() == Variant::VECTOR3I);
+
+ Variant int_v = 0;
+ vec3i_v = Vector3i(2, 3, 5);
+ int_v = vec3i_v;
+ CHECK(int_v == Variant(Vector3i(2, 3, 5)));
+ vec3i_v = Vector3i(-5, -7, -2);
+ int_v = vec3i_v;
+ CHECK(int_v.get_type() == Variant::VECTOR3I);
+
+ Variant float_v = 0.0f;
+ vec3i_v = Vector3i(2, 3, 5);
+ float_v = vec3i_v;
+ CHECK(float_v == Variant(Vector3i(2, 3, 5)));
+ vec3i_v = Vector3i(-5, -7, -2);
+ float_v = vec3i_v;
+ CHECK(float_v.get_type() == Variant::VECTOR3I);
+
+ Variant string_v = "";
+ vec3i_v = Vector3i(2, 3, 5);
+ string_v = vec3i_v;
+ CHECK(string_v == Variant(Vector3i(2, 3, 5)));
+ vec3i_v = Vector3i(-5, -7, -2);
+ string_v = vec3i_v;
+ CHECK(string_v.get_type() == Variant::VECTOR3I);
+
+ Variant vec2_v = Vector2(0, 0);
+ vec3i_v = Vector3i(2, 3, 5);
+ vec2_v = vec3i_v;
+ CHECK(vec2_v == Variant(Vector3i(2, 3, 5)));
+ vec3i_v = Vector3i(-5, -7, -2);
+ vec2_v = vec3i_v;
+ CHECK(vec2_v.get_type() == Variant::VECTOR3I);
+
+ Variant vec2i_v = Vector2i(0, 0);
+ vec3i_v = Vector3i(2, 3, 5);
+ vec2i_v = vec3i_v;
+ CHECK(vec2i_v == Variant(Vector3i(2, 3, 5)));
+ vec3i_v = Vector3i(-5, -7, -2);
+ vec2i_v = vec3i_v;
+ CHECK(vec2i_v.get_type() == Variant::VECTOR3I);
+
+ Variant vec3_v = Vector3(0, 0, 0);
+ vec3i_v = Vector3i(2, 3, 5);
+ vec3_v = vec3i_v;
+ CHECK(vec3_v == Variant(Vector3i(2, 3, 5)));
+ vec3i_v = Vector3i(-5, -7, -2);
+ vec3_v = vec3i_v;
+ CHECK(vec3_v.get_type() == Variant::VECTOR3I);
+
+ Variant col_v = Color(0.5f, 0.2f, 0.75f);
+ vec3i_v = Vector3i(2, 3, 5);
+ col_v = vec3i_v;
+ CHECK(col_v == Variant(Vector3i(2, 3, 5)));
+ vec3i_v = Vector3i(-5, -7, -2);
+ col_v = vec3i_v;
+ CHECK(col_v.get_type() == Variant::VECTOR3I);
+}
+
+TEST_CASE("[Variant] Assignment To Color from Bool,Int,Float,String,Vec2,Vec2i,Vec3 and Vec3i") {
+ Variant bool_v = false;
+ Variant col_v = Color(0.25f, 0.4f, 0.78f);
+ bool_v = col_v; // Now bool_v is Color
+ CHECK(bool_v == Variant(Color(0.25f, 0.4f, 0.78f)));
+ col_v = Color(0.33f, 0.75f, 0.21f);
+ bool_v = col_v;
+ CHECK(bool_v.get_type() == Variant::COLOR);
+
+ Variant int_v = 0;
+ col_v = Color(0.25f, 0.4f, 0.78f);
+ int_v = col_v;
+ CHECK(int_v == Variant(Color(0.25f, 0.4f, 0.78f)));
+ col_v = Color(0.33f, 0.75f, 0.21f);
+ int_v = col_v;
+ CHECK(int_v.get_type() == Variant::COLOR);
+
+ Variant float_v = 0.0f;
+ col_v = Color(0.25f, 0.4f, 0.78f);
+ float_v = col_v;
+ CHECK(float_v == Variant(Color(0.25f, 0.4f, 0.78f)));
+ col_v = Color(0.33f, 0.75f, 0.21f);
+ float_v = col_v;
+ CHECK(float_v.get_type() == Variant::COLOR);
+
+ Variant string_v = "";
+ col_v = Color(0.25f, 0.4f, 0.78f);
+ string_v = col_v;
+ CHECK(string_v == Variant(Color(0.25f, 0.4f, 0.78f)));
+ col_v = Color(0.33f, 0.75f, 0.21f);
+ string_v = col_v;
+ CHECK(string_v.get_type() == Variant::COLOR);
+
+ Variant vec2_v = Vector2(0, 0);
+ col_v = Color(0.25f, 0.4f, 0.78f);
+ vec2_v = col_v;
+ CHECK(vec2_v == Variant(Color(0.25f, 0.4f, 0.78f)));
+ col_v = Color(0.33f, 0.75f, 0.21f);
+ vec2_v = col_v;
+ CHECK(vec2_v.get_type() == Variant::COLOR);
+
+ Variant vec2i_v = Vector2i(0, 0);
+ col_v = Color(0.25f, 0.4f, 0.78f);
+ vec2i_v = col_v;
+ CHECK(vec2i_v == Variant(Color(0.25f, 0.4f, 0.78f)));
+ col_v = Color(0.33f, 0.75f, 0.21f);
+ vec2i_v = col_v;
+ CHECK(vec2i_v.get_type() == Variant::COLOR);
+
+ Variant vec3_v = Vector3(0, 0, 0);
+ col_v = Color(0.25f, 0.4f, 0.78f);
+ vec3_v = col_v;
+ CHECK(vec3_v == Variant(Color(0.25f, 0.4f, 0.78f)));
+ col_v = Color(0.33f, 0.75f, 0.21f);
+ vec3_v = col_v;
+ CHECK(vec3_v.get_type() == Variant::COLOR);
+
+ Variant vec3i_v = Vector3i(0, 0, 0);
+ col_v = Color(0.25f, 0.4f, 0.78f);
+ vec3i_v = col_v;
+ CHECK(vec3i_v == Variant(Color(0.25f, 0.4f, 0.78f)));
+ col_v = Color(0.33f, 0.75f, 0.21f);
+ vec3i_v = col_v;
+ CHECK(vec3i_v.get_type() == Variant::COLOR);
+}
} // namespace TestVariant
#endif // TEST_VARIANT_H
diff --git a/drivers/windows/rw_lock_windows.cpp b/tests/test_xml_parser.h
index 1007689728..55de048d6a 100644
--- a/drivers/windows/rw_lock_windows.cpp
+++ b/tests/test_xml_parser.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* rw_lock_windows.cpp */
+/* test_xml_parser.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -28,60 +28,47 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if defined(WINDOWS_ENABLED)
+#ifndef TEST_XML_PARSER_H
+#define TEST_XML_PARSER_H
-#include "rw_lock_windows.h"
+#include <inttypes.h>
-#include "core/error/error_macros.h"
-#include "core/os/memory.h"
+#include "core/io/xml_parser.h"
+#include "core/string/ustring.h"
-#include <stdio.h>
+#include "tests/test_macros.h"
-void RWLockWindows::read_lock() {
- AcquireSRWLockShared(&lock);
-}
-
-void RWLockWindows::read_unlock() {
- ReleaseSRWLockShared(&lock);
-}
-
-Error RWLockWindows::read_try_lock() {
- if (TryAcquireSRWLockShared(&lock) == 0) {
- return ERR_BUSY;
- } else {
- return OK;
- }
-}
-
-void RWLockWindows::write_lock() {
- AcquireSRWLockExclusive(&lock);
-}
+namespace TestXMLParser {
+TEST_CASE("[XMLParser] End-to-end") {
+ String source = "<?xml version = \"1.0\" encoding=\"UTF-8\" ?>\
+<top attr=\"attr value\">\
+ Text&lt;&#65;&#x42;&gt;\
+</top>";
+ Vector<uint8_t> buff = source.to_utf8_buffer();
-void RWLockWindows::write_unlock() {
- ReleaseSRWLockExclusive(&lock);
-}
+ XMLParser parser;
+ parser.open_buffer(buff);
-Error RWLockWindows::write_try_lock() {
- if (TryAcquireSRWLockExclusive(&lock) == 0) {
- return ERR_BUSY;
- } else {
- return OK;
- }
-}
+ // <?xml ...?> gets parsed as NODE_UNKNOWN
+ CHECK(parser.read() == OK);
+ CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_UNKNOWN);
-RWLock *RWLockWindows::create_func_windows() {
- return memnew(RWLockWindows);
-}
+ CHECK(parser.read() == OK);
+ CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_ELEMENT);
+ CHECK(parser.get_node_name() == "top");
+ CHECK(parser.has_attribute("attr"));
+ CHECK(parser.get_attribute_value("attr") == "attr value");
-void RWLockWindows::make_default() {
- create_func = create_func_windows;
-}
+ CHECK(parser.read() == OK);
+ CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_TEXT);
+ CHECK(parser.get_node_data().lstrip(" \t") == "Text<AB>");
-RWLockWindows::RWLockWindows() {
- InitializeSRWLock(&lock);
-}
+ CHECK(parser.read() == OK);
+ CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_ELEMENT_END);
+ CHECK(parser.get_node_name() == "top");
-RWLockWindows::~RWLockWindows() {
+ parser.close();
}
+} // namespace TestXMLParser
-#endif
+#endif // TEST_XML_PARSER_H
diff --git a/thirdparty/README.md b/thirdparty/README.md
index f31a9b864c..3803e87fea 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -3,7 +3,6 @@
Please keep categories (`##` level) listed alphabetically and matching their
respective folder names. Use two empty lines to separate categories for
readability.
-Subcategories (`###` level) where needed are separated by a single empty line.
## basis_universal
@@ -22,7 +21,7 @@ Files extracted from upstream source:
## bullet
- Upstream: https://github.com/bulletphysics/bullet3
-- Version: 3.07 (e32fc59c88a3908876949c6f2665e8d091d987fa, 2020)
+- Version: 3.08 (df09fd9ed37e365ceae884ca7f620b61607dae2e, 2020)
- License: zlib
Files extracted from upstream source:
@@ -46,7 +45,7 @@ as it's generated on the user's system.)
## cvtt
- Upstream: https://github.com/elasota/cvtt
-- Version: 1.0.0-beta4 (2018)
+- Version: 1.0.0-beta4 (cc8472a04ba110fe999c686d07af40f7839051fd, 2018)
- License: MIT
Files extracted from upstream source:
@@ -55,16 +54,18 @@ Files extracted from upstream source:
## doctest
+
- Upstream: https://github.com/onqtam/doctest
-- Version: 8424be5 (2.4.1)
+- Version: 2.4.4 (97d5a9447e66cd5e107b7a6c463be4a468a40496, 2020)
- License: MIT
Extracted from .zip provided. Extracted license and header only.
+
## enet
- Upstream: http://enet.bespin.org
-- Version: 1.3.15 (224f31101fc60939c02f6bbe8e8fc810a7db306b, 2020)
+- Version: 1.3.17 (e0e7045b7e056b454b5093cb34df49dc4cee0bee, 2020)
- License: MIT
Files extracted from upstream source:
@@ -74,11 +75,11 @@ Files extracted from upstream source:
- LICENSE file
Important: enet.h, host.c, protocol.c have been slightly modified
-to be usable by godot socket implementation and allow IPv6 and DTLS.
+to be usable by Godot's socket implementation and allow IPv6 and DTLS.
Apply the patches in the `patches/` folder when syncing on newer upstream
commits.
-Two files (godot.cpp and enet/godot.h) have been added to provide
+Three files (godot.cpp, enet/godot.h, enet/godot_ext.h) have been added to provide
enet socket implementation using Godot classes.
It is still possible to build against a system wide ENet but doing so
@@ -103,37 +104,31 @@ comments.
## fonts
-### Noto Sans
-
-- Upstream: https://github.com/googlei18n/noto-fonts
-- Version: 1.06 (2017)
-- License: OFL-1.1
-
-Use UI font variant if available, because it has tight vertical metrics and good for UI.
-
-### Hack Regular
-
-- Upstream: https://github.com/source-foundry/Hack
-- Version: 3.003 (2018)
-- License: MIT + Bitstream Vera License
-
-### DroidSans*.ttf
-
-- Upstream: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/
-- Version: ? (pre-2014 commit when DroidSansJapanese.ttf was obsoleted)
-- License: Apache 2.0
-
-### Tamsyn
-- Upstream: http://www.fial.com/~scott/tamsyn-font/
-- Version: 1.11
-- License: Tamsyn
+- `NotoSans*.ttf`, `NotoNaskhArabicUI_Regular.ttf`:
+ * Upstream: https://github.com/googlei18n/noto-fonts
+ * Version: 1.06 (2017)
+ * License: OFL-1.1
+ * Comment: Use UI font variant if available, because it has tight vertical metrics and
+ good for UI.
+- `Hack_Regular.ttf`:
+ * Upstream: https://github.com/source-foundry/Hack
+ * Version: 3.003 (2018)
+ * License: MIT + Bitstream Vera License
+- `DroidSans*.ttf`:
+ * Upstream: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/
+ * Version: ? (pre-2014 commit when DroidSansJapanese.ttf was obsoleted)
+ * License: Apache 2.0
+- `Tamsyn*.png`:
+ * Upstream: http://www.fial.com/~scott/tamsyn-font/
+ * Version: 1.11 (2015)
+ * License: Tamsyn
+ * Comment: Extracted "0..9,A..F" characters for hex code printing.
-Extracted "0..9,A..F" characters for hex code printing.
## freetype
- Upstream: https://www.freetype.org
-- Version: 2.10.4 (2020)
+- Version: 2.10.4 (6a2b3e4007e794bfc6c91030d0ed987f925164a8, 2020)
- License: FreeType License (BSD-like)
Files extracted from upstream source:
@@ -162,45 +157,55 @@ Files extracted from upstream source:
- `LICENSE.txt`
- Unnecessary files like `CMakeLists.txt` and `updateGrammar` removed.
-## Graphite engine
+
+## graphite
- Upstream: https://github.com/silnrsi/graphite
-- Version: 1.3.14
+- Version: 1.3.14 (92f59dcc52f73ce747f1cdc831579ed2546884aa, 2020)
- License: MPL-2.0
Files extracted from upstream source:
+
- the `include` folder
- the `src` folder
- `COPYING`, `ChangeLog`
-## HarfBuzz
+
+## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz
-- Version: 2.7.2
-- License: HarfBuzz
+- Version: 2.7.4 (7236c7e29cef1c2d76c7a284c5081ff4d3aa1127, 2020)
+- License: MIT
Files extracted from upstream source:
+
- the `src` folder
- `AUTHORS`, `COPYING`, `NEWS`, `THANKS`
-## International Components for Unicode
+
+## icu4c
- Upstream: https://github.com/unicode-org/icu
-- Version: 68.2
+- Version: 68.2 (84e1f26ea77152936e70d53178a816dbfbf69989, 2020)
- License: Unicode
Files extracted from upstream source:
+
- the `common` folder
- `APIChangeReport.md`, `LICENSE`
Files generated from upstream source:
-- the `icudt68l.dat` built with the provided `godot_data.json` config file (see https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/buildtool.md for instructions)
+
+- the `icudt68l.dat` built with the provided `godot_data.json` config file (see
+ https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/buildtool.md
+ for instructions)
+
## jpeg-compressor
- Upstream: https://github.com/richgel999/jpeg-compressor
- Version: 2.00 (aeb7d3b463aa8228b87a28013c15ee50a7e6fcf3, 2020)
-- License: Public domain
+- License: Public domain or MIT
Files extracted from upstream source:
@@ -223,7 +228,7 @@ Files extracted from upstream source:
## libpng
- Upstream: http://libpng.org/pub/png/libpng.html
-- Version: 1.6.37 (2019)
+- Version: 1.6.37 (a40189cf881e9f0db80511c382292a5604c3c3d1, 2019)
- License: libpng/zlib
Files extracted from upstream source:
@@ -303,7 +308,7 @@ from the Android NDK r18.
## libwebp
- Upstream: https://chromium.googlesource.com/webm/libwebp/
-- Version: 1.1.0 (2020)
+- Version: 1.1.0 (d7844e9762b61c9638c263657bd49e1690184832, 2020)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -319,7 +324,7 @@ changes are marked with `// -- GODOT --` comments.
## mbedtls
- Upstream: https://tls.mbed.org/
-- Version: 2.16.9 (2020)
+- Version: 2.16.9 (3fac0bae4a50113989b3d015cd2d948f51a6d9ac, 2020)
- License: Apache 2.0
File extracted from upstream release tarball:
@@ -339,16 +344,13 @@ File extracted from upstream release tarball:
## meshoptimizer
- Upstream: https://github.com/zeux/meshoptimizer
-- Version: 0.15 (2020)
+- Version: git (e3f53f66e7a35b9b8764bee478589d79e34fa698, 2021)
- License: MIT
-File extracted from upstream release tarball:
+Files extracted from upstream repository:
- All files in `src/`.
-
-Important: Some files have Godot-made changes.
-They can be applied with the patch in the `patches` folder, but are meant to be superseded
-by upstream API changes.
+- `LICENSE.md`.
## miniupnpc
@@ -386,8 +388,6 @@ comments and a patch is provided in the minizip/ folder.
Collection of single-file libraries used in Godot components.
-### core
-
- `clipper.{cpp,hpp}`
* Upstream: https://sourceforge.net/projects/polyclipping
* Version: 6.4.2 (2017) + Godot changes (added optional exceptions handling)
@@ -396,6 +396,10 @@ Collection of single-file libraries used in Godot components.
* Upstream: https://research.activision.com/publications/archives/fast-filtering-of-reflection-probes
File coeffs_const_8.txt (retrieved April 2020)
* License: MIT
+- `easing_equations.cpp`
+ * Upstream: http://robertpenner.com/easing/ via https://github.com/jesusgollonet/ofpennereasing (modified to fit Godot types)
+ * Version: git (af72c147c3a74e7e872aa28c7e2abfcced04fdce, 2008) + Godot types and style changes
+ * License: BSD-3-Clause
- `fastlz.{c,h}`
* Upstream: https://github.com/ariya/FastLZ
* Version: 0.5.0 (4f20f54d46f5a6dd4fae4def134933369b7602d2, 2020)
@@ -404,61 +408,49 @@ Collection of single-file libraries used in Godot components.
* Upstream: https://github.com/brunexgeek/hqx
* Version: TBD, file structure differs
* License: Apache 2.0
+- `ifaddrs-android.{cc,h}`
+ * Upstream: https://chromium.googlesource.com/external/webrtc/stable/talk/+/master/base/ifaddrs-android.h
+ * Version: git (5976650443d68ccfadf1dea24999ee459dd2819d, 2013)
+ * License: BSD-3-Clause
+- `mikktspace.{c,h}`
+ * Upstream: https://archive.blender.org/wiki/index.php/Dev:Shading/Tangent_Space_Normal_Maps/
+ * Version: 1.0 (2011)
+ * License: zlib
- `open-simplex-noise.{c,h}`
* Upstream: https://github.com/smcameron/open-simplex-noise-in-c
* Version: git (826f1dd1724e6fb3ff45f58e48c0fbae864c3403, 2020) + custom changes
- * License: Unlicense
+ * License: Public Domain or Unlicense
- `pcg.{cpp,h}`
* Upstream: http://www.pcg-random.org
* Version: minimal C implementation, http://www.pcg-random.org/download.html
* License: Apache 2.0
+- `polypartition.{cpp,h}`
+ * Upstream: https://github.com/ivanfratric/polypartition (`src/polypartition.{cpp,h}`)
+ * Version: git (7bdffb428b2b19ad1c43aa44c714dcc104177e84, 2021)
+ * Modifications: Change from STL to Godot types (see provided patch).
+ * License: MIT
- `r128.h`
* Upstream: https://github.com/fahickman/r128
- * Version: git (423f693617faafd01de21e92818add4208eb8bd1, 2020)
- * License: Public Domain
+ * Version: 1.4.4 (cf2e88fc3e7d7dfe99189686f914874cd0bda15e, 2020)
+ * License: Public Domain or Unlicense
- `smaz.{c,h}`
* Upstream: https://github.com/antirez/smaz
- * Version: git (150e125cbae2e8fd20dd332432776ce13395d4d4, 2009)
+ * Version: git (2f625846a775501fb69456567409a8b12f10ea25, 2012)
* License: BSD-3-Clause
* Modifications: use `const char*` instead of `char*` for input string
- `stb_rect_pack.h`
* Upstream: https://github.com/nothings/stb
- * Version: 1.00 (2019)
- * License: Public Domain (Unlicense) or MIT
-- `triangulator.{cpp,h}`
- * Upstream: https://github.com/ivanfratric/polypartition (`src/polypartition.cpp`)
- * Version: TBD, class was renamed
- * License: MIT
-
-### modules
-
+ * Version: 1.00 (2bb4a0accd4003c1db4c24533981e01b1adfd656, 2019)
+ * License: Public Domain or Unlicense or MIT
+- `stb_vorbis.c`
+ * Upstream: https://github.com/nothings/stb
+ * Version: 1.20 (314d0a6f9af5af27e585336eecea333e95c5a2d8, 2020)
+ * License: Public Domain or Unlicense or MIT
- `yuv2rgb.h`
* Upstream: http://wss.co.uk/pinknoise/yuv2rgb/ (to check)
* Version: ?
* License: BSD
-### platform
-
-- `ifaddrs-android.{cc,h}`
- * Upstream: https://chromium.googlesource.com/external/webrtc/stable/talk/+/master/base/ifaddrs-android.h
- * Version: git (5976650443d68ccfadf1dea24999ee459dd2819d, 2013)
- * License: BSD-3-Clause
-
-### scene
-
-- `easing_equations.cpp`
- * Upstream: http://robertpenner.com/easing/ via https://github.com/jesusgollonet/ofpennereasing (modified to fit Godot types)
- * Version: git (af72c147c3a74e7e872aa28c7e2abfcced04fdce, 2008) + Godot types and style changes
- * License: BSD-3-Clause
-- `mikktspace.{c,h}`
- * Upstream: https://archive.blender.org/wiki/index.php/Dev:Shading/Tangent_Space_Normal_Maps/
- * Version: 1.0 (2011)
- * License: zlib
-- `stb_vorbis.c`
- * Upstream: https://github.com/nothings/stb
- * Version: 1.20
- * License: Public Domain (Unlicense) or MIT
-
## nanosvg
@@ -480,27 +472,27 @@ Files extracted from the upstream source:
Files extracted from upstream source:
-common/* (except tasking.* and CMakeLists.txt)
-core/*
-include/OpenImageDenoise/* (except version.h.in)
-LICENSE.txt
-mkl-dnn/include/*
-mkl-dnn/src/* (except CMakeLists.txt)
-weights/rtlightmap_hdr.tza
-scripts/resource_to_cpp.py
+- common/* (except tasking.* and CMakeLists.txt)
+- core/*
+- include/OpenImageDenoise/* (except version.h.in)
+- LICENSE.txt
+- mkl-dnn/include/*
+- mkl-dnn/src/* (except CMakeLists.txt)
+- weights/rtlightmap_hdr.tza
+- scripts/resource_to_cpp.py
Modified files:
Modifications are marked with `// -- GODOT start --` and `// -- GODOT end --`.
Patch files are provided in `oidn/patches/`.
-core/autoencoder.cpp
-core/autoencoder.h
-core/common.h
-core/device.cpp
-core/device.h
-core/transfer_function.cpp
+- core/autoencoder.cpp
+- core/autoencoder.h
+- core/common.h
+- core/device.cpp
+- core/device.h
+- core/transfer_function.cpp
-scripts/resource_to_cpp.py (used in modules/denoise/resource_to_cpp.py)
+- scripts/resource_to_cpp.py (used in modules/denoise/resource_to_cpp.py)
## opus
@@ -523,7 +515,7 @@ Files extracted from upstream source:
## pcre2
- Upstream: http://www.pcre.org
-- Version: 10.34 (2019)
+- Version: 10.36 (r1288, 2020)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -532,13 +524,14 @@ Files extracted from upstream source:
- All .h files in src/ apart from pcre2posix.h
- src/pcre2_jit_match.c
- src/pcre2_jit_misc.c
-- src/sljit/*
+- src/sljit/
- AUTHORS and LICENCE
## pvrtccompressor
-- Upstream: https://bitbucket.org/jthlim/pvrtccompressor
+- Upstream: https://bitbucket.org/jthlim/pvrtccompressor (dead link)
+ Unofficial backup fork: https://github.com/LibreGamesArchive/PVRTCCompressor
- Version: hg (cf7177748ee0dcdccfe89716dc11a47d2dc81af5, 2015)
- License: BSD-3-Clause
@@ -562,8 +555,8 @@ Files extracted from upstream source:
## rvo2
-- Upstream: http://gamma.cs.unc.edu/RVO2/
-- Version: 3D - 1.0.1 (2016)
+- Upstream: https://github.com/snape/RVO2-3D
+- Version: 1.0.1 (e3883f288a9e55ecfed3633a01af3e12778c6acf, 2016)
- License: Apache 2.0
Files extracted from upstream source:
@@ -576,10 +569,23 @@ originally proposed by this library and better integrate this library with
Godot. Please check the file to know what's new.
+## spirv-reflect
+
+- Upstream: https://github.com/KhronosGroup/SPIRV-Reflect
+- Version: git (c0ce03a43ca77fedb5abfd1976ae2fd0eeb0e611, 2021)
+- License: Apache 2.0
+
+Files extracted from upstream source:
+
+- `spirv_reflect.{c,h}`
+- `include` folder
+- `LICENSE`
+
+
## squish
- Upstream: https://sourceforge.net/projects/libsquish
-- Version: 1.15 (2017)
+- Version: 1.15 (r104, 2017)
- License: MIT
Files extracted from upstream source:
@@ -622,7 +628,7 @@ folder.
## vulkan
- Upstream: https://github.com/KhronosGroup/Vulkan-Loader
-- Version: sdk-1.2.162.0 (2020)
+- Version: sdk-1.2.162.0 (7a313093b5c4af964d50a5a64e73d7df6152ea3f, 2020)
- License: Apache 2.0
Unless there is a specific reason to package a more recent version, please stick
@@ -651,7 +657,7 @@ Patches in the `patches` directory should be re-applied after updates.
## wslay
- Upstream: https://github.com/tatsuhiro-t/wslay
-- Version: 1.1.1 (2020)
+- Version: 1.1.1 (c9a84aa6df8512584c77c8cd15be9536b89c35aa, 2020)
- License: MIT
File extracted from upstream release tarball:
@@ -687,7 +693,7 @@ Files extracted from upstream source:
## zstd
- Upstream: https://github.com/facebook/zstd
-- Version: 1.4.5 (2020)
+- Version: 1.4.8 (97a3da1df009d4dc67251de0c4b1c9d7fe286fc1, 2020)
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
index cac5302a73..cac5302a73 100755..100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h
index 75ca34e978..75ca34e978 100755..100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
index bec8c6530d..7cb92fa3b4 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
@@ -125,7 +125,8 @@ btMultiBody::btMultiBody(int n_links,
m_posVarCnt(0),
m_useRK4(false),
m_useGlobalVelocities(false),
- m_internalNeedsJointFeedback(false)
+ m_internalNeedsJointFeedback(false),
+ m_kinematic_calculate_velocity(false)
{
m_cachedInertiaTopLeft.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0);
m_cachedInertiaTopRight.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -2381,7 +2382,7 @@ const char *btMultiBody::serialize(void *dataBuffer, class btSerializer *seriali
void btMultiBody::saveKinematicState(btScalar timeStep)
{
//todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities
- if (timeStep != btScalar(0.))
+ if (m_kinematic_calculate_velocity && timeStep != btScalar(0.))
{
btVector3 linearVelocity, angularVelocity;
btTransformUtil::calculateVelocity(getInterpolateBaseWorldTransform(), getBaseWorldTransform(), timeStep, linearVelocity, angularVelocity);
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
index 25112a6805..5a3efc9414 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
@@ -823,6 +823,9 @@ private:
///the m_needsJointFeedback gets updated/computed during the stepVelocitiesMultiDof and it for internal usage only
bool m_internalNeedsJointFeedback;
+
+ //If enabled, calculate the velocity based on kinematic transform changes. Currently only implemented for the base.
+ bool m_kinematic_calculate_velocity;
};
struct btMultiBodyLinkDoubleData
diff --git a/thirdparty/bullet/LinearMath/btQuickprof.cpp b/thirdparty/bullet/LinearMath/btQuickprof.cpp
index 86fd1d7812..33b51eb763 100644
--- a/thirdparty/bullet/LinearMath/btQuickprof.cpp
+++ b/thirdparty/bullet/LinearMath/btQuickprof.cpp
@@ -720,6 +720,9 @@ void btLeaveProfileZoneDefault()
#define BT_HAVE_TLS 1
#elif __linux__
#define BT_HAVE_TLS 1
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+ // TODO: At the moment disabling purposely OpenBSD, albeit tls support exists but not fully functioning
+ #define BT_HAVE_TLS 1
#endif
// __thread is broken on Andorid clang until r12b. See
diff --git a/thirdparty/bullet/LinearMath/btScalar.h b/thirdparty/bullet/LinearMath/btScalar.h
index 36b90cc944..0402146af1 100644
--- a/thirdparty/bullet/LinearMath/btScalar.h
+++ b/thirdparty/bullet/LinearMath/btScalar.h
@@ -25,7 +25,7 @@ subject to the following restrictions:
#include <float.h>
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
-#define BT_BULLET_VERSION 307
+#define BT_BULLET_VERSION 308
inline int btGetVersion()
{
diff --git a/thirdparty/bullet/LinearMath/btSerializer.h b/thirdparty/bullet/LinearMath/btSerializer.h
index 9abcf031d0..4d1c760e24 100644
--- a/thirdparty/bullet/LinearMath/btSerializer.h
+++ b/thirdparty/bullet/LinearMath/btSerializer.h
@@ -481,7 +481,7 @@ public:
buffer[9] = '3';
buffer[10] = '0';
- buffer[11] = '7';
+ buffer[11] = '8';
}
virtual void startSerialization()
diff --git a/thirdparty/doctest/doctest.h b/thirdparty/doctest/doctest.h
index acbe6cd321..7712dd6b63 100644
--- a/thirdparty/doctest/doctest.h
+++ b/thirdparty/doctest/doctest.h
@@ -48,8 +48,8 @@
#define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 4
-#define DOCTEST_VERSION_PATCH 1
-#define DOCTEST_VERSION_STR "2.4.1"
+#define DOCTEST_VERSION_PATCH 4
+#define DOCTEST_VERSION_STR "2.4.4"
#define DOCTEST_VERSION \
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
@@ -368,7 +368,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
#endif
#elif defined(DOCTEST_PLATFORM_MAC)
-#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#else
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
@@ -747,6 +747,7 @@ struct ContextOptions //!OCLINT too many fields
bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x):
bool no_path_in_filenames; // if the path to files should be removed from the output
bool no_line_numbers; // if source code line numbers should be omitted from the output
+ bool no_debug_output; // no output in the debug console when a debugger is attached
bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!!
bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!!
@@ -806,7 +807,7 @@ namespace detail {
} // namespace has_insertion_operator_impl
template<class T>
- using has_insertion_operator = has_insertion_operator_impl::check<T>;
+ using has_insertion_operator = has_insertion_operator_impl::check<const T>;
DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num);
@@ -1035,6 +1036,7 @@ namespace detail {
template <typename L, typename R>
String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op,
const DOCTEST_REF_WRAP(R) rhs) {
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
return toString(lhs) + op + toString(rhs);
}
@@ -1122,6 +1124,7 @@ namespace detail {
#define DOCTEST_COMPARISON_RETURN_TYPE bool
#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
@@ -1541,12 +1544,24 @@ namespace detail {
MessageBuilder() = delete;
~MessageBuilder();
+ // the preferred way of chaining parameters for stringification
template <typename T>
- MessageBuilder& operator<<(const T& in) {
+ MessageBuilder& operator,(const T& in) {
toStream(m_stream, in);
return *this;
}
+ // kept here just for backwards-compatibility - the comma operator should be preferred now
+ template <typename T>
+ MessageBuilder& operator<<(const T& in) { return this->operator,(in); }
+
+ // the `,` operator has the lowest operator precedence - if `<<` is used by the user then
+ // the `,` operator will be called last which is not what we want and thus the `*` operator
+ // is used first (has higher operator precedence compared to `<<`) so that we guarantee that
+ // an operator of the MessageBuilder class is called first before the rest of the parameters
+ template <typename T>
+ MessageBuilder& operator*(const T& in) { return this->operator,(in); }
+
bool log();
void react();
};
@@ -1962,38 +1977,38 @@ int registerReporter(const char* name, int priority, bool isReporter) {
DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)
// for logging
-#define DOCTEST_INFO(expression) \
+#define DOCTEST_INFO(...) \
DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \
- DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), expression)
+ DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), __VA_ARGS__)
-#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, expression) \
+#define DOCTEST_INFO_IMPL(lambda_name, mb_name, s_name, ...) \
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4626) \
auto lambda_name = [&](std::ostream* s_name) { \
doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
mb_name.m_stream = s_name; \
- mb_name << expression; \
+ mb_name * __VA_ARGS__; \
}; \
DOCTEST_MSVC_SUPPRESS_WARNING_POP \
auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(lambda_name)
-#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := " << x)
+#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
-#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, x) \
+#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \
do { \
doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \
- mb << x; \
+ mb * __VA_ARGS__; \
DOCTEST_ASSERT_LOG_AND_REACT(mb); \
} while(false)
// clang-format off
-#define DOCTEST_ADD_MESSAGE_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
-#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
-#define DOCTEST_ADD_FAIL_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x)
+#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
+#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
+#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), __VA_ARGS__)
// clang-format on
-#define DOCTEST_MESSAGE(x) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, x)
-#define DOCTEST_FAIL_CHECK(x) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, x)
-#define DOCTEST_FAIL(x) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, x)
+#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)
+#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)
+#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)
#define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility.
@@ -2036,12 +2051,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)
// clang-format off
-#define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false)
-#define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false)
-#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false)
-#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false)
-#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false)
-#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false)
+#define DOCTEST_WARN_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } while(false)
+#define DOCTEST_CHECK_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } while(false)
+#define DOCTEST_REQUIRE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } while(false)
+#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } while(false)
+#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } while(false)
+#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } while(false)
// clang-format on
#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \
@@ -2051,8 +2066,8 @@ int registerReporter(const char* name, int priority, bool isReporter) {
__LINE__, #expr, #__VA_ARGS__, message); \
try { \
DOCTEST_CAST_TO_VOID(expr) \
- } catch(const doctest::detail::remove_const< \
- doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \
+ } catch(const typename doctest::detail::remove_const< \
+ typename doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) { \
_DOCTEST_RB.translateException(); \
_DOCTEST_RB.m_threw_as = true; \
} catch(...) { _DOCTEST_RB.translateException(); } \
@@ -2103,21 +2118,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)
-#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while(false)
-#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while(false)
-#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while(false)
-#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false)
-#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false)
-#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false)
-#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false)
-#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false)
-#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false)
-#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false)
-#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false)
-#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false)
-#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while(false)
-#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while(false)
-#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while(false)
+#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } while(false)
+#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } while(false)
+#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } while(false)
+#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } while(false)
+#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } while(false)
+#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while(false)
+#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } while(false)
+#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } while(false)
+#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } while(false)
+#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } while(false)
+#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } while(false)
+#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } while(false)
+#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } while(false)
+#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } while(false)
+#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) do { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } while(false)
// clang-format on
#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS
@@ -2230,21 +2245,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
-#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
@@ -2335,14 +2350,14 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
-#define DOCTEST_INFO(x) (static_cast<void>(0))
+#define DOCTEST_INFO(...) (static_cast<void>(0))
#define DOCTEST_CAPTURE(x) (static_cast<void>(0))
-#define DOCTEST_ADD_MESSAGE_AT(file, line, x) (static_cast<void>(0))
-#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) (static_cast<void>(0))
-#define DOCTEST_ADD_FAIL_AT(file, line, x) (static_cast<void>(0))
-#define DOCTEST_MESSAGE(x) (static_cast<void>(0))
-#define DOCTEST_FAIL_CHECK(x) (static_cast<void>(0))
-#define DOCTEST_FAIL(x) (static_cast<void>(0))
+#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))
+#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))
+#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))
+#define DOCTEST_MESSAGE(...) (static_cast<void>(0))
+#define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))
+#define DOCTEST_FAIL(...) (static_cast<void>(0))
#define DOCTEST_WARN(...) (static_cast<void>(0))
#define DOCTEST_CHECK(...) (static_cast<void>(0))
@@ -2351,12 +2366,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_CHECK_FALSE(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_FALSE(...) (static_cast<void>(0))
-#define DOCTEST_WARN_MESSAGE(cond, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_MESSAGE(cond, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_MESSAGE(cond, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_MESSAGE(cond, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_MESSAGE(cond, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_MESSAGE(cond, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) (static_cast<void>(0))
#define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))
#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
@@ -2374,21 +2389,21 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
-#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
-#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
-#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) (static_cast<void>(0))
#define DOCTEST_WARN_EQ(...) (static_cast<void>(0))
#define DOCTEST_CHECK_EQ(...) (static_cast<void>(0))
@@ -2754,9 +2769,7 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#include <map>
#include <exception>
#include <stdexcept>
-#ifdef DOCTEST_CONFIG_POSIX_SIGNALS
#include <csignal>
-#endif // DOCTEST_CONFIG_POSIX_SIGNALS
#include <cfloat>
#include <cctype>
#include <cstdint>
@@ -3071,6 +3084,7 @@ String::String() {
String::~String() {
if(!isOnStack())
delete[] data.ptr;
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
}
String::String(const char* in)
@@ -3112,6 +3126,7 @@ String& String::operator+=(const String& other) {
if(total_size < len) {
// append to the current stack space
memcpy(buf + my_old_size, other.c_str(), other_size + 1);
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
setLast(last - total_size);
} else {
// alloc new chunk
@@ -3153,6 +3168,7 @@ String& String::operator+=(const String& other) {
return *this;
}
+// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
String String::operator+(const String& other) const { return String(*this) += other; }
String::String(String&& other) {
@@ -3307,6 +3323,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
// depending on the current options this will remove the path of filenames
const char* skipPathFromFilename(const char* file) {
+#ifndef DOCTEST_CONFIG_DISABLE
if(getContextOptions()->no_path_in_filenames) {
auto back = std::strrchr(file, '\\');
auto forward = std::strrchr(file, '/');
@@ -3316,6 +3333,7 @@ const char* skipPathFromFilename(const char* file) {
return forward + 1;
}
}
+#endif // DOCTEST_CONFIG_DISABLE
return file;
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP
@@ -3334,6 +3352,7 @@ IContextScope::~IContextScope() = default;
#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
String toString(char* in) { return toString(static_cast<const char*>(in)); }
+// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
String toString(bool in) { return in ? "true" : "false"; }
@@ -3406,6 +3425,7 @@ bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs
bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }
String toString(const Approx& in) {
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
return String("Approx( ") + doctest::toString(in.m_value) + " )";
}
const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }
@@ -3698,11 +3718,15 @@ namespace detail {
}
bool TestCase::operator<(const TestCase& other) const {
+ // this will be used only to differentiate between test cases - not relevant for sorting
if(m_line != other.m_line)
return m_line < other.m_line;
const int file_cmp = m_file.compare(other.m_file);
if(file_cmp != 0)
return file_cmp < 0;
+ const int name_cmp = strcmp(m_name, other.m_name);
+ if(name_cmp != 0)
+ return name_cmp < 0;
return m_template_id < other.m_template_id;
}
} // namespace detail
@@ -4009,24 +4033,40 @@ namespace {
// Windows can easily distinguish between SO and SigSegV,
// but SigInt, SigTerm, etc are handled differently.
SignalDefs signalDefs[] = {
- {EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"},
- {EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"},
- {EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"},
- {EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"},
+ {static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),
+ "SIGILL - Illegal instruction signal"},
+ {static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"},
+ {static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION),
+ "SIGSEGV - Segmentation violation signal"},
+ {static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"},
};
struct FatalConditionHandler
{
static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) {
- for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
- if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
- reportFatal(signalDefs[i].name);
- break;
+ // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the
+ // console just once no matter how many threads have crashed.
+ static std::mutex mutex;
+ static bool execute = true;
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ if(execute) {
+ bool reported = false;
+ for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
+ if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
+ reportFatal(signalDefs[i].name);
+ reported = true;
+ break;
+ }
+ }
+ if(reported == false)
+ reportFatal("Unhandled SEH exception caught");
+ if(isDebuggerActive() && !g_cs->no_breaks)
+ DOCTEST_BREAK_INTO_DEBUGGER();
}
+ execute = false;
}
- // If its not an exception we care about, pass it along.
- // This stops us from eating debugger breaks etc.
- return EXCEPTION_CONTINUE_SEARCH;
+ std::exit(EXIT_FAILURE);
}
FatalConditionHandler() {
@@ -4038,6 +4078,51 @@ namespace {
previousTop = SetUnhandledExceptionFilter(handleException);
// Pass in guarantee size to be filled
SetThreadStackGuarantee(&guaranteeSize);
+
+ // On Windows uncaught exceptions from another thread, exceptions from
+ // destructors, or calls to std::terminate are not a SEH exception
+
+ // The terminal handler gets called when:
+ // - std::terminate is called FROM THE TEST RUNNER THREAD
+ // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD
+ original_terminate_handler = std::get_terminate();
+ std::set_terminate([]() noexcept {
+ reportFatal("Terminate handler called");
+ if(isDebuggerActive() && !g_cs->no_breaks)
+ DOCTEST_BREAK_INTO_DEBUGGER();
+ std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well
+ });
+
+ // SIGABRT is raised when:
+ // - std::terminate is called FROM A DIFFERENT THREAD
+ // - an exception is thrown from a destructor FROM A DIFFERENT THREAD
+ // - an uncaught exception is thrown FROM A DIFFERENT THREAD
+ prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) noexcept {
+ if(signal == SIGABRT) {
+ reportFatal("SIGABRT - Abort (abnormal termination) signal");
+ if(isDebuggerActive() && !g_cs->no_breaks)
+ DOCTEST_BREAK_INTO_DEBUGGER();
+ std::exit(EXIT_FAILURE);
+ }
+ });
+
+ // The following settings are taken from google test, and more
+ // specifically from UnitTest::Run() inside of gtest.cc
+
+ // the user does not want to see pop-up dialogs about crashes
+ prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
+ SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
+ // This forces the abort message to go to stderr in all circumstances.
+ prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR);
+ // In the debug version, Visual Studio pops up a separate dialog
+ // offering a choice to debug the aborted program - we want to disable that.
+ prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
+ // In debug mode, the Windows CRT can crash with an assertion over invalid
+ // input (e.g. passing an invalid file descriptor). The default handling
+ // for these assertions is to pop up a dialog and wait for user input.
+ // Instead ask the CRT to dump such assertions to stderr non-interactively.
+ prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
+ prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
}
static void reset() {
@@ -4045,7 +4130,13 @@ namespace {
// Unregister handler and restore the old guarantee
SetUnhandledExceptionFilter(previousTop);
SetThreadStackGuarantee(&guaranteeSize);
- previousTop = nullptr;
+ std::set_terminate(original_terminate_handler);
+ std::signal(SIGABRT, prev_sigabrt_handler);
+ SetErrorMode(prev_error_mode_1);
+ _set_error_mode(prev_error_mode_2);
+ _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
+ _CrtSetReportMode(_CRT_ASSERT, prev_report_mode);
+ _CrtSetReportFile(_CRT_ASSERT, prev_report_file);
isSet = false;
}
}
@@ -4053,11 +4144,25 @@ namespace {
~FatalConditionHandler() { reset(); }
private:
+ static UINT prev_error_mode_1;
+ static int prev_error_mode_2;
+ static unsigned int prev_abort_behavior;
+ static int prev_report_mode;
+ static _HFILE prev_report_file;
+ static void (*prev_sigabrt_handler)(int);
+ static std::terminate_handler original_terminate_handler;
static bool isSet;
static ULONG guaranteeSize;
static LPTOP_LEVEL_EXCEPTION_FILTER previousTop;
};
+ UINT FatalConditionHandler::prev_error_mode_1;
+ int FatalConditionHandler::prev_error_mode_2;
+ unsigned int FatalConditionHandler::prev_abort_behavior;
+ int FatalConditionHandler::prev_report_mode;
+ _HFILE FatalConditionHandler::prev_report_file;
+ void (*FatalConditionHandler::prev_sigabrt_handler)(int);
+ std::terminate_handler FatalConditionHandler::original_terminate_handler;
bool FatalConditionHandler::isSet = false;
ULONG FatalConditionHandler::guaranteeSize = 0;
LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr;
@@ -4257,6 +4362,7 @@ namespace detail {
// ###################################################################################
DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp);
DOCTEST_ASSERT_IN_TESTS(result.m_decomp);
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
}
MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) {
@@ -4979,7 +5085,6 @@ namespace {
}
// TODO:
- // - log_contexts()
// - log_message()
// - respond to queries
// - honor remaining options
@@ -4993,7 +5098,6 @@ namespace {
struct JUnitTestCaseData
{
-DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") // gmtime
static std::string getCurrentTimestamp() {
// Beware, this is not reentrant because of backward compatibility issues
// Also, UTC only, again because of backward compatibility (%z is C++11)
@@ -5001,16 +5105,19 @@ DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") // gmtime
std::time(&rawtime);
auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
- std::tm* timeInfo;
- timeInfo = std::gmtime(&rawtime);
+ std::tm timeInfo;
+#ifdef DOCTEST_PLATFORM_WINDOWS
+ gmtime_s(&timeInfo, &rawtime);
+#else // DOCTEST_PLATFORM_WINDOWS
+ gmtime_r(&rawtime, &timeInfo);
+#endif // DOCTEST_PLATFORM_WINDOWS
char timeStamp[timeStampSize];
const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
- std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
+ std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
return std::string(timeStamp);
}
-DOCTEST_CLANG_SUPPRESS_WARNING_POP
struct JUnitTestMessage
{
@@ -5175,12 +5282,27 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP
<< line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl;
fulltext_log_assert_to_stream(os, rb);
+ log_contexts(os);
testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str());
}
void log_message(const MessageData&) override {}
void test_case_skipped(const TestCaseData&) override {}
+
+ void log_contexts(std::ostringstream& s) {
+ int num_contexts = get_num_active_contexts();
+ if(num_contexts) {
+ auto contexts = get_active_contexts();
+
+ s << " logged: ";
+ for(int i = 0; i < num_contexts; ++i) {
+ s << (i == 0 ? "" : " ");
+ contexts[i]->stringify(&s);
+ s << std::endl;
+ }
+ }
+ }
};
DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter);
@@ -5894,6 +6016,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC));
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false);
+ DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false);
DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false);
// clang-format on
@@ -5951,6 +6074,7 @@ void Context::clearFilters() {
// allows the user to override procedurally the int/bool options from the command line
void Context::setOption(const char* option, int value) {
setOption(option, toString(value).c_str());
+ // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
}
// allows the user to override procedurally the string options from the command line
@@ -6026,7 +6150,7 @@ int Context::run() {
p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs));
#ifdef DOCTEST_PLATFORM_WINDOWS
- if(isDebuggerActive())
+ if(isDebuggerActive() && p->no_debug_output == false)
p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs));
#endif // DOCTEST_PLATFORM_WINDOWS
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
index 24d36647d9..77f8004b80 100644
--- a/thirdparty/enet/enet/enet.h
+++ b/thirdparty/enet/enet/enet.h
@@ -31,7 +31,7 @@ extern "C"
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
-#define ENET_VERSION_PATCH 15
+#define ENET_VERSION_PATCH 17
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
@@ -323,12 +323,10 @@ typedef struct _ENetPeer
ENetList acknowledgements;
ENetList sentReliableCommands;
ENetList sentUnreliableCommands;
- ENetList outgoingReliableCommands;
- ENetList outgoingUnreliableCommands;
+ ENetList outgoingCommands;
ENetList dispatchedCommands;
enet_uint16 flags;
- enet_uint8 roundTripTimeRemainder;
- enet_uint8 roundTripTimeVarianceRemainder;
+ enet_uint16 reserved;
enet_uint16 incomingUnsequencedGroup;
enet_uint16 outgoingUnsequencedGroup;
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
@@ -604,8 +602,8 @@ extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetO
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, const void *, size_t, enet_uint32, enet_uint32);
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
-extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
-extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
+extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
+extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
extern void enet_peer_on_connect (ENetPeer *);
extern void enet_peer_on_disconnect (ENetPeer *);
diff --git a/thirdparty/enet/enet/godot.h b/thirdparty/enet/enet/godot.h
index 296b92763d..2486de6b04 100644
--- a/thirdparty/enet/enet/godot.h
+++ b/thirdparty/enet/enet/godot.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/thirdparty/enet/godot.cpp b/thirdparty/enet/godot.cpp
index 55b160d752..73fa3c62a2 100644
--- a/thirdparty/enet/godot.cpp
+++ b/thirdparty/enet/godot.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/thirdparty/enet/host.c b/thirdparty/enet/host.c
index fc4da4ca67..21ab27e247 100644
--- a/thirdparty/enet/host.c
+++ b/thirdparty/enet/host.c
@@ -124,8 +124,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
enet_list_clear (& currentPeer -> acknowledgements);
enet_list_clear (& currentPeer -> sentReliableCommands);
enet_list_clear (& currentPeer -> sentUnreliableCommands);
- enet_list_clear (& currentPeer -> outgoingReliableCommands);
- enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
+ enet_list_clear (& currentPeer -> outgoingCommands);
enet_list_clear (& currentPeer -> dispatchedCommands);
enet_peer_reset (currentPeer);
diff --git a/thirdparty/enet/patches/godot.patch b/thirdparty/enet/patches/godot_socket.patch
index c8b4a5225d..364b3536be 100644
--- a/thirdparty/enet/patches/godot.patch
+++ b/thirdparty/enet/patches/godot_socket.patch
@@ -1,5 +1,5 @@
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
-index 54d91b5603..24d36647d9 100644
+index fc45cbd0c9..77f8004b80 100644
--- a/thirdparty/enet/enet/enet.h
+++ b/thirdparty/enet/enet/enet.h
@@ -10,13 +10,19 @@ extern "C"
@@ -38,7 +38,7 @@ index 54d91b5603..24d36647d9 100644
/**
* Packet flag bit constants.
-@@ -606,6 +616,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t,
+@@ -604,6 +614,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t,
extern size_t enet_protocol_command_size (enet_uint8);
@@ -50,7 +50,7 @@ index 54d91b5603..24d36647d9 100644
}
#endif
diff --git a/thirdparty/enet/host.c b/thirdparty/enet/host.c
-index 3be6c0922c..fc4da4ca67 100644
+index 3b2180f7fd..21ab27e247 100644
--- a/thirdparty/enet/host.c
+++ b/thirdparty/enet/host.c
@@ -87,7 +87,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
@@ -63,10 +63,10 @@ index 3be6c0922c..fc4da4ca67 100644
host -> receivedData = NULL;
host -> receivedDataLength = 0;
diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c
-index 0a60253173..fefc0e6f0a 100644
+index 9d654f1d96..d7fe80f117 100644
--- a/thirdparty/enet/protocol.c
+++ b/thirdparty/enet/protocol.c
-@@ -307,7 +307,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
+@@ -309,7 +309,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
}
else
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
@@ -75,7 +75,7 @@ index 0a60253173..fefc0e6f0a 100644
{
if (currentPeer -> address.port == host -> receivedAddress.port &&
currentPeer -> connectID == command -> connect.connectID)
-@@ -1027,9 +1027,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
+@@ -1031,9 +1031,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
@@ -87,7 +87,7 @@ index 0a60253173..fefc0e6f0a 100644
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
sessionID != peer -> incomingSessionID))
return 0;
-@@ -1071,7 +1070,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
+@@ -1075,7 +1074,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer != NULL)
{
diff --git a/thirdparty/enet/peer.c b/thirdparty/enet/peer.c
index 1278b85a80..9370ef4be1 100644
--- a/thirdparty/enet/peer.c
+++ b/thirdparty/enet/peer.c
@@ -76,7 +76,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
return 1;
}
else
- if (rtt >= peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
+ if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
{
if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
peer -> packetThrottle -= peer -> packetThrottleDeceleration;
@@ -268,7 +268,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
}
static void
-enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand)
+enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand, ENetIncomingCommand * excludeCommand)
{
ENetListIterator currentCommand;
@@ -278,6 +278,9 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
currentCommand = enet_list_next (currentCommand);
+ if (incomingCommand == excludeCommand)
+ continue;
+
enet_list_remove (& incomingCommand -> incomingCommandList);
if (incomingCommand -> packet != NULL)
@@ -298,7 +301,7 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
static void
enet_peer_reset_incoming_commands (ENetList * queue)
{
- enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue));
+ enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue), NULL);
}
void
@@ -318,8 +321,7 @@ enet_peer_reset_queues (ENetPeer * peer)
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
- enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
- enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
+ enet_peer_reset_outgoing_commands (& peer -> outgoingCommands);
enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
if (peer -> channels != NULL && peer -> channelCount > 0)
@@ -419,8 +421,6 @@ enet_peer_reset (ENetPeer * peer)
peer -> eventData = 0;
peer -> totalWaitingData = 0;
peer -> flags = 0;
- peer -> roundTripTimeRemainder = 0;
- peer -> roundTripTimeVarianceRemainder = 0;
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
@@ -573,8 +573,7 @@ void
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
{
if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
- ! (enet_list_empty (& peer -> outgoingReliableCommands) &&
- enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ ! (enet_list_empty (& peer -> outgoingCommands) &&
enet_list_empty (& peer -> sentReliableCommands)))
{
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
@@ -676,10 +675,7 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
break;
}
- if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
- enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
- else
- enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
+ enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand);
}
ENetOutgoingCommand *
@@ -702,7 +698,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
}
void
-enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
+enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand)
{
ENetListIterator droppedCommand, startCommand, currentCommand;
@@ -781,11 +777,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
droppedCommand = currentCommand;
}
- enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand);
+ enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand, queuedCommand);
}
void
-enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
+enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand)
{
ENetListIterator currentCommand;
@@ -820,7 +816,7 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
}
if (! enet_list_empty (& channel -> incomingUnreliableCommands))
- enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel, queuedCommand);
}
ENetIncomingCommand *
@@ -978,11 +974,11 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
{
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
- enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_reliable_commands (peer, channel, incomingCommand);
break;
default:
- enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel, incomingCommand);
break;
}
diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c
index fefc0e6f0a..d7fe80f117 100644
--- a/thirdparty/enet/protocol.c
+++ b/thirdparty/enet/protocol.c
@@ -188,8 +188,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
} while (! enet_list_empty (& peer -> sentUnreliableCommands));
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
- enet_list_empty (& peer -> outgoingReliableCommands) &&
- enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ enet_list_empty (& peer -> outgoingCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
enet_peer_disconnect (peer, peer -> eventData);
}
@@ -215,12 +214,15 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
{
- for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
- currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
+ for (currentCommand = enet_list_begin (& peer -> outgoingCommands);
+ currentCommand != enet_list_end (& peer -> outgoingCommands);
currentCommand = enet_list_next (currentCommand))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+ if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
+ continue;
+
if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
@@ -228,7 +230,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
break;
}
- if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
+ if (currentCommand == enet_list_end (& peer -> outgoingCommands))
return ENET_PROTOCOL_COMMAND_NONE;
wasSent = 0;
@@ -623,7 +625,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
fragmentLength);
if (startCommand -> fragmentsRemaining <= 0)
- enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_reliable_commands (peer, channel, NULL);
}
return 0;
@@ -741,7 +743,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
fragmentLength);
if (startCommand -> fragmentsRemaining <= 0)
- enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel, NULL);
}
return 0;
@@ -856,19 +858,22 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
if (peer -> lastReceiveTime > 0)
{
- enet_uint32 accumRoundTripTime = (peer -> roundTripTime << 8) + peer -> roundTripTimeRemainder;
- enet_uint32 accumRoundTripTimeVariance = (peer -> roundTripTimeVariance << 8) + peer -> roundTripTimeVarianceRemainder;
-
enet_peer_throttle (peer, roundTripTime);
- roundTripTime <<= 8;
- accumRoundTripTimeVariance = (accumRoundTripTimeVariance * 3 + ENET_DIFFERENCE (roundTripTime, accumRoundTripTime)) / 4;
- accumRoundTripTime = (accumRoundTripTime * 7 + roundTripTime) / 8;
+ peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
- peer -> roundTripTime = accumRoundTripTime >> 8;
- peer -> roundTripTimeRemainder = accumRoundTripTime & 0xFF;
- peer -> roundTripTimeVariance = accumRoundTripTimeVariance >> 8;
- peer -> roundTripTimeVarianceRemainder = accumRoundTripTimeVariance & 0xFF;
+ if (roundTripTime >= peer -> roundTripTime)
+ {
+ enet_uint32 diff = roundTripTime - peer -> roundTripTime;
+ peer -> roundTripTimeVariance += diff / 4;
+ peer -> roundTripTime += diff / 8;
+ }
+ else
+ {
+ enet_uint32 diff = peer -> roundTripTime - roundTripTime;
+ peer -> roundTripTimeVariance += diff / 4;
+ peer -> roundTripTime -= diff / 8;
+ }
}
else
{
@@ -879,14 +884,14 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
if (peer -> roundTripTime < peer -> lowestRoundTripTime)
peer -> lowestRoundTripTime = peer -> roundTripTime;
- if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
+ if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
if (peer -> packetThrottleEpoch == 0 ||
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
{
peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
- peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 2);
+ peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1);
peer -> lowestRoundTripTime = peer -> roundTripTime;
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
peer -> packetThrottleEpoch = host -> serviceTime;
@@ -916,8 +921,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
break;
case ENET_PEER_STATE_DISCONNECT_LATER:
- if (enet_list_empty (& peer -> outgoingReliableCommands) &&
- enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ if (enet_list_empty (& peer -> outgoingCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
enet_peer_disconnect (peer, peer -> eventData);
break;
@@ -1325,108 +1329,6 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
host -> bufferCount = buffer - host -> buffers;
}
-static void
-enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
-{
- ENetProtocol * command = & host -> commands [host -> commandCount];
- ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
- ENetOutgoingCommand * outgoingCommand;
- ENetListIterator currentCommand;
-
- currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands);
-
- while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
- {
- size_t commandSize;
-
- outgoingCommand = (ENetOutgoingCommand *) currentCommand;
- commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
-
- if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
- buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
- peer -> mtu - host -> packetSize < commandSize ||
- (outgoingCommand -> packet != NULL &&
- peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength))
- {
- host -> continueSending = 1;
-
- break;
- }
-
- currentCommand = enet_list_next (currentCommand);
-
- if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
- {
- peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
- peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
-
- if (peer -> packetThrottleCounter > peer -> packetThrottle)
- {
- enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
- unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
- for (;;)
- {
- -- outgoingCommand -> packet -> referenceCount;
-
- if (outgoingCommand -> packet -> referenceCount == 0)
- enet_packet_destroy (outgoingCommand -> packet);
-
- enet_list_remove (& outgoingCommand -> outgoingCommandList);
- enet_free (outgoingCommand);
-
- if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands))
- break;
-
- outgoingCommand = (ENetOutgoingCommand *) currentCommand;
- if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
- outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
- break;
-
- currentCommand = enet_list_next (currentCommand);
- }
-
- continue;
- }
- }
-
- buffer -> data = command;
- buffer -> dataLength = commandSize;
-
- host -> packetSize += buffer -> dataLength;
-
- * command = outgoingCommand -> command;
-
- enet_list_remove (& outgoingCommand -> outgoingCommandList);
-
- if (outgoingCommand -> packet != NULL)
- {
- ++ buffer;
-
- buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
- buffer -> dataLength = outgoingCommand -> fragmentLength;
-
- host -> packetSize += buffer -> dataLength;
-
- enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
- }
- else
- enet_free (outgoingCommand);
-
- ++ command;
- ++ buffer;
- }
-
- host -> commandCount = command - host -> commands;
- host -> bufferCount = buffer - host -> buffers;
-
- if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
- enet_list_empty (& peer -> outgoingReliableCommands) &&
- enet_list_empty (& peer -> outgoingUnreliableCommands) &&
- enet_list_empty (& peer -> sentReliableCommands) &&
- enet_list_empty (& peer -> sentUnreliableCommands))
- enet_peer_disconnect (peer, peer -> eventData);
-}
-
static int
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
{
@@ -1434,7 +1336,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
ENetListIterator currentCommand, insertPosition;
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
- insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
+ insertPosition = enet_list_begin (& peer -> outgoingCommands);
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
{
@@ -1481,7 +1383,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
}
static int
-enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
+enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer)
{
ENetProtocol * command = & host -> commands [host -> commandCount];
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
@@ -1492,49 +1394,52 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
size_t commandSize;
int windowExceeded = 0, windowWrap = 0, canPing = 1;
- currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
+ currentCommand = enet_list_begin (& peer -> outgoingCommands);
- while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
+ while (currentCommand != enet_list_end (& peer -> outgoingCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
- channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
- reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
- if (channel != NULL)
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{
- if (! windowWrap &&
- outgoingCommand -> sendAttempts < 1 &&
- ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
- (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
- channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
- (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
- windowWrap = 1;
- if (windowWrap)
+ channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
+ reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+ if (channel != NULL)
{
- currentCommand = enet_list_next (currentCommand);
+ if (! windowWrap &&
+ outgoingCommand -> sendAttempts < 1 &&
+ ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
+ (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
+ channel -> usedReliableWindows & ((((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) << reliableWindow) |
+ (((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
+ windowWrap = 1;
+ if (windowWrap)
+ {
+ currentCommand = enet_list_next (currentCommand);
- continue;
+ continue;
+ }
}
- }
- if (outgoingCommand -> packet != NULL)
- {
- if (! windowExceeded)
+ if (outgoingCommand -> packet != NULL)
{
- enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
+ if (! windowExceeded)
+ {
+ enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
- if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
- windowExceeded = 1;
- }
- if (windowExceeded)
- {
- currentCommand = enet_list_next (currentCommand);
+ if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
+ windowExceeded = 1;
+ }
+ if (windowExceeded)
+ {
+ currentCommand = enet_list_next (currentCommand);
- continue;
+ continue;
+ }
}
- }
- canPing = 0;
+ canPing = 0;
+ }
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
@@ -1550,33 +1455,80 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
currentCommand = enet_list_next (currentCommand);
- if (channel != NULL && outgoingCommand -> sendAttempts < 1)
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{
- channel -> usedReliableWindows |= 1 << reliableWindow;
- ++ channel -> reliableWindows [reliableWindow];
- }
+ if (channel != NULL && outgoingCommand -> sendAttempts < 1)
+ {
+ channel -> usedReliableWindows |= 1 << reliableWindow;
+ ++ channel -> reliableWindows [reliableWindow];
+ }
- ++ outgoingCommand -> sendAttempts;
+ ++ outgoingCommand -> sendAttempts;
- if (outgoingCommand -> roundTripTimeout == 0)
- {
- outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
- outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
+ if (outgoingCommand -> roundTripTimeout == 0)
+ {
+ outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
+ outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
+ }
+
+ if (enet_list_empty (& peer -> sentReliableCommands))
+ peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
+
+ enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
+ enet_list_remove (& outgoingCommand -> outgoingCommandList));
+
+ outgoingCommand -> sentTime = host -> serviceTime;
+
+ host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
+
+ peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
}
+ else
+ {
+ if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
+ {
+ peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
+ peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
+
+ if (peer -> packetThrottleCounter > peer -> packetThrottle)
+ {
+ enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
+ unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
+ for (;;)
+ {
+ -- outgoingCommand -> packet -> referenceCount;
+
+ if (outgoingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (outgoingCommand -> packet);
- if (enet_list_empty (& peer -> sentReliableCommands))
- peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
+ enet_list_remove (& outgoingCommand -> outgoingCommandList);
+ enet_free (outgoingCommand);
- enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
- enet_list_remove (& outgoingCommand -> outgoingCommandList));
+ if (currentCommand == enet_list_end (& peer -> outgoingCommands))
+ break;
- outgoingCommand -> sentTime = host -> serviceTime;
+ outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+ if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
+ outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
+ break;
+
+ currentCommand = enet_list_next (currentCommand);
+ }
+
+ continue;
+ }
+ }
+
+ enet_list_remove (& outgoingCommand -> outgoingCommandList);
+
+ if (outgoingCommand -> packet != NULL)
+ enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
+ }
buffer -> data = command;
buffer -> dataLength = commandSize;
host -> packetSize += buffer -> dataLength;
- host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
* command = outgoingCommand -> command;
@@ -1588,9 +1540,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
buffer -> dataLength = outgoingCommand -> fragmentLength;
host -> packetSize += outgoingCommand -> fragmentLength;
-
- peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
}
+ else
+ if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
+ enet_free (outgoingCommand);
++ peer -> packetsSent;
@@ -1601,6 +1554,12 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
host -> commandCount = command - host -> commands;
host -> bufferCount = buffer - host -> buffers;
+ if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
+ enet_list_empty (& peer -> outgoingCommands) &&
+ enet_list_empty (& peer -> sentReliableCommands) &&
+ enet_list_empty (& peer -> sentUnreliableCommands))
+ enet_peer_disconnect (peer, peer -> eventData);
+
return canPing;
}
@@ -1644,18 +1603,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
continue;
}
- if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
- enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
+ if ((enet_list_empty (& currentPeer -> outgoingCommands) ||
+ enet_protocol_check_outgoing_commands (host, currentPeer)) &&
enet_list_empty (& currentPeer -> sentReliableCommands) &&
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval &&
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
{
enet_peer_ping (currentPeer);
- enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
+ enet_protocol_check_outgoing_commands (host, currentPeer);
}
-
- if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
- enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
if (host -> commandCount == 0)
continue;
@@ -1669,7 +1625,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
#ifdef ENET_DEBUG
- printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
+ printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
#endif
currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;
diff --git a/thirdparty/harfbuzz/NEWS b/thirdparty/harfbuzz/NEWS
index f211a3781c..f09c2fafd1 100644
--- a/thirdparty/harfbuzz/NEWS
+++ b/thirdparty/harfbuzz/NEWS
@@ -1,3 +1,33 @@
+Overview of changes leading to 2.7.4
+Sunday, December 27, 2020
+====================================
+- Fix missing --enable-introspection configure option from previous release
+ tarball.
+- Documentation updates.
+
+Overview of changes leading to 2.7.3
+Wednesday, December 23, 2020
+====================================
+- Update USE shaper to 2020-08-13 specification, and other improvements.
+- Don’t disable liga feature in myanmar shaper, to match Uniscribe.
+- Improvements to language and script tags handling.
+- Update language system tag registry to OpenType 1.8.4
+- Support for serializing and deserializing Unicode buffers. Serialized buffers
+ are now delimited with `<>` or `[]` based on whether it is a Unicode or
+ glyphs buffer.
+- Increase buffer work limits to handle fonts with many complex lookups.
+- Handle more shaping operations in trace output.
+- Memory access fixes.
+- More OOM fixes.
+- Improved documentation.
+- Build system improvements.
+- New API:
++hb_buffer_has_positions()
++hb_buffer_serialize()
++hb_buffer_serialize_unicode()
++hb_buffer_deserialize_unicode()
+
+
Overview of changes leading to 2.7.2
Saturday, August 29, 2020
====================================
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout.cc b/thirdparty/harfbuzz/src/hb-aat-layout.cc
index fac510e9e6..74ebaa64ec 100644
--- a/thirdparty/harfbuzz/src/hb-aat-layout.cc
+++ b/thirdparty/harfbuzz/src/hb-aat-layout.cc
@@ -79,13 +79,18 @@ AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
* @short_description: Apple Advanced Typography Layout
* @include: hb-aat.h
*
- * Functions for querying OpenType Layout features in the font face.
+ * Functions for querying AAT Layout features in the font face.
+ *
+ * HarfBuzz supports all of the AAT tables used to implement shaping. Other
+ * AAT tables and their associated features are not supported.
**/
#if !defined(HB_NO_AAT) || defined(HAVE_CORETEXT)
-/* Table data courtesy of Apple. Converted from mnemonics to integers
+/* Mapping from OpenType feature tags to AAT feature names and selectors.
+ *
+ * Table data courtesy of Apple. Converted from mnemonics to integers
* when moving to this file. */
static const hb_aat_feature_mapping_t feature_mappings[] =
{
@@ -167,6 +172,17 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
{HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF},
};
+/**
+ * hb_aat_layout_find_feature_mapping:
+ * @tag: The requested #hb_tag_t feature tag
+ *
+ * Fetches the AAT feature-and-selector combination that corresponds
+ * to a given OpenType feature tag.
+ *
+ * Return value: the AAT features and selectors corresponding to the
+ * OpenType feature tag queried
+ *
+ **/
const hb_aat_feature_mapping_t *
hb_aat_layout_find_feature_mapping (hb_tag_t tag)
{
@@ -202,11 +218,17 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
}
-/*
+/**
* hb_aat_layout_has_substitution:
- * @face:
+ * @face: #hb_face_t to work upon
+ *
+ * Tests whether the specified face includes any substitutions in the
+ * `morx` or `mort` tables.
+ *
+ * <note>Note: does not examine the `GSUB` table.</note>
+ *
+ * Return value: true if data found, false otherwise
*
- * Returns:
* Since: 2.3.0
*/
hb_bool_t
@@ -263,11 +285,17 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
}
-/*
+/**
* hb_aat_layout_has_positioning:
- * @face:
+ * @face: #hb_face_t to work upon
+ *
+ * Tests whether the specified face includes any positioning information
+ * in the `kerx` table.
+ *
+ * <note>Note: does not examine the `GPOS` table.</note>
+ *
+ * Return value: true if data found, false otherwise
*
- * Returns:
* Since: 2.3.0
*/
hb_bool_t
@@ -290,11 +318,15 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
}
-/*
+/**
* hb_aat_layout_has_tracking:
- * @face:
+ * @face:: #hb_face_t to work upon
+ *
+ * Tests whether the specified face includes any tracking information
+ * in the `trak` table.
+ *
+ * Return value: true if data found, false otherwise
*
- * Returns:
* Since: 2.3.0
*/
hb_bool_t
@@ -316,10 +348,13 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
/**
* hb_aat_layout_get_feature_types:
- * @face: a face object
- * @start_offset: iteration's start offset
- * @feature_count:(inout) (allow-none): buffer size as input, filled size as output
- * @features: (out caller-allocates) (array length=feature_count): features buffer
+ * @face: #hb_face_t to work upon
+ * @start_offset: offset of the first feature type to retrieve
+ * @feature_count: (inout) (allow-none): Input = the maximum number of feature types to return;
+ * Output = the actual number of feature types returned (may be zero)
+ * @features: (out caller-allocates) (array length=feature_count): Array of feature types found
+ *
+ * Fetches a list of the AAT feature types included in the specified face.
*
* Return value: Number of all available feature types.
*
@@ -336,10 +371,12 @@ hb_aat_layout_get_feature_types (hb_face_t *face,
/**
* hb_aat_layout_feature_type_get_name_id:
- * @face: a face object
- * @feature_type: feature id
+ * @face: #hb_face_t to work upon
+ * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type
*
- * Return value: Name ID index
+ * Fetches the name ID of the specified feature type in the face's `name` table.
+ *
+ * Return value: Name ID of the requested feature type
*
* Since: 2.2.0
*/
@@ -352,18 +389,22 @@ hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
/**
* hb_aat_layout_feature_type_get_selectors:
- * @face: a face object
- * @feature_type: feature id
- * @start_offset: iteration's start offset
- * @selector_count: (inout) (allow-none): buffer size as input, filled size as output
- * @selectors: (out caller-allocates) (array length=selector_count): settings buffer
- * @default_index: (out) (allow-none): index of default selector if any
+ * @face: #hb_face_t to work upon
+ * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type
+ * @start_offset: offset of the first feature type to retrieve
+ * @selector_count: (inout) (allow-none): Input = the maximum number of selectors to return;
+ * Output = the actual number of selectors returned (may be zero)
+ * @selectors: (out caller-allocates) (array length=selector_count): A buffer pointer.
+ * The selectors available for the feature type queries.
+ * @default_index: (out) (allow-none): The index of the feature's default selector, if any
+ *
+ * Fetches a list of the selectors available for the specified feature in the given face.
*
* If upon return, @default_index is set to #HB_AAT_LAYOUT_NO_SELECTOR_INDEX, then
* the feature type is non-exclusive. Otherwise, @default_index is the index of
* the selector that is selected by default.
*
- * Return value: Number of all available feature selectors.
+ * Return value: Number of all available feature selectors
*
* Since: 2.2.0
*/
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout.h b/thirdparty/harfbuzz/src/hb-aat-layout.h
index b617e8b703..dc1bf96573 100644
--- a/thirdparty/harfbuzz/src/hb-aat-layout.h
+++ b/thirdparty/harfbuzz/src/hb-aat-layout.h
@@ -37,7 +37,48 @@ HB_BEGIN_DECLS
/**
* hb_aat_layout_feature_type_t:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_INVALID: Initial, unset feature type
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE:
+ * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE:
*
+ * The possible feature types defined for AAT shaping.
*
* Since: 2.2.0
*/
@@ -85,12 +126,265 @@ typedef enum
HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39,
HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103,
+ /*< private >*/
_HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_aat_layout_feature_type_t;
/**
* hb_aat_layout_feature_selector_t:
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID: Initial, unset feature selector
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE: Deprecated
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS: Deprecated
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE: Deprecated
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS: Deprecated
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS: Deprecated
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS: Deprecated
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
+ * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
*
+ * The selectors defined for specifying AAT feature settings.
*
* Since: 2.2.0
*/
@@ -424,6 +718,7 @@ typedef enum
HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2,
HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3,
+ /*< private >*/
_HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_aat_layout_feature_selector_t;
@@ -437,8 +732,7 @@ HB_EXTERN hb_ot_name_id_t
hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
hb_aat_layout_feature_type_t feature_type);
-typedef struct hb_aat_layout_feature_selector_info_t
-{
+typedef struct hb_aat_layout_feature_selector_info_t {
hb_ot_name_id_t name_id;
hb_aat_layout_feature_selector_t enable;
hb_aat_layout_feature_selector_t disable;
@@ -446,6 +740,13 @@ typedef struct hb_aat_layout_feature_selector_info_t
unsigned int reserved;
} hb_aat_layout_feature_selector_info_t;
+/**
+ * HB_AAT_LAYOUT_NO_SELECTOR_INDEX
+ *
+ * Used when getting or setting AAT feature selectors. Indicates that
+ * there is no selector index corresponding to the selector of interest.
+ *
+ */
#define HB_AAT_LAYOUT_NO_SELECTOR_INDEX 0xFFFFu
HB_EXTERN unsigned int
diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh
index 30b5812e12..98de61f3e8 100644
--- a/thirdparty/harfbuzz/src/hb-algs.hh
+++ b/thirdparty/harfbuzz/src/hb-algs.hh
@@ -350,14 +350,14 @@ struct
{
template <typename T, typename T2> constexpr auto
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
- (hb_forward<T> (a) <= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
+ (a <= b ? hb_forward<T> (a) : hb_forward<T2> (b))
}
HB_FUNCOBJ (hb_min);
struct
{
template <typename T, typename T2> constexpr auto
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
- (hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
+ (a >= b ? hb_forward<T> (a) : hb_forward<T2> (b))
}
HB_FUNCOBJ (hb_max);
struct
diff --git a/thirdparty/harfbuzz/src/hb-blob.cc b/thirdparty/harfbuzz/src/hb-blob.cc
index 94ed50fd3c..e340bc346d 100644
--- a/thirdparty/harfbuzz/src/hb-blob.cc
+++ b/thirdparty/harfbuzz/src/hb-blob.cc
@@ -58,7 +58,7 @@
* @length: Length of @data in bytes.
* @mode: Memory mode for @data.
* @user_data: Data parameter to pass to @destroy.
- * @destroy: Callback to call when @data is not needed anymore.
+ * @destroy: (optional): Callback to call when @data is not needed anymore.
*
* Creates a new "blob" object wrapping @data. The @mode parameter is used
* to negotiate ownership and lifecycle of @data.
@@ -156,7 +156,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
*
* Makes a writable copy of @blob.
*
- * Return value: New blob, or nullptr if allocation failed.
+ * Return value: The new blob, or nullptr if allocation failed
*
* Since: 1.8.0
**/
@@ -182,7 +182,7 @@ hb_blob_copy_writable_or_fail (hb_blob_t *blob)
*
* See TODO:link object types for more information.
*
- * Return value: (transfer full): the empty blob.
+ * Return value: (transfer full): The empty blob.
*
* Since: 0.9.2
**/
@@ -234,13 +234,15 @@ hb_blob_destroy (hb_blob_t *blob)
/**
* hb_blob_set_user_data: (skip)
- * @blob: a blob.
- * @key: key for data to set.
- * @data: data to set.
- * @destroy: callback to call when @data is not needed anymore.
- * @replace: whether to replace an existing data with the same key.
+ * @blob: An #hb_blob_t
+ * @key: The user-data key to set
+ * @data: A pointer to the user data to set
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
+ *
+ * Attaches a user-data key/data pair to the specified blob.
*
- * Return value:
+ * Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@@ -256,12 +258,13 @@ hb_blob_set_user_data (hb_blob_t *blob,
/**
* hb_blob_get_user_data: (skip)
- * @blob: a blob.
- * @key: key for data to get.
+ * @blob: a blob
+ * @key: The user-data key to query
*
+ * Fetches the user data associated with the specified key,
+ * attached to the specified font-functions structure.
*
- *
- * Return value: (transfer none):
+ * Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@@ -275,9 +278,9 @@ hb_blob_get_user_data (hb_blob_t *blob,
/**
* hb_blob_make_immutable:
- * @blob: a blob.
- *
+ * @blob: a blob
*
+ * Makes a blob immutable.
*
* Since: 0.9.2
**/
@@ -294,9 +297,9 @@ hb_blob_make_immutable (hb_blob_t *blob)
* hb_blob_is_immutable:
* @blob: a blob.
*
+ * Tests whether a blob is immutable.
*
- *
- * Return value: TODO
+ * Return value: %true if @blob is immutable, false otherwise
*
* Since: 0.9.2
**/
@@ -311,9 +314,9 @@ hb_blob_is_immutable (hb_blob_t *blob)
* hb_blob_get_length:
* @blob: a blob.
*
+ * Fetches the length of a blob's data.
*
- *
- * Return value: the length of blob data in bytes.
+ * Return value: the length of @blob data in bytes.
*
* Since: 0.9.2
**/
@@ -326,11 +329,11 @@ hb_blob_get_length (hb_blob_t *blob)
/**
* hb_blob_get_data:
* @blob: a blob.
- * @length: (out):
+ * @length: (out): The length in bytes of the data retrieved
*
+ * Fetches the data from a blob.
*
- *
- * Returns: (transfer none) (array length=length):
+ * Returns: (transfer none) (array length=length): the byte data of @blob.
*
* Since: 0.9.2
**/
@@ -558,9 +561,12 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file)
/**
* hb_blob_create_from_file:
- * @file_name: font filename.
+ * @file_name: A font filename
+ *
+ * Creates a new blob containing the data from the
+ * specified binary font file.
*
- * Returns: A hb_blob_t pointer with the content of the file
+ * Returns: An #hb_blob_t pointer with the content of the file
*
* Since: 1.7.7
**/
diff --git a/thirdparty/harfbuzz/src/hb-blob.h b/thirdparty/harfbuzz/src/hb-blob.h
index f80e9af2d9..00e41f3ce3 100644
--- a/thirdparty/harfbuzz/src/hb-blob.h
+++ b/thirdparty/harfbuzz/src/hb-blob.h
@@ -36,25 +36,34 @@
HB_BEGIN_DECLS
-/*
- * Note re various memory-modes:
+/**
+ * hb_memory_mode_t:
+ * @HB_MEMORY_MODE_DUPLICATE
+ * @HB_MEMORY_MODE_READONLY
+ * @HB_MEMORY_MODE_WRITABLE
+ * @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
+ *
+ * Data type holding the memory modes available to
+ * client programs.
+ *
+ * Regarding these various memory-modes:
*
* - In no case shall the HarfBuzz client modify memory
* that is passed to HarfBuzz in a blob. If there is
- * any such possibility, MODE_DUPLICATE should be used
+ * any such possibility, @HB_MEMORY_MODE_DUPLICATE should be used
* such that HarfBuzz makes a copy immediately,
*
- * - Use MODE_READONLY otherwise, unless you really really
+ * - Use @HB_MEMORY_MODE_READONLY otherwise, unless you really really
* really know what you are doing,
*
- * - MODE_WRITABLE is appropriate if you really made a
+ * - @HB_MEMORY_MODE_WRITABLE is appropriate if you really made a
* copy of data solely for the purpose of passing to
* HarfBuzz and doing that just once (no reuse!),
*
- * - If the font is mmap()ed, it's ok to use
- * READONLY_MAY_MAKE_WRITABLE, however, using that mode
- * correctly is very tricky. Use MODE_READONLY instead.
- */
+ * - If the font is mmap()ed, it's okay to use
+ * @HB_MEMORY_READONLY_MAY_MAKE_WRITABLE, however, using that mode
+ * correctly is very tricky. Use @HB_MEMORY_MODE_READONLY instead.
+ **/
typedef enum {
HB_MEMORY_MODE_DUPLICATE,
HB_MEMORY_MODE_READONLY,
@@ -62,6 +71,14 @@ typedef enum {
HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
} hb_memory_mode_t;
+/**
+ * hb_blob_t:
+ *
+ * Data type for blobs. A blob wraps a chunk of binary
+ * data and facilitates its lifecycle management between
+ * a client program and HarfBuzz.
+ *
+ **/
typedef struct hb_blob_t hb_blob_t;
HB_EXTERN hb_blob_t *
diff --git a/thirdparty/harfbuzz/src/hb-blob.hh b/thirdparty/harfbuzz/src/hb-blob.hh
index d85bd823b0..b03dfc1380 100644
--- a/thirdparty/harfbuzz/src/hb-blob.hh
+++ b/thirdparty/harfbuzz/src/hb-blob.hh
@@ -90,6 +90,7 @@ struct hb_blob_ptr_t
unsigned int get_length () const { return b.get ()->length; }
void destroy () { hb_blob_destroy (b.get ()); b = nullptr; }
+ private:
hb_nonnull_ptr_t<hb_blob_t> b;
};
diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh
index 1f9e2e91db..01db295498 100644
--- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh
+++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh
@@ -1,30 +1,29 @@
-
#line 1 "hb-buffer-deserialize-json.rl"
/*
- * Copyright © 2013 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
+* Copyright © 2013 Google, Inc.
+*
+* This is part of HarfBuzz, a text shaping library.
+*
+* Permission is hereby granted, without written agreement and without
+* license or royalty fees, to use, copy, modify, and distribute this
+* software and its documentation for any purpose, provided that the
+* above copyright notice and the following two paragraphs appear in
+* all copies of this software.
+*
+* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*
+* Google Author(s): Behdad Esfahbod
+*/
#ifndef HB_BUFFER_DESERIALIZE_JSON_HH
#define HB_BUFFER_DESERIALIZE_JSON_HH
@@ -32,612 +31,577 @@
#include "hb.hh"
-#line 36 "hb-buffer-deserialize-json.hh"
+#line 35 "hb-buffer-deserialize-json.hh"
static const unsigned char _deserialize_json_trans_keys[] = {
- 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
- 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
- 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u,
- 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u,
- 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
- 65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0
+ 1u, 0u, 0u, 18u, 0u, 2u, 10u, 15u,
+ 16u, 17u, 2u, 2u, 0u, 7u, 0u, 6u,
+ 5u, 6u, 0u, 19u, 0u, 19u, 0u, 19u,
+ 2u, 2u, 0u, 7u, 0u, 6u, 5u, 6u,
+ 0u, 19u, 0u, 19u, 14u, 14u, 2u, 2u,
+ 0u, 7u, 0u, 6u, 0u, 19u, 0u, 19u,
+ 16u, 17u, 2u, 2u, 0u, 7u, 0u, 6u,
+ 5u, 6u, 0u, 19u, 0u, 19u, 2u, 2u,
+ 0u, 7u, 0u, 6u, 5u, 6u, 0u, 19u,
+ 0u, 19u, 2u, 2u, 0u, 7u, 0u, 6u,
+ 2u, 8u, 0u, 19u, 2u, 8u, 0u, 19u,
+ 0u, 19u, 2u, 2u, 0u, 7u, 0u, 6u,
+ 0u, 19u, 0u, 9u, 0u, 18u, 1u, 0u,
+ 0u
};
-static const char _deserialize_json_key_spans[] = {
- 0, 115, 26, 7, 2, 1, 50, 49,
- 10, 117, 117, 117, 1, 50, 49, 10,
- 117, 117, 1, 1, 50, 49, 117, 117,
- 2, 1, 50, 49, 10, 117, 117, 1,
- 50, 49, 10, 117, 117, 1, 50, 49,
- 58, 89, 117, 117, 85, 115, 0
+static const signed char _deserialize_json_char_class[] = {
+ 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 4, 1, 1, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 7, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 8, 9, 1, 1, 1,
+ 10, 1, 11, 12, 1, 1, 13, 1,
+ 1, 1, 1, 14, 1, 1, 1, 1,
+ 1, 1, 1, 1, 15, 1, 1, 16,
+ 17, 1, 18, 1, 19, 0
};
static const short _deserialize_json_index_offsets[] = {
- 0, 0, 116, 143, 151, 154, 156, 207,
- 257, 268, 386, 504, 622, 624, 675, 725,
- 736, 854, 972, 974, 976, 1027, 1077, 1195,
- 1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666,
- 1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069,
- 2119, 2178, 2268, 2386, 2504, 2590, 2706
+ 0, 0, 19, 22, 28, 30, 31, 39,
+ 46, 48, 68, 88, 108, 109, 117, 124,
+ 126, 146, 166, 167, 168, 176, 183, 203,
+ 223, 225, 226, 234, 241, 243, 263, 283,
+ 284, 292, 299, 301, 321, 341, 342, 350,
+ 357, 364, 384, 391, 411, 431, 432, 440,
+ 447, 467, 477, 496, 0
+};
+
+static const signed char _deserialize_json_indicies[] = {
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 3, 0, 4, 5, 6,
+ 7, 8, 0, 9, 10, 11, 12, 12,
+ 0, 0, 0, 0, 0, 0, 13, 13,
+ 0, 0, 0, 14, 15, 16, 18, 19,
+ 20, 0, 0, 21, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 22, 23, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 24,
+ 20, 0, 0, 21, 0, 19, 19, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 22, 25, 25, 0, 0,
+ 0, 0, 0, 0, 26, 26, 0, 0,
+ 0, 27, 28, 29, 31, 32, 33, 0,
+ 0, 34, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 35, 33, 0, 0, 34, 0, 32,
+ 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 35, 36, 37,
+ 37, 0, 0, 0, 0, 0, 0, 38,
+ 38, 0, 0, 0, 0, 39, 40, 42,
+ 0, 0, 43, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 44, 42, 0, 0, 43, 0,
+ 45, 45, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 44, 46,
+ 47, 48, 48, 0, 0, 0, 0, 0,
+ 0, 49, 49, 0, 0, 0, 50, 51,
+ 52, 54, 55, 56, 0, 0, 57, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 58, 56,
+ 0, 0, 57, 0, 55, 55, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 58, 59, 59, 0, 0, 0,
+ 0, 0, 0, 60, 60, 0, 0, 0,
+ 61, 62, 63, 65, 66, 67, 0, 0,
+ 68, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 69, 67, 0, 0, 68, 0, 66, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 69, 70, 70, 0,
+ 0, 0, 0, 0, 0, 71, 71, 0,
+ 72, 0, 0, 73, 74, 76, 75, 75,
+ 75, 75, 75, 77, 79, 0, 0, 80,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 81,
+ 75, 0, 0, 0, 0, 0, 75, 83,
+ 0, 0, 84, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 85, 83, 0, 0, 84, 0,
+ 87, 87, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 85, 88,
+ 88, 0, 0, 0, 0, 0, 0, 89,
+ 89, 0, 0, 0, 0, 90, 91, 83,
+ 0, 0, 84, 0, 93, 93, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 85, 94, 0, 0, 95, 0,
+ 0, 0, 0, 0, 96, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2,
+ 0
};
-static const char _deserialize_json_indicies[] = {
- 0, 0, 0, 0, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 2, 1, 3, 3, 3,
- 3, 3, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 3, 1, 4, 1,
- 5, 1, 6, 7, 1, 1, 8, 1,
- 9, 10, 1, 11, 1, 11, 11, 11,
- 11, 11, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 11, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 12, 1,
- 12, 12, 12, 12, 12, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 12,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 13, 1, 1, 14,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 1, 16, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 1, 18, 18, 18,
- 18, 18, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 18, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 19, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 20, 1, 21, 21, 21, 21, 21,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 21, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 3, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 22,
- 1, 18, 18, 18, 18, 18, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 18, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 19, 1, 1, 1,
- 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 20, 1, 23,
- 1, 23, 23, 23, 23, 23, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 23, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 24, 1, 24, 24, 24, 24,
- 24, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 24, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 25, 1, 1, 26, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 1, 28, 29,
- 29, 29, 29, 29, 29, 29, 29, 29,
- 1, 30, 30, 30, 30, 30, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 30, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 31, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 32, 1, 30,
- 30, 30, 30, 30, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 30, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 31, 1, 1, 1, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 32, 1, 33, 1, 34,
- 1, 34, 34, 34, 34, 34, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 34, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 35, 1, 35, 35, 35, 35,
- 35, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 35, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 36, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 1, 38, 38,
- 38, 38, 38, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 38, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 39, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 40, 1, 38, 38, 38, 38,
- 38, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 38, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 39,
- 1, 1, 1, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 40, 1, 42, 43, 1, 44, 1, 44,
- 44, 44, 44, 44, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 44, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 45, 1, 45, 45, 45, 45, 45, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 45, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 46, 1,
- 1, 47, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 1, 49, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 1, 51,
- 51, 51, 51, 51, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 51, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 52, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 53, 1, 51, 51, 51,
- 51, 51, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 51, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 52, 1, 1, 1, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 53, 1, 54, 1, 54, 54, 54,
- 54, 54, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 54, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 55, 1,
- 55, 55, 55, 55, 55, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 55,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 56, 1, 1, 57,
- 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 1, 59, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 1, 61, 61, 61,
- 61, 61, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 61, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 62, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 63, 1, 61, 61, 61, 61, 61,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 61, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 62, 1,
- 1, 1, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 63,
- 1, 64, 1, 64, 64, 64, 64, 64,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 64, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 65, 1, 65, 65,
- 65, 65, 65, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 65, 1, 66,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 67, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 1,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 1, 1, 1, 1, 1, 1,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 1, 70, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 71, 71,
- 1, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 1, 1, 1, 1, 1,
- 1, 1, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 1, 1, 1, 1,
- 71, 1, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 1, 72, 72, 72,
- 72, 72, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 72, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 73, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 74, 1, 72, 72, 72, 72, 72,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 72, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 73, 1,
- 1, 1, 75, 75, 75, 75, 75, 75,
- 75, 75, 75, 75, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 74,
- 1, 76, 76, 76, 76, 76, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 76, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 77, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 78, 1, 0,
- 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 1, 1, 0
+static const signed char _deserialize_json_index_defaults[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 75, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0
};
-static const char _deserialize_json_trans_targs[] = {
- 1, 0, 2, 2, 3, 4, 18, 24,
- 37, 5, 12, 6, 7, 8, 9, 11,
- 9, 11, 10, 2, 44, 10, 44, 13,
- 14, 15, 16, 17, 16, 17, 10, 2,
- 44, 19, 20, 21, 22, 23, 10, 2,
- 44, 23, 25, 31, 26, 27, 28, 29,
- 30, 29, 30, 10, 2, 44, 32, 33,
- 34, 35, 36, 35, 36, 10, 2, 44,
- 38, 39, 40, 42, 43, 41, 10, 41,
- 10, 2, 44, 43, 44, 45, 46
+static const signed char _deserialize_json_cond_targs[] = {
+ 0, 1, 2, 2, 3, 4, 18, 24,
+ 37, 45, 5, 12, 6, 7, 8, 9,
+ 11, 8, 9, 11, 10, 2, 49, 10,
+ 49, 13, 14, 15, 16, 17, 15, 16,
+ 17, 10, 2, 49, 19, 20, 21, 22,
+ 23, 22, 10, 2, 49, 23, 25, 31,
+ 26, 27, 28, 29, 30, 28, 29, 30,
+ 10, 2, 49, 32, 33, 34, 35, 36,
+ 34, 35, 36, 10, 2, 49, 38, 39,
+ 40, 43, 44, 40, 41, 42, 41, 10,
+ 2, 49, 43, 10, 2, 49, 44, 44,
+ 46, 47, 43, 48, 48, 48, 49, 50,
+ 51, 0
};
-static const char _deserialize_json_trans_actions[] = {
- 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 2, 2, 2,
- 0, 0, 3, 3, 4, 0, 5, 0,
- 0, 2, 2, 2, 0, 0, 6, 6,
- 7, 0, 0, 0, 2, 2, 8, 8,
- 9, 0, 0, 0, 0, 0, 2, 2,
- 2, 0, 0, 10, 10, 11, 0, 0,
- 2, 2, 2, 0, 0, 12, 12, 13,
- 0, 0, 0, 2, 2, 2, 14, 0,
- 15, 15, 16, 0, 0, 0, 0
+static const signed char _deserialize_json_cond_actions[] = {
+ 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 2,
+ 2, 0, 0, 0, 3, 3, 4, 0,
+ 5, 0, 0, 2, 2, 2, 0, 0,
+ 0, 6, 6, 7, 0, 0, 0, 2,
+ 2, 0, 8, 8, 9, 0, 0, 0,
+ 0, 0, 2, 2, 2, 0, 0, 0,
+ 10, 10, 11, 0, 0, 2, 2, 2,
+ 0, 0, 0, 12, 12, 13, 0, 0,
+ 2, 14, 14, 0, 15, 0, 0, 16,
+ 16, 17, 0, 18, 18, 19, 0, 15,
+ 0, 0, 20, 20, 0, 21, 0, 0,
+ 0, 0
};
static const int deserialize_json_start = 1;
-static const int deserialize_json_first_final = 44;
+static const int deserialize_json_first_final = 49;
static const int deserialize_json_error = 0;
static const int deserialize_json_en_main = 1;
-#line 97 "hb-buffer-deserialize-json.rl"
+#line 108 "hb-buffer-deserialize-json.rl"
static hb_bool_t
-_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
- const char *buf,
- unsigned int buf_len,
- const char **end_ptr,
- hb_font_t *font)
+_hb_buffer_deserialize_json (hb_buffer_t *buffer,
+const char *buf,
+unsigned int buf_len,
+const char **end_ptr,
+hb_font_t *font)
{
- const char *p = buf, *pe = buf + buf_len;
-
- /* Ensure we have positions. */
- (void) hb_buffer_get_glyph_positions (buffer, nullptr);
-
- while (p < pe && ISSPACE (*p))
- p++;
- if (p < pe && *p == (buffer->len ? ',' : '['))
- {
- *end_ptr = ++p;
- }
-
- const char *tok = nullptr;
- int cs;
- hb_glyph_info_t info = {0};
- hb_glyph_position_t pos = {0};
-
-#line 466 "hb-buffer-deserialize-json.hh"
+ const char *p = buf, *pe = buf + buf_len;
+
+ /* Ensure we have positions. */
+ (void) hb_buffer_get_glyph_positions (buffer, nullptr);
+
+ while (p < pe && ISSPACE (*p))
+ p++;
+ if (p < pe && *p == (buffer->len ? ',' : '['))
+ {
+ *end_ptr = ++p;
+ }
+
+ const char *tok = nullptr;
+ int cs;
+ hb_glyph_info_t info = {0};
+ hb_glyph_position_t pos = {0};
+
+#line 223 "hb-buffer-deserialize-json.hh"
{
- cs = deserialize_json_start;
+ cs = (int)deserialize_json_start;
}
-
-#line 471 "hb-buffer-deserialize-json.hh"
+
+#line 228 "hb-buffer-deserialize-json.hh"
{
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
- if ( cs == 0 )
- goto _out;
-_resume:
- _keys = _deserialize_json_trans_keys + (cs<<1);
- _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs];
-
- _slen = _deserialize_json_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
- (*p) <= _keys[1] ?
- (*p) - _keys[0] : _slen ];
-
- cs = _deserialize_json_trans_targs[_trans];
-
- if ( _deserialize_json_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _deserialize_json_trans_actions[_trans] ) {
- case 1:
+ unsigned int _trans = 0;
+ const unsigned char * _keys;
+ const signed char * _inds;
+ int _ic;
+ _resume: {}
+ if ( p == pe )
+ goto _out;
+ _keys = ( _deserialize_json_trans_keys + ((cs<<1)));
+ _inds = ( _deserialize_json_indicies + (_deserialize_json_index_offsets[cs]));
+
+ if ( ( (*( p))) <= 125 && ( (*( p))) >= 9 ) {
+ _ic = (int)_deserialize_json_char_class[(int)( (*( p))) - 9];
+ if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) )
+ _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) ));
+ else
+ _trans = (unsigned int)_deserialize_json_index_defaults[cs];
+ }
+ else {
+ _trans = (unsigned int)_deserialize_json_index_defaults[cs];
+ }
+
+ cs = (int)_deserialize_json_cond_targs[_trans];
+
+ if ( _deserialize_json_cond_actions[_trans] != 0 ) {
+
+ switch ( _deserialize_json_cond_actions[_trans] ) {
+ case 1: {
+ {
#line 38 "hb-buffer-deserialize-json.rl"
- {
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
-}
- break;
- case 5:
+
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+ }
+
+#line 264 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 5: {
+ {
#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 2:
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 280 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 2: {
+ {
#line 51 "hb-buffer-deserialize-json.rl"
- {
- tok = p;
-}
- break;
- case 14:
+
+ tok = p;
+ }
+
+#line 292 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 15: {
+ {
#line 55 "hb-buffer-deserialize-json.rl"
- {
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
- break;
- case 15:
-#line 62 "hb-buffer-deserialize-json.rl"
- { if (!parse_uint (tok, p, &info.codepoint)) return false; }
- break;
- case 8:
-#line 63 "hb-buffer-deserialize-json.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
- break;
- case 10:
-#line 64 "hb-buffer-deserialize-json.rl"
- { if (!parse_int (tok, p, &pos.x_offset )) return false; }
- break;
- case 12:
-#line 65 "hb-buffer-deserialize-json.rl"
- { if (!parse_int (tok, p, &pos.y_offset )) return false; }
- break;
- case 3:
+ if (unlikely (!buffer->ensure_glyphs ())) return false; }
+
+#line 302 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 21: {
+ {
+#line 56 "hb-buffer-deserialize-json.rl"
+ if (unlikely (!buffer->ensure_unicode ())) return false; }
+
+#line 312 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 16: {
+ {
+#line 58 "hb-buffer-deserialize-json.rl"
+
+ /* TODO Unescape \" and \\ if found. */
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+ }
+
+#line 328 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 18: {
+ {
#line 66 "hb-buffer-deserialize-json.rl"
- { if (!parse_int (tok, p, &pos.x_advance)) return false; }
- break;
- case 6:
+ if (!parse_uint (tok, p, &info.codepoint)) return false; }
+
+#line 338 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 8: {
+ {
#line 67 "hb-buffer-deserialize-json.rl"
- { if (!parse_int (tok, p, &pos.y_advance)) return false; }
- break;
- case 16:
-#line 62 "hb-buffer-deserialize-json.rl"
- { if (!parse_uint (tok, p, &info.codepoint)) return false; }
+ if (!parse_uint (tok, p, &info.cluster )) return false; }
+
+#line 348 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 10: {
+ {
+#line 68 "hb-buffer-deserialize-json.rl"
+ if (!parse_int (tok, p, &pos.x_offset )) return false; }
+
+#line 358 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 12: {
+ {
+#line 69 "hb-buffer-deserialize-json.rl"
+ if (!parse_int (tok, p, &pos.y_offset )) return false; }
+
+#line 368 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 3: {
+ {
+#line 70 "hb-buffer-deserialize-json.rl"
+ if (!parse_int (tok, p, &pos.x_advance)) return false; }
+
+#line 378 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 6: {
+ {
+#line 71 "hb-buffer-deserialize-json.rl"
+ if (!parse_int (tok, p, &pos.y_advance)) return false; }
+
+#line 388 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 14: {
+ {
+#line 51 "hb-buffer-deserialize-json.rl"
+
+ tok = p;
+ }
+
+#line 400 "hb-buffer-deserialize-json.hh"
+
+ {
+#line 55 "hb-buffer-deserialize-json.rl"
+ if (unlikely (!buffer->ensure_glyphs ())) return false; }
+
+#line 406 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 20: {
+ {
+#line 51 "hb-buffer-deserialize-json.rl"
+
+ tok = p;
+ }
+
+#line 418 "hb-buffer-deserialize-json.hh"
+
+ {
+#line 56 "hb-buffer-deserialize-json.rl"
+ if (unlikely (!buffer->ensure_unicode ())) return false; }
+
+#line 424 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 17: {
+ {
+#line 58 "hb-buffer-deserialize-json.rl"
+
+ /* TODO Unescape \" and \\ if found. */
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+ }
+
+#line 440 "hb-buffer-deserialize-json.hh"
+
+ {
#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 9:
-#line 63 "hb-buffer-deserialize-json.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 452 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 19: {
+ {
+#line 66 "hb-buffer-deserialize-json.rl"
+ if (!parse_uint (tok, p, &info.codepoint)) return false; }
+
+#line 462 "hb-buffer-deserialize-json.hh"
+
+ {
#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 11:
-#line 64 "hb-buffer-deserialize-json.rl"
- { if (!parse_int (tok, p, &pos.x_offset )) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 474 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 9: {
+ {
+#line 67 "hb-buffer-deserialize-json.rl"
+ if (!parse_uint (tok, p, &info.cluster )) return false; }
+
+#line 484 "hb-buffer-deserialize-json.hh"
+
+ {
#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 13:
-#line 65 "hb-buffer-deserialize-json.rl"
- { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 496 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 11: {
+ {
+#line 68 "hb-buffer-deserialize-json.rl"
+ if (!parse_int (tok, p, &pos.x_offset )) return false; }
+
+#line 506 "hb-buffer-deserialize-json.hh"
+
+ {
#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 4:
-#line 66 "hb-buffer-deserialize-json.rl"
- { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 518 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 13: {
+ {
+#line 69 "hb-buffer-deserialize-json.rl"
+ if (!parse_int (tok, p, &pos.y_offset )) return false; }
+
+#line 528 "hb-buffer-deserialize-json.hh"
+
+ {
#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 7:
-#line 67 "hb-buffer-deserialize-json.rl"
- { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 540 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 4: {
+ {
+#line 70 "hb-buffer-deserialize-json.rl"
+ if (!parse_int (tok, p, &pos.x_advance)) return false; }
+
+#line 550 "hb-buffer-deserialize-json.hh"
+
+ {
#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
-#line 624 "hb-buffer-deserialize-json.hh"
- }
-
-_again:
- if ( cs == 0 )
- goto _out;
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- _out: {}
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 562 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ case 7: {
+ {
+#line 71 "hb-buffer-deserialize-json.rl"
+ if (!parse_int (tok, p, &pos.y_advance)) return false; }
+
+#line 572 "hb-buffer-deserialize-json.hh"
+
+ {
+#line 43 "hb-buffer-deserialize-json.rl"
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 584 "hb-buffer-deserialize-json.hh"
+
+
+ break;
+ }
+ }
+
+ }
+
+ if ( cs != 0 ) {
+ p += 1;
+ goto _resume;
+ }
+ _out: {}
}
-
-#line 125 "hb-buffer-deserialize-json.rl"
-
-
- *end_ptr = p;
-
- return p == pe && *(p-1) != ']';
+
+#line 136 "hb-buffer-deserialize-json.rl"
+
+
+ *end_ptr = p;
+
+ return p == pe && *(p-1) != ']';
}
#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */
diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh
index 67f0a1252f..fb36f56015 100644
--- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh
+++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh
@@ -1,30 +1,29 @@
-
#line 1 "hb-buffer-deserialize-text.rl"
/*
- * Copyright © 2013 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
+* Copyright © 2013 Google, Inc.
+*
+* This is part of HarfBuzz, a text shaping library.
+*
+* Permission is hereby granted, without written agreement and without
+* license or royalty fees, to use, copy, modify, and distribute this
+* software and its documentation for any purpose, provided that the
+* above copyright notice and the following two paragraphs appear in
+* all copies of this software.
+*
+* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*
+* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*
+* Google Author(s): Behdad Esfahbod
+*/
#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH
#define HB_BUFFER_DESERIALIZE_TEXT_HH
@@ -32,540 +31,734 @@
#include "hb.hh"
-#line 36 "hb-buffer-deserialize-text.hh"
+#line 35 "hb-buffer-deserialize-text.hh"
static const unsigned char _deserialize_text_trans_keys[] = {
- 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
- 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
- 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
- 9u, 124u, 9u, 124u, 9u, 124u, 0
+ 1u, 0u, 0u, 13u, 12u, 12u, 2u, 2u,
+ 5u, 11u, 0u, 12u, 5u, 6u, 4u, 6u,
+ 5u, 6u, 5u, 6u, 4u, 6u, 5u, 6u,
+ 3u, 3u, 4u, 6u, 5u, 6u, 3u, 6u,
+ 2u, 16u, 4u, 6u, 5u, 6u, 0u, 16u,
+ 0u, 16u, 1u, 0u, 0u, 12u, 0u, 16u,
+ 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u,
+ 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u,
+ 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u,
+ 0u, 16u, 0u
};
-static const char _deserialize_text_key_spans[] = {
- 0, 114, 13, 10, 13, 10, 10, 13,
- 10, 1, 13, 10, 14, 116, 116, 0,
- 114, 116, 116, 116, 116, 116, 116, 116,
- 116, 116, 116
+static const signed char _deserialize_text_char_class[] = {
+ 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 3, 4, 1, 1, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 1, 1, 7, 8, 9, 1, 10,
+ 11, 11, 11, 11, 11, 11, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 12, 1, 1, 1,
+ 1, 1, 13, 14, 15, 1, 1, 1,
+ 11, 11, 11, 11, 11, 11, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 16, 0
};
static const short _deserialize_text_index_offsets[] = {
- 0, 0, 115, 129, 140, 154, 165, 176,
- 190, 201, 203, 217, 228, 243, 360, 477,
- 478, 593, 710, 827, 944, 1061, 1178, 1295,
- 1412, 1529, 1646
+ 0, 0, 14, 15, 16, 23, 36, 38,
+ 41, 43, 45, 48, 50, 51, 54, 56,
+ 60, 75, 78, 80, 97, 114, 114, 127,
+ 144, 161, 178, 195, 212, 229, 246, 263,
+ 280, 297, 314, 331, 348, 0
+};
+
+static const signed char _deserialize_text_indicies[] = {
+ 1, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 3, 4, 6,
+ 7, 7, 0, 0, 0, 0, 7, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 10, 11, 13, 14,
+ 15, 17, 18, 20, 21, 23, 24, 25,
+ 27, 28, 29, 31, 32, 33, 35, 36,
+ 29, 0, 28, 28, 38, 38, 0, 0,
+ 0, 0, 38, 0, 38, 0, 0, 0,
+ 38, 38, 38, 40, 41, 42, 44, 45,
+ 47, 0, 0, 0, 0, 48, 48, 0,
+ 49, 50, 0, 48, 0, 0, 0, 0,
+ 51, 52, 0, 0, 0, 0, 0, 0,
+ 0, 0, 53, 0, 0, 0, 0, 0,
+ 0, 54, 8, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 4, 56,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 57, 0, 0, 0, 0, 0, 0, 58,
+ 56, 0, 0, 0, 0, 60, 60, 0,
+ 0, 57, 0, 0, 0, 0, 0, 0,
+ 58, 63, 62, 64, 0, 62, 62, 62,
+ 62, 65, 62, 66, 62, 62, 62, 67,
+ 68, 69, 71, 38, 72, 0, 38, 38,
+ 38, 38, 73, 38, 74, 38, 38, 38,
+ 37, 75, 76, 78, 0, 0, 79, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 80, 81, 82, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 53, 83, 84, 62, 64,
+ 0, 62, 62, 62, 62, 65, 62, 66,
+ 62, 62, 62, 67, 68, 69, 86, 0,
+ 87, 0, 0, 0, 0, 0, 0, 0,
+ 88, 0, 0, 0, 0, 57, 89, 91,
+ 0, 92, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 93, 94,
+ 91, 0, 92, 0, 0, 36, 36, 0,
+ 0, 0, 0, 0, 0, 0, 0, 93,
+ 94, 86, 0, 87, 0, 0, 97, 97,
+ 0, 0, 0, 88, 0, 0, 0, 0,
+ 57, 89, 99, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 100, 101, 99, 0, 0, 0, 0,
+ 45, 45, 0, 0, 0, 0, 0, 0,
+ 0, 0, 100, 101, 78, 0, 0, 79,
+ 0, 18, 18, 0, 0, 0, 0, 0,
+ 0, 0, 0, 80, 81, 0
};
-static const char _deserialize_text_indicies[] = {
- 0, 0, 0, 0, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 1, 1, 1, 1, 1, 1,
- 1, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 1, 1, 1, 1, 1,
- 1, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 1, 5, 1, 1, 6,
- 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 1, 8, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 1, 10, 1, 1,
- 11, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 1, 13, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 1, 15, 16,
- 16, 16, 16, 16, 16, 16, 16, 16,
- 1, 17, 1, 1, 18, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 1, 20,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 1, 22, 1, 23, 1, 1, 24,
- 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 1, 26, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 1, 22, 1, 1,
- 1, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 1, 28, 28, 28, 28,
- 28, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 28, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 29, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 30, 1, 1, 31, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 32, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 33,
- 1, 34, 34, 34, 34, 34, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 34, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 35, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 36, 1, 1, 0,
- 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 2, 3,
- 3, 3, 3, 3, 3, 3, 3, 3,
- 1, 1, 1, 1, 1, 1, 1, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 1, 1, 1, 1, 1, 1, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 1, 28, 28, 28, 28, 28, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 28, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 29, 1, 1, 1,
- 1, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 1, 1, 1, 30, 1,
- 1, 31, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 32, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 33, 1, 38,
- 38, 38, 38, 38, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 38, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 39, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 40, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 41, 1, 42, 42, 42, 42,
- 42, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 42, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 43, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 44,
- 1, 42, 42, 42, 42, 42, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 42, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 43, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 44, 1, 38, 38,
- 38, 38, 38, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 38, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 39, 1, 1, 1, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 40, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 41, 1, 45, 45, 45, 45, 45,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 45, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 46, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 47, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 48,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 49, 1,
- 50, 50, 50, 50, 50, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 50,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 51, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 52, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 53, 1, 50, 50, 50,
- 50, 50, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 50, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 51,
- 1, 1, 1, 1, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 52, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 53, 1, 45, 45, 45, 45, 45, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 45, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 46, 1, 1, 1,
- 1, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 1, 1, 1, 1, 1,
- 1, 47, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 48, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 49, 1, 28,
- 28, 28, 28, 28, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 28, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 29, 1, 55, 55, 1, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 1, 1, 1, 30, 1, 1, 31, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 1, 1, 32, 1, 55, 1, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 1, 33, 1, 0
+static const signed char _deserialize_text_index_defaults[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 62, 38, 0, 0, 62, 0, 0,
+ 0, 0, 0, 0, 0, 0
};
-static const char _deserialize_text_trans_targs[] = {
- 1, 0, 13, 17, 26, 3, 18, 21,
- 18, 21, 5, 19, 20, 19, 20, 22,
- 25, 8, 9, 12, 9, 12, 10, 11,
- 23, 24, 23, 24, 14, 2, 6, 7,
- 15, 16, 14, 15, 16, 17, 14, 4,
- 15, 16, 14, 15, 16, 14, 2, 7,
- 15, 16, 14, 2, 15, 16, 25, 26
+static const signed char _deserialize_text_cond_targs[] = {
+ 0, 1, 2, 25, 3, 3, 4, 19,
+ 5, 6, 23, 24, 7, 8, 27, 36,
+ 8, 27, 36, 9, 30, 33, 10, 11,
+ 12, 15, 11, 12, 15, 13, 13, 14,
+ 31, 32, 14, 31, 32, 16, 26, 17,
+ 18, 34, 35, 18, 34, 35, 19, 20,
+ 19, 6, 21, 22, 20, 21, 22, 23,
+ 20, 21, 22, 24, 24, 25, 26, 26,
+ 7, 9, 10, 16, 21, 29, 26, 26,
+ 7, 9, 10, 21, 29, 27, 28, 17,
+ 21, 29, 28, 29, 29, 30, 28, 7,
+ 10, 29, 31, 28, 7, 21, 29, 32,
+ 33, 33, 34, 28, 21, 29, 35, 36,
+ 0
};
-static const char _deserialize_text_trans_actions[] = {
- 0, 0, 1, 1, 1, 2, 2, 2,
- 0, 0, 2, 2, 2, 0, 0, 2,
- 2, 2, 2, 2, 0, 0, 3, 2,
- 2, 2, 0, 0, 4, 5, 5, 5,
- 4, 4, 0, 0, 0, 0, 6, 7,
- 6, 6, 8, 8, 8, 9, 10, 10,
- 9, 9, 11, 12, 11, 11, 0, 0
+static const signed char _deserialize_text_cond_actions[] = {
+ 0, 0, 0, 0, 1, 0, 0, 2,
+ 0, 0, 2, 2, 0, 3, 4, 4,
+ 0, 5, 5, 0, 4, 4, 0, 3,
+ 3, 3, 0, 0, 0, 6, 0, 3,
+ 4, 4, 0, 5, 5, 0, 5, 0,
+ 3, 4, 4, 0, 5, 5, 7, 7,
+ 8, 9, 7, 7, 0, 0, 0, 10,
+ 10, 10, 10, 10, 8, 11, 12, 13,
+ 14, 14, 14, 15, 11, 11, 16, 17,
+ 18, 18, 18, 16, 16, 19, 19, 20,
+ 19, 19, 0, 0, 13, 10, 10, 21,
+ 21, 10, 22, 22, 23, 22, 22, 22,
+ 10, 5, 24, 24, 24, 24, 24, 19,
+ 0
};
-static const char _deserialize_text_eof_actions[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 4, 0, 0,
- 0, 4, 6, 8, 8, 6, 9, 11,
- 11, 9, 4
+static const signed char _deserialize_text_eof_trans[] = {
+ 1, 2, 3, 6, 7, 9, 10, 13,
+ 17, 20, 23, 27, 28, 31, 35, 29,
+ 38, 40, 44, 47, 53, 54, 55, 56,
+ 60, 62, 71, 78, 83, 70, 86, 91,
+ 96, 97, 99, 103, 104, 0
};
static const int deserialize_text_start = 1;
-static const int deserialize_text_first_final = 13;
+static const int deserialize_text_first_final = 19;
static const int deserialize_text_error = 0;
static const int deserialize_text_en_main = 1;
-#line 91 "hb-buffer-deserialize-text.rl"
+#line 114 "hb-buffer-deserialize-text.rl"
static hb_bool_t
-_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
- const char *buf,
- unsigned int buf_len,
- const char **end_ptr,
- hb_font_t *font)
+_hb_buffer_deserialize_text (hb_buffer_t *buffer,
+const char *buf,
+unsigned int buf_len,
+const char **end_ptr,
+hb_font_t *font)
{
- const char *p = buf, *pe = buf + buf_len;
-
- /* Ensure we have positions. */
- (void) hb_buffer_get_glyph_positions (buffer, nullptr);
-
- while (p < pe && ISSPACE (*p))
- p++;
- if (p < pe && *p == (buffer->len ? '|' : '['))
- {
- *end_ptr = ++p;
- }
-
- const char *eof = pe, *tok = nullptr;
- int cs;
- hb_glyph_info_t info = {0};
- hb_glyph_position_t pos = {0};
-
-#line 343 "hb-buffer-deserialize-text.hh"
+ const char *p = buf, *pe = buf + buf_len;
+
+ /* Ensure we have positions. */
+ (void) hb_buffer_get_glyph_positions (buffer, nullptr);
+
+ while (p < pe && ISSPACE (*p))
+ p++;
+
+ const char *eof = pe, *tok = nullptr;
+ int cs;
+ hb_glyph_info_t info = {0};
+ hb_glyph_position_t pos = {0};
+
+#line 204 "hb-buffer-deserialize-text.hh"
{
- cs = deserialize_text_start;
+ cs = (int)deserialize_text_start;
}
-
-#line 348 "hb-buffer-deserialize-text.hh"
+
+#line 209 "hb-buffer-deserialize-text.hh"
{
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
- if ( cs == 0 )
- goto _out;
-_resume:
- _keys = _deserialize_text_trans_keys + (cs<<1);
- _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs];
-
- _slen = _deserialize_text_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
- (*p) <= _keys[1] ?
- (*p) - _keys[0] : _slen ];
-
- cs = _deserialize_text_trans_targs[_trans];
-
- if ( _deserialize_text_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _deserialize_text_trans_actions[_trans] ) {
- case 2:
+ unsigned int _trans = 0;
+ const unsigned char * _keys;
+ const signed char * _inds;
+ int _ic;
+ _resume: {}
+ if ( p == pe && p != eof )
+ goto _out;
+ if ( p == eof ) {
+ if ( _deserialize_text_eof_trans[cs] > 0 ) {
+ _trans = (unsigned int)_deserialize_text_eof_trans[cs] - 1;
+ }
+ }
+ else {
+ _keys = ( _deserialize_text_trans_keys + ((cs<<1)));
+ _inds = ( _deserialize_text_indicies + (_deserialize_text_index_offsets[cs]));
+
+ if ( ( (*( p))) <= 124 && ( (*( p))) >= 9 ) {
+ _ic = (int)_deserialize_text_char_class[(int)( (*( p))) - 9];
+ if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) )
+ _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) ));
+ else
+ _trans = (unsigned int)_deserialize_text_index_defaults[cs];
+ }
+ else {
+ _trans = (unsigned int)_deserialize_text_index_defaults[cs];
+ }
+
+ }
+ cs = (int)_deserialize_text_cond_targs[_trans];
+
+ if ( _deserialize_text_cond_actions[_trans] != 0 ) {
+
+ switch ( _deserialize_text_cond_actions[_trans] ) {
+ case 1: {
+ {
+#line 38 "hb-buffer-deserialize-text.rl"
+
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+ }
+
+#line 252 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 3: {
+ {
#line 51 "hb-buffer-deserialize-text.rl"
- {
- tok = p;
-}
- break;
- case 5:
+
+ tok = p;
+ }
+
+#line 264 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 5: {
+ {
#line 55 "hb-buffer-deserialize-text.rl"
- {
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
- break;
- case 10:
-#line 62 "hb-buffer-deserialize-text.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
- break;
- case 3:
-#line 63 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.x_offset )) return false; }
- break;
- case 12:
-#line 64 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.y_offset )) return false; }
- break;
- case 7:
-#line 65 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.x_advance)) return false; }
- break;
- case 1:
+ if (unlikely (!buffer->ensure_glyphs ())) return false; }
+
+#line 274 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 8: {
+ {
+#line 56 "hb-buffer-deserialize-text.rl"
+ if (unlikely (!buffer->ensure_unicode ())) return false; }
+
+#line 284 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 18: {
+ {
+#line 58 "hb-buffer-deserialize-text.rl"
+
+ /* TODO Unescape delimeters. */
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+ }
+
+#line 300 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 9: {
+ {
+#line 66 "hb-buffer-deserialize-text.rl"
+ if (!parse_hex (tok, p, &info.codepoint )) return false; }
+
+#line 310 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 21: {
+ {
+#line 68 "hb-buffer-deserialize-text.rl"
+ if (!parse_uint (tok, p, &info.cluster )) return false; }
+
+#line 320 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 6: {
+ {
+#line 69 "hb-buffer-deserialize-text.rl"
+ if (!parse_int (tok, p, &pos.x_offset )) return false; }
+
+#line 330 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 23: {
+ {
+#line 70 "hb-buffer-deserialize-text.rl"
+ if (!parse_int (tok, p, &pos.y_offset )) return false; }
+
+#line 340 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 20: {
+ {
+#line 71 "hb-buffer-deserialize-text.rl"
+ if (!parse_int (tok, p, &pos.x_advance)) return false; }
+
+#line 350 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 15: {
+ {
#line 38 "hb-buffer-deserialize-text.rl"
- {
- memset (&info, 0, sizeof (info));
- memset (&pos , 0, sizeof (pos ));
-}
+
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+ }
+
+#line 363 "hb-buffer-deserialize-text.hh"
+
+ {
#line 51 "hb-buffer-deserialize-text.rl"
- {
- tok = p;
-}
- break;
- case 4:
+
+ tok = p;
+ }
+
+#line 371 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 4: {
+ {
+#line 51 "hb-buffer-deserialize-text.rl"
+
+ tok = p;
+ }
+
+#line 383 "hb-buffer-deserialize-text.hh"
+
+ {
#line 55 "hb-buffer-deserialize-text.rl"
- {
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 9:
-#line 62 "hb-buffer-deserialize-text.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
+ if (unlikely (!buffer->ensure_glyphs ())) return false; }
+
+#line 389 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 2: {
+ {
+#line 51 "hb-buffer-deserialize-text.rl"
+
+ tok = p;
+ }
+
+#line 401 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 56 "hb-buffer-deserialize-text.rl"
+ if (unlikely (!buffer->ensure_unicode ())) return false; }
+
+#line 407 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 16: {
+ {
+#line 58 "hb-buffer-deserialize-text.rl"
+
+ /* TODO Unescape delimeters. */
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+ }
+
+#line 423 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 11:
-#line 64 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 435 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 7: {
+ {
+#line 66 "hb-buffer-deserialize-text.rl"
+ if (!parse_hex (tok, p, &info.codepoint )) return false; }
+
+#line 445 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 6:
-#line 65 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 457 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 10: {
+ {
+#line 68 "hb-buffer-deserialize-text.rl"
+ if (!parse_uint (tok, p, &info.cluster )) return false; }
+
+#line 467 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 8:
-#line 66 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 479 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 22: {
+ {
+#line 70 "hb-buffer-deserialize-text.rl"
+ if (!parse_int (tok, p, &pos.y_offset )) return false; }
+
+#line 489 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
-#line 480 "hb-buffer-deserialize-text.hh"
- }
-
-_again:
- if ( cs == 0 )
- goto _out;
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- switch ( _deserialize_text_eof_actions[cs] ) {
- case 4:
-#line 55 "hb-buffer-deserialize-text.rl"
- {
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 501 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 19: {
+ {
+#line 71 "hb-buffer-deserialize-text.rl"
+ if (!parse_int (tok, p, &pos.x_advance)) return false; }
+
+#line 511 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 9:
-#line 62 "hb-buffer-deserialize-text.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 523 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 24: {
+ {
+#line 72 "hb-buffer-deserialize-text.rl"
+ if (!parse_int (tok, p, &pos.y_advance)) return false; }
+
+#line 533 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 11:
-#line 64 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 545 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 12: {
+ {
+#line 38 "hb-buffer-deserialize-text.rl"
+
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+ }
+
+#line 558 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 51 "hb-buffer-deserialize-text.rl"
+
+ tok = p;
+ }
+
+#line 566 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 55 "hb-buffer-deserialize-text.rl"
+ if (unlikely (!buffer->ensure_glyphs ())) return false; }
+
+#line 572 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 14: {
+ {
+#line 38 "hb-buffer-deserialize-text.rl"
+
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+ }
+
+#line 585 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 51 "hb-buffer-deserialize-text.rl"
+
+ tok = p;
+ }
+
+#line 593 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 58 "hb-buffer-deserialize-text.rl"
+
+ /* TODO Unescape delimeters. */
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+ }
+
+#line 605 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 17: {
+ {
+#line 58 "hb-buffer-deserialize-text.rl"
+
+ /* TODO Unescape delimeters. */
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+ }
+
+#line 621 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 55 "hb-buffer-deserialize-text.rl"
+ if (unlikely (!buffer->ensure_glyphs ())) return false; }
+
+#line 627 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 6:
-#line 65 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 639 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 11: {
+ {
+#line 38 "hb-buffer-deserialize-text.rl"
+
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+ }
+
+#line 652 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 51 "hb-buffer-deserialize-text.rl"
+
+ tok = p;
+ }
+
+#line 660 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 58 "hb-buffer-deserialize-text.rl"
+
+ /* TODO Unescape delimeters. */
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+ }
+
+#line 672 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 8:
-#line 66 "hb-buffer-deserialize-text.rl"
- { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 684 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ case 13: {
+ {
+#line 38 "hb-buffer-deserialize-text.rl"
+
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+ }
+
+#line 697 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 51 "hb-buffer-deserialize-text.rl"
+
+ tok = p;
+ }
+
+#line 705 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 58 "hb-buffer-deserialize-text.rl"
+
+ /* TODO Unescape delimeters. */
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+ }
+
+#line 717 "hb-buffer-deserialize-text.hh"
+
+ {
+#line 55 "hb-buffer-deserialize-text.rl"
+ if (unlikely (!buffer->ensure_glyphs ())) return false; }
+
+#line 723 "hb-buffer-deserialize-text.hh"
+
+ {
#line 43 "hb-buffer-deserialize-text.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
-#line 557 "hb-buffer-deserialize-text.hh"
- }
- }
-
- _out: {}
+
+ buffer->add_info (info);
+ if (unlikely (!buffer->successful))
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+ }
+
+#line 735 "hb-buffer-deserialize-text.hh"
+
+
+ break;
+ }
+ }
+
+ }
+
+ if ( p == eof ) {
+ if ( cs >= 19 )
+ goto _out;
+ }
+ else {
+ if ( cs != 0 ) {
+ p += 1;
+ goto _resume;
+ }
+ }
+ _out: {}
}
-
-#line 119 "hb-buffer-deserialize-text.rl"
-
-
- *end_ptr = p;
-
- return p == pe && *(p-1) != ']';
+
+#line 138 "hb-buffer-deserialize-text.rl"
+
+
+ *end_ptr = p;
+
+ return p == pe && *(p-1) != ']';
}
#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */
diff --git a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc
index bc6c978b38..f65bad45bb 100644
--- a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc
@@ -91,26 +91,26 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
switch ((unsigned) format)
{
- case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
- case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
default:
- case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
}
}
static unsigned int
_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_font_t *font,
- hb_buffer_serialize_flags_t flags)
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_flags_t flags)
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
- nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
+ nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
hb_position_t x = 0, y = 0;
@@ -125,6 +125,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (i)
*p++ = ',';
+ else
+ *p++ = '[';
*p++ = '{';
@@ -134,8 +136,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
char g[128];
hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
*p++ = '"';
- for (char *q = g; *q; q++) {
- if (*q == '"')
+ for (char *q = g; *q; q++)
+ {
+ if (unlikely (*q == '"' || *q == '\\'))
*p++ = '\\';
*p++ = *q;
}
@@ -151,16 +154,16 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
- x+pos[i].x_offset, y+pos[i].y_offset));
+ x+pos[i].x_offset, y+pos[i].y_offset));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
- pos[i].x_advance, pos[i].y_advance));
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
+ pos[i].x_advance, pos[i].y_advance));
}
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
{
if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
}
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
@@ -168,12 +171,14 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
hb_glyph_extents_t extents;
hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
- extents.x_bearing, extents.y_bearing));
+ extents.x_bearing, extents.y_bearing));
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
- extents.width, extents.height));
+ extents.width, extents.height));
}
*p++ = '}';
+ if (i == end-1)
+ *p++ = ']';
unsigned int l = p - b;
if (buf_size > l)
@@ -197,18 +202,71 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
}
static unsigned int
+_hb_buffer_serialize_unicode_json (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_buffer_serialize_flags_t flags)
+{
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
+
+ *buf_consumed = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ char b[1024];
+ char *p = b;
+
+ if (i)
+ *p++ = ',';
+ else
+ *p++ = '[';
+
+ *p++ = '{';
+
+ APPEND ("\"u\":");
+
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
+ }
+
+ *p++ = '}';
+
+ if (i == end-1)
+ *p++ = ']';
+
+ unsigned int l = p - b;
+ if (buf_size > l)
+ {
+ memcpy (buf, b, l);
+ buf += l;
+ buf_size -= l;
+ *buf_consumed += l;
+ *buf = '\0';
+ } else
+ return i - start;
+
+ }
+
+ return end - start;
+}
+
+static unsigned int
_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_font_t *font,
- hb_buffer_serialize_flags_t flags)
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_flags_t flags)
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
- nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
+ nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
hb_position_t x = 0, y = 0;
@@ -221,9 +279,12 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
if (i)
*p++ = '|';
+ else
+ *p++ = '[';
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
{
+ /* TODO Escape delimiters we use. */
hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
p += strlen (p);
}
@@ -237,21 +298,21 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{
if (x+pos[i].x_offset || y+pos[i].y_offset)
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
{
- *p++ = '+';
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
- if (pos[i].y_advance)
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
+ *p++ = '+';
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
+ if (pos[i].y_advance)
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
}
}
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
{
if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
}
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
@@ -261,6 +322,10 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
}
+ if (i == end-1) {
+ *p++ = ']';
+ }
+
unsigned int l = p - b;
if (buf_size > l)
{
@@ -282,6 +347,51 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
return end - start;
}
+
+static unsigned int
+_hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_buffer_serialize_flags_t flags)
+{
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
+ *buf_consumed = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ char b[1024];
+ char *p = b;
+
+ if (i)
+ *p++ = '|';
+ else
+ *p++ = '<';
+
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "U+%04X", info[i].codepoint));
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
+ p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
+ }
+
+ if (i == end-1)
+ *p++ = '>';
+
+ unsigned int l = p - b;
+ if (buf_size > l)
+ {
+ memcpy (buf, b, l);
+ buf += l;
+ buf_size -= l;
+ *buf_consumed += l;
+ *buf = '\0';
+ } else
+ return i - start;
+ }
+ return end - start;
+}
+
/**
* hb_buffer_serialize_glyphs:
* @buffer: an #hb_buffer_t buffer.
@@ -308,6 +418,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
* ```
* [uni0651=0@518,0+0|uni0628=0+1897]
* ```
+ *
* - The serialized glyphs are delimited with `[` and `]`.
* - Glyphs are separated with `|`
* - Each glyph starts with glyph name, or glyph index if
@@ -316,12 +427,28 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format:
* - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then,
* - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then,
- * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the
- * #hb_glyph_extents_t in the format
- * `&lt;x_bearing,y_bearing,width,height&gt;`
+ * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `<x_bearing,y_bearing,width,height>`
*
* ## json
- * TODO.
+ * A machine-readable, structured format.
+ * The serialized glyphs will look something like:
+ *
+ * ```
+ * [{"g":"uni0651","cl":0,"dx":518,"dy":0,"ax":0,"ay":0},
+ * {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}]
+ * ```
+ *
+ * Each glyph is a JSON object, with the following properties:
+ * - `g`: the glyph name or glyph index if
+ * #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set.
+ * - `cl`: #hb_glyph_info_t.cluster if
+ * #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.
+ * - `dx`,`dy`,`ax`,`ay`: #hb_glyph_position_t.x_offset, #hb_glyph_position_t.y_offset,
+ * #hb_glyph_position_t.x_advance and #hb_glyph_position_t.y_advance
+ * respectively, if #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set.
+ * - `xb`,`yb`,`w`,`h`: #hb_glyph_extents_t.x_bearing, #hb_glyph_extents_t.y_bearing,
+ * #hb_glyph_extents_t.width and #hb_glyph_extents_t.height respectively if
+ * #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set.
*
* Return value:
* The number of serialized items.
@@ -330,16 +457,17 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
**/
unsigned int
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_font_t *font,
- hb_buffer_serialize_format_t format,
- hb_buffer_serialize_flags_t flags)
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags)
{
- assert (start <= end && end <= buffer->len);
+ end = hb_clamp (end, start, buffer->len);
+ start = hb_min (start, end);
unsigned int sconsumed;
if (!buf_consumed)
@@ -348,8 +476,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
if (buf_size)
*buf = '\0';
- assert ((!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)) ||
- (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS));
+ buffer->assert_glyphs ();
if (!buffer->have_positions)
flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS;
@@ -364,13 +491,13 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_serialize_glyphs_text (buffer, start, end,
- buf, buf_size, buf_consumed,
- font, flags);
+ buf, buf_size, buf_consumed,
+ font, flags);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_serialize_glyphs_json (buffer, start, end,
- buf, buf_size, buf_consumed,
- font, flags);
+ buf, buf_size, buf_consumed,
+ font, flags);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
@@ -379,6 +506,182 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
}
}
+/**
+ * hb_buffer_serialize_unicode:
+ * @buffer: an #hb_buffer_t buffer.
+ * @start: the first item in @buffer to serialize.
+ * @end: the last item in @buffer to serialize.
+ * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
+ * write serialized buffer into.
+ * @buf_size: the size of @buf.
+ * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf.
+ * @format: the #hb_buffer_serialize_format_t to use for formatting the output.
+ *
+ * Serializes @buffer into a textual representation of its content,
+ * when the buffer contains Unicode codepoints (i.e., before shaping). This is
+ * useful for showing the contents of the buffer, for example during debugging.
+ * There are currently two supported serialization formats:
+ *
+ * ## text
+ * A human-readable, plain text format.
+ * The serialized codepoints will look something like:
+ *
+ * ```
+ *  <U+0651=0|U+0628=1>
+ * ```
+ *
+ * - Glyphs are separated with `|`
+ * - Unicode codepoints are expressed as zero-padded four (or more)
+ * digit hexadecimal numbers preceded by `U+`
+ * - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, the cluster
+ * will be indicated with a `=` then #hb_glyph_info_t.cluster.
+ *
+ * ## json
+ * A machine-readable, structured format.
+ * The serialized codepoints will be a list of objects with the following
+ * properties:
+ * - `u`: the Unicode codepoint as a decimal integer
+ * - `cl`: #hb_glyph_info_t.cluster if
+ * #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.
+ *
+ * For example:
+ *
+ * ```
+ * [{u:1617,cl:0},{u:1576,cl:1}]
+ * ```
+ *
+ * Return value:
+ * The number of serialized items.
+ *
+ * Since: 2.7.3
+ **/
+unsigned int
+hb_buffer_serialize_unicode (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags)
+{
+ end = hb_clamp (end, start, buffer->len);
+ start = hb_min (start, end);
+
+ unsigned int sconsumed;
+ if (!buf_consumed)
+ buf_consumed = &sconsumed;
+ *buf_consumed = 0;
+ if (buf_size)
+ *buf = '\0';
+
+ buffer->assert_unicode ();
+
+ if (unlikely (start == end))
+ return 0;
+
+ switch (format)
+ {
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
+ return _hb_buffer_serialize_unicode_text (buffer, start, end,
+ buf, buf_size, buf_consumed, flags);
+
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON:
+ return _hb_buffer_serialize_unicode_json (buffer, start, end,
+ buf, buf_size, buf_consumed, flags);
+
+ default:
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
+ return 0;
+
+ }
+}
+
+static unsigned int
+_hb_buffer_serialize_invalid (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags)
+{
+ assert (!buffer->len);
+
+ unsigned int sconsumed;
+ if (!buf_consumed)
+ buf_consumed = &sconsumed;
+ if (buf_size < 3)
+ return 0;
+ if (format == HB_BUFFER_SERIALIZE_FORMAT_JSON) {
+ *buf++ = '[';
+ *buf++ = ']';
+ *buf = '\0';
+ } else if (format == HB_BUFFER_SERIALIZE_FORMAT_TEXT) {
+ *buf++ = '!';
+ *buf++ = '!';
+ *buf = '\0';
+ }
+ *buf_consumed = 2;
+ return 0;
+}
+
+/**
+ * hb_buffer_serialize:
+ * @buffer: an #hb_buffer_t buffer.
+ * @start: the first item in @buffer to serialize.
+ * @end: the last item in @buffer to serialize.
+ * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
+ * write serialized buffer into.
+ * @buf_size: the size of @buf.
+ * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf.
+ * @font: (allow-none): the #hb_font_t used to shape this buffer, needed to
+ * read glyph names and extents. If %NULL, and empty font will be used.
+ * @format: the #hb_buffer_serialize_format_t to use for formatting the output.
+ * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
+ * to serialize.
+ *
+ * Serializes @buffer into a textual representation of its content, whether
+ * Unicode codepoints or glyph identifiers and positioning information. This is
+ * useful for showing the contents of the buffer, for example during debugging.
+ * See the documentation of hb_buffer_serialize_unicode() and
+ * hb_buffer_serialize_glyphs() for a description of the output format.
+ *
+ * Return value:
+ * The number of serialized items.
+ *
+ * Since: 2.7.3
+ **/
+unsigned int
+hb_buffer_serialize (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags)
+{
+ switch (buffer->content_type)
+ {
+
+ case HB_BUFFER_CONTENT_TYPE_GLYPHS:
+ return hb_buffer_serialize_glyphs (buffer, start, end, buf, buf_size,
+ buf_consumed, font, format, flags);
+
+ case HB_BUFFER_CONTENT_TYPE_UNICODE:
+ return hb_buffer_serialize_unicode (buffer, start, end, buf, buf_size,
+ buf_consumed, format, flags);
+
+ case HB_BUFFER_CONTENT_TYPE_INVALID:
+ default:
+ return _hb_buffer_serialize_invalid (buffer, start, end, buf, buf_size,
+ buf_consumed, format, flags);
+ }
+}
+
static bool
parse_int (const char *pp, const char *end, int32_t *pv)
{
@@ -403,6 +706,18 @@ parse_uint (const char *pp, const char *end, uint32_t *pv)
return true;
}
+static bool
+parse_hex (const char *pp, const char *end, uint32_t *pv)
+{
+ unsigned int v;
+ const char *p = pp;
+ if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, 16)))
+ return false;
+
+ *pv = v;
+ return true;
+}
+
#include "hb-buffer-deserialize-json.hh"
#include "hb-buffer-deserialize-text.hh"
@@ -423,19 +738,25 @@ parse_uint (const char *pp, const char *end, uint32_t *pv)
**/
hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
- const char *buf,
- int buf_len, /* -1 means nul-terminated */
- const char **end_ptr, /* May be NULL */
- hb_font_t *font, /* May be NULL */
- hb_buffer_serialize_format_t format)
+ const char *buf,
+ int buf_len, /* -1 means nul-terminated */
+ const char **end_ptr, /* May be NULL */
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format)
{
const char *end;
if (!end_ptr)
end_ptr = &end;
*end_ptr = buf;
- assert ((!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)) ||
- (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS));
+ buffer->assert_glyphs ();
+
+ if (unlikely (hb_object_is_immutable (buffer)))
+ {
+ if (end_ptr)
+ *end_ptr = buf;
+ return false;
+ }
if (buf_len == -1)
buf_len = strlen (buf);
@@ -454,14 +775,82 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
- return _hb_buffer_deserialize_glyphs_text (buffer,
- buf, buf_len, end_ptr,
- font);
+ return _hb_buffer_deserialize_text (buffer,
+ buf, buf_len, end_ptr,
+ font);
+
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON:
+ return _hb_buffer_deserialize_json (buffer,
+ buf, buf_len, end_ptr,
+ font);
+
+ default:
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
+ return false;
+
+ }
+}
+
+
+/**
+ * hb_buffer_deserialize_unicode:
+ * @buffer: an #hb_buffer_t buffer.
+ * @buf: (array length=buf_len):
+ * @buf_len:
+ * @end_ptr: (out):
+ * @format:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 2.7.3
+ **/
+hb_bool_t
+hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
+ const char *buf,
+ int buf_len, /* -1 means nul-terminated */
+ const char **end_ptr, /* May be NULL */
+ hb_buffer_serialize_format_t format)
+{
+ const char *end;
+ if (!end_ptr)
+ end_ptr = &end;
+ *end_ptr = buf;
+
+ buffer->assert_unicode ();
+
+ if (unlikely (hb_object_is_immutable (buffer)))
+ {
+ if (end_ptr)
+ *end_ptr = buf;
+ return false;
+ }
+
+ if (buf_len == -1)
+ buf_len = strlen (buf);
+
+ if (!buf_len)
+ {
+ *end_ptr = buf;
+ return false;
+ }
+
+ hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
+
+ hb_font_t* font = hb_font_get_empty ();
+
+ switch (format)
+ {
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
+ return _hb_buffer_deserialize_text (buffer,
+ buf, buf_len, end_ptr,
+ font);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
- return _hb_buffer_deserialize_glyphs_json (buffer,
- buf, buf_len, end_ptr,
- font);
+ return _hb_buffer_deserialize_json (buffer,
+ buf, buf_len, end_ptr,
+ font);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc
index 4fadbb78d2..10063db050 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer.cc
@@ -37,8 +37,9 @@
* @short_description: Input and output buffers
* @include: hb.h
*
- * Buffers serve dual role in HarfBuzz; they hold the input characters that are
- * passed to hb_shape(), and after shaping they hold the output glyphs.
+ * Buffers serve a dual role in HarfBuzz; before shaping, they hold
+ * the input characters that are passed to hb_shape(), and after
+ * shaping they hold the output glyphs.
**/
@@ -50,7 +51,7 @@
* Checks the equality of two #hb_segment_properties_t's.
*
* Return value:
- * %true if all properties of @a equal those of @b, false otherwise.
+ * %true if all properties of @a equal those of @b, %false otherwise.
*
* Since: 0.9.7
**/
@@ -617,8 +618,7 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en
void
hb_buffer_t::guess_segment_properties ()
{
- assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
- (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
+ assert_unicode ();
/* If script is set to INVALID, guess from buffer contents */
if (props.script == HB_SCRIPT_INVALID) {
@@ -706,9 +706,9 @@ hb_buffer_create ()
/**
* hb_buffer_get_empty:
*
+ * Fetches an empty #hb_buffer_t.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): The empty buffer
*
* Since: 0.9.2
**/
@@ -720,7 +720,7 @@ hb_buffer_get_empty ()
/**
* hb_buffer_reference: (skip)
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Increases the reference count on @buffer by one. This prevents @buffer from
* being destroyed until a matching call to hb_buffer_destroy() is made.
@@ -738,7 +738,7 @@ hb_buffer_reference (hb_buffer_t *buffer)
/**
* hb_buffer_destroy: (skip)
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Deallocate the @buffer.
* Decreases the reference count on @buffer by one. If the result is zero, then
@@ -765,15 +765,15 @@ hb_buffer_destroy (hb_buffer_t *buffer)
/**
* hb_buffer_set_user_data: (skip)
- * @buffer: an #hb_buffer_t.
- * @key:
- * @data:
- * @destroy:
- * @replace:
+ * @buffer: An #hb_buffer_t
+ * @key: The user-data key
+ * @data: A pointer to the user data
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
*
+ * Attaches a user-data key/data pair to the specified buffer.
*
- *
- * Return value:
+ * Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@@ -789,12 +789,13 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_get_user_data: (skip)
- * @buffer: an #hb_buffer_t.
- * @key:
+ * @buffer: An #hb_buffer_t
+ * @key: The user-data key to query
*
+ * Fetches the user data associated with the specified key,
+ * attached to the specified buffer.
*
- *
- * Return value:
+ * Return value: (transfer-none): A pointer to the user data
*
* Since: 0.9.2
**/
@@ -808,11 +809,11 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_set_content_type:
- * @buffer: an #hb_buffer_t.
- * @content_type: the type of buffer contents to set
+ * @buffer: An #hb_buffer_t
+ * @content_type: The type of buffer contents to set
*
- * Sets the type of @buffer contents, buffers are either empty, contain
- * characters (before shaping) or glyphs (the result of shaping).
+ * Sets the type of @buffer contents. Buffers are either empty, contain
+ * characters (before shaping), or contain glyphs (the result of shaping).
*
* Since: 0.9.5
**/
@@ -825,12 +826,13 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
/**
* hb_buffer_get_content_type:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
- * see hb_buffer_set_content_type().
+ * Fetches the type of @buffer contents. Buffers are either empty, contain
+ * characters (before shaping), or contain glyphs (the result of shaping).
*
* Return value:
- * The type of @buffer contents.
+ * The type of @buffer contents
*
* Since: 0.9.5
**/
@@ -843,10 +845,11 @@ hb_buffer_get_content_type (hb_buffer_t *buffer)
/**
* hb_buffer_set_unicode_funcs:
- * @buffer: an #hb_buffer_t.
- * @unicode_funcs:
- *
+ * @buffer: An #hb_buffer_t
+ * @unicode_funcs: The Unicode-functions structure
*
+ * Sets the Unicode-functions structure of a buffer to
+ * @unicode_funcs.
*
* Since: 0.9.2
**/
@@ -867,11 +870,11 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
/**
* hb_buffer_get_unicode_funcs:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
+ * Fetches the Unicode-functions structure of a buffer.
*
- *
- * Return value:
+ * Return value: The Unicode-functions structure
*
* Since: 0.9.2
**/
@@ -883,7 +886,7 @@ hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
/**
* hb_buffer_set_direction:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
* @direction: the #hb_direction_t of the @buffer
*
* Set the text flow direction of the buffer. No shaping can happen without
@@ -909,7 +912,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
/**
* hb_buffer_get_direction:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* See hb_buffer_set_direction()
*
@@ -926,8 +929,8 @@ hb_buffer_get_direction (hb_buffer_t *buffer)
/**
* hb_buffer_set_script:
- * @buffer: an #hb_buffer_t.
- * @script: an #hb_script_t to set.
+ * @buffer: An #hb_buffer_t
+ * @script: An #hb_script_t to set.
*
* Sets the script of @buffer to @script.
*
@@ -953,12 +956,12 @@ hb_buffer_set_script (hb_buffer_t *buffer,
/**
* hb_buffer_get_script:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
- * See hb_buffer_set_script().
+ * Fetches the script of @buffer.
*
* Return value:
- * The #hb_script_t of the @buffer.
+ * The #hb_script_t of the @buffer
*
* Since: 0.9.2
**/
@@ -970,8 +973,8 @@ hb_buffer_get_script (hb_buffer_t *buffer)
/**
* hb_buffer_set_language:
- * @buffer: an #hb_buffer_t.
- * @language: an hb_language_t to set.
+ * @buffer: An #hb_buffer_t
+ * @language: An hb_language_t to set
*
* Sets the language of @buffer to @language.
*
@@ -997,7 +1000,7 @@ hb_buffer_set_language (hb_buffer_t *buffer,
/**
* hb_buffer_get_language:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* See hb_buffer_set_language().
*
@@ -1014,8 +1017,8 @@ hb_buffer_get_language (hb_buffer_t *buffer)
/**
* hb_buffer_set_segment_properties:
- * @buffer: an #hb_buffer_t.
- * @props: an #hb_segment_properties_t to use.
+ * @buffer: An #hb_buffer_t
+ * @props: An #hb_segment_properties_t to use
*
* Sets the segment properties of the buffer, a shortcut for calling
* hb_buffer_set_direction(), hb_buffer_set_script() and
@@ -1035,8 +1038,8 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_get_segment_properties:
- * @buffer: an #hb_buffer_t.
- * @props: (out): the output #hb_segment_properties_t.
+ * @buffer: An #hb_buffer_t
+ * @props: (out): The output #hb_segment_properties_t
*
* Sets @props to the #hb_segment_properties_t of @buffer.
*
@@ -1052,8 +1055,8 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_set_flags:
- * @buffer: an #hb_buffer_t.
- * @flags: the buffer flags to set.
+ * @buffer: An #hb_buffer_t
+ * @flags: The buffer flags to set
*
* Sets @buffer flags to @flags. See #hb_buffer_flags_t.
*
@@ -1071,12 +1074,12 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
/**
* hb_buffer_get_flags:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
- * See hb_buffer_set_flags().
+ * Fetches the #hb_buffer_flags_t of @buffer.
*
* Return value:
- * The @buffer flags.
+ * The @buffer flags
*
* Since: 0.9.7
**/
@@ -1088,10 +1091,12 @@ hb_buffer_get_flags (hb_buffer_t *buffer)
/**
* hb_buffer_set_cluster_level:
- * @buffer: an #hb_buffer_t.
- * @cluster_level:
- *
+ * @buffer: An #hb_buffer_t
+ * @cluster_level: The cluster level to set on the buffer
*
+ * Sets the cluster level of a buffer. The #hb_buffer_cluster_level_t
+ * dictates one aspect of how HarfBuzz will treat non-base characters
+ * during shaping.
*
* Since: 0.9.42
**/
@@ -1107,11 +1112,13 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer,
/**
* hb_buffer_get_cluster_level:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
+ * Fetches the cluster level of a buffer. The #hb_buffer_cluster_level_t
+ * dictates one aspect of how HarfBuzz will treat non-base characters
+ * during shaping.
*
- *
- * Return value:
+ * Return value: The cluster level of @buffer
*
* Since: 0.9.42
**/
@@ -1124,7 +1131,7 @@ hb_buffer_get_cluster_level (hb_buffer_t *buffer)
/**
* hb_buffer_set_replacement_codepoint:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
* @replacement: the replacement #hb_codepoint_t
*
* Sets the #hb_codepoint_t that replaces invalid entries for a given encoding
@@ -1146,12 +1153,13 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
/**
* hb_buffer_get_replacement_codepoint:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
- * See hb_buffer_set_replacement_codepoint().
+ * Fetches the #hb_codepoint_t that replaces invalid entries for a given encoding
+ * when adding text to @buffer.
*
* Return value:
- * The @buffer replacement #hb_codepoint_t.
+ * The @buffer replacement #hb_codepoint_t
*
* Since: 0.9.31
**/
@@ -1164,7 +1172,7 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer)
/**
* hb_buffer_set_invisible_glyph:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
* @invisible: the invisible #hb_codepoint_t
*
* Sets the #hb_codepoint_t that replaces invisible characters in
@@ -1186,12 +1194,12 @@ hb_buffer_set_invisible_glyph (hb_buffer_t *buffer,
/**
* hb_buffer_get_invisible_glyph:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* See hb_buffer_set_invisible_glyph().
*
* Return value:
- * The @buffer invisible #hb_codepoint_t.
+ * The @buffer invisible #hb_codepoint_t
*
* Since: 2.0.0
**/
@@ -1204,7 +1212,7 @@ hb_buffer_get_invisible_glyph (hb_buffer_t *buffer)
/**
* hb_buffer_reset:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Resets the buffer to its initial status, as if it was just newly created
* with hb_buffer_create().
@@ -1219,7 +1227,7 @@ hb_buffer_reset (hb_buffer_t *buffer)
/**
* hb_buffer_clear_contents:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Similar to hb_buffer_reset(), but does not clear the Unicode functions and
* the replacement code point.
@@ -1234,13 +1242,13 @@ hb_buffer_clear_contents (hb_buffer_t *buffer)
/**
* hb_buffer_pre_allocate:
- * @buffer: an #hb_buffer_t.
- * @size: number of items to pre allocate.
+ * @buffer: An #hb_buffer_t
+ * @size: Number of items to pre allocate.
*
* Pre allocates memory for @buffer to fit at least @size number of items.
*
* Return value:
- * %true if @buffer memory allocation succeeded, %false otherwise.
+ * %true if @buffer memory allocation succeeded, %false otherwise
*
* Since: 0.9.2
**/
@@ -1252,7 +1260,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
/**
* hb_buffer_allocation_successful:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Check if allocating memory for the buffer succeeded.
*
@@ -1269,9 +1277,9 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer)
/**
* hb_buffer_add:
- * @buffer: an #hb_buffer_t.
- * @codepoint: a Unicode code point.
- * @cluster: the cluster value of @codepoint.
+ * @buffer: An #hb_buffer_t
+ * @codepoint: A Unicode code point.
+ * @cluster: The cluster value of @codepoint.
*
* Appends a character with the Unicode value of @codepoint to @buffer, and
* gives it the initial cluster value of @cluster. Clusters can be any thing
@@ -1295,8 +1303,8 @@ hb_buffer_add (hb_buffer_t *buffer,
/**
* hb_buffer_set_length:
- * @buffer: an #hb_buffer_t.
- * @length: the new length of @buffer.
+ * @buffer: An #hb_buffer_t
+ * @length: The new length of @buffer
*
* Similar to hb_buffer_pre_allocate(), but clears any new items added at the
* end.
@@ -1337,7 +1345,7 @@ hb_buffer_set_length (hb_buffer_t *buffer,
/**
* hb_buffer_get_length:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Returns the number of items in the buffer.
*
@@ -1355,8 +1363,8 @@ hb_buffer_get_length (hb_buffer_t *buffer)
/**
* hb_buffer_get_glyph_infos:
- * @buffer: an #hb_buffer_t.
- * @length: (out): output array length.
+ * @buffer: An #hb_buffer_t
+ * @length: (out): The output-array length.
*
* Returns @buffer glyph information array. Returned pointer
* is valid as long as @buffer contents are not modified.
@@ -1379,8 +1387,8 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
/**
* hb_buffer_get_glyph_positions:
- * @buffer: an #hb_buffer_t.
- * @length: (out): output length.
+ * @buffer: An #hb_buffer_t
+ * @length: (out): The output length
*
* Returns @buffer glyph position array. Returned pointer
* is valid as long as @buffer contents are not modified.
@@ -1405,13 +1413,32 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
}
/**
+ * hb_buffer_has_positions:
+ * @buffer: an #hb_buffer_t.
+ *
+ * Returns whether @buffer has glyph position data.
+ * A buffer gains position data when hb_buffer_get_glyph_positions() is called on it,
+ * and cleared of position data when hb_buffer_clear_contents() is called.
+ *
+ * Return value:
+ * %true if the @buffer has position array, %false otherwise.
+ *
+ * Since: 2.7.3
+ **/
+HB_EXTERN hb_bool_t
+hb_buffer_has_positions (hb_buffer_t *buffer)
+{
+ return buffer->have_positions;
+}
+
+/**
* hb_glyph_info_get_glyph_flags:
- * @info: a #hb_glyph_info_t.
+ * @info: a #hb_glyph_info_t
*
* Returns glyph flags encoded within a #hb_glyph_info_t.
*
* Return value:
- * The #hb_glyph_flags_t encoded within @info.
+ * The #hb_glyph_flags_t encoded within @info
*
* Since: 1.5.0
**/
@@ -1423,7 +1450,7 @@ hb_glyph_flags_t
/**
* hb_buffer_reverse:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Reverses buffer contents.
*
@@ -1437,11 +1464,11 @@ hb_buffer_reverse (hb_buffer_t *buffer)
/**
* hb_buffer_reverse_range:
- * @buffer: an #hb_buffer_t.
- * @start: start index.
- * @end: end index.
+ * @buffer: An #hb_buffer_t
+ * @start: start index
+ * @end: end index
*
- * Reverses buffer contents between start to end.
+ * Reverses buffer contents between @start and @end.
*
* Since: 0.9.41
**/
@@ -1454,7 +1481,7 @@ hb_buffer_reverse_range (hb_buffer_t *buffer,
/**
* hb_buffer_reverse_clusters:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Reverses buffer clusters. That is, the buffer contents are
* reversed, then each cluster (consecutive items having the
@@ -1470,7 +1497,7 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
/**
* hb_buffer_guess_segment_properties:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Sets unset buffer segment properties based on buffer Unicode
* contents. If buffer is not empty, it must have content type
@@ -1513,8 +1540,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
typedef typename utf_t::codepoint_t T;
const hb_codepoint_t replacement = buffer->replacement;
- assert ((buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
- (!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
+ buffer->assert_unicode ();
if (unlikely (hb_object_is_immutable (buffer)))
return;
@@ -1573,12 +1599,12 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf8:
- * @buffer: an #hb_buffer_t.
- * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
+ * @buffer: An #hb_buffer_t
+ * @text: (array length=text_length) (element-type uint8_t): An array of UTF-8
* characters to append.
- * @text_length: the length of the @text, or -1 if it is %NULL terminated.
- * @item_offset: the offset of the first character to add to the @buffer.
- * @item_length: the number of characters to add to the @buffer, or -1 for the
+ * @text_length: The length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: The offset of the first character to add to the @buffer.
+ * @item_length: The number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
*
* See hb_buffer_add_codepoints().
@@ -1600,12 +1626,12 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf16:
- * @buffer: an #hb_buffer_t.
- * @text: (array length=text_length): an array of UTF-16 characters to append.
- * @text_length: the length of the @text, or -1 if it is %NULL terminated.
- * @item_offset: the offset of the first character to add to the @buffer.
- * @item_length: the number of characters to add to the @buffer, or -1 for the
- * end of @text (assuming it is %NULL terminated).
+ * @buffer: An #hb_buffer_t
+ * @text: (array length=text_length): An array of UTF-16 characters to append
+ * @text_length: The length of the @text, or -1 if it is %NULL terminated
+ * @item_offset: The offset of the first character to add to the @buffer
+ * @item_length: The number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated)
*
* See hb_buffer_add_codepoints().
*
@@ -1626,12 +1652,12 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf32:
- * @buffer: an #hb_buffer_t.
- * @text: (array length=text_length): an array of UTF-32 characters to append.
- * @text_length: the length of the @text, or -1 if it is %NULL terminated.
- * @item_offset: the offset of the first character to add to the @buffer.
- * @item_length: the number of characters to add to the @buffer, or -1 for the
- * end of @text (assuming it is %NULL terminated).
+ * @buffer: An #hb_buffer_t
+ * @text: (array length=text_length): An array of UTF-32 characters to append
+ * @text_length: The length of the @text, or -1 if it is %NULL terminated
+ * @item_offset: The offset of the first character to add to the @buffer
+ * @item_length: The number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated)
*
* See hb_buffer_add_codepoints().
*
@@ -1652,13 +1678,13 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
/**
* hb_buffer_add_latin1:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
* @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
- * characters to append.
- * @text_length: the length of the @text, or -1 if it is %NULL terminated.
- * @item_offset: the offset of the first character to add to the @buffer.
+ * characters to append
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated
+ * @item_offset: the offset of the first character to add to the @buffer
* @item_length: the number of characters to add to the @buffer, or -1 for the
- * end of @text (assuming it is %NULL terminated).
+ * end of @text (assuming it is %NULL terminated)
*
* Similar to hb_buffer_add_codepoints(), but allows only access to first 256
* Unicode code points that can fit in 8-bit strings.
@@ -1714,8 +1740,8 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
/**
* hb_buffer_append:
- * @buffer: an #hb_buffer_t.
- * @source: source #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
+ * @source: source #hb_buffer_t
* @start: start index into source buffer to copy. Use 0 to copy from start of buffer.
* @end: end index into source buffer to copy. Use @HB_FEATURE_GLOBAL_END to copy to end of buffer.
*
@@ -1821,7 +1847,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
/**
* hb_buffer_normalize_glyphs:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
*
* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
* The resulting clusters should behave identical to pre-reordering clusters.
@@ -1834,8 +1860,8 @@ void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
{
assert (buffer->have_positions);
- assert ((buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) ||
- (!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
+
+ buffer->assert_glyphs ();
bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
@@ -1967,7 +1993,7 @@ hb_buffer_diff (hb_buffer_t *buffer,
#ifndef HB_NO_BUFFER_MESSAGE
/**
* hb_buffer_set_message_func:
- * @buffer: an #hb_buffer_t.
+ * @buffer: An #hb_buffer_t
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h
index 2f581f3c73..b13757e68f 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.h
+++ b/thirdparty/harfbuzz/src/hb-buffer.h
@@ -59,8 +59,7 @@ HB_BEGIN_DECLS
* The #hb_glyph_info_t is the structure that holds information about the
* glyphs and their relation to input text.
*/
-typedef struct hb_glyph_info_t
-{
+typedef struct hb_glyph_info_t {
hb_codepoint_t codepoint;
/*< private >*/
hb_mask_t mask;
@@ -315,6 +314,23 @@ hb_buffer_get_flags (hb_buffer_t *buffer);
* @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values.
* @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level,
* equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES.
+ *
+ * Data type for holding HarfBuzz's clustering behavior options. The cluster level
+ * dictates one aspect of how HarfBuzz will treat non-base characters
+ * during shaping.
+ *
+ * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES, non-base
+ * characters are merged into the cluster of the base character that precedes them.
+ *
+ * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, non-base characters are initially
+ * assigned their own cluster values, which are not merged into preceding base
+ * clusters. This allows HarfBuzz to perform additional operations like reorder
+ * sequences of adjacent marks.
+ *
+ * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES is the default, because it maintains
+ * backward compatibility with older versions of HarfBuzz. New client programs that
+ * do not need to maintain such backward compatibility are recommended to use
+ * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS instead of the default.
*
* Since: 0.9.42
*/
@@ -447,6 +463,9 @@ HB_EXTERN hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
unsigned int *length);
+HB_EXTERN hb_bool_t
+hb_buffer_has_positions (hb_buffer_t *buffer);
+
HB_EXTERN void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
@@ -518,6 +537,27 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags);
+HB_EXTERN unsigned int
+hb_buffer_serialize_unicode (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags);
+
+HB_EXTERN unsigned int
+hb_buffer_serialize (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags);
+
HB_EXTERN hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf,
@@ -526,6 +566,14 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
hb_font_t *font,
hb_buffer_serialize_format_t format);
+HB_EXTERN hb_bool_t
+hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
+ const char *buf,
+ int buf_len,
+ const char **end_ptr,
+ hb_buffer_serialize_format_t format);
+
+
/*
* Compare buffers
diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh
index 3420ba434a..9cad5206e2 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.hh
+++ b/thirdparty/harfbuzz/src/hb-buffer.hh
@@ -35,20 +35,20 @@
#ifndef HB_BUFFER_MAX_LEN_FACTOR
-#define HB_BUFFER_MAX_LEN_FACTOR 32
+#define HB_BUFFER_MAX_LEN_FACTOR 64
#endif
#ifndef HB_BUFFER_MAX_LEN_MIN
-#define HB_BUFFER_MAX_LEN_MIN 8192
+#define HB_BUFFER_MAX_LEN_MIN 16384
#endif
#ifndef HB_BUFFER_MAX_LEN_DEFAULT
#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
#endif
#ifndef HB_BUFFER_MAX_OPS_FACTOR
-#define HB_BUFFER_MAX_OPS_FACTOR 64
+#define HB_BUFFER_MAX_OPS_FACTOR 1024
#endif
#ifndef HB_BUFFER_MAX_OPS_MIN
-#define HB_BUFFER_MAX_OPS_MIN 1024
+#define HB_BUFFER_MAX_OPS_MIN 16384
#endif
#ifndef HB_BUFFER_MAX_OPS_DEFAULT
#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
@@ -339,6 +339,39 @@ struct hb_buffer_t
bool ensure_inplace (unsigned int size)
{ return likely (!size || size < allocated); }
+ void assert_glyphs ()
+ {
+ assert ((content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) ||
+ (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
+ }
+ void assert_unicode ()
+ {
+ assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
+ (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
+ }
+ bool ensure_glyphs ()
+ {
+ if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
+ {
+ if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
+ return false;
+ assert (len == 0);
+ content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+ }
+ return true;
+ }
+ bool ensure_unicode ()
+ {
+ if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
+ {
+ if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
+ return false;
+ assert (len == 0);
+ content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
+ }
+ return true;
+ }
+
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
HB_INTERNAL bool shift_forward (unsigned int count);
diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc
index 5acfa78431..ddbcaa064c 100644
--- a/thirdparty/harfbuzz/src/hb-common.cc
+++ b/thirdparty/harfbuzz/src/hb-common.cc
@@ -86,12 +86,15 @@ _hb_options_init ()
/**
* hb_tag_from_string:
- * @str: (array length=len) (element-type uint8_t):
- * @len:
+ * @str: (array length=len) (element-type uint8_t): String to convert
+ * @len: Length of @str, or -1 if it is %NULL-terminated
*
+ * Converts a string into an #hb_tag_t. Valid tags
+ * are four characters. Shorter input strings will be
+ * padded with spaces. Longer input strings will be
+ * truncated.
*
- *
- * Return value:
+ * Return value: The #hb_tag_t corresponding to @str
*
* Since: 0.9.2
**/
@@ -116,10 +119,11 @@ hb_tag_from_string (const char *str, int len)
/**
* hb_tag_to_string:
- * @tag:
- * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t):
- *
+ * @tag: #hb_tag_t to convert
+ * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): Converted string
*
+ * Converts an #hb_tag_t to a string and returns it in @buf.
+ * Strings will be four characters long.
*
* Since: 0.9.5
**/
@@ -144,12 +148,17 @@ const char direction_strings[][4] = {
/**
* hb_direction_from_string:
- * @str: (array length=len) (element-type uint8_t):
- * @len:
+ * @str: (array length=len) (element-type uint8_t): String to convert
+ * @len: Length of @str, or -1 if it is %NULL-terminated
*
+ * Converts a string to an #hb_direction_t.
*
+ * Matching is loose and applies only to the first letter. For
+ * examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR.
*
- * Return value:
+ * Unmatched strings will return #HB_DIRECTION_INVALID.
+ *
+ * Return value: The #hb_direction_t matching @str
*
* Since: 0.9.2
**/
@@ -172,11 +181,11 @@ hb_direction_from_string (const char *str, int len)
/**
* hb_direction_to_string:
- * @direction:
- *
+ * @direction: The #hb_direction_t to convert
*
+ * Converts an #hb_direction_t to a string.
*
- * Return value: (transfer none):
+ * Return value: (transfer none): The string corresponding to @direction
*
* Since: 0.9.2
**/
@@ -367,9 +376,9 @@ hb_language_from_string (const char *str, int len)
/**
* hb_language_to_string:
- * @language: an #hb_language_t to convert.
+ * @language: The #hb_language_t to convert
*
- * See hb_language_from_string().
+ * Converts an #hb_language_t to a string.
*
* Return value: (transfer none):
* A %NULL-terminated string representing the @language. Must not be freed by
@@ -388,16 +397,17 @@ hb_language_to_string (hb_language_t language)
/**
* hb_language_get_default:
*
- * Get default language from current locale.
+ * Fetch the default language from current locale.
*
- * Note that the first time this function is called, it calls
+ * <note>Note that the first time this function is called, it calls
* "setlocale (LC_CTYPE, nullptr)" to fetch current locale. The underlying
* setlocale function is, in many implementations, NOT threadsafe. To avoid
* problems, call this function once before multiple threads can call it.
* This function is only used from hb_buffer_guess_segment_properties() by
- * HarfBuzz itself.
+ * HarfBuzz itself.</note>
*
- * Return value: (transfer none):
+ * Return value: (transfer none): The default language of the locale as
+ * an #hb_language_t
*
* Since: 0.9.2
**/
@@ -448,7 +458,12 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
/* Script variants from https://unicode.org/iso15924/ */
+ case HB_TAG('A','r','a','n'): return HB_SCRIPT_ARABIC;
case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
+ case HB_TAG('G','e','o','k'): return HB_SCRIPT_GEORGIAN;
+ case HB_TAG('H','a','n','s'): return HB_SCRIPT_HAN;
+ case HB_TAG('H','a','n','t'): return HB_SCRIPT_HAN;
+ case HB_TAG('J','a','m','o'): return HB_SCRIPT_HANGUL;
case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
@@ -489,7 +504,7 @@ hb_script_from_string (const char *str, int len)
* hb_script_to_iso15924_tag:
* @script: an #hb_script_t to convert.
*
- * See hb_script_from_iso15924_tag().
+ * Converts an #hb_script_t to a corresponding ISO 15924 script tag.
*
* Return value:
* An #hb_tag_t representing an ISO 15924 script tag.
@@ -504,11 +519,16 @@ hb_script_to_iso15924_tag (hb_script_t script)
/**
* hb_script_get_horizontal_direction:
- * @script:
- *
+ * @script: The #hb_script_t to query
*
+ * Fetches the #hb_direction_t of a script when it is
+ * set horizontally. All right-to-left scripts will return
+ * #HB_DIRECTION_RTL. All left-to-right scripts will return
+ * #HB_DIRECTION_LTR. Scripts that can be written either
+ * horizontally or vertically will return #HB_DIRECTION_INVALID.
+ * Unknown scripts will return #HB_DIRECTION_LTR.
*
- * Return value:
+ * Return value: The horizontal #hb_direction_t of @script
*
* Since: 0.9.2
**/
@@ -613,9 +633,9 @@ hb_script_get_horizontal_direction (hb_script_t script)
/**
* hb_version:
- * @major: (out): Library major version component.
- * @minor: (out): Library minor version component.
- * @micro: (out): Library micro version component.
+ * @major: (out): Library major version component
+ * @minor: (out): Library minor version component
+ * @micro: (out): Library micro version component
*
* Returns library version as three integer components.
*
@@ -636,7 +656,7 @@ hb_version (unsigned int *major,
*
* Returns library version as a string with three components.
*
- * Return value: library version string.
+ * Return value: Library version string
*
* Since: 0.9.2
**/
@@ -648,13 +668,15 @@ hb_version_string ()
/**
* hb_version_atleast:
- * @major:
- * @minor:
- * @micro:
+ * @major: Library major version component
+ * @minor: Library minor version component
+ * @micro: Library micro version component
*
+ * Tests the library version against a minimum value,
+ * as three integer components.
*
- *
- * Return value:
+ * Return value: True if the library is equal to or greater than
+ * the test value, false otherwise
*
* Since: 0.9.30
**/
@@ -883,7 +905,7 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
* </informaltable>
*
* Return value:
- * %true if @str is successfully parsed, %false otherwise.
+ * %true if @str is successfully parsed, %false otherwise
*
* Since: 0.9.5
**/
diff --git a/thirdparty/harfbuzz/src/hb-common.h b/thirdparty/harfbuzz/src/hb-common.h
index a97a5f5a04..efe185cdfd 100644
--- a/thirdparty/harfbuzz/src/hb-common.h
+++ b/thirdparty/harfbuzz/src/hb-common.h
@@ -88,11 +88,37 @@ typedef unsigned __int64 uint64_t;
HB_BEGIN_DECLS
-
+/**
+ * hb_bool_t:
+ *
+ * Data type for booleans.
+ *
+ **/
typedef int hb_bool_t;
+/**
+ * hb_codepoint_t:
+ *
+ * Data type for holding Unicode codepoints. Also
+ * used to hold glyph IDs.
+ *
+ **/
typedef uint32_t hb_codepoint_t;
+/**
+ * hb_position_t:
+ *
+ * Data type for holding a single coordinate value.
+ * Contour points and other multi-dimensional data are
+ * stored as tuples of #hb_position_t's.
+ *
+ **/
typedef int32_t hb_position_t;
+/**
+ * hb_mask_t:
+ *
+ * Data type for bitmasks.
+ *
+ **/
typedef uint32_t hb_mask_t;
typedef union _hb_var_int_t {
@@ -107,9 +133,33 @@ typedef union _hb_var_int_t {
/* hb_tag_t */
+/**
+ * hb_tag_t:
+ *
+ * Data type for tag identifiers. Tags are four
+ * byte integers, each byte representing a character.
+ *
+ * Tags are used to identify tables, design-variation axes,
+ * scripts, languages, font features, and baselines with
+ * human-readable names.
+ *
+ **/
typedef uint32_t hb_tag_t;
+/**
+ * HB_TAG:
+ *
+ * Constructs an #hb_tag_t from four characters.
+ *
+ **/
#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint32_t)(c1)&0xFF)<<24)|(((uint32_t)(c2)&0xFF)<<16)|(((uint32_t)(c3)&0xFF)<<8)|((uint32_t)(c4)&0xFF)))
+
+/**
+ * HB_UNTAG:
+ *
+ * Extracts the characters from an #hb_tag_t.
+ *
+ **/
#define HB_UNTAG(tag) (uint8_t)(((tag)>>24)&0xFF), (uint8_t)(((tag)>>16)&0xFF), (uint8_t)(((tag)>>8)&0xFF), (uint8_t)((tag)&0xFF)
#define HB_TAG_NONE HB_TAG(0,0,0,0)
@@ -132,6 +182,13 @@ hb_tag_to_string (hb_tag_t tag, char *buf);
* @HB_DIRECTION_RTL: Text is set horizontally from right to left.
* @HB_DIRECTION_TTB: Text is set vertically from top to bottom.
* @HB_DIRECTION_BTT: Text is set vertically from bottom to top.
+ *
+ * The direction of a text segment or buffer.
+ *
+ * A segment can also be tested for horizontal or vertical
+ * orientation (irrespective of specific direction) with
+ * HB_DIRECTION_IS_HORIZONTAL() or HB_DIRECTION_IS_VERTICAL().
+ *
*/
typedef enum {
HB_DIRECTION_INVALID = 0,
@@ -148,12 +205,59 @@ hb_direction_from_string (const char *str, int len);
HB_EXTERN const char *
hb_direction_to_string (hb_direction_t direction);
+/**
+ * HB_DIRECTION_IS_VALID:
+ * @dir: #hb_direction_t to test
+ *
+ * Tests whether a text direction is valid.
+ *
+ **/
#define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
/* Direction must be valid for the following */
+/**
+ * HB_DIRECTION_IS_HORIZONTAL:
+ * @dir: #hb_direction_t to test
+ *
+ * Tests whether a text direction is horizontal. Requires
+ * that the direction be valid.
+ *
+ **/
#define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4)
+/**
+ * HB_DIRECTION_IS_VERTICAL:
+ * @dir: #hb_direction_t to test
+ *
+ * Tests whether a text direction is vertical. Requires
+ * that the direction be valid.
+ *
+ **/
#define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6)
+/**
+ * HB_DIRECTION_IS_FORWARD:
+ * @dir: #hb_direction_t to test
+ *
+ * Tests whether a text direction moves forward (from left to right, or from
+ * top to bottom). Requires that the direction be valid.
+ *
+ **/
#define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4)
+/**
+ * HB_DIRECTION_IS_BACKWARD:
+ * @dir: #hb_direction_t to test
+ *
+ * Tests whether a text direction moves backward (from right to left, or from
+ * bottom to top). Requires that the direction be valid.
+ *
+ **/
#define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5)
+/**
+ * HB_DIRECTION_REVERSE:
+ * @dir: #hb_direction_t to reverse
+ *
+ * Reverses a text direction. Requires that the direction
+ * be valid.
+ *
+ **/
#define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1))
@@ -173,7 +277,169 @@ HB_EXTERN hb_language_t
hb_language_get_default (void);
-/* hb_script_t */
+/**
+ * hb_script_t:
+ * @HB_SCRIPT_COMMON: HB_TAG ('Z','y','y','y')
+ * @HB_SCRIPT_INHERITED: HB_TAG ('Z','i','n','h')
+ * @HB_SCRIPT_UNKNOWN: HB_TAG ('Z','z','z','z')
+ * @HB_SCRIPT_ARABIC
+ * @HB_SCRIPT_ARMENIAN
+ * @HB_SCRIPT_BENGALI
+ * @HB_SCRIPT_CYRILLIC
+ * @HB_SCRIPT_DEVANAGARI
+ * @HB_SCRIPT_GEORGIAN
+ * @HB_SCRIPT_GREEK
+ * @HB_SCRIPT_GUJARATI
+ * @HB_SCRIPT_GURMUKHI
+ * @HB_SCRIPT_HANGUL
+ * @HB_SCRIPT_HAN
+ * @HB_SCRIPT_HEBREW
+ * @HB_SCRIPT_HIRAGANA
+ * @HB_SCRIPT_KANNADA
+ * @HB_SCRIPT_KATAKANA
+ * @HB_SCRIPT_LAO
+ * @HB_SCRIPT_LATIN
+ * @HB_SCRIPT_MALAYALAM
+ * @HB_SCRIPT_ORIYA
+ * @HB_SCRIPT_TAMIL
+ * @HB_SCRIPT_TELUGU
+ * @HB_SCRIPT_THAI
+ * @HB_SCRIPT_TIBETAN
+ * @HB_SCRIPT_BOPOMOFO
+ * @HB_SCRIPT_BRAILLE
+ * @HB_SCRIPT_CANADIAN_SYLLABICS
+ * @HB_SCRIPT_CHEROKEE
+ * @HB_SCRIPT_ETHIOPIC
+ * @HB_SCRIPT_KHMER
+ * @HB_SCRIPT_MONGOLIAN
+ * @HB_SCRIPT_MYANMAR
+ * @HB_SCRIPT_OGHAM
+ * @HB_SCRIPT_RUNIC
+ * @HB_SCRIPT_SINHALA
+ * @HB_SCRIPT_SYRIAC
+ * @HB_SCRIPT_THAANA
+ * @HB_SCRIPT_YI
+ * @HB_SCRIPT_DESERET
+ * @HB_SCRIPT_GOTHIC
+ * @HB_SCRIPT_OLD_ITALIC
+ * @HB_SCRIPT_BUHID
+ * @HB_SCRIPT_HANUNOO
+ * @HB_SCRIPT_TAGALOG
+ * @HB_SCRIPT_TAGBANWA
+ * @HB_SCRIPT_CYPRIOT
+ * @HB_SCRIPT_LIMBU
+ * @HB_SCRIPT_LINEAR_B
+ * @HB_SCRIPT_OSMANYA
+ * @HB_SCRIPT_SHAVIAN
+ * @HB_SCRIPT_TAI_LE
+ * @HB_SCRIPT_UGARITIC
+ * @HB_SCRIPT_BUGINESE
+ * @HB_SCRIPT_COPTIC
+ * @HB_SCRIPT_GLAGOLITIC
+ * @HB_SCRIPT_KHAROSHTHI
+ * @HB_SCRIPT_NEW_TAI_LUE
+ * @HB_SCRIPT_OLD_PERSIAN
+ * @HB_SCRIPT_SYLOTI_NAGRI
+ * @HB_SCRIPT_TIFINAGH
+ * @HB_SCRIPT_BALINESE
+ * @HB_SCRIPT_CUNEIFORM
+ * @HB_SCRIPT_NKO
+ * @HB_SCRIPT_PHAGS_PA
+ * @HB_SCRIPT_PHOENICIAN
+ * @HB_SCRIPT_CARIAN
+ * @HB_SCRIPT_CHAM
+ * @HB_SCRIPT_KAYAH_LI
+ * @HB_SCRIPT_LEPCHA
+ * @HB_SCRIPT_LYCIAN
+ * @HB_SCRIPT_LYDIAN
+ * @HB_SCRIPT_OL_CHIKI
+ * @HB_SCRIPT_REJANG
+ * @HB_SCRIPT_SAURASHTRA
+ * @HB_SCRIPT_SUNDANESE
+ * @HB_SCRIPT_VAI
+ * @HB_SCRIPT_AVESTAN
+ * @HB_SCRIPT_BAMUM
+ * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS
+ * @HB_SCRIPT_IMPERIAL_ARAMAIC
+ * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI
+ * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN
+ * @HB_SCRIPT_JAVANESE
+ * @HB_SCRIPT_KAITHI
+ * @HB_SCRIPT_LISU
+ * @HB_SCRIPT_MEETEI_MAYEK
+ * @HB_SCRIPT_OLD_SOUTH_ARABIAN
+ * @HB_SCRIPT_OLD_TURKIC
+ * @HB_SCRIPT_SAMARITAN
+ * @HB_SCRIPT_TAI_THAM
+ * @HB_SCRIPT_TAI_VIET
+ * @HB_SCRIPT_BATAK
+ * @HB_SCRIPT_BRAHMI
+ * @HB_SCRIPT_MANDAIC
+ * @HB_SCRIPT_CHAKMA
+ * @HB_SCRIPT_MEROITIC_CURSIVE
+ * @HB_SCRIPT_MEROITIC_HIEROGLYPHS
+ * @HB_SCRIPT_MIAO
+ * @HB_SCRIPT_SHARADA
+ * @HB_SCRIPT_SORA_SOMPENG
+ * @HB_SCRIPT_TAKRI
+ * @HB_SCRIPT_BASSA_VAH
+ * @HB_SCRIPT_CAUCASIAN_ALBANIAN
+ * @HB_SCRIPT_DUPLOYAN
+ * @HB_SCRIPT_ELBASAN
+ * @HB_SCRIPT_GRANTHA
+ * @HB_SCRIPT_KHOJKI
+ * @HB_SCRIPT_KHUDAWADI
+ * @HB_SCRIPT_LINEAR_A
+ * @HB_SCRIPT_MAHAJANI
+ * @HB_SCRIPT_MANICHAEAN
+ * @HB_SCRIPT_MENDE_KIKAKUI
+ * @HB_SCRIPT_MODI
+ * @HB_SCRIPT_MRO
+ * @HB_SCRIPT_NABATAEAN
+ * @HB_SCRIPT_OLD_NORTH_ARABIAN
+ * @HB_SCRIPT_OLD_PERMIC
+ * @HB_SCRIPT_PAHAWH_HMONG
+ * @HB_SCRIPT_PALMYRENE
+ * @HB_SCRIPT_PAU_CIN_HAU
+ * @HB_SCRIPT_PSALTER_PAHLAVI
+ * @HB_SCRIPT_SIDDHAM
+ * @HB_SCRIPT_TIRHUTA
+ * @HB_SCRIPT_WARANG_CITI
+ * @HB_SCRIPT_AHOM
+ * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS
+ * @HB_SCRIPT_HATRAN
+ * @HB_SCRIPT_MULTANI
+ * @HB_SCRIPT_OLD_HUNGARIAN
+ * @HB_SCRIPT_SIGNWRITING
+ * @HB_SCRIPT_ADLAM
+ * @HB_SCRIPT_BHAIKSUKI
+ * @HB_SCRIPT_MARCHEN
+ * @HB_SCRIPT_OSAGE
+ * @HB_SCRIPT_TANGUT
+ * @HB_SCRIPT_NEWA
+ * @HB_SCRIPT_MASARAM_GONDI
+ * @HB_SCRIPT_NUSHU
+ * @HB_SCRIPT_SOYOMBO
+ * @HB_SCRIPT_ZANABAZAR_SQUARE
+ * @HB_SCRIPT_DOGRA
+ * @HB_SCRIPT_GUNJALA_GONDI
+ * @HB_SCRIPT_HANIFI_ROHINGYA
+ * @HB_SCRIPT_MAKASAR
+ * @HB_SCRIPT_MEDEFAIDRIN
+ * @HB_SCRIPT_OLD_SOGDIAN
+ * @HB_SCRIPT_SOGDIAN
+ * @HB_SCRIPT_ELYMAIC
+ * @HB_SCRIPT_NANDINAGARI
+ * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG
+ * @HB_SCRIPT_WANCHO
+ * @HB_SCRIPT_INVALID: #HB_TAG_NONE
+ *
+ * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding
+ * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/).
+ *
+ * See also the Script (sc) property of the Unicode Character Database.
+ *
+ **/
/* https://unicode.org/iso15924/ */
/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */
@@ -410,6 +676,12 @@ hb_script_get_horizontal_direction (hb_script_t script);
/* User data */
+/**
+ * hb_user_data_key_t:
+ *
+ * Data structure for holding user-data keys.
+ *
+ **/
typedef struct hb_user_data_key_t {
/*< private >*/
char unused;
@@ -435,10 +707,10 @@ typedef void (*hb_destroy_func_t) (void *user_data);
/**
* hb_feature_t:
- * @tag: a feature tag
- * @value: 0 disables the feature, non-zero (usually 1) enables the feature.
- * For features implemented as lookup type 3 (like 'salt') the @value is a one
- * based index into the alternates.
+ * @tag: The #hb_tag_t tag of the feature
+ * @value: The value of the feature. 0 disables the feature, non-zero (usually
+ * 1) enables the feature. For features implemented as lookup type 3 (like
+ * 'salt') the @value is a one based index into the alternates.
* @start: the cluster to start applying this feature setting (inclusive).
* @end: the cluster to end applying this feature setting (exclusive).
*
@@ -465,7 +737,13 @@ hb_feature_to_string (hb_feature_t *feature,
/**
* hb_variation_t:
+ * @tag: The #hb_tag_t tag of the variation-axis name
+ * @value: The value of the variation axis
*
+ * Data type for holding variation data. Registered OpenType
+ * variation-axis tags are listed at
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg
+ *
* Since: 1.4.2
*/
typedef struct hb_variation_t {
@@ -484,7 +762,8 @@ hb_variation_to_string (hb_variation_t *variation,
/**
* hb_color_t:
*
- * Data type for holding color values.
+ * Data type for holding color values. Colors are eight bits per
+ * channel RGB plus alpha transparency.
*
* Since: 2.1.0
*/
diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc
index f2fce073e0..92c956c032 100644
--- a/thirdparty/harfbuzz/src/hb-directwrite.cc
+++ b/thirdparty/harfbuzz/src/hb-directwrite.cc
@@ -33,6 +33,15 @@
#include "hb-directwrite.h"
+/**
+ * SECTION:hb-directwrite
+ * @title: hb-directwrite
+ * @short_description: DirectWrite integration
+ * @include: hb-directwrite.h
+ *
+ * Functions for using HarfBuzz with DirectWrite fonts.
+ **/
+
/* Declare object creator for dynamic support of DWRITE */
typedef HRESULT (* WINAPI t_DWriteCreateFactory)(
DWRITE_FACTORY_TYPE factoryType,
diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc
index 7bde50df5b..33a788e7c5 100644
--- a/thirdparty/harfbuzz/src/hb-face.cc
+++ b/thirdparty/harfbuzz/src/hb-face.cc
@@ -41,8 +41,10 @@
* @short_description: Font face objects
* @include: hb.h
*
- * Font face is objects represent a single face in a font family.
- * More exactly, a font face represents a single face in a binary font file.
+ * A font face is an object that represents a single face from within a
+ * font family.
+ *
+ * More precisely, a font face represents a single face in a binary font file.
* Font faces are typically built from a binary blob and a face index.
* Font faces are used to create fonts.
**/
@@ -52,7 +54,7 @@
* hb_face_count:
* @blob: a blob.
*
- * Get number of faces in a blob.
+ * Fetches the number of faces in a blob.
*
* Return value: Number of faces in @blob
*
@@ -96,13 +98,19 @@ DEFINE_NULL_INSTANCE (hb_face_t) =
/**
* hb_face_create_for_tables:
- * @reference_table_func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): Table-referencing function
+ * @user_data: A pointer to the user data
+ * @destroy: (optional): A callback to call when @data is not needed anymore
*
+ * Variant of hb_face_create(), built for those cases where it is more
+ * convenient to provide data for individual tables instead of the whole font
+ * data. With the caveat that hb_face_get_table_tags() does not currently work
+ * with faces created this way.
+ *
+ * Creates a new face object from the specified @user_data and @reference_table_func,
+ * with the @destroy callback.
*
- * Return value: (transfer full)
+ * Return value: (transfer full): The new face object
*
* Since: 0.9.2
**/
@@ -182,12 +190,15 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
/**
* hb_face_create: (Xconstructor)
- * @blob:
- * @index:
- *
+ * @blob: #hb_blob_t to work upon
+ * @index: The index of the face within @blob
*
+ * Constructs a new face object from the specified blob and
+ * a face index into that blob. This is used for blobs of
+ * file formats such as Dfont and TTC that can contain more
+ * than one face.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): The new face object
*
* Since: 0.9.2
**/
@@ -222,9 +233,9 @@ hb_face_create (hb_blob_t *blob,
/**
* hb_face_get_empty:
*
+ * Fetches the singleton empty face object.
*
- *
- * Return value: (transfer full)
+ * Return value: (transfer full) The empty face object
*
* Since: 0.9.2
**/
@@ -237,11 +248,11 @@ hb_face_get_empty ()
/**
* hb_face_reference: (skip)
- * @face: a face.
- *
+ * @face: A face object
*
+ * Increases the reference count on a face object.
*
- * Return value:
+ * Return value: The @face object
*
* Since: 0.9.2
**/
@@ -253,9 +264,11 @@ hb_face_reference (hb_face_t *face)
/**
* hb_face_destroy: (skip)
- * @face: a face.
- *
- *
+ * @face: A face object
+ *
+ * Decreases the reference count on a face object. When the
+ * reference count reaches zero, the face is destroyed,
+ * freeing all memory.
*
* Since: 0.9.2
**/
@@ -283,15 +296,15 @@ hb_face_destroy (hb_face_t *face)
/**
* hb_face_set_user_data: (skip)
- * @face: a face.
- * @key:
- * @data:
- * @destroy:
- * @replace:
- *
+ * @face: A face object
+ * @key: The user-data key to set
+ * @data: A pointer to the user data
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
*
+ * Attaches a user-data key/data pair to the given face object.
*
- * Return value:
+ * Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@@ -307,12 +320,13 @@ hb_face_set_user_data (hb_face_t *face,
/**
* hb_face_get_user_data: (skip)
- * @face: a face.
- * @key:
+ * @face: A face object
+ * @key: The user-data key to query
*
+ * Fetches the user data associated with the specified key,
+ * attached to the specified face object.
*
- *
- * Return value: (transfer none):
+ * Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@@ -325,9 +339,9 @@ hb_face_get_user_data (const hb_face_t *face,
/**
* hb_face_make_immutable:
- * @face: a face.
- *
+ * @face: A face object
*
+ * Makes the given face object immutable.
*
* Since: 0.9.2
**/
@@ -342,11 +356,11 @@ hb_face_make_immutable (hb_face_t *face)
/**
* hb_face_is_immutable:
- * @face: a face.
+ * @face: A face object
*
+ * Tests whether the given face object is immutable.
*
- *
- * Return value:
+ * Return value: True is @face is immutable, false otherwise
*
* Since: 0.9.2
**/
@@ -359,12 +373,13 @@ hb_face_is_immutable (const hb_face_t *face)
/**
* hb_face_reference_table:
- * @face: a face.
- * @tag:
- *
+ * @face: A face object
+ * @tag: The #hb_tag_t of the table to query
*
+ * Fetches a reference to the specified table within
+ * the specified face.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): A pointer to the @tag table within @face
*
* Since: 0.9.2
**/
@@ -380,11 +395,13 @@ hb_face_reference_table (const hb_face_t *face,
/**
* hb_face_reference_blob:
- * @face: a face.
- *
+ * @face: A face object
*
+ * Fetches a pointer to the binary blob that contains the
+ * specified face. Returns an empty blob if referencing face data is not
+ * possible.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): A pointer to the blob for @face
*
* Since: 0.9.2
**/
@@ -396,10 +413,13 @@ hb_face_reference_blob (hb_face_t *face)
/**
* hb_face_set_index:
- * @face: a face.
- * @index:
+ * @face: A face object
+ * @index: The index to assign
*
+ * Assigns the specified face-index to @face. Fails if the
+ * face is immutable.
*
+ * <note>Note: face indices within a collection are zero-based.</note>
*
* Since: 0.9.2
**/
@@ -415,11 +435,13 @@ hb_face_set_index (hb_face_t *face,
/**
* hb_face_get_index:
- * @face: a face.
+ * @face: A face object
*
+ * Fetches the face-index corresponding to the given face.
*
+ * <note>Note: face indices within a collection are zero-based.</note>
*
- * Return value:
+ * Return value: The index of @face.
*
* Since: 0.9.2
**/
@@ -431,10 +453,10 @@ hb_face_get_index (const hb_face_t *face)
/**
* hb_face_set_upem:
- * @face: a face.
- * @upem:
- *
+ * @face: A face object
+ * @upem: The units-per-em value to assign
*
+ * Sets the units-per-em (upem) for a face object to the specified value.
*
* Since: 0.9.2
**/
@@ -450,11 +472,11 @@ hb_face_set_upem (hb_face_t *face,
/**
* hb_face_get_upem:
- * @face: a face.
- *
+ * @face: A face object
*
+ * Fetches the units-per-em (upem) value of the specified face object.
*
- * Return value:
+ * Return value: The upem value of @face
*
* Since: 0.9.2
**/
@@ -466,10 +488,10 @@ hb_face_get_upem (const hb_face_t *face)
/**
* hb_face_set_glyph_count:
- * @face: a face.
- * @glyph_count:
- *
+ * @face: A face object
+ * @glyph_count: The glyph-count value to assign
*
+ * Sets the glyph count for a face object to the specified value.
*
* Since: 0.9.7
**/
@@ -485,11 +507,11 @@ hb_face_set_glyph_count (hb_face_t *face,
/**
* hb_face_get_glyph_count:
- * @face: a face.
- *
+ * @face: A face object
*
+ * Fetches the glyph-count value of the specified face object.
*
- * Return value:
+ * Return value: The glyph-count value of @face
*
* Since: 0.9.7
**/
@@ -501,14 +523,16 @@ hb_face_get_glyph_count (const hb_face_t *face)
/**
* hb_face_get_table_tags:
- * @face: a face.
- * @start_offset: index of first tag to return.
- * @table_count: input length of @table_tags array, output number of items written.
- * @table_tags: array to write tags into.
+ * @face: A face object
+ * @start_offset: The index of first table tag to retrieve
+ * @table_count: (inout): Input = the maximum number of table tags to return;
+ * Output = the actual number of table tags returned (may be zero)
+ * @table_tags: (out) (array length=table_count): The array of table tags found
*
- * Retrieves table tags for a face, if possible.
+ * Fetches a list of all table tags for a face, if possible. The list returned will
+ * begin at the offset provided
*
- * Return value: total number of tables, or 0 if not possible to list.
+ * Return value: Total number of tables, or zero if it is not possible to list
*
* Since: 1.6.0
**/
@@ -542,8 +566,11 @@ hb_face_get_table_tags (const hb_face_t *face,
#ifndef HB_NO_FACE_COLLECT_UNICODES
/**
* hb_face_collect_unicodes:
- * @face: font face.
- * @out: set to add Unicode characters covered by @face to.
+ * @face: A face object
+ * @out: The set to add Unicode characters to
+ *
+ * Collects all of the Unicode characters covered by @face and adds
+ * them to the #hb_set_t set @out.
*
* Since: 1.9.0
*/
@@ -555,10 +582,11 @@ hb_face_collect_unicodes (hb_face_t *face,
}
/**
* hb_face_collect_variation_selectors:
- * @face: font face.
- * @out: set to add Variation Selector characters covered by @face to.
- *
+ * @face: A face object
+ * @out: The set to add Variation Selector characters to
*
+ * Collects all Unicode "Variation Selector" characters covered by @face and adds
+ * them to the #hb_set_t set @out.
*
* Since: 1.9.0
*/
@@ -570,10 +598,12 @@ hb_face_collect_variation_selectors (hb_face_t *face,
}
/**
* hb_face_collect_variation_unicodes:
- * @face: font face.
- * @out: set to add Unicode characters for @variation_selector covered by @face to.
- *
+ * @face: A face object
+ * @variation_selector: The Variation Selector to query
+ * @out: The set to add Unicode characters to
*
+ * Collects all Unicode characters for @variation_selector covered by @face and adds
+ * them to the #hb_set_t set @out.
*
* Since: 1.9.0
*/
@@ -708,6 +738,9 @@ hb_face_builder_create ()
/**
* hb_face_builder_add_table:
+ * @face: A face object created with hb_face_builder_create()
+ * @tag: The #hb_tag_t of the table to add
+ * @blob: The blob containing the table data to add
*
* Add table for @tag with data provided by @blob to the face. @face must
* be created using hb_face_builder_create().
diff --git a/thirdparty/harfbuzz/src/hb-face.h b/thirdparty/harfbuzz/src/hb-face.h
index e8ff090d55..3b18f7eef9 100644
--- a/thirdparty/harfbuzz/src/hb-face.h
+++ b/thirdparty/harfbuzz/src/hb-face.h
@@ -46,6 +46,12 @@ hb_face_count (hb_blob_t *blob);
* hb_face_t
*/
+/**
+ * hb_face_t:
+ *
+ * Data type for holding font faces.
+ *
+ **/
typedef struct hb_face_t hb_face_t;
HB_EXTERN hb_face_t *
diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc
index 27959487dc..5c8357ff28 100644
--- a/thirdparty/harfbuzz/src/hb-font.cc
+++ b/thirdparty/harfbuzz/src/hb-font.cc
@@ -43,10 +43,20 @@
* @short_description: Font objects
* @include: hb.h
*
- * Font objects represent a font face at a certain size and other
- * parameters (pixels per EM, points per EM, variation settings.)
- * Fonts are created from font faces, and are used as input to
- * hb_shape() among other things.
+ * Functions for working with font objects.
+ *
+ * A font object represents a font face at a specific size and with
+ * certain other parameters (pixels-per-em, points-per-em, variation
+ * settings) specified. Font objects are created from font face
+ * objects, and are used as input to hb_shape(), among other things.
+ *
+ * Client programs can optionally pass in their own functions that
+ * implement the basic, lower-level queries of font objects. This set
+ * of font functions is defined by the virtual methods in
+ * #hb_font_funcs_t.
+ *
+ * HarfBuzz provides a built-in set of lightweight default
+ * functions for each method in #hb_font_funcs_t.
**/
@@ -55,19 +65,20 @@
*/
static hb_bool_t
-hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
+hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
hb_font_extents_t *extents,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
memset (extents, 0, sizeof (*extents));
return false;
}
+
static hb_bool_t
-hb_font_get_font_h_extents_default (hb_font_t *font,
- void *font_data HB_UNUSED,
+hb_font_get_font_h_extents_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
hb_font_extents_t *extents,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_font_h_extents (extents);
if (ret) {
@@ -79,19 +90,20 @@ hb_font_get_font_h_extents_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
+hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
hb_font_extents_t *extents,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
memset (extents, 0, sizeof (*extents));
return false;
}
+
static hb_bool_t
-hb_font_get_font_v_extents_default (hb_font_t *font,
- void *font_data HB_UNUSED,
+hb_font_get_font_v_extents_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
hb_font_extents_t *extents,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_font_v_extents (extents);
if (ret) {
@@ -103,21 +115,22 @@ hb_font_get_font_v_extents_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
+hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
*glyph = 0;
return false;
}
+
static hb_bool_t
-hb_font_get_nominal_glyph_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t unicode,
+hb_font_get_nominal_glyph_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode,
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
if (font->has_nominal_glyphs_func_set ())
{
@@ -127,15 +140,16 @@ hb_font_get_nominal_glyph_default (hb_font_t *font,
}
#define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
+
static unsigned int
-hb_font_get_nominal_glyphs_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- unsigned int count,
+hb_font_get_nominal_glyphs_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ unsigned int count,
const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- void *user_data HB_UNUSED)
+ unsigned int unicode_stride,
+ hb_codepoint_t *first_glyph,
+ unsigned int glyph_stride,
+ void *user_data HB_UNUSED)
{
if (font->has_nominal_glyph_func_set ())
{
@@ -156,41 +170,43 @@ hb_font_get_nominal_glyphs_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
- hb_codepoint_t variation_selector HB_UNUSED,
+hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ hb_codepoint_t variation_selector HB_UNUSED,
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
*glyph = 0;
return false;
}
+
static hb_bool_t
-hb_font_get_variation_glyph_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
+hb_font_get_variation_glyph_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
}
static hb_position_t
-hb_font_get_glyph_h_advance_nil (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_advance_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph HB_UNUSED,
+ void *user_data HB_UNUSED)
{
return font->x_scale;
}
+
static hb_position_t
-hb_font_get_glyph_h_advance_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_advance_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ void *user_data HB_UNUSED)
{
if (font->has_glyph_h_advances_func_set ())
{
@@ -202,19 +218,20 @@ hb_font_get_glyph_h_advance_default (hb_font_t *font,
}
static hb_position_t
-hb_font_get_glyph_v_advance_nil (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_advance_nil (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph HB_UNUSED,
+ void *user_data HB_UNUSED)
{
/* TODO use font_extents.ascender+descender */
return font->y_scale;
}
+
static hb_position_t
-hb_font_get_glyph_v_advance_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_advance_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ void *user_data HB_UNUSED)
{
if (font->has_glyph_v_advances_func_set ())
{
@@ -226,15 +243,16 @@ hb_font_get_glyph_v_advance_default (hb_font_t *font,
}
#define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default
+
static void
-hb_font_get_glyph_h_advances_default (hb_font_t* font,
- void* font_data HB_UNUSED,
- unsigned int count,
+hb_font_get_glyph_h_advances_default (hb_font_t* font,
+ void* font_data HB_UNUSED,
+ unsigned int count,
const hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- hb_position_t *first_advance,
- unsigned int advance_stride,
- void *user_data HB_UNUSED)
+ unsigned int glyph_stride,
+ hb_position_t *first_advance,
+ unsigned int advance_stride,
+ void *user_data HB_UNUSED)
{
if (font->has_glyph_h_advance_func_set ())
{
@@ -259,14 +277,14 @@ hb_font_get_glyph_h_advances_default (hb_font_t* font,
#define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default
static void
-hb_font_get_glyph_v_advances_default (hb_font_t* font,
- void* font_data HB_UNUSED,
- unsigned int count,
+hb_font_get_glyph_v_advances_default (hb_font_t* font,
+ void* font_data HB_UNUSED,
+ unsigned int count,
const hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- hb_position_t *first_advance,
- unsigned int advance_stride,
- void *user_data HB_UNUSED)
+ unsigned int glyph_stride,
+ hb_position_t *first_advance,
+ unsigned int advance_stride,
+ void *user_data HB_UNUSED)
{
if (font->has_glyph_v_advance_func_set ())
{
@@ -290,23 +308,24 @@ hb_font_get_glyph_v_advances_default (hb_font_t* font,
}
static hb_bool_t
-hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph HB_UNUSED,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
*x = *y = 0;
return true;
}
+
static hb_bool_t
-hb_font_get_glyph_h_origin_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_origin_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
if (ret)
@@ -315,23 +334,24 @@ hb_font_get_glyph_h_origin_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph HB_UNUSED,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
*x = *y = 0;
return false;
}
+
static hb_bool_t
-hb_font_get_glyph_v_origin_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_origin_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
if (ret)
@@ -340,61 +360,64 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font,
}
static hb_position_t
-hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t left_glyph HB_UNUSED,
- hb_codepoint_t right_glyph HB_UNUSED,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t left_glyph HB_UNUSED,
+ hb_codepoint_t right_glyph HB_UNUSED,
+ void *user_data HB_UNUSED)
{
return 0;
}
+
static hb_position_t
-hb_font_get_glyph_h_kerning_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t left_glyph,
- hb_codepoint_t right_glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_kerning_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t left_glyph,
+ hb_codepoint_t right_glyph,
+ void *user_data HB_UNUSED)
{
return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
}
#ifndef HB_DISABLE_DEPRECATED
static hb_position_t
-hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t top_glyph HB_UNUSED,
- hb_codepoint_t bottom_glyph HB_UNUSED,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t top_glyph HB_UNUSED,
+ hb_codepoint_t bottom_glyph HB_UNUSED,
+ void *user_data HB_UNUSED)
{
return 0;
}
+
static hb_position_t
-hb_font_get_glyph_v_kerning_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t top_glyph,
- hb_codepoint_t bottom_glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_kerning_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t top_glyph,
+ hb_codepoint_t bottom_glyph,
+ void *user_data HB_UNUSED)
{
return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
}
#endif
static hb_bool_t
-hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
+hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph HB_UNUSED,
hb_glyph_extents_t *extents,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
memset (extents, 0, sizeof (*extents));
return false;
}
+
static hb_bool_t
-hb_font_get_glyph_extents_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
+hb_font_get_glyph_extents_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
if (ret) {
@@ -405,25 +428,26 @@ hb_font_get_glyph_extents_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- unsigned int point_index HB_UNUSED,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph HB_UNUSED,
+ unsigned int point_index HB_UNUSED,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
*x = *y = 0;
return false;
}
+
static hb_bool_t
-hb_font_get_glyph_contour_point_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- unsigned int point_index,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_contour_point_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ unsigned int point_index,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
if (ret)
@@ -432,42 +456,47 @@ hb_font_get_glyph_contour_point_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- char *name, unsigned int size,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph HB_UNUSED,
+ char *name,
+ unsigned int size,
+ void *user_data HB_UNUSED)
{
if (size) *name = '\0';
return false;
}
+
static hb_bool_t
-hb_font_get_glyph_name_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- char *name, unsigned int size,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_name_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ char *name,
+ unsigned int size,
+ void *user_data HB_UNUSED)
{
return font->parent->get_glyph_name (glyph, name, size);
}
static hb_bool_t
-hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- const char *name HB_UNUSED,
- int len HB_UNUSED, /* -1 means nul-terminated */
+hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ const char *name HB_UNUSED,
+ int len HB_UNUSED, /* -1 means nul-terminated */
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
*glyph = 0;
return false;
}
+
static hb_bool_t
-hb_font_get_glyph_from_name_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- const char *name, int len, /* -1 means nul-terminated */
+hb_font_get_glyph_from_name_default (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ const char *name,
+ int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
return font->parent->get_glyph_from_name (name, len, glyph);
}
@@ -521,9 +550,9 @@ static const hb_font_funcs_t _hb_font_funcs_default = {
/**
* hb_font_funcs_create: (Xconstructor)
*
+ * Creates a new #hb_font_funcs_t structure of font functions.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): The font-functions structure
*
* Since: 0.9.2
**/
@@ -543,9 +572,9 @@ hb_font_funcs_create ()
/**
* hb_font_funcs_get_empty:
*
+ * Fetches an empty font-functions structure.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): The font-functions structure
*
* Since: 0.9.2
**/
@@ -557,11 +586,11 @@ hb_font_funcs_get_empty ()
/**
* hb_font_funcs_reference: (skip)
- * @ffuncs: font functions.
+ * @ffuncs: The font-functions structure
*
+ * Increases the reference count on a font-functions structure.
*
- *
- * Return value:
+ * Return value: The font-functions structure
*
* Since: 0.9.2
**/
@@ -573,9 +602,11 @@ hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
/**
* hb_font_funcs_destroy: (skip)
- * @ffuncs: font functions.
- *
+ * @ffuncs: The font-functions structure
*
+ * Decreases the reference count on a font-functions structure. When
+ * the reference count reaches zero, the font-functions structure is
+ * destroyed, freeing all memory.
*
* Since: 0.9.2
**/
@@ -594,15 +625,15 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
/**
* hb_font_funcs_set_user_data: (skip)
- * @ffuncs: font functions.
- * @key:
- * @data:
- * @destroy:
- * @replace:
- *
+ * @ffuncs: The font-functions structure
+ * @key: The user-data key to set
+ * @data: A pointer to the user data set
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
*
+ * Attaches a user-data key/data pair to the specified font-functions structure.
*
- * Return value:
+ * Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@@ -610,7 +641,7 @@ hb_bool_t
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
hb_user_data_key_t *key,
void * data,
- hb_destroy_func_t destroy,
+ hb_destroy_func_t destroy /* May be NULL. */,
hb_bool_t replace)
{
return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
@@ -618,12 +649,13 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_get_user_data: (skip)
- * @ffuncs: font functions.
- * @key:
- *
+ * @ffuncs: The font-functions structure
+ * @key: The user-data key to query
*
+ * Fetches the user data associated with the specified key,
+ * attached to the specified font-functions structure.
*
- * Return value: (transfer none):
+ * Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@@ -637,9 +669,9 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_make_immutable:
- * @ffuncs: font functions.
- *
+ * @ffuncs: The font-functions structure
*
+ * Makes a font-functions structure immutable.
*
* Since: 0.9.2
**/
@@ -654,11 +686,11 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
/**
* hb_font_funcs_is_immutable:
- * @ffuncs: font functions.
- *
+ * @ffuncs: The font-functions structure
*
+ * Tests whether a font-functions structure is immutable.
*
- * Return value:
+ * Return value: %true if @ffuncs is immutable, false otherwise
*
* Since: 0.9.2
**/
@@ -718,17 +750,18 @@ hb_font_t::has_func (unsigned int i)
/**
* hb_font_get_h_extents:
- * @font: a font.
- * @extents: (out):
+ * @font: #hb_font_t to work upon
+ * @extents: (out): The font extents retrieved
*
+ * Fetches the extents for a specified font, in horizontal
+ * text segments.
*
- *
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 1.1.3
**/
hb_bool_t
-hb_font_get_h_extents (hb_font_t *font,
+hb_font_get_h_extents (hb_font_t *font,
hb_font_extents_t *extents)
{
return font->get_font_h_extents (extents);
@@ -736,17 +769,18 @@ hb_font_get_h_extents (hb_font_t *font,
/**
* hb_font_get_v_extents:
- * @font: a font.
- * @extents: (out):
- *
+ * @font: #hb_font_t to work upon
+ * @extents: (out): The font extents retrieved
*
+ * Fetches the extents for a specified font, in vertical
+ * text segments.
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 1.1.3
**/
hb_bool_t
-hb_font_get_v_extents (hb_font_t *font,
+hb_font_get_v_extents (hb_font_t *font,
hb_font_extents_t *extents)
{
return font->get_font_v_extents (extents);
@@ -754,20 +788,25 @@ hb_font_get_v_extents (hb_font_t *font,
/**
* hb_font_get_glyph:
- * @font: a font.
- * @unicode:
- * @variation_selector:
- * @glyph: (out):
+ * @font: #hb_font_t to work upon
+ * @unicode: The Unicode code point to query
+ * @variation_selector: (optional): A variation-selector code point
+ * @glyph: (out): The glyph ID retrieved
*
+ * Fetches the glyph ID for a Unicode code point in the specified
+ * font, with an optional variation selector.
*
+ * If @variation_selector is 0, calls hb_font_get_nominal_glyph();
+ * otherwise calls hb_font_get_variation_glyph().
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph (hb_font_t *font,
- hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+hb_font_get_glyph (hb_font_t *font,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
{
if (unlikely (variation_selector))
@@ -777,19 +816,24 @@ hb_font_get_glyph (hb_font_t *font,
/**
* hb_font_get_nominal_glyph:
- * @font: a font.
- * @unicode:
- * @glyph: (out):
+ * @font: #hb_font_t to work upon
+ * @unicode: The Unicode code point to query
+ * @glyph: (out): The glyph ID retrieved
*
+ * Fetches the nominal glyph ID for a Unicode code point in the
+ * specified font.
*
+ * This version of the function should not be used to fetch glyph IDs
+ * for code points modified by variation selectors. For variation-selector
+ * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph().
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 1.2.3
**/
hb_bool_t
-hb_font_get_nominal_glyph (hb_font_t *font,
- hb_codepoint_t unicode,
+hb_font_get_nominal_glyph (hb_font_t *font,
+ hb_codepoint_t unicode,
hb_codepoint_t *glyph)
{
return font->get_nominal_glyph (unicode, glyph);
@@ -820,20 +864,23 @@ hb_font_get_nominal_glyphs (hb_font_t *font,
/**
* hb_font_get_variation_glyph:
- * @font: a font.
- * @unicode:
- * @variation_selector:
- * @glyph: (out):
+ * @font: #hb_font_t to work upon
+ * @unicode: The Unicode code point to query
+ * @variation_selector: The variation-selector code point to query
+ * @glyph: (out): The glyph ID retrieved
*
+ * Fetches the glyph ID for a Unicode code point when followed by
+ * by the specified variation-selector code point, in the specified
+ * font.
*
- *
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 1.2.3
**/
hb_bool_t
-hb_font_get_variation_glyph (hb_font_t *font,
- hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+hb_font_get_variation_glyph (hb_font_t *font,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
{
return font->get_variation_glyph (unicode, variation_selector, glyph);
@@ -841,134 +888,157 @@ hb_font_get_variation_glyph (hb_font_t *font,
/**
* hb_font_get_glyph_h_advance:
- * @font: a font.
- * @glyph:
- *
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
*
+ * Fetches the advance for a glyph ID in the specified font,
+ * for horizontal text segments.
*
- * Return value:
+ * Return value: The advance of @glyph within @font
*
* Since: 0.9.2
**/
hb_position_t
-hb_font_get_glyph_h_advance (hb_font_t *font,
- hb_codepoint_t glyph)
+hb_font_get_glyph_h_advance (hb_font_t *font,
+ hb_codepoint_t glyph)
{
return font->get_glyph_h_advance (glyph);
}
/**
* hb_font_get_glyph_v_advance:
- * @font: a font.
- * @glyph:
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
*
+ * Fetches the advance for a glyph ID in the specified font,
+ * for vertical text segments.
*
- *
- * Return value:
+ * Return value: The advance of @glyph within @font
*
* Since: 0.9.2
**/
hb_position_t
-hb_font_get_glyph_v_advance (hb_font_t *font,
- hb_codepoint_t glyph)
+hb_font_get_glyph_v_advance (hb_font_t *font,
+ hb_codepoint_t glyph)
{
return font->get_glyph_v_advance (glyph);
}
/**
* hb_font_get_glyph_h_advances:
- * @font: a font.
- *
+ * @font: #hb_font_t to work upon
+ * @count: The number of glyph IDs in the sequence queried
+ * @first_glyph: The first glyph ID to query
+ * @glyph_stride: The stride between successive glyph IDs
+ * @first_advance: (out): The first advance retrieved
+ * @advance_stride: (out): The stride between successive advances
*
+ * Fetches the advances for a sequence of glyph IDs in the specified
+ * font, for horizontal text segments.
*
* Since: 1.8.6
**/
void
-hb_font_get_glyph_h_advances (hb_font_t* font,
- unsigned int count,
+hb_font_get_glyph_h_advances (hb_font_t* font,
+ unsigned int count,
const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride)
+ unsigned glyph_stride,
+ hb_position_t *first_advance,
+ unsigned advance_stride)
{
font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
}
/**
* hb_font_get_glyph_v_advances:
- * @font: a font.
- *
+ * @font: #hb_font_t to work upon
+ * @count: The number of glyph IDs in the sequence queried
+ * @first_glyph: The first glyph ID to query
+ * @glyph_stride: The stride between successive glyph IDs
+ * @first_advance: (out): The first advance retrieved
+ * @advance_stride: (out): The stride between successive advances
*
+ * Fetches the advances for a sequence of glyph IDs in the specified
+ * font, for vertical text segments.
*
* Since: 1.8.6
**/
void
-hb_font_get_glyph_v_advances (hb_font_t* font,
- unsigned int count,
+hb_font_get_glyph_v_advances (hb_font_t* font,
+ unsigned int count,
const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride)
+ unsigned glyph_stride,
+ hb_position_t *first_advance,
+ unsigned advance_stride)
{
font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
}
/**
* hb_font_get_glyph_h_origin:
- * @font: a font.
- * @glyph:
- * @x: (out):
- * @y: (out):
- *
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @x: (out): The X coordinate of the origin
+ * @y: (out): The Y coordinate of the origin
*
+ * Fetches the (X,Y) coordinates of the origin for a glyph ID
+ * in the specified font, for horizontal text segments.
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_h_origin (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_h_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->get_glyph_h_origin (glyph, x, y);
}
/**
* hb_font_get_glyph_v_origin:
- * @font: a font.
- * @glyph:
- * @x: (out):
- * @y: (out):
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @x: (out): The X coordinate of the origin
+ * @y: (out): The Y coordinate of the origin
*
+ * Fetches the (X,Y) coordinates of the origin for a glyph ID
+ * in the specified font, for vertical text segments.
*
- *
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_v_origin (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_v_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->get_glyph_v_origin (glyph, x, y);
}
/**
* hb_font_get_glyph_h_kerning:
- * @font: a font.
- * @left_glyph:
- * @right_glyph:
+ * @font: #hb_font_t to work upon
+ * @left_glyph: The glyph ID of the left glyph in the glyph pair
+ * @right_glyph: The glyph ID of the right glyph in the glyph pair
*
+ * Fetches the kerning-adjustment value for a glyph-pair in
+ * the specified font, in horizontal text segments.
*
+ * <note>It handles legacy kerning only (as returned by the corresponding
+ * #hb_font_funcs_t function).</note>
*
- * Return value:
+ * Return value: The kerning adjustment value
*
* Since: 0.9.2
**/
hb_position_t
-hb_font_get_glyph_h_kerning (hb_font_t *font,
- hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+ hb_codepoint_t left_glyph,
+ hb_codepoint_t right_glyph)
{
return font->get_glyph_h_kerning (left_glyph, right_glyph);
}
@@ -976,20 +1046,25 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_v_kerning:
- * @font: a font.
- * @top_glyph:
- * @bottom_glyph:
+ * @font: #hb_font_t to work upon
+ * @top_glyph: The glyph ID of the top glyph in the glyph pair
+ * @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair
*
+ * Fetches the kerning-adjustment value for a glyph-pair in
+ * the specified font, in vertical text segments.
*
+ * <note>It handles legacy kerning only (as returned by the corresponding
+ * #hb_font_funcs_t function).</note>
*
- * Return value:
+ * Return value: The kerning adjustment value
*
* Since: 0.9.2
* Deprecated: 2.0.0
**/
hb_position_t
-hb_font_get_glyph_v_kerning (hb_font_t *font,
- hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+ hb_codepoint_t top_glyph,
+ hb_codepoint_t bottom_glyph)
{
return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
}
@@ -997,19 +1072,20 @@ hb_font_get_glyph_v_kerning (hb_font_t *font,
/**
* hb_font_get_glyph_extents:
- * @font: a font.
- * @glyph:
- * @extents: (out):
- *
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @extents: (out): The #hb_glyph_extents_t retrieved
*
+ * Fetches the #hb_glyph_extents_t data for a glyph ID
+ * in the specified font.
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_extents (hb_font_t *font,
- hb_codepoint_t glyph,
+hb_font_get_glyph_extents (hb_font_t *font,
+ hb_codepoint_t glyph,
hb_glyph_extents_t *extents)
{
return font->get_glyph_extents (glyph, extents);
@@ -1017,63 +1093,70 @@ hb_font_get_glyph_extents (hb_font_t *font,
/**
* hb_font_get_glyph_contour_point:
- * @font: a font.
- * @glyph:
- * @point_index:
- * @x: (out):
- * @y: (out):
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @point_index: The contour-point index to query
+ * @x: (out): The X value retrieved for the contour point
+ * @y: (out): The Y value retrieved for the contour point
*
+ * Fetches the (x,y) coordinates of a specified contour-point index
+ * in the specified glyph, within the specified font.
*
- *
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_contour_point (hb_font_t *font,
- hb_codepoint_t glyph, unsigned int point_index,
- hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_contour_point (hb_font_t *font,
+ hb_codepoint_t glyph,
+ unsigned int point_index,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->get_glyph_contour_point (glyph, point_index, x, y);
}
/**
* hb_font_get_glyph_name:
- * @font: a font.
- * @glyph:
- * @name: (array length=size):
- * @size:
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @name: (out) (array length=size): Name string retrieved for the glyph ID
+ * @size: Length of the glyph-name string retrieved
*
+ * Fetches the glyph-name string for a glyph ID in the specified @font.
*
- *
- * Return value:
+ * Return value: %true if data found, zero otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_name (hb_font_t *font,
- hb_codepoint_t glyph,
- char *name, unsigned int size)
+hb_font_get_glyph_name (hb_font_t *font,
+ hb_codepoint_t glyph,
+ char *name,
+ unsigned int size)
{
return font->get_glyph_name (glyph, name, size);
}
/**
* hb_font_get_glyph_from_name:
- * @font: a font.
- * @name: (array length=len):
- * @len:
- * @glyph: (out):
+ * @font: #hb_font_t to work upon
+ * @name: (array length=len): The name string to query
+ * @len: The length of the name queried
+ * @glyph: (out): The glyph ID retrieved
*
+ * Fetches the glyph ID that corresponds to a name string in the specified @font.
*
+ * <note>Note: @len == -1 means the name string is null-terminated.</note>
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_from_name (hb_font_t *font,
- const char *name, int len, /* -1 means nul-terminated */
+hb_font_get_glyph_from_name (hb_font_t *font,
+ const char *name,
+ int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph)
{
return font->get_glyph_from_name (name, len, glyph);
@@ -1084,164 +1167,211 @@ hb_font_get_glyph_from_name (hb_font_t *font,
/**
* hb_font_get_extents_for_direction:
- * @font: a font.
- * @direction:
- * @extents: (out):
+ * @font: #hb_font_t to work upon
+ * @direction: The direction of the text segment
+ * @extents: (out): The #hb_glyph_extents_t retrieved
*
+ * Fetches the extents for a font in a text segment of the
+ * specified direction.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
* Since: 1.1.3
**/
void
-hb_font_get_extents_for_direction (hb_font_t *font,
- hb_direction_t direction,
+hb_font_get_extents_for_direction (hb_font_t *font,
+ hb_direction_t direction,
hb_font_extents_t *extents)
{
return font->get_extents_for_direction (direction, extents);
}
/**
* hb_font_get_glyph_advance_for_direction:
- * @font: a font.
- * @glyph:
- * @direction:
- * @x: (out):
- * @y: (out):
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @direction: The direction of the text segment
+ * @x: (out): The horizontal advance retrieved
+ * @y: (out): The vertical advance retrieved
*
+ * Fetches the advance for a glyph ID from the specified font,
+ * in a text segment of the specified direction.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
* Since: 0.9.2
**/
void
-hb_font_get_glyph_advance_for_direction (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_advance_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->get_glyph_advance_for_direction (glyph, direction, x, y);
}
/**
* hb_font_get_glyph_advances_for_direction:
- * @font: a font.
- * @direction:
+ * @font: #hb_font_t to work upon
+ * @direction: The direction of the text segment
+ * @count: The number of glyph IDs in the sequence queried
+ * @first_glyph: The first glyph ID to query
+ * @glyph_stride: The stride between successive glyph IDs
+ * @first_advance: (out): The first advance retrieved
+ * @advance_stride: (out): The stride between successive advances
*
+ * Fetches the advances for a sequence of glyph IDs in the specified
+ * font, in a text segment of the specified direction.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
* Since: 1.8.6
**/
HB_EXTERN void
-hb_font_get_glyph_advances_for_direction (hb_font_t* font,
- hb_direction_t direction,
- unsigned int count,
+hb_font_get_glyph_advances_for_direction (hb_font_t* font,
+ hb_direction_t direction,
+ unsigned int count,
const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride)
+ unsigned glyph_stride,
+ hb_position_t *first_advance,
+ unsigned advance_stride)
{
font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride);
}
/**
* hb_font_get_glyph_origin_for_direction:
- * @font: a font.
- * @glyph:
- * @direction:
- * @x: (out):
- * @y: (out):
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @direction: The direction of the text segment
+ * @x: (out): The X coordinate retrieved for the origin
+ * @y: (out): The Y coordinate retrieved for the origin
*
+ * Fetches the (X,Y) coordinates of the origin for a glyph in
+ * the specified font.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
* Since: 0.9.2
**/
void
-hb_font_get_glyph_origin_for_direction (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->get_glyph_origin_for_direction (glyph, direction, x, y);
}
/**
* hb_font_add_glyph_origin_for_direction:
- * @font: a font.
- * @glyph:
- * @direction:
- * @x: (out):
- * @y: (out):
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @direction: The direction of the text segment
+ * @x: (inout): Input = The original X coordinate
+ * Output = The X coordinate plus the X-coordinate of the origin
+ * @y: (inout): Input = The original Y coordinate
+ * Output = The Y coordinate plus the Y-coordinate of the origin
*
+ * Adds the origin coordinates to an (X,Y) point coordinate, in
+ * the specified glyph ID in the specified font.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
* Since: 0.9.2
**/
void
-hb_font_add_glyph_origin_for_direction (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
+hb_font_add_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->add_glyph_origin_for_direction (glyph, direction, x, y);
}
/**
* hb_font_subtract_glyph_origin_for_direction:
- * @font: a font.
- * @glyph:
- * @direction:
- * @x: (out):
- * @y: (out):
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @direction: The direction of the text segment
+ * @x: (inout): Input = The original X coordinate
+ * Output = The X coordinate minus the X-coordinate of the origin
+ * @y: (inout): Input = The original Y coordinate
+ * Output = The Y coordinate minus the Y-coordinate of the origin
*
+ * Subtracts the origin coordinates from an (X,Y) point coordinate,
+ * in the specified glyph ID in the specified font.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
* Since: 0.9.2
**/
void
-hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
+hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
}
/**
* hb_font_get_glyph_kerning_for_direction:
- * @font: a font.
- * @first_glyph:
- * @second_glyph:
- * @direction:
- * @x: (out):
- * @y: (out):
+ * @font: #hb_font_t to work upon
+ * @first_glyph: The glyph ID of the first glyph in the glyph pair to query
+ * @second_glyph: The glyph ID of the second glyph in the glyph pair to query
+ * @direction: The direction of the text segment
+ * @x: (out): The horizontal kerning-adjustment value retrieved
+ * @y: (out): The vertical kerning-adjustment value retrieved
*
+ * Fetches the kerning-adjustment value for a glyph-pair in the specified font.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
* Since: 0.9.2
**/
void
-hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
- hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+ hb_codepoint_t first_glyph,
+ hb_codepoint_t second_glyph,
+ hb_direction_t direction,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
}
/**
* hb_font_get_glyph_extents_for_origin:
- * @font: a font.
- * @glyph:
- * @direction:
- * @extents: (out):
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @direction: The direction of the text segment
+ * @extents: (out): The #hb_glyph_extents_t retrieved
*
+ * Fetches the #hb_glyph_extents_t data for a glyph ID
+ * in the specified font, with respect to the origin in
+ * a text segment in the specified direction.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_extents_for_origin (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
+hb_font_get_glyph_extents_for_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
hb_glyph_extents_t *extents)
{
return font->get_glyph_extents_for_origin (glyph, direction, extents);
@@ -1249,65 +1379,79 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font,
/**
* hb_font_get_glyph_contour_point_for_origin:
- * @font: a font.
- * @glyph:
- * @point_index:
- * @direction:
- * @x: (out):
- * @y: (out):
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @point_index: The contour-point index to query
+ * @direction: The direction of the text segment
+ * @x: (out): The X value retrieved for the contour point
+ * @y: (out): The Y value retrieved for the contour point
*
+ * Fetches the (X,Y) coordinates of a specified contour-point index
+ * in the specified glyph ID in the specified font, with respect
+ * to the origin in a text segment in the specified direction.
*
+ * Calls the appropriate direction-specific variant (horizontal
+ * or vertical) depending on the value of @direction.
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
- hb_codepoint_t glyph, unsigned int point_index,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ unsigned int point_index,
+ hb_direction_t direction,
+ hb_position_t *x,
+ hb_position_t *y)
{
return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
}
-/* Generates gidDDD if glyph has no name. */
/**
* hb_font_glyph_to_string:
- * @font: a font.
- * @glyph:
- * @s: (array length=size):
- * @size:
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID to query
+ * @s: (out) (array length=size): The string containing the glyph name
+ * @size: Length of string @s
*
+ * Fetches the name of the specified glyph ID in @font and returns
+ * it in string @s.
*
+ * If the glyph ID has no name in @font, a string of the form `gidDDD` is
+ * generated, with `DDD` being the glyph ID.
*
* Since: 0.9.2
**/
void
-hb_font_glyph_to_string (hb_font_t *font,
- hb_codepoint_t glyph,
- char *s, unsigned int size)
+hb_font_glyph_to_string (hb_font_t *font,
+ hb_codepoint_t glyph,
+ char *s,
+ unsigned int size)
{
font->glyph_to_string (glyph, s, size);
}
-/* Parses gidDDD and uniUUUU strings automatically. */
/**
* hb_font_glyph_from_string:
- * @font: a font.
- * @s: (array length=len) (element-type uint8_t):
- * @len:
- * @glyph: (out):
+ * @font: #hb_font_t to work upon
+ * @s: (array length=len) (element-type uint8_t): string to query
+ * @len: The length of the string @s
+ * @glyph: (out): The glyph ID corresponding to the string requested
*
+ * Fetches the glyph ID from @font that matches the specified string.
+ * Strings of the format `gidDDD` or `uniUUUU` are parsed automatically.
*
+ * <note>Note: @len == -1 means the string is null-terminated.</note>
*
- * Return value:
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_glyph_from_string (hb_font_t *font,
- const char *s, int len, /* -1 means nul-terminated */
+hb_font_glyph_from_string (hb_font_t *font,
+ const char *s,
+ int len,
hb_codepoint_t *glyph)
{
return font->glyph_from_string (s, len, glyph);
@@ -1369,9 +1513,9 @@ _hb_font_create (hb_face_t *face)
* hb_font_create: (Xconstructor)
* @face: a face.
*
+ * Constructs a new font object from the specified face.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): The new font object
*
* Since: 0.9.2
**/
@@ -1404,11 +1548,12 @@ _hb_font_adopt_var_coords (hb_font_t *font,
/**
* hb_font_create_sub_font:
- * @parent: parent font.
- *
+ * @parent: The parent font object
*
+ * Constructs a sub-font font object from the specified @parent font,
+ * replicating the parent's properties.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): The new sub-font font object
*
* Since: 0.9.2
**/
@@ -1456,9 +1601,9 @@ hb_font_create_sub_font (hb_font_t *parent)
/**
* hb_font_get_empty:
*
+ * Fetches the empty font object.
*
- *
- * Return value: (transfer full)
+ * Return value: (transfer full): The empty font object
*
* Since: 0.9.2
**/
@@ -1470,11 +1615,11 @@ hb_font_get_empty ()
/**
* hb_font_reference: (skip)
- * @font: a font.
+ * @font: #hb_font_t to work upon
*
+ * Increases the reference count on the given font object.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): The @font object
*
* Since: 0.9.2
**/
@@ -1486,9 +1631,11 @@ hb_font_reference (hb_font_t *font)
/**
* hb_font_destroy: (skip)
- * @font: a font.
- *
+ * @font: #hb_font_t to work upon
*
+ * Decreases the reference count on the given font object. When the
+ * reference count reaches zero, the font is destroyed,
+ * freeing all memory.
*
* Since: 0.9.2
**/
@@ -1514,13 +1661,13 @@ hb_font_destroy (hb_font_t *font)
/**
* hb_font_set_user_data: (skip)
- * @font: a font.
- * @key:
- * @data:
- * @destroy:
- * @replace:
- *
+ * @font: #hb_font_t to work upon
+ * @key: The user-data key
+ * @data: A pointer to the user data
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
*
+ * Attaches a user-data key/data pair to the specified font object.
*
* Return value:
*
@@ -1530,7 +1677,7 @@ hb_bool_t
hb_font_set_user_data (hb_font_t *font,
hb_user_data_key_t *key,
void * data,
- hb_destroy_func_t destroy,
+ hb_destroy_func_t destroy /* May be NULL. */,
hb_bool_t replace)
{
return hb_object_set_user_data (font, key, data, destroy, replace);
@@ -1538,12 +1685,13 @@ hb_font_set_user_data (hb_font_t *font,
/**
* hb_font_get_user_data: (skip)
- * @font: a font.
- * @key:
+ * @font: #hb_font_t to work upon
+ * @key: The user-data key to query
*
+ * Fetches the user-data object associated with the specified key,
+ * attached to the specified font object.
*
- *
- * Return value: (transfer none):
+ * Return value: (transfer none): Pointer to the user data
*
* Since: 0.9.2
**/
@@ -1556,9 +1704,9 @@ hb_font_get_user_data (hb_font_t *font,
/**
* hb_font_make_immutable:
- * @font: a font.
- *
+ * @font: #hb_font_t to work upon
*
+ * Makes @font immutable.
*
* Since: 0.9.2
**/
@@ -1576,11 +1724,11 @@ hb_font_make_immutable (hb_font_t *font)
/**
* hb_font_is_immutable:
- * @font: a font.
+ * @font: #hb_font_t to work upon
*
+ * Tests whether a font object is immutable.
*
- *
- * Return value:
+ * Return value: %true if @font is immutable, false otherwise
*
* Since: 0.9.2
**/
@@ -1592,10 +1740,10 @@ hb_font_is_immutable (hb_font_t *font)
/**
* hb_font_set_parent:
- * @font: a font.
- * @parent: new parent.
+ * @font: #hb_font_t to work upon
+ * @parent: The parent font object to assign
*
- * Sets parent font of @font.
+ * Sets the parent font of @font.
*
* Since: 1.0.5
**/
@@ -1618,11 +1766,11 @@ hb_font_set_parent (hb_font_t *font,
/**
* hb_font_get_parent:
- * @font: a font.
+ * @font: #hb_font_t to work upon
*
+ * Fetches the parent font of @font.
*
- *
- * Return value: (transfer none):
+ * Return value: (transfer none): The parent font object
*
* Since: 0.9.2
**/
@@ -1634,10 +1782,10 @@ hb_font_get_parent (hb_font_t *font)
/**
* hb_font_set_face:
- * @font: a font.
- * @face: new face.
+ * @font: #hb_font_t to work upon
+ * @face: The #hb_face_t to assign
*
- * Sets font-face of @font.
+ * Sets @face as the font-face value of @font.
*
* Since: 1.4.3
**/
@@ -1662,11 +1810,11 @@ hb_font_set_face (hb_font_t *font,
/**
* hb_font_get_face:
- * @font: a font.
- *
+ * @font: #hb_font_t to work upon
*
+ * Fetches the face associated with the specified font object.
*
- * Return value: (transfer none):
+ * Return value: (transfer none): The #hb_face_t value
*
* Since: 0.9.2
**/
@@ -1679,12 +1827,13 @@ hb_font_get_face (hb_font_t *font)
/**
* hb_font_set_funcs:
- * @font: a font.
+ * @font: #hb_font_t to work upon
* @klass: (closure font_data) (destroy destroy) (scope notified):
- * @font_data:
- * @destroy:
- *
+ * @font_data: Data to attach to @font
+ * @destroy: (optional): The function to call when @font_data is not needed anymore
*
+ * Replaces the font-functions structure attached to a font, updating
+ * the font's user-data with @font-data and the @destroy callback.
*
* Since: 0.9.2
**/
@@ -1692,7 +1841,7 @@ void
hb_font_set_funcs (hb_font_t *font,
hb_font_funcs_t *klass,
void *font_data,
- hb_destroy_func_t destroy)
+ hb_destroy_func_t destroy /* May be NULL. */)
{
if (hb_object_is_immutable (font))
{
@@ -1716,18 +1865,19 @@ hb_font_set_funcs (hb_font_t *font,
/**
* hb_font_set_funcs_data:
- * @font: a font.
- * @font_data: (destroy destroy) (scope notified):
- * @destroy:
- *
+ * @font: #hb_font_t to work upon
+ * @font_data: (destroy destroy) (scope notified): Data to attach to @font
+ * @destroy: (optional): The function to call when @font_data is not needed anymore
*
+ * Replaces the user data attached to a font, updating the font's
+ * @destroy callback.
*
* Since: 0.9.2
**/
void
hb_font_set_funcs_data (hb_font_t *font,
- void *font_data,
- hb_destroy_func_t destroy)
+ void *font_data,
+ hb_destroy_func_t destroy /* May be NULL. */)
{
/* Destroy user_data? */
if (hb_object_is_immutable (font))
@@ -1747,18 +1897,18 @@ hb_font_set_funcs_data (hb_font_t *font,
/**
* hb_font_set_scale:
- * @font: a font.
- * @x_scale:
- * @y_scale:
- *
+ * @font: #hb_font_t to work upon
+ * @x_scale: Horizontal scale value to assign
+ * @y_scale: Vertical scale value to assign
*
+ * Sets the horizontal and vertical scale of a font.
*
* Since: 0.9.2
**/
void
hb_font_set_scale (hb_font_t *font,
- int x_scale,
- int y_scale)
+ int x_scale,
+ int y_scale)
{
if (hb_object_is_immutable (font))
return;
@@ -1770,18 +1920,18 @@ hb_font_set_scale (hb_font_t *font,
/**
* hb_font_get_scale:
- * @font: a font.
- * @x_scale: (out):
- * @y_scale: (out):
- *
+ * @font: #hb_font_t to work upon
+ * @x_scale: (out): Horizontal scale value
+ * @y_scale: (out): Vertical scale value
*
+ * Fetches the horizontal and vertical scale of a font.
*
* Since: 0.9.2
**/
void
hb_font_get_scale (hb_font_t *font,
- int *x_scale,
- int *y_scale)
+ int *x_scale,
+ int *y_scale)
{
if (x_scale) *x_scale = font->x_scale;
if (y_scale) *y_scale = font->y_scale;
@@ -1789,18 +1939,18 @@ hb_font_get_scale (hb_font_t *font,
/**
* hb_font_set_ppem:
- * @font: a font.
- * @x_ppem:
- * @y_ppem:
- *
+ * @font: #hb_font_t to work upon
+ * @x_ppem: Horizontal ppem value to assign
+ * @y_ppem: Vertical ppem value to assign
*
+ * Sets the horizontal and vertical pixels-per-em (ppem) of a font.
*
* Since: 0.9.2
**/
void
-hb_font_set_ppem (hb_font_t *font,
- unsigned int x_ppem,
- unsigned int y_ppem)
+hb_font_set_ppem (hb_font_t *font,
+ unsigned int x_ppem,
+ unsigned int y_ppem)
{
if (hb_object_is_immutable (font))
return;
@@ -1811,16 +1961,16 @@ hb_font_set_ppem (hb_font_t *font,
/**
* hb_font_get_ppem:
- * @font: a font.
- * @x_ppem: (out):
- * @y_ppem: (out):
- *
+ * @font: #hb_font_t to work upon
+ * @x_ppem: (out): Horizontal ppem value
+ * @y_ppem: (out): Vertical ppem value
*
+ * Fetches the horizontal and vertical points-per-em (ppem) of a font.
*
* Since: 0.9.2
**/
void
-hb_font_get_ppem (hb_font_t *font,
+hb_font_get_ppem (hb_font_t *font,
unsigned int *x_ppem,
unsigned int *y_ppem)
{
@@ -1830,17 +1980,19 @@ hb_font_get_ppem (hb_font_t *font,
/**
* hb_font_set_ptem:
- * @font: a font.
+ * @font: #hb_font_t to work upon
* @ptem: font size in points.
*
- * Sets "point size" of the font. Set to 0 to unset.
+ * Sets the "point size" of a font. Set to zero to unset.
+ * Used in CoreText to implement optical sizing.
*
- * There are 72 points in an inch.
+ * <note>Note: There are 72 points in an inch.</note>
*
* Since: 1.6.0
**/
void
-hb_font_set_ptem (hb_font_t *font, float ptem)
+hb_font_set_ptem (hb_font_t *font,
+ float ptem)
{
if (hb_object_is_immutable (font))
return;
@@ -1850,11 +2002,12 @@ hb_font_set_ptem (hb_font_t *font, float ptem)
/**
* hb_font_get_ptem:
- * @font: a font.
+ * @font: #hb_font_t to work upon
*
- * Gets the "point size" of the font. A value of 0 means unset.
+ * Fetches the "point size" of a font. Used in CoreText to
+ * implement optical sizing.
*
- * Return value: Point size.
+ * Return value: Point size. A value of zero means "not set."
*
* Since: 0.9.2
**/
@@ -1871,13 +2024,18 @@ hb_font_get_ptem (hb_font_t *font)
/**
* hb_font_set_variations:
+ * @font: #hb_font_t to work upon
+ * @variations: (array length=variations_length): Array of variation settings to apply
+ * @variations_length: Number of variations to apply
+ *
+ * Applies a list of font-variation settings to a font.
*
* Since: 1.4.2
*/
void
-hb_font_set_variations (hb_font_t *font,
+hb_font_set_variations (hb_font_t *font,
const hb_variation_t *variations,
- unsigned int variations_length)
+ unsigned int variations_length)
{
if (hb_object_is_immutable (font))
return;
@@ -1919,13 +2077,19 @@ hb_font_set_variations (hb_font_t *font,
/**
* hb_font_set_var_coords_design:
+ * @font: #hb_font_t to work upon
+ * @coords: (array length=coords_length): Array of variation coordinates to apply
+ * @coords_length: Number of coordinates to apply
+ *
+ * Applies a list of variation coordinates (in design-space units)
+ * to a font.
*
* Since: 1.4.2
*/
void
-hb_font_set_var_coords_design (hb_font_t *font,
- const float *coords,
- unsigned int coords_length)
+hb_font_set_var_coords_design (hb_font_t *font,
+ const float *coords,
+ unsigned int coords_length)
{
if (hb_object_is_immutable (font))
return;
@@ -1976,13 +2140,21 @@ hb_font_set_var_named_instance (hb_font_t *font,
/**
* hb_font_set_var_coords_normalized:
+ * @font: #hb_font_t to work upon
+ * @coords: (array length=coords_length): Array of variation coordinates to apply
+ * @coords_length: Number of coordinates to apply
+ *
+ * Applies a list of variation coordinates (in normalized units)
+ * to a font.
+ *
+ * <note>Note: Coordinates should be normalized to 2.14.</note>
*
* Since: 1.4.2
*/
void
-hb_font_set_var_coords_normalized (hb_font_t *font,
- const int *coords, /* 2.14 normalized */
- unsigned int coords_length)
+hb_font_set_var_coords_normalized (hb_font_t *font,
+ const int *coords, /* 2.14 normalized */
+ unsigned int coords_length)
{
if (hb_object_is_immutable (font))
return;
@@ -2016,6 +2188,11 @@ hb_font_set_var_coords_normalized (hb_font_t *font,
/**
* hb_font_get_var_coords_normalized:
+ * @font: #hb_font_t to work upon
+ * @length: Number of coordinates retrieved
+ *
+ * Fetches the list of normalized variation coordinates currently
+ * set on a font.
*
* Return value is valid as long as variation coordinates of the font
* are not modified.
@@ -2023,7 +2200,7 @@ hb_font_set_var_coords_normalized (hb_font_t *font,
* Since: 1.4.2
*/
const int *
-hb_font_get_var_coords_normalized (hb_font_t *font,
+hb_font_get_var_coords_normalized (hb_font_t *font,
unsigned int *length)
{
if (length)
@@ -2115,23 +2292,23 @@ trampoline_destroy (void *user_data)
typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
static hb_bool_t
-hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
- void *font_data,
- hb_codepoint_t unicode,
+hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
+ void *font_data,
+ hb_codepoint_t unicode,
hb_codepoint_t *glyph,
- void *user_data)
+ void *user_data)
{
hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
}
static hb_bool_t
-hb_font_get_variation_glyph_trampoline (hb_font_t *font,
- void *font_data,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
+hb_font_get_variation_glyph_trampoline (hb_font_t *font,
+ void *font_data,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
- void *user_data)
+ void *user_data)
{
hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
@@ -2139,10 +2316,10 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font,
/**
* hb_font_funcs_set_glyph_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified): callback function.
- * @user_data: data to pass to @func.
- * @destroy: function to call when @user_data is not needed anymore.
+ * @ffuncs: The font-functions structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): callback function
+ * @user_data: data to pass to @func
+ * @destroy: (optional): function to call when @user_data is not needed anymore
*
* Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and
* hb_font_funcs_set_variation_glyph_func() instead.
@@ -2151,9 +2328,10 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font,
* Deprecated: 1.2.3
**/
void
-hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_func_t func,
- void *user_data, hb_destroy_func_t destroy)
+hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_func_t func,
+ void *user_data,
+ hb_destroy_func_t destroy /* May be NULL. */)
{
if (hb_object_is_immutable (ffuncs))
{
diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h
index e1a5719f1d..05f6c03f47 100644
--- a/thirdparty/harfbuzz/src/hb-font.h
+++ b/thirdparty/harfbuzz/src/hb-font.h
@@ -45,6 +45,19 @@ typedef struct hb_font_t hb_font_t;
* hb_font_funcs_t
*/
+/**
+ * hb_font_funcs_t:
+ *
+ * Data type containing a set of virtual methods used for
+ * working on #hb_font_t font objects.
+ *
+ * HarfBuzz provides a lightweight default function for each of
+ * the methods in #hb_font_funcs_t. Client programs can implement
+ * their own replacements for the individual font functions, as
+ * needed, and replace the default by calling the setter for a
+ * method.
+ *
+ **/
typedef struct hb_font_funcs_t hb_font_funcs_t;
HB_EXTERN hb_font_funcs_t *
@@ -81,12 +94,21 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
/* font and glyph extents */
-/* Note that typically ascender is positive and descender negative in coordinate systems that grow up. */
-typedef struct hb_font_extents_t
-{
- hb_position_t ascender; /* typographic ascender. */
- hb_position_t descender; /* typographic descender. */
- hb_position_t line_gap; /* suggested line spacing gap. */
+/**
+ * hb_font_extents_t:
+ * @ascender: The height of typographic ascenders.
+ * @descender: The depth of typographic descenders.
+ * @line_gap: The suggested line-spacing gap.
+ *
+ * Font-wide extent values, measured in font units.
+ *
+ * Note that typically @ascender is positive and @descender
+ * negative, in coordinate systems that grow up.
+ **/
+typedef struct hb_font_extents_t {
+ hb_position_t ascender;
+ hb_position_t descender;
+ hb_position_t line_gap;
/*< private >*/
hb_position_t reserved9;
hb_position_t reserved8;
@@ -99,13 +121,22 @@ typedef struct hb_font_extents_t
hb_position_t reserved1;
} hb_font_extents_t;
-/* Note that height is negative in coordinate systems that grow up. */
-typedef struct hb_glyph_extents_t
-{
- hb_position_t x_bearing; /* left side of glyph from origin. */
- hb_position_t y_bearing; /* top side of glyph from origin. */
- hb_position_t width; /* distance from left to right side. */
- hb_position_t height; /* distance from top to bottom side. */
+/**
+ * hb_glyph_extents_t:
+ * @x_bearing: Distance from the x-origin to the left extremum of the glyph.
+ * @y_bearing: Distance from the top extremum of the glyph to the y-origin.
+ * @width: Distance from the left extremum of the glyph to the right extremum.
+ * @height: Distance from the top extremum of the glyph to the bottom extremum.
+ *
+ * Glyph extent values, measured in font units.
+ *
+ * Note that @height is negative, in coordinate systems that grow up.
+ **/
+typedef struct hb_glyph_extents_t {
+ hb_position_t x_bearing;
+ hb_position_t y_bearing;
+ hb_position_t width;
+ hb_position_t height;
} hb_glyph_extents_t;
/* func types */
@@ -113,19 +144,72 @@ typedef struct hb_glyph_extents_t
typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data,
hb_font_extents_t *extents,
void *user_data);
+
+/**
+ * hb_font_get_font_h_extents_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the extents for a font, in horizontal-direction
+ * text segments. Extents must be returned in an #hb_glyph_extents output
+ * parameter.
+ *
+ **/
typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t;
+
+/**
+ * hb_font_get_font_v_extents_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the extents for a font, in vertical-direction
+ * text segments. Extents must be returned in an #hb_glyph_extents output
+ * parameter.
+ *
+ **/
typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t;
+/**
+ * hb_font_get_nominal_glyph_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the nominal glyph ID for a specified Unicode code
+ * point. Glyph IDs must be returned in a #hb_codepoint_t output parameter.
+ *
+ **/
typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode,
hb_codepoint_t *glyph,
void *user_data);
+
+/**
+ * hb_font_get_variation_glyph_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the glyph ID for a specified Unicode code point
+ * followed by a specified Variation Selector code point. Glyph IDs must be
+ * returned in a #hb_codepoint_t output parameter.
+ *
+ **/
typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data);
+
+/**
+ * hb_font_get_nominal_glyphs_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the nominal glyph IDs for a sequence of
+ * Unicode code points. Glyph IDs must be returned in a #hb_codepoint_t
+ * output parameter.
+ *
+ **/
typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void *font_data,
unsigned int count,
const hb_codepoint_t *first_unicode,
@@ -134,13 +218,51 @@ typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void
unsigned int glyph_stride,
void *user_data);
-
+/**
+ * hb_font_get_glyph_advance_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the advance for a specified glyph. The
+ * method must return an #hb_position_t.
+ *
+ **/
typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
void *user_data);
+
+/**
+ * hb_font_get_glyph_h_advance_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the advance for a specified glyph, in
+ * horizontal-direction text segments. Advances must be returned in
+ * an #hb_position_t output parameter.
+ *
+ **/
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
+
+/**
+ * hb_font_get_glyph_v_advance_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the advance for a specified glyph, in
+ * vertical-direction text segments. Advances must be returned in
+ * an #hb_position_t output parameter.
+ *
+ **/
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
+/**
+ * hb_font_get_glyph_advances_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the advances for a sequence of glyphs.
+ *
+ **/
typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_data,
unsigned int count,
const hb_codepoint_t *first_glyph,
@@ -148,14 +270,66 @@ typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_d
hb_position_t *first_advance,
unsigned advance_stride,
void *user_data);
+
+/**
+ * hb_font_get_glyph_h_advances_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the advances for a sequence of glyphs, in
+ * horizontal-direction text segments.
+ *
+ **/
typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_h_advances_func_t;
+
+/**
+ * hb_font_get_glyph_v_advances_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the advances for a sequence of glyphs, in
+ * vertical-direction text segments.
+ *
+ **/
typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t;
+/**
+ * hb_font_get_glyph_origin_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the (X,Y) coordinates (in font units) of the
+ * origin for a glyph. Each coordinate must be returned in an #hb_position_t
+ * output parameter.
+ *
+ **/
typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y,
void *user_data);
+
+/**
+ * hb_font_get_glyph_h_origin_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the (X,Y) coordinates (in font units) of the
+ * origin for a glyph, in horizontal-direction text segments. Each
+ * coordinate must be returned in an #hb_position_t output parameter.
+ *
+ **/
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
+
+/**
+ * hb_font_get_glyph_v_origin_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the (X,Y) coordinates (in font units) of the
+ * origin for a glyph, in vertical-direction text segments. Each coordinate
+ * must be returned in an #hb_position_t output parameter.
+ *
+ **/
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
@@ -164,20 +338,59 @@ typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+/**
+ * hb_font_get_glyph_extents_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the extents for a specified glyph. Extents must be
+ * returned in an #hb_glyph_extents output parameter.
+ *
+ **/
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
void *user_data);
+
+/**
+ * hb_font_get_glyph_contour_point_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the (X,Y) coordinates (in font units) for a
+ * specified contour point in a glyph. Each coordinate must be returned as
+ * an #hb_position_t output parameter.
+ *
+ **/
typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph, unsigned int point_index,
hb_position_t *x, hb_position_t *y,
void *user_data);
+/**
+ * hb_font_get_glyph_name_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the glyph name that corresponds to a
+ * glyph ID. The name should be returned in a string output parameter.
+ *
+ **/
typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
char *name, unsigned int size,
void *user_data);
+
+/**
+ * hb_font_get_glyph_from_name_func_t:
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * This method should retrieve the glyph ID that corresponds to a glyph-name
+ * string.
+ *
+ **/
typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data,
const char *name, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph,
@@ -188,12 +401,12 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
/**
* hb_font_funcs_set_font_h_extents_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_font_h_extents_func_t.
*
* Since: 1.1.2
**/
@@ -204,12 +417,12 @@ hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_font_v_extents_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_font_v_extents_func_t.
*
* Since: 1.1.2
**/
@@ -220,12 +433,12 @@ hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_nominal_glyph_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_nominal_glyph_func_t.
*
* Since: 1.2.3
**/
@@ -236,12 +449,12 @@ hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_nominal_glyphs_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_nominal_glyphs_func_t.
*
* Since: 2.0.0
**/
@@ -252,12 +465,12 @@ hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_variation_glyph_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_variation_glyph_func_t.
*
* Since: 1.2.3
**/
@@ -268,12 +481,12 @@ hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_advance_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_h_advance_func_t.
*
* Since: 0.9.2
**/
@@ -284,12 +497,12 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_v_advance_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_v_advance_func_t.
*
* Since: 0.9.2
**/
@@ -300,12 +513,12 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_advances_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_h_advances_func_t.
*
* Since: 1.8.6
**/
@@ -316,12 +529,12 @@ hb_font_funcs_set_glyph_h_advances_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_v_advances_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_v_advances_func_t.
*
* Since: 1.8.6
**/
@@ -332,12 +545,12 @@ hb_font_funcs_set_glyph_v_advances_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_origin_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_h_origin_func_t.
*
* Since: 0.9.2
**/
@@ -348,12 +561,12 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_v_origin_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_v_origin_func_t.
*
* Since: 0.9.2
**/
@@ -380,12 +593,12 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_extents_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_extents_func_t.
*
* Since: 0.9.2
**/
@@ -396,12 +609,12 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_contour_point_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_contour_point_func_t.
*
* Since: 0.9.2
**/
@@ -412,12 +625,12 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_name_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_name_func_t.
*
* Since: 0.9.2
**/
@@ -428,12 +641,12 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_from_name_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_font_get_glyph_from_name_func_t.
*
* Since: 0.9.2
**/
diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc
index 2680873c27..ab7d6146ce 100644
--- a/thirdparty/harfbuzz/src/hb-ft.cc
+++ b/thirdparty/harfbuzz/src/hb-ft.cc
@@ -661,7 +661,7 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data
/**
* hb_ft_face_create:
* @ft_face: (destroy destroy) (scope notified): FT_Face to work upon
- * @destroy: A callback to call when the face object is not needed anymore
+ * @destroy: (optional): A callback to call when the face object is not needed anymore
*
* Creates an #hb_face_t face object from the specified FT_Face.
*
diff --git a/thirdparty/harfbuzz/src/hb-gdi.cc b/thirdparty/harfbuzz/src/hb-gdi.cc
index f6306ef89f..3a67cef160 100644
--- a/thirdparty/harfbuzz/src/hb-gdi.cc
+++ b/thirdparty/harfbuzz/src/hb-gdi.cc
@@ -28,6 +28,16 @@
#include "hb-gdi.h"
+
+/**
+ * SECTION:hb-gdi
+ * @title: hb-gdi
+ * @short_description: GDI integration
+ * @include: hb-gdi.h
+ *
+ * Functions for using HarfBuzz with GDI fonts.
+ **/
+
static hb_blob_t *
_hb_gdi_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
{
diff --git a/thirdparty/harfbuzz/src/hb-map.cc b/thirdparty/harfbuzz/src/hb-map.cc
index 191be14372..f898bd8f92 100644
--- a/thirdparty/harfbuzz/src/hb-map.cc
+++ b/thirdparty/harfbuzz/src/hb-map.cc
@@ -42,7 +42,9 @@
/**
* hb_map_create: (Xconstructor)
*
- * Return value: (transfer full):
+ * Creates a new, initially empty map.
+ *
+ * Return value: (transfer full): The new #hb_map_t
*
* Since: 1.7.7
**/
@@ -62,7 +64,9 @@ hb_map_create ()
/**
* hb_map_get_empty:
*
- * Return value: (transfer full):
+ * Fetches the singleton empty #hb_map_t.
+ *
+ * Return value: (transfer full): The empty #hb_map_t
*
* Since: 1.7.7
**/
@@ -74,9 +78,11 @@ hb_map_get_empty ()
/**
* hb_map_reference: (skip)
- * @map: a map.
+ * @map: A map
+ *
+ * Increases the reference count on a map.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): The map
*
* Since: 1.7.7
**/
@@ -88,7 +94,11 @@ hb_map_reference (hb_map_t *map)
/**
* hb_map_destroy: (skip)
- * @map: a map.
+ * @map: A map
+ *
+ * Decreases the reference count on a map. When
+ * the reference count reaches zero, the map is
+ * destroyed, freeing all memory.
*
* Since: 1.7.7
**/
@@ -104,13 +114,15 @@ hb_map_destroy (hb_map_t *map)
/**
* hb_map_set_user_data: (skip)
- * @map: a map.
- * @key:
- * @data:
- * @destroy:
- * @replace:
+ * @map: A map
+ * @key: The user-data key to set
+ * @data: A pointer to the user data to set
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
+ *
+ * Attaches a user-data key/data pair to the specified map.
*
- * Return value:
+ * Return value: %true if success, %false otherwise
*
* Since: 1.7.7
**/
@@ -126,10 +138,13 @@ hb_map_set_user_data (hb_map_t *map,
/**
* hb_map_get_user_data: (skip)
- * @map: a map.
- * @key:
+ * @map: A map
+ * @key: The user-data key to query
+ *
+ * Fetches the user data associated with the specified key,
+ * attached to the specified map.
*
- * Return value: (transfer none):
+ * Return value: (transfer none): A pointer to the user data
*
* Since: 1.7.7
**/
@@ -143,11 +158,11 @@ hb_map_get_user_data (hb_map_t *map,
/**
* hb_map_allocation_successful:
- * @map: a map.
+ * @map: A map
*
+ * Tests whether memory allocation for a set was successful.
*
- *
- * Return value:
+ * Return value: %true if allocation succeeded, false otherwise
*
* Since: 1.7.7
**/
@@ -160,11 +175,11 @@ hb_map_allocation_successful (const hb_map_t *map)
/**
* hb_map_set:
- * @map: a map.
- * @key:
- * @value:
- *
+ * @map: A map
+ * @key: The key to store in the map
+ * @value: The value to store for @key
*
+ * Stores @key:@value in the map.
*
* Since: 1.7.7
**/
@@ -178,10 +193,10 @@ hb_map_set (hb_map_t *map,
/**
* hb_map_get:
- * @map: a map.
- * @key:
- *
+ * @map: A map
+ * @key: The key to query
*
+ * Fetches the value stored for @key in @map.
*
* Since: 1.7.7
**/
@@ -194,10 +209,10 @@ hb_map_get (const hb_map_t *map,
/**
* hb_map_del:
- * @map: a map.
- * @key:
- *
+ * @map: A map
+ * @key: The key to delete
*
+ * Removes @key and its stored value from @map.
*
* Since: 1.7.7
**/
@@ -210,10 +225,12 @@ hb_map_del (hb_map_t *map,
/**
* hb_map_has:
- * @map: a map.
- * @key:
+ * @map: A map
+ * @key: The key to query
*
+ * Tests whether @key is an element of @map.
*
+ * Return value: %true if @key is found in @map, false otherwise
*
* Since: 1.7.7
**/
@@ -227,9 +244,9 @@ hb_map_has (const hb_map_t *map,
/**
* hb_map_clear:
- * @map: a map.
- *
+ * @map: A map
*
+ * Clears out the contents of @map.
*
* Since: 1.7.7
**/
@@ -241,9 +258,11 @@ hb_map_clear (hb_map_t *map)
/**
* hb_map_is_empty:
- * @map: a map.
+ * @map: A map
*
+ * Tests whether @map is empty (contains no elements).
*
+ * Return value: %true if @map is empty
*
* Since: 1.7.7
**/
@@ -255,9 +274,11 @@ hb_map_is_empty (const hb_map_t *map)
/**
* hb_map_get_population:
- * @map: a map.
+ * @map: A map
*
+ * Returns the number of key-value pairs in the map.
*
+ * Return value: The population of @map
*
* Since: 1.7.7
**/
diff --git a/thirdparty/harfbuzz/src/hb-map.h b/thirdparty/harfbuzz/src/hb-map.h
index b77843c2ba..0c19ac8fb5 100644
--- a/thirdparty/harfbuzz/src/hb-map.h
+++ b/thirdparty/harfbuzz/src/hb-map.h
@@ -41,6 +41,12 @@ HB_BEGIN_DECLS
*/
#define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1)
+/**
+ * hb_map_t:
+ *
+ * Data type for holding integer-to-integer hash maps.
+ *
+ **/
typedef struct hb_map_t hb_map_t;
diff --git a/thirdparty/harfbuzz/src/hb-null.hh b/thirdparty/harfbuzz/src/hb-null.hh
index 9853939b07..d09f858cde 100644
--- a/thirdparty/harfbuzz/src/hb-null.hh
+++ b/thirdparty/harfbuzz/src/hb-null.hh
@@ -177,6 +177,7 @@ struct hb_nonnull_ptr_t
T * get () const { return v ? v : const_cast<T *> (&Null (T)); }
T * get_raw () const { return v; }
+ private:
T *v;
};
diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh
index 50558cf8d3..99634b76f0 100644
--- a/thirdparty/harfbuzz/src/hb-open-type.hh
+++ b/thirdparty/harfbuzz/src/hb-open-type.hh
@@ -433,8 +433,6 @@ struct UnsizedArrayOf
{ return hb_array (arrayZ, len); }
hb_array_t<const Type> as_array (unsigned int len) const
{ return hb_array (arrayZ, len); }
- operator hb_array_t< Type> () { return as_array (); }
- operator hb_array_t<const Type> () const { return as_array (); }
template <typename T>
Type &lsearch (unsigned int len, const T &x, Type &not_found = Crap (Type))
diff --git a/thirdparty/harfbuzz/src/hb-ot-color.h b/thirdparty/harfbuzz/src/hb-ot-color.h
index 63ef20a1a0..4f37a4386f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color.h
+++ b/thirdparty/harfbuzz/src/hb-ot-color.h
@@ -100,8 +100,7 @@ hb_ot_color_has_layers (hb_face_t *face);
*
* Since: 2.1.0
**/
-typedef struct hb_ot_color_layer_t
-{
+typedef struct hb_ot_color_layer_t {
hb_codepoint_t glyph;
unsigned int color_index;
} hb_ot_color_layer_t;
diff --git a/thirdparty/harfbuzz/src/hb-ot-deprecated.h b/thirdparty/harfbuzz/src/hb-ot-deprecated.h
index bc72f8a701..2e75deef2d 100644
--- a/thirdparty/harfbuzz/src/hb-ot-deprecated.h
+++ b/thirdparty/harfbuzz/src/hb-ot-deprecated.h
@@ -82,8 +82,7 @@ hb_ot_tag_from_language (hb_language_t language);
* Since: 1.4.2
* Deprecated: 2.2.0
*/
-typedef struct hb_ot_var_axis_t
-{
+typedef struct hb_ot_var_axis_t {
hb_tag_t tag;
hb_ot_name_id_t name_id;
float min_value;
diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc
index a1dc88603a..fae7b5b65a 100644
--- a/thirdparty/harfbuzz/src/hb-ot-font.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-font.cc
@@ -306,6 +306,9 @@ _hb_ot_get_font_funcs ()
/**
* hb_ot_font_set_funcs:
+ * @font: #hb_font_t to work upon
+ *
+ * Sets the font functions to use when working with @font.
*
* Since: 0.9.28
**/
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh
index 02fe14fa06..4df0d942ce 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh
@@ -379,12 +379,20 @@ struct Axis
const BaseCoord **coord) const
{
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
- if (!base_script.has_data ()) return false;
+ if (!base_script.has_data ())
+ {
+ *coord = nullptr;
+ return false;
+ }
if (likely (coord))
{
unsigned int tag_index = 0;
- (this+baseTagList).bfind (baseline_tag, &tag_index);
+ if (!(this+baseTagList).bfind (baseline_tag, &tag_index))
+ {
+ *coord = nullptr;
+ return false;
+ }
*coord = &base_script.get_base_coord (tag_index);
}
@@ -398,7 +406,11 @@ struct Axis
const BaseCoord **max_coord) const
{
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
- if (!base_script.has_data ()) return false;
+ if (!base_script.has_data ())
+ {
+ *min_coord = *max_coord = nullptr;
+ return false;
+ }
base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
index 3140dd6328..6ab950a322 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
@@ -2537,7 +2537,10 @@ struct VariationStore
for (unsigned i = 0; i < inner_maps.length; i++)
inner_maps[i].fini ();
- return_trace (bool (varstore_prime->dataSets));
+
+ return_trace (
+ !c->serializer->in_error()
+ && varstore_prime->dataSets);
}
unsigned int get_region_index_count (unsigned int ivs) const
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
index 03a578cec0..cb95e6dcd5 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
@@ -1859,7 +1859,7 @@ struct ContextFormat2
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
bool ret = true;
- unsigned non_zero_index = 0, index = 0;
+ int non_zero_index = 0, index = 0;
for (const hb_pair_t<unsigned, const OffsetTo<RuleSet>&> _ : + hb_enumerate (ruleSet)
| hb_filter (klass_map, hb_first))
{
@@ -3378,7 +3378,11 @@ struct GSUBGPOS
this->accels = (hb_ot_layout_lookup_accelerator_t *) calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t));
if (unlikely (!this->accels))
+ {
this->lookup_count = 0;
+ this->table.destroy ();
+ this->table = hb_blob_get_empty ();
+ }
for (unsigned int i = 0; i < this->lookup_count; i++)
this->accels[i].init (table->get_lookup (i));
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc
index 46408bb9d3..f25f0f9e23 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc
@@ -76,7 +76,7 @@
* Tests whether a face includes any kerning data in the 'kern' table.
* Does NOT test for kerning lookups in the GPOS table.
*
- * Return value: true if data found, false otherwise
+ * Return value: %true if data found, false otherwise
*
**/
bool
@@ -92,7 +92,7 @@ hb_ot_layout_has_kerning (hb_face_t *face)
* Tests whether a face includes any state-machine kerning in the 'kern' table.
* Does NOT examine the GPOS table.
*
- * Return value: true if data found, false otherwise
+ * Return value: %true if data found, false otherwise
*
**/
bool
@@ -112,7 +112,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face)
*
* Does NOT examine the GPOS table.
*
- * Return value: true is data found, false otherwise
+ * Return value: %true is data found, false otherwise
*
**/
bool
@@ -268,7 +268,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font,
*
* Tests whether a face has any glyph classes defined in its GDEF table.
*
- * Return value: true if data found, false otherwise
+ * Return value: %true if data found, false otherwise
*
**/
hb_bool_t
@@ -444,7 +444,7 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face,
* Fetches the index if a given script tag in the specified face's GSUB table
* or GPOS table.
*
- * Return value: true if the script is found, false otherwise
+ * Return value: %true if the script is found, false otherwise
*
**/
hb_bool_t
@@ -598,7 +598,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face,
* Fetches the index for a given feature tag in the specified face's GSUB table
* or GPOS table.
*
- * Return value: true if the feature is found, false otherwise
+ * Return value: %true if the feature is found, false otherwise
**/
bool
hb_ot_layout_table_find_feature (hb_face_t *face,
@@ -663,7 +663,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
* Fetches the index of a given language tag in the specified face's GSUB table
* or GPOS table, underneath the specified script tag.
*
- * Return value: true if the language tag is found, false otherwise
+ * Return value: %true if the language tag is found, false otherwise
*
* Since: ??
* Deprecated: ??
@@ -697,7 +697,7 @@ hb_ot_layout_script_find_language (hb_face_t *face,
* Fetches the index of a given language tag in the specified face's GSUB table
* or GPOS table, underneath the specified script index.
*
- * Return value: true if the language tag is found, false otherwise
+ * Return value: %true if the language tag is found, false otherwise
*
* Since: 2.0.0
**/
@@ -739,7 +739,7 @@ hb_ot_layout_script_select_language (hb_face_t *face,
* Fetches the index of a requested feature in the given face's GSUB or GPOS table,
* underneath the specified script and language.
*
- * Return value: true if the feature is found, false otherwise
+ * Return value: %true if the feature is found, false otherwise
*
**/
hb_bool_t
@@ -770,7 +770,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
* Fetches the tag of a requested feature index in the given face's GSUB or GPOS table,
* underneath the specified script and language.
*
- * Return value: true if the feature is found, false otherwise
+ * Return value: %true if the feature is found, false otherwise
*
* Since: 0.9.30
**/
@@ -877,7 +877,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
* Fetches the index of a given feature tag in the specified face's GSUB table
* or GPOS table, underneath the specified script and language.
*
- * Return value: true if the feature is found, false otherwise
+ * Return value: %true if the feature is found, false otherwise
*
**/
hb_bool_t
@@ -1196,7 +1196,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
* @glyphs_before: (out): Array of glyphs preceding the substitution range
* @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup
* @glyphs_after: (out): Array of glyphs following the substitution range
- * @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
+ * @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup
*
* Fetches a list of all glyphs affected by the specified lookup in the
* specified face's GSUB table or GPOS table.
@@ -1245,7 +1245,7 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @coords: The variation coordinates to query
- * @num_coords: The number of variation coorinates
+ * @num_coords: The number of variation coordinates
* @variations_index: (out): The array of feature variations found for the query
*
* Fetches a list of feature variations in the specified face's GSUB table
@@ -1310,7 +1310,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
*
* Tests whether the specified face includes any GSUB substitutions.
*
- * Return value: true if data found, false otherwise
+ * Return value: %true if data found, false otherwise
*
**/
hb_bool_t
@@ -1331,7 +1331,7 @@ hb_ot_layout_has_substitution (hb_face_t *face)
* Tests whether a specified lookup in the specified face would
* trigger a substitution on the given glyph sequence.
*
- * Return value: true if a substitution would be triggered, false otherwise
+ * Return value: %true if a substitution would be triggered, false otherwise
*
* Since: 0.9.7
**/
@@ -1488,7 +1488,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
* hb_ot_layout_has_positioning:
* @face: #hb_face_t to work upon
*
- * Return value: true if the face has GPOS data, false otherwise
+ * Return value: %true if the face has GPOS data, false otherwise
*
**/
hb_bool_t
@@ -1561,7 +1561,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
* For more information on this distinction, see the [`size` feature documentation](
* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size).
*
- * Return value: true if data found, false otherwise
+ * Return value: %true if data found, false otherwise
*
* Since: 0.9.10
**/
@@ -1625,7 +1625,7 @@ hb_ot_layout_get_size_params (hb_face_t *face,
* Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or
* "Character Variant" ('cvXX') features.
*
- * Return value: true if data found, false otherwise
+ * Return value: %true if data found, false otherwise
*
* Since: 2.0.0
**/
@@ -1881,7 +1881,7 @@ void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, h
GSUBProxy proxy (font->face);
if (!buffer->message (font, "start table GSUB")) return;
apply (proxy, plan, font, buffer);
- (void)buffer->message (font, "end table GSUB");
+ (void) buffer->message (font, "end table GSUB");
}
void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
@@ -1889,7 +1889,7 @@ void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_
GPOSProxy proxy (font->face);
if (!buffer->message (font, "start table GPOS")) return;
apply (proxy, plan, font, buffer);
- (void)buffer->message (font, "end table GPOS");
+ (void) buffer->message (font, "end table GPOS");
}
void
diff --git a/thirdparty/harfbuzz/src/hb-ot-map.hh b/thirdparty/harfbuzz/src/hb-ot-map.hh
index 7629a869bd..5f2afae281 100644
--- a/thirdparty/harfbuzz/src/hb-ot-map.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-map.hh
@@ -140,12 +140,12 @@ struct hb_ot_map_t
void get_stage_lookups (unsigned int table_index, unsigned int stage,
const struct lookup_map_t **plookups, unsigned int *lookup_count) const
{
- if (unlikely (stage == UINT_MAX)) {
+ if (unlikely (stage > stages[table_index].length))
+ {
*plookups = nullptr;
*lookup_count = 0;
return;
}
- assert (stage <= stages[table_index].length);
unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0;
unsigned int end = stage < stages[table_index].length ? stages[table_index][stage].last_lookup : lookups[table_index].length;
*plookups = end == start ? nullptr : &lookups[table_index][start];
diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.cc b/thirdparty/harfbuzz/src/hb-ot-metrics.cc
index 181ac4d57e..3065ea2adf 100644
--- a/thirdparty/harfbuzz/src/hb-ot-metrics.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-metrics.cc
@@ -33,6 +33,15 @@
#include "hb-ot-face.hh"
+/**
+ * SECTION:hb-ot-metrics
+ * @title: hb-ot-metrics
+ * @short_description: OpenType Metrics
+ * @include: hb-ot.h
+ *
+ * Functions for fetching metrics from fonts.
+ **/
+
static float
_fix_ascender_descender (float value, hb_ot_metrics_tag_t metrics_tag)
{
diff --git a/thirdparty/harfbuzz/src/hb-ot-name.h b/thirdparty/harfbuzz/src/hb-ot-name.h
index 3b4ad581c7..6f3fcd2427 100644
--- a/thirdparty/harfbuzz/src/hb-ot-name.h
+++ b/thirdparty/harfbuzz/src/hb-ot-name.h
@@ -88,8 +88,7 @@ typedef unsigned int hb_ot_name_id_t;
*
* Since: 2.1.0
**/
-typedef struct hb_ot_name_entry_t
-{
+typedef struct hb_ot_name_entry_t {
hb_ot_name_id_t name_id;
/*< private >*/
hb_var_int_t var;
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc
index 34972f81e2..652ef47040 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc
@@ -1006,11 +1006,14 @@ initial_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
+ if (!buffer->message (font, "start reordering indic initial"))
+ return;
update_consonant_positions_indic (plan, font, buffer);
insert_dotted_circles_indic (plan, font, buffer);
foreach_syllable (buffer, start, end)
initial_reordering_syllable_indic (plan, font->face, buffer, start, end);
+ (void) buffer->message (font, "end reordering indic initial");
}
static void
@@ -1485,8 +1488,11 @@ final_reordering_indic (const hb_ot_shape_plan_t *plan,
unsigned int count = buffer->len;
if (unlikely (!count)) return;
- foreach_syllable (buffer, start, end)
- final_reordering_syllable_indic (plan, buffer, start, end);
+ if (buffer->message (font, "start reordering indic final")) {
+ foreach_syllable (buffer, start, end)
+ final_reordering_syllable_indic (plan, buffer, start, end);
+ (void) buffer->message (font, "end reordering indic final");
+ }
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc
index 3da8374899..d6fcd7c814 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc
@@ -389,11 +389,13 @@ reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- insert_dotted_circles_khmer (plan, font, buffer);
-
- foreach_syllable (buffer, start, end)
- reorder_syllable_khmer (plan, font->face, buffer, start, end);
+ if (buffer->message (font, "start reordering khmer")) {
+ insert_dotted_circles_khmer (plan, font, buffer);
+ foreach_syllable (buffer, start, end)
+ reorder_syllable_khmer (plan, font->face, buffer, start, end);
+ (void) buffer->message (font, "end reordering khmer");
+ }
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-machine-index.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-machine-index.hh
new file mode 100644
index 0000000000..9ec1f3eb7c
--- /dev/null
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-machine-index.hh
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2019,2020 David Corbett
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_MACHINE_INDEX_HH
+#define HB_OT_SHAPE_COMPLEX_MACHINE_INDEX_HH
+
+#include "hb.hh"
+
+
+template <typename Iter>
+struct machine_index_t :
+ hb_iter_with_fallback_t<machine_index_t<Iter>,
+ typename Iter::item_t>
+{
+ machine_index_t (const Iter& it) : it (it) {}
+ machine_index_t (const machine_index_t& o) : it (o.it) {}
+
+ static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
+ static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
+
+ typename Iter::item_t __item__ () const { return *it; }
+ typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; }
+ unsigned __len__ () const { return it.len (); }
+ void __next__ () { ++it; }
+ void __forward__ (unsigned n) { it += n; }
+ void __prev__ () { --it; }
+ void __rewind__ (unsigned n) { it -= n; }
+ void operator = (unsigned n)
+ { unsigned index = (*it).first; if (index < n) it += n - index; else if (index > n) it -= index - n; }
+ void operator = (const machine_index_t& o) { *this = (*o.it).first; }
+ bool operator == (const machine_index_t& o) const { return (*it).first == (*o.it).first; }
+ bool operator != (const machine_index_t& o) const { return !(*this == o); }
+
+ private:
+ Iter it;
+};
+struct
+{
+ template <typename Iter,
+ hb_requires (hb_is_iterable (Iter))>
+ machine_index_t<hb_iter_type<Iter>>
+ operator () (Iter&& it) const
+ { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); }
+}
+HB_FUNCOBJ (machine_index);
+
+
+#endif /* HB_OT_SHAPE_COMPLEX_MACHINE_INDEX_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
index fc3490d716..fe096ef28a 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
@@ -97,12 +97,6 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
}
-static void
-override_features_myanmar (hb_ot_shape_planner_t *plan)
-{
- plan->map.disable_feature (HB_TAG('l','i','g','a'));
-}
-
enum myanmar_syllable_type_t {
myanmar_consonant_syllable,
@@ -333,10 +327,13 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- insert_dotted_circles_myanmar (plan, font, buffer);
+ if (buffer->message (font, "start reordering myanmar")) {
+ insert_dotted_circles_myanmar (plan, font, buffer);
- foreach_syllable (buffer, start, end)
- reorder_syllable_myanmar (plan, font->face, buffer, start, end);
+ foreach_syllable (buffer, start, end)
+ reorder_syllable_myanmar (plan, font->face, buffer, start, end);
+ (void) buffer->message (font, "end reordering myanmar");
+ }
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
@@ -346,7 +343,7 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan,
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
{
collect_features_myanmar,
- override_features_myanmar,
+ nullptr, /* override_features */
nullptr, /* data_create */
nullptr, /* data_destroy */
nullptr, /* preprocess_text */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh
index 462342c618..144e7d3a40 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh
@@ -32,367 +32,326 @@
#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
#include "hb.hh"
+#include "hb-ot-shape-complex-machine-index.hh"
-#line 38 "hb-ot-shape-complex-use-machine.hh"
+#line 39 "hb-ot-shape-complex-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = {
- 12u, 48u, 1u, 15u, 1u, 1u, 12u, 48u, 1u, 1u, 0u, 48u, 21u, 21u, 11u, 48u,
- 11u, 48u, 1u, 15u, 1u, 1u, 11u, 48u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u,
- 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u,
- 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 11u, 48u,
- 1u, 48u, 11u, 48u, 13u, 21u, 4u, 4u, 13u, 13u, 11u, 48u, 11u, 48u, 41u, 42u,
- 42u, 42u, 11u, 48u, 11u, 48u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u,
- 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u,
- 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 11u, 48u, 1u, 48u, 1u, 15u,
- 4u, 4u, 13u, 21u, 13u, 13u, 12u, 48u, 1u, 48u, 11u, 48u, 41u, 42u, 42u, 42u,
- 21u, 42u, 1u, 5u, 0
+ 1u, 1u, 1u, 1u, 0u, 51u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u,
+ 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u,
+ 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u,
+ 11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u,
+ 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u,
+ 24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u,
+ 22u, 48u, 11u, 48u, 1u, 48u, 1u, 1u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u,
+ 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0
};
static const char _use_syllable_machine_key_spans[] = {
- 37, 15, 1, 37, 1, 49, 1, 38,
- 38, 15, 1, 38, 27, 26, 24, 23,
- 22, 2, 1, 25, 25, 25, 1, 25,
- 26, 26, 26, 27, 27, 27, 27, 38,
- 48, 38, 9, 1, 1, 38, 38, 2,
- 1, 38, 38, 27, 26, 24, 23, 22,
- 2, 1, 25, 25, 25, 25, 26, 26,
- 26, 27, 27, 27, 27, 38, 48, 15,
- 1, 9, 1, 37, 48, 38, 2, 1,
- 22, 5
+ 1, 1, 52, 38, 38, 1, 27, 26,
+ 24, 23, 22, 2, 1, 25, 25, 25,
+ 1, 25, 26, 26, 26, 27, 27, 27,
+ 38, 48, 1, 1, 38, 2, 1, 38,
+ 27, 26, 24, 23, 22, 2, 1, 25,
+ 25, 25, 25, 26, 26, 26, 27, 27,
+ 27, 38, 48, 1, 1, 1, 48, 38,
+ 2, 1, 5, 3, 4, 3
};
static const short _use_syllable_machine_index_offsets[] = {
- 0, 38, 54, 56, 94, 96, 146, 148,
- 187, 226, 242, 244, 283, 311, 338, 363,
- 387, 410, 413, 415, 441, 467, 493, 495,
- 521, 548, 575, 602, 630, 658, 686, 714,
- 753, 802, 841, 851, 853, 855, 894, 933,
- 936, 938, 977, 1016, 1044, 1071, 1096, 1120,
- 1143, 1146, 1148, 1174, 1200, 1226, 1252, 1279,
- 1306, 1333, 1361, 1389, 1417, 1445, 1484, 1533,
- 1549, 1551, 1561, 1563, 1601, 1650, 1689, 1692,
- 1694, 1717
+ 0, 2, 4, 57, 96, 135, 137, 165,
+ 192, 217, 241, 264, 267, 269, 295, 321,
+ 347, 349, 375, 402, 429, 456, 484, 512,
+ 540, 579, 628, 630, 632, 671, 674, 676,
+ 715, 743, 770, 795, 819, 842, 845, 847,
+ 873, 899, 925, 951, 978, 1005, 1032, 1060,
+ 1088, 1116, 1155, 1204, 1206, 1208, 1210, 1259,
+ 1298, 1301, 1303, 1309, 1313, 1318
};
static const char _use_syllable_machine_indicies[] = {
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 1, 0, 3, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 4, 2, 3, 2,
- 6, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 6, 5, 5, 5, 6, 5, 7, 5,
- 8, 9, 10, 8, 11, 12, 10, 10,
- 10, 10, 10, 3, 13, 14, 10, 15,
- 8, 8, 16, 17, 10, 10, 18, 19,
- 20, 21, 22, 23, 24, 18, 25, 26,
- 27, 28, 29, 30, 10, 31, 32, 33,
- 10, 34, 35, 36, 37, 38, 39, 40,
- 13, 10, 42, 41, 44, 1, 43, 43,
- 45, 43, 43, 43, 43, 43, 46, 47,
- 48, 49, 50, 51, 52, 53, 47, 54,
- 46, 55, 56, 57, 58, 43, 59, 60,
- 61, 43, 43, 43, 43, 62, 63, 64,
- 65, 1, 43, 44, 1, 43, 43, 45,
- 43, 43, 43, 43, 43, 66, 47, 48,
- 49, 50, 51, 52, 53, 47, 54, 55,
- 55, 56, 57, 58, 43, 59, 60, 61,
- 43, 43, 43, 43, 62, 63, 64, 65,
- 1, 43, 44, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 67,
- 68, 67, 44, 67, 44, 1, 43, 43,
- 45, 43, 43, 43, 43, 43, 43, 47,
- 48, 49, 50, 51, 52, 53, 47, 54,
- 55, 55, 56, 57, 58, 43, 59, 60,
- 61, 43, 43, 43, 43, 62, 63, 64,
- 65, 1, 43, 47, 48, 49, 50, 51,
- 43, 43, 43, 43, 43, 43, 56, 57,
- 58, 43, 59, 60, 61, 43, 43, 43,
- 43, 48, 63, 64, 65, 69, 43, 48,
- 49, 50, 51, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 59, 60, 61,
- 43, 43, 43, 43, 43, 63, 64, 65,
- 69, 43, 49, 50, 51, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 63,
- 64, 65, 43, 50, 51, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 63,
- 64, 65, 43, 51, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 63, 64,
- 65, 43, 63, 64, 43, 64, 43, 49,
- 50, 51, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 59, 60, 61, 43,
- 43, 43, 43, 43, 63, 64, 65, 69,
- 43, 49, 50, 51, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 60,
- 61, 43, 43, 43, 43, 43, 63, 64,
- 65, 69, 43, 49, 50, 51, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 61, 43, 43, 43, 43, 43,
- 63, 64, 65, 69, 43, 71, 70, 49,
- 50, 51, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 63, 64, 65, 69,
- 43, 48, 49, 50, 51, 43, 43, 43,
- 43, 43, 43, 56, 57, 58, 43, 59,
- 60, 61, 43, 43, 43, 43, 48, 63,
- 64, 65, 69, 43, 48, 49, 50, 51,
- 43, 43, 43, 43, 43, 43, 43, 57,
- 58, 43, 59, 60, 61, 43, 43, 43,
- 43, 48, 63, 64, 65, 69, 43, 48,
- 49, 50, 51, 43, 43, 43, 43, 43,
- 43, 43, 43, 58, 43, 59, 60, 61,
- 43, 43, 43, 43, 48, 63, 64, 65,
- 69, 43, 47, 48, 49, 50, 51, 43,
- 53, 47, 43, 43, 43, 56, 57, 58,
- 43, 59, 60, 61, 43, 43, 43, 43,
- 48, 63, 64, 65, 69, 43, 47, 48,
- 49, 50, 51, 43, 72, 47, 43, 43,
- 43, 56, 57, 58, 43, 59, 60, 61,
- 43, 43, 43, 43, 48, 63, 64, 65,
- 69, 43, 47, 48, 49, 50, 51, 43,
- 43, 47, 43, 43, 43, 56, 57, 58,
- 43, 59, 60, 61, 43, 43, 43, 43,
- 48, 63, 64, 65, 69, 43, 47, 48,
- 49, 50, 51, 52, 53, 47, 43, 43,
- 43, 56, 57, 58, 43, 59, 60, 61,
- 43, 43, 43, 43, 48, 63, 64, 65,
- 69, 43, 44, 1, 43, 43, 45, 43,
- 43, 43, 43, 43, 43, 47, 48, 49,
- 50, 51, 52, 53, 47, 54, 43, 55,
- 56, 57, 58, 43, 59, 60, 61, 43,
- 43, 43, 43, 62, 63, 64, 65, 1,
- 43, 44, 67, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 68,
- 67, 67, 67, 67, 67, 67, 67, 48,
- 49, 50, 51, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 59, 60, 61,
- 67, 67, 67, 67, 67, 63, 64, 65,
- 69, 67, 44, 1, 43, 43, 45, 43,
- 43, 43, 43, 43, 43, 47, 48, 49,
- 50, 51, 52, 53, 47, 54, 46, 55,
- 56, 57, 58, 43, 59, 60, 61, 43,
- 43, 43, 43, 62, 63, 64, 65, 1,
- 43, 74, 73, 73, 73, 73, 73, 73,
- 73, 75, 73, 11, 76, 74, 73, 44,
- 1, 43, 43, 45, 43, 43, 43, 43,
- 43, 77, 47, 48, 49, 50, 51, 52,
- 53, 47, 54, 46, 55, 56, 57, 58,
- 43, 59, 60, 61, 43, 78, 79, 43,
- 62, 63, 64, 65, 1, 43, 44, 1,
- 43, 43, 45, 43, 43, 43, 43, 43,
- 43, 47, 48, 49, 50, 51, 52, 53,
- 47, 54, 46, 55, 56, 57, 58, 43,
- 59, 60, 61, 43, 78, 79, 43, 62,
- 63, 64, 65, 1, 43, 78, 79, 80,
- 79, 80, 3, 6, 81, 81, 82, 81,
- 81, 81, 81, 81, 83, 18, 19, 20,
- 21, 22, 23, 24, 18, 25, 27, 27,
- 28, 29, 30, 81, 31, 32, 33, 81,
- 81, 81, 81, 37, 38, 39, 40, 6,
- 81, 3, 6, 81, 81, 82, 81, 81,
- 81, 81, 81, 81, 18, 19, 20, 21,
- 22, 23, 24, 18, 25, 27, 27, 28,
- 29, 30, 81, 31, 32, 33, 81, 81,
- 81, 81, 37, 38, 39, 40, 6, 81,
- 18, 19, 20, 21, 22, 81, 81, 81,
- 81, 81, 81, 28, 29, 30, 81, 31,
- 32, 33, 81, 81, 81, 81, 19, 38,
- 39, 40, 84, 81, 19, 20, 21, 22,
- 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 31, 32, 33, 81, 81, 81,
- 81, 81, 38, 39, 40, 84, 81, 20,
- 21, 22, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 38, 39, 40, 81,
- 21, 22, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 38, 39, 40, 81,
- 22, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 38, 39, 40, 81, 38,
- 39, 81, 39, 81, 20, 21, 22, 81,
- 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 31, 32, 33, 81, 81, 81, 81,
- 81, 38, 39, 40, 84, 81, 20, 21,
- 22, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 32, 33, 81, 81,
- 81, 81, 81, 38, 39, 40, 84, 81,
- 20, 21, 22, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 33,
- 81, 81, 81, 81, 81, 38, 39, 40,
- 84, 81, 20, 21, 22, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 38,
- 39, 40, 84, 81, 19, 20, 21, 22,
- 81, 81, 81, 81, 81, 81, 28, 29,
- 30, 81, 31, 32, 33, 81, 81, 81,
- 81, 19, 38, 39, 40, 84, 81, 19,
- 20, 21, 22, 81, 81, 81, 81, 81,
- 81, 81, 29, 30, 81, 31, 32, 33,
- 81, 81, 81, 81, 19, 38, 39, 40,
- 84, 81, 19, 20, 21, 22, 81, 81,
- 81, 81, 81, 81, 81, 81, 30, 81,
- 31, 32, 33, 81, 81, 81, 81, 19,
- 38, 39, 40, 84, 81, 18, 19, 20,
- 21, 22, 81, 24, 18, 81, 81, 81,
- 28, 29, 30, 81, 31, 32, 33, 81,
- 81, 81, 81, 19, 38, 39, 40, 84,
- 81, 18, 19, 20, 21, 22, 81, 85,
- 18, 81, 81, 81, 28, 29, 30, 81,
- 31, 32, 33, 81, 81, 81, 81, 19,
- 38, 39, 40, 84, 81, 18, 19, 20,
- 21, 22, 81, 81, 18, 81, 81, 81,
- 28, 29, 30, 81, 31, 32, 33, 81,
- 81, 81, 81, 19, 38, 39, 40, 84,
- 81, 18, 19, 20, 21, 22, 23, 24,
- 18, 81, 81, 81, 28, 29, 30, 81,
- 31, 32, 33, 81, 81, 81, 81, 19,
- 38, 39, 40, 84, 81, 3, 6, 81,
- 81, 82, 81, 81, 81, 81, 81, 81,
- 18, 19, 20, 21, 22, 23, 24, 18,
- 25, 81, 27, 28, 29, 30, 81, 31,
- 32, 33, 81, 81, 81, 81, 37, 38,
- 39, 40, 6, 81, 3, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 4, 81, 81, 81, 81, 81,
- 81, 81, 19, 20, 21, 22, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81,
- 31, 32, 33, 81, 81, 81, 81, 81,
- 38, 39, 40, 84, 81, 3, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 4, 86, 87, 81, 14,
- 81, 81, 81, 81, 81, 81, 81, 88,
- 81, 14, 81, 6, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 6, 86, 86, 86, 6,
- 86, 9, 81, 81, 81, 9, 81, 81,
- 81, 81, 81, 3, 6, 14, 81, 82,
- 81, 81, 81, 81, 81, 81, 18, 19,
- 20, 21, 22, 23, 24, 18, 25, 26,
- 27, 28, 29, 30, 81, 31, 32, 33,
- 81, 34, 35, 81, 37, 38, 39, 40,
- 6, 81, 3, 6, 81, 81, 82, 81,
- 81, 81, 81, 81, 81, 18, 19, 20,
- 21, 22, 23, 24, 18, 25, 26, 27,
- 28, 29, 30, 81, 31, 32, 33, 81,
- 81, 81, 81, 37, 38, 39, 40, 6,
- 81, 34, 35, 81, 35, 81, 78, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 78, 79, 80, 9, 86, 86,
- 86, 9, 86, 0
+ 1, 0, 2, 0, 3, 4, 5, 5,
+ 6, 7, 5, 5, 5, 5, 5, 1,
+ 8, 9, 5, 5, 5, 5, 10, 11,
+ 5, 5, 12, 13, 14, 15, 16, 17,
+ 18, 12, 19, 20, 21, 22, 23, 24,
+ 5, 25, 26, 27, 5, 28, 29, 30,
+ 31, 32, 33, 34, 8, 35, 5, 36,
+ 5, 38, 39, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 40, 41, 42, 43,
+ 44, 45, 46, 40, 47, 4, 48, 49,
+ 50, 51, 37, 52, 53, 54, 37, 37,
+ 37, 37, 55, 56, 57, 58, 39, 37,
+ 38, 39, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 40, 41, 42, 43, 44,
+ 45, 46, 40, 47, 48, 48, 49, 50,
+ 51, 37, 52, 53, 54, 37, 37, 37,
+ 37, 55, 56, 57, 58, 39, 37, 38,
+ 59, 40, 41, 42, 43, 44, 37, 37,
+ 37, 37, 37, 37, 49, 50, 51, 37,
+ 52, 53, 54, 37, 37, 37, 37, 41,
+ 56, 57, 58, 60, 37, 41, 42, 43,
+ 44, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 52, 53, 54, 37, 37,
+ 37, 37, 37, 56, 57, 58, 60, 37,
+ 42, 43, 44, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 56, 57, 58,
+ 37, 43, 44, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 56, 57, 58,
+ 37, 44, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 56, 57, 58, 37,
+ 56, 57, 37, 57, 37, 42, 43, 44,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 52, 53, 54, 37, 37, 37,
+ 37, 37, 56, 57, 58, 60, 37, 42,
+ 43, 44, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 53, 54, 37,
+ 37, 37, 37, 37, 56, 57, 58, 60,
+ 37, 42, 43, 44, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 54, 37, 37, 37, 37, 37, 56, 57,
+ 58, 60, 37, 62, 61, 42, 43, 44,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 56, 57, 58, 60, 37, 41,
+ 42, 43, 44, 37, 37, 37, 37, 37,
+ 37, 49, 50, 51, 37, 52, 53, 54,
+ 37, 37, 37, 37, 41, 56, 57, 58,
+ 60, 37, 41, 42, 43, 44, 37, 37,
+ 37, 37, 37, 37, 37, 50, 51, 37,
+ 52, 53, 54, 37, 37, 37, 37, 41,
+ 56, 57, 58, 60, 37, 41, 42, 43,
+ 44, 37, 37, 37, 37, 37, 37, 37,
+ 37, 51, 37, 52, 53, 54, 37, 37,
+ 37, 37, 41, 56, 57, 58, 60, 37,
+ 40, 41, 42, 43, 44, 37, 46, 40,
+ 37, 37, 37, 49, 50, 51, 37, 52,
+ 53, 54, 37, 37, 37, 37, 41, 56,
+ 57, 58, 60, 37, 40, 41, 42, 43,
+ 44, 37, 37, 40, 37, 37, 37, 49,
+ 50, 51, 37, 52, 53, 54, 37, 37,
+ 37, 37, 41, 56, 57, 58, 60, 37,
+ 40, 41, 42, 43, 44, 45, 46, 40,
+ 37, 37, 37, 49, 50, 51, 37, 52,
+ 53, 54, 37, 37, 37, 37, 41, 56,
+ 57, 58, 60, 37, 38, 39, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 40,
+ 41, 42, 43, 44, 45, 46, 40, 47,
+ 37, 48, 49, 50, 51, 37, 52, 53,
+ 54, 37, 37, 37, 37, 55, 56, 57,
+ 58, 39, 37, 38, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 41, 42, 43, 44, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 52,
+ 53, 54, 59, 59, 59, 59, 59, 56,
+ 57, 58, 60, 59, 64, 63, 6, 65,
+ 38, 39, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 40, 41, 42, 43, 44,
+ 45, 46, 40, 47, 4, 48, 49, 50,
+ 51, 37, 52, 53, 54, 37, 11, 66,
+ 37, 55, 56, 57, 58, 39, 37, 11,
+ 66, 67, 66, 67, 1, 69, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 12,
+ 13, 14, 15, 16, 17, 18, 12, 19,
+ 21, 21, 22, 23, 24, 68, 25, 26,
+ 27, 68, 68, 68, 68, 31, 32, 33,
+ 34, 69, 68, 12, 13, 14, 15, 16,
+ 68, 68, 68, 68, 68, 68, 22, 23,
+ 24, 68, 25, 26, 27, 68, 68, 68,
+ 68, 13, 32, 33, 34, 70, 68, 13,
+ 14, 15, 16, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 25, 26, 27,
+ 68, 68, 68, 68, 68, 32, 33, 34,
+ 70, 68, 14, 15, 16, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 32,
+ 33, 34, 68, 15, 16, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 32,
+ 33, 34, 68, 16, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 32, 33,
+ 34, 68, 32, 33, 68, 33, 68, 14,
+ 15, 16, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 25, 26, 27, 68,
+ 68, 68, 68, 68, 32, 33, 34, 70,
+ 68, 14, 15, 16, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 26,
+ 27, 68, 68, 68, 68, 68, 32, 33,
+ 34, 70, 68, 14, 15, 16, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 27, 68, 68, 68, 68, 68,
+ 32, 33, 34, 70, 68, 14, 15, 16,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 32, 33, 34, 70, 68, 13,
+ 14, 15, 16, 68, 68, 68, 68, 68,
+ 68, 22, 23, 24, 68, 25, 26, 27,
+ 68, 68, 68, 68, 13, 32, 33, 34,
+ 70, 68, 13, 14, 15, 16, 68, 68,
+ 68, 68, 68, 68, 68, 23, 24, 68,
+ 25, 26, 27, 68, 68, 68, 68, 13,
+ 32, 33, 34, 70, 68, 13, 14, 15,
+ 16, 68, 68, 68, 68, 68, 68, 68,
+ 68, 24, 68, 25, 26, 27, 68, 68,
+ 68, 68, 13, 32, 33, 34, 70, 68,
+ 12, 13, 14, 15, 16, 68, 18, 12,
+ 68, 68, 68, 22, 23, 24, 68, 25,
+ 26, 27, 68, 68, 68, 68, 13, 32,
+ 33, 34, 70, 68, 12, 13, 14, 15,
+ 16, 68, 68, 12, 68, 68, 68, 22,
+ 23, 24, 68, 25, 26, 27, 68, 68,
+ 68, 68, 13, 32, 33, 34, 70, 68,
+ 12, 13, 14, 15, 16, 17, 18, 12,
+ 68, 68, 68, 22, 23, 24, 68, 25,
+ 26, 27, 68, 68, 68, 68, 13, 32,
+ 33, 34, 70, 68, 1, 69, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 12,
+ 13, 14, 15, 16, 17, 18, 12, 19,
+ 68, 21, 22, 23, 24, 68, 25, 26,
+ 27, 68, 68, 68, 68, 31, 32, 33,
+ 34, 69, 68, 1, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 13, 14, 15, 16, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 25,
+ 26, 27, 68, 68, 68, 68, 68, 32,
+ 33, 34, 70, 68, 1, 71, 72, 68,
+ 9, 68, 4, 68, 68, 68, 4, 68,
+ 68, 68, 68, 68, 1, 69, 9, 68,
+ 68, 68, 68, 68, 68, 68, 68, 12,
+ 13, 14, 15, 16, 17, 18, 12, 19,
+ 20, 21, 22, 23, 24, 68, 25, 26,
+ 27, 68, 28, 29, 68, 31, 32, 33,
+ 34, 69, 68, 1, 69, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 12, 13,
+ 14, 15, 16, 17, 18, 12, 19, 20,
+ 21, 22, 23, 24, 68, 25, 26, 27,
+ 68, 68, 68, 68, 31, 32, 33, 34,
+ 69, 68, 28, 29, 68, 29, 68, 4,
+ 71, 71, 71, 4, 71, 74, 73, 35,
+ 73, 35, 74, 73, 74, 73, 35, 73,
+ 36, 73, 0
};
static const char _use_syllable_machine_trans_targs[] = {
- 5, 9, 5, 41, 2, 5, 1, 53,
- 6, 7, 5, 34, 37, 63, 64, 67,
- 68, 72, 43, 44, 45, 46, 47, 57,
- 58, 60, 69, 61, 54, 55, 56, 50,
- 51, 52, 70, 71, 73, 62, 48, 49,
- 5, 5, 5, 5, 8, 0, 33, 12,
- 13, 14, 15, 16, 27, 28, 30, 31,
- 24, 25, 26, 19, 20, 21, 32, 17,
- 18, 5, 11, 5, 10, 22, 5, 23,
- 29, 5, 35, 36, 5, 38, 39, 40,
- 5, 5, 3, 42, 4, 59, 5, 65,
- 66
+ 2, 31, 42, 2, 3, 2, 26, 28,
+ 51, 52, 54, 29, 32, 33, 34, 35,
+ 36, 46, 47, 48, 55, 49, 43, 44,
+ 45, 39, 40, 41, 56, 57, 58, 50,
+ 37, 38, 2, 59, 61, 2, 4, 5,
+ 6, 7, 8, 9, 10, 21, 22, 23,
+ 24, 18, 19, 20, 13, 14, 15, 25,
+ 11, 12, 2, 2, 16, 2, 17, 2,
+ 27, 2, 30, 2, 2, 0, 1, 2,
+ 53, 2, 60
};
static const char _use_syllable_machine_trans_actions[] = {
- 1, 0, 2, 3, 0, 4, 0, 5,
- 0, 5, 8, 0, 5, 9, 0, 9,
- 3, 0, 5, 5, 0, 0, 0, 5,
- 5, 5, 3, 3, 5, 5, 5, 5,
- 5, 5, 0, 0, 0, 3, 0, 0,
- 10, 11, 12, 13, 5, 0, 5, 0,
- 0, 0, 0, 0, 0, 0, 0, 5,
+ 1, 2, 2, 5, 0, 6, 0, 0,
+ 0, 0, 2, 0, 2, 2, 0, 0,
+ 0, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 0, 0, 0, 2,
+ 0, 0, 7, 0, 0, 8, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 14, 5, 15, 0, 0, 16, 0,
- 0, 17, 0, 0, 18, 5, 0, 0,
- 19, 20, 0, 3, 0, 5, 21, 0,
- 0
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 9, 10, 0, 11, 0, 12,
+ 0, 13, 0, 14, 15, 0, 0, 16,
+ 0, 17, 0
};
static const char _use_syllable_machine_to_state_actions[] = {
- 0, 0, 0, 0, 0, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
+ 0, 0, 0, 0, 0, 0
};
static const char _use_syllable_machine_from_state_actions[] = {
- 0, 0, 0, 0, 0, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
+ 0, 0, 0, 0, 0, 0
};
static const short _use_syllable_machine_eof_trans[] = {
- 1, 3, 3, 6, 6, 0, 42, 44,
- 44, 68, 68, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 71, 44,
- 44, 44, 44, 44, 44, 44, 44, 44,
- 68, 44, 74, 77, 74, 44, 44, 81,
- 81, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 87,
- 82, 82, 82, 87, 82, 82, 82, 82,
- 81, 87
+ 1, 1, 0, 38, 38, 60, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38,
+ 62, 38, 38, 38, 38, 38, 38, 38,
+ 38, 60, 64, 66, 38, 68, 68, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 72, 69, 69, 69, 69,
+ 69, 69, 72, 74, 74, 74
};
-static const int use_syllable_machine_start = 5;
-static const int use_syllable_machine_first_final = 5;
+static const int use_syllable_machine_start = 2;
+static const int use_syllable_machine_first_final = 2;
static const int use_syllable_machine_error = -1;
-static const int use_syllable_machine_en_main = 5;
+static const int use_syllable_machine_en_main = 2;
-#line 38 "hb-ot-shape-complex-use-machine.rl"
+#line 39 "hb-ot-shape-complex-use-machine.rl"
-#line 162 "hb-ot-shape-complex-use-machine.rl"
+#line 154 "hb-ot-shape-complex-use-machine.rl"
#define found_syllable(syllable_type) \
HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
- for (unsigned int i = ts; i < te; i++) \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
+ for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
+static bool
+not_standard_default_ignorable (const hb_glyph_info_t &i)
+{ return !(i.use_category() == USE_O && _hb_glyph_info_is_default_ignorable (&i)); }
+
static void
find_syllables_use (hb_buffer_t *buffer)
{
- unsigned int p, pe, eof, ts, te, act;
- int cs;
hb_glyph_info_t *info = buffer->info;
+ auto p =
+ + hb_iter (info, buffer->len)
+ | hb_enumerate
+ | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); },
+ hb_second)
+ | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
+ {
+ if (p.second.use_category() == USE_ZWNJ)
+ for (unsigned i = p.first + 1; i < buffer->len; ++i)
+ if (not_standard_default_ignorable (info[i]))
+ return !_hb_glyph_info_is_unicode_mark (&info[i]);
+ return true;
+ })
+ | hb_enumerate
+ | machine_index
+ ;
+ auto pe = p + p.len ();
+ auto eof = +pe;
+ auto ts = +p;
+ auto te = +p;
+ unsigned int act HB_UNUSED;
+ int cs;
-#line 396 "hb-ot-shape-complex-use-machine.hh"
+#line 355 "hb-ot-shape-complex-use-machine.hh"
{
cs = use_syllable_machine_start;
ts = 0;
@@ -400,15 +359,12 @@ find_syllables_use (hb_buffer_t *buffer)
act = 0;
}
-#line 182 "hb-ot-shape-complex-use-machine.rl"
-
+#line 198 "hb-ot-shape-complex-use-machine.rl"
- p = 0;
- pe = eof = buffer->len;
unsigned int syllable_serial = 1;
-#line 412 "hb-ot-shape-complex-use-machine.hh"
+#line 368 "hb-ot-shape-complex-use-machine.hh"
{
int _slen;
int _trans;
@@ -418,20 +374,20 @@ find_syllables_use (hb_buffer_t *buffer)
goto _test_eof;
_resume:
switch ( _use_syllable_machine_from_state_actions[cs] ) {
- case 7:
+ case 4:
#line 1 "NONE"
{ts = p;}
break;
-#line 426 "hb-ot-shape-complex-use-machine.hh"
+#line 382 "hb-ot-shape-complex-use-machine.hh"
}
_keys = _use_syllable_machine_trans_keys + (cs<<1);
_inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs];
_slen = _use_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].use_category()) &&
- ( info[p].use_category()) <= _keys[1] ?
- ( info[p].use_category()) - _keys[0] : _slen ];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) &&
+ ( (*p).second.second.use_category()) <= _keys[1] ?
+ ( (*p).second.second.use_category()) - _keys[0] : _slen ];
_eof_trans:
cs = _use_syllable_machine_trans_targs[_trans];
@@ -440,104 +396,76 @@ _eof_trans:
goto _again;
switch ( _use_syllable_machine_trans_actions[_trans] ) {
- case 5:
+ case 2:
#line 1 "NONE"
{te = p+1;}
break;
- case 12:
-#line 150 "hb-ot-shape-complex-use-machine.rl"
+ case 5:
+#line 141 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (independent_cluster); }}
break;
- case 14:
-#line 153 "hb-ot-shape-complex-use-machine.rl"
+ case 9:
+#line 144 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (standard_cluster); }}
break;
- case 10:
-#line 157 "hb-ot-shape-complex-use-machine.rl"
+ case 7:
+#line 149 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
- case 8:
-#line 158 "hb-ot-shape-complex-use-machine.rl"
- {te = p+1;{ found_syllable (non_cluster); }}
- break;
- case 11:
+ case 6:
#line 150 "hb-ot-shape-complex-use-machine.rl"
- {te = p;p--;{ found_syllable (independent_cluster); }}
+ {te = p+1;{ found_syllable (non_cluster); }}
break;
- case 15:
-#line 151 "hb-ot-shape-complex-use-machine.rl"
+ case 10:
+#line 142 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (virama_terminated_cluster); }}
break;
- case 16:
-#line 152 "hb-ot-shape-complex-use-machine.rl"
+ case 11:
+#line 143 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (sakot_terminated_cluster); }}
break;
- case 13:
-#line 153 "hb-ot-shape-complex-use-machine.rl"
+ case 8:
+#line 144 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (standard_cluster); }}
break;
- case 18:
-#line 154 "hb-ot-shape-complex-use-machine.rl"
+ case 13:
+#line 145 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
break;
- case 17:
-#line 155 "hb-ot-shape-complex-use-machine.rl"
+ case 12:
+#line 146 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (numeral_cluster); }}
break;
- case 19:
-#line 156 "hb-ot-shape-complex-use-machine.rl"
+ case 14:
+#line 147 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (symbol_cluster); }}
break;
- case 20:
-#line 157 "hb-ot-shape-complex-use-machine.rl"
+ case 17:
+#line 148 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (hieroglyph_cluster); }}
+ break;
+ case 15:
+#line 149 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
- case 21:
-#line 158 "hb-ot-shape-complex-use-machine.rl"
+ case 16:
+#line 150 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (non_cluster); }}
break;
case 1:
-#line 153 "hb-ot-shape-complex-use-machine.rl"
- {{p = ((te))-1;}{ found_syllable (standard_cluster); }}
- break;
- case 4:
-#line 157 "hb-ot-shape-complex-use-machine.rl"
+#line 149 "hb-ot-shape-complex-use-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
- case 2:
-#line 1 "NONE"
- { switch( act ) {
- case 8:
- {{p = ((te))-1;} found_syllable (broken_cluster); }
- break;
- case 9:
- {{p = ((te))-1;} found_syllable (non_cluster); }
- break;
- }
- }
- break;
- case 3:
-#line 1 "NONE"
- {te = p+1;}
-#line 157 "hb-ot-shape-complex-use-machine.rl"
- {act = 8;}
- break;
- case 9:
-#line 1 "NONE"
- {te = p+1;}
-#line 158 "hb-ot-shape-complex-use-machine.rl"
- {act = 9;}
- break;
-#line 532 "hb-ot-shape-complex-use-machine.hh"
+#line 460 "hb-ot-shape-complex-use-machine.hh"
}
_again:
switch ( _use_syllable_machine_to_state_actions[cs] ) {
- case 6:
+ case 3:
#line 1 "NONE"
{ts = 0;}
break;
-#line 541 "hb-ot-shape-complex-use-machine.hh"
+#line 469 "hb-ot-shape-complex-use-machine.hh"
}
if ( ++p != pe )
@@ -553,7 +481,7 @@ _again:
}
-#line 190 "hb-ot-shape-complex-use-machine.rl"
+#line 203 "hb-ot-shape-complex-use-machine.rl"
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc
index aa9c350862..df3652b18a 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc
@@ -2,7 +2,7 @@
/*
* The following table is generated by running:
*
- * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
+ * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt ArabicShaping.txt Blocks.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
*
* on files with these headers:
*
@@ -10,8 +10,24 @@
* # Date: 2019-07-22, 19:55:00 GMT [KW, RP]
* # IndicPositionalCategory-13.0.0.txt
* # Date: 2019-07-23, 00:01:00 GMT [KW, RP]
+ * # ArabicShaping-13.0.0.txt
+ * # Date: 2020-01-31, 23:55:00 GMT [KW, RP]
* # Blocks-13.0.0.txt
* # Date: 2019-07-10, 19:06:00 GMT [KW]
+ * # Override values For Indic_Syllabic_Category
+ * # Not derivable
+ * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
+ * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
+ * # Updated for Unicode 12.1 by Andrew Glass 2019-05-24
+ * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
+ * # Override values For Indic_Positional_Category
+ * # Not derivable
+ * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
+ * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
+ * # Ammended for Unicode 10.0 by Andrew Glass 2018-09-21
+ * # Updated for L2/19-083 by Andrew Glass 2019-05-06
+ * # Updated for Unicode 12.1 by Andrew Glass 2019-05-30
+ * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
* UnicodeData.txt does not have a header.
*/
@@ -24,23 +40,21 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
#define B USE_B /* BASE */
-#define CGJ USE_CGJ /* CGJ */
#define CS USE_CS /* CONS_WITH_STACKER */
+#define G USE_G /* HIEROGLYPH */
#define GB USE_GB /* BASE_OTHER */
#define H USE_H /* HALANT */
#define HN USE_HN /* HALANT_NUM */
#define HVM USE_HVM /* HALANT_OR_VOWEL_MODIFIER */
-#define IND USE_IND /* BASE_IND */
+#define J USE_J /* HIEROGLYPH_JOINER */
#define N USE_N /* BASE_NUM */
#define O USE_O /* OTHER */
#define R USE_R /* REPHA */
-#define Rsv USE_Rsv /* Reserved */
#define S USE_S /* SYM */
+#define SB USE_SB /* HIEROGLYPH_SEGMENT_BEGIN */
+#define SE USE_SE /* HIEROGLYPH_SEGMENT_END */
#define SUB USE_SUB /* CONS_SUB */
#define Sk USE_Sk /* SAKOT */
-#define VS USE_VS /* VARIATION_SELECTOR */
-#define WJ USE_WJ /* Word_Joiner */
-#define ZWJ USE_ZWJ /* ZWJ */
#define ZWNJ USE_ZWNJ /* ZWNJ */
#define CMAbv USE_CMAbv
#define CMBlw USE_CMBlw
@@ -86,13 +100,31 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 00D0 */ O, O, O, O, O, O, O, GB,
-#define use_offset_0x0348u 80
+#define use_offset_0x0640u 80
- /* Combining Diacritical Marks */
- O, O, O, O, O, O, O, CGJ,
+ /* Arabic */
-#define use_offset_0x0900u 88
+ /* 0640 */ B, O, O, O, O, O, O, O,
+
+#define use_offset_0x07c8u 88
+
+
+ /* NKo */
+ O, O, B, B, B, B, B, B,
+ /* 07D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 07E0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
+ /* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, O, O, O, B, O, O, VMAbv, O, O,
+
+#define use_offset_0x0840u 144
+
+
+ /* Mandaic */
+
+ /* 0840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0850 */ B, B, B, B, B, B, B, B, B, CMBlw, CMBlw, CMBlw, O, O, O, O,
+
+#define use_offset_0x0900u 176
/* Devanagari */
@@ -112,7 +144,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre,
- /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPst, VPst, H, IND, O,
+ /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
/* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B,
/* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FMAbv, O,
@@ -145,18 +177,18 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0B10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv,
- /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, O, O, VPst, VPst, H, O, O,
+ /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
/* 0B50 */ O, O, O, O, O, VAbv, VAbv, VAbv, O, O, O, O, B, B, O, B,
/* 0B60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Tamil */
- /* 0B80 */ O, O, VMAbv, IND, O, B, B, B, B, B, B, O, O, O, B, B,
+ /* 0B80 */ O, O, VMAbv, O, O, B, B, B, B, B, B, O, O, O, B, B,
/* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B,
/* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B,
/* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst,
- /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, O, O,
+ /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O,
/* 0BD0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O,
/* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
@@ -189,10 +221,10 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0D10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst,
- /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, R, O,
- /* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B,
+ /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O,
+ /* 0D50 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, B,
/* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
- /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND,
+ /* 0D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Sinhala */
@@ -201,28 +233,30 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O,
/* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst,
- /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPst, VPre, VPst, VPst, VPst, VPst,
+ /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst,
/* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0DF0 */ O, O, VPst, VPst, O, O, O, O,
-#define use_offset_0x0f18u 1360
+#define use_offset_0x0f00u 1448
/* Tibetan */
- VBlw, VBlw, O, O, O, O, O, O,
+
+ /* 0F00 */ B, B, O, O, B, B, B, O, O, O, O, O, O, O, O, O,
+ /* 0F10 */ O, O, O, O, O, O, O, O, VBlw, VBlw, O, O, O, O, O, O,
/* 0F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* 0F30 */ B, B, B, B, O, FMBlw, O, FMBlw, O, CMAbv, O, O, O, O, VPst, VPre,
+ /* 0F30 */ B, B, B, B, O, FBlw, O, FBlw, O, CMAbv, O, O, O, O, VPst, VPre,
/* 0F40 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B,
/* 0F50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0F60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O,
- /* 0F70 */ O, VBlw, VBlw, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, VMPst,
- /* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, IND, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB,
+ /* 0F70 */ O, CMBlw, VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, O,
+ /* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, O, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB,
/* 0F90 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 0FA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O,
- /* 0FC0 */ O, O, O, O, O, O, FMBlw, O,
+ /* 0FC0 */ O, O, O, O, O, O, FBlw, O,
-#define use_offset_0x1000u 1536
+#define use_offset_0x1000u 1648
/* Myanmar */
@@ -238,7 +272,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst,
/* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O,
-#define use_offset_0x1700u 1696
+#define use_offset_0x1700u 1808
/* Tagalog */
@@ -266,12 +300,27 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPst, VPst,
- /* 17C0 */ VPst, VPre, VPre, VPre, VPst, VPst, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, FMAbv,
+ /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre,
+ /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, VMAbv,
/* 17D0 */ FMAbv, VAbv, H, FMAbv, O, O, O, O, O, O, O, O, B, FMAbv, O, O,
/* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+ /* 17F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
-#define use_offset_0x1900u 1936
+ /* Mongolian */
+
+ /* 1800 */ B, O, O, O, O, O, O, B, O, O, B, O, O, O, O, O,
+ /* 1810 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 1820 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1830 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1870 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
+ /* 1880 */ GB, GB, GB, GB, GB, CMAbv, CMAbv, B, B, B, B, B, B, B, B, B,
+ /* 1890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18A0 */ B, B, B, B, B, B, B, B, B, CMBlw, B, O, O, O, O, O,
+
+#define use_offset_0x1900u 2240
/* Limbu */
@@ -279,7 +328,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O,
/* 1920 */ VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, O, O, O, O,
- /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VAbv, FMBlw, O, O, O, O,
+ /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VMAbv, FMBlw, O, O, O, O,
/* 1940 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
/* Tai Le */
@@ -302,7 +351,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* Buginese */
/* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* 1A10 */ B, B, B, B, B, B, B, VAbv, VBlw, VPre, VPst, VAbv, O, O, O, O,
+ /* 1A10 */ B, B, B, B, B, B, B, VAbv, VAbv, VPre, VPst, VAbv, O, O, O, O,
/* Tai Tham */
@@ -311,11 +360,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, O,
/* 1A60 */ Sk, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre,
- /* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, FMAbv, FMAbv, O, O, FMBlw,
+ /* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, VMAbv, VMAbv, O, O, VMBlw,
/* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
-#define use_offset_0x1b00u 2352
+#define use_offset_0x1b00u 2656
/* Balinese */
@@ -324,7 +373,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre,
- /* 1B40 */ VPst, VPst, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O,
+ /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O,
/* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB,
/* 1B60 */ O, S, GB, S, S, S, S, S, GB, S, S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
/* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O,
@@ -351,51 +400,61 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, O, O, O, O, O, O, O, O,
/* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B,
-#define use_offset_0x1cd0u 2688
+#define use_offset_0x1cd0u 2992
/* Vedic Extensions */
/* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
/* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O,
- /* 1CF0 */ O, O, IND, IND, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O,
+ /* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O,
-#define use_offset_0x1df8u 2736
+#define use_offset_0x1df8u 3040
/* Combining Diacritical Marks Supplement */
O, O, O, FMAbv, O, O, O, O,
-#define use_offset_0x2008u 2744
+#define use_offset_0x2008u 3048
/* General Punctuation */
- O, O, O, O, ZWNJ, ZWJ, O, O,
+ O, O, O, O, ZWNJ, O, O, O,
/* 2010 */ GB, GB, GB, GB, GB, O, O, O,
-#define use_offset_0x2060u 2760
+#define use_offset_0x2070u 3064
- /* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Superscripts and Subscripts */
/* 2070 */ O, O, O, O, FMPst, O, O, O, O, O, O, O, O, O, O, O,
/* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O,
-#define use_offset_0x20f0u 2800
+#define use_offset_0x20f0u 3088
/* Combining Diacritical Marks for Symbols */
/* 20F0 */ VMAbv, O, O, O, O, O, O, O,
-#define use_offset_0x25c8u 2808
+#define use_offset_0x25c8u 3096
/* Geometric Shapes */
- O, O, O, O, GB, O, O, O,
+ O, O, O, O, B, O, O, O,
+
+#define use_offset_0x2d30u 3104
+
-#define use_offset_0xa800u 2816
+ /* Tifinagh */
+
+ /* 2D30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 2D40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 2D50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 2D60 */ B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, B,
+ /* 2D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, H,
+
+#define use_offset_0xa800u 3184
/* Syloti Nagri */
@@ -445,7 +504,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* A980 */ VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B,
/* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, MBlw, MBlw, MBlw,
+ /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, MBlw, MPst, MBlw,
/* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* A9D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@@ -459,7 +518,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* AA00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* AA20 */ B, B, B, B, B, B, B, B, B, VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre,
- /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MBlw, MBlw, O, O, O, O, O, O, O, O, O,
+ /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MAbv, MBlw, O, O, O, O, O, O, O, O, O,
/* AA40 */ B, B, B, FAbv, B, B, B, B, B, B, B, B, FAbv, FPst, O, O,
/* AA50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@@ -482,7 +541,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst,
/* AAF0 */ O, O, O, O, O, VMPst, H, O,
-#define use_offset_0xabc0u 3576
+#define use_offset_0xabc0u 3944
/* Meetei Mayek */
@@ -492,26 +551,74 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O,
/* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
-#define use_offset_0xfe00u 3640
-
-
- /* Variation Selectors */
-
- /* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS,
-
-#define use_offset_0x10a00u 3656
+#define use_offset_0x10a00u 4008
/* Kharoshthi */
- /* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VBlw, VBlw, VMBlw, VMAbv,
+ /* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VPst, VMBlw, VMBlw, VMAbv,
/* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B,
/* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H,
/* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
-#define use_offset_0x11000u 3736
+#define use_offset_0x10ac0u 4088
+
+
+ /* Manichaean */
+
+ /* 10AC0 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B,
+ /* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O,
+
+#define use_offset_0x10b80u 4128
+
+
+ /* Psalter Pahlavi */
+
+ /* 10B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 10B90 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 10BA0 */ O, O, O, O, O, O, O, O, O, B, B, B, B, B, B, O,
+
+#define use_offset_0x10d00u 4176
+
+
+ /* Hanifi Rohingya */
+
+ /* 10D00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 10D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, O, O, O, O, O, O, O, O,
+ /* 10D30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+
+#define use_offset_0x10e80u 4240
+
+
+ /* Yezidi */
+
+ /* 10E80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 10E90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 10EA0 */ B, B, B, B, B, B, B, B, B, B, O, VAbv, VAbv, O, O, O,
+ /* 10EB0 */ B, B, O, O, O, O, O, O,
+#define use_offset_0x10f30u 4296
+
+
+ /* Sogdian */
+
+ /* 10F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,
+ /* 10F50 */ VMBlw, B, B, B, B, O, O, O,
+
+#define use_offset_0x10fb0u 4336
+
+
+ /* Chorasmian */
+
+ /* 10FB0 */ B, O, B, B, B, B, B, O, B, B, B, B, B, B, B, B,
+ /* 10FC0 */ O, B, B, B, B, O, O, O, O, B, B, B, O, O, O, O,
+ /* 10FD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 10FE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 10FF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Brahmi */
@@ -531,7 +638,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O,
-#define use_offset_0x11100u 3928
+#define use_offset_0x11100u 4608
/* Chakma */
@@ -539,7 +646,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11120 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VBlw, VAbv, VAbv,
- /* 11130 */ VBlw, VAbv, VAbv, H, CMBlw, O, B, B, B, B, B, B, B, B, B, B,
+ /* 11130 */ VBlw, VAbv, VAbv, H, CMAbv, O, B, B, B, B, B, B, B, B, B, B,
/* 11140 */ O, O, O, O, B, VPst, VPst, B, O, O, O, O, O, O, O, O,
/* Mahajani */
@@ -555,7 +662,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv,
/* 111C0 */ H, B, R, R, O, O, O, O, GB, FMBlw, CMBlw, VAbv, VBlw, O, VPre, VMAbv,
- /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+ /* 111D0 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, O,
/* Sinhala Archaic Numbers */
@@ -569,7 +676,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw,
/* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O,
-#define use_offset_0x11280u 4248
+#define use_offset_0x11280u 4928
/* Multani */
@@ -592,12 +699,12 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11310 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 11330 */ B, O, B, B, O, B, B, B, B, B, O, CMBlw, CMBlw, B, VPst, VPst,
- /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPst, VPst, HVM, O, O,
+ /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, HVM, O, O,
/* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, B, B,
/* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
/* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
-#define use_offset_0x11400u 4496
+#define use_offset_0x11400u 5176
/* Newa */
@@ -616,11 +723,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPst, VPst, VPst, VPst, VMAbv,
+ /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv,
/* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O,
/* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
-#define use_offset_0x11580u 4720
+#define use_offset_0x11580u 5400
/* Siddham */
@@ -628,7 +735,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst,
- /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, VPst, VPst, VMAbv, VMAbv, VMPst, H,
+ /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H,
/* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, O, O,
/* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
@@ -660,10 +767,10 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11710 */ B, B, B, B, B, B, B, B, B, B, B, O, O, MBlw, MPre, MAbv,
- /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O,
+ /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VMAbv, O, O, O, O,
/* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O,
-#define use_offset_0x11800u 5168
+#define use_offset_0x11800u 5848
/* Dogra */
@@ -673,7 +780,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw,
/* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O,
-#define use_offset_0x11900u 5232
+#define use_offset_0x11900u 5912
/* Dives Akuru */
@@ -681,11 +788,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11900 */ B, B, B, B, B, B, B, O, O, B, O, O, B, B, B, B,
/* 11910 */ B, B, B, B, O, B, B, O, B, B, B, B, B, B, B, B,
/* 11920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* 11930 */ VPst, VPst, VPst, VPst, VPst, VPre, O, VPre, VPst, O, O, VMAbv, VMAbv, VPst, H, R,
- /* 11940 */ MPst, R, MBlw, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 11930 */ VPst, VPst, VPst, VPst, VPst, VPre, O, VPre, VPre, O, O, VMAbv, VMAbv, VPst, H, R,
+ /* 11940 */ MPst, R, MPst, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O,
/* 11950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
-#define use_offset_0x119a0u 5328
+#define use_offset_0x119a0u 6008
/* Nandinagari */
@@ -713,7 +820,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw,
/* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O,
-#define use_offset_0x11c00u 5584
+#define use_offset_0x11c00u 6264
/* Bhaiksuki */
@@ -734,7 +841,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O,
-#define use_offset_0x11d00u 5768
+#define use_offset_0x11d00u 6448
/* Masaram Gondi */
@@ -754,7 +861,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O,
/* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
-#define use_offset_0x11ee0u 5944
+#define use_offset_0x11ee0u 6624
/* Makasar */
@@ -762,7 +869,202 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O,
-}; /* Table items: 5968; occupancy: 74% */
+#define use_offset_0x13000u 6648
+
+
+ /* Egyptian Hieroglyphs */
+
+ /* 13000 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13010 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13020 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13030 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13040 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13050 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13060 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13070 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13080 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13090 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 130A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 130B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 130C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 130D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 130E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 130F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13100 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13110 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13120 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13130 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13140 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13150 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13160 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13170 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13180 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13190 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 131A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 131B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 131C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 131D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 131E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 131F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13200 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13210 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13220 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13230 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13240 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13250 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13260 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13270 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13280 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13290 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 132A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 132B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 132C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 132D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 132E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 132F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13300 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13310 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13320 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13330 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13340 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13350 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13360 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13370 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13380 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13390 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 133A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 133B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 133C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 133D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 133E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 133F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13400 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13410 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
+ /* 13420 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, O,
+
+ /* Egyptian Hieroglyph Format Controls */
+
+ /* 13430 */ J, J, J, J, J, J, J, SB, SE, O, O, O, O, O, O, O,
+
+#define use_offset_0x16b00u 7736
+
+
+ /* Pahawh Hmong */
+
+ /* 16B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 16B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O,
+
+#define use_offset_0x16f00u 7792
+
+
+ /* Miao */
+
+ /* 16F00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 16F10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 16F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 16F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 16F40 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, CMBlw,
+ /* 16F50 */ O, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
+ /* 16F60 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
+ /* 16F70 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
+ /* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, O, O, O, O, O, O, O, VMBlw,
+ /* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O,
+
+#define use_offset_0x16fe0u 7944
+
+
+ /* Ideographic Symbols and Punctuation */
+
+ /* 16FE0 */ O, O, O, O, B, O, O, O,
+
+#define use_offset_0x18b00u 7952
+
+
+ /* Khitan Small Script */
+
+ /* 18B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18BA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18BE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18BF0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18C90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18CA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18CB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 18CD0 */ B, B, B, B, B, B, O, O,
+
+#define use_offset_0x1bc00u 8424
+
+
+ /* Duployan */
+
+ /* 1BC00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BC10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BC20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BC30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BC40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BC50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BC60 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, O,
+ /* 1BC70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O,
+ /* 1BC80 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
+ /* 1BC90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, CMBlw, CMBlw, O,
+
+#define use_offset_0x1e100u 8584
+
+
+ /* Nyiakeng Puachue Hmong */
+
+ /* 1E100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1E110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1E120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O,
+ /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, O, O,
+ /* 1E140 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, B, B,
+
+#define use_offset_0x1e2c0u 8664
+
+
+ /* Wancho */
+
+ /* 1E2C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1E2D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv,
+ /* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+
+#define use_offset_0x1e900u 8728
+
+
+ /* Adlam */
+
+ /* 1E900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1E910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1E920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1E930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, O, O, O, O,
+ /* 1E950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+
+}; /* Table items: 8824; occupancy: 79% */
USE_TABLE_ELEMENT_TYPE
hb_use_get_category (hb_codepoint_t u)
@@ -772,14 +1074,16 @@ hb_use_get_category (hb_codepoint_t u)
case 0x0u:
if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
- if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u];
if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u];
- if (hb_in_range<hb_codepoint_t> (u, 0x0F18u, 0x0FC7u)) return use_table[u - 0x0F18u + use_offset_0x0f18u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0F00u, 0x0FC7u)) return use_table[u - 0x0F00u + use_offset_0x0f00u];
break;
case 0x1u:
if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u];
- if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x18AFu)) return use_table[u - 0x1700u + use_offset_0x1700u];
if (hb_in_range<hb_codepoint_t> (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u];
if (hb_in_range<hb_codepoint_t> (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u];
if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u];
@@ -788,9 +1092,10 @@ hb_use_get_category (hb_codepoint_t u)
case 0x2u:
if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u];
- if (hb_in_range<hb_codepoint_t> (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u];
if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u];
if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x2D30u, 0x2D7Fu)) return use_table[u - 0x2D30u + use_offset_0x2d30u];
break;
case 0xAu:
@@ -798,16 +1103,18 @@ hb_use_get_category (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u];
break;
- case 0xFu:
- if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
- break;
-
case 0x10u:
if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AE7u)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F57u)) return use_table[u - 0x10F30u + use_offset_0x10f30u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110BFu)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u];
break;
case 0x11u:
- if (hb_in_range<hb_codepoint_t> (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110BFu)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u];
if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u];
if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
@@ -820,6 +1127,30 @@ hb_use_get_category (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0x11EE0u, 0x11EF7u)) return use_table[u - 0x11EE0u + use_offset_0x11ee0u];
break;
+ case 0x13u:
+ if (hb_in_range<hb_codepoint_t> (u, 0x13000u, 0x1343Fu)) return use_table[u - 0x13000u + use_offset_0x13000u];
+ break;
+
+ case 0x16u:
+ if (hb_in_range<hb_codepoint_t> (u, 0x16B00u, 0x16B37u)) return use_table[u - 0x16B00u + use_offset_0x16b00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u];
+ break;
+
+ case 0x18u:
+ if (hb_in_range<hb_codepoint_t> (u, 0x18B00u, 0x18CD7u)) return use_table[u - 0x18B00u + use_offset_0x18b00u];
+ break;
+
+ case 0x1Bu:
+ if (hb_in_range<hb_codepoint_t> (u, 0x1BC00u, 0x1BC9Fu)) return use_table[u - 0x1BC00u + use_offset_0x1bc00u];
+ break;
+
+ case 0x1Eu:
+ if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1E2C0u, 0x1E2FFu)) return use_table[u - 0x1E2C0u + use_offset_0x1e2c0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u];
+ break;
+
default:
break;
}
@@ -827,23 +1158,21 @@ hb_use_get_category (hb_codepoint_t u)
}
#undef B
-#undef CGJ
#undef CS
+#undef G
#undef GB
#undef H
#undef HN
#undef HVM
-#undef IND
+#undef J
#undef N
#undef O
#undef R
-#undef Rsv
#undef S
+#undef SB
+#undef SE
#undef SUB
#undef Sk
-#undef VS
-#undef WJ
-#undef ZWJ
#undef ZWNJ
#undef CMAbv
#undef CMBlw
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc
index a1e25bdd80..8ac569d8bf 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc
@@ -194,6 +194,7 @@ enum use_syllable_type_t {
use_number_joiner_terminated_cluster,
use_numeral_cluster,
use_symbol_cluster,
+ use_hieroglyph_cluster,
use_broken_cluster,
use_non_cluster,
};
@@ -275,6 +276,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
{
case use_independent_cluster:
case use_symbol_cluster:
+ case use_hieroglyph_cluster:
case use_non_cluster:
/* These don't join. Nothing to do. */
last_form = _USE_NONE;
@@ -385,8 +387,7 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
hb_glyph_info_t *info = buffer->info;
-#define POST_BASE_FLAGS64 (FLAG64 (USE_FM) | \
- FLAG64 (USE_FAbv) | \
+#define POST_BASE_FLAGS64 (FLAG64 (USE_FAbv) | \
FLAG64 (USE_FBlw) | \
FLAG64 (USE_FPst) | \
FLAG64 (USE_MAbv) | \
@@ -516,10 +517,14 @@ reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- insert_dotted_circles_use (plan, font, buffer);
+ if (buffer->message (font, "start reordering USE")) {
+ insert_dotted_circles_use (plan, font, buffer);
- foreach_syllable (buffer, start, end)
- reorder_syllable_use (buffer, start, end);
+ foreach_syllable (buffer, start, end)
+ reorder_syllable_use (buffer, start, end);
+
+ (void) buffer->message (font, "end reordering USE");
+ }
HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.hh
index ce6645ecd3..788fb6b6ac 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.hh
@@ -46,34 +46,25 @@ enum use_category_t {
USE_O = 0, /* OTHER */
USE_B = 1, /* BASE */
- USE_IND = 3, /* BASE_IND */
USE_N = 4, /* BASE_NUM */
USE_GB = 5, /* BASE_OTHER */
- USE_CGJ = 6, /* CGJ */
-// USE_F = 7, /* CONS_FINAL */
- USE_FM = 8, /* CONS_FINAL_MOD */
-// USE_M = 9, /* CONS_MED */
-// USE_CM = 10, /* CONS_MOD */
USE_SUB = 11, /* CONS_SUB */
USE_H = 12, /* HALANT */
USE_HN = 13, /* HALANT_NUM */
USE_ZWNJ = 14, /* Zero width non-joiner */
- USE_ZWJ = 15, /* Zero width joiner */
- USE_WJ = 16, /* Word joiner */
- USE_Rsv = 17, /* Reserved characters */
USE_R = 18, /* REPHA */
USE_S = 19, /* SYM */
-// USE_SM = 20, /* SYM_MOD */
- USE_VS = 21, /* VARIATION_SELECTOR */
-// USE_V = 36, /* VOWEL */
-// USE_VM = 40, /* VOWEL_MOD */
USE_CS = 43, /* CONS_WITH_STACKER */
/* https://github.com/harfbuzz/harfbuzz/issues/1102 */
USE_HVM = 44, /* HALANT_OR_VOWEL_MODIFIER */
USE_Sk = 48, /* SAKOT */
+ USE_G = 49, /* HIEROGLYPH */
+ USE_J = 50, /* HIEROGLYPH_JOINER */
+ USE_SB = 51, /* HIEROGLYPH_SEGMENT_BEGIN */
+ USE_SE = 52, /* HIEROGLYPH_SEGMENT_END */
USE_FAbv = 24, /* CONS_FINAL_ABOVE */
USE_FBlw = 25, /* CONS_FINAL_BELOW */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc
index c3368c6ec2..1af546e4fa 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc
@@ -320,7 +320,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
switch (buffer->cur (1).codepoint)
{
case 0x0DCAu: case 0x0DD9u: case 0x0DDAu: case 0x0DDCu:
- case 0x0DDDu:
+ case 0x0DDDu: case 0x0DDEu:
matched = true;
break;
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh
index 61f4c0e158..a1a7a6a47b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh
@@ -341,6 +341,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-6.1 additions */
case HB_SCRIPT_CHAKMA:
+ case HB_SCRIPT_MIAO:
case HB_SCRIPT_SHARADA:
case HB_SCRIPT_TAKRI:
@@ -359,6 +360,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-8.0 additions */
case HB_SCRIPT_AHOM:
+ case HB_SCRIPT_MULTANI:
/* Unicode-9.0 additions */
//case HB_SCRIPT_ADLAM:
@@ -376,10 +378,15 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_GUNJALA_GONDI:
//case HB_SCRIPT_HANIFI_ROHINGYA:
case HB_SCRIPT_MAKASAR:
+ case HB_SCRIPT_MEDEFAIDRIN:
+ case HB_SCRIPT_OLD_SOGDIAN:
//case HB_SCRIPT_SOGDIAN:
/* Unicode-12.0 additions */
+ case HB_SCRIPT_ELYMAIC:
case HB_SCRIPT_NANDINAGARI:
+ case HB_SCRIPT_NYIAKENG_PUACHUE_HMONG:
+ case HB_SCRIPT_WANCHO:
/* Unicode-13.0 additions */
case HB_SCRIPT_CHORASMIAN:
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc b/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
index 42bf524d16..7d00a35ab9 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
@@ -301,7 +301,7 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* Don't shift down "above" marks too much. */
if ((y_gap > 0) != (pos.y_offset > 0))
{
- unsigned int correction = -pos.y_offset / 2;
+ int correction = -pos.y_offset / 2;
base_extents.y_bearing += correction;
base_extents.height -= correction;
pos.y_offset += correction;
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
index 50b5829c4a..3eabae1b45 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
@@ -373,7 +373,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
/* Second round, reorder (inplace) */
- if (!all_simple)
+ if (!all_simple && buffer->message(font, "start reorder"))
{
count = buffer->len;
for (unsigned int i = 0; i < count; i++)
@@ -399,6 +399,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
i = end;
}
+ (void) buffer->message(font, "end reorder");
}
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
{
@@ -408,7 +409,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
*/
for (unsigned int i = 1; i + 1 < buffer->len; i++)
if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
- info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1]))
+ (info_cc(buffer->info[i+1]) == 0 || info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1])))
{
_hb_glyph_info_unhide (&buffer->info[i]);
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc
index fe0444987a..7d90558458 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc
@@ -896,8 +896,11 @@ hb_ot_substitute_post (const hb_ot_shape_context_t *c)
hb_aat_layout_remove_deleted_glyphs (c->buffer);
#endif
- if (c->plan->shaper->postprocess_glyphs)
+ if (c->plan->shaper->postprocess_glyphs &&
+ c->buffer->message(c->font, "start postprocess-glyphs")) {
c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
+ (void) c->buffer->message(c->font, "end postprocess-glyphs");
+ }
}
@@ -1120,8 +1123,11 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
hb_ensure_native_direction (c->buffer);
- if (c->plan->shaper->preprocess_text)
+ if (c->plan->shaper->preprocess_text &&
+ c->buffer->message(c->font, "start preprocess-text")) {
c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
+ (void) c->buffer->message(c->font, "end preprocess-text");
+ }
hb_ot_substitute_pre (c);
hb_ot_position (c);
@@ -1155,6 +1161,12 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan,
/**
* hb_ot_shape_plan_collect_lookups:
+ * @shape_plan: #hb_shape_plan_t to query
+ * @table_tag: GSUB or GPOS
+ * @lookup_indexes: (out): The #hb_set_t set of lookups returned
+ *
+ * Computes the complete set of GSUB or GPOS lookups that are applicable
+ * under a given @shape_plan.
*
* Since: 0.9.7
**/
@@ -1189,6 +1201,15 @@ add_char (hb_font_t *font,
/**
* hb_ot_shape_glyphs_closure:
+ * @font: #hb_font_t to work upon
+ * @buffer: The input buffer to compute from
+ * @features: (array length=num_features): The features enabled on the buffer
+ * @num_features: The number of features enabled on the buffer
+ * @glyphs: (out): The #hb_set_t set of glyphs comprising the transitive closure of the query
+ *
+ * Computes the transitive closure of glyphs needed for a specified
+ * input buffer under the given font and feature list. The closure is
+ * computed as a set, not as a list.
*
* Since: 0.9.2
**/
diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
index 99937d9f69..f1c391cf0e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
@@ -6,8 +6,8 @@
*
* on files with these headers:
*
- * <meta name="updated_at" content="2019-05-22 06:05 PM" />
- * File-Date: 2020-05-12
+ * <meta name="updated_at" content="2020-11-17 08:21 AM" />
+ * File-Date: 2020-09-29
*/
#ifndef HB_OT_TAG_TABLE_HH
@@ -19,14 +19,18 @@ static const LangTag ot_languages[] = {
{"aao", HB_TAG('A','R','A',' ')}, /* Algerian Saharan Arabic -> Arabic */
{"aat", HB_TAG('S','Q','I',' ')}, /* Arvanitika Albanian -> Albanian */
{"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
+ {"aba", HB_TAG_NONE }, /* Abé != Abaza */
{"abh", HB_TAG('A','R','A',' ')}, /* Tajiki Arabic -> Arabic */
{"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
+ {"abs", HB_TAG('C','P','P',' ')}, /* Ambonese Malay -> Creoles */
{"abv", HB_TAG('A','R','A',' ')}, /* Baharna Arabic -> Arabic */
{"acf", HB_TAG('F','A','N',' ')}, /* Saint Lucian Creole French -> French Antillean */
+ {"acf", HB_TAG('C','P','P',' ')}, /* Saint Lucian Creole French -> Creoles */
/*{"ach", HB_TAG('A','C','H',' ')},*/ /* Acoli -> Acholi */
{"acm", HB_TAG('A','R','A',' ')}, /* Mesopotamian Arabic -> Arabic */
{"acq", HB_TAG('A','R','A',' ')}, /* Ta'izzi-Adeni Arabic -> Arabic */
-/*{"acr", HB_TAG('A','C','R',' ')},*/ /* Achi */
+ {"acr", HB_TAG('A','C','R',' ')}, /* Achi */
+ {"acr", HB_TAG('M','Y','N',' ')}, /* Achi -> Mayan */
{"acw", HB_TAG('A','R','A',' ')}, /* Hijazi Arabic -> Arabic */
{"acx", HB_TAG('A','R','A',' ')}, /* Omani Arabic -> Arabic */
{"acy", HB_TAG('A','R','A',' ')}, /* Cypriot Arabic -> Arabic */
@@ -38,15 +42,21 @@ static const LangTag ot_languages[] = {
{"aec", HB_TAG('A','R','A',' ')}, /* Saidi Arabic -> Arabic */
{"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
{"afb", HB_TAG('A','R','A',' ')}, /* Gulf Arabic -> Arabic */
+ {"afk", HB_TAG_NONE }, /* Nanubae != Afrikaans */
+ {"afs", HB_TAG('C','P','P',' ')}, /* Afro-Seminole Creole -> Creoles */
+ {"agu", HB_TAG('M','Y','N',' ')}, /* Aguacateco -> Mayan */
+ {"agw", HB_TAG_NONE }, /* Kahua != Agaw */
{"ahg", HB_TAG('A','G','W',' ')}, /* Qimant -> Agaw */
{"aht", HB_TAG('A','T','H',' ')}, /* Ahtena -> Athapaskan */
+ {"aig", HB_TAG('C','P','P',' ')}, /* Antigua and Barbuda Creole English -> Creoles */
{"aii", HB_TAG('S','W','A',' ')}, /* Assyrian Neo-Aramaic -> Swadaya Aramaic */
{"aii", HB_TAG('S','Y','R',' ')}, /* Assyrian Neo-Aramaic -> Syriac */
/*{"aio", HB_TAG('A','I','O',' ')},*/ /* Aiton */
{"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
{"ajp", HB_TAG('A','R','A',' ')}, /* South Levantine Arabic -> Arabic */
{"ak", HB_TAG('A','K','A',' ')}, /* Akan [macrolanguage] */
- {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] -> Twi */
+ {"akb", HB_TAG('A','K','B',' ')}, /* Batak Angkola */
+ {"akb", HB_TAG('B','T','K',' ')}, /* Batak Angkola -> Batak */
{"aln", HB_TAG('S','Q','I',' ')}, /* Gheg Albanian -> Albanian */
{"als", HB_TAG('S','Q','I',' ')}, /* Tosk Albanian -> Albanian */
/*{"alt", HB_TAG('A','L','T',' ')},*/ /* Southern Altai -> Altai */
@@ -55,6 +65,8 @@ static const LangTag ot_languages[] = {
{"amw", HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic -> Syriac */
{"an", HB_TAG('A','R','G',' ')}, /* Aragonese */
/*{"ang", HB_TAG('A','N','G',' ')},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */
+ {"aoa", HB_TAG('C','P','P',' ')}, /* Angolar -> Creoles */
+ {"apa", HB_TAG('A','T','H',' ')}, /* Apache [family] -> Athapaskan */
{"apc", HB_TAG('A','R','A',' ')}, /* North Levantine Arabic -> Arabic */
{"apd", HB_TAG('A','R','A',' ')}, /* Sudanese Arabic -> Arabic */
{"apj", HB_TAG('A','T','H',' ')}, /* Jicarilla Apache -> Athapaskan */
@@ -64,16 +76,20 @@ static const LangTag ot_languages[] = {
{"apw", HB_TAG('A','T','H',' ')}, /* Western Apache -> Athapaskan */
{"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */
{"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic -> Arabic */
+ {"ari", HB_TAG_NONE }, /* Arikara != Aari */
+ {"ark", HB_TAG_NONE }, /* Arikapú != Rakhine */
{"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
{"arq", HB_TAG('A','R','A',' ')}, /* Algerian Arabic -> Arabic */
{"ars", HB_TAG('A','R','A',' ')}, /* Najdi Arabic -> Arabic */
{"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic -> Moroccan */
+ {"ary", HB_TAG('A','R','A',' ')}, /* Moroccan Arabic -> Arabic */
{"arz", HB_TAG('A','R','A',' ')}, /* Egyptian Arabic -> Arabic */
{"as", HB_TAG('A','S','M',' ')}, /* Assamese */
/*{"ast", HB_TAG('A','S','T',' ')},*/ /* Asturian */
/*{"ath", HB_TAG('A','T','H',' ')},*/ /* Athapascan [family] -> Athapaskan */
{"atj", HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */
{"atv", HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */
+ {"auj", HB_TAG('B','B','R',' ')}, /* Awjilah -> Berber */
{"auz", HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */
{"av", HB_TAG('A','V','R',' ')}, /* Avaric -> Avar */
{"avl", HB_TAG('A','R','A',' ')}, /* Eastern Egyptian Bedawi Arabic -> Arabic */
@@ -86,17 +102,29 @@ static const LangTag ot_languages[] = {
{"ayp", HB_TAG('A','R','A',' ')}, /* North Mesopotamian Arabic -> Arabic */
{"ayr", HB_TAG('A','Y','M',' ')}, /* Central Aymara -> Aymara */
{"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */
-/*{"azb", HB_TAG('A','Z','B',' ')},*/ /* South Azerbaijani -> Torki */
+ {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani -> Torki */
+ {"azb", HB_TAG('A','Z','E',' ')}, /* South Azerbaijani -> Azerbaijani */
+ {"azd", HB_TAG('N','A','H',' ')}, /* Eastern Durango Nahuatl -> Nahuatl */
{"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani -> Azerbaijani */
+ {"azn", HB_TAG('N','A','H',' ')}, /* Western Durango Nahuatl -> Nahuatl */
+ {"azz", HB_TAG('N','A','H',' ')}, /* Highland Puebla Nahuatl -> Nahuatl */
{"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
{"bad", HB_TAG('B','A','D','0')}, /* Banda [family] */
+ {"bag", HB_TAG_NONE }, /* Tuki != Baghelkhandi */
+ {"bah", HB_TAG('C','P','P',' ')}, /* Bahamas Creole English -> Creoles */
{"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
{"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolanguage] */
/*{"ban", HB_TAG('B','A','N',' ')},*/ /* Balinese */
/*{"bar", HB_TAG('B','A','R',' ')},*/ /* Bavarian */
-/*{"bbc", HB_TAG('B','B','C',' ')},*/ /* Batak Toba */
+ {"bau", HB_TAG_NONE }, /* Bada (Nigeria) != Baulé */
+ {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */
+ {"bbc", HB_TAG('B','T','K',' ')}, /* Batak Toba -> Batak */
+ {"bbj", HB_TAG('B','M','L',' ')}, /* Ghomálá' -> Bamileke */
+ {"bbp", HB_TAG('B','A','D','0')}, /* West Central Banda -> Banda */
+ {"bbr", HB_TAG_NONE }, /* Girawa != Berber */
{"bbz", HB_TAG('A','R','A',' ')}, /* Babalia Creole Arabic (retired code) -> Arabic */
{"bcc", HB_TAG('B','L','I',' ')}, /* Southern Balochi -> Baluchi */
+ {"bch", HB_TAG_NONE }, /* Bariai != Bench */
{"bci", HB_TAG('B','A','U',' ')}, /* Baoulé -> Baulé */
{"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol -> Bikol */
{"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
@@ -107,6 +135,8 @@ static const LangTag ot_languages[] = {
{"beb", HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */
/*{"bem", HB_TAG('B','E','M',' ')},*/ /* Bemba (Zambia) */
{"ber", HB_TAG('B','B','R',' ')}, /* Berber [family] */
+ {"bew", HB_TAG('C','P','P',' ')}, /* Betawi -> Creoles */
+ {"bfl", HB_TAG('B','A','D','0')}, /* Banda-Ndélé -> Banda */
{"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
{"bft", HB_TAG('B','L','T',' ')}, /* Balti */
{"bfu", HB_TAG('L','A','H',' ')}, /* Gahri -> Lahuli */
@@ -115,7 +145,8 @@ static const LangTag ot_languages[] = {
/*{"bgc", HB_TAG('B','G','C',' ')},*/ /* Haryanvi */
{"bgn", HB_TAG('B','L','I',' ')}, /* Western Balochi -> Baluchi */
{"bgp", HB_TAG('B','L','I',' ')}, /* Eastern Balochi -> Baluchi */
-/*{"bgq", HB_TAG('B','G','Q',' ')},*/ /* Bagri */
+ {"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */
+ {"bgq", HB_TAG('R','A','J',' ')}, /* Bagri -> Rajasthani */
{"bgr", HB_TAG('Q','I','N',' ')}, /* Bawm Chin -> Chin */
{"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
/*{"bhi", HB_TAG('B','H','I',' ')},*/ /* Bhilali -> Bhili */
@@ -123,58 +154,107 @@ static const LangTag ot_languages[] = {
/*{"bho", HB_TAG('B','H','O',' ')},*/ /* Bhojpuri */
{"bhr", HB_TAG('M','L','G',' ')}, /* Bara Malagasy -> Malagasy */
{"bi", HB_TAG('B','I','S',' ')}, /* Bislama */
+ {"bi", HB_TAG('C','P','P',' ')}, /* Bislama -> Creoles */
/*{"bik", HB_TAG('B','I','K',' ')},*/ /* Bikol [macrolanguage] */
+ {"bil", HB_TAG_NONE }, /* Bile != Bilen */
{"bin", HB_TAG('E','D','O',' ')}, /* Edo */
+ {"biu", HB_TAG('Q','I','N',' ')}, /* Biete -> Chin */
/*{"bjj", HB_TAG('B','J','J',' ')},*/ /* Kanauji */
{"bjn", HB_TAG('M','L','Y',' ')}, /* Banjar -> Malay */
+ {"bjo", HB_TAG('B','A','D','0')}, /* Mid-Southern Banda -> Banda */
{"bjq", HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */
+ {"bjs", HB_TAG('C','P','P',' ')}, /* Bajan -> Creoles */
{"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja -> Balante */
+ {"bkf", HB_TAG_NONE }, /* Beeke != Blackfoot */
+ {"bko", HB_TAG('B','M','L',' ')}, /* Kwa' -> Bamileke */
{"bla", HB_TAG('B','K','F',' ')}, /* Siksika -> Blackfoot */
{"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe -> Balante */
-/*{"blk", HB_TAG('B','L','K',' ')},*/ /* Pa’o Karen */
+ {"bli", HB_TAG_NONE }, /* Bolia != Baluchi */
+ {"blk", HB_TAG('B','L','K',' ')}, /* Pa’o Karen */
+ {"blk", HB_TAG('K','R','N',' ')}, /* Pa'o Karen -> Karen */
{"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol -> Bikol */
+ {"blt", HB_TAG_NONE }, /* Tai Dam != Balti */
{"bm", HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */
+ {"bmb", HB_TAG_NONE }, /* Bembe != Bambara (Bamanankan) */
+ {"bml", HB_TAG_NONE }, /* Bomboli != Bamileke */
{"bmm", HB_TAG('M','L','G',' ')}, /* Northern Betsimisaraka Malagasy -> Malagasy */
{"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
{"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
+ {"bpd", HB_TAG('B','A','D','0')}, /* Banda-Banda -> Banda */
+ {"bpl", HB_TAG('C','P','P',' ')}, /* Broome Pearling Lugger Pidgin -> Creoles */
+ {"bpq", HB_TAG('C','P','P',' ')}, /* Banda Malay -> Creoles */
/*{"bpy", HB_TAG('B','P','Y',' ')},*/ /* Bishnupriya -> Bishnupriya Manipuri */
{"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari -> Luri */
+ {"bqk", HB_TAG('B','A','D','0')}, /* Banda-Mbrès -> Banda */
{"br", HB_TAG('B','R','E',' ')}, /* Breton */
{"bra", HB_TAG('B','R','I',' ')}, /* Braj -> Braj Bhasha */
+ {"brc", HB_TAG('C','P','P',' ')}, /* Berbice Creole Dutch -> Creoles */
/*{"brh", HB_TAG('B','R','H',' ')},*/ /* Brahui */
+ {"bri", HB_TAG_NONE }, /* Mokpwe != Braj Bhasha */
+ {"brm", HB_TAG_NONE }, /* Barambu != Burmese */
/*{"brx", HB_TAG('B','R','X',' ')},*/ /* Bodo (India) */
{"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
+ {"bsh", HB_TAG_NONE }, /* Kati != Bashkir */
/*{"bsk", HB_TAG('B','S','K',' ')},*/ /* Burushaski */
{"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) (retired code) */
+ {"btd", HB_TAG('B','T','D',' ')}, /* Batak Dairi (Pakpak) */
+ {"btd", HB_TAG('B','T','K',' ')}, /* Batak Dairi -> Batak */
+ {"bti", HB_TAG_NONE }, /* Burate != Beti */
{"btj", HB_TAG('M','L','Y',' ')}, /* Bacanese Malay -> Malay */
+/*{"btk", HB_TAG('B','T','K',' ')},*/ /* Batak [family] */
+ {"btm", HB_TAG('B','T','M',' ')}, /* Batak Mandailing */
+ {"btm", HB_TAG('B','T','K',' ')}, /* Batak Mandailing -> Batak */
{"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol -> Bikol */
-/*{"bts", HB_TAG('B','T','S',' ')},*/ /* Batak Simalungun */
+ {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */
+ {"bts", HB_TAG('B','T','K',' ')}, /* Batak Simalungun -> Batak */
+ {"btx", HB_TAG('B','T','X',' ')}, /* Batak Karo */
+ {"btx", HB_TAG('B','T','K',' ')}, /* Batak Karo -> Batak */
+ {"btz", HB_TAG('B','T','Z',' ')}, /* Batak Alas-Kluet */
+ {"btz", HB_TAG('B','T','K',' ')}, /* Batak Alas-Kluet -> Batak */
/*{"bug", HB_TAG('B','U','G',' ')},*/ /* Buginese -> Bugis */
{"bum", HB_TAG('B','T','I',' ')}, /* Bulu (Cameroon) -> Beti */
{"bve", HB_TAG('M','L','Y',' ')}, /* Berau Malay -> Malay */
{"bvu", HB_TAG('M','L','Y',' ')}, /* Bukit Malay -> Malay */
+ {"bwe", HB_TAG('K','R','N',' ')}, /* Bwe Karen -> Karen */
{"bxk", HB_TAG('L','U','H',' ')}, /* Bukusu -> Luyia */
+ {"bxo", HB_TAG('C','P','P',' ')}, /* Barikanchi -> Creoles */
{"bxp", HB_TAG('B','T','I',' ')}, /* Bebil -> Beti */
{"bxr", HB_TAG('R','B','U',' ')}, /* Russia Buriat -> Russian Buriat */
{"byn", HB_TAG('B','I','L',' ')}, /* Bilin -> Bilen */
-/*{"byv", HB_TAG('B','Y','V',' ')},*/ /* Medumba */
+ {"byv", HB_TAG('B','Y','V',' ')}, /* Medumba */
+ {"byv", HB_TAG('B','M','L',' ')}, /* Medumba -> Bamileke */
{"bzc", HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy -> Malagasy */
+ {"bzj", HB_TAG('C','P','P',' ')}, /* Belize Kriol English -> Creoles */
+ {"bzk", HB_TAG('C','P','P',' ')}, /* Nicaragua Creole English -> Creoles */
{"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
+ {"caa", HB_TAG('M','Y','N',' ')}, /* Chortí -> Mayan */
+ {"cac", HB_TAG('M','Y','N',' ')}, /* Chuj -> Mayan */
{"caf", HB_TAG('C','R','R',' ')}, /* Southern Carrier -> Carrier */
{"caf", HB_TAG('A','T','H',' ')}, /* Southern Carrier -> Athapaskan */
-/*{"cak", HB_TAG('C','A','K',' ')},*/ /* Kaqchikel */
-/*{"cbk", HB_TAG('C','B','K',' ')},*/ /* Chavacano -> Zamboanga Chavacano */
+ {"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */
+ {"cak", HB_TAG('M','Y','N',' ')}, /* Kaqchikel -> Mayan */
+ {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano -> Zamboanga Chavacano */
+ {"cbk", HB_TAG('C','P','P',' ')}, /* Chavacano -> Creoles */
{"cbl", HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin -> Chin */
+ {"ccl", HB_TAG('C','P','P',' ')}, /* Cutchi-Swahili -> Creoles */
+ {"ccm", HB_TAG('C','P','P',' ')}, /* Malaccan Creole Malay -> Creoles */
{"cco", HB_TAG('C','C','H','N')}, /* Comaltepec Chinantec -> Chinantec */
{"ccq", HB_TAG('A','R','K',' ')}, /* Chaungtha (retired code) -> Rakhine */
- {"cdo", HB_TAG('Z','H','S',' ')}, /* Min Dong Chinese -> Chinese Simplified */
+ {"cdo", HB_TAG('Z','H','S',' ')}, /* Min Dong Chinese -> Chinese, Simplified */
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
/*{"ceb", HB_TAG('C','E','B',' ')},*/ /* Cebuano */
+ {"cek", HB_TAG('Q','I','N',' ')}, /* Eastern Khumi Chin -> Chin */
+ {"cey", HB_TAG('Q','I','N',' ')}, /* Ekai Chin -> Chin */
{"cfm", HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) */
+ {"cfm", HB_TAG('Q','I','N',' ')}, /* Falam Chin -> Chin */
/*{"cgg", HB_TAG('C','G','G',' ')},*/ /* Chiga */
{"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */
+ {"chf", HB_TAG('M','Y','N',' ')}, /* Tabasco Chontal -> Mayan */
+ {"chg", HB_TAG_NONE }, /* Chagatai != Chaha Gurage */
+ {"chh", HB_TAG_NONE }, /* Chinook != Chattisgarhi */
{"chj", HB_TAG('C','C','H','N')}, /* Ojitlán Chinantec -> Chinantec */
{"chk", HB_TAG('C','H','K','0')}, /* Chuukese */
+ {"chn", HB_TAG('C','P','P',' ')}, /* Chinook jargon -> Creoles */
/*{"cho", HB_TAG('C','H','O',' ')},*/ /* Choctaw */
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
{"chp", HB_TAG('S','A','Y',' ')}, /* Chipewyan -> Sayisi */
@@ -186,59 +266,85 @@ static const LangTag ot_languages[] = {
{"ciw", HB_TAG('O','J','B',' ')}, /* Chippewa -> Ojibway */
/*{"cja", HB_TAG('C','J','A',' ')},*/ /* Western Cham */
/*{"cjm", HB_TAG('C','J','M',' ')},*/ /* Eastern Cham */
- {"cjy", HB_TAG('Z','H','S',' ')}, /* Jinyu Chinese -> Chinese Simplified */
+ {"cjy", HB_TAG('Z','H','S',' ')}, /* Jinyu Chinese -> Chinese, Simplified */
{"cka", HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin (retired code) -> Chin */
{"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish -> Kurdish */
+ {"ckn", HB_TAG('Q','I','N',' ')}, /* Kaang Chin -> Chin */
+ {"cks", HB_TAG('C','P','P',' ')}, /* Tayo -> Creoles */
{"ckt", HB_TAG('C','H','K',' ')}, /* Chukot -> Chukchi */
+ {"ckz", HB_TAG('M','Y','N',' ')}, /* Cakchiquel-Quiché Mixed Language -> Mayan */
{"clc", HB_TAG('A','T','H',' ')}, /* Chilcotin -> Athapaskan */
{"cld", HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic -> Syriac */
{"cle", HB_TAG('C','C','H','N')}, /* Lealao Chinantec -> Chinantec */
- {"cmn", HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese Simplified */
+ {"clj", HB_TAG('Q','I','N',' ')}, /* Laitu Chin -> Chin */
+ {"clt", HB_TAG('Q','I','N',' ')}, /* Lautu Chin -> Chin */
+ {"cmn", HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese, Simplified */
{"cmr", HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */
{"cnb", HB_TAG('Q','I','N',' ')}, /* Chinbon Chin -> Chin */
{"cnh", HB_TAG('Q','I','N',' ')}, /* Hakha Chin -> Chin */
{"cnk", HB_TAG('Q','I','N',' ')}, /* Khumi Chin -> Chin */
{"cnl", HB_TAG('C','C','H','N')}, /* Lalana Chinantec -> Chinantec */
- {"cnp", HB_TAG('Z','H','S',' ')}, /* Northern Ping Chinese -> Chinese Simplified */
+ {"cnp", HB_TAG('Z','H','S',' ')}, /* Northern Ping Chinese -> Chinese, Simplified */
+ {"cnr", HB_TAG('S','R','B',' ')}, /* Montenegrin -> Serbian */
{"cnt", HB_TAG('C','C','H','N')}, /* Tepetotutla Chinantec -> Chinantec */
+ {"cnu", HB_TAG('B','B','R',' ')}, /* Chenoua -> Berber */
{"cnw", HB_TAG('Q','I','N',' ')}, /* Ngawn Chin -> Chin */
{"co", HB_TAG('C','O','S',' ')}, /* Corsican */
{"coa", HB_TAG('M','L','Y',' ')}, /* Cocos Islands Malay -> Malay */
+ {"cob", HB_TAG('M','Y','N',' ')}, /* Chicomuceltec -> Mayan */
/*{"cop", HB_TAG('C','O','P',' ')},*/ /* Coptic */
{"coq", HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */
{"cpa", HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */
{"cpe", HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [family] -> Creoles */
{"cpf", HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [family] -> Creoles */
+ {"cpi", HB_TAG('C','P','P',' ')}, /* Chinese Pidgin English -> Creoles */
/*{"cpp", HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [family] -> Creoles */
- {"cpx", HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese Simplified */
+ {"cpx", HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese, Simplified */
{"cqd", HB_TAG('H','M','N',' ')}, /* Chuanqiandian Cluster Miao -> Hmong */
{"cqu", HB_TAG('Q','U','H',' ')}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */
+ {"cqu", HB_TAG('Q','U','Z',' ')}, /* Chilean Quechua (retired code) -> Quechua */
{"cr", HB_TAG('C','R','E',' ')}, /* Cree [macrolanguage] */
- {"cr", HB_TAG('Y','C','R',' ')}, /* Cree [macrolanguage] -> Y-Cree */
{"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */
+ {"cri", HB_TAG('C','P','P',' ')}, /* Sãotomense -> Creoles */
{"crj", HB_TAG('E','C','R',' ')}, /* Southern East Cree -> Eastern Cree */
+ {"crj", HB_TAG('Y','C','R',' ')}, /* Southern East Cree -> Y-Cree */
+ {"crj", HB_TAG('C','R','E',' ')}, /* Southern East Cree -> Cree */
{"crk", HB_TAG('W','C','R',' ')}, /* Plains Cree -> West-Cree */
+ {"crk", HB_TAG('Y','C','R',' ')}, /* Plains Cree -> Y-Cree */
+ {"crk", HB_TAG('C','R','E',' ')}, /* Plains Cree -> Cree */
{"crl", HB_TAG('E','C','R',' ')}, /* Northern East Cree -> Eastern Cree */
+ {"crl", HB_TAG('Y','C','R',' ')}, /* Northern East Cree -> Y-Cree */
+ {"crl", HB_TAG('C','R','E',' ')}, /* Northern East Cree -> Cree */
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
{"crm", HB_TAG('L','C','R',' ')}, /* Moose Cree -> L-Cree */
+ {"crm", HB_TAG('C','R','E',' ')}, /* Moose Cree -> Cree */
{"crp", HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [family] -> Creoles */
+ {"crr", HB_TAG_NONE }, /* Carolina Algonquian != Carrier */
+ {"crs", HB_TAG('C','P','P',' ')}, /* Seselwa Creole French -> Creoles */
+ {"crt", HB_TAG_NONE }, /* Iyojwa'ja Chorote != Crimean Tatar */
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
{"crx", HB_TAG('A','T','H',' ')}, /* Carrier -> Athapaskan */
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
{"csa", HB_TAG('C','C','H','N')}, /* Chiltepec Chinantec -> Chinantec */
/*{"csb", HB_TAG('C','S','B',' ')},*/ /* Kashubian */
{"csh", HB_TAG('Q','I','N',' ')}, /* Asho Chin -> Chin */
+ {"csj", HB_TAG('Q','I','N',' ')}, /* Songlai Chin -> Chin */
+ {"csl", HB_TAG_NONE }, /* Chinese Sign Language != Church Slavonic */
{"cso", HB_TAG('C','C','H','N')}, /* Sochiapam Chinantec -> Chinantec */
- {"csp", HB_TAG('Z','H','S',' ')}, /* Southern Ping Chinese -> Chinese Simplified */
+ {"csp", HB_TAG('Z','H','S',' ')}, /* Southern Ping Chinese -> Chinese, Simplified */
+ {"csv", HB_TAG('Q','I','N',' ')}, /* Sumtu Chin -> Chin */
{"csw", HB_TAG('N','C','R',' ')}, /* Swampy Cree -> N-Cree */
{"csw", HB_TAG('N','H','C',' ')}, /* Swampy Cree -> Norway House Cree */
+ {"csw", HB_TAG('C','R','E',' ')}, /* Swampy Cree -> Cree */
{"csy", HB_TAG('Q','I','N',' ')}, /* Siyin Chin -> Chin */
{"ctc", HB_TAG('A','T','H',' ')}, /* Chetco -> Athapaskan */
{"ctd", HB_TAG('Q','I','N',' ')}, /* Tedim Chin -> Chin */
{"cte", HB_TAG('C','C','H','N')}, /* Tepinapa Chinantec -> Chinantec */
/*{"ctg", HB_TAG('C','T','G',' ')},*/ /* Chittagonian */
+ {"cth", HB_TAG('Q','I','N',' ')}, /* Thaiphum Chin -> Chin */
{"ctl", HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */
{"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */
+ {"ctu", HB_TAG('M','Y','N',' ')}, /* Chol -> Mayan */
{"cu", HB_TAG('C','S','L',' ')}, /* Church Slavonic */
{"cuc", HB_TAG('C','C','H','N')}, /* Usila Chinantec -> Chinantec */
/*{"cuk", HB_TAG('C','U','K',' ')},*/ /* San Blas Kuna */
@@ -246,39 +352,50 @@ static const LangTag ot_languages[] = {
{"cvn", HB_TAG('C','C','H','N')}, /* Valle Nacional Chinantec -> Chinantec */
{"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
{"cwd", HB_TAG('T','C','R',' ')}, /* Woods Cree -> TH-Cree */
+ {"cwd", HB_TAG('C','R','E',' ')}, /* Woods Cree -> Cree */
{"cy", HB_TAG('W','E','L',' ')}, /* Welsh */
- {"czh", HB_TAG('Z','H','S',' ')}, /* Huizhou Chinese -> Chinese Simplified */
- {"czo", HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese Simplified */
+ {"czh", HB_TAG('Z','H','S',' ')}, /* Huizhou Chinese -> Chinese, Simplified */
+ {"czo", HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese, Simplified */
{"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin -> Chin */
{"da", HB_TAG('D','A','N',' ')}, /* Danish */
{"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin -> Chin */
{"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) (retired code) */
/*{"dar", HB_TAG('D','A','R',' ')},*/ /* Dargwa */
/*{"dax", HB_TAG('D','A','X',' ')},*/ /* Dayi */
+ {"dcr", HB_TAG('C','P','P',' ')}, /* Negerhollands -> Creoles */
{"de", HB_TAG('D','E','U',' ')}, /* German */
{"den", HB_TAG('S','L','A',' ')}, /* Slave (Athapascan) [macrolanguage] -> Slavey */
{"den", HB_TAG('A','T','H',' ')}, /* Slave (Athapascan) [macrolanguage] -> Athapaskan */
-/*{"dgo", HB_TAG('D','G','O',' ')},*/ /* Dogri */
+ {"dep", HB_TAG('C','P','P',' ')}, /* Pidgin Delaware -> Creoles */
+ {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri (individual language) */
+ {"dgo", HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) */
{"dgr", HB_TAG('A','T','H',' ')}, /* Dogrib -> Athapaskan */
{"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari -> Marwari */
/*{"dhg", HB_TAG('D','H','G',' ')},*/ /* Dhangu */
+ {"dhv", HB_TAG_NONE }, /* Dehu != Divehi (Dhivehi, Maldivian) (deprecated) */
{"dib", HB_TAG('D','N','K',' ')}, /* South Central Dinka -> Dinka */
{"dik", HB_TAG('D','N','K',' ')}, /* Southwestern Dinka -> Dinka */
{"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */
{"dip", HB_TAG('D','N','K',' ')}, /* Northeastern Dinka -> Dinka */
-/*{"diq", HB_TAG('D','I','Q',' ')},*/ /* Dimli */
+ {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */
+ {"diq", HB_TAG('Z','Z','A',' ')}, /* Dimli -> Zazaki */
{"diw", HB_TAG('D','N','K',' ')}, /* Northwestern Dinka -> Dinka */
{"dje", HB_TAG('D','J','R',' ')}, /* Zarma */
+ {"djk", HB_TAG('C','P','P',' ')}, /* Eastern Maroon Creole -> Creoles */
{"djr", HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */
{"dks", HB_TAG('D','N','K',' ')}, /* Southeastern Dinka -> Dinka */
{"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
/*{"dnj", HB_TAG('D','N','J',' ')},*/ /* Dan */
- {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */
+ {"dnk", HB_TAG_NONE }, /* Dengka != Dinka */
+ {"doi", HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) [macrolanguage] */
{"drh", HB_TAG('M','N','G',' ')}, /* Darkhat (retired code) -> Mongolian */
+ {"dri", HB_TAG_NONE }, /* C'Lela != Dari */
{"drw", HB_TAG('D','R','I',' ')}, /* Darwazi (retired code) -> Dari */
+ {"drw", HB_TAG('F','A','R',' ')}, /* Darwazi (retired code) -> Persian */
{"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
{"dty", HB_TAG('N','E','P',' ')}, /* Dotyali -> Nepali */
/*{"duj", HB_TAG('D','U','J',' ')},*/ /* Dhuwal (retired code) */
+ {"dun", HB_TAG_NONE }, /* Dusun Deyah != Dungan */
{"dup", HB_TAG('M','L','Y',' ')}, /* Duano -> Malay */
{"dv", HB_TAG('D','I','V',' ')}, /* Divehi (Dhivehi, Maldivian) */
{"dv", HB_TAG('D','H','V',' ')}, /* Divehi (Dhivehi, Maldivian) (deprecated) */
@@ -287,16 +404,20 @@ static const LangTag ot_languages[] = {
{"dwy", HB_TAG('D','U','J',' ')}, /* Dhuwaya -> Dhuwal */
{"dyu", HB_TAG('J','U','L',' ')}, /* Dyula -> Jula */
{"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
+ {"dzn", HB_TAG_NONE }, /* Dzando != Dzongkha */
+ {"ecr", HB_TAG_NONE }, /* Eteocretan != Eastern Cree */
{"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
/*{"efi", HB_TAG('E','F','I',' ')},*/ /* Efik */
{"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian -> Estonian */
+ {"eky", HB_TAG('K','R','N',' ')}, /* Eastern Kayah -> Karen */
{"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) -> Greek */
{"emk", HB_TAG('E','M','K',' ')}, /* Eastern Maninkakan */
{"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan -> Maninka */
+ {"emy", HB_TAG('M','Y','N',' ')}, /* Epigraphic Mayan -> Mayan */
{"en", HB_TAG('E','N','G',' ')}, /* English */
{"enb", HB_TAG('K','A','L',' ')}, /* Markweeta -> Kalenjin */
- {"enf", HB_TAG('F','N','E',' ')}, /* Forest Enets -> Forest Nenets */
- {"enh", HB_TAG('T','N','E',' ')}, /* Tundra Enets -> Tundra Nenets */
+ {"enf", HB_TAG('F','N','E',' ')}, /* Forest Enets */
+ {"enh", HB_TAG('T','N','E',' ')}, /* Tundra Enets */
{"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
{"es", HB_TAG('E','S','P',' ')}, /* Spanish */
{"esg", HB_TAG('G','O','N',' ')}, /* Aheri Gondi -> Gondi */
@@ -306,13 +427,18 @@ static const LangTag ot_languages[] = {
{"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */
{"eto", HB_TAG('B','T','I',' ')}, /* Eton (Cameroon) -> Beti */
{"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
+ {"euq", HB_TAG_NONE }, /* Basque [family] != Basque */
{"eve", HB_TAG('E','V','N',' ')}, /* Even */
{"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
{"ewo", HB_TAG('B','T','I',' ')}, /* Ewondo -> Beti */
{"eyo", HB_TAG('K','A','L',' ')}, /* Keiyo -> Kalenjin */
{"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */
+ {"fab", HB_TAG('C','P','P',' ')}, /* Fa d'Ambu -> Creoles */
{"fan", HB_TAG('F','A','N','0')}, /* Fang (Equatorial Guinea) */
-/*{"fat", HB_TAG('F','A','T',' ')},*/ /* Fanti */
+ {"fan", HB_TAG('B','T','I',' ')}, /* Fang (Equatorial Guinea) -> Beti */
+ {"far", HB_TAG_NONE }, /* Fataleka != Persian */
+ {"fat", HB_TAG('F','A','T',' ')}, /* Fanti */
+ {"fat", HB_TAG('A','K','A',' ')}, /* Fanti -> Akan */
{"fbl", HB_TAG('B','I','K',' ')}, /* West Albay Bikol -> Bikol */
{"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */
{"ffm", HB_TAG('F','U','L',' ')}, /* Maasina Fulfulde -> Fulah */
@@ -321,9 +447,13 @@ static const LangTag ot_languages[] = {
{"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
{"flm", HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) (retired code) */
{"flm", HB_TAG('Q','I','N',' ')}, /* Falam Chin (retired code) -> Chin */
-/*{"fmp", HB_TAG('F','M','P',' ')},*/ /* Fe’fe’ */
+ {"fmp", HB_TAG('F','M','P',' ')}, /* Fe’fe’ */
+ {"fmp", HB_TAG('B','M','L',' ')}, /* Fe'fe' -> Bamileke */
+ {"fng", HB_TAG('C','P','P',' ')}, /* Fanagalo -> Creoles */
{"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
/*{"fon", HB_TAG('F','O','N',' ')},*/ /* Fon */
+ {"fos", HB_TAG_NONE }, /* Siraya != Faroese */
+ {"fpe", HB_TAG('C','P','P',' ')}, /* Fernando Po Creole English -> Creoles */
{"fr", HB_TAG('F','R','A',' ')}, /* French */
/*{"frc", HB_TAG('F','R','C',' ')},*/ /* Cajun French */
/*{"frp", HB_TAG('F','R','P',' ')},*/ /* Arpitan */
@@ -331,60 +461,89 @@ static const LangTag ot_languages[] = {
{"fuc", HB_TAG('F','U','L',' ')}, /* Pulaar -> Fulah */
{"fue", HB_TAG('F','U','L',' ')}, /* Borgu Fulfulde -> Fulah */
{"fuf", HB_TAG('F','T','A',' ')}, /* Pular -> Futa */
+ {"fuf", HB_TAG('F','U','L',' ')}, /* Pular -> Fulah */
{"fuh", HB_TAG('F','U','L',' ')}, /* Western Niger Fulfulde -> Fulah */
{"fui", HB_TAG('F','U','L',' ')}, /* Bagirmi Fulfulde -> Fulah */
{"fuq", HB_TAG('F','U','L',' ')}, /* Central-Eastern Niger Fulfulde -> Fulah */
{"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
-/*{"fuv", HB_TAG('F','U','V',' ')},*/ /* Nigerian Fulfulde */
+ {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */
+ {"fuv", HB_TAG('F','U','L',' ')}, /* Nigerian Fulfulde -> Fulah */
{"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */
{"ga", HB_TAG('I','R','I',' ')}, /* Irish */
{"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
+ {"gac", HB_TAG('C','P','P',' ')}, /* Mixed Great Andamanese -> Creoles */
+ {"gad", HB_TAG_NONE }, /* Gaddang != Ga */
+ {"gae", HB_TAG_NONE }, /* Guarequena != Scottish Gaelic (Gaelic) */
/*{"gag", HB_TAG('G','A','G',' ')},*/ /* Gagauz */
- {"gan", HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese Simplified */
+ {"gal", HB_TAG_NONE }, /* Galolen != Galician */
+ {"gan", HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese, Simplified */
+ {"gar", HB_TAG_NONE }, /* Galeya != Garshuni */
+ {"gaw", HB_TAG_NONE }, /* Nobonob != Garhwali */
{"gax", HB_TAG('O','R','O',' ')}, /* Borana-Arsi-Guji Oromo -> Oromo */
{"gaz", HB_TAG('O','R','O',' ')}, /* West Central Oromo -> Oromo */
{"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
{"gce", HB_TAG('A','T','H',' ')}, /* Galice -> Athapaskan */
+ {"gcf", HB_TAG('C','P','P',' ')}, /* Guadeloupean Creole French -> Creoles */
+ {"gcl", HB_TAG('C','P','P',' ')}, /* Grenadian Creole English -> Creoles */
+ {"gcr", HB_TAG('C','P','P',' ')}, /* Guianese Creole French -> Creoles */
{"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */
{"gda", HB_TAG('R','A','J',' ')}, /* Gade Lohar -> Rajasthani */
/*{"gez", HB_TAG('G','E','Z',' ')},*/ /* Geez */
{"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi (retired code) -> Gondi */
+ {"gha", HB_TAG('B','B','R',' ')}, /* Ghadamès -> Berber */
+ {"ghk", HB_TAG('K','R','N',' ')}, /* Geko Karen -> Karen */
+ {"gho", HB_TAG('B','B','R',' ')}, /* Ghomara -> Berber */
+ {"gib", HB_TAG('C','P','P',' ')}, /* Gibanawa -> Creoles */
/*{"gih", HB_TAG('G','I','H',' ')},*/ /* Githabul */
{"gil", HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */
{"gju", HB_TAG('R','A','J',' ')}, /* Gujari -> Rajasthani */
-/*{"gkp", HB_TAG('G','K','P',' ')},*/ /* Guinea Kpelle -> Kpelle (Guinea) */
+ {"gkp", HB_TAG('G','K','P',' ')}, /* Guinea Kpelle -> Kpelle (Guinea) */
+ {"gkp", HB_TAG('K','P','L',' ')}, /* Guinea Kpelle -> Kpelle */
{"gl", HB_TAG('G','A','L',' ')}, /* Galician */
{"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
/*{"glk", HB_TAG('G','L','K',' ')},*/ /* Gilaki */
+ {"gmz", HB_TAG_NONE }, /* Mgbolizhia != Gumuz */
{"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */
+ {"gnb", HB_TAG('Q','I','N',' ')}, /* Gangte -> Chin */
/*{"gnn", HB_TAG('G','N','N',' ')},*/ /* Gumatj */
{"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi -> Gondi */
{"gnw", HB_TAG('G','U','A',' ')}, /* Western Bolivian Guaraní -> Guarani */
/*{"gog", HB_TAG('G','O','G',' ')},*/ /* Gogo */
{"gom", HB_TAG('K','O','K',' ')}, /* Goan Konkani -> Konkani */
/*{"gon", HB_TAG('G','O','N',' ')},*/ /* Gondi [macrolanguage] */
+ {"goq", HB_TAG('C','P','P',' ')}, /* Gorap -> Creoles */
+ {"gox", HB_TAG('B','A','D','0')}, /* Gobu -> Banda */
+ {"gpe", HB_TAG('C','P','P',' ')}, /* Ghanaian Pidgin English -> Creoles */
+ {"gro", HB_TAG_NONE }, /* Groma != Garo */
+ {"grr", HB_TAG('B','B','R',' ')}, /* Taznatit -> Berber */
{"grt", HB_TAG('G','R','O',' ')}, /* Garo */
{"gru", HB_TAG('S','O','G',' ')}, /* Kistane -> Sodo Gurage */
{"gsw", HB_TAG('A','L','S',' ')}, /* Alsatian */
{"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
+ {"gua", HB_TAG_NONE }, /* Shiki != Guarani */
/*{"guc", HB_TAG('G','U','C',' ')},*/ /* Wayuu */
/*{"guf", HB_TAG('G','U','F',' ')},*/ /* Gupapuyngu */
{"gug", HB_TAG('G','U','A',' ')}, /* Paraguayan Guaraní -> Guarani */
{"gui", HB_TAG('G','U','A',' ')}, /* Eastern Bolivian Guaraní -> Guarani */
{"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
- {"guk", HB_TAG('G','U','K',' ')}, /* Gumuz (SIL fonts) */
+ {"gul", HB_TAG('C','P','P',' ')}, /* Sea Island Creole English -> Creoles */
{"gun", HB_TAG('G','U','A',' ')}, /* Mbyá Guaraní -> Guarani */
/*{"guz", HB_TAG('G','U','Z',' ')},*/ /* Gusii */
{"gv", HB_TAG('M','N','X',' ')}, /* Manx */
{"gwi", HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */
+ {"gyn", HB_TAG('C','P','P',' ')}, /* Guyanese Creole English -> Creoles */
{"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
{"haa", HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */
{"hae", HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */
- {"hak", HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese Simplified */
+ {"hai", HB_TAG_NONE }, /* Haida [macrolanguage] != Haitian (Haitian Creole) */
+ {"hak", HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese, Simplified */
+ {"hal", HB_TAG_NONE }, /* Halang != Halam (Falam Chin) */
{"har", HB_TAG('H','R','I',' ')}, /* Harari */
/*{"haw", HB_TAG('H','A','W',' ')},*/ /* Hawaiian */
/*{"hay", HB_TAG('H','A','Y',' ')},*/ /* Haya */
/*{"haz", HB_TAG('H','A','Z',' ')},*/ /* Hazaragi */
+ {"hbn", HB_TAG_NONE }, /* Heiban != Hammer-Banna */
+ {"hca", HB_TAG('C','P','P',' ')}, /* Andaman Creole Hindi -> Creoles */
{"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
{"hea", HB_TAG('H','M','N',' ')}, /* Northern Qiandong Miao -> Hmong */
{"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
@@ -404,6 +563,7 @@ static const LangTag ot_languages[] = {
/*{"hmn", HB_TAG('H','M','N',' ')},*/ /* Hmong [macrolanguage] */
{"hmp", HB_TAG('H','M','N',' ')}, /* Northern Mashan Hmong -> Hmong */
{"hmq", HB_TAG('H','M','N',' ')}, /* Eastern Qiandong Miao -> Hmong */
+ {"hmr", HB_TAG('Q','I','N',' ')}, /* Hmar -> Chin */
{"hms", HB_TAG('H','M','N',' ')}, /* Southern Qiandong Miao -> Hmong */
{"hmw", HB_TAG('H','M','N',' ')}, /* Western Mashan Hmong -> Hmong */
{"hmy", HB_TAG('H','M','N',' ')}, /* Southern Guiyang Hmong -> Hmong */
@@ -413,17 +573,23 @@ static const LangTag ot_languages[] = {
{"hnj", HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */
{"hno", HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */
{"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */
+ {"ho", HB_TAG('C','P','P',' ')}, /* Hiri Motu -> Creoles */
{"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
{"hoi", HB_TAG('A','T','H',' ')}, /* Holikachuk -> Athapaskan */
{"hoj", HB_TAG('H','A','R',' ')}, /* Hadothi -> Harauti */
+ {"hoj", HB_TAG('R','A','J',' ')}, /* Hadothi -> Rajasthani */
{"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
+ {"hra", HB_TAG('Q','I','N',' ')}, /* Hrangkhol -> Chin */
{"hrm", HB_TAG('H','M','N',' ')}, /* Horned Miao -> Hmong */
{"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
- {"hsn", HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese Simplified */
+ {"hsn", HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese, Simplified */
{"ht", HB_TAG('H','A','I',' ')}, /* Haitian (Haitian Creole) */
+ {"ht", HB_TAG('C','P','P',' ')}, /* Haitian -> Creoles */
{"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
{"huj", HB_TAG('H','M','N',' ')}, /* Northern Guiyang Hmong -> Hmong */
{"hup", HB_TAG('A','T','H',' ')}, /* Hupa -> Athapaskan */
+ {"hus", HB_TAG('M','Y','N',' ')}, /* Huastec -> Mayan */
+ {"hwc", HB_TAG('C','P','P',' ')}, /* Hawai'i Creole English -> Creoles */
{"hy", HB_TAG('H','Y','E','0')}, /* Armenian -> Armenian East */
{"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
{"hyw", HB_TAG('H','Y','E',' ')}, /* Western Armenian -> Armenian */
@@ -431,38 +597,65 @@ static const LangTag ot_languages[] = {
{"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */
/*{"iba", HB_TAG('I','B','A',' ')},*/ /* Iban */
/*{"ibb", HB_TAG('I','B','B',' ')},*/ /* Ibibio */
+ {"iby", HB_TAG('I','J','O',' ')}, /* Ibani -> Ijo */
+ {"icr", HB_TAG('C','P','P',' ')}, /* Islander Creole English -> Creoles */
{"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
+ {"id", HB_TAG('M','L','Y',' ')}, /* Indonesian -> Malay */
{"ida", HB_TAG('L','U','H',' ')}, /* Idakho-Isukha-Tiriki -> Luyia */
+ {"idb", HB_TAG('C','P','P',' ')}, /* Indo-Portuguese -> Creoles */
{"ie", HB_TAG('I','L','E',' ')}, /* Interlingue */
{"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
{"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
+ {"ihb", HB_TAG('C','P','P',' ')}, /* Iha Based Pidgin -> Creoles */
{"ii", HB_TAG('Y','I','M',' ')}, /* Sichuan Yi -> Yi Modern */
{"ijc", HB_TAG('I','J','O',' ')}, /* Izon -> Ijo */
+ {"ije", HB_TAG('I','J','O',' ')}, /* Biseni -> Ijo */
+ {"ijn", HB_TAG('I','J','O',' ')}, /* Kalabari -> Ijo */
/*{"ijo", HB_TAG('I','J','O',' ')},*/ /* Ijo [family] */
+ {"ijs", HB_TAG('I','J','O',' ')}, /* Southeast Ijo -> Ijo */
{"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] -> Inupiat */
{"ike", HB_TAG('I','N','U',' ')}, /* Eastern Canadian Inuktitut -> Inuktitut */
{"ikt", HB_TAG('I','N','U',' ')}, /* Inuinnaqtun -> Inuktitut */
/*{"ilo", HB_TAG('I','L','O',' ')},*/ /* Iloko -> Ilokano */
{"in", HB_TAG('I','N','D',' ')}, /* Indonesian (retired code) */
+ {"in", HB_TAG('M','L','Y',' ')}, /* Indonesian (retired code) -> Malay */
{"ing", HB_TAG('A','T','H',' ')}, /* Degexit'an -> Athapaskan */
{"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
{"io", HB_TAG('I','D','O',' ')}, /* Ido */
+ {"iri", HB_TAG_NONE }, /* Rigwe != Irish */
{"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
+ {"ism", HB_TAG_NONE }, /* Masimasi != Inari Sami */
{"it", HB_TAG('I','T','A',' ')}, /* Italian */
+ {"itz", HB_TAG('M','Y','N',' ')}, /* Itzá -> Mayan */
{"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */
{"iw", HB_TAG('I','W','R',' ')}, /* Hebrew (retired code) */
+ {"ixl", HB_TAG('M','Y','N',' ')}, /* Ixil -> Mayan */
{"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
+ {"jac", HB_TAG('M','Y','N',' ')}, /* Popti' -> Mayan */
{"jak", HB_TAG('M','L','Y',' ')}, /* Jakun -> Malay */
-/*{"jam", HB_TAG('J','A','M',' ')},*/ /* Jamaican Creole English -> Jamaican Creole */
+ {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English -> Jamaican Creole */
+ {"jam", HB_TAG('C','P','P',' ')}, /* Jamaican Creole English -> Creoles */
+ {"jan", HB_TAG_NONE }, /* Jandai != Japanese */
{"jax", HB_TAG('M','L','Y',' ')}, /* Jambi Malay -> Malay */
+ {"jbe", HB_TAG('B','B','R',' ')}, /* Judeo-Berber -> Berber */
+ {"jbn", HB_TAG('B','B','R',' ')}, /* Nafusi -> Berber */
/*{"jbo", HB_TAG('J','B','O',' ')},*/ /* Lojban */
/*{"jct", HB_TAG('J','C','T',' ')},*/ /* Krymchak */
+ {"jgo", HB_TAG('B','M','L',' ')}, /* Ngomba -> Bamileke */
{"ji", HB_TAG('J','I','I',' ')}, /* Yiddish (retired code) */
+ {"jii", HB_TAG_NONE }, /* Jiiddu != Yiddish */
+ {"jkm", HB_TAG('K','R','N',' ')}, /* Mobwa Karen -> Karen */
+ {"jkp", HB_TAG('K','R','N',' ')}, /* Paku Karen -> Karen */
+ {"jud", HB_TAG_NONE }, /* Worodougou != Ladino */
+ {"jul", HB_TAG_NONE }, /* Jirel != Jula */
{"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
+ {"jvd", HB_TAG('C','P','P',' ')}, /* Javindo -> Creoles */
{"jw", HB_TAG('J','A','V',' ')}, /* Javanese (retired code) */
{"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
{"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */
{"kab", HB_TAG('K','A','B','0')}, /* Kabyle */
+ {"kab", HB_TAG('B','B','R',' ')}, /* Kabyle -> Berber */
+ {"kac", HB_TAG_NONE }, /* Kachin != Kachchi */
{"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
{"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
{"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
@@ -470,83 +663,139 @@ static const LangTag ot_languages[] = {
{"kca", HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */
{"kca", HB_TAG('K','H','S',' ')}, /* Khanty -> Khanty-Shurishkar */
{"kca", HB_TAG('K','H','V',' ')}, /* Khanty -> Khanty-Vakhi */
+ {"kcn", HB_TAG('C','P','P',' ')}, /* Nubi -> Creoles */
/*{"kde", HB_TAG('K','D','E',' ')},*/ /* Makonde */
{"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
{"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
-/*{"kea", HB_TAG('K','E','A',' ')},*/ /* Kabuverdianu (Crioulo) */
-/*{"kek", HB_TAG('K','E','K',' ')},*/ /* Kekchi */
+ {"kea", HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */
+ {"kea", HB_TAG('C','P','P',' ')}, /* Kabuverdianu -> Creoles */
+ {"keb", HB_TAG_NONE }, /* Kélé != Kebena */
+ {"kek", HB_TAG('K','E','K',' ')}, /* Kekchi */
+ {"kek", HB_TAG('M','Y','N',' ')}, /* Kekchí -> Mayan */
{"kex", HB_TAG('K','K','N',' ')}, /* Kukna -> Kokni */
{"kfa", HB_TAG('K','O','D',' ')}, /* Kodava -> Kodagu */
{"kfr", HB_TAG('K','A','C',' ')}, /* Kachhi -> Kachchi */
{"kfx", HB_TAG('K','U','L',' ')}, /* Kullu Pahari -> Kulvi */
{"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
{"kg", HB_TAG('K','O','N','0')}, /* Kongo [macrolanguage] */
+ {"kge", HB_TAG_NONE }, /* Komering != Khutsuri Georgian */
{"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
{"khb", HB_TAG('X','B','D',' ')}, /* Lü */
{"khk", HB_TAG('M','N','G',' ')}, /* Halh Mongolian -> Mongolian */
+ {"khn", HB_TAG_NONE }, /* Khandesi != Khamti Shan (Microsoft fonts) */
+ {"khs", HB_TAG_NONE }, /* Kasua != Khanty-Shurishkar */
+ {"kht", HB_TAG('K','H','T',' ')}, /* Khamti -> Khamti Shan */
{"kht", HB_TAG('K','H','N',' ')}, /* Khamti -> Khamti Shan (Microsoft fonts) */
- {"kht", HB_TAG('K','H','T',' ')}, /* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */
+ {"khv", HB_TAG_NONE }, /* Khvarshi != Khanty-Vakhi */
/*{"khw", HB_TAG('K','H','W',' ')},*/ /* Khowar */
{"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu (Gikuyu) */
-/*{"kiu", HB_TAG('K','I','U',' ')},*/ /* Kirmanjki */
+ {"kis", HB_TAG_NONE }, /* Kis != Kisii */
+ {"kiu", HB_TAG('K','I','U',' ')}, /* Kirmanjki */
+ {"kiu", HB_TAG('Z','Z','A',' ')}, /* Kirmanjki -> Zazaki */
{"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama */
+ {"kjb", HB_TAG('M','Y','N',' ')}, /* Q'anjob'al -> Mayan */
/*{"kjd", HB_TAG('K','J','D',' ')},*/ /* Southern Kiwai */
{"kjh", HB_TAG('K','H','A',' ')}, /* Khakas -> Khakass */
-/*{"kjp", HB_TAG('K','J','P',' ')},*/ /* Pwo Eastern Karen -> Eastern Pwo Karen */
+ {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen -> Eastern Pwo Karen */
+ {"kjp", HB_TAG('K','R','N',' ')}, /* Pwo Eastern Karen -> Karen */
+ {"kjt", HB_TAG('K','R','N',' ')}, /* Phrae Pwo Karen -> Karen */
/*{"kjz", HB_TAG('K','J','Z',' ')},*/ /* Bumthangkha */
{"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
+ {"kkn", HB_TAG_NONE }, /* Kon Keu != Kokni */
{"kkz", HB_TAG('A','T','H',' ')}, /* Kaska -> Athapaskan */
{"kl", HB_TAG('G','R','N',' ')}, /* Greenlandic */
+ {"klm", HB_TAG_NONE }, /* Migum != Kalmyk */
{"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin [macrolanguage] */
{"km", HB_TAG('K','H','M',' ')}, /* Khmer */
{"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu -> Mbundu */
+ {"kmn", HB_TAG_NONE }, /* Awtuw != Kumaoni */
+ {"kmo", HB_TAG_NONE }, /* Kwoma != Komo */
{"kmr", HB_TAG('K','U','R',' ')}, /* Northern Kurdish -> Kurdish */
+ {"kms", HB_TAG_NONE }, /* Kamasau != Komso */
+ {"kmv", HB_TAG('C','P','P',' ')}, /* Karipúna Creole French -> Creoles */
{"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
/*{"kmz", HB_TAG('K','M','Z',' ')},*/ /* Khorasani Turkish -> Khorasani Turkic */
{"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
{"knc", HB_TAG('K','N','R',' ')}, /* Central Kanuri -> Kanuri */
{"kng", HB_TAG('K','O','N','0')}, /* Koongo -> Kongo */
+ {"knj", HB_TAG('M','Y','N',' ')}, /* Western Kanjobal -> Mayan */
{"knn", HB_TAG('K','O','K',' ')}, /* Konkani */
+ {"knr", HB_TAG_NONE }, /* Kaningra != Kanuri */
{"ko", HB_TAG('K','O','R',' ')}, /* Korean */
+ {"ko", HB_TAG('K','O','H',' ')}, /* Korean -> Korean Old Hangul */
+ {"kod", HB_TAG_NONE }, /* Kodi != Kodagu */
+ {"koh", HB_TAG_NONE }, /* Koyo != Korean Old Hangul */
{"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
+ {"koi", HB_TAG('K','O','M',' ')}, /* Komi-Permyak -> Komi */
/*{"kok", HB_TAG('K','O','K',' ')},*/ /* Konkani [macrolanguage] */
+ {"kop", HB_TAG_NONE }, /* Waube != Komi-Permyak */
/*{"kos", HB_TAG('K','O','S',' ')},*/ /* Kosraean */
{"koy", HB_TAG('A','T','H',' ')}, /* Koyukon -> Athapaskan */
+ {"koz", HB_TAG_NONE }, /* Korak != Komi-Zyrian */
{"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */
+ {"kpl", HB_TAG_NONE }, /* Kpala != Kpelle */
+ {"kpp", HB_TAG('K','R','N',' ')}, /* Paku Karen (retired code) -> Karen */
{"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
+ {"kpv", HB_TAG('K','O','M',' ')}, /* Komi-Zyrian -> Komi */
{"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
{"kqs", HB_TAG('K','I','S',' ')}, /* Northern Kissi -> Kisii */
{"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
{"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */
{"krc", HB_TAG('K','A','R',' ')}, /* Karachay-Balkar -> Karachay */
{"krc", HB_TAG('B','A','L',' ')}, /* Karachay-Balkar -> Balkar */
-/*{"kri", HB_TAG('K','R','I',' ')},*/ /* Krio */
+ {"kri", HB_TAG('K','R','I',' ')}, /* Krio */
+ {"kri", HB_TAG('C','P','P',' ')}, /* Krio -> Creoles */
+ {"krk", HB_TAG_NONE }, /* Kerek != Karakalpak */
/*{"krl", HB_TAG('K','R','L',' ')},*/ /* Karelian */
+ {"krm", HB_TAG_NONE }, /* Krim (retired code) != Karaim */
+ {"krn", HB_TAG_NONE }, /* Sapo != Karen */
{"krt", HB_TAG('K','N','R',' ')}, /* Tumari Kanuri -> Kanuri */
{"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
{"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
{"ksh", HB_TAG('K','S','H','0')}, /* Kölsch -> Ripuarian */
+ {"ksi", HB_TAG_NONE }, /* Krisa != Khasi */
+ {"ksm", HB_TAG_NONE }, /* Kumba != Kildin Sami */
{"kss", HB_TAG('K','I','S',' ')}, /* Southern Kisi -> Kisii */
-/*{"ksw", HB_TAG('K','S','W',' ')},*/ /* S’gaw Karen */
+ {"ksw", HB_TAG('K','S','W',' ')}, /* S’gaw Karen */
+ {"ksw", HB_TAG('K','R','N',' ')}, /* S'gaw Karen -> Karen */
{"ktb", HB_TAG('K','E','B',' ')}, /* Kambaata -> Kebena */
{"ktu", HB_TAG('K','O','N',' ')}, /* Kituba (Democratic Republic of Congo) -> Kikongo */
{"ktw", HB_TAG('A','T','H',' ')}, /* Kato -> Athapaskan */
{"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */
+ {"kui", HB_TAG_NONE }, /* Kuikúro-Kalapálo != Kui */
+ {"kul", HB_TAG_NONE }, /* Kulere != Kulvi */
/*{"kum", HB_TAG('K','U','M',' ')},*/ /* Kumyk */
{"kuu", HB_TAG('A','T','H',' ')}, /* Upper Kuskokwim -> Athapaskan */
+ {"kuw", HB_TAG('B','A','D','0')}, /* Kpagua -> Banda */
+ {"kuy", HB_TAG_NONE }, /* Kuuku-Ya'u != Kuy */
{"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */
{"kvb", HB_TAG('M','L','Y',' ')}, /* Kubu -> Malay */
+ {"kvl", HB_TAG('K','R','N',' ')}, /* Kayaw -> Karen */
+ {"kvq", HB_TAG('K','R','N',' ')}, /* Geba Karen -> Karen */
{"kvr", HB_TAG('M','L','Y',' ')}, /* Kerinci -> Malay */
+ {"kvt", HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */
+ {"kvu", HB_TAG('K','R','N',' ')}, /* Yinbaw Karen -> Karen */
+ {"kvy", HB_TAG('K','R','N',' ')}, /* Yintale Karen -> Karen */
{"kw", HB_TAG('C','O','R',' ')}, /* Cornish */
+ {"kww", HB_TAG('C','P','P',' ')}, /* Kwinti -> Creoles */
{"kwy", HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */
{"kxc", HB_TAG('K','M','S',' ')}, /* Konso -> Komso */
{"kxd", HB_TAG('M','L','Y',' ')}, /* Brunei -> Malay */
+ {"kxf", HB_TAG('K','R','N',' ')}, /* Manumanaw Karen -> Karen */
+ {"kxk", HB_TAG('K','R','N',' ')}, /* Zayein Karen -> Karen */
{"kxl", HB_TAG('K','U','U',' ')}, /* Nepali Kurux (retired code) -> Kurukh */
{"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) (retired code) */
{"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz (Kyrgyz) */
-/*{"kyu", HB_TAG('K','Y','U',' ')},*/ /* Western Kayah */
+ {"kyk", HB_TAG_NONE }, /* Kamayo != Koryak */
+ {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */
+ {"kyu", HB_TAG('K','R','N',' ')}, /* Western Kayah -> Karen */
{"la", HB_TAG('L','A','T',' ')}, /* Latin */
+ {"lac", HB_TAG('M','Y','N',' ')}, /* Lacandon -> Mayan */
{"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
+ {"lah", HB_TAG_NONE }, /* Lahnda [macrolanguage] != Lahuli */
+ {"lak", HB_TAG_NONE }, /* Laka (Nigeria) != Lak */
+ {"lam", HB_TAG_NONE }, /* Lamba != Lambani */
+ {"laz", HB_TAG_NONE }, /* Aribwatsa != Laz */
{"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
{"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
{"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
@@ -554,85 +803,128 @@ static const LangTag ot_languages[] = {
{"lce", HB_TAG('M','L','Y',' ')}, /* Loncong -> Malay */
{"lcf", HB_TAG('M','L','Y',' ')}, /* Lubu -> Malay */
{"ldi", HB_TAG('K','O','N','0')}, /* Laari -> Kongo */
+ {"ldk", HB_TAG_NONE }, /* Leelau != Ladakhi */
/*{"lez", HB_TAG('L','E','Z',' ')},*/ /* Lezghian -> Lezgi */
{"lg", HB_TAG('L','U','G',' ')}, /* Ganda */
{"li", HB_TAG('L','I','M',' ')}, /* Limburgish */
{"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
/*{"lij", HB_TAG('L','I','J',' ')},*/ /* Ligurian */
+ {"lir", HB_TAG('C','P','P',' ')}, /* Liberian English -> Creoles */
/*{"lis", HB_TAG('L','I','S',' ')},*/ /* Lisu */
{"liw", HB_TAG('M','L','Y',' ')}, /* Col -> Malay */
+ {"liy", HB_TAG('B','A','D','0')}, /* Banda-Bambari -> Banda */
/*{"ljp", HB_TAG('L','J','P',' ')},*/ /* Lampung Api -> Lampung */
{"lkb", HB_TAG('L','U','H',' ')}, /* Kabras -> Luyia */
/*{"lki", HB_TAG('L','K','I',' ')},*/ /* Laki */
{"lko", HB_TAG('L','U','H',' ')}, /* Khayo -> Luyia */
{"lks", HB_TAG('L','U','H',' ')}, /* Kisa -> Luyia */
{"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
+ {"lma", HB_TAG_NONE }, /* East Limba != Low Mari */
+ {"lmb", HB_TAG_NONE }, /* Merei != Limbu */
{"lmn", HB_TAG('L','A','M',' ')}, /* Lambadi -> Lambani */
/*{"lmo", HB_TAG('L','M','O',' ')},*/ /* Lombard */
+ {"lmw", HB_TAG_NONE }, /* Lake Miwok != Lomwe */
{"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
+ {"lna", HB_TAG('B','A','D','0')}, /* Langbashe -> Banda */
+ {"lnl", HB_TAG('B','A','D','0')}, /* South Central Banda -> Banda */
{"lo", HB_TAG('L','A','O',' ')}, /* Lao */
/*{"lom", HB_TAG('L','O','M',' ')},*/ /* Loma (Liberia) */
+ {"lou", HB_TAG('C','P','P',' ')}, /* Louisiana Creole -> Creoles */
/*{"lrc", HB_TAG('L','R','C',' ')},*/ /* Northern Luri -> Luri */
{"lri", HB_TAG('L','U','H',' ')}, /* Marachi -> Luyia */
{"lrm", HB_TAG('L','U','H',' ')}, /* Marama -> Luyia */
+ {"lrt", HB_TAG('C','P','P',' ')}, /* Larantuka Malay -> Creoles */
{"lsm", HB_TAG('L','U','H',' ')}, /* Saamia -> Luyia */
{"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
{"ltg", HB_TAG('L','V','I',' ')}, /* Latgalian -> Latvian */
+ {"lth", HB_TAG_NONE }, /* Thur != Lithuanian */
{"lto", HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */
{"lts", HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */
{"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */
/*{"lua", HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */
/*{"luo", HB_TAG('L','U','O',' ')},*/ /* Luo (Kenya and Tanzania) */
{"lus", HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */
+ {"lus", HB_TAG('Q','I','N',' ')}, /* Lushai -> Chin */
{"luy", HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */
{"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */
{"lv", HB_TAG('L','V','I',' ')}, /* Latvian [macrolanguage] */
+ {"lvi", HB_TAG_NONE }, /* Lavi != Latvian */
{"lvs", HB_TAG('L','V','I',' ')}, /* Standard Latvian -> Latvian */
{"lwg", HB_TAG('L','U','H',' ')}, /* Wanga -> Luyia */
- {"lzh", HB_TAG('Z','H','T',' ')}, /* Literary Chinese -> Chinese Traditional */
+ {"lzh", HB_TAG('Z','H','T',' ')}, /* Literary Chinese -> Chinese, Traditional */
{"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
/*{"mad", HB_TAG('M','A','D',' ')},*/ /* Madurese -> Madura */
/*{"mag", HB_TAG('M','A','G',' ')},*/ /* Magahi */
{"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
+ {"maj", HB_TAG_NONE }, /* Jalapa De Díaz Mazatec != Majang */
{"mak", HB_TAG('M','K','R',' ')}, /* Makasar */
-/*{"mam", HB_TAG('M','A','M',' ')},*/ /* Mam */
+ {"mam", HB_TAG('M','A','M',' ')}, /* Mam */
+ {"mam", HB_TAG('M','Y','N',' ')}, /* Mam -> Mayan */
{"man", HB_TAG('M','N','K',' ')}, /* Mandingo [macrolanguage] -> Maninka */
+ {"map", HB_TAG_NONE }, /* Austronesian [family] != Mapudungun */
+ {"maw", HB_TAG_NONE }, /* Mampruli != Marwari */
{"max", HB_TAG('M','L','Y',' ')}, /* North Moluccan Malay -> Malay */
+ {"max", HB_TAG('C','P','P',' ')}, /* North Moluccan Malay -> Creoles */
+ {"mbf", HB_TAG('C','P','P',' ')}, /* Baba Malay -> Creoles */
+ {"mbn", HB_TAG_NONE }, /* Macaguán != Mbundu */
/*{"mbo", HB_TAG('M','B','O',' ')},*/ /* Mbo (Cameroon) */
+ {"mch", HB_TAG_NONE }, /* Maquiritari != Manchu */
+ {"mcm", HB_TAG('C','P','P',' ')}, /* Malaccan Creole Portuguese -> Creoles */
+ {"mcr", HB_TAG_NONE }, /* Menya != Moose Cree */
{"mct", HB_TAG('B','T','I',' ')}, /* Mengisa -> Beti */
+ {"mde", HB_TAG_NONE }, /* Maba (Chad) != Mende */
{"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
/*{"mdr", HB_TAG('M','D','R',' ')},*/ /* Mandar */
{"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
{"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
{"meo", HB_TAG('M','L','Y',' ')}, /* Kedah Malay -> Malay */
/*{"mer", HB_TAG('M','E','R',' ')},*/ /* Meru */
-/*{"mfa", HB_TAG('M','F','A',' ')},*/ /* Pattani Malay */
+ {"mfa", HB_TAG('M','F','A',' ')}, /* Pattani Malay */
+ {"mfa", HB_TAG('M','L','Y',' ')}, /* Pattani Malay -> Malay */
{"mfb", HB_TAG('M','L','Y',' ')}, /* Bangka -> Malay */
-/*{"mfe", HB_TAG('M','F','E',' ')},*/ /* Morisyen */
+ {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */
+ {"mfe", HB_TAG('C','P','P',' ')}, /* Morisyen -> Creoles */
+ {"mfp", HB_TAG('C','P','P',' ')}, /* Makassar Malay -> Creoles */
{"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */
{"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */
+ {"mhc", HB_TAG('M','Y','N',' ')}, /* Mocho -> Mayan */
{"mhr", HB_TAG('L','M','A',' ')}, /* Eastern Mari -> Low Mari */
{"mhv", HB_TAG('A','R','K',' ')}, /* Arakanese (retired code) -> Rakhine */
{"mi", HB_TAG('M','R','I',' ')}, /* Maori */
-/*{"min", HB_TAG('M','I','N',' ')},*/ /* Minangkabau */
+ {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */
+ {"min", HB_TAG('M','L','Y',' ')}, /* Minangkabau -> Malay */
+ {"miz", HB_TAG_NONE }, /* Coatzospan Mixtec != Mizo */
{"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
+ {"mkn", HB_TAG('C','P','P',' ')}, /* Kupang Malay -> Creoles */
+ {"mkr", HB_TAG_NONE }, /* Malas != Makasar */
{"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka -> Maninka */
/*{"mkw", HB_TAG('M','K','W',' ')},*/ /* Kituba (Congo) */
{"ml", HB_TAG('M','A','L',' ')}, /* Malayalam -> Malayalam Traditional */
{"ml", HB_TAG('M','L','R',' ')}, /* Malayalam -> Malayalam Reformed */
+ {"mle", HB_TAG_NONE }, /* Manambu != Male */
+ {"mln", HB_TAG_NONE }, /* Malango != Malinke */
{"mlq", HB_TAG('M','L','N',' ')}, /* Western Maninkakan -> Malinke */
{"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan -> Maninka */
+ {"mlr", HB_TAG_NONE }, /* Vame != Malayalam Reformed */
{"mmr", HB_TAG('H','M','N',' ')}, /* Western Xiangxi Miao -> Hmong */
{"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */
{"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
+ {"mnd", HB_TAG_NONE }, /* Mondé != Mandinka */
+ {"mng", HB_TAG_NONE }, /* Eastern Mnong != Mongolian */
+ {"mnh", HB_TAG('B','A','D','0')}, /* Mono (Democratic Republic of Congo) -> Banda */
/*{"mni", HB_TAG('M','N','I',' ')},*/ /* Manipuri */
{"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
{"mnk", HB_TAG('M','N','K',' ')}, /* Mandinka -> Maninka */
- {"mnp", HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese Simplified */
+ {"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 */
+ {"mnx", HB_TAG_NONE }, /* Manikion != Manx */
{"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */
+ {"mod", HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */
/*{"moh", HB_TAG('M','O','H',' ')},*/ /* Mohawk */
+ {"mok", HB_TAG_NONE }, /* Morori != Moksha */
+ {"mop", HB_TAG('M','Y','N',' ')}, /* Mopán Maya -> Mayan */
+ {"mor", HB_TAG_NONE }, /* Moro != Moroccan */
/*{"mos", HB_TAG('M','O','S',' ')},*/ /* Mossi */
{"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
{"mqg", HB_TAG('M','L','Y',' ')}, /* Kota Bangun Kutai Malay -> Malay */
@@ -643,9 +935,14 @@ static const LangTag ot_languages[] = {
{"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka -> Maninka */
{"msh", HB_TAG('M','L','G',' ')}, /* Masikoro Malagasy -> Malagasy */
{"msi", HB_TAG('M','L','Y',' ')}, /* Sabah Malay -> Malay */
+ {"msi", HB_TAG('C','P','P',' ')}, /* Sabah Malay -> Creoles */
{"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
+ {"mth", HB_TAG_NONE }, /* Munggui != Maithili */
{"mtr", HB_TAG('M','A','W',' ')}, /* Mewari -> Marwari */
+ {"mts", HB_TAG_NONE }, /* Yora != Maltese */
+ {"mud", HB_TAG('C','P','P',' ')}, /* Mednyj Aleut -> Creoles */
{"mui", HB_TAG('M','L','Y',' ')}, /* Musi -> Malay */
+ {"mun", HB_TAG_NONE }, /* Munda [family] != Mundari */
{"mup", HB_TAG('R','A','J',' ')}, /* Malvi -> Rajasthani */
{"muq", HB_TAG('H','M','N',' ')}, /* Eastern Xiangxi Miao -> Hmong */
/*{"mus", HB_TAG('M','U','S',' ')},*/ /* Creek -> Muscogee */
@@ -654,49 +951,101 @@ static const LangTag ot_languages[] = {
{"mvf", HB_TAG('M','N','G',' ')}, /* Peripheral Mongolian -> Mongolian */
{"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan -> Maninka */
/*{"mwl", HB_TAG('M','W','L',' ')},*/ /* Mirandese */
+ {"mwq", HB_TAG('Q','I','N',' ')}, /* Mün Chin -> Chin */
{"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */
-/*{"mww", HB_TAG('M','W','W',' ')},*/ /* Hmong Daw */
+ {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */
+ {"mww", HB_TAG('H','M','N',' ')}, /* Hmong Daw -> Hmong */
{"my", HB_TAG('B','R','M',' ')}, /* Burmese */
{"mym", HB_TAG('M','E','N',' ')}, /* Me’en */
/*{"myn", HB_TAG('M','Y','N',' ')},*/ /* Mayan [family] */
{"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) -> Maninka */
{"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
+ {"mzb", HB_TAG('B','B','R',' ')}, /* Tumzabt -> Berber */
/*{"mzn", HB_TAG('M','Z','N',' ')},*/ /* Mazanderani */
+ {"mzs", HB_TAG('C','P','P',' ')}, /* Macanese -> Creoles */
{"na", HB_TAG('N','A','U',' ')}, /* Nauru -> Nauruan */
-/*{"nag", HB_TAG('N','A','G',' ')},*/ /* Naga Pidgin -> Naga-Assamese */
+ {"nag", HB_TAG('N','A','G',' ')}, /* Naga Pidgin -> Naga-Assamese */
+ {"nag", HB_TAG('C','P','P',' ')}, /* Naga Pidgin -> Creoles */
/*{"nah", HB_TAG('N','A','H',' ')},*/ /* Nahuatl [family] */
- {"nan", HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese Simplified */
+ {"nan", HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese, Simplified */
/*{"nap", HB_TAG('N','A','P',' ')},*/ /* Neapolitan */
+ {"nas", HB_TAG_NONE }, /* Naasioi != Naskapi */
+ {"naz", HB_TAG('N','A','H',' ')}, /* Coatepec Nahuatl -> Nahuatl */
{"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål -> Norwegian */
+ {"nch", HB_TAG('N','A','H',' ')}, /* Central Huasteca Nahuatl -> Nahuatl */
+ {"nci", HB_TAG('N','A','H',' ')}, /* Classical Nahuatl -> Nahuatl */
+ {"ncj", HB_TAG('N','A','H',' ')}, /* Northern Puebla Nahuatl -> Nahuatl */
+ {"ncl", HB_TAG('N','A','H',' ')}, /* Michoacán Nahuatl -> Nahuatl */
+ {"ncr", HB_TAG_NONE }, /* Ncane != N-Cree */
+ {"ncx", HB_TAG('N','A','H',' ')}, /* Central Puebla Nahuatl -> Nahuatl */
{"nd", HB_TAG('N','D','B',' ')}, /* North Ndebele -> Ndebele */
+ {"ndb", HB_TAG_NONE }, /* Kenswei Nsei != Ndebele */
/*{"ndc", HB_TAG('N','D','C',' ')},*/ /* Ndau */
+ {"ndg", HB_TAG_NONE }, /* Ndengereko != Ndonga */
/*{"nds", HB_TAG('N','D','S',' ')},*/ /* Low Saxon */
{"ne", HB_TAG('N','E','P',' ')}, /* Nepali [macrolanguage] */
+ {"nef", HB_TAG('C','P','P',' ')}, /* Nefamese -> Creoles */
/*{"new", HB_TAG('N','E','W',' ')},*/ /* Newari */
{"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
/*{"nga", HB_TAG('N','G','A',' ')},*/ /* Ngbaka */
{"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
+ {"ngm", HB_TAG('C','P','P',' ')}, /* Ngatik Men's Creole -> Creoles */
{"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni -> Sutu */
+ {"ngr", HB_TAG_NONE }, /* Engdewu != Nagari */
+ {"ngu", HB_TAG('N','A','H',' ')}, /* Guerrero Nahuatl -> Nahuatl */
+ {"nhc", HB_TAG('N','A','H',' ')}, /* Tabasco Nahuatl -> Nahuatl */
{"nhd", HB_TAG('G','U','A',' ')}, /* Chiripá -> Guarani */
+ {"nhe", HB_TAG('N','A','H',' ')}, /* Eastern Huasteca Nahuatl -> Nahuatl */
+ {"nhg", HB_TAG('N','A','H',' ')}, /* Tetelcingo Nahuatl -> Nahuatl */
+ {"nhi", HB_TAG('N','A','H',' ')}, /* Zacatlán-Ahuacatlán-Tepetzintla Nahuatl -> Nahuatl */
+ {"nhk", HB_TAG('N','A','H',' ')}, /* Isthmus-Cosoleacaque Nahuatl -> Nahuatl */
+ {"nhm", HB_TAG('N','A','H',' ')}, /* Morelos Nahuatl -> Nahuatl */
+ {"nhn", HB_TAG('N','A','H',' ')}, /* Central Nahuatl -> Nahuatl */
+ {"nhp", HB_TAG('N','A','H',' ')}, /* Isthmus-Pajapan Nahuatl -> Nahuatl */
+ {"nhq", HB_TAG('N','A','H',' ')}, /* Huaxcaleca Nahuatl -> Nahuatl */
+ {"nht", HB_TAG('N','A','H',' ')}, /* Ometepec Nahuatl -> Nahuatl */
+ {"nhv", HB_TAG('N','A','H',' ')}, /* Temascaltepec Nahuatl -> Nahuatl */
+ {"nhw", HB_TAG('N','A','H',' ')}, /* Western Huasteca Nahuatl -> Nahuatl */
+ {"nhx", HB_TAG('N','A','H',' ')}, /* Isthmus-Mecayapan Nahuatl -> Nahuatl */
+ {"nhy", HB_TAG('N','A','H',' ')}, /* Northern Oaxaca Nahuatl -> Nahuatl */
+ {"nhz", HB_TAG('N','A','H',' ')}, /* Santa María La Alta Nahuatl -> Nahuatl */
{"niq", HB_TAG('K','A','L',' ')}, /* Nandi -> Kalenjin */
+ {"nis", HB_TAG_NONE }, /* Nimi != Nisi */
/*{"niu", HB_TAG('N','I','U',' ')},*/ /* Niuean */
{"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
+ {"njt", HB_TAG('C','P','P',' ')}, /* Ndyuka-Trio Pidgin -> Creoles */
{"njz", HB_TAG('N','I','S',' ')}, /* Nyishi -> Nisi */
+ {"nko", HB_TAG_NONE }, /* Nkonya != N’Ko */
+ {"nkx", HB_TAG('I','J','O',' ')}, /* Nkoroo -> Ijo */
{"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
+ {"nla", HB_TAG('B','M','L',' ')}, /* Ngombale -> Bamileke */
{"nle", HB_TAG('L','U','H',' ')}, /* East Nyala -> Luyia */
+ {"nln", HB_TAG('N','A','H',' ')}, /* Durango Nahuatl (retired code) -> Nahuatl */
+ {"nlv", HB_TAG('N','A','H',' ')}, /* Orizaba Nahuatl -> Nahuatl */
{"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */
+ {"nn", HB_TAG('N','O','R',' ')}, /* Norwegian Nynorsk -> Norwegian */
+ {"nnh", HB_TAG('B','M','L',' ')}, /* Ngiemboon -> Bamileke */
+ {"nnz", HB_TAG('B','M','L',' ')}, /* Nda'nda' -> Bamileke */
{"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */
{"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai -> Northern Tai */
/*{"noe", HB_TAG('N','O','E',' ')},*/ /* Nimadi */
/*{"nog", HB_TAG('N','O','G',' ')},*/ /* Nogai */
/*{"nov", HB_TAG('N','O','V',' ')},*/ /* Novial */
{"npi", HB_TAG('N','E','P',' ')}, /* Nepali */
+ {"npl", HB_TAG('N','A','H',' ')}, /* Southeastern Puebla Nahuatl -> Nahuatl */
{"nqo", HB_TAG('N','K','O',' ')}, /* N’Ko */
{"nr", HB_TAG('N','D','B',' ')}, /* South Ndebele -> Ndebele */
{"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
-/*{"nso", HB_TAG('N','S','O',' ')},*/ /* Pedi -> Sotho, Northern */
+ {"nsm", HB_TAG_NONE }, /* Sumi Naga != Northern Sami */
+/*{"nso", HB_TAG('N','S','O',' ')},*/ /* Northern Sotho */
+ {"nsu", HB_TAG('N','A','H',' ')}, /* Sierra Negra Nahuatl -> Nahuatl */
+ {"nto", HB_TAG_NONE }, /* Ntomba != Esperanto */
+ {"nue", HB_TAG('B','A','D','0')}, /* Ngundu -> Banda */
+ {"nuu", HB_TAG('B','A','D','0')}, /* Ngbundu -> Banda */
+ {"nuz", HB_TAG('N','A','H',' ')}, /* Tlamacazapa Nahuatl -> Nahuatl */
{"nv", HB_TAG('N','A','V',' ')}, /* Navajo */
{"nv", HB_TAG('A','T','H',' ')}, /* Navajo -> Athapaskan */
+ {"nwe", HB_TAG('B','M','L',' ')}, /* Ngwe -> Bamileke */
{"ny", HB_TAG('C','H','I',' ')}, /* Chichewa (Chewa, Nyanja) */
{"nyd", HB_TAG('L','U','H',' ')}, /* Nyore -> Luyia */
/*{"nym", HB_TAG('N','Y','M',' ')},*/ /* Nyamwezi */
@@ -708,21 +1057,33 @@ static const LangTag ot_languages[] = {
{"ojc", HB_TAG('O','J','B',' ')}, /* Central Ojibwa -> Ojibway */
{"ojg", HB_TAG('O','J','B',' ')}, /* Eastern Ojibwa -> Ojibway */
{"ojs", HB_TAG('O','C','R',' ')}, /* Severn Ojibwa -> Oji-Cree */
+ {"ojs", HB_TAG('O','J','B',' ')}, /* Severn Ojibwa -> Ojibway */
{"ojw", HB_TAG('O','J','B',' ')}, /* Western Ojibwa -> Ojibway */
+ {"okd", HB_TAG('I','J','O',' ')}, /* Okodia -> Ijo */
{"oki", HB_TAG('K','A','L',' ')}, /* Okiek -> Kalenjin */
{"okm", HB_TAG('K','O','H',' ')}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */
+ {"okr", HB_TAG('I','J','O',' ')}, /* Kirike -> Ijo */
{"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */
+ {"onx", HB_TAG('C','P','P',' ')}, /* Onin Based Pidgin -> Creoles */
+ {"oor", HB_TAG('C','P','P',' ')}, /* Oorlams -> Creoles */
{"or", HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) [macrolanguage] */
{"orc", HB_TAG('O','R','O',' ')}, /* Orma -> Oromo */
{"orn", HB_TAG('M','L','Y',' ')}, /* Orang Kanaq -> Malay */
+ {"oro", HB_TAG_NONE }, /* Orokolo != Oromo */
+ {"orr", HB_TAG('I','J','O',' ')}, /* Oruma -> Ijo */
{"ors", HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */
{"ory", HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) */
{"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
{"otw", HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */
+ {"oua", HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */
{"pa", HB_TAG('P','A','N',' ')}, /* Punjabi */
+ {"paa", HB_TAG_NONE }, /* Papuan [family] != Palestinian Aramaic */
/*{"pag", HB_TAG('P','A','G',' ')},*/ /* Pangasinan */
+ {"pal", HB_TAG_NONE }, /* Pahlavi != Pali */
/*{"pam", HB_TAG('P','A','M',' ')},*/ /* Pampanga -> Pampangan */
{"pap", HB_TAG('P','A','P','0')}, /* Papiamento -> Papiamentu */
+ {"pap", HB_TAG('C','P','P',' ')}, /* Papiamento -> Creoles */
+ {"pas", HB_TAG_NONE }, /* Papasena != Pashto */
/*{"pau", HB_TAG('P','A','U',' ')},*/ /* Palauan */
{"pbt", HB_TAG('P','A','S',' ')}, /* Southern Pashto -> Pashto */
{"pbu", HB_TAG('P','A','S',' ')}, /* Northern Pashto -> Pashto */
@@ -730,83 +1091,146 @@ static const LangTag ot_languages[] = {
/*{"pcd", HB_TAG('P','C','D',' ')},*/ /* Picard */
{"pce", HB_TAG('P','L','G',' ')}, /* Ruching Palaung -> Palaung */
{"pck", HB_TAG('Q','I','N',' ')}, /* Paite Chin -> Chin */
+ {"pcm", HB_TAG('C','P','P',' ')}, /* Nigerian Pidgin -> Creoles */
/*{"pdc", HB_TAG('P','D','C',' ')},*/ /* Pennsylvania German */
+ {"pdu", HB_TAG('K','R','N',' ')}, /* Kayan -> Karen */
+ {"pea", HB_TAG('C','P','P',' ')}, /* Peranakan Indonesian -> Creoles */
{"pel", HB_TAG('M','L','Y',' ')}, /* Pekal -> Malay */
{"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian -> Persian */
+ {"pey", HB_TAG('C','P','P',' ')}, /* Petjo -> Creoles */
{"pga", HB_TAG('A','R','A',' ')}, /* Sudanese Creole Arabic -> Arabic */
+ {"pga", HB_TAG('C','P','P',' ')}, /* Sudanese Creole Arabic -> Creoles */
/*{"phk", HB_TAG('P','H','K',' ')},*/ /* Phake */
{"pi", HB_TAG('P','A','L',' ')}, /* Pali */
-/*{"pih", HB_TAG('P','I','H',' ')},*/ /* Pitcairn-Norfolk -> Norfolk */
+ {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk -> Norfolk */
+ {"pih", HB_TAG('C','P','P',' ')}, /* Pitcairn-Norfolk -> Creoles */
+ {"pil", HB_TAG_NONE }, /* Yom != Filipino */
+ {"pis", HB_TAG('C','P','P',' ')}, /* Pijin -> Creoles */
+ {"pkh", HB_TAG('Q','I','N',' ')}, /* Pankhu -> Chin */
{"pko", HB_TAG('K','A','L',' ')}, /* Pökoot -> Kalenjin */
{"pl", HB_TAG('P','L','K',' ')}, /* Polish */
+ {"plg", HB_TAG_NONE }, /* Pilagá != Palaung */
+ {"plk", HB_TAG_NONE }, /* Kohistani Shina != Polish */
{"pll", HB_TAG('P','L','G',' ')}, /* Shwe Palaung -> Palaung */
+ {"pln", HB_TAG('C','P','P',' ')}, /* Palenquero -> Creoles */
{"plp", HB_TAG('P','A','P',' ')}, /* Palpa (retired code) */
{"plt", HB_TAG('M','L','G',' ')}, /* Plateau Malagasy -> Malagasy */
+ {"pml", HB_TAG('C','P','P',' ')}, /* Lingua Franca -> Creoles */
/*{"pms", HB_TAG('P','M','S',' ')},*/ /* Piemontese */
+ {"pmy", HB_TAG('C','P','P',' ')}, /* Papuan Malay -> Creoles */
/*{"pnb", HB_TAG('P','N','B',' ')},*/ /* Western Panjabi */
-/*{"poh", HB_TAG('P','O','H',' ')},*/ /* Poqomchi' -> Pocomchi */
+ {"poc", HB_TAG('M','Y','N',' ')}, /* Poqomam -> Mayan */
+ {"poh", HB_TAG('P','O','H',' ')}, /* Poqomchi' -> Pocomchi */
+ {"poh", HB_TAG('M','Y','N',' ')}, /* Poqomchi' -> Mayan */
/*{"pon", HB_TAG('P','O','N',' ')},*/ /* Pohnpeian */
+ {"pov", HB_TAG('C','P','P',' ')}, /* Upper Guinea Crioulo -> Creoles */
{"ppa", HB_TAG('B','A','G',' ')}, /* Pao (retired code) -> Baghelkhandi */
+ {"pre", HB_TAG('C','P','P',' ')}, /* Principense -> Creoles */
/*{"pro", HB_TAG('P','R','O',' ')},*/ /* Old Provençal (to 1500) -> Provençal / Old Provençal */
{"prs", HB_TAG('D','R','I',' ')}, /* Dari */
+ {"prs", HB_TAG('F','A','R',' ')}, /* Dari -> Persian */
{"ps", HB_TAG('P','A','S',' ')}, /* Pashto [macrolanguage] */
{"pse", HB_TAG('M','L','Y',' ')}, /* Central Malay -> Malay */
{"pst", HB_TAG('P','A','S',' ')}, /* Central Pashto -> Pashto */
{"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
-/*{"pwo", HB_TAG('P','W','O',' ')},*/ /* Pwo Western Karen -> Western Pwo Karen */
+ {"pub", HB_TAG('Q','I','N',' ')}, /* Purum -> Chin */
+ {"puz", HB_TAG('Q','I','N',' ')}, /* Purum Naga (retired code) -> Chin */
+ {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen -> Western Pwo Karen */
+ {"pwo", HB_TAG('K','R','N',' ')}, /* Pwo Western Karen -> Karen */
+ {"pww", HB_TAG('K','R','N',' ')}, /* Pwo Northern Karen -> Karen */
{"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */
{"qub", HB_TAG('Q','W','H',' ')}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */
-/*{"quc", HB_TAG('Q','U','C',' ')},*/ /* K’iche’ */
+ {"qub", HB_TAG('Q','U','Z',' ')}, /* Huallaga Huánuco Quechua -> Quechua */
+ {"quc", HB_TAG('Q','U','C',' ')}, /* K’iche’ */
+ {"quc", HB_TAG('M','Y','N',' ')}, /* K'iche' -> Mayan */
{"qud", HB_TAG('Q','V','I',' ')}, /* Calderón Highland Quichua -> Quechua (Ecuador) */
+ {"qud", HB_TAG('Q','U','Z',' ')}, /* Calderón Highland Quichua -> Quechua */
{"quf", HB_TAG('Q','U','Z',' ')}, /* Lambayeque Quechua -> Quechua */
{"qug", HB_TAG('Q','V','I',' ')}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */
-/*{"quh", HB_TAG('Q','U','H',' ')},*/ /* South Bolivian Quechua -> Quechua (Bolivia) */
+ {"qug", HB_TAG('Q','U','Z',' ')}, /* Chimborazo Highland Quichua -> Quechua */
+ {"quh", HB_TAG('Q','U','H',' ')}, /* South Bolivian Quechua -> Quechua (Bolivia) */
+ {"quh", HB_TAG('Q','U','Z',' ')}, /* South Bolivian Quechua -> Quechua */
{"quk", HB_TAG('Q','U','Z',' ')}, /* Chachapoyas Quechua -> Quechua */
+ {"qul", HB_TAG('Q','U','H',' ')}, /* North Bolivian Quechua -> Quechua (Bolivia) */
{"qul", HB_TAG('Q','U','Z',' ')}, /* North Bolivian Quechua -> Quechua */
+ {"qum", HB_TAG('M','Y','N',' ')}, /* Sipacapense -> Mayan */
{"qup", HB_TAG('Q','V','I',' ')}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */
+ {"qup", HB_TAG('Q','U','Z',' ')}, /* Southern Pastaza Quechua -> Quechua */
{"qur", HB_TAG('Q','W','H',' ')}, /* Yanahuanca Pasco Quechua -> Quechua (Peru) */
+ {"qur", HB_TAG('Q','U','Z',' ')}, /* Yanahuanca Pasco Quechua -> Quechua */
{"qus", HB_TAG('Q','U','H',' ')}, /* Santiago del Estero Quichua -> Quechua (Bolivia) */
+ {"qus", HB_TAG('Q','U','Z',' ')}, /* Santiago del Estero Quichua -> Quechua */
+ {"quv", HB_TAG('M','Y','N',' ')}, /* Sacapulteco -> Mayan */
{"quw", HB_TAG('Q','V','I',' ')}, /* Tena Lowland Quichua -> Quechua (Ecuador) */
+ {"quw", HB_TAG('Q','U','Z',' ')}, /* Tena Lowland Quichua -> Quechua */
{"qux", HB_TAG('Q','W','H',' ')}, /* Yauyos Quechua -> Quechua (Peru) */
+ {"qux", HB_TAG('Q','U','Z',' ')}, /* Yauyos Quechua -> Quechua */
{"quy", HB_TAG('Q','U','Z',' ')}, /* Ayacucho Quechua -> Quechua */
/*{"quz", HB_TAG('Q','U','Z',' ')},*/ /* Cusco Quechua -> Quechua */
{"qva", HB_TAG('Q','W','H',' ')}, /* Ambo-Pasco Quechua -> Quechua (Peru) */
+ {"qva", HB_TAG('Q','U','Z',' ')}, /* Ambo-Pasco Quechua -> Quechua */
{"qvc", HB_TAG('Q','U','Z',' ')}, /* Cajamarca Quechua -> Quechua */
{"qve", HB_TAG('Q','U','Z',' ')}, /* Eastern Apurímac Quechua -> Quechua */
{"qvh", HB_TAG('Q','W','H',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */
-/*{"qvi", HB_TAG('Q','V','I',' ')},*/ /* Imbabura Highland Quichua -> Quechua (Ecuador) */
+ {"qvh", HB_TAG('Q','U','Z',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua */
+ {"qvi", HB_TAG('Q','V','I',' ')}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */
+ {"qvi", HB_TAG('Q','U','Z',' ')}, /* Imbabura Highland Quichua -> Quechua */
{"qvj", HB_TAG('Q','V','I',' ')}, /* Loja Highland Quichua -> Quechua (Ecuador) */
+ {"qvj", HB_TAG('Q','U','Z',' ')}, /* Loja Highland Quichua -> Quechua */
{"qvl", HB_TAG('Q','W','H',' ')}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */
+ {"qvl", HB_TAG('Q','U','Z',' ')}, /* Cajatambo North Lima Quechua -> Quechua */
{"qvm", HB_TAG('Q','W','H',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */
+ {"qvm", HB_TAG('Q','U','Z',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua */
{"qvn", HB_TAG('Q','W','H',' ')}, /* North Junín Quechua -> Quechua (Peru) */
+ {"qvn", HB_TAG('Q','U','Z',' ')}, /* North Junín Quechua -> Quechua */
{"qvo", HB_TAG('Q','V','I',' ')}, /* Napo Lowland Quechua -> Quechua (Ecuador) */
+ {"qvo", HB_TAG('Q','U','Z',' ')}, /* Napo Lowland Quechua -> Quechua */
{"qvp", HB_TAG('Q','W','H',' ')}, /* Pacaraos Quechua -> Quechua (Peru) */
+ {"qvp", HB_TAG('Q','U','Z',' ')}, /* Pacaraos Quechua -> Quechua */
{"qvs", HB_TAG('Q','U','Z',' ')}, /* San Martín Quechua -> Quechua */
{"qvw", HB_TAG('Q','W','H',' ')}, /* Huaylla Wanca Quechua -> Quechua (Peru) */
+ {"qvw", HB_TAG('Q','U','Z',' ')}, /* Huaylla Wanca Quechua -> Quechua */
{"qvz", HB_TAG('Q','V','I',' ')}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */
+ {"qvz", HB_TAG('Q','U','Z',' ')}, /* Northern Pastaza Quichua -> Quechua */
{"qwa", HB_TAG('Q','W','H',' ')}, /* Corongo Ancash Quechua -> Quechua (Peru) */
+ {"qwa", HB_TAG('Q','U','Z',' ')}, /* Corongo Ancash Quechua -> Quechua */
{"qwc", HB_TAG('Q','U','Z',' ')}, /* Classical Quechua -> Quechua */
-/*{"qwh", HB_TAG('Q','W','H',' ')},*/ /* Huaylas Ancash Quechua -> Quechua (Peru) */
+ {"qwh", HB_TAG('Q','W','H',' ')}, /* Huaylas Ancash Quechua -> Quechua (Peru) */
+ {"qwh", HB_TAG('Q','U','Z',' ')}, /* Huaylas Ancash Quechua -> Quechua */
{"qws", HB_TAG('Q','W','H',' ')}, /* Sihuas Ancash Quechua -> Quechua (Peru) */
+ {"qws", HB_TAG('Q','U','Z',' ')}, /* Sihuas Ancash Quechua -> Quechua */
+ {"qwt", HB_TAG('A','T','H',' ')}, /* Kwalhioqua-Tlatskanai -> Athapaskan */
{"qxa", HB_TAG('Q','W','H',' ')}, /* Chiquián Ancash Quechua -> Quechua (Peru) */
+ {"qxa", HB_TAG('Q','U','Z',' ')}, /* Chiquián Ancash Quechua -> Quechua */
{"qxc", HB_TAG('Q','W','H',' ')}, /* Chincha Quechua -> Quechua (Peru) */
+ {"qxc", HB_TAG('Q','U','Z',' ')}, /* Chincha Quechua -> Quechua */
{"qxh", HB_TAG('Q','W','H',' ')}, /* Panao Huánuco Quechua -> Quechua (Peru) */
+ {"qxh", HB_TAG('Q','U','Z',' ')}, /* Panao Huánuco Quechua -> Quechua */
{"qxl", HB_TAG('Q','V','I',' ')}, /* Salasaca Highland Quichua -> Quechua (Ecuador) */
+ {"qxl", HB_TAG('Q','U','Z',' ')}, /* Salasaca Highland Quichua -> Quechua */
{"qxn", HB_TAG('Q','W','H',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */
+ {"qxn", HB_TAG('Q','U','Z',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua */
{"qxo", HB_TAG('Q','W','H',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */
+ {"qxo", HB_TAG('Q','U','Z',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua */
{"qxp", HB_TAG('Q','U','Z',' ')}, /* Puno Quechua -> Quechua */
{"qxr", HB_TAG('Q','V','I',' ')}, /* Cañar Highland Quichua -> Quechua (Ecuador) */
+ {"qxr", HB_TAG('Q','U','Z',' ')}, /* Cañar Highland Quichua -> Quechua */
{"qxt", HB_TAG('Q','W','H',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */
+ {"qxt", HB_TAG('Q','U','Z',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua */
{"qxu", HB_TAG('Q','U','Z',' ')}, /* Arequipa-La Unión Quechua -> Quechua */
{"qxw", HB_TAG('Q','W','H',' ')}, /* Jauja Wanca Quechua -> Quechua (Peru) */
+ {"qxw", HB_TAG('Q','U','Z',' ')}, /* Jauja Wanca Quechua -> Quechua */
{"rag", HB_TAG('L','U','H',' ')}, /* Logooli -> Luyia */
/*{"raj", HB_TAG('R','A','J',' ')},*/ /* Rajasthani [macrolanguage] */
+ {"ral", HB_TAG('Q','I','N',' ')}, /* Ralte -> Chin */
/*{"rar", HB_TAG('R','A','R',' ')},*/ /* Rarotongan */
{"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung -> Palaung */
{"rbl", HB_TAG('B','I','K',' ')}, /* Miraya Bikol -> Bikol */
+ {"rcf", HB_TAG('C','P','P',' ')}, /* Réunion Creole French -> Creoles */
/*{"rej", HB_TAG('R','E','J',' ')},*/ /* Rejang */
/*{"ria", HB_TAG('R','I','A',' ')},*/ /* Riang (India) */
-/*{"rif", HB_TAG('R','I','F',' ')},*/ /* Tarifit */
+ {"rif", HB_TAG('R','I','F',' ')}, /* Tarifit */
+ {"rif", HB_TAG('B','B','R',' ')}, /* Tarifit -> Berber */
/*{"rit", HB_TAG('R','I','T',' ')},*/ /* Ritharrngu -> Ritarungo */
{"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */
/*{"rkw", HB_TAG('R','K','W',' ')},*/ /* Arakwal */
@@ -816,13 +1240,16 @@ static const LangTag ot_languages[] = {
{"rml", HB_TAG('R','O','Y',' ')}, /* Baltic Romani -> Romany */
{"rmn", HB_TAG('R','O','Y',' ')}, /* Balkan Romani -> Romany */
{"rmo", HB_TAG('R','O','Y',' ')}, /* Sinte Romani -> Romany */
+ {"rms", HB_TAG_NONE }, /* Romanian Sign Language != Romansh */
{"rmw", HB_TAG('R','O','Y',' ')}, /* Welsh Romani -> Romany */
-/*{"rmy", HB_TAG('R','M','Y',' ')},*/ /* Vlax Romani */
+ {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */
+ {"rmy", HB_TAG('R','O','Y',' ')}, /* Vlax Romani -> Romany */
{"rmz", HB_TAG('A','R','K',' ')}, /* Marma -> Rakhine */
{"rn", HB_TAG('R','U','N',' ')}, /* Rundi */
- {"rnl", HB_TAG('H','A','L',' ')}, /* Ranglong -> Halam (Falam Chin) */
{"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
{"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */
+ {"rop", HB_TAG('C','P','P',' ')}, /* Kriol -> Creoles */
+ {"rtc", HB_TAG('Q','I','N',' ')}, /* Rungtu Chin -> Chin */
/*{"rtm", HB_TAG('R','T','M',' ')},*/ /* Rotuman */
{"ru", HB_TAG('R','U','S',' ')}, /* Russian */
{"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
@@ -830,11 +1257,16 @@ static const LangTag ot_languages[] = {
{"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */
{"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */
{"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
+ {"sad", HB_TAG_NONE }, /* Sandawe != Sadri */
{"sah", HB_TAG('Y','A','K',' ')}, /* Yakut -> Sakha */
{"sam", HB_TAG('P','A','A',' ')}, /* Samaritan Aramaic -> Palestinian Aramaic */
/*{"sas", HB_TAG('S','A','S',' ')},*/ /* Sasak */
/*{"sat", HB_TAG('S','A','T',' ')},*/ /* Santali */
+ {"say", HB_TAG_NONE }, /* Saya != Sayisi */
{"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */
+ {"scf", HB_TAG('C','P','P',' ')}, /* San Miguel Creole French -> Creoles */
+ {"sch", HB_TAG('Q','I','N',' ')}, /* Sakachep -> Chin */
+ {"sci", HB_TAG('C','P','P',' ')}, /* Sri Lankan Creole Malay -> Creoles */
{"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
/*{"scn", HB_TAG('S','C','N',' ')},*/ /* Sicilian */
/*{"sco", HB_TAG('S','C','O',' ')},*/ /* Scots */
@@ -845,6 +1277,7 @@ static const LangTag ot_languages[] = {
{"sdc", HB_TAG('S','R','D',' ')}, /* Sassarese Sardinian -> Sardinian */
{"sdh", HB_TAG('K','U','R',' ')}, /* Southern Kurdish -> Kurdish */
{"sdn", HB_TAG('S','R','D',' ')}, /* Gallurese Sardinian -> Sardinian */
+ {"sds", HB_TAG('B','B','R',' ')}, /* Sened -> Berber */
{"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
{"seh", HB_TAG('S','N','A',' ')}, /* Sena */
{"sek", HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */
@@ -854,51 +1287,78 @@ static const LangTag ot_languages[] = {
{"sg", HB_TAG('S','G','O',' ')}, /* Sango */
/*{"sga", HB_TAG('S','G','A',' ')},*/ /* Old Irish (to 900) */
{"sgc", HB_TAG('K','A','L',' ')}, /* Kipsigis -> Kalenjin */
+ {"sgo", HB_TAG_NONE }, /* Songa (retired code) != Sango */
/*{"sgs", HB_TAG('S','G','S',' ')},*/ /* Samogitian */
{"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage -> Chaha Gurage */
- {"sgw", HB_TAG('S','G','W',' ')}, /* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */
-/*{"shi", HB_TAG('S','H','I',' ')},*/ /* Tachelhit */
+ {"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */
+ {"shi", HB_TAG('B','B','R',' ')}, /* Tachelhit -> Berber */
+ {"shl", HB_TAG('Q','I','N',' ')}, /* Shendu -> Chin */
/*{"shn", HB_TAG('S','H','N',' ')},*/ /* Shan */
{"shu", HB_TAG('A','R','A',' ')}, /* Chadian Arabic -> Arabic */
+ {"shy", HB_TAG('B','B','R',' ')}, /* Tachawit -> Berber */
{"si", HB_TAG('S','N','H',' ')}, /* Sinhala (Sinhalese) */
+ {"sib", HB_TAG_NONE }, /* Sebop != Sibe */
/*{"sid", HB_TAG('S','I','D',' ')},*/ /* Sidamo */
+ {"sig", HB_TAG_NONE }, /* Paasaal != Silte Gurage */
+ {"siz", HB_TAG('B','B','R',' ')}, /* Siwi -> Berber */
{"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */
{"sjo", HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */
+ {"sjs", HB_TAG('B','B','R',' ')}, /* Senhaja De Srair -> Berber */
{"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */
{"skg", HB_TAG('M','L','G',' ')}, /* Sakalava Malagasy -> Malagasy */
{"skr", HB_TAG('S','R','K',' ')}, /* Saraiki */
+ {"sks", HB_TAG_NONE }, /* Maia != Skolt Sami */
+ {"skw", HB_TAG('C','P','P',' ')}, /* Skepi Creole Dutch -> Creoles */
+ {"sky", HB_TAG_NONE }, /* Sikaiana != Slovak */
{"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */
+ {"sla", HB_TAG_NONE }, /* Slavic [family] != Slavey */
{"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
{"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
{"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
+ {"sml", HB_TAG_NONE }, /* Central Sama != Somali */
{"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
{"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
+ {"smt", HB_TAG('Q','I','N',' ')}, /* Simte -> Chin */
{"sn", HB_TAG('S','N','A','0')}, /* Shona */
+ {"snh", HB_TAG_NONE }, /* Shinabo (retired code) != Sinhala (Sinhalese) */
/*{"snk", HB_TAG('S','N','K',' ')},*/ /* Soninke */
{"so", HB_TAG('S','M','L',' ')}, /* Somali */
+ {"sog", HB_TAG_NONE }, /* Sogdian != Sodo Gurage */
/*{"sop", HB_TAG('S','O','P',' ')},*/ /* Songe */
{"spv", HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */
{"spy", HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */
{"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */
{"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
+ {"srb", HB_TAG_NONE }, /* Sora != Serbian */
{"src", HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */
+ {"srk", HB_TAG_NONE }, /* Serudung Murut != Saraiki */
+ {"srm", HB_TAG('C','P','P',' ')}, /* Saramaccan -> Creoles */
+ {"srn", HB_TAG('C','P','P',' ')}, /* Sranan Tongo -> Creoles */
{"sro", HB_TAG('S','R','D',' ')}, /* Campidanese Sardinian -> Sardinian */
/*{"srr", HB_TAG('S','R','R',' ')},*/ /* Serer */
{"srs", HB_TAG('A','T','H',' ')}, /* Sarsi -> Athapaskan */
{"ss", HB_TAG('S','W','Z',' ')}, /* Swati */
{"ssh", HB_TAG('A','R','A',' ')}, /* Shihhi Arabic -> Arabic */
- {"st", HB_TAG('S','O','T',' ')}, /* Southern Sotho -> Sotho, Southern */
+ {"ssl", HB_TAG_NONE }, /* Western Sisaala != South Slavey */
+ {"ssm", HB_TAG_NONE }, /* Semnam != Southern Sami */
+ {"st", HB_TAG('S','O','T',' ')}, /* Southern Sotho */
+ {"sta", HB_TAG('C','P','P',' ')}, /* Settla -> Creoles */
/*{"stq", HB_TAG('S','T','Q',' ')},*/ /* Saterfriesisch -> Saterland Frisian */
{"stv", HB_TAG('S','I','G',' ')}, /* Silt'e -> Silte Gurage */
{"su", HB_TAG('S','U','N',' ')}, /* Sundanese */
/*{"suk", HB_TAG('S','U','K',' ')},*/ /* Sukuma */
{"suq", HB_TAG('S','U','R',' ')}, /* Suri */
+ {"sur", HB_TAG_NONE }, /* Mwaghavul != Suri */
{"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
/*{"sva", HB_TAG('S','V','A',' ')},*/ /* Svan */
+ {"svc", HB_TAG('C','P','P',' ')}, /* Vincentian Creole English -> Creoles */
+ {"sve", HB_TAG_NONE }, /* Serili != Swedish */
{"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */
{"swb", HB_TAG('C','M','R',' ')}, /* Maore Comorian -> Comorian */
{"swc", HB_TAG('S','W','K',' ')}, /* Congo Swahili -> Swahili */
{"swh", HB_TAG('S','W','K',' ')}, /* Swahili */
+ {"swk", HB_TAG_NONE }, /* Malawi Sena != Swahili */
+ {"swn", HB_TAG('B','B','R',' ')}, /* Sawknah -> Berber */
{"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati -> Marwari */
/*{"sxu", HB_TAG('S','X','U',' ')},*/ /* Upper Saxon */
{"syc", HB_TAG('S','Y','R',' ')}, /* Classical Syriac -> Syriac */
@@ -908,11 +1368,16 @@ static const LangTag ot_languages[] = {
{"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
{"taa", HB_TAG('A','T','H',' ')}, /* Lower Tanana -> Athapaskan */
/*{"tab", HB_TAG('T','A','B',' ')},*/ /* Tabassaran -> Tabasaran */
+ {"taj", HB_TAG_NONE }, /* Eastern Tamang != Tajiki */
{"taq", HB_TAG('T','M','H',' ')}, /* Tamasheq -> Tamashek */
+ {"taq", HB_TAG('B','B','R',' ')}, /* Tamasheq -> Berber */
+ {"tas", HB_TAG('C','P','P',' ')}, /* Tay Boi -> Creoles */
{"tau", HB_TAG('A','T','H',' ')}, /* Upper Tanana -> Athapaskan */
{"tcb", HB_TAG('A','T','H',' ')}, /* Tanacross -> Athapaskan */
{"tce", HB_TAG('A','T','H',' ')}, /* Southern Tutchone -> Athapaskan */
+ {"tch", HB_TAG('C','P','P',' ')}, /* Turks And Caicos Creole English -> Creoles */
{"tcp", HB_TAG('Q','I','N',' ')}, /* Tawr Chin -> Chin */
+ {"tcs", HB_TAG('C','P','P',' ')}, /* Torres Strait Creole -> Creoles */
{"tcy", HB_TAG('T','U','L',' ')}, /* Tulu -> Tumbuka */
{"tcz", HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */
/*{"tdd", HB_TAG('T','D','D',' ')},*/ /* Tai Nüa -> Dehong Dai */
@@ -921,41 +1386,70 @@ static const LangTag ot_languages[] = {
{"tec", HB_TAG('K','A','L',' ')}, /* Terik -> Kalenjin */
{"tem", HB_TAG('T','M','N',' ')}, /* Timne -> Temne */
/*{"tet", HB_TAG('T','E','T',' ')},*/ /* Tetum */
+ {"tez", HB_TAG('B','B','R',' ')}, /* Tetserret -> Berber */
{"tfn", HB_TAG('A','T','H',' ')}, /* Tanaina -> Athapaskan */
{"tg", HB_TAG('T','A','J',' ')}, /* Tajik -> Tajiki */
+ {"tgh", HB_TAG('C','P','P',' ')}, /* Tobagonian Creole English -> Creoles */
{"tgj", HB_TAG('N','I','S',' ')}, /* Tagin -> Nisi */
+ {"tgn", HB_TAG_NONE }, /* Tandaganon != Tongan */
+ {"tgr", HB_TAG_NONE }, /* Tareng != Tigre */
{"tgx", HB_TAG('A','T','H',' ')}, /* Tagish -> Athapaskan */
+ {"tgy", HB_TAG_NONE }, /* Togoyo != Tigrinya */
{"th", HB_TAG('T','H','A',' ')}, /* Thai */
{"tht", HB_TAG('A','T','H',' ')}, /* Tahltan -> Athapaskan */
{"thv", HB_TAG('T','M','H',' ')}, /* Tahaggart Tamahaq -> Tamashek */
+ {"thv", HB_TAG('B','B','R',' ')}, /* Tahaggart Tamahaq -> Berber */
{"thz", HB_TAG('T','M','H',' ')}, /* Tayart Tamajeq -> Tamashek */
+ {"thz", HB_TAG('B','B','R',' ')}, /* Tayart Tamajeq -> Berber */
{"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
+ {"tia", HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */
{"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
/*{"tiv", HB_TAG('T','I','V',' ')},*/ /* Tiv */
+ {"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 */
+ {"tkm", HB_TAG_NONE }, /* Takelma != Turkmen */
{"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */
-/*{"tmh", HB_TAG('T','M','H',' ')},*/ /* Tamashek [macrolanguage] */
+ {"tmg", HB_TAG('C','P','P',' ')}, /* Ternateño -> Creoles */
+ {"tmh", HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */
+ {"tmh", HB_TAG('B','B','R',' ')}, /* Tamashek [macrolanguage] -> Berber */
+ {"tmn", HB_TAG_NONE }, /* Taman (Indonesia) != Temne */
{"tmw", HB_TAG('M','L','Y',' ')}, /* Temuan -> Malay */
{"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
+ {"tna", HB_TAG_NONE }, /* Tacana != Tswana */
+ {"tne", HB_TAG_NONE }, /* Tinoc Kallahan (retired code) != Tundra Enets */
{"tnf", HB_TAG('D','R','I',' ')}, /* Tangshewi (retired code) -> Dari */
+ {"tnf", HB_TAG('F','A','R',' ')}, /* Tangshewi (retired code) -> Persian */
+ {"tng", HB_TAG_NONE }, /* Tobanga != Tonga */
{"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) -> Tongan */
{"tod", HB_TAG('T','O','D','0')}, /* Toma */
{"toi", HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */
+ {"toj", HB_TAG('M','Y','N',' ')}, /* Tojolabal -> Mayan */
{"tol", HB_TAG('A','T','H',' ')}, /* Tolowa -> Athapaskan */
-/*{"tpi", HB_TAG('T','P','I',' ')},*/ /* Tok Pisin */
+ {"tor", HB_TAG('B','A','D','0')}, /* Togbo-Vara Banda -> Banda */
+ {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */
+ {"tpi", HB_TAG('C','P','P',' ')}, /* Tok Pisin -> Creoles */
{"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
+ {"trf", HB_TAG('C','P','P',' ')}, /* Trinidadian Creole English -> Creoles */
+ {"trk", HB_TAG_NONE }, /* Turkic [family] != Turkish */
{"tru", HB_TAG('T','U','A',' ')}, /* Turoyo -> Turoyo Aramaic */
{"tru", HB_TAG('S','Y','R',' ')}, /* Turoyo -> Syriac */
{"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
+ {"tsg", HB_TAG_NONE }, /* Tausug != Tsonga */
/*{"tsj", HB_TAG('T','S','J',' ')},*/ /* Tshangla */
{"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
+ {"ttc", HB_TAG('M','Y','N',' ')}, /* Tektiteko -> Mayan */
{"ttm", HB_TAG('A','T','H',' ')}, /* Northern Tutchone -> Athapaskan */
{"ttq", HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */
+ {"ttq", HB_TAG('B','B','R',' ')}, /* Tawallammat Tamajaq -> Berber */
+ {"tua", HB_TAG_NONE }, /* Wiarumus != Turoyo Aramaic */
+ {"tul", HB_TAG_NONE }, /* Tula != Tumbuka */
/*{"tum", HB_TAG('T','U','M',' ')},*/ /* Tumbuka -> Tulu */
{"tuu", HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */
+ {"tuv", HB_TAG_NONE }, /* Turkana != Tuvin */
{"tuy", HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */
/*{"tvl", HB_TAG('T','V','L',' ')},*/ /* Tuvalu */
+ {"tvy", HB_TAG('C','P','P',' ')}, /* Timor Pidgin -> Creoles */
{"tw", HB_TAG('T','W','I',' ')}, /* Twi */
{"tw", HB_TAG('A','K','A',' ')}, /* Twi -> Akan */
{"txc", HB_TAG('A','T','H',' ')}, /* Tsetsaut -> Athapaskan */
@@ -963,33 +1457,48 @@ static const LangTag ot_languages[] = {
{"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
{"tyv", HB_TAG('T','U','V',' ')}, /* Tuvinian -> Tuvin */
/*{"tyz", HB_TAG('T','Y','Z',' ')},*/ /* Tày */
-/*{"tzm", HB_TAG('T','Z','M',' ')},*/ /* Central Atlas Tamazight -> Tamazight */
-/*{"tzo", HB_TAG('T','Z','O',' ')},*/ /* Tzotzil */
+ {"tzh", HB_TAG('M','Y','N',' ')}, /* Tzeltal -> Mayan */
+ {"tzj", HB_TAG('M','Y','N',' ')}, /* Tz'utujil -> Mayan */
+ {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight -> Tamazight */
+ {"tzm", HB_TAG('B','B','R',' ')}, /* Central Atlas Tamazight -> Berber */
+ {"tzo", HB_TAG('T','Z','O',' ')}, /* Tzotzil */
+ {"tzo", HB_TAG('M','Y','N',' ')}, /* Tzotzil -> Mayan */
{"ubl", HB_TAG('B','I','K',' ')}, /* Buhi'non Bikol -> Bikol */
/*{"udm", HB_TAG('U','D','M',' ')},*/ /* Udmurt */
{"ug", HB_TAG('U','Y','G',' ')}, /* Uyghur */
{"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
{"uki", HB_TAG('K','U','I',' ')}, /* Kui (India) */
+ {"uln", HB_TAG('C','P','P',' ')}, /* Unserdeutsch -> Creoles */
/*{"umb", HB_TAG('U','M','B',' ')},*/ /* Umbundu */
{"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
{"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
{"urk", HB_TAG('M','L','Y',' ')}, /* Urak Lawoi' -> Malay */
+ {"usp", HB_TAG('M','Y','N',' ')}, /* Uspanteco -> Mayan */
{"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */
{"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek -> Uzbek */
{"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek -> Uzbek */
+ {"vap", HB_TAG('Q','I','N',' ')}, /* Vaiphei -> Chin */
{"ve", HB_TAG('V','E','N',' ')}, /* Venda */
/*{"vec", HB_TAG('V','E','C',' ')},*/ /* Venetian */
{"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
+ {"vic", HB_TAG('C','P','P',' ')}, /* Virgin Islands Creole English -> Creoles */
+ {"vit", HB_TAG_NONE }, /* Viti != Vietnamese */
{"vkk", HB_TAG('M','L','Y',' ')}, /* Kaur -> Malay */
+ {"vkp", HB_TAG('C','P','P',' ')}, /* Korlai Creole Portuguese -> Creoles */
{"vkt", HB_TAG('M','L','Y',' ')}, /* Tenggarong Kutai Malay -> Malay */
{"vls", HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */
{"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */
{"vo", HB_TAG('V','O','L',' ')}, /* Volapük */
/*{"vro", HB_TAG('V','R','O',' ')},*/ /* Võro */
{"wa", HB_TAG('W','L','N',' ')}, /* Walloon */
+ {"wag", HB_TAG_NONE }, /* Wa'ema != Wagdi */
/*{"war", HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */
{"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
{"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
+ {"wbr", HB_TAG('R','A','J',' ')}, /* Wagdi -> Rajasthani */
+ {"wea", HB_TAG('K','R','N',' ')}, /* Wewaw -> Karen */
+ {"wes", HB_TAG('C','P','P',' ')}, /* Cameroon Pidgin -> Creoles */
+ {"weu", HB_TAG('Q','I','N',' ')}, /* Rawngtu Chin -> Chin */
{"wlc", HB_TAG('C','M','R',' ')}, /* Mwali Comorian -> Comorian */
{"wle", HB_TAG('S','I','G',' ')}, /* Wolane -> Silte Gurage */
{"wlk", HB_TAG('A','T','H',' ')}, /* Wailaki -> Athapaskan */
@@ -998,45 +1507,56 @@ static const LangTag ot_languages[] = {
{"wry", HB_TAG('M','A','W',' ')}, /* Merwari -> Marwari */
{"wsg", HB_TAG('G','O','N',' ')}, /* Adilabad Gondi -> Gondi */
/*{"wtm", HB_TAG('W','T','M',' ')},*/ /* Mewati */
- {"wuu", HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese Simplified */
+ {"wuu", HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese, Simplified */
{"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
{"xal", HB_TAG('T','O','D',' ')}, /* Kalmyk -> Todo */
{"xan", HB_TAG('S','E','K',' ')}, /* Xamtanga -> Sekota */
+ {"xbd", HB_TAG_NONE }, /* Bindal != Lü */
{"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
/*{"xjb", HB_TAG('X','J','B',' ')},*/ /* Minjungbal -> Minjangbal */
/*{"xkf", HB_TAG('X','K','F',' ')},*/ /* Khengkha */
+ {"xmg", HB_TAG('B','M','L',' ')}, /* Mengaka -> Bamileke */
{"xmm", HB_TAG('M','L','Y',' ')}, /* Manado Malay -> Malay */
+ {"xmm", HB_TAG('C','P','P',' ')}, /* Manado Malay -> Creoles */
{"xmv", HB_TAG('M','L','G',' ')}, /* Antankarana Malagasy -> Malagasy */
{"xmw", HB_TAG('M','L','G',' ')}, /* Tsimihety Malagasy -> Malagasy */
- {"xnr", HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri */
+ {"xnr", HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri (macrolanguage) */
/*{"xog", HB_TAG('X','O','G',' ')},*/ /* Soga */
-/*{"xpe", HB_TAG('X','P','E',' ')},*/ /* Liberia Kpelle -> Kpelle (Liberia) */
+ {"xpe", HB_TAG('X','P','E',' ')}, /* Liberia Kpelle -> Kpelle (Liberia) */
+ {"xpe", HB_TAG('K','P','L',' ')}, /* Liberia Kpelle -> Kpelle */
{"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
{"xsl", HB_TAG('S','L','A',' ')}, /* South Slavey -> Slavey */
{"xsl", HB_TAG('A','T','H',' ')}, /* South Slavey -> Athapaskan */
{"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) -> Silte Gurage */
+ {"xup", HB_TAG('A','T','H',' ')}, /* Upper Umpqua -> Athapaskan */
{"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat -> Todo */
+ {"yaj", HB_TAG('B','A','D','0')}, /* Banda-Yangere -> Banda */
+ {"yak", HB_TAG_NONE }, /* Yakama != Sakha */
/*{"yao", HB_TAG('Y','A','O',' ')},*/ /* Yao */
/*{"yap", HB_TAG('Y','A','P',' ')},*/ /* Yapese */
+ {"yba", HB_TAG_NONE }, /* Yala != Yoruba */
+ {"ybb", HB_TAG('B','M','L',' ')}, /* Yemba -> Bamileke */
{"ybd", HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */
{"ydd", HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */
{"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */
{"yih", HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */
+ {"yim", HB_TAG_NONE }, /* Yimchungru Naga != Yi Modern */
{"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
{"yos", HB_TAG('Q','I','N',' ')}, /* Yos (retired code) -> Chin */
- {"yrk", HB_TAG('T','N','E',' ')}, /* Nenets -> Tundra Nenets */
- {"yrk", HB_TAG('F','N','E',' ')}, /* Nenets -> Forest Nenets */
- {"yue", HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Hong Kong SAR */
+ {"yua", HB_TAG('M','Y','N',' ')}, /* Yucateco -> Mayan */
+ {"yue", HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Traditional, Hong Kong SAR */
{"za", HB_TAG('Z','H','A',' ')}, /* Zhuang [macrolanguage] */
{"zch", HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */
{"zdj", HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */
/*{"zea", HB_TAG('Z','E','A',' ')},*/ /* Zeeuws -> Zealandic */
{"zeh", HB_TAG('Z','H','A',' ')}, /* Eastern Hongshuihe Zhuang -> Zhuang */
+ {"zen", HB_TAG('B','B','R',' ')}, /* Zenaga -> Berber */
{"zgb", HB_TAG('Z','H','A',' ')}, /* Guibei Zhuang -> Zhuang */
-/*{"zgh", HB_TAG('Z','G','H',' ')},*/ /* Standard Moroccan Tamazight */
+ {"zgh", HB_TAG('Z','G','H',' ')}, /* Standard Moroccan Tamazight */
+ {"zgh", HB_TAG('B','B','R',' ')}, /* Standard Moroccan Tamazight -> Berber */
{"zgm", HB_TAG('Z','H','A',' ')}, /* Minz Zhuang -> Zhuang */
{"zgn", HB_TAG('Z','H','A',' ')}, /* Guibian Zhuang -> Zhuang */
- {"zh", HB_TAG('Z','H','S',' ')}, /* Chinese [macrolanguage] -> Chinese Simplified */
+ {"zh", HB_TAG('Z','H','S',' ')}, /* Chinese, Simplified [macrolanguage] */
{"zhd", HB_TAG('Z','H','A',' ')}, /* Dai Zhuang -> Zhuang */
{"zhn", HB_TAG('Z','H','A',' ')}, /* Nong Zhuang -> Zhuang */
{"zlj", HB_TAG('Z','H','A',' ')}, /* Liujiang Zhuang -> Zhuang */
@@ -1044,6 +1564,8 @@ static const LangTag ot_languages[] = {
{"zln", HB_TAG('Z','H','A',' ')}, /* Lianshan Zhuang -> Zhuang */
{"zlq", HB_TAG('Z','H','A',' ')}, /* Liuqian Zhuang -> Zhuang */
{"zmi", HB_TAG('M','L','Y',' ')}, /* Negeri Sembilan Malay -> Malay */
+ {"zmz", HB_TAG('B','A','D','0')}, /* Mbandja -> Banda */
+ {"znd", HB_TAG_NONE }, /* Zande [family] != Zande */
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
{"zom", HB_TAG('Q','I','N',' ')}, /* Zou -> Chin */
{"zqe", HB_TAG('Z','H','A',' ')}, /* Qiubei Zhuang -> Zhuang */
@@ -1054,6 +1576,7 @@ static const LangTag ot_languages[] = {
{"zyg", HB_TAG('Z','H','A',' ')}, /* Yang Zhuang -> Zhuang */
{"zyj", HB_TAG('Z','H','A',' ')}, /* Youjiang Zhuang -> Zhuang */
{"zyn", HB_TAG('Z','H','A',' ')}, /* Yongnan Zhuang -> Zhuang */
+ {"zyp", HB_TAG('Q','I','N',' ')}, /* Zyphe Chin -> Chin */
/*{"zza", HB_TAG('Z','Z','A',' ')},*/ /* Zazaki [macrolanguage] */
{"zzj", HB_TAG('Z','H','A',' ')}, /* Zuojiang Zhuang -> Zhuang */
};
@@ -1092,6 +1615,13 @@ hb_ot_tags_from_complex_language (const char *lang_str,
*count = 1;
return true;
}
+ if (subtag_matches (lang_str, limit, "-arevmda"))
+ {
+ /* Armenian; Western Armenian (retired code) */
+ tags[0] = HB_TAG('H','Y','E',' '); /* Armenian */
+ *count = 1;
+ return true;
+ }
if (subtag_matches (lang_str, limit, "-provenc"))
{
/* Occitan (post 1500); Provençal */
@@ -1139,7 +1669,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'a':
if (0 == strcmp (&lang_str[1], "rt-lojban"))
{
- /* Lojban */
+ /* Lojban (retired code) */
tags[0] = HB_TAG('J','B','O',' '); /* Lojban */
*count = 1;
return true;
@@ -1148,225 +1678,273 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'c':
if (lang_matches (&lang_str[1], "do-hant-hk"))
{
- /* Min Dong Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Min Dong Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "do-hant-mo"))
{
- /* Min Dong Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Min Dong Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "jy-hant-hk"))
{
- /* Jinyu Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Jinyu Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "jy-hant-mo"))
{
- /* Jinyu Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Jinyu Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "mn-hant-hk"))
{
- /* Mandarin Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Mandarin Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "mn-hant-mo"))
{
- /* Mandarin Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Mandarin Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "np-hant-hk"))
{
- /* Northern Ping Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Northern Ping Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "np-hant-mo"))
{
- /* Northern Ping Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Northern Ping Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "px-hant-hk"))
{
- /* Pu-Xian Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Pu-Xian Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "px-hant-mo"))
{
- /* Pu-Xian Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Pu-Xian Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "sp-hant-hk"))
{
- /* Southern Ping Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Southern Ping Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "sp-hant-mo"))
{
- /* Southern Ping Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Southern Ping Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "zh-hant-hk"))
{
- /* Huizhou Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Huizhou Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "zh-hant-mo"))
{
- /* Huizhou Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Huizhou Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "zo-hant-hk"))
{
- /* Min Zhong Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Min Zhong Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "zo-hant-mo"))
{
- /* Min Zhong Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Min Zhong Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "do-hans"))
{
- /* Min Dong Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Min Dong Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "do-hant"))
{
- /* Min Dong Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Min Dong Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "jy-hans"))
{
- /* Jinyu Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Jinyu Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "jy-hant"))
{
- /* Jinyu Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Jinyu Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "mn-hans"))
{
- /* Mandarin Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Mandarin Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "mn-hant"))
{
- /* Mandarin Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Mandarin Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "np-hans"))
{
- /* Northern Ping Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Northern Ping Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "np-hant"))
{
- /* Northern Ping Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Northern Ping Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "px-hans"))
{
- /* Pu-Xian Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Pu-Xian Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "px-hant"))
{
- /* Pu-Xian Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Pu-Xian Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "sp-hans"))
{
- /* Southern Ping Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Southern Ping Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "sp-hant"))
{
- /* Southern Ping Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Southern Ping Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "zh-hans"))
{
- /* Huizhou Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Huizhou Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "zh-hant"))
{
- /* Huizhou Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Huizhou Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "zo-hans"))
{
- /* Min Zhong Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Min Zhong Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "zo-hant"))
{
- /* Min Zhong Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Min Zhong Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1374,7 +1952,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Min Dong Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1382,15 +1960,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Min Dong Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "do-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Min Dong Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1398,7 +1982,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Jinyu Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1406,15 +1990,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Jinyu Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "jy-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Jinyu Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1422,7 +2012,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Mandarin Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1430,15 +2020,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Mandarin Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "mn-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Mandarin Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1446,7 +2042,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Northern Ping Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1454,15 +2050,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Northern Ping Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "np-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Northern Ping Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1470,7 +2072,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Pu-Xian Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1478,15 +2080,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Pu-Xian Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "px-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Pu-Xian Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1494,7 +2102,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Southern Ping Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1502,15 +2110,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Southern Ping Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "sp-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Southern Ping Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1518,7 +2132,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Huizhou Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1526,15 +2140,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Huizhou Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "zh-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Huizhou Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1542,7 +2162,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Min Zhong Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1550,15 +2170,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Min Zhong Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "zo-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Min Zhong Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1566,35 +2192,41 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'g':
if (lang_matches (&lang_str[1], "an-hant-hk"))
{
- /* Gan Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Gan Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "an-hant-mo"))
{
- /* Gan Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Gan Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "an-hans"))
{
- /* Gan Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Gan Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "an-hant"))
{
- /* Gan Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Gan Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "a-latg"))
{
- /* Irish */
+ /* Irish; Latin (Gaelic variant) */
tags[0] = HB_TAG('I','R','T',' '); /* Irish Traditional */
*count = 1;
return true;
@@ -1603,7 +2235,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Gan Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1611,15 +2243,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Gan Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "an-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Gan Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1627,57 +2265,69 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'h':
if (lang_matches (&lang_str[1], "ak-hant-hk"))
{
- /* Hakka Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Hakka Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "ak-hant-mo"))
{
- /* Hakka Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Hakka Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "sn-hant-hk"))
{
- /* Xiang Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Xiang Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "sn-hant-mo"))
{
- /* Xiang Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Xiang Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "ak-hans"))
{
- /* Hakka Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Hakka Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "ak-hant"))
{
- /* Hakka Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Hakka Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "sn-hans"))
{
- /* Xiang Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Xiang Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "sn-hant"))
{
- /* Xiang Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Xiang Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1685,7 +2335,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Hakka Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1693,15 +2343,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Hakka Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "ak-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Hakka Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1709,7 +2365,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Xiang Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1717,15 +2373,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Xiang Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "sn-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Xiang Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1733,7 +2395,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'i':
if (0 == strcmp (&lang_str[1], "-navajo"))
{
- /* Navajo */
+ /* Navajo (retired code) */
unsigned int i;
hb_tag_t possible_tags[] = {
HB_TAG('N','A','V',' '), /* Navajo */
@@ -1746,14 +2408,14 @@ hb_ot_tags_from_complex_language (const char *lang_str,
}
if (0 == strcmp (&lang_str[1], "-hak"))
{
- /* Hakka */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Hakka (retired code) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (0 == strcmp (&lang_str[1], "-lux"))
{
- /* Luxembourgish */
+ /* Luxembourgish (retired code) */
tags[0] = HB_TAG('L','T','Z',' '); /* Luxembourgish */
*count = 1;
return true;
@@ -1762,8 +2424,8 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'l':
if (lang_matches (&lang_str[1], "zh-hans"))
{
- /* Literary Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Literary Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
@@ -1771,29 +2433,35 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'm':
if (lang_matches (&lang_str[1], "np-hant-hk"))
{
- /* Min Bei Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Min Bei Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "np-hant-mo"))
{
- /* Min Bei Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Min Bei Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "np-hans"))
{
- /* Min Bei Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Min Bei Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "np-hant"))
{
- /* Min Bei Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Min Bei Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1801,7 +2469,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Min Bei Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1809,15 +2477,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Min Bei Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "np-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Min Bei Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1825,29 +2499,35 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'n':
if (lang_matches (&lang_str[1], "an-hant-hk"))
{
- /* Min Nan Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Min Nan Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "an-hant-mo"))
{
- /* Min Nan Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Min Nan Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "an-hans"))
{
- /* Min Nan Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Min Nan Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "an-hant"))
{
- /* Min Nan Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Min Nan Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1855,7 +2535,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Min Nan Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1863,30 +2543,42 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Min Nan Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "an-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Min Nan Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (0 == strcmp (&lang_str[1], "o-bok"))
{
- /* Norwegian Bokmal */
+ /* Norwegian Bokmal (retired code) */
tags[0] = HB_TAG('N','O','R',' '); /* Norwegian */
*count = 1;
return true;
}
if (0 == strcmp (&lang_str[1], "o-nyn"))
{
- /* Norwegian Nynorsk */
- tags[0] = HB_TAG('N','Y','N',' '); /* Norwegian Nynorsk (Nynorsk, Norwegian) */
- *count = 1;
+ /* Norwegian Nynorsk (retired code) */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('N','Y','N',' '), /* Norwegian Nynorsk (Nynorsk, Norwegian) */
+ HB_TAG('N','O','R',' '), /* Norwegian */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
break;
@@ -1903,29 +2595,35 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'w':
if (lang_matches (&lang_str[1], "uu-hant-hk"))
{
- /* Wu Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Wu Chinese; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "uu-hant-mo"))
{
- /* Wu Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Wu Chinese; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (lang_matches (&lang_str[1], "uu-hans"))
{
- /* Wu Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Wu Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "uu-hant"))
{
- /* Wu Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Wu Chinese; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1933,7 +2631,7 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-hk"))
{
/* Wu Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
@@ -1941,15 +2639,21 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-mo"))
{
/* Wu Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "uu-", 3)
&& subtag_matches (lang_str, limit, "-tw"))
{
/* Wu Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -1957,8 +2661,8 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'y':
if (lang_matches (&lang_str[1], "ue-hans"))
{
- /* Yue Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Yue Chinese; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
@@ -1966,67 +2670,79 @@ hb_ot_tags_from_complex_language (const char *lang_str,
case 'z':
if (lang_matches (&lang_str[1], "h-hant-hk"))
{
- /* Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Chinese [macrolanguage]; Han (Traditional variant); Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "h-hant-mo"))
{
- /* Chinese */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Chinese [macrolanguage]; Han (Traditional variant); Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strcmp (&lang_str[1], "h-min-nan"))
{
- /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo (retired code) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "h-hans"))
{
- /* Chinese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Chinese [macrolanguage]; Han (Simplified variant) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (lang_matches (&lang_str[1], "h-hant"))
{
- /* Chinese */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Chinese [macrolanguage]; Han (Traditional variant) */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
if (0 == strcmp (&lang_str[1], "h-min"))
{
- /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese Simplified */
+ /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese (retired code) */
+ tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
*count = 1;
return true;
}
if (0 == strncmp (&lang_str[1], "h-", 2)
&& subtag_matches (lang_str, limit, "-hk"))
{
- /* Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
+ /* Chinese [macrolanguage]; Hong Kong */
+ tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
*count = 1;
return true;
}
if (0 == strncmp (&lang_str[1], "h-", 2)
&& subtag_matches (lang_str, limit, "-mo"))
{
- /* Chinese; Macao */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Hong Kong SAR */
- *count = 1;
+ /* Chinese [macrolanguage]; Macao */
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
+ HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
if (0 == strncmp (&lang_str[1], "h-", 2)
&& subtag_matches (lang_str, limit, "-tw"))
{
- /* Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese Traditional */
+ /* Chinese [macrolanguage]; Taiwan, Province of China */
+ tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
*count = 1;
return true;
}
@@ -2057,99 +2773,127 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */
return hb_language_from_string ("und-fonnapa", -1); /* Undetermined; North American Phonetic Alphabet */
case HB_TAG('A','R','A',' '): /* Arabic */
- return hb_language_from_string ("ar", -1); /* Arabic */
+ return hb_language_from_string ("ar", -1); /* Arabic [macrolanguage] */
case HB_TAG('A','R','K',' '): /* Rakhine */
return hb_language_from_string ("rki", -1); /* Rakhine */
case HB_TAG('A','T','H',' '): /* Athapaskan */
- return hb_language_from_string ("ath", -1); /* Athapascan */
+ return hb_language_from_string ("ath", -1); /* Athapascan [family] */
+ case HB_TAG('B','B','R',' '): /* Berber */
+ return hb_language_from_string ("ber", -1); /* Berber [family] */
case HB_TAG('B','I','K',' '): /* Bikol */
- return hb_language_from_string ("bik", -1); /* Bikol */
+ return hb_language_from_string ("bik", -1); /* Bikol [macrolanguage] */
+ case HB_TAG('B','T','K',' '): /* Batak */
+ return hb_language_from_string ("btk", -1); /* Batak [family] */
case HB_TAG('C','P','P',' '): /* Creoles */
- return hb_language_from_string ("crp", -1); /* Creoles and pidgins */
+ return hb_language_from_string ("crp", -1); /* Creoles and pidgins [family] */
case HB_TAG('C','R','R',' '): /* Carrier */
return hb_language_from_string ("crx", -1); /* Carrier */
+ case HB_TAG('D','G','R',' '): /* Dogri (macrolanguage) */
+ return hb_language_from_string ("doi", -1); /* Dogri [macrolanguage] */
case HB_TAG('D','N','K',' '): /* Dinka */
- return hb_language_from_string ("din", -1); /* Dinka */
+ return hb_language_from_string ("din", -1); /* Dinka [macrolanguage] */
case HB_TAG('D','R','I',' '): /* Dari */
return hb_language_from_string ("prs", -1); /* Dari */
case HB_TAG('D','Z','N',' '): /* Dzongkha */
return hb_language_from_string ("dz", -1); /* Dzongkha */
case HB_TAG('E','T','I',' '): /* Estonian */
- return hb_language_from_string ("et", -1); /* Estonian */
+ return hb_language_from_string ("et", -1); /* Estonian [macrolanguage] */
+ case HB_TAG('F','A','R',' '): /* Persian */
+ return hb_language_from_string ("fa", -1); /* Persian [macrolanguage] */
case HB_TAG('G','O','N',' '): /* Gondi */
- return hb_language_from_string ("gon", -1); /* Gondi */
+ return hb_language_from_string ("gon", -1); /* Gondi [macrolanguage] */
case HB_TAG('H','M','N',' '): /* Hmong */
- return hb_language_from_string ("hmn", -1); /* Hmong */
+ return hb_language_from_string ("hmn", -1); /* Hmong [macrolanguage] */
case HB_TAG('H','N','D',' '): /* Hindko */
return hb_language_from_string ("hnd", -1); /* Southern Hindko */
+ case HB_TAG('H','Y','E',' '): /* Armenian */
+ return hb_language_from_string ("hyw", -1); /* Western Armenian */
case HB_TAG('I','J','O',' '): /* Ijo */
- return hb_language_from_string ("ijo", -1); /* Ijo */
+ return hb_language_from_string ("ijo", -1); /* Ijo [family] */
case HB_TAG('I','N','U',' '): /* Inuktitut */
- return hb_language_from_string ("iu", -1); /* Inuktitut */
+ return hb_language_from_string ("iu", -1); /* Inuktitut [macrolanguage] */
case HB_TAG('I','P','K',' '): /* Inupiat */
- return hb_language_from_string ("ik", -1); /* Inupiaq */
+ return hb_language_from_string ("ik", -1); /* Inupiaq [macrolanguage] */
case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */
return hb_language_from_string ("und-fonipa", -1); /* Undetermined; International Phonetic Alphabet */
case HB_TAG('I','R','T',' '): /* Irish Traditional */
return hb_language_from_string ("ga-Latg", -1); /* Irish; Latin (Gaelic variant) */
case HB_TAG('J','I','I',' '): /* Yiddish */
- return hb_language_from_string ("yi", -1); /* Yiddish */
+ return hb_language_from_string ("yi", -1); /* Yiddish [macrolanguage] */
case HB_TAG('K','A','L',' '): /* Kalenjin */
- return hb_language_from_string ("kln", -1); /* Kalenjin */
+ return hb_language_from_string ("kln", -1); /* Kalenjin [macrolanguage] */
case HB_TAG('K','G','E',' '): /* Khutsuri Georgian */
return hb_language_from_string ("und-Geok", -1); /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */
case HB_TAG('K','N','R',' '): /* Kanuri */
- return hb_language_from_string ("kr", -1); /* Kanuri */
+ return hb_language_from_string ("kr", -1); /* Kanuri [macrolanguage] */
+ case HB_TAG('K','O','H',' '): /* Korean Old Hangul */
+ return hb_language_from_string ("okm", -1); /* Middle Korean (10th-16th cent.) */
case HB_TAG('K','O','K',' '): /* Konkani */
- return hb_language_from_string ("kok", -1); /* Konkani */
+ return hb_language_from_string ("kok", -1); /* Konkani [macrolanguage] */
+ case HB_TAG('K','O','M',' '): /* Komi */
+ return hb_language_from_string ("kv", -1); /* Komi [macrolanguage] */
+ case HB_TAG('K','P','L',' '): /* Kpelle */
+ return hb_language_from_string ("kpe", -1); /* Kpelle [macrolanguage] */
+ case HB_TAG('K','R','N',' '): /* Karen */
+ return hb_language_from_string ("kar", -1); /* Karen [family] */
case HB_TAG('K','U','I',' '): /* Kui */
return hb_language_from_string ("uki", -1); /* Kui (India) */
case HB_TAG('K','U','R',' '): /* Kurdish */
- return hb_language_from_string ("ku", -1); /* Kurdish */
+ return hb_language_from_string ("ku", -1); /* Kurdish [macrolanguage] */
case HB_TAG('L','U','H',' '): /* Luyia */
- return hb_language_from_string ("luy", -1); /* Luyia */
+ return hb_language_from_string ("luy", -1); /* Luyia [macrolanguage] */
case HB_TAG('L','V','I',' '): /* Latvian */
- return hb_language_from_string ("lv", -1); /* Latvian */
+ return hb_language_from_string ("lv", -1); /* Latvian [macrolanguage] */
case HB_TAG('M','A','W',' '): /* Marwari */
- return hb_language_from_string ("mwr", -1); /* Marwari */
+ return hb_language_from_string ("mwr", -1); /* Marwari [macrolanguage] */
case HB_TAG('M','L','G',' '): /* Malagasy */
- return hb_language_from_string ("mg", -1); /* Malagasy */
+ return hb_language_from_string ("mg", -1); /* Malagasy [macrolanguage] */
case HB_TAG('M','L','Y',' '): /* Malay */
- return hb_language_from_string ("ms", -1); /* Malay */
+ return hb_language_from_string ("ms", -1); /* Malay [macrolanguage] */
case HB_TAG('M','N','G',' '): /* Mongolian */
- return hb_language_from_string ("mn", -1); /* Mongolian */
+ return hb_language_from_string ("mn", -1); /* Mongolian [macrolanguage] */
+ case HB_TAG('M','N','K',' '): /* Maninka */
+ 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','Y','N',' '): /* Mayan */
+ return hb_language_from_string ("myn", -1); /* Mayan [family] */
+ case HB_TAG('N','A','H',' '): /* Nahuatl */
+ return hb_language_from_string ("nah", -1); /* Nahuatl [family] */
case HB_TAG('N','E','P',' '): /* Nepali */
- return hb_language_from_string ("ne", -1); /* Nepali */
+ return hb_language_from_string ("ne", -1); /* Nepali [macrolanguage] */
case HB_TAG('N','I','S',' '): /* Nisi */
return hb_language_from_string ("njz", -1); /* Nyishi */
case HB_TAG('N','O','R',' '): /* Norwegian */
- return hb_language_from_string ("no", -1); /* Norwegian */
+ return hb_language_from_string ("no", -1); /* Norwegian [macrolanguage] */
case HB_TAG('O','J','B',' '): /* Ojibway */
- return hb_language_from_string ("oj", -1); /* Ojibwa */
+ return hb_language_from_string ("oj", -1); /* Ojibwa [macrolanguage] */
case HB_TAG('O','R','O',' '): /* Oromo */
- return hb_language_from_string ("om", -1); /* Oromo */
+ return hb_language_from_string ("om", -1); /* Oromo [macrolanguage] */
case HB_TAG('P','A','S',' '): /* Pashto */
- return hb_language_from_string ("ps", -1); /* Pashto */
+ return hb_language_from_string ("ps", -1); /* Pashto [macrolanguage] */
case HB_TAG('P','G','R',' '): /* Polytonic Greek */
return hb_language_from_string ("el-polyton", -1); /* Modern Greek (1453-); Polytonic Greek */
case HB_TAG('P','R','O',' '): /* Provençal / Old Provençal */
return hb_language_from_string ("pro", -1); /* Old Provençal (to 1500) */
case HB_TAG('Q','U','H',' '): /* Quechua (Bolivia) */
return hb_language_from_string ("quh", -1); /* South Bolivian Quechua */
+ case HB_TAG('Q','U','Z',' '): /* Quechua */
+ return hb_language_from_string ("qu", -1); /* Quechua [macrolanguage] */
case HB_TAG('Q','V','I',' '): /* Quechua (Ecuador) */
return hb_language_from_string ("qvi", -1); /* Imbabura Highland Quichua */
case HB_TAG('Q','W','H',' '): /* Quechua (Peru) */
return hb_language_from_string ("qwh", -1); /* Huaylas Ancash Quechua */
case HB_TAG('R','A','J',' '): /* Rajasthani */
- return hb_language_from_string ("raj", -1); /* Rajasthani */
+ return hb_language_from_string ("raj", -1); /* Rajasthani [macrolanguage] */
case HB_TAG('R','O','Y',' '): /* Romany */
- return hb_language_from_string ("rom", -1); /* Romany */
+ return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */
case HB_TAG('S','Q','I',' '): /* Albanian */
- return hb_language_from_string ("sq", -1); /* Albanian */
+ return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */
+ case HB_TAG('S','R','B',' '): /* Serbian */
+ return hb_language_from_string ("sr", -1); /* Serbian */
case HB_TAG('S','Y','R',' '): /* Syriac */
- return hb_language_from_string ("syr", -1); /* Syriac */
+ return hb_language_from_string ("syr", -1); /* Syriac [macrolanguage] */
case HB_TAG('S','Y','R','E'): /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */
return hb_language_from_string ("und-Syre", -1); /* Undetermined; Syriac (Estrangelo variant) */
case HB_TAG('S','Y','R','J'): /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */
@@ -2157,15 +2901,19 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
case HB_TAG('S','Y','R','N'): /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */
return hb_language_from_string ("und-Syrn", -1); /* Undetermined; Syriac (Eastern variant) */
case HB_TAG('T','M','H',' '): /* Tamashek */
- return hb_language_from_string ("tmh", -1); /* Tamashek */
- case HB_TAG('T','N','E',' '): /* Tundra Nenets */
- return hb_language_from_string ("yrk", -1); /* Nenets */
- case HB_TAG('Z','H','H',' '): /* Chinese, Hong Kong SAR */
- return hb_language_from_string ("zh-HK", -1); /* Chinese; Hong Kong */
- case HB_TAG('Z','H','S',' '): /* Chinese Simplified */
- return hb_language_from_string ("zh-Hans", -1); /* Chinese; Han (Simplified variant) */
- case HB_TAG('Z','H','T',' '): /* Chinese Traditional */
- return hb_language_from_string ("zh-Hant", -1); /* Chinese; Han (Traditional variant) */
+ return hb_language_from_string ("tmh", -1); /* Tamashek [macrolanguage] */
+ case HB_TAG('T','O','D',' '): /* Todo */
+ return hb_language_from_string ("xwo", -1); /* Written Oirat */
+ case HB_TAG('Z','H','H',' '): /* Chinese, Traditional, Hong Kong SAR */
+ return hb_language_from_string ("zh-HK", -1); /* Chinese [macrolanguage]; Hong Kong */
+ case HB_TAG('Z','H','S',' '): /* Chinese, Simplified */
+ return hb_language_from_string ("zh-Hans", -1); /* Chinese [macrolanguage]; Han (Simplified variant) */
+ case HB_TAG('Z','H','T',' '): /* Chinese, Traditional */
+ return hb_language_from_string ("zh-Hant", -1); /* Chinese [macrolanguage]; Han (Traditional variant) */
+ case HB_TAG('Z','H','T','M'): /* Chinese, Traditional, Macao SAR */
+ return hb_language_from_string ("zh-MO", -1); /* Chinese [macrolanguage]; Macao */
+ case HB_TAG('Z','Z','A',' '): /* Zazaki */
+ return hb_language_from_string ("zza", -1); /* Zazaki [macrolanguage] */
default:
return HB_LANGUAGE_INVALID;
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-tag.cc b/thirdparty/harfbuzz/src/hb-ot-tag.cc
index 7ec91c5815..19bd3639d3 100644
--- a/thirdparty/harfbuzz/src/hb-ot-tag.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-tag.cc
@@ -280,6 +280,7 @@ hb_ot_tags_from_language (const char *lang_str,
for (i = 0;
i < *count &&
tag_idx + i < ARRAY_LENGTH (ot_languages) &&
+ ot_languages[tag_idx + i].tag != HB_TAG_NONE &&
0 == strcmp (ot_languages[tag_idx + i].language, ot_languages[tag_idx].language);
i++)
tags[i] = ot_languages[tag_idx + i].tag;
diff --git a/thirdparty/harfbuzz/src/hb-ot-var.cc b/thirdparty/harfbuzz/src/hb-ot-var.cc
index 6b8b09b6ba..1fe57383c0 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-var.cc
@@ -52,11 +52,11 @@
/**
* hb_ot_var_has_data:
- * @face: #hb_face_t to test
+ * @face: The #hb_face_t to work on
*
- * This function allows to verify the presence of OpenType variation data on the face.
+ * Tests whether a face includes any OpenType variation data in the `fvar` table.
*
- * Return value: true if face has a `fvar' table and false otherwise
+ * Return value: true if data found, false otherwise
*
* Since: 1.4.2
**/
@@ -68,6 +68,11 @@ hb_ot_var_has_data (hb_face_t *face)
/**
* hb_ot_var_get_axis_count:
+ * @face: The #hb_face_t to work on
+ *
+ * Fetches the number of OpenType variation axes included in the face.
+ *
+ * Return value: the number of variation axes defined
*
* Since: 1.4.2
**/
@@ -80,9 +85,17 @@ hb_ot_var_get_axis_count (hb_face_t *face)
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_ot_var_get_axes:
+ * @face: #hb_face_t to work upon
+ * @start_offset: offset of the first lookup to retrieve
+ * @axes_count: (inout) (allow-none): Input = the maximum number of variation axes to return;
+ * Output = the actual number of variation axes returned (may be zero)
+ * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found
+ *
+ * Fetches a list of all variation axes in the specified face. The list returned will begin
+ * at the offset provided.
*
* Since: 1.4.2
- * Deprecated: 2.2.0
+ * Deprecated: 2.2.0: use hb_ot_var_get_axis_infos() instead
**/
unsigned int
hb_ot_var_get_axes (hb_face_t *face,
@@ -95,9 +108,16 @@ hb_ot_var_get_axes (hb_face_t *face,
/**
* hb_ot_var_find_axis:
+ * @face: #hb_face_t to work upon
+ * @axis_tag: The #hb_tag_t of the variation axis to query
+ * @axis_index: The index of the variation axis
+ * @axis_info: (out): The #hb_ot_var_axis_info_t of the axis tag queried
+ *
+ * Fetches the variation-axis information corresponding to the specified axis tag
+ * in the specified face.
*
* Since: 1.4.2
- * Deprecated: 2.2.0
+ * Deprecated: 2.2.0 - use hb_ot_var_find_axis_info() instead
**/
hb_bool_t
hb_ot_var_find_axis (hb_face_t *face,
@@ -111,6 +131,16 @@ hb_ot_var_find_axis (hb_face_t *face,
/**
* hb_ot_var_get_axis_infos:
+ * @face: #hb_face_t to work upon
+ * @start_offset: offset of the first lookup to retrieve
+ * @axes_count: (inout) (allow-none): Input = the maximum number of variation axes to return;
+ * Output = the actual number of variation axes returned (may be zero)
+ * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found
+ *
+ * Fetches a list of all variation axes in the specified face. The list returned will begin
+ * at the offset provided.
+ *
+ * Return value: the number of variation axes in the face
*
* Since: 2.2.0
**/
@@ -125,6 +155,14 @@ hb_ot_var_get_axis_infos (hb_face_t *face,
/**
* hb_ot_var_find_axis_info:
+ * @face: #hb_face_t to work upon
+ * @axis_tag: The #hb_tag_t of the variation axis to query
+ * @axis_info: (out): The #hb_ot_var_axis_info_t of the axis tag queried
+ *
+ * Fetches the variation-axis information corresponding to the specified axis tag
+ * in the specified face.
+ *
+ * Return value: true if data found, false otherwise
*
* Since: 2.2.0
**/
@@ -141,12 +179,34 @@ hb_ot_var_find_axis_info (hb_face_t *face,
* Named instances.
*/
+/**
+ * hb_ot_var_get_named_instance_count:
+ * @face: The #hb_face_t to work on
+ *
+ * Fetches the number of named instances included in the face.
+ *
+ * Return value: the number of named instances defined
+ *
+ * Since: 2.2.0
+ **/
unsigned int
hb_ot_var_get_named_instance_count (hb_face_t *face)
{
return face->table.fvar->get_instance_count ();
}
+/**
+ * hb_ot_var_named_instance_get_subfamily_name_id:
+ * @face: The #hb_face_t to work on
+ * @instance_index: The index of the named instance to query
+ *
+ * Fetches the `name` table Name ID that provides display names for
+ * the "Subfamily name" defined for the given named instance in the face.
+ *
+ * Return value: the Name ID found for the Subfamily name
+ *
+ * Since: 2.2.0
+ **/
hb_ot_name_id_t
hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face,
unsigned int instance_index)
@@ -154,6 +214,18 @@ hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face,
return face->table.fvar->get_instance_subfamily_name_id (instance_index);
}
+/**
+ * hb_ot_var_named_instance_get_postscript_name_id:
+ * @face: The #hb_face_t to work on
+ * @instance_index: The index of the named instance to query
+ *
+ * Fetches the `name` table Name ID that provides display names for
+ * the "PostScript name" defined for the given named instance in the face.
+ *
+ * Return value: the Name ID found for the PostScript name
+ *
+ * Since: 2.2.0
+ **/
hb_ot_name_id_t
hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face,
unsigned int instance_index)
@@ -161,6 +233,21 @@ hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face,
return face->table.fvar->get_instance_postscript_name_id (instance_index);
}
+/**
+ * hb_ot_var_named_instance_get_design_coords:
+ * @face: The #hb_face_t to work on
+ * @instance_index: The index of the named instance to query
+ * @coords_length: (inout) (allow-none): Input = the maximum number of coordinates to return;
+ * Output = the actual number of coordinates returned (may be zero)
+ * @coords: (out) (array length=coords_length): The array of coordinates found for the query
+ *
+ * Fetches the design-space coordinates corresponding to the given
+ * named instance in the face.
+ *
+ * Return value: the number of variation axes in the face
+ *
+ * Since: 2.2.0
+ **/
unsigned int
hb_ot_var_named_instance_get_design_coords (hb_face_t *face,
unsigned int instance_index,
@@ -173,6 +260,13 @@ hb_ot_var_named_instance_get_design_coords (hb_face_t *face,
/**
* hb_ot_var_normalize_variations:
+ * @face: The #hb_face_t to work on
+ * @variations: The array of variations to normalize
+ * @variations_length: The number of variations to normalize
+ * @coords: (out) (array length=coords_length): The array of normalized coordinates
+ * @coords_length: The length of the coordinate array
+ *
+ * Normalizes all of the coordinates in the given list of variation axes.
*
* Since: 1.4.2
**/
@@ -200,6 +294,17 @@ hb_ot_var_normalize_variations (hb_face_t *face,
/**
* hb_ot_var_normalize_coords:
+ * @face: The #hb_face_t to work on
+ * @coords_length: The length of the coordinate array
+ * @design_coords: The design-space coordinates to normalize
+ * @normalized_coords: (out): The normalized coordinates
+ *
+ * Normalizes the given design-space coordinates. The minimum and maximum
+ * values for the axis are mapped to the interval [-1,1], with the default
+ * axis value mapped to 0.
+ *
+ * Any additional scaling defined in the face's `avar` table is also
+ * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar
*
* Since: 1.4.2
**/
diff --git a/thirdparty/harfbuzz/src/hb-ot-var.h b/thirdparty/harfbuzz/src/hb-ot-var.h
index df89bc5a23..ef2ca0a716 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var.h
+++ b/thirdparty/harfbuzz/src/hb-ot-var.h
@@ -35,11 +35,36 @@
HB_BEGIN_DECLS
-
+/**
+ * hb_tag_t:
+ * @HB_OT_TAG_VAR_AXIS_ITALIC: Registered tag for the roman/italic axis
+ */
#define HB_OT_TAG_VAR_AXIS_ITALIC HB_TAG('i','t','a','l')
+
+/**
+ * hb_tag_t:
+ * @HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE: Registered tag for the optical-size axis
+ *
+ * <note>Note: The optical-size axis supersedes the OpenType `size` feature.</note>
+ */
#define HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE HB_TAG('o','p','s','z')
+
+/**
+ * hb_tag_t:
+ * @HB_OT_TAG_VAR_AXIS_SLANT: Registered tag for the slant axis
+ */
#define HB_OT_TAG_VAR_AXIS_SLANT HB_TAG('s','l','n','t')
+
+/**
+ * hb_tag_t:
+ * @HB_OT_TAG_VAR_AXIS_WIDTH: Registered tag for the width axis
+ */
#define HB_OT_TAG_VAR_AXIS_WIDTH HB_TAG('w','d','t','h')
+
+/**
+ * hb_tag_t:
+ * @HB_OT_TAG_VAR_AXIS_WEIGHT: Registered tag for the weight axis
+ */
#define HB_OT_TAG_VAR_AXIS_WEIGHT HB_TAG('w','g','h','t')
@@ -73,11 +98,24 @@ typedef enum { /*< flags >*/
/**
* hb_ot_var_axis_info_t:
+ * @axis_index: Index of the axis in the variation-axis array
+ * @tag: The #hb_tag_t tag identifying the design variation of the axis
+ * @name_id: The `name` table Name ID that provides display names for the axis
+ * @flags: The #hb_ot_var_axis_flags_t flags for the axis
+ * @min_value: The mininum value on the variation axis that the font covers
+ * @default_value: The position on the variation axis corresponding to the font's defaults
+ * @max_value: The maximum value on the variation axis that the font covers
+ *
+ * Data type for holding variation-axis values.
+ *
+ * The minimum, default, and maximum values are in un-normalized, user scales.
+ *
+ * <note>Note: at present, the only flag defined for @flags is
+ * #HB_OT_VAR_AXIS_FLAG_HIDDEN.</note>
*
* Since: 2.2.0
*/
-typedef struct hb_ot_var_axis_info_t
-{
+typedef struct hb_ot_var_axis_info_t {
unsigned int axis_index;
hb_tag_t tag;
hb_ot_name_id_t name_id;
diff --git a/thirdparty/harfbuzz/src/hb-set.cc b/thirdparty/harfbuzz/src/hb-set.cc
index 0551ed80f2..3b4059ad32 100644
--- a/thirdparty/harfbuzz/src/hb-set.cc
+++ b/thirdparty/harfbuzz/src/hb-set.cc
@@ -30,11 +30,11 @@
/**
* SECTION:hb-set
* @title: hb-set
- * @short_description: Object representing a set of integers
+ * @short_description: Objects representing a set of integers
* @include: hb.h
*
* Set objects represent a mathematical set of integer values. They are
- * used in non-shaping API to query certain set of characters or glyphs,
+ * used in non-shaping APIs to query certain sets of characters or glyphs,
* or other integer values.
**/
@@ -42,7 +42,9 @@
/**
* hb_set_create: (Xconstructor)
*
- * Return value: (transfer full):
+ * Creates a new, initially empty set.
+ *
+ * Return value: (transfer full): The new #hb_set_t
*
* Since: 0.9.2
**/
@@ -62,7 +64,9 @@ hb_set_create ()
/**
* hb_set_get_empty:
*
- * Return value: (transfer full):
+ * Fetches the singleton empty #hb_set_t.
+ *
+ * Return value: (transfer full): The empty #hb_set_t
*
* Since: 0.9.2
**/
@@ -74,9 +78,11 @@ hb_set_get_empty ()
/**
* hb_set_reference: (skip)
- * @set: a set.
+ * @set: A set
+ *
+ * Increases the reference count on a set.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): The set
*
* Since: 0.9.2
**/
@@ -88,7 +94,11 @@ hb_set_reference (hb_set_t *set)
/**
* hb_set_destroy: (skip)
- * @set: a set.
+ * @set: A set
+ *
+ * Decreases the reference count on a set. When
+ * the reference count reaches zero, the set is
+ * destroyed, freeing all memory.
*
* Since: 0.9.2
**/
@@ -104,13 +114,15 @@ hb_set_destroy (hb_set_t *set)
/**
* hb_set_set_user_data: (skip)
- * @set: a set.
- * @key:
- * @data:
- * @destroy:
- * @replace:
+ * @set: A set
+ * @key: The user-data key to set
+ * @data: A pointer to the user data to set
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
*
- * Return value:
+ * Attaches a user-data key/data pair to the specified set.
+ *
+ * Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@@ -126,10 +138,13 @@ hb_set_set_user_data (hb_set_t *set,
/**
* hb_set_get_user_data: (skip)
- * @set: a set.
- * @key:
+ * @set: A set
+ * @key: The user-data key to query
+ *
+ * Fetches the user data associated with the specified key,
+ * attached to the specified set.
*
- * Return value: (transfer none):
+ * Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@@ -143,11 +158,11 @@ hb_set_get_user_data (hb_set_t *set,
/**
* hb_set_allocation_successful:
- * @set: a set.
- *
+ * @set: A set
*
+ * Tests whether memory allocation for a set was successful.
*
- * Return value:
+ * Return value: %true if allocation succeeded, false otherwise
*
* Since: 0.9.2
**/
@@ -159,9 +174,9 @@ hb_set_allocation_successful (const hb_set_t *set)
/**
* hb_set_clear:
- * @set: a set.
- *
+ * @set: A set
*
+ * Clears out the contents of a set.
*
* Since: 0.9.2
**/
@@ -175,9 +190,9 @@ hb_set_clear (hb_set_t *set)
* hb_set_is_empty:
* @set: a set.
*
+ * Tests whether a set is empty (contains no elements).
*
- *
- * Return value:
+ * Return value: %true if @set is empty
*
* Since: 0.9.7
**/
@@ -189,12 +204,12 @@ hb_set_is_empty (const hb_set_t *set)
/**
* hb_set_has:
- * @set: a set.
- * @codepoint:
+ * @set: A set
+ * @codepoint: The element to query
*
+ * Tests whether @codepoint belongs to @set.
*
- *
- * Return value:
+ * Return value: %true if @codepoint is in @set, false otherwise
*
* Since: 0.9.2
**/
@@ -207,10 +222,10 @@ hb_set_has (const hb_set_t *set,
/**
* hb_set_add:
- * @set: a set.
- * @codepoint:
- *
+ * @set: A set
+ * @codepoint: The element to add to @set
*
+ * Adds @codepoint to @set.
*
* Since: 0.9.2
**/
@@ -223,11 +238,12 @@ hb_set_add (hb_set_t *set,
/**
* hb_set_add_range:
- * @set: a set.
- * @first:
- * @last:
- *
+ * @set: A set
+ * @first: The first element to add to @set
+ * @last: The final element to add to @set
*
+ * Adds all of the elements from @first to @last
+ * (inclusive) to @set.
*
* Since: 0.9.7
**/
@@ -241,10 +257,10 @@ hb_set_add_range (hb_set_t *set,
/**
* hb_set_del:
- * @set: a set.
- * @codepoint:
- *
+ * @set: A set
+ * @codepoint: Removes @codepoint from @set
*
+ * Removes @codepoint from @set.
*
* Since: 0.9.2
**/
@@ -257,11 +273,12 @@ hb_set_del (hb_set_t *set,
/**
* hb_set_del_range:
- * @set: a set.
- * @first:
- * @last:
- *
+ * @set: A set
+ * @first: The first element to remove from @set
+ * @last: The final element to remove from @set
*
+ * Removes all of the elements from @first to @last
+ * (inclusive) from @set.
*
* Since: 0.9.7
**/
@@ -275,10 +292,11 @@ hb_set_del_range (hb_set_t *set,
/**
* hb_set_is_equal:
- * @set: a set.
- * @other: other set.
- *
+ * @set: A set
+ * @other: Another set
*
+ * Tests whether @set and @other are equal (contain the same
+ * elements).
*
* Return value: %TRUE if the two sets are equal, %FALSE otherwise.
*
@@ -293,10 +311,10 @@ hb_set_is_equal (const hb_set_t *set,
/**
* hb_set_is_subset:
- * @set: a set.
- * @larger_set: other set.
- *
+ * @set: A set
+ * @larger_set: Another set
*
+ * Tests whether @set is a subset of @larger_set.
*
* Return value: %TRUE if the @set is a subset of (or equal to) @larger_set, %FALSE otherwise.
*
@@ -311,10 +329,10 @@ hb_set_is_subset (const hb_set_t *set,
/**
* hb_set_set:
- * @set: a set.
- * @other:
- *
+ * @set: A set
+ * @other: Another set
*
+ * Makes the contents of @set equal to the contents of @other.
*
* Since: 0.9.2
**/
@@ -327,10 +345,10 @@ hb_set_set (hb_set_t *set,
/**
* hb_set_union:
- * @set: a set.
- * @other:
- *
+ * @set: A set
+ * @other: Another set
*
+ * Makes @set the union of @set and @other.
*
* Since: 0.9.2
**/
@@ -343,10 +361,10 @@ hb_set_union (hb_set_t *set,
/**
* hb_set_intersect:
- * @set: a set.
- * @other:
- *
+ * @set: A set
+ * @other: Another set
*
+ * Makes @set the intersection of @set and @other.
*
* Since: 0.9.2
**/
@@ -359,10 +377,10 @@ hb_set_intersect (hb_set_t *set,
/**
* hb_set_subtract:
- * @set: a set.
- * @other:
- *
+ * @set: A set
+ * @other: Another set
*
+ * Subtracts the contents of @other from @set.
*
* Since: 0.9.2
**/
@@ -375,10 +393,11 @@ hb_set_subtract (hb_set_t *set,
/**
* hb_set_symmetric_difference:
- * @set: a set.
- * @other:
- *
+ * @set: A set
+ * @other: Another set
*
+ * Makes @set the symmetric difference of @set
+ * and @other.
*
* Since: 0.9.2
**/
@@ -392,9 +411,9 @@ hb_set_symmetric_difference (hb_set_t *set,
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_set_invert:
- * @set: a set.
- *
+ * @set: A set
*
+ * Inverts the contents of @set.
*
* Since: 0.9.10
*
@@ -408,11 +427,11 @@ hb_set_invert (hb_set_t *set HB_UNUSED)
/**
* hb_set_get_population:
- * @set: a set.
+ * @set: A set
*
- * Returns the number of numbers in the set.
+ * Returns the number of elements in the set.
*
- * Return value: set population.
+ * Return value: The population of @set
*
* Since: 0.9.7
**/
@@ -424,11 +443,11 @@ hb_set_get_population (const hb_set_t *set)
/**
* hb_set_get_min:
- * @set: a set.
+ * @set: A set
*
- * Finds the minimum number in the set.
+ * Finds the smallest element in the set.
*
- * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
+ * Return value: minimum of @set, or %HB_SET_VALUE_INVALID if @set is empty.
*
* Since: 0.9.7
**/
@@ -440,11 +459,11 @@ hb_set_get_min (const hb_set_t *set)
/**
* hb_set_get_max:
- * @set: a set.
+ * @set: A set
*
- * Finds the maximum number in the set.
+ * Finds the largest element in the set.
*
- * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
+ * Return value: maximum of @set, or %HB_SET_VALUE_INVALID if @set is empty.
*
* Since: 0.9.7
**/
@@ -456,14 +475,15 @@ hb_set_get_max (const hb_set_t *set)
/**
* hb_set_next:
- * @set: a set.
- * @codepoint: (inout):
+ * @set: A set
+ * @codepoint: (inout): Input = Code point to query
+ * Output = Code point retrieved
*
- * Gets the next number in @set that is greater than current value of @codepoint.
+ * Fetches the next element in @set that is greater than current value of @codepoint.
*
* Set @codepoint to %HB_SET_VALUE_INVALID to get started.
*
- * Return value: whether there was a next value.
+ * Return value: %true if there was a next value, false otherwise
*
* Since: 0.9.2
**/
@@ -476,14 +496,15 @@ hb_set_next (const hb_set_t *set,
/**
* hb_set_previous:
- * @set: a set.
- * @codepoint: (inout):
+ * @set: A set
+ * @codepoint: (inout): Input = Code point to query
+ * Output = Code point retrieved
*
- * Gets the previous number in @set that is lower than current value of @codepoint.
+ * Fetches the previous element in @set that is lower than current value of @codepoint.
*
* Set @codepoint to %HB_SET_VALUE_INVALID to get started.
*
- * Return value: whether there was a previous value.
+ * Return value: %true if there was a previous value, false otherwise
*
* Since: 1.8.0
**/
@@ -496,16 +517,17 @@ hb_set_previous (const hb_set_t *set,
/**
* hb_set_next_range:
- * @set: a set.
- * @first: (out): output first codepoint in the range.
- * @last: (inout): input current last and output last codepoint in the range.
+ * @set: A set
+ * @first: (out): The first code point in the range
+ * @last: (inout): Input = The current last code point in the range
+ * Output = The last code point in the range
*
- * Gets the next consecutive range of numbers in @set that
+ * Fetches the next consecutive range of elements in @set that
* are greater than current value of @last.
*
* Set @last to %HB_SET_VALUE_INVALID to get started.
*
- * Return value: whether there was a next range.
+ * Return value: %true if there was a next range, false otherwise
*
* Since: 0.9.7
**/
@@ -519,16 +541,17 @@ hb_set_next_range (const hb_set_t *set,
/**
* hb_set_previous_range:
- * @set: a set.
- * @first: (inout): input current first and output first codepoint in the range.
- * @last: (out): output last codepoint in the range.
+ * @set: A set
+ * @first: (inout): Input = The current first code point in the range
+ * Output = The first code point in the range
+ * @last: (out): The last code point in the range
*
- * Gets the previous consecutive range of numbers in @set that
- * are less than current value of @first.
+ * Fetches the previous consecutive range of elements in @set that
+ * are greater than current value of @last.
*
* Set @first to %HB_SET_VALUE_INVALID to get started.
*
- * Return value: whether there was a previous range.
+ * Return value: %true if there was a previous range, false otherwise
*
* Since: 1.8.0
**/
diff --git a/thirdparty/harfbuzz/src/hb-set.h b/thirdparty/harfbuzz/src/hb-set.h
index ed0e05db2e..cafc36dbad 100644
--- a/thirdparty/harfbuzz/src/hb-set.h
+++ b/thirdparty/harfbuzz/src/hb-set.h
@@ -41,6 +41,15 @@ HB_BEGIN_DECLS
*/
#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
+/**
+ * hb_set_t:
+ *
+ * Data type for holding a set of integers. #hb_set_t's are
+ * used to gather and contain glyph IDs, Unicode code
+ * points, and various other collections of discrete
+ * values.
+ *
+ **/
typedef struct hb_set_t hb_set_t;
diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.cc b/thirdparty/harfbuzz/src/hb-shape-plan.cc
index 666470b4f1..65a5fc4512 100644
--- a/thirdparty/harfbuzz/src/hb-shape-plan.cc
+++ b/thirdparty/harfbuzz/src/hb-shape-plan.cc
@@ -37,10 +37,17 @@
* @short_description: Object representing a shaping plan
* @include: hb.h
*
- * Shape plans are not used for shaping directly, but can be access to query
- * certain information about how shaping will perform given a set of input
- * parameters (script, language, direction, features, etc.)
- * Most client would not need to deal with shape plans directly.
+ * Shape plans are an internal mechanism. Each plan contains state
+ * describing how HarfBuzz will shape a particular text segment, based on
+ * the combination of segment properties and the capabilities in the
+ * font face in use.
+ *
+ * Shape plans are not used for shaping directly, but can be queried to
+ * access certain information about how shaping will perform, given a set
+ * of specific input parameters (script, language, direction, features,
+ * etc.).
+ *
+ * Most client programs will not need to deal with shape plans directly.
**/
@@ -164,15 +171,16 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
/**
* hb_shape_plan_create: (Xconstructor)
- * @face:
- * @props:
- * @user_features: (array length=num_user_features):
- * @num_user_features:
- * @shaper_list: (array zero-terminated=1):
- *
+ * @face: #hb_face_t to use
+ * @props: The #hb_segment_properties_t of the segment
+ * @user_features: (array length=num_user_features): The list of user-selected features
+ * @num_user_features: The number of user-selected features
+ * @shaper_list: (array zero-terminated=1): List of shapers to try
*
+ * Constructs a shaping plan for a combination of @face, @user_features, @props,
+ * and @shaper_list.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): The shaping plan
*
* Since: 0.9.7
**/
@@ -189,6 +197,24 @@ hb_shape_plan_create (hb_face_t *face,
shaper_list);
}
+/**
+ * hb_shape_plan_create2: (Xconstructor)
+ * @face: #hb_face_t to use
+ * @props: The #hb_segment_properties_t of the segment
+ * @user_features: (array length=num_user_features): The list of user-selected features
+ * @num_user_features: The number of user-selected features
+ * @coords: (array length=num_coords): The list of variation-space coordinates
+ * @num_coords: The number of variation-space coordinates
+ * @shaper_list: (array zero-terminated=1): List of shapers to try
+ *
+ * The variable-font version of #hb_shape_plan_create.
+ * Constructs a shaping plan for a combination of @face, @user_features, @props,
+ * and @shaper_list, plus the variation-space coordinates @coords.
+ *
+ * Return value: (transfer full): The shaping plan
+ *
+ * Since: 1.4.0
+ **/
hb_shape_plan_t *
hb_shape_plan_create2 (hb_face_t *face,
const hb_segment_properties_t *props,
@@ -248,9 +274,9 @@ bail:
/**
* hb_shape_plan_get_empty:
*
+ * Fetches the singleton empty shaping plan.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): The empty shaping plan
*
* Since: 0.9.7
**/
@@ -262,11 +288,11 @@ hb_shape_plan_get_empty ()
/**
* hb_shape_plan_reference: (skip)
- * @shape_plan: a shape plan.
+ * @shape_plan: A shaping plan
*
+ * Increases the reference count on the given shaping plan.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): @shape_plan
*
* Since: 0.9.7
**/
@@ -278,9 +304,11 @@ hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
/**
* hb_shape_plan_destroy: (skip)
- * @shape_plan: a shape plan.
- *
+ * @shape_plan: A shaping plan
*
+ * Decreases the reference count on the given shaping plan. When the
+ * reference count reaches zero, the shaping plan is destroyed,
+ * freeing all memory.
*
* Since: 0.9.7
**/
@@ -298,13 +326,13 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
/**
* hb_shape_plan_set_user_data: (skip)
- * @shape_plan: a shape plan.
- * @key:
- * @data:
- * @destroy:
- * @replace:
- *
+ * @shape_plan: A shaping plan
+ * @key: The user-data key to set
+ * @data: A pointer to the user data
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
*
+ * Attaches a user-data key/data pair to the given shaping plan.
*
* Return value:
*
@@ -322,12 +350,13 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
/**
* hb_shape_plan_get_user_data: (skip)
- * @shape_plan: a shape plan.
- * @key:
+ * @shape_plan: A shaping plan
+ * @key: The user-data key to query
*
+ * Fetches the user data associated with the specified key,
+ * attached to the specified shaping plan.
*
- *
- * Return value: (transfer none):
+ * Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.7
**/
@@ -340,11 +369,11 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
/**
* hb_shape_plan_get_shaper:
- * @shape_plan: a shape plan.
- *
+ * @shape_plan: A shaping plan
*
+ * Fetches the shaper from a given shaping plan.
*
- * Return value: (transfer none):
+ * Return value: (transfer none): The shaper
*
* Since: 0.9.7
**/
@@ -355,26 +384,12 @@ hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
}
-/**
- * hb_shape_plan_execute:
- * @shape_plan: a shape plan.
- * @font: a font.
- * @buffer: a buffer.
- * @features: (array length=num_features):
- * @num_features:
- *
- *
- *
- * Return value:
- *
- * Since: 0.9.7
- **/
-hb_bool_t
-hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features)
+static bool
+_hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
{
DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
"num_features=%d shaper_func=%p, shaper_name=%s",
@@ -386,7 +401,8 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
return true;
assert (!hb_object_is_immutable (buffer));
- assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
+
+ buffer->assert_unicode ();
if (unlikely (hb_object_is_inert (shape_plan)))
return false;
@@ -412,6 +428,36 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
return false;
}
+/**
+ * hb_shape_plan_execute:
+ * @shape_plan: A shaping plan
+ * @font: The #hb_font_t to use
+ * @buffer: The #hb_buffer_t to work upon
+ * @features: (array length=num_features): Features to enable
+ * @num_features: The number of features to enable
+ *
+ * Executes the given shaping plan on the specified buffer, using
+ * the given @font and @features.
+ *
+ * Return value:
+ *
+ * Since: 0.9.7
+ **/
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ bool ret = _hb_shape_plan_execute_internal (shape_plan, font, buffer,
+ features, num_features);
+
+ if (ret && buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE)
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+
+ return ret;
+}
/*
@@ -420,15 +466,16 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
/**
* hb_shape_plan_create_cached:
- * @face:
- * @props:
- * @user_features: (array length=num_user_features):
- * @num_user_features:
- * @shaper_list: (array zero-terminated=1):
- *
+ * @face: #hb_face_t to use
+ * @props: The #hb_segment_properties_t of the segment
+ * @user_features: (array length=num_user_features): The list of user-selected features
+ * @num_user_features: The number of user-selected features
+ * @shaper_list: (array zero-terminated=1): List of shapers to try
*
+ * Creates a cached shaping plan suitable for reuse, for a combination
+ * of @face, @user_features, @props, and @shaper_list.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): The shaping plan
*
* Since: 0.9.7
**/
@@ -445,6 +492,25 @@ hb_shape_plan_create_cached (hb_face_t *face,
shaper_list);
}
+/**
+ * hb_shape_plan_create_cached2:
+ * @face: #hb_face_t to use
+ * @props: The #hb_segment_properties_t of the segment
+ * @user_features: (array length=num_user_features): The list of user-selected features
+ * @num_user_features: The number of user-selected features
+ * @coords: (array length=num_coords): The list of variation-space coordinates
+ * @num_coords: The number of variation-space coordinates
+ * @shaper_list: (array zero-terminated=1): List of shapers to try
+ *
+ * The variable-font version of #hb_shape_plan_create_cached.
+ * Creates a cached shaping plan suitable for reuse, for a combination
+ * of @face, @user_features, @props, and @shaper_list, plus the
+ * variation-space coordinates @coords.
+ *
+ * Return value: (transfer full): The shaping plan
+ *
+ * Since: 1.4.0
+ **/
hb_shape_plan_t *
hb_shape_plan_create_cached2 (hb_face_t *face,
const hb_segment_properties_t *props,
diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.h b/thirdparty/harfbuzz/src/hb-shape-plan.h
index b62ae7ca35..336524ee2f 100644
--- a/thirdparty/harfbuzz/src/hb-shape-plan.h
+++ b/thirdparty/harfbuzz/src/hb-shape-plan.h
@@ -36,6 +36,20 @@
HB_BEGIN_DECLS
+/**
+ * hb_shape_plan_t:
+ *
+ * Data type for holding a shaping plan.
+ *
+ * Shape plans contain information about how HarfBuzz will shape a
+ * particular text segment, based on the segment's properties and the
+ * capabilities in the font face in use.
+ *
+ * Shape plans can be queried about how shaping will perform, given a set
+ * of specific input parameters (script, language, direction, features,
+ * etc.).
+ *
+ **/
typedef struct hb_shape_plan_t hb_shape_plan_t;
HB_EXTERN hb_shape_plan_t *
diff --git a/thirdparty/harfbuzz/src/hb-shape.cc b/thirdparty/harfbuzz/src/hb-shape.cc
index 017fb91b69..a3debce397 100644
--- a/thirdparty/harfbuzz/src/hb-shape.cc
+++ b/thirdparty/harfbuzz/src/hb-shape.cc
@@ -132,8 +132,6 @@ hb_shape_full (hb_font_t *font,
unsigned int num_features,
const char * const *shaper_list)
{
- if (unlikely (hb_object_is_immutable (buffer))) return false;
-
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached2 (font->face, &buffer->props,
features, num_features,
font->coords, font->num_coords,
@@ -141,8 +139,6 @@ hb_shape_full (hb_font_t *font,
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
hb_shape_plan_destroy (shape_plan);
- if (res)
- buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
return res;
}
diff --git a/thirdparty/harfbuzz/src/hb-unicode.cc b/thirdparty/harfbuzz/src/hb-unicode.cc
index 36070a7f18..d7f6a6e130 100644
--- a/thirdparty/harfbuzz/src/hb-unicode.cc
+++ b/thirdparty/harfbuzz/src/hb-unicode.cc
@@ -40,11 +40,16 @@
* @include: hb.h
*
* Unicode functions are used to access Unicode character properties.
- * Client can pass its own Unicode functions to HarfBuzz, or access
- * the built-in Unicode functions that come with HarfBuzz.
+ * With these functions, client programs can query various properties from
+ * the Unicode Character Database for any code point, such as General
+ * Category (gc), Script (sc), Canonical Combining Class (ccc), etc.
*
- * With the Unicode functions, one can query variour Unicode character
- * properties, such as General Category, Script, Combining Class, etc.
+ * Client programs can optionally pass in their own Unicode functions
+ * that implement the same queries. The set of functions available is
+ * defined by the virtual methods in #hb_unicode_funcs_t.
+ *
+ * HarfBuzz provides built-in default functions for each method in
+ * #hb_unicode_funcs_t.
**/
@@ -133,6 +138,16 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED
#include "hb-icu.h"
#endif
+/**
+ * hb_unicode_funcs_get_default:
+ *
+ * Fetches a pointer to the default Unicode-functions structure that is used
+ * when no functions are explicitly set on #hb_buffer_t.
+ *
+ * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure
+ *
+ * Since: 0.9.2
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_get_default ()
{
@@ -155,11 +170,11 @@ hb_unicode_funcs_get_default ()
/**
* hb_unicode_funcs_create: (Xconstructor)
- * @parent: (nullable):
- *
+ * @parent: (nullable): Parent Unicode-functions structure
*
+ * Creates a new #hb_unicode_funcs_t structure of Unicode functions.
*
- * Return value: (transfer full):
+ * Return value: (transfer full): The Unicode-functions structure
*
* Since: 0.9.2
**/
@@ -203,9 +218,9 @@ DEFINE_NULL_INSTANCE (hb_unicode_funcs_t) =
/**
* hb_unicode_funcs_get_empty:
*
+ * Fetches the singleton empty Unicode-functions structure.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): The empty Unicode-functions structure
*
* Since: 0.9.2
**/
@@ -217,11 +232,11 @@ hb_unicode_funcs_get_empty ()
/**
* hb_unicode_funcs_reference: (skip)
- * @ufuncs: Unicode functions.
+ * @ufuncs: The Unicode-functions structure
*
+ * Increases the reference count on a Unicode-functions structure.
*
- *
- * Return value: (transfer full):
+ * Return value: (transfer full): The Unicode-functions structure
*
* Since: 0.9.2
**/
@@ -233,9 +248,11 @@ hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
/**
* hb_unicode_funcs_destroy: (skip)
- * @ufuncs: Unicode functions.
- *
+ * @ufuncs: The Unicode-functions structure
*
+ * Decreases the reference count on a Unicode-functions structure. When
+ * the reference count reaches zero, the Unicode-functions structure is
+ * destroyed, freeing all memory.
*
* Since: 0.9.2
**/
@@ -256,15 +273,15 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
/**
* hb_unicode_funcs_set_user_data: (skip)
- * @ufuncs: Unicode functions.
- * @key:
- * @data:
- * @destroy:
- * @replace:
+ * @ufuncs: The Unicode-functions structure
+ * @key: The user-data key
+ * @data: A pointer to the user data
+ * @destroy: (optional): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
*
+ * Attaches a user-data key/data pair to the specified Unicode-functions structure.
*
- *
- * Return value:
+ * Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@@ -280,12 +297,13 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_get_user_data: (skip)
- * @ufuncs: Unicode functions.
- * @key:
- *
+ * @ufuncs: The Unicode-functions structure
+ * @key: The user-data key to query
*
+ * Fetches the user-data associated with the specified key,
+ * attached to the specified Unicode-functions structure.
*
- * Return value: (transfer none):
+ * Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@@ -299,9 +317,10 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_make_immutable:
- * @ufuncs: Unicode functions.
- *
+ * @ufuncs: The Unicode-functions structure
*
+ * Makes the specified Unicode-functions structure
+ * immutable.
*
* Since: 0.9.2
**/
@@ -316,11 +335,12 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
/**
* hb_unicode_funcs_is_immutable:
- * @ufuncs: Unicode functions.
- *
+ * @ufuncs: The Unicode-functions structure
*
+ * Tests whether the specified Unicode-functions structure
+ * is immutable.
*
- * Return value:
+ * Return value: %true if @ufuncs is immutable, false otherwise
*
* Since: 0.9.2
**/
@@ -332,11 +352,12 @@ hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
/**
* hb_unicode_funcs_get_parent:
- * @ufuncs: Unicode functions.
+ * @ufuncs: The Unicode-functions structure
*
+ * Fetches the parent of the Unicode-functions structure
+ * @ufuncs.
*
- *
- * Return value:
+ * Return value: The parent Unicode-functions structure
*
* Since: 0.9.2
**/
@@ -389,14 +410,18 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
/**
* hb_unicode_compose:
- * @ufuncs: Unicode functions.
- * @a:
- * @b:
- * @ab: (out):
+ * @ufuncs: The Unicode-functions structure
+ * @a: The first Unicode code point to compose
+ * @b: The second Unicode code point to compose
+ * @ab: (out): The composition of @a, @b
*
+ * Fetches the composition of a sequence of two Unicode
+ * code points.
*
+ * Calls the composition function of the specified
+ * Unicode-functions structure @ufuncs.
*
- * Return value:
+ * Return value: %true if @a and @b composed, false otherwise
*
* Since: 0.9.2
**/
@@ -411,14 +436,17 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_decompose:
- * @ufuncs: Unicode functions.
- * @ab:
- * @a: (out):
- * @b: (out):
+ * @ufuncs: The Unicode-functions structure
+ * @ab: Unicode code point to decompose
+ * @a: (out): The first code point of the decomposition of @ab
+ * @b: (out): The second code point of the decomposition of @ab
*
+ * Fetches the decomposition of a Unicode code point.
*
+ * Calls the decomposition function of the specified
+ * Unicode-functions structure @ufuncs.
*
- * Return value:
+ * Return value: %true if @ab was decomposed, false otherwise
*
* Since: 0.9.2
**/
@@ -434,11 +462,12 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_unicode_decompose_compatibility:
- * @ufuncs: Unicode functions.
- * @u:
- * @decomposed: (out):
- *
+ * @ufuncs: The Unicode-functions structure
+ * @u: Code point to decompose
+ * @decomposed: (out): Compatibility decomposition of @u
*
+ * Fetches the compatibility decomposition of a Unicode
+ * code point. Deprecated.
*
* Return value:
*
diff --git a/thirdparty/harfbuzz/src/hb-unicode.h b/thirdparty/harfbuzz/src/hb-unicode.h
index 61b1b0ba1f..7ea0848c0f 100644
--- a/thirdparty/harfbuzz/src/hb-unicode.h
+++ b/thirdparty/harfbuzz/src/hb-unicode.h
@@ -48,7 +48,42 @@ HB_BEGIN_DECLS
#define HB_UNICODE_MAX 0x10FFFFu
-/* hb_unicode_general_category_t */
+/**
+ * hb_unicode_general_category_t:
+ * @HB_UNICODE_GENERAL_CATEGORY_CONTROL: [Cc]
+ * @HB_UNICODE_GENERAL_CATEGORY_FORMAT: [Cf]
+ * @HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED: [Cn]
+ * @HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE: [Co]
+ * @HB_UNICODE_GENERAL_CATEGORY_SURROGATE: [Cs]
+ * @HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER: [Ll]
+ * @HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER: [Lm]
+ * @HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER: [Lo]
+ * @HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER: [Lt]
+ * @HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER: [Lu]
+ * @HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK: [Mc]
+ * @HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK: [Me]
+ * @HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK: [Mn]
+ * @HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER: [Nd]
+ * @HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER: [Nl]
+ * @HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER: [No]
+ * @HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION: [Pc]
+ * @HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION: [Pd]
+ * @HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION: [Pe]
+ * @HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION: [Pf]
+ * @HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION: [Pi]
+ * @HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION: [Po]
+ * @HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION: [Ps]
+ * @HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL: [Sc]
+ * @HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL: [Sk]
+ * @HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL: [Sm]
+ * @HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL: [So]
+ * @HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR: [Zl]
+ * @HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR: [Zp]
+ * @HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR: [Zs]
+ *
+ * Data type for the "General_Category" (gc) property from
+ * the Unicode Character Database.
+ **/
/* Unicode Character Database property: General_Category (gc) */
typedef enum
@@ -85,13 +120,74 @@ typedef enum
HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR /* Zs */
} hb_unicode_general_category_t;
-/* hb_unicode_combining_class_t */
-
-/* Note: newer versions of Unicode may add new values. Clients should be ready to handle
- * any value in the 0..254 range being returned from hb_unicode_combining_class().
- */
-
-/* Unicode Character Database property: Canonical_Combining_Class (ccc) */
+/**
+ * hb_unicode_combining_class_t:
+ * @HB_UNICODE_COMBINING_CLASS_NOT_REORDERED: Spacing and enclosing marks; also many vowel and consonant signs, even if nonspacing
+ * @HB_UNICODE_COMBINING_CLASS_OVERLAY: Marks which overlay a base letter or symbol
+ * @HB_UNICODE_COMBINING_CLASS_NUKTA: Diacritic nukta marks in Brahmi-derived scripts
+ * @HB_UNICODE_COMBINING_CLASS_KANA_VOICING: Hiragana/Katakana voicing marks
+ * @HB_UNICODE_COMBINING_CLASS_VIRAMA: Viramas
+ * @HB_UNICODE_COMBINING_CLASS_CCC10: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC11: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC12: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC13: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC14: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC15: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC16: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC17: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC18: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC19: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC20: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC21: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC22: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC23: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC24: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC25: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC26: [Hebrew]
+ * @HB_UNICODE_COMBINING_CLASS_CCC27: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC28: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC29: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC30: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC31: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC32: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC33: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC34: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC35: [Arabic]
+ * @HB_UNICODE_COMBINING_CLASS_CCC36: [Syriac]
+ * @HB_UNICODE_COMBINING_CLASS_CCC84: [Telugu]
+ * @HB_UNICODE_COMBINING_CLASS_CCC91: [Telugu]
+ * @HB_UNICODE_COMBINING_CLASS_CCC103: [Thai]
+ * @HB_UNICODE_COMBINING_CLASS_CCC107: [Thai]
+ * @HB_UNICODE_COMBINING_CLASS_CCC118: [Lao]
+ * @HB_UNICODE_COMBINING_CLASS_CCC122: [Lao]
+ * @HB_UNICODE_COMBINING_CLASS_CCC129: [Tibetan]
+ * @HB_UNICODE_COMBINING_CLASS_CCC130: [Tibetan]
+ * @HB_UNICODE_COMBINING_CLASS_CCC133: [Tibetan]
+ * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: Marks attached at the bottom left
+ * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: Marks attached directly below
+ * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: Marks attached directly above
+ * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT: Marks attached at the top right
+ * @HB_UNICODE_COMBINING_CLASS_BELOW_LEFT: Distinct marks at the bottom left
+ * @HB_UNICODE_COMBINING_CLASS_BELOW: Distinct marks directly below
+ * @HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT: Distinct marks at the bottom right
+ * @HB_UNICODE_COMBINING_CLASS_LEFT: Distinct marks to the left
+ * @HB_UNICODE_COMBINING_CLASS_RIGHT: Distinct marks to the right
+ * @HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT: Distinct marks at the top left
+ * @HB_UNICODE_COMBINING_CLASS_ABOVE: Distinct marks directly above
+ * @HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT: Distinct marks at the top right
+ * @HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW: Distinct marks subtending two bases
+ * @HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE: Distinct marks extending above two bases
+ * @HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT: Greek iota subscript only
+ * @HB_UNICODE_COMBINING_CLASS_INVALID: Invalid combining class
+ *
+ * Data type for the Canonical_Combining_Class (ccc) property
+ * from the Unicode Character Database.
+ *
+ * <note>Note: newer versions of Unicode may add new values.
+ * Client programs should be ready to handle any value in the 0..254 range
+ * being returned from hb_unicode_combining_class().</note>
+ *
+ **/
typedef enum
{
HB_UNICODE_COMBINING_CLASS_NOT_REORDERED = 0,
@@ -176,6 +272,18 @@ typedef enum
* hb_unicode_funcs_t
*/
+/**
+ * hb_unicode_funcs_t:
+ *
+ * Data type containing a set of virtual methods used for
+ * accessing various Unicode character properties.
+ *
+ * HarfBuzz provides a default function for each of the
+ * methods in #hb_unicode_funcs_t. Client programs can implement
+ * their own replacements for the individual Unicode functions, as
+ * needed, and replace the default by calling the setter for a
+ * method.
+ **/
typedef struct hb_unicode_funcs_t hb_unicode_funcs_t;
@@ -227,40 +335,141 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
/* typedefs */
+/**
+ * hb_unicode_combining_class_func_t:
+ * @ufuncs: A Unicode-functions structure
+ * @unicode: The code point to query
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_unicode_funcs_t structure.
+ *
+ * This method should retrieve the Canonical Combining Class (ccc)
+ * property for a specified Unicode code point.
+ *
+ * Return value: The #hb_unicode_combining_class_t of @unicode
+ *
+ **/
typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
+
+/**
+ * hb_unicode_general_category_func_t:
+ * @ufuncs: A Unicode-functions structure
+ * @unicode: The code point to query
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_unicode_funcs_t structure.
+ *
+ * This method should retrieve the General Category property for
+ * a specified Unicode code point.
+ *
+ * Return value: The #hb_unicode_general_category_t of @unicode
+ *
+ **/
typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
+
+/**
+ * hb_unicode_mirroring_func_t:
+ * @ufuncs: A Unicode-functions structure
+ * @unicode: The code point to query
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_unicode_funcs_t structure.
+ *
+ * This method should retrieve the Bi-Directional Mirroring Glyph
+ * code point for a specified Unicode code point.
+ *
+ * <note>Note: If a code point does not have a specified
+ * Bi-Directional Mirroring Glyph defined, the method should
+ * return the original code point.</note>
+ *
+ * Return value: The #hb_codepoint_t of the Mirroring Glyph for @unicode
+ *
+ **/
typedef hb_codepoint_t (*hb_unicode_mirroring_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
+
+/**
+ * hb_unicode_script_func_t:
+ * @ufuncs: A Unicode-functions structure
+ * @unicode: The code point to query
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_unicode_funcs_t structure.
+ *
+ * This method should retrieve the Script property for a
+ * specified Unicode code point.
+ *
+ * Return value: The #hb_script_t of @unicode
+ *
+ **/
typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
+/**
+ * hb_unicode_compose_func_t:
+ * @ufuncs: A Unicode-functions structure
+ * @a: The first code point to compose
+ * @b: The second code point to compose
+ * @ab: (out): The composed code point
+ * @user_data: user data pointer passed by the caller
+ *
+ * A virtual method for the #hb_unicode_funcs_t structure.
+ *
+ * This method should compose a sequence of two input Unicode code
+ * points by canonical equivalence, returning the composed code
+ * point in a #hb_codepoint_t output parameter (if successful).
+ * The method must return an #hb_bool_t indicating the success
+ * of the composition.
+ *
+ * Return value: True is @a,@b composed, false otherwise
+ *
+ **/
typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t a,
hb_codepoint_t b,
hb_codepoint_t *ab,
void *user_data);
+
+/**
+ * hb_unicode_decompose_func_t:
+ * @ufuncs: A Unicode-functions structure
+ * @ab: The code point to decompose
+ * @a: (out): The first decomposed code point
+ * @b: (out): The second decomposed code point
+ * @user_data: user data pointer passed by the caller
+ *
+ * A virtual method for the #hb_unicode_funcs_t structure.
+ *
+ * This method should decompose an input Unicode code point,
+ * returning the two decomposed code points in #hb_codepoint_t
+ * output parameters (if successful). The method must return an
+ * #hb_bool_t indicating the success of the composition.
+ *
+ * Return value: True if @ab decomposed, false otherwise
+ *
+ **/
typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t ab,
hb_codepoint_t *a,
hb_codepoint_t *b,
void *user_data);
-/* setters */
+/* func setters */
/**
* hb_unicode_funcs_set_combining_class_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ufuncs: A Unicode-functions structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_unicode_combining_class_func_t.
*
* Since: 0.9.2
**/
@@ -271,12 +480,12 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_general_category_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ufuncs: A Unicode-functions structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_unicode_general_category_func_t.
*
* Since: 0.9.2
**/
@@ -287,12 +496,12 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_mirroring_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ufuncs: A Unicode-functions structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_unicode_mirroring_func_t.
*
* Since: 0.9.2
**/
@@ -303,12 +512,12 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_script_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ufuncs: A Unicode-functions structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_unicode_script_func_t.
*
* Since: 0.9.2
**/
@@ -319,12 +528,12 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_compose_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ufuncs: A Unicode-functions structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_unicode_compose_func_t.
*
* Since: 0.9.2
**/
@@ -335,12 +544,12 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_decompose_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
+ * @ufuncs: A Unicode-functions structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (optional): The function to call when @user_data is not needed anymore
*
+ * Sets the implementation function for #hb_unicode_decompose_func_t.
*
* Since: 0.9.2
**/
@@ -353,6 +562,13 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_combining_class:
+ * @ufuncs: The Unicode-functions structure
+ * @unicode: The code point to query
+ *
+ * Retrieves the Canonical Combining Class (ccc) property
+ * of code point @unicode.
+ *
+ * Return value: The #hb_unicode_combining_class_t of @unicode
*
* Since: 0.9.2
**/
@@ -362,6 +578,13 @@ hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_general_category:
+ * @ufuncs: The Unicode-functions structure
+ * @unicode: The code point to query
+ *
+ * Retrieves the General Category (gc) property
+ * of code point @unicode.
+ *
+ * Return value: The #hb_unicode_general_category_t of @unicode
*
* Since: 0.9.2
**/
@@ -371,6 +594,13 @@ hb_unicode_general_category (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_mirroring:
+ * @ufuncs: The Unicode-functions structure
+ * @unicode: The code point to query
+ *
+ * Retrieves the Bi-directional Mirroring Glyph code
+ * point defined for code point @unicode.
+ *
+ * Return value: The #hb_codepoint_t of the Mirroring Glyph for @unicode
*
* Since: 0.9.2
**/
@@ -380,6 +610,13 @@ hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_script:
+ * @ufuncs: The Unicode-functions structure
+ * @unicode: The code point to query
+ *
+ * Retrieves the #hb_script_t script to which code
+ * point @unicode belongs.
+ *
+ * Return value: The #hb_script_t of @unicode
*
* Since: 0.9.2
**/
@@ -387,12 +624,40 @@ HB_EXTERN hb_script_t
hb_unicode_script (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode);
+/**
+ * hb_unicode_compose:
+ * @ufuncs: The Unicode-functions structure
+ * @a: The first code point to compose
+ * @b: The second code point to compose
+ * @ab: (out): The composed code point
+ *
+ * Composes the code point sequence @a,@b by canonical equivalence into
+ * code point @ab.
+ *
+ * Return value: True is @a,@b composed, false otherwise
+ *
+ * Since: 0.9.2
+ **/
HB_EXTERN hb_bool_t
hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t a,
hb_codepoint_t b,
hb_codepoint_t *ab);
+/**
+ * hb_unicode_decompose:
+ * @ufuncs: The Unicode-functions structure
+ * @ab: The code point to decompose
+ * @a: (out): The first decomposed code point
+ * @b: (out): The second decomposed code point
+ *
+ * Decomposes code point @ab by canonical equivalence, into code points
+ * @a and @b.
+ *
+ * Return value: True if @ab decomposed, false otherwise
+ *
+ * Since: 0.9.2
+ **/
HB_EXTERN hb_bool_t
hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t ab,
diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h
index 92d61b8cdb..da377b9df6 100644
--- a/thirdparty/harfbuzz/src/hb-version.h
+++ b/thirdparty/harfbuzz/src/hb-version.h
@@ -38,9 +38,9 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 2
#define HB_VERSION_MINOR 7
-#define HB_VERSION_MICRO 2
+#define HB_VERSION_MICRO 4
-#define HB_VERSION_STRING "2.7.2"
+#define HB_VERSION_STRING "2.7.4"
#define HB_VERSION_ATLEAST(major,minor,micro) \
((major)*10000+(minor)*100+(micro) <= \
diff --git a/thirdparty/meshoptimizer/indexcodec.cpp b/thirdparty/meshoptimizer/indexcodec.cpp
index eeb541e5be..e4495b8586 100644
--- a/thirdparty/meshoptimizer/indexcodec.cpp
+++ b/thirdparty/meshoptimizer/indexcodec.cpp
@@ -4,14 +4,6 @@
#include <assert.h>
#include <string.h>
-#ifndef TRACE
-#define TRACE 0
-#endif
-
-#if TRACE
-#include <stdio.h>
-#endif
-
// This work is based on:
// Fabian Giesen. Simple lossless index buffer compression & follow-up. 2013
// Conor Stokes. Vertex Cache Optimised Index Buffer Compression. 2014
@@ -116,7 +108,7 @@ static unsigned int decodeVByte(const unsigned char*& data)
for (int i = 0; i < 4; ++i)
{
unsigned char group = *data++;
- result |= (group & 127) << shift;
+ result |= unsigned(group & 127) << shift;
shift += 7;
if (group < 128)
@@ -167,38 +159,6 @@ static void writeTriangle(void* destination, size_t offset, size_t index_size, u
}
}
-#if TRACE
-static size_t sortTop16(unsigned char dest[16], size_t stats[256])
-{
- size_t destsize = 0;
-
- for (size_t i = 0; i < 256; ++i)
- {
- size_t j = 0;
- for (; j < destsize; ++j)
- {
- if (stats[i] >= stats[dest[j]])
- {
- if (destsize < 16)
- destsize++;
-
- memmove(&dest[j + 1], &dest[j], destsize - 1 - j);
- dest[j] = (unsigned char)i;
- break;
- }
- }
-
- if (j == destsize && destsize < 16)
- {
- dest[destsize] = (unsigned char)i;
- destsize++;
- }
- }
-
- return destsize;
-}
-#endif
-
} // namespace meshopt
size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, const unsigned int* indices, size_t index_count)
@@ -207,11 +167,6 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons
assert(index_count % 3 == 0);
-#if TRACE
- size_t codestats[256] = {};
- size_t codeauxstats[256] = {};
-#endif
-
// the minimum valid encoding is header, 1 byte per triangle and a 16-byte codeaux table
if (buffer_size < 1 + index_count / 3 + 16)
return 0;
@@ -275,10 +230,6 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons
*code++ = (unsigned char)((fe << 4) | fec);
-#if TRACE
- codestats[code[-1]]++;
-#endif
-
// note that we need to update the last index since free indices are delta-encoded
if (fec == 15)
encodeIndex(data, c, last), last = c;
@@ -334,11 +285,6 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons
*data++ = codeaux;
}
-#if TRACE
- codestats[code[-1]]++;
- codeauxstats[codeaux]++;
-#endif
-
// note that we need to update the last index since free indices are delta-encoded
if (fea == 15)
encodeIndex(data, a, last), last = a;
@@ -387,30 +333,6 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons
assert(data >= buffer + index_count / 3 + 16);
assert(data <= buffer + buffer_size);
-#if TRACE
- unsigned char codetop[16], codeauxtop[16];
- size_t codetopsize = sortTop16(codetop, codestats);
- size_t codeauxtopsize = sortTop16(codeauxtop, codeauxstats);
-
- size_t sumcode = 0, sumcodeaux = 0;
- for (size_t i = 0; i < 256; ++i)
- sumcode += codestats[i], sumcodeaux += codeauxstats[i];
-
- size_t acccode = 0, acccodeaux = 0;
-
- printf("code\t\t\t\t\tcodeaux\n");
-
- for (size_t i = 0; i < codetopsize && i < codeauxtopsize; ++i)
- {
- acccode += codestats[codetop[i]];
- acccodeaux += codeauxstats[codeauxtop[i]];
-
- printf("%2d: %02x = %d (%.1f%% ..%.1f%%)\t\t%2d: %02x = %d (%.1f%% ..%.1f%%)\n",
- int(i), codetop[i], int(codestats[codetop[i]]), double(codestats[codetop[i]]) / double(sumcode) * 100, double(acccode) / double(sumcode) * 100,
- int(i), codeauxtop[i], int(codeauxstats[codeauxtop[i]]), double(codeauxstats[codeauxtop[i]]) / double(sumcodeaux) * 100, double(acccodeaux) / double(sumcodeaux) * 100);
- }
-#endif
-
return data - buffer;
}
diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h
index fde00f9c82..1714000384 100644
--- a/thirdparty/meshoptimizer/meshoptimizer.h
+++ b/thirdparty/meshoptimizer/meshoptimizer.h
@@ -239,7 +239,6 @@ MESHOPTIMIZER_API int meshopt_decodeVertexBuffer(void* destination, size_t verte
/**
* Vertex buffer filters
* These functions can be used to filter output of meshopt_decodeVertexBuffer in-place.
- * count must be aligned by 4 and stride is fixed for each function to facilitate SIMD implementation.
*
* meshopt_decodeFilterOct decodes octahedral encoding of a unit vector with K-bit (K <= 16) signed X/Y as an input; Z must store 1.0f.
* Each component is stored as an 8-bit or 16-bit normalized integer; stride must be equal to 4 or 8. W is preserved as is.
@@ -263,26 +262,27 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t ver
* The resulting index buffer references vertices from the original vertex buffer.
* If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended.
*
- * destination must contain enough space for the *source* index buffer (since optimization is iterative, this means index_count elements - *not* target_index_count!)
+ * destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)!
* vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation
+ * result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification
*/
-// -- GODOT start --
-//MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error);
-MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_resulting_error);
-// -- GODOT end --
+MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error);
/**
* Experimental: Mesh simplifier (sloppy)
* Reduces the number of triangles in the mesh, sacrificing mesh apperance for simplification performance
- * The algorithm doesn't preserve mesh topology but is always able to reach target triangle count.
+ * The algorithm doesn't preserve mesh topology but can stop short of the target goal based on target error.
* Returns the number of indices after simplification, with destination containing new index data
* The resulting index buffer references vertices from the original vertex buffer.
* If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended.
*
- * destination must contain enough space for the target index buffer
+ * destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)!
* vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
+ * target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation
+ * result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification
*/
-MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count);
+MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error);
/**
* Experimental: Point cloud simplifier
@@ -291,12 +291,20 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destinati
* The resulting index buffer references vertices from the original vertex buffer.
* If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended.
*
- * destination must contain enough space for the target index buffer
+ * destination must contain enough space for the target index buffer (target_vertex_count elements)
* vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
*/
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_vertex_count);
/**
+ * Experimental: Returns the error scaling factor used by the simplifier to convert between absolute and relative extents
+ *
+ * Absolute error must be *divided* by the scaling factor before passing it to meshopt_simplify as target_error
+ * Relative error returned by meshopt_simplify via result_error must be *multiplied* by the scaling factor to get absolute error.
+ */
+MESHOPTIMIZER_EXPERIMENTAL float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
+
+/**
* Mesh stripifier
* Converts a previously vertex cache optimized triangle list to triangle strip, stitching strips using restart index or degenerate triangles
* Returns the number of indices in the resulting strip, with destination containing new index data
@@ -525,9 +533,9 @@ inline size_t meshopt_encodeIndexSequence(unsigned char* buffer, size_t buffer_s
template <typename T>
inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const unsigned char* buffer, size_t buffer_size);
template <typename T>
-inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error);
+inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0);
template <typename T>
-inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count);
+inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0);
template <typename T>
inline size_t meshopt_stripify(T* destination, const T* indices, size_t index_count, size_t vertex_count, T restart_index);
template <typename T>
@@ -840,21 +848,21 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const
}
template <typename T>
-inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error)
+inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error)
{
meshopt_IndexAdapter<T> in(0, indices, index_count);
meshopt_IndexAdapter<T> out(destination, 0, index_count);
- return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error);
+ return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, result_error);
}
template <typename T>
-inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count)
+inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error)
{
meshopt_IndexAdapter<T> in(0, indices, index_count);
- meshopt_IndexAdapter<T> out(destination, 0, target_index_count);
+ meshopt_IndexAdapter<T> out(destination, 0, index_count);
- return meshopt_simplifySloppy(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count);
+ return meshopt_simplifySloppy(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, result_error);
}
template <typename T>
diff --git a/thirdparty/meshoptimizer/patches/simplifier_get_resulting_error.patch b/thirdparty/meshoptimizer/patches/simplifier_get_resulting_error.patch
deleted file mode 100644
index 1be38e45d2..0000000000
--- a/thirdparty/meshoptimizer/patches/simplifier_get_resulting_error.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-diff --git a/thirdparty/meshoptimizer/meshoptimizer.h b/thirdparty/meshoptimizer/meshoptimizer.h
-index a442d103c8..fde00f9c82 100644
---- a/thirdparty/meshoptimizer/meshoptimizer.h
-+++ b/thirdparty/meshoptimizer/meshoptimizer.h
-@@ -266,7 +266,10 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t ver
- * destination must contain enough space for the *source* index buffer (since optimization is iterative, this means index_count elements - *not* target_index_count!)
- * vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
- */
--MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error);
-+// -- GODOT start --
-+//MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error);
-+MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_resulting_error);
-+// -- GODOT end --
-
- /**
- * Experimental: Mesh simplifier (sloppy)
-diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp
-index bd523275ce..51cf634186 100644
---- a/thirdparty/meshoptimizer/simplifier.cpp
-+++ b/thirdparty/meshoptimizer/simplifier.cpp
-@@ -1143,7 +1143,10 @@ unsigned int* meshopt_simplifyDebugLoop = 0;
- unsigned int* meshopt_simplifyDebugLoopBack = 0;
- #endif
-
--size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error)
-+// -- GODOT start --
-+//size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error)
-+size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_resulting_error)
-+// -- GODOT end --
- {
- using namespace meshopt;
-
-@@ -1198,10 +1201,13 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- if (result != indices)
- memcpy(result, indices, index_count * sizeof(unsigned int));
-
-+// -- GODOT start --
- #if TRACE
- size_t pass_count = 0;
-- float worst_error = 0;
-+ //float worst_error = 0;
- #endif
-+ float worst_error = 0;
-+// -- GODOT end --
-
- Collapse* edge_collapses = allocator.allocate<Collapse>(index_count);
- unsigned int* collapse_order = allocator.allocate<unsigned int>(index_count);
-@@ -1213,6 +1219,12 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- // target_error input is linear; we need to adjust it to match quadricError units
- float error_limit = target_error * target_error;
-
-+// -- GODOT start --
-+ if (r_resulting_error) {
-+ *r_resulting_error = 1.0;
-+ }
-+// -- GODOT end --
-+
- while (result_count > target_index_count)
- {
- size_t edge_collapse_count = pickEdgeCollapses(edge_collapses, result, result_count, remap, vertex_kind, loop);
-@@ -1257,7 +1269,8 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- size_t new_count = remapIndexBuffer(result, result_count, collapse_remap);
- assert(new_count < result_count);
-
--#if TRACE
-+// -- GODOT start --
-+//#if TRACE
- float pass_error = 0.f;
- for (size_t i = 0; i < edge_collapse_count; ++i)
- {
-@@ -1267,15 +1280,24 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
- pass_error = c.error;
- }
-
-- pass_count++;
-+ //pass_count++;
- worst_error = (worst_error < pass_error) ? pass_error : worst_error;
-
-+#if TRACE
-+ pass_count++;
- printf("pass %d: triangles: %d -> %d, collapses: %d/%d (goal: %d), error: %e (limit %e goal %e)\n", int(pass_count), int(result_count / 3), int(new_count / 3), int(collapses), int(edge_collapse_count), int(edge_collapse_goal), pass_error, error_limit, error_goal);
- #endif
-+// -- GODOT end --
-
- result_count = new_count;
- }
-
-+// -- GODOT start --
-+ if (r_resulting_error) {
-+ *r_resulting_error = sqrt(worst_error);
-+ }
-+// -- GODOT end --
-+
- #if TRACE
- printf("passes: %d, worst error: %e\n", int(pass_count), worst_error);
- #endif
diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp
index b195a8cb5d..942db14461 100644
--- a/thirdparty/meshoptimizer/simplifier.cpp
+++ b/thirdparty/meshoptimizer/simplifier.cpp
@@ -6,7 +6,6 @@
#include <math.h>
#include <string.h>
-
#ifndef TRACE
#define TRACE 0
#endif
@@ -15,6 +14,12 @@
#include <stdio.h>
#endif
+#if TRACE
+#define TRACESTATS(i) stats[i]++;
+#else
+#define TRACESTATS(i) (void)0
+#endif
+
// This work is based on:
// Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997
// Michael Garland. Quadric-based polygonal surface simplification. 1999
@@ -26,28 +31,37 @@ namespace meshopt
struct EdgeAdjacency
{
+ struct Edge
+ {
+ unsigned int next;
+ unsigned int prev;
+ };
+
unsigned int* counts;
unsigned int* offsets;
- unsigned int* data;
+ Edge* data;
};
-static void buildEdgeAdjacency(EdgeAdjacency& adjacency, const unsigned int* indices, size_t index_count, size_t vertex_count, meshopt_Allocator& allocator)
+static void prepareEdgeAdjacency(EdgeAdjacency& adjacency, size_t index_count, size_t vertex_count, meshopt_Allocator& allocator)
{
- size_t face_count = index_count / 3;
-
- // allocate arrays
adjacency.counts = allocator.allocate<unsigned int>(vertex_count);
adjacency.offsets = allocator.allocate<unsigned int>(vertex_count);
- adjacency.data = allocator.allocate<unsigned int>(index_count);
+ adjacency.data = allocator.allocate<EdgeAdjacency::Edge>(index_count);
+}
+
+static void updateEdgeAdjacency(EdgeAdjacency& adjacency, const unsigned int* indices, size_t index_count, size_t vertex_count, const unsigned int* remap)
+{
+ size_t face_count = index_count / 3;
// fill edge counts
memset(adjacency.counts, 0, vertex_count * sizeof(unsigned int));
for (size_t i = 0; i < index_count; ++i)
{
- assert(indices[i] < vertex_count);
+ unsigned int v = remap ? remap[indices[i]] : indices[i];
+ assert(v < vertex_count);
- adjacency.counts[indices[i]]++;
+ adjacency.counts[v]++;
}
// fill offset table
@@ -66,9 +80,24 @@ static void buildEdgeAdjacency(EdgeAdjacency& adjacency, const unsigned int* ind
{
unsigned int a = indices[i * 3 + 0], b = indices[i * 3 + 1], c = indices[i * 3 + 2];
- adjacency.data[adjacency.offsets[a]++] = b;
- adjacency.data[adjacency.offsets[b]++] = c;
- adjacency.data[adjacency.offsets[c]++] = a;
+ if (remap)
+ {
+ a = remap[a];
+ b = remap[b];
+ c = remap[c];
+ }
+
+ adjacency.data[adjacency.offsets[a]].next = b;
+ adjacency.data[adjacency.offsets[a]].prev = c;
+ adjacency.offsets[a]++;
+
+ adjacency.data[adjacency.offsets[b]].next = c;
+ adjacency.data[adjacency.offsets[b]].prev = a;
+ adjacency.offsets[b]++;
+
+ adjacency.data[adjacency.offsets[c]].next = a;
+ adjacency.data[adjacency.offsets[c]].prev = b;
+ adjacency.offsets[c]++;
}
// fix offsets that have been disturbed by the previous pass
@@ -209,10 +238,10 @@ const unsigned char kHasOpposite[Kind_Count][Kind_Count] = {
static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int b)
{
unsigned int count = adjacency.counts[a];
- const unsigned int* data = adjacency.data + adjacency.offsets[a];
+ const EdgeAdjacency::Edge* edges = adjacency.data + adjacency.offsets[a];
for (size_t i = 0; i < count; ++i)
- if (data[i] == b)
+ if (edges[i].next == b)
return true;
return false;
@@ -234,11 +263,11 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
unsigned int vertex = unsigned(i);
unsigned int count = adjacency.counts[vertex];
- const unsigned int* data = adjacency.data + adjacency.offsets[vertex];
+ const EdgeAdjacency::Edge* edges = adjacency.data + adjacency.offsets[vertex];
for (size_t j = 0; j < count; ++j)
{
- unsigned int target = data[j];
+ unsigned int target = edges[j].next;
if (!hasEdge(adjacency, target, vertex))
{
@@ -249,10 +278,7 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
}
#if TRACE
- size_t lockedstats[4] = {};
-#define TRACELOCKED(i) lockedstats[i]++;
-#else
-#define TRACELOCKED(i) (void)0
+ size_t stats[4] = {};
#endif
for (size_t i = 0; i < vertex_count; ++i)
@@ -278,7 +304,7 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
else
{
result[i] = Kind_Locked;
- TRACELOCKED(0);
+ TRACESTATS(0);
}
}
else if (wedge[wedge[i]] == i)
@@ -299,20 +325,20 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
else
{
result[i] = Kind_Locked;
- TRACELOCKED(1);
+ TRACESTATS(1);
}
}
else
{
result[i] = Kind_Locked;
- TRACELOCKED(2);
+ TRACESTATS(2);
}
}
else
{
// more than one vertex maps to this one; we don't have classification available
result[i] = Kind_Locked;
- TRACELOCKED(3);
+ TRACESTATS(3);
}
}
else
@@ -325,7 +351,7 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
#if TRACE
printf("locked: many open edges %d, disconnected seam %d, many seam edges %d, many wedges %d\n",
- int(lockedstats[0]), int(lockedstats[1]), int(lockedstats[2]), int(lockedstats[3]));
+ int(stats[0]), int(stats[1]), int(stats[2]), int(stats[3]));
#endif
}
@@ -333,11 +359,8 @@ struct Vector3
{
float x, y, z;
};
-// -- GODOT start --
-//static void rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride)
-static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride)
-// -- GODOT end --
+static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride)
{
size_t vertex_stride_float = vertex_positions_stride / sizeof(float);
@@ -348,9 +371,12 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat
{
const float* v = vertex_positions_data + i * vertex_stride_float;
- result[i].x = v[0];
- result[i].y = v[1];
- result[i].z = v[2];
+ if (result)
+ {
+ result[i].x = v[0];
+ result[i].y = v[1];
+ result[i].z = v[2];
+ }
for (int j = 0; j < 3; ++j)
{
@@ -367,18 +393,19 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat
extent = (maxv[1] - minv[1]) < extent ? extent : (maxv[1] - minv[1]);
extent = (maxv[2] - minv[2]) < extent ? extent : (maxv[2] - minv[2]);
- float scale = extent == 0 ? 0.f : 1.f / extent;
-
- for (size_t i = 0; i < vertex_count; ++i)
+ if (result)
{
- result[i].x = (result[i].x - minv[0]) * scale;
- result[i].y = (result[i].y - minv[1]) * scale;
- result[i].z = (result[i].z - minv[2]) * scale;
+ float scale = extent == 0 ? 0.f : 1.f / extent;
+
+ for (size_t i = 0; i < vertex_count; ++i)
+ {
+ result[i].x = (result[i].x - minv[0]) * scale;
+ result[i].y = (result[i].y - minv[1]) * scale;
+ result[i].z = (result[i].z - minv[2]) * scale;
+ }
}
-// -- GODOT start --
- return extent;
-// -- GODOT end --
+ return extent;
}
struct Quadric
@@ -594,6 +621,48 @@ static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indic
}
}
+// does triangle ABC flip when C is replaced with D?
+static bool hasTriangleFlip(const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& d)
+{
+ Vector3 eb = {b.x - a.x, b.y - a.y, b.z - a.z};
+ Vector3 ec = {c.x - a.x, c.y - a.y, c.z - a.z};
+ Vector3 ed = {d.x - a.x, d.y - a.y, d.z - a.z};
+
+ Vector3 nbc = {eb.y * ec.z - eb.z * ec.y, eb.z * ec.x - eb.x * ec.z, eb.x * ec.y - eb.y * ec.x};
+ Vector3 nbd = {eb.y * ed.z - eb.z * ed.y, eb.z * ed.x - eb.x * ed.z, eb.x * ed.y - eb.y * ed.x};
+
+ return nbc.x * nbd.x + nbc.y * nbd.y + nbc.z * nbd.z < 0;
+}
+
+static bool hasTriangleFlips(const EdgeAdjacency& adjacency, const Vector3* vertex_positions, const unsigned int* collapse_remap, unsigned int i0, unsigned int i1)
+{
+ assert(collapse_remap[i0] == i0);
+ assert(collapse_remap[i1] == i1);
+
+ const Vector3& v0 = vertex_positions[i0];
+ const Vector3& v1 = vertex_positions[i1];
+
+ const EdgeAdjacency::Edge* edges = &adjacency.data[adjacency.offsets[i0]];
+ size_t count = adjacency.counts[i0];
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ unsigned int a = collapse_remap[edges[i].next];
+ unsigned int b = collapse_remap[edges[i].prev];
+
+ // skip triangles that get collapsed
+ // note: this is mathematically redundant as if either of these is true, the dot product in hasTriangleFlip should be 0
+ if (a == i1 || b == i1)
+ continue;
+
+ // early-out when at least one triangle flips due to a collapse
+ if (hasTriangleFlip(vertex_positions[a], vertex_positions[b], v0, v1))
+ return true;
+ }
+
+ return false;
+}
+
static size_t pickEdgeCollapses(Collapse* collapses, const unsigned int* indices, size_t index_count, const unsigned int* remap, const unsigned char* vertex_kind, const unsigned int* loop)
{
size_t collapse_count = 0;
@@ -704,7 +773,7 @@ static void dumpEdgeCollapses(const Collapse* collapses, size_t collapse_count,
for (int k0 = 0; k0 < Kind_Count; ++k0)
for (int k1 = 0; k1 < Kind_Count; ++k1)
if (ckinds[k0][k1])
- printf("collapses %d -> %d: %d, min error %e\n", k0, k1, int(ckinds[k0][k1]), cerrors[k0][k1]);
+ printf("collapses %d -> %d: %d, min error %e\n", k0, k1, int(ckinds[k0][k1]), ckinds[k0][k1] ? sqrtf(cerrors[k0][k1]) : 0.f);
}
static void dumpLockedCollapses(const unsigned int* indices, size_t index_count, const unsigned char* vertex_kind)
@@ -772,22 +841,38 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse
}
}
-static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* collapse_locked, Quadric* vertex_quadrics, const Collapse* collapses, size_t collapse_count, const unsigned int* collapse_order, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_kind, size_t triangle_collapse_goal, float error_goal, float error_limit)
+static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* collapse_locked, Quadric* vertex_quadrics, const Collapse* collapses, size_t collapse_count, const unsigned int* collapse_order, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_kind, const Vector3* vertex_positions, const EdgeAdjacency& adjacency, size_t triangle_collapse_goal, float error_limit, float& result_error)
{
size_t edge_collapses = 0;
size_t triangle_collapses = 0;
+ // most collapses remove 2 triangles; use this to establish a bound on the pass in terms of error limit
+ // note that edge_collapse_goal is an estimate; triangle_collapse_goal will be used to actually limit collapses
+ size_t edge_collapse_goal = triangle_collapse_goal / 2;
+
+#if TRACE
+ size_t stats[4] = {};
+#endif
+
for (size_t i = 0; i < collapse_count; ++i)
{
const Collapse& c = collapses[collapse_order[i]];
+ TRACESTATS(0);
+
if (c.error > error_limit)
break;
- if (c.error > error_goal && triangle_collapses > triangle_collapse_goal / 10)
+ if (triangle_collapses >= triangle_collapse_goal)
break;
- if (triangle_collapses >= triangle_collapse_goal)
+ // we limit the error in each pass based on the error of optimal last collapse; since many collapses will be locked
+ // as they will share vertices with other successfull collapses, we need to increase the acceptable error by some factor
+ float error_goal = edge_collapse_goal < collapse_count ? 1.5f * collapses[collapse_order[edge_collapse_goal]].error : FLT_MAX;
+
+ // on average, each collapse is expected to lock 6 other collapses; to avoid degenerate passes on meshes with odd
+ // topology, we only abort if we got over 1/6 collapses accordingly.
+ if (c.error > error_goal && triangle_collapses > triangle_collapse_goal / 6)
break;
unsigned int i0 = c.v0;
@@ -800,7 +885,19 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char*
// it's important to not move the vertices twice since it complicates the tracking/remapping logic
// it's important to not move other vertices towards a moved vertex to preserve error since we don't re-rank collapses mid-pass
if (collapse_locked[r0] | collapse_locked[r1])
+ {
+ TRACESTATS(1);
+ continue;
+ }
+
+ if (hasTriangleFlips(adjacency, vertex_positions, collapse_remap, r0, r1))
+ {
+ // adjust collapse goal since this collapse is invalid and shouldn't factor into error goal
+ edge_collapse_goal++;
+
+ TRACESTATS(2);
continue;
+ }
assert(collapse_remap[r0] == r0);
assert(collapse_remap[r1] == r1);
@@ -842,8 +939,18 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char*
// border edges collapse 1 triangle, other edges collapse 2 or more
triangle_collapses += (vertex_kind[i0] == Kind_Border) ? 1 : 2;
edge_collapses++;
+
+ result_error = result_error < c.error ? c.error : result_error;
}
+#if TRACE
+ float error_goal_perfect = edge_collapse_goal < collapse_count ? collapses[collapse_order[edge_collapse_goal]].error : 0.f;
+
+ printf("removed %d triangles, error %e (goal %e); evaluated %d/%d collapses (done %d, skipped %d, invalid %d)\n",
+ int(triangle_collapses), sqrtf(result_error), sqrtf(error_goal_perfect),
+ int(stats[0]), int(collapse_count), int(edge_collapses), int(stats[1]), int(stats[2]));
+#endif
+
return edge_collapses;
}
@@ -1151,10 +1258,7 @@ unsigned int* meshopt_simplifyDebugLoop = 0;
unsigned int* meshopt_simplifyDebugLoopBack = 0;
#endif
-// -- GODOT start --
-//size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error)
-size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_resulting_error)
-// -- GODOT end --
+size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error)
{
using namespace meshopt;
@@ -1169,7 +1273,8 @@ size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices,
// build adjacency information
EdgeAdjacency adjacency = {};
- buildEdgeAdjacency(adjacency, indices, index_count, vertex_count, allocator);
+ prepareEdgeAdjacency(adjacency, index_count, vertex_count, allocator);
+ updateEdgeAdjacency(adjacency, indices, index_count, vertex_count, NULL);
// build position remap that maps each vertex to the one with identical position
unsigned int* remap = allocator.allocate<unsigned int>(vertex_count);
@@ -1198,10 +1303,7 @@ size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices,
#endif
Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count);
-// -- GODOT start --
- //rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride);
- float extent = rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride);
-// -- GODOT end --
+ rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride);
Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count);
memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric));
@@ -1212,13 +1314,9 @@ size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices,
if (result != indices)
memcpy(result, indices, index_count * sizeof(unsigned int));
-// -- GODOT start --
#if TRACE
size_t pass_count = 0;
- //float worst_error = 0;
#endif
- float worst_error = 0;
-// -- GODOT end --
Collapse* edge_collapses = allocator.allocate<Collapse>(index_count);
unsigned int* collapse_order = allocator.allocate<unsigned int>(index_count);
@@ -1226,18 +1324,16 @@ size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices,
unsigned char* collapse_locked = allocator.allocate<unsigned char>(vertex_count);
size_t result_count = index_count;
+ float result_error = 0;
// target_error input is linear; we need to adjust it to match quadricError units
float error_limit = target_error * target_error;
-// -- GODOT start --
- if (r_resulting_error) {
- *r_resulting_error = 1.0;
- }
-// -- GODOT end --
-
while (result_count > target_index_count)
{
+ // note: throughout the simplification process adjacency structure reflects welded topology for result-in-progress
+ updateEdgeAdjacency(adjacency, result, result_count, vertex_count, remap);
+
size_t edge_collapse_count = pickEdgeCollapses(edge_collapses, result, result_count, remap, vertex_kind, loop);
// no edges can be collapsed any more due to topology restrictions
@@ -1252,23 +1348,18 @@ size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices,
sortEdgeCollapses(collapse_order, edge_collapses, edge_collapse_count);
- // most collapses remove 2 triangles; use this to establish a bound on the pass in terms of error limit
- // note that edge_collapse_goal is an estimate; triangle_collapse_goal will be used to actually limit collapses
size_t triangle_collapse_goal = (result_count - target_index_count) / 3;
- size_t edge_collapse_goal = triangle_collapse_goal / 2;
-
- // we limit the error in each pass based on the error of optimal last collapse; since many collapses will be locked
- // as they will share vertices with other successfull collapses, we need to increase the acceptable error by this factor
- const float kPassErrorBound = 1.5f;
-
- float error_goal = edge_collapse_goal < edge_collapse_count ? edge_collapses[collapse_order[edge_collapse_goal]].error * kPassErrorBound : FLT_MAX;
for (size_t i = 0; i < vertex_count; ++i)
collapse_remap[i] = unsigned(i);
memset(collapse_locked, 0, vertex_count);
- size_t collapses = performEdgeCollapses(collapse_remap, collapse_locked, vertex_quadrics, edge_collapses, edge_collapse_count, collapse_order, remap, wedge, vertex_kind, triangle_collapse_goal, error_goal, error_limit);
+#if TRACE
+ printf("pass %d: ", int(pass_count++));
+#endif
+
+ size_t collapses = performEdgeCollapses(collapse_remap, collapse_locked, vertex_quadrics, edge_collapses, edge_collapse_count, collapse_order, remap, wedge, vertex_kind, vertex_positions, adjacency, triangle_collapse_goal, error_limit, result_error);
// no edges can be collapsed any more due to hitting the error limit or triangle collapse limit
if (collapses == 0)
@@ -1280,37 +1371,11 @@ size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices,
size_t new_count = remapIndexBuffer(result, result_count, collapse_remap);
assert(new_count < result_count);
-// -- GODOT start --
-//#if TRACE
- float pass_error = 0.f;
- for (size_t i = 0; i < edge_collapse_count; ++i)
- {
- Collapse& c = edge_collapses[collapse_order[i]];
-
- if (collapse_remap[c.v0] == c.v1)
- pass_error = c.error;
- }
-
- //pass_count++;
- worst_error = (worst_error < pass_error) ? pass_error : worst_error;
-
-#if TRACE
- pass_count++;
- printf("pass %d: triangles: %d -> %d, collapses: %d/%d (goal: %d), error: %e (limit %e goal %e)\n", int(pass_count), int(result_count / 3), int(new_count / 3), int(collapses), int(edge_collapse_count), int(edge_collapse_goal), pass_error, error_limit, error_goal);
-#endif
-// -- GODOT end --
-
result_count = new_count;
}
-// -- GODOT start --
- if (r_resulting_error) {
- *r_resulting_error = sqrt(worst_error) * extent;
- }
-// -- GODOT end --
-
#if TRACE
- printf("passes: %d, worst error: %e\n", int(pass_count), worst_error);
+ printf("result: %d triangles, error: %e; total %d passes\n", int(result_count), sqrtf(result_error), int(pass_count));
#endif
#if TRACE > 1
@@ -1328,10 +1393,14 @@ size_t meshopt_simplify(unsigned int *destination, const unsigned int *indices,
memcpy(meshopt_simplifyDebugLoopBack, loopback, vertex_count * sizeof(unsigned int));
#endif
+ // result_error is quadratic; we need to remap it back to linear
+ if (out_result_error)
+ *out_result_error = sqrtf(result_error);
+
return result_count;
}
-size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count)
+size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error)
{
using namespace meshopt;
@@ -1343,9 +1412,6 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind
// we expect to get ~2 triangles/vertex in the output
size_t target_cell_count = target_index_count / 6;
- if (target_cell_count == 0)
- return 0;
-
meshopt_Allocator allocator;
Vector3* vertex_positions = allocator.allocate<Vector3>(vertex_count);
@@ -1362,18 +1428,25 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind
const int kInterpolationPasses = 5;
// invariant: # of triangles in min_grid <= target_count
- int min_grid = 0;
+ int min_grid = int(1.f / (target_error < 1e-3f ? 1e-3f : target_error));
int max_grid = 1025;
size_t min_triangles = 0;
size_t max_triangles = index_count / 3;
+ // when we're error-limited, we compute the triangle count for the min. size; this accelerates convergence and provides the correct answer when we can't use a larger grid
+ if (min_grid > 1)
+ {
+ computeVertexIds(vertex_ids, vertex_positions, vertex_count, min_grid);
+ min_triangles = countTriangles(vertex_ids, indices, index_count);
+ }
+
// instead of starting in the middle, let's guess as to what the answer might be! triangle count usually grows as a square of grid size...
int next_grid_size = int(sqrtf(float(target_cell_count)) + 0.5f);
for (int pass = 0; pass < 10 + kInterpolationPasses; ++pass)
{
- assert(min_triangles < target_index_count / 3);
- assert(max_grid - min_grid > 1);
+ if (min_triangles >= target_index_count / 3 || max_grid - min_grid <= 1)
+ break;
// we clamp the prediction of the grid size to make sure that the search converges
int grid_size = next_grid_size;
@@ -1402,16 +1475,18 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind
max_triangles = triangles;
}
- if (triangles == target_index_count / 3 || max_grid - min_grid <= 1)
- break;
-
// we start by using interpolation search - it usually converges faster
// however, interpolation search has a worst case of O(N) so we switch to binary search after a few iterations which converges in O(logN)
next_grid_size = (pass < kInterpolationPasses) ? int(tip + 0.5f) : (min_grid + max_grid) / 2;
}
if (min_triangles == 0)
+ {
+ if (out_result_error)
+ *out_result_error = 1.f;
+
return 0;
+ }
// build vertex->cell association by mapping all vertices with the same quantized position to the same cell
size_t table_size = hashBuckets2(vertex_count);
@@ -1434,18 +1509,26 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind
fillCellRemap(cell_remap, cell_errors, cell_count, vertex_cells, cell_quadrics, vertex_positions, vertex_count);
+ // compute error
+ float result_error = 0.f;
+
+ for (size_t i = 0; i < cell_count; ++i)
+ result_error = result_error < cell_errors[i] ? cell_errors[i] : result_error;
+
// collapse triangles!
// note that we need to filter out triangles that we've already output because we very frequently generate redundant triangles between cells :(
size_t tritable_size = hashBuckets2(min_triangles);
unsigned int* tritable = allocator.allocate<unsigned int>(tritable_size);
size_t write = filterTriangles(destination, tritable, tritable_size, indices, index_count, vertex_cells, cell_remap);
- assert(write <= target_index_count);
#if TRACE
- printf("result: %d cells, %d triangles (%d unfiltered)\n", int(cell_count), int(write / 3), int(min_triangles));
+ printf("result: %d cells, %d triangles (%d unfiltered), error %e\n", int(cell_count), int(write / 3), int(min_triangles), sqrtf(result_error));
#endif
+ if (out_result_error)
+ *out_result_error = sqrtf(result_error);
+
return write;
}
@@ -1560,3 +1643,15 @@ size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_pos
return cell_count;
}
+
+float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
+{
+ using namespace meshopt;
+
+ assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
+ assert(vertex_positions_stride % sizeof(float) == 0);
+
+ float extent = rescalePositions(NULL, vertex_positions, vertex_count, vertex_positions_stride);
+
+ return extent;
+}
diff --git a/thirdparty/meshoptimizer/vertexcodec.cpp b/thirdparty/meshoptimizer/vertexcodec.cpp
index 784c9a13db..2cbfaac367 100644
--- a/thirdparty/meshoptimizer/vertexcodec.cpp
+++ b/thirdparty/meshoptimizer/vertexcodec.cpp
@@ -80,14 +80,6 @@
#include <wasm_simd128.h>
#endif
-#ifndef TRACE
-#define TRACE 0
-#endif
-
-#if TRACE
-#include <stdio.h>
-#endif
-
#ifdef SIMD_WASM
#define wasmx_splat_v32x4(v, i) wasm_v32x4_shuffle(v, v, i, i, i, i)
#define wasmx_unpacklo_v8x16(a, b) wasm_v8x16_shuffle(a, b, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23)
@@ -133,19 +125,6 @@ inline unsigned char unzigzag8(unsigned char v)
return -(v & 1) ^ (v >> 1);
}
-#if TRACE
-struct Stats
-{
- size_t size;
- size_t header;
- size_t bitg[4];
- size_t bitb[4];
-};
-
-Stats* bytestats;
-Stats vertexstats[256];
-#endif
-
static bool encodeBytesGroupZero(const unsigned char* buffer)
{
for (size_t i = 0; i < kByteGroupSize; ++i)
@@ -267,17 +246,8 @@ static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end,
assert(data + best_size == next);
data = next;
-
-#if TRACE > 1
- bytestats->bitg[bitslog2]++;
- bytestats->bitb[bitslog2] += best_size;
-#endif
}
-#if TRACE > 1
- bytestats->header += header_size;
-#endif
-
return data;
}
@@ -306,19 +276,9 @@ static unsigned char* encodeVertexBlock(unsigned char* data, unsigned char* data
vertex_offset += vertex_size;
}
-#if TRACE
- const unsigned char* olddata = data;
- bytestats = &vertexstats[k];
-#endif
-
data = encodeBytes(data, data_end, buffer, (vertex_count + kByteGroupSize - 1) & ~(kByteGroupSize - 1));
if (!data)
return 0;
-
-#if TRACE
- bytestats = 0;
- vertexstats[k].size += data - olddata;
-#endif
}
memcpy(last_vertex, &vertex_data[vertex_size * (vertex_count - 1)], vertex_size);
@@ -1086,10 +1046,6 @@ size_t meshopt_encodeVertexBuffer(unsigned char* buffer, size_t buffer_size, con
assert(vertex_size > 0 && vertex_size <= 256);
assert(vertex_size % 4 == 0);
-#if TRACE
- memset(vertexstats, 0, sizeof(vertexstats));
-#endif
-
const unsigned char* vertex_data = static_cast<const unsigned char*>(vertices);
unsigned char* data = buffer;
@@ -1142,28 +1098,6 @@ size_t meshopt_encodeVertexBuffer(unsigned char* buffer, size_t buffer_size, con
assert(data >= buffer + tail_size);
assert(data <= buffer + buffer_size);
-#if TRACE
- size_t total_size = data - buffer;
-
- for (size_t k = 0; k < vertex_size; ++k)
- {
- const Stats& vsk = vertexstats[k];
-
- printf("%2d: %d bytes\t%.1f%%\t%.1f bpv", int(k), int(vsk.size), double(vsk.size) / double(total_size) * 100, double(vsk.size) / double(vertex_count) * 8);
-
-#if TRACE > 1
- printf("\t\thdr %d bytes\tbit0 %d (%d bytes)\tbit1 %d (%d bytes)\tbit2 %d (%d bytes)\tbit3 %d (%d bytes)",
- int(vsk.header),
- int(vsk.bitg[0]), int(vsk.bitb[0]),
- int(vsk.bitg[1]), int(vsk.bitb[1]),
- int(vsk.bitg[2]), int(vsk.bitb[2]),
- int(vsk.bitg[3]), int(vsk.bitb[3]));
-#endif
-
- printf("\n");
- }
-#endif
-
return data - buffer;
}
diff --git a/thirdparty/meshoptimizer/vertexfilter.cpp b/thirdparty/meshoptimizer/vertexfilter.cpp
index e7ad2c9d39..39946f46ed 100644
--- a/thirdparty/meshoptimizer/vertexfilter.cpp
+++ b/thirdparty/meshoptimizer/vertexfilter.cpp
@@ -2,6 +2,7 @@
#include "meshoptimizer.h"
#include <math.h>
+#include <string.h>
// The block below auto-detects SIMD ISA that can be used on the target platform
#ifndef MESHOPTIMIZER_NO_SIMD
@@ -159,6 +160,25 @@ static void decodeFilterExp(unsigned int* data, size_t count)
#endif
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
+template <typename T> static void dispatchSimd(void (*process)(T*, size_t), T* data, size_t count, size_t stride)
+{
+ assert(stride <= 4);
+
+ size_t count4 = count & ~size_t(3);
+ process(data, count4);
+
+ if (count4 < count)
+ {
+ T tail[4 * 4] = {}; // max stride 4, max count 4
+ size_t tail_size = (count - count4) * stride * sizeof(T);
+ assert(tail_size <= sizeof(tail));
+
+ memcpy(tail, data + count4 * stride, tail_size);
+ process(tail, count - count4);
+ memcpy(data + count4 * stride, tail, tail_size);
+ }
+}
+
inline uint64_t rotateleft64(uint64_t v, int x)
{
#if defined(_MSC_VER) && !defined(__clang__)
@@ -775,14 +795,13 @@ void meshopt_decodeFilterOct(void* buffer, size_t vertex_count, size_t vertex_si
{
using namespace meshopt;
- assert(vertex_count % 4 == 0);
assert(vertex_size == 4 || vertex_size == 8);
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
if (vertex_size == 4)
- decodeFilterOctSimd(static_cast<signed char*>(buffer), vertex_count);
+ dispatchSimd(decodeFilterOctSimd, static_cast<signed char*>(buffer), vertex_count, 4);
else
- decodeFilterOctSimd(static_cast<short*>(buffer), vertex_count);
+ dispatchSimd(decodeFilterOctSimd, static_cast<short*>(buffer), vertex_count, 4);
#else
if (vertex_size == 4)
decodeFilterOct(static_cast<signed char*>(buffer), vertex_count);
@@ -795,12 +814,11 @@ void meshopt_decodeFilterQuat(void* buffer, size_t vertex_count, size_t vertex_s
{
using namespace meshopt;
- assert(vertex_count % 4 == 0);
assert(vertex_size == 8);
(void)vertex_size;
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
- decodeFilterQuatSimd(static_cast<short*>(buffer), vertex_count);
+ dispatchSimd(decodeFilterQuatSimd, static_cast<short*>(buffer), vertex_count, 4);
#else
decodeFilterQuat(static_cast<short*>(buffer), vertex_count);
#endif
@@ -810,11 +828,10 @@ void meshopt_decodeFilterExp(void* buffer, size_t vertex_count, size_t vertex_si
{
using namespace meshopt;
- assert(vertex_count % 4 == 0);
assert(vertex_size % 4 == 0);
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
- decodeFilterExpSimd(static_cast<unsigned int*>(buffer), vertex_count * (vertex_size / 4));
+ dispatchSimd(decodeFilterExpSimd, static_cast<unsigned int*>(buffer), vertex_count * (vertex_size / 4), 1);
#else
decodeFilterExp(static_cast<unsigned int*>(buffer), vertex_count * (vertex_size / 4));
#endif
diff --git a/thirdparty/misc/patches/polypartition-godot-types.patch b/thirdparty/misc/patches/polypartition-godot-types.patch
new file mode 100644
index 0000000000..59fdb2707c
--- /dev/null
+++ b/thirdparty/misc/patches/polypartition-godot-types.patch
@@ -0,0 +1,819 @@
+diff --git a/thirdparty/misc/polypartition.cpp b/thirdparty/misc/polypartition.cpp
+index 3a8a6efa8319..4f1b6dcb21d8 100644
+--- a/thirdparty/misc/polypartition.cpp
++++ b/thirdparty/misc/polypartition.cpp
+@@ -23,10 +23,7 @@
+
+ #include "polypartition.h"
+
+-#include <math.h>
+-#include <string.h>
+ #include <algorithm>
+-#include <vector>
+
+ TPPLPoly::TPPLPoly() {
+ hole = false;
+@@ -186,7 +183,7 @@ int TPPLPartition::Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TP
+ // Removes holes from inpolys by merging them with non-holes.
+ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+ TPPLPolyList polys;
+- TPPLPolyList::iterator holeiter, polyiter, iter, iter2;
++ TPPLPolyList::Element *holeiter, *polyiter, *iter, *iter2;
+ long i, i2, holepointindex, polypointindex;
+ TPPLPoint holepoint, polypoint, bestpolypoint;
+ TPPLPoint linep1, linep2;
+@@ -198,15 +195,15 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+
+ // Check for the trivial case of no holes.
+ hasholes = false;
+- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) {
+- if (iter->IsHole()) {
++ for (iter = inpolys->front(); iter; iter = iter->next()) {
++ if (iter->get().IsHole()) {
+ hasholes = true;
+ break;
+ }
+ }
+ if (!hasholes) {
+- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) {
+- outpolys->push_back(*iter);
++ for (iter = inpolys->front(); iter; iter = iter->next()) {
++ outpolys->push_back(iter->get());
+ }
+ return 1;
+ }
+@@ -216,8 +213,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+ while (1) {
+ // Find the hole point with the largest x.
+ hasholes = false;
+- for (iter = polys.begin(); iter != polys.end(); iter++) {
+- if (!iter->IsHole()) {
++ for (iter = polys.front(); iter; iter = iter->next()) {
++ if (!iter->get().IsHole()) {
+ continue;
+ }
+
+@@ -227,8 +224,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+ holepointindex = 0;
+ }
+
+- for (i = 0; i < iter->GetNumPoints(); i++) {
+- if (iter->GetPoint(i).x > holeiter->GetPoint(holepointindex).x) {
++ for (i = 0; i < iter->get().GetNumPoints(); i++) {
++ if (iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) {
+ holeiter = iter;
+ holepointindex = i;
+ }
+@@ -237,24 +234,24 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+ if (!hasholes) {
+ break;
+ }
+- holepoint = holeiter->GetPoint(holepointindex);
++ holepoint = holeiter->get().GetPoint(holepointindex);
+
+ pointfound = false;
+- for (iter = polys.begin(); iter != polys.end(); iter++) {
+- if (iter->IsHole()) {
++ for (iter = polys.front(); iter; iter = iter->next()) {
++ if (iter->get().IsHole()) {
+ continue;
+ }
+- for (i = 0; i < iter->GetNumPoints(); i++) {
+- if (iter->GetPoint(i).x <= holepoint.x) {
++ for (i = 0; i < iter->get().GetNumPoints(); i++) {
++ if (iter->get().GetPoint(i).x <= holepoint.x) {
+ continue;
+ }
+- if (!InCone(iter->GetPoint((i + iter->GetNumPoints() - 1) % (iter->GetNumPoints())),
+- iter->GetPoint(i),
+- iter->GetPoint((i + 1) % (iter->GetNumPoints())),
++ if (!InCone(iter->get().GetPoint((i + iter->get().GetNumPoints() - 1) % (iter->get().GetNumPoints())),
++ iter->get().GetPoint(i),
++ iter->get().GetPoint((i + 1) % (iter->get().GetNumPoints())),
+ holepoint)) {
+ continue;
+ }
+- polypoint = iter->GetPoint(i);
++ polypoint = iter->get().GetPoint(i);
+ if (pointfound) {
+ v1 = Normalize(polypoint - holepoint);
+ v2 = Normalize(bestpolypoint - holepoint);
+@@ -263,13 +260,13 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+ }
+ }
+ pointvisible = true;
+- for (iter2 = polys.begin(); iter2 != polys.end(); iter2++) {
+- if (iter2->IsHole()) {
++ for (iter2 = polys.front(); iter2; iter2->next()) {
++ if (iter2->get().IsHole()) {
+ continue;
+ }
+- for (i2 = 0; i2 < iter2->GetNumPoints(); i2++) {
+- linep1 = iter2->GetPoint(i2);
+- linep2 = iter2->GetPoint((i2 + 1) % (iter2->GetNumPoints()));
++ for (i2 = 0; i2 < iter2->get().GetNumPoints(); i2++) {
++ linep1 = iter2->get().GetPoint(i2);
++ linep2 = iter2->get().GetPoint((i2 + 1) % (iter2->get().GetNumPoints()));
+ if (Intersects(holepoint, polypoint, linep1, linep2)) {
+ pointvisible = false;
+ break;
+@@ -292,18 +289,18 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+ return 0;
+ }
+
+- newpoly.Init(holeiter->GetNumPoints() + polyiter->GetNumPoints() + 2);
++ newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2);
+ i2 = 0;
+ for (i = 0; i <= polypointindex; i++) {
+- newpoly[i2] = polyiter->GetPoint(i);
++ newpoly[i2] = polyiter->get().GetPoint(i);
+ i2++;
+ }
+- for (i = 0; i <= holeiter->GetNumPoints(); i++) {
+- newpoly[i2] = holeiter->GetPoint((i + holepointindex) % holeiter->GetNumPoints());
++ for (i = 0; i <= holeiter->get().GetNumPoints(); i++) {
++ newpoly[i2] = holeiter->get().GetPoint((i + holepointindex) % holeiter->get().GetNumPoints());
+ i2++;
+ }
+- for (i = polypointindex; i < polyiter->GetNumPoints(); i++) {
+- newpoly[i2] = polyiter->GetPoint(i);
++ for (i = polypointindex; i < polyiter->get().GetNumPoints(); i++) {
++ newpoly[i2] = polyiter->get().GetPoint(i);
+ i2++;
+ }
+
+@@ -312,8 +309,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+ polys.push_back(newpoly);
+ }
+
+- for (iter = polys.begin(); iter != polys.end(); iter++) {
+- outpolys->push_back(*iter);
++ for (iter = polys.front(); iter; iter = iter->next()) {
++ outpolys->push_back(iter->get());
+ }
+
+ return 1;
+@@ -524,13 +521,13 @@ int TPPLPartition::Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles) {
+
+ int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
+ TPPLPolyList outpolys;
+- TPPLPolyList::iterator iter;
++ TPPLPolyList::Element *iter;
+
+ if (!RemoveHoles(inpolys, &outpolys)) {
+ return 0;
+ }
+- for (iter = outpolys.begin(); iter != outpolys.end(); iter++) {
+- if (!Triangulate_EC(&(*iter), triangles)) {
++ for (iter = outpolys.front(); iter; iter = iter->next()) {
++ if (!Triangulate_EC(&(iter->get()), triangles)) {
+ return 0;
+ }
+ }
+@@ -543,7 +540,7 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
+ }
+
+ TPPLPolyList triangles;
+- TPPLPolyList::iterator iter1, iter2;
++ TPPLPolyList::Element *iter1, *iter2;
+ TPPLPoly *poly1 = NULL, *poly2 = NULL;
+ TPPLPoly newpoly;
+ TPPLPoint d1, d2, p1, p2, p3;
+@@ -578,19 +575,19 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
+ return 0;
+ }
+
+- for (iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) {
+- poly1 = &(*iter1);
++ for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) {
++ poly1 = &(iter1->get());
+ for (i11 = 0; i11 < poly1->GetNumPoints(); i11++) {
+ d1 = poly1->GetPoint(i11);
+ i12 = (i11 + 1) % (poly1->GetNumPoints());
+ d2 = poly1->GetPoint(i12);
+
+ isdiagonal = false;
+- for (iter2 = iter1; iter2 != triangles.end(); iter2++) {
++ for (iter2 = iter1; iter2; iter2 = iter2->next()) {
+ if (iter1 == iter2) {
+ continue;
+ }
+- poly2 = &(*iter2);
++ poly2 = &(iter2->get());
+
+ for (i21 = 0; i21 < poly2->GetNumPoints(); i21++) {
+ if ((d2.x != poly2->GetPoint(i21).x) || (d2.y != poly2->GetPoint(i21).y)) {
+@@ -660,16 +657,16 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
+ }
+
+ triangles.erase(iter2);
+- *iter1 = newpoly;
+- poly1 = &(*iter1);
++ iter1->get() = newpoly;
++ poly1 = &(iter1->get());
+ i11 = -1;
+
+ continue;
+ }
+ }
+
+- for (iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) {
+- parts->push_back(*iter1);
++ for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) {
++ parts->push_back(iter1->get());
+ }
+
+ return 1;
+@@ -677,13 +674,13 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
+
+ int TPPLPartition::ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts) {
+ TPPLPolyList outpolys;
+- TPPLPolyList::iterator iter;
++ TPPLPolyList::Element *iter;
+
+ if (!RemoveHoles(inpolys, &outpolys)) {
+ return 0;
+ }
+- for (iter = outpolys.begin(); iter != outpolys.end(); iter++) {
+- if (!ConvexPartition_HM(&(*iter), parts)) {
++ for (iter = outpolys.front(); iter; iter = iter->next()) {
++ if (!ConvexPartition_HM(&(iter->get()), parts)) {
+ return 0;
+ }
+ }
+@@ -824,8 +821,8 @@ int TPPLPartition::Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles) {
+ newdiagonal.index1 = 0;
+ newdiagonal.index2 = n - 1;
+ diagonals.push_back(newdiagonal);
+- while (!diagonals.empty()) {
+- diagonal = *(diagonals.begin());
++ while (!diagonals.is_empty()) {
++ diagonal = diagonals.front()->get();
+ diagonals.pop_front();
+ bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex;
+ if (bestvertex == -1) {
+@@ -873,10 +870,10 @@ void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2
+ pairs->push_front(newdiagonal);
+ dpstates[a][b].weight = w;
+ } else {
+- if ((!pairs->empty()) && (i <= pairs->begin()->index1)) {
++ if ((!pairs->is_empty()) && (i <= pairs->front()->get().index1)) {
+ return;
+ }
+- while ((!pairs->empty()) && (pairs->begin()->index2 >= j)) {
++ while ((!pairs->is_empty()) && (pairs->front()->get().index2 >= j)) {
+ pairs->pop_front();
+ }
+ pairs->push_front(newdiagonal);
+@@ -885,7 +882,7 @@ void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2
+
+ void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
+ DiagonalList *pairs = NULL;
+- DiagonalList::iterator iter, lastiter;
++ DiagonalList::Element *iter, *lastiter;
+ long top;
+ long w;
+
+@@ -902,23 +899,23 @@ void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPS
+ }
+ if (j - i > 1) {
+ pairs = &(dpstates[i][j].pairs);
+- iter = pairs->end();
+- lastiter = pairs->end();
+- while (iter != pairs->begin()) {
++ iter = pairs->back();
++ lastiter = pairs->back();
++ while (iter != pairs->front()) {
+ iter--;
+- if (!IsReflex(vertices[iter->index2].p, vertices[j].p, vertices[k].p)) {
++ if (!IsReflex(vertices[iter->get().index2].p, vertices[j].p, vertices[k].p)) {
+ lastiter = iter;
+ } else {
+ break;
+ }
+ }
+- if (lastiter == pairs->end()) {
++ if (lastiter == pairs->back()) {
+ w++;
+ } else {
+- if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->index1].p)) {
++ if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->get().index1].p)) {
+ w++;
+ } else {
+- top = lastiter->index1;
++ top = lastiter->get().index1;
+ }
+ }
+ }
+@@ -927,7 +924,7 @@ void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPS
+
+ void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
+ DiagonalList *pairs = NULL;
+- DiagonalList::iterator iter, lastiter;
++ DiagonalList::Element *iter, *lastiter;
+ long top;
+ long w;
+
+@@ -946,21 +943,21 @@ void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPS
+ if (k - j > 1) {
+ pairs = &(dpstates[j][k].pairs);
+
+- iter = pairs->begin();
+- if ((!pairs->empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->index1].p))) {
++ iter = pairs->front();
++ if ((!pairs->is_empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p))) {
+ lastiter = iter;
+- while (iter != pairs->end()) {
+- if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->index1].p)) {
++ while (iter) {
++ if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p)) {
+ lastiter = iter;
+- iter++;
++ iter = iter->next();
+ } else {
+ break;
+ }
+ }
+- if (IsReflex(vertices[lastiter->index2].p, vertices[k].p, vertices[i].p)) {
++ if (IsReflex(vertices[lastiter->get().index2].p, vertices[k].p, vertices[i].p)) {
+ w++;
+ } else {
+- top = lastiter->index2;
++ top = lastiter->get().index2;
+ }
+ } else {
+ w++;
+@@ -981,11 +978,11 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ DiagonalList diagonals, diagonals2;
+ Diagonal diagonal, newdiagonal;
+ DiagonalList *pairs = NULL, *pairs2 = NULL;
+- DiagonalList::iterator iter, iter2;
++ DiagonalList::Element *iter, *iter2;
+ int ret;
+ TPPLPoly newpoly;
+- std::vector<long> indices;
+- std::vector<long>::iterator iiter;
++ List<long> indices;
++ List<long>::Element *iiter;
+ bool ijreal, jkreal;
+
+ n = poly->GetNumPoints();
+@@ -1110,35 +1107,35 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ newdiagonal.index1 = 0;
+ newdiagonal.index2 = n - 1;
+ diagonals.push_front(newdiagonal);
+- while (!diagonals.empty()) {
+- diagonal = *(diagonals.begin());
++ while (!diagonals.is_empty()) {
++ diagonal = diagonals.front()->get();
+ diagonals.pop_front();
+ if ((diagonal.index2 - diagonal.index1) <= 1) {
+ continue;
+ }
+ pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
+- if (pairs->empty()) {
++ if (pairs->is_empty()) {
+ ret = 0;
+ break;
+ }
+ if (!vertices[diagonal.index1].isConvex) {
+- iter = pairs->end();
++ iter = pairs->back();
+ iter--;
+- j = iter->index2;
++ j = iter->get().index2;
+ newdiagonal.index1 = j;
+ newdiagonal.index2 = diagonal.index2;
+ diagonals.push_front(newdiagonal);
+ if ((j - diagonal.index1) > 1) {
+- if (iter->index1 != iter->index2) {
++ if (iter->get().index1 != iter->get().index2) {
+ pairs2 = &(dpstates[diagonal.index1][j].pairs);
+ while (1) {
+- if (pairs2->empty()) {
++ if (pairs2->is_empty()) {
+ ret = 0;
+ break;
+ }
+- iter2 = pairs2->end();
++ iter2 = pairs2->back();
+ iter2--;
+- if (iter->index1 != iter2->index1) {
++ if (iter->get().index1 != iter2->get().index1) {
+ pairs2->pop_back();
+ } else {
+ break;
+@@ -1153,21 +1150,21 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ diagonals.push_front(newdiagonal);
+ }
+ } else {
+- iter = pairs->begin();
+- j = iter->index1;
++ iter = pairs->front();
++ j = iter->get().index1;
+ newdiagonal.index1 = diagonal.index1;
+ newdiagonal.index2 = j;
+ diagonals.push_front(newdiagonal);
+ if ((diagonal.index2 - j) > 1) {
+- if (iter->index1 != iter->index2) {
++ if (iter->get().index1 != iter->get().index2) {
+ pairs2 = &(dpstates[j][diagonal.index2].pairs);
+ while (1) {
+- if (pairs2->empty()) {
++ if (pairs2->is_empty()) {
+ ret = 0;
+ break;
+ }
+- iter2 = pairs2->begin();
+- if (iter->index2 != iter2->index2) {
++ iter2 = pairs2->front();
++ if (iter->get().index2 != iter2->get().index2) {
+ pairs2->pop_front();
+ } else {
+ break;
+@@ -1197,8 +1194,8 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ newdiagonal.index1 = 0;
+ newdiagonal.index2 = n - 1;
+ diagonals.push_front(newdiagonal);
+- while (!diagonals.empty()) {
+- diagonal = *(diagonals.begin());
++ while (!diagonals.is_empty()) {
++ diagonal = diagonals.front()->get();
+ diagonals.pop_front();
+ if ((diagonal.index2 - diagonal.index1) <= 1) {
+ continue;
+@@ -1210,8 +1207,8 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ indices.push_back(diagonal.index2);
+ diagonals2.push_front(diagonal);
+
+- while (!diagonals2.empty()) {
+- diagonal = *(diagonals2.begin());
++ while (!diagonals2.is_empty()) {
++ diagonal = diagonals2.front()->get();
+ diagonals2.pop_front();
+ if ((diagonal.index2 - diagonal.index1) <= 1) {
+ continue;
+@@ -1220,16 +1217,16 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ jkreal = true;
+ pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
+ if (!vertices[diagonal.index1].isConvex) {
+- iter = pairs->end();
++ iter = pairs->back();
+ iter--;
+- j = iter->index2;
+- if (iter->index1 != iter->index2) {
++ j = iter->get().index2;
++ if (iter->get().index1 != iter->get().index2) {
+ ijreal = false;
+ }
+ } else {
+- iter = pairs->begin();
+- j = iter->index1;
+- if (iter->index1 != iter->index2) {
++ iter = pairs->front();
++ j = iter->get().index1;
++ if (iter->get().index1 != iter->get().index2) {
+ jkreal = false;
+ }
+ }
+@@ -1253,11 +1250,12 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ indices.push_back(j);
+ }
+
+- std::sort(indices.begin(), indices.end());
++ //std::sort(indices.begin(), indices.end());
++ indices.sort();
+ newpoly.Init((long)indices.size());
+ k = 0;
+- for (iiter = indices.begin(); iiter != indices.end(); iiter++) {
+- newpoly[k] = vertices[*iiter].p;
++ for (iiter = indices.front(); iiter != indices.back(); iiter = iiter->next()) {
++ newpoly[k] = vertices[iiter->get()].p;
+ k++;
+ }
+ parts->push_back(newpoly);
+@@ -1281,7 +1279,7 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ // "Computational Geometry: Algorithms and Applications"
+ // by Mark de Berg, Otfried Cheong, Marc van Kreveld, and Mark Overmars.
+ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys) {
+- TPPLPolyList::iterator iter;
++ TPPLPolyList::Element *iter;
+ MonotoneVertex *vertices = NULL;
+ long i, numvertices, vindex, vindex2, newnumvertices, maxnumvertices;
+ long polystartindex, polyendindex;
+@@ -1291,11 +1289,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
+ bool error = false;
+
+ numvertices = 0;
+- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) {
+- if (!iter->Valid()) {
+- return 0;
+- }
+- numvertices += iter->GetNumPoints();
++ for (iter = inpolys->front(); iter; iter++) {
++ numvertices += iter->get().GetNumPoints();
+ }
+
+ maxnumvertices = numvertices * 3;
+@@ -1303,8 +1298,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
+ newnumvertices = numvertices;
+
+ polystartindex = 0;
+- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) {
+- poly = &(*iter);
++ for (iter = inpolys->front(); iter; iter++) {
++ poly = &(iter->get());
+ polyendindex = polystartindex + poly->GetNumPoints() - 1;
+ for (i = 0; i < poly->GetNumPoints(); i++) {
+ vertices[i + polystartindex].p = poly->GetPoint(i);
+@@ -1360,14 +1355,14 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
+ // Note that while set doesn't actually have to be implemented as
+ // a tree, complexity requirements for operations are the same as
+ // for the balanced binary search tree.
+- std::set<ScanLineEdge> edgeTree;
++ Set<ScanLineEdge> edgeTree;
+ // Store iterators to the edge tree elements.
+ // This makes deleting existing edges much faster.
+- std::set<ScanLineEdge>::iterator *edgeTreeIterators, edgeIter;
+- edgeTreeIterators = new std::set<ScanLineEdge>::iterator[maxnumvertices];
+- std::pair<std::set<ScanLineEdge>::iterator, bool> edgeTreeRet;
++ Set<ScanLineEdge>::Element **edgeTreeIterators, *edgeIter;
++ edgeTreeIterators = new Set<ScanLineEdge>::Element *[maxnumvertices];
++ //Pair<Set<ScanLineEdge>::iterator, bool> edgeTreeRet;
+ for (i = 0; i < numvertices; i++) {
+- edgeTreeIterators[i] = edgeTree.end();
++ edgeTreeIterators[i] = nullptr;
+ }
+
+ // For each vertex.
+@@ -1387,13 +1382,14 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
+ newedge.p1 = v->p;
+ newedge.p2 = vertices[v->next].p;
+ newedge.index = vindex;
+- edgeTreeRet = edgeTree.insert(newedge);
+- edgeTreeIterators[vindex] = edgeTreeRet.first;
++ //edgeTreeRet = edgeTree.insert(newedge);
++ //edgeTreeIterators[vindex] = edgeTreeRet.first;
++ edgeTreeIterators[vindex] = edgeTree.insert(newedge);
+ helpers[vindex] = vindex;
+ break;
+
+ case TPPL_VERTEXTYPE_END:
+- if (edgeTreeIterators[v->previous] == edgeTree.end()) {
++ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
+ error = true;
+ break;
+ }
+@@ -1412,29 +1408,30 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
+ newedge.p1 = v->p;
+ newedge.p2 = v->p;
+ edgeIter = edgeTree.lower_bound(newedge);
+- if (edgeIter == edgeTree.begin()) {
++ if (edgeIter == edgeTree.front()) {
+ error = true;
+ break;
+ }
+ edgeIter--;
+ // Insert the diagonal connecting vi to helper(e_j) in D.
+- AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->index],
++ AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ vindex2 = newnumvertices - 2;
+ v2 = &(vertices[vindex2]);
+ // helper(e_j) in v_i.
+- helpers[edgeIter->index] = vindex;
++ helpers[edgeIter->get().index] = vindex;
+ // Insert e_i in T and set helper(e_i) to v_i.
+ newedge.p1 = v2->p;
+ newedge.p2 = vertices[v2->next].p;
+ newedge.index = vindex2;
+- edgeTreeRet = edgeTree.insert(newedge);
+- edgeTreeIterators[vindex2] = edgeTreeRet.first;
++ //edgeTreeRet = edgeTree.insert(newedge);
++ //edgeTreeIterators[vindex2] = edgeTreeRet.first;
++ edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
+ helpers[vindex2] = vindex2;
+ break;
+
+ case TPPL_VERTEXTYPE_MERGE:
+- if (edgeTreeIterators[v->previous] == edgeTree.end()) {
++ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
+ error = true;
+ break;
+ }
+@@ -1452,25 +1449,25 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
+ newedge.p1 = v->p;
+ newedge.p2 = v->p;
+ edgeIter = edgeTree.lower_bound(newedge);
+- if (edgeIter == edgeTree.begin()) {
++ if (edgeIter == edgeTree.front()) {
+ error = true;
+ break;
+ }
+ edgeIter--;
+ // If helper(e_j) is a merge vertex.
+- if (vertextypes[helpers[edgeIter->index]] == TPPL_VERTEXTYPE_MERGE) {
++ if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) {
+ // Insert the diagonal connecting v_i to helper(e_j) in D.
+- AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->index],
++ AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->get().index],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ }
+ // helper(e_j) <- v_i
+- helpers[edgeIter->index] = vindex2;
++ helpers[edgeIter->get().index] = vindex2;
+ break;
+
+ case TPPL_VERTEXTYPE_REGULAR:
+ // If the interior of P lies to the right of v_i.
+ if (Below(v->p, vertices[v->previous].p)) {
+- if (edgeTreeIterators[v->previous] == edgeTree.end()) {
++ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
+ error = true;
+ break;
+ }
+@@ -1488,27 +1485,28 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
+ newedge.p1 = v2->p;
+ newedge.p2 = vertices[v2->next].p;
+ newedge.index = vindex2;
+- edgeTreeRet = edgeTree.insert(newedge);
+- edgeTreeIterators[vindex2] = edgeTreeRet.first;
++ //edgeTreeRet = edgeTree.insert(newedge);
++ //edgeTreeIterators[vindex2] = edgeTreeRet.first;
++ edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
+ helpers[vindex2] = vindex;
+ } else {
+ // Search in T to find the edge e_j directly left of v_i.
+ newedge.p1 = v->p;
+ newedge.p2 = v->p;
+ edgeIter = edgeTree.lower_bound(newedge);
+- if (edgeIter == edgeTree.begin()) {
++ if (edgeIter == edgeTree.front()) {
+ error = true;
+ break;
+ }
+- edgeIter--;
++ edgeIter = edgeIter->prev();
+ // If helper(e_j) is a merge vertex.
+- if (vertextypes[helpers[edgeIter->index]] == TPPL_VERTEXTYPE_MERGE) {
++ if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) {
+ // Insert the diagonal connecting v_i to helper(e_j) in D.
+- AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->index],
++ AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ }
+ // helper(e_j) <- v_i.
+- helpers[edgeIter->index] = vindex;
++ helpers[edgeIter->get().index] = vindex;
+ }
+ break;
+ }
+@@ -1569,8 +1567,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
+
+ // Adds a diagonal to the doubly-connected list of vertices.
+ void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
+- TPPLVertexType *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators,
+- std::set<ScanLineEdge> *edgeTree, long *helpers) {
++ TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
++ Set<ScanLineEdge> *edgeTree, long *helpers) {
+ long newindex1, newindex2;
+
+ newindex1 = *numvertices;
+@@ -1597,14 +1595,14 @@ void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, lon
+ vertextypes[newindex1] = vertextypes[index1];
+ edgeTreeIterators[newindex1] = edgeTreeIterators[index1];
+ helpers[newindex1] = helpers[index1];
+- if (edgeTreeIterators[newindex1] != edgeTree->end()) {
+- edgeTreeIterators[newindex1]->index = newindex1;
++ if (edgeTreeIterators[newindex1] != edgeTree->back()) {
++ edgeTreeIterators[newindex1]->get().index = newindex1;
+ }
+ vertextypes[newindex2] = vertextypes[index2];
+ edgeTreeIterators[newindex2] = edgeTreeIterators[index2];
+ helpers[newindex2] = helpers[index2];
+- if (edgeTreeIterators[newindex2] != edgeTree->end()) {
+- edgeTreeIterators[newindex2]->index = newindex2;
++ if (edgeTreeIterators[newindex2] != edgeTree->back()) {
++ edgeTreeIterators[newindex2]->get().index = newindex2;
+ }
+ }
+
+@@ -1830,13 +1828,13 @@ int TPPLPartition::TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles
+
+ int TPPLPartition::Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
+ TPPLPolyList monotone;
+- TPPLPolyList::iterator iter;
++ TPPLPolyList::Element *iter;
+
+ if (!MonotonePartition(inpolys, &monotone)) {
+ return 0;
+ }
+- for (iter = monotone.begin(); iter != monotone.end(); iter++) {
+- if (!TriangulateMonotone(&(*iter), triangles)) {
++ for (iter = monotone.front(); iter; iter = iter->next()) {
++ if (!TriangulateMonotone(&(iter->get()), triangles)) {
+ return 0;
+ }
+ }
+diff --git a/thirdparty/misc/polypartition.h b/thirdparty/misc/polypartition.h
+index f163f5d2173f..b2d905a3ef76 100644
+--- a/thirdparty/misc/polypartition.h
++++ b/thirdparty/misc/polypartition.h
+@@ -24,8 +24,9 @@
+ #ifndef POLYPARTITION_H
+ #define POLYPARTITION_H
+
+-#include <list>
+-#include <set>
++#include "core/math/vector2.h"
++#include "core/templates/list.h"
++#include "core/templates/set.h"
+
+ typedef double tppl_float;
+
+@@ -44,49 +45,7 @@ enum TPPLVertexType {
+ };
+
+ // 2D point structure.
+-struct TPPLPoint {
+- tppl_float x;
+- tppl_float y;
+- // User-specified vertex identifier. Note that this isn't used internally
+- // by the library, but will be faithfully copied around.
+- int id;
+-
+- TPPLPoint operator+(const TPPLPoint &p) const {
+- TPPLPoint r;
+- r.x = x + p.x;
+- r.y = y + p.y;
+- return r;
+- }
+-
+- TPPLPoint operator-(const TPPLPoint &p) const {
+- TPPLPoint r;
+- r.x = x - p.x;
+- r.y = y - p.y;
+- return r;
+- }
+-
+- TPPLPoint operator*(const tppl_float f) const {
+- TPPLPoint r;
+- r.x = x * f;
+- r.y = y * f;
+- return r;
+- }
+-
+- TPPLPoint operator/(const tppl_float f) const {
+- TPPLPoint r;
+- r.x = x / f;
+- r.y = y / f;
+- return r;
+- }
+-
+- bool operator==(const TPPLPoint &p) const {
+- return ((x == p.x) && (y == p.y));
+- }
+-
+- bool operator!=(const TPPLPoint &p) const {
+- return !((x == p.x) && (y == p.y));
+- }
+-};
++typedef Vector2 TPPLPoint;
+
+ // Polygon implemented as an array of points with a "hole" flag.
+ class TPPLPoly {
+@@ -168,9 +127,9 @@ class TPPLPoly {
+ };
+
+ #ifdef TPPL_ALLOCATOR
+-typedef std::list<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList;
++typedef List<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList;
+ #else
+-typedef std::list<TPPLPoly> TPPLPolyList;
++typedef List<TPPLPoly> TPPLPolyList;
+ #endif
+
+ class TPPLPartition {
+@@ -209,9 +168,9 @@ public:
+ };
+
+ #ifdef TPPL_ALLOCATOR
+- typedef std::list<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList;
++ typedef List<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList;
+ #else
+- typedef std::list<Diagonal> DiagonalList;
++ typedef List<Diagonal> DiagonalList;
+ #endif
+
+ // Dynamic programming state for minimum-weight triangulation.
+@@ -265,8 +224,8 @@ public:
+ // Helper functions for MonotonePartition.
+ bool Below(TPPLPoint &p1, TPPLPoint &p2);
+ void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
+- TPPLVertexType *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators,
+- std::set<ScanLineEdge> *edgeTree, long *helpers);
++ TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
++ Set<ScanLineEdge> *edgeTree, long *helpers);
+
+ // Triangulates a monotone polygon, used in Triangulate_MONO.
+ int TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles);
diff --git a/thirdparty/misc/polypartition.cpp b/thirdparty/misc/polypartition.cpp
new file mode 100644
index 0000000000..4f1b6dcb21
--- /dev/null
+++ b/thirdparty/misc/polypartition.cpp
@@ -0,0 +1,1849 @@
+/*************************************************************************/
+/* Copyright (c) 2011-2021 Ivan Fratric and contributors. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "polypartition.h"
+
+#include <algorithm>
+
+TPPLPoly::TPPLPoly() {
+ hole = false;
+ numpoints = 0;
+ points = NULL;
+}
+
+TPPLPoly::~TPPLPoly() {
+ if (points) {
+ delete[] points;
+ }
+}
+
+void TPPLPoly::Clear() {
+ if (points) {
+ delete[] points;
+ }
+ hole = false;
+ numpoints = 0;
+ points = NULL;
+}
+
+void TPPLPoly::Init(long numpoints) {
+ Clear();
+ this->numpoints = numpoints;
+ points = new TPPLPoint[numpoints];
+}
+
+void TPPLPoly::Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) {
+ Init(3);
+ points[0] = p1;
+ points[1] = p2;
+ points[2] = p3;
+}
+
+TPPLPoly::TPPLPoly(const TPPLPoly &src) :
+ TPPLPoly() {
+ hole = src.hole;
+ numpoints = src.numpoints;
+
+ if (numpoints > 0) {
+ points = new TPPLPoint[numpoints];
+ memcpy(points, src.points, numpoints * sizeof(TPPLPoint));
+ }
+}
+
+TPPLPoly &TPPLPoly::operator=(const TPPLPoly &src) {
+ Clear();
+ hole = src.hole;
+ numpoints = src.numpoints;
+
+ if (numpoints > 0) {
+ points = new TPPLPoint[numpoints];
+ memcpy(points, src.points, numpoints * sizeof(TPPLPoint));
+ }
+
+ return *this;
+}
+
+TPPLOrientation TPPLPoly::GetOrientation() const {
+ long i1, i2;
+ tppl_float area = 0;
+ for (i1 = 0; i1 < numpoints; i1++) {
+ i2 = i1 + 1;
+ if (i2 == numpoints) {
+ i2 = 0;
+ }
+ area += points[i1].x * points[i2].y - points[i1].y * points[i2].x;
+ }
+ if (area > 0) {
+ return TPPL_ORIENTATION_CCW;
+ }
+ if (area < 0) {
+ return TPPL_ORIENTATION_CW;
+ }
+ return TPPL_ORIENTATION_NONE;
+}
+
+void TPPLPoly::SetOrientation(TPPLOrientation orientation) {
+ TPPLOrientation polyorientation = GetOrientation();
+ if (polyorientation != TPPL_ORIENTATION_NONE && polyorientation != orientation) {
+ Invert();
+ }
+}
+
+void TPPLPoly::Invert() {
+ std::reverse(points, points + numpoints);
+}
+
+TPPLPartition::PartitionVertex::PartitionVertex() :
+ previous(NULL), next(NULL) {
+}
+
+TPPLPoint TPPLPartition::Normalize(const TPPLPoint &p) {
+ TPPLPoint r;
+ tppl_float n = sqrt(p.x * p.x + p.y * p.y);
+ if (n != 0) {
+ r = p / n;
+ } else {
+ r.x = 0;
+ r.y = 0;
+ }
+ return r;
+}
+
+tppl_float TPPLPartition::Distance(const TPPLPoint &p1, const TPPLPoint &p2) {
+ tppl_float dx, dy;
+ dx = p2.x - p1.x;
+ dy = p2.y - p1.y;
+ return (sqrt(dx * dx + dy * dy));
+}
+
+// Checks if two lines intersect.
+int TPPLPartition::Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22) {
+ if ((p11.x == p21.x) && (p11.y == p21.y)) {
+ return 0;
+ }
+ if ((p11.x == p22.x) && (p11.y == p22.y)) {
+ return 0;
+ }
+ if ((p12.x == p21.x) && (p12.y == p21.y)) {
+ return 0;
+ }
+ if ((p12.x == p22.x) && (p12.y == p22.y)) {
+ return 0;
+ }
+
+ TPPLPoint v1ort, v2ort, v;
+ tppl_float dot11, dot12, dot21, dot22;
+
+ v1ort.x = p12.y - p11.y;
+ v1ort.y = p11.x - p12.x;
+
+ v2ort.x = p22.y - p21.y;
+ v2ort.y = p21.x - p22.x;
+
+ v = p21 - p11;
+ dot21 = v.x * v1ort.x + v.y * v1ort.y;
+ v = p22 - p11;
+ dot22 = v.x * v1ort.x + v.y * v1ort.y;
+
+ v = p11 - p21;
+ dot11 = v.x * v2ort.x + v.y * v2ort.y;
+ v = p12 - p21;
+ dot12 = v.x * v2ort.x + v.y * v2ort.y;
+
+ if (dot11 * dot12 > 0) {
+ return 0;
+ }
+ if (dot21 * dot22 > 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+// Removes holes from inpolys by merging them with non-holes.
+int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
+ TPPLPolyList polys;
+ TPPLPolyList::Element *holeiter, *polyiter, *iter, *iter2;
+ long i, i2, holepointindex, polypointindex;
+ TPPLPoint holepoint, polypoint, bestpolypoint;
+ TPPLPoint linep1, linep2;
+ TPPLPoint v1, v2;
+ TPPLPoly newpoly;
+ bool hasholes;
+ bool pointvisible;
+ bool pointfound;
+
+ // Check for the trivial case of no holes.
+ hasholes = false;
+ for (iter = inpolys->front(); iter; iter = iter->next()) {
+ if (iter->get().IsHole()) {
+ hasholes = true;
+ break;
+ }
+ }
+ if (!hasholes) {
+ for (iter = inpolys->front(); iter; iter = iter->next()) {
+ outpolys->push_back(iter->get());
+ }
+ return 1;
+ }
+
+ polys = *inpolys;
+
+ while (1) {
+ // Find the hole point with the largest x.
+ hasholes = false;
+ for (iter = polys.front(); iter; iter = iter->next()) {
+ if (!iter->get().IsHole()) {
+ continue;
+ }
+
+ if (!hasholes) {
+ hasholes = true;
+ holeiter = iter;
+ holepointindex = 0;
+ }
+
+ for (i = 0; i < iter->get().GetNumPoints(); i++) {
+ if (iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) {
+ holeiter = iter;
+ holepointindex = i;
+ }
+ }
+ }
+ if (!hasholes) {
+ break;
+ }
+ holepoint = holeiter->get().GetPoint(holepointindex);
+
+ pointfound = false;
+ for (iter = polys.front(); iter; iter = iter->next()) {
+ if (iter->get().IsHole()) {
+ continue;
+ }
+ for (i = 0; i < iter->get().GetNumPoints(); i++) {
+ if (iter->get().GetPoint(i).x <= holepoint.x) {
+ continue;
+ }
+ if (!InCone(iter->get().GetPoint((i + iter->get().GetNumPoints() - 1) % (iter->get().GetNumPoints())),
+ iter->get().GetPoint(i),
+ iter->get().GetPoint((i + 1) % (iter->get().GetNumPoints())),
+ holepoint)) {
+ continue;
+ }
+ polypoint = iter->get().GetPoint(i);
+ if (pointfound) {
+ v1 = Normalize(polypoint - holepoint);
+ v2 = Normalize(bestpolypoint - holepoint);
+ if (v2.x > v1.x) {
+ continue;
+ }
+ }
+ pointvisible = true;
+ for (iter2 = polys.front(); iter2; iter2->next()) {
+ if (iter2->get().IsHole()) {
+ continue;
+ }
+ for (i2 = 0; i2 < iter2->get().GetNumPoints(); i2++) {
+ linep1 = iter2->get().GetPoint(i2);
+ linep2 = iter2->get().GetPoint((i2 + 1) % (iter2->get().GetNumPoints()));
+ if (Intersects(holepoint, polypoint, linep1, linep2)) {
+ pointvisible = false;
+ break;
+ }
+ }
+ if (!pointvisible) {
+ break;
+ }
+ }
+ if (pointvisible) {
+ pointfound = true;
+ bestpolypoint = polypoint;
+ polyiter = iter;
+ polypointindex = i;
+ }
+ }
+ }
+
+ if (!pointfound) {
+ return 0;
+ }
+
+ newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2);
+ i2 = 0;
+ for (i = 0; i <= polypointindex; i++) {
+ newpoly[i2] = polyiter->get().GetPoint(i);
+ i2++;
+ }
+ for (i = 0; i <= holeiter->get().GetNumPoints(); i++) {
+ newpoly[i2] = holeiter->get().GetPoint((i + holepointindex) % holeiter->get().GetNumPoints());
+ i2++;
+ }
+ for (i = polypointindex; i < polyiter->get().GetNumPoints(); i++) {
+ newpoly[i2] = polyiter->get().GetPoint(i);
+ i2++;
+ }
+
+ polys.erase(holeiter);
+ polys.erase(polyiter);
+ polys.push_back(newpoly);
+ }
+
+ for (iter = polys.front(); iter; iter = iter->next()) {
+ outpolys->push_back(iter->get());
+ }
+
+ return 1;
+}
+
+bool TPPLPartition::IsConvex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) {
+ tppl_float tmp;
+ tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y);
+ if (tmp > 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+bool TPPLPartition::IsReflex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3) {
+ tppl_float tmp;
+ tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y);
+ if (tmp < 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+bool TPPLPartition::IsInside(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p) {
+ if (IsConvex(p1, p, p2)) {
+ return false;
+ }
+ if (IsConvex(p2, p, p3)) {
+ return false;
+ }
+ if (IsConvex(p3, p, p1)) {
+ return false;
+ }
+ return true;
+}
+
+bool TPPLPartition::InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p) {
+ bool convex;
+
+ convex = IsConvex(p1, p2, p3);
+
+ if (convex) {
+ if (!IsConvex(p1, p2, p)) {
+ return false;
+ }
+ if (!IsConvex(p2, p3, p)) {
+ return false;
+ }
+ return true;
+ } else {
+ if (IsConvex(p1, p2, p)) {
+ return true;
+ }
+ if (IsConvex(p2, p3, p)) {
+ return true;
+ }
+ return false;
+ }
+}
+
+bool TPPLPartition::InCone(PartitionVertex *v, TPPLPoint &p) {
+ TPPLPoint p1, p2, p3;
+
+ p1 = v->previous->p;
+ p2 = v->p;
+ p3 = v->next->p;
+
+ return InCone(p1, p2, p3, p);
+}
+
+void TPPLPartition::UpdateVertexReflexity(PartitionVertex *v) {
+ PartitionVertex *v1 = NULL, *v3 = NULL;
+ v1 = v->previous;
+ v3 = v->next;
+ v->isConvex = !IsReflex(v1->p, v->p, v3->p);
+}
+
+void TPPLPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices) {
+ long i;
+ PartitionVertex *v1 = NULL, *v3 = NULL;
+ TPPLPoint vec1, vec3;
+
+ v1 = v->previous;
+ v3 = v->next;
+
+ v->isConvex = IsConvex(v1->p, v->p, v3->p);
+
+ vec1 = Normalize(v1->p - v->p);
+ vec3 = Normalize(v3->p - v->p);
+ v->angle = vec1.x * vec3.x + vec1.y * vec3.y;
+
+ if (v->isConvex) {
+ v->isEar = true;
+ for (i = 0; i < numvertices; i++) {
+ if ((vertices[i].p.x == v->p.x) && (vertices[i].p.y == v->p.y)) {
+ continue;
+ }
+ if ((vertices[i].p.x == v1->p.x) && (vertices[i].p.y == v1->p.y)) {
+ continue;
+ }
+ if ((vertices[i].p.x == v3->p.x) && (vertices[i].p.y == v3->p.y)) {
+ continue;
+ }
+ if (IsInside(v1->p, v->p, v3->p, vertices[i].p)) {
+ v->isEar = false;
+ break;
+ }
+ }
+ } else {
+ v->isEar = false;
+ }
+}
+
+// Triangulation by ear removal.
+int TPPLPartition::Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles) {
+ if (!poly->Valid()) {
+ return 0;
+ }
+
+ long numvertices;
+ PartitionVertex *vertices = NULL;
+ PartitionVertex *ear = NULL;
+ TPPLPoly triangle;
+ long i, j;
+ bool earfound;
+
+ if (poly->GetNumPoints() < 3) {
+ return 0;
+ }
+ if (poly->GetNumPoints() == 3) {
+ triangles->push_back(*poly);
+ return 1;
+ }
+
+ numvertices = poly->GetNumPoints();
+
+ vertices = new PartitionVertex[numvertices];
+ for (i = 0; i < numvertices; i++) {
+ vertices[i].isActive = true;
+ vertices[i].p = poly->GetPoint(i);
+ if (i == (numvertices - 1)) {
+ vertices[i].next = &(vertices[0]);
+ } else {
+ vertices[i].next = &(vertices[i + 1]);
+ }
+ if (i == 0) {
+ vertices[i].previous = &(vertices[numvertices - 1]);
+ } else {
+ vertices[i].previous = &(vertices[i - 1]);
+ }
+ }
+ for (i = 0; i < numvertices; i++) {
+ UpdateVertex(&vertices[i], vertices, numvertices);
+ }
+
+ for (i = 0; i < numvertices - 3; i++) {
+ earfound = false;
+ // Find the most extruded ear.
+ for (j = 0; j < numvertices; j++) {
+ if (!vertices[j].isActive) {
+ continue;
+ }
+ if (!vertices[j].isEar) {
+ continue;
+ }
+ if (!earfound) {
+ earfound = true;
+ ear = &(vertices[j]);
+ } else {
+ if (vertices[j].angle > ear->angle) {
+ ear = &(vertices[j]);
+ }
+ }
+ }
+ if (!earfound) {
+ delete[] vertices;
+ return 0;
+ }
+
+ triangle.Triangle(ear->previous->p, ear->p, ear->next->p);
+ triangles->push_back(triangle);
+
+ ear->isActive = false;
+ ear->previous->next = ear->next;
+ ear->next->previous = ear->previous;
+
+ if (i == numvertices - 4) {
+ break;
+ }
+
+ UpdateVertex(ear->previous, vertices, numvertices);
+ UpdateVertex(ear->next, vertices, numvertices);
+ }
+ for (i = 0; i < numvertices; i++) {
+ if (vertices[i].isActive) {
+ triangle.Triangle(vertices[i].previous->p, vertices[i].p, vertices[i].next->p);
+ triangles->push_back(triangle);
+ break;
+ }
+ }
+
+ delete[] vertices;
+
+ return 1;
+}
+
+int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
+ TPPLPolyList outpolys;
+ TPPLPolyList::Element *iter;
+
+ if (!RemoveHoles(inpolys, &outpolys)) {
+ return 0;
+ }
+ for (iter = outpolys.front(); iter; iter = iter->next()) {
+ if (!Triangulate_EC(&(iter->get()), triangles)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
+ if (!poly->Valid()) {
+ return 0;
+ }
+
+ TPPLPolyList triangles;
+ TPPLPolyList::Element *iter1, *iter2;
+ TPPLPoly *poly1 = NULL, *poly2 = NULL;
+ TPPLPoly newpoly;
+ TPPLPoint d1, d2, p1, p2, p3;
+ long i11, i12, i21, i22, i13, i23, j, k;
+ bool isdiagonal;
+ long numreflex;
+
+ // Check if the poly is already convex.
+ numreflex = 0;
+ for (i11 = 0; i11 < poly->GetNumPoints(); i11++) {
+ if (i11 == 0) {
+ i12 = poly->GetNumPoints() - 1;
+ } else {
+ i12 = i11 - 1;
+ }
+ if (i11 == (poly->GetNumPoints() - 1)) {
+ i13 = 0;
+ } else {
+ i13 = i11 + 1;
+ }
+ if (IsReflex(poly->GetPoint(i12), poly->GetPoint(i11), poly->GetPoint(i13))) {
+ numreflex = 1;
+ break;
+ }
+ }
+ if (numreflex == 0) {
+ parts->push_back(*poly);
+ return 1;
+ }
+
+ if (!Triangulate_EC(poly, &triangles)) {
+ return 0;
+ }
+
+ for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) {
+ poly1 = &(iter1->get());
+ for (i11 = 0; i11 < poly1->GetNumPoints(); i11++) {
+ d1 = poly1->GetPoint(i11);
+ i12 = (i11 + 1) % (poly1->GetNumPoints());
+ d2 = poly1->GetPoint(i12);
+
+ isdiagonal = false;
+ for (iter2 = iter1; iter2; iter2 = iter2->next()) {
+ if (iter1 == iter2) {
+ continue;
+ }
+ poly2 = &(iter2->get());
+
+ for (i21 = 0; i21 < poly2->GetNumPoints(); i21++) {
+ if ((d2.x != poly2->GetPoint(i21).x) || (d2.y != poly2->GetPoint(i21).y)) {
+ continue;
+ }
+ i22 = (i21 + 1) % (poly2->GetNumPoints());
+ if ((d1.x != poly2->GetPoint(i22).x) || (d1.y != poly2->GetPoint(i22).y)) {
+ continue;
+ }
+ isdiagonal = true;
+ break;
+ }
+ if (isdiagonal) {
+ break;
+ }
+ }
+
+ if (!isdiagonal) {
+ continue;
+ }
+
+ p2 = poly1->GetPoint(i11);
+ if (i11 == 0) {
+ i13 = poly1->GetNumPoints() - 1;
+ } else {
+ i13 = i11 - 1;
+ }
+ p1 = poly1->GetPoint(i13);
+ if (i22 == (poly2->GetNumPoints() - 1)) {
+ i23 = 0;
+ } else {
+ i23 = i22 + 1;
+ }
+ p3 = poly2->GetPoint(i23);
+
+ if (!IsConvex(p1, p2, p3)) {
+ continue;
+ }
+
+ p2 = poly1->GetPoint(i12);
+ if (i12 == (poly1->GetNumPoints() - 1)) {
+ i13 = 0;
+ } else {
+ i13 = i12 + 1;
+ }
+ p3 = poly1->GetPoint(i13);
+ if (i21 == 0) {
+ i23 = poly2->GetNumPoints() - 1;
+ } else {
+ i23 = i21 - 1;
+ }
+ p1 = poly2->GetPoint(i23);
+
+ if (!IsConvex(p1, p2, p3)) {
+ continue;
+ }
+
+ newpoly.Init(poly1->GetNumPoints() + poly2->GetNumPoints() - 2);
+ k = 0;
+ for (j = i12; j != i11; j = (j + 1) % (poly1->GetNumPoints())) {
+ newpoly[k] = poly1->GetPoint(j);
+ k++;
+ }
+ for (j = i22; j != i21; j = (j + 1) % (poly2->GetNumPoints())) {
+ newpoly[k] = poly2->GetPoint(j);
+ k++;
+ }
+
+ triangles.erase(iter2);
+ iter1->get() = newpoly;
+ poly1 = &(iter1->get());
+ i11 = -1;
+
+ continue;
+ }
+ }
+
+ for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) {
+ parts->push_back(iter1->get());
+ }
+
+ return 1;
+}
+
+int TPPLPartition::ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts) {
+ TPPLPolyList outpolys;
+ TPPLPolyList::Element *iter;
+
+ if (!RemoveHoles(inpolys, &outpolys)) {
+ return 0;
+ }
+ for (iter = outpolys.front(); iter; iter = iter->next()) {
+ if (!ConvexPartition_HM(&(iter->get()), parts)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+// Minimum-weight polygon triangulation by dynamic programming.
+// Time complexity: O(n^3)
+// Space complexity: O(n^2)
+int TPPLPartition::Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles) {
+ if (!poly->Valid()) {
+ return 0;
+ }
+
+ long i, j, k, gap, n;
+ DPState **dpstates = NULL;
+ TPPLPoint p1, p2, p3, p4;
+ long bestvertex;
+ tppl_float weight, minweight, d1, d2;
+ Diagonal diagonal, newdiagonal;
+ DiagonalList diagonals;
+ TPPLPoly triangle;
+ int ret = 1;
+
+ n = poly->GetNumPoints();
+ dpstates = new DPState *[n];
+ for (i = 1; i < n; i++) {
+ dpstates[i] = new DPState[i];
+ }
+
+ // Initialize states and visibility.
+ for (i = 0; i < (n - 1); i++) {
+ p1 = poly->GetPoint(i);
+ for (j = i + 1; j < n; j++) {
+ dpstates[j][i].visible = true;
+ dpstates[j][i].weight = 0;
+ dpstates[j][i].bestvertex = -1;
+ if (j != (i + 1)) {
+ p2 = poly->GetPoint(j);
+
+ // Visibility check.
+ if (i == 0) {
+ p3 = poly->GetPoint(n - 1);
+ } else {
+ p3 = poly->GetPoint(i - 1);
+ }
+ if (i == (n - 1)) {
+ p4 = poly->GetPoint(0);
+ } else {
+ p4 = poly->GetPoint(i + 1);
+ }
+ if (!InCone(p3, p1, p4, p2)) {
+ dpstates[j][i].visible = false;
+ continue;
+ }
+
+ if (j == 0) {
+ p3 = poly->GetPoint(n - 1);
+ } else {
+ p3 = poly->GetPoint(j - 1);
+ }
+ if (j == (n - 1)) {
+ p4 = poly->GetPoint(0);
+ } else {
+ p4 = poly->GetPoint(j + 1);
+ }
+ if (!InCone(p3, p2, p4, p1)) {
+ dpstates[j][i].visible = false;
+ continue;
+ }
+
+ for (k = 0; k < n; k++) {
+ p3 = poly->GetPoint(k);
+ if (k == (n - 1)) {
+ p4 = poly->GetPoint(0);
+ } else {
+ p4 = poly->GetPoint(k + 1);
+ }
+ if (Intersects(p1, p2, p3, p4)) {
+ dpstates[j][i].visible = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ dpstates[n - 1][0].visible = true;
+ dpstates[n - 1][0].weight = 0;
+ dpstates[n - 1][0].bestvertex = -1;
+
+ for (gap = 2; gap < n; gap++) {
+ for (i = 0; i < (n - gap); i++) {
+ j = i + gap;
+ if (!dpstates[j][i].visible) {
+ continue;
+ }
+ bestvertex = -1;
+ for (k = (i + 1); k < j; k++) {
+ if (!dpstates[k][i].visible) {
+ continue;
+ }
+ if (!dpstates[j][k].visible) {
+ continue;
+ }
+
+ if (k <= (i + 1)) {
+ d1 = 0;
+ } else {
+ d1 = Distance(poly->GetPoint(i), poly->GetPoint(k));
+ }
+ if (j <= (k + 1)) {
+ d2 = 0;
+ } else {
+ d2 = Distance(poly->GetPoint(k), poly->GetPoint(j));
+ }
+
+ weight = dpstates[k][i].weight + dpstates[j][k].weight + d1 + d2;
+
+ if ((bestvertex == -1) || (weight < minweight)) {
+ bestvertex = k;
+ minweight = weight;
+ }
+ }
+ if (bestvertex == -1) {
+ for (i = 1; i < n; i++) {
+ delete[] dpstates[i];
+ }
+ delete[] dpstates;
+
+ return 0;
+ }
+
+ dpstates[j][i].bestvertex = bestvertex;
+ dpstates[j][i].weight = minweight;
+ }
+ }
+
+ newdiagonal.index1 = 0;
+ newdiagonal.index2 = n - 1;
+ diagonals.push_back(newdiagonal);
+ while (!diagonals.is_empty()) {
+ diagonal = diagonals.front()->get();
+ diagonals.pop_front();
+ bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex;
+ if (bestvertex == -1) {
+ ret = 0;
+ break;
+ }
+ triangle.Triangle(poly->GetPoint(diagonal.index1), poly->GetPoint(bestvertex), poly->GetPoint(diagonal.index2));
+ triangles->push_back(triangle);
+ if (bestvertex > (diagonal.index1 + 1)) {
+ newdiagonal.index1 = diagonal.index1;
+ newdiagonal.index2 = bestvertex;
+ diagonals.push_back(newdiagonal);
+ }
+ if (diagonal.index2 > (bestvertex + 1)) {
+ newdiagonal.index1 = bestvertex;
+ newdiagonal.index2 = diagonal.index2;
+ diagonals.push_back(newdiagonal);
+ }
+ }
+
+ for (i = 1; i < n; i++) {
+ delete[] dpstates[i];
+ }
+ delete[] dpstates;
+
+ return ret;
+}
+
+void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates) {
+ Diagonal newdiagonal;
+ DiagonalList *pairs = NULL;
+ long w2;
+
+ w2 = dpstates[a][b].weight;
+ if (w > w2) {
+ return;
+ }
+
+ pairs = &(dpstates[a][b].pairs);
+ newdiagonal.index1 = i;
+ newdiagonal.index2 = j;
+
+ if (w < w2) {
+ pairs->clear();
+ pairs->push_front(newdiagonal);
+ dpstates[a][b].weight = w;
+ } else {
+ if ((!pairs->is_empty()) && (i <= pairs->front()->get().index1)) {
+ return;
+ }
+ while ((!pairs->is_empty()) && (pairs->front()->get().index2 >= j)) {
+ pairs->pop_front();
+ }
+ pairs->push_front(newdiagonal);
+ }
+}
+
+void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
+ DiagonalList *pairs = NULL;
+ DiagonalList::Element *iter, *lastiter;
+ long top;
+ long w;
+
+ if (!dpstates[i][j].visible) {
+ return;
+ }
+ top = j;
+ w = dpstates[i][j].weight;
+ if (k - j > 1) {
+ if (!dpstates[j][k].visible) {
+ return;
+ }
+ w += dpstates[j][k].weight + 1;
+ }
+ if (j - i > 1) {
+ pairs = &(dpstates[i][j].pairs);
+ iter = pairs->back();
+ lastiter = pairs->back();
+ while (iter != pairs->front()) {
+ iter--;
+ if (!IsReflex(vertices[iter->get().index2].p, vertices[j].p, vertices[k].p)) {
+ lastiter = iter;
+ } else {
+ break;
+ }
+ }
+ if (lastiter == pairs->back()) {
+ w++;
+ } else {
+ if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->get().index1].p)) {
+ w++;
+ } else {
+ top = lastiter->get().index1;
+ }
+ }
+ }
+ UpdateState(i, k, w, top, j, dpstates);
+}
+
+void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
+ DiagonalList *pairs = NULL;
+ DiagonalList::Element *iter, *lastiter;
+ long top;
+ long w;
+
+ if (!dpstates[j][k].visible) {
+ return;
+ }
+ top = j;
+ w = dpstates[j][k].weight;
+
+ if (j - i > 1) {
+ if (!dpstates[i][j].visible) {
+ return;
+ }
+ w += dpstates[i][j].weight + 1;
+ }
+ if (k - j > 1) {
+ pairs = &(dpstates[j][k].pairs);
+
+ iter = pairs->front();
+ if ((!pairs->is_empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p))) {
+ lastiter = iter;
+ while (iter) {
+ if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p)) {
+ lastiter = iter;
+ iter = iter->next();
+ } else {
+ break;
+ }
+ }
+ if (IsReflex(vertices[lastiter->get().index2].p, vertices[k].p, vertices[i].p)) {
+ w++;
+ } else {
+ top = lastiter->get().index2;
+ }
+ } else {
+ w++;
+ }
+ }
+ UpdateState(i, k, w, j, top, dpstates);
+}
+
+int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
+ if (!poly->Valid()) {
+ return 0;
+ }
+
+ TPPLPoint p1, p2, p3, p4;
+ PartitionVertex *vertices = NULL;
+ DPState2 **dpstates = NULL;
+ long i, j, k, n, gap;
+ DiagonalList diagonals, diagonals2;
+ Diagonal diagonal, newdiagonal;
+ DiagonalList *pairs = NULL, *pairs2 = NULL;
+ DiagonalList::Element *iter, *iter2;
+ int ret;
+ TPPLPoly newpoly;
+ List<long> indices;
+ List<long>::Element *iiter;
+ bool ijreal, jkreal;
+
+ n = poly->GetNumPoints();
+ vertices = new PartitionVertex[n];
+
+ dpstates = new DPState2 *[n];
+ for (i = 0; i < n; i++) {
+ dpstates[i] = new DPState2[n];
+ }
+
+ // Initialize vertex information.
+ for (i = 0; i < n; i++) {
+ vertices[i].p = poly->GetPoint(i);
+ vertices[i].isActive = true;
+ if (i == 0) {
+ vertices[i].previous = &(vertices[n - 1]);
+ } else {
+ vertices[i].previous = &(vertices[i - 1]);
+ }
+ if (i == (poly->GetNumPoints() - 1)) {
+ vertices[i].next = &(vertices[0]);
+ } else {
+ vertices[i].next = &(vertices[i + 1]);
+ }
+ }
+ for (i = 1; i < n; i++) {
+ UpdateVertexReflexity(&(vertices[i]));
+ }
+
+ // Initialize states and visibility.
+ for (i = 0; i < (n - 1); i++) {
+ p1 = poly->GetPoint(i);
+ for (j = i + 1; j < n; j++) {
+ dpstates[i][j].visible = true;
+ if (j == i + 1) {
+ dpstates[i][j].weight = 0;
+ } else {
+ dpstates[i][j].weight = 2147483647;
+ }
+ if (j != (i + 1)) {
+ p2 = poly->GetPoint(j);
+
+ // Visibility check.
+ if (!InCone(&vertices[i], p2)) {
+ dpstates[i][j].visible = false;
+ continue;
+ }
+ if (!InCone(&vertices[j], p1)) {
+ dpstates[i][j].visible = false;
+ continue;
+ }
+
+ for (k = 0; k < n; k++) {
+ p3 = poly->GetPoint(k);
+ if (k == (n - 1)) {
+ p4 = poly->GetPoint(0);
+ } else {
+ p4 = poly->GetPoint(k + 1);
+ }
+ if (Intersects(p1, p2, p3, p4)) {
+ dpstates[i][j].visible = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ for (i = 0; i < (n - 2); i++) {
+ j = i + 2;
+ if (dpstates[i][j].visible) {
+ dpstates[i][j].weight = 0;
+ newdiagonal.index1 = i + 1;
+ newdiagonal.index2 = i + 1;
+ dpstates[i][j].pairs.push_back(newdiagonal);
+ }
+ }
+
+ dpstates[0][n - 1].visible = true;
+ vertices[0].isConvex = false; // By convention.
+
+ for (gap = 3; gap < n; gap++) {
+ for (i = 0; i < n - gap; i++) {
+ if (vertices[i].isConvex) {
+ continue;
+ }
+ k = i + gap;
+ if (dpstates[i][k].visible) {
+ if (!vertices[k].isConvex) {
+ for (j = i + 1; j < k; j++) {
+ TypeA(i, j, k, vertices, dpstates);
+ }
+ } else {
+ for (j = i + 1; j < (k - 1); j++) {
+ if (vertices[j].isConvex) {
+ continue;
+ }
+ TypeA(i, j, k, vertices, dpstates);
+ }
+ TypeA(i, k - 1, k, vertices, dpstates);
+ }
+ }
+ }
+ for (k = gap; k < n; k++) {
+ if (vertices[k].isConvex) {
+ continue;
+ }
+ i = k - gap;
+ if ((vertices[i].isConvex) && (dpstates[i][k].visible)) {
+ TypeB(i, i + 1, k, vertices, dpstates);
+ for (j = i + 2; j < k; j++) {
+ if (vertices[j].isConvex) {
+ continue;
+ }
+ TypeB(i, j, k, vertices, dpstates);
+ }
+ }
+ }
+ }
+
+ // Recover solution.
+ ret = 1;
+ newdiagonal.index1 = 0;
+ newdiagonal.index2 = n - 1;
+ diagonals.push_front(newdiagonal);
+ while (!diagonals.is_empty()) {
+ diagonal = diagonals.front()->get();
+ diagonals.pop_front();
+ if ((diagonal.index2 - diagonal.index1) <= 1) {
+ continue;
+ }
+ pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
+ if (pairs->is_empty()) {
+ ret = 0;
+ break;
+ }
+ if (!vertices[diagonal.index1].isConvex) {
+ iter = pairs->back();
+ iter--;
+ j = iter->get().index2;
+ newdiagonal.index1 = j;
+ newdiagonal.index2 = diagonal.index2;
+ diagonals.push_front(newdiagonal);
+ if ((j - diagonal.index1) > 1) {
+ if (iter->get().index1 != iter->get().index2) {
+ pairs2 = &(dpstates[diagonal.index1][j].pairs);
+ while (1) {
+ if (pairs2->is_empty()) {
+ ret = 0;
+ break;
+ }
+ iter2 = pairs2->back();
+ iter2--;
+ if (iter->get().index1 != iter2->get().index1) {
+ pairs2->pop_back();
+ } else {
+ break;
+ }
+ }
+ if (ret == 0) {
+ break;
+ }
+ }
+ newdiagonal.index1 = diagonal.index1;
+ newdiagonal.index2 = j;
+ diagonals.push_front(newdiagonal);
+ }
+ } else {
+ iter = pairs->front();
+ j = iter->get().index1;
+ newdiagonal.index1 = diagonal.index1;
+ newdiagonal.index2 = j;
+ diagonals.push_front(newdiagonal);
+ if ((diagonal.index2 - j) > 1) {
+ if (iter->get().index1 != iter->get().index2) {
+ pairs2 = &(dpstates[j][diagonal.index2].pairs);
+ while (1) {
+ if (pairs2->is_empty()) {
+ ret = 0;
+ break;
+ }
+ iter2 = pairs2->front();
+ if (iter->get().index2 != iter2->get().index2) {
+ pairs2->pop_front();
+ } else {
+ break;
+ }
+ }
+ if (ret == 0) {
+ break;
+ }
+ }
+ newdiagonal.index1 = j;
+ newdiagonal.index2 = diagonal.index2;
+ diagonals.push_front(newdiagonal);
+ }
+ }
+ }
+
+ if (ret == 0) {
+ for (i = 0; i < n; i++) {
+ delete[] dpstates[i];
+ }
+ delete[] dpstates;
+ delete[] vertices;
+
+ return ret;
+ }
+
+ newdiagonal.index1 = 0;
+ newdiagonal.index2 = n - 1;
+ diagonals.push_front(newdiagonal);
+ while (!diagonals.is_empty()) {
+ diagonal = diagonals.front()->get();
+ diagonals.pop_front();
+ if ((diagonal.index2 - diagonal.index1) <= 1) {
+ continue;
+ }
+
+ indices.clear();
+ diagonals2.clear();
+ indices.push_back(diagonal.index1);
+ indices.push_back(diagonal.index2);
+ diagonals2.push_front(diagonal);
+
+ while (!diagonals2.is_empty()) {
+ diagonal = diagonals2.front()->get();
+ diagonals2.pop_front();
+ if ((diagonal.index2 - diagonal.index1) <= 1) {
+ continue;
+ }
+ ijreal = true;
+ jkreal = true;
+ pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
+ if (!vertices[diagonal.index1].isConvex) {
+ iter = pairs->back();
+ iter--;
+ j = iter->get().index2;
+ if (iter->get().index1 != iter->get().index2) {
+ ijreal = false;
+ }
+ } else {
+ iter = pairs->front();
+ j = iter->get().index1;
+ if (iter->get().index1 != iter->get().index2) {
+ jkreal = false;
+ }
+ }
+
+ newdiagonal.index1 = diagonal.index1;
+ newdiagonal.index2 = j;
+ if (ijreal) {
+ diagonals.push_back(newdiagonal);
+ } else {
+ diagonals2.push_back(newdiagonal);
+ }
+
+ newdiagonal.index1 = j;
+ newdiagonal.index2 = diagonal.index2;
+ if (jkreal) {
+ diagonals.push_back(newdiagonal);
+ } else {
+ diagonals2.push_back(newdiagonal);
+ }
+
+ indices.push_back(j);
+ }
+
+ //std::sort(indices.begin(), indices.end());
+ indices.sort();
+ newpoly.Init((long)indices.size());
+ k = 0;
+ for (iiter = indices.front(); iiter != indices.back(); iiter = iiter->next()) {
+ newpoly[k] = vertices[iiter->get()].p;
+ k++;
+ }
+ parts->push_back(newpoly);
+ }
+
+ for (i = 0; i < n; i++) {
+ delete[] dpstates[i];
+ }
+ delete[] dpstates;
+ delete[] vertices;
+
+ return ret;
+}
+
+// Creates a monotone partition of a list of polygons that
+// can contain holes. Triangulates a set of polygons by
+// first partitioning them into monotone polygons.
+// Time complexity: O(n*log(n)), n is the number of vertices.
+// Space complexity: O(n)
+// The algorithm used here is outlined in the book
+// "Computational Geometry: Algorithms and Applications"
+// by Mark de Berg, Otfried Cheong, Marc van Kreveld, and Mark Overmars.
+int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys) {
+ TPPLPolyList::Element *iter;
+ MonotoneVertex *vertices = NULL;
+ long i, numvertices, vindex, vindex2, newnumvertices, maxnumvertices;
+ long polystartindex, polyendindex;
+ TPPLPoly *poly = NULL;
+ MonotoneVertex *v = NULL, *v2 = NULL, *vprev = NULL, *vnext = NULL;
+ ScanLineEdge newedge;
+ bool error = false;
+
+ numvertices = 0;
+ for (iter = inpolys->front(); iter; iter++) {
+ numvertices += iter->get().GetNumPoints();
+ }
+
+ maxnumvertices = numvertices * 3;
+ vertices = new MonotoneVertex[maxnumvertices];
+ newnumvertices = numvertices;
+
+ polystartindex = 0;
+ for (iter = inpolys->front(); iter; iter++) {
+ poly = &(iter->get());
+ polyendindex = polystartindex + poly->GetNumPoints() - 1;
+ for (i = 0; i < poly->GetNumPoints(); i++) {
+ vertices[i + polystartindex].p = poly->GetPoint(i);
+ if (i == 0) {
+ vertices[i + polystartindex].previous = polyendindex;
+ } else {
+ vertices[i + polystartindex].previous = i + polystartindex - 1;
+ }
+ if (i == (poly->GetNumPoints() - 1)) {
+ vertices[i + polystartindex].next = polystartindex;
+ } else {
+ vertices[i + polystartindex].next = i + polystartindex + 1;
+ }
+ }
+ polystartindex = polyendindex + 1;
+ }
+
+ // Construct the priority queue.
+ long *priority = new long[numvertices];
+ for (i = 0; i < numvertices; i++) {
+ priority[i] = i;
+ }
+ std::sort(priority, &(priority[numvertices]), VertexSorter(vertices));
+
+ // Determine vertex types.
+ TPPLVertexType *vertextypes = new TPPLVertexType[maxnumvertices];
+ for (i = 0; i < numvertices; i++) {
+ v = &(vertices[i]);
+ vprev = &(vertices[v->previous]);
+ vnext = &(vertices[v->next]);
+
+ if (Below(vprev->p, v->p) && Below(vnext->p, v->p)) {
+ if (IsConvex(vnext->p, vprev->p, v->p)) {
+ vertextypes[i] = TPPL_VERTEXTYPE_START;
+ } else {
+ vertextypes[i] = TPPL_VERTEXTYPE_SPLIT;
+ }
+ } else if (Below(v->p, vprev->p) && Below(v->p, vnext->p)) {
+ if (IsConvex(vnext->p, vprev->p, v->p)) {
+ vertextypes[i] = TPPL_VERTEXTYPE_END;
+ } else {
+ vertextypes[i] = TPPL_VERTEXTYPE_MERGE;
+ }
+ } else {
+ vertextypes[i] = TPPL_VERTEXTYPE_REGULAR;
+ }
+ }
+
+ // Helpers.
+ long *helpers = new long[maxnumvertices];
+
+ // Binary search tree that holds edges intersecting the scanline.
+ // Note that while set doesn't actually have to be implemented as
+ // a tree, complexity requirements for operations are the same as
+ // for the balanced binary search tree.
+ Set<ScanLineEdge> edgeTree;
+ // Store iterators to the edge tree elements.
+ // This makes deleting existing edges much faster.
+ Set<ScanLineEdge>::Element **edgeTreeIterators, *edgeIter;
+ edgeTreeIterators = new Set<ScanLineEdge>::Element *[maxnumvertices];
+ //Pair<Set<ScanLineEdge>::iterator, bool> edgeTreeRet;
+ for (i = 0; i < numvertices; i++) {
+ edgeTreeIterators[i] = nullptr;
+ }
+
+ // For each vertex.
+ for (i = 0; i < numvertices; i++) {
+ vindex = priority[i];
+ v = &(vertices[vindex]);
+ vindex2 = vindex;
+ v2 = v;
+
+ // Depending on the vertex type, do the appropriate action.
+ // Comments in the following sections are copied from
+ // "Computational Geometry: Algorithms and Applications".
+ // Notation: e_i = e subscript i, v_i = v subscript i, etc.
+ switch (vertextypes[vindex]) {
+ case TPPL_VERTEXTYPE_START:
+ // Insert e_i in T and set helper(e_i) to v_i.
+ newedge.p1 = v->p;
+ newedge.p2 = vertices[v->next].p;
+ newedge.index = vindex;
+ //edgeTreeRet = edgeTree.insert(newedge);
+ //edgeTreeIterators[vindex] = edgeTreeRet.first;
+ edgeTreeIterators[vindex] = edgeTree.insert(newedge);
+ helpers[vindex] = vindex;
+ break;
+
+ case TPPL_VERTEXTYPE_END:
+ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
+ error = true;
+ break;
+ }
+ // If helper(e_i - 1) is a merge vertex
+ if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) {
+ // Insert the diagonal connecting vi to helper(e_i - 1) in D.
+ AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ }
+ // Delete e_i - 1 from T
+ edgeTree.erase(edgeTreeIterators[v->previous]);
+ break;
+
+ case TPPL_VERTEXTYPE_SPLIT:
+ // Search in T to find the edge e_j directly left of v_i.
+ newedge.p1 = v->p;
+ newedge.p2 = v->p;
+ edgeIter = edgeTree.lower_bound(newedge);
+ if (edgeIter == edgeTree.front()) {
+ error = true;
+ break;
+ }
+ edgeIter--;
+ // Insert the diagonal connecting vi to helper(e_j) in D.
+ AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ vindex2 = newnumvertices - 2;
+ v2 = &(vertices[vindex2]);
+ // helper(e_j) in v_i.
+ helpers[edgeIter->get().index] = vindex;
+ // Insert e_i in T and set helper(e_i) to v_i.
+ newedge.p1 = v2->p;
+ newedge.p2 = vertices[v2->next].p;
+ newedge.index = vindex2;
+ //edgeTreeRet = edgeTree.insert(newedge);
+ //edgeTreeIterators[vindex2] = edgeTreeRet.first;
+ edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
+ helpers[vindex2] = vindex2;
+ break;
+
+ case TPPL_VERTEXTYPE_MERGE:
+ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
+ error = true;
+ break;
+ }
+ // if helper(e_i - 1) is a merge vertex
+ if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) {
+ // Insert the diagonal connecting vi to helper(e_i - 1) in D.
+ AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ vindex2 = newnumvertices - 2;
+ v2 = &(vertices[vindex2]);
+ }
+ // Delete e_i - 1 from T.
+ edgeTree.erase(edgeTreeIterators[v->previous]);
+ // Search in T to find the edge e_j directly left of v_i.
+ newedge.p1 = v->p;
+ newedge.p2 = v->p;
+ edgeIter = edgeTree.lower_bound(newedge);
+ if (edgeIter == edgeTree.front()) {
+ error = true;
+ break;
+ }
+ edgeIter--;
+ // If helper(e_j) is a merge vertex.
+ if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) {
+ // Insert the diagonal connecting v_i to helper(e_j) in D.
+ AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->get().index],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ }
+ // helper(e_j) <- v_i
+ helpers[edgeIter->get().index] = vindex2;
+ break;
+
+ case TPPL_VERTEXTYPE_REGULAR:
+ // If the interior of P lies to the right of v_i.
+ if (Below(v->p, vertices[v->previous].p)) {
+ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
+ error = true;
+ break;
+ }
+ // If helper(e_i - 1) is a merge vertex.
+ if (vertextypes[helpers[v->previous]] == TPPL_VERTEXTYPE_MERGE) {
+ // Insert the diagonal connecting v_i to helper(e_i - 1) in D.
+ AddDiagonal(vertices, &newnumvertices, vindex, helpers[v->previous],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ vindex2 = newnumvertices - 2;
+ v2 = &(vertices[vindex2]);
+ }
+ // Delete e_i - 1 from T.
+ edgeTree.erase(edgeTreeIterators[v->previous]);
+ // Insert e_i in T and set helper(e_i) to v_i.
+ newedge.p1 = v2->p;
+ newedge.p2 = vertices[v2->next].p;
+ newedge.index = vindex2;
+ //edgeTreeRet = edgeTree.insert(newedge);
+ //edgeTreeIterators[vindex2] = edgeTreeRet.first;
+ edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
+ helpers[vindex2] = vindex;
+ } else {
+ // Search in T to find the edge e_j directly left of v_i.
+ newedge.p1 = v->p;
+ newedge.p2 = v->p;
+ edgeIter = edgeTree.lower_bound(newedge);
+ if (edgeIter == edgeTree.front()) {
+ error = true;
+ break;
+ }
+ edgeIter = edgeIter->prev();
+ // If helper(e_j) is a merge vertex.
+ if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) {
+ // Insert the diagonal connecting v_i to helper(e_j) in D.
+ AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index],
+ vertextypes, edgeTreeIterators, &edgeTree, helpers);
+ }
+ // helper(e_j) <- v_i.
+ helpers[edgeIter->get().index] = vindex;
+ }
+ break;
+ }
+
+ if (error)
+ break;
+ }
+
+ char *used = new char[newnumvertices];
+ memset(used, 0, newnumvertices * sizeof(char));
+
+ if (!error) {
+ // Return result.
+ long size;
+ TPPLPoly mpoly;
+ for (i = 0; i < newnumvertices; i++) {
+ if (used[i]) {
+ continue;
+ }
+ v = &(vertices[i]);
+ vnext = &(vertices[v->next]);
+ size = 1;
+ while (vnext != v) {
+ vnext = &(vertices[vnext->next]);
+ size++;
+ }
+ mpoly.Init(size);
+ v = &(vertices[i]);
+ mpoly[0] = v->p;
+ vnext = &(vertices[v->next]);
+ size = 1;
+ used[i] = 1;
+ used[v->next] = 1;
+ while (vnext != v) {
+ mpoly[size] = vnext->p;
+ used[vnext->next] = 1;
+ vnext = &(vertices[vnext->next]);
+ size++;
+ }
+ monotonePolys->push_back(mpoly);
+ }
+ }
+
+ // Cleanup.
+ delete[] vertices;
+ delete[] priority;
+ delete[] vertextypes;
+ delete[] edgeTreeIterators;
+ delete[] helpers;
+ delete[] used;
+
+ if (error) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+// Adds a diagonal to the doubly-connected list of vertices.
+void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
+ TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
+ Set<ScanLineEdge> *edgeTree, long *helpers) {
+ long newindex1, newindex2;
+
+ newindex1 = *numvertices;
+ (*numvertices)++;
+ newindex2 = *numvertices;
+ (*numvertices)++;
+
+ vertices[newindex1].p = vertices[index1].p;
+ vertices[newindex2].p = vertices[index2].p;
+
+ vertices[newindex2].next = vertices[index2].next;
+ vertices[newindex1].next = vertices[index1].next;
+
+ vertices[vertices[index2].next].previous = newindex2;
+ vertices[vertices[index1].next].previous = newindex1;
+
+ vertices[index1].next = newindex2;
+ vertices[newindex2].previous = index1;
+
+ vertices[index2].next = newindex1;
+ vertices[newindex1].previous = index2;
+
+ // Update all relevant structures.
+ vertextypes[newindex1] = vertextypes[index1];
+ edgeTreeIterators[newindex1] = edgeTreeIterators[index1];
+ helpers[newindex1] = helpers[index1];
+ if (edgeTreeIterators[newindex1] != edgeTree->back()) {
+ edgeTreeIterators[newindex1]->get().index = newindex1;
+ }
+ vertextypes[newindex2] = vertextypes[index2];
+ edgeTreeIterators[newindex2] = edgeTreeIterators[index2];
+ helpers[newindex2] = helpers[index2];
+ if (edgeTreeIterators[newindex2] != edgeTree->back()) {
+ edgeTreeIterators[newindex2]->get().index = newindex2;
+ }
+}
+
+bool TPPLPartition::Below(TPPLPoint &p1, TPPLPoint &p2) {
+ if (p1.y < p2.y) {
+ return true;
+ } else if (p1.y == p2.y) {
+ if (p1.x < p2.x) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Sorts in the falling order of y values, if y is equal, x is used instead.
+bool TPPLPartition::VertexSorter::operator()(long index1, long index2) {
+ if (vertices[index1].p.y > vertices[index2].p.y) {
+ return true;
+ } else if (vertices[index1].p.y == vertices[index2].p.y) {
+ if (vertices[index1].p.x > vertices[index2].p.x) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TPPLPartition::ScanLineEdge::IsConvex(const TPPLPoint &p1, const TPPLPoint &p2, const TPPLPoint &p3) const {
+ tppl_float tmp;
+ tmp = (p3.y - p1.y) * (p2.x - p1.x) - (p3.x - p1.x) * (p2.y - p1.y);
+ if (tmp > 0) {
+ return 1;
+ }
+
+ return 0;
+}
+
+bool TPPLPartition::ScanLineEdge::operator<(const ScanLineEdge &other) const {
+ if (other.p1.y == other.p2.y) {
+ if (p1.y == p2.y) {
+ return (p1.y < other.p1.y);
+ }
+ return IsConvex(p1, p2, other.p1);
+ } else if (p1.y == p2.y) {
+ return !IsConvex(other.p1, other.p2, p1);
+ } else if (p1.y < other.p1.y) {
+ return !IsConvex(other.p1, other.p2, p1);
+ } else {
+ return IsConvex(p1, p2, other.p1);
+ }
+}
+
+// Triangulates monotone polygon.
+// Time complexity: O(n)
+// Space complexity: O(n)
+int TPPLPartition::TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles) {
+ if (!inPoly->Valid()) {
+ return 0;
+ }
+
+ long i, i2, j, topindex, bottomindex, leftindex, rightindex, vindex;
+ TPPLPoint *points = NULL;
+ long numpoints;
+ TPPLPoly triangle;
+
+ numpoints = inPoly->GetNumPoints();
+ points = inPoly->GetPoints();
+
+ // Trivial case.
+ if (numpoints == 3) {
+ triangles->push_back(*inPoly);
+ return 1;
+ }
+
+ topindex = 0;
+ bottomindex = 0;
+ for (i = 1; i < numpoints; i++) {
+ if (Below(points[i], points[bottomindex])) {
+ bottomindex = i;
+ }
+ if (Below(points[topindex], points[i])) {
+ topindex = i;
+ }
+ }
+
+ // Check if the poly is really monotone.
+ i = topindex;
+ while (i != bottomindex) {
+ i2 = i + 1;
+ if (i2 >= numpoints) {
+ i2 = 0;
+ }
+ if (!Below(points[i2], points[i])) {
+ return 0;
+ }
+ i = i2;
+ }
+ i = bottomindex;
+ while (i != topindex) {
+ i2 = i + 1;
+ if (i2 >= numpoints) {
+ i2 = 0;
+ }
+ if (!Below(points[i], points[i2])) {
+ return 0;
+ }
+ i = i2;
+ }
+
+ char *vertextypes = new char[numpoints];
+ long *priority = new long[numpoints];
+
+ // Merge left and right vertex chains.
+ priority[0] = topindex;
+ vertextypes[topindex] = 0;
+ leftindex = topindex + 1;
+ if (leftindex >= numpoints) {
+ leftindex = 0;
+ }
+ rightindex = topindex - 1;
+ if (rightindex < 0) {
+ rightindex = numpoints - 1;
+ }
+ for (i = 1; i < (numpoints - 1); i++) {
+ if (leftindex == bottomindex) {
+ priority[i] = rightindex;
+ rightindex--;
+ if (rightindex < 0) {
+ rightindex = numpoints - 1;
+ }
+ vertextypes[priority[i]] = -1;
+ } else if (rightindex == bottomindex) {
+ priority[i] = leftindex;
+ leftindex++;
+ if (leftindex >= numpoints) {
+ leftindex = 0;
+ }
+ vertextypes[priority[i]] = 1;
+ } else {
+ if (Below(points[leftindex], points[rightindex])) {
+ priority[i] = rightindex;
+ rightindex--;
+ if (rightindex < 0) {
+ rightindex = numpoints - 1;
+ }
+ vertextypes[priority[i]] = -1;
+ } else {
+ priority[i] = leftindex;
+ leftindex++;
+ if (leftindex >= numpoints) {
+ leftindex = 0;
+ }
+ vertextypes[priority[i]] = 1;
+ }
+ }
+ }
+ priority[i] = bottomindex;
+ vertextypes[bottomindex] = 0;
+
+ long *stack = new long[numpoints];
+ long stackptr = 0;
+
+ stack[0] = priority[0];
+ stack[1] = priority[1];
+ stackptr = 2;
+
+ // For each vertex from top to bottom trim as many triangles as possible.
+ for (i = 2; i < (numpoints - 1); i++) {
+ vindex = priority[i];
+ if (vertextypes[vindex] != vertextypes[stack[stackptr - 1]]) {
+ for (j = 0; j < (stackptr - 1); j++) {
+ if (vertextypes[vindex] == 1) {
+ triangle.Triangle(points[stack[j + 1]], points[stack[j]], points[vindex]);
+ } else {
+ triangle.Triangle(points[stack[j]], points[stack[j + 1]], points[vindex]);
+ }
+ triangles->push_back(triangle);
+ }
+ stack[0] = priority[i - 1];
+ stack[1] = priority[i];
+ stackptr = 2;
+ } else {
+ stackptr--;
+ while (stackptr > 0) {
+ if (vertextypes[vindex] == 1) {
+ if (IsConvex(points[vindex], points[stack[stackptr - 1]], points[stack[stackptr]])) {
+ triangle.Triangle(points[vindex], points[stack[stackptr - 1]], points[stack[stackptr]]);
+ triangles->push_back(triangle);
+ stackptr--;
+ } else {
+ break;
+ }
+ } else {
+ if (IsConvex(points[vindex], points[stack[stackptr]], points[stack[stackptr - 1]])) {
+ triangle.Triangle(points[vindex], points[stack[stackptr]], points[stack[stackptr - 1]]);
+ triangles->push_back(triangle);
+ stackptr--;
+ } else {
+ break;
+ }
+ }
+ }
+ stackptr++;
+ stack[stackptr] = vindex;
+ stackptr++;
+ }
+ }
+ vindex = priority[i];
+ for (j = 0; j < (stackptr - 1); j++) {
+ if (vertextypes[stack[j + 1]] == 1) {
+ triangle.Triangle(points[stack[j]], points[stack[j + 1]], points[vindex]);
+ } else {
+ triangle.Triangle(points[stack[j + 1]], points[stack[j]], points[vindex]);
+ }
+ triangles->push_back(triangle);
+ }
+
+ delete[] priority;
+ delete[] vertextypes;
+ delete[] stack;
+
+ return 1;
+}
+
+int TPPLPartition::Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
+ TPPLPolyList monotone;
+ TPPLPolyList::Element *iter;
+
+ if (!MonotonePartition(inpolys, &monotone)) {
+ return 0;
+ }
+ for (iter = monotone.front(); iter; iter = iter->next()) {
+ if (!TriangulateMonotone(&(iter->get()), triangles)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int TPPLPartition::Triangulate_MONO(TPPLPoly *poly, TPPLPolyList *triangles) {
+ TPPLPolyList polys;
+ polys.push_back(*poly);
+
+ return Triangulate_MONO(&polys, triangles);
+}
diff --git a/thirdparty/misc/polypartition.h b/thirdparty/misc/polypartition.h
new file mode 100644
index 0000000000..b2d905a3ef
--- /dev/null
+++ b/thirdparty/misc/polypartition.h
@@ -0,0 +1,378 @@
+/*************************************************************************/
+/* Copyright (c) 2011-2021 Ivan Fratric and contributors. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef POLYPARTITION_H
+#define POLYPARTITION_H
+
+#include "core/math/vector2.h"
+#include "core/templates/list.h"
+#include "core/templates/set.h"
+
+typedef double tppl_float;
+
+enum TPPLOrientation {
+ TPPL_ORIENTATION_CW = -1,
+ TPPL_ORIENTATION_NONE = 0,
+ TPPL_ORIENTATION_CCW = 1,
+};
+
+enum TPPLVertexType {
+ TPPL_VERTEXTYPE_REGULAR = 0,
+ TPPL_VERTEXTYPE_START = 1,
+ TPPL_VERTEXTYPE_END = 2,
+ TPPL_VERTEXTYPE_SPLIT = 3,
+ TPPL_VERTEXTYPE_MERGE = 4,
+};
+
+// 2D point structure.
+typedef Vector2 TPPLPoint;
+
+// Polygon implemented as an array of points with a "hole" flag.
+class TPPLPoly {
+ protected:
+ TPPLPoint *points;
+ long numpoints;
+ bool hole;
+
+ public:
+ // Constructors and destructors.
+ TPPLPoly();
+ ~TPPLPoly();
+
+ TPPLPoly(const TPPLPoly &src);
+ TPPLPoly &operator=(const TPPLPoly &src);
+
+ // Getters and setters.
+ long GetNumPoints() const {
+ return numpoints;
+ }
+
+ bool IsHole() const {
+ return hole;
+ }
+
+ void SetHole(bool hole) {
+ this->hole = hole;
+ }
+
+ TPPLPoint &GetPoint(long i) {
+ return points[i];
+ }
+
+ const TPPLPoint &GetPoint(long i) const {
+ return points[i];
+ }
+
+ TPPLPoint *GetPoints() {
+ return points;
+ }
+
+ TPPLPoint &operator[](int i) {
+ return points[i];
+ }
+
+ const TPPLPoint &operator[](int i) const {
+ return points[i];
+ }
+
+ // Clears the polygon points.
+ void Clear();
+
+ // Inits the polygon with numpoints vertices.
+ void Init(long numpoints);
+
+ // Creates a triangle with points p1, p2, and p3.
+ void Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3);
+
+ // Inverts the orfer of vertices.
+ void Invert();
+
+ // Returns the orientation of the polygon.
+ // Possible values:
+ // TPPL_ORIENTATION_CCW: Polygon vertices are in counter-clockwise order.
+ // TPPL_ORIENTATION_CW: Polygon vertices are in clockwise order.
+ // TPPL_ORIENTATION_NONE: The polygon has no (measurable) area.
+ TPPLOrientation GetOrientation() const;
+
+ // Sets the polygon orientation.
+ // Possible values:
+ // TPPL_ORIENTATION_CCW: Sets vertices in counter-clockwise order.
+ // TPPL_ORIENTATION_CW: Sets vertices in clockwise order.
+ // TPPL_ORIENTATION_NONE: Reverses the orientation of the vertices if there
+ // is one, otherwise does nothing (if orientation is already NONE).
+ void SetOrientation(TPPLOrientation orientation);
+
+ // Checks whether a polygon is valid or not.
+ inline bool Valid() const { return this->numpoints >= 3; }
+};
+
+#ifdef TPPL_ALLOCATOR
+typedef List<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList;
+#else
+typedef List<TPPLPoly> TPPLPolyList;
+#endif
+
+class TPPLPartition {
+ protected:
+ struct PartitionVertex {
+ bool isActive;
+ bool isConvex;
+ bool isEar;
+
+ TPPLPoint p;
+ tppl_float angle;
+ PartitionVertex *previous;
+ PartitionVertex *next;
+
+ PartitionVertex();
+ };
+
+ struct MonotoneVertex {
+ TPPLPoint p;
+ long previous;
+ long next;
+ };
+
+ class VertexSorter {
+ MonotoneVertex *vertices;
+
+public:
+ VertexSorter(MonotoneVertex *v) :
+ vertices(v) {}
+ bool operator()(long index1, long index2);
+ };
+
+ struct Diagonal {
+ long index1;
+ long index2;
+ };
+
+#ifdef TPPL_ALLOCATOR
+ typedef List<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList;
+#else
+ typedef List<Diagonal> DiagonalList;
+#endif
+
+ // Dynamic programming state for minimum-weight triangulation.
+ struct DPState {
+ bool visible;
+ tppl_float weight;
+ long bestvertex;
+ };
+
+ // Dynamic programming state for convex partitioning.
+ struct DPState2 {
+ bool visible;
+ long weight;
+ DiagonalList pairs;
+ };
+
+ // Edge that intersects the scanline.
+ struct ScanLineEdge {
+ mutable long index;
+ TPPLPoint p1;
+ TPPLPoint p2;
+
+ // Determines if the edge is to the left of another edge.
+ bool operator<(const ScanLineEdge &other) const;
+
+ bool IsConvex(const TPPLPoint &p1, const TPPLPoint &p2, const TPPLPoint &p3) const;
+ };
+
+ // Standard helper functions.
+ bool IsConvex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3);
+ bool IsReflex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3);
+ bool IsInside(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p);
+
+ bool InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p);
+ bool InCone(PartitionVertex *v, TPPLPoint &p);
+
+ int Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22);
+
+ TPPLPoint Normalize(const TPPLPoint &p);
+ tppl_float Distance(const TPPLPoint &p1, const TPPLPoint &p2);
+
+ // Helper functions for Triangulate_EC.
+ void UpdateVertexReflexity(PartitionVertex *v);
+ void UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices);
+
+ // Helper functions for ConvexPartition_OPT.
+ void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates);
+ void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
+ void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
+
+ // Helper functions for MonotonePartition.
+ bool Below(TPPLPoint &p1, TPPLPoint &p2);
+ void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
+ TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
+ Set<ScanLineEdge> *edgeTree, long *helpers);
+
+ // Triangulates a monotone polygon, used in Triangulate_MONO.
+ int TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles);
+
+ public:
+ // Simple heuristic procedure for removing holes from a list of polygons.
+ // It works by creating a diagonal from the right-most hole vertex
+ // to some other visible vertex.
+ // Time complexity: O(h*(n^2)), h is the # of holes, n is the # of vertices.
+ // Space complexity: O(n)
+ // params:
+ // inpolys:
+ // A list of polygons that can contain holes.
+ // Vertices of all non-hole polys have to be in counter-clockwise order.
+ // Vertices of all hole polys have to be in clockwise order.
+ // outpolys:
+ // A list of polygons without holes.
+ // Returns 1 on success, 0 on failure.
+ int RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys);
+
+ // Triangulates a polygon by ear clipping.
+ // Time complexity: O(n^2), n is the number of vertices.
+ // Space complexity: O(n)
+ // params:
+ // poly:
+ // An input polygon to be triangulated.
+ // Vertices have to be in counter-clockwise order.
+ // triangles:
+ // A list of triangles (result).
+ // Returns 1 on success, 0 on failure.
+ int Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles);
+
+ // Triangulates a list of polygons that may contain holes by ear clipping
+ // algorithm. It first calls RemoveHoles to get rid of the holes, and then
+ // calls Triangulate_EC for each resulting polygon.
+ // Time complexity: O(h*(n^2)), h is the # of holes, n is the # of vertices.
+ // Space complexity: O(n)
+ // params:
+ // inpolys:
+ // A list of polygons to be triangulated (can contain holes).
+ // Vertices of all non-hole polys have to be in counter-clockwise order.
+ // Vertices of all hole polys have to be in clockwise order.
+ // triangles:
+ // A list of triangles (result).
+ // Returns 1 on success, 0 on failure.
+ int Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles);
+
+ // Creates an optimal polygon triangulation in terms of minimal edge length.
+ // Time complexity: O(n^3), n is the number of vertices
+ // Space complexity: O(n^2)
+ // params:
+ // poly:
+ // An input polygon to be triangulated.
+ // Vertices have to be in counter-clockwise order.
+ // triangles:
+ // A list of triangles (result).
+ // Returns 1 on success, 0 on failure.
+ int Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles);
+
+ // Triangulates a polygon by first partitioning it into monotone polygons.
+ // Time complexity: O(n*log(n)), n is the number of vertices.
+ // Space complexity: O(n)
+ // params:
+ // poly:
+ // An input polygon to be triangulated.
+ // Vertices have to be in counter-clockwise order.
+ // triangles:
+ // A list of triangles (result).
+ // Returns 1 on success, 0 on failure.
+ int Triangulate_MONO(TPPLPoly *poly, TPPLPolyList *triangles);
+
+ // Triangulates a list of polygons by first
+ // partitioning them into monotone polygons.
+ // Time complexity: O(n*log(n)), n is the number of vertices.
+ // Space complexity: O(n)
+ // params:
+ // inpolys:
+ // A list of polygons to be triangulated (can contain holes).
+ // Vertices of all non-hole polys have to be in counter-clockwise order.
+ // Vertices of all hole polys have to be in clockwise order.
+ // triangles:
+ // A list of triangles (result).
+ // Returns 1 on success, 0 on failure.
+ int Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles);
+
+ // Creates a monotone partition of a list of polygons that
+ // can contain holes. Triangulates a set of polygons by
+ // first partitioning them into monotone polygons.
+ // Time complexity: O(n*log(n)), n is the number of vertices.
+ // Space complexity: O(n)
+ // params:
+ // inpolys:
+ // A list of polygons to be triangulated (can contain holes).
+ // Vertices of all non-hole polys have to be in counter-clockwise order.
+ // Vertices of all hole polys have to be in clockwise order.
+ // monotonePolys:
+ // A list of monotone polygons (result).
+ // Returns 1 on success, 0 on failure.
+ int MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys);
+
+ // Partitions a polygon into convex polygons by using the
+ // Hertel-Mehlhorn algorithm. The algorithm gives at most four times
+ // the number of parts as the optimal algorithm, however, in practice
+ // it works much better than that and often gives optimal partition.
+ // It uses triangulation obtained by ear clipping as intermediate result.
+ // Time complexity O(n^2), n is the number of vertices.
+ // Space complexity: O(n)
+ // params:
+ // poly:
+ // An input polygon to be partitioned.
+ // Vertices have to be in counter-clockwise order.
+ // parts:
+ // Resulting list of convex polygons.
+ // Returns 1 on success, 0 on failure.
+ int ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts);
+
+ // Partitions a list of polygons into convex parts by using the
+ // Hertel-Mehlhorn algorithm. The algorithm gives at most four times
+ // the number of parts as the optimal algorithm, however, in practice
+ // it works much better than that and often gives optimal partition.
+ // It uses triangulation obtained by ear clipping as intermediate result.
+ // Time complexity O(n^2), n is the number of vertices.
+ // Space complexity: O(n)
+ // params:
+ // inpolys:
+ // An input list of polygons to be partitioned. Vertices of
+ // all non-hole polys have to be in counter-clockwise order.
+ // Vertices of all hole polys have to be in clockwise order.
+ // parts:
+ // Resulting list of convex polygons.
+ // Returns 1 on success, 0 on failure.
+ int ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts);
+
+ // Optimal convex partitioning (in terms of number of resulting
+ // convex polygons) using the Keil-Snoeyink algorithm.
+ // For reference, see M. Keil, J. Snoeyink, "On the time bound for
+ // convex decomposition of simple polygons", 1998.
+ // Time complexity O(n^3), n is the number of vertices.
+ // Space complexity: O(n^3)
+ // params:
+ // poly:
+ // An input polygon to be partitioned.
+ // Vertices have to be in counter-clockwise order.
+ // parts:
+ // Resulting list of convex polygons.
+ // Returns 1 on success, 0 on failure.
+ int ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts);
+};
+
+#endif
diff --git a/thirdparty/misc/r128.h b/thirdparty/misc/r128.h
index 1f7aab78fb..a345cc47ba 100644
--- a/thirdparty/misc/r128.h
+++ b/thirdparty/misc/r128.h
@@ -1,5 +1,5 @@
/*
-r128.h: 128-bit (64.64) signed fixed-point arithmetic. Version 1.4.3
+r128.h: 128-bit (64.64) signed fixed-point arithmetic. Version 1.4.4
COMPILATION
-----------
@@ -76,8 +76,8 @@ OTHER DEALINGS IN THE SOFTWARE.
# include <stdint.h>
# define R128_S32 int32_t
# define R128_U32 uint32_t
-# define R128_S64 int64_t
-# define R128_U64 uint64_t
+# define R128_S64 long long
+# define R128_U64 unsigned long long
# define R128_LIT_S64(x) x##ll
# define R128_LIT_U64(x) x##ull
#endif
@@ -701,7 +701,7 @@ static R128_U32 r128__udiv64(R128_U32 nlo, R128_U32 nhi, R128_U32 d, R128_U32 *r
return (R128_U32)(n64 / d);
# endif
}
-#elif !defined(_M_X64) || defined(R128_STDC_ONLY)
+#elif defined(R128_STDC_ONLY) || !R128_INTEL
#define r128__umul64(a, b) ((a) * (R128_U64)(b))
static R128_U32 r128__udiv64(R128_U32 nlo, R128_U32 nhi, R128_U32 d, R128_U32 *rem)
{
@@ -799,7 +799,7 @@ static void r128__umul128(R128 *dst, R128_U64 a, R128_U64 b)
// MSVC x64 provides neither inline assembly nor (pre-2019) a div intrinsic, so we do fake
// "inline assembly" to avoid long division or outline assembly.
#pragma code_seg(".text")
-__declspec(allocate(".text")) static const unsigned char r128__udiv128Code[] = {
+__declspec(allocate(".text") align(16)) static const unsigned char r128__udiv128Code[] = {
0x48, 0x8B, 0xC1, //mov rax, rcx
0x49, 0xF7, 0xF0, //div rax, r8
0x49, 0x89, 0x11, //mov qword ptr [r9], rdx
diff --git a/thirdparty/misc/triangulator.cpp b/thirdparty/misc/triangulator.cpp
deleted file mode 100644
index 75b2b064c4..0000000000
--- a/thirdparty/misc/triangulator.cpp
+++ /dev/null
@@ -1,1550 +0,0 @@
-//Copyright (C) 2011 by Ivan Fratric
-//
-//Permission is hereby granted, free of charge, to any person obtaining a copy
-//of this software and associated documentation files (the "Software"), to deal
-//in the Software without restriction, including without limitation the rights
-//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//copies of the Software, and to permit persons to whom the Software is
-//furnished to do so, subject to the following conditions:
-//
-//The above copyright notice and this permission notice shall be included in
-//all copies or substantial portions of the Software.
-//
-//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-//THE SOFTWARE.
-
-
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include "triangulator.h"
-
-
-#define TRIANGULATOR_VERTEXTYPE_REGULAR 0
-#define TRIANGULATOR_VERTEXTYPE_START 1
-#define TRIANGULATOR_VERTEXTYPE_END 2
-#define TRIANGULATOR_VERTEXTYPE_SPLIT 3
-#define TRIANGULATOR_VERTEXTYPE_MERGE 4
-
-TriangulatorPoly::TriangulatorPoly() {
- hole = false;
- numpoints = 0;
- points = NULL;
-}
-
-TriangulatorPoly::~TriangulatorPoly() {
- if(points) delete [] points;
-}
-
-void TriangulatorPoly::Clear() {
- if(points) delete [] points;
- hole = false;
- numpoints = 0;
- points = NULL;
-}
-
-void TriangulatorPoly::Init(long numpoints) {
- Clear();
- this->numpoints = numpoints;
- points = new Vector2[numpoints];
-}
-
-void TriangulatorPoly::Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3) {
- Init(3);
- points[0] = p1;
- points[1] = p2;
- points[2] = p3;
-}
-
-TriangulatorPoly::TriangulatorPoly(const TriangulatorPoly &src) {
- hole = src.hole;
- numpoints = src.numpoints;
- points = new Vector2[numpoints];
- memcpy(points, src.points, numpoints*sizeof(Vector2));
-}
-
-TriangulatorPoly& TriangulatorPoly::operator=(const TriangulatorPoly &src) {
- Clear();
- hole = src.hole;
- numpoints = src.numpoints;
- points = new Vector2[numpoints];
- memcpy(points, src.points, numpoints*sizeof(Vector2));
- return *this;
-}
-
-int TriangulatorPoly::GetOrientation() {
- long i1,i2;
- real_t area = 0;
- for(i1=0; i1<numpoints; i1++) {
- i2 = i1+1;
- if(i2 == numpoints) i2 = 0;
- area += points[i1].x * points[i2].y - points[i1].y * points[i2].x;
- }
- if(area>0) return TRIANGULATOR_CCW;
- if(area<0) return TRIANGULATOR_CW;
- return 0;
-}
-
-void TriangulatorPoly::SetOrientation(int orientation) {
- int polyorientation = GetOrientation();
- if(polyorientation&&(polyorientation!=orientation)) {
- Invert();
- }
-}
-
-void TriangulatorPoly::Invert() {
- long i;
- Vector2 *invpoints;
-
- invpoints = new Vector2[numpoints];
- for(i=0;i<numpoints;i++) {
- invpoints[i] = points[numpoints-i-1];
- }
-
- delete [] points;
- points = invpoints;
-}
-
-Vector2 TriangulatorPartition::Normalize(const Vector2 &p) {
- Vector2 r;
- real_t n = sqrt(p.x*p.x + p.y*p.y);
- if(n!=0) {
- r = p/n;
- } else {
- r.x = 0;
- r.y = 0;
- }
- return r;
-}
-
-real_t TriangulatorPartition::Distance(const Vector2 &p1, const Vector2 &p2) {
- real_t dx,dy;
- dx = p2.x - p1.x;
- dy = p2.y - p1.y;
- return(sqrt(dx*dx + dy*dy));
-}
-
-//checks if two lines intersect
-int TriangulatorPartition::Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, Vector2 &p22) {
- if((p11.x == p21.x)&&(p11.y == p21.y)) return 0;
- if((p11.x == p22.x)&&(p11.y == p22.y)) return 0;
- if((p12.x == p21.x)&&(p12.y == p21.y)) return 0;
- if((p12.x == p22.x)&&(p12.y == p22.y)) return 0;
-
- Vector2 v1ort,v2ort,v;
- real_t dot11,dot12,dot21,dot22;
-
- v1ort.x = p12.y-p11.y;
- v1ort.y = p11.x-p12.x;
-
- v2ort.x = p22.y-p21.y;
- v2ort.y = p21.x-p22.x;
-
- v = p21-p11;
- dot21 = v.x*v1ort.x + v.y*v1ort.y;
- v = p22-p11;
- dot22 = v.x*v1ort.x + v.y*v1ort.y;
-
- v = p11-p21;
- dot11 = v.x*v2ort.x + v.y*v2ort.y;
- v = p12-p21;
- dot12 = v.x*v2ort.x + v.y*v2ort.y;
-
- if(dot11*dot12>0) return 0;
- if(dot21*dot22>0) return 0;
-
- return 1;
-}
-
-//removes holes from inpolys by merging them with non-holes
-int TriangulatorPartition::RemoveHoles(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *outpolys) {
- List<TriangulatorPoly> polys;
- List<TriangulatorPoly>::Element *holeiter,*polyiter,*iter,*iter2;
- long i,i2,holepointindex,polypointindex;
- Vector2 holepoint,polypoint,bestpolypoint;
- Vector2 linep1,linep2;
- Vector2 v1,v2;
- TriangulatorPoly newpoly;
- bool hasholes;
- bool pointvisible;
- bool pointfound;
-
- //check for trivial case (no holes)
- hasholes = false;
- for(iter = inpolys->front(); iter; iter=iter->next()) {
- if(iter->get().IsHole()) {
- hasholes = true;
- break;
- }
- }
- if(!hasholes) {
- for(iter = inpolys->front(); iter; iter=iter->next()) {
- outpolys->push_back(iter->get());
- }
- return 1;
- }
-
- polys = *inpolys;
-
- while(1) {
- //find the hole point with the largest x
- hasholes = false;
- for(iter = polys.front(); iter; iter=iter->next()) {
- if(!iter->get().IsHole()) continue;
-
- if(!hasholes) {
- hasholes = true;
- holeiter = iter;
- holepointindex = 0;
- }
-
- for(i=0; i < iter->get().GetNumPoints(); i++) {
- if(iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) {
- holeiter = iter;
- holepointindex = i;
- }
- }
- }
- if(!hasholes) break;
- holepoint = holeiter->get().GetPoint(holepointindex);
-
- pointfound = false;
- for(iter = polys.front(); iter; iter=iter->next()) {
- if(iter->get().IsHole()) continue;
- for(i=0; i < iter->get().GetNumPoints(); i++) {
- if(iter->get().GetPoint(i).x <= holepoint.x) continue;
- if(!InCone(iter->get().GetPoint((i+iter->get().GetNumPoints()-1)%(iter->get().GetNumPoints())),
- iter->get().GetPoint(i),
- iter->get().GetPoint((i+1)%(iter->get().GetNumPoints())),
- holepoint))
- continue;
- polypoint = iter->get().GetPoint(i);
- if(pointfound) {
- v1 = Normalize(polypoint-holepoint);
- v2 = Normalize(bestpolypoint-holepoint);
- if(v2.x > v1.x) continue;
- }
- pointvisible = true;
- for(iter2 = polys.front(); iter2; iter2=iter2->next()) {
- if(iter2->get().IsHole()) continue;
- for(i2=0; i2 < iter2->get().GetNumPoints(); i2++) {
- linep1 = iter2->get().GetPoint(i2);
- linep2 = iter2->get().GetPoint((i2+1)%(iter2->get().GetNumPoints()));
- if(Intersects(holepoint,polypoint,linep1,linep2)) {
- pointvisible = false;
- break;
- }
- }
- if(!pointvisible) break;
- }
- if(pointvisible) {
- pointfound = true;
- bestpolypoint = polypoint;
- polyiter = iter;
- polypointindex = i;
- }
- }
- }
-
- if(!pointfound) return 0;
-
- newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2);
- i2 = 0;
- for(i=0;i<=polypointindex;i++) {
- newpoly[i2] = polyiter->get().GetPoint(i);
- i2++;
- }
- for(i=0;i<=holeiter->get().GetNumPoints();i++) {
- newpoly[i2] = holeiter->get().GetPoint((i+holepointindex)%holeiter->get().GetNumPoints());
- i2++;
- }
- for(i=polypointindex;i<polyiter->get().GetNumPoints();i++) {
- newpoly[i2] = polyiter->get().GetPoint(i);
- i2++;
- }
-
- polys.erase(holeiter);
- polys.erase(polyiter);
- polys.push_back(newpoly);
- }
-
- for(iter = polys.front(); iter; iter=iter->next()) {
- outpolys->push_back(iter->get());
- }
-
- return 1;
-}
-
-bool TriangulatorPartition::IsConvex(Vector2& p1, Vector2& p2, Vector2& p3) {
- real_t tmp;
- tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y);
- if(tmp>0) return 1;
- else return 0;
-}
-
-bool TriangulatorPartition::IsReflex(Vector2& p1, Vector2& p2, Vector2& p3) {
- real_t tmp;
- tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y);
- if(tmp<0) return 1;
- else return 0;
-}
-
-bool TriangulatorPartition::IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p) {
- if(IsConvex(p1,p,p2)) return false;
- if(IsConvex(p2,p,p3)) return false;
- if(IsConvex(p3,p,p1)) return false;
- return true;
-}
-
-bool TriangulatorPartition::InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p) {
- bool convex;
-
- convex = IsConvex(p1,p2,p3);
-
- if(convex) {
- if(!IsConvex(p1,p2,p)) return false;
- if(!IsConvex(p2,p3,p)) return false;
- return true;
- } else {
- if(IsConvex(p1,p2,p)) return true;
- if(IsConvex(p2,p3,p)) return true;
- return false;
- }
-}
-
-bool TriangulatorPartition::InCone(PartitionVertex *v, Vector2 &p) {
- Vector2 p1,p2,p3;
-
- p1 = v->previous->p;
- p2 = v->p;
- p3 = v->next->p;
-
- return InCone(p1,p2,p3,p);
-}
-
-void TriangulatorPartition::UpdateVertexReflexity(PartitionVertex *v) {
- PartitionVertex *v1,*v3;
- v1 = v->previous;
- v3 = v->next;
- v->isConvex = !IsReflex(v1->p,v->p,v3->p);
-}
-
-void TriangulatorPartition::UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices) {
- long i;
- PartitionVertex *v1,*v3;
- Vector2 vec1,vec3;
-
- v1 = v->previous;
- v3 = v->next;
-
- v->isConvex = IsConvex(v1->p,v->p,v3->p);
-
- vec1 = Normalize(v1->p - v->p);
- vec3 = Normalize(v3->p - v->p);
- v->angle = vec1.x*vec3.x + vec1.y*vec3.y;
-
- if(v->isConvex) {
- v->isEar = true;
- for(i=0;i<numvertices;i++) {
- if((vertices[i].p.x==v->p.x)&&(vertices[i].p.y==v->p.y)) continue;
- if((vertices[i].p.x==v1->p.x)&&(vertices[i].p.y==v1->p.y)) continue;
- if((vertices[i].p.x==v3->p.x)&&(vertices[i].p.y==v3->p.y)) continue;
- if(IsInside(v1->p,v->p,v3->p,vertices[i].p)) {
- v->isEar = false;
- break;
- }
- }
- } else {
- v->isEar = false;
- }
-}
-
-//triangulation by ear removal
-int TriangulatorPartition::Triangulate_EC(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles) {
- long numvertices;
- PartitionVertex *vertices;
- PartitionVertex *ear;
- TriangulatorPoly triangle;
- long i,j;
- bool earfound;
-
- if(poly->GetNumPoints() < 3) return 0;
- if(poly->GetNumPoints() == 3) {
- triangles->push_back(*poly);
- return 1;
- }
-
- numvertices = poly->GetNumPoints();
-
- vertices = new PartitionVertex[numvertices];
- for(i=0;i<numvertices;i++) {
- vertices[i].isActive = true;
- vertices[i].p = poly->GetPoint(i);
- if(i==(numvertices-1)) vertices[i].next=&(vertices[0]);
- else vertices[i].next=&(vertices[i+1]);
- if(i==0) vertices[i].previous = &(vertices[numvertices-1]);
- else vertices[i].previous = &(vertices[i-1]);
- }
- for(i=0;i<numvertices;i++) {
- UpdateVertex(&vertices[i],vertices,numvertices);
- }
-
- for(i=0;i<numvertices-3;i++) {
- earfound = false;
- //find the most extruded ear
- for(j=0;j<numvertices;j++) {
- if(!vertices[j].isActive) continue;
- if(!vertices[j].isEar) continue;
- if(!earfound) {
- earfound = true;
- ear = &(vertices[j]);
- } else {
- if(vertices[j].angle > ear->angle) {
- ear = &(vertices[j]);
- }
- }
- }
- if(!earfound) {
- delete [] vertices;
- return 0;
- }
-
- triangle.Triangle(ear->previous->p,ear->p,ear->next->p);
- triangles->push_back(triangle);
-
- ear->isActive = false;
- ear->previous->next = ear->next;
- ear->next->previous = ear->previous;
-
- if(i==numvertices-4) break;
-
- UpdateVertex(ear->previous,vertices,numvertices);
- UpdateVertex(ear->next,vertices,numvertices);
- }
- for(i=0;i<numvertices;i++) {
- if(vertices[i].isActive) {
- triangle.Triangle(vertices[i].previous->p,vertices[i].p,vertices[i].next->p);
- triangles->push_back(triangle);
- break;
- }
- }
-
- delete [] vertices;
-
- return 1;
-}
-
-int TriangulatorPartition::Triangulate_EC(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles) {
- List<TriangulatorPoly> outpolys;
- List<TriangulatorPoly>::Element*iter;
-
- if(!RemoveHoles(inpolys,&outpolys)) return 0;
- for(iter=outpolys.front();iter;iter=iter->next()) {
- if(!Triangulate_EC(&(iter->get()),triangles)) return 0;
- }
- return 1;
-}
-
-int TriangulatorPartition::ConvexPartition_HM(TriangulatorPoly *poly, List<TriangulatorPoly> *parts) {
- List<TriangulatorPoly> triangles;
- List<TriangulatorPoly>::Element *iter1,*iter2;
- TriangulatorPoly *poly1,*poly2;
- TriangulatorPoly newpoly;
- Vector2 d1,d2,p1,p2,p3;
- long i11,i12,i21,i22,i13,i23,j,k;
- bool isdiagonal;
- long numreflex;
-
- //check if the poly is already convex
- numreflex = 0;
- for(i11=0;i11<poly->GetNumPoints();i11++) {
- if(i11==0) i12 = poly->GetNumPoints()-1;
- else i12=i11-1;
- if(i11==(poly->GetNumPoints()-1)) i13=0;
- else i13=i11+1;
- if(IsReflex(poly->GetPoint(i12),poly->GetPoint(i11),poly->GetPoint(i13))) {
- numreflex = 1;
- break;
- }
- }
- if(numreflex == 0) {
- parts->push_back(*poly);
- return 1;
- }
-
- if(!Triangulate_EC(poly,&triangles)) return 0;
-
- for(iter1 = triangles.front(); iter1 ; iter1=iter1->next()) {
- poly1 = &(iter1->get());
- for(i11=0;i11<poly1->GetNumPoints();i11++) {
- d1 = poly1->GetPoint(i11);
- i12 = (i11+1)%(poly1->GetNumPoints());
- d2 = poly1->GetPoint(i12);
-
- isdiagonal = false;
- for(iter2 = iter1; iter2 ; iter2=iter2->next()) {
- if(iter1 == iter2) continue;
- poly2 = &(iter2->get());
-
- for(i21=0;i21<poly2->GetNumPoints();i21++) {
- if((d2.x != poly2->GetPoint(i21).x)||(d2.y != poly2->GetPoint(i21).y)) continue;
- i22 = (i21+1)%(poly2->GetNumPoints());
- if((d1.x != poly2->GetPoint(i22).x)||(d1.y != poly2->GetPoint(i22).y)) continue;
- isdiagonal = true;
- break;
- }
- if(isdiagonal) break;
- }
-
- if(!isdiagonal) continue;
-
- p2 = poly1->GetPoint(i11);
- if(i11 == 0) i13 = poly1->GetNumPoints()-1;
- else i13 = i11-1;
- p1 = poly1->GetPoint(i13);
- if(i22 == (poly2->GetNumPoints()-1)) i23 = 0;
- else i23 = i22+1;
- p3 = poly2->GetPoint(i23);
-
- if(!IsConvex(p1,p2,p3)) continue;
-
- p2 = poly1->GetPoint(i12);
- if(i12 == (poly1->GetNumPoints()-1)) i13 = 0;
- else i13 = i12+1;
- p3 = poly1->GetPoint(i13);
- if(i21 == 0) i23 = poly2->GetNumPoints()-1;
- else i23 = i21-1;
- p1 = poly2->GetPoint(i23);
-
- if(!IsConvex(p1,p2,p3)) continue;
-
- newpoly.Init(poly1->GetNumPoints()+poly2->GetNumPoints()-2);
- k = 0;
- for(j=i12;j!=i11;j=(j+1)%(poly1->GetNumPoints())) {
- newpoly[k] = poly1->GetPoint(j);
- k++;
- }
- for(j=i22;j!=i21;j=(j+1)%(poly2->GetNumPoints())) {
- newpoly[k] = poly2->GetPoint(j);
- k++;
- }
-
- triangles.erase(iter2);
- iter1->get() = newpoly;
- poly1 = &(iter1->get());
- i11 = -1;
-
- continue;
- }
- }
-
- for(iter1 = triangles.front(); iter1 ; iter1=iter1->next()) {
- parts->push_back(iter1->get());
- }
-
- return 1;
-}
-
-int TriangulatorPartition::ConvexPartition_HM(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *parts) {
- List<TriangulatorPoly> outpolys;
- List<TriangulatorPoly>::Element* iter;
-
- if(!RemoveHoles(inpolys,&outpolys)) return 0;
- for(iter=outpolys.front();iter;iter=iter->next()) {
- if(!ConvexPartition_HM(&(iter->get()),parts)) return 0;
- }
- return 1;
-}
-
-//minimum-weight polygon triangulation by dynamic programming
-//O(n^3) time complexity
-//O(n^2) space complexity
-int TriangulatorPartition::Triangulate_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles) {
- long i,j,k,gap,n;
- DPState **dpstates;
- Vector2 p1,p2,p3,p4;
- long bestvertex;
- real_t weight,minweight,d1,d2;
- Diagonal diagonal,newdiagonal;
- List<Diagonal> diagonals;
- TriangulatorPoly triangle;
- int ret = 1;
-
- n = poly->GetNumPoints();
- dpstates = new DPState *[n];
- for(i=1;i<n;i++) {
- dpstates[i] = new DPState[i];
- }
-
- //init states and visibility
- for(i=0;i<(n-1);i++) {
- p1 = poly->GetPoint(i);
- for(j=i+1;j<n;j++) {
- dpstates[j][i].visible = true;
- dpstates[j][i].weight = 0;
- dpstates[j][i].bestvertex = -1;
- if(j!=(i+1)) {
- p2 = poly->GetPoint(j);
-
- //visibility check
- if(i==0) p3 = poly->GetPoint(n-1);
- else p3 = poly->GetPoint(i-1);
- if(i==(n-1)) p4 = poly->GetPoint(0);
- else p4 = poly->GetPoint(i+1);
- if(!InCone(p3,p1,p4,p2)) {
- dpstates[j][i].visible = false;
- continue;
- }
-
- if(j==0) p3 = poly->GetPoint(n-1);
- else p3 = poly->GetPoint(j-1);
- if(j==(n-1)) p4 = poly->GetPoint(0);
- else p4 = poly->GetPoint(j+1);
- if(!InCone(p3,p2,p4,p1)) {
- dpstates[j][i].visible = false;
- continue;
- }
-
- for(k=0;k<n;k++) {
- p3 = poly->GetPoint(k);
- if(k==(n-1)) p4 = poly->GetPoint(0);
- else p4 = poly->GetPoint(k+1);
- if(Intersects(p1,p2,p3,p4)) {
- dpstates[j][i].visible = false;
- break;
- }
- }
- }
- }
- }
- dpstates[n-1][0].visible = true;
- dpstates[n-1][0].weight = 0;
- dpstates[n-1][0].bestvertex = -1;
-
- for(gap = 2; gap<n; gap++) {
- for(i=0; i<(n-gap); i++) {
- j = i+gap;
- if(!dpstates[j][i].visible) continue;
- bestvertex = -1;
- for(k=(i+1);k<j;k++) {
- if(!dpstates[k][i].visible) continue;
- if(!dpstates[j][k].visible) continue;
-
- if(k<=(i+1)) d1=0;
- else d1 = Distance(poly->GetPoint(i),poly->GetPoint(k));
- if(j<=(k+1)) d2=0;
- else d2 = Distance(poly->GetPoint(k),poly->GetPoint(j));
-
- weight = dpstates[k][i].weight + dpstates[j][k].weight + d1 + d2;
-
- if((bestvertex == -1)||(weight<minweight)) {
- bestvertex = k;
- minweight = weight;
- }
- }
- if(bestvertex == -1) {
- for(i=1;i<n;i++) {
- delete [] dpstates[i];
- }
- delete [] dpstates;
-
- return 0;
- }
-
- dpstates[j][i].bestvertex = bestvertex;
- dpstates[j][i].weight = minweight;
- }
- }
-
- newdiagonal.index1 = 0;
- newdiagonal.index2 = n-1;
- diagonals.push_back(newdiagonal);
- while(!diagonals.empty()) {
- diagonal = (diagonals.front()->get());
- diagonals.pop_front();
- bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex;
- if(bestvertex == -1) {
- ret = 0;
- break;
- }
- triangle.Triangle(poly->GetPoint(diagonal.index1),poly->GetPoint(bestvertex),poly->GetPoint(diagonal.index2));
- triangles->push_back(triangle);
- if(bestvertex > (diagonal.index1+1)) {
- newdiagonal.index1 = diagonal.index1;
- newdiagonal.index2 = bestvertex;
- diagonals.push_back(newdiagonal);
- }
- if(diagonal.index2 > (bestvertex+1)) {
- newdiagonal.index1 = bestvertex;
- newdiagonal.index2 = diagonal.index2;
- diagonals.push_back(newdiagonal);
- }
- }
-
- for(i=1;i<n;i++) {
- delete [] dpstates[i];
- }
- delete [] dpstates;
-
- return ret;
-}
-
-void TriangulatorPartition::UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates) {
- Diagonal newdiagonal;
- List<Diagonal> *pairs;
- long w2;
-
- w2 = dpstates[a][b].weight;
- if(w>w2) return;
-
- pairs = &(dpstates[a][b].pairs);
- newdiagonal.index1 = i;
- newdiagonal.index2 = j;
-
- if(w<w2) {
- pairs->clear();
- pairs->push_front(newdiagonal);
- dpstates[a][b].weight = w;
- } else {
- if((!pairs->empty())&&(i <= pairs->front()->get().index1)) return;
- while((!pairs->empty())&&(pairs->front()->get().index2 >= j)) pairs->pop_front();
- pairs->push_front(newdiagonal);
- }
-}
-
-void TriangulatorPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
- List<Diagonal> *pairs;
- List<Diagonal>::Element *iter,*lastiter;
- long top;
- long w;
-
- if(!dpstates[i][j].visible) return;
- top = j;
- w = dpstates[i][j].weight;
- if(k-j > 1) {
- if (!dpstates[j][k].visible) return;
- w += dpstates[j][k].weight + 1;
- }
- if(j-i > 1) {
- pairs = &(dpstates[i][j].pairs);
- iter = NULL;
- lastiter = NULL;
- while(iter!=pairs->front()) {
- if (!iter)
- iter=pairs->back();
- else
- iter=iter->prev();
-
- if(!IsReflex(vertices[iter->get().index2].p,vertices[j].p,vertices[k].p)) lastiter = iter;
- else break;
- }
- if(lastiter == NULL) w++;
- else {
- if(IsReflex(vertices[k].p,vertices[i].p,vertices[lastiter->get().index1].p)) w++;
- else top = lastiter->get().index1;
- }
- }
- UpdateState(i,k,w,top,j,dpstates);
-}
-
-void TriangulatorPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
- List<Diagonal> *pairs;
- List<Diagonal>::Element* iter,*lastiter;
- long top;
- long w;
-
- if(!dpstates[j][k].visible) return;
- top = j;
- w = dpstates[j][k].weight;
-
- if (j-i > 1) {
- if (!dpstates[i][j].visible) return;
- w += dpstates[i][j].weight + 1;
- }
- if (k-j > 1) {
- pairs = &(dpstates[j][k].pairs);
-
- iter = pairs->front();
- if((!pairs->empty())&&(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->get().index1].p))) {
- lastiter = iter;
- while(iter!=NULL) {
- if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->get().index1].p)) {
- lastiter = iter;
- iter=iter->next();
- }
- else break;
- }
- if(IsReflex(vertices[lastiter->get().index2].p,vertices[k].p,vertices[i].p)) w++;
- else top = lastiter->get().index2;
- } else w++;
- }
- UpdateState(i,k,w,j,top,dpstates);
-}
-
-int TriangulatorPartition::ConvexPartition_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *parts) {
- Vector2 p1,p2,p3,p4;
- PartitionVertex *vertices;
- DPState2 **dpstates;
- long i,j,k,n,gap;
- List<Diagonal> diagonals,diagonals2;
- Diagonal diagonal,newdiagonal;
- List<Diagonal> *pairs,*pairs2;
- List<Diagonal>::Element* iter,*iter2;
- int ret;
- TriangulatorPoly newpoly;
- List<long> indices;
- List<long>::Element* iiter;
- bool ijreal,jkreal;
-
- n = poly->GetNumPoints();
- vertices = new PartitionVertex[n];
-
- dpstates = new DPState2 *[n];
- for(i=0;i<n;i++) {
- dpstates[i] = new DPState2[n];
- }
-
- //init vertex information
- for(i=0;i<n;i++) {
- vertices[i].p = poly->GetPoint(i);
- vertices[i].isActive = true;
- if(i==0) vertices[i].previous = &(vertices[n-1]);
- else vertices[i].previous = &(vertices[i-1]);
- if(i==(poly->GetNumPoints()-1)) vertices[i].next = &(vertices[0]);
- else vertices[i].next = &(vertices[i+1]);
- }
- for(i=1;i<n;i++) {
- UpdateVertexReflexity(&(vertices[i]));
- }
-
- //init states and visibility
- for(i=0;i<(n-1);i++) {
- p1 = poly->GetPoint(i);
- for(j=i+1;j<n;j++) {
- dpstates[i][j].visible = true;
- if(j==i+1) {
- dpstates[i][j].weight = 0;
- } else {
- dpstates[i][j].weight = 2147483647;
- }
- if(j!=(i+1)) {
- p2 = poly->GetPoint(j);
-
- //visibility check
- if(!InCone(&vertices[i],p2)) {
- dpstates[i][j].visible = false;
- continue;
- }
- if(!InCone(&vertices[j],p1)) {
- dpstates[i][j].visible = false;
- continue;
- }
-
- for(k=0;k<n;k++) {
- p3 = poly->GetPoint(k);
- if(k==(n-1)) p4 = poly->GetPoint(0);
- else p4 = poly->GetPoint(k+1);
- if(Intersects(p1,p2,p3,p4)) {
- dpstates[i][j].visible = false;
- break;
- }
- }
- }
- }
- }
- for(i=0;i<(n-2);i++) {
- j = i+2;
- if(dpstates[i][j].visible) {
- dpstates[i][j].weight = 0;
- newdiagonal.index1 = i+1;
- newdiagonal.index2 = i+1;
- dpstates[i][j].pairs.push_back(newdiagonal);
- }
- }
-
- dpstates[0][n-1].visible = true;
- vertices[0].isConvex = false; //by convention
-
- for(gap=3; gap<n; gap++) {
- for(i=0;i<n-gap;i++) {
- if(vertices[i].isConvex) continue;
- k = i+gap;
- if(dpstates[i][k].visible) {
- if(!vertices[k].isConvex) {
- for(j=i+1;j<k;j++) TypeA(i,j,k,vertices,dpstates);
- } else {
- for(j=i+1;j<(k-1);j++) {
- if(vertices[j].isConvex) continue;
- TypeA(i,j,k,vertices,dpstates);
- }
- TypeA(i,k-1,k,vertices,dpstates);
- }
- }
- }
- for(k=gap;k<n;k++) {
- if(vertices[k].isConvex) continue;
- i = k-gap;
- if((vertices[i].isConvex)&&(dpstates[i][k].visible)) {
- TypeB(i,i+1,k,vertices,dpstates);
- for(j=i+2;j<k;j++) {
- if(vertices[j].isConvex) continue;
- TypeB(i,j,k,vertices,dpstates);
- }
- }
- }
- }
-
-
- //recover solution
- ret = 1;
- newdiagonal.index1 = 0;
- newdiagonal.index2 = n-1;
- diagonals.push_front(newdiagonal);
- while(!diagonals.empty()) {
- diagonal = (diagonals.front()->get());
- diagonals.pop_front();
- if((diagonal.index2 - diagonal.index1) <=1) continue;
- pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
- if(pairs->empty()) {
- ret = 0;
- break;
- }
- if(!vertices[diagonal.index1].isConvex) {
- iter = pairs->back();
-
- j = iter->get().index2;
- newdiagonal.index1 = j;
- newdiagonal.index2 = diagonal.index2;
- diagonals.push_front(newdiagonal);
- if((j - diagonal.index1)>1) {
- if(iter->get().index1 != iter->get().index2) {
- pairs2 = &(dpstates[diagonal.index1][j].pairs);
- while(1) {
- if(pairs2->empty()) {
- ret = 0;
- break;
- }
- iter2 = pairs2->back();
-
- if(iter->get().index1 != iter2->get().index1) pairs2->pop_back();
- else break;
- }
- if(ret == 0) break;
- }
- newdiagonal.index1 = diagonal.index1;
- newdiagonal.index2 = j;
- diagonals.push_front(newdiagonal);
- }
- } else {
- iter = pairs->front();
- j = iter->get().index1;
- newdiagonal.index1 = diagonal.index1;
- newdiagonal.index2 = j;
- diagonals.push_front(newdiagonal);
- if((diagonal.index2 - j) > 1) {
- if(iter->get().index1 != iter->get().index2) {
- pairs2 = &(dpstates[j][diagonal.index2].pairs);
- while(1) {
- if(pairs2->empty()) {
- ret = 0;
- break;
- }
- iter2 = pairs2->front();
- if(iter->get().index2 != iter2->get().index2) pairs2->pop_front();
- else break;
- }
- if(ret == 0) break;
- }
- newdiagonal.index1 = j;
- newdiagonal.index2 = diagonal.index2;
- diagonals.push_front(newdiagonal);
- }
- }
- }
-
- if(ret == 0) {
- for(i=0;i<n;i++) {
- delete [] dpstates[i];
- }
- delete [] dpstates;
- delete [] vertices;
-
- return ret;
- }
-
- newdiagonal.index1 = 0;
- newdiagonal.index2 = n-1;
- diagonals.push_front(newdiagonal);
- while(!diagonals.empty()) {
- diagonal = (diagonals.front())->get();
- diagonals.pop_front();
- if((diagonal.index2 - diagonal.index1) <= 1) continue;
-
- indices.clear();
- diagonals2.clear();
- indices.push_back(diagonal.index1);
- indices.push_back(diagonal.index2);
- diagonals2.push_front(diagonal);
-
- while(!diagonals2.empty()) {
- diagonal = (diagonals2.front()->get());
- diagonals2.pop_front();
- if((diagonal.index2 - diagonal.index1) <= 1) continue;
- ijreal = true;
- jkreal = true;
- pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
- if(!vertices[diagonal.index1].isConvex) {
- iter = pairs->back();
- j = iter->get().index2;
- if(iter->get().index1 != iter->get().index2) ijreal = false;
- } else {
- iter = pairs->front();
- j = iter->get().index1;
- if(iter->get().index1 != iter->get().index2) jkreal = false;
- }
-
- newdiagonal.index1 = diagonal.index1;
- newdiagonal.index2 = j;
- if(ijreal) {
- diagonals.push_back(newdiagonal);
- } else {
- diagonals2.push_back(newdiagonal);
- }
-
- newdiagonal.index1 = j;
- newdiagonal.index2 = diagonal.index2;
- if(jkreal) {
- diagonals.push_back(newdiagonal);
- } else {
- diagonals2.push_back(newdiagonal);
- }
-
- indices.push_back(j);
- }
-
- indices.sort();
- newpoly.Init((long)indices.size());
- k=0;
- for(iiter = indices.front();iiter;iiter=iiter->next()) {
- newpoly[k] = vertices[iiter->get()].p;
- k++;
- }
- parts->push_back(newpoly);
- }
-
- for(i=0;i<n;i++) {
- delete [] dpstates[i];
- }
- delete [] dpstates;
- delete [] vertices;
-
- return ret;
-}
-
-//triangulates a set of polygons by first partitioning them into monotone polygons
-//O(n*log(n)) time complexity, O(n) space complexity
-//the algorithm used here is outlined in the book
-//"Computational Geometry: Algorithms and Applications"
-//by Mark de Berg, Otfried Cheong, Marc van Kreveld and Mark Overmars
-int TriangulatorPartition::MonotonePartition(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *monotonePolys) {
- List<TriangulatorPoly>::Element *iter;
- MonotoneVertex *vertices;
- long i,numvertices,vindex,vindex2,newnumvertices,maxnumvertices;
- long polystartindex, polyendindex;
- TriangulatorPoly *poly;
- MonotoneVertex *v,*v2,*vprev,*vnext;
- ScanLineEdge newedge;
- bool error = false;
-
- numvertices = 0;
- for(iter = inpolys->front(); iter ; iter=iter->next()) {
- numvertices += iter->get().GetNumPoints();
- }
-
- maxnumvertices = numvertices*3;
- vertices = new MonotoneVertex[maxnumvertices];
- newnumvertices = numvertices;
-
- polystartindex = 0;
- for(iter = inpolys->front(); iter ; iter=iter->next()) {
- poly = &(iter->get());
- polyendindex = polystartindex + poly->GetNumPoints()-1;
- for(i=0;i<poly->GetNumPoints();i++) {
- vertices[i+polystartindex].p = poly->GetPoint(i);
- if(i==0) vertices[i+polystartindex].previous = polyendindex;
- else vertices[i+polystartindex].previous = i+polystartindex-1;
- if(i==(poly->GetNumPoints()-1)) vertices[i+polystartindex].next = polystartindex;
- else vertices[i+polystartindex].next = i+polystartindex+1;
- }
- polystartindex = polyendindex+1;
- }
-
- //construct the priority queue
- long *priority = new long [numvertices];
- for(i=0;i<numvertices;i++) priority[i] = i;
- SortArray<long,VertexSorter> sorter;
- sorter.compare.vertices=vertices;
- sorter.sort(priority,numvertices);
-
- //determine vertex types
- char *vertextypes = new char[maxnumvertices];
- for(i=0;i<numvertices;i++) {
- v = &(vertices[i]);
- vprev = &(vertices[v->previous]);
- vnext = &(vertices[v->next]);
-
- if(Below(vprev->p,v->p)&&Below(vnext->p,v->p)) {
- if(IsConvex(vnext->p,vprev->p,v->p)) {
- vertextypes[i] = TRIANGULATOR_VERTEXTYPE_START;
- } else {
- vertextypes[i] = TRIANGULATOR_VERTEXTYPE_SPLIT;
- }
- } else if(Below(v->p,vprev->p)&&Below(v->p,vnext->p)) {
- if(IsConvex(vnext->p,vprev->p,v->p))
- {
- vertextypes[i] = TRIANGULATOR_VERTEXTYPE_END;
- } else {
- vertextypes[i] = TRIANGULATOR_VERTEXTYPE_MERGE;
- }
- } else {
- vertextypes[i] = TRIANGULATOR_VERTEXTYPE_REGULAR;
- }
- }
-
- //helpers
- long *helpers = new long[maxnumvertices];
-
- //binary search tree that holds edges intersecting the scanline
- //note that while set doesn't actually have to be implemented as a tree
- //complexity requirements for operations are the same as for the balanced binary search tree
- Set<ScanLineEdge> edgeTree;
- //store iterators to the edge tree elements
- //this makes deleting existing edges much faster
- Set<ScanLineEdge>::Element **edgeTreeIterators,*edgeIter;
- edgeTreeIterators = new Set<ScanLineEdge>::Element*[maxnumvertices];
- //Pair<Set<ScanLineEdge>::Element*,bool> edgeTreeRet;
- for(i = 0; i<numvertices; i++) edgeTreeIterators[i] = NULL;
-
- //for each vertex
- for(i=0;i<numvertices;i++) {
- vindex = priority[i];
- v = &(vertices[vindex]);
- vindex2 = vindex;
- v2 = v;
-
- //depending on the vertex type, do the appropriate action
- //comments in the following sections are copied from "Computational Geometry: Algorithms and Applications"
- switch(vertextypes[vindex]) {
- case TRIANGULATOR_VERTEXTYPE_START:
- //Insert ei in T and set helper(ei) to vi.
- newedge.p1 = v->p;
- newedge.p2 = vertices[v->next].p;
- newedge.index = vindex;
- edgeTreeIterators[vindex] = edgeTree.insert(newedge);
- helpers[vindex] = vindex;
- break;
-
- case TRIANGULATOR_VERTEXTYPE_END:
- //if helper(ei-1) is a merge vertex
- if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
- //Insert the diagonal connecting vi to helper(ei-1) in D.
- AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous],
- vertextypes, edgeTreeIterators, &edgeTree, helpers);
- }
- //Delete ei-1 from T
- edgeTree.erase(edgeTreeIterators[v->previous]);
- break;
-
- case TRIANGULATOR_VERTEXTYPE_SPLIT:
- //Search in T to find the edge e j directly left of vi.
- newedge.p1 = v->p;
- newedge.p2 = v->p;
- edgeIter = edgeTree.lower_bound(newedge);
- if(edgeIter == edgeTree.front()) {
- error = true;
- break;
- }
- edgeIter=edgeIter->prev();
- //Insert the diagonal connecting vi to helper(ej) in D.
- AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->get().index],
- vertextypes, edgeTreeIterators, &edgeTree, helpers);
- vindex2 = newnumvertices-2;
- v2 = &(vertices[vindex2]);
- //helper(e j)�vi
- helpers[edgeIter->get().index] = vindex;
- //Insert ei in T and set helper(ei) to vi.
- newedge.p1 = v2->p;
- newedge.p2 = vertices[v2->next].p;
- newedge.index = vindex2;
-
- edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
- helpers[vindex2] = vindex2;
- break;
-
- case TRIANGULATOR_VERTEXTYPE_MERGE:
- //if helper(ei-1) is a merge vertex
- if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
- //Insert the diagonal connecting vi to helper(ei-1) in D.
- AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous],
- vertextypes, edgeTreeIterators, &edgeTree, helpers);
- vindex2 = newnumvertices-2;
- v2 = &(vertices[vindex2]);
- }
- //Delete ei-1 from T.
- edgeTree.erase(edgeTreeIterators[v->previous]);
- //Search in T to find the edge e j directly left of vi.
- newedge.p1 = v->p;
- newedge.p2 = v->p;
- edgeIter = edgeTree.lower_bound(newedge);
- if(edgeIter == edgeTree.front()) {
- error = true;
- break;
- }
- edgeIter=edgeIter->prev();
- //if helper(ej) is a merge vertex
- if(vertextypes[helpers[edgeIter->get().index]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
- //Insert the diagonal connecting vi to helper(e j) in D.
- AddDiagonal(vertices,&newnumvertices,vindex2,helpers[edgeIter->get().index],
- vertextypes, edgeTreeIterators, &edgeTree, helpers);
- }
- //helper(e j)�vi
- helpers[edgeIter->get().index] = vindex2;
- break;
-
- case TRIANGULATOR_VERTEXTYPE_REGULAR:
- //if the interior of P lies to the right of vi
- if(Below(v->p,vertices[v->previous].p)) {
- //if helper(ei-1) is a merge vertex
- if(vertextypes[helpers[v->previous]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
- //Insert the diagonal connecting vi to helper(ei-1) in D.
- AddDiagonal(vertices,&newnumvertices,vindex,helpers[v->previous],
- vertextypes, edgeTreeIterators, &edgeTree, helpers);
- vindex2 = newnumvertices-2;
- v2 = &(vertices[vindex2]);
- }
- //Delete ei-1 from T.
- edgeTree.erase(edgeTreeIterators[v->previous]);
- //Insert ei in T and set helper(ei) to vi.
- newedge.p1 = v2->p;
- newedge.p2 = vertices[v2->next].p;
- newedge.index = vindex2;
- edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
- helpers[vindex2] = vindex;
- } else {
- //Search in T to find the edge ej directly left of vi.
- newedge.p1 = v->p;
- newedge.p2 = v->p;
- edgeIter = edgeTree.lower_bound(newedge);
- if(edgeIter == edgeTree.front()) {
- error = true;
- break;
- }
- edgeIter=edgeIter->prev();
- //if helper(ej) is a merge vertex
- if(vertextypes[helpers[edgeIter->get().index]]==TRIANGULATOR_VERTEXTYPE_MERGE) {
- //Insert the diagonal connecting vi to helper(e j) in D.
- AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->get().index],
- vertextypes, edgeTreeIterators, &edgeTree, helpers);
- }
- //helper(e j)�vi
- helpers[edgeIter->get().index] = vindex;
- }
- break;
- }
-
- if(error) break;
- }
-
- char *used = new char[newnumvertices];
- memset(used,0,newnumvertices*sizeof(char));
-
- if(!error) {
- //return result
- long size;
- TriangulatorPoly mpoly;
- for(i=0;i<newnumvertices;i++) {
- if(used[i]) continue;
- v = &(vertices[i]);
- vnext = &(vertices[v->next]);
- size = 1;
- while(vnext!=v) {
- vnext = &(vertices[vnext->next]);
- size++;
- }
- mpoly.Init(size);
- v = &(vertices[i]);
- mpoly[0] = v->p;
- vnext = &(vertices[v->next]);
- size = 1;
- used[i] = 1;
- used[v->next] = 1;
- while(vnext!=v) {
- mpoly[size] = vnext->p;
- used[vnext->next] = 1;
- vnext = &(vertices[vnext->next]);
- size++;
- }
- monotonePolys->push_back(mpoly);
- }
- }
-
- //cleanup
- delete [] vertices;
- delete [] priority;
- delete [] vertextypes;
- delete [] edgeTreeIterators;
- delete [] helpers;
- delete [] used;
-
- if(error) {
- return 0;
- } else {
- return 1;
- }
-}
-
-//adds a diagonal to the doubly-connected list of vertices
-void TriangulatorPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
- char *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
- Set<ScanLineEdge> *edgeTree, long *helpers)
-{
- long newindex1,newindex2;
-
- newindex1 = *numvertices;
- (*numvertices)++;
- newindex2 = *numvertices;
- (*numvertices)++;
-
- vertices[newindex1].p = vertices[index1].p;
- vertices[newindex2].p = vertices[index2].p;
-
- vertices[newindex2].next = vertices[index2].next;
- vertices[newindex1].next = vertices[index1].next;
-
- vertices[vertices[index2].next].previous = newindex2;
- vertices[vertices[index1].next].previous = newindex1;
-
- vertices[index1].next = newindex2;
- vertices[newindex2].previous = index1;
-
- vertices[index2].next = newindex1;
- vertices[newindex1].previous = index2;
-
- //update all relevant structures
- vertextypes[newindex1] = vertextypes[index1];
- edgeTreeIterators[newindex1] = edgeTreeIterators[index1];
- helpers[newindex1] = helpers[index1];
- if(edgeTreeIterators[newindex1] != NULL)
- edgeTreeIterators[newindex1]->get().index = newindex1;
- vertextypes[newindex2] = vertextypes[index2];
- edgeTreeIterators[newindex2] = edgeTreeIterators[index2];
- helpers[newindex2] = helpers[index2];
- if(edgeTreeIterators[newindex2] != NULL)
- edgeTreeIterators[newindex2]->get().index = newindex2;
-}
-
-bool TriangulatorPartition::Below(Vector2 &p1, Vector2 &p2) {
- if(p1.y < p2.y) return true;
- else if(p1.y == p2.y) {
- if(p1.x < p2.x) return true;
- }
- return false;
-}
-
-
-
-
-
-//sorts in the falling order of y values, if y is equal, x is used instead
-bool TriangulatorPartition::VertexSorter::operator() (long index1, long index2) const {
- if(vertices[index1].p.y > vertices[index2].p.y) return true;
- else if(vertices[index1].p.y == vertices[index2].p.y) {
- if(vertices[index1].p.x > vertices[index2].p.x) return true;
- }
- return false;
-}
-
-bool TriangulatorPartition::ScanLineEdge::IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const {
- real_t tmp;
- tmp = (p3.y-p1.y)*(p2.x-p1.x)-(p3.x-p1.x)*(p2.y-p1.y);
- if(tmp>0) return 1;
- else return 0;
-}
-
-bool TriangulatorPartition::ScanLineEdge::operator < (const ScanLineEdge & other) const {
- if(other.p1.y == other.p2.y) {
- if(p1.y == p2.y) {
- if(p1.y < other.p1.y) return true;
- else return false;
- }
- if(IsConvex(p1,p2,other.p1)) return true;
- else return false;
- } else if(p1.y == p2.y) {
- if(IsConvex(other.p1,other.p2,p1)) return false;
- else return true;
- } else if(p1.y < other.p1.y) {
- if(IsConvex(other.p1,other.p2,p1)) return false;
- else return true;
- } else {
- if(IsConvex(p1,p2,other.p1)) return true;
- else return false;
- }
-}
-
-//triangulates monotone polygon
-//O(n) time, O(n) space complexity
-int TriangulatorPartition::TriangulateMonotone(TriangulatorPoly *inPoly, List<TriangulatorPoly> *triangles) {
- long i,i2,j,topindex,bottomindex,leftindex,rightindex,vindex;
- Vector2 *points;
- long numpoints;
- TriangulatorPoly triangle;
-
- numpoints = inPoly->GetNumPoints();
- points = inPoly->GetPoints();
-
- //trivial calses
- if(numpoints < 3) return 0;
- if(numpoints == 3) {
- triangles->push_back(*inPoly);
- }
-
- topindex = 0; bottomindex=0;
- for(i=1;i<numpoints;i++) {
- if(Below(points[i],points[bottomindex])) bottomindex = i;
- if(Below(points[topindex],points[i])) topindex = i;
- }
-
- //check if the poly is really monotone
- i = topindex;
- while(i!=bottomindex) {
- i2 = i+1; if(i2>=numpoints) i2 = 0;
- if(!Below(points[i2],points[i])) return 0;
- i = i2;
- }
- i = bottomindex;
- while(i!=topindex) {
- i2 = i+1; if(i2>=numpoints) i2 = 0;
- if(!Below(points[i],points[i2])) return 0;
- i = i2;
- }
-
- char *vertextypes = new char[numpoints];
- long *priority = new long[numpoints];
-
- //merge left and right vertex chains
- priority[0] = topindex;
- vertextypes[topindex] = 0;
- leftindex = topindex+1; if(leftindex>=numpoints) leftindex = 0;
- rightindex = topindex-1; if(rightindex<0) rightindex = numpoints-1;
- for(i=1;i<(numpoints-1);i++) {
- if(leftindex==bottomindex) {
- priority[i] = rightindex;
- rightindex--; if(rightindex<0) rightindex = numpoints-1;
- vertextypes[priority[i]] = -1;
- } else if(rightindex==bottomindex) {
- priority[i] = leftindex;
- leftindex++; if(leftindex>=numpoints) leftindex = 0;
- vertextypes[priority[i]] = 1;
- } else {
- if(Below(points[leftindex],points[rightindex])) {
- priority[i] = rightindex;
- rightindex--; if(rightindex<0) rightindex = numpoints-1;
- vertextypes[priority[i]] = -1;
- } else {
- priority[i] = leftindex;
- leftindex++; if(leftindex>=numpoints) leftindex = 0;
- vertextypes[priority[i]] = 1;
- }
- }
- }
- priority[i] = bottomindex;
- vertextypes[bottomindex] = 0;
-
- long *stack = new long[numpoints];
- long stackptr = 0;
-
- stack[0] = priority[0];
- stack[1] = priority[1];
- stackptr = 2;
-
- //for each vertex from top to bottom trim as many triangles as possible
- for(i=2;i<(numpoints-1);i++) {
- vindex = priority[i];
- if(vertextypes[vindex]!=vertextypes[stack[stackptr-1]]) {
- for(j=0;j<(stackptr-1);j++) {
- if(vertextypes[vindex]==1) {
- triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]);
- } else {
- triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]);
- }
- triangles->push_back(triangle);
- }
- stack[0] = priority[i-1];
- stack[1] = priority[i];
- stackptr = 2;
- } else {
- stackptr--;
- while(stackptr>0) {
- if(vertextypes[vindex]==1) {
- if(IsConvex(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]])) {
- triangle.Triangle(points[vindex],points[stack[stackptr-1]],points[stack[stackptr]]);
- triangles->push_back(triangle);
- stackptr--;
- } else {
- break;
- }
- } else {
- if(IsConvex(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]])) {
- triangle.Triangle(points[vindex],points[stack[stackptr]],points[stack[stackptr-1]]);
- triangles->push_back(triangle);
- stackptr--;
- } else {
- break;
- }
- }
- }
- stackptr++;
- stack[stackptr] = vindex;
- stackptr++;
- }
- }
- vindex = priority[i];
- for(j=0;j<(stackptr-1);j++) {
- if(vertextypes[stack[j+1]]==1) {
- triangle.Triangle(points[stack[j]],points[stack[j+1]],points[vindex]);
- } else {
- triangle.Triangle(points[stack[j+1]],points[stack[j]],points[vindex]);
- }
- triangles->push_back(triangle);
- }
-
- delete [] priority;
- delete [] vertextypes;
- delete [] stack;
-
- return 1;
-}
-
-int TriangulatorPartition::Triangulate_MONO(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles) {
- List<TriangulatorPoly> monotone;
- List<TriangulatorPoly>::Element* iter;
-
- if(!MonotonePartition(inpolys,&monotone)) return 0;
- for(iter = monotone.front(); iter;iter=iter->next()) {
- if(!TriangulateMonotone(&(iter->get()),triangles)) return 0;
- }
- return 1;
-}
-
-int TriangulatorPartition::Triangulate_MONO(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles) {
- List<TriangulatorPoly> polys;
- polys.push_back(*poly);
-
- return Triangulate_MONO(&polys, triangles);
-}
diff --git a/thirdparty/misc/triangulator.h b/thirdparty/misc/triangulator.h
deleted file mode 100644
index 24b79e7d34..0000000000
--- a/thirdparty/misc/triangulator.h
+++ /dev/null
@@ -1,306 +0,0 @@
-//Copyright (C) 2011 by Ivan Fratric
-//
-//Permission is hereby granted, free of charge, to any person obtaining a copy
-//of this software and associated documentation files (the "Software"), to deal
-//in the Software without restriction, including without limitation the rights
-//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//copies of the Software, and to permit persons to whom the Software is
-//furnished to do so, subject to the following conditions:
-//
-//The above copyright notice and this permission notice shall be included in
-//all copies or substantial portions of the Software.
-//
-//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-//THE SOFTWARE.
-
-#ifndef TRIANGULATOR_H
-#define TRIANGULATOR_H
-
-#include "core/templates/list.h"
-#include "core/math/vector2.h"
-#include "core/templates/set.h"
-
-//2D point structure
-
-#define TRIANGULATOR_CCW 1
-#define TRIANGULATOR_CW -1
-//Polygon implemented as an array of points with a 'hole' flag
-class TriangulatorPoly {
-protected:
-
-
-
- Vector2 *points;
- long numpoints;
- bool hole;
-
-public:
-
- //constructors/destructors
- TriangulatorPoly();
- ~TriangulatorPoly();
-
- TriangulatorPoly(const TriangulatorPoly &src);
- TriangulatorPoly& operator=(const TriangulatorPoly &src);
-
- //getters and setters
- long GetNumPoints() {
- return numpoints;
- }
-
- bool IsHole() {
- return hole;
- }
-
- void SetHole(bool hole) {
- this->hole = hole;
- }
-
- Vector2 &GetPoint(long i) {
- return points[i];
- }
-
- Vector2 *GetPoints() {
- return points;
- }
-
- Vector2& operator[] (int i) {
- return points[i];
- }
-
- //clears the polygon points
- void Clear();
-
- //inits the polygon with numpoints vertices
- void Init(long numpoints);
-
- //creates a triangle with points p1,p2,p3
- void Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3);
-
- //inverts the orfer of vertices
- void Invert();
-
- //returns the orientation of the polygon
- //possible values:
- // Triangulator_CCW : polygon vertices are in counter-clockwise order
- // Triangulator_CW : polygon vertices are in clockwise order
- // 0 : the polygon has no (measurable) area
- int GetOrientation();
-
- //sets the polygon orientation
- //orientation can be
- // Triangulator_CCW : sets vertices in counter-clockwise order
- // Triangulator_CW : sets vertices in clockwise order
- void SetOrientation(int orientation);
-};
-
-class TriangulatorPartition {
-protected:
- struct PartitionVertex {
- bool isActive;
- bool isConvex;
- bool isEar;
-
- Vector2 p;
- real_t angle;
- PartitionVertex *previous;
- PartitionVertex *next;
- };
-
- struct MonotoneVertex {
- Vector2 p;
- long previous;
- long next;
- };
-
- struct VertexSorter{
- mutable MonotoneVertex *vertices;
- bool operator() (long index1, long index2) const;
- };
-
- struct Diagonal {
- long index1;
- long index2;
- };
-
- //dynamic programming state for minimum-weight triangulation
- struct DPState {
- bool visible;
- real_t weight;
- long bestvertex;
- };
-
- //dynamic programming state for convex partitioning
- struct DPState2 {
- bool visible;
- long weight;
- List<Diagonal> pairs;
- };
-
- //edge that intersects the scanline
- struct ScanLineEdge {
- mutable long index;
- Vector2 p1;
- Vector2 p2;
-
- //determines if the edge is to the left of another edge
- bool operator< (const ScanLineEdge & other) const;
-
- bool IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const;
- };
-
- //standard helper functions
- bool IsConvex(Vector2& p1, Vector2& p2, Vector2& p3);
- bool IsReflex(Vector2& p1, Vector2& p2, Vector2& p3);
- bool IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p);
-
- bool InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p);
- bool InCone(PartitionVertex *v, Vector2 &p);
-
- int Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, Vector2 &p22);
-
- Vector2 Normalize(const Vector2 &p);
- real_t Distance(const Vector2 &p1, const Vector2 &p2);
-
- //helper functions for Triangulate_EC
- void UpdateVertexReflexity(PartitionVertex *v);
- void UpdateVertex(PartitionVertex *v,PartitionVertex *vertices, long numvertices);
-
- //helper functions for ConvexPartition_OPT
- void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates);
- void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
- void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
-
- //helper functions for MonotonePartition
- bool Below(Vector2 &p1, Vector2 &p2);
- void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
- char *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
- Set<ScanLineEdge> *edgeTree, long *helpers);
-
- //triangulates a monotone polygon, used in Triangulate_MONO
- int TriangulateMonotone(TriangulatorPoly *inPoly, List<TriangulatorPoly> *triangles);
-
-public:
-
- //simple heuristic procedure for removing holes from a list of polygons
- //works by creating a diagonal from the rightmost hole vertex to some visible vertex
- //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
- //space complexity: O(n)
- //params:
- // inpolys : a list of polygons that can contain holes
- // vertices of all non-hole polys have to be in counter-clockwise order
- // vertices of all hole polys have to be in clockwise order
- // outpolys : a list of polygons without holes
- //returns 1 on success, 0 on failure
- int RemoveHoles(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *outpolys);
-
- //triangulates a polygon by ear clipping
- //time complexity O(n^2), n is the number of vertices
- //space complexity: O(n)
- //params:
- // poly : an input polygon to be triangulated
- // vertices have to be in counter-clockwise order
- // triangles : a list of triangles (result)
- //returns 1 on success, 0 on failure
- int Triangulate_EC(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
-
- //triangulates a list of polygons that may contain holes by ear clipping algorithm
- //first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon
- //time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
- //space complexity: O(n)
- //params:
- // inpolys : a list of polygons to be triangulated (can contain holes)
- // vertices of all non-hole polys have to be in counter-clockwise order
- // vertices of all hole polys have to be in clockwise order
- // triangles : a list of triangles (result)
- //returns 1 on success, 0 on failure
- int Triangulate_EC(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles);
-
- //creates an optimal polygon triangulation in terms of minimal edge length
- //time complexity: O(n^3), n is the number of vertices
- //space complexity: O(n^2)
- //params:
- // poly : an input polygon to be triangulated
- // vertices have to be in counter-clockwise order
- // triangles : a list of triangles (result)
- //returns 1 on success, 0 on failure
- int Triangulate_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
-
- //triangulates a polygons by firstly partitioning it into monotone polygons
- //time complexity: O(n*log(n)), n is the number of vertices
- //space complexity: O(n)
- //params:
- // poly : an input polygon to be triangulated
- // vertices have to be in counter-clockwise order
- // triangles : a list of triangles (result)
- //returns 1 on success, 0 on failure
- int Triangulate_MONO(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
-
- //triangulates a list of polygons by firstly partitioning them into monotone polygons
- //time complexity: O(n*log(n)), n is the number of vertices
- //space complexity: O(n)
- //params:
- // inpolys : a list of polygons to be triangulated (can contain holes)
- // vertices of all non-hole polys have to be in counter-clockwise order
- // vertices of all hole polys have to be in clockwise order
- // triangles : a list of triangles (result)
- //returns 1 on success, 0 on failure
- int Triangulate_MONO(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles);
-
- //creates a monotone partition of a list of polygons that can contain holes
- //time complexity: O(n*log(n)), n is the number of vertices
- //space complexity: O(n)
- //params:
- // inpolys : a list of polygons to be triangulated (can contain holes)
- // vertices of all non-hole polys have to be in counter-clockwise order
- // vertices of all hole polys have to be in clockwise order
- // monotonePolys : a list of monotone polygons (result)
- //returns 1 on success, 0 on failure
- int MonotonePartition(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *monotonePolys);
-
- //partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm
- //the algorithm gives at most four times the number of parts as the optimal algorithm
- //however, in practice it works much better than that and often gives optimal partition
- //uses triangulation obtained by ear clipping as intermediate result
- //time complexity O(n^2), n is the number of vertices
- //space complexity: O(n)
- //params:
- // poly : an input polygon to be partitioned
- // vertices have to be in counter-clockwise order
- // parts : resulting list of convex polygons
- //returns 1 on success, 0 on failure
- int ConvexPartition_HM(TriangulatorPoly *poly, List<TriangulatorPoly> *parts);
-
- //partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm
- //the algorithm gives at most four times the number of parts as the optimal algorithm
- //however, in practice it works much better than that and often gives optimal partition
- //uses triangulation obtained by ear clipping as intermediate result
- //time complexity O(n^2), n is the number of vertices
- //space complexity: O(n)
- //params:
- // inpolys : an input list of polygons to be partitioned
- // vertices of all non-hole polys have to be in counter-clockwise order
- // vertices of all hole polys have to be in clockwise order
- // parts : resulting list of convex polygons
- //returns 1 on success, 0 on failure
- int ConvexPartition_HM(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *parts);
-
- //optimal convex partitioning (in terms of number of resulting convex polygons)
- //using the Keil-Snoeyink algorithm
- //M. Keil, J. Snoeyink, "On the time bound for convex decomposition of simple polygons", 1998
- //time complexity O(n^3), n is the number of vertices
- //space complexity: O(n^3)
- // poly : an input polygon to be partitioned
- // vertices have to be in counter-clockwise order
- // parts : resulting list of convex polygons
- //returns 1 on success, 0 on failure
- int ConvexPartition_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *parts);
-};
-
-
-#endif
diff --git a/thirdparty/opus/celt/arm/arm2gnu.pl b/thirdparty/opus/celt/arm/arm2gnu.pl
deleted file mode 100755
index 6c922ac819..0000000000
--- a/thirdparty/opus/celt/arm/arm2gnu.pl
+++ /dev/null
@@ -1,353 +0,0 @@
-#!/usr/bin/perl
-# Copyright (C) 2002-2013 Xiph.org Foundation
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# - Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-my $bigend; # little/big endian
-my $nxstack;
-my $apple = 0;
-my $symprefix = "";
-
-$nxstack = 0;
-
-eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
- if $running_under_some_shell;
-
-while ($ARGV[0] =~ /^-/) {
- $_ = shift;
- last if /^--$/;
- if (/^-n$/) {
- $nflag++;
- next;
- }
- if (/^--apple$/) {
- $apple = 1;
- $symprefix = "_";
- next;
- }
- die "I don't recognize this switch: $_\\n";
-}
-$printit++ unless $nflag;
-
-$\ = "\n"; # automatically add newline on print
-$n=0;
-
-$thumb = 0; # ARM mode by default, not Thumb.
-@proc_stack = ();
-
-printf (" .syntax unified\n");
-
-LINE:
-while (<>) {
-
- # For ADRLs we need to add a new line after the substituted one.
- $addPadding = 0;
-
- # First, we do not dare to touch *anything* inside double quotes, do we?
- # Second, if you want a dollar character in the string,
- # insert two of them -- that's how ARM C and assembler treat strings.
- s/^([A-Za-z_]\w*)[ \t]+DCB[ \t]*\"/$1: .ascii \"/ && do { s/\$\$/\$/g; next };
- s/\bDCB\b[ \t]*\"/.ascii \"/ && do { s/\$\$/\$/g; next };
- s/^(\S+)\s+RN\s+(\S+)/$1 .req r$2/ && do { s/\$\$/\$/g; next };
- # If there's nothing on a line but a comment, don't try to apply any further
- # substitutions (this is a cheap hack to avoid mucking up the license header)
- s/^([ \t]*);/$1@/ && do { s/\$\$/\$/g; next };
- # If substituted -- leave immediately !
-
- s/@/,:/;
- s/;/@/;
- while ( /@.*'/ ) {
- s/(@.*)'/$1/g;
- }
- s/\{FALSE\}/0/g;
- s/\{TRUE\}/1/g;
- s/\{(\w\w\w\w+)\}/$1/g;
- s/\bINCLUDE[ \t]*([^ \t\n]+)/.include \"$1\"/;
- s/\bGET[ \t]*([^ \t\n]+)/.include \"${ my $x=$1; $x =~ s|\.s|-gnu.S|; \$x }\"/;
- s/\bIMPORT\b/.extern/;
- s/\bEXPORT\b\s*/.global $symprefix/;
- s/^(\s+)\[/$1IF/;
- s/^(\s+)\|/$1ELSE/;
- s/^(\s+)\]/$1ENDIF/;
- s/IF *:DEF:/ .ifdef/;
- s/IF *:LNOT: *:DEF:/ .ifndef/;
- s/ELSE/ .else/;
- s/ENDIF/ .endif/;
-
- if( /\bIF\b/ ) {
- s/\bIF\b/ .if/;
- s/=/==/;
- }
- if ( $n == 2) {
- s/\$/\\/g;
- }
- if ($n == 1) {
- s/\$//g;
- s/label//g;
- $n = 2;
- }
- if ( /MACRO/ ) {
- s/MACRO *\n/.macro/;
- $n=1;
- }
- if ( /\bMEND\b/ ) {
- s/\bMEND\b/.endm/;
- $n=0;
- }
-
- # ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there.
- #
- if ( /\bAREA\b/ ) {
- my $align;
- $align = "2";
- if ( /ALIGN=(\d+)/ ) {
- $align = $1;
- }
- if ( /CODE/ ) {
- $nxstack = 1;
- }
- s/^(.+)CODE(.+)READONLY(.*)/ .text/;
- s/^(.+)DATA(.+)READONLY(.*)/ .section .rdata/;
- s/^(.+)\|\|\.data\|\|(.+)/ .data/;
- s/^(.+)\|\|\.bss\|\|(.+)/ .bss/;
- s/$/; .p2align $align/;
- # Enable NEON instructions but don't produce a binary that requires
- # ARMv7. RVCT does not have equivalent directives, so we just do this
- # for all CODE areas.
- if ( /.text/ ) {
- # Separating .arch, .fpu, etc., by semicolons does not work (gas
- # thinks the semicolon is part of the arch name, even when there's
- # whitespace separating them). Sadly this means our line numbers
- # won't match the original source file (we could use the .line
- # directive, which is documented to be obsolete, but then gdb will
- # show the wrong line in the translated source file).
- s/$/; .arch armv7-a\n .fpu neon\n .object_arch armv4t/ unless ($apple);
- }
- }
-
- s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/; # ||.constdata$3||
- s/\|\|\.bss\$(\d+)\|\|/.L_BSS$1/; # ||.bss$2||
- s/\|\|\.data\$(\d+)\|\|/.L_DATA$1/; # ||.data$2||
- s/\|\|([a-zA-Z0-9_]+)\@([a-zA-Z0-9_]+)\|\|/@ $&/;
- s/^(\s+)\%(\s)/ .space $1/;
-
- s/\|(.+)\.(\d+)\|/\.$1_$2/; # |L80.123| -> .L80_123
- s/\bCODE32\b/.code 32/ && do {$thumb = 0};
- s/\bCODE16\b/.code 16/ && do {$thumb = 1};
- if (/\bPROC\b/)
- {
- my $prefix;
- my $proc;
- /^([A-Za-z_\.]\w+)\b/;
- $proc = $1;
- $prefix = "";
- if ($proc)
- {
- $prefix = $prefix.sprintf("\t.type\t%s, %%function; ",$proc) unless ($apple);
- # Make sure we $prefix isn't empty here (for the $apple case).
- # We handle mangling the label here, make sure it doesn't match
- # the label handling below (if $prefix would be empty).
- $prefix = "; ";
- push(@proc_stack, $proc);
- s/^[A-Za-z_\.]\w+/$symprefix$&:/;
- }
- $prefix = $prefix."\t.thumb_func; " if ($thumb);
- s/\bPROC\b/@ $&/;
- $_ = $prefix.$_;
- }
- s/^(\s*)(S|Q|SH|U|UQ|UH)ASX\b/$1$2ADDSUBX/;
- s/^(\s*)(S|Q|SH|U|UQ|UH)SAX\b/$1$2SUBADDX/;
- if (/\bENDP\b/)
- {
- my $proc;
- s/\bENDP\b/@ $&/;
- $proc = pop(@proc_stack);
- $_ = "\t.size $proc, .-$proc".$_ if ($proc && !$apple);
- }
- s/\bSUBT\b/@ $&/;
- s/\bDATA\b/@ $&/; # DATA directive is deprecated -- Asm guide, p.7-25
- s/\bKEEP\b/@ $&/;
- s/\bEXPORTAS\b/@ $&/;
- s/\|\|(.)+\bEQU\b/@ $&/;
- s/\|\|([\w\$]+)\|\|/$1/;
- s/\bENTRY\b/@ $&/;
- s/\bASSERT\b/@ $&/;
- s/\bGBLL\b/@ $&/;
- s/\bGBLA\b/@ $&/;
- s/^\W+OPT\b/@ $&/;
- s/:OR:/|/g;
- s/:SHL:/<</g;
- s/:SHR:/>>/g;
- s/:AND:/&/g;
- s/:LAND:/&&/g;
- s/CPSR/cpsr/;
- s/SPSR/spsr/;
- s/ALIGN$/.balign 4/;
- s/ALIGN\s+([0-9x]+)$/.balign $1/;
- s/psr_cxsf/psr_all/;
- s/LTORG/.ltorg/;
- s/^([A-Za-z_]\w*)[ \t]+EQU/ .set $1,/;
- s/^([A-Za-z_]\w*)[ \t]+SETL/ .set $1,/;
- s/^([A-Za-z_]\w*)[ \t]+SETA/ .set $1,/;
- s/^([A-Za-z_]\w*)[ \t]+\*/ .set $1,/;
-
- # {PC} + 0xdeadfeed --> . + 0xdeadfeed
- s/\{PC\} \+/ \. +/;
-
- # Single hex constant on the line !
- #
- # >>> NOTE <<<
- # Double-precision floats in gcc are always mixed-endian, which means
- # bytes in two words are little-endian, but words are big-endian.
- # So, 0x0000deadfeed0000 would be stored as 0x0000dead at low address
- # and 0xfeed0000 at high address.
- #
- s/\bDCFD\b[ \t]+0x([a-fA-F0-9]{8})([a-fA-F0-9]{8})/.long 0x$1, 0x$2/;
- # Only decimal constants on the line, no hex !
- s/\bDCFD\b[ \t]+([0-9\.\-]+)/.double $1/;
-
- # Single hex constant on the line !
-# s/\bDCFS\b[ \t]+0x([a-f0-9]{8})([a-f0-9]{8})/.long 0x$1, 0x$2/;
- # Only decimal constants on the line, no hex !
-# s/\bDCFS\b[ \t]+([0-9\.\-]+)/.double $1/;
- s/\bDCFS[ \t]+0x/.word 0x/;
- s/\bDCFS\b/.float/;
-
- s/^([A-Za-z_]\w*)[ \t]+DCD/$1 .word/;
- s/\bDCD\b/.word/;
- s/^([A-Za-z_]\w*)[ \t]+DCW/$1 .short/;
- s/\bDCW\b/.short/;
- s/^([A-Za-z_]\w*)[ \t]+DCB/$1 .byte/;
- s/\bDCB\b/.byte/;
- s/^([A-Za-z_]\w*)[ \t]+\%/.comm $1,/;
- s/^[A-Za-z_\.]\w+/$&:/;
- s/^(\d+)/$1:/;
- s/\%(\d+)/$1b_or_f/;
- s/\%[Bb](\d+)/$1b/;
- s/\%[Ff](\d+)/$1f/;
- s/\%[Ff][Tt](\d+)/$1f/;
- s/&([\dA-Fa-f]+)/0x$1/;
- if ( /\b2_[01]+\b/ ) {
- s/\b2_([01]+)\b/conv$1&&&&/g;
- while ( /[01][01][01][01]&&&&/ ) {
- s/0000&&&&/&&&&0/g;
- s/0001&&&&/&&&&1/g;
- s/0010&&&&/&&&&2/g;
- s/0011&&&&/&&&&3/g;
- s/0100&&&&/&&&&4/g;
- s/0101&&&&/&&&&5/g;
- s/0110&&&&/&&&&6/g;
- s/0111&&&&/&&&&7/g;
- s/1000&&&&/&&&&8/g;
- s/1001&&&&/&&&&9/g;
- s/1010&&&&/&&&&A/g;
- s/1011&&&&/&&&&B/g;
- s/1100&&&&/&&&&C/g;
- s/1101&&&&/&&&&D/g;
- s/1110&&&&/&&&&E/g;
- s/1111&&&&/&&&&F/g;
- }
- s/000&&&&/&&&&0/g;
- s/001&&&&/&&&&1/g;
- s/010&&&&/&&&&2/g;
- s/011&&&&/&&&&3/g;
- s/100&&&&/&&&&4/g;
- s/101&&&&/&&&&5/g;
- s/110&&&&/&&&&6/g;
- s/111&&&&/&&&&7/g;
- s/00&&&&/&&&&0/g;
- s/01&&&&/&&&&1/g;
- s/10&&&&/&&&&2/g;
- s/11&&&&/&&&&3/g;
- s/0&&&&/&&&&0/g;
- s/1&&&&/&&&&1/g;
- s/conv&&&&/0x/g;
- }
-
- if ( /commandline/)
- {
- if( /-bigend/)
- {
- $bigend=1;
- }
- }
-
- if ( /\bDCDU\b/ )
- {
- my $cmd=$_;
- my $value;
- my $prefix;
- my $w1;
- my $w2;
- my $w3;
- my $w4;
-
- s/\s+DCDU\b/@ $&/;
-
- $cmd =~ /\bDCDU\b\s+0x(\d+)/;
- $value = $1;
- $value =~ /(\w\w)(\w\w)(\w\w)(\w\w)/;
- $w1 = $1;
- $w2 = $2;
- $w3 = $3;
- $w4 = $4;
-
- if( $bigend ne "")
- {
- # big endian
- $prefix = "\t.byte\t0x".$w1.";".
- "\t.byte\t0x".$w2.";".
- "\t.byte\t0x".$w3.";".
- "\t.byte\t0x".$w4."; ";
- }
- else
- {
- # little endian
- $prefix = "\t.byte\t0x".$w4.";".
- "\t.byte\t0x".$w3.";".
- "\t.byte\t0x".$w2.";".
- "\t.byte\t0x".$w1."; ";
- }
- $_=$prefix.$_;
- }
-
- if ( /\badrl\b/i )
- {
- s/\badrl\s+(\w+)\s*,\s*(\w+)/ldr $1,=$2/i;
- $addPadding = 1;
- }
- s/\bEND\b/@ END/;
-} continue {
- printf ("%s", $_) if $printit;
- if ($addPadding != 0)
- {
- printf (" mov r0,r0\n");
- $addPadding = 0;
- }
-}
-#If we had a code section, mark that this object doesn't need an executable
-# stack.
-if ($nxstack && !$apple) {
- printf (" .section\t.note.GNU-stack,\"\",\%\%progbits\n");
-}
diff --git a/thirdparty/pcre2/AUTHORS b/thirdparty/pcre2/AUTHORS
index 8d4e15a247..f001cb770e 100644
--- a/thirdparty/pcre2/AUTHORS
+++ b/thirdparty/pcre2/AUTHORS
@@ -2,13 +2,13 @@ THE MAIN PCRE2 LIBRARY CODE
---------------------------
Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
+Email local part: Philip.Hazel
+Email domain: gmail.com
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2019 University of Cambridge
+Copyright (c) 1997-2020 University of Cambridge
All rights reserved
@@ -19,7 +19,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2019 Zoltan Herczeg
+Copyright(c) 2010-2020 Zoltan Herczeg
All rights reserved.
@@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2019 Zoltan Herczeg
+Copyright(c) 2009-2020 Zoltan Herczeg
All rights reserved.
####
diff --git a/thirdparty/pcre2/LICENCE b/thirdparty/pcre2/LICENCE
index 142b3b3f9a..155d073127 100644
--- a/thirdparty/pcre2/LICENCE
+++ b/thirdparty/pcre2/LICENCE
@@ -20,13 +20,13 @@ THE BASIC LIBRARY FUNCTIONS
---------------------------
Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
+Email local part: Philip.Hazel
+Email domain: gmail.com
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2019 University of Cambridge
+Copyright (c) 1997-2020 University of Cambridge
All rights reserved.
@@ -37,7 +37,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
-Copyright(c) 2010-2019 Zoltan Herczeg
+Copyright(c) 2010-2020 Zoltan Herczeg
All rights reserved.
@@ -48,7 +48,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
-Copyright(c) 2009-2019 Zoltan Herczeg
+Copyright(c) 2009-2020 Zoltan Herczeg
All rights reserved.
diff --git a/thirdparty/pcre2/src/config.h b/thirdparty/pcre2/src/config.h
index 787bb9c999..10f4104790 100644
--- a/thirdparty/pcre2/src/config.h
+++ b/thirdparty/pcre2/src/config.h
@@ -52,6 +52,9 @@ sure both macros are undefined; an emulation function will then be used. */
LF does in an ASCII/Unicode environment. */
/* #undef EBCDIC_NL25 */
+/* Define this if your compiler supports __attribute__((uninitialized)) */
+/* #undef HAVE_ATTRIBUTE_UNINITIALIZED */
+
/* Define to 1 if you have the `bcopy' function. */
/* #undef HAVE_BCOPY */
@@ -76,6 +79,9 @@ sure both macros are undefined; an emulation function will then be used. */
/* Define to 1 if you have the <limits.h> header file. */
/* #undef HAVE_LIMITS_H */
+/* Define to 1 if you have the `memfd_create' function. */
+/* #undef HAVE_MEMFD_CREATE */
+
/* Define to 1 if you have the `memmove' function. */
/* #undef HAVE_MEMMOVE */
@@ -218,7 +224,7 @@ sure both macros are undefined; an emulation function will then be used. */
#define PACKAGE_NAME "PCRE2"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE2 10.34"
+#define PACKAGE_STRING "PCRE2 10.36"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "pcre2"
@@ -227,7 +233,7 @@ sure both macros are undefined; an emulation function will then be used. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "10.34"
+#define PACKAGE_VERSION "10.36"
/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
parentheses (of any kind) in a pattern. This limits the amount of system
@@ -352,7 +358,7 @@ sure both macros are undefined; an emulation function will then be used. */
#endif
/* Version number of package */
-#define VERSION "10.34"
+#define VERSION "10.36"
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
diff --git a/thirdparty/pcre2/src/pcre2.h b/thirdparty/pcre2/src/pcre2.h
index cb9d61a35b..f204ec8180 100644
--- a/thirdparty/pcre2/src/pcre2.h
+++ b/thirdparty/pcre2/src/pcre2.h
@@ -5,7 +5,7 @@
/* This is the public header file for the PCRE library, second API, to be
#included by applications that call PCRE2 functions.
- Copyright (c) 2016-2019 University of Cambridge
+ Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE2_MAJOR 10
-#define PCRE2_MINOR 34
+#define PCRE2_MINOR 36
#define PCRE2_PRERELEASE
-#define PCRE2_DATE 2019-11-21
+#define PCRE2_DATE 2020-12-04
/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE2, the appropriate
@@ -181,6 +181,9 @@ pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */
#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u /* pcre2_substitute() only */
#define PCRE2_NO_JIT 0x00002000u /* Not for pcre2_dfa_match() */
#define PCRE2_COPY_MATCHED_SUBJECT 0x00004000u
+#define PCRE2_SUBSTITUTE_LITERAL 0x00008000u /* pcre2_substitute() only */
+#define PCRE2_SUBSTITUTE_MATCHED 0x00010000u /* pcre2_substitute() only */
+#define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u /* pcre2_substitute() only */
/* Options for pcre2_pattern_convert(). */
@@ -445,6 +448,7 @@ released, the numbers must not be changed. */
#define PCRE2_CONFIG_HEAPLIMIT 12
#define PCRE2_CONFIG_NEVER_BACKSLASH_C 13
#define PCRE2_CONFIG_COMPILED_WIDTHS 14
+#define PCRE2_CONFIG_TABLES_LENGTH 15
/* Types for code units in patterns and subject strings. */
diff --git a/thirdparty/pcre2/src/pcre2_auto_possess.c b/thirdparty/pcre2/src/pcre2_auto_possess.c
index 5b95b9b8a8..c64cf856d1 100644
--- a/thirdparty/pcre2/src/pcre2_auto_possess.c
+++ b/thirdparty/pcre2/src/pcre2_auto_possess.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -292,6 +292,7 @@ possessification, and if so, fills a list with its properties.
Arguments:
code points to start of expression
utf TRUE if in UTF mode
+ ucp TRUE if in UCP mode
fcc points to the case-flipping table
list points to output list
list[0] will be filled with the opcode
@@ -304,7 +305,7 @@ Returns: points to the start of the next opcode if *code is accepted
*/
static PCRE2_SPTR
-get_chr_property_list(PCRE2_SPTR code, BOOL utf, const uint8_t *fcc,
+get_chr_property_list(PCRE2_SPTR code, BOOL utf, BOOL ucp, const uint8_t *fcc,
uint32_t *list)
{
PCRE2_UCHAR c = *code;
@@ -316,7 +317,8 @@ uint32_t chr;
uint32_t *clist_dest;
const uint32_t *clist_src;
#else
-(void)utf; /* Suppress "unused parameter" compiler warning */
+(void)utf; /* Suppress "unused parameter" compiler warnings */
+(void)ucp;
#endif
list[0] = c;
@@ -396,7 +398,7 @@ switch(c)
list[2] = chr;
#ifdef SUPPORT_UNICODE
- if (chr < 128 || (chr < 256 && !utf))
+ if (chr < 128 || (chr < 256 && !utf && !ucp))
list[3] = fcc[chr];
else
list[3] = UCD_OTHERCASE(chr);
@@ -503,6 +505,7 @@ which case the base cannot be possessified.
Arguments:
code points to the byte code
utf TRUE in UTF mode
+ ucp TRUE in UCP mode
cb compile data block
base_list the data list of the base opcode
base_end the end of the base opcode
@@ -512,7 +515,7 @@ Returns: TRUE if the auto-possessification is possible
*/
static BOOL
-compare_opcodes(PCRE2_SPTR code, BOOL utf, const compile_block *cb,
+compare_opcodes(PCRE2_SPTR code, BOOL utf, BOOL ucp, const compile_block *cb,
const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit)
{
PCRE2_UCHAR c;
@@ -651,7 +654,7 @@ for(;;)
while (*next_code == OP_ALT)
{
- if (!compare_opcodes(code, utf, cb, base_list, base_end, rec_limit))
+ if (!compare_opcodes(code, utf, ucp, cb, base_list, base_end, rec_limit))
return FALSE;
code = next_code + 1 + LINK_SIZE;
next_code += GET(next_code, 1);
@@ -672,7 +675,8 @@ for(;;)
/* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */
next_code += 1 + LINK_SIZE;
- if (!compare_opcodes(next_code, utf, cb, base_list, base_end, rec_limit))
+ if (!compare_opcodes(next_code, utf, ucp, cb, base_list, base_end,
+ rec_limit))
return FALSE;
code += PRIV(OP_lengths)[c];
@@ -688,7 +692,7 @@ for(;;)
/* We now have the next appropriate opcode to compare with the base. Check
for a supported opcode, and load its properties. */
- code = get_chr_property_list(code, utf, cb->fcc, list);
+ code = get_chr_property_list(code, utf, ucp, cb->fcc, list);
if (code == NULL) return FALSE; /* Unsupported */
/* If either opcode is a small character list, set pointers for comparing
@@ -1100,7 +1104,6 @@ leaving the remainder of the pattern unpossessified.
Arguments:
code points to start of the byte code
- utf TRUE in UTF mode
cb compile data block
Returns: 0 for success
@@ -1108,13 +1111,15 @@ Returns: 0 for success
*/
int
-PRIV(auto_possessify)(PCRE2_UCHAR *code, BOOL utf, const compile_block *cb)
+PRIV(auto_possessify)(PCRE2_UCHAR *code, const compile_block *cb)
{
PCRE2_UCHAR c;
PCRE2_SPTR end;
PCRE2_UCHAR *repeat_opcode;
uint32_t list[8];
int rec_limit = 1000; /* Was 10,000 but clang+ASAN uses a lot of stack. */
+BOOL utf = (cb->external_options & PCRE2_UTF) != 0;
+BOOL ucp = (cb->external_options & PCRE2_UCP) != 0;
for (;;)
{
@@ -1126,10 +1131,11 @@ for (;;)
{
c -= get_repeat_base(c) - OP_STAR;
end = (c <= OP_MINUPTO) ?
- get_chr_property_list(code, utf, cb->fcc, list) : NULL;
+ get_chr_property_list(code, utf, ucp, cb->fcc, list) : NULL;
list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
- if (end != NULL && compare_opcodes(end, utf, cb, list, end, &rec_limit))
+ if (end != NULL && compare_opcodes(end, utf, ucp, cb, list, end,
+ &rec_limit))
{
switch(c)
{
@@ -1181,11 +1187,11 @@ for (;;)
if (c >= OP_CRSTAR && c <= OP_CRMINRANGE)
{
/* end must not be NULL. */
- end = get_chr_property_list(code, utf, cb->fcc, list);
+ end = get_chr_property_list(code, utf, ucp, cb->fcc, list);
list[1] = (c & 1) == 0;
- if (compare_opcodes(end, utf, cb, list, end, &rec_limit))
+ if (compare_opcodes(end, utf, ucp, cb, list, end, &rec_limit))
{
switch (c)
{
diff --git a/thirdparty/pcre2/src/pcre2_chartables.c b/thirdparty/pcre2/src/pcre2_chartables.c
index 0e07edb494..861914d1ac 100644
--- a/thirdparty/pcre2/src/pcre2_chartables.c
+++ b/thirdparty/pcre2/src/pcre2_chartables.c
@@ -2,17 +2,21 @@
* Perl-Compatible Regular Expressions *
*************************************************/
-/* This file was automatically written by the dftables auxiliary
+/* This file was automatically written by the pcre2_dftables auxiliary
program. It contains character tables that are used when no external
tables are passed to PCRE2 by the application that calls it. The tables
are used only for characters whose code values are less than 256. */
-/*The dftables program (which is distributed with PCRE2) can be used to
-build alternative versions of this file. This is necessary if you are
+/* This set of tables was written in the C locale. */
+
+/* The pcre2_ftables program (which is distributed with PCRE2) can be used
+to build alternative versions of this file. This is necessary if you are
running in an EBCDIC environment, or if you want to default to a different
-encoding, for example ISO-8859-1. When dftables is run, it creates these
-tables in the current locale. This happens automatically if PCRE2 is
-configured with --enable-rebuild-chartables. */
+encoding, for example ISO-8859-1. When pcre2_dftables is run, it creates
+these tables in the "C" locale by default. This happens automatically if
+PCRE2 is configured with --enable-rebuild-chartables. However, you can run
+pcre2_dftables manually with the -L option to build tables using the LC_ALL
+locale. */
/* The following #include is present because without it gcc 4.x may remove
the array definition from the final binary if PCRE2 is built into a static
@@ -102,54 +106,54 @@ const uint8_t PRIV(default_tables)[] = {
/* This table contains bit maps for various character classes. Each map is 32
bytes long and the bits run from the least significant end of each byte. The
classes that have their own maps are: space, xdigit, digit, upper, lower, word,
-graph print, punct, and cntrl. Other classes are built from combinations. */
+graph, print, punct, and cntrl. Other classes are built from combinations. */
- 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, /* space */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* xdigit */
0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* digit */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* upper */
0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* lower */
0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* word */
0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, /* graph */
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, /* print */
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, /* punct */
0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, /* cntrl */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
diff --git a/thirdparty/pcre2/src/pcre2_compile.c b/thirdparty/pcre2/src/pcre2_compile.c
index f2e6b6b5bd..e811f12f02 100644
--- a/thirdparty/pcre2/src/pcre2_compile.c
+++ b/thirdparty/pcre2/src/pcre2_compile.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -1202,7 +1202,7 @@ in the decoded tables. */
if ((code->flags & PCRE2_DEREF_TABLES) != 0)
{
- ref_count = (PCRE2_SIZE *)(code->tables + tables_length);
+ ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);
(*ref_count)++;
}
@@ -1232,15 +1232,15 @@ if (newcode == NULL) return NULL;
memcpy(newcode, code, code->blocksize);
newcode->executable_jit = NULL;
-newtables = code->memctl.malloc(tables_length + sizeof(PCRE2_SIZE),
+newtables = code->memctl.malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE),
code->memctl.memory_data);
if (newtables == NULL)
{
code->memctl.free((void *)newcode, code->memctl.memory_data);
return NULL;
}
-memcpy(newtables, code->tables, tables_length);
-ref_count = (PCRE2_SIZE *)(newtables + tables_length);
+memcpy(newtables, code->tables, TABLES_LENGTH);
+ref_count = (PCRE2_SIZE *)(newtables + TABLES_LENGTH);
*ref_count = 1;
newcode->tables = newtables;
@@ -1270,7 +1270,7 @@ if (code != NULL)
be freed when there are no more references to them. The *ref_count should
always be > 0. */
- ref_count = (PCRE2_SIZE *)(code->tables + tables_length);
+ ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);
if (*ref_count > 0)
{
(*ref_count)--;
@@ -2344,7 +2344,7 @@ if (ptr > *nameptr + MAX_NAME_SIZE)
*errorcodeptr = ERR48;
goto FAILED;
}
-*namelenptr = ptr - *nameptr;
+*namelenptr = (uint32_t)(ptr - *nameptr);
/* Subpattern names must not be empty, and their terminator is checked here.
(What follows a verb or alpha assertion name is checked separately.) */
@@ -3653,7 +3653,7 @@ while (ptr < ptrend)
if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
/* If ( is not followed by ? it is either a capture or a special verb or an
- alpha assertion. */
+ alpha assertion or a positive non-atomic lookahead. */
if (*ptr != CHAR_QUESTION_MARK)
{
@@ -3685,10 +3685,10 @@ while (ptr < ptrend)
break;
/* Handle "alpha assertions" such as (*pla:...). Most of these are
- synonyms for the historical symbolic assertions, but the script run ones
- are new. They are distinguished by starting with a lower case letter.
- Checking both ends of the alphabet makes this work in all character
- codes. */
+ synonyms for the historical symbolic assertions, but the script run and
+ non-atomic lookaround ones are new. They are distinguished by starting
+ with a lower case letter. Checking both ends of the alphabet makes this
+ work in all character codes. */
else if (CHMAX_255(c) && (cb->ctypes[c] & ctype_lcletter) != 0)
{
@@ -3747,9 +3747,7 @@ while (ptr < ptrend)
goto POSITIVE_LOOK_AHEAD;
case META_LOOKAHEAD_NA:
- *parsed_pattern++ = meta;
- ptr++;
- goto POST_ASSERTION;
+ goto POSITIVE_NONATOMIC_LOOK_AHEAD;
case META_LOOKAHEADNOT:
goto NEGATIVE_LOOK_AHEAD;
@@ -4333,6 +4331,7 @@ while (ptr < ptrend)
{
if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION;
minor = (*ptr++ - CHAR_0) * 10;
+ if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
if (IS_DIGIT(*ptr)) minor += *ptr++ - CHAR_0;
if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
goto BAD_VERSION_CONDITION;
@@ -4438,6 +4437,12 @@ while (ptr < ptrend)
ptr++;
goto POST_ASSERTION;
+ case CHAR_ASTERISK:
+ POSITIVE_NONATOMIC_LOOK_AHEAD: /* Come from (?* */
+ *parsed_pattern++ = META_LOOKAHEAD_NA;
+ ptr++;
+ goto POST_ASSERTION;
+
case CHAR_EXCLAMATION_MARK:
NEGATIVE_LOOK_AHEAD: /* Come from (*nla: */
*parsed_pattern++ = META_LOOKAHEADNOT;
@@ -4447,20 +4452,23 @@ while (ptr < ptrend)
/* ---- Lookbehind assertions ---- */
- /* (?< followed by = or ! is a lookbehind assertion. Otherwise (?< is the
- start of the name of a capturing group. */
+ /* (?< followed by = or ! or * is a lookbehind assertion. Otherwise (?<
+ is the start of the name of a capturing group. */
case CHAR_LESS_THAN_SIGN:
if (ptrend - ptr <= 1 ||
- (ptr[1] != CHAR_EQUALS_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK))
+ (ptr[1] != CHAR_EQUALS_SIGN &&
+ ptr[1] != CHAR_EXCLAMATION_MARK &&
+ ptr[1] != CHAR_ASTERISK))
{
terminator = CHAR_GREATER_THAN_SIGN;
goto DEFINE_NAME;
}
*parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)?
- META_LOOKBEHIND : META_LOOKBEHINDNOT;
+ META_LOOKBEHIND : (ptr[1] == CHAR_EXCLAMATION_MARK)?
+ META_LOOKBEHINDNOT : META_LOOKBEHIND_NA;
- POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */
+ POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */
*has_lookbehind = TRUE;
offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
PUTOFFSET(offset, parsed_pattern);
@@ -4633,8 +4641,6 @@ while (ptr < ptrend)
*parsed_pattern++ = META_KET;
}
-
-
if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL;
else top_nest--;
}
@@ -4899,7 +4905,7 @@ range. */
if ((options & PCRE2_CASELESS) != 0)
{
#ifdef SUPPORT_UNICODE
- if ((options & PCRE2_UTF) != 0)
+ if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0)
{
int rc;
uint32_t oc, od;
@@ -5314,7 +5320,8 @@ dynamically as we process the pattern. */
#ifdef SUPPORT_UNICODE
BOOL utf = (options & PCRE2_UTF) != 0;
-#else /* No UTF support */
+BOOL ucp = (options & PCRE2_UCP) != 0;
+#else /* No Unicode support */
BOOL utf = FALSE;
#endif
@@ -5559,12 +5566,12 @@ for (;; pptr++)
zerofirstcu = firstcu;
zerofirstcuflags = firstcuflags;
- /* For caseless UTF mode, check whether this character has more than
- one other case. If so, generate a special OP_NOTPROP item instead of
+ /* For caseless UTF or UCP mode, check whether this character has more
+ than one other case. If so, generate a special OP_NOTPROP item instead of
OP_NOTI. */
#ifdef SUPPORT_UNICODE
- if (utf && (options & PCRE2_CASELESS) != 0 &&
+ if ((utf||ucp) && (options & PCRE2_CASELESS) != 0 &&
(d = UCD_CASESET(c)) != 0)
{
*code++ = OP_NOTPROP;
@@ -5597,7 +5604,7 @@ for (;; pptr++)
uint32_t d;
#ifdef SUPPORT_UNICODE
- if (utf && c > 127) d = UCD_OTHERCASE(c); else
+ if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else
#endif
{
#if PCRE2_CODE_UNIT_WIDTH != 8
@@ -6671,23 +6678,11 @@ for (;; pptr++)
}
/* For a back reference, update the back reference map and the
- maximum back reference. Then, for each group, we must check to
- see if it is recursive, that is, it is inside the group that it
- references. A flag is set so that the group can be made atomic.
- */
+ maximum back reference. */
cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
if (groupnumber > cb->top_backref)
cb->top_backref = groupnumber;
-
- for (oc = cb->open_caps; oc != NULL; oc = oc->next)
- {
- if (oc->number == groupnumber)
- {
- oc->flag = TRUE;
- break;
- }
- }
}
}
@@ -7081,15 +7076,18 @@ for (;; pptr++)
previous[GET(previous, 1)] != OP_ALT)
goto END_REPEAT;
- /* There is no sense in actually repeating assertions. The only
- potential use of repetition is in cases when the assertion is optional.
- Therefore, if the minimum is greater than zero, just ignore the repeat.
- If the maximum is not zero or one, set it to 1. */
+ /* Perl allows all assertions to be quantified, and when they contain
+ capturing parentheses and/or are optional there are potential uses for
+ this feature. PCRE2 used to force the maximum quantifier to 1 on the
+ invalid grounds that further repetition was never useful. This was
+ always a bit pointless, since an assertion could be wrapped with a
+ repeated group to achieve the effect. General repetition is now
+ permitted, but if the maximum is unlimited it is set to one more than
+ the minimum. */
if (op_previous < OP_ONCE) /* Assertion */
{
- if (repeat_min > 0) goto END_REPEAT;
- if (repeat_max > 1) repeat_max = 1;
+ if (repeat_max == REPEAT_UNLIMITED) repeat_max = repeat_min + 1;
}
/* The case of a zero minimum is special because of the need to stick
@@ -7682,19 +7680,6 @@ for (;; pptr++)
cb->backref_map |= (meta_arg < 32)? (1u << meta_arg) : 1;
if (meta_arg > cb->top_backref) cb->top_backref = meta_arg;
-
- /* Check to see if this back reference is recursive, that it, it
- is inside the group that it references. A flag is set so that the
- group can be made atomic. */
-
- for (oc = cb->open_caps; oc != NULL; oc = oc->next)
- {
- if (oc->number == meta_arg)
- {
- oc->flag = TRUE;
- break;
- }
- }
break;
@@ -7840,11 +7825,12 @@ for (;; pptr++)
NORMAL_CHAR_SET: /* Character is already in meta */
matched_char = TRUE;
- /* For caseless UTF mode, check whether this character has more than one
- other case. If so, generate a special OP_PROP item instead of OP_CHARI. */
+ /* For caseless UTF or UCP mode, check whether this character has more than
+ one other case. If so, generate a special OP_PROP item instead of OP_CHARI.
+ */
#ifdef SUPPORT_UNICODE
- if (utf && (options & PCRE2_CASELESS) != 0)
+ if ((utf||ucp) && (options & PCRE2_CASELESS) != 0)
{
uint32_t caseset = UCD_CASESET(meta);
if (caseset != 0)
@@ -8053,7 +8039,6 @@ if (*code == OP_CBRA)
capnumber = GET2(code, 1 + LINK_SIZE);
capitem.number = capnumber;
capitem.next = cb->open_caps;
- capitem.flag = FALSE;
capitem.assert_depth = cb->assert_depth;
cb->open_caps = &capitem;
}
@@ -8182,26 +8167,9 @@ for (;;)
PUT(code, 1, (int)(code - start_bracket));
code += 1 + LINK_SIZE;
- /* If it was a capturing subpattern, check to see if it contained any
- recursive back references. If so, we must wrap it in atomic brackets. In
- any event, remove the block from the chain. */
+ /* If it was a capturing subpattern, remove the block from the chain. */
- if (capnumber > 0)
- {
- if (cb->open_caps->flag)
- {
- (void)memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
- CU2BYTES(code - start_bracket));
- *start_bracket = OP_ONCE;
- code += 1 + LINK_SIZE;
- PUT(start_bracket, 1, (int)(code - start_bracket));
- *code = OP_KET;
- PUT(code, 1, (int)(code - start_bracket));
- code += 1 + LINK_SIZE;
- length += 2 + 2*LINK_SIZE;
- }
- cb->open_caps = cb->open_caps->next;
- }
+ if (capnumber > 0) cb->open_caps = cb->open_caps->next;
/* Set values to pass back */
@@ -8836,9 +8804,10 @@ memset(slot + IMM2_SIZE + length, 0,
/* This function is called to skip parts of the parsed pattern when finding the
length of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find
-the end of the branch, it is called to skip over an internal lookaround, and it
-is also called to skip to the end of a class, during which it will never
-encounter nested groups (but there's no need to have special code for that).
+the end of the branch, it is called to skip over an internal lookaround or
+(DEFINE) group, and it is also called to skip to the end of a class, during
+which it will never encounter nested groups (but there's no need to have
+special code for that).
When called to find the end of a branch or group, pptr must point to the first
meta code inside the branch, not the branch-starting code. In other cases it
@@ -9316,14 +9285,21 @@ for (;; pptr++)
itemlength = grouplength;
break;
- /* Check nested groups - advance past the initial data for each type and
- then seek a fixed length with get_grouplength(). */
+ /* A (DEFINE) group is never obeyed inline and so it does not contribute to
+ the length of this branch. Skip from the following item to the next
+ unpaired ket. */
+
+ case META_COND_DEFINE:
+ pptr = parsed_skip(pptr + 1, PSKIP_KET);
+ break;
+
+ /* Check other nested groups - advance past the initial data for each type
+ and then seek a fixed length with get_grouplength(). */
case META_COND_NAME:
case META_COND_NUMBER:
case META_COND_RNAME:
case META_COND_RNUMBER:
- case META_COND_DEFINE:
pptr += 2 + SIZEOFFSET;
goto CHECK_GROUP;
@@ -9580,6 +9556,10 @@ for (; *pptr != META_END; pptr++)
break;
case META_COND_DEFINE:
+ pptr += SIZEOFFSET;
+ nestlevel++;
+ break;
+
case META_COND_NAME:
case META_COND_NUMBER:
case META_COND_RNAME:
@@ -9660,6 +9640,7 @@ pcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options,
int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext)
{
BOOL utf; /* Set TRUE for UTF mode */
+BOOL ucp; /* Set TRUE for UCP mode */
BOOL has_lookbehind = FALSE; /* Set TRUE if a lookbehind is found */
BOOL zero_terminated; /* Set TRUE for zero-terminated pattern */
pcre2_real_code *re = NULL; /* What we will return */
@@ -9947,8 +9928,8 @@ if (utf)
/* Check UCP lockout. */
-if ((cb.external_options & (PCRE2_UCP|PCRE2_NEVER_UCP)) ==
- (PCRE2_UCP|PCRE2_NEVER_UCP))
+ucp = (cb.external_options & PCRE2_UCP) != 0;
+if (ucp && (cb.external_options & PCRE2_NEVER_UCP) != 0)
{
errorcode = ERR75;
goto HAD_EARLY_ERROR;
@@ -10324,7 +10305,7 @@ function call. */
if (errorcode == 0 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0)
{
PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;
- if (PRIV(auto_possessify)(temp, utf, &cb) != 0) errorcode = ERR80;
+ if (PRIV(auto_possessify)(temp, &cb) != 0) errorcode = ERR80;
}
/* Failed to compile, or error while post-processing. */
@@ -10372,21 +10353,25 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
if ((firstcuflags & REQ_CASELESS) != 0)
{
- if (firstcu < 128 || (!utf && firstcu < 255))
+ if (firstcu < 128 || (!utf && !ucp && firstcu < 255))
{
if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS;
}
- /* The first code unit is > 128 in UTF mode, or > 255 otherwise. In
- 8-bit UTF mode, codepoints in the range 128-255 are introductory code
- points and cannot have another case. In 16-bit and 32-bit modes, we can
- check wide characters when UTF (and therefore UCP) is supported. */
+ /* The first code unit is > 128 in UTF or UCP mode, or > 255 otherwise.
+ In 8-bit UTF mode, codepoints in the range 128-255 are introductory code
+ points and cannot have another case, but if UCP is set they may do. */
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- else if (firstcu <= MAX_UTF_CODE_POINT &&
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ else if (ucp && !utf && UCD_OTHERCASE(firstcu) != firstcu)
+ re->flags |= PCRE2_FIRSTCASELESS;
+#else
+ else if ((utf || ucp) && firstcu <= MAX_UTF_CODE_POINT &&
UCD_OTHERCASE(firstcu) != firstcu)
re->flags |= PCRE2_FIRSTCASELESS;
#endif
+#endif /* SUPPORT_UNICODE */
}
}
@@ -10435,14 +10420,20 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
if ((reqcuflags & REQ_CASELESS) != 0)
{
- if (reqcu < 128 || (!utf && reqcu < 255))
+ if (reqcu < 128 || (!utf && !ucp && reqcu < 255))
{
if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;
}
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu)
- re->flags |= PCRE2_LASTCASELESS;
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ else if (ucp && !utf && UCD_OTHERCASE(reqcu) != reqcu)
+ re->flags |= PCRE2_LASTCASELESS;
+#else
+ else if ((utf || ucp) && reqcu <= MAX_UTF_CODE_POINT &&
+ UCD_OTHERCASE(reqcu) != reqcu)
+ re->flags |= PCRE2_LASTCASELESS;
#endif
+#endif /* SUPPORT_UNICODE */
}
}
}
diff --git a/thirdparty/pcre2/src/pcre2_config.c b/thirdparty/pcre2/src/pcre2_config.c
index e487b10220..5ef103caf7 100644
--- a/thirdparty/pcre2/src/pcre2_config.c
+++ b/thirdparty/pcre2/src/pcre2_config.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2017 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -43,7 +43,8 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
/* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes
-its value gets changed by pcre2_internal.h to be in code units. */
+its value gets changed by pcre2_intmodedep.h (included by pcre2_internal.h) to
+be in code units. */
static int configured_link_size = LINK_SIZE;
@@ -94,6 +95,7 @@ if (where == NULL) /* Requests a length */
case PCRE2_CONFIG_NEWLINE:
case PCRE2_CONFIG_PARENSLIMIT:
case PCRE2_CONFIG_STACKRECURSE: /* Obsolete */
+ case PCRE2_CONFIG_TABLES_LENGTH:
case PCRE2_CONFIG_UNICODE:
return sizeof(uint32_t);
@@ -191,6 +193,10 @@ switch (what)
*((uint32_t *)where) = 0;
break;
+ case PCRE2_CONFIG_TABLES_LENGTH:
+ *((uint32_t *)where) = TABLES_LENGTH;
+ break;
+
case PCRE2_CONFIG_UNICODE_VERSION:
{
#if defined SUPPORT_UNICODE
diff --git a/thirdparty/pcre2/src/pcre2_dfa_match.c b/thirdparty/pcre2/src/pcre2_dfa_match.c
index 7d8ffe8a3e..625695b7cb 100644
--- a/thirdparty/pcre2/src/pcre2_dfa_match.c
+++ b/thirdparty/pcre2/src/pcre2_dfa_match.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -548,6 +548,7 @@ PCRE2_SPTR start_code = mb->start_code;
#ifdef SUPPORT_UNICODE
BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
+BOOL utf_or_ucp = utf || (mb->poptions & PCRE2_UCP) != 0;
#else
BOOL utf = FALSE;
#endif
@@ -2190,7 +2191,7 @@ for (;;)
if (clen == 0) break;
#ifdef SUPPORT_UNICODE
- if (utf)
+ if (utf_or_ucp)
{
if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
{
@@ -2204,7 +2205,7 @@ for (;;)
}
else
#endif /* SUPPORT_UNICODE */
- /* Not UTF mode */
+ /* Not UTF or UCP mode */
{
if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
{ ADD_NEW(state_offset + 2, 0); }
@@ -2339,7 +2340,7 @@ for (;;)
{
uint32_t otherd;
#ifdef SUPPORT_UNICODE
- if (utf && d >= 128)
+ if (utf_or_ucp && d >= 128)
otherd = UCD_OTHERCASE(d);
else
#endif /* SUPPORT_UNICODE */
@@ -2374,7 +2375,7 @@ for (;;)
if (caseless)
{
#ifdef SUPPORT_UNICODE
- if (utf && d >= 128)
+ if (utf_or_ucp && d >= 128)
otherd = UCD_OTHERCASE(d);
else
#endif /* SUPPORT_UNICODE */
@@ -2417,7 +2418,7 @@ for (;;)
if (caseless)
{
#ifdef SUPPORT_UNICODE
- if (utf && d >= 128)
+ if (utf_or_ucp && d >= 128)
otherd = UCD_OTHERCASE(d);
else
#endif /* SUPPORT_UNICODE */
@@ -2458,7 +2459,7 @@ for (;;)
if (caseless)
{
#ifdef SUPPORT_UNICODE
- if (utf && d >= 128)
+ if (utf_or_ucp && d >= 128)
otherd = UCD_OTHERCASE(d);
else
#endif /* SUPPORT_UNICODE */
@@ -2491,7 +2492,7 @@ for (;;)
if (caseless)
{
#ifdef SUPPORT_UNICODE
- if (utf && d >= 128)
+ if (utf_or_ucp && d >= 128)
otherd = UCD_OTHERCASE(d);
else
#endif /* SUPPORT_UNICODE */
@@ -2531,7 +2532,7 @@ for (;;)
if (caseless)
{
#ifdef SUPPORT_UNICODE
- if (utf && d >= 128)
+ if (utf_or_ucp && d >= 128)
otherd = UCD_OTHERCASE(d);
else
#endif /* SUPPORT_UNICODE */
@@ -3526,10 +3527,15 @@ if ((re->flags & PCRE2_FIRSTSET) != 0)
if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
{
first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- if (utf && first_cu > 127)
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (first_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)
+ first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
+#else
+ if (first_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))
first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
#endif
+#endif /* SUPPORT_UNICODE */
}
}
else
@@ -3545,9 +3551,15 @@ if ((re->flags & PCRE2_LASTSET) != 0)
if ((re->flags & PCRE2_LASTCASELESS) != 0)
{
req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- if (utf && req_cu > 127) req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (req_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)
+ req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
+#else
+ if (req_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))
+ req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
#endif
+#endif /* SUPPORT_UNICODE */
}
}
diff --git a/thirdparty/pcre2/src/pcre2_internal.h b/thirdparty/pcre2/src/pcre2_internal.h
index fe8ffe5c80..d8fad1e93b 100644
--- a/thirdparty/pcre2/src/pcre2_internal.h
+++ b/thirdparty/pcre2/src/pcre2_internal.h
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -76,6 +76,17 @@ typedef int BOOL;
#include <valgrind/memcheck.h>
#endif
+/* -ftrivial-auto-var-init support supports initializing all local variables
+to avoid some classes of bug, but this can cause an unacceptable slowdown
+for large on-stack arrays in hot functions. This macro lets us annotate
+such arrays. */
+
+#ifdef HAVE_ATTRIBUTE_UNINITIALIZED
+#define PCRE2_KEEP_UNINITIALIZED __attribute__((uninitialized))
+#else
+#define PCRE2_KEEP_UNINITIALIZED
+#endif
+
/* Older versions of MSVC lack snprintf(). This define allows for
warning/error-free compilation and testing with MSVC compilers back to at least
MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */
@@ -579,7 +590,7 @@ total length of the tables. */
#define fcc_offset 256 /* Flip case */
#define cbits_offset 512 /* Character classes */
#define ctypes_offset (cbits_offset + cbit_length) /* Character types */
-#define tables_length (ctypes_offset + 256)
+#define TABLES_LENGTH (ctypes_offset + 256)
/* -------------------- Character and string names ------------------------ */
@@ -1759,13 +1770,11 @@ typedef struct pcre2_memctl {
/* Structure for building a chain of open capturing subpatterns during
compiling, so that instructions to close them can be compiled when (*ACCEPT) is
-encountered. This is also used to identify subpatterns that contain recursive
-back references to themselves, so that they can be made atomic. */
+encountered. */
typedef struct open_capitem {
struct open_capitem *next; /* Chain link */
uint16_t number; /* Capture number */
- uint16_t flag; /* Set TRUE if recursive back ref */
uint16_t assert_depth; /* Assertion depth when opened */
} open_capitem;
@@ -1954,7 +1963,7 @@ is available. */
#define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_)
#define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_)
-extern int _pcre2_auto_possessify(PCRE2_UCHAR *, BOOL,
+extern int _pcre2_auto_possessify(PCRE2_UCHAR *,
const compile_block *);
extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *,
int *, uint32_t, uint32_t, BOOL, compile_block *);
diff --git a/thirdparty/pcre2/src/pcre2_jit_compile.c b/thirdparty/pcre2/src/pcre2_jit_compile.c
index f564127c2a..1977d28aa5 100644
--- a/thirdparty/pcre2/src/pcre2_jit_compile.c
+++ b/thirdparty/pcre2/src/pcre2_jit_compile.c
@@ -223,6 +223,12 @@ enum control_types {
type_then_trap = 1
};
+enum early_fail_types {
+ type_skip = 0,
+ type_fail = 1,
+ type_fail_range = 2
+};
+
typedef int (SLJIT_FUNC *jit_function)(jit_arguments *args);
/* The following structure is the key data type for the recursive
@@ -405,8 +411,8 @@ typedef struct compiler_common {
/* Fast forward skipping byte code pointer. */
PCRE2_SPTR fast_forward_bc_ptr;
/* Locals used by fast fail optimization. */
- sljit_s32 fast_fail_start_ptr;
- sljit_s32 fast_fail_end_ptr;
+ sljit_s32 early_fail_start_ptr;
+ sljit_s32 early_fail_end_ptr;
/* Flipped and lower case tables. */
const sljit_u8 *fcc;
@@ -476,7 +482,7 @@ typedef struct compiler_common {
#ifdef SUPPORT_UNICODE
BOOL utf;
BOOL invalid_utf;
- BOOL use_ucp;
+ BOOL ucp;
/* Points to saving area for iref. */
sljit_s32 iref_ptr;
jump_list *getucd;
@@ -607,6 +613,8 @@ the start pointers when the end of the capturing group has not yet reached. */
sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
+#define OP_SRC(op, src, srcw) \
+ sljit_emit_op_src(compiler, (op), (src), (srcw))
#define LABEL() \
sljit_emit_label(compiler)
#define JUMP(type) \
@@ -823,7 +831,7 @@ the start pointers when the end of the capturing group has not yet reached. */
static PCRE2_SPTR bracketend(PCRE2_SPTR cc)
{
-SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
do cc += GET(cc, 1); while (*cc == OP_ALT);
SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
cc += 1 + LINK_SIZE;
@@ -833,7 +841,7 @@ return cc;
static int no_alternatives(PCRE2_SPTR cc)
{
int count = 0;
-SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
do
{
cc += GET(cc, 1);
@@ -918,6 +926,8 @@ switch(*cc)
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_BRA:
@@ -1050,8 +1060,7 @@ switch(*cc)
return cc + 1 + 2 + cc[1];
default:
- /* Unsupported opcodes: OP_ASSERT_NA and OP_ASSERTBACK_NA */
- /* SLJIT_UNREACHABLE(); */
+ SLJIT_UNREACHABLE();
return NULL;
}
}
@@ -1061,6 +1070,7 @@ static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPT
int count;
PCRE2_SPTR slot;
PCRE2_SPTR assert_back_end = cc - 1;
+PCRE2_SPTR assert_na_end = cc - 1;
/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
while (cc < ccend)
@@ -1087,6 +1097,14 @@ while (cc < ccend)
cc += 1 + IMM2_SIZE;
break;
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
+ slot = bracketend(cc);
+ if (slot > assert_na_end)
+ assert_na_end = slot;
+ cc += 1 + LINK_SIZE;
+ break;
+
case OP_CBRAPOS:
case OP_SCBRAPOS:
common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
@@ -1154,6 +1172,9 @@ while (cc < ccend)
case OP_COMMIT_ARG:
case OP_PRUNE_ARG:
+ if (cc < assert_na_end)
+ return FALSE;
+ /* Fall through */
case OP_MARK:
if (common->mark_ptr == 0)
{
@@ -1172,6 +1193,8 @@ while (cc < ccend)
case OP_SKIP:
if (cc < assert_back_end)
common->has_skip_in_assert_back = TRUE;
+ if (cc < assert_na_end)
+ return FALSE;
cc += 1;
break;
@@ -1180,9 +1203,19 @@ while (cc < ccend)
common->has_skip_arg = TRUE;
if (cc < assert_back_end)
common->has_skip_in_assert_back = TRUE;
+ if (cc < assert_na_end)
+ return FALSE;
cc += 1 + 2 + cc[1];
break;
+ case OP_PRUNE:
+ case OP_COMMIT:
+ case OP_ASSERT_ACCEPT:
+ if (cc < assert_na_end)
+ return FALSE;
+ cc++;
+ break;
+
default:
cc = next_opcode(common, cc);
if (cc == NULL)
@@ -1193,183 +1226,355 @@ while (cc < ccend)
return TRUE;
}
-static BOOL is_accelerated_repeat(PCRE2_SPTR cc)
+#define EARLY_FAIL_ENHANCE_MAX (1 + 1)
+
+/*
+start:
+ 0 - skip / early fail allowed
+ 1 - only early fail with range allowed
+ >1 - (start - 1) early fail is processed
+
+return: current number of iterators enhanced with fast fail
+*/
+static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth, int start)
{
-switch(*cc)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI);
+PCRE2_SPTR next_alt;
+PCRE2_SPTR end;
+PCRE2_SPTR accelerated_start;
+int result = 0;
+int count;
+BOOL fast_forward_allowed = TRUE;
- case OP_STAR:
- case OP_MINSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSSTAR:
- case OP_POSPLUS:
+SLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA);
+SLJIT_ASSERT(*cc != OP_CBRA || common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] != 0);
+SLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX);
- case OP_STARI:
- case OP_MINSTARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSSTARI:
- case OP_POSPLUSI:
+do
+ {
+ count = start;
+ next_alt = cc + GET(cc, 1);
+ cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSPLUS:
+ while (TRUE)
+ {
+ accelerated_start = NULL;
- case OP_NOTSTARI:
- case OP_NOTMINSTARI:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUSI:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSPLUSI:
- return TRUE;
+ switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_SET_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ /* Zero width assertions. */
+ cc++;
+ continue;
+
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ fast_forward_allowed = FALSE;
+ cc++;
+ continue;
- case OP_CLASS:
- case OP_NCLASS:
-#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
- case OP_XCLASS:
- cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(PCRE2_UCHAR)));
-#else
- cc += (1 + (32 / sizeof(PCRE2_UCHAR)));
+ case OP_ANYNL:
+ case OP_EXTUNI:
+ fast_forward_allowed = FALSE;
+ if (count == 0)
+ count = 1;
+ cc++;
+ continue;
+
+ case OP_NOTPROP:
+ case OP_PROP:
+ fast_forward_allowed = FALSE;
+ cc += 1 + 2;
+ continue;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ fast_forward_allowed = FALSE;
+ cc += 2;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
#endif
+ continue;
- switch(*cc)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRPOSSTAR:
- case OP_CRPOSPLUS:
- return TRUE;
- }
- break;
- }
-return FALSE;
-}
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ /* The type or prop opcode is skipped in the next iteration. */
+ cc += 1;
-static SLJIT_INLINE BOOL detect_fast_forward_skip(compiler_common *common, int *private_data_start)
-{
-PCRE2_SPTR cc = common->start;
-PCRE2_SPTR end;
+ if (cc[0] != OP_ANYNL && cc[0] != OP_EXTUNI)
+ {
+ accelerated_start = cc - 1;
+ break;
+ }
-/* Skip not repeated brackets. */
-while (TRUE)
- {
- switch(*cc)
- {
- case OP_SOD:
- case OP_SOM:
- case OP_SET_SOM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_EODN:
- case OP_EOD:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- /* Zero width assertions. */
- cc++;
- continue;
- }
+ if (count == 0)
+ count = 1;
+ fast_forward_allowed = FALSE;
+ continue;
- if (*cc != OP_BRA && *cc != OP_CBRA)
- break;
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ cc += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ /* The type or prop opcode is skipped in the next iteration. */
+ fast_forward_allowed = FALSE;
+ if (count == 0)
+ count = 1;
+ cc += 1;
+ continue;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ accelerated_start = cc;
+ cc += 2;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
- end = cc + GET(cc, 1);
- if (*end != OP_KET || PRIVATE_DATA(end) != 0)
- return FALSE;
- if (*cc == OP_CBRA)
- {
- if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
- return FALSE;
- cc += IMM2_SIZE;
- }
- cc += 1 + LINK_SIZE;
- }
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSUPTO:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSUPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSUPTOI:
+ cc += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSQUERYI:
+ fast_forward_allowed = FALSE;
+ if (count == 0)
+ count = 1;
+ cc += 2;
+#ifdef SUPPORT_UNICODE
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ continue;
-if (is_accelerated_repeat(cc))
- {
- common->fast_forward_bc_ptr = cc;
- common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
- *private_data_start += sizeof(sljit_sw);
- return TRUE;
- }
-return FALSE;
-}
+ case OP_CLASS:
+ case OP_NCLASS:
+#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
+ case OP_XCLASS:
+ accelerated_start = cc;
+ cc += ((*cc == OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR))));
+#else
+ accelerated_start = cc;
+ cc += (1 + (32 / sizeof(PCRE2_UCHAR)));
+#endif
-static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth)
-{
- PCRE2_SPTR next_alt;
+ switch (*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ cc++;
+ break;
- SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA);
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ cc += 2 * IMM2_SIZE;
+ /* Fall through */
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSQUERY:
+ cc++;
+ if (count == 0)
+ count = 1;
+ /* Fall through */
+ default:
+ accelerated_start = NULL;
+ fast_forward_allowed = FALSE;
+ continue;
+ }
+ break;
- if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
- return;
+ case OP_ONCE:
+ case OP_BRA:
+ case OP_CBRA:
+ end = cc + GET(cc, 1);
- next_alt = bracketend(cc) - (1 + LINK_SIZE);
- if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0)
- return;
+ if (*end == OP_KET && PRIVATE_DATA(end) == 0)
+ {
+ if (*cc == OP_CBRA)
+ {
+ if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
+ break;
+ cc += IMM2_SIZE;
+ }
- do
- {
- next_alt = cc + GET(cc, 1);
+ cc += 1 + LINK_SIZE;
+ continue;
+ }
- cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);
+ fast_forward_allowed = FALSE;
+ if (depth >= 4)
+ break;
- while (TRUE)
- {
- switch(*cc)
+ end = bracketend(cc) - (1 + LINK_SIZE);
+ if (*end != OP_KET || PRIVATE_DATA(end) != 0)
+ break;
+
+ if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
+ break;
+
+ count = detect_early_fail(common, cc, private_data_start, depth + 1, count);
+ if (count < EARLY_FAIL_ENHANCE_MAX)
{
- case OP_SOD:
- case OP_SOM:
- case OP_SET_SOM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- case OP_EODN:
- case OP_EOD:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- /* Zero width assertions. */
- cc++;
+ cc = end + (1 + LINK_SIZE);
continue;
}
break;
- }
- if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA))
- detect_fast_fail(common, cc, private_data_start, depth - 1);
+ case OP_KET:
+ SLJIT_ASSERT(PRIVATE_DATA(cc) == 0);
+ if (cc >= next_alt)
+ break;
+ cc += 1 + LINK_SIZE;
+ continue;
+ }
- if (is_accelerated_repeat(cc))
+ if (accelerated_start != NULL)
{
- common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
+ if (count == 0)
+ {
+ count++;
- if (common->fast_fail_start_ptr == 0)
- common->fast_fail_start_ptr = *private_data_start;
+ if (fast_forward_allowed && *next_alt == OP_KET)
+ {
+ common->fast_forward_bc_ptr = accelerated_start;
+ common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip;
+ *private_data_start += sizeof(sljit_sw);
+ }
+ else
+ {
+ common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail;
- *private_data_start += sizeof(sljit_sw);
- common->fast_fail_end_ptr = *private_data_start;
+ if (common->early_fail_start_ptr == 0)
+ common->early_fail_start_ptr = *private_data_start;
- if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
- return;
+ *private_data_start += sizeof(sljit_sw);
+ common->early_fail_end_ptr = *private_data_start;
+
+ if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
+ return EARLY_FAIL_ENHANCE_MAX;
+ }
+ }
+ else
+ {
+ common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range;
+
+ if (common->early_fail_start_ptr == 0)
+ common->early_fail_start_ptr = *private_data_start;
+
+ *private_data_start += 2 * sizeof(sljit_sw);
+ common->early_fail_end_ptr = *private_data_start;
+
+ if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
+ return EARLY_FAIL_ENHANCE_MAX;
+ }
+
+ count++;
+
+ if (count < EARLY_FAIL_ENHANCE_MAX)
+ continue;
}
- cc = next_alt;
+ break;
}
- while (*cc == OP_ALT);
+
+ if (*cc != OP_ALT && *cc != OP_KET)
+ result = EARLY_FAIL_ENHANCE_MAX;
+ else if (result < count)
+ result = count;
+
+ fast_forward_allowed = FALSE;
+ cc = next_alt;
+ }
+while (*cc == OP_ALT);
+
+return result;
}
static int get_class_iterator_size(PCRE2_SPTR cc)
@@ -1586,6 +1791,8 @@ while (cc < ccend)
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_BRAPOS:
@@ -1627,57 +1834,57 @@ while (cc < ccend)
case OP_BRAZERO:
case OP_BRAMINZERO:
case OP_BRAPOSZERO:
- repeat_check = FALSE;
size = 1;
+ repeat_check = FALSE;
break;
CASE_ITERATOR_PRIVATE_DATA_1
- space = 1;
size = -2;
+ space = 1;
break;
CASE_ITERATOR_PRIVATE_DATA_2A
- space = 2;
size = -2;
+ space = 2;
break;
CASE_ITERATOR_PRIVATE_DATA_2B
- space = 2;
size = -(2 + IMM2_SIZE);
+ space = 2;
break;
CASE_ITERATOR_TYPE_PRIVATE_DATA_1
- space = 1;
size = 1;
+ space = 1;
break;
CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
+ size = 1;
if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
space = 2;
- size = 1;
break;
case OP_TYPEUPTO:
+ size = 1 + IMM2_SIZE;
if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
space = 2;
- size = 1 + IMM2_SIZE;
break;
case OP_TYPEMINUPTO:
- space = 2;
size = 1 + IMM2_SIZE;
+ space = 2;
break;
case OP_CLASS:
case OP_NCLASS:
- space = get_class_iterator_size(cc + size);
size = 1 + 32 / sizeof(PCRE2_UCHAR);
+ space = get_class_iterator_size(cc + size);
break;
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
case OP_XCLASS:
- space = get_class_iterator_size(cc + size);
size = GET(cc, 1);
+ space = get_class_iterator_size(cc + size);
break;
#endif
@@ -2163,6 +2370,8 @@ while (cc < ccend)
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_BRAPOS:
@@ -2487,6 +2696,8 @@ while (cc < ccend)
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_BRAPOS:
@@ -2660,8 +2871,8 @@ while (cc < ccend)
}
if (common->control_head_ptr != 0 && !control_head_found)
{
- shared_srcw[0] = common->control_head_ptr;
- shared_count = 1;
+ private_srcw[0] = common->control_head_ptr;
+ private_count = 1;
control_head_found = TRUE;
}
cc += 1 + 2 + cc[1];
@@ -2671,8 +2882,8 @@ while (cc < ccend)
SLJIT_ASSERT(common->control_head_ptr != 0);
if (!control_head_found)
{
- shared_srcw[0] = common->control_head_ptr;
- shared_count = 1;
+ private_srcw[0] = common->control_head_ptr;
+ private_count = 1;
control_head_found = TRUE;
}
cc++;
@@ -2756,7 +2967,7 @@ PCRE2_SPTR end = bracketend(cc);
BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
/* Assert captures then. */
-if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
+if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA)
current_offset = NULL;
/* Conditional block does not. */
if (*cc == OP_COND || *cc == OP_SCOND)
@@ -2768,7 +2979,7 @@ if (has_alternatives)
while (cc < end)
{
- if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
+ if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
cc = set_then_offsets(common, cc, current_offset);
else
{
@@ -2938,16 +3149,54 @@ else
}
}
-static SLJIT_INLINE void reset_fast_fail(compiler_common *common)
+static SLJIT_INLINE void reset_early_fail(compiler_common *common)
{
DEFINE_COMPILER;
+sljit_u32 size = (sljit_u32)(common->early_fail_end_ptr - common->early_fail_start_ptr);
+sljit_u32 uncleared_size;
+sljit_s32 src = SLJIT_IMM;
sljit_s32 i;
+struct sljit_label *loop;
+
+SLJIT_ASSERT(common->early_fail_start_ptr < common->early_fail_end_ptr);
+
+if (size == sizeof(sljit_sw))
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->early_fail_start_ptr, SLJIT_IMM, 0);
+ return;
+ }
+
+if (sljit_get_register_index(TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER))
+ {
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
+ src = TMP3;
+ }
+
+if (size <= 6 * sizeof(sljit_sw))
+ {
+ for (i = common->early_fail_start_ptr; i < common->early_fail_end_ptr; i += sizeof(sljit_sw))
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, src, 0);
+ return;
+ }
-SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr);
+GET_LOCAL_BASE(TMP1, 0, common->early_fail_start_ptr);
-OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw))
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0);
+uncleared_size = ((size / sizeof(sljit_sw)) % 3) * sizeof(sljit_sw);
+
+OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, size - uncleared_size);
+
+loop = LABEL();
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -2 * (sljit_sw)sizeof(sljit_sw), src, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -1 * (sljit_sw)sizeof(sljit_sw), src, 0);
+CMPTO(SLJIT_LESS, TMP1, 0, TMP2, 0, loop);
+
+if (uncleared_size >= sizeof(sljit_sw))
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);
+
+if (uncleared_size >= 2 * sizeof(sljit_sw))
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), sizeof(sljit_sw), src, 0);
}
static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
@@ -3193,16 +3442,19 @@ static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR
unsigned int c;
#ifdef SUPPORT_UNICODE
-if (common->utf)
+if (common->utf || common->ucp)
{
- GETCHAR(c, cc);
- if (c > 127)
+ if (common->utf)
{
- return c != UCD_OTHERCASE(c);
+ GETCHAR(c, cc);
}
-#if PCRE2_CODE_UNIT_WIDTH != 8
+ else
+ c = *cc;
+
+ if (c > 127)
+ return c != UCD_OTHERCASE(c);
+
return common->fcc[c] != c;
-#endif
}
else
#endif
@@ -3214,10 +3466,8 @@ static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigne
{
/* Returns with the othercase. */
#ifdef SUPPORT_UNICODE
-if (common->utf && c > 127)
- {
+if ((common->utf || common->ucp) && c > 127)
return UCD_OTHERCASE(c);
- }
#endif
return TABLE_GET(c, common->fcc, c);
}
@@ -3231,15 +3481,19 @@ int n;
#endif
#ifdef SUPPORT_UNICODE
-if (common->utf)
+if (common->utf || common->ucp)
{
- GETCHAR(c, cc);
+ if (common->utf)
+ {
+ GETCHAR(c, cc);
+ }
+ else
+ c = *cc;
+
if (c <= 127)
oc = common->fcc[c];
else
- {
oc = UCD_OTHERCASE(c);
- }
}
else
{
@@ -4083,7 +4337,7 @@ jump = JUMP(SLJIT_NOT_ZERO);
/* Two byte sequence. */
OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3000);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(jump);
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
@@ -4096,7 +4350,7 @@ jump = JUMP(SLJIT_NOT_ZERO);
/* Three byte sequence. */
OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0000);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
/* Four byte sequence. */
JUMPHERE(jump);
@@ -4106,7 +4360,7 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfreadtype8(compiler_common *common)
@@ -4131,18 +4385,18 @@ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(compare);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
/* We only have types for characters less than 256. */
JUMPHERE(jump);
OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfreadchar_invalid(compiler_common *common)
@@ -4182,7 +4436,7 @@ OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
jump = JUMP(SLJIT_NOT_ZERO);
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(jump);
@@ -4225,7 +4479,7 @@ if (has_cmov)
}
else
exit_invalid[4] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(jump);
@@ -4254,7 +4508,7 @@ else
exit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(buffer_end_close);
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
@@ -4271,7 +4525,7 @@ exit_invalid[8] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
jump = JUMP(SLJIT_NOT_ZERO);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
/* Three-byte sequence. */
JUMPHERE(jump);
@@ -4301,7 +4555,7 @@ for (i = 0; i < 11; i++)
sljit_set_label(exit_invalid[i], exit_invalid_label);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfreadnewline_invalid(compiler_common *common)
@@ -4324,7 +4578,14 @@ if (common->nltype != NLTYPE_ANY)
/* All newlines are ascii, just skip intermediate octets. */
jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
loop = LABEL();
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)) == SLJIT_SUCCESS)
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ else
+ {
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);
CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop);
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
@@ -4332,7 +4593,7 @@ if (common->nltype != NLTYPE_ANY)
JUMPHERE(jump[0]);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
- sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+ OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
return;
}
@@ -4363,14 +4624,14 @@ JUMPHERE(jump[0]);
JUMPHERE(jump[4]);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
/* Two byte long newline: 0x85. */
JUMPHERE(jump[1]);
CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x85, skip_start);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x85);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
/* Three byte long newlines: 0x2028 and 0x2029. */
JUMPHERE(jump[2]);
@@ -4385,7 +4646,7 @@ CMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40, skip_start);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0x2000);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfmoveback_invalid(compiler_common *common)
@@ -4414,7 +4675,7 @@ jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x20);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
/* Three-byte sequence. */
JUMPHERE(jump);
@@ -4427,7 +4688,7 @@ jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x10);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
/* Four-byte sequence. */
JUMPHERE(jump);
@@ -4440,7 +4701,7 @@ exit_invalid[3] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x05);
exit_ok_label = LABEL();
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
/* Two-byte sequence. */
JUMPHERE(buffer_start_close);
@@ -4470,7 +4731,7 @@ sljit_set_label(exit_invalid[5], exit_invalid_label);
sljit_set_label(exit_invalid[6], exit_invalid_label);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(exit_invalid[4]);
/* -2 + 4 = 2 */
@@ -4481,7 +4742,7 @@ for (i = 0; i < 4; i++)
sljit_set_label(exit_invalid[i], exit_invalid_label);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(4));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfpeakcharback(compiler_common *common)
@@ -4518,7 +4779,7 @@ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfpeakcharback_invalid(compiler_common *common)
@@ -4548,7 +4809,7 @@ two_byte_entry = LABEL();
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
/* If TMP1 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(jump[1]);
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80);
@@ -4586,7 +4847,7 @@ if (has_cmov)
else
exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(jump[1]);
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0 - 0x80);
@@ -4612,7 +4873,7 @@ else
exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(jump[0]);
OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
@@ -4635,7 +4896,7 @@ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0);
CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x10, three_byte_entry);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(jump[0]);
exit_invalid[7] = CMP(SLJIT_GREATER, TMP2, 0, STR_PTR, 0);
@@ -4650,7 +4911,7 @@ for (i = 0; i < 8; i++)
sljit_set_label(exit_invalid[i], exit_invalid_label);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
@@ -4680,13 +4941,13 @@ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000);
exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(exit_invalid[0]);
JUMPHERE(exit_invalid[1]);
JUMPHERE(exit_invalid[2]);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfreadnewline_invalid(compiler_common *common)
@@ -4713,12 +4974,12 @@ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(exit_invalid[0]);
JUMPHERE(exit_invalid[1]);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfmoveback_invalid(compiler_common *common)
@@ -4738,7 +4999,7 @@ exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x400);
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(exit_invalid[0]);
JUMPHERE(exit_invalid[1]);
@@ -4746,7 +5007,7 @@ JUMPHERE(exit_invalid[2]);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_utfpeakcharback_invalid(compiler_common *common)
@@ -4771,14 +5032,14 @@ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
JUMPHERE(jump);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(exit_invalid[0]);
JUMPHERE(exit_invalid[1]);
JUMPHERE(exit_invalid[2]);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */
@@ -4824,7 +5085,7 @@ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_getucdtype(compiler_common *common)
@@ -4871,7 +5132,7 @@ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 1);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
#endif /* SUPPORT_UNICODE */
@@ -5159,6 +5420,8 @@ while (TRUE)
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
cc = bracketend(cc);
continue;
@@ -5458,7 +5721,12 @@ while (TRUE)
#endif
{
chr = *cc;
- othercase[0] = TABLE_GET(chr, common->fcc, chr);
+#ifdef SUPPORT_UNICODE
+ if (common->ucp && chr > 127)
+ othercase[0] = UCD_OTHERCASE(chr);
+ else
+#endif
+ othercase[0] = TABLE_GET(chr, common->fcc, chr);
}
}
else
@@ -5887,8 +6155,8 @@ oc = first_char;
if ((common->re->flags & PCRE2_FIRSTCASELESS) != 0)
{
oc = TABLE_GET(first_char, common->fcc, first_char);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- if (first_char > 127 && common->utf)
+#if defined SUPPORT_UNICODE
+ if (first_char > 127 && (common->utf || common->ucp))
oc = UCD_OTHERCASE(first_char);
#endif
}
@@ -5900,9 +6168,9 @@ static SLJIT_INLINE void fast_forward_newline(compiler_common *common)
{
DEFINE_COMPILER;
struct sljit_label *loop;
-struct sljit_jump *lastchar;
+struct sljit_jump *lastchar = NULL;
struct sljit_jump *firstchar;
-struct sljit_jump *quit;
+struct sljit_jump *quit = NULL;
struct sljit_jump *foundcr = NULL;
struct sljit_jump *notfoundnl;
jump_list *newline = NULL;
@@ -5915,39 +6183,71 @@ if (common->match_end_ptr != 0)
if (common->nltype == NLTYPE_FIXED && common->newline > 255)
{
- lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- if (HAS_VIRTUAL_REGISTERS)
+#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
+ if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && common->mode == PCRE2_JIT_COMPLETE)
{
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+ OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_NOT_EQUAL);
+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+
+ fast_forward_char_pair_simd(common, 1, common->newline & 0xff, common->newline & 0xff, 0, (common->newline >> 8) & 0xff, (common->newline >> 8) & 0xff);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
}
else
+#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */
{
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
- }
- firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+ lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
- OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
#endif
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
- loop = LABEL();
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
- CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
+ loop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
+ CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
+
+ JUMPHERE(quit);
+ JUMPHERE(lastchar);
+ }
- JUMPHERE(quit);
JUMPHERE(firstchar);
- JUMPHERE(lastchar);
if (common->match_end_ptr != 0)
OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
@@ -5964,22 +6264,59 @@ else
/* Example: match /^/ to \r\n from offset 1. */
firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-move_back(common, NULL, FALSE);
+
+if (common->nltype == NLTYPE_ANY)
+ move_back(common, NULL, FALSE);
+else
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
loop = LABEL();
common->ff_newline_shortcut = loop;
-read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);
-lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
- foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
-check_newlinechar(common, common->nltype, &newline, FALSE);
-set_jumps(newline, loop);
+#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD
+if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common->nltype == NLTYPE_ANYCRLF))
+ {
+ if (common->nltype == NLTYPE_ANYCRLF)
+ {
+ fast_forward_char_simd(common, CHAR_CR, CHAR_LF, 0);
+ if (common->mode != PCRE2_JIT_COMPLETE)
+ lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ quit = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ }
+ else
+ {
+ fast_forward_char_simd(common, common->newline, common->newline, 0);
+
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ if (common->mode != PCRE2_JIT_COMPLETE)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
+ CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
+ }
+ }
+ }
+else
+#endif /* JIT_HAS_FAST_FORWARD_CHAR_SIMD */
+ {
+ read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);
+ lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ check_newlinechar(common, common->nltype, &newline, FALSE);
+ set_jumps(newline, loop);
+ }
if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
{
- quit = JUMP(SLJIT_JUMP);
- JUMPHERE(foundcr);
+ if (quit == NULL)
+ {
+ quit = JUMP(SLJIT_JUMP);
+ JUMPHERE(foundcr);
+ }
+
notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
@@ -5991,7 +6328,9 @@ if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
JUMPHERE(notfoundnl);
JUMPHERE(quit);
}
-JUMPHERE(lastchar);
+
+if (lastchar)
+ JUMPHERE(lastchar);
JUMPHERE(firstchar);
if (common->match_end_ptr != 0)
@@ -6072,67 +6411,80 @@ if (common->match_end_ptr != 0)
OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
}
-static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar)
+static SLJIT_INLINE jump_list *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar)
{
DEFINE_COMPILER;
struct sljit_label *loop;
struct sljit_jump *toolong;
-struct sljit_jump *alreadyfound;
+struct sljit_jump *already_found;
struct sljit_jump *found;
-struct sljit_jump *foundoc = NULL;
-struct sljit_jump *notfound;
+struct sljit_jump *found_oc = NULL;
+jump_list *not_found = NULL;
sljit_u32 oc, bit;
SLJIT_ASSERT(common->req_char_ptr != 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);
-OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_CU_MAX);
-toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0);
-alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
+OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(REQ_CU_MAX) * 100);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);
+toolong = CMP(SLJIT_LESS, TMP2, 0, STR_END, 0);
+already_found = CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0);
if (has_firstchar)
OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
else
OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
-loop = LABEL();
-notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0);
-
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
oc = req_char;
if (caseless)
{
oc = TABLE_GET(req_char, common->fcc, req_char);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- if (req_char > 127 && common->utf)
+#if defined SUPPORT_UNICODE
+ if (req_char > 127 && (common->utf || common->ucp))
oc = UCD_OTHERCASE(req_char);
#endif
}
-if (req_char == oc)
- found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+
+#ifdef JIT_HAS_FAST_REQUESTED_CHAR_SIMD
+if (JIT_HAS_FAST_REQUESTED_CHAR_SIMD)
+ {
+ not_found = fast_requested_char_simd(common, req_char, oc);
+ }
else
+#endif
{
- bit = req_char ^ oc;
- if (is_powerof2(bit))
- {
- OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
- found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
- }
+ loop = LABEL();
+ add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
+
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+
+ if (req_char == oc)
+ found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
else
{
- found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
- foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);
+ bit = req_char ^ oc;
+ if (is_powerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
+ found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
+ }
+ else
+ {
+ found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+ found_oc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);
+ }
}
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+ JUMPTO(SLJIT_JUMP, loop);
+
+ JUMPHERE(found);
+ if (found_oc)
+ JUMPHERE(found_oc);
}
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
-JUMPTO(SLJIT_JUMP, loop);
-JUMPHERE(found);
-if (foundoc)
- JUMPHERE(foundoc);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);
-JUMPHERE(alreadyfound);
+
+JUMPHERE(already_found);
JUMPHERE(toolong);
-return notfound;
+return not_found;
}
static void do_revertframes(compiler_common *common)
@@ -6170,7 +6522,7 @@ JUMPTO(SLJIT_JUMP, mainloop);
JUMPHERE(jump);
jump = CMP(SLJIT_NOT_ZERO /* SIG_LESS */, TMP2, 0, SLJIT_IMM, 0);
/* End of reverting values. */
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
JUMPHERE(jump);
OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
@@ -6219,9 +6571,11 @@ if (common->invalid_utf)
if (common->mode != PCRE2_JIT_COMPLETE)
{
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
move_back(common, NULL, TRUE);
check_start_used_ptr(common);
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);
}
}
@@ -6240,7 +6594,7 @@ else
/* Testing char type. */
#ifdef SUPPORT_UNICODE
-if (common->use_ucp)
+if (common->ucp)
{
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
@@ -6286,7 +6640,7 @@ peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2);
valid_utf = LABEL();
-if (common->use_ucp)
+if (common->ucp)
{
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
@@ -6326,7 +6680,7 @@ set_jumps(skipread_list, LABEL());
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
OP2(SLJIT_XOR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, TMP3, 0);
-sljit_emit_fast_return(compiler, TMP1, 0);
+OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
#ifdef SUPPORT_UNICODE
if (common->invalid_utf)
@@ -6338,12 +6692,12 @@ if (common->invalid_utf)
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1);
- sljit_emit_fast_return(compiler, TMP1, 0);
+ OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
set_jumps(invalid_utf2, LABEL());
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
OP1(SLJIT_MOV, TMP2, 0, TMP3, 0);
- sljit_emit_fast_return(compiler, TMP1, 0);
+ OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
}
#endif /* SUPPORT_UNICODE */
}
@@ -6633,7 +6987,7 @@ if (common->utf)
#endif
#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void check_hspace(compiler_common *common)
@@ -6672,7 +7026,7 @@ if (common->utf)
#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void check_vspace(compiler_common *common)
@@ -6700,7 +7054,7 @@ if (common->utf)
#endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
static void do_casefulcmp(compiler_common *common)
@@ -6780,7 +7134,7 @@ if (char1_reg == STR_END)
OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);
}
-sljit_emit_fast_return(compiler, TMP1, 0);
+OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
}
static void do_caselesscmp(compiler_common *common)
@@ -6878,7 +7232,7 @@ if (char2_reg == STACK_TOP)
}
OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-sljit_emit_fast_return(compiler, TMP1, 0);
+OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
}
static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc,
@@ -7189,7 +7543,13 @@ cc = ccbegin;
if ((cc[-1] & XCL_NOT) != 0)
read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR);
else
+ {
+#ifdef SUPPORT_UNICODE
+ read_char(common, min, max, (needstype || needsscript) ? backtracks : NULL, 0);
+#else /* !SUPPORT_UNICODE */
read_char(common, min, max, NULL, 0);
+#endif /* SUPPORT_UNICODE */
+ }
if ((cc[-1] & XCL_HASPROP) == 0)
{
@@ -7275,16 +7635,11 @@ if (needstype || needsscript)
/* Before anything else, we deal with scripts. */
if (needsscript)
{
-// PH hacking
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
-
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
-
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0);
+ OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
- // OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
ccbegin = cc;
@@ -7319,41 +7674,52 @@ if (needstype || needsscript)
}
cc = ccbegin;
- }
- if (needschar)
- OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ if (needstype)
+ {
+ /* TMP2 has already been shifted by 2 */
+ if (!needschar)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP2, 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+ }
+ else
+ {
+ OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP2, 0);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
- if (needstype)
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+ typereg = RETURN_ADDR;
+ }
+ }
+ else if (needschar)
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ }
+ else if (needstype)
{
+ OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
+
if (!needschar)
{
-// PH hacking
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP1, 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
-
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0);
-
-// OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
}
else
{
-// PH hacking
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
-
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
-
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
- OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
typereg = RETURN_ADDR;
}
}
+ else if (needschar)
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
}
#endif /* SUPPORT_UNICODE */
@@ -8728,16 +9094,13 @@ if (common->utf && *cc == OP_REFI)
CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);
-// PH hacking
OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
-
+ OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
-
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records));
@@ -9597,7 +9960,8 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
}
else
{
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ SLJIT_ASSERT(extrasize == 3);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
}
}
@@ -9929,7 +10293,7 @@ if (opcode == OP_CBRA || opcode == OP_SCBRA)
BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
matchingpath += IMM2_SIZE;
}
-else if (opcode == OP_ONCE || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
+else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
{
/* Other brackets simply allocate the next entry. */
private_data_ptr = PRIVATE_DATA(ccbegin);
@@ -10114,7 +10478,7 @@ else if (opcode == OP_CBRA || opcode == OP_SCBRA)
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
}
}
-else if (opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
+else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
{
/* Saving the previous value. */
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
@@ -10240,6 +10604,9 @@ compile_matchingpath(common, matchingpath, cc, backtrack);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
return NULL;
+if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+
if (opcode == OP_ONCE)
match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
@@ -10840,8 +11207,8 @@ backtrack_common *backtrack;
PCRE2_UCHAR opcode;
PCRE2_UCHAR type;
sljit_u32 max = 0, exact;
-BOOL fast_fail;
-sljit_s32 fast_str_ptr;
+sljit_s32 early_fail_ptr = PRIVATE_DATA(cc + 1);
+sljit_s32 early_fail_type;
BOOL charpos_enabled;
PCRE2_UCHAR charpos_char;
unsigned int charpos_othercasebit;
@@ -10855,21 +11222,27 @@ int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP
int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
int tmp_base, tmp_offset;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+BOOL use_tmp;
+#endif
PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL);
-fast_str_ptr = PRIVATE_DATA(cc + 1);
-fast_fail = TRUE;
+early_fail_type = (early_fail_ptr & 0x7);
+early_fail_ptr >>= 3;
-SLJIT_ASSERT(common->fast_forward_bc_ptr == NULL || fast_str_ptr == 0 || cc == common->fast_forward_bc_ptr);
+/* During recursion, these optimizations are disabled. */
+if (common->early_fail_start_ptr == 0)
+ {
+ early_fail_ptr = 0;
+ early_fail_type = type_skip;
+ }
-if (cc == common->fast_forward_bc_ptr)
- fast_fail = FALSE;
-else if (common->fast_fail_start_ptr == 0)
- fast_str_ptr = 0;
+SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0
+ || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr));
-SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || fast_str_ptr == 0
- || (fast_str_ptr >= common->fast_fail_start_ptr && fast_str_ptr <= common->fast_fail_end_ptr));
+if (early_fail_type == type_fail)
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr));
cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
@@ -10884,13 +11257,11 @@ else
tmp_offset = POSSESSIVE0;
}
-if (fast_fail && fast_str_ptr != 0)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr));
-
/* Handle fixed part first. */
if (exact > 1)
{
- SLJIT_ASSERT(fast_str_ptr == 0);
+ SLJIT_ASSERT(early_fail_ptr == 0);
+
if (common->mode == PCRE2_JIT_COMPLETE
#ifdef SUPPORT_UNICODE
&& !common->utf
@@ -10915,18 +11286,31 @@ if (exact > 1)
}
}
else if (exact == 1)
+ {
compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
+ if (early_fail_type == type_fail_range)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0);
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0));
+
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw), STR_PTR, 0);
+ }
+ }
+
switch(opcode)
{
case OP_STAR:
case OP_UPTO:
- SLJIT_ASSERT(fast_str_ptr == 0 || opcode == OP_STAR);
+ SLJIT_ASSERT(early_fail_ptr == 0 || opcode == OP_STAR);
if (type == OP_ANYNL || type == OP_EXTUNI)
{
SLJIT_ASSERT(private_data_ptr == 0);
- SLJIT_ASSERT(fast_str_ptr == 0);
+ SLJIT_ASSERT(early_fail_ptr == 0);
allocate_stack(common, 2);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
@@ -10945,7 +11329,7 @@ switch(opcode)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
}
- /* We cannot use TMP3 because of this allocate_stack. */
+ /* We cannot use TMP3 because of allocate_stack. */
allocate_stack(common, 1);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
JUMPTO(SLJIT_JUMP, label);
@@ -10971,8 +11355,8 @@ switch(opcode)
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
process_partial_match(common);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_END, 0);
+ if (early_fail_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0);
BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
break;
}
@@ -11002,8 +11386,8 @@ switch(opcode)
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ if (early_fail_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
break;
}
@@ -11030,7 +11414,7 @@ switch(opcode)
if (charpos_enabled)
{
charpos_char = end[1];
- /* Consumpe the OP_CHAR opcode. */
+ /* Consume the OP_CHAR opcode. */
end += 2;
#if PCRE2_CODE_UNIT_WIDTH == 8
SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);
@@ -11062,8 +11446,8 @@ switch(opcode)
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));
}
compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ if (early_fail_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
JUMPHERE(jump);
detect_partial_match(common, &backtrack->topbacktracks);
@@ -11076,6 +11460,7 @@ switch(opcode)
allocate_stack(common, 2);
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+
if (opcode == OP_UPTO)
{
OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
@@ -11085,53 +11470,55 @@ switch(opcode)
/* Search the last instance of charpos_char. */
label = LABEL();
compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ if (early_fail_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
detect_partial_match(common, &no_match);
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
if (charpos_othercasebit != 0)
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
+
if (opcode == OP_STAR)
{
CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
}
else
{
jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char);
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
JUMPHERE(jump);
- }
-
- if (opcode == OP_UPTO)
- {
OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
JUMPTO(SLJIT_NOT_ZERO, label);
}
- else
- JUMPTO(SLJIT_JUMP, label);
set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_ADD, STR_PTR, 0, base, offset0, SLJIT_IMM, IN_UCHARS(1));
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
}
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- else if (common->utf)
+ else
{
if (private_data_ptr == 0)
allocate_stack(common, 2);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR);
+ SLJIT_ASSERT(!use_tmp || tmp_base == TMP3);
+ if (common->utf)
+ OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0);
+#endif
if (opcode == OP_UPTO)
OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
detect_partial_match(common, &no_match);
label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf)
+ OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0);
+#endif
if (opcode == OP_UPTO)
{
@@ -11142,39 +11529,29 @@ switch(opcode)
detect_partial_match_to(common, label);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
- }
+ set_jumps(no_char1_match, LABEL());
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf)
+ {
+ set_jumps(no_match, LABEL());
+ if (use_tmp)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+ OP1(SLJIT_MOV, base, offset0, TMP3, 0);
+ }
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ }
+ else
#endif
- else
- {
- if (private_data_ptr == 0)
- allocate_stack(common, 2);
-
- OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
- if (opcode == OP_UPTO)
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
-
- detect_partial_match(common, &no_match);
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
- if (opcode == OP_UPTO)
{
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
}
- detect_partial_match_to(common, label);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-
- set_jumps(no_char1_match, LABEL());
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ if (early_fail_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
}
BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
@@ -11185,12 +11562,12 @@ switch(opcode)
allocate_stack(common, 1);
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ if (early_fail_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
break;
case OP_MINUPTO:
- SLJIT_ASSERT(fast_str_ptr == 0);
+ SLJIT_ASSERT(early_fail_ptr == 0);
if (private_data_ptr == 0)
allocate_stack(common, 2);
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
@@ -11200,7 +11577,7 @@ switch(opcode)
case OP_QUERY:
case OP_MINQUERY:
- SLJIT_ASSERT(fast_str_ptr == 0);
+ SLJIT_ASSERT(early_fail_ptr == 0);
if (private_data_ptr == 0)
allocate_stack(common, 1);
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
@@ -11221,8 +11598,8 @@ switch(opcode)
{
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
process_partial_match(common);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_END, 0);
+ if (early_fail_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_END, 0);
break;
}
@@ -11238,16 +11615,17 @@ switch(opcode)
set_jumps(no_match, LABEL());
OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
- if (fast_str_ptr != 0)
+ if (early_fail_ptr != 0)
{
- if (tmp_base == TMP3)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, TMP3, 0);
+ if (!HAS_VIRTUAL_REGISTERS && tmp_base == TMP3)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, TMP3, 0);
else
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
}
break;
}
#endif
+
detect_partial_match(common, &no_match);
label = LABEL();
compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
@@ -11257,12 +11635,12 @@ switch(opcode)
set_jumps(no_char1_match, LABEL());
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
set_jumps(no_match, LABEL());
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ if (early_fail_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
break;
case OP_POSUPTO:
- SLJIT_ASSERT(fast_str_ptr == 0);
+ SLJIT_ASSERT(early_fail_ptr == 0);
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
if (common->utf)
{
@@ -11298,9 +11676,6 @@ switch(opcode)
process_partial_match(common);
JUMPHERE(jump);
}
-
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
break;
}
@@ -11320,7 +11695,7 @@ switch(opcode)
break;
case OP_POSQUERY:
- SLJIT_ASSERT(fast_str_ptr == 0);
+ SLJIT_ASSERT(early_fail_ptr == 0);
OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
@@ -11695,6 +12070,8 @@ while (cc < ccend)
count_match(common);
break;
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_BRA:
@@ -12232,6 +12609,7 @@ else if (has_alternatives)
SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_put_label);
sljit_set_put_label(CURRENT_AS(bracket_backtrack)->u.matching_put_label, LABEL());
+ sljit_emit_op0(compiler, SLJIT_ENDBR);
}
else
next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
@@ -12298,6 +12676,9 @@ if (has_alternatives)
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
return;
+ if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
+
if (opcode == OP_SCRIPT_RUN)
match_script_run_common(common, private_data_ptr, current);
}
@@ -12379,7 +12760,10 @@ if (has_alternatives)
}
}
else
+ {
sljit_set_put_label(put_label, LABEL());
+ sljit_emit_op0(compiler, SLJIT_ENDBR);
+ }
}
COMPILE_BACKTRACKINGPATH(current->top);
@@ -12427,7 +12811,7 @@ if (offset != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
}
}
-else if (opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
+else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND)
{
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
free_stack(common, 1);
@@ -12775,6 +13159,8 @@ while (current)
compile_assert_backtrackingpath(common, current);
break;
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_BRA:
@@ -12872,7 +13258,7 @@ jump_list *match = NULL;
struct sljit_jump *next_alt = NULL;
struct sljit_jump *accept_exit = NULL;
struct sljit_label *quit;
-struct sljit_put_label *put_label;
+struct sljit_put_label *put_label = NULL;
/* Recurse captures then. */
common->then_trap = NULL;
@@ -12969,6 +13355,7 @@ while (1)
{
sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);
sljit_set_put_label(put_label, LABEL());
+ sljit_emit_op0(compiler, SLJIT_ENDBR);
}
else
next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
@@ -12977,7 +13364,10 @@ while (1)
free_stack(common, has_accept ? 2 : 1);
}
else if (alt_max > 3)
+ {
sljit_set_put_label(put_label, LABEL());
+ sljit_emit_op0(compiler, SLJIT_ENDBR);
+ }
else
{
JUMPHERE(next_alt);
@@ -13011,7 +13401,7 @@ copy_recurse_data(common, ccbegin, ccend, recurse_copy_private_to_global, local_
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));
free_stack(common, private_data_size + local_size);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-sljit_emit_fast_return(compiler, TMP2, 0);
+OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);
if (common->quit != NULL)
{
@@ -13036,7 +13426,7 @@ if (has_accept)
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));
free_stack(common, private_data_size + local_size);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
- sljit_emit_fast_return(compiler, TMP2, 0);
+ OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);
}
if (common->accept != NULL)
@@ -13060,7 +13450,7 @@ copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, priva
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), STACK(local_size - 1));
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
-sljit_emit_fast_return(compiler, TMP2, 0);
+OP_SRC(SLJIT_FAST_RETURN, TMP2, 0);
}
#undef COMPILE_BACKTRACKINGPATH
@@ -13092,9 +13482,9 @@ struct sljit_label *reset_match_label;
struct sljit_label *quit_label;
struct sljit_jump *jump;
struct sljit_jump *minlength_check_failed = NULL;
-struct sljit_jump *reqbyte_notfound = NULL;
struct sljit_jump *empty_match = NULL;
struct sljit_jump *end_anchor_failed = NULL;
+jump_list *reqcu_not_found = NULL;
SLJIT_ASSERT(tables);
@@ -13122,8 +13512,8 @@ common->read_only_data_head = NULL;
common->fcc = tables + fcc_offset;
common->lcc = (sljit_sw)(tables + lcc_offset);
common->mode = mode;
-common->might_be_empty = re->minlength == 0;
-common->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY) != 0;
+common->might_be_empty = (re->minlength == 0) || (re->flags & PCRE2_MATCH_EMPTY);
+common->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY);
common->nltype = NLTYPE_FIXED;
switch(re->newline_convention)
{
@@ -13160,7 +13550,7 @@ common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0;
#ifdef SUPPORT_UNICODE
/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
common->utf = (re->overall_options & PCRE2_UTF) != 0;
-common->use_ucp = (re->overall_options & PCRE2_UCP) != 0;
+common->ucp = (re->overall_options & PCRE2_UCP) != 0;
if (common->utf)
{
if (common->nltype == NLTYPE_ANY)
@@ -13272,13 +13662,10 @@ memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32));
private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
set_private_data_ptrs(common, &private_data_size, ccend);
-if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
- {
- if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back)
- detect_fast_fail(common, common->start, &private_data_size, 4);
- }
+if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back)
+ detect_early_fail(common, common->start, &private_data_size, 0, 0);
-SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr);
+SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr);
if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
{
@@ -13294,7 +13681,7 @@ if (common->has_then)
set_then_offsets(common, common->start, NULL);
}
-compiler = sljit_create_compiler(allocator_data);
+compiler = sljit_create_compiler(allocator_data, NULL);
if (!compiler)
{
SLJIT_FREE(common->optimized_cbracket, allocator_data);
@@ -13322,8 +13709,8 @@ OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_sta
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
-if (common->fast_fail_start_ptr < common->fast_fail_end_ptr)
- reset_fast_fail(common);
+if (common->early_fail_start_ptr < common->early_fail_end_ptr)
+ reset_early_fail(common);
if (mode == PCRE2_JIT_PARTIAL_SOFT)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
@@ -13360,7 +13747,7 @@ if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PC
minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0);
}
if (common->req_char_ptr != 0)
- reqbyte_notfound = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0);
+ reqcu_not_found = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0);
/* Store the current STR_PTR in OVECTOR(0). */
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
@@ -13369,7 +13756,7 @@ OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH);
if (common->capture_last_ptr != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0);
if (common->fast_forward_bc_ptr != NULL)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3, STR_PTR, 0);
if (common->start_ptr != OVECTOR(0))
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0);
@@ -13416,6 +13803,8 @@ if (common->abort != NULL)
set_jumps(common->abort, common->abort_label);
if (minlength_check_failed != NULL)
SET_LABEL(minlength_check_failed, common->abort_label);
+
+sljit_emit_op0(compiler, SLJIT_SKIP_FRAMES_BEFORE_RETURN);
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
if (common->failed_match != NULL)
@@ -13468,7 +13857,7 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0)
}
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP),
- (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1)) : common->start_ptr);
+ (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3) : common->start_ptr);
if ((re->overall_options & PCRE2_ANCHORED) == 0)
{
@@ -13493,8 +13882,8 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0)
}
/* No more remaining characters. */
-if (reqbyte_notfound != NULL)
- JUMPHERE(reqbyte_notfound);
+if (reqcu_not_found != NULL)
+ set_jumps(reqcu_not_found, LABEL());
if (mode == PCRE2_JIT_PARTIAL_SOFT)
CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
@@ -13519,8 +13908,8 @@ if (common->might_be_empty)
}
common->fast_forward_bc_ptr = NULL;
-common->fast_fail_start_ptr = 0;
-common->fast_fail_end_ptr = 0;
+common->early_fail_start_ptr = 0;
+common->early_fail_end_ptr = 0;
common->currententry = common->entries;
common->local_quit_available = TRUE;
quit_label = common->quit_label;
@@ -13563,7 +13952,7 @@ OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
-sljit_emit_fast_return(compiler, TMP1, 0);
+OP_SRC(SLJIT_FAST_RETURN, TMP1, 0);
/* Allocation failed. */
JUMPHERE(jump);
@@ -13694,7 +14083,7 @@ else
{
/* This case is highly unlikely since we just recently
freed a lot of memory. Not impossible though. */
- sljit_free_code(executable_func);
+ sljit_free_code(executable_func, NULL);
PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
return PCRE2_ERROR_NOMEMORY;
}
@@ -13742,11 +14131,6 @@ pcre2_jit_compile(pcre2_code *code, uint32_t options)
{
pcre2_real_code *re = (pcre2_real_code *)code;
-#ifdef SUPPORT_JIT
-executable_functions *functions = (executable_functions *)re->executable_jit;
-static int executable_allocator_is_working = 0;
-#endif
-
if (code == NULL)
return PCRE2_ERROR_NULL;
@@ -13779,6 +14163,11 @@ actions are needed:
avoid compiler warnings.
*/
+#ifdef SUPPORT_JIT
+executable_functions *functions = (executable_functions *)re->executable_jit;
+static int executable_allocator_is_working = 0;
+#endif
+
if ((options & PCRE2_JIT_INVALID_UTF) != 0)
{
if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) == 0)
@@ -13808,13 +14197,13 @@ if (executable_allocator_is_working == 0)
/* Checks whether the executable allocator is working. This check
might run multiple times in multi-threaded environments, but the
result should not be affected by it. */
- void *ptr = SLJIT_MALLOC_EXEC(32);
+ void *ptr = SLJIT_MALLOC_EXEC(32, NULL);
executable_allocator_is_working = -1;
if (ptr != NULL)
{
- SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr));
+ SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr), NULL);
executable_allocator_is_working = 1;
}
}
diff --git a/thirdparty/pcre2/src/pcre2_jit_misc.c b/thirdparty/pcre2/src/pcre2_jit_misc.c
index efdb05580f..ec924e0f9b 100644
--- a/thirdparty/pcre2/src/pcre2_jit_misc.c
+++ b/thirdparty/pcre2/src/pcre2_jit_misc.c
@@ -89,7 +89,7 @@ int i;
for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
{
if (functions->executable_funcs[i] != NULL)
- sljit_free_code(functions->executable_funcs[i]);
+ sljit_free_code(functions->executable_funcs[i], NULL);
PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data);
}
@@ -145,6 +145,11 @@ maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);
if (jit_stack == NULL) return NULL;
jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl);
+if (jit_stack->stack == NULL)
+ {
+ jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);
+ return NULL;
+ }
return jit_stack;
#endif
diff --git a/thirdparty/pcre2/src/pcre2_jit_neon_inc.h b/thirdparty/pcre2/src/pcre2_jit_neon_inc.h
index 55b1f32ac9..150da29eba 100644
--- a/thirdparty/pcre2/src/pcre2_jit_neon_inc.h
+++ b/thirdparty/pcre2/src/pcre2_jit_neon_inc.h
@@ -87,6 +87,10 @@ static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_u
{
quad_word qw;
int_char ic;
+
+SLJIT_UNUSED_ARG(offs1);
+SLJIT_UNUSED_ARG(offs2);
+
ic.x = chars;
#if defined(FFCS)
@@ -117,11 +121,16 @@ PCRE2_UCHAR char2a = ic.c.c3;
# ifdef FFCPS_CHAR1A2A
cmp1a = VDUPQ(char1a);
cmp2a = VDUPQ(char2a);
+cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
+cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
# else
PCRE2_UCHAR char1b = ic.c.c2;
PCRE2_UCHAR char2b = ic.c.c4;
if (char1a == char1b)
+ {
cmp1a = VDUPQ(char1a);
+ cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
+ }
else
{
sljit_u32 bit1 = char1a ^ char1b;
@@ -140,7 +149,10 @@ else
}
if (char2a == char2b)
+ {
cmp2a = VDUPQ(char2a);
+ cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
+ }
else
{
sljit_u32 bit2 = char2a ^ char2b;
@@ -208,8 +220,16 @@ if (p1 < str_ptr)
else
data2 = shift_left_n_lanes(data, offs1 - offs2);
-data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
-data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
+if (compare1_type == compare_match1)
+ data = VCEQQ(data, cmp1a);
+else
+ data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
+
+if (compare2_type == compare_match1)
+ data2 = VCEQQ(data2, cmp2a);
+else
+ data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
+
vect_t eq = VANDQ(data, data2);
#endif
@@ -275,8 +295,14 @@ while (str_ptr < str_end)
data = VCEQQ(data, cmp1a);
data2 = VCEQQ(data2, cmp2a);
# else
- data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
- data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
+ if (compare1_type == compare_match1)
+ data = VCEQQ(data, cmp1a);
+ else
+ data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
+ if (compare2_type == compare_match1)
+ data2 = VCEQQ(data2, cmp2a);
+ else
+ data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
# endif
eq = VANDQ(data, data2);
diff --git a/thirdparty/pcre2/src/pcre2_jit_simd_inc.h b/thirdparty/pcre2/src/pcre2_jit_simd_inc.h
index f7d56b29f8..5673d338c0 100644
--- a/thirdparty/pcre2/src/pcre2_jit_simd_inc.h
+++ b/thirdparty/pcre2/src/pcre2_jit_simd_inc.h
@@ -344,6 +344,136 @@ if (common->utf && offset > 0)
#endif
}
+#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
+
+static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *quit;
+jump_list *not_found = NULL;
+sse2_compare_type compare_type = sse2_compare_match1;
+sljit_u8 instruction[8];
+sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
+sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
+sljit_s32 data_ind = 0;
+sljit_s32 tmp_ind = 1;
+sljit_s32 cmp1_ind = 2;
+sljit_s32 cmp2_ind = 3;
+sljit_u32 bit = 0;
+int i;
+
+if (char1 != char2)
+ {
+ bit = char1 ^ char2;
+ compare_type = sse2_compare_match1i;
+
+ if (!is_powerof2(bit))
+ {
+ bit = 0;
+ compare_type = sse2_compare_match2;
+ }
+ }
+
+add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
+OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);
+OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
+
+/* First part (unaligned start) */
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
+
+SLJIT_ASSERT(tmp1_reg_ind < 8);
+
+/* MOVD xmm, r/m32 */
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+instruction[2] = 0x6e;
+instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (char1 != char2)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
+
+ /* MOVD xmm, r/m32 */
+ instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);
+
+/* PSHUFD xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x70;
+instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind;
+instruction[4] = 0;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+if (char1 != char2)
+ {
+ /* PSHUFD xmm1, xmm2/m128, imm8 */
+ instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind;
+ sljit_emit_op_custom(compiler, instruction, 5);
+ }
+
+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
+
+load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
+for (i = 0; i < 4; i++)
+ fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
+
+/* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
+
+quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
+
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+/* Second part (aligned) */
+start = LABEL();
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
+
+add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
+for (i = 0; i < 4; i++)
+ fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
+
+/* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
+
+JUMPHERE(quit);
+
+/* BSF r32, r/m32 */
+instruction[0] = 0x0f;
+instruction[1] = 0xbc;
+instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;
+sljit_emit_op_custom(compiler, instruction, 3);
+
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0);
+add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
+
+OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+return not_found;
+}
+
#ifndef _WIN64
static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void)
diff --git a/thirdparty/pcre2/src/pcre2_maketables.c b/thirdparty/pcre2/src/pcre2_maketables.c
index 8c93b4b573..56d2494023 100644
--- a/thirdparty/pcre2/src/pcre2_maketables.c
+++ b/thirdparty/pcre2/src/pcre2_maketables.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -41,10 +41,11 @@ POSSIBILITY OF SUCH DAMAGE.
/* This module contains the external function pcre2_maketables(), which builds
character tables for PCRE2 in the current locale. The file is compiled on its
-own as part of the PCRE2 library. However, it is also included in the
-compilation of dftables.c, in which case the macro DFTABLES is defined. */
+own as part of the PCRE2 library. It is also included in the compilation of
+pcre2_dftables.c as a freestanding program, in which case the macro
+PCRE2_DFTABLES is defined. */
-#ifndef DFTABLES
+#ifndef PCRE2_DFTABLES /* Compiling the library */
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
@@ -61,28 +62,29 @@ compilation of dftables.c, in which case the macro DFTABLES is defined. */
a pointer to them. They are build using the ctype functions, and consequently
their contents will depend upon the current locale setting. When compiled as
part of the library, the store is obtained via a general context malloc, if
-supplied, but when DFTABLES is defined (when compiling the dftables auxiliary
-program) malloc() is used, and the function has a different name so as not to
-clash with the prototype in pcre2.h.
+supplied, but when PCRE2_DFTABLES is defined (when compiling the pcre2_dftables
+freestanding auxiliary program) malloc() is used, and the function has a
+different name so as not to clash with the prototype in pcre2.h.
-Arguments: none when DFTABLES is defined
- else a PCRE2 general context or NULL
+Arguments: none when PCRE2_DFTABLES is defined
+ else a PCRE2 general context or NULL
Returns: pointer to the contiguous block of data
+ else NULL if memory allocation failed
*/
-#ifdef DFTABLES /* Included in freestanding dftables.c program */
+#ifdef PCRE2_DFTABLES /* Included in freestanding pcre2_dftables program */
static const uint8_t *maketables(void)
{
-uint8_t *yield = (uint8_t *)malloc(tables_length);
+uint8_t *yield = (uint8_t *)malloc(TABLES_LENGTH);
-#else /* Not DFTABLES, compiling the library */
+#else /* Not PCRE2_DFTABLES, that is, compiling the library */
PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION
pcre2_maketables(pcre2_general_context *gcontext)
{
uint8_t *yield = (uint8_t *)((gcontext != NULL)?
- gcontext->memctl.malloc(tables_length, gcontext->memctl.memory_data) :
- malloc(tables_length));
-#endif /* DFTABLES */
+ gcontext->memctl.malloc(TABLES_LENGTH, gcontext->memctl.memory_data) :
+ malloc(TABLES_LENGTH));
+#endif /* PCRE2_DFTABLES */
int i;
uint8_t *p;
@@ -103,8 +105,8 @@ exclusive ones - in some locales things may be different.
Note that the table for "space" includes everything "isspace" gives, including
VT in the default locale. This makes it work for the POSIX class [:space:].
-From release 8.34 is is also correct for Perl space, because Perl added VT at
-release 5.18.
+From PCRE1 release 8.34 and for all PCRE2 releases it is also correct for Perl
+space, because Perl added VT at release 5.18.
Note also that it is possible for a character to be alnum or alpha without
being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the
@@ -114,24 +116,24 @@ test for alnum specially. */
memset(p, 0, cbit_length);
for (i = 0; i < 256; i++)
{
- if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7);
- if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7);
- if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7);
- if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7);
- if (i == '_') p[cbit_word + i/8] |= 1u << (i&7);
- if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7);
- if (isxdigit(i))p[cbit_xdigit + i/8] |= 1u << (i&7);
- if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7);
- if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7);
- if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7);
- if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7);
+ if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7);
+ if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7);
+ if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7);
+ if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7);
+ if (i == '_') p[cbit_word + i/8] |= 1u << (i&7);
+ if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7);
+ if (isxdigit(i)) p[cbit_xdigit + i/8] |= 1u << (i&7);
+ if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7);
+ if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7);
+ if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7);
+ if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7);
}
p += cbit_length;
/* Finally, the character type table. In this, we used to exclude VT from the
white space chars, because Perl didn't recognize it as such for \s and for
-comments within regexes. However, Perl changed at release 5.18, so PCRE changed
-at release 8.34. */
+comments within regexes. However, Perl changed at release 5.18, so PCRE1
+changed at release 8.34 and it's always been this way for PCRE2. */
for (i = 0; i < 256; i++)
{
@@ -147,7 +149,7 @@ for (i = 0; i < 256; i++)
return yield;
}
-#ifndef DFTABLES
+#ifndef PCRE2_DFTABLES /* Compiling the library */
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables)
{
diff --git a/thirdparty/pcre2/src/pcre2_match.c b/thirdparty/pcre2/src/pcre2_match.c
index 48e7b9dbb2..e3f78c2ca3 100644
--- a/thirdparty/pcre2/src/pcre2_match.c
+++ b/thirdparty/pcre2/src/pcre2_match.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2015-2019 University of Cambridge
+ New API code Copyright (c) 2015-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -381,8 +381,12 @@ length = Fovector[offset+1] - Fovector[offset];
if (caseless)
{
#if defined SUPPORT_UNICODE
- if ((mb->poptions & PCRE2_UTF) != 0)
+ BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
+
+ if (utf || (mb->poptions & PCRE2_UCP) != 0)
{
+ PCRE2_SPTR endptr = p + length;
+
/* Match characters up to the end of the reference. NOTE: the number of
code units matched may differ, because in UTF-8 there are some characters
whose upper and lower case codes have different numbers of bytes. For
@@ -390,16 +394,25 @@ if (caseless)
bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
sequence of two of the latter. It is important, therefore, to check the
length along the reference, not along the subject (earlier code did this
- wrong). */
+ wrong). UCP without uses Unicode properties but without UTF encoding. */
- PCRE2_SPTR endptr = p + length;
while (p < endptr)
{
uint32_t c, d;
const ucd_record *ur;
if (eptr >= mb->end_subject) return 1; /* Partial match */
- GETCHARINC(c, eptr);
- GETCHARINC(d, p);
+
+ if (utf)
+ {
+ GETCHARINC(c, eptr);
+ GETCHARINC(d, p);
+ }
+ else
+ {
+ c = *eptr++;
+ d = *p++;
+ }
+
ur = GET_UCD(d);
if (c != d && c != (uint32_t)((int)d + ur->other_case))
{
@@ -415,7 +428,7 @@ if (caseless)
else
#endif
- /* Not in UTF mode */
+ /* Not in UTF or UCP mode */
{
for (; length > 0; length--)
{
@@ -432,7 +445,8 @@ if (caseless)
}
/* In the caseful case, we can just compare the code units, whether or not we
-are in UTF mode. When partial matching, we have to do this unit-by-unit. */
+are in UTF and/or UCP mode. When partial matching, we have to do this unit by
+unit. */
else
{
@@ -574,8 +588,8 @@ match(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, PCRE2_SIZE *ovector,
heapframe *F; /* Current frame pointer */
heapframe *N = NULL; /* Temporary frame pointers */
heapframe *P = NULL;
-heapframe *assert_accept_frame; /* For passing back the frame with captures */
-PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */
+heapframe *assert_accept_frame = NULL; /* For passing back a frame with captures */
+PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */
/* Local variables that do not need to be preserved over calls to RRMATCH(). */
@@ -598,12 +612,13 @@ BOOL condition; /* Used in conditional groups */
BOOL cur_is_word; /* Used in "word" tests */
BOOL prev_is_word; /* Used in "word" tests */
-/* UTF flag */
+/* UTF and UCP flags */
#ifdef SUPPORT_UNICODE
BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
+BOOL ucp = (mb->poptions & PCRE2_UCP) != 0;
#else
-BOOL utf = FALSE;
+BOOL utf = FALSE; /* Required for convenience even when no Unicode support */
#endif
/* This is the length of the last part of a backtracking frame that must be
@@ -928,6 +943,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
}
else
#endif
+
/* Not UTF mode */
{
if (mb->end_subject - Feptr < 1)
@@ -987,10 +1003,30 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
if (dc != fc && dc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
}
}
+
+ /* If UCP is set without UTF we must do the same as above, but with one
+ character per code unit. */
+
+ else if (ucp)
+ {
+ uint32_t cc = UCHAR21(Feptr);
+ fc = Fecode[1];
+ if (fc < 128)
+ {
+ if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ {
+ if (cc != fc && cc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
+ }
+ Feptr++;
+ Fecode += 2;
+ }
+
else
#endif /* SUPPORT_UNICODE */
- /* Not UTF mode; use the table for characters < 256. */
+ /* Not UTF or UCP mode; use the table for characters < 256. */
{
if (TABLE_GET(Fecode[1], mb->lcc, Fecode[1])
!= TABLE_GET(*Feptr, mb->lcc, *Feptr)) RRETURN(MATCH_NOMATCH);
@@ -1010,6 +1046,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
+
#ifdef SUPPORT_UNICODE
if (utf)
{
@@ -1026,15 +1063,42 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
if (ch > 127)
ch = UCD_OTHERCASE(ch);
else
- ch = TABLE_GET(ch, mb->fcc, ch);
+ ch = (mb->fcc)[ch];
+ if (ch == fc) RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ /* UCP without UTF is as above, but with one character per code unit. */
+
+ else if (ucp)
+ {
+ uint32_t ch;
+ fc = UCHAR21INC(Feptr);
+ ch = Fecode[1];
+ Fecode += 2;
+
+ if (ch == fc)
+ {
+ RRETURN(MATCH_NOMATCH); /* Caseful match */
+ }
+ else if (Fop == OP_NOTI) /* If caseless */
+ {
+ if (ch > 127)
+ ch = UCD_OTHERCASE(ch);
+ else
+ ch = (mb->fcc)[ch];
if (ch == fc) RRETURN(MATCH_NOMATCH);
}
}
+
else
#endif /* SUPPORT_UNICODE */
+
+ /* Neither UTF nor UCP is set */
+
{
uint32_t ch = Fecode[1];
- fc = *Feptr++;
+ fc = UCHAR21INC(Feptr);
if (ch == fc || (Fop == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == fc))
RRETURN(MATCH_NOMATCH);
Fecode += 2;
@@ -1244,7 +1308,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
#endif /* SUPPORT_UNICODE */
/* When not in UTF mode, load a single-code-unit character. Then proceed as
- above. */
+ above, using Unicode casing if either UTF or UCP is set. */
Lc = *Fecode++;
@@ -1253,11 +1317,15 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
if (Fop >= OP_STARI)
{
#if PCRE2_CODE_UNIT_WIDTH == 8
- /* Lc must be < 128 in UTF-8 mode. */
+#ifdef SUPPORT_UNICODE
+ if (ucp && !utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);
+ else
+#endif /* SUPPORT_UNICODE */
+ /* Lc will be < 128 in UTF-8 mode. */
Loc = mb->fcc[Lc];
#else /* 16-bit & 32-bit */
#ifdef SUPPORT_UNICODE
- if (utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);
+ if ((utf || ucp) && Lc > 127) Loc = UCD_OTHERCASE(Lc);
else
#endif /* SUPPORT_UNICODE */
Loc = TABLE_GET(Lc, mb->fcc, Lc);
@@ -1490,7 +1558,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
if (Fop >= OP_NOTSTARI) /* Caseless */
{
#ifdef SUPPORT_UNICODE
- if (utf && Lc > 127)
+ if ((utf || ucp) && Lc > 127)
Loc = UCD_OTHERCASE(Lc);
else
#endif /* SUPPORT_UNICODE */
@@ -6045,11 +6113,10 @@ BOOL firstline;
BOOL has_first_cu = FALSE;
BOOL has_req_cu = FALSE;
BOOL startline;
-BOOL utf;
#if PCRE2_CODE_UNIT_WIDTH == 8
-BOOL memchr_not_found_first_cu = FALSE;
-BOOL memchr_not_found_first_cu2 = FALSE;
+BOOL memchr_not_found_first_cu;
+BOOL memchr_not_found_first_cu2;
#endif
PCRE2_UCHAR first_cu = 0;
@@ -6069,13 +6136,19 @@ PCRE2_SPTR match_partial;
BOOL use_jit;
#endif
+/* This flag is needed even when Unicode is not supported for convenience
+(it is used by the IS_NEWLINE macro). */
+
+BOOL utf = FALSE;
+
#ifdef SUPPORT_UNICODE
+BOOL ucp = FALSE;
BOOL allow_invalid;
uint32_t fragment_options = 0;
#ifdef SUPPORT_JIT
BOOL jit_checked_utf = FALSE;
#endif
-#endif
+#endif /* SUPPORT_UNICODE */
PCRE2_SIZE frame_size;
@@ -6091,7 +6164,8 @@ proves to be too small, it is replaced by a larger one on the heap. To get a
vector of the size required that is aligned for pointers, allocate it as a
vector of pointers. */
-PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)];
+PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)]
+ PCRE2_KEEP_UNINITIALIZED;
mb->stack_frames = (heapframe *)stack_frames_vector;
/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated
@@ -6147,12 +6221,13 @@ use_jit = (re->executable_jit != NULL &&
(options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0);
#endif
-/* Initialize UTF parameters. */
+/* Initialize UTF/UCP parameters. */
-utf = (re->overall_options & PCRE2_UTF) != 0;
#ifdef SUPPORT_UNICODE
+utf = (re->overall_options & PCRE2_UTF) != 0;
allow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0;
-#endif
+ucp = (re->overall_options & PCRE2_UCP) != 0;
+#endif /* SUPPORT_UNICODE */
/* Convert the partial matching flags into an integer. */
@@ -6589,9 +6664,13 @@ if ((re->flags & PCRE2_FIRSTSET) != 0)
if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
{
first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu);
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (first_cu > 127 && ucp && !utf) first_cu2 = UCD_OTHERCASE(first_cu);
+#else
+ if (first_cu > 127 && (utf || ucp)) first_cu2 = UCD_OTHERCASE(first_cu);
#endif
+#endif /* SUPPORT_UNICODE */
}
}
else
@@ -6607,9 +6686,13 @@ if ((re->flags & PCRE2_LASTSET) != 0)
if ((re->flags & PCRE2_LASTCASELESS) != 0)
{
req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu);
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu);
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (req_cu > 127 && ucp && !utf) req_cu2 = UCD_OTHERCASE(req_cu);
+#else
+ if (req_cu > 127 && (utf || ucp)) req_cu2 = UCD_OTHERCASE(req_cu);
#endif
+#endif /* SUPPORT_UNICODE */
}
}
@@ -6626,6 +6709,11 @@ FRAGMENT_RESTART:
start_partial = match_partial = NULL;
mb->hitend = FALSE;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+memchr_not_found_first_cu = FALSE;
+memchr_not_found_first_cu2 = FALSE;
+#endif
+
for(;;)
{
PCRE2_SPTR new_start_match;
@@ -6756,15 +6844,16 @@ for(;;)
#endif
}
- /* If we can't find the required code unit, having reached the true end
- of the subject, break the bumpalong loop, to force a match failure,
- except when doing partial matching, when we let the next cycle run at
- the end of the subject. To see why, consider the pattern /(?<=abc)def/,
- which partially matches "abc", even though the string does not contain
- the starting character "d". If we have not reached the true end of the
- subject (PCRE2_FIRSTLINE caused end_subject to be temporarily modified)
- we also let the cycle run, because the matching string is legitimately
- allowed to start with the first code unit of a newline. */
+ /* If we can't find the required first code unit, having reached the
+ true end of the subject, break the bumpalong loop, to force a match
+ failure, except when doing partial matching, when we let the next cycle
+ run at the end of the subject. To see why, consider the pattern
+ /(?<=abc)def/, which partially matches "abc", even though the string
+ does not contain the starting character "d". If we have not reached the
+ true end of the subject (PCRE2_FIRSTLINE caused end_subject to be
+ temporarily modified) we also let the cycle run, because the matching
+ string is legitimately allowed to start with the first code unit of a
+ newline. */
if (mb->partial == 0 && start_match >= mb->end_subject)
{
@@ -7103,6 +7192,7 @@ if (utf && end_subject != true_end_subject &&
starting code units in 8-bit and 16-bit modes. */
start_match = end_subject + 1;
+
#if PCRE2_CODE_UNIT_WIDTH != 32
while (start_match < true_end_subject && NOT_FIRSTCU(*start_match))
start_match++;
diff --git a/thirdparty/pcre2/src/pcre2_serialize.c b/thirdparty/pcre2/src/pcre2_serialize.c
index cec1a035d1..ba17a26d2e 100644
--- a/thirdparty/pcre2/src/pcre2_serialize.c
+++ b/thirdparty/pcre2/src/pcre2_serialize.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2018 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -90,7 +90,7 @@ if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL)
if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;
/* Compute total size. */
-total_size = sizeof(pcre2_serialized_data) + tables_length;
+total_size = sizeof(pcre2_serialized_data) + TABLES_LENGTH;
tables = NULL;
for (i = 0; i < number_of_codes; i++)
@@ -121,8 +121,8 @@ data->number_of_codes = number_of_codes;
/* Copy all compiled code data. */
dst_bytes = bytes + sizeof(pcre2_serialized_data);
-memcpy(dst_bytes, tables, tables_length);
-dst_bytes += tables_length;
+memcpy(dst_bytes, tables, TABLES_LENGTH);
+dst_bytes += TABLES_LENGTH;
for (i = 0; i < number_of_codes; i++)
{
@@ -189,12 +189,12 @@ src_bytes = bytes + sizeof(pcre2_serialized_data);
/* Decode tables. The reference count for the tables is stored immediately
following them. */
-tables = memctl->malloc(tables_length + sizeof(PCRE2_SIZE), memctl->memory_data);
+tables = memctl->malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE), memctl->memory_data);
if (tables == NULL) return PCRE2_ERROR_NOMEMORY;
-memcpy(tables, src_bytes, tables_length);
-*(PCRE2_SIZE *)(tables + tables_length) = number_of_codes;
-src_bytes += tables_length;
+memcpy(tables, src_bytes, TABLES_LENGTH);
+*(PCRE2_SIZE *)(tables + TABLES_LENGTH) = number_of_codes;
+src_bytes += TABLES_LENGTH;
/* Decode the byte stream. We must not try to read the size from the compiled
code block in the stream, because it might be unaligned, which causes errors on
diff --git a/thirdparty/pcre2/src/pcre2_study.c b/thirdparty/pcre2/src/pcre2_study.c
index 2883868618..9bbb37570f 100644
--- a/thirdparty/pcre2/src/pcre2_study.c
+++ b/thirdparty/pcre2/src/pcre2_study.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -58,7 +58,7 @@ collecting data (e.g. minimum matching length). */
/* Returns from set_start_bits() */
-enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN };
+enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN, SSB_TOODEEP };
/*************************************************
@@ -772,15 +772,19 @@ Arguments:
p points to the first code unit of the character
caseless TRUE if caseless
utf TRUE for UTF mode
+ ucp TRUE for UCP mode
Returns: pointer after the character
*/
static PCRE2_SPTR
-set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf)
+set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf,
+ BOOL ucp)
{
uint32_t c = *p++; /* First code unit */
-(void)utf; /* Stop compiler warning when UTF not supported */
+
+(void)utf; /* Stop compiler warnings when UTF not supported */
+(void)ucp;
/* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for
0xff. */
@@ -810,22 +814,26 @@ if (utf)
if (caseless)
{
#ifdef SUPPORT_UNICODE
- if (utf)
+ if (utf || ucp)
{
-#if PCRE2_CODE_UNIT_WIDTH == 8
- PCRE2_UCHAR buff[6];
c = UCD_OTHERCASE(c);
- (void)PRIV(ord2utf)(c, buff);
- SET_BIT(buff[0]);
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (utf)
+ {
+ PCRE2_UCHAR buff[6];
+ (void)PRIV(ord2utf)(c, buff);
+ SET_BIT(buff[0]);
+ }
+ else if (c < 256) SET_BIT(c);
#else /* 16-bit or 32-bit mode */
- c = UCD_OTHERCASE(c);
if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
#endif
}
+
else
#endif /* SUPPORT_UNICODE */
- /* Not UTF */
+ /* Not UTF or UCP */
if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]);
}
@@ -924,19 +932,26 @@ The SSB_CONTINUE return is useful for parenthesized groups in patterns such as
must continue at the outer level to find at least one mandatory code unit. At
the outermost level, this function fails unless the result is SSB_DONE.
+We restrict recursion (for nested groups) to 1000 to avoid stack overflow
+issues.
+
Arguments:
re points to the compiled regex block
code points to an expression
utf TRUE if in UTF mode
+ ucp TRUE if in UCP mode
+ depthptr pointer to recurse depth
Returns: SSB_FAIL => Failed to find any starting code units
SSB_DONE => Found mandatory starting code units
SSB_CONTINUE => Found optional starting code units
SSB_UNKNOWN => Hit an unrecognized opcode
+ SSB_TOODEEP => Recursion is too deep
*/
static int
-set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf)
+set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf, BOOL ucp,
+ int *depthptr)
{
uint32_t c;
int yield = SSB_DONE;
@@ -947,6 +962,9 @@ int table_limit = utf? 16:32;
int table_limit = 32;
#endif
+*depthptr += 1;
+if (*depthptr > 1000) return SSB_TOODEEP;
+
do
{
BOOL try_next = TRUE;
@@ -1103,13 +1121,17 @@ do
case OP_SCRIPT_RUN:
case OP_ASSERT:
case OP_ASSERT_NA:
- rc = set_start_bits(re, tcode, utf);
- if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
- if (rc == SSB_DONE) try_next = FALSE; else
+ rc = set_start_bits(re, tcode, utf, ucp, depthptr);
+ if (rc == SSB_DONE)
+ {
+ try_next = FALSE;
+ }
+ else if (rc == SSB_CONTINUE)
{
do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
tcode += 1 + LINK_SIZE;
}
+ else return rc; /* FAIL, UNKNOWN, or TOODEEP */
break;
/* If we hit ALT or KET, it means we haven't found anything mandatory in
@@ -1155,8 +1177,8 @@ do
case OP_BRAZERO:
case OP_BRAMINZERO:
case OP_BRAPOSZERO:
- rc = set_start_bits(re, ++tcode, utf);
- if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
+ rc = set_start_bits(re, ++tcode, utf, ucp, depthptr);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN || rc == SSB_TOODEEP) return rc;
do tcode += GET(tcode,1); while (*tcode == OP_ALT);
tcode += 1 + LINK_SIZE;
break;
@@ -1177,7 +1199,7 @@ do
case OP_QUERY:
case OP_MINQUERY:
case OP_POSQUERY:
- tcode = set_table_bit(re, tcode + 1, FALSE, utf);
+ tcode = set_table_bit(re, tcode + 1, FALSE, utf, ucp);
break;
case OP_STARI:
@@ -1186,7 +1208,7 @@ do
case OP_QUERYI:
case OP_MINQUERYI:
case OP_POSQUERYI:
- tcode = set_table_bit(re, tcode + 1, TRUE, utf);
+ tcode = set_table_bit(re, tcode + 1, TRUE, utf, ucp);
break;
/* Single-char upto sets the bit and tries the next */
@@ -1194,13 +1216,13 @@ do
case OP_UPTO:
case OP_MINUPTO:
case OP_POSUPTO:
- tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf);
+ tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf, ucp);
break;
case OP_UPTOI:
case OP_MINUPTOI:
case OP_POSUPTOI:
- tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf);
+ tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf, ucp);
break;
/* At least one single char sets the bit and stops */
@@ -1212,7 +1234,7 @@ do
case OP_PLUS:
case OP_MINPLUS:
case OP_POSPLUS:
- (void)set_table_bit(re, tcode + 1, FALSE, utf);
+ (void)set_table_bit(re, tcode + 1, FALSE, utf, ucp);
try_next = FALSE;
break;
@@ -1223,7 +1245,7 @@ do
case OP_PLUSI:
case OP_MINPLUSI:
case OP_POSPLUSI:
- (void)set_table_bit(re, tcode + 1, TRUE, utf);
+ (void)set_table_bit(re, tcode + 1, TRUE, utf, ucp);
try_next = FALSE;
break;
@@ -1652,6 +1674,7 @@ PRIV(study)(pcre2_real_code *re)
int count = 0;
PCRE2_UCHAR *code;
BOOL utf = (re->overall_options & PCRE2_UTF) != 0;
+BOOL ucp = (re->overall_options & PCRE2_UCP) != 0;
/* Find start of compiled code */
@@ -1664,7 +1687,8 @@ code units. */
if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
{
- int rc = set_start_bits(re, code, utf);
+ int depth = 0;
+ int rc = set_start_bits(re, code, utf, ucp, &depth);
if (rc == SSB_UNKNOWN) return 1;
/* If a list of starting code units was set up, scan the list to see if only
@@ -1712,27 +1736,27 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
}
/* c contains the code unit value, in the range 0-255. In 8-bit UTF
- mode, only values < 128 can be used. */
+ mode, only values < 128 can be used. In all the other cases, c is a
+ character value. */
#if PCRE2_CODE_UNIT_WIDTH == 8
- if (c > 127) goto DONE;
+ if (utf && c > 127) goto DONE;
#endif
- if (a < 0) a = c; /* First one found */
+ if (a < 0) a = c; /* First one found, save in a */
else if (b < 0) /* Second one found */
{
int d = TABLE_GET((unsigned int)c, re->tables + fcc_offset, c);
#ifdef SUPPORT_UNICODE
-#if PCRE2_CODE_UNIT_WIDTH == 8
- if (utf && UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
-#else /* 16-bit or 32-bit */
- if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
- if (utf && c > 127) d = UCD_OTHERCASE(c);
-#endif /* Code width */
+ if (utf || ucp)
+ {
+ if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
+ if (c > 127) d = UCD_OTHERCASE(c);
+ }
#endif /* SUPPORT_UNICODE */
- if (d != a) goto DONE; /* Not other case of a */
- b = c;
+ if (d != a) goto DONE; /* Not the other case of a */
+ b = c; /* Save second in b */
}
else goto DONE; /* More than two characters found */
}
diff --git a/thirdparty/pcre2/src/pcre2_substitute.c b/thirdparty/pcre2/src/pcre2_substitute.c
index ec3dd66df9..981a106a9f 100644
--- a/thirdparty/pcre2/src/pcre2_substitute.c
+++ b/thirdparty/pcre2/src/pcre2_substitute.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -49,8 +49,9 @@ POSSIBILITY OF SUCH DAMAGE.
#define SUBSTITUTE_OPTIONS \
(PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \
- PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_UNKNOWN_UNSET| \
- PCRE2_SUBSTITUTE_UNSET_EMPTY)
+ PCRE2_SUBSTITUTE_LITERAL|PCRE2_SUBSTITUTE_MATCHED| \
+ PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_REPLACEMENT_ONLY| \
+ PCRE2_SUBSTITUTE_UNKNOWN_UNSET|PCRE2_SUBSTITUTE_UNSET_EMPTY)
@@ -194,6 +195,7 @@ overflow, either give an error immediately, or keep on, accumulating the
length. */
#define CHECKMEMCPY(from,length) \
+ { \
if (!overflowed && lengthleft < length) \
{ \
if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \
@@ -209,7 +211,8 @@ length. */
memcpy(buffer + buff_offset, from, CU2BYTES(length)); \
buff_offset += length; \
lengthleft -= length; \
- }
+ } \
+ }
/* Here's the function */
@@ -226,11 +229,14 @@ int forcecasereset = 0;
uint32_t ovector_count;
uint32_t goptions = 0;
uint32_t suboptions;
-BOOL match_data_created = FALSE;
-BOOL literal = FALSE;
+pcre2_match_data *internal_match_data = NULL;
+BOOL escaped_literal = FALSE;
BOOL overflowed = FALSE;
+BOOL use_existing_match;
+BOOL replacement_only;
#ifdef SUPPORT_UNICODE
BOOL utf = (code->overall_options & PCRE2_UTF) != 0;
+BOOL ucp = (code->overall_options & PCRE2_UCP) != 0;
#endif
PCRE2_UCHAR temp[6];
PCRE2_SPTR ptr;
@@ -248,23 +254,54 @@ lengthleft = buff_length = *blength;
*blength = PCRE2_UNSET;
ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET;
-/* Partial matching is not valid. This must come after setting *blength to
+/* Partial matching is not valid. This must come after setting *blength to
PCRE2_UNSET, so as not to imply an offset in the replacement. */
if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0)
return PCRE2_ERROR_BADOPTION;
-/* If no match data block is provided, create one. */
+/* Check for using a match that has already happened. Note that the subject
+pointer in the match data may be NULL after a no-match. */
+
+use_existing_match = ((options & PCRE2_SUBSTITUTE_MATCHED) != 0);
+replacement_only = ((options & PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) != 0);
+
+/* If starting from an existing match, there must be an externally provided
+match data block. We create an internal match_data block in two cases: (a) an
+external one is not supplied (and we are not starting from an existing match);
+(b) an existing match is to be used for the first substitution. In the latter
+case, we copy the existing match into the internal block. This ensures that no
+changes are made to the existing match data block. */
if (match_data == NULL)
{
+ pcre2_general_context *gcontext;
+ if (use_existing_match) return PCRE2_ERROR_NULL;
+ gcontext = (mcontext == NULL)?
+ (pcre2_general_context *)code :
+ (pcre2_general_context *)mcontext;
+ match_data = internal_match_data =
+ pcre2_match_data_create_from_pattern(code, gcontext);
+ if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;
+ }
+
+else if (use_existing_match)
+ {
pcre2_general_context *gcontext = (mcontext == NULL)?
(pcre2_general_context *)code :
(pcre2_general_context *)mcontext;
- match_data = pcre2_match_data_create_from_pattern(code, gcontext);
- if (match_data == NULL) return PCRE2_ERROR_NOMEMORY;
- match_data_created = TRUE;
+ int pairs = (code->top_bracket + 1 < match_data->oveccount)?
+ code->top_bracket + 1 : match_data->oveccount;
+ internal_match_data = pcre2_match_data_create(match_data->oveccount,
+ gcontext);
+ if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;
+ memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector)
+ + 2*pairs*sizeof(PCRE2_SIZE));
+ match_data = internal_match_data;
}
+
+/* Remember ovector details */
+
ovector = pcre2_get_ovector_pointer(match_data);
ovector_count = pcre2_get_ovector_count(match_data);
@@ -286,7 +323,7 @@ repend = replacement + rlength;
#ifdef SUPPORT_UNICODE
if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
{
- rc = PRIV(valid_utf)(replacement, rlength, &(match_data->rightchar));
+ rc = PRIV(valid_utf)(replacement, rlength, &(match_data->startchar));
if (rc != 0)
{
match_data->leftchar = 0;
@@ -300,7 +337,7 @@ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
suboptions = options & SUBSTITUTE_OPTIONS;
options &= ~SUBSTITUTE_OPTIONS;
-/* Copy up to the start offset */
+/* Error if the start match offset is greater than the length of the subject. */
if (start_offset > length)
{
@@ -308,9 +345,13 @@ if (start_offset > length)
rc = PCRE2_ERROR_BADOFFSET;
goto EXIT;
}
-CHECKMEMCPY(subject, start_offset);
-/* Loop for global substituting. */
+/* Copy up to the start offset, unless only the replacement is required. */
+
+if (!replacement_only) CHECKMEMCPY(subject, start_offset);
+
+/* Loop for global substituting. If PCRE2_SUBSTITUTE_MATCHED is set, the first
+match is taken from the match_data that was passed in. */
subs = 0;
do
@@ -318,7 +359,12 @@ do
PCRE2_SPTR ptrstack[PTR_STACK_SIZE];
uint32_t ptrstackptr = 0;
- rc = pcre2_match(code, subject, length, start_offset, options|goptions,
+ if (use_existing_match)
+ {
+ rc = match_data->rc;
+ use_existing_match = FALSE;
+ }
+ else rc = pcre2_match(code, subject, length, start_offset, options|goptions,
match_data, mcontext);
#ifdef SUPPORT_UNICODE
@@ -364,44 +410,44 @@ do
#endif
}
- /* Copy what we have advanced past, reset the special global options, and
- continue to the next match. */
+ /* Copy what we have advanced past (unless not required), reset the special
+ global options, and continue to the next match. */
fraglength = start_offset - save_start;
- CHECKMEMCPY(subject + save_start, fraglength);
+ if (!replacement_only) CHECKMEMCPY(subject + save_start, fraglength);
goptions = 0;
continue;
}
/* Handle a successful match. Matches that use \K to end before they start
or start before the current point in the subject are not supported. */
-
+
if (ovector[1] < ovector[0] || ovector[0] < start_offset)
{
rc = PCRE2_ERROR_BADSUBSPATTERN;
goto EXIT;
}
-
- /* Check for the same match as previous. This is legitimate after matching an
+
+ /* Check for the same match as previous. This is legitimate after matching an
empty string that starts after the initial match offset. We have tried again
at the match point in case the pattern is one like /(?<=\G.)/ which can never
match at its starting point, so running the match achieves the bumpalong. If
we do get the same (null) match at the original match point, it isn't such a
pattern, so we now do the empty string magic. In all other cases, a repeat
match should never occur. */
-
+
if (ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1])
- {
- if (ovector[0] == ovector[1] && ovecsave[2] != start_offset)
- {
- goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
- ovecsave[2] = start_offset;
- continue; /* Back to the top of the loop */
+ {
+ if (ovector[0] == ovector[1] && ovecsave[2] != start_offset)
+ {
+ goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
+ ovecsave[2] = start_offset;
+ continue; /* Back to the top of the loop */
}
rc = PCRE2_ERROR_INTERNAL_DUPMATCH;
- goto EXIT;
- }
-
+ goto EXIT;
+ }
+
/* Count substitutions with a paranoid check for integer overflow; surely no
real call to this function would ever hit this! */
@@ -412,21 +458,30 @@ do
}
subs++;
- /* Copy the text leading up to the match, and remember where the insert
- begins and how many ovector pairs are set. */
+ /* Copy the text leading up to the match (unless not required), and remember
+ where the insert begins and how many ovector pairs are set. */
if (rc == 0) rc = ovector_count;
fraglength = ovector[0] - start_offset;
- CHECKMEMCPY(subject + start_offset, fraglength);
+ if (!replacement_only) CHECKMEMCPY(subject + start_offset, fraglength);
scb.output_offsets[0] = buff_offset;
scb.oveccount = rc;
- /* Process the replacement string. Literal mode is set by \Q, but only in
- extended mode when backslashes are being interpreted. In extended mode we
- must handle nested substrings that are to be reprocessed. */
+ /* Process the replacement string. If the entire replacement is literal, just
+ copy it with length check. */
ptr = replacement;
- for (;;)
+ if ((suboptions & PCRE2_SUBSTITUTE_LITERAL) != 0)
+ {
+ CHECKMEMCPY(ptr, rlength);
+ }
+
+ /* Within a non-literal replacement, which must be scanned character by
+ character, local literal mode can be set by \Q, but only in extended mode
+ when backslashes are being interpreted. In extended mode we must handle
+ nested substrings that are to be reprocessed. */
+
+ else for (;;)
{
uint32_t ch;
unsigned int chlen;
@@ -443,11 +498,11 @@ do
/* Handle the next character */
- if (literal)
+ if (escaped_literal)
{
if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E)
{
- literal = FALSE;
+ escaped_literal = FALSE;
ptr += 2;
continue;
}
@@ -704,7 +759,7 @@ do
if (forcecase != 0)
{
#ifdef SUPPORT_UNICODE
- if (utf)
+ if (utf || ucp)
{
uint32_t type = UCD_CHARTYPE(ch);
if (PRIV(ucp_gentype)[type] == ucp_L &&
@@ -784,7 +839,7 @@ do
continue;
case ESC_Q:
- literal = TRUE;
+ escaped_literal = TRUE;
continue;
case 0: /* Data character */
@@ -806,7 +861,7 @@ do
if (forcecase != 0)
{
#ifdef SUPPORT_UNICODE
- if (utf)
+ if (utf || ucp)
{
uint32_t type = UCD_CHARTYPE(ch);
if (PRIV(ucp_gentype)[type] == ucp_L &&
@@ -835,53 +890,59 @@ do
} /* End handling a literal code unit */
} /* End of loop for scanning the replacement. */
- /* The replacement has been copied to the output, or its size has been
- remembered. Do the callout if there is one and we have done an actual
+ /* The replacement has been copied to the output, or its size has been
+ remembered. Do the callout if there is one and we have done an actual
replacement. */
-
+
if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL)
{
- scb.subscount = subs;
+ scb.subscount = subs;
scb.output_offsets[1] = buff_offset;
- rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data);
+ rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data);
- /* A non-zero return means cancel this substitution. Instead, copy the
+ /* A non-zero return means cancel this substitution. Instead, copy the
matched string fragment. */
if (rc != 0)
{
PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0];
PCRE2_SIZE oldlength = ovector[1] - ovector[0];
-
+
buff_offset -= newlength;
lengthleft += newlength;
- CHECKMEMCPY(subject + ovector[0], oldlength);
-
+ if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength);
+
/* A negative return means do not do any more. */
-
+
if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL);
}
- }
-
+ }
+
/* Save the details of this match. See above for how this data is used. If we
- matched an empty string, do the magic for global matches. Finally, update the
- start offset to point to the rest of the subject string. */
-
- ovecsave[0] = ovector[0];
- ovecsave[1] = ovector[1];
+ matched an empty string, do the magic for global matches. Update the start
+ offset to point to the rest of the subject string. If we re-used an existing
+ match for the first match, switch to the internal match data block. */
+
+ ovecsave[0] = ovector[0];
+ ovecsave[1] = ovector[1];
ovecsave[2] = start_offset;
-
+
goptions = (ovector[0] != ovector[1] || ovector[0] > start_offset)? 0 :
PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART;
start_offset = ovector[1];
} while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */
-/* Copy the rest of the subject. */
+/* Copy the rest of the subject unless not required, and terminate the output
+with a binary zero. */
+
+if (!replacement_only)
+ {
+ fraglength = length - start_offset;
+ CHECKMEMCPY(subject + start_offset, fraglength);
+ }
-fraglength = length - start_offset;
-CHECKMEMCPY(subject + start_offset, fraglength);
temp[0] = 0;
-CHECKMEMCPY(temp , 1);
+CHECKMEMCPY(temp, 1);
/* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set,
and matching has carried on after a full buffer, in order to compute the length
@@ -903,7 +964,7 @@ else
}
EXIT:
-if (match_data_created) pcre2_match_data_free(match_data);
+if (internal_match_data != NULL) pcre2_match_data_free(internal_match_data);
else match_data->rc = rc;
return rc;
diff --git a/thirdparty/pcre2/src/pcre2_tables.c b/thirdparty/pcre2/src/pcre2_tables.c
index 25531d98c6..b10de45efb 100644
--- a/thirdparty/pcre2/src/pcre2_tables.c
+++ b/thirdparty/pcre2/src/pcre2_tables.c
@@ -265,6 +265,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0"
#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
+#define STRING_Chorasmian0 STR_C STR_h STR_o STR_r STR_a STR_s STR_m STR_i STR_a STR_n "\0"
#define STRING_Cn0 STR_C STR_n "\0"
#define STRING_Co0 STR_C STR_o "\0"
#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"
@@ -275,6 +276,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
+#define STRING_Dives_Akuru0 STR_D STR_i STR_v STR_e STR_s STR_UNDERSCORE STR_A STR_k STR_u STR_r STR_u "\0"
#define STRING_Dogra0 STR_D STR_o STR_g STR_r STR_a "\0"
#define STRING_Duployan0 STR_D STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0"
#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
@@ -306,6 +308,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
+#define STRING_Khitan_Small_Script0 STR_K STR_h STR_i STR_t STR_a STR_n STR_UNDERSCORE STR_S STR_m STR_a STR_l STR_l STR_UNDERSCORE STR_S STR_c STR_r STR_i STR_p STR_t "\0"
#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
#define STRING_Khojki0 STR_K STR_h STR_o STR_j STR_k STR_i "\0"
#define STRING_Khudawadi0 STR_K STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0"
@@ -429,6 +432,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Xsp0 STR_X STR_s STR_p "\0"
#define STRING_Xuc0 STR_X STR_u STR_c "\0"
#define STRING_Xwd0 STR_X STR_w STR_d "\0"
+#define STRING_Yezidi0 STR_Y STR_e STR_z STR_i STR_d STR_i "\0"
#define STRING_Yi0 STR_Y STR_i "\0"
#define STRING_Z0 STR_Z "\0"
#define STRING_Zanabazar_Square0 STR_Z STR_a STR_n STR_a STR_b STR_a STR_z STR_a STR_r STR_UNDERSCORE STR_S STR_q STR_u STR_a STR_r STR_e "\0"
@@ -464,6 +468,7 @@ const char PRIV(utt_names)[] =
STRING_Chakma0
STRING_Cham0
STRING_Cherokee0
+ STRING_Chorasmian0
STRING_Cn0
STRING_Co0
STRING_Common0
@@ -474,6 +479,7 @@ const char PRIV(utt_names)[] =
STRING_Cyrillic0
STRING_Deseret0
STRING_Devanagari0
+ STRING_Dives_Akuru0
STRING_Dogra0
STRING_Duployan0
STRING_Egyptian_Hieroglyphs0
@@ -505,6 +511,7 @@ const char PRIV(utt_names)[] =
STRING_Katakana0
STRING_Kayah_Li0
STRING_Kharoshthi0
+ STRING_Khitan_Small_Script0
STRING_Khmer0
STRING_Khojki0
STRING_Khudawadi0
@@ -628,6 +635,7 @@ const char PRIV(utt_names)[] =
STRING_Xsp0
STRING_Xuc0
STRING_Xwd0
+ STRING_Yezidi0
STRING_Yi0
STRING_Z0
STRING_Zanabazar_Square0
@@ -663,176 +671,180 @@ const ucp_type_table PRIV(utt)[] = {
{ 203, PT_SC, ucp_Chakma },
{ 210, PT_SC, ucp_Cham },
{ 215, PT_SC, ucp_Cherokee },
- { 224, PT_PC, ucp_Cn },
- { 227, PT_PC, ucp_Co },
- { 230, PT_SC, ucp_Common },
- { 237, PT_SC, ucp_Coptic },
- { 244, PT_PC, ucp_Cs },
- { 247, PT_SC, ucp_Cuneiform },
- { 257, PT_SC, ucp_Cypriot },
- { 265, PT_SC, ucp_Cyrillic },
- { 274, PT_SC, ucp_Deseret },
- { 282, PT_SC, ucp_Devanagari },
- { 293, PT_SC, ucp_Dogra },
- { 299, PT_SC, ucp_Duployan },
- { 308, PT_SC, ucp_Egyptian_Hieroglyphs },
- { 329, PT_SC, ucp_Elbasan },
- { 337, PT_SC, ucp_Elymaic },
- { 345, PT_SC, ucp_Ethiopic },
- { 354, PT_SC, ucp_Georgian },
- { 363, PT_SC, ucp_Glagolitic },
- { 374, PT_SC, ucp_Gothic },
- { 381, PT_SC, ucp_Grantha },
- { 389, PT_SC, ucp_Greek },
- { 395, PT_SC, ucp_Gujarati },
- { 404, PT_SC, ucp_Gunjala_Gondi },
- { 418, PT_SC, ucp_Gurmukhi },
- { 427, PT_SC, ucp_Han },
- { 431, PT_SC, ucp_Hangul },
- { 438, PT_SC, ucp_Hanifi_Rohingya },
- { 454, PT_SC, ucp_Hanunoo },
- { 462, PT_SC, ucp_Hatran },
- { 469, PT_SC, ucp_Hebrew },
- { 476, PT_SC, ucp_Hiragana },
- { 485, PT_SC, ucp_Imperial_Aramaic },
- { 502, PT_SC, ucp_Inherited },
- { 512, PT_SC, ucp_Inscriptional_Pahlavi },
- { 534, PT_SC, ucp_Inscriptional_Parthian },
- { 557, PT_SC, ucp_Javanese },
- { 566, PT_SC, ucp_Kaithi },
- { 573, PT_SC, ucp_Kannada },
- { 581, PT_SC, ucp_Katakana },
- { 590, PT_SC, ucp_Kayah_Li },
- { 599, PT_SC, ucp_Kharoshthi },
- { 610, PT_SC, ucp_Khmer },
- { 616, PT_SC, ucp_Khojki },
- { 623, PT_SC, ucp_Khudawadi },
- { 633, PT_GC, ucp_L },
- { 635, PT_LAMP, 0 },
- { 638, PT_SC, ucp_Lao },
- { 642, PT_SC, ucp_Latin },
- { 648, PT_SC, ucp_Lepcha },
- { 655, PT_SC, ucp_Limbu },
- { 661, PT_SC, ucp_Linear_A },
- { 670, PT_SC, ucp_Linear_B },
- { 679, PT_SC, ucp_Lisu },
- { 684, PT_PC, ucp_Ll },
- { 687, PT_PC, ucp_Lm },
- { 690, PT_PC, ucp_Lo },
- { 693, PT_PC, ucp_Lt },
- { 696, PT_PC, ucp_Lu },
- { 699, PT_SC, ucp_Lycian },
- { 706, PT_SC, ucp_Lydian },
- { 713, PT_GC, ucp_M },
- { 715, PT_SC, ucp_Mahajani },
- { 724, PT_SC, ucp_Makasar },
- { 732, PT_SC, ucp_Malayalam },
- { 742, PT_SC, ucp_Mandaic },
- { 750, PT_SC, ucp_Manichaean },
- { 761, PT_SC, ucp_Marchen },
- { 769, PT_SC, ucp_Masaram_Gondi },
- { 783, PT_PC, ucp_Mc },
- { 786, PT_PC, ucp_Me },
- { 789, PT_SC, ucp_Medefaidrin },
- { 801, PT_SC, ucp_Meetei_Mayek },
- { 814, PT_SC, ucp_Mende_Kikakui },
- { 828, PT_SC, ucp_Meroitic_Cursive },
- { 845, PT_SC, ucp_Meroitic_Hieroglyphs },
- { 866, PT_SC, ucp_Miao },
- { 871, PT_PC, ucp_Mn },
- { 874, PT_SC, ucp_Modi },
- { 879, PT_SC, ucp_Mongolian },
- { 889, PT_SC, ucp_Mro },
- { 893, PT_SC, ucp_Multani },
- { 901, PT_SC, ucp_Myanmar },
- { 909, PT_GC, ucp_N },
- { 911, PT_SC, ucp_Nabataean },
- { 921, PT_SC, ucp_Nandinagari },
- { 933, PT_PC, ucp_Nd },
- { 936, PT_SC, ucp_New_Tai_Lue },
- { 948, PT_SC, ucp_Newa },
- { 953, PT_SC, ucp_Nko },
- { 957, PT_PC, ucp_Nl },
- { 960, PT_PC, ucp_No },
- { 963, PT_SC, ucp_Nushu },
- { 969, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
- { 992, PT_SC, ucp_Ogham },
- { 998, PT_SC, ucp_Ol_Chiki },
- { 1007, PT_SC, ucp_Old_Hungarian },
- { 1021, PT_SC, ucp_Old_Italic },
- { 1032, PT_SC, ucp_Old_North_Arabian },
- { 1050, PT_SC, ucp_Old_Permic },
- { 1061, PT_SC, ucp_Old_Persian },
- { 1073, PT_SC, ucp_Old_Sogdian },
- { 1085, PT_SC, ucp_Old_South_Arabian },
- { 1103, PT_SC, ucp_Old_Turkic },
- { 1114, PT_SC, ucp_Oriya },
- { 1120, PT_SC, ucp_Osage },
- { 1126, PT_SC, ucp_Osmanya },
- { 1134, PT_GC, ucp_P },
- { 1136, PT_SC, ucp_Pahawh_Hmong },
- { 1149, PT_SC, ucp_Palmyrene },
- { 1159, PT_SC, ucp_Pau_Cin_Hau },
- { 1171, PT_PC, ucp_Pc },
- { 1174, PT_PC, ucp_Pd },
- { 1177, PT_PC, ucp_Pe },
- { 1180, PT_PC, ucp_Pf },
- { 1183, PT_SC, ucp_Phags_Pa },
- { 1192, PT_SC, ucp_Phoenician },
- { 1203, PT_PC, ucp_Pi },
- { 1206, PT_PC, ucp_Po },
- { 1209, PT_PC, ucp_Ps },
- { 1212, PT_SC, ucp_Psalter_Pahlavi },
- { 1228, PT_SC, ucp_Rejang },
- { 1235, PT_SC, ucp_Runic },
- { 1241, PT_GC, ucp_S },
- { 1243, PT_SC, ucp_Samaritan },
- { 1253, PT_SC, ucp_Saurashtra },
- { 1264, PT_PC, ucp_Sc },
- { 1267, PT_SC, ucp_Sharada },
- { 1275, PT_SC, ucp_Shavian },
- { 1283, PT_SC, ucp_Siddham },
- { 1291, PT_SC, ucp_SignWriting },
- { 1303, PT_SC, ucp_Sinhala },
- { 1311, PT_PC, ucp_Sk },
- { 1314, PT_PC, ucp_Sm },
- { 1317, PT_PC, ucp_So },
- { 1320, PT_SC, ucp_Sogdian },
- { 1328, PT_SC, ucp_Sora_Sompeng },
- { 1341, PT_SC, ucp_Soyombo },
- { 1349, PT_SC, ucp_Sundanese },
- { 1359, PT_SC, ucp_Syloti_Nagri },
- { 1372, PT_SC, ucp_Syriac },
- { 1379, PT_SC, ucp_Tagalog },
- { 1387, PT_SC, ucp_Tagbanwa },
- { 1396, PT_SC, ucp_Tai_Le },
- { 1403, PT_SC, ucp_Tai_Tham },
- { 1412, PT_SC, ucp_Tai_Viet },
- { 1421, PT_SC, ucp_Takri },
- { 1427, PT_SC, ucp_Tamil },
- { 1433, PT_SC, ucp_Tangut },
- { 1440, PT_SC, ucp_Telugu },
- { 1447, PT_SC, ucp_Thaana },
- { 1454, PT_SC, ucp_Thai },
- { 1459, PT_SC, ucp_Tibetan },
- { 1467, PT_SC, ucp_Tifinagh },
- { 1476, PT_SC, ucp_Tirhuta },
- { 1484, PT_SC, ucp_Ugaritic },
- { 1493, PT_SC, ucp_Unknown },
- { 1501, PT_SC, ucp_Vai },
- { 1505, PT_SC, ucp_Wancho },
- { 1512, PT_SC, ucp_Warang_Citi },
- { 1524, PT_ALNUM, 0 },
- { 1528, PT_PXSPACE, 0 },
- { 1532, PT_SPACE, 0 },
- { 1536, PT_UCNC, 0 },
- { 1540, PT_WORD, 0 },
- { 1544, PT_SC, ucp_Yi },
- { 1547, PT_GC, ucp_Z },
- { 1549, PT_SC, ucp_Zanabazar_Square },
- { 1566, PT_PC, ucp_Zl },
- { 1569, PT_PC, ucp_Zp },
- { 1572, PT_PC, ucp_Zs }
+ { 224, PT_SC, ucp_Chorasmian },
+ { 235, PT_PC, ucp_Cn },
+ { 238, PT_PC, ucp_Co },
+ { 241, PT_SC, ucp_Common },
+ { 248, PT_SC, ucp_Coptic },
+ { 255, PT_PC, ucp_Cs },
+ { 258, PT_SC, ucp_Cuneiform },
+ { 268, PT_SC, ucp_Cypriot },
+ { 276, PT_SC, ucp_Cyrillic },
+ { 285, PT_SC, ucp_Deseret },
+ { 293, PT_SC, ucp_Devanagari },
+ { 304, PT_SC, ucp_Dives_Akuru },
+ { 316, PT_SC, ucp_Dogra },
+ { 322, PT_SC, ucp_Duployan },
+ { 331, PT_SC, ucp_Egyptian_Hieroglyphs },
+ { 352, PT_SC, ucp_Elbasan },
+ { 360, PT_SC, ucp_Elymaic },
+ { 368, PT_SC, ucp_Ethiopic },
+ { 377, PT_SC, ucp_Georgian },
+ { 386, PT_SC, ucp_Glagolitic },
+ { 397, PT_SC, ucp_Gothic },
+ { 404, PT_SC, ucp_Grantha },
+ { 412, PT_SC, ucp_Greek },
+ { 418, PT_SC, ucp_Gujarati },
+ { 427, PT_SC, ucp_Gunjala_Gondi },
+ { 441, PT_SC, ucp_Gurmukhi },
+ { 450, PT_SC, ucp_Han },
+ { 454, PT_SC, ucp_Hangul },
+ { 461, PT_SC, ucp_Hanifi_Rohingya },
+ { 477, PT_SC, ucp_Hanunoo },
+ { 485, PT_SC, ucp_Hatran },
+ { 492, PT_SC, ucp_Hebrew },
+ { 499, PT_SC, ucp_Hiragana },
+ { 508, PT_SC, ucp_Imperial_Aramaic },
+ { 525, PT_SC, ucp_Inherited },
+ { 535, PT_SC, ucp_Inscriptional_Pahlavi },
+ { 557, PT_SC, ucp_Inscriptional_Parthian },
+ { 580, PT_SC, ucp_Javanese },
+ { 589, PT_SC, ucp_Kaithi },
+ { 596, PT_SC, ucp_Kannada },
+ { 604, PT_SC, ucp_Katakana },
+ { 613, PT_SC, ucp_Kayah_Li },
+ { 622, PT_SC, ucp_Kharoshthi },
+ { 633, PT_SC, ucp_Khitan_Small_Script },
+ { 653, PT_SC, ucp_Khmer },
+ { 659, PT_SC, ucp_Khojki },
+ { 666, PT_SC, ucp_Khudawadi },
+ { 676, PT_GC, ucp_L },
+ { 678, PT_LAMP, 0 },
+ { 681, PT_SC, ucp_Lao },
+ { 685, PT_SC, ucp_Latin },
+ { 691, PT_SC, ucp_Lepcha },
+ { 698, PT_SC, ucp_Limbu },
+ { 704, PT_SC, ucp_Linear_A },
+ { 713, PT_SC, ucp_Linear_B },
+ { 722, PT_SC, ucp_Lisu },
+ { 727, PT_PC, ucp_Ll },
+ { 730, PT_PC, ucp_Lm },
+ { 733, PT_PC, ucp_Lo },
+ { 736, PT_PC, ucp_Lt },
+ { 739, PT_PC, ucp_Lu },
+ { 742, PT_SC, ucp_Lycian },
+ { 749, PT_SC, ucp_Lydian },
+ { 756, PT_GC, ucp_M },
+ { 758, PT_SC, ucp_Mahajani },
+ { 767, PT_SC, ucp_Makasar },
+ { 775, PT_SC, ucp_Malayalam },
+ { 785, PT_SC, ucp_Mandaic },
+ { 793, PT_SC, ucp_Manichaean },
+ { 804, PT_SC, ucp_Marchen },
+ { 812, PT_SC, ucp_Masaram_Gondi },
+ { 826, PT_PC, ucp_Mc },
+ { 829, PT_PC, ucp_Me },
+ { 832, PT_SC, ucp_Medefaidrin },
+ { 844, PT_SC, ucp_Meetei_Mayek },
+ { 857, PT_SC, ucp_Mende_Kikakui },
+ { 871, PT_SC, ucp_Meroitic_Cursive },
+ { 888, PT_SC, ucp_Meroitic_Hieroglyphs },
+ { 909, PT_SC, ucp_Miao },
+ { 914, PT_PC, ucp_Mn },
+ { 917, PT_SC, ucp_Modi },
+ { 922, PT_SC, ucp_Mongolian },
+ { 932, PT_SC, ucp_Mro },
+ { 936, PT_SC, ucp_Multani },
+ { 944, PT_SC, ucp_Myanmar },
+ { 952, PT_GC, ucp_N },
+ { 954, PT_SC, ucp_Nabataean },
+ { 964, PT_SC, ucp_Nandinagari },
+ { 976, PT_PC, ucp_Nd },
+ { 979, PT_SC, ucp_New_Tai_Lue },
+ { 991, PT_SC, ucp_Newa },
+ { 996, PT_SC, ucp_Nko },
+ { 1000, PT_PC, ucp_Nl },
+ { 1003, PT_PC, ucp_No },
+ { 1006, PT_SC, ucp_Nushu },
+ { 1012, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
+ { 1035, PT_SC, ucp_Ogham },
+ { 1041, PT_SC, ucp_Ol_Chiki },
+ { 1050, PT_SC, ucp_Old_Hungarian },
+ { 1064, PT_SC, ucp_Old_Italic },
+ { 1075, PT_SC, ucp_Old_North_Arabian },
+ { 1093, PT_SC, ucp_Old_Permic },
+ { 1104, PT_SC, ucp_Old_Persian },
+ { 1116, PT_SC, ucp_Old_Sogdian },
+ { 1128, PT_SC, ucp_Old_South_Arabian },
+ { 1146, PT_SC, ucp_Old_Turkic },
+ { 1157, PT_SC, ucp_Oriya },
+ { 1163, PT_SC, ucp_Osage },
+ { 1169, PT_SC, ucp_Osmanya },
+ { 1177, PT_GC, ucp_P },
+ { 1179, PT_SC, ucp_Pahawh_Hmong },
+ { 1192, PT_SC, ucp_Palmyrene },
+ { 1202, PT_SC, ucp_Pau_Cin_Hau },
+ { 1214, PT_PC, ucp_Pc },
+ { 1217, PT_PC, ucp_Pd },
+ { 1220, PT_PC, ucp_Pe },
+ { 1223, PT_PC, ucp_Pf },
+ { 1226, PT_SC, ucp_Phags_Pa },
+ { 1235, PT_SC, ucp_Phoenician },
+ { 1246, PT_PC, ucp_Pi },
+ { 1249, PT_PC, ucp_Po },
+ { 1252, PT_PC, ucp_Ps },
+ { 1255, PT_SC, ucp_Psalter_Pahlavi },
+ { 1271, PT_SC, ucp_Rejang },
+ { 1278, PT_SC, ucp_Runic },
+ { 1284, PT_GC, ucp_S },
+ { 1286, PT_SC, ucp_Samaritan },
+ { 1296, PT_SC, ucp_Saurashtra },
+ { 1307, PT_PC, ucp_Sc },
+ { 1310, PT_SC, ucp_Sharada },
+ { 1318, PT_SC, ucp_Shavian },
+ { 1326, PT_SC, ucp_Siddham },
+ { 1334, PT_SC, ucp_SignWriting },
+ { 1346, PT_SC, ucp_Sinhala },
+ { 1354, PT_PC, ucp_Sk },
+ { 1357, PT_PC, ucp_Sm },
+ { 1360, PT_PC, ucp_So },
+ { 1363, PT_SC, ucp_Sogdian },
+ { 1371, PT_SC, ucp_Sora_Sompeng },
+ { 1384, PT_SC, ucp_Soyombo },
+ { 1392, PT_SC, ucp_Sundanese },
+ { 1402, PT_SC, ucp_Syloti_Nagri },
+ { 1415, PT_SC, ucp_Syriac },
+ { 1422, PT_SC, ucp_Tagalog },
+ { 1430, PT_SC, ucp_Tagbanwa },
+ { 1439, PT_SC, ucp_Tai_Le },
+ { 1446, PT_SC, ucp_Tai_Tham },
+ { 1455, PT_SC, ucp_Tai_Viet },
+ { 1464, PT_SC, ucp_Takri },
+ { 1470, PT_SC, ucp_Tamil },
+ { 1476, PT_SC, ucp_Tangut },
+ { 1483, PT_SC, ucp_Telugu },
+ { 1490, PT_SC, ucp_Thaana },
+ { 1497, PT_SC, ucp_Thai },
+ { 1502, PT_SC, ucp_Tibetan },
+ { 1510, PT_SC, ucp_Tifinagh },
+ { 1519, PT_SC, ucp_Tirhuta },
+ { 1527, PT_SC, ucp_Ugaritic },
+ { 1536, PT_SC, ucp_Unknown },
+ { 1544, PT_SC, ucp_Vai },
+ { 1548, PT_SC, ucp_Wancho },
+ { 1555, PT_SC, ucp_Warang_Citi },
+ { 1567, PT_ALNUM, 0 },
+ { 1571, PT_PXSPACE, 0 },
+ { 1575, PT_SPACE, 0 },
+ { 1579, PT_UCNC, 0 },
+ { 1583, PT_WORD, 0 },
+ { 1587, PT_SC, ucp_Yezidi },
+ { 1594, PT_SC, ucp_Yi },
+ { 1597, PT_GC, ucp_Z },
+ { 1599, PT_SC, ucp_Zanabazar_Square },
+ { 1616, PT_PC, ucp_Zl },
+ { 1619, PT_PC, ucp_Zp },
+ { 1622, PT_PC, ucp_Zs }
};
const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
diff --git a/thirdparty/pcre2/src/pcre2_ucd.c b/thirdparty/pcre2/src/pcre2_ucd.c
index 55ba03bd43..46e23ff06b 100644
--- a/thirdparty/pcre2/src/pcre2_ucd.c
+++ b/thirdparty/pcre2/src/pcre2_ucd.c
@@ -20,7 +20,7 @@ needed. */
/* Unicode character database. */
/* This file was autogenerated by the MultiStage2.py script. */
-/* Total size: 99316 bytes, block size: 128. */
+/* Total size: 101044 bytes, block size: 128. */
/* The tables herein are needed only when UCP support is built,
and in PCRE2 that happens automatically with UTF support.
@@ -39,7 +39,7 @@ const uint16_t PRIV(ucd_stage2)[] = {0};
const uint32_t PRIV(ucd_caseless_sets)[] = {0};
#else
-const char *PRIV(unicode_version) = "12.1.0";
+const char *PRIV(unicode_version) = "13.0.0";
/* If the 32-bit library is run in non-32-bit mode, character values
greater than 0x10ffff may be encountered. For these we set up a
@@ -116,15 +116,16 @@ set of decimal digits. It is used to ensure that all the digits in
a script run come from the same set. */
const uint32_t PRIV(ucd_digit_sets)[] = {
- 63, /* Number of subsequent values */
+ 65, /* Number of subsequent values */
0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef,
0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9,
0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89,
0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909,
0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f,
0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9,
- 0x11739, 0x118e9, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16b59, 0x1d7d7,
- 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, 0x1e959,
+ 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16b59,
+ 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, 0x1e959,
+ 0x1fbf9,
};
/* This vector is a list of lists of scripts for the Script Extension
@@ -136,14 +137,14 @@ const uint8_t PRIV(ucd_script_sets)[] = {
/* 4 */ 1, 144, 0,
/* 7 */ 1, 50, 0,
/* 10 */ 1, 56, 0,
- /* 13 */ 2, 17, 0,
- /* 16 */ 3, 15, 0,
- /* 19 */ 4, 23, 0,
- /* 22 */ 6, 84, 0,
- /* 25 */ 12, 36, 0,
- /* 28 */ 13, 18, 0,
- /* 31 */ 13, 34, 0,
- /* 34 */ 13, 118, 0,
+ /* 13 */ 3, 15, 0,
+ /* 16 */ 4, 23, 0,
+ /* 19 */ 6, 84, 0,
+ /* 22 */ 12, 36, 0,
+ /* 25 */ 13, 18, 0,
+ /* 28 */ 13, 34, 0,
+ /* 31 */ 13, 118, 0,
+ /* 34 */ 13, 50, 0,
/* 37 */ 15, 107, 0,
/* 40 */ 15, 150, 0,
/* 43 */ 15, 100, 0,
@@ -152,35 +153,37 @@ const uint8_t PRIV(ucd_script_sets)[] = {
/* 52 */ 107, 54, 0,
/* 55 */ 21, 108, 0,
/* 58 */ 22, 129, 0,
- /* 61 */ 27, 30, 0,
- /* 64 */ 29, 150, 0,
- /* 67 */ 34, 38, 0,
- /* 70 */ 38, 65, 0,
- /* 73 */ 1, 50, 56, 0,
- /* 77 */ 3, 96, 49, 0,
- /* 81 */ 96, 39, 53, 0,
- /* 85 */ 12, 110, 36, 0,
- /* 89 */ 15, 107, 29, 0,
- /* 93 */ 15, 107, 34, 0,
- /* 97 */ 23, 27, 30, 0,
- /* 101 */ 69, 34, 39, 0,
- /* 105 */ 1, 144, 50, 56, 0,
- /* 110 */ 3, 15, 107, 29, 0,
- /* 115 */ 7, 25, 52, 51, 0,
- /* 120 */ 15, 142, 85, 111, 0,
- /* 125 */ 4, 24, 23, 27, 30, 0,
- /* 131 */ 4, 24, 23, 27, 30, 61, 0,
- /* 138 */ 15, 29, 37, 44, 54, 55, 0,
- /* 145 */ 132, 1, 95, 112, 121, 144, 148, 50, 0,
- /* 154 */ 3, 15, 107, 29, 150, 44, 55, 124, 0,
- /* 163 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0,
- /* 175 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0,
- /* 188 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0,
- /* 202 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 150, 109, 102, 124, 0,
- /* 216 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 150, 109, 102, 124, 0,
- /* 231 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0,
- /* 252 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 35, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0,
- /* 274 */
+ /* 61 */ 23, 34, 0,
+ /* 64 */ 27, 30, 0,
+ /* 67 */ 29, 150, 0,
+ /* 70 */ 34, 38, 0,
+ /* 73 */ 38, 65, 0,
+ /* 76 */ 1, 50, 56, 0,
+ /* 80 */ 1, 56, 156, 0,
+ /* 84 */ 3, 96, 49, 0,
+ /* 88 */ 96, 39, 53, 0,
+ /* 92 */ 12, 110, 36, 0,
+ /* 96 */ 15, 107, 29, 0,
+ /* 100 */ 15, 107, 34, 0,
+ /* 104 */ 23, 27, 30, 0,
+ /* 108 */ 69, 34, 39, 0,
+ /* 112 */ 3, 15, 107, 29, 0,
+ /* 117 */ 7, 25, 52, 51, 0,
+ /* 122 */ 15, 142, 85, 111, 0,
+ /* 127 */ 1, 144, 50, 56, 156, 0,
+ /* 133 */ 4, 24, 23, 27, 30, 0,
+ /* 139 */ 4, 24, 23, 27, 30, 61, 0,
+ /* 146 */ 15, 29, 37, 44, 54, 55, 0,
+ /* 153 */ 132, 1, 95, 112, 121, 144, 148, 50, 0,
+ /* 162 */ 3, 15, 107, 29, 150, 44, 55, 124, 0,
+ /* 171 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0,
+ /* 183 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0,
+ /* 196 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0,
+ /* 210 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 150, 109, 102, 124, 0,
+ /* 224 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 150, 109, 102, 124, 0,
+ /* 239 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0,
+ /* 260 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 35, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0,
+ /* 282 */
};
/* These are the main two-stage UCD tables. The fields in each record are:
@@ -189,7 +192,7 @@ offset to multichar other cases or zero (8 bits), offset to other case
or zero (32 bits, signed), script extension (16 bits, signed), and a dummy
16-bit field to make the whole thing a multiple of 4 bytes. */
-const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */
+const ucd_record PRIV(ucd_records)[] = { /* 11700 bytes, record size 12 */
{ 10, 0, 2, 0, 0, 10, 256, }, /* 0 */
{ 10, 0, 2, 0, 0, 10, 0, }, /* 1 */
{ 10, 0, 1, 0, 0, 10, 0, }, /* 2 */
@@ -387,9 +390,9 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */
{ 13, 9, 12, 88, 1, 13, 0, }, /* 194 */
{ 13, 5, 12, 88, -1, 13, 0, }, /* 195 */
{ 13, 26, 12, 0, 0, 13, 0, }, /* 196 */
- { 13, 12, 3, 0, 0, -34, 0, }, /* 197 */
- { 13, 12, 3, 0, 0, -28, 0, }, /* 198 */
- { 28, 12, 3, 0, 0, -31, 0, }, /* 199 */
+ { 13, 12, 3, 0, 0, -31, 0, }, /* 197 */
+ { 13, 12, 3, 0, 0, -25, 0, }, /* 198 */
+ { 28, 12, 3, 0, 0, -28, 0, }, /* 199 */
{ 13, 11, 3, 0, 0, 13, 0, }, /* 200 */
{ 13, 9, 12, 0, 15, 13, 0, }, /* 201 */
{ 13, 5, 12, 0, -15, 13, 0, }, /* 202 */
@@ -398,281 +401,281 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */
{ 2, 21, 12, 0, 0, 2, 0, }, /* 205 */
{ 2, 5, 12, 0, 0, 2, 0, }, /* 206 */
{ 2, 5, 12, 0, -48, 2, 0, }, /* 207 */
- { 10, 21, 12, 0, 0, -13, 0, }, /* 208 */
- { 2, 17, 12, 0, 0, 2, 0, }, /* 209 */
- { 2, 26, 12, 0, 0, 2, 0, }, /* 210 */
- { 2, 23, 12, 0, 0, 2, 0, }, /* 211 */
- { 26, 12, 3, 0, 0, 26, 0, }, /* 212 */
- { 26, 17, 12, 0, 0, 26, 0, }, /* 213 */
- { 26, 21, 12, 0, 0, 26, 0, }, /* 214 */
- { 26, 7, 12, 0, 0, 26, 0, }, /* 215 */
- { 1, 1, 4, 0, 0, 1, 0, }, /* 216 */
- { 10, 1, 4, 0, 0, 10, 0, }, /* 217 */
- { 1, 25, 12, 0, 0, 1, 0, }, /* 218 */
- { 1, 21, 12, 0, 0, 1, 0, }, /* 219 */
- { 1, 23, 12, 0, 0, 1, 0, }, /* 220 */
- { 10, 21, 12, 0, 0, -105, 0, }, /* 221 */
- { 1, 26, 12, 0, 0, 1, 0, }, /* 222 */
- { 1, 12, 3, 0, 0, 1, 0, }, /* 223 */
- { 1, 1, 2, 0, 0, -73, 0, }, /* 224 */
- { 1, 7, 12, 0, 0, 1, 0, }, /* 225 */
- { 10, 6, 12, 0, 0, -145, 0, }, /* 226 */
- { 28, 12, 3, 0, 0, -7, 0, }, /* 227 */
- { 1, 13, 12, 0, 0, -10, 0, }, /* 228 */
- { 1, 21, 12, 0, 0, -4, 0, }, /* 229 */
- { 1, 6, 12, 0, 0, 1, 0, }, /* 230 */
- { 1, 13, 12, 0, 0, 1, 0, }, /* 231 */
- { 50, 21, 12, 0, 0, 50, 0, }, /* 232 */
- { 50, 1, 4, 0, 0, 50, 0, }, /* 233 */
- { 50, 7, 12, 0, 0, 50, 0, }, /* 234 */
- { 50, 12, 3, 0, 0, 50, 0, }, /* 235 */
- { 56, 7, 12, 0, 0, 56, 0, }, /* 236 */
- { 56, 12, 3, 0, 0, 56, 0, }, /* 237 */
- { 64, 13, 12, 0, 0, 64, 0, }, /* 238 */
- { 64, 7, 12, 0, 0, 64, 0, }, /* 239 */
- { 64, 12, 3, 0, 0, 64, 0, }, /* 240 */
- { 64, 6, 12, 0, 0, 64, 0, }, /* 241 */
- { 64, 26, 12, 0, 0, 64, 0, }, /* 242 */
- { 64, 21, 12, 0, 0, 64, 0, }, /* 243 */
- { 64, 23, 12, 0, 0, 64, 0, }, /* 244 */
- { 90, 7, 12, 0, 0, 90, 0, }, /* 245 */
- { 90, 12, 3, 0, 0, 90, 0, }, /* 246 */
- { 90, 6, 12, 0, 0, 90, 0, }, /* 247 */
- { 90, 21, 12, 0, 0, 90, 0, }, /* 248 */
- { 95, 7, 12, 0, 0, 95, 0, }, /* 249 */
- { 95, 12, 3, 0, 0, 95, 0, }, /* 250 */
- { 95, 21, 12, 0, 0, 95, 0, }, /* 251 */
- { 15, 12, 3, 0, 0, 15, 0, }, /* 252 */
- { 15, 10, 5, 0, 0, 15, 0, }, /* 253 */
- { 15, 7, 12, 0, 0, 15, 0, }, /* 254 */
- { 28, 12, 3, 0, 0, -188, 0, }, /* 255 */
- { 28, 12, 3, 0, 0, -175, 0, }, /* 256 */
- { 10, 21, 12, 0, 0, -231, 0, }, /* 257 */
- { 10, 21, 12, 0, 0, -252, 0, }, /* 258 */
- { 15, 13, 12, 0, 0, -120, 0, }, /* 259 */
- { 15, 21, 12, 0, 0, 15, 0, }, /* 260 */
- { 15, 6, 12, 0, 0, 15, 0, }, /* 261 */
- { 3, 7, 12, 0, 0, 3, 0, }, /* 262 */
- { 3, 12, 3, 0, 0, 3, 0, }, /* 263 */
- { 3, 10, 5, 0, 0, 3, 0, }, /* 264 */
- { 3, 10, 3, 0, 0, 3, 0, }, /* 265 */
- { 3, 13, 12, 0, 0, -77, 0, }, /* 266 */
- { 3, 23, 12, 0, 0, 3, 0, }, /* 267 */
- { 3, 15, 12, 0, 0, 3, 0, }, /* 268 */
- { 3, 26, 12, 0, 0, 3, 0, }, /* 269 */
- { 3, 21, 12, 0, 0, 3, 0, }, /* 270 */
- { 22, 12, 3, 0, 0, 22, 0, }, /* 271 */
- { 22, 10, 5, 0, 0, 22, 0, }, /* 272 */
- { 22, 7, 12, 0, 0, 22, 0, }, /* 273 */
- { 22, 13, 12, 0, 0, -58, 0, }, /* 274 */
- { 22, 21, 12, 0, 0, 22, 0, }, /* 275 */
- { 21, 12, 3, 0, 0, 21, 0, }, /* 276 */
- { 21, 10, 5, 0, 0, 21, 0, }, /* 277 */
- { 21, 7, 12, 0, 0, 21, 0, }, /* 278 */
- { 21, 13, 12, 0, 0, -55, 0, }, /* 279 */
- { 21, 21, 12, 0, 0, 21, 0, }, /* 280 */
- { 21, 23, 12, 0, 0, 21, 0, }, /* 281 */
- { 44, 12, 3, 0, 0, 44, 0, }, /* 282 */
- { 44, 10, 5, 0, 0, 44, 0, }, /* 283 */
- { 44, 7, 12, 0, 0, 44, 0, }, /* 284 */
- { 44, 10, 3, 0, 0, 44, 0, }, /* 285 */
- { 44, 13, 12, 0, 0, 44, 0, }, /* 286 */
- { 44, 26, 12, 0, 0, 44, 0, }, /* 287 */
- { 44, 15, 12, 0, 0, 44, 0, }, /* 288 */
- { 54, 12, 3, 0, 0, 54, 0, }, /* 289 */
- { 54, 7, 12, 0, 0, 54, 0, }, /* 290 */
- { 54, 10, 3, 0, 0, 54, 0, }, /* 291 */
- { 54, 10, 5, 0, 0, 54, 0, }, /* 292 */
- { 54, 13, 12, 0, 0, -52, 0, }, /* 293 */
- { 54, 15, 12, 0, 0, -52, 0, }, /* 294 */
- { 54, 26, 12, 0, 0, -52, 0, }, /* 295 */
- { 54, 26, 12, 0, 0, 54, 0, }, /* 296 */
- { 54, 23, 12, 0, 0, 54, 0, }, /* 297 */
- { 55, 12, 3, 0, 0, 55, 0, }, /* 298 */
- { 55, 10, 5, 0, 0, 55, 0, }, /* 299 */
- { 55, 7, 12, 0, 0, 55, 0, }, /* 300 */
- { 55, 13, 12, 0, 0, 55, 0, }, /* 301 */
- { 55, 21, 12, 0, 0, 55, 0, }, /* 302 */
- { 55, 15, 12, 0, 0, 55, 0, }, /* 303 */
- { 55, 26, 12, 0, 0, 55, 0, }, /* 304 */
- { 29, 7, 12, 0, 0, 29, 0, }, /* 305 */
- { 29, 12, 3, 0, 0, 29, 0, }, /* 306 */
- { 29, 10, 5, 0, 0, 29, 0, }, /* 307 */
- { 29, 21, 12, 0, 0, 29, 0, }, /* 308 */
- { 29, 10, 3, 0, 0, 29, 0, }, /* 309 */
- { 29, 13, 12, 0, 0, -64, 0, }, /* 310 */
- { 37, 12, 3, 0, 0, 37, 0, }, /* 311 */
- { 37, 10, 5, 0, 0, 37, 0, }, /* 312 */
- { 37, 7, 12, 0, 0, 37, 0, }, /* 313 */
- { 37, 10, 3, 0, 0, 37, 0, }, /* 314 */
- { 37, 7, 4, 0, 0, 37, 0, }, /* 315 */
- { 37, 26, 12, 0, 0, 37, 0, }, /* 316 */
- { 37, 15, 12, 0, 0, 37, 0, }, /* 317 */
- { 37, 13, 12, 0, 0, 37, 0, }, /* 318 */
+ { 2, 17, 12, 0, 0, 2, 0, }, /* 208 */
+ { 2, 26, 12, 0, 0, 2, 0, }, /* 209 */
+ { 2, 23, 12, 0, 0, 2, 0, }, /* 210 */
+ { 26, 12, 3, 0, 0, 26, 0, }, /* 211 */
+ { 26, 17, 12, 0, 0, 26, 0, }, /* 212 */
+ { 26, 21, 12, 0, 0, 26, 0, }, /* 213 */
+ { 26, 7, 12, 0, 0, 26, 0, }, /* 214 */
+ { 1, 1, 4, 0, 0, 1, 0, }, /* 215 */
+ { 10, 1, 4, 0, 0, 10, 0, }, /* 216 */
+ { 1, 25, 12, 0, 0, 1, 0, }, /* 217 */
+ { 1, 21, 12, 0, 0, 1, 0, }, /* 218 */
+ { 1, 23, 12, 0, 0, 1, 0, }, /* 219 */
+ { 10, 21, 12, 0, 0, -127, 0, }, /* 220 */
+ { 1, 26, 12, 0, 0, 1, 0, }, /* 221 */
+ { 1, 12, 3, 0, 0, 1, 0, }, /* 222 */
+ { 1, 1, 2, 0, 0, -76, 0, }, /* 223 */
+ { 1, 7, 12, 0, 0, 1, 0, }, /* 224 */
+ { 10, 6, 12, 0, 0, -153, 0, }, /* 225 */
+ { 28, 12, 3, 0, 0, -7, 0, }, /* 226 */
+ { 1, 13, 12, 0, 0, -80, 0, }, /* 227 */
+ { 1, 21, 12, 0, 0, -4, 0, }, /* 228 */
+ { 1, 6, 12, 0, 0, 1, 0, }, /* 229 */
+ { 1, 13, 12, 0, 0, 1, 0, }, /* 230 */
+ { 50, 21, 12, 0, 0, 50, 0, }, /* 231 */
+ { 50, 1, 4, 0, 0, 50, 0, }, /* 232 */
+ { 50, 7, 12, 0, 0, 50, 0, }, /* 233 */
+ { 50, 12, 3, 0, 0, 50, 0, }, /* 234 */
+ { 56, 7, 12, 0, 0, 56, 0, }, /* 235 */
+ { 56, 12, 3, 0, 0, 56, 0, }, /* 236 */
+ { 64, 13, 12, 0, 0, 64, 0, }, /* 237 */
+ { 64, 7, 12, 0, 0, 64, 0, }, /* 238 */
+ { 64, 12, 3, 0, 0, 64, 0, }, /* 239 */
+ { 64, 6, 12, 0, 0, 64, 0, }, /* 240 */
+ { 64, 26, 12, 0, 0, 64, 0, }, /* 241 */
+ { 64, 21, 12, 0, 0, 64, 0, }, /* 242 */
+ { 64, 23, 12, 0, 0, 64, 0, }, /* 243 */
+ { 90, 7, 12, 0, 0, 90, 0, }, /* 244 */
+ { 90, 12, 3, 0, 0, 90, 0, }, /* 245 */
+ { 90, 6, 12, 0, 0, 90, 0, }, /* 246 */
+ { 90, 21, 12, 0, 0, 90, 0, }, /* 247 */
+ { 95, 7, 12, 0, 0, 95, 0, }, /* 248 */
+ { 95, 12, 3, 0, 0, 95, 0, }, /* 249 */
+ { 95, 21, 12, 0, 0, 95, 0, }, /* 250 */
+ { 15, 12, 3, 0, 0, 15, 0, }, /* 251 */
+ { 15, 10, 5, 0, 0, 15, 0, }, /* 252 */
+ { 15, 7, 12, 0, 0, 15, 0, }, /* 253 */
+ { 28, 12, 3, 0, 0, -196, 0, }, /* 254 */
+ { 28, 12, 3, 0, 0, -183, 0, }, /* 255 */
+ { 10, 21, 12, 0, 0, -239, 0, }, /* 256 */
+ { 10, 21, 12, 0, 0, -260, 0, }, /* 257 */
+ { 15, 13, 12, 0, 0, -122, 0, }, /* 258 */
+ { 15, 21, 12, 0, 0, 15, 0, }, /* 259 */
+ { 15, 6, 12, 0, 0, 15, 0, }, /* 260 */
+ { 3, 7, 12, 0, 0, 3, 0, }, /* 261 */
+ { 3, 12, 3, 0, 0, 3, 0, }, /* 262 */
+ { 3, 10, 5, 0, 0, 3, 0, }, /* 263 */
+ { 3, 10, 3, 0, 0, 3, 0, }, /* 264 */
+ { 3, 13, 12, 0, 0, -84, 0, }, /* 265 */
+ { 3, 23, 12, 0, 0, 3, 0, }, /* 266 */
+ { 3, 15, 12, 0, 0, 3, 0, }, /* 267 */
+ { 3, 26, 12, 0, 0, 3, 0, }, /* 268 */
+ { 3, 21, 12, 0, 0, 3, 0, }, /* 269 */
+ { 22, 12, 3, 0, 0, 22, 0, }, /* 270 */
+ { 22, 10, 5, 0, 0, 22, 0, }, /* 271 */
+ { 22, 7, 12, 0, 0, 22, 0, }, /* 272 */
+ { 22, 13, 12, 0, 0, -58, 0, }, /* 273 */
+ { 22, 21, 12, 0, 0, 22, 0, }, /* 274 */
+ { 21, 12, 3, 0, 0, 21, 0, }, /* 275 */
+ { 21, 10, 5, 0, 0, 21, 0, }, /* 276 */
+ { 21, 7, 12, 0, 0, 21, 0, }, /* 277 */
+ { 21, 13, 12, 0, 0, -55, 0, }, /* 278 */
+ { 21, 21, 12, 0, 0, 21, 0, }, /* 279 */
+ { 21, 23, 12, 0, 0, 21, 0, }, /* 280 */
+ { 44, 12, 3, 0, 0, 44, 0, }, /* 281 */
+ { 44, 10, 5, 0, 0, 44, 0, }, /* 282 */
+ { 44, 7, 12, 0, 0, 44, 0, }, /* 283 */
+ { 44, 10, 3, 0, 0, 44, 0, }, /* 284 */
+ { 44, 13, 12, 0, 0, 44, 0, }, /* 285 */
+ { 44, 26, 12, 0, 0, 44, 0, }, /* 286 */
+ { 44, 15, 12, 0, 0, 44, 0, }, /* 287 */
+ { 54, 12, 3, 0, 0, 54, 0, }, /* 288 */
+ { 54, 7, 12, 0, 0, 54, 0, }, /* 289 */
+ { 54, 10, 3, 0, 0, 54, 0, }, /* 290 */
+ { 54, 10, 5, 0, 0, 54, 0, }, /* 291 */
+ { 54, 13, 12, 0, 0, -52, 0, }, /* 292 */
+ { 54, 15, 12, 0, 0, -52, 0, }, /* 293 */
+ { 54, 26, 12, 0, 0, -52, 0, }, /* 294 */
+ { 54, 26, 12, 0, 0, 54, 0, }, /* 295 */
+ { 54, 23, 12, 0, 0, 54, 0, }, /* 296 */
+ { 55, 12, 3, 0, 0, 55, 0, }, /* 297 */
+ { 55, 10, 5, 0, 0, 55, 0, }, /* 298 */
+ { 55, 7, 12, 0, 0, 55, 0, }, /* 299 */
+ { 55, 13, 12, 0, 0, 55, 0, }, /* 300 */
+ { 55, 21, 12, 0, 0, 55, 0, }, /* 301 */
+ { 55, 15, 12, 0, 0, 55, 0, }, /* 302 */
+ { 55, 26, 12, 0, 0, 55, 0, }, /* 303 */
+ { 29, 7, 12, 0, 0, 29, 0, }, /* 304 */
+ { 29, 12, 3, 0, 0, 29, 0, }, /* 305 */
+ { 29, 10, 5, 0, 0, 29, 0, }, /* 306 */
+ { 29, 21, 12, 0, 0, 29, 0, }, /* 307 */
+ { 29, 10, 3, 0, 0, 29, 0, }, /* 308 */
+ { 29, 13, 12, 0, 0, -67, 0, }, /* 309 */
+ { 37, 12, 3, 0, 0, 37, 0, }, /* 310 */
+ { 37, 10, 5, 0, 0, 37, 0, }, /* 311 */
+ { 37, 7, 12, 0, 0, 37, 0, }, /* 312 */
+ { 37, 10, 3, 0, 0, 37, 0, }, /* 313 */
+ { 37, 7, 4, 0, 0, 37, 0, }, /* 314 */
+ { 37, 26, 12, 0, 0, 37, 0, }, /* 315 */
+ { 37, 15, 12, 0, 0, 37, 0, }, /* 316 */
+ { 37, 13, 12, 0, 0, 37, 0, }, /* 317 */
+ { 48, 12, 3, 0, 0, 48, 0, }, /* 318 */
{ 48, 10, 5, 0, 0, 48, 0, }, /* 319 */
{ 48, 7, 12, 0, 0, 48, 0, }, /* 320 */
- { 48, 12, 3, 0, 0, 48, 0, }, /* 321 */
- { 48, 10, 3, 0, 0, 48, 0, }, /* 322 */
- { 48, 13, 12, 0, 0, 48, 0, }, /* 323 */
- { 48, 21, 12, 0, 0, 48, 0, }, /* 324 */
- { 57, 7, 12, 0, 0, 57, 0, }, /* 325 */
- { 57, 12, 3, 0, 0, 57, 0, }, /* 326 */
- { 57, 7, 5, 0, 0, 57, 0, }, /* 327 */
- { 57, 6, 12, 0, 0, 57, 0, }, /* 328 */
- { 57, 21, 12, 0, 0, 57, 0, }, /* 329 */
- { 57, 13, 12, 0, 0, 57, 0, }, /* 330 */
- { 33, 7, 12, 0, 0, 33, 0, }, /* 331 */
- { 33, 12, 3, 0, 0, 33, 0, }, /* 332 */
- { 33, 7, 5, 0, 0, 33, 0, }, /* 333 */
- { 33, 6, 12, 0, 0, 33, 0, }, /* 334 */
- { 33, 13, 12, 0, 0, 33, 0, }, /* 335 */
- { 58, 7, 12, 0, 0, 58, 0, }, /* 336 */
- { 58, 26, 12, 0, 0, 58, 0, }, /* 337 */
- { 58, 21, 12, 0, 0, 58, 0, }, /* 338 */
- { 58, 12, 3, 0, 0, 58, 0, }, /* 339 */
- { 58, 13, 12, 0, 0, 58, 0, }, /* 340 */
- { 58, 15, 12, 0, 0, 58, 0, }, /* 341 */
- { 58, 22, 12, 0, 0, 58, 0, }, /* 342 */
- { 58, 18, 12, 0, 0, 58, 0, }, /* 343 */
- { 58, 10, 5, 0, 0, 58, 0, }, /* 344 */
- { 39, 7, 12, 0, 0, 39, 0, }, /* 345 */
- { 39, 10, 12, 0, 0, 39, 0, }, /* 346 */
- { 39, 12, 3, 0, 0, 39, 0, }, /* 347 */
- { 39, 10, 5, 0, 0, 39, 0, }, /* 348 */
- { 39, 13, 12, 0, 0, -81, 0, }, /* 349 */
- { 39, 21, 12, 0, 0, 39, 0, }, /* 350 */
- { 39, 13, 12, 0, 0, 39, 0, }, /* 351 */
- { 39, 26, 12, 0, 0, 39, 0, }, /* 352 */
- { 17, 9, 12, 0, 7264, 17, 0, }, /* 353 */
- { 17, 5, 12, 0, 3008, 17, 0, }, /* 354 */
- { 10, 21, 12, 0, 0, -49, 0, }, /* 355 */
- { 17, 6, 12, 0, 0, 17, 0, }, /* 356 */
- { 24, 7, 6, 0, 0, 24, 0, }, /* 357 */
- { 24, 7, 7, 0, 0, 24, 0, }, /* 358 */
- { 24, 7, 8, 0, 0, 24, 0, }, /* 359 */
- { 16, 7, 12, 0, 0, 16, 0, }, /* 360 */
- { 16, 12, 3, 0, 0, 16, 0, }, /* 361 */
- { 16, 21, 12, 0, 0, 16, 0, }, /* 362 */
- { 16, 15, 12, 0, 0, 16, 0, }, /* 363 */
- { 16, 26, 12, 0, 0, 16, 0, }, /* 364 */
- { 9, 9, 12, 0, 38864, 9, 0, }, /* 365 */
- { 9, 9, 12, 0, 8, 9, 0, }, /* 366 */
- { 9, 5, 12, 0, -8, 9, 0, }, /* 367 */
- { 8, 17, 12, 0, 0, 8, 0, }, /* 368 */
- { 8, 7, 12, 0, 0, 8, 0, }, /* 369 */
- { 8, 26, 12, 0, 0, 8, 0, }, /* 370 */
- { 8, 21, 12, 0, 0, 8, 0, }, /* 371 */
- { 41, 29, 12, 0, 0, 41, 0, }, /* 372 */
- { 41, 7, 12, 0, 0, 41, 0, }, /* 373 */
- { 41, 22, 12, 0, 0, 41, 0, }, /* 374 */
- { 41, 18, 12, 0, 0, 41, 0, }, /* 375 */
- { 46, 7, 12, 0, 0, 46, 0, }, /* 376 */
- { 46, 14, 12, 0, 0, 46, 0, }, /* 377 */
- { 51, 7, 12, 0, 0, 51, 0, }, /* 378 */
- { 51, 12, 3, 0, 0, 51, 0, }, /* 379 */
- { 25, 7, 12, 0, 0, 25, 0, }, /* 380 */
- { 25, 12, 3, 0, 0, 25, 0, }, /* 381 */
- { 10, 21, 12, 0, 0, -115, 0, }, /* 382 */
- { 7, 7, 12, 0, 0, 7, 0, }, /* 383 */
- { 7, 12, 3, 0, 0, 7, 0, }, /* 384 */
- { 52, 7, 12, 0, 0, 52, 0, }, /* 385 */
- { 52, 12, 3, 0, 0, 52, 0, }, /* 386 */
- { 32, 7, 12, 0, 0, 32, 0, }, /* 387 */
- { 32, 12, 3, 0, 0, 32, 0, }, /* 388 */
- { 32, 10, 5, 0, 0, 32, 0, }, /* 389 */
- { 32, 21, 12, 0, 0, 32, 0, }, /* 390 */
- { 32, 6, 12, 0, 0, 32, 0, }, /* 391 */
- { 32, 23, 12, 0, 0, 32, 0, }, /* 392 */
- { 32, 13, 12, 0, 0, 32, 0, }, /* 393 */
- { 32, 15, 12, 0, 0, 32, 0, }, /* 394 */
- { 38, 21, 12, 0, 0, 38, 0, }, /* 395 */
- { 10, 21, 12, 0, 0, -70, 0, }, /* 396 */
- { 38, 17, 12, 0, 0, 38, 0, }, /* 397 */
- { 38, 12, 3, 0, 0, 38, 0, }, /* 398 */
- { 38, 1, 2, 0, 0, 38, 0, }, /* 399 */
- { 38, 13, 12, 0, 0, 38, 0, }, /* 400 */
- { 38, 7, 12, 0, 0, 38, 0, }, /* 401 */
- { 38, 6, 12, 0, 0, 38, 0, }, /* 402 */
- { 35, 7, 12, 0, 0, 35, 0, }, /* 403 */
- { 35, 12, 3, 0, 0, 35, 0, }, /* 404 */
- { 35, 10, 5, 0, 0, 35, 0, }, /* 405 */
- { 35, 26, 12, 0, 0, 35, 0, }, /* 406 */
- { 35, 21, 12, 0, 0, 35, 0, }, /* 407 */
- { 35, 13, 12, 0, 0, 35, 0, }, /* 408 */
- { 53, 7, 12, 0, 0, 53, 0, }, /* 409 */
- { 40, 7, 12, 0, 0, 40, 0, }, /* 410 */
- { 40, 13, 12, 0, 0, 40, 0, }, /* 411 */
- { 40, 15, 12, 0, 0, 40, 0, }, /* 412 */
- { 40, 26, 12, 0, 0, 40, 0, }, /* 413 */
- { 32, 26, 12, 0, 0, 32, 0, }, /* 414 */
- { 6, 7, 12, 0, 0, 6, 0, }, /* 415 */
- { 6, 12, 3, 0, 0, 6, 0, }, /* 416 */
- { 6, 10, 5, 0, 0, 6, 0, }, /* 417 */
- { 6, 21, 12, 0, 0, 6, 0, }, /* 418 */
- { 91, 7, 12, 0, 0, 91, 0, }, /* 419 */
- { 91, 10, 5, 0, 0, 91, 0, }, /* 420 */
- { 91, 12, 3, 0, 0, 91, 0, }, /* 421 */
- { 91, 10, 12, 0, 0, 91, 0, }, /* 422 */
- { 91, 13, 12, 0, 0, 91, 0, }, /* 423 */
- { 91, 21, 12, 0, 0, 91, 0, }, /* 424 */
- { 91, 6, 12, 0, 0, 91, 0, }, /* 425 */
- { 28, 11, 3, 0, 0, 28, 0, }, /* 426 */
- { 62, 12, 3, 0, 0, 62, 0, }, /* 427 */
- { 62, 10, 5, 0, 0, 62, 0, }, /* 428 */
- { 62, 7, 12, 0, 0, 62, 0, }, /* 429 */
- { 62, 10, 3, 0, 0, 62, 0, }, /* 430 */
- { 62, 13, 12, 0, 0, 62, 0, }, /* 431 */
- { 62, 21, 12, 0, 0, 62, 0, }, /* 432 */
- { 62, 26, 12, 0, 0, 62, 0, }, /* 433 */
- { 76, 12, 3, 0, 0, 76, 0, }, /* 434 */
- { 76, 10, 5, 0, 0, 76, 0, }, /* 435 */
- { 76, 7, 12, 0, 0, 76, 0, }, /* 436 */
- { 76, 13, 12, 0, 0, 76, 0, }, /* 437 */
- { 93, 7, 12, 0, 0, 93, 0, }, /* 438 */
- { 93, 12, 3, 0, 0, 93, 0, }, /* 439 */
- { 93, 10, 5, 0, 0, 93, 0, }, /* 440 */
- { 93, 21, 12, 0, 0, 93, 0, }, /* 441 */
- { 70, 7, 12, 0, 0, 70, 0, }, /* 442 */
- { 70, 10, 5, 0, 0, 70, 0, }, /* 443 */
- { 70, 12, 3, 0, 0, 70, 0, }, /* 444 */
- { 70, 21, 12, 0, 0, 70, 0, }, /* 445 */
- { 70, 13, 12, 0, 0, 70, 0, }, /* 446 */
- { 73, 13, 12, 0, 0, 73, 0, }, /* 447 */
- { 73, 7, 12, 0, 0, 73, 0, }, /* 448 */
- { 73, 6, 12, 0, 0, 73, 0, }, /* 449 */
- { 73, 21, 12, 0, 0, 73, 0, }, /* 450 */
- { 13, 5, 12, 63, -6222, 13, 0, }, /* 451 */
- { 13, 5, 12, 67, -6221, 13, 0, }, /* 452 */
- { 13, 5, 12, 71, -6212, 13, 0, }, /* 453 */
- { 13, 5, 12, 75, -6210, 13, 0, }, /* 454 */
- { 13, 5, 12, 79, -6210, 13, 0, }, /* 455 */
- { 13, 5, 12, 79, -6211, 13, 0, }, /* 456 */
- { 13, 5, 12, 84, -6204, 13, 0, }, /* 457 */
- { 13, 5, 12, 88, -6180, 13, 0, }, /* 458 */
- { 13, 5, 12, 108, 35267, 13, 0, }, /* 459 */
- { 17, 9, 12, 0, -3008, 17, 0, }, /* 460 */
- { 76, 21, 12, 0, 0, 76, 0, }, /* 461 */
- { 28, 12, 3, 0, 0, -110, 0, }, /* 462 */
- { 28, 12, 3, 0, 0, 15, 0, }, /* 463 */
- { 10, 21, 12, 0, 0, -37, 0, }, /* 464 */
- { 28, 12, 3, 0, 0, -16, 0, }, /* 465 */
- { 28, 12, 3, 0, 0, -43, 0, }, /* 466 */
- { 28, 12, 3, 0, 0, -138, 0, }, /* 467 */
- { 10, 10, 5, 0, 0, -16, 0, }, /* 468 */
- { 10, 7, 12, 0, 0, -40, 0, }, /* 469 */
- { 10, 7, 12, 0, 0, -16, 0, }, /* 470 */
- { 10, 7, 12, 0, 0, 15, 0, }, /* 471 */
- { 10, 7, 12, 0, 0, -154, 0, }, /* 472 */
- { 10, 7, 12, 0, 0, -37, 0, }, /* 473 */
- { 28, 12, 3, 0, 0, -89, 0, }, /* 474 */
- { 10, 10, 5, 0, 0, 3, 0, }, /* 475 */
- { 28, 12, 3, 0, 0, -37, 0, }, /* 476 */
- { 10, 7, 12, 0, 0, 150, 0, }, /* 477 */
- { 13, 5, 12, 0, 0, 13, 0, }, /* 478 */
- { 13, 6, 12, 0, 0, 13, 0, }, /* 479 */
- { 34, 5, 12, 0, 35332, 34, 0, }, /* 480 */
- { 34, 5, 12, 0, 3814, 34, 0, }, /* 481 */
- { 34, 5, 12, 0, 35384, 34, 0, }, /* 482 */
+ { 48, 10, 3, 0, 0, 48, 0, }, /* 321 */
+ { 48, 13, 12, 0, 0, 48, 0, }, /* 322 */
+ { 48, 21, 12, 0, 0, 48, 0, }, /* 323 */
+ { 57, 7, 12, 0, 0, 57, 0, }, /* 324 */
+ { 57, 12, 3, 0, 0, 57, 0, }, /* 325 */
+ { 57, 7, 5, 0, 0, 57, 0, }, /* 326 */
+ { 57, 6, 12, 0, 0, 57, 0, }, /* 327 */
+ { 57, 21, 12, 0, 0, 57, 0, }, /* 328 */
+ { 57, 13, 12, 0, 0, 57, 0, }, /* 329 */
+ { 33, 7, 12, 0, 0, 33, 0, }, /* 330 */
+ { 33, 12, 3, 0, 0, 33, 0, }, /* 331 */
+ { 33, 7, 5, 0, 0, 33, 0, }, /* 332 */
+ { 33, 6, 12, 0, 0, 33, 0, }, /* 333 */
+ { 33, 13, 12, 0, 0, 33, 0, }, /* 334 */
+ { 58, 7, 12, 0, 0, 58, 0, }, /* 335 */
+ { 58, 26, 12, 0, 0, 58, 0, }, /* 336 */
+ { 58, 21, 12, 0, 0, 58, 0, }, /* 337 */
+ { 58, 12, 3, 0, 0, 58, 0, }, /* 338 */
+ { 58, 13, 12, 0, 0, 58, 0, }, /* 339 */
+ { 58, 15, 12, 0, 0, 58, 0, }, /* 340 */
+ { 58, 22, 12, 0, 0, 58, 0, }, /* 341 */
+ { 58, 18, 12, 0, 0, 58, 0, }, /* 342 */
+ { 58, 10, 5, 0, 0, 58, 0, }, /* 343 */
+ { 39, 7, 12, 0, 0, 39, 0, }, /* 344 */
+ { 39, 10, 12, 0, 0, 39, 0, }, /* 345 */
+ { 39, 12, 3, 0, 0, 39, 0, }, /* 346 */
+ { 39, 10, 5, 0, 0, 39, 0, }, /* 347 */
+ { 39, 13, 12, 0, 0, -88, 0, }, /* 348 */
+ { 39, 21, 12, 0, 0, 39, 0, }, /* 349 */
+ { 39, 13, 12, 0, 0, 39, 0, }, /* 350 */
+ { 39, 26, 12, 0, 0, 39, 0, }, /* 351 */
+ { 17, 9, 12, 0, 7264, 17, 0, }, /* 352 */
+ { 17, 5, 12, 0, 3008, 17, 0, }, /* 353 */
+ { 10, 21, 12, 0, 0, -49, 0, }, /* 354 */
+ { 17, 6, 12, 0, 0, 17, 0, }, /* 355 */
+ { 24, 7, 6, 0, 0, 24, 0, }, /* 356 */
+ { 24, 7, 7, 0, 0, 24, 0, }, /* 357 */
+ { 24, 7, 8, 0, 0, 24, 0, }, /* 358 */
+ { 16, 7, 12, 0, 0, 16, 0, }, /* 359 */
+ { 16, 12, 3, 0, 0, 16, 0, }, /* 360 */
+ { 16, 21, 12, 0, 0, 16, 0, }, /* 361 */
+ { 16, 15, 12, 0, 0, 16, 0, }, /* 362 */
+ { 16, 26, 12, 0, 0, 16, 0, }, /* 363 */
+ { 9, 9, 12, 0, 38864, 9, 0, }, /* 364 */
+ { 9, 9, 12, 0, 8, 9, 0, }, /* 365 */
+ { 9, 5, 12, 0, -8, 9, 0, }, /* 366 */
+ { 8, 17, 12, 0, 0, 8, 0, }, /* 367 */
+ { 8, 7, 12, 0, 0, 8, 0, }, /* 368 */
+ { 8, 26, 12, 0, 0, 8, 0, }, /* 369 */
+ { 8, 21, 12, 0, 0, 8, 0, }, /* 370 */
+ { 41, 29, 12, 0, 0, 41, 0, }, /* 371 */
+ { 41, 7, 12, 0, 0, 41, 0, }, /* 372 */
+ { 41, 22, 12, 0, 0, 41, 0, }, /* 373 */
+ { 41, 18, 12, 0, 0, 41, 0, }, /* 374 */
+ { 46, 7, 12, 0, 0, 46, 0, }, /* 375 */
+ { 46, 14, 12, 0, 0, 46, 0, }, /* 376 */
+ { 51, 7, 12, 0, 0, 51, 0, }, /* 377 */
+ { 51, 12, 3, 0, 0, 51, 0, }, /* 378 */
+ { 25, 7, 12, 0, 0, 25, 0, }, /* 379 */
+ { 25, 12, 3, 0, 0, 25, 0, }, /* 380 */
+ { 10, 21, 12, 0, 0, -117, 0, }, /* 381 */
+ { 7, 7, 12, 0, 0, 7, 0, }, /* 382 */
+ { 7, 12, 3, 0, 0, 7, 0, }, /* 383 */
+ { 52, 7, 12, 0, 0, 52, 0, }, /* 384 */
+ { 52, 12, 3, 0, 0, 52, 0, }, /* 385 */
+ { 32, 7, 12, 0, 0, 32, 0, }, /* 386 */
+ { 32, 12, 3, 0, 0, 32, 0, }, /* 387 */
+ { 32, 10, 5, 0, 0, 32, 0, }, /* 388 */
+ { 32, 21, 12, 0, 0, 32, 0, }, /* 389 */
+ { 32, 6, 12, 0, 0, 32, 0, }, /* 390 */
+ { 32, 23, 12, 0, 0, 32, 0, }, /* 391 */
+ { 32, 13, 12, 0, 0, 32, 0, }, /* 392 */
+ { 32, 15, 12, 0, 0, 32, 0, }, /* 393 */
+ { 38, 21, 12, 0, 0, 38, 0, }, /* 394 */
+ { 10, 21, 12, 0, 0, -73, 0, }, /* 395 */
+ { 38, 17, 12, 0, 0, 38, 0, }, /* 396 */
+ { 38, 12, 3, 0, 0, 38, 0, }, /* 397 */
+ { 38, 1, 2, 0, 0, 38, 0, }, /* 398 */
+ { 38, 13, 12, 0, 0, 38, 0, }, /* 399 */
+ { 38, 7, 12, 0, 0, 38, 0, }, /* 400 */
+ { 38, 6, 12, 0, 0, 38, 0, }, /* 401 */
+ { 35, 7, 12, 0, 0, 35, 0, }, /* 402 */
+ { 35, 12, 3, 0, 0, 35, 0, }, /* 403 */
+ { 35, 10, 5, 0, 0, 35, 0, }, /* 404 */
+ { 35, 26, 12, 0, 0, 35, 0, }, /* 405 */
+ { 35, 21, 12, 0, 0, 35, 0, }, /* 406 */
+ { 35, 13, 12, 0, 0, 35, 0, }, /* 407 */
+ { 53, 7, 12, 0, 0, 53, 0, }, /* 408 */
+ { 40, 7, 12, 0, 0, 40, 0, }, /* 409 */
+ { 40, 13, 12, 0, 0, 40, 0, }, /* 410 */
+ { 40, 15, 12, 0, 0, 40, 0, }, /* 411 */
+ { 40, 26, 12, 0, 0, 40, 0, }, /* 412 */
+ { 32, 26, 12, 0, 0, 32, 0, }, /* 413 */
+ { 6, 7, 12, 0, 0, 6, 0, }, /* 414 */
+ { 6, 12, 3, 0, 0, 6, 0, }, /* 415 */
+ { 6, 10, 5, 0, 0, 6, 0, }, /* 416 */
+ { 6, 21, 12, 0, 0, 6, 0, }, /* 417 */
+ { 91, 7, 12, 0, 0, 91, 0, }, /* 418 */
+ { 91, 10, 5, 0, 0, 91, 0, }, /* 419 */
+ { 91, 12, 3, 0, 0, 91, 0, }, /* 420 */
+ { 91, 10, 12, 0, 0, 91, 0, }, /* 421 */
+ { 91, 13, 12, 0, 0, 91, 0, }, /* 422 */
+ { 91, 21, 12, 0, 0, 91, 0, }, /* 423 */
+ { 91, 6, 12, 0, 0, 91, 0, }, /* 424 */
+ { 28, 11, 3, 0, 0, 28, 0, }, /* 425 */
+ { 62, 12, 3, 0, 0, 62, 0, }, /* 426 */
+ { 62, 10, 5, 0, 0, 62, 0, }, /* 427 */
+ { 62, 7, 12, 0, 0, 62, 0, }, /* 428 */
+ { 62, 10, 3, 0, 0, 62, 0, }, /* 429 */
+ { 62, 13, 12, 0, 0, 62, 0, }, /* 430 */
+ { 62, 21, 12, 0, 0, 62, 0, }, /* 431 */
+ { 62, 26, 12, 0, 0, 62, 0, }, /* 432 */
+ { 76, 12, 3, 0, 0, 76, 0, }, /* 433 */
+ { 76, 10, 5, 0, 0, 76, 0, }, /* 434 */
+ { 76, 7, 12, 0, 0, 76, 0, }, /* 435 */
+ { 76, 13, 12, 0, 0, 76, 0, }, /* 436 */
+ { 93, 7, 12, 0, 0, 93, 0, }, /* 437 */
+ { 93, 12, 3, 0, 0, 93, 0, }, /* 438 */
+ { 93, 10, 5, 0, 0, 93, 0, }, /* 439 */
+ { 93, 21, 12, 0, 0, 93, 0, }, /* 440 */
+ { 70, 7, 12, 0, 0, 70, 0, }, /* 441 */
+ { 70, 10, 5, 0, 0, 70, 0, }, /* 442 */
+ { 70, 12, 3, 0, 0, 70, 0, }, /* 443 */
+ { 70, 21, 12, 0, 0, 70, 0, }, /* 444 */
+ { 70, 13, 12, 0, 0, 70, 0, }, /* 445 */
+ { 73, 13, 12, 0, 0, 73, 0, }, /* 446 */
+ { 73, 7, 12, 0, 0, 73, 0, }, /* 447 */
+ { 73, 6, 12, 0, 0, 73, 0, }, /* 448 */
+ { 73, 21, 12, 0, 0, 73, 0, }, /* 449 */
+ { 13, 5, 12, 63, -6222, 13, 0, }, /* 450 */
+ { 13, 5, 12, 67, -6221, 13, 0, }, /* 451 */
+ { 13, 5, 12, 71, -6212, 13, 0, }, /* 452 */
+ { 13, 5, 12, 75, -6210, 13, 0, }, /* 453 */
+ { 13, 5, 12, 79, -6210, 13, 0, }, /* 454 */
+ { 13, 5, 12, 79, -6211, 13, 0, }, /* 455 */
+ { 13, 5, 12, 84, -6204, 13, 0, }, /* 456 */
+ { 13, 5, 12, 88, -6180, 13, 0, }, /* 457 */
+ { 13, 5, 12, 108, 35267, 13, 0, }, /* 458 */
+ { 17, 9, 12, 0, -3008, 17, 0, }, /* 459 */
+ { 76, 21, 12, 0, 0, 76, 0, }, /* 460 */
+ { 28, 12, 3, 0, 0, -112, 0, }, /* 461 */
+ { 28, 12, 3, 0, 0, 15, 0, }, /* 462 */
+ { 10, 21, 12, 0, 0, -37, 0, }, /* 463 */
+ { 28, 12, 3, 0, 0, -13, 0, }, /* 464 */
+ { 28, 12, 3, 0, 0, -43, 0, }, /* 465 */
+ { 28, 12, 3, 0, 0, -146, 0, }, /* 466 */
+ { 10, 10, 5, 0, 0, -13, 0, }, /* 467 */
+ { 10, 7, 12, 0, 0, -40, 0, }, /* 468 */
+ { 10, 7, 12, 0, 0, -13, 0, }, /* 469 */
+ { 10, 7, 12, 0, 0, 15, 0, }, /* 470 */
+ { 10, 7, 12, 0, 0, -162, 0, }, /* 471 */
+ { 10, 7, 12, 0, 0, -37, 0, }, /* 472 */
+ { 28, 12, 3, 0, 0, -96, 0, }, /* 473 */
+ { 10, 10, 5, 0, 0, 3, 0, }, /* 474 */
+ { 28, 12, 3, 0, 0, -37, 0, }, /* 475 */
+ { 10, 7, 12, 0, 0, 150, 0, }, /* 476 */
+ { 13, 5, 12, 0, 0, 13, 0, }, /* 477 */
+ { 13, 6, 12, 0, 0, 13, 0, }, /* 478 */
+ { 34, 5, 12, 0, 35332, 34, 0, }, /* 479 */
+ { 34, 5, 12, 0, 3814, 34, 0, }, /* 480 */
+ { 34, 5, 12, 0, 35384, 34, 0, }, /* 481 */
+ { 28, 12, 3, 0, 0, -34, 0, }, /* 482 */
{ 34, 9, 12, 92, 1, 34, 0, }, /* 483 */
{ 34, 5, 12, 92, -1, 34, 0, }, /* 484 */
{ 34, 5, 12, 92, -58, 34, 0, }, /* 485 */
@@ -699,10 +702,10 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */
{ 28, 1, 13, 0, 0, 28, 0, }, /* 506 */
{ 10, 27, 2, 0, 0, 10, 0, }, /* 507 */
{ 10, 28, 2, 0, 0, 10, 0, }, /* 508 */
- { 10, 29, 12, 0, 0, -67, 0, }, /* 509 */
+ { 10, 29, 12, 0, 0, -70, 0, }, /* 509 */
{ 10, 21, 14, 0, 0, 10, 0, }, /* 510 */
{ 0, 2, 2, 0, 0, 0, 0, }, /* 511 */
- { 28, 12, 3, 0, 0, -93, 0, }, /* 512 */
+ { 28, 12, 3, 0, 0, -100, 0, }, /* 512 */
{ 10, 9, 12, 0, 0, 10, 0, }, /* 513 */
{ 10, 5, 12, 0, 0, 10, 0, }, /* 514 */
{ 20, 9, 12, 96, -7517, 20, 0, }, /* 515 */
@@ -743,31 +746,31 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */
{ 59, 21, 12, 0, 0, 59, 0, }, /* 550 */
{ 59, 12, 3, 0, 0, 59, 0, }, /* 551 */
{ 13, 12, 3, 0, 0, 13, 0, }, /* 552 */
- { 10, 21, 12, 0, 0, -28, 0, }, /* 553 */
+ { 10, 21, 12, 0, 0, -25, 0, }, /* 553 */
{ 23, 26, 12, 0, 0, 23, 0, }, /* 554 */
- { 10, 21, 12, 0, 0, -131, 0, }, /* 555 */
- { 10, 21, 12, 0, 0, -125, 0, }, /* 556 */
+ { 10, 21, 12, 0, 0, -139, 0, }, /* 555 */
+ { 10, 21, 12, 0, 0, -133, 0, }, /* 556 */
{ 23, 6, 12, 0, 0, 23, 0, }, /* 557 */
{ 10, 7, 12, 0, 0, 23, 0, }, /* 558 */
{ 23, 14, 12, 0, 0, 23, 0, }, /* 559 */
- { 10, 22, 12, 0, 0, -131, 0, }, /* 560 */
- { 10, 18, 12, 0, 0, -131, 0, }, /* 561 */
- { 10, 26, 12, 0, 0, -125, 0, }, /* 562 */
- { 10, 17, 12, 0, 0, -125, 0, }, /* 563 */
- { 10, 22, 12, 0, 0, -125, 0, }, /* 564 */
- { 10, 18, 12, 0, 0, -125, 0, }, /* 565 */
- { 28, 12, 3, 0, 0, -19, 0, }, /* 566 */
+ { 10, 22, 12, 0, 0, -139, 0, }, /* 560 */
+ { 10, 18, 12, 0, 0, -139, 0, }, /* 561 */
+ { 10, 26, 12, 0, 0, -133, 0, }, /* 562 */
+ { 10, 17, 12, 0, 0, -133, 0, }, /* 563 */
+ { 10, 22, 12, 0, 0, -133, 0, }, /* 564 */
+ { 10, 18, 12, 0, 0, -133, 0, }, /* 565 */
+ { 28, 12, 3, 0, 0, -16, 0, }, /* 566 */
{ 24, 10, 3, 0, 0, 24, 0, }, /* 567 */
- { 10, 17, 14, 0, 0, -125, 0, }, /* 568 */
- { 10, 6, 12, 0, 0, -61, 0, }, /* 569 */
- { 10, 7, 12, 0, 0, -97, 0, }, /* 570 */
- { 10, 21, 14, 0, 0, -97, 0, }, /* 571 */
+ { 10, 17, 14, 0, 0, -133, 0, }, /* 568 */
+ { 10, 6, 12, 0, 0, -64, 0, }, /* 569 */
+ { 10, 7, 12, 0, 0, -104, 0, }, /* 570 */
+ { 10, 21, 14, 0, 0, -104, 0, }, /* 571 */
{ 10, 26, 12, 0, 0, 23, 0, }, /* 572 */
{ 27, 7, 12, 0, 0, 27, 0, }, /* 573 */
- { 28, 12, 3, 0, 0, -61, 0, }, /* 574 */
- { 10, 24, 12, 0, 0, -61, 0, }, /* 575 */
+ { 28, 12, 3, 0, 0, -64, 0, }, /* 574 */
+ { 10, 24, 12, 0, 0, -64, 0, }, /* 575 */
{ 27, 6, 12, 0, 0, 27, 0, }, /* 576 */
- { 10, 17, 12, 0, 0, -61, 0, }, /* 577 */
+ { 10, 17, 12, 0, 0, -64, 0, }, /* 577 */
{ 30, 7, 12, 0, 0, 30, 0, }, /* 578 */
{ 30, 6, 12, 0, 0, 30, 0, }, /* 579 */
{ 4, 7, 12, 0, 0, 4, 0, }, /* 580 */
@@ -795,360 +798,376 @@ const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */
{ 79, 14, 12, 0, 0, 79, 0, }, /* 602 */
{ 79, 12, 3, 0, 0, 79, 0, }, /* 603 */
{ 79, 21, 12, 0, 0, 79, 0, }, /* 604 */
- { 34, 9, 12, 0, -35332, 34, 0, }, /* 605 */
- { 34, 9, 12, 0, -42280, 34, 0, }, /* 606 */
- { 34, 5, 12, 0, 48, 34, 0, }, /* 607 */
- { 34, 9, 12, 0, -42308, 34, 0, }, /* 608 */
- { 34, 9, 12, 0, -42319, 34, 0, }, /* 609 */
- { 34, 9, 12, 0, -42315, 34, 0, }, /* 610 */
- { 34, 9, 12, 0, -42305, 34, 0, }, /* 611 */
- { 34, 9, 12, 0, -42258, 34, 0, }, /* 612 */
- { 34, 9, 12, 0, -42282, 34, 0, }, /* 613 */
- { 34, 9, 12, 0, -42261, 34, 0, }, /* 614 */
- { 34, 9, 12, 0, 928, 34, 0, }, /* 615 */
- { 34, 9, 12, 0, -48, 34, 0, }, /* 616 */
- { 34, 9, 12, 0, -42307, 34, 0, }, /* 617 */
- { 34, 9, 12, 0, -35384, 34, 0, }, /* 618 */
- { 49, 7, 12, 0, 0, 49, 0, }, /* 619 */
- { 49, 12, 3, 0, 0, 49, 0, }, /* 620 */
- { 49, 10, 5, 0, 0, 49, 0, }, /* 621 */
- { 49, 26, 12, 0, 0, 49, 0, }, /* 622 */
- { 10, 15, 12, 0, 0, -216, 0, }, /* 623 */
- { 10, 15, 12, 0, 0, -202, 0, }, /* 624 */
- { 10, 26, 12, 0, 0, -163, 0, }, /* 625 */
- { 10, 23, 12, 0, 0, -163, 0, }, /* 626 */
- { 65, 7, 12, 0, 0, 65, 0, }, /* 627 */
- { 65, 21, 12, 0, 0, 65, 0, }, /* 628 */
- { 75, 10, 5, 0, 0, 75, 0, }, /* 629 */
- { 75, 7, 12, 0, 0, 75, 0, }, /* 630 */
- { 75, 12, 3, 0, 0, 75, 0, }, /* 631 */
- { 75, 21, 12, 0, 0, 75, 0, }, /* 632 */
- { 75, 13, 12, 0, 0, 75, 0, }, /* 633 */
- { 15, 12, 3, 0, 0, -16, 0, }, /* 634 */
- { 15, 7, 12, 0, 0, -46, 0, }, /* 635 */
- { 69, 13, 12, 0, 0, 69, 0, }, /* 636 */
- { 69, 7, 12, 0, 0, 69, 0, }, /* 637 */
- { 69, 12, 3, 0, 0, 69, 0, }, /* 638 */
- { 10, 21, 12, 0, 0, -101, 0, }, /* 639 */
- { 69, 21, 12, 0, 0, 69, 0, }, /* 640 */
- { 74, 7, 12, 0, 0, 74, 0, }, /* 641 */
- { 74, 12, 3, 0, 0, 74, 0, }, /* 642 */
- { 74, 10, 5, 0, 0, 74, 0, }, /* 643 */
- { 74, 21, 12, 0, 0, 74, 0, }, /* 644 */
- { 84, 12, 3, 0, 0, 84, 0, }, /* 645 */
- { 84, 10, 5, 0, 0, 84, 0, }, /* 646 */
- { 84, 7, 12, 0, 0, 84, 0, }, /* 647 */
- { 84, 21, 12, 0, 0, 84, 0, }, /* 648 */
- { 10, 6, 12, 0, 0, -22, 0, }, /* 649 */
- { 84, 13, 12, 0, 0, 84, 0, }, /* 650 */
- { 39, 6, 12, 0, 0, 39, 0, }, /* 651 */
- { 68, 7, 12, 0, 0, 68, 0, }, /* 652 */
- { 68, 12, 3, 0, 0, 68, 0, }, /* 653 */
- { 68, 10, 5, 0, 0, 68, 0, }, /* 654 */
- { 68, 13, 12, 0, 0, 68, 0, }, /* 655 */
- { 68, 21, 12, 0, 0, 68, 0, }, /* 656 */
- { 92, 7, 12, 0, 0, 92, 0, }, /* 657 */
- { 92, 12, 3, 0, 0, 92, 0, }, /* 658 */
- { 92, 6, 12, 0, 0, 92, 0, }, /* 659 */
- { 92, 21, 12, 0, 0, 92, 0, }, /* 660 */
- { 87, 7, 12, 0, 0, 87, 0, }, /* 661 */
- { 87, 10, 5, 0, 0, 87, 0, }, /* 662 */
- { 87, 12, 3, 0, 0, 87, 0, }, /* 663 */
- { 87, 21, 12, 0, 0, 87, 0, }, /* 664 */
- { 87, 6, 12, 0, 0, 87, 0, }, /* 665 */
- { 34, 5, 12, 0, -928, 34, 0, }, /* 666 */
- { 9, 5, 12, 0, -38864, 9, 0, }, /* 667 */
- { 87, 13, 12, 0, 0, 87, 0, }, /* 668 */
- { 24, 7, 9, 0, 0, 24, 0, }, /* 669 */
- { 24, 7, 10, 0, 0, 24, 0, }, /* 670 */
- { 0, 4, 12, 0, 0, 0, 0, }, /* 671 */
- { 0, 3, 12, 0, 0, 0, 0, }, /* 672 */
- { 26, 25, 12, 0, 0, 26, 0, }, /* 673 */
- { 1, 24, 12, 0, 0, 1, 0, }, /* 674 */
- { 1, 7, 12, 0, 0, -10, 0, }, /* 675 */
- { 1, 26, 12, 0, 0, -10, 0, }, /* 676 */
- { 10, 6, 3, 0, 0, -61, 0, }, /* 677 */
- { 36, 7, 12, 0, 0, 36, 0, }, /* 678 */
- { 10, 21, 12, 0, 0, -25, 0, }, /* 679 */
- { 10, 15, 12, 0, 0, -85, 0, }, /* 680 */
- { 10, 26, 12, 0, 0, -25, 0, }, /* 681 */
- { 20, 14, 12, 0, 0, 20, 0, }, /* 682 */
- { 20, 15, 12, 0, 0, 20, 0, }, /* 683 */
- { 20, 26, 12, 0, 0, 20, 0, }, /* 684 */
- { 71, 7, 12, 0, 0, 71, 0, }, /* 685 */
- { 67, 7, 12, 0, 0, 67, 0, }, /* 686 */
- { 28, 12, 3, 0, 0, -1, 0, }, /* 687 */
- { 10, 15, 12, 0, 0, -1, 0, }, /* 688 */
- { 42, 7, 12, 0, 0, 42, 0, }, /* 689 */
- { 42, 15, 12, 0, 0, 42, 0, }, /* 690 */
- { 19, 7, 12, 0, 0, 19, 0, }, /* 691 */
- { 19, 14, 12, 0, 0, 19, 0, }, /* 692 */
- { 118, 7, 12, 0, 0, 118, 0, }, /* 693 */
- { 118, 12, 3, 0, 0, 118, 0, }, /* 694 */
- { 60, 7, 12, 0, 0, 60, 0, }, /* 695 */
- { 60, 21, 12, 0, 0, 60, 0, }, /* 696 */
- { 43, 7, 12, 0, 0, 43, 0, }, /* 697 */
- { 43, 21, 12, 0, 0, 43, 0, }, /* 698 */
- { 43, 14, 12, 0, 0, 43, 0, }, /* 699 */
- { 14, 9, 12, 0, 40, 14, 0, }, /* 700 */
- { 14, 5, 12, 0, -40, 14, 0, }, /* 701 */
- { 47, 7, 12, 0, 0, 47, 0, }, /* 702 */
- { 45, 7, 12, 0, 0, 45, 0, }, /* 703 */
- { 45, 13, 12, 0, 0, 45, 0, }, /* 704 */
- { 136, 9, 12, 0, 40, 136, 0, }, /* 705 */
- { 136, 5, 12, 0, -40, 136, 0, }, /* 706 */
- { 106, 7, 12, 0, 0, 106, 0, }, /* 707 */
- { 104, 7, 12, 0, 0, 104, 0, }, /* 708 */
- { 104, 21, 12, 0, 0, 104, 0, }, /* 709 */
- { 110, 7, 12, 0, 0, 110, 0, }, /* 710 */
- { 12, 7, 12, 0, 0, 12, 0, }, /* 711 */
- { 81, 7, 12, 0, 0, 81, 0, }, /* 712 */
- { 81, 21, 12, 0, 0, 81, 0, }, /* 713 */
- { 81, 15, 12, 0, 0, 81, 0, }, /* 714 */
- { 120, 7, 12, 0, 0, 120, 0, }, /* 715 */
- { 120, 26, 12, 0, 0, 120, 0, }, /* 716 */
- { 120, 15, 12, 0, 0, 120, 0, }, /* 717 */
- { 116, 7, 12, 0, 0, 116, 0, }, /* 718 */
- { 116, 15, 12, 0, 0, 116, 0, }, /* 719 */
- { 128, 7, 12, 0, 0, 128, 0, }, /* 720 */
- { 128, 15, 12, 0, 0, 128, 0, }, /* 721 */
- { 66, 7, 12, 0, 0, 66, 0, }, /* 722 */
- { 66, 15, 12, 0, 0, 66, 0, }, /* 723 */
- { 66, 21, 12, 0, 0, 66, 0, }, /* 724 */
- { 72, 7, 12, 0, 0, 72, 0, }, /* 725 */
- { 72, 21, 12, 0, 0, 72, 0, }, /* 726 */
- { 98, 7, 12, 0, 0, 98, 0, }, /* 727 */
- { 97, 7, 12, 0, 0, 97, 0, }, /* 728 */
- { 97, 15, 12, 0, 0, 97, 0, }, /* 729 */
- { 31, 7, 12, 0, 0, 31, 0, }, /* 730 */
- { 31, 12, 3, 0, 0, 31, 0, }, /* 731 */
- { 31, 15, 12, 0, 0, 31, 0, }, /* 732 */
- { 31, 21, 12, 0, 0, 31, 0, }, /* 733 */
- { 88, 7, 12, 0, 0, 88, 0, }, /* 734 */
- { 88, 15, 12, 0, 0, 88, 0, }, /* 735 */
- { 88, 21, 12, 0, 0, 88, 0, }, /* 736 */
- { 117, 7, 12, 0, 0, 117, 0, }, /* 737 */
- { 117, 15, 12, 0, 0, 117, 0, }, /* 738 */
- { 112, 7, 12, 0, 0, 112, 0, }, /* 739 */
- { 112, 26, 12, 0, 0, 112, 0, }, /* 740 */
- { 112, 12, 3, 0, 0, 112, 0, }, /* 741 */
- { 112, 15, 12, 0, 0, 112, 0, }, /* 742 */
- { 112, 21, 12, 0, 0, 112, 0, }, /* 743 */
- { 78, 7, 12, 0, 0, 78, 0, }, /* 744 */
- { 78, 21, 12, 0, 0, 78, 0, }, /* 745 */
- { 83, 7, 12, 0, 0, 83, 0, }, /* 746 */
- { 83, 15, 12, 0, 0, 83, 0, }, /* 747 */
- { 82, 7, 12, 0, 0, 82, 0, }, /* 748 */
- { 82, 15, 12, 0, 0, 82, 0, }, /* 749 */
- { 121, 7, 12, 0, 0, 121, 0, }, /* 750 */
- { 121, 21, 12, 0, 0, 121, 0, }, /* 751 */
- { 121, 15, 12, 0, 0, 121, 0, }, /* 752 */
- { 89, 7, 12, 0, 0, 89, 0, }, /* 753 */
- { 130, 9, 12, 0, 64, 130, 0, }, /* 754 */
- { 130, 5, 12, 0, -64, 130, 0, }, /* 755 */
- { 130, 15, 12, 0, 0, 130, 0, }, /* 756 */
- { 144, 7, 12, 0, 0, 144, 0, }, /* 757 */
- { 144, 12, 3, 0, 0, 144, 0, }, /* 758 */
- { 144, 13, 12, 0, 0, 144, 0, }, /* 759 */
- { 1, 15, 12, 0, 0, 1, 0, }, /* 760 */
- { 147, 7, 12, 0, 0, 147, 0, }, /* 761 */
- { 147, 15, 12, 0, 0, 147, 0, }, /* 762 */
- { 148, 7, 12, 0, 0, 148, 0, }, /* 763 */
- { 148, 12, 3, 0, 0, 148, 0, }, /* 764 */
- { 148, 15, 12, 0, 0, 148, 0, }, /* 765 */
- { 148, 21, 12, 0, 0, 148, 0, }, /* 766 */
- { 149, 7, 12, 0, 0, 149, 0, }, /* 767 */
- { 94, 10, 5, 0, 0, 94, 0, }, /* 768 */
- { 94, 12, 3, 0, 0, 94, 0, }, /* 769 */
- { 94, 7, 12, 0, 0, 94, 0, }, /* 770 */
- { 94, 21, 12, 0, 0, 94, 0, }, /* 771 */
- { 94, 15, 12, 0, 0, 94, 0, }, /* 772 */
- { 94, 13, 12, 0, 0, 94, 0, }, /* 773 */
- { 85, 12, 3, 0, 0, 85, 0, }, /* 774 */
- { 85, 10, 5, 0, 0, 85, 0, }, /* 775 */
- { 85, 7, 12, 0, 0, 85, 0, }, /* 776 */
- { 85, 21, 12, 0, 0, 85, 0, }, /* 777 */
- { 85, 1, 4, 0, 0, 85, 0, }, /* 778 */
- { 101, 7, 12, 0, 0, 101, 0, }, /* 779 */
- { 101, 13, 12, 0, 0, 101, 0, }, /* 780 */
- { 96, 12, 3, 0, 0, 96, 0, }, /* 781 */
- { 96, 7, 12, 0, 0, 96, 0, }, /* 782 */
- { 96, 10, 5, 0, 0, 96, 0, }, /* 783 */
- { 96, 13, 12, 0, 0, 96, 0, }, /* 784 */
- { 96, 21, 12, 0, 0, 96, 0, }, /* 785 */
- { 111, 7, 12, 0, 0, 111, 0, }, /* 786 */
- { 111, 12, 3, 0, 0, 111, 0, }, /* 787 */
- { 111, 21, 12, 0, 0, 111, 0, }, /* 788 */
- { 100, 12, 3, 0, 0, 100, 0, }, /* 789 */
- { 100, 10, 5, 0, 0, 100, 0, }, /* 790 */
- { 100, 7, 12, 0, 0, 100, 0, }, /* 791 */
- { 100, 7, 4, 0, 0, 100, 0, }, /* 792 */
- { 100, 21, 12, 0, 0, 100, 0, }, /* 793 */
- { 100, 13, 12, 0, 0, 100, 0, }, /* 794 */
- { 48, 15, 12, 0, 0, 48, 0, }, /* 795 */
- { 108, 7, 12, 0, 0, 108, 0, }, /* 796 */
- { 108, 10, 5, 0, 0, 108, 0, }, /* 797 */
- { 108, 12, 3, 0, 0, 108, 0, }, /* 798 */
- { 108, 21, 12, 0, 0, 108, 0, }, /* 799 */
- { 129, 7, 12, 0, 0, 129, 0, }, /* 800 */
- { 129, 21, 12, 0, 0, 129, 0, }, /* 801 */
- { 109, 7, 12, 0, 0, 109, 0, }, /* 802 */
- { 109, 12, 3, 0, 0, 109, 0, }, /* 803 */
- { 109, 10, 5, 0, 0, 109, 0, }, /* 804 */
- { 109, 13, 12, 0, 0, 109, 0, }, /* 805 */
- { 107, 12, 3, 0, 0, 107, 0, }, /* 806 */
- { 107, 12, 3, 0, 0, -52, 0, }, /* 807 */
- { 107, 10, 5, 0, 0, 107, 0, }, /* 808 */
- { 107, 10, 5, 0, 0, -52, 0, }, /* 809 */
- { 107, 7, 12, 0, 0, 107, 0, }, /* 810 */
- { 28, 12, 3, 0, 0, -52, 0, }, /* 811 */
- { 107, 10, 3, 0, 0, 107, 0, }, /* 812 */
- { 135, 7, 12, 0, 0, 135, 0, }, /* 813 */
- { 135, 10, 5, 0, 0, 135, 0, }, /* 814 */
- { 135, 12, 3, 0, 0, 135, 0, }, /* 815 */
- { 135, 21, 12, 0, 0, 135, 0, }, /* 816 */
- { 135, 13, 12, 0, 0, 135, 0, }, /* 817 */
- { 124, 7, 12, 0, 0, 124, 0, }, /* 818 */
- { 124, 10, 3, 0, 0, 124, 0, }, /* 819 */
- { 124, 10, 5, 0, 0, 124, 0, }, /* 820 */
- { 124, 12, 3, 0, 0, 124, 0, }, /* 821 */
- { 124, 21, 12, 0, 0, 124, 0, }, /* 822 */
- { 124, 13, 12, 0, 0, 124, 0, }, /* 823 */
- { 123, 7, 12, 0, 0, 123, 0, }, /* 824 */
- { 123, 10, 3, 0, 0, 123, 0, }, /* 825 */
- { 123, 10, 5, 0, 0, 123, 0, }, /* 826 */
- { 123, 12, 3, 0, 0, 123, 0, }, /* 827 */
- { 123, 21, 12, 0, 0, 123, 0, }, /* 828 */
- { 114, 7, 12, 0, 0, 114, 0, }, /* 829 */
- { 114, 10, 5, 0, 0, 114, 0, }, /* 830 */
- { 114, 12, 3, 0, 0, 114, 0, }, /* 831 */
- { 114, 21, 12, 0, 0, 114, 0, }, /* 832 */
- { 114, 13, 12, 0, 0, 114, 0, }, /* 833 */
- { 102, 7, 12, 0, 0, 102, 0, }, /* 834 */
- { 102, 12, 3, 0, 0, 102, 0, }, /* 835 */
- { 102, 10, 5, 0, 0, 102, 0, }, /* 836 */
- { 102, 13, 12, 0, 0, 102, 0, }, /* 837 */
- { 126, 7, 12, 0, 0, 126, 0, }, /* 838 */
- { 126, 12, 3, 0, 0, 126, 0, }, /* 839 */
- { 126, 10, 5, 0, 0, 126, 0, }, /* 840 */
- { 126, 13, 12, 0, 0, 126, 0, }, /* 841 */
- { 126, 15, 12, 0, 0, 126, 0, }, /* 842 */
- { 126, 21, 12, 0, 0, 126, 0, }, /* 843 */
- { 126, 26, 12, 0, 0, 126, 0, }, /* 844 */
- { 142, 7, 12, 0, 0, 142, 0, }, /* 845 */
- { 142, 10, 5, 0, 0, 142, 0, }, /* 846 */
- { 142, 12, 3, 0, 0, 142, 0, }, /* 847 */
- { 142, 21, 12, 0, 0, 142, 0, }, /* 848 */
- { 125, 9, 12, 0, 32, 125, 0, }, /* 849 */
- { 125, 5, 12, 0, -32, 125, 0, }, /* 850 */
- { 125, 13, 12, 0, 0, 125, 0, }, /* 851 */
- { 125, 15, 12, 0, 0, 125, 0, }, /* 852 */
- { 125, 7, 12, 0, 0, 125, 0, }, /* 853 */
- { 150, 7, 12, 0, 0, 150, 0, }, /* 854 */
- { 150, 10, 5, 0, 0, 150, 0, }, /* 855 */
- { 150, 12, 3, 0, 0, 150, 0, }, /* 856 */
- { 150, 21, 12, 0, 0, 150, 0, }, /* 857 */
- { 141, 7, 12, 0, 0, 141, 0, }, /* 858 */
- { 141, 12, 3, 0, 0, 141, 0, }, /* 859 */
- { 141, 10, 5, 0, 0, 141, 0, }, /* 860 */
- { 141, 7, 4, 0, 0, 141, 0, }, /* 861 */
- { 141, 21, 12, 0, 0, 141, 0, }, /* 862 */
- { 140, 7, 12, 0, 0, 140, 0, }, /* 863 */
- { 140, 12, 3, 0, 0, 140, 0, }, /* 864 */
- { 140, 10, 5, 0, 0, 140, 0, }, /* 865 */
- { 140, 7, 4, 0, 0, 140, 0, }, /* 866 */
- { 140, 21, 12, 0, 0, 140, 0, }, /* 867 */
- { 122, 7, 12, 0, 0, 122, 0, }, /* 868 */
- { 133, 7, 12, 0, 0, 133, 0, }, /* 869 */
- { 133, 10, 5, 0, 0, 133, 0, }, /* 870 */
- { 133, 12, 3, 0, 0, 133, 0, }, /* 871 */
- { 133, 21, 12, 0, 0, 133, 0, }, /* 872 */
- { 133, 13, 12, 0, 0, 133, 0, }, /* 873 */
- { 133, 15, 12, 0, 0, 133, 0, }, /* 874 */
- { 134, 21, 12, 0, 0, 134, 0, }, /* 875 */
- { 134, 7, 12, 0, 0, 134, 0, }, /* 876 */
- { 134, 12, 3, 0, 0, 134, 0, }, /* 877 */
- { 134, 10, 5, 0, 0, 134, 0, }, /* 878 */
- { 138, 7, 12, 0, 0, 138, 0, }, /* 879 */
- { 138, 12, 3, 0, 0, 138, 0, }, /* 880 */
- { 138, 7, 4, 0, 0, 138, 0, }, /* 881 */
- { 138, 13, 12, 0, 0, 138, 0, }, /* 882 */
- { 143, 7, 12, 0, 0, 143, 0, }, /* 883 */
- { 143, 10, 5, 0, 0, 143, 0, }, /* 884 */
- { 143, 12, 3, 0, 0, 143, 0, }, /* 885 */
- { 143, 13, 12, 0, 0, 143, 0, }, /* 886 */
- { 145, 7, 12, 0, 0, 145, 0, }, /* 887 */
- { 145, 12, 3, 0, 0, 145, 0, }, /* 888 */
- { 145, 10, 5, 0, 0, 145, 0, }, /* 889 */
- { 145, 21, 12, 0, 0, 145, 0, }, /* 890 */
- { 54, 15, 12, 0, 0, 54, 0, }, /* 891 */
- { 54, 21, 12, 0, 0, 54, 0, }, /* 892 */
- { 63, 7, 12, 0, 0, 63, 0, }, /* 893 */
- { 63, 14, 12, 0, 0, 63, 0, }, /* 894 */
- { 63, 21, 12, 0, 0, 63, 0, }, /* 895 */
- { 80, 7, 12, 0, 0, 80, 0, }, /* 896 */
- { 80, 1, 2, 0, 0, 80, 0, }, /* 897 */
- { 127, 7, 12, 0, 0, 127, 0, }, /* 898 */
- { 115, 7, 12, 0, 0, 115, 0, }, /* 899 */
- { 115, 13, 12, 0, 0, 115, 0, }, /* 900 */
- { 115, 21, 12, 0, 0, 115, 0, }, /* 901 */
- { 103, 7, 12, 0, 0, 103, 0, }, /* 902 */
- { 103, 12, 3, 0, 0, 103, 0, }, /* 903 */
- { 103, 21, 12, 0, 0, 103, 0, }, /* 904 */
- { 119, 7, 12, 0, 0, 119, 0, }, /* 905 */
- { 119, 12, 3, 0, 0, 119, 0, }, /* 906 */
- { 119, 21, 12, 0, 0, 119, 0, }, /* 907 */
- { 119, 26, 12, 0, 0, 119, 0, }, /* 908 */
- { 119, 6, 12, 0, 0, 119, 0, }, /* 909 */
- { 119, 13, 12, 0, 0, 119, 0, }, /* 910 */
- { 119, 15, 12, 0, 0, 119, 0, }, /* 911 */
- { 146, 9, 12, 0, 32, 146, 0, }, /* 912 */
- { 146, 5, 12, 0, -32, 146, 0, }, /* 913 */
- { 146, 15, 12, 0, 0, 146, 0, }, /* 914 */
- { 146, 21, 12, 0, 0, 146, 0, }, /* 915 */
- { 99, 7, 12, 0, 0, 99, 0, }, /* 916 */
- { 99, 12, 3, 0, 0, 99, 0, }, /* 917 */
- { 99, 10, 5, 0, 0, 99, 0, }, /* 918 */
- { 99, 6, 12, 0, 0, 99, 0, }, /* 919 */
- { 137, 6, 12, 0, 0, 137, 0, }, /* 920 */
- { 139, 6, 12, 0, 0, 139, 0, }, /* 921 */
- { 137, 7, 12, 0, 0, 137, 0, }, /* 922 */
- { 139, 7, 12, 0, 0, 139, 0, }, /* 923 */
- { 105, 7, 12, 0, 0, 105, 0, }, /* 924 */
- { 105, 26, 12, 0, 0, 105, 0, }, /* 925 */
- { 105, 12, 3, 0, 0, 105, 0, }, /* 926 */
- { 105, 21, 12, 0, 0, 105, 0, }, /* 927 */
- { 10, 1, 2, 0, 0, 105, 0, }, /* 928 */
- { 10, 10, 3, 0, 0, 10, 0, }, /* 929 */
- { 10, 10, 5, 0, 0, 10, 0, }, /* 930 */
- { 20, 12, 3, 0, 0, 20, 0, }, /* 931 */
- { 131, 26, 12, 0, 0, 131, 0, }, /* 932 */
- { 131, 12, 3, 0, 0, 131, 0, }, /* 933 */
- { 131, 21, 12, 0, 0, 131, 0, }, /* 934 */
- { 18, 12, 3, 0, 0, 18, 0, }, /* 935 */
- { 151, 7, 12, 0, 0, 151, 0, }, /* 936 */
- { 151, 12, 3, 0, 0, 151, 0, }, /* 937 */
- { 151, 6, 12, 0, 0, 151, 0, }, /* 938 */
- { 151, 13, 12, 0, 0, 151, 0, }, /* 939 */
- { 151, 26, 12, 0, 0, 151, 0, }, /* 940 */
- { 152, 7, 12, 0, 0, 152, 0, }, /* 941 */
- { 152, 12, 3, 0, 0, 152, 0, }, /* 942 */
- { 152, 13, 12, 0, 0, 152, 0, }, /* 943 */
- { 152, 23, 12, 0, 0, 152, 0, }, /* 944 */
- { 113, 7, 12, 0, 0, 113, 0, }, /* 945 */
- { 113, 15, 12, 0, 0, 113, 0, }, /* 946 */
- { 113, 12, 3, 0, 0, 113, 0, }, /* 947 */
- { 132, 9, 12, 0, 34, 132, 0, }, /* 948 */
- { 132, 5, 12, 0, -34, 132, 0, }, /* 949 */
- { 132, 12, 3, 0, 0, 132, 0, }, /* 950 */
- { 132, 6, 12, 0, 0, 132, 0, }, /* 951 */
- { 132, 13, 12, 0, 0, 132, 0, }, /* 952 */
- { 132, 21, 12, 0, 0, 132, 0, }, /* 953 */
- { 0, 2, 14, 0, 0, 0, 0, }, /* 954 */
- { 10, 26, 11, 0, 0, 10, 0, }, /* 955 */
- { 27, 26, 12, 0, 0, 27, 0, }, /* 956 */
- { 10, 24, 3, 0, 0, 10, 0, }, /* 957 */
- { 10, 1, 3, 0, 0, 10, 0, }, /* 958 */
+ { 10, 24, 12, 0, 0, -61, 0, }, /* 605 */
+ { 34, 9, 12, 0, -35332, 34, 0, }, /* 606 */
+ { 34, 9, 12, 0, -42280, 34, 0, }, /* 607 */
+ { 34, 5, 12, 0, 48, 34, 0, }, /* 608 */
+ { 34, 9, 12, 0, -42308, 34, 0, }, /* 609 */
+ { 34, 9, 12, 0, -42319, 34, 0, }, /* 610 */
+ { 34, 9, 12, 0, -42315, 34, 0, }, /* 611 */
+ { 34, 9, 12, 0, -42305, 34, 0, }, /* 612 */
+ { 34, 9, 12, 0, -42258, 34, 0, }, /* 613 */
+ { 34, 9, 12, 0, -42282, 34, 0, }, /* 614 */
+ { 34, 9, 12, 0, -42261, 34, 0, }, /* 615 */
+ { 34, 9, 12, 0, 928, 34, 0, }, /* 616 */
+ { 34, 9, 12, 0, -48, 34, 0, }, /* 617 */
+ { 34, 9, 12, 0, -42307, 34, 0, }, /* 618 */
+ { 34, 9, 12, 0, -35384, 34, 0, }, /* 619 */
+ { 49, 7, 12, 0, 0, 49, 0, }, /* 620 */
+ { 49, 12, 3, 0, 0, 49, 0, }, /* 621 */
+ { 49, 10, 5, 0, 0, 49, 0, }, /* 622 */
+ { 49, 26, 12, 0, 0, 49, 0, }, /* 623 */
+ { 10, 15, 12, 0, 0, -224, 0, }, /* 624 */
+ { 10, 15, 12, 0, 0, -210, 0, }, /* 625 */
+ { 10, 26, 12, 0, 0, -171, 0, }, /* 626 */
+ { 10, 23, 12, 0, 0, -171, 0, }, /* 627 */
+ { 65, 7, 12, 0, 0, 65, 0, }, /* 628 */
+ { 65, 21, 12, 0, 0, 65, 0, }, /* 629 */
+ { 75, 10, 5, 0, 0, 75, 0, }, /* 630 */
+ { 75, 7, 12, 0, 0, 75, 0, }, /* 631 */
+ { 75, 12, 3, 0, 0, 75, 0, }, /* 632 */
+ { 75, 21, 12, 0, 0, 75, 0, }, /* 633 */
+ { 75, 13, 12, 0, 0, 75, 0, }, /* 634 */
+ { 15, 12, 3, 0, 0, -13, 0, }, /* 635 */
+ { 15, 7, 12, 0, 0, -46, 0, }, /* 636 */
+ { 69, 13, 12, 0, 0, 69, 0, }, /* 637 */
+ { 69, 7, 12, 0, 0, 69, 0, }, /* 638 */
+ { 69, 12, 3, 0, 0, 69, 0, }, /* 639 */
+ { 10, 21, 12, 0, 0, -108, 0, }, /* 640 */
+ { 69, 21, 12, 0, 0, 69, 0, }, /* 641 */
+ { 74, 7, 12, 0, 0, 74, 0, }, /* 642 */
+ { 74, 12, 3, 0, 0, 74, 0, }, /* 643 */
+ { 74, 10, 5, 0, 0, 74, 0, }, /* 644 */
+ { 74, 21, 12, 0, 0, 74, 0, }, /* 645 */
+ { 84, 12, 3, 0, 0, 84, 0, }, /* 646 */
+ { 84, 10, 5, 0, 0, 84, 0, }, /* 647 */
+ { 84, 7, 12, 0, 0, 84, 0, }, /* 648 */
+ { 84, 21, 12, 0, 0, 84, 0, }, /* 649 */
+ { 10, 6, 12, 0, 0, -19, 0, }, /* 650 */
+ { 84, 13, 12, 0, 0, 84, 0, }, /* 651 */
+ { 39, 6, 12, 0, 0, 39, 0, }, /* 652 */
+ { 68, 7, 12, 0, 0, 68, 0, }, /* 653 */
+ { 68, 12, 3, 0, 0, 68, 0, }, /* 654 */
+ { 68, 10, 5, 0, 0, 68, 0, }, /* 655 */
+ { 68, 13, 12, 0, 0, 68, 0, }, /* 656 */
+ { 68, 21, 12, 0, 0, 68, 0, }, /* 657 */
+ { 92, 7, 12, 0, 0, 92, 0, }, /* 658 */
+ { 92, 12, 3, 0, 0, 92, 0, }, /* 659 */
+ { 92, 6, 12, 0, 0, 92, 0, }, /* 660 */
+ { 92, 21, 12, 0, 0, 92, 0, }, /* 661 */
+ { 87, 7, 12, 0, 0, 87, 0, }, /* 662 */
+ { 87, 10, 5, 0, 0, 87, 0, }, /* 663 */
+ { 87, 12, 3, 0, 0, 87, 0, }, /* 664 */
+ { 87, 21, 12, 0, 0, 87, 0, }, /* 665 */
+ { 87, 6, 12, 0, 0, 87, 0, }, /* 666 */
+ { 34, 5, 12, 0, -928, 34, 0, }, /* 667 */
+ { 9, 5, 12, 0, -38864, 9, 0, }, /* 668 */
+ { 87, 13, 12, 0, 0, 87, 0, }, /* 669 */
+ { 24, 7, 9, 0, 0, 24, 0, }, /* 670 */
+ { 24, 7, 10, 0, 0, 24, 0, }, /* 671 */
+ { 0, 4, 12, 0, 0, 0, 0, }, /* 672 */
+ { 0, 3, 12, 0, 0, 0, 0, }, /* 673 */
+ { 26, 25, 12, 0, 0, 26, 0, }, /* 674 */
+ { 1, 24, 12, 0, 0, 1, 0, }, /* 675 */
+ { 1, 7, 12, 0, 0, -10, 0, }, /* 676 */
+ { 1, 26, 12, 0, 0, -10, 0, }, /* 677 */
+ { 10, 6, 3, 0, 0, -64, 0, }, /* 678 */
+ { 36, 7, 12, 0, 0, 36, 0, }, /* 679 */
+ { 10, 21, 12, 0, 0, -22, 0, }, /* 680 */
+ { 10, 15, 12, 0, 0, -92, 0, }, /* 681 */
+ { 10, 26, 12, 0, 0, -22, 0, }, /* 682 */
+ { 20, 14, 12, 0, 0, 20, 0, }, /* 683 */
+ { 20, 15, 12, 0, 0, 20, 0, }, /* 684 */
+ { 20, 26, 12, 0, 0, 20, 0, }, /* 685 */
+ { 71, 7, 12, 0, 0, 71, 0, }, /* 686 */
+ { 67, 7, 12, 0, 0, 67, 0, }, /* 687 */
+ { 28, 12, 3, 0, 0, -1, 0, }, /* 688 */
+ { 10, 15, 12, 0, 0, -1, 0, }, /* 689 */
+ { 42, 7, 12, 0, 0, 42, 0, }, /* 690 */
+ { 42, 15, 12, 0, 0, 42, 0, }, /* 691 */
+ { 19, 7, 12, 0, 0, 19, 0, }, /* 692 */
+ { 19, 14, 12, 0, 0, 19, 0, }, /* 693 */
+ { 118, 7, 12, 0, 0, 118, 0, }, /* 694 */
+ { 118, 12, 3, 0, 0, 118, 0, }, /* 695 */
+ { 60, 7, 12, 0, 0, 60, 0, }, /* 696 */
+ { 60, 21, 12, 0, 0, 60, 0, }, /* 697 */
+ { 43, 7, 12, 0, 0, 43, 0, }, /* 698 */
+ { 43, 21, 12, 0, 0, 43, 0, }, /* 699 */
+ { 43, 14, 12, 0, 0, 43, 0, }, /* 700 */
+ { 14, 9, 12, 0, 40, 14, 0, }, /* 701 */
+ { 14, 5, 12, 0, -40, 14, 0, }, /* 702 */
+ { 47, 7, 12, 0, 0, 47, 0, }, /* 703 */
+ { 45, 7, 12, 0, 0, 45, 0, }, /* 704 */
+ { 45, 13, 12, 0, 0, 45, 0, }, /* 705 */
+ { 136, 9, 12, 0, 40, 136, 0, }, /* 706 */
+ { 136, 5, 12, 0, -40, 136, 0, }, /* 707 */
+ { 106, 7, 12, 0, 0, 106, 0, }, /* 708 */
+ { 104, 7, 12, 0, 0, 104, 0, }, /* 709 */
+ { 104, 21, 12, 0, 0, 104, 0, }, /* 710 */
+ { 110, 7, 12, 0, 0, 110, 0, }, /* 711 */
+ { 12, 7, 12, 0, 0, 12, 0, }, /* 712 */
+ { 81, 7, 12, 0, 0, 81, 0, }, /* 713 */
+ { 81, 21, 12, 0, 0, 81, 0, }, /* 714 */
+ { 81, 15, 12, 0, 0, 81, 0, }, /* 715 */
+ { 120, 7, 12, 0, 0, 120, 0, }, /* 716 */
+ { 120, 26, 12, 0, 0, 120, 0, }, /* 717 */
+ { 120, 15, 12, 0, 0, 120, 0, }, /* 718 */
+ { 116, 7, 12, 0, 0, 116, 0, }, /* 719 */
+ { 116, 15, 12, 0, 0, 116, 0, }, /* 720 */
+ { 128, 7, 12, 0, 0, 128, 0, }, /* 721 */
+ { 128, 15, 12, 0, 0, 128, 0, }, /* 722 */
+ { 66, 7, 12, 0, 0, 66, 0, }, /* 723 */
+ { 66, 15, 12, 0, 0, 66, 0, }, /* 724 */
+ { 66, 21, 12, 0, 0, 66, 0, }, /* 725 */
+ { 72, 7, 12, 0, 0, 72, 0, }, /* 726 */
+ { 72, 21, 12, 0, 0, 72, 0, }, /* 727 */
+ { 98, 7, 12, 0, 0, 98, 0, }, /* 728 */
+ { 97, 7, 12, 0, 0, 97, 0, }, /* 729 */
+ { 97, 15, 12, 0, 0, 97, 0, }, /* 730 */
+ { 31, 7, 12, 0, 0, 31, 0, }, /* 731 */
+ { 31, 12, 3, 0, 0, 31, 0, }, /* 732 */
+ { 31, 15, 12, 0, 0, 31, 0, }, /* 733 */
+ { 31, 21, 12, 0, 0, 31, 0, }, /* 734 */
+ { 88, 7, 12, 0, 0, 88, 0, }, /* 735 */
+ { 88, 15, 12, 0, 0, 88, 0, }, /* 736 */
+ { 88, 21, 12, 0, 0, 88, 0, }, /* 737 */
+ { 117, 7, 12, 0, 0, 117, 0, }, /* 738 */
+ { 117, 15, 12, 0, 0, 117, 0, }, /* 739 */
+ { 112, 7, 12, 0, 0, 112, 0, }, /* 740 */
+ { 112, 26, 12, 0, 0, 112, 0, }, /* 741 */
+ { 112, 12, 3, 0, 0, 112, 0, }, /* 742 */
+ { 112, 15, 12, 0, 0, 112, 0, }, /* 743 */
+ { 112, 21, 12, 0, 0, 112, 0, }, /* 744 */
+ { 78, 7, 12, 0, 0, 78, 0, }, /* 745 */
+ { 78, 21, 12, 0, 0, 78, 0, }, /* 746 */
+ { 83, 7, 12, 0, 0, 83, 0, }, /* 747 */
+ { 83, 15, 12, 0, 0, 83, 0, }, /* 748 */
+ { 82, 7, 12, 0, 0, 82, 0, }, /* 749 */
+ { 82, 15, 12, 0, 0, 82, 0, }, /* 750 */
+ { 121, 7, 12, 0, 0, 121, 0, }, /* 751 */
+ { 121, 21, 12, 0, 0, 121, 0, }, /* 752 */
+ { 121, 15, 12, 0, 0, 121, 0, }, /* 753 */
+ { 89, 7, 12, 0, 0, 89, 0, }, /* 754 */
+ { 130, 9, 12, 0, 64, 130, 0, }, /* 755 */
+ { 130, 5, 12, 0, -64, 130, 0, }, /* 756 */
+ { 130, 15, 12, 0, 0, 130, 0, }, /* 757 */
+ { 144, 7, 12, 0, 0, 144, 0, }, /* 758 */
+ { 144, 12, 3, 0, 0, 144, 0, }, /* 759 */
+ { 144, 13, 12, 0, 0, 144, 0, }, /* 760 */
+ { 1, 15, 12, 0, 0, 1, 0, }, /* 761 */
+ { 156, 7, 12, 0, 0, 156, 0, }, /* 762 */
+ { 156, 12, 3, 0, 0, 156, 0, }, /* 763 */
+ { 156, 17, 12, 0, 0, 156, 0, }, /* 764 */
+ { 147, 7, 12, 0, 0, 147, 0, }, /* 765 */
+ { 147, 15, 12, 0, 0, 147, 0, }, /* 766 */
+ { 148, 7, 12, 0, 0, 148, 0, }, /* 767 */
+ { 148, 12, 3, 0, 0, 148, 0, }, /* 768 */
+ { 148, 15, 12, 0, 0, 148, 0, }, /* 769 */
+ { 148, 21, 12, 0, 0, 148, 0, }, /* 770 */
+ { 153, 7, 12, 0, 0, 153, 0, }, /* 771 */
+ { 153, 15, 12, 0, 0, 153, 0, }, /* 772 */
+ { 149, 7, 12, 0, 0, 149, 0, }, /* 773 */
+ { 94, 10, 5, 0, 0, 94, 0, }, /* 774 */
+ { 94, 12, 3, 0, 0, 94, 0, }, /* 775 */
+ { 94, 7, 12, 0, 0, 94, 0, }, /* 776 */
+ { 94, 21, 12, 0, 0, 94, 0, }, /* 777 */
+ { 94, 15, 12, 0, 0, 94, 0, }, /* 778 */
+ { 94, 13, 12, 0, 0, 94, 0, }, /* 779 */
+ { 85, 12, 3, 0, 0, 85, 0, }, /* 780 */
+ { 85, 10, 5, 0, 0, 85, 0, }, /* 781 */
+ { 85, 7, 12, 0, 0, 85, 0, }, /* 782 */
+ { 85, 21, 12, 0, 0, 85, 0, }, /* 783 */
+ { 85, 1, 4, 0, 0, 85, 0, }, /* 784 */
+ { 101, 7, 12, 0, 0, 101, 0, }, /* 785 */
+ { 101, 13, 12, 0, 0, 101, 0, }, /* 786 */
+ { 96, 12, 3, 0, 0, 96, 0, }, /* 787 */
+ { 96, 7, 12, 0, 0, 96, 0, }, /* 788 */
+ { 96, 10, 5, 0, 0, 96, 0, }, /* 789 */
+ { 96, 13, 12, 0, 0, 96, 0, }, /* 790 */
+ { 96, 21, 12, 0, 0, 96, 0, }, /* 791 */
+ { 111, 7, 12, 0, 0, 111, 0, }, /* 792 */
+ { 111, 12, 3, 0, 0, 111, 0, }, /* 793 */
+ { 111, 21, 12, 0, 0, 111, 0, }, /* 794 */
+ { 100, 12, 3, 0, 0, 100, 0, }, /* 795 */
+ { 100, 10, 5, 0, 0, 100, 0, }, /* 796 */
+ { 100, 7, 12, 0, 0, 100, 0, }, /* 797 */
+ { 100, 7, 4, 0, 0, 100, 0, }, /* 798 */
+ { 100, 21, 12, 0, 0, 100, 0, }, /* 799 */
+ { 100, 13, 12, 0, 0, 100, 0, }, /* 800 */
+ { 48, 15, 12, 0, 0, 48, 0, }, /* 801 */
+ { 108, 7, 12, 0, 0, 108, 0, }, /* 802 */
+ { 108, 10, 5, 0, 0, 108, 0, }, /* 803 */
+ { 108, 12, 3, 0, 0, 108, 0, }, /* 804 */
+ { 108, 21, 12, 0, 0, 108, 0, }, /* 805 */
+ { 129, 7, 12, 0, 0, 129, 0, }, /* 806 */
+ { 129, 21, 12, 0, 0, 129, 0, }, /* 807 */
+ { 109, 7, 12, 0, 0, 109, 0, }, /* 808 */
+ { 109, 12, 3, 0, 0, 109, 0, }, /* 809 */
+ { 109, 10, 5, 0, 0, 109, 0, }, /* 810 */
+ { 109, 13, 12, 0, 0, 109, 0, }, /* 811 */
+ { 107, 12, 3, 0, 0, 107, 0, }, /* 812 */
+ { 107, 12, 3, 0, 0, -52, 0, }, /* 813 */
+ { 107, 10, 5, 0, 0, 107, 0, }, /* 814 */
+ { 107, 10, 5, 0, 0, -52, 0, }, /* 815 */
+ { 107, 7, 12, 0, 0, 107, 0, }, /* 816 */
+ { 28, 12, 3, 0, 0, -52, 0, }, /* 817 */
+ { 107, 10, 3, 0, 0, 107, 0, }, /* 818 */
+ { 135, 7, 12, 0, 0, 135, 0, }, /* 819 */
+ { 135, 10, 5, 0, 0, 135, 0, }, /* 820 */
+ { 135, 12, 3, 0, 0, 135, 0, }, /* 821 */
+ { 135, 21, 12, 0, 0, 135, 0, }, /* 822 */
+ { 135, 13, 12, 0, 0, 135, 0, }, /* 823 */
+ { 124, 7, 12, 0, 0, 124, 0, }, /* 824 */
+ { 124, 10, 3, 0, 0, 124, 0, }, /* 825 */
+ { 124, 10, 5, 0, 0, 124, 0, }, /* 826 */
+ { 124, 12, 3, 0, 0, 124, 0, }, /* 827 */
+ { 124, 21, 12, 0, 0, 124, 0, }, /* 828 */
+ { 124, 13, 12, 0, 0, 124, 0, }, /* 829 */
+ { 123, 7, 12, 0, 0, 123, 0, }, /* 830 */
+ { 123, 10, 3, 0, 0, 123, 0, }, /* 831 */
+ { 123, 10, 5, 0, 0, 123, 0, }, /* 832 */
+ { 123, 12, 3, 0, 0, 123, 0, }, /* 833 */
+ { 123, 21, 12, 0, 0, 123, 0, }, /* 834 */
+ { 114, 7, 12, 0, 0, 114, 0, }, /* 835 */
+ { 114, 10, 5, 0, 0, 114, 0, }, /* 836 */
+ { 114, 12, 3, 0, 0, 114, 0, }, /* 837 */
+ { 114, 21, 12, 0, 0, 114, 0, }, /* 838 */
+ { 114, 13, 12, 0, 0, 114, 0, }, /* 839 */
+ { 102, 7, 12, 0, 0, 102, 0, }, /* 840 */
+ { 102, 12, 3, 0, 0, 102, 0, }, /* 841 */
+ { 102, 10, 5, 0, 0, 102, 0, }, /* 842 */
+ { 102, 13, 12, 0, 0, 102, 0, }, /* 843 */
+ { 126, 7, 12, 0, 0, 126, 0, }, /* 844 */
+ { 126, 12, 3, 0, 0, 126, 0, }, /* 845 */
+ { 126, 10, 5, 0, 0, 126, 0, }, /* 846 */
+ { 126, 13, 12, 0, 0, 126, 0, }, /* 847 */
+ { 126, 15, 12, 0, 0, 126, 0, }, /* 848 */
+ { 126, 21, 12, 0, 0, 126, 0, }, /* 849 */
+ { 126, 26, 12, 0, 0, 126, 0, }, /* 850 */
+ { 142, 7, 12, 0, 0, 142, 0, }, /* 851 */
+ { 142, 10, 5, 0, 0, 142, 0, }, /* 852 */
+ { 142, 12, 3, 0, 0, 142, 0, }, /* 853 */
+ { 142, 21, 12, 0, 0, 142, 0, }, /* 854 */
+ { 125, 9, 12, 0, 32, 125, 0, }, /* 855 */
+ { 125, 5, 12, 0, -32, 125, 0, }, /* 856 */
+ { 125, 13, 12, 0, 0, 125, 0, }, /* 857 */
+ { 125, 15, 12, 0, 0, 125, 0, }, /* 858 */
+ { 125, 7, 12, 0, 0, 125, 0, }, /* 859 */
+ { 154, 7, 12, 0, 0, 154, 0, }, /* 860 */
+ { 154, 10, 3, 0, 0, 154, 0, }, /* 861 */
+ { 154, 10, 5, 0, 0, 154, 0, }, /* 862 */
+ { 154, 12, 3, 0, 0, 154, 0, }, /* 863 */
+ { 154, 7, 4, 0, 0, 154, 0, }, /* 864 */
+ { 154, 21, 12, 0, 0, 154, 0, }, /* 865 */
+ { 154, 13, 12, 0, 0, 154, 0, }, /* 866 */
+ { 150, 7, 12, 0, 0, 150, 0, }, /* 867 */
+ { 150, 10, 5, 0, 0, 150, 0, }, /* 868 */
+ { 150, 12, 3, 0, 0, 150, 0, }, /* 869 */
+ { 150, 21, 12, 0, 0, 150, 0, }, /* 870 */
+ { 141, 7, 12, 0, 0, 141, 0, }, /* 871 */
+ { 141, 12, 3, 0, 0, 141, 0, }, /* 872 */
+ { 141, 10, 5, 0, 0, 141, 0, }, /* 873 */
+ { 141, 7, 4, 0, 0, 141, 0, }, /* 874 */
+ { 141, 21, 12, 0, 0, 141, 0, }, /* 875 */
+ { 140, 7, 12, 0, 0, 140, 0, }, /* 876 */
+ { 140, 12, 3, 0, 0, 140, 0, }, /* 877 */
+ { 140, 10, 5, 0, 0, 140, 0, }, /* 878 */
+ { 140, 7, 4, 0, 0, 140, 0, }, /* 879 */
+ { 140, 21, 12, 0, 0, 140, 0, }, /* 880 */
+ { 122, 7, 12, 0, 0, 122, 0, }, /* 881 */
+ { 133, 7, 12, 0, 0, 133, 0, }, /* 882 */
+ { 133, 10, 5, 0, 0, 133, 0, }, /* 883 */
+ { 133, 12, 3, 0, 0, 133, 0, }, /* 884 */
+ { 133, 21, 12, 0, 0, 133, 0, }, /* 885 */
+ { 133, 13, 12, 0, 0, 133, 0, }, /* 886 */
+ { 133, 15, 12, 0, 0, 133, 0, }, /* 887 */
+ { 134, 21, 12, 0, 0, 134, 0, }, /* 888 */
+ { 134, 7, 12, 0, 0, 134, 0, }, /* 889 */
+ { 134, 12, 3, 0, 0, 134, 0, }, /* 890 */
+ { 134, 10, 5, 0, 0, 134, 0, }, /* 891 */
+ { 138, 7, 12, 0, 0, 138, 0, }, /* 892 */
+ { 138, 12, 3, 0, 0, 138, 0, }, /* 893 */
+ { 138, 7, 4, 0, 0, 138, 0, }, /* 894 */
+ { 138, 13, 12, 0, 0, 138, 0, }, /* 895 */
+ { 143, 7, 12, 0, 0, 143, 0, }, /* 896 */
+ { 143, 10, 5, 0, 0, 143, 0, }, /* 897 */
+ { 143, 12, 3, 0, 0, 143, 0, }, /* 898 */
+ { 143, 13, 12, 0, 0, 143, 0, }, /* 899 */
+ { 145, 7, 12, 0, 0, 145, 0, }, /* 900 */
+ { 145, 12, 3, 0, 0, 145, 0, }, /* 901 */
+ { 145, 10, 5, 0, 0, 145, 0, }, /* 902 */
+ { 145, 21, 12, 0, 0, 145, 0, }, /* 903 */
+ { 54, 15, 12, 0, 0, 54, 0, }, /* 904 */
+ { 54, 21, 12, 0, 0, 54, 0, }, /* 905 */
+ { 63, 7, 12, 0, 0, 63, 0, }, /* 906 */
+ { 63, 14, 12, 0, 0, 63, 0, }, /* 907 */
+ { 63, 21, 12, 0, 0, 63, 0, }, /* 908 */
+ { 80, 7, 12, 0, 0, 80, 0, }, /* 909 */
+ { 80, 1, 2, 0, 0, 80, 0, }, /* 910 */
+ { 127, 7, 12, 0, 0, 127, 0, }, /* 911 */
+ { 115, 7, 12, 0, 0, 115, 0, }, /* 912 */
+ { 115, 13, 12, 0, 0, 115, 0, }, /* 913 */
+ { 115, 21, 12, 0, 0, 115, 0, }, /* 914 */
+ { 103, 7, 12, 0, 0, 103, 0, }, /* 915 */
+ { 103, 12, 3, 0, 0, 103, 0, }, /* 916 */
+ { 103, 21, 12, 0, 0, 103, 0, }, /* 917 */
+ { 119, 7, 12, 0, 0, 119, 0, }, /* 918 */
+ { 119, 12, 3, 0, 0, 119, 0, }, /* 919 */
+ { 119, 21, 12, 0, 0, 119, 0, }, /* 920 */
+ { 119, 26, 12, 0, 0, 119, 0, }, /* 921 */
+ { 119, 6, 12, 0, 0, 119, 0, }, /* 922 */
+ { 119, 13, 12, 0, 0, 119, 0, }, /* 923 */
+ { 119, 15, 12, 0, 0, 119, 0, }, /* 924 */
+ { 146, 9, 12, 0, 32, 146, 0, }, /* 925 */
+ { 146, 5, 12, 0, -32, 146, 0, }, /* 926 */
+ { 146, 15, 12, 0, 0, 146, 0, }, /* 927 */
+ { 146, 21, 12, 0, 0, 146, 0, }, /* 928 */
+ { 99, 7, 12, 0, 0, 99, 0, }, /* 929 */
+ { 99, 12, 3, 0, 0, 99, 0, }, /* 930 */
+ { 99, 10, 5, 0, 0, 99, 0, }, /* 931 */
+ { 99, 6, 12, 0, 0, 99, 0, }, /* 932 */
+ { 137, 6, 12, 0, 0, 137, 0, }, /* 933 */
+ { 139, 6, 12, 0, 0, 139, 0, }, /* 934 */
+ { 155, 12, 3, 0, 0, 155, 0, }, /* 935 */
+ { 23, 10, 5, 0, 0, 23, 0, }, /* 936 */
+ { 137, 7, 12, 0, 0, 137, 0, }, /* 937 */
+ { 155, 7, 12, 0, 0, 155, 0, }, /* 938 */
+ { 139, 7, 12, 0, 0, 139, 0, }, /* 939 */
+ { 105, 7, 12, 0, 0, 105, 0, }, /* 940 */
+ { 105, 26, 12, 0, 0, 105, 0, }, /* 941 */
+ { 105, 12, 3, 0, 0, 105, 0, }, /* 942 */
+ { 105, 21, 12, 0, 0, 105, 0, }, /* 943 */
+ { 10, 1, 2, 0, 0, 105, 0, }, /* 944 */
+ { 10, 10, 3, 0, 0, 10, 0, }, /* 945 */
+ { 10, 10, 5, 0, 0, 10, 0, }, /* 946 */
+ { 20, 12, 3, 0, 0, 20, 0, }, /* 947 */
+ { 131, 26, 12, 0, 0, 131, 0, }, /* 948 */
+ { 131, 12, 3, 0, 0, 131, 0, }, /* 949 */
+ { 131, 21, 12, 0, 0, 131, 0, }, /* 950 */
+ { 18, 12, 3, 0, 0, 18, 0, }, /* 951 */
+ { 151, 7, 12, 0, 0, 151, 0, }, /* 952 */
+ { 151, 12, 3, 0, 0, 151, 0, }, /* 953 */
+ { 151, 6, 12, 0, 0, 151, 0, }, /* 954 */
+ { 151, 13, 12, 0, 0, 151, 0, }, /* 955 */
+ { 151, 26, 12, 0, 0, 151, 0, }, /* 956 */
+ { 152, 7, 12, 0, 0, 152, 0, }, /* 957 */
+ { 152, 12, 3, 0, 0, 152, 0, }, /* 958 */
+ { 152, 13, 12, 0, 0, 152, 0, }, /* 959 */
+ { 152, 23, 12, 0, 0, 152, 0, }, /* 960 */
+ { 113, 7, 12, 0, 0, 113, 0, }, /* 961 */
+ { 113, 15, 12, 0, 0, 113, 0, }, /* 962 */
+ { 113, 12, 3, 0, 0, 113, 0, }, /* 963 */
+ { 132, 9, 12, 0, 34, 132, 0, }, /* 964 */
+ { 132, 5, 12, 0, -34, 132, 0, }, /* 965 */
+ { 132, 12, 3, 0, 0, 132, 0, }, /* 966 */
+ { 132, 6, 12, 0, 0, 132, 0, }, /* 967 */
+ { 132, 13, 12, 0, 0, 132, 0, }, /* 968 */
+ { 132, 21, 12, 0, 0, 132, 0, }, /* 969 */
+ { 0, 2, 14, 0, 0, 0, 0, }, /* 970 */
+ { 10, 26, 11, 0, 0, 10, 0, }, /* 971 */
+ { 27, 26, 12, 0, 0, 27, 0, }, /* 972 */
+ { 10, 24, 3, 0, 0, 10, 0, }, /* 973 */
+ { 10, 1, 3, 0, 0, 10, 0, }, /* 974 */
};
const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
@@ -1185,37 +1204,37 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F000 */
126,126, 98, 98,127,128,129,130,131,131,132,133,134,135,136,137, /* U+F800 */
138,139,140,141,142,143,144,145,146,147,148,142,149,149,150,142, /* U+10000 */
-151,152,153,154,155,156,157,158,159,160,161,142,162,142,163,164, /* U+10800 */
-165,166,167,168,169,170,171,142,172,173,142,174,175,176,177,142, /* U+11000 */
-178,179,142,180,181,182,142,142,183,184,185,186,142,187,142,188, /* U+11800 */
-189,189,189,189,189,189,189,190,191,189,192,142,142,142,142,142, /* U+12000 */
+151,152,153,154,155,156,157,158,159,160,161,142,162,163,164,165, /* U+10800 */
+166,167,168,169,170,171,172,142,173,174,142,175,176,177,178,142, /* U+11000 */
+179,180,181,182,183,184,142,142,185,186,187,188,142,189,142,190, /* U+11800 */
+191,191,191,191,191,191,191,192,193,191,194,142,142,142,142,142, /* U+12000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+12800 */
-193,193,193,193,193,193,193,193,194,142,142,142,142,142,142,142, /* U+13000 */
+195,195,195,195,195,195,195,195,196,142,142,142,142,142,142,142, /* U+13000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+13800 */
-142,142,142,142,142,142,142,142,195,195,195,195,196,142,142,142, /* U+14000 */
+142,142,142,142,142,142,142,142,197,197,197,197,198,142,142,142, /* U+14000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+14800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+16000 */
-197,197,197,197,198,199,200,201,142,142,142,142,202,203,204,205, /* U+16800 */
-206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* U+17000 */
-206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* U+17800 */
-206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,207, /* U+18000 */
-206,206,206,206,206,208,142,142,142,142,142,142,142,142,142,142, /* U+18800 */
+199,199,199,199,200,201,202,203,142,142,142,142,204,205,206,207, /* U+16800 */
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, /* U+17000 */
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, /* U+17800 */
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,209, /* U+18000 */
+208,208,208,208,208,208,210,210,210,211,212,142,142,142,142,142, /* U+18800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A800 */
-209,210,211,212,212,213,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */
-142,142,142,142,142,142,142,142,214,215,142,142,142,142,142,142, /* U+1B800 */
+213,214,215,216,216,217,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */
+142,142,142,142,142,142,142,142,218,219,142,142,142,142,142,142, /* U+1B800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C800 */
- 71,216,217,218,219,220,221,142,222,223,224,225,226,227,228,229, /* U+1D000 */
-230,230,230,230,231,232,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */
-233,142,234,142,142,235,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */
-236,237,238,142,142,142,142,142,239,240,241,142,242,243,142,142, /* U+1E800 */
-244,245,246,247,248,249,250,251,250,250,252,250,253,254,255,256, /* U+1F000 */
-257,258,259,260,261,262,249,249,249,249,249,249,249,249,249,263, /* U+1F800 */
+ 71,220,221,222,223,224,225,142,226,227,228,229,230,231,232,233, /* U+1D000 */
+234,234,234,234,235,236,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */
+237,142,238,142,142,239,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */
+240,241,242,142,142,142,142,142,243,244,245,142,246,247,142,142, /* U+1E800 */
+248,249,250,251,252,253,254,255,254,254,256,254,257,258,259,260, /* U+1F000 */
+261,262,263,264,265,266, 71,267,253,253,253,253,253,253,253,268, /* U+1F800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20000 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+21000 */
@@ -1236,21 +1255,21 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+28800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29000 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29800 */
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,264, 98, 98, /* U+2A000 */
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,269, 98, 98, /* U+2A000 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2A800 */
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,265, 98, /* U+2B000 */
-266, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,270, 98, /* U+2B000 */
+271, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2C000 */
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,267, 98, 98, /* U+2C800 */
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,272, 98, 98, /* U+2C800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D000 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2E000 */
- 98, 98, 98, 98, 98, 98, 98,268,142,142,142,142,142,142,142,142, /* U+2E800 */
+ 98, 98, 98, 98, 98, 98, 98,273,142,142,142,142,142,142,142,142, /* U+2E800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+2F000 */
- 98, 98, 98, 98,269,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */
-142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+30000 */
-142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+30800 */
-142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+31000 */
+ 98, 98, 98, 98,274,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+30000 */
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+30800 */
+ 98, 98, 98, 98, 98, 98,275,142,142,142,142,142,142,142,142,142, /* U+31000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+31800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+32000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+32800 */
@@ -1600,8 +1619,8 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DE800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF800 */
-270,271,272,273,271,271,271,271,271,271,271,271,271,271,271,271, /* U+E0000 */
-271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, /* U+E0800 */
+276,277,278,279,277,277,277,277,277,277,277,277,277,277,277,277, /* U+E0000 */
+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277, /* U+E0800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E2000 */
@@ -1663,7 +1682,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE000 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE800 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FF000 */
-126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,274, /* U+FF800 */
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,280, /* U+FF800 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100000 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100800 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+101000 */
@@ -1695,10 +1714,10 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E000 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E800 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10F000 */
-126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,274, /* U+10F800 */
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,280, /* U+10F800 */
};
-const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
+const uint16_t PRIV(ucd_stage2)[] = { /* 71936 bytes, block = 128 */
/* block 0 */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1810,474 +1829,474 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
/* block 11 */
-207,207,207,207,207,207,207,206,206,208,209,120,120,210,210,211,
-120,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
-212,212,212,212,212,212,212,212,212,212,212,212,212,212,213,212,
-214,212,212,214,212,212,214,212,120,120,120,120,120,120,120,120,
-215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
-215,215,215,215,215,215,215,215,215,215,215,120,120,120,120,215,
-215,215,215,214,214,120,120,120,120,120,120,120,120,120,120,120,
+207,207,207,207,207,207,207,206,206,205,208,120,120,209,209,210,
+120,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,212,211,
+213,211,211,213,211,211,213,211,120,120,120,120,120,120,120,120,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,120,120,120,120,214,
+214,214,214,213,213,120,120,120,120,120,120,120,120,120,120,120,
/* block 12 */
-216,216,216,216,216,217,218,218,218,219,219,220,221,219,222,222,
-223,223,223,223,223,223,223,223,223,223,223,221,224,120,219,221,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-226,225,225,225,225,225,225,225,225,225,225,227,227,227,227,227,
-227,227,227,227,227,227,223,223,223,223,223,223,223,223,223,223,
-228,228,228,228,228,228,228,228,228,228,219,219,219,219,225,225,
-227,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+215,215,215,215,215,216,217,217,217,218,218,219,220,218,221,221,
+222,222,222,222,222,222,222,222,222,222,222,220,223,120,218,220,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+225,224,224,224,224,224,224,224,224,224,224,226,226,226,226,226,
+226,226,226,226,226,226,222,222,222,222,222,222,222,222,222,222,
+227,227,227,227,227,227,227,227,227,227,218,218,218,218,224,224,
+226,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
/* block 13 */
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,229,225,223,223,223,223,223,223,223,217,222,223,
-223,223,223,223,223,230,230,223,223,222,223,223,223,223,225,225,
-231,231,231,231,231,231,231,231,231,231,225,225,225,222,222,225,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,228,224,222,222,222,222,222,222,222,216,221,222,
+222,222,222,222,222,229,229,222,222,221,222,222,222,222,224,224,
+230,230,230,230,230,230,230,230,230,230,224,224,224,221,221,224,
/* block 14 */
-232,232,232,232,232,232,232,232,232,232,232,232,232,232,120,233,
-234,235,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,120,232,
+233,234,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
-235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
-235,235,235,235,235,235,235,235,235,235,235,120,120,234,234,234,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+234,234,234,234,234,234,234,234,234,234,234,120,120,233,233,233,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
/* block 15 */
-236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
-236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
-236,236,236,236,236,236,237,237,237,237,237,237,237,237,237,237,
-237,236,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-238,238,238,238,238,238,238,238,238,238,239,239,239,239,239,239,
-239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
-239,239,239,239,239,239,239,239,239,239,239,240,240,240,240,240,
-240,240,240,240,241,241,242,243,243,243,241,120,120,240,244,244,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,236,236,236,236,236,236,236,236,236,236,
+236,235,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+237,237,237,237,237,237,237,237,237,237,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,239,239,239,239,239,
+239,239,239,239,240,240,241,242,242,242,240,120,120,239,243,243,
/* block 16 */
-245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-245,245,245,245,245,245,246,246,246,246,247,246,246,246,246,246,
-246,246,246,246,247,246,246,246,247,246,246,246,246,246,120,120,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,120,
-249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
-249,249,249,249,249,249,249,249,249,250,250,250,120,120,251,120,
-234,234,234,234,234,234,234,234,234,234,234,120,120,120,120,120,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,245,245,245,245,246,245,245,245,245,245,
+245,245,245,245,246,245,245,245,246,245,245,245,245,245,120,120,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,120,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,249,249,249,120,120,250,120,
+233,233,233,233,233,233,233,233,233,233,233,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 17 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,120,225,225,225,225,225,225,225,225,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,223,223,223,223,223,223,223,223,223,223,223,223,223,
-223,223,217,223,223,223,223,223,223,223,223,223,223,223,223,223,
-223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,120,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,120,120,120,120,120,120,120,120,
+120,120,120,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,216,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
/* block 18 */
-252,252,252,253,254,254,254,254,254,254,254,254,254,254,254,254,
-254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
-254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
-254,254,254,254,254,254,254,254,254,254,252,253,252,254,253,253,
-253,252,252,252,252,252,252,252,252,253,253,253,253,252,253,253,
-254,255,256,113,113,252,252,252,254,254,254,254,254,254,254,254,
-254,254,252,252,257,258,259,259,259,259,259,259,259,259,259,259,
-260,261,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+251,251,251,252,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,251,252,251,253,252,252,
+252,251,251,251,251,251,251,251,251,252,252,252,252,251,252,252,
+253,254,255,113,113,251,251,251,253,253,253,253,253,253,253,253,
+253,253,251,251,256,257,258,258,258,258,258,258,258,258,258,258,
+259,260,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
/* block 19 */
-262,263,264,264,120,262,262,262,262,262,262,262,262,120,120,262,
-262,120,120,262,262,262,262,262,262,262,262,262,262,262,262,262,
-262,262,262,262,262,262,262,262,262,120,262,262,262,262,262,262,
-262,120,262,120,120,120,262,262,262,262,120,120,263,262,265,264,
-264,263,263,263,263,120,120,264,264,120,120,264,264,263,262,120,
-120,120,120,120,120,120,120,265,120,120,120,120,262,262,120,262,
-262,262,263,263,120,120,266,266,266,266,266,266,266,266,266,266,
-262,262,267,267,268,268,268,268,268,268,269,267,262,270,263,120,
+261,262,263,263,120,261,261,261,261,261,261,261,261,120,120,261,
+261,120,120,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,120,261,261,261,261,261,261,
+261,120,261,120,120,120,261,261,261,261,120,120,262,261,264,263,
+263,262,262,262,262,120,120,263,263,120,120,263,263,262,261,120,
+120,120,120,120,120,120,120,264,120,120,120,120,261,261,120,261,
+261,261,262,262,120,120,265,265,265,265,265,265,265,265,265,265,
+261,261,266,266,267,267,267,267,267,267,268,266,261,269,262,120,
/* block 20 */
-120,271,271,272,120,273,273,273,273,273,273,120,120,120,120,273,
-273,120,120,273,273,273,273,273,273,273,273,273,273,273,273,273,
-273,273,273,273,273,273,273,273,273,120,273,273,273,273,273,273,
-273,120,273,273,120,273,273,120,273,273,120,120,271,120,272,272,
-272,271,271,120,120,120,120,271,271,120,120,271,271,271,120,120,
-120,271,120,120,120,120,120,120,120,273,273,273,273,120,273,120,
-120,120,120,120,120,120,274,274,274,274,274,274,274,274,274,274,
-271,271,273,273,273,271,275,120,120,120,120,120,120,120,120,120,
+120,270,270,271,120,272,272,272,272,272,272,120,120,120,120,272,
+272,120,120,272,272,272,272,272,272,272,272,272,272,272,272,272,
+272,272,272,272,272,272,272,272,272,120,272,272,272,272,272,272,
+272,120,272,272,120,272,272,120,272,272,120,120,270,120,271,271,
+271,270,270,120,120,120,120,270,270,120,120,270,270,270,120,120,
+120,270,120,120,120,120,120,120,120,272,272,272,272,120,272,120,
+120,120,120,120,120,120,273,273,273,273,273,273,273,273,273,273,
+270,270,272,272,272,270,274,120,120,120,120,120,120,120,120,120,
/* block 21 */
-120,276,276,277,120,278,278,278,278,278,278,278,278,278,120,278,
-278,278,120,278,278,278,278,278,278,278,278,278,278,278,278,278,
-278,278,278,278,278,278,278,278,278,120,278,278,278,278,278,278,
-278,120,278,278,120,278,278,278,278,278,120,120,276,278,277,277,
-277,276,276,276,276,276,120,276,276,277,120,277,277,276,120,120,
-278,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-278,278,276,276,120,120,279,279,279,279,279,279,279,279,279,279,
-280,281,120,120,120,120,120,120,120,278,276,276,276,276,276,276,
+120,275,275,276,120,277,277,277,277,277,277,277,277,277,120,277,
+277,277,120,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,277,277,277,277,277,277,277,120,277,277,277,277,277,277,
+277,120,277,277,120,277,277,277,277,277,120,120,275,277,276,276,
+276,275,275,275,275,275,120,275,275,276,120,276,276,275,120,120,
+277,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+277,277,275,275,120,120,278,278,278,278,278,278,278,278,278,278,
+279,280,120,120,120,120,120,120,120,277,275,275,275,275,275,275,
/* block 22 */
-120,282,283,283,120,284,284,284,284,284,284,284,284,120,120,284,
-284,120,120,284,284,284,284,284,284,284,284,284,284,284,284,284,
-284,284,284,284,284,284,284,284,284,120,284,284,284,284,284,284,
-284,120,284,284,120,284,284,284,284,284,120,120,282,284,285,282,
-283,282,282,282,282,120,120,283,283,120,120,283,283,282,120,120,
-120,120,120,120,120,120,282,285,120,120,120,120,284,284,120,284,
-284,284,282,282,120,120,286,286,286,286,286,286,286,286,286,286,
-287,284,288,288,288,288,288,288,120,120,120,120,120,120,120,120,
+120,281,282,282,120,283,283,283,283,283,283,283,283,120,120,283,
+283,120,120,283,283,283,283,283,283,283,283,283,283,283,283,283,
+283,283,283,283,283,283,283,283,283,120,283,283,283,283,283,283,
+283,120,283,283,120,283,283,283,283,283,120,120,281,283,284,281,
+282,281,281,281,281,120,120,282,282,120,120,282,282,281,120,120,
+120,120,120,120,120,281,281,284,120,120,120,120,283,283,120,283,
+283,283,281,281,120,120,285,285,285,285,285,285,285,285,285,285,
+286,283,287,287,287,287,287,287,120,120,120,120,120,120,120,120,
/* block 23 */
-120,120,289,290,120,290,290,290,290,290,290,120,120,120,290,290,
-290,120,290,290,290,290,120,120,120,290,290,120,290,120,290,290,
-120,120,120,290,290,120,120,120,290,290,290,120,120,120,290,290,
-290,290,290,290,290,290,290,290,290,290,120,120,120,120,291,292,
-289,292,292,120,120,120,292,292,292,120,292,292,292,289,120,120,
-290,120,120,120,120,120,120,291,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,293,293,293,293,293,293,293,293,293,293,
-294,294,294,295,296,296,296,296,296,297,296,120,120,120,120,120,
+120,120,288,289,120,289,289,289,289,289,289,120,120,120,289,289,
+289,120,289,289,289,289,120,120,120,289,289,120,289,120,289,289,
+120,120,120,289,289,120,120,120,289,289,289,120,120,120,289,289,
+289,289,289,289,289,289,289,289,289,289,120,120,120,120,290,291,
+288,291,291,120,120,120,291,291,291,120,291,291,291,288,120,120,
+289,120,120,120,120,120,120,290,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,292,292,292,292,292,292,292,292,292,292,
+293,293,293,294,295,295,295,295,295,296,295,120,120,120,120,120,
/* block 24 */
-298,299,299,299,298,300,300,300,300,300,300,300,300,120,300,300,
-300,120,300,300,300,300,300,300,300,300,300,300,300,300,300,300,
-300,300,300,300,300,300,300,300,300,120,300,300,300,300,300,300,
-300,300,300,300,300,300,300,300,300,300,120,120,120,300,298,298,
-298,299,299,299,299,120,298,298,298,120,298,298,298,298,120,120,
-120,120,120,120,120,298,298,120,300,300,300,120,120,120,120,120,
-300,300,298,298,120,120,301,301,301,301,301,301,301,301,301,301,
-120,120,120,120,120,120,120,302,303,303,303,303,303,303,303,304,
+297,298,298,298,297,299,299,299,299,299,299,299,299,120,299,299,
+299,120,299,299,299,299,299,299,299,299,299,299,299,299,299,299,
+299,299,299,299,299,299,299,299,299,120,299,299,299,299,299,299,
+299,299,299,299,299,299,299,299,299,299,120,120,120,299,297,297,
+297,298,298,298,298,120,297,297,297,120,297,297,297,297,120,120,
+120,120,120,120,120,297,297,120,299,299,299,120,120,120,120,120,
+299,299,297,297,120,120,300,300,300,300,300,300,300,300,300,300,
+120,120,120,120,120,120,120,301,302,302,302,302,302,302,302,303,
/* block 25 */
-305,306,307,307,308,305,305,305,305,305,305,305,305,120,305,305,
-305,120,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-305,305,305,305,305,305,305,305,305,120,305,305,305,305,305,305,
-305,305,305,305,120,305,305,305,305,305,120,120,306,305,307,306,
-307,307,309,307,307,120,306,307,307,120,307,307,306,306,120,120,
-120,120,120,120,120,309,309,120,120,120,120,120,120,120,305,120,
-305,305,306,306,120,120,310,310,310,310,310,310,310,310,310,310,
-120,305,305,120,120,120,120,120,120,120,120,120,120,120,120,120,
+304,305,306,306,307,304,304,304,304,304,304,304,304,120,304,304,
+304,120,304,304,304,304,304,304,304,304,304,304,304,304,304,304,
+304,304,304,304,304,304,304,304,304,120,304,304,304,304,304,304,
+304,304,304,304,120,304,304,304,304,304,120,120,305,304,306,305,
+306,306,308,306,306,120,305,306,306,120,306,306,305,305,120,120,
+120,120,120,120,120,308,308,120,120,120,120,120,120,120,304,120,
+304,304,305,305,120,120,309,309,309,309,309,309,309,309,309,309,
+120,304,304,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 26 */
-311,311,312,312,120,313,313,313,313,313,313,313,313,120,313,313,
-313,120,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,313,313,313,313,313,313,311,311,313,314,312,
-312,311,311,311,311,120,312,312,312,120,312,312,312,311,315,316,
-120,120,120,120,313,313,313,314,317,317,317,317,317,317,317,313,
-313,313,311,311,120,120,318,318,318,318,318,318,318,318,318,318,
-317,317,317,317,317,317,317,317,317,316,313,313,313,313,313,313,
+310,310,311,311,312,312,312,312,312,312,312,312,312,120,312,312,
+312,120,312,312,312,312,312,312,312,312,312,312,312,312,312,312,
+312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,312,
+312,312,312,312,312,312,312,312,312,312,312,310,310,312,313,311,
+311,310,310,310,310,120,311,311,311,120,311,311,311,310,314,315,
+120,120,120,120,312,312,312,313,316,316,316,316,316,316,316,312,
+312,312,310,310,120,120,317,317,317,317,317,317,317,317,317,317,
+316,316,316,316,316,316,316,316,316,315,312,312,312,312,312,312,
/* block 27 */
-120,120,319,319,120,320,320,320,320,320,320,320,320,320,320,320,
+120,318,319,319,120,320,320,320,320,320,320,320,320,320,320,320,
320,320,320,320,320,320,320,120,120,120,320,320,320,320,320,320,
320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,
320,320,120,320,320,320,320,320,320,320,320,320,120,320,120,120,
-320,320,320,320,320,320,320,120,120,120,321,120,120,120,120,322,
-319,319,321,321,321,120,321,120,319,319,319,319,319,319,319,322,
-120,120,120,120,120,120,323,323,323,323,323,323,323,323,323,323,
-120,120,319,319,324,120,120,120,120,120,120,120,120,120,120,120,
+320,320,320,320,320,320,320,120,120,120,318,120,120,120,120,321,
+319,319,318,318,318,120,318,120,319,319,319,319,319,319,319,321,
+120,120,120,120,120,120,322,322,322,322,322,322,322,322,322,322,
+120,120,319,319,323,120,120,120,120,120,120,120,120,120,120,120,
/* block 28 */
-120,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,
-325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,
-325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,
-325,326,325,327,326,326,326,326,326,326,326,120,120,120,120, 6,
-325,325,325,325,325,325,328,326,326,326,326,326,326,326,326,329,
-330,330,330,330,330,330,330,330,330,330,329,329,120,120,120,120,
+120,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,
+324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,
+324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,
+324,325,324,326,325,325,325,325,325,325,325,120,120,120,120, 6,
+324,324,324,324,324,324,327,325,325,325,325,325,325,325,325,328,
+329,329,329,329,329,329,329,329,329,329,328,328,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 29 */
-120,331,331,120,331,120,331,331,331,331,331,120,331,331,331,331,
-331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,
-331,331,331,331,120,331,120,331,331,331,331,331,331,331,331,331,
-331,332,331,333,332,332,332,332,332,332,332,332,332,331,120,120,
-331,331,331,331,331,120,334,120,332,332,332,332,332,332,120,120,
-335,335,335,335,335,335,335,335,335,335,120,120,331,331,331,331,
+120,330,330,120,330,120,330,330,330,330,330,120,330,330,330,330,
+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,120,330,120,330,330,330,330,330,330,330,330,330,
+330,331,330,332,331,331,331,331,331,331,331,331,331,330,120,120,
+330,330,330,330,330,120,333,120,331,331,331,331,331,331,120,120,
+334,334,334,334,334,334,334,334,334,334,120,120,330,330,330,330,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 30 */
-336,337,337,337,338,338,338,338,338,338,338,338,338,338,338,338,
-338,338,338,337,338,337,337,337,339,339,337,337,337,337,337,337,
-340,340,340,340,340,340,340,340,340,340,341,341,341,341,341,341,
-341,341,341,341,337,339,337,339,337,339,342,343,342,343,344,344,
-336,336,336,336,336,336,336,336,120,336,336,336,336,336,336,336,
-336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
-336,336,336,336,336,336,336,336,336,336,336,336,336,120,120,120,
-120,339,339,339,339,339,339,339,339,339,339,339,339,339,339,344,
+335,336,336,336,337,337,337,337,337,337,337,337,337,337,337,337,
+337,337,337,336,337,336,336,336,338,338,336,336,336,336,336,336,
+339,339,339,339,339,339,339,339,339,339,340,340,340,340,340,340,
+340,340,340,340,336,338,336,338,336,338,341,342,341,342,343,343,
+335,335,335,335,335,335,335,335,120,335,335,335,335,335,335,335,
+335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,
+335,335,335,335,335,335,335,335,335,335,335,335,335,120,120,120,
+120,338,338,338,338,338,338,338,338,338,338,338,338,338,338,343,
/* block 31 */
-339,339,339,339,339,338,339,339,336,336,336,336,336,339,339,339,
-339,339,339,339,339,339,339,339,120,339,339,339,339,339,339,339,
-339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,
-339,339,339,339,339,339,339,339,339,339,339,339,339,120,337,337,
-337,337,337,337,337,337,339,337,337,337,337,337,337,120,337,337,
-338,338,338,338,338, 20, 20, 20, 20,338,338,120,120,120,120,120,
+338,338,338,338,338,337,338,338,335,335,335,335,335,338,338,338,
+338,338,338,338,338,338,338,338,120,338,338,338,338,338,338,338,
+338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,
+338,338,338,338,338,338,338,338,338,338,338,338,338,120,336,336,
+336,336,336,336,336,336,338,336,336,336,336,336,336,120,336,336,
+337,337,337,337,337, 20, 20, 20, 20,337,337,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 32 */
-345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
-345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
-345,345,345,345,345,345,345,345,345,345,345,346,346,347,347,347,
-347,348,347,347,347,347,347,347,346,347,347,348,348,347,347,345,
-349,349,349,349,349,349,349,349,349,349,350,350,350,350,350,350,
-345,345,345,345,345,345,348,348,347,347,345,345,345,345,347,347,
-347,345,346,346,346,345,345,346,346,346,346,346,346,346,345,345,
-345,347,347,347,347,345,345,345,345,345,345,345,345,345,345,345,
+344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
+344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
+344,344,344,344,344,344,344,344,344,344,344,345,345,346,346,346,
+346,347,346,346,346,346,346,346,345,346,346,347,347,346,346,344,
+348,348,348,348,348,348,348,348,348,348,349,349,349,349,349,349,
+344,344,344,344,344,344,347,347,346,346,344,344,344,344,346,346,
+346,344,345,345,345,344,344,345,345,345,345,345,345,345,344,344,
+344,346,346,346,346,344,344,344,344,344,344,344,344,344,344,344,
/* block 33 */
-345,345,347,346,348,347,347,346,346,346,346,346,346,347,345,346,
-351,351,351,351,351,351,351,351,351,351,346,346,346,347,352,352,
+344,344,346,345,347,346,346,345,345,345,345,345,345,346,344,345,
+350,350,350,350,350,350,350,350,350,350,345,345,345,346,351,351,
+352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,
+352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,
+352,352,352,352,352,352,120,352,120,120,120,120,120,352,120,120,
353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,
353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,
-353,353,353,353,353,353,120,353,120,120,120,120,120,353,120,120,
-354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,
-354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,
-354,354,354,354,354,354,354,354,354,354,354,355,356,354,354,354,
+353,353,353,353,353,353,353,353,353,353,353,354,355,353,353,353,
/* block 34 */
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
+
+/* block 35 */
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
-357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
-357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
+357,357,357,357,357,357,357,357,358,358,358,358,358,358,358,358,
358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-
-/* block 35 */
358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,359,359,359,359,359,359,359,359,
+358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+
+/* block 36 */
359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,120,359,359,359,359,120,120,
+359,359,359,359,359,359,359,120,359,120,359,359,359,359,120,120,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-
-/* block 36 */
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,120,360,360,360,360,120,120,
-360,360,360,360,360,360,360,120,360,120,360,360,360,360,120,120,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
/* block 37 */
-360,360,360,360,360,360,360,360,360,120,360,360,360,360,120,120,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,120,
-360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+359,359,359,359,359,359,359,359,359,120,359,359,359,359,120,120,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,120,
+359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
/* block 38 */
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,360,360,360,360,120,120,361,361,361,
-362,362,362,362,362,362,362,362,362,363,363,363,363,363,363,363,
-363,363,363,363,363,363,363,363,363,363,363,363,363,120,120,120,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,120,359,359,359,359,120,120,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,120,120,360,360,360,
+361,361,361,361,361,361,361,361,361,362,362,362,362,362,362,362,
+362,362,362,362,362,362,362,362,362,362,362,362,362,120,120,120,
/* block 39 */
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-364,364,364,364,364,364,364,364,364,364,120,120,120,120,120,120,
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-366,366,366,366,366,366,120,120,367,367,367,367,367,367,120,120,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+363,363,363,363,363,363,363,363,363,363,120,120,120,120,120,120,
+364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
+364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
+364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
+364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
+364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
+365,365,365,365,365,365,120,120,366,366,366,366,366,366,120,120,
/* block 40 */
-368,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+367,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
/* block 41 */
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
/* block 42 */
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,370,371,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,369,370,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
/* block 43 */
-372,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-373,373,373,373,373,373,373,373,373,373,373,374,375,120,120,120,
-376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
-376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
-376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
-376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
-376,376,376,376,376,376,376,376,376,376,376, 5, 5, 5,377,377,
-377,376,376,376,376,376,376,376,376,120,120,120,120,120,120,120,
+371,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,
+372,372,372,372,372,372,372,372,372,372,372,373,374,120,120,120,
+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,
+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,
+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,
+375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,375,
+375,375,375,375,375,375,375,375,375,375,375, 5, 5, 5,376,376,
+376,375,375,375,375,375,375,375,375,120,120,120,120,120,120,120,
/* block 44 */
-378,378,378,378,378,378,378,378,378,378,378,378,378,120,378,378,
-378,378,379,379,379,120,120,120,120,120,120,120,120,120,120,120,
-380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,
-380,380,381,381,381,382,382,120,120,120,120,120,120,120,120,120,
-383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
-383,383,384,384,120,120,120,120,120,120,120,120,120,120,120,120,
-385,385,385,385,385,385,385,385,385,385,385,385,385,120,385,385,
-385,120,386,386,120,120,120,120,120,120,120,120,120,120,120,120,
+377,377,377,377,377,377,377,377,377,377,377,377,377,120,377,377,
+377,377,378,378,378,120,120,120,120,120,120,120,120,120,120,120,
+379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,
+379,379,380,380,380,381,381,120,120,120,120,120,120,120,120,120,
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,
+382,382,383,383,120,120,120,120,120,120,120,120,120,120,120,120,
+384,384,384,384,384,384,384,384,384,384,384,384,384,120,384,384,
+384,120,385,385,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 45 */
-387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
-387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
-387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
-387,387,387,387,388,388,389,388,388,388,388,388,388,388,389,389,
-389,389,389,389,389,389,388,389,389,388,388,388,388,388,388,388,
-388,388,388,388,390,390,390,391,390,390,390,392,387,388,120,120,
+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,
+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,
+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,
+386,386,386,386,387,387,388,387,387,387,387,387,387,387,388,388,
+388,388,388,388,388,388,387,388,388,387,387,387,387,387,387,387,
+387,387,387,387,389,389,389,390,389,389,389,391,386,387,120,120,
+392,392,392,392,392,392,392,392,392,392,120,120,120,120,120,120,
393,393,393,393,393,393,393,393,393,393,120,120,120,120,120,120,
-394,394,394,394,394,394,394,394,394,394,120,120,120,120,120,120,
/* block 46 */
-395,395,396,396,395,396,397,395,395,395,395,398,398,398,399,120,
-400,400,400,400,400,400,400,400,400,400,120,120,120,120,120,120,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,402,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,120,120,120,120,120,120,120,
+394,394,395,395,394,395,396,394,394,394,394,397,397,397,398,120,
+399,399,399,399,399,399,399,399,399,399,120,120,120,120,120,120,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,401,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,120,120,120,120,120,120,120,
/* block 47 */
-401,401,401,401,401,398,398,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,398,401,120,120,120,120,120,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,120,120,120,120,120,120,120,120,120,120,
+400,400,400,400,400,397,397,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,397,400,120,120,120,120,120,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
+368,368,368,368,368,368,120,120,120,120,120,120,120,120,120,120,
/* block 48 */
-403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,
-403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,120,
-404,404,404,405,405,405,405,404,404,405,405,405,120,120,120,120,
-405,405,404,405,405,405,405,405,405,404,404,404,120,120,120,120,
-406,120,120,120,407,407,408,408,408,408,408,408,408,408,408,408,
-409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,
-409,409,409,409,409,409,409,409,409,409,409,409,409,409,120,120,
-409,409,409,409,409,120,120,120,120,120,120,120,120,120,120,120,
+402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
+402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,120,
+403,403,403,404,404,404,404,403,403,404,404,404,120,120,120,120,
+404,404,403,404,404,404,404,404,404,403,403,403,120,120,120,120,
+405,120,120,120,406,406,407,407,407,407,407,407,407,407,407,407,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,120,120,
+408,408,408,408,408,120,120,120,120,120,120,120,120,120,120,120,
/* block 49 */
-410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
-410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
-410,410,410,410,410,410,410,410,410,410,410,410,120,120,120,120,
-410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
-410,410,410,410,410,410,410,410,410,410,120,120,120,120,120,120,
-411,411,411,411,411,411,411,411,411,411,412,120,120,120,413,413,
-414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
-414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,
+409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,
+409,409,409,409,409,409,409,409,409,409,409,409,120,120,120,120,
+409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,
+409,409,409,409,409,409,409,409,409,409,120,120,120,120,120,120,
+410,410,410,410,410,410,410,410,410,410,411,120,120,120,412,412,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
/* block 50 */
-415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
-415,415,415,415,415,415,415,416,416,417,417,416,120,120,418,418,
-419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
-419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
-419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
-419,419,419,419,419,420,421,420,421,421,421,421,421,421,421,120,
-421,422,421,422,422,421,421,421,421,421,421,421,421,420,420,420,
-420,420,420,421,421,421,421,421,421,421,421,421,421,120,120,421,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,415,415,416,416,415,120,120,417,417,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,419,420,419,420,420,420,420,420,420,420,120,
+420,421,420,421,421,420,420,420,420,420,420,420,420,419,419,419,
+419,419,419,420,420,420,420,420,420,420,420,420,420,120,120,420,
/* block 51 */
-423,423,423,423,423,423,423,423,423,423,120,120,120,120,120,120,
-423,423,423,423,423,423,423,423,423,423,120,120,120,120,120,120,
-424,424,424,424,424,424,424,425,424,424,424,424,424,424,120,120,
-113,113,113,113,113,113,113,113,113,113,113,113,113,113,426,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+422,422,422,422,422,422,422,422,422,422,120,120,120,120,120,120,
+422,422,422,422,422,422,422,422,422,422,120,120,120,120,120,120,
+423,423,423,423,423,423,423,424,423,423,423,423,423,423,120,120,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,425,113,
+113,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 52 */
-427,427,427,427,428,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,427,430,427,427,427,427,427,428,427,428,428,428,
-428,428,427,428,428,429,429,429,429,429,429,429,120,120,120,120,
-431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432,
-432,433,433,433,433,433,433,433,433,433,433,427,427,427,427,427,
-427,427,427,427,433,433,433,433,433,433,433,433,433,120,120,120,
+426,426,426,426,427,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,426,429,426,426,426,426,426,427,426,427,427,427,
+427,427,426,427,427,428,428,428,428,428,428,428,120,120,120,120,
+430,430,430,430,430,430,430,430,430,430,431,431,431,431,431,431,
+431,432,432,432,432,432,432,432,432,432,432,426,426,426,426,426,
+426,426,426,426,432,432,432,432,432,432,432,432,432,120,120,120,
/* block 53 */
-434,434,435,436,436,436,436,436,436,436,436,436,436,436,436,436,
-436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,
-436,435,434,434,434,434,435,435,434,434,435,434,434,434,436,436,
-437,437,437,437,437,437,437,437,437,437,436,436,436,436,436,436,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,439,440,439,439,440,440,440,439,440,439,
-439,439,440,440,120,120,120,120,120,120,120,120,441,441,441,441,
+433,433,434,435,435,435,435,435,435,435,435,435,435,435,435,435,
+435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,
+435,434,433,433,433,433,434,434,433,433,434,433,433,433,435,435,
+436,436,436,436,436,436,436,436,436,436,435,435,435,435,435,435,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,
+437,437,437,437,437,437,438,439,438,438,439,439,439,438,439,438,
+438,438,439,439,120,120,120,120,120,120,120,120,440,440,440,440,
/* block 54 */
-442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,
-442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,
-442,442,442,442,443,443,443,443,443,443,443,443,444,444,444,444,
-444,444,444,444,443,443,444,444,120,120,120,445,445,445,445,445,
-446,446,446,446,446,446,446,446,446,446,120,120,120,442,442,442,
-447,447,447,447,447,447,447,447,447,447,448,448,448,448,448,448,
-448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,
-448,448,448,448,448,448,448,448,449,449,449,449,449,449,450,450,
+441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,442,442,442,442,442,442,442,442,443,443,443,443,
+443,443,443,443,442,442,443,443,120,120,120,444,444,444,444,444,
+445,445,445,445,445,445,445,445,445,445,120,120,120,441,441,441,
+446,446,446,446,446,446,446,446,446,446,447,447,447,447,447,447,
+447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,
+447,447,447,447,447,447,447,447,448,448,448,448,448,448,449,449,
/* block 55 */
-451,452,453,454,455,456,457,458,459,120,120,120,120,120,120,120,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,120,120,460,460,460,
-461,461,461,461,461,461,461,461,120,120,120,120,120,120,120,120,
-462,463,462,464,463,465,465,466,465,466,467,463,466,466,463,463,
-466,468,463,463,463,463,463,463,463,469,470,471,471,465,471,471,
-471,471,472,473,474,470,470,475,476,476,477,120,120,120,120,120,
+450,451,452,453,454,455,456,457,458,120,120,120,120,120,120,120,
+459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,
+459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,
+459,459,459,459,459,459,459,459,459,459,459,120,120,459,459,459,
+460,460,460,460,460,460,460,460,120,120,120,120,120,120,120,120,
+461,462,461,463,462,464,464,465,464,465,466,462,465,465,462,462,
+465,467,462,462,462,462,462,462,462,468,469,470,470,464,470,470,
+470,470,471,472,473,469,469,474,475,475,476,120,120,120,120,120,
/* block 56 */
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35,128,128,128,128,128,478,110,110,110,110,
+ 35, 35, 35, 35, 35, 35,128,128,128,128,128,477,110,110,110,110,
110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
110,110,110,110,110,110,110,110,110,110,110,110,110,121,121,121,
121,121,110,110,110,110,121,121,121,121,121, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,479,480, 35, 35, 35,481, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,478,479, 35, 35, 35,480, 35, 35,
/* block 57 */
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,482, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,481, 35,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,110,110,110,110,110,
110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,121,
114,114,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-113,113,113,113,113,113,113,113,113,113,120,113,113,113,113,113,
+113,113,113,113,113,113,113,113,482,113,120,113,113,113,113,113,
/* block 58 */
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
@@ -2335,8 +2354,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-113,113,113,113,113,113,113,113,113,113,113,113,113,426,426,426,
-426,113,426,426,426,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,425,425,425,
+425,113,425,425,425,113,113,113,113,113,113,113,113,113,113,113,
512,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 64 */
@@ -2511,7 +2530,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
/* block 81 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20,120, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -2550,12 +2569,12 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
550,120,120,120,120,120,120,120,120,120,120,120,120,120,120,551,
/* block 85 */
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,120,120,120,120,120,120,120,120,120,
-360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
-360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
-360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
-360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,120,120,120,120,120,120,120,120,120,
+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,
+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,
+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,
+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,
552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
@@ -2565,7 +2584,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
23, 27, 7, 8, 7, 8, 7, 8, 7, 8, 5, 5, 5, 5, 5,111,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 5, 5, 5, 5,
10, 5, 7,553, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+ 20, 20, 5,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -2633,7 +2652,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120,
572,572,582,582,582,582,572,572,572,572,572,572,572,572,572,572,
580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
-580,580,580,580,580,580,580,580,580,580,580,120,120,120,120,120,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
572,572,572,572,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -2693,7 +2712,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,120,120,120,120,120,120,120,120,120,120,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -2707,7 +2726,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+586,586,586,586,586,586,586,586,586,586,586,586,586,120,120,120,
/* block 101 */
587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
@@ -2757,11 +2776,11 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
192,193,192,193,192,193,192,193,192,193,597,598,192,193,192,193,
192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
192,193,192,193,192,193,192,193,192,193,192,193,192,193,599,198,
-200,200,200,600,552,552,552,552,552,552,552,552,552,552,600,479,
+200,200,200,600,552,552,552,552,552,552,552,552,552,552,600,478,
/* block 106 */
192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
-192,193,192,193,192,193,192,193,192,193,192,193,479,479,552,552,
+192,193,192,193,192,193,192,193,192,193,192,193,478,478,552,552,
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
@@ -2770,196 +2789,186 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
603,603,604,604,604,604,604,604,120,120,120,120,120,120,120,120,
/* block 107 */
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+605,605,605,605,605,605,605,605, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15,111,111,111,111,111,111,111,111,111,
15, 15, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
35, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
-110, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,605, 32, 33,
+110, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,606, 32, 33,
/* block 108 */
- 32, 33, 32, 33, 32, 33, 32, 33,111, 15, 15, 32, 33,606, 35, 22,
- 32, 33, 32, 33,607, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
- 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,608,609,610,611,608, 35,
-612,613,614,615, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
-120,120, 32, 33,616,617,618,120,120,120,120,120,120,120,120,120,
+ 32, 33, 32, 33, 32, 33, 32, 33,111, 15, 15, 32, 33,607, 35, 22,
+ 32, 33, 32, 33,608, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,609,610,611,612,609, 35,
+613,614,615,616, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
+120,120, 32, 33,617,618,619, 32, 33, 32, 33,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120, 22,110,110, 35, 22, 22, 22, 22, 22,
+120,120,120,120,120, 32, 33, 22,110,110, 35, 22, 22, 22, 22, 22,
/* block 109 */
-619,619,620,619,619,619,620,619,619,619,619,620,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,621,621,620,620,621,622,622,622,622,120,120,120,120,
-623,623,623,624,624,624,625,625,626,625,120,120,120,120,120,120,
-627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,
-627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,
-627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,
-627,627,627,627,628,628,628,628,120,120,120,120,120,120,120,120,
+620,620,621,620,620,620,621,620,620,620,620,621,620,620,620,620,
+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
+620,620,620,622,622,621,621,622,623,623,623,623,621,120,120,120,
+624,624,624,625,625,625,626,626,627,626,120,120,120,120,120,120,
+628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,
+628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,
+628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,
+628,628,628,628,629,629,629,629,120,120,120,120,120,120,120,120,
/* block 110 */
-629,629,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
-630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
-630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
-630,630,630,630,629,629,629,629,629,629,629,629,629,629,629,629,
-629,629,629,629,631,631,120,120,120,120,120,120,120,120,632,632,
-633,633,633,633,633,633,633,633,633,633,120,120,120,120,120,120,
-252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
-252,634,254,635,254,254,254,254,260,260,260,254,260,254,254,252,
+630,630,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
+631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
+631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,631,
+631,631,631,631,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,630,632,632,120,120,120,120,120,120,120,120,633,633,
+634,634,634,634,634,634,634,634,634,634,120,120,120,120,120,120,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,635,253,636,253,253,253,253,259,259,259,253,259,253,253,251,
/* block 111 */
-636,636,636,636,636,636,636,636,636,636,637,637,637,637,637,637,
-637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,
-637,637,637,637,637,637,638,638,638,638,638,638,638,638,639,640,
-641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,
-641,641,641,641,641,641,641,642,642,642,642,642,642,642,642,642,
-642,642,643,643,120,120,120,120,120,120,120,120,120,120,120,644,
-357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
-357,357,357,357,357,357,357,357,357,357,357,357,357,120,120,120,
+637,637,637,637,637,637,637,637,637,637,638,638,638,638,638,638,
+638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,
+638,638,638,638,638,638,639,639,639,639,639,639,639,639,640,641,
+642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,
+642,642,642,642,642,642,642,643,643,643,643,643,643,643,643,643,
+643,643,644,644,120,120,120,120,120,120,120,120,120,120,120,645,
+356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
+356,356,356,356,356,356,356,356,356,356,356,356,356,120,120,120,
/* block 112 */
-645,645,645,646,647,647,647,647,647,647,647,647,647,647,647,647,
-647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,
-647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,
-647,647,647,645,646,646,645,645,645,645,646,646,645,645,646,646,
-646,648,648,648,648,648,648,648,648,648,648,648,648,648,120,649,
-650,650,650,650,650,650,650,650,650,650,120,120,120,120,648,648,
-345,345,345,345,345,347,651,345,345,345,345,345,345,345,345,345,
-351,351,351,351,351,351,351,351,351,351,345,345,345,345,345,120,
+646,646,646,647,648,648,648,648,648,648,648,648,648,648,648,648,
+648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,
+648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,
+648,648,648,646,647,647,646,646,646,646,647,647,646,646,647,647,
+647,649,649,649,649,649,649,649,649,649,649,649,649,649,120,650,
+651,651,651,651,651,651,651,651,651,651,120,120,120,120,649,649,
+344,344,344,344,344,346,652,344,344,344,344,344,344,344,344,344,
+350,350,350,350,350,350,350,350,350,350,344,344,344,344,344,120,
/* block 113 */
-652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
-652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
-652,652,652,652,652,652,652,652,652,653,653,653,653,653,653,654,
-654,653,653,654,654,653,653,120,120,120,120,120,120,120,120,120,
-652,652,652,653,652,652,652,652,652,652,652,652,653,654,120,120,
-655,655,655,655,655,655,655,655,655,655,120,120,656,656,656,656,
-345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
-651,345,345,345,345,345,345,352,352,352,345,346,347,346,345,345,
+653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,
+653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,653,
+653,653,653,653,653,653,653,653,653,654,654,654,654,654,654,655,
+655,654,654,655,655,654,654,120,120,120,120,120,120,120,120,120,
+653,653,653,654,653,653,653,653,653,653,653,653,654,655,120,120,
+656,656,656,656,656,656,656,656,656,656,120,120,657,657,657,657,
+344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
+652,344,344,344,344,344,344,351,351,351,344,345,346,345,344,344,
/* block 114 */
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-658,657,658,658,658,657,657,658,658,657,657,657,657,657,658,658,
-657,658,657,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,657,657,659,660,660,
-661,661,661,661,661,661,661,661,661,661,661,662,663,663,662,662,
-664,664,661,665,665,662,663,120,120,120,120,120,120,120,120,120,
+658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
+658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
+658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
+659,658,659,659,659,658,658,659,659,658,658,658,658,658,659,659,
+658,659,658,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,658,658,660,661,661,
+662,662,662,662,662,662,662,662,662,662,662,663,664,664,663,663,
+665,665,662,666,666,663,664,120,120,120,120,120,120,120,120,120,
/* block 115 */
-120,360,360,360,360,360,360,120,120,360,360,360,360,360,360,120,
-120,360,360,360,360,360,360,120,120,120,120,120,120,120,120,120,
-360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
+120,359,359,359,359,359,359,120,120,359,359,359,359,359,359,120,
+120,359,359,359,359,359,359,120,120,120,120,120,120,120,120,120,
+359,359,359,359,359,359,359,120,359,359,359,359,359,359,359,120,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35,666, 35, 35, 35, 35, 35, 35, 35, 15,110,110,110,110,
- 35, 35, 35, 35, 35,128, 35, 35,120,120,120,120,120,120,120,120,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+ 35, 35, 35,667, 35, 35, 35, 35, 35, 35, 35, 15,110,110,110,110,
+ 35, 35, 35, 35, 35,128, 35, 35, 35,110, 15, 15,120,120,120,120,
+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,
/* block 116 */
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
-661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,
-661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,
-661,661,661,662,662,663,662,662,663,662,662,664,662,663,120,120,
-668,668,668,668,668,668,668,668,668,668,120,120,120,120,120,120,
+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,
+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,
+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,
+668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,
+662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,
+662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,662,
+662,662,662,663,663,664,663,663,664,663,663,665,663,664,120,120,
+669,669,669,669,669,669,669,669,669,669,120,120,120,120,120,120,
/* block 117 */
-669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
/* block 118 */
-670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,
/* block 119 */
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
/* block 120 */
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
/* block 121 */
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
/* block 122 */
-670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
-
-/* block 123 */
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-
-/* block 124 */
-670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
-670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
-670,670,670,670,120,120,120,120,120,120,120,120,120,120,120,120,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,120,120,120,120,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,120,120,120,120,
-
-/* block 125 */
+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,
671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,
671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,
+
+/* block 123 */
671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+670,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,670,671,671,671,
671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,670,671,671,671,671,671,671,671,671,671,671,671,
671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+
+/* block 124 */
+671,671,671,671,671,671,671,671,670,671,671,671,671,671,671,671,
671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,120,120,120,120,120,120,120,120,120,120,120,120,
+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
+357,357,357,357,357,357,357,120,120,120,120,358,358,358,358,358,
+358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+358,358,358,358,358,358,358,358,358,358,358,358,120,120,120,120,
-/* block 126 */
+/* block 125 */
672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
@@ -2969,6 +2978,16 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+/* block 126 */
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+
/* block 127 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
@@ -2991,53 +3010,53 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
/* block 129 */
35, 35, 35, 35, 35, 35, 35,120,120,120,120,120,120,120,120,120,
-120,120,120,206,206,206,206,206,120,120,120,120,120,215,212,215,
-215,215,215,215,215,215,215,215,215,673,215,215,215,215,215,215,
-215,215,215,215,215,215,215,120,215,215,215,215,215,120,215,120,
-215,215,120,215,215,120,215,215,215,215,215,215,215,215,215,215,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+120,120,120,206,206,206,206,206,120,120,120,120,120,214,211,214,
+214,214,214,214,214,214,214,214,214,674,214,214,214,214,214,214,
+214,214,214,214,214,214,214,120,214,214,214,214,214,120,214,120,
+214,214,120,214,214,120,214,214,214,214,214,214,214,214,214,214,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
/* block 130 */
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,674,674,674,674,674,674,674,674,674,674,674,674,674,674,
-674,674,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
+675,675,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
/* block 131 */
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
/* block 132 */
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225, 8, 7,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224, 8, 7,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
/* block 133 */
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-120,120,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,120,120,120,120,120,120,120,120,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+120,120,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-225,225,675,225,225,225,225,225,225,225,225,225,220,676,120,120,
+224,224,676,224,224,224,224,224,224,224,224,224,219,677,120,120,
/* block 134 */
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
@@ -3047,17 +3066,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
8, 7, 8, 7, 8,556,556, 7, 8, 5, 5, 5, 5, 16, 16, 16,
5, 5, 5,120, 5, 5, 5, 5, 10, 7, 8, 7, 8, 7, 8, 5,
5, 5, 9, 10, 9, 9, 9,120, 5, 6, 5, 5,120,120,120,120,
-225,225,225,225,225,120,225,225,225,225,225,225,225,225,225,225,
+224,224,224,224,224,120,224,224,224,224,224,224,224,224,224,224,
/* block 135 */
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,120,120, 24,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,120,120, 24,
/* block 136 */
120, 5, 5, 5, 6, 5, 5, 5, 7, 8, 5, 9, 5, 10, 5, 5,
@@ -3071,7 +3090,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
/* block 137 */
578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,677,677,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,678,678,
581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120,
120,120,581,581,581,581,581,581,120,120,581,581,581,581,581,581,
@@ -3080,39 +3099,39 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
511,511,511,511,511,511,511,511,511, 24, 24, 24, 20, 20,120,120,
/* block 138 */
-678,678,678,678,678,678,678,678,678,678,678,678,120,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,120,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,120,678,678,120,678,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,120,120,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,120,120,
+679,679,679,679,679,679,679,679,679,679,679,679,120,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,120,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,120,679,679,120,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,120,120,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 139 */
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,678,678,678,678,678,678,678,678,678,678,120,120,120,120,120,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,679,
+679,679,679,679,679,679,679,679,679,679,679,120,120,120,120,120,
/* block 140 */
-679,679,679,120,120,120,120,680,680,680,680,680,680,680,680,680,
-680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,
-680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,
-680,680,680,680,120,120,120,681,681,681,681,681,681,681,681,681,
-682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
-682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
-682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
-682,682,682,682,682,683,683,683,683,684,684,684,684,684,684,684,
+680,680,680,120,120,120,120,681,681,681,681,681,681,681,681,681,
+681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,
+681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,
+681,681,681,681,120,120,120,682,682,682,682,682,682,682,682,682,
+683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,
+683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,
+683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,683,
+683,683,683,683,683,684,684,684,684,685,685,685,685,685,685,685,
/* block 141 */
-684,684,684,684,684,684,684,684,684,684,683,683,684,684,684,120,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,
-684,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+685,685,685,685,685,685,685,685,685,685,684,684,685,685,685,120,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,
+685,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -3130,159 +3149,159 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 143 */
-685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
-685,685,685,685,685,685,685,685,685,685,685,685,685,120,120,120,
-686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
-686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
-686,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-687,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,
-688,688,688,688,688,688,688,688,688,688,688,688,120,120,120,120,
+686,686,686,686,686,686,686,686,686,686,686,686,686,120,120,120,
+687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,
+687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,
+687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,
+687,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+688,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
+689,689,689,689,689,689,689,689,689,689,689,689,120,120,120,120,
/* block 144 */
-689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
-689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
-690,690,690,690,120,120,120,120,120,120,120,120,120,689,689,689,
-691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
-691,692,691,691,691,691,691,691,691,691,692,120,120,120,120,120,
-693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,
-693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,
-693,693,693,693,693,693,694,694,694,694,694,120,120,120,120,120,
+690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,
+690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,
+691,691,691,691,120,120,120,120,120,120,120,120,120,690,690,690,
+692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,
+692,693,692,692,692,692,692,692,692,692,693,120,120,120,120,120,
+694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,
+694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,
+694,694,694,694,694,694,695,695,695,695,695,120,120,120,120,120,
/* block 145 */
-695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
-695,695,695,695,695,695,695,695,695,695,695,695,695,695,120,696,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,120,120,120,120,697,697,697,697,697,697,697,697,
-698,699,699,699,699,699,120,120,120,120,120,120,120,120,120,120,
+696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,696,
+696,696,696,696,696,696,696,696,696,696,696,696,696,696,120,697,
+698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,
+698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,
+698,698,698,698,120,120,120,120,698,698,698,698,698,698,698,698,
+699,700,700,700,700,700,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 146 */
-700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
-700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
-700,700,700,700,700,700,700,700,701,701,701,701,701,701,701,701,
701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,
701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,
+701,701,701,701,701,701,701,701,702,702,702,702,702,702,702,702,
702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
-702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
+703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
+703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
+703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
/* block 147 */
-703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
-703,703,703,703,703,703,703,703,703,703,703,703,703,703,120,120,
-704,704,704,704,704,704,704,704,704,704,120,120,120,120,120,120,
-705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,
-705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,
-705,705,705,705,120,120,120,120,706,706,706,706,706,706,706,706,
+704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,704,
+704,704,704,704,704,704,704,704,704,704,704,704,704,704,120,120,
+705,705,705,705,705,705,705,705,705,705,120,120,120,120,120,120,
+706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,
706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,
-706,706,706,706,706,706,706,706,706,706,706,706,120,120,120,120,
+706,706,706,706,120,120,120,120,707,707,707,707,707,707,707,707,
+707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
+707,707,707,707,707,707,707,707,707,707,707,707,120,120,120,120,
/* block 148 */
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,707,707,707,707,707,120,120,120,120,120,120,120,120,
-708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
-708,708,708,708,120,120,120,120,120,120,120,120,120,120,120,709,
+708,708,708,708,708,708,708,708,120,120,120,120,120,120,120,120,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
+709,709,709,709,120,120,120,120,120,120,120,120,120,120,120,710,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 149 */
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
/* block 150 */
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,710,120,120,120,120,120,120,120,120,120,
-710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
-710,710,710,710,710,710,120,120,120,120,120,120,120,120,120,120,
-710,710,710,710,710,710,710,710,120,120,120,120,120,120,120,120,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,120,120,120,120,120,120,120,120,120,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,120,120,120,120,120,120,120,120,120,120,
+711,711,711,711,711,711,711,711,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 151 */
-711,711,711,711,711,711,120,120,711,120,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
-711,711,711,711,711,711,120,711,711,120,120,120,711,120,120,711,
+712,712,712,712,712,712,120,120,712,120,712,712,712,712,712,712,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,120,713,714,714,714,714,714,714,714,714,
-715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,
-715,715,715,715,715,715,715,716,716,717,717,717,717,717,717,717,
+712,712,712,712,712,712,120,712,712,120,120,120,712,120,120,712,
+713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,
+713,713,713,713,713,713,120,714,715,715,715,715,715,715,715,715,
+716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,
+716,716,716,716,716,716,716,717,717,718,718,718,718,718,718,718,
/* block 152 */
-718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,
-718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,120,
-120,120,120,120,120,120,120,719,719,719,719,719,719,719,719,719,
+719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,
+719,719,719,719,719,719,719,719,719,719,719,719,719,719,719,120,
+120,120,120,120,120,120,120,720,720,720,720,720,720,720,720,720,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,
-720,720,720,120,720,720,120,120,120,120,120,721,721,721,721,721,
+721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,
+721,721,721,120,721,721,120,120,120,120,120,722,722,722,722,722,
/* block 153 */
-722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,
-722,722,722,722,722,722,723,723,723,723,723,723,120,120,120,724,
-725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
-725,725,725,725,725,725,725,725,725,725,120,120,120,120,120,726,
+723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,
+723,723,723,723,723,723,724,724,724,724,724,724,120,120,120,725,
+726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
+726,726,726,726,726,726,726,726,726,726,120,120,120,120,120,727,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 154 */
-727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
-727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,
-728,728,728,728,728,728,728,728,120,120,120,120,729,729,728,728,
-729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
-120,120,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
-729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
+728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,
729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
+729,729,729,729,729,729,729,729,120,120,120,120,730,730,729,729,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+120,120,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
/* block 155 */
-730,731,731,731,120,731,731,120,120,120,120,120,731,731,731,731,
-730,730,730,730,120,730,730,730,120,730,730,730,730,730,730,730,
-730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
-730,730,730,730,730,730,120,120,731,731,731,120,120,120,120,731,
-732,732,732,732,732,732,732,732,732,120,120,120,120,120,120,120,
+731,732,732,732,120,732,732,120,120,120,120,120,732,732,732,732,
+731,731,731,731,120,731,731,731,120,731,731,731,731,731,731,731,
+731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,
+731,731,731,731,731,731,120,120,732,732,732,120,120,120,120,732,
733,733,733,733,733,733,733,733,733,120,120,120,120,120,120,120,
-734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,
-734,734,734,734,734,734,734,734,734,734,734,734,734,735,735,736,
+734,734,734,734,734,734,734,734,734,120,120,120,120,120,120,120,
+735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,
+735,735,735,735,735,735,735,735,735,735,735,735,735,736,736,737,
/* block 156 */
-737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
-737,737,737,737,737,737,737,737,737,737,737,737,737,738,738,738,
+738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,
+738,738,738,738,738,738,738,738,738,738,738,738,738,739,739,739,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-739,739,739,739,739,739,739,739,740,739,739,739,739,739,739,739,
-739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
-739,739,739,739,739,741,741,120,120,120,120,742,742,742,742,742,
-743,743,743,743,743,743,743,120,120,120,120,120,120,120,120,120,
+740,740,740,740,740,740,740,740,741,740,740,740,740,740,740,740,
+740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,
+740,740,740,740,740,742,742,120,120,120,120,743,743,743,743,743,
+744,744,744,744,744,744,744,120,120,120,120,120,120,120,120,120,
/* block 157 */
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,744,744,120,120,120,745,745,745,745,745,745,745,
-746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,
-746,746,746,746,746,746,120,120,747,747,747,747,747,747,747,747,
-748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,
-748,748,748,120,120,120,120,120,749,749,749,749,749,749,749,749,
+745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,
+745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,
+745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,
+745,745,745,745,745,745,120,120,120,746,746,746,746,746,746,746,
+747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,
+747,747,747,747,747,747,120,120,748,748,748,748,748,748,748,748,
+749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,749,
+749,749,749,120,120,120,120,120,750,750,750,750,750,750,750,750,
/* block 158 */
-750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,
-750,750,120,120,120,120,120,120,120,751,751,751,751,120,120,120,
-120,120,120,120,120,120,120,120,120,752,752,752,752,752,752,752,
+751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,
+751,751,120,120,120,120,120,120,120,752,752,752,752,120,120,120,
+120,120,120,120,120,120,120,120,120,753,753,753,753,753,753,753,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -3290,30 +3309,30 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 159 */
-753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
-753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
-753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
-753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
-753,753,753,753,753,753,753,753,753,120,120,120,120,120,120,120,
+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
+754,754,754,754,754,754,754,754,754,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 160 */
-754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
-754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
-754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
-754,754,754,120,120,120,120,120,120,120,120,120,120,120,120,120,
755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,
755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,
755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,
-755,755,755,120,120,120,120,120,120,120,756,756,756,756,756,756,
+755,755,755,120,120,120,120,120,120,120,120,120,120,120,120,120,
+756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,
+756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,
+756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,
+756,756,756,120,120,120,120,120,120,120,757,757,757,757,757,757,
/* block 161 */
-757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,
-757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,
-757,757,757,757,758,758,758,758,120,120,120,120,120,120,120,120,
-759,759,759,759,759,759,759,759,759,759,120,120,120,120,120,120,
+758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,
+758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,758,
+758,758,758,758,759,759,759,759,120,120,120,120,120,120,120,120,
+760,760,760,760,760,760,760,760,760,760,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -3326,350 +3345,370 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,
-760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,120,
+761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,
+761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,120,
/* block 163 */
-761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,
-761,761,761,761,761,761,761,761,761,761,761,761,761,762,762,762,
-762,762,762,762,762,762,762,761,120,120,120,120,120,120,120,120,
-763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
-763,763,763,763,763,763,764,764,764,764,764,764,764,764,764,764,
-764,765,765,765,765,766,766,766,766,766,120,120,120,120,120,120,
+762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,
+762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,
+762,762,762,762,762,762,762,762,762,762,120,763,763,764,120,120,
+762,762,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 164 */
+765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,
+765,765,765,765,765,765,765,765,765,765,765,765,765,766,766,766,
+766,766,766,766,766,766,766,765,120,120,120,120,120,120,120,120,
+767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,
+767,767,767,767,767,767,768,768,768,768,768,768,768,768,768,768,
+768,769,769,769,769,770,770,770,770,770,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 165 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,771,
+771,771,771,771,771,772,772,772,772,772,772,772,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,
-767,767,767,767,767,767,767,120,120,120,120,120,120,120,120,120,
-
-/* block 165 */
-768,769,768,770,770,770,770,770,770,770,770,770,770,770,770,770,
-770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,
-770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,
-770,770,770,770,770,770,770,770,769,769,769,769,769,769,769,769,
-769,769,769,769,769,769,769,771,771,771,771,771,771,771,120,120,
-120,120,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
-772,772,772,772,772,772,773,773,773,773,773,773,773,773,773,773,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,769,
+773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,
+773,773,773,773,773,773,773,120,120,120,120,120,120,120,120,120,
/* block 166 */
-774,774,775,776,776,776,776,776,776,776,776,776,776,776,776,776,
+774,775,774,776,776,776,776,776,776,776,776,776,776,776,776,776,
776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
-775,775,775,774,774,774,774,775,775,774,774,777,777,778,777,777,
-777,777,120,120,120,120,120,120,120,120,120,120,120,778,120,120,
-779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,
-779,779,779,779,779,779,779,779,779,120,120,120,120,120,120,120,
-780,780,780,780,780,780,780,780,780,780,120,120,120,120,120,120,
+776,776,776,776,776,776,776,776,775,775,775,775,775,775,775,775,
+775,775,775,775,775,775,775,777,777,777,777,777,777,777,120,120,
+120,120,778,778,778,778,778,778,778,778,778,778,778,778,778,778,
+778,778,778,778,778,778,779,779,779,779,779,779,779,779,779,779,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,775,
/* block 167 */
-781,781,781,782,782,782,782,782,782,782,782,782,782,782,782,782,
+780,780,781,782,782,782,782,782,782,782,782,782,782,782,782,782,
782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,
-782,782,782,782,782,782,782,781,781,781,781,781,783,781,781,781,
-781,781,781,781,781,120,784,784,784,784,784,784,784,784,784,784,
-785,785,785,785,782,783,783,120,120,120,120,120,120,120,120,120,
-786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,
-786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,
-786,786,786,787,788,788,786,120,120,120,120,120,120,120,120,120,
+782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,
+781,781,781,780,780,780,780,781,781,780,780,783,783,784,783,783,
+783,783,120,120,120,120,120,120,120,120,120,120,120,784,120,120,
+785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,785,
+785,785,785,785,785,785,785,785,785,120,120,120,120,120,120,120,
+786,786,786,786,786,786,786,786,786,786,120,120,120,120,120,120,
/* block 168 */
-789,789,790,791,791,791,791,791,791,791,791,791,791,791,791,791,
-791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,
-791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,
-791,791,791,790,790,790,789,789,789,789,789,789,789,789,789,790,
-790,791,792,792,791,793,793,793,793,789,789,789,789,793,120,120,
-794,794,794,794,794,794,794,794,794,794,791,793,791,793,793,793,
-120,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,
-795,795,795,795,795,120,120,120,120,120,120,120,120,120,120,120,
+787,787,787,788,788,788,788,788,788,788,788,788,788,788,788,788,
+788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,
+788,788,788,788,788,788,788,787,787,787,787,787,789,787,787,787,
+787,787,787,787,787,120,790,790,790,790,790,790,790,790,790,790,
+791,791,791,791,788,789,789,788,120,120,120,120,120,120,120,120,
+792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,
+792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,792,
+792,792,792,793,794,794,792,120,120,120,120,120,120,120,120,120,
/* block 169 */
-796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
-796,796,120,796,796,796,796,796,796,796,796,796,796,796,796,796,
-796,796,796,796,796,796,796,796,796,796,796,796,797,797,797,798,
-798,798,797,797,798,797,798,798,799,799,799,799,799,799,798,120,
+795,795,796,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,
+797,797,797,796,796,796,795,795,795,795,795,795,795,795,795,796,
+796,797,798,798,797,799,799,799,799,795,795,795,795,799,796,795,
+800,800,800,800,800,800,800,800,800,800,797,799,797,799,799,799,
+120,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,
+801,801,801,801,801,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 170 */
+802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,
+802,802,120,802,802,802,802,802,802,802,802,802,802,802,802,802,
+802,802,802,802,802,802,802,802,802,802,802,802,803,803,803,804,
+804,804,803,803,804,803,804,804,805,805,805,805,805,805,804,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 170 */
-800,800,800,800,800,800,800,120,800,120,800,800,800,800,120,800,
-800,800,800,800,800,800,800,800,800,800,800,800,800,800,120,800,
-800,800,800,800,800,800,800,800,800,801,120,120,120,120,120,120,
-802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,
-802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,
-802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,803,
-804,804,804,803,803,803,803,803,803,803,803,120,120,120,120,120,
-805,805,805,805,805,805,805,805,805,805,120,120,120,120,120,120,
-
/* block 171 */
-806,807,808,809,120,810,810,810,810,810,810,810,810,120,120,810,
-810,120,120,810,810,810,810,810,810,810,810,810,810,810,810,810,
-810,810,810,810,810,810,810,810,810,120,810,810,810,810,810,810,
-810,120,810,810,120,810,810,810,810,810,120,811,807,810,812,808,
-806,808,808,808,808,120,120,808,808,120,120,808,808,808,120,120,
-810,120,120,120,120,120,120,812,120,120,120,120,120,810,810,810,
-810,810,808,808,120,120,806,806,806,806,806,806,806,120,120,120,
-806,806,806,806,806,120,120,120,120,120,120,120,120,120,120,120,
+806,806,806,806,806,806,806,120,806,120,806,806,806,806,120,806,
+806,806,806,806,806,806,806,806,806,806,806,806,806,806,120,806,
+806,806,806,806,806,806,806,806,806,807,120,120,120,120,120,120,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,
+808,808,808,808,808,808,808,808,808,808,808,808,808,808,808,809,
+810,810,810,809,809,809,809,809,809,809,809,120,120,120,120,120,
+811,811,811,811,811,811,811,811,811,811,120,120,120,120,120,120,
/* block 172 */
-813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,
-813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,
-813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,
-813,813,813,813,813,814,814,814,815,815,815,815,815,815,815,815,
-814,814,815,815,815,814,815,813,813,813,813,816,816,816,816,816,
-817,817,817,817,817,817,817,817,817,817,120,816,120,816,815,813,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+812,813,814,815,120,816,816,816,816,816,816,816,816,120,120,816,
+816,120,120,816,816,816,816,816,816,816,816,816,816,816,816,816,
+816,816,816,816,816,816,816,816,816,120,816,816,816,816,816,816,
+816,120,816,816,120,816,816,816,816,816,120,817,813,816,818,814,
+812,814,814,814,814,120,120,814,814,120,120,814,814,814,120,120,
+816,120,120,120,120,120,120,818,120,120,120,120,120,816,816,816,
+816,816,814,814,120,120,812,812,812,812,812,812,812,120,120,120,
+812,812,812,812,812,120,120,120,120,120,120,120,120,120,120,120,
/* block 173 */
-818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
-818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
-818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
-819,820,820,821,821,821,821,821,821,820,821,820,820,819,820,821,
-821,820,821,821,818,818,822,818,120,120,120,120,120,120,120,120,
-823,823,823,823,823,823,823,823,823,823,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
+819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
+819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,
+819,819,819,819,819,820,820,820,821,821,821,821,821,821,821,821,
+820,820,821,821,821,820,821,819,819,819,819,822,822,822,822,822,
+823,823,823,823,823,823,823,823,823,823,822,822,120,822,821,819,
+819,819,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 174 */
824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,825,
-826,826,827,827,827,827,120,120,826,826,826,826,827,827,826,827,
-827,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,
-828,828,828,828,828,828,828,828,824,824,824,824,827,827,120,120,
+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
+825,826,826,827,827,827,827,827,827,826,827,826,826,825,826,827,
+827,826,827,827,824,824,828,824,120,120,120,120,120,120,120,120,
+829,829,829,829,829,829,829,829,829,829,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 175 */
-829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
-829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
-829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
-830,830,830,831,831,831,831,831,831,831,831,830,830,831,830,831,
-831,832,832,832,829,120,120,120,120,120,120,120,120,120,120,120,
-833,833,833,833,833,833,833,833,833,833,120,120,120,120,120,120,
-395,395,395,395,395,395,395,395,395,395,395,395,395,120,120,120,
+830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,
+830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,
+830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,831,
+832,832,833,833,833,833,120,120,832,832,832,832,833,833,832,833,
+833,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,
+834,834,834,834,834,834,834,834,830,830,830,830,833,833,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 176 */
-834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,
-834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,
-834,834,834,834,834,834,834,834,834,834,834,835,836,835,836,836,
-835,835,835,835,835,835,836,835,834,120,120,120,120,120,120,120,
-837,837,837,837,837,837,837,837,837,837,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,
+835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,
+835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,
+836,836,836,837,837,837,837,837,837,837,837,836,836,837,836,837,
+837,838,838,838,835,120,120,120,120,120,120,120,120,120,120,120,
+839,839,839,839,839,839,839,839,839,839,120,120,120,120,120,120,
+394,394,394,394,394,394,394,394,394,394,394,394,394,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 177 */
-838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
-838,838,838,838,838,838,838,838,838,838,838,120,120,839,839,839,
-840,840,839,839,839,839,840,839,839,839,839,839,120,120,120,120,
-841,841,841,841,841,841,841,841,841,841,842,842,843,843,843,844,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,
+840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,
+840,840,840,840,840,840,840,840,840,840,840,841,842,841,842,842,
+841,841,841,841,841,841,842,841,840,120,120,120,120,120,120,120,
+843,843,843,843,843,843,843,843,843,843,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 178 */
-845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,
-845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,
-845,845,845,845,845,845,845,845,845,845,845,845,846,846,846,847,
-847,847,847,847,847,847,847,847,846,847,847,848,120,120,120,120,
+844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,
+844,844,844,844,844,844,844,844,844,844,844,120,120,845,845,845,
+846,846,845,845,845,845,846,845,845,845,845,845,120,120,120,120,
+847,847,847,847,847,847,847,847,847,847,848,848,849,849,849,850,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 179 */
+851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,
+851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,
+851,851,851,851,851,851,851,851,851,851,851,851,852,852,852,853,
+853,853,853,853,853,853,853,853,852,853,853,854,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,
-849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,
-850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,
-850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,
-851,851,851,851,851,851,851,851,851,851,852,852,852,852,852,852,
-852,852,852,120,120,120,120,120,120,120,120,120,120,120,120,853,
/* block 180 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-854,854,854,854,854,854,854,854,120,120,854,854,854,854,854,854,
-854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,
-854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,
-854,855,855,855,856,856,856,856,120,120,856,856,855,855,855,855,
-856,854,857,854,855,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,
+855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,855,
+856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,
+856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,856,
+857,857,857,857,857,857,857,857,857,857,858,858,858,858,858,858,
+858,858,858,120,120,120,120,120,120,120,120,120,120,120,120,859,
/* block 181 */
-858,859,859,859,859,859,859,859,859,859,859,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-858,858,858,859,859,859,859,859,859,860,861,859,859,859,859,862,
-862,862,862,862,862,862,862,859,120,120,120,120,120,120,120,120,
-863,864,864,864,864,864,864,865,865,864,864,864,863,863,863,863,
-863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,
-863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,
+860,860,860,860,860,860,860,120,120,860,120,120,860,860,860,860,
+860,860,860,860,120,860,860,120,860,860,860,860,860,860,860,860,
+860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,
+861,862,862,862,862,862,120,862,862,120,120,863,863,862,863,864,
+862,864,862,863,865,865,865,120,120,120,120,120,120,120,120,120,
+866,866,866,866,866,866,866,866,866,866,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 182 */
-863,863,863,863,866,866,866,866,866,866,864,864,864,864,864,864,
-864,864,864,864,864,864,864,865,864,864,867,867,867,863,867,867,
-867,867,867,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,
-868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,
-868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,
-868,868,868,868,868,868,868,868,868,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+867,867,867,867,867,867,867,867,120,120,867,867,867,867,867,867,
+867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,
+867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,867,
+867,868,868,868,869,869,869,869,120,120,869,869,868,868,868,868,
+869,867,870,867,868,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 183 */
-869,869,869,869,869,869,869,869,869,120,869,869,869,869,869,869,
-869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,
-869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,870,
-871,871,871,871,871,871,871,120,871,871,871,871,871,871,870,871,
-869,872,872,872,872,872,120,120,120,120,120,120,120,120,120,120,
-873,873,873,873,873,873,873,873,873,873,874,874,874,874,874,874,
-874,874,874,874,874,874,874,874,874,874,874,874,874,120,120,120,
-875,875,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
+871,872,872,872,872,872,872,872,872,872,872,871,871,871,871,871,
+871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,
+871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,871,
+871,871,871,872,872,872,872,872,872,873,874,872,872,872,872,875,
+875,875,875,875,875,875,875,872,120,120,120,120,120,120,120,120,
+876,877,877,877,877,877,877,878,878,877,877,877,876,876,876,876,
+876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
+876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
/* block 184 */
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-120,120,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,120,878,877,877,877,877,877,877,
-877,878,877,877,878,877,877,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+876,876,876,876,879,879,879,879,879,879,877,877,877,877,877,877,
+877,877,877,877,877,877,877,878,877,877,880,880,880,876,880,880,
+880,880,880,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,
+881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,
+881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,
+881,881,881,881,881,881,881,881,881,120,120,120,120,120,120,120,
/* block 185 */
-879,879,879,879,879,879,879,120,879,879,120,879,879,879,879,879,
-879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,
-879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,
-879,880,880,880,880,880,880,120,120,120,880,120,880,880,120,880,
-880,880,880,880,880,880,881,880,120,120,120,120,120,120,120,120,
-882,882,882,882,882,882,882,882,882,882,120,120,120,120,120,120,
-883,883,883,883,883,883,120,883,883,120,883,883,883,883,883,883,
-883,883,883,883,883,883,883,883,883,883,883,883,883,883,883,883,
+882,882,882,882,882,882,882,882,882,120,882,882,882,882,882,882,
+882,882,882,882,882,882,882,882,882,882,882,882,882,882,882,882,
+882,882,882,882,882,882,882,882,882,882,882,882,882,882,882,883,
+884,884,884,884,884,884,884,120,884,884,884,884,884,884,883,884,
+882,885,885,885,885,885,120,120,120,120,120,120,120,120,120,120,
+886,886,886,886,886,886,886,886,886,886,887,887,887,887,887,887,
+887,887,887,887,887,887,887,887,887,887,887,887,887,120,120,120,
+888,888,889,889,889,889,889,889,889,889,889,889,889,889,889,889,
/* block 186 */
-883,883,883,883,883,883,883,883,883,883,884,884,884,884,884,120,
-885,885,120,884,884,885,884,885,883,120,120,120,120,120,120,120,
-886,886,886,886,886,886,886,886,886,886,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+889,889,889,889,889,889,889,889,889,889,889,889,889,889,889,889,
+120,120,890,890,890,890,890,890,890,890,890,890,890,890,890,890,
+890,890,890,890,890,890,890,890,120,891,890,890,890,890,890,890,
+890,891,890,890,891,890,890,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 187 */
+892,892,892,892,892,892,892,120,892,892,120,892,892,892,892,892,
+892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,
+892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,
+892,893,893,893,893,893,893,120,120,120,893,120,893,893,120,893,
+893,893,893,893,893,893,894,893,120,120,120,120,120,120,120,120,
+895,895,895,895,895,895,895,895,895,895,120,120,120,120,120,120,
+896,896,896,896,896,896,120,896,896,120,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+
+/* block 188 */
+896,896,896,896,896,896,896,896,896,896,897,897,897,897,897,120,
+898,898,120,897,897,898,897,898,896,120,120,120,120,120,120,120,
+899,899,899,899,899,899,899,899,899,899,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-887,887,887,887,887,887,887,887,887,887,887,887,887,887,887,887,
-887,887,887,888,888,889,889,890,890,120,120,120,120,120,120,120,
-/* block 188 */
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+/* block 189 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,
-294,294,891,294,891,296,296,296,296,296,296,296,296,297,297,297,
-297,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,
-296,296,120,120,120,120,120,120,120,120,120,120,120,120,120,892,
-
-/* block 189 */
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-
-/* block 190 */
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,
+900,900,900,901,901,902,902,903,903,120,120,120,120,120,120,120,
+
+/* block 190 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+590,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,
+293,293,904,293,904,295,295,295,295,295,295,295,295,296,296,296,
+296,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,
+295,295,120,120,120,120,120,120,120,120,120,120,120,120,120,905,
/* block 191 */
-894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
-894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
-894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
-894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
-894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
-894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
-894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,120,
-895,895,895,895,895,120,120,120,120,120,120,120,120,120,120,120,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
/* block 192 */
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,120,120,120,120,120,120,120,120,120,120,120,120,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 193 */
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,
+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,
+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,
+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,
+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,
+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,
+907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,120,
+908,908,908,908,908,120,120,120,120,120,120,120,120,120,120,120,
/* block 194 */
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,120,
-897,897,897,897,897,897,897,897,897,120,120,120,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,906,
+906,906,906,906,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 195 */
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
/* block 196 */
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
-898,898,898,898,898,898,898,120,120,120,120,120,120,120,120,120,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,
+909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,120,
+910,910,910,910,910,910,910,910,910,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 197 */
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+
+/* block 198 */
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+911,911,911,911,911,911,911,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 199 */
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
@@ -3679,38 +3718,38 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
-/* block 198 */
+/* block 200 */
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
601,601,601,601,601,601,601,601,601,120,120,120,120,120,120,120,
-899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,
-899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,120,
-900,900,900,900,900,900,900,900,900,900,120,120,120,120,901,901,
+912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
+912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,120,
+913,913,913,913,913,913,913,913,913,913,120,120,120,120,914,914,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 199 */
+/* block 201 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,120,120,
-903,903,903,903,903,904,120,120,120,120,120,120,120,120,120,120,
+915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
+915,915,915,915,915,915,915,915,915,915,915,915,915,915,120,120,
+916,916,916,916,916,917,120,120,120,120,120,120,120,120,120,120,
-/* block 200 */
-905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,
-905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,
-905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,
-906,906,906,906,906,906,906,907,907,907,907,907,908,908,908,908,
-909,909,909,909,907,908,120,120,120,120,120,120,120,120,120,120,
-910,910,910,910,910,910,910,910,910,910,120,911,911,911,911,911,
-911,911,120,905,905,905,905,905,905,905,905,905,905,905,905,905,
-905,905,905,905,905,905,905,905,120,120,120,120,120,905,905,905,
+/* block 202 */
+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
+919,919,919,919,919,919,919,920,920,920,920,920,921,921,921,921,
+922,922,922,922,920,921,120,120,120,120,120,120,120,120,120,120,
+923,923,923,923,923,923,923,923,923,923,120,924,924,924,924,924,
+924,924,120,918,918,918,918,918,918,918,918,918,918,918,918,918,
+918,918,918,918,918,918,918,918,120,120,120,120,120,918,918,918,
-/* block 201 */
-905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,
+/* block 203 */
+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -3719,19 +3758,19 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 202 */
+/* block 204 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
-912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
-913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,
-913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,
+925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,
+925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,925,
+926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,
+926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,926,
-/* block 203 */
-914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,
-914,914,914,914,914,914,914,915,915,915,915,120,120,120,120,120,
+/* block 205 */
+927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,
+927,927,927,927,927,927,927,928,928,928,928,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -3739,57 +3778,77 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 204 */
-916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,
-916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,
-916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,
-916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,
-916,916,916,916,916,916,916,916,916,916,916,120,120,120,120,917,
-916,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
-918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
-918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
+/* block 206 */
+929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,
+929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,
+929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,
+929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,
+929,929,929,929,929,929,929,929,929,929,929,120,120,120,120,930,
+929,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,
+931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,
+931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,931,
-/* block 205 */
-918,918,918,918,918,918,918,918,120,120,120,120,120,120,120,917,
-917,917,917,919,919,919,919,919,919,919,919,919,919,919,919,919,
-120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+/* block 207 */
+931,931,931,931,931,931,931,931,120,120,120,120,120,120,120,930,
+930,930,930,932,932,932,932,932,932,932,932,932,932,932,932,932,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-920,921, 5,111,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-
-/* block 206 */
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-
-/* block 207 */
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,120,120,120,120,120,120,120,120,
+933,934, 5,111,935,120,120,120,120,120,120,120,120,120,120,120,
+936,936,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 208 */
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
-922,922,922,120,120,120,120,120,120,120,120,120,120,120,120,120,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
/* block 209 */
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,937,
+937,937,937,937,937,937,937,937,120,120,120,120,120,120,120,120,
+
+/* block 210 */
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+
+/* block 211 */
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,
+938,938,938,938,938,938,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 212 */
+937,937,937,937,937,937,937,937,937,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 213 */
578,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
@@ -3799,7 +3858,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
-/* block 210 */
+/* block 214 */
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
@@ -3809,7 +3868,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
-/* block 211 */
+/* block 215 */
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -3817,49 +3876,49 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
573,573,573,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,578,578,578,578,120,120,120,120,120,120,120,120,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
-/* block 212 */
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+/* block 216 */
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
-/* block 213 */
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,120,120,120,120,
+/* block 217 */
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,939,
+939,939,939,939,939,939,939,939,939,939,939,939,120,120,120,120,
-/* block 214 */
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,924,924,120,120,120,120,120,
-924,924,924,924,924,924,924,924,924,924,924,924,924,120,120,120,
+/* block 218 */
+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,
+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,
+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,
+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,
+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,
+940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,940,
+940,940,940,940,940,940,940,940,940,940,940,120,120,120,120,120,
+940,940,940,940,940,940,940,940,940,940,940,940,940,120,120,120,
-/* block 215 */
-924,924,924,924,924,924,924,924,924,120,120,120,120,120,120,120,
-924,924,924,924,924,924,924,924,924,924,120,120,925,926,926,927,
-928,928,928,928,120,120,120,120,120,120,120,120,120,120,120,120,
+/* block 219 */
+940,940,940,940,940,940,940,940,940,120,120,120,120,120,120,120,
+940,940,940,940,940,940,940,940,940,940,120,120,941,942,942,943,
+944,944,944,944,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 216 */
+/* block 220 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -3869,17 +3928,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,120,
-/* block 217 */
+/* block 221 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20,929,930,113,113,113, 20, 20, 20,930,929,929,
-929,929,929, 24, 24, 24, 24, 24, 24, 24, 24,113,113,113,113,113,
+ 20, 20, 20, 20, 20,945,946,113,113,113, 20, 20, 20,946,945,945,
+945,945,945, 24, 24, 24, 24, 24, 24, 24, 24,113,113,113,113,113,
-/* block 218 */
+/* block 222 */
113,113,113, 20, 20,113,113,113,113,113,113,113, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20,113,113,113,113, 20, 20,
@@ -3889,17 +3948,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 219 */
-684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
-684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
-684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
-684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
-684,684,931,931,931,684,120,120,120,120,120,120,120,120,120,120,
+/* block 223 */
+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
+685,685,947,947,947,685,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 220 */
+/* block 224 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -3909,7 +3968,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 221 */
+/* block 225 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -3919,7 +3978,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,
582,582, 25, 25, 25, 25, 25, 25, 25,120,120,120,120,120,120,120,
-/* block 222 */
+/* block 226 */
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514,
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
@@ -3929,7 +3988,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513,
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-/* block 223 */
+/* block 227 */
513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
514,514,514,514,514,514,514,514,514,514,514,514,513,120,513,513,
120,120,513,120,120,513,513,120,120,513,513,513,513,120,513,513,
@@ -3939,7 +3998,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514,
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
-/* block 224 */
+/* block 228 */
514,514,514,514,513,513,120,513,513,513,513,120,120,513,513,513,
513,513,513,513,513,120,513,513,513,513,513,513,513,120,514,514,
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
@@ -3949,7 +4008,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
514,514,514,514,514,514,514,514,514,514,514,514,513,513,513,513,
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-/* block 225 */
+/* block 229 */
513,513,513,513,513,513,514,514,514,514,514,514,514,514,514,514,
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
@@ -3959,7 +4018,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
513,513,513,513,513,513,513,513,513,513,513,513,513,513,514,514,
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
-/* block 226 */
+/* block 230 */
514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513,
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
@@ -3969,7 +4028,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-/* block 227 */
+/* block 231 */
513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514,
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
514,514,514,514,514,514,120,120,513,513,513,513,513,513,513,513,
@@ -3979,7 +4038,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
514,514,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
513,513,513,513,513,513,513,513,513,513,513, 9,514,514,514,514,
-/* block 228 */
+/* block 232 */
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
514,514,514,514,514, 9,514,514,514,514,514,514,513,513,513,513,
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
@@ -3989,7 +4048,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 9,
514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
-/* block 229 */
+/* block 233 */
514,514,514,514,514,514,514,514,514, 9,514,514,514,514,514,514,
513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
513,513,513,513,513,513,513,513,513, 9,514,514,514,514,514,514,
@@ -3999,97 +4058,97 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-/* block 230 */
-932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
-932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
-932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
-932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
-932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
-932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
-932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
-932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
+/* block 234 */
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
-/* block 231 */
-933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
-933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
-933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
-933,933,933,933,933,933,933,932,932,932,932,933,933,933,933,933,
-933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
-933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
-933,933,933,933,933,933,933,933,933,933,933,933,933,932,932,932,
-932,932,932,932,932,933,932,932,932,932,932,932,932,932,932,932,
+/* block 235 */
+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
+949,949,949,949,949,949,949,948,948,948,948,949,949,949,949,949,
+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
+949,949,949,949,949,949,949,949,949,949,949,949,949,948,948,948,
+948,948,948,948,948,949,948,948,948,948,948,948,948,948,948,948,
-/* block 232 */
-932,932,932,932,933,932,932,934,934,934,934,934,120,120,120,120,
-120,120,120,120,120,120,120,120,120,120,120,933,933,933,933,933,
-120,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
+/* block 236 */
+948,948,948,948,949,948,948,950,950,950,950,950,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,949,949,949,949,949,
+120,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 233 */
-935,935,935,935,935,935,935,120,935,935,935,935,935,935,935,935,
-935,935,935,935,935,935,935,935,935,120,120,935,935,935,935,935,
-935,935,120,935,935,120,935,935,935,935,935,120,120,120,120,120,
+/* block 237 */
+951,951,951,951,951,951,951,120,951,951,951,951,951,951,951,951,
+951,951,951,951,951,951,951,951,951,120,120,951,951,951,951,951,
+951,951,120,951,951,120,951,951,951,951,951,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 234 */
-936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,
-936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,
-936,936,936,936,936,936,936,936,936,936,936,936,936,120,120,120,
-937,937,937,937,937,937,937,938,938,938,938,938,938,938,120,120,
-939,939,939,939,939,939,939,939,939,939,120,120,120,120,936,940,
+/* block 238 */
+952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
+952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,
+952,952,952,952,952,952,952,952,952,952,952,952,952,120,120,120,
+953,953,953,953,953,953,953,954,954,954,954,954,954,954,120,120,
+955,955,955,955,955,955,955,955,955,955,120,120,120,120,952,956,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 235 */
+/* block 239 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,
-941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,
-941,941,941,941,941,941,941,941,941,941,941,941,942,942,942,942,
-943,943,943,943,943,943,943,943,943,943,120,120,120,120,120,944,
+957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,
+957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,
+957,957,957,957,957,957,957,957,957,957,957,957,958,958,958,958,
+959,959,959,959,959,959,959,959,959,959,120,120,120,120,120,960,
-/* block 236 */
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+/* block 240 */
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
-/* block 237 */
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
-945,945,945,945,945,120,120,946,946,946,946,946,946,946,946,946,
-947,947,947,947,947,947,947,120,120,120,120,120,120,120,120,120,
+/* block 241 */
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,
+961,961,961,961,961,120,120,962,962,962,962,962,962,962,962,962,
+963,963,963,963,963,963,963,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 238 */
-948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
-948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
-948,948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
-949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
-949,949,949,949,950,950,950,950,950,950,950,951,120,120,120,120,
-952,952,952,952,952,952,952,952,952,952,120,120,120,120,953,953,
+/* block 242 */
+964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,
+964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,
+964,964,965,965,965,965,965,965,965,965,965,965,965,965,965,965,
+965,965,965,965,965,965,965,965,965,965,965,965,965,965,965,965,
+965,965,965,965,966,966,966,966,966,966,966,967,120,120,120,120,
+968,968,968,968,968,968,968,968,968,968,120,120,120,120,969,969,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 239 */
+/* block 243 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -4099,7 +4158,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-/* block 240 */
+/* block 244 */
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, 25, 25,
@@ -4109,7 +4168,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 241 */
+/* block 245 */
120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25,
@@ -4119,87 +4178,87 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 242 */
-225,225,225,225,120,225,225,225,225,225,225,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
-120,225,225,120,225,120,120,225,120,225,225,225,225,225,225,225,
-225,225,225,120,225,225,225,225,120,225,120,225,120,120,120,120,
-120,120,225,120,120,120,120,225,120,225,120,225,120,225,225,225,
-120,225,225,120,225,120,120,225,120,225,120,225,120,225,120,225,
-120,225,225,120,225,120,120,225,225,225,225,120,225,225,225,225,
-225,225,225,120,225,225,225,225,120,225,225,225,225,120,225,120,
+/* block 246 */
+224,224,224,224,120,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+120,224,224,120,224,120,120,224,120,224,224,224,224,224,224,224,
+224,224,224,120,224,224,224,224,120,224,120,224,120,120,120,120,
+120,120,224,120,120,120,120,224,120,224,120,224,120,224,224,224,
+120,224,224,120,224,120,120,224,120,224,120,224,120,224,120,224,
+120,224,224,120,224,120,120,224,224,224,224,120,224,224,224,224,
+224,224,224,120,224,224,224,224,120,224,224,224,224,120,224,120,
-/* block 243 */
-225,225,225,225,225,225,225,225,225,225,120,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,120,120,120,120,
-120,225,225,225,120,225,225,225,225,225,120,225,225,225,225,225,
-225,225,225,225,225,225,225,225,225,225,225,225,120,120,120,120,
+/* block 247 */
+224,224,224,224,224,224,224,224,224,224,120,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,120,120,120,120,
+120,224,224,224,120,224,224,224,224,224,120,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-218,218,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+217,217,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 244 */
+/* block 248 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-/* block 245 */
+/* block 249 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,
-954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,
+970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+970, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,
+ 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,
-/* block 246 */
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,954,954,954,
+/* block 250 */
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 21, 21, 21,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,954,954,954,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21,
21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21,
-/* block 247 */
+/* block 251 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20,
20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,955,955,955,955,955,955,955,955,955,955,
-955,955,955,955,955,955,955,955,955,955,955,955,955,955,955,955,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,971,971,971,971,971,971,971,971,971,971,
+971,971,971,971,971,971,971,971,971,971,971,971,971,971,971,971,
-/* block 248 */
-956, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,954,
+/* block 252 */
+972, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
- 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,954,954,954,954,
- 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,
-584,584,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
- 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+ 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,970,970,970,970,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970,
+584,584,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+ 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
-/* block 249 */
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+/* block 253 */
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
-/* block 250 */
+/* block 254 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4209,7 +4268,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-/* block 251 */
+/* block 255 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4217,9 +4276,9 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,957,957,957,957,957,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,973,973,973,973,973,
-/* block 252 */
+/* block 256 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4229,7 +4288,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-/* block 253 */
+/* block 257 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4239,17 +4298,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-/* block 254 */
+/* block 258 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954,954,
+ 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,
-/* block 255 */
+/* block 259 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -4257,99 +4316,109 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20,954,954,954,954,954,954,954,954,954,954,954,954,
+ 20, 20, 20, 20,970,970,970,970,970,970,970,970,970,970,970,970,
-/* block 256 */
+/* block 260 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 21, 21, 21, 21,954,954,954,954,954,954,954,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+ 20, 20, 20, 20, 20, 21, 21, 21, 21,970,970,970,970,970,970,970,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
-/* block 257 */
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,
+/* block 261 */
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,954,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,
+ 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970,970,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-/* block 258 */
- 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,954,
+/* block 262 */
+ 20, 20, 20, 20, 20, 20, 20, 20,970,970,970,970,970,970,970,970,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,970,970,
+ 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
-/* block 259 */
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954, 21, 21, 21,
+/* block 263 */
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21,954, 21, 21, 21, 21,954,954,954, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21,970, 21, 21, 21, 21, 21, 21,
-/* block 260 */
+/* block 264 */
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21,954,954, 21, 21, 21, 21, 21, 21,954,954,954, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-/* block 261 */
+/* block 265 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,
- 21, 21, 21, 21,954,954,954,954, 21, 21, 21,954,954,954,954,954,
+ 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,
+ 21, 21, 21, 21, 21,970,970,970, 21, 21, 21,970,970,970,970,970,
-/* block 262 */
- 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,954,
- 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+/* block 266 */
+ 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,
+ 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,
+ 21, 21, 21,970,970,970,970,970,970,970,970,970,970,970,970,970,
+ 21, 21, 21, 21, 21, 21, 21,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
-/* block 263 */
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-954,954,954,954,954,954,954,954,954,954,954,954,954,954,120,120,
+/* block 267 */
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,120,120,120,120,120,120,
-/* block 264 */
+/* block 268 */
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,970,
+970,970,970,970,970,970,970,970,970,970,970,970,970,970,120,120,
+
+/* block 269 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-586,586,586,586,586,586,586,120,120,120,120,120,120,120,120,120,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 265 */
+/* block 270 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
@@ -4359,7 +4428,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-/* block 266 */
+/* block 271 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
@@ -4369,7 +4438,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-/* block 267 */
+/* block 272 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -4379,7 +4448,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
-/* block 268 */
+/* block 273 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
@@ -4389,7 +4458,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
586,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 269 */
+/* block 274 */
586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
@@ -4399,17 +4468,27 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 270 */
+/* block 275 */
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 276 */
511, 24,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
-958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
-958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
-958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
-958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
-958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
-958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
-
-/* block 271 */
+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,
+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,
+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,
+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,
+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,
+974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,974,
+
+/* block 277 */
511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
@@ -4419,7 +4498,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
-/* block 272 */
+/* block 278 */
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
@@ -4429,7 +4508,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
-/* block 273 */
+/* block 279 */
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
@@ -4439,15 +4518,15 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
-/* block 274 */
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,120,120,
+/* block 280 */
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
+673,673,673,673,673,673,673,673,673,673,673,673,673,673,120,120,
};
diff --git a/thirdparty/pcre2/src/pcre2_ucp.h b/thirdparty/pcre2/src/pcre2_ucp.h
index 84b22fb064..9538062c71 100644
--- a/thirdparty/pcre2/src/pcre2_ucp.h
+++ b/thirdparty/pcre2/src/pcre2_ucp.h
@@ -286,7 +286,12 @@ enum {
ucp_Elymaic,
ucp_Nandinagari,
ucp_Nyiakeng_Puachue_Hmong,
- ucp_Wancho
+ ucp_Wancho,
+ /* New for Unicode 13.0.0 */
+ ucp_Chorasmian,
+ ucp_Dives_Akuru,
+ ucp_Khitan_Small_Script,
+ ucp_Yezidi
};
#endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */
diff --git a/thirdparty/pcre2/src/pcre2_valid_utf.c b/thirdparty/pcre2/src/pcre2_valid_utf.c
index 96e8bff993..e47ea78f16 100644
--- a/thirdparty/pcre2/src/pcre2_valid_utf.c
+++ b/thirdparty/pcre2/src/pcre2_valid_utf.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2017 University of Cambridge
+ New API code Copyright (c) 2016-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -347,7 +347,7 @@ for (p = string; length > 0; p++)
length--;
if ((*p & 0xfc00) != 0xdc00)
{
- *erroroffset = p - string;
+ *erroroffset = p - string - 1;
return PCRE2_ERROR_UTF16_ERR2;
}
}
diff --git a/thirdparty/pcre2/src/sljit/sljitConfig.h b/thirdparty/pcre2/src/sljit/sljitConfig.h
index d54b5e6f54..1c821d287d 100644
--- a/thirdparty/pcre2/src/sljit/sljitConfig.h
+++ b/thirdparty/pcre2/src/sljit/sljitConfig.h
@@ -24,15 +24,19 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _SLJIT_CONFIG_H_
-#define _SLJIT_CONFIG_H_
+#ifndef SLJIT_CONFIG_H_
+#define SLJIT_CONFIG_H_
-/* --------------------------------------------------------------------- */
-/* Custom defines */
-/* --------------------------------------------------------------------- */
+#ifdef __cplusplus
+extern "C" {
+#endif
-/* Put your custom defines here. This empty section will never change
- which helps maintaining patches (with diff / patch utilities). */
+/*
+ This file contains the basic configuration options for the SLJIT compiler
+ and their default values. These options can be overridden in the
+ sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a
+ non-zero value.
+*/
/* --------------------------------------------------------------------- */
/* Architecture */
@@ -50,7 +54,7 @@
/* #define SLJIT_CONFIG_MIPS_32 1 */
/* #define SLJIT_CONFIG_MIPS_64 1 */
/* #define SLJIT_CONFIG_SPARC_32 1 */
-/* #define SLJIT_CONFIG_TILEGX 1 */
+/* #define SLJIT_CONFIG_S390X 1 */
/* #define SLJIT_CONFIG_AUTO 1 */
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
@@ -59,18 +63,19 @@
/* Utilities */
/* --------------------------------------------------------------------- */
-/* Useful for thread-safe compiling of global functions. */
-#ifndef SLJIT_UTIL_GLOBAL_LOCK
-/* Enabled by default */
-#define SLJIT_UTIL_GLOBAL_LOCK 1
-#endif
-
-/* Implements a stack like data structure (by using mmap / VirtualAlloc). */
+/* Implements a stack like data structure (by using mmap / VirtualAlloc */
+/* or a custom allocator). */
#ifndef SLJIT_UTIL_STACK
/* Enabled by default */
#define SLJIT_UTIL_STACK 1
#endif
+/* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */
+#ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION
+/* Disabled by default */
+#define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0
+#endif
+
/* Single threaded application. Does not require any locks. */
#ifndef SLJIT_SINGLE_THREADED
/* Disabled by default. */
@@ -97,15 +102,31 @@
/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
an allocator which does not set writable and executable
- permission flags at the same time. The trade-of is increased
- memory consumption and disabled dynamic code modifications. */
+ permission flags at the same time.
+ Instead, it creates a shared memory segment (usually backed by a file)
+ and maps it twice, with different permissions, depending on the use
+ case.
+ The trade-off is increased use of virtual memory, incompatibility with
+ fork(), and some possible additional security risks by the use of
+ publicly accessible files for the generated code. */
#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
/* Disabled by default. */
#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
#endif
+/* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an
+ allocator which does not set writable and executable permission
+ flags at the same time.
+ Instead, it creates a new independent map on each invocation and
+ switches permissions at the underlying pages as needed.
+ The trade-off is increased memory use and degraded performance. */
+#ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR
+/* Disabled by default. */
+#define SLJIT_WX_EXECUTABLE_ALLOCATOR 0
#endif
+#endif /* !SLJIT_EXECUTABLE_ALLOCATOR */
+
/* Force cdecl calling convention even if a better calling
convention (e.g. fastcall) is supported by the C compiler.
If this option is disabled (this is the default), functions
@@ -144,4 +165,8 @@
/* For further configurations, see the beginning of sljitConfigInternal.h */
+#ifdef __cplusplus
+} /* extern "C" */
#endif
+
+#endif /* SLJIT_CONFIG_H_ */
diff --git a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h
index acba9da4be..eb1132db30 100644
--- a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h
+++ b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h
@@ -24,8 +24,22 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _SLJIT_CONFIG_INTERNAL_H_
-#define _SLJIT_CONFIG_INTERNAL_H_
+#ifndef SLJIT_CONFIG_INTERNAL_H_
+#define SLJIT_CONFIG_INTERNAL_H_
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)))
+#include <stdio.h>
+#endif
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG \
+ && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS)))
+#include <stdlib.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/*
SLJIT defines the following architecture dependent types and macros:
@@ -67,30 +81,13 @@
Other macros:
SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT
- SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
+ SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)
*/
/*****************/
/* Sanity check. */
/*****************/
-#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
- || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
- || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
- || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
- || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
- || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
- || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
- || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
- || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
- || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
- || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
- || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
- || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
- || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))
-#error "An architecture must be selected"
-#endif
-
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
@@ -99,15 +96,36 @@
+ (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
- + (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
+ (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
#error "Multiple architectures are selected"
#endif
+#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ && !(defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
+ && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \
+ && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
+#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO
+#error "An architecture must be selected"
+#else /* SLJIT_CONFIG_AUTO */
+#define SLJIT_CONFIG_AUTO 1
+#endif /* !SLJIT_CONFIG_AUTO */
+#endif /* !SLJIT_CONFIG */
+
/********************************************************/
/* Automatic CPU detection (requires compiler support). */
/********************************************************/
@@ -140,8 +158,6 @@
#define SLJIT_CONFIG_MIPS_64 1
#elif defined(__sparc__) || defined(__sparc)
#define SLJIT_CONFIG_SPARC_32 1
-#elif defined(__tilegx__)
-#define SLJIT_CONFIG_TILEGX 1
#else
/* Unsupported architecture */
#define SLJIT_CONFIG_UNSUPPORTED 1
@@ -191,6 +207,22 @@
#define SLJIT_CONFIG_SPARC 1
#endif
+/***********************************************************/
+/* Intel Control-flow Enforcement Technology (CET) spport. */
+/***********************************************************/
+
+#ifdef SLJIT_CONFIG_X86
+
+#if defined(__CET__) && !(defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
+#define SLJIT_CONFIG_X86_CET 1
+#endif
+
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined(__GNUC__)
+#include <x86intrin.h>
+#endif
+
+#endif /* SLJIT_CONFIG_X86 */
+
/**********************************/
/* External function definitions. */
/**********************************/
@@ -265,6 +297,7 @@
/* Type of public API functions. */
/*********************************/
+#ifndef SLJIT_API_FUNC_ATTRIBUTE
#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
/* Static ABI functions. For all-in-one programs. */
@@ -278,6 +311,7 @@
#else
#define SLJIT_API_FUNC_ATTRIBUTE
#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */
+#endif /* defined SLJIT_API_FUNC_ATTRIBUTE */
/****************************/
/* Instruction cache flush. */
@@ -287,7 +321,7 @@
#if __has_builtin(__builtin___clear_cache)
#define SLJIT_CACHE_FLUSH(from, to) \
- __builtin___clear_cache((char*)from, (char*)to)
+ __builtin___clear_cache((char*)(from), (char*)(to))
#endif /* __has_builtin(__builtin___clear_cache) */
#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */
@@ -318,7 +352,7 @@
#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
#define SLJIT_CACHE_FLUSH(from, to) \
- __builtin___clear_cache((char*)from, (char*)to)
+ __builtin___clear_cache((char*)(from), (char*)(to))
#elif defined __ANDROID__
@@ -377,7 +411,7 @@ typedef long int sljit_sw;
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
- && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+ && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
#define SLJIT_32BIT_ARCHITECTURE 1
#define SLJIT_WORD_SHIFT 2
typedef unsigned int sljit_uw;
@@ -419,10 +453,14 @@ typedef double sljit_f64;
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
#define SLJIT_W(w) (w##l)
#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#ifdef _WIN64
#define SLJIT_W(w) (w##ll)
-#else
+#else /* !windows */
+#define SLJIT_W(w) (w##l)
+#endif /* windows */
+#else /* 32 bit */
#define SLJIT_W(w) (w)
-#endif
+#endif /* unknown */
#endif /* !SLJIT_W */
@@ -451,7 +489,27 @@ typedef double sljit_f64;
#define SLJIT_BIG_ENDIAN 1
#endif
-#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+#ifndef SLJIT_MIPS_REV
+
+/* Auto detecting mips revision. */
+#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
+#define SLJIT_MIPS_REV 6
+#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \
+ || (defined __clang__ && defined _MIPS_ARCH_OCTEON) \
+ || (defined __clang__ && defined _MIPS_ARCH_P5600)
+/* clang either forgets to define (clang-7) __mips_isa_rev at all
+ * or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+)
+ * and -march=p5600 (MIPS32 R5).
+ * It also sets the __mips macro to 64 or 32 for -mipsN when N <= 5
+ * (should be set to N exactly) so we cannot rely on this too.
+ */
+#define SLJIT_MIPS_REV 1
+#endif
+
+#endif /* !SLJIT_MIPS_REV */
+
+#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
#define SLJIT_BIG_ENDIAN 1
@@ -478,7 +536,8 @@ typedef double sljit_f64;
|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|| (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
- || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
#define SLJIT_UNALIGNED 1
#endif
@@ -496,17 +555,19 @@ typedef double sljit_f64;
#ifndef SLJIT_FUNC
-#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
+#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) \
+ || !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-/* Force cdecl. */
#define SLJIT_FUNC
-#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-
-#if defined(__GNUC__) && !defined(__APPLE__)
+#elif defined(__GNUC__) && !defined(__APPLE__)
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define SLJIT_FUNC __attribute__ ((fastcall))
#define SLJIT_X86_32_FASTCALL 1
+#else
+#define SLJIT_FUNC
+#endif /* gcc >= 3.4 */
#elif defined(_MSC_VER)
@@ -520,16 +581,10 @@ typedef double sljit_f64;
#else /* Unknown compiler. */
-/* The cdecl attribute is the default. */
-#define SLJIT_FUNC
-
-#endif
-
-#else /* Non x86-32 architectures. */
-
+/* The cdecl calling convention is usually the x86 default. */
#define SLJIT_FUNC
-#endif /* SLJIT_CONFIG_X86_32 */
+#endif /* SLJIT_USE_CDECL_CALLING_CONVENTION */
#endif /* !SLJIT_FUNC */
@@ -560,8 +615,16 @@ determine the next executed instruction after return. */
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
-#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
-#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
+#define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size)
+#define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr)
+
+#ifndef SLJIT_MALLOC_EXEC
+#define SLJIT_MALLOC_EXEC(size, exec_allocator_data) SLJIT_BUILTIN_MALLOC_EXEC((size), (exec_allocator_data))
+#endif /* SLJIT_MALLOC_EXEC */
+
+#ifndef SLJIT_FREE_EXEC
+#define SLJIT_FREE_EXEC(ptr, exec_allocator_data) SLJIT_BUILTIN_FREE_EXEC((ptr), (exec_allocator_data))
+#endif /* SLJIT_FREE_EXEC */
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
@@ -570,7 +633,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_EXEC_OFFSET(ptr) 0
#endif
-#endif
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
/**********************************************/
/* Registers and locals offset determination. */
@@ -646,11 +709,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_LOCALS_OFFSET_BASE ((16 + 1 + 6 + 2 + 1) * sizeof(sljit_sw))
#endif
-#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-#define SLJIT_NUMBER_OF_REGISTERS 10
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5
-#define SLJIT_LOCALS_OFFSET_BASE 0
+/*
+ * https://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html#STACKFRAME
+ *
+ * 160
+ * .. FR6
+ * .. FR4
+ * .. FR2
+ * 128 FR0
+ * 120 R15 (used for SP)
+ * 112 R14
+ * 104 R13
+ * 96 R12
+ * ..
+ * 48 R6
+ * ..
+ * 16 R2
+ * 8 RESERVED
+ * 0 SP
+ */
+#define SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE 160
+
+#define SLJIT_NUMBER_OF_REGISTERS 12
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
+#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
@@ -679,24 +763,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
/* Debug and verbose related macros. */
/*************************************/
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
-#include <stdio.h>
-#endif
-
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
#if !defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)
/* SLJIT_HALT_PROCESS must halt the process. */
#ifndef SLJIT_HALT_PROCESS
-#include <stdlib.h>
-
#define SLJIT_HALT_PROCESS() \
abort();
#endif /* !SLJIT_HALT_PROCESS */
-#include <stdio.h>
-
#endif /* !SLJIT_ASSERT || !SLJIT_UNREACHABLE */
/* Feel free to redefine these two macros. */
@@ -742,4 +818,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#endif /* !SLJIT_COMPILE_ASSERT */
+#ifdef __cplusplus
+} /* extern "C" */
#endif
+
+#endif /* SLJIT_CONFIG_INTERNAL_H_ */
diff --git a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c
index 92ddb94914..61a32f23e9 100644
--- a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c
+++ b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c
@@ -72,9 +72,8 @@
alloc_chunk / free_chunk :
* allocate executable system memory chunks
* the size is always divisible by CHUNK_SIZE
- allocator_grab_lock / allocator_release_lock :
- * make the allocator thread safe
- * can be empty if the OS (or the application) does not support threading
+ SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
+ * provided as part of sljitUtils
* only the allocator requires this lock, sljit is fully thread safe
as it only uses local variables
*/
@@ -95,6 +94,7 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
#else
#ifdef __APPLE__
+#ifdef MAP_ANON
/* Configures TARGET_OS_OSX when appropriate */
#include <TargetConditionals.h>
@@ -104,17 +104,23 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
#ifdef MAP_JIT
+/*
+ On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
+ version where it's OK to have more than one JIT block.
+ On non-macOS systems, returns MAP_JIT if it is defined.
+*/
static SLJIT_INLINE int get_map_jit_flag()
{
#if TARGET_OS_OSX
- /* On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a version
- of macOS where it's OK to have more than one JIT block. On non-macOS systems, returns
- MAP_JIT if it is defined. */
+ sljit_sw page_size = get_page_alignment() + 1;
+ void *ptr;
static int map_jit_flag = -1;
- /* The following code is thread safe because multiple initialization
- sets map_jit_flag to the same value and the code has no side-effects.
- Changing the kernel version witout system restart is (very) unlikely. */
+ /*
+ The following code is thread safe because multiple initialization
+ sets map_jit_flag to the same value and the code has no side-effects.
+ Changing the kernel version witout system restart is (very) unlikely.
+ */
if (map_jit_flag == -1) {
struct utsname name;
@@ -123,13 +129,14 @@ static SLJIT_INLINE int get_map_jit_flag()
/* Kernel version for 10.14.0 (Mojave) */
if (atoi(name.release) >= 18) {
- /* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible with fork(). */
- void *ptr = mmap(NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ /* Only use MAP_JIT if a hardened runtime is used */
+
+ ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
if (ptr == MAP_FAILED) {
map_jit_flag = MAP_JIT;
} else {
- munmap(ptr, getpagesize());
+ munmap(ptr, page_size);
}
}
}
@@ -141,7 +148,7 @@ static SLJIT_INLINE int get_map_jit_flag()
}
#endif /* MAP_JIT */
-
+#endif /* MAP_ANON */
#endif /* __APPLE__ */
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
@@ -159,10 +166,9 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
retval = mmap(NULL, size, prot, flags, -1, 0);
#else /* !MAP_ANON */
- if (dev_zero < 0) {
- if (open_dev_zero())
- return NULL;
- }
+ if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))
+ return NULL;
+
retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0);
#endif /* MAP_ANON */
@@ -246,7 +252,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
struct free_block *free_block;
sljit_uw chunk_size;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
if (size < (64 - sizeof(struct block_header)))
size = (64 - sizeof(struct block_header));
size = ALIGN_SIZE(size);
@@ -270,7 +276,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
}
allocated_size += size;
header->size = size;
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
free_block = free_block->next;
@@ -279,7 +285,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;
header = (struct block_header*)alloc_chunk(chunk_size);
if (!header) {
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return NULL;
}
@@ -306,7 +312,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
}
next_header->size = 1;
next_header->prev_size = chunk_size;
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
@@ -315,7 +321,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
struct block_header *header;
struct free_block* free_block;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
allocated_size -= header->size;
@@ -352,7 +358,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
}
}
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
@@ -360,7 +366,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
struct free_block* free_block;
struct free_block* next_free_block;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
free_block = free_blocks;
while (free_block) {
@@ -375,5 +381,5 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
}
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
}
diff --git a/thirdparty/pcre2/src/sljit/sljitLir.c b/thirdparty/pcre2/src/sljit/sljitLir.c
index 9bab0c3ec6..d817c90b3a 100644
--- a/thirdparty/pcre2/src/sljit/sljitLir.c
+++ b/thirdparty/pcre2/src/sljit/sljitLir.c
@@ -28,7 +28,6 @@
#ifdef _WIN32
-/* For SLJIT_CACHE_FLUSH, which can expand to FlushInstructionCache. */
#include <windows.h>
#endif /* _WIN32 */
@@ -223,14 +222,6 @@
# define FCSR_FCC 33
#endif
-#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
-# define IS_JAL 0x04
-# define IS_COND 0x08
-
-# define PATCH_B 0x10
-# define PATCH_J 0x20
-#endif
-
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
# define IS_MOVABLE 0x04
# define IS_COND 0x08
@@ -274,6 +265,8 @@
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
#include "sljitProtExecAllocator.c"
+#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
+#include "sljitWXExecAllocator.c"
#else
#include "sljitExecAllocator.c"
#endif
@@ -286,6 +279,10 @@
#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
#endif
+#ifndef SLJIT_UPDATE_WX_FLAGS
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
+#endif
+
/* Argument checking features. */
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
@@ -366,7 +363,7 @@ static sljit_s32 compiler_initialized = 0;
static void init_compiler(void);
#endif
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
{
struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
if (!compiler)
@@ -393,6 +390,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
compiler->error = SLJIT_SUCCESS;
compiler->allocator_data = allocator_data;
+ compiler->exec_allocator_data = exec_allocator_data;
compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
@@ -485,22 +483,28 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
}
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
+ SLJIT_UNUSED_ARG(exec_allocator_data);
+
/* Remove thumb mode flag. */
- SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
+ SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1), exec_allocator_data);
}
#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
+ SLJIT_UNUSED_ARG(exec_allocator_data);
+
/* Resolve indirection. */
code = (void*)(*(sljit_uw*)code);
- SLJIT_FREE_EXEC(code);
+ SLJIT_FREE_EXEC(code, exec_allocator_data);
}
#else
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
- SLJIT_FREE_EXEC(code);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
+
+ SLJIT_FREE_EXEC(code, exec_allocator_data);
}
#endif
@@ -627,7 +631,10 @@ static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)
return arg_count;
}
-#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+/* Only used in RISC architectures where the instruction size is constant */
+#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
+ && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump,
struct sljit_const *const_, struct sljit_put_label *put_label)
@@ -649,7 +656,7 @@ static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct
return result;
}
-#endif /* !SLJIT_CONFIG_X86 */
+#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X */
static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
@@ -926,7 +933,8 @@ static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, s
static const char* op0_names[] = {
(char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw",
- (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s"
+ (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s",
+ (char*)"endbr", (char*)"skip_frames_before_return"
};
static const char* op1_names[] = {
@@ -943,6 +951,12 @@ static const char* op2_names[] = {
(char*)"shl", (char*)"lshr", (char*)"ashr",
};
+static const char* op_src_names[] = {
+ (char*)"fast_return", (char*)"skip_frames_before_fast_return",
+ (char*)"prefetch_l1", (char*)"prefetch_l2",
+ (char*)"prefetch_l3", (char*)"prefetch_once",
+};
+
static const char* fop1_names[] = {
(char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv",
(char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg",
@@ -1152,37 +1166,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_c
CHECK_RETURN_OK;
}
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_SRC(src, srcw);
- CHECK_ARGUMENT(src != SLJIT_IMM);
- compiler->last_flags = 0;
-#endif
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " fast_return ");
- sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
- }
-#endif
- CHECK_RETURN_OK;
-}
-
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
- || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW));
- CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2);
- if (op >= SLJIT_LMUL_UW)
+ || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW)
+ || (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));
+ CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2);
+ if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)
compiler->last_flags = 0;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose))
{
fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
- if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW) {
+ if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {
fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w");
}
fprintf(compiler->verbose, "\n");
@@ -1224,7 +1222,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler
break;
}
- FUNCTION_CHECK_DST(dst, dstw, 1);
+ FUNCTION_CHECK_DST(dst, dstw, HAS_FLAGS(op));
FUNCTION_CHECK_SRC(src, srcw);
if (GET_OPCODE(op) >= SLJIT_NOT) {
@@ -1304,7 +1302,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler
break;
}
- FUNCTION_CHECK_DST(dst, dstw, 1);
+ FUNCTION_CHECK_DST(dst, dstw, HAS_FLAGS(op));
FUNCTION_CHECK_SRC(src1, src1w);
FUNCTION_CHECK_SRC(src2, src2w);
compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
@@ -1325,6 +1323,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler
CHECK_RETURN_OK;
}
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE);
+ FUNCTION_CHECK_SRC(src, srcw);
+
+ if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN)
+ {
+ CHECK_ARGUMENT(src != SLJIT_IMM);
+ compiler->last_flags = 0;
+ }
+ else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE)
+ {
+ CHECK_ARGUMENT(src & SLJIT_MEM);
+ }
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s ", op_src_names[op - SLJIT_OP_SRC_BASE]);
+ sljit_verbose_param(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg)
{
SLJIT_UNUSED_ARG(reg);
@@ -1360,6 +1385,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
+#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+ CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
#else
CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
#endif
@@ -2016,7 +2043,7 @@ static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *comp
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
- || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1))
+ || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6))
static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 dst_reg,
@@ -2093,8 +2120,8 @@ static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *com
# include "sljitNativeMIPS_common.c"
#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
# include "sljitNativeSPARC_common.c"
-#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
-# include "sljitNativeTILEGX_64.c"
+#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+# include "sljitNativeS390X.c"
#endif
#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
@@ -2125,7 +2152,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
#endif
if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
- /* Immediate is prefered as second argument by most architectures. */
+ /* Immediate is preferred as second argument by most architectures. */
switch (condition) {
case SLJIT_LESS:
condition = SLJIT_GREATER;
@@ -2274,9 +2301,10 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
return "unsupported";
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
{
SLJIT_UNUSED_ARG(allocator_data);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
SLJIT_UNREACHABLE();
return NULL;
}
@@ -2324,9 +2352,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
return 0;
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
SLJIT_UNUSED_ARG(code);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
SLJIT_UNREACHABLE();
}
@@ -2381,15 +2410,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
return SLJIT_ERR_UNSUPPORTED;
}
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(src);
- SLJIT_UNUSED_ARG(srcw);
- SLJIT_UNREACHABLE();
- return SLJIT_ERR_UNSUPPORTED;
-}
-
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
{
SLJIT_UNUSED_ARG(compiler);
@@ -2429,6 +2449,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
return SLJIT_ERR_UNSUPPORTED;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_UNREACHABLE();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
{
SLJIT_UNREACHABLE();
@@ -2549,6 +2580,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw
SLJIT_UNREACHABLE();
}
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
+{
+ SLJIT_UNUSED_ARG(put_label);
+ SLJIT_UNUSED_ARG(label);
+ SLJIT_UNREACHABLE();
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
{
SLJIT_UNUSED_ARG(compiler);
diff --git a/thirdparty/pcre2/src/sljit/sljitLir.h b/thirdparty/pcre2/src/sljit/sljitLir.h
index 836d25cf71..93d2804675 100644
--- a/thirdparty/pcre2/src/sljit/sljitLir.h
+++ b/thirdparty/pcre2/src/sljit/sljitLir.h
@@ -24,8 +24,8 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _SLJIT_LIR_H_
-#define _SLJIT_LIR_H_
+#ifndef SLJIT_LIR_H_
+#define SLJIT_LIR_H_
/*
------------------------------------------------------------------------
@@ -70,9 +70,11 @@
- pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
*/
-#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)
+#if (defined SLJIT_HAVE_CONFIG_PRE && SLJIT_HAVE_CONFIG_PRE)
+#include "sljitConfigPre.h"
+#endif /* SLJIT_HAVE_CONFIG_PRE */
+
#include "sljitConfig.h"
-#endif
/* The following header file defines useful macros for fine tuning
sljit based code generators. They are listed in the beginning
@@ -80,6 +82,14 @@ of sljitConfigInternal.h */
#include "sljitConfigInternal.h"
+#if (defined SLJIT_HAVE_CONFIG_POST && SLJIT_HAVE_CONFIG_POST)
+#include "sljitConfigPost.h"
+#endif /* SLJIT_HAVE_CONFIG_POST */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* --------------------------------------------------------------------- */
/* Error codes */
/* --------------------------------------------------------------------- */
@@ -154,10 +164,10 @@ of sljitConfigInternal.h */
*/
/* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1
- or sljit_emit_op2 operations the result is discarded. If no status
- flags are set, no instructions are emitted for these operations. Data
- prefetch is a special exception, see SLJIT_MOV operation. Other SLJIT
- operations do not support SLJIT_UNUSED as a destination operand. */
+ or sljit_emit_op2 operations the result is discarded. Some status
+ flags must be set when the destination is SLJIT_UNUSED, because the
+ operation would have no effect otherwise. Other SLJIT operations do
+ not support SLJIT_UNUSED as a destination operand. */
#define SLJIT_UNUSED 0
/* Scratch registers. */
@@ -381,6 +391,7 @@ struct sljit_compiler {
struct sljit_put_label *last_put_label;
void *allocator_data;
+ void *exec_allocator_data;
struct sljit_memory_fragment *buf;
struct sljit_memory_fragment *abuf;
@@ -447,9 +458,9 @@ struct sljit_compiler {
sljit_sw cache_argw;
#endif
-#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
- sljit_s32 cache_arg;
- sljit_sw cache_argw;
+#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+ /* Need to allocate register save area to make calls. */
+ sljit_s32 have_save_area;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
@@ -481,10 +492,12 @@ struct sljit_compiler {
custom memory managers. This pointer is passed to SLJIT_MALLOC
and SLJIT_FREE macros. Most allocators (including the default
one) ignores this value, and it is recommended to pass NULL
- as a dummy value for allocator_data.
+ as a dummy value for allocator_data. The exec_allocator_data
+ has the same purpose but this one is passed to SLJIT_MALLOC_EXEC /
+ SLJIT_MALLOC_FREE functions.
Returns NULL if failed. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data);
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data);
/* Frees everything except the compiled machine code. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
@@ -531,7 +544,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* Free executable code. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data);
/*
When the protected executable allocator is used the JIT code is mapped
@@ -567,10 +580,14 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler
#define SLJIT_HAS_FPU 0
/* [Limitation] Some registers are virtual registers. */
#define SLJIT_HAS_VIRTUAL_REGISTERS 1
+/* [Emulated] Has zero register (setting a memory location to zero is efficient). */
+#define SLJIT_HAS_ZERO_REGISTER 2
/* [Emulated] Count leading zero is supported. */
-#define SLJIT_HAS_CLZ 2
+#define SLJIT_HAS_CLZ 3
/* [Emulated] Conditional move is supported. */
-#define SLJIT_HAS_CMOV 3
+#define SLJIT_HAS_CMOV 4
+/* [Emulated] Conditional move is supported. */
+#define SLJIT_HAS_PREFETCH 5
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
/* [Not emulated] SSE2 support is available on x86. */
@@ -658,10 +675,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
sljit_s32 src, sljit_sw srcw);
/* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL).
- Both sljit_emit_fast_enter and sljit_emit_fast_return functions preserve the
+ Both sljit_emit_fast_enter and SLJIT_FAST_RETURN operations preserve the
values of all registers and stack frame. The return address is stored in the
dst argument of sljit_emit_fast_enter, and this return address can be passed
- to sljit_emit_fast_return to continue the execution after the fast call.
+ to SLJIT_FAST_RETURN to continue the execution after the fast call.
Fast calls are cheap operations (usually only a single call instruction is
emitted) but they do not preserve any registers. However the callee function
@@ -669,16 +686,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
efficiently exploited by various optimizations. Registers can be saved
manually by the callee function if needed.
- Although returning to different address by sljit_emit_fast_return is possible,
+ Although returning to different address by SLJIT_FAST_RETURN is possible,
this address usually cannot be predicted by the return address predictor of
- modern CPUs which may reduce performance. Furthermore using sljit_emit_ijump
- to return is also inefficient since return address prediction is usually
- triggered by a specific form of ijump.
+ modern CPUs which may reduce performance. Furthermore certain security
+ enhancement technologies such as Intel Control-flow Enforcement Technology
+ (CET) may disallow returning to a different address.
Flags: - (does not modify flags). */
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw);
/*
Source and destination operands for arithmetical instructions
@@ -692,7 +708,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
*/
/*
- IMPORATNT NOTE: memory access MUST be naturally aligned except
+ IMPORTANT NOTE: memory access MUST be naturally aligned unless
SLJIT_UNALIGNED macro is defined and its value is 1.
length | alignment
@@ -734,6 +750,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
mips: [reg+imm], -65536 <= imm <= 65535
sparc: [reg+imm], -4096 <= imm <= 4095
[reg+reg] is supported
+ s390x: [reg+imm], -2^19 <= imm < 2^19
+ [reg+reg] is supported
+ Write-back is not supported
*/
/* Macros for specifying operand types. */
@@ -887,6 +906,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
the behaviour is undefined. */
#define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7)
#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_I32_OP)
+/* Flags: - (does not modify flags)
+ ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64
+ when Intel Control-flow Enforcement Technology (CET) is enabled.
+ No instruction for other architectures. */
+#define SLJIT_ENDBR (SLJIT_OP0_BASE + 8)
+/* Flags: - (may destroy flags)
+ Skip stack frames before return. */
+#define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 9)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op);
@@ -904,15 +931,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
U32 - unsigned int (32 bit) data transfer
S32 - signed int (32 bit) data transfer
P - pointer (sljit_p) data transfer
-
- If the destination of a MOV instruction is SLJIT_UNUSED and the source
- operand is a memory address the compiler emits a prefetch instruction
- if this instruction is supported by the current CPU. Higher data sizes
- bring the data closer to the core: a MOV with word size loads the data
- into a higher level cache than a byte size. Otherwise the type does not
- affect the prefetch instruction. Furthermore a prefetch instruction
- never fails, so it can be used to prefetch a data from an address and
- check whether that address is NULL afterwards.
*/
/* Flags: - (does not modify flags) */
@@ -1017,8 +1035,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2, sljit_sw src2w);
+/* Starting index of opcodes for sljit_emit_op2. */
+#define SLJIT_OP_SRC_BASE 128
+
+/* Note: src cannot be an immedate value
+ Flags: - (does not modify flags) */
+#define SLJIT_FAST_RETURN (SLJIT_OP_SRC_BASE + 0)
+/* Skip stack frames before fast return.
+ Note: src cannot be an immedate value
+ Flags: may destroy flags. */
+#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_BASE + 1)
+/* Prefetch value into the level 1 data cache
+ Note: if the target CPU does not support data prefetch,
+ no instructions are emitted.
+ Note: this instruction never fails, even if the memory address is invalid.
+ Flags: - (does not modify flags) */
+#define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_BASE + 2)
+/* Prefetch value into the level 2 data cache
+ Note: same as SLJIT_PREFETCH_L1 if the target CPU
+ does not support this instruction form.
+ Note: this instruction never fails, even if the memory address is invalid.
+ Flags: - (does not modify flags) */
+#define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_BASE + 3)
+/* Prefetch value into the level 3 data cache
+ Note: same as SLJIT_PREFETCH_L2 if the target CPU
+ does not support this instruction form.
+ Note: this instruction never fails, even if the memory address is invalid.
+ Flags: - (does not modify flags) */
+#define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_BASE + 4)
+/* Prefetch a value which is only used once (and can be discarded afterwards)
+ Note: same as SLJIT_PREFETCH_L1 if the target CPU
+ does not support this instruction form.
+ Note: this instruction never fails, even if the memory address is invalid.
+ Flags: - (does not modify flags) */
+#define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_BASE + 5)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw);
+
/* Starting index of opcodes for sljit_emit_fop1. */
-#define SLJIT_FOP1_BASE 128
+#define SLJIT_FOP1_BASE 160
/* Flags: - (does not modify flags) */
#define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0)
@@ -1057,7 +1113,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
sljit_s32 src, sljit_sw srcw);
/* Starting index of opcodes for sljit_emit_fop2. */
-#define SLJIT_FOP2_BASE 160
+#define SLJIT_FOP2_BASE 192
/* Flags: - (does not modify flags) */
#define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0)
@@ -1161,7 +1217,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
/* Unconditional jump types. */
#define SLJIT_JUMP 24
- /* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
+ /* Fast calling method. See sljit_emit_fast_enter / SLJIT_FAST_RETURN. */
#define SLJIT_FAST_CALL 25
/* Called function must be declared with the SLJIT_FUNC attribute. */
#define SLJIT_CALL 26
@@ -1361,12 +1417,6 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);
/* Portable helper function to get an offset of a member. */
#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
-#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
-/* This global lock is useful to compile common functions. */
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void);
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void);
-#endif
-
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
/* The sljit_stack structure and its manipulation functions provides
@@ -1490,4 +1540,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler,
sljit_s32 current_flags);
-#endif /* _SLJIT_LIR_H_ */
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* SLJIT_LIR_H_ */
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
index 71f7bcdadb..ae8479f031 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
@@ -467,18 +467,28 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut
sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2);
+ SLJIT_UNUSED_ARG(executable_offset);
+
if (diff <= 0x7fffff && diff >= -0x800000) {
/* Turn to branch. */
if (!bl) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ }
inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
} else {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ }
inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
inst[1] = NOP;
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
@@ -491,28 +501,52 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut
ptr = inst + 1;
if (*inst != mov_pc) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + (!bl ? 1 : 2), 0);
+ }
inst[0] = mov_pc;
if (!bl) {
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
} else {
inst[1] = BLX | RM(TMP_REG1);
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
}
}
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
+ }
+
*ptr = new_addr;
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
+ }
}
#else
sljit_uw *inst = (sljit_uw*)jump_ptr;
+
+ SLJIT_UNUSED_ARG(executable_offset);
+
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ }
+
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
@@ -529,10 +563,18 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
sljit_uw ldr_literal = ptr[1];
sljit_uw src2;
+ SLJIT_UNUSED_ARG(executable_offset);
+
src2 = get_imm(new_constant);
if (src2) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ }
+
*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
@@ -541,8 +583,14 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
src2 = get_imm(~new_constant);
if (src2) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ }
+
*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
@@ -555,19 +603,44 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
ptr = inst + 1;
if (*inst != ldr_literal) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ }
+
*inst = ldr_literal;
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
}
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
+ }
+
*ptr = new_constant;
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
+ }
#else
sljit_uw *inst = (sljit_uw*)addr;
+
+ SLJIT_UNUSED_ARG(executable_offset);
+
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ }
+
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
@@ -612,7 +685,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
#else
size = compiler->size;
#endif
- code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw));
+ code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -653,7 +726,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
}
else {
if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
- SLJIT_FREE_EXEC(code);
+ SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
compiler->error = SLJIT_ERR_ALLOC_FAILED;
return NULL;
}
@@ -666,6 +739,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = code_ptr - code;
label = label->next;
+
+ next_addr = compute_next_addr(label, jump, const_, put_label);
}
}
}
@@ -754,7 +829,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
cpool_current_index = 0;
while (buf_ptr < buf_end) {
if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
- SLJIT_FREE_EXEC(code);
+ SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
compiler->error = SLJIT_ERR_ALLOC_FAILED;
return NULL;
}
@@ -854,6 +929,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
return code;
}
@@ -870,6 +946,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
case SLJIT_HAS_CLZ:
case SLJIT_HAS_CMOV:
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ case SLJIT_HAS_PREFETCH:
+#endif
return 1;
default:
@@ -1676,6 +1755,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
}
return SLJIT_SUCCESS;
+ case SLJIT_ENDBR:
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return SLJIT_SUCCESS;
}
return SLJIT_SUCCESS;
@@ -1690,14 +1772,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
ADJUST_LOCAL_OFFSET(dst, dstw);
ADJUST_LOCAL_OFFSET(src, srcw);
- if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
-#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
- if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
- return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1);
-#endif
- return SLJIT_SUCCESS;
- }
-
switch (GET_OPCODE(op)) {
case SLJIT_MOV:
case SLJIT_MOV_U32:
@@ -1779,6 +1853,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
return SLJIT_SUCCESS;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));
+ else
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1));
+
+ return push_inst(compiler, BX | RM(TMP_REG2));
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ return SLJIT_SUCCESS;
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ SLJIT_ASSERT(src & SLJIT_MEM);
+ return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1);
+#else /* !SLJIT_CONFIG_ARM_V7 */
+ return SLJIT_SUCCESS;
+#endif /* SLJIT_CONFIG_ARM_V7 */
+ }
+
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
{
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
@@ -2041,22 +2149,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1);
}
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1));
-
- return push_inst(compiler, BX | RM(TMP_REG2));
-}
-
/* --------------------------------------------------------------------- */
/* Conditional instructions */
/* --------------------------------------------------------------------- */
@@ -2615,11 +2707,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
}
else {
if (is_type1_transfer) {
- if (memw > 4095 && memw < -4095)
+ if (memw > 4095 || memw < -4095)
return SLJIT_ERR_UNSUPPORTED;
}
else {
- if (memw > 255 && memw < -255)
+ if (memw > 255 || memw < -255)
return SLJIT_ERR_UNSUPPORTED;
}
}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
index e15b3451e8..52267e7df7 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
@@ -151,16 +151,6 @@ static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler,
return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21));
}
-static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
-{
- sljit_s32 dst = inst[0] & 0x1f;
- SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
- inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5);
- inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21);
- inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21);
- inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
-}
-
static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
{
sljit_sw diff;
@@ -253,7 +243,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
CHECK_PTR(check_sljit_generate_code(compiler));
reverse_buf(compiler);
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -380,6 +370,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
return code;
}
@@ -396,6 +387,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
case SLJIT_HAS_CLZ:
case SLJIT_HAS_CMOV:
+ case SLJIT_HAS_PREFETCH:
return 1;
default:
@@ -1154,6 +1146,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
case SLJIT_DIV_UW:
case SLJIT_DIV_SW:
return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
+ case SLJIT_ENDBR:
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return SLJIT_SUCCESS;
}
return SLJIT_SUCCESS;
@@ -1171,23 +1166,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
ADJUST_LOCAL_OFFSET(dst, dstw);
ADJUST_LOCAL_OFFSET(src, srcw);
- if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
- if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) {
- SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4);
-
- if (op >= SLJIT_MOV_U8 && op <= SLJIT_MOV_S8)
- dst = 5;
- else if (op >= SLJIT_MOV_U16 && op <= SLJIT_MOV_S16)
- dst = 3;
- else
- dst = 1;
-
- /* Signed word sized load is the prefetch instruction. */
- return emit_op_mem(compiler, WORD_SIZE | SIGNED, dst, src, srcw, TMP_REG1);
- }
- return SLJIT_SUCCESS;
- }
-
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
op = GET_OPCODE(op);
@@ -1327,6 +1305,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
return SLJIT_SUCCESS;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
+ else
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));
+
+ return push_inst(compiler, RET | RN(TMP_LR));
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ return SLJIT_SUCCESS;
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+ SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4);
+
+ /* The reg_map[op] should provide the appropriate constant. */
+ if (op == SLJIT_PREFETCH_L1)
+ op = 1;
+ else if (op == SLJIT_PREFETCH_L2)
+ op = 3;
+ else if (op == SLJIT_PREFETCH_L3)
+ op = 5;
+ else
+ op = 2;
+
+ /* Signed word sized load is the prefetch instruction. */
+ return emit_op_mem(compiler, WORD_SIZE | SIGNED, op, src, srcw, TMP_REG1);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
{
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
@@ -1578,20 +1596,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw, TMP_REG1);
}
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));
-
- return push_inst(compiler, RET | RN(TMP_LR));
-}
-
/* --------------------------------------------------------------------- */
/* Conditional instructions */
/* --------------------------------------------------------------------- */
@@ -1865,7 +1869,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
CHECK_ERROR();
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
- if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256))
+ if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP)
@@ -1915,7 +1919,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
CHECK_ERROR();
CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
- if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256))
+ if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP)
@@ -2021,15 +2025,24 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins* inst = (sljit_ins*)addr;
- modify_imm64_const(inst, new_target);
+ sljit_s32 dst;
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
+
+ dst = inst[0] & 0x1f;
+ SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
+ inst[0] = MOVZ | dst | ((new_target & 0xffff) << 5);
+ inst[1] = MOVK | dst | (((new_target >> 16) & 0xffff) << 5) | (1 << 21);
+ inst[2] = MOVK | dst | (((new_target >> 32) & 0xffff) << 5) | (2 << 21);
+ inst[3] = MOVK | dst | ((new_target >> 48) << 5) | (3 << 21);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 4);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins* inst = (sljit_ins*)addr;
- modify_imm64_const(inst, new_constant);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 4);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c
index cdfe4a4d24..4624882f42 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c
@@ -377,7 +377,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
CHECK_PTR(check_sljit_generate_code(compiler));
reverse_buf(compiler);
- code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16));
+ code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -463,6 +463,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
+
/* Set thumb mode flag. */
return (void*)((sljit_uw)code | 0x1);
}
@@ -480,6 +482,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
case SLJIT_HAS_CLZ:
case SLJIT_HAS_CMOV:
+ case SLJIT_HAS_PREFETCH:
return 1;
default:
@@ -607,7 +610,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
Although some clever things could be done here, "NOT IMM" does not worth the efforts. */
break;
case SLJIT_ADD:
- nimm = -imm;
+ nimm = -(sljit_sw)imm;
if (IS_2_LO_REGS(reg, dst)) {
if (imm <= 0x7)
return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
@@ -629,7 +632,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
nimm = get_imm(imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
- nimm = get_imm(-imm);
+ nimm = get_imm(-(sljit_sw)imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
break;
@@ -654,11 +657,11 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
nimm = get_imm(imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, CMPI_W | RN4(reg) | nimm);
- nimm = get_imm(-imm);
+ nimm = get_imm(-(sljit_sw)imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, CMNI_W | RN4(reg) | nimm);
}
- nimm = -imm;
+ nimm = -(sljit_sw)imm;
if (IS_2_LO_REGS(reg, dst)) {
if (imm <= 0x7)
return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
@@ -680,7 +683,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
nimm = get_imm(imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
- nimm = get_imm(-imm);
+ nimm = get_imm(-(sljit_sw)imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
break;
@@ -1328,6 +1331,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
}
return SLJIT_SUCCESS;
#endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */
+ case SLJIT_ENDBR:
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return SLJIT_SUCCESS;
}
return SLJIT_SUCCESS;
@@ -1345,13 +1351,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
ADJUST_LOCAL_OFFSET(dst, dstw);
ADJUST_LOCAL_OFFSET(src, srcw);
- if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
- /* Since TMP_PC has index 15, IS_2_LO_REGS and IS_3_LO_REGS checks always fail. */
- if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
- return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1);
- return SLJIT_SUCCESS;
- }
-
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
op = GET_OPCODE(op);
@@ -1475,6 +1474,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG2);
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
+
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
+ else
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
+
+ return push_inst16(compiler, BX | RN3(TMP_REG2));
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ return SLJIT_SUCCESS;
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+ return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
{
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
@@ -1728,22 +1756,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1);
}
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
-
- return push_inst16(compiler, BX | RN3(TMP_REG2));
-}
-
/* --------------------------------------------------------------------- */
/* Conditional instructions */
/* --------------------------------------------------------------------- */
@@ -2264,7 +2276,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
CHECK_ERROR();
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
- if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -255))
+ if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -255))
return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP)
@@ -2356,15 +2368,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_u16 *inst = (sljit_u16*)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
modify_imm32_const(inst, new_target);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 4);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_u16 *inst = (sljit_u16*)addr;
- modify_imm32_const(inst, new_constant);
- inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 4);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
index 16dec052fe..f887ee1311 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
@@ -86,12 +86,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
if (op == SLJIT_MOV_S8) {
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
-#else
+#else /* SLJIT_MIPS_REV < 1 */
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 */
}
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
}
@@ -105,12 +105,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
if (op == SLJIT_MOV_S16) {
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
-#else
+#else /* SLJIT_MIPS_REV < 1 */
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 */
}
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
}
@@ -129,12 +129,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
case SLJIT_CLZ:
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
if (op & SLJIT_SET_Z)
FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
if (!(flags & UNUSED_DEST))
FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
-#else
+#else /* SLJIT_MIPS_REV < 1 */
if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
@@ -149,7 +149,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst)));
FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 */
return SLJIT_SUCCESS;
case SLJIT_ADD:
@@ -368,21 +368,22 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
SLJIT_ASSERT(!(flags & SRC2_IMM));
if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
-#else /* !SLJIT_MIPS_R1 && !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 1 */
FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
return push_inst(compiler, MFLO | D(dst), DR(dst));
-#endif /* SLJIT_MIPS_R1 || SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 1 */
}
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
FAIL_IF(push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)));
FAIL_IF(push_inst(compiler, MUH | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
return push_inst(compiler, SUBU | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
@@ -424,23 +425,20 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins *)addr;
-
- SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
- inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c
index a6a2bcc0c9..5ab9b7d06b 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c
@@ -220,12 +220,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
case SLJIT_CLZ:
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
if (op & SLJIT_SET_Z)
FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
if (!(flags & UNUSED_DEST))
FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst)));
-#else
+#else /* SLJIT_MIPS_REV < 1 */
if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
@@ -240,7 +240,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst)));
FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 */
return SLJIT_SUCCESS;
case SLJIT_ADD:
@@ -459,26 +459,27 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
SLJIT_ASSERT(!(flags & SRC2_IMM));
if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
-#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
if (op & SLJIT_I32_OP)
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
return push_inst(compiler, MFLO | D(dst), DR(dst));
-#else /* !SLJIT_MIPS_R6 && !SLJIT_MIPS_R1 */
+#else /* SLJIT_MIPS_REV < 1 */
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
return push_inst(compiler, MFLO | D(dst), DR(dst));
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
}
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
@@ -524,25 +525,21 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 6);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins *)addr;
-
- inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
- inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
- inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 6);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
index 7d1d087496..ecf4dac4c8 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
@@ -25,15 +25,16 @@
*/
/* Latest MIPS architecture. */
-/* Automatically detect SLJIT_MIPS_R1 */
-#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
-#define SLJIT_MIPS_R6 1
+#ifndef __mips_hard_float
+/* Disable automatic detection, covers both -msoft-float and -mno-float */
+#undef SLJIT_IS_FPU_AVAILABLE
+#define SLJIT_IS_FPU_AVAILABLE 0
#endif
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
{
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
return "MIPS32-R6" SLJIT_CPUINFO;
@@ -41,7 +42,7 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
return "MIPS64-R6" SLJIT_CPUINFO;
#endif /* SLJIT_CONFIG_MIPS_32 */
-#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
return "MIPS32-R1" SLJIT_CPUINFO;
@@ -49,9 +50,9 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
return "MIPS64-R1" SLJIT_CPUINFO;
#endif /* SLJIT_CONFIG_MIPS_32 */
-#else /* SLJIT_MIPS_R1 */
+#else /* SLJIT_MIPS_REV < 1 */
return "MIPS III" SLJIT_CPUINFO;
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
}
/* Length of an instruction word
@@ -117,11 +118,11 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
#define FR(dr) (freg_map[dr])
#define HI(opcode) ((opcode) << 26)
#define LO(opcode) (opcode)
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
/* CMP.cond.fmt */
/* S = (20 << 21) D = (21 << 21) */
#define CMP_FMT_S (20 << 21)
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
/* S = (16 << 21) D = (17 << 21) */
#define FMT_S (16 << 21)
#define FMT_D (17 << 21)
@@ -134,13 +135,13 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
#define ANDI (HI(12))
#define B (HI(4))
#define BAL (HI(1) | (17 << 16))
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3))
#define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3))
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
#define BC1F (HI(17) | (8 << 21))
#define BC1T (HI(17) | (8 << 21) | (1 << 16))
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
#define BEQ (HI(4))
#define BGEZ (HI(1) | (1 << 16))
#define BGTZ (HI(7))
@@ -149,23 +150,23 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
#define BNE (HI(5))
#define BREAK (HI(0) | LO(13))
#define CFC1 (HI(17) | (2 << 21))
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#define C_UEQ_S (HI(17) | CMP_FMT_S | LO(3))
#define C_ULE_S (HI(17) | CMP_FMT_S | LO(7))
#define C_ULT_S (HI(17) | CMP_FMT_S | LO(5))
#define C_UN_S (HI(17) | CMP_FMT_S | LO(1))
#define C_FD (FD(TMP_FREG3))
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
#define C_UEQ_S (HI(17) | FMT_S | LO(51))
#define C_ULE_S (HI(17) | FMT_S | LO(55))
#define C_ULT_S (HI(17) | FMT_S | LO(53))
#define C_UN_S (HI(17) | FMT_S | LO(49))
#define C_FD (0)
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
#define CVT_S_S (HI(17) | FMT_S | LO(32))
#define DADDIU (HI(25))
#define DADDU (HI(0) | LO(45))
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#define DDIV (HI(0) | (2 << 6) | LO(30))
#define DDIVU (HI(0) | (2 << 6) | LO(31))
#define DMOD (HI(0) | (3 << 6) | LO(30))
@@ -176,14 +177,14 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
#define DMUHU (HI(0) | (3 << 6) | LO(29))
#define DMUL (HI(0) | (2 << 6) | LO(28))
#define DMULU (HI(0) | (2 << 6) | LO(29))
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
#define DDIV (HI(0) | LO(30))
#define DDIVU (HI(0) | LO(31))
#define DIV (HI(0) | LO(26))
#define DIVU (HI(0) | LO(27))
#define DMULT (HI(0) | LO(28))
#define DMULTU (HI(0) | LO(29))
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
#define DIV_S (HI(17) | FMT_S | LO(3))
#define DSLL (HI(0) | LO(56))
#define DSLL32 (HI(0) | LO(60))
@@ -198,33 +199,33 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
#define J (HI(2))
#define JAL (HI(3))
#define JALR (HI(0) | LO(9))
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#define JR (HI(0) | LO(9))
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
#define JR (HI(0) | LO(8))
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
#define LD (HI(55))
#define LUI (HI(15))
#define LW (HI(35))
#define MFC1 (HI(17))
-#if !(defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
-#define MFHI (HI(0) | LO(16))
-#define MFLO (HI(0) | LO(18))
-#else /* SLJIT_MIPS_R6 */
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#define MOD (HI(0) | (3 << 6) | LO(26))
#define MODU (HI(0) | (3 << 6) | LO(27))
-#endif /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
+#define MFHI (HI(0) | LO(16))
+#define MFLO (HI(0) | LO(18))
+#endif /* SLJIT_MIPS_REV >= 6 */
#define MOV_S (HI(17) | FMT_S | LO(6))
#define MTC1 (HI(17) | (4 << 21))
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#define MUH (HI(0) | (3 << 6) | LO(24))
#define MUHU (HI(0) | (3 << 6) | LO(25))
#define MUL (HI(0) | (2 << 6) | LO(24))
#define MULU (HI(0) | (2 << 6) | LO(25))
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
#define MULT (HI(0) | LO(24))
#define MULTU (HI(0) | LO(25))
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
#define MUL_S (HI(17) | FMT_S | LO(2))
#define NEG_S (HI(17) | FMT_S | LO(7))
#define NOP (HI(0) | LO(0))
@@ -251,23 +252,23 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
#define XOR (HI(0) | LO(38))
#define XORI (HI(14))
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
#define CLZ (HI(28) | LO(32))
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#define DCLZ (LO(18))
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
#define DCLZ (HI(28) | LO(36))
#define MOVF (HI(0) | (0 << 16) | LO(1))
#define MOVN (HI(0) | LO(11))
#define MOVT (HI(0) | (1 << 16) | LO(1))
#define MOVZ (HI(0) | LO(10))
#define MUL (HI(28) | LO(2))
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
#define PREF (HI(51))
#define PREFX (HI(19) | LO(15))
#define SEB (HI(31) | (16 << 6) | LO(32))
#define SEH (HI(31) | (24 << 6) | LO(32))
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 */
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
#define ADDU_W ADDU
@@ -289,9 +290,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
Useful for reordering instructions in the delay slot. */
static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
{
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
|| delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f));
- sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
FAIL_IF(!ptr);
*ptr = ins;
compiler->size++;
@@ -303,10 +304,10 @@ static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags)
{
if (flags & IS_BIT26_COND)
return (1 << 26);
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
if (flags & IS_BIT23_COND)
return (1 << 23);
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
return (1 << 16);
}
@@ -519,7 +520,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
CHECK_PTR(check_sljit_generate_code(compiler));
reverse_buf(compiler);
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -666,6 +667,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* GCC workaround for invalid code generation with -O2. */
sljit_cache_flush(code, code_ptr);
#endif
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
return code;
}
@@ -678,17 +680,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
#ifdef SLJIT_IS_FPU_AVAILABLE
return SLJIT_IS_FPU_AVAILABLE;
#elif defined(__GNUC__)
- asm ("cfc1 %0, $0" : "=r"(fir));
+ __asm__ ("cfc1 %0, $0" : "=r"(fir));
return (fir >> 22) & 0x1;
#else
#error "FIR check is not implemented for this architecture"
#endif
+ case SLJIT_HAS_ZERO_REGISTER:
+ return 1;
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
case SLJIT_HAS_CLZ:
case SLJIT_HAS_CMOV:
+ case SLJIT_HAS_PREFETCH:
return 1;
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 */
default:
return fir;
@@ -1230,7 +1235,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
return push_inst(compiler, NOP, UNMOVABLE_INS);
case SLJIT_LMUL_UW:
case SLJIT_LMUL_SW:
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
@@ -1240,7 +1245,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
#endif /* SLJIT_CONFIG_MIPS_64 */
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
#else /* !SLJIT_CONFIG_MIPS_64 */
@@ -1248,13 +1253,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
#endif /* SLJIT_CONFIG_MIPS_64 */
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
case SLJIT_DIVMOD_UW:
case SLJIT_DIVMOD_SW:
case SLJIT_DIV_UW:
case SLJIT_DIV_SW:
SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
if (int_op) {
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
@@ -1270,11 +1275,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
#endif /* SLJIT_CONFIG_MIPS_64 */
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
-#else /* !SLJIT_MIPS_R6 */
-#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#else /* SLJIT_MIPS_REV < 6 */
+#if !(defined SLJIT_MIPS_REV)
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif /* !SLJIT_MIPS_R1 */
+#endif /* !SLJIT_MIPS_REV */
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
if (int_op)
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
@@ -1285,13 +1290,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
#endif /* SLJIT_CONFIG_MIPS_64 */
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
+ case SLJIT_ENDBR:
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return SLJIT_SUCCESS;
}
return SLJIT_SUCCESS;
}
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
sljit_s32 src, sljit_sw srcw)
{
@@ -1312,7 +1320,7 @@ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
}
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 */
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 dst, sljit_sw dstw,
@@ -1329,14 +1337,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
ADJUST_LOCAL_OFFSET(dst, dstw);
ADJUST_LOCAL_OFFSET(src, srcw);
- if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
- if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
- return emit_prefetch(compiler, src, srcw);
-#endif
- return SLJIT_SUCCESS;
- }
-
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT)
flags |= INT_DATA | SIGNED_DATA;
@@ -1463,6 +1463,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
#endif
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
+ else
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
+
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ return SLJIT_SUCCESS;
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
+ return emit_prefetch(compiler, src, srcw);
+#else /* SLJIT_MIPS_REV < 1 */
+ return SLJIT_SUCCESS;
+#endif /* SLJIT_MIPS_REV >= 1 */
+ }
+
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
{
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
@@ -1732,25 +1764,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
ADJUST_LOCAL_OFFSET(dst, dstw);
if (FAST_IS_REG(dst))
- return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst));
+ return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);
/* Memory. */
- return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
-
- FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
- return push_inst(compiler, NOP, UNMOVABLE_INS);
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw));
+ compiler->delay_slot = UNMOVABLE_INS;
+ return SLJIT_SUCCESS;
}
/* --------------------------------------------------------------------- */
@@ -1790,7 +1809,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
flags = IS_BIT26_COND; \
delay_check = src;
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
#define BR_T() \
inst = BC1NEZ; \
@@ -1801,7 +1820,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
flags = IS_BIT23_COND; \
delay_check = FCSR_FCC;
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
#define BR_T() \
inst = BC1T | JUMP_LENGTH; \
@@ -1812,7 +1831,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
flags = IS_BIT16_COND; \
delay_check = FCSR_FCC;
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
{
@@ -2123,11 +2142,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
case SLJIT_GREATER_EQUAL_F64:
case SLJIT_UNORDERED_F64:
case SLJIT_ORDERED_F64:
-#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
-#else /* !SLJIT_MIPS_R6 */
+#else /* SLJIT_MIPS_REV < 6 */
FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
-#endif /* SLJIT_MIPS_R6 */
+#endif /* SLJIT_MIPS_REV >= 6 */
FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
src_ar = dst_ar;
@@ -2167,14 +2186,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
sljit_s32 dst_reg,
sljit_s32 src, sljit_sw srcw)
{
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
sljit_ins ins;
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */
CHECK_ERROR();
CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
@@ -2231,9 +2250,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg));
-#else
+#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
-#endif
+#endif /* SLJIT_MIPS_REV >= 1 */
}
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
index 3ce741153f..7d9ec5338f 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
@@ -258,21 +258,18 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins *)addr;
-
- SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
- inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
index 3b73021cc8..92147d2a5d 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
@@ -477,23 +477,19 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins*)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 5);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins*)addr;
-
- inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
- inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
- inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 5);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c
index e827514315..d84562ce09 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c
@@ -404,7 +404,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
#endif
#endif
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -607,6 +607,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
return code_ptr;
@@ -626,7 +627,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
return 1;
#endif
+ /* A saved register is set to a zero value. */
+ case SLJIT_HAS_ZERO_REGISTER:
case SLJIT_HAS_CLZ:
+ case SLJIT_HAS_PREFETCH:
return 1;
default:
@@ -1158,6 +1162,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
#else
return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
#endif
+ case SLJIT_ENDBR:
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return SLJIT_SUCCESS;
}
return SLJIT_SUCCESS;
@@ -1203,13 +1210,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
ADJUST_LOCAL_OFFSET(dst, dstw);
ADJUST_LOCAL_OFFSET(src, srcw);
- if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
- if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
- return emit_prefetch(compiler, src, srcw);
-
- return SLJIT_SUCCESS;
- }
-
op = GET_OPCODE(op);
if ((src & SLJIT_IMM) && srcw == 0)
src = TMP_ZERO;
@@ -1536,6 +1536,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
return SLJIT_SUCCESS;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, MTLR | S(src)));
+ else {
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
+ }
+
+ return push_inst(compiler, BLR);
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ return SLJIT_SUCCESS;
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+ return emit_prefetch(compiler, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
{
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
@@ -1854,22 +1883,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
}
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, MTLR | S(src)));
- else {
- FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
- FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
- }
-
- return push_inst(compiler, BLR);
-}
-
/* --------------------------------------------------------------------- */
/* Conditional instructions */
/* --------------------------------------------------------------------- */
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeS390X.c b/thirdparty/pcre2/src/sljit/sljitNativeS390X.c
new file mode 100644
index 0000000000..a8b65112d4
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitNativeS390X.c
@@ -0,0 +1,2812 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/auxv.h>
+
+#ifdef __ARCH__
+#define ENABLE_STATIC_FACILITY_DETECTION 1
+#else
+#define ENABLE_STATIC_FACILITY_DETECTION 0
+#endif
+#define ENABLE_DYNAMIC_FACILITY_DETECTION 1
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+ return "s390x" SLJIT_CPUINFO;
+}
+
+/* Instructions. */
+typedef sljit_uw sljit_ins;
+
+/* Instruction tags (most significant halfword). */
+const sljit_ins sljit_ins_const = (sljit_ins)1 << 48;
+
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
+ 14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1
+};
+
+/* there are also a[2-15] available, but they are slower to access and
+ * their use is limited as mundaym explained:
+ * https://github.com/zherczeg/sljit/pull/91#discussion_r486895689
+ */
+
+/* General Purpose Registers [0-15]. */
+typedef sljit_uw sljit_gpr;
+
+/*
+ * WARNING
+ * the following code is non standard and should be improved for
+ * consistency, but doesn't use SLJIT_NUMBER_OF_REGISTERS based
+ * registers because r0 and r1 are the ABI recommended volatiles.
+ * there is a gpr() function that maps sljit to physical register numbers
+ * that should be used instead of the usual index into reg_map[] and
+ * will be retired ASAP (TODO: carenas)
+ */
+
+const sljit_gpr r0 = 0; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */
+const sljit_gpr r1 = 1; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */
+const sljit_gpr r2 = 2; /* reg_map[1]: 1st argument */
+const sljit_gpr r3 = 3; /* reg_map[2]: 2nd argument */
+const sljit_gpr r4 = 4; /* reg_map[3]: 3rd argument */
+const sljit_gpr r5 = 5; /* reg_map[4]: 4th argument */
+const sljit_gpr r6 = 6; /* reg_map[5]: 5th argument; 1st saved register */
+const sljit_gpr r7 = 7; /* reg_map[6] */
+const sljit_gpr r8 = 8; /* reg_map[7] */
+const sljit_gpr r9 = 9; /* reg_map[8] */
+const sljit_gpr r10 = 10; /* reg_map[9] */
+const sljit_gpr r11 = 11; /* reg_map[10] */
+const sljit_gpr r12 = 12; /* reg_map[11]: GOT */
+const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */
+const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */
+const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */
+
+/* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */
+/* TODO(carenas): r12 might conflict in PIC code, reserve? */
+/* TODO(carenas): r13 is usually pointed to "pool" per ABI, using a tmp
+ * like we do know might be faster though, reserve?
+ */
+
+/* TODO(carenas): should be named TMP_REG[1-2] for consistency */
+#define tmp0 r0
+#define tmp1 r1
+
+/* TODO(carenas): flags should move to a different register so that
+ * link register doesn't need to change
+ */
+
+/* Link registers. The normal link register is r14, but since
+ we use that for flags we need to use r0 instead to do fast
+ calls so that flags are preserved. */
+const sljit_gpr link_r = 14; /* r14 */
+const sljit_gpr fast_link_r = 0; /* r0 */
+
+/* Flag register layout:
+
+ 0 32 33 34 36 64
+ +---------------+---+---+-------+-------+
+ | ZERO | 0 | 0 | C C |///////|
+ +---------------+---+---+-------+-------+
+*/
+const sljit_gpr flag_r = 14; /* r14 */
+
+struct sljit_s390x_const {
+ struct sljit_const const_; /* must be first */
+ sljit_sw init_value; /* required to build literal pool */
+};
+
+/* Convert SLJIT register to hardware register. */
+static SLJIT_INLINE sljit_gpr gpr(sljit_s32 r)
+{
+ SLJIT_ASSERT(r != SLJIT_UNUSED);
+ SLJIT_ASSERT(r < (sljit_s32)(sizeof(reg_map) / sizeof(reg_map[0])));
+ return reg_map[r];
+}
+
+/* Size of instruction in bytes. Tags must already be cleared. */
+static SLJIT_INLINE sljit_uw sizeof_ins(sljit_ins ins)
+{
+ /* keep faulting instructions */
+ if (ins == 0)
+ return 2;
+
+ if ((ins & 0x00000000ffffL) == ins)
+ return 2;
+ if ((ins & 0x0000ffffffffL) == ins)
+ return 4;
+ if ((ins & 0xffffffffffffL) == ins)
+ return 6;
+
+ SLJIT_UNREACHABLE();
+ return (sljit_uw)-1;
+}
+
+static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
+{
+ sljit_ins *ibuf = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ibuf);
+ *ibuf = ins;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 encode_inst(void **ptr, sljit_ins ins)
+{
+ sljit_u16 *ibuf = (sljit_u16 *)*ptr;
+ sljit_uw size = sizeof_ins(ins);
+
+ SLJIT_ASSERT((size & 6) == size);
+ switch (size) {
+ case 6:
+ *ibuf++ = (sljit_u16)(ins >> 32);
+ /* fallthrough */
+ case 4:
+ *ibuf++ = (sljit_u16)(ins >> 16);
+ /* fallthrough */
+ case 2:
+ *ibuf++ = (sljit_u16)(ins);
+ }
+ *ptr = (void*)ibuf;
+ return SLJIT_SUCCESS;
+}
+
+/* Map the given type to a 4-bit condition code mask. */
+static SLJIT_INLINE sljit_u8 get_cc(sljit_s32 type) {
+ const sljit_u8 eq = 1 << 3; /* equal {,to zero} */
+ const sljit_u8 lt = 1 << 2; /* less than {,zero} */
+ const sljit_u8 gt = 1 << 1; /* greater than {,zero} */
+ const sljit_u8 ov = 1 << 0; /* {overflow,NaN} */
+
+ switch (type) {
+ case SLJIT_EQUAL:
+ case SLJIT_EQUAL_F64:
+ return eq;
+
+ case SLJIT_NOT_EQUAL:
+ case SLJIT_NOT_EQUAL_F64:
+ return ~eq;
+
+ case SLJIT_LESS:
+ case SLJIT_SIG_LESS:
+ case SLJIT_LESS_F64:
+ return lt;
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_SIG_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ return (lt | eq);
+
+ case SLJIT_GREATER:
+ case SLJIT_SIG_GREATER:
+ case SLJIT_GREATER_F64:
+ return gt;
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_SIG_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ return (gt | eq);
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_MUL_OVERFLOW:
+ case SLJIT_UNORDERED_F64:
+ return ov;
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ case SLJIT_ORDERED_F64:
+ return ~ov;
+ }
+
+ SLJIT_UNREACHABLE();
+ return (sljit_u8)-1;
+}
+
+/* Facility to bit index mappings.
+ Note: some facilities share the same bit index. */
+typedef sljit_uw facility_bit;
+#define STORE_FACILITY_LIST_EXTENDED_FACILITY 7
+#define FAST_LONG_DISPLACEMENT_FACILITY 19
+#define EXTENDED_IMMEDIATE_FACILITY 21
+#define GENERAL_INSTRUCTION_EXTENSION_FACILITY 34
+#define DISTINCT_OPERAND_FACILITY 45
+#define HIGH_WORD_FACILITY 45
+#define POPULATION_COUNT_FACILITY 45
+#define LOAD_STORE_ON_CONDITION_1_FACILITY 45
+#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY 49
+#define LOAD_STORE_ON_CONDITION_2_FACILITY 53
+#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY 58
+#define VECTOR_FACILITY 129
+#define VECTOR_ENHANCEMENTS_1_FACILITY 135
+
+/* Report whether a facility is known to be present due to the compiler
+ settings. This function should always be compiled to a constant
+ value given a constant argument. */
+static SLJIT_INLINE int have_facility_static(facility_bit x)
+{
+#if ENABLE_STATIC_FACILITY_DETECTION
+ switch (x) {
+ case FAST_LONG_DISPLACEMENT_FACILITY:
+ return (__ARCH__ >= 6 /* z990 */);
+ case EXTENDED_IMMEDIATE_FACILITY:
+ case STORE_FACILITY_LIST_EXTENDED_FACILITY:
+ return (__ARCH__ >= 7 /* z9-109 */);
+ case GENERAL_INSTRUCTION_EXTENSION_FACILITY:
+ return (__ARCH__ >= 8 /* z10 */);
+ case DISTINCT_OPERAND_FACILITY:
+ return (__ARCH__ >= 9 /* z196 */);
+ case MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY:
+ return (__ARCH__ >= 10 /* zEC12 */);
+ case LOAD_STORE_ON_CONDITION_2_FACILITY:
+ case VECTOR_FACILITY:
+ return (__ARCH__ >= 11 /* z13 */);
+ case MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY:
+ case VECTOR_ENHANCEMENTS_1_FACILITY:
+ return (__ARCH__ >= 12 /* z14 */);
+ default:
+ SLJIT_UNREACHABLE();
+ }
+#endif
+ return 0;
+}
+
+static SLJIT_INLINE unsigned long get_hwcap()
+{
+ static unsigned long hwcap = 0;
+ if (SLJIT_UNLIKELY(!hwcap)) {
+ hwcap = getauxval(AT_HWCAP);
+ SLJIT_ASSERT(hwcap != 0);
+ }
+ return hwcap;
+}
+
+static SLJIT_INLINE int have_stfle()
+{
+ if (have_facility_static(STORE_FACILITY_LIST_EXTENDED_FACILITY))
+ return 1;
+
+ return (get_hwcap() & HWCAP_S390_STFLE);
+}
+
+/* Report whether the given facility is available. This function always
+ performs a runtime check. */
+static int have_facility_dynamic(facility_bit x)
+{
+#if ENABLE_DYNAMIC_FACILITY_DETECTION
+ static struct {
+ sljit_uw bits[4];
+ } cpu_features;
+ size_t size = sizeof(cpu_features);
+ const sljit_uw word_index = x >> 6;
+ const sljit_uw bit_index = ((1UL << 63) >> (x & 63));
+
+ SLJIT_ASSERT(x < size * 8);
+ if (SLJIT_UNLIKELY(!have_stfle()))
+ return 0;
+
+ if (SLJIT_UNLIKELY(cpu_features.bits[0] == 0)) {
+ __asm__ __volatile__ (
+ "lgr %%r0, %0;"
+ "stfle 0(%1);"
+ /* outputs */:
+ /* inputs */: "d" ((size / 8) - 1), "a" (&cpu_features)
+ /* clobbers */: "r0", "cc", "memory"
+ );
+ SLJIT_ASSERT(cpu_features.bits[0] != 0);
+ }
+ return (cpu_features.bits[word_index] & bit_index) != 0;
+#else
+ return 0;
+#endif
+}
+
+#define HAVE_FACILITY(name, bit) \
+static SLJIT_INLINE int name() \
+{ \
+ static int have = -1; \
+ /* Static check first. May allow the function to be optimized away. */ \
+ if (have_facility_static(bit)) \
+ have = 1; \
+ else if (SLJIT_UNLIKELY(have < 0)) \
+ have = have_facility_dynamic(bit) ? 1 : 0; \
+\
+ return have; \
+}
+
+HAVE_FACILITY(have_eimm, EXTENDED_IMMEDIATE_FACILITY)
+HAVE_FACILITY(have_ldisp, FAST_LONG_DISPLACEMENT_FACILITY)
+HAVE_FACILITY(have_genext, GENERAL_INSTRUCTION_EXTENSION_FACILITY)
+HAVE_FACILITY(have_lscond1, LOAD_STORE_ON_CONDITION_1_FACILITY)
+HAVE_FACILITY(have_lscond2, LOAD_STORE_ON_CONDITION_2_FACILITY)
+HAVE_FACILITY(have_misc2, MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY)
+#undef HAVE_FACILITY
+
+#define is_u12(d) (0 <= (d) && (d) <= 0x00000fffL)
+#define is_u32(d) (0 <= (d) && (d) <= 0xffffffffL)
+
+#define CHECK_SIGNED(v, bitlen) \
+ ((v) == (((v) << (sizeof(v) * 8 - bitlen)) >> (sizeof(v) * 8 - bitlen)))
+
+#define is_s16(d) CHECK_SIGNED((d), 16)
+#define is_s20(d) CHECK_SIGNED((d), 20)
+#define is_s32(d) CHECK_SIGNED((d), 32)
+
+static SLJIT_INLINE sljit_uw disp_s20(sljit_s32 d)
+{
+ sljit_uw dh = (d >> 12) & 0xff;
+ sljit_uw dl = (d << 8) & 0xfff00;
+
+ SLJIT_ASSERT(is_s20(d));
+ return dh | dl;
+}
+
+/* TODO(carenas): variadic macro is not strictly needed */
+#define SLJIT_S390X_INSTRUCTION(op, ...) \
+static SLJIT_INLINE sljit_ins op(__VA_ARGS__)
+
+/* RR form instructions. */
+#define SLJIT_S390X_RR(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \
+{ \
+ return (pattern) | ((dst & 0xf) << 4) | (src & 0xf); \
+}
+
+/* ADD */
+SLJIT_S390X_RR(ar, 0x1a00)
+
+/* ADD LOGICAL */
+SLJIT_S390X_RR(alr, 0x1e00)
+
+/* AND */
+SLJIT_S390X_RR(nr, 0x1400)
+
+/* BRANCH AND SAVE */
+SLJIT_S390X_RR(basr, 0x0d00)
+
+/* BRANCH ON CONDITION */
+SLJIT_S390X_RR(bcr, 0x0700) /* TODO(mundaym): type for mask? */
+
+/* COMPARE */
+SLJIT_S390X_RR(cr, 0x1900)
+
+/* COMPARE LOGICAL */
+SLJIT_S390X_RR(clr, 0x1500)
+
+/* DIVIDE */
+SLJIT_S390X_RR(dr, 0x1d00)
+
+/* EXCLUSIVE OR */
+SLJIT_S390X_RR(xr, 0x1700)
+
+/* LOAD */
+SLJIT_S390X_RR(lr, 0x1800)
+
+/* LOAD COMPLEMENT */
+SLJIT_S390X_RR(lcr, 0x1300)
+
+/* OR */
+SLJIT_S390X_RR(or, 0x1600)
+
+/* SUBTRACT */
+SLJIT_S390X_RR(sr, 0x1b00)
+
+/* SUBTRACT LOGICAL */
+SLJIT_S390X_RR(slr, 0x1f00)
+
+#undef SLJIT_S390X_RR
+
+/* RRE form instructions */
+#define SLJIT_S390X_RRE(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \
+{ \
+ return (pattern) | ((dst & 0xf) << 4) | (src & 0xf); \
+}
+
+/* ADD */
+SLJIT_S390X_RRE(agr, 0xb9080000)
+
+/* ADD LOGICAL */
+SLJIT_S390X_RRE(algr, 0xb90a0000)
+
+/* ADD LOGICAL WITH CARRY */
+SLJIT_S390X_RRE(alcr, 0xb9980000)
+SLJIT_S390X_RRE(alcgr, 0xb9880000)
+
+/* AND */
+SLJIT_S390X_RRE(ngr, 0xb9800000)
+
+/* COMPARE */
+SLJIT_S390X_RRE(cgr, 0xb9200000)
+
+/* COMPARE LOGICAL */
+SLJIT_S390X_RRE(clgr, 0xb9210000)
+
+/* DIVIDE LOGICAL */
+SLJIT_S390X_RRE(dlr, 0xb9970000)
+SLJIT_S390X_RRE(dlgr, 0xb9870000)
+
+/* DIVIDE SINGLE */
+SLJIT_S390X_RRE(dsgr, 0xb90d0000)
+
+/* EXCLUSIVE OR */
+SLJIT_S390X_RRE(xgr, 0xb9820000)
+
+/* LOAD */
+SLJIT_S390X_RRE(lgr, 0xb9040000)
+SLJIT_S390X_RRE(lgfr, 0xb9140000)
+
+/* LOAD BYTE */
+SLJIT_S390X_RRE(lbr, 0xb9260000)
+SLJIT_S390X_RRE(lgbr, 0xb9060000)
+
+/* LOAD COMPLEMENT */
+SLJIT_S390X_RRE(lcgr, 0xb9030000)
+
+/* LOAD HALFWORD */
+SLJIT_S390X_RRE(lhr, 0xb9270000)
+SLJIT_S390X_RRE(lghr, 0xb9070000)
+
+/* LOAD LOGICAL */
+SLJIT_S390X_RRE(llgfr, 0xb9160000)
+
+/* LOAD LOGICAL CHARACTER */
+SLJIT_S390X_RRE(llcr, 0xb9940000)
+SLJIT_S390X_RRE(llgcr, 0xb9840000)
+
+/* LOAD LOGICAL HALFWORD */
+SLJIT_S390X_RRE(llhr, 0xb9950000)
+SLJIT_S390X_RRE(llghr, 0xb9850000)
+
+/* MULTIPLY LOGICAL */
+SLJIT_S390X_RRE(mlgr, 0xb9860000)
+
+/* MULTIPLY SINGLE */
+SLJIT_S390X_RRE(msr, 0xb2520000)
+SLJIT_S390X_RRE(msgr, 0xb90c0000)
+SLJIT_S390X_RRE(msgfr, 0xb91c0000)
+
+/* OR */
+SLJIT_S390X_RRE(ogr, 0xb9810000)
+
+/* SUBTRACT */
+SLJIT_S390X_RRE(sgr, 0xb9090000)
+
+/* SUBTRACT LOGICAL */
+SLJIT_S390X_RRE(slgr, 0xb90b0000)
+
+/* SUBTRACT LOGICAL WITH BORROW */
+SLJIT_S390X_RRE(slbr, 0xb9990000)
+SLJIT_S390X_RRE(slbgr, 0xb9890000)
+
+#undef SLJIT_S390X_RRE
+
+/* RI-a form instructions */
+#define SLJIT_S390X_RIA(name, pattern, imm_type) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \
+{ \
+ return (pattern) | ((reg & 0xf) << 20) | (imm & 0xffff); \
+}
+
+/* ADD HALFWORD IMMEDIATE */
+SLJIT_S390X_RIA(ahi, 0xa70a0000, sljit_s16)
+SLJIT_S390X_RIA(aghi, 0xa70b0000, sljit_s16)
+
+/* COMPARE HALFWORD IMMEDIATE */
+SLJIT_S390X_RIA(chi, 0xa70e0000, sljit_s16)
+SLJIT_S390X_RIA(cghi, 0xa70f0000, sljit_s16)
+
+/* LOAD HALFWORD IMMEDIATE */
+SLJIT_S390X_RIA(lhi, 0xa7080000, sljit_s16)
+SLJIT_S390X_RIA(lghi, 0xa7090000, sljit_s16)
+
+/* LOAD LOGICAL IMMEDIATE */
+SLJIT_S390X_RIA(llihh, 0xa50c0000, sljit_u16)
+SLJIT_S390X_RIA(llihl, 0xa50d0000, sljit_u16)
+SLJIT_S390X_RIA(llilh, 0xa50e0000, sljit_u16)
+SLJIT_S390X_RIA(llill, 0xa50f0000, sljit_u16)
+
+/* MULTIPLY HALFWORD IMMEDIATE */
+SLJIT_S390X_RIA(mhi, 0xa70c0000, sljit_s16)
+SLJIT_S390X_RIA(mghi, 0xa70d0000, sljit_s16)
+
+/* OR IMMEDIATE */
+SLJIT_S390X_RIA(oilh, 0xa50a0000, sljit_u16)
+
+/* TEST UNDER MASK */
+SLJIT_S390X_RIA(tmlh, 0xa7000000, sljit_u16)
+
+#undef SLJIT_S390X_RIA
+
+/* RIL-a form instructions (requires extended immediate facility) */
+#define SLJIT_S390X_RILA(name, pattern, imm_type) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \
+{ \
+ SLJIT_ASSERT(have_eimm()); \
+ return (pattern) | ((sljit_ins)(reg & 0xf) << 36) | (imm & 0xffffffff); \
+}
+
+/* ADD IMMEDIATE */
+SLJIT_S390X_RILA(afi, 0xc20900000000, sljit_s32)
+SLJIT_S390X_RILA(agfi, 0xc20800000000, sljit_s32)
+
+/* ADD IMMEDIATE HIGH */
+SLJIT_S390X_RILA(aih, 0xcc0800000000, sljit_s32) /* TODO(mundaym): high-word facility? */
+
+/* ADD LOGICAL IMMEDIATE */
+SLJIT_S390X_RILA(alfi, 0xc20b00000000, sljit_u32)
+SLJIT_S390X_RILA(algfi, 0xc20a00000000, sljit_u32)
+
+/* AND IMMEDIATE */
+SLJIT_S390X_RILA(nihf, 0xc00a00000000, sljit_u32)
+SLJIT_S390X_RILA(nilf, 0xc00b00000000, sljit_u32)
+
+/* COMPARE IMMEDIATE */
+SLJIT_S390X_RILA(cfi, 0xc20d00000000, sljit_s32)
+SLJIT_S390X_RILA(cgfi, 0xc20c00000000, sljit_s32)
+
+/* COMPARE IMMEDIATE HIGH */
+SLJIT_S390X_RILA(cih, 0xcc0d00000000, sljit_s32) /* TODO(mundaym): high-word facility? */
+
+/* COMPARE LOGICAL IMMEDIATE */
+SLJIT_S390X_RILA(clfi, 0xc20f00000000, sljit_u32)
+SLJIT_S390X_RILA(clgfi, 0xc20e00000000, sljit_u32)
+
+/* EXCLUSIVE OR IMMEDIATE */
+SLJIT_S390X_RILA(xilf, 0xc00700000000, sljit_u32)
+
+/* INSERT IMMEDIATE */
+SLJIT_S390X_RILA(iihf, 0xc00800000000, sljit_u32)
+SLJIT_S390X_RILA(iilf, 0xc00900000000, sljit_u32)
+
+/* LOAD IMMEDIATE */
+SLJIT_S390X_RILA(lgfi, 0xc00100000000, sljit_s32)
+
+/* LOAD LOGICAL IMMEDIATE */
+SLJIT_S390X_RILA(llihf, 0xc00e00000000, sljit_u32)
+SLJIT_S390X_RILA(llilf, 0xc00f00000000, sljit_u32)
+
+/* OR IMMEDIATE */
+SLJIT_S390X_RILA(oilf, 0xc00d00000000, sljit_u32)
+
+#undef SLJIT_S390X_RILA
+
+/* RX-a form instructions */
+#define SLJIT_S390X_RXA(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_u16 d, sljit_gpr x, sljit_gpr b) \
+{ \
+ sljit_ins ri, xi, bi, di; \
+\
+ SLJIT_ASSERT((d & 0xfff) == d); \
+ ri = (sljit_ins)(r & 0xf) << 20; \
+ xi = (sljit_ins)(x & 0xf) << 16; \
+ bi = (sljit_ins)(b & 0xf) << 12; \
+ di = (sljit_ins)(d & 0xfff); \
+\
+ return (pattern) | ri | xi | bi | di; \
+}
+
+/* ADD */
+SLJIT_S390X_RXA(a, 0x5a000000)
+
+/* ADD LOGICAL */
+SLJIT_S390X_RXA(al, 0x5e000000)
+
+/* AND */
+SLJIT_S390X_RXA(n, 0x54000000)
+
+/* EXCLUSIVE OR */
+SLJIT_S390X_RXA(x, 0x57000000)
+
+/* LOAD */
+SLJIT_S390X_RXA(l, 0x58000000)
+
+/* LOAD ADDRESS */
+SLJIT_S390X_RXA(la, 0x41000000)
+
+/* LOAD HALFWORD */
+SLJIT_S390X_RXA(lh, 0x48000000)
+
+/* MULTIPLY SINGLE */
+SLJIT_S390X_RXA(ms, 0x71000000)
+
+/* OR */
+SLJIT_S390X_RXA(o, 0x56000000)
+
+/* STORE */
+SLJIT_S390X_RXA(st, 0x50000000)
+
+/* STORE CHARACTER */
+SLJIT_S390X_RXA(stc, 0x42000000)
+
+/* STORE HALFWORD */
+SLJIT_S390X_RXA(sth, 0x40000000)
+
+/* SUBTRACT */
+SLJIT_S390X_RXA(s, 0x5b000000)
+
+/* SUBTRACT LOGICAL */
+SLJIT_S390X_RXA(sl, 0x5f000000)
+
+#undef SLJIT_S390X_RXA
+
+/* RXY-a instructions */
+#define SLJIT_S390X_RXYA(name, pattern, cond) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b) \
+{ \
+ sljit_ins ri, xi, bi, di; \
+\
+ SLJIT_ASSERT(cond); \
+ ri = (sljit_ins)(r & 0xf) << 36; \
+ xi = (sljit_ins)(x & 0xf) << 32; \
+ bi = (sljit_ins)(b & 0xf) << 28; \
+ di = (sljit_ins)disp_s20(d) << 8; \
+\
+ return (pattern) | ri | xi | bi | di; \
+}
+
+/* ADD */
+SLJIT_S390X_RXYA(ay, 0xe3000000005a, have_ldisp())
+SLJIT_S390X_RXYA(ag, 0xe30000000008, 1)
+
+/* ADD LOGICAL */
+SLJIT_S390X_RXYA(aly, 0xe3000000005e, have_ldisp())
+SLJIT_S390X_RXYA(alg, 0xe3000000000a, 1)
+
+/* ADD LOGICAL WITH CARRY */
+SLJIT_S390X_RXYA(alc, 0xe30000000098, 1)
+SLJIT_S390X_RXYA(alcg, 0xe30000000088, 1)
+
+/* AND */
+SLJIT_S390X_RXYA(ny, 0xe30000000054, have_ldisp())
+SLJIT_S390X_RXYA(ng, 0xe30000000080, 1)
+
+/* EXCLUSIVE OR */
+SLJIT_S390X_RXYA(xy, 0xe30000000057, have_ldisp())
+SLJIT_S390X_RXYA(xg, 0xe30000000082, 1)
+
+/* LOAD */
+SLJIT_S390X_RXYA(ly, 0xe30000000058, have_ldisp())
+SLJIT_S390X_RXYA(lg, 0xe30000000004, 1)
+SLJIT_S390X_RXYA(lgf, 0xe30000000014, 1)
+
+/* LOAD BYTE */
+SLJIT_S390X_RXYA(lb, 0xe30000000076, have_ldisp())
+SLJIT_S390X_RXYA(lgb, 0xe30000000077, have_ldisp())
+
+/* LOAD HALFWORD */
+SLJIT_S390X_RXYA(lhy, 0xe30000000078, have_ldisp())
+SLJIT_S390X_RXYA(lgh, 0xe30000000015, 1)
+
+/* LOAD LOGICAL */
+SLJIT_S390X_RXYA(llgf, 0xe30000000016, 1)
+
+/* LOAD LOGICAL CHARACTER */
+SLJIT_S390X_RXYA(llc, 0xe30000000094, have_eimm())
+SLJIT_S390X_RXYA(llgc, 0xe30000000090, 1)
+
+/* LOAD LOGICAL HALFWORD */
+SLJIT_S390X_RXYA(llh, 0xe30000000095, have_eimm())
+SLJIT_S390X_RXYA(llgh, 0xe30000000091, 1)
+
+/* MULTIPLY SINGLE */
+SLJIT_S390X_RXYA(msy, 0xe30000000051, have_ldisp())
+SLJIT_S390X_RXYA(msg, 0xe3000000000c, 1)
+
+/* OR */
+SLJIT_S390X_RXYA(oy, 0xe30000000056, have_ldisp())
+SLJIT_S390X_RXYA(og, 0xe30000000081, 1)
+
+/* STORE */
+SLJIT_S390X_RXYA(sty, 0xe30000000050, have_ldisp())
+SLJIT_S390X_RXYA(stg, 0xe30000000024, 1)
+
+/* STORE CHARACTER */
+SLJIT_S390X_RXYA(stcy, 0xe30000000072, have_ldisp())
+
+/* STORE HALFWORD */
+SLJIT_S390X_RXYA(sthy, 0xe30000000070, have_ldisp())
+
+/* SUBTRACT */
+SLJIT_S390X_RXYA(sy, 0xe3000000005b, have_ldisp())
+SLJIT_S390X_RXYA(sg, 0xe30000000009, 1)
+
+/* SUBTRACT LOGICAL */
+SLJIT_S390X_RXYA(sly, 0xe3000000005f, have_ldisp())
+SLJIT_S390X_RXYA(slg, 0xe3000000000b, 1)
+
+/* SUBTRACT LOGICAL WITH BORROW */
+SLJIT_S390X_RXYA(slb, 0xe30000000099, 1)
+SLJIT_S390X_RXYA(slbg, 0xe30000000089, 1)
+
+#undef SLJIT_S390X_RXYA
+
+/* RS-a instructions */
+#define SLJIT_S390X_RSA(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw d, sljit_gpr b) \
+{ \
+ sljit_ins r1 = (sljit_ins)(reg & 0xf) << 20; \
+ sljit_ins b2 = (sljit_ins)(b & 0xf) << 12; \
+ sljit_ins d2 = (sljit_ins)(d & 0xfff); \
+ return (pattern) | r1 | b2 | d2; \
+}
+
+/* SHIFT LEFT SINGLE LOGICAL */
+SLJIT_S390X_RSA(sll, 0x89000000)
+
+/* SHIFT RIGHT SINGLE */
+SLJIT_S390X_RSA(sra, 0x8a000000)
+
+/* SHIFT RIGHT SINGLE LOGICAL */
+SLJIT_S390X_RSA(srl, 0x88000000)
+
+#undef SLJIT_S390X_RSA
+
+/* RSY-a instructions */
+#define SLJIT_S390X_RSYA(name, pattern, cond) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_sw d, sljit_gpr b) \
+{ \
+ sljit_ins r1, r3, b2, d2; \
+\
+ SLJIT_ASSERT(cond); \
+ r1 = (sljit_ins)(dst & 0xf) << 36; \
+ r3 = (sljit_ins)(src & 0xf) << 32; \
+ b2 = (sljit_ins)(b & 0xf) << 28; \
+ d2 = (sljit_ins)disp_s20(d) << 8; \
+\
+ return (pattern) | r1 | r3 | b2 | d2; \
+}
+
+/* LOAD MULTIPLE */
+SLJIT_S390X_RSYA(lmg, 0xeb0000000004, 1)
+
+/* SHIFT LEFT LOGICAL */
+SLJIT_S390X_RSYA(sllg, 0xeb000000000d, 1)
+
+/* SHIFT RIGHT SINGLE */
+SLJIT_S390X_RSYA(srag, 0xeb000000000a, 1)
+
+/* SHIFT RIGHT SINGLE LOGICAL */
+SLJIT_S390X_RSYA(srlg, 0xeb000000000c, 1)
+
+/* STORE MULTIPLE */
+SLJIT_S390X_RSYA(stmg, 0xeb0000000024, 1)
+
+#undef SLJIT_S390X_RSYA
+
+/* RIE-f instructions (require general-instructions-extension facility) */
+#define SLJIT_S390X_RIEF(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot) \
+{ \
+ sljit_ins r1, r2, i3, i4, i5; \
+\
+ SLJIT_ASSERT(have_genext()); \
+ r1 = (sljit_ins)(dst & 0xf) << 36; \
+ r2 = (sljit_ins)(src & 0xf) << 32; \
+ i3 = (sljit_ins)start << 24; \
+ i4 = (sljit_ins)end << 16; \
+ i5 = (sljit_ins)rot << 8; \
+\
+ return (pattern) | r1 | r2 | i3 | i4 | i5; \
+}
+
+/* ROTATE THEN AND SELECTED BITS */
+/* SLJIT_S390X_RIEF(rnsbg, 0xec0000000054) */
+
+/* ROTATE THEN EXCLUSIVE OR SELECTED BITS */
+/* SLJIT_S390X_RIEF(rxsbg, 0xec0000000057) */
+
+/* ROTATE THEN OR SELECTED BITS */
+SLJIT_S390X_RIEF(rosbg, 0xec0000000056)
+
+/* ROTATE THEN INSERT SELECTED BITS */
+/* SLJIT_S390X_RIEF(risbg, 0xec0000000055) */
+/* SLJIT_S390X_RIEF(risbgn, 0xec0000000059) */
+
+/* ROTATE THEN INSERT SELECTED BITS HIGH */
+SLJIT_S390X_RIEF(risbhg, 0xec000000005d)
+
+/* ROTATE THEN INSERT SELECTED BITS LOW */
+/* SLJIT_S390X_RIEF(risblg, 0xec0000000051) */
+
+#undef SLJIT_S390X_RIEF
+
+/* RRF-a instructions */
+#define SLJIT_S390X_RRFA(name, pattern, cond) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src1, sljit_gpr src2) \
+{ \
+ sljit_ins r1, r2, r3; \
+\
+ SLJIT_ASSERT(cond); \
+ r1 = (sljit_ins)(dst & 0xf) << 4; \
+ r2 = (sljit_ins)(src1 & 0xf); \
+ r3 = (sljit_ins)(src2 & 0xf) << 12; \
+\
+ return (pattern) | r3 | r1 | r2; \
+}
+
+/* MULTIPLY */
+SLJIT_S390X_RRFA(msrkc, 0xb9fd0000, have_misc2())
+SLJIT_S390X_RRFA(msgrkc, 0xb9ed0000, have_misc2())
+
+#undef SLJIT_S390X_RRFA
+
+/* RRF-c instructions (require load/store-on-condition 1 facility) */
+#define SLJIT_S390X_RRFC(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_uw mask) \
+{ \
+ sljit_ins r1, r2, m3; \
+\
+ SLJIT_ASSERT(have_lscond1()); \
+ r1 = (sljit_ins)(dst & 0xf) << 4; \
+ r2 = (sljit_ins)(src & 0xf); \
+ m3 = (sljit_ins)(mask & 0xf) << 12; \
+\
+ return (pattern) | m3 | r1 | r2; \
+}
+
+/* LOAD HALFWORD IMMEDIATE ON CONDITION */
+SLJIT_S390X_RRFC(locr, 0xb9f20000)
+SLJIT_S390X_RRFC(locgr, 0xb9e20000)
+
+#undef SLJIT_S390X_RRFC
+
+/* RIE-g instructions (require load/store-on-condition 2 facility) */
+#define SLJIT_S390X_RIEG(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw imm, sljit_uw mask) \
+{ \
+ sljit_ins r1, m3, i2; \
+\
+ SLJIT_ASSERT(have_lscond2()); \
+ r1 = (sljit_ins)(reg & 0xf) << 36; \
+ m3 = (sljit_ins)(mask & 0xf) << 32; \
+ i2 = (sljit_ins)(imm & 0xffffL) << 16; \
+\
+ return (pattern) | r1 | m3 | i2; \
+}
+
+/* LOAD HALFWORD IMMEDIATE ON CONDITION */
+SLJIT_S390X_RIEG(lochi, 0xec0000000042)
+SLJIT_S390X_RIEG(locghi, 0xec0000000046)
+
+#undef SLJIT_S390X_RIEG
+
+#define SLJIT_S390X_RILB(name, pattern, cond) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw ri) \
+{ \
+ sljit_ins r1, ri2; \
+\
+ SLJIT_ASSERT(cond); \
+ r1 = (sljit_ins)(reg & 0xf) << 36; \
+ ri2 = (sljit_ins)(ri & 0xffffffff); \
+\
+ return (pattern) | r1 | ri2; \
+}
+
+/* BRANCH RELATIVE AND SAVE LONG */
+SLJIT_S390X_RILB(brasl, 0xc00500000000, 1)
+
+/* LOAD ADDRESS RELATIVE LONG */
+SLJIT_S390X_RILB(larl, 0xc00000000000, 1)
+
+/* LOAD RELATIVE LONG */
+SLJIT_S390X_RILB(lgrl, 0xc40800000000, have_genext())
+
+#undef SLJIT_S390X_RILB
+
+SLJIT_S390X_INSTRUCTION(br, sljit_gpr target)
+{
+ return 0x07f0 | target;
+}
+
+SLJIT_S390X_INSTRUCTION(brcl, sljit_uw mask, sljit_sw target)
+{
+ sljit_ins m1 = (sljit_ins)(mask & 0xf) << 36;
+ sljit_ins ri2 = (sljit_ins)target & 0xffffffff;
+ return 0xc00400000000L | m1 | ri2;
+}
+
+SLJIT_S390X_INSTRUCTION(flogr, sljit_gpr dst, sljit_gpr src)
+{
+ sljit_ins r1 = ((sljit_ins)dst & 0xf) << 8;
+ sljit_ins r2 = ((sljit_ins)src & 0xf);
+ SLJIT_ASSERT(have_eimm());
+ return 0xb9830000 | r1 | r2;
+}
+
+/* INSERT PROGRAM MASK */
+SLJIT_S390X_INSTRUCTION(ipm, sljit_gpr dst)
+{
+ return 0xb2220000 | ((sljit_ins)(dst & 0xf) << 4);
+}
+
+/* ROTATE THEN INSERT SELECTED BITS HIGH (ZERO) */
+SLJIT_S390X_INSTRUCTION(risbhgz, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot)
+{
+ return risbhg(dst, src, start, 0x8 | end, rot);
+}
+
+#undef SLJIT_S390X_INSTRUCTION
+
+/* load condition code as needed to match type */
+static sljit_s32 push_load_cc(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ type &= ~SLJIT_I32_OP;
+ switch (type) {
+ case SLJIT_ZERO:
+ case SLJIT_NOT_ZERO:
+ return push_inst(compiler, cih(flag_r, 0));
+ break;
+ default:
+ return push_inst(compiler, tmlh(flag_r, 0x3000));
+ break;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_store_zero_flag(struct sljit_compiler *compiler, sljit_s32 op, sljit_gpr source)
+{
+ /* insert low 32-bits into high 32-bits of flag register */
+ FAIL_IF(push_inst(compiler, risbhgz(flag_r, source, 0, 31, 32)));
+ if (!(op & SLJIT_I32_OP)) {
+ /* OR high 32-bits with high 32-bits of flag register */
+ return push_inst(compiler, rosbg(flag_r, source, 0, 31, 0));
+ }
+ return SLJIT_SUCCESS;
+}
+
+/* load 64-bit immediate into register without clobbering flags */
+static sljit_s32 push_load_imm_inst(struct sljit_compiler *compiler, sljit_gpr target, sljit_sw v)
+{
+ /* 4 byte instructions */
+ if (is_s16(v))
+ return push_inst(compiler, lghi(target, (sljit_s16)v));
+
+ if ((sljit_uw)v == (v & 0x000000000000ffffU))
+ return push_inst(compiler, llill(target, (sljit_u16)v));
+
+ if ((sljit_uw)v == (v & 0x00000000ffff0000U))
+ return push_inst(compiler, llilh(target, (sljit_u16)(v >> 16)));
+
+ if ((sljit_uw)v == (v & 0x0000ffff00000000U))
+ return push_inst(compiler, llihl(target, (sljit_u16)(v >> 32)));
+
+ if ((sljit_uw)v == (v & 0xffff000000000000U))
+ return push_inst(compiler, llihh(target, (sljit_u16)(v >> 48)));
+
+ /* 6 byte instructions (requires extended immediate facility) */
+ if (have_eimm()) {
+ if (is_s32(v))
+ return push_inst(compiler, lgfi(target, (sljit_s32)v));
+
+ if ((sljit_uw)v == (v & 0x00000000ffffffffU))
+ return push_inst(compiler, llilf(target, (sljit_u32)v));
+
+ if ((sljit_uw)v == (v & 0xffffffff00000000U))
+ return push_inst(compiler, llihf(target, (sljit_u32)(v >> 32)));
+
+ FAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v)));
+ return push_inst(compiler, iihf(target, (sljit_u32)(v >> 32)));
+ }
+ /* TODO(mundaym): instruction sequences that don't use extended immediates */
+ abort();
+}
+
+struct addr {
+ sljit_gpr base;
+ sljit_gpr index;
+ sljit_sw offset;
+};
+
+/* transform memory operand into D(X,B) form with a signed 20-bit offset */
+static sljit_s32 make_addr_bxy(struct sljit_compiler *compiler,
+ struct addr *addr, sljit_s32 mem, sljit_sw off,
+ sljit_gpr tmp /* clobbered, must not be r0 */)
+{
+ sljit_gpr base = r0;
+ sljit_gpr index = r0;
+
+ SLJIT_ASSERT(tmp != r0);
+ if (mem & REG_MASK)
+ base = gpr(mem & REG_MASK);
+
+ if (mem & OFFS_REG_MASK) {
+ index = gpr(OFFS_REG(mem));
+ if (off != 0) {
+ /* shift and put the result into tmp */
+ SLJIT_ASSERT(0 <= off && off < 64);
+ FAIL_IF(push_inst(compiler, sllg(tmp, index, off, 0)));
+ index = tmp;
+ off = 0; /* clear offset */
+ }
+ }
+ else if (!is_s20(off)) {
+ FAIL_IF(push_load_imm_inst(compiler, tmp, off));
+ index = tmp;
+ off = 0; /* clear offset */
+ }
+ addr->base = base;
+ addr->index = index;
+ addr->offset = off;
+ return SLJIT_SUCCESS;
+}
+
+/* transform memory operand into D(X,B) form with an unsigned 12-bit offset */
+static sljit_s32 make_addr_bx(struct sljit_compiler *compiler,
+ struct addr *addr, sljit_s32 mem, sljit_sw off,
+ sljit_gpr tmp /* clobbered, must not be r0 */)
+{
+ sljit_gpr base = r0;
+ sljit_gpr index = r0;
+
+ SLJIT_ASSERT(tmp != r0);
+ if (mem & REG_MASK)
+ base = gpr(mem & REG_MASK);
+
+ if (mem & OFFS_REG_MASK) {
+ index = gpr(OFFS_REG(mem));
+ if (off != 0) {
+ /* shift and put the result into tmp */
+ SLJIT_ASSERT(0 <= off && off < 64);
+ FAIL_IF(push_inst(compiler, sllg(tmp, index, off, 0)));
+ index = tmp;
+ off = 0; /* clear offset */
+ }
+ }
+ else if (!is_u12(off)) {
+ FAIL_IF(push_load_imm_inst(compiler, tmp, off));
+ index = tmp;
+ off = 0; /* clear offset */
+ }
+ addr->base = base;
+ addr->index = index;
+ addr->offset = off;
+ return SLJIT_SUCCESS;
+}
+
+#define EVAL(op, r, addr) op(r, addr.offset, addr.index, addr.base)
+#define WHEN(cond, r, i1, i2, addr) \
+ (cond) ? EVAL(i1, r, addr) : EVAL(i2, r, addr)
+
+static sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_gpr tmp /* clobbered */, sljit_s32 is_32bit)
+{
+ struct addr addr;
+ sljit_ins ins;
+
+ SLJIT_ASSERT(src & SLJIT_MEM);
+ if (have_ldisp() || !is_32bit)
+ FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp));
+ else
+ FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp));
+
+ if (is_32bit)
+ ins = WHEN(is_u12(addr.offset), dst, l, ly, addr);
+ else
+ ins = lg(dst, addr.offset, addr.index, addr.base);
+
+ return push_inst(compiler, ins);
+}
+
+static sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_gpr tmp /* clobbered */, sljit_s32 is_32bit)
+{
+ struct addr addr;
+ sljit_ins ins;
+
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+ if (have_ldisp() || !is_32bit)
+ FAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp));
+ else
+ FAIL_IF(make_addr_bx(compiler, &addr, dst, dstw, tmp));
+
+ if (is_32bit)
+ ins = WHEN(is_u12(addr.offset), src, st, sty, addr);
+ else
+ ins = stg(src, addr.offset, addr.index, addr.base);
+
+ return push_inst(compiler, ins);
+}
+
+#undef WHEN
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_s390x_const *const_;
+ struct sljit_put_label *put_label;
+ sljit_sw executable_offset;
+ sljit_uw ins_size = 0; /* instructions */
+ sljit_uw pool_size = 0; /* literal pool */
+ sljit_uw pad_size;
+ sljit_uw i, j = 0;
+ struct sljit_memory_fragment *buf;
+ void *code, *code_ptr;
+ sljit_uw *pool, *pool_ptr;
+
+ sljit_uw source;
+ sljit_sw offset; /* TODO(carenas): only need 32 bit */
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_generate_code(compiler));
+ reverse_buf(compiler);
+
+ /* branch handling */
+ label = compiler->labels;
+ jump = compiler->jumps;
+ put_label = compiler->put_labels;
+
+ /* TODO(carenas): compiler->executable_size could be calculated
+ * before to avoid the following loop (except for
+ * pool_size)
+ */
+ /* calculate the size of the code */
+ for (buf = compiler->buf; buf != NULL; buf = buf->next) {
+ sljit_uw len = buf->used_size / sizeof(sljit_ins);
+ sljit_ins *ibuf = (sljit_ins *)buf->memory;
+ for (i = 0; i < len; ++i, ++j) {
+ sljit_ins ins = ibuf[i];
+
+ /* TODO(carenas): instruction tag vs size/addr == j
+ * using instruction tags for const is creative
+ * but unlike all other architectures, and is not
+ * done consistently for all other objects.
+ * This might need reviewing later.
+ */
+ if (ins & sljit_ins_const) {
+ pool_size += sizeof(*pool);
+ ins &= ~sljit_ins_const;
+ }
+ if (label && label->size == j) {
+ label->size = ins_size;
+ label = label->next;
+ }
+ if (jump && jump->addr == j) {
+ if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) {
+ /* encoded: */
+ /* brasl %r14, <rel_addr> (or brcl <mask>, <rel_addr>) */
+ /* replace with: */
+ /* lgrl %r1, <pool_addr> */
+ /* bras %r14, %r1 (or bcr <mask>, %r1) */
+ pool_size += sizeof(*pool);
+ ins_size += 2;
+ }
+ jump = jump->next;
+ }
+ if (put_label && put_label->addr == j) {
+ pool_size += sizeof(*pool);
+ put_label = put_label->next;
+ }
+ ins_size += sizeof_ins(ins);
+ }
+ }
+
+ /* emit trailing label */
+ if (label && label->size == j) {
+ label->size = ins_size;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!put_label);
+
+ /* pad code size to 8 bytes so is accessible with half word offsets */
+ /* the literal pool needs to be doubleword aligned */
+ pad_size = ((ins_size + 7UL) & ~7UL) - ins_size;
+ SLJIT_ASSERT(pad_size < 8UL);
+
+ /* allocate target buffer */
+ code = SLJIT_MALLOC_EXEC(ins_size + pad_size + pool_size,
+ compiler->exec_allocator_data);
+ PTR_FAIL_WITH_EXEC_IF(code);
+ code_ptr = code;
+ executable_offset = SLJIT_EXEC_OFFSET(code);
+
+ /* TODO(carenas): pool is optional, and the ABI recommends it to
+ * be created before the function code, instead of
+ * globally; if generated code is too big could
+ * need offsets bigger than 32bit words and asser()
+ */
+ pool = (sljit_uw *)((sljit_uw)code + ins_size + pad_size);
+ pool_ptr = pool;
+ const_ = (struct sljit_s390x_const *)compiler->consts;
+
+ /* update label addresses */
+ label = compiler->labels;
+ while (label) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(
+ (sljit_uw)code_ptr + label->size, executable_offset);
+ label = label->next;
+ }
+
+ /* reset jumps */
+ jump = compiler->jumps;
+ put_label = compiler->put_labels;
+
+ /* emit the code */
+ j = 0;
+ for (buf = compiler->buf; buf != NULL; buf = buf->next) {
+ sljit_uw len = buf->used_size / sizeof(sljit_ins);
+ sljit_ins *ibuf = (sljit_ins *)buf->memory;
+ for (i = 0; i < len; ++i, ++j) {
+ sljit_ins ins = ibuf[i];
+ if (ins & sljit_ins_const) {
+ /* clear the const tag */
+ ins &= ~sljit_ins_const;
+
+ /* update instruction with relative address of constant */
+ source = (sljit_uw)code_ptr;
+ offset = (sljit_uw)pool_ptr - source;
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1; /* halfword (not byte) offset */
+ SLJIT_ASSERT(is_s32(offset));
+ ins |= (sljit_ins)offset & 0xffffffff;
+
+ /* update address */
+ const_->const_.addr = (sljit_uw)pool_ptr;
+
+ /* store initial value into pool and update pool address */
+ *(pool_ptr++) = const_->init_value;
+
+ /* move to next constant */
+ const_ = (struct sljit_s390x_const *)const_->const_.next;
+ }
+ if (jump && jump->addr == j) {
+ sljit_sw target = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) {
+ jump->addr = (sljit_uw)pool_ptr;
+
+ /* load address into tmp1 */
+ source = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ offset = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1;
+ SLJIT_ASSERT(is_s32(offset));
+ encode_inst(&code_ptr,
+ lgrl(tmp1, offset & 0xffffffff));
+
+ /* store jump target into pool and update pool address */
+ *(pool_ptr++) = target;
+
+ /* branch to tmp1 */
+ sljit_ins op = (ins >> 32) & 0xf;
+ sljit_ins arg = (ins >> 36) & 0xf;
+ switch (op) {
+ case 4: /* brcl -> bcr */
+ ins = bcr(arg, tmp1);
+ break;
+ case 5: /* brasl -> basr */
+ ins = basr(arg, tmp1);
+ break;
+ default:
+ abort();
+ }
+ }
+ else {
+ jump->addr = (sljit_uw)code_ptr + 2;
+ source = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ offset = target - source;
+
+ /* offset must be halfword aligned */
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1;
+ SLJIT_ASSERT(is_s32(offset)); /* TODO(mundaym): handle arbitrary offsets */
+
+ /* patch jump target */
+ ins |= (sljit_ins)offset & 0xffffffff;
+ }
+ jump = jump->next;
+ }
+ if (put_label && put_label->addr == j) {
+ source = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)code_ptr;
+
+ /* store target into pool */
+ *pool_ptr = put_label->label->addr;
+ offset = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
+ pool_ptr++;
+
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1;
+ SLJIT_ASSERT(is_s32(offset));
+ ins |= (sljit_ins)offset & 0xffffffff;
+
+ put_label = put_label->next;
+ }
+ encode_inst(&code_ptr, ins);
+ }
+ }
+ SLJIT_ASSERT((sljit_u8 *)code + ins_size == code_ptr);
+ SLJIT_ASSERT((sljit_u8 *)pool + pool_size == (sljit_u8 *)pool_ptr);
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_offset = executable_offset;
+ compiler->executable_size = ins_size;
+ code = SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ code_ptr = SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
+ return code;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+ /* TODO(mundaym): implement all */
+ switch (feature_type) {
+ case SLJIT_HAS_CLZ:
+ return have_eimm() ? 1 : 0; /* FLOGR instruction */
+ case SLJIT_HAS_CMOV:
+ return have_lscond1() ? 1 : 0;
+ case SLJIT_HAS_FPU:
+ return 0;
+ }
+ return 0;
+}
+
+/* --------------------------------------------------------------------- */
+/* Entry, exit */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 args = get_arg_count(arg_types);
+ sljit_sw frame_size;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
+
+ /* saved registers go in callee allocated save area */
+ compiler->local_size = (local_size + 0xf) & ~0xf;
+ frame_size = compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE;
+
+ FAIL_IF(push_inst(compiler, stmg(r6, r15, r6 * sizeof(sljit_sw), r15))); /* save registers TODO(MGM): optimize */
+ if (frame_size != 0) {
+ if (is_s16(-frame_size))
+ FAIL_IF(push_inst(compiler, aghi(r15, -((sljit_s16)frame_size))));
+ else if (is_s32(-frame_size))
+ FAIL_IF(push_inst(compiler, agfi(r15, -((sljit_s32)frame_size))));
+ else {
+ FAIL_IF(push_load_imm_inst(compiler, tmp1, -frame_size));
+ FAIL_IF(push_inst(compiler, la(r15, 0, tmp1, r15)));
+ }
+ }
+
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S0), gpr(SLJIT_R0))));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S1), gpr(SLJIT_R1))));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S2), gpr(SLJIT_R2))));
+ SLJIT_ASSERT(args < 4);
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
+
+ /* TODO(mundaym): stack space for saved floating point registers */
+ compiler->local_size = (local_size + 0xf) & ~0xf;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_sw size;
+ sljit_gpr end;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ size = compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + (r6 * sizeof(sljit_sw));
+ if (!is_s20(size)) {
+ FAIL_IF(push_load_imm_inst(compiler, tmp1, compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE));
+ FAIL_IF(push_inst(compiler, la(r15, 0, tmp1, r15)));
+ size = r6 * sizeof(sljit_sw);
+ end = r14; /* r15 has been restored already */
+ }
+ else
+ end = r15;
+
+ FAIL_IF(push_inst(compiler, lmg(r6, end, size, r15))); /* restore registers TODO(MGM): optimize */
+ FAIL_IF(push_inst(compiler, br(r14))); /* return */
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+ sljit_gpr arg0 = gpr(SLJIT_R0);
+ sljit_gpr arg1 = gpr(SLJIT_R1);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op) | (op & SLJIT_I32_OP);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ /* TODO(mundaym): insert real breakpoint? */
+ case SLJIT_NOP:
+ return push_inst(compiler, 0x0700 /* 2-byte nop */);
+ case SLJIT_LMUL_UW:
+ FAIL_IF(push_inst(compiler, mlgr(arg0, arg0)));
+ break;
+ case SLJIT_LMUL_SW:
+ /* signed multiplication from: */
+ /* Hacker's Delight, Second Edition: Chapter 8-3. */
+ FAIL_IF(push_inst(compiler, srag(tmp0, arg0, 63, 0)));
+ FAIL_IF(push_inst(compiler, srag(tmp1, arg1, 63, 0)));
+ FAIL_IF(push_inst(compiler, ngr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, ngr(tmp1, arg0)));
+
+ /* unsigned multiplication */
+ FAIL_IF(push_inst(compiler, mlgr(arg0, arg0)));
+
+ FAIL_IF(push_inst(compiler, sgr(arg0, tmp0)));
+ FAIL_IF(push_inst(compiler, sgr(arg0, tmp1)));
+ break;
+ case SLJIT_DIV_U32:
+ case SLJIT_DIVMOD_U32:
+ FAIL_IF(push_inst(compiler, lhi(tmp0, 0)));
+ FAIL_IF(push_inst(compiler, lr(tmp1, arg0)));
+ FAIL_IF(push_inst(compiler, dlr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */
+ if (op == SLJIT_DIVMOD_U32)
+ return push_inst(compiler, lr(arg1, tmp0)); /* remainder */
+
+ return SLJIT_SUCCESS;
+ case SLJIT_DIV_S32:
+ case SLJIT_DIVMOD_S32:
+ FAIL_IF(push_inst(compiler, lhi(tmp0, 0)));
+ FAIL_IF(push_inst(compiler, lr(tmp1, arg0)));
+ FAIL_IF(push_inst(compiler, dr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */
+ if (op == SLJIT_DIVMOD_S32)
+ return push_inst(compiler, lr(arg1, tmp0)); /* remainder */
+
+ return SLJIT_SUCCESS;
+ case SLJIT_DIV_UW:
+ case SLJIT_DIVMOD_UW:
+ FAIL_IF(push_inst(compiler, lghi(tmp0, 0)));
+ FAIL_IF(push_inst(compiler, lgr(tmp1, arg0)));
+ FAIL_IF(push_inst(compiler, dlgr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */
+ if (op == SLJIT_DIVMOD_UW)
+ return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */
+
+ return SLJIT_SUCCESS;
+ case SLJIT_DIV_SW:
+ case SLJIT_DIVMOD_SW:
+ FAIL_IF(push_inst(compiler, lgr(tmp1, arg0)));
+ FAIL_IF(push_inst(compiler, dsgr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */
+ if (op == SLJIT_DIVMOD_SW)
+ return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */
+
+ return SLJIT_SUCCESS;
+ case SLJIT_ENDBR:
+ return SLJIT_SUCCESS;
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return SLJIT_SUCCESS;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ /* swap result registers */
+ FAIL_IF(push_inst(compiler, lgr(tmp0, arg0)));
+ FAIL_IF(push_inst(compiler, lgr(arg0, arg1)));
+ return push_inst(compiler, lgr(arg1, tmp0));
+}
+
+/* LEVAL will be defined later with different parameters as needed */
+#define WHEN2(cond, i1, i2) (cond) ? LEVAL(i1) : LEVAL(i2)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_ins ins;
+ struct addr mem;
+ sljit_gpr dst_r;
+ sljit_gpr src_r;
+ sljit_s32 opcode = GET_OPCODE(op);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if ((dst == SLJIT_UNUSED) && !HAS_FLAGS(op)) {
+ /* TODO(carenas): implement prefetch? */
+ return SLJIT_SUCCESS;
+ }
+ if (opcode >= SLJIT_MOV && opcode <= SLJIT_MOV_P) {
+ /* LOAD REGISTER */
+ if (FAST_IS_REG(dst) && FAST_IS_REG(src)) {
+ dst_r = gpr(dst);
+ src_r = gpr(src);
+ switch (opcode | (op & SLJIT_I32_OP)) {
+ /* 32-bit */
+ case SLJIT_MOV32_U8:
+ ins = llcr(dst_r, src_r);
+ break;
+ case SLJIT_MOV32_S8:
+ ins = lbr(dst_r, src_r);
+ break;
+ case SLJIT_MOV32_U16:
+ ins = llhr(dst_r, src_r);
+ break;
+ case SLJIT_MOV32_S16:
+ ins = lhr(dst_r, src_r);
+ break;
+ case SLJIT_MOV32:
+ ins = lr(dst_r, src_r);
+ break;
+ /* 64-bit */
+ case SLJIT_MOV_U8:
+ ins = llgcr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_S8:
+ ins = lgbr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_U16:
+ ins = llghr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_S16:
+ ins = lghr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_U32:
+ ins = llgfr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_S32:
+ ins = lgfr(dst_r, src_r);
+ break;
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ ins = lgr(dst_r, src_r);
+ break;
+ default:
+ ins = 0;
+ SLJIT_UNREACHABLE();
+ }
+ FAIL_IF(push_inst(compiler, ins));
+ if (HAS_FLAGS(op)) {
+ /* only handle zero flag */
+ SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK));
+ return push_store_zero_flag(compiler, op, dst_r);
+ }
+ return SLJIT_SUCCESS;
+ }
+ /* LOAD IMMEDIATE */
+ if (FAST_IS_REG(dst) && (src & SLJIT_IMM)) {
+ switch (opcode) {
+ case SLJIT_MOV_U8:
+ srcw = (sljit_sw)((sljit_u8)(srcw));
+ break;
+ case SLJIT_MOV_S8:
+ srcw = (sljit_sw)((sljit_s8)(srcw));
+ break;
+ case SLJIT_MOV_U16:
+ srcw = (sljit_sw)((sljit_u16)(srcw));
+ break;
+ case SLJIT_MOV_S16:
+ srcw = (sljit_sw)((sljit_s16)(srcw));
+ break;
+ case SLJIT_MOV_U32:
+ srcw = (sljit_sw)((sljit_u32)(srcw));
+ break;
+ case SLJIT_MOV_S32:
+ srcw = (sljit_sw)((sljit_s32)(srcw));
+ break;
+ }
+ return push_load_imm_inst(compiler, gpr(dst), srcw);
+ }
+ /* LOAD */
+ /* TODO(carenas): avoid reg being defined later */
+ #define LEVAL(i) EVAL(i, reg, mem)
+ if (FAST_IS_REG(dst) && (src & SLJIT_MEM)) {
+ sljit_gpr reg = gpr(dst);
+
+ FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));
+ /* TODO(carenas): convert all calls below to LEVAL */
+ switch (opcode | (op & SLJIT_I32_OP)) {
+ case SLJIT_MOV32_U8:
+ ins = llc(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV32_S8:
+ ins = lb(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV32_U16:
+ ins = llh(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV32_S16:
+ ins = WHEN2(is_u12(mem.offset), lh, lhy);
+ break;
+ case SLJIT_MOV32:
+ ins = WHEN2(is_u12(mem.offset), l, ly);
+ break;
+ case SLJIT_MOV_U8:
+ ins = LEVAL(llgc);
+ break;
+ case SLJIT_MOV_S8:
+ ins = lgb(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV_U16:
+ ins = LEVAL(llgh);
+ break;
+ case SLJIT_MOV_S16:
+ ins = lgh(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV_U32:
+ ins = LEVAL(llgf);
+ break;
+ case SLJIT_MOV_S32:
+ ins = lgf(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV_P:
+ case SLJIT_MOV:
+ ins = lg(reg, mem.offset, mem.index, mem.base);
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ FAIL_IF(push_inst(compiler, ins));
+ if (HAS_FLAGS(op)) {
+ /* only handle zero flag */
+ SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK));
+ return push_store_zero_flag(compiler, op, reg);
+ }
+ return SLJIT_SUCCESS;
+ }
+ /* STORE and STORE IMMEDIATE */
+ if ((dst & SLJIT_MEM)
+ && (FAST_IS_REG(src) || (src & SLJIT_IMM))) {
+ sljit_gpr reg = FAST_IS_REG(src) ? gpr(src) : tmp0;
+ if (src & SLJIT_IMM) {
+ /* TODO(mundaym): MOVE IMMEDIATE? */
+ FAIL_IF(push_load_imm_inst(compiler, reg, srcw));
+ }
+ struct addr mem;
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ switch (opcode) {
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ return push_inst(compiler,
+ WHEN2(is_u12(mem.offset), stc, stcy));
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ return push_inst(compiler,
+ WHEN2(is_u12(mem.offset), sth, sthy));
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ return push_inst(compiler,
+ WHEN2(is_u12(mem.offset), st, sty));
+ case SLJIT_MOV_P:
+ case SLJIT_MOV:
+ FAIL_IF(push_inst(compiler, LEVAL(stg)));
+ if (HAS_FLAGS(op)) {
+ /* only handle zero flag */
+ SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK));
+ return push_store_zero_flag(compiler, op, reg);
+ }
+ return SLJIT_SUCCESS;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ }
+ #undef LEVAL
+ /* MOVE CHARACTERS */
+ if ((dst & SLJIT_MEM) && (src & SLJIT_MEM)) {
+ struct addr mem;
+ FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));
+ switch (opcode) {
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ FAIL_IF(push_inst(compiler,
+ EVAL(llgc, tmp0, mem)));
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ return push_inst(compiler,
+ EVAL(stcy, tmp0, mem));
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ FAIL_IF(push_inst(compiler,
+ EVAL(llgh, tmp0, mem)));
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ return push_inst(compiler,
+ EVAL(sthy, tmp0, mem));
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ FAIL_IF(push_inst(compiler,
+ EVAL(ly, tmp0, mem)));
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ return push_inst(compiler,
+ EVAL(sty, tmp0, mem));
+ case SLJIT_MOV_P:
+ case SLJIT_MOV:
+ FAIL_IF(push_inst(compiler,
+ EVAL(lg, tmp0, mem)));
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ FAIL_IF(push_inst(compiler,
+ EVAL(stg, tmp0, mem)));
+ if (HAS_FLAGS(op)) {
+ /* only handle zero flag */
+ SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK));
+ return push_store_zero_flag(compiler, op, tmp0);
+ }
+ return SLJIT_SUCCESS;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ }
+ SLJIT_UNREACHABLE();
+ }
+
+ SLJIT_ASSERT((src & SLJIT_IMM) == 0); /* no immediates */
+
+ dst_r = SLOW_IS_REG(dst) ? gpr(REG_MASK & dst) : tmp0;
+ src_r = FAST_IS_REG(src) ? gpr(REG_MASK & src) : tmp0;
+ if (src & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, src_r, src, srcw, tmp1, src & SLJIT_I32_OP));
+
+ /* TODO(mundaym): optimize loads and stores */
+ switch (opcode | (op & SLJIT_I32_OP)) {
+ case SLJIT_NOT:
+ /* emulate ~x with x^-1 */
+ FAIL_IF(push_load_imm_inst(compiler, tmp1, -1));
+ if (src_r != dst_r)
+ FAIL_IF(push_inst(compiler, lgr(dst_r, src_r)));
+
+ FAIL_IF(push_inst(compiler, xgr(dst_r, tmp1)));
+ break;
+ case SLJIT_NOT32:
+ /* emulate ~x with x^-1 */
+ if (have_eimm())
+ FAIL_IF(push_inst(compiler, xilf(dst_r, -1)));
+ else {
+ FAIL_IF(push_load_imm_inst(compiler, tmp1, -1));
+ if (src_r != dst_r)
+ FAIL_IF(push_inst(compiler, lr(dst_r, src_r)));
+
+ FAIL_IF(push_inst(compiler, xr(dst_r, tmp1)));
+ }
+ break;
+ case SLJIT_NEG:
+ FAIL_IF(push_inst(compiler, lcgr(dst_r, src_r)));
+ break;
+ case SLJIT_NEG32:
+ FAIL_IF(push_inst(compiler, lcr(dst_r, src_r)));
+ break;
+ case SLJIT_CLZ:
+ if (have_eimm()) {
+ FAIL_IF(push_inst(compiler, flogr(tmp0, src_r))); /* clobbers tmp1 */
+ if (dst_r != tmp0)
+ FAIL_IF(push_inst(compiler, lgr(dst_r, tmp0)));
+ } else {
+ abort(); /* TODO(mundaym): no eimm (?) */
+ }
+ break;
+ case SLJIT_CLZ32:
+ if (have_eimm()) {
+ FAIL_IF(push_inst(compiler, sllg(tmp1, src_r, 32, 0)));
+ FAIL_IF(push_inst(compiler, iilf(tmp1, 0xffffffff)));
+ FAIL_IF(push_inst(compiler, flogr(tmp0, tmp1))); /* clobbers tmp1 */
+ if (dst_r != tmp0)
+ FAIL_IF(push_inst(compiler, lr(dst_r, tmp0)));
+ } else {
+ abort(); /* TODO(mundaym): no eimm (?) */
+ }
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+
+ /* write condition code to emulated flag register */
+ if (op & VARIABLE_FLAG_MASK)
+ FAIL_IF(push_inst(compiler, ipm(flag_r)));
+
+ /* write zero flag to emulated flag register */
+ if (op & SLJIT_SET_Z)
+ FAIL_IF(push_store_zero_flag(compiler, op, dst_r));
+
+ /* TODO(carenas): doesn't need FAIL_IF */
+ if ((dst != SLJIT_UNUSED) && (dst & SLJIT_MEM))
+ FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP));
+
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int is_commutative(sljit_s32 op)
+{
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ case SLJIT_MUL:
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return 1;
+ }
+ return 0;
+}
+
+static SLJIT_INLINE int is_shift(sljit_s32 op) {
+ sljit_s32 v = GET_OPCODE(op);
+ return (v == SLJIT_SHL || v == SLJIT_ASHR || v == SLJIT_LSHR) ? 1 : 0;
+}
+
+static SLJIT_INLINE int sets_signed_flag(sljit_s32 op)
+{
+ switch (GET_FLAG_TYPE(op)) {
+ case SLJIT_OVERFLOW:
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_LESS_EQUAL:
+ case SLJIT_SIG_GREATER:
+ case SLJIT_SIG_GREATER_EQUAL:
+ return 1;
+ }
+ return 0;
+}
+
+/* Report whether we have an instruction for:
+ op dst src imm
+ where dst and src are separate registers. */
+static int have_op_3_imm(sljit_s32 op, sljit_sw imm) {
+ return 0; /* TODO(mundaym): implement */
+}
+
+/* Report whether we have an instruction for:
+ op reg imm
+ where reg is both a source and the destination. */
+static int have_op_2_imm(sljit_s32 op, sljit_sw imm) {
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ case SLJIT_ADD32:
+ case SLJIT_ADD:
+ if (!HAS_FLAGS(op) || sets_signed_flag(op))
+ return have_eimm() ? is_s32(imm) : is_s16(imm);
+
+ return have_eimm() && is_u32(imm);
+ case SLJIT_MUL32:
+ case SLJIT_MUL:
+ /* TODO(mundaym): general extension check */
+ /* for ms{,g}fi */
+ if (op & VARIABLE_FLAG_MASK)
+ return 0;
+
+ return have_genext() && is_s16(imm);
+ case SLJIT_OR32:
+ case SLJIT_XOR32:
+ case SLJIT_AND32:
+ /* only use if have extended immediate facility */
+ /* this ensures flags are set correctly */
+ return have_eimm();
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ /* TODO(mundaym): make this more flexible */
+ /* avoid using immediate variations, flags */
+ /* won't be set correctly */
+ return 0;
+ case SLJIT_ADDC32:
+ case SLJIT_ADDC:
+ /* no ADD LOGICAL WITH CARRY IMMEDIATE */
+ return 0;
+ case SLJIT_SUB:
+ case SLJIT_SUB32:
+ case SLJIT_SUBC:
+ case SLJIT_SUBC32:
+ /* no SUBTRACT IMMEDIATE */
+ /* TODO(mundaym): SUBTRACT LOGICAL IMMEDIATE */
+ return 0;
+ }
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+ return SLJIT_SUCCESS;
+
+ sljit_gpr dst_r = SLOW_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+
+ if (is_commutative(op)) {
+ #define SWAP_ARGS \
+ do { \
+ sljit_s32 t = src1; \
+ sljit_sw tw = src1w; \
+ src1 = src2; \
+ src1w = src2w; \
+ src2 = t; \
+ src2w = tw; \
+ } while(0);
+
+ /* prefer immediate in src2 */
+ if (src1 & SLJIT_IMM) {
+ SWAP_ARGS
+ }
+
+ /* prefer to have src1 use same register as dst */
+ if (FAST_IS_REG(src2) && gpr(src2 & REG_MASK) == dst_r) {
+ SWAP_ARGS
+ }
+
+ /* prefer memory argument in src2 */
+ if (FAST_IS_REG(src2) && (src1 & SLJIT_MEM)) {
+ SWAP_ARGS
+ }
+ #undef SWAP_ARGS
+ }
+
+ /* src1 must be in a register */
+ sljit_gpr src1_r = FAST_IS_REG(src1) ? gpr(src1 & REG_MASK) : tmp0;
+ if (src1 & SLJIT_IMM)
+ FAIL_IF(push_load_imm_inst(compiler, src1_r, src1w));
+
+ if (src1 & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, src1_r, src1, src1w, tmp1, op & SLJIT_I32_OP));
+
+ /* emit comparison before subtract */
+ if (GET_OPCODE(op) == SLJIT_SUB && (op & VARIABLE_FLAG_MASK)) {
+ sljit_sw cmp = 0;
+ switch (GET_FLAG_TYPE(op)) {
+ case SLJIT_LESS:
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_EQUAL:
+ cmp = 1; /* unsigned */
+ break;
+ case SLJIT_EQUAL:
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_LESS_EQUAL:
+ case SLJIT_SIG_GREATER:
+ case SLJIT_SIG_GREATER_EQUAL:
+ cmp = -1; /* signed */
+ break;
+ }
+ if (cmp) {
+ /* clear flags - no need to generate now */
+ op &= ~VARIABLE_FLAG_MASK;
+ sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1;
+ if (src2 & SLJIT_IMM) {
+ #define LEVAL(i) i(src1_r, src2w)
+ if (cmp > 0 && is_u32(src2w)) {
+ /* unsigned */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, clfi, clgfi)));
+ }
+ else if (cmp < 0 && is_s16(src2w)) {
+ /* signed */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, chi, cghi)));
+ }
+ else if (cmp < 0 && is_s32(src2w)) {
+ /* signed */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, cfi, cgfi)));
+ }
+ #undef LEVAL
+ #define LEVAL(i) i(src1_r, src2_r)
+ else {
+ FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w));
+ if (cmp > 0) {
+ /* unsigned */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, clr, clgr)));
+ }
+ if (cmp < 0) {
+ /* signed */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, cr, cgr)));
+ }
+ }
+ }
+ else {
+ if (src2 & SLJIT_MEM) {
+ /* TODO(mundaym): comparisons with memory */
+ /* load src2 into register */
+ FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ }
+ if (cmp > 0) {
+ /* unsigned */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, clr, clgr)));
+ }
+ if (cmp < 0) {
+ /* signed */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, cr, cgr)));
+ }
+ #undef LEVAL
+ }
+ FAIL_IF(push_inst(compiler, ipm(flag_r)));
+ }
+ }
+
+ if (!HAS_FLAGS(op) && dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ /* need to specify signed or logical operation */
+ int signed_flags = sets_signed_flag(op);
+
+ if (is_shift(op)) {
+ /* handle shifts first, they have more constraints than other operations */
+ sljit_sw d = 0;
+ sljit_gpr b = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : r0;
+ if (src2 & SLJIT_IMM)
+ d = src2w & ((op & SLJIT_I32_OP) ? 31 : 63);
+
+ if (src2 & SLJIT_MEM) {
+ /* shift amount (b) cannot be in r0 (i.e. tmp0) */
+ FAIL_IF(load_word(compiler, tmp1, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ b = tmp1;
+ }
+ /* src1 and dst share the same register in the base 32-bit ISA */
+ /* TODO(mundaym): not needed when distinct-operand facility is available */
+ int workaround_alias = op & SLJIT_I32_OP && src1_r != dst_r;
+ if (workaround_alias) {
+ /* put src1 into tmp0 so we can overwrite it */
+ FAIL_IF(push_inst(compiler, lr(tmp0, src1_r)));
+ src1_r = tmp0;
+ }
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ case SLJIT_SHL:
+ FAIL_IF(push_inst(compiler, sllg(dst_r, src1_r, d, b)));
+ break;
+ case SLJIT_SHL32:
+ FAIL_IF(push_inst(compiler, sll(src1_r, d, b)));
+ break;
+ case SLJIT_LSHR:
+ FAIL_IF(push_inst(compiler, srlg(dst_r, src1_r, d, b)));
+ break;
+ case SLJIT_LSHR32:
+ FAIL_IF(push_inst(compiler, srl(src1_r, d, b)));
+ break;
+ case SLJIT_ASHR:
+ FAIL_IF(push_inst(compiler, srag(dst_r, src1_r, d, b)));
+ break;
+ case SLJIT_ASHR32:
+ FAIL_IF(push_inst(compiler, sra(src1_r, d, b)));
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ if (workaround_alias && dst_r != src1_r)
+ FAIL_IF(push_inst(compiler, lr(dst_r, src1_r)));
+
+ }
+ else if ((GET_OPCODE(op) == SLJIT_MUL) && HAS_FLAGS(op)) {
+ /* multiply instructions do not generally set flags so we need to manually */
+ /* detect overflow conditions */
+ /* TODO(mundaym): 64-bit overflow */
+ SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_MUL_OVERFLOW ||
+ GET_FLAG_TYPE(op) == SLJIT_MUL_NOT_OVERFLOW);
+ sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1;
+ if (src2 & SLJIT_IMM) {
+ /* load src2 into register */
+ FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w));
+ }
+ if (src2 & SLJIT_MEM) {
+ /* load src2 into register */
+ FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ }
+ if (have_misc2()) {
+ #define LEVAL(i) i(dst_r, src1_r, src2_r)
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, msrkc, msgrkc)));
+ #undef LEVAL
+ }
+ else if (op & SLJIT_I32_OP) {
+ op &= ~VARIABLE_FLAG_MASK;
+ FAIL_IF(push_inst(compiler, lgfr(tmp0, src1_r)));
+ FAIL_IF(push_inst(compiler, msgfr(tmp0, src2_r)));
+ if (dst_r != tmp0) {
+ FAIL_IF(push_inst(compiler, lr(dst_r, tmp0)));
+ }
+ FAIL_IF(push_inst(compiler, aih(tmp0, 1)));
+ FAIL_IF(push_inst(compiler, nihf(tmp0, ~1U)));
+ FAIL_IF(push_inst(compiler, ipm(flag_r)));
+ FAIL_IF(push_inst(compiler, oilh(flag_r, 0x2000)));
+ }
+ else
+ return SLJIT_ERR_UNSUPPORTED;
+
+ }
+ else if ((GET_OPCODE(op) == SLJIT_SUB) && (op & SLJIT_SET_Z) && !signed_flags) {
+ /* subtract logical instructions do not set the right flags unfortunately */
+ /* instead, negate src2 and issue an add logical */
+ /* TODO(mundaym): distinct operand facility where needed */
+ if (src1_r != dst_r && src1_r != tmp0) {
+ #define LEVAL(i) i(tmp0, src1_r)
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, lr, lgr)));
+ src1_r = tmp0;
+ #undef LEVAL
+ }
+ sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1;
+ if (src2 & SLJIT_IMM) {
+ /* load src2 into register */
+ FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w));
+ }
+ if (src2 & SLJIT_MEM) {
+ /* load src2 into register */
+ FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ }
+ if (op & SLJIT_I32_OP) {
+ FAIL_IF(push_inst(compiler, lcr(tmp1, src2_r)));
+ FAIL_IF(push_inst(compiler, alr(src1_r, tmp1)));
+ if (src1_r != dst_r)
+ FAIL_IF(push_inst(compiler, lr(dst_r, src1_r)));
+ }
+ else {
+ FAIL_IF(push_inst(compiler, lcgr(tmp1, src2_r)));
+ FAIL_IF(push_inst(compiler, algr(src1_r, tmp1)));
+ if (src1_r != dst_r)
+ FAIL_IF(push_inst(compiler, lgr(dst_r, src1_r)));
+ }
+ }
+ else if ((src2 & SLJIT_IMM) && (src1_r == dst_r) && have_op_2_imm(op, src2w)) {
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ #define LEVAL(i) i(dst_r, src2w)
+ case SLJIT_ADD:
+ if (!HAS_FLAGS(op) || signed_flags) {
+ FAIL_IF(push_inst(compiler,
+ WHEN2(is_s16(src2w), aghi, agfi)));
+ }
+ else
+ FAIL_IF(push_inst(compiler, LEVAL(algfi)));
+
+ break;
+ case SLJIT_ADD32:
+ if (!HAS_FLAGS(op) || signed_flags)
+ FAIL_IF(push_inst(compiler,
+ WHEN2(is_s16(src2w), ahi, afi)));
+ else
+ FAIL_IF(push_inst(compiler, LEVAL(alfi)));
+
+ break;
+ #undef LEVAL /* TODO(carenas): move down and refactor? */
+ case SLJIT_MUL:
+ FAIL_IF(push_inst(compiler, mhi(dst_r, src2w)));
+ break;
+ case SLJIT_MUL32:
+ FAIL_IF(push_inst(compiler, mghi(dst_r, src2w)));
+ break;
+ case SLJIT_OR32:
+ FAIL_IF(push_inst(compiler, oilf(dst_r, src2w)));
+ break;
+ case SLJIT_XOR32:
+ FAIL_IF(push_inst(compiler, xilf(dst_r, src2w)));
+ break;
+ case SLJIT_AND32:
+ FAIL_IF(push_inst(compiler, nilf(dst_r, src2w)));
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ }
+ else if ((src2 & SLJIT_IMM) && have_op_3_imm(op, src2w)) {
+ abort(); /* TODO(mundaym): implement */
+ }
+ else if ((src2 & SLJIT_MEM) && (dst_r == src1_r)) {
+ /* most 32-bit instructions can only handle 12-bit immediate offsets */
+ int need_u12 = !have_ldisp() &&
+ (op & SLJIT_I32_OP) &&
+ (GET_OPCODE(op) != SLJIT_ADDC) &&
+ (GET_OPCODE(op) != SLJIT_SUBC);
+ struct addr mem;
+ if (need_u12)
+ FAIL_IF(make_addr_bx(compiler, &mem, src2, src2w, tmp1));
+ else
+ FAIL_IF(make_addr_bxy(compiler, &mem, src2, src2w, tmp1));
+
+ int can_u12 = is_u12(mem.offset) ? 1 : 0;
+ sljit_ins ins = 0;
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ /* 64-bit ops */
+ #define LEVAL(i) EVAL(i, dst_r, mem)
+ case SLJIT_ADD:
+ ins = WHEN2(signed_flags, ag, alg);
+ break;
+ case SLJIT_SUB:
+ ins = WHEN2(signed_flags, sg, slg);
+ break;
+ case SLJIT_ADDC:
+ ins = LEVAL(alcg);
+ break;
+ case SLJIT_SUBC:
+ ins = LEVAL(slbg);
+ break;
+ case SLJIT_MUL:
+ ins = LEVAL(msg);
+ break;
+ case SLJIT_OR:
+ ins = LEVAL(og);
+ break;
+ case SLJIT_XOR:
+ ins = LEVAL(xg);
+ break;
+ case SLJIT_AND:
+ ins = LEVAL(ng);
+ break;
+ /* 32-bit ops */
+ case SLJIT_ADD32:
+ if (signed_flags)
+ ins = WHEN2(can_u12, a, ay);
+ else
+ ins = WHEN2(can_u12, al, aly);
+ break;
+ case SLJIT_SUB32:
+ if (signed_flags)
+ ins = WHEN2(can_u12, s, sy);
+ else
+ ins = WHEN2(can_u12, sl, sly);
+ break;
+ case SLJIT_ADDC32:
+ ins = LEVAL(alc);
+ break;
+ case SLJIT_SUBC32:
+ ins = LEVAL(slb);
+ break;
+ case SLJIT_MUL32:
+ ins = WHEN2(can_u12, ms, msy);
+ break;
+ case SLJIT_OR32:
+ ins = WHEN2(can_u12, o, oy);
+ break;
+ case SLJIT_XOR32:
+ ins = WHEN2(can_u12, x, xy);
+ break;
+ case SLJIT_AND32:
+ ins = WHEN2(can_u12, n, ny);
+ break;
+ #undef LEVAL
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ FAIL_IF(push_inst(compiler, ins));
+ }
+ else {
+ sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1;
+ if (src2 & SLJIT_IMM) {
+ /* load src2 into register */
+ FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w));
+ }
+ if (src2 & SLJIT_MEM) {
+ /* load src2 into register */
+ FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ }
+ /* TODO(mundaym): distinct operand facility where needed */
+ #define LEVAL(i) i(tmp0, src1_r)
+ if (src1_r != dst_r && src1_r != tmp0) {
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, lr, lgr)));
+ src1_r = tmp0;
+ }
+ #undef LEVAL
+ sljit_ins ins = 0;
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ #define LEVAL(i) i(src1_r, src2_r)
+ /* 64-bit ops */
+ case SLJIT_ADD:
+ ins = WHEN2(signed_flags, agr, algr);
+ break;
+ case SLJIT_SUB:
+ ins = WHEN2(signed_flags, sgr, slgr);
+ break;
+ case SLJIT_ADDC:
+ ins = LEVAL(alcgr);
+ break;
+ case SLJIT_SUBC:
+ ins = LEVAL(slbgr);
+ break;
+ case SLJIT_MUL:
+ ins = LEVAL(msgr);
+ break;
+ case SLJIT_AND:
+ ins = LEVAL(ngr);
+ break;
+ case SLJIT_OR:
+ ins = LEVAL(ogr);
+ break;
+ case SLJIT_XOR:
+ ins = LEVAL(xgr);
+ break;
+ /* 32-bit ops */
+ case SLJIT_ADD32:
+ ins = WHEN2(signed_flags, ar, alr);
+ break;
+ case SLJIT_SUB32:
+ ins = WHEN2(signed_flags, sr, slr);
+ break;
+ case SLJIT_ADDC32:
+ ins = LEVAL(alcr);
+ break;
+ case SLJIT_SUBC32:
+ ins = LEVAL(slbr);
+ break;
+ case SLJIT_MUL32:
+ ins = LEVAL(msr);
+ break;
+ case SLJIT_AND32:
+ ins = LEVAL(nr);
+ break;
+ case SLJIT_OR32:
+ ins = LEVAL(or);
+ break;
+ case SLJIT_XOR32:
+ ins = LEVAL(xr);
+ break;
+ #undef LEVAL
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ FAIL_IF(push_inst(compiler, ins));
+ #define LEVAL(i) i(dst_r, src1_r)
+ if (src1_r != dst_r)
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, lr, lgr)));
+ #undef LEVAL
+ }
+
+ /* write condition code to emulated flag register */
+ if (op & VARIABLE_FLAG_MASK)
+ FAIL_IF(push_inst(compiler, ipm(flag_r)));
+
+ /* write zero flag to emulated flag register */
+ if (op & SLJIT_SET_Z)
+ FAIL_IF(push_store_zero_flag(compiler, op, dst_r));
+
+ /* finally write the result to memory if required */
+ if (dst & SLJIT_MEM) {
+ SLJIT_ASSERT(dst_r != tmp1);
+ /* TODO(carenas): s/FAIL_IF/ return */
+ FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(
+ struct sljit_compiler *compiler,
+ sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_gpr src_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;
+ if (src & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, tmp1, src, srcw, tmp1, 0));
+
+ return push_inst(compiler, br(src_r));
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ /* TODO(carenas): implement? */
+ return SLJIT_SUCCESS;
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+ /* TODO(carenas): implement */
+ return SLJIT_SUCCESS;
+ default:
+ /* TODO(carenas): probably should not success by default */
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return gpr(reg);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ abort();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ sljit_ins ins = 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ memcpy((sljit_u8 *)&ins + sizeof(ins) - size, instruction, size);
+ return push_inst(compiler, ins);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ abort();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ CHECK_ERROR();
+ abort();
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, lgr(gpr(dst), fast_link_r));
+
+ /* memory */
+ return store_word(compiler, fast_link_r, dst, dstw, tmp1, 0);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ sljit_u8 mask = ((type & 0xff) < SLJIT_JUMP) ? get_cc(type & 0xff) : 0xf;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ /* reload condition code */
+ if (mask != 0xf)
+ PTR_FAIL_IF(push_load_cc(compiler, type & 0xff));
+
+ /* record jump */
+ struct sljit_jump *jump = (struct sljit_jump *)
+ ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ jump->addr = compiler->size;
+
+ /* emit jump instruction */
+ type &= 0xff;
+ if (type >= SLJIT_FAST_CALL)
+ PTR_FAIL_IF(push_inst(compiler, brasl(type == SLJIT_FAST_CALL ? fast_link_r : link_r, 0)));
+ else
+ PTR_FAIL_IF(push_inst(compiler, brcl(mask, 0)));
+
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 arg_types)
+{
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+
+ return sljit_emit_jump(compiler, type);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (src & SLJIT_IMM) {
+ SLJIT_ASSERT(!(srcw & 1)); /* target address must be even */
+ FAIL_IF(push_load_imm_inst(compiler, src_r, srcw));
+ }
+ else if (src & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, src_r, src, srcw, tmp1, 0 /* 64-bit */));
+
+ /* emit jump instruction */
+ if (type >= SLJIT_FAST_CALL)
+ return push_inst(compiler, basr(type == SLJIT_FAST_CALL ? fast_link_r : link_r, src_r));
+
+ return push_inst(compiler, br(src_r));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 arg_types,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+
+ return sljit_emit_ijump(compiler, type, src, srcw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 type)
+{
+ sljit_u8 mask = get_cc(type & 0xff);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
+
+ sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+ sljit_gpr loc_r = tmp1;
+ switch (GET_OPCODE(op)) {
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ /* dst is also source operand */
+ if (dst & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP));
+
+ break;
+ case SLJIT_MOV:
+ case (SLJIT_MOV32 & ~SLJIT_I32_OP):
+ /* can write straight into destination */
+ loc_r = dst_r;
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+
+ if (mask != 0xf)
+ FAIL_IF(push_load_cc(compiler, type & 0xff));
+
+ /* TODO(mundaym): fold into cmov helper function? */
+ #define LEVAL(i) i(loc_r, 1, mask)
+ if (have_lscond2()) {
+ FAIL_IF(push_load_imm_inst(compiler, loc_r, 0));
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, lochi, locghi)));
+ } else {
+ /* TODO(mundaym): no load/store-on-condition 2 facility (ipm? branch-and-set?) */
+ abort();
+ }
+ #undef LEVAL
+
+ /* apply bitwise op and set condition codes */
+ switch (GET_OPCODE(op)) {
+ #define LEVAL(i) i(dst_r, loc_r)
+ case SLJIT_AND:
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, nr, ngr)));
+ break;
+ case SLJIT_OR:
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, or, ogr)));
+ break;
+ case SLJIT_XOR:
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, xr, xgr)));
+ break;
+ #undef LEVAL
+ }
+
+ /* set zero flag if needed */
+ if (op & SLJIT_SET_Z)
+ FAIL_IF(push_store_zero_flag(compiler, op, dst_r));
+
+ /* store result to memory if required */
+ /* TODO(carenas): s/FAIL_IF/ return */
+ if (dst & SLJIT_MEM)
+ FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 dst_reg,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8 mask = get_cc(type & 0xff);
+ sljit_gpr dst_r = gpr(dst_reg & ~SLJIT_I32_OP);
+ sljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+ if (mask != 0xf)
+ FAIL_IF(push_load_cc(compiler, type & 0xff));
+
+ if (src & SLJIT_IMM) {
+ /* TODO(mundaym): fast path with lscond2 */
+ FAIL_IF(push_load_imm_inst(compiler, src_r, srcw));
+ }
+
+ #define LEVAL(i) i(dst_r, src_r, mask)
+ if (have_lscond1())
+ return push_inst(compiler,
+ WHEN2(dst_reg & SLJIT_I32_OP, locr, locgr));
+
+ #undef LEVAL
+
+ /* TODO(mundaym): implement */
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+/* On s390x we build a literal pool to hold constants. This has two main
+ advantages:
+
+ 1. we only need one instruction in the instruction stream (LGRL)
+ 2. we can store 64 bit addresses and use 32 bit offsets
+
+ To retrofit the extra information needed to build the literal pool we
+ add a new sljit_s390x_const struct that contains the initial value but
+ can still be cast to a sljit_const. */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ struct sljit_s390x_const *const_;
+ sljit_gpr dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+
+ const_ = (struct sljit_s390x_const*)ensure_abuf(compiler,
+ sizeof(struct sljit_s390x_const));
+ PTR_FAIL_IF(!const_);
+ set_const((struct sljit_const*)const_, compiler);
+ const_->init_value = init_value;
+
+ dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+ if (have_genext())
+ PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | lgrl(dst_r, 0)));
+ else {
+ PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | larl(tmp1, 0)));
+ PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
+ }
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, 0 /* always 64-bit */));
+
+ return (struct sljit_const*)const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ /* Update the constant pool. */
+ sljit_uw *ptr = (sljit_uw *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
+ *ptr = new_target;
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
+ SLJIT_CACHE_FLUSH(ptr, ptr + 1);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label *sljit_emit_put_label(
+ struct sljit_compiler *compiler,
+ sljit_s32 dst, sljit_sw dstw)
+{
+ struct sljit_put_label *put_label;
+ sljit_gpr dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
+ PTR_FAIL_IF(!put_label);
+ set_put_label(put_label, compiler, 0);
+
+ dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+
+ if (have_genext())
+ PTR_FAIL_IF(push_inst(compiler, lgrl(dst_r, 0)));
+ else {
+ PTR_FAIL_IF(push_inst(compiler, larl(tmp1, 0)));
+ PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
+ }
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, 0));
+
+ return put_label;
+}
+
+/* TODO(carenas): EVAL probably should move up or be refactored */
+#undef WHEN2
+#undef EVAL
+
+#undef tmp1
+#undef tmp0
+
+/* TODO(carenas): undef other macros that spill like is_u12? */
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
index 8079fad8df..e5167f02ba 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
@@ -266,21 +266,18 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));
inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins *)addr;
-
- SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));
- inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
- inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c
index bfa4ecede2..544d80d028 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c
@@ -311,7 +311,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
CHECK_PTR(check_sljit_generate_code(compiler));
reverse_buf(compiler);
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -437,6 +437,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
return code;
}
@@ -451,6 +452,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
return 1;
#endif
+ case SLJIT_HAS_ZERO_REGISTER:
+ return 1;
+
#if (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)
case SLJIT_HAS_CMOV:
return 1;
@@ -872,6 +876,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
#else
#error "Implementation required"
#endif
+ case SLJIT_ENDBR:
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return SLJIT_SUCCESS;
}
return SLJIT_SUCCESS;
@@ -888,9 +895,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
ADJUST_LOCAL_OFFSET(dst, dstw);
ADJUST_LOCAL_OFFSET(src, srcw);
- if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
- return SLJIT_SUCCESS;
-
op = GET_OPCODE(op);
switch (op) {
case SLJIT_MOV:
@@ -971,6 +975,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
return SLJIT_SUCCESS;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ if (FAST_IS_REG(src))
+ FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
+ else
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
+
+ FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
{
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
@@ -1215,25 +1246,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
ADJUST_LOCAL_OFFSET(dst, dstw);
if (FAST_IS_REG(dst))
- return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst));
+ return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), UNMOVABLE_INS);
/* Memory. */
- return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
- else
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
-
- FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
- return push_inst(compiler, NOP, UNMOVABLE_INS);
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw));
+ compiler->delay_slot = UNMOVABLE_INS;
+ return SLJIT_SUCCESS;
}
/* --------------------------------------------------------------------- */
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c b/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c
deleted file mode 100644
index dd82ebae6a..0000000000
--- a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c
+++ /dev/null
@@ -1,10159 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* This code is owned by Tilera Corporation, and distributed as part
- of multiple projects. In sljit, the code is under BSD licence. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#define BFD_RELOC(x) R_##x
-
-/* Special registers. */
-#define TREG_LR 55
-#define TREG_SN 56
-#define TREG_ZERO 63
-
-/* Canonical name of each register. */
-const char *const tilegx_register_names[] =
-{
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
- "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
- "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
- "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr",
- "sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero"
-};
-
-enum
-{
- R_NONE = 0,
- R_TILEGX_NONE = 0,
- R_TILEGX_64 = 1,
- R_TILEGX_32 = 2,
- R_TILEGX_16 = 3,
- R_TILEGX_8 = 4,
- R_TILEGX_64_PCREL = 5,
- R_TILEGX_32_PCREL = 6,
- R_TILEGX_16_PCREL = 7,
- R_TILEGX_8_PCREL = 8,
- R_TILEGX_HW0 = 9,
- R_TILEGX_HW1 = 10,
- R_TILEGX_HW2 = 11,
- R_TILEGX_HW3 = 12,
- R_TILEGX_HW0_LAST = 13,
- R_TILEGX_HW1_LAST = 14,
- R_TILEGX_HW2_LAST = 15,
- R_TILEGX_COPY = 16,
- R_TILEGX_GLOB_DAT = 17,
- R_TILEGX_JMP_SLOT = 18,
- R_TILEGX_RELATIVE = 19,
- R_TILEGX_BROFF_X1 = 20,
- R_TILEGX_JUMPOFF_X1 = 21,
- R_TILEGX_JUMPOFF_X1_PLT = 22,
- R_TILEGX_IMM8_X0 = 23,
- R_TILEGX_IMM8_Y0 = 24,
- R_TILEGX_IMM8_X1 = 25,
- R_TILEGX_IMM8_Y1 = 26,
- R_TILEGX_DEST_IMM8_X1 = 27,
- R_TILEGX_MT_IMM14_X1 = 28,
- R_TILEGX_MF_IMM14_X1 = 29,
- R_TILEGX_MMSTART_X0 = 30,
- R_TILEGX_MMEND_X0 = 31,
- R_TILEGX_SHAMT_X0 = 32,
- R_TILEGX_SHAMT_X1 = 33,
- R_TILEGX_SHAMT_Y0 = 34,
- R_TILEGX_SHAMT_Y1 = 35,
- R_TILEGX_IMM16_X0_HW0 = 36,
- R_TILEGX_IMM16_X1_HW0 = 37,
- R_TILEGX_IMM16_X0_HW1 = 38,
- R_TILEGX_IMM16_X1_HW1 = 39,
- R_TILEGX_IMM16_X0_HW2 = 40,
- R_TILEGX_IMM16_X1_HW2 = 41,
- R_TILEGX_IMM16_X0_HW3 = 42,
- R_TILEGX_IMM16_X1_HW3 = 43,
- R_TILEGX_IMM16_X0_HW0_LAST = 44,
- R_TILEGX_IMM16_X1_HW0_LAST = 45,
- R_TILEGX_IMM16_X0_HW1_LAST = 46,
- R_TILEGX_IMM16_X1_HW1_LAST = 47,
- R_TILEGX_IMM16_X0_HW2_LAST = 48,
- R_TILEGX_IMM16_X1_HW2_LAST = 49,
- R_TILEGX_IMM16_X0_HW0_PCREL = 50,
- R_TILEGX_IMM16_X1_HW0_PCREL = 51,
- R_TILEGX_IMM16_X0_HW1_PCREL = 52,
- R_TILEGX_IMM16_X1_HW1_PCREL = 53,
- R_TILEGX_IMM16_X0_HW2_PCREL = 54,
- R_TILEGX_IMM16_X1_HW2_PCREL = 55,
- R_TILEGX_IMM16_X0_HW3_PCREL = 56,
- R_TILEGX_IMM16_X1_HW3_PCREL = 57,
- R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58,
- R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59,
- R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60,
- R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61,
- R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62,
- R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63,
- R_TILEGX_IMM16_X0_HW0_GOT = 64,
- R_TILEGX_IMM16_X1_HW0_GOT = 65,
-
- R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66,
- R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67,
- R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68,
- R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69,
- R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70,
- R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71,
-
- R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72,
- R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73,
- R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74,
- R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75,
- R_TILEGX_IMM16_X0_HW0_TLS_GD = 78,
- R_TILEGX_IMM16_X1_HW0_TLS_GD = 79,
- R_TILEGX_IMM16_X0_HW0_TLS_LE = 80,
- R_TILEGX_IMM16_X1_HW0_TLS_LE = 81,
- R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82,
- R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83,
- R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84,
- R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85,
- R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86,
- R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87,
- R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88,
- R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89,
- R_TILEGX_IMM16_X0_HW0_TLS_IE = 92,
- R_TILEGX_IMM16_X1_HW0_TLS_IE = 93,
-
- R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94,
- R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95,
- R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96,
- R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97,
- R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98,
- R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99,
-
- R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100,
- R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101,
- R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102,
- R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103,
- R_TILEGX_TLS_DTPMOD64 = 106,
- R_TILEGX_TLS_DTPOFF64 = 107,
- R_TILEGX_TLS_TPOFF64 = 108,
- R_TILEGX_TLS_DTPMOD32 = 109,
- R_TILEGX_TLS_DTPOFF32 = 110,
- R_TILEGX_TLS_TPOFF32 = 111,
- R_TILEGX_TLS_GD_CALL = 112,
- R_TILEGX_IMM8_X0_TLS_GD_ADD = 113,
- R_TILEGX_IMM8_X1_TLS_GD_ADD = 114,
- R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115,
- R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116,
- R_TILEGX_TLS_IE_LOAD = 117,
- R_TILEGX_IMM8_X0_TLS_ADD = 118,
- R_TILEGX_IMM8_X1_TLS_ADD = 119,
- R_TILEGX_IMM8_Y0_TLS_ADD = 120,
- R_TILEGX_IMM8_Y1_TLS_ADD = 121,
- R_TILEGX_GNU_VTINHERIT = 128,
- R_TILEGX_GNU_VTENTRY = 129,
- R_TILEGX_IRELATIVE = 130,
- R_TILEGX_NUM = 131
-};
-
-typedef enum
-{
- TILEGX_PIPELINE_X0,
- TILEGX_PIPELINE_X1,
- TILEGX_PIPELINE_Y0,
- TILEGX_PIPELINE_Y1,
- TILEGX_PIPELINE_Y2,
-} tilegx_pipeline;
-
-typedef unsigned long long tilegx_bundle_bits;
-
-/* These are the bits that determine if a bundle is in the X encoding. */
-#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
-
-enum
-{
- /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
- TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
-
- /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
- TILEGX_NUM_PIPELINE_ENCODINGS = 5,
-
- /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
- TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
-
- /* Instructions take this many bytes. */
- TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
-
- /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
- TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
-
- /* Bundles should be aligned modulo this number of bytes. */
- TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
- (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
-
- /* Number of registers (some are magic, such as network I/O). */
- TILEGX_NUM_REGISTERS = 64,
-};
-
-/* Make a few "tile_" variables to simplify common code between
- architectures. */
-
-typedef tilegx_bundle_bits tile_bundle_bits;
-#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES
-#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
-#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
- TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
-
-/* 64-bit pattern for a { bpt ; nop } bundle. */
-#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
-
-typedef enum
-{
- TILEGX_OP_TYPE_REGISTER,
- TILEGX_OP_TYPE_IMMEDIATE,
- TILEGX_OP_TYPE_ADDRESS,
- TILEGX_OP_TYPE_SPR
-} tilegx_operand_type;
-
-struct tilegx_operand
-{
- /* Is this operand a register, immediate or address? */
- tilegx_operand_type type;
-
- /* The default relocation type for this operand. */
- signed int default_reloc : 16;
-
- /* How many bits is this value? (used for range checking) */
- unsigned int num_bits : 5;
-
- /* Is the value signed? (used for range checking) */
- unsigned int is_signed : 1;
-
- /* Is this operand a source register? */
- unsigned int is_src_reg : 1;
-
- /* Is this operand written? (i.e. is it a destination register) */
- unsigned int is_dest_reg : 1;
-
- /* Is this operand PC-relative? */
- unsigned int is_pc_relative : 1;
-
- /* By how many bits do we right shift the value before inserting? */
- unsigned int rightshift : 2;
-
- /* Return the bits for this operand to be ORed into an existing bundle. */
- tilegx_bundle_bits (*insert) (int op);
-
- /* Extract this operand and return it. */
- unsigned int (*extract) (tilegx_bundle_bits bundle);
-};
-
-typedef enum
-{
- TILEGX_OPC_BPT,
- TILEGX_OPC_INFO,
- TILEGX_OPC_INFOL,
- TILEGX_OPC_LD4S_TLS,
- TILEGX_OPC_LD_TLS,
- TILEGX_OPC_MOVE,
- TILEGX_OPC_MOVEI,
- TILEGX_OPC_MOVELI,
- TILEGX_OPC_PREFETCH,
- TILEGX_OPC_PREFETCH_ADD_L1,
- TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L2,
- TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_L1,
- TILEGX_OPC_PREFETCH_L1_FAULT,
- TILEGX_OPC_PREFETCH_L2,
- TILEGX_OPC_PREFETCH_L2_FAULT,
- TILEGX_OPC_PREFETCH_L3,
- TILEGX_OPC_PREFETCH_L3_FAULT,
- TILEGX_OPC_RAISE,
- TILEGX_OPC_ADD,
- TILEGX_OPC_ADDI,
- TILEGX_OPC_ADDLI,
- TILEGX_OPC_ADDX,
- TILEGX_OPC_ADDXI,
- TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXSC,
- TILEGX_OPC_AND,
- TILEGX_OPC_ANDI,
- TILEGX_OPC_BEQZ,
- TILEGX_OPC_BEQZT,
- TILEGX_OPC_BFEXTS,
- TILEGX_OPC_BFEXTU,
- TILEGX_OPC_BFINS,
- TILEGX_OPC_BGEZ,
- TILEGX_OPC_BGEZT,
- TILEGX_OPC_BGTZ,
- TILEGX_OPC_BGTZT,
- TILEGX_OPC_BLBC,
- TILEGX_OPC_BLBCT,
- TILEGX_OPC_BLBS,
- TILEGX_OPC_BLBST,
- TILEGX_OPC_BLEZ,
- TILEGX_OPC_BLEZT,
- TILEGX_OPC_BLTZ,
- TILEGX_OPC_BLTZT,
- TILEGX_OPC_BNEZ,
- TILEGX_OPC_BNEZT,
- TILEGX_OPC_CLZ,
- TILEGX_OPC_CMOVEQZ,
- TILEGX_OPC_CMOVNEZ,
- TILEGX_OPC_CMPEQ,
- TILEGX_OPC_CMPEQI,
- TILEGX_OPC_CMPEXCH,
- TILEGX_OPC_CMPEXCH4,
- TILEGX_OPC_CMPLES,
- TILEGX_OPC_CMPLEU,
- TILEGX_OPC_CMPLTS,
- TILEGX_OPC_CMPLTSI,
- TILEGX_OPC_CMPLTU,
- TILEGX_OPC_CMPLTUI,
- TILEGX_OPC_CMPNE,
- TILEGX_OPC_CMUL,
- TILEGX_OPC_CMULA,
- TILEGX_OPC_CMULAF,
- TILEGX_OPC_CMULF,
- TILEGX_OPC_CMULFR,
- TILEGX_OPC_CMULH,
- TILEGX_OPC_CMULHR,
- TILEGX_OPC_CRC32_32,
- TILEGX_OPC_CRC32_8,
- TILEGX_OPC_CTZ,
- TILEGX_OPC_DBLALIGN,
- TILEGX_OPC_DBLALIGN2,
- TILEGX_OPC_DBLALIGN4,
- TILEGX_OPC_DBLALIGN6,
- TILEGX_OPC_DRAIN,
- TILEGX_OPC_DTLBPR,
- TILEGX_OPC_EXCH,
- TILEGX_OPC_EXCH4,
- TILEGX_OPC_FDOUBLE_ADD_FLAGS,
- TILEGX_OPC_FDOUBLE_ADDSUB,
- TILEGX_OPC_FDOUBLE_MUL_FLAGS,
- TILEGX_OPC_FDOUBLE_PACK1,
- TILEGX_OPC_FDOUBLE_PACK2,
- TILEGX_OPC_FDOUBLE_SUB_FLAGS,
- TILEGX_OPC_FDOUBLE_UNPACK_MAX,
- TILEGX_OPC_FDOUBLE_UNPACK_MIN,
- TILEGX_OPC_FETCHADD,
- TILEGX_OPC_FETCHADD4,
- TILEGX_OPC_FETCHADDGEZ,
- TILEGX_OPC_FETCHADDGEZ4,
- TILEGX_OPC_FETCHAND,
- TILEGX_OPC_FETCHAND4,
- TILEGX_OPC_FETCHOR,
- TILEGX_OPC_FETCHOR4,
- TILEGX_OPC_FINV,
- TILEGX_OPC_FLUSH,
- TILEGX_OPC_FLUSHWB,
- TILEGX_OPC_FNOP,
- TILEGX_OPC_FSINGLE_ADD1,
- TILEGX_OPC_FSINGLE_ADDSUB2,
- TILEGX_OPC_FSINGLE_MUL1,
- TILEGX_OPC_FSINGLE_MUL2,
- TILEGX_OPC_FSINGLE_PACK1,
- TILEGX_OPC_FSINGLE_PACK2,
- TILEGX_OPC_FSINGLE_SUB1,
- TILEGX_OPC_ICOH,
- TILEGX_OPC_ILL,
- TILEGX_OPC_INV,
- TILEGX_OPC_IRET,
- TILEGX_OPC_J,
- TILEGX_OPC_JAL,
- TILEGX_OPC_JALR,
- TILEGX_OPC_JALRP,
- TILEGX_OPC_JR,
- TILEGX_OPC_JRP,
- TILEGX_OPC_LD,
- TILEGX_OPC_LD1S,
- TILEGX_OPC_LD1S_ADD,
- TILEGX_OPC_LD1U,
- TILEGX_OPC_LD1U_ADD,
- TILEGX_OPC_LD2S,
- TILEGX_OPC_LD2S_ADD,
- TILEGX_OPC_LD2U,
- TILEGX_OPC_LD2U_ADD,
- TILEGX_OPC_LD4S,
- TILEGX_OPC_LD4S_ADD,
- TILEGX_OPC_LD4U,
- TILEGX_OPC_LD4U_ADD,
- TILEGX_OPC_LD_ADD,
- TILEGX_OPC_LDNA,
- TILEGX_OPC_LDNA_ADD,
- TILEGX_OPC_LDNT,
- TILEGX_OPC_LDNT1S,
- TILEGX_OPC_LDNT1S_ADD,
- TILEGX_OPC_LDNT1U,
- TILEGX_OPC_LDNT1U_ADD,
- TILEGX_OPC_LDNT2S,
- TILEGX_OPC_LDNT2S_ADD,
- TILEGX_OPC_LDNT2U,
- TILEGX_OPC_LDNT2U_ADD,
- TILEGX_OPC_LDNT4S,
- TILEGX_OPC_LDNT4S_ADD,
- TILEGX_OPC_LDNT4U,
- TILEGX_OPC_LDNT4U_ADD,
- TILEGX_OPC_LDNT_ADD,
- TILEGX_OPC_LNK,
- TILEGX_OPC_MF,
- TILEGX_OPC_MFSPR,
- TILEGX_OPC_MM,
- TILEGX_OPC_MNZ,
- TILEGX_OPC_MTSPR,
- TILEGX_OPC_MUL_HS_HS,
- TILEGX_OPC_MUL_HS_HU,
- TILEGX_OPC_MUL_HS_LS,
- TILEGX_OPC_MUL_HS_LU,
- TILEGX_OPC_MUL_HU_HU,
- TILEGX_OPC_MUL_HU_LS,
- TILEGX_OPC_MUL_HU_LU,
- TILEGX_OPC_MUL_LS_LS,
- TILEGX_OPC_MUL_LS_LU,
- TILEGX_OPC_MUL_LU_LU,
- TILEGX_OPC_MULA_HS_HS,
- TILEGX_OPC_MULA_HS_HU,
- TILEGX_OPC_MULA_HS_LS,
- TILEGX_OPC_MULA_HS_LU,
- TILEGX_OPC_MULA_HU_HU,
- TILEGX_OPC_MULA_HU_LS,
- TILEGX_OPC_MULA_HU_LU,
- TILEGX_OPC_MULA_LS_LS,
- TILEGX_OPC_MULA_LS_LU,
- TILEGX_OPC_MULA_LU_LU,
- TILEGX_OPC_MULAX,
- TILEGX_OPC_MULX,
- TILEGX_OPC_MZ,
- TILEGX_OPC_NAP,
- TILEGX_OPC_NOP,
- TILEGX_OPC_NOR,
- TILEGX_OPC_OR,
- TILEGX_OPC_ORI,
- TILEGX_OPC_PCNT,
- TILEGX_OPC_REVBITS,
- TILEGX_OPC_REVBYTES,
- TILEGX_OPC_ROTL,
- TILEGX_OPC_ROTLI,
- TILEGX_OPC_SHL,
- TILEGX_OPC_SHL16INSLI,
- TILEGX_OPC_SHL1ADD,
- TILEGX_OPC_SHL1ADDX,
- TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADDX,
- TILEGX_OPC_SHL3ADD,
- TILEGX_OPC_SHL3ADDX,
- TILEGX_OPC_SHLI,
- TILEGX_OPC_SHLX,
- TILEGX_OPC_SHLXI,
- TILEGX_OPC_SHRS,
- TILEGX_OPC_SHRSI,
- TILEGX_OPC_SHRU,
- TILEGX_OPC_SHRUI,
- TILEGX_OPC_SHRUX,
- TILEGX_OPC_SHRUXI,
- TILEGX_OPC_SHUFFLEBYTES,
- TILEGX_OPC_ST,
- TILEGX_OPC_ST1,
- TILEGX_OPC_ST1_ADD,
- TILEGX_OPC_ST2,
- TILEGX_OPC_ST2_ADD,
- TILEGX_OPC_ST4,
- TILEGX_OPC_ST4_ADD,
- TILEGX_OPC_ST_ADD,
- TILEGX_OPC_STNT,
- TILEGX_OPC_STNT1,
- TILEGX_OPC_STNT1_ADD,
- TILEGX_OPC_STNT2,
- TILEGX_OPC_STNT2_ADD,
- TILEGX_OPC_STNT4,
- TILEGX_OPC_STNT4_ADD,
- TILEGX_OPC_STNT_ADD,
- TILEGX_OPC_SUB,
- TILEGX_OPC_SUBX,
- TILEGX_OPC_SUBXSC,
- TILEGX_OPC_SWINT0,
- TILEGX_OPC_SWINT1,
- TILEGX_OPC_SWINT2,
- TILEGX_OPC_SWINT3,
- TILEGX_OPC_TBLIDXB0,
- TILEGX_OPC_TBLIDXB1,
- TILEGX_OPC_TBLIDXB2,
- TILEGX_OPC_TBLIDXB3,
- TILEGX_OPC_V1ADD,
- TILEGX_OPC_V1ADDI,
- TILEGX_OPC_V1ADDUC,
- TILEGX_OPC_V1ADIFFU,
- TILEGX_OPC_V1AVGU,
- TILEGX_OPC_V1CMPEQ,
- TILEGX_OPC_V1CMPEQI,
- TILEGX_OPC_V1CMPLES,
- TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLTS,
- TILEGX_OPC_V1CMPLTSI,
- TILEGX_OPC_V1CMPLTU,
- TILEGX_OPC_V1CMPLTUI,
- TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1DDOTPU,
- TILEGX_OPC_V1DDOTPUA,
- TILEGX_OPC_V1DDOTPUS,
- TILEGX_OPC_V1DDOTPUSA,
- TILEGX_OPC_V1DOTP,
- TILEGX_OPC_V1DOTPA,
- TILEGX_OPC_V1DOTPU,
- TILEGX_OPC_V1DOTPUA,
- TILEGX_OPC_V1DOTPUS,
- TILEGX_OPC_V1DOTPUSA,
- TILEGX_OPC_V1INT_H,
- TILEGX_OPC_V1INT_L,
- TILEGX_OPC_V1MAXU,
- TILEGX_OPC_V1MAXUI,
- TILEGX_OPC_V1MINU,
- TILEGX_OPC_V1MINUI,
- TILEGX_OPC_V1MNZ,
- TILEGX_OPC_V1MULTU,
- TILEGX_OPC_V1MULU,
- TILEGX_OPC_V1MULUS,
- TILEGX_OPC_V1MZ,
- TILEGX_OPC_V1SADAU,
- TILEGX_OPC_V1SADU,
- TILEGX_OPC_V1SHL,
- TILEGX_OPC_V1SHLI,
- TILEGX_OPC_V1SHRS,
- TILEGX_OPC_V1SHRSI,
- TILEGX_OPC_V1SHRU,
- TILEGX_OPC_V1SHRUI,
- TILEGX_OPC_V1SUB,
- TILEGX_OPC_V1SUBUC,
- TILEGX_OPC_V2ADD,
- TILEGX_OPC_V2ADDI,
- TILEGX_OPC_V2ADDSC,
- TILEGX_OPC_V2ADIFFS,
- TILEGX_OPC_V2AVGS,
- TILEGX_OPC_V2CMPEQ,
- TILEGX_OPC_V2CMPEQI,
- TILEGX_OPC_V2CMPLES,
- TILEGX_OPC_V2CMPLEU,
- TILEGX_OPC_V2CMPLTS,
- TILEGX_OPC_V2CMPLTSI,
- TILEGX_OPC_V2CMPLTU,
- TILEGX_OPC_V2CMPLTUI,
- TILEGX_OPC_V2CMPNE,
- TILEGX_OPC_V2DOTP,
- TILEGX_OPC_V2DOTPA,
- TILEGX_OPC_V2INT_H,
- TILEGX_OPC_V2INT_L,
- TILEGX_OPC_V2MAXS,
- TILEGX_OPC_V2MAXSI,
- TILEGX_OPC_V2MINS,
- TILEGX_OPC_V2MINSI,
- TILEGX_OPC_V2MNZ,
- TILEGX_OPC_V2MULFSC,
- TILEGX_OPC_V2MULS,
- TILEGX_OPC_V2MULTS,
- TILEGX_OPC_V2MZ,
- TILEGX_OPC_V2PACKH,
- TILEGX_OPC_V2PACKL,
- TILEGX_OPC_V2PACKUC,
- TILEGX_OPC_V2SADAS,
- TILEGX_OPC_V2SADAU,
- TILEGX_OPC_V2SADS,
- TILEGX_OPC_V2SADU,
- TILEGX_OPC_V2SHL,
- TILEGX_OPC_V2SHLI,
- TILEGX_OPC_V2SHLSC,
- TILEGX_OPC_V2SHRS,
- TILEGX_OPC_V2SHRSI,
- TILEGX_OPC_V2SHRU,
- TILEGX_OPC_V2SHRUI,
- TILEGX_OPC_V2SUB,
- TILEGX_OPC_V2SUBSC,
- TILEGX_OPC_V4ADD,
- TILEGX_OPC_V4ADDSC,
- TILEGX_OPC_V4INT_H,
- TILEGX_OPC_V4INT_L,
- TILEGX_OPC_V4PACKSC,
- TILEGX_OPC_V4SHL,
- TILEGX_OPC_V4SHLSC,
- TILEGX_OPC_V4SHRS,
- TILEGX_OPC_V4SHRU,
- TILEGX_OPC_V4SUB,
- TILEGX_OPC_V4SUBSC,
- TILEGX_OPC_WH64,
- TILEGX_OPC_XOR,
- TILEGX_OPC_XORI,
- TILEGX_OPC_NONE
-} tilegx_mnemonic;
-
-enum
-{
- TILEGX_MAX_OPERANDS = 4 /* bfexts */
-};
-
-struct tilegx_opcode
-{
- /* The opcode mnemonic, e.g. "add" */
- const char *name;
-
- /* The enum value for this mnemonic. */
- tilegx_mnemonic mnemonic;
-
- /* A bit mask of which of the five pipes this instruction
- is compatible with:
- X0 0x01
- X1 0x02
- Y0 0x04
- Y1 0x08
- Y2 0x10 */
- unsigned char pipes;
-
- /* How many operands are there? */
- unsigned char num_operands;
-
- /* Which register does this write implicitly, or TREG_ZERO if none? */
- unsigned char implicitly_written_register;
-
- /* Can this be bundled with other instructions (almost always true). */
- unsigned char can_bundle;
-
- /* The description of the operands. Each of these is an
- * index into the tilegx_operands[] table. */
- unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];
-
- /* A mask of which bits have predefined values for each pipeline.
- * This is useful for disassembly. */
- tilegx_bundle_bits fixed_bit_masks[TILEGX_NUM_PIPELINE_ENCODINGS];
-
- /* For each bit set in fixed_bit_masks, what the value is for this
- * instruction. */
- tilegx_bundle_bits fixed_bit_values[TILEGX_NUM_PIPELINE_ENCODINGS];
-};
-
-/* Used for non-textual disassembly into structs. */
-struct tilegx_decoded_instruction
-{
- const struct tilegx_opcode *opcode;
- const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];
- long long operand_values[TILEGX_MAX_OPERANDS];
-};
-
-enum
-{
- ADDI_IMM8_OPCODE_X0 = 1,
- ADDI_IMM8_OPCODE_X1 = 1,
- ADDI_OPCODE_Y0 = 0,
- ADDI_OPCODE_Y1 = 1,
- ADDLI_OPCODE_X0 = 1,
- ADDLI_OPCODE_X1 = 0,
- ADDXI_IMM8_OPCODE_X0 = 2,
- ADDXI_IMM8_OPCODE_X1 = 2,
- ADDXI_OPCODE_Y0 = 1,
- ADDXI_OPCODE_Y1 = 2,
- ADDXLI_OPCODE_X0 = 2,
- ADDXLI_OPCODE_X1 = 1,
- ADDXSC_RRR_0_OPCODE_X0 = 1,
- ADDXSC_RRR_0_OPCODE_X1 = 1,
- ADDX_RRR_0_OPCODE_X0 = 2,
- ADDX_RRR_0_OPCODE_X1 = 2,
- ADDX_RRR_0_OPCODE_Y0 = 0,
- ADDX_SPECIAL_0_OPCODE_Y1 = 0,
- ADD_RRR_0_OPCODE_X0 = 3,
- ADD_RRR_0_OPCODE_X1 = 3,
- ADD_RRR_0_OPCODE_Y0 = 1,
- ADD_SPECIAL_0_OPCODE_Y1 = 1,
- ANDI_IMM8_OPCODE_X0 = 3,
- ANDI_IMM8_OPCODE_X1 = 3,
- ANDI_OPCODE_Y0 = 2,
- ANDI_OPCODE_Y1 = 3,
- AND_RRR_0_OPCODE_X0 = 4,
- AND_RRR_0_OPCODE_X1 = 4,
- AND_RRR_5_OPCODE_Y0 = 0,
- AND_RRR_5_OPCODE_Y1 = 0,
- BEQZT_BRANCH_OPCODE_X1 = 16,
- BEQZ_BRANCH_OPCODE_X1 = 17,
- BFEXTS_BF_OPCODE_X0 = 4,
- BFEXTU_BF_OPCODE_X0 = 5,
- BFINS_BF_OPCODE_X0 = 6,
- BF_OPCODE_X0 = 3,
- BGEZT_BRANCH_OPCODE_X1 = 18,
- BGEZ_BRANCH_OPCODE_X1 = 19,
- BGTZT_BRANCH_OPCODE_X1 = 20,
- BGTZ_BRANCH_OPCODE_X1 = 21,
- BLBCT_BRANCH_OPCODE_X1 = 22,
- BLBC_BRANCH_OPCODE_X1 = 23,
- BLBST_BRANCH_OPCODE_X1 = 24,
- BLBS_BRANCH_OPCODE_X1 = 25,
- BLEZT_BRANCH_OPCODE_X1 = 26,
- BLEZ_BRANCH_OPCODE_X1 = 27,
- BLTZT_BRANCH_OPCODE_X1 = 28,
- BLTZ_BRANCH_OPCODE_X1 = 29,
- BNEZT_BRANCH_OPCODE_X1 = 30,
- BNEZ_BRANCH_OPCODE_X1 = 31,
- BRANCH_OPCODE_X1 = 2,
- CMOVEQZ_RRR_0_OPCODE_X0 = 5,
- CMOVEQZ_RRR_4_OPCODE_Y0 = 0,
- CMOVNEZ_RRR_0_OPCODE_X0 = 6,
- CMOVNEZ_RRR_4_OPCODE_Y0 = 1,
- CMPEQI_IMM8_OPCODE_X0 = 4,
- CMPEQI_IMM8_OPCODE_X1 = 4,
- CMPEQI_OPCODE_Y0 = 3,
- CMPEQI_OPCODE_Y1 = 4,
- CMPEQ_RRR_0_OPCODE_X0 = 7,
- CMPEQ_RRR_0_OPCODE_X1 = 5,
- CMPEQ_RRR_3_OPCODE_Y0 = 0,
- CMPEQ_RRR_3_OPCODE_Y1 = 2,
- CMPEXCH4_RRR_0_OPCODE_X1 = 6,
- CMPEXCH_RRR_0_OPCODE_X1 = 7,
- CMPLES_RRR_0_OPCODE_X0 = 8,
- CMPLES_RRR_0_OPCODE_X1 = 8,
- CMPLES_RRR_2_OPCODE_Y0 = 0,
- CMPLES_RRR_2_OPCODE_Y1 = 0,
- CMPLEU_RRR_0_OPCODE_X0 = 9,
- CMPLEU_RRR_0_OPCODE_X1 = 9,
- CMPLEU_RRR_2_OPCODE_Y0 = 1,
- CMPLEU_RRR_2_OPCODE_Y1 = 1,
- CMPLTSI_IMM8_OPCODE_X0 = 5,
- CMPLTSI_IMM8_OPCODE_X1 = 5,
- CMPLTSI_OPCODE_Y0 = 4,
- CMPLTSI_OPCODE_Y1 = 5,
- CMPLTS_RRR_0_OPCODE_X0 = 10,
- CMPLTS_RRR_0_OPCODE_X1 = 10,
- CMPLTS_RRR_2_OPCODE_Y0 = 2,
- CMPLTS_RRR_2_OPCODE_Y1 = 2,
- CMPLTUI_IMM8_OPCODE_X0 = 6,
- CMPLTUI_IMM8_OPCODE_X1 = 6,
- CMPLTU_RRR_0_OPCODE_X0 = 11,
- CMPLTU_RRR_0_OPCODE_X1 = 11,
- CMPLTU_RRR_2_OPCODE_Y0 = 3,
- CMPLTU_RRR_2_OPCODE_Y1 = 3,
- CMPNE_RRR_0_OPCODE_X0 = 12,
- CMPNE_RRR_0_OPCODE_X1 = 12,
- CMPNE_RRR_3_OPCODE_Y0 = 1,
- CMPNE_RRR_3_OPCODE_Y1 = 3,
- CMULAF_RRR_0_OPCODE_X0 = 13,
- CMULA_RRR_0_OPCODE_X0 = 14,
- CMULFR_RRR_0_OPCODE_X0 = 15,
- CMULF_RRR_0_OPCODE_X0 = 16,
- CMULHR_RRR_0_OPCODE_X0 = 17,
- CMULH_RRR_0_OPCODE_X0 = 18,
- CMUL_RRR_0_OPCODE_X0 = 19,
- CNTLZ_UNARY_OPCODE_X0 = 1,
- CNTLZ_UNARY_OPCODE_Y0 = 1,
- CNTTZ_UNARY_OPCODE_X0 = 2,
- CNTTZ_UNARY_OPCODE_Y0 = 2,
- CRC32_32_RRR_0_OPCODE_X0 = 20,
- CRC32_8_RRR_0_OPCODE_X0 = 21,
- DBLALIGN2_RRR_0_OPCODE_X0 = 22,
- DBLALIGN2_RRR_0_OPCODE_X1 = 13,
- DBLALIGN4_RRR_0_OPCODE_X0 = 23,
- DBLALIGN4_RRR_0_OPCODE_X1 = 14,
- DBLALIGN6_RRR_0_OPCODE_X0 = 24,
- DBLALIGN6_RRR_0_OPCODE_X1 = 15,
- DBLALIGN_RRR_0_OPCODE_X0 = 25,
- DRAIN_UNARY_OPCODE_X1 = 1,
- DTLBPR_UNARY_OPCODE_X1 = 2,
- EXCH4_RRR_0_OPCODE_X1 = 16,
- EXCH_RRR_0_OPCODE_X1 = 17,
- FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26,
- FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27,
- FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28,
- FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29,
- FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30,
- FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31,
- FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32,
- FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33,
- FETCHADD4_RRR_0_OPCODE_X1 = 18,
- FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19,
- FETCHADDGEZ_RRR_0_OPCODE_X1 = 20,
- FETCHADD_RRR_0_OPCODE_X1 = 21,
- FETCHAND4_RRR_0_OPCODE_X1 = 22,
- FETCHAND_RRR_0_OPCODE_X1 = 23,
- FETCHOR4_RRR_0_OPCODE_X1 = 24,
- FETCHOR_RRR_0_OPCODE_X1 = 25,
- FINV_UNARY_OPCODE_X1 = 3,
- FLUSHWB_UNARY_OPCODE_X1 = 4,
- FLUSH_UNARY_OPCODE_X1 = 5,
- FNOP_UNARY_OPCODE_X0 = 3,
- FNOP_UNARY_OPCODE_X1 = 6,
- FNOP_UNARY_OPCODE_Y0 = 3,
- FNOP_UNARY_OPCODE_Y1 = 8,
- FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34,
- FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35,
- FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36,
- FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37,
- FSINGLE_PACK1_UNARY_OPCODE_X0 = 4,
- FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4,
- FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38,
- FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39,
- ICOH_UNARY_OPCODE_X1 = 7,
- ILL_UNARY_OPCODE_X1 = 8,
- ILL_UNARY_OPCODE_Y1 = 9,
- IMM8_OPCODE_X0 = 4,
- IMM8_OPCODE_X1 = 3,
- INV_UNARY_OPCODE_X1 = 9,
- IRET_UNARY_OPCODE_X1 = 10,
- JALRP_UNARY_OPCODE_X1 = 11,
- JALRP_UNARY_OPCODE_Y1 = 10,
- JALR_UNARY_OPCODE_X1 = 12,
- JALR_UNARY_OPCODE_Y1 = 11,
- JAL_JUMP_OPCODE_X1 = 0,
- JRP_UNARY_OPCODE_X1 = 13,
- JRP_UNARY_OPCODE_Y1 = 12,
- JR_UNARY_OPCODE_X1 = 14,
- JR_UNARY_OPCODE_Y1 = 13,
- JUMP_OPCODE_X1 = 4,
- J_JUMP_OPCODE_X1 = 1,
- LD1S_ADD_IMM8_OPCODE_X1 = 7,
- LD1S_OPCODE_Y2 = 0,
- LD1S_UNARY_OPCODE_X1 = 15,
- LD1U_ADD_IMM8_OPCODE_X1 = 8,
- LD1U_OPCODE_Y2 = 1,
- LD1U_UNARY_OPCODE_X1 = 16,
- LD2S_ADD_IMM8_OPCODE_X1 = 9,
- LD2S_OPCODE_Y2 = 2,
- LD2S_UNARY_OPCODE_X1 = 17,
- LD2U_ADD_IMM8_OPCODE_X1 = 10,
- LD2U_OPCODE_Y2 = 3,
- LD2U_UNARY_OPCODE_X1 = 18,
- LD4S_ADD_IMM8_OPCODE_X1 = 11,
- LD4S_OPCODE_Y2 = 1,
- LD4S_UNARY_OPCODE_X1 = 19,
- LD4U_ADD_IMM8_OPCODE_X1 = 12,
- LD4U_OPCODE_Y2 = 2,
- LD4U_UNARY_OPCODE_X1 = 20,
- LDNA_UNARY_OPCODE_X1 = 21,
- LDNT1S_ADD_IMM8_OPCODE_X1 = 13,
- LDNT1S_UNARY_OPCODE_X1 = 22,
- LDNT1U_ADD_IMM8_OPCODE_X1 = 14,
- LDNT1U_UNARY_OPCODE_X1 = 23,
- LDNT2S_ADD_IMM8_OPCODE_X1 = 15,
- LDNT2S_UNARY_OPCODE_X1 = 24,
- LDNT2U_ADD_IMM8_OPCODE_X1 = 16,
- LDNT2U_UNARY_OPCODE_X1 = 25,
- LDNT4S_ADD_IMM8_OPCODE_X1 = 17,
- LDNT4S_UNARY_OPCODE_X1 = 26,
- LDNT4U_ADD_IMM8_OPCODE_X1 = 18,
- LDNT4U_UNARY_OPCODE_X1 = 27,
- LDNT_ADD_IMM8_OPCODE_X1 = 19,
- LDNT_UNARY_OPCODE_X1 = 28,
- LD_ADD_IMM8_OPCODE_X1 = 20,
- LD_OPCODE_Y2 = 3,
- LD_UNARY_OPCODE_X1 = 29,
- LNK_UNARY_OPCODE_X1 = 30,
- LNK_UNARY_OPCODE_Y1 = 14,
- LWNA_ADD_IMM8_OPCODE_X1 = 21,
- MFSPR_IMM8_OPCODE_X1 = 22,
- MF_UNARY_OPCODE_X1 = 31,
- MM_BF_OPCODE_X0 = 7,
- MNZ_RRR_0_OPCODE_X0 = 40,
- MNZ_RRR_0_OPCODE_X1 = 26,
- MNZ_RRR_4_OPCODE_Y0 = 2,
- MNZ_RRR_4_OPCODE_Y1 = 2,
- MODE_OPCODE_YA2 = 1,
- MODE_OPCODE_YB2 = 2,
- MODE_OPCODE_YC2 = 3,
- MTSPR_IMM8_OPCODE_X1 = 23,
- MULAX_RRR_0_OPCODE_X0 = 41,
- MULAX_RRR_3_OPCODE_Y0 = 2,
- MULA_HS_HS_RRR_0_OPCODE_X0 = 42,
- MULA_HS_HS_RRR_9_OPCODE_Y0 = 0,
- MULA_HS_HU_RRR_0_OPCODE_X0 = 43,
- MULA_HS_LS_RRR_0_OPCODE_X0 = 44,
- MULA_HS_LU_RRR_0_OPCODE_X0 = 45,
- MULA_HU_HU_RRR_0_OPCODE_X0 = 46,
- MULA_HU_HU_RRR_9_OPCODE_Y0 = 1,
- MULA_HU_LS_RRR_0_OPCODE_X0 = 47,
- MULA_HU_LU_RRR_0_OPCODE_X0 = 48,
- MULA_LS_LS_RRR_0_OPCODE_X0 = 49,
- MULA_LS_LS_RRR_9_OPCODE_Y0 = 2,
- MULA_LS_LU_RRR_0_OPCODE_X0 = 50,
- MULA_LU_LU_RRR_0_OPCODE_X0 = 51,
- MULA_LU_LU_RRR_9_OPCODE_Y0 = 3,
- MULX_RRR_0_OPCODE_X0 = 52,
- MULX_RRR_3_OPCODE_Y0 = 3,
- MUL_HS_HS_RRR_0_OPCODE_X0 = 53,
- MUL_HS_HS_RRR_8_OPCODE_Y0 = 0,
- MUL_HS_HU_RRR_0_OPCODE_X0 = 54,
- MUL_HS_LS_RRR_0_OPCODE_X0 = 55,
- MUL_HS_LU_RRR_0_OPCODE_X0 = 56,
- MUL_HU_HU_RRR_0_OPCODE_X0 = 57,
- MUL_HU_HU_RRR_8_OPCODE_Y0 = 1,
- MUL_HU_LS_RRR_0_OPCODE_X0 = 58,
- MUL_HU_LU_RRR_0_OPCODE_X0 = 59,
- MUL_LS_LS_RRR_0_OPCODE_X0 = 60,
- MUL_LS_LS_RRR_8_OPCODE_Y0 = 2,
- MUL_LS_LU_RRR_0_OPCODE_X0 = 61,
- MUL_LU_LU_RRR_0_OPCODE_X0 = 62,
- MUL_LU_LU_RRR_8_OPCODE_Y0 = 3,
- MZ_RRR_0_OPCODE_X0 = 63,
- MZ_RRR_0_OPCODE_X1 = 27,
- MZ_RRR_4_OPCODE_Y0 = 3,
- MZ_RRR_4_OPCODE_Y1 = 3,
- NAP_UNARY_OPCODE_X1 = 32,
- NOP_UNARY_OPCODE_X0 = 5,
- NOP_UNARY_OPCODE_X1 = 33,
- NOP_UNARY_OPCODE_Y0 = 5,
- NOP_UNARY_OPCODE_Y1 = 15,
- NOR_RRR_0_OPCODE_X0 = 64,
- NOR_RRR_0_OPCODE_X1 = 28,
- NOR_RRR_5_OPCODE_Y0 = 1,
- NOR_RRR_5_OPCODE_Y1 = 1,
- ORI_IMM8_OPCODE_X0 = 7,
- ORI_IMM8_OPCODE_X1 = 24,
- OR_RRR_0_OPCODE_X0 = 65,
- OR_RRR_0_OPCODE_X1 = 29,
- OR_RRR_5_OPCODE_Y0 = 2,
- OR_RRR_5_OPCODE_Y1 = 2,
- PCNT_UNARY_OPCODE_X0 = 6,
- PCNT_UNARY_OPCODE_Y0 = 6,
- REVBITS_UNARY_OPCODE_X0 = 7,
- REVBITS_UNARY_OPCODE_Y0 = 7,
- REVBYTES_UNARY_OPCODE_X0 = 8,
- REVBYTES_UNARY_OPCODE_Y0 = 8,
- ROTLI_SHIFT_OPCODE_X0 = 1,
- ROTLI_SHIFT_OPCODE_X1 = 1,
- ROTLI_SHIFT_OPCODE_Y0 = 0,
- ROTLI_SHIFT_OPCODE_Y1 = 0,
- ROTL_RRR_0_OPCODE_X0 = 66,
- ROTL_RRR_0_OPCODE_X1 = 30,
- ROTL_RRR_6_OPCODE_Y0 = 0,
- ROTL_RRR_6_OPCODE_Y1 = 0,
- RRR_0_OPCODE_X0 = 5,
- RRR_0_OPCODE_X1 = 5,
- RRR_0_OPCODE_Y0 = 5,
- RRR_0_OPCODE_Y1 = 6,
- RRR_1_OPCODE_Y0 = 6,
- RRR_1_OPCODE_Y1 = 7,
- RRR_2_OPCODE_Y0 = 7,
- RRR_2_OPCODE_Y1 = 8,
- RRR_3_OPCODE_Y0 = 8,
- RRR_3_OPCODE_Y1 = 9,
- RRR_4_OPCODE_Y0 = 9,
- RRR_4_OPCODE_Y1 = 10,
- RRR_5_OPCODE_Y0 = 10,
- RRR_5_OPCODE_Y1 = 11,
- RRR_6_OPCODE_Y0 = 11,
- RRR_6_OPCODE_Y1 = 12,
- RRR_7_OPCODE_Y0 = 12,
- RRR_7_OPCODE_Y1 = 13,
- RRR_8_OPCODE_Y0 = 13,
- RRR_9_OPCODE_Y0 = 14,
- SHIFT_OPCODE_X0 = 6,
- SHIFT_OPCODE_X1 = 6,
- SHIFT_OPCODE_Y0 = 15,
- SHIFT_OPCODE_Y1 = 14,
- SHL16INSLI_OPCODE_X0 = 7,
- SHL16INSLI_OPCODE_X1 = 7,
- SHL1ADDX_RRR_0_OPCODE_X0 = 67,
- SHL1ADDX_RRR_0_OPCODE_X1 = 31,
- SHL1ADDX_RRR_7_OPCODE_Y0 = 1,
- SHL1ADDX_RRR_7_OPCODE_Y1 = 1,
- SHL1ADD_RRR_0_OPCODE_X0 = 68,
- SHL1ADD_RRR_0_OPCODE_X1 = 32,
- SHL1ADD_RRR_1_OPCODE_Y0 = 0,
- SHL1ADD_RRR_1_OPCODE_Y1 = 0,
- SHL2ADDX_RRR_0_OPCODE_X0 = 69,
- SHL2ADDX_RRR_0_OPCODE_X1 = 33,
- SHL2ADDX_RRR_7_OPCODE_Y0 = 2,
- SHL2ADDX_RRR_7_OPCODE_Y1 = 2,
- SHL2ADD_RRR_0_OPCODE_X0 = 70,
- SHL2ADD_RRR_0_OPCODE_X1 = 34,
- SHL2ADD_RRR_1_OPCODE_Y0 = 1,
- SHL2ADD_RRR_1_OPCODE_Y1 = 1,
- SHL3ADDX_RRR_0_OPCODE_X0 = 71,
- SHL3ADDX_RRR_0_OPCODE_X1 = 35,
- SHL3ADDX_RRR_7_OPCODE_Y0 = 3,
- SHL3ADDX_RRR_7_OPCODE_Y1 = 3,
- SHL3ADD_RRR_0_OPCODE_X0 = 72,
- SHL3ADD_RRR_0_OPCODE_X1 = 36,
- SHL3ADD_RRR_1_OPCODE_Y0 = 2,
- SHL3ADD_RRR_1_OPCODE_Y1 = 2,
- SHLI_SHIFT_OPCODE_X0 = 2,
- SHLI_SHIFT_OPCODE_X1 = 2,
- SHLI_SHIFT_OPCODE_Y0 = 1,
- SHLI_SHIFT_OPCODE_Y1 = 1,
- SHLXI_SHIFT_OPCODE_X0 = 3,
- SHLXI_SHIFT_OPCODE_X1 = 3,
- SHLX_RRR_0_OPCODE_X0 = 73,
- SHLX_RRR_0_OPCODE_X1 = 37,
- SHL_RRR_0_OPCODE_X0 = 74,
- SHL_RRR_0_OPCODE_X1 = 38,
- SHL_RRR_6_OPCODE_Y0 = 1,
- SHL_RRR_6_OPCODE_Y1 = 1,
- SHRSI_SHIFT_OPCODE_X0 = 4,
- SHRSI_SHIFT_OPCODE_X1 = 4,
- SHRSI_SHIFT_OPCODE_Y0 = 2,
- SHRSI_SHIFT_OPCODE_Y1 = 2,
- SHRS_RRR_0_OPCODE_X0 = 75,
- SHRS_RRR_0_OPCODE_X1 = 39,
- SHRS_RRR_6_OPCODE_Y0 = 2,
- SHRS_RRR_6_OPCODE_Y1 = 2,
- SHRUI_SHIFT_OPCODE_X0 = 5,
- SHRUI_SHIFT_OPCODE_X1 = 5,
- SHRUI_SHIFT_OPCODE_Y0 = 3,
- SHRUI_SHIFT_OPCODE_Y1 = 3,
- SHRUXI_SHIFT_OPCODE_X0 = 6,
- SHRUXI_SHIFT_OPCODE_X1 = 6,
- SHRUX_RRR_0_OPCODE_X0 = 76,
- SHRUX_RRR_0_OPCODE_X1 = 40,
- SHRU_RRR_0_OPCODE_X0 = 77,
- SHRU_RRR_0_OPCODE_X1 = 41,
- SHRU_RRR_6_OPCODE_Y0 = 3,
- SHRU_RRR_6_OPCODE_Y1 = 3,
- SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78,
- ST1_ADD_IMM8_OPCODE_X1 = 25,
- ST1_OPCODE_Y2 = 0,
- ST1_RRR_0_OPCODE_X1 = 42,
- ST2_ADD_IMM8_OPCODE_X1 = 26,
- ST2_OPCODE_Y2 = 1,
- ST2_RRR_0_OPCODE_X1 = 43,
- ST4_ADD_IMM8_OPCODE_X1 = 27,
- ST4_OPCODE_Y2 = 2,
- ST4_RRR_0_OPCODE_X1 = 44,
- STNT1_ADD_IMM8_OPCODE_X1 = 28,
- STNT1_RRR_0_OPCODE_X1 = 45,
- STNT2_ADD_IMM8_OPCODE_X1 = 29,
- STNT2_RRR_0_OPCODE_X1 = 46,
- STNT4_ADD_IMM8_OPCODE_X1 = 30,
- STNT4_RRR_0_OPCODE_X1 = 47,
- STNT_ADD_IMM8_OPCODE_X1 = 31,
- STNT_RRR_0_OPCODE_X1 = 48,
- ST_ADD_IMM8_OPCODE_X1 = 32,
- ST_OPCODE_Y2 = 3,
- ST_RRR_0_OPCODE_X1 = 49,
- SUBXSC_RRR_0_OPCODE_X0 = 79,
- SUBXSC_RRR_0_OPCODE_X1 = 50,
- SUBX_RRR_0_OPCODE_X0 = 80,
- SUBX_RRR_0_OPCODE_X1 = 51,
- SUBX_RRR_0_OPCODE_Y0 = 2,
- SUBX_RRR_0_OPCODE_Y1 = 2,
- SUB_RRR_0_OPCODE_X0 = 81,
- SUB_RRR_0_OPCODE_X1 = 52,
- SUB_RRR_0_OPCODE_Y0 = 3,
- SUB_RRR_0_OPCODE_Y1 = 3,
- SWINT0_UNARY_OPCODE_X1 = 34,
- SWINT1_UNARY_OPCODE_X1 = 35,
- SWINT2_UNARY_OPCODE_X1 = 36,
- SWINT3_UNARY_OPCODE_X1 = 37,
- TBLIDXB0_UNARY_OPCODE_X0 = 9,
- TBLIDXB0_UNARY_OPCODE_Y0 = 9,
- TBLIDXB1_UNARY_OPCODE_X0 = 10,
- TBLIDXB1_UNARY_OPCODE_Y0 = 10,
- TBLIDXB2_UNARY_OPCODE_X0 = 11,
- TBLIDXB2_UNARY_OPCODE_Y0 = 11,
- TBLIDXB3_UNARY_OPCODE_X0 = 12,
- TBLIDXB3_UNARY_OPCODE_Y0 = 12,
- UNARY_RRR_0_OPCODE_X0 = 82,
- UNARY_RRR_0_OPCODE_X1 = 53,
- UNARY_RRR_1_OPCODE_Y0 = 3,
- UNARY_RRR_1_OPCODE_Y1 = 3,
- V1ADDI_IMM8_OPCODE_X0 = 8,
- V1ADDI_IMM8_OPCODE_X1 = 33,
- V1ADDUC_RRR_0_OPCODE_X0 = 83,
- V1ADDUC_RRR_0_OPCODE_X1 = 54,
- V1ADD_RRR_0_OPCODE_X0 = 84,
- V1ADD_RRR_0_OPCODE_X1 = 55,
- V1ADIFFU_RRR_0_OPCODE_X0 = 85,
- V1AVGU_RRR_0_OPCODE_X0 = 86,
- V1CMPEQI_IMM8_OPCODE_X0 = 9,
- V1CMPEQI_IMM8_OPCODE_X1 = 34,
- V1CMPEQ_RRR_0_OPCODE_X0 = 87,
- V1CMPEQ_RRR_0_OPCODE_X1 = 56,
- V1CMPLES_RRR_0_OPCODE_X0 = 88,
- V1CMPLES_RRR_0_OPCODE_X1 = 57,
- V1CMPLEU_RRR_0_OPCODE_X0 = 89,
- V1CMPLEU_RRR_0_OPCODE_X1 = 58,
- V1CMPLTSI_IMM8_OPCODE_X0 = 10,
- V1CMPLTSI_IMM8_OPCODE_X1 = 35,
- V1CMPLTS_RRR_0_OPCODE_X0 = 90,
- V1CMPLTS_RRR_0_OPCODE_X1 = 59,
- V1CMPLTUI_IMM8_OPCODE_X0 = 11,
- V1CMPLTUI_IMM8_OPCODE_X1 = 36,
- V1CMPLTU_RRR_0_OPCODE_X0 = 91,
- V1CMPLTU_RRR_0_OPCODE_X1 = 60,
- V1CMPNE_RRR_0_OPCODE_X0 = 92,
- V1CMPNE_RRR_0_OPCODE_X1 = 61,
- V1DDOTPUA_RRR_0_OPCODE_X0 = 161,
- V1DDOTPUSA_RRR_0_OPCODE_X0 = 93,
- V1DDOTPUS_RRR_0_OPCODE_X0 = 94,
- V1DDOTPU_RRR_0_OPCODE_X0 = 162,
- V1DOTPA_RRR_0_OPCODE_X0 = 95,
- V1DOTPUA_RRR_0_OPCODE_X0 = 163,
- V1DOTPUSA_RRR_0_OPCODE_X0 = 96,
- V1DOTPUS_RRR_0_OPCODE_X0 = 97,
- V1DOTPU_RRR_0_OPCODE_X0 = 164,
- V1DOTP_RRR_0_OPCODE_X0 = 98,
- V1INT_H_RRR_0_OPCODE_X0 = 99,
- V1INT_H_RRR_0_OPCODE_X1 = 62,
- V1INT_L_RRR_0_OPCODE_X0 = 100,
- V1INT_L_RRR_0_OPCODE_X1 = 63,
- V1MAXUI_IMM8_OPCODE_X0 = 12,
- V1MAXUI_IMM8_OPCODE_X1 = 37,
- V1MAXU_RRR_0_OPCODE_X0 = 101,
- V1MAXU_RRR_0_OPCODE_X1 = 64,
- V1MINUI_IMM8_OPCODE_X0 = 13,
- V1MINUI_IMM8_OPCODE_X1 = 38,
- V1MINU_RRR_0_OPCODE_X0 = 102,
- V1MINU_RRR_0_OPCODE_X1 = 65,
- V1MNZ_RRR_0_OPCODE_X0 = 103,
- V1MNZ_RRR_0_OPCODE_X1 = 66,
- V1MULTU_RRR_0_OPCODE_X0 = 104,
- V1MULUS_RRR_0_OPCODE_X0 = 105,
- V1MULU_RRR_0_OPCODE_X0 = 106,
- V1MZ_RRR_0_OPCODE_X0 = 107,
- V1MZ_RRR_0_OPCODE_X1 = 67,
- V1SADAU_RRR_0_OPCODE_X0 = 108,
- V1SADU_RRR_0_OPCODE_X0 = 109,
- V1SHLI_SHIFT_OPCODE_X0 = 7,
- V1SHLI_SHIFT_OPCODE_X1 = 7,
- V1SHL_RRR_0_OPCODE_X0 = 110,
- V1SHL_RRR_0_OPCODE_X1 = 68,
- V1SHRSI_SHIFT_OPCODE_X0 = 8,
- V1SHRSI_SHIFT_OPCODE_X1 = 8,
- V1SHRS_RRR_0_OPCODE_X0 = 111,
- V1SHRS_RRR_0_OPCODE_X1 = 69,
- V1SHRUI_SHIFT_OPCODE_X0 = 9,
- V1SHRUI_SHIFT_OPCODE_X1 = 9,
- V1SHRU_RRR_0_OPCODE_X0 = 112,
- V1SHRU_RRR_0_OPCODE_X1 = 70,
- V1SUBUC_RRR_0_OPCODE_X0 = 113,
- V1SUBUC_RRR_0_OPCODE_X1 = 71,
- V1SUB_RRR_0_OPCODE_X0 = 114,
- V1SUB_RRR_0_OPCODE_X1 = 72,
- V2ADDI_IMM8_OPCODE_X0 = 14,
- V2ADDI_IMM8_OPCODE_X1 = 39,
- V2ADDSC_RRR_0_OPCODE_X0 = 115,
- V2ADDSC_RRR_0_OPCODE_X1 = 73,
- V2ADD_RRR_0_OPCODE_X0 = 116,
- V2ADD_RRR_0_OPCODE_X1 = 74,
- V2ADIFFS_RRR_0_OPCODE_X0 = 117,
- V2AVGS_RRR_0_OPCODE_X0 = 118,
- V2CMPEQI_IMM8_OPCODE_X0 = 15,
- V2CMPEQI_IMM8_OPCODE_X1 = 40,
- V2CMPEQ_RRR_0_OPCODE_X0 = 119,
- V2CMPEQ_RRR_0_OPCODE_X1 = 75,
- V2CMPLES_RRR_0_OPCODE_X0 = 120,
- V2CMPLES_RRR_0_OPCODE_X1 = 76,
- V2CMPLEU_RRR_0_OPCODE_X0 = 121,
- V2CMPLEU_RRR_0_OPCODE_X1 = 77,
- V2CMPLTSI_IMM8_OPCODE_X0 = 16,
- V2CMPLTSI_IMM8_OPCODE_X1 = 41,
- V2CMPLTS_RRR_0_OPCODE_X0 = 122,
- V2CMPLTS_RRR_0_OPCODE_X1 = 78,
- V2CMPLTUI_IMM8_OPCODE_X0 = 17,
- V2CMPLTUI_IMM8_OPCODE_X1 = 42,
- V2CMPLTU_RRR_0_OPCODE_X0 = 123,
- V2CMPLTU_RRR_0_OPCODE_X1 = 79,
- V2CMPNE_RRR_0_OPCODE_X0 = 124,
- V2CMPNE_RRR_0_OPCODE_X1 = 80,
- V2DOTPA_RRR_0_OPCODE_X0 = 125,
- V2DOTP_RRR_0_OPCODE_X0 = 126,
- V2INT_H_RRR_0_OPCODE_X0 = 127,
- V2INT_H_RRR_0_OPCODE_X1 = 81,
- V2INT_L_RRR_0_OPCODE_X0 = 128,
- V2INT_L_RRR_0_OPCODE_X1 = 82,
- V2MAXSI_IMM8_OPCODE_X0 = 18,
- V2MAXSI_IMM8_OPCODE_X1 = 43,
- V2MAXS_RRR_0_OPCODE_X0 = 129,
- V2MAXS_RRR_0_OPCODE_X1 = 83,
- V2MINSI_IMM8_OPCODE_X0 = 19,
- V2MINSI_IMM8_OPCODE_X1 = 44,
- V2MINS_RRR_0_OPCODE_X0 = 130,
- V2MINS_RRR_0_OPCODE_X1 = 84,
- V2MNZ_RRR_0_OPCODE_X0 = 131,
- V2MNZ_RRR_0_OPCODE_X1 = 85,
- V2MULFSC_RRR_0_OPCODE_X0 = 132,
- V2MULS_RRR_0_OPCODE_X0 = 133,
- V2MULTS_RRR_0_OPCODE_X0 = 134,
- V2MZ_RRR_0_OPCODE_X0 = 135,
- V2MZ_RRR_0_OPCODE_X1 = 86,
- V2PACKH_RRR_0_OPCODE_X0 = 136,
- V2PACKH_RRR_0_OPCODE_X1 = 87,
- V2PACKL_RRR_0_OPCODE_X0 = 137,
- V2PACKL_RRR_0_OPCODE_X1 = 88,
- V2PACKUC_RRR_0_OPCODE_X0 = 138,
- V2PACKUC_RRR_0_OPCODE_X1 = 89,
- V2SADAS_RRR_0_OPCODE_X0 = 139,
- V2SADAU_RRR_0_OPCODE_X0 = 140,
- V2SADS_RRR_0_OPCODE_X0 = 141,
- V2SADU_RRR_0_OPCODE_X0 = 142,
- V2SHLI_SHIFT_OPCODE_X0 = 10,
- V2SHLI_SHIFT_OPCODE_X1 = 10,
- V2SHLSC_RRR_0_OPCODE_X0 = 143,
- V2SHLSC_RRR_0_OPCODE_X1 = 90,
- V2SHL_RRR_0_OPCODE_X0 = 144,
- V2SHL_RRR_0_OPCODE_X1 = 91,
- V2SHRSI_SHIFT_OPCODE_X0 = 11,
- V2SHRSI_SHIFT_OPCODE_X1 = 11,
- V2SHRS_RRR_0_OPCODE_X0 = 145,
- V2SHRS_RRR_0_OPCODE_X1 = 92,
- V2SHRUI_SHIFT_OPCODE_X0 = 12,
- V2SHRUI_SHIFT_OPCODE_X1 = 12,
- V2SHRU_RRR_0_OPCODE_X0 = 146,
- V2SHRU_RRR_0_OPCODE_X1 = 93,
- V2SUBSC_RRR_0_OPCODE_X0 = 147,
- V2SUBSC_RRR_0_OPCODE_X1 = 94,
- V2SUB_RRR_0_OPCODE_X0 = 148,
- V2SUB_RRR_0_OPCODE_X1 = 95,
- V4ADDSC_RRR_0_OPCODE_X0 = 149,
- V4ADDSC_RRR_0_OPCODE_X1 = 96,
- V4ADD_RRR_0_OPCODE_X0 = 150,
- V4ADD_RRR_0_OPCODE_X1 = 97,
- V4INT_H_RRR_0_OPCODE_X0 = 151,
- V4INT_H_RRR_0_OPCODE_X1 = 98,
- V4INT_L_RRR_0_OPCODE_X0 = 152,
- V4INT_L_RRR_0_OPCODE_X1 = 99,
- V4PACKSC_RRR_0_OPCODE_X0 = 153,
- V4PACKSC_RRR_0_OPCODE_X1 = 100,
- V4SHLSC_RRR_0_OPCODE_X0 = 154,
- V4SHLSC_RRR_0_OPCODE_X1 = 101,
- V4SHL_RRR_0_OPCODE_X0 = 155,
- V4SHL_RRR_0_OPCODE_X1 = 102,
- V4SHRS_RRR_0_OPCODE_X0 = 156,
- V4SHRS_RRR_0_OPCODE_X1 = 103,
- V4SHRU_RRR_0_OPCODE_X0 = 157,
- V4SHRU_RRR_0_OPCODE_X1 = 104,
- V4SUBSC_RRR_0_OPCODE_X0 = 158,
- V4SUBSC_RRR_0_OPCODE_X1 = 105,
- V4SUB_RRR_0_OPCODE_X0 = 159,
- V4SUB_RRR_0_OPCODE_X1 = 106,
- WH64_UNARY_OPCODE_X1 = 38,
- XORI_IMM8_OPCODE_X0 = 20,
- XORI_IMM8_OPCODE_X1 = 45,
- XOR_RRR_0_OPCODE_X0 = 160,
- XOR_RRR_0_OPCODE_X1 = 107,
- XOR_RRR_5_OPCODE_Y0 = 3,
- XOR_RRR_5_OPCODE_Y1 = 3
-};
-
-static __inline unsigned int
-get_BFEnd_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 24)) & 0xf);
-}
-
-static __inline unsigned int
-get_BFStart_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3f);
-}
-
-static __inline unsigned int
-get_BrOff_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x0000003f) |
- (((unsigned int)(n >> 37)) & 0x0001ffc0);
-}
-
-static __inline unsigned int
-get_BrType_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 54)) & 0x1f);
-}
-
-static __inline unsigned int
-get_Dest_Imm8_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x0000003f) |
- (((unsigned int)(n >> 43)) & 0x000000c0);
-}
-
-static __inline unsigned int
-get_Dest_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 0)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 0)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Imm16_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0xffff);
-}
-
-static __inline unsigned int
-get_Imm16_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0xffff);
-}
-
-static __inline unsigned int
-get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 20)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 51)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0xff);
-}
-
-static __inline unsigned int
-get_JumpOff_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x7ffffff);
-}
-
-static __inline unsigned int
-get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 58)) & 0x1);
-}
-
-static __inline unsigned int
-get_MF_Imm14_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 37)) & 0x3fff);
-}
-
-static __inline unsigned int
-get_MT_Imm14_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x0000003f) |
- (((unsigned int)(n >> 37)) & 0x00003fc0);
-}
-
-static __inline unsigned int
-get_Mode(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 62)) & 0x3);
-}
-
-static __inline unsigned int
-get_Opcode_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 28)) & 0x7);
-}
-
-static __inline unsigned int
-get_Opcode_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 59)) & 0x7);
-}
-
-static __inline unsigned int
-get_Opcode_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 27)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 58)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y2(tilegx_bundle_bits n)
-{
- return (((n >> 26)) & 0x00000001) |
- (((unsigned int)(n >> 56)) & 0x00000002);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 49)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 49)) & 0x3);
-}
-
-static __inline unsigned int
-get_ShAmt_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 49)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 49)) & 0x3);
-}
-
-static __inline unsigned int
-get_SrcA_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 6)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 37)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 6)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 37)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y2(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 20)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcBDest_Y2(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 51)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline int
-sign_extend(int n, int num_bits)
-{
- int shift = (int)(sizeof(int) * 8 - num_bits);
- return (n << shift) >> shift;
-}
-
-static __inline tilegx_bundle_bits
-create_BFEnd_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_BFOpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xf) << 24);
-}
-
-static __inline tilegx_bundle_bits
-create_BFStart_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_BrOff_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
- (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_BrType_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x1f)) << 54);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Imm8_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
- (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 0);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 0);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm16_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xffff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm16_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xffff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8OpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xff) << 20);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8OpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xff)) << 51);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_JumpOff_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_JumpOpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x1)) << 58);
-}
-
-static __inline tilegx_bundle_bits
-create_MF_Imm14_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_MT_Imm14_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
- (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_Mode(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3)) << 62);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x7) << 28);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x7)) << 59);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xf) << 27);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xf)) << 58);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y2(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x00000001) << 26) |
- (((tilegx_bundle_bits)(n & 0x00000002)) << 56);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3ff) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3ff) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 6);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 6);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y2(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 20);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcBDest_Y2(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 51);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-const struct tilegx_opcode tilegx_opcodes[336] =
-{
- { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffffffff80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a44ae00000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
- { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00fffULL,
- 0xfff807ff80000000ULL,
- 0x0000000078000fffULL,
- 0x3c0007ff80000000ULL,
- 0ULL
- },
- {
- 0x0000000040300fffULL,
- 0x181807ff80000000ULL,
- 0x0000000010000fffULL,
- 0x0c0007ff80000000ULL,
- -1ULL
- }
-#endif
- },
- { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
- { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000fffULL,
- 0xf80007ff80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000070000fffULL,
- 0x380007ff80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld4s_tls", TILEGX_OPC_LD4S_TLS, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1858000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld_tls", TILEGX_OPC_LD_TLS, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18a0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 6, 7 }, { 10, 11 }, { 12, 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0xfffff80000000000ULL,
- 0x00000000780ff000ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- 0x000000005107f000ULL,
- 0x283bf80000000000ULL,
- 0x00000000500bf000ULL,
- 0x2c05f80000000000ULL,
- -1ULL
- }
-#endif
- },
- { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
- { { 8, 0 }, { 6, 1 }, { 10, 2 }, { 12, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00fc0ULL,
- 0xfff807e000000000ULL,
- 0x0000000078000fc0ULL,
- 0x3c0007e000000000ULL,
- 0ULL
- },
- {
- 0x0000000040100fc0ULL,
- 0x180807e000000000ULL,
- 0x0000000000000fc0ULL,
- 0x040007e000000000ULL,
- -1ULL
- }
-#endif
- },
- { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
- { { 8, 4 }, { 6, 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000fc0ULL,
- 0xf80007e000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000010000fc0ULL,
- 0x000007e000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a801f80000000ULL,
- -1ULL,
- -1ULL,
- 0x41f8000004000000ULL
- }
-#endif
- },
- { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1840001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1838001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1850001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1848001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1860001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1858001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a801f80000000ULL,
- -1ULL,
- -1ULL,
- 0x41f8000004000000ULL
- }
-#endif
- },
- { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a781f80000000ULL,
- -1ULL,
- -1ULL,
- 0x41f8000000000000ULL
- }
-#endif
- },
- { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a901f80000000ULL,
- -1ULL,
- -1ULL,
- 0x43f8000004000000ULL
- }
-#endif
- },
- { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a881f80000000ULL,
- -1ULL,
- -1ULL,
- 0x43f8000000000000ULL
- }
-#endif
- },
- { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286aa01f80000000ULL,
- -1ULL,
- -1ULL,
- 0x83f8000000000000ULL
- }
-#endif
- },
- { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a981f80000000ULL,
- -1ULL,
- -1ULL,
- 0x81f8000004000000ULL
- }
-#endif
- },
- { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffffffff80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a44ae80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000500c0000ULL,
- 0x2806000000000000ULL,
- 0x0000000028040000ULL,
- 0x1802000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040100000ULL,
- 0x1808000000000000ULL,
- 0ULL,
- 0x0400000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000000ULL,
- 0xf800000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000010000000ULL,
- 0ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050080000ULL,
- 0x2804000000000000ULL,
- 0x0000000028000000ULL,
- 0x1800000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040200000ULL,
- 0x1810000000000000ULL,
- 0x0000000008000000ULL,
- 0x0800000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000000ULL,
- 0xf800000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000020000000ULL,
- 0x0800000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050040000ULL,
- 0x2802000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050100000ULL,
- 0x2808000000000000ULL,
- 0x0000000050000000ULL,
- 0x2c00000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040300000ULL,
- 0x1818000000000000ULL,
- 0x0000000010000000ULL,
- 0x0c00000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1440000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1400000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1,
- { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007f000000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000034000000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1,
- { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007f000000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000035000000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1,
- { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007f000000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000036000000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x14c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1480000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1540000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1500000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x15c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1580000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1640000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1600000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x16c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1680000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1740000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1700000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x17c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1780000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051481000ULL,
- -1ULL,
- 0x00000000300c1000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050140000ULL,
- -1ULL,
- 0x0000000048000000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050180000ULL,
- -1ULL,
- 0x0000000048040000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000501c0000ULL,
- 0x280a000000000000ULL,
- 0x0000000040000000ULL,
- 0x2404000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040400000ULL,
- 0x1820000000000000ULL,
- 0x0000000018000000ULL,
- 0x1000000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x280e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x280c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050200000ULL,
- 0x2810000000000000ULL,
- 0x0000000038000000ULL,
- 0x2000000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050240000ULL,
- 0x2812000000000000ULL,
- 0x0000000038040000ULL,
- 0x2002000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050280000ULL,
- 0x2814000000000000ULL,
- 0x0000000038080000ULL,
- 0x2004000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040500000ULL,
- 0x1828000000000000ULL,
- 0x0000000020000000ULL,
- 0x1400000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000502c0000ULL,
- 0x2816000000000000ULL,
- 0x00000000380c0000ULL,
- 0x2006000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040600000ULL,
- 0x1830000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050300000ULL,
- 0x2818000000000000ULL,
- 0x0000000040040000ULL,
- 0x2406000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000504c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050380000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050340000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050400000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000503c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050480000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050440000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050500000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050540000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051482000ULL,
- -1ULL,
- 0x00000000300c2000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050640000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050580000ULL,
- 0x281a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000505c0000ULL,
- 0x281c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050600000ULL,
- 0x281e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a080000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a100000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2822000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2820000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000506c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050680000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050700000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050740000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050780000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000507c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050800000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050840000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x282a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2824000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2828000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2826000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x282e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x282c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2832000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2830000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a180000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a280000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a200000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
- { { }, { }, { }, { }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0xfffff80000000000ULL,
- 0x00000000780ff000ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- 0x0000000051483000ULL,
- 0x286a300000000000ULL,
- 0x00000000300c3000ULL,
- 0x1c06400000000000ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050880000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000508c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050900000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050940000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051484000ULL,
- -1ULL,
- 0x00000000300c4000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050980000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000509c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a380000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a400000000000ULL,
- -1ULL,
- 0x1c06480000000000ULL,
- -1ULL
- }
-#endif
- },
- { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a480000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a500000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfc00000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2400000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1,
- { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfc00000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2000000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1,
- { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a600000000000ULL,
- -1ULL,
- 0x1c06580000000000ULL,
- -1ULL
- }
-#endif
- },
- { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1,
- { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a580000000000ULL,
- -1ULL,
- 0x1c06500000000000ULL,
- -1ULL
- }
-#endif
- },
- { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a700000000000ULL,
- -1ULL,
- 0x1c06680000000000ULL,
- -1ULL
- }
-#endif
- },
- { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a680000000000ULL,
- -1ULL,
- 0x1c06600000000000ULL,
- -1ULL
- }
-#endif
- },
- { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286ae80000000000ULL,
- -1ULL,
- -1ULL,
- 0x8200000004000000ULL
- }
-#endif
- },
- { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a780000000000ULL,
- -1ULL,
- -1ULL,
- 0x4000000000000000ULL
- }
-#endif
- },
- { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1838000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a800000000000ULL,
- -1ULL,
- -1ULL,
- 0x4000000004000000ULL
- }
-#endif
- },
- { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1840000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a880000000000ULL,
- -1ULL,
- -1ULL,
- 0x4200000000000000ULL
- }
-#endif
- },
- { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1848000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a900000000000ULL,
- -1ULL,
- -1ULL,
- 0x4200000004000000ULL
- }
-#endif
- },
- { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1850000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a980000000000ULL,
- -1ULL,
- -1ULL,
- 0x8000000004000000ULL
- }
-#endif
- },
- { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1858000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286aa00000000000ULL,
- -1ULL,
- -1ULL,
- 0x8200000000000000ULL
- }
-#endif
- },
- { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1860000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18a0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286aa80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18a8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ae00000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ab00000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1868000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ab80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1870000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ac00000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1878000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ac80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1880000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ad00000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1888000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ad80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1890000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1898000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1,
- { { 0, }, { 6 }, { 0, }, { 12 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286af00000000000ULL,
- -1ULL,
- 0x1c06700000000000ULL,
- -1ULL
- }
-#endif
- },
- { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286af80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 27 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18b0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1,
- { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007f000000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000037000000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050a00000ULL,
- 0x2834000000000000ULL,
- 0x0000000048080000ULL,
- 0x2804000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 28, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18b8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050d40000ULL,
- -1ULL,
- 0x0000000068000000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050d80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050dc0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050e00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050e40000ULL,
- -1ULL,
- 0x0000000068040000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050e80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050ec0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050f00000ULL,
- -1ULL,
- 0x0000000068080000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050f40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050f80000ULL,
- -1ULL,
- 0x00000000680c0000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050a80000ULL,
- -1ULL,
- 0x0000000070000000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050ac0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050b00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050b40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050b80000ULL,
- -1ULL,
- 0x0000000070040000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050bc0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050c00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050c40000ULL,
- -1ULL,
- 0x0000000070080000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050c80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050cc0000ULL,
- -1ULL,
- 0x00000000700c0000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050a40000ULL,
- -1ULL,
- 0x0000000040080000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050d00000ULL,
- -1ULL,
- 0x00000000400c0000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050fc0000ULL,
- 0x2836000000000000ULL,
- 0x00000000480c0000ULL,
- 0x2806000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
- { { }, { }, { }, { }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0xfffff80000000000ULL,
- 0x00000000780ff000ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- 0x0000000051485000ULL,
- 0x286b080000000000ULL,
- 0x00000000300c5000ULL,
- 0x1c06780000000000ULL,
- -1ULL
- }
-#endif
- },
- { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051000000ULL,
- 0x2838000000000000ULL,
- 0x0000000050040000ULL,
- 0x2c02000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051040000ULL,
- 0x283a000000000000ULL,
- 0x0000000050080000ULL,
- 0x2c04000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040700000ULL,
- 0x18c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051486000ULL,
- -1ULL,
- 0x00000000300c6000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051487000ULL,
- -1ULL,
- 0x00000000300c7000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051488000ULL,
- -1ULL,
- 0x00000000300c8000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051080000ULL,
- 0x283c000000000000ULL,
- 0x0000000058000000ULL,
- 0x3000000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000060040000ULL,
- 0x3002000000000000ULL,
- 0x0000000078000000ULL,
- 0x3800000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051280000ULL,
- 0x284c000000000000ULL,
- 0x0000000058040000ULL,
- 0x3002000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000000ULL,
- 0xf800000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000070000000ULL,
- 0x3800000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051100000ULL,
- 0x2840000000000000ULL,
- 0x0000000030000000ULL,
- 0x1c00000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000510c0000ULL,
- 0x283e000000000000ULL,
- 0x0000000060040000ULL,
- 0x3402000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051180000ULL,
- 0x2844000000000000ULL,
- 0x0000000030040000ULL,
- 0x1c02000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051140000ULL,
- 0x2842000000000000ULL,
- 0x0000000060080000ULL,
- 0x3404000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051200000ULL,
- 0x2848000000000000ULL,
- 0x0000000030080000ULL,
- 0x1c04000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000511c0000ULL,
- 0x2846000000000000ULL,
- 0x00000000600c0000ULL,
- 0x3406000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000060080000ULL,
- 0x3004000000000000ULL,
- 0x0000000078040000ULL,
- 0x3802000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051240000ULL,
- 0x284a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000600c0000ULL,
- 0x3006000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000512c0000ULL,
- 0x284e000000000000ULL,
- 0x0000000058080000ULL,
- 0x3004000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000060100000ULL,
- 0x3008000000000000ULL,
- 0x0000000078080000ULL,
- 0x3804000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051340000ULL,
- 0x2852000000000000ULL,
- 0x00000000580c0000ULL,
- 0x3006000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000060140000ULL,
- 0x300a000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3806000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051300000ULL,
- 0x2850000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060180000ULL,
- 0x300c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051380000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x2862000000000000ULL,
- -1ULL,
- -1ULL,
- 0xc200000004000000ULL
- }
-#endif
- },
- { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x2854000000000000ULL,
- -1ULL,
- -1ULL,
- 0xc000000000000000ULL
- }
-#endif
- },
- { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18c8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x2856000000000000ULL,
- -1ULL,
- -1ULL,
- 0xc000000004000000ULL
- }
-#endif
- },
- { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18d0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x2858000000000000ULL,
- -1ULL,
- -1ULL,
- 0xc200000000000000ULL
- }
-#endif
- },
- { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18d8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1900000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2860000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x285a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18e0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x285c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18e8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x285e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18f0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18f8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051440000ULL,
- 0x2868000000000000ULL,
- 0x00000000280c0000ULL,
- 0x1806000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051400000ULL,
- 0x2866000000000000ULL,
- 0x0000000028080000ULL,
- 0x1804000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000513c0000ULL,
- 0x2864000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b100000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b180000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b200000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b280000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
- { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051489000ULL,
- -1ULL,
- 0x00000000300c9000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
- { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x000000005148a000ULL,
- -1ULL,
- 0x00000000300ca000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
- { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x000000005148b000ULL,
- -1ULL,
- 0x00000000300cb000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
- { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x000000005148c000ULL,
- -1ULL,
- 0x00000000300cc000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051500000ULL,
- 0x286e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040800000ULL,
- 0x1908000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000514c0000ULL,
- 0x286c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051540000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051580000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000515c0000ULL,
- 0x2870000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040900000ULL,
- 0x1910000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051600000ULL,
- 0x2872000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051640000ULL,
- 0x2874000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051680000ULL,
- 0x2876000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040a00000ULL,
- 0x1918000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000516c0000ULL,
- 0x2878000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040b00000ULL,
- 0x1920000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051700000ULL,
- 0x287a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052880000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052840000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051780000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051740000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051880000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000517c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052900000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000528c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051840000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051800000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000518c0000ULL,
- 0x287c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051900000ULL,
- 0x287e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051940000ULL,
- 0x2880000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040c00000ULL,
- 0x1928000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051980000ULL,
- 0x2882000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040d00000ULL,
- 0x1930000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000519c0000ULL,
- 0x2884000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051a00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051a80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051a40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051ac0000ULL,
- 0x2886000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051b00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051b40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051b80000ULL,
- 0x2888000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000601c0000ULL,
- 0x300e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051bc0000ULL,
- 0x288a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060200000ULL,
- 0x3010000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051c00000ULL,
- 0x288c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060240000ULL,
- 0x3012000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051c80000ULL,
- 0x2890000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051c40000ULL,
- 0x288e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051d00000ULL,
- 0x2894000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040e00000ULL,
- 0x1938000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051cc0000ULL,
- 0x2892000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051d40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051d80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051dc0000ULL,
- 0x2896000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040f00000ULL,
- 0x1940000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051e00000ULL,
- 0x2898000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051e40000ULL,
- 0x289a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051e80000ULL,
- 0x289c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041000000ULL,
- 0x1948000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051ec0000ULL,
- 0x289e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041100000ULL,
- 0x1950000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051f00000ULL,
- 0x28a0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051f80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051f40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051fc0000ULL,
- 0x28a2000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052000000ULL,
- 0x28a4000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052040000ULL,
- 0x28a6000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041200000ULL,
- 0x1958000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052080000ULL,
- 0x28a8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041300000ULL,
- 0x1960000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000520c0000ULL,
- 0x28aa000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052100000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052140000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052180000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000521c0000ULL,
- 0x28ac000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052200000ULL,
- 0x28ae000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052240000ULL,
- 0x28b0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052280000ULL,
- 0x28b2000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000522c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052300000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052340000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052380000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052400000ULL,
- 0x28b6000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060280000ULL,
- 0x3014000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000523c0000ULL,
- 0x28b4000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052440000ULL,
- 0x28b8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000602c0000ULL,
- 0x3016000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052480000ULL,
- 0x28ba000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060300000ULL,
- 0x3018000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052500000ULL,
- 0x28be000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000524c0000ULL,
- 0x28bc000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052580000ULL,
- 0x28c2000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052540000ULL,
- 0x28c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000525c0000ULL,
- 0x28c4000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052600000ULL,
- 0x28c6000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052640000ULL,
- 0x28c8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000526c0000ULL,
- 0x28cc000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052680000ULL,
- 0x28ca000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052700000ULL,
- 0x28ce000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052740000ULL,
- 0x28d0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000527c0000ULL,
- 0x28d4000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052780000ULL,
- 0x28d2000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b300000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000052800000ULL,
- 0x28d6000000000000ULL,
- 0x00000000500c0000ULL,
- 0x2c06000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041400000ULL,
- 0x1968000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
-#ifndef DISASM_ONLY
- { 0, }, { 0, }
-#endif
- }
-};
-
-#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))
-#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index))
-
-static const unsigned short decode_X0_fsm[936] =
-{
- BITFIELD(22, 9) /* index 0 */,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS,
- TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU,
- TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS,
- TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM,
- TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578),
- CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671),
- CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865),
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- BITFIELD(6, 2) /* index 513 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),
- BITFIELD(8, 2) /* index 518 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),
- BITFIELD(10, 2) /* index 523 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,
- BITFIELD(20, 2) /* index 528 */,
- TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),
- BITFIELD(6, 2) /* index 533 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),
- BITFIELD(8, 2) /* index 538 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),
- BITFIELD(10, 2) /* index 543 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
- BITFIELD(0, 2) /* index 548 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),
- BITFIELD(2, 2) /* index 553 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),
- BITFIELD(4, 2) /* index 558 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),
- BITFIELD(6, 2) /* index 563 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),
- BITFIELD(8, 2) /* index 568 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),
- BITFIELD(10, 2) /* index 573 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
- BITFIELD(20, 2) /* index 578 */,
- TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI,
- BITFIELD(20, 2) /* index 583 */,
- TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI,
- TILEGX_OPC_V1CMPLTUI,
- BITFIELD(20, 2) /* index 588 */,
- TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI,
- TILEGX_OPC_V2CMPEQI,
- BITFIELD(20, 2) /* index 593 */,
- TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI,
- TILEGX_OPC_V2MINSI,
- BITFIELD(20, 2) /* index 598 */,
- TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(18, 4) /* index 603 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,
- TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ,
- TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
- TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR,
- BITFIELD(18, 4) /* index 620 */,
- TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL,
- TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2,
- TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN,
- TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS,
- TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1,
- TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS,
- BITFIELD(18, 4) /* index 637 */,
- TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN,
- TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2,
- TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2,
- TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX,
- TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS,
- TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS,
- BITFIELD(18, 4) /* index 654 */,
- TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU,
- TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS,
- TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU,
- TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU,
- TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU,
- TILEGX_OPC_MZ,
- BITFIELD(18, 4) /* index 671 */,
- TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,
- TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES,
- TILEGX_OPC_SUBXSC,
- BITFIELD(12, 2) /* index 688 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693),
- BITFIELD(14, 2) /* index 693 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698),
- BITFIELD(16, 2) /* index 698 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
- BITFIELD(18, 4) /* index 703 */,
- TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC,
- TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU,
- TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA,
- BITFIELD(12, 4) /* index 720 */,
- TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757),
- CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787),
- CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 737 */,
- TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 742 */,
- TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 747 */,
- TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 752 */,
- TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 757 */,
- TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 762 */,
- TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 767 */,
- TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 772 */,
- TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 777 */,
- TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 782 */,
- TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 787 */,
- TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 792 */,
- TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(18, 4) /* index 797 */,
- TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP,
- TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU,
- TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS,
- TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU,
- TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS,
- BITFIELD(18, 4) /* index 814 */,
- TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC,
- TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS,
- TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU,
- TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE,
- TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H,
- BITFIELD(18, 4) /* index 831 */,
- TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ,
- TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ,
- TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,
- TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS,
- TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC,
- BITFIELD(18, 4) /* index 848 */,
- TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC,
- TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,
- TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,
- TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,
- TILEGX_OPC_V4SUB,
- BITFIELD(18, 3) /* index 865 */,
- CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 874 */,
- TILEGX_OPC_XOR, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 877 */,
- TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 880 */,
- TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 883 */,
- TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 886 */,
- TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE,
- BITFIELD(18, 4) /* index 889 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,
- TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,
- TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,
- TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE,
- BITFIELD(0, 2) /* index 906 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(911),
- BITFIELD(2, 2) /* index 911 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(916),
- BITFIELD(4, 2) /* index 916 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(921),
- BITFIELD(6, 2) /* index 921 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(926),
- BITFIELD(8, 2) /* index 926 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(931),
- BITFIELD(10, 2) /* index 931 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- TILEGX_OPC_INFOL,
-};
-
-static const unsigned short decode_X1_fsm[1266] =
-{
- BITFIELD(53, 9) /* index 0 */,
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT,
- TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT,
- TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT,
- TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT,
- TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST,
- TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT,
- TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT,
- TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT,
- TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578),
- CHILD(598), CHILD(703), CHILD(723), CHILD(728), CHILD(753), CHILD(758),
- CHILD(763), CHILD(768), CHILD(773), CHILD(778), TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- CHILD(783), CHILD(800), CHILD(832), CHILD(849), CHILD(1168), CHILD(1185),
- CHILD(1202), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1219), TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236),
- BITFIELD(37, 2) /* index 513 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),
- BITFIELD(39, 2) /* index 518 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),
- BITFIELD(41, 2) /* index 523 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,
- BITFIELD(51, 2) /* index 528 */,
- TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),
- BITFIELD(37, 2) /* index 533 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),
- BITFIELD(39, 2) /* index 538 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),
- BITFIELD(41, 2) /* index 543 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
- BITFIELD(31, 2) /* index 548 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),
- BITFIELD(33, 2) /* index 553 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),
- BITFIELD(35, 2) /* index 558 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),
- BITFIELD(37, 2) /* index 563 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),
- BITFIELD(39, 2) /* index 568 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),
- BITFIELD(41, 2) /* index 573 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
- BITFIELD(51, 2) /* index 578 */,
- TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583),
- BITFIELD(31, 2) /* index 583 */,
- TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588),
- BITFIELD(33, 2) /* index 588 */,
- TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593),
- BITFIELD(35, 2) /* index 593 */,
- TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD,
- TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
- BITFIELD(51, 2) /* index 598 */,
- CHILD(603), CHILD(618), CHILD(633), CHILD(648),
- BITFIELD(31, 2) /* index 603 */,
- TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608),
- BITFIELD(33, 2) /* index 608 */,
- TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613),
- BITFIELD(35, 2) /* index 613 */,
- TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD,
- TILEGX_OPC_PREFETCH_ADD_L1,
- BITFIELD(31, 2) /* index 618 */,
- TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623),
- BITFIELD(33, 2) /* index 623 */,
- TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628),
- BITFIELD(35, 2) /* index 628 */,
- TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD,
- TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
- BITFIELD(31, 2) /* index 633 */,
- TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638),
- BITFIELD(33, 2) /* index 638 */,
- TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643),
- BITFIELD(35, 2) /* index 643 */,
- TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD,
- TILEGX_OPC_PREFETCH_ADD_L2,
- BITFIELD(31, 2) /* index 648 */,
- CHILD(653), CHILD(653), CHILD(653), CHILD(673),
- BITFIELD(43, 2) /* index 653 */,
- CHILD(658), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
- BITFIELD(45, 2) /* index 658 */,
- CHILD(663), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
- BITFIELD(47, 2) /* index 663 */,
- CHILD(668), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
- BITFIELD(49, 2) /* index 668 */,
- TILEGX_OPC_LD4S_TLS, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
- TILEGX_OPC_LD4S_ADD,
- BITFIELD(33, 2) /* index 673 */,
- CHILD(653), CHILD(653), CHILD(653), CHILD(678),
- BITFIELD(35, 2) /* index 678 */,
- CHILD(653), CHILD(653), CHILD(653), CHILD(683),
- BITFIELD(43, 2) /* index 683 */,
- CHILD(688), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- BITFIELD(45, 2) /* index 688 */,
- CHILD(693), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- BITFIELD(47, 2) /* index 693 */,
- CHILD(698), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- BITFIELD(49, 2) /* index 698 */,
- TILEGX_OPC_LD4S_TLS, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- BITFIELD(51, 2) /* index 703 */,
- CHILD(708), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD,
- TILEGX_OPC_LDNT2S_ADD,
- BITFIELD(31, 2) /* index 708 */,
- TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(713),
- BITFIELD(33, 2) /* index 713 */,
- TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(718),
- BITFIELD(35, 2) /* index 718 */,
- TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD,
- TILEGX_OPC_PREFETCH_ADD_L3,
- BITFIELD(51, 2) /* index 723 */,
- TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD,
- TILEGX_OPC_LDNT_ADD,
- BITFIELD(51, 2) /* index 728 */,
- CHILD(733), TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR,
- BITFIELD(43, 2) /* index 733 */,
- CHILD(738), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
- BITFIELD(45, 2) /* index 738 */,
- CHILD(743), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
- BITFIELD(47, 2) /* index 743 */,
- CHILD(748), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
- BITFIELD(49, 2) /* index 748 */,
- TILEGX_OPC_LD_TLS, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
- BITFIELD(51, 2) /* index 753 */,
- TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD,
- BITFIELD(51, 2) /* index 758 */,
- TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD,
- TILEGX_OPC_STNT_ADD,
- BITFIELD(51, 2) /* index 763 */,
- TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI,
- TILEGX_OPC_V1CMPLTSI,
- BITFIELD(51, 2) /* index 768 */,
- TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI,
- TILEGX_OPC_V2ADDI,
- BITFIELD(51, 2) /* index 773 */,
- TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI,
- TILEGX_OPC_V2MAXSI,
- BITFIELD(51, 2) /* index 778 */,
- TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(49, 4) /* index 783 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,
- TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH,
- TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
- TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4,
- TILEGX_OPC_DBLALIGN6,
- BITFIELD(49, 4) /* index 800 */,
- TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4,
- TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD,
- TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4,
- TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR,
- CHILD(817), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,
- BITFIELD(43, 2) /* index 817 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(822),
- BITFIELD(45, 2) /* index 822 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(827),
- BITFIELD(47, 2) /* index 827 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
- BITFIELD(49, 4) /* index 832 */,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,
- TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1,
- TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2,
- TILEGX_OPC_STNT4,
- BITFIELD(46, 7) /* index 849 */,
- TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,
- TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,
- TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST,
- TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC,
- TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC,
- TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX,
- TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX,
- TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
- TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB,
- TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(978), CHILD(987),
- CHILD(1066), CHILD(1150), CHILD(1159), TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,
- TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,
- TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,
- TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,
- TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
- TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
- TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
- TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,
- TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,
- TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
- TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
- TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
- TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,
- TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,
- TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
- TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
- TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
- TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
- TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
- TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
- BITFIELD(43, 3) /* index 978 */,
- TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV,
- TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH,
- BITFIELD(43, 3) /* index 987 */,
- CHILD(996), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP,
- TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(1051),
- BITFIELD(31, 2) /* index 996 */,
- CHILD(1001), CHILD(1026), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(33, 2) /* index 1001 */,
- TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1006),
- BITFIELD(35, 2) /* index 1006 */,
- TILEGX_OPC_ILL, CHILD(1011), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(37, 2) /* index 1011 */,
- TILEGX_OPC_ILL, CHILD(1016), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(39, 2) /* index 1016 */,
- TILEGX_OPC_ILL, CHILD(1021), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(41, 2) /* index 1021 */,
- TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL,
- BITFIELD(33, 2) /* index 1026 */,
- TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1031),
- BITFIELD(35, 2) /* index 1031 */,
- TILEGX_OPC_ILL, CHILD(1036), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(37, 2) /* index 1036 */,
- TILEGX_OPC_ILL, CHILD(1041), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(39, 2) /* index 1041 */,
- TILEGX_OPC_ILL, CHILD(1046), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(41, 2) /* index 1046 */,
- TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL,
- BITFIELD(31, 2) /* index 1051 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1056),
- BITFIELD(33, 2) /* index 1056 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1061),
- BITFIELD(35, 2) /* index 1061 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,
- TILEGX_OPC_PREFETCH_L1_FAULT,
- BITFIELD(43, 3) /* index 1066 */,
- CHILD(1075), CHILD(1090), CHILD(1105), CHILD(1120), CHILD(1135),
- TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U,
- BITFIELD(31, 2) /* index 1075 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1080),
- BITFIELD(33, 2) /* index 1080 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1085),
- BITFIELD(35, 2) /* index 1085 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,
- BITFIELD(31, 2) /* index 1090 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1095),
- BITFIELD(33, 2) /* index 1095 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1100),
- BITFIELD(35, 2) /* index 1100 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,
- TILEGX_OPC_PREFETCH_L2_FAULT,
- BITFIELD(31, 2) /* index 1105 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1110),
- BITFIELD(33, 2) /* index 1110 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1115),
- BITFIELD(35, 2) /* index 1115 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,
- BITFIELD(31, 2) /* index 1120 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1125),
- BITFIELD(33, 2) /* index 1125 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1130),
- BITFIELD(35, 2) /* index 1130 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S,
- TILEGX_OPC_PREFETCH_L3_FAULT,
- BITFIELD(31, 2) /* index 1135 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1140),
- BITFIELD(33, 2) /* index 1140 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1145),
- BITFIELD(35, 2) /* index 1145 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,
- BITFIELD(43, 3) /* index 1150 */,
- TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U,
- TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF,
- BITFIELD(43, 3) /* index 1159 */,
- TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1,
- TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE,
- BITFIELD(49, 4) /* index 1168 */,
- TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ,
- TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC,
- TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ,
- TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS,
- TILEGX_OPC_V2CMPLTU,
- BITFIELD(49, 4) /* index 1185 */,
- TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L,
- TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ,
- TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,
- TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU,
- TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB,
- BITFIELD(49, 4) /* index 1202 */,
- TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,
- TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,
- TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,
- TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(49, 4) /* index 1219 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,
- TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,
- TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,
- TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE,
- BITFIELD(31, 2) /* index 1236 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1241),
- BITFIELD(33, 2) /* index 1241 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1246),
- BITFIELD(35, 2) /* index 1246 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1251),
- BITFIELD(37, 2) /* index 1251 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1256),
- BITFIELD(39, 2) /* index 1256 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1261),
- BITFIELD(41, 2) /* index 1261 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- TILEGX_OPC_INFOL,
-};
-
-static const unsigned short decode_Y0_fsm[178] =
-{
- BITFIELD(27, 4) /* index 0 */,
- CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,
- TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123),
- CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168),
- CHILD(173),
- BITFIELD(6, 2) /* index 17 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),
- BITFIELD(8, 2) /* index 22 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),
- BITFIELD(10, 2) /* index 27 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
- BITFIELD(0, 2) /* index 32 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),
- BITFIELD(2, 2) /* index 37 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),
- BITFIELD(4, 2) /* index 42 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),
- BITFIELD(6, 2) /* index 47 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),
- BITFIELD(8, 2) /* index 52 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),
- BITFIELD(10, 2) /* index 57 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
- BITFIELD(18, 2) /* index 62 */,
- TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
- BITFIELD(15, 5) /* index 67 */,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,
- TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,
- TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100),
- CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(12, 3) /* index 100 */,
- TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP,
- TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT,
- TILEGX_OPC_REVBITS,
- BITFIELD(12, 3) /* index 109 */,
- TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1,
- TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE,
- BITFIELD(18, 2) /* index 118 */,
- TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
- BITFIELD(18, 2) /* index 123 */,
- TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX,
- BITFIELD(18, 2) /* index 128 */,
- TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,
- BITFIELD(18, 2) /* index 133 */,
- TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR,
- BITFIELD(12, 2) /* index 138 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143),
- BITFIELD(14, 2) /* index 143 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148),
- BITFIELD(16, 2) /* index 148 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
- BITFIELD(18, 2) /* index 153 */,
- TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,
- BITFIELD(18, 2) /* index 158 */,
- TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,
- TILEGX_OPC_SHL3ADDX,
- BITFIELD(18, 2) /* index 163 */,
- TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS,
- TILEGX_OPC_MUL_LU_LU,
- BITFIELD(18, 2) /* index 168 */,
- TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS,
- TILEGX_OPC_MULA_LU_LU,
- BITFIELD(18, 2) /* index 173 */,
- TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,
-};
-
-static const unsigned short decode_Y1_fsm[167] =
-{
- BITFIELD(58, 4) /* index 0 */,
- TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,
- TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122),
- CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE,
- BITFIELD(37, 2) /* index 17 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),
- BITFIELD(39, 2) /* index 22 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),
- BITFIELD(41, 2) /* index 27 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
- BITFIELD(31, 2) /* index 32 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),
- BITFIELD(33, 2) /* index 37 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),
- BITFIELD(35, 2) /* index 42 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),
- BITFIELD(37, 2) /* index 47 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),
- BITFIELD(39, 2) /* index 52 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),
- BITFIELD(41, 2) /* index 57 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
- BITFIELD(49, 2) /* index 62 */,
- TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
- BITFIELD(47, 4) /* index 67 */,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD,
- TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84),
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(43, 3) /* index 84 */,
- CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108),
- CHILD(111), CHILD(114),
- BITFIELD(46, 1) /* index 93 */,
- TILEGX_OPC_NONE, TILEGX_OPC_FNOP,
- BITFIELD(46, 1) /* index 96 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ILL,
- BITFIELD(46, 1) /* index 99 */,
- TILEGX_OPC_NONE, TILEGX_OPC_JALRP,
- BITFIELD(46, 1) /* index 102 */,
- TILEGX_OPC_NONE, TILEGX_OPC_JALR,
- BITFIELD(46, 1) /* index 105 */,
- TILEGX_OPC_NONE, TILEGX_OPC_JRP,
- BITFIELD(46, 1) /* index 108 */,
- TILEGX_OPC_NONE, TILEGX_OPC_JR,
- BITFIELD(46, 1) /* index 111 */,
- TILEGX_OPC_NONE, TILEGX_OPC_LNK,
- BITFIELD(46, 1) /* index 114 */,
- TILEGX_OPC_NONE, TILEGX_OPC_NOP,
- BITFIELD(49, 2) /* index 117 */,
- TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
- BITFIELD(49, 2) /* index 122 */,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE,
- BITFIELD(49, 2) /* index 127 */,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,
- BITFIELD(49, 2) /* index 132 */,
- TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR,
- BITFIELD(43, 2) /* index 137 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142),
- BITFIELD(45, 2) /* index 142 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147),
- BITFIELD(47, 2) /* index 147 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
- BITFIELD(49, 2) /* index 152 */,
- TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,
- BITFIELD(49, 2) /* index 157 */,
- TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,
- TILEGX_OPC_SHL3ADDX,
- BITFIELD(49, 2) /* index 162 */,
- TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,
-};
-
-static const unsigned short decode_Y2_fsm[118] =
-{
- BITFIELD(62, 2) /* index 0 */,
- TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109),
- BITFIELD(55, 3) /* index 5 */,
- CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40),
- CHILD(43),
- BITFIELD(26, 1) /* index 14 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1U,
- BITFIELD(26, 1) /* index 17 */,
- CHILD(20), CHILD(30),
- BITFIELD(51, 2) /* index 20 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25),
- BITFIELD(53, 2) /* index 25 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,
- TILEGX_OPC_PREFETCH_L1_FAULT,
- BITFIELD(51, 2) /* index 30 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35),
- BITFIELD(53, 2) /* index 35 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,
- BITFIELD(26, 1) /* index 40 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2U,
- BITFIELD(26, 1) /* index 43 */,
- CHILD(46), CHILD(56),
- BITFIELD(51, 2) /* index 46 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51),
- BITFIELD(53, 2) /* index 51 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,
- TILEGX_OPC_PREFETCH_L2_FAULT,
- BITFIELD(51, 2) /* index 56 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61),
- BITFIELD(53, 2) /* index 61 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,
- BITFIELD(56, 2) /* index 66 */,
- CHILD(71), CHILD(74), CHILD(90), CHILD(93),
- BITFIELD(26, 1) /* index 71 */,
- TILEGX_OPC_NONE, TILEGX_OPC_LD4S,
- BITFIELD(26, 1) /* index 74 */,
- TILEGX_OPC_NONE, CHILD(77),
- BITFIELD(51, 2) /* index 77 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82),
- BITFIELD(53, 2) /* index 82 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87),
- BITFIELD(55, 1) /* index 87 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT,
- BITFIELD(26, 1) /* index 90 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD,
- BITFIELD(26, 1) /* index 93 */,
- CHILD(96), TILEGX_OPC_LD,
- BITFIELD(51, 2) /* index 96 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101),
- BITFIELD(53, 2) /* index 101 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106),
- BITFIELD(55, 1) /* index 106 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,
- BITFIELD(26, 1) /* index 109 */,
- CHILD(112), CHILD(115),
- BITFIELD(57, 1) /* index 112 */,
- TILEGX_OPC_ST1, TILEGX_OPC_ST4,
- BITFIELD(57, 1) /* index 115 */,
- TILEGX_OPC_ST2, TILEGX_OPC_ST,
-};
-
-#undef BITFIELD
-#undef CHILD
-
-const unsigned short * const
-tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] =
-{
- decode_X0_fsm,
- decode_X1_fsm,
- decode_Y0_fsm,
- decode_Y1_fsm,
- decode_Y2_fsm
-};
-
-const struct tilegx_operand tilegx_operands[35] =
-{
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0),
- 8, 1, 0, 0, 0, 0,
- create_Imm8_X0, get_Imm8_X0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1),
- 8, 1, 0, 0, 0, 0,
- create_Imm8_X1, get_Imm8_X1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0),
- 8, 1, 0, 0, 0, 0,
- create_Imm8_Y0, get_Imm8_Y0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1),
- 8, 1, 0, 0, 0, 0,
- create_Imm8_Y1, get_Imm8_Y1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST),
- 16, 1, 0, 0, 0, 0,
- create_Imm16_X0, get_Imm16_X0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST),
- 16, 1, 0, 0, 0, 0,
- create_Imm16_X1, get_Imm16_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_Dest_X1, get_Dest_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_X1, get_SrcA_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_Dest_X0, get_Dest_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_X0, get_SrcA_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_Dest_Y0, get_Dest_Y0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_Y0, get_SrcA_Y0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_Dest_Y1, get_Dest_Y1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_Y1, get_SrcA_Y1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_Y2, get_SrcA_Y2
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 1, 0, 0,
- create_SrcA_X1, get_SrcA_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcB_X0, get_SrcB_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcB_X1, get_SrcB_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcB_Y0, get_SrcB_Y0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcB_Y1, get_SrcB_Y1
- },
- {
- TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1),
- 17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
- create_BrOff_X1, get_BrOff_X1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0),
- 6, 0, 0, 0, 0, 0,
- create_BFStart_X0, get_BFStart_X0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0),
- 6, 0, 0, 0, 0, 0,
- create_BFEnd_X0, get_BFEnd_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 1, 0, 0,
- create_Dest_X0, get_Dest_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 1, 0, 0,
- create_Dest_Y0, get_Dest_Y0
- },
- {
- TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1),
- 27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
- create_JumpOff_X1, get_JumpOff_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_SrcBDest_Y2, get_SrcBDest_Y2
- },
- {
- TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1),
- 14, 0, 0, 0, 0, 0,
- create_MF_Imm14_X1, get_MF_Imm14_X1
- },
- {
- TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1),
- 14, 0, 0, 0, 0, 0,
- create_MT_Imm14_X1, get_MT_Imm14_X1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0),
- 6, 0, 0, 0, 0, 0,
- create_ShAmt_X0, get_ShAmt_X0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1),
- 6, 0, 0, 0, 0, 0,
- create_ShAmt_X1, get_ShAmt_X1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0),
- 6, 0, 0, 0, 0, 0,
- create_ShAmt_Y0, get_ShAmt_Y0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1),
- 6, 0, 0, 0, 0, 0,
- create_ShAmt_Y1, get_ShAmt_Y1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcBDest_Y2, get_SrcBDest_Y2
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1),
- 8, 1, 0, 0, 0, 0,
- create_Dest_Imm8_X1, get_Dest_Imm8_X1
- }
-};
-
-/* Given a set of bundle bits and a specific pipe, returns which
- * instruction the bundle contains in that pipe.
- */
-const struct tilegx_opcode *
-find_opcode(tilegx_bundle_bits bits, tilegx_pipeline pipe)
-{
- const unsigned short *table = tilegx_bundle_decoder_fsms[pipe];
- int index = 0;
-
- while (1)
- {
- unsigned short bitspec = table[index];
- unsigned int bitfield =
- ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);
-
- unsigned short next = table[index + 1 + bitfield];
- if (next <= TILEGX_OPC_NONE)
- return &tilegx_opcodes[next];
-
- index = next - TILEGX_OPC_NONE;
- }
-}
-
-int
-parse_insn_tilegx(tilegx_bundle_bits bits,
- unsigned long long pc,
- struct tilegx_decoded_instruction
- decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE])
-{
- int num_instructions = 0;
- int pipe;
-
- int min_pipe, max_pipe;
- if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0)
- {
- min_pipe = TILEGX_PIPELINE_X0;
- max_pipe = TILEGX_PIPELINE_X1;
- }
- else
- {
- min_pipe = TILEGX_PIPELINE_Y0;
- max_pipe = TILEGX_PIPELINE_Y2;
- }
-
- /* For each pipe, find an instruction that fits. */
- for (pipe = min_pipe; pipe <= max_pipe; pipe++)
- {
- const struct tilegx_opcode *opc;
- struct tilegx_decoded_instruction *d;
- int i;
-
- d = &decoded[num_instructions++];
- opc = find_opcode (bits, (tilegx_pipeline)pipe);
- d->opcode = opc;
-
- /* Decode each operand, sign extending, etc. as appropriate. */
- for (i = 0; i < opc->num_operands; i++)
- {
- const struct tilegx_operand *op =
- &tilegx_operands[opc->operands[pipe][i]];
- int raw_opval = op->extract (bits);
- long long opval;
-
- if (op->is_signed)
- {
- /* Sign-extend the operand. */
- int shift = (int)((sizeof(int) * 8) - op->num_bits);
- raw_opval = (raw_opval << shift) >> shift;
- }
-
- /* Adjust PC-relative scaled branch offsets. */
- if (op->type == TILEGX_OP_TYPE_ADDRESS)
- opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc;
- else
- opval = raw_opval;
-
- /* Record the final value. */
- d->operands[i] = op;
- d->operand_values[i] = opval;
- }
- }
-
- return num_instructions;
-}
-
-struct tilegx_spr
-{
- /* The number */
- int number;
-
- /* The name */
- const char *name;
-};
-
-static int
-tilegx_spr_compare (const void *a_ptr, const void *b_ptr)
-{
- const struct tilegx_spr *a = (const struct tilegx_spr *) a_ptr;
- const struct tilegx_spr *b = (const struct tilegx_spr *) b_ptr;
- return (a->number - b->number);
-}
-
-const struct tilegx_spr tilegx_sprs[] = {
- { 0, "MPL_MEM_ERROR_SET_0" },
- { 1, "MPL_MEM_ERROR_SET_1" },
- { 2, "MPL_MEM_ERROR_SET_2" },
- { 3, "MPL_MEM_ERROR_SET_3" },
- { 4, "MPL_MEM_ERROR" },
- { 5, "MEM_ERROR_CBOX_ADDR" },
- { 6, "MEM_ERROR_CBOX_STATUS" },
- { 7, "MEM_ERROR_ENABLE" },
- { 8, "MEM_ERROR_MBOX_ADDR" },
- { 9, "MEM_ERROR_MBOX_STATUS" },
- { 10, "SBOX_ERROR" },
- { 11, "XDN_DEMUX_ERROR" },
- { 256, "MPL_SINGLE_STEP_3_SET_0" },
- { 257, "MPL_SINGLE_STEP_3_SET_1" },
- { 258, "MPL_SINGLE_STEP_3_SET_2" },
- { 259, "MPL_SINGLE_STEP_3_SET_3" },
- { 260, "MPL_SINGLE_STEP_3" },
- { 261, "SINGLE_STEP_CONTROL_3" },
- { 512, "MPL_SINGLE_STEP_2_SET_0" },
- { 513, "MPL_SINGLE_STEP_2_SET_1" },
- { 514, "MPL_SINGLE_STEP_2_SET_2" },
- { 515, "MPL_SINGLE_STEP_2_SET_3" },
- { 516, "MPL_SINGLE_STEP_2" },
- { 517, "SINGLE_STEP_CONTROL_2" },
- { 768, "MPL_SINGLE_STEP_1_SET_0" },
- { 769, "MPL_SINGLE_STEP_1_SET_1" },
- { 770, "MPL_SINGLE_STEP_1_SET_2" },
- { 771, "MPL_SINGLE_STEP_1_SET_3" },
- { 772, "MPL_SINGLE_STEP_1" },
- { 773, "SINGLE_STEP_CONTROL_1" },
- { 1024, "MPL_SINGLE_STEP_0_SET_0" },
- { 1025, "MPL_SINGLE_STEP_0_SET_1" },
- { 1026, "MPL_SINGLE_STEP_0_SET_2" },
- { 1027, "MPL_SINGLE_STEP_0_SET_3" },
- { 1028, "MPL_SINGLE_STEP_0" },
- { 1029, "SINGLE_STEP_CONTROL_0" },
- { 1280, "MPL_IDN_COMPLETE_SET_0" },
- { 1281, "MPL_IDN_COMPLETE_SET_1" },
- { 1282, "MPL_IDN_COMPLETE_SET_2" },
- { 1283, "MPL_IDN_COMPLETE_SET_3" },
- { 1284, "MPL_IDN_COMPLETE" },
- { 1285, "IDN_COMPLETE_PENDING" },
- { 1536, "MPL_UDN_COMPLETE_SET_0" },
- { 1537, "MPL_UDN_COMPLETE_SET_1" },
- { 1538, "MPL_UDN_COMPLETE_SET_2" },
- { 1539, "MPL_UDN_COMPLETE_SET_3" },
- { 1540, "MPL_UDN_COMPLETE" },
- { 1541, "UDN_COMPLETE_PENDING" },
- { 1792, "MPL_ITLB_MISS_SET_0" },
- { 1793, "MPL_ITLB_MISS_SET_1" },
- { 1794, "MPL_ITLB_MISS_SET_2" },
- { 1795, "MPL_ITLB_MISS_SET_3" },
- { 1796, "MPL_ITLB_MISS" },
- { 1797, "ITLB_TSB_BASE_ADDR_0" },
- { 1798, "ITLB_TSB_BASE_ADDR_1" },
- { 1920, "ITLB_CURRENT_ATTR" },
- { 1921, "ITLB_CURRENT_PA" },
- { 1922, "ITLB_CURRENT_VA" },
- { 1923, "ITLB_INDEX" },
- { 1924, "ITLB_MATCH_0" },
- { 1925, "ITLB_PERF" },
- { 1926, "ITLB_PR" },
- { 1927, "ITLB_TSB_ADDR_0" },
- { 1928, "ITLB_TSB_ADDR_1" },
- { 1929, "ITLB_TSB_FILL_CURRENT_ATTR" },
- { 1930, "ITLB_TSB_FILL_MATCH" },
- { 1931, "NUMBER_ITLB" },
- { 1932, "REPLACEMENT_ITLB" },
- { 1933, "WIRED_ITLB" },
- { 2048, "MPL_ILL_SET_0" },
- { 2049, "MPL_ILL_SET_1" },
- { 2050, "MPL_ILL_SET_2" },
- { 2051, "MPL_ILL_SET_3" },
- { 2052, "MPL_ILL" },
- { 2304, "MPL_GPV_SET_0" },
- { 2305, "MPL_GPV_SET_1" },
- { 2306, "MPL_GPV_SET_2" },
- { 2307, "MPL_GPV_SET_3" },
- { 2308, "MPL_GPV" },
- { 2309, "GPV_REASON" },
- { 2560, "MPL_IDN_ACCESS_SET_0" },
- { 2561, "MPL_IDN_ACCESS_SET_1" },
- { 2562, "MPL_IDN_ACCESS_SET_2" },
- { 2563, "MPL_IDN_ACCESS_SET_3" },
- { 2564, "MPL_IDN_ACCESS" },
- { 2565, "IDN_DEMUX_COUNT_0" },
- { 2566, "IDN_DEMUX_COUNT_1" },
- { 2567, "IDN_FLUSH_EGRESS" },
- { 2568, "IDN_PENDING" },
- { 2569, "IDN_ROUTE_ORDER" },
- { 2570, "IDN_SP_FIFO_CNT" },
- { 2688, "IDN_DATA_AVAIL" },
- { 2816, "MPL_UDN_ACCESS_SET_0" },
- { 2817, "MPL_UDN_ACCESS_SET_1" },
- { 2818, "MPL_UDN_ACCESS_SET_2" },
- { 2819, "MPL_UDN_ACCESS_SET_3" },
- { 2820, "MPL_UDN_ACCESS" },
- { 2821, "UDN_DEMUX_COUNT_0" },
- { 2822, "UDN_DEMUX_COUNT_1" },
- { 2823, "UDN_DEMUX_COUNT_2" },
- { 2824, "UDN_DEMUX_COUNT_3" },
- { 2825, "UDN_FLUSH_EGRESS" },
- { 2826, "UDN_PENDING" },
- { 2827, "UDN_ROUTE_ORDER" },
- { 2828, "UDN_SP_FIFO_CNT" },
- { 2944, "UDN_DATA_AVAIL" },
- { 3072, "MPL_SWINT_3_SET_0" },
- { 3073, "MPL_SWINT_3_SET_1" },
- { 3074, "MPL_SWINT_3_SET_2" },
- { 3075, "MPL_SWINT_3_SET_3" },
- { 3076, "MPL_SWINT_3" },
- { 3328, "MPL_SWINT_2_SET_0" },
- { 3329, "MPL_SWINT_2_SET_1" },
- { 3330, "MPL_SWINT_2_SET_2" },
- { 3331, "MPL_SWINT_2_SET_3" },
- { 3332, "MPL_SWINT_2" },
- { 3584, "MPL_SWINT_1_SET_0" },
- { 3585, "MPL_SWINT_1_SET_1" },
- { 3586, "MPL_SWINT_1_SET_2" },
- { 3587, "MPL_SWINT_1_SET_3" },
- { 3588, "MPL_SWINT_1" },
- { 3840, "MPL_SWINT_0_SET_0" },
- { 3841, "MPL_SWINT_0_SET_1" },
- { 3842, "MPL_SWINT_0_SET_2" },
- { 3843, "MPL_SWINT_0_SET_3" },
- { 3844, "MPL_SWINT_0" },
- { 4096, "MPL_ILL_TRANS_SET_0" },
- { 4097, "MPL_ILL_TRANS_SET_1" },
- { 4098, "MPL_ILL_TRANS_SET_2" },
- { 4099, "MPL_ILL_TRANS_SET_3" },
- { 4100, "MPL_ILL_TRANS" },
- { 4101, "ILL_TRANS_REASON" },
- { 4102, "ILL_VA_PC" },
- { 4352, "MPL_UNALIGN_DATA_SET_0" },
- { 4353, "MPL_UNALIGN_DATA_SET_1" },
- { 4354, "MPL_UNALIGN_DATA_SET_2" },
- { 4355, "MPL_UNALIGN_DATA_SET_3" },
- { 4356, "MPL_UNALIGN_DATA" },
- { 4608, "MPL_DTLB_MISS_SET_0" },
- { 4609, "MPL_DTLB_MISS_SET_1" },
- { 4610, "MPL_DTLB_MISS_SET_2" },
- { 4611, "MPL_DTLB_MISS_SET_3" },
- { 4612, "MPL_DTLB_MISS" },
- { 4613, "DTLB_TSB_BASE_ADDR_0" },
- { 4614, "DTLB_TSB_BASE_ADDR_1" },
- { 4736, "AAR" },
- { 4737, "CACHE_PINNED_WAYS" },
- { 4738, "DTLB_BAD_ADDR" },
- { 4739, "DTLB_BAD_ADDR_REASON" },
- { 4740, "DTLB_CURRENT_ATTR" },
- { 4741, "DTLB_CURRENT_PA" },
- { 4742, "DTLB_CURRENT_VA" },
- { 4743, "DTLB_INDEX" },
- { 4744, "DTLB_MATCH_0" },
- { 4745, "DTLB_PERF" },
- { 4746, "DTLB_TSB_ADDR_0" },
- { 4747, "DTLB_TSB_ADDR_1" },
- { 4748, "DTLB_TSB_FILL_CURRENT_ATTR" },
- { 4749, "DTLB_TSB_FILL_MATCH" },
- { 4750, "NUMBER_DTLB" },
- { 4751, "REPLACEMENT_DTLB" },
- { 4752, "WIRED_DTLB" },
- { 4864, "MPL_DTLB_ACCESS_SET_0" },
- { 4865, "MPL_DTLB_ACCESS_SET_1" },
- { 4866, "MPL_DTLB_ACCESS_SET_2" },
- { 4867, "MPL_DTLB_ACCESS_SET_3" },
- { 4868, "MPL_DTLB_ACCESS" },
- { 5120, "MPL_IDN_FIREWALL_SET_0" },
- { 5121, "MPL_IDN_FIREWALL_SET_1" },
- { 5122, "MPL_IDN_FIREWALL_SET_2" },
- { 5123, "MPL_IDN_FIREWALL_SET_3" },
- { 5124, "MPL_IDN_FIREWALL" },
- { 5125, "IDN_DIRECTION_PROTECT" },
- { 5376, "MPL_UDN_FIREWALL_SET_0" },
- { 5377, "MPL_UDN_FIREWALL_SET_1" },
- { 5378, "MPL_UDN_FIREWALL_SET_2" },
- { 5379, "MPL_UDN_FIREWALL_SET_3" },
- { 5380, "MPL_UDN_FIREWALL" },
- { 5381, "UDN_DIRECTION_PROTECT" },
- { 5632, "MPL_TILE_TIMER_SET_0" },
- { 5633, "MPL_TILE_TIMER_SET_1" },
- { 5634, "MPL_TILE_TIMER_SET_2" },
- { 5635, "MPL_TILE_TIMER_SET_3" },
- { 5636, "MPL_TILE_TIMER" },
- { 5637, "TILE_TIMER_CONTROL" },
- { 5888, "MPL_AUX_TILE_TIMER_SET_0" },
- { 5889, "MPL_AUX_TILE_TIMER_SET_1" },
- { 5890, "MPL_AUX_TILE_TIMER_SET_2" },
- { 5891, "MPL_AUX_TILE_TIMER_SET_3" },
- { 5892, "MPL_AUX_TILE_TIMER" },
- { 5893, "AUX_TILE_TIMER_CONTROL" },
- { 6144, "MPL_IDN_TIMER_SET_0" },
- { 6145, "MPL_IDN_TIMER_SET_1" },
- { 6146, "MPL_IDN_TIMER_SET_2" },
- { 6147, "MPL_IDN_TIMER_SET_3" },
- { 6148, "MPL_IDN_TIMER" },
- { 6149, "IDN_DEADLOCK_COUNT" },
- { 6150, "IDN_DEADLOCK_TIMEOUT" },
- { 6400, "MPL_UDN_TIMER_SET_0" },
- { 6401, "MPL_UDN_TIMER_SET_1" },
- { 6402, "MPL_UDN_TIMER_SET_2" },
- { 6403, "MPL_UDN_TIMER_SET_3" },
- { 6404, "MPL_UDN_TIMER" },
- { 6405, "UDN_DEADLOCK_COUNT" },
- { 6406, "UDN_DEADLOCK_TIMEOUT" },
- { 6656, "MPL_IDN_AVAIL_SET_0" },
- { 6657, "MPL_IDN_AVAIL_SET_1" },
- { 6658, "MPL_IDN_AVAIL_SET_2" },
- { 6659, "MPL_IDN_AVAIL_SET_3" },
- { 6660, "MPL_IDN_AVAIL" },
- { 6661, "IDN_AVAIL_EN" },
- { 6912, "MPL_UDN_AVAIL_SET_0" },
- { 6913, "MPL_UDN_AVAIL_SET_1" },
- { 6914, "MPL_UDN_AVAIL_SET_2" },
- { 6915, "MPL_UDN_AVAIL_SET_3" },
- { 6916, "MPL_UDN_AVAIL" },
- { 6917, "UDN_AVAIL_EN" },
- { 7168, "MPL_IPI_3_SET_0" },
- { 7169, "MPL_IPI_3_SET_1" },
- { 7170, "MPL_IPI_3_SET_2" },
- { 7171, "MPL_IPI_3_SET_3" },
- { 7172, "MPL_IPI_3" },
- { 7173, "IPI_EVENT_3" },
- { 7174, "IPI_EVENT_RESET_3" },
- { 7175, "IPI_EVENT_SET_3" },
- { 7176, "IPI_MASK_3" },
- { 7177, "IPI_MASK_RESET_3" },
- { 7178, "IPI_MASK_SET_3" },
- { 7424, "MPL_IPI_2_SET_0" },
- { 7425, "MPL_IPI_2_SET_1" },
- { 7426, "MPL_IPI_2_SET_2" },
- { 7427, "MPL_IPI_2_SET_3" },
- { 7428, "MPL_IPI_2" },
- { 7429, "IPI_EVENT_2" },
- { 7430, "IPI_EVENT_RESET_2" },
- { 7431, "IPI_EVENT_SET_2" },
- { 7432, "IPI_MASK_2" },
- { 7433, "IPI_MASK_RESET_2" },
- { 7434, "IPI_MASK_SET_2" },
- { 7680, "MPL_IPI_1_SET_0" },
- { 7681, "MPL_IPI_1_SET_1" },
- { 7682, "MPL_IPI_1_SET_2" },
- { 7683, "MPL_IPI_1_SET_3" },
- { 7684, "MPL_IPI_1" },
- { 7685, "IPI_EVENT_1" },
- { 7686, "IPI_EVENT_RESET_1" },
- { 7687, "IPI_EVENT_SET_1" },
- { 7688, "IPI_MASK_1" },
- { 7689, "IPI_MASK_RESET_1" },
- { 7690, "IPI_MASK_SET_1" },
- { 7936, "MPL_IPI_0_SET_0" },
- { 7937, "MPL_IPI_0_SET_1" },
- { 7938, "MPL_IPI_0_SET_2" },
- { 7939, "MPL_IPI_0_SET_3" },
- { 7940, "MPL_IPI_0" },
- { 7941, "IPI_EVENT_0" },
- { 7942, "IPI_EVENT_RESET_0" },
- { 7943, "IPI_EVENT_SET_0" },
- { 7944, "IPI_MASK_0" },
- { 7945, "IPI_MASK_RESET_0" },
- { 7946, "IPI_MASK_SET_0" },
- { 8192, "MPL_PERF_COUNT_SET_0" },
- { 8193, "MPL_PERF_COUNT_SET_1" },
- { 8194, "MPL_PERF_COUNT_SET_2" },
- { 8195, "MPL_PERF_COUNT_SET_3" },
- { 8196, "MPL_PERF_COUNT" },
- { 8197, "PERF_COUNT_0" },
- { 8198, "PERF_COUNT_1" },
- { 8199, "PERF_COUNT_CTL" },
- { 8200, "PERF_COUNT_DN_CTL" },
- { 8201, "PERF_COUNT_STS" },
- { 8202, "WATCH_MASK" },
- { 8203, "WATCH_VAL" },
- { 8448, "MPL_AUX_PERF_COUNT_SET_0" },
- { 8449, "MPL_AUX_PERF_COUNT_SET_1" },
- { 8450, "MPL_AUX_PERF_COUNT_SET_2" },
- { 8451, "MPL_AUX_PERF_COUNT_SET_3" },
- { 8452, "MPL_AUX_PERF_COUNT" },
- { 8453, "AUX_PERF_COUNT_0" },
- { 8454, "AUX_PERF_COUNT_1" },
- { 8455, "AUX_PERF_COUNT_CTL" },
- { 8456, "AUX_PERF_COUNT_STS" },
- { 8704, "MPL_INTCTRL_3_SET_0" },
- { 8705, "MPL_INTCTRL_3_SET_1" },
- { 8706, "MPL_INTCTRL_3_SET_2" },
- { 8707, "MPL_INTCTRL_3_SET_3" },
- { 8708, "MPL_INTCTRL_3" },
- { 8709, "INTCTRL_3_STATUS" },
- { 8710, "INTERRUPT_MASK_3" },
- { 8711, "INTERRUPT_MASK_RESET_3" },
- { 8712, "INTERRUPT_MASK_SET_3" },
- { 8713, "INTERRUPT_VECTOR_BASE_3" },
- { 8714, "SINGLE_STEP_EN_0_3" },
- { 8715, "SINGLE_STEP_EN_1_3" },
- { 8716, "SINGLE_STEP_EN_2_3" },
- { 8717, "SINGLE_STEP_EN_3_3" },
- { 8832, "EX_CONTEXT_3_0" },
- { 8833, "EX_CONTEXT_3_1" },
- { 8834, "SYSTEM_SAVE_3_0" },
- { 8835, "SYSTEM_SAVE_3_1" },
- { 8836, "SYSTEM_SAVE_3_2" },
- { 8837, "SYSTEM_SAVE_3_3" },
- { 8960, "MPL_INTCTRL_2_SET_0" },
- { 8961, "MPL_INTCTRL_2_SET_1" },
- { 8962, "MPL_INTCTRL_2_SET_2" },
- { 8963, "MPL_INTCTRL_2_SET_3" },
- { 8964, "MPL_INTCTRL_2" },
- { 8965, "INTCTRL_2_STATUS" },
- { 8966, "INTERRUPT_MASK_2" },
- { 8967, "INTERRUPT_MASK_RESET_2" },
- { 8968, "INTERRUPT_MASK_SET_2" },
- { 8969, "INTERRUPT_VECTOR_BASE_2" },
- { 8970, "SINGLE_STEP_EN_0_2" },
- { 8971, "SINGLE_STEP_EN_1_2" },
- { 8972, "SINGLE_STEP_EN_2_2" },
- { 8973, "SINGLE_STEP_EN_3_2" },
- { 9088, "EX_CONTEXT_2_0" },
- { 9089, "EX_CONTEXT_2_1" },
- { 9090, "SYSTEM_SAVE_2_0" },
- { 9091, "SYSTEM_SAVE_2_1" },
- { 9092, "SYSTEM_SAVE_2_2" },
- { 9093, "SYSTEM_SAVE_2_3" },
- { 9216, "MPL_INTCTRL_1_SET_0" },
- { 9217, "MPL_INTCTRL_1_SET_1" },
- { 9218, "MPL_INTCTRL_1_SET_2" },
- { 9219, "MPL_INTCTRL_1_SET_3" },
- { 9220, "MPL_INTCTRL_1" },
- { 9221, "INTCTRL_1_STATUS" },
- { 9222, "INTERRUPT_MASK_1" },
- { 9223, "INTERRUPT_MASK_RESET_1" },
- { 9224, "INTERRUPT_MASK_SET_1" },
- { 9225, "INTERRUPT_VECTOR_BASE_1" },
- { 9226, "SINGLE_STEP_EN_0_1" },
- { 9227, "SINGLE_STEP_EN_1_1" },
- { 9228, "SINGLE_STEP_EN_2_1" },
- { 9229, "SINGLE_STEP_EN_3_1" },
- { 9344, "EX_CONTEXT_1_0" },
- { 9345, "EX_CONTEXT_1_1" },
- { 9346, "SYSTEM_SAVE_1_0" },
- { 9347, "SYSTEM_SAVE_1_1" },
- { 9348, "SYSTEM_SAVE_1_2" },
- { 9349, "SYSTEM_SAVE_1_3" },
- { 9472, "MPL_INTCTRL_0_SET_0" },
- { 9473, "MPL_INTCTRL_0_SET_1" },
- { 9474, "MPL_INTCTRL_0_SET_2" },
- { 9475, "MPL_INTCTRL_0_SET_3" },
- { 9476, "MPL_INTCTRL_0" },
- { 9477, "INTCTRL_0_STATUS" },
- { 9478, "INTERRUPT_MASK_0" },
- { 9479, "INTERRUPT_MASK_RESET_0" },
- { 9480, "INTERRUPT_MASK_SET_0" },
- { 9481, "INTERRUPT_VECTOR_BASE_0" },
- { 9482, "SINGLE_STEP_EN_0_0" },
- { 9483, "SINGLE_STEP_EN_1_0" },
- { 9484, "SINGLE_STEP_EN_2_0" },
- { 9485, "SINGLE_STEP_EN_3_0" },
- { 9600, "EX_CONTEXT_0_0" },
- { 9601, "EX_CONTEXT_0_1" },
- { 9602, "SYSTEM_SAVE_0_0" },
- { 9603, "SYSTEM_SAVE_0_1" },
- { 9604, "SYSTEM_SAVE_0_2" },
- { 9605, "SYSTEM_SAVE_0_3" },
- { 9728, "MPL_BOOT_ACCESS_SET_0" },
- { 9729, "MPL_BOOT_ACCESS_SET_1" },
- { 9730, "MPL_BOOT_ACCESS_SET_2" },
- { 9731, "MPL_BOOT_ACCESS_SET_3" },
- { 9732, "MPL_BOOT_ACCESS" },
- { 9733, "BIG_ENDIAN_CONFIG" },
- { 9734, "CACHE_INVALIDATION_COMPRESSION_MODE" },
- { 9735, "CACHE_INVALIDATION_MASK_0" },
- { 9736, "CACHE_INVALIDATION_MASK_1" },
- { 9737, "CACHE_INVALIDATION_MASK_2" },
- { 9738, "CBOX_CACHEASRAM_CONFIG" },
- { 9739, "CBOX_CACHE_CONFIG" },
- { 9740, "CBOX_HOME_MAP_ADDR" },
- { 9741, "CBOX_HOME_MAP_DATA" },
- { 9742, "CBOX_MMAP_0" },
- { 9743, "CBOX_MMAP_1" },
- { 9744, "CBOX_MMAP_2" },
- { 9745, "CBOX_MMAP_3" },
- { 9746, "CBOX_MSR" },
- { 9747, "DIAG_BCST_CTL" },
- { 9748, "DIAG_BCST_MASK" },
- { 9749, "DIAG_BCST_TRIGGER" },
- { 9750, "DIAG_MUX_CTL" },
- { 9751, "DIAG_TRACE_CTL" },
- { 9752, "DIAG_TRACE_DATA" },
- { 9753, "DIAG_TRACE_STS" },
- { 9754, "IDN_DEMUX_BUF_THRESH" },
- { 9755, "L1_I_PIN_WAY_0" },
- { 9756, "MEM_ROUTE_ORDER" },
- { 9757, "MEM_STRIPE_CONFIG" },
- { 9758, "PERF_COUNT_PLS" },
- { 9759, "PSEUDO_RANDOM_NUMBER_MODIFY" },
- { 9760, "QUIESCE_CTL" },
- { 9761, "RSHIM_COORD" },
- { 9762, "SBOX_CONFIG" },
- { 9763, "UDN_DEMUX_BUF_THRESH" },
- { 9764, "XDN_CORE_STARVATION_COUNT" },
- { 9765, "XDN_ROUND_ROBIN_ARB_CTL" },
- { 9856, "CYCLE_MODIFY" },
- { 9857, "I_AAR" },
- { 9984, "MPL_WORLD_ACCESS_SET_0" },
- { 9985, "MPL_WORLD_ACCESS_SET_1" },
- { 9986, "MPL_WORLD_ACCESS_SET_2" },
- { 9987, "MPL_WORLD_ACCESS_SET_3" },
- { 9988, "MPL_WORLD_ACCESS" },
- { 9989, "DONE" },
- { 9990, "DSTREAM_PF" },
- { 9991, "FAIL" },
- { 9992, "INTERRUPT_CRITICAL_SECTION" },
- { 9993, "PASS" },
- { 9994, "PSEUDO_RANDOM_NUMBER" },
- { 9995, "TILE_COORD" },
- { 9996, "TILE_RTF_HWM" },
- { 10112, "CMPEXCH_VALUE" },
- { 10113, "CYCLE" },
- { 10114, "EVENT_BEGIN" },
- { 10115, "EVENT_END" },
- { 10116, "PROC_STATUS" },
- { 10117, "SIM_CONTROL" },
- { 10118, "SIM_SOCKET" },
- { 10119, "STATUS_SATURATE" },
- { 10240, "MPL_I_ASID_SET_0" },
- { 10241, "MPL_I_ASID_SET_1" },
- { 10242, "MPL_I_ASID_SET_2" },
- { 10243, "MPL_I_ASID_SET_3" },
- { 10244, "MPL_I_ASID" },
- { 10245, "I_ASID" },
- { 10496, "MPL_D_ASID_SET_0" },
- { 10497, "MPL_D_ASID_SET_1" },
- { 10498, "MPL_D_ASID_SET_2" },
- { 10499, "MPL_D_ASID_SET_3" },
- { 10500, "MPL_D_ASID" },
- { 10501, "D_ASID" },
- { 10752, "MPL_DOUBLE_FAULT_SET_0" },
- { 10753, "MPL_DOUBLE_FAULT_SET_1" },
- { 10754, "MPL_DOUBLE_FAULT_SET_2" },
- { 10755, "MPL_DOUBLE_FAULT_SET_3" },
- { 10756, "MPL_DOUBLE_FAULT" },
- { 10757, "LAST_INTERRUPT_REASON" },
-};
-
-const int tilegx_num_sprs = 441;
-
-const char *
-get_tilegx_spr_name (int num)
-{
- void *result;
- struct tilegx_spr key;
-
- key.number = num;
- result = bsearch((const void *) &key, (const void *) tilegx_sprs,
- tilegx_num_sprs, sizeof (struct tilegx_spr),
- tilegx_spr_compare);
-
- if (result == NULL)
- {
- return (NULL);
- }
- else
- {
- struct tilegx_spr *result_ptr = (struct tilegx_spr *) result;
- return (result_ptr->name);
- }
-}
-
-int
-print_insn_tilegx (unsigned char * memaddr)
-{
- struct tilegx_decoded_instruction
- decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
- unsigned char opbuf[TILEGX_BUNDLE_SIZE_IN_BYTES];
- int i, num_instructions, num_printed;
- tilegx_mnemonic padding_mnemonic;
-
- memcpy((void *)opbuf, (void *)memaddr, TILEGX_BUNDLE_SIZE_IN_BYTES);
-
- /* Parse the instructions in the bundle. */
- num_instructions =
- parse_insn_tilegx (*(unsigned long long *)opbuf, (unsigned long long)memaddr, decoded);
-
- /* Print the instructions in the bundle. */
- printf("{ ");
- num_printed = 0;
-
- /* Determine which nop opcode is used for padding and should be skipped. */
- padding_mnemonic = TILEGX_OPC_FNOP;
- for (i = 0; i < num_instructions; i++)
- {
- if (!decoded[i].opcode->can_bundle)
- {
- /* Instructions that cannot be bundled are padded out with nops,
- rather than fnops. Displaying them is always clutter. */
- padding_mnemonic = TILEGX_OPC_NOP;
- break;
- }
- }
-
- for (i = 0; i < num_instructions; i++)
- {
- const struct tilegx_opcode *opcode = decoded[i].opcode;
- const char *name;
- int j;
-
- /* Do not print out fnops, unless everything is an fnop, in
- which case we will print out just the last one. */
- if (opcode->mnemonic == padding_mnemonic
- && (num_printed > 0 || i + 1 < num_instructions))
- continue;
-
- if (num_printed > 0)
- printf(" ; ");
- ++num_printed;
-
- name = opcode->name;
- if (name == NULL)
- name = "<invalid>";
- printf("%s", name);
-
- for (j = 0; j < opcode->num_operands; j++)
- {
- unsigned long long num;
- const struct tilegx_operand *op;
- const char *spr_name;
-
- if (j > 0)
- printf (",");
- printf (" ");
-
- num = decoded[i].operand_values[j];
-
- op = decoded[i].operands[j];
- switch (op->type)
- {
- case TILEGX_OP_TYPE_REGISTER:
- printf ("%s", tilegx_register_names[(int)num]);
- break;
- case TILEGX_OP_TYPE_SPR:
- spr_name = get_tilegx_spr_name(num);
- if (spr_name != NULL)
- printf ("%s", spr_name);
- else
- printf ("%d", (int)num);
- break;
- case TILEGX_OP_TYPE_IMMEDIATE:
- printf ("%d", (int)num);
- break;
- case TILEGX_OP_TYPE_ADDRESS:
- printf ("0x%016llx", num);
- break;
- default:
- abort ();
- }
- }
- }
- printf (" }\n");
-
- return TILEGX_BUNDLE_SIZE_IN_BYTES;
-}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c b/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c
deleted file mode 100644
index 003f43a790..0000000000
--- a/thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c
+++ /dev/null
@@ -1,2555 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* TileGX architecture. */
-/* Contributed by Tilera Corporation. */
-#include "sljitNativeTILEGX-encoder.c"
-
-#define SIMM_8BIT_MAX (0x7f)
-#define SIMM_8BIT_MIN (-0x80)
-#define SIMM_16BIT_MAX (0x7fff)
-#define SIMM_16BIT_MIN (-0x8000)
-#define SIMM_17BIT_MAX (0xffff)
-#define SIMM_17BIT_MIN (-0x10000)
-#define SIMM_32BIT_MAX (0x7fffffff)
-#define SIMM_32BIT_MIN (-0x7fffffff - 1)
-#define SIMM_48BIT_MAX (0x7fffffff0000L)
-#define SIMM_48BIT_MIN (-0x800000000000L)
-#define IMM16(imm) ((imm) & 0xffff)
-
-#define UIMM_16BIT_MAX (0xffff)
-
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
-#define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5)
-#define PIC_ADDR_REG TMP_REG2
-
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
- 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7
-};
-
-#define SLJIT_LOCALS_REG_mapped 54
-#define TMP_REG1_mapped 5
-#define TMP_REG2_mapped 16
-#define TMP_REG3_mapped 6
-#define ADDR_TMP_mapped 7
-
-/* Flags are keept in volatile registers. */
-#define EQUAL_FLAG 8
-/* And carry flag as well. */
-#define ULESS_FLAG 9
-#define UGREATER_FLAG 10
-#define LESS_FLAG 11
-#define GREATER_FLAG 12
-#define OVERFLOW_FLAG 13
-
-#define ZERO 63
-#define RA 55
-#define TMP_EREG1 14
-#define TMP_EREG2 15
-
-#define LOAD_DATA 0x01
-#define WORD_DATA 0x00
-#define BYTE_DATA 0x02
-#define HALF_DATA 0x04
-#define INT_DATA 0x06
-#define SIGNED_DATA 0x08
-#define DOUBLE_DATA 0x10
-
-/* Separates integer and floating point registers */
-#define GPR_REG 0xf
-
-#define MEM_MASK 0x1f
-
-#define WRITE_BACK 0x00020
-#define ARG_TEST 0x00040
-#define ALT_KEEP_CACHE 0x00080
-#define CUMULATIVE_OP 0x00100
-#define LOGICAL_OP 0x00200
-#define IMM_OP 0x00400
-#define SRC2_IMM 0x00800
-
-#define UNUSED_DEST 0x01000
-#define REG_DEST 0x02000
-#define REG1_SOURCE 0x04000
-#define REG2_SOURCE 0x08000
-#define SLOW_SRC1 0x10000
-#define SLOW_SRC2 0x20000
-#define SLOW_DEST 0x40000
-
-/* Only these flags are set. UNUSED_DEST is not set when no flags should be set.
- */
-#define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list))))
-
-SLJIT_API_FUNC_ATTRIBUTE const char *sljit_get_platform_name(void)
-{
- return "TileGX" SLJIT_CPUINFO;
-}
-
-/* Length of an instruction word */
-typedef sljit_uw sljit_ins;
-
-struct jit_instr {
- const struct tilegx_opcode* opcode;
- tilegx_pipeline pipe;
- unsigned long input_registers;
- unsigned long output_registers;
- int operand_value[4];
- int line;
-};
-
-/* Opcode Helper Macros */
-#define TILEGX_X_MODE 0
-
-#define X_MODE create_Mode(TILEGX_X_MODE)
-
-#define FNOP_X0 \
- create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
- create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0)
-
-#define FNOP_X1 \
- create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1)
-
-#define NOP \
- create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1
-
-#define ANOP_X0 \
- create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
- create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0)
-
-#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \
- create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0
-
-#define ADD_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define ADDI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define SUB_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define NOR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define OR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define AND_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define XOR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define CMOVNEZ_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1
-
-#define CMOVEQZ_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1
-
-#define ADDLI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0
-
-#define V4INT_L_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define BFEXTU_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \
- create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1
-
-#define BFEXTS_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \
- create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1
-
-#define SHL16INSLI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0
-
-#define ST_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0
-
-#define LD_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0
-
-#define JR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0
-
-#define JALR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0
-
-#define CLZ_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
- create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1
-
-#define CMPLTUI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define CMPLTU_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define CMPLTS_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define XORI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define ORI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define ANDI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define SHLI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
- create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0
-
-#define SHL_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define SHRSI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
- create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0
-
-#define SHRS_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define SHRUI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
- create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0
-
-#define SHRU_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define BEQZ_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \
- create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0
-
-#define BNEZ_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \
- create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0
-
-#define J_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \
- create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0
-
-#define JAL_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \
- create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0
-
-#define DEST_X0(x) create_Dest_X0(x)
-#define SRCA_X0(x) create_SrcA_X0(x)
-#define SRCB_X0(x) create_SrcB_X0(x)
-#define DEST_X1(x) create_Dest_X1(x)
-#define SRCA_X1(x) create_SrcA_X1(x)
-#define SRCB_X1(x) create_SrcB_X1(x)
-#define IMM16_X1(x) create_Imm16_X1(x)
-#define IMM8_X1(x) create_Imm8_X1(x)
-#define BFSTART_X0(x) create_BFStart_X0(x)
-#define BFEND_X0(x) create_BFEnd_X0(x)
-#define SHIFTIMM_X1(x) create_ShAmt_X1(x)
-#define JOFF_X1(x) create_JumpOff_X1(x)
-#define BOFF_X1(x) create_BrOff_X1(x)
-
-static const tilegx_mnemonic data_transfer_insts[16] = {
- /* u w s */ TILEGX_OPC_ST /* st */,
- /* u w l */ TILEGX_OPC_LD /* ld */,
- /* u b s */ TILEGX_OPC_ST1 /* st1 */,
- /* u b l */ TILEGX_OPC_LD1U /* ld1u */,
- /* u h s */ TILEGX_OPC_ST2 /* st2 */,
- /* u h l */ TILEGX_OPC_LD2U /* ld2u */,
- /* u i s */ TILEGX_OPC_ST4 /* st4 */,
- /* u i l */ TILEGX_OPC_LD4U /* ld4u */,
- /* s w s */ TILEGX_OPC_ST /* st */,
- /* s w l */ TILEGX_OPC_LD /* ld */,
- /* s b s */ TILEGX_OPC_ST1 /* st1 */,
- /* s b l */ TILEGX_OPC_LD1S /* ld1s */,
- /* s h s */ TILEGX_OPC_ST2 /* st2 */,
- /* s h l */ TILEGX_OPC_LD2S /* ld2s */,
- /* s i s */ TILEGX_OPC_ST4 /* st4 */,
- /* s i l */ TILEGX_OPC_LD4S /* ld4s */,
-};
-
-#ifdef TILEGX_JIT_DEBUG
-static sljit_s32 push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line)
-{
- sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- printf("|%04d|S0|:\t\t", line);
- print_insn_tilegx(ptr);
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins)
-{
- sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-
-#define push_inst(a, b) push_inst_debug(a, b, __LINE__)
-#else
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
-{
- sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-#endif
-
-#define BUNDLE_FORMAT_MASK(p0, p1, p2) \
- ((p0) | ((p1) << 8) | ((p2) << 16))
-
-#define BUNDLE_FORMAT(p0, p1, p2) \
- { \
- { \
- (tilegx_pipeline)(p0), \
- (tilegx_pipeline)(p1), \
- (tilegx_pipeline)(p2) \
- }, \
- BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \
- }
-
-#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS
-
-#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
-
-#define PI(encoding) \
- push_inst(compiler, encoding)
-
-#define PB3(opcode, dst, srca, srcb) \
- push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__)
-
-#define PB2(opcode, dst, src) \
- push_2_buffer(compiler, opcode, dst, src, __LINE__)
-
-#define JR(reg) \
- push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__)
-
-#define ADD(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__)
-
-#define SUB(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__)
-
-#define MUL(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__)
-
-#define NOR(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__)
-
-#define OR(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__)
-
-#define XOR(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__)
-
-#define AND(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__)
-
-#define CLZ(dst, src) \
- push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__)
-
-#define SHLI(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__)
-
-#define SHRUI(dst, srca, imm) \
- push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__)
-
-#define XORI(dst, srca, imm) \
- push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__)
-
-#define ORI(dst, srca, imm) \
- push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__)
-
-#define CMPLTU(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__)
-
-#define CMPLTS(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__)
-
-#define CMPLTUI(dst, srca, imm) \
- push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__)
-
-#define CMOVNEZ(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__)
-
-#define CMOVEQZ(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__)
-
-#define ADDLI(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__)
-
-#define SHL16INSLI(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__)
-
-#define LD_ADD(dst, addr, adjust) \
- push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__)
-
-#define ST_ADD(src, addr, adjust) \
- push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__)
-
-#define LD(dst, addr) \
- push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__)
-
-#define BFEXTU(dst, src, start, end) \
- push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__)
-
-#define BFEXTS(dst, src, start, end) \
- push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__)
-
-#define ADD_SOLO(dest, srca, srcb) \
- push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb))
-
-#define ADDI_SOLO(dest, srca, imm) \
- push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm))
-
-#define ADDLI_SOLO(dest, srca, imm) \
- push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))
-
-#define SHL16INSLI_SOLO(dest, srca, imm) \
- push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))
-
-#define JALR_SOLO(reg) \
- push_inst(compiler, JALR_X1 | SRCA_X1(reg))
-
-#define JR_SOLO(reg) \
- push_inst(compiler, JR_X1 | SRCA_X1(reg))
-
-struct Format {
- /* Mapping of bundle issue slot to assigned pipe. */
- tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
-
- /* Mask of pipes used by this bundle. */
- unsigned int pipe_mask;
-};
-
-const struct Format formats[] =
-{
- /* In Y format we must always have something in Y2, since it has
- * no fnop, so this conveys that Y2 must always be used. */
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE),
-
- /* Y format has three instructions. */
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0),
-
- /* X format has only two instructions. */
- BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE),
- BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE)
-};
-
-
-struct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
-unsigned long inst_buf_index;
-
-tilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode)
-{
- /* FIXME: tile: we could pregenerate this. */
- int pipe;
- for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++)
- ;
- return (tilegx_pipeline)(pipe);
-}
-
-void insert_nop(tilegx_mnemonic opc, int line)
-{
- const struct tilegx_opcode* opcode = NULL;
-
- memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]);
-
- opcode = &tilegx_opcodes[opc];
- inst_buf[0].opcode = opcode;
- inst_buf[0].pipe = get_any_valid_pipe(opcode);
- inst_buf[0].input_registers = 0;
- inst_buf[0].output_registers = 0;
- inst_buf[0].line = line;
- ++inst_buf_index;
-}
-
-const struct Format* compute_format()
-{
- unsigned int compatible_pipes = BUNDLE_FORMAT_MASK(
- inst_buf[0].opcode->pipes,
- inst_buf[1].opcode->pipes,
- (inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE)));
-
- const struct Format* match = NULL;
- const struct Format *b = NULL;
- unsigned int i;
- for (i = 0; i < sizeof formats / sizeof formats[0]; i++) {
- b = &formats[i];
- if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) {
- match = b;
- break;
- }
- }
-
- return match;
-}
-
-sljit_s32 assign_pipes()
-{
- unsigned long output_registers = 0;
- unsigned int i = 0;
-
- if (inst_buf_index == 1) {
- tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle
- ? TILEGX_OPC_FNOP : TILEGX_OPC_NOP;
- insert_nop(opc, __LINE__);
- }
-
- const struct Format* match = compute_format();
-
- if (match == NULL)
- return -1;
-
- for (i = 0; i < inst_buf_index; i++) {
-
- if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0))
- return -1;
-
- if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0))
- return -1;
-
- /* Don't include Rzero in the match set, to avoid triggering
- needlessly on 'prefetch' instrs. */
-
- output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL;
-
- inst_buf[i].pipe = match->pipe[i];
- }
-
- /* If only 2 instrs, and in Y-mode, insert a nop. */
- if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) {
- insert_nop(TILEGX_OPC_FNOP, __LINE__);
-
- /* Select the yet unassigned pipe. */
- tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0
- + TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2)
- - (inst_buf[1].pipe + inst_buf[2].pipe)));
-
- inst_buf[0].pipe = pipe;
- }
-
- return 0;
-}
-
-tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst)
-{
- int i, val;
- const struct tilegx_opcode* opcode = inst->opcode;
- tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe];
-
- const struct tilegx_operand* operand = NULL;
- for (i = 0; i < opcode->num_operands; i++) {
- operand = &tilegx_operands[opcode->operands[inst->pipe][i]];
- val = inst->operand_value[i];
-
- bits |= operand->insert(val);
- }
-
- return bits;
-}
-
-static sljit_s32 update_buffer(struct sljit_compiler *compiler)
-{
- int i;
- int orig_index = inst_buf_index;
- struct jit_instr inst0 = inst_buf[0];
- struct jit_instr inst1 = inst_buf[1];
- struct jit_instr inst2 = inst_buf[2];
- tilegx_bundle_bits bits = 0;
-
- /* If the bundle is valid as is, perform the encoding and return 1. */
- if (assign_pipes() == 0) {
- for (i = 0; i < inst_buf_index; i++) {
- bits |= get_bundle_bit(inst_buf + i);
-#ifdef TILEGX_JIT_DEBUG
- printf("|%04d", inst_buf[i].line);
-#endif
- }
-#ifdef TILEGX_JIT_DEBUG
- if (inst_buf_index == 3)
- printf("|M0|:\t");
- else
- printf("|M0|:\t\t");
- print_insn_tilegx(&bits);
-#endif
-
- inst_buf_index = 0;
-
-#ifdef TILEGX_JIT_DEBUG
- return push_inst_nodebug(compiler, bits);
-#else
- return push_inst(compiler, bits);
-#endif
- }
-
- /* If the bundle is invalid, split it in two. First encode the first two
- (or possibly 1) instructions, and then the last, separately. Note that
- assign_pipes may have re-ordered the instrs (by inserting no-ops in
- lower slots) so we need to reset them. */
-
- inst_buf_index = orig_index - 1;
- inst_buf[0] = inst0;
- inst_buf[1] = inst1;
- inst_buf[2] = inst2;
- if (assign_pipes() == 0) {
- for (i = 0; i < inst_buf_index; i++) {
- bits |= get_bundle_bit(inst_buf + i);
-#ifdef TILEGX_JIT_DEBUG
- printf("|%04d", inst_buf[i].line);
-#endif
- }
-
-#ifdef TILEGX_JIT_DEBUG
- if (inst_buf_index == 3)
- printf("|M1|:\t");
- else
- printf("|M1|:\t\t");
- print_insn_tilegx(&bits);
-#endif
-
- if ((orig_index - 1) == 2) {
- inst_buf[0] = inst2;
- inst_buf_index = 1;
- } else if ((orig_index - 1) == 1) {
- inst_buf[0] = inst1;
- inst_buf_index = 1;
- } else
- SLJIT_UNREACHABLE();
-
-#ifdef TILEGX_JIT_DEBUG
- return push_inst_nodebug(compiler, bits);
-#else
- return push_inst(compiler, bits);
-#endif
- } else {
- /* We had 3 instrs of which the first 2 can't live in the same bundle.
- Split those two. Note that we don't try to then combine the second
- and third instr into a single bundle. First instruction: */
- inst_buf_index = 1;
- inst_buf[0] = inst0;
- inst_buf[1] = inst1;
- inst_buf[2] = inst2;
- if (assign_pipes() == 0) {
- for (i = 0; i < inst_buf_index; i++) {
- bits |= get_bundle_bit(inst_buf + i);
-#ifdef TILEGX_JIT_DEBUG
- printf("|%04d", inst_buf[i].line);
-#endif
- }
-
-#ifdef TILEGX_JIT_DEBUG
- if (inst_buf_index == 3)
- printf("|M2|:\t");
- else
- printf("|M2|:\t\t");
- print_insn_tilegx(&bits);
-#endif
-
- inst_buf[0] = inst1;
- inst_buf[1] = inst2;
- inst_buf_index = orig_index - 1;
-#ifdef TILEGX_JIT_DEBUG
- return push_inst_nodebug(compiler, bits);
-#else
- return push_inst(compiler, bits);
-#endif
- } else
- SLJIT_UNREACHABLE();
- }
-
- SLJIT_UNREACHABLE();
-}
-
-static sljit_s32 flush_buffer(struct sljit_compiler *compiler)
-{
- while (inst_buf_index != 0) {
- FAIL_IF(update_buffer(compiler));
- }
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].operand_value[0] = op0;
- inst_buf[inst_buf_index].operand_value[1] = op1;
- inst_buf[inst_buf_index].operand_value[2] = op2;
- inst_buf[inst_buf_index].operand_value[3] = op3;
- inst_buf[inst_buf_index].input_registers = 1L << op1;
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- inst_buf[inst_buf_index].line = line;
- inst_buf_index++;
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].operand_value[0] = op0;
- inst_buf[inst_buf_index].operand_value[1] = op1;
- inst_buf[inst_buf_index].operand_value[2] = op2;
- inst_buf[inst_buf_index].line = line;
-
- switch (opc) {
- case TILEGX_OPC_ST_ADD:
- inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- break;
- case TILEGX_OPC_LD_ADD:
- inst_buf[inst_buf_index].input_registers = 1L << op1;
- inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1);
- break;
- case TILEGX_OPC_ADD:
- case TILEGX_OPC_AND:
- case TILEGX_OPC_SUB:
- case TILEGX_OPC_MULX:
- case TILEGX_OPC_OR:
- case TILEGX_OPC_XOR:
- case TILEGX_OPC_NOR:
- case TILEGX_OPC_SHL:
- case TILEGX_OPC_SHRU:
- case TILEGX_OPC_SHRS:
- case TILEGX_OPC_CMPLTU:
- case TILEGX_OPC_CMPLTS:
- case TILEGX_OPC_CMOVEQZ:
- case TILEGX_OPC_CMOVNEZ:
- inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2);
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- break;
- case TILEGX_OPC_ADDLI:
- case TILEGX_OPC_XORI:
- case TILEGX_OPC_ORI:
- case TILEGX_OPC_SHLI:
- case TILEGX_OPC_SHRUI:
- case TILEGX_OPC_SHRSI:
- case TILEGX_OPC_SHL16INSLI:
- case TILEGX_OPC_CMPLTUI:
- case TILEGX_OPC_CMPLTSI:
- inst_buf[inst_buf_index].input_registers = 1L << op1;
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- break;
- default:
- printf("unrecoginzed opc: %s\n", opcode->name);
- SLJIT_UNREACHABLE();
- }
-
- inst_buf_index++;
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].operand_value[0] = op0;
- inst_buf[inst_buf_index].operand_value[1] = op1;
- inst_buf[inst_buf_index].line = line;
-
- switch (opc) {
- case TILEGX_OPC_BEQZ:
- case TILEGX_OPC_BNEZ:
- inst_buf[inst_buf_index].input_registers = 1L << op0;
- break;
- case TILEGX_OPC_ST:
- case TILEGX_OPC_ST1:
- case TILEGX_OPC_ST2:
- case TILEGX_OPC_ST4:
- inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);
- inst_buf[inst_buf_index].output_registers = 0;
- break;
- case TILEGX_OPC_CLZ:
- case TILEGX_OPC_LD:
- case TILEGX_OPC_LD1U:
- case TILEGX_OPC_LD1S:
- case TILEGX_OPC_LD2U:
- case TILEGX_OPC_LD2S:
- case TILEGX_OPC_LD4U:
- case TILEGX_OPC_LD4S:
- inst_buf[inst_buf_index].input_registers = 1L << op1;
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- break;
- default:
- printf("unrecoginzed opc: %s\n", opcode->name);
- SLJIT_UNREACHABLE();
- }
-
- inst_buf_index++;
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].input_registers = 0;
- inst_buf[inst_buf_index].output_registers = 0;
- inst_buf[inst_buf_index].line = line;
- inst_buf_index++;
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].operand_value[0] = op0;
- inst_buf[inst_buf_index].input_registers = 1L << op0;
- inst_buf[inst_buf_index].output_registers = 0;
- inst_buf[inst_buf_index].line = line;
- inst_buf_index++;
-
- return flush_buffer(compiler);
-}
-
-static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
-{
- sljit_sw diff;
- sljit_uw target_addr;
- sljit_ins *inst;
-
- if (jump->flags & SLJIT_REWRITABLE_JUMP)
- return code_ptr;
-
- if (jump->flags & JUMP_ADDR)
- target_addr = jump->u.target;
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- target_addr = (sljit_uw)(code + jump->u.label->size);
- }
-
- inst = (sljit_ins *)jump->addr;
- if (jump->flags & IS_COND)
- inst--;
-
- diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3;
- if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) {
- jump->flags |= PATCH_B;
-
- if (!(jump->flags & IS_COND)) {
- if (jump->flags & IS_JAL) {
- jump->flags &= ~(PATCH_B);
- jump->flags |= PATCH_J;
- inst[0] = JAL_X1;
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
- } else {
- inst[0] = BEQZ_X1 | SRCA_X1(ZERO);
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
- }
-
- return inst;
- }
-
- inst[0] = inst[0] ^ (0x7L << 55);
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
- jump->addr -= sizeof(sljit_ins);
- return inst;
- }
-
- if (jump->flags & IS_COND) {
- if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {
- jump->flags |= PATCH_J;
- inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2);
- inst[1] = J_X1;
- return inst + 1;
- }
-
- return code_ptr;
- }
-
- if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {
- jump->flags |= PATCH_J;
-
- if (jump->flags & IS_JAL) {
- inst[0] = JAL_X1;
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
-
- } else {
- inst[0] = J_X1;
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
- }
-
- return inst;
- }
-
- return code_ptr;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_ins *code;
- sljit_ins *code_ptr;
- sljit_ins *buf_ptr;
- sljit_ins *buf_end;
- sljit_uw word_count;
- sljit_uw addr;
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
- code_ptr = code;
- word_count = 0;
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- do {
- buf_ptr = (sljit_ins *)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 3);
- do {
- *code_ptr = *buf_ptr++;
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- /* Just recording the address. */
- label->addr = (sljit_uw) code_ptr;
- label->size = code_ptr - code;
- label = label->next;
- }
-
- if (jump && jump->addr == word_count) {
- if (jump->flags & IS_JAL)
- jump->addr = (sljit_uw)(code_ptr - 4);
- else
- jump->addr = (sljit_uw)(code_ptr - 3);
-
- code_ptr = detect_jump_type(jump, code_ptr, code);
- jump = jump->next;
- }
-
- if (const_ && const_->addr == word_count) {
- /* Just recording the address. */
- const_->addr = (sljit_uw) code_ptr;
- const_ = const_->next;
- }
-
- code_ptr++;
- word_count++;
- } while (buf_ptr < buf_end);
-
- buf = buf->next;
- } while (buf);
-
- if (label && label->size == word_count) {
- label->addr = (sljit_uw) code_ptr;
- label->size = code_ptr - code;
- label = label->next;
- }
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
-
- jump = compiler->jumps;
- while (jump) {
- do {
- addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
- buf_ptr = (sljit_ins *)jump->addr;
-
- if (jump->flags & PATCH_B) {
- addr = (sljit_sw)(addr - (jump->addr)) >> 3;
- SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN);
- buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr);
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(buf_ptr);
-#endif
- break;
- }
-
- if (jump->flags & PATCH_J) {
- SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL));
- addr = (sljit_sw)(addr - (jump->addr)) >> 3;
- buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr);
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(buf_ptr);
-#endif
- break;
- }
-
- SLJIT_ASSERT(!(jump->flags & IS_JAL));
-
- /* Set the fields of immediate loads. */
- buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43);
- buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43);
- buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43);
- } while (0);
-
- jump = jump->next;
- }
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
- SLJIT_CACHE_FLUSH(code, code_ptr);
- return code;
-}
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
-{
-
- if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN)
- return ADDLI(dst_ar, ZERO, imm);
-
- if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) {
- FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16));
- return SHL16INSLI(dst_ar, dst_ar, imm);
- }
-
- if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) {
- FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));
- FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
- return SHL16INSLI(dst_ar, dst_ar, imm);
- }
-
- FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48));
- FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32));
- FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
- return SHL16INSLI(dst_ar, dst_ar, imm);
-}
-
-static sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush)
-{
- /* Should *not* be optimized as load_immediate, as pcre relocation
- mechanism will match this fixed 4-instruction pattern. */
- if (flush) {
- FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32));
- FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16));
- return SHL16INSLI_SOLO(dst_ar, dst_ar, imm);
- }
-
- FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));
- FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
- return SHL16INSLI(dst_ar, dst_ar, imm);
-}
-
-static sljit_s32 emit_const_64(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush)
-{
- /* Should *not* be optimized as load_immediate, as pcre relocation
- mechanism will match this fixed 4-instruction pattern. */
- if (flush) {
- FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48));
- FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));
- FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));
- return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm);
- }
-
- FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48));
- FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));
- FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));
- return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_ins base;
- sljit_s32 i, tmp;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
- local_size = (local_size + 7) & ~7;
- compiler->local_size = local_size;
-
- if (local_size <= SIMM_16BIT_MAX) {
- /* Frequent case. */
- FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size));
- base = SLJIT_LOCALS_REG_mapped;
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));
- FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO));
- FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));
- base = TMP_REG2_mapped;
- local_size = 0;
- }
-
- /* Save the return address. */
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8));
-
- /* Save the S registers. */
- tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
- for (i = SLJIT_S0; i >= tmp; i--) {
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
- }
-
- /* Save the R registers that need to be reserved. */
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
- }
-
- /* Move the arguments to S registers. */
- for (i = 0; i < args; i++) {
- FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO));
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
- compiler->local_size = (local_size + 7) & ~7;
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 local_size;
- sljit_ins base;
- sljit_s32 i, tmp;
- sljit_s32 saveds;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_return(compiler, op, src, srcw));
-
- FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
-
- local_size = compiler->local_size;
- if (local_size <= SIMM_16BIT_MAX)
- base = SLJIT_LOCALS_REG_mapped;
- else {
- FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));
- FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));
- base = TMP_REG1_mapped;
- local_size = 0;
- }
-
- /* Restore the return address. */
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
- FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8));
-
- /* Restore the S registers. */
- saveds = compiler->saveds;
- tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
- for (i = SLJIT_S0; i >= tmp; i--) {
- FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
- }
-
- /* Restore the R registers that need to be reserved. */
- for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
- }
-
- if (compiler->local_size <= SIMM_16BIT_MAX)
- FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size));
- else
- FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO));
-
- return JR(RA);
-}
-
-/* reg_ar is an absoulute register! */
-
-/* Can perform an operation using at most 1 instruction. */
-static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
-{
- SLJIT_ASSERT(arg & SLJIT_MEM);
-
- if ((!(flags & WRITE_BACK) || !(arg & REG_MASK))
- && !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
- /* Works for both absoulte and relative addresses. */
- if (SLJIT_UNLIKELY(flags & ARG_TEST))
- return 1;
-
- FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw));
-
- if (flags & LOAD_DATA)
- FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
- else
- FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
-
- return -1;
- }
-
- return 0;
-}
-
-/* See getput_arg below.
- Note: can_cache is called only for binary operators. Those
- operators always uses word arguments without write back. */
-static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
- SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
-
- /* Simple operation except for updates. */
- if (arg & OFFS_REG_MASK) {
- argw &= 0x3;
- next_argw &= 0x3;
- if (argw && argw == next_argw
- && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
- return 1;
- return 0;
- }
-
- if (arg == next_arg) {
- if (((next_argw - argw) <= SIMM_16BIT_MAX
- && (next_argw - argw) >= SIMM_16BIT_MIN))
- return 1;
-
- return 0;
- }
-
- return 0;
-}
-
-/* Emit the necessary instructions. See can_cache above. */
-static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
- sljit_s32 tmp_ar, base;
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
- if (!(next_arg & SLJIT_MEM)) {
- next_arg = 0;
- next_argw = 0;
- }
-
- if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))
- tmp_ar = reg_ar;
- else
- tmp_ar = TMP_REG1_mapped;
-
- base = arg & REG_MASK;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
-
- if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) {
- SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar);
- FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
- reg_ar = TMP_REG1_mapped;
- }
-
- /* Using the cache. */
- if (argw == compiler->cache_argw) {
- if (!(flags & WRITE_BACK)) {
- if (arg == compiler->cache_arg) {
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
- if (arg == next_arg && argw == (next_argw & 0x3)) {
- compiler->cache_arg = arg;
- compiler->cache_argw = argw;
- FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped));
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped));
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
- }
- } else {
- if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
- FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
- }
- }
- }
-
- if (SLJIT_UNLIKELY(argw)) {
- compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
- compiler->cache_argw = argw;
- FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw));
- }
-
- if (!(flags & WRITE_BACK)) {
- if (arg == next_arg && argw == (next_argw & 0x3)) {
- compiler->cache_arg = arg;
- compiler->cache_argw = argw;
- FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
- tmp_ar = TMP_REG3_mapped;
- } else
- FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
- }
-
- FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
- }
-
- if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
- /* Update only applies if a base register exists. */
- if (reg_ar == reg_map[base]) {
- SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar);
- if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
- FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw));
- if (flags & LOAD_DATA)
- FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
- else
- FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
-
- if (argw)
- return ADDLI(reg_map[base], reg_map[base], argw);
-
- return SLJIT_SUCCESS;
- }
-
- FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
- reg_ar = TMP_REG1_mapped;
- }
-
- if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
- if (argw)
- FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw));
- } else {
- if (compiler->cache_arg == SLJIT_MEM
- && argw - compiler->cache_argw <= SIMM_16BIT_MAX
- && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
- if (argw != compiler->cache_argw) {
- FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
- compiler->cache_argw = argw;
- }
-
- FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
- } else {
- compiler->cache_arg = SLJIT_MEM;
- compiler->cache_argw = argw;
- FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
- FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
- }
- }
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
- }
-
- if (compiler->cache_arg == arg
- && argw - compiler->cache_argw <= SIMM_16BIT_MAX
- && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
- if (argw != compiler->cache_argw) {
- FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
- compiler->cache_argw = argw;
- }
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- if (compiler->cache_arg == SLJIT_MEM
- && argw - compiler->cache_argw <= SIMM_16BIT_MAX
- && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
- if (argw != compiler->cache_argw)
- FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
- } else {
- compiler->cache_arg = SLJIT_MEM;
- FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
- }
-
- compiler->cache_argw = argw;
-
- if (!base) {
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- if (arg == next_arg
- && next_argw - argw <= SIMM_16BIT_MAX
- && next_argw - argw >= SIMM_16BIT_MIN) {
- compiler->cache_arg = arg;
- FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base]));
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base]));
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
-{
- if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
- return compiler->error;
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
- return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
-{
- if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
- return compiler->error;
- return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- /* For UNUSED dst. Uncommon, but possible. */
- if (dst == SLJIT_UNUSED)
- return SLJIT_SUCCESS;
-
- if (FAST_IS_REG(dst))
- return ADD(reg_map[dst], RA, ZERO);
-
- /* Memory. */
- return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- if (FAST_IS_REG(src))
- FAIL_IF(ADD(RA, reg_map[src], ZERO));
-
- else if (src & SLJIT_MEM)
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw));
-
- else if (src & SLJIT_IMM)
- FAIL_IF(load_immediate(compiler, RA, srcw));
-
- return JR(RA);
-}
-
-static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
-{
- sljit_s32 overflow_ra = 0;
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (dst != src2)
- return ADD(reg_map[dst], reg_map[src2], ZERO);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S32)
- return BFEXTS(reg_map[dst], reg_map[src2], 0, 31);
-
- return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);
- } else if (dst != src2) {
- SLJIT_ASSERT(src2 == 0);
- return ADD(reg_map[dst], reg_map[src2], ZERO);
- }
-
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S8)
- return BFEXTS(reg_map[dst], reg_map[src2], 0, 7);
-
- return BFEXTU(reg_map[dst], reg_map[src2], 0, 7);
- } else if (dst != src2) {
- SLJIT_ASSERT(src2 == 0);
- return ADD(reg_map[dst], reg_map[src2], ZERO);
- }
-
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U16:
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S16)
- return BFEXTS(reg_map[dst], reg_map[src2], 0, 15);
-
- return BFEXTU(reg_map[dst], reg_map[src2], 0, 15);
- } else if (dst != src2) {
- SLJIT_ASSERT(src2 == 0);
- return ADD(reg_map[dst], reg_map[src2], ZERO);
- }
-
- return SLJIT_SUCCESS;
-
- case SLJIT_NOT:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (op & SLJIT_SET_E)
- FAIL_IF(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2]));
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2]));
-
- return SLJIT_SUCCESS;
-
- case SLJIT_CLZ:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (op & SLJIT_SET_E)
- FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2]));
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(CLZ(reg_map[dst], reg_map[src2]));
-
- return SLJIT_SUCCESS;
-
- case SLJIT_ADD:
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_O) {
- FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63));
- if (src2 < 0)
- FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));
- }
-
- if (op & SLJIT_SET_E)
- FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2));
-
- if (op & SLJIT_SET_C) {
- if (src2 >= 0)
- FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2));
- else {
- FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2));
- FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG));
- }
- }
-
- /* dst may be the same as src1 or src2. */
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));
-
- if (op & SLJIT_SET_O) {
- FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63));
-
- if (src2 < 0)
- FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1));
- }
- } else {
- if (op & SLJIT_SET_O) {
- FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));
- FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));
-
- if (src1 != dst)
- overflow_ra = reg_map[src1];
- else if (src2 != dst)
- overflow_ra = reg_map[src2];
- else {
- /* Rare ocasion. */
- FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
- overflow_ra = TMP_EREG2;
- }
- }
-
- if (op & SLJIT_SET_E)
- FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2]));
-
- if (op & SLJIT_SET_C)
- FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2]));
-
- /* dst may be the same as src1 or src2. */
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2]));
-
- if (op & SLJIT_SET_O) {
- FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra));
- FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));
- }
- }
-
- /* a + b >= a | b (otherwise, the carry should be set to 1). */
- if (op & SLJIT_SET_C)
- FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG));
-
- if (op & SLJIT_SET_O)
- return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);
-
- return SLJIT_SUCCESS;
-
- case SLJIT_ADDC:
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_C) {
- if (src2 >= 0)
- FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2));
- else {
- FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2));
- FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1));
- }
- }
-
- FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));
-
- } else {
- if (op & SLJIT_SET_C)
- FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2]));
-
- /* dst may be the same as src1 or src2. */
- FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2]));
- }
-
- if (op & SLJIT_SET_C)
- FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1));
-
- FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG));
-
- if (!(op & SLJIT_SET_C))
- return SLJIT_SUCCESS;
-
- /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
- FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1));
- FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG));
- /* Set carry flag. */
- return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1);
-
- case SLJIT_SUB:
- if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) {
- FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_O) {
- FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63));
-
- if (src2 < 0)
- FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));
-
- if (src1 != dst)
- overflow_ra = reg_map[src1];
- else {
- /* Rare ocasion. */
- FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
- overflow_ra = TMP_EREG2;
- }
- }
-
- if (op & SLJIT_SET_E)
- FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2));
-
- if (op & SLJIT_SET_C) {
- FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2));
- FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped));
- }
-
- /* dst may be the same as src1 or src2. */
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));
-
- } else {
-
- if (op & SLJIT_SET_O) {
- FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));
- FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));
-
- if (src1 != dst)
- overflow_ra = reg_map[src1];
- else {
- /* Rare ocasion. */
- FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
- overflow_ra = TMP_EREG2;
- }
- }
-
- if (op & SLJIT_SET_E)
- FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2]));
-
- if (op & (SLJIT_SET_U | SLJIT_SET_C))
- FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2]));
-
- if (op & SLJIT_SET_U)
- FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1]));
-
- if (op & SLJIT_SET_S) {
- FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2]));
- FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1]));
- }
-
- /* dst may be the same as src1 or src2. */
- if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
- FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
- }
-
- if (op & SLJIT_SET_O) {
- FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra));
- FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));
- return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);
- }
-
- return SLJIT_SUCCESS;
-
- case SLJIT_SUBC:
- if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) {
- FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_C) {
- FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2));
- FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped));
- }
-
- /* dst may be the same as src1 or src2. */
- FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));
-
- } else {
- if (op & SLJIT_SET_C)
- FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2]));
- /* dst may be the same as src1 or src2. */
- FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
- }
-
- if (op & SLJIT_SET_C)
- FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG));
-
- FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG));
-
- if (op & SLJIT_SET_C)
- FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO));
-
- return SLJIT_SUCCESS;
-
- case SLJIT_MUL:
- if (flags & SRC2_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2]));
-
- return SLJIT_SUCCESS;
-
-#define EMIT_LOGICAL(op_imm, op_norm) \
- if (flags & SRC2_IMM) { \
- FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \
- if (op & SLJIT_SET_E) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
- ADDR_TMP_mapped, __LINE__)); \
- if (CHECK_FLAGS(SLJIT_SET_E)) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, reg_map[dst], reg_map[src1], \
- ADDR_TMP_mapped, __LINE__)); \
- } else { \
- if (op & SLJIT_SET_E) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
- reg_map[src2], __LINE__)); \
- if (CHECK_FLAGS(SLJIT_SET_E)) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, reg_map[dst], reg_map[src1], \
- reg_map[src2], __LINE__)); \
- }
-
- case SLJIT_AND:
- EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND);
- return SLJIT_SUCCESS;
-
- case SLJIT_OR:
- EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR);
- return SLJIT_SUCCESS;
-
- case SLJIT_XOR:
- EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR);
- return SLJIT_SUCCESS;
-
-#define EMIT_SHIFT(op_imm, op_norm) \
- if (flags & SRC2_IMM) { \
- if (op & SLJIT_SET_E) \
- FAIL_IF(push_3_buffer( \
- compiler, op_imm, EQUAL_FLAG, reg_map[src1], \
- src2 & 0x3F, __LINE__)); \
- if (CHECK_FLAGS(SLJIT_SET_E)) \
- FAIL_IF(push_3_buffer( \
- compiler, op_imm, reg_map[dst], reg_map[src1], \
- src2 & 0x3F, __LINE__)); \
- } else { \
- if (op & SLJIT_SET_E) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
- reg_map[src2], __LINE__)); \
- if (CHECK_FLAGS(SLJIT_SET_E)) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, reg_map[dst], reg_map[src1], \
- reg_map[src2], __LINE__)); \
- }
-
- case SLJIT_SHL:
- EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL);
- return SLJIT_SUCCESS;
-
- case SLJIT_LSHR:
- EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU);
- return SLJIT_SUCCESS;
-
- case SLJIT_ASHR:
- EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS);
- return SLJIT_SUCCESS;
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
-{
- /* arg1 goes to TMP_REG1 or src reg.
- arg2 goes to TMP_REG2, imm or src reg.
- TMP_REG3 can be used for caching.
- result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
- sljit_s32 dst_r = TMP_REG2;
- sljit_s32 src1_r;
- sljit_sw src2_r = 0;
- sljit_s32 sugg_src2_r = TMP_REG2;
-
- if (!(flags & ALT_KEEP_CACHE)) {
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
- }
-
- if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
- if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
- return SLJIT_SUCCESS;
- if (GET_FLAGS(op))
- flags |= UNUSED_DEST;
- } else if (FAST_IS_REG(dst)) {
- dst_r = dst;
- flags |= REG_DEST;
- if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
- sugg_src2_r = dst_r;
- } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw))
- flags |= SLOW_DEST;
-
- if (flags & IMM_OP) {
- if ((src2 & SLJIT_IMM) && src2w) {
- if ((!(flags & LOGICAL_OP)
- && (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN))
- || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) {
- flags |= SRC2_IMM;
- src2_r = src2w;
- }
- }
-
- if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
- if ((!(flags & LOGICAL_OP)
- && (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN))
- || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) {
- flags |= SRC2_IMM;
- src2_r = src1w;
-
- /* And swap arguments. */
- src1 = src2;
- src1w = src2w;
- src2 = SLJIT_IMM;
- /* src2w = src2_r unneeded. */
- }
- }
- }
-
- /* Source 1. */
- if (FAST_IS_REG(src1)) {
- src1_r = src1;
- flags |= REG1_SOURCE;
- } else if (src1 & SLJIT_IMM) {
- if (src1w) {
- FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w));
- src1_r = TMP_REG1;
- } else
- src1_r = 0;
- } else {
- if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w))
- FAIL_IF(compiler->error);
- else
- flags |= SLOW_SRC1;
- src1_r = TMP_REG1;
- }
-
- /* Source 2. */
- if (FAST_IS_REG(src2)) {
- src2_r = src2;
- flags |= REG2_SOURCE;
- if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
- dst_r = src2_r;
- } else if (src2 & SLJIT_IMM) {
- if (!(flags & SRC2_IMM)) {
- if (src2w) {
- FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w));
- src2_r = sugg_src2_r;
- } else {
- src2_r = 0;
- if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
- dst_r = 0;
- }
- }
- } else {
- if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w))
- FAIL_IF(compiler->error);
- else
- flags |= SLOW_SRC2;
- src2_r = sugg_src2_r;
- }
-
- if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
- SLJIT_ASSERT(src2_r == TMP_REG2);
- if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, src1, src1w));
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));
- } else {
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w));
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw));
- }
- } else if (flags & SLOW_SRC1)
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));
- else if (flags & SLOW_SRC2)
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w, dst, dstw));
-
- FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
-
- if (dst & SLJIT_MEM) {
- if (!(flags & SLOW_DEST)) {
- getput_arg_fast(compiler, flags, reg_map[dst_r], dst, dstw);
- return compiler->error;
- }
-
- return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw, sljit_s32 type)
-{
- sljit_s32 sugg_dst_ar, dst_ar;
- sljit_s32 flags = GET_ALL_FLAGS(op);
- sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- op = GET_OPCODE(op);
- if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32)
- mem_type = INT_DATA | SIGNED_DATA;
- sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2];
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
- if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw));
- src = TMP_REG1;
- srcw = 0;
- }
-
- switch (type & 0xff) {
- case SLJIT_EQUAL:
- case SLJIT_NOT_EQUAL:
- FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1));
- dst_ar = sugg_dst_ar;
- break;
- case SLJIT_LESS:
- case SLJIT_GREATER_EQUAL:
- dst_ar = ULESS_FLAG;
- break;
- case SLJIT_GREATER:
- case SLJIT_LESS_EQUAL:
- dst_ar = UGREATER_FLAG;
- break;
- case SLJIT_SIG_LESS:
- case SLJIT_SIG_GREATER_EQUAL:
- dst_ar = LESS_FLAG;
- break;
- case SLJIT_SIG_GREATER:
- case SLJIT_SIG_LESS_EQUAL:
- dst_ar = GREATER_FLAG;
- break;
- case SLJIT_OVERFLOW:
- case SLJIT_NOT_OVERFLOW:
- dst_ar = OVERFLOW_FLAG;
- break;
- case SLJIT_MUL_OVERFLOW:
- case SLJIT_MUL_NOT_OVERFLOW:
- FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1));
- dst_ar = sugg_dst_ar;
- type ^= 0x1; /* Flip type bit for the XORI below. */
- break;
-
- default:
- SLJIT_UNREACHABLE();
- dst_ar = sugg_dst_ar;
- break;
- }
-
- if (type & 0x1) {
- FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1));
- dst_ar = sugg_dst_ar;
- }
-
- if (op >= SLJIT_ADD) {
- if (TMP_REG2_mapped != dst_ar)
- FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO));
- return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
- }
-
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);
-
- if (sugg_dst_ar != dst_ar)
- return ADD(sugg_dst_ar, dst_ar, ZERO);
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) {
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- op = GET_OPCODE(op);
- switch (op) {
- case SLJIT_NOP:
- return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__);
-
- case SLJIT_BREAKPOINT:
- return PI(BPT);
-
- case SLJIT_LMUL_UW:
- case SLJIT_LMUL_SW:
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
- SLJIT_UNREACHABLE();
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOV_U32:
- return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOV_S32:
- return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOV_U8:
- return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw);
-
- case SLJIT_MOV_S8:
- return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw);
-
- case SLJIT_MOV_U16:
- return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw);
-
- case SLJIT_MOV_S16:
- return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw);
-
- case SLJIT_MOVU:
- case SLJIT_MOVU_P:
- return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOVU_U32:
- return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOVU_S32:
- return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOVU_U8:
- return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw);
-
- case SLJIT_MOVU_S8:
- return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw);
-
- case SLJIT_MOVU_U16:
- return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw);
-
- case SLJIT_MOVU_S16:
- return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw);
-
- case SLJIT_NOT:
- return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_NEG:
- return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
-
- case SLJIT_CLZ:
- return emit_op(compiler, op, (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- case SLJIT_ADDC:
- return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SUB:
- case SLJIT_SUBC:
- return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_MUL:
- return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SHL:
- case SLJIT_LSHR:
- case SLJIT_ASHR:
- if (src2 & SLJIT_IMM)
- src2w &= 0x3f;
- if (op & SLJIT_I32_OP)
- src2w &= 0x1f;
-
- return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- flush_buffer(compiler);
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label *)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- return label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 src_r = TMP_REG2;
- struct sljit_jump *jump = NULL;
-
- flush_buffer(compiler);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- if (FAST_IS_REG(src)) {
- if (reg_map[src] != 0)
- src_r = src;
- else
- FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO));
- }
-
- if (type >= SLJIT_CALL0) {
- SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
- if (src & (SLJIT_IMM | SLJIT_MEM)) {
- if (src & SLJIT_IMM)
- FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1));
- else {
- SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
- FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
- }
-
- FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
-
- FAIL_IF(ADDI_SOLO(54, 54, -16));
-
- FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG]));
-
- return ADDI_SOLO(54, 54, 16);
- }
-
- /* Register input. */
- if (type >= SLJIT_CALL1)
- FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
-
- FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO));
-
- FAIL_IF(ADDI_SOLO(54, 54, -16));
-
- FAIL_IF(JALR_SOLO(reg_map[src_r]));
-
- return ADDI_SOLO(54, 54, 16);
- }
-
- if (src & SLJIT_IMM) {
- jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
- jump->u.target = srcw;
- FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));
-
- if (type >= SLJIT_FAST_CALL) {
- FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO));
- jump->addr = compiler->size;
- FAIL_IF(JR_SOLO(reg_map[src_r]));
- } else {
- jump->addr = compiler->size;
- FAIL_IF(JR_SOLO(reg_map[src_r]));
- }
-
- return SLJIT_SUCCESS;
-
- } else if (src & SLJIT_MEM) {
- FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
- flush_buffer(compiler);
- }
-
- FAIL_IF(JR_SOLO(reg_map[src_r]));
-
- if (jump)
- jump->addr = compiler->size;
-
- return SLJIT_SUCCESS;
-}
-
-#define BR_Z(src) \
- inst = BEQZ_X1 | SRCA_X1(src); \
- flags = IS_COND;
-
-#define BR_NZ(src) \
- inst = BNEZ_X1 | SRCA_X1(src); \
- flags = IS_COND;
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- struct sljit_jump *jump;
- sljit_ins inst;
- sljit_s32 flags = 0;
-
- flush_buffer(compiler);
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- switch (type) {
- case SLJIT_EQUAL:
- BR_NZ(EQUAL_FLAG);
- break;
- case SLJIT_NOT_EQUAL:
- BR_Z(EQUAL_FLAG);
- break;
- case SLJIT_LESS:
- BR_Z(ULESS_FLAG);
- break;
- case SLJIT_GREATER_EQUAL:
- BR_NZ(ULESS_FLAG);
- break;
- case SLJIT_GREATER:
- BR_Z(UGREATER_FLAG);
- break;
- case SLJIT_LESS_EQUAL:
- BR_NZ(UGREATER_FLAG);
- break;
- case SLJIT_SIG_LESS:
- BR_Z(LESS_FLAG);
- break;
- case SLJIT_SIG_GREATER_EQUAL:
- BR_NZ(LESS_FLAG);
- break;
- case SLJIT_SIG_GREATER:
- BR_Z(GREATER_FLAG);
- break;
- case SLJIT_SIG_LESS_EQUAL:
- BR_NZ(GREATER_FLAG);
- break;
- case SLJIT_OVERFLOW:
- case SLJIT_MUL_OVERFLOW:
- BR_Z(OVERFLOW_FLAG);
- break;
- case SLJIT_NOT_OVERFLOW:
- case SLJIT_MUL_NOT_OVERFLOW:
- BR_NZ(OVERFLOW_FLAG);
- break;
- default:
- /* Not conditional branch. */
- inst = 0;
- break;
- }
-
- jump->flags |= flags;
-
- if (inst) {
- inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6));
- PTR_FAIL_IF(PI(inst));
- }
-
- PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));
- if (type <= SLJIT_JUMP) {
- jump->addr = compiler->size;
- PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped));
- } else {
- SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
- /* Cannot be optimized out if type is >= CALL0. */
- jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);
- PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
- jump->addr = compiler->size;
- PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped));
- }
-
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
-{
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_const *const_;
- sljit_s32 reg;
-
- flush_buffer(compiler);
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const));
- PTR_FAIL_IF(!const_);
- set_const(const_, compiler);
-
- reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
- PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1));
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target)
-{
- sljit_ins *inst = (sljit_ins *)addr;
-
- inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_target >> 32) & 0xffff) << 43);
- inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_target >> 16) & 0xffff) << 43);
- inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_target & 0xffff) << 43);
- SLJIT_CACHE_FLUSH(inst, inst + 3);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
-{
- sljit_ins *inst = (sljit_ins *)addr;
-
- inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43);
- inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43);
- inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43);
- inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43);
- SLJIT_CACHE_FLUSH(inst, inst + 4);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_s32 size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
- return SLJIT_ERR_UNSUPPORTED;
-}
-
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
index 34a3a3d940..79a7e8bba5 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
@@ -76,6 +76,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
+ /* Emit ENDBR32 at function entry if needed. */
+ FAIL_IF(emit_endbranch(compiler));
+
args = get_arg_count(arg_types);
compiler->args = args;
@@ -307,14 +310,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
#endif
- size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) +
+ size = 2 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0) +
(compiler->saveds <= 3 ? compiler->saveds : 3);
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
if (compiler->args > 2)
size += 2;
-#else
- if (compiler->args > 0)
- size += 2;
#endif
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
FAIL_IF(!inst);
@@ -367,6 +367,8 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
&& (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
&& (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
+ /* We don't support (%ebp). */
+ SLJIT_ASSERT(!(b & SLJIT_MEM) || immb || reg_map[b & REG_MASK] != 5);
size &= 0xf;
inst_size = size;
@@ -863,14 +865,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
return SLJIT_SUCCESS;
}
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
{
sljit_u8 *inst;
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
CHECK_EXTRA_REGS(src, srcw, (void)0);
if (FAST_IS_REG(src)) {
@@ -894,3 +892,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
RET();
return SLJIT_SUCCESS;
}
+
+static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)
+{
+ sljit_s32 size, saved_size;
+ sljit_s32 has_f64_aligment;
+
+ /* Don't adjust shadow stack if it isn't enabled. */
+ if (!cpu_has_shadow_stack ())
+ return SLJIT_SUCCESS;
+
+ SLJIT_ASSERT(compiler->args >= 0);
+ SLJIT_ASSERT(compiler->local_size > 0);
+
+#if !defined(__APPLE__)
+ has_f64_aligment = compiler->options & SLJIT_F64_ALIGNMENT;
+#else
+ has_f64_aligment = 0;
+#endif
+
+ size = compiler->local_size;
+ saved_size = (1 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0) + (compiler->saveds <= 3 ? compiler->saveds : 3)) * sizeof(sljit_uw);
+ if (has_f64_aligment) {
+ /* mov TMP_REG1, [esp + local_size]. */
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), size);
+ /* mov TMP_REG1, [TMP_REG1+ saved_size]. */
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), saved_size);
+ /* Move return address to [esp]. */
+ EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, TMP_REG1, 0);
+ size = 0;
+ } else
+ size += saved_size;
+
+ return adjust_shadow_stack(compiler, SLJIT_UNUSED, 0, SLJIT_SP, size);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
index 5758711954..e85b56a61a 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
@@ -135,6 +135,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
+ /* Emit ENDBR64 at function entry if needed. */
+ FAIL_IF(emit_endbranch(compiler));
+
compiler->mode32 = 0;
#ifdef _WIN64
@@ -796,14 +799,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
return SLJIT_SUCCESS;
}
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
{
sljit_u8 *inst;
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
if (FAST_IS_REG(src)) {
if (reg_map[src] < 8) {
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
@@ -898,3 +897,22 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign,
return SLJIT_SUCCESS;
}
+
+static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)
+{
+ sljit_s32 tmp, size;
+
+ /* Don't adjust shadow stack if it isn't enabled. */
+ if (!cpu_has_shadow_stack ())
+ return SLJIT_SUCCESS;
+
+ size = compiler->local_size;
+ tmp = compiler->scratches;
+ if (tmp >= SLJIT_FIRST_SAVED_REG)
+ size += (tmp - SLJIT_FIRST_SAVED_REG + 1) * sizeof(sljit_uw);
+ tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
+ if (SLJIT_S0 >= tmp)
+ size += (SLJIT_S0 - tmp + 1) * sizeof(sljit_uw);
+
+ return adjust_shadow_stack(compiler, SLJIT_UNUSED, 0, SLJIT_SP, size);
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
index 6296da5382..ddcc5ebf76 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
@@ -506,7 +506,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
reverse_buf(compiler);
/* Second code generation pass. */
- code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size);
+ code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size, compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -557,7 +557,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(put_label->label);
put_label->addr = (sljit_uw)code_ptr;
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
+ code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size);
#endif
put_label = put_label->next;
break;
@@ -629,7 +629,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
compiler->error = SLJIT_ERR_COMPILED;
compiler->executable_offset = executable_offset;
compiler->executable_size = code_ptr - code;
- return (void*)(code + executable_offset);
+
+ code = (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS(code, (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset), 1);
+ return (void*)code;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
@@ -657,6 +661,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
get_cpu_features();
return cpu_has_cmov;
+ case SLJIT_HAS_PREFETCH:
+ return 1;
+
case SLJIT_HAS_SSE2:
#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
if (cpu_has_sse2 == -1)
@@ -702,6 +709,166 @@ static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,
static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,
sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw);
+static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
+static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler)
+{
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
+ /* Emit endbr32/endbr64 when CET is enabled. */
+ sljit_u8 *inst;
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!inst);
+ INC_SIZE(4);
+ *inst++ = 0xf3;
+ *inst++ = 0x0f;
+ *inst++ = 0x1e;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *inst = 0xfb;
+#else
+ *inst = 0xfa;
+#endif
+#else /* !SLJIT_CONFIG_X86_CET */
+ SLJIT_UNUSED_ARG(compiler);
+#endif /* SLJIT_CONFIG_X86_CET */
+ return SLJIT_SUCCESS;
+}
+
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
+
+static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_s32 reg)
+{
+ sljit_u8 *inst;
+ sljit_s32 size;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ size = 5;
+#else
+ size = 4;
+#endif
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+ INC_SIZE(size);
+ *inst++ = 0xf3;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);
+#endif
+ *inst++ = 0x0f;
+ *inst++ = 0x1e;
+ *inst = (0x3 << 6) | (0x1 << 3) | (reg_map[reg] & 0x7);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit_s32 reg)
+{
+ sljit_u8 *inst;
+ sljit_s32 size;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ size = 5;
+#else
+ size = 4;
+#endif
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!inst);
+ INC_SIZE(size);
+ *inst++ = 0xf3;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);
+#endif
+ *inst++ = 0x0f;
+ *inst++ = 0xae;
+ *inst = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7);
+ return SLJIT_SUCCESS;
+}
+
+#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
+
+static SLJIT_INLINE sljit_s32 cpu_has_shadow_stack(void)
+{
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
+ return _get_ssp() != 0;
+#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */
+ return 0;
+#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
+}
+
+static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compiler,
+ sljit_s32 src, sljit_sw srcw, sljit_s32 base, sljit_sw disp)
+{
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
+ sljit_u8 *inst, *jz_after_cmp_inst;
+ sljit_uw size_jz_after_cmp_inst;
+
+ sljit_uw size_before_rdssp_inst = compiler->size;
+
+ /* Generate "RDSSP TMP_REG1". */
+ FAIL_IF(emit_rdssp(compiler, TMP_REG1));
+
+ /* Load return address on shadow stack into TMP_REG1. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ SLJIT_ASSERT(reg_map[TMP_REG1] == 5);
+
+ /* Hand code unsupported "mov 0x0(%ebp),%ebp". */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
+ FAIL_IF(!inst);
+ INC_SIZE(3);
+ *inst++ = 0x8b;
+ *inst++ = 0x6d;
+ *inst = 0;
+#else /* !SLJIT_CONFIG_X86_32 */
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0);
+#endif /* SLJIT_CONFIG_X86_32 */
+
+ if (src == SLJIT_UNUSED) {
+ /* Return address is on stack. */
+ src = SLJIT_MEM1(base);
+ srcw = disp;
+ }
+
+ /* Compare return address against TMP_REG1. */
+ FAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw));
+
+ /* Generate JZ to skip shadow stack ajdustment when shadow
+ stack matches normal stack. */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!inst);
+ INC_SIZE(2);
+ *inst++ = get_jump_code(SLJIT_EQUAL) - 0x10;
+ size_jz_after_cmp_inst = compiler->size;
+ jz_after_cmp_inst = inst;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ /* REX_W is not necessary. */
+ compiler->mode32 = 1;
+#endif
+ /* Load 1 into TMP_REG1. */
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1);
+
+ /* Generate "INCSSP TMP_REG1". */
+ FAIL_IF(emit_incssp(compiler, TMP_REG1));
+
+ /* Jump back to "RDSSP TMP_REG1" to check shadow stack again. */
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!inst);
+ INC_SIZE(2);
+ *inst++ = JMP_i8;
+ *inst = size_before_rdssp_inst - compiler->size;
+
+ *jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst;
+#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_UNUSED_ARG(base);
+ SLJIT_UNUSED_ARG(disp);
+#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
+ return SLJIT_SUCCESS;
+}
+
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
#include "sljitNativeX86_32.c"
#else
@@ -905,6 +1072,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
#endif
break;
+ case SLJIT_ENDBR:
+ return emit_endbranch(compiler);
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return skip_frames_before_return(compiler);
}
return SLJIT_SUCCESS;
@@ -1074,12 +1245,12 @@ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 op,
*inst++ = GROUP_0F;
*inst++ = PREFETCH;
- if (op >= SLJIT_MOV_U8 && op <= SLJIT_MOV_S8)
- *inst |= (3 << 3);
- else if (op >= SLJIT_MOV_U16 && op <= SLJIT_MOV_S16)
- *inst |= (2 << 3);
- else
+ if (op == SLJIT_PREFETCH_L1)
*inst |= (1 << 3);
+ else if (op == SLJIT_PREFETCH_L2)
+ *inst |= (2 << 3);
+ else if (op == SLJIT_PREFETCH_L3)
+ *inst |= (3 << 3);
return SLJIT_SUCCESS;
}
@@ -1284,12 +1455,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
compiler->mode32 = op_flags & SLJIT_I32_OP;
#endif
- if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
- if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
- return emit_prefetch(compiler, op, src, srcw);
- return SLJIT_SUCCESS;
- }
-
op = GET_OPCODE(op);
if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
@@ -2150,6 +2315,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
if (!HAS_FLAGS(op)) {
if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
return compiler->error;
+ if (SLOW_IS_REG(dst) && src2 == dst) {
+ FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w));
+ return emit_unary(compiler, NEG_rm, dst, 0, dst, 0);
+ }
}
if (dst == SLJIT_UNUSED)
@@ -2186,6 +2355,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
return SLJIT_SUCCESS;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ return emit_fast_return(compiler, src, srcw);
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ /* Don't adjust shadow stack if it isn't enabled. */
+ if (!cpu_has_shadow_stack ())
+ return SLJIT_SUCCESS;
+ return adjust_shadow_stack(compiler, src, srcw, SLJIT_UNUSED, 0);
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+ return emit_prefetch(compiler, op, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
{
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
@@ -2926,15 +3122,21 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 0);
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset);
#else
sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target);
#endif
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 0);
sljit_unaligned_store_sw((void*)addr, new_constant);
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 1);
}
diff --git a/thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c
index 8a5b2b3cfe..147175afa6 100644
--- a/thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c
+++ b/thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c
@@ -70,92 +70,112 @@
struct chunk_header {
void *executable;
- int fd;
};
/*
alloc_chunk / free_chunk :
* allocate executable system memory chunks
* the size is always divisible by CHUNK_SIZE
- allocator_grab_lock / allocator_release_lock :
- * make the allocator thread safe
- * can be empty if the OS (or the application) does not support threading
+ SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
+ * provided as part of sljitUtils
* only the allocator requires this lock, sljit is fully thread safe
as it only uses local variables
*/
+#ifndef __NetBSD__
+#include <sys/stat.h>
#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
#ifndef O_NOATIME
#define O_NOATIME 0
#endif
-#ifdef __O_TMPFILE
+/* this is a linux extension available since kernel 3.11 */
#ifndef O_TMPFILE
-#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-#endif
+#define O_TMPFILE 020200000
#endif
-int mkostemp(char *template, int flags);
+#ifndef _GNU_SOURCE
char *secure_getenv(const char *name);
+int mkostemp(char *template, int flags);
+#endif
static SLJIT_INLINE int create_tempfile(void)
{
int fd;
-
char tmp_name[256];
- size_t tmp_name_len;
+ size_t tmp_name_len = 0;
char *dir;
- size_t len;
-
-#ifdef P_tmpdir
- len = (P_tmpdir != NULL) ? strlen(P_tmpdir) : 0;
+ struct stat st;
+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
+ mode_t mode;
+#endif
- if (len > 0 && len < sizeof(tmp_name)) {
- strcpy(tmp_name, P_tmpdir);
- tmp_name_len = len;
- }
- else {
- strcpy(tmp_name, "/tmp");
- tmp_name_len = 4;
+#ifdef HAVE_MEMFD_CREATE
+ /* this is a GNU extension, make sure to use -D_GNU_SOURCE */
+ fd = memfd_create("sljit", MFD_CLOEXEC);
+ if (fd != -1) {
+ fchmod(fd, 0);
+ return fd;
}
-#else
- strcpy(tmp_name, "/tmp");
- tmp_name_len = 4;
#endif
dir = secure_getenv("TMPDIR");
+
if (dir) {
- len = strlen(dir);
- if (len > 0 && len < sizeof(tmp_name)) {
- strcpy(tmp_name, dir);
- tmp_name_len = len;
+ tmp_name_len = strlen(dir);
+ if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) {
+ if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode))
+ strcpy(tmp_name, dir);
}
}
+#ifdef P_tmpdir
+ if (!tmp_name_len) {
+ tmp_name_len = strlen(P_tmpdir);
+ if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))
+ strcpy(tmp_name, P_tmpdir);
+ }
+#endif
+ if (!tmp_name_len) {
+ strcpy(tmp_name, "/tmp");
+ tmp_name_len = 4;
+ }
+
SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));
- while (tmp_name_len > 0 && tmp_name[tmp_name_len - 1] == '/') {
- tmp_name_len--;
- tmp_name[tmp_name_len] = '\0';
- }
+ if (tmp_name[tmp_name_len - 1] == '/')
+ tmp_name[--tmp_name_len] = '\0';
-#ifdef O_TMPFILE
- fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, S_IRUSR | S_IWUSR);
+#ifdef __linux__
+ /*
+ * the previous trimming might had left an empty string if TMPDIR="/"
+ * so work around the problem below
+ */
+ fd = open(tmp_name_len ? tmp_name : "/",
+ O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0);
if (fd != -1)
return fd;
#endif
if (tmp_name_len + 7 >= sizeof(tmp_name))
- {
return -1;
- }
strcpy(tmp_name + tmp_name_len, "/XXXXXX");
+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
+ mode = umask(0777);
+#endif
fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME);
+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
+ umask(mode);
+#else
+ fchmod(fd, 0);
+#endif
if (fd == -1)
- return fd;
+ return -1;
if (unlink(tmp_name)) {
close(fd);
@@ -189,23 +209,52 @@ static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
if (retval->executable == MAP_FAILED) {
- munmap(retval, size);
+ munmap((void *)retval, size);
close(fd);
return NULL;
}
- retval->fd = fd;
+ close(fd);
return retval;
}
+#else
+/*
+ * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to
+ * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed
+ */
+static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
+{
+ struct chunk_header *retval;
+
+ retval = (struct chunk_header *)mmap(NULL, size,
+ PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC),
+ MAP_ANON | MAP_SHARED, -1, 0);
+
+ if (retval == MAP_FAILED)
+ return NULL;
+
+ retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP);
+ if (retval->executable == MAP_FAILED) {
+ munmap((void *)retval, size);
+ return NULL;
+ }
+
+ if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) {
+ munmap(retval->executable, size);
+ munmap((void *)retval, size);
+ return NULL;
+ }
+
+ return retval;
+}
+#endif /* NetBSD */
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
struct chunk_header *header = ((struct chunk_header *)chunk) - 1;
- int fd = header->fd;
munmap(header->executable, size);
- munmap(header, size);
- close(fd);
+ munmap((void *)header, size);
}
/* --------------------------------------------------------------------- */
@@ -272,7 +321,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
sljit_uw chunk_size;
sljit_sw executable_offset;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
if (size < (64 - sizeof(struct block_header)))
size = (64 - sizeof(struct block_header));
size = ALIGN_SIZE(size);
@@ -297,7 +346,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
}
allocated_size += size;
header->size = size;
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
free_block = free_block->next;
@@ -308,7 +357,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
chunk_header = alloc_chunk(chunk_size);
if (!chunk_header) {
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return NULL;
}
@@ -342,7 +391,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
next_header->size = 1;
next_header->prev_size = chunk_size;
next_header->executable_offset = executable_offset;
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
@@ -351,7 +400,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
struct block_header *header;
struct free_block* free_block;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
header = AS_BLOCK_HEADER(header, -header->executable_offset);
allocated_size -= header->size;
@@ -385,11 +434,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
if (total_size - free_block->size > (allocated_size * 3 / 2)) {
total_size -= free_block->size;
sljit_remove_free_block(free_block);
- free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ free_chunk(free_block, free_block->size +
+ sizeof(struct chunk_header) +
+ sizeof(struct block_header));
}
}
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
@@ -397,7 +448,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
struct free_block* free_block;
struct free_block* next_free_block;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
free_block = free_blocks;
while (free_block) {
@@ -406,13 +457,15 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
total_size -= free_block->size;
sljit_remove_free_block(free_block);
- free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ free_chunk(free_block, free_block->size +
+ sizeof(struct chunk_header) +
+ sizeof(struct block_header));
}
free_block = next_free_block;
}
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
}
SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr)
diff --git a/thirdparty/pcre2/src/sljit/sljitUtils.c b/thirdparty/pcre2/src/sljit/sljitUtils.c
index 857492a174..08ca35cf37 100644
--- a/thirdparty/pcre2/src/sljit/sljitUtils.c
+++ b/thirdparty/pcre2/src/sljit/sljitUtils.c
@@ -28,220 +28,225 @@
/* Locks */
/* ------------------------------------------------------------------------ */
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+/* Executable Allocator */
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
+ && !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
+#define SLJIT_ALLOCATOR_LOCK()
+#define SLJIT_ALLOCATOR_UNLOCK()
+#elif !(defined _WIN32)
+#include <pthread.h>
+
+static pthread_mutex_t allocator_lock = PTHREAD_MUTEX_INITIALIZER;
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+#define SLJIT_ALLOCATOR_LOCK() pthread_mutex_lock(&allocator_lock)
+#define SLJIT_ALLOCATOR_UNLOCK() pthread_mutex_unlock(&allocator_lock)
+#else /* windows */
+static HANDLE allocator_lock;
static SLJIT_INLINE void allocator_grab_lock(void)
{
- /* Always successful. */
+ HANDLE lock;
+ if (SLJIT_UNLIKELY(!allocator_lock)) {
+ lock = CreateMutex(NULL, FALSE, NULL);
+ if (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL))
+ CloseHandle(lock);
+ }
+ WaitForSingleObject(allocator_lock, INFINITE);
}
-static SLJIT_INLINE void allocator_release_lock(void)
-{
- /* Always successful. */
-}
+#define SLJIT_ALLOCATOR_LOCK() allocator_grab_lock()
+#define SLJIT_ALLOCATOR_UNLOCK() ReleaseMutex(allocator_lock)
+#endif /* thread implementation */
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+/* ------------------------------------------------------------------------ */
+/* Stack */
+/* ------------------------------------------------------------------------ */
-#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+#if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
+ && !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \
+ || ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
+ && !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \
+ || (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)))
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
-{
- /* Always successful. */
-}
+#ifndef _WIN32
+/* Provides mmap function. */
+#include <sys/types.h>
+#include <sys/mman.h>
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
-{
- /* Always successful. */
-}
+#ifndef MAP_ANON
+#ifdef MAP_ANONYMOUS
+#define MAP_ANON MAP_ANONYMOUS
+#endif /* MAP_ANONYMOUS */
+#endif /* !MAP_ANON */
-#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+#ifndef MAP_ANON
-#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */
+#include <fcntl.h>
-#include "windows.h"
+#ifdef O_CLOEXEC
+#define SLJIT_CLOEXEC O_CLOEXEC
+#else /* !O_CLOEXEC */
+#define SLJIT_CLOEXEC 0
+#endif /* O_CLOEXEC */
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+/* Some old systems do not have MAP_ANON. */
+static int dev_zero = -1;
-static HANDLE allocator_mutex = 0;
+#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
-static SLJIT_INLINE void allocator_grab_lock(void)
+static SLJIT_INLINE int open_dev_zero(void)
{
- /* No idea what to do if an error occures. Static mutexes should never fail... */
- if (!allocator_mutex)
- allocator_mutex = CreateMutex(NULL, TRUE, NULL);
- else
- WaitForSingleObject(allocator_mutex, INFINITE);
-}
+ dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
-static SLJIT_INLINE void allocator_release_lock(void)
-{
- ReleaseMutex(allocator_mutex);
+ return dev_zero < 0;
}
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+#else /* !SLJIT_SINGLE_THREADED */
-#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+#include <pthread.h>
-static HANDLE global_mutex = 0;
+static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
+static SLJIT_INLINE int open_dev_zero(void)
{
- /* No idea what to do if an error occures. Static mutexes should never fail... */
- if (!global_mutex)
- global_mutex = CreateMutex(NULL, TRUE, NULL);
- else
- WaitForSingleObject(global_mutex, INFINITE);
-}
+ pthread_mutex_lock(&dev_zero_mutex);
+ if (SLJIT_UNLIKELY(dev_zero < 0))
+ dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
-{
- ReleaseMutex(global_mutex);
+ pthread_mutex_unlock(&dev_zero_mutex);
+ return dev_zero < 0;
}
-#endif /* SLJIT_UTIL_GLOBAL_LOCK */
-
-#else /* _WIN32 */
-
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-
-#include <pthread.h>
+#endif /* SLJIT_SINGLE_THREADED */
+#undef SLJIT_CLOEXEC
+#endif /* !MAP_ANON */
+#endif /* !_WIN32 */
+#endif /* open_dev_zero */
-static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
+ || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-static SLJIT_INLINE void allocator_grab_lock(void)
-{
- pthread_mutex_lock(&allocator_mutex);
-}
+#ifdef _WIN32
-static SLJIT_INLINE void allocator_release_lock(void)
-{
- pthread_mutex_unlock(&allocator_mutex);
+static SLJIT_INLINE sljit_sw get_page_alignment(void) {
+ SYSTEM_INFO si;
+ static sljit_sw sljit_page_align;
+ if (!sljit_page_align) {
+ GetSystemInfo(&si);
+ sljit_page_align = si.dwPageSize - 1;
+ }
+ return sljit_page_align;
}
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
-
-#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
-
-#include <pthread.h>
+#else
-static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
+#include <unistd.h>
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
-{
- pthread_mutex_lock(&global_mutex);
+static SLJIT_INLINE sljit_sw get_page_alignment(void) {
+ static sljit_sw sljit_page_align;
+ if (!sljit_page_align) {
+ sljit_page_align = sysconf(_SC_PAGESIZE);
+ /* Should never happen. */
+ if (sljit_page_align < 0)
+ sljit_page_align = 4096;
+ sljit_page_align--;
+ }
+ return sljit_page_align;
}
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
-{
- pthread_mutex_unlock(&global_mutex);
-}
+#endif /* _WIN32 */
-#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+#endif /* get_page_alignment() */
-#endif /* _WIN32 */
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
-/* ------------------------------------------------------------------------ */
-/* Stack */
-/* ------------------------------------------------------------------------ */
+#if (defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)
-#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
+{
+ struct sljit_stack *stack;
+ void *ptr;
-#ifdef _WIN32
-#include "windows.h"
-#else
-/* Provides mmap function. */
-#include <sys/types.h>
-#include <sys/mman.h>
-#ifndef MAP_ANON
-#ifdef MAP_ANONYMOUS
-#define MAP_ANON MAP_ANONYMOUS
-#endif
-#endif
-/* For detecting the page size. */
-#include <unistd.h>
+ SLJIT_UNUSED_ARG(allocator_data);
-#ifndef MAP_ANON
+ if (start_size > max_size || start_size < 1)
+ return NULL;
-#include <fcntl.h>
+ stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
+ if (stack == NULL)
+ return NULL;
-/* Some old systems does not have MAP_ANON. */
-static sljit_s32 dev_zero = -1;
+ ptr = SLJIT_MALLOC(max_size, allocator_data);
+ if (ptr == NULL) {
+ SLJIT_FREE(stack, allocator_data);
+ return NULL;
+ }
-#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
+ stack->min_start = (sljit_u8 *)ptr;
+ stack->end = stack->min_start + max_size;
+ stack->start = stack->end - start_size;
+ stack->top = stack->end;
+ return stack;
+}
-static SLJIT_INLINE sljit_s32 open_dev_zero(void)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
{
- dev_zero = open("/dev/zero", O_RDWR);
- return dev_zero < 0;
+ SLJIT_UNUSED_ARG(allocator_data);
+ SLJIT_FREE((void*)stack->min_start, allocator_data);
+ SLJIT_FREE(stack, allocator_data);
}
-#else /* SLJIT_SINGLE_THREADED */
-
-#include <pthread.h>
-
-static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static SLJIT_INLINE sljit_s32 open_dev_zero(void)
+SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
{
- pthread_mutex_lock(&dev_zero_mutex);
- /* The dev_zero might be initialized by another thread during the waiting. */
- if (dev_zero < 0) {
- dev_zero = open("/dev/zero", O_RDWR);
- }
- pthread_mutex_unlock(&dev_zero_mutex);
- return dev_zero < 0;
+ if ((new_start < stack->min_start) || (new_start >= stack->end))
+ return NULL;
+ stack->start = new_start;
+ return new_start;
}
-#endif /* SLJIT_SINGLE_THREADED */
+#else /* !SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */
-#endif
+#ifdef _WIN32
-#endif
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
+{
+ SLJIT_UNUSED_ARG(allocator_data);
+ VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
+ SLJIT_FREE(stack, allocator_data);
+}
-#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */
+#else /* !_WIN32 */
-#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
+{
+ SLJIT_UNUSED_ARG(allocator_data);
+ munmap((void*)stack->min_start, stack->end - stack->min_start);
+ SLJIT_FREE(stack, allocator_data);
+}
-/* Planning to make it even more clever in the future. */
-static sljit_sw sljit_page_align = 0;
+#endif /* _WIN32 */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
{
struct sljit_stack *stack;
void *ptr;
-#ifdef _WIN32
- SYSTEM_INFO si;
-#endif
+ sljit_sw page_align;
SLJIT_UNUSED_ARG(allocator_data);
+
if (start_size > max_size || start_size < 1)
return NULL;
-#ifdef _WIN32
- if (!sljit_page_align) {
- GetSystemInfo(&si);
- sljit_page_align = si.dwPageSize - 1;
- }
-#else
- if (!sljit_page_align) {
- sljit_page_align = sysconf(_SC_PAGESIZE);
- /* Should never happen. */
- if (sljit_page_align < 0)
- sljit_page_align = 4096;
- sljit_page_align--;
- }
-#endif
-
stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
- if (!stack)
+ if (stack == NULL)
return NULL;
/* Align max_size. */
- max_size = (max_size + sljit_page_align) & ~sljit_page_align;
+ page_align = get_page_alignment();
+ max_size = (max_size + page_align) & ~page_align;
#ifdef _WIN32
ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
@@ -258,18 +263,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
sljit_free_stack(stack, allocator_data);
return NULL;
}
-#else
+#else /* !_WIN32 */
#ifdef MAP_ANON
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
-#else
- if (dev_zero < 0) {
- if (open_dev_zero()) {
- SLJIT_FREE(stack, allocator_data);
- return NULL;
- }
+#else /* !MAP_ANON */
+ if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) {
+ SLJIT_FREE(stack, allocator_data);
+ return NULL;
}
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
-#endif
+#endif /* MAP_ANON */
if (ptr == MAP_FAILED) {
SLJIT_FREE(stack, allocator_data);
return NULL;
@@ -277,35 +280,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
stack->min_start = (sljit_u8 *)ptr;
stack->end = stack->min_start + max_size;
stack->start = stack->end - start_size;
-#endif
+#endif /* _WIN32 */
+
stack->top = stack->end;
return stack;
}
-#undef PAGE_ALIGN
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
-{
- SLJIT_UNUSED_ARG(allocator_data);
-#ifdef _WIN32
- VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
-#else
- munmap((void*)stack->min_start, stack->end - stack->min_start);
-#endif
- SLJIT_FREE(stack, allocator_data);
-}
-
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
{
+#if defined _WIN32 || defined(POSIX_MADV_DONTNEED)
sljit_uw aligned_old_start;
sljit_uw aligned_new_start;
+ sljit_sw page_align;
+#endif
if ((new_start < stack->min_start) || (new_start >= stack->end))
return NULL;
#ifdef _WIN32
- aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
- aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
+ page_align = get_page_alignment();
+
+ aligned_new_start = (sljit_uw)new_start & ~page_align;
+ aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
if (aligned_new_start != aligned_old_start) {
if (aligned_new_start < aligned_old_start) {
if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
@@ -316,24 +312,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st
return NULL;
}
}
-#else
- if (stack->start < new_start) {
- aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
- aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
- /* If madvise is available, we release the unnecessary space. */
-#if defined(MADV_DONTNEED)
- if (aligned_new_start > aligned_old_start)
- madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
#elif defined(POSIX_MADV_DONTNEED)
- if (aligned_new_start > aligned_old_start)
+ if (stack->start < new_start) {
+ page_align = get_page_alignment();
+
+ aligned_new_start = (sljit_uw)new_start & ~page_align;
+ aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
+
+ if (aligned_new_start > aligned_old_start) {
posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
-#endif
+#ifdef MADV_FREE
+ madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE);
+#endif /* MADV_FREE */
+ }
}
-#endif
+#endif /* _WIN32 */
+
stack->start = new_start;
return new_start;
}
-#endif /* SLJIT_UTIL_STACK */
+#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */
-#endif
+#endif /* SLJIT_UTIL_STACK */
diff --git a/thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c
new file mode 100644
index 0000000000..6ef71f7d83
--- /dev/null
+++ b/thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c
@@ -0,0 +1,225 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ This file contains a simple W^X executable memory allocator for POSIX
+ like systems and Windows
+
+ In *NIX, MAP_ANON is required (that is considered a feature) so make
+ sure to set the right availability macros for your system or the code
+ will fail to build.
+
+ If your system doesn't support mapping of anonymous pages (ex: IRIX) it
+ is also likely that it doesn't need this allocator and should be using
+ the standard one instead.
+
+ It allocates a separate map for each code block and may waste a lot of
+ memory, because whatever was requested, will be rounded up to the page
+ size (minimum 4KB, but could be even bigger).
+
+ It changes the page permissions (RW <-> RX) as needed and therefore, if you
+ will be updating the code after it has been generated, need to make sure to
+ block any concurrent execution, or could result in a SIGBUS, that could
+ even manifest itself at a different address than the one that was being
+ modified.
+
+ Only use if you are unable to use the regular allocator because of security
+ restrictions and adding exceptions to your application or the system are
+ not possible.
+*/
+
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
+ sljit_update_wx_flags((from), (to), (enable_exec))
+
+#ifndef _WIN32
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#ifdef __NetBSD__
+#if defined(PROT_MPROTECT)
+#define check_se_protected(ptr, size) (0)
+#define SLJIT_PROT_WX PROT_MPROTECT(PROT_EXEC)
+#else /* !PROT_MPROTECT */
+#ifdef _NETBSD_SOURCE
+#include <sys/param.h>
+#else /* !_NETBSD_SOURCE */
+typedef unsigned int u_int;
+#define devmajor_t sljit_s32
+#endif /* _NETBSD_SOURCE */
+#include <sys/sysctl.h>
+#include <unistd.h>
+
+#define check_se_protected(ptr, size) netbsd_se_protected()
+
+static SLJIT_INLINE int netbsd_se_protected(void)
+{
+ int mib[3];
+ int paxflags;
+ size_t len = sizeof(paxflags);
+
+ mib[0] = CTL_PROC;
+ mib[1] = getpid();
+ mib[2] = PROC_PID_PAXFLAGS;
+
+ if (SLJIT_UNLIKELY(sysctl(mib, 3, &paxflags, &len, NULL, 0) < 0))
+ return -1;
+
+ return (paxflags & CTL_PROC_PAXFLAGS_MPROTECT) ? -1 : 0;
+}
+#endif /* PROT_MPROTECT */
+#else /* POSIX */
+#define check_se_protected(ptr, size) generic_se_protected(ptr, size)
+
+static SLJIT_INLINE int generic_se_protected(void *ptr, sljit_uw size)
+{
+ if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC)))
+ return mprotect(ptr, size, PROT_READ | PROT_WRITE);
+
+ return -1;
+}
+#endif /* NetBSD */
+
+#if defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED
+#define SLJIT_SE_LOCK()
+#define SLJIT_SE_UNLOCK()
+#else /* !SLJIT_SINGLE_THREADED */
+#include <pthread.h>
+#define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock)
+#define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock)
+#endif /* SLJIT_SINGLE_THREADED */
+
+#ifndef SLJIT_PROT_WX
+#define SLJIT_PROT_WX 0
+#endif /* !SLJIT_PROT_WX */
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
+{
+#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
+ static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+ static int se_protected = !SLJIT_PROT_WX;
+ sljit_uw* ptr;
+
+ if (SLJIT_UNLIKELY(se_protected < 0))
+ return NULL;
+
+ size += sizeof(sljit_uw);
+ ptr = (sljit_uw*)mmap(NULL, size, PROT_READ | PROT_WRITE | SLJIT_PROT_WX,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+
+ if (ptr == MAP_FAILED)
+ return NULL;
+
+ if (SLJIT_UNLIKELY(se_protected > 0)) {
+ SLJIT_SE_LOCK();
+ se_protected = check_se_protected(ptr, size);
+ SLJIT_SE_UNLOCK();
+ if (SLJIT_UNLIKELY(se_protected < 0)) {
+ munmap((void *)ptr, size);
+ return NULL;
+ }
+ }
+
+ *ptr++ = size;
+ return ptr;
+}
+
+#undef SLJIT_PROT_WX
+#undef SLJIT_SE_UNLOCK
+#undef SLJIT_SE_LOCK
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
+{
+ sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1;
+ munmap((void*)start_ptr, *start_ptr);
+}
+
+static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
+{
+ sljit_uw page_mask = (sljit_uw)get_page_alignment();
+ sljit_uw start = (sljit_uw)from;
+ sljit_uw end = (sljit_uw)to;
+ int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE);
+
+ SLJIT_ASSERT(start < end);
+
+ start &= ~page_mask;
+ end = (end + page_mask) & ~page_mask;
+
+ mprotect((void*)start, end - start, prot);
+}
+
+#else /* windows */
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
+{
+ sljit_uw *ptr;
+
+ size += sizeof(sljit_uw);
+ ptr = (sljit_uw*)VirtualAlloc(NULL, size,
+ MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+
+ if (!ptr)
+ return NULL;
+
+ *ptr++ = size;
+
+ return ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
+{
+ sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw);
+#if defined(SLJIT_DEBUG) && SLJIT_DEBUG
+ sljit_uw page_mask = (sljit_uw)get_page_alignment();
+
+ SLJIT_ASSERT(!(start & page_mask));
+#endif
+ VirtualFree((void*)start, 0, MEM_RELEASE);
+}
+
+static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
+{
+ DWORD oldprot;
+ sljit_uw page_mask = (sljit_uw)get_page_alignment();
+ sljit_uw start = (sljit_uw)from;
+ sljit_uw end = (sljit_uw)to;
+ DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE;
+
+ SLJIT_ASSERT(start < end);
+
+ start &= ~page_mask;
+ end = (end + page_mask) & ~page_mask;
+
+ VirtualProtect((void*)start, end - start, prot, &oldprot);
+}
+
+#endif /* !windows */
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
+{
+ /* This allocator does not keep unused memory for future allocations. */
+}
diff --git a/thirdparty/spirv-reflect/LICENSE b/thirdparty/spirv-reflect/LICENSE
new file mode 100644
index 0000000000..261eeb9e9f
--- /dev/null
+++ b/thirdparty/spirv-reflect/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h b/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h
index a61a2d2935..949f1980e7 100644
--- a/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h
+++ b/thirdparty/spirv-reflect/include/spirv/unified1/spirv.h
@@ -1,5 +1,5 @@
/*
-** Copyright (c) 2014-2018 The Khronos Group Inc.
+** Copyright (c) 2014-2020 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
@@ -31,13 +31,16 @@
/*
** Enumeration tokens for SPIR-V, in various styles:
-** C, C++, C++11, JSON, Lua, Python
+** C, C++, C++11, JSON, Lua, Python, C#, D
**
** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
+** - C# will use enum classes in the Specification class located in the "Spv" namespace,
+** e.g.: Spv.Specification.SourceLanguage.GLSL
+** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL
**
** Some tokens act like mask values, which can be OR'd together,
** while others are mutually exclusive. The mask-like ones have
@@ -50,12 +53,12 @@
typedef unsigned int SpvId;
-#define SPV_VERSION 0x10300
-#define SPV_REVISION 1
+#define SPV_VERSION 0x10500
+#define SPV_REVISION 4
static const unsigned int SpvMagicNumber = 0x07230203;
-static const unsigned int SpvVersion = 0x00010300;
-static const unsigned int SpvRevision = 1;
+static const unsigned int SpvVersion = 0x00010500;
+static const unsigned int SpvRevision = 4;
static const unsigned int SpvOpCodeMask = 0xffff;
static const unsigned int SpvWordCountShift = 16;
@@ -77,6 +80,20 @@ typedef enum SpvExecutionModel_ {
SpvExecutionModelFragment = 4,
SpvExecutionModelGLCompute = 5,
SpvExecutionModelKernel = 6,
+ SpvExecutionModelTaskNV = 5267,
+ SpvExecutionModelMeshNV = 5268,
+ SpvExecutionModelRayGenerationKHR = 5313,
+ SpvExecutionModelRayGenerationNV = 5313,
+ SpvExecutionModelIntersectionKHR = 5314,
+ SpvExecutionModelIntersectionNV = 5314,
+ SpvExecutionModelAnyHitKHR = 5315,
+ SpvExecutionModelAnyHitNV = 5315,
+ SpvExecutionModelClosestHitKHR = 5316,
+ SpvExecutionModelClosestHitNV = 5316,
+ SpvExecutionModelMissKHR = 5317,
+ SpvExecutionModelMissNV = 5317,
+ SpvExecutionModelCallableKHR = 5318,
+ SpvExecutionModelCallableNV = 5318,
SpvExecutionModelMax = 0x7fffffff,
} SpvExecutionModel;
@@ -84,6 +101,8 @@ typedef enum SpvAddressingModel_ {
SpvAddressingModelLogical = 0,
SpvAddressingModelPhysical32 = 1,
SpvAddressingModelPhysical64 = 2,
+ SpvAddressingModelPhysicalStorageBuffer64 = 5348,
+ SpvAddressingModelPhysicalStorageBuffer64EXT = 5348,
SpvAddressingModelMax = 0x7fffffff,
} SpvAddressingModel;
@@ -91,6 +110,8 @@ typedef enum SpvMemoryModel_ {
SpvMemoryModelSimple = 0,
SpvMemoryModelGLSL450 = 1,
SpvMemoryModelOpenCL = 2,
+ SpvMemoryModelVulkan = 3,
+ SpvMemoryModelVulkanKHR = 3,
SpvMemoryModelMax = 0x7fffffff,
} SpvMemoryModel;
@@ -134,7 +155,27 @@ typedef enum SpvExecutionMode_ {
SpvExecutionModeLocalSizeId = 38,
SpvExecutionModeLocalSizeHintId = 39,
SpvExecutionModePostDepthCoverage = 4446,
+ SpvExecutionModeDenormPreserve = 4459,
+ SpvExecutionModeDenormFlushToZero = 4460,
+ SpvExecutionModeSignedZeroInfNanPreserve = 4461,
+ SpvExecutionModeRoundingModeRTE = 4462,
+ SpvExecutionModeRoundingModeRTZ = 4463,
SpvExecutionModeStencilRefReplacingEXT = 5027,
+ SpvExecutionModeOutputLinesNV = 5269,
+ SpvExecutionModeOutputPrimitivesNV = 5270,
+ SpvExecutionModeDerivativeGroupQuadsNV = 5289,
+ SpvExecutionModeDerivativeGroupLinearNV = 5290,
+ SpvExecutionModeOutputTrianglesNV = 5298,
+ SpvExecutionModePixelInterlockOrderedEXT = 5366,
+ SpvExecutionModePixelInterlockUnorderedEXT = 5367,
+ SpvExecutionModeSampleInterlockOrderedEXT = 5368,
+ SpvExecutionModeSampleInterlockUnorderedEXT = 5369,
+ SpvExecutionModeShadingRateInterlockOrderedEXT = 5370,
+ SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371,
+ SpvExecutionModeMaxWorkgroupSizeINTEL = 5893,
+ SpvExecutionModeMaxWorkDimINTEL = 5894,
+ SpvExecutionModeNoGlobalOffsetINTEL = 5895,
+ SpvExecutionModeNumSIMDWorkitemsINTEL = 5896,
SpvExecutionModeMax = 0x7fffffff,
} SpvExecutionMode;
@@ -152,6 +193,21 @@ typedef enum SpvStorageClass_ {
SpvStorageClassAtomicCounter = 10,
SpvStorageClassImage = 11,
SpvStorageClassStorageBuffer = 12,
+ SpvStorageClassCallableDataKHR = 5328,
+ SpvStorageClassCallableDataNV = 5328,
+ SpvStorageClassIncomingCallableDataKHR = 5329,
+ SpvStorageClassIncomingCallableDataNV = 5329,
+ SpvStorageClassRayPayloadKHR = 5338,
+ SpvStorageClassRayPayloadNV = 5338,
+ SpvStorageClassHitAttributeKHR = 5339,
+ SpvStorageClassHitAttributeNV = 5339,
+ SpvStorageClassIncomingRayPayloadKHR = 5342,
+ SpvStorageClassIncomingRayPayloadNV = 5342,
+ SpvStorageClassShaderRecordBufferKHR = 5343,
+ SpvStorageClassShaderRecordBufferNV = 5343,
+ SpvStorageClassPhysicalStorageBuffer = 5349,
+ SpvStorageClassPhysicalStorageBufferEXT = 5349,
+ SpvStorageClassCodeSectionINTEL = 5605,
SpvStorageClassMax = 0x7fffffff,
} SpvStorageClass;
@@ -222,6 +278,8 @@ typedef enum SpvImageFormat_ {
SpvImageFormatRg8ui = 37,
SpvImageFormatR16ui = 38,
SpvImageFormatR8ui = 39,
+ SpvImageFormatR64ui = 40,
+ SpvImageFormatR64i = 41,
SpvImageFormatMax = 0x7fffffff,
} SpvImageFormat;
@@ -279,6 +337,16 @@ typedef enum SpvImageOperandsShift_ {
SpvImageOperandsConstOffsetsShift = 5,
SpvImageOperandsSampleShift = 6,
SpvImageOperandsMinLodShift = 7,
+ SpvImageOperandsMakeTexelAvailableShift = 8,
+ SpvImageOperandsMakeTexelAvailableKHRShift = 8,
+ SpvImageOperandsMakeTexelVisibleShift = 9,
+ SpvImageOperandsMakeTexelVisibleKHRShift = 9,
+ SpvImageOperandsNonPrivateTexelShift = 10,
+ SpvImageOperandsNonPrivateTexelKHRShift = 10,
+ SpvImageOperandsVolatileTexelShift = 11,
+ SpvImageOperandsVolatileTexelKHRShift = 11,
+ SpvImageOperandsSignExtendShift = 12,
+ SpvImageOperandsZeroExtendShift = 13,
SpvImageOperandsMax = 0x7fffffff,
} SpvImageOperandsShift;
@@ -292,6 +360,16 @@ typedef enum SpvImageOperandsMask_ {
SpvImageOperandsConstOffsetsMask = 0x00000020,
SpvImageOperandsSampleMask = 0x00000040,
SpvImageOperandsMinLodMask = 0x00000080,
+ SpvImageOperandsMakeTexelAvailableMask = 0x00000100,
+ SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100,
+ SpvImageOperandsMakeTexelVisibleMask = 0x00000200,
+ SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200,
+ SpvImageOperandsNonPrivateTexelMask = 0x00000400,
+ SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400,
+ SpvImageOperandsVolatileTexelMask = 0x00000800,
+ SpvImageOperandsVolatileTexelKHRMask = 0x00000800,
+ SpvImageOperandsSignExtendMask = 0x00001000,
+ SpvImageOperandsZeroExtendMask = 0x00002000,
} SpvImageOperandsMask;
typedef enum SpvFPFastMathModeShift_ {
@@ -372,6 +450,7 @@ typedef enum SpvDecoration_ {
SpvDecorationNonWritable = 24,
SpvDecorationNonReadable = 25,
SpvDecorationUniform = 26,
+ SpvDecorationUniformId = 27,
SpvDecorationSaturatedConversion = 28,
SpvDecorationStream = 29,
SpvDecorationLocation = 30,
@@ -392,13 +471,41 @@ typedef enum SpvDecoration_ {
SpvDecorationMaxByteOffset = 45,
SpvDecorationAlignmentId = 46,
SpvDecorationMaxByteOffsetId = 47,
+ SpvDecorationNoSignedWrap = 4469,
+ SpvDecorationNoUnsignedWrap = 4470,
SpvDecorationExplicitInterpAMD = 4999,
SpvDecorationOverrideCoverageNV = 5248,
SpvDecorationPassthroughNV = 5250,
SpvDecorationViewportRelativeNV = 5252,
SpvDecorationSecondaryViewportRelativeNV = 5256,
+ SpvDecorationPerPrimitiveNV = 5271,
+ SpvDecorationPerViewNV = 5272,
+ SpvDecorationPerTaskNV = 5273,
+ SpvDecorationPerVertexNV = 5285,
+ SpvDecorationNonUniform = 5300,
+ SpvDecorationNonUniformEXT = 5300,
+ SpvDecorationRestrictPointer = 5355,
+ SpvDecorationRestrictPointerEXT = 5355,
+ SpvDecorationAliasedPointer = 5356,
+ SpvDecorationAliasedPointerEXT = 5356,
+ SpvDecorationReferencedIndirectlyINTEL = 5602,
+ SpvDecorationCounterBuffer = 5634,
SpvDecorationHlslCounterBufferGOOGLE = 5634,
SpvDecorationHlslSemanticGOOGLE = 5635,
+ SpvDecorationUserSemantic = 5635,
+ SpvDecorationUserTypeGOOGLE = 5636,
+ SpvDecorationRegisterINTEL = 5825,
+ SpvDecorationMemoryINTEL = 5826,
+ SpvDecorationNumbanksINTEL = 5827,
+ SpvDecorationBankwidthINTEL = 5828,
+ SpvDecorationMaxPrivateCopiesINTEL = 5829,
+ SpvDecorationSinglepumpINTEL = 5830,
+ SpvDecorationDoublepumpINTEL = 5831,
+ SpvDecorationMaxReplicatesINTEL = 5832,
+ SpvDecorationSimpleDualPortINTEL = 5833,
+ SpvDecorationMergeINTEL = 5834,
+ SpvDecorationBankBitsINTEL = 5835,
+ SpvDecorationForcePow2DepthINTEL = 5836,
SpvDecorationMax = 0x7fffffff,
} SpvDecoration;
@@ -457,8 +564,10 @@ typedef enum SpvBuiltIn_ {
SpvBuiltInBaseVertex = 4424,
SpvBuiltInBaseInstance = 4425,
SpvBuiltInDrawIndex = 4426,
+ SpvBuiltInPrimitiveShadingRateKHR = 4432,
SpvBuiltInDeviceIndex = 4438,
SpvBuiltInViewIndex = 4440,
+ SpvBuiltInShadingRateKHR = 4444,
SpvBuiltInBaryCoordNoPerspAMD = 4992,
SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993,
SpvBuiltInBaryCoordNoPerspSampleAMD = 4994,
@@ -473,6 +582,52 @@ typedef enum SpvBuiltIn_ {
SpvBuiltInPositionPerViewNV = 5261,
SpvBuiltInViewportMaskPerViewNV = 5262,
SpvBuiltInFullyCoveredEXT = 5264,
+ SpvBuiltInTaskCountNV = 5274,
+ SpvBuiltInPrimitiveCountNV = 5275,
+ SpvBuiltInPrimitiveIndicesNV = 5276,
+ SpvBuiltInClipDistancePerViewNV = 5277,
+ SpvBuiltInCullDistancePerViewNV = 5278,
+ SpvBuiltInLayerPerViewNV = 5279,
+ SpvBuiltInMeshViewCountNV = 5280,
+ SpvBuiltInMeshViewIndicesNV = 5281,
+ SpvBuiltInBaryCoordNV = 5286,
+ SpvBuiltInBaryCoordNoPerspNV = 5287,
+ SpvBuiltInFragSizeEXT = 5292,
+ SpvBuiltInFragmentSizeNV = 5292,
+ SpvBuiltInFragInvocationCountEXT = 5293,
+ SpvBuiltInInvocationsPerPixelNV = 5293,
+ SpvBuiltInLaunchIdKHR = 5319,
+ SpvBuiltInLaunchIdNV = 5319,
+ SpvBuiltInLaunchSizeKHR = 5320,
+ SpvBuiltInLaunchSizeNV = 5320,
+ SpvBuiltInWorldRayOriginKHR = 5321,
+ SpvBuiltInWorldRayOriginNV = 5321,
+ SpvBuiltInWorldRayDirectionKHR = 5322,
+ SpvBuiltInWorldRayDirectionNV = 5322,
+ SpvBuiltInObjectRayOriginKHR = 5323,
+ SpvBuiltInObjectRayOriginNV = 5323,
+ SpvBuiltInObjectRayDirectionKHR = 5324,
+ SpvBuiltInObjectRayDirectionNV = 5324,
+ SpvBuiltInRayTminKHR = 5325,
+ SpvBuiltInRayTminNV = 5325,
+ SpvBuiltInRayTmaxKHR = 5326,
+ SpvBuiltInRayTmaxNV = 5326,
+ SpvBuiltInInstanceCustomIndexKHR = 5327,
+ SpvBuiltInInstanceCustomIndexNV = 5327,
+ SpvBuiltInObjectToWorldKHR = 5330,
+ SpvBuiltInObjectToWorldNV = 5330,
+ SpvBuiltInWorldToObjectKHR = 5331,
+ SpvBuiltInWorldToObjectNV = 5331,
+ SpvBuiltInHitTNV = 5332,
+ SpvBuiltInHitKindKHR = 5333,
+ SpvBuiltInHitKindNV = 5333,
+ SpvBuiltInIncomingRayFlagsKHR = 5351,
+ SpvBuiltInIncomingRayFlagsNV = 5351,
+ SpvBuiltInRayGeometryIndexKHR = 5352,
+ SpvBuiltInWarpsPerSMNV = 5374,
+ SpvBuiltInSMCountNV = 5375,
+ SpvBuiltInWarpIDNV = 5376,
+ SpvBuiltInSMIDNV = 5377,
SpvBuiltInMax = 0x7fffffff,
} SpvBuiltIn;
@@ -493,6 +648,18 @@ typedef enum SpvLoopControlShift_ {
SpvLoopControlDontUnrollShift = 1,
SpvLoopControlDependencyInfiniteShift = 2,
SpvLoopControlDependencyLengthShift = 3,
+ SpvLoopControlMinIterationsShift = 4,
+ SpvLoopControlMaxIterationsShift = 5,
+ SpvLoopControlIterationMultipleShift = 6,
+ SpvLoopControlPeelCountShift = 7,
+ SpvLoopControlPartialCountShift = 8,
+ SpvLoopControlInitiationIntervalINTELShift = 16,
+ SpvLoopControlMaxConcurrencyINTELShift = 17,
+ SpvLoopControlDependencyArrayINTELShift = 18,
+ SpvLoopControlPipelineEnableINTELShift = 19,
+ SpvLoopControlLoopCoalesceINTELShift = 20,
+ SpvLoopControlMaxInterleavingINTELShift = 21,
+ SpvLoopControlSpeculatedIterationsINTELShift = 22,
SpvLoopControlMax = 0x7fffffff,
} SpvLoopControlShift;
@@ -502,6 +669,18 @@ typedef enum SpvLoopControlMask_ {
SpvLoopControlDontUnrollMask = 0x00000002,
SpvLoopControlDependencyInfiniteMask = 0x00000004,
SpvLoopControlDependencyLengthMask = 0x00000008,
+ SpvLoopControlMinIterationsMask = 0x00000010,
+ SpvLoopControlMaxIterationsMask = 0x00000020,
+ SpvLoopControlIterationMultipleMask = 0x00000040,
+ SpvLoopControlPeelCountMask = 0x00000080,
+ SpvLoopControlPartialCountMask = 0x00000100,
+ SpvLoopControlInitiationIntervalINTELMask = 0x00010000,
+ SpvLoopControlMaxConcurrencyINTELMask = 0x00020000,
+ SpvLoopControlDependencyArrayINTELMask = 0x00040000,
+ SpvLoopControlPipelineEnableINTELMask = 0x00080000,
+ SpvLoopControlLoopCoalesceINTELMask = 0x00100000,
+ SpvLoopControlMaxInterleavingINTELMask = 0x00200000,
+ SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000,
} SpvLoopControlMask;
typedef enum SpvFunctionControlShift_ {
@@ -531,6 +710,13 @@ typedef enum SpvMemorySemanticsShift_ {
SpvMemorySemanticsCrossWorkgroupMemoryShift = 9,
SpvMemorySemanticsAtomicCounterMemoryShift = 10,
SpvMemorySemanticsImageMemoryShift = 11,
+ SpvMemorySemanticsOutputMemoryShift = 12,
+ SpvMemorySemanticsOutputMemoryKHRShift = 12,
+ SpvMemorySemanticsMakeAvailableShift = 13,
+ SpvMemorySemanticsMakeAvailableKHRShift = 13,
+ SpvMemorySemanticsMakeVisibleShift = 14,
+ SpvMemorySemanticsMakeVisibleKHRShift = 14,
+ SpvMemorySemanticsVolatileShift = 15,
SpvMemorySemanticsMax = 0x7fffffff,
} SpvMemorySemanticsShift;
@@ -546,12 +732,25 @@ typedef enum SpvMemorySemanticsMask_ {
SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400,
SpvMemorySemanticsImageMemoryMask = 0x00000800,
+ SpvMemorySemanticsOutputMemoryMask = 0x00001000,
+ SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000,
+ SpvMemorySemanticsMakeAvailableMask = 0x00002000,
+ SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000,
+ SpvMemorySemanticsMakeVisibleMask = 0x00004000,
+ SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000,
+ SpvMemorySemanticsVolatileMask = 0x00008000,
} SpvMemorySemanticsMask;
typedef enum SpvMemoryAccessShift_ {
SpvMemoryAccessVolatileShift = 0,
SpvMemoryAccessAlignedShift = 1,
SpvMemoryAccessNontemporalShift = 2,
+ SpvMemoryAccessMakePointerAvailableShift = 3,
+ SpvMemoryAccessMakePointerAvailableKHRShift = 3,
+ SpvMemoryAccessMakePointerVisibleShift = 4,
+ SpvMemoryAccessMakePointerVisibleKHRShift = 4,
+ SpvMemoryAccessNonPrivatePointerShift = 5,
+ SpvMemoryAccessNonPrivatePointerKHRShift = 5,
SpvMemoryAccessMax = 0x7fffffff,
} SpvMemoryAccessShift;
@@ -560,6 +759,12 @@ typedef enum SpvMemoryAccessMask_ {
SpvMemoryAccessVolatileMask = 0x00000001,
SpvMemoryAccessAlignedMask = 0x00000002,
SpvMemoryAccessNontemporalMask = 0x00000004,
+ SpvMemoryAccessMakePointerAvailableMask = 0x00000008,
+ SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008,
+ SpvMemoryAccessMakePointerVisibleMask = 0x00000010,
+ SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010,
+ SpvMemoryAccessNonPrivatePointerMask = 0x00000020,
+ SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020,
} SpvMemoryAccessMask;
typedef enum SpvScope_ {
@@ -568,6 +773,9 @@ typedef enum SpvScope_ {
SpvScopeWorkgroup = 2,
SpvScopeSubgroup = 3,
SpvScopeInvocation = 4,
+ SpvScopeQueueFamily = 5,
+ SpvScopeQueueFamilyKHR = 5,
+ SpvScopeShaderCallKHR = 6,
SpvScopeMax = 0x7fffffff,
} SpvScope;
@@ -667,6 +875,9 @@ typedef enum SpvCapability_ {
SpvCapabilityGroupNonUniformShuffleRelative = 66,
SpvCapabilityGroupNonUniformClustered = 67,
SpvCapabilityGroupNonUniformQuad = 68,
+ SpvCapabilityShaderLayer = 69,
+ SpvCapabilityShaderViewportIndex = 70,
+ SpvCapabilityFragmentShadingRateKHR = 4422,
SpvCapabilitySubgroupBallotKHR = 4423,
SpvCapabilityDrawParameters = 4427,
SpvCapabilitySubgroupVoteKHR = 4431,
@@ -682,11 +893,25 @@ typedef enum SpvCapability_ {
SpvCapabilityVariablePointers = 4442,
SpvCapabilityAtomicStorageOps = 4445,
SpvCapabilitySampleMaskPostDepthCoverage = 4447,
+ SpvCapabilityStorageBuffer8BitAccess = 4448,
+ SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449,
+ SpvCapabilityStoragePushConstant8 = 4450,
+ SpvCapabilityDenormPreserve = 4464,
+ SpvCapabilityDenormFlushToZero = 4465,
+ SpvCapabilitySignedZeroInfNanPreserve = 4466,
+ SpvCapabilityRoundingModeRTE = 4467,
+ SpvCapabilityRoundingModeRTZ = 4468,
+ SpvCapabilityRayQueryProvisionalKHR = 4471,
+ SpvCapabilityRayQueryKHR = 4472,
+ SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478,
+ SpvCapabilityRayTracingKHR = 4479,
SpvCapabilityFloat16ImageAMD = 5008,
SpvCapabilityImageGatherBiasLodAMD = 5009,
SpvCapabilityFragmentMaskAMD = 5010,
SpvCapabilityStencilExportEXT = 5013,
SpvCapabilityImageReadWriteLodAMD = 5015,
+ SpvCapabilityInt64ImageEXT = 5016,
+ SpvCapabilityShaderClockKHR = 5055,
SpvCapabilitySampleMaskOverrideCoverageNV = 5249,
SpvCapabilityGeometryShaderPassthroughNV = 5251,
SpvCapabilityShaderViewportIndexLayerEXT = 5254,
@@ -695,13 +920,137 @@ typedef enum SpvCapability_ {
SpvCapabilityShaderStereoViewNV = 5259,
SpvCapabilityPerViewAttributesNV = 5260,
SpvCapabilityFragmentFullyCoveredEXT = 5265,
+ SpvCapabilityMeshShadingNV = 5266,
+ SpvCapabilityImageFootprintNV = 5282,
+ SpvCapabilityFragmentBarycentricNV = 5284,
+ SpvCapabilityComputeDerivativeGroupQuadsNV = 5288,
+ SpvCapabilityFragmentDensityEXT = 5291,
+ SpvCapabilityShadingRateNV = 5291,
SpvCapabilityGroupNonUniformPartitionedNV = 5297,
+ SpvCapabilityShaderNonUniform = 5301,
+ SpvCapabilityShaderNonUniformEXT = 5301,
+ SpvCapabilityRuntimeDescriptorArray = 5302,
+ SpvCapabilityRuntimeDescriptorArrayEXT = 5302,
+ SpvCapabilityInputAttachmentArrayDynamicIndexing = 5303,
+ SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303,
+ SpvCapabilityUniformTexelBufferArrayDynamicIndexing = 5304,
+ SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304,
+ SpvCapabilityStorageTexelBufferArrayDynamicIndexing = 5305,
+ SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305,
+ SpvCapabilityUniformBufferArrayNonUniformIndexing = 5306,
+ SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306,
+ SpvCapabilitySampledImageArrayNonUniformIndexing = 5307,
+ SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307,
+ SpvCapabilityStorageBufferArrayNonUniformIndexing = 5308,
+ SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308,
+ SpvCapabilityStorageImageArrayNonUniformIndexing = 5309,
+ SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309,
+ SpvCapabilityInputAttachmentArrayNonUniformIndexing = 5310,
+ SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
+ SpvCapabilityUniformTexelBufferArrayNonUniformIndexing = 5311,
+ SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
+ SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
+ SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
+ SpvCapabilityRayTracingNV = 5340,
+ SpvCapabilityVulkanMemoryModel = 5345,
+ SpvCapabilityVulkanMemoryModelKHR = 5345,
+ SpvCapabilityVulkanMemoryModelDeviceScope = 5346,
+ SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
+ SpvCapabilityPhysicalStorageBufferAddresses = 5347,
+ SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347,
+ SpvCapabilityComputeDerivativeGroupLinearNV = 5350,
+ SpvCapabilityRayTracingProvisionalKHR = 5353,
+ SpvCapabilityCooperativeMatrixNV = 5357,
+ SpvCapabilityFragmentShaderSampleInterlockEXT = 5363,
+ SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372,
+ SpvCapabilityShaderSMBuiltinsNV = 5373,
+ SpvCapabilityFragmentShaderPixelInterlockEXT = 5378,
+ SpvCapabilityDemoteToHelperInvocationEXT = 5379,
SpvCapabilitySubgroupShuffleINTEL = 5568,
SpvCapabilitySubgroupBufferBlockIOINTEL = 5569,
SpvCapabilitySubgroupImageBlockIOINTEL = 5570,
+ SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579,
+ SpvCapabilityIntegerFunctions2INTEL = 5584,
+ SpvCapabilityFunctionPointersINTEL = 5603,
+ SpvCapabilityIndirectReferencesINTEL = 5604,
+ SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696,
+ SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
+ SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
+ SpvCapabilityFPGAMemoryAttributesINTEL = 5824,
+ SpvCapabilityUnstructuredLoopControlsINTEL = 5886,
+ SpvCapabilityFPGALoopControlsINTEL = 5888,
+ SpvCapabilityKernelAttributesINTEL = 5892,
+ SpvCapabilityFPGAKernelAttributesINTEL = 5897,
+ SpvCapabilityBlockingPipesINTEL = 5945,
+ SpvCapabilityFPGARegINTEL = 5948,
+ SpvCapabilityAtomicFloat32AddEXT = 6033,
+ SpvCapabilityAtomicFloat64AddEXT = 6034,
SpvCapabilityMax = 0x7fffffff,
} SpvCapability;
+typedef enum SpvRayFlagsShift_ {
+ SpvRayFlagsOpaqueKHRShift = 0,
+ SpvRayFlagsNoOpaqueKHRShift = 1,
+ SpvRayFlagsTerminateOnFirstHitKHRShift = 2,
+ SpvRayFlagsSkipClosestHitShaderKHRShift = 3,
+ SpvRayFlagsCullBackFacingTrianglesKHRShift = 4,
+ SpvRayFlagsCullFrontFacingTrianglesKHRShift = 5,
+ SpvRayFlagsCullOpaqueKHRShift = 6,
+ SpvRayFlagsCullNoOpaqueKHRShift = 7,
+ SpvRayFlagsSkipTrianglesKHRShift = 8,
+ SpvRayFlagsSkipAABBsKHRShift = 9,
+ SpvRayFlagsMax = 0x7fffffff,
+} SpvRayFlagsShift;
+
+typedef enum SpvRayFlagsMask_ {
+ SpvRayFlagsMaskNone = 0,
+ SpvRayFlagsOpaqueKHRMask = 0x00000001,
+ SpvRayFlagsNoOpaqueKHRMask = 0x00000002,
+ SpvRayFlagsTerminateOnFirstHitKHRMask = 0x00000004,
+ SpvRayFlagsSkipClosestHitShaderKHRMask = 0x00000008,
+ SpvRayFlagsCullBackFacingTrianglesKHRMask = 0x00000010,
+ SpvRayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020,
+ SpvRayFlagsCullOpaqueKHRMask = 0x00000040,
+ SpvRayFlagsCullNoOpaqueKHRMask = 0x00000080,
+ SpvRayFlagsSkipTrianglesKHRMask = 0x00000100,
+ SpvRayFlagsSkipAABBsKHRMask = 0x00000200,
+} SpvRayFlagsMask;
+
+typedef enum SpvRayQueryIntersection_ {
+ SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR = 0,
+ SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR = 1,
+ SpvRayQueryIntersectionMax = 0x7fffffff,
+} SpvRayQueryIntersection;
+
+typedef enum SpvRayQueryCommittedIntersectionType_ {
+ SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0,
+ SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1,
+ SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2,
+ SpvRayQueryCommittedIntersectionTypeMax = 0x7fffffff,
+} SpvRayQueryCommittedIntersectionType;
+
+typedef enum SpvRayQueryCandidateIntersectionType_ {
+ SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0,
+ SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1,
+ SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff,
+} SpvRayQueryCandidateIntersectionType;
+
+typedef enum SpvFragmentShadingRateShift_ {
+ SpvFragmentShadingRateVertical2PixelsShift = 0,
+ SpvFragmentShadingRateVertical4PixelsShift = 1,
+ SpvFragmentShadingRateHorizontal2PixelsShift = 2,
+ SpvFragmentShadingRateHorizontal4PixelsShift = 3,
+ SpvFragmentShadingRateMax = 0x7fffffff,
+} SpvFragmentShadingRateShift;
+
+typedef enum SpvFragmentShadingRateMask_ {
+ SpvFragmentShadingRateMaskNone = 0,
+ SpvFragmentShadingRateVertical2PixelsMask = 0x00000001,
+ SpvFragmentShadingRateVertical4PixelsMask = 0x00000002,
+ SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004,
+ SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008,
+} SpvFragmentShadingRateMask;
+
typedef enum SpvOp_ {
SpvOpNop = 0,
SpvOpUndef = 1,
@@ -1043,12 +1392,29 @@ typedef enum SpvOp_ {
SpvOpGroupNonUniformLogicalXor = 364,
SpvOpGroupNonUniformQuadBroadcast = 365,
SpvOpGroupNonUniformQuadSwap = 366,
+ SpvOpCopyLogical = 400,
+ SpvOpPtrEqual = 401,
+ SpvOpPtrNotEqual = 402,
+ SpvOpPtrDiff = 403,
+ SpvOpTerminateInvocation = 4416,
SpvOpSubgroupBallotKHR = 4421,
SpvOpSubgroupFirstInvocationKHR = 4422,
SpvOpSubgroupAllKHR = 4428,
SpvOpSubgroupAnyKHR = 4429,
SpvOpSubgroupAllEqualKHR = 4430,
SpvOpSubgroupReadInvocationKHR = 4432,
+ SpvOpTraceRayKHR = 4445,
+ SpvOpExecuteCallableKHR = 4446,
+ SpvOpConvertUToAccelerationStructureKHR = 4447,
+ SpvOpIgnoreIntersectionKHR = 4448,
+ SpvOpTerminateRayKHR = 4449,
+ SpvOpTypeRayQueryKHR = 4472,
+ SpvOpRayQueryInitializeKHR = 4473,
+ SpvOpRayQueryTerminateKHR = 4474,
+ SpvOpRayQueryGenerateIntersectionKHR = 4475,
+ SpvOpRayQueryConfirmIntersectionKHR = 4476,
+ SpvOpRayQueryProceedKHR = 4477,
+ SpvOpRayQueryGetIntersectionTypeKHR = 4479,
SpvOpGroupIAddNonUniformAMD = 5000,
SpvOpGroupFAddNonUniformAMD = 5001,
SpvOpGroupFMinNonUniformAMD = 5002,
@@ -1059,7 +1425,27 @@ typedef enum SpvOp_ {
SpvOpGroupSMaxNonUniformAMD = 5007,
SpvOpFragmentMaskFetchAMD = 5011,
SpvOpFragmentFetchAMD = 5012,
+ SpvOpReadClockKHR = 5056,
+ SpvOpImageSampleFootprintNV = 5283,
SpvOpGroupNonUniformPartitionNV = 5296,
+ SpvOpWritePackedPrimitiveIndices4x8NV = 5299,
+ SpvOpReportIntersectionKHR = 5334,
+ SpvOpReportIntersectionNV = 5334,
+ SpvOpIgnoreIntersectionNV = 5335,
+ SpvOpTerminateRayNV = 5336,
+ SpvOpTraceNV = 5337,
+ SpvOpTypeAccelerationStructureKHR = 5341,
+ SpvOpTypeAccelerationStructureNV = 5341,
+ SpvOpExecuteCallableNV = 5344,
+ SpvOpTypeCooperativeMatrixNV = 5358,
+ SpvOpCooperativeMatrixLoadNV = 5359,
+ SpvOpCooperativeMatrixStoreNV = 5360,
+ SpvOpCooperativeMatrixMulAddNV = 5361,
+ SpvOpCooperativeMatrixLengthNV = 5362,
+ SpvOpBeginInvocationInterlockEXT = 5364,
+ SpvOpEndInvocationInterlockEXT = 5365,
+ SpvOpDemoteToHelperInvocationEXT = 5380,
+ SpvOpIsHelperInvocationEXT = 5381,
SpvOpSubgroupShuffleINTEL = 5571,
SpvOpSubgroupShuffleDownINTEL = 5572,
SpvOpSubgroupShuffleUpINTEL = 5573,
@@ -1068,10 +1454,739 @@ typedef enum SpvOp_ {
SpvOpSubgroupBlockWriteINTEL = 5576,
SpvOpSubgroupImageBlockReadINTEL = 5577,
SpvOpSubgroupImageBlockWriteINTEL = 5578,
+ SpvOpSubgroupImageMediaBlockReadINTEL = 5580,
+ SpvOpSubgroupImageMediaBlockWriteINTEL = 5581,
+ SpvOpUCountLeadingZerosINTEL = 5585,
+ SpvOpUCountTrailingZerosINTEL = 5586,
+ SpvOpAbsISubINTEL = 5587,
+ SpvOpAbsUSubINTEL = 5588,
+ SpvOpIAddSatINTEL = 5589,
+ SpvOpUAddSatINTEL = 5590,
+ SpvOpIAverageINTEL = 5591,
+ SpvOpUAverageINTEL = 5592,
+ SpvOpIAverageRoundedINTEL = 5593,
+ SpvOpUAverageRoundedINTEL = 5594,
+ SpvOpISubSatINTEL = 5595,
+ SpvOpUSubSatINTEL = 5596,
+ SpvOpIMul32x16INTEL = 5597,
+ SpvOpUMul32x16INTEL = 5598,
+ SpvOpFunctionPointerINTEL = 5600,
+ SpvOpFunctionPointerCallINTEL = 5601,
+ SpvOpDecorateString = 5632,
SpvOpDecorateStringGOOGLE = 5632,
+ SpvOpMemberDecorateString = 5633,
SpvOpMemberDecorateStringGOOGLE = 5633,
+ SpvOpVmeImageINTEL = 5699,
+ SpvOpTypeVmeImageINTEL = 5700,
+ SpvOpTypeAvcImePayloadINTEL = 5701,
+ SpvOpTypeAvcRefPayloadINTEL = 5702,
+ SpvOpTypeAvcSicPayloadINTEL = 5703,
+ SpvOpTypeAvcMcePayloadINTEL = 5704,
+ SpvOpTypeAvcMceResultINTEL = 5705,
+ SpvOpTypeAvcImeResultINTEL = 5706,
+ SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707,
+ SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708,
+ SpvOpTypeAvcImeSingleReferenceStreaminINTEL = 5709,
+ SpvOpTypeAvcImeDualReferenceStreaminINTEL = 5710,
+ SpvOpTypeAvcRefResultINTEL = 5711,
+ SpvOpTypeAvcSicResultINTEL = 5712,
+ SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713,
+ SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714,
+ SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715,
+ SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716,
+ SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717,
+ SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718,
+ SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719,
+ SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720,
+ SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721,
+ SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722,
+ SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723,
+ SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724,
+ SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725,
+ SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726,
+ SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727,
+ SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728,
+ SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729,
+ SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730,
+ SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731,
+ SpvOpSubgroupAvcMceConvertToImePayloadINTEL = 5732,
+ SpvOpSubgroupAvcMceConvertToImeResultINTEL = 5733,
+ SpvOpSubgroupAvcMceConvertToRefPayloadINTEL = 5734,
+ SpvOpSubgroupAvcMceConvertToRefResultINTEL = 5735,
+ SpvOpSubgroupAvcMceConvertToSicPayloadINTEL = 5736,
+ SpvOpSubgroupAvcMceConvertToSicResultINTEL = 5737,
+ SpvOpSubgroupAvcMceGetMotionVectorsINTEL = 5738,
+ SpvOpSubgroupAvcMceGetInterDistortionsINTEL = 5739,
+ SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740,
+ SpvOpSubgroupAvcMceGetInterMajorShapeINTEL = 5741,
+ SpvOpSubgroupAvcMceGetInterMinorShapeINTEL = 5742,
+ SpvOpSubgroupAvcMceGetInterDirectionsINTEL = 5743,
+ SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744,
+ SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745,
+ SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746,
+ SpvOpSubgroupAvcImeInitializeINTEL = 5747,
+ SpvOpSubgroupAvcImeSetSingleReferenceINTEL = 5748,
+ SpvOpSubgroupAvcImeSetDualReferenceINTEL = 5749,
+ SpvOpSubgroupAvcImeRefWindowSizeINTEL = 5750,
+ SpvOpSubgroupAvcImeAdjustRefOffsetINTEL = 5751,
+ SpvOpSubgroupAvcImeConvertToMcePayloadINTEL = 5752,
+ SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753,
+ SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754,
+ SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755,
+ SpvOpSubgroupAvcImeSetWeightedSadINTEL = 5756,
+ SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757,
+ SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758,
+ SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759,
+ SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760,
+ SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761,
+ SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762,
+ SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763,
+ SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764,
+ SpvOpSubgroupAvcImeConvertToMceResultINTEL = 5765,
+ SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766,
+ SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767,
+ SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768,
+ SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769,
+ SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770,
+ SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771,
+ SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772,
+ SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773,
+ SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774,
+ SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775,
+ SpvOpSubgroupAvcImeGetBorderReachedINTEL = 5776,
+ SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777,
+ SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778,
+ SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779,
+ SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780,
+ SpvOpSubgroupAvcFmeInitializeINTEL = 5781,
+ SpvOpSubgroupAvcBmeInitializeINTEL = 5782,
+ SpvOpSubgroupAvcRefConvertToMcePayloadINTEL = 5783,
+ SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784,
+ SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785,
+ SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786,
+ SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787,
+ SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788,
+ SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789,
+ SpvOpSubgroupAvcRefConvertToMceResultINTEL = 5790,
+ SpvOpSubgroupAvcSicInitializeINTEL = 5791,
+ SpvOpSubgroupAvcSicConfigureSkcINTEL = 5792,
+ SpvOpSubgroupAvcSicConfigureIpeLumaINTEL = 5793,
+ SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794,
+ SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795,
+ SpvOpSubgroupAvcSicConvertToMcePayloadINTEL = 5796,
+ SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797,
+ SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798,
+ SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799,
+ SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800,
+ SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801,
+ SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802,
+ SpvOpSubgroupAvcSicEvaluateIpeINTEL = 5803,
+ SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804,
+ SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805,
+ SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806,
+ SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807,
+ SpvOpSubgroupAvcSicConvertToMceResultINTEL = 5808,
+ SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809,
+ SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810,
+ SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811,
+ SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812,
+ SpvOpSubgroupAvcSicGetIpeChromaModeINTEL = 5813,
+ SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
+ SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
+ SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
+ SpvOpLoopControlINTEL = 5887,
+ SpvOpReadPipeBlockingINTEL = 5946,
+ SpvOpWritePipeBlockingINTEL = 5947,
+ SpvOpFPGARegINTEL = 5949,
+ SpvOpRayQueryGetRayTMinKHR = 6016,
+ SpvOpRayQueryGetRayFlagsKHR = 6017,
+ SpvOpRayQueryGetIntersectionTKHR = 6018,
+ SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019,
+ SpvOpRayQueryGetIntersectionInstanceIdKHR = 6020,
+ SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021,
+ SpvOpRayQueryGetIntersectionGeometryIndexKHR = 6022,
+ SpvOpRayQueryGetIntersectionPrimitiveIndexKHR = 6023,
+ SpvOpRayQueryGetIntersectionBarycentricsKHR = 6024,
+ SpvOpRayQueryGetIntersectionFrontFaceKHR = 6025,
+ SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026,
+ SpvOpRayQueryGetIntersectionObjectRayDirectionKHR = 6027,
+ SpvOpRayQueryGetIntersectionObjectRayOriginKHR = 6028,
+ SpvOpRayQueryGetWorldRayDirectionKHR = 6029,
+ SpvOpRayQueryGetWorldRayOriginKHR = 6030,
+ SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031,
+ SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032,
+ SpvOpAtomicFAddEXT = 6035,
SpvOpMax = 0x7fffffff,
} SpvOp;
-#endif // #ifndef spirv_H
+#ifdef SPV_ENABLE_UTILITY_CODE
+inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) {
+ *hasResult = *hasResultType = false;
+ switch (opcode) {
+ default: /* unknown opcode */ break;
+ case SpvOpNop: *hasResult = false; *hasResultType = false; break;
+ case SpvOpUndef: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSourceContinued: *hasResult = false; *hasResultType = false; break;
+ case SpvOpSource: *hasResult = false; *hasResultType = false; break;
+ case SpvOpSourceExtension: *hasResult = false; *hasResultType = false; break;
+ case SpvOpName: *hasResult = false; *hasResultType = false; break;
+ case SpvOpMemberName: *hasResult = false; *hasResultType = false; break;
+ case SpvOpString: *hasResult = true; *hasResultType = false; break;
+ case SpvOpLine: *hasResult = false; *hasResultType = false; break;
+ case SpvOpExtension: *hasResult = false; *hasResultType = false; break;
+ case SpvOpExtInstImport: *hasResult = true; *hasResultType = false; break;
+ case SpvOpExtInst: *hasResult = true; *hasResultType = true; break;
+ case SpvOpMemoryModel: *hasResult = false; *hasResultType = false; break;
+ case SpvOpEntryPoint: *hasResult = false; *hasResultType = false; break;
+ case SpvOpExecutionMode: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCapability: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTypeVoid: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeBool: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeInt: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeFloat: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeVector: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeMatrix: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeImage: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeSampler: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeSampledImage: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeArray: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeStruct: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeOpaque: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypePointer: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeFunction: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeEvent: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeReserveId: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeQueue: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypePipe: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeForwardPointer: *hasResult = false; *hasResultType = false; break;
+ case SpvOpConstantTrue: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConstantFalse: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConstant: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConstantComposite: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConstantSampler: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConstantNull: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSpecConstantTrue: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSpecConstantFalse: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSpecConstant: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSpecConstantComposite: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSpecConstantOp: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFunction: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFunctionParameter: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFunctionEnd: *hasResult = false; *hasResultType = false; break;
+ case SpvOpFunctionCall: *hasResult = true; *hasResultType = true; break;
+ case SpvOpVariable: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageTexelPointer: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLoad: *hasResult = true; *hasResultType = true; break;
+ case SpvOpStore: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCopyMemory: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCopyMemorySized: *hasResult = false; *hasResultType = false; break;
+ case SpvOpAccessChain: *hasResult = true; *hasResultType = true; break;
+ case SpvOpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break;
+ case SpvOpPtrAccessChain: *hasResult = true; *hasResultType = true; break;
+ case SpvOpArrayLength: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break;
+ case SpvOpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDecorate: *hasResult = false; *hasResultType = false; break;
+ case SpvOpMemberDecorate: *hasResult = false; *hasResultType = false; break;
+ case SpvOpDecorationGroup: *hasResult = true; *hasResultType = false; break;
+ case SpvOpGroupDecorate: *hasResult = false; *hasResultType = false; break;
+ case SpvOpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break;
+ case SpvOpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break;
+ case SpvOpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break;
+ case SpvOpVectorShuffle: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCompositeConstruct: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCompositeExtract: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCompositeInsert: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCopyObject: *hasResult = true; *hasResultType = true; break;
+ case SpvOpTranspose: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSampledImage: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageFetch: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageGather: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageDrefGather: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageRead: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageWrite: *hasResult = false; *hasResultType = false; break;
+ case SpvOpImage: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageQueryFormat: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageQueryOrder: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageQuerySize: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageQueryLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageQueryLevels: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageQuerySamples: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConvertFToU: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConvertFToS: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConvertSToF: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConvertUToF: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUConvert: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSConvert: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFConvert: *hasResult = true; *hasResultType = true; break;
+ case SpvOpQuantizeToF16: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConvertPtrToU: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSatConvertSToU: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSatConvertUToS: *hasResult = true; *hasResultType = true; break;
+ case SpvOpConvertUToPtr: *hasResult = true; *hasResultType = true; break;
+ case SpvOpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGenericCastToPtr: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitcast: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSNegate: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFNegate: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIAdd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFAdd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpISub: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFSub: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIMul: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFMul: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUDiv: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSDiv: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFDiv: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUMod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSRem: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSMod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFRem: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFMod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpVectorTimesScalar: *hasResult = true; *hasResultType = true; break;
+ case SpvOpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break;
+ case SpvOpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break;
+ case SpvOpMatrixTimesVector: *hasResult = true; *hasResultType = true; break;
+ case SpvOpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break;
+ case SpvOpOuterProduct: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDot: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIAddCarry: *hasResult = true; *hasResultType = true; break;
+ case SpvOpISubBorrow: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUMulExtended: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSMulExtended: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAny: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAll: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIsNan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIsInf: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIsFinite: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIsNormal: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSignBitSet: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLessOrGreater: *hasResult = true; *hasResultType = true; break;
+ case SpvOpOrdered: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUnordered: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLogicalEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLogicalNotEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLogicalOr: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLogicalAnd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLogicalNot: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSelect: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpINotEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUGreaterThan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSGreaterThan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpULessThan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSLessThan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpULessThanEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSLessThanEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFOrdEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFUnordEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFOrdNotEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFUnordNotEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFOrdLessThan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFUnordLessThan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpShiftRightLogical: *hasResult = true; *hasResultType = true; break;
+ case SpvOpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break;
+ case SpvOpShiftLeftLogical: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitwiseOr: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitwiseXor: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitwiseAnd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpNot: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitFieldInsert: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitFieldSExtract: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitFieldUExtract: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitReverse: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBitCount: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDPdx: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDPdy: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFwidth: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDPdxFine: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDPdyFine: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFwidthFine: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDPdxCoarse: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDPdyCoarse: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFwidthCoarse: *hasResult = true; *hasResultType = true; break;
+ case SpvOpEmitVertex: *hasResult = false; *hasResultType = false; break;
+ case SpvOpEndPrimitive: *hasResult = false; *hasResultType = false; break;
+ case SpvOpEmitStreamVertex: *hasResult = false; *hasResultType = false; break;
+ case SpvOpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break;
+ case SpvOpControlBarrier: *hasResult = false; *hasResultType = false; break;
+ case SpvOpMemoryBarrier: *hasResult = false; *hasResultType = false; break;
+ case SpvOpAtomicLoad: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicStore: *hasResult = false; *hasResultType = false; break;
+ case SpvOpAtomicExchange: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicIIncrement: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicIDecrement: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicIAdd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicISub: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicSMin: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicUMin: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicSMax: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicUMax: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicAnd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicOr: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicXor: *hasResult = true; *hasResultType = true; break;
+ case SpvOpPhi: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLoopMerge: *hasResult = false; *hasResultType = false; break;
+ case SpvOpSelectionMerge: *hasResult = false; *hasResultType = false; break;
+ case SpvOpLabel: *hasResult = true; *hasResultType = false; break;
+ case SpvOpBranch: *hasResult = false; *hasResultType = false; break;
+ case SpvOpBranchConditional: *hasResult = false; *hasResultType = false; break;
+ case SpvOpSwitch: *hasResult = false; *hasResultType = false; break;
+ case SpvOpKill: *hasResult = false; *hasResultType = false; break;
+ case SpvOpReturn: *hasResult = false; *hasResultType = false; break;
+ case SpvOpReturnValue: *hasResult = false; *hasResultType = false; break;
+ case SpvOpUnreachable: *hasResult = false; *hasResultType = false; break;
+ case SpvOpLifetimeStart: *hasResult = false; *hasResultType = false; break;
+ case SpvOpLifetimeStop: *hasResult = false; *hasResultType = false; break;
+ case SpvOpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupWaitEvents: *hasResult = false; *hasResultType = false; break;
+ case SpvOpGroupAll: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupAny: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupBroadcast: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupIAdd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupFAdd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupFMin: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupUMin: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupSMin: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupFMax: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupUMax: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupSMax: *hasResult = true; *hasResultType = true; break;
+ case SpvOpReadPipe: *hasResult = true; *hasResultType = true; break;
+ case SpvOpWritePipe: *hasResult = true; *hasResultType = true; break;
+ case SpvOpReservedReadPipe: *hasResult = true; *hasResultType = true; break;
+ case SpvOpReservedWritePipe: *hasResult = true; *hasResultType = true; break;
+ case SpvOpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break;
+ case SpvOpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCommitReadPipe: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCommitWritePipe: *hasResult = false; *hasResultType = false; break;
+ case SpvOpIsValidReserveId: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGetNumPipePackets: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break;
+ case SpvOpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break;
+ case SpvOpEnqueueMarker: *hasResult = true; *hasResultType = true; break;
+ case SpvOpEnqueueKernel: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRetainEvent: *hasResult = false; *hasResultType = false; break;
+ case SpvOpReleaseEvent: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCreateUserEvent: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIsValidEvent: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSetUserEventStatus: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break;
+ case SpvOpGetDefaultQueue: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBuildNDRange: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseFetch: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseGather: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break;
+ case SpvOpNoLine: *hasResult = false; *hasResultType = false; break;
+ case SpvOpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicFlagClear: *hasResult = false; *hasResultType = false; break;
+ case SpvOpImageSparseRead: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSizeOf: *hasResult = true; *hasResultType = true; break;
+ case SpvOpTypePipeStorage: *hasResult = true; *hasResultType = false; break;
+ case SpvOpConstantPipeStorage: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break;
+ case SpvOpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break;
+ case SpvOpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break;
+ case SpvOpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break;
+ case SpvOpModuleProcessed: *hasResult = false; *hasResultType = false; break;
+ case SpvOpExecutionModeId: *hasResult = false; *hasResultType = false; break;
+ case SpvOpDecorateId: *hasResult = false; *hasResultType = false; break;
+ case SpvOpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break;
+ case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break;
+ case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break;
+ case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break;
+ case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
+ case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;
+ case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break;
+ case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
+ case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
+ case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break;
+ case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
+ case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break;
+ case SpvOpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break;
+ case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
+ case SpvOpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
+ case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break;
+ case SpvOpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAbsISubINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIAddSatINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUAddSatINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIAverageINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUAverageINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpISubSatINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break;
+ case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
+ case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break;
+ case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
+ case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
+ }
+}
+#endif /* SPV_ENABLE_UTILITY_CODE */
+
+#endif
diff --git a/thirdparty/spirv-reflect/spirv_reflect.c b/thirdparty/spirv-reflect/spirv_reflect.c
index 3df963d1ae..0fc979a8a4 100644
--- a/thirdparty/spirv-reflect/spirv_reflect.c
+++ b/thirdparty/spirv-reflect/spirv_reflect.c
@@ -27,6 +27,13 @@
#include <stdlib.h>
#endif
+#if defined(SPIRV_REFLECT_ENABLE_ASSERTS)
+ #define SPV_REFLECT_ASSERT(COND) \
+ assert(COND);
+#else
+#define SPV_REFLECT_ASSERT(COND)
+#endif
+
// Temporary enums until these make it into SPIR-V/Vulkan
// clang-format off
enum {
@@ -192,7 +199,7 @@ typedef struct Parser {
SpvSourceLanguage source_language;
uint32_t source_language_version;
uint32_t source_file_id;
- String source_embedded;
+ const char* source_embedded;
size_t node_count;
Node* nodes;
uint32_t entry_point_count;
@@ -552,6 +559,7 @@ static void DestroyParser(Parser* p_parser)
SafeFree(p_parser->nodes);
SafeFree(p_parser->strings);
+ SafeFree(p_parser->source_embedded);
SafeFree(p_parser->functions);
SafeFree(p_parser->access_chains);
p_parser->node_count = 0;
@@ -605,6 +613,7 @@ static SpvReflectResult ParseNodes(Parser* p_parser)
}
// Mark source file id node
p_parser->source_file_id = (uint32_t)INVALID_VALUE;
+ p_parser->source_embedded = NULL;
// Function node
uint32_t function_node = (uint32_t)INVALID_VALUE;
@@ -645,6 +654,48 @@ static SpvReflectResult ParseNodes(Parser* p_parser)
if (p_node->word_count >= 4) {
CHECKED_READU32(p_parser, p_node->word_offset + 3, p_parser->source_file_id);
}
+ if (p_node->word_count >= 5) {
+ const char* p_source = (const char*)(p_parser->spirv_code + p_node->word_offset + 4);
+
+ const size_t source_len = strlen(p_source);
+ char* p_source_temp = (char*)calloc(source_len + 1, sizeof(char*));
+
+ if (IsNull(p_source_temp)) {
+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
+ }
+
+ #ifdef _WIN32
+ strcpy_s(p_source_temp, source_len + 1, p_source);
+ #else
+ strcpy(p_source_temp, p_source);
+ #endif
+
+ p_parser->source_embedded = p_source_temp;
+ }
+ }
+ break;
+
+ case SpvOpSourceContinued: {
+ const char* p_source = (const char*)(p_parser->spirv_code + p_node->word_offset + 1);
+
+ const size_t source_len = strlen(p_source);
+ const size_t embedded_source_len = strlen(p_parser->source_embedded);
+ char* p_continued_source = (char*)calloc(source_len + embedded_source_len + 1, sizeof(char*));
+
+ if (IsNull(p_continued_source)) {
+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
+ }
+
+ #ifdef _WIN32
+ strcpy_s(p_continued_source, embedded_source_len + 1, p_parser->source_embedded);
+ strcat_s(p_continued_source, source_len + 1, p_source);
+ #else
+ strcpy(p_continued_source, p_parser->source_embedded);
+ strcat(p_continued_source, p_source);
+ #endif
+
+ SafeFree(p_parser->source_embedded);
+ p_parser->source_embedded = p_continued_source;
}
break;
@@ -680,6 +731,8 @@ static SpvReflectResult ParseNodes(Parser* p_parser)
case SpvOpTypeReserveId:
case SpvOpTypeQueue:
case SpvOpTypePipe:
+ case SpvOpTypeAccelerationStructureKHR:
+ case SpvOpTypeRayQueryKHR:
{
CHECKED_READU32(p_parser, p_node->word_offset + 1, p_node->result_id);
p_node->is_type = true;
@@ -889,7 +942,7 @@ static SpvReflectResult ParseStrings(Parser* p_parser)
++string_index;
}
}
-
+
return SPV_REFLECT_RESULT_SUCCESS;
}
@@ -909,6 +962,25 @@ static SpvReflectResult ParseSource(Parser* p_parser, SpvReflectShaderModule* p_
}
}
}
+
+ //Source code
+ if (IsNotNull(p_parser->source_embedded))
+ {
+ const size_t source_len = strlen(p_parser->source_embedded);
+ char* p_source = (char*)calloc(source_len + 1, sizeof(char*));
+
+ if (IsNull(p_source)) {
+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
+ }
+
+ #ifdef _WIN32
+ strcpy_s(p_source, source_len + 1, p_parser->source_embedded);
+ #else
+ strcpy(p_source, p_parser->source_embedded);
+ #endif
+
+ p_module->source_source = p_source;
+ }
}
return SPV_REFLECT_RESULT_SUCCESS;
@@ -1486,6 +1558,7 @@ static SpvReflectResult ParseType(
}
else {
result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ SPV_REFLECT_ASSERT(false);
}
}
break;
@@ -1501,6 +1574,7 @@ static SpvReflectResult ParseType(
}
else {
result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ SPV_REFLECT_ASSERT(false);
}
p_type->traits.numeric.matrix.row_count = p_type->traits.numeric.vector.component_count;
p_type->traits.numeric.matrix.stride = p_node->decorations.matrix_stride;
@@ -1536,7 +1610,8 @@ static SpvReflectResult ParseType(
result = ParseType(p_parser, p_next_node, NULL, p_module, p_type);
}
else {
- result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ SPV_REFLECT_ASSERT(false);
}
}
break;
@@ -1567,6 +1642,7 @@ static SpvReflectResult ParseType(
p_type->traits.array.dims_count += 1;
} else {
result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ SPV_REFLECT_ASSERT(false);
}
}
// Parse next dimension or element type
@@ -1577,6 +1653,7 @@ static SpvReflectResult ParseType(
}
else {
result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ SPV_REFLECT_ASSERT(false);
}
}
}
@@ -1592,6 +1669,7 @@ static SpvReflectResult ParseType(
}
else {
result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ SPV_REFLECT_ASSERT(false);
}
}
break;
@@ -1608,6 +1686,7 @@ static SpvReflectResult ParseType(
Node* p_member_node = FindNode(p_parser, member_id);
if (IsNull(p_member_node)) {
result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ SPV_REFLECT_ASSERT(false);
break;
}
@@ -1643,9 +1722,15 @@ static SpvReflectResult ParseType(
}
else {
result = SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ SPV_REFLECT_ASSERT(false);
}
}
break;
+
+ case SpvOpTypeAccelerationStructureKHR: {
+ p_type->type_flags |= SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE;
+ }
+ break;
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
@@ -1718,7 +1803,9 @@ static SpvReflectResult ParseDescriptorBindings(Parser* p_parser, SpvReflectShad
for (size_t i = 0; i < p_parser->node_count; ++i) {
Node* p_node = &(p_parser->nodes[i]);
if ((p_node->op != SpvOpVariable) ||
- ((p_node->storage_class != SpvStorageClassUniform) && (p_node->storage_class != SpvStorageClassUniformConstant)))
+ ((p_node->storage_class != SpvStorageClassUniform) &&
+ (p_node->storage_class != SpvStorageClassStorageBuffer) &&
+ (p_node->storage_class != SpvStorageClassUniformConstant)))
{
continue;
}
@@ -1752,7 +1839,9 @@ static SpvReflectResult ParseDescriptorBindings(Parser* p_parser, SpvReflectShad
for (size_t i = 0; i < p_parser->node_count; ++i) {
Node* p_node = &(p_parser->nodes[i]);
if ((p_node->op != SpvOpVariable) ||
- ((p_node->storage_class != SpvStorageClassUniform) && (p_node->storage_class != SpvStorageClassUniformConstant)))\
+ ((p_node->storage_class != SpvStorageClassUniform) &&
+ (p_node->storage_class != SpvStorageClassStorageBuffer) &&
+ (p_node->storage_class != SpvStorageClassUniformConstant)))
{
continue;
}
@@ -1764,8 +1853,11 @@ static SpvReflectResult ParseDescriptorBindings(Parser* p_parser, SpvReflectShad
if (IsNull(p_type)) {
return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
}
- // If the type is a pointer, resolve it
+ // If the type is a pointer, resolve it. We need to retain the storage class
+ // from the pointer so that we can use it to deduce deescriptor types.
+ SpvStorageClass pointer_storage_class = SpvStorageClassMax;
if (p_type->op == SpvOpTypePointer) {
+ pointer_storage_class = p_type->storage_class;
// Find the type's node
Node* p_type_node = FindNode(p_parser, p_type->id);
if (IsNull(p_type_node)) {
@@ -1788,6 +1880,18 @@ static SpvReflectResult ParseDescriptorBindings(Parser* p_parser, SpvReflectShad
p_descriptor->uav_counter_id = p_node->decorations.uav_counter_buffer.value;
p_descriptor->type_description = p_type;
+ // If this is in the StorageBuffer storage class, it's for sure a storage
+ // buffer descriptor. We need to handle this case earlier because in SPIR-V
+ // there are two ways to indicate a storage buffer:
+ // 1) Uniform storage class + BufferBlock decoration, or
+ // 2) StorageBuffer storage class + Buffer decoration.
+ // The 1) way is deprecated since SPIR-V v1.3. But the Buffer decoration is
+ // also used together with Uniform storage class to mean uniform buffer..
+ // We'll handle the pre-v1.3 cases in ParseDescriptorType().
+ if (pointer_storage_class == SpvStorageClassStorageBuffer) {
+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ }
+
// Copy image traits
if ((p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) == SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE) {
memcpy(&p_descriptor->image, &p_type->traits.image, sizeof(p_descriptor->image));
@@ -1840,78 +1944,84 @@ static SpvReflectResult ParseDescriptorType(SpvReflectShaderModule* p_module)
SpvReflectDescriptorBinding* p_descriptor = &(p_module->descriptor_bindings[descriptor_index]);
SpvReflectTypeDescription* p_type = p_descriptor->type_description;
- switch (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) {
- default: assert(false && "unknown type flag"); break;
+ if ((int)p_descriptor->descriptor_type == (int)INVALID_VALUE) {
+ switch (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK) {
+ default: assert(false && "unknown type flag"); break;
- case SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE: {
- if (p_descriptor->image.dim == SpvDimBuffer) {
- switch (p_descriptor->image.sampled) {
- default: assert(false && "unknown texel buffer sampled value"); break;
- case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break;
- case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break;
+ case SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE: {
+ if (p_descriptor->image.dim == SpvDimBuffer) {
+ switch (p_descriptor->image.sampled) {
+ default: assert(false && "unknown texel buffer sampled value"); break;
+ case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break;
+ case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break;
+ }
}
- }
- else if(p_descriptor->image.dim == SpvDimSubpassData) {
- p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
- }
- else {
- switch (p_descriptor->image.sampled) {
- default: assert(false && "unknown image sampled value"); break;
- case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE; break;
- case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE; break;
+ else if(p_descriptor->image.dim == SpvDimSubpassData) {
+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
+ }
+ else {
+ switch (p_descriptor->image.sampled) {
+ default: assert(false && "unknown image sampled value"); break;
+ case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE; break;
+ case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE; break;
+ }
}
}
- }
- break;
+ break;
- case SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER: {
- p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER;
- }
- break;
+ case SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER: {
+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER;
+ }
+ break;
- case (SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE | SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE): {
- // This is a workaround for: https://github.com/KhronosGroup/glslang/issues/1096
- if (p_descriptor->image.dim == SpvDimBuffer) {
- switch (p_descriptor->image.sampled) {
- default: assert(false && "unknown texel buffer sampled value"); break;
- case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break;
- case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break;
+ case (SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE | SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE): {
+ // This is a workaround for: https://github.com/KhronosGroup/glslang/issues/1096
+ if (p_descriptor->image.dim == SpvDimBuffer) {
+ switch (p_descriptor->image.sampled) {
+ default: assert(false && "unknown texel buffer sampled value"); break;
+ case IMAGE_SAMPLED: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; break;
+ case IMAGE_STORAGE: p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; break;
+ }
+ }
+ else {
+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
}
}
- else {
- p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- }
- }
- break;
+ break;
- case SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK: {
- if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BLOCK) {
- p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- }
- else if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BUFFER_BLOCK) {
- p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ case SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK: {
+ if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BLOCK) {
+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ }
+ else if (p_type->decoration_flags & SPV_REFLECT_DECORATION_BUFFER_BLOCK) {
+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+ }
+ else {
+ assert(false && "unknown struct");
+ }
}
- else {
- assert(false && "unknown struct");
+ break;
+
+ case SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE: {
+ p_descriptor->descriptor_type = SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
}
+ break;
}
- break;
}
switch (p_descriptor->descriptor_type) {
- case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SAMPLER; break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : p_descriptor->resource_type = (SpvReflectResourceType)(SPV_REFLECT_RESOURCE_FLAG_SAMPLER | SPV_REFLECT_RESOURCE_FLAG_SRV); break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
- case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
-
- case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
- break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SAMPLER; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : p_descriptor->resource_type = (SpvReflectResourceType)(SPV_REFLECT_RESOURCE_FLAG_SAMPLER | SPV_REFLECT_RESOURCE_FLAG_SRV); break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_CBV; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_UAV; break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : break;
+ case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR : p_descriptor->resource_type = SPV_REFLECT_RESOURCE_FLAG_SRV; break;
}
}
@@ -1950,7 +2060,7 @@ static SpvReflectResult ParseUAVCounterBindings(SpvReflectShaderModule* p_module
memset(name, 0, MAX_NODE_NAME_LENGTH);
memcpy(name, p_descriptor->name, descriptor_name_length);
-#if defined(WIN32)
+#if defined(_WIN32)
strcat_s(name, MAX_NODE_NAME_LENGTH, k_count_tag);
#else
strcat(name, k_count_tag);
@@ -2188,6 +2298,29 @@ static SpvReflectResult ParseDescriptorBlockVariableSizes(
return SPV_REFLECT_RESULT_SUCCESS;
}
+static void MarkSelfAndAllMemberVarsAsUsed(SpvReflectBlockVariable* p_var)
+{
+ // Clear the current variable's USED flag
+ p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED;
+
+ SpvOp op_type = p_var->type_description->op;
+ switch (op_type) {
+ default: break;
+
+ case SpvOpTypeArray: {
+ }
+ break;
+
+ case SpvOpTypeStruct: {
+ for (uint32_t i = 0; i < p_var->member_count; ++i) {
+ SpvReflectBlockVariable* p_member_var = &p_var->members[i];
+ MarkSelfAndAllMemberVarsAsUsed(p_member_var);
+ }
+ }
+ break;
+ }
+}
+
static SpvReflectResult ParseDescriptorBlockVariableUsage(
Parser* p_parser,
SpvReflectShaderModule* p_module,
@@ -2201,7 +2334,7 @@ static SpvReflectResult ParseDescriptorBlockVariableUsage(
(void)p_access_chain;
(void)p_var;
- // Clear the current variable's USED flag
+ // Clear the current variable's UNUSED flag
p_var->flags &= ~SPV_REFLECT_VARIABLE_FLAGS_UNUSED;
// Parsing arrays requires overriding the op type for
@@ -2229,19 +2362,33 @@ static SpvReflectResult ParseDescriptorBlockVariableUsage(
if (p_type == NULL) {
return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
}
- // Next access index
+ // Next access chain index
index_index += 1;
}
- // Parse current var again with a type override and advanced index index
- SpvReflectResult result = ParseDescriptorBlockVariableUsage(
- p_parser,
- p_module,
- p_access_chain,
- index_index,
- p_type->op,
- p_var);
- if (result != SPV_REFLECT_RESULT_SUCCESS) {
- return result;
+
+ // Only continue parsing if there's remaining indices in the access
+ // chain. If the end of the access chain has been reach then all
+ // remaining variables (including those in struct hierarchies)
+ // are considered USED.
+ //
+ // See: https://github.com/KhronosGroup/SPIRV-Reflect/issues/78
+ //
+ if (index_index < p_access_chain->index_count) {
+ // Parse current var again with a type override and advanced index index
+ SpvReflectResult result = ParseDescriptorBlockVariableUsage(
+ p_parser,
+ p_module,
+ p_access_chain,
+ index_index,
+ p_type->op,
+ p_var);
+ if (result != SPV_REFLECT_RESULT_SUCCESS) {
+ return result;
+ }
+ }
+ else {
+ // Clear UNUSED flag for remaining variables
+ MarkSelfAndAllMemberVarsAsUsed(p_var);
}
}
break;
@@ -2251,26 +2398,52 @@ static SpvReflectResult ParseDescriptorBlockVariableUsage(
if (p_var->member_count == 0) {
return SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA;
}
-
+ // Get member variable at the access's chain current index
uint32_t index = p_access_chain->indexes[index_index];
-
if (index >= p_var->member_count) {
return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE;
}
-
SpvReflectBlockVariable* p_member_var = &p_var->members[index];
+
+ // Next access chain index
+ index_index += 1;
+
+ // Only continue parsing if there's remaining indices in the access
+ // chain. If the end of the access chain has been reach then all
+ // remaining variables (including those in struct hierarchies)
+ // are considered USED.
+ //
+ // See: https://github.com/KhronosGroup/SPIRV-Reflect/issues/78
+ //
if (index_index < p_access_chain->index_count) {
- SpvReflectResult result = ParseDescriptorBlockVariableUsage(
- p_parser,
- p_module,
- p_access_chain,
- index_index + 1,
- (SpvOp)INVALID_VALUE,
- p_member_var);
- if (result != SPV_REFLECT_RESULT_SUCCESS) {
- return result;
- }
+ SpvReflectResult result = ParseDescriptorBlockVariableUsage(
+ p_parser,
+ p_module,
+ p_access_chain,
+ index_index,
+ (SpvOp)INVALID_VALUE,
+ p_member_var);
+ if (result != SPV_REFLECT_RESULT_SUCCESS) {
+ return result;
+ }
}
+ else {
+ // Clear UNUSED flag for remaining variables
+ MarkSelfAndAllMemberVarsAsUsed(p_member_var);
+ }
+ //SpvReflectBlockVariable* p_member_var = &p_var->members[index];
+ //if (index_index < p_access_chain->index_count) {
+ // SpvReflectResult result = ParseDescriptorBlockVariableUsage(
+ // p_parser,
+ // p_module,
+ // p_access_chain,
+ // index_index + 1,
+ // (SpvOp)INVALID_VALUE,
+ // p_member_var);
+ // if (result != SPV_REFLECT_RESULT_SUCCESS) {
+ // return result;
+ // }
+ //}
}
break;
}
@@ -2342,39 +2515,69 @@ static SpvReflectResult ParseFormat(
)
{
SpvReflectResult result = SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR;
- bool signedness = p_type->traits.numeric.scalar.signedness;
+ bool signedness = (p_type->traits.numeric.scalar.signedness != 0);
+ uint32_t bit_width = p_type->traits.numeric.scalar.width;
if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_VECTOR) {
uint32_t component_count = p_type->traits.numeric.vector.component_count;
if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_FLOAT) {
- switch (component_count) {
- case 2: *p_format = SPV_REFLECT_FORMAT_R32G32_SFLOAT; break;
- case 3: *p_format = SPV_REFLECT_FORMAT_R32G32B32_SFLOAT; break;
- case 4: *p_format = SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT; break;
+ switch (bit_width) {
+ case 32: {
+ switch (component_count) {
+ case 2: *p_format = SPV_REFLECT_FORMAT_R32G32_SFLOAT; break;
+ case 3: *p_format = SPV_REFLECT_FORMAT_R32G32B32_SFLOAT; break;
+ case 4: *p_format = SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT; break;
+ }
+ }
+ case 64: {
+ switch (component_count) {
+ case 2: *p_format = SPV_REFLECT_FORMAT_R64G64_SFLOAT; break;
+ case 3: *p_format = SPV_REFLECT_FORMAT_R64G64B64_SFLOAT; break;
+ case 4: *p_format = SPV_REFLECT_FORMAT_R64G64B64A64_SFLOAT; break;
+ }
+ }
}
result = SPV_REFLECT_RESULT_SUCCESS;
}
else if (p_type->type_flags & (SPV_REFLECT_TYPE_FLAG_INT | SPV_REFLECT_TYPE_FLAG_BOOL)) {
- switch (component_count) {
- case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32_SINT : SPV_REFLECT_FORMAT_R32G32_UINT; break;
- case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32_SINT : SPV_REFLECT_FORMAT_R32G32B32_UINT; break;
- case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32A32_SINT : SPV_REFLECT_FORMAT_R32G32B32A32_UINT; break;
+ switch (bit_width) {
+ case 32: {
+ switch (component_count) {
+ case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32_SINT : SPV_REFLECT_FORMAT_R32G32_UINT; break;
+ case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32_SINT : SPV_REFLECT_FORMAT_R32G32B32_UINT; break;
+ case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R32G32B32A32_SINT : SPV_REFLECT_FORMAT_R32G32B32A32_UINT; break;
+ }
+ }
+ case 64: {
+ switch (component_count) {
+ case 2: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64_SINT : SPV_REFLECT_FORMAT_R64G64_UINT; break;
+ case 3: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64B64_SINT : SPV_REFLECT_FORMAT_R64G64B64_UINT; break;
+ case 4: *p_format = signedness ? SPV_REFLECT_FORMAT_R64G64B64A64_SINT : SPV_REFLECT_FORMAT_R64G64B64A64_UINT; break;
+ }
+ }
}
result = SPV_REFLECT_RESULT_SUCCESS;
}
}
else if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_FLOAT) {
- *p_format = SPV_REFLECT_FORMAT_R32_SFLOAT;
+ switch(bit_width) {
+ case 32:
+ *p_format = SPV_REFLECT_FORMAT_R32_SFLOAT;
+ break;
+ case 64:
+ *p_format = SPV_REFLECT_FORMAT_R64_SFLOAT;
+ break;
+ }
result = SPV_REFLECT_RESULT_SUCCESS;
}
else if (p_type->type_flags & (SPV_REFLECT_TYPE_FLAG_INT | SPV_REFLECT_TYPE_FLAG_BOOL)) {
- if (signedness) {
- *p_format = SPV_REFLECT_FORMAT_R32_SINT;
- result = SPV_REFLECT_RESULT_SUCCESS;
- }
- else {
- *p_format = SPV_REFLECT_FORMAT_R32_UINT;
- result = SPV_REFLECT_RESULT_SUCCESS;
- }
+ switch(bit_width) {
+ case 32:
+ *p_format = signedness ? SPV_REFLECT_FORMAT_R32_SINT : SPV_REFLECT_FORMAT_R32_UINT; break;
+ break;
+ case 64:
+ *p_format = signedness ? SPV_REFLECT_FORMAT_R64_SINT : SPV_REFLECT_FORMAT_R64_UINT; break;
+ }
+ result = SPV_REFLECT_RESULT_SUCCESS;
}
else if (p_type->type_flags & SPV_REFLECT_TYPE_FLAG_STRUCT) {
*p_format = SPV_REFLECT_FORMAT_UNDEFINED;
@@ -2410,6 +2613,7 @@ static SpvReflectResult ParseInterfaceVariable(
SpvReflectInterfaceVariable* p_member_var = &p_var->members[member_index];
SpvReflectResult result = ParseInterfaceVariable(p_parser, p_member_decorations, p_module, p_member_type, p_member_var, p_has_built_in);
if (result != SPV_REFLECT_RESULT_SUCCESS) {
+ SPV_REFLECT_ASSERT(false);
return result;
}
}
@@ -2427,9 +2631,13 @@ static SpvReflectResult ParseInterfaceVariable(
*p_has_built_in |= p_type_node_decorations->is_built_in;
- SpvReflectResult result = ParseFormat(p_var->type_description, &p_var->format);
- if (result != SPV_REFLECT_RESULT_SUCCESS) {
- return result;
+ // Only parse format for interface variables that are input or output
+ if ((p_var->storage_class == SpvStorageClassInput) || (p_var->storage_class == SpvStorageClassOutput)) {
+ SpvReflectResult result = ParseFormat(p_var->type_description, &p_var->format);
+ if (result != SPV_REFLECT_RESULT_SUCCESS) {
+ SPV_REFLECT_ASSERT(false);
+ return result;
+ }
}
return SPV_REFLECT_RESULT_SUCCESS;
@@ -2439,50 +2647,57 @@ static SpvReflectResult ParseInterfaceVariables(
Parser* p_parser,
SpvReflectShaderModule* p_module,
SpvReflectEntryPoint* p_entry,
- size_t io_var_count,
- uint32_t* io_vars
+ uint32_t interface_variable_count,
+ uint32_t* p_interface_variable_ids
)
{
- if (io_var_count == 0) {
+ if (interface_variable_count == 0) {
return SPV_REFLECT_RESULT_SUCCESS;
}
- p_entry->input_variable_count = 0;
- p_entry->output_variable_count = 0;
- for (size_t i = 0; i < io_var_count; ++i) {
- uint32_t var_result_id = *(io_vars + i);
- Node* p_node = FindNode(p_parser, var_result_id);
- if (IsNull(p_node)) {
- return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
- }
-
- if (p_node->storage_class == SpvStorageClassInput) {
- p_entry->input_variable_count += 1;
- }
- else if (p_node->storage_class == SpvStorageClassOutput) {
- p_entry->output_variable_count += 1;
- }
- }
-
- if (p_entry->input_variable_count > 0) {
- p_entry->input_variables = (SpvReflectInterfaceVariable*)calloc(p_entry->input_variable_count, sizeof(*(p_entry->input_variables)));
- if (IsNull(p_entry->input_variables)) {
- return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
- }
- }
-
-
- if (p_entry->output_variable_count > 0) {
- p_entry->output_variables = (SpvReflectInterfaceVariable*)calloc(p_entry->output_variable_count, sizeof(*(p_entry->output_variables)));
- if (IsNull(p_entry->output_variables)) {
+ p_entry->interface_variable_count = interface_variable_count;
+ p_entry->input_variable_count = 0;
+ p_entry->output_variable_count = 0;
+ for (size_t i = 0; i < interface_variable_count; ++i) {
+ uint32_t var_result_id = *(p_interface_variable_ids + i);
+ Node* p_node = FindNode(p_parser, var_result_id);
+ if (IsNull(p_node)) {
+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
+ }
+
+ if (p_node->storage_class == SpvStorageClassInput) {
+ p_entry->input_variable_count += 1;
+ }
+ else if (p_node->storage_class == SpvStorageClassOutput) {
+ p_entry->output_variable_count += 1;
+ }
+ }
+
+ if (p_entry->input_variable_count > 0) {
+ p_entry->input_variables = (SpvReflectInterfaceVariable**)calloc(p_entry->input_variable_count, sizeof(*(p_entry->input_variables)));
+ if (IsNull(p_entry->input_variables)) {
+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
+ }
+ }
+
+ if (p_entry->output_variable_count > 0) {
+ p_entry->output_variables = (SpvReflectInterfaceVariable**)calloc(p_entry->output_variable_count, sizeof(*(p_entry->output_variables)));
+ if (IsNull(p_entry->output_variables)) {
+ return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
+ }
+ }
+
+ if (p_entry->interface_variable_count > 0) {
+ p_entry->interface_variables = (SpvReflectInterfaceVariable*)calloc(p_entry->interface_variable_count, sizeof(*(p_entry->interface_variables)));
+ if (IsNull(p_entry->interface_variables)) {
return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
}
}
size_t input_index = 0;
size_t output_index = 0;
- for (size_t i = 0; i < io_var_count; ++i) {
- uint32_t var_result_id = *(io_vars + i);
+ for (size_t i = 0; i < interface_variable_count; ++i) {
+ uint32_t var_result_id = *(p_interface_variable_ids + i);
Node* p_node = FindNode(p_parser, var_result_id);
if (IsNull(p_node)) {
return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
@@ -2511,22 +2726,8 @@ static SpvReflectResult ParseInterfaceVariables(
return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE;
}
- SpvReflectInterfaceVariable* p_var = NULL;
- if (p_node->storage_class == SpvStorageClassInput) {
- p_var = &(p_entry->input_variables[input_index]);
- p_var->storage_class = SpvStorageClassInput;
- ++input_index;
- }
- else if (p_node->storage_class == SpvStorageClassOutput) {
- p_var = &(p_entry->output_variables[output_index]);
- p_var->storage_class = SpvStorageClassOutput;
- ++output_index;
- } else {
- // interface variables can only have input or output storage classes;
- // anything else is either a new addition or an error.
- assert(false && "Unsupported storage class for interface variable");
- return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_STORAGE_CLASS;
- }
+ SpvReflectInterfaceVariable* p_var = &(p_entry->interface_variables[i]);
+ p_var->storage_class = p_node->storage_class;
bool has_built_in = p_node->decorations.is_built_in;
SpvReflectResult result = ParseInterfaceVariable(
@@ -2537,9 +2738,20 @@ static SpvReflectResult ParseInterfaceVariables(
p_var,
&has_built_in);
if (result != SPV_REFLECT_RESULT_SUCCESS) {
+ SPV_REFLECT_ASSERT(false);
return result;
}
+ // Input and output variables
+ if (p_var->storage_class == SpvStorageClassInput) {
+ p_entry->input_variables[input_index] = p_var;
+ ++input_index;
+ }
+ else if (p_node->storage_class == SpvStorageClassOutput) {
+ p_entry->output_variables[output_index] = p_var;
+ ++output_index;
+ }
+
// SPIR-V result id
p_var->spirv_id = p_node->result_id;
// Name
@@ -2809,6 +3021,14 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul
case SpvExecutionModelGeometry : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_GEOMETRY_BIT; break;
case SpvExecutionModelFragment : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT; break;
case SpvExecutionModelGLCompute : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT; break;
+ case SpvExecutionModelTaskNV : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV; break;
+ case SpvExecutionModelMeshNV : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV; break;
+ case SpvExecutionModelRayGenerationKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR; break;
+ case SpvExecutionModelIntersectionKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR; break;
+ case SpvExecutionModelAnyHitKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR; break;
+ case SpvExecutionModelClosestHitKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; break;
+ case SpvExecutionModelMissKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR; break;
+ case SpvExecutionModelCallableKHR : p_entry_point->shader_stage = SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR; break;
}
++entry_point_index;
@@ -2823,11 +3043,11 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul
p_entry_point->name = (const char*)(p_parser->spirv_code + p_node->word_offset + name_start_word_offset);
uint32_t name_word_count = RoundUp(name_length_with_terminator, SPIRV_WORD_SIZE) / SPIRV_WORD_SIZE;
- size_t interface_variable_count = (p_node->word_count - (name_start_word_offset + name_word_count));
- uint32_t* interface_variables = NULL;
+ uint32_t interface_variable_count = (p_node->word_count - (name_start_word_offset + name_word_count));
+ uint32_t* p_interface_variables = NULL;
if (interface_variable_count > 0) {
- interface_variables = (uint32_t*)calloc(interface_variable_count, sizeof(*(interface_variables)));
- if (IsNull(interface_variables)) {
+ p_interface_variables = (uint32_t*)calloc(interface_variable_count, sizeof(*(p_interface_variables)));
+ if (IsNull(p_interface_variables)) {
return SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED;
}
}
@@ -2836,7 +3056,7 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul
uint32_t var_result_id = (uint32_t)INVALID_VALUE;
uint32_t offset = name_start_word_offset + name_word_count + var_index;
CHECKED_READU32(p_parser, p_node->word_offset + offset, var_result_id);
- interface_variables[var_index] = var_result_id;
+ p_interface_variables[var_index] = var_result_id;
}
result = ParseInterfaceVariables(
@@ -2844,11 +3064,11 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul
p_module,
p_entry_point,
interface_variable_count,
- interface_variables);
+ p_interface_variables);
if (result != SPV_REFLECT_RESULT_SUCCESS) {
return result;
}
- SafeFree(interface_variables);
+ SafeFree(p_interface_variables);
result = ParseStaticallyUsedResources(
p_parser,
@@ -2869,6 +3089,104 @@ static SpvReflectResult ParseEntryPoints(Parser* p_parser, SpvReflectShaderModul
return SPV_REFLECT_RESULT_SUCCESS;
}
+static SpvReflectResult ParseExecutionModes(Parser* p_parser, SpvReflectShaderModule* p_module)
+{
+ assert(IsNotNull(p_parser));
+ assert(IsNotNull(p_parser->nodes));
+ assert(IsNotNull(p_module));
+
+ if (IsNotNull(p_parser) && IsNotNull(p_parser->spirv_code) && IsNotNull(p_parser->nodes)) {
+ for (size_t node_idx = 0; node_idx < p_parser->node_count; ++node_idx) {
+ Node* p_node = &(p_parser->nodes[node_idx]);
+ if (p_node->op != SpvOpExecutionMode) {
+ continue;
+ }
+
+ // Read entry point id
+ uint32_t entry_point_id = 0;
+ CHECKED_READU32(p_parser, p_node->word_offset + 1, entry_point_id);
+
+ // Find entry point
+ SpvReflectEntryPoint* p_entry_point = NULL;
+ for (size_t entry_point_idx = 0; entry_point_idx < p_module->entry_point_count; ++entry_point_idx) {
+ if (p_module->entry_points[entry_point_idx].id == entry_point_id) {
+ p_entry_point = &p_module->entry_points[entry_point_idx];
+ break;
+ }
+ }
+ // Bail if entry point is null
+ if (IsNull(p_entry_point)) {
+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT;
+ }
+
+ // Read execution mode
+ uint32_t execution_mode = (uint32_t)INVALID_VALUE;
+ CHECKED_READU32(p_parser, p_node->word_offset + 2, execution_mode);
+
+ // Parse execution mode
+ switch (execution_mode) {
+ default: {
+ return SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE;
+ }
+ break;
+
+ case SpvExecutionModeInvocations:
+ case SpvExecutionModeSpacingEqual:
+ case SpvExecutionModeSpacingFractionalEven:
+ case SpvExecutionModeSpacingFractionalOdd:
+ case SpvExecutionModeVertexOrderCw:
+ case SpvExecutionModeVertexOrderCcw:
+ case SpvExecutionModePixelCenterInteger:
+ case SpvExecutionModeOriginUpperLeft:
+ case SpvExecutionModeOriginLowerLeft:
+ case SpvExecutionModeEarlyFragmentTests:
+ case SpvExecutionModePointMode:
+ case SpvExecutionModeXfb:
+ case SpvExecutionModeDepthReplacing:
+ case SpvExecutionModeDepthGreater:
+ case SpvExecutionModeDepthLess:
+ case SpvExecutionModeDepthUnchanged:
+ break;
+
+ case SpvExecutionModeLocalSize: {
+ CHECKED_READU32(p_parser, p_node->word_offset + 3, p_entry_point->local_size.x);
+ CHECKED_READU32(p_parser, p_node->word_offset + 4, p_entry_point->local_size.y);
+ CHECKED_READU32(p_parser, p_node->word_offset + 5, p_entry_point->local_size.z);
+ }
+ break;
+
+ case SpvExecutionModeLocalSizeHint:
+ case SpvExecutionModeInputPoints:
+ case SpvExecutionModeInputLines:
+ case SpvExecutionModeInputLinesAdjacency:
+ case SpvExecutionModeTriangles:
+ case SpvExecutionModeInputTrianglesAdjacency:
+ case SpvExecutionModeQuads:
+ case SpvExecutionModeIsolines:
+ case SpvExecutionModeOutputVertices:
+ case SpvExecutionModeOutputPoints:
+ case SpvExecutionModeOutputLineStrip:
+ case SpvExecutionModeOutputTriangleStrip:
+ case SpvExecutionModeVecTypeHint:
+ case SpvExecutionModeContractionOff:
+ case SpvExecutionModeInitializer:
+ case SpvExecutionModeFinalizer:
+ case SpvExecutionModeSubgroupSize:
+ case SpvExecutionModeSubgroupsPerWorkgroup:
+ case SpvExecutionModeSubgroupsPerWorkgroupId:
+ case SpvExecutionModeLocalSizeId:
+ case SpvExecutionModeLocalSizeHintId:
+ case SpvExecutionModePostDepthCoverage:
+ case SpvExecutionModeStencilRefReplacingEXT:
+ case SpvExecutionModeOutputPrimitivesNV:
+ case SpvExecutionModeOutputTrianglesNV:
+ break;
+ }
+ }
+ }
+ return SPV_REFLECT_RESULT_SUCCESS;
+}
+
static SpvReflectResult ParsePushConstantBlocks(Parser* p_parser, SpvReflectShaderModule* p_module)
{
for (size_t i = 0; i < p_parser->node_count; ++i) {
@@ -3180,24 +3498,31 @@ SpvReflectResult spvReflectCreateShaderModule(
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseNodes(&parser);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseStrings(&parser);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseSource(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseFunctions(&parser);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseMemberCounts(&parser);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseNames(&parser);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseDecorations(&parser);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
// Start of reflection data parsing
@@ -3215,24 +3540,31 @@ SpvReflectResult spvReflectCreateShaderModule(
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseTypes(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseDescriptorBindings(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseDescriptorType(p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseUAVCounterBindings(p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseDescriptorBlocks(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParsePushConstantBlocks(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = ParseEntryPoints(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS && p_module->entry_point_count > 0) {
SpvReflectEntryPoint* p_entry = &(p_module->entry_points[0]);
@@ -3244,12 +3576,20 @@ SpvReflectResult spvReflectCreateShaderModule(
p_module->input_variables = p_entry->input_variables;
p_module->output_variable_count = p_entry->output_variable_count;
p_module->output_variables = p_entry->output_variables;
+ p_module->interface_variable_count = p_entry->interface_variable_count;
+ p_module->interface_variables = p_entry->interface_variables;
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = DisambiguateStorageBufferSrvUav(p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
if (result == SPV_REFLECT_RESULT_SUCCESS) {
result = SynchronizeDescriptorSets(p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
+ }
+ if (result == SPV_REFLECT_RESULT_SUCCESS) {
+ result = ParseExecutionModes(&parser, p_module);
+ SPV_REFLECT_ASSERT(result == SPV_REFLECT_RESULT_SUCCESS);
}
// Destroy module if parse was not successful
@@ -3319,6 +3659,8 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module)
return;
}
+ SafeFree(p_module->source_source);
+
// Descriptor set bindings
for (size_t i = 0; i < p_module->descriptor_set_count; ++i) {
SpvReflectDescriptorSet* p_set = &p_module->descriptor_sets[i];
@@ -3335,11 +3677,8 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module)
// Entry points
for (size_t i = 0; i < p_module->entry_point_count; ++i) {
SpvReflectEntryPoint* p_entry = &p_module->entry_points[i];
- for (size_t j = 0; j < p_entry->input_variable_count; j++) {
- SafeFreeInterfaceVariable(&p_entry->input_variables[j]);
- }
- for (size_t j = 0; j < p_entry->output_variable_count; j++) {
- SafeFreeInterfaceVariable(&p_entry->output_variables[j]);
+ for (size_t j = 0; j < p_entry->interface_variable_count; j++) {
+ SafeFreeInterfaceVariable(&p_entry->interface_variables[j]);
}
for (uint32_t j = 0; j < p_entry->descriptor_set_count; ++j) {
SafeFree(p_entry->descriptor_sets[j].bindings);
@@ -3347,6 +3686,7 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module)
SafeFree(p_entry->descriptor_sets);
SafeFree(p_entry->input_variables);
SafeFree(p_entry->output_variables);
+ SafeFree(p_entry->interface_variables);
SafeFree(p_entry->used_uniforms);
SafeFree(p_entry->used_push_constants);
}
@@ -3552,6 +3892,73 @@ SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets(
return SPV_REFLECT_RESULT_SUCCESS;
}
+SpvReflectResult spvReflectEnumerateInterfaceVariables(
+ const SpvReflectShaderModule* p_module,
+ uint32_t* p_count,
+ SpvReflectInterfaceVariable** pp_variables
+)
+{
+ if (IsNull(p_module)) {
+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
+ }
+ if (IsNull(p_count)) {
+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
+ }
+
+ if (IsNotNull(pp_variables)) {
+ if (*p_count != p_module->interface_variable_count) {
+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
+ }
+
+ for (uint32_t index = 0; index < *p_count; ++index) {
+ SpvReflectInterfaceVariable* p_var = &p_module->interface_variables[index];
+ pp_variables[index] = p_var;
+ }
+ }
+ else {
+ *p_count = p_module->interface_variable_count;
+ }
+
+ return SPV_REFLECT_RESULT_SUCCESS;
+}
+
+SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables(
+ const SpvReflectShaderModule* p_module,
+ const char* entry_point,
+ uint32_t* p_count,
+ SpvReflectInterfaceVariable** pp_variables
+)
+{
+ if (IsNull(p_module)) {
+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
+ }
+ if (IsNull(p_count)) {
+ return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
+ }
+
+ const SpvReflectEntryPoint* p_entry =
+ spvReflectGetEntryPoint(p_module, entry_point);
+ if (IsNull(p_entry)) {
+ return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
+ }
+
+ if (IsNotNull(pp_variables)) {
+ if (*p_count != p_entry->interface_variable_count) {
+ return SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH;
+ }
+
+ for (uint32_t index = 0; index < *p_count; ++index) {
+ SpvReflectInterfaceVariable* p_var = &p_entry->interface_variables[index];
+ pp_variables[index] = p_var;
+ }
+ }
+ else {
+ *p_count = p_entry->interface_variable_count;
+ }
+
+ return SPV_REFLECT_RESULT_SUCCESS;
+}
+
SpvReflectResult spvReflectEnumerateInputVariables(
const SpvReflectShaderModule* p_module,
uint32_t* p_count,
@@ -3571,7 +3978,7 @@ SpvReflectResult spvReflectEnumerateInputVariables(
}
for (uint32_t index = 0; index < *p_count; ++index) {
- SpvReflectInterfaceVariable* p_var = (SpvReflectInterfaceVariable*)&p_module->input_variables[index];
+ SpvReflectInterfaceVariable* p_var = p_module->input_variables[index];
pp_variables[index] = p_var;
}
}
@@ -3608,7 +4015,7 @@ SpvReflectResult spvReflectEnumerateEntryPointInputVariables(
}
for (uint32_t index = 0; index < *p_count; ++index) {
- SpvReflectInterfaceVariable* p_var = (SpvReflectInterfaceVariable*)&p_entry->input_variables[index];
+ SpvReflectInterfaceVariable* p_var = p_entry->input_variables[index];
pp_variables[index] = p_var;
}
}
@@ -3638,7 +4045,7 @@ SpvReflectResult spvReflectEnumerateOutputVariables(
}
for (uint32_t index = 0; index < *p_count; ++index) {
- SpvReflectInterfaceVariable* p_var = (SpvReflectInterfaceVariable*)&p_module->output_variables[index];
+ SpvReflectInterfaceVariable* p_var = p_module->output_variables[index];
pp_variables[index] = p_var;
}
}
@@ -3675,7 +4082,7 @@ SpvReflectResult spvReflectEnumerateEntryPointOutputVariables(
}
for (uint32_t index = 0; index < *p_count; ++index) {
- SpvReflectInterfaceVariable* p_var = (SpvReflectInterfaceVariable*)&p_entry->output_variables[index];
+ SpvReflectInterfaceVariable* p_var = p_entry->output_variables[index];
pp_variables[index] = p_var;
}
}
@@ -3907,7 +4314,7 @@ const SpvReflectInterfaceVariable* spvReflectGetInputVariableByLocation(
const SpvReflectInterfaceVariable* p_var = NULL;
if (IsNotNull(p_module)) {
for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {
- const SpvReflectInterfaceVariable* p_potential = &p_module->input_variables[index];
+ const SpvReflectInterfaceVariable* p_potential = p_module->input_variables[index];
if (p_potential->location == location) {
p_var = p_potential;
}
@@ -3955,7 +4362,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableByLocatio
return NULL;
}
for (uint32_t index = 0; index < p_entry->input_variable_count; ++index) {
- const SpvReflectInterfaceVariable* p_potential = &p_entry->input_variables[index];
+ const SpvReflectInterfaceVariable* p_potential = p_entry->input_variables[index];
if (p_potential->location == location) {
p_var = p_potential;
}
@@ -3991,7 +4398,7 @@ const SpvReflectInterfaceVariable* spvReflectGetInputVariableBySemantic(
const SpvReflectInterfaceVariable* p_var = NULL;
if (IsNotNull(p_module)) {
for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {
- const SpvReflectInterfaceVariable* p_potential = &p_module->input_variables[index];
+ const SpvReflectInterfaceVariable* p_potential = p_module->input_variables[index];
if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {
p_var = p_potential;
}
@@ -4035,7 +4442,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableBySemanti
return NULL;
}
for (uint32_t index = 0; index < p_entry->input_variable_count; ++index) {
- const SpvReflectInterfaceVariable* p_potential = &p_entry->input_variables[index];
+ const SpvReflectInterfaceVariable* p_potential = p_entry->input_variables[index];
if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {
p_var = p_potential;
}
@@ -4065,7 +4472,7 @@ const SpvReflectInterfaceVariable* spvReflectGetOutputVariableByLocation(
const SpvReflectInterfaceVariable* p_var = NULL;
if (IsNotNull(p_module)) {
for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {
- const SpvReflectInterfaceVariable* p_potential = &p_module->output_variables[index];
+ const SpvReflectInterfaceVariable* p_potential = p_module->output_variables[index];
if (p_potential->location == location) {
p_var = p_potential;
}
@@ -4112,7 +4519,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableByLocati
return NULL;
}
for (uint32_t index = 0; index < p_entry->output_variable_count; ++index) {
- const SpvReflectInterfaceVariable* p_potential = &p_entry->output_variables[index];
+ const SpvReflectInterfaceVariable* p_potential = p_entry->output_variables[index];
if (p_potential->location == location) {
p_var = p_potential;
}
@@ -4148,7 +4555,7 @@ const SpvReflectInterfaceVariable* spvReflectGetOutputVariableBySemantic(
const SpvReflectInterfaceVariable* p_var = NULL;
if (IsNotNull(p_module)) {
for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {
- const SpvReflectInterfaceVariable* p_potential = &p_module->output_variables[index];
+ const SpvReflectInterfaceVariable* p_potential = p_module->output_variables[index];
if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {
p_var = p_potential;
}
@@ -4191,7 +4598,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableBySemant
return NULL;
}
for (uint32_t index = 0; index < p_entry->output_variable_count; ++index) {
- const SpvReflectInterfaceVariable* p_potential = &p_entry->output_variables[index];
+ const SpvReflectInterfaceVariable* p_potential = p_entry->output_variables[index];
if (p_potential->semantic != NULL && strcmp(p_potential->semantic, semantic) == 0) {
p_var = p_potential;
}
@@ -4297,13 +4704,13 @@ SpvReflectResult spvReflectChangeDescriptorBindingNumbers(
return SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED;
}
// Binding number
- if (new_binding_number != SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE) {
+ if (new_binding_number != (uint32_t)SPV_REFLECT_BINDING_NUMBER_DONT_CHANGE) {
uint32_t* p_code = p_module->_internal->spirv_code + p_target_descriptor->word_offset.binding;
*p_code = new_binding_number;
p_target_descriptor->binding = new_binding_number;
}
// Set number
- if (new_set_binding != SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
+ if (new_set_binding != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
uint32_t* p_code = p_module->_internal->spirv_code + p_target_descriptor->word_offset.set;
*p_code = new_set_binding;
p_target_descriptor->set = new_set_binding;
@@ -4311,7 +4718,7 @@ SpvReflectResult spvReflectChangeDescriptorBindingNumbers(
}
SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;
- if (new_set_binding != SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
+ if (new_set_binding != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
result = SynchronizeDescriptorSets(p_module);
}
return result;
@@ -4352,7 +4759,7 @@ SpvReflectResult spvReflectChangeDescriptorSetNumber(
}
SpvReflectResult result = SPV_REFLECT_RESULT_SUCCESS;
- if (IsNotNull(p_target_set) && new_set_number != SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
+ if (IsNotNull(p_target_set) && new_set_number != (uint32_t)SPV_REFLECT_SET_NUMBER_DONT_CHANGE) {
for (uint32_t index = 0; index < p_target_set->binding_count; ++index) {
SpvReflectDescriptorBinding* p_descriptor = p_target_set->bindings[index];
if (p_descriptor->word_offset.set > (p_module->_internal->spirv_word_count - 1)) {
@@ -4398,8 +4805,8 @@ SpvReflectResult spvReflectChangeInputVariableLocation(
return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
}
for (uint32_t index = 0; index < p_module->input_variable_count; ++index) {
- if(&p_module->input_variables[index] == p_input_variable) {
- return ChangeVariableLocation(p_module, &p_module->input_variables[index], new_location);
+ if(p_module->input_variables[index] == p_input_variable) {
+ return ChangeVariableLocation(p_module, p_module->input_variables[index], new_location);
}
}
return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
@@ -4418,8 +4825,8 @@ SpvReflectResult spvReflectChangeOutputVariableLocation(
return SPV_REFLECT_RESULT_ERROR_NULL_POINTER;
}
for (uint32_t index = 0; index < p_module->output_variable_count; ++index) {
- if(&p_module->output_variables[index] == p_output_variable) {
- return ChangeVariableLocation(p_module, &p_module->output_variables[index], new_location);
+ if(p_module->output_variables[index] == p_output_variable) {
+ return ChangeVariableLocation(p_module, p_module->output_variables[index], new_location);
}
}
return SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND;
diff --git a/thirdparty/spirv-reflect/spirv_reflect.h b/thirdparty/spirv-reflect/spirv_reflect.h
index 6554aaa2cf..a5a956e9e8 100644
--- a/thirdparty/spirv-reflect/spirv_reflect.h
+++ b/thirdparty/spirv-reflect/spirv_reflect.h
@@ -72,26 +72,29 @@ typedef enum SpvReflectResult {
SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_INSTRUCTION,
SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA,
SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE,
+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT,
+ SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE,
} SpvReflectResult;
/*! @enum SpvReflectTypeFlagBits
*/
typedef enum SpvReflectTypeFlagBits {
- SPV_REFLECT_TYPE_FLAG_UNDEFINED = 0x00000000,
- SPV_REFLECT_TYPE_FLAG_VOID = 0x00000001,
- SPV_REFLECT_TYPE_FLAG_BOOL = 0x00000002,
- SPV_REFLECT_TYPE_FLAG_INT = 0x00000004,
- SPV_REFLECT_TYPE_FLAG_FLOAT = 0x00000008,
- SPV_REFLECT_TYPE_FLAG_VECTOR = 0x00000100,
- SPV_REFLECT_TYPE_FLAG_MATRIX = 0x00000200,
- SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE = 0x00010000,
- SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER = 0x00020000,
- SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE = 0x00040000,
- SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK = 0x00080000,
- SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK = 0x000F0000,
- SPV_REFLECT_TYPE_FLAG_STRUCT = 0x10000000,
- SPV_REFLECT_TYPE_FLAG_ARRAY = 0x20000000,
+ SPV_REFLECT_TYPE_FLAG_UNDEFINED = 0x00000000,
+ SPV_REFLECT_TYPE_FLAG_VOID = 0x00000001,
+ SPV_REFLECT_TYPE_FLAG_BOOL = 0x00000002,
+ SPV_REFLECT_TYPE_FLAG_INT = 0x00000004,
+ SPV_REFLECT_TYPE_FLAG_FLOAT = 0x00000008,
+ SPV_REFLECT_TYPE_FLAG_VECTOR = 0x00000100,
+ SPV_REFLECT_TYPE_FLAG_MATRIX = 0x00000200,
+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_IMAGE = 0x00010000,
+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLER = 0x00020000,
+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_SAMPLED_IMAGE = 0x00040000,
+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_BLOCK = 0x00080000,
+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_ACCELERATION_STRUCTURE = 0x00100000,
+ SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK = 0x00FF0000,
+ SPV_REFLECT_TYPE_FLAG_STRUCT = 0x10000000,
+ SPV_REFLECT_TYPE_FLAG_ARRAY = 0x20000000,
} SpvReflectTypeFlagBits;
typedef uint32_t SpvReflectTypeFlags;
@@ -141,6 +144,18 @@ typedef enum SpvReflectFormat {
SPV_REFLECT_FORMAT_R32G32B32A32_UINT = 107, // = VK_FORMAT_R32G32B32A32_UINT
SPV_REFLECT_FORMAT_R32G32B32A32_SINT = 108, // = VK_FORMAT_R32G32B32A32_SINT
SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT = 109, // = VK_FORMAT_R32G32B32A32_SFLOAT
+ SPV_REFLECT_FORMAT_R64_UINT = 110, // = VK_FORMAT_R64_UINT
+ SPV_REFLECT_FORMAT_R64_SINT = 111, // = VK_FORMAT_R64_SINT
+ SPV_REFLECT_FORMAT_R64_SFLOAT = 112, // = VK_FORMAT_R64_SFLOAT
+ SPV_REFLECT_FORMAT_R64G64_UINT = 113, // = VK_FORMAT_R64G64_UINT
+ SPV_REFLECT_FORMAT_R64G64_SINT = 114, // = VK_FORMAT_R64G64_SINT
+ SPV_REFLECT_FORMAT_R64G64_SFLOAT = 115, // = VK_FORMAT_R64G64_SFLOAT
+ SPV_REFLECT_FORMAT_R64G64B64_UINT = 116, // = VK_FORMAT_R64G64B64_UINT
+ SPV_REFLECT_FORMAT_R64G64B64_SINT = 117, // = VK_FORMAT_R64G64B64_SINT
+ SPV_REFLECT_FORMAT_R64G64B64_SFLOAT = 118, // = VK_FORMAT_R64G64B64_FLOAT
+ SPV_REFLECT_FORMAT_R64G64B64A64_UINT = 119, // = VK_FORMAT_R64G64B64A64_UINT
+ SPV_REFLECT_FORMAT_R64G64B64A64_SINT = 120, // = VK_FORMAT_R64G64B64A64_SINT
+ SPV_REFLECT_FORMAT_R64G64B64A64_SFLOAT = 121, // = VK_FORMAT_R64G64B64A64_SFLOAT
} SpvReflectFormat;
/*! @enum SpvReflectVariableFlagBits
@@ -157,17 +172,18 @@ typedef uint32_t SpvReflectVariableFlags;
*/
typedef enum SpvReflectDescriptorType {
- SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER = 0, // = VK_DESCRIPTOR_TYPE_SAMPLER
- SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, // = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
- SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, // = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
- SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, // = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
- SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, // = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
- SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, // = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
- SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
- SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
- SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
- SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
- SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, // = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
+ SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER = 0, // = VK_DESCRIPTOR_TYPE_SAMPLER
+ SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, // = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
+ SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, // = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
+ SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, // = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
+ SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, // = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
+ SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, // = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
+ SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
+ SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
+ SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, // = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
+ SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, // = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
+ SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, // = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
+ SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000 // = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR
} SpvReflectDescriptorType;
/*! @enum SpvReflectShaderStageFlagBits
@@ -180,6 +196,15 @@ typedef enum SpvReflectShaderStageFlagBits {
SPV_REFLECT_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, // = VK_SHADER_STAGE_GEOMETRY_BIT
SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, // = VK_SHADER_STAGE_FRAGMENT_BIT
SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT = 0x00000020, // = VK_SHADER_STAGE_COMPUTE_BIT
+ SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV = 0x00000040, // = VK_SHADER_STAGE_TASK_BIT_NV
+ SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV = 0x00000080, // = VK_SHADER_STAGE_MESH_BIT_NV
+ SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, // VK_SHADER_STAGE_RAYGEN_BIT_KHR
+ SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, // VK_SHADER_STAGE_ANY_HIT_BIT_KHR
+ SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, // VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
+ SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, // VK_SHADER_STAGE_MISS_BIT_KHR
+ SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, // VK_SHADER_STAGE_INTERSECTION_BIT_KHR
+ SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, // VK_SHADER_STAGE_CALLABLE_BIT_KHR
+
} SpvReflectShaderStageFlagBits;
/*! @enum SpvReflectGenerator
@@ -365,10 +390,12 @@ typedef struct SpvReflectEntryPoint {
SpvExecutionModel spirv_execution_model;
SpvReflectShaderStageFlagBits shader_stage;
- uint32_t input_variable_count;
- SpvReflectInterfaceVariable* input_variables;
- uint32_t output_variable_count;
- SpvReflectInterfaceVariable* output_variables;
+ uint32_t input_variable_count;
+ SpvReflectInterfaceVariable** input_variables;
+ uint32_t output_variable_count;
+ SpvReflectInterfaceVariable** output_variables;
+ uint32_t interface_variable_count;
+ SpvReflectInterfaceVariable* interface_variables;
uint32_t descriptor_set_count;
SpvReflectDescriptorSet* descriptor_sets;
@@ -377,6 +404,12 @@ typedef struct SpvReflectEntryPoint {
uint32_t* used_uniforms;
uint32_t used_push_constant_count;
uint32_t* used_push_constants;
+
+ struct LocalSize {
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+ } local_size;
} SpvReflectEntryPoint;
/*! @struct SpvReflectShaderModule
@@ -398,10 +431,12 @@ typedef struct SpvReflectShaderModule {
SpvReflectDescriptorBinding* descriptor_bindings;
uint32_t descriptor_set_count;
SpvReflectDescriptorSet descriptor_sets[SPV_REFLECT_MAX_DESCRIPTOR_SETS];
- uint32_t input_variable_count;
- SpvReflectInterfaceVariable* input_variables;
- uint32_t output_variable_count;
- SpvReflectInterfaceVariable* output_variables;
+ uint32_t input_variable_count;
+ SpvReflectInterfaceVariable** input_variables;
+ uint32_t output_variable_count;
+ SpvReflectInterfaceVariable** output_variables;
+ uint32_t interface_variable_count;
+ SpvReflectInterfaceVariable* interface_variables;
uint32_t push_constant_block_count;
SpvReflectBlockVariable* push_constant_blocks;
@@ -582,6 +617,58 @@ SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets(
);
+/*! @fn spvReflectEnumerateInterfaceVariables
+ @brief If the module contains multiple entry points, this will only get
+ the interface variables for the first one.
+ @param p_module Pointer to an instance of SpvReflectShaderModule.
+ @param p_count If pp_variables is NULL, the module's interface variable
+ count will be stored here.
+ If pp_variables is not NULL, *p_count must contain
+ the module's interface variable count.
+ @param pp_variables If NULL, the module's interface variable count will be
+ written to *p_count.
+ If non-NULL, pp_variables must point to an array with
+ *p_count entries, where pointers to the module's
+ interface variables will be written. The caller must not
+ free the interface variables written to this array.
+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.
+ Otherwise, the error code indicates the cause of the
+ failure.
+
+*/
+SpvReflectResult spvReflectEnumerateInterfaceVariables(
+ const SpvReflectShaderModule* p_module,
+ uint32_t* p_count,
+ SpvReflectInterfaceVariable** pp_variables
+);
+
+/*! @fn spvReflectEnumerateEntryPointInterfaceVariables
+ @brief Enumerate the interface variables for a given entry point.
+ @param entry_point The name of the entry point to get the interface variables for.
+ @param p_module Pointer to an instance of SpvReflectShaderModule.
+ @param p_count If pp_variables is NULL, the entry point's interface variable
+ count will be stored here.
+ If pp_variables is not NULL, *p_count must contain
+ the entry point's interface variable count.
+ @param pp_variables If NULL, the entry point's interface variable count will be
+ written to *p_count.
+ If non-NULL, pp_variables must point to an array with
+ *p_count entries, where pointers to the entry point's
+ interface variables will be written. The caller must not
+ free the interface variables written to this array.
+ @return If successful, returns SPV_REFLECT_RESULT_SUCCESS.
+ Otherwise, the error code indicates the cause of the
+ failure.
+
+*/
+SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables(
+ const SpvReflectShaderModule* p_module,
+ const char* entry_point,
+ uint32_t* p_count,
+ SpvReflectInterfaceVariable** pp_variables
+);
+
+
/*! @fn spvReflectEnumerateInputVariables
@brief If the module contains multiple entry points, this will only get
the input variables for the first one.
@@ -1310,10 +1397,12 @@ public:
SpvReflectResult EnumerateEntryPointDescriptorBindings(const char* entry_point, uint32_t* p_count, SpvReflectDescriptorBinding** pp_bindings) const;
SpvReflectResult EnumerateDescriptorSets( uint32_t* p_count, SpvReflectDescriptorSet** pp_sets) const ;
SpvReflectResult EnumerateEntryPointDescriptorSets(const char* entry_point, uint32_t* p_count, SpvReflectDescriptorSet** pp_sets) const ;
+ SpvReflectResult EnumerateInterfaceVariables(uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const;
+ SpvReflectResult EnumerateEntryPointInterfaceVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const;
SpvReflectResult EnumerateInputVariables(uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const;
- SpvReflectResult EnumerateEntryPointInputVariables(const char* entry_point, uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const;
+ SpvReflectResult EnumerateEntryPointInputVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const;
SpvReflectResult EnumerateOutputVariables(uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const;
- SpvReflectResult EnumerateEntryPointOutputVariables(const char* entry_point, uint32_t* p_count,SpvReflectInterfaceVariable** pp_variables) const;
+ SpvReflectResult EnumerateEntryPointOutputVariables(const char* entry_point, uint32_t* p_count, SpvReflectInterfaceVariable** pp_variables) const;
SpvReflectResult EnumeratePushConstantBlocks(uint32_t* p_count, SpvReflectBlockVariable** pp_blocks) const;
SpvReflectResult EnumerateEntryPointPushConstantBlocks(const char* entry_point, uint32_t* p_count, SpvReflectBlockVariable** pp_blocks) const;
SPV_REFLECT_DEPRECATED("Renamed to EnumeratePushConstantBlocks")
@@ -1361,6 +1450,11 @@ public:
SpvReflectResult ChangeOutputVariableLocation(const SpvReflectInterfaceVariable* p_output_variable, uint32_t new_location);
private:
+ // Make noncopyable
+ ShaderModule(const ShaderModule&);
+ ShaderModule& operator=(const ShaderModule&);
+
+private:
mutable SpvReflectResult m_result = SPV_REFLECT_RESULT_NOT_READY;
SpvReflectShaderModule m_module = {};
};
@@ -1591,6 +1685,48 @@ inline SpvReflectResult ShaderModule::EnumerateEntryPointDescriptorSets(
}
+/*! @fn EnumerateInterfaceVariables
+
+ @param count
+ @param pp_variables
+ @return
+
+*/
+inline SpvReflectResult ShaderModule::EnumerateInterfaceVariables(
+ uint32_t* p_count,
+ SpvReflectInterfaceVariable** pp_variables
+) const
+{
+ m_result = spvReflectEnumerateInterfaceVariables(
+ &m_module,
+ p_count,
+ pp_variables);
+ return m_result;
+}
+
+/*! @fn EnumerateEntryPointInterfaceVariables
+
+ @param entry_point
+ @param count
+ @param pp_variables
+ @return
+
+*/
+inline SpvReflectResult ShaderModule::EnumerateEntryPointInterfaceVariables(
+ const char* entry_point,
+ uint32_t* p_count,
+ SpvReflectInterfaceVariable** pp_variables
+) const
+{
+ m_result = spvReflectEnumerateEntryPointInterfaceVariables(
+ &m_module,
+ entry_point,
+ p_count,
+ pp_variables);
+ return m_result;
+}
+
+
/*! @fn EnumerateInputVariables
@param count
diff --git a/thirdparty/zstd/common/bitstream.h b/thirdparty/zstd/common/bitstream.h
index 37b99c01ee..d9a2730104 100644
--- a/thirdparty/zstd/common/bitstream.h
+++ b/thirdparty/zstd/common/bitstream.h
@@ -17,7 +17,6 @@
#if defined (__cplusplus)
extern "C" {
#endif
-
/*
* This API consists of small unitary functions, which must be inlined for best performance.
* Since link-time-optimization is not available for all compilers,
@@ -36,10 +35,12 @@ extern "C" {
/*=========================================
* Target specific
=========================================*/
-#if defined(__BMI__) && defined(__GNUC__)
-# include <immintrin.h> /* support for bextr (experimental) */
-#elif defined(__ICCARM__)
-# include <intrinsics.h>
+#ifndef ZSTD_NO_INTRINSICS
+# if defined(__BMI__) && defined(__GNUC__)
+# include <immintrin.h> /* support for bextr (experimental) */
+# elif defined(__ICCARM__)
+# include <intrinsics.h>
+# endif
#endif
#define STREAM_ACCUMULATOR_MIN_32 25
@@ -141,8 +142,12 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val)
assert(val != 0);
{
# if defined(_MSC_VER) /* Visual */
- unsigned long r=0;
- return _BitScanReverse ( &r, val ) ? (unsigned)r : 0;
+# if STATIC_BMI2 == 1
+ return _lzcnt_u32(val) ^ 31;
+# else
+ unsigned long r = 0;
+ return _BitScanReverse(&r, val) ? (unsigned)r : 0;
+# endif
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
return __builtin_clz (val) ^ 31;
# elif defined(__ICCARM__) /* IAR Intrinsic */
@@ -198,7 +203,7 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
size_t value, unsigned nbBits)
{
- MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32);
+ DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);
assert(nbBits < BIT_MASK_SIZE);
assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
@@ -271,7 +276,7 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
*/
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
{
- if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
+ if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
bitD->start = (const char*)srcBuffer;
bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
@@ -317,12 +322,12 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
return srcSize;
}
-MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
+MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
{
return bitContainer >> start;
}
-MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
+MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
{
U32 const regMask = sizeof(bitContainer)*8 - 1;
/* if start > regMask, bitstream is corrupted, and result is undefined */
@@ -330,10 +335,14 @@ MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 co
return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
}
-MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
+MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
{
+#if defined(STATIC_BMI2) && STATIC_BMI2 == 1
+ return _bzhi_u64(bitContainer, nbBits);
+#else
assert(nbBits < BIT_MASK_SIZE);
return bitContainer & BIT_mask[nbBits];
+#endif
}
/*! BIT_lookBits() :
@@ -342,7 +351,7 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
* On 32-bits, maxNbBits==24.
* On 64-bits, maxNbBits==56.
* @return : value extracted */
-MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
+MEM_STATIC FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
{
/* arbitrate between double-shift and shift+mask */
#if 1
@@ -365,7 +374,7 @@ MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
}
-MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
+MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
{
bitD->bitsConsumed += nbBits;
}
@@ -374,7 +383,7 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
* Read (consume) next n bits from local register and update.
* Pay attention to not read more than nbBits contained into local register.
* @return : extracted value. */
-MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
+MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
{
size_t const value = BIT_lookBits(bitD, nbBits);
BIT_skipBits(bitD, nbBits);
diff --git a/thirdparty/zstd/common/compiler.h b/thirdparty/zstd/common/compiler.h
index 95e9483521..3e454f38c1 100644
--- a/thirdparty/zstd/common/compiler.h
+++ b/thirdparty/zstd/common/compiler.h
@@ -39,6 +39,17 @@
#endif
/**
+ On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC).
+ This explictly marks such functions as __cdecl so that the code will still compile
+ if a CC other than __cdecl has been made the default.
+*/
+#if defined(_MSC_VER)
+# define WIN_CDECL __cdecl
+#else
+# define WIN_CDECL
+#endif
+
+/**
* FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
* parameters. They must be inlined for the compiler to eliminate the constant
* branches.
@@ -114,12 +125,12 @@
# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
-# elif defined(__aarch64__)
-# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
-# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
+# elif defined(__aarch64__)
+# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
+# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
# else
# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
@@ -172,4 +183,106 @@
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
#endif
+/*Like DYNAMIC_BMI2 but for compile time determination of BMI2 support*/
+#ifndef STATIC_BMI2
+# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86))
+# ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
+# define STATIC_BMI2 1
+# endif
+# endif
+#endif
+
+#ifndef STATIC_BMI2
+ #define STATIC_BMI2 0
+#endif
+
+/* compat. with non-clang compilers */
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/* compat. with non-clang compilers */
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+/* detects whether we are being compiled under msan */
+#ifndef ZSTD_MEMORY_SANITIZER
+# if __has_feature(memory_sanitizer)
+# define ZSTD_MEMORY_SANITIZER 1
+# else
+# define ZSTD_MEMORY_SANITIZER 0
+# endif
+#endif
+
+#if ZSTD_MEMORY_SANITIZER
+/* Not all platforms that support msan provide sanitizers/msan_interface.h.
+ * We therefore declare the functions we need ourselves, rather than trying to
+ * include the header file... */
+#include <stddef.h> /* size_t */
+#define ZSTD_DEPS_NEED_STDINT
+#include "zstd_deps.h" /* intptr_t */
+
+/* Make memory region fully initialized (without changing its contents). */
+void __msan_unpoison(const volatile void *a, size_t size);
+
+/* Make memory region fully uninitialized (without changing its contents).
+ This is a legacy interface that does not update origin information. Use
+ __msan_allocated_memory() instead. */
+void __msan_poison(const volatile void *a, size_t size);
+
+/* Returns the offset of the first (at least partially) poisoned byte in the
+ memory range, or -1 if the whole range is good. */
+intptr_t __msan_test_shadow(const volatile void *x, size_t size);
+#endif
+
+/* detects whether we are being compiled under asan */
+#ifndef ZSTD_ADDRESS_SANITIZER
+# if __has_feature(address_sanitizer)
+# define ZSTD_ADDRESS_SANITIZER 1
+# elif defined(__SANITIZE_ADDRESS__)
+# define ZSTD_ADDRESS_SANITIZER 1
+# else
+# define ZSTD_ADDRESS_SANITIZER 0
+# endif
+#endif
+
+#if ZSTD_ADDRESS_SANITIZER
+/* Not all platforms that support asan provide sanitizers/asan_interface.h.
+ * We therefore declare the functions we need ourselves, rather than trying to
+ * include the header file... */
+#include <stddef.h> /* size_t */
+
+/**
+ * Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.
+ *
+ * This memory must be previously allocated by your program. Instrumented
+ * code is forbidden from accessing addresses in this region until it is
+ * unpoisoned. This function is not guaranteed to poison the entire region -
+ * it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan
+ * alignment restrictions.
+ *
+ * \note This function is not thread-safe because no two threads can poison or
+ * unpoison memory in the same memory region simultaneously.
+ *
+ * \param addr Start of memory region.
+ * \param size Size of memory region. */
+void __asan_poison_memory_region(void const volatile *addr, size_t size);
+
+/**
+ * Marks a memory region (<c>[addr, addr+size)</c>) as addressable.
+ *
+ * This memory must be previously allocated by your program. Accessing
+ * addresses in this region is allowed until this region is poisoned again.
+ * This function could unpoison a super-region of <c>[addr, addr+size)</c> due
+ * to ASan alignment restrictions.
+ *
+ * \note This function is not thread-safe because no two threads can
+ * poison or unpoison memory in the same memory region simultaneously.
+ *
+ * \param addr Start of memory region.
+ * \param size Size of memory region. */
+void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+#endif
+
#endif /* ZSTD_COMPILER_H */
diff --git a/thirdparty/zstd/common/cpu.h b/thirdparty/zstd/common/cpu.h
index 6e8a974f62..cb210593ea 100644
--- a/thirdparty/zstd/common/cpu.h
+++ b/thirdparty/zstd/common/cpu.h
@@ -16,8 +16,6 @@
* https://github.com/facebook/folly/blob/master/folly/CpuId.h
*/
-#include <string.h>
-
#include "mem.h"
#ifdef _MSC_VER
diff --git a/thirdparty/zstd/common/debug.h b/thirdparty/zstd/common/debug.h
index ac6224888d..8b5734366c 100644
--- a/thirdparty/zstd/common/debug.h
+++ b/thirdparty/zstd/common/debug.h
@@ -51,15 +51,6 @@ extern "C" {
#endif
-/* DEBUGFILE can be defined externally,
- * typically through compiler command line.
- * note : currently useless.
- * Value must be stderr or stdout */
-#ifndef DEBUGFILE
-# define DEBUGFILE stderr
-#endif
-
-
/* recommended values for DEBUGLEVEL :
* 0 : release mode, no debug, all run-time checks disabled
* 1 : enables assert() only, no display
@@ -76,7 +67,8 @@ extern "C" {
*/
#if (DEBUGLEVEL>=1)
-# include <assert.h>
+# define ZSTD_DEPS_NEED_ASSERT
+# include "zstd_deps.h"
#else
# ifndef assert /* assert may be already defined, due to prior #include <assert.h> */
# define assert(condition) ((void)0) /* disable assert (default) */
@@ -84,7 +76,8 @@ extern "C" {
#endif
#if (DEBUGLEVEL>=2)
-# include <stdio.h>
+# define ZSTD_DEPS_NEED_IO
+# include "zstd_deps.h"
extern int g_debuglevel; /* the variable is only declared,
it actually lives in debug.c,
and is shared by the whole process.
@@ -92,14 +85,14 @@ extern int g_debuglevel; /* the variable is only declared,
It's useful when enabling very verbose levels
on selective conditions (such as position in src) */
-# define RAWLOG(l, ...) { \
- if (l<=g_debuglevel) { \
- fprintf(stderr, __VA_ARGS__); \
+# define RAWLOG(l, ...) { \
+ if (l<=g_debuglevel) { \
+ ZSTD_DEBUG_PRINT(__VA_ARGS__); \
} }
-# define DEBUGLOG(l, ...) { \
- if (l<=g_debuglevel) { \
- fprintf(stderr, __FILE__ ": " __VA_ARGS__); \
- fprintf(stderr, " \n"); \
+# define DEBUGLOG(l, ...) { \
+ if (l<=g_debuglevel) { \
+ ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \
+ ZSTD_DEBUG_PRINT(" \n"); \
} }
#else
# define RAWLOG(l, ...) {} /* disabled */
diff --git a/thirdparty/zstd/common/entropy_common.c b/thirdparty/zstd/common/entropy_common.c
index 9d3e4e8e36..f9fcb1acfc 100644
--- a/thirdparty/zstd/common/entropy_common.c
+++ b/thirdparty/zstd/common/entropy_common.c
@@ -38,8 +38,31 @@ const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
/*-**************************************************************
* FSE NCount encoding-decoding
****************************************************************/
-size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
- const void* headerBuffer, size_t hbSize)
+static U32 FSE_ctz(U32 val)
+{
+ assert(val != 0);
+ {
+# if defined(_MSC_VER) /* Visual */
+ unsigned long r=0;
+ return _BitScanForward(&r, val) ? (unsigned)r : 0;
+# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
+ return __builtin_ctz(val);
+# elif defined(__ICCARM__) /* IAR Intrinsic */
+ return __CTZ(val);
+# else /* Software version */
+ U32 count = 0;
+ while ((val & 1) == 0) {
+ val >>= 1;
+ ++count;
+ }
+ return count;
+# endif
+ }
+}
+
+FORCE_INLINE_TEMPLATE
+size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
+ const void* headerBuffer, size_t hbSize)
{
const BYTE* const istart = (const BYTE*) headerBuffer;
const BYTE* const iend = istart + hbSize;
@@ -50,23 +73,23 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
U32 bitStream;
int bitCount;
unsigned charnum = 0;
+ unsigned const maxSV1 = *maxSVPtr + 1;
int previous0 = 0;
- if (hbSize < 4) {
- /* This function only works when hbSize >= 4 */
- char buffer[4];
- memset(buffer, 0, sizeof(buffer));
- memcpy(buffer, headerBuffer, hbSize);
+ if (hbSize < 8) {
+ /* This function only works when hbSize >= 8 */
+ char buffer[8] = {0};
+ ZSTD_memcpy(buffer, headerBuffer, hbSize);
{ size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr,
buffer, sizeof(buffer));
if (FSE_isError(countSize)) return countSize;
if (countSize > hbSize) return ERROR(corruption_detected);
return countSize;
} }
- assert(hbSize >= 4);
+ assert(hbSize >= 8);
/* init */
- memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */
+ ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */
bitStream = MEM_readLE32(ip);
nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
@@ -77,36 +100,58 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
threshold = 1<<nbBits;
nbBits++;
- while ((remaining>1) & (charnum<=*maxSVPtr)) {
+ for (;;) {
if (previous0) {
- unsigned n0 = charnum;
- while ((bitStream & 0xFFFF) == 0xFFFF) {
- n0 += 24;
- if (ip < iend-5) {
- ip += 2;
- bitStream = MEM_readLE32(ip) >> bitCount;
+ /* Count the number of repeats. Each time the
+ * 2-bit repeat code is 0b11 there is another
+ * repeat.
+ * Avoid UB by setting the high bit to 1.
+ */
+ int repeats = FSE_ctz(~bitStream | 0x80000000) >> 1;
+ while (repeats >= 12) {
+ charnum += 3 * 12;
+ if (LIKELY(ip <= iend-7)) {
+ ip += 3;
} else {
- bitStream >>= 16;
- bitCount += 16;
- } }
- while ((bitStream & 3) == 3) {
- n0 += 3;
- bitStream >>= 2;
- bitCount += 2;
+ bitCount -= (int)(8 * (iend - 7 - ip));
+ bitCount &= 31;
+ ip = iend - 4;
+ }
+ bitStream = MEM_readLE32(ip) >> bitCount;
+ repeats = FSE_ctz(~bitStream | 0x80000000) >> 1;
}
- n0 += bitStream & 3;
+ charnum += 3 * repeats;
+ bitStream >>= 2 * repeats;
+ bitCount += 2 * repeats;
+
+ /* Add the final repeat which isn't 0b11. */
+ assert((bitStream & 3) < 3);
+ charnum += bitStream & 3;
bitCount += 2;
- if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
- while (charnum < n0) normalizedCounter[charnum++] = 0;
- if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
+
+ /* This is an error, but break and return an error
+ * at the end, because returning out of a loop makes
+ * it harder for the compiler to optimize.
+ */
+ if (charnum >= maxSV1) break;
+
+ /* We don't need to set the normalized count to 0
+ * because we already memset the whole buffer to 0.
+ */
+
+ if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
assert((bitCount >> 3) <= 3); /* For first condition to work */
ip += bitCount>>3;
bitCount &= 7;
- bitStream = MEM_readLE32(ip) >> bitCount;
} else {
- bitStream >>= 2;
- } }
- { int const max = (2*threshold-1) - remaining;
+ bitCount -= (int)(8 * (iend - 4 - ip));
+ bitCount &= 31;
+ ip = iend - 4;
+ }
+ bitStream = MEM_readLE32(ip) >> bitCount;
+ }
+ {
+ int const max = (2*threshold-1) - remaining;
int count;
if ((bitStream & (threshold-1)) < (U32)max) {
@@ -119,24 +164,43 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
}
count--; /* extra accuracy */
- remaining -= count < 0 ? -count : count; /* -1 means +1 */
+ /* When it matters (small blocks), this is a
+ * predictable branch, because we don't use -1.
+ */
+ if (count >= 0) {
+ remaining -= count;
+ } else {
+ assert(count == -1);
+ remaining += count;
+ }
normalizedCounter[charnum++] = (short)count;
previous0 = !count;
- while (remaining < threshold) {
- nbBits--;
- threshold >>= 1;
+
+ assert(threshold > 1);
+ if (remaining < threshold) {
+ /* This branch can be folded into the
+ * threshold update condition because we
+ * know that threshold > 1.
+ */
+ if (remaining <= 1) break;
+ nbBits = BIT_highbit32(remaining) + 1;
+ threshold = 1 << (nbBits - 1);
}
+ if (charnum >= maxSV1) break;
- if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
+ if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
ip += bitCount>>3;
bitCount &= 7;
} else {
bitCount -= (int)(8 * (iend - 4 - ip));
+ bitCount &= 31;
ip = iend - 4;
}
- bitStream = MEM_readLE32(ip) >> (bitCount & 31);
- } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
+ bitStream = MEM_readLE32(ip) >> bitCount;
+ } }
if (remaining != 1) return ERROR(corruption_detected);
+ /* Only possible when there are too many zeros. */
+ if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall);
if (bitCount > 32) return ERROR(corruption_detected);
*maxSVPtr = charnum-1;
@@ -144,6 +208,43 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
return ip-istart;
}
+/* Avoids the FORCE_INLINE of the _body() function. */
+static size_t FSE_readNCount_body_default(
+ short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
+ const void* headerBuffer, size_t hbSize)
+{
+ return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
+}
+
+#if DYNAMIC_BMI2
+TARGET_ATTRIBUTE("bmi2") static size_t FSE_readNCount_body_bmi2(
+ short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
+ const void* headerBuffer, size_t hbSize)
+{
+ return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
+}
+#endif
+
+size_t FSE_readNCount_bmi2(
+ short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
+ const void* headerBuffer, size_t hbSize, int bmi2)
+{
+#if DYNAMIC_BMI2
+ if (bmi2) {
+ return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
+ }
+#endif
+ (void)bmi2;
+ return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
+}
+
+size_t FSE_readNCount(
+ short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
+ const void* headerBuffer, size_t hbSize)
+{
+ return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0);
+}
+
/*! HUF_readStats() :
Read compact Huffman tree, saved by HUF_writeCTable().
@@ -156,6 +257,17 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
U32* nbSymbolsPtr, U32* tableLogPtr,
const void* src, size_t srcSize)
{
+ U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
+ return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* bmi2 */ 0);
+}
+
+FORCE_INLINE_TEMPLATE size_t
+HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats,
+ U32* nbSymbolsPtr, U32* tableLogPtr,
+ const void* src, size_t srcSize,
+ void* workSpace, size_t wkspSize,
+ int bmi2)
+{
U32 weightTotal;
const BYTE* ip = (const BYTE*) src;
size_t iSize;
@@ -163,7 +275,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
if (!srcSize) return ERROR(srcSize_wrong);
iSize = ip[0];
- /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
+ /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
if (iSize >= 128) { /* special header */
oSize = iSize - 127;
@@ -177,14 +289,14 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
huffWeight[n+1] = ip[n/2] & 15;
} } }
else { /* header compressed with FSE (normal case) */
- FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */
if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
- oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */
+ /* max (hwSize-1) values decoded, as last one is implied */
+ oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2);
if (FSE_isError(oSize)) return oSize;
}
/* collect weight stats */
- memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
+ ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
weightTotal = 0;
{ U32 n; for (n=0; n<oSize; n++) {
if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
@@ -214,3 +326,37 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
*nbSymbolsPtr = (U32)(oSize+1);
return iSize+1;
}
+
+/* Avoids the FORCE_INLINE of the _body() function. */
+static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats,
+ U32* nbSymbolsPtr, U32* tableLogPtr,
+ const void* src, size_t srcSize,
+ void* workSpace, size_t wkspSize)
+{
+ return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0);
+}
+
+#if DYNAMIC_BMI2
+static TARGET_ATTRIBUTE("bmi2") size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats,
+ U32* nbSymbolsPtr, U32* tableLogPtr,
+ const void* src, size_t srcSize,
+ void* workSpace, size_t wkspSize)
+{
+ return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1);
+}
+#endif
+
+size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats,
+ U32* nbSymbolsPtr, U32* tableLogPtr,
+ const void* src, size_t srcSize,
+ void* workSpace, size_t wkspSize,
+ int bmi2)
+{
+#if DYNAMIC_BMI2
+ if (bmi2) {
+ return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
+ }
+#endif
+ (void)bmi2;
+ return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
+}
diff --git a/thirdparty/zstd/common/error_private.c b/thirdparty/zstd/common/error_private.c
index cd437529c1..45bba5305b 100644
--- a/thirdparty/zstd/common/error_private.c
+++ b/thirdparty/zstd/common/error_private.c
@@ -48,6 +48,7 @@ const char* ERR_getErrorString(ERR_enum code)
case PREFIX(frameIndex_tooLarge): return "Frame index is too large";
case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking";
case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong";
+ case PREFIX(srcBuffer_wrong): return "Source buffer is wrong";
case PREFIX(maxCode):
default: return notErrorCode;
}
diff --git a/thirdparty/zstd/common/error_private.h b/thirdparty/zstd/common/error_private.h
index 982cf8e9fe..71b37b8dfa 100644
--- a/thirdparty/zstd/common/error_private.h
+++ b/thirdparty/zstd/common/error_private.h
@@ -21,7 +21,7 @@ extern "C" {
/* ****************************************
* Dependencies
******************************************/
-#include <stddef.h> /* size_t */
+#include "zstd_deps.h" /* size_t */
#include "zstd_errors.h" /* enum list */
diff --git a/thirdparty/zstd/common/fse.h b/thirdparty/zstd/common/fse.h
index ff54e70ea7..dd5fc44e80 100644
--- a/thirdparty/zstd/common/fse.h
+++ b/thirdparty/zstd/common/fse.h
@@ -23,7 +23,7 @@ extern "C" {
/*-*****************************************
* Dependencies
******************************************/
-#include <stddef.h> /* size_t, ptrdiff_t */
+#include "zstd_deps.h" /* size_t, ptrdiff_t */
/*-*****************************************
@@ -137,10 +137,16 @@ FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize
/*! FSE_normalizeCount():
normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
+ useLowProbCount is a boolean parameter which trades off compressed size for
+ faster header decoding. When it is set to 1, the compressed data will be slightly
+ smaller. And when it is set to 0, FSE_readNCount() and FSE_buildDTable() will be
+ faster. If you are compressing a small amount of data (< 2 KB) then useLowProbCount=0
+ is a good default, since header deserialization makes a big speed difference.
+ Otherwise, useLowProbCount=1 is a good default, since the speed difference is small.
@return : tableLog,
or an errorCode, which can be tested using FSE_isError() */
FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog,
- const unsigned* count, size_t srcSize, unsigned maxSymbolValue);
+ const unsigned* count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount);
/*! FSE_NCountWriteBound():
Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
@@ -228,6 +234,13 @@ FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter,
unsigned* maxSymbolValuePtr, unsigned* tableLogPtr,
const void* rBuffer, size_t rBuffSize);
+/*! FSE_readNCount_bmi2():
+ * Same as FSE_readNCount() but pass bmi2=1 when your CPU supports BMI2 and 0 otherwise.
+ */
+FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short* normalizedCounter,
+ unsigned* maxSymbolValuePtr, unsigned* tableLogPtr,
+ const void* rBuffer, size_t rBuffSize, int bmi2);
+
/*! Constructor and Destructor of FSE_DTable.
Note that its size depends on 'tableLog' */
typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */
@@ -288,12 +301,12 @@ If there is an error, the function will return an error code, which can be teste
*******************************************/
/* FSE buffer bounds */
#define FSE_NCOUNTBOUND 512
-#define FSE_BLOCKBOUND(size) (size + (size>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */)
+#define FSE_BLOCKBOUND(size) ((size) + ((size)>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */)
#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */
-#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))
-#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog))
+#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<((maxTableLog)-1)) + (((maxSymbolValue)+1)*2))
+#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<(maxTableLog)))
/* or use the size to malloc() space directly. Pay attention to alignment restrictions though */
#define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable))
@@ -309,9 +322,9 @@ unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsi
/* FSE_compress_wksp() :
* Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
- * FSE_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable.
+ * FSE_COMPRESS_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable.
*/
-#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) )
+#define FSE_COMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) )
size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);
@@ -322,18 +335,30 @@ size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
/* FSE_buildCTable_wksp() :
* Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
- * `wkspSize` must be >= `(1<<tableLog)`.
+ * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`.
*/
+#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (maxSymbolValue + 2 + (1ull << (tableLog - 2)))
+#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog))
size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
+#define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) (sizeof(short) * (maxSymbolValue + 1) + (1ULL << maxTableLog) + 8)
+#define FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ((FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) + sizeof(unsigned) - 1) / sizeof(unsigned))
+FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
+/**< Same as FSE_buildDTable(), using an externally allocated `workspace` produced with `FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxSymbolValue)` */
+
size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);
/**< build a fake FSE_DTable, designed to read a flat distribution where each symbol uses nbBits */
size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);
/**< build a fake FSE_DTable, designed to always generate the same symbolValue */
-size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog);
-/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DTABLE_SIZE_U32(maxLog)` */
+#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue))
+#define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned))
+size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize);
+/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)` */
+
+size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2);
+/**< Same as FSE_decompress_wksp() but with dynamic BMI2 support. Pass 1 if your CPU supports BMI2 or 0 if it doesn't. */
typedef enum {
FSE_repeat_none, /**< Cannot use the previous table */
@@ -644,6 +669,9 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
#ifndef FSE_DEFAULT_MEMORY_USAGE
# define FSE_DEFAULT_MEMORY_USAGE 13
#endif
+#if (FSE_DEFAULT_MEMORY_USAGE > FSE_MAX_MEMORY_USAGE)
+# error "FSE_DEFAULT_MEMORY_USAGE must be <= FSE_MAX_MEMORY_USAGE"
+#endif
/*!FSE_MAX_SYMBOL_VALUE :
* Maximum symbol value authorized.
@@ -677,7 +705,7 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
#endif
-#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)
+#define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3)
#endif /* FSE_STATIC_LINKING_ONLY */
diff --git a/thirdparty/zstd/common/fse_decompress.c b/thirdparty/zstd/common/fse_decompress.c
index bcc2223ccc..c164430f99 100644
--- a/thirdparty/zstd/common/fse_decompress.c
+++ b/thirdparty/zstd/common/fse_decompress.c
@@ -16,13 +16,14 @@
/* **************************************************************
* Includes
****************************************************************/
-#include <stdlib.h> /* malloc, free, qsort */
-#include <string.h> /* memcpy, memset */
+#include "debug.h" /* assert */
#include "bitstream.h"
#include "compiler.h"
#define FSE_STATIC_LINKING_ONLY
#include "fse.h"
#include "error_private.h"
+#define ZSTD_DEPS_NEED_MALLOC
+#include "zstd_deps.h"
/* **************************************************************
@@ -59,25 +60,27 @@
FSE_DTable* FSE_createDTable (unsigned tableLog)
{
if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
- return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
+ return (FSE_DTable*)ZSTD_malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
}
void FSE_freeDTable (FSE_DTable* dt)
{
- free(dt);
+ ZSTD_free(dt);
}
-size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
+static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
{
void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */
FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
- U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
+ U16* symbolNext = (U16*)workSpace;
+ BYTE* spread = (BYTE*)(symbolNext + maxSymbolValue + 1);
U32 const maxSV1 = maxSymbolValue + 1;
U32 const tableSize = 1 << tableLog;
U32 highThreshold = tableSize-1;
/* Sanity Checks */
+ if (FSE_BUILD_DTABLE_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(maxSymbolValue_tooLarge);
if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
@@ -95,11 +98,57 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned
if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
symbolNext[s] = normalizedCounter[s];
} } }
- memcpy(dt, &DTableH, sizeof(DTableH));
+ ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
}
/* Spread symbols */
- { U32 const tableMask = tableSize-1;
+ if (highThreshold == tableSize - 1) {
+ size_t const tableMask = tableSize-1;
+ size_t const step = FSE_TABLESTEP(tableSize);
+ /* First lay down the symbols in order.
+ * We use a uint64_t to lay down 8 bytes at a time. This reduces branch
+ * misses since small blocks generally have small table logs, so nearly
+ * all symbols have counts <= 8. We ensure we have 8 bytes at the end of
+ * our buffer to handle the over-write.
+ */
+ {
+ U64 const add = 0x0101010101010101ull;
+ size_t pos = 0;
+ U64 sv = 0;
+ U32 s;
+ for (s=0; s<maxSV1; ++s, sv += add) {
+ int i;
+ int const n = normalizedCounter[s];
+ MEM_write64(spread + pos, sv);
+ for (i = 8; i < n; i += 8) {
+ MEM_write64(spread + pos + i, sv);
+ }
+ pos += n;
+ }
+ }
+ /* Now we spread those positions across the table.
+ * The benefit of doing it in two stages is that we avoid the the
+ * variable size inner loop, which caused lots of branch misses.
+ * Now we can run through all the positions without any branch misses.
+ * We unroll the loop twice, since that is what emperically worked best.
+ */
+ {
+ size_t position = 0;
+ size_t s;
+ size_t const unroll = 2;
+ assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
+ for (s = 0; s < (size_t)tableSize; s += unroll) {
+ size_t u;
+ for (u = 0; u < unroll; ++u) {
+ size_t const uPosition = (position + (u * step)) & tableMask;
+ tableDecode[uPosition].symbol = spread[s + u];
+ }
+ position = (position + (unroll * step)) & tableMask;
+ }
+ assert(position == 0);
+ }
+ } else {
+ U32 const tableMask = tableSize-1;
U32 const step = FSE_TABLESTEP(tableSize);
U32 s, position = 0;
for (s=0; s<maxSV1; s++) {
@@ -124,6 +173,11 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned
return 0;
}
+size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
+{
+ return FSE_buildDTable_internal(dt, normalizedCounter, maxSymbolValue, tableLog, workSpace, wkspSize);
+}
+
#ifndef FSE_COMMONDEFS_ONLY
@@ -251,36 +305,89 @@ size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
}
-size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog)
+size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
+{
+ return FSE_decompress_wksp_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, /* bmi2 */ 0);
+}
+
+FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
+ void* dst, size_t dstCapacity,
+ const void* cSrc, size_t cSrcSize,
+ unsigned maxLog, void* workSpace, size_t wkspSize,
+ int bmi2)
{
const BYTE* const istart = (const BYTE*)cSrc;
const BYTE* ip = istart;
short counting[FSE_MAX_SYMBOL_VALUE+1];
unsigned tableLog;
unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
+ FSE_DTable* const dtable = (FSE_DTable*)workSpace;
/* normal FSE decoding mode */
- size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
+ size_t const NCountLength = FSE_readNCount_bmi2(counting, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
if (FSE_isError(NCountLength)) return NCountLength;
- /* if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); */ /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */
if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
+ assert(NCountLength <= cSrcSize);
ip += NCountLength;
cSrcSize -= NCountLength;
- CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) );
+ if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge);
+ workSpace = dtable + FSE_DTABLE_SIZE_U32(tableLog);
+ wkspSize -= FSE_DTABLE_SIZE(tableLog);
+
+ CHECK_F( FSE_buildDTable_internal(dtable, counting, maxSymbolValue, tableLog, workSpace, wkspSize) );
+
+ {
+ const void* ptr = dtable;
+ const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
+ const U32 fastMode = DTableH->fastMode;
+
+ /* select fast mode (static) */
+ if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1);
+ return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0);
+ }
+}
+
+/* Avoids the FORCE_INLINE of the _body() function. */
+static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
+{
+ return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 0);
+}
+
+#if DYNAMIC_BMI2
+TARGET_ATTRIBUTE("bmi2") static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
+{
+ return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1);
+}
+#endif
- return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */
+size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2)
+{
+#if DYNAMIC_BMI2
+ if (bmi2) {
+ return FSE_decompress_wksp_body_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize);
+ }
+#endif
+ (void)bmi2;
+ return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize);
}
typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
+#ifndef ZSTD_NO_UNUSED_FUNCTIONS
+size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) {
+ U32 wksp[FSE_BUILD_DTABLE_WKSP_SIZE_U32(FSE_TABLELOG_ABSOLUTE_MAX, FSE_MAX_SYMBOL_VALUE)];
+ return FSE_buildDTable_wksp(dt, normalizedCounter, maxSymbolValue, tableLog, wksp, sizeof(wksp));
+}
+
size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize)
{
- DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */
- return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG);
+ /* Static analyzer seems unable to understand this table will be properly initialized later */
+ U32 wksp[FSE_DECOMPRESS_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
+ return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, FSE_MAX_TABLELOG, wksp, sizeof(wksp));
}
-
+#endif
#endif /* FSE_COMMONDEFS_ONLY */
diff --git a/thirdparty/zstd/common/huf.h b/thirdparty/zstd/common/huf.h
index ef432685da..1afef90c7c 100644
--- a/thirdparty/zstd/common/huf.h
+++ b/thirdparty/zstd/common/huf.h
@@ -20,7 +20,7 @@ extern "C" {
#define HUF_H_298734234
/* *** Dependencies *** */
-#include <stddef.h> /* size_t */
+#include "zstd_deps.h" /* size_t */
/* *** library symbols visibility *** */
@@ -111,6 +111,8 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
/* *** Dependencies *** */
#include "mem.h" /* U32 */
+#define FSE_STATIC_LINKING_ONLY
+#include "fse.h"
/* *** Constants *** */
@@ -133,12 +135,16 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
/* static allocation of HUF's Compression Table */
+/* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */
+struct HUF_CElt_s {
+ U16 val;
+ BYTE nbBits;
+}; /* typedef'd to HUF_CElt */
+typedef struct HUF_CElt_s HUF_CElt; /* consider it an incomplete type */
#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */
#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32))
#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
- U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \
- void* name##hv = &(name##hb); \
- HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */
+ HUF_CElt name[HUF_CTABLE_SIZE_U32(maxSymbolValue)] /* no final ; */
/* static allocation of HUF's DTable */
typedef U32 HUF_DTable;
@@ -184,7 +190,6 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
* or to save and regenerate 'CTable' using external methods.
*/
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
-typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */
size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
@@ -226,6 +231,19 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize,
U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,
const void* src, size_t srcSize);
+/*! HUF_readStats_wksp() :
+ * Same as HUF_readStats() but takes an external workspace which must be
+ * 4-byte aligned and its size must be >= HUF_READ_STATS_WORKSPACE_SIZE.
+ * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.
+ */
+#define HUF_READ_STATS_WORKSPACE_SIZE_U32 FSE_DECOMPRESS_WKSP_SIZE_U32(6, HUF_TABLELOG_MAX-1)
+#define HUF_READ_STATS_WORKSPACE_SIZE (HUF_READ_STATS_WORKSPACE_SIZE_U32 * sizeof(unsigned))
+size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize,
+ U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,
+ const void* src, size_t srcSize,
+ void* workspace, size_t wkspSize,
+ int bmi2);
+
/** HUF_readCTable() :
* Loading a CTable saved with HUF_writeCTable() */
size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights);
@@ -332,6 +350,9 @@ size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstS
#endif
size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
+#ifndef HUF_FORCE_DECOMPRESS_X2
+size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2);
+#endif
#endif /* HUF_STATIC_LINKING_ONLY */
diff --git a/thirdparty/zstd/common/mem.h b/thirdparty/zstd/common/mem.h
index 89c8aea7d2..4728ef767b 100644
--- a/thirdparty/zstd/common/mem.h
+++ b/thirdparty/zstd/common/mem.h
@@ -18,8 +18,10 @@ extern "C" {
/*-****************************************
* Dependencies
******************************************/
-#include <stddef.h> /* size_t, ptrdiff_t */
-#include <string.h> /* memcpy */
+#include <stddef.h> /* size_t, ptrdiff_t */
+#include "compiler.h" /* __has_builtin */
+#include "debug.h" /* DEBUG_STATIC_ASSERT */
+#include "zstd_deps.h" /* ZSTD_memcpy */
/*-****************************************
@@ -39,93 +41,15 @@ extern "C" {
# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
#endif
-#ifndef __has_builtin
-# define __has_builtin(x) 0 /* compat. with non-clang compilers */
-#endif
-
-/* code only tested on 32 and 64 bits systems */
-#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; }
-MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
-
-/* detects whether we are being compiled under msan */
-#if defined (__has_feature)
-# if __has_feature(memory_sanitizer)
-# define MEMORY_SANITIZER 1
-# endif
-#endif
-
-#if defined (MEMORY_SANITIZER)
-/* Not all platforms that support msan provide sanitizers/msan_interface.h.
- * We therefore declare the functions we need ourselves, rather than trying to
- * include the header file... */
-
-#include <stdint.h> /* intptr_t */
-
-/* Make memory region fully initialized (without changing its contents). */
-void __msan_unpoison(const volatile void *a, size_t size);
-
-/* Make memory region fully uninitialized (without changing its contents).
- This is a legacy interface that does not update origin information. Use
- __msan_allocated_memory() instead. */
-void __msan_poison(const volatile void *a, size_t size);
-
-/* Returns the offset of the first (at least partially) poisoned byte in the
- memory range, or -1 if the whole range is good. */
-intptr_t __msan_test_shadow(const volatile void *x, size_t size);
-#endif
-
-/* detects whether we are being compiled under asan */
-#if defined (__has_feature)
-# if __has_feature(address_sanitizer)
-# define ADDRESS_SANITIZER 1
-# endif
-#elif defined(__SANITIZE_ADDRESS__)
-# define ADDRESS_SANITIZER 1
-#endif
-
-#if defined (ADDRESS_SANITIZER)
-/* Not all platforms that support asan provide sanitizers/asan_interface.h.
- * We therefore declare the functions we need ourselves, rather than trying to
- * include the header file... */
-
-/**
- * Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.
- *
- * This memory must be previously allocated by your program. Instrumented
- * code is forbidden from accessing addresses in this region until it is
- * unpoisoned. This function is not guaranteed to poison the entire region -
- * it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan
- * alignment restrictions.
- *
- * \note This function is not thread-safe because no two threads can poison or
- * unpoison memory in the same memory region simultaneously.
- *
- * \param addr Start of memory region.
- * \param size Size of memory region. */
-void __asan_poison_memory_region(void const volatile *addr, size_t size);
-
-/**
- * Marks a memory region (<c>[addr, addr+size)</c>) as addressable.
- *
- * This memory must be previously allocated by your program. Accessing
- * addresses in this region is allowed until this region is poisoned again.
- * This function could unpoison a super-region of <c>[addr, addr+size)</c> due
- * to ASan alignment restrictions.
- *
- * \note This function is not thread-safe because no two threads can
- * poison or unpoison memory in the same memory region simultaneously.
- *
- * \param addr Start of memory region.
- * \param size Size of memory region. */
-void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
-#endif
-
-
/*-**************************************************************
* Basic Types
*****************************************************************/
#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
-# include <stdint.h>
+# if defined(_AIX)
+# include <inttypes.h>
+# else
+# include <stdint.h> /* intptr_t */
+# endif
typedef uint8_t BYTE;
typedef uint16_t U16;
typedef int16_t S16;
@@ -157,7 +81,53 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
/*-**************************************************************
-* Memory I/O
+* Memory I/O API
+*****************************************************************/
+/*=== Static platform detection ===*/
+MEM_STATIC unsigned MEM_32bits(void);
+MEM_STATIC unsigned MEM_64bits(void);
+MEM_STATIC unsigned MEM_isLittleEndian(void);
+
+/*=== Native unaligned read/write ===*/
+MEM_STATIC U16 MEM_read16(const void* memPtr);
+MEM_STATIC U32 MEM_read32(const void* memPtr);
+MEM_STATIC U64 MEM_read64(const void* memPtr);
+MEM_STATIC size_t MEM_readST(const void* memPtr);
+
+MEM_STATIC void MEM_write16(void* memPtr, U16 value);
+MEM_STATIC void MEM_write32(void* memPtr, U32 value);
+MEM_STATIC void MEM_write64(void* memPtr, U64 value);
+
+/*=== Little endian unaligned read/write ===*/
+MEM_STATIC U16 MEM_readLE16(const void* memPtr);
+MEM_STATIC U32 MEM_readLE24(const void* memPtr);
+MEM_STATIC U32 MEM_readLE32(const void* memPtr);
+MEM_STATIC U64 MEM_readLE64(const void* memPtr);
+MEM_STATIC size_t MEM_readLEST(const void* memPtr);
+
+MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val);
+MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val);
+MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32);
+MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64);
+MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val);
+
+/*=== Big endian unaligned read/write ===*/
+MEM_STATIC U32 MEM_readBE32(const void* memPtr);
+MEM_STATIC U64 MEM_readBE64(const void* memPtr);
+MEM_STATIC size_t MEM_readBEST(const void* memPtr);
+
+MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32);
+MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64);
+MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val);
+
+/*=== Byteswap ===*/
+MEM_STATIC U32 MEM_swap32(U32 in);
+MEM_STATIC U64 MEM_swap64(U64 in);
+MEM_STATIC size_t MEM_swapST(size_t in);
+
+
+/*-**************************************************************
+* Memory I/O Implementation
*****************************************************************/
/* MEM_FORCE_MEMORY_ACCESS :
* By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
@@ -236,37 +206,37 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v =
MEM_STATIC U16 MEM_read16(const void* memPtr)
{
- U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
+ U16 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
}
MEM_STATIC U32 MEM_read32(const void* memPtr)
{
- U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
+ U32 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
}
MEM_STATIC U64 MEM_read64(const void* memPtr)
{
- U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
+ U64 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
}
MEM_STATIC size_t MEM_readST(const void* memPtr)
{
- size_t val; memcpy(&val, memPtr, sizeof(val)); return val;
+ size_t val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
}
MEM_STATIC void MEM_write16(void* memPtr, U16 value)
{
- memcpy(memPtr, &value, sizeof(value));
+ ZSTD_memcpy(memPtr, &value, sizeof(value));
}
MEM_STATIC void MEM_write32(void* memPtr, U32 value)
{
- memcpy(memPtr, &value, sizeof(value));
+ ZSTD_memcpy(memPtr, &value, sizeof(value));
}
MEM_STATIC void MEM_write64(void* memPtr, U64 value)
{
- memcpy(memPtr, &value, sizeof(value));
+ ZSTD_memcpy(memPtr, &value, sizeof(value));
}
#endif /* MEM_FORCE_MEMORY_ACCESS */
@@ -445,6 +415,9 @@ MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
MEM_writeBE64(memPtr, (U64)val);
}
+/* code only tested on 32 and 64 bits systems */
+MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
+
#if defined (__cplusplus)
}
diff --git a/thirdparty/zstd/common/pool.c b/thirdparty/zstd/common/pool.c
index aa4b4de0d3..4c1b83376f 100644
--- a/thirdparty/zstd/common/pool.c
+++ b/thirdparty/zstd/common/pool.c
@@ -10,9 +10,9 @@
/* ====== Dependencies ======= */
-#include <stddef.h> /* size_t */
+#include "zstd_deps.h" /* size_t */
#include "debug.h" /* assert */
-#include "zstd_internal.h" /* ZSTD_malloc, ZSTD_free */
+#include "zstd_internal.h" /* ZSTD_customMalloc, ZSTD_customFree */
#include "pool.h"
/* ====== Compiler specifics ====== */
@@ -105,6 +105,10 @@ static void* POOL_thread(void* opaque) {
assert(0); /* Unreachable */
}
+POOL_ctx* ZSTD_createThreadPool(size_t numThreads) {
+ return POOL_create (numThreads, 0);
+}
+
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
}
@@ -115,14 +119,14 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
/* Check parameters */
if (!numThreads) { return NULL; }
/* Allocate the context and zero initialize */
- ctx = (POOL_ctx*)ZSTD_calloc(sizeof(POOL_ctx), customMem);
+ ctx = (POOL_ctx*)ZSTD_customCalloc(sizeof(POOL_ctx), customMem);
if (!ctx) { return NULL; }
/* Initialize the job queue.
* It needs one extra space since one space is wasted to differentiate
* empty and full queues.
*/
ctx->queueSize = queueSize + 1;
- ctx->queue = (POOL_job*)ZSTD_malloc(ctx->queueSize * sizeof(POOL_job), customMem);
+ ctx->queue = (POOL_job*)ZSTD_customMalloc(ctx->queueSize * sizeof(POOL_job), customMem);
ctx->queueHead = 0;
ctx->queueTail = 0;
ctx->numThreadsBusy = 0;
@@ -136,7 +140,7 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
}
ctx->shutdown = 0;
/* Allocate space for the thread handles */
- ctx->threads = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
+ ctx->threads = (ZSTD_pthread_t*)ZSTD_customMalloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
ctx->threadCapacity = 0;
ctx->customMem = customMem;
/* Check for errors */
@@ -179,12 +183,14 @@ void POOL_free(POOL_ctx *ctx) {
ZSTD_pthread_mutex_destroy(&ctx->queueMutex);
ZSTD_pthread_cond_destroy(&ctx->queuePushCond);
ZSTD_pthread_cond_destroy(&ctx->queuePopCond);
- ZSTD_free(ctx->queue, ctx->customMem);
- ZSTD_free(ctx->threads, ctx->customMem);
- ZSTD_free(ctx, ctx->customMem);
+ ZSTD_customFree(ctx->queue, ctx->customMem);
+ ZSTD_customFree(ctx->threads, ctx->customMem);
+ ZSTD_customFree(ctx, ctx->customMem);
}
-
+void ZSTD_freeThreadPool (ZSTD_threadPool* pool) {
+ POOL_free (pool);
+}
size_t POOL_sizeof(POOL_ctx *ctx) {
if (ctx==NULL) return 0; /* supports sizeof NULL */
@@ -203,11 +209,11 @@ static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
return 0;
}
/* numThreads > threadCapacity */
- { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
+ { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customMalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
if (!threadPool) return 1;
/* replace existing thread pool */
- memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));
- ZSTD_free(ctx->threads, ctx->customMem);
+ ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));
+ ZSTD_customFree(ctx->threads, ctx->customMem);
ctx->threads = threadPool;
/* Initialize additional threads */
{ size_t threadId;
@@ -301,7 +307,7 @@ int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque)
struct POOL_ctx_s {
int dummy;
};
-static POOL_ctx g_ctx;
+static POOL_ctx g_poolCtx;
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
@@ -311,11 +317,11 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customM
(void)numThreads;
(void)queueSize;
(void)customMem;
- return &g_ctx;
+ return &g_poolCtx;
}
void POOL_free(POOL_ctx* ctx) {
- assert(!ctx || ctx == &g_ctx);
+ assert(!ctx || ctx == &g_poolCtx);
(void)ctx;
}
@@ -337,7 +343,7 @@ int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {
size_t POOL_sizeof(POOL_ctx* ctx) {
if (ctx==NULL) return 0; /* supports sizeof NULL */
- assert(ctx == &g_ctx);
+ assert(ctx == &g_poolCtx);
return sizeof(*ctx);
}
diff --git a/thirdparty/zstd/common/pool.h b/thirdparty/zstd/common/pool.h
index 259bafc975..63954ca6ca 100644
--- a/thirdparty/zstd/common/pool.h
+++ b/thirdparty/zstd/common/pool.h
@@ -16,7 +16,7 @@ extern "C" {
#endif
-#include <stddef.h> /* size_t */
+#include "zstd_deps.h"
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */
#include "../zstd.h"
diff --git a/thirdparty/zstd/common/threading.c b/thirdparty/zstd/common/threading.c
index e2edb313eb..92cf57c195 100644
--- a/thirdparty/zstd/common/threading.c
+++ b/thirdparty/zstd/common/threading.c
@@ -78,11 +78,12 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
-#include <stdlib.h>
+#define ZSTD_DEPS_NEED_MALLOC
+#include "zstd_deps.h"
int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
{
- *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
+ *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
if (!*mutex)
return 1;
return pthread_mutex_init(*mutex, attr);
@@ -94,14 +95,14 @@ int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
return 0;
{
int const ret = pthread_mutex_destroy(*mutex);
- free(*mutex);
+ ZSTD_free(*mutex);
return ret;
}
}
int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
{
- *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));
+ *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
if (!*cond)
return 1;
return pthread_cond_init(*cond, attr);
@@ -113,7 +114,7 @@ int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
return 0;
{
int const ret = pthread_cond_destroy(*cond);
- free(*cond);
+ ZSTD_free(*cond);
return ret;
}
}
diff --git a/thirdparty/zstd/common/xxhash.c b/thirdparty/zstd/common/xxhash.c
index 597de18fc8..e708df3c33 100644
--- a/thirdparty/zstd/common/xxhash.c
+++ b/thirdparty/zstd/common/xxhash.c
@@ -77,14 +77,12 @@
* Includes & Memory related functions
***************************************/
/* Modify the local functions below should you wish to use some other memory routines */
-/* for malloc(), free() */
-#include <stdlib.h>
-#include <stddef.h> /* size_t */
-static void* XXH_malloc(size_t s) { return malloc(s); }
-static void XXH_free (void* p) { free(p); }
-/* for memcpy() */
-#include <string.h>
-static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
+/* for ZSTD_malloc(), ZSTD_free() */
+#define ZSTD_DEPS_NEED_MALLOC
+#include "zstd_deps.h" /* size_t, ZSTD_malloc, ZSTD_free, ZSTD_memcpy */
+static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); }
+static void XXH_free (void* p) { ZSTD_free(p); }
+static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); }
#ifndef XXH_STATIC_LINKING_ONLY
# define XXH_STATIC_LINKING_ONLY
@@ -95,49 +93,13 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp
/* *************************************
* Compiler Specific Options
***************************************/
-#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
-# define INLINE_KEYWORD inline
-#else
-# define INLINE_KEYWORD
-#endif
-
-#if defined(__GNUC__) || defined(__ICCARM__)
-# define FORCE_INLINE_ATTR __attribute__((always_inline))
-#elif defined(_MSC_VER)
-# define FORCE_INLINE_ATTR __forceinline
-#else
-# define FORCE_INLINE_ATTR
-#endif
-
-#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
-
-
-#ifdef _MSC_VER
-# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
-#endif
+#include "compiler.h"
/* *************************************
* Basic Types
***************************************/
-#ifndef MEM_MODULE
-# define MEM_MODULE
-# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
-# include <stdint.h>
- typedef uint8_t BYTE;
- typedef uint16_t U16;
- typedef uint32_t U32;
- typedef int32_t S32;
- typedef uint64_t U64;
-# else
- typedef unsigned char BYTE;
- typedef unsigned short U16;
- typedef unsigned int U32;
- typedef signed int S32;
- typedef unsigned long long U64; /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */
-# endif
-#endif
-
+#include "mem.h" /* BYTE, U32, U64, size_t */
#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
@@ -163,14 +125,14 @@ static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
static U32 XXH_read32(const void* memPtr)
{
U32 val;
- memcpy(&val, memPtr, sizeof(val));
+ ZSTD_memcpy(&val, memPtr, sizeof(val));
return val;
}
static U64 XXH_read64(const void* memPtr)
{
U64 val;
- memcpy(&val, memPtr, sizeof(val));
+ ZSTD_memcpy(&val, memPtr, sizeof(val));
return val;
}
@@ -307,12 +269,12 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
****************************/
XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState)
{
- memcpy(dstState, srcState, sizeof(*dstState));
+ ZSTD_memcpy(dstState, srcState, sizeof(*dstState));
}
XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState)
{
- memcpy(dstState, srcState, sizeof(*dstState));
+ ZSTD_memcpy(dstState, srcState, sizeof(*dstState));
}
@@ -554,12 +516,12 @@ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
{
XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
- memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */
+ ZSTD_memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */
state.v1 = seed + PRIME32_1 + PRIME32_2;
state.v2 = seed + PRIME32_2;
state.v3 = seed + 0;
state.v4 = seed - PRIME32_1;
- memcpy(statePtr, &state, sizeof(state));
+ ZSTD_memcpy(statePtr, &state, sizeof(state));
return XXH_OK;
}
@@ -567,12 +529,12 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int s
XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
{
XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
- memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */
+ ZSTD_memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */
state.v1 = seed + PRIME64_1 + PRIME64_2;
state.v2 = seed + PRIME64_2;
state.v3 = seed + 0;
state.v4 = seed - PRIME64_1;
- memcpy(statePtr, &state, sizeof(state));
+ ZSTD_memcpy(statePtr, &state, sizeof(state));
return XXH_OK;
}
@@ -843,14 +805,14 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
{
XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
- memcpy(dst, &hash, sizeof(*dst));
+ ZSTD_memcpy(dst, &hash, sizeof(*dst));
}
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
{
XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
- memcpy(dst, &hash, sizeof(*dst));
+ ZSTD_memcpy(dst, &hash, sizeof(*dst));
}
XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
diff --git a/thirdparty/zstd/common/xxhash.h b/thirdparty/zstd/common/xxhash.h
index 4207eba832..eceb55d5e0 100644
--- a/thirdparty/zstd/common/xxhash.h
+++ b/thirdparty/zstd/common/xxhash.h
@@ -55,7 +55,7 @@ extern "C" {
/* ****************************
* Definitions
******************************/
-#include <stddef.h> /* size_t */
+#include "zstd_deps.h"
typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
diff --git a/thirdparty/zstd/common/zstd_common.c b/thirdparty/zstd/common/zstd_common.c
index 91fe3323a5..939e9f08fa 100644
--- a/thirdparty/zstd/common/zstd_common.c
+++ b/thirdparty/zstd/common/zstd_common.c
@@ -13,8 +13,8 @@
/*-*************************************
* Dependencies
***************************************/
-#include <stdlib.h> /* malloc, calloc, free */
-#include <string.h> /* memset */
+#define ZSTD_DEPS_NEED_MALLOC
+#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */
#include "error_private.h"
#include "zstd_internal.h"
@@ -53,31 +53,31 @@ const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString
/*=**************************************************************
* Custom allocator
****************************************************************/
-void* ZSTD_malloc(size_t size, ZSTD_customMem customMem)
+void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem)
{
if (customMem.customAlloc)
return customMem.customAlloc(customMem.opaque, size);
- return malloc(size);
+ return ZSTD_malloc(size);
}
-void* ZSTD_calloc(size_t size, ZSTD_customMem customMem)
+void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem)
{
if (customMem.customAlloc) {
/* calloc implemented as malloc+memset;
* not as efficient as calloc, but next best guess for custom malloc */
void* const ptr = customMem.customAlloc(customMem.opaque, size);
- memset(ptr, 0, size);
+ ZSTD_memset(ptr, 0, size);
return ptr;
}
- return calloc(1, size);
+ return ZSTD_calloc(1, size);
}
-void ZSTD_free(void* ptr, ZSTD_customMem customMem)
+void ZSTD_customFree(void* ptr, ZSTD_customMem customMem)
{
if (ptr!=NULL) {
if (customMem.customFree)
customMem.customFree(customMem.opaque, ptr);
else
- free(ptr);
+ ZSTD_free(ptr);
}
}
diff --git a/thirdparty/zstd/common/zstd_deps.h b/thirdparty/zstd/common/zstd_deps.h
new file mode 100644
index 0000000000..0fb8b7818b
--- /dev/null
+++ b/thirdparty/zstd/common/zstd_deps.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016-2020, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+/* This file provides common libc dependencies that zstd requires.
+ * The purpose is to allow replacing this file with a custom implementation
+ * to compile zstd without libc support.
+ */
+
+/* Need:
+ * NULL
+ * INT_MAX
+ * UINT_MAX
+ * ZSTD_memcpy()
+ * ZSTD_memset()
+ * ZSTD_memmove()
+ */
+#ifndef ZSTD_DEPS_COMMON
+#define ZSTD_DEPS_COMMON
+
+#include <limits.h>
+#include <stddef.h>
+#include <string.h>
+
+#if defined(__GNUC__) && __GNUC__ >= 4
+# define ZSTD_memcpy(d,s,l) __builtin_memcpy((d),(s),(l))
+# define ZSTD_memmove(d,s,l) __builtin_memmove((d),(s),(l))
+# define ZSTD_memset(p,v,l) __builtin_memset((p),(v),(l))
+#else
+# define ZSTD_memcpy(d,s,l) memcpy((d),(s),(l))
+# define ZSTD_memmove(d,s,l) memmove((d),(s),(l))
+# define ZSTD_memset(p,v,l) memset((p),(v),(l))
+#endif
+
+#endif /* ZSTD_DEPS_COMMON */
+
+/* Need:
+ * ZSTD_malloc()
+ * ZSTD_free()
+ * ZSTD_calloc()
+ */
+#ifdef ZSTD_DEPS_NEED_MALLOC
+#ifndef ZSTD_DEPS_MALLOC
+#define ZSTD_DEPS_MALLOC
+
+#include <stdlib.h>
+
+#define ZSTD_malloc(s) malloc(s)
+#define ZSTD_calloc(n,s) calloc((n), (s))
+#define ZSTD_free(p) free((p))
+
+#endif /* ZSTD_DEPS_MALLOC */
+#endif /* ZSTD_DEPS_NEED_MALLOC */
+
+/*
+ * Provides 64-bit math support.
+ * Need:
+ * U64 ZSTD_div64(U64 dividend, U32 divisor)
+ */
+#ifdef ZSTD_DEPS_NEED_MATH64
+#ifndef ZSTD_DEPS_MATH64
+#define ZSTD_DEPS_MATH64
+
+#define ZSTD_div64(dividend, divisor) ((dividend) / (divisor))
+
+#endif /* ZSTD_DEPS_MATH64 */
+#endif /* ZSTD_DEPS_NEED_MATH64 */
+
+/* Need:
+ * assert()
+ */
+#ifdef ZSTD_DEPS_NEED_ASSERT
+#ifndef ZSTD_DEPS_ASSERT
+#define ZSTD_DEPS_ASSERT
+
+#include <assert.h>
+
+#endif /* ZSTD_DEPS_ASSERT */
+#endif /* ZSTD_DEPS_NEED_ASSERT */
+
+/* Need:
+ * ZSTD_DEBUG_PRINT()
+ */
+#ifdef ZSTD_DEPS_NEED_IO
+#ifndef ZSTD_DEPS_IO
+#define ZSTD_DEPS_IO
+
+#include <stdio.h>
+#define ZSTD_DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__)
+
+#endif /* ZSTD_DEPS_IO */
+#endif /* ZSTD_DEPS_NEED_IO */
+
+/* Only requested when <stdint.h> is known to be present.
+ * Need:
+ * intptr_t
+ */
+#ifdef ZSTD_DEPS_NEED_STDINT
+#ifndef ZSTD_DEPS_STDINT
+#define ZSTD_DEPS_STDINT
+
+#include <stdint.h>
+
+#endif /* ZSTD_DEPS_STDINT */
+#endif /* ZSTD_DEPS_NEED_STDINT */
diff --git a/thirdparty/zstd/common/zstd_errors.h b/thirdparty/zstd/common/zstd_errors.h
index 998398e7e5..6d0d003004 100644
--- a/thirdparty/zstd/common/zstd_errors.h
+++ b/thirdparty/zstd/common/zstd_errors.h
@@ -77,6 +77,7 @@ typedef enum {
ZSTD_error_frameIndex_tooLarge = 100,
ZSTD_error_seekableIO = 102,
ZSTD_error_dstBuffer_wrong = 104,
+ ZSTD_error_srcBuffer_wrong = 105,
ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */
} ZSTD_ErrorCode;
diff --git a/thirdparty/zstd/common/zstd_internal.h b/thirdparty/zstd/common/zstd_internal.h
index 3bc7e55a0a..0991f20a08 100644
--- a/thirdparty/zstd/common/zstd_internal.h
+++ b/thirdparty/zstd/common/zstd_internal.h
@@ -19,7 +19,7 @@
/*-*************************************
* Dependencies
***************************************/
-#ifdef __aarch64__
+#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)
#include <arm_neon.h>
#endif
#include "compiler.h"
@@ -139,7 +139,7 @@ void _force_has_format_string(const char *format, ...) {
#define ZSTD_REP_NUM 3 /* number of repcodes */
#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
-static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
+static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
#define KB *(1 <<10)
#define MB *(1 <<20)
@@ -153,13 +153,13 @@ static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
#define BIT0 1
#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
-static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
-static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
+static UNUSED_ATTR const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
+static UNUSED_ATTR const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
#define ZSTD_FRAMEIDSIZE 4 /* magic number size */
#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
-static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
+static UNUSED_ATTR const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
#define ZSTD_FRAMECHECKSUMSIZE 4
@@ -186,61 +186,75 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy
#define OffFSELog 8
#define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
-static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 2, 2, 3, 3,
- 4, 6, 7, 8, 9,10,11,12,
- 13,14,15,16 };
-static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 3, 2, 1, 1, 1, 1, 1,
- -1,-1,-1,-1 };
+#define ZSTD_MAX_HUF_HEADER_SIZE 128 /* header + <= 127 byte tree description */
+/* Each table cannot take more than #symbols * FSELog bits */
+#define ZSTD_MAX_FSE_HEADERS_SIZE (((MaxML + 1) * MLFSELog + (MaxLL + 1) * LLFSELog + (MaxOff + 1) * OffFSELog + 7) / 8)
+
+static UNUSED_ATTR const U32 LL_bits[MaxLL+1] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 2, 2, 3, 3,
+ 4, 6, 7, 8, 9,10,11,12,
+ 13,14,15,16
+};
+static UNUSED_ATTR const S16 LL_defaultNorm[MaxLL+1] = {
+ 4, 3, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 3, 2, 1, 1, 1, 1, 1,
+ -1,-1,-1,-1
+};
#define LL_DEFAULTNORMLOG 6 /* for static allocation */
-static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
-
-static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 2, 2, 3, 3,
- 4, 4, 5, 7, 8, 9,10,11,
- 12,13,14,15,16 };
-static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2,
- 2, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1,-1,-1,
- -1,-1,-1,-1,-1 };
+static UNUSED_ATTR const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
+
+static UNUSED_ATTR const U32 ML_bits[MaxML+1] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 2, 2, 3, 3,
+ 4, 4, 5, 7, 8, 9,10,11,
+ 12,13,14,15,16
+};
+static UNUSED_ATTR const S16 ML_defaultNorm[MaxML+1] = {
+ 1, 4, 3, 2, 2, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1,-1,-1,
+ -1,-1,-1,-1,-1
+};
#define ML_DEFAULTNORMLOG 6 /* for static allocation */
-static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
-
-static const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2,
- 2, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- -1,-1,-1,-1,-1 };
+static UNUSED_ATTR const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
+
+static UNUSED_ATTR const S16 OF_defaultNorm[DefaultMaxOff+1] = {
+ 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ -1,-1,-1,-1,-1
+};
#define OF_DEFAULTNORMLOG 5 /* for static allocation */
-static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
+static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
/*-*******************************************
* Shared functions to include for inlining
*********************************************/
static void ZSTD_copy8(void* dst, const void* src) {
-#ifdef __aarch64__
+#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)
vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
#else
- memcpy(dst, src, 8);
+ ZSTD_memcpy(dst, src, 8);
#endif
}
#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
static void ZSTD_copy16(void* dst, const void* src) {
-#ifdef __aarch64__
+#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON)
vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
#else
- memcpy(dst, src, 16);
+ ZSTD_memcpy(dst, src, 16);
#endif
}
#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
@@ -255,13 +269,13 @@ typedef enum {
} ZSTD_overlap_e;
/*! ZSTD_wildcopy() :
- * Custom version of memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
+ * Custom version of ZSTD_memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
* @param ovtype controls the overlap detection
* - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
* - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
* The src buffer must be before the dst buffer.
*/
-MEM_STATIC FORCE_INLINE_ATTR
+MEM_STATIC FORCE_INLINE_ATTR
void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
{
ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
@@ -284,14 +298,16 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e
* one COPY16() in the first call. Then, do two calls per loop since
* at that point it is more likely to have a high trip count.
*/
-#ifndef __aarch64__
+#ifdef __aarch64__
do {
COPY16(op, ip);
}
while (op < oend);
#else
- COPY16(op, ip);
- if (op >= oend) return;
+ ZSTD_copy16(op, ip);
+ if (16 >= length) return;
+ op += 16;
+ ip += 16;
do {
COPY16(op, ip);
COPY16(op, ip);
@@ -305,7 +321,7 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src,
{
size_t const length = MIN(dstCapacity, srcSize);
if (length > 0) {
- memcpy(dst, src, length);
+ ZSTD_memcpy(dst, src, length);
}
return length;
}
@@ -320,28 +336,39 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src,
* In which case, resize it down to free some memory */
#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
+/* Controls whether the input/output buffer is buffered or stable. */
+typedef enum {
+ ZSTD_bm_buffered = 0, /* Buffer the input/output */
+ ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */
+} ZSTD_bufferMode_e;
+
/*-*******************************************
* Private declarations
*********************************************/
typedef struct seqDef_s {
- U32 offset;
+ U32 offset; /* Offset code of the sequence */
U16 litLength;
U16 matchLength;
} seqDef;
typedef struct {
seqDef* sequencesStart;
- seqDef* sequences;
+ seqDef* sequences; /* ptr to end of sequences */
BYTE* litStart;
- BYTE* lit;
+ BYTE* lit; /* ptr to end of literals */
BYTE* llCode;
BYTE* mlCode;
BYTE* ofCode;
size_t maxNbSeq;
size_t maxNbLit;
- U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
- U32 longLengthPos;
+
+ /* longLengthPos and longLengthID to allow us to represent either a single litLength or matchLength
+ * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment
+ * the existing value of the litLength or matchLength by 0x10000.
+ */
+ U32 longLengthID; /* 0 == no longLength; 1 == Represent the long literal; 2 == Represent the long match; */
+ U32 longLengthPos; /* Index of the sequence to apply long length modification to */
} seqStore_t;
typedef struct {
@@ -384,9 +411,9 @@ const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBu
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
/* custom memory allocation functions */
-void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
-void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
-void ZSTD_free(void* ptr, ZSTD_customMem customMem);
+void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem);
+void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem);
+void ZSTD_customFree(void* ptr, ZSTD_customMem customMem);
MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
@@ -394,8 +421,12 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus
assert(val != 0);
{
# if defined(_MSC_VER) /* Visual */
- unsigned long r=0;
- return _BitScanReverse(&r, val) ? (unsigned)r : 0;
+# if STATIC_BMI2 == 1
+ return _lzcnt_u32(val)^31;
+# else
+ unsigned long r=0;
+ return _BitScanReverse(&r, val) ? (unsigned)r : 0;
+# endif
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
return __builtin_clz (val) ^ 31;
# elif defined(__ICCARM__) /* IAR Intrinsic */
diff --git a/thirdparty/zstd/compress/fse_compress.c b/thirdparty/zstd/compress/fse_compress.c
index a42759814f..304a82b3cc 100644
--- a/thirdparty/zstd/compress/fse_compress.c
+++ b/thirdparty/zstd/compress/fse_compress.c
@@ -15,8 +15,6 @@
/* **************************************************************
* Includes
****************************************************************/
-#include <stdlib.h> /* malloc, free, qsort */
-#include <string.h> /* memcpy, memset */
#include "../common/compiler.h"
#include "../common/mem.h" /* U32, U16, etc. */
#include "../common/debug.h" /* assert, DEBUGLOG */
@@ -25,6 +23,9 @@
#define FSE_STATIC_LINKING_ONLY
#include "../common/fse.h"
#include "../common/error_private.h"
+#define ZSTD_DEPS_NEED_MALLOC
+#define ZSTD_DEPS_NEED_MATH64
+#include "../common/zstd_deps.h" /* ZSTD_malloc, ZSTD_free, ZSTD_memcpy, ZSTD_memset */
/* **************************************************************
@@ -74,13 +75,15 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
U32 const step = FSE_TABLESTEP(tableSize);
- U32 cumul[FSE_MAX_SYMBOL_VALUE+2];
- FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;
+ U32* cumul = (U32*)workSpace;
+ FSE_FUNCTION_TYPE* tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSymbolValue + 2));
+
U32 highThreshold = tableSize-1;
+ if ((size_t)workSpace & 3) return ERROR(GENERIC); /* Must be 4 byte aligned */
+ if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge);
/* CTable header */
- if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
tableU16[-2] = (U16) tableLog;
tableU16[-1] = (U16) maxSymbolValue;
assert(tableLog < 16); /* required for threshold strategy to work */
@@ -89,7 +92,7 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
* http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
#ifdef __clang_analyzer__
- memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */
+ ZSTD_memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */
#endif
/* symbol start positions */
@@ -168,12 +171,13 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
return 0;
}
-
+#ifndef ZSTD_NO_UNUSED_FUNCTIONS
size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
{
FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol));
}
+#endif
@@ -307,10 +311,10 @@ FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
size_t size;
if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
- return (FSE_CTable*)malloc(size);
+ return (FSE_CTable*)ZSTD_malloc(size);
}
-void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
+void FSE_freeCTable (FSE_CTable* ct) { ZSTD_free(ct); }
/* provides the minimum logSize to safely represent a distribution */
static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
@@ -341,11 +345,10 @@ unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
}
-
/* Secondary normalization method.
To be used when primary method fails. */
-static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
+static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue, short lowProbCount)
{
short const NOT_YET_ASSIGNED = -2;
U32 s;
@@ -362,7 +365,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
continue;
}
if (count[s] <= lowThreshold) {
- norm[s] = -1;
+ norm[s] = lowProbCount;
distributed++;
total -= count[s];
continue;
@@ -414,7 +417,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
{ U64 const vStepLog = 62 - tableLog;
U64 const mid = (1ULL << (vStepLog-1)) - 1;
- U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */
+ U64 const rStep = ZSTD_div64((((U64)1<<vStepLog) * ToDistribute) + mid, (U32)total); /* scale on remaining */
U64 tmpTotal = mid;
for (s=0; s<=maxSymbolValue; s++) {
if (norm[s]==NOT_YET_ASSIGNED) {
@@ -431,10 +434,9 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
return 0;
}
-
size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
const unsigned* count, size_t total,
- unsigned maxSymbolValue)
+ unsigned maxSymbolValue, unsigned useLowProbCount)
{
/* Sanity checks */
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
@@ -443,8 +445,9 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
{ static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
+ short const lowProbCount = useLowProbCount ? -1 : 1;
U64 const scale = 62 - tableLog;
- U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
+ U64 const step = ZSTD_div64((U64)1<<62, (U32)total); /* <== here, one division ! */
U64 const vStep = 1ULL<<(scale-20);
int stillToDistribute = 1<<tableLog;
unsigned s;
@@ -456,7 +459,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
if (count[s] == total) return 0; /* rle special case */
if (count[s] == 0) { normalizedCounter[s]=0; continue; }
if (count[s] <= lowThreshold) {
- normalizedCounter[s] = -1;
+ normalizedCounter[s] = lowProbCount;
stillToDistribute--;
} else {
short proba = (short)((count[s]*step) >> scale);
@@ -470,7 +473,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
} }
if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
/* corner case, need another normalization method */
- size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
+ size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount);
if (FSE_isError(errorCode)) return errorCode;
}
else normalizedCounter[largest] += (short)stillToDistribute;
@@ -625,6 +628,7 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
+#ifndef ZSTD_NO_UNUSED_FUNCTIONS
/* FSE_compress_wksp() :
* Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
* `wkspSize` size must be `(1<<tableLog)`.
@@ -643,7 +647,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable));
/* init conditions */
- if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge);
+ if (wkspSize < FSE_COMPRESS_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge);
if (srcSize <= 1) return 0; /* Not compressible */
if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
@@ -656,7 +660,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
}
tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
- CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
+ CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue, /* useLowProbCount */ srcSize >= 2048) );
/* Write table description header */
{ CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
@@ -678,13 +682,16 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
typedef struct {
FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
- BYTE scratchBuffer[1 << FSE_MAX_TABLELOG];
+ union {
+ U32 hist_wksp[HIST_WKSP_SIZE_U32];
+ BYTE scratchBuffer[1 << FSE_MAX_TABLELOG];
+ } workspace;
} fseWkspMax_t;
size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
{
fseWkspMax_t scratchBuffer;
- DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */
+ DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_COMPRESS_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */
if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer));
}
@@ -693,6 +700,6 @@ size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcS
{
return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
}
-
+#endif
#endif /* FSE_COMMONDEFS_ONLY */
diff --git a/thirdparty/zstd/compress/hist.c b/thirdparty/zstd/compress/hist.c
index 61e08c7968..a9659d11ad 100644
--- a/thirdparty/zstd/compress/hist.c
+++ b/thirdparty/zstd/compress/hist.c
@@ -34,7 +34,7 @@ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
unsigned maxSymbolValue = *maxSymbolValuePtr;
unsigned largestCount=0;
- memset(count, 0, (maxSymbolValue+1) * sizeof(*count));
+ ZSTD_memset(count, 0, (maxSymbolValue+1) * sizeof(*count));
if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
while (ip<end) {
@@ -60,9 +60,9 @@ typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;
* this design makes better use of OoO cpus,
* and is noticeably faster when some values are heavily repeated.
* But it needs some additional workspace for intermediate tables.
- * `workSpace` size must be a table of size >= HIST_WKSP_SIZE_U32.
+ * `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32.
* @return : largest histogram frequency,
- * or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */
+ * or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */
static size_t HIST_count_parallel_wksp(
unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize,
@@ -71,22 +71,21 @@ static size_t HIST_count_parallel_wksp(
{
const BYTE* ip = (const BYTE*)source;
const BYTE* const iend = ip+sourceSize;
- unsigned maxSymbolValue = *maxSymbolValuePtr;
+ size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count);
unsigned max=0;
U32* const Counting1 = workSpace;
U32* const Counting2 = Counting1 + 256;
U32* const Counting3 = Counting2 + 256;
U32* const Counting4 = Counting3 + 256;
- memset(workSpace, 0, 4*256*sizeof(unsigned));
-
/* safety checks */
+ assert(*maxSymbolValuePtr <= 255);
if (!sourceSize) {
- memset(count, 0, maxSymbolValue + 1);
+ ZSTD_memset(count, 0, countSize);
*maxSymbolValuePtr = 0;
return 0;
}
- if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */
+ ZSTD_memset(workSpace, 0, 4*256*sizeof(unsigned));
/* by stripes of 16 bytes */
{ U32 cached = MEM_read32(ip); ip += 4;
@@ -118,21 +117,18 @@ static size_t HIST_count_parallel_wksp(
/* finish last symbols */
while (ip<iend) Counting1[*ip++]++;
- if (check) { /* verify stats will fit into destination table */
- U32 s; for (s=255; s>maxSymbolValue; s--) {
- Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
- if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
- } }
-
{ U32 s;
- if (maxSymbolValue > 255) maxSymbolValue = 255;
- for (s=0; s<=maxSymbolValue; s++) {
- count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
- if (count[s] > max) max = count[s];
+ for (s=0; s<256; s++) {
+ Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
+ if (Counting1[s] > max) max = Counting1[s];
} }
- while (!count[maxSymbolValue]) maxSymbolValue--;
- *maxSymbolValuePtr = maxSymbolValue;
+ { unsigned maxSymbolValue = 255;
+ while (!Counting1[maxSymbolValue]) maxSymbolValue--;
+ if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall);
+ *maxSymbolValuePtr = maxSymbolValue;
+ ZSTD_memmove(count, Counting1, countSize); /* in case count & Counting1 are overlapping */
+ }
return (size_t)max;
}
@@ -152,14 +148,6 @@ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);
}
-/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
-size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
- const void* source, size_t sourceSize)
-{
- unsigned tmpCounters[HIST_WKSP_SIZE_U32];
- return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));
-}
-
/* HIST_count_wksp() :
* Same as HIST_count(), but using an externally provided scratch buffer.
* `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */
@@ -175,9 +163,19 @@ size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize);
}
+#ifndef ZSTD_NO_UNUSED_FUNCTIONS
+/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
+size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
+ const void* source, size_t sourceSize)
+{
+ unsigned tmpCounters[HIST_WKSP_SIZE_U32];
+ return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));
+}
+
size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize)
{
unsigned tmpCounters[HIST_WKSP_SIZE_U32];
return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters));
}
+#endif
diff --git a/thirdparty/zstd/compress/hist.h b/thirdparty/zstd/compress/hist.h
index 77e3ec4fb1..fb9ead6834 100644
--- a/thirdparty/zstd/compress/hist.h
+++ b/thirdparty/zstd/compress/hist.h
@@ -14,7 +14,7 @@
****************************************************************** */
/* --- dependencies --- */
-#include <stddef.h> /* size_t */
+#include "../common/zstd_deps.h" /* size_t */
/* --- simple histogram functions --- */
diff --git a/thirdparty/zstd/compress/huf_compress.c b/thirdparty/zstd/compress/huf_compress.c
index 546879868a..302e08864d 100644
--- a/thirdparty/zstd/compress/huf_compress.c
+++ b/thirdparty/zstd/compress/huf_compress.c
@@ -23,8 +23,7 @@
/* **************************************************************
* Includes
****************************************************************/
-#include <string.h> /* memcpy, memset */
-#include <stdio.h> /* printf (debug) */
+#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */
#include "../common/compiler.h"
#include "../common/bitstream.h"
#include "hist.h"
@@ -70,7 +69,7 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
- BYTE scratchBuffer[1<<MAX_FSE_TABLELOG_FOR_HUFF_HEADER];
+ U32 scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)];
unsigned count[HUF_TABLELOG_MAX+1];
S16 norm[HUF_TABLELOG_MAX+1];
@@ -85,7 +84,7 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
}
tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
- CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
+ CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) );
/* Write table description header */
{ CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), norm, maxSymbolValue, tableLog) );
@@ -103,11 +102,6 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
}
-struct HUF_CElt_s {
- U16 val;
- BYTE nbBits;
-}; /* typedef'd to HUF_CElt within "huf.h" */
-
/*! HUF_writeCTable() :
`CTable` : Huffman tree to save, using huf representation.
@return : size of saved CTable */
@@ -156,6 +150,7 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
/* get symbol weights */
CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize));
+ *hasZeroWeights = (rankVal[0] > 0);
/* check result */
if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
@@ -164,16 +159,14 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
/* Prepare base value per rank */
{ U32 n, nextRankStart = 0;
for (n=1; n<=tableLog; n++) {
- U32 current = nextRankStart;
+ U32 curr = nextRankStart;
nextRankStart += (rankVal[n] << (n-1));
- rankVal[n] = current;
+ rankVal[n] = curr;
} }
/* fill nbBits */
- *hasZeroWeights = 0;
{ U32 n; for (n=0; n<nbSymbols; n++) {
const U32 w = huffWeight[n];
- *hasZeroWeights |= (w == 0);
CTable[n].nbBits = (BYTE)(tableLog + 1 - w) & -(w != 0);
} }
@@ -212,32 +205,63 @@ typedef struct nodeElt_s {
BYTE nbBits;
} nodeElt;
+/**
+ * HUF_setMaxHeight():
+ * Enforces maxNbBits on the Huffman tree described in huffNode.
+ *
+ * It sets all nodes with nbBits > maxNbBits to be maxNbBits. Then it adjusts
+ * the tree to so that it is a valid canonical Huffman tree.
+ *
+ * @pre The sum of the ranks of each symbol == 2^largestBits,
+ * where largestBits == huffNode[lastNonNull].nbBits.
+ * @post The sum of the ranks of each symbol == 2^largestBits,
+ * where largestBits is the return value <= maxNbBits.
+ *
+ * @param huffNode The Huffman tree modified in place to enforce maxNbBits.
+ * @param lastNonNull The symbol with the lowest count in the Huffman tree.
+ * @param maxNbBits The maximum allowed number of bits, which the Huffman tree
+ * may not respect. After this function the Huffman tree will
+ * respect maxNbBits.
+ * @return The maximum number of bits of the Huffman tree after adjustment,
+ * necessarily no more than maxNbBits.
+ */
static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
{
const U32 largestBits = huffNode[lastNonNull].nbBits;
- if (largestBits <= maxNbBits) return largestBits; /* early exit : no elt > maxNbBits */
+ /* early exit : no elt > maxNbBits, so the tree is already valid. */
+ if (largestBits <= maxNbBits) return largestBits;
/* there are several too large elements (at least >= 2) */
{ int totalCost = 0;
const U32 baseCost = 1 << (largestBits - maxNbBits);
int n = (int)lastNonNull;
+ /* Adjust any ranks > maxNbBits to maxNbBits.
+ * Compute totalCost, which is how far the sum of the ranks is
+ * we are over 2^largestBits after adjust the offending ranks.
+ */
while (huffNode[n].nbBits > maxNbBits) {
totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
huffNode[n].nbBits = (BYTE)maxNbBits;
- n --;
- } /* n stops at huffNode[n].nbBits <= maxNbBits */
- while (huffNode[n].nbBits == maxNbBits) n--; /* n end at index of smallest symbol using < maxNbBits */
+ n--;
+ }
+ /* n stops at huffNode[n].nbBits <= maxNbBits */
+ assert(huffNode[n].nbBits <= maxNbBits);
+ /* n end at index of smallest symbol using < maxNbBits */
+ while (huffNode[n].nbBits == maxNbBits) --n;
- /* renorm totalCost */
- totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */
+ /* renorm totalCost from 2^largestBits to 2^maxNbBits
+ * note : totalCost is necessarily a multiple of baseCost */
+ assert((totalCost & (baseCost - 1)) == 0);
+ totalCost >>= (largestBits - maxNbBits);
+ assert(totalCost > 0);
/* repay normalized cost */
{ U32 const noSymbol = 0xF0F0F0F0;
U32 rankLast[HUF_TABLELOG_MAX+2];
- /* Get pos of last (smallest) symbol per rank */
- memset(rankLast, 0xF0, sizeof(rankLast));
+ /* Get pos of last (smallest = lowest cum. count) symbol per rank */
+ ZSTD_memset(rankLast, 0xF0, sizeof(rankLast));
{ U32 currentNbBits = maxNbBits;
int pos;
for (pos=n ; pos >= 0; pos--) {
@@ -247,34 +271,65 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
} }
while (totalCost > 0) {
+ /* Try to reduce the next power of 2 above totalCost because we
+ * gain back half the rank.
+ */
U32 nBitsToDecrease = BIT_highbit32((U32)totalCost) + 1;
for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
U32 const highPos = rankLast[nBitsToDecrease];
U32 const lowPos = rankLast[nBitsToDecrease-1];
if (highPos == noSymbol) continue;
+ /* Decrease highPos if no symbols of lowPos or if it is
+ * not cheaper to remove 2 lowPos than highPos.
+ */
if (lowPos == noSymbol) break;
{ U32 const highTotal = huffNode[highPos].count;
U32 const lowTotal = 2 * huffNode[lowPos].count;
if (highTotal <= lowTotal) break;
} }
/* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
+ assert(rankLast[nBitsToDecrease] != noSymbol || nBitsToDecrease == 1);
/* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
- nBitsToDecrease ++;
+ nBitsToDecrease++;
+ assert(rankLast[nBitsToDecrease] != noSymbol);
+ /* Increase the number of bits to gain back half the rank cost. */
totalCost -= 1 << (nBitsToDecrease-1);
+ huffNode[rankLast[nBitsToDecrease]].nbBits++;
+
+ /* Fix up the new rank.
+ * If the new rank was empty, this symbol is now its smallest.
+ * Otherwise, this symbol will be the largest in the new rank so no adjustment.
+ */
if (rankLast[nBitsToDecrease-1] == noSymbol)
- rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */
- huffNode[rankLast[nBitsToDecrease]].nbBits ++;
+ rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease];
+ /* Fix up the old rank.
+ * If the symbol was at position 0, meaning it was the highest weight symbol in the tree,
+ * it must be the only symbol in its rank, so the old rank now has no symbols.
+ * Otherwise, since the Huffman nodes are sorted by count, the previous position is now
+ * the smallest node in the rank. If the previous position belongs to a different rank,
+ * then the rank is now empty.
+ */
if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */
rankLast[nBitsToDecrease] = noSymbol;
else {
rankLast[nBitsToDecrease]--;
if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */
- } } /* while (totalCost > 0) */
-
+ }
+ } /* while (totalCost > 0) */
+
+ /* If we've removed too much weight, then we have to add it back.
+ * To avoid overshooting again, we only adjust the smallest rank.
+ * We take the largest nodes from the lowest rank 0 and move them
+ * to rank 1. There's guaranteed to be enough rank 0 symbols because
+ * TODO.
+ */
while (totalCost < 0) { /* Sometimes, cost correction overshoot */
- if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */
+ /* special case : no rank 1 symbol (using maxNbBits-1);
+ * let's create one from largest rank 0 (using maxNbBits).
+ */
+ if (rankLast[1] == noSymbol) {
while (huffNode[n].nbBits == maxNbBits) n--;
huffNode[n+1].nbBits--;
assert(n >= 0);
@@ -285,14 +340,16 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
huffNode[ rankLast[1] + 1 ].nbBits--;
rankLast[1]++;
totalCost ++;
- } } } /* there are several too large elements (at least >= 2) */
+ }
+ } /* repay normalized cost */
+ } /* there are several too large elements (at least >= 2) */
return maxNbBits;
}
typedef struct {
U32 base;
- U32 current;
+ U32 curr;
} rankPos;
typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];
@@ -304,21 +361,45 @@ typedef struct {
rankPos rankPosition[RANK_POSITION_TABLE_SIZE];
} HUF_buildCTable_wksp_tables;
+/**
+ * HUF_sort():
+ * Sorts the symbols [0, maxSymbolValue] by count[symbol] in decreasing order.
+ *
+ * @param[out] huffNode Sorted symbols by decreasing count. Only members `.count` and `.byte` are filled.
+ * Must have (maxSymbolValue + 1) entries.
+ * @param[in] count Histogram of the symbols.
+ * @param[in] maxSymbolValue Maximum symbol value.
+ * @param rankPosition This is a scratch workspace. Must have RANK_POSITION_TABLE_SIZE entries.
+ */
static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue, rankPos* rankPosition)
{
- U32 n;
-
- memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE);
- for (n=0; n<=maxSymbolValue; n++) {
- U32 r = BIT_highbit32(count[n] + 1);
- rankPosition[r].base ++;
+ int n;
+ int const maxSymbolValue1 = (int)maxSymbolValue + 1;
+
+ /* Compute base and set curr to base.
+ * For symbol s let lowerRank = BIT_highbit32(count[n]+1) and rank = lowerRank + 1.
+ * Then 2^lowerRank <= count[n]+1 <= 2^rank.
+ * We attribute each symbol to lowerRank's base value, because we want to know where
+ * each rank begins in the output, so for rank R we want to count ranks R+1 and above.
+ */
+ ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE);
+ for (n = 0; n < maxSymbolValue1; ++n) {
+ U32 lowerRank = BIT_highbit32(count[n] + 1);
+ rankPosition[lowerRank].base++;
}
- for (n=30; n>0; n--) rankPosition[n-1].base += rankPosition[n].base;
- for (n=0; n<32; n++) rankPosition[n].current = rankPosition[n].base;
- for (n=0; n<=maxSymbolValue; n++) {
+ assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0);
+ for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) {
+ rankPosition[n-1].base += rankPosition[n].base;
+ rankPosition[n-1].curr = rankPosition[n-1].base;
+ }
+ /* Sort */
+ for (n = 0; n < maxSymbolValue1; ++n) {
U32 const c = count[n];
U32 const r = BIT_highbit32(c+1) + 1;
- U32 pos = rankPosition[r].current++;
+ U32 pos = rankPosition[r].curr++;
+ /* Insert into the correct position in the rank.
+ * We have at most 256 symbols, so this insertion should be fine.
+ */
while ((pos > rankPosition[r].base) && (c > huffNode[pos-1].count)) {
huffNode[pos] = huffNode[pos-1];
pos--;
@@ -335,28 +416,20 @@ static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValu
*/
#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
-size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
+/* HUF_buildTree():
+ * Takes the huffNode array sorted by HUF_sort() and builds an unlimited-depth Huffman tree.
+ *
+ * @param huffNode The array sorted by HUF_sort(). Builds the Huffman tree in this array.
+ * @param maxSymbolValue The maximum symbol value.
+ * @return The smallest node in the Huffman tree (by count).
+ */
+static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue)
{
- HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)workSpace;
- nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
- nodeElt* const huffNode = huffNode0+1;
+ nodeElt* const huffNode0 = huffNode - 1;
int nonNullRank;
int lowS, lowN;
int nodeNb = STARTNODE;
int n, nodeRoot;
-
- /* safety checks */
- if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
- if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
- return ERROR(workSpace_tooSmall);
- if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
- if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
- return ERROR(maxSymbolValue_tooLarge);
- memset(huffNode0, 0, sizeof(huffNodeTable));
-
- /* sort, decreasing order */
- HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition);
-
/* init for parents */
nonNullRank = (int)maxSymbolValue;
while(huffNode[nonNullRank].count == 0) nonNullRank--;
@@ -383,42 +456,72 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbo
for (n=0; n<=nonNullRank; n++)
huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
+ return nonNullRank;
+}
+
+/**
+ * HUF_buildCTableFromTree():
+ * Build the CTable given the Huffman tree in huffNode.
+ *
+ * @param[out] CTable The output Huffman CTable.
+ * @param huffNode The Huffman tree.
+ * @param nonNullRank The last and smallest node in the Huffman tree.
+ * @param maxSymbolValue The maximum symbol value.
+ * @param maxNbBits The exact maximum number of bits used in the Huffman tree.
+ */
+static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits)
+{
+ /* fill result into ctable (val, nbBits) */
+ int n;
+ U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
+ U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
+ int const alphabetSize = (int)(maxSymbolValue + 1);
+ for (n=0; n<=nonNullRank; n++)
+ nbPerRank[huffNode[n].nbBits]++;
+ /* determine starting value per rank */
+ { U16 min = 0;
+ for (n=(int)maxNbBits; n>0; n--) {
+ valPerRank[n] = min; /* get starting value within each rank */
+ min += nbPerRank[n];
+ min >>= 1;
+ } }
+ for (n=0; n<alphabetSize; n++)
+ CTable[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
+ for (n=0; n<alphabetSize; n++)
+ CTable[n].val = valPerRank[CTable[n].nbBits]++; /* assign value within rank, symbol order */
+}
+
+size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
+{
+ HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)workSpace;
+ nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
+ nodeElt* const huffNode = huffNode0+1;
+ int nonNullRank;
+
+ /* safety checks */
+ if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
+ if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
+ return ERROR(workSpace_tooSmall);
+ if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
+ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
+ return ERROR(maxSymbolValue_tooLarge);
+ ZSTD_memset(huffNode0, 0, sizeof(huffNodeTable));
+
+ /* sort, decreasing order */
+ HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition);
+
+ /* build tree */
+ nonNullRank = HUF_buildTree(huffNode, maxSymbolValue);
+
/* enforce maxTableLog */
maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits);
+ if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
- /* fill result into tree (val, nbBits) */
- { U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
- U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
- int const alphabetSize = (int)(maxSymbolValue + 1);
- if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
- for (n=0; n<=nonNullRank; n++)
- nbPerRank[huffNode[n].nbBits]++;
- /* determine stating value per rank */
- { U16 min = 0;
- for (n=(int)maxNbBits; n>0; n--) {
- valPerRank[n] = min; /* get starting value within each rank */
- min += nbPerRank[n];
- min >>= 1;
- } }
- for (n=0; n<alphabetSize; n++)
- tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
- for (n=0; n<alphabetSize; n++)
- tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank, symbol order */
- }
+ HUF_buildCTableFromTree(tree, huffNode, nonNullRank, maxSymbolValue, maxNbBits);
return maxNbBits;
}
-/** HUF_buildCTable() :
- * @return : maxNbBits
- * Note : count is used before tree is written, so they can safely overlap
- */
-size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits)
-{
- HUF_buildCTable_wksp_tables workspace;
- return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace, sizeof(workspace));
-}
-
size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
{
size_t nbBits = 0;
@@ -633,25 +736,26 @@ typedef struct {
} HUF_compress_tables_t;
/* HUF_compress_internal() :
- * `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
+ * `workSpace_align4` must be aligned on 4-bytes boundaries,
+ * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U32 unsigned */
static size_t
HUF_compress_internal (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog,
HUF_nbStreams_e nbStreams,
- void* workSpace, size_t wkspSize,
+ void* workSpace_align4, size_t wkspSize,
HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
const int bmi2)
{
- HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace;
+ HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace_align4;
BYTE* const ostart = (BYTE*)dst;
BYTE* const oend = ostart + dstSize;
BYTE* op = ostart;
HUF_STATIC_ASSERT(sizeof(*table) <= HUF_WORKSPACE_SIZE);
+ assert(((size_t)workSpace_align4 & 3) == 0); /* must be aligned on 4-bytes boundaries */
/* checks & inits */
- if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);
if (!srcSize) return 0; /* Uncompressed */
if (!dstSize) return 0; /* cannot fit anything within dst budget */
@@ -669,7 +773,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
}
/* Scan input and build symbol stats */
- { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace, wkspSize) );
+ { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace_align4, wkspSize) );
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
}
@@ -695,7 +799,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
CHECK_F(maxBits);
huffLog = (U32)maxBits;
/* Zero unused symbols in CTable, so we can check it for validity */
- memset(table->CTable + (maxSymbolValue + 1), 0,
+ ZSTD_memset(table->CTable + (maxSymbolValue + 1), 0,
sizeof(table->CTable) - ((maxSymbolValue + 1) * sizeof(HUF_CElt)));
}
@@ -716,7 +820,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
op += hSize;
if (repeat) { *repeat = HUF_repeat_none; }
if (oldHufTable)
- memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */
+ ZSTD_memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */
}
return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize,
@@ -747,14 +851,6 @@ size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
repeat, preferRepeat, bmi2);
}
-size_t HUF_compress1X (void* dst, size_t dstSize,
- const void* src, size_t srcSize,
- unsigned maxSymbolValue, unsigned huffLog)
-{
- unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
- return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
-}
-
/* HUF_compress4X_repeat():
* compress input using 4 streams.
* provide workspace to generate compression tables */
@@ -784,6 +880,25 @@ size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
hufTable, repeat, preferRepeat, bmi2);
}
+#ifndef ZSTD_NO_UNUSED_FUNCTIONS
+/** HUF_buildCTable() :
+ * @return : maxNbBits
+ * Note : count is used before tree is written, so they can safely overlap
+ */
+size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits)
+{
+ HUF_buildCTable_wksp_tables workspace;
+ return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace, sizeof(workspace));
+}
+
+size_t HUF_compress1X (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog)
+{
+ unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
+ return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
+}
+
size_t HUF_compress2 (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog)
@@ -796,3 +911,4 @@ size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSi
{
return HUF_compress2(dst, maxDstSize, src, srcSize, 255, HUF_TABLELOG_DEFAULT);
}
+#endif
diff --git a/thirdparty/zstd/compress/zstd_compress.c b/thirdparty/zstd/compress/zstd_compress.c
index 3f963b1cff..386b051df6 100644
--- a/thirdparty/zstd/compress/zstd_compress.c
+++ b/thirdparty/zstd/compress/zstd_compress.c
@@ -11,8 +11,7 @@
/*-*************************************
* Dependencies
***************************************/
-#include <limits.h> /* INT_MAX */
-#include <string.h> /* memset */
+#include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */
#include "../common/cpu.h"
#include "../common/mem.h"
#include "hist.h" /* HIST_countFast_wksp */
@@ -30,6 +29,19 @@
#include "zstd_ldm.h"
#include "zstd_compress_superblock.h"
+/* ***************************************************************
+* Tuning parameters
+*****************************************************************/
+/*!
+ * COMPRESS_HEAPMODE :
+ * Select how default decompression function ZSTD_compress() allocates its context,
+ * on stack (0, default), or into heap (1).
+ * Note that functions with explicit context such as ZSTD_compressCCtx() are unaffected.
+ */
+#ifndef ZSTD_COMPRESS_HEAPMODE
+# define ZSTD_COMPRESS_HEAPMODE 0
+#endif
+
/*-*************************************
* Helper functions
@@ -52,6 +64,7 @@ size_t ZSTD_compressBound(size_t srcSize) {
struct ZSTD_CDict_s {
const void* dictContent;
size_t dictContentSize;
+ ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */
U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
ZSTD_cwksp workspace;
ZSTD_matchState_t matchState;
@@ -69,7 +82,7 @@ ZSTD_CCtx* ZSTD_createCCtx(void)
static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager)
{
assert(cctx != NULL);
- memset(cctx, 0, sizeof(*cctx));
+ ZSTD_memset(cctx, 0, sizeof(*cctx));
cctx->customMem = memManager;
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
{ size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters);
@@ -82,8 +95,8 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
{
ZSTD_STATIC_ASSERT(zcss_init==0);
ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
- if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
- { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
+ if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
+ { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_customMalloc(sizeof(ZSTD_CCtx), customMem);
if (!cctx) return NULL;
ZSTD_initCCtx(cctx, customMem);
return cctx;
@@ -96,20 +109,20 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
ZSTD_CCtx* cctx;
if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL; /* minimum size */
if ((size_t)workspace & 7) return NULL; /* must be 8-aligned */
- ZSTD_cwksp_init(&ws, workspace, workspaceSize);
+ ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc);
cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));
if (cctx == NULL) return NULL;
- memset(cctx, 0, sizeof(ZSTD_CCtx));
+ ZSTD_memset(cctx, 0, sizeof(ZSTD_CCtx));
ZSTD_cwksp_move(&cctx->workspace, &ws);
cctx->staticSize = workspaceSize;
/* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
- if (!ZSTD_cwksp_check_available(&cctx->workspace, HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
+ if (!ZSTD_cwksp_check_available(&cctx->workspace, ENTROPY_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
- cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace, HUF_WORKSPACE_SIZE);
+ cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace, ENTROPY_WORKSPACE_SIZE);
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
return cctx;
}
@@ -119,10 +132,10 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
*/
static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx)
{
- ZSTD_free(cctx->localDict.dictBuffer, cctx->customMem);
+ ZSTD_customFree(cctx->localDict.dictBuffer, cctx->customMem);
ZSTD_freeCDict(cctx->localDict.cdict);
- memset(&cctx->localDict, 0, sizeof(cctx->localDict));
- memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));
+ ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict));
+ ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));
cctx->cdict = NULL;
}
@@ -153,7 +166,7 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx);
ZSTD_freeCCtxContent(cctx);
if (!cctxInWorkspace) {
- ZSTD_free(cctx, cctx->customMem);
+ ZSTD_customFree(cctx, cctx->customMem);
}
}
return 0;
@@ -189,15 +202,32 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
/* private API call, for dictBuilder only */
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
+/* Returns 1 if compression parameters are such that we should
+ * enable long distance matching (wlog >= 27, strategy >= btopt).
+ * Returns 0 otherwise.
+ */
+static U32 ZSTD_CParams_shouldEnableLdm(const ZSTD_compressionParameters* const cParams) {
+ return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27;
+}
+
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
ZSTD_compressionParameters cParams)
{
ZSTD_CCtx_params cctxParams;
- memset(&cctxParams, 0, sizeof(cctxParams));
+ /* should not matter, as all cParams are presumed properly defined */
+ ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT);
cctxParams.cParams = cParams;
- cctxParams.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
+
+ if (ZSTD_CParams_shouldEnableLdm(&cParams)) {
+ DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including LDM into cctx params");
+ cctxParams.ldmParams.enableLdm = 1;
+ /* LDM is enabled by default for optimal parser and window size >= 128MB */
+ ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams);
+ assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog);
+ assert(cctxParams.ldmParams.hashRateLog < 32);
+ }
+
assert(!ZSTD_checkCParams(cParams));
- cctxParams.fParams.contentSizeFlag = 1;
return cctxParams;
}
@@ -205,13 +235,12 @@ static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced(
ZSTD_customMem customMem)
{
ZSTD_CCtx_params* params;
- if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
- params = (ZSTD_CCtx_params*)ZSTD_calloc(
+ if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
+ params = (ZSTD_CCtx_params*)ZSTD_customCalloc(
sizeof(ZSTD_CCtx_params), customMem);
if (!params) { return NULL; }
+ ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT);
params->customMem = customMem;
- params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
- params->fParams.contentSizeFlag = 1;
return params;
}
@@ -223,7 +252,7 @@ ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
{
if (params == NULL) { return 0; }
- ZSTD_free(params, params->customMem);
+ ZSTD_customFree(params, params->customMem);
return 0;
}
@@ -234,7 +263,7 @@ size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params)
size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
- memset(cctxParams, 0, sizeof(*cctxParams));
+ ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
cctxParams->compressionLevel = compressionLevel;
cctxParams->fParams.contentSizeFlag = 1;
return 0;
@@ -244,7 +273,7 @@ size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_paramete
{
RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
- memset(cctxParams, 0, sizeof(*cctxParams));
+ ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
assert(!ZSTD_checkCParams(params.cParams));
cctxParams->cParams = params.cParams;
cctxParams->fParams = params.fParams;
@@ -354,6 +383,11 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
#endif
return bounds;
+ case ZSTD_c_enableDedicatedDictSearch:
+ bounds.lowerBound = 0;
+ bounds.upperBound = 1;
+ return bounds;
+
case ZSTD_c_enableLongDistanceMatching:
bounds.lowerBound = 0;
bounds.upperBound = 1;
@@ -397,7 +431,7 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
return bounds;
case ZSTD_c_forceAttachDict:
- ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceCopy);
+ ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceLoad);
bounds.lowerBound = ZSTD_dictDefaultAttach;
bounds.upperBound = ZSTD_dictForceLoad; /* note : how to ensure at compile time that this is the highest value enum ? */
return bounds;
@@ -418,6 +452,22 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
bounds.upperBound = ZSTD_SRCSIZEHINT_MAX;
return bounds;
+ case ZSTD_c_stableInBuffer:
+ case ZSTD_c_stableOutBuffer:
+ bounds.lowerBound = (int)ZSTD_bm_buffered;
+ bounds.upperBound = (int)ZSTD_bm_stable;
+ return bounds;
+
+ case ZSTD_c_blockDelimiters:
+ bounds.lowerBound = (int)ZSTD_sf_noBlockDelimiters;
+ bounds.upperBound = (int)ZSTD_sf_explicitBlockDelimiters;
+ return bounds;
+
+ case ZSTD_c_validateSequences:
+ bounds.lowerBound = 0;
+ bounds.upperBound = 1;
+ return bounds;
+
default:
bounds.error = ERROR(parameter_unsupported);
return bounds;
@@ -465,6 +515,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
case ZSTD_c_jobSize:
case ZSTD_c_overlapLog:
case ZSTD_c_rsyncable:
+ case ZSTD_c_enableDedicatedDictSearch:
case ZSTD_c_enableLongDistanceMatching:
case ZSTD_c_ldmHashLog:
case ZSTD_c_ldmMinMatch:
@@ -474,6 +525,10 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
case ZSTD_c_literalCompressionMode:
case ZSTD_c_targetCBlockSize:
case ZSTD_c_srcSizeHint:
+ case ZSTD_c_stableInBuffer:
+ case ZSTD_c_stableOutBuffer:
+ case ZSTD_c_blockDelimiters:
+ case ZSTD_c_validateSequences:
default:
return 0;
}
@@ -515,12 +570,17 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
case ZSTD_c_jobSize:
case ZSTD_c_overlapLog:
case ZSTD_c_rsyncable:
+ case ZSTD_c_enableDedicatedDictSearch:
case ZSTD_c_enableLongDistanceMatching:
case ZSTD_c_ldmHashLog:
case ZSTD_c_ldmMinMatch:
case ZSTD_c_ldmBucketSizeLog:
case ZSTD_c_targetCBlockSize:
case ZSTD_c_srcSizeHint:
+ case ZSTD_c_stableInBuffer:
+ case ZSTD_c_stableOutBuffer:
+ case ZSTD_c_blockDelimiters:
+ case ZSTD_c_validateSequences:
break;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
@@ -541,9 +601,10 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
case ZSTD_c_compressionLevel : {
FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
- if (value) { /* 0 : does not change current level */
+ if (value == 0)
+ CCtxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
+ else
CCtxParams->compressionLevel = value;
- }
if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel;
return 0; /* return type (size_t) cannot represent negative values */
}
@@ -667,6 +728,10 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
return CCtxParams->rsyncable;
#endif
+ case ZSTD_c_enableDedicatedDictSearch :
+ CCtxParams->enableDedicatedDictSearch = (value!=0);
+ return CCtxParams->enableDedicatedDictSearch;
+
case ZSTD_c_enableLongDistanceMatching :
CCtxParams->ldmParams.enableLdm = (value!=0);
return CCtxParams->ldmParams.enableLdm;
@@ -707,6 +772,26 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
CCtxParams->srcSizeHint = value;
return CCtxParams->srcSizeHint;
+ case ZSTD_c_stableInBuffer:
+ BOUNDCHECK(ZSTD_c_stableInBuffer, value);
+ CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value;
+ return CCtxParams->inBufferMode;
+
+ case ZSTD_c_stableOutBuffer:
+ BOUNDCHECK(ZSTD_c_stableOutBuffer, value);
+ CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value;
+ return CCtxParams->outBufferMode;
+
+ case ZSTD_c_blockDelimiters:
+ BOUNDCHECK(ZSTD_c_blockDelimiters, value);
+ CCtxParams->blockDelimiters = (ZSTD_sequenceFormat_e)value;
+ return CCtxParams->blockDelimiters;
+
+ case ZSTD_c_validateSequences:
+ BOUNDCHECK(ZSTD_c_validateSequences, value);
+ CCtxParams->validateSequences = value;
+ return CCtxParams->validateSequences;
+
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
}
}
@@ -794,6 +879,9 @@ size_t ZSTD_CCtxParams_getParameter(
*value = CCtxParams->rsyncable;
break;
#endif
+ case ZSTD_c_enableDedicatedDictSearch :
+ *value = CCtxParams->enableDedicatedDictSearch;
+ break;
case ZSTD_c_enableLongDistanceMatching :
*value = CCtxParams->ldmParams.enableLdm;
break;
@@ -815,6 +903,18 @@ size_t ZSTD_CCtxParams_getParameter(
case ZSTD_c_srcSizeHint :
*value = (int)CCtxParams->srcSizeHint;
break;
+ case ZSTD_c_stableInBuffer :
+ *value = (int)CCtxParams->inBufferMode;
+ break;
+ case ZSTD_c_stableOutBuffer :
+ *value = (int)CCtxParams->outBufferMode;
+ break;
+ case ZSTD_c_blockDelimiters :
+ *value = (int)CCtxParams->blockDelimiters;
+ break;
+ case ZSTD_c_validateSequences :
+ *value = (int)CCtxParams->validateSequences;
+ break;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
}
return 0;
@@ -850,6 +950,14 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
return 0;
}
+static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(
+ int const compressionLevel,
+ size_t const dictSize);
+static int ZSTD_dedicatedDictSearch_isSupported(
+ const ZSTD_compressionParameters* cParams);
+static void ZSTD_dedicatedDictSearch_revertCParams(
+ ZSTD_compressionParameters* cParams);
+
/**
* Initializes the local dict using the requested parameters.
* NOTE: This does not use the pledged src size, because it may be used for more
@@ -858,8 +966,6 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
{
ZSTD_localDict* const dl = &cctx->localDict;
- ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams(
- &cctx->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN, dl->dictSize);
if (dl->dict == NULL) {
/* No local dictionary. */
assert(dl->dictBuffer == NULL);
@@ -876,12 +982,12 @@ static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
assert(cctx->cdict == NULL);
assert(cctx->prefixDict.dict == NULL);
- dl->cdict = ZSTD_createCDict_advanced(
+ dl->cdict = ZSTD_createCDict_advanced2(
dl->dict,
dl->dictSize,
ZSTD_dlm_byRef,
dl->dictContentType,
- cParams,
+ &cctx->requestedParams,
cctx->customMem);
RETURN_ERROR_IF(!dl->cdict, memory_allocation, "ZSTD_createCDict_advanced failed");
cctx->cdict = dl->cdict;
@@ -894,8 +1000,6 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
{
RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
"Can't load a dictionary when ctx is not in init stage.");
- RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
- "no malloc for static CCtx");
DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize);
ZSTD_clearAllDicts(cctx); /* in case one already exists */
if (dict == NULL || dictSize == 0) /* no dictionary mode */
@@ -903,9 +1007,12 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
if (dictLoadMethod == ZSTD_dlm_byRef) {
cctx->localDict.dict = dict;
} else {
- void* dictBuffer = ZSTD_malloc(dictSize, cctx->customMem);
+ void* dictBuffer;
+ RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
+ "no malloc for static CCtx");
+ dictBuffer = ZSTD_customMalloc(dictSize, cctx->customMem);
RETURN_ERROR_IF(!dictBuffer, memory_allocation, "NULL pointer!");
- memcpy(dictBuffer, dict, dictSize);
+ ZSTD_memcpy(dictBuffer, dict, dictSize);
cctx->localDict.dictBuffer = dictBuffer;
cctx->localDict.dict = dictBuffer;
}
@@ -938,6 +1045,14 @@ size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
return 0;
}
+size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool)
+{
+ RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
+ "Can't ref a pool when ctx not in init stage.");
+ cctx->pool = pool;
+ return 0;
+}
+
size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
{
return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent);
@@ -1022,24 +1137,73 @@ U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
return hashLog - btScale;
}
+/** ZSTD_dictAndWindowLog() :
+ * Returns an adjusted window log that is large enough to fit the source and the dictionary.
+ * The zstd format says that the entire dictionary is valid if one byte of the dictionary
+ * is within the window. So the hashLog and chainLog should be large enough to reference both
+ * the dictionary and the window. So we must use this adjusted dictAndWindowLog when downsizing
+ * the hashLog and windowLog.
+ * NOTE: srcSize must not be ZSTD_CONTENTSIZE_UNKNOWN.
+ */
+static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize)
+{
+ const U64 maxWindowSize = 1ULL << ZSTD_WINDOWLOG_MAX;
+ /* No dictionary ==> No change */
+ if (dictSize == 0) {
+ return windowLog;
+ }
+ assert(windowLog <= ZSTD_WINDOWLOG_MAX);
+ assert(srcSize != ZSTD_CONTENTSIZE_UNKNOWN); /* Handled in ZSTD_adjustCParams_internal() */
+ {
+ U64 const windowSize = 1ULL << windowLog;
+ U64 const dictAndWindowSize = dictSize + windowSize;
+ /* If the window size is already large enough to fit both the source and the dictionary
+ * then just use the window size. Otherwise adjust so that it fits the dictionary and
+ * the window.
+ */
+ if (windowSize >= dictSize + srcSize) {
+ return windowLog; /* Window size large enough already */
+ } else if (dictAndWindowSize >= maxWindowSize) {
+ return ZSTD_WINDOWLOG_MAX; /* Larger than max window log */
+ } else {
+ return ZSTD_highbit32((U32)dictAndWindowSize - 1) + 1;
+ }
+ }
+}
+
/** ZSTD_adjustCParams_internal() :
* optimize `cPar` for a specified input (`srcSize` and `dictSize`).
* mostly downsize to reduce memory consumption and initialization latency.
* `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.
+ * `mode` is the mode for parameter adjustment. See docs for `ZSTD_cParamMode_e`.
* note : `srcSize==0` means 0!
* condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */
static ZSTD_compressionParameters
ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
unsigned long long srcSize,
- size_t dictSize)
+ size_t dictSize,
+ ZSTD_cParamMode_e mode)
{
- static const U64 minSrcSize = 513; /* (1<<9) + 1 */
- static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
+ const U64 minSrcSize = 513; /* (1<<9) + 1 */
+ const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
assert(ZSTD_checkCParams(cPar)==0);
if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN)
srcSize = minSrcSize;
+ switch (mode) {
+ case ZSTD_cpm_noAttachDict:
+ case ZSTD_cpm_unknown:
+ case ZSTD_cpm_createCDict:
+ break;
+ case ZSTD_cpm_attachDict:
+ dictSize = 0;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
/* resize windowLog if input is small enough, to use less memory */
if ( (srcSize < maxWindowResize)
&& (dictSize < maxWindowResize) ) {
@@ -1049,10 +1213,11 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
ZSTD_highbit32(tSize-1) + 1;
if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
}
- if (cPar.hashLog > cPar.windowLog+1) cPar.hashLog = cPar.windowLog+1;
- { U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
- if (cycleLog > cPar.windowLog)
- cPar.chainLog -= (cycleLog - cPar.windowLog);
+ { U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize);
+ U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
+ if (cPar.hashLog > dictAndWindowLog+1) cPar.hashLog = dictAndWindowLog+1;
+ if (cycleLog > dictAndWindowLog)
+ cPar.chainLog -= (cycleLog - dictAndWindowLog);
}
if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN)
@@ -1068,31 +1233,38 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
{
cPar = ZSTD_clampCParams(cPar); /* resulting cPar is necessarily valid (all parameters within range) */
if (srcSize == 0) srcSize = ZSTD_CONTENTSIZE_UNKNOWN;
- return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
+ return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown);
}
-static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize);
-static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize);
+static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
+static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
+
+static void ZSTD_overrideCParams(
+ ZSTD_compressionParameters* cParams,
+ const ZSTD_compressionParameters* overrides)
+{
+ if (overrides->windowLog) cParams->windowLog = overrides->windowLog;
+ if (overrides->hashLog) cParams->hashLog = overrides->hashLog;
+ if (overrides->chainLog) cParams->chainLog = overrides->chainLog;
+ if (overrides->searchLog) cParams->searchLog = overrides->searchLog;
+ if (overrides->minMatch) cParams->minMatch = overrides->minMatch;
+ if (overrides->targetLength) cParams->targetLength = overrides->targetLength;
+ if (overrides->strategy) cParams->strategy = overrides->strategy;
+}
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
- const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
+ const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
{
ZSTD_compressionParameters cParams;
if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
srcSizeHint = CCtxParams->srcSizeHint;
}
- cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize);
+ cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode);
if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
- if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
- if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
- if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
- if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
- if (CCtxParams->cParams.minMatch) cParams.minMatch = CCtxParams->cParams.minMatch;
- if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
- if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
+ ZSTD_overrideCParams(&cParams, &CCtxParams->cParams);
assert(!ZSTD_checkCParams(cParams));
/* srcSizeHint == 0 means 0 */
- return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
+ return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize, mode);
}
static size_t
@@ -1123,45 +1295,61 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
return tableSpace + optSpace;
}
-size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
+static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
+ const ZSTD_compressionParameters* cParams,
+ const ldmParams_t* ldmParams,
+ const int isStatic,
+ const size_t buffInSize,
+ const size_t buffOutSize,
+ const U64 pledgedSrcSize)
{
- RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
- { ZSTD_compressionParameters const cParams =
- ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0);
- size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
- U32 const divider = (cParams.minMatch==3) ? 3 : 4;
- size_t const maxNbSeq = blockSize / divider;
- size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
- + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))
- + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
- size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE);
- size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
- size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
+ size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << cParams->windowLog), pledgedSrcSize));
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
+ U32 const divider = (cParams->minMatch==3) ? 3 : 4;
+ size_t const maxNbSeq = blockSize / divider;
+ size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
+ + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))
+ + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
+ size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE);
+ size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
+ size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, /* forCCtx */ 1);
- size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams);
- size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize) * sizeof(rawSeq));
+ size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
+ size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
+ size_t const ldmSeqSpace = ldmParams->enableLdm ?
+ ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
- /* estimateCCtxSize is for one-shot compression. So no buffers should
- * be needed. However, we still allocate two 0-sized buffers, which can
- * take space under ASAN. */
- size_t const bufferSpace = ZSTD_cwksp_alloc_size(0)
- + ZSTD_cwksp_alloc_size(0);
- size_t const cctxSpace = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx));
+ size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize)
+ + ZSTD_cwksp_alloc_size(buffOutSize);
- size_t const neededSpace =
- cctxSpace +
- entropySpace +
- blockStateSpace +
- ldmSpace +
- ldmSeqSpace +
- matchStateSize +
- tokenSpace +
- bufferSpace;
+ size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;
- DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
- return neededSpace;
- }
+ size_t const neededSpace =
+ cctxSpace +
+ entropySpace +
+ blockStateSpace +
+ ldmSpace +
+ ldmSeqSpace +
+ matchStateSize +
+ tokenSpace +
+ bufferSpace;
+
+ DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
+ return neededSpace;
+}
+
+size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
+{
+ ZSTD_compressionParameters const cParams =
+ ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
+
+ RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
+ /* estimateCCtxSize is for one-shot compression. So no buffers should
+ * be needed. However, we still allocate two 0-sized buffers, which can
+ * take space under ASAN. */
+ return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
+ &cParams, &params->ldmParams, 1, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN);
}
size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
@@ -1172,7 +1360,7 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
{
- ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
return ZSTD_estimateCCtxSize_usingCParams(cParams);
}
@@ -1191,15 +1379,18 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
{
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
{ ZSTD_compressionParameters const cParams =
- ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0);
- size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
+ ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
- size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
- size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
- size_t const streamingSize = ZSTD_cwksp_alloc_size(inBuffSize)
- + ZSTD_cwksp_alloc_size(outBuffSize);
-
- return CCtxSize + streamingSize;
+ size_t const inBuffSize = (params->inBufferMode == ZSTD_bm_buffered)
+ ? ((size_t)1 << cParams.windowLog) + blockSize
+ : 0;
+ size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered)
+ ? ZSTD_compressBound(blockSize) + 1
+ : 0;
+
+ return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
+ &cParams, &params->ldmParams, 1, inBuffSize, outBuffSize,
+ ZSTD_CONTENTSIZE_UNKNOWN);
}
}
@@ -1211,7 +1402,7 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
{
- ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
return ZSTD_estimateCStreamSize_usingCParams(cParams);
}
@@ -1305,16 +1496,6 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
}
/**
- * Indicates whether this compression proceeds directly from user-provided
- * source buffer to user-provided destination buffer (ZSTDb_not_buffered), or
- * whether the context needs to buffer the input/output (ZSTDb_buffered).
- */
-typedef enum {
- ZSTDb_not_buffered,
- ZSTDb_buffered
-} ZSTD_buffered_policy_e;
-
-/**
* Controls, for this matchState reset, whether the tables need to be cleared /
* prepared for the coming compression (ZSTDcrp_makeClean), or whether the
* tables can be left unclean (ZSTDcrp_leaveDirty), because we know that a
@@ -1441,45 +1622,32 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
U32 const divider = (params.cParams.minMatch==3) ? 3 : 4;
size_t const maxNbSeq = blockSize / divider;
- size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
- + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))
- + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
- size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
- size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
- size_t const matchStateSize = ZSTD_sizeof_matchState(&params.cParams, /* forCCtx */ 1);
+ size_t const buffOutSize = (zbuff == ZSTDb_buffered && params.outBufferMode == ZSTD_bm_buffered)
+ ? ZSTD_compressBound(blockSize) + 1
+ : 0;
+ size_t const buffInSize = (zbuff == ZSTDb_buffered && params.inBufferMode == ZSTD_bm_buffered)
+ ? windowSize + blockSize
+ : 0;
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
- ZSTD_indexResetPolicy_e needsIndexReset = zc->initialized ? ZSTDirp_continue : ZSTDirp_reset;
+ int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window);
+ ZSTD_indexResetPolicy_e needsIndexReset =
+ (!indexTooClose && zc->initialized) ? ZSTDirp_continue : ZSTDirp_reset;
- if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
- needsIndexReset = ZSTDirp_reset;
- }
+ size_t const neededSpace =
+ ZSTD_estimateCCtxSize_usingCCtxParams_internal(
+ &params.cParams, &params.ldmParams, zc->staticSize != 0,
+ buffInSize, buffOutSize, pledgedSrcSize);
+ FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!");
if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0);
/* Check if workspace is large enough, alloc a new one if needed */
- { size_t const cctxSpace = zc->staticSize ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;
- size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE);
- size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
- size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + ZSTD_cwksp_alloc_size(buffOutSize);
- size_t const ldmSpace = ZSTD_ldm_getTableSize(params.ldmParams);
- size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq));
-
- size_t const neededSpace =
- cctxSpace +
- entropySpace +
- blockStateSpace +
- ldmSpace +
- ldmSeqSpace +
- matchStateSize +
- tokenSpace +
- bufferSpace;
-
+ {
int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace;
int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace);
- DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
- neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
+ DEBUGLOG(4, "Need %zu B workspace", neededSpace);
DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
if (workspaceTooSmall || workspaceWasteful) {
@@ -1503,7 +1671,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock");
zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
- zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, HUF_WORKSPACE_SIZE);
+ zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, ENTROPY_WORKSPACE_SIZE);
RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate entropyWorkspace");
} }
@@ -1534,6 +1702,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->seqStore.maxNbLit = blockSize;
/* buffers */
+ zc->bufferedPolicy = zbuff;
zc->inBuffSize = buffInSize;
zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize);
zc->outBuffSize = buffOutSize;
@@ -1546,7 +1715,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
((size_t)1) << (params.ldmParams.hashLog -
params.ldmParams.bucketSizeLog);
zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, ldmBucketSize);
- memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize);
+ ZSTD_memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize);
}
/* sequences storage */
@@ -1570,7 +1739,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
/* TODO: avoid memset? */
size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t));
- memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
+ ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
zc->maxNbLdmSequences = maxNbLdmSeq;
@@ -1579,6 +1748,12 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->ldmState.loadedDictEnd = 0;
}
+ /* Due to alignment, when reusing a workspace, we can actually consume
+ * up to 3 extra bytes for alignment. See the comments in zstd_cwksp.h
+ */
+ assert(ZSTD_cwksp_used(ws) >= neededSpace &&
+ ZSTD_cwksp_used(ws) <= neededSpace + 3);
+
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
zc->initialized = 1;
@@ -1618,12 +1793,14 @@ static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
U64 pledgedSrcSize)
{
size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy];
- return ( pledgedSrcSize <= cutoff
- || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
- || params->attachDictPref == ZSTD_dictForceAttach )
- && params->attachDictPref != ZSTD_dictForceCopy
- && !params->forceWindow; /* dictMatchState isn't correctly
- * handled in _enforceMaxDist */
+ int const dedicatedDictSearch = cdict->matchState.dedicatedDictSearch;
+ return dedicatedDictSearch
+ || ( ( pledgedSrcSize <= cutoff
+ || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
+ || params->attachDictPref == ZSTD_dictForceAttach )
+ && params->attachDictPref != ZSTD_dictForceCopy
+ && !params->forceWindow ); /* dictMatchState isn't correctly
+ * handled in _enforceMaxDist */
}
static size_t
@@ -1633,17 +1810,24 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
U64 pledgedSrcSize,
ZSTD_buffered_policy_e zbuff)
{
- { const ZSTD_compressionParameters* const cdict_cParams = &cdict->matchState.cParams;
+ {
+ ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams;
unsigned const windowLog = params.cParams.windowLog;
assert(windowLog != 0);
/* Resize working context table params for input only, since the dict
* has its own tables. */
- /* pledgeSrcSize == 0 means 0! */
- params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
+ /* pledgedSrcSize == 0 means 0! */
+
+ if (cdict->matchState.dedicatedDictSearch) {
+ ZSTD_dedicatedDictSearch_revertCParams(&adjusted_cdict_cParams);
+ }
+
+ params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize,
+ cdict->dictContentSize, ZSTD_cpm_attachDict);
params.cParams.windowLog = windowLog;
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
ZSTDcrp_makeClean, zbuff), "");
- assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
+ assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy);
}
{ const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
@@ -1670,7 +1854,7 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
cctx->dictID = cdict->dictID;
/* copy block state */
- memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
+ ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
return 0;
}
@@ -1683,6 +1867,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
{
const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
+ assert(!cdict->matchState.dedicatedDictSearch);
+
DEBUGLOG(4, "copying dictionary into context");
{ unsigned const windowLog = params.cParams.windowLog;
@@ -1703,10 +1889,10 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
{ size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog);
size_t const hSize = (size_t)1 << cdict_cParams->hashLog;
- memcpy(cctx->blockState.matchState.hashTable,
+ ZSTD_memcpy(cctx->blockState.matchState.hashTable,
cdict->matchState.hashTable,
hSize * sizeof(U32));
- memcpy(cctx->blockState.matchState.chainTable,
+ ZSTD_memcpy(cctx->blockState.matchState.chainTable,
cdict->matchState.chainTable,
chainSize * sizeof(U32));
}
@@ -1715,7 +1901,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
{ int const h3log = cctx->blockState.matchState.hashLog3;
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
assert(cdict->matchState.hashLog3 == 0);
- memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
+ ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
}
ZSTD_cwksp_mark_tables_clean(&cctx->workspace);
@@ -1731,7 +1917,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
cctx->dictID = cdict->dictID;
/* copy block state */
- memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
+ ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
return 0;
}
@@ -1775,7 +1961,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong,
"Can't copy a ctx that's not in init stage.");
- memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
+ ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
{ ZSTD_CCtx_params params = dstCCtx->requestedParams;
/* Copy only compression parameters related to tables. */
params.cParams = srcCCtx->appliedParams.cParams;
@@ -1797,13 +1983,13 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
int const h3log = srcCCtx->blockState.matchState.hashLog3;
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
- memcpy(dstCCtx->blockState.matchState.hashTable,
+ ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable,
srcCCtx->blockState.matchState.hashTable,
hSize * sizeof(U32));
- memcpy(dstCCtx->blockState.matchState.chainTable,
+ ZSTD_memcpy(dstCCtx->blockState.matchState.chainTable,
srcCCtx->blockState.matchState.chainTable,
chainSize * sizeof(U32));
- memcpy(dstCCtx->blockState.matchState.hashTable3,
+ ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable3,
srcCCtx->blockState.matchState.hashTable3,
h3Size * sizeof(U32));
}
@@ -1821,7 +2007,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
dstCCtx->dictID = srcCCtx->dictID;
/* copy block state */
- memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock));
+ ZSTD_memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock));
return 0;
}
@@ -1834,7 +2020,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
{
ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
- ZSTD_buffered_policy_e const zbuff = (ZSTD_buffered_policy_e)(srcCCtx->inBuffSize>0);
+ ZSTD_buffered_policy_e const zbuff = srcCCtx->bufferedPolicy;
ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1);
if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN);
@@ -1861,7 +2047,7 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
assert(size < (1U<<31)); /* can be casted to int */
-#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
+#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
/* To validate that the table re-use logic is sound, and that we don't
* access table space that we haven't cleaned, we re-"poison" the table
* space every time we mark it dirty.
@@ -1958,10 +2144,10 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams)
return (cctxParams->targetCBlockSize != 0);
}
-/* ZSTD_compressSequences_internal():
+/* ZSTD_entropyCompressSequences_internal():
* actually compresses both literals and sequences */
MEM_STATIC size_t
-ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
+ZSTD_entropyCompressSequences_internal(seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams,
@@ -1971,7 +2157,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
{
const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
ZSTD_strategy const strategy = cctxParams->cParams.strategy;
- unsigned count[MaxSeq+1];
+ unsigned* count = (unsigned*)entropyWorkspace;
FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
@@ -1987,8 +2173,12 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
BYTE* seqHead;
BYTE* lastNCount = NULL;
- DEBUGLOG(5, "ZSTD_compressSequences_internal (nbSeq=%zu)", nbSeq);
+ entropyWorkspace = count + (MaxSeq + 1);
+ entropyWkspSize -= (MaxSeq + 1) * sizeof(*count);
+
+ DEBUGLOG(4, "ZSTD_entropyCompressSequences_internal (nbSeq=%zu)", nbSeq);
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
+ assert(entropyWkspSize >= HUF_WORKSPACE_SIZE);
/* Compress literals */
{ const BYTE* const literals = seqStorePtr->litStart;
@@ -2023,7 +2213,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
assert(op <= oend);
if (nbSeq==0) {
/* Copy the old tables over as if we repeated them */
- memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
+ ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
return (size_t)(op - ostart);
}
@@ -2148,7 +2338,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
}
MEM_STATIC size_t
-ZSTD_compressSequences(seqStore_t* seqStorePtr,
+ZSTD_entropyCompressSequences(seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams,
@@ -2157,7 +2347,7 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr,
void* entropyWorkspace, size_t entropyWkspSize,
int bmi2)
{
- size_t const cSize = ZSTD_compressSequences_internal(
+ size_t const cSize = ZSTD_entropyCompressSequences_internal(
seqStorePtr, prevEntropy, nextEntropy, cctxParams,
dst, dstCapacity,
entropyWorkspace, entropyWkspSize, bmi2);
@@ -2167,13 +2357,13 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr,
*/
if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
return 0; /* block not compressed */
- FORWARD_IF_ERROR(cSize, "ZSTD_compressSequences_internal failed");
+ FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSequences_internal failed");
/* Check compressibility */
{ size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
if (cSize >= maxCSize) return 0; /* block not compressed */
}
-
+ DEBUGLOG(4, "ZSTD_entropyCompressSequences() cSize: %zu\n", cSize);
return cSize;
}
@@ -2182,7 +2372,7 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr,
* assumption : strat is a valid strategy */
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)
{
- static const ZSTD_blockCompressor blockCompressor[3][ZSTD_STRATEGY_MAX+1] = {
+ static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
{ ZSTD_compressBlock_fast /* default for 0 */,
ZSTD_compressBlock_fast,
ZSTD_compressBlock_doubleFast,
@@ -2212,7 +2402,17 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMo
ZSTD_compressBlock_btlazy2_dictMatchState,
ZSTD_compressBlock_btopt_dictMatchState,
ZSTD_compressBlock_btultra_dictMatchState,
- ZSTD_compressBlock_btultra_dictMatchState }
+ ZSTD_compressBlock_btultra_dictMatchState },
+ { NULL /* default for 0 */,
+ NULL,
+ NULL,
+ ZSTD_compressBlock_greedy_dedicatedDictSearch,
+ ZSTD_compressBlock_lazy_dedicatedDictSearch,
+ ZSTD_compressBlock_lazy2_dedicatedDictSearch,
+ NULL,
+ NULL,
+ NULL,
+ NULL }
};
ZSTD_blockCompressor selectedCompressor;
ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
@@ -2226,7 +2426,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMo
static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
const BYTE* anchor, size_t lastLLSize)
{
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize);
seqStorePtr->lit += lastLLSize;
}
@@ -2247,7 +2447,11 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
/* Assert that we have correctly flushed the ctx params into the ms's copy */
ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
- ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);
+ if (zc->appliedParams.cParams.strategy >= ZSTD_btopt) {
+ ZSTD_ldm_skipRawSeqStoreBytes(&zc->externSeqStore, srcSize);
+ } else {
+ ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);
+ }
return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */
}
ZSTD_resetSeqStore(&(zc->seqStore));
@@ -2263,10 +2467,10 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
/* limited update after a very long match */
{ const BYTE* const base = ms->window.base;
const BYTE* const istart = (const BYTE*)src;
- const U32 current = (U32)(istart-base);
+ const U32 curr = (U32)(istart-base);
if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1)); /* ensure no overflow */
- if (current > ms->nextToUpdate + 384)
- ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384));
+ if (curr > ms->nextToUpdate + 384)
+ ms->nextToUpdate = curr - MIN(192, (U32)(curr - ms->nextToUpdate - 384));
}
/* select and store sequences */
@@ -2286,7 +2490,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
src, srcSize);
assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
} else if (zc->appliedParams.ldmParams.enableLdm) {
- rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};
+ rawSeqStore_t ldmSeqStore = kNullRawSeqStore;
ldmSeqStore.seq = zc->ldmSequences;
ldmSeqStore.capacity = zc->maxNbLdmSequences;
@@ -2303,6 +2507,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
assert(ldmSeqStore.pos == ldmSeqStore.size);
} else { /* not long range mode */
ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode);
+ ms->ldmSeqStore = NULL;
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
}
{ const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
@@ -2314,17 +2519,25 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
{
const seqStore_t* seqStore = ZSTD_getSeqStore(zc);
- const seqDef* seqs = seqStore->sequencesStart;
- size_t seqsSize = seqStore->sequences - seqs;
+ const seqDef* seqStoreSeqs = seqStore->sequencesStart;
+ size_t seqStoreSeqSize = seqStore->sequences - seqStoreSeqs;
+ size_t seqStoreLiteralsSize = (size_t)(seqStore->lit - seqStore->litStart);
+ size_t literalsRead = 0;
+ size_t lastLLSize;
ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex];
- size_t i; size_t position; int repIdx;
+ size_t i;
+ repcodes_t updatedRepcodes;
assert(zc->seqCollector.seqIndex + 1 < zc->seqCollector.maxSequences);
- for (i = 0, position = 0; i < seqsSize; ++i) {
- outSeqs[i].offset = seqs[i].offset;
- outSeqs[i].litLength = seqs[i].litLength;
- outSeqs[i].matchLength = seqs[i].matchLength + MINMATCH;
+ /* Ensure we have enough space for last literals "sequence" */
+ assert(zc->seqCollector.maxSequences >= seqStoreSeqSize + 1);
+ ZSTD_memcpy(updatedRepcodes.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
+ for (i = 0; i < seqStoreSeqSize; ++i) {
+ U32 rawOffset = seqStoreSeqs[i].offset - ZSTD_REP_NUM;
+ outSeqs[i].litLength = seqStoreSeqs[i].litLength;
+ outSeqs[i].matchLength = seqStoreSeqs[i].matchLength + MINMATCH;
+ outSeqs[i].rep = 0;
if (i == seqStore->longLengthPos) {
if (seqStore->longLengthID == 1) {
@@ -2334,39 +2547,44 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
}
}
- if (outSeqs[i].offset <= ZSTD_REP_NUM) {
- outSeqs[i].rep = outSeqs[i].offset;
- repIdx = (unsigned int)i - outSeqs[i].offset;
-
- if (outSeqs[i].litLength == 0) {
- if (outSeqs[i].offset < 3) {
- --repIdx;
+ if (seqStoreSeqs[i].offset <= ZSTD_REP_NUM) {
+ /* Derive the correct offset corresponding to a repcode */
+ outSeqs[i].rep = seqStoreSeqs[i].offset;
+ if (outSeqs[i].litLength != 0) {
+ rawOffset = updatedRepcodes.rep[outSeqs[i].rep - 1];
+ } else {
+ if (outSeqs[i].rep == 3) {
+ rawOffset = updatedRepcodes.rep[0] - 1;
} else {
- repIdx = (unsigned int)i - 1;
+ rawOffset = updatedRepcodes.rep[outSeqs[i].rep];
}
- ++outSeqs[i].rep;
- }
- assert(repIdx >= -3);
- outSeqs[i].offset = repIdx >= 0 ? outSeqs[repIdx].offset : repStartValue[-repIdx - 1];
- if (outSeqs[i].rep == 4) {
- --outSeqs[i].offset;
}
- } else {
- outSeqs[i].offset -= ZSTD_REP_NUM;
}
-
- position += outSeqs[i].litLength;
- outSeqs[i].matchPos = (unsigned int)position;
- position += outSeqs[i].matchLength;
+ outSeqs[i].offset = rawOffset;
+ /* seqStoreSeqs[i].offset == offCode+1, and ZSTD_updateRep() expects offCode
+ so we provide seqStoreSeqs[i].offset - 1 */
+ updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep,
+ seqStoreSeqs[i].offset - 1,
+ seqStoreSeqs[i].litLength == 0);
+ literalsRead += outSeqs[i].litLength;
}
- zc->seqCollector.seqIndex += seqsSize;
+ /* Insert last literals (if any exist) in the block as a sequence with ml == off == 0.
+ * If there are no last literals, then we'll emit (of: 0, ml: 0, ll: 0), which is a marker
+ * for the block boundary, according to the API.
+ */
+ assert(seqStoreLiteralsSize >= literalsRead);
+ lastLLSize = seqStoreLiteralsSize - literalsRead;
+ outSeqs[i].litLength = (U32)lastLLSize;
+ outSeqs[i].matchLength = outSeqs[i].offset = outSeqs[i].rep = 0;
+ seqStoreSeqSize++;
+ zc->seqCollector.seqIndex += seqStoreSeqSize;
}
-size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
- size_t outSeqsSize, const void* src, size_t srcSize)
+size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
+ size_t outSeqsSize, const void* src, size_t srcSize)
{
const size_t dstCapacity = ZSTD_compressBound(srcSize);
- void* dst = ZSTD_malloc(dstCapacity, ZSTD_defaultCMem);
+ void* dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem);
SeqCollector seqCollector;
RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
@@ -2378,16 +2596,47 @@ size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
zc->seqCollector = seqCollector;
ZSTD_compress2(zc, dst, dstCapacity, src, srcSize);
- ZSTD_free(dst, ZSTD_defaultCMem);
+ ZSTD_customFree(dst, ZSTD_defaultCMem);
return zc->seqCollector.seqIndex;
}
-/* Returns true if the given block is a RLE block */
-static int ZSTD_isRLE(const BYTE *ip, size_t length) {
+size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize) {
+ size_t in = 0;
+ size_t out = 0;
+ for (; in < seqsSize; ++in) {
+ if (sequences[in].offset == 0 && sequences[in].matchLength == 0) {
+ if (in != seqsSize - 1) {
+ sequences[in+1].litLength += sequences[in].litLength;
+ }
+ } else {
+ sequences[out] = sequences[in];
+ ++out;
+ }
+ }
+ return out;
+}
+
+/* Unrolled loop to read four size_ts of input at a time. Returns 1 if is RLE, 0 if not. */
+static int ZSTD_isRLE(const BYTE* src, size_t length) {
+ const BYTE* ip = src;
+ const BYTE value = ip[0];
+ const size_t valueST = (size_t)((U64)value * 0x0101010101010101ULL);
+ const size_t unrollSize = sizeof(size_t) * 4;
+ const size_t unrollMask = unrollSize - 1;
+ const size_t prefixLength = length & unrollMask;
size_t i;
- if (length < 2) return 1;
- for (i = 1; i < length; ++i) {
- if (ip[0] != ip[i]) return 0;
+ size_t u;
+ if (length == 1) return 1;
+ /* Check if prefix is RLE first before using unrolled loop */
+ if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) {
+ return 0;
+ }
+ for (i = prefixLength; i != length; i += unrollSize) {
+ for (u = 0; u < unrollSize; u += sizeof(size_t)) {
+ if (MEM_readST(ip + i + u) != valueST) {
+ return 0;
+ }
+ }
}
return 1;
}
@@ -2434,18 +2683,25 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
if (zc->seqCollector.collectSequences) {
ZSTD_copyBlockSequences(zc);
+ ZSTD_confirmRepcodesAndEntropyTables(zc);
return 0;
}
/* encode sequences and literals */
- cSize = ZSTD_compressSequences(&zc->seqStore,
+ cSize = ZSTD_entropyCompressSequences(&zc->seqStore,
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
&zc->appliedParams,
dst, dstCapacity,
srcSize,
- zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
+ zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
zc->bmi2);
+ if (zc->seqCollector.collectSequences) {
+ ZSTD_copyBlockSequences(zc);
+ return 0;
+ }
+
+
if (frame &&
/* We don't want to emit our first block as a RLE even if it qualifies because
* doing so will cause the decoder (cli only) to throw a "should consume all input error."
@@ -2593,7 +2849,7 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
- DEBUGLOG(5, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
+ DEBUGLOG(4, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
if (cctx->appliedParams.fParams.checksumFlag && srcSize)
XXH64_update(&cctx->xxhState, src, srcSize);
@@ -2673,7 +2929,6 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
"dst buf is too small to fit worst-case frame header size.");
DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
!params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
-
if (params->format == ZSTD_f_zstd1) {
MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
pos = 4;
@@ -2725,6 +2980,7 @@ size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSe
cctx->externSeqStore.size = nbSeq;
cctx->externSeqStore.capacity = nbSeq;
cctx->externSeqStore.pos = 0;
+ cctx->externSeqStore.posInSequence = 0;
return 0;
}
@@ -2862,8 +3118,12 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
case ZSTD_greedy:
case ZSTD_lazy:
case ZSTD_lazy2:
- if (chunk >= HASH_READ_SIZE)
+ if (chunk >= HASH_READ_SIZE && ms->dedicatedDictSearch) {
+ assert(chunk == remaining); /* must load everything in one go */
+ ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, ichunk-HASH_READ_SIZE);
+ } else if (chunk >= HASH_READ_SIZE) {
ZSTD_insertAndFindFirstIndex(ms, ichunk-HASH_READ_SIZE);
+ }
break;
case ZSTD_btlazy2: /* we want the dictionary table fully sorted */
@@ -2887,22 +3147,28 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
/* Dictionaries that assign zero probability to symbols that show up causes problems
- when FSE encoding. Refuse dictionaries that assign zero probability to symbols
- that we may encounter during compression.
- NOTE: This behavior is not standard and could be improved in the future. */
-static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
+ * when FSE encoding. Mark dictionaries with zero probability symbols as FSE_repeat_check
+ * and only dictionaries with 100% valid symbols can be assumed valid.
+ */
+static FSE_repeat ZSTD_dictNCountRepeat(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue)
+{
U32 s;
- RETURN_ERROR_IF(dictMaxSymbolValue < maxSymbolValue, dictionary_corrupted, "dict fse tables don't have all symbols");
+ if (dictMaxSymbolValue < maxSymbolValue) {
+ return FSE_repeat_check;
+ }
for (s = 0; s <= maxSymbolValue; ++s) {
- RETURN_ERROR_IF(normalizedCounter[s] == 0, dictionary_corrupted, "dict fse tables don't have all symbols");
+ if (normalizedCounter[s] == 0) {
+ return FSE_repeat_check;
+ }
}
- return 0;
+ return FSE_repeat_valid;
}
size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
- short* offcodeNCount, unsigned* offcodeMaxValue,
const void* const dict, size_t dictSize)
{
+ short offcodeNCount[MaxOff+1];
+ unsigned offcodeMaxValue = MaxOff;
const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */
const BYTE* const dictEnd = dictPtr + dictSize;
dictPtr += 8;
@@ -2924,16 +3190,16 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
}
{ unsigned offcodeLog;
- size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
+ size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
- /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
/* fill all offset symbols to avoid garbage at end of table */
RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
bs->entropy.fse.offcodeCTable,
offcodeNCount, MaxOff, offcodeLog,
workspace, HUF_WORKSPACE_SIZE)),
dictionary_corrupted, "");
+ /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
dictPtr += offcodeHeaderSize;
}
@@ -2942,13 +3208,12 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
- /* Every match length code must have non-zero probability */
- FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML), "");
RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
bs->entropy.fse.matchlengthCTable,
matchlengthNCount, matchlengthMaxValue, matchlengthLog,
workspace, HUF_WORKSPACE_SIZE)),
dictionary_corrupted, "");
+ bs->entropy.fse.matchlength_repeatMode = ZSTD_dictNCountRepeat(matchlengthNCount, matchlengthMaxValue, MaxML);
dictPtr += matchlengthHeaderSize;
}
@@ -2957,13 +3222,12 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
- /* Every literal length code must have non-zero probability */
- FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL), "");
RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
bs->entropy.fse.litlengthCTable,
litlengthNCount, litlengthMaxValue, litlengthLog,
workspace, HUF_WORKSPACE_SIZE)),
dictionary_corrupted, "");
+ bs->entropy.fse.litlength_repeatMode = ZSTD_dictNCountRepeat(litlengthNCount, litlengthMaxValue, MaxLL);
dictPtr += litlengthHeaderSize;
}
@@ -2973,12 +3237,28 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
bs->rep[2] = MEM_readLE32(dictPtr+8);
dictPtr += 12;
+ { size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
+ U32 offcodeMax = MaxOff;
+ if (dictContentSize <= ((U32)-1) - 128 KB) {
+ U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
+ offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
+ }
+ /* All offset values <= dictContentSize + 128 KB must be representable for a valid table */
+ bs->entropy.fse.offcode_repeatMode = ZSTD_dictNCountRepeat(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff));
+
+ /* All repCodes must be <= dictContentSize and != 0 */
+ { U32 u;
+ for (u=0; u<3; u++) {
+ RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, "");
+ RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
+ } } }
+
return dictPtr - (const BYTE*)dict;
}
/* Dictionary format :
* See :
- * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
+ * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#dictionary-format
*/
/*! ZSTD_loadZstdDictionary() :
* @return : dictID, or an error code
@@ -2995,8 +3275,6 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
{
const BYTE* dictPtr = (const BYTE*)dict;
const BYTE* const dictEnd = dictPtr + dictSize;
- short offcodeNCount[MaxOff+1];
- unsigned offcodeMaxValue = MaxOff;
size_t dictID;
size_t eSize;
@@ -3005,32 +3283,16 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr + 4 /* skip magic number */ );
- eSize = ZSTD_loadCEntropy(bs, workspace, offcodeNCount, &offcodeMaxValue, dict, dictSize);
+ eSize = ZSTD_loadCEntropy(bs, workspace, dict, dictSize);
FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed");
dictPtr += eSize;
- { size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
- U32 offcodeMax = MaxOff;
- if (dictContentSize <= ((U32)-1) - 128 KB) {
- U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
- offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
- }
- /* All offset values <= dictContentSize + 128 KB must be representable */
- FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)), "");
- /* All repCodes must be <= dictContentSize and != 0*/
- { U32 u;
- for (u=0; u<3; u++) {
- RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, "");
- RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
- } }
-
- bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
- bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
- bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
+ {
+ size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(
ms, NULL, ws, params, dictPtr, dictContentSize, dtlm), "");
- return dictID;
}
+ return dictID;
}
/** ZSTD_compress_insertDictionary() :
@@ -3074,7 +3336,7 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
}
#define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB)
-#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6)
+#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6ULL)
/*! ZSTD_compressBegin_internal() :
* @return : 0, or an error code */
@@ -3106,7 +3368,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
ZSTD_compress_insertDictionary(
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
&cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent,
- cdict->dictContentSize, dictContentType, dtlm,
+ cdict->dictContentSize, cdict->dictContentType, dtlm,
cctx->entropyWorkspace)
: ZSTD_compress_insertDictionary(
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
@@ -3153,7 +3415,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
{
- ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
+ ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict);
ZSTD_CCtx_params const cctxParams =
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, &params);
DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
@@ -3234,7 +3496,6 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
return cSize + endResult;
}
-
static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
@@ -3287,7 +3548,7 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
int compressionLevel)
{
- ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0);
+ ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict);
ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, &params);
DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize);
assert(params.fParams.contentSizeFlag == 1);
@@ -3309,10 +3570,17 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity,
int compressionLevel)
{
size_t result;
+#if ZSTD_COMPRESS_HEAPMODE
+ ZSTD_CCtx* cctx = ZSTD_createCCtx();
+ RETURN_ERROR_IF(!cctx, memory_allocation, "ZSTD_createCCtx failed");
+ result = ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel);
+ ZSTD_freeCCtx(cctx);
+#else
ZSTD_CCtx ctxBody;
ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem);
result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */
+#endif
return result;
}
@@ -3335,7 +3603,7 @@ size_t ZSTD_estimateCDictSize_advanced(
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
{
- ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);
}
@@ -3353,20 +3621,25 @@ static size_t ZSTD_initCDict_internal(
const void* dictBuffer, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
- ZSTD_compressionParameters cParams)
+ ZSTD_CCtx_params params)
{
DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (unsigned)dictContentType);
- assert(!ZSTD_checkCParams(cParams));
- cdict->matchState.cParams = cParams;
+ assert(!ZSTD_checkCParams(params.cParams));
+ cdict->matchState.cParams = params.cParams;
+ cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch;
+ if (cdict->matchState.dedicatedDictSearch && dictSize > ZSTD_CHUNKSIZE_MAX) {
+ cdict->matchState.dedicatedDictSearch = 0;
+ }
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
cdict->dictContent = dictBuffer;
} else {
void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!");
cdict->dictContent = internalBuffer;
- memcpy(internalBuffer, dictBuffer, dictSize);
+ ZSTD_memcpy(internalBuffer, dictBuffer, dictSize);
}
cdict->dictContentSize = dictSize;
+ cdict->dictContentType = dictContentType;
cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE);
@@ -3376,18 +3649,15 @@ static size_t ZSTD_initCDict_internal(
FORWARD_IF_ERROR(ZSTD_reset_matchState(
&cdict->matchState,
&cdict->workspace,
- &cParams,
+ &params.cParams,
ZSTDcrp_makeClean,
ZSTDirp_reset,
ZSTD_resetTarget_CDict), "");
/* (Maybe) load the dictionary
* Skips loading the dictionary if it is < 8 bytes.
*/
- { ZSTD_CCtx_params params;
- memset(&params, 0, sizeof(params));
- params.compressionLevel = ZSTD_CLEVEL_DEFAULT;
+ { params.compressionLevel = ZSTD_CLEVEL_DEFAULT;
params.fParams.contentSizeFlag = 1;
- params.cParams = cParams;
{ size_t const dictID = ZSTD_compress_insertDictionary(
&cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace,
&params, cdict->dictContent, cdict->dictContentSize,
@@ -3401,13 +3671,11 @@ static size_t ZSTD_initCDict_internal(
return 0;
}
-ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
+static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
- ZSTD_dictContentType_e dictContentType,
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
{
- DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (unsigned)dictContentType);
- if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
+ if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
{ size_t const workspaceSize =
ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) +
@@ -3415,16 +3683,16 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0) +
(dictLoadMethod == ZSTD_dlm_byRef ? 0
: ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))));
- void* const workspace = ZSTD_malloc(workspaceSize, customMem);
+ void* const workspace = ZSTD_customMalloc(workspaceSize, customMem);
ZSTD_cwksp ws;
ZSTD_CDict* cdict;
if (!workspace) {
- ZSTD_free(workspace, customMem);
+ ZSTD_customFree(workspace, customMem);
return NULL;
}
- ZSTD_cwksp_init(&ws, workspace, workspaceSize);
+ ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_dynamic_alloc);
cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
assert(cdict != NULL);
@@ -3432,35 +3700,94 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
cdict->customMem = customMem;
cdict->compressionLevel = 0; /* signals advanced API usage */
- if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
- dictBuffer, dictSize,
- dictLoadMethod, dictContentType,
- cParams) )) {
- ZSTD_freeCDict(cdict);
- return NULL;
- }
-
return cdict;
}
}
+ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_dictContentType_e dictContentType,
+ ZSTD_compressionParameters cParams,
+ ZSTD_customMem customMem)
+{
+ ZSTD_CCtx_params cctxParams;
+ ZSTD_memset(&cctxParams, 0, sizeof(cctxParams));
+ ZSTD_CCtxParams_init(&cctxParams, 0);
+ cctxParams.cParams = cParams;
+ cctxParams.customMem = customMem;
+ return ZSTD_createCDict_advanced2(
+ dictBuffer, dictSize,
+ dictLoadMethod, dictContentType,
+ &cctxParams, customMem);
+}
+
+ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2(
+ const void* dict, size_t dictSize,
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_dictContentType_e dictContentType,
+ const ZSTD_CCtx_params* originalCctxParams,
+ ZSTD_customMem customMem)
+{
+ ZSTD_CCtx_params cctxParams = *originalCctxParams;
+ ZSTD_compressionParameters cParams;
+ ZSTD_CDict* cdict;
+
+ DEBUGLOG(3, "ZSTD_createCDict_advanced2, mode %u", (unsigned)dictContentType);
+ if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
+
+ if (cctxParams.enableDedicatedDictSearch) {
+ cParams = ZSTD_dedicatedDictSearch_getCParams(
+ cctxParams.compressionLevel, dictSize);
+ ZSTD_overrideCParams(&cParams, &cctxParams.cParams);
+ } else {
+ cParams = ZSTD_getCParamsFromCCtxParams(
+ &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
+ }
+
+ if (!ZSTD_dedicatedDictSearch_isSupported(&cParams)) {
+ /* Fall back to non-DDSS params */
+ cctxParams.enableDedicatedDictSearch = 0;
+ cParams = ZSTD_getCParamsFromCCtxParams(
+ &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
+ }
+
+ cctxParams.cParams = cParams;
+
+ cdict = ZSTD_createCDict_advanced_internal(dictSize,
+ dictLoadMethod, cctxParams.cParams,
+ customMem);
+
+ if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
+ dict, dictSize,
+ dictLoadMethod, dictContentType,
+ cctxParams) )) {
+ ZSTD_freeCDict(cdict);
+ return NULL;
+ }
+
+ return cdict;
+}
+
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
{
- ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
- ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dict, dictSize,
+ ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
+ ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize,
ZSTD_dlm_byCopy, ZSTD_dct_auto,
cParams, ZSTD_defaultCMem);
if (cdict)
- cdict->compressionLevel = compressionLevel == 0 ? ZSTD_CLEVEL_DEFAULT : compressionLevel;
+ cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel;
return cdict;
}
ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
{
- ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
- return ZSTD_createCDict_advanced(dict, dictSize,
+ ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
+ ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize,
ZSTD_dlm_byRef, ZSTD_dct_auto,
cParams, ZSTD_defaultCMem);
+ if (cdict)
+ cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel;
+ return cdict;
}
size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
@@ -3470,7 +3797,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict);
ZSTD_cwksp_free(&cdict->workspace, cMem);
if (!cdictInWorkspace) {
- ZSTD_free(cdict, cMem);
+ ZSTD_customFree(cdict, cMem);
}
return 0;
}
@@ -3503,12 +3830,13 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
+ ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE)
+ matchStateSize;
ZSTD_CDict* cdict;
+ ZSTD_CCtx_params params;
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
{
ZSTD_cwksp ws;
- ZSTD_cwksp_init(&ws, workspace, workspaceSize);
+ ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc);
cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
if (cdict == NULL) return NULL;
ZSTD_cwksp_move(&cdict->workspace, &ws);
@@ -3518,10 +3846,13 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
(unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
if (workspaceSize < neededSize) return NULL;
+ ZSTD_CCtxParams_init(&params, 0);
+ params.cParams = cParams;
+
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
dict, dictSize,
dictLoadMethod, dictContentType,
- cParams) ))
+ params) ))
return NULL;
return cdict;
@@ -3533,6 +3864,17 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict)
return cdict->matchState.cParams;
}
+/*! ZSTD_getDictID_fromCDict() :
+ * Provides the dictID of the dictionary loaded into `cdict`.
+ * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
+ * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
+unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict)
+{
+ if (cdict==NULL) return 0;
+ return cdict->dictID;
+}
+
+
/* ZSTD_compressBegin_usingCDict_advanced() :
* cdict must be != NULL */
size_t ZSTD_compressBegin_usingCDict_advanced(
@@ -3640,32 +3982,12 @@ size_t ZSTD_CStreamOutSize(void)
return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
}
-static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
- const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType,
- const ZSTD_CDict* const cdict,
- ZSTD_CCtx_params params, unsigned long long const pledgedSrcSize)
+static ZSTD_cParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize)
{
- DEBUGLOG(4, "ZSTD_resetCStream_internal");
- /* Finalize the compression parameters */
- params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);
- /* params are supposed to be fully validated at this point */
- assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
- assert(!((dict) && (cdict))); /* either dict or cdict, not both */
-
- FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
- dict, dictSize, dictContentType, ZSTD_dtlm_fast,
- cdict,
- &params, pledgedSrcSize,
- ZSTDb_buffered) , "");
-
- cctx->inToCompress = 0;
- cctx->inBuffPos = 0;
- cctx->inBuffTarget = cctx->blockSize
- + (cctx->blockSize == pledgedSrcSize); /* for small input: avoid automatic flush on reaching end of block, since it would require to add a 3-bytes null block to end frame */
- cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0;
- cctx->streamStage = zcss_load;
- cctx->frameEnded = 0;
- return 0; /* ready to go */
+ if (cdict != NULL && ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize))
+ return ZSTD_cpm_attachDict;
+ else
+ return ZSTD_cpm_noAttachDict;
}
/* ZSTD_resetCStream():
@@ -3815,12 +4137,17 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
/* check expectations */
DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%u", (unsigned)flushMode);
- assert(zcs->inBuff != NULL);
- assert(zcs->inBuffSize > 0);
- assert(zcs->outBuff != NULL);
- assert(zcs->outBuffSize > 0);
+ if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) {
+ assert(zcs->inBuff != NULL);
+ assert(zcs->inBuffSize > 0);
+ }
+ if (zcs->appliedParams.outBufferMode == ZSTD_bm_buffered) {
+ assert(zcs->outBuff != NULL);
+ assert(zcs->outBuffSize > 0);
+ }
assert(output->pos <= output->size);
assert(input->pos <= input->size);
+ assert((U32)flushMode <= (U32)ZSTD_e_end);
while (someMoreWork) {
switch(zcs->streamStage)
@@ -3830,7 +4157,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
case zcss_load:
if ( (flushMode == ZSTD_e_end)
- && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip)) /* enough dstCapacity */
+ && ( (size_t)(oend-op) >= ZSTD_compressBound(iend-ip) /* Enough output space */
+ || zcs->appliedParams.outBufferMode == ZSTD_bm_stable) /* OR we are allowed to return dstSizeTooSmall */
&& (zcs->inBuffPos == 0) ) {
/* shortcut to compression pass directly into output buffer */
size_t const cSize = ZSTD_compressEnd(zcs,
@@ -3843,8 +4171,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
someMoreWork = 0; break;
}
- /* complete loading into inBuffer */
- { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
+ /* complete loading into inBuffer in buffered mode */
+ if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) {
+ size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
size_t const loaded = ZSTD_limitCopy(
zcs->inBuff + zcs->inBuffPos, toLoad,
ip, iend-ip);
@@ -3864,31 +4193,49 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
}
/* compress current block (note : this stage cannot be stopped in the middle) */
DEBUGLOG(5, "stream compression stage (flushMode==%u)", flushMode);
- { void* cDst;
+ { int const inputBuffered = (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered);
+ void* cDst;
size_t cSize;
- size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
size_t oSize = oend-op;
- unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend);
- if (oSize >= ZSTD_compressBound(iSize))
+ size_t const iSize = inputBuffered
+ ? zcs->inBuffPos - zcs->inToCompress
+ : MIN((size_t)(iend - ip), zcs->blockSize);
+ if (oSize >= ZSTD_compressBound(iSize) || zcs->appliedParams.outBufferMode == ZSTD_bm_stable)
cDst = op; /* compress into output buffer, to skip flush stage */
else
cDst = zcs->outBuff, oSize = zcs->outBuffSize;
- cSize = lastBlock ?
- ZSTD_compressEnd(zcs, cDst, oSize,
- zcs->inBuff + zcs->inToCompress, iSize) :
- ZSTD_compressContinue(zcs, cDst, oSize,
- zcs->inBuff + zcs->inToCompress, iSize);
- FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
- zcs->frameEnded = lastBlock;
- /* prepare next block */
- zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
- if (zcs->inBuffTarget > zcs->inBuffSize)
- zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
- DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
- (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);
- if (!lastBlock)
- assert(zcs->inBuffTarget <= zcs->inBuffSize);
- zcs->inToCompress = zcs->inBuffPos;
+ if (inputBuffered) {
+ unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend);
+ cSize = lastBlock ?
+ ZSTD_compressEnd(zcs, cDst, oSize,
+ zcs->inBuff + zcs->inToCompress, iSize) :
+ ZSTD_compressContinue(zcs, cDst, oSize,
+ zcs->inBuff + zcs->inToCompress, iSize);
+ FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
+ zcs->frameEnded = lastBlock;
+ /* prepare next block */
+ zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
+ if (zcs->inBuffTarget > zcs->inBuffSize)
+ zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
+ DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
+ (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);
+ if (!lastBlock)
+ assert(zcs->inBuffTarget <= zcs->inBuffSize);
+ zcs->inToCompress = zcs->inBuffPos;
+ } else {
+ unsigned const lastBlock = (ip + iSize == iend);
+ assert(flushMode == ZSTD_e_end /* Already validated */);
+ cSize = lastBlock ?
+ ZSTD_compressEnd(zcs, cDst, oSize, ip, iSize) :
+ ZSTD_compressContinue(zcs, cDst, oSize, ip, iSize);
+ /* Consume the input prior to error checking to mirror buffered mode. */
+ if (iSize > 0)
+ ip += iSize;
+ FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
+ zcs->frameEnded = lastBlock;
+ if (lastBlock)
+ assert(ip == iend);
+ }
if (cDst == op) { /* no need to flush */
op += cSize;
if (zcs->frameEnded) {
@@ -3905,6 +4252,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
/* fall-through */
case zcss_flush:
DEBUGLOG(5, "flush stage");
+ assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered);
{ size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
size_t const flushed = ZSTD_limitCopy(op, (size_t)(oend-op),
zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
@@ -3959,6 +4307,116 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf
return ZSTD_nextInputSizeHint_MTorST(zcs);
}
+/* After a compression call set the expected input/output buffer.
+ * This is validated at the start of the next compression call.
+ */
+static void ZSTD_setBufferExpectations(ZSTD_CCtx* cctx, ZSTD_outBuffer const* output, ZSTD_inBuffer const* input)
+{
+ if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
+ cctx->expectedInBuffer = *input;
+ }
+ if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
+ cctx->expectedOutBufferSize = output->size - output->pos;
+ }
+}
+
+/* Validate that the input/output buffers match the expectations set by
+ * ZSTD_setBufferExpectations.
+ */
+static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx,
+ ZSTD_outBuffer const* output,
+ ZSTD_inBuffer const* input,
+ ZSTD_EndDirective endOp)
+{
+ if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
+ ZSTD_inBuffer const expect = cctx->expectedInBuffer;
+ if (expect.src != input->src || expect.pos != input->pos || expect.size != input->size)
+ RETURN_ERROR(srcBuffer_wrong, "ZSTD_c_stableInBuffer enabled but input differs!");
+ if (endOp != ZSTD_e_end)
+ RETURN_ERROR(srcBuffer_wrong, "ZSTD_c_stableInBuffer can only be used with ZSTD_e_end!");
+ }
+ if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
+ size_t const outBufferSize = output->size - output->pos;
+ if (cctx->expectedOutBufferSize != outBufferSize)
+ RETURN_ERROR(dstBuffer_wrong, "ZSTD_c_stableOutBuffer enabled but output size differs!");
+ }
+ return 0;
+}
+
+static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
+ ZSTD_EndDirective endOp,
+ size_t inSize) {
+ ZSTD_CCtx_params params = cctx->requestedParams;
+ ZSTD_prefixDict const prefixDict = cctx->prefixDict;
+ FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */
+ ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */
+ assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
+ if (cctx->cdict)
+ params.compressionLevel = cctx->cdict->compressionLevel; /* let cdict take priority in terms of compression level */
+ DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
+ if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1; /* auto-fix pledgedSrcSize */
+ {
+ size_t const dictSize = prefixDict.dict
+ ? prefixDict.dictSize
+ : (cctx->cdict ? cctx->cdict->dictContentSize : 0);
+ ZSTD_cParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, &params, cctx->pledgedSrcSizePlusOne - 1);
+ params.cParams = ZSTD_getCParamsFromCCtxParams(
+ &params, cctx->pledgedSrcSizePlusOne-1,
+ dictSize, mode);
+ }
+
+ if (ZSTD_CParams_shouldEnableLdm(&params.cParams)) {
+ /* Enable LDM by default for optimal parser and window size >= 128MB */
+ DEBUGLOG(4, "LDM enabled by default (window size >= 128MB, strategy >= btopt)");
+ params.ldmParams.enableLdm = 1;
+ }
+
+#ifdef ZSTD_MULTITHREAD
+ if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
+ params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
+ }
+ if (params.nbWorkers > 0) {
+ /* mt context creation */
+ if (cctx->mtctx == NULL) {
+ DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
+ params.nbWorkers);
+ cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem, cctx->pool);
+ RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!");
+ }
+ /* mt compression */
+ DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
+ FORWARD_IF_ERROR( ZSTDMT_initCStream_internal(
+ cctx->mtctx,
+ prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
+ cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , "");
+ cctx->streamStage = zcss_load;
+ cctx->appliedParams = params;
+ } else
+#endif
+ { U64 const pledgedSrcSize = cctx->pledgedSrcSizePlusOne - 1;
+ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
+ FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
+ prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, ZSTD_dtlm_fast,
+ cctx->cdict,
+ &params, pledgedSrcSize,
+ ZSTDb_buffered) , "");
+ assert(cctx->appliedParams.nbWorkers == 0);
+ cctx->inToCompress = 0;
+ cctx->inBuffPos = 0;
+ if (cctx->appliedParams.inBufferMode == ZSTD_bm_buffered) {
+ /* for small input: avoid automatic flush on reaching end of block, since
+ * it would require to add a 3-bytes null block to end frame
+ */
+ cctx->inBuffTarget = cctx->blockSize + (cctx->blockSize == pledgedSrcSize);
+ } else {
+ cctx->inBuffTarget = 0;
+ }
+ cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0;
+ cctx->streamStage = zcss_load;
+ cctx->frameEnded = 0;
+ }
+ return 0;
+}
size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
ZSTD_outBuffer* output,
@@ -3967,82 +4425,65 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
{
DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
/* check conditions */
- RETURN_ERROR_IF(output->pos > output->size, GENERIC, "invalid buffer");
- RETURN_ERROR_IF(input->pos > input->size, GENERIC, "invalid buffer");
- assert(cctx!=NULL);
+ RETURN_ERROR_IF(output->pos > output->size, dstSize_tooSmall, "invalid output buffer");
+ RETURN_ERROR_IF(input->pos > input->size, srcSize_wrong, "invalid input buffer");
+ RETURN_ERROR_IF((U32)endOp > (U32)ZSTD_e_end, parameter_outOfBound, "invalid endDirective");
+ assert(cctx != NULL);
/* transparent initialization stage */
if (cctx->streamStage == zcss_init) {
- ZSTD_CCtx_params params = cctx->requestedParams;
- ZSTD_prefixDict const prefixDict = cctx->prefixDict;
- FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */
- memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */
- assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
- DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
- if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1; /* auto-fix pledgedSrcSize */
- params.cParams = ZSTD_getCParamsFromCCtxParams(
- &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
-
-
-#ifdef ZSTD_MULTITHREAD
- if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
- params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
- }
- if (params.nbWorkers > 0) {
- /* mt context creation */
- if (cctx->mtctx == NULL) {
- DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
- params.nbWorkers);
- cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem);
- RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!");
- }
- /* mt compression */
- DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
- FORWARD_IF_ERROR( ZSTDMT_initCStream_internal(
- cctx->mtctx,
- prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
- cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , "");
- cctx->streamStage = zcss_load;
- cctx->appliedParams.nbWorkers = params.nbWorkers;
- } else
-#endif
- { FORWARD_IF_ERROR( ZSTD_resetCStream_internal(cctx,
- prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
- cctx->cdict,
- params, cctx->pledgedSrcSizePlusOne-1) , "");
- assert(cctx->streamStage == zcss_load);
- assert(cctx->appliedParams.nbWorkers == 0);
- } }
+ FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, endOp, input->size), "CompressStream2 initialization failed");
+ ZSTD_setBufferExpectations(cctx, output, input); /* Set initial buffer expectations now that we've initialized */
+ }
/* end of transparent initialization stage */
+ FORWARD_IF_ERROR(ZSTD_checkBufferStability(cctx, output, input, endOp), "invalid buffers");
/* compression stage */
#ifdef ZSTD_MULTITHREAD
if (cctx->appliedParams.nbWorkers > 0) {
- int const forceMaxProgress = (endOp == ZSTD_e_flush || endOp == ZSTD_e_end);
size_t flushMin;
- assert(forceMaxProgress || endOp == ZSTD_e_continue /* Protection for a new flush type */);
if (cctx->cParamsChanged) {
ZSTDMT_updateCParams_whileCompressing(cctx->mtctx, &cctx->requestedParams);
cctx->cParamsChanged = 0;
}
- do {
+ for (;;) {
+ size_t const ipos = input->pos;
+ size_t const opos = output->pos;
flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
if ( ZSTD_isError(flushMin)
|| (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
}
FORWARD_IF_ERROR(flushMin, "ZSTDMT_compressStream_generic failed");
- } while (forceMaxProgress && flushMin != 0 && output->pos < output->size);
+
+ if (endOp == ZSTD_e_continue) {
+ /* We only require some progress with ZSTD_e_continue, not maximal progress.
+ * We're done if we've consumed or produced any bytes, or either buffer is
+ * full.
+ */
+ if (input->pos != ipos || output->pos != opos || input->pos == input->size || output->pos == output->size)
+ break;
+ } else {
+ assert(endOp == ZSTD_e_flush || endOp == ZSTD_e_end);
+ /* We require maximal progress. We're done when the flush is complete or the
+ * output buffer is full.
+ */
+ if (flushMin == 0 || output->pos == output->size)
+ break;
+ }
+ }
DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic");
/* Either we don't require maximum forward progress, we've finished the
* flush, or we are out of output space.
*/
- assert(!forceMaxProgress || flushMin == 0 || output->pos == output->size);
+ assert(endOp == ZSTD_e_continue || flushMin == 0 || output->pos == output->size);
+ ZSTD_setBufferExpectations(cctx, output, input);
return flushMin;
}
#endif
FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) , "");
DEBUGLOG(5, "completed ZSTD_compressStream2");
+ ZSTD_setBufferExpectations(cctx, output, input);
return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
}
@@ -4065,14 +4506,22 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize)
{
+ ZSTD_bufferMode_e const originalInBufferMode = cctx->requestedParams.inBufferMode;
+ ZSTD_bufferMode_e const originalOutBufferMode = cctx->requestedParams.outBufferMode;
DEBUGLOG(4, "ZSTD_compress2 (srcSize=%u)", (unsigned)srcSize);
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
+ /* Enable stable input/output buffers. */
+ cctx->requestedParams.inBufferMode = ZSTD_bm_stable;
+ cctx->requestedParams.outBufferMode = ZSTD_bm_stable;
{ size_t oPos = 0;
size_t iPos = 0;
size_t const result = ZSTD_compressStream2_simpleArgs(cctx,
dst, dstCapacity, &oPos,
src, srcSize, &iPos,
ZSTD_e_end);
+ /* Reset to the original values. */
+ cctx->requestedParams.inBufferMode = originalInBufferMode;
+ cctx->requestedParams.outBufferMode = originalOutBufferMode;
FORWARD_IF_ERROR(result, "ZSTD_compressStream2_simpleArgs failed");
if (result != 0) { /* compression not completed, due to lack of output space */
assert(oPos == dstCapacity);
@@ -4083,6 +4532,409 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
}
}
+typedef struct {
+ U32 idx; /* Index in array of ZSTD_Sequence */
+ U32 posInSequence; /* Position within sequence at idx */
+ size_t posInSrc; /* Number of bytes given by sequences provided so far */
+} ZSTD_sequencePosition;
+
+/* Returns a ZSTD error code if sequence is not valid */
+static size_t ZSTD_validateSequence(U32 offCode, U32 matchLength,
+ size_t posInSrc, U32 windowLog, size_t dictSize, U32 minMatch) {
+ size_t offsetBound;
+ U32 windowSize = 1 << windowLog;
+ /* posInSrc represents the amount of data the the decoder would decode up to this point.
+ * As long as the amount of data decoded is less than or equal to window size, offsets may be
+ * larger than the total length of output decoded in order to reference the dict, even larger than
+ * window size. After output surpasses windowSize, we're limited to windowSize offsets again.
+ */
+ offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
+ RETURN_ERROR_IF(offCode > offsetBound + ZSTD_REP_MOVE, corruption_detected, "Offset too large!");
+ RETURN_ERROR_IF(matchLength < minMatch, corruption_detected, "Matchlength too small");
+ return 0;
+}
+
+/* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */
+static U32 ZSTD_finalizeOffCode(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0) {
+ U32 offCode = rawOffset + ZSTD_REP_MOVE;
+ U32 repCode = 0;
+
+ if (!ll0 && rawOffset == rep[0]) {
+ repCode = 1;
+ } else if (rawOffset == rep[1]) {
+ repCode = 2 - ll0;
+ } else if (rawOffset == rep[2]) {
+ repCode = 3 - ll0;
+ } else if (ll0 && rawOffset == rep[0] - 1) {
+ repCode = 3;
+ }
+ if (repCode) {
+ /* ZSTD_storeSeq expects a number in the range [0, 2] to represent a repcode */
+ offCode = repCode - 1;
+ }
+ return offCode;
+}
+
+/* Returns 0 on success, and a ZSTD_error otherwise. This function scans through an array of
+ * ZSTD_Sequence, storing the sequences it finds, until it reaches a block delimiter.
+ */
+static size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
+ const void* src, size_t blockSize) {
+ U32 idx = seqPos->idx;
+ BYTE const* ip = (BYTE const*)(src);
+ const BYTE* const iend = ip + blockSize;
+ repcodes_t updatedRepcodes;
+ U32 dictSize;
+ U32 litLength;
+ U32 matchLength;
+ U32 ll0;
+ U32 offCode;
+
+ if (cctx->cdict) {
+ dictSize = (U32)cctx->cdict->dictContentSize;
+ } else if (cctx->prefixDict.dict) {
+ dictSize = (U32)cctx->prefixDict.dictSize;
+ } else {
+ dictSize = 0;
+ }
+ ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
+ for (; (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0) && idx < inSeqsSize; ++idx) {
+ litLength = inSeqs[idx].litLength;
+ matchLength = inSeqs[idx].matchLength;
+ ll0 = litLength == 0;
+ offCode = ZSTD_finalizeOffCode(inSeqs[idx].offset, updatedRepcodes.rep, ll0);
+ updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0);
+
+ DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offCode, matchLength, litLength);
+ if (cctx->appliedParams.validateSequences) {
+ seqPos->posInSrc += litLength + matchLength;
+ FORWARD_IF_ERROR(ZSTD_validateSequence(offCode, matchLength, seqPos->posInSrc,
+ cctx->appliedParams.cParams.windowLog, dictSize,
+ cctx->appliedParams.cParams.minMatch),
+ "Sequence validation failed");
+ }
+ RETURN_ERROR_IF(idx - seqPos->idx > cctx->seqStore.maxNbSeq, memory_allocation,
+ "Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
+ ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength - MINMATCH);
+ ip += matchLength + litLength;
+ }
+ ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
+
+ if (inSeqs[idx].litLength) {
+ DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength);
+ ZSTD_storeLastLiterals(&cctx->seqStore, ip, inSeqs[idx].litLength);
+ ip += inSeqs[idx].litLength;
+ seqPos->posInSrc += inSeqs[idx].litLength;
+ }
+ RETURN_ERROR_IF(ip != iend, corruption_detected, "Blocksize doesn't agree with block delimiter!");
+ seqPos->idx = idx+1;
+ return 0;
+}
+
+/* Returns the number of bytes to move the current read position back by. Only non-zero
+ * if we ended up splitting a sequence. Otherwise, it may return a ZSTD error if something
+ * went wrong.
+ *
+ * This function will attempt to scan through blockSize bytes represented by the sequences
+ * in inSeqs, storing any (partial) sequences.
+ *
+ * Occasionally, we may want to change the actual number of bytes we consumed from inSeqs to
+ * avoid splitting a match, or to avoid splitting a match such that it would produce a match
+ * smaller than MINMATCH. In this case, we return the number of bytes that we didn't read from this block.
+ */
+static size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
+ const void* src, size_t blockSize) {
+ U32 idx = seqPos->idx;
+ U32 startPosInSequence = seqPos->posInSequence;
+ U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize;
+ size_t dictSize;
+ BYTE const* ip = (BYTE const*)(src);
+ BYTE const* iend = ip + blockSize; /* May be adjusted if we decide to process fewer than blockSize bytes */
+ repcodes_t updatedRepcodes;
+ U32 bytesAdjustment = 0;
+ U32 finalMatchSplit = 0;
+ U32 litLength;
+ U32 matchLength;
+ U32 rawOffset;
+ U32 offCode;
+
+ if (cctx->cdict) {
+ dictSize = cctx->cdict->dictContentSize;
+ } else if (cctx->prefixDict.dict) {
+ dictSize = cctx->prefixDict.dictSize;
+ } else {
+ dictSize = 0;
+ }
+ DEBUGLOG(5, "ZSTD_copySequencesToSeqStore: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize);
+ DEBUGLOG(5, "Start seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
+ ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
+ while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) {
+ const ZSTD_Sequence currSeq = inSeqs[idx];
+ litLength = currSeq.litLength;
+ matchLength = currSeq.matchLength;
+ rawOffset = currSeq.offset;
+
+ /* Modify the sequence depending on where endPosInSequence lies */
+ if (endPosInSequence >= currSeq.litLength + currSeq.matchLength) {
+ if (startPosInSequence >= litLength) {
+ startPosInSequence -= litLength;
+ litLength = 0;
+ matchLength -= startPosInSequence;
+ } else {
+ litLength -= startPosInSequence;
+ }
+ /* Move to the next sequence */
+ endPosInSequence -= currSeq.litLength + currSeq.matchLength;
+ startPosInSequence = 0;
+ idx++;
+ } else {
+ /* This is the final (partial) sequence we're adding from inSeqs, and endPosInSequence
+ does not reach the end of the match. So, we have to split the sequence */
+ DEBUGLOG(6, "Require a split: diff: %u, idx: %u PIS: %u",
+ currSeq.litLength + currSeq.matchLength - endPosInSequence, idx, endPosInSequence);
+ if (endPosInSequence > litLength) {
+ U32 firstHalfMatchLength;
+ litLength = startPosInSequence >= litLength ? 0 : litLength - startPosInSequence;
+ firstHalfMatchLength = endPosInSequence - startPosInSequence - litLength;
+ if (matchLength > blockSize && firstHalfMatchLength >= cctx->appliedParams.cParams.minMatch) {
+ /* Only ever split the match if it is larger than the block size */
+ U32 secondHalfMatchLength = currSeq.matchLength + currSeq.litLength - endPosInSequence;
+ if (secondHalfMatchLength < cctx->appliedParams.cParams.minMatch) {
+ /* Move the endPosInSequence backward so that it creates match of minMatch length */
+ endPosInSequence -= cctx->appliedParams.cParams.minMatch - secondHalfMatchLength;
+ bytesAdjustment = cctx->appliedParams.cParams.minMatch - secondHalfMatchLength;
+ firstHalfMatchLength -= bytesAdjustment;
+ }
+ matchLength = firstHalfMatchLength;
+ /* Flag that we split the last match - after storing the sequence, exit the loop,
+ but keep the value of endPosInSequence */
+ finalMatchSplit = 1;
+ } else {
+ /* Move the position in sequence backwards so that we don't split match, and break to store
+ * the last literals. We use the original currSeq.litLength as a marker for where endPosInSequence
+ * should go. We prefer to do this whenever it is not necessary to split the match, or if doing so
+ * would cause the first half of the match to be too small
+ */
+ bytesAdjustment = endPosInSequence - currSeq.litLength;
+ endPosInSequence = currSeq.litLength;
+ break;
+ }
+ } else {
+ /* This sequence ends inside the literals, break to store the last literals */
+ break;
+ }
+ }
+ /* Check if this offset can be represented with a repcode */
+ { U32 ll0 = (litLength == 0);
+ offCode = ZSTD_finalizeOffCode(rawOffset, updatedRepcodes.rep, ll0);
+ updatedRepcodes = ZSTD_updateRep(updatedRepcodes.rep, offCode, ll0);
+ }
+
+ if (cctx->appliedParams.validateSequences) {
+ seqPos->posInSrc += litLength + matchLength;
+ FORWARD_IF_ERROR(ZSTD_validateSequence(offCode, matchLength, seqPos->posInSrc,
+ cctx->appliedParams.cParams.windowLog, dictSize,
+ cctx->appliedParams.cParams.minMatch),
+ "Sequence validation failed");
+ }
+ DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offCode, matchLength, litLength);
+ RETURN_ERROR_IF(idx - seqPos->idx > cctx->seqStore.maxNbSeq, memory_allocation,
+ "Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
+ ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offCode, matchLength - MINMATCH);
+ ip += matchLength + litLength;
+ }
+ DEBUGLOG(5, "Ending seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
+ assert(idx == inSeqsSize || endPosInSequence <= inSeqs[idx].litLength + inSeqs[idx].matchLength);
+ seqPos->idx = idx;
+ seqPos->posInSequence = endPosInSequence;
+ ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
+
+ iend -= bytesAdjustment;
+ if (ip != iend) {
+ /* Store any last literals */
+ U32 lastLLSize = (U32)(iend - ip);
+ assert(ip <= iend);
+ DEBUGLOG(6, "Storing last literals of size: %u", lastLLSize);
+ ZSTD_storeLastLiterals(&cctx->seqStore, ip, lastLLSize);
+ seqPos->posInSrc += lastLLSize;
+ }
+
+ return bytesAdjustment;
+}
+
+typedef size_t (*ZSTD_sequenceCopier) (ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
+ const void* src, size_t blockSize);
+static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode) {
+ ZSTD_sequenceCopier sequenceCopier = NULL;
+ assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, mode));
+ if (mode == ZSTD_sf_explicitBlockDelimiters) {
+ return ZSTD_copySequencesToSeqStoreExplicitBlockDelim;
+ } else if (mode == ZSTD_sf_noBlockDelimiters) {
+ return ZSTD_copySequencesToSeqStoreNoBlockDelim;
+ }
+ assert(sequenceCopier != NULL);
+ return sequenceCopier;
+}
+
+/* Compress, block-by-block, all of the sequences given.
+ *
+ * Returns the cumulative size of all compressed blocks (including their headers), otherwise a ZSTD error.
+ */
+static size_t ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
+ const void* src, size_t srcSize) {
+ size_t cSize = 0;
+ U32 lastBlock;
+ size_t blockSize;
+ size_t compressedSeqsSize;
+ size_t remaining = srcSize;
+ ZSTD_sequencePosition seqPos = {0, 0, 0};
+
+ BYTE const* ip = (BYTE const*)src;
+ BYTE* op = (BYTE*)dst;
+ ZSTD_sequenceCopier sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
+
+ DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize);
+ /* Special case: empty frame */
+ if (remaining == 0) {
+ U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1);
+ RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "No room for empty frame block header");
+ MEM_writeLE32(op, cBlockHeader24);
+ op += ZSTD_blockHeaderSize;
+ dstCapacity -= ZSTD_blockHeaderSize;
+ cSize += ZSTD_blockHeaderSize;
+ }
+
+ while (remaining) {
+ size_t cBlockSize;
+ size_t additionalByteAdjustment;
+ lastBlock = remaining <= cctx->blockSize;
+ blockSize = lastBlock ? (U32)remaining : (U32)cctx->blockSize;
+ ZSTD_resetSeqStore(&cctx->seqStore);
+ DEBUGLOG(4, "Working on new block. Blocksize: %zu", blockSize);
+
+ additionalByteAdjustment = sequenceCopier(cctx, &seqPos, inSeqs, inSeqsSize, ip, blockSize);
+ FORWARD_IF_ERROR(additionalByteAdjustment, "Bad sequence copy");
+ blockSize -= additionalByteAdjustment;
+
+ /* If blocks are too small, emit as a nocompress block */
+ if (blockSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
+ cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
+ FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed");
+ DEBUGLOG(4, "Block too small, writing out nocompress block: cSize: %zu", cBlockSize);
+ cSize += cBlockSize;
+ ip += blockSize;
+ op += cBlockSize;
+ remaining -= blockSize;
+ dstCapacity -= cBlockSize;
+ continue;
+ }
+
+ compressedSeqsSize = ZSTD_entropyCompressSequences(&cctx->seqStore,
+ &cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy,
+ &cctx->appliedParams,
+ op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
+ blockSize,
+ cctx->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
+ cctx->bmi2);
+ FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
+ DEBUGLOG(4, "Compressed sequences size: %zu", compressedSeqsSize);
+
+ if (!cctx->isFirstBlock &&
+ ZSTD_maybeRLE(&cctx->seqStore) &&
+ ZSTD_isRLE((BYTE const*)src, srcSize)) {
+ /* We don't want to emit our first block as a RLE even if it qualifies because
+ * doing so will cause the decoder (cli only) to throw a "should consume all input error."
+ * This is only an issue for zstd <= v1.4.3
+ */
+ compressedSeqsSize = 1;
+ }
+
+ if (compressedSeqsSize == 0) {
+ /* ZSTD_noCompressBlock writes the block header as well */
+ cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
+ FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed");
+ DEBUGLOG(4, "Writing out nocompress block, size: %zu", cBlockSize);
+ } else if (compressedSeqsSize == 1) {
+ cBlockSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, blockSize, lastBlock);
+ FORWARD_IF_ERROR(cBlockSize, "RLE compress block failed");
+ DEBUGLOG(4, "Writing out RLE block, size: %zu", cBlockSize);
+ } else {
+ U32 cBlockHeader;
+ /* Error checking and repcodes update */
+ ZSTD_confirmRepcodesAndEntropyTables(cctx);
+ if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
+ cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
+
+ /* Write block header into beginning of block*/
+ cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3);
+ MEM_writeLE24(op, cBlockHeader);
+ cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize;
+ DEBUGLOG(4, "Writing out compressed block, size: %zu", cBlockSize);
+ }
+
+ cSize += cBlockSize;
+ DEBUGLOG(4, "cSize running total: %zu", cSize);
+
+ if (lastBlock) {
+ break;
+ } else {
+ ip += blockSize;
+ op += cBlockSize;
+ remaining -= blockSize;
+ dstCapacity -= cBlockSize;
+ cctx->isFirstBlock = 0;
+ }
+ }
+
+ return cSize;
+}
+
+size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstCapacity,
+ const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
+ const void* src, size_t srcSize) {
+ BYTE* op = (BYTE*)dst;
+ size_t cSize = 0;
+ size_t compressedBlocksSize = 0;
+ size_t frameHeaderSize = 0;
+
+ /* Transparent initialization stage, same as compressStream2() */
+ DEBUGLOG(3, "ZSTD_compressSequences()");
+ assert(cctx != NULL);
+ FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, srcSize), "CCtx initialization failed");
+ /* Begin writing output, starting with frame header */
+ frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity, &cctx->appliedParams, srcSize, cctx->dictID);
+ op += frameHeaderSize;
+ dstCapacity -= frameHeaderSize;
+ cSize += frameHeaderSize;
+ if (cctx->appliedParams.fParams.checksumFlag && srcSize) {
+ XXH64_update(&cctx->xxhState, src, srcSize);
+ }
+ /* cSize includes block header size and compressed sequences size */
+ compressedBlocksSize = ZSTD_compressSequences_internal(cctx,
+ op, dstCapacity,
+ inSeqs, inSeqsSize,
+ src, srcSize);
+ FORWARD_IF_ERROR(compressedBlocksSize, "Compressing blocks failed!");
+ cSize += compressedBlocksSize;
+ dstCapacity -= compressedBlocksSize;
+
+ if (cctx->appliedParams.fParams.checksumFlag) {
+ U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
+ RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
+ DEBUGLOG(4, "Write checksum : %08X", (unsigned)checksum);
+ MEM_writeLE32((char*)dst + cSize, checksum);
+ cSize += 4;
+ }
+
+ DEBUGLOG(3, "Final compressed size: %zu", cSize);
+ return cSize;
+}
+
/*====== Finalize ======*/
/*! ZSTD_flushStream() :
@@ -4223,25 +5075,103 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
},
};
+static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize)
+{
+ ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict);
+ switch (cParams.strategy) {
+ case ZSTD_fast:
+ case ZSTD_dfast:
+ break;
+ case ZSTD_greedy:
+ case ZSTD_lazy:
+ case ZSTD_lazy2:
+ cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG;
+ break;
+ case ZSTD_btlazy2:
+ case ZSTD_btopt:
+ case ZSTD_btultra:
+ case ZSTD_btultra2:
+ break;
+ }
+ return cParams;
+}
+
+static int ZSTD_dedicatedDictSearch_isSupported(
+ ZSTD_compressionParameters const* cParams)
+{
+ return (cParams->strategy >= ZSTD_greedy) && (cParams->strategy <= ZSTD_lazy2);
+}
+
+/**
+ * Reverses the adjustment applied to cparams when enabling dedicated dict
+ * search. This is used to recover the params set to be used in the working
+ * context. (Otherwise, those tables would also grow.)
+ */
+static void ZSTD_dedicatedDictSearch_revertCParams(
+ ZSTD_compressionParameters* cParams) {
+ switch (cParams->strategy) {
+ case ZSTD_fast:
+ case ZSTD_dfast:
+ break;
+ case ZSTD_greedy:
+ case ZSTD_lazy:
+ case ZSTD_lazy2:
+ cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG;
+ break;
+ case ZSTD_btlazy2:
+ case ZSTD_btopt:
+ case ZSTD_btultra:
+ case ZSTD_btultra2:
+ break;
+ }
+}
+
+static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
+{
+ switch (mode) {
+ case ZSTD_cpm_unknown:
+ case ZSTD_cpm_noAttachDict:
+ case ZSTD_cpm_createCDict:
+ break;
+ case ZSTD_cpm_attachDict:
+ dictSize = 0;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ { int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN;
+ size_t const addedSize = unknown && dictSize > 0 ? 500 : 0;
+ return unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize;
+ }
+}
+
/*! ZSTD_getCParams_internal() :
* @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
* Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown.
- * Use dictSize == 0 for unknown or unused. */
-static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
+ * Use dictSize == 0 for unknown or unused.
+ * Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_cParamMode_e`. */
+static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
{
- int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN;
- size_t const addedSize = unknown && dictSize > 0 ? 500 : 0;
- U64 const rSize = unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize;
+ U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode);
U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
- int row = compressionLevel;
+ int row;
DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel);
+
+ /* row */
if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
- if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */
- if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
+ else if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */
+ else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
+ else row = compressionLevel;
+
{ ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
- if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel); /* acceleration factor */
+ /* acceleration factor */
+ if (compressionLevel < 0) {
+ int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel);
+ cp.targetLength = (unsigned)(-clampedCompressionLevel);
+ }
/* refine parameters based on srcSize & dictSize */
- return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);
+ return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize, mode);
}
}
@@ -4251,18 +5181,18 @@ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel,
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
{
if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
- return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize);
+ return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
}
/*! ZSTD_getParams() :
* same idea as ZSTD_getCParams()
* @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
* Fields of `ZSTD_frameParameters` are set to default values */
-static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
+static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode) {
ZSTD_parameters params;
- ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize);
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode);
DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
- memset(&params, 0, sizeof(params));
+ ZSTD_memset(&params, 0, sizeof(params));
params.cParams = cParams;
params.fParams.contentSizeFlag = 1;
return params;
@@ -4274,5 +5204,5 @@ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned lo
* Fields of `ZSTD_frameParameters` are set to default values */
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
- return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize);
+ return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
}
diff --git a/thirdparty/zstd/compress/zstd_compress_internal.h b/thirdparty/zstd/compress/zstd_compress_internal.h
index db73f6ce21..c04998b8b1 100644
--- a/thirdparty/zstd/compress/zstd_compress_internal.h
+++ b/thirdparty/zstd/compress/zstd_compress_internal.h
@@ -28,7 +28,6 @@
extern "C" {
#endif
-
/*-*************************************
* Constants
***************************************/
@@ -64,7 +63,7 @@ typedef struct {
} ZSTD_localDict;
typedef struct {
- U32 CTable[HUF_CTABLE_SIZE_U32(255)];
+ HUF_CElt CTable[HUF_CTABLE_SIZE_U32(255)];
HUF_repeat repeatMode;
} ZSTD_hufCTables_t;
@@ -83,11 +82,28 @@ typedef struct {
} ZSTD_entropyCTables_t;
typedef struct {
- U32 off;
- U32 len;
+ U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */
+ U32 len; /* Raw length of match */
} ZSTD_match_t;
typedef struct {
+ U32 offset; /* Offset of sequence */
+ U32 litLength; /* Length of literals prior to match */
+ U32 matchLength; /* Raw length of match */
+} rawSeq;
+
+typedef struct {
+ rawSeq* seq; /* The start of the sequences */
+ size_t pos; /* The index in seq where reading stopped. pos <= size. */
+ size_t posInSequence; /* The position within the sequence at seq[pos] where reading
+ stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */
+ size_t size; /* The number of sequences. <= capacity. */
+ size_t capacity; /* The capacity starting from `seq` pointer */
+} rawSeqStore_t;
+
+UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0};
+
+typedef struct {
int price;
U32 off;
U32 mlen;
@@ -147,9 +163,13 @@ struct ZSTD_matchState_t {
U32* hashTable;
U32* hashTable3;
U32* chainTable;
+ int dedicatedDictSearch; /* Indicates whether this matchState is using the
+ * dedicated dictionary search structure.
+ */
optState_t opt; /* optimal parser state */
const ZSTD_matchState_t* dictMatchState;
ZSTD_compressionParameters cParams;
+ const rawSeqStore_t* ldmSeqStore;
};
typedef struct {
@@ -182,19 +202,6 @@ typedef struct {
} ldmParams_t;
typedef struct {
- U32 offset;
- U32 litLength;
- U32 matchLength;
-} rawSeq;
-
-typedef struct {
- rawSeq* seq; /* The start of the sequences */
- size_t pos; /* The position where reading stopped. <= size. */
- size_t size; /* The number of sequences. <= capacity. */
- size_t capacity; /* The capacity starting from `seq` pointer */
-} rawSeqStore_t;
-
-typedef struct {
int collectSequences;
ZSTD_Sequence* seqStart;
size_t seqIndex;
@@ -228,10 +235,34 @@ struct ZSTD_CCtx_params_s {
/* Long distance matching parameters */
ldmParams_t ldmParams;
+ /* Dedicated dict search algorithm trigger */
+ int enableDedicatedDictSearch;
+
+ /* Input/output buffer modes */
+ ZSTD_bufferMode_e inBufferMode;
+ ZSTD_bufferMode_e outBufferMode;
+
+ /* Sequence compression API */
+ ZSTD_sequenceFormat_e blockDelimiters;
+ int validateSequences;
+
/* Internal use, for createCCtxParams() and freeCCtxParams() only */
ZSTD_customMem customMem;
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
+#define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2))
+#define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE)
+
+/**
+ * Indicates whether this compression proceeds directly from user-provided
+ * source buffer to user-provided destination buffer (ZSTDb_not_buffered), or
+ * whether the context needs to buffer the input/output (ZSTDb_buffered).
+ */
+typedef enum {
+ ZSTDb_not_buffered,
+ ZSTDb_buffered
+} ZSTD_buffered_policy_e;
+
struct ZSTD_CCtx_s {
ZSTD_compressionStage_e stage;
int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */
@@ -247,6 +278,7 @@ struct ZSTD_CCtx_s {
unsigned long long producedCSize;
XXH64_state_t xxhState;
ZSTD_customMem customMem;
+ ZSTD_threadPool* pool;
size_t staticSize;
SeqCollector seqCollector;
int isFirstBlock;
@@ -258,7 +290,10 @@ struct ZSTD_CCtx_s {
size_t maxNbLdmSequences;
rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */
ZSTD_blockState_t blockState;
- U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
+ U32* entropyWorkspace; /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */
+
+ /* Wether we are streaming or not */
+ ZSTD_buffered_policy_e bufferedPolicy;
/* streaming */
char* inBuff;
@@ -273,6 +308,10 @@ struct ZSTD_CCtx_s {
ZSTD_cStreamStage streamStage;
U32 frameEnded;
+ /* Stable in/out buffer verification */
+ ZSTD_inBuffer expectedInBuffer;
+ size_t expectedOutBufferSize;
+
/* Dictionary */
ZSTD_localDict localDict;
const ZSTD_CDict* cdict;
@@ -286,8 +325,32 @@ struct ZSTD_CCtx_s {
typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;
-typedef enum { ZSTD_noDict = 0, ZSTD_extDict = 1, ZSTD_dictMatchState = 2 } ZSTD_dictMode_e;
-
+typedef enum {
+ ZSTD_noDict = 0,
+ ZSTD_extDict = 1,
+ ZSTD_dictMatchState = 2,
+ ZSTD_dedicatedDictSearch = 3
+} ZSTD_dictMode_e;
+
+typedef enum {
+ ZSTD_cpm_noAttachDict = 0, /* Compression with ZSTD_noDict or ZSTD_extDict.
+ * In this mode we use both the srcSize and the dictSize
+ * when selecting and adjusting parameters.
+ */
+ ZSTD_cpm_attachDict = 1, /* Compression with ZSTD_dictMatchState or ZSTD_dedicatedDictSearch.
+ * In this mode we only take the srcSize into account when selecting
+ * and adjusting parameters.
+ */
+ ZSTD_cpm_createCDict = 2, /* Creating a CDict.
+ * In this mode we take both the source size and the dictionary size
+ * into account when selecting and adjusting the parameters.
+ */
+ ZSTD_cpm_unknown = 3, /* ZSTD_getCParams, ZSTD_getParams, ZSTD_adjustParams.
+ * We don't know what these parameters are for. We default to the legacy
+ * behavior of taking both the source size and the dict size into account
+ * when selecting and adjusting parameters.
+ */
+} ZSTD_cParamMode_e;
typedef size_t (*ZSTD_blockCompressor) (
ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -345,7 +408,7 @@ MEM_STATIC repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 con
newReps.rep[1] = rep[0];
newReps.rep[0] = currentOffset;
} else { /* repCode == 0 */
- memcpy(&newReps, rep, sizeof(newReps));
+ ZSTD_memcpy(&newReps, rep, sizeof(newReps));
}
}
return newReps;
@@ -372,7 +435,7 @@ MEM_STATIC size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const voi
RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
dstSize_tooSmall, "dst buf too small for uncompressed block");
MEM_writeLE24(dst, cBlockHeader24);
- memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
+ ZSTD_memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
return ZSTD_blockHeaderSize + srcSize;
}
@@ -498,8 +561,12 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
if (MEM_isLittleEndian()) {
if (MEM_64bits()) {
# if defined(_MSC_VER) && defined(_WIN64)
- unsigned long r = 0;
- return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0;
+# if STATIC_BMI2
+ return _tzcnt_u64(val) >> 3;
+# else
+ unsigned long r = 0;
+ return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0;
+# endif
# elif defined(__GNUC__) && (__GNUC__ >= 4)
return (__builtin_ctzll((U64)val) >> 3);
# else
@@ -530,8 +597,12 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
} else { /* Big Endian CPU */
if (MEM_64bits()) {
# if defined(_MSC_VER) && defined(_WIN64)
- unsigned long r = 0;
- return _BitScanReverse64( &r, val ) ? (unsigned)(r >> 3) : 0;
+# if STATIC_BMI2
+ return _lzcnt_u64(val) >> 3;
+# else
+ unsigned long r = 0;
+ return _BitScanReverse64(&r, (U64)val) ? (unsigned)(r >> 3) : 0;
+# endif
# elif defined(__GNUC__) && (__GNUC__ >= 4)
return (__builtin_clzll(val) >> 3);
# else
@@ -626,7 +697,8 @@ static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
-MEM_STATIC size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
+MEM_STATIC FORCE_INLINE_ATTR
+size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
{
switch(mls)
{
@@ -742,7 +814,7 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
return ZSTD_window_hasExtDict(ms->window) ?
ZSTD_extDict :
ms->dictMatchState != NULL ?
- ZSTD_dictMatchState :
+ (ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) :
ZSTD_noDict;
}
@@ -754,8 +826,8 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
void const* srcEnd)
{
- U32 const current = (U32)((BYTE const*)srcEnd - window.base);
- return current > ZSTD_CURRENT_MAX;
+ U32 const curr = (U32)((BYTE const*)srcEnd - window.base);
+ return curr > ZSTD_CURRENT_MAX;
}
/**
@@ -791,14 +863,14 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
* windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
*/
U32 const cycleMask = (1U << cycleLog) - 1;
- U32 const current = (U32)((BYTE const*)src - window->base);
- U32 const currentCycle0 = current & cycleMask;
+ U32 const curr = (U32)((BYTE const*)src - window->base);
+ U32 const currentCycle0 = curr & cycleMask;
/* Exclude zero so that newCurrent - maxDist >= 1. */
U32 const currentCycle1 = currentCycle0 == 0 ? (1U << cycleLog) : currentCycle0;
U32 const newCurrent = currentCycle1 + maxDist;
- U32 const correction = current - newCurrent;
+ U32 const correction = curr - newCurrent;
assert((maxDist & cycleMask) == 0);
- assert(current > newCurrent);
+ assert(curr > newCurrent);
/* Loose bound, should be around 1<<29 (see above) */
assert(correction > 1<<28);
@@ -919,7 +991,7 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
}
MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
- memset(window, 0, sizeof(*window));
+ ZSTD_memset(window, 0, sizeof(*window));
window->base = (BYTE const*)"";
window->dictBase = (BYTE const*)"";
window->dictLimit = 1; /* start from 1, so that 1st position is valid */
@@ -973,12 +1045,16 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
/**
* Returns the lowest allowed match index. It may either be in the ext-dict or the prefix.
*/
-MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog)
+MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
{
U32 const maxDistance = 1U << windowLog;
U32 const lowestValid = ms->window.lowLimit;
- U32 const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
+ U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
U32 const isDictionary = (ms->loadedDictEnd != 0);
+ /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary
+ * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't
+ * valid for the entire block. So this check is sufficient to find the lowest valid match index.
+ */
U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
return matchLowest;
}
@@ -986,12 +1062,15 @@ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current
/**
* Returns the lowest allowed match index in the prefix.
*/
-MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog)
+MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
{
U32 const maxDistance = 1U << windowLog;
U32 const lowestValid = ms->window.dictLimit;
- U32 const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
+ U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
U32 const isDictionary = (ms->loadedDictEnd != 0);
+ /* When computing the lowest prefix index we need to take the dictionary into account to handle
+ * the edge case where the dictionary and the source are contiguous in memory.
+ */
U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
return matchLowest;
}
@@ -1045,7 +1124,6 @@ MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)
* assumptions : magic number supposed already checked
* and dictSize >= 8 */
size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
- short* offcodeNCount, unsigned* offcodeMaxValue,
const void* const dict, size_t dictSize);
void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
@@ -1061,7 +1139,7 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
* Note: srcSizeHint == 0 means 0!
*/
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
- const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize);
+ const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
/*! ZSTD_initCStream_internal() :
* Private use only. Init streaming operation.
diff --git a/thirdparty/zstd/compress/zstd_compress_literals.c b/thirdparty/zstd/compress/zstd_compress_literals.c
index 17e7168d89..6dd1c1447a 100644
--- a/thirdparty/zstd/compress/zstd_compress_literals.c
+++ b/thirdparty/zstd/compress/zstd_compress_literals.c
@@ -35,7 +35,7 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src,
assert(0);
}
- memcpy(ostart + flSize, src, srcSize);
+ ZSTD_memcpy(ostart + flSize, src, srcSize);
DEBUGLOG(5, "Raw literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize));
return srcSize + flSize;
}
@@ -86,7 +86,7 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
disableLiteralCompression, (U32)srcSize);
/* Prepare nextEntropy assuming reusing the existing table */
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
if (disableLiteralCompression)
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
@@ -118,11 +118,11 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
}
if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
}
if (cLitSize==1) {
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
}
diff --git a/thirdparty/zstd/compress/zstd_compress_sequences.c b/thirdparty/zstd/compress/zstd_compress_sequences.c
index f9f8097c83..be30c08c6b 100644
--- a/thirdparty/zstd/compress/zstd_compress_sequences.c
+++ b/thirdparty/zstd/compress/zstd_compress_sequences.c
@@ -51,6 +51,19 @@ static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
}
/**
+ * Returns true if we should use ncount=-1 else we should
+ * use ncount=1 for low probability symbols instead.
+ */
+static unsigned ZSTD_useLowProbCount(size_t const nbSeq)
+{
+ /* Heuristic: This should cover most blocks <= 16K and
+ * start to fade out after 16K to about 32K depending on
+ * comprssibility.
+ */
+ return nbSeq >= 2048;
+}
+
+/**
* Returns the cost in bytes of encoding the normalized count header.
* Returns an error if any of the helper functions return an error.
*/
@@ -60,7 +73,7 @@ static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
BYTE wksp[FSE_NCOUNTBOUND];
S16 norm[MaxSeq + 1];
const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
- FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max), "");
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), "");
return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
}
@@ -239,7 +252,7 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
*op = codeTable[0];
return 1;
case set_repeat:
- memcpy(nextCTable, prevCTable, prevCTableSize);
+ ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize);
return 0;
case set_basic:
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
@@ -253,7 +266,8 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
nbSeq_1--;
}
assert(nbSeq_1 > 1);
- FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max), "");
+ assert(entropyWorkspaceSize >= FSE_BUILD_CTABLE_WORKSPACE_SIZE(MaxSeq, MaxFSELog));
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
diff --git a/thirdparty/zstd/compress/zstd_compress_superblock.c b/thirdparty/zstd/compress/zstd_compress_superblock.c
index b693866c0a..e23e619eef 100644
--- a/thirdparty/zstd/compress/zstd_compress_superblock.c
+++ b/thirdparty/zstd/compress/zstd_compress_superblock.c
@@ -29,7 +29,7 @@
* This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */
typedef struct {
symbolEncodingType_e hType;
- BYTE hufDesBuffer[500]; /* TODO give name to this value */
+ BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
size_t hufDesSize;
} ZSTD_hufCTablesMetadata_t;
@@ -42,7 +42,7 @@ typedef struct {
symbolEncodingType_e llType;
symbolEncodingType_e ofType;
symbolEncodingType_e mlType;
- BYTE fseTablesBuffer[500]; /* TODO give name to this value */
+ BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
size_t fseTablesSize;
size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */
} ZSTD_fseCTablesMetadata_t;
@@ -79,7 +79,7 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize);
/* Prepare nextEntropy assuming reusing the existing table */
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
if (disableLiteralsCompression) {
DEBUGLOG(5, "set_basic - disabled");
@@ -118,7 +118,7 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
}
/* Build Huffman Tree */
- memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
+ ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
{ size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
maxSymbolValue, huffLog,
@@ -137,14 +137,14 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
(HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
DEBUGLOG(5, "set_repeat - smaller");
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
hufMetadata->hType = set_repeat;
return 0;
}
}
if (newCSize + hSize >= srcSize) {
DEBUGLOG(5, "set_basic - no gains");
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
hufMetadata->hType = set_basic;
return 0;
}
@@ -188,7 +188,7 @@ static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr,
assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE));
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq);
- memset(workspace, 0, wkspSize);
+ ZSTD_memset(workspace, 0, wkspSize);
fseMetadata->lastCountSize = 0;
/* convert length/distances into codes */
@@ -348,7 +348,7 @@ static size_t ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable,
assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat);
if (writeEntropy && hufMetadata->hType == set_compressed) {
- memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize);
+ ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize);
op += hufMetadata->hufDesSize;
cLitSize += hufMetadata->hufDesSize;
DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize);
@@ -474,7 +474,7 @@ static size_t ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables
const U32 MLtype = fseMetadata->mlType;
DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize);
*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
- memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize);
+ ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize);
op += fseMetadata->fseTablesSize;
} else {
const U32 repeat = set_repeat;
@@ -603,7 +603,7 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
const BYTE* codeTable, unsigned maxCode,
size_t nbSeq, const FSE_CTable* fseCTable,
const U32* additionalBits,
- short const* defaultNorm, U32 defaultNormLog,
+ short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
void* workspace, size_t wkspSize)
{
unsigned* const countWksp = (unsigned*)workspace;
@@ -615,7 +615,11 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */
if (type == set_basic) {
- cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max);
+ /* We selected this encoding type, so it must be valid. */
+ assert(max <= defaultMax);
+ cSymbolTypeSizeEstimateInBits = max <= defaultMax
+ ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max)
+ : ERROR(GENERIC);
} else if (type == set_rle) {
cSymbolTypeSizeEstimateInBits = 0;
} else if (type == set_compressed || type == set_repeat) {
@@ -643,15 +647,15 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
size_t cSeqSizeEstimate = 0;
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
nbSeq, fseTables->offcodeCTable, NULL,
- OF_defaultNorm, OF_defaultNormLog,
+ OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
workspace, wkspSize);
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL,
nbSeq, fseTables->litlengthCTable, LL_bits,
- LL_defaultNorm, LL_defaultNormLog,
+ LL_defaultNorm, LL_defaultNormLog, MaxLL,
workspace, wkspSize);
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML,
nbSeq, fseTables->matchlengthCTable, ML_bits,
- ML_defaultNorm, ML_defaultNormLog,
+ ML_defaultNorm, ML_defaultNormLog, MaxML,
workspace, wkspSize);
if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
return cSeqSizeEstimate + sequencesSectionHeaderSize;
@@ -790,7 +794,7 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
} while (!lastSequence);
if (writeLitEntropy) {
DEBUGLOG(5, "ZSTD_compressSubBlock_multi has literal entropy tables unwritten");
- memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf));
+ ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf));
}
if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) {
/* If we haven't written our entropy tables, then we've violated our contract and
@@ -809,11 +813,11 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
if (sp < send) {
seqDef const* seq;
repcodes_t rep;
- memcpy(&rep, prevCBlock->rep, sizeof(rep));
+ ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep));
for (seq = sstart; seq < sp; ++seq) {
rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0);
}
- memcpy(nextCBlock->rep, &rep, sizeof(rep));
+ ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep));
}
}
DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed");
@@ -831,7 +835,7 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
&zc->blockState.nextCBlock->entropy,
&zc->appliedParams,
&entropyMetadata,
- zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
+ zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
return ZSTD_compressSubBlock_multi(&zc->seqStore,
zc->blockState.prevCBlock,
@@ -841,5 +845,5 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
dst, dstCapacity,
src, srcSize,
zc->bmi2, lastBlock,
- zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */);
+ zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */);
}
diff --git a/thirdparty/zstd/compress/zstd_cwksp.h b/thirdparty/zstd/compress/zstd_cwksp.h
index a25c9263b7..d65170b39c 100644
--- a/thirdparty/zstd/compress/zstd_cwksp.h
+++ b/thirdparty/zstd/compress/zstd_cwksp.h
@@ -45,6 +45,16 @@ typedef enum {
} ZSTD_cwksp_alloc_phase_e;
/**
+ * Used to describe whether the workspace is statically allocated (and will not
+ * necessarily ever be freed), or if it's dynamically allocated and we can
+ * expect a well-formed caller to free this.
+ */
+typedef enum {
+ ZSTD_cwksp_dynamic_alloc,
+ ZSTD_cwksp_static_alloc
+} ZSTD_cwksp_static_alloc_e;
+
+/**
* Zstd fits all its internal datastructures into a single continuous buffer,
* so that it only needs to perform a single OS allocation (or so that a buffer
* can be provided to it and it can perform no allocations at all). This buffer
@@ -92,7 +102,7 @@ typedef enum {
*
* - Static objects: this is optionally the enclosing ZSTD_CCtx or ZSTD_CDict,
* so that literally everything fits in a single buffer. Note: if present,
- * this must be the first object in the workspace, since ZSTD_free{CCtx,
+ * this must be the first object in the workspace, since ZSTD_customFree{CCtx,
* CDict}() rely on a pointer comparison to see whether one or two frees are
* required.
*
@@ -137,9 +147,10 @@ typedef struct {
void* tableValidEnd;
void* allocStart;
- int allocFailed;
+ BYTE allocFailed;
int workspaceOversizedDuration;
ZSTD_cwksp_alloc_phase_e phase;
+ ZSTD_cwksp_static_alloc_e isStatic;
} ZSTD_cwksp;
/*-*************************************
@@ -178,7 +189,9 @@ MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t const align) {
* else is though.
*/
MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) {
-#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
+ if (size == 0)
+ return 0;
+#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
#else
return size;
@@ -228,7 +241,10 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal(
ZSTD_cwksp_internal_advance_phase(ws, phase);
alloc = (BYTE *)ws->allocStart - bytes;
-#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
+ if (bytes == 0)
+ return NULL;
+
+#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
/* over-reserve space */
alloc = (BYTE *)alloc - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
#endif
@@ -247,11 +263,13 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal(
}
ws->allocStart = alloc;
-#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
+#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
/* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
* either size. */
alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
- __asan_unpoison_memory_region(alloc, bytes);
+ if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
+ __asan_unpoison_memory_region(alloc, bytes);
+ }
#endif
return alloc;
@@ -296,8 +314,10 @@ MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) {
}
ws->tableEnd = end;
-#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
- __asan_unpoison_memory_region(alloc, bytes);
+#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
+ if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
+ __asan_unpoison_memory_region(alloc, bytes);
+ }
#endif
return alloc;
@@ -311,7 +331,7 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
void* alloc = ws->objectEnd;
void* end = (BYTE*)alloc + roundedBytes;
-#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
+#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
/* over-reserve space */
end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
#endif
@@ -332,11 +352,13 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
ws->tableEnd = end;
ws->tableValidEnd = end;
-#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
+#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
/* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
* either size. */
alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
- __asan_unpoison_memory_region(alloc, bytes);
+ if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
+ __asan_unpoison_memory_region(alloc, bytes);
+ }
#endif
return alloc;
@@ -345,7 +367,7 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) {
DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty");
-#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
+#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
/* To validate that the table re-use logic is sound, and that we don't
* access table space that we haven't cleaned, we re-"poison" the table
* space every time we mark it dirty. */
@@ -380,7 +402,7 @@ MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) {
assert(ws->tableValidEnd >= ws->objectEnd);
assert(ws->tableValidEnd <= ws->allocStart);
if (ws->tableValidEnd < ws->tableEnd) {
- memset(ws->tableValidEnd, 0, (BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd);
+ ZSTD_memset(ws->tableValidEnd, 0, (BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd);
}
ZSTD_cwksp_mark_tables_clean(ws);
}
@@ -392,8 +414,12 @@ MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) {
MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) {
DEBUGLOG(4, "cwksp: clearing tables!");
-#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
- {
+#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
+ /* We don't do this when the workspace is statically allocated, because
+ * when that is the case, we have no capability to hook into the end of the
+ * workspace's lifecycle to unpoison the memory.
+ */
+ if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd;
__asan_poison_memory_region(ws->objectEnd, size);
}
@@ -410,7 +436,7 @@ MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) {
MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) {
DEBUGLOG(4, "cwksp: clearing!");
-#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
+#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
/* To validate that the context re-use logic is sound, and that we don't
* access stuff that this compression hasn't initialized, we re-"poison"
* the workspace (or at least the non-static, non-table parts of it)
@@ -421,8 +447,12 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) {
}
#endif
-#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
- {
+#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
+ /* We don't do this when the workspace is statically allocated, because
+ * when that is the case, we have no capability to hook into the end of the
+ * workspace's lifecycle to unpoison the memory.
+ */
+ if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd;
__asan_poison_memory_region(ws->objectEnd, size);
}
@@ -442,7 +472,7 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) {
* Any existing values in the workspace are ignored (the previously managed
* buffer, if present, must be separately freed).
*/
-MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) {
+MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size, ZSTD_cwksp_static_alloc_e isStatic) {
DEBUGLOG(4, "cwksp: init'ing workspace with %zd bytes", size);
assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */
ws->workspace = start;
@@ -450,24 +480,25 @@ MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) {
ws->objectEnd = ws->workspace;
ws->tableValidEnd = ws->objectEnd;
ws->phase = ZSTD_cwksp_alloc_objects;
+ ws->isStatic = isStatic;
ZSTD_cwksp_clear(ws);
ws->workspaceOversizedDuration = 0;
ZSTD_cwksp_assert_internal_consistency(ws);
}
MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) {
- void* workspace = ZSTD_malloc(size, customMem);
+ void* workspace = ZSTD_customMalloc(size, customMem);
DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size);
RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!");
- ZSTD_cwksp_init(ws, workspace, size);
+ ZSTD_cwksp_init(ws, workspace, size, ZSTD_cwksp_dynamic_alloc);
return 0;
}
MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) {
void *ptr = ws->workspace;
DEBUGLOG(4, "cwksp: freeing workspace");
- memset(ws, 0, sizeof(ZSTD_cwksp));
- ZSTD_free(ptr, customMem);
+ ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp));
+ ZSTD_customFree(ptr, customMem);
}
/**
@@ -476,13 +507,18 @@ MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) {
*/
MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) {
*dst = *src;
- memset(src, 0, sizeof(ZSTD_cwksp));
+ ZSTD_memset(src, 0, sizeof(ZSTD_cwksp));
}
MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) {
return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace);
}
+MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) {
+ return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace)
+ + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart);
+}
+
MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) {
return ws->allocFailed;
}
diff --git a/thirdparty/zstd/compress/zstd_double_fast.c b/thirdparty/zstd/compress/zstd_double_fast.c
index 27eed66cfe..ef12a524f7 100644
--- a/thirdparty/zstd/compress/zstd_double_fast.c
+++ b/thirdparty/zstd/compress/zstd_double_fast.c
@@ -31,15 +31,15 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,
* is empty.
*/
for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) {
- U32 const current = (U32)(ip - base);
+ U32 const curr = (U32)(ip - base);
U32 i;
for (i = 0; i < fastHashFillStep; ++i) {
size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls);
size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8);
if (i == 0)
- hashSmall[smHash] = current + i;
+ hashSmall[smHash] = curr + i;
if (i == 0 || hashLarge[lgHash] == 0)
- hashLarge[lgHash] = current + i;
+ hashLarge[lgHash] = curr + i;
/* Only load extra positions for ZSTD_dtlm_full */
if (dtlm == ZSTD_dtlm_fast)
break;
@@ -108,9 +108,9 @@ size_t ZSTD_compressBlock_doubleFast_generic(
/* init */
ip += (dictAndPrefixLength == 0);
if (dictMode == ZSTD_noDict) {
- U32 const current = (U32)(ip - base);
- U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog);
- U32 const maxRep = current - windowLow;
+ U32 const curr = (U32)(ip - base);
+ U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog);
+ U32 const maxRep = curr - windowLow;
if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
}
@@ -129,17 +129,17 @@ size_t ZSTD_compressBlock_doubleFast_generic(
size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
size_t const dictHL = ZSTD_hashPtr(ip, dictHBitsL, 8);
size_t const dictHS = ZSTD_hashPtr(ip, dictHBitsS, mls);
- U32 const current = (U32)(ip-base);
+ U32 const curr = (U32)(ip-base);
U32 const matchIndexL = hashLong[h2];
U32 matchIndexS = hashSmall[h];
const BYTE* matchLong = base + matchIndexL;
const BYTE* match = base + matchIndexS;
- const U32 repIndex = current + 1 - offset_1;
+ const U32 repIndex = curr + 1 - offset_1;
const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
&& repIndex < prefixLowestIndex) ?
dictBase + (repIndex - dictIndexDelta) :
base + repIndex;
- hashLong[h2] = hashSmall[h] = current; /* update hash tables */
+ hashLong[h2] = hashSmall[h] = curr; /* update hash tables */
/* check dictMatchState repcode */
if (dictMode == ZSTD_dictMatchState
@@ -177,7 +177,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) {
mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8;
- offset = (U32)(current - dictMatchIndexL - dictIndexDelta);
+ offset = (U32)(curr - dictMatchIndexL - dictIndexDelta);
while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */
goto _match_found;
} }
@@ -209,7 +209,7 @@ _search_next_long:
size_t const dictHLNext = ZSTD_hashPtr(ip+1, dictHBitsL, 8);
U32 const matchIndexL3 = hashLong[hl3];
const BYTE* matchL3 = base + matchIndexL3;
- hashLong[hl3] = current + 1;
+ hashLong[hl3] = curr + 1;
/* check prefix long +1 match */
if (matchIndexL3 > prefixLowestIndex) {
@@ -228,7 +228,7 @@ _search_next_long:
if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) {
mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8;
ip++;
- offset = (U32)(current + 1 - dictMatchIndexL3 - dictIndexDelta);
+ offset = (U32)(curr + 1 - dictMatchIndexL3 - dictIndexDelta);
while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */
goto _match_found;
} } }
@@ -236,7 +236,7 @@ _search_next_long:
/* if no long +1 match, explore the short match we found */
if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) {
mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4;
- offset = (U32)(current - matchIndexS);
+ offset = (U32)(curr - matchIndexS);
while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
} else {
mLength = ZSTD_count(ip+4, match+4, iend) + 4;
@@ -260,7 +260,7 @@ _match_stored:
if (ip <= ilimit) {
/* Complementary insertion */
/* done after iLimit test, as candidates could be > iend-8 */
- { U32 const indexToInsert = current+2;
+ { U32 const indexToInsert = curr+2;
hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
@@ -401,12 +401,12 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base;
const BYTE* matchLong = matchLongBase + matchLongIndex;
- const U32 current = (U32)(ip-base);
- const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
+ const U32 curr = (U32)(ip-base);
+ const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */
const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
size_t mLength;
- hashSmall[hSmall] = hashLong[hLong] = current; /* update hash table */
+ hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */
if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */
& (repIndex > dictStartIndex))
@@ -421,7 +421,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart;
U32 offset;
mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8;
- offset = current - matchLongIndex;
+ offset = curr - matchLongIndex;
while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
offset_2 = offset_1;
offset_1 = offset;
@@ -433,19 +433,19 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base;
const BYTE* match3 = match3Base + matchIndex3;
U32 offset;
- hashLong[h3] = current + 1;
+ hashLong[h3] = curr + 1;
if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend;
const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart;
mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8;
ip++;
- offset = current+1 - matchIndex3;
+ offset = curr+1 - matchIndex3;
while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
} else {
const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
- offset = current - matchIndex;
+ offset = curr - matchIndex;
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
}
offset_2 = offset_1;
@@ -464,7 +464,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
if (ip <= ilimit) {
/* Complementary insertion */
/* done after iLimit test, as candidates could be > iend-8 */
- { U32 const indexToInsert = current+2;
+ { U32 const indexToInsert = curr+2;
hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
diff --git a/thirdparty/zstd/compress/zstd_fast.c b/thirdparty/zstd/compress/zstd_fast.c
index 85a3a7a91e..db7ce83d0a 100644
--- a/thirdparty/zstd/compress/zstd_fast.c
+++ b/thirdparty/zstd/compress/zstd_fast.c
@@ -29,16 +29,16 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
* Insert the other positions if their hash entry is empty.
*/
for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) {
- U32 const current = (U32)(ip - base);
+ U32 const curr = (U32)(ip - base);
size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls);
- hashTable[hash0] = current;
+ hashTable[hash0] = curr;
if (dtlm == ZSTD_dtlm_fast) continue;
/* Only load extra positions for ZSTD_dtlm_full */
{ U32 p;
for (p = 1; p < fastHashFillStep; ++p) {
size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls);
if (hashTable[hash] == 0) { /* not yet filled */
- hashTable[hash] = current + p;
+ hashTable[hash] = curr + p;
} } } }
}
@@ -72,9 +72,9 @@ ZSTD_compressBlock_fast_generic(
DEBUGLOG(5, "ZSTD_compressBlock_fast_generic");
ip0 += (ip0 == prefixStart);
ip1 = ip0 + 1;
- { U32 const current = (U32)(ip0 - base);
- U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog);
- U32 const maxRep = current - windowLow;
+ { U32 const curr = (U32)(ip0 - base);
+ U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog);
+ U32 const maxRep = curr - windowLow;
if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
}
@@ -258,14 +258,14 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
size_t mLength;
size_t const h = ZSTD_hashPtr(ip, hlog, mls);
- U32 const current = (U32)(ip-base);
+ U32 const curr = (U32)(ip-base);
U32 const matchIndex = hashTable[h];
const BYTE* match = base + matchIndex;
- const U32 repIndex = current + 1 - offset_1;
+ const U32 repIndex = curr + 1 - offset_1;
const BYTE* repMatch = (repIndex < prefixStartIndex) ?
dictBase + (repIndex - dictIndexDelta) :
base + repIndex;
- hashTable[h] = current; /* update hash table */
+ hashTable[h] = curr; /* update hash table */
if ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex isn't overlapping dict + prefix */
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
@@ -284,7 +284,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
continue;
} else {
/* found a dict match */
- U32 const offset = (U32)(current-dictMatchIndex-dictIndexDelta);
+ U32 const offset = (U32)(curr-dictMatchIndex-dictIndexDelta);
mLength = ZSTD_count_2segments(ip+4, dictMatch+4, iend, dictEnd, prefixStart) + 4;
while (((ip>anchor) & (dictMatch>dictStart))
&& (ip[-1] == dictMatch[-1])) {
@@ -316,8 +316,8 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
if (ip <= ilimit) {
/* Fill Table */
- assert(base+current+2 > istart); /* check base overflow */
- hashTable[ZSTD_hashPtr(base+current+2, hlog, mls)] = current+2; /* here because current+2 could be > iend-8 */
+ assert(base+curr+2 > istart); /* check base overflow */
+ hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; /* here because curr+2 could be > iend-8 */
hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base);
/* check immediate repcode */
@@ -410,13 +410,13 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const U32 matchIndex = hashTable[h];
const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base;
const BYTE* match = matchBase + matchIndex;
- const U32 current = (U32)(ip-base);
- const U32 repIndex = current + 1 - offset_1;
+ const U32 curr = (U32)(ip-base);
+ const U32 repIndex = curr + 1 - offset_1;
const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
- hashTable[h] = current; /* update hash table */
- DEBUGLOG(7, "offset_1 = %u , current = %u", offset_1, current);
- assert(offset_1 <= current +1); /* check repIndex */
+ hashTable[h] = curr; /* update hash table */
+ DEBUGLOG(7, "offset_1 = %u , curr = %u", offset_1, curr);
+ assert(offset_1 <= curr +1); /* check repIndex */
if ( (((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > dictStartIndex))
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
@@ -435,7 +435,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
}
{ const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
- U32 const offset = current - matchIndex;
+ U32 const offset = curr - matchIndex;
size_t mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
offset_2 = offset_1; offset_1 = offset; /* update offset history */
@@ -446,7 +446,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
if (ip <= ilimit) {
/* Fill Table */
- hashTable[ZSTD_hashPtr(base+current+2, hlog, mls)] = current+2;
+ hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2;
hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base);
/* check immediate repcode */
while (ip <= ilimit) {
diff --git a/thirdparty/zstd/compress/zstd_lazy.c b/thirdparty/zstd/compress/zstd_lazy.c
index 4cf5c88b53..49ec1b09ef 100644
--- a/thirdparty/zstd/compress/zstd_lazy.c
+++ b/thirdparty/zstd/compress/zstd_lazy.c
@@ -58,11 +58,11 @@ ZSTD_updateDUBT(ZSTD_matchState_t* ms,
/** ZSTD_insertDUBT1() :
* sort one already inserted but unsorted position
- * assumption : current >= btlow == (current - btmask)
+ * assumption : curr >= btlow == (curr - btmask)
* doesn't fail */
static void
ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
- U32 current, const BYTE* inputEnd,
+ U32 curr, const BYTE* inputEnd,
U32 nbCompares, U32 btLow,
const ZSTD_dictMode_e dictMode)
{
@@ -74,41 +74,41 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
const BYTE* const base = ms->window.base;
const BYTE* const dictBase = ms->window.dictBase;
const U32 dictLimit = ms->window.dictLimit;
- const BYTE* const ip = (current>=dictLimit) ? base + current : dictBase + current;
- const BYTE* const iend = (current>=dictLimit) ? inputEnd : dictBase + dictLimit;
+ const BYTE* const ip = (curr>=dictLimit) ? base + curr : dictBase + curr;
+ const BYTE* const iend = (curr>=dictLimit) ? inputEnd : dictBase + dictLimit;
const BYTE* const dictEnd = dictBase + dictLimit;
const BYTE* const prefixStart = base + dictLimit;
const BYTE* match;
- U32* smallerPtr = bt + 2*(current&btMask);
+ U32* smallerPtr = bt + 2*(curr&btMask);
U32* largerPtr = smallerPtr + 1;
U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */
U32 dummy32; /* to be nullified at the end */
U32 const windowValid = ms->window.lowLimit;
U32 const maxDistance = 1U << cParams->windowLog;
- U32 const windowLow = (current - windowValid > maxDistance) ? current - maxDistance : windowValid;
+ U32 const windowLow = (curr - windowValid > maxDistance) ? curr - maxDistance : windowValid;
DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)",
- current, dictLimit, windowLow);
- assert(current >= btLow);
+ curr, dictLimit, windowLow);
+ assert(curr >= btLow);
assert(ip < iend); /* condition for ZSTD_count */
while (nbCompares-- && (matchIndex > windowLow)) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
- assert(matchIndex < current);
+ assert(matchIndex < curr);
/* note : all candidates are now supposed sorted,
* but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK
* when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */
if ( (dictMode != ZSTD_extDict)
|| (matchIndex+matchLength >= dictLimit) /* both in current segment*/
- || (current < dictLimit) /* both in extDict */) {
+ || (curr < dictLimit) /* both in extDict */) {
const BYTE* const mBase = ( (dictMode != ZSTD_extDict)
|| (matchIndex+matchLength >= dictLimit)) ?
base : dictBase;
assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */
- || (current < dictLimit) );
+ || (curr < dictLimit) );
match = mBase + matchIndex;
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
} else {
@@ -119,7 +119,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
}
DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ",
- current, matchIndex, (U32)matchLength);
+ curr, matchIndex, (U32)matchLength);
if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */
@@ -168,7 +168,7 @@ ZSTD_DUBT_findBetterDictMatch (
const BYTE* const base = ms->window.base;
const BYTE* const prefixStart = base + ms->window.dictLimit;
- U32 const current = (U32)(ip-base);
+ U32 const curr = (U32)(ip-base);
const BYTE* const dictBase = dms->window.base;
const BYTE* const dictEnd = dms->window.nextSrc;
U32 const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base);
@@ -195,10 +195,10 @@ ZSTD_DUBT_findBetterDictMatch (
if (matchLength > bestLength) {
U32 matchIndex = dictMatchIndex + dictIndexDelta;
- if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) {
+ if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) {
DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)",
- current, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + current - matchIndex, dictMatchIndex, matchIndex);
- bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
+ curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + curr - matchIndex, dictMatchIndex, matchIndex);
+ bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
}
if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */
break; /* drop, to guarantee consistency (miss a little bit of compression) */
@@ -218,9 +218,9 @@ ZSTD_DUBT_findBetterDictMatch (
}
if (bestLength >= MINMATCH) {
- U32 const mIndex = current - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
+ U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
- current, (U32)bestLength, (U32)*offsetPtr, mIndex);
+ curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
}
return bestLength;
@@ -241,13 +241,13 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
U32 matchIndex = hashTable[h];
const BYTE* const base = ms->window.base;
- U32 const current = (U32)(ip-base);
- U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog);
+ U32 const curr = (U32)(ip-base);
+ U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
U32* const bt = ms->chainTable;
U32 const btLog = cParams->chainLog - 1;
U32 const btMask = (1 << btLog) - 1;
- U32 const btLow = (btMask >= current) ? 0 : current - btMask;
+ U32 const btLow = (btMask >= curr) ? 0 : curr - btMask;
U32 const unsortLimit = MAX(btLow, windowLow);
U32* nextCandidate = bt + 2*(matchIndex&btMask);
@@ -256,8 +256,9 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
U32 nbCandidates = nbCompares;
U32 previousCandidate = 0;
- DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", current);
+ DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", curr);
assert(ip <= iend-8); /* required for h calculation */
+ assert(dictMode != ZSTD_dedicatedDictSearch);
/* reach end of unsorted candidates list */
while ( (matchIndex > unsortLimit)
@@ -299,14 +300,14 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
const U32 dictLimit = ms->window.dictLimit;
const BYTE* const dictEnd = dictBase + dictLimit;
const BYTE* const prefixStart = base + dictLimit;
- U32* smallerPtr = bt + 2*(current&btMask);
- U32* largerPtr = bt + 2*(current&btMask) + 1;
- U32 matchEndIdx = current + 8 + 1;
+ U32* smallerPtr = bt + 2*(curr&btMask);
+ U32* largerPtr = bt + 2*(curr&btMask) + 1;
+ U32 matchEndIdx = curr + 8 + 1;
U32 dummy32; /* to be nullified at the end */
size_t bestLength = 0;
matchIndex = hashTable[h];
- hashTable[h] = current; /* Update Hash Table */
+ hashTable[h] = curr; /* Update Hash Table */
while (nbCompares-- && (matchIndex > windowLow)) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
@@ -326,8 +327,8 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
if (matchLength > bestLength) {
if (matchLength > matchEndIdx - matchIndex)
matchEndIdx = matchIndex + (U32)matchLength;
- if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
- bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
+ if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
+ bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
if (dictMode == ZSTD_dictMatchState) {
nbCompares = 0; /* in addition to avoiding checking any
@@ -363,12 +364,12 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
mls, dictMode);
}
- assert(matchEndIdx > current+8); /* ensure nextToUpdate is increased */
+ assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */
ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
if (bestLength >= MINMATCH) {
- U32 const mIndex = current - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
+ U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
- current, (U32)bestLength, (U32)*offsetPtr, mIndex);
+ curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
}
return bestLength;
}
@@ -446,7 +447,7 @@ static size_t ZSTD_BtFindBestMatch_extDict_selectMLS (
/* Update chains up to ip (excluded)
Assumption : always within prefix (i.e. not within extDict) */
-static U32 ZSTD_insertAndFindFirstIndex_internal(
+FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal(
ZSTD_matchState_t* ms,
const ZSTD_compressionParameters* const cParams,
const BYTE* ip, U32 const mls)
@@ -475,6 +476,121 @@ U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) {
return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch);
}
+void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip)
+{
+ const BYTE* const base = ms->window.base;
+ U32 const target = (U32)(ip - base);
+ U32* const hashTable = ms->hashTable;
+ U32* const chainTable = ms->chainTable;
+ U32 const chainSize = 1 << ms->cParams.chainLog;
+ U32 idx = ms->nextToUpdate;
+ U32 const minChain = chainSize < target ? target - chainSize : idx;
+ U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG;
+ U32 const cacheSize = bucketSize - 1;
+ U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize;
+ U32 const chainLimit = chainAttempts > 255 ? 255 : chainAttempts;
+
+ /* We know the hashtable is oversized by a factor of `bucketSize`.
+ * We are going to temporarily pretend `bucketSize == 1`, keeping only a
+ * single entry. We will use the rest of the space to construct a temporary
+ * chaintable.
+ */
+ U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG;
+ U32* const tmpHashTable = hashTable;
+ U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog);
+ U32 const tmpChainSize = ((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog;
+ U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx;
+
+ U32 hashIdx;
+
+ assert(ms->cParams.chainLog <= 24);
+ assert(ms->cParams.hashLog >= ms->cParams.chainLog);
+ assert(idx != 0);
+ assert(tmpMinChain <= minChain);
+
+ /* fill conventional hash table and conventional chain table */
+ for ( ; idx < target; idx++) {
+ U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch);
+ if (idx >= tmpMinChain) {
+ tmpChainTable[idx - tmpMinChain] = hashTable[h];
+ }
+ tmpHashTable[h] = idx;
+ }
+
+ /* sort chains into ddss chain table */
+ {
+ U32 chainPos = 0;
+ for (hashIdx = 0; hashIdx < (1U << hashLog); hashIdx++) {
+ U32 count;
+ U32 countBeyondMinChain = 0;
+ U32 i = tmpHashTable[hashIdx];
+ for (count = 0; i >= tmpMinChain && count < cacheSize; count++) {
+ /* skip through the chain to the first position that won't be
+ * in the hash cache bucket */
+ if (i < minChain) {
+ countBeyondMinChain++;
+ }
+ i = tmpChainTable[i - tmpMinChain];
+ }
+ if (count == cacheSize) {
+ for (count = 0; count < chainLimit;) {
+ if (i < minChain) {
+ if (!i || countBeyondMinChain++ > cacheSize) {
+ /* only allow pulling `cacheSize` number of entries
+ * into the cache or chainTable beyond `minChain`,
+ * to replace the entries pulled out of the
+ * chainTable into the cache. This lets us reach
+ * back further without increasing the total number
+ * of entries in the chainTable, guaranteeing the
+ * DDSS chain table will fit into the space
+ * allocated for the regular one. */
+ break;
+ }
+ }
+ chainTable[chainPos++] = i;
+ count++;
+ if (i < tmpMinChain) {
+ break;
+ }
+ i = tmpChainTable[i - tmpMinChain];
+ }
+ } else {
+ count = 0;
+ }
+ if (count) {
+ tmpHashTable[hashIdx] = ((chainPos - count) << 8) + count;
+ } else {
+ tmpHashTable[hashIdx] = 0;
+ }
+ }
+ assert(chainPos <= chainSize); /* I believe this is guaranteed... */
+ }
+
+ /* move chain pointers into the last entry of each hash bucket */
+ for (hashIdx = (1 << hashLog); hashIdx; ) {
+ U32 const bucketIdx = --hashIdx << ZSTD_LAZY_DDSS_BUCKET_LOG;
+ U32 const chainPackedPointer = tmpHashTable[hashIdx];
+ U32 i;
+ for (i = 0; i < cacheSize; i++) {
+ hashTable[bucketIdx + i] = 0;
+ }
+ hashTable[bucketIdx + bucketSize - 1] = chainPackedPointer;
+ }
+
+ /* fill the buckets of the hash table */
+ for (idx = ms->nextToUpdate; idx < target; idx++) {
+ U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch)
+ << ZSTD_LAZY_DDSS_BUCKET_LOG;
+ U32 i;
+ /* Shift hash cache down 1. */
+ for (i = cacheSize - 1; i; i--)
+ hashTable[h + i] = hashTable[h + i - 1];
+ hashTable[h] = idx;
+ }
+
+ ms->nextToUpdate = target;
+}
+
/* inlining is important to hardwire a hot branch (template emulation) */
FORCE_INLINE_TEMPLATE
@@ -493,20 +609,33 @@ size_t ZSTD_HcFindBestMatch_generic (
const U32 dictLimit = ms->window.dictLimit;
const BYTE* const prefixStart = base + dictLimit;
const BYTE* const dictEnd = dictBase + dictLimit;
- const U32 current = (U32)(ip-base);
+ const U32 curr = (U32)(ip-base);
const U32 maxDistance = 1U << cParams->windowLog;
const U32 lowestValid = ms->window.lowLimit;
- const U32 withinMaxDistance = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
+ const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
const U32 isDictionary = (ms->loadedDictEnd != 0);
const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;
- const U32 minChain = current > chainSize ? current - chainSize : 0;
+ const U32 minChain = curr > chainSize ? curr - chainSize : 0;
U32 nbAttempts = 1U << cParams->searchLog;
size_t ml=4-1;
+ const ZSTD_matchState_t* const dms = ms->dictMatchState;
+ const U32 ddsHashLog = dictMode == ZSTD_dedicatedDictSearch
+ ? dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG : 0;
+ const size_t ddsIdx = dictMode == ZSTD_dedicatedDictSearch
+ ? ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG : 0;
+
+ U32 matchIndex;
+
+ if (dictMode == ZSTD_dedicatedDictSearch) {
+ const U32* entry = &dms->hashTable[ddsIdx];
+ PREFETCH_L1(entry);
+ }
+
/* HC4 match finder */
- U32 matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls);
+ matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls);
- for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
+ for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) {
size_t currentMl=0;
if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
const BYTE* const match = base + matchIndex;
@@ -523,7 +652,7 @@ size_t ZSTD_HcFindBestMatch_generic (
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
- *offsetPtr = current - matchIndex + ZSTD_REP_MOVE;
+ *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
@@ -531,8 +660,92 @@ size_t ZSTD_HcFindBestMatch_generic (
matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
}
- if (dictMode == ZSTD_dictMatchState) {
- const ZSTD_matchState_t* const dms = ms->dictMatchState;
+ if (dictMode == ZSTD_dedicatedDictSearch) {
+ const U32 ddsLowestIndex = dms->window.dictLimit;
+ const BYTE* const ddsBase = dms->window.base;
+ const BYTE* const ddsEnd = dms->window.nextSrc;
+ const U32 ddsSize = (U32)(ddsEnd - ddsBase);
+ const U32 ddsIndexDelta = dictLimit - ddsSize;
+ const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG);
+ const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1;
+ U32 ddsAttempt;
+
+ for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) {
+ PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]);
+ }
+
+ {
+ U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
+ U32 const chainIndex = chainPackedPointer >> 8;
+
+ PREFETCH_L1(&dms->chainTable[chainIndex]);
+ }
+
+ for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) {
+ size_t currentMl=0;
+ const BYTE* match;
+ matchIndex = dms->hashTable[ddsIdx + ddsAttempt];
+ match = ddsBase + matchIndex;
+
+ if (!matchIndex) {
+ return ml;
+ }
+
+ /* guaranteed by table construction */
+ (void)ddsLowestIndex;
+ assert(matchIndex >= ddsLowestIndex);
+ assert(match+4 <= ddsEnd);
+ if (MEM_read32(match) == MEM_read32(ip)) {
+ /* assumption : matchIndex <= dictLimit-4 (by table construction) */
+ currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
+ }
+
+ /* save best solution */
+ if (currentMl > ml) {
+ ml = currentMl;
+ *offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
+ if (ip+currentMl == iLimit) {
+ /* best possible, avoids read overflow on next attempt */
+ return ml;
+ }
+ }
+ }
+
+ {
+ U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
+ U32 chainIndex = chainPackedPointer >> 8;
+ U32 const chainLength = chainPackedPointer & 0xFF;
+ U32 const chainAttempts = nbAttempts - ddsAttempt;
+ U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts;
+ U32 chainAttempt;
+
+ for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) {
+ PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]);
+ }
+
+ for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) {
+ size_t currentMl=0;
+ const BYTE* match;
+ matchIndex = dms->chainTable[chainIndex];
+ match = ddsBase + matchIndex;
+
+ /* guaranteed by table construction */
+ assert(matchIndex >= ddsLowestIndex);
+ assert(match+4 <= ddsEnd);
+ if (MEM_read32(match) == MEM_read32(ip)) {
+ /* assumption : matchIndex <= dictLimit-4 (by table construction) */
+ currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
+ }
+
+ /* save best solution */
+ if (currentMl > ml) {
+ ml = currentMl;
+ *offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
+ if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
+ }
+ }
+ }
+ } else if (dictMode == ZSTD_dictMatchState) {
const U32* const dmsChainTable = dms->chainTable;
const U32 dmsChainSize = (1 << dms->cParams.chainLog);
const U32 dmsChainMask = dmsChainSize - 1;
@@ -545,7 +758,7 @@ size_t ZSTD_HcFindBestMatch_generic (
matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)];
- for ( ; (matchIndex>dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) {
+ for ( ; (matchIndex>=dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) {
size_t currentMl=0;
const BYTE* const match = dmsBase + matchIndex;
assert(match+4 <= dmsEnd);
@@ -555,11 +768,12 @@ size_t ZSTD_HcFindBestMatch_generic (
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
- *offsetPtr = current - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
+ *offsetPtr = curr - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
if (matchIndex <= dmsMinChain) break;
+
matchIndex = dmsChainTable[matchIndex & dmsChainMask];
}
}
@@ -600,6 +814,22 @@ static size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS (
}
+static size_t ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS (
+ ZSTD_matchState_t* ms,
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr)
+{
+ switch(ms->cParams.minMatch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dedicatedDictSearch);
+ case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dedicatedDictSearch);
+ case 7 :
+ case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dedicatedDictSearch);
+ }
+}
+
+
FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* const iLimit,
@@ -641,39 +871,62 @@ ZSTD_compressBlock_lazy_generic(
typedef size_t (*searchMax_f)(
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
- searchMax_f const searchMax = dictMode == ZSTD_dictMatchState ?
- (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS
- : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) :
- (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_selectMLS
- : ZSTD_HcFindBestMatch_selectMLS);
+
+ /**
+ * This table is indexed first by the four ZSTD_dictMode_e values, and then
+ * by the two searchMethod_e values. NULLs are placed for configurations
+ * that should never occur (extDict modes go to the other implementation
+ * below and there is no DDSS for binary tree search yet).
+ */
+ const searchMax_f searchFuncs[4][2] = {
+ {
+ ZSTD_HcFindBestMatch_selectMLS,
+ ZSTD_BtFindBestMatch_selectMLS
+ },
+ {
+ NULL,
+ NULL
+ },
+ {
+ ZSTD_HcFindBestMatch_dictMatchState_selectMLS,
+ ZSTD_BtFindBestMatch_dictMatchState_selectMLS
+ },
+ {
+ ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS,
+ NULL
+ }
+ };
+
+ searchMax_f const searchMax = searchFuncs[dictMode][searchMethod == search_binaryTree];
U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
+ const int isDMS = dictMode == ZSTD_dictMatchState;
+ const int isDDS = dictMode == ZSTD_dedicatedDictSearch;
+ const int isDxS = isDMS || isDDS;
const ZSTD_matchState_t* const dms = ms->dictMatchState;
- const U32 dictLowestIndex = dictMode == ZSTD_dictMatchState ?
- dms->window.dictLimit : 0;
- const BYTE* const dictBase = dictMode == ZSTD_dictMatchState ?
- dms->window.base : NULL;
- const BYTE* const dictLowest = dictMode == ZSTD_dictMatchState ?
- dictBase + dictLowestIndex : NULL;
- const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ?
- dms->window.nextSrc : NULL;
- const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ?
+ const U32 dictLowestIndex = isDxS ? dms->window.dictLimit : 0;
+ const BYTE* const dictBase = isDxS ? dms->window.base : NULL;
+ const BYTE* const dictLowest = isDxS ? dictBase + dictLowestIndex : NULL;
+ const BYTE* const dictEnd = isDxS ? dms->window.nextSrc : NULL;
+ const U32 dictIndexDelta = isDxS ?
prefixLowestIndex - (U32)(dictEnd - dictBase) :
0;
const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest));
+ assert(searchMax != NULL);
+
DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u)", (U32)dictMode);
/* init */
ip += (dictAndPrefixLength == 0);
if (dictMode == ZSTD_noDict) {
- U32 const current = (U32)(ip - base);
- U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, ms->cParams.windowLog);
- U32 const maxRep = current - windowLow;
+ U32 const curr = (U32)(ip - base);
+ U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, ms->cParams.windowLog);
+ U32 const maxRep = curr - windowLow;
if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
}
- if (dictMode == ZSTD_dictMatchState) {
+ if (isDxS) {
/* dictMatchState repCode checks don't currently handle repCode == 0
* disabling. */
assert(offset_1 <= dictAndPrefixLength);
@@ -693,9 +946,9 @@ ZSTD_compressBlock_lazy_generic(
const BYTE* start=ip+1;
/* check repCode */
- if (dictMode == ZSTD_dictMatchState) {
+ if (isDxS) {
const U32 repIndex = (U32)(ip - base) + 1 - offset_1;
- const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
+ const BYTE* repMatch = ((dictMode == ZSTD_dictMatchState || dictMode == ZSTD_dedicatedDictSearch)
&& repIndex < prefixLowestIndex) ?
dictBase + (repIndex - dictIndexDelta) :
base + repIndex;
@@ -736,7 +989,7 @@ ZSTD_compressBlock_lazy_generic(
if ((mlRep >= 4) && (gain2 > gain1))
matchLength = mlRep, offset = 0, start = ip;
}
- if (dictMode == ZSTD_dictMatchState) {
+ if (isDxS) {
const U32 repIndex = (U32)(ip - base) - offset_1;
const BYTE* repMatch = repIndex < prefixLowestIndex ?
dictBase + (repIndex - dictIndexDelta) :
@@ -771,7 +1024,7 @@ ZSTD_compressBlock_lazy_generic(
if ((mlRep >= 4) && (gain2 > gain1))
matchLength = mlRep, offset = 0, start = ip;
}
- if (dictMode == ZSTD_dictMatchState) {
+ if (isDxS) {
const U32 repIndex = (U32)(ip - base) - offset_1;
const BYTE* repMatch = repIndex < prefixLowestIndex ?
dictBase + (repIndex - dictIndexDelta) :
@@ -809,7 +1062,7 @@ ZSTD_compressBlock_lazy_generic(
&& (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */
{ start--; matchLength++; }
}
- if (dictMode == ZSTD_dictMatchState) {
+ if (isDxS) {
U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex;
const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest;
@@ -825,12 +1078,11 @@ _storeSequence:
}
/* check immediate repcode */
- if (dictMode == ZSTD_dictMatchState) {
+ if (isDxS) {
while (ip <= ilimit) {
U32 const current2 = (U32)(ip-base);
U32 const repIndex = current2 - offset_2;
- const BYTE* repMatch = dictMode == ZSTD_dictMatchState
- && repIndex < prefixLowestIndex ?
+ const BYTE* repMatch = repIndex < prefixLowestIndex ?
dictBase - dictIndexDelta + repIndex :
base + repIndex;
if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex) >= 3 /* intentional overflow */)
@@ -925,6 +1177,28 @@ size_t ZSTD_compressBlock_greedy_dictMatchState(
}
+size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ void const* src, size_t srcSize)
+{
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch);
+}
+
+size_t ZSTD_compressBlock_lazy_dedicatedDictSearch(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ void const* src, size_t srcSize)
+{
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch);
+}
+
+size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ void const* src, size_t srcSize)
+{
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch);
+}
+
+
FORCE_INLINE_TEMPLATE
size_t ZSTD_compressBlock_lazy_extDict_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore,
@@ -968,11 +1242,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
size_t matchLength=0;
size_t offset=0;
const BYTE* start=ip+1;
- U32 current = (U32)(ip-base);
+ U32 curr = (U32)(ip-base);
/* check repCode */
- { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current+1, windowLog);
- const U32 repIndex = (U32)(current+1 - offset_1);
+ { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr+1, windowLog);
+ const U32 repIndex = (U32)(curr+1 - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
@@ -999,11 +1273,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
if (depth>=1)
while (ip<ilimit) {
ip ++;
- current++;
+ curr++;
/* check repCode */
if (offset) {
- const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current, windowLog);
- const U32 repIndex = (U32)(current - offset_1);
+ const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
+ const U32 repIndex = (U32)(curr - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
@@ -1030,11 +1304,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
/* let's find an even better one */
if ((depth==2) && (ip<ilimit)) {
ip ++;
- current++;
+ curr++;
/* check repCode */
if (offset) {
- const U32 windowLow = ZSTD_getLowestMatchIndex(ms, current, windowLog);
- const U32 repIndex = (U32)(current - offset_1);
+ const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
+ const U32 repIndex = (U32)(curr - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex;
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
diff --git a/thirdparty/zstd/compress/zstd_lazy.h b/thirdparty/zstd/compress/zstd_lazy.h
index 581936f03b..d0214d5e73 100644
--- a/thirdparty/zstd/compress/zstd_lazy.h
+++ b/thirdparty/zstd/compress/zstd_lazy.h
@@ -17,8 +17,18 @@ extern "C" {
#include "zstd_compress_internal.h"
+/**
+ * Dedicated Dictionary Search Structure bucket log. In the
+ * ZSTD_dedicatedDictSearch mode, the hashTable has
+ * 2 ** ZSTD_LAZY_DDSS_BUCKET_LOG entries in each bucket, rather than just
+ * one.
+ */
+#define ZSTD_LAZY_DDSS_BUCKET_LOG 2
+
U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip);
+void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip);
+
void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue); /*! used in ZSTD_reduceIndex(). preemptively increase value of ZSTD_DUBT_UNSORTED_MARK */
size_t ZSTD_compressBlock_btlazy2(
@@ -47,6 +57,16 @@ size_t ZSTD_compressBlock_greedy_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
+size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ void const* src, size_t srcSize);
+size_t ZSTD_compressBlock_lazy_dedicatedDictSearch(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ void const* src, size_t srcSize);
+size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
+ void const* src, size_t srcSize);
+
size_t ZSTD_compressBlock_greedy_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
diff --git a/thirdparty/zstd/compress/zstd_ldm.c b/thirdparty/zstd/compress/zstd_ldm.c
index 8c47948358..3f3d7c46ab 100644
--- a/thirdparty/zstd/compress/zstd_ldm.c
+++ b/thirdparty/zstd/compress/zstd_ldm.c
@@ -27,13 +27,6 @@ void ZSTD_ldm_adjustParameters(ldmParams_t* params,
DEBUGLOG(4, "ZSTD_ldm_adjustParameters");
if (!params->bucketSizeLog) params->bucketSizeLog = LDM_BUCKET_SIZE_LOG;
if (!params->minMatchLength) params->minMatchLength = LDM_MIN_MATCH_LENGTH;
- if (cParams->strategy >= ZSTD_btopt) {
- /* Get out of the way of the optimal parser */
- U32 const minMatch = MAX(cParams->targetLength, params->minMatchLength);
- assert(minMatch >= ZSTD_LDM_MINMATCH_MIN);
- assert(minMatch <= ZSTD_LDM_MINMATCH_MAX);
- params->minMatchLength = minMatch;
- }
if (params->hashLog == 0) {
params->hashLog = MAX(ZSTD_HASHLOG_MIN, params->windowLog - LDM_HASH_RLOG);
assert(params->hashLog <= ZSTD_HASHLOG_MAX);
@@ -150,10 +143,10 @@ static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState,
* We count only bytes where pMatch >= pBase and pIn >= pAnchor. */
static size_t ZSTD_ldm_countBackwardsMatch(
const BYTE* pIn, const BYTE* pAnchor,
- const BYTE* pMatch, const BYTE* pBase)
+ const BYTE* pMatch, const BYTE* pMatchBase)
{
size_t matchLength = 0;
- while (pIn > pAnchor && pMatch > pBase && pIn[-1] == pMatch[-1]) {
+ while (pIn > pAnchor && pMatch > pMatchBase && pIn[-1] == pMatch[-1]) {
pIn--;
pMatch--;
matchLength++;
@@ -161,6 +154,27 @@ static size_t ZSTD_ldm_countBackwardsMatch(
return matchLength;
}
+/** ZSTD_ldm_countBackwardsMatch_2segments() :
+ * Returns the number of bytes that match backwards from pMatch,
+ * even with the backwards match spanning 2 different segments.
+ *
+ * On reaching `pMatchBase`, start counting from mEnd */
+static size_t ZSTD_ldm_countBackwardsMatch_2segments(
+ const BYTE* pIn, const BYTE* pAnchor,
+ const BYTE* pMatch, const BYTE* pMatchBase,
+ const BYTE* pExtDictStart, const BYTE* pExtDictEnd)
+{
+ size_t matchLength = ZSTD_ldm_countBackwardsMatch(pIn, pAnchor, pMatch, pMatchBase);
+ if (pMatch - matchLength != pMatchBase || pMatchBase == pExtDictStart) {
+ /* If backwards match is entirely in the extDict or prefix, immediately return */
+ return matchLength;
+ }
+ DEBUGLOG(7, "ZSTD_ldm_countBackwardsMatch_2segments: found 2-parts backwards match (length in prefix==%zu)", matchLength);
+ matchLength += ZSTD_ldm_countBackwardsMatch(pIn - matchLength, pAnchor, pExtDictEnd, pExtDictStart);
+ DEBUGLOG(7, "final backwards match length = %zu", matchLength);
+ return matchLength;
+}
+
/** ZSTD_ldm_fillFastTables() :
*
* Fills the relevant tables for the ZSTD_fast and ZSTD_dfast strategies.
@@ -246,10 +260,10 @@ void ZSTD_ldm_fillHashTable(
* (after a long match, only update tables a limited amount). */
static void ZSTD_ldm_limitTableUpdate(ZSTD_matchState_t* ms, const BYTE* anchor)
{
- U32 const current = (U32)(anchor - ms->window.base);
- if (current > ms->nextToUpdate + 1024) {
+ U32 const curr = (U32)(anchor - ms->window.base);
+ if (curr > ms->nextToUpdate + 1024) {
ms->nextToUpdate =
- current - MIN(512, current - ms->nextToUpdate - 1024);
+ curr - MIN(512, curr - ms->nextToUpdate - 1024);
}
}
@@ -286,7 +300,7 @@ static size_t ZSTD_ldm_generateSequences_internal(
while (ip <= ilimit) {
size_t mLength;
- U32 const current = (U32)(ip - base);
+ U32 const curr = (U32)(ip - base);
size_t forwardMatchLength = 0, backwardMatchLength = 0;
ldmEntry_t* bestEntry = NULL;
if (ip != istart) {
@@ -336,8 +350,9 @@ static size_t ZSTD_ldm_generateSequences_internal(
continue;
}
curBackwardMatchLength =
- ZSTD_ldm_countBackwardsMatch(ip, anchor, pMatch,
- lowMatchPtr);
+ ZSTD_ldm_countBackwardsMatch_2segments(ip, anchor,
+ pMatch, lowMatchPtr,
+ dictStart, dictEnd);
curTotalMatchLength = curForwardMatchLength +
curBackwardMatchLength;
} else { /* !extDict */
@@ -365,7 +380,7 @@ static size_t ZSTD_ldm_generateSequences_internal(
/* No match found -- continue searching */
if (bestEntry == NULL) {
ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash,
- hBits, current,
+ hBits, curr,
*params);
ip++;
continue;
@@ -377,11 +392,11 @@ static size_t ZSTD_ldm_generateSequences_internal(
{
/* Store the sequence:
- * ip = current - backwardMatchLength
+ * ip = curr - backwardMatchLength
* The match is at (bestEntry->offset - backwardMatchLength)
*/
U32 const matchIndex = bestEntry->offset;
- U32 const offset = current - matchIndex;
+ U32 const offset = curr - matchIndex;
rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size;
/* Out of sequence storage */
@@ -562,6 +577,23 @@ static rawSeq maybeSplitSequence(rawSeqStore_t* rawSeqStore,
return sequence;
}
+void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
+ U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
+ while (currPos && rawSeqStore->pos < rawSeqStore->size) {
+ rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
+ if (currPos >= currSeq.litLength + currSeq.matchLength) {
+ currPos -= currSeq.litLength + currSeq.matchLength;
+ rawSeqStore->pos++;
+ } else {
+ rawSeqStore->posInSequence = currPos;
+ break;
+ }
+ }
+ if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) {
+ rawSeqStore->posInSequence = 0;
+ }
+}
+
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
@@ -577,6 +609,15 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
BYTE const* ip = istart;
DEBUGLOG(5, "ZSTD_ldm_blockCompress: srcSize=%zu", srcSize);
+ /* If using opt parser, use LDMs only as candidates rather than always accepting them */
+ if (cParams->strategy >= ZSTD_btopt) {
+ size_t lastLLSize;
+ ms->ldmSeqStore = rawSeqStore;
+ lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize);
+ ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize);
+ return lastLLSize;
+ }
+
assert(rawSeqStore->pos <= rawSeqStore->size);
assert(rawSeqStore->size <= rawSeqStore->capacity);
/* Loop through each sequence and apply the block compressor to the lits */
diff --git a/thirdparty/zstd/compress/zstd_ldm.h b/thirdparty/zstd/compress/zstd_ldm.h
index 229ea05a9e..6561024e4c 100644
--- a/thirdparty/zstd/compress/zstd_ldm.h
+++ b/thirdparty/zstd/compress/zstd_ldm.h
@@ -78,6 +78,12 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
void ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize,
U32 const minMatch);
+/* ZSTD_ldm_skipRawSeqStoreBytes():
+ * Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'.
+ * Not to be used in conjunction with ZSTD_ldm_skipSequences().
+ * Must be called for data with is not passed to ZSTD_ldm_blockCompress().
+ */
+void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes);
/** ZSTD_ldm_getTableSize() :
* Estimate the space needed for long distance matching tables or 0 if LDM is
diff --git a/thirdparty/zstd/compress/zstd_opt.c b/thirdparty/zstd/compress/zstd_opt.c
index 36fff050cf..e55c459deb 100644
--- a/thirdparty/zstd/compress/zstd_opt.c
+++ b/thirdparty/zstd/compress/zstd_opt.c
@@ -386,32 +386,32 @@ static U32 ZSTD_insertBt1(
const BYTE* const dictEnd = dictBase + dictLimit;
const BYTE* const prefixStart = base + dictLimit;
const BYTE* match;
- const U32 current = (U32)(ip-base);
- const U32 btLow = btMask >= current ? 0 : current - btMask;
- U32* smallerPtr = bt + 2*(current&btMask);
+ const U32 curr = (U32)(ip-base);
+ const U32 btLow = btMask >= curr ? 0 : curr - btMask;
+ U32* smallerPtr = bt + 2*(curr&btMask);
U32* largerPtr = smallerPtr + 1;
U32 dummy32; /* to be nullified at the end */
U32 const windowLow = ms->window.lowLimit;
- U32 matchEndIdx = current+8+1;
+ U32 matchEndIdx = curr+8+1;
size_t bestLength = 8;
U32 nbCompares = 1U << cParams->searchLog;
#ifdef ZSTD_C_PREDICT
- U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
- U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
+ U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0);
+ U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1);
predictedSmall += (predictedSmall>0);
predictedLarge += (predictedLarge>0);
#endif /* ZSTD_C_PREDICT */
- DEBUGLOG(8, "ZSTD_insertBt1 (%u)", current);
+ DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr);
assert(ip <= iend-8); /* required for h calculation */
- hashTable[h] = current; /* Update Hash Table */
+ hashTable[h] = curr; /* Update Hash Table */
assert(windowLow > 0);
while (nbCompares-- && (matchIndex >= windowLow)) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
- assert(matchIndex < current);
+ assert(matchIndex < curr);
#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
@@ -474,8 +474,8 @@ static U32 ZSTD_insertBt1(
*smallerPtr = *largerPtr = 0;
{ U32 positions = 0;
if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */
- assert(matchEndIdx > current + 8);
- return MAX(positions, matchEndIdx - (current + 8));
+ assert(matchEndIdx > curr + 8);
+ return MAX(positions, matchEndIdx - (curr + 8));
}
}
@@ -519,7 +519,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
const ZSTD_compressionParameters* const cParams = &ms->cParams;
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
const BYTE* const base = ms->window.base;
- U32 const current = (U32)(ip-base);
+ U32 const curr = (U32)(ip-base);
U32 const hashLog = cParams->hashLog;
U32 const minMatch = (mls==3) ? 3 : 4;
U32* const hashTable = ms->hashTable;
@@ -533,12 +533,12 @@ U32 ZSTD_insertBtAndGetAllMatches (
U32 const dictLimit = ms->window.dictLimit;
const BYTE* const dictEnd = dictBase + dictLimit;
const BYTE* const prefixStart = base + dictLimit;
- U32 const btLow = (btMask >= current) ? 0 : current - btMask;
- U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog);
+ U32 const btLow = (btMask >= curr) ? 0 : curr - btMask;
+ U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
U32 const matchLow = windowLow ? windowLow : 1;
- U32* smallerPtr = bt + 2*(current&btMask);
- U32* largerPtr = bt + 2*(current&btMask) + 1;
- U32 matchEndIdx = current+8+1; /* farthest referenced position of any match => detects repetitive patterns */
+ U32* smallerPtr = bt + 2*(curr&btMask);
+ U32* largerPtr = bt + 2*(curr&btMask) + 1;
+ U32 matchEndIdx = curr+8+1; /* farthest referenced position of any match => detects repetitive patterns */
U32 dummy32; /* to be nullified at the end */
U32 mnum = 0;
U32 nbCompares = 1U << cParams->searchLog;
@@ -557,7 +557,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit;
size_t bestLength = lengthToBeat-1;
- DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", current);
+ DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr);
/* check repCode */
assert(ll0 <= 1); /* necessarily 1 or 0 */
@@ -565,29 +565,29 @@ U32 ZSTD_insertBtAndGetAllMatches (
U32 repCode;
for (repCode = ll0; repCode < lastR; repCode++) {
U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
- U32 const repIndex = current - repOffset;
+ U32 const repIndex = curr - repOffset;
U32 repLen = 0;
- assert(current >= dictLimit);
- if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < current-dictLimit) { /* equivalent to `current > repIndex >= dictLimit` */
+ assert(curr >= dictLimit);
+ if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) { /* equivalent to `curr > repIndex >= dictLimit` */
/* We must validate the repcode offset because when we're using a dictionary the
* valid offset range shrinks when the dictionary goes out of bounds.
*/
if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) {
repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
}
- } else { /* repIndex < dictLimit || repIndex >= current */
+ } else { /* repIndex < dictLimit || repIndex >= curr */
const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ?
dmsBase + repIndex - dmsIndexDelta :
dictBase + repIndex;
- assert(current >= windowLow);
+ assert(curr >= windowLow);
if ( dictMode == ZSTD_extDict
- && ( ((repOffset-1) /*intentional overflow*/ < current - windowLow) /* equivalent to `current > repIndex >= windowLow` */
+ && ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow) /* equivalent to `curr > repIndex >= windowLow` */
& (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */)
&& (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch;
}
if (dictMode == ZSTD_dictMatchState
- && ( ((repOffset-1) /*intentional overflow*/ < current - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `current > repIndex >= dmsLowLimit` */
+ && ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `curr > repIndex >= dmsLowLimit` */
& ((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */
&& (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch;
@@ -609,7 +609,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
if ((mls == 3) /*static*/ && (bestLength < mls)) {
U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);
if ((matchIndex3 >= matchLow)
- & (current - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
+ & (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
size_t mlen;
if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) {
const BYTE* const match = base + matchIndex3;
@@ -624,26 +624,26 @@ U32 ZSTD_insertBtAndGetAllMatches (
DEBUGLOG(8, "found small match with hlog3, of length %u",
(U32)mlen);
bestLength = mlen;
- assert(current > matchIndex3);
+ assert(curr > matchIndex3);
assert(mnum==0); /* no prior solution */
- matches[0].off = (current - matchIndex3) + ZSTD_REP_MOVE;
+ matches[0].off = (curr - matchIndex3) + ZSTD_REP_MOVE;
matches[0].len = (U32)mlen;
mnum = 1;
if ( (mlen > sufficient_len) |
(ip+mlen == iLimit) ) { /* best possible length */
- ms->nextToUpdate = current+1; /* skip insertion */
+ ms->nextToUpdate = curr+1; /* skip insertion */
return 1;
} } }
/* no dictMatchState lookup: dicts don't have a populated HC3 table */
}
- hashTable[h] = current; /* Update Hash Table */
+ hashTable[h] = curr; /* Update Hash Table */
while (nbCompares-- && (matchIndex >= matchLow)) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
const BYTE* match;
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
- assert(current > matchIndex);
+ assert(curr > matchIndex);
if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {
assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */
@@ -660,12 +660,12 @@ U32 ZSTD_insertBtAndGetAllMatches (
if (matchLength > bestLength) {
DEBUGLOG(8, "found match of length %u at distance %u (offCode=%u)",
- (U32)matchLength, current - matchIndex, current - matchIndex + ZSTD_REP_MOVE);
+ (U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE);
assert(matchEndIdx > matchIndex);
if (matchLength > matchEndIdx - matchIndex)
matchEndIdx = matchIndex + (U32)matchLength;
bestLength = matchLength;
- matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE;
+ matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE;
matches[mnum].len = (U32)matchLength;
mnum++;
if ( (matchLength > ZSTD_OPT_NUM)
@@ -708,11 +708,11 @@ U32 ZSTD_insertBtAndGetAllMatches (
if (matchLength > bestLength) {
matchIndex = dictMatchIndex + dmsIndexDelta;
DEBUGLOG(8, "found dms match of length %u at distance %u (offCode=%u)",
- (U32)matchLength, current - matchIndex, current - matchIndex + ZSTD_REP_MOVE);
+ (U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE);
if (matchLength > matchEndIdx - matchIndex)
matchEndIdx = matchIndex + (U32)matchLength;
bestLength = matchLength;
- matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE;
+ matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE;
matches[mnum].len = (U32)matchLength;
mnum++;
if ( (matchLength > ZSTD_OPT_NUM)
@@ -733,7 +733,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
}
}
- assert(matchEndIdx > current+8);
+ assert(matchEndIdx > curr+8);
ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
return mnum;
}
@@ -764,6 +764,140 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
}
}
+/*************************
+* LDM helper functions *
+*************************/
+
+/* Struct containing info needed to make decision about ldm inclusion */
+typedef struct {
+ rawSeqStore_t seqStore; /* External match candidates store for this block */
+ U32 startPosInBlock; /* Start position of the current match candidate */
+ U32 endPosInBlock; /* End position of the current match candidate */
+ U32 offset; /* Offset of the match candidate */
+} ZSTD_optLdm_t;
+
+/* ZSTD_optLdm_skipRawSeqStoreBytes():
+ * Moves forward in rawSeqStore by nbBytes, which will update the fields 'pos' and 'posInSequence'.
+ */
+static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
+ U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
+ while (currPos && rawSeqStore->pos < rawSeqStore->size) {
+ rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
+ if (currPos >= currSeq.litLength + currSeq.matchLength) {
+ currPos -= currSeq.litLength + currSeq.matchLength;
+ rawSeqStore->pos++;
+ } else {
+ rawSeqStore->posInSequence = currPos;
+ break;
+ }
+ }
+ if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) {
+ rawSeqStore->posInSequence = 0;
+ }
+}
+
+/* ZSTD_opt_getNextMatchAndUpdateSeqStore():
+ * Calculates the beginning and end of the next match in the current block.
+ * Updates 'pos' and 'posInSequence' of the ldmSeqStore.
+ */
+static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock,
+ U32 blockBytesRemaining) {
+ rawSeq currSeq;
+ U32 currBlockEndPos;
+ U32 literalsBytesRemaining;
+ U32 matchBytesRemaining;
+
+ /* Setting match end position to MAX to ensure we never use an LDM during this block */
+ if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
+ optLdm->startPosInBlock = UINT_MAX;
+ optLdm->endPosInBlock = UINT_MAX;
+ return;
+ }
+ /* Calculate appropriate bytes left in matchLength and litLength after adjusting
+ based on ldmSeqStore->posInSequence */
+ currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos];
+ assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength);
+ currBlockEndPos = currPosInBlock + blockBytesRemaining;
+ literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ?
+ currSeq.litLength - (U32)optLdm->seqStore.posInSequence :
+ 0;
+ matchBytesRemaining = (literalsBytesRemaining == 0) ?
+ currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) :
+ currSeq.matchLength;
+
+ /* If there are more literal bytes than bytes remaining in block, no ldm is possible */
+ if (literalsBytesRemaining >= blockBytesRemaining) {
+ optLdm->startPosInBlock = UINT_MAX;
+ optLdm->endPosInBlock = UINT_MAX;
+ ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining);
+ return;
+ }
+
+ /* Matches may be < MINMATCH by this process. In that case, we will reject them
+ when we are deciding whether or not to add the ldm */
+ optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining;
+ optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining;
+ optLdm->offset = currSeq.offset;
+
+ if (optLdm->endPosInBlock > currBlockEndPos) {
+ /* Match ends after the block ends, we can't use the whole match */
+ optLdm->endPosInBlock = currBlockEndPos;
+ ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock);
+ } else {
+ /* Consume nb of bytes equal to size of sequence left */
+ ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining);
+ }
+}
+
+/* ZSTD_optLdm_maybeAddMatch():
+ * Adds a match if it's long enough, based on it's 'matchStartPosInBlock'
+ * and 'matchEndPosInBlock', into 'matches'. Maintains the correct ordering of 'matches'
+ */
+static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
+ ZSTD_optLdm_t* optLdm, U32 currPosInBlock) {
+ U32 posDiff = currPosInBlock - optLdm->startPosInBlock;
+ /* Note: ZSTD_match_t actually contains offCode and matchLength (before subtracting MINMATCH) */
+ U32 candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff;
+ U32 candidateOffCode = optLdm->offset + ZSTD_REP_MOVE;
+
+ /* Ensure that current block position is not outside of the match */
+ if (currPosInBlock < optLdm->startPosInBlock
+ || currPosInBlock >= optLdm->endPosInBlock
+ || candidateMatchLength < MINMATCH) {
+ return;
+ }
+
+ if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) {
+ DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offCode: %u matchLength %u) at block position=%u",
+ candidateOffCode, candidateMatchLength, currPosInBlock);
+ matches[*nbMatches].len = candidateMatchLength;
+ matches[*nbMatches].off = candidateOffCode;
+ (*nbMatches)++;
+ }
+}
+
+/* ZSTD_optLdm_processMatchCandidate():
+ * Wrapper function to update ldm seq store and call ldm functions as necessary.
+ */
+static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_t* matches, U32* nbMatches,
+ U32 currPosInBlock, U32 remainingBytes) {
+ if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
+ return;
+ }
+
+ if (currPosInBlock >= optLdm->endPosInBlock) {
+ if (currPosInBlock > optLdm->endPosInBlock) {
+ /* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily
+ * at the end of a match from the ldm seq store, and will often be some bytes
+ * over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots"
+ */
+ U32 posOvershoot = currPosInBlock - optLdm->endPosInBlock;
+ ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot);
+ }
+ ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
+ }
+ ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock);
+}
/*-*******************************
* Optimal parser
@@ -817,6 +951,11 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
ZSTD_optimal_t* const opt = optStatePtr->priceTable;
ZSTD_match_t* const matches = optStatePtr->matchTable;
ZSTD_optimal_t lastSequence;
+ ZSTD_optLdm_t optLdm;
+
+ optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore;
+ optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0;
+ ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip));
/* init */
DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
@@ -832,7 +971,9 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
/* find first match */
{ U32 const litlen = (U32)(ip - anchor);
U32 const ll0 = !litlen;
- U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
+ U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
+ ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
+ (U32)(ip-istart), (U32)(iend - ip));
if (!nbMatches) { ip++; continue; }
/* initialize opt[0] */
@@ -925,9 +1066,9 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
if (opt[cur].mlen != 0) {
U32 const prev = cur - opt[cur].mlen;
repcodes_t newReps = ZSTD_updateRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
- memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
+ ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
} else {
- memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
+ ZSTD_memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
}
/* last match must start at a minimum distance of 8 from oend */
@@ -945,8 +1086,12 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
U32 const previousPrice = opt[cur].price;
U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
- U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
+ U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
U32 matchNb;
+
+ ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
+ (U32)(inr-istart), (U32)(iend-inr));
+
if (!nbMatches) {
DEBUGLOG(7, "rPos:%u : no match found", cur);
continue;
@@ -1010,9 +1155,9 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
*/
if (lastSequence.mlen != 0) {
repcodes_t reps = ZSTD_updateRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
- memcpy(rep, &reps, sizeof(reps));
+ ZSTD_memcpy(rep, &reps, sizeof(reps));
} else {
- memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
+ ZSTD_memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
}
{ U32 const storeEnd = cur + 1;
@@ -1110,7 +1255,7 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
const void* src, size_t srcSize)
{
U32 tmpRep[ZSTD_REP_NUM]; /* updated rep codes will sink here */
- memcpy(tmpRep, rep, sizeof(tmpRep));
+ ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep));
DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize);
assert(ms->opt.litLengthSum == 0); /* first block */
@@ -1143,7 +1288,7 @@ size_t ZSTD_compressBlock_btultra2(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize)
{
- U32 const current = (U32)((const BYTE*)src - ms->window.base);
+ U32 const curr = (U32)((const BYTE*)src - ms->window.base);
DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize);
/* 2-pass strategy:
@@ -1158,7 +1303,7 @@ size_t ZSTD_compressBlock_btultra2(
if ( (ms->opt.litLengthSum==0) /* first block */
&& (seqStore->sequences == seqStore->sequencesStart) /* no ldm */
&& (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */
- && (current == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */
+ && (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */
&& (srcSize > ZSTD_PREDEF_THRESHOLD)
) {
ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);
diff --git a/thirdparty/zstd/compress/zstdmt_compress.c b/thirdparty/zstd/compress/zstdmt_compress.c
index 1e3c8fdbee..50454a50b9 100644
--- a/thirdparty/zstd/compress/zstdmt_compress.c
+++ b/thirdparty/zstd/compress/zstdmt_compress.c
@@ -20,8 +20,7 @@
/* ====== Dependencies ====== */
-#include <string.h> /* memcpy, memset */
-#include <limits.h> /* INT_MAX, UINT_MAX */
+#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset, INT_MAX, UINT_MAX */
#include "../common/mem.h" /* MEM_STATIC */
#include "../common/pool.h" /* threadpool */
#include "../common/threading.h" /* mutex */
@@ -106,11 +105,11 @@ typedef struct ZSTDMT_bufferPool_s {
static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbWorkers, ZSTD_customMem cMem)
{
unsigned const maxNbBuffers = 2*nbWorkers + 3;
- ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_calloc(
+ ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_customCalloc(
sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem);
if (bufPool==NULL) return NULL;
if (ZSTD_pthread_mutex_init(&bufPool->poolMutex, NULL)) {
- ZSTD_free(bufPool, cMem);
+ ZSTD_customFree(bufPool, cMem);
return NULL;
}
bufPool->bufferSize = 64 KB;
@@ -127,10 +126,10 @@ static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
if (!bufPool) return; /* compatibility with free on NULL */
for (u=0; u<bufPool->totalBuffers; u++) {
DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->bTable[u].start);
- ZSTD_free(bufPool->bTable[u].start, bufPool->cMem);
+ ZSTD_customFree(bufPool->bTable[u].start, bufPool->cMem);
}
ZSTD_pthread_mutex_destroy(&bufPool->poolMutex);
- ZSTD_free(bufPool, bufPool->cMem);
+ ZSTD_customFree(bufPool, bufPool->cMem);
}
/* only works at initialization, not during compression */
@@ -201,13 +200,13 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
}
/* size conditions not respected : scratch this buffer, create new one */
DEBUGLOG(5, "ZSTDMT_getBuffer: existing buffer does not meet size conditions => freeing");
- ZSTD_free(buf.start, bufPool->cMem);
+ ZSTD_customFree(buf.start, bufPool->cMem);
}
ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
/* create new buffer */
DEBUGLOG(5, "ZSTDMT_getBuffer: create a new buffer");
{ buffer_t buffer;
- void* const start = ZSTD_malloc(bSize, bufPool->cMem);
+ void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
buffer.start = start; /* note : start can be NULL if malloc fails ! */
buffer.capacity = (start==NULL) ? 0 : bSize;
if (start==NULL) {
@@ -229,13 +228,13 @@ static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)
{
size_t const bSize = bufPool->bufferSize;
if (buffer.capacity < bSize) {
- void* const start = ZSTD_malloc(bSize, bufPool->cMem);
+ void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
buffer_t newBuffer;
newBuffer.start = start;
newBuffer.capacity = start == NULL ? 0 : bSize;
if (start != NULL) {
assert(newBuffer.capacity >= buffer.capacity);
- memcpy(newBuffer.start, buffer.start, buffer.capacity);
+ ZSTD_memcpy(newBuffer.start, buffer.start, buffer.capacity);
DEBUGLOG(5, "ZSTDMT_resizeBuffer: created buffer of size %u", (U32)bSize);
return newBuffer;
}
@@ -261,14 +260,12 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
/* Reached bufferPool capacity (should not happen) */
DEBUGLOG(5, "ZSTDMT_releaseBuffer: pool capacity reached => freeing ");
- ZSTD_free(buf.start, bufPool->cMem);
+ ZSTD_customFree(buf.start, bufPool->cMem);
}
/* ===== Seq Pool Wrapper ====== */
-static rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0};
-
typedef ZSTDMT_bufferPool ZSTDMT_seqPool;
static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool)
@@ -278,7 +275,7 @@ static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool)
static rawSeqStore_t bufferToSeq(buffer_t buffer)
{
- rawSeqStore_t seq = {NULL, 0, 0, 0};
+ rawSeqStore_t seq = kNullRawSeqStore;
seq.seq = (rawSeq*)buffer.start;
seq.capacity = buffer.capacity / sizeof(rawSeq);
return seq;
@@ -354,7 +351,7 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
for (cid=0; cid<pool->totalCCtx; cid++)
ZSTD_freeCCtx(pool->cctx[cid]); /* note : compatible with free on NULL */
ZSTD_pthread_mutex_destroy(&pool->poolMutex);
- ZSTD_free(pool, pool->cMem);
+ ZSTD_customFree(pool, pool->cMem);
}
/* ZSTDMT_createCCtxPool() :
@@ -362,12 +359,12 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(int nbWorkers,
ZSTD_customMem cMem)
{
- ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_calloc(
+ ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_customCalloc(
sizeof(ZSTDMT_CCtxPool) + (nbWorkers-1)*sizeof(ZSTD_CCtx*), cMem);
assert(nbWorkers > 0);
if (!cctxPool) return NULL;
if (ZSTD_pthread_mutex_init(&cctxPool->poolMutex, NULL)) {
- ZSTD_free(cctxPool, cMem);
+ ZSTD_customFree(cctxPool, cMem);
return NULL;
}
cctxPool->cMem = cMem;
@@ -478,7 +475,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
serialState->ldmState.hashPower =
ZSTD_rollingHash_primePower(params.ldmParams.minMatchLength);
} else {
- memset(&params.ldmParams, 0, sizeof(params.ldmParams));
+ ZSTD_memset(&params.ldmParams, 0, sizeof(params.ldmParams));
}
serialState->nextJobID = 0;
if (params.fParams.checksumFlag)
@@ -499,18 +496,18 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
ZSTD_window_init(&serialState->ldmState.window);
/* Resize tables and output space if necessary. */
if (serialState->ldmState.hashTable == NULL || serialState->params.ldmParams.hashLog < hashLog) {
- ZSTD_free(serialState->ldmState.hashTable, cMem);
- serialState->ldmState.hashTable = (ldmEntry_t*)ZSTD_malloc(hashSize, cMem);
+ ZSTD_customFree(serialState->ldmState.hashTable, cMem);
+ serialState->ldmState.hashTable = (ldmEntry_t*)ZSTD_customMalloc(hashSize, cMem);
}
if (serialState->ldmState.bucketOffsets == NULL || prevBucketLog < bucketLog) {
- ZSTD_free(serialState->ldmState.bucketOffsets, cMem);
- serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_malloc(bucketSize, cMem);
+ ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
+ serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_customMalloc(bucketSize, cMem);
}
if (!serialState->ldmState.hashTable || !serialState->ldmState.bucketOffsets)
return 1;
/* Zero the tables */
- memset(serialState->ldmState.hashTable, 0, hashSize);
- memset(serialState->ldmState.bucketOffsets, 0, bucketSize);
+ ZSTD_memset(serialState->ldmState.hashTable, 0, hashSize);
+ ZSTD_memset(serialState->ldmState.bucketOffsets, 0, bucketSize);
/* Update window state and fill hash table with dict */
serialState->ldmState.loadedDictEnd = 0;
@@ -537,7 +534,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
static int ZSTDMT_serialState_init(serialState_t* serialState)
{
int initError = 0;
- memset(serialState, 0, sizeof(*serialState));
+ ZSTD_memset(serialState, 0, sizeof(*serialState));
initError |= ZSTD_pthread_mutex_init(&serialState->mutex, NULL);
initError |= ZSTD_pthread_cond_init(&serialState->cond, NULL);
initError |= ZSTD_pthread_mutex_init(&serialState->ldmWindowMutex, NULL);
@@ -552,8 +549,8 @@ static void ZSTDMT_serialState_free(serialState_t* serialState)
ZSTD_pthread_cond_destroy(&serialState->cond);
ZSTD_pthread_mutex_destroy(&serialState->ldmWindowMutex);
ZSTD_pthread_cond_destroy(&serialState->ldmWindowCond);
- ZSTD_free(serialState->ldmState.hashTable, cMem);
- ZSTD_free(serialState->ldmState.bucketOffsets, cMem);
+ ZSTD_customFree(serialState->ldmState.hashTable, cMem);
+ ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
}
static void ZSTDMT_serialState_update(serialState_t* serialState,
@@ -820,7 +817,6 @@ struct ZSTDMT_CCtx_s {
roundBuff_t roundBuff;
serialState_t serial;
rsyncState_t rsync;
- unsigned singleBlockingThread;
unsigned jobIDMask;
unsigned doneJobID;
unsigned nextJobID;
@@ -832,6 +828,7 @@ struct ZSTDMT_CCtx_s {
ZSTD_customMem cMem;
ZSTD_CDict* cdictLocal;
const ZSTD_CDict* cdict;
+ unsigned providedFactory: 1;
};
static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZSTD_customMem cMem)
@@ -842,7 +839,7 @@ static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZS
ZSTD_pthread_mutex_destroy(&jobTable[jobNb].job_mutex);
ZSTD_pthread_cond_destroy(&jobTable[jobNb].job_cond);
}
- ZSTD_free(jobTable, cMem);
+ ZSTD_customFree(jobTable, cMem);
}
/* ZSTDMT_allocJobsTable()
@@ -854,7 +851,7 @@ static ZSTDMT_jobDescription* ZSTDMT_createJobsTable(U32* nbJobsPtr, ZSTD_custom
U32 const nbJobs = 1 << nbJobsLog2;
U32 jobNb;
ZSTDMT_jobDescription* const jobTable = (ZSTDMT_jobDescription*)
- ZSTD_calloc(nbJobs * sizeof(ZSTDMT_jobDescription), cMem);
+ ZSTD_customCalloc(nbJobs * sizeof(ZSTDMT_jobDescription), cMem);
int initError = 0;
if (jobTable==NULL) return NULL;
*nbJobsPtr = nbJobs;
@@ -885,12 +882,12 @@ static size_t ZSTDMT_expandJobsTable (ZSTDMT_CCtx* mtctx, U32 nbWorkers) {
/* ZSTDMT_CCtxParam_setNbWorkers():
* Internal use only */
-size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers)
+static size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers)
{
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, (int)nbWorkers);
}
-MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem)
+MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool)
{
ZSTDMT_CCtx* mtctx;
U32 nbJobs = nbWorkers + 2;
@@ -903,12 +900,19 @@ MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers,
/* invalid custom allocator */
return NULL;
- mtctx = (ZSTDMT_CCtx*) ZSTD_calloc(sizeof(ZSTDMT_CCtx), cMem);
+ mtctx = (ZSTDMT_CCtx*) ZSTD_customCalloc(sizeof(ZSTDMT_CCtx), cMem);
if (!mtctx) return NULL;
ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers);
mtctx->cMem = cMem;
mtctx->allJobsCompleted = 1;
- mtctx->factory = POOL_create_advanced(nbWorkers, 0, cMem);
+ if (pool != NULL) {
+ mtctx->factory = pool;
+ mtctx->providedFactory = 1;
+ }
+ else {
+ mtctx->factory = POOL_create_advanced(nbWorkers, 0, cMem);
+ mtctx->providedFactory = 0;
+ }
mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, cMem);
assert(nbJobs > 0); assert((nbJobs & (nbJobs - 1)) == 0); /* ensure nbJobs is a power of 2 */
mtctx->jobIDMask = nbJobs - 1;
@@ -925,22 +929,18 @@ MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers,
return mtctx;
}
-ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem)
+ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool)
{
#ifdef ZSTD_MULTITHREAD
- return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem);
+ return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem, pool);
#else
(void)nbWorkers;
(void)cMem;
+ (void)pool;
return NULL;
#endif
}
-ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbWorkers)
-{
- return ZSTDMT_createCCtx_advanced(nbWorkers, ZSTD_defaultCMem);
-}
-
/* ZSTDMT_releaseAllJobResources() :
* note : ensure all workers are killed first ! */
@@ -957,7 +957,7 @@ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);
/* Clear the job description, but keep the mutex/cond */
- memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID]));
+ ZSTD_memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID]));
mtctx->jobs[jobID].job_mutex = mutex;
mtctx->jobs[jobID].job_cond = cond;
}
@@ -984,7 +984,8 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* mtctx)
size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
{
if (mtctx==NULL) return 0; /* compatible with free on NULL */
- POOL_free(mtctx->factory); /* stop and free worker threads */
+ if (!mtctx->providedFactory)
+ POOL_free(mtctx->factory); /* stop and free worker threads */
ZSTDMT_releaseAllJobResources(mtctx); /* release job resources into pools first */
ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem);
ZSTDMT_freeBufferPool(mtctx->bufPool);
@@ -993,8 +994,8 @@ size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
ZSTDMT_serialState_free(&mtctx->serial);
ZSTD_freeCDict(mtctx->cdictLocal);
if (mtctx->roundBuff.buffer)
- ZSTD_free(mtctx->roundBuff.buffer, mtctx->cMem);
- ZSTD_free(mtctx, mtctx->cMem);
+ ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem);
+ ZSTD_customFree(mtctx, mtctx->cMem);
return 0;
}
@@ -1011,65 +1012,6 @@ size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx)
+ mtctx->roundBuff.capacity;
}
-/* Internal only */
-size_t
-ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params,
- ZSTDMT_parameter parameter,
- int value)
-{
- DEBUGLOG(4, "ZSTDMT_CCtxParam_setMTCtxParameter");
- switch(parameter)
- {
- case ZSTDMT_p_jobSize :
- DEBUGLOG(4, "ZSTDMT_CCtxParam_setMTCtxParameter : set jobSize to %i", value);
- return ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, value);
- case ZSTDMT_p_overlapLog :
- DEBUGLOG(4, "ZSTDMT_p_overlapLog : %i", value);
- return ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, value);
- case ZSTDMT_p_rsyncable :
- DEBUGLOG(4, "ZSTD_p_rsyncable : %i", value);
- return ZSTD_CCtxParams_setParameter(params, ZSTD_c_rsyncable, value);
- default :
- return ERROR(parameter_unsupported);
- }
-}
-
-size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int value)
-{
- DEBUGLOG(4, "ZSTDMT_setMTCtxParameter");
- return ZSTDMT_CCtxParam_setMTCtxParameter(&mtctx->params, parameter, value);
-}
-
-size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int* value)
-{
- switch (parameter) {
- case ZSTDMT_p_jobSize:
- return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_jobSize, value);
- case ZSTDMT_p_overlapLog:
- return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_overlapLog, value);
- case ZSTDMT_p_rsyncable:
- return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_rsyncable, value);
- default:
- return ERROR(parameter_unsupported);
- }
-}
-
-/* Sets parameters relevant to the compression job,
- * initializing others to default values. */
-static ZSTD_CCtx_params ZSTDMT_initJobCCtxParams(const ZSTD_CCtx_params* params)
-{
- ZSTD_CCtx_params jobParams = *params;
- /* Clear parameters related to multithreading */
- jobParams.forceWindow = 0;
- jobParams.nbWorkers = 0;
- jobParams.jobSize = 0;
- jobParams.overlapLog = 0;
- jobParams.rsyncable = 0;
- memset(&jobParams.ldmParams, 0, sizeof(ldmParams_t));
- memset(&jobParams.customMem, 0, sizeof(ZSTD_customMem));
- return jobParams;
-}
-
/* ZSTDMT_resize() :
* @return : error code if fails, 0 on success */
@@ -1098,7 +1040,7 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p
DEBUGLOG(5, "ZSTDMT_updateCParams_whileCompressing (level:%i)",
compressionLevel);
mtctx->params.compressionLevel = compressionLevel;
- { ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0);
+ { ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
cParams.windowLog = saved_wlog;
mtctx->params.cParams = cParams;
}
@@ -1185,8 +1127,8 @@ static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params)
if (params->ldmParams.enableLdm) {
/* In Long Range Mode, the windowLog is typically oversized.
* In which case, it's preferable to determine the jobSize
- * based on chainLog instead. */
- jobLog = MAX(21, params->cParams.chainLog + 4);
+ * based on cycleLog instead. */
+ jobLog = MAX(21, ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy) + 3);
} else {
jobLog = MAX(20, params->cParams.windowLog + 2);
}
@@ -1240,174 +1182,6 @@ static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params)
return (ovLog==0) ? 0 : (size_t)1 << ovLog;
}
-static unsigned
-ZSTDMT_computeNbJobs(const ZSTD_CCtx_params* params, size_t srcSize, unsigned nbWorkers)
-{
- assert(nbWorkers>0);
- { size_t const jobSizeTarget = (size_t)1 << ZSTDMT_computeTargetJobLog(params);
- size_t const jobMaxSize = jobSizeTarget << 2;
- size_t const passSizeMax = jobMaxSize * nbWorkers;
- unsigned const multiplier = (unsigned)(srcSize / passSizeMax) + 1;
- unsigned const nbJobsLarge = multiplier * nbWorkers;
- unsigned const nbJobsMax = (unsigned)(srcSize / jobSizeTarget) + 1;
- unsigned const nbJobsSmall = MIN(nbJobsMax, nbWorkers);
- return (multiplier>1) ? nbJobsLarge : nbJobsSmall;
-} }
-
-/* ZSTDMT_compress_advanced_internal() :
- * This is a blocking function : it will only give back control to caller after finishing its compression job.
- */
-static size_t
-ZSTDMT_compress_advanced_internal(
- ZSTDMT_CCtx* mtctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- const ZSTD_CDict* cdict,
- ZSTD_CCtx_params params)
-{
- ZSTD_CCtx_params const jobParams = ZSTDMT_initJobCCtxParams(&params);
- size_t const overlapSize = ZSTDMT_computeOverlapSize(&params);
- unsigned const nbJobs = ZSTDMT_computeNbJobs(&params, srcSize, params.nbWorkers);
- size_t const proposedJobSize = (srcSize + (nbJobs-1)) / nbJobs;
- size_t const avgJobSize = (((proposedJobSize-1) & 0x1FFFF) < 0x7FFF) ? proposedJobSize + 0xFFFF : proposedJobSize; /* avoid too small last block */
- const char* const srcStart = (const char*)src;
- size_t remainingSrcSize = srcSize;
- unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbJobs : (unsigned)(dstCapacity / ZSTD_compressBound(avgJobSize)); /* presumes avgJobSize >= 256 KB, which should be the case */
- size_t frameStartPos = 0, dstBufferPos = 0;
- assert(jobParams.nbWorkers == 0);
- assert(mtctx->cctxPool->totalCCtx == params.nbWorkers);
-
- params.jobSize = (U32)avgJobSize;
- DEBUGLOG(4, "ZSTDMT_compress_advanced_internal: nbJobs=%2u (rawSize=%u bytes; fixedSize=%u) ",
- nbJobs, (U32)proposedJobSize, (U32)avgJobSize);
-
- if ((nbJobs==1) | (params.nbWorkers<=1)) { /* fallback to single-thread mode : this is a blocking invocation anyway */
- ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
- DEBUGLOG(4, "ZSTDMT_compress_advanced_internal: fallback to single-thread mode");
- if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, jobParams.fParams);
- return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, &jobParams);
- }
-
- assert(avgJobSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), required to compress directly into Dst (no additional buffer) */
- ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgJobSize) );
- /* LDM doesn't even try to load the dictionary in single-ingestion mode */
- if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, avgJobSize, NULL, 0, ZSTD_dct_auto))
- return ERROR(memory_allocation);
-
- FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbJobs) , ""); /* only expands if necessary */
-
- { unsigned u;
- for (u=0; u<nbJobs; u++) {
- size_t const jobSize = MIN(remainingSrcSize, avgJobSize);
- size_t const dstBufferCapacity = ZSTD_compressBound(jobSize);
- buffer_t const dstAsBuffer = { (char*)dst + dstBufferPos, dstBufferCapacity };
- buffer_t const dstBuffer = u < compressWithinDst ? dstAsBuffer : g_nullBuffer;
- size_t dictSize = u ? overlapSize : 0;
-
- mtctx->jobs[u].prefix.start = srcStart + frameStartPos - dictSize;
- mtctx->jobs[u].prefix.size = dictSize;
- mtctx->jobs[u].src.start = srcStart + frameStartPos;
- mtctx->jobs[u].src.size = jobSize; assert(jobSize > 0); /* avoid job.src.size == 0 */
- mtctx->jobs[u].consumed = 0;
- mtctx->jobs[u].cSize = 0;
- mtctx->jobs[u].cdict = (u==0) ? cdict : NULL;
- mtctx->jobs[u].fullFrameSize = srcSize;
- mtctx->jobs[u].params = jobParams;
- /* do not calculate checksum within sections, but write it in header for first section */
- mtctx->jobs[u].dstBuff = dstBuffer;
- mtctx->jobs[u].cctxPool = mtctx->cctxPool;
- mtctx->jobs[u].bufPool = mtctx->bufPool;
- mtctx->jobs[u].seqPool = mtctx->seqPool;
- mtctx->jobs[u].serial = &mtctx->serial;
- mtctx->jobs[u].jobID = u;
- mtctx->jobs[u].firstJob = (u==0);
- mtctx->jobs[u].lastJob = (u==nbJobs-1);
-
- DEBUGLOG(5, "ZSTDMT_compress_advanced_internal: posting job %u (%u bytes)", u, (U32)jobSize);
- DEBUG_PRINTHEX(6, mtctx->jobs[u].prefix.start, 12);
- POOL_add(mtctx->factory, ZSTDMT_compressionJob, &mtctx->jobs[u]);
-
- frameStartPos += jobSize;
- dstBufferPos += dstBufferCapacity;
- remainingSrcSize -= jobSize;
- } }
-
- /* collect result */
- { size_t error = 0, dstPos = 0;
- unsigned jobID;
- for (jobID=0; jobID<nbJobs; jobID++) {
- DEBUGLOG(5, "waiting for job %u ", jobID);
- ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex);
- while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) {
- DEBUGLOG(5, "waiting for jobCompleted signal from job %u", jobID);
- ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex);
- }
- ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex);
- DEBUGLOG(5, "ready to write job %u ", jobID);
-
- { size_t const cSize = mtctx->jobs[jobID].cSize;
- if (ZSTD_isError(cSize)) error = cSize;
- if ((!error) && (dstPos + cSize > dstCapacity)) error = ERROR(dstSize_tooSmall);
- if (jobID) { /* note : job 0 is written directly at dst, which is correct position */
- if (!error)
- memmove((char*)dst + dstPos, mtctx->jobs[jobID].dstBuff.start, cSize); /* may overlap when job compressed within dst */
- if (jobID >= compressWithinDst) { /* job compressed into its own buffer, which must be released */
- DEBUGLOG(5, "releasing buffer %u>=%u", jobID, compressWithinDst);
- ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);
- } }
- mtctx->jobs[jobID].dstBuff = g_nullBuffer;
- mtctx->jobs[jobID].cSize = 0;
- dstPos += cSize ;
- }
- } /* for (jobID=0; jobID<nbJobs; jobID++) */
-
- DEBUGLOG(4, "checksumFlag : %u ", params.fParams.checksumFlag);
- if (params.fParams.checksumFlag) {
- U32 const checksum = (U32)XXH64_digest(&mtctx->serial.xxhState);
- if (dstPos + 4 > dstCapacity) {
- error = ERROR(dstSize_tooSmall);
- } else {
- DEBUGLOG(4, "writing checksum : %08X \n", checksum);
- MEM_writeLE32((char*)dst + dstPos, checksum);
- dstPos += 4;
- } }
-
- if (!error) DEBUGLOG(4, "compressed size : %u ", (U32)dstPos);
- return error ? error : dstPos;
- }
-}
-
-size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- const ZSTD_CDict* cdict,
- ZSTD_parameters params,
- int overlapLog)
-{
- ZSTD_CCtx_params cctxParams = mtctx->params;
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
- assert(ZSTD_OVERLAPLOG_MIN <= overlapLog && overlapLog <= ZSTD_OVERLAPLOG_MAX);
- cctxParams.overlapLog = overlapLog;
- return ZSTDMT_compress_advanced_internal(mtctx,
- dst, dstCapacity,
- src, srcSize,
- cdict, cctxParams);
-}
-
-
-size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- int compressionLevel)
-{
- ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0);
- int const overlapLog = ZSTDMT_overlapLog_default(params.cParams.strategy);
- params.fParams.contentSizeFlag = 1;
- return ZSTDMT_compress_advanced(mtctx, dst, dstCapacity, src, srcSize, NULL, params, overlapLog);
-}
-
-
/* ====================================== */
/* ======= Streaming API ======= */
/* ====================================== */
@@ -1432,16 +1206,6 @@ size_t ZSTDMT_initCStream_internal(
if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN;
if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX;
- mtctx->singleBlockingThread = (pledgedSrcSize <= ZSTDMT_JOBSIZE_MIN); /* do not trigger multi-threading when srcSize is too small */
- if (mtctx->singleBlockingThread) {
- ZSTD_CCtx_params const singleThreadParams = ZSTDMT_initJobCCtxParams(&params);
- DEBUGLOG(5, "ZSTDMT_initCStream_internal: switch to single blocking thread mode");
- assert(singleThreadParams.nbWorkers == 0);
- return ZSTD_initCStream_internal(mtctx->cctxPool->cctx[0],
- dict, dictSize, cdict,
- &singleThreadParams, pledgedSrcSize);
- }
-
DEBUGLOG(4, "ZSTDMT_initCStream_internal: %u workers", params.nbWorkers);
if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */
@@ -1504,8 +1268,8 @@ size_t ZSTDMT_initCStream_internal(
size_t const capacity = MAX(windowSize, sectionsSize) + slackSize;
if (mtctx->roundBuff.capacity < capacity) {
if (mtctx->roundBuff.buffer)
- ZSTD_free(mtctx->roundBuff.buffer, mtctx->cMem);
- mtctx->roundBuff.buffer = (BYTE*)ZSTD_malloc(capacity, mtctx->cMem);
+ ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem);
+ mtctx->roundBuff.buffer = (BYTE*)ZSTD_customMalloc(capacity, mtctx->cMem);
if (mtctx->roundBuff.buffer == NULL) {
mtctx->roundBuff.capacity = 0;
return ERROR(memory_allocation);
@@ -1530,53 +1294,6 @@ size_t ZSTDMT_initCStream_internal(
return 0;
}
-size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
- const void* dict, size_t dictSize,
- ZSTD_parameters params,
- unsigned long long pledgedSrcSize)
-{
- ZSTD_CCtx_params cctxParams = mtctx->params; /* retrieve sticky params */
- DEBUGLOG(4, "ZSTDMT_initCStream_advanced (pledgedSrcSize=%u)", (U32)pledgedSrcSize);
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
- return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, ZSTD_dct_auto, NULL,
- cctxParams, pledgedSrcSize);
-}
-
-size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
- const ZSTD_CDict* cdict,
- ZSTD_frameParameters fParams,
- unsigned long long pledgedSrcSize)
-{
- ZSTD_CCtx_params cctxParams = mtctx->params;
- if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
- cctxParams.cParams = ZSTD_getCParamsFromCDict(cdict);
- cctxParams.fParams = fParams;
- return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, ZSTD_dct_auto, cdict,
- cctxParams, pledgedSrcSize);
-}
-
-
-/* ZSTDMT_resetCStream() :
- * pledgedSrcSize can be zero == unknown (for the time being)
- * prefer using ZSTD_CONTENTSIZE_UNKNOWN,
- * as `0` might mean "empty" in the future */
-size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize)
-{
- if (!pledgedSrcSize) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
- return ZSTDMT_initCStream_internal(mtctx, NULL, 0, ZSTD_dct_auto, 0, mtctx->params,
- pledgedSrcSize);
-}
-
-size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel) {
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
- ZSTD_CCtx_params cctxParams = mtctx->params; /* retrieve sticky params */
- DEBUGLOG(4, "ZSTDMT_initCStream (cLevel=%i)", compressionLevel);
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
- return ZSTDMT_initCStream_internal(mtctx, NULL, 0, ZSTD_dct_auto, NULL, cctxParams, ZSTD_CONTENTSIZE_UNKNOWN);
-}
-
/* ZSTDMT_writeLastEmptyBlock()
* Write a single empty block with an end-of-frame to finish a frame.
@@ -1740,7 +1457,7 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
assert(cSize >= mtctx->jobs[wJobID].dstFlushed);
assert(mtctx->jobs[wJobID].dstBuff.start != NULL);
if (toFlush > 0) {
- memcpy((char*)output->dst + output->pos,
+ ZSTD_memcpy((char*)output->dst + output->pos,
(const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed,
toFlush);
}
@@ -1894,7 +1611,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
return 0;
}
ZSTDMT_waitForLdmComplete(mtctx, buffer);
- memmove(start, mtctx->inBuff.prefix.start, prefixSize);
+ ZSTD_memmove(start, mtctx->inBuff.prefix.start, prefixSize);
mtctx->inBuff.prefix.start = start;
mtctx->roundBuff.pos = prefixSize;
}
@@ -1968,6 +1685,16 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
pos = 0;
prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH;
hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH);
+ if ((hash & hitMask) == hitMask) {
+ /* We're already at a sync point so don't load any more until
+ * we're able to flush this sync point.
+ * This likely happened because the job table was full so we
+ * couldn't add our job.
+ */
+ syncPoint.toLoad = 0;
+ syncPoint.flush = 1;
+ return syncPoint;
+ }
} else {
/* We don't have enough bytes buffered to initialize the hash, but
* we know we have at least RSYNC_LENGTH bytes total.
@@ -2022,34 +1749,11 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
assert(output->pos <= output->size);
assert(input->pos <= input->size);
- if (mtctx->singleBlockingThread) { /* delegate to single-thread (synchronous) */
- return ZSTD_compressStream2(mtctx->cctxPool->cctx[0], output, input, endOp);
- }
-
if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) {
/* current frame being ended. Only flush/end are allowed */
return ERROR(stage_wrong);
}
- /* single-pass shortcut (note : synchronous-mode) */
- if ( (!mtctx->params.rsyncable) /* rsyncable mode is disabled */
- && (mtctx->nextJobID == 0) /* just started */
- && (mtctx->inBuff.filled == 0) /* nothing buffered */
- && (!mtctx->jobReady) /* no job already created */
- && (endOp == ZSTD_e_end) /* end order */
- && (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) ) { /* enough space in dst */
- size_t const cSize = ZSTDMT_compress_advanced_internal(mtctx,
- (char*)output->dst + output->pos, output->size - output->pos,
- (const char*)input->src + input->pos, input->size - input->pos,
- mtctx->cdict, mtctx->params);
- if (ZSTD_isError(cSize)) return cSize;
- input->pos = input->size;
- output->pos += cSize;
- mtctx->allJobsCompleted = 1;
- mtctx->frameEnded = 1;
- return 0;
- }
-
/* fill input buffer */
if ( (!mtctx->jobReady)
&& (input->size > input->pos) ) { /* support NULL input */
@@ -2072,13 +1776,21 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
assert(mtctx->inBuff.buffer.capacity >= mtctx->targetSectionSize);
DEBUGLOG(5, "ZSTDMT_compressStream_generic: adding %u bytes on top of %u to buffer of size %u",
(U32)syncPoint.toLoad, (U32)mtctx->inBuff.filled, (U32)mtctx->targetSectionSize);
- memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, syncPoint.toLoad);
+ ZSTD_memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, syncPoint.toLoad);
input->pos += syncPoint.toLoad;
mtctx->inBuff.filled += syncPoint.toLoad;
forwardInputProgress = syncPoint.toLoad>0;
}
- if ((input->pos < input->size) && (endOp == ZSTD_e_end))
- endOp = ZSTD_e_flush; /* can't end now : not all input consumed */
+ }
+ if ((input->pos < input->size) && (endOp == ZSTD_e_end)) {
+ /* Can't end yet because the input is not fully consumed.
+ * We are in one of these cases:
+ * - mtctx->inBuff is NULL & empty: we couldn't get an input buffer so don't create a new job.
+ * - We filled the input buffer: flush this job but don't end the frame.
+ * - We hit a synchronization point: flush this job but don't end the frame.
+ */
+ assert(mtctx->inBuff.filled == 0 || mtctx->inBuff.filled == mtctx->targetSectionSize || mtctx->params.rsyncable);
+ endOp = ZSTD_e_flush;
}
if ( (mtctx->jobReady)
@@ -2097,47 +1809,3 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
return remainingToFlush;
}
}
-
-
-size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
-{
- FORWARD_IF_ERROR( ZSTDMT_compressStream_generic(mtctx, output, input, ZSTD_e_continue) , "");
-
- /* recommended next input size : fill current input buffer */
- return mtctx->targetSectionSize - mtctx->inBuff.filled; /* note : could be zero when input buffer is fully filled and no more availability to create new job */
-}
-
-
-static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_EndDirective endFrame)
-{
- size_t const srcSize = mtctx->inBuff.filled;
- DEBUGLOG(5, "ZSTDMT_flushStream_internal");
-
- if ( mtctx->jobReady /* one job ready for a worker to pick up */
- || (srcSize > 0) /* still some data within input buffer */
- || ((endFrame==ZSTD_e_end) && !mtctx->frameEnded)) { /* need a last 0-size block to end frame */
- DEBUGLOG(5, "ZSTDMT_flushStream_internal : create a new job (%u bytes, end:%u)",
- (U32)srcSize, (U32)endFrame);
- FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, srcSize, endFrame) , "");
- }
-
- /* check if there is any data available to flush */
- return ZSTDMT_flushProduced(mtctx, output, 1 /* blockToFlush */, endFrame);
-}
-
-
-size_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output)
-{
- DEBUGLOG(5, "ZSTDMT_flushStream");
- if (mtctx->singleBlockingThread)
- return ZSTD_flushStream(mtctx->cctxPool->cctx[0], output);
- return ZSTDMT_flushStream_internal(mtctx, output, ZSTD_e_flush);
-}
-
-size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output)
-{
- DEBUGLOG(4, "ZSTDMT_endStream");
- if (mtctx->singleBlockingThread)
- return ZSTD_endStream(mtctx->cctxPool->cctx[0], output);
- return ZSTDMT_flushStream_internal(mtctx, output, ZSTD_e_end);
-}
diff --git a/thirdparty/zstd/compress/zstdmt_compress.h b/thirdparty/zstd/compress/zstdmt_compress.h
index 89914eb7f8..0a9e551c99 100644
--- a/thirdparty/zstd/compress/zstdmt_compress.h
+++ b/thirdparty/zstd/compress/zstdmt_compress.h
@@ -19,26 +19,14 @@
/* Note : This is an internal API.
* These APIs used to be exposed with ZSTDLIB_API,
* because it used to be the only way to invoke MT compression.
- * Now, it's recommended to use ZSTD_compress2 and ZSTD_compressStream2()
- * instead.
- *
- * If you depend on these APIs and can't switch, then define
- * ZSTD_LEGACY_MULTITHREADED_API when making the dynamic library.
- * However, we may completely remove these functions in a future
- * release, so please switch soon.
+ * Now, you must use ZSTD_compress2 and ZSTD_compressStream2() instead.
*
* This API requires ZSTD_MULTITHREAD to be defined during compilation,
* otherwise ZSTDMT_createCCtx*() will fail.
*/
-#ifdef ZSTD_LEGACY_MULTITHREADED_API
-# define ZSTDMT_API ZSTDLIB_API
-#else
-# define ZSTDMT_API
-#endif
-
/* === Dependencies === */
-#include <stddef.h> /* size_t */
+#include "../common/zstd_deps.h" /* size_t */
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */
#include "../zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */
@@ -54,78 +42,34 @@
#define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB))
+/* ========================================================
+ * === Private interface, for use by ZSTD_compress.c ===
+ * === Not exposed in libzstd. Never invoke directly ===
+ * ======================================================== */
+
/* === Memory management === */
typedef struct ZSTDMT_CCtx_s ZSTDMT_CCtx;
/* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */
-ZSTDMT_API ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbWorkers);
-/* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */
-ZSTDMT_API ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers,
- ZSTD_customMem cMem);
-ZSTDMT_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);
-
-ZSTDMT_API size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);
-
-
-/* === Simple one-pass compression function === */
-
-ZSTDMT_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- int compressionLevel);
-
+ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers,
+ ZSTD_customMem cMem,
+ ZSTD_threadPool *pool);
+size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);
+size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);
/* === Streaming functions === */
-ZSTDMT_API size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel);
-ZSTDMT_API size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize); /**< if srcSize is not known at reset time, use ZSTD_CONTENTSIZE_UNKNOWN. Note: for compatibility with older programs, 0 means the same as ZSTD_CONTENTSIZE_UNKNOWN, but it will change in the future to mean "empty" */
-
-ZSTDMT_API size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx);
-ZSTDMT_API size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
-
-ZSTDMT_API size_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */
-ZSTDMT_API size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */
-
-
-/* === Advanced functions and parameters === */
-
-ZSTDMT_API size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- const ZSTD_CDict* cdict,
- ZSTD_parameters params,
- int overlapLog);
-
-ZSTDMT_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
- const void* dict, size_t dictSize, /* dict can be released after init, a local copy is preserved within zcs */
- ZSTD_parameters params,
- unsigned long long pledgedSrcSize); /* pledgedSrcSize is optional and can be zero == unknown */
-
-ZSTDMT_API size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
- const ZSTD_CDict* cdict,
- ZSTD_frameParameters fparams,
- unsigned long long pledgedSrcSize); /* note : zero means empty */
-
-/* ZSTDMT_parameter :
- * List of parameters that can be set using ZSTDMT_setMTCtxParameter() */
-typedef enum {
- ZSTDMT_p_jobSize, /* Each job is compressed in parallel. By default, this value is dynamically determined depending on compression parameters. Can be set explicitly here. */
- ZSTDMT_p_overlapLog, /* Each job may reload a part of previous job to enhance compression ratio; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window. This is a "sticky" parameter : its value will be re-used on next compression job */
- ZSTDMT_p_rsyncable /* Enables rsyncable mode. */
-} ZSTDMT_parameter;
-
-/* ZSTDMT_setMTCtxParameter() :
- * allow setting individual parameters, one at a time, among a list of enums defined in ZSTDMT_parameter.
- * The function must be called typically after ZSTD_createCCtx() but __before ZSTDMT_init*() !__
- * Parameters not explicitly reset by ZSTDMT_init*() remain the same in consecutive compression sessions.
- * @return : 0, or an error code (which can be tested using ZSTD_isError()) */
-ZSTDMT_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int value);
-
-/* ZSTDMT_getMTCtxParameter() :
- * Query the ZSTDMT_CCtx for a parameter value.
- * @return : 0, or an error code (which can be tested using ZSTD_isError()) */
-ZSTDMT_API size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int* value);
+size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx);
+/*! ZSTDMT_initCStream_internal() :
+ * Private use only. Init streaming operation.
+ * expects params to be valid.
+ * must receive dict, or cdict, or none, but not both.
+ * @return : 0, or an error code */
+size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
+ const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
/*! ZSTDMT_compressStream_generic() :
* Combines ZSTDMT_compressStream() with optional ZSTDMT_flushStream() or ZSTDMT_endStream()
@@ -134,16 +78,10 @@ ZSTDMT_API size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter
* 0 if fully flushed
* or an error code
* note : needs to be init using any ZSTD_initCStream*() variant */
-ZSTDMT_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
- ZSTD_outBuffer* output,
- ZSTD_inBuffer* input,
- ZSTD_EndDirective endOp);
-
-
-/* ========================================================
- * === Private interface, for use by ZSTD_compress.c ===
- * === Not exposed in libzstd. Never invoke directly ===
- * ======================================================== */
+size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
+ ZSTD_outBuffer* output,
+ ZSTD_inBuffer* input,
+ ZSTD_EndDirective endOp);
/*! ZSTDMT_toFlushNow()
* Tell how many bytes are ready to be flushed immediately.
@@ -153,15 +91,6 @@ ZSTDMT_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
* therefore flushing is limited by speed of oldest job. */
size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx);
-/*! ZSTDMT_CCtxParam_setMTCtxParameter()
- * like ZSTDMT_setMTCtxParameter(), but into a ZSTD_CCtx_Params */
-size_t ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, int value);
-
-/*! ZSTDMT_CCtxParam_setNbWorkers()
- * Set nbWorkers, and clamp it.
- * Also reset jobSize and overlapLog */
-size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers);
-
/*! ZSTDMT_updateCParams_whileCompressing() :
* Updates only a selected set of compression parameters, to remain compatible with current frame.
* New parameters will be applied to next compression job. */
@@ -174,17 +103,6 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p
ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx);
-/*! ZSTDMT_initCStream_internal() :
- * Private use only. Init streaming operation.
- * expects params to be valid.
- * must receive dict, or cdict, or none, but not both.
- * @return : 0, or an error code */
-size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
- const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,
- const ZSTD_CDict* cdict,
- ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
-
-
#if defined (__cplusplus)
}
#endif
diff --git a/thirdparty/zstd/decompress/huf_decompress.c b/thirdparty/zstd/decompress/huf_decompress.c
index 68293a1309..1418206718 100644
--- a/thirdparty/zstd/decompress/huf_decompress.c
+++ b/thirdparty/zstd/decompress/huf_decompress.c
@@ -15,7 +15,7 @@
/* **************************************************************
* Dependencies
****************************************************************/
-#include <string.h> /* memcpy, memset */
+#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */
#include "../common/compiler.h"
#include "../common/bitstream.h" /* BIT_* */
#include "../common/fse.h" /* to compress headers */
@@ -103,7 +103,7 @@ typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved;
static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
{
DTableDesc dtd;
- memcpy(&dtd, table, sizeof(dtd));
+ ZSTD_memcpy(&dtd, table, sizeof(dtd));
return dtd;
}
@@ -115,29 +115,51 @@ static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
/*-***************************/
typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decoding */
+/**
+ * Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at
+ * a time.
+ */
+static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) {
+ U64 D4;
+ if (MEM_isLittleEndian()) {
+ D4 = symbol + (nbBits << 8);
+ } else {
+ D4 = (symbol << 8) + nbBits;
+ }
+ D4 *= 0x0001000100010001ULL;
+ return D4;
+}
+
+typedef struct {
+ U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
+ U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1];
+ U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
+ BYTE symbols[HUF_SYMBOLVALUE_MAX + 1];
+ BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
+} HUF_ReadDTableX1_Workspace;
+
+
size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize)
{
+ return HUF_readDTableX1_wksp_bmi2(DTable, src, srcSize, workSpace, wkspSize, /* bmi2 */ 0);
+}
+
+size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2)
+{
U32 tableLog = 0;
U32 nbSymbols = 0;
size_t iSize;
void* const dtPtr = DTable + 1;
HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr;
+ HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace;
- U32* rankVal;
- BYTE* huffWeight;
- size_t spaceUsed32 = 0;
-
- rankVal = (U32 *)workSpace + spaceUsed32;
- spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1;
- huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32);
- spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
-
- if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);
+ DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp));
+ if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge);
DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
- /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
+ /* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
- iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
+ iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), bmi2);
if (HUF_isError(iSize)) return iSize;
/* Table header */
@@ -145,52 +167,117 @@ size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize
if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */
dtd.tableType = 0;
dtd.tableLog = (BYTE)tableLog;
- memcpy(DTable, &dtd, sizeof(dtd));
+ ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
}
- /* Calculate starting value for each rank */
- { U32 n, nextRankStart = 0;
- for (n=1; n<tableLog+1; n++) {
- U32 const current = nextRankStart;
- nextRankStart += (rankVal[n] << (n-1));
- rankVal[n] = current;
- } }
+ /* Compute symbols and rankStart given rankVal:
+ *
+ * rankVal already contains the number of values of each weight.
+ *
+ * symbols contains the symbols ordered by weight. First are the rankVal[0]
+ * weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on.
+ * symbols[0] is filled (but unused) to avoid a branch.
+ *
+ * rankStart contains the offset where each rank belongs in the DTable.
+ * rankStart[0] is not filled because there are no entries in the table for
+ * weight 0.
+ */
+ {
+ int n;
+ int nextRankStart = 0;
+ int const unroll = 4;
+ int const nLimit = (int)nbSymbols - unroll + 1;
+ for (n=0; n<(int)tableLog+1; n++) {
+ U32 const curr = nextRankStart;
+ nextRankStart += wksp->rankVal[n];
+ wksp->rankStart[n] = curr;
+ }
+ for (n=0; n < nLimit; n += unroll) {
+ int u;
+ for (u=0; u < unroll; ++u) {
+ size_t const w = wksp->huffWeight[n+u];
+ wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u);
+ }
+ }
+ for (; n < (int)nbSymbols; ++n) {
+ size_t const w = wksp->huffWeight[n];
+ wksp->symbols[wksp->rankStart[w]++] = (BYTE)n;
+ }
+ }
- /* fill DTable */
- { U32 n;
- size_t const nEnd = nbSymbols;
- for (n=0; n<nEnd; n++) {
- size_t const w = huffWeight[n];
- size_t const length = (1 << w) >> 1;
- size_t const uStart = rankVal[w];
- size_t const uEnd = uStart + length;
- size_t u;
- HUF_DEltX1 D;
- D.byte = (BYTE)n;
- D.nbBits = (BYTE)(tableLog + 1 - w);
- rankVal[w] = (U32)uEnd;
- if (length < 4) {
- /* Use length in the loop bound so the compiler knows it is short. */
- for (u = 0; u < length; ++u)
- dt[uStart + u] = D;
- } else {
- /* Unroll the loop 4 times, we know it is a power of 2. */
- for (u = uStart; u < uEnd; u += 4) {
- dt[u + 0] = D;
- dt[u + 1] = D;
- dt[u + 2] = D;
- dt[u + 3] = D;
- } } } }
+ /* fill DTable
+ * We fill all entries of each weight in order.
+ * That way length is a constant for each iteration of the outter loop.
+ * We can switch based on the length to a different inner loop which is
+ * optimized for that particular case.
+ */
+ {
+ U32 w;
+ int symbol=wksp->rankVal[0];
+ int rankStart=0;
+ for (w=1; w<tableLog+1; ++w) {
+ int const symbolCount = wksp->rankVal[w];
+ int const length = (1 << w) >> 1;
+ int uStart = rankStart;
+ BYTE const nbBits = (BYTE)(tableLog + 1 - w);
+ int s;
+ int u;
+ switch (length) {
+ case 1:
+ for (s=0; s<symbolCount; ++s) {
+ HUF_DEltX1 D;
+ D.byte = wksp->symbols[symbol + s];
+ D.nbBits = nbBits;
+ dt[uStart] = D;
+ uStart += 1;
+ }
+ break;
+ case 2:
+ for (s=0; s<symbolCount; ++s) {
+ HUF_DEltX1 D;
+ D.byte = wksp->symbols[symbol + s];
+ D.nbBits = nbBits;
+ dt[uStart+0] = D;
+ dt[uStart+1] = D;
+ uStart += 2;
+ }
+ break;
+ case 4:
+ for (s=0; s<symbolCount; ++s) {
+ U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
+ MEM_write64(dt + uStart, D4);
+ uStart += 4;
+ }
+ break;
+ case 8:
+ for (s=0; s<symbolCount; ++s) {
+ U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
+ MEM_write64(dt + uStart, D4);
+ MEM_write64(dt + uStart + 4, D4);
+ uStart += 8;
+ }
+ break;
+ default:
+ for (s=0; s<symbolCount; ++s) {
+ U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
+ for (u=0; u < length; u += 16) {
+ MEM_write64(dt + uStart + u + 0, D4);
+ MEM_write64(dt + uStart + u + 4, D4);
+ MEM_write64(dt + uStart + u + 8, D4);
+ MEM_write64(dt + uStart + u + 12, D4);
+ }
+ assert(u == length);
+ uStart += length;
+ }
+ break;
+ }
+ symbol += symbolCount;
+ rankStart += symbolCount * length;
+ }
+ }
return iSize;
}
-size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize)
-{
- U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
- return HUF_readDTableX1_wksp(DTable, src, srcSize,
- workSpace, sizeof(workSpace));
-}
-
FORCE_INLINE_TEMPLATE BYTE
HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog)
{
@@ -389,20 +476,6 @@ size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
}
-size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
- const void* cSrc, size_t cSrcSize)
-{
- U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
- return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
- workSpace, sizeof(workSpace));
-}
-
-size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
-{
- HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
- return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
-}
-
size_t HUF_decompress4X1_usingDTable(
void* dst, size_t dstSize,
const void* cSrc, size_t cSrcSize,
@@ -419,8 +492,7 @@ static size_t HUF_decompress4X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size
{
const BYTE* ip = (const BYTE*) cSrc;
- size_t const hSize = HUF_readDTableX1_wksp (dctx, cSrc, cSrcSize,
- workSpace, wkspSize);
+ size_t const hSize = HUF_readDTableX1_wksp_bmi2(dctx, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
if (HUF_isError(hSize)) return hSize;
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
ip += hSize; cSrcSize -= hSize;
@@ -436,18 +508,6 @@ size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
}
-size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
-{
- U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
- return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
- workSpace, sizeof(workSpace));
-}
-size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
-{
- HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
- return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
-}
-
#endif /* HUF_FORCE_DECOMPRESS_X2 */
@@ -474,7 +534,7 @@ static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 co
U32 rankVal[HUF_TABLELOG_MAX + 1];
/* get pre-calculated rankVal */
- memcpy(rankVal, rankValOrigin, sizeof(rankVal));
+ ZSTD_memcpy(rankVal, rankValOrigin, sizeof(rankVal));
/* fill skipped values */
if (minWeight>1) {
@@ -516,7 +576,7 @@ static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
const U32 minBits = nbBitsBaseline - maxWeight;
U32 s;
- memcpy(rankVal, rankValOrigin, sizeof(rankVal));
+ ZSTD_memcpy(rankVal, rankValOrigin, sizeof(rankVal));
/* fill DTable */
for (s=0; s<sortedListSize; s++) {
@@ -581,11 +641,11 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);
rankStart = rankStart0 + 1;
- memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));
+ ZSTD_memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));
DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
- /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
+ /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
if (HUF_isError(iSize)) return iSize;
@@ -599,9 +659,9 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
/* Get start index of each weight */
{ U32 w, nextRankStart = 0;
for (w=1; w<maxW+1; w++) {
- U32 current = nextRankStart;
+ U32 curr = nextRankStart;
nextRankStart += rankStats[w];
- rankStart[w] = current;
+ rankStart[w] = curr;
}
rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
sizeOfSort = nextRankStart;
@@ -624,9 +684,9 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
U32 nextRankVal = 0;
U32 w;
for (w=1; w<maxW+1; w++) {
- U32 current = nextRankVal;
+ U32 curr = nextRankVal;
nextRankVal += rankStats[w] << (w+rescale);
- rankVal0[w] = current;
+ rankVal0[w] = curr;
} }
{ U32 const minBits = tableLog+1 - maxW;
U32 consumed;
@@ -644,23 +704,16 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
dtd.tableLog = (BYTE)maxTableLog;
dtd.tableType = 1;
- memcpy(DTable, &dtd, sizeof(dtd));
+ ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
return iSize;
}
-size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)
-{
- U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
- return HUF_readDTableX2_wksp(DTable, src, srcSize,
- workSpace, sizeof(workSpace));
-}
-
FORCE_INLINE_TEMPLATE U32
HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
{
size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
- memcpy(op, dt+val, 2);
+ ZSTD_memcpy(op, dt+val, 2);
BIT_skipBits(DStream, dt[val].nbBits);
return dt[val].length;
}
@@ -669,7 +722,7 @@ FORCE_INLINE_TEMPLATE U32
HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
{
size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
- memcpy(op, dt+val, 1);
+ ZSTD_memcpy(op, dt+val, 1);
if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
else {
if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
@@ -890,20 +943,6 @@ size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
}
-size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
- const void* cSrc, size_t cSrcSize)
-{
- U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
- return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
- workSpace, sizeof(workSpace));
-}
-
-size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
-{
- HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
- return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
-}
-
size_t HUF_decompress4X2_usingDTable(
void* dst, size_t dstSize,
const void* cSrc, size_t cSrcSize,
@@ -937,20 +976,6 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
}
-size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
- const void* cSrc, size_t cSrcSize)
-{
- U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
- return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
- workSpace, sizeof(workSpace));
-}
-
-size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
-{
- HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
- return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
-}
-
#endif /* HUF_FORCE_DECOMPRESS_X1 */
@@ -1051,67 +1076,6 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
}
-typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
-
-size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
-{
-#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
- static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 };
-#endif
-
- /* validation checks */
- if (dstSize == 0) return ERROR(dstSize_tooSmall);
- if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
- if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
- if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
-
- { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
-#if defined(HUF_FORCE_DECOMPRESS_X1)
- (void)algoNb;
- assert(algoNb == 0);
- return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize);
-#elif defined(HUF_FORCE_DECOMPRESS_X2)
- (void)algoNb;
- assert(algoNb == 1);
- return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize);
-#else
- return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
-#endif
- }
-}
-
-size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
-{
- /* validation checks */
- if (dstSize == 0) return ERROR(dstSize_tooSmall);
- if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
- if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
- if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
-
- { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
-#if defined(HUF_FORCE_DECOMPRESS_X1)
- (void)algoNb;
- assert(algoNb == 0);
- return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
-#elif defined(HUF_FORCE_DECOMPRESS_X2)
- (void)algoNb;
- assert(algoNb == 1);
- return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
-#else
- return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
- HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
-#endif
- }
-}
-
-size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
-{
- U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
- return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
- workSpace, sizeof(workSpace));
-}
-
-
size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst,
size_t dstSize, const void* cSrc,
size_t cSrcSize, void* workSpace,
@@ -1145,8 +1109,8 @@ size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
/* validation checks */
if (dstSize == 0) return ERROR(dstSize_tooSmall);
if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
- if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
- if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
+ if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
+ if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
{ U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
#if defined(HUF_FORCE_DECOMPRESS_X1)
@@ -1168,14 +1132,6 @@ size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
}
}
-size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
- const void* cSrc, size_t cSrcSize)
-{
- U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
- return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
- workSpace, sizeof(workSpace));
-}
-
size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2)
{
@@ -1199,7 +1155,7 @@ size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstS
{
const BYTE* ip = (const BYTE*) cSrc;
- size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize);
+ size_t const hSize = HUF_readDTableX1_wksp_bmi2(dctx, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
if (HUF_isError(hSize)) return hSize;
if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
ip += hSize; cSrcSize -= hSize;
@@ -1246,3 +1202,149 @@ size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t ds
#endif
}
}
+
+#ifndef ZSTD_NO_UNUSED_FUNCTIONS
+#ifndef HUF_FORCE_DECOMPRESS_X2
+size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize)
+{
+ U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
+ return HUF_readDTableX1_wksp(DTable, src, srcSize,
+ workSpace, sizeof(workSpace));
+}
+
+size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize)
+{
+ U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
+ return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
+ workSpace, sizeof(workSpace));
+}
+
+size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
+ return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
+}
+#endif
+
+#ifndef HUF_FORCE_DECOMPRESS_X1
+size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)
+{
+ U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
+ return HUF_readDTableX2_wksp(DTable, src, srcSize,
+ workSpace, sizeof(workSpace));
+}
+
+size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize)
+{
+ U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
+ return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
+ workSpace, sizeof(workSpace));
+}
+
+size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
+ return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
+}
+#endif
+
+#ifndef HUF_FORCE_DECOMPRESS_X2
+size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
+ return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
+ workSpace, sizeof(workSpace));
+}
+size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
+ return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
+}
+#endif
+
+#ifndef HUF_FORCE_DECOMPRESS_X1
+size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize)
+{
+ U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
+ return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
+ workSpace, sizeof(workSpace));
+}
+
+size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
+ return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
+}
+#endif
+
+typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
+
+size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
+ static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 };
+#endif
+
+ /* validation checks */
+ if (dstSize == 0) return ERROR(dstSize_tooSmall);
+ if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
+ if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
+ if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
+
+ { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
+#if defined(HUF_FORCE_DECOMPRESS_X1)
+ (void)algoNb;
+ assert(algoNb == 0);
+ return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize);
+#elif defined(HUF_FORCE_DECOMPRESS_X2)
+ (void)algoNb;
+ assert(algoNb == 1);
+ return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize);
+#else
+ return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
+#endif
+ }
+}
+
+size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ /* validation checks */
+ if (dstSize == 0) return ERROR(dstSize_tooSmall);
+ if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
+ if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
+ if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
+
+ { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
+#if defined(HUF_FORCE_DECOMPRESS_X1)
+ (void)algoNb;
+ assert(algoNb == 0);
+ return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
+#elif defined(HUF_FORCE_DECOMPRESS_X2)
+ (void)algoNb;
+ assert(algoNb == 1);
+ return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
+#else
+ return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
+ HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
+#endif
+ }
+}
+
+size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
+ return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
+ workSpace, sizeof(workSpace));
+}
+
+size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize)
+{
+ U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
+ return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
+ workSpace, sizeof(workSpace));
+}
+#endif
diff --git a/thirdparty/zstd/decompress/zstd_ddict.c b/thirdparty/zstd/decompress/zstd_ddict.c
index c8cb8ecc95..f5cc23b387 100644
--- a/thirdparty/zstd/decompress/zstd_ddict.c
+++ b/thirdparty/zstd/decompress/zstd_ddict.c
@@ -14,7 +14,7 @@
/*-*******************************************************
* Dependencies
*********************************************************/
-#include <string.h> /* memcpy, memmove, memset */
+#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
#include "../common/cpu.h" /* bmi2 */
#include "../common/mem.h" /* low level memory routines */
#define FSE_STATIC_LINKING_ONLY
@@ -127,11 +127,11 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict,
ddict->dictContent = dict;
if (!dict) dictSize = 0;
} else {
- void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem);
+ void* const internalBuffer = ZSTD_customMalloc(dictSize, ddict->cMem);
ddict->dictBuffer = internalBuffer;
ddict->dictContent = internalBuffer;
if (!internalBuffer) return ERROR(memory_allocation);
- memcpy(internalBuffer, dict, dictSize);
+ ZSTD_memcpy(internalBuffer, dict, dictSize);
}
ddict->dictSize = dictSize;
ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
@@ -147,9 +147,9 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
ZSTD_dictContentType_e dictContentType,
ZSTD_customMem customMem)
{
- if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
+ if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
- { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
+ { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_customMalloc(sizeof(ZSTD_DDict), customMem);
if (ddict == NULL) return NULL;
ddict->cMem = customMem;
{ size_t const initResult = ZSTD_initDDict_internal(ddict,
@@ -198,7 +198,7 @@ const ZSTD_DDict* ZSTD_initStaticDDict(
if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */
if (sBufferSize < neededSpace) return NULL;
if (dictLoadMethod == ZSTD_dlm_byCopy) {
- memcpy(ddict+1, dict, dictSize); /* local copy */
+ ZSTD_memcpy(ddict+1, dict, dictSize); /* local copy */
dict = ddict+1;
}
if (ZSTD_isError( ZSTD_initDDict_internal(ddict,
@@ -213,8 +213,8 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
{
if (ddict==NULL) return 0; /* support free on NULL */
{ ZSTD_customMem const cMem = ddict->cMem;
- ZSTD_free(ddict->dictBuffer, cMem);
- ZSTD_free(ddict, cMem);
+ ZSTD_customFree(ddict->dictBuffer, cMem);
+ ZSTD_customFree(ddict, cMem);
return 0;
}
}
diff --git a/thirdparty/zstd/decompress/zstd_ddict.h b/thirdparty/zstd/decompress/zstd_ddict.h
index af307efd3d..8906a71c94 100644
--- a/thirdparty/zstd/decompress/zstd_ddict.h
+++ b/thirdparty/zstd/decompress/zstd_ddict.h
@@ -15,7 +15,7 @@
/*-*******************************************************
* Dependencies
*********************************************************/
-#include <stddef.h> /* size_t */
+#include "../common/zstd_deps.h" /* size_t */
#include "../zstd.h" /* ZSTD_DDict, and several public functions */
diff --git a/thirdparty/zstd/decompress/zstd_decompress.c b/thirdparty/zstd/decompress/zstd_decompress.c
index be5c7cfc33..21f846bc77 100644
--- a/thirdparty/zstd/decompress/zstd_decompress.c
+++ b/thirdparty/zstd/decompress/zstd_decompress.c
@@ -55,7 +55,7 @@
/*-*******************************************************
* Dependencies
*********************************************************/
-#include <string.h> /* memcpy, memmove, memset */
+#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
#include "../common/cpu.h" /* bmi2 */
#include "../common/mem.h" /* low level memory routines */
#define FSE_STATIC_LINKING_ONLY
@@ -94,11 +94,18 @@ static size_t ZSTD_startingInputLength(ZSTD_format_e format)
return startingInputLength;
}
+static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
+{
+ assert(dctx->streamStage == zdss_init);
+ dctx->format = ZSTD_f_zstd1;
+ dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
+ dctx->outBufferMode = ZSTD_bm_buffered;
+ dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
+}
+
static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
{
- dctx->format = ZSTD_f_zstd1; /* ZSTD_decompressBegin() invokes ZSTD_startingInputLength() with argument dctx->format */
dctx->staticSize = 0;
- dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
dctx->ddict = NULL;
dctx->ddictLocal = NULL;
dctx->dictEnd = NULL;
@@ -113,7 +120,8 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
dctx->noForwardProgress = 0;
dctx->oversizedDuration = 0;
dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
- dctx->outBufferMode = ZSTD_obm_buffered;
+ ZSTD_DCtx_resetParameters(dctx);
+ dctx->validateChecksum = 1;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
dctx->dictContentEndForFuzzing = NULL;
#endif
@@ -134,9 +142,9 @@ ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
{
- if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
+ if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
- { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem);
+ { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem);
if (!dctx) return NULL;
dctx->customMem = customMem;
ZSTD_initDCtx_internal(dctx);
@@ -164,13 +172,13 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx");
{ ZSTD_customMem const cMem = dctx->customMem;
ZSTD_clearDict(dctx);
- ZSTD_free(dctx->inBuff, cMem);
+ ZSTD_customFree(dctx->inBuff, cMem);
dctx->inBuff = NULL;
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
if (dctx->legacyContext)
ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion);
#endif
- ZSTD_free(dctx, cMem);
+ ZSTD_customFree(dctx, cMem);
return 0;
}
}
@@ -179,7 +187,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
{
size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx);
- memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */
+ ZSTD_memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */
}
@@ -246,7 +254,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
const BYTE* ip = (const BYTE*)src;
size_t const minInputSize = ZSTD_startingInputLength(format);
- memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */
+ ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */
if (srcSize < minInputSize) return minInputSize;
RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter");
@@ -256,7 +264,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
/* skippable frame */
if (srcSize < ZSTD_SKIPPABLEHEADERSIZE)
return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */
- memset(zfhPtr, 0, sizeof(*zfhPtr));
+ ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr));
zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
zfhPtr->frameType = ZSTD_skippableFrame;
return 0;
@@ -446,7 +454,8 @@ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t he
RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID),
dictionary_wrong, "");
#endif
- if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
+ dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0;
+ if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0);
return 0;
}
@@ -461,7 +470,7 @@ static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)
{
ZSTD_frameSizeInfo frameSizeInfo;
- memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
+ ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
if (ZSTD_isLegacy(src, srcSize))
@@ -516,7 +525,7 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
ip += 4;
}
- frameSizeInfo.compressedSize = ip - ipstart;
+ frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
? zfh.frameContentSize
: nbBlocks * zfh.blockSizeMax;
@@ -579,12 +588,12 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
const void* src, size_t srcSize)
{
DEBUGLOG(5, "ZSTD_copyRawBlock");
+ RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, "");
if (dst == NULL) {
if (srcSize == 0) return 0;
RETURN_ERROR(dstBuffer_null, "");
}
- RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, "");
- memcpy(dst, src, srcSize);
+ ZSTD_memcpy(dst, src, srcSize);
return srcSize;
}
@@ -592,12 +601,12 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
BYTE b,
size_t regenSize)
{
+ RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, "");
if (dst == NULL) {
if (regenSize == 0) return 0;
RETURN_ERROR(dstBuffer_null, "");
}
- RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, "");
- memset(dst, b, regenSize);
+ ZSTD_memset(dst, b, regenSize);
return regenSize;
}
@@ -647,13 +656,13 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
switch(blockProperties.blockType)
{
case bt_compressed:
- decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize, /* frame */ 1);
+ decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1);
break;
case bt_raw :
- decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
+ decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
break;
case bt_rle :
- decodedSize = ZSTD_setRleBlock(op, oend-op, *ip, blockProperties.origSize);
+ decodedSize = ZSTD_setRleBlock(op, (size_t)(oend-op), *ip, blockProperties.origSize);
break;
case bt_reserved :
default:
@@ -661,7 +670,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
}
if (ZSTD_isError(decodedSize)) return decodedSize;
- if (dctx->fParams.checksumFlag)
+ if (dctx->validateChecksum)
XXH64_update(&dctx->xxhState, op, decodedSize);
if (decodedSize != 0)
op += decodedSize;
@@ -676,11 +685,13 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
corruption_detected, "");
}
if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
- U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
- U32 checkRead;
RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, "");
- checkRead = MEM_readLE32(ip);
- RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, "");
+ if (!dctx->forceIgnoreChecksum) {
+ U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
+ U32 checkRead;
+ checkRead = MEM_readLE32(ip);
+ RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, "");
+ }
ip += 4;
remainingSrcSize -= 4;
}
@@ -688,7 +699,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
/* Allow caller to get size read */
*srcPtr = ip;
*srcSizePtr = remainingSrcSize;
- return op-ostart;
+ return (size_t)(op-ostart);
}
static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
@@ -721,7 +732,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
if (ZSTD_isError(decodedSize)) return decodedSize;
- assert(decodedSize <=- dstCapacity);
+ assert(decodedSize <= dstCapacity);
dst = (BYTE*)dst + decodedSize;
dstCapacity -= decodedSize;
@@ -761,15 +772,13 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
(ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown)
&& (moreThan1Frame==1),
srcSize_wrong,
- "at least one frame successfully completed, but following "
- "bytes are garbage: it's more likely to be a srcSize error, "
- "specifying more bytes than compressed size of frame(s). This "
- "error message replaces ERROR(prefix_unknown), which would be "
- "confusing, as the first header is actually correct. Note that "
- "one could be unlucky, it might be a corruption error instead, "
- "happening right at the place where we expect zstd magic "
- "bytes. But this is _much_ less likely than a srcSize field "
- "error.");
+ "At least one frame successfully completed, "
+ "but following bytes are garbage: "
+ "it's more likely to be a srcSize error, "
+ "specifying more input bytes than size of frame(s). "
+ "Note: one could be unlucky, it might be a corruption error instead, "
+ "happening right at the place where we expect zstd magic bytes. "
+ "But this is _much_ less likely than a srcSize field error.");
if (ZSTD_isError(res)) return res;
assert(res <= dstCapacity);
if (res != 0)
@@ -781,7 +790,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed");
- return (BYTE*)dst - (BYTE*)dststart;
+ return (size_t)((BYTE*)dst - (BYTE*)dststart);
}
size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
@@ -899,21 +908,21 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
if (dctx->format == ZSTD_f_zstd1) { /* allows header */
assert(srcSize >= ZSTD_FRAMEIDSIZE); /* to read skippable magic number */
if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
- memcpy(dctx->headerBuffer, src, srcSize);
+ ZSTD_memcpy(dctx->headerBuffer, src, srcSize);
dctx->expected = ZSTD_SKIPPABLEHEADERSIZE - srcSize; /* remaining to load to get full skippable frame header */
dctx->stage = ZSTDds_decodeSkippableHeader;
return 0;
} }
dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format);
if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
- memcpy(dctx->headerBuffer, src, srcSize);
+ ZSTD_memcpy(dctx->headerBuffer, src, srcSize);
dctx->expected = dctx->headerSize - srcSize;
dctx->stage = ZSTDds_decodeFrameHeader;
return 0;
case ZSTDds_decodeFrameHeader:
assert(src != NULL);
- memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
+ ZSTD_memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize), "");
dctx->expected = ZSTD_blockHeaderSize;
dctx->stage = ZSTDds_decodeBlockHeader;
@@ -977,7 +986,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, "Decompressed Block Size Exceeds Maximum");
DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize);
dctx->decodedSize += rSize;
- if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
+ if (dctx->validateChecksum) XXH64_update(&dctx->xxhState, dst, rSize);
dctx->previousDstEnd = (char*)dst + rSize;
/* Stay on the same stage until we are finished streaming the block. */
@@ -1007,10 +1016,13 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
case ZSTDds_checkChecksum:
assert(srcSize == 4); /* guaranteed by dctx->expected */
- { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
- U32 const check32 = MEM_readLE32(src);
- DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
- RETURN_ERROR_IF(check32 != h32, checksum_wrong, "");
+ {
+ if (dctx->validateChecksum) {
+ U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
+ U32 const check32 = MEM_readLE32(src);
+ DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
+ RETURN_ERROR_IF(check32 != h32, checksum_wrong, "");
+ }
dctx->expected = 0;
dctx->stage = ZSTDds_getFrameHeaderSize;
return 0;
@@ -1019,7 +1031,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
case ZSTDds_decodeSkippableHeader:
assert(src != NULL);
assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);
- memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */
+ ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */
dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */
dctx->stage = ZSTDds_skipFrame;
return 0;
@@ -1075,7 +1087,7 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
workspace, workspaceSize);
#else
size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,
- dictPtr, dictEnd - dictPtr,
+ dictPtr, (size_t)(dictEnd - dictPtr),
workspace, workspaceSize);
#endif
RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, "");
@@ -1084,40 +1096,46 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
{ short offcodeNCount[MaxOff+1];
unsigned offcodeMaxValue = MaxOff, offcodeLog;
- size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
+ size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr));
RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, "");
RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
ZSTD_buildFSETable( entropy->OFTable,
offcodeNCount, offcodeMaxValue,
OF_base, OF_bits,
- offcodeLog);
+ offcodeLog,
+ entropy->workspace, sizeof(entropy->workspace),
+ /* bmi2 */0);
dictPtr += offcodeHeaderSize;
}
{ short matchlengthNCount[MaxML+1];
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
- size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
+ size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, "");
RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
ZSTD_buildFSETable( entropy->MLTable,
matchlengthNCount, matchlengthMaxValue,
ML_base, ML_bits,
- matchlengthLog);
+ matchlengthLog,
+ entropy->workspace, sizeof(entropy->workspace),
+ /* bmi2 */ 0);
dictPtr += matchlengthHeaderSize;
}
{ short litlengthNCount[MaxLL+1];
unsigned litlengthMaxValue = MaxLL, litlengthLog;
- size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
+ size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, "");
RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
ZSTD_buildFSETable( entropy->LLTable,
litlengthNCount, litlengthMaxValue,
LL_base, LL_bits,
- litlengthLog);
+ litlengthLog,
+ entropy->workspace, sizeof(entropy->workspace),
+ /* bmi2 */ 0);
dictPtr += litlengthHeaderSize;
}
@@ -1131,7 +1149,7 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
entropy->rep[i] = rep;
} }
- return dictPtr - (const BYTE*)dict;
+ return (size_t)(dictPtr - (const BYTE*)dict);
}
static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
@@ -1170,7 +1188,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
dctx->dictID = 0;
dctx->bType = bt_reserved;
ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
- memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
+ ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
dctx->LLTptr = dctx->entropy.LLTable;
dctx->MLTptr = dctx->entropy.MLTable;
dctx->OFTptr = dctx->entropy.OFTable;
@@ -1394,7 +1412,7 @@ size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format)
{
- return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, format);
+ return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, (int)format);
}
ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
@@ -1411,8 +1429,12 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
return bounds;
case ZSTD_d_stableOutBuffer:
- bounds.lowerBound = (int)ZSTD_obm_buffered;
- bounds.upperBound = (int)ZSTD_obm_stable;
+ bounds.lowerBound = (int)ZSTD_bm_buffered;
+ bounds.upperBound = (int)ZSTD_bm_stable;
+ return bounds;
+ case ZSTD_d_forceIgnoreChecksum:
+ bounds.lowerBound = (int)ZSTD_d_validateChecksum;
+ bounds.upperBound = (int)ZSTD_d_ignoreChecksum;
return bounds;
default:;
}
@@ -1436,6 +1458,26 @@ static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)
RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound, ""); \
}
+size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value)
+{
+ switch (param) {
+ case ZSTD_d_windowLogMax:
+ *value = (int)ZSTD_highbit32((U32)dctx->maxWindowSize);
+ return 0;
+ case ZSTD_d_format:
+ *value = (int)dctx->format;
+ return 0;
+ case ZSTD_d_stableOutBuffer:
+ *value = (int)dctx->outBufferMode;
+ return 0;
+ case ZSTD_d_forceIgnoreChecksum:
+ *value = (int)dctx->forceIgnoreChecksum;
+ return 0;
+ default:;
+ }
+ RETURN_ERROR(parameter_unsupported, "");
+}
+
size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)
{
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
@@ -1451,7 +1493,11 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
return 0;
case ZSTD_d_stableOutBuffer:
CHECK_DBOUNDS(ZSTD_d_stableOutBuffer, value);
- dctx->outBufferMode = (ZSTD_outBufferMode_e)value;
+ dctx->outBufferMode = (ZSTD_bufferMode_e)value;
+ return 0;
+ case ZSTD_d_forceIgnoreChecksum:
+ CHECK_DBOUNDS(ZSTD_d_forceIgnoreChecksum, value);
+ dctx->forceIgnoreChecksum = (ZSTD_forceIgnoreChecksum_e)value;
return 0;
default:;
}
@@ -1469,8 +1515,7 @@ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
|| (reset == ZSTD_reset_session_and_parameters) ) {
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
ZSTD_clearDict(dctx);
- dctx->format = ZSTD_f_zstd1;
- dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
+ ZSTD_DCtx_resetParameters(dctx);
}
return 0;
}
@@ -1524,7 +1569,7 @@ static void ZSTD_DCtx_updateOversizedDuration(ZSTD_DStream* zds, size_t const ne
{
if (ZSTD_DCtx_isOverflow(zds, neededInBuffSize, neededOutBuffSize))
zds->oversizedDuration++;
- else
+ else
zds->oversizedDuration = 0;
}
@@ -1538,7 +1583,7 @@ static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const*
{
ZSTD_outBuffer const expect = zds->expectedOutBuffer;
/* No requirement when ZSTD_obm_stable is not enabled. */
- if (zds->outBufferMode != ZSTD_obm_stable)
+ if (zds->outBufferMode != ZSTD_bm_stable)
return 0;
/* Any buffer is allowed in zdss_init, this must be the same for every other call until
* the context is reset.
@@ -1548,7 +1593,7 @@ static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const*
/* The buffer must match our expectation exactly. */
if (expect.dst == output->dst && expect.pos == output->pos && expect.size == output->size)
return 0;
- RETURN_ERROR(dstBuffer_wrong, "ZSTD_obm_stable enabled but output differs!");
+ RETURN_ERROR(dstBuffer_wrong, "ZSTD_d_stableOutBuffer enabled but output differs!");
}
/* Calls ZSTD_decompressContinue() with the right parameters for ZSTD_decompressStream()
@@ -1560,7 +1605,7 @@ static size_t ZSTD_decompressContinueStream(
ZSTD_DStream* zds, char** op, char* oend,
void const* src, size_t srcSize) {
int const isSkipFrame = ZSTD_isSkipFrame(zds);
- if (zds->outBufferMode == ZSTD_obm_buffered) {
+ if (zds->outBufferMode == ZSTD_bm_buffered) {
size_t const dstSize = isSkipFrame ? 0 : zds->outBuffSize - zds->outStart;
size_t const decodedSize = ZSTD_decompressContinue(zds,
zds->outBuff + zds->outStart, dstSize, src, srcSize);
@@ -1573,14 +1618,14 @@ static size_t ZSTD_decompressContinueStream(
}
} else {
/* Write directly into the output buffer */
- size_t const dstSize = isSkipFrame ? 0 : oend - *op;
+ size_t const dstSize = isSkipFrame ? 0 : (size_t)(oend - *op);
size_t const decodedSize = ZSTD_decompressContinue(zds, *op, dstSize, src, srcSize);
FORWARD_IF_ERROR(decodedSize, "");
*op += decodedSize;
/* Flushing is not needed. */
zds->streamStage = zdss_read;
assert(*op <= oend);
- assert(zds->outBufferMode == ZSTD_obm_stable);
+ assert(zds->outBufferMode == ZSTD_bm_stable);
}
return 0;
}
@@ -1663,14 +1708,14 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
assert(iend >= ip);
if (toLoad > remainingInput) { /* not enough input to load full header */
if (remainingInput > 0) {
- memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput);
+ ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput);
zds->lhSize += remainingInput;
}
input->pos = input->size;
return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
}
assert(ip != NULL);
- memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
+ ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
break;
} }
@@ -1678,10 +1723,10 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
&& zds->fParams.frameType != ZSTD_skippableFrame
&& (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
- size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
+ size_t const cSize = ZSTD_findFrameCompressedSize(istart, (size_t)(iend-istart));
if (cSize <= (size_t)(iend-istart)) {
/* shortcut : using single-pass mode */
- size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, ZSTD_getDDict(zds));
+ size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
if (ZSTD_isError(decompressedSize)) return decompressedSize;
DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
ip = istart + cSize;
@@ -1693,7 +1738,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
} }
/* Check output buffer is large enough for ZSTD_odm_stable. */
- if (zds->outBufferMode == ZSTD_obm_stable
+ if (zds->outBufferMode == ZSTD_bm_stable
&& zds->fParams.frameType != ZSTD_skippableFrame
&& zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
&& (U64)(size_t)(oend-op) < zds->fParams.frameContentSize) {
@@ -1723,7 +1768,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
/* Adapt buffer sizes to frame header instructions */
{ size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
- size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_obm_buffered
+ size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered
? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize)
: 0;
@@ -1731,7 +1776,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
{ int const tooSmall = (zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize);
int const tooLarge = ZSTD_DCtx_isOversizedTooLong(zds);
-
+
if (tooSmall || tooLarge) {
size_t const bufferSize = neededInBuffSize + neededOutBuffSize;
DEBUGLOG(4, "inBuff : from %u to %u",
@@ -1745,10 +1790,10 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),
memory_allocation, "");
} else {
- ZSTD_free(zds->inBuff, zds->customMem);
+ ZSTD_customFree(zds->inBuff, zds->customMem);
zds->inBuffSize = 0;
zds->outBuffSize = 0;
- zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);
+ zds->inBuff = (char*)ZSTD_customMalloc(bufferSize, zds->customMem);
RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation, "");
}
zds->inBuffSize = neededInBuffSize;
@@ -1760,7 +1805,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
case zdss_read:
DEBUGLOG(5, "stage zdss_read");
- { size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, iend - ip);
+ { size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip));
DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize);
if (neededInSize==0) { /* end of frame */
zds->streamStage = zdss_init;
@@ -1790,7 +1835,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos,
corruption_detected,
"should never happen");
- loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);
+ loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
}
ip += loadedSize;
zds->inPos += loadedSize;
@@ -1804,7 +1849,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
}
case zdss_flush:
{ size_t const toFlushSize = zds->outEnd - zds->outStart;
- size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
+ size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize);
op += flushedSize;
zds->outStart += flushedSize;
if (flushedSize == toFlushSize) { /* flush completed */
diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.c b/thirdparty/zstd/decompress/zstd_decompress_block.c
index ad3b3d8dbd..19cbdc5c16 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_block.c
+++ b/thirdparty/zstd/decompress/zstd_decompress_block.c
@@ -14,7 +14,7 @@
/*-*******************************************************
* Dependencies
*********************************************************/
-#include <string.h> /* memcpy, memmove, memset */
+#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
#include "../common/compiler.h" /* prefetch */
#include "../common/cpu.h" /* bmi2 */
#include "../common/mem.h" /* low level memory routines */
@@ -44,7 +44,7 @@
/*_*******************************************************
* Memory operations
**********************************************************/
-static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
+static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); }
/*-*************************************************************
@@ -166,7 +166,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
dctx->litSize = litSize;
dctx->litEntropy = 1;
if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;
- memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
+ ZSTD_memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
return litCSize + lhSize;
}
@@ -191,10 +191,10 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, "");
- memcpy(dctx->litBuffer, istart+lhSize, litSize);
+ ZSTD_memcpy(dctx->litBuffer, istart+lhSize, litSize);
dctx->litPtr = dctx->litBuffer;
dctx->litSize = litSize;
- memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
+ ZSTD_memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
return lhSize+litSize;
}
/* direct reference into compressed stream */
@@ -223,7 +223,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
break;
}
RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
- memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
+ ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
dctx->litPtr = dctx->litBuffer;
dctx->litSize = litSize;
return lhSize+1;
@@ -236,7 +236,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
/* Default FSE distribution tables.
* These are pre-calculated FSE decoding tables using default distributions as defined in specification :
- * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#default-distributions
+ * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions
* They were generated programmatically with following method :
* - start from default distributions, present in /lib/common/zstd_internal.h
* - generate tables normally, using ZSTD_buildFSETable()
@@ -364,23 +364,26 @@ static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddB
* generate FSE decoding table for one symbol (ll, ml or off)
* cannot fail if input is valid =>
* all inputs are presumed validated at this stage */
-void
-ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
+FORCE_INLINE_TEMPLATE
+void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
const short* normalizedCounter, unsigned maxSymbolValue,
const U32* baseValue, const U32* nbAdditionalBits,
- unsigned tableLog)
+ unsigned tableLog, void* wksp, size_t wkspSize)
{
ZSTD_seqSymbol* const tableDecode = dt+1;
- U16 symbolNext[MaxSeq+1];
-
U32 const maxSV1 = maxSymbolValue + 1;
U32 const tableSize = 1 << tableLog;
- U32 highThreshold = tableSize-1;
+
+ U16* symbolNext = (U16*)wksp;
+ BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1);
+ U32 highThreshold = tableSize - 1;
+
/* Sanity Checks */
assert(maxSymbolValue <= MaxSeq);
assert(tableLog <= MaxFSELog);
-
+ assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE);
+ (void)wkspSize;
/* Init, lay down lowprob symbols */
{ ZSTD_seqSymbol_header DTableH;
DTableH.tableLog = tableLog;
@@ -396,16 +399,69 @@ ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
assert(normalizedCounter[s]>=0);
symbolNext[s] = (U16)normalizedCounter[s];
} } }
- memcpy(dt, &DTableH, sizeof(DTableH));
+ ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
}
/* Spread symbols */
- { U32 const tableMask = tableSize-1;
+ assert(tableSize <= 512);
+ /* Specialized symbol spreading for the case when there are
+ * no low probability (-1 count) symbols. When compressing
+ * small blocks we avoid low probability symbols to hit this
+ * case, since header decoding speed matters more.
+ */
+ if (highThreshold == tableSize - 1) {
+ size_t const tableMask = tableSize-1;
+ size_t const step = FSE_TABLESTEP(tableSize);
+ /* First lay down the symbols in order.
+ * We use a uint64_t to lay down 8 bytes at a time. This reduces branch
+ * misses since small blocks generally have small table logs, so nearly
+ * all symbols have counts <= 8. We ensure we have 8 bytes at the end of
+ * our buffer to handle the over-write.
+ */
+ {
+ U64 const add = 0x0101010101010101ull;
+ size_t pos = 0;
+ U64 sv = 0;
+ U32 s;
+ for (s=0; s<maxSV1; ++s, sv += add) {
+ int i;
+ int const n = normalizedCounter[s];
+ MEM_write64(spread + pos, sv);
+ for (i = 8; i < n; i += 8) {
+ MEM_write64(spread + pos + i, sv);
+ }
+ pos += n;
+ }
+ }
+ /* Now we spread those positions across the table.
+ * The benefit of doing it in two stages is that we avoid the the
+ * variable size inner loop, which caused lots of branch misses.
+ * Now we can run through all the positions without any branch misses.
+ * We unroll the loop twice, since that is what emperically worked best.
+ */
+ {
+ size_t position = 0;
+ size_t s;
+ size_t const unroll = 2;
+ assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
+ for (s = 0; s < (size_t)tableSize; s += unroll) {
+ size_t u;
+ for (u = 0; u < unroll; ++u) {
+ size_t const uPosition = (position + (u * step)) & tableMask;
+ tableDecode[uPosition].baseValue = spread[s + u];
+ }
+ position = (position + (unroll * step)) & tableMask;
+ }
+ assert(position == 0);
+ }
+ } else {
+ U32 const tableMask = tableSize-1;
U32 const step = FSE_TABLESTEP(tableSize);
U32 s, position = 0;
for (s=0; s<maxSV1; s++) {
int i;
- for (i=0; i<normalizedCounter[s]; i++) {
+ int const n = normalizedCounter[s];
+ for (i=0; i<n; i++) {
tableDecode[position].baseValue = s;
position = (position + step) & tableMask;
while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
@@ -414,7 +470,8 @@ ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
}
/* Build Decoding table */
- { U32 u;
+ {
+ U32 u;
for (u=0; u<tableSize; u++) {
U32 const symbol = tableDecode[u].baseValue;
U32 const nextState = symbolNext[symbol]++;
@@ -423,7 +480,46 @@ ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
assert(nbAdditionalBits[symbol] < 255);
tableDecode[u].nbAdditionalBits = (BYTE)nbAdditionalBits[symbol];
tableDecode[u].baseValue = baseValue[symbol];
- } }
+ }
+ }
+}
+
+/* Avoids the FORCE_INLINE of the _body() function. */
+static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt,
+ const short* normalizedCounter, unsigned maxSymbolValue,
+ const U32* baseValue, const U32* nbAdditionalBits,
+ unsigned tableLog, void* wksp, size_t wkspSize)
+{
+ ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue,
+ baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
+}
+
+#if DYNAMIC_BMI2
+TARGET_ATTRIBUTE("bmi2") static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt,
+ const short* normalizedCounter, unsigned maxSymbolValue,
+ const U32* baseValue, const U32* nbAdditionalBits,
+ unsigned tableLog, void* wksp, size_t wkspSize)
+{
+ ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue,
+ baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
+}
+#endif
+
+void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
+ const short* normalizedCounter, unsigned maxSymbolValue,
+ const U32* baseValue, const U32* nbAdditionalBits,
+ unsigned tableLog, void* wksp, size_t wkspSize, int bmi2)
+{
+#if DYNAMIC_BMI2
+ if (bmi2) {
+ ZSTD_buildFSETable_body_bmi2(dt, normalizedCounter, maxSymbolValue,
+ baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
+ return;
+ }
+#endif
+ (void)bmi2;
+ ZSTD_buildFSETable_body_default(dt, normalizedCounter, maxSymbolValue,
+ baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
}
@@ -435,7 +531,8 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
const void* src, size_t srcSize,
const U32* baseValue, const U32* nbAdditionalBits,
const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable,
- int ddictIsCold, int nbSeq)
+ int ddictIsCold, int nbSeq, U32* wksp, size_t wkspSize,
+ int bmi2)
{
switch(type)
{
@@ -467,7 +564,7 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected, "");
RETURN_ERROR_IF(tableLog > maxLog, corruption_detected, "");
- ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog);
+ ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog, wksp, wkspSize, bmi2);
*DTablePtr = DTableSpace;
return headerSize;
}
@@ -499,7 +596,8 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
if (nbSeq > 0x7F) {
if (nbSeq == 0xFF) {
RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, "");
- nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
+ nbSeq = MEM_readLE16(ip) + LONGNBSEQ;
+ ip+=2;
} else {
RETURN_ERROR_IF(ip >= iend, srcSize_wrong, "");
nbSeq = ((nbSeq-0x80)<<8) + *ip++;
@@ -520,7 +618,9 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
ip, iend-ip,
LL_base, LL_bits,
LL_defaultDTable, dctx->fseEntropy,
- dctx->ddictIsCold, nbSeq);
+ dctx->ddictIsCold, nbSeq,
+ dctx->workspace, sizeof(dctx->workspace),
+ dctx->bmi2);
RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += llhSize;
}
@@ -530,7 +630,9 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
ip, iend-ip,
OF_base, OF_bits,
OF_defaultDTable, dctx->fseEntropy,
- dctx->ddictIsCold, nbSeq);
+ dctx->ddictIsCold, nbSeq,
+ dctx->workspace, sizeof(dctx->workspace),
+ dctx->bmi2);
RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += ofhSize;
}
@@ -540,7 +642,9 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
ip, iend-ip,
ML_base, ML_bits,
ML_defaultDTable, dctx->fseEntropy,
- dctx->ddictIsCold, nbSeq);
+ dctx->ddictIsCold, nbSeq,
+ dctx->workspace, sizeof(dctx->workspace),
+ dctx->bmi2);
RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed");
ip += mlhSize;
}
@@ -686,12 +790,12 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, "");
match = dictEnd - (prefixStart-match);
if (match + sequence.matchLength <= dictEnd) {
- memmove(oLitEnd, match, sequence.matchLength);
+ ZSTD_memmove(oLitEnd, match, sequence.matchLength);
return sequenceLength;
}
/* span extDict & currentPrefixSegment */
{ size_t const length1 = dictEnd - match;
- memmove(oLitEnd, match, length1);
+ ZSTD_memmove(oLitEnd, match, length1);
op = oLitEnd + length1;
sequence.matchLength -= length1;
match = prefixStart;
@@ -752,12 +856,12 @@ size_t ZSTD_execSequence(BYTE* op,
RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, "");
match = dictEnd + (match - prefixStart);
if (match + sequence.matchLength <= dictEnd) {
- memmove(oLitEnd, match, sequence.matchLength);
+ ZSTD_memmove(oLitEnd, match, sequence.matchLength);
return sequenceLength;
}
/* span extDict & currentPrefixSegment */
{ size_t const length1 = dictEnd - match;
- memmove(oLitEnd, match, length1);
+ ZSTD_memmove(oLitEnd, match, length1);
op = oLitEnd + length1;
sequence.matchLength -= length1;
match = prefixStart;
@@ -948,7 +1052,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c
}
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
-static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd)
+MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd)
{
size_t const windowSize = dctx->fParams.windowSize;
/* No dictionary used. */
@@ -969,6 +1073,7 @@ MEM_STATIC void ZSTD_assertValidSequence(
seq_t const seq,
BYTE const* prefixStart, BYTE const* virtualStart)
{
+#if DEBUGLEVEL >= 1
size_t const windowSize = dctx->fParams.windowSize;
size_t const sequenceSize = seq.litLength + seq.matchLength;
BYTE const* const oLitEnd = op + seq.litLength;
@@ -986,6 +1091,9 @@ MEM_STATIC void ZSTD_assertValidSequence(
/* Offset must be within our window. */
assert(seq.offset <= windowSize);
}
+#else
+ (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart;
+#endif
}
#endif
@@ -1080,14 +1188,14 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
#endif
DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
BIT_reloadDStream(&(seqState.DStream));
+ op += oneSeqSize;
/* gcc and clang both don't like early returns in this loop.
- * gcc doesn't like early breaks either.
- * Instead save an error and report it at the end.
- * When there is an error, don't increment op, so we don't
- * overwrite.
+ * Instead break and check for an error at the end of the loop.
*/
- if (UNLIKELY(ZSTD_isError(oneSeqSize))) error = oneSeqSize;
- else op += oneSeqSize;
+ if (UNLIKELY(ZSTD_isError(oneSeqSize))) {
+ error = oneSeqSize;
+ break;
+ }
if (UNLIKELY(!--nbSeq)) break;
}
@@ -1104,7 +1212,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
{ size_t const lastLLSize = litEnd - litPtr;
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
if (op != NULL) {
- memcpy(op, litPtr, lastLLSize);
+ ZSTD_memcpy(op, litPtr, lastLLSize);
op += lastLLSize;
}
}
@@ -1209,7 +1317,7 @@ ZSTD_decompressSequencesLong_body(
{ size_t const lastLLSize = litEnd - litPtr;
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
if (op != NULL) {
- memcpy(op, litPtr, lastLLSize);
+ ZSTD_memcpy(op, litPtr, lastLLSize);
op += lastLLSize;
}
}
diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.h b/thirdparty/zstd/decompress/zstd_decompress_block.h
index bf39b7350c..b5715c168e 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_block.h
+++ b/thirdparty/zstd/decompress/zstd_decompress_block.h
@@ -15,7 +15,7 @@
/*-*******************************************************
* Dependencies
*********************************************************/
-#include <stddef.h> /* size_t */
+#include "../common/zstd_deps.h" /* size_t */
#include "../zstd.h" /* DCtx, and some public functions */
#include "../common/zstd_internal.h" /* blockProperties_t, and some public functions */
#include "zstd_decompress_internal.h" /* ZSTD_seqSymbol */
@@ -48,12 +48,15 @@ size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
* this function must be called with valid parameters only
* (dt is large enough, normalizedCounter distribution total is a power of 2, max is within range, etc.)
* in which case it cannot fail.
+ * The workspace must be 4-byte aligned and at least ZSTD_BUILD_FSE_TABLE_WKSP_SIZE bytes, which is
+ * defined in zstd_decompress_internal.h.
* Internal use only.
*/
void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
const short* normalizedCounter, unsigned maxSymbolValue,
const U32* baseValue, const U32* nbAdditionalBits,
- unsigned tableLog);
+ unsigned tableLog, void* wksp, size_t wkspSize,
+ int bmi2);
#endif /* ZSTD_DEC_BLOCK_H */
diff --git a/thirdparty/zstd/decompress/zstd_decompress_internal.h b/thirdparty/zstd/decompress/zstd_decompress_internal.h
index 9ad96c5548..f80b471e99 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_internal.h
+++ b/thirdparty/zstd/decompress/zstd_decompress_internal.h
@@ -27,26 +27,26 @@
/*-*******************************************************
* Constants
*********************************************************/
-static const U32 LL_base[MaxLL+1] = {
+static UNUSED_ATTR const U32 LL_base[MaxLL+1] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 18, 20, 22, 24, 28, 32, 40,
48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
0x2000, 0x4000, 0x8000, 0x10000 };
-static const U32 OF_base[MaxOff+1] = {
+static UNUSED_ATTR const U32 OF_base[MaxOff+1] = {
0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
-static const U32 OF_bits[MaxOff+1] = {
+static UNUSED_ATTR const U32 OF_bits[MaxOff+1] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31 };
-static const U32 ML_base[MaxML+1] = {
+static UNUSED_ATTR const U32 ML_base[MaxML+1] = {
3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26,
@@ -73,12 +73,16 @@ static const U32 ML_base[MaxML+1] = {
#define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log)))
+#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE (sizeof(S16) * (MaxSeq + 1) + (1u << MaxFSELog) + sizeof(U64))
+#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32 ((ZSTD_BUILD_FSE_TABLE_WKSP_SIZE + sizeof(U32) - 1) / sizeof(U32))
+
typedef struct {
ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */
ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */
ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */
HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
U32 rep[ZSTD_REP_NUM];
+ U32 workspace[ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32];
} ZSTD_entropyDTables_t;
typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
@@ -95,11 +99,6 @@ typedef enum {
ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */
} ZSTD_dictUses_e;
-typedef enum {
- ZSTD_obm_buffered = 0, /* Buffer the output */
- ZSTD_obm_stable = 1 /* ZSTD_outBuffer is stable */
-} ZSTD_outBufferMode_e;
-
struct ZSTD_DCtx_s
{
const ZSTD_seqSymbol* LLTptr;
@@ -122,6 +121,8 @@ struct ZSTD_DCtx_s
XXH64_state_t xxhState;
size_t headerSize;
ZSTD_format_e format;
+ ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum; /* User specified: if == 1, will ignore checksums in compressed frame. Default == 0 */
+ U32 validateChecksum; /* if == 1, will validate checksum. Is == 1 if (fParams.checksumFlag == 1) and (forceIgnoreChecksum == 0). */
const BYTE* litPtr;
ZSTD_customMem customMem;
size_t litSize;
@@ -152,7 +153,7 @@ struct ZSTD_DCtx_s
U32 legacyVersion;
U32 hostageByte;
int noForwardProgress;
- ZSTD_outBufferMode_e outBufferMode;
+ ZSTD_bufferMode_e outBufferMode;
ZSTD_outBuffer expectedOutBuffer;
/* workspace */
diff --git a/thirdparty/zstd/zstd.h b/thirdparty/zstd/zstd.h
index 8c6fc6ae90..b0ecdf5538 100644
--- a/thirdparty/zstd/zstd.h
+++ b/thirdparty/zstd/zstd.h
@@ -72,16 +72,21 @@ extern "C" {
/*------ Version ------*/
#define ZSTD_VERSION_MAJOR 1
#define ZSTD_VERSION_MINOR 4
-#define ZSTD_VERSION_RELEASE 5
-
+#define ZSTD_VERSION_RELEASE 8
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
-ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< to check runtime library version */
+
+/*! ZSTD_versionNumber() :
+ * Return runtime library version, the value is (MAJOR*100*100 + MINOR*100 + RELEASE). */
+ZSTDLIB_API unsigned ZSTD_versionNumber(void);
#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
#define ZSTD_QUOTE(str) #str
#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str)
#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)
-ZSTDLIB_API const char* ZSTD_versionString(void); /* requires v1.3.0+ */
+
+/*! ZSTD_versionString() :
+ * Return runtime library version, like "1.4.5". Requires v1.3.0+. */
+ZSTDLIB_API const char* ZSTD_versionString(void);
/* *************************************
* Default constant
@@ -334,7 +339,9 @@ typedef enum {
* for large inputs, by finding large matches at long distance.
* It increases memory usage and window size.
* Note: enabling this parameter increases default ZSTD_c_windowLog to 128 MB
- * except when expressly set to a different value. */
+ * except when expressly set to a different value.
+ * Note: will be enabled by default if ZSTD_c_windowLog >= 128 MB and
+ * compression strategy >= ZSTD_btopt (== compression level 16+) */
ZSTD_c_ldmHashLog=161, /* Size of the table for long distance matching, as a power of 2.
* Larger values increase memory usage and compression ratio,
* but decrease compression speed.
@@ -365,16 +372,20 @@ typedef enum {
ZSTD_c_dictIDFlag=202, /* When applicable, dictionary's ID is written into frame header (default:1) */
/* multi-threading parameters */
- /* These parameters are only useful if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD).
- * They return an error otherwise. */
+ /* These parameters are only active if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD).
+ * Otherwise, trying to set any other value than default (0) will be a no-op and return an error.
+ * In a situation where it's unknown if the linked library supports multi-threading or not,
+ * setting ZSTD_c_nbWorkers to any value >= 1 and consulting the return value provides a quick way to check this property.
+ */
ZSTD_c_nbWorkers=400, /* Select how many threads will be spawned to compress in parallel.
- * When nbWorkers >= 1, triggers asynchronous mode when used with ZSTD_compressStream*() :
+ * When nbWorkers >= 1, triggers asynchronous mode when invoking ZSTD_compressStream*() :
* ZSTD_compressStream*() consumes input and flush output if possible, but immediately gives back control to caller,
- * while compression work is performed in parallel, within worker threads.
+ * while compression is performed in parallel, within worker thread(s).
* (note : a strong exception to this rule is when first invocation of ZSTD_compressStream2() sets ZSTD_e_end :
* in which case, ZSTD_compressStream2() delegates to ZSTD_compress2(), which is always a blocking call).
* More workers improve speed, but also increase memory usage.
- * Default value is `0`, aka "single-threaded mode" : no worker is spawned, compression is performed inside Caller's thread, all invocations are blocking */
+ * Default value is `0`, aka "single-threaded mode" : no worker is spawned,
+ * compression is performed inside Caller's thread, and all invocations are blocking */
ZSTD_c_jobSize=401, /* Size of a compression job. This value is enforced only when nbWorkers >= 1.
* Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads.
* 0 means default, which is dynamically determined based on compression parameters.
@@ -403,6 +414,11 @@ typedef enum {
* ZSTD_c_literalCompressionMode
* ZSTD_c_targetCBlockSize
* ZSTD_c_srcSizeHint
+ * ZSTD_c_enableDedicatedDictSearch
+ * ZSTD_c_stableInBuffer
+ * ZSTD_c_stableOutBuffer
+ * ZSTD_c_blockDelimiters
+ * ZSTD_c_validateSequences
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
* note : never ever use experimentalParam? names directly;
* also, the enums values themselves are unstable and can still change.
@@ -413,7 +429,12 @@ typedef enum {
ZSTD_c_experimentalParam4=1001,
ZSTD_c_experimentalParam5=1002,
ZSTD_c_experimentalParam6=1003,
- ZSTD_c_experimentalParam7=1004
+ ZSTD_c_experimentalParam7=1004,
+ ZSTD_c_experimentalParam8=1005,
+ ZSTD_c_experimentalParam9=1006,
+ ZSTD_c_experimentalParam10=1007,
+ ZSTD_c_experimentalParam11=1008,
+ ZSTD_c_experimentalParam12=1009
} ZSTD_cParameter;
typedef struct {
@@ -524,11 +545,13 @@ typedef enum {
* At the time of this writing, they include :
* ZSTD_d_format
* ZSTD_d_stableOutBuffer
+ * ZSTD_d_forceIgnoreChecksum
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
* note : never ever use experimentalParam? names directly
*/
ZSTD_d_experimentalParam1=1000,
- ZSTD_d_experimentalParam2=1001
+ ZSTD_d_experimentalParam2=1001,
+ ZSTD_d_experimentalParam3=1002
} ZSTD_dParameter;
@@ -664,8 +687,9 @@ typedef enum {
* - Compression parameters cannot be changed once compression is started (save a list of exceptions in multi-threading mode)
* - output->pos must be <= dstCapacity, input->pos must be <= srcSize
* - output->pos and input->pos will be updated. They are guaranteed to remain below their respective limit.
+ * - endOp must be a valid directive
* - When nbWorkers==0 (default), function is blocking : it completes its job before returning to caller.
- * - When nbWorkers>=1, function is non-blocking : it just acquires a copy of input, and distributes jobs to internal worker threads, flush whatever is available,
+ * - When nbWorkers>=1, function is non-blocking : it copies a portion of input, distributes jobs to internal worker threads, flush to output whatever is available,
* and then immediately returns, just indicating that there is some data remaining to be flushed.
* The function nonetheless guarantees forward progress : it will return only after it reads or write at least 1+ byte.
* - Exception : if the first call requests a ZSTD_e_end directive and provides enough dstCapacity, the function delegates to ZSTD_compress2() which is always blocking.
@@ -1100,21 +1124,40 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
typedef struct ZSTD_CCtx_params_s ZSTD_CCtx_params;
typedef struct {
- unsigned int matchPos; /* Match pos in dst */
- /* If seqDef.offset > 3, then this is seqDef.offset - 3
- * If seqDef.offset < 3, then this is the corresponding repeat offset
- * But if seqDef.offset < 3 and litLength == 0, this is the
- * repeat offset before the corresponding repeat offset
- * And if seqDef.offset == 3 and litLength == 0, this is the
- * most recent repeat offset - 1
- */
- unsigned int offset;
- unsigned int litLength; /* Literal length */
- unsigned int matchLength; /* Match length */
- /* 0 when seq not rep and seqDef.offset otherwise
- * when litLength == 0 this will be <= 4, otherwise <= 3 like normal
- */
- unsigned int rep;
+ unsigned int offset; /* The offset of the match. (NOT the same as the offset code)
+ * If offset == 0 and matchLength == 0, this sequence represents the last
+ * literals in the block of litLength size.
+ */
+
+ unsigned int litLength; /* Literal length of the sequence. */
+ unsigned int matchLength; /* Match length of the sequence. */
+
+ /* Note: Users of this API may provide a sequence with matchLength == litLength == offset == 0.
+ * In this case, we will treat the sequence as a marker for a block boundary.
+ */
+
+ unsigned int rep; /* Represents which repeat offset is represented by the field 'offset'.
+ * Ranges from [0, 3].
+ *
+ * Repeat offsets are essentially previous offsets from previous sequences sorted in
+ * recency order. For more detail, see doc/zstd_compression_format.md
+ *
+ * If rep == 0, then 'offset' does not contain a repeat offset.
+ * If rep > 0:
+ * If litLength != 0:
+ * rep == 1 --> offset == repeat_offset_1
+ * rep == 2 --> offset == repeat_offset_2
+ * rep == 3 --> offset == repeat_offset_3
+ * If litLength == 0:
+ * rep == 1 --> offset == repeat_offset_2
+ * rep == 2 --> offset == repeat_offset_3
+ * rep == 3 --> offset == repeat_offset_1 - 1
+ *
+ * Note: This field is optional. ZSTD_generateSequences() will calculate the value of
+ * 'rep', but repeat offsets do not necessarily need to be calculated from an external
+ * sequence provider's perspective. For example, ZSTD_compressSequences() does not
+ * use this 'rep' field at all (as of now).
+ */
} ZSTD_Sequence;
typedef struct {
@@ -1157,6 +1200,12 @@ typedef enum {
} ZSTD_format_e;
typedef enum {
+ /* Note: this enum controls ZSTD_d_forceIgnoreChecksum */
+ ZSTD_d_validateChecksum = 0,
+ ZSTD_d_ignoreChecksum = 1
+} ZSTD_forceIgnoreChecksum_e;
+
+typedef enum {
/* Note: this enum and the behavior it controls are effectively internal
* implementation details of the compressor. They are expected to continue
* to evolve and should be considered only in the context of extremely
@@ -1253,14 +1302,74 @@ ZSTDLIB_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcS
* or an error code (if srcSize is too small) */
ZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);
-/*! ZSTD_getSequences() :
- * Extract sequences from the sequence store
+typedef enum {
+ ZSTD_sf_noBlockDelimiters = 0, /* Representation of ZSTD_Sequence has no block delimiters, sequences only */
+ ZSTD_sf_explicitBlockDelimiters = 1 /* Representation of ZSTD_Sequence contains explicit block delimiters */
+} ZSTD_sequenceFormat_e;
+
+/*! ZSTD_generateSequences() :
+ * Generate sequences using ZSTD_compress2, given a source buffer.
+ *
+ * Each block will end with a dummy sequence
+ * with offset == 0, matchLength == 0, and litLength == length of last literals.
+ * litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0)
+ * simply acts as a block delimiter.
+ *
* zc can be used to insert custom compression params.
* This function invokes ZSTD_compress2
- * @return : number of sequences extracted
+ *
+ * The output of this function can be fed into ZSTD_compressSequences() with CCtx
+ * setting of ZSTD_c_blockDelimiters as ZSTD_sf_explicitBlockDelimiters
+ * @return : number of sequences generated
+ */
+
+ZSTDLIB_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
+ size_t outSeqsSize, const void* src, size_t srcSize);
+
+/*! ZSTD_mergeBlockDelimiters() :
+ * Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals
+ * by merging them into into the literals of the next sequence.
+ *
+ * As such, the final generated result has no explicit representation of block boundaries,
+ * and the final last literals segment is not represented in the sequences.
+ *
+ * The output of this function can be fed into ZSTD_compressSequences() with CCtx
+ * setting of ZSTD_c_blockDelimiters as ZSTD_sf_noBlockDelimiters
+ * @return : number of sequences left after merging
+ */
+ZSTDLIB_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize);
+
+/*! ZSTD_compressSequences() :
+ * Compress an array of ZSTD_Sequence, generated from the original source buffer, into dst.
+ * If a dictionary is included, then the cctx should reference the dict. (see: ZSTD_CCtx_refCDict(), ZSTD_CCtx_loadDictionary(), etc.)
+ * The entire source is compressed into a single frame.
+ *
+ * The compression behavior changes based on cctx params. In particular:
+ * If ZSTD_c_blockDelimiters == ZSTD_sf_noBlockDelimiters, the array of ZSTD_Sequence is expected to contain
+ * no block delimiters (defined in ZSTD_Sequence). Block boundaries are roughly determined based on
+ * the block size derived from the cctx, and sequences may be split. This is the default setting.
+ *
+ * If ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, the array of ZSTD_Sequence is expected to contain
+ * block delimiters (defined in ZSTD_Sequence). Behavior is undefined if no block delimiters are provided.
+ *
+ * If ZSTD_c_validateSequences == 0, this function will blindly accept the sequences provided. Invalid sequences cause undefined
+ * behavior. If ZSTD_c_validateSequences == 1, then if sequence is invalid (see doc/zstd_compression_format.md for
+ * specifics regarding offset/matchlength requirements) then the function will bail out and return an error.
+ *
+ * In addition to the two adjustable experimental params, there are other important cctx params.
+ * - ZSTD_c_minMatch MUST be set as less than or equal to the smallest match generated by the match finder. It has a minimum value of ZSTD_MINMATCH_MIN.
+ * - ZSTD_c_compressionLevel accordingly adjusts the strength of the entropy coder, as it would in typical compression.
+ * - ZSTD_c_windowLog affects offset validation: this function will return an error at higher debug levels if a provided offset
+ * is larger than what the spec allows for a given window log and dictionary (if present). See: doc/zstd_compression_format.md
+ *
+ * Note: Repcodes are, as of now, always re-calculated within this function, so ZSTD_Sequence::rep is unused.
+ * Note 2: Once we integrate ability to ingest repcodes, the explicit block delims mode must respect those repcodes exactly,
+ * and cannot emit an RLE block that disagrees with the repcode history
+ * @return : final compressed size or a ZSTD error.
*/
-ZSTDLIB_API size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
- size_t outSeqsSize, const void* src, size_t srcSize);
+ZSTDLIB_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstSize,
+ const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
+ const void* src, size_t srcSize);
/***************************************
@@ -1372,7 +1481,11 @@ ZSTDLIB_API const ZSTD_DDict* ZSTD_initStaticDDict(
typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
typedef void (*ZSTD_freeFunction) (void* opaque, void* address);
typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
-static ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
+static
+#ifdef __GNUC__
+__attribute__((__unused__))
+#endif
+ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
@@ -1385,13 +1498,36 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS
ZSTD_compressionParameters cParams,
ZSTD_customMem customMem);
+/* ! Thread pool :
+ * These prototypes make it possible to share a thread pool among multiple compression contexts.
+ * This can limit resources for applications with multiple threads where each one uses
+ * a threaded compression mode (via ZSTD_c_nbWorkers parameter).
+ * ZSTD_createThreadPool creates a new thread pool with a given number of threads.
+ * Note that the lifetime of such pool must exist while being used.
+ * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value
+ * to use an internal thread pool).
+ * ZSTD_freeThreadPool frees a thread pool.
+ */
+typedef struct POOL_ctx_s ZSTD_threadPool;
+ZSTDLIB_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads);
+ZSTDLIB_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool);
+ZSTDLIB_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool);
+
+/*
+ * This API is temporary and is expected to change or disappear in the future!
+ */
+ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2(
+ const void* dict, size_t dictSize,
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_dictContentType_e dictContentType,
+ const ZSTD_CCtx_params* cctxParams,
+ ZSTD_customMem customMem);
+
ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
ZSTD_customMem customMem);
-
-
/***************************************
* Advanced compression functions
***************************************/
@@ -1404,6 +1540,12 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictS
* note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
+/*! ZSTD_getDictID_fromCDict() :
+ * Provides the dictID of the dictionary loaded into `cdict`.
+ * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
+ * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
+ZSTDLIB_API unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict);
+
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
* `estimatedSrcSize` value is optional, select 0 if not known */
@@ -1518,6 +1660,143 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
* but compression ratio may regress significantly if guess considerably underestimates */
#define ZSTD_c_srcSizeHint ZSTD_c_experimentalParam7
+/* Controls whether the new and experimental "dedicated dictionary search
+ * structure" can be used. This feature is still rough around the edges, be
+ * prepared for surprising behavior!
+ *
+ * How to use it:
+ *
+ * When using a CDict, whether to use this feature or not is controlled at
+ * CDict creation, and it must be set in a CCtxParams set passed into that
+ * construction (via ZSTD_createCDict_advanced2()). A compression will then
+ * use the feature or not based on how the CDict was constructed; the value of
+ * this param, set in the CCtx, will have no effect.
+ *
+ * However, when a dictionary buffer is passed into a CCtx, such as via
+ * ZSTD_CCtx_loadDictionary(), this param can be set on the CCtx to control
+ * whether the CDict that is created internally can use the feature or not.
+ *
+ * What it does:
+ *
+ * Normally, the internal data structures of the CDict are analogous to what
+ * would be stored in a CCtx after compressing the contents of a dictionary.
+ * To an approximation, a compression using a dictionary can then use those
+ * data structures to simply continue what is effectively a streaming
+ * compression where the simulated compression of the dictionary left off.
+ * Which is to say, the search structures in the CDict are normally the same
+ * format as in the CCtx.
+ *
+ * It is possible to do better, since the CDict is not like a CCtx: the search
+ * structures are written once during CDict creation, and then are only read
+ * after that, while the search structures in the CCtx are both read and
+ * written as the compression goes along. This means we can choose a search
+ * structure for the dictionary that is read-optimized.
+ *
+ * This feature enables the use of that different structure.
+ *
+ * Note that some of the members of the ZSTD_compressionParameters struct have
+ * different semantics and constraints in the dedicated search structure. It is
+ * highly recommended that you simply set a compression level in the CCtxParams
+ * you pass into the CDict creation call, and avoid messing with the cParams
+ * directly.
+ *
+ * Effects:
+ *
+ * This will only have any effect when the selected ZSTD_strategy
+ * implementation supports this feature. Currently, that's limited to
+ * ZSTD_greedy, ZSTD_lazy, and ZSTD_lazy2.
+ *
+ * Note that this means that the CDict tables can no longer be copied into the
+ * CCtx, so the dict attachment mode ZSTD_dictForceCopy will no longer be
+ * useable. The dictionary can only be attached or reloaded.
+ *
+ * In general, you should expect compression to be faster--sometimes very much
+ * so--and CDict creation to be slightly slower. Eventually, we will probably
+ * make this mode the default.
+ */
+#define ZSTD_c_enableDedicatedDictSearch ZSTD_c_experimentalParam8
+
+/* ZSTD_c_stableInBuffer
+ * Experimental parameter.
+ * Default is 0 == disabled. Set to 1 to enable.
+ *
+ * Tells the compressor that the ZSTD_inBuffer will ALWAYS be the same
+ * between calls, except for the modifications that zstd makes to pos (the
+ * caller must not modify pos). This is checked by the compressor, and
+ * compression will fail if it ever changes. This means the only flush
+ * mode that makes sense is ZSTD_e_end, so zstd will error if ZSTD_e_end
+ * is not used. The data in the ZSTD_inBuffer in the range [src, src + pos)
+ * MUST not be modified during compression or you will get data corruption.
+ *
+ * When this flag is enabled zstd won't allocate an input window buffer,
+ * because the user guarantees it can reference the ZSTD_inBuffer until
+ * the frame is complete. But, it will still allocate an output buffer
+ * large enough to fit a block (see ZSTD_c_stableOutBuffer). This will also
+ * avoid the memcpy() from the input buffer to the input window buffer.
+ *
+ * NOTE: ZSTD_compressStream2() will error if ZSTD_e_end is not used.
+ * That means this flag cannot be used with ZSTD_compressStream().
+ *
+ * NOTE: So long as the ZSTD_inBuffer always points to valid memory, using
+ * this flag is ALWAYS memory safe, and will never access out-of-bounds
+ * memory. However, compression WILL fail if you violate the preconditions.
+ *
+ * WARNING: The data in the ZSTD_inBuffer in the range [dst, dst + pos) MUST
+ * not be modified during compression or you will get data corruption. This
+ * is because zstd needs to reference data in the ZSTD_inBuffer to find
+ * matches. Normally zstd maintains its own window buffer for this purpose,
+ * but passing this flag tells zstd to use the user provided buffer.
+ */
+#define ZSTD_c_stableInBuffer ZSTD_c_experimentalParam9
+
+/* ZSTD_c_stableOutBuffer
+ * Experimental parameter.
+ * Default is 0 == disabled. Set to 1 to enable.
+ *
+ * Tells he compressor that the ZSTD_outBuffer will not be resized between
+ * calls. Specifically: (out.size - out.pos) will never grow. This gives the
+ * compressor the freedom to say: If the compressed data doesn't fit in the
+ * output buffer then return ZSTD_error_dstSizeTooSmall. This allows us to
+ * always decompress directly into the output buffer, instead of decompressing
+ * into an internal buffer and copying to the output buffer.
+ *
+ * When this flag is enabled zstd won't allocate an output buffer, because
+ * it can write directly to the ZSTD_outBuffer. It will still allocate the
+ * input window buffer (see ZSTD_c_stableInBuffer).
+ *
+ * Zstd will check that (out.size - out.pos) never grows and return an error
+ * if it does. While not strictly necessary, this should prevent surprises.
+ */
+#define ZSTD_c_stableOutBuffer ZSTD_c_experimentalParam10
+
+/* ZSTD_c_blockDelimiters
+ * Default is 0 == ZSTD_sf_noBlockDelimiters.
+ *
+ * For use with sequence compression API: ZSTD_compressSequences().
+ *
+ * Designates whether or not the given array of ZSTD_Sequence contains block delimiters
+ * and last literals, which are defined as sequences with offset == 0 and matchLength == 0.
+ * See the definition of ZSTD_Sequence for more specifics.
+ */
+#define ZSTD_c_blockDelimiters ZSTD_c_experimentalParam11
+
+/* ZSTD_c_validateSequences
+ * Default is 0 == disabled. Set to 1 to enable sequence validation.
+ *
+ * For use with sequence compression API: ZSTD_compressSequences().
+ * Designates whether or not we validate sequences provided to ZSTD_compressSequences()
+ * during function execution.
+ *
+ * Without validation, providing a sequence that does not conform to the zstd spec will cause
+ * undefined behavior, and may produce a corrupted block.
+ *
+ * With validation enabled, a if sequence is invalid (see doc/zstd_compression_format.md for
+ * specifics regarding offset/matchlength requirements) then the function will bail out and
+ * return an error.
+ *
+ */
+#define ZSTD_c_validateSequences ZSTD_c_experimentalParam12
+
/*! ZSTD_CCtx_getParameter() :
* Get the requested compression parameter value, selected by enum ZSTD_cParameter,
* and store it into int* value.
@@ -1566,8 +1845,10 @@ ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, Z
/*! ZSTD_CCtxParams_setParameter() :
* Similar to ZSTD_CCtx_setParameter.
* Set one compression parameter, selected by enum ZSTD_cParameter.
- * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams().
- * @result : 0, or an error code (which can be tested with ZSTD_isError()).
+ * Parameters must be applied to a ZSTD_CCtx using
+ * ZSTD_CCtx_setParametersUsingCCtxParams().
+ * @result : a code representing success or failure (which can be tested with
+ * ZSTD_isError()).
*/
ZSTDLIB_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value);
@@ -1647,6 +1928,13 @@ ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* pre
*/
ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize);
+/*! ZSTD_DCtx_getParameter() :
+ * Get the requested decompression parameter value, selected by enum ZSTD_dParameter,
+ * and store it into int* value.
+ * @return : 0, or an error code (which can be tested with ZSTD_isError()).
+ */
+ZSTDLIB_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value);
+
/* ZSTD_d_format
* experimental parameter,
* allowing selection between ZSTD_format_e input compression formats
@@ -1684,6 +1972,17 @@ ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowS
*/
#define ZSTD_d_stableOutBuffer ZSTD_d_experimentalParam2
+/* ZSTD_d_forceIgnoreChecksum
+ * Experimental parameter.
+ * Default is 0 == disabled. Set to 1 to enable
+ *
+ * Tells the decompressor to skip checksum validation during decompression, regardless
+ * of whether checksumming was specified during compression. This offers some
+ * slight performance benefits, and may be useful for debugging.
+ * Param has values of type ZSTD_forceIgnoreChecksum_e
+ */
+#define ZSTD_d_forceIgnoreChecksum ZSTD_d_experimentalParam3
+
/*! ZSTD_DCtx_setFormat() :
* Instruct the decoder context about what kind of data to decode next.
* This instruction is mandatory to decode data without a fully-formed header,
@@ -1711,7 +2010,8 @@ ZSTDLIB_API size_t ZSTD_decompressStream_simpleArgs (
********************************************************************/
/*===== Advanced Streaming compression functions =====*/
-/**! ZSTD_initCStream_srcSize() :
+
+/*! ZSTD_initCStream_srcSize() :
* This function is deprecated, and equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any)
@@ -1728,7 +2028,7 @@ ZSTD_initCStream_srcSize(ZSTD_CStream* zcs,
int compressionLevel,
unsigned long long pledgedSrcSize);
-/**! ZSTD_initCStream_usingDict() :
+/*! ZSTD_initCStream_usingDict() :
* This function is deprecated, and is equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
@@ -1745,7 +2045,7 @@ ZSTD_initCStream_usingDict(ZSTD_CStream* zcs,
const void* dict, size_t dictSize,
int compressionLevel);
-/**! ZSTD_initCStream_advanced() :
+/*! ZSTD_initCStream_advanced() :
* This function is deprecated, and is approximately equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* // Pseudocode: Set each zstd parameter and leave the rest as-is.
@@ -1766,7 +2066,7 @@ ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
ZSTD_parameters params,
unsigned long long pledgedSrcSize);
-/**! ZSTD_initCStream_usingCDict() :
+/*! ZSTD_initCStream_usingCDict() :
* This function is deprecated, and equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* ZSTD_CCtx_refCDict(zcs, cdict);
@@ -1776,7 +2076,7 @@ ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
*/
ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);
-/**! ZSTD_initCStream_usingCDict_advanced() :
+/*! ZSTD_initCStream_usingCDict_advanced() :
* This function is DEPRECATED, and is approximately equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* // Pseudocode: Set each zstd frame parameter and leave the rest as-is.
@@ -1849,7 +2149,8 @@ ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);
/*===== Advanced Streaming decompression functions =====*/
-/**
+
+/*!
* This function is deprecated, and is equivalent to:
*
* ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);
@@ -1860,7 +2161,7 @@ ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);
*/
ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
-/**
+/*!
* This function is deprecated, and is equivalent to:
*
* ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);
@@ -1871,7 +2172,7 @@ ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dic
*/
ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);
-/**
+/*!
* This function is deprecated, and is equivalent to:
*
* ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);
@@ -1933,7 +2234,7 @@ ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstC
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
-/*-
+/**
Buffer-less streaming decompression (synchronous mode)
A ZSTD_DCtx object is required to track streaming operations.
diff --git a/version.py b/version.py
index 2a6a9c0a28..517a47f568 100644
--- a/version.py
+++ b/version.py
@@ -5,5 +5,5 @@ minor = 0
patch = 0
status = "dev"
module_config = ""
-year = 2020
+year = 2021
website = "https://godotengine.org"